blob: df356b1f91f23456aabe46fd4ba24cb43bdd8720 [file] [log] [blame]
Alex Deymoaea4c1c2015-08-19 20:24:43 -07001//
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//
Darin Petkov30030592010-07-27 13:53:20 -070016
Alex Deymoaab50e32014-11-10 19:55:35 -080017#include "update_engine/prefs.h"
18
Darin Petkov30030592010-07-27 13:53:20 -070019#include <inttypes.h>
20
21#include <string>
22
Ben Chan06c76a42014-09-05 08:21:06 -070023#include <base/files/file_util.h>
Ben Chan05735a12014-09-03 07:48:22 -070024#include <base/macros.h>
Alex Vakulenko75039d72014-03-25 12:36:28 -070025#include <base/strings/string_util.h>
26#include <base/strings/stringprintf.h>
Alex Deymod6f60072015-10-12 12:22:27 -070027#include <gmock/gmock.h>
Ben Chan05735a12014-09-03 07:48:22 -070028#include <gtest/gtest.h>
29
Darin Petkov30030592010-07-27 13:53:20 -070030using std::string;
Alex Deymod6f60072015-10-12 12:22:27 -070031using testing::Eq;
32using testing::_;
33
34namespace {
35// Test key used along the tests.
36const char kKey[] = "test-key";
37}
Darin Petkov30030592010-07-27 13:53:20 -070038
39namespace chromeos_update_engine {
40
41class PrefsTest : public ::testing::Test {
42 protected:
Alex Deymo610277e2014-11-11 21:18:11 -080043 void SetUp() override {
Alex Vakulenko75039d72014-03-25 12:36:28 -070044 ASSERT_TRUE(base::CreateNewTempDirectory("auprefs", &prefs_dir_));
Darin Petkov30030592010-07-27 13:53:20 -070045 ASSERT_TRUE(prefs_.Init(prefs_dir_));
46 }
47
Alex Deymo610277e2014-11-11 21:18:11 -080048 void TearDown() override {
Alex Vakulenko75039d72014-03-25 12:36:28 -070049 base::DeleteFile(prefs_dir_, true); // recursive
Darin Petkov30030592010-07-27 13:53:20 -070050 }
51
52 bool SetValue(const string& key, const string& value) {
Ben Chan736fcb52014-05-21 18:28:22 -070053 return base::WriteFile(prefs_dir_.Append(key), value.data(),
54 value.length()) == static_cast<int>(value.length());
Darin Petkov30030592010-07-27 13:53:20 -070055 }
56
Alex Vakulenko75039d72014-03-25 12:36:28 -070057 base::FilePath prefs_dir_;
Darin Petkov30030592010-07-27 13:53:20 -070058 Prefs prefs_;
59};
60
61TEST_F(PrefsTest, GetFileNameForKey) {
Alex Deymod6f60072015-10-12 12:22:27 -070062 const char kAllvalidCharsKey[] =
63 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-";
Alex Vakulenko75039d72014-03-25 12:36:28 -070064 base::FilePath path;
Alex Deymod6f60072015-10-12 12:22:27 -070065 EXPECT_TRUE(prefs_.GetFileNameForKey(kAllvalidCharsKey, &path));
66 EXPECT_EQ(prefs_dir_.Append(kAllvalidCharsKey).value(), path.value());
Darin Petkov30030592010-07-27 13:53:20 -070067}
68
69TEST_F(PrefsTest, GetFileNameForKeyBadCharacter) {
Alex Vakulenko75039d72014-03-25 12:36:28 -070070 base::FilePath path;
Darin Petkov30030592010-07-27 13:53:20 -070071 EXPECT_FALSE(prefs_.GetFileNameForKey("ABC abc", &path));
72}
73
74TEST_F(PrefsTest, GetFileNameForKeyEmpty) {
Alex Vakulenko75039d72014-03-25 12:36:28 -070075 base::FilePath path;
Darin Petkov30030592010-07-27 13:53:20 -070076 EXPECT_FALSE(prefs_.GetFileNameForKey("", &path));
77}
78
79TEST_F(PrefsTest, GetString) {
Darin Petkov30030592010-07-27 13:53:20 -070080 const string test_data = "test data";
81 ASSERT_TRUE(SetValue(kKey, test_data));
82 string value;
83 EXPECT_TRUE(prefs_.GetString(kKey, &value));
84 EXPECT_EQ(test_data, value);
85}
86
87TEST_F(PrefsTest, GetStringBadKey) {
88 string value;
89 EXPECT_FALSE(prefs_.GetString(",bad", &value));
90}
91
92TEST_F(PrefsTest, GetStringNonExistentKey) {
93 string value;
94 EXPECT_FALSE(prefs_.GetString("non-existent-key", &value));
95}
96
97TEST_F(PrefsTest, SetString) {
Darin Petkov30030592010-07-27 13:53:20 -070098 const char kValue[] = "some test value\non 2 lines";
99 EXPECT_TRUE(prefs_.SetString(kKey, kValue));
100 string value;
Alex Vakulenko75039d72014-03-25 12:36:28 -0700101 EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
Darin Petkov30030592010-07-27 13:53:20 -0700102 EXPECT_EQ(kValue, value);
103}
104
105TEST_F(PrefsTest, SetStringBadKey) {
Alex Deymod6f60072015-10-12 12:22:27 -0700106 const char kKeyWithDots[] = ".no-dots";
107 EXPECT_FALSE(prefs_.SetString(kKeyWithDots, "some value"));
108 EXPECT_FALSE(base::PathExists(prefs_dir_.Append(kKeyWithDots)));
Darin Petkov30030592010-07-27 13:53:20 -0700109}
110
111TEST_F(PrefsTest, SetStringCreateDir) {
Darin Petkov30030592010-07-27 13:53:20 -0700112 const char kValue[] = "test value";
Alex Vakulenko75039d72014-03-25 12:36:28 -0700113 base::FilePath subdir = prefs_dir_.Append("subdir1").Append("subdir2");
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700114 EXPECT_TRUE(prefs_.Init(subdir));
Darin Petkov30030592010-07-27 13:53:20 -0700115 EXPECT_TRUE(prefs_.SetString(kKey, kValue));
116 string value;
Alex Vakulenko75039d72014-03-25 12:36:28 -0700117 EXPECT_TRUE(base::ReadFileToString(subdir.Append(kKey), &value));
Darin Petkov30030592010-07-27 13:53:20 -0700118 EXPECT_EQ(kValue, value);
119}
120
121TEST_F(PrefsTest, SetStringDirCreationFailure) {
Alex Vakulenko75039d72014-03-25 12:36:28 -0700122 EXPECT_TRUE(prefs_.Init(base::FilePath("/dev/null")));
Darin Petkov30030592010-07-27 13:53:20 -0700123 EXPECT_FALSE(prefs_.SetString(kKey, "test value"));
124}
125
126TEST_F(PrefsTest, SetStringFileCreationFailure) {
Alex Vakulenko75039d72014-03-25 12:36:28 -0700127 base::CreateDirectory(prefs_dir_.Append(kKey));
Darin Petkov30030592010-07-27 13:53:20 -0700128 EXPECT_FALSE(prefs_.SetString(kKey, "test value"));
Alex Vakulenko75039d72014-03-25 12:36:28 -0700129 EXPECT_TRUE(base::DirectoryExists(prefs_dir_.Append(kKey)));
Darin Petkov30030592010-07-27 13:53:20 -0700130}
131
132TEST_F(PrefsTest, GetInt64) {
Darin Petkov30030592010-07-27 13:53:20 -0700133 ASSERT_TRUE(SetValue(kKey, " \n 25 \t "));
134 int64_t value;
135 EXPECT_TRUE(prefs_.GetInt64(kKey, &value));
136 EXPECT_EQ(25, value);
137}
138
139TEST_F(PrefsTest, GetInt64BadValue) {
Darin Petkov30030592010-07-27 13:53:20 -0700140 ASSERT_TRUE(SetValue(kKey, "30a"));
141 int64_t value;
142 EXPECT_FALSE(prefs_.GetInt64(kKey, &value));
143}
144
145TEST_F(PrefsTest, GetInt64Max) {
Alex Vakulenko75039d72014-03-25 12:36:28 -0700146 ASSERT_TRUE(SetValue(kKey, base::StringPrintf("%" PRIi64, kint64max)));
Darin Petkov30030592010-07-27 13:53:20 -0700147 int64_t value;
148 EXPECT_TRUE(prefs_.GetInt64(kKey, &value));
149 EXPECT_EQ(kint64max, value);
150}
151
152TEST_F(PrefsTest, GetInt64Min) {
Alex Vakulenko75039d72014-03-25 12:36:28 -0700153 ASSERT_TRUE(SetValue(kKey, base::StringPrintf("%" PRIi64, kint64min)));
Darin Petkov30030592010-07-27 13:53:20 -0700154 int64_t value;
155 EXPECT_TRUE(prefs_.GetInt64(kKey, &value));
156 EXPECT_EQ(kint64min, value);
157}
158
159TEST_F(PrefsTest, GetInt64Negative) {
Darin Petkov30030592010-07-27 13:53:20 -0700160 ASSERT_TRUE(SetValue(kKey, " \t -100 \n "));
161 int64_t value;
162 EXPECT_TRUE(prefs_.GetInt64(kKey, &value));
163 EXPECT_EQ(-100, value);
164}
165
166TEST_F(PrefsTest, GetInt64NonExistentKey) {
167 int64_t value;
168 EXPECT_FALSE(prefs_.GetInt64("random-key", &value));
169}
170
171TEST_F(PrefsTest, SetInt64) {
Darin Petkov30030592010-07-27 13:53:20 -0700172 EXPECT_TRUE(prefs_.SetInt64(kKey, -123));
173 string value;
Alex Vakulenko75039d72014-03-25 12:36:28 -0700174 EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
Darin Petkov30030592010-07-27 13:53:20 -0700175 EXPECT_EQ("-123", value);
176}
177
178TEST_F(PrefsTest, SetInt64BadKey) {
Alex Deymod6f60072015-10-12 12:22:27 -0700179 const char kKeyWithSpaces[] = "s p a c e s";
180 EXPECT_FALSE(prefs_.SetInt64(kKeyWithSpaces, 20));
181 EXPECT_FALSE(base::PathExists(prefs_dir_.Append(kKeyWithSpaces)));
Darin Petkov30030592010-07-27 13:53:20 -0700182}
183
184TEST_F(PrefsTest, SetInt64Max) {
Darin Petkov30030592010-07-27 13:53:20 -0700185 EXPECT_TRUE(prefs_.SetInt64(kKey, kint64max));
186 string value;
Alex Vakulenko75039d72014-03-25 12:36:28 -0700187 EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
188 EXPECT_EQ(base::StringPrintf("%" PRIi64, kint64max), value);
Darin Petkov30030592010-07-27 13:53:20 -0700189}
190
191TEST_F(PrefsTest, SetInt64Min) {
Darin Petkov30030592010-07-27 13:53:20 -0700192 EXPECT_TRUE(prefs_.SetInt64(kKey, kint64min));
193 string value;
Alex Vakulenko75039d72014-03-25 12:36:28 -0700194 EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
195 EXPECT_EQ(base::StringPrintf("%" PRIi64, kint64min), value);
Darin Petkov30030592010-07-27 13:53:20 -0700196}
197
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700198TEST_F(PrefsTest, GetBooleanFalse) {
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700199 ASSERT_TRUE(SetValue(kKey, " \n false \t "));
200 bool value;
201 EXPECT_TRUE(prefs_.GetBoolean(kKey, &value));
202 EXPECT_FALSE(value);
203}
204
205TEST_F(PrefsTest, GetBooleanTrue) {
206 const char kKey[] = "test-key";
207 ASSERT_TRUE(SetValue(kKey, " \t true \n "));
208 bool value;
209 EXPECT_TRUE(prefs_.GetBoolean(kKey, &value));
210 EXPECT_TRUE(value);
211}
212
213TEST_F(PrefsTest, GetBooleanBadValue) {
214 const char kKey[] = "test-key";
215 ASSERT_TRUE(SetValue(kKey, "1"));
216 bool value;
217 EXPECT_FALSE(prefs_.GetBoolean(kKey, &value));
218}
219
220TEST_F(PrefsTest, GetBooleanBadEmptyValue) {
221 const char kKey[] = "test-key";
222 ASSERT_TRUE(SetValue(kKey, ""));
223 bool value;
224 EXPECT_FALSE(prefs_.GetBoolean(kKey, &value));
225}
226
227TEST_F(PrefsTest, GetBooleanNonExistentKey) {
228 bool value;
229 EXPECT_FALSE(prefs_.GetBoolean("random-key", &value));
230}
231
232TEST_F(PrefsTest, SetBooleanTrue) {
233 const char kKey[] = "test-bool";
234 EXPECT_TRUE(prefs_.SetBoolean(kKey, true));
235 string value;
Alex Vakulenko75039d72014-03-25 12:36:28 -0700236 EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700237 EXPECT_EQ("true", value);
238}
239
240TEST_F(PrefsTest, SetBooleanFalse) {
241 const char kKey[] = "test-bool";
242 EXPECT_TRUE(prefs_.SetBoolean(kKey, false));
243 string value;
Alex Vakulenko75039d72014-03-25 12:36:28 -0700244 EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700245 EXPECT_EQ("false", value);
246}
247
248TEST_F(PrefsTest, SetBooleanBadKey) {
249 const char kKey[] = "s p a c e s";
250 EXPECT_FALSE(prefs_.SetBoolean(kKey, true));
Alex Vakulenko75039d72014-03-25 12:36:28 -0700251 EXPECT_FALSE(base::PathExists(prefs_dir_.Append(kKey)));
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700252}
253
Jay Srinivasan480ddfa2012-06-01 19:15:26 -0700254TEST_F(PrefsTest, ExistsWorks) {
Jay Srinivasan480ddfa2012-06-01 19:15:26 -0700255 // test that the key doesn't exist before we set it.
256 EXPECT_FALSE(prefs_.Exists(kKey));
257
258 // test that the key exists after we set it.
259 ASSERT_TRUE(prefs_.SetInt64(kKey, 8));
260 EXPECT_TRUE(prefs_.Exists(kKey));
261}
262
263TEST_F(PrefsTest, DeleteWorks) {
Jay Srinivasan480ddfa2012-06-01 19:15:26 -0700264 // test that it's alright to delete a non-existent key.
265 EXPECT_TRUE(prefs_.Delete(kKey));
266
267 // delete the key after we set it.
268 ASSERT_TRUE(prefs_.SetInt64(kKey, 0));
269 EXPECT_TRUE(prefs_.Delete(kKey));
270
271 // make sure it doesn't exist anymore.
272 EXPECT_FALSE(prefs_.Exists(kKey));
273}
274
Alex Deymod6f60072015-10-12 12:22:27 -0700275class MockPrefsObserver : public PrefsInterface::ObserverInterface {
276 public:
277 MOCK_METHOD1(OnPrefSet, void(const string&));
278 MOCK_METHOD1(OnPrefDeleted, void(const string& key));
279};
280
281TEST_F(PrefsTest, ObserversCalled) {
282 MockPrefsObserver mock_obserser;
283 prefs_.AddObserver(kKey, &mock_obserser);
284
285 EXPECT_CALL(mock_obserser, OnPrefSet(Eq(kKey)));
286 EXPECT_CALL(mock_obserser, OnPrefDeleted(_)).Times(0);
287 prefs_.SetString(kKey, "value");
288 testing::Mock::VerifyAndClearExpectations(&mock_obserser);
289
290 EXPECT_CALL(mock_obserser, OnPrefSet(_)).Times(0);
291 EXPECT_CALL(mock_obserser, OnPrefDeleted(Eq(kKey)));
292 prefs_.Delete(kKey);
293 testing::Mock::VerifyAndClearExpectations(&mock_obserser);
294
295 prefs_.RemoveObserver(kKey, &mock_obserser);
296}
297
298TEST_F(PrefsTest, OnlyCalledOnObservedKeys) {
299 MockPrefsObserver mock_obserser;
300 const char kUnusedKey[] = "unused-key";
301 prefs_.AddObserver(kUnusedKey, &mock_obserser);
302
303 EXPECT_CALL(mock_obserser, OnPrefSet(_)).Times(0);
304 EXPECT_CALL(mock_obserser, OnPrefDeleted(_)).Times(0);
305 prefs_.SetString(kKey, "value");
306 prefs_.Delete(kKey);
307
308 prefs_.RemoveObserver(kUnusedKey, &mock_obserser);
309}
310
311TEST_F(PrefsTest, RemovedObserversNotCalled) {
312 MockPrefsObserver mock_obserser_a, mock_obserser_b;
313 prefs_.AddObserver(kKey, &mock_obserser_a);
314 prefs_.AddObserver(kKey, &mock_obserser_b);
315 EXPECT_CALL(mock_obserser_a, OnPrefSet(_)).Times(2);
316 EXPECT_CALL(mock_obserser_b, OnPrefSet(_)).Times(1);
317 EXPECT_TRUE(prefs_.SetString(kKey, "value"));
318 prefs_.RemoveObserver(kKey, &mock_obserser_b);
319 EXPECT_TRUE(prefs_.SetString(kKey, "other value"));
320 prefs_.RemoveObserver(kKey, &mock_obserser_a);
321 EXPECT_TRUE(prefs_.SetString(kKey, "yet another value"));
322}
323
324TEST_F(PrefsTest, UnsuccessfulCallsNotObserved) {
325 MockPrefsObserver mock_obserser;
326 const char kInvalidKey[] = "no spaces or .";
327 prefs_.AddObserver(kInvalidKey, &mock_obserser);
328
329 EXPECT_CALL(mock_obserser, OnPrefSet(_)).Times(0);
330 EXPECT_CALL(mock_obserser, OnPrefDeleted(_)).Times(0);
331 EXPECT_FALSE(prefs_.SetString(kInvalidKey, "value"));
332 EXPECT_FALSE(prefs_.Delete(kInvalidKey));
333
334 prefs_.RemoveObserver(kInvalidKey, &mock_obserser);
335}
336
Darin Petkov30030592010-07-27 13:53:20 -0700337} // namespace chromeos_update_engine