1 // Copyright 2020 The Chromium Authors
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/entropy_state.h"
6
7 #include <string>
8
9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/string_util.h"
11 #include "components/metrics/metrics_pref_names.h"
12 #include "components/metrics/metrics_service.h"
13 #include "components/prefs/testing_pref_service.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 namespace metrics {
17
18 class EntropyStateTest : public testing::Test {
19 public:
EntropyStateTest()20 EntropyStateTest() { MetricsService::RegisterPrefs(prefs_.registry()); }
21
22 EntropyStateTest(const EntropyStateTest&) = delete;
23 EntropyStateTest& operator=(const EntropyStateTest&) = delete;
24
25 protected:
26 TestingPrefServiceSimple prefs_;
27 };
28
TEST_F(EntropyStateTest,LowEntropySourceNotReset)29 TEST_F(EntropyStateTest, LowEntropySourceNotReset) {
30 EntropyState entropy_state(&prefs_);
31 // Get the low entropy source once, to initialize it.
32 entropy_state.GetLowEntropySource();
33
34 // Now, set it to 0 and ensure it doesn't get reset.
35 entropy_state.low_entropy_source_ = 0;
36 EXPECT_EQ(0, entropy_state.GetLowEntropySource());
37 // Call it another time, just to make sure.
38 EXPECT_EQ(0, entropy_state.GetLowEntropySource());
39 }
40
TEST_F(EntropyStateTest,PseudoLowEntropySourceNotReset)41 TEST_F(EntropyStateTest, PseudoLowEntropySourceNotReset) {
42 EntropyState entropy_state(&prefs_);
43 // Get the pseudo low entropy source once, to initialize it.
44 entropy_state.GetPseudoLowEntropySource();
45
46 // Now, set it to 0 and ensure it doesn't get reset.
47 entropy_state.pseudo_low_entropy_source_ = 0;
48 EXPECT_EQ(0, entropy_state.GetPseudoLowEntropySource());
49 // Call it another time, just to make sure.
50 EXPECT_EQ(0, entropy_state.GetPseudoLowEntropySource());
51 }
52
TEST_F(EntropyStateTest,HaveNoLowEntropySource)53 TEST_F(EntropyStateTest, HaveNoLowEntropySource) {
54 EntropyState entropy_state(&prefs_);
55 // If we have none of the new, old, or pseudo low entropy sources in prefs,
56 // then the new source should be created...
57 int new_low_source = entropy_state.GetLowEntropySource();
58 EXPECT_TRUE(EntropyState::IsValidLowEntropySource(new_low_source))
59 << new_low_source;
60 int pseudo_low_source = entropy_state.GetPseudoLowEntropySource();
61 EXPECT_TRUE(EntropyState::IsValidLowEntropySource(pseudo_low_source))
62 << pseudo_low_source;
63 // ...but the old source should not...
64 EXPECT_EQ(EntropyState::kLowEntropySourceNotSet,
65 entropy_state.GetOldLowEntropySource());
66 // ...and the high entropy source should include the *new* low entropy source.
67 std::string high_source = entropy_state.GetHighEntropySource(
68 "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEF");
69 EXPECT_TRUE(base::EndsWith(high_source, base::NumberToString(new_low_source),
70 base::CompareCase::SENSITIVE))
71 << high_source;
72 }
73
TEST_F(EntropyStateTest,HaveOnlyNewLowEntropySource)74 TEST_F(EntropyStateTest, HaveOnlyNewLowEntropySource) {
75 // If we have the new low entropy sources in prefs, but not the old one...
76 const int new_low_source = 1234;
77 prefs_.SetInteger(prefs::kMetricsLowEntropySource, new_low_source);
78
79 EntropyState entropy_state(&prefs_);
80 // ...then the new source should be loaded...
81 EXPECT_EQ(new_low_source, entropy_state.GetLowEntropySource());
82 // ...but the old source should not be created...
83 EXPECT_EQ(EntropyState::kLowEntropySourceNotSet,
84 entropy_state.GetOldLowEntropySource());
85 // ...and the high entropy source should include the *new* low entropy source.
86 std::string high_source = entropy_state.GetHighEntropySource(
87 "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEF");
88 EXPECT_TRUE(base::EndsWith(high_source, base::NumberToString(new_low_source),
89 base::CompareCase::SENSITIVE))
90 << high_source;
91 }
92
TEST_F(EntropyStateTest,HaveOnlyOldLowEntropySource)93 TEST_F(EntropyStateTest, HaveOnlyOldLowEntropySource) {
94 // If we have the old low entropy sources in prefs, but not the new one...
95 const int old_low_source = 5678;
96 prefs_.SetInteger(prefs::kMetricsOldLowEntropySource, old_low_source);
97
98 // ...then the new source should be created...
99 EntropyState entropy_state(&prefs_);
100
101 int new_low_source = entropy_state.GetLowEntropySource();
102 EXPECT_TRUE(EntropyState::IsValidLowEntropySource(new_low_source))
103 << new_low_source;
104 // ...and the old source should be loaded...
105 EXPECT_EQ(old_low_source, entropy_state.GetOldLowEntropySource());
106 // ...and the high entropy source should include the *old* low entropy source.
107 std::string high_source = entropy_state.GetHighEntropySource(
108 "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEF");
109 EXPECT_TRUE(base::EndsWith(high_source, base::NumberToString(old_low_source),
110 base::CompareCase::SENSITIVE))
111 << high_source;
112 }
113
TEST_F(EntropyStateTest,HaveAllLowEntropySources)114 TEST_F(EntropyStateTest, HaveAllLowEntropySources) {
115 // If we have all three of new, old, and pseudo low entropy sources in
116 // prefs...
117 const int new_low_source = 1234;
118 const int old_low_source = 5678;
119 const int pseudo_low_source = 4321;
120 prefs_.SetInteger(prefs::kMetricsLowEntropySource, new_low_source);
121 prefs_.SetInteger(prefs::kMetricsOldLowEntropySource, old_low_source);
122 prefs_.SetInteger(prefs::kMetricsPseudoLowEntropySource, pseudo_low_source);
123
124 // ...then all three should be loaded...
125 EntropyState entropy_state(&prefs_);
126
127 EXPECT_EQ(new_low_source, entropy_state.GetLowEntropySource());
128 EXPECT_EQ(old_low_source, entropy_state.GetOldLowEntropySource());
129 EXPECT_EQ(pseudo_low_source, entropy_state.GetPseudoLowEntropySource());
130 // ...and the high entropy source should include the *old* low entropy source.
131 std::string high_source = entropy_state.GetHighEntropySource(
132 "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEF");
133 EXPECT_TRUE(base::EndsWith(high_source, base::NumberToString(old_low_source),
134 base::CompareCase::SENSITIVE))
135 << high_source;
136 }
137
TEST_F(EntropyStateTest,CorruptNewLowEntropySources)138 TEST_F(EntropyStateTest, CorruptNewLowEntropySources) {
139 EntropyState entropy_state(&prefs_);
140 const int corrupt_sources[] = {-12345, -1, 8000, 12345};
141 for (int corrupt_source : corrupt_sources) {
142 // If the new low entropy source has been corrupted...
143 EXPECT_FALSE(EntropyState::IsValidLowEntropySource(corrupt_source))
144 << corrupt_source;
145 prefs_.SetInteger(prefs::kMetricsLowEntropySource, corrupt_source);
146 // ...then a new source should be created.
147 int loaded_source = entropy_state.GetLowEntropySource();
148 EXPECT_TRUE(EntropyState::IsValidLowEntropySource(loaded_source))
149 << loaded_source;
150 }
151 }
152
TEST_F(EntropyStateTest,CorruptOldLowEntropySources)153 TEST_F(EntropyStateTest, CorruptOldLowEntropySources) {
154 EntropyState entropy_state(&prefs_);
155 const int corrupt_sources[] = {-12345, -1, 8000, 12345};
156 for (int corrupt_source : corrupt_sources) {
157 // If the old low entropy source has been corrupted...
158 EXPECT_FALSE(EntropyState::IsValidLowEntropySource(corrupt_source))
159 << corrupt_source;
160 prefs_.SetInteger(prefs::kMetricsOldLowEntropySource, corrupt_source);
161 // ...then it should be ignored.
162 EXPECT_EQ(EntropyState::kLowEntropySourceNotSet,
163 entropy_state.GetOldLowEntropySource());
164 }
165 }
166
TEST_F(EntropyStateTest,ClearPrefs)167 TEST_F(EntropyStateTest, ClearPrefs) {
168 prefs_.SetInteger(prefs::kMetricsLowEntropySource, 1234);
169 prefs_.SetInteger(prefs::kMetricsOldLowEntropySource, 5678);
170 prefs_.SetInteger(prefs::kMetricsPseudoLowEntropySource, 4321);
171
172 EntropyState::ClearPrefs(&prefs_);
173
174 EXPECT_FALSE(prefs_.HasPrefPath(prefs::kMetricsLowEntropySource));
175 EXPECT_FALSE(prefs_.HasPrefPath(prefs::kMetricsOldLowEntropySource));
176 EXPECT_FALSE(prefs_.HasPrefPath(prefs::kMetricsPseudoLowEntropySource));
177 }
178
179 } // namespace metrics
180