| 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 "components/metrics/persisted_logs.h" | 5 #include "components/metrics/persisted_logs.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include "base/base64.h" | 9 #include "base/base64.h" |
| 10 #include "base/macros.h" | 10 #include "base/macros.h" |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 : PersistedLogs(std::unique_ptr<PersistedLogsMetricsImpl>( | 67 : PersistedLogs(std::unique_ptr<PersistedLogsMetricsImpl>( |
| 68 new PersistedLogsMetricsImpl()), | 68 new PersistedLogsMetricsImpl()), |
| 69 service, | 69 service, |
| 70 kTestPrefName, | 70 kTestPrefName, |
| 71 kLogCountLimit, | 71 kLogCountLimit, |
| 72 min_log_bytes, | 72 min_log_bytes, |
| 73 0) {} | 73 0) {} |
| 74 | 74 |
| 75 // Stages and removes the next log, while testing it's value. | 75 // Stages and removes the next log, while testing it's value. |
| 76 void ExpectNextLog(const std::string& expected_log) { | 76 void ExpectNextLog(const std::string& expected_log) { |
| 77 StageLog(); | 77 StageNextLog(); |
| 78 EXPECT_EQ(staged_log(), Compress(expected_log)); | 78 EXPECT_EQ(staged_log(), Compress(expected_log)); |
| 79 DiscardStagedLog(); | 79 DiscardStagedLog(); |
| 80 } | 80 } |
| 81 | 81 |
| 82 private: | 82 private: |
| 83 DISALLOW_COPY_AND_ASSIGN(TestPersistedLogs); | 83 DISALLOW_COPY_AND_ASSIGN(TestPersistedLogs); |
| 84 }; | 84 }; |
| 85 | 85 |
| 86 } // namespace | 86 } // namespace |
| 87 | 87 |
| 88 // Store and retrieve empty list_value. | 88 // Store and retrieve empty list_value. |
| 89 TEST_F(PersistedLogsTest, EmptyLogList) { | 89 TEST_F(PersistedLogsTest, EmptyLogList) { |
| 90 TestPersistedLogs persisted_logs(&prefs_, kLogByteLimit); | 90 TestPersistedLogs persisted_logs(&prefs_, kLogByteLimit); |
| 91 | 91 |
| 92 persisted_logs.SerializeLogs(); | 92 persisted_logs.PersistUnsentLogs(); |
| 93 const base::ListValue* list_value = prefs_.GetList(kTestPrefName); | 93 const base::ListValue* list_value = prefs_.GetList(kTestPrefName); |
| 94 EXPECT_EQ(0U, list_value->GetSize()); | 94 EXPECT_EQ(0U, list_value->GetSize()); |
| 95 | 95 |
| 96 TestPersistedLogs result_persisted_logs(&prefs_, kLogByteLimit); | 96 TestPersistedLogs result_persisted_logs(&prefs_, kLogByteLimit); |
| 97 EXPECT_EQ(PersistedLogs::LIST_EMPTY, result_persisted_logs.DeserializeLogs()); | 97 result_persisted_logs.LoadPersistedUnsentLogs(); |
| 98 EXPECT_EQ(0U, result_persisted_logs.size()); | 98 EXPECT_EQ(0U, result_persisted_logs.size()); |
| 99 } | 99 } |
| 100 | 100 |
| 101 // Store and retrieve a single log value. | 101 // Store and retrieve a single log value. |
| 102 TEST_F(PersistedLogsTest, SingleElementLogList) { | 102 TEST_F(PersistedLogsTest, SingleElementLogList) { |
| 103 TestPersistedLogs persisted_logs(&prefs_, kLogByteLimit); | 103 TestPersistedLogs persisted_logs(&prefs_, kLogByteLimit); |
| 104 | 104 |
| 105 persisted_logs.StoreLog("Hello world!"); | 105 persisted_logs.StoreLog("Hello world!"); |
| 106 persisted_logs.SerializeLogs(); | 106 persisted_logs.PersistUnsentLogs(); |
| 107 | 107 |
| 108 TestPersistedLogs result_persisted_logs(&prefs_, kLogByteLimit); | 108 TestPersistedLogs result_persisted_logs(&prefs_, kLogByteLimit); |
| 109 EXPECT_EQ(PersistedLogs::RECALL_SUCCESS, | 109 result_persisted_logs.LoadPersistedUnsentLogs(); |
| 110 result_persisted_logs.DeserializeLogs()); | |
| 111 EXPECT_EQ(1U, result_persisted_logs.size()); | 110 EXPECT_EQ(1U, result_persisted_logs.size()); |
| 112 | 111 |
| 113 // Verify that the result log matches the initial log. | 112 // Verify that the result log matches the initial log. |
| 114 persisted_logs.StageLog(); | 113 persisted_logs.StageNextLog(); |
| 115 result_persisted_logs.StageLog(); | 114 result_persisted_logs.StageNextLog(); |
| 116 EXPECT_EQ(persisted_logs.staged_log(), result_persisted_logs.staged_log()); | 115 EXPECT_EQ(persisted_logs.staged_log(), result_persisted_logs.staged_log()); |
| 117 EXPECT_EQ(persisted_logs.staged_log_hash(), | 116 EXPECT_EQ(persisted_logs.staged_log_hash(), |
| 118 result_persisted_logs.staged_log_hash()); | 117 result_persisted_logs.staged_log_hash()); |
| 119 EXPECT_EQ(persisted_logs.staged_log_timestamp(), | 118 EXPECT_EQ(persisted_logs.staged_log_timestamp(), |
| 120 result_persisted_logs.staged_log_timestamp()); | 119 result_persisted_logs.staged_log_timestamp()); |
| 121 } | 120 } |
| 122 | 121 |
| 123 // Store a set of logs over the length limit, but smaller than the min number of | 122 // Store a set of logs over the length limit, but smaller than the min number of |
| 124 // bytes. | 123 // bytes. |
| 125 TEST_F(PersistedLogsTest, LongButTinyLogList) { | 124 TEST_F(PersistedLogsTest, LongButTinyLogList) { |
| 126 TestPersistedLogs persisted_logs(&prefs_, kLogByteLimit); | 125 TestPersistedLogs persisted_logs(&prefs_, kLogByteLimit); |
| 127 | 126 |
| 128 size_t log_count = kLogCountLimit * 5; | 127 size_t log_count = kLogCountLimit * 5; |
| 129 for (size_t i = 0; i < log_count; ++i) | 128 for (size_t i = 0; i < log_count; ++i) |
| 130 persisted_logs.StoreLog("x"); | 129 persisted_logs.StoreLog("x"); |
| 131 | 130 |
| 132 persisted_logs.SerializeLogs(); | 131 persisted_logs.PersistUnsentLogs(); |
| 133 | 132 |
| 134 TestPersistedLogs result_persisted_logs(&prefs_, kLogByteLimit); | 133 TestPersistedLogs result_persisted_logs(&prefs_, kLogByteLimit); |
| 135 EXPECT_EQ(PersistedLogs::RECALL_SUCCESS, | 134 result_persisted_logs.LoadPersistedUnsentLogs(); |
| 136 result_persisted_logs.DeserializeLogs()); | |
| 137 EXPECT_EQ(persisted_logs.size(), result_persisted_logs.size()); | 135 EXPECT_EQ(persisted_logs.size(), result_persisted_logs.size()); |
| 138 | 136 |
| 139 result_persisted_logs.ExpectNextLog("x"); | 137 result_persisted_logs.ExpectNextLog("x"); |
| 140 } | 138 } |
| 141 | 139 |
| 142 // Store a set of logs over the length limit, but that doesn't reach the minimum | 140 // Store a set of logs over the length limit, but that doesn't reach the minimum |
| 143 // number of bytes until after passing the length limit. | 141 // number of bytes until after passing the length limit. |
| 144 TEST_F(PersistedLogsTest, LongButSmallLogList) { | 142 TEST_F(PersistedLogsTest, LongButSmallLogList) { |
| 145 size_t log_count = kLogCountLimit * 5; | 143 size_t log_count = kLogCountLimit * 5; |
| 146 size_t log_size = 50; | 144 size_t log_size = 50; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 159 (log_count - 4) * Compress(blank_log).length(); | 157 (log_count - 4) * Compress(blank_log).length(); |
| 160 TestPersistedLogs persisted_logs(&prefs_, min_log_bytes); | 158 TestPersistedLogs persisted_logs(&prefs_, min_log_bytes); |
| 161 | 159 |
| 162 persisted_logs.StoreLog("one"); | 160 persisted_logs.StoreLog("one"); |
| 163 persisted_logs.StoreLog("two"); | 161 persisted_logs.StoreLog("two"); |
| 164 persisted_logs.StoreLog(first_kept); | 162 persisted_logs.StoreLog(first_kept); |
| 165 for (size_t i = persisted_logs.size(); i < log_count - 1; ++i) { | 163 for (size_t i = persisted_logs.size(); i < log_count - 1; ++i) { |
| 166 persisted_logs.StoreLog(blank_log); | 164 persisted_logs.StoreLog(blank_log); |
| 167 } | 165 } |
| 168 persisted_logs.StoreLog(last_kept); | 166 persisted_logs.StoreLog(last_kept); |
| 169 persisted_logs.SerializeLogs(); | 167 persisted_logs.PersistUnsentLogs(); |
| 170 | 168 |
| 171 TestPersistedLogs result_persisted_logs(&prefs_, kLogByteLimit); | 169 TestPersistedLogs result_persisted_logs(&prefs_, kLogByteLimit); |
| 172 EXPECT_EQ(PersistedLogs::RECALL_SUCCESS, | 170 result_persisted_logs.LoadPersistedUnsentLogs(); |
| 173 result_persisted_logs.DeserializeLogs()); | |
| 174 EXPECT_EQ(persisted_logs.size() - 2, result_persisted_logs.size()); | 171 EXPECT_EQ(persisted_logs.size() - 2, result_persisted_logs.size()); |
| 175 | 172 |
| 176 result_persisted_logs.ExpectNextLog(last_kept); | 173 result_persisted_logs.ExpectNextLog(last_kept); |
| 177 while (result_persisted_logs.size() > 1) { | 174 while (result_persisted_logs.size() > 1) { |
| 178 result_persisted_logs.ExpectNextLog(blank_log); | 175 result_persisted_logs.ExpectNextLog(blank_log); |
| 179 } | 176 } |
| 180 result_persisted_logs.ExpectNextLog(first_kept); | 177 result_persisted_logs.ExpectNextLog(first_kept); |
| 181 } | 178 } |
| 182 | 179 |
| 183 // Store a set of logs within the length limit, but well over the minimum | 180 // Store a set of logs within the length limit, but well over the minimum |
| 184 // number of bytes. | 181 // number of bytes. |
| 185 TEST_F(PersistedLogsTest, ShortButLargeLogList) { | 182 TEST_F(PersistedLogsTest, ShortButLargeLogList) { |
| 186 // Make the total byte count about twice the minimum. | 183 // Make the total byte count about twice the minimum. |
| 187 size_t log_count = kLogCountLimit; | 184 size_t log_count = kLogCountLimit; |
| 188 size_t log_size = (kLogByteLimit / log_count) * 2; | 185 size_t log_size = (kLogByteLimit / log_count) * 2; |
| 189 std::string log_data = GenerateLogWithMinCompressedSize(log_size); | 186 std::string log_data = GenerateLogWithMinCompressedSize(log_size); |
| 190 | 187 |
| 191 TestPersistedLogs persisted_logs(&prefs_, kLogByteLimit); | 188 TestPersistedLogs persisted_logs(&prefs_, kLogByteLimit); |
| 192 for (size_t i = 0; i < log_count; ++i) { | 189 for (size_t i = 0; i < log_count; ++i) { |
| 193 persisted_logs.StoreLog(log_data); | 190 persisted_logs.StoreLog(log_data); |
| 194 } | 191 } |
| 195 persisted_logs.SerializeLogs(); | 192 persisted_logs.PersistUnsentLogs(); |
| 196 | 193 |
| 197 TestPersistedLogs result_persisted_logs(&prefs_, kLogByteLimit); | 194 TestPersistedLogs result_persisted_logs(&prefs_, kLogByteLimit); |
| 198 EXPECT_EQ(PersistedLogs::RECALL_SUCCESS, | 195 result_persisted_logs.LoadPersistedUnsentLogs(); |
| 199 result_persisted_logs.DeserializeLogs()); | |
| 200 EXPECT_EQ(persisted_logs.size(), result_persisted_logs.size()); | 196 EXPECT_EQ(persisted_logs.size(), result_persisted_logs.size()); |
| 201 } | 197 } |
| 202 | 198 |
| 203 // Store a set of logs over the length limit, and over the minimum number of | 199 // Store a set of logs over the length limit, and over the minimum number of |
| 204 // bytes. | 200 // bytes. |
| 205 TEST_F(PersistedLogsTest, LongAndLargeLogList) { | 201 TEST_F(PersistedLogsTest, LongAndLargeLogList) { |
| 206 TestPersistedLogs persisted_logs(&prefs_, kLogByteLimit); | 202 TestPersistedLogs persisted_logs(&prefs_, kLogByteLimit); |
| 207 | 203 |
| 208 // Include twice the max number of logs. | 204 // Include twice the max number of logs. |
| 209 size_t log_count = kLogCountLimit * 2; | 205 size_t log_count = kLogCountLimit * 2; |
| 210 // Make the total byte count about four times the minimum. | 206 // Make the total byte count about four times the minimum. |
| 211 size_t log_size = (kLogByteLimit / log_count) * 4; | 207 size_t log_size = (kLogByteLimit / log_count) * 4; |
| 212 | 208 |
| 213 std::string target_log = "First to keep"; | 209 std::string target_log = "First to keep"; |
| 214 target_log += GenerateLogWithMinCompressedSize(log_size); | 210 target_log += GenerateLogWithMinCompressedSize(log_size); |
| 215 | 211 |
| 216 std::string log_data = GenerateLogWithMinCompressedSize(log_size); | 212 std::string log_data = GenerateLogWithMinCompressedSize(log_size); |
| 217 for (size_t i = 0; i < log_count; ++i) { | 213 for (size_t i = 0; i < log_count; ++i) { |
| 218 if (i == log_count - kLogCountLimit) | 214 if (i == log_count - kLogCountLimit) |
| 219 persisted_logs.StoreLog(target_log); | 215 persisted_logs.StoreLog(target_log); |
| 220 else | 216 else |
| 221 persisted_logs.StoreLog(log_data); | 217 persisted_logs.StoreLog(log_data); |
| 222 } | 218 } |
| 223 | 219 |
| 224 persisted_logs.SerializeLogs(); | 220 persisted_logs.PersistUnsentLogs(); |
| 225 | 221 |
| 226 TestPersistedLogs result_persisted_logs(&prefs_, kLogByteLimit); | 222 TestPersistedLogs result_persisted_logs(&prefs_, kLogByteLimit); |
| 227 EXPECT_EQ(PersistedLogs::RECALL_SUCCESS, | 223 result_persisted_logs.LoadPersistedUnsentLogs(); |
| 228 result_persisted_logs.DeserializeLogs()); | |
| 229 EXPECT_EQ(kLogCountLimit, result_persisted_logs.size()); | 224 EXPECT_EQ(kLogCountLimit, result_persisted_logs.size()); |
| 230 | 225 |
| 231 while (result_persisted_logs.size() > 1) { | 226 while (result_persisted_logs.size() > 1) { |
| 232 result_persisted_logs.ExpectNextLog(log_data); | 227 result_persisted_logs.ExpectNextLog(log_data); |
| 233 } | 228 } |
| 234 result_persisted_logs.ExpectNextLog(target_log); | 229 result_persisted_logs.ExpectNextLog(target_log); |
| 235 } | 230 } |
| 236 | 231 |
| 237 // Check that the store/stage/discard functions work as expected. | 232 // Check that the store/stage/discard functions work as expected. |
| 238 TEST_F(PersistedLogsTest, Staging) { | 233 TEST_F(PersistedLogsTest, Staging) { |
| 239 TestPersistedLogs persisted_logs(&prefs_, kLogByteLimit); | 234 TestPersistedLogs persisted_logs(&prefs_, kLogByteLimit); |
| 240 std::string tmp; | 235 std::string tmp; |
| 241 | 236 |
| 242 EXPECT_FALSE(persisted_logs.has_staged_log()); | 237 EXPECT_FALSE(persisted_logs.has_staged_log()); |
| 243 persisted_logs.StoreLog("one"); | 238 persisted_logs.StoreLog("one"); |
| 244 EXPECT_FALSE(persisted_logs.has_staged_log()); | 239 EXPECT_FALSE(persisted_logs.has_staged_log()); |
| 245 persisted_logs.StoreLog("two"); | 240 persisted_logs.StoreLog("two"); |
| 246 persisted_logs.StageLog(); | 241 persisted_logs.StageNextLog(); |
| 247 EXPECT_TRUE(persisted_logs.has_staged_log()); | 242 EXPECT_TRUE(persisted_logs.has_staged_log()); |
| 248 EXPECT_EQ(persisted_logs.staged_log(), Compress("two")); | 243 EXPECT_EQ(persisted_logs.staged_log(), Compress("two")); |
| 249 persisted_logs.StoreLog("three"); | 244 persisted_logs.StoreLog("three"); |
| 250 EXPECT_EQ(persisted_logs.staged_log(), Compress("two")); | 245 EXPECT_EQ(persisted_logs.staged_log(), Compress("two")); |
| 251 EXPECT_EQ(persisted_logs.size(), 3U); | 246 EXPECT_EQ(persisted_logs.size(), 3U); |
| 252 persisted_logs.DiscardStagedLog(); | 247 persisted_logs.DiscardStagedLog(); |
| 253 EXPECT_FALSE(persisted_logs.has_staged_log()); | 248 EXPECT_FALSE(persisted_logs.has_staged_log()); |
| 254 EXPECT_EQ(persisted_logs.size(), 2U); | 249 EXPECT_EQ(persisted_logs.size(), 2U); |
| 255 persisted_logs.StageLog(); | 250 persisted_logs.StageNextLog(); |
| 256 EXPECT_EQ(persisted_logs.staged_log(), Compress("three")); | 251 EXPECT_EQ(persisted_logs.staged_log(), Compress("three")); |
| 257 persisted_logs.DiscardStagedLog(); | 252 persisted_logs.DiscardStagedLog(); |
| 258 persisted_logs.StageLog(); | 253 persisted_logs.StageNextLog(); |
| 259 EXPECT_EQ(persisted_logs.staged_log(), Compress("one")); | 254 EXPECT_EQ(persisted_logs.staged_log(), Compress("one")); |
| 260 persisted_logs.DiscardStagedLog(); | 255 persisted_logs.DiscardStagedLog(); |
| 261 EXPECT_FALSE(persisted_logs.has_staged_log()); | 256 EXPECT_FALSE(persisted_logs.has_staged_log()); |
| 262 EXPECT_EQ(persisted_logs.size(), 0U); | 257 EXPECT_EQ(persisted_logs.size(), 0U); |
| 263 } | 258 } |
| 264 | 259 |
| 265 TEST_F(PersistedLogsTest, DiscardOrder) { | 260 TEST_F(PersistedLogsTest, DiscardOrder) { |
| 266 // Ensure that the correct log is discarded if new logs are pushed while | 261 // Ensure that the correct log is discarded if new logs are pushed while |
| 267 // a log is staged. | 262 // a log is staged. |
| 268 TestPersistedLogs persisted_logs(&prefs_, kLogByteLimit); | 263 TestPersistedLogs persisted_logs(&prefs_, kLogByteLimit); |
| 269 | 264 |
| 270 persisted_logs.StoreLog("one"); | 265 persisted_logs.StoreLog("one"); |
| 271 persisted_logs.StageLog(); | 266 persisted_logs.StageNextLog(); |
| 272 persisted_logs.StoreLog("two"); | 267 persisted_logs.StoreLog("two"); |
| 273 persisted_logs.DiscardStagedLog(); | 268 persisted_logs.DiscardStagedLog(); |
| 274 persisted_logs.SerializeLogs(); | 269 persisted_logs.PersistUnsentLogs(); |
| 275 | 270 |
| 276 TestPersistedLogs result_persisted_logs(&prefs_, kLogByteLimit); | 271 TestPersistedLogs result_persisted_logs(&prefs_, kLogByteLimit); |
| 277 EXPECT_EQ(PersistedLogs::RECALL_SUCCESS, | 272 result_persisted_logs.LoadPersistedUnsentLogs(); |
| 278 result_persisted_logs.DeserializeLogs()); | |
| 279 EXPECT_EQ(1U, result_persisted_logs.size()); | 273 EXPECT_EQ(1U, result_persisted_logs.size()); |
| 280 result_persisted_logs.ExpectNextLog("two"); | 274 result_persisted_logs.ExpectNextLog("two"); |
| 281 } | 275 } |
| 282 | 276 |
| 283 | 277 |
| 284 TEST_F(PersistedLogsTest, Hashes) { | 278 TEST_F(PersistedLogsTest, Hashes) { |
| 285 const char kFooText[] = "foo"; | 279 const char kFooText[] = "foo"; |
| 286 const std::string foo_hash = base::SHA1HashString(kFooText); | 280 const std::string foo_hash = base::SHA1HashString(kFooText); |
| 287 | 281 |
| 288 TestPersistedLogs persisted_logs(&prefs_, kLogByteLimit); | 282 TestPersistedLogs persisted_logs(&prefs_, kLogByteLimit); |
| 289 persisted_logs.StoreLog(kFooText); | 283 persisted_logs.StoreLog(kFooText); |
| 290 persisted_logs.StageLog(); | 284 persisted_logs.StageNextLog(); |
| 291 | 285 |
| 292 EXPECT_EQ(Compress(kFooText), persisted_logs.staged_log()); | 286 EXPECT_EQ(Compress(kFooText), persisted_logs.staged_log()); |
| 293 EXPECT_EQ(foo_hash, persisted_logs.staged_log_hash()); | 287 EXPECT_EQ(foo_hash, persisted_logs.staged_log_hash()); |
| 294 } | 288 } |
| 295 | 289 |
| 296 } // namespace metrics | 290 } // namespace metrics |
| OLD | NEW |