• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (C) 2012 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #include "update_engine/common/prefs.h"
18 
19 #include <inttypes.h>
20 
21 #include <limits>
22 #include <string>
23 
24 #include <base/files/file_util.h>
25 #include <base/macros.h>
26 #include <base/strings/string_util.h>
27 #include <base/strings/stringprintf.h>
28 #include <gmock/gmock.h>
29 #include <gtest/gtest.h>
30 
31 using std::string;
32 using testing::Eq;
33 using testing::_;
34 
35 namespace {
36 // Test key used along the tests.
37 const char kKey[] = "test-key";
38 }
39 
40 namespace chromeos_update_engine {
41 
42 class PrefsTest : public ::testing::Test {
43  protected:
SetUp()44   void SetUp() override {
45     ASSERT_TRUE(base::CreateNewTempDirectory("auprefs", &prefs_dir_));
46     ASSERT_TRUE(prefs_.Init(prefs_dir_));
47   }
48 
TearDown()49   void TearDown() override {
50     base::DeleteFile(prefs_dir_, true);  // recursive
51   }
52 
SetValue(const string & key,const string & value)53   bool SetValue(const string& key, const string& value) {
54     return base::WriteFile(prefs_dir_.Append(key), value.data(),
55                            value.length()) == static_cast<int>(value.length());
56   }
57 
58   base::FilePath prefs_dir_;
59   Prefs prefs_;
60 };
61 
TEST_F(PrefsTest,GetFileNameForKey)62 TEST_F(PrefsTest, GetFileNameForKey) {
63   const char kAllvalidCharsKey[] =
64       "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-";
65   base::FilePath path;
66   EXPECT_TRUE(prefs_.file_storage_.GetFileNameForKey(kAllvalidCharsKey, &path));
67   EXPECT_EQ(prefs_dir_.Append(kAllvalidCharsKey).value(), path.value());
68 }
69 
TEST_F(PrefsTest,GetFileNameForKeyBadCharacter)70 TEST_F(PrefsTest, GetFileNameForKeyBadCharacter) {
71   base::FilePath path;
72   EXPECT_FALSE(prefs_.file_storage_.GetFileNameForKey("ABC abc", &path));
73 }
74 
TEST_F(PrefsTest,GetFileNameForKeyEmpty)75 TEST_F(PrefsTest, GetFileNameForKeyEmpty) {
76   base::FilePath path;
77   EXPECT_FALSE(prefs_.file_storage_.GetFileNameForKey("", &path));
78 }
79 
TEST_F(PrefsTest,GetString)80 TEST_F(PrefsTest, GetString) {
81   const string test_data = "test data";
82   ASSERT_TRUE(SetValue(kKey, test_data));
83   string value;
84   EXPECT_TRUE(prefs_.GetString(kKey, &value));
85   EXPECT_EQ(test_data, value);
86 }
87 
TEST_F(PrefsTest,GetStringBadKey)88 TEST_F(PrefsTest, GetStringBadKey) {
89   string value;
90   EXPECT_FALSE(prefs_.GetString(",bad", &value));
91 }
92 
TEST_F(PrefsTest,GetStringNonExistentKey)93 TEST_F(PrefsTest, GetStringNonExistentKey) {
94   string value;
95   EXPECT_FALSE(prefs_.GetString("non-existent-key", &value));
96 }
97 
TEST_F(PrefsTest,SetString)98 TEST_F(PrefsTest, SetString) {
99   const char kValue[] = "some test value\non 2 lines";
100   EXPECT_TRUE(prefs_.SetString(kKey, kValue));
101   string value;
102   EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
103   EXPECT_EQ(kValue, value);
104 }
105 
TEST_F(PrefsTest,SetStringBadKey)106 TEST_F(PrefsTest, SetStringBadKey) {
107   const char kKeyWithDots[] = ".no-dots";
108   EXPECT_FALSE(prefs_.SetString(kKeyWithDots, "some value"));
109   EXPECT_FALSE(base::PathExists(prefs_dir_.Append(kKeyWithDots)));
110 }
111 
TEST_F(PrefsTest,SetStringCreateDir)112 TEST_F(PrefsTest, SetStringCreateDir) {
113   const char kValue[] = "test value";
114   base::FilePath subdir = prefs_dir_.Append("subdir1").Append("subdir2");
115   EXPECT_TRUE(prefs_.Init(subdir));
116   EXPECT_TRUE(prefs_.SetString(kKey, kValue));
117   string value;
118   EXPECT_TRUE(base::ReadFileToString(subdir.Append(kKey), &value));
119   EXPECT_EQ(kValue, value);
120 }
121 
TEST_F(PrefsTest,SetStringDirCreationFailure)122 TEST_F(PrefsTest, SetStringDirCreationFailure) {
123   EXPECT_TRUE(prefs_.Init(base::FilePath("/dev/null")));
124   EXPECT_FALSE(prefs_.SetString(kKey, "test value"));
125 }
126 
TEST_F(PrefsTest,SetStringFileCreationFailure)127 TEST_F(PrefsTest, SetStringFileCreationFailure) {
128   base::CreateDirectory(prefs_dir_.Append(kKey));
129   EXPECT_FALSE(prefs_.SetString(kKey, "test value"));
130   EXPECT_TRUE(base::DirectoryExists(prefs_dir_.Append(kKey)));
131 }
132 
TEST_F(PrefsTest,GetInt64)133 TEST_F(PrefsTest, GetInt64) {
134   ASSERT_TRUE(SetValue(kKey, " \n 25 \t "));
135   int64_t value;
136   EXPECT_TRUE(prefs_.GetInt64(kKey, &value));
137   EXPECT_EQ(25, value);
138 }
139 
TEST_F(PrefsTest,GetInt64BadValue)140 TEST_F(PrefsTest, GetInt64BadValue) {
141   ASSERT_TRUE(SetValue(kKey, "30a"));
142   int64_t value;
143   EXPECT_FALSE(prefs_.GetInt64(kKey, &value));
144 }
145 
TEST_F(PrefsTest,GetInt64Max)146 TEST_F(PrefsTest, GetInt64Max) {
147   ASSERT_TRUE(SetValue(kKey, base::StringPrintf(
148       "%" PRIi64, std::numeric_limits<int64_t>::max())));
149   int64_t value;
150   EXPECT_TRUE(prefs_.GetInt64(kKey, &value));
151   EXPECT_EQ(std::numeric_limits<int64_t>::max(), value);
152 }
153 
TEST_F(PrefsTest,GetInt64Min)154 TEST_F(PrefsTest, GetInt64Min) {
155   ASSERT_TRUE(SetValue(kKey, base::StringPrintf(
156         "%" PRIi64, std::numeric_limits<int64_t>::min())));
157   int64_t value;
158   EXPECT_TRUE(prefs_.GetInt64(kKey, &value));
159   EXPECT_EQ(std::numeric_limits<int64_t>::min(), value);
160 }
161 
TEST_F(PrefsTest,GetInt64Negative)162 TEST_F(PrefsTest, GetInt64Negative) {
163   ASSERT_TRUE(SetValue(kKey, " \t -100 \n "));
164   int64_t value;
165   EXPECT_TRUE(prefs_.GetInt64(kKey, &value));
166   EXPECT_EQ(-100, value);
167 }
168 
TEST_F(PrefsTest,GetInt64NonExistentKey)169 TEST_F(PrefsTest, GetInt64NonExistentKey) {
170   int64_t value;
171   EXPECT_FALSE(prefs_.GetInt64("random-key", &value));
172 }
173 
TEST_F(PrefsTest,SetInt64)174 TEST_F(PrefsTest, SetInt64) {
175   EXPECT_TRUE(prefs_.SetInt64(kKey, -123));
176   string value;
177   EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
178   EXPECT_EQ("-123", value);
179 }
180 
TEST_F(PrefsTest,SetInt64BadKey)181 TEST_F(PrefsTest, SetInt64BadKey) {
182   const char kKeyWithSpaces[] = "s p a c e s";
183   EXPECT_FALSE(prefs_.SetInt64(kKeyWithSpaces, 20));
184   EXPECT_FALSE(base::PathExists(prefs_dir_.Append(kKeyWithSpaces)));
185 }
186 
TEST_F(PrefsTest,SetInt64Max)187 TEST_F(PrefsTest, SetInt64Max) {
188   EXPECT_TRUE(prefs_.SetInt64(kKey, std::numeric_limits<int64_t>::max()));
189   string value;
190   EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
191   EXPECT_EQ(base::StringPrintf("%" PRIi64, std::numeric_limits<int64_t>::max()),
192             value);
193 }
194 
TEST_F(PrefsTest,SetInt64Min)195 TEST_F(PrefsTest, SetInt64Min) {
196   EXPECT_TRUE(prefs_.SetInt64(kKey, std::numeric_limits<int64_t>::min()));
197   string value;
198   EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
199   EXPECT_EQ(base::StringPrintf("%" PRIi64, std::numeric_limits<int64_t>::min()),
200             value);
201 }
202 
TEST_F(PrefsTest,GetBooleanFalse)203 TEST_F(PrefsTest, GetBooleanFalse) {
204   ASSERT_TRUE(SetValue(kKey, " \n false \t "));
205   bool value;
206   EXPECT_TRUE(prefs_.GetBoolean(kKey, &value));
207   EXPECT_FALSE(value);
208 }
209 
TEST_F(PrefsTest,GetBooleanTrue)210 TEST_F(PrefsTest, GetBooleanTrue) {
211   const char kKey[] = "test-key";
212   ASSERT_TRUE(SetValue(kKey, " \t true \n "));
213   bool value;
214   EXPECT_TRUE(prefs_.GetBoolean(kKey, &value));
215   EXPECT_TRUE(value);
216 }
217 
TEST_F(PrefsTest,GetBooleanBadValue)218 TEST_F(PrefsTest, GetBooleanBadValue) {
219   const char kKey[] = "test-key";
220   ASSERT_TRUE(SetValue(kKey, "1"));
221   bool value;
222   EXPECT_FALSE(prefs_.GetBoolean(kKey, &value));
223 }
224 
TEST_F(PrefsTest,GetBooleanBadEmptyValue)225 TEST_F(PrefsTest, GetBooleanBadEmptyValue) {
226   const char kKey[] = "test-key";
227   ASSERT_TRUE(SetValue(kKey, ""));
228   bool value;
229   EXPECT_FALSE(prefs_.GetBoolean(kKey, &value));
230 }
231 
TEST_F(PrefsTest,GetBooleanNonExistentKey)232 TEST_F(PrefsTest, GetBooleanNonExistentKey) {
233   bool value;
234   EXPECT_FALSE(prefs_.GetBoolean("random-key", &value));
235 }
236 
TEST_F(PrefsTest,SetBooleanTrue)237 TEST_F(PrefsTest, SetBooleanTrue) {
238   const char kKey[] = "test-bool";
239   EXPECT_TRUE(prefs_.SetBoolean(kKey, true));
240   string value;
241   EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
242   EXPECT_EQ("true", value);
243 }
244 
TEST_F(PrefsTest,SetBooleanFalse)245 TEST_F(PrefsTest, SetBooleanFalse) {
246   const char kKey[] = "test-bool";
247   EXPECT_TRUE(prefs_.SetBoolean(kKey, false));
248   string value;
249   EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
250   EXPECT_EQ("false", value);
251 }
252 
TEST_F(PrefsTest,SetBooleanBadKey)253 TEST_F(PrefsTest, SetBooleanBadKey) {
254   const char kKey[] = "s p a c e s";
255   EXPECT_FALSE(prefs_.SetBoolean(kKey, true));
256   EXPECT_FALSE(base::PathExists(prefs_dir_.Append(kKey)));
257 }
258 
TEST_F(PrefsTest,ExistsWorks)259 TEST_F(PrefsTest, ExistsWorks) {
260   // test that the key doesn't exist before we set it.
261   EXPECT_FALSE(prefs_.Exists(kKey));
262 
263   // test that the key exists after we set it.
264   ASSERT_TRUE(prefs_.SetInt64(kKey, 8));
265   EXPECT_TRUE(prefs_.Exists(kKey));
266 }
267 
TEST_F(PrefsTest,DeleteWorks)268 TEST_F(PrefsTest, DeleteWorks) {
269   // test that it's alright to delete a non-existent key.
270   EXPECT_TRUE(prefs_.Delete(kKey));
271 
272   // delete the key after we set it.
273   ASSERT_TRUE(prefs_.SetInt64(kKey, 0));
274   EXPECT_TRUE(prefs_.Delete(kKey));
275 
276   // make sure it doesn't exist anymore.
277   EXPECT_FALSE(prefs_.Exists(kKey));
278 }
279 
280 class MockPrefsObserver : public PrefsInterface::ObserverInterface {
281  public:
282   MOCK_METHOD1(OnPrefSet, void(const string&));
283   MOCK_METHOD1(OnPrefDeleted, void(const string& key));
284 };
285 
TEST_F(PrefsTest,ObserversCalled)286 TEST_F(PrefsTest, ObserversCalled) {
287   MockPrefsObserver mock_obserser;
288   prefs_.AddObserver(kKey, &mock_obserser);
289 
290   EXPECT_CALL(mock_obserser, OnPrefSet(Eq(kKey)));
291   EXPECT_CALL(mock_obserser, OnPrefDeleted(_)).Times(0);
292   prefs_.SetString(kKey, "value");
293   testing::Mock::VerifyAndClearExpectations(&mock_obserser);
294 
295   EXPECT_CALL(mock_obserser, OnPrefSet(_)).Times(0);
296   EXPECT_CALL(mock_obserser, OnPrefDeleted(Eq(kKey)));
297   prefs_.Delete(kKey);
298   testing::Mock::VerifyAndClearExpectations(&mock_obserser);
299 
300   prefs_.RemoveObserver(kKey, &mock_obserser);
301 }
302 
TEST_F(PrefsTest,OnlyCalledOnObservedKeys)303 TEST_F(PrefsTest, OnlyCalledOnObservedKeys) {
304   MockPrefsObserver mock_obserser;
305   const char kUnusedKey[] = "unused-key";
306   prefs_.AddObserver(kUnusedKey, &mock_obserser);
307 
308   EXPECT_CALL(mock_obserser, OnPrefSet(_)).Times(0);
309   EXPECT_CALL(mock_obserser, OnPrefDeleted(_)).Times(0);
310   prefs_.SetString(kKey, "value");
311   prefs_.Delete(kKey);
312 
313   prefs_.RemoveObserver(kUnusedKey, &mock_obserser);
314 }
315 
TEST_F(PrefsTest,RemovedObserversNotCalled)316 TEST_F(PrefsTest, RemovedObserversNotCalled) {
317   MockPrefsObserver mock_obserser_a, mock_obserser_b;
318   prefs_.AddObserver(kKey, &mock_obserser_a);
319   prefs_.AddObserver(kKey, &mock_obserser_b);
320   EXPECT_CALL(mock_obserser_a, OnPrefSet(_)).Times(2);
321   EXPECT_CALL(mock_obserser_b, OnPrefSet(_)).Times(1);
322   EXPECT_TRUE(prefs_.SetString(kKey, "value"));
323   prefs_.RemoveObserver(kKey, &mock_obserser_b);
324   EXPECT_TRUE(prefs_.SetString(kKey, "other value"));
325   prefs_.RemoveObserver(kKey, &mock_obserser_a);
326   EXPECT_TRUE(prefs_.SetString(kKey, "yet another value"));
327 }
328 
TEST_F(PrefsTest,UnsuccessfulCallsNotObserved)329 TEST_F(PrefsTest, UnsuccessfulCallsNotObserved) {
330   MockPrefsObserver mock_obserser;
331   const char kInvalidKey[] = "no spaces or .";
332   prefs_.AddObserver(kInvalidKey, &mock_obserser);
333 
334   EXPECT_CALL(mock_obserser, OnPrefSet(_)).Times(0);
335   EXPECT_CALL(mock_obserser, OnPrefDeleted(_)).Times(0);
336   EXPECT_FALSE(prefs_.SetString(kInvalidKey, "value"));
337   EXPECT_FALSE(prefs_.Delete(kInvalidKey));
338 
339   prefs_.RemoveObserver(kInvalidKey, &mock_obserser);
340 }
341 
342 class MemoryPrefsTest : public ::testing::Test {
343  protected:
344   MemoryPrefs prefs_;
345 };
346 
TEST_F(MemoryPrefsTest,BasicTest)347 TEST_F(MemoryPrefsTest, BasicTest) {
348   EXPECT_FALSE(prefs_.Exists(kKey));
349   int64_t value = 0;
350   EXPECT_FALSE(prefs_.GetInt64(kKey, &value));
351 
352   EXPECT_TRUE(prefs_.SetInt64(kKey, 1234));
353   EXPECT_TRUE(prefs_.Exists(kKey));
354   EXPECT_TRUE(prefs_.GetInt64(kKey, &value));
355   EXPECT_EQ(1234, value);
356 
357   EXPECT_TRUE(prefs_.Delete(kKey));
358   EXPECT_FALSE(prefs_.Exists(kKey));
359   EXPECT_FALSE(prefs_.Delete(kKey));
360 }
361 
362 }  // namespace chromeos_update_engine
363