[M120 Migration][VD] Enable direct rendering for TVPlus
[platform/framework/web/chromium-efl.git] / components / power_metrics / system_power_monitor_unittest.cc
1 // Copyright 2023 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/system_power_monitor.h"
6
7 #include "base/memory/raw_ptr.h"
8 #include "base/test/task_environment.h"
9 #include "base/test/test_future.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11
12 namespace power_metrics {
13
14 class FakeProvider : public EnergyMetricsProvider {
15  public:
16   void set_metrics(EnergyMetrics metrics) { metrics_ = metrics; }
17
18   absl::optional<EnergyMetrics> CaptureMetrics() override { return metrics_; }
19
20  private:
21   absl::optional<EnergyMetrics> metrics_;
22 };
23
24 class FakeDelegate : public SystemPowerMonitorDelegate {
25  public:
26   void set_trace_category_enabled(bool enabled) {
27     trace_category_enabled_ = enabled;
28   }
29
30   void RecordSystemPower(const char* category,
31                          base::TimeTicks timestamp,
32                          int64_t power) override {
33     timestamp_ = timestamp;
34     if (strcmp(category, "Package Power (mW)") == 0) {
35       system_power_.package_nanojoules = static_cast<uint64_t>(power);
36     } else if (strcmp(category, "CPU Power (mW)") == 0) {
37       system_power_.cpu_nanojoules = static_cast<uint64_t>(power);
38     } else if (strcmp(category, "iGPU Power (mW)") == 0) {
39       system_power_.gpu_nanojoules = static_cast<uint64_t>(power);
40     } else if (strcmp(category, "DRAM Power (mW)") == 0) {
41       system_power_.dram_nanojoules = static_cast<uint64_t>(power);
42     } else if (strcmp(category, "Psys Power (mW)") == 0) {
43       system_power_.psys_nanojoules = static_cast<uint64_t>(power);
44     } else if (strcmp(category, "VDDCR VDD (mW)") == 0) {
45       system_power_.vdd_nanojoules = static_cast<uint64_t>(power);
46     } else if (strcmp(category, "VDDCR SOC (mW)") == 0) {
47       system_power_.soc_nanojoules = static_cast<uint64_t>(power);
48     } else if (strcmp(category, "Current Socket (mW)") == 0) {
49       system_power_.socket_nanojoules = static_cast<uint64_t>(power);
50     } else if (strcmp(category, "APU Power (mW)") == 0) {
51       system_power_.apu_nanojoules = static_cast<uint64_t>(power);
52     }
53   }
54
55   bool IsTraceCategoryEnabled() const override {
56     return trace_category_enabled_;
57   }
58
59   EnergyMetricsProvider::EnergyMetrics& SystemPower() { return system_power_; }
60
61   base::TimeTicks timestamp() { return timestamp_; }
62
63  private:
64   // We use EnergyMetrics to save recorded power data in milliwatts for
65   // simplicity.
66   EnergyMetricsProvider::EnergyMetrics system_power_;
67   base::TimeTicks timestamp_;
68   bool trace_category_enabled_{true};
69 };
70
71 class SystemPowerMonitorHelperTest : public testing::Test {
72  public:
73   SystemPowerMonitorHelperTest()
74       : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
75
76   void SetUp() override {
77     auto provider = std::make_unique<FakeProvider>();
78     provider_ = provider.get();
79     auto delegate = std::make_unique<FakeDelegate>();
80     delegate_ = delegate.get();
81     helper_ = std::make_unique<SystemPowerMonitorHelper>(std::move(provider),
82                                                          std::move(delegate));
83   }
84
85   void TearDown() override { helper_.reset(); }
86
87   base::test::TaskEnvironment& task_environment() { return task_environment_; }
88   SystemPowerMonitorHelper* helper() { return helper_.get(); }
89   FakeDelegate* delegate() { return delegate_.get(); }
90   FakeProvider* provider() { return provider_.get(); }
91
92  protected:
93   base::test::TaskEnvironment task_environment_;
94
95  private:
96   std::unique_ptr<SystemPowerMonitorHelper> helper_;
97   raw_ptr<FakeDelegate, DanglingUntriaged> delegate_;
98   raw_ptr<FakeProvider, DanglingUntriaged> provider_;
99 };
100
101 class SystemPowerMonitorTest : public testing::Test {
102  public:
103   SystemPowerMonitorTest() : task_environment_() {}
104
105   void SetUp() override {
106     auto provider = std::make_unique<FakeProvider>();
107
108     // Assign a valid metric to provider, so the timer can start successfully.
109     provider->set_metrics({1llu});
110     monitor_.reset(new SystemPowerMonitor(std::move(provider),
111                                           std::make_unique<FakeDelegate>()));
112   }
113
114   void TearDown() override { monitor_.reset(); }
115
116   SystemPowerMonitor* monitor() { return monitor_.get(); }
117   base::SequenceBound<SystemPowerMonitorHelper>* helper() {
118     return monitor_->GetHelperForTesting();
119   }
120
121  protected:
122   base::test::TaskEnvironment task_environment_;
123
124  private:
125   std::unique_ptr<SystemPowerMonitor> monitor_;
126 };
127
128 TEST_F(SystemPowerMonitorHelperTest, MonitorHelperStartStop) {
129   provider()->set_metrics({1llu});
130
131   helper()->Start();
132   ASSERT_TRUE(helper()->IsTimerRunningForTesting());
133   helper()->Stop();
134   ASSERT_FALSE(helper()->IsTimerRunningForTesting());
135   helper()->Start();
136   ASSERT_TRUE(helper()->IsTimerRunningForTesting());
137   helper()->Stop();
138   ASSERT_FALSE(helper()->IsTimerRunningForTesting());
139 }
140
141 TEST_F(SystemPowerMonitorHelperTest, TimerStartFailed_InvalidSample) {
142   // We haven't set metrics for provider, so monitor gets an
143   // absl::nullopt sample at the beginning and it will not start.
144   helper()->Start();
145   ASSERT_FALSE(helper()->IsTimerRunningForTesting());
146 }
147
148 TEST_F(SystemPowerMonitorHelperTest, TimerStartFailed_MetricsAllZero) {
149   // If the metrics are all 0, we determine that there is no valid metric
150   // provided, so monitor will not start.
151   provider()->set_metrics({});
152   helper()->Start();
153   ASSERT_FALSE(helper()->IsTimerRunningForTesting());
154 }
155
156 TEST_F(SystemPowerMonitorHelperTest, TraceCategoryEnableDisable) {
157   provider()->set_metrics({1llu});
158
159   delegate()->set_trace_category_enabled(false);
160   ASSERT_FALSE(delegate()->IsTraceCategoryEnabled());
161   helper()->Start();
162   ASSERT_FALSE(helper()->IsTimerRunningForTesting());
163
164   delegate()->set_trace_category_enabled(true);
165   ASSERT_TRUE(delegate()->IsTraceCategoryEnabled());
166   helper()->Start();
167   ASSERT_TRUE(helper()->IsTimerRunningForTesting());
168 }
169
170 TEST_F(SystemPowerMonitorHelperTest, TestSample) {
171   EnergyMetricsProvider::EnergyMetrics sample1 = {
172       100000llu, 100000llu, 100000llu, 100000llu, 100000llu,
173       100000llu, 100000llu, 100000llu, 100000llu};
174   EnergyMetricsProvider::EnergyMetrics sample2 = {
175       200000llu, 300000llu, 400000llu, 500000llu, 600000llu,
176       700000llu, 800000llu, 900000llu, 1000000llu};
177
178   provider()->set_metrics(sample1);
179   helper()->Start();
180   ASSERT_TRUE(helper()->IsTimerRunningForTesting());
181
182   provider()->set_metrics(sample2);
183   task_environment().FastForwardBy(
184       SystemPowerMonitorHelper::kDefaultSampleInterval);
185   auto power = delegate()->SystemPower();
186   EXPECT_EQ(delegate()->timestamp() +
187                 SystemPowerMonitorHelper::kDefaultSampleInterval,
188             task_environment().NowTicks());
189   EXPECT_EQ(
190       power.package_nanojoules,
191       (sample2.package_nanojoules - sample1.package_nanojoules) /
192           SystemPowerMonitorHelper::kDefaultSampleInterval.InMicroseconds());
193   EXPECT_EQ(
194       power.cpu_nanojoules,
195       (sample2.cpu_nanojoules - sample1.cpu_nanojoules) /
196           SystemPowerMonitorHelper::kDefaultSampleInterval.InMicroseconds());
197   EXPECT_EQ(
198       power.gpu_nanojoules,
199       (sample2.gpu_nanojoules - sample1.gpu_nanojoules) /
200           SystemPowerMonitorHelper::kDefaultSampleInterval.InMicroseconds());
201   EXPECT_EQ(
202       power.dram_nanojoules,
203       (sample2.dram_nanojoules - sample1.dram_nanojoules) /
204           SystemPowerMonitorHelper::kDefaultSampleInterval.InMicroseconds());
205   EXPECT_EQ(
206       power.psys_nanojoules,
207       (sample2.psys_nanojoules - sample1.psys_nanojoules) /
208           SystemPowerMonitorHelper::kDefaultSampleInterval.InMicroseconds());
209   EXPECT_EQ(
210       power.vdd_nanojoules,
211       (sample2.vdd_nanojoules - sample1.vdd_nanojoules) /
212           SystemPowerMonitorHelper::kDefaultSampleInterval.InMicroseconds());
213   EXPECT_EQ(
214       power.soc_nanojoules,
215       (sample2.soc_nanojoules - sample1.soc_nanojoules) /
216           SystemPowerMonitorHelper::kDefaultSampleInterval.InMicroseconds());
217   EXPECT_EQ(
218       power.socket_nanojoules,
219       (sample2.socket_nanojoules - sample1.socket_nanojoules) /
220           SystemPowerMonitorHelper::kDefaultSampleInterval.InMicroseconds());
221   EXPECT_EQ(
222       power.apu_nanojoules,
223       (sample2.apu_nanojoules - sample1.apu_nanojoules) /
224           SystemPowerMonitorHelper::kDefaultSampleInterval.InMicroseconds());
225 }
226
227 TEST_F(SystemPowerMonitorTest, TraceLogEnableDisable) {
228   ASSERT_NE(helper(), nullptr);
229
230   base::test::TestFuture<bool> future_enable;
231   monitor()->OnTraceLogEnabled();
232   helper()
233       ->AsyncCall(&SystemPowerMonitorHelper::IsTimerRunningForTesting)
234       .Then(base::BindOnce(
235           [](base::OnceCallback<void(bool)> callback, bool is_running) {
236             std::move(callback).Run(is_running);
237           },
238           future_enable.GetCallback()));
239   EXPECT_TRUE(future_enable.Get());
240
241   base::test::TestFuture<bool> future_disable;
242   monitor()->OnTraceLogDisabled();
243   helper()
244       ->AsyncCall(&SystemPowerMonitorHelper::IsTimerRunningForTesting)
245       .Then(base::BindOnce(
246           [](base::OnceCallback<void(bool)> callback, bool is_running) {
247             std::move(callback).Run(is_running);
248           },
249           future_disable.GetCallback()));
250   EXPECT_FALSE(future_disable.Get());
251 }
252
253 }  // namespace power_metrics