Chromium Code Reviews| 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/metrics_log_manager.h" | 5 #include "components/metrics/metrics_log_manager.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <string> | 9 #include <string> |
| 10 #include <utility> | 10 #include <utility> |
| 11 #include <vector> | 11 #include <vector> |
| 12 | 12 |
| 13 #include "base/memory/ptr_util.h" | 13 #include "base/memory/ptr_util.h" |
| 14 #include "components/metrics/metrics_log.h" | 14 #include "components/metrics/metrics_log.h" |
| 15 #include "components/metrics/metrics_log_store.h" | |
| 15 #include "components/metrics/metrics_pref_names.h" | 16 #include "components/metrics/metrics_pref_names.h" |
| 16 #include "components/metrics/persisted_logs_metrics_impl.h" | 17 #include "components/metrics/persisted_logs_metrics_impl.h" |
| 17 #include "components/metrics/test_metrics_service_client.h" | 18 #include "components/metrics/test_metrics_service_client.h" |
| 18 #include "components/prefs/pref_registry_simple.h" | 19 #include "components/prefs/pref_registry_simple.h" |
| 19 #include "components/prefs/testing_pref_service.h" | 20 #include "components/prefs/testing_pref_service.h" |
| 20 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
| 21 | 22 |
| 22 namespace metrics { | 23 namespace metrics { |
| 23 | 24 |
| 24 namespace { | 25 namespace { |
| 25 | 26 |
| 26 // Dummy serializer that just stores logs in memory. | 27 class MetricsLogManagerTest : public testing::Test { |
| 27 class TestLogPrefService : public TestingPrefServiceSimple { | |
| 28 public: | 28 public: |
| 29 TestLogPrefService() { | 29 MetricsLogManagerTest() : log_store_(&pref_service_, 0) { |
| 30 registry()->RegisterListPref(prefs::kMetricsInitialLogs); | 30 MetricsLogStore::RegisterPrefs(pref_service_.registry()); |
| 31 registry()->RegisterListPref(prefs::kMetricsOngoingLogs); | 31 log_store()->LoadPersistedUnsentLogs(); |
| 32 } | |
| 33 ~MetricsLogManagerTest() override {} | |
| 34 | |
| 35 MetricsLogStore* log_store() { return &log_store_; } | |
| 36 | |
| 37 MetricsLog* CreateLog(MetricsLog::LogType log_type) { | |
| 38 return new MetricsLog("id", 0, log_type, &client_, &pref_service_); | |
| 32 } | 39 } |
| 33 | 40 |
| 34 // Returns the number of logs of the given type. | 41 private: |
| 35 size_t TypeCount(MetricsLog::LogType log_type) { | 42 TestMetricsServiceClient client_; |
| 36 int list_length = 0; | 43 TestingPrefServiceSimple pref_service_; |
| 37 if (log_type == MetricsLog::INITIAL_STABILITY_LOG) | 44 MetricsLogStore log_store_; |
| 38 list_length = GetList(prefs::kMetricsInitialLogs)->GetSize(); | 45 |
| 39 else | 46 DISALLOW_COPY_AND_ASSIGN(MetricsLogManagerTest); |
| 40 list_length = GetList(prefs::kMetricsOngoingLogs)->GetSize(); | |
| 41 return list_length; | |
| 42 } | |
| 43 }; | 47 }; |
| 44 | 48 |
| 45 } // namespace | 49 } // namespace |
| 46 | 50 |
| 47 TEST(MetricsLogManagerTest, StandardFlow) { | 51 TEST_F(MetricsLogManagerTest, StandardFlow) { |
| 48 TestMetricsServiceClient client; | 52 MetricsLogManager log_manager; |
| 49 TestLogPrefService pref_service; | |
| 50 MetricsLogManager log_manager(&pref_service, 0); | |
| 51 | 53 |
| 52 // Make sure a new manager has a clean slate. | 54 // Make sure a new manager has a clean slate. |
| 53 EXPECT_EQ(NULL, log_manager.current_log()); | 55 EXPECT_EQ(NULL, log_manager.current_log()); |
| 54 EXPECT_FALSE(log_manager.has_staged_log()); | |
| 55 EXPECT_FALSE(log_manager.has_unsent_logs()); | |
| 56 | 56 |
| 57 // Check that the normal flow works. | 57 // Check that the normal flow works. |
| 58 MetricsLog* initial_log = new MetricsLog( | 58 MetricsLog* initial_log = CreateLog(MetricsLog::INITIAL_STABILITY_LOG); |
| 59 "id", 0, MetricsLog::INITIAL_STABILITY_LOG, &client, &pref_service); | |
| 60 log_manager.BeginLoggingWithLog(base::WrapUnique(initial_log)); | 59 log_manager.BeginLoggingWithLog(base::WrapUnique(initial_log)); |
| 61 EXPECT_EQ(initial_log, log_manager.current_log()); | 60 EXPECT_EQ(initial_log, log_manager.current_log()); |
| 62 EXPECT_FALSE(log_manager.has_staged_log()); | |
| 63 | 61 |
| 64 log_manager.FinishCurrentLog(); | 62 EXPECT_FALSE(log_store()->has_unsent_logs()); |
| 63 log_manager.FinishCurrentLog(log_store()); | |
| 65 EXPECT_EQ(NULL, log_manager.current_log()); | 64 EXPECT_EQ(NULL, log_manager.current_log()); |
| 66 EXPECT_TRUE(log_manager.has_unsent_logs()); | 65 EXPECT_TRUE(log_store()->has_unsent_logs()); |
| 67 EXPECT_FALSE(log_manager.has_staged_log()); | |
| 68 | 66 |
| 69 MetricsLog* second_log = | 67 MetricsLog* second_log = CreateLog(MetricsLog::ONGOING_LOG); |
| 70 new MetricsLog("id", 0, MetricsLog::ONGOING_LOG, &client, &pref_service); | |
| 71 log_manager.BeginLoggingWithLog(base::WrapUnique(second_log)); | 68 log_manager.BeginLoggingWithLog(base::WrapUnique(second_log)); |
| 72 EXPECT_EQ(second_log, log_manager.current_log()); | 69 EXPECT_EQ(second_log, log_manager.current_log()); |
| 73 | |
| 74 log_manager.StageNextLogForUpload(); | |
| 75 EXPECT_TRUE(log_manager.has_staged_log()); | |
| 76 EXPECT_FALSE(log_manager.staged_log().empty()); | |
| 77 | |
| 78 log_manager.DiscardStagedLog(); | |
| 79 EXPECT_EQ(second_log, log_manager.current_log()); | |
| 80 EXPECT_FALSE(log_manager.has_staged_log()); | |
| 81 EXPECT_FALSE(log_manager.has_unsent_logs()); | |
| 82 | |
| 83 EXPECT_FALSE(log_manager.has_unsent_logs()); | |
| 84 } | 70 } |
| 85 | 71 |
| 86 TEST(MetricsLogManagerTest, AbandonedLog) { | 72 TEST_F(MetricsLogManagerTest, AbandonedLog) { |
| 87 TestMetricsServiceClient client; | 73 MetricsLogManager log_manager; |
| 88 TestLogPrefService pref_service; | |
| 89 MetricsLogManager log_manager(&pref_service, 0); | |
| 90 | 74 |
| 91 MetricsLog* dummy_log = new MetricsLog( | 75 MetricsLog* dummy_log = CreateLog(MetricsLog::INITIAL_STABILITY_LOG); |
| 92 "id", 0, MetricsLog::INITIAL_STABILITY_LOG, &client, &pref_service); | |
| 93 log_manager.BeginLoggingWithLog(base::WrapUnique(dummy_log)); | 76 log_manager.BeginLoggingWithLog(base::WrapUnique(dummy_log)); |
| 94 EXPECT_EQ(dummy_log, log_manager.current_log()); | 77 EXPECT_EQ(dummy_log, log_manager.current_log()); |
| 95 | 78 |
| 96 log_manager.DiscardCurrentLog(); | 79 log_manager.DiscardCurrentLog(); |
| 97 EXPECT_EQ(NULL, log_manager.current_log()); | 80 EXPECT_EQ(NULL, log_manager.current_log()); |
| 98 EXPECT_FALSE(log_manager.has_staged_log()); | |
| 99 } | 81 } |
| 100 | 82 |
| 101 TEST(MetricsLogManagerTest, InterjectedLog) { | 83 TEST_F(MetricsLogManagerTest, InterjectedLog) { |
| 102 TestMetricsServiceClient client; | 84 MetricsLogManager log_manager; |
| 103 TestLogPrefService pref_service; | |
| 104 MetricsLogManager log_manager(&pref_service, 0); | |
| 105 | 85 |
| 106 MetricsLog* ongoing_log = | 86 MetricsLog* ongoing_log = CreateLog(MetricsLog::ONGOING_LOG); |
| 107 new MetricsLog("id", 0, MetricsLog::ONGOING_LOG, &client, &pref_service); | 87 MetricsLog* temp_log = CreateLog(MetricsLog::INITIAL_STABILITY_LOG); |
| 108 MetricsLog* temp_log = new MetricsLog( | |
| 109 "id", 0, MetricsLog::INITIAL_STABILITY_LOG, &client, &pref_service); | |
| 110 | 88 |
| 111 log_manager.BeginLoggingWithLog(base::WrapUnique(ongoing_log)); | 89 log_manager.BeginLoggingWithLog(base::WrapUnique(ongoing_log)); |
| 112 EXPECT_EQ(ongoing_log, log_manager.current_log()); | 90 EXPECT_EQ(ongoing_log, log_manager.current_log()); |
| 113 | 91 |
| 114 log_manager.PauseCurrentLog(); | 92 log_manager.PauseCurrentLog(); |
| 115 EXPECT_EQ(NULL, log_manager.current_log()); | 93 EXPECT_EQ(NULL, log_manager.current_log()); |
| 116 | 94 |
| 117 log_manager.BeginLoggingWithLog(base::WrapUnique(temp_log)); | 95 log_manager.BeginLoggingWithLog(base::WrapUnique(temp_log)); |
| 118 EXPECT_EQ(temp_log, log_manager.current_log()); | 96 EXPECT_EQ(temp_log, log_manager.current_log()); |
| 119 log_manager.FinishCurrentLog(); | 97 log_manager.FinishCurrentLog(log_store()); |
| 120 EXPECT_EQ(NULL, log_manager.current_log()); | 98 EXPECT_EQ(NULL, log_manager.current_log()); |
| 121 | 99 |
| 122 log_manager.ResumePausedLog(); | 100 log_manager.ResumePausedLog(); |
| 123 EXPECT_EQ(ongoing_log, log_manager.current_log()); | 101 EXPECT_EQ(ongoing_log, log_manager.current_log()); |
| 124 | |
| 125 EXPECT_FALSE(log_manager.has_staged_log()); | |
| 126 log_manager.StageNextLogForUpload(); | |
| 127 log_manager.DiscardStagedLog(); | |
| 128 EXPECT_FALSE(log_manager.has_unsent_logs()); | |
| 129 } | 102 } |
| 130 | 103 |
|
rkaplow
2017/02/20 21:24:13
should this test be re-thought? We're not checking
Steven Holte
2017/02/21 21:51:18
I think the test is fine, since the initial/ongoin
| |
| 131 TEST(MetricsLogManagerTest, InterjectedLogPreservesType) { | 104 TEST_F(MetricsLogManagerTest, InterjectedLogPreservesType) { |
| 132 TestMetricsServiceClient client; | 105 MetricsLogManager log_manager; |
| 133 TestLogPrefService pref_service; | |
| 134 MetricsLogManager log_manager(&pref_service, 0); | |
| 135 log_manager.LoadPersistedUnsentLogs(); | |
| 136 | 106 |
| 137 log_manager.BeginLoggingWithLog(base::MakeUnique<MetricsLog>( | 107 log_manager.BeginLoggingWithLog( |
| 138 "id", 0, MetricsLog::ONGOING_LOG, &client, &pref_service)); | 108 base::WrapUnique(CreateLog(MetricsLog::ONGOING_LOG))); |
| 139 log_manager.PauseCurrentLog(); | 109 log_manager.PauseCurrentLog(); |
| 140 log_manager.BeginLoggingWithLog(base::MakeUnique<MetricsLog>( | 110 log_manager.BeginLoggingWithLog( |
| 141 "id", 0, MetricsLog::INITIAL_STABILITY_LOG, &client, &pref_service)); | 111 base::WrapUnique(CreateLog(MetricsLog::INITIAL_STABILITY_LOG))); |
| 142 log_manager.FinishCurrentLog(); | 112 log_manager.FinishCurrentLog(log_store()); |
| 143 log_manager.ResumePausedLog(); | 113 log_manager.ResumePausedLog(); |
| 144 log_manager.StageNextLogForUpload(); | 114 EXPECT_EQ(1U, log_store()->initial_log_count()); |
| 145 log_manager.DiscardStagedLog(); | 115 EXPECT_EQ(0U, log_store()->ongoing_log_count()); |
| 146 | 116 |
| 147 // Verify that the remaining log (which is the original ongoing log) still | 117 // Verify that the remaining log (which is the original ongoing log) still |
| 148 // has the right type. | 118 // has the right type. |
| 149 log_manager.FinishCurrentLog(); | 119 log_manager.FinishCurrentLog(log_store()); |
| 150 log_manager.PersistUnsentLogs(); | 120 EXPECT_EQ(1U, log_store()->initial_log_count()); |
| 151 EXPECT_EQ(0U, pref_service.TypeCount(MetricsLog::INITIAL_STABILITY_LOG)); | 121 EXPECT_EQ(1U, log_store()->ongoing_log_count()); |
| 152 EXPECT_EQ(1U, pref_service.TypeCount(MetricsLog::ONGOING_LOG)); | |
| 153 } | |
| 154 | |
| 155 TEST(MetricsLogManagerTest, StoreAndLoad) { | |
| 156 TestMetricsServiceClient client; | |
| 157 TestLogPrefService pref_service; | |
| 158 // Set up some in-progress logging in a scoped log manager simulating the | |
| 159 // leadup to quitting, then persist as would be done on quit. | |
| 160 { | |
| 161 MetricsLogManager log_manager(&pref_service, 0); | |
| 162 log_manager.LoadPersistedUnsentLogs(); | |
| 163 | |
| 164 // Simulate a log having already been unsent from a previous session. | |
| 165 { | |
| 166 std::string log("proto"); | |
| 167 PersistedLogs ongoing_logs(std::unique_ptr<PersistedLogsMetricsImpl>( | |
| 168 new PersistedLogsMetricsImpl()), | |
| 169 &pref_service, prefs::kMetricsOngoingLogs, | |
| 170 1, 1, 0); | |
| 171 ongoing_logs.StoreLog(log); | |
| 172 ongoing_logs.SerializeLogs(); | |
| 173 } | |
| 174 EXPECT_EQ(1U, pref_service.TypeCount(MetricsLog::ONGOING_LOG)); | |
| 175 EXPECT_FALSE(log_manager.has_unsent_logs()); | |
| 176 log_manager.LoadPersistedUnsentLogs(); | |
| 177 EXPECT_TRUE(log_manager.has_unsent_logs()); | |
| 178 | |
| 179 log_manager.BeginLoggingWithLog(base::MakeUnique<MetricsLog>( | |
| 180 "id", 0, MetricsLog::INITIAL_STABILITY_LOG, &client, &pref_service)); | |
| 181 log_manager.FinishCurrentLog(); | |
| 182 log_manager.BeginLoggingWithLog(base::MakeUnique<MetricsLog>( | |
| 183 "id", 0, MetricsLog::ONGOING_LOG, &client, &pref_service)); | |
| 184 log_manager.StageNextLogForUpload(); | |
| 185 log_manager.FinishCurrentLog(); | |
| 186 | |
| 187 // Nothing should be written out until PersistUnsentLogs is called. | |
| 188 EXPECT_EQ(0U, pref_service.TypeCount(MetricsLog::INITIAL_STABILITY_LOG)); | |
| 189 EXPECT_EQ(1U, pref_service.TypeCount(MetricsLog::ONGOING_LOG)); | |
| 190 log_manager.PersistUnsentLogs(); | |
| 191 EXPECT_EQ(1U, pref_service.TypeCount(MetricsLog::INITIAL_STABILITY_LOG)); | |
| 192 EXPECT_EQ(2U, pref_service.TypeCount(MetricsLog::ONGOING_LOG)); | |
| 193 } | |
| 194 | |
| 195 // Now simulate the relaunch, ensure that the log manager restores | |
| 196 // everything correctly, and verify that once the are handled they are not | |
| 197 // re-persisted. | |
| 198 { | |
| 199 MetricsLogManager log_manager(&pref_service, 0); | |
| 200 log_manager.LoadPersistedUnsentLogs(); | |
| 201 EXPECT_TRUE(log_manager.has_unsent_logs()); | |
| 202 | |
| 203 log_manager.StageNextLogForUpload(); | |
| 204 log_manager.DiscardStagedLog(); | |
| 205 // The initial log should be sent first; update the persisted storage to | |
| 206 // verify. | |
| 207 log_manager.PersistUnsentLogs(); | |
| 208 EXPECT_EQ(0U, pref_service.TypeCount(MetricsLog::INITIAL_STABILITY_LOG)); | |
| 209 EXPECT_EQ(2U, pref_service.TypeCount(MetricsLog::ONGOING_LOG)); | |
| 210 | |
| 211 // Handle the first ongoing log. | |
| 212 log_manager.StageNextLogForUpload(); | |
| 213 log_manager.DiscardStagedLog(); | |
| 214 EXPECT_TRUE(log_manager.has_unsent_logs()); | |
| 215 | |
| 216 // Handle the last log. | |
| 217 log_manager.StageNextLogForUpload(); | |
| 218 log_manager.DiscardStagedLog(); | |
| 219 EXPECT_FALSE(log_manager.has_unsent_logs()); | |
| 220 | |
| 221 // Nothing should have changed "on disk" since PersistUnsentLogs hasn't been | |
| 222 // called again. | |
| 223 EXPECT_EQ(2U, pref_service.TypeCount(MetricsLog::ONGOING_LOG)); | |
| 224 // Persist, and make sure nothing is left. | |
| 225 log_manager.PersistUnsentLogs(); | |
| 226 EXPECT_EQ(0U, pref_service.TypeCount(MetricsLog::INITIAL_STABILITY_LOG)); | |
| 227 EXPECT_EQ(0U, pref_service.TypeCount(MetricsLog::ONGOING_LOG)); | |
| 228 } | |
| 229 } | |
| 230 | |
| 231 TEST(MetricsLogManagerTest, StoreStagedLogTypes) { | |
| 232 TestMetricsServiceClient client; | |
| 233 | |
| 234 // Ensure that types are preserved when storing staged logs. | |
| 235 { | |
| 236 TestLogPrefService pref_service; | |
| 237 MetricsLogManager log_manager(&pref_service, 0); | |
| 238 log_manager.LoadPersistedUnsentLogs(); | |
| 239 | |
| 240 log_manager.BeginLoggingWithLog(base::MakeUnique<MetricsLog>( | |
| 241 "id", 0, MetricsLog::ONGOING_LOG, &client, &pref_service)); | |
| 242 log_manager.FinishCurrentLog(); | |
| 243 log_manager.StageNextLogForUpload(); | |
| 244 log_manager.PersistUnsentLogs(); | |
| 245 | |
| 246 EXPECT_EQ(0U, pref_service.TypeCount(MetricsLog::INITIAL_STABILITY_LOG)); | |
| 247 EXPECT_EQ(1U, pref_service.TypeCount(MetricsLog::ONGOING_LOG)); | |
| 248 } | |
| 249 | |
| 250 { | |
| 251 TestLogPrefService pref_service; | |
| 252 MetricsLogManager log_manager(&pref_service, 0); | |
| 253 log_manager.LoadPersistedUnsentLogs(); | |
| 254 | |
| 255 log_manager.BeginLoggingWithLog(base::MakeUnique<MetricsLog>( | |
| 256 "id", 0, MetricsLog::INITIAL_STABILITY_LOG, &client, &pref_service)); | |
| 257 log_manager.FinishCurrentLog(); | |
| 258 log_manager.StageNextLogForUpload(); | |
| 259 log_manager.PersistUnsentLogs(); | |
| 260 | |
| 261 EXPECT_EQ(1U, pref_service.TypeCount(MetricsLog::INITIAL_STABILITY_LOG)); | |
| 262 EXPECT_EQ(0U, pref_service.TypeCount(MetricsLog::ONGOING_LOG)); | |
| 263 } | |
| 264 } | |
| 265 | |
| 266 TEST(MetricsLogManagerTest, LargeLogDiscarding) { | |
| 267 TestMetricsServiceClient client; | |
| 268 TestLogPrefService pref_service; | |
| 269 // Set the size threshold very low, to verify that it's honored. | |
| 270 MetricsLogManager log_manager(&pref_service, 1); | |
| 271 log_manager.LoadPersistedUnsentLogs(); | |
| 272 | |
| 273 log_manager.BeginLoggingWithLog(base::MakeUnique<MetricsLog>( | |
| 274 "id", 0, MetricsLog::INITIAL_STABILITY_LOG, &client, &pref_service)); | |
| 275 log_manager.FinishCurrentLog(); | |
| 276 log_manager.BeginLoggingWithLog(base::MakeUnique<MetricsLog>( | |
| 277 "id", 0, MetricsLog::ONGOING_LOG, &client, &pref_service)); | |
| 278 log_manager.FinishCurrentLog(); | |
| 279 | |
| 280 // Only the ongoing log should be written out, due to the threshold. | |
| 281 log_manager.PersistUnsentLogs(); | |
| 282 EXPECT_EQ(1U, pref_service.TypeCount(MetricsLog::INITIAL_STABILITY_LOG)); | |
| 283 EXPECT_EQ(0U, pref_service.TypeCount(MetricsLog::ONGOING_LOG)); | |
| 284 } | |
| 285 | |
| 286 TEST(MetricsLogManagerTest, DiscardOrder) { | |
| 287 // Ensure that the correct log is discarded if new logs are pushed while | |
| 288 // a log is staged. | |
| 289 TestMetricsServiceClient client; | |
| 290 { | |
| 291 TestLogPrefService pref_service; | |
| 292 MetricsLogManager log_manager(&pref_service, 0); | |
| 293 log_manager.LoadPersistedUnsentLogs(); | |
| 294 | |
| 295 log_manager.BeginLoggingWithLog(base::MakeUnique<MetricsLog>( | |
| 296 "id", 0, MetricsLog::INITIAL_STABILITY_LOG, &client, &pref_service)); | |
| 297 log_manager.FinishCurrentLog(); | |
| 298 log_manager.BeginLoggingWithLog(base::MakeUnique<MetricsLog>( | |
| 299 "id", 0, MetricsLog::ONGOING_LOG, &client, &pref_service)); | |
| 300 log_manager.StageNextLogForUpload(); | |
| 301 log_manager.FinishCurrentLog(); | |
| 302 log_manager.DiscardStagedLog(); | |
| 303 | |
| 304 log_manager.PersistUnsentLogs(); | |
| 305 EXPECT_EQ(0U, pref_service.TypeCount(MetricsLog::INITIAL_STABILITY_LOG)); | |
| 306 EXPECT_EQ(1U, pref_service.TypeCount(MetricsLog::ONGOING_LOG)); | |
| 307 } | |
| 308 } | 122 } |
| 309 | 123 |
| 310 } // namespace metrics | 124 } // namespace metrics |
| OLD | NEW |