1 // Copyright 2014 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.
5 #include "components/metrics/metrics_log_manager.h"
11 #include "base/prefs/pref_registry_simple.h"
12 #include "base/prefs/testing_pref_service.h"
13 #include "components/metrics/metrics_log.h"
14 #include "components/metrics/metrics_pref_names.h"
15 #include "components/metrics/test_metrics_service_client.h"
16 #include "testing/gtest/include/gtest/gtest.h"
22 // Dummy serializer that just stores logs in memory.
23 class TestLogPrefService
: public TestingPrefServiceSimple
{
25 TestLogPrefService() {
26 registry()->RegisterListPref(prefs::kMetricsInitialLogs
);
27 registry()->RegisterListPref(prefs::kMetricsOngoingLogs
);
30 // Returns the number of logs of the given type.
31 size_t TypeCount(MetricsLog::LogType log_type
) {
33 if (log_type
== MetricsLog::INITIAL_STABILITY_LOG
)
34 list_length
= GetList(prefs::kMetricsInitialLogs
)->GetSize();
36 list_length
= GetList(prefs::kMetricsOngoingLogs
)->GetSize();
37 return list_length
/ 2;
43 TEST(MetricsLogManagerTest
, StandardFlow
) {
44 TestMetricsServiceClient client
;
45 TestLogPrefService pref_service
;
46 MetricsLogManager
log_manager(&pref_service
, 0);
48 // Make sure a new manager has a clean slate.
49 EXPECT_EQ(NULL
, log_manager
.current_log());
50 EXPECT_FALSE(log_manager
.has_staged_log());
51 EXPECT_FALSE(log_manager
.has_unsent_logs());
53 // Check that the normal flow works.
54 MetricsLog
* initial_log
= new MetricsLog(
55 "id", 0, MetricsLog::INITIAL_STABILITY_LOG
, &client
, &pref_service
);
56 log_manager
.BeginLoggingWithLog(make_scoped_ptr(initial_log
));
57 EXPECT_EQ(initial_log
, log_manager
.current_log());
58 EXPECT_FALSE(log_manager
.has_staged_log());
60 log_manager
.FinishCurrentLog();
61 EXPECT_EQ(NULL
, log_manager
.current_log());
62 EXPECT_TRUE(log_manager
.has_unsent_logs());
63 EXPECT_FALSE(log_manager
.has_staged_log());
65 MetricsLog
* second_log
=
66 new MetricsLog("id", 0, MetricsLog::ONGOING_LOG
, &client
, &pref_service
);
67 log_manager
.BeginLoggingWithLog(make_scoped_ptr(second_log
));
68 EXPECT_EQ(second_log
, log_manager
.current_log());
70 log_manager
.StageNextLogForUpload();
71 EXPECT_TRUE(log_manager
.has_staged_log());
72 EXPECT_FALSE(log_manager
.staged_log().empty());
74 log_manager
.DiscardStagedLog();
75 EXPECT_EQ(second_log
, log_manager
.current_log());
76 EXPECT_FALSE(log_manager
.has_staged_log());
77 EXPECT_FALSE(log_manager
.has_unsent_logs());
79 EXPECT_FALSE(log_manager
.has_unsent_logs());
82 TEST(MetricsLogManagerTest
, AbandonedLog
) {
83 TestMetricsServiceClient client
;
84 TestLogPrefService pref_service
;
85 MetricsLogManager
log_manager(&pref_service
, 0);
87 MetricsLog
* dummy_log
= new MetricsLog(
88 "id", 0, MetricsLog::INITIAL_STABILITY_LOG
, &client
, &pref_service
);
89 log_manager
.BeginLoggingWithLog(make_scoped_ptr(dummy_log
));
90 EXPECT_EQ(dummy_log
, log_manager
.current_log());
92 log_manager
.DiscardCurrentLog();
93 EXPECT_EQ(NULL
, log_manager
.current_log());
94 EXPECT_FALSE(log_manager
.has_staged_log());
97 TEST(MetricsLogManagerTest
, InterjectedLog
) {
98 TestMetricsServiceClient client
;
99 TestLogPrefService pref_service
;
100 MetricsLogManager
log_manager(&pref_service
, 0);
102 MetricsLog
* ongoing_log
=
103 new MetricsLog("id", 0, MetricsLog::ONGOING_LOG
, &client
, &pref_service
);
104 MetricsLog
* temp_log
= new MetricsLog(
105 "id", 0, MetricsLog::INITIAL_STABILITY_LOG
, &client
, &pref_service
);
107 log_manager
.BeginLoggingWithLog(make_scoped_ptr(ongoing_log
));
108 EXPECT_EQ(ongoing_log
, log_manager
.current_log());
110 log_manager
.PauseCurrentLog();
111 EXPECT_EQ(NULL
, log_manager
.current_log());
113 log_manager
.BeginLoggingWithLog(make_scoped_ptr(temp_log
));
114 EXPECT_EQ(temp_log
, log_manager
.current_log());
115 log_manager
.FinishCurrentLog();
116 EXPECT_EQ(NULL
, log_manager
.current_log());
118 log_manager
.ResumePausedLog();
119 EXPECT_EQ(ongoing_log
, log_manager
.current_log());
121 EXPECT_FALSE(log_manager
.has_staged_log());
122 log_manager
.StageNextLogForUpload();
123 log_manager
.DiscardStagedLog();
124 EXPECT_FALSE(log_manager
.has_unsent_logs());
127 TEST(MetricsLogManagerTest
, InterjectedLogPreservesType
) {
128 TestMetricsServiceClient client
;
129 TestLogPrefService pref_service
;
130 MetricsLogManager
log_manager(&pref_service
, 0);
131 log_manager
.LoadPersistedUnsentLogs();
133 log_manager
.BeginLoggingWithLog(make_scoped_ptr(new MetricsLog(
134 "id", 0, MetricsLog::ONGOING_LOG
, &client
, &pref_service
)));
135 log_manager
.PauseCurrentLog();
136 log_manager
.BeginLoggingWithLog(make_scoped_ptr(new MetricsLog(
137 "id", 0, MetricsLog::INITIAL_STABILITY_LOG
, &client
, &pref_service
)));
138 log_manager
.FinishCurrentLog();
139 log_manager
.ResumePausedLog();
140 log_manager
.StageNextLogForUpload();
141 log_manager
.DiscardStagedLog();
143 // Verify that the remaining log (which is the original ongoing log) still
144 // has the right type.
145 log_manager
.FinishCurrentLog();
146 log_manager
.PersistUnsentLogs();
147 EXPECT_EQ(0U, pref_service
.TypeCount(MetricsLog::INITIAL_STABILITY_LOG
));
148 EXPECT_EQ(1U, pref_service
.TypeCount(MetricsLog::ONGOING_LOG
));
151 TEST(MetricsLogManagerTest
, StoreAndLoad
) {
152 TestMetricsServiceClient client
;
153 TestLogPrefService pref_service
;
154 // Set up some in-progress logging in a scoped log manager simulating the
155 // leadup to quitting, then persist as would be done on quit.
157 MetricsLogManager
log_manager(&pref_service
, 0);
158 log_manager
.LoadPersistedUnsentLogs();
160 // Simulate a log having already been unsent from a previous session.
162 std::string
log("proto");
163 PersistedLogs
ongoing_logs(&pref_service
, prefs::kMetricsOngoingLogs
, 1,
165 ongoing_logs
.StoreLog(log
);
166 ongoing_logs
.SerializeLogs();
168 EXPECT_EQ(1U, pref_service
.TypeCount(MetricsLog::ONGOING_LOG
));
169 EXPECT_FALSE(log_manager
.has_unsent_logs());
170 log_manager
.LoadPersistedUnsentLogs();
171 EXPECT_TRUE(log_manager
.has_unsent_logs());
173 log_manager
.BeginLoggingWithLog(make_scoped_ptr(new MetricsLog(
174 "id", 0, MetricsLog::INITIAL_STABILITY_LOG
, &client
, &pref_service
)));
175 log_manager
.FinishCurrentLog();
176 log_manager
.BeginLoggingWithLog(make_scoped_ptr(new MetricsLog(
177 "id", 0, MetricsLog::ONGOING_LOG
, &client
, &pref_service
)));
178 log_manager
.StageNextLogForUpload();
179 log_manager
.FinishCurrentLog();
181 // Nothing should be written out until PersistUnsentLogs is called.
182 EXPECT_EQ(0U, pref_service
.TypeCount(MetricsLog::INITIAL_STABILITY_LOG
));
183 EXPECT_EQ(1U, pref_service
.TypeCount(MetricsLog::ONGOING_LOG
));
184 log_manager
.PersistUnsentLogs();
185 EXPECT_EQ(1U, pref_service
.TypeCount(MetricsLog::INITIAL_STABILITY_LOG
));
186 EXPECT_EQ(2U, pref_service
.TypeCount(MetricsLog::ONGOING_LOG
));
189 // Now simulate the relaunch, ensure that the log manager restores
190 // everything correctly, and verify that once the are handled they are not
193 MetricsLogManager
log_manager(&pref_service
, 0);
194 log_manager
.LoadPersistedUnsentLogs();
195 EXPECT_TRUE(log_manager
.has_unsent_logs());
197 log_manager
.StageNextLogForUpload();
198 log_manager
.DiscardStagedLog();
199 // The initial log should be sent first; update the persisted storage to
201 log_manager
.PersistUnsentLogs();
202 EXPECT_EQ(0U, pref_service
.TypeCount(MetricsLog::INITIAL_STABILITY_LOG
));
203 EXPECT_EQ(2U, pref_service
.TypeCount(MetricsLog::ONGOING_LOG
));
205 // Handle the first ongoing log.
206 log_manager
.StageNextLogForUpload();
207 log_manager
.DiscardStagedLog();
208 EXPECT_TRUE(log_manager
.has_unsent_logs());
210 // Handle the last log.
211 log_manager
.StageNextLogForUpload();
212 log_manager
.DiscardStagedLog();
213 EXPECT_FALSE(log_manager
.has_unsent_logs());
215 // Nothing should have changed "on disk" since PersistUnsentLogs hasn't been
217 EXPECT_EQ(2U, pref_service
.TypeCount(MetricsLog::ONGOING_LOG
));
218 // Persist, and make sure nothing is left.
219 log_manager
.PersistUnsentLogs();
220 EXPECT_EQ(0U, pref_service
.TypeCount(MetricsLog::INITIAL_STABILITY_LOG
));
221 EXPECT_EQ(0U, pref_service
.TypeCount(MetricsLog::ONGOING_LOG
));
225 TEST(MetricsLogManagerTest
, StoreStagedLogTypes
) {
226 TestMetricsServiceClient client
;
228 // Ensure that types are preserved when storing staged logs.
230 TestLogPrefService pref_service
;
231 MetricsLogManager
log_manager(&pref_service
, 0);
232 log_manager
.LoadPersistedUnsentLogs();
234 log_manager
.BeginLoggingWithLog(make_scoped_ptr(new MetricsLog(
235 "id", 0, MetricsLog::ONGOING_LOG
, &client
, &pref_service
)));
236 log_manager
.FinishCurrentLog();
237 log_manager
.StageNextLogForUpload();
238 log_manager
.PersistUnsentLogs();
240 EXPECT_EQ(0U, pref_service
.TypeCount(MetricsLog::INITIAL_STABILITY_LOG
));
241 EXPECT_EQ(1U, pref_service
.TypeCount(MetricsLog::ONGOING_LOG
));
245 TestLogPrefService pref_service
;
246 MetricsLogManager
log_manager(&pref_service
, 0);
247 log_manager
.LoadPersistedUnsentLogs();
249 log_manager
.BeginLoggingWithLog(make_scoped_ptr(new MetricsLog(
250 "id", 0, MetricsLog::INITIAL_STABILITY_LOG
, &client
, &pref_service
)));
251 log_manager
.FinishCurrentLog();
252 log_manager
.StageNextLogForUpload();
253 log_manager
.PersistUnsentLogs();
255 EXPECT_EQ(1U, pref_service
.TypeCount(MetricsLog::INITIAL_STABILITY_LOG
));
256 EXPECT_EQ(0U, pref_service
.TypeCount(MetricsLog::ONGOING_LOG
));
260 TEST(MetricsLogManagerTest
, LargeLogDiscarding
) {
261 TestMetricsServiceClient client
;
262 TestLogPrefService pref_service
;
263 // Set the size threshold very low, to verify that it's honored.
264 MetricsLogManager
log_manager(&pref_service
, 1);
265 log_manager
.LoadPersistedUnsentLogs();
267 log_manager
.BeginLoggingWithLog(make_scoped_ptr(new MetricsLog(
268 "id", 0, MetricsLog::INITIAL_STABILITY_LOG
, &client
, &pref_service
)));
269 log_manager
.FinishCurrentLog();
270 log_manager
.BeginLoggingWithLog(make_scoped_ptr(new MetricsLog(
271 "id", 0, MetricsLog::ONGOING_LOG
, &client
, &pref_service
)));
272 log_manager
.FinishCurrentLog();
274 // Only the ongoing log should be written out, due to the threshold.
275 log_manager
.PersistUnsentLogs();
276 EXPECT_EQ(1U, pref_service
.TypeCount(MetricsLog::INITIAL_STABILITY_LOG
));
277 EXPECT_EQ(0U, pref_service
.TypeCount(MetricsLog::ONGOING_LOG
));
280 TEST(MetricsLogManagerTest
, DiscardOrder
) {
281 // Ensure that the correct log is discarded if new logs are pushed while
283 TestMetricsServiceClient client
;
285 TestLogPrefService pref_service
;
286 MetricsLogManager
log_manager(&pref_service
, 0);
287 log_manager
.LoadPersistedUnsentLogs();
289 log_manager
.BeginLoggingWithLog(make_scoped_ptr(new MetricsLog(
290 "id", 0, MetricsLog::INITIAL_STABILITY_LOG
, &client
, &pref_service
)));
291 log_manager
.FinishCurrentLog();
292 log_manager
.BeginLoggingWithLog(make_scoped_ptr(new MetricsLog(
293 "id", 0, MetricsLog::ONGOING_LOG
, &client
, &pref_service
)));
294 log_manager
.StageNextLogForUpload();
295 log_manager
.FinishCurrentLog();
296 log_manager
.DiscardStagedLog();
298 log_manager
.PersistUnsentLogs();
299 EXPECT_EQ(0U, pref_service
.TypeCount(MetricsLog::INITIAL_STABILITY_LOG
));
300 EXPECT_EQ(1U, pref_service
.TypeCount(MetricsLog::ONGOING_LOG
));
304 } // namespace metrics