blob: aa2eb043d6055a1e1612d40eaa3efa096e4f22eb [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 Deymo39910dc2015-11-09 17:04:30 -080017#include "update_engine/common/prefs.h"
Alex Deymoaab50e32014-11-10 19:55:35 -080018
Darin Petkov30030592010-07-27 13:53:20 -070019#include <inttypes.h>
20
Alex Deymoa0284ac2016-07-22 12:51:41 -070021#include <limits>
Darin Petkov30030592010-07-27 13:53:20 -070022#include <string>
23
Ben Chan06c76a42014-09-05 08:21:06 -070024#include <base/files/file_util.h>
Sen Jiang371615b2016-04-13 15:54:29 -070025#include <base/files/scoped_temp_dir.h>
Ben Chan05735a12014-09-03 07:48:22 -070026#include <base/macros.h>
Alex Vakulenko75039d72014-03-25 12:36:28 -070027#include <base/strings/string_util.h>
28#include <base/strings/stringprintf.h>
Alex Deymod6f60072015-10-12 12:22:27 -070029#include <gmock/gmock.h>
Ben Chan05735a12014-09-03 07:48:22 -070030#include <gtest/gtest.h>
31
Darin Petkov30030592010-07-27 13:53:20 -070032using std::string;
Alex Deymod6f60072015-10-12 12:22:27 -070033using testing::Eq;
34using testing::_;
35
36namespace {
37// Test key used along the tests.
38const char kKey[] = "test-key";
39}
Darin Petkov30030592010-07-27 13:53:20 -070040
41namespace chromeos_update_engine {
42
43class PrefsTest : public ::testing::Test {
44 protected:
Alex Deymo610277e2014-11-11 21:18:11 -080045 void SetUp() override {
Sen Jiang371615b2016-04-13 15:54:29 -070046 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
Jay Civellia78ddf82017-03-30 11:02:03 -070047 prefs_dir_ = temp_dir_.GetPath();
Darin Petkov30030592010-07-27 13:53:20 -070048 ASSERT_TRUE(prefs_.Init(prefs_dir_));
49 }
50
Darin Petkov30030592010-07-27 13:53:20 -070051 bool SetValue(const string& key, const string& value) {
Ben Chan736fcb52014-05-21 18:28:22 -070052 return base::WriteFile(prefs_dir_.Append(key), value.data(),
53 value.length()) == static_cast<int>(value.length());
Darin Petkov30030592010-07-27 13:53:20 -070054 }
55
Sen Jiang371615b2016-04-13 15:54:29 -070056 base::ScopedTempDir temp_dir_;
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 Deymoa0284ac2016-07-22 12:51:41 -070065 EXPECT_TRUE(prefs_.file_storage_.GetFileNameForKey(kAllvalidCharsKey, &path));
Alex Deymod6f60072015-10-12 12:22:27 -070066 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;
Alex Deymoa0284ac2016-07-22 12:51:41 -070071 EXPECT_FALSE(prefs_.file_storage_.GetFileNameForKey("ABC abc", &path));
Darin Petkov30030592010-07-27 13:53:20 -070072}
73
74TEST_F(PrefsTest, GetFileNameForKeyEmpty) {
Alex Vakulenko75039d72014-03-25 12:36:28 -070075 base::FilePath path;
Alex Deymoa0284ac2016-07-22 12:51:41 -070076 EXPECT_FALSE(prefs_.file_storage_.GetFileNameForKey("", &path));
Darin Petkov30030592010-07-27 13:53:20 -070077}
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 Vakulenko0103c362016-01-20 07:56:15 -0800146 ASSERT_TRUE(SetValue(kKey, base::StringPrintf(
Alex Deymo80f70ff2016-02-10 16:08:11 -0800147 "%" PRIi64, std::numeric_limits<int64_t>::max())));
Darin Petkov30030592010-07-27 13:53:20 -0700148 int64_t value;
149 EXPECT_TRUE(prefs_.GetInt64(kKey, &value));
Alex Deymo80f70ff2016-02-10 16:08:11 -0800150 EXPECT_EQ(std::numeric_limits<int64_t>::max(), value);
Darin Petkov30030592010-07-27 13:53:20 -0700151}
152
153TEST_F(PrefsTest, GetInt64Min) {
Alex Vakulenko0103c362016-01-20 07:56:15 -0800154 ASSERT_TRUE(SetValue(kKey, base::StringPrintf(
Alex Deymo80f70ff2016-02-10 16:08:11 -0800155 "%" PRIi64, std::numeric_limits<int64_t>::min())));
Darin Petkov30030592010-07-27 13:53:20 -0700156 int64_t value;
157 EXPECT_TRUE(prefs_.GetInt64(kKey, &value));
Alex Deymo80f70ff2016-02-10 16:08:11 -0800158 EXPECT_EQ(std::numeric_limits<int64_t>::min(), value);
Darin Petkov30030592010-07-27 13:53:20 -0700159}
160
161TEST_F(PrefsTest, GetInt64Negative) {
Darin Petkov30030592010-07-27 13:53:20 -0700162 ASSERT_TRUE(SetValue(kKey, " \t -100 \n "));
163 int64_t value;
164 EXPECT_TRUE(prefs_.GetInt64(kKey, &value));
165 EXPECT_EQ(-100, value);
166}
167
168TEST_F(PrefsTest, GetInt64NonExistentKey) {
169 int64_t value;
170 EXPECT_FALSE(prefs_.GetInt64("random-key", &value));
171}
172
173TEST_F(PrefsTest, SetInt64) {
Darin Petkov30030592010-07-27 13:53:20 -0700174 EXPECT_TRUE(prefs_.SetInt64(kKey, -123));
175 string value;
Alex Vakulenko75039d72014-03-25 12:36:28 -0700176 EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
Darin Petkov30030592010-07-27 13:53:20 -0700177 EXPECT_EQ("-123", value);
178}
179
180TEST_F(PrefsTest, SetInt64BadKey) {
Alex Deymod6f60072015-10-12 12:22:27 -0700181 const char kKeyWithSpaces[] = "s p a c e s";
182 EXPECT_FALSE(prefs_.SetInt64(kKeyWithSpaces, 20));
183 EXPECT_FALSE(base::PathExists(prefs_dir_.Append(kKeyWithSpaces)));
Darin Petkov30030592010-07-27 13:53:20 -0700184}
185
186TEST_F(PrefsTest, SetInt64Max) {
Alex Vakulenko0103c362016-01-20 07:56:15 -0800187 EXPECT_TRUE(prefs_.SetInt64(kKey, std::numeric_limits<int64_t>::max()));
Darin Petkov30030592010-07-27 13:53:20 -0700188 string value;
Alex Vakulenko75039d72014-03-25 12:36:28 -0700189 EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
Alex Vakulenko0103c362016-01-20 07:56:15 -0800190 EXPECT_EQ(base::StringPrintf("%" PRIi64, std::numeric_limits<int64_t>::max()),
191 value);
Darin Petkov30030592010-07-27 13:53:20 -0700192}
193
194TEST_F(PrefsTest, SetInt64Min) {
Alex Vakulenko0103c362016-01-20 07:56:15 -0800195 EXPECT_TRUE(prefs_.SetInt64(kKey, std::numeric_limits<int64_t>::min()));
Darin Petkov30030592010-07-27 13:53:20 -0700196 string value;
Alex Vakulenko75039d72014-03-25 12:36:28 -0700197 EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
Alex Vakulenko0103c362016-01-20 07:56:15 -0800198 EXPECT_EQ(base::StringPrintf("%" PRIi64, std::numeric_limits<int64_t>::min()),
199 value);
Darin Petkov30030592010-07-27 13:53:20 -0700200}
201
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700202TEST_F(PrefsTest, GetBooleanFalse) {
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700203 ASSERT_TRUE(SetValue(kKey, " \n false \t "));
204 bool value;
205 EXPECT_TRUE(prefs_.GetBoolean(kKey, &value));
206 EXPECT_FALSE(value);
207}
208
209TEST_F(PrefsTest, GetBooleanTrue) {
210 const char kKey[] = "test-key";
211 ASSERT_TRUE(SetValue(kKey, " \t true \n "));
212 bool value;
213 EXPECT_TRUE(prefs_.GetBoolean(kKey, &value));
214 EXPECT_TRUE(value);
215}
216
217TEST_F(PrefsTest, GetBooleanBadValue) {
218 const char kKey[] = "test-key";
219 ASSERT_TRUE(SetValue(kKey, "1"));
220 bool value;
221 EXPECT_FALSE(prefs_.GetBoolean(kKey, &value));
222}
223
224TEST_F(PrefsTest, GetBooleanBadEmptyValue) {
225 const char kKey[] = "test-key";
226 ASSERT_TRUE(SetValue(kKey, ""));
227 bool value;
228 EXPECT_FALSE(prefs_.GetBoolean(kKey, &value));
229}
230
231TEST_F(PrefsTest, GetBooleanNonExistentKey) {
232 bool value;
233 EXPECT_FALSE(prefs_.GetBoolean("random-key", &value));
234}
235
236TEST_F(PrefsTest, SetBooleanTrue) {
237 const char kKey[] = "test-bool";
238 EXPECT_TRUE(prefs_.SetBoolean(kKey, true));
239 string value;
Alex Vakulenko75039d72014-03-25 12:36:28 -0700240 EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700241 EXPECT_EQ("true", value);
242}
243
244TEST_F(PrefsTest, SetBooleanFalse) {
245 const char kKey[] = "test-bool";
246 EXPECT_TRUE(prefs_.SetBoolean(kKey, false));
247 string value;
Alex Vakulenko75039d72014-03-25 12:36:28 -0700248 EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700249 EXPECT_EQ("false", value);
250}
251
252TEST_F(PrefsTest, SetBooleanBadKey) {
253 const char kKey[] = "s p a c e s";
254 EXPECT_FALSE(prefs_.SetBoolean(kKey, true));
Alex Vakulenko75039d72014-03-25 12:36:28 -0700255 EXPECT_FALSE(base::PathExists(prefs_dir_.Append(kKey)));
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700256}
257
Jay Srinivasan480ddfa2012-06-01 19:15:26 -0700258TEST_F(PrefsTest, ExistsWorks) {
Jay Srinivasan480ddfa2012-06-01 19:15:26 -0700259 // test that the key doesn't exist before we set it.
260 EXPECT_FALSE(prefs_.Exists(kKey));
261
262 // test that the key exists after we set it.
263 ASSERT_TRUE(prefs_.SetInt64(kKey, 8));
264 EXPECT_TRUE(prefs_.Exists(kKey));
265}
266
267TEST_F(PrefsTest, DeleteWorks) {
Jay Srinivasan480ddfa2012-06-01 19:15:26 -0700268 // test that it's alright to delete a non-existent key.
269 EXPECT_TRUE(prefs_.Delete(kKey));
270
271 // delete the key after we set it.
272 ASSERT_TRUE(prefs_.SetInt64(kKey, 0));
273 EXPECT_TRUE(prefs_.Delete(kKey));
274
275 // make sure it doesn't exist anymore.
276 EXPECT_FALSE(prefs_.Exists(kKey));
277}
278
Alex Deymod6f60072015-10-12 12:22:27 -0700279class MockPrefsObserver : public PrefsInterface::ObserverInterface {
280 public:
281 MOCK_METHOD1(OnPrefSet, void(const string&));
282 MOCK_METHOD1(OnPrefDeleted, void(const string& key));
283};
284
285TEST_F(PrefsTest, ObserversCalled) {
286 MockPrefsObserver mock_obserser;
287 prefs_.AddObserver(kKey, &mock_obserser);
288
289 EXPECT_CALL(mock_obserser, OnPrefSet(Eq(kKey)));
290 EXPECT_CALL(mock_obserser, OnPrefDeleted(_)).Times(0);
291 prefs_.SetString(kKey, "value");
292 testing::Mock::VerifyAndClearExpectations(&mock_obserser);
293
294 EXPECT_CALL(mock_obserser, OnPrefSet(_)).Times(0);
295 EXPECT_CALL(mock_obserser, OnPrefDeleted(Eq(kKey)));
296 prefs_.Delete(kKey);
297 testing::Mock::VerifyAndClearExpectations(&mock_obserser);
298
299 prefs_.RemoveObserver(kKey, &mock_obserser);
300}
301
302TEST_F(PrefsTest, OnlyCalledOnObservedKeys) {
303 MockPrefsObserver mock_obserser;
304 const char kUnusedKey[] = "unused-key";
305 prefs_.AddObserver(kUnusedKey, &mock_obserser);
306
307 EXPECT_CALL(mock_obserser, OnPrefSet(_)).Times(0);
308 EXPECT_CALL(mock_obserser, OnPrefDeleted(_)).Times(0);
309 prefs_.SetString(kKey, "value");
310 prefs_.Delete(kKey);
311
312 prefs_.RemoveObserver(kUnusedKey, &mock_obserser);
313}
314
315TEST_F(PrefsTest, RemovedObserversNotCalled) {
316 MockPrefsObserver mock_obserser_a, mock_obserser_b;
317 prefs_.AddObserver(kKey, &mock_obserser_a);
318 prefs_.AddObserver(kKey, &mock_obserser_b);
319 EXPECT_CALL(mock_obserser_a, OnPrefSet(_)).Times(2);
320 EXPECT_CALL(mock_obserser_b, OnPrefSet(_)).Times(1);
321 EXPECT_TRUE(prefs_.SetString(kKey, "value"));
322 prefs_.RemoveObserver(kKey, &mock_obserser_b);
323 EXPECT_TRUE(prefs_.SetString(kKey, "other value"));
324 prefs_.RemoveObserver(kKey, &mock_obserser_a);
325 EXPECT_TRUE(prefs_.SetString(kKey, "yet another value"));
326}
327
328TEST_F(PrefsTest, UnsuccessfulCallsNotObserved) {
329 MockPrefsObserver mock_obserser;
330 const char kInvalidKey[] = "no spaces or .";
331 prefs_.AddObserver(kInvalidKey, &mock_obserser);
332
333 EXPECT_CALL(mock_obserser, OnPrefSet(_)).Times(0);
334 EXPECT_CALL(mock_obserser, OnPrefDeleted(_)).Times(0);
335 EXPECT_FALSE(prefs_.SetString(kInvalidKey, "value"));
336 EXPECT_FALSE(prefs_.Delete(kInvalidKey));
337
338 prefs_.RemoveObserver(kInvalidKey, &mock_obserser);
339}
340
Alex Deymoa0284ac2016-07-22 12:51:41 -0700341class MemoryPrefsTest : public ::testing::Test {
342 protected:
343 MemoryPrefs prefs_;
344};
345
346TEST_F(MemoryPrefsTest, BasicTest) {
347 EXPECT_FALSE(prefs_.Exists(kKey));
348 int64_t value = 0;
349 EXPECT_FALSE(prefs_.GetInt64(kKey, &value));
350
351 EXPECT_TRUE(prefs_.SetInt64(kKey, 1234));
352 EXPECT_TRUE(prefs_.Exists(kKey));
353 EXPECT_TRUE(prefs_.GetInt64(kKey, &value));
354 EXPECT_EQ(1234, value);
355
356 EXPECT_TRUE(prefs_.Delete(kKey));
357 EXPECT_FALSE(prefs_.Exists(kKey));
358 EXPECT_FALSE(prefs_.Delete(kKey));
359}
360
Darin Petkov30030592010-07-27 13:53:20 -0700361} // namespace chromeos_update_engine