Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(997)

Side by Side Diff: chrome/common/metrics/metrics_log_manager_unittest.cc

Issue 239093004: Move part of metrics from chrome/common to components (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Adding TBR section for owners of minor changes. Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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.
4
5 #include "chrome/common/metrics/metrics_log_manager.h"
6
7 #include <string>
8 #include <utility>
9 #include <vector>
10
11 #include "base/sha1.h"
12 #include "chrome/common/metrics/metrics_log_base.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 namespace {
16
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;
24 }
25
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];
31 }
32
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();
36 }
37
38 // In-memory "persitent storage".
39 std::vector<MetricsLogManager::SerializedLog> persisted_logs_[2];
40 };
41
42 } // namespace
43
44 TEST(MetricsLogManagerTest, StandardFlow) {
45 MetricsLogManager log_manager;
46
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());
51
52 // Check that the normal flow works.
53 MetricsLogBase* initial_log =
54 new MetricsLogBase("id", 0, MetricsLogBase::INITIAL_STABILITY_LOG, "v");
55 log_manager.BeginLoggingWithLog(initial_log);
56 EXPECT_EQ(initial_log, log_manager.current_log());
57 EXPECT_FALSE(log_manager.has_staged_log());
58
59 log_manager.FinishCurrentLog();
60 EXPECT_EQ(NULL, log_manager.current_log());
61 EXPECT_TRUE(log_manager.has_unsent_logs());
62 EXPECT_FALSE(log_manager.has_staged_log());
63
64 MetricsLogBase* second_log =
65 new MetricsLogBase("id", 0, MetricsLogBase::ONGOING_LOG, "version");
66 log_manager.BeginLoggingWithLog(second_log);
67 EXPECT_EQ(second_log, log_manager.current_log());
68
69 log_manager.StageNextLogForUpload();
70 EXPECT_TRUE(log_manager.has_staged_log());
71 EXPECT_FALSE(log_manager.staged_log_text().empty());
72
73 log_manager.DiscardStagedLog();
74 EXPECT_EQ(second_log, log_manager.current_log());
75 EXPECT_FALSE(log_manager.has_staged_log());
76 EXPECT_FALSE(log_manager.has_unsent_logs());
77 EXPECT_TRUE(log_manager.staged_log_text().empty());
78
79 EXPECT_FALSE(log_manager.has_unsent_logs());
80 }
81
82 TEST(MetricsLogManagerTest, AbandonedLog) {
83 MetricsLogManager log_manager;
84
85 MetricsLogBase* dummy_log =
86 new MetricsLogBase("id", 0, MetricsLogBase::INITIAL_STABILITY_LOG, "v");
87 log_manager.BeginLoggingWithLog(dummy_log);
88 EXPECT_EQ(dummy_log, log_manager.current_log());
89
90 log_manager.DiscardCurrentLog();
91 EXPECT_EQ(NULL, log_manager.current_log());
92 EXPECT_FALSE(log_manager.has_staged_log());
93 }
94
95 TEST(MetricsLogManagerTest, InterjectedLog) {
96 MetricsLogManager log_manager;
97
98 MetricsLogBase* ongoing_log =
99 new MetricsLogBase("id", 0, MetricsLogBase::ONGOING_LOG, "v");
100 MetricsLogBase* temp_log =
101 new MetricsLogBase("id", 0, MetricsLogBase::INITIAL_STABILITY_LOG, "v");
102
103 log_manager.BeginLoggingWithLog(ongoing_log);
104 EXPECT_EQ(ongoing_log, log_manager.current_log());
105
106 log_manager.PauseCurrentLog();
107 EXPECT_EQ(NULL, log_manager.current_log());
108
109 log_manager.BeginLoggingWithLog(temp_log);
110 EXPECT_EQ(temp_log, log_manager.current_log());
111 log_manager.FinishCurrentLog();
112 EXPECT_EQ(NULL, log_manager.current_log());
113
114 log_manager.ResumePausedLog();
115 EXPECT_EQ(ongoing_log, log_manager.current_log());
116
117 EXPECT_FALSE(log_manager.has_staged_log());
118 log_manager.StageNextLogForUpload();
119 log_manager.DiscardStagedLog();
120 EXPECT_FALSE(log_manager.has_unsent_logs());
121 }
122
123 TEST(MetricsLogManagerTest, InterjectedLogPreservesType) {
124 MetricsLogManager log_manager;
125 DummyLogSerializer* serializer = new DummyLogSerializer;
126 log_manager.set_log_serializer(serializer);
127 log_manager.LoadPersistedUnsentLogs();
128
129 MetricsLogBase* ongoing_log =
130 new MetricsLogBase("id", 0, MetricsLogBase::ONGOING_LOG, "v");
131 MetricsLogBase* temp_log =
132 new MetricsLogBase("id", 0, MetricsLogBase::INITIAL_STABILITY_LOG, "v");
133
134 log_manager.BeginLoggingWithLog(ongoing_log);
135 log_manager.PauseCurrentLog();
136 log_manager.BeginLoggingWithLog(temp_log);
137 log_manager.FinishCurrentLog();
138 log_manager.ResumePausedLog();
139 log_manager.StageNextLogForUpload();
140 log_manager.DiscardStagedLog();
141
142 // Verify that the remaining log (which is the original ongoing log) still
143 // has the right type.
144 log_manager.FinishCurrentLog();
145 log_manager.PersistUnsentLogs();
146 EXPECT_EQ(0U, serializer->TypeCount(MetricsLogBase::INITIAL_STABILITY_LOG));
147 EXPECT_EQ(1U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
148 }
149
150 TEST(MetricsLogManagerTest, StoreAndLoad) {
151 std::vector<MetricsLogManager::SerializedLog> initial_logs;
152 std::vector<MetricsLogManager::SerializedLog> ongoing_logs;
153
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.
156 {
157 MetricsLogManager log_manager;
158 DummyLogSerializer* serializer = new DummyLogSerializer;
159 log_manager.set_log_serializer(serializer);
160 log_manager.LoadPersistedUnsentLogs();
161
162 // Simulate a log having already been unsent from a previous session.
163 MetricsLogManager::SerializedLog log;
164 std::string text = "proto";
165 log.SwapLogText(&text);
166 serializer->persisted_logs_[MetricsLogBase::ONGOING_LOG].push_back(log);
167 EXPECT_FALSE(log_manager.has_unsent_logs());
168 log_manager.LoadPersistedUnsentLogs();
169 EXPECT_TRUE(log_manager.has_unsent_logs());
170
171 MetricsLogBase* log1 =
172 new MetricsLogBase("id", 0, MetricsLogBase::INITIAL_STABILITY_LOG, "v");
173 MetricsLogBase* log2 =
174 new MetricsLogBase("id", 0, MetricsLogBase::ONGOING_LOG, "v");
175 log_manager.BeginLoggingWithLog(log1);
176 log_manager.FinishCurrentLog();
177 log_manager.BeginLoggingWithLog(log2);
178 log_manager.StageNextLogForUpload();
179 log_manager.StoreStagedLogAsUnsent(MetricsLogManager::NORMAL_STORE);
180 log_manager.FinishCurrentLog();
181
182 // Nothing should be written out until PersistUnsentLogs is called.
183 EXPECT_EQ(0U, serializer->TypeCount(MetricsLogBase::INITIAL_STABILITY_LOG));
184 EXPECT_EQ(1U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
185 log_manager.PersistUnsentLogs();
186 EXPECT_EQ(1U, serializer->TypeCount(MetricsLogBase::INITIAL_STABILITY_LOG));
187 EXPECT_EQ(2U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
188
189 // Save the logs to transfer over to a new serializer (since log_manager
190 // owns |serializer|, so it's about to go away.
191 initial_logs =
192 serializer->persisted_logs_[MetricsLogBase::INITIAL_STABILITY_LOG];
193 ongoing_logs = serializer->persisted_logs_[MetricsLogBase::ONGOING_LOG];
194 }
195
196 // Now simulate the relaunch, ensure that the log manager restores
197 // everything correctly, and verify that once the are handled they are not
198 // re-persisted.
199 {
200 MetricsLogManager log_manager;
201
202 DummyLogSerializer* serializer = new DummyLogSerializer;
203 serializer->persisted_logs_[MetricsLogBase::INITIAL_STABILITY_LOG] =
204 initial_logs;
205 serializer->persisted_logs_[MetricsLogBase::ONGOING_LOG] = ongoing_logs;
206
207 log_manager.set_log_serializer(serializer);
208 log_manager.LoadPersistedUnsentLogs();
209 EXPECT_TRUE(log_manager.has_unsent_logs());
210
211 log_manager.StageNextLogForUpload();
212 log_manager.DiscardStagedLog();
213 // The initial log should be sent first; update the persisted storage to
214 // verify.
215 log_manager.PersistUnsentLogs();
216 EXPECT_EQ(0U, serializer->TypeCount(MetricsLogBase::INITIAL_STABILITY_LOG));
217 EXPECT_EQ(2U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
218
219 // Handle the first ongoing log.
220 log_manager.StageNextLogForUpload();
221 log_manager.DiscardStagedLog();
222 EXPECT_TRUE(log_manager.has_unsent_logs());
223
224 // Handle the last log.
225 log_manager.StageNextLogForUpload();
226 log_manager.DiscardStagedLog();
227 EXPECT_FALSE(log_manager.has_unsent_logs());
228
229 // Nothing should have changed "on disk" since PersistUnsentLogs hasn't been
230 // called again.
231 EXPECT_EQ(2U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
232 // Persist, and make sure nothing is left.
233 log_manager.PersistUnsentLogs();
234 EXPECT_EQ(0U, serializer->TypeCount(MetricsLogBase::INITIAL_STABILITY_LOG));
235 EXPECT_EQ(0U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
236 }
237 }
238
239 TEST(MetricsLogManagerTest, StoreStagedLogTypes) {
240 // Ensure that types are preserved when storing staged logs.
241 {
242 MetricsLogManager log_manager;
243 DummyLogSerializer* serializer = new DummyLogSerializer;
244 log_manager.set_log_serializer(serializer);
245 log_manager.LoadPersistedUnsentLogs();
246
247 MetricsLogBase* log =
248 new MetricsLogBase("id", 0, MetricsLogBase::ONGOING_LOG, "version");
249 log_manager.BeginLoggingWithLog(log);
250 log_manager.FinishCurrentLog();
251 log_manager.StageNextLogForUpload();
252 log_manager.StoreStagedLogAsUnsent(MetricsLogManager::NORMAL_STORE);
253 log_manager.PersistUnsentLogs();
254
255 EXPECT_EQ(0U, serializer->TypeCount(MetricsLogBase::INITIAL_STABILITY_LOG));
256 EXPECT_EQ(1U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
257 }
258
259 {
260 MetricsLogManager log_manager;
261 DummyLogSerializer* serializer = new DummyLogSerializer;
262 log_manager.set_log_serializer(serializer);
263 log_manager.LoadPersistedUnsentLogs();
264
265 MetricsLogBase* log =
266 new MetricsLogBase("id", 0, MetricsLogBase::INITIAL_STABILITY_LOG, "v");
267 log_manager.BeginLoggingWithLog(log);
268 log_manager.FinishCurrentLog();
269 log_manager.StageNextLogForUpload();
270 log_manager.StoreStagedLogAsUnsent(MetricsLogManager::NORMAL_STORE);
271 log_manager.PersistUnsentLogs();
272
273 EXPECT_EQ(1U, serializer->TypeCount(MetricsLogBase::INITIAL_STABILITY_LOG));
274 EXPECT_EQ(0U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
275 }
276 }
277
278 TEST(MetricsLogManagerTest, LargeLogDiscarding) {
279 MetricsLogManager log_manager;
280 DummyLogSerializer* serializer = new DummyLogSerializer;
281 log_manager.set_log_serializer(serializer);
282 log_manager.LoadPersistedUnsentLogs();
283
284 // Set the size threshold very low, to verify that it's honored.
285 log_manager.set_max_ongoing_log_store_size(1);
286
287 MetricsLogBase* log1 =
288 new MetricsLogBase("id", 0, MetricsLogBase::INITIAL_STABILITY_LOG, "v");
289 MetricsLogBase* log2 =
290 new MetricsLogBase("id", 0, MetricsLogBase::ONGOING_LOG, "v");
291 log_manager.BeginLoggingWithLog(log1);
292 log_manager.FinishCurrentLog();
293 log_manager.BeginLoggingWithLog(log2);
294 log_manager.FinishCurrentLog();
295
296 // Only the ongoing log should be written out, due to the threshold.
297 log_manager.PersistUnsentLogs();
298 EXPECT_EQ(1U, serializer->TypeCount(MetricsLogBase::INITIAL_STABILITY_LOG));
299 EXPECT_EQ(0U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
300 }
301
302 TEST(MetricsLogManagerTest, ProvisionalStoreStandardFlow) {
303 // Ensure that provisional store works, and discards the correct log.
304 {
305 MetricsLogManager log_manager;
306 DummyLogSerializer* serializer = new DummyLogSerializer;
307 log_manager.set_log_serializer(serializer);
308 log_manager.LoadPersistedUnsentLogs();
309
310 MetricsLogBase* log1 =
311 new MetricsLogBase("id", 0, MetricsLogBase::INITIAL_STABILITY_LOG, "v");
312 MetricsLogBase* log2 =
313 new MetricsLogBase("id", 0, MetricsLogBase::ONGOING_LOG, "v");
314 log_manager.BeginLoggingWithLog(log1);
315 log_manager.FinishCurrentLog();
316 log_manager.BeginLoggingWithLog(log2);
317 log_manager.StageNextLogForUpload();
318 log_manager.StoreStagedLogAsUnsent(MetricsLogManager::PROVISIONAL_STORE);
319 log_manager.FinishCurrentLog();
320 log_manager.DiscardLastProvisionalStore();
321
322 log_manager.PersistUnsentLogs();
323 EXPECT_EQ(0U, serializer->TypeCount(MetricsLogBase::INITIAL_STABILITY_LOG));
324 EXPECT_EQ(1U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
325 }
326 }
327
328 TEST(MetricsLogManagerTest, ProvisionalStoreNoop) {
329 // Ensure that trying to drop a sent log is a no-op, even if another log has
330 // since been staged.
331 {
332 MetricsLogManager log_manager;
333 DummyLogSerializer* serializer = new DummyLogSerializer;
334 log_manager.set_log_serializer(serializer);
335 log_manager.LoadPersistedUnsentLogs();
336
337 MetricsLogBase* log1 =
338 new MetricsLogBase("id", 0, MetricsLogBase::ONGOING_LOG, "version");
339 MetricsLogBase* log2 =
340 new MetricsLogBase("id", 0, MetricsLogBase::ONGOING_LOG, "version");
341 log_manager.BeginLoggingWithLog(log1);
342 log_manager.FinishCurrentLog();
343 log_manager.StageNextLogForUpload();
344 log_manager.StoreStagedLogAsUnsent(MetricsLogManager::PROVISIONAL_STORE);
345 log_manager.StageNextLogForUpload();
346 log_manager.DiscardStagedLog();
347 log_manager.BeginLoggingWithLog(log2);
348 log_manager.FinishCurrentLog();
349 log_manager.StageNextLogForUpload();
350 log_manager.StoreStagedLogAsUnsent(MetricsLogManager::NORMAL_STORE);
351 log_manager.DiscardLastProvisionalStore();
352
353 log_manager.PersistUnsentLogs();
354 EXPECT_EQ(1U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
355 }
356
357 // Ensure that trying to drop more than once is a no-op
358 {
359 MetricsLogManager log_manager;
360 DummyLogSerializer* serializer = new DummyLogSerializer;
361 log_manager.set_log_serializer(serializer);
362 log_manager.LoadPersistedUnsentLogs();
363
364 MetricsLogBase* log1 =
365 new MetricsLogBase("id", 0, MetricsLogBase::ONGOING_LOG, "version");
366 MetricsLogBase* log2 =
367 new MetricsLogBase("id", 0, MetricsLogBase::ONGOING_LOG, "version");
368 log_manager.BeginLoggingWithLog(log1);
369 log_manager.FinishCurrentLog();
370 log_manager.StageNextLogForUpload();
371 log_manager.StoreStagedLogAsUnsent(MetricsLogManager::NORMAL_STORE);
372 log_manager.BeginLoggingWithLog(log2);
373 log_manager.FinishCurrentLog();
374 log_manager.StageNextLogForUpload();
375 log_manager.StoreStagedLogAsUnsent(MetricsLogManager::PROVISIONAL_STORE);
376 log_manager.DiscardLastProvisionalStore();
377 log_manager.DiscardLastProvisionalStore();
378
379 log_manager.PersistUnsentLogs();
380 EXPECT_EQ(1U, serializer->TypeCount(MetricsLogBase::ONGOING_LOG));
381 }
382 }
383
384 TEST(MetricsLogManagerTest, SerializedLog) {
385 const char kFooText[] = "foo";
386 const std::string foo_hash = base::SHA1HashString(kFooText);
387 const char kBarText[] = "bar";
388 const std::string bar_hash = base::SHA1HashString(kBarText);
389
390 MetricsLogManager::SerializedLog log;
391 EXPECT_TRUE(log.log_text().empty());
392 EXPECT_TRUE(log.log_hash().empty());
393
394 std::string foo = kFooText;
395 log.SwapLogText(&foo);
396 EXPECT_TRUE(foo.empty());
397 EXPECT_FALSE(log.IsEmpty());
398 EXPECT_EQ(kFooText, log.log_text());
399 EXPECT_EQ(foo_hash, log.log_hash());
400
401 std::string bar = kBarText;
402 log.SwapLogText(&bar);
403 EXPECT_EQ(kFooText, bar);
404 EXPECT_FALSE(log.IsEmpty());
405 EXPECT_EQ(kBarText, log.log_text());
406 EXPECT_EQ(bar_hash, log.log_hash());
407
408 log.Clear();
409 EXPECT_TRUE(log.IsEmpty());
410 EXPECT_TRUE(log.log_text().empty());
411 EXPECT_TRUE(log.log_hash().empty());
412
413 MetricsLogManager::SerializedLog log2;
414 foo = kFooText;
415 log2.SwapLogText(&foo);
416 log.Swap(&log2);
417 EXPECT_FALSE(log.IsEmpty());
418 EXPECT_EQ(kFooText, log.log_text());
419 EXPECT_EQ(foo_hash, log.log_hash());
420 EXPECT_TRUE(log2.IsEmpty());
421 EXPECT_TRUE(log2.log_text().empty());
422 EXPECT_TRUE(log2.log_hash().empty());
423 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698