OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/base64.h" | 5 #include "components/metrics/persisted_logs.h" |
6 #include "base/md5.h" | 6 |
7 #include "base/prefs/pref_registry_simple.h" | 7 #include "base/prefs/pref_registry_simple.h" |
8 #include "base/prefs/scoped_user_pref_update.h" | 8 #include "base/prefs/scoped_user_pref_update.h" |
9 #include "base/prefs/testing_pref_service.h" | 9 #include "base/prefs/testing_pref_service.h" |
10 #include "base/rand_util.h" | |
10 #include "base/sha1.h" | 11 #include "base/sha1.h" |
11 #include "base/values.h" | 12 #include "base/values.h" |
12 #include "components/metrics/persisted_logs.h" | 13 #include "components/metrics/compression_utils.h" |
13 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
14 | 15 |
15 namespace metrics { | 16 namespace metrics { |
16 | 17 |
17 namespace { | 18 namespace { |
18 | 19 |
19 const char kTestPrefName[] = "TestPref"; | 20 const char kTestPrefName[] = "TestPref"; |
21 const char kTestOldPrefName[] = "TestPrefOld"; | |
20 const size_t kLogCountLimit = 3; | 22 const size_t kLogCountLimit = 3; |
21 const size_t kLogByteLimit = 1000; | 23 const size_t kLogByteLimit = 1000; |
22 | 24 |
25 // Compresses |log_data| and returns the result. | |
26 std::string Compress(const std::string& log_data) { | |
27 std::string compressed_log_data; | |
28 EXPECT_TRUE(GzipCompress(log_data, &compressed_log_data)); | |
29 return compressed_log_data; | |
30 } | |
31 | |
32 // Generates and returns log data such that its size after compression is at | |
33 // least |min_compressed_size|. | |
34 std::string GenerateLogWithMinCompressedSize(size_t min_compressed_size) { | |
35 // Since the size check is done against a compressed log, generate enough | |
36 // data that compresses to larger than |log_size|. | |
37 std::string rand_bytes = base::RandBytesAsString(min_compressed_size); | |
38 while (Compress(rand_bytes).size() < min_compressed_size) | |
39 rand_bytes.append(base::RandBytesAsString(min_compressed_size)); | |
40 return rand_bytes; | |
41 } | |
Ilya Sherman
2014/06/09 23:17:00
Please make sure to log random inputs on failure,
Alexei Svitkine (slow)
2014/06/10 17:01:15
Done.
| |
23 | 42 |
24 class PersistedLogsTest : public testing::Test { | 43 class PersistedLogsTest : public testing::Test { |
25 public: | 44 public: |
26 PersistedLogsTest() { | 45 PersistedLogsTest() { |
27 prefs_.registry()->RegisterListPref(kTestPrefName); | 46 prefs_.registry()->RegisterListPref(kTestPrefName); |
47 prefs_.registry()->RegisterListPref(kTestOldPrefName); | |
28 } | 48 } |
29 | 49 |
30 protected: | 50 protected: |
31 TestingPrefServiceSimple prefs_; | 51 TestingPrefServiceSimple prefs_; |
32 | 52 |
33 private: | 53 private: |
34 DISALLOW_COPY_AND_ASSIGN(PersistedLogsTest); | 54 DISALLOW_COPY_AND_ASSIGN(PersistedLogsTest); |
35 }; | 55 }; |
36 | 56 |
37 class TestPersistedLogs : public PersistedLogs { | 57 class TestPersistedLogs : public PersistedLogs { |
38 public: | 58 public: |
39 TestPersistedLogs(PrefService* service) | 59 explicit TestPersistedLogs(PrefService* service) |
40 : PersistedLogs(service, kTestPrefName, kLogCountLimit, kLogByteLimit, 0) { | 60 : PersistedLogs(service, kTestPrefName, kTestOldPrefName, kLogCountLimit, |
41 } | 61 kLogByteLimit, 0) { |
62 } | |
42 | 63 |
43 // Make a copy of the string and store the copy. | 64 TestPersistedLogs(PrefService* service, size_t min_log_bytes) |
44 void StoreLogCopy(std::string tmp) { | 65 : PersistedLogs(service, kTestPrefName, kTestOldPrefName, kLogCountLimit, |
45 StoreLog(&tmp); | 66 min_log_bytes, 0) { |
Ilya Sherman
2014/06/09 23:17:00
nit: I'd prefer that we have just a single constru
Alexei Svitkine (slow)
2014/06/10 17:01:15
Done.
| |
46 } | 67 } |
47 | 68 |
48 // Stages and removes the next log, while testing it's value. | 69 // Stages and removes the next log, while testing it's value. |
49 void ExpectNextLog(const std::string& expected_log) { | 70 void ExpectNextLog(const std::string& expected_log) { |
50 StageLog(); | 71 StageLog(); |
51 EXPECT_EQ(staged_log(), expected_log); | 72 EXPECT_EQ(staged_log(), Compress(expected_log)); |
52 DiscardStagedLog(); | 73 DiscardStagedLog(); |
53 } | 74 } |
75 | |
76 private: | |
77 DISALLOW_COPY_AND_ASSIGN(TestPersistedLogs); | |
54 }; | 78 }; |
55 | 79 |
56 } // namespace | 80 } // namespace |
57 | 81 |
58 // Store and retrieve empty list_value. | 82 // Store and retrieve empty list_value. |
59 TEST_F(PersistedLogsTest, EmptyLogList) { | 83 TEST_F(PersistedLogsTest, EmptyLogList) { |
60 TestPersistedLogs persisted_logs(&prefs_); | 84 TestPersistedLogs persisted_logs(&prefs_); |
61 | 85 |
62 persisted_logs.SerializeLogs(); | 86 persisted_logs.SerializeLogs(); |
63 const base::ListValue* list_value = prefs_.GetList(kTestPrefName); | 87 const base::ListValue* list_value = prefs_.GetList(kTestPrefName); |
64 EXPECT_EQ(0U, list_value->GetSize()); | 88 EXPECT_EQ(0U, list_value->GetSize()); |
65 | 89 |
66 TestPersistedLogs result_persisted_logs(&prefs_); | 90 TestPersistedLogs result_persisted_logs(&prefs_); |
67 EXPECT_EQ(PersistedLogs::LIST_EMPTY, result_persisted_logs.DeserializeLogs()); | 91 EXPECT_EQ(PersistedLogs::LIST_EMPTY, result_persisted_logs.DeserializeLogs()); |
68 EXPECT_EQ(0U, result_persisted_logs.size()); | 92 EXPECT_EQ(0U, result_persisted_logs.size()); |
69 } | 93 } |
70 | 94 |
71 // Store and retrieve a single log value. | 95 // Store and retrieve a single log value. |
72 TEST_F(PersistedLogsTest, SingleElementLogList) { | 96 TEST_F(PersistedLogsTest, SingleElementLogList) { |
73 TestPersistedLogs persisted_logs(&prefs_); | 97 TestPersistedLogs persisted_logs(&prefs_); |
74 | 98 |
75 persisted_logs.StoreLogCopy("Hello world!"); | 99 persisted_logs.StoreLog("Hello world!"); |
76 persisted_logs.SerializeLogs(); | 100 persisted_logs.SerializeLogs(); |
77 | 101 |
78 const base::ListValue* list_value = prefs_.GetList(kTestPrefName); | |
79 // |list_value| will now contain the following: | |
80 // [1, Base64Encode("Hello world!"), MD5("Hello world!")]. | |
81 ASSERT_EQ(3U, list_value->GetSize()); | |
82 | |
83 // Examine each element. | |
84 base::ListValue::const_iterator it = list_value->begin(); | |
85 int size = 0; | |
86 (*it)->GetAsInteger(&size); | |
87 EXPECT_EQ(1, size); | |
88 | |
89 ++it; | |
90 std::string str; | |
91 (*it)->GetAsString(&str); // Base64 encoded "Hello world!" string. | |
92 std::string encoded; | |
93 base::Base64Encode("Hello world!", &encoded); | |
94 EXPECT_TRUE(encoded == str); | |
95 | |
96 ++it; | |
97 (*it)->GetAsString(&str); // MD5 for encoded "Hello world!" string. | |
98 EXPECT_TRUE(base::MD5String(encoded) == str); | |
99 | |
100 ++it; | |
101 EXPECT_TRUE(it == list_value->end()); // Reached end of list_value. | |
102 | |
103 TestPersistedLogs result_persisted_logs(&prefs_); | 102 TestPersistedLogs result_persisted_logs(&prefs_); |
104 EXPECT_EQ(PersistedLogs::RECALL_SUCCESS, | 103 EXPECT_EQ(PersistedLogs::RECALL_SUCCESS, |
105 result_persisted_logs.DeserializeLogs()); | 104 result_persisted_logs.DeserializeLogs()); |
106 EXPECT_EQ(1U, result_persisted_logs.size()); | 105 EXPECT_EQ(1U, result_persisted_logs.size()); |
106 | |
107 // Verify that the result log matches the initial log. | |
108 persisted_logs.StageLog(); | |
109 result_persisted_logs.StageLog(); | |
110 EXPECT_EQ(persisted_logs.staged_log(), result_persisted_logs.staged_log()); | |
111 EXPECT_EQ(persisted_logs.staged_log_hash(), | |
112 result_persisted_logs.staged_log_hash()); | |
107 } | 113 } |
108 | 114 |
109 // Store a set of logs over the length limit, but smaller than the min number of | 115 // Store a set of logs over the length limit, but smaller than the min number of |
110 // bytes. | 116 // bytes. |
111 TEST_F(PersistedLogsTest, LongButTinyLogList) { | 117 TEST_F(PersistedLogsTest, LongButTinyLogList) { |
112 TestPersistedLogs persisted_logs(&prefs_); | 118 TestPersistedLogs persisted_logs(&prefs_); |
113 | 119 |
114 size_t log_count = kLogCountLimit * 5; | 120 size_t log_count = kLogCountLimit * 5; |
115 for (size_t i = 0; i < log_count; ++i) | 121 for (size_t i = 0; i < log_count; ++i) |
116 persisted_logs.StoreLogCopy("x"); | 122 persisted_logs.StoreLog("x"); |
117 | 123 |
118 persisted_logs.SerializeLogs(); | 124 persisted_logs.SerializeLogs(); |
119 | 125 |
120 TestPersistedLogs result_persisted_logs(&prefs_); | 126 TestPersistedLogs result_persisted_logs(&prefs_); |
121 EXPECT_EQ(PersistedLogs::RECALL_SUCCESS, | 127 EXPECT_EQ(PersistedLogs::RECALL_SUCCESS, |
122 result_persisted_logs.DeserializeLogs()); | 128 result_persisted_logs.DeserializeLogs()); |
123 EXPECT_EQ(persisted_logs.size(), result_persisted_logs.size()); | 129 EXPECT_EQ(persisted_logs.size(), result_persisted_logs.size()); |
124 | 130 |
125 result_persisted_logs.ExpectNextLog("x"); | 131 result_persisted_logs.ExpectNextLog("x"); |
126 } | 132 } |
127 | 133 |
128 // Store a set of logs over the length limit, but that doesn't reach the minimum | 134 // Store a set of logs over the length limit, but that doesn't reach the minimum |
129 // number of bytes until after passing the length limit. | 135 // number of bytes until after passing the length limit. |
130 TEST_F(PersistedLogsTest, LongButSmallLogList) { | 136 TEST_F(PersistedLogsTest, LongButSmallLogList) { |
131 TestPersistedLogs persisted_logs(&prefs_); | 137 size_t log_count = kLogCountLimit * 5; |
138 size_t log_size = 50; | |
132 | 139 |
133 // Make log_count logs each slightly larger than | |
134 // kLogByteLimit / (log_count - 2) | |
135 // so that the minimum is reached before the oldest (first) two logs. | |
136 size_t log_count = kLogCountLimit * 5; | |
137 size_t log_size = (kLogByteLimit / (log_count - 2)) + 2; | |
138 persisted_logs.StoreLogCopy("one"); | |
139 persisted_logs.StoreLogCopy("two"); | |
140 std::string first_kept = "First to keep"; | 140 std::string first_kept = "First to keep"; |
141 first_kept.resize(log_size, ' '); | 141 first_kept.resize(log_size, ' '); |
142 persisted_logs.StoreLogCopy(first_kept); | 142 |
143 std::string blank_log = std::string(log_size, ' '); | 143 std::string blank_log = std::string(log_size, ' '); |
144 for (size_t i = persisted_logs.size(); i < log_count - 1; ++i) { | 144 |
145 persisted_logs.StoreLogCopy(blank_log); | |
146 } | |
147 std::string last_kept = "Last to keep"; | 145 std::string last_kept = "Last to keep"; |
148 last_kept.resize(log_size, ' '); | 146 last_kept.resize(log_size, ' '); |
149 persisted_logs.StoreLogCopy(last_kept); | |
150 | 147 |
148 // Set the byte limit enough to keep everything but the first two logs. | |
149 const size_t min_log_bytes = | |
150 Compress(first_kept).length() + Compress(last_kept).length() + | |
151 (log_count - 4) * Compress(blank_log).length(); | |
152 TestPersistedLogs persisted_logs(&prefs_, min_log_bytes); | |
153 | |
154 persisted_logs.StoreLog("one"); | |
155 persisted_logs.StoreLog("two"); | |
156 persisted_logs.StoreLog(first_kept); | |
157 for (size_t i = persisted_logs.size(); i < log_count - 1; ++i) { | |
158 persisted_logs.StoreLog(blank_log); | |
159 } | |
160 persisted_logs.StoreLog(last_kept); | |
151 persisted_logs.SerializeLogs(); | 161 persisted_logs.SerializeLogs(); |
152 | 162 |
153 TestPersistedLogs result_persisted_logs(&prefs_); | 163 TestPersistedLogs result_persisted_logs(&prefs_); |
154 EXPECT_EQ(PersistedLogs::RECALL_SUCCESS, | 164 EXPECT_EQ(PersistedLogs::RECALL_SUCCESS, |
155 result_persisted_logs.DeserializeLogs()); | 165 result_persisted_logs.DeserializeLogs()); |
156 EXPECT_EQ(persisted_logs.size() - 2, result_persisted_logs.size()); | 166 EXPECT_EQ(persisted_logs.size() - 2, result_persisted_logs.size()); |
157 | 167 |
158 result_persisted_logs.ExpectNextLog(last_kept); | 168 result_persisted_logs.ExpectNextLog(last_kept); |
159 while (result_persisted_logs.size() > 1) { | 169 while (result_persisted_logs.size() > 1) { |
160 result_persisted_logs.ExpectNextLog(blank_log); | 170 result_persisted_logs.ExpectNextLog(blank_log); |
161 } | 171 } |
162 result_persisted_logs.ExpectNextLog(first_kept); | 172 result_persisted_logs.ExpectNextLog(first_kept); |
163 } | 173 } |
164 | 174 |
165 // Store a set of logs within the length limit, but well over the minimum | 175 // Store a set of logs within the length limit, but well over the minimum |
166 // number of bytes. | 176 // number of bytes. |
167 TEST_F(PersistedLogsTest, ShortButLargeLogList) { | 177 TEST_F(PersistedLogsTest, ShortButLargeLogList) { |
168 TestPersistedLogs persisted_logs(&prefs_); | |
169 | |
170 // Make the total byte count about twice the minimum. | 178 // Make the total byte count about twice the minimum. |
171 size_t log_count = kLogCountLimit; | 179 size_t log_count = kLogCountLimit; |
172 size_t log_size = (kLogByteLimit / log_count) * 2; | 180 size_t log_size = (kLogByteLimit / log_count) * 2; |
173 std::string blank_log = std::string(log_size, ' '); | 181 std::string log_data = GenerateLogWithMinCompressedSize(log_size); |
182 | |
183 TestPersistedLogs persisted_logs(&prefs_); | |
174 for (size_t i = 0; i < log_count; ++i) { | 184 for (size_t i = 0; i < log_count; ++i) { |
175 persisted_logs.StoreLogCopy(blank_log); | 185 persisted_logs.StoreLog(log_data); |
176 } | 186 } |
177 | |
178 persisted_logs.SerializeLogs(); | 187 persisted_logs.SerializeLogs(); |
179 | 188 |
180 TestPersistedLogs result_persisted_logs(&prefs_); | 189 TestPersistedLogs result_persisted_logs(&prefs_); |
181 EXPECT_EQ(PersistedLogs::RECALL_SUCCESS, | 190 EXPECT_EQ(PersistedLogs::RECALL_SUCCESS, |
182 result_persisted_logs.DeserializeLogs()); | 191 result_persisted_logs.DeserializeLogs()); |
183 EXPECT_EQ(persisted_logs.size(), result_persisted_logs.size()); | 192 EXPECT_EQ(persisted_logs.size(), result_persisted_logs.size()); |
184 } | 193 } |
185 | 194 |
186 // Store a set of logs over the length limit, and over the minimum number of | 195 // Store a set of logs over the length limit, and over the minimum number of |
187 // bytes. | 196 // bytes. |
188 TEST_F(PersistedLogsTest, LongAndLargeLogList) { | 197 TEST_F(PersistedLogsTest, LongAndLargeLogList) { |
189 TestPersistedLogs persisted_logs(&prefs_); | 198 TestPersistedLogs persisted_logs(&prefs_); |
190 | 199 |
191 // Include twice the max number of logs. | 200 // Include twice the max number of logs. |
192 size_t log_count = kLogCountLimit * 2; | 201 size_t log_count = kLogCountLimit * 2; |
193 // Make the total byte count about four times the minimum. | 202 // Make the total byte count about four times the minimum. |
194 size_t log_size = (kLogByteLimit / log_count) * 4; | 203 size_t log_size = (kLogByteLimit / log_count) * 4; |
204 | |
195 std::string target_log = "First to keep"; | 205 std::string target_log = "First to keep"; |
196 target_log.resize(log_size, ' '); | 206 target_log += GenerateLogWithMinCompressedSize(log_size); |
197 std::string blank_log = std::string(log_size, ' '); | 207 |
208 std::string log_data = GenerateLogWithMinCompressedSize(log_size); | |
198 for (size_t i = 0; i < log_count; ++i) { | 209 for (size_t i = 0; i < log_count; ++i) { |
199 if (i == log_count - kLogCountLimit) | 210 if (i == log_count - kLogCountLimit) |
200 persisted_logs.StoreLogCopy(target_log); | 211 persisted_logs.StoreLog(target_log); |
201 else | 212 else |
202 persisted_logs.StoreLogCopy(blank_log); | 213 persisted_logs.StoreLog(log_data); |
203 } | 214 } |
204 | 215 |
205 persisted_logs.SerializeLogs(); | 216 persisted_logs.SerializeLogs(); |
206 | 217 |
207 TestPersistedLogs result_persisted_logs(&prefs_); | 218 TestPersistedLogs result_persisted_logs(&prefs_); |
208 EXPECT_EQ(PersistedLogs::RECALL_SUCCESS, | 219 EXPECT_EQ(PersistedLogs::RECALL_SUCCESS, |
209 result_persisted_logs.DeserializeLogs()); | 220 result_persisted_logs.DeserializeLogs()); |
210 EXPECT_EQ(kLogCountLimit, result_persisted_logs.size()); | 221 EXPECT_EQ(kLogCountLimit, result_persisted_logs.size()); |
211 | 222 |
212 while (result_persisted_logs.size() > 1) { | 223 while (result_persisted_logs.size() > 1) { |
213 result_persisted_logs.ExpectNextLog(blank_log); | 224 result_persisted_logs.ExpectNextLog(log_data); |
214 } | 225 } |
215 result_persisted_logs.ExpectNextLog(target_log); | 226 result_persisted_logs.ExpectNextLog(target_log); |
216 } | 227 } |
217 | 228 |
218 // Induce LIST_SIZE_TOO_SMALL corruption | |
219 TEST_F(PersistedLogsTest, SmallRecoveredListSize) { | |
220 TestPersistedLogs persisted_logs(&prefs_); | |
221 | |
222 persisted_logs.StoreLogCopy("Hello world!"); | |
223 | |
224 persisted_logs.SerializeLogs(); | |
225 | |
226 { | |
227 ListPrefUpdate update(&prefs_, kTestPrefName); | |
228 base::ListValue* list_value = update.Get(); | |
229 EXPECT_EQ(3U, list_value->GetSize()); | |
230 | |
231 // Remove last element. | |
232 list_value->Remove(list_value->GetSize() - 1, NULL); | |
233 EXPECT_EQ(2U, list_value->GetSize()); | |
234 } | |
235 | |
236 TestPersistedLogs result_persisted_logs(&prefs_); | |
237 EXPECT_EQ(PersistedLogs::LIST_SIZE_TOO_SMALL, | |
238 result_persisted_logs.DeserializeLogs()); | |
239 } | |
240 | |
241 // Remove size from the stored list_value. | |
242 TEST_F(PersistedLogsTest, RemoveSizeFromLogList) { | |
243 TestPersistedLogs persisted_logs(&prefs_); | |
244 | |
245 persisted_logs.StoreLogCopy("one"); | |
246 persisted_logs.StoreLogCopy("two"); | |
247 EXPECT_EQ(2U, persisted_logs.size()); | |
248 | |
249 persisted_logs.SerializeLogs(); | |
250 | |
251 { | |
252 ListPrefUpdate update(&prefs_, kTestPrefName); | |
253 base::ListValue* list_value = update.Get(); | |
254 EXPECT_EQ(4U, list_value->GetSize()); | |
255 | |
256 list_value->Remove(0, NULL); // Delete size (1st element). | |
257 EXPECT_EQ(3U, list_value->GetSize()); | |
258 } | |
259 | |
260 TestPersistedLogs result_persisted_logs(&prefs_); | |
261 EXPECT_EQ(PersistedLogs::LIST_SIZE_MISSING, | |
262 result_persisted_logs.DeserializeLogs()); | |
263 } | |
264 | |
265 // Corrupt size of stored list_value. | |
266 TEST_F(PersistedLogsTest, CorruptSizeOfLogList) { | |
267 TestPersistedLogs persisted_logs(&prefs_); | |
268 | |
269 persisted_logs.StoreLogCopy("Hello world!"); | |
270 | |
271 persisted_logs.SerializeLogs(); | |
272 | |
273 { | |
274 ListPrefUpdate update(&prefs_, kTestPrefName); | |
275 base::ListValue* list_value = update.Get(); | |
276 EXPECT_EQ(3U, list_value->GetSize()); | |
277 | |
278 // Change list_value size from 1 to 2. | |
279 EXPECT_TRUE(list_value->Set(0, base::Value::CreateIntegerValue(2))); | |
280 EXPECT_EQ(3U, list_value->GetSize()); | |
281 } | |
282 | |
283 TestPersistedLogs result_persisted_logs(&prefs_); | |
284 EXPECT_EQ(PersistedLogs::LIST_SIZE_CORRUPTION, | |
285 result_persisted_logs.DeserializeLogs()); | |
286 } | |
287 | |
288 // Corrupt checksum of stored list_value. | |
Ilya Sherman
2014/06/09 23:17:00
It's possible to corrupt the hash, right? Should
Alexei Svitkine (slow)
2014/06/10 17:01:15
The new code doesn't check for this. The hash is c
Ilya Sherman
2014/06/10 23:38:39
So it's just checked on the server? I guess that'
Alexei Svitkine (slow)
2014/06/11 00:16:27
Yes that's the plan. We're not dropping just yet (
| |
289 TEST_F(PersistedLogsTest, CorruptChecksumOfLogList) { | |
290 TestPersistedLogs persisted_logs(&prefs_); | |
291 | |
292 persisted_logs.StoreLogCopy("Hello world!"); | |
293 | |
294 persisted_logs.SerializeLogs(); | |
295 | |
296 { | |
297 ListPrefUpdate update(&prefs_, kTestPrefName); | |
298 base::ListValue* list_value = update.Get(); | |
299 EXPECT_EQ(3U, list_value->GetSize()); | |
300 | |
301 // Fetch checksum (last element) and change it. | |
302 std::string checksum; | |
303 EXPECT_TRUE((*(list_value->end() - 1))->GetAsString(&checksum)); | |
304 checksum[0] = (checksum[0] == 'a') ? 'b' : 'a'; | |
305 EXPECT_TRUE(list_value->Set(2, base::Value::CreateStringValue(checksum))); | |
306 EXPECT_EQ(3U, list_value->GetSize()); | |
307 } | |
308 | |
309 TestPersistedLogs result_persisted_logs(&prefs_); | |
310 EXPECT_EQ(PersistedLogs::CHECKSUM_CORRUPTION, | |
311 result_persisted_logs.DeserializeLogs()); | |
312 } | |
313 | |
314 // Check that the store/stage/discard functions work as expected. | 229 // Check that the store/stage/discard functions work as expected. |
315 TEST_F(PersistedLogsTest, Staging) { | 230 TEST_F(PersistedLogsTest, Staging) { |
316 TestPersistedLogs persisted_logs(&prefs_); | 231 TestPersistedLogs persisted_logs(&prefs_); |
317 std::string tmp; | 232 std::string tmp; |
318 | 233 |
319 EXPECT_FALSE(persisted_logs.has_staged_log()); | 234 EXPECT_FALSE(persisted_logs.has_staged_log()); |
320 persisted_logs.StoreLogCopy("one"); | 235 persisted_logs.StoreLog("one"); |
321 EXPECT_FALSE(persisted_logs.has_staged_log()); | 236 EXPECT_FALSE(persisted_logs.has_staged_log()); |
322 persisted_logs.StoreLogCopy("two"); | 237 persisted_logs.StoreLog("two"); |
323 persisted_logs.StageLog(); | 238 persisted_logs.StageLog(); |
324 EXPECT_TRUE(persisted_logs.has_staged_log()); | 239 EXPECT_TRUE(persisted_logs.has_staged_log()); |
325 EXPECT_EQ(persisted_logs.staged_log(), std::string("two")); | 240 EXPECT_EQ(persisted_logs.staged_log(), Compress("two")); |
326 persisted_logs.StoreLogCopy("three"); | 241 persisted_logs.StoreLog("three"); |
327 EXPECT_EQ(persisted_logs.staged_log(), std::string("two")); | 242 EXPECT_EQ(persisted_logs.staged_log(), Compress("two")); |
328 EXPECT_EQ(persisted_logs.size(), 2U); | 243 EXPECT_EQ(persisted_logs.size(), 2U); |
329 persisted_logs.DiscardStagedLog(); | 244 persisted_logs.DiscardStagedLog(); |
330 EXPECT_FALSE(persisted_logs.has_staged_log()); | 245 EXPECT_FALSE(persisted_logs.has_staged_log()); |
331 EXPECT_EQ(persisted_logs.size(), 2U); | 246 EXPECT_EQ(persisted_logs.size(), 2U); |
332 persisted_logs.StageLog(); | 247 persisted_logs.StageLog(); |
333 EXPECT_EQ(persisted_logs.staged_log(), std::string("three")); | 248 EXPECT_EQ(persisted_logs.staged_log(), Compress("three")); |
334 persisted_logs.DiscardStagedLog(); | 249 persisted_logs.DiscardStagedLog(); |
335 persisted_logs.StageLog(); | 250 persisted_logs.StageLog(); |
336 EXPECT_EQ(persisted_logs.staged_log(), std::string("one")); | 251 EXPECT_EQ(persisted_logs.staged_log(), Compress("one")); |
337 persisted_logs.DiscardStagedLog(); | 252 persisted_logs.DiscardStagedLog(); |
338 EXPECT_FALSE(persisted_logs.has_staged_log()); | 253 EXPECT_FALSE(persisted_logs.has_staged_log()); |
339 EXPECT_EQ(persisted_logs.size(), 0U); | 254 EXPECT_EQ(persisted_logs.size(), 0U); |
340 } | 255 } |
341 | 256 |
342 TEST_F(PersistedLogsTest, ProvisionalStoreStandardFlow) { | 257 TEST_F(PersistedLogsTest, ProvisionalStoreStandardFlow) { |
343 // Ensure that provisional store works, and discards the correct log. | 258 // Ensure that provisional store works, and discards the correct log. |
344 TestPersistedLogs persisted_logs(&prefs_); | 259 TestPersistedLogs persisted_logs(&prefs_); |
345 | 260 |
346 persisted_logs.StoreLogCopy("one"); | 261 persisted_logs.StoreLog("one"); |
347 persisted_logs.StageLog(); | 262 persisted_logs.StageLog(); |
348 persisted_logs.StoreStagedLogAsUnsent(PersistedLogs::PROVISIONAL_STORE); | 263 persisted_logs.StoreStagedLogAsUnsent(PersistedLogs::PROVISIONAL_STORE); |
349 persisted_logs.StoreLogCopy("two"); | 264 persisted_logs.StoreLog("two"); |
350 persisted_logs.DiscardLastProvisionalStore(); | 265 persisted_logs.DiscardLastProvisionalStore(); |
351 persisted_logs.SerializeLogs(); | 266 persisted_logs.SerializeLogs(); |
352 | 267 |
353 TestPersistedLogs result_persisted_logs(&prefs_); | 268 TestPersistedLogs result_persisted_logs(&prefs_); |
354 EXPECT_EQ(PersistedLogs::RECALL_SUCCESS, | 269 EXPECT_EQ(PersistedLogs::RECALL_SUCCESS, |
355 result_persisted_logs.DeserializeLogs()); | 270 result_persisted_logs.DeserializeLogs()); |
356 EXPECT_EQ(1U, result_persisted_logs.size()); | 271 EXPECT_EQ(1U, result_persisted_logs.size()); |
357 result_persisted_logs.ExpectNextLog("two"); | 272 result_persisted_logs.ExpectNextLog("two"); |
358 } | 273 } |
359 | 274 |
360 TEST_F(PersistedLogsTest, ProvisionalStoreNoop1) { | 275 TEST_F(PersistedLogsTest, ProvisionalStoreNoop1) { |
361 // Ensure that trying to drop a sent log is a no-op, even if another log has | 276 // Ensure that trying to drop a sent log is a no-op, even if another log has |
362 // since been staged. | 277 // since been staged. |
363 TestPersistedLogs persisted_logs(&prefs_); | 278 TestPersistedLogs persisted_logs(&prefs_); |
364 persisted_logs.DeserializeLogs(); | 279 persisted_logs.DeserializeLogs(); |
365 persisted_logs.StoreLogCopy("one"); | 280 persisted_logs.StoreLog("one"); |
366 persisted_logs.StageLog(); | 281 persisted_logs.StageLog(); |
367 persisted_logs.StoreStagedLogAsUnsent(PersistedLogs::PROVISIONAL_STORE); | 282 persisted_logs.StoreStagedLogAsUnsent(PersistedLogs::PROVISIONAL_STORE); |
368 persisted_logs.StageLog(); | 283 persisted_logs.StageLog(); |
369 persisted_logs.DiscardStagedLog(); | 284 persisted_logs.DiscardStagedLog(); |
370 persisted_logs.StoreLogCopy("two"); | 285 persisted_logs.StoreLog("two"); |
371 persisted_logs.StageLog(); | 286 persisted_logs.StageLog(); |
372 persisted_logs.StoreStagedLogAsUnsent(PersistedLogs::NORMAL_STORE); | 287 persisted_logs.StoreStagedLogAsUnsent(PersistedLogs::NORMAL_STORE); |
373 persisted_logs.DiscardLastProvisionalStore(); | 288 persisted_logs.DiscardLastProvisionalStore(); |
374 persisted_logs.SerializeLogs(); | 289 persisted_logs.SerializeLogs(); |
375 | 290 |
376 TestPersistedLogs result_persisted_logs(&prefs_); | 291 TestPersistedLogs result_persisted_logs(&prefs_); |
377 EXPECT_EQ(PersistedLogs::RECALL_SUCCESS, | 292 EXPECT_EQ(PersistedLogs::RECALL_SUCCESS, |
378 result_persisted_logs.DeserializeLogs()); | 293 result_persisted_logs.DeserializeLogs()); |
379 EXPECT_EQ(1U, result_persisted_logs.size()); | 294 EXPECT_EQ(1U, result_persisted_logs.size()); |
380 result_persisted_logs.ExpectNextLog("two"); | 295 result_persisted_logs.ExpectNextLog("two"); |
381 } | 296 } |
382 | 297 |
383 TEST_F(PersistedLogsTest, ProvisionalStoreNoop2) { | 298 TEST_F(PersistedLogsTest, ProvisionalStoreNoop2) { |
384 // Ensure that trying to drop more than once is a no-op | 299 // Ensure that trying to drop more than once is a no-op |
385 TestPersistedLogs persisted_logs(&prefs_); | 300 TestPersistedLogs persisted_logs(&prefs_); |
386 persisted_logs.DeserializeLogs(); | 301 persisted_logs.DeserializeLogs(); |
387 persisted_logs.StoreLogCopy("one"); | 302 persisted_logs.StoreLog("one"); |
388 persisted_logs.StageLog(); | 303 persisted_logs.StageLog(); |
389 persisted_logs.StoreStagedLogAsUnsent(PersistedLogs::NORMAL_STORE); | 304 persisted_logs.StoreStagedLogAsUnsent(PersistedLogs::NORMAL_STORE); |
390 persisted_logs.StoreLogCopy("two"); | 305 persisted_logs.StoreLog("two"); |
391 persisted_logs.StageLog(); | 306 persisted_logs.StageLog(); |
392 persisted_logs.StoreStagedLogAsUnsent(PersistedLogs::PROVISIONAL_STORE); | 307 persisted_logs.StoreStagedLogAsUnsent(PersistedLogs::PROVISIONAL_STORE); |
393 persisted_logs.DiscardLastProvisionalStore(); | 308 persisted_logs.DiscardLastProvisionalStore(); |
394 persisted_logs.DiscardLastProvisionalStore(); | 309 persisted_logs.DiscardLastProvisionalStore(); |
395 persisted_logs.SerializeLogs(); | 310 persisted_logs.SerializeLogs(); |
396 | 311 |
397 TestPersistedLogs result_persisted_logs(&prefs_); | 312 TestPersistedLogs result_persisted_logs(&prefs_); |
398 EXPECT_EQ(PersistedLogs::RECALL_SUCCESS, | 313 EXPECT_EQ(PersistedLogs::RECALL_SUCCESS, |
399 result_persisted_logs.DeserializeLogs()); | 314 result_persisted_logs.DeserializeLogs()); |
400 EXPECT_EQ(1U, result_persisted_logs.size()); | 315 EXPECT_EQ(1U, result_persisted_logs.size()); |
401 result_persisted_logs.ExpectNextLog("one"); | 316 result_persisted_logs.ExpectNextLog("one"); |
402 } | 317 } |
403 | 318 |
404 TEST_F(PersistedLogsTest, Hashes) { | 319 TEST_F(PersistedLogsTest, Encoding) { |
405 const char kFooText[] = "foo"; | 320 const char kFooText[] = "foo"; |
406 const std::string foo_hash = base::SHA1HashString(kFooText); | 321 const std::string foo_hash = base::SHA1HashString(kFooText); |
407 TestingPrefServiceSimple prefs_; | 322 |
408 prefs_.registry()->RegisterListPref(kTestPrefName); | |
409 TestPersistedLogs persisted_logs(&prefs_); | 323 TestPersistedLogs persisted_logs(&prefs_); |
410 persisted_logs.StoreLogCopy(kFooText); | 324 persisted_logs.StoreLog(kFooText); |
411 persisted_logs.StageLog(); | 325 persisted_logs.StageLog(); |
326 | |
327 EXPECT_EQ(Compress(kFooText), persisted_logs.staged_log()); | |
412 EXPECT_EQ(foo_hash, persisted_logs.staged_log_hash()); | 328 EXPECT_EQ(foo_hash, persisted_logs.staged_log_hash()); |
413 } | 329 } |
414 | 330 |
415 } // namespace metrics | 331 } // namespace metrics |
OLD | NEW |