1010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// found in the LICENSE file.
4010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "components/metrics/metrics_state_manager.h"
6010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
7010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include <ctype.h>
8010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include <string>
9010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "base/bind.h"
11010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/command_line.h"
12010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/prefs/testing_pref_service.h"
135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/metrics/client_info.h"
14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/metrics/metrics_pref_names.h"
155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "components/metrics/metrics_service.h"
1646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "components/metrics/metrics_switches.h"
17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/variations/caching_permuted_entropy_provider.h"
18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/variations/pref_names.h"
19010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
20010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
21010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)namespace metrics {
22010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
23010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)class MetricsStateManagerTest : public testing::Test {
24010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) public:
25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  MetricsStateManagerTest() : is_metrics_reporting_enabled_(false) {
265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    MetricsService::RegisterPrefs(prefs_.registry());
27010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
28010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
29010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  scoped_ptr<MetricsStateManager> CreateStateManager() {
30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return MetricsStateManager::Create(
31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        &prefs_,
32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        base::Bind(&MetricsStateManagerTest::is_metrics_reporting_enabled,
335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   base::Unretained(this)),
345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        base::Bind(&MetricsStateManagerTest::MockStoreClientInfoBackup,
355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   base::Unretained(this)),
365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        base::Bind(&MetricsStateManagerTest::LoadFakeClientInfoBackup,
37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                   base::Unretained(this))).Pass();
38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Sets metrics reporting as enabled for testing.
41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void EnableMetricsReporting() {
42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    is_metrics_reporting_enabled_ = true;
43010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
44010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
45010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) protected:
46010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  TestingPrefServiceSimple prefs_;
47010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Last ClientInfo stored by the MetricsStateManager via
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // MockStoreClientInfoBackup.
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_ptr<ClientInfo> stored_client_info_backup_;
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // If set, will be returned via LoadFakeClientInfoBackup if requested by the
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // MetricsStateManager.
545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_ptr<ClientInfo> fake_client_info_backup_;
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
56010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) private:
57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool is_metrics_reporting_enabled() const {
58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return is_metrics_reporting_enabled_;
59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Stores the |client_info| in |stored_client_info_backup_| for verification
625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // by the tests later.
635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void MockStoreClientInfoBackup(const ClientInfo& client_info) {
645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    stored_client_info_backup_.reset(new ClientInfo);
655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    stored_client_info_backup_->client_id = client_info.client_id;
665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    stored_client_info_backup_->installation_date =
675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        client_info.installation_date;
685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    stored_client_info_backup_->reporting_enabled_date =
695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        client_info.reporting_enabled_date;
705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Respect the contract that storing an empty client_id voids the existing
725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // backup (required for the last section of the ForceClientIdCreation test
735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // below).
745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (client_info.client_id.empty())
755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      fake_client_info_backup_.reset();
765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Hands out a copy of |fake_client_info_backup_| if it is set.
795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_ptr<ClientInfo> LoadFakeClientInfoBackup() {
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (!fake_client_info_backup_)
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      return scoped_ptr<ClientInfo>();
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    scoped_ptr<ClientInfo> backup_copy(new ClientInfo);
845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    backup_copy->client_id = fake_client_info_backup_->client_id;
855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    backup_copy->installation_date =
865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        fake_client_info_backup_->installation_date;
875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    backup_copy->reporting_enabled_date =
885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        fake_client_info_backup_->reporting_enabled_date;
895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return backup_copy.Pass();
905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  bool is_metrics_reporting_enabled_;
93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
94010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(MetricsStateManagerTest);
95010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)};
96010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
97010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Ensure the ClientId is formatted as expected.
98010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)TEST_F(MetricsStateManagerTest, ClientIdCorrectlyFormatted) {
99010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  scoped_ptr<MetricsStateManager> state_manager(CreateStateManager());
100010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  state_manager->ForceClientIdCreation();
101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
102010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  const std::string client_id = state_manager->client_id();
103010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(36U, client_id.length());
104010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
105010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  for (size_t i = 0; i < client_id.length(); ++i) {
106010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    char current = client_id[i];
107010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    if (i == 8 || i == 13 || i == 18 || i == 23)
108010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      EXPECT_EQ('-', current);
109010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    else
110010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      EXPECT_TRUE(isxdigit(current));
111010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
112010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
113010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
114010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)TEST_F(MetricsStateManagerTest, EntropySourceUsed_Low) {
115010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  scoped_ptr<MetricsStateManager> state_manager(CreateStateManager());
116010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  state_manager->CreateEntropyProvider();
117010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(MetricsStateManager::ENTROPY_SOURCE_LOW,
118010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)            state_manager->entropy_source_returned());
119010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
120010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
121010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)TEST_F(MetricsStateManagerTest, EntropySourceUsed_High) {
122cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EnableMetricsReporting();
123010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  scoped_ptr<MetricsStateManager> state_manager(CreateStateManager());
124010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  state_manager->CreateEntropyProvider();
125010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(MetricsStateManager::ENTROPY_SOURCE_HIGH,
126010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)            state_manager->entropy_source_returned());
127010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
128010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
129010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)TEST_F(MetricsStateManagerTest, LowEntropySource0NotReset) {
130010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  scoped_ptr<MetricsStateManager> state_manager(CreateStateManager());
131010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
132010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Get the low entropy source once, to initialize it.
133010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  state_manager->GetLowEntropySource();
134010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
135010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Now, set it to 0 and ensure it doesn't get reset.
136010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  state_manager->low_entropy_source_ = 0;
137010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(0, state_manager->GetLowEntropySource());
138010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Call it another time, just to make sure.
139010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EXPECT_EQ(0, state_manager->GetLowEntropySource());
140010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
141010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
142010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)TEST_F(MetricsStateManagerTest,
143010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)       PermutedEntropyCacheClearedWhenLowEntropyReset) {
144010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  const PrefService::Preference* low_entropy_pref =
14546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      prefs_.FindPreference(prefs::kMetricsLowEntropySource);
146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  const char* kCachePrefName = prefs::kVariationsPermutedEntropyCache;
147010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  int low_entropy_value = -1;
148010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
149010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // First, generate an initial low entropy source value.
150010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  {
151010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    EXPECT_TRUE(low_entropy_pref->IsDefaultValue());
152010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
153010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    scoped_ptr<MetricsStateManager> state_manager(CreateStateManager());
154010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    state_manager->GetLowEntropySource();
155010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
156010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    EXPECT_FALSE(low_entropy_pref->IsDefaultValue());
157010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    EXPECT_TRUE(low_entropy_pref->GetValue()->GetAsInteger(&low_entropy_value));
158010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
159010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
160010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Now, set a dummy value in the permuted entropy cache pref and verify that
161010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // another call to GetLowEntropySource() doesn't clobber it when
162010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // --reset-variation-state wasn't specified.
163010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  {
164010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    prefs_.SetString(kCachePrefName, "test");
165010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
166010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    scoped_ptr<MetricsStateManager> state_manager(CreateStateManager());
167010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    state_manager->GetLowEntropySource();
168010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
169010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    EXPECT_EQ("test", prefs_.GetString(kCachePrefName));
170010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    EXPECT_EQ(low_entropy_value,
17146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)              prefs_.GetInteger(prefs::kMetricsLowEntropySource));
172010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
173010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
174010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Verify that the cache does get reset if --reset-variations-state is passed.
175010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  {
176010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    CommandLine::ForCurrentProcess()->AppendSwitch(
177010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        switches::kResetVariationState);
178010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
179010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    scoped_ptr<MetricsStateManager> state_manager(CreateStateManager());
180010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    state_manager->GetLowEntropySource();
181010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
182010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    EXPECT_TRUE(prefs_.GetString(kCachePrefName).empty());
183010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
184010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
185010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
186010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Check that setting the kMetricsResetIds pref to true causes the client id to
187010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// be reset. We do not check that the low entropy source is reset because we
188010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// cannot ensure that metrics state manager won't generate the same id again.
189010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)TEST_F(MetricsStateManagerTest, ResetMetricsIDs) {
190010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Set an initial client id in prefs. It should not be possible for the
191010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // metrics state manager to generate this id randomly.
192010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  const std::string kInitialClientId = "initial client id";
19346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  prefs_.SetString(prefs::kMetricsClientID, kInitialClientId);
194010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
195010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Make sure the initial client id isn't reset by the metrics state manager.
196010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  {
197010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    scoped_ptr<MetricsStateManager> state_manager(CreateStateManager());
198010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    state_manager->ForceClientIdCreation();
199010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    EXPECT_EQ(kInitialClientId, state_manager->client_id());
200010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
201010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
202010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Set the reset pref to cause the IDs to be reset.
203010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  prefs_.SetBoolean(prefs::kMetricsResetIds, true);
204010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
205010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Cause the actual reset to happen.
206010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  {
207010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    scoped_ptr<MetricsStateManager> state_manager(CreateStateManager());
208010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    state_manager->ForceClientIdCreation();
209010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    EXPECT_NE(kInitialClientId, state_manager->client_id());
210010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
211010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    state_manager->GetLowEntropySource();
212010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
213010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    EXPECT_FALSE(prefs_.GetBoolean(prefs::kMetricsResetIds));
214010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
215010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
21646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  EXPECT_NE(kInitialClientId, prefs_.GetString(prefs::kMetricsClientID));
217010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
218010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST_F(MetricsStateManagerTest, ForceClientIdCreation) {
2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const int64 kFakeInstallationDate = 12345;
2215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  prefs_.SetInt64(prefs::kInstallDate, kFakeInstallationDate);
2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const int64 test_begin_time = base::Time::Now().ToTimeT();
2245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Holds ClientInfo from previous scoped test for extra checks.
2265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_ptr<ClientInfo> previous_client_info;
2275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  {
2295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    scoped_ptr<MetricsStateManager> state_manager(CreateStateManager());
2305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // client_id shouldn't be auto-generated if metrics reporting is not
2325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // enabled.
2335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_EQ(std::string(), state_manager->client_id());
2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_EQ(0, prefs_.GetInt64(prefs::kMetricsReportingEnabledTimestamp));
2355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Confirm that the initial ForceClientIdCreation call creates the client id
2375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // and backs it up via MockStoreClientInfoBackup.
2385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_FALSE(stored_client_info_backup_);
2395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    state_manager->ForceClientIdCreation();
2405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_NE(std::string(), state_manager->client_id());
2415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_GE(prefs_.GetInt64(prefs::kMetricsReportingEnabledTimestamp),
2425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              test_begin_time);
2435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ASSERT_TRUE(stored_client_info_backup_);
2455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_EQ(state_manager->client_id(),
2465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              stored_client_info_backup_->client_id);
2475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_EQ(kFakeInstallationDate,
2485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              stored_client_info_backup_->installation_date);
2495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_EQ(prefs_.GetInt64(prefs::kMetricsReportingEnabledTimestamp),
2505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              stored_client_info_backup_->reporting_enabled_date);
2515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    previous_client_info = stored_client_info_backup_.Pass();
2535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EnableMetricsReporting();
2565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  {
2585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_FALSE(stored_client_info_backup_);
2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    scoped_ptr<MetricsStateManager> state_manager(CreateStateManager());
2615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // client_id should be auto-obtained from the constructor when metrics
2635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // reporting is enabled.
2645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_EQ(previous_client_info->client_id, state_manager->client_id());
2655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // The backup should also be refreshed when the client id re-initialized.
2675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ASSERT_TRUE(stored_client_info_backup_);
2685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_EQ(previous_client_info->client_id,
2695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              stored_client_info_backup_->client_id);
2705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_EQ(kFakeInstallationDate,
2715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              stored_client_info_backup_->installation_date);
2725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_EQ(previous_client_info->reporting_enabled_date,
2735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              stored_client_info_backup_->reporting_enabled_date);
2745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Re-forcing client id creation shouldn't cause another backup and
2765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // shouldn't affect the existing client id.
2775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    stored_client_info_backup_.reset();
2785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    state_manager->ForceClientIdCreation();
2795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_FALSE(stored_client_info_backup_);
2805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_EQ(previous_client_info->client_id, state_manager->client_id());
2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
2825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const int64 kBackupInstallationDate = 1111;
2845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const int64 kBackupReportingEnabledDate = 2222;
2855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const char kBackupClientId[] = "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE";
2865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  fake_client_info_backup_.reset(new ClientInfo);
2875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  fake_client_info_backup_->client_id = kBackupClientId;
2885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  fake_client_info_backup_->installation_date = kBackupInstallationDate;
2895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  fake_client_info_backup_->reporting_enabled_date =
2905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      kBackupReportingEnabledDate;
2915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  {
2935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // The existence of a backup should result in the same behaviour as
2945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // before if we already have a client id.
2955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_FALSE(stored_client_info_backup_);
2975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    scoped_ptr<MetricsStateManager> state_manager(CreateStateManager());
2995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_EQ(previous_client_info->client_id, state_manager->client_id());
3005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // The backup should also be refreshed when the client id re-initialized.
3025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ASSERT_TRUE(stored_client_info_backup_);
3035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_EQ(previous_client_info->client_id,
3045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              stored_client_info_backup_->client_id);
3055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_EQ(kFakeInstallationDate,
3065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              stored_client_info_backup_->installation_date);
3075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_EQ(previous_client_info->reporting_enabled_date,
3085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              stored_client_info_backup_->reporting_enabled_date);
3095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    stored_client_info_backup_.reset();
3105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
3115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  prefs_.ClearPref(prefs::kMetricsClientID);
3135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  prefs_.ClearPref(prefs::kMetricsReportingEnabledTimestamp);
3145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  {
3165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // The backup should kick in if the client id has gone missing. It should
3175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // replace remaining and missing dates as well.
3185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_FALSE(stored_client_info_backup_);
3205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    scoped_ptr<MetricsStateManager> state_manager(CreateStateManager());
3225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_EQ(kBackupClientId, state_manager->client_id());
3235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_EQ(kBackupInstallationDate, prefs_.GetInt64(prefs::kInstallDate));
3245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_EQ(kBackupReportingEnabledDate,
3255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              prefs_.GetInt64(prefs::kMetricsReportingEnabledTimestamp));
3265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_TRUE(stored_client_info_backup_);
3285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    stored_client_info_backup_.reset();
3295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
3305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const char kNoDashesBackupClientId[] = "AAAAAAAABBBBCCCCDDDDEEEEEEEEEEEE";
3325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  fake_client_info_backup_.reset(new ClientInfo);
3335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  fake_client_info_backup_->client_id = kNoDashesBackupClientId;
3345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  prefs_.ClearPref(prefs::kInstallDate);
3365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  prefs_.ClearPref(prefs::kMetricsClientID);
3375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  prefs_.ClearPref(prefs::kMetricsReportingEnabledTimestamp);
3385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  {
3405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // When running the backup from old-style client ids, dashes should be
3415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // re-added. And missing dates in backup should be replaced by Time::Now().
3425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_FALSE(stored_client_info_backup_);
3445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    scoped_ptr<MetricsStateManager> state_manager(CreateStateManager());
3465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_EQ(kBackupClientId, state_manager->client_id());
3475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_GE(prefs_.GetInt64(prefs::kInstallDate), test_begin_time);
3485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_GE(prefs_.GetInt64(prefs::kMetricsReportingEnabledTimestamp),
3495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              test_begin_time);
3505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_TRUE(stored_client_info_backup_);
3525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    previous_client_info = stored_client_info_backup_.Pass();
3535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
3545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  prefs_.SetBoolean(prefs::kMetricsResetIds, true);
3565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  {
3585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Upon request to reset metrics ids, the existing backup should not be
3595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // restored.
3605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_FALSE(stored_client_info_backup_);
3625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    scoped_ptr<MetricsStateManager> state_manager(CreateStateManager());
3645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // A brand new client id should have been generated.
3665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_NE(std::string(), state_manager->client_id());
3675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_NE(previous_client_info->client_id, state_manager->client_id());
3685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // The installation date should not have been affected.
3705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_EQ(previous_client_info->installation_date,
3715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              prefs_.GetInt64(prefs::kInstallDate));
3725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // The metrics-reporting-enabled date will be reset to Now().
3745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_GE(prefs_.GetInt64(prefs::kMetricsReportingEnabledTimestamp),
3755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              previous_client_info->reporting_enabled_date);
3765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    stored_client_info_backup_.reset();
3785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
3795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
3805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
381010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}  // namespace metrics
382