Chromium Code Reviews| Index: components/metrics/metrics_log_store_unittest.cc |
| diff --git a/components/metrics/metrics_log_store_unittest.cc b/components/metrics/metrics_log_store_unittest.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..c1e1cd8703f6788aa2438ba56ed9dc5b7b1429f5 |
| --- /dev/null |
| +++ b/components/metrics/metrics_log_store_unittest.cc |
| @@ -0,0 +1,198 @@ |
| +// Copyright 2017 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "components/metrics/metrics_log_store.h" |
| + |
| +#include "components/metrics/metrics_pref_names.h" |
| +#include "components/metrics/test_metrics_service_client.h" |
| +#include "components/prefs/testing_pref_service.h" |
| +#include "testing/gtest/include/gtest/gtest.h" |
| + |
| +namespace metrics { |
| + |
| +namespace { |
| + |
| +class MetricsLogStoreTest : public testing::Test { |
| + public: |
| + MetricsLogStoreTest() { |
| + MetricsLogStore::RegisterPrefs(pref_service_.registry()); |
| + } |
| + ~MetricsLogStoreTest() override {} |
| + |
| + MetricsLog* CreateLog(MetricsLog::LogType log_type) { |
| + return new MetricsLog("id", 0, log_type, &client_, &pref_service_); |
| + } |
| + |
| + // Returns the stored number of logs of the given type. |
| + size_t TypeCount(MetricsLog::LogType log_type) { |
| + int list_length = 0; |
| + if (log_type == MetricsLog::INITIAL_STABILITY_LOG) |
| + list_length = |
|
rkaplow
2017/02/20 21:24:13
I would just return pref_service_.Get(...) here, a
Steven Holte
2017/02/21 21:51:19
Done.
|
| + pref_service_.GetList(prefs::kMetricsInitialLogs)->GetSize(); |
| + else |
| + list_length = |
| + pref_service_.GetList(prefs::kMetricsOngoingLogs)->GetSize(); |
| + return list_length; |
| + } |
| + |
| + TestMetricsServiceClient client_; |
| + TestingPrefServiceSimple pref_service_; |
| + |
| + private: |
| + DISALLOW_COPY_AND_ASSIGN(MetricsLogStoreTest); |
| +}; |
| + |
| +} // namespace |
| + |
| +TEST_F(MetricsLogStoreTest, StandardFlow) { |
| + MetricsLogStore log_store(&pref_service_, 0); |
| + log_store.LoadPersistedUnsentLogs(); |
| + |
| + // Make sure a new manager has a clean slate. |
| + EXPECT_FALSE(log_store.has_staged_log()); |
| + EXPECT_FALSE(log_store.has_unsent_logs()); |
| + |
| + log_store.StoreLog("a", MetricsLog::ONGOING_LOG); |
| + EXPECT_TRUE(log_store.has_unsent_logs()); |
| + EXPECT_FALSE(log_store.has_staged_log()); |
| + |
| + log_store.StageNextLog(); |
| + EXPECT_TRUE(log_store.has_staged_log()); |
| + EXPECT_FALSE(log_store.staged_log().empty()); |
| + |
| + log_store.DiscardStagedLog(); |
| + EXPECT_FALSE(log_store.has_staged_log()); |
| + EXPECT_FALSE(log_store.has_unsent_logs()); |
| +} |
| + |
| +TEST_F(MetricsLogStoreTest, StoreAndLoad) { |
| + // Set up some in-progress logging in a scoped log manager simulating the |
| + // leadup to quitting, then persist as would be done on quit. |
| + { |
| + MetricsLogStore log_store(&pref_service_, 0); |
| + log_store.LoadPersistedUnsentLogs(); |
| + EXPECT_FALSE(log_store.has_unsent_logs()); |
| + log_store.StoreLog("a", MetricsLog::ONGOING_LOG); |
| + log_store.PersistUnsentLogs(); |
| + EXPECT_EQ(0U, TypeCount(MetricsLog::INITIAL_STABILITY_LOG)); |
| + EXPECT_EQ(1U, TypeCount(MetricsLog::ONGOING_LOG)); |
| + } |
| + |
| + // Relaunch load and store more logs. |
| + { |
| + MetricsLogStore log_store(&pref_service_, 0); |
| + log_store.LoadPersistedUnsentLogs(); |
| + EXPECT_TRUE(log_store.has_unsent_logs()); |
| + EXPECT_EQ(0U, TypeCount(MetricsLog::INITIAL_STABILITY_LOG)); |
| + EXPECT_EQ(1U, TypeCount(MetricsLog::ONGOING_LOG)); |
| + log_store.StoreLog("x", MetricsLog::INITIAL_STABILITY_LOG); |
| + log_store.StageNextLog(); |
| + log_store.StoreLog("b", MetricsLog::ONGOING_LOG); |
| + |
| + EXPECT_TRUE(log_store.has_unsent_logs()); |
| + EXPECT_TRUE(log_store.has_staged_log()); |
| + EXPECT_EQ(0U, TypeCount(MetricsLog::INITIAL_STABILITY_LOG)); |
| + EXPECT_EQ(1U, TypeCount(MetricsLog::ONGOING_LOG)); |
| + |
| + log_store.PersistUnsentLogs(); |
| + EXPECT_EQ(1U, TypeCount(MetricsLog::INITIAL_STABILITY_LOG)); |
| + EXPECT_EQ(2U, TypeCount(MetricsLog::ONGOING_LOG)); |
| + } |
| + |
| + // Relaunch and verify that once logs are handled they are not re-persisted. |
| + { |
| + MetricsLogStore log_store(&pref_service_, 0); |
| + log_store.LoadPersistedUnsentLogs(); |
| + EXPECT_TRUE(log_store.has_unsent_logs()); |
| + |
| + log_store.StageNextLog(); |
| + log_store.DiscardStagedLog(); |
| + // The initial log should be sent first; update the persisted storage to |
| + // verify. |
| + log_store.PersistUnsentLogs(); |
| + EXPECT_EQ(0U, TypeCount(MetricsLog::INITIAL_STABILITY_LOG)); |
| + EXPECT_EQ(2U, TypeCount(MetricsLog::ONGOING_LOG)); |
| + |
| + // Handle the first ongoing log. |
| + log_store.StageNextLog(); |
| + log_store.DiscardStagedLog(); |
| + EXPECT_TRUE(log_store.has_unsent_logs()); |
| + |
| + // Handle the last log. |
| + log_store.StageNextLog(); |
| + log_store.DiscardStagedLog(); |
| + EXPECT_FALSE(log_store.has_unsent_logs()); |
| + |
| + // Nothing should have changed "on disk" since PersistUnsentLogs hasn't been |
| + // called again. |
| + EXPECT_EQ(2U, TypeCount(MetricsLog::ONGOING_LOG)); |
| + // Persist, and make sure nothing is left. |
| + log_store.PersistUnsentLogs(); |
| + EXPECT_EQ(0U, TypeCount(MetricsLog::INITIAL_STABILITY_LOG)); |
| + EXPECT_EQ(0U, TypeCount(MetricsLog::ONGOING_LOG)); |
| + } |
| +} |
| + |
| +TEST_F(MetricsLogStoreTest, StoreStagedOngoingLog) { |
| + // Ensure that types are preserved when storing staged logs. |
| + MetricsLogStore log_store(&pref_service_, 0); |
| + log_store.LoadPersistedUnsentLogs(); |
| + log_store.StoreLog("a", MetricsLog::ONGOING_LOG); |
| + log_store.StageNextLog(); |
| + log_store.PersistUnsentLogs(); |
| + |
| + EXPECT_EQ(0U, TypeCount(MetricsLog::INITIAL_STABILITY_LOG)); |
| + EXPECT_EQ(1U, TypeCount(MetricsLog::ONGOING_LOG)); |
| +} |
| + |
| +TEST_F(MetricsLogStoreTest, StoreStagedInitialLog) { |
| + // Ensure that types are preserved when storing staged logs. |
| + MetricsLogStore log_store(&pref_service_, 0); |
| + log_store.LoadPersistedUnsentLogs(); |
| + log_store.StoreLog("b", MetricsLog::INITIAL_STABILITY_LOG); |
| + log_store.StageNextLog(); |
| + log_store.PersistUnsentLogs(); |
| + |
| + EXPECT_EQ(1U, TypeCount(MetricsLog::INITIAL_STABILITY_LOG)); |
| + EXPECT_EQ(0U, TypeCount(MetricsLog::ONGOING_LOG)); |
| +} |
| + |
| +TEST_F(MetricsLogStoreTest, LargeLogDiscarding) { |
| + // Set the size threshold very low, to verify that it's honored. |
| + MetricsLogStore log_store(&pref_service_, 1); |
| + log_store.LoadPersistedUnsentLogs(); |
| + |
| + log_store.StoreLog("persisted", MetricsLog::INITIAL_STABILITY_LOG); |
| + log_store.StoreLog("not_persisted", MetricsLog::ONGOING_LOG); |
| + |
| + // Only the stability log should be written out, due to the threshold. |
| + log_store.PersistUnsentLogs(); |
| + EXPECT_EQ(1U, TypeCount(MetricsLog::INITIAL_STABILITY_LOG)); |
| + EXPECT_EQ(0U, TypeCount(MetricsLog::ONGOING_LOG)); |
| +} |
| + |
| +TEST_F(MetricsLogStoreTest, DiscardOrder) { |
| + // Ensure that the correct log is discarded if new logs are pushed while |
| + // a log is staged. |
| + MetricsLogStore log_store(&pref_service_, 0); |
| + log_store.LoadPersistedUnsentLogs(); |
| + |
| + log_store.StoreLog("a", MetricsLog::ONGOING_LOG); |
| + log_store.StoreLog("b", MetricsLog::ONGOING_LOG); |
| + log_store.StageNextLog(); |
| + log_store.StoreLog("c", MetricsLog::INITIAL_STABILITY_LOG); |
| + EXPECT_EQ(2U, log_store.ongoing_log_count()); |
| + EXPECT_EQ(1U, log_store.initial_log_count()); |
| + // Should discard the ongoing log staged earlier. |
| + log_store.DiscardStagedLog(); |
| + EXPECT_EQ(1U, log_store.ongoing_log_count()); |
| + EXPECT_EQ(1U, log_store.initial_log_count()); |
| + // Initial log should be staged next. |
| + log_store.StageNextLog(); |
| + log_store.DiscardStagedLog(); |
| + EXPECT_EQ(1U, log_store.ongoing_log_count()); |
| + EXPECT_EQ(0U, log_store.initial_log_count()); |
| +} |
| + |
| +} // namespace metrics |