blob: 598543c6115adfc8fd20851d471ef214764c78b4 [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
Darin Petkov083047b2011-06-23 20:42:48 -07007#include <base/file_util.h>
Paul Stewart5ad16062013-02-21 18:10:48 -08008#include <base/files/scoped_temp_dir.h>
Eric Shienbrood3e20a232012-02-16 11:35:56 -05009#include <base/stl_util.h>
Paul Stewartdab3b5a2012-07-11 18:25:10 -070010#include <base/string_number_conversions.h>
Darin Petkov083047b2011-06-23 20:42:48 -070011#include <base/stringprintf.h>
Darin Petkov083047b2011-06-23 20:42:48 -070012#include <gtest/gtest.h>
13
Paul Stewart5b9ec982013-01-18 14:12:14 -080014#include "shill/key_value_store.h"
15
Albert Chaulk0e1cdea2013-02-27 15:32:55 -080016using base::FilePath;
Gary Morain96970242012-04-20 10:59:58 -070017using file_util::FileEnumerator;
Darin Petkov083047b2011-06-23 20:42:48 -070018using std::set;
19using std::string;
Darin Petkovb2841fd2011-06-30 12:54:12 -070020using std::vector;
Darin Petkov083047b2011-06-23 20:42:48 -070021using testing::Test;
22
Ben Chanc9638612012-09-13 16:20:46 -070023// TODO(benchan): Remove this workaround after finishing glib 2.32 migration.
24#ifdef GLIB_VERSION_2_32
25#define KEY_FILE_EXTRA_NEW_LINE
26#else
27#define KEY_FILE_EXTRA_NEW_LINE "\n"
28#endif
29
Darin Petkov083047b2011-06-23 20:42:48 -070030namespace shill {
31
Darin Petkov86964e02011-06-29 13:49:28 -070032namespace {
33const char kPlainText[] = "This is a test!";
34const char kROT47Text[] = "rot47:%9:D :D 2 E6DEP";
35} // namespace {}
36
Darin Petkov083047b2011-06-23 20:42:48 -070037class KeyFileStoreTest : public Test {
38 public:
39 KeyFileStoreTest() : store_(&glib_) {}
40
41 virtual void SetUp() {
42 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
Chris Masoneb9c00592011-10-06 13:10:39 -070043 test_file_ = temp_dir_.path().Append("test-key-file-store");
44 store_.set_path(test_file_);
Darin Petkov083047b2011-06-23 20:42:48 -070045 }
46
47 virtual void TearDown() {
48 store_.set_path(FilePath("")); // Don't try to save the store.
49 ASSERT_TRUE(temp_dir_.Delete());
50 }
51
52 protected:
53 string ReadKeyFile();
54 void WriteKeyFile(string data);
Chris Masoneb9c00592011-10-06 13:10:39 -070055 bool OpenCheckClose(const string &group,
56 const string &key,
57 const string &expected_value);
Darin Petkov083047b2011-06-23 20:42:48 -070058
59 GLib glib_; // Use real GLib for testing KeyFileStore.
Paul Stewart5ad16062013-02-21 18:10:48 -080060 base::ScopedTempDir temp_dir_;
Chris Masoneb9c00592011-10-06 13:10:39 -070061 FilePath test_file_;
Darin Petkov083047b2011-06-23 20:42:48 -070062 KeyFileStore store_;
63};
64
65string KeyFileStoreTest::ReadKeyFile() {
66 string data;
67 EXPECT_TRUE(file_util::ReadFileToString(store_.path(), &data));
68 return data;
69}
70
71void KeyFileStoreTest::WriteKeyFile(string data) {
72 EXPECT_EQ(data.size(),
73 file_util::WriteFile(store_.path(), data.data(), data.size()));
74}
75
76TEST_F(KeyFileStoreTest, OpenClose) {
77 EXPECT_FALSE(store_.key_file_);
78
Paul Stewart5dc40aa2011-10-28 19:43:43 -070079 EXPECT_FALSE(store_.IsNonEmpty());
Darin Petkov083047b2011-06-23 20:42:48 -070080 ASSERT_TRUE(store_.Open());
81 EXPECT_TRUE(store_.key_file_);
Darin Petkov86964e02011-06-29 13:49:28 -070082 EXPECT_EQ(1, store_.crypto_.cryptos_.size());
Darin Petkov083047b2011-06-23 20:42:48 -070083 ASSERT_TRUE(store_.Close());
84 EXPECT_FALSE(store_.key_file_);
Gary Morain96970242012-04-20 10:59:58 -070085 FileEnumerator file_enumerator(temp_dir_.path(),
86 false /* not recursive */,
87 FileEnumerator::FILES);
88
89 // Verify that the file actually got written with the right name.
90 EXPECT_EQ(test_file_.value(), file_enumerator.Next().value());
91 FileEnumerator::FindInfo find_info;
92 file_enumerator.GetFindInfo(&find_info);
93
94 // Verify that the profile is a regular file, readable and writeable by the
95 // owner only.
96 EXPECT_EQ(S_IFREG | S_IRUSR | S_IWUSR, find_info.stat.st_mode);
Darin Petkov083047b2011-06-23 20:42:48 -070097
98 ASSERT_TRUE(store_.Open());
99 EXPECT_TRUE(store_.key_file_);
100 ASSERT_TRUE(store_.Close());
101 EXPECT_FALSE(store_.key_file_);
102
103 ASSERT_TRUE(store_.Open());
104 store_.set_path(FilePath(""));
105 ASSERT_FALSE(store_.Close());
106 EXPECT_FALSE(store_.key_file_);
107}
108
109TEST_F(KeyFileStoreTest, OpenFail) {
110 WriteKeyFile("garbage\n");
111 EXPECT_FALSE(store_.Open());
112 EXPECT_FALSE(store_.key_file_);
113}
114
Paul Stewart2ebc16d2012-08-23 10:38:39 -0700115TEST_F(KeyFileStoreTest, MarkAsCorrupted) {
116 EXPECT_FALSE(store_.MarkAsCorrupted());
117 EXPECT_FALSE(store_.IsNonEmpty());
118 WriteKeyFile("garbage\n");
119 EXPECT_TRUE(store_.IsNonEmpty());
120 EXPECT_TRUE(file_util::PathExists(store_.path()));
121 EXPECT_TRUE(store_.MarkAsCorrupted());
122 EXPECT_FALSE(store_.IsNonEmpty());
123 EXPECT_FALSE(file_util::PathExists(store_.path()));
124 EXPECT_TRUE(
125 file_util::PathExists(FilePath(store_.path().value() + ".corrupted")));
126}
127
Darin Petkov083047b2011-06-23 20:42:48 -0700128TEST_F(KeyFileStoreTest, GetGroups) {
129 static const char kGroupA[] = "g-a";
130 static const char kGroupB[] = "g-b";
131 static const char kGroupC[] = "g-c";
132 WriteKeyFile(base::StringPrintf("[%s]\n"
133 "[%s]\n"
134 "[%s]\n",
135 kGroupA, kGroupB, kGroupC));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700136 EXPECT_TRUE(store_.IsNonEmpty());
Darin Petkov083047b2011-06-23 20:42:48 -0700137 ASSERT_TRUE(store_.Open());
138 set<string> groups = store_.GetGroups();
139 EXPECT_EQ(3, groups.size());
140 EXPECT_TRUE(ContainsKey(groups, kGroupA));
141 EXPECT_TRUE(ContainsKey(groups, kGroupB));
142 EXPECT_TRUE(ContainsKey(groups, kGroupC));
143 EXPECT_FALSE(ContainsKey(groups, "g-x"));
144 ASSERT_TRUE(store_.Close());
145}
146
Paul Stewarta41e38d2011-11-11 07:47:29 -0800147TEST_F(KeyFileStoreTest, GetGroupsWithKey) {
148 static const char kGroupA[] = "g-a";
149 static const char kGroupB[] = "g-b";
150 static const char kGroupC[] = "g-c";
151 static const char kKeyA[] = "k-a";
152 static const char kKeyB[] = "k-b";
153 static const char kValue[] = "true";
154 WriteKeyFile(base::StringPrintf("[%s]\n"
155 "%s=%s\n"
156 "[%s]\n"
157 "%s=%s\n"
158 "%s=%s\n"
159 "[%s]\n"
160 "%s=%s\n",
161 kGroupA, kKeyA, kValue,
162 kGroupB, kKeyA, kValue, kKeyB, kValue,
163 kGroupC, kKeyB, kValue));
164 EXPECT_TRUE(store_.IsNonEmpty());
165 ASSERT_TRUE(store_.Open());
166 set<string> groups_a = store_.GetGroupsWithKey(kKeyA);
167 EXPECT_EQ(2, groups_a.size());
168 EXPECT_TRUE(ContainsKey(groups_a, kGroupA));
169 EXPECT_TRUE(ContainsKey(groups_a, kGroupB));
170 set<string> groups_b = store_.GetGroupsWithKey(kKeyB);
171 EXPECT_EQ(2, groups_b.size());
172 EXPECT_TRUE(ContainsKey(groups_b, kGroupB));
173 EXPECT_TRUE(ContainsKey(groups_b, kGroupC));
174 ASSERT_TRUE(store_.Close());
175}
176
Darin Petkov083047b2011-06-23 20:42:48 -0700177TEST_F(KeyFileStoreTest, ContainsGroup) {
178 static const char kGroupA[] = "group-a";
179 static const char kGroupB[] = "group-b";
180 static const char kGroupC[] = "group-c";
181 WriteKeyFile(base::StringPrintf("[%s]\n"
182 "[%s]\n"
183 "[%s]\n",
184 kGroupA, kGroupB, kGroupC));
185 ASSERT_TRUE(store_.Open());
186 EXPECT_TRUE(store_.ContainsGroup(kGroupA));
187 EXPECT_TRUE(store_.ContainsGroup(kGroupB));
188 EXPECT_TRUE(store_.ContainsGroup(kGroupC));
189 EXPECT_FALSE(store_.ContainsGroup("group-d"));
190 ASSERT_TRUE(store_.Close());
191}
192
Paul Stewart5b9ec982013-01-18 14:12:14 -0800193TEST_F(KeyFileStoreTest, GetGroupsWithProperties) {
194 static const char kGroupA[] = "group-a";
195 static const char kGroupB[] = "group-b";
196 static const char kGroupC[] = "group-c";
197 static const char kAttributeA[] = "attr-a";
198 static const char kAttributeB[] = "attr-b";
199 static const char kAttributeC[] = "attr-c";
200 static const char kValueA_0[] = "val-a";
201 static const char kValueA_1[] = "val-b";
202 static const int kValueB_0 = 1;
203 static const int kValueB_1 = 2;
204 static const bool kValueC_0 = true;
205 static const char kValueC_0_string[] = "true";
206 static const bool kValueC_1 = false;
207 static const char kValueC_1_string[] = "false";
208 WriteKeyFile(base::StringPrintf("[%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 "[%s]\n"
217 "%s=%s\n"
218 "%s=%d\n"
219 "%s=%s\n",
220 kGroupA,
221 kAttributeA, kValueA_0,
222 kAttributeB, kValueB_0,
223 kAttributeC, kValueC_0_string,
224 kGroupB,
225 kAttributeA, kValueA_0,
226 kAttributeB, kValueB_1,
227 kAttributeC, kValueC_0_string,
228 kGroupC,
229 kAttributeA, kValueA_0,
230 kAttributeB, kValueB_0,
231 kAttributeC, kValueC_1_string));
232 ASSERT_TRUE(store_.Open());
233 {
234 KeyValueStore args;
235 args.SetString(kAttributeA, kValueA_0);
236 args.SetInt(kAttributeB, kValueB_0);
237 set<string> results = store_.GetGroupsWithProperties(args);
238 EXPECT_EQ(2, results.size());
239 EXPECT_TRUE(results.find(kGroupA) != results.end());
240 EXPECT_TRUE(results.find(kGroupC) != results.end());
241 }
242 {
243 KeyValueStore args;
244 args.SetString(kAttributeA, kValueA_0);
245 args.SetBool(kAttributeC, kValueC_0);
246 set<string> results = store_.GetGroupsWithProperties(args);
247 EXPECT_EQ(2, results.size());
248 EXPECT_TRUE(results.find(kGroupA) != results.end());
249 EXPECT_TRUE(results.find(kGroupB) != results.end());
250 }
251 {
252 KeyValueStore args;
253 args.SetBool(kAttributeC, kValueC_1);
254 set<string> results = store_.GetGroupsWithProperties(args);
255 EXPECT_EQ(1, results.size());
256 EXPECT_TRUE(results.find(kGroupC) != results.end());
257 }
258 {
259 KeyValueStore args;
260 args.SetString(kAttributeA, kValueA_0);
261 set<string> results = store_.GetGroupsWithProperties(args);
262 EXPECT_EQ(3, results.size());
263 EXPECT_TRUE(results.find(kGroupA) != results.end());
264 EXPECT_TRUE(results.find(kGroupB) != results.end());
265 EXPECT_TRUE(results.find(kGroupC) != results.end());
266 }
267 {
268 KeyValueStore args;
269 args.SetString(kAttributeA, kValueA_1);
270 set<string> results = store_.GetGroupsWithProperties(args);
271 EXPECT_EQ(0, results.size());
272 }
273 ASSERT_TRUE(store_.Close());
274}
275
Darin Petkov083047b2011-06-23 20:42:48 -0700276TEST_F(KeyFileStoreTest, DeleteKey) {
277 static const char kGroup[] = "the-group";
278 static const char kKeyDead[] = "dead";
279 static const char kKeyAlive[] = "alive";
280 const int kValueAlive = 3;
281 WriteKeyFile(base::StringPrintf("[%s]\n"
282 "%s=5\n"
283 "%s=%d\n",
284 kGroup, kKeyDead, kKeyAlive, kValueAlive));
285 ASSERT_TRUE(store_.Open());
286 EXPECT_TRUE(store_.DeleteKey(kGroup, kKeyDead));
Chris Masone9d779932011-08-25 16:33:41 -0700287 EXPECT_TRUE(store_.DeleteKey(kGroup, "random-key"));
Darin Petkov083047b2011-06-23 20:42:48 -0700288 EXPECT_FALSE(store_.DeleteKey("random-group", kKeyAlive));
289 ASSERT_TRUE(store_.Close());
Ben Chanc9638612012-09-13 16:20:46 -0700290 EXPECT_EQ(base::StringPrintf(KEY_FILE_EXTRA_NEW_LINE
Darin Petkov083047b2011-06-23 20:42:48 -0700291 "[%s]\n"
292 "%s=%d\n",
293 kGroup, kKeyAlive, kValueAlive),
294 ReadKeyFile());
295}
296
297TEST_F(KeyFileStoreTest, DeleteGroup) {
298 static const char kGroupA[] = "group-a";
299 static const char kGroupB[] = "group-b";
300 static const char kGroupC[] = "group-c";
301 WriteKeyFile(base::StringPrintf("[%s]\n"
302 "[%s]\n"
303 "key-to-be-deleted=true\n"
304 "[%s]\n",
305 kGroupA, kGroupB, kGroupC));
306 ASSERT_TRUE(store_.Open());
307 EXPECT_TRUE(store_.DeleteGroup(kGroupB));
Chris Masone9d779932011-08-25 16:33:41 -0700308 EXPECT_TRUE(store_.DeleteGroup("group-d"));
Darin Petkov083047b2011-06-23 20:42:48 -0700309 ASSERT_TRUE(store_.Close());
Ben Chanc9638612012-09-13 16:20:46 -0700310 EXPECT_EQ(base::StringPrintf(KEY_FILE_EXTRA_NEW_LINE
Darin Petkov083047b2011-06-23 20:42:48 -0700311 "[%s]\n"
312 "\n"
313 "[%s]\n",
314 kGroupA, kGroupC),
315 ReadKeyFile());
316}
317
318TEST_F(KeyFileStoreTest, GetString) {
319 static const char kGroup[] = "something";
320 static const char kKey[] = "foo";
321 static const char kValue[] = "bar";
322 WriteKeyFile(base::StringPrintf("[%s]\n"
323 "%s=%s\n",
324 kGroup, kKey, kValue));
325 ASSERT_TRUE(store_.Open());
326 string value;
327 EXPECT_TRUE(store_.GetString(kGroup, kKey, &value));
328 EXPECT_EQ(kValue, value);
329 EXPECT_FALSE(store_.GetString("something-else", kKey, &value));
330 EXPECT_FALSE(store_.GetString(kGroup, "bar", &value));
331 EXPECT_TRUE(store_.GetString(kGroup, kKey, NULL));
332 ASSERT_TRUE(store_.Close());
333}
334
335TEST_F(KeyFileStoreTest, SetString) {
336 static const char kGroup[] = "string-group";
337 static const char kKey1[] = "test-string";
338 static const char kValue1[] = "foo";
339 static const char kKey2[] = "empty-string";
340 static const char kValue2[] = "";
341 ASSERT_TRUE(store_.Open());
342 ASSERT_TRUE(store_.SetString(kGroup, kKey1, kValue1));
343 ASSERT_TRUE(store_.SetString(kGroup, kKey2, kValue2));
344 ASSERT_TRUE(store_.Close());
Ben Chanc9638612012-09-13 16:20:46 -0700345 EXPECT_EQ(base::StringPrintf(KEY_FILE_EXTRA_NEW_LINE
Darin Petkov083047b2011-06-23 20:42:48 -0700346 "[%s]\n"
347 "%s=%s\n"
348 "%s=%s\n",
349 kGroup, kKey1, kValue1, kKey2, kValue2),
350 ReadKeyFile());
351}
352
353TEST_F(KeyFileStoreTest, GetBool) {
354 static const char kGroup[] = "boo";
355 static const char kKeyTrue[] = "foo";
356 static const char kKeyFalse[] = "bar";
357 static const char kKeyBad[] = "zoo";
358 WriteKeyFile(base::StringPrintf("[%s]\n"
359 "%s=true\n"
360 "%s=false\n"
361 "%s=moo\n",
362 kGroup, kKeyTrue, kKeyFalse, kKeyBad));
363 ASSERT_TRUE(store_.Open());
364 {
365 bool value = true;
366 EXPECT_TRUE(store_.GetBool(kGroup, kKeyFalse, &value));
367 EXPECT_FALSE(value);
368 }
369 {
370 bool value = false;
371 EXPECT_TRUE(store_.GetBool(kGroup, kKeyTrue, &value));
372 EXPECT_TRUE(value);
373 }
374 {
375 bool value;
376 EXPECT_FALSE(store_.GetBool(kGroup, kKeyBad, &value));
377 EXPECT_FALSE(store_.GetBool(kGroup, "unknown", &value));
378 EXPECT_FALSE(store_.GetBool("unknown", kKeyTrue, &value));
379 }
380 EXPECT_TRUE(store_.GetBool(kGroup, kKeyFalse, NULL));
381 ASSERT_TRUE(store_.Close());
382}
383
384TEST_F(KeyFileStoreTest, SetBool) {
385 static const char kGroup[] = "bool-group";
386 static const char kKeyTrue[] = "test-true-bool";
387 static const char kKeyFalse[] = "test-false-bool";
388 ASSERT_TRUE(store_.Open());
389 ASSERT_TRUE(store_.SetBool(kGroup, kKeyTrue, true));
390 ASSERT_TRUE(store_.SetBool(kGroup, kKeyFalse, false));
391 ASSERT_TRUE(store_.Close());
Ben Chanc9638612012-09-13 16:20:46 -0700392 EXPECT_EQ(base::StringPrintf(KEY_FILE_EXTRA_NEW_LINE
Darin Petkov083047b2011-06-23 20:42:48 -0700393 "[%s]\n"
394 "%s=true\n"
395 "%s=false\n",
396 kGroup, kKeyTrue, kKeyFalse),
397 ReadKeyFile());
398}
399
400TEST_F(KeyFileStoreTest, GetInt) {
401 static const char kGroup[] = "numbers";
402 static const char kKeyPos[] = "pos";
403 static const char kKeyNeg[] = "neg";
404 static const char kKeyBad[] = "bad";
405 const int kValuePos = 50;
406 const int kValueNeg = -20;
407 static const char kValueBad[] = "nan";
408 WriteKeyFile(base::StringPrintf("[%s]\n"
409 "%s=%d\n"
410 "%s=%d\n"
411 "%s=%s\n",
412 kGroup,
413 kKeyPos, kValuePos,
414 kKeyNeg, kValueNeg,
415 kKeyBad, kValueBad));
416 ASSERT_TRUE(store_.Open());
417 {
418 int value = 0;
419 EXPECT_TRUE(store_.GetInt(kGroup, kKeyNeg, &value));
420 EXPECT_EQ(kValueNeg, value);
421 }
422 {
423 int value = 0;
424 EXPECT_TRUE(store_.GetInt(kGroup, kKeyPos, &value));
425 EXPECT_EQ(kValuePos, value);
426 }
427 {
428 int value;
429 EXPECT_FALSE(store_.GetInt(kGroup, kKeyBad, &value));
430 EXPECT_FALSE(store_.GetInt(kGroup, "invalid", &value));
431 EXPECT_FALSE(store_.GetInt("invalid", kKeyPos, &value));
432 }
433 EXPECT_TRUE(store_.GetInt(kGroup, kKeyPos, NULL));
434 ASSERT_TRUE(store_.Close());
435}
436
437TEST_F(KeyFileStoreTest, SetInt) {
438 static const char kGroup[] = "int-group";
439 static const char kKey1[] = "test-int";
440 static const char kKey2[] = "test-negative";
441 const int kValue1 = 5;
442 const int kValue2 = -10;
443 ASSERT_TRUE(store_.Open());
444 ASSERT_TRUE(store_.SetInt(kGroup, kKey1, kValue1));
445 ASSERT_TRUE(store_.SetInt(kGroup, kKey2, kValue2));
446 ASSERT_TRUE(store_.Close());
Ben Chanc9638612012-09-13 16:20:46 -0700447 EXPECT_EQ(base::StringPrintf(KEY_FILE_EXTRA_NEW_LINE
Darin Petkov083047b2011-06-23 20:42:48 -0700448 "[%s]\n"
449 "%s=%d\n"
450 "%s=%d\n",
451 kGroup, kKey1, kValue1, kKey2, kValue2),
452 ReadKeyFile());
453}
454
Paul Stewartdab3b5a2012-07-11 18:25:10 -0700455TEST_F(KeyFileStoreTest, GetUint64) {
456 static const char kGroup[] = "numbers";
457 static const char kKeyGood[] = "good";
458 static const char kKeyBad[] = "bad";
459 const uint64 kValueGood = 0xFEDCBA9876543210LL;
460 static const char kValueBad[] = "nan";
461 // Use base::Uint64ToString() instead of using something like "%llu"
462 // (not correct for native 64 bit architectures) or PRIu64 (does not
463 // work correctly using cros_workon_make due to include intricacies).
464 WriteKeyFile(base::StringPrintf("[%s]\n"
465 "%s=%s\n"
466 "%s=%s\n",
467 kGroup,
468 kKeyGood,
469 base::Uint64ToString(kValueGood).c_str(),
470 kKeyBad, kValueBad));
471 ASSERT_TRUE(store_.Open());
472 {
473 uint64 value = 0;
474 EXPECT_TRUE(store_.GetUint64(kGroup, kKeyGood, &value));
475 EXPECT_EQ(kValueGood, value);
476 }
477 {
478 uint64 value;
479 EXPECT_FALSE(store_.GetUint64(kGroup, kKeyBad, &value));
480 EXPECT_FALSE(store_.GetUint64(kGroup, "invalid", &value));
481 EXPECT_FALSE(store_.GetUint64("invalid", kKeyGood, &value));
482 }
483 EXPECT_TRUE(store_.GetUint64(kGroup, kKeyGood, NULL));
484 ASSERT_TRUE(store_.Close());
485}
486
487TEST_F(KeyFileStoreTest, SetUint64) {
488 static const char kGroup[] = "int-group";
489 static const char kKey[] = "test-int";
490 const uint64 kValue = 0xFEDCBA9876543210LL;
491 ASSERT_TRUE(store_.Open());
492 ASSERT_TRUE(store_.SetUint64(kGroup, kKey, kValue));
493 ASSERT_TRUE(store_.Close());
Ben Chanc9638612012-09-13 16:20:46 -0700494 EXPECT_EQ(base::StringPrintf(KEY_FILE_EXTRA_NEW_LINE
Paul Stewartdab3b5a2012-07-11 18:25:10 -0700495 "[%s]\n"
496 "%s=%s\n",
497 kGroup, kKey,
498 base::Uint64ToString(kValue).c_str()),
499 ReadKeyFile());
500}
501
Darin Petkovb2841fd2011-06-30 12:54:12 -0700502TEST_F(KeyFileStoreTest, GetStringList) {
503 static const char kGroup[] = "string-lists";
504 static const char kKeyEmpty[] = "empty";
505 static const char kKeyEmptyValue[] = "empty-value";
506 static const char kKeyValueEmpty[] = "value-empty";
507 static const char kKeyValueEmptyValue[] = "value-empty-value";
508 static const char kKeyValues[] = "values";
509 static const char kValue[] = "value";
510 static const char kValue2[] = "value2";
511 static const char kValue3[] = "value3";
512 WriteKeyFile(base::StringPrintf("[%s]\n"
513 "%s=\n"
514 "%s=;%s\n"
515 "%s=%s;;\n"
516 "%s=%s;;%s\n"
517 "%s=%s;%s;%s\n",
518 kGroup,
519 kKeyEmpty,
520 kKeyEmptyValue, kValue,
521 kKeyValueEmpty, kValue,
522 kKeyValueEmptyValue, kValue, kValue2,
523 kKeyValues, kValue, kValue2, kValue3));
524 ASSERT_TRUE(store_.Open());
525
526 vector<string> value;
527
528 EXPECT_TRUE(store_.GetStringList(kGroup, kKeyValues, &value));
529 ASSERT_EQ(3, value.size());
530 EXPECT_EQ(kValue, value[0]);
531 EXPECT_EQ(kValue2, value[1]);
532 EXPECT_EQ(kValue3, value[2]);
533
534 EXPECT_TRUE(store_.GetStringList(kGroup, kKeyEmptyValue, &value));
535 ASSERT_EQ(2, value.size());
536 EXPECT_EQ("", value[0]);
537 EXPECT_EQ(kValue, value[1]);
538
539 EXPECT_TRUE(store_.GetStringList(kGroup, kKeyValueEmpty, &value));
540 ASSERT_EQ(2, value.size());
541 EXPECT_EQ(kValue, value[0]);
542 EXPECT_EQ("", value[1]);
543
544 EXPECT_TRUE(store_.GetStringList(kGroup, kKeyEmpty, &value));
545 ASSERT_EQ(0, value.size());
546
547 EXPECT_TRUE(store_.GetStringList(kGroup, kKeyValueEmptyValue, &value));
548 ASSERT_EQ(3, value.size());
549 EXPECT_EQ(kValue, value[0]);
550 EXPECT_EQ("", value[1]);
551 EXPECT_EQ(kValue2, value[2]);
552
553 EXPECT_FALSE(store_.GetStringList("unknown-string-lists", kKeyEmpty, &value));
554 EXPECT_FALSE(store_.GetStringList(kGroup, "some-key", &value));
555 EXPECT_TRUE(store_.GetStringList(kGroup, kKeyValues, NULL));
556 ASSERT_TRUE(store_.Close());
557}
558
559TEST_F(KeyFileStoreTest, SetStringList) {
560 static const char kGroup[] = "strings";
561 static const char kKeyEmpty[] = "e";
562 static const char kKeyEmptyValue[] = "ev";
563 static const char kKeyValueEmpty[] = "ve";
564 static const char kKeyValueEmptyValue[] = "vev";
565 static const char kKeyValues[] = "v";
566 static const char kValue[] = "abc";
567 static const char kValue2[] = "pqr";
568 static const char kValue3[] = "xyz";
569 ASSERT_TRUE(store_.Open());
570 {
571 vector<string> value;
572 ASSERT_TRUE(store_.SetStringList(kGroup, kKeyEmpty, value));
573 }
574 {
575 vector<string> value;
576 value.push_back("");
577 value.push_back(kValue);
578 ASSERT_TRUE(store_.SetStringList(kGroup, kKeyEmptyValue, value));
579 }
580 {
581 vector<string> value;
582 value.push_back(kValue);
583 value.push_back("");
584 ASSERT_TRUE(store_.SetStringList(kGroup, kKeyValueEmpty, value));
585 }
586 {
587 vector<string> value;
588 value.push_back(kValue);
589 value.push_back("");
590 value.push_back(kValue2);
591 ASSERT_TRUE(store_.SetStringList(kGroup, kKeyValueEmptyValue, value));
592 }
593 {
594 vector<string> value;
595 value.push_back(kValue);
596 value.push_back(kValue2);
597 value.push_back(kValue3);
598 ASSERT_TRUE(store_.SetStringList(kGroup, kKeyValues, value));
599 }
600 ASSERT_TRUE(store_.Close());
Ben Chanc9638612012-09-13 16:20:46 -0700601 EXPECT_EQ(base::StringPrintf(KEY_FILE_EXTRA_NEW_LINE
Darin Petkovb2841fd2011-06-30 12:54:12 -0700602 "[%s]\n"
603 "%s=\n"
604 "%s=;%s;\n"
605 "%s=%s;;\n"
606 "%s=%s;;%s;\n"
607 "%s=%s;%s;%s;\n",
608 kGroup,
609 kKeyEmpty,
610 kKeyEmptyValue, kValue,
611 kKeyValueEmpty, kValue,
612 kKeyValueEmptyValue, kValue, kValue2,
613 kKeyValues, kValue, kValue2, kValue3),
614 ReadKeyFile());
615}
616
Darin Petkov86964e02011-06-29 13:49:28 -0700617TEST_F(KeyFileStoreTest, GetCryptedString) {
618 static const char kGroup[] = "crypto-group";
619 static const char kKey[] = "secret";
620 WriteKeyFile(base::StringPrintf("[%s]\n"
621 "%s=%s\n",
622 kGroup, kKey, kROT47Text));
623 ASSERT_TRUE(store_.Open());
624 string value;
625 EXPECT_TRUE(store_.GetCryptedString(kGroup, kKey, &value));
626 EXPECT_EQ(kPlainText, value);
627 EXPECT_FALSE(store_.GetCryptedString("something-else", kKey, &value));
628 EXPECT_FALSE(store_.GetCryptedString(kGroup, "non-secret", &value));
629 EXPECT_TRUE(store_.GetCryptedString(kGroup, kKey, NULL));
630 ASSERT_TRUE(store_.Close());
631}
632
633TEST_F(KeyFileStoreTest, SetCryptedString) {
634 static const char kGroup[] = "crypted-string-group";
635 static const char kKey[] = "test-string";
636 ASSERT_TRUE(store_.Open());
637 ASSERT_TRUE(store_.SetCryptedString(kGroup, kKey, kPlainText));
638 ASSERT_TRUE(store_.Close());
Ben Chanc9638612012-09-13 16:20:46 -0700639 EXPECT_EQ(base::StringPrintf(KEY_FILE_EXTRA_NEW_LINE
Darin Petkov86964e02011-06-29 13:49:28 -0700640 "[%s]\n"
641 "%s=%s\n",
642 kGroup, kKey, kROT47Text),
643 ReadKeyFile());
644}
645
Chris Masoneb9c00592011-10-06 13:10:39 -0700646TEST_F(KeyFileStoreTest, PersistAcrossClose) {
647 static const char kGroup[] = "string-group";
648 static const char kKey1[] = "test-string";
649 static const char kValue1[] = "foo";
650 static const char kKey2[] = "empty-string";
651 static const char kValue2[] = "";
652 ASSERT_TRUE(store_.Open());
653 ASSERT_TRUE(store_.SetString(kGroup, kKey1, kValue1));
654 ASSERT_TRUE(store_.Close());
655 ASSERT_TRUE(store_.Open());
656 ASSERT_TRUE(store_.SetString(kGroup, kKey2, kValue2));
657 string value;
658 ASSERT_TRUE(store_.GetString(kGroup, kKey1, &value));
659 ASSERT_EQ(kValue1, value);
660 ASSERT_TRUE(store_.GetString(kGroup, kKey2, &value));
661 ASSERT_EQ(kValue2, value);
662 ASSERT_TRUE(store_.Close());
663}
664
665bool KeyFileStoreTest::OpenCheckClose(const string &group,
666 const string &key,
667 const string &expected_value) {
668 KeyFileStore store(&glib_);
669 store.set_path(test_file_);
670 EXPECT_TRUE(store.Open());
671 string value;
672 bool could_get = store.GetString(group, key, &value);
673 store.set_path(FilePath("")); // Don't persist to disk.
674 store.Close();
675 return could_get && expected_value == value;
676}
677
678TEST_F(KeyFileStoreTest, Flush) {
679 static const char kGroup[] = "string-group";
680 static const char kKey1[] = "test-string";
681 static const char kValue1[] = "foo";
682 static const char kKey2[] = "empty-string";
683 static const char kValue2[] = "";
684 ASSERT_TRUE(store_.Open());
685 ASSERT_TRUE(store_.SetString(kGroup, kKey1, kValue1));
686 ASSERT_TRUE(store_.Flush());
687 ASSERT_TRUE(OpenCheckClose(kGroup, kKey1, kValue1));
688
689 ASSERT_TRUE(store_.SetString(kGroup, kKey2, kValue2));
690 ASSERT_TRUE(store_.Flush());
691 ASSERT_TRUE(OpenCheckClose(kGroup, kKey2, kValue2));
692
693 EXPECT_TRUE(store_.DeleteKey(kGroup, kKey1));
694 ASSERT_TRUE(store_.Flush());
695 ASSERT_FALSE(OpenCheckClose(kGroup, kKey1, kValue1));
696}
697
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700698TEST_F(KeyFileStoreTest, EmptyFile) {
699 ASSERT_TRUE(store_.Open());
700 ASSERT_TRUE(store_.Close());
701 EXPECT_FALSE(store_.IsNonEmpty());
702}
703
704TEST_F(KeyFileStoreTest, SetHeader) {
705 ASSERT_TRUE(store_.Open());
706 ASSERT_TRUE(store_.SetHeader("this is a test"));
707 ASSERT_TRUE(store_.Close());
708 EXPECT_TRUE(store_.IsNonEmpty());
709 ASSERT_TRUE(store_.Open());
710}
711
Darin Petkov083047b2011-06-23 20:42:48 -0700712TEST_F(KeyFileStoreTest, Combo) {
713 static const char kGroupA[] = "square";
714 static const char kGroupB[] = "circle";
715 static const char kGroupC[] = "triangle";
716 static const char kGroupX[] = "pentagon";
717 static const char kKeyString[] = "color";
Darin Petkovb2841fd2011-06-30 12:54:12 -0700718 static const char kKeyStringList[] = "alternative-colors";
Darin Petkov083047b2011-06-23 20:42:48 -0700719 static const char kKeyInt[] = "area";
720 static const char kKeyBool[] = "visible";
721 static const char kValueStringA[] = "blue";
722 static const char kValueStringB[] = "red";
723 static const char kValueStringC[] = "yellow";
724 static const char kValueStringCNew[] = "purple";
725 const int kValueIntA = 5;
726 const int kValueIntB = 10;
727 const int kValueIntBNew = 333;
728 WriteKeyFile(base::StringPrintf("[%s]\n"
729 "%s=%s\n"
Darin Petkovb2841fd2011-06-30 12:54:12 -0700730 "%s=%s;%s\n"
Darin Petkov083047b2011-06-23 20:42:48 -0700731 "%s=%d\n"
732 "[%s]\n"
733 "%s=%s\n"
Darin Petkovb2841fd2011-06-30 12:54:12 -0700734 "%s=%s;%s\n"
Darin Petkov083047b2011-06-23 20:42:48 -0700735 "%s=%d\n"
736 "%s=true\n"
737 "[%s]\n"
738 "%s=%s\n"
739 "%s=false\n",
740 kGroupA,
741 kKeyString, kValueStringA,
Darin Petkovb2841fd2011-06-30 12:54:12 -0700742 kKeyStringList, kValueStringB, kValueStringC,
Darin Petkov083047b2011-06-23 20:42:48 -0700743 kKeyInt, kValueIntA,
744 kGroupB,
745 kKeyString, kValueStringB,
Darin Petkovb2841fd2011-06-30 12:54:12 -0700746 kKeyStringList, kValueStringA, kValueStringC,
Darin Petkov083047b2011-06-23 20:42:48 -0700747 kKeyInt, kValueIntB,
748 kKeyBool,
749 kGroupC,
750 kKeyString, kValueStringC,
751 kKeyBool));
752 ASSERT_TRUE(store_.Open());
753
754 EXPECT_TRUE(store_.ContainsGroup(kGroupA));
755 EXPECT_TRUE(store_.ContainsGroup(kGroupB));
756 EXPECT_TRUE(store_.ContainsGroup(kGroupC));
757 EXPECT_FALSE(store_.ContainsGroup(kGroupX));
758
759 set<string> groups = store_.GetGroups();
760 EXPECT_EQ(3, groups.size());
761 EXPECT_TRUE(ContainsKey(groups, kGroupA));
762 EXPECT_TRUE(ContainsKey(groups, kGroupB));
763 EXPECT_TRUE(ContainsKey(groups, kGroupC));
764 EXPECT_FALSE(ContainsKey(groups, kGroupX));
765
766 {
767 string value;
768 EXPECT_TRUE(store_.GetString(kGroupB, kKeyString, &value));
769 EXPECT_EQ(kValueStringB, value);
770 EXPECT_TRUE(store_.GetString(kGroupA, kKeyString, &value));
771 EXPECT_EQ(kValueStringA, value);
772 EXPECT_TRUE(store_.GetString(kGroupC, kKeyString, &value));
773 EXPECT_EQ(kValueStringC, value);
774 }
775 {
Darin Petkovb2841fd2011-06-30 12:54:12 -0700776 vector<string> value;
777 EXPECT_TRUE(store_.GetStringList(kGroupB, kKeyStringList, &value));
778 ASSERT_EQ(2, value.size());
779 EXPECT_EQ(kValueStringA, value[0]);
780 EXPECT_EQ(kValueStringC, value[1]);
781 EXPECT_TRUE(store_.GetStringList(kGroupA, kKeyStringList, &value));
782 ASSERT_EQ(2, value.size());
783 EXPECT_EQ(kValueStringB, value[0]);
784 EXPECT_EQ(kValueStringC, value[1]);
785 EXPECT_FALSE(store_.GetStringList(kGroupC, kKeyStringList, &value));
786 }
787 {
Darin Petkov083047b2011-06-23 20:42:48 -0700788 int value = 0;
789 EXPECT_TRUE(store_.GetInt(kGroupB, kKeyInt, &value));
790 EXPECT_EQ(kValueIntB, value);
791 EXPECT_TRUE(store_.GetInt(kGroupA, kKeyInt, &value));
792 EXPECT_EQ(kValueIntA, value);
793 EXPECT_FALSE(store_.GetInt(kGroupC, kKeyInt, &value));
794 }
795 {
796 bool value = false;
797 EXPECT_TRUE(store_.GetBool(kGroupB, kKeyBool, &value));
798 EXPECT_TRUE(value);
799 EXPECT_TRUE(store_.GetBool(kGroupC, kKeyBool, &value));
800 EXPECT_FALSE(value);
801 EXPECT_FALSE(store_.GetBool(kGroupA, kKeyBool, &value));
802 }
803
804 EXPECT_TRUE(store_.DeleteGroup(kGroupA));
Chris Masone9d779932011-08-25 16:33:41 -0700805 EXPECT_TRUE(store_.DeleteGroup(kGroupA));
Darin Petkov083047b2011-06-23 20:42:48 -0700806
807 EXPECT_FALSE(store_.ContainsGroup(kGroupA));
808 EXPECT_TRUE(store_.ContainsGroup(kGroupB));
809 EXPECT_TRUE(store_.ContainsGroup(kGroupC));
810
811 groups = store_.GetGroups();
812 EXPECT_EQ(2, groups.size());
813 EXPECT_FALSE(ContainsKey(groups, kGroupA));
814 EXPECT_TRUE(ContainsKey(groups, kGroupB));
815 EXPECT_TRUE(ContainsKey(groups, kGroupC));
816
817 EXPECT_TRUE(store_.SetBool(kGroupB, kKeyBool, false));
818 EXPECT_TRUE(store_.SetInt(kGroupB, kKeyInt, kValueIntBNew));
819 EXPECT_TRUE(store_.SetString(kGroupC, kKeyString, kValueStringCNew));
Darin Petkovb2841fd2011-06-30 12:54:12 -0700820 store_.SetStringList(kGroupB,
821 kKeyStringList,
822 vector<string>(1, kValueStringB));
Darin Petkov083047b2011-06-23 20:42:48 -0700823
824 EXPECT_TRUE(store_.DeleteKey(kGroupB, kKeyString));
Chris Masone9d779932011-08-25 16:33:41 -0700825 EXPECT_TRUE(store_.DeleteKey(kGroupB, kKeyString));
Darin Petkov083047b2011-06-23 20:42:48 -0700826
827 {
828 string value;
829 EXPECT_FALSE(store_.GetString(kGroupB, kKeyString, &value));
830 EXPECT_FALSE(store_.GetString(kGroupA, kKeyString, &value));
831 EXPECT_TRUE(store_.GetString(kGroupC, kKeyString, &value));
832 EXPECT_EQ(kValueStringCNew, value);
833 }
Darin Petkovb2841fd2011-06-30 12:54:12 -0700834 {
835 vector<string> value;
836 EXPECT_TRUE(store_.GetStringList(kGroupB, kKeyStringList, &value));
837 ASSERT_EQ(1, value.size());
838 EXPECT_EQ(kValueStringB, value[0]);
839 EXPECT_FALSE(store_.GetStringList(kGroupA, kKeyStringList, &value));
840 EXPECT_FALSE(store_.GetStringList(kGroupC, kKeyStringList, &value));
841 }
Darin Petkov083047b2011-06-23 20:42:48 -0700842 {
843 int value = 0;
844 EXPECT_TRUE(store_.GetInt(kGroupB, kKeyInt, &value));
845 EXPECT_EQ(kValueIntBNew, value);
846 EXPECT_FALSE(store_.GetInt(kGroupA, kKeyInt, &value));
847 EXPECT_FALSE(store_.GetInt(kGroupC, kKeyInt, &value));
848 }
Darin Petkov083047b2011-06-23 20:42:48 -0700849 {
850 bool value = false;
851 EXPECT_TRUE(store_.GetBool(kGroupB, kKeyBool, &value));
852 EXPECT_FALSE(value);
853 EXPECT_TRUE(store_.GetBool(kGroupC, kKeyBool, &value));
854 EXPECT_FALSE(value);
855 EXPECT_FALSE(store_.GetBool(kGroupA, kKeyBool, &value));
856 }
857
858 ASSERT_TRUE(store_.Close());
Ben Chanc9638612012-09-13 16:20:46 -0700859 EXPECT_EQ(base::StringPrintf(KEY_FILE_EXTRA_NEW_LINE
Darin Petkov083047b2011-06-23 20:42:48 -0700860 "[%s]\n"
Darin Petkovb2841fd2011-06-30 12:54:12 -0700861 "%s=%s;\n"
Darin Petkov083047b2011-06-23 20:42:48 -0700862 "%s=%d\n"
863 "%s=false\n"
864 "\n"
865 "[%s]\n"
866 "%s=%s\n"
867 "%s=false\n",
868 kGroupB,
Darin Petkovb2841fd2011-06-30 12:54:12 -0700869 kKeyStringList, kValueStringB,
Darin Petkov083047b2011-06-23 20:42:48 -0700870 kKeyInt, kValueIntBNew,
871 kKeyBool,
872 kGroupC,
873 kKeyString, kValueStringCNew,
874 kKeyBool),
875 ReadKeyFile());
876}
877
878} // namespace shill