blob: ecbfcf177b1cb225a1db4e210f97c81c045eb76d [file] [log] [blame]
holteade6fdf2017-02-23 02:42:391// Copyright 2017 The Chromium Authors. All rights reserved.
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_pref_names.h"
8#include "components/metrics/test_metrics_service_client.h"
9#include "components/prefs/testing_pref_service.h"
10#include "testing/gtest/include/gtest/gtest.h"
11
12namespace metrics {
13
14namespace {
15
16class MetricsLogStoreTest : public testing::Test {
17 public:
18 MetricsLogStoreTest() {
19 MetricsLogStore::RegisterPrefs(pref_service_.registry());
20 }
21 ~MetricsLogStoreTest() override {}
22
23 MetricsLog* CreateLog(MetricsLog::LogType log_type) {
Steven Holted0429a702017-08-03 08:56:1724 return new MetricsLog("id", 0, log_type, &client_);
holteade6fdf2017-02-23 02:42:3925 }
26
27 // Returns the stored number of logs of the given type.
28 size_t TypeCount(MetricsLog::LogType log_type) {
29 const char* pref = log_type == MetricsLog::INITIAL_STABILITY_LOG
30 ? prefs::kMetricsInitialLogs
31 : prefs::kMetricsOngoingLogs;
32 return pref_service_.GetList(pref)->GetSize();
33 }
34
35 TestMetricsServiceClient client_;
36 TestingPrefServiceSimple pref_service_;
37
38 private:
39 DISALLOW_COPY_AND_ASSIGN(MetricsLogStoreTest);
40};
41
42} // namespace
43
44TEST_F(MetricsLogStoreTest, StandardFlow) {
Jesse Dohertybf020162018-12-11 15:40:0145 MetricsLogStore log_store(&pref_service_, 0, std::string());
holteade6fdf2017-02-23 02:42:3946 log_store.LoadPersistedUnsentLogs();
47
48 // Make sure a new manager has a clean slate.
49 EXPECT_FALSE(log_store.has_staged_log());
50 EXPECT_FALSE(log_store.has_unsent_logs());
51
52 log_store.StoreLog("a", MetricsLog::ONGOING_LOG);
53 EXPECT_TRUE(log_store.has_unsent_logs());
54 EXPECT_FALSE(log_store.has_staged_log());
55
56 log_store.StageNextLog();
57 EXPECT_TRUE(log_store.has_staged_log());
58 EXPECT_FALSE(log_store.staged_log().empty());
59
60 log_store.DiscardStagedLog();
61 EXPECT_FALSE(log_store.has_staged_log());
62 EXPECT_FALSE(log_store.has_unsent_logs());
63}
64
65TEST_F(MetricsLogStoreTest, StoreAndLoad) {
66 // Set up some in-progress logging in a scoped log manager simulating the
67 // leadup to quitting, then persist as would be done on quit.
68 {
Jesse Dohertybf020162018-12-11 15:40:0169 MetricsLogStore log_store(&pref_service_, 0, std::string());
holteade6fdf2017-02-23 02:42:3970 log_store.LoadPersistedUnsentLogs();
71 EXPECT_FALSE(log_store.has_unsent_logs());
72 log_store.StoreLog("a", MetricsLog::ONGOING_LOG);
73 log_store.PersistUnsentLogs();
74 EXPECT_EQ(0U, TypeCount(MetricsLog::INITIAL_STABILITY_LOG));
75 EXPECT_EQ(1U, TypeCount(MetricsLog::ONGOING_LOG));
76 }
77
78 // Relaunch load and store more logs.
79 {
Jesse Dohertybf020162018-12-11 15:40:0180 MetricsLogStore log_store(&pref_service_, 0, std::string());
holteade6fdf2017-02-23 02:42:3981 log_store.LoadPersistedUnsentLogs();
82 EXPECT_TRUE(log_store.has_unsent_logs());
83 EXPECT_EQ(0U, TypeCount(MetricsLog::INITIAL_STABILITY_LOG));
84 EXPECT_EQ(1U, TypeCount(MetricsLog::ONGOING_LOG));
85 log_store.StoreLog("x", MetricsLog::INITIAL_STABILITY_LOG);
86 log_store.StageNextLog();
87 log_store.StoreLog("b", MetricsLog::ONGOING_LOG);
88
89 EXPECT_TRUE(log_store.has_unsent_logs());
90 EXPECT_TRUE(log_store.has_staged_log());
91 EXPECT_EQ(0U, TypeCount(MetricsLog::INITIAL_STABILITY_LOG));
92 EXPECT_EQ(1U, TypeCount(MetricsLog::ONGOING_LOG));
93
94 log_store.PersistUnsentLogs();
95 EXPECT_EQ(1U, TypeCount(MetricsLog::INITIAL_STABILITY_LOG));
96 EXPECT_EQ(2U, TypeCount(MetricsLog::ONGOING_LOG));
97 }
98
99 // Relaunch and verify that once logs are handled they are not re-persisted.
100 {
Jesse Dohertybf020162018-12-11 15:40:01101 MetricsLogStore log_store(&pref_service_, 0, std::string());
holteade6fdf2017-02-23 02:42:39102 log_store.LoadPersistedUnsentLogs();
103 EXPECT_TRUE(log_store.has_unsent_logs());
104
105 log_store.StageNextLog();
106 log_store.DiscardStagedLog();
107 // The initial log should be sent first; update the persisted storage to
108 // verify.
109 log_store.PersistUnsentLogs();
110 EXPECT_EQ(0U, TypeCount(MetricsLog::INITIAL_STABILITY_LOG));
111 EXPECT_EQ(2U, TypeCount(MetricsLog::ONGOING_LOG));
112
113 // Handle the first ongoing log.
114 log_store.StageNextLog();
115 log_store.DiscardStagedLog();
116 EXPECT_TRUE(log_store.has_unsent_logs());
117
118 // Handle the last log.
119 log_store.StageNextLog();
120 log_store.DiscardStagedLog();
121 EXPECT_FALSE(log_store.has_unsent_logs());
122
123 // Nothing should have changed "on disk" since PersistUnsentLogs hasn't been
124 // called again.
125 EXPECT_EQ(2U, TypeCount(MetricsLog::ONGOING_LOG));
126 // Persist, and make sure nothing is left.
127 log_store.PersistUnsentLogs();
128 EXPECT_EQ(0U, TypeCount(MetricsLog::INITIAL_STABILITY_LOG));
129 EXPECT_EQ(0U, TypeCount(MetricsLog::ONGOING_LOG));
130 }
131}
132
133TEST_F(MetricsLogStoreTest, StoreStagedOngoingLog) {
134 // Ensure that types are preserved when storing staged logs.
Jesse Dohertybf020162018-12-11 15:40:01135 MetricsLogStore log_store(&pref_service_, 0, std::string());
holteade6fdf2017-02-23 02:42:39136 log_store.LoadPersistedUnsentLogs();
137 log_store.StoreLog("a", MetricsLog::ONGOING_LOG);
138 log_store.StageNextLog();
139 log_store.PersistUnsentLogs();
140
141 EXPECT_EQ(0U, TypeCount(MetricsLog::INITIAL_STABILITY_LOG));
142 EXPECT_EQ(1U, TypeCount(MetricsLog::ONGOING_LOG));
143}
144
145TEST_F(MetricsLogStoreTest, StoreStagedInitialLog) {
146 // Ensure that types are preserved when storing staged logs.
Jesse Dohertybf020162018-12-11 15:40:01147 MetricsLogStore log_store(&pref_service_, 0, std::string());
holteade6fdf2017-02-23 02:42:39148 log_store.LoadPersistedUnsentLogs();
149 log_store.StoreLog("b", MetricsLog::INITIAL_STABILITY_LOG);
150 log_store.StageNextLog();
151 log_store.PersistUnsentLogs();
152
153 EXPECT_EQ(1U, TypeCount(MetricsLog::INITIAL_STABILITY_LOG));
154 EXPECT_EQ(0U, TypeCount(MetricsLog::ONGOING_LOG));
155}
156
157TEST_F(MetricsLogStoreTest, LargeLogDiscarding) {
158 // Set the size threshold very low, to verify that it's honored.
Jesse Dohertybf020162018-12-11 15:40:01159 MetricsLogStore log_store(&pref_service_, 1, std::string());
holteade6fdf2017-02-23 02:42:39160 log_store.LoadPersistedUnsentLogs();
161
162 log_store.StoreLog("persisted", MetricsLog::INITIAL_STABILITY_LOG);
163 log_store.StoreLog("not_persisted", MetricsLog::ONGOING_LOG);
164
165 // Only the stability log should be written out, due to the threshold.
166 log_store.PersistUnsentLogs();
167 EXPECT_EQ(1U, TypeCount(MetricsLog::INITIAL_STABILITY_LOG));
168 EXPECT_EQ(0U, TypeCount(MetricsLog::ONGOING_LOG));
169}
170
171TEST_F(MetricsLogStoreTest, DiscardOrder) {
172 // Ensure that the correct log is discarded if new logs are pushed while
173 // a log is staged.
Jesse Dohertybf020162018-12-11 15:40:01174 MetricsLogStore log_store(&pref_service_, 0, std::string());
holteade6fdf2017-02-23 02:42:39175 log_store.LoadPersistedUnsentLogs();
176
177 log_store.StoreLog("a", MetricsLog::ONGOING_LOG);
178 log_store.StoreLog("b", MetricsLog::ONGOING_LOG);
179 log_store.StageNextLog();
180 log_store.StoreLog("c", MetricsLog::INITIAL_STABILITY_LOG);
181 EXPECT_EQ(2U, log_store.ongoing_log_count());
182 EXPECT_EQ(1U, log_store.initial_log_count());
183 // Should discard the ongoing log staged earlier.
184 log_store.DiscardStagedLog();
185 EXPECT_EQ(1U, log_store.ongoing_log_count());
186 EXPECT_EQ(1U, log_store.initial_log_count());
187 // Initial log should be staged next.
188 log_store.StageNextLog();
189 log_store.DiscardStagedLog();
190 EXPECT_EQ(1U, log_store.ongoing_log_count());
191 EXPECT_EQ(0U, log_store.initial_log_count());
192}
193
194} // namespace metrics