blob: 831cf059f8f9a4aaf77f5d4c1de68378131ac8ca [file] [log] [blame]
Paul Stewart2ebc16d2012-08-23 10:38:39 -07001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Darin Petkov083047b2011-06-23 20:42:48 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Chris Masone8a7b8be2011-07-22 12:43:37 -07005#include "shill/key_file_store.h"
6
Alex Vakulenko8a532292014-06-16 17:18:44 -07007#include <set>
8#include <string>
9#include <vector>
10
Ben Chana0ddf462014-02-06 11:32:42 -080011#include <base/files/file_enumerator.h>
Ben Chan11c213f2014-09-05 08:21:06 -070012#include <base/files/file_util.h>
Paul Stewart5ad16062013-02-21 18:10:48 -080013#include <base/files/scoped_temp_dir.h>
Eric Shienbrood3e20a232012-02-16 11:35:56 -050014#include <base/stl_util.h>
Ben Chana0ddf462014-02-06 11:32:42 -080015#include <base/strings/string_number_conversions.h>
16#include <base/strings/stringprintf.h>
Darin Petkov083047b2011-06-23 20:42:48 -070017#include <gtest/gtest.h>
18
Paul Stewart5b9ec982013-01-18 14:12:14 -080019#include "shill/key_value_store.h"
20
Ben Chana0ddf462014-02-06 11:32:42 -080021using base::FileEnumerator;
Albert Chaulk0e1cdea2013-02-27 15:32:55 -080022using base::FilePath;
Darin Petkov083047b2011-06-23 20:42:48 -070023using std::set;
24using std::string;
Darin Petkovb2841fd2011-06-30 12:54:12 -070025using std::vector;
Darin Petkov083047b2011-06-23 20:42:48 -070026using testing::Test;
27
28namespace shill {
29
Darin Petkov86964e02011-06-29 13:49:28 -070030namespace {
31const char kPlainText[] = "This is a test!";
32const char kROT47Text[] = "rot47:%9:D :D 2 E6DEP";
Alex Vakulenko8a532292014-06-16 17:18:44 -070033} // namespace
Darin Petkov86964e02011-06-29 13:49:28 -070034
Darin Petkov083047b2011-06-23 20:42:48 -070035class KeyFileStoreTest : public Test {
36 public:
37 KeyFileStoreTest() : store_(&glib_) {}
38
39 virtual void SetUp() {
40 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
Chris Masoneb9c00592011-10-06 13:10:39 -070041 test_file_ = temp_dir_.path().Append("test-key-file-store");
42 store_.set_path(test_file_);
Darin Petkov083047b2011-06-23 20:42:48 -070043 }
44
45 virtual void TearDown() {
46 store_.set_path(FilePath("")); // Don't try to save the store.
47 ASSERT_TRUE(temp_dir_.Delete());
48 }
49
50 protected:
51 string ReadKeyFile();
52 void WriteKeyFile(string data);
Chris Masoneb9c00592011-10-06 13:10:39 -070053 bool OpenCheckClose(const string &group,
54 const string &key,
55 const string &expected_value);
Darin Petkov083047b2011-06-23 20:42:48 -070056
57 GLib glib_; // Use real GLib for testing KeyFileStore.
Paul Stewart5ad16062013-02-21 18:10:48 -080058 base::ScopedTempDir temp_dir_;
Chris Masoneb9c00592011-10-06 13:10:39 -070059 FilePath test_file_;
Darin Petkov083047b2011-06-23 20:42:48 -070060 KeyFileStore store_;
61};
62
63string KeyFileStoreTest::ReadKeyFile() {
64 string data;
Ben Chana0ddf462014-02-06 11:32:42 -080065 EXPECT_TRUE(base::ReadFileToString(store_.path(), &data));
Darin Petkov083047b2011-06-23 20:42:48 -070066 return data;
67}
68
69void KeyFileStoreTest::WriteKeyFile(string data) {
70 EXPECT_EQ(data.size(),
Ben Chan6fbf64f2014-05-21 18:07:01 -070071 base::WriteFile(store_.path(), data.data(), data.size()));
Darin Petkov083047b2011-06-23 20:42:48 -070072}
73
74TEST_F(KeyFileStoreTest, OpenClose) {
75 EXPECT_FALSE(store_.key_file_);
76
Paul Stewart5dc40aa2011-10-28 19:43:43 -070077 EXPECT_FALSE(store_.IsNonEmpty());
Darin Petkov083047b2011-06-23 20:42:48 -070078 ASSERT_TRUE(store_.Open());
79 EXPECT_TRUE(store_.key_file_);
Darin Petkov86964e02011-06-29 13:49:28 -070080 EXPECT_EQ(1, store_.crypto_.cryptos_.size());
Darin Petkov083047b2011-06-23 20:42:48 -070081 ASSERT_TRUE(store_.Close());
82 EXPECT_FALSE(store_.key_file_);
Gary Morain96970242012-04-20 10:59:58 -070083 FileEnumerator file_enumerator(temp_dir_.path(),
84 false /* not recursive */,
85 FileEnumerator::FILES);
86
87 // Verify that the file actually got written with the right name.
88 EXPECT_EQ(test_file_.value(), file_enumerator.Next().value());
Ben Chana0ddf462014-02-06 11:32:42 -080089 FileEnumerator::FileInfo file_info = file_enumerator.GetInfo();
Gary Morain96970242012-04-20 10:59:58 -070090
91 // Verify that the profile is a regular file, readable and writeable by the
92 // owner only.
Ben Chana0ddf462014-02-06 11:32:42 -080093 EXPECT_EQ(S_IFREG | S_IRUSR | S_IWUSR, file_info.stat().st_mode);
Darin Petkov083047b2011-06-23 20:42:48 -070094
95 ASSERT_TRUE(store_.Open());
96 EXPECT_TRUE(store_.key_file_);
97 ASSERT_TRUE(store_.Close());
98 EXPECT_FALSE(store_.key_file_);
99
100 ASSERT_TRUE(store_.Open());
101 store_.set_path(FilePath(""));
102 ASSERT_FALSE(store_.Close());
103 EXPECT_FALSE(store_.key_file_);
104}
105
106TEST_F(KeyFileStoreTest, OpenFail) {
107 WriteKeyFile("garbage\n");
108 EXPECT_FALSE(store_.Open());
109 EXPECT_FALSE(store_.key_file_);
110}
111
Paul Stewart2ebc16d2012-08-23 10:38:39 -0700112TEST_F(KeyFileStoreTest, MarkAsCorrupted) {
113 EXPECT_FALSE(store_.MarkAsCorrupted());
114 EXPECT_FALSE(store_.IsNonEmpty());
115 WriteKeyFile("garbage\n");
116 EXPECT_TRUE(store_.IsNonEmpty());
Ben Chana0ddf462014-02-06 11:32:42 -0800117 EXPECT_TRUE(base::PathExists(store_.path()));
Paul Stewart2ebc16d2012-08-23 10:38:39 -0700118 EXPECT_TRUE(store_.MarkAsCorrupted());
119 EXPECT_FALSE(store_.IsNonEmpty());
Ben Chana0ddf462014-02-06 11:32:42 -0800120 EXPECT_FALSE(base::PathExists(store_.path()));
121 EXPECT_TRUE(base::PathExists(FilePath(store_.path().value() + ".corrupted")));
Paul Stewart2ebc16d2012-08-23 10:38:39 -0700122}
123
Darin Petkov083047b2011-06-23 20:42:48 -0700124TEST_F(KeyFileStoreTest, GetGroups) {
125 static const char kGroupA[] = "g-a";
126 static const char kGroupB[] = "g-b";
127 static const char kGroupC[] = "g-c";
128 WriteKeyFile(base::StringPrintf("[%s]\n"
129 "[%s]\n"
130 "[%s]\n",
131 kGroupA, kGroupB, kGroupC));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700132 EXPECT_TRUE(store_.IsNonEmpty());
Darin Petkov083047b2011-06-23 20:42:48 -0700133 ASSERT_TRUE(store_.Open());
134 set<string> groups = store_.GetGroups();
135 EXPECT_EQ(3, groups.size());
136 EXPECT_TRUE(ContainsKey(groups, kGroupA));
137 EXPECT_TRUE(ContainsKey(groups, kGroupB));
138 EXPECT_TRUE(ContainsKey(groups, kGroupC));
139 EXPECT_FALSE(ContainsKey(groups, "g-x"));
140 ASSERT_TRUE(store_.Close());
141}
142
Paul Stewarta41e38d2011-11-11 07:47:29 -0800143TEST_F(KeyFileStoreTest, GetGroupsWithKey) {
144 static const char kGroupA[] = "g-a";
145 static const char kGroupB[] = "g-b";
146 static const char kGroupC[] = "g-c";
147 static const char kKeyA[] = "k-a";
148 static const char kKeyB[] = "k-b";
149 static const char kValue[] = "true";
150 WriteKeyFile(base::StringPrintf("[%s]\n"
151 "%s=%s\n"
152 "[%s]\n"
153 "%s=%s\n"
154 "%s=%s\n"
155 "[%s]\n"
156 "%s=%s\n",
157 kGroupA, kKeyA, kValue,
158 kGroupB, kKeyA, kValue, kKeyB, kValue,
159 kGroupC, kKeyB, kValue));
160 EXPECT_TRUE(store_.IsNonEmpty());
161 ASSERT_TRUE(store_.Open());
162 set<string> groups_a = store_.GetGroupsWithKey(kKeyA);
163 EXPECT_EQ(2, groups_a.size());
164 EXPECT_TRUE(ContainsKey(groups_a, kGroupA));
165 EXPECT_TRUE(ContainsKey(groups_a, kGroupB));
166 set<string> groups_b = store_.GetGroupsWithKey(kKeyB);
167 EXPECT_EQ(2, groups_b.size());
168 EXPECT_TRUE(ContainsKey(groups_b, kGroupB));
169 EXPECT_TRUE(ContainsKey(groups_b, kGroupC));
170 ASSERT_TRUE(store_.Close());
171}
172
Darin Petkov083047b2011-06-23 20:42:48 -0700173TEST_F(KeyFileStoreTest, ContainsGroup) {
174 static const char kGroupA[] = "group-a";
175 static const char kGroupB[] = "group-b";
176 static const char kGroupC[] = "group-c";
177 WriteKeyFile(base::StringPrintf("[%s]\n"
178 "[%s]\n"
179 "[%s]\n",
180 kGroupA, kGroupB, kGroupC));
181 ASSERT_TRUE(store_.Open());
182 EXPECT_TRUE(store_.ContainsGroup(kGroupA));
183 EXPECT_TRUE(store_.ContainsGroup(kGroupB));
184 EXPECT_TRUE(store_.ContainsGroup(kGroupC));
185 EXPECT_FALSE(store_.ContainsGroup("group-d"));
186 ASSERT_TRUE(store_.Close());
187}
188
Paul Stewart5b9ec982013-01-18 14:12:14 -0800189TEST_F(KeyFileStoreTest, GetGroupsWithProperties) {
190 static const char kGroupA[] = "group-a";
191 static const char kGroupB[] = "group-b";
192 static const char kGroupC[] = "group-c";
193 static const char kAttributeA[] = "attr-a";
194 static const char kAttributeB[] = "attr-b";
195 static const char kAttributeC[] = "attr-c";
196 static const char kValueA_0[] = "val-a";
197 static const char kValueA_1[] = "val-b";
198 static const int kValueB_0 = 1;
199 static const int kValueB_1 = 2;
200 static const bool kValueC_0 = true;
201 static const char kValueC_0_string[] = "true";
202 static const bool kValueC_1 = false;
203 static const char kValueC_1_string[] = "false";
204 WriteKeyFile(base::StringPrintf("[%s]\n"
205 "%s=%s\n"
206 "%s=%d\n"
207 "%s=%s\n"
208 "[%s]\n"
209 "%s=%s\n"
210 "%s=%d\n"
211 "%s=%s\n"
212 "[%s]\n"
213 "%s=%s\n"
214 "%s=%d\n"
215 "%s=%s\n",
216 kGroupA,
217 kAttributeA, kValueA_0,
218 kAttributeB, kValueB_0,
219 kAttributeC, kValueC_0_string,
220 kGroupB,
221 kAttributeA, kValueA_0,
222 kAttributeB, kValueB_1,
223 kAttributeC, kValueC_0_string,
224 kGroupC,
225 kAttributeA, kValueA_0,
226 kAttributeB, kValueB_0,
227 kAttributeC, kValueC_1_string));
228 ASSERT_TRUE(store_.Open());
229 {
230 KeyValueStore args;
231 args.SetString(kAttributeA, kValueA_0);
232 args.SetInt(kAttributeB, kValueB_0);
233 set<string> results = store_.GetGroupsWithProperties(args);
234 EXPECT_EQ(2, results.size());
235 EXPECT_TRUE(results.find(kGroupA) != results.end());
236 EXPECT_TRUE(results.find(kGroupC) != results.end());
237 }
238 {
239 KeyValueStore args;
240 args.SetString(kAttributeA, kValueA_0);
241 args.SetBool(kAttributeC, kValueC_0);
242 set<string> results = store_.GetGroupsWithProperties(args);
243 EXPECT_EQ(2, results.size());
244 EXPECT_TRUE(results.find(kGroupA) != results.end());
245 EXPECT_TRUE(results.find(kGroupB) != results.end());
246 }
247 {
248 KeyValueStore args;
249 args.SetBool(kAttributeC, kValueC_1);
250 set<string> results = store_.GetGroupsWithProperties(args);
251 EXPECT_EQ(1, results.size());
252 EXPECT_TRUE(results.find(kGroupC) != results.end());
253 }
254 {
255 KeyValueStore args;
256 args.SetString(kAttributeA, kValueA_0);
257 set<string> results = store_.GetGroupsWithProperties(args);
258 EXPECT_EQ(3, results.size());
259 EXPECT_TRUE(results.find(kGroupA) != results.end());
260 EXPECT_TRUE(results.find(kGroupB) != results.end());
261 EXPECT_TRUE(results.find(kGroupC) != results.end());
262 }
263 {
264 KeyValueStore args;
265 args.SetString(kAttributeA, kValueA_1);
266 set<string> results = store_.GetGroupsWithProperties(args);
267 EXPECT_EQ(0, results.size());
268 }
269 ASSERT_TRUE(store_.Close());
270}
271
Darin Petkov083047b2011-06-23 20:42:48 -0700272TEST_F(KeyFileStoreTest, DeleteKey) {
273 static const char kGroup[] = "the-group";
274 static const char kKeyDead[] = "dead";
275 static const char kKeyAlive[] = "alive";
276 const int kValueAlive = 3;
277 WriteKeyFile(base::StringPrintf("[%s]\n"
278 "%s=5\n"
279 "%s=%d\n",
280 kGroup, kKeyDead, kKeyAlive, kValueAlive));
281 ASSERT_TRUE(store_.Open());
282 EXPECT_TRUE(store_.DeleteKey(kGroup, kKeyDead));
Chris Masone9d779932011-08-25 16:33:41 -0700283 EXPECT_TRUE(store_.DeleteKey(kGroup, "random-key"));
Darin Petkov083047b2011-06-23 20:42:48 -0700284 EXPECT_FALSE(store_.DeleteKey("random-group", kKeyAlive));
285 ASSERT_TRUE(store_.Close());
Ben Chana0ddf462014-02-06 11:32:42 -0800286 EXPECT_EQ(base::StringPrintf("[%s]\n"
Darin Petkov083047b2011-06-23 20:42:48 -0700287 "%s=%d\n",
288 kGroup, kKeyAlive, kValueAlive),
289 ReadKeyFile());
290}
291
292TEST_F(KeyFileStoreTest, DeleteGroup) {
293 static const char kGroupA[] = "group-a";
294 static const char kGroupB[] = "group-b";
295 static const char kGroupC[] = "group-c";
296 WriteKeyFile(base::StringPrintf("[%s]\n"
297 "[%s]\n"
298 "key-to-be-deleted=true\n"
299 "[%s]\n",
300 kGroupA, kGroupB, kGroupC));
301 ASSERT_TRUE(store_.Open());
302 EXPECT_TRUE(store_.DeleteGroup(kGroupB));
Chris Masone9d779932011-08-25 16:33:41 -0700303 EXPECT_TRUE(store_.DeleteGroup("group-d"));
Darin Petkov083047b2011-06-23 20:42:48 -0700304 ASSERT_TRUE(store_.Close());
Ben Chana0ddf462014-02-06 11:32:42 -0800305 EXPECT_EQ(base::StringPrintf("[%s]\n"
Darin Petkov083047b2011-06-23 20:42:48 -0700306 "\n"
307 "[%s]\n",
308 kGroupA, kGroupC),
309 ReadKeyFile());
310}
311
312TEST_F(KeyFileStoreTest, GetString) {
313 static const char kGroup[] = "something";
314 static const char kKey[] = "foo";
315 static const char kValue[] = "bar";
316 WriteKeyFile(base::StringPrintf("[%s]\n"
317 "%s=%s\n",
318 kGroup, kKey, kValue));
319 ASSERT_TRUE(store_.Open());
320 string value;
321 EXPECT_TRUE(store_.GetString(kGroup, kKey, &value));
322 EXPECT_EQ(kValue, value);
323 EXPECT_FALSE(store_.GetString("something-else", kKey, &value));
324 EXPECT_FALSE(store_.GetString(kGroup, "bar", &value));
325 EXPECT_TRUE(store_.GetString(kGroup, kKey, NULL));
326 ASSERT_TRUE(store_.Close());
327}
328
329TEST_F(KeyFileStoreTest, SetString) {
330 static const char kGroup[] = "string-group";
331 static const char kKey1[] = "test-string";
332 static const char kValue1[] = "foo";
333 static const char kKey2[] = "empty-string";
334 static const char kValue2[] = "";
335 ASSERT_TRUE(store_.Open());
336 ASSERT_TRUE(store_.SetString(kGroup, kKey1, kValue1));
337 ASSERT_TRUE(store_.SetString(kGroup, kKey2, kValue2));
338 ASSERT_TRUE(store_.Close());
Ben Chana0ddf462014-02-06 11:32:42 -0800339 EXPECT_EQ(base::StringPrintf("[%s]\n"
Darin Petkov083047b2011-06-23 20:42:48 -0700340 "%s=%s\n"
341 "%s=%s\n",
342 kGroup, kKey1, kValue1, kKey2, kValue2),
343 ReadKeyFile());
344}
345
346TEST_F(KeyFileStoreTest, GetBool) {
347 static const char kGroup[] = "boo";
348 static const char kKeyTrue[] = "foo";
349 static const char kKeyFalse[] = "bar";
350 static const char kKeyBad[] = "zoo";
351 WriteKeyFile(base::StringPrintf("[%s]\n"
352 "%s=true\n"
353 "%s=false\n"
354 "%s=moo\n",
355 kGroup, kKeyTrue, kKeyFalse, kKeyBad));
356 ASSERT_TRUE(store_.Open());
357 {
358 bool value = true;
359 EXPECT_TRUE(store_.GetBool(kGroup, kKeyFalse, &value));
360 EXPECT_FALSE(value);
361 }
362 {
363 bool value = false;
364 EXPECT_TRUE(store_.GetBool(kGroup, kKeyTrue, &value));
365 EXPECT_TRUE(value);
366 }
367 {
368 bool value;
369 EXPECT_FALSE(store_.GetBool(kGroup, kKeyBad, &value));
370 EXPECT_FALSE(store_.GetBool(kGroup, "unknown", &value));
371 EXPECT_FALSE(store_.GetBool("unknown", kKeyTrue, &value));
372 }
373 EXPECT_TRUE(store_.GetBool(kGroup, kKeyFalse, NULL));
374 ASSERT_TRUE(store_.Close());
375}
376
377TEST_F(KeyFileStoreTest, SetBool) {
378 static const char kGroup[] = "bool-group";
379 static const char kKeyTrue[] = "test-true-bool";
380 static const char kKeyFalse[] = "test-false-bool";
381 ASSERT_TRUE(store_.Open());
382 ASSERT_TRUE(store_.SetBool(kGroup, kKeyTrue, true));
383 ASSERT_TRUE(store_.SetBool(kGroup, kKeyFalse, false));
384 ASSERT_TRUE(store_.Close());
Ben Chana0ddf462014-02-06 11:32:42 -0800385 EXPECT_EQ(base::StringPrintf("[%s]\n"
Darin Petkov083047b2011-06-23 20:42:48 -0700386 "%s=true\n"
387 "%s=false\n",
388 kGroup, kKeyTrue, kKeyFalse),
389 ReadKeyFile());
390}
391
392TEST_F(KeyFileStoreTest, GetInt) {
393 static const char kGroup[] = "numbers";
394 static const char kKeyPos[] = "pos";
395 static const char kKeyNeg[] = "neg";
396 static const char kKeyBad[] = "bad";
397 const int kValuePos = 50;
398 const int kValueNeg = -20;
399 static const char kValueBad[] = "nan";
400 WriteKeyFile(base::StringPrintf("[%s]\n"
401 "%s=%d\n"
402 "%s=%d\n"
403 "%s=%s\n",
404 kGroup,
405 kKeyPos, kValuePos,
406 kKeyNeg, kValueNeg,
407 kKeyBad, kValueBad));
408 ASSERT_TRUE(store_.Open());
409 {
410 int value = 0;
411 EXPECT_TRUE(store_.GetInt(kGroup, kKeyNeg, &value));
412 EXPECT_EQ(kValueNeg, value);
413 }
414 {
415 int value = 0;
416 EXPECT_TRUE(store_.GetInt(kGroup, kKeyPos, &value));
417 EXPECT_EQ(kValuePos, value);
418 }
419 {
420 int value;
421 EXPECT_FALSE(store_.GetInt(kGroup, kKeyBad, &value));
422 EXPECT_FALSE(store_.GetInt(kGroup, "invalid", &value));
423 EXPECT_FALSE(store_.GetInt("invalid", kKeyPos, &value));
424 }
425 EXPECT_TRUE(store_.GetInt(kGroup, kKeyPos, NULL));
426 ASSERT_TRUE(store_.Close());
427}
428
429TEST_F(KeyFileStoreTest, SetInt) {
430 static const char kGroup[] = "int-group";
431 static const char kKey1[] = "test-int";
432 static const char kKey2[] = "test-negative";
433 const int kValue1 = 5;
434 const int kValue2 = -10;
435 ASSERT_TRUE(store_.Open());
436 ASSERT_TRUE(store_.SetInt(kGroup, kKey1, kValue1));
437 ASSERT_TRUE(store_.SetInt(kGroup, kKey2, kValue2));
438 ASSERT_TRUE(store_.Close());
Ben Chana0ddf462014-02-06 11:32:42 -0800439 EXPECT_EQ(base::StringPrintf("[%s]\n"
Darin Petkov083047b2011-06-23 20:42:48 -0700440 "%s=%d\n"
441 "%s=%d\n",
442 kGroup, kKey1, kValue1, kKey2, kValue2),
443 ReadKeyFile());
444}
445
Paul Stewartdab3b5a2012-07-11 18:25:10 -0700446TEST_F(KeyFileStoreTest, GetUint64) {
447 static const char kGroup[] = "numbers";
448 static const char kKeyGood[] = "good";
449 static const char kKeyBad[] = "bad";
Ben Chan7fab8972014-08-10 17:14:46 -0700450 const uint64_t kValueGood = 0xFEDCBA9876543210LL;
Paul Stewartdab3b5a2012-07-11 18:25:10 -0700451 static const char kValueBad[] = "nan";
452 // Use base::Uint64ToString() instead of using something like "%llu"
453 // (not correct for native 64 bit architectures) or PRIu64 (does not
454 // work correctly using cros_workon_make due to include intricacies).
455 WriteKeyFile(base::StringPrintf("[%s]\n"
456 "%s=%s\n"
457 "%s=%s\n",
458 kGroup,
459 kKeyGood,
460 base::Uint64ToString(kValueGood).c_str(),
461 kKeyBad, kValueBad));
462 ASSERT_TRUE(store_.Open());
463 {
Ben Chan7fab8972014-08-10 17:14:46 -0700464 uint64_t value = 0;
Paul Stewartdab3b5a2012-07-11 18:25:10 -0700465 EXPECT_TRUE(store_.GetUint64(kGroup, kKeyGood, &value));
466 EXPECT_EQ(kValueGood, value);
467 }
468 {
Ben Chan7fab8972014-08-10 17:14:46 -0700469 uint64_t value;
Paul Stewartdab3b5a2012-07-11 18:25:10 -0700470 EXPECT_FALSE(store_.GetUint64(kGroup, kKeyBad, &value));
471 EXPECT_FALSE(store_.GetUint64(kGroup, "invalid", &value));
472 EXPECT_FALSE(store_.GetUint64("invalid", kKeyGood, &value));
473 }
474 EXPECT_TRUE(store_.GetUint64(kGroup, kKeyGood, NULL));
475 ASSERT_TRUE(store_.Close());
476}
477
478TEST_F(KeyFileStoreTest, SetUint64) {
479 static const char kGroup[] = "int-group";
480 static const char kKey[] = "test-int";
Ben Chan7fab8972014-08-10 17:14:46 -0700481 const uint64_t kValue = 0xFEDCBA9876543210LL;
Paul Stewartdab3b5a2012-07-11 18:25:10 -0700482 ASSERT_TRUE(store_.Open());
483 ASSERT_TRUE(store_.SetUint64(kGroup, kKey, kValue));
484 ASSERT_TRUE(store_.Close());
Ben Chana0ddf462014-02-06 11:32:42 -0800485 EXPECT_EQ(base::StringPrintf("[%s]\n"
Paul Stewartdab3b5a2012-07-11 18:25:10 -0700486 "%s=%s\n",
487 kGroup, kKey,
488 base::Uint64ToString(kValue).c_str()),
489 ReadKeyFile());
490}
491
Darin Petkovb2841fd2011-06-30 12:54:12 -0700492TEST_F(KeyFileStoreTest, GetStringList) {
493 static const char kGroup[] = "string-lists";
494 static const char kKeyEmpty[] = "empty";
495 static const char kKeyEmptyValue[] = "empty-value";
496 static const char kKeyValueEmpty[] = "value-empty";
497 static const char kKeyValueEmptyValue[] = "value-empty-value";
498 static const char kKeyValues[] = "values";
499 static const char kValue[] = "value";
500 static const char kValue2[] = "value2";
501 static const char kValue3[] = "value3";
502 WriteKeyFile(base::StringPrintf("[%s]\n"
503 "%s=\n"
504 "%s=;%s\n"
505 "%s=%s;;\n"
506 "%s=%s;;%s\n"
507 "%s=%s;%s;%s\n",
508 kGroup,
509 kKeyEmpty,
510 kKeyEmptyValue, kValue,
511 kKeyValueEmpty, kValue,
512 kKeyValueEmptyValue, kValue, kValue2,
513 kKeyValues, kValue, kValue2, kValue3));
514 ASSERT_TRUE(store_.Open());
515
516 vector<string> value;
517
518 EXPECT_TRUE(store_.GetStringList(kGroup, kKeyValues, &value));
519 ASSERT_EQ(3, value.size());
520 EXPECT_EQ(kValue, value[0]);
521 EXPECT_EQ(kValue2, value[1]);
522 EXPECT_EQ(kValue3, value[2]);
523
524 EXPECT_TRUE(store_.GetStringList(kGroup, kKeyEmptyValue, &value));
525 ASSERT_EQ(2, value.size());
526 EXPECT_EQ("", value[0]);
527 EXPECT_EQ(kValue, value[1]);
528
529 EXPECT_TRUE(store_.GetStringList(kGroup, kKeyValueEmpty, &value));
530 ASSERT_EQ(2, value.size());
531 EXPECT_EQ(kValue, value[0]);
532 EXPECT_EQ("", value[1]);
533
534 EXPECT_TRUE(store_.GetStringList(kGroup, kKeyEmpty, &value));
535 ASSERT_EQ(0, value.size());
536
537 EXPECT_TRUE(store_.GetStringList(kGroup, kKeyValueEmptyValue, &value));
538 ASSERT_EQ(3, value.size());
539 EXPECT_EQ(kValue, value[0]);
540 EXPECT_EQ("", value[1]);
541 EXPECT_EQ(kValue2, value[2]);
542
543 EXPECT_FALSE(store_.GetStringList("unknown-string-lists", kKeyEmpty, &value));
544 EXPECT_FALSE(store_.GetStringList(kGroup, "some-key", &value));
545 EXPECT_TRUE(store_.GetStringList(kGroup, kKeyValues, NULL));
546 ASSERT_TRUE(store_.Close());
547}
548
549TEST_F(KeyFileStoreTest, SetStringList) {
550 static const char kGroup[] = "strings";
551 static const char kKeyEmpty[] = "e";
552 static const char kKeyEmptyValue[] = "ev";
553 static const char kKeyValueEmpty[] = "ve";
554 static const char kKeyValueEmptyValue[] = "vev";
555 static const char kKeyValues[] = "v";
556 static const char kValue[] = "abc";
557 static const char kValue2[] = "pqr";
558 static const char kValue3[] = "xyz";
559 ASSERT_TRUE(store_.Open());
560 {
561 vector<string> value;
562 ASSERT_TRUE(store_.SetStringList(kGroup, kKeyEmpty, value));
563 }
564 {
565 vector<string> value;
566 value.push_back("");
567 value.push_back(kValue);
568 ASSERT_TRUE(store_.SetStringList(kGroup, kKeyEmptyValue, value));
569 }
570 {
571 vector<string> value;
572 value.push_back(kValue);
573 value.push_back("");
574 ASSERT_TRUE(store_.SetStringList(kGroup, kKeyValueEmpty, value));
575 }
576 {
577 vector<string> value;
578 value.push_back(kValue);
579 value.push_back("");
580 value.push_back(kValue2);
581 ASSERT_TRUE(store_.SetStringList(kGroup, kKeyValueEmptyValue, value));
582 }
583 {
584 vector<string> value;
585 value.push_back(kValue);
586 value.push_back(kValue2);
587 value.push_back(kValue3);
588 ASSERT_TRUE(store_.SetStringList(kGroup, kKeyValues, value));
589 }
590 ASSERT_TRUE(store_.Close());
Ben Chana0ddf462014-02-06 11:32:42 -0800591 EXPECT_EQ(base::StringPrintf("[%s]\n"
Darin Petkovb2841fd2011-06-30 12:54:12 -0700592 "%s=\n"
593 "%s=;%s;\n"
594 "%s=%s;;\n"
595 "%s=%s;;%s;\n"
596 "%s=%s;%s;%s;\n",
597 kGroup,
598 kKeyEmpty,
599 kKeyEmptyValue, kValue,
600 kKeyValueEmpty, kValue,
601 kKeyValueEmptyValue, kValue, kValue2,
602 kKeyValues, kValue, kValue2, kValue3),
603 ReadKeyFile());
604}
605
Darin Petkov86964e02011-06-29 13:49:28 -0700606TEST_F(KeyFileStoreTest, GetCryptedString) {
607 static const char kGroup[] = "crypto-group";
608 static const char kKey[] = "secret";
609 WriteKeyFile(base::StringPrintf("[%s]\n"
610 "%s=%s\n",
611 kGroup, kKey, kROT47Text));
612 ASSERT_TRUE(store_.Open());
613 string value;
614 EXPECT_TRUE(store_.GetCryptedString(kGroup, kKey, &value));
615 EXPECT_EQ(kPlainText, value);
616 EXPECT_FALSE(store_.GetCryptedString("something-else", kKey, &value));
617 EXPECT_FALSE(store_.GetCryptedString(kGroup, "non-secret", &value));
618 EXPECT_TRUE(store_.GetCryptedString(kGroup, kKey, NULL));
619 ASSERT_TRUE(store_.Close());
620}
621
622TEST_F(KeyFileStoreTest, SetCryptedString) {
623 static const char kGroup[] = "crypted-string-group";
624 static const char kKey[] = "test-string";
625 ASSERT_TRUE(store_.Open());
626 ASSERT_TRUE(store_.SetCryptedString(kGroup, kKey, kPlainText));
627 ASSERT_TRUE(store_.Close());
Ben Chana0ddf462014-02-06 11:32:42 -0800628 EXPECT_EQ(base::StringPrintf("[%s]\n"
Darin Petkov86964e02011-06-29 13:49:28 -0700629 "%s=%s\n",
630 kGroup, kKey, kROT47Text),
631 ReadKeyFile());
632}
633
Chris Masoneb9c00592011-10-06 13:10:39 -0700634TEST_F(KeyFileStoreTest, PersistAcrossClose) {
635 static const char kGroup[] = "string-group";
636 static const char kKey1[] = "test-string";
637 static const char kValue1[] = "foo";
638 static const char kKey2[] = "empty-string";
639 static const char kValue2[] = "";
640 ASSERT_TRUE(store_.Open());
641 ASSERT_TRUE(store_.SetString(kGroup, kKey1, kValue1));
642 ASSERT_TRUE(store_.Close());
643 ASSERT_TRUE(store_.Open());
644 ASSERT_TRUE(store_.SetString(kGroup, kKey2, kValue2));
645 string value;
646 ASSERT_TRUE(store_.GetString(kGroup, kKey1, &value));
647 ASSERT_EQ(kValue1, value);
648 ASSERT_TRUE(store_.GetString(kGroup, kKey2, &value));
649 ASSERT_EQ(kValue2, value);
650 ASSERT_TRUE(store_.Close());
651}
652
653bool KeyFileStoreTest::OpenCheckClose(const string &group,
654 const string &key,
655 const string &expected_value) {
656 KeyFileStore store(&glib_);
657 store.set_path(test_file_);
658 EXPECT_TRUE(store.Open());
659 string value;
660 bool could_get = store.GetString(group, key, &value);
661 store.set_path(FilePath("")); // Don't persist to disk.
662 store.Close();
663 return could_get && expected_value == value;
664}
665
666TEST_F(KeyFileStoreTest, Flush) {
667 static const char kGroup[] = "string-group";
668 static const char kKey1[] = "test-string";
669 static const char kValue1[] = "foo";
670 static const char kKey2[] = "empty-string";
671 static const char kValue2[] = "";
672 ASSERT_TRUE(store_.Open());
673 ASSERT_TRUE(store_.SetString(kGroup, kKey1, kValue1));
674 ASSERT_TRUE(store_.Flush());
675 ASSERT_TRUE(OpenCheckClose(kGroup, kKey1, kValue1));
676
677 ASSERT_TRUE(store_.SetString(kGroup, kKey2, kValue2));
678 ASSERT_TRUE(store_.Flush());
679 ASSERT_TRUE(OpenCheckClose(kGroup, kKey2, kValue2));
680
681 EXPECT_TRUE(store_.DeleteKey(kGroup, kKey1));
682 ASSERT_TRUE(store_.Flush());
683 ASSERT_FALSE(OpenCheckClose(kGroup, kKey1, kValue1));
684}
685
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700686TEST_F(KeyFileStoreTest, EmptyFile) {
687 ASSERT_TRUE(store_.Open());
688 ASSERT_TRUE(store_.Close());
689 EXPECT_FALSE(store_.IsNonEmpty());
690}
691
692TEST_F(KeyFileStoreTest, SetHeader) {
693 ASSERT_TRUE(store_.Open());
694 ASSERT_TRUE(store_.SetHeader("this is a test"));
695 ASSERT_TRUE(store_.Close());
696 EXPECT_TRUE(store_.IsNonEmpty());
697 ASSERT_TRUE(store_.Open());
698}
699
Darin Petkov083047b2011-06-23 20:42:48 -0700700TEST_F(KeyFileStoreTest, Combo) {
701 static const char kGroupA[] = "square";
702 static const char kGroupB[] = "circle";
703 static const char kGroupC[] = "triangle";
704 static const char kGroupX[] = "pentagon";
705 static const char kKeyString[] = "color";
Darin Petkovb2841fd2011-06-30 12:54:12 -0700706 static const char kKeyStringList[] = "alternative-colors";
Darin Petkov083047b2011-06-23 20:42:48 -0700707 static const char kKeyInt[] = "area";
708 static const char kKeyBool[] = "visible";
709 static const char kValueStringA[] = "blue";
710 static const char kValueStringB[] = "red";
711 static const char kValueStringC[] = "yellow";
712 static const char kValueStringCNew[] = "purple";
713 const int kValueIntA = 5;
714 const int kValueIntB = 10;
715 const int kValueIntBNew = 333;
716 WriteKeyFile(base::StringPrintf("[%s]\n"
717 "%s=%s\n"
Darin Petkovb2841fd2011-06-30 12:54:12 -0700718 "%s=%s;%s\n"
Darin Petkov083047b2011-06-23 20:42:48 -0700719 "%s=%d\n"
720 "[%s]\n"
721 "%s=%s\n"
Darin Petkovb2841fd2011-06-30 12:54:12 -0700722 "%s=%s;%s\n"
Darin Petkov083047b2011-06-23 20:42:48 -0700723 "%s=%d\n"
724 "%s=true\n"
725 "[%s]\n"
726 "%s=%s\n"
727 "%s=false\n",
728 kGroupA,
729 kKeyString, kValueStringA,
Darin Petkovb2841fd2011-06-30 12:54:12 -0700730 kKeyStringList, kValueStringB, kValueStringC,
Darin Petkov083047b2011-06-23 20:42:48 -0700731 kKeyInt, kValueIntA,
732 kGroupB,
733 kKeyString, kValueStringB,
Darin Petkovb2841fd2011-06-30 12:54:12 -0700734 kKeyStringList, kValueStringA, kValueStringC,
Darin Petkov083047b2011-06-23 20:42:48 -0700735 kKeyInt, kValueIntB,
736 kKeyBool,
737 kGroupC,
738 kKeyString, kValueStringC,
739 kKeyBool));
740 ASSERT_TRUE(store_.Open());
741
742 EXPECT_TRUE(store_.ContainsGroup(kGroupA));
743 EXPECT_TRUE(store_.ContainsGroup(kGroupB));
744 EXPECT_TRUE(store_.ContainsGroup(kGroupC));
745 EXPECT_FALSE(store_.ContainsGroup(kGroupX));
746
747 set<string> groups = store_.GetGroups();
748 EXPECT_EQ(3, groups.size());
749 EXPECT_TRUE(ContainsKey(groups, kGroupA));
750 EXPECT_TRUE(ContainsKey(groups, kGroupB));
751 EXPECT_TRUE(ContainsKey(groups, kGroupC));
752 EXPECT_FALSE(ContainsKey(groups, kGroupX));
753
754 {
755 string value;
756 EXPECT_TRUE(store_.GetString(kGroupB, kKeyString, &value));
757 EXPECT_EQ(kValueStringB, value);
758 EXPECT_TRUE(store_.GetString(kGroupA, kKeyString, &value));
759 EXPECT_EQ(kValueStringA, value);
760 EXPECT_TRUE(store_.GetString(kGroupC, kKeyString, &value));
761 EXPECT_EQ(kValueStringC, value);
762 }
763 {
Darin Petkovb2841fd2011-06-30 12:54:12 -0700764 vector<string> value;
765 EXPECT_TRUE(store_.GetStringList(kGroupB, kKeyStringList, &value));
766 ASSERT_EQ(2, value.size());
767 EXPECT_EQ(kValueStringA, value[0]);
768 EXPECT_EQ(kValueStringC, value[1]);
769 EXPECT_TRUE(store_.GetStringList(kGroupA, kKeyStringList, &value));
770 ASSERT_EQ(2, value.size());
771 EXPECT_EQ(kValueStringB, value[0]);
772 EXPECT_EQ(kValueStringC, value[1]);
773 EXPECT_FALSE(store_.GetStringList(kGroupC, kKeyStringList, &value));
774 }
775 {
Darin Petkov083047b2011-06-23 20:42:48 -0700776 int value = 0;
777 EXPECT_TRUE(store_.GetInt(kGroupB, kKeyInt, &value));
778 EXPECT_EQ(kValueIntB, value);
779 EXPECT_TRUE(store_.GetInt(kGroupA, kKeyInt, &value));
780 EXPECT_EQ(kValueIntA, value);
781 EXPECT_FALSE(store_.GetInt(kGroupC, kKeyInt, &value));
782 }
783 {
784 bool value = false;
785 EXPECT_TRUE(store_.GetBool(kGroupB, kKeyBool, &value));
786 EXPECT_TRUE(value);
787 EXPECT_TRUE(store_.GetBool(kGroupC, kKeyBool, &value));
788 EXPECT_FALSE(value);
789 EXPECT_FALSE(store_.GetBool(kGroupA, kKeyBool, &value));
790 }
791
792 EXPECT_TRUE(store_.DeleteGroup(kGroupA));
Chris Masone9d779932011-08-25 16:33:41 -0700793 EXPECT_TRUE(store_.DeleteGroup(kGroupA));
Darin Petkov083047b2011-06-23 20:42:48 -0700794
795 EXPECT_FALSE(store_.ContainsGroup(kGroupA));
796 EXPECT_TRUE(store_.ContainsGroup(kGroupB));
797 EXPECT_TRUE(store_.ContainsGroup(kGroupC));
798
799 groups = store_.GetGroups();
800 EXPECT_EQ(2, groups.size());
801 EXPECT_FALSE(ContainsKey(groups, kGroupA));
802 EXPECT_TRUE(ContainsKey(groups, kGroupB));
803 EXPECT_TRUE(ContainsKey(groups, kGroupC));
804
805 EXPECT_TRUE(store_.SetBool(kGroupB, kKeyBool, false));
806 EXPECT_TRUE(store_.SetInt(kGroupB, kKeyInt, kValueIntBNew));
807 EXPECT_TRUE(store_.SetString(kGroupC, kKeyString, kValueStringCNew));
Darin Petkovb2841fd2011-06-30 12:54:12 -0700808 store_.SetStringList(kGroupB,
809 kKeyStringList,
810 vector<string>(1, kValueStringB));
Darin Petkov083047b2011-06-23 20:42:48 -0700811
812 EXPECT_TRUE(store_.DeleteKey(kGroupB, kKeyString));
Chris Masone9d779932011-08-25 16:33:41 -0700813 EXPECT_TRUE(store_.DeleteKey(kGroupB, kKeyString));
Darin Petkov083047b2011-06-23 20:42:48 -0700814
815 {
816 string value;
817 EXPECT_FALSE(store_.GetString(kGroupB, kKeyString, &value));
818 EXPECT_FALSE(store_.GetString(kGroupA, kKeyString, &value));
819 EXPECT_TRUE(store_.GetString(kGroupC, kKeyString, &value));
820 EXPECT_EQ(kValueStringCNew, value);
821 }
Darin Petkovb2841fd2011-06-30 12:54:12 -0700822 {
823 vector<string> value;
824 EXPECT_TRUE(store_.GetStringList(kGroupB, kKeyStringList, &value));
825 ASSERT_EQ(1, value.size());
826 EXPECT_EQ(kValueStringB, value[0]);
827 EXPECT_FALSE(store_.GetStringList(kGroupA, kKeyStringList, &value));
828 EXPECT_FALSE(store_.GetStringList(kGroupC, kKeyStringList, &value));
829 }
Darin Petkov083047b2011-06-23 20:42:48 -0700830 {
831 int value = 0;
832 EXPECT_TRUE(store_.GetInt(kGroupB, kKeyInt, &value));
833 EXPECT_EQ(kValueIntBNew, value);
834 EXPECT_FALSE(store_.GetInt(kGroupA, kKeyInt, &value));
835 EXPECT_FALSE(store_.GetInt(kGroupC, kKeyInt, &value));
836 }
Darin Petkov083047b2011-06-23 20:42:48 -0700837 {
838 bool value = false;
839 EXPECT_TRUE(store_.GetBool(kGroupB, kKeyBool, &value));
840 EXPECT_FALSE(value);
841 EXPECT_TRUE(store_.GetBool(kGroupC, kKeyBool, &value));
842 EXPECT_FALSE(value);
843 EXPECT_FALSE(store_.GetBool(kGroupA, kKeyBool, &value));
844 }
845
846 ASSERT_TRUE(store_.Close());
Ben Chana0ddf462014-02-06 11:32:42 -0800847 EXPECT_EQ(base::StringPrintf("[%s]\n"
Darin Petkovb2841fd2011-06-30 12:54:12 -0700848 "%s=%s;\n"
Darin Petkov083047b2011-06-23 20:42:48 -0700849 "%s=%d\n"
850 "%s=false\n"
851 "\n"
852 "[%s]\n"
853 "%s=%s\n"
854 "%s=false\n",
855 kGroupB,
Darin Petkovb2841fd2011-06-30 12:54:12 -0700856 kKeyStringList, kValueStringB,
Darin Petkov083047b2011-06-23 20:42:48 -0700857 kKeyInt, kValueIntBNew,
858 kKeyBool,
859 kGroupC,
860 kKeyString, kValueStringCNew,
861 kKeyBool),
862 ReadKeyFile());
863}
864
865} // namespace shill