| 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..5c352744d1d7233546ae7e86315b66f47cc85192
|
| --- /dev/null
|
| +++ b/components/metrics/metrics_log_store_unittest.cc
|
| @@ -0,0 +1,194 @@
|
| +// 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) {
|
| + const char* pref = log_type == MetricsLog::INITIAL_STABILITY_LOG
|
| + ? prefs::kMetricsInitialLogs
|
| + : prefs::kMetricsOngoingLogs;
|
| + return pref_service_.GetList(pref)->GetSize();
|
| + }
|
| +
|
| + 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
|
|
|