blob: 1000131a27f81ae5c61097515cdce362d4097546 [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
21#include <string>
22
Ben Chan06c76a42014-09-05 08:21:06 -070023#include <base/files/file_util.h>
Sen Jiang371615b2016-04-13 15:54:29 -070024#include <base/files/scoped_temp_dir.h>
Ben Chan05735a12014-09-03 07:48:22 -070025#include <base/macros.h>
Alex Vakulenko75039d72014-03-25 12:36:28 -070026#include <base/strings/string_util.h>
27#include <base/strings/stringprintf.h>
Alex Deymod6f60072015-10-12 12:22:27 -070028#include <gmock/gmock.h>
Ben Chan05735a12014-09-03 07:48:22 -070029#include <gtest/gtest.h>
30
Darin Petkov30030592010-07-27 13:53:20 -070031using std::string;
Alex Deymod6f60072015-10-12 12:22:27 -070032using testing::Eq;
33using testing::_;
34
35namespace {
36// Test key used along the tests.
37const char kKey[] = "test-key";
38}
Darin Petkov30030592010-07-27 13:53:20 -070039
40namespace chromeos_update_engine {
41
42class PrefsTest : public ::testing::Test {
43 protected:
Alex Deymo610277e2014-11-11 21:18:11 -080044 void SetUp() override {
Sen Jiang371615b2016-04-13 15:54:29 -070045 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
46 prefs_dir_ = temp_dir_.path();
Darin Petkov30030592010-07-27 13:53:20 -070047 ASSERT_TRUE(prefs_.Init(prefs_dir_));
48 }
49
Darin Petkov30030592010-07-27 13:53:20 -070050 bool SetValue(const string& key, const string& value) {
Ben Chan736fcb52014-05-21 18:28:22 -070051 return base::WriteFile(prefs_dir_.Append(key), value.data(),
52 value.length()) == static_cast<int>(value.length());
Darin Petkov30030592010-07-27 13:53:20 -070053 }
54
Sen Jiang371615b2016-04-13 15:54:29 -070055 base::ScopedTempDir temp_dir_;
Alex Vakulenko75039d72014-03-25 12:36:28 -070056 base::FilePath prefs_dir_;
Darin Petkov30030592010-07-27 13:53:20 -070057 Prefs prefs_;
58};
59
60TEST_F(PrefsTest, GetFileNameForKey) {
Alex Deymod6f60072015-10-12 12:22:27 -070061 const char kAllvalidCharsKey[] =
62 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-";
Alex Vakulenko75039d72014-03-25 12:36:28 -070063 base::FilePath path;
Alex Deymod6f60072015-10-12 12:22:27 -070064 EXPECT_TRUE(prefs_.GetFileNameForKey(kAllvalidCharsKey, &path));
65 EXPECT_EQ(prefs_dir_.Append(kAllvalidCharsKey).value(), path.value());
Darin Petkov30030592010-07-27 13:53:20 -070066}
67
68TEST_F(PrefsTest, GetFileNameForKeyBadCharacter) {
Alex Vakulenko75039d72014-03-25 12:36:28 -070069 base::FilePath path;
Darin Petkov30030592010-07-27 13:53:20 -070070 EXPECT_FALSE(prefs_.GetFileNameForKey("ABC abc", &path));
71}
72
73TEST_F(PrefsTest, GetFileNameForKeyEmpty) {
Alex Vakulenko75039d72014-03-25 12:36:28 -070074 base::FilePath path;
Darin Petkov30030592010-07-27 13:53:20 -070075 EXPECT_FALSE(prefs_.GetFileNameForKey("", &path));
76}
77
78TEST_F(PrefsTest, GetString) {
Darin Petkov30030592010-07-27 13:53:20 -070079 const string test_data = "test data";
80 ASSERT_TRUE(SetValue(kKey, test_data));
81 string value;
82 EXPECT_TRUE(prefs_.GetString(kKey, &value));
83 EXPECT_EQ(test_data, value);
84}
85
86TEST_F(PrefsTest, GetStringBadKey) {
87 string value;
88 EXPECT_FALSE(prefs_.GetString(",bad", &value));
89}
90
91TEST_F(PrefsTest, GetStringNonExistentKey) {
92 string value;
93 EXPECT_FALSE(prefs_.GetString("non-existent-key", &value));
94}
95
96TEST_F(PrefsTest, SetString) {
Darin Petkov30030592010-07-27 13:53:20 -070097 const char kValue[] = "some test value\non 2 lines";
98 EXPECT_TRUE(prefs_.SetString(kKey, kValue));
99 string value;
Alex Vakulenko75039d72014-03-25 12:36:28 -0700100 EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
Darin Petkov30030592010-07-27 13:53:20 -0700101 EXPECT_EQ(kValue, value);
102}
103
104TEST_F(PrefsTest, SetStringBadKey) {
Alex Deymod6f60072015-10-12 12:22:27 -0700105 const char kKeyWithDots[] = ".no-dots";
106 EXPECT_FALSE(prefs_.SetString(kKeyWithDots, "some value"));
107 EXPECT_FALSE(base::PathExists(prefs_dir_.Append(kKeyWithDots)));
Darin Petkov30030592010-07-27 13:53:20 -0700108}
109
110TEST_F(PrefsTest, SetStringCreateDir) {
Darin Petkov30030592010-07-27 13:53:20 -0700111 const char kValue[] = "test value";
Alex Vakulenko75039d72014-03-25 12:36:28 -0700112 base::FilePath subdir = prefs_dir_.Append("subdir1").Append("subdir2");
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700113 EXPECT_TRUE(prefs_.Init(subdir));
Darin Petkov30030592010-07-27 13:53:20 -0700114 EXPECT_TRUE(prefs_.SetString(kKey, kValue));
115 string value;
Alex Vakulenko75039d72014-03-25 12:36:28 -0700116 EXPECT_TRUE(base::ReadFileToString(subdir.Append(kKey), &value));
Darin Petkov30030592010-07-27 13:53:20 -0700117 EXPECT_EQ(kValue, value);
118}
119
120TEST_F(PrefsTest, SetStringDirCreationFailure) {
Alex Vakulenko75039d72014-03-25 12:36:28 -0700121 EXPECT_TRUE(prefs_.Init(base::FilePath("/dev/null")));
Darin Petkov30030592010-07-27 13:53:20 -0700122 EXPECT_FALSE(prefs_.SetString(kKey, "test value"));
123}
124
125TEST_F(PrefsTest, SetStringFileCreationFailure) {
Alex Vakulenko75039d72014-03-25 12:36:28 -0700126 base::CreateDirectory(prefs_dir_.Append(kKey));
Darin Petkov30030592010-07-27 13:53:20 -0700127 EXPECT_FALSE(prefs_.SetString(kKey, "test value"));
Alex Vakulenko75039d72014-03-25 12:36:28 -0700128 EXPECT_TRUE(base::DirectoryExists(prefs_dir_.Append(kKey)));
Darin Petkov30030592010-07-27 13:53:20 -0700129}
130
131TEST_F(PrefsTest, GetInt64) {
Darin Petkov30030592010-07-27 13:53:20 -0700132 ASSERT_TRUE(SetValue(kKey, " \n 25 \t "));
133 int64_t value;
134 EXPECT_TRUE(prefs_.GetInt64(kKey, &value));
135 EXPECT_EQ(25, value);
136}
137
138TEST_F(PrefsTest, GetInt64BadValue) {
Darin Petkov30030592010-07-27 13:53:20 -0700139 ASSERT_TRUE(SetValue(kKey, "30a"));
140 int64_t value;
141 EXPECT_FALSE(prefs_.GetInt64(kKey, &value));
142}
143
144TEST_F(PrefsTest, GetInt64Max) {
Alex Vakulenko0103c362016-01-20 07:56:15 -0800145 ASSERT_TRUE(SetValue(kKey, base::StringPrintf(
Alex Deymo80f70ff2016-02-10 16:08:11 -0800146 "%" PRIi64, std::numeric_limits<int64_t>::max())));
Darin Petkov30030592010-07-27 13:53:20 -0700147 int64_t value;
148 EXPECT_TRUE(prefs_.GetInt64(kKey, &value));
Alex Deymo80f70ff2016-02-10 16:08:11 -0800149 EXPECT_EQ(std::numeric_limits<int64_t>::max(), value);
Darin Petkov30030592010-07-27 13:53:20 -0700150}
151
152TEST_F(PrefsTest, GetInt64Min) {
Alex Vakulenko0103c362016-01-20 07:56:15 -0800153 ASSERT_TRUE(SetValue(kKey, base::StringPrintf(
Alex Deymo80f70ff2016-02-10 16:08:11 -0800154 "%" PRIi64, std::numeric_limits<int64_t>::min())));
Darin Petkov30030592010-07-27 13:53:20 -0700155 int64_t value;
156 EXPECT_TRUE(prefs_.GetInt64(kKey, &value));
Alex Deymo80f70ff2016-02-10 16:08:11 -0800157 EXPECT_EQ(std::numeric_limits<int64_t>::min(), value);
Darin Petkov30030592010-07-27 13:53:20 -0700158}
159
160TEST_F(PrefsTest, GetInt64Negative) {
Darin Petkov30030592010-07-27 13:53:20 -0700161 ASSERT_TRUE(SetValue(kKey, " \t -100 \n "));
162 int64_t value;
163 EXPECT_TRUE(prefs_.GetInt64(kKey, &value));
164 EXPECT_EQ(-100, value);
165}
166
167TEST_F(PrefsTest, GetInt64NonExistentKey) {
168 int64_t value;
169 EXPECT_FALSE(prefs_.GetInt64("random-key", &value));
170}
171
172TEST_F(PrefsTest, SetInt64) {
Darin Petkov30030592010-07-27 13:53:20 -0700173 EXPECT_TRUE(prefs_.SetInt64(kKey, -123));
174 string value;
Alex Vakulenko75039d72014-03-25 12:36:28 -0700175 EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
Darin Petkov30030592010-07-27 13:53:20 -0700176 EXPECT_EQ("-123", value);
177}
178
179TEST_F(PrefsTest, SetInt64BadKey) {
Alex Deymod6f60072015-10-12 12:22:27 -0700180 const char kKeyWithSpaces[] = "s p a c e s";
181 EXPECT_FALSE(prefs_.SetInt64(kKeyWithSpaces, 20));
182 EXPECT_FALSE(base::PathExists(prefs_dir_.Append(kKeyWithSpaces)));
Darin Petkov30030592010-07-27 13:53:20 -0700183}
184
185TEST_F(PrefsTest, SetInt64Max) {
Alex Vakulenko0103c362016-01-20 07:56:15 -0800186 EXPECT_TRUE(prefs_.SetInt64(kKey, std::numeric_limits<int64_t>::max()));
Darin Petkov30030592010-07-27 13:53:20 -0700187 string value;
Alex Vakulenko75039d72014-03-25 12:36:28 -0700188 EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
Alex Vakulenko0103c362016-01-20 07:56:15 -0800189 EXPECT_EQ(base::StringPrintf("%" PRIi64, std::numeric_limits<int64_t>::max()),
190 value);
Darin Petkov30030592010-07-27 13:53:20 -0700191}
192
193TEST_F(PrefsTest, SetInt64Min) {
Alex Vakulenko0103c362016-01-20 07:56:15 -0800194 EXPECT_TRUE(prefs_.SetInt64(kKey, std::numeric_limits<int64_t>::min()));
Darin Petkov30030592010-07-27 13:53:20 -0700195 string value;
Alex Vakulenko75039d72014-03-25 12:36:28 -0700196 EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
Alex Vakulenko0103c362016-01-20 07:56:15 -0800197 EXPECT_EQ(base::StringPrintf("%" PRIi64, std::numeric_limits<int64_t>::min()),
198 value);
Darin Petkov30030592010-07-27 13:53:20 -0700199}
200
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700201TEST_F(PrefsTest, GetBooleanFalse) {
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700202 ASSERT_TRUE(SetValue(kKey, " \n false \t "));
203 bool value;
204 EXPECT_TRUE(prefs_.GetBoolean(kKey, &value));
205 EXPECT_FALSE(value);
206}
207
208TEST_F(PrefsTest, GetBooleanTrue) {
209 const char kKey[] = "test-key";
210 ASSERT_TRUE(SetValue(kKey, " \t true \n "));
211 bool value;
212 EXPECT_TRUE(prefs_.GetBoolean(kKey, &value));
213 EXPECT_TRUE(value);
214}
215
216TEST_F(PrefsTest, GetBooleanBadValue) {
217 const char kKey[] = "test-key";
218 ASSERT_TRUE(SetValue(kKey, "1"));
219 bool value;
220 EXPECT_FALSE(prefs_.GetBoolean(kKey, &value));
221}
222
223TEST_F(PrefsTest, GetBooleanBadEmptyValue) {
224 const char kKey[] = "test-key";
225 ASSERT_TRUE(SetValue(kKey, ""));
226 bool value;
227 EXPECT_FALSE(prefs_.GetBoolean(kKey, &value));
228}
229
230TEST_F(PrefsTest, GetBooleanNonExistentKey) {
231 bool value;
232 EXPECT_FALSE(prefs_.GetBoolean("random-key", &value));
233}
234
235TEST_F(PrefsTest, SetBooleanTrue) {
236 const char kKey[] = "test-bool";
237 EXPECT_TRUE(prefs_.SetBoolean(kKey, true));
238 string value;
Alex Vakulenko75039d72014-03-25 12:36:28 -0700239 EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700240 EXPECT_EQ("true", value);
241}
242
243TEST_F(PrefsTest, SetBooleanFalse) {
244 const char kKey[] = "test-bool";
245 EXPECT_TRUE(prefs_.SetBoolean(kKey, false));
246 string value;
Alex Vakulenko75039d72014-03-25 12:36:28 -0700247 EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700248 EXPECT_EQ("false", value);
249}
250
251TEST_F(PrefsTest, SetBooleanBadKey) {
252 const char kKey[] = "s p a c e s";
253 EXPECT_FALSE(prefs_.SetBoolean(kKey, true));
Alex Vakulenko75039d72014-03-25 12:36:28 -0700254 EXPECT_FALSE(base::PathExists(prefs_dir_.Append(kKey)));
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700255}
256
Jay Srinivasan480ddfa2012-06-01 19:15:26 -0700257TEST_F(PrefsTest, ExistsWorks) {
Jay Srinivasan480ddfa2012-06-01 19:15:26 -0700258 // test that the key doesn't exist before we set it.
259 EXPECT_FALSE(prefs_.Exists(kKey));
260
261 // test that the key exists after we set it.
262 ASSERT_TRUE(prefs_.SetInt64(kKey, 8));
263 EXPECT_TRUE(prefs_.Exists(kKey));
264}
265
266TEST_F(PrefsTest, DeleteWorks) {
Jay Srinivasan480ddfa2012-06-01 19:15:26 -0700267 // test that it's alright to delete a non-existent key.
268 EXPECT_TRUE(prefs_.Delete(kKey));
269
270 // delete the key after we set it.
271 ASSERT_TRUE(prefs_.SetInt64(kKey, 0));
272 EXPECT_TRUE(prefs_.Delete(kKey));
273
274 // make sure it doesn't exist anymore.
275 EXPECT_FALSE(prefs_.Exists(kKey));
276}
277
Alex Deymod6f60072015-10-12 12:22:27 -0700278class MockPrefsObserver : public PrefsInterface::ObserverInterface {
279 public:
280 MOCK_METHOD1(OnPrefSet, void(const string&));
281 MOCK_METHOD1(OnPrefDeleted, void(const string& key));
282};
283
284TEST_F(PrefsTest, ObserversCalled) {
285 MockPrefsObserver mock_obserser;
286 prefs_.AddObserver(kKey, &mock_obserser);
287
288 EXPECT_CALL(mock_obserser, OnPrefSet(Eq(kKey)));
289 EXPECT_CALL(mock_obserser, OnPrefDeleted(_)).Times(0);
290 prefs_.SetString(kKey, "value");
291 testing::Mock::VerifyAndClearExpectations(&mock_obserser);
292
293 EXPECT_CALL(mock_obserser, OnPrefSet(_)).Times(0);
294 EXPECT_CALL(mock_obserser, OnPrefDeleted(Eq(kKey)));
295 prefs_.Delete(kKey);
296 testing::Mock::VerifyAndClearExpectations(&mock_obserser);
297
298 prefs_.RemoveObserver(kKey, &mock_obserser);
299}
300
301TEST_F(PrefsTest, OnlyCalledOnObservedKeys) {
302 MockPrefsObserver mock_obserser;
303 const char kUnusedKey[] = "unused-key";
304 prefs_.AddObserver(kUnusedKey, &mock_obserser);
305
306 EXPECT_CALL(mock_obserser, OnPrefSet(_)).Times(0);
307 EXPECT_CALL(mock_obserser, OnPrefDeleted(_)).Times(0);
308 prefs_.SetString(kKey, "value");
309 prefs_.Delete(kKey);
310
311 prefs_.RemoveObserver(kUnusedKey, &mock_obserser);
312}
313
314TEST_F(PrefsTest, RemovedObserversNotCalled) {
315 MockPrefsObserver mock_obserser_a, mock_obserser_b;
316 prefs_.AddObserver(kKey, &mock_obserser_a);
317 prefs_.AddObserver(kKey, &mock_obserser_b);
318 EXPECT_CALL(mock_obserser_a, OnPrefSet(_)).Times(2);
319 EXPECT_CALL(mock_obserser_b, OnPrefSet(_)).Times(1);
320 EXPECT_TRUE(prefs_.SetString(kKey, "value"));
321 prefs_.RemoveObserver(kKey, &mock_obserser_b);
322 EXPECT_TRUE(prefs_.SetString(kKey, "other value"));
323 prefs_.RemoveObserver(kKey, &mock_obserser_a);
324 EXPECT_TRUE(prefs_.SetString(kKey, "yet another value"));
325}
326
327TEST_F(PrefsTest, UnsuccessfulCallsNotObserved) {
328 MockPrefsObserver mock_obserser;
329 const char kInvalidKey[] = "no spaces or .";
330 prefs_.AddObserver(kInvalidKey, &mock_obserser);
331
332 EXPECT_CALL(mock_obserser, OnPrefSet(_)).Times(0);
333 EXPECT_CALL(mock_obserser, OnPrefDeleted(_)).Times(0);
334 EXPECT_FALSE(prefs_.SetString(kInvalidKey, "value"));
335 EXPECT_FALSE(prefs_.Delete(kInvalidKey));
336
337 prefs_.RemoveObserver(kInvalidKey, &mock_obserser);
338}
339
Darin Petkov30030592010-07-27 13:53:20 -0700340} // namespace chromeos_update_engine