| // Copyright 2014 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_state_manager.h" |
| |
| #include <ctype.h> |
| #include <string> |
| |
| #include "base/bind.h" |
| #include "base/command_line.h" |
| #include "base/prefs/testing_pref_service.h" |
| #include "components/metrics/metrics_pref_names.h" |
| #include "components/metrics/metrics_switches.h" |
| #include "components/variations/caching_permuted_entropy_provider.h" |
| #include "components/variations/pref_names.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| namespace metrics { |
| |
| class MetricsStateManagerTest : public testing::Test { |
| public: |
| MetricsStateManagerTest() : is_metrics_reporting_enabled_(false) { |
| MetricsStateManager::RegisterPrefs(prefs_.registry()); |
| } |
| |
| scoped_ptr<MetricsStateManager> CreateStateManager() { |
| return MetricsStateManager::Create( |
| &prefs_, |
| base::Bind(&MetricsStateManagerTest::is_metrics_reporting_enabled, |
| base::Unretained(this))).Pass(); |
| } |
| |
| // Sets metrics reporting as enabled for testing. |
| void EnableMetricsReporting() { |
| is_metrics_reporting_enabled_ = true; |
| } |
| |
| protected: |
| TestingPrefServiceSimple prefs_; |
| |
| private: |
| bool is_metrics_reporting_enabled() const { |
| return is_metrics_reporting_enabled_; |
| } |
| |
| bool is_metrics_reporting_enabled_; |
| |
| DISALLOW_COPY_AND_ASSIGN(MetricsStateManagerTest); |
| }; |
| |
| // Ensure the ClientId is formatted as expected. |
| TEST_F(MetricsStateManagerTest, ClientIdCorrectlyFormatted) { |
| scoped_ptr<MetricsStateManager> state_manager(CreateStateManager()); |
| state_manager->ForceClientIdCreation(); |
| |
| const std::string client_id = state_manager->client_id(); |
| EXPECT_EQ(36U, client_id.length()); |
| |
| for (size_t i = 0; i < client_id.length(); ++i) { |
| char current = client_id[i]; |
| if (i == 8 || i == 13 || i == 18 || i == 23) |
| EXPECT_EQ('-', current); |
| else |
| EXPECT_TRUE(isxdigit(current)); |
| } |
| } |
| |
| TEST_F(MetricsStateManagerTest, EntropySourceUsed_Low) { |
| scoped_ptr<MetricsStateManager> state_manager(CreateStateManager()); |
| state_manager->CreateEntropyProvider(); |
| EXPECT_EQ(MetricsStateManager::ENTROPY_SOURCE_LOW, |
| state_manager->entropy_source_returned()); |
| } |
| |
| TEST_F(MetricsStateManagerTest, EntropySourceUsed_High) { |
| EnableMetricsReporting(); |
| scoped_ptr<MetricsStateManager> state_manager(CreateStateManager()); |
| state_manager->CreateEntropyProvider(); |
| EXPECT_EQ(MetricsStateManager::ENTROPY_SOURCE_HIGH, |
| state_manager->entropy_source_returned()); |
| } |
| |
| TEST_F(MetricsStateManagerTest, LowEntropySource0NotReset) { |
| scoped_ptr<MetricsStateManager> state_manager(CreateStateManager()); |
| |
| // Get the low entropy source once, to initialize it. |
| state_manager->GetLowEntropySource(); |
| |
| // Now, set it to 0 and ensure it doesn't get reset. |
| state_manager->low_entropy_source_ = 0; |
| EXPECT_EQ(0, state_manager->GetLowEntropySource()); |
| // Call it another time, just to make sure. |
| EXPECT_EQ(0, state_manager->GetLowEntropySource()); |
| } |
| |
| TEST_F(MetricsStateManagerTest, |
| PermutedEntropyCacheClearedWhenLowEntropyReset) { |
| const PrefService::Preference* low_entropy_pref = |
| prefs_.FindPreference(prefs::kMetricsLowEntropySource); |
| const char* kCachePrefName = prefs::kVariationsPermutedEntropyCache; |
| int low_entropy_value = -1; |
| |
| // First, generate an initial low entropy source value. |
| { |
| EXPECT_TRUE(low_entropy_pref->IsDefaultValue()); |
| |
| scoped_ptr<MetricsStateManager> state_manager(CreateStateManager()); |
| state_manager->GetLowEntropySource(); |
| |
| EXPECT_FALSE(low_entropy_pref->IsDefaultValue()); |
| EXPECT_TRUE(low_entropy_pref->GetValue()->GetAsInteger(&low_entropy_value)); |
| } |
| |
| // Now, set a dummy value in the permuted entropy cache pref and verify that |
| // another call to GetLowEntropySource() doesn't clobber it when |
| // --reset-variation-state wasn't specified. |
| { |
| prefs_.SetString(kCachePrefName, "test"); |
| |
| scoped_ptr<MetricsStateManager> state_manager(CreateStateManager()); |
| state_manager->GetLowEntropySource(); |
| |
| EXPECT_EQ("test", prefs_.GetString(kCachePrefName)); |
| EXPECT_EQ(low_entropy_value, |
| prefs_.GetInteger(prefs::kMetricsLowEntropySource)); |
| } |
| |
| // Verify that the cache does get reset if --reset-variations-state is passed. |
| { |
| CommandLine::ForCurrentProcess()->AppendSwitch( |
| switches::kResetVariationState); |
| |
| scoped_ptr<MetricsStateManager> state_manager(CreateStateManager()); |
| state_manager->GetLowEntropySource(); |
| |
| EXPECT_TRUE(prefs_.GetString(kCachePrefName).empty()); |
| } |
| } |
| |
| // Check that setting the kMetricsResetIds pref to true causes the client id to |
| // be reset. We do not check that the low entropy source is reset because we |
| // cannot ensure that metrics state manager won't generate the same id again. |
| TEST_F(MetricsStateManagerTest, ResetMetricsIDs) { |
| // Set an initial client id in prefs. It should not be possible for the |
| // metrics state manager to generate this id randomly. |
| const std::string kInitialClientId = "initial client id"; |
| prefs_.SetString(prefs::kMetricsClientID, kInitialClientId); |
| |
| // Make sure the initial client id isn't reset by the metrics state manager. |
| { |
| scoped_ptr<MetricsStateManager> state_manager(CreateStateManager()); |
| state_manager->ForceClientIdCreation(); |
| EXPECT_EQ(kInitialClientId, state_manager->client_id()); |
| } |
| |
| // Set the reset pref to cause the IDs to be reset. |
| prefs_.SetBoolean(prefs::kMetricsResetIds, true); |
| |
| // Cause the actual reset to happen. |
| { |
| scoped_ptr<MetricsStateManager> state_manager(CreateStateManager()); |
| state_manager->ForceClientIdCreation(); |
| EXPECT_NE(kInitialClientId, state_manager->client_id()); |
| |
| state_manager->GetLowEntropySource(); |
| |
| EXPECT_FALSE(prefs_.GetBoolean(prefs::kMetricsResetIds)); |
| } |
| |
| EXPECT_NE(kInitialClientId, prefs_.GetString(prefs::kMetricsClientID)); |
| } |
| |
| } // namespace metrics |