• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2024 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/metrics/dwa/dwa_service.h"
6 
7 #include "base/test/scoped_feature_list.h"
8 #include "base/test/task_environment.h"
9 #include "base/time/time_override.h"
10 #include "components/metrics/dwa/dwa_entry_builder.h"
11 #include "components/metrics/dwa/dwa_pref_names.h"
12 #include "components/metrics/dwa/dwa_recorder.h"
13 #include "components/metrics/metrics_state_manager.h"
14 #include "components/metrics/test/test_metrics_service_client.h"
15 #include "components/prefs/pref_service.h"
16 #include "components/prefs/testing_pref_service.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 
19 namespace metrics::dwa {
20 class DwaServiceTest : public testing::Test {
21  public:
DwaServiceTest()22   DwaServiceTest() {
23     DwaRecorder::Get()->Purge();
24 
25     MetricsStateManager::RegisterPrefs(prefs_.registry());
26     DwaService::RegisterPrefs(prefs_.registry());
27 
28     scoped_feature_list_.InitAndEnableFeature(kDwaFeature);
29   }
30 
31   DwaServiceTest(const DwaServiceTest&) = delete;
32   DwaServiceTest& operator=(const DwaServiceTest&) = delete;
33 
34   ~DwaServiceTest() override = default;
35 
TearDown()36   void TearDown() override { DwaRecorder::Get()->Purge(); }
37 
GetPersistedLogCount()38   int GetPersistedLogCount() {
39     return prefs_.GetList(prefs::kUnsentLogStoreName).size();
40   }
41 
42  protected:
43   // Check that the values in |coarse_system_info| are filled in and expected
44   // ones correspond to the test data.
CheckCoarseSystemInformation(const::dwa::CoarseSystemInfo & coarse_system_info)45   void CheckCoarseSystemInformation(
46       const ::dwa::CoarseSystemInfo& coarse_system_info) {
47     EXPECT_TRUE(coarse_system_info.has_channel());
48     // TestMetricsServiceClient::GetChannel() returns CHANNEL_BETA, so we should
49     // expect |coarse_system_info| channel to be "NOT_STABLE".
50     EXPECT_EQ(coarse_system_info.channel(),
51               ::dwa::CoarseSystemInfo::CHANNEL_NOT_STABLE);
52     EXPECT_TRUE(coarse_system_info.has_platform());
53     EXPECT_TRUE(coarse_system_info.has_geo_designation());
54     EXPECT_TRUE(coarse_system_info.has_client_age());
55     EXPECT_TRUE(coarse_system_info.has_milestone_prefix_trimmed());
56     EXPECT_TRUE(coarse_system_info.has_is_ukm_enabled());
57   }
58 
59   // Records a test data DWA metric into DwaRecorder.
RecordTestMetric()60   void RecordTestMetric() {
61     ::dwa::DwaEntryBuilder builder("Kangaroo.Jumped");
62     builder.SetContent("adtech.com");
63     builder.SetMetric("Length", 5);
64     builder.Record(DwaRecorder::Get());
65   }
66 
67   TestMetricsServiceClient client_;
68   TestingPrefServiceSimple prefs_;
69   base::test::ScopedFeatureList scoped_feature_list_;
70 };
71 
72 class DwaServiceEnvironmentTest : public DwaServiceTest {
73  protected:
74   base::test::TaskEnvironment task_environment_{
75       base::test::TaskEnvironment::MainThreadType::UI,
76       base::test::TaskEnvironment::ThreadPoolExecutionMode::QUEUED,
77       base::test::TaskEnvironment::TimeSource::MOCK_TIME};
78 };
79 
TEST_F(DwaServiceTest,RecordCoarseSystemInformation)80 TEST_F(DwaServiceTest, RecordCoarseSystemInformation) {
81   TestingPrefServiceSimple pref_service;
82   MetricsStateManager::RegisterPrefs(pref_service.registry());
83   ::dwa::CoarseSystemInfo coarse_system_info;
84   DwaService::RecordCoarseSystemInformation(client_, pref_service,
85                                             &coarse_system_info);
86   CheckCoarseSystemInformation(coarse_system_info);
87 }
88 
TEST_F(DwaServiceTest,ClientIdIsGenerated)89 TEST_F(DwaServiceTest, ClientIdIsGenerated) {
90   TestingPrefServiceSimple pref_service;
91   DwaService::RegisterPrefs(pref_service.registry());
92 
93   base::Time expected_time_at_daily_resolution;
94   EXPECT_TRUE(base::Time::FromString("1 May 2024 00:00:00 GMT",
95                                      &expected_time_at_daily_resolution));
96 
97   uint64_t client_id;
98 
99   {
100     base::subtle::ScopedTimeClockOverrides time_override(
101         []() {
102           base::Time now;
103           EXPECT_TRUE(base::Time::FromString("1 May 2024 12:15 GMT", &now));
104           return now;
105         },
106         nullptr, nullptr);
107     client_id = DwaService::GetEphemeralClientId(pref_service);
108   }
109 
110   EXPECT_GT(pref_service.GetUint64(metrics::dwa::prefs::kDwaClientId), 0u);
111   EXPECT_EQ(client_id,
112             pref_service.GetUint64(metrics::dwa::prefs::kDwaClientId));
113   EXPECT_EQ(expected_time_at_daily_resolution,
114             pref_service.GetTime(metrics::dwa::prefs::kDwaClientIdLastUpdated));
115 }
116 
TEST_F(DwaServiceTest,ClientIdOnlyChangesBetweenDays)117 TEST_F(DwaServiceTest, ClientIdOnlyChangesBetweenDays) {
118   TestingPrefServiceSimple pref_service;
119   DwaService::RegisterPrefs(pref_service.registry());
120 
121   uint64_t client_id_day1;
122   uint64_t client_id_day2;
123   uint64_t client_id_day2_later;
124 
125   {
126     base::subtle::ScopedTimeClockOverrides time_override(
127         []() {
128           base::Time now;
129           EXPECT_TRUE(base::Time::FromString("1 May 2024 12:15 GMT", &now));
130           return now;
131         },
132         nullptr, nullptr);
133     client_id_day1 = DwaService::GetEphemeralClientId(pref_service);
134   }
135 
136   {
137     base::subtle::ScopedTimeClockOverrides time_override(
138         []() {
139           base::Time now;
140           EXPECT_TRUE(base::Time::FromString("2 May 2024 12:15 GMT", &now));
141           return now;
142         },
143         nullptr, nullptr);
144     client_id_day2 = DwaService::GetEphemeralClientId(pref_service);
145   }
146 
147   {
148     base::subtle::ScopedTimeClockOverrides time_override(
149         []() {
150           base::Time now;
151           EXPECT_TRUE(base::Time::FromString("2 May 2024 16:15 GMT", &now));
152           return now;
153         },
154         nullptr, nullptr);
155     client_id_day2_later = DwaService::GetEphemeralClientId(pref_service);
156   }
157 
158   EXPECT_NE(client_id_day1, client_id_day2);
159   EXPECT_EQ(client_id_day2, client_id_day2_later);
160 }
161 
TEST_F(DwaServiceEnvironmentTest,Flush)162 TEST_F(DwaServiceEnvironmentTest, Flush) {
163   DwaService service(&client_, &prefs_);
164   DwaRecorder::Get()->EnableRecording();
165 
166   // Tests Flush() when there are no page load events.
167   RecordTestMetric();
168   EXPECT_TRUE(DwaRecorder::Get()->HasEntries());
169   EXPECT_FALSE(DwaRecorder::Get()->HasPageLoadEvents());
170 
171   EXPECT_EQ(GetPersistedLogCount(), 0);
172   service.Flush(metrics::MetricsLogsEventManager::CreateReason::kPeriodic);
173   EXPECT_EQ(GetPersistedLogCount(), 0);
174 
175   // Tests Flush() when there are page load events.
176   RecordTestMetric();
177   EXPECT_TRUE(DwaRecorder::Get()->HasEntries());
178   DwaRecorder::Get()->OnPageLoad();
179   EXPECT_TRUE(DwaRecorder::Get()->HasPageLoadEvents());
180 
181   EXPECT_EQ(GetPersistedLogCount(), 0);
182   service.Flush(metrics::MetricsLogsEventManager::CreateReason::kPeriodic);
183   EXPECT_EQ(GetPersistedLogCount(), 1);
184 }
185 
TEST_F(DwaServiceEnvironmentTest,Purge)186 TEST_F(DwaServiceEnvironmentTest, Purge) {
187   DwaService service(&client_, &prefs_);
188   DwaRecorder::Get()->EnableRecording();
189 
190   // Test that Purge() removes all metrics (entries and page load events).
191   RecordTestMetric();
192   EXPECT_TRUE(DwaRecorder::Get()->HasEntries());
193   DwaRecorder::Get()->OnPageLoad();
194   EXPECT_TRUE(DwaRecorder::Get()->HasPageLoadEvents());
195   RecordTestMetric();
196   service.Purge();
197   EXPECT_FALSE(DwaRecorder::Get()->HasEntries());
198   EXPECT_FALSE(DwaRecorder::Get()->HasPageLoadEvents());
199 
200   // Test that Purge() removes all logs.
201   RecordTestMetric();
202   EXPECT_TRUE(DwaRecorder::Get()->HasEntries());
203   DwaRecorder::Get()->OnPageLoad();
204   EXPECT_TRUE(DwaRecorder::Get()->HasPageLoadEvents());
205 
206   EXPECT_EQ(GetPersistedLogCount(), 0);
207   service.Flush(metrics::MetricsLogsEventManager::CreateReason::kPeriodic);
208   EXPECT_EQ(GetPersistedLogCount(), 1);
209 
210   service.Purge();
211   EXPECT_FALSE(DwaRecorder::Get()->HasEntries());
212   EXPECT_FALSE(DwaRecorder::Get()->HasPageLoadEvents());
213   EXPECT_EQ(GetPersistedLogCount(), 0);
214 }
215 
TEST_F(DwaServiceEnvironmentTest,EnableDisableRecordingAndReporting)216 TEST_F(DwaServiceEnvironmentTest, EnableDisableRecordingAndReporting) {
217   DwaService service(&client_, &prefs_);
218   EXPECT_EQ(task_environment_.GetPendingMainThreadTaskCount(), 0u);
219 
220   // When the reporting is enabled, the scheduler starts and creates tasks to
221   // rotate logs.
222   service.EnableReporting();
223   EXPECT_GE(task_environment_.GetPendingMainThreadTaskCount(), 1u);
224 
225   service.DisableReporting();
226   EXPECT_EQ(task_environment_.GetPendingMainThreadTaskCount(), 0u);
227 
228   // Tests EnableRecording() records an entry.
229   DwaRecorder::Get()->EnableRecording();
230   RecordTestMetric();
231   EXPECT_TRUE(DwaRecorder::Get()->HasEntries());
232   EXPECT_FALSE(service.unsent_log_store()->has_unsent_logs());
233 
234   // Save the above entry to memory as a page load event.
235   DwaRecorder::Get()->OnPageLoad();
236   EXPECT_TRUE(DwaRecorder::Get()->HasPageLoadEvents());
237   EXPECT_EQ(GetPersistedLogCount(), 0);
238   EXPECT_FALSE(service.unsent_log_store()->has_unsent_logs());
239 
240   // DisableRecording() and persist the above page load event to disk.
241   DwaRecorder::Get()->DisableRecording();
242   service.Flush(metrics::MetricsLogsEventManager::CreateReason::kPeriodic);
243   EXPECT_EQ(GetPersistedLogCount(), 1);
244   EXPECT_TRUE(service.unsent_log_store()->has_unsent_logs());
245 
246   // Tests EnableRecording() with reporting_active() also starts
247   // DwaReportingService when there are unsent logs on disk.
248   service.EnableReporting();
249   DwaRecorder::Get()->EnableRecording();
250   // Validate there should be two pending tasks, one to rotate logs, and one to
251   // upload unsent logs from disk.
252   EXPECT_EQ(task_environment_.GetPendingMainThreadTaskCount(), 2u);
253 
254   base::TimeDelta upload_interval = client_.GetUploadInterval();
255   task_environment_.FastForwardBy(upload_interval);
256   EXPECT_TRUE(client_.uploader()->is_uploading());
257 
258   // Simulate logs upload.
259   client_.uploader()->CompleteUpload(200);
260   EXPECT_FALSE(client_.uploader()->is_uploading());
261 
262   // Logs are uploaded and there are no metrics in memory or on disk.
263   EXPECT_FALSE(DwaRecorder::Get()->HasEntries());
264   EXPECT_FALSE(DwaRecorder::Get()->HasPageLoadEvents());
265   EXPECT_FALSE(service.unsent_log_store()->has_unsent_logs());
266   EXPECT_EQ(GetPersistedLogCount(), 0);
267 
268   // Cleans up state of DwaService for the test following.
269   service.DisableReporting();
270   service.Purge();
271 
272   // Tests DisableRecording() does not record an entry.
273   DwaRecorder::Get()->DisableRecording();
274   RecordTestMetric();
275   EXPECT_FALSE(DwaRecorder::Get()->HasEntries());
276 }
277 
TEST_F(DwaServiceEnvironmentTest,LogsRotatedPeriodically)278 TEST_F(DwaServiceEnvironmentTest, LogsRotatedPeriodically) {
279   DwaService service(&client_, &prefs_);
280   DwaRecorder::Get()->EnableRecording();
281   service.EnableReporting();
282 
283   RecordTestMetric();
284   EXPECT_TRUE(DwaRecorder::Get()->HasEntries());
285   DwaRecorder::Get()->OnPageLoad();
286 
287   // Metrics are stored in memory as page load events in DwaRecorder, and there
288   // are no unsent logs.
289   EXPECT_TRUE(DwaRecorder::Get()->HasPageLoadEvents());
290   EXPECT_FALSE(service.unsent_log_store()->has_unsent_logs());
291 
292   // Metrics are stored in memory as unsent logs, and DwaRecorder is empty.
293   base::TimeDelta upload_interval = client_.GetUploadInterval();
294   task_environment_.FastForwardBy(upload_interval);
295   EXPECT_FALSE(DwaRecorder::Get()->HasEntries());
296   EXPECT_FALSE(DwaRecorder::Get()->HasPageLoadEvents());
297   EXPECT_TRUE(service.unsent_log_store()->has_unsent_logs());
298   // PersistedLogCount is 0 because logs are stored in memory and not on disk.
299   EXPECT_EQ(GetPersistedLogCount(), 0);
300   EXPECT_TRUE(client_.uploader()->is_uploading());
301 
302   // Simulate logs upload.
303   client_.uploader()->CompleteUpload(200);
304   EXPECT_FALSE(client_.uploader()->is_uploading());
305 
306   // Logs are uploaded and there are no metrics in memory or on disk.
307   EXPECT_FALSE(DwaRecorder::Get()->HasEntries());
308   EXPECT_FALSE(DwaRecorder::Get()->HasPageLoadEvents());
309   EXPECT_FALSE(service.unsent_log_store()->has_unsent_logs());
310   EXPECT_EQ(GetPersistedLogCount(), 0);
311 
312   // Checks there is another rotation scheduled when the previous one finished.
313   EXPECT_EQ(task_environment_.GetPendingMainThreadTaskCount(), 1u);
314 
315   // Repeat test above to validate the task scheduled is the task that rotates
316   // logs.
317   RecordTestMetric();
318   EXPECT_TRUE(DwaRecorder::Get()->HasEntries());
319   DwaRecorder::Get()->OnPageLoad();
320 
321   EXPECT_TRUE(DwaRecorder::Get()->HasPageLoadEvents());
322   EXPECT_FALSE(service.unsent_log_store()->has_unsent_logs());
323 
324   task_environment_.FastForwardBy(upload_interval);
325   EXPECT_FALSE(DwaRecorder::Get()->HasEntries());
326   EXPECT_FALSE(DwaRecorder::Get()->HasPageLoadEvents());
327   EXPECT_TRUE(service.unsent_log_store()->has_unsent_logs());
328   EXPECT_EQ(GetPersistedLogCount(), 0);
329   EXPECT_TRUE(client_.uploader()->is_uploading());
330 
331   client_.uploader()->CompleteUpload(200);
332   EXPECT_FALSE(client_.uploader()->is_uploading());
333 
334   EXPECT_FALSE(DwaRecorder::Get()->HasEntries());
335   EXPECT_FALSE(DwaRecorder::Get()->HasPageLoadEvents());
336   EXPECT_FALSE(service.unsent_log_store()->has_unsent_logs());
337   EXPECT_EQ(GetPersistedLogCount(), 0);
338 }
339 
340 }  // namespace metrics::dwa
341