blob: 43695406f7badbbc4bbe50da59c0c13ee84a6c7c [file] [log] [blame]
[email protected]2e4cd1a2012-01-12 08:51:031// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]cac267c2011-09-29 15:18:102// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]fe58acc22012-02-29 01:29:585#include <string>
6#include <utility>
7#include <vector>
8
[email protected]e182be02012-01-27 02:35:449#include "chrome/common/metrics/metrics_log_base.h"
[email protected]2e4cd1a2012-01-12 08:51:0310#include "chrome/common/metrics/metrics_log_manager.h"
[email protected]cac267c2011-09-29 15:18:1011#include "testing/gtest/include/gtest/gtest.h"
12
[email protected]fe58acc22012-02-29 01:29:5813typedef MetricsLogManager::SerializedLog SerializedLog;
[email protected]cac267c2011-09-29 15:18:1014
15namespace {
[email protected]fe58acc22012-02-29 01:29:5816
[email protected]cac267c2011-09-29 15:18:1017class MetricsLogManagerTest : public testing::Test {
18};
19
20// Dummy serializer that just stores logs in memory.
21class DummyLogSerializer : public MetricsLogManager::LogSerializer {
22 public:
[email protected]fe58acc22012-02-29 01:29:5823 virtual void SerializeLogs(const std::vector<SerializedLog>& logs,
[email protected]cac267c2011-09-29 15:18:1024 MetricsLogManager::LogType log_type) {
25 persisted_logs_[log_type] = logs;
26 }
27
28 virtual void DeserializeLogs(MetricsLogManager::LogType log_type,
[email protected]fe58acc22012-02-29 01:29:5829 std::vector<SerializedLog>* logs) {
[email protected]cac267c2011-09-29 15:18:1030 ASSERT_NE(static_cast<void*>(NULL), logs);
31 *logs = persisted_logs_[log_type];
32 }
33
34 // Returns the number of logs of the given type.
35 size_t TypeCount(MetricsLogManager::LogType log_type) {
36 return persisted_logs_[log_type].size();
37 }
38
39 // In-memory "persitent storage".
[email protected]fe58acc22012-02-29 01:29:5840 std::vector<SerializedLog> persisted_logs_[2];
[email protected]cac267c2011-09-29 15:18:1041};
[email protected]fe58acc22012-02-29 01:29:5842
43} // namespace
[email protected]cac267c2011-09-29 15:18:1044
45TEST(MetricsLogManagerTest, StandardFlow) {
46 MetricsLogManager log_manager;
47
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());
52
53 // Check that the normal flow works.
54 MetricsLogBase* initial_log = new MetricsLogBase("id", 0, "version");
[email protected]29948262012-03-01 12:15:0855 log_manager.BeginLoggingWithLog(initial_log, MetricsLogManager::INITIAL_LOG);
[email protected]cac267c2011-09-29 15:18:1056 EXPECT_EQ(initial_log, log_manager.current_log());
57 EXPECT_FALSE(log_manager.has_staged_log());
58
[email protected]29948262012-03-01 12:15:0859 log_manager.FinishCurrentLog();
[email protected]cac267c2011-09-29 15:18:1060 EXPECT_EQ(NULL, log_manager.current_log());
[email protected]29948262012-03-01 12:15:0861 EXPECT_TRUE(log_manager.has_unsent_logs());
62 EXPECT_FALSE(log_manager.has_staged_log());
[email protected]cac267c2011-09-29 15:18:1063
64 MetricsLogBase* second_log = new MetricsLogBase("id", 0, "version");
[email protected]29948262012-03-01 12:15:0865 log_manager.BeginLoggingWithLog(second_log, MetricsLogManager::ONGOING_LOG);
[email protected]cac267c2011-09-29 15:18:1066 EXPECT_EQ(second_log, log_manager.current_log());
[email protected]29948262012-03-01 12:15:0867
68 log_manager.StageNextLogForUpload();
[email protected]cac267c2011-09-29 15:18:1069 EXPECT_TRUE(log_manager.has_staged_log());
[email protected]29948262012-03-01 12:15:0870 EXPECT_FALSE(log_manager.staged_log_text().empty());
[email protected]cac267c2011-09-29 15:18:1071
72 log_manager.DiscardStagedLog();
73 EXPECT_EQ(second_log, log_manager.current_log());
74 EXPECT_FALSE(log_manager.has_staged_log());
[email protected]29948262012-03-01 12:15:0875 EXPECT_FALSE(log_manager.has_unsent_logs());
[email protected]cac267c2011-09-29 15:18:1076 EXPECT_TRUE(log_manager.staged_log_text().empty());
77
78 EXPECT_FALSE(log_manager.has_unsent_logs());
79}
80
81TEST(MetricsLogManagerTest, AbandonedLog) {
82 MetricsLogManager log_manager;
83
84 MetricsLogBase* dummy_log = new MetricsLogBase("id", 0, "version");
[email protected]29948262012-03-01 12:15:0885 log_manager.BeginLoggingWithLog(dummy_log, MetricsLogManager::INITIAL_LOG);
[email protected]cac267c2011-09-29 15:18:1086 EXPECT_EQ(dummy_log, log_manager.current_log());
87
88 log_manager.DiscardCurrentLog();
89 EXPECT_EQ(NULL, log_manager.current_log());
90 EXPECT_FALSE(log_manager.has_staged_log());
91}
92
93TEST(MetricsLogManagerTest, InterjectedLog) {
94 MetricsLogManager log_manager;
95
96 MetricsLogBase* ongoing_log = new MetricsLogBase("id", 0, "version");
97 MetricsLogBase* temp_log = new MetricsLogBase("id", 0, "version");
98
[email protected]29948262012-03-01 12:15:0899 log_manager.BeginLoggingWithLog(ongoing_log, MetricsLogManager::ONGOING_LOG);
[email protected]cac267c2011-09-29 15:18:10100 EXPECT_EQ(ongoing_log, log_manager.current_log());
101
102 log_manager.PauseCurrentLog();
103 EXPECT_EQ(NULL, log_manager.current_log());
104
[email protected]29948262012-03-01 12:15:08105 log_manager.BeginLoggingWithLog(temp_log, MetricsLogManager::INITIAL_LOG);
[email protected]cac267c2011-09-29 15:18:10106 EXPECT_EQ(temp_log, log_manager.current_log());
[email protected]29948262012-03-01 12:15:08107 log_manager.FinishCurrentLog();
[email protected]cac267c2011-09-29 15:18:10108 EXPECT_EQ(NULL, log_manager.current_log());
[email protected]cac267c2011-09-29 15:18:10109
110 log_manager.ResumePausedLog();
111 EXPECT_EQ(ongoing_log, log_manager.current_log());
[email protected]cac267c2011-09-29 15:18:10112
[email protected]29948262012-03-01 12:15:08113 EXPECT_FALSE(log_manager.has_staged_log());
114 log_manager.StageNextLogForUpload();
115 log_manager.DiscardStagedLog();
[email protected]cac267c2011-09-29 15:18:10116 EXPECT_FALSE(log_manager.has_unsent_logs());
117}
118
[email protected]aa752c3f2012-04-27 22:31:51119TEST(MetricsLogManagerTest, InterjectedLogPreservesType) {
120 MetricsLogManager log_manager;
121
122 MetricsLogBase* ongoing_log = new MetricsLogBase("id", 0, "version");
123 MetricsLogBase* temp_log = new MetricsLogBase("id", 0, "version");
124
125 log_manager.BeginLoggingWithLog(ongoing_log, MetricsLogManager::ONGOING_LOG);
126 log_manager.PauseCurrentLog();
127 log_manager.BeginLoggingWithLog(temp_log, MetricsLogManager::INITIAL_LOG);
128 log_manager.FinishCurrentLog();
129 log_manager.ResumePausedLog();
130 log_manager.StageNextLogForUpload();
131 log_manager.DiscardStagedLog();
132
133 // Verify that the remaining log (which is the original ongoing log) still
134 // has the right type.
135 DummyLogSerializer* serializer = new DummyLogSerializer;
136 log_manager.set_log_serializer(serializer);
137 log_manager.FinishCurrentLog();
138 log_manager.PersistUnsentLogs();
139 EXPECT_EQ(0U, serializer->TypeCount(MetricsLogManager::INITIAL_LOG));
140 EXPECT_EQ(1U, serializer->TypeCount(MetricsLogManager::ONGOING_LOG));
141}
142
[email protected]cac267c2011-09-29 15:18:10143TEST(MetricsLogManagerTest, StoreAndLoad) {
[email protected]fe58acc22012-02-29 01:29:58144 std::vector<SerializedLog> initial_logs;
145 std::vector<SerializedLog> ongoing_logs;
[email protected]cac267c2011-09-29 15:18:10146
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.
149 {
150 MetricsLogManager log_manager;
151 DummyLogSerializer* serializer = new DummyLogSerializer;
152 log_manager.set_log_serializer(serializer);
153 // Simulate a log having already been unsent from a previous session.
[email protected]fe58acc22012-02-29 01:29:58154 SerializedLog log = {"xml", "proto"};
155 serializer->persisted_logs_[MetricsLogManager::ONGOING_LOG].push_back(log);
[email protected]cac267c2011-09-29 15:18:10156 EXPECT_FALSE(log_manager.has_unsent_logs());
157 log_manager.LoadPersistedUnsentLogs();
158 EXPECT_TRUE(log_manager.has_unsent_logs());
159
160 MetricsLogBase* log1 = new MetricsLogBase("id", 0, "version");
161 MetricsLogBase* log2 = new MetricsLogBase("id", 0, "version");
[email protected]29948262012-03-01 12:15:08162 log_manager.BeginLoggingWithLog(log1, MetricsLogManager::INITIAL_LOG);
163 log_manager.FinishCurrentLog();
164 log_manager.BeginLoggingWithLog(log2, MetricsLogManager::ONGOING_LOG);
165 log_manager.StageNextLogForUpload();
166 log_manager.StoreStagedLogAsUnsent();
167 log_manager.FinishCurrentLog();
[email protected]cac267c2011-09-29 15:18:10168
169 // Nothing should be written out until PersistUnsentLogs is called.
170 EXPECT_EQ(0U, serializer->TypeCount(MetricsLogManager::INITIAL_LOG));
171 EXPECT_EQ(1U, serializer->TypeCount(MetricsLogManager::ONGOING_LOG));
172 log_manager.PersistUnsentLogs();
173 EXPECT_EQ(1U, serializer->TypeCount(MetricsLogManager::INITIAL_LOG));
174 EXPECT_EQ(2U, serializer->TypeCount(MetricsLogManager::ONGOING_LOG));
175
176 // Save the logs to transfer over to a new serializer (since log_manager
177 // owns |serializer|, so it's about to go away.
178 initial_logs = serializer->persisted_logs_[MetricsLogManager::INITIAL_LOG];
179 ongoing_logs = serializer->persisted_logs_[MetricsLogManager::ONGOING_LOG];
180 }
181
182 // Now simulate the relaunch, ensure that the log manager restores
183 // everything correctly, and verify that once the are handled they are not
184 // re-persisted.
185 {
186 MetricsLogManager log_manager;
187
188 DummyLogSerializer* serializer = new DummyLogSerializer;
189 serializer->persisted_logs_[MetricsLogManager::INITIAL_LOG] = initial_logs;
190 serializer->persisted_logs_[MetricsLogManager::ONGOING_LOG] = ongoing_logs;
191
192 log_manager.set_log_serializer(serializer);
193 log_manager.LoadPersistedUnsentLogs();
194 EXPECT_TRUE(log_manager.has_unsent_logs());
195
[email protected]29948262012-03-01 12:15:08196 log_manager.StageNextLogForUpload();
[email protected]cac267c2011-09-29 15:18:10197 log_manager.DiscardStagedLog();
198 // The initial log should be sent first; update the persisted storage to
199 // verify.
200 log_manager.PersistUnsentLogs();
201 EXPECT_EQ(0U, serializer->TypeCount(MetricsLogManager::INITIAL_LOG));
202 EXPECT_EQ(2U, serializer->TypeCount(MetricsLogManager::ONGOING_LOG));
203
204 // Handle the first ongoing log.
[email protected]29948262012-03-01 12:15:08205 log_manager.StageNextLogForUpload();
[email protected]cac267c2011-09-29 15:18:10206 log_manager.DiscardStagedLog();
207 EXPECT_TRUE(log_manager.has_unsent_logs());
208
209 // Handle the last log.
[email protected]29948262012-03-01 12:15:08210 log_manager.StageNextLogForUpload();
[email protected]cac267c2011-09-29 15:18:10211 log_manager.DiscardStagedLog();
212 EXPECT_FALSE(log_manager.has_unsent_logs());
213
214 // Nothing should have changed "on disk" since PersistUnsentLogs hasn't been
215 // called again.
216 EXPECT_EQ(2U, serializer->TypeCount(MetricsLogManager::ONGOING_LOG));
217 // Persist, and make sure nothing is left.
218 log_manager.PersistUnsentLogs();
219 EXPECT_EQ(0U, serializer->TypeCount(MetricsLogManager::INITIAL_LOG));
220 EXPECT_EQ(0U, serializer->TypeCount(MetricsLogManager::ONGOING_LOG));
221 }
222}
223
[email protected]f829cc362012-03-10 10:09:16224TEST(MetricsLogManagerTest, StoreStagedLogTypes) {
225 // Ensure that types are preserved when storing staged logs.
226 {
227 MetricsLogManager log_manager;
228 DummyLogSerializer* serializer = new DummyLogSerializer;
229 log_manager.set_log_serializer(serializer);
230
231 MetricsLogBase* log = new MetricsLogBase("id", 0, "version");
232 log_manager.BeginLoggingWithLog(log, MetricsLogManager::ONGOING_LOG);
233 log_manager.FinishCurrentLog();
234 log_manager.StageNextLogForUpload();
235 log_manager.StoreStagedLogAsUnsent();
236 log_manager.PersistUnsentLogs();
237
238 EXPECT_EQ(0U, serializer->TypeCount(MetricsLogManager::INITIAL_LOG));
239 EXPECT_EQ(1U, serializer->TypeCount(MetricsLogManager::ONGOING_LOG));
240 }
241
242 {
243 MetricsLogManager log_manager;
244 DummyLogSerializer* serializer = new DummyLogSerializer;
245 log_manager.set_log_serializer(serializer);
246
247 MetricsLogBase* log = new MetricsLogBase("id", 0, "version");
248 log_manager.BeginLoggingWithLog(log, MetricsLogManager::INITIAL_LOG);
249 log_manager.FinishCurrentLog();
250 log_manager.StageNextLogForUpload();
251 log_manager.StoreStagedLogAsUnsent();
252 log_manager.PersistUnsentLogs();
253
254 EXPECT_EQ(1U, serializer->TypeCount(MetricsLogManager::INITIAL_LOG));
255 EXPECT_EQ(0U, serializer->TypeCount(MetricsLogManager::ONGOING_LOG));
256 }
257}
258
[email protected]cac267c2011-09-29 15:18:10259TEST(MetricsLogManagerTest, LargeLogDiscarding) {
260 MetricsLogManager log_manager;
261 DummyLogSerializer* serializer = new DummyLogSerializer;
262 log_manager.set_log_serializer(serializer);
263 // Set the size threshold very low, to verify that it's honored.
264 log_manager.set_max_ongoing_log_store_size(1);
265
266 MetricsLogBase* log1 = new MetricsLogBase("id", 0, "version");
267 MetricsLogBase* log2 = new MetricsLogBase("id", 0, "version");
[email protected]29948262012-03-01 12:15:08268 log_manager.BeginLoggingWithLog(log1, MetricsLogManager::INITIAL_LOG);
269 log_manager.FinishCurrentLog();
270 log_manager.BeginLoggingWithLog(log2, MetricsLogManager::ONGOING_LOG);
271 log_manager.FinishCurrentLog();
[email protected]cac267c2011-09-29 15:18:10272
273 // Only the ongoing log should be written out, due to the threshold.
274 log_manager.PersistUnsentLogs();
275 EXPECT_EQ(1U, serializer->TypeCount(MetricsLogManager::INITIAL_LOG));
276 EXPECT_EQ(0U, serializer->TypeCount(MetricsLogManager::ONGOING_LOG));
277}