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