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 "base/base64.h"
7 #include "base/values.h"
8 #include "chrome/browser/metrics/metrics_log_serializer.h"
9 #include "testing/gtest/include/gtest/gtest.h"
13 const size_t kListLengthLimit
= 3;
14 const size_t kLogByteLimit
= 1000;
16 void SetLogText(const std::string
& log_text
,
17 MetricsLogManager::SerializedLog
* log
) {
18 std::string log_text_copy
= log_text
;
19 log
->SwapLogText(&log_text_copy
);
24 // Store and retrieve empty list.
25 TEST(MetricsLogSerializerTest
, EmptyLogList
) {
27 std::vector
<MetricsLogManager::SerializedLog
> local_list
;
29 MetricsLogSerializer::WriteLogsToPrefList(local_list
, kListLengthLimit
,
30 kLogByteLimit
, &list
);
31 EXPECT_EQ(0U, list
.GetSize());
33 local_list
.clear(); // ReadLogsFromPrefList() expects empty |local_list|.
35 MetricsLogSerializer::LIST_EMPTY
,
36 MetricsLogSerializer::ReadLogsFromPrefList(list
, &local_list
));
37 EXPECT_EQ(0U, local_list
.size());
40 // Store and retrieve a single log value.
41 TEST(MetricsLogSerializerTest
, SingleElementLogList
) {
44 std::vector
<MetricsLogManager::SerializedLog
> local_list(1);
45 SetLogText("Hello world!", &local_list
[0]);
47 MetricsLogSerializer::WriteLogsToPrefList(local_list
, kListLengthLimit
,
48 kLogByteLimit
, &list
);
50 // |list| will now contain the following:
51 // [1, Base64Encode("Hello world!"), MD5("Hello world!")].
52 ASSERT_EQ(3U, list
.GetSize());
54 // Examine each element.
55 base::ListValue::const_iterator it
= list
.begin();
57 (*it
)->GetAsInteger(&size
);
62 (*it
)->GetAsString(&str
); // Base64 encoded "Hello world!" string.
64 base::Base64Encode("Hello world!", &encoded
);
65 EXPECT_TRUE(encoded
== str
);
68 (*it
)->GetAsString(&str
); // MD5 for encoded "Hello world!" string.
69 EXPECT_TRUE(base::MD5String(encoded
) == str
);
72 EXPECT_TRUE(it
== list
.end()); // Reached end of list.
76 MetricsLogSerializer::RECALL_SUCCESS
,
77 MetricsLogSerializer::ReadLogsFromPrefList(list
, &local_list
));
78 EXPECT_EQ(1U, local_list
.size());
81 // Store a set of logs over the length limit, but smaller than the min number of
83 TEST(MetricsLogSerializerTest
, LongButTinyLogList
) {
86 size_t log_count
= kListLengthLimit
* 5;
87 std::vector
<MetricsLogManager::SerializedLog
> local_list(log_count
);
88 for (size_t i
= 0; i
< local_list
.size(); ++i
)
89 SetLogText("x", &local_list
[i
]);
91 MetricsLogSerializer::WriteLogsToPrefList(local_list
, kListLengthLimit
,
92 kLogByteLimit
, &list
);
93 std::vector
<MetricsLogManager::SerializedLog
> result_list
;
95 MetricsLogSerializer::RECALL_SUCCESS
,
96 MetricsLogSerializer::ReadLogsFromPrefList(list
, &result_list
));
97 EXPECT_EQ(local_list
.size(), result_list
.size());
99 EXPECT_TRUE(result_list
.front().log_text().find("x") == 0);
102 // Store a set of logs over the length limit, but that doesn't reach the minimum
103 // number of bytes until after passing the length limit.
104 TEST(MetricsLogSerializerTest
, LongButSmallLogList
) {
105 base::ListValue list
;
107 size_t log_count
= kListLengthLimit
* 5;
108 // Make log_count logs each slightly larger than
109 // kLogByteLimit / (log_count - 2)
110 // so that the minimum is reached before the oldest (first) two logs.
111 std::vector
<MetricsLogManager::SerializedLog
> local_list(log_count
);
112 size_t log_size
= (kLogByteLimit
/ (log_count
- 2)) + 2;
113 SetLogText("one", &local_list
[0]);
114 SetLogText("two", &local_list
[1]);
115 SetLogText("three", &local_list
[2]);
116 SetLogText("last", &local_list
[log_count
- 1]);
117 for (size_t i
= 0; i
< local_list
.size(); ++i
) {
118 std::string log_text
= local_list
[i
].log_text();
119 log_text
.resize(log_size
, ' ');
120 local_list
[i
].SwapLogText(&log_text
);
123 MetricsLogSerializer::WriteLogsToPrefList(local_list
, kListLengthLimit
,
124 kLogByteLimit
, &list
);
125 std::vector
<MetricsLogManager::SerializedLog
> result_list
;
127 MetricsLogSerializer::RECALL_SUCCESS
,
128 MetricsLogSerializer::ReadLogsFromPrefList(list
, &result_list
));
129 EXPECT_EQ(local_list
.size() - 2, result_list
.size());
131 EXPECT_TRUE(result_list
.front().log_text().find("three") == 0);
132 EXPECT_TRUE(result_list
.back().log_text().find("last") == 0);
135 // Store a set of logs within the length limit, but well over the minimum
137 TEST(MetricsLogSerializerTest
, ShortButLargeLogList
) {
138 base::ListValue list
;
140 std::vector
<MetricsLogManager::SerializedLog
> local_list(kListLengthLimit
);
141 // Make the total byte count about twice the minimum.
142 size_t log_size
= (kLogByteLimit
/ local_list
.size()) * 2;
143 for (size_t i
= 0; i
< local_list
.size(); ++i
) {
144 std::string log_text
= local_list
[i
].log_text();
145 log_text
.resize(log_size
, ' ');
146 local_list
[i
].SwapLogText(&log_text
);
149 MetricsLogSerializer::WriteLogsToPrefList(local_list
, kListLengthLimit
,
150 kLogByteLimit
, &list
);
151 std::vector
<MetricsLogManager::SerializedLog
> result_list
;
153 MetricsLogSerializer::RECALL_SUCCESS
,
154 MetricsLogSerializer::ReadLogsFromPrefList(list
, &result_list
));
155 EXPECT_EQ(local_list
.size(), result_list
.size());
158 // Store a set of logs over the length limit, and over the minimum number of
160 TEST(MetricsLogSerializerTest
, LongAndLargeLogList
) {
161 base::ListValue list
;
163 // Include twice the max number of logs.
164 std::vector
<MetricsLogManager::SerializedLog
>
165 local_list(kListLengthLimit
* 2);
166 // Make the total byte count about four times the minimum.
167 size_t log_size
= (kLogByteLimit
/ local_list
.size()) * 4;
168 SetLogText("First to keep",
169 &local_list
[local_list
.size() - kListLengthLimit
]);
170 for (size_t i
= 0; i
< local_list
.size(); ++i
) {
171 std::string log_text
= local_list
[i
].log_text();
172 log_text
.resize(log_size
, ' ');
173 local_list
[i
].SwapLogText(&log_text
);
176 MetricsLogSerializer::WriteLogsToPrefList(local_list
, kListLengthLimit
,
177 kLogByteLimit
, &list
);
178 std::vector
<MetricsLogManager::SerializedLog
> result_list
;
180 MetricsLogSerializer::RECALL_SUCCESS
,
181 MetricsLogSerializer::ReadLogsFromPrefList(list
, &result_list
));
182 // The max length should control the resulting size.
183 EXPECT_EQ(kListLengthLimit
, result_list
.size());
184 EXPECT_TRUE(result_list
.front().log_text().find("First to keep") == 0);
187 // Induce LIST_SIZE_TOO_SMALL corruption
188 TEST(MetricsLogSerializerTest
, SmallRecoveredListSize
) {
189 base::ListValue list
;
191 std::vector
<MetricsLogManager::SerializedLog
> local_list(1);
192 SetLogText("Hello world!", &local_list
[0]);
194 MetricsLogSerializer::WriteLogsToPrefList(local_list
, kListLengthLimit
,
195 kLogByteLimit
, &list
);
196 EXPECT_EQ(3U, list
.GetSize());
198 // Remove last element.
199 list
.Remove(list
.GetSize() - 1, NULL
);
200 EXPECT_EQ(2U, list
.GetSize());
204 MetricsLogSerializer::LIST_SIZE_TOO_SMALL
,
205 MetricsLogSerializer::ReadLogsFromPrefList(list
, &local_list
));
208 // Remove size from the stored list.
209 TEST(MetricsLogSerializerTest
, RemoveSizeFromLogList
) {
210 base::ListValue list
;
212 std::vector
<MetricsLogManager::SerializedLog
> local_list(2);
213 SetLogText("one", &local_list
[0]);
214 SetLogText("two", &local_list
[1]);
215 EXPECT_EQ(2U, local_list
.size());
216 MetricsLogSerializer::WriteLogsToPrefList(local_list
, kListLengthLimit
,
217 kLogByteLimit
, &list
);
218 EXPECT_EQ(4U, list
.GetSize());
220 list
.Remove(0, NULL
); // Delete size (1st element).
221 EXPECT_EQ(3U, list
.GetSize());
225 MetricsLogSerializer::LIST_SIZE_MISSING
,
226 MetricsLogSerializer::ReadLogsFromPrefList(list
, &local_list
));
229 // Corrupt size of stored list.
230 TEST(MetricsLogSerializerTest
, CorruptSizeOfLogList
) {
231 base::ListValue list
;
233 std::vector
<MetricsLogManager::SerializedLog
> local_list(1);
234 SetLogText("Hello world!", &local_list
[0]);
236 MetricsLogSerializer::WriteLogsToPrefList(local_list
, kListLengthLimit
,
237 kLogByteLimit
, &list
);
238 EXPECT_EQ(3U, list
.GetSize());
240 // Change list size from 1 to 2.
241 EXPECT_TRUE(list
.Set(0, base::Value::CreateIntegerValue(2)));
242 EXPECT_EQ(3U, list
.GetSize());
246 MetricsLogSerializer::LIST_SIZE_CORRUPTION
,
247 MetricsLogSerializer::ReadLogsFromPrefList(list
, &local_list
));
250 // Corrupt checksum of stored list.
251 TEST(MetricsLogSerializerTest
, CorruptChecksumOfLogList
) {
252 base::ListValue list
;
254 std::vector
<MetricsLogManager::SerializedLog
> local_list(1);
255 SetLogText("Hello world!", &local_list
[0]);
257 MetricsLogSerializer::WriteLogsToPrefList(local_list
, kListLengthLimit
,
258 kLogByteLimit
, &list
);
259 EXPECT_EQ(3U, list
.GetSize());
261 // Fetch checksum (last element) and change it.
262 std::string checksum
;
263 EXPECT_TRUE((*(list
.end() - 1))->GetAsString(&checksum
));
264 checksum
[0] = (checksum
[0] == 'a') ? 'b' : 'a';
265 EXPECT_TRUE(list
.Set(2, base::Value::CreateStringValue(checksum
)));
266 EXPECT_EQ(3U, list
.GetSize());
270 MetricsLogSerializer::CHECKSUM_CORRUPTION
,
271 MetricsLogSerializer::ReadLogsFromPrefList(list
, &local_list
));