1 /*
2 * Copyright (C) 2024 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <gtest/gtest.h>
18 #include <pixelstats/MmMetricsReporter.h>
19
20 #include "MmMetricsGoldenAtomFieldTypes.h"
21 #include "MmMetricsGoldenResults.h"
22 #include "MockMmMetricsReporter.h"
23 #include "VendorAtomIntValueUtil.h"
24
25 #ifndef ARRAY_SIZE
26 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
27 #endif
28
29 namespace android {
30 namespace hardware {
31 namespace google {
32 namespace pixel {
33
34 using mm_metrics_atom_field_test_golden_results::PixelMmMetricsPerDay_field_types;
35 using mm_metrics_atom_field_test_golden_results::PixelMmMetricsPerHour_field_types;
36 using mm_metrics_reporter_test_golden_result::PixelMmMetricsPerDay_golden;
37 using mm_metrics_reporter_test_golden_result::PixelMmMetricsPerHour_golden;
38
39 const char *data_base_path = "/data/local/tmp/test/pixelstats_mm_test/data";
40
TEST(MmMetricsReporterTest,MmMetricsPerHourAtomFieldOffsetTypeTest)41 TEST(MmMetricsReporterTest, MmMetricsPerHourAtomFieldOffsetTypeTest) {
42 int i = -1;
43 uint64_t golden_result;
44 int field_type;
45 std::vector<VendorAtomValue> values;
46 MockMmMetricsReporter mreport;
47 const std::string data_path0 = std::string(data_base_path) + "/test_data_0";
48 const std::string data_path1 = std::string(data_base_path) + "/test_data_1";
49
50 // Assert failure means the test case itself has a bug.
51 ASSERT_EQ(ARRAY_SIZE(PixelMmMetricsPerHour_golden),
52 ARRAY_SIZE(PixelMmMetricsPerHour_field_types));
53
54 /**
55 * In test code we use setBasePath() to read different data sets for simulating
56 * different timing reads of a sysfs node.
57 */
58
59 /**
60 * aggregatePixelMmMetricsPer5Min() aggregates PSI into max, min, and avg.
61 * For the regular code, it will be called 12 times per hour (i.e. once per 5min)
62 * For test code we do 6 times: enough for testing.
63 * e.g. here average = (3 x data0 + 3 x data1) / 6 == avg of data 0, 1
64 * The following sequence simulate regular code obtaining sysfs nodes into
65 * values[] array (i.e. atom), ready to be sent to the server
66 */
67 mreport.setBasePath(data_path0);
68 mreport.aggregatePixelMmMetricsPer5Min();
69 mreport.aggregatePixelMmMetricsPer5Min();
70 mreport.aggregatePixelMmMetricsPer5Min();
71 mreport.setBasePath(data_path1);
72 mreport.aggregatePixelMmMetricsPer5Min();
73 mreport.aggregatePixelMmMetricsPer5Min();
74 mreport.aggregatePixelMmMetricsPer5Min();
75
76 // other fields from data set #0
77 mreport.setBasePath(data_path0);
78 values = mreport.genPixelMmMetricsPerHour();
79
80 // Validate the atom: compare with golden results
81 EXPECT_EQ(values.size(), ARRAY_SIZE(PixelMmMetricsPerHour_field_types));
82 for (auto const &v : values) {
83 i++;
84 golden_result = PixelMmMetricsPerHour_golden[i];
85 field_type = PixelMmMetricsPerHour_field_types[i];
86 if (golden_result == -1)
87 continue; // no need to test (e.g. deprecated field)
88
89 EXPECT_EQ(static_cast<int>(v.getTag()), field_type) << "type mismatch at offset " << i;
90 EXPECT_EQ(getVendorAtomIntValue(v), golden_result) << "value mismatch at offset " << i;
91 }
92 }
93
TEST(MmMetricsReporterTest,MmMetricsPerDayAtomFieldOffsetTypeTest)94 TEST(MmMetricsReporterTest, MmMetricsPerDayAtomFieldOffsetTypeTest) {
95 int i = -1;
96 uint64_t golden_result;
97 int field_type;
98 std::vector<VendorAtomValue> values;
99 MockMmMetricsReporter mreport;
100 const std::string data_path0 = std::string(data_base_path) + "/test_data_0";
101 const std::string data_path1 = std::string(data_base_path) + "/test_data_1";
102
103 // Assert failure means the test case itself has a bug.
104 ASSERT_EQ(ARRAY_SIZE(PixelMmMetricsPerDay_golden),
105 ARRAY_SIZE(PixelMmMetricsPerDay_field_types));
106
107 mreport.setBasePath(data_path0);
108 values = mreport.genPixelMmMetricsPerDay();
109
110 // PixelMmMetricsPerDay calculatd the difference of consecutive readings.
111 // So, it will not send values[] at the 1st read. (i.e. empty for the 1st read)
112 EXPECT_EQ(values.size(), 0);
113 values.clear();
114
115 mreport.setBasePath(data_path1);
116 values = mreport.genPixelMmMetricsPerDay();
117
118 // Per Day metrics (diffs) should be calculated, values[] will be non-empty now.
119 // number of data should be the same as the number of fields in the atom.
120 EXPECT_EQ(values.size(), ARRAY_SIZE(PixelMmMetricsPerDay_field_types));
121 for (auto const &v : values) {
122 i++;
123 EXPECT_LT(i, ARRAY_SIZE(PixelMmMetricsPerDay_field_types));
124
125 golden_result = PixelMmMetricsPerDay_golden[i];
126 field_type = PixelMmMetricsPerDay_field_types[i];
127 if (golden_result == -1)
128 continue; // no need to test (e.g. deprecated field)
129
130 EXPECT_EQ(static_cast<int>(v.getTag()), field_type) << "type mismatch at offset " << i;
131 EXPECT_EQ(getVendorAtomIntValue(v), golden_result) << "value mismatch at offset " << i;
132 }
133 }
134
135 } // namespace pixel
136 } // namespace google
137 } // namespace hardware
138 } // namespace android
139