[M120 Migration][VD] Enable direct rendering for TVPlus
[platform/framework/web/chromium-efl.git] / components / power_metrics / energy_impact_mac_unittest.mm
1 // Copyright 2021 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/power_metrics/energy_impact_mac.h"
6
7 #include "base/base_paths.h"
8 #include "base/path_service.h"
9 #include "components/power_metrics/resource_coalition_mac.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11
12 namespace power_metrics {
13
14 namespace {
15
16 constexpr mach_timebase_info_data_t kIntelTimebase = {1, 1};
17 constexpr mach_timebase_info_data_t kM1Timebase = {125, 3};
18
19 base::FilePath GetTestDataPath() {
20   base::FilePath test_path;
21   EXPECT_TRUE(base::PathService::Get(base::DIR_SRC_TEST_DATA_ROOT, &test_path));
22   test_path = test_path.Append(FILE_PATH_LITERAL("components"));
23   test_path = test_path.Append(FILE_PATH_LITERAL("power_metrics"));
24   test_path = test_path.Append(FILE_PATH_LITERAL("test"));
25   test_path = test_path.Append(FILE_PATH_LITERAL("data"));
26   return test_path;
27 }
28
29 coalition_resource_usage MakeResourceUsageWithQOS(int qos_level,
30                                                   base::TimeDelta cpu_time) {
31   coalition_resource_usage result{};
32   result.cpu_time_eqos_len = COALITION_NUM_THREAD_QOS_TYPES;
33   result.cpu_time_eqos[qos_level] = cpu_time.InNanoseconds();
34   return result;
35 }
36
37 // Scales a time given in ns to mach_time in |timebase|.
38 uint64_t NsScaleToTimebase(const mach_timebase_info_data_t& timebase,
39                            int64_t time_ns) {
40   return time_ns * timebase.denom / timebase.numer;
41 }
42
43 }  // namespace
44
45 TEST(EnergyImpactTest, ReadCoefficientsFromPath) {
46   base::FilePath test_path = GetTestDataPath();
47
48   // Validate that attempting to read from a non-existent file fails.
49   auto coefficients = internal::ReadCoefficientsFromPath(
50       test_path.Append(FILE_PATH_LITERAL("does-not-exist.plist")));
51   EXPECT_FALSE(coefficients.has_value());
52
53   // Validate that a well-formed file returns the expected coefficients.
54   coefficients = internal::ReadCoefficientsFromPath(
55       test_path.Append(FILE_PATH_LITERAL("test.plist")));
56   ASSERT_TRUE(coefficients.has_value());
57
58   const EnergyImpactCoefficients& value = coefficients.value();
59   EXPECT_FLOAT_EQ(value.kcpu_time, 1.23);
60   EXPECT_FLOAT_EQ(value.kdiskio_bytesread, 7.89);
61   EXPECT_FLOAT_EQ(value.kdiskio_byteswritten, 1.2345);
62   EXPECT_FLOAT_EQ(value.kgpu_time, 6.789);
63   EXPECT_FLOAT_EQ(value.knetwork_recv_bytes, 12.3);
64   EXPECT_FLOAT_EQ(value.knetwork_recv_packets, 45.6);
65   EXPECT_FLOAT_EQ(value.knetwork_sent_bytes, 67.8);
66   EXPECT_FLOAT_EQ(value.knetwork_sent_packets, 89);
67   EXPECT_FLOAT_EQ(value.kqos_background, 8.9);
68   EXPECT_FLOAT_EQ(value.kqos_default, 6.78);
69   EXPECT_FLOAT_EQ(value.kqos_legacy, 5.678);
70   EXPECT_FLOAT_EQ(value.kqos_user_initiated, 9.012);
71   EXPECT_FLOAT_EQ(value.kqos_user_interactive, 3.456);
72   EXPECT_FLOAT_EQ(value.kqos_utility, 1.234);
73   EXPECT_FLOAT_EQ(value.kcpu_wakeups, 3.45);
74 }
75
76 TEST(EnergyImpactTest, ReadCoefficientsForBoardIdOrDefault_Exists) {
77   // This board-id should exist.
78   auto coefficients = internal::ReadCoefficientsForBoardIdOrDefault(
79       GetTestDataPath(), "Mac-7BA5B2DFE22DDD8C");
80   ASSERT_TRUE(coefficients.has_value());
81
82   // Validate that the default coefficients haven't been loaded.
83   EXPECT_FLOAT_EQ(3.4, coefficients.value().kgpu_time);
84   EXPECT_FLOAT_EQ(0.39, coefficients.value().kqos_background);
85 }
86
87 TEST(EnergyImpactTest, ReadCoefficientsForBoardIdOrDefault_Default) {
88   // This board-id should not exist.
89   auto coefficients = internal::ReadCoefficientsForBoardIdOrDefault(
90       GetTestDataPath(), "Mac-031B6874CF7F642A");
91   ASSERT_TRUE(coefficients.has_value());
92
93   // Validate that the default coefficients were loaded.
94   EXPECT_FLOAT_EQ(0, coefficients.value().kgpu_time);
95   EXPECT_FLOAT_EQ(0.8, coefficients.value().kqos_background);
96 }
97
98 TEST(EnergyImpactTest,
99      ReadCoefficientsForBoardIdOrDefault_NonExistentDirectory) {
100   // This directory shouldn't exist, so nothing should be loaded.
101   EXPECT_FALSE(
102       internal::ReadCoefficientsForBoardIdOrDefault(
103           GetTestDataPath().Append("nonexistent"), "Mac-7BA5B2DFE22DDD8C")
104           .has_value());
105 }
106
107 TEST(EnergyImpactTest, GetBoardIdForThisMachine) {
108   // This can't really be tested except that the contract holds one way
109   // or the other.
110   auto board_id = internal::GetBoardIdForThisMachine();
111   if (board_id.has_value()) {
112     EXPECT_FALSE(board_id.value().empty());
113   }
114 }
115
116 // Verify the Energy Impact score when there is a single source of energy
117 // consumption (only one member set in `coalition_resource_usage`).
118 TEST(EnergyImpactTest, ComputeEnergyImpactForResourceUsage_Individual) {
119   EXPECT_EQ(0.0, ComputeEnergyImpactForResourceUsage(coalition_resource_usage(),
120                                                      EnergyImpactCoefficients{},
121                                                      kIntelTimebase));
122
123   // Test the coefficients and sample factors individually.
124   EXPECT_DOUBLE_EQ(
125       2.66, ComputeEnergyImpactForResourceUsage(
126                 coalition_resource_usage{.platform_idle_wakeups = 133},
127                 EnergyImpactCoefficients{
128                     .kcpu_wakeups = base::Microseconds(200).InSecondsF()},
129                 kIntelTimebase));
130
131   // Test 100 ms of CPU, which should come out to 8% of a CPU second with a
132   // background QOS discount of rate of 0.8.
133   EXPECT_DOUBLE_EQ(8.0, ComputeEnergyImpactForResourceUsage(
134                             MakeResourceUsageWithQOS(THREAD_QOS_BACKGROUND,
135                                                      base::Milliseconds(100)),
136                             EnergyImpactCoefficients{.kqos_background = 0.8},
137                             kIntelTimebase));
138   EXPECT_DOUBLE_EQ(
139       5.0,
140       ComputeEnergyImpactForResourceUsage(
141           MakeResourceUsageWithQOS(THREAD_QOS_DEFAULT, base::Milliseconds(50)),
142           EnergyImpactCoefficients{.kqos_default = 1.0}, kIntelTimebase));
143   EXPECT_DOUBLE_EQ(
144       10.0,
145       ComputeEnergyImpactForResourceUsage(
146           MakeResourceUsageWithQOS(THREAD_QOS_UTILITY, base::Milliseconds(100)),
147           EnergyImpactCoefficients{.kqos_utility = 1.0}, kIntelTimebase));
148   EXPECT_DOUBLE_EQ(
149       1.0,
150       ComputeEnergyImpactForResourceUsage(
151           MakeResourceUsageWithQOS(THREAD_QOS_LEGACY, base::Milliseconds(10)),
152           EnergyImpactCoefficients{.kqos_legacy = 1.0}, kIntelTimebase));
153   EXPECT_DOUBLE_EQ(1.0,
154                    ComputeEnergyImpactForResourceUsage(
155                        MakeResourceUsageWithQOS(THREAD_QOS_USER_INITIATED,
156                                                 base::Milliseconds(10)),
157                        EnergyImpactCoefficients{.kqos_user_initiated = 1.0},
158                        kIntelTimebase));
159   EXPECT_DOUBLE_EQ(1.0,
160                    ComputeEnergyImpactForResourceUsage(
161                        MakeResourceUsageWithQOS(THREAD_QOS_USER_INTERACTIVE,
162                                                 base::Milliseconds(10)),
163                        EnergyImpactCoefficients{.kqos_user_interactive = 1.0},
164                        kIntelTimebase));
165   EXPECT_DOUBLE_EQ(
166       1.0, ComputeEnergyImpactForResourceUsage(
167                coalition_resource_usage{
168                    .gpu_time = base::Milliseconds(4).InNanoseconds()},
169                EnergyImpactCoefficients{.kgpu_time = 2.5}, kIntelTimebase));
170 }
171
172 // Verify the Energy Impact score when there are multiple sources of energy
173 // consumption (multiple members set in `coalition_resource_usage`).
174 TEST(EnergyImpactTest, ComputeEnergyImpactForResourceUsage_Combined) {
175   EnergyImpactCoefficients coefficients{
176       .kcpu_wakeups = base::Microseconds(200).InSecondsF(),
177       .kqos_default = 1.0,
178       .kqos_background = 0.8,
179       .kqos_utility = 1.0,
180       .kqos_legacy = 1.0,
181       .kqos_user_initiated = 1.0,
182       .kqos_user_interactive = 1.0,
183       .kgpu_time = 2.5,
184   };
185   coalition_resource_usage sample{
186       .platform_idle_wakeups = 133,
187       .gpu_time =
188           NsScaleToTimebase(kM1Timebase, base::Milliseconds(4).InNanoseconds()),
189       .cpu_time_eqos_len = COALITION_NUM_THREAD_QOS_TYPES,
190   };
191   sample.cpu_time_eqos[THREAD_QOS_BACKGROUND] =
192       NsScaleToTimebase(kM1Timebase, base::Milliseconds(100).InNanoseconds());
193   sample.cpu_time_eqos[THREAD_QOS_DEFAULT] =
194       NsScaleToTimebase(kM1Timebase, base::Milliseconds(50).InNanoseconds());
195   sample.cpu_time_eqos[THREAD_QOS_UTILITY] =
196       NsScaleToTimebase(kM1Timebase, base::Milliseconds(100).InNanoseconds());
197   sample.cpu_time_eqos[THREAD_QOS_LEGACY] =
198       NsScaleToTimebase(kM1Timebase, base::Milliseconds(10).InNanoseconds());
199   sample.cpu_time_eqos[THREAD_QOS_USER_INITIATED] =
200       NsScaleToTimebase(kM1Timebase, base::Milliseconds(10).InNanoseconds());
201   sample.cpu_time_eqos[THREAD_QOS_USER_INTERACTIVE] =
202       NsScaleToTimebase(kM1Timebase, base::Milliseconds(10).InNanoseconds());
203
204   EXPECT_DOUBLE_EQ(29.66, ComputeEnergyImpactForResourceUsage(
205                               sample, coefficients, kM1Timebase));
206 }
207
208 // Verify the Energy Impact score when fields of `coalition_resource_usage` that
209 // don't contribute to the score are set.
210 TEST(EnergyImpactTest, ComputeEnergyImpactForResourceUsage_Unused) {
211   EnergyImpactCoefficients coefficients{
212       .kdiskio_bytesread = 1000,
213       .kdiskio_byteswritten = 1000,
214       .knetwork_recv_bytes = 1000,
215       .knetwork_recv_packets = 1000,
216       .knetwork_sent_bytes = 1000,
217       .knetwork_sent_packets = 1000,
218   };
219   coalition_resource_usage sample{
220       .tasks_started = 1000,
221       .tasks_exited = 1000,
222       .time_nonempty = 1000,
223       .cpu_time = 1000,
224       .interrupt_wakeups = 1000,
225       .bytesread = 1000,
226       .byteswritten = 1000,
227       .cpu_time_billed_to_me = 1000,
228       .cpu_time_billed_to_others = 1000,
229       .energy = 1000,
230       .logical_immediate_writes = 1000,
231       .logical_deferred_writes = 1000,
232       .logical_invalidated_writes = 1000,
233       .logical_metadata_writes = 1000,
234       .logical_immediate_writes_to_external = 1000,
235       .logical_deferred_writes_to_external = 1000,
236       .logical_invalidated_writes_to_external = 1000,
237       .logical_metadata_writes_to_external = 1000,
238       .energy_billed_to_me = 1000,
239       .energy_billed_to_others = 1000,
240       .cpu_ptime = 1000,
241       .cpu_instructions = 1000,
242       .cpu_cycles = 1000,
243       .fs_metadata_writes = 1000,
244       .pm_writes = 1000,
245   };
246
247   EXPECT_EQ(0, ComputeEnergyImpactForResourceUsage(sample, coefficients,
248                                                    kM1Timebase));
249 }
250
251 }  // namespace power_metrics