blob: d8be9671e7054136fc5830df79431cf00eacaa3b [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
119TEST(MetricsLogManagerTest, StoreAndLoad) {
[email protected]fe58acc22012-02-29 01:29:58120 std::vector<SerializedLog> initial_logs;
121 std::vector<SerializedLog> ongoing_logs;
[email protected]cac267c2011-09-29 15:18:10122
123 // Set up some in-progress logging in a scoped log manager simulating the
124 // leadup to quitting, then persist as would be done on quit.
125 {
126 MetricsLogManager log_manager;
127 DummyLogSerializer* serializer = new DummyLogSerializer;
128 log_manager.set_log_serializer(serializer);
129 // Simulate a log having already been unsent from a previous session.
[email protected]fe58acc22012-02-29 01:29:58130 SerializedLog log = {"xml", "proto"};
131 serializer->persisted_logs_[MetricsLogManager::ONGOING_LOG].push_back(log);
[email protected]cac267c2011-09-29 15:18:10132 EXPECT_FALSE(log_manager.has_unsent_logs());
133 log_manager.LoadPersistedUnsentLogs();
134 EXPECT_TRUE(log_manager.has_unsent_logs());
135
136 MetricsLogBase* log1 = new MetricsLogBase("id", 0, "version");
137 MetricsLogBase* log2 = new MetricsLogBase("id", 0, "version");
[email protected]29948262012-03-01 12:15:08138 log_manager.BeginLoggingWithLog(log1, MetricsLogManager::INITIAL_LOG);
139 log_manager.FinishCurrentLog();
140 log_manager.BeginLoggingWithLog(log2, MetricsLogManager::ONGOING_LOG);
141 log_manager.StageNextLogForUpload();
142 log_manager.StoreStagedLogAsUnsent();
143 log_manager.FinishCurrentLog();
[email protected]cac267c2011-09-29 15:18:10144
145 // Nothing should be written out until PersistUnsentLogs is called.
146 EXPECT_EQ(0U, serializer->TypeCount(MetricsLogManager::INITIAL_LOG));
147 EXPECT_EQ(1U, serializer->TypeCount(MetricsLogManager::ONGOING_LOG));
148 log_manager.PersistUnsentLogs();
149 EXPECT_EQ(1U, serializer->TypeCount(MetricsLogManager::INITIAL_LOG));
150 EXPECT_EQ(2U, serializer->TypeCount(MetricsLogManager::ONGOING_LOG));
151
152 // Save the logs to transfer over to a new serializer (since log_manager
153 // owns |serializer|, so it's about to go away.
154 initial_logs = serializer->persisted_logs_[MetricsLogManager::INITIAL_LOG];
155 ongoing_logs = serializer->persisted_logs_[MetricsLogManager::ONGOING_LOG];
156 }
157
158 // Now simulate the relaunch, ensure that the log manager restores
159 // everything correctly, and verify that once the are handled they are not
160 // re-persisted.
161 {
162 MetricsLogManager log_manager;
163
164 DummyLogSerializer* serializer = new DummyLogSerializer;
165 serializer->persisted_logs_[MetricsLogManager::INITIAL_LOG] = initial_logs;
166 serializer->persisted_logs_[MetricsLogManager::ONGOING_LOG] = ongoing_logs;
167
168 log_manager.set_log_serializer(serializer);
169 log_manager.LoadPersistedUnsentLogs();
170 EXPECT_TRUE(log_manager.has_unsent_logs());
171
[email protected]29948262012-03-01 12:15:08172 log_manager.StageNextLogForUpload();
[email protected]cac267c2011-09-29 15:18:10173 log_manager.DiscardStagedLog();
174 // The initial log should be sent first; update the persisted storage to
175 // verify.
176 log_manager.PersistUnsentLogs();
177 EXPECT_EQ(0U, serializer->TypeCount(MetricsLogManager::INITIAL_LOG));
178 EXPECT_EQ(2U, serializer->TypeCount(MetricsLogManager::ONGOING_LOG));
179
180 // Handle the first ongoing log.
[email protected]29948262012-03-01 12:15:08181 log_manager.StageNextLogForUpload();
[email protected]cac267c2011-09-29 15:18:10182 log_manager.DiscardStagedLog();
183 EXPECT_TRUE(log_manager.has_unsent_logs());
184
185 // Handle the last log.
[email protected]29948262012-03-01 12:15:08186 log_manager.StageNextLogForUpload();
[email protected]cac267c2011-09-29 15:18:10187 log_manager.DiscardStagedLog();
188 EXPECT_FALSE(log_manager.has_unsent_logs());
189
190 // Nothing should have changed "on disk" since PersistUnsentLogs hasn't been
191 // called again.
192 EXPECT_EQ(2U, serializer->TypeCount(MetricsLogManager::ONGOING_LOG));
193 // Persist, and make sure nothing is left.
194 log_manager.PersistUnsentLogs();
195 EXPECT_EQ(0U, serializer->TypeCount(MetricsLogManager::INITIAL_LOG));
196 EXPECT_EQ(0U, serializer->TypeCount(MetricsLogManager::ONGOING_LOG));
197 }
198}
199
[email protected]f829cc362012-03-10 10:09:16200TEST(MetricsLogManagerTest, StoreStagedLogTypes) {
201 // Ensure that types are preserved when storing staged logs.
202 {
203 MetricsLogManager log_manager;
204 DummyLogSerializer* serializer = new DummyLogSerializer;
205 log_manager.set_log_serializer(serializer);
206
207 MetricsLogBase* log = new MetricsLogBase("id", 0, "version");
208 log_manager.BeginLoggingWithLog(log, MetricsLogManager::ONGOING_LOG);
209 log_manager.FinishCurrentLog();
210 log_manager.StageNextLogForUpload();
211 log_manager.StoreStagedLogAsUnsent();
212 log_manager.PersistUnsentLogs();
213
214 EXPECT_EQ(0U, serializer->TypeCount(MetricsLogManager::INITIAL_LOG));
215 EXPECT_EQ(1U, serializer->TypeCount(MetricsLogManager::ONGOING_LOG));
216 }
217
218 {
219 MetricsLogManager log_manager;
220 DummyLogSerializer* serializer = new DummyLogSerializer;
221 log_manager.set_log_serializer(serializer);
222
223 MetricsLogBase* log = new MetricsLogBase("id", 0, "version");
224 log_manager.BeginLoggingWithLog(log, MetricsLogManager::INITIAL_LOG);
225 log_manager.FinishCurrentLog();
226 log_manager.StageNextLogForUpload();
227 log_manager.StoreStagedLogAsUnsent();
228 log_manager.PersistUnsentLogs();
229
230 EXPECT_EQ(1U, serializer->TypeCount(MetricsLogManager::INITIAL_LOG));
231 EXPECT_EQ(0U, serializer->TypeCount(MetricsLogManager::ONGOING_LOG));
232 }
233}
234
[email protected]cac267c2011-09-29 15:18:10235TEST(MetricsLogManagerTest, LargeLogDiscarding) {
236 MetricsLogManager log_manager;
237 DummyLogSerializer* serializer = new DummyLogSerializer;
238 log_manager.set_log_serializer(serializer);
239 // Set the size threshold very low, to verify that it's honored.
240 log_manager.set_max_ongoing_log_store_size(1);
241
242 MetricsLogBase* log1 = new MetricsLogBase("id", 0, "version");
243 MetricsLogBase* log2 = new MetricsLogBase("id", 0, "version");
[email protected]29948262012-03-01 12:15:08244 log_manager.BeginLoggingWithLog(log1, MetricsLogManager::INITIAL_LOG);
245 log_manager.FinishCurrentLog();
246 log_manager.BeginLoggingWithLog(log2, MetricsLogManager::ONGOING_LOG);
247 log_manager.FinishCurrentLog();
[email protected]cac267c2011-09-29 15:18:10248
249 // Only the ongoing log should be written out, due to the threshold.
250 log_manager.PersistUnsentLogs();
251 EXPECT_EQ(1U, serializer->TypeCount(MetricsLogManager::INITIAL_LOG));
252 EXPECT_EQ(0U, serializer->TypeCount(MetricsLogManager::ONGOING_LOG));
253}