• 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/files/scoped_temp_dir.h>
26 #include <base/macros.h>
27 #include <base/strings/string_util.h>
28 #include <base/strings/stringprintf.h>
29 #include <gmock/gmock.h>
30 #include <gtest/gtest.h>
31 
32 using std::string;
33 using testing::_;
34 using testing::Eq;
35 
36 namespace {
37 // Test key used along the tests.
38 const char kKey[] = "test-key";
39 }  // namespace
40 
41 namespace chromeos_update_engine {
42 
43 class PrefsTest : public ::testing::Test {
44  protected:
SetUp()45   void SetUp() override {
46     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
47     prefs_dir_ = temp_dir_.GetPath();
48     ASSERT_TRUE(prefs_.Init(prefs_dir_));
49   }
50 
SetValue(const string & key,const string & value)51   bool SetValue(const string& key, const string& value) {
52     return base::WriteFile(prefs_dir_.Append(key),
53                            value.data(),
54                            value.length()) == static_cast<int>(value.length());
55   }
56 
57   base::ScopedTempDir temp_dir_;
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(
148       kKey,
149       base::StringPrintf("%" PRIi64, std::numeric_limits<int64_t>::max())));
150   int64_t value;
151   EXPECT_TRUE(prefs_.GetInt64(kKey, &value));
152   EXPECT_EQ(std::numeric_limits<int64_t>::max(), value);
153 }
154 
TEST_F(PrefsTest,GetInt64Min)155 TEST_F(PrefsTest, GetInt64Min) {
156   ASSERT_TRUE(SetValue(
157       kKey,
158       base::StringPrintf("%" PRIi64, std::numeric_limits<int64_t>::min())));
159   int64_t value;
160   EXPECT_TRUE(prefs_.GetInt64(kKey, &value));
161   EXPECT_EQ(std::numeric_limits<int64_t>::min(), value);
162 }
163 
TEST_F(PrefsTest,GetInt64Negative)164 TEST_F(PrefsTest, GetInt64Negative) {
165   ASSERT_TRUE(SetValue(kKey, " \t -100 \n "));
166   int64_t value;
167   EXPECT_TRUE(prefs_.GetInt64(kKey, &value));
168   EXPECT_EQ(-100, value);
169 }
170 
TEST_F(PrefsTest,GetInt64NonExistentKey)171 TEST_F(PrefsTest, GetInt64NonExistentKey) {
172   int64_t value;
173   EXPECT_FALSE(prefs_.GetInt64("random-key", &value));
174 }
175 
TEST_F(PrefsTest,SetInt64)176 TEST_F(PrefsTest, SetInt64) {
177   EXPECT_TRUE(prefs_.SetInt64(kKey, -123));
178   string value;
179   EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
180   EXPECT_EQ("-123", value);
181 }
182 
TEST_F(PrefsTest,SetInt64BadKey)183 TEST_F(PrefsTest, SetInt64BadKey) {
184   const char kKeyWithSpaces[] = "s p a c e s";
185   EXPECT_FALSE(prefs_.SetInt64(kKeyWithSpaces, 20));
186   EXPECT_FALSE(base::PathExists(prefs_dir_.Append(kKeyWithSpaces)));
187 }
188 
TEST_F(PrefsTest,SetInt64Max)189 TEST_F(PrefsTest, SetInt64Max) {
190   EXPECT_TRUE(prefs_.SetInt64(kKey, std::numeric_limits<int64_t>::max()));
191   string value;
192   EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
193   EXPECT_EQ(base::StringPrintf("%" PRIi64, std::numeric_limits<int64_t>::max()),
194             value);
195 }
196 
TEST_F(PrefsTest,SetInt64Min)197 TEST_F(PrefsTest, SetInt64Min) {
198   EXPECT_TRUE(prefs_.SetInt64(kKey, std::numeric_limits<int64_t>::min()));
199   string value;
200   EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
201   EXPECT_EQ(base::StringPrintf("%" PRIi64, std::numeric_limits<int64_t>::min()),
202             value);
203 }
204 
TEST_F(PrefsTest,GetBooleanFalse)205 TEST_F(PrefsTest, GetBooleanFalse) {
206   ASSERT_TRUE(SetValue(kKey, " \n false \t "));
207   bool value;
208   EXPECT_TRUE(prefs_.GetBoolean(kKey, &value));
209   EXPECT_FALSE(value);
210 }
211 
TEST_F(PrefsTest,GetBooleanTrue)212 TEST_F(PrefsTest, GetBooleanTrue) {
213   const char kKey[] = "test-key";
214   ASSERT_TRUE(SetValue(kKey, " \t true \n "));
215   bool value;
216   EXPECT_TRUE(prefs_.GetBoolean(kKey, &value));
217   EXPECT_TRUE(value);
218 }
219 
TEST_F(PrefsTest,GetBooleanBadValue)220 TEST_F(PrefsTest, GetBooleanBadValue) {
221   const char kKey[] = "test-key";
222   ASSERT_TRUE(SetValue(kKey, "1"));
223   bool value;
224   EXPECT_FALSE(prefs_.GetBoolean(kKey, &value));
225 }
226 
TEST_F(PrefsTest,GetBooleanBadEmptyValue)227 TEST_F(PrefsTest, GetBooleanBadEmptyValue) {
228   const char kKey[] = "test-key";
229   ASSERT_TRUE(SetValue(kKey, ""));
230   bool value;
231   EXPECT_FALSE(prefs_.GetBoolean(kKey, &value));
232 }
233 
TEST_F(PrefsTest,GetBooleanNonExistentKey)234 TEST_F(PrefsTest, GetBooleanNonExistentKey) {
235   bool value;
236   EXPECT_FALSE(prefs_.GetBoolean("random-key", &value));
237 }
238 
TEST_F(PrefsTest,SetBooleanTrue)239 TEST_F(PrefsTest, SetBooleanTrue) {
240   const char kKey[] = "test-bool";
241   EXPECT_TRUE(prefs_.SetBoolean(kKey, true));
242   string value;
243   EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
244   EXPECT_EQ("true", value);
245 }
246 
TEST_F(PrefsTest,SetBooleanFalse)247 TEST_F(PrefsTest, SetBooleanFalse) {
248   const char kKey[] = "test-bool";
249   EXPECT_TRUE(prefs_.SetBoolean(kKey, false));
250   string value;
251   EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
252   EXPECT_EQ("false", value);
253 }
254 
TEST_F(PrefsTest,SetBooleanBadKey)255 TEST_F(PrefsTest, SetBooleanBadKey) {
256   const char kKey[] = "s p a c e s";
257   EXPECT_FALSE(prefs_.SetBoolean(kKey, true));
258   EXPECT_FALSE(base::PathExists(prefs_dir_.Append(kKey)));
259 }
260 
TEST_F(PrefsTest,ExistsWorks)261 TEST_F(PrefsTest, ExistsWorks) {
262   // test that the key doesn't exist before we set it.
263   EXPECT_FALSE(prefs_.Exists(kKey));
264 
265   // test that the key exists after we set it.
266   ASSERT_TRUE(prefs_.SetInt64(kKey, 8));
267   EXPECT_TRUE(prefs_.Exists(kKey));
268 }
269 
TEST_F(PrefsTest,DeleteWorks)270 TEST_F(PrefsTest, DeleteWorks) {
271   // test that it's alright to delete a non-existent key.
272   EXPECT_TRUE(prefs_.Delete(kKey));
273 
274   // delete the key after we set it.
275   ASSERT_TRUE(prefs_.SetInt64(kKey, 0));
276   EXPECT_TRUE(prefs_.Delete(kKey));
277 
278   // make sure it doesn't exist anymore.
279   EXPECT_FALSE(prefs_.Exists(kKey));
280 }
281 
282 class MockPrefsObserver : public PrefsInterface::ObserverInterface {
283  public:
284   MOCK_METHOD1(OnPrefSet, void(const string&));
285   MOCK_METHOD1(OnPrefDeleted, void(const string& key));
286 };
287 
TEST_F(PrefsTest,ObserversCalled)288 TEST_F(PrefsTest, ObserversCalled) {
289   MockPrefsObserver mock_obserser;
290   prefs_.AddObserver(kKey, &mock_obserser);
291 
292   EXPECT_CALL(mock_obserser, OnPrefSet(Eq(kKey)));
293   EXPECT_CALL(mock_obserser, OnPrefDeleted(_)).Times(0);
294   prefs_.SetString(kKey, "value");
295   testing::Mock::VerifyAndClearExpectations(&mock_obserser);
296 
297   EXPECT_CALL(mock_obserser, OnPrefSet(_)).Times(0);
298   EXPECT_CALL(mock_obserser, OnPrefDeleted(Eq(kKey)));
299   prefs_.Delete(kKey);
300   testing::Mock::VerifyAndClearExpectations(&mock_obserser);
301 
302   prefs_.RemoveObserver(kKey, &mock_obserser);
303 }
304 
TEST_F(PrefsTest,OnlyCalledOnObservedKeys)305 TEST_F(PrefsTest, OnlyCalledOnObservedKeys) {
306   MockPrefsObserver mock_obserser;
307   const char kUnusedKey[] = "unused-key";
308   prefs_.AddObserver(kUnusedKey, &mock_obserser);
309 
310   EXPECT_CALL(mock_obserser, OnPrefSet(_)).Times(0);
311   EXPECT_CALL(mock_obserser, OnPrefDeleted(_)).Times(0);
312   prefs_.SetString(kKey, "value");
313   prefs_.Delete(kKey);
314 
315   prefs_.RemoveObserver(kUnusedKey, &mock_obserser);
316 }
317 
TEST_F(PrefsTest,RemovedObserversNotCalled)318 TEST_F(PrefsTest, RemovedObserversNotCalled) {
319   MockPrefsObserver mock_obserser_a, mock_obserser_b;
320   prefs_.AddObserver(kKey, &mock_obserser_a);
321   prefs_.AddObserver(kKey, &mock_obserser_b);
322   EXPECT_CALL(mock_obserser_a, OnPrefSet(_)).Times(2);
323   EXPECT_CALL(mock_obserser_b, OnPrefSet(_)).Times(1);
324   EXPECT_TRUE(prefs_.SetString(kKey, "value"));
325   prefs_.RemoveObserver(kKey, &mock_obserser_b);
326   EXPECT_TRUE(prefs_.SetString(kKey, "other value"));
327   prefs_.RemoveObserver(kKey, &mock_obserser_a);
328   EXPECT_TRUE(prefs_.SetString(kKey, "yet another value"));
329 }
330 
TEST_F(PrefsTest,UnsuccessfulCallsNotObserved)331 TEST_F(PrefsTest, UnsuccessfulCallsNotObserved) {
332   MockPrefsObserver mock_obserser;
333   const char kInvalidKey[] = "no spaces or .";
334   prefs_.AddObserver(kInvalidKey, &mock_obserser);
335 
336   EXPECT_CALL(mock_obserser, OnPrefSet(_)).Times(0);
337   EXPECT_CALL(mock_obserser, OnPrefDeleted(_)).Times(0);
338   EXPECT_FALSE(prefs_.SetString(kInvalidKey, "value"));
339   EXPECT_FALSE(prefs_.Delete(kInvalidKey));
340 
341   prefs_.RemoveObserver(kInvalidKey, &mock_obserser);
342 }
343 
344 class MemoryPrefsTest : public ::testing::Test {
345  protected:
346   MemoryPrefs prefs_;
347 };
348 
TEST_F(MemoryPrefsTest,BasicTest)349 TEST_F(MemoryPrefsTest, BasicTest) {
350   EXPECT_FALSE(prefs_.Exists(kKey));
351   int64_t value = 0;
352   EXPECT_FALSE(prefs_.GetInt64(kKey, &value));
353 
354   EXPECT_TRUE(prefs_.SetInt64(kKey, 1234));
355   EXPECT_TRUE(prefs_.Exists(kKey));
356   EXPECT_TRUE(prefs_.GetInt64(kKey, &value));
357   EXPECT_EQ(1234, value);
358 
359   EXPECT_TRUE(prefs_.Delete(kKey));
360   EXPECT_FALSE(prefs_.Exists(kKey));
361   EXPECT_FALSE(prefs_.Delete(kKey));
362 }
363 
364 }  // namespace chromeos_update_engine
365