blob: 08225990f48e981b6946d088094392f3fb96851d [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 Deymoe6eef832016-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>
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 {
Alex Vakulenko75039d72014-03-25 12:36:28 -070045 ASSERT_TRUE(base::CreateNewTempDirectory("auprefs", &prefs_dir_));
Darin Petkov30030592010-07-27 13:53:20 -070046 ASSERT_TRUE(prefs_.Init(prefs_dir_));
47 }
48
Alex Deymo610277e2014-11-11 21:18:11 -080049 void TearDown() override {
Alex Vakulenko75039d72014-03-25 12:36:28 -070050 base::DeleteFile(prefs_dir_, true); // recursive
Darin Petkov30030592010-07-27 13:53:20 -070051 }
52
53 bool SetValue(const string& key, const string& value) {
Ben Chan736fcb52014-05-21 18:28:22 -070054 return base::WriteFile(prefs_dir_.Append(key), value.data(),
55 value.length()) == static_cast<int>(value.length());
Darin Petkov30030592010-07-27 13:53:20 -070056 }
57
Alex Vakulenko75039d72014-03-25 12:36:28 -070058 base::FilePath prefs_dir_;
Darin Petkov30030592010-07-27 13:53:20 -070059 Prefs prefs_;
60};
61
62TEST_F(PrefsTest, GetFileNameForKey) {
Alex Deymod6f60072015-10-12 12:22:27 -070063 const char kAllvalidCharsKey[] =
64 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-";
Alex Vakulenko75039d72014-03-25 12:36:28 -070065 base::FilePath path;
Alex Deymoe6eef832016-07-22 12:51:41 -070066 EXPECT_TRUE(prefs_.file_storage_.GetFileNameForKey(kAllvalidCharsKey, &path));
Alex Deymod6f60072015-10-12 12:22:27 -070067 EXPECT_EQ(prefs_dir_.Append(kAllvalidCharsKey).value(), path.value());
Darin Petkov30030592010-07-27 13:53:20 -070068}
69
70TEST_F(PrefsTest, GetFileNameForKeyBadCharacter) {
Alex Vakulenko75039d72014-03-25 12:36:28 -070071 base::FilePath path;
Alex Deymoe6eef832016-07-22 12:51:41 -070072 EXPECT_FALSE(prefs_.file_storage_.GetFileNameForKey("ABC abc", &path));
Darin Petkov30030592010-07-27 13:53:20 -070073}
74
75TEST_F(PrefsTest, GetFileNameForKeyEmpty) {
Alex Vakulenko75039d72014-03-25 12:36:28 -070076 base::FilePath path;
Alex Deymoe6eef832016-07-22 12:51:41 -070077 EXPECT_FALSE(prefs_.file_storage_.GetFileNameForKey("", &path));
Darin Petkov30030592010-07-27 13:53:20 -070078}
79
80TEST_F(PrefsTest, GetString) {
Darin Petkov30030592010-07-27 13:53:20 -070081 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
88TEST_F(PrefsTest, GetStringBadKey) {
89 string value;
90 EXPECT_FALSE(prefs_.GetString(",bad", &value));
91}
92
93TEST_F(PrefsTest, GetStringNonExistentKey) {
94 string value;
95 EXPECT_FALSE(prefs_.GetString("non-existent-key", &value));
96}
97
98TEST_F(PrefsTest, SetString) {
Darin Petkov30030592010-07-27 13:53:20 -070099 const char kValue[] = "some test value\non 2 lines";
100 EXPECT_TRUE(prefs_.SetString(kKey, kValue));
101 string value;
Alex Vakulenko75039d72014-03-25 12:36:28 -0700102 EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
Darin Petkov30030592010-07-27 13:53:20 -0700103 EXPECT_EQ(kValue, value);
104}
105
106TEST_F(PrefsTest, SetStringBadKey) {
Alex Deymod6f60072015-10-12 12:22:27 -0700107 const char kKeyWithDots[] = ".no-dots";
108 EXPECT_FALSE(prefs_.SetString(kKeyWithDots, "some value"));
109 EXPECT_FALSE(base::PathExists(prefs_dir_.Append(kKeyWithDots)));
Darin Petkov30030592010-07-27 13:53:20 -0700110}
111
112TEST_F(PrefsTest, SetStringCreateDir) {
Darin Petkov30030592010-07-27 13:53:20 -0700113 const char kValue[] = "test value";
Alex Vakulenko75039d72014-03-25 12:36:28 -0700114 base::FilePath subdir = prefs_dir_.Append("subdir1").Append("subdir2");
Darin Petkov1cbd78f2010-07-29 12:38:34 -0700115 EXPECT_TRUE(prefs_.Init(subdir));
Darin Petkov30030592010-07-27 13:53:20 -0700116 EXPECT_TRUE(prefs_.SetString(kKey, kValue));
117 string value;
Alex Vakulenko75039d72014-03-25 12:36:28 -0700118 EXPECT_TRUE(base::ReadFileToString(subdir.Append(kKey), &value));
Darin Petkov30030592010-07-27 13:53:20 -0700119 EXPECT_EQ(kValue, value);
120}
121
122TEST_F(PrefsTest, SetStringDirCreationFailure) {
Alex Vakulenko75039d72014-03-25 12:36:28 -0700123 EXPECT_TRUE(prefs_.Init(base::FilePath("/dev/null")));
Darin Petkov30030592010-07-27 13:53:20 -0700124 EXPECT_FALSE(prefs_.SetString(kKey, "test value"));
125}
126
127TEST_F(PrefsTest, SetStringFileCreationFailure) {
Alex Vakulenko75039d72014-03-25 12:36:28 -0700128 base::CreateDirectory(prefs_dir_.Append(kKey));
Darin Petkov30030592010-07-27 13:53:20 -0700129 EXPECT_FALSE(prefs_.SetString(kKey, "test value"));
Alex Vakulenko75039d72014-03-25 12:36:28 -0700130 EXPECT_TRUE(base::DirectoryExists(prefs_dir_.Append(kKey)));
Darin Petkov30030592010-07-27 13:53:20 -0700131}
132
133TEST_F(PrefsTest, GetInt64) {
Darin Petkov30030592010-07-27 13:53:20 -0700134 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
140TEST_F(PrefsTest, GetInt64BadValue) {
Darin Petkov30030592010-07-27 13:53:20 -0700141 ASSERT_TRUE(SetValue(kKey, "30a"));
142 int64_t value;
143 EXPECT_FALSE(prefs_.GetInt64(kKey, &value));
144}
145
146TEST_F(PrefsTest, GetInt64Max) {
Alex Vakulenko0103c362016-01-20 07:56:15 -0800147 ASSERT_TRUE(SetValue(kKey, base::StringPrintf(
Alex Deymo80f70ff2016-02-10 16:08:11 -0800148 "%" PRIi64, std::numeric_limits<int64_t>::max())));
Darin Petkov30030592010-07-27 13:53:20 -0700149 int64_t value;
150 EXPECT_TRUE(prefs_.GetInt64(kKey, &value));
Alex Deymo80f70ff2016-02-10 16:08:11 -0800151 EXPECT_EQ(std::numeric_limits<int64_t>::max(), value);
Darin Petkov30030592010-07-27 13:53:20 -0700152}
153
154TEST_F(PrefsTest, GetInt64Min) {
Alex Vakulenko0103c362016-01-20 07:56:15 -0800155 ASSERT_TRUE(SetValue(kKey, base::StringPrintf(
Alex Deymo80f70ff2016-02-10 16:08:11 -0800156 "%" PRIi64, std::numeric_limits<int64_t>::min())));
Darin Petkov30030592010-07-27 13:53:20 -0700157 int64_t value;
158 EXPECT_TRUE(prefs_.GetInt64(kKey, &value));
Alex Deymo80f70ff2016-02-10 16:08:11 -0800159 EXPECT_EQ(std::numeric_limits<int64_t>::min(), value);
Darin Petkov30030592010-07-27 13:53:20 -0700160}
161
162TEST_F(PrefsTest, GetInt64Negative) {
Darin Petkov30030592010-07-27 13:53:20 -0700163 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
169TEST_F(PrefsTest, GetInt64NonExistentKey) {
170 int64_t value;
171 EXPECT_FALSE(prefs_.GetInt64("random-key", &value));
172}
173
174TEST_F(PrefsTest, SetInt64) {
Darin Petkov30030592010-07-27 13:53:20 -0700175 EXPECT_TRUE(prefs_.SetInt64(kKey, -123));
176 string value;
Alex Vakulenko75039d72014-03-25 12:36:28 -0700177 EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
Darin Petkov30030592010-07-27 13:53:20 -0700178 EXPECT_EQ("-123", value);
179}
180
181TEST_F(PrefsTest, SetInt64BadKey) {
Alex Deymod6f60072015-10-12 12:22:27 -0700182 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)));
Darin Petkov30030592010-07-27 13:53:20 -0700185}
186
187TEST_F(PrefsTest, SetInt64Max) {
Alex Vakulenko0103c362016-01-20 07:56:15 -0800188 EXPECT_TRUE(prefs_.SetInt64(kKey, std::numeric_limits<int64_t>::max()));
Darin Petkov30030592010-07-27 13:53:20 -0700189 string value;
Alex Vakulenko75039d72014-03-25 12:36:28 -0700190 EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
Alex Vakulenko0103c362016-01-20 07:56:15 -0800191 EXPECT_EQ(base::StringPrintf("%" PRIi64, std::numeric_limits<int64_t>::max()),
192 value);
Darin Petkov30030592010-07-27 13:53:20 -0700193}
194
195TEST_F(PrefsTest, SetInt64Min) {
Alex Vakulenko0103c362016-01-20 07:56:15 -0800196 EXPECT_TRUE(prefs_.SetInt64(kKey, std::numeric_limits<int64_t>::min()));
Darin Petkov30030592010-07-27 13:53:20 -0700197 string value;
Alex Vakulenko75039d72014-03-25 12:36:28 -0700198 EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
Alex Vakulenko0103c362016-01-20 07:56:15 -0800199 EXPECT_EQ(base::StringPrintf("%" PRIi64, std::numeric_limits<int64_t>::min()),
200 value);
Darin Petkov30030592010-07-27 13:53:20 -0700201}
202
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700203TEST_F(PrefsTest, GetBooleanFalse) {
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700204 ASSERT_TRUE(SetValue(kKey, " \n false \t "));
205 bool value;
206 EXPECT_TRUE(prefs_.GetBoolean(kKey, &value));
207 EXPECT_FALSE(value);
208}
209
210TEST_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
218TEST_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
225TEST_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
232TEST_F(PrefsTest, GetBooleanNonExistentKey) {
233 bool value;
234 EXPECT_FALSE(prefs_.GetBoolean("random-key", &value));
235}
236
237TEST_F(PrefsTest, SetBooleanTrue) {
238 const char kKey[] = "test-bool";
239 EXPECT_TRUE(prefs_.SetBoolean(kKey, true));
240 string value;
Alex Vakulenko75039d72014-03-25 12:36:28 -0700241 EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700242 EXPECT_EQ("true", value);
243}
244
245TEST_F(PrefsTest, SetBooleanFalse) {
246 const char kKey[] = "test-bool";
247 EXPECT_TRUE(prefs_.SetBoolean(kKey, false));
248 string value;
Alex Vakulenko75039d72014-03-25 12:36:28 -0700249 EXPECT_TRUE(base::ReadFileToString(prefs_dir_.Append(kKey), &value));
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700250 EXPECT_EQ("false", value);
251}
252
253TEST_F(PrefsTest, SetBooleanBadKey) {
254 const char kKey[] = "s p a c e s";
255 EXPECT_FALSE(prefs_.SetBoolean(kKey, true));
Alex Vakulenko75039d72014-03-25 12:36:28 -0700256 EXPECT_FALSE(base::PathExists(prefs_dir_.Append(kKey)));
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700257}
258
Jay Srinivasan480ddfa2012-06-01 19:15:26 -0700259TEST_F(PrefsTest, ExistsWorks) {
Jay Srinivasan480ddfa2012-06-01 19:15:26 -0700260 // 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
268TEST_F(PrefsTest, DeleteWorks) {
Jay Srinivasan480ddfa2012-06-01 19:15:26 -0700269 // 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
Alex Deymod6f60072015-10-12 12:22:27 -0700280class MockPrefsObserver : public PrefsInterface::ObserverInterface {
281 public:
282 MOCK_METHOD1(OnPrefSet, void(const string&));
283 MOCK_METHOD1(OnPrefDeleted, void(const string& key));
284};
285
286TEST_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
303TEST_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
316TEST_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
329TEST_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
Alex Deymoe6eef832016-07-22 12:51:41 -0700342class MemoryPrefsTest : public ::testing::Test {
343 protected:
344 MemoryPrefs prefs_;
345};
346
347TEST_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
Darin Petkov30030592010-07-27 13:53:20 -0700362} // namespace chromeos_update_engine