Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / common / metrics / metrics_log_manager_unittest.cc
blobd5facdfe69f71a62172ee1e8c2af2339d9cac9e3
1 // Copyright (c) 2012 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 "chrome/common/metrics/metrics_log_manager.h"
7 #include <string>
8 #include <utility>
9 #include <vector>
11 #include "base/sha1.h"
12 #include "chrome/common/metrics/metrics_log_base.h"
13 #include "testing/gtest/include/gtest/gtest.h"
15 namespace {
17 // Dummy serializer that just stores logs in memory.
18 class DummyLogSerializer : public MetricsLogManager::LogSerializer {
19 public:
20 virtual void SerializeLogs(
21 const std::vector<MetricsLogManager::SerializedLog>& logs,
22 MetricsLogManager::LogType log_type) OVERRIDE {
23 persisted_logs_[log_type] = logs;
26 virtual void DeserializeLogs(
27 MetricsLogManager::LogType log_type,
28 std::vector<MetricsLogManager::SerializedLog>* logs) OVERRIDE {
29 ASSERT_NE(static_cast<void*>(NULL), logs);
30 *logs = persisted_logs_[log_type];
33 // Returns the number of logs of the given type.
34 size_t TypeCount(MetricsLogManager::LogType log_type) {
35 return persisted_logs_[log_type].size();
38 // In-memory "persitent storage".
39 std::vector<MetricsLogManager::SerializedLog> persisted_logs_[2];
42 } // namespace
44 TEST(MetricsLogManagerTest, StandardFlow) {
45 MetricsLogManager log_manager;
47 // Make sure a new manager has a clean slate.
48 EXPECT_EQ(NULL, log_manager.current_log());
49 EXPECT_FALSE(log_manager.has_staged_log());
50 EXPECT_FALSE(log_manager.has_unsent_logs());
52 // Check that the normal flow works.
53 MetricsLogBase* initial_log = new MetricsLogBase("id", 0, "version");
54 log_manager.BeginLoggingWithLog(initial_log, MetricsLogBase::INITIAL_LOG);
55 EXPECT_EQ(initial_log, log_manager.current_log());
56 EXPECT_FALSE(log_manager.has_staged_log());
58 log_manager.FinishCurrentLog();
59 EXPECT_EQ(NULL, log_manager.current_log());
60 EXPECT_TRUE(log_manager.has_unsent_logs());
61 EXPECT_FALSE(log_manager.has_staged_log());
63 MetricsLogBase* second_log = new MetricsLogBase("id", 0, "version");
64 log_manager.BeginLoggingWithLog(second_log, MetricsLogBase::ONGOING_LOG);
65 EXPECT_EQ(second_log, log_manager.current_log());
67 log_manager.StageNextLogForUpload();
68 EXPECT_TRUE(log_manager.has_staged_log());
69 EXPECT_FALSE(log_manager.staged_log_text().empty());
71 log_manager.DiscardStagedLog();
72 EXPECT_EQ(second_log, log_manager.current_log());
73 EXPECT_FALSE(log_manager.has_staged_log());
74 EXPECT_FALSE(log_manager.has_unsent_logs());
75 EXPECT_TRUE(log_manager.staged_log_text().empty());
77 EXPECT_FALSE(log_manager.has_unsent_logs());
80 TEST(MetricsLogManagerTest, AbandonedLog) {
81 MetricsLogManager log_manager;
83 MetricsLogBase* dummy_log = new MetricsLogBase("id", 0, "version");
84 log_manager.BeginLoggingWithLog(dummy_log, MetricsLogBase::INITIAL_LOG);
85 EXPECT_EQ(dummy_log, log_manager.current_log());
87 log_manager.DiscardCurrentLog();
88 EXPECT_EQ(NULL, log_manager.current_log());
89 EXPECT_FALSE(log_manager.has_staged_log());
92 TEST(MetricsLogManagerTest, InterjectedLog) {
93 MetricsLogManager log_manager;
95 MetricsLogBase* ongoing_log = new MetricsLogBase("id", 0, "version");
96 MetricsLogBase* temp_log = new MetricsLogBase("id", 0, "version");
98 log_manager.BeginLoggingWithLog(ongoing_log, MetricsLogBase::ONGOING_LOG);
99 EXPECT_EQ(ongoing_log, log_manager.current_log());
101 log_manager.PauseCurrentLog();
102 EXPECT_EQ(NULL, log_manager.current_log());
104 log_manager.BeginLoggingWithLog(temp_log, MetricsLogBase::INITIAL_LOG);
105 EXPECT_EQ(temp_log, log_manager.current_log());
106 log_manager.FinishCurrentLog();
107 EXPECT_EQ(NULL, log_manager.current_log());
109 log_manager.ResumePausedLog();
110 EXPECT_EQ(ongoing_log, log_manager.current_log());
112 EXPECT_FALSE(log_manager.has_staged_log());
113 log_manager.StageNextLogForUpload();
114 log_manager.DiscardStagedLog();
115 EXPECT_FALSE(log_manager.has_unsent_logs());
118 TEST(MetricsLogManagerTest, InterjectedLogPreservesType) {
119 MetricsLogManager log_manager;
120 DummyLogSerializer* serializer = new DummyLogSerializer;
121 log_manager.set_log_serializer(serializer);
122 log_manager.LoadPersistedUnsentLogs();
124 MetricsLogBase* ongoing_log = new MetricsLogBase("id", 0, "version");
125 MetricsLogBase* temp_log = new MetricsLogBase("id", 0, "version");
127 log_manager.BeginLoggingWithLog(ongoing_log, MetricsLogBase::ONGOING_LOG);
128 log_manager.PauseCurrentLog();
129 log_manager.BeginLoggingWithLog(temp_log, MetricsLogBase::INITIAL_LOG);
130 log_manager.FinishCurrentLog();
131 log_manager.ResumePausedLog();
132 log_manager.StageNextLogForUpload();
133 log_manager.DiscardStagedLog();
135 // Verify that the remaining log (which is the original ongoing log) still
136 // has the right type.
137 log_manager.FinishCurrentLog();
138 log_manager.PersistUnsentLogs();
139 EXPECT_EQ(0U, serializer->TypeCount(MetricsLogBase::INITIAL_LOG));
140 EXPECT_EQ(1U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
143 TEST(MetricsLogManagerTest, StoreAndLoad) {
144 std::vector<MetricsLogManager::SerializedLog> initial_logs;
145 std::vector<MetricsLogManager::SerializedLog> ongoing_logs;
147 // Set up some in-progress logging in a scoped log manager simulating the
148 // leadup to quitting, then persist as would be done on quit.
150 MetricsLogManager log_manager;
151 DummyLogSerializer* serializer = new DummyLogSerializer;
152 log_manager.set_log_serializer(serializer);
153 log_manager.LoadPersistedUnsentLogs();
155 // Simulate a log having already been unsent from a previous session.
156 MetricsLogManager::SerializedLog log;
157 std::string text = "proto";
158 log.SwapLogText(&text);
159 serializer->persisted_logs_[MetricsLogBase::ONGOING_LOG].push_back(log);
160 EXPECT_FALSE(log_manager.has_unsent_logs());
161 log_manager.LoadPersistedUnsentLogs();
162 EXPECT_TRUE(log_manager.has_unsent_logs());
164 MetricsLogBase* log1 = new MetricsLogBase("id", 0, "version");
165 MetricsLogBase* log2 = new MetricsLogBase("id", 0, "version");
166 log_manager.BeginLoggingWithLog(log1, MetricsLogBase::INITIAL_LOG);
167 log_manager.FinishCurrentLog();
168 log_manager.BeginLoggingWithLog(log2, MetricsLogBase::ONGOING_LOG);
169 log_manager.StageNextLogForUpload();
170 log_manager.StoreStagedLogAsUnsent(MetricsLogManager::NORMAL_STORE);
171 log_manager.FinishCurrentLog();
173 // Nothing should be written out until PersistUnsentLogs is called.
174 EXPECT_EQ(0U, serializer->TypeCount(MetricsLogBase::INITIAL_LOG));
175 EXPECT_EQ(1U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
176 log_manager.PersistUnsentLogs();
177 EXPECT_EQ(1U, serializer->TypeCount(MetricsLogBase::INITIAL_LOG));
178 EXPECT_EQ(2U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
180 // Save the logs to transfer over to a new serializer (since log_manager
181 // owns |serializer|, so it's about to go away.
182 initial_logs = serializer->persisted_logs_[MetricsLogBase::INITIAL_LOG];
183 ongoing_logs = serializer->persisted_logs_[MetricsLogBase::ONGOING_LOG];
186 // Now simulate the relaunch, ensure that the log manager restores
187 // everything correctly, and verify that once the are handled they are not
188 // re-persisted.
190 MetricsLogManager log_manager;
192 DummyLogSerializer* serializer = new DummyLogSerializer;
193 serializer->persisted_logs_[MetricsLogBase::INITIAL_LOG] = initial_logs;
194 serializer->persisted_logs_[MetricsLogBase::ONGOING_LOG] = ongoing_logs;
196 log_manager.set_log_serializer(serializer);
197 log_manager.LoadPersistedUnsentLogs();
198 EXPECT_TRUE(log_manager.has_unsent_logs());
200 log_manager.StageNextLogForUpload();
201 log_manager.DiscardStagedLog();
202 // The initial log should be sent first; update the persisted storage to
203 // verify.
204 log_manager.PersistUnsentLogs();
205 EXPECT_EQ(0U, serializer->TypeCount(MetricsLogBase::INITIAL_LOG));
206 EXPECT_EQ(2U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
208 // Handle the first ongoing log.
209 log_manager.StageNextLogForUpload();
210 log_manager.DiscardStagedLog();
211 EXPECT_TRUE(log_manager.has_unsent_logs());
213 // Handle the last log.
214 log_manager.StageNextLogForUpload();
215 log_manager.DiscardStagedLog();
216 EXPECT_FALSE(log_manager.has_unsent_logs());
218 // Nothing should have changed "on disk" since PersistUnsentLogs hasn't been
219 // called again.
220 EXPECT_EQ(2U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
221 // Persist, and make sure nothing is left.
222 log_manager.PersistUnsentLogs();
223 EXPECT_EQ(0U, serializer->TypeCount(MetricsLogBase::INITIAL_LOG));
224 EXPECT_EQ(0U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
228 TEST(MetricsLogManagerTest, StoreStagedLogTypes) {
229 // Ensure that types are preserved when storing staged logs.
231 MetricsLogManager log_manager;
232 DummyLogSerializer* serializer = new DummyLogSerializer;
233 log_manager.set_log_serializer(serializer);
234 log_manager.LoadPersistedUnsentLogs();
236 MetricsLogBase* log = new MetricsLogBase("id", 0, "version");
237 log_manager.BeginLoggingWithLog(log, MetricsLogBase::ONGOING_LOG);
238 log_manager.FinishCurrentLog();
239 log_manager.StageNextLogForUpload();
240 log_manager.StoreStagedLogAsUnsent(MetricsLogManager::NORMAL_STORE);
241 log_manager.PersistUnsentLogs();
243 EXPECT_EQ(0U, serializer->TypeCount(MetricsLogBase::INITIAL_LOG));
244 EXPECT_EQ(1U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
248 MetricsLogManager log_manager;
249 DummyLogSerializer* serializer = new DummyLogSerializer;
250 log_manager.set_log_serializer(serializer);
251 log_manager.LoadPersistedUnsentLogs();
253 MetricsLogBase* log = new MetricsLogBase("id", 0, "version");
254 log_manager.BeginLoggingWithLog(log, MetricsLogBase::INITIAL_LOG);
255 log_manager.FinishCurrentLog();
256 log_manager.StageNextLogForUpload();
257 log_manager.StoreStagedLogAsUnsent(MetricsLogManager::NORMAL_STORE);
258 log_manager.PersistUnsentLogs();
260 EXPECT_EQ(1U, serializer->TypeCount(MetricsLogBase::INITIAL_LOG));
261 EXPECT_EQ(0U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
265 TEST(MetricsLogManagerTest, LargeLogDiscarding) {
266 MetricsLogManager log_manager;
267 DummyLogSerializer* serializer = new DummyLogSerializer;
268 log_manager.set_log_serializer(serializer);
269 log_manager.LoadPersistedUnsentLogs();
271 // Set the size threshold very low, to verify that it's honored.
272 log_manager.set_max_ongoing_log_store_size(1);
274 MetricsLogBase* log1 = new MetricsLogBase("id", 0, "version");
275 MetricsLogBase* log2 = new MetricsLogBase("id", 0, "version");
276 log_manager.BeginLoggingWithLog(log1, MetricsLogBase::INITIAL_LOG);
277 log_manager.FinishCurrentLog();
278 log_manager.BeginLoggingWithLog(log2, MetricsLogBase::ONGOING_LOG);
279 log_manager.FinishCurrentLog();
281 // Only the ongoing log should be written out, due to the threshold.
282 log_manager.PersistUnsentLogs();
283 EXPECT_EQ(1U, serializer->TypeCount(MetricsLogBase::INITIAL_LOG));
284 EXPECT_EQ(0U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
287 TEST(MetricsLogManagerTest, ProvisionalStoreStandardFlow) {
288 // Ensure that provisional store works, and discards the correct log.
290 MetricsLogManager log_manager;
291 DummyLogSerializer* serializer = new DummyLogSerializer;
292 log_manager.set_log_serializer(serializer);
293 log_manager.LoadPersistedUnsentLogs();
295 MetricsLogBase* log1 = new MetricsLogBase("id", 0, "version");
296 MetricsLogBase* log2 = new MetricsLogBase("id", 0, "version");
297 log_manager.BeginLoggingWithLog(log1, MetricsLogBase::INITIAL_LOG);
298 log_manager.FinishCurrentLog();
299 log_manager.BeginLoggingWithLog(log2, MetricsLogBase::ONGOING_LOG);
300 log_manager.StageNextLogForUpload();
301 log_manager.StoreStagedLogAsUnsent(MetricsLogManager::PROVISIONAL_STORE);
302 log_manager.FinishCurrentLog();
303 log_manager.DiscardLastProvisionalStore();
305 log_manager.PersistUnsentLogs();
306 EXPECT_EQ(0U, serializer->TypeCount(MetricsLogBase::INITIAL_LOG));
307 EXPECT_EQ(1U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
311 TEST(MetricsLogManagerTest, ProvisionalStoreNoop) {
312 // Ensure that trying to drop a sent log is a no-op, even if another log has
313 // since been staged.
315 MetricsLogManager log_manager;
316 DummyLogSerializer* serializer = new DummyLogSerializer;
317 log_manager.set_log_serializer(serializer);
318 log_manager.LoadPersistedUnsentLogs();
320 MetricsLogBase* log1 = new MetricsLogBase("id", 0, "version");
321 MetricsLogBase* log2 = new MetricsLogBase("id", 0, "version");
322 log_manager.BeginLoggingWithLog(log1, MetricsLogBase::ONGOING_LOG);
323 log_manager.FinishCurrentLog();
324 log_manager.StageNextLogForUpload();
325 log_manager.StoreStagedLogAsUnsent(MetricsLogManager::PROVISIONAL_STORE);
326 log_manager.StageNextLogForUpload();
327 log_manager.DiscardStagedLog();
328 log_manager.BeginLoggingWithLog(log2, MetricsLogBase::ONGOING_LOG);
329 log_manager.FinishCurrentLog();
330 log_manager.StageNextLogForUpload();
331 log_manager.StoreStagedLogAsUnsent(MetricsLogManager::NORMAL_STORE);
332 log_manager.DiscardLastProvisionalStore();
334 log_manager.PersistUnsentLogs();
335 EXPECT_EQ(1U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
338 // Ensure that trying to drop more than once is a no-op
340 MetricsLogManager log_manager;
341 DummyLogSerializer* serializer = new DummyLogSerializer;
342 log_manager.set_log_serializer(serializer);
343 log_manager.LoadPersistedUnsentLogs();
345 MetricsLogBase* log1 = new MetricsLogBase("id", 0, "version");
346 MetricsLogBase* log2 = new MetricsLogBase("id", 0, "version");
347 log_manager.BeginLoggingWithLog(log1, MetricsLogBase::ONGOING_LOG);
348 log_manager.FinishCurrentLog();
349 log_manager.StageNextLogForUpload();
350 log_manager.StoreStagedLogAsUnsent(MetricsLogManager::NORMAL_STORE);
351 log_manager.BeginLoggingWithLog(log2, MetricsLogBase::ONGOING_LOG);
352 log_manager.FinishCurrentLog();
353 log_manager.StageNextLogForUpload();
354 log_manager.StoreStagedLogAsUnsent(MetricsLogManager::PROVISIONAL_STORE);
355 log_manager.DiscardLastProvisionalStore();
356 log_manager.DiscardLastProvisionalStore();
358 log_manager.PersistUnsentLogs();
359 EXPECT_EQ(1U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
363 TEST(MetricsLogManagerTest, SerializedLog) {
364 const char kFooText[] = "foo";
365 const std::string foo_hash = base::SHA1HashString(kFooText);
366 const char kBarText[] = "bar";
367 const std::string bar_hash = base::SHA1HashString(kBarText);
369 MetricsLogManager::SerializedLog log;
370 EXPECT_TRUE(log.log_text().empty());
371 EXPECT_TRUE(log.log_hash().empty());
373 std::string foo = kFooText;
374 log.SwapLogText(&foo);
375 EXPECT_TRUE(foo.empty());
376 EXPECT_FALSE(log.IsEmpty());
377 EXPECT_EQ(kFooText, log.log_text());
378 EXPECT_EQ(foo_hash, log.log_hash());
380 std::string bar = kBarText;
381 log.SwapLogText(&bar);
382 EXPECT_EQ(kFooText, bar);
383 EXPECT_FALSE(log.IsEmpty());
384 EXPECT_EQ(kBarText, log.log_text());
385 EXPECT_EQ(bar_hash, log.log_hash());
387 log.Clear();
388 EXPECT_TRUE(log.IsEmpty());
389 EXPECT_TRUE(log.log_text().empty());
390 EXPECT_TRUE(log.log_hash().empty());
392 MetricsLogManager::SerializedLog log2;
393 foo = kFooText;
394 log2.SwapLogText(&foo);
395 log.Swap(&log2);
396 EXPECT_FALSE(log.IsEmpty());
397 EXPECT_EQ(kFooText, log.log_text());
398 EXPECT_EQ(foo_hash, log.log_hash());
399 EXPECT_TRUE(log2.IsEmpty());
400 EXPECT_TRUE(log2.log_text().empty());
401 EXPECT_TRUE(log2.log_hash().empty());