1 // Copyright 2015 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.
5 #include "components/rappor/rappor_prefs.h"
7 #include "base/base64.h"
8 #include "base/prefs/testing_pref_service.h"
9 #include "base/test/histogram_tester.h"
10 #include "components/rappor/byte_vector_utils.h"
11 #include "components/rappor/proto/rappor_metric.pb.h"
12 #include "components/rappor/rappor_pref_names.h"
13 #include "testing/gtest/include/gtest/gtest.h"
21 // Convert a secret to base 64 and store it in preferences.
22 void StoreSecret(const std::string
& secret
,
23 TestingPrefServiceSimple
* test_prefs
) {
24 std::string secret_base64
;
25 base::Base64Encode(secret
, &secret_base64
);
26 test_prefs
->SetString(prefs::kRapporSecret
, secret_base64
);
29 // Verify that the current value of the secret pref matches the loaded secret.
30 void ExpectConsistentSecret(const TestingPrefServiceSimple
& test_prefs
,
31 const std::string
& loaded_secret
) {
32 std::string pref
= test_prefs
.GetString(prefs::kRapporSecret
);
33 std::string decoded_pref
;
34 EXPECT_TRUE(base::Base64Decode(pref
, &decoded_pref
));
35 EXPECT_EQ(loaded_secret
, decoded_pref
);
40 class RapporPrefsTest
: public testing::Test
{
43 RegisterPrefs(test_prefs_
.registry());
47 base::HistogramTester tester_
;
48 TestingPrefServiceSimple test_prefs_
;
50 DISALLOW_COPY_AND_ASSIGN(RapporPrefsTest
);
53 TEST_F(RapporPrefsTest
, EmptyCohort
) {
54 test_prefs_
.ClearPref(prefs::kRapporCohortSeed
);
55 // Loaded cohort should have been rerolled into a valid number.
56 int32_t cohort
= LoadCohort(&test_prefs_
);
57 tester_
.ExpectUniqueSample(kLoadCohortHistogramName
, LOAD_EMPTY_VALUE
, 1);
59 EXPECT_LT(cohort
, RapporParameters::kMaxCohorts
);
60 // The preferences should be consistent with the loaded value.
61 int32_t pref
= test_prefs_
.GetInteger(prefs::kRapporCohortSeed
);
62 EXPECT_EQ(pref
, cohort
);
65 TEST_F(RapporPrefsTest
, LoadCohort
) {
66 test_prefs_
.SetInteger(prefs::kRapporCohortSeed
, 1);
67 // Loading the valid cohort should just retrieve it.
68 int32_t cohort
= LoadCohort(&test_prefs_
);
69 tester_
.ExpectUniqueSample(kLoadCohortHistogramName
, LOAD_SUCCESS
, 1);
71 // The preferences should be consistent with the loaded value.
72 int32_t pref
= test_prefs_
.GetInteger(prefs::kRapporCohortSeed
);
73 EXPECT_EQ(pref
, cohort
);
76 TEST_F(RapporPrefsTest
, CorruptCohort
) {
77 // Set an invalid cohort value in the preference.
78 test_prefs_
.SetInteger(prefs::kRapporCohortSeed
, -10);
79 // Loaded cohort should have been rerolled into a valid number.
80 int32_t cohort
= LoadCohort(&test_prefs_
);
81 tester_
.ExpectUniqueSample(kLoadCohortHistogramName
, LOAD_CORRUPT_VALUE
, 1);
83 EXPECT_LT(cohort
, RapporParameters::kMaxCohorts
);
84 // The preferences should be consistent with the loaded value.
85 int32_t pref
= test_prefs_
.GetInteger(prefs::kRapporCohortSeed
);
86 EXPECT_EQ(pref
, cohort
);
89 TEST_F(RapporPrefsTest
, EmptySecret
) {
90 test_prefs_
.ClearPref(prefs::kRapporSecret
);
91 // Loaded secret should be rerolled from empty.
92 std::string secret2
= LoadSecret(&test_prefs_
);
93 tester_
.ExpectUniqueSample(kLoadSecretHistogramName
, LOAD_EMPTY_VALUE
, 1);
94 EXPECT_EQ(HmacByteVectorGenerator::kEntropyInputSize
, secret2
.size());
95 // The stored preference should also be updated.
96 ExpectConsistentSecret(test_prefs_
, secret2
);
99 TEST_F(RapporPrefsTest
, LoadSecret
) {
100 std::string secret1
= HmacByteVectorGenerator::GenerateEntropyInput();
101 StoreSecret(secret1
, &test_prefs_
);
102 // Secret should load successfully.
103 std::string secret2
= LoadSecret(&test_prefs_
);
104 tester_
.ExpectUniqueSample(kLoadSecretHistogramName
, LOAD_SUCCESS
, 1);
105 EXPECT_EQ(secret1
, secret2
);
106 // The stored preference should also be unchanged.
107 ExpectConsistentSecret(test_prefs_
, secret2
);
110 TEST_F(RapporPrefsTest
, CorruptSecret
) {
111 // Store an invalid secret in the preferences that won't decode as base64.
112 test_prefs_
.SetString(prefs::kRapporSecret
, "!!INVALID!!");
113 // We should have rerolled a new secret.
114 std::string secret2
= LoadSecret(&test_prefs_
);
115 tester_
.ExpectUniqueSample(kLoadSecretHistogramName
, LOAD_CORRUPT_VALUE
, 1);
116 EXPECT_EQ(HmacByteVectorGenerator::kEntropyInputSize
, secret2
.size());
117 // The stored preference should also be updated.
118 ExpectConsistentSecret(test_prefs_
, secret2
);
121 TEST_F(RapporPrefsTest
, DecodableCorruptSecret
) {
122 // Store an invalid secret in the preferences that will decode as base64.
123 std::string secret1
= "!!INVALID!!";
124 StoreSecret(secret1
, &test_prefs_
);
125 // We should have rerolled a new secret.
126 std::string secret2
= LoadSecret(&test_prefs_
);
127 tester_
.ExpectUniqueSample(kLoadSecretHistogramName
, LOAD_CORRUPT_VALUE
, 1);
128 EXPECT_NE(secret1
, secret2
);
129 EXPECT_EQ(HmacByteVectorGenerator::kEntropyInputSize
, secret2
.size());
130 // The stored preference should also be updated.
131 ExpectConsistentSecret(test_prefs_
, secret2
);
134 } // namespace internal
136 } // namespace rappor