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 3// found in the LICENSE file. 4 5#include "components/metrics/metrics_state_manager.h" 6 7#include <ctype.h> 8#include <string> 9 10#include "base/bind.h" 11#include "base/command_line.h" 12#include "base/prefs/testing_pref_service.h" 13#include "components/metrics/metrics_pref_names.h" 14#include "components/metrics/metrics_switches.h" 15#include "components/variations/caching_permuted_entropy_provider.h" 16#include "components/variations/pref_names.h" 17#include "testing/gtest/include/gtest/gtest.h" 18 19namespace metrics { 20 21class MetricsStateManagerTest : public testing::Test { 22 public: 23 MetricsStateManagerTest() : is_metrics_reporting_enabled_(false) { 24 MetricsStateManager::RegisterPrefs(prefs_.registry()); 25 } 26 27 scoped_ptr<MetricsStateManager> CreateStateManager() { 28 return MetricsStateManager::Create( 29 &prefs_, 30 base::Bind(&MetricsStateManagerTest::is_metrics_reporting_enabled, 31 base::Unretained(this))).Pass(); 32 } 33 34 // Sets metrics reporting as enabled for testing. 35 void EnableMetricsReporting() { 36 is_metrics_reporting_enabled_ = true; 37 } 38 39 protected: 40 TestingPrefServiceSimple prefs_; 41 42 private: 43 bool is_metrics_reporting_enabled() const { 44 return is_metrics_reporting_enabled_; 45 } 46 47 bool is_metrics_reporting_enabled_; 48 49 DISALLOW_COPY_AND_ASSIGN(MetricsStateManagerTest); 50}; 51 52// Ensure the ClientId is formatted as expected. 53TEST_F(MetricsStateManagerTest, ClientIdCorrectlyFormatted) { 54 scoped_ptr<MetricsStateManager> state_manager(CreateStateManager()); 55 state_manager->ForceClientIdCreation(); 56 57 const std::string client_id = state_manager->client_id(); 58 EXPECT_EQ(36U, client_id.length()); 59 60 for (size_t i = 0; i < client_id.length(); ++i) { 61 char current = client_id[i]; 62 if (i == 8 || i == 13 || i == 18 || i == 23) 63 EXPECT_EQ('-', current); 64 else 65 EXPECT_TRUE(isxdigit(current)); 66 } 67} 68 69TEST_F(MetricsStateManagerTest, EntropySourceUsed_Low) { 70 scoped_ptr<MetricsStateManager> state_manager(CreateStateManager()); 71 state_manager->CreateEntropyProvider(); 72 EXPECT_EQ(MetricsStateManager::ENTROPY_SOURCE_LOW, 73 state_manager->entropy_source_returned()); 74} 75 76TEST_F(MetricsStateManagerTest, EntropySourceUsed_High) { 77 EnableMetricsReporting(); 78 scoped_ptr<MetricsStateManager> state_manager(CreateStateManager()); 79 state_manager->CreateEntropyProvider(); 80 EXPECT_EQ(MetricsStateManager::ENTROPY_SOURCE_HIGH, 81 state_manager->entropy_source_returned()); 82} 83 84TEST_F(MetricsStateManagerTest, LowEntropySource0NotReset) { 85 scoped_ptr<MetricsStateManager> state_manager(CreateStateManager()); 86 87 // Get the low entropy source once, to initialize it. 88 state_manager->GetLowEntropySource(); 89 90 // Now, set it to 0 and ensure it doesn't get reset. 91 state_manager->low_entropy_source_ = 0; 92 EXPECT_EQ(0, state_manager->GetLowEntropySource()); 93 // Call it another time, just to make sure. 94 EXPECT_EQ(0, state_manager->GetLowEntropySource()); 95} 96 97TEST_F(MetricsStateManagerTest, 98 PermutedEntropyCacheClearedWhenLowEntropyReset) { 99 const PrefService::Preference* low_entropy_pref = 100 prefs_.FindPreference(prefs::kMetricsLowEntropySource); 101 const char* kCachePrefName = prefs::kVariationsPermutedEntropyCache; 102 int low_entropy_value = -1; 103 104 // First, generate an initial low entropy source value. 105 { 106 EXPECT_TRUE(low_entropy_pref->IsDefaultValue()); 107 108 scoped_ptr<MetricsStateManager> state_manager(CreateStateManager()); 109 state_manager->GetLowEntropySource(); 110 111 EXPECT_FALSE(low_entropy_pref->IsDefaultValue()); 112 EXPECT_TRUE(low_entropy_pref->GetValue()->GetAsInteger(&low_entropy_value)); 113 } 114 115 // Now, set a dummy value in the permuted entropy cache pref and verify that 116 // another call to GetLowEntropySource() doesn't clobber it when 117 // --reset-variation-state wasn't specified. 118 { 119 prefs_.SetString(kCachePrefName, "test"); 120 121 scoped_ptr<MetricsStateManager> state_manager(CreateStateManager()); 122 state_manager->GetLowEntropySource(); 123 124 EXPECT_EQ("test", prefs_.GetString(kCachePrefName)); 125 EXPECT_EQ(low_entropy_value, 126 prefs_.GetInteger(prefs::kMetricsLowEntropySource)); 127 } 128 129 // Verify that the cache does get reset if --reset-variations-state is passed. 130 { 131 CommandLine::ForCurrentProcess()->AppendSwitch( 132 switches::kResetVariationState); 133 134 scoped_ptr<MetricsStateManager> state_manager(CreateStateManager()); 135 state_manager->GetLowEntropySource(); 136 137 EXPECT_TRUE(prefs_.GetString(kCachePrefName).empty()); 138 } 139} 140 141// Check that setting the kMetricsResetIds pref to true causes the client id to 142// be reset. We do not check that the low entropy source is reset because we 143// cannot ensure that metrics state manager won't generate the same id again. 144TEST_F(MetricsStateManagerTest, ResetMetricsIDs) { 145 // Set an initial client id in prefs. It should not be possible for the 146 // metrics state manager to generate this id randomly. 147 const std::string kInitialClientId = "initial client id"; 148 prefs_.SetString(prefs::kMetricsClientID, kInitialClientId); 149 150 // Make sure the initial client id isn't reset by the metrics state manager. 151 { 152 scoped_ptr<MetricsStateManager> state_manager(CreateStateManager()); 153 state_manager->ForceClientIdCreation(); 154 EXPECT_EQ(kInitialClientId, state_manager->client_id()); 155 } 156 157 // Set the reset pref to cause the IDs to be reset. 158 prefs_.SetBoolean(prefs::kMetricsResetIds, true); 159 160 // Cause the actual reset to happen. 161 { 162 scoped_ptr<MetricsStateManager> state_manager(CreateStateManager()); 163 state_manager->ForceClientIdCreation(); 164 EXPECT_NE(kInitialClientId, state_manager->client_id()); 165 166 state_manager->GetLowEntropySource(); 167 168 EXPECT_FALSE(prefs_.GetBoolean(prefs::kMetricsResetIds)); 169 } 170 171 EXPECT_NE(kInitialClientId, prefs_.GetString(prefs::kMetricsClientID)); 172} 173 174} // namespace metrics 175