xref: /aosp_15_r20/external/cronet/components/metrics/metrics_log_store_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2017 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/metrics_log_store.h"
6 
7 #include "components/metrics/metrics_logs_event_manager.h"
8 #include "components/metrics/metrics_pref_names.h"
9 #include "components/metrics/test/test_metrics_service_client.h"
10 #include "components/metrics/unsent_log_store_metrics_impl.h"
11 #include "components/prefs/pref_registry_simple.h"
12 #include "components/prefs/testing_pref_service.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 
15 namespace metrics {
16 namespace {
17 
18 const char kTestPrefName[] = "TestPref";
19 
20 class TestUnsentLogStore : public UnsentLogStore {
21  public:
TestUnsentLogStore(PrefService * service)22   explicit TestUnsentLogStore(PrefService* service)
23       : UnsentLogStore(std::make_unique<UnsentLogStoreMetricsImpl>(),
24                        service,
25                        kTestPrefName,
26                        nullptr,
27                        // Set to 3 so logs are not dropped in the test.
28                        UnsentLogStore::UnsentLogStoreLimits{
29                            .min_log_count = 3,
30                        },
31                        /*signing_key=*/std::string(),
32                        /*logs_event_manager=*/nullptr) {}
33   ~TestUnsentLogStore() override = default;
34 
35   TestUnsentLogStore(const TestUnsentLogStore&) = delete;
36   TestUnsentLogStore& operator=(const TestUnsentLogStore&) = delete;
37 
RegisterPrefs(PrefRegistrySimple * registry)38   static void RegisterPrefs(PrefRegistrySimple* registry) {
39     registry->RegisterListPref(kTestPrefName);
40   }
41 };
42 
43 class MetricsLogStoreTest : public testing::Test {
44  public:
MetricsLogStoreTest()45   MetricsLogStoreTest() {
46     MetricsLogStore::RegisterPrefs(pref_service_.registry());
47     TestUnsentLogStore::RegisterPrefs(pref_service_.registry());
48   }
49 
50   MetricsLogStoreTest(const MetricsLogStoreTest&) = delete;
51   MetricsLogStoreTest& operator=(const MetricsLogStoreTest&) = delete;
52 
~MetricsLogStoreTest()53   ~MetricsLogStoreTest() override {}
54 
CreateLog(MetricsLog::LogType log_type)55   MetricsLog* CreateLog(MetricsLog::LogType log_type) {
56     return new MetricsLog("0a94430b-18e5-43c8-a657-580f7e855ce1", 0, log_type,
57                           &client_);
58   }
59 
60   // Returns the stored number of logs of the given type.
TypeCount(MetricsLog::LogType log_type)61   size_t TypeCount(MetricsLog::LogType log_type) {
62     const char* pref = log_type == MetricsLog::INITIAL_STABILITY_LOG
63                            ? prefs::kMetricsInitialLogs
64                            : prefs::kMetricsOngoingLogs;
65     return pref_service_.GetList(pref).size();
66   }
67 
68   TestMetricsServiceClient client_;
69   TestingPrefServiceSimple pref_service_;
70 };
71 
72 }  // namespace
73 
TEST_F(MetricsLogStoreTest,StandardFlow)74 TEST_F(MetricsLogStoreTest, StandardFlow) {
75   MetricsLogStore log_store(&pref_service_, client_.GetStorageLimits(),
76                             /*signing_key=*/std::string(),
77                             /*logs_event_manager=*/nullptr);
78   log_store.LoadPersistedUnsentLogs();
79 
80   // Make sure a new manager has a clean slate.
81   EXPECT_FALSE(log_store.has_staged_log());
82   EXPECT_FALSE(log_store.has_unsent_logs());
83 
84   log_store.StoreLog("a", MetricsLog::ONGOING_LOG, LogMetadata(),
85                      MetricsLogsEventManager::CreateReason::kUnknown);
86   EXPECT_TRUE(log_store.has_unsent_logs());
87   EXPECT_FALSE(log_store.has_staged_log());
88 
89   log_store.StageNextLog();
90   EXPECT_TRUE(log_store.has_staged_log());
91   EXPECT_FALSE(log_store.staged_log().empty());
92 
93   log_store.DiscardStagedLog();
94   EXPECT_FALSE(log_store.has_staged_log());
95   EXPECT_FALSE(log_store.has_unsent_logs());
96 }
97 
TEST_F(MetricsLogStoreTest,StoreAndLoad)98 TEST_F(MetricsLogStoreTest, StoreAndLoad) {
99   // Set up some in-progress logging in a scoped log manager simulating the
100   // leadup to quitting, then persist as would be done on quit.
101   {
102     MetricsLogStore log_store(&pref_service_, client_.GetStorageLimits(),
103                               /*signing_key=*/std::string(),
104                               /*logs_event_manager=*/nullptr);
105     log_store.LoadPersistedUnsentLogs();
106     EXPECT_FALSE(log_store.has_unsent_logs());
107     log_store.StoreLog("a", MetricsLog::ONGOING_LOG, LogMetadata(),
108                        MetricsLogsEventManager::CreateReason::kUnknown);
109     log_store.TrimAndPersistUnsentLogs(/*overwrite_in_memory_store=*/true);
110     EXPECT_EQ(0U, TypeCount(MetricsLog::INITIAL_STABILITY_LOG));
111     EXPECT_EQ(1U, TypeCount(MetricsLog::ONGOING_LOG));
112   }
113 
114   // Relaunch load and store more logs.
115   {
116     MetricsLogStore log_store(&pref_service_, client_.GetStorageLimits(),
117                               /*signing_key=*/std::string(),
118                               /*logs_event_manager=*/nullptr);
119     log_store.LoadPersistedUnsentLogs();
120     EXPECT_TRUE(log_store.has_unsent_logs());
121     EXPECT_EQ(0U, TypeCount(MetricsLog::INITIAL_STABILITY_LOG));
122     EXPECT_EQ(1U, TypeCount(MetricsLog::ONGOING_LOG));
123     log_store.StoreLog("x", MetricsLog::INITIAL_STABILITY_LOG, LogMetadata(),
124                        MetricsLogsEventManager::CreateReason::kUnknown);
125     log_store.StageNextLog();
126     log_store.StoreLog("b", MetricsLog::ONGOING_LOG, LogMetadata(),
127                        MetricsLogsEventManager::CreateReason::kUnknown);
128 
129     EXPECT_TRUE(log_store.has_unsent_logs());
130     EXPECT_TRUE(log_store.has_staged_log());
131     EXPECT_EQ(0U, TypeCount(MetricsLog::INITIAL_STABILITY_LOG));
132     EXPECT_EQ(1U, TypeCount(MetricsLog::ONGOING_LOG));
133 
134     log_store.TrimAndPersistUnsentLogs(/*overwrite_in_memory_store=*/true);
135     EXPECT_EQ(1U, TypeCount(MetricsLog::INITIAL_STABILITY_LOG));
136     EXPECT_EQ(2U, TypeCount(MetricsLog::ONGOING_LOG));
137   }
138 
139   // Relaunch and verify that once logs are handled they are not re-persisted.
140   {
141     MetricsLogStore log_store(&pref_service_, client_.GetStorageLimits(),
142                               /*signing_key=*/std::string(),
143                               /*logs_event_manager=*/nullptr);
144     log_store.LoadPersistedUnsentLogs();
145     EXPECT_TRUE(log_store.has_unsent_logs());
146 
147     log_store.StageNextLog();
148     log_store.DiscardStagedLog();
149     // The initial log should be sent first; update the persisted storage to
150     // verify.
151     log_store.TrimAndPersistUnsentLogs(/*overwrite_in_memory_store=*/true);
152     EXPECT_EQ(0U, TypeCount(MetricsLog::INITIAL_STABILITY_LOG));
153     EXPECT_EQ(2U, TypeCount(MetricsLog::ONGOING_LOG));
154 
155     // Handle the first ongoing log.
156     log_store.StageNextLog();
157     log_store.DiscardStagedLog();
158     EXPECT_TRUE(log_store.has_unsent_logs());
159 
160     // Handle the last log.
161     log_store.StageNextLog();
162     log_store.DiscardStagedLog();
163     EXPECT_FALSE(log_store.has_unsent_logs());
164 
165     // Nothing should have changed "on disk" since TrimAndPersistUnsentLogs
166     // hasn't been called again.
167     EXPECT_EQ(2U, TypeCount(MetricsLog::ONGOING_LOG));
168     // Persist, and make sure nothing is left.
169     log_store.TrimAndPersistUnsentLogs(/*overwrite_in_memory_store=*/true);
170     EXPECT_EQ(0U, TypeCount(MetricsLog::INITIAL_STABILITY_LOG));
171     EXPECT_EQ(0U, TypeCount(MetricsLog::ONGOING_LOG));
172   }
173 }
174 
TEST_F(MetricsLogStoreTest,StoreStagedOngoingLog)175 TEST_F(MetricsLogStoreTest, StoreStagedOngoingLog) {
176   // Ensure that types are preserved when storing staged logs.
177   MetricsLogStore log_store(&pref_service_, client_.GetStorageLimits(),
178                             /*signing_key=*/std::string(),
179                             /*logs_event_manager=*/nullptr);
180   log_store.LoadPersistedUnsentLogs();
181   log_store.StoreLog("a", MetricsLog::ONGOING_LOG, LogMetadata(),
182                      MetricsLogsEventManager::CreateReason::kUnknown);
183   log_store.StageNextLog();
184   log_store.TrimAndPersistUnsentLogs(/*overwrite_in_memory_store=*/true);
185 
186   EXPECT_EQ(0U, TypeCount(MetricsLog::INITIAL_STABILITY_LOG));
187   EXPECT_EQ(1U, TypeCount(MetricsLog::ONGOING_LOG));
188 }
189 
TEST_F(MetricsLogStoreTest,StoreStagedInitialLog)190 TEST_F(MetricsLogStoreTest, StoreStagedInitialLog) {
191   // Ensure that types are preserved when storing staged logs.
192   MetricsLogStore log_store(&pref_service_, client_.GetStorageLimits(),
193                             /*signing_key=*/std::string(),
194                             /*logs_event_manager=*/nullptr);
195   log_store.LoadPersistedUnsentLogs();
196   log_store.StoreLog("b", MetricsLog::INITIAL_STABILITY_LOG, LogMetadata(),
197                      MetricsLogsEventManager::CreateReason::kUnknown);
198   log_store.StageNextLog();
199   log_store.TrimAndPersistUnsentLogs(/*overwrite_in_memory_store=*/true);
200 
201   EXPECT_EQ(1U, TypeCount(MetricsLog::INITIAL_STABILITY_LOG));
202   EXPECT_EQ(0U, TypeCount(MetricsLog::ONGOING_LOG));
203 }
204 
TEST_F(MetricsLogStoreTest,LargeLogDiscarding)205 TEST_F(MetricsLogStoreTest, LargeLogDiscarding) {
206   // Set the size threshold very low, to verify that it's honored.
207   client_.set_max_ongoing_log_size_bytes(1);
208   MetricsLogStore log_store(&pref_service_, client_.GetStorageLimits(),
209                             /*signing_key=*/std::string(),
210                             /*logs_event_manager=*/nullptr);
211   log_store.LoadPersistedUnsentLogs();
212 
213   log_store.StoreLog("persisted", MetricsLog::INITIAL_STABILITY_LOG,
214                      LogMetadata(),
215                      MetricsLogsEventManager::CreateReason::kUnknown);
216   log_store.StoreLog("not_persisted", MetricsLog::ONGOING_LOG, LogMetadata(),
217                      MetricsLogsEventManager::CreateReason::kUnknown);
218 
219   // Only the stability log should be written out, due to the threshold.
220   log_store.TrimAndPersistUnsentLogs(/*overwrite_in_memory_store=*/true);
221   EXPECT_EQ(1U, TypeCount(MetricsLog::INITIAL_STABILITY_LOG));
222   EXPECT_EQ(0U, TypeCount(MetricsLog::ONGOING_LOG));
223 }
224 
TEST_F(MetricsLogStoreTest,DiscardOrder)225 TEST_F(MetricsLogStoreTest, DiscardOrder) {
226   // Ensure that the correct log is discarded if new logs are pushed while
227   // a log is staged.
228   MetricsLogStore log_store(&pref_service_, client_.GetStorageLimits(),
229                             /*signing_key=*/std::string(),
230                             /*logs_event_manager=*/nullptr);
231   log_store.LoadPersistedUnsentLogs();
232 
233   log_store.StoreLog("a", MetricsLog::ONGOING_LOG, LogMetadata(),
234                      MetricsLogsEventManager::CreateReason::kUnknown);
235   log_store.StoreLog("b", MetricsLog::ONGOING_LOG, LogMetadata(),
236                      MetricsLogsEventManager::CreateReason::kUnknown);
237   log_store.StageNextLog();
238   log_store.StoreLog("c", MetricsLog::INITIAL_STABILITY_LOG, LogMetadata(),
239                      MetricsLogsEventManager::CreateReason::kUnknown);
240   EXPECT_EQ(2U, log_store.ongoing_log_count());
241   EXPECT_EQ(1U, log_store.initial_log_count());
242   // Should discard the ongoing log staged earlier.
243   log_store.DiscardStagedLog();
244   EXPECT_EQ(1U, log_store.ongoing_log_count());
245   EXPECT_EQ(1U, log_store.initial_log_count());
246   // Initial log should be staged next.
247   log_store.StageNextLog();
248   log_store.DiscardStagedLog();
249   EXPECT_EQ(1U, log_store.ongoing_log_count());
250   EXPECT_EQ(0U, log_store.initial_log_count());
251 }
252 
TEST_F(MetricsLogStoreTest,WritesToAlternateOngoingLogStore)253 TEST_F(MetricsLogStoreTest, WritesToAlternateOngoingLogStore) {
254   MetricsLogStore log_store(&pref_service_, client_.GetStorageLimits(),
255                             /*signing_key=*/std::string(),
256                             /*logs_event_manager=*/nullptr);
257   std::unique_ptr<TestUnsentLogStore> alternate_ongoing_log_store =
258       std::make_unique<TestUnsentLogStore>(&pref_service_);
259   TestUnsentLogStore* alternate_ongoing_log_store_ptr =
260       alternate_ongoing_log_store.get();
261 
262   // Needs to be called before writing logs to alternate ongoing store since
263   // SetAlternateOngoingLogStore loads persisted unsent logs and assumes that
264   // the native initial and ongoing unsent logs have already been loaded.
265   log_store.LoadPersistedUnsentLogs();
266 
267   log_store.StoreLog("a", MetricsLog::ONGOING_LOG, LogMetadata(),
268                      MetricsLogsEventManager::CreateReason::kUnknown);
269   log_store.SetAlternateOngoingLogStore(std::move(alternate_ongoing_log_store));
270   log_store.StoreLog("b", MetricsLog::ONGOING_LOG, LogMetadata(),
271                      MetricsLogsEventManager::CreateReason::kUnknown);
272   log_store.StoreLog("c", MetricsLog::ONGOING_LOG, LogMetadata(),
273                      MetricsLogsEventManager::CreateReason::kUnknown);
274 
275   EXPECT_EQ(1U, log_store.ongoing_log_count());
276   EXPECT_EQ(2U, alternate_ongoing_log_store_ptr->size());
277 }
278 
TEST_F(MetricsLogStoreTest,AlternateOngoingLogStoreGetsEventsLogsManager)279 TEST_F(MetricsLogStoreTest, AlternateOngoingLogStoreGetsEventsLogsManager) {
280   // Create a MetricsLogStore with a MetricsLogsEventManager.
281   MetricsLogsEventManager logs_event_manager;
282   MetricsLogStore log_store(&pref_service_, client_.GetStorageLimits(),
283                             /*signing_key=*/std::string(), &logs_event_manager);
284 
285   // Create an UnsentLogStore that will be used as an alternate ongoing log
286   // store.
287   std::unique_ptr<TestUnsentLogStore> alternate_ongoing_log_store =
288       std::make_unique<TestUnsentLogStore>(&pref_service_);
289   TestUnsentLogStore* alternate_ongoing_log_store_ptr =
290       alternate_ongoing_log_store.get();
291 
292   // Verify that |alternate_ongoing_log_store| has no logs event manager.
293   EXPECT_FALSE(
294       alternate_ongoing_log_store_ptr->GetLogsEventManagerForTesting());
295 
296   // Needs to be called before we can set |log_store|'s alternate ongoing log
297   // store.
298   log_store.LoadPersistedUnsentLogs();
299 
300   // Verify that after setting |log_store|'s alternate ongoing log store to
301   // |alternate_ongoing_log_store|, the latter should have the former's logs
302   // event manager.
303   log_store.SetAlternateOngoingLogStore(std::move(alternate_ongoing_log_store));
304   EXPECT_EQ(alternate_ongoing_log_store_ptr->GetLogsEventManagerForTesting(),
305             &logs_event_manager);
306 }
307 
TEST_F(MetricsLogStoreTest,StagesInitialOverBothOngoing)308 TEST_F(MetricsLogStoreTest, StagesInitialOverBothOngoing) {
309   MetricsLogStore log_store(&pref_service_, client_.GetStorageLimits(),
310                             /*signing_key=*/std::string(),
311                             /*logs_event_manager=*/nullptr);
312   std::unique_ptr<TestUnsentLogStore> alternate_ongoing_log_store =
313       std::make_unique<TestUnsentLogStore>(&pref_service_);
314   TestUnsentLogStore* alternate_ongoing_log_store_ptr =
315       alternate_ongoing_log_store.get();
316 
317   // Needs to be called before writing logs to alternate ongoing store since
318   // SetAlternateOngoingLogStore loads persisted unsent logs and assumes that
319   // the native initial and ongoing unsent logs have already been loaded.
320   log_store.LoadPersistedUnsentLogs();
321 
322   log_store.StoreLog("a", MetricsLog::INITIAL_STABILITY_LOG, LogMetadata(),
323                      MetricsLogsEventManager::CreateReason::kUnknown);
324   log_store.StoreLog("b", MetricsLog::ONGOING_LOG, LogMetadata(),
325                      MetricsLogsEventManager::CreateReason::kUnknown);
326   log_store.SetAlternateOngoingLogStore(std::move(alternate_ongoing_log_store));
327   log_store.StoreLog("c", MetricsLog::ONGOING_LOG, LogMetadata(),
328                      MetricsLogsEventManager::CreateReason::kUnknown);
329   log_store.StageNextLog();
330   log_store.DiscardStagedLog();
331 
332   // Discarded log should be from initial_log_store.
333   EXPECT_EQ(0U, log_store.initial_log_count());
334   EXPECT_EQ(1U, log_store.ongoing_log_count());
335   EXPECT_EQ(1U, alternate_ongoing_log_store_ptr->size());
336 }
337 
TEST_F(MetricsLogStoreTest,StagesAlternateOverOngoing)338 TEST_F(MetricsLogStoreTest, StagesAlternateOverOngoing) {
339   MetricsLogStore log_store(&pref_service_, client_.GetStorageLimits(),
340                             /*signing_key=*/std::string(),
341                             /*logs_event_manager=*/nullptr);
342   std::unique_ptr<TestUnsentLogStore> alternate_ongoing_log_store =
343       std::make_unique<TestUnsentLogStore>(&pref_service_);
344   TestUnsentLogStore* alternate_ongoing_log_store_ptr =
345       alternate_ongoing_log_store.get();
346 
347   // Needs to be called before writing logs to alternate ongoing store since
348   // SetAlternateOngoingLogStore loads persisted unsent logs and assumes that
349   // the native initial and ongoing unsent logs have already been loaded.
350   log_store.LoadPersistedUnsentLogs();
351 
352   log_store.StoreLog("a", MetricsLog::ONGOING_LOG, LogMetadata(),
353                      MetricsLogsEventManager::CreateReason::kUnknown);
354   log_store.SetAlternateOngoingLogStore(std::move(alternate_ongoing_log_store));
355   log_store.StoreLog("b", MetricsLog::ONGOING_LOG, LogMetadata(),
356                      MetricsLogsEventManager::CreateReason::kUnknown);
357   log_store.StageNextLog();
358   log_store.DiscardStagedLog();
359 
360   // Discarded log should be from alternate_ongoing_log_store.
361   EXPECT_EQ(1U, log_store.ongoing_log_count());
362   EXPECT_EQ(0U, alternate_ongoing_log_store_ptr->size());
363 }
364 
TEST_F(MetricsLogStoreTest,UnboundAlternateOngoingLogStoreWritesToNativeOngoing)365 TEST_F(MetricsLogStoreTest,
366        UnboundAlternateOngoingLogStoreWritesToNativeOngoing) {
367   MetricsLogStore log_store(&pref_service_, client_.GetStorageLimits(),
368                             /*signing_key=*/std::string(),
369                             /*logs_event_manager=*/nullptr);
370   std::unique_ptr<TestUnsentLogStore> alternate_ongoing_log_store =
371       std::make_unique<TestUnsentLogStore>(&pref_service_);
372 
373   // Needs to be called before writing logs to alternate ongoing store since
374   // SetAlternateOngoingLogStore loads persisted unsent logs and assumes that
375   // the native initial and ongoing unsent logs have already been loaded.
376   log_store.LoadPersistedUnsentLogs();
377 
378   log_store.SetAlternateOngoingLogStore(std::move(alternate_ongoing_log_store));
379   // Should be written to alternate ongoing log store.
380   log_store.StoreLog("a", MetricsLog::ONGOING_LOG, LogMetadata(),
381                      MetricsLogsEventManager::CreateReason::kUnknown);
382 
383   log_store.UnsetAlternateOngoingLogStore();
384 
385   // Should be in native ongoing log store.
386   log_store.StoreLog("b", MetricsLog::ONGOING_LOG, LogMetadata(),
387                      MetricsLogsEventManager::CreateReason::kUnknown);
388   log_store.StoreLog("c", MetricsLog::ONGOING_LOG, LogMetadata(),
389                      MetricsLogsEventManager::CreateReason::kUnknown);
390 
391   EXPECT_EQ(2U, log_store.ongoing_log_count());
392 }
393 
TEST_F(MetricsLogStoreTest,StageOngoingLogWhenAlternateOngoingLogStoreIsEmpty)394 TEST_F(MetricsLogStoreTest,
395        StageOngoingLogWhenAlternateOngoingLogStoreIsEmpty) {
396   MetricsLogStore log_store(&pref_service_, client_.GetStorageLimits(),
397                             /*signing_key=*/std::string(),
398                             /*logs_event_manager=*/nullptr);
399   std::unique_ptr<TestUnsentLogStore> alternate_ongoing_log_store =
400       std::make_unique<TestUnsentLogStore>(&pref_service_);
401 
402   // Needs to be called before writing logs to alternate ongoing store since
403   // SetAlternateOngoingLogStore loads persisted unsent logs and assumes that
404   // the native initial and ongoing unsent logs have already been loaded.
405   log_store.LoadPersistedUnsentLogs();
406 
407   // Should be written to ongoing log store.
408   log_store.StoreLog("a", MetricsLog::ONGOING_LOG, LogMetadata(),
409                      MetricsLogsEventManager::CreateReason::kUnknown);
410 
411   // Ensure that the log was stored in ongoing log.
412   EXPECT_EQ(1U, log_store.ongoing_log_count());
413 
414   log_store.SetAlternateOngoingLogStore(std::move(alternate_ongoing_log_store));
415 
416   log_store.StageNextLog();
417   log_store.DiscardStagedLog();
418 
419   // Discarded log should be from ongoing.
420   EXPECT_EQ(0U, log_store.ongoing_log_count());
421 }
422 
423 }  // namespace metrics
424