blob: adbe60366f7c568d79ad0240001016d5b87f42d4 [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>
Ben Chana0ddf462014-02-06 11:32:42 -08008#include <base/files/file_enumerator.h>
Paul Stewart5ad16062013-02-21 18:10:48 -08009#include <base/files/scoped_temp_dir.h>
Eric Shienbrood3e20a232012-02-16 11:35:56 -050010#include <base/stl_util.h>
Ben Chana0ddf462014-02-06 11:32:42 -080011#include <base/strings/string_number_conversions.h>
12#include <base/strings/stringprintf.h>
Darin Petkov083047b2011-06-23 20:42:48 -070013#include <gtest/gtest.h>
14
Paul Stewart5b9ec982013-01-18 14:12:14 -080015#include "shill/key_value_store.h"
16
Ben Chana0ddf462014-02-06 11:32:42 -080017using base::FileEnumerator;
Albert Chaulk0e1cdea2013-02-27 15:32:55 -080018using base::FilePath;
Darin Petkov083047b2011-06-23 20:42:48 -070019using std::set;
20using std::string;
Darin Petkovb2841fd2011-06-30 12:54:12 -070021using std::vector;
Darin Petkov083047b2011-06-23 20:42:48 -070022using testing::Test;
23
24namespace shill {
25
Darin Petkov86964e02011-06-29 13:49:28 -070026namespace {
27const char kPlainText[] = "This is a test!";
28const char kROT47Text[] = "rot47:%9:D :D 2 E6DEP";
29} // namespace {}
30
Darin Petkov083047b2011-06-23 20:42:48 -070031class KeyFileStoreTest : public Test {
32 public:
33 KeyFileStoreTest() : store_(&glib_) {}
34
35 virtual void SetUp() {
36 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
Chris Masoneb9c00592011-10-06 13:10:39 -070037 test_file_ = temp_dir_.path().Append("test-key-file-store");
38 store_.set_path(test_file_);
Darin Petkov083047b2011-06-23 20:42:48 -070039 }
40
41 virtual void TearDown() {
42 store_.set_path(FilePath("")); // Don't try to save the store.
43 ASSERT_TRUE(temp_dir_.Delete());
44 }
45
46 protected:
47 string ReadKeyFile();
48 void WriteKeyFile(string data);
Chris Masoneb9c00592011-10-06 13:10:39 -070049 bool OpenCheckClose(const string &group,
50 const string &key,
51 const string &expected_value);
Darin Petkov083047b2011-06-23 20:42:48 -070052
53 GLib glib_; // Use real GLib for testing KeyFileStore.
Paul Stewart5ad16062013-02-21 18:10:48 -080054 base::ScopedTempDir temp_dir_;
Chris Masoneb9c00592011-10-06 13:10:39 -070055 FilePath test_file_;
Darin Petkov083047b2011-06-23 20:42:48 -070056 KeyFileStore store_;
57};
58
59string KeyFileStoreTest::ReadKeyFile() {
60 string data;
Ben Chana0ddf462014-02-06 11:32:42 -080061 EXPECT_TRUE(base::ReadFileToString(store_.path(), &data));
Darin Petkov083047b2011-06-23 20:42:48 -070062 return data;
63}
64
65void KeyFileStoreTest::WriteKeyFile(string data) {
66 EXPECT_EQ(data.size(),
67 file_util::WriteFile(store_.path(), data.data(), data.size()));
68}
69
70TEST_F(KeyFileStoreTest, OpenClose) {
71 EXPECT_FALSE(store_.key_file_);
72
Paul Stewart5dc40aa2011-10-28 19:43:43 -070073 EXPECT_FALSE(store_.IsNonEmpty());
Darin Petkov083047b2011-06-23 20:42:48 -070074 ASSERT_TRUE(store_.Open());
75 EXPECT_TRUE(store_.key_file_);
Darin Petkov86964e02011-06-29 13:49:28 -070076 EXPECT_EQ(1, store_.crypto_.cryptos_.size());
Darin Petkov083047b2011-06-23 20:42:48 -070077 ASSERT_TRUE(store_.Close());
78 EXPECT_FALSE(store_.key_file_);
Gary Morain96970242012-04-20 10:59:58 -070079 FileEnumerator file_enumerator(temp_dir_.path(),
80 false /* not recursive */,
81 FileEnumerator::FILES);
82
83 // Verify that the file actually got written with the right name.
84 EXPECT_EQ(test_file_.value(), file_enumerator.Next().value());
Ben Chana0ddf462014-02-06 11:32:42 -080085 FileEnumerator::FileInfo file_info = file_enumerator.GetInfo();
Gary Morain96970242012-04-20 10:59:58 -070086
87 // Verify that the profile is a regular file, readable and writeable by the
88 // owner only.
Ben Chana0ddf462014-02-06 11:32:42 -080089 EXPECT_EQ(S_IFREG | S_IRUSR | S_IWUSR, file_info.stat().st_mode);
Darin Petkov083047b2011-06-23 20:42:48 -070090
91 ASSERT_TRUE(store_.Open());
92 EXPECT_TRUE(store_.key_file_);
93 ASSERT_TRUE(store_.Close());
94 EXPECT_FALSE(store_.key_file_);
95
96 ASSERT_TRUE(store_.Open());
97 store_.set_path(FilePath(""));
98 ASSERT_FALSE(store_.Close());
99 EXPECT_FALSE(store_.key_file_);
100}
101
102TEST_F(KeyFileStoreTest, OpenFail) {
103 WriteKeyFile("garbage\n");
104 EXPECT_FALSE(store_.Open());
105 EXPECT_FALSE(store_.key_file_);
106}
107
Paul Stewart2ebc16d2012-08-23 10:38:39 -0700108TEST_F(KeyFileStoreTest, MarkAsCorrupted) {
109 EXPECT_FALSE(store_.MarkAsCorrupted());
110 EXPECT_FALSE(store_.IsNonEmpty());
111 WriteKeyFile("garbage\n");
112 EXPECT_TRUE(store_.IsNonEmpty());
Ben Chana0ddf462014-02-06 11:32:42 -0800113 EXPECT_TRUE(base::PathExists(store_.path()));
Paul Stewart2ebc16d2012-08-23 10:38:39 -0700114 EXPECT_TRUE(store_.MarkAsCorrupted());
115 EXPECT_FALSE(store_.IsNonEmpty());
Ben Chana0ddf462014-02-06 11:32:42 -0800116 EXPECT_FALSE(base::PathExists(store_.path()));
117 EXPECT_TRUE(base::PathExists(FilePath(store_.path().value() + ".corrupted")));
Paul Stewart2ebc16d2012-08-23 10:38:39 -0700118}
119
Darin Petkov083047b2011-06-23 20:42:48 -0700120TEST_F(KeyFileStoreTest, GetGroups) {
121 static const char kGroupA[] = "g-a";
122 static const char kGroupB[] = "g-b";
123 static const char kGroupC[] = "g-c";
124 WriteKeyFile(base::StringPrintf("[%s]\n"
125 "[%s]\n"
126 "[%s]\n",
127 kGroupA, kGroupB, kGroupC));
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700128 EXPECT_TRUE(store_.IsNonEmpty());
Darin Petkov083047b2011-06-23 20:42:48 -0700129 ASSERT_TRUE(store_.Open());
130 set<string> groups = store_.GetGroups();
131 EXPECT_EQ(3, groups.size());
132 EXPECT_TRUE(ContainsKey(groups, kGroupA));
133 EXPECT_TRUE(ContainsKey(groups, kGroupB));
134 EXPECT_TRUE(ContainsKey(groups, kGroupC));
135 EXPECT_FALSE(ContainsKey(groups, "g-x"));
136 ASSERT_TRUE(store_.Close());
137}
138
Paul Stewarta41e38d2011-11-11 07:47:29 -0800139TEST_F(KeyFileStoreTest, GetGroupsWithKey) {
140 static const char kGroupA[] = "g-a";
141 static const char kGroupB[] = "g-b";
142 static const char kGroupC[] = "g-c";
143 static const char kKeyA[] = "k-a";
144 static const char kKeyB[] = "k-b";
145 static const char kValue[] = "true";
146 WriteKeyFile(base::StringPrintf("[%s]\n"
147 "%s=%s\n"
148 "[%s]\n"
149 "%s=%s\n"
150 "%s=%s\n"
151 "[%s]\n"
152 "%s=%s\n",
153 kGroupA, kKeyA, kValue,
154 kGroupB, kKeyA, kValue, kKeyB, kValue,
155 kGroupC, kKeyB, kValue));
156 EXPECT_TRUE(store_.IsNonEmpty());
157 ASSERT_TRUE(store_.Open());
158 set<string> groups_a = store_.GetGroupsWithKey(kKeyA);
159 EXPECT_EQ(2, groups_a.size());
160 EXPECT_TRUE(ContainsKey(groups_a, kGroupA));
161 EXPECT_TRUE(ContainsKey(groups_a, kGroupB));
162 set<string> groups_b = store_.GetGroupsWithKey(kKeyB);
163 EXPECT_EQ(2, groups_b.size());
164 EXPECT_TRUE(ContainsKey(groups_b, kGroupB));
165 EXPECT_TRUE(ContainsKey(groups_b, kGroupC));
166 ASSERT_TRUE(store_.Close());
167}
168
Darin Petkov083047b2011-06-23 20:42:48 -0700169TEST_F(KeyFileStoreTest, ContainsGroup) {
170 static const char kGroupA[] = "group-a";
171 static const char kGroupB[] = "group-b";
172 static const char kGroupC[] = "group-c";
173 WriteKeyFile(base::StringPrintf("[%s]\n"
174 "[%s]\n"
175 "[%s]\n",
176 kGroupA, kGroupB, kGroupC));
177 ASSERT_TRUE(store_.Open());
178 EXPECT_TRUE(store_.ContainsGroup(kGroupA));
179 EXPECT_TRUE(store_.ContainsGroup(kGroupB));
180 EXPECT_TRUE(store_.ContainsGroup(kGroupC));
181 EXPECT_FALSE(store_.ContainsGroup("group-d"));
182 ASSERT_TRUE(store_.Close());
183}
184
Paul Stewart5b9ec982013-01-18 14:12:14 -0800185TEST_F(KeyFileStoreTest, GetGroupsWithProperties) {
186 static const char kGroupA[] = "group-a";
187 static const char kGroupB[] = "group-b";
188 static const char kGroupC[] = "group-c";
189 static const char kAttributeA[] = "attr-a";
190 static const char kAttributeB[] = "attr-b";
191 static const char kAttributeC[] = "attr-c";
192 static const char kValueA_0[] = "val-a";
193 static const char kValueA_1[] = "val-b";
194 static const int kValueB_0 = 1;
195 static const int kValueB_1 = 2;
196 static const bool kValueC_0 = true;
197 static const char kValueC_0_string[] = "true";
198 static const bool kValueC_1 = false;
199 static const char kValueC_1_string[] = "false";
200 WriteKeyFile(base::StringPrintf("[%s]\n"
201 "%s=%s\n"
202 "%s=%d\n"
203 "%s=%s\n"
204 "[%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 kGroupA,
213 kAttributeA, kValueA_0,
214 kAttributeB, kValueB_0,
215 kAttributeC, kValueC_0_string,
216 kGroupB,
217 kAttributeA, kValueA_0,
218 kAttributeB, kValueB_1,
219 kAttributeC, kValueC_0_string,
220 kGroupC,
221 kAttributeA, kValueA_0,
222 kAttributeB, kValueB_0,
223 kAttributeC, kValueC_1_string));
224 ASSERT_TRUE(store_.Open());
225 {
226 KeyValueStore args;
227 args.SetString(kAttributeA, kValueA_0);
228 args.SetInt(kAttributeB, kValueB_0);
229 set<string> results = store_.GetGroupsWithProperties(args);
230 EXPECT_EQ(2, results.size());
231 EXPECT_TRUE(results.find(kGroupA) != results.end());
232 EXPECT_TRUE(results.find(kGroupC) != results.end());
233 }
234 {
235 KeyValueStore args;
236 args.SetString(kAttributeA, kValueA_0);
237 args.SetBool(kAttributeC, kValueC_0);
238 set<string> results = store_.GetGroupsWithProperties(args);
239 EXPECT_EQ(2, results.size());
240 EXPECT_TRUE(results.find(kGroupA) != results.end());
241 EXPECT_TRUE(results.find(kGroupB) != results.end());
242 }
243 {
244 KeyValueStore args;
245 args.SetBool(kAttributeC, kValueC_1);
246 set<string> results = store_.GetGroupsWithProperties(args);
247 EXPECT_EQ(1, results.size());
248 EXPECT_TRUE(results.find(kGroupC) != results.end());
249 }
250 {
251 KeyValueStore args;
252 args.SetString(kAttributeA, kValueA_0);
253 set<string> results = store_.GetGroupsWithProperties(args);
254 EXPECT_EQ(3, results.size());
255 EXPECT_TRUE(results.find(kGroupA) != results.end());
256 EXPECT_TRUE(results.find(kGroupB) != results.end());
257 EXPECT_TRUE(results.find(kGroupC) != results.end());
258 }
259 {
260 KeyValueStore args;
261 args.SetString(kAttributeA, kValueA_1);
262 set<string> results = store_.GetGroupsWithProperties(args);
263 EXPECT_EQ(0, results.size());
264 }
265 ASSERT_TRUE(store_.Close());
266}
267
Darin Petkov083047b2011-06-23 20:42:48 -0700268TEST_F(KeyFileStoreTest, DeleteKey) {
269 static const char kGroup[] = "the-group";
270 static const char kKeyDead[] = "dead";
271 static const char kKeyAlive[] = "alive";
272 const int kValueAlive = 3;
273 WriteKeyFile(base::StringPrintf("[%s]\n"
274 "%s=5\n"
275 "%s=%d\n",
276 kGroup, kKeyDead, kKeyAlive, kValueAlive));
277 ASSERT_TRUE(store_.Open());
278 EXPECT_TRUE(store_.DeleteKey(kGroup, kKeyDead));
Chris Masone9d779932011-08-25 16:33:41 -0700279 EXPECT_TRUE(store_.DeleteKey(kGroup, "random-key"));
Darin Petkov083047b2011-06-23 20:42:48 -0700280 EXPECT_FALSE(store_.DeleteKey("random-group", kKeyAlive));
281 ASSERT_TRUE(store_.Close());
Ben Chana0ddf462014-02-06 11:32:42 -0800282 EXPECT_EQ(base::StringPrintf("[%s]\n"
Darin Petkov083047b2011-06-23 20:42:48 -0700283 "%s=%d\n",
284 kGroup, kKeyAlive, kValueAlive),
285 ReadKeyFile());
286}
287
288TEST_F(KeyFileStoreTest, DeleteGroup) {
289 static const char kGroupA[] = "group-a";
290 static const char kGroupB[] = "group-b";
291 static const char kGroupC[] = "group-c";
292 WriteKeyFile(base::StringPrintf("[%s]\n"
293 "[%s]\n"
294 "key-to-be-deleted=true\n"
295 "[%s]\n",
296 kGroupA, kGroupB, kGroupC));
297 ASSERT_TRUE(store_.Open());
298 EXPECT_TRUE(store_.DeleteGroup(kGroupB));
Chris Masone9d779932011-08-25 16:33:41 -0700299 EXPECT_TRUE(store_.DeleteGroup("group-d"));
Darin Petkov083047b2011-06-23 20:42:48 -0700300 ASSERT_TRUE(store_.Close());
Ben Chana0ddf462014-02-06 11:32:42 -0800301 EXPECT_EQ(base::StringPrintf("[%s]\n"
Darin Petkov083047b2011-06-23 20:42:48 -0700302 "\n"
303 "[%s]\n",
304 kGroupA, kGroupC),
305 ReadKeyFile());
306}
307
308TEST_F(KeyFileStoreTest, GetString) {
309 static const char kGroup[] = "something";
310 static const char kKey[] = "foo";
311 static const char kValue[] = "bar";
312 WriteKeyFile(base::StringPrintf("[%s]\n"
313 "%s=%s\n",
314 kGroup, kKey, kValue));
315 ASSERT_TRUE(store_.Open());
316 string value;
317 EXPECT_TRUE(store_.GetString(kGroup, kKey, &value));
318 EXPECT_EQ(kValue, value);
319 EXPECT_FALSE(store_.GetString("something-else", kKey, &value));
320 EXPECT_FALSE(store_.GetString(kGroup, "bar", &value));
321 EXPECT_TRUE(store_.GetString(kGroup, kKey, NULL));
322 ASSERT_TRUE(store_.Close());
323}
324
325TEST_F(KeyFileStoreTest, SetString) {
326 static const char kGroup[] = "string-group";
327 static const char kKey1[] = "test-string";
328 static const char kValue1[] = "foo";
329 static const char kKey2[] = "empty-string";
330 static const char kValue2[] = "";
331 ASSERT_TRUE(store_.Open());
332 ASSERT_TRUE(store_.SetString(kGroup, kKey1, kValue1));
333 ASSERT_TRUE(store_.SetString(kGroup, kKey2, kValue2));
334 ASSERT_TRUE(store_.Close());
Ben Chana0ddf462014-02-06 11:32:42 -0800335 EXPECT_EQ(base::StringPrintf("[%s]\n"
Darin Petkov083047b2011-06-23 20:42:48 -0700336 "%s=%s\n"
337 "%s=%s\n",
338 kGroup, kKey1, kValue1, kKey2, kValue2),
339 ReadKeyFile());
340}
341
342TEST_F(KeyFileStoreTest, GetBool) {
343 static const char kGroup[] = "boo";
344 static const char kKeyTrue[] = "foo";
345 static const char kKeyFalse[] = "bar";
346 static const char kKeyBad[] = "zoo";
347 WriteKeyFile(base::StringPrintf("[%s]\n"
348 "%s=true\n"
349 "%s=false\n"
350 "%s=moo\n",
351 kGroup, kKeyTrue, kKeyFalse, kKeyBad));
352 ASSERT_TRUE(store_.Open());
353 {
354 bool value = true;
355 EXPECT_TRUE(store_.GetBool(kGroup, kKeyFalse, &value));
356 EXPECT_FALSE(value);
357 }
358 {
359 bool value = false;
360 EXPECT_TRUE(store_.GetBool(kGroup, kKeyTrue, &value));
361 EXPECT_TRUE(value);
362 }
363 {
364 bool value;
365 EXPECT_FALSE(store_.GetBool(kGroup, kKeyBad, &value));
366 EXPECT_FALSE(store_.GetBool(kGroup, "unknown", &value));
367 EXPECT_FALSE(store_.GetBool("unknown", kKeyTrue, &value));
368 }
369 EXPECT_TRUE(store_.GetBool(kGroup, kKeyFalse, NULL));
370 ASSERT_TRUE(store_.Close());
371}
372
373TEST_F(KeyFileStoreTest, SetBool) {
374 static const char kGroup[] = "bool-group";
375 static const char kKeyTrue[] = "test-true-bool";
376 static const char kKeyFalse[] = "test-false-bool";
377 ASSERT_TRUE(store_.Open());
378 ASSERT_TRUE(store_.SetBool(kGroup, kKeyTrue, true));
379 ASSERT_TRUE(store_.SetBool(kGroup, kKeyFalse, false));
380 ASSERT_TRUE(store_.Close());
Ben Chana0ddf462014-02-06 11:32:42 -0800381 EXPECT_EQ(base::StringPrintf("[%s]\n"
Darin Petkov083047b2011-06-23 20:42:48 -0700382 "%s=true\n"
383 "%s=false\n",
384 kGroup, kKeyTrue, kKeyFalse),
385 ReadKeyFile());
386}
387
388TEST_F(KeyFileStoreTest, GetInt) {
389 static const char kGroup[] = "numbers";
390 static const char kKeyPos[] = "pos";
391 static const char kKeyNeg[] = "neg";
392 static const char kKeyBad[] = "bad";
393 const int kValuePos = 50;
394 const int kValueNeg = -20;
395 static const char kValueBad[] = "nan";
396 WriteKeyFile(base::StringPrintf("[%s]\n"
397 "%s=%d\n"
398 "%s=%d\n"
399 "%s=%s\n",
400 kGroup,
401 kKeyPos, kValuePos,
402 kKeyNeg, kValueNeg,
403 kKeyBad, kValueBad));
404 ASSERT_TRUE(store_.Open());
405 {
406 int value = 0;
407 EXPECT_TRUE(store_.GetInt(kGroup, kKeyNeg, &value));
408 EXPECT_EQ(kValueNeg, value);
409 }
410 {
411 int value = 0;
412 EXPECT_TRUE(store_.GetInt(kGroup, kKeyPos, &value));
413 EXPECT_EQ(kValuePos, value);
414 }
415 {
416 int value;
417 EXPECT_FALSE(store_.GetInt(kGroup, kKeyBad, &value));
418 EXPECT_FALSE(store_.GetInt(kGroup, "invalid", &value));
419 EXPECT_FALSE(store_.GetInt("invalid", kKeyPos, &value));
420 }
421 EXPECT_TRUE(store_.GetInt(kGroup, kKeyPos, NULL));
422 ASSERT_TRUE(store_.Close());
423}
424
425TEST_F(KeyFileStoreTest, SetInt) {
426 static const char kGroup[] = "int-group";
427 static const char kKey1[] = "test-int";
428 static const char kKey2[] = "test-negative";
429 const int kValue1 = 5;
430 const int kValue2 = -10;
431 ASSERT_TRUE(store_.Open());
432 ASSERT_TRUE(store_.SetInt(kGroup, kKey1, kValue1));
433 ASSERT_TRUE(store_.SetInt(kGroup, kKey2, kValue2));
434 ASSERT_TRUE(store_.Close());
Ben Chana0ddf462014-02-06 11:32:42 -0800435 EXPECT_EQ(base::StringPrintf("[%s]\n"
Darin Petkov083047b2011-06-23 20:42:48 -0700436 "%s=%d\n"
437 "%s=%d\n",
438 kGroup, kKey1, kValue1, kKey2, kValue2),
439 ReadKeyFile());
440}
441
Paul Stewartdab3b5a2012-07-11 18:25:10 -0700442TEST_F(KeyFileStoreTest, GetUint64) {
443 static const char kGroup[] = "numbers";
444 static const char kKeyGood[] = "good";
445 static const char kKeyBad[] = "bad";
446 const uint64 kValueGood = 0xFEDCBA9876543210LL;
447 static const char kValueBad[] = "nan";
448 // Use base::Uint64ToString() instead of using something like "%llu"
449 // (not correct for native 64 bit architectures) or PRIu64 (does not
450 // work correctly using cros_workon_make due to include intricacies).
451 WriteKeyFile(base::StringPrintf("[%s]\n"
452 "%s=%s\n"
453 "%s=%s\n",
454 kGroup,
455 kKeyGood,
456 base::Uint64ToString(kValueGood).c_str(),
457 kKeyBad, kValueBad));
458 ASSERT_TRUE(store_.Open());
459 {
460 uint64 value = 0;
461 EXPECT_TRUE(store_.GetUint64(kGroup, kKeyGood, &value));
462 EXPECT_EQ(kValueGood, value);
463 }
464 {
465 uint64 value;
466 EXPECT_FALSE(store_.GetUint64(kGroup, kKeyBad, &value));
467 EXPECT_FALSE(store_.GetUint64(kGroup, "invalid", &value));
468 EXPECT_FALSE(store_.GetUint64("invalid", kKeyGood, &value));
469 }
470 EXPECT_TRUE(store_.GetUint64(kGroup, kKeyGood, NULL));
471 ASSERT_TRUE(store_.Close());
472}
473
474TEST_F(KeyFileStoreTest, SetUint64) {
475 static const char kGroup[] = "int-group";
476 static const char kKey[] = "test-int";
477 const uint64 kValue = 0xFEDCBA9876543210LL;
478 ASSERT_TRUE(store_.Open());
479 ASSERT_TRUE(store_.SetUint64(kGroup, kKey, kValue));
480 ASSERT_TRUE(store_.Close());
Ben Chana0ddf462014-02-06 11:32:42 -0800481 EXPECT_EQ(base::StringPrintf("[%s]\n"
Paul Stewartdab3b5a2012-07-11 18:25:10 -0700482 "%s=%s\n",
483 kGroup, kKey,
484 base::Uint64ToString(kValue).c_str()),
485 ReadKeyFile());
486}
487
Darin Petkovb2841fd2011-06-30 12:54:12 -0700488TEST_F(KeyFileStoreTest, GetStringList) {
489 static const char kGroup[] = "string-lists";
490 static const char kKeyEmpty[] = "empty";
491 static const char kKeyEmptyValue[] = "empty-value";
492 static const char kKeyValueEmpty[] = "value-empty";
493 static const char kKeyValueEmptyValue[] = "value-empty-value";
494 static const char kKeyValues[] = "values";
495 static const char kValue[] = "value";
496 static const char kValue2[] = "value2";
497 static const char kValue3[] = "value3";
498 WriteKeyFile(base::StringPrintf("[%s]\n"
499 "%s=\n"
500 "%s=;%s\n"
501 "%s=%s;;\n"
502 "%s=%s;;%s\n"
503 "%s=%s;%s;%s\n",
504 kGroup,
505 kKeyEmpty,
506 kKeyEmptyValue, kValue,
507 kKeyValueEmpty, kValue,
508 kKeyValueEmptyValue, kValue, kValue2,
509 kKeyValues, kValue, kValue2, kValue3));
510 ASSERT_TRUE(store_.Open());
511
512 vector<string> value;
513
514 EXPECT_TRUE(store_.GetStringList(kGroup, kKeyValues, &value));
515 ASSERT_EQ(3, value.size());
516 EXPECT_EQ(kValue, value[0]);
517 EXPECT_EQ(kValue2, value[1]);
518 EXPECT_EQ(kValue3, value[2]);
519
520 EXPECT_TRUE(store_.GetStringList(kGroup, kKeyEmptyValue, &value));
521 ASSERT_EQ(2, value.size());
522 EXPECT_EQ("", value[0]);
523 EXPECT_EQ(kValue, value[1]);
524
525 EXPECT_TRUE(store_.GetStringList(kGroup, kKeyValueEmpty, &value));
526 ASSERT_EQ(2, value.size());
527 EXPECT_EQ(kValue, value[0]);
528 EXPECT_EQ("", value[1]);
529
530 EXPECT_TRUE(store_.GetStringList(kGroup, kKeyEmpty, &value));
531 ASSERT_EQ(0, value.size());
532
533 EXPECT_TRUE(store_.GetStringList(kGroup, kKeyValueEmptyValue, &value));
534 ASSERT_EQ(3, value.size());
535 EXPECT_EQ(kValue, value[0]);
536 EXPECT_EQ("", value[1]);
537 EXPECT_EQ(kValue2, value[2]);
538
539 EXPECT_FALSE(store_.GetStringList("unknown-string-lists", kKeyEmpty, &value));
540 EXPECT_FALSE(store_.GetStringList(kGroup, "some-key", &value));
541 EXPECT_TRUE(store_.GetStringList(kGroup, kKeyValues, NULL));
542 ASSERT_TRUE(store_.Close());
543}
544
545TEST_F(KeyFileStoreTest, SetStringList) {
546 static const char kGroup[] = "strings";
547 static const char kKeyEmpty[] = "e";
548 static const char kKeyEmptyValue[] = "ev";
549 static const char kKeyValueEmpty[] = "ve";
550 static const char kKeyValueEmptyValue[] = "vev";
551 static const char kKeyValues[] = "v";
552 static const char kValue[] = "abc";
553 static const char kValue2[] = "pqr";
554 static const char kValue3[] = "xyz";
555 ASSERT_TRUE(store_.Open());
556 {
557 vector<string> value;
558 ASSERT_TRUE(store_.SetStringList(kGroup, kKeyEmpty, value));
559 }
560 {
561 vector<string> value;
562 value.push_back("");
563 value.push_back(kValue);
564 ASSERT_TRUE(store_.SetStringList(kGroup, kKeyEmptyValue, value));
565 }
566 {
567 vector<string> value;
568 value.push_back(kValue);
569 value.push_back("");
570 ASSERT_TRUE(store_.SetStringList(kGroup, kKeyValueEmpty, value));
571 }
572 {
573 vector<string> value;
574 value.push_back(kValue);
575 value.push_back("");
576 value.push_back(kValue2);
577 ASSERT_TRUE(store_.SetStringList(kGroup, kKeyValueEmptyValue, value));
578 }
579 {
580 vector<string> value;
581 value.push_back(kValue);
582 value.push_back(kValue2);
583 value.push_back(kValue3);
584 ASSERT_TRUE(store_.SetStringList(kGroup, kKeyValues, value));
585 }
586 ASSERT_TRUE(store_.Close());
Ben Chana0ddf462014-02-06 11:32:42 -0800587 EXPECT_EQ(base::StringPrintf("[%s]\n"
Darin Petkovb2841fd2011-06-30 12:54:12 -0700588 "%s=\n"
589 "%s=;%s;\n"
590 "%s=%s;;\n"
591 "%s=%s;;%s;\n"
592 "%s=%s;%s;%s;\n",
593 kGroup,
594 kKeyEmpty,
595 kKeyEmptyValue, kValue,
596 kKeyValueEmpty, kValue,
597 kKeyValueEmptyValue, kValue, kValue2,
598 kKeyValues, kValue, kValue2, kValue3),
599 ReadKeyFile());
600}
601
Darin Petkov86964e02011-06-29 13:49:28 -0700602TEST_F(KeyFileStoreTest, GetCryptedString) {
603 static const char kGroup[] = "crypto-group";
604 static const char kKey[] = "secret";
605 WriteKeyFile(base::StringPrintf("[%s]\n"
606 "%s=%s\n",
607 kGroup, kKey, kROT47Text));
608 ASSERT_TRUE(store_.Open());
609 string value;
610 EXPECT_TRUE(store_.GetCryptedString(kGroup, kKey, &value));
611 EXPECT_EQ(kPlainText, value);
612 EXPECT_FALSE(store_.GetCryptedString("something-else", kKey, &value));
613 EXPECT_FALSE(store_.GetCryptedString(kGroup, "non-secret", &value));
614 EXPECT_TRUE(store_.GetCryptedString(kGroup, kKey, NULL));
615 ASSERT_TRUE(store_.Close());
616}
617
618TEST_F(KeyFileStoreTest, SetCryptedString) {
619 static const char kGroup[] = "crypted-string-group";
620 static const char kKey[] = "test-string";
621 ASSERT_TRUE(store_.Open());
622 ASSERT_TRUE(store_.SetCryptedString(kGroup, kKey, kPlainText));
623 ASSERT_TRUE(store_.Close());
Ben Chana0ddf462014-02-06 11:32:42 -0800624 EXPECT_EQ(base::StringPrintf("[%s]\n"
Darin Petkov86964e02011-06-29 13:49:28 -0700625 "%s=%s\n",
626 kGroup, kKey, kROT47Text),
627 ReadKeyFile());
628}
629
Chris Masoneb9c00592011-10-06 13:10:39 -0700630TEST_F(KeyFileStoreTest, PersistAcrossClose) {
631 static const char kGroup[] = "string-group";
632 static const char kKey1[] = "test-string";
633 static const char kValue1[] = "foo";
634 static const char kKey2[] = "empty-string";
635 static const char kValue2[] = "";
636 ASSERT_TRUE(store_.Open());
637 ASSERT_TRUE(store_.SetString(kGroup, kKey1, kValue1));
638 ASSERT_TRUE(store_.Close());
639 ASSERT_TRUE(store_.Open());
640 ASSERT_TRUE(store_.SetString(kGroup, kKey2, kValue2));
641 string value;
642 ASSERT_TRUE(store_.GetString(kGroup, kKey1, &value));
643 ASSERT_EQ(kValue1, value);
644 ASSERT_TRUE(store_.GetString(kGroup, kKey2, &value));
645 ASSERT_EQ(kValue2, value);
646 ASSERT_TRUE(store_.Close());
647}
648
649bool KeyFileStoreTest::OpenCheckClose(const string &group,
650 const string &key,
651 const string &expected_value) {
652 KeyFileStore store(&glib_);
653 store.set_path(test_file_);
654 EXPECT_TRUE(store.Open());
655 string value;
656 bool could_get = store.GetString(group, key, &value);
657 store.set_path(FilePath("")); // Don't persist to disk.
658 store.Close();
659 return could_get && expected_value == value;
660}
661
662TEST_F(KeyFileStoreTest, Flush) {
663 static const char kGroup[] = "string-group";
664 static const char kKey1[] = "test-string";
665 static const char kValue1[] = "foo";
666 static const char kKey2[] = "empty-string";
667 static const char kValue2[] = "";
668 ASSERT_TRUE(store_.Open());
669 ASSERT_TRUE(store_.SetString(kGroup, kKey1, kValue1));
670 ASSERT_TRUE(store_.Flush());
671 ASSERT_TRUE(OpenCheckClose(kGroup, kKey1, kValue1));
672
673 ASSERT_TRUE(store_.SetString(kGroup, kKey2, kValue2));
674 ASSERT_TRUE(store_.Flush());
675 ASSERT_TRUE(OpenCheckClose(kGroup, kKey2, kValue2));
676
677 EXPECT_TRUE(store_.DeleteKey(kGroup, kKey1));
678 ASSERT_TRUE(store_.Flush());
679 ASSERT_FALSE(OpenCheckClose(kGroup, kKey1, kValue1));
680}
681
Paul Stewart5dc40aa2011-10-28 19:43:43 -0700682TEST_F(KeyFileStoreTest, EmptyFile) {
683 ASSERT_TRUE(store_.Open());
684 ASSERT_TRUE(store_.Close());
685 EXPECT_FALSE(store_.IsNonEmpty());
686}
687
688TEST_F(KeyFileStoreTest, SetHeader) {
689 ASSERT_TRUE(store_.Open());
690 ASSERT_TRUE(store_.SetHeader("this is a test"));
691 ASSERT_TRUE(store_.Close());
692 EXPECT_TRUE(store_.IsNonEmpty());
693 ASSERT_TRUE(store_.Open());
694}
695
Darin Petkov083047b2011-06-23 20:42:48 -0700696TEST_F(KeyFileStoreTest, Combo) {
697 static const char kGroupA[] = "square";
698 static const char kGroupB[] = "circle";
699 static const char kGroupC[] = "triangle";
700 static const char kGroupX[] = "pentagon";
701 static const char kKeyString[] = "color";
Darin Petkovb2841fd2011-06-30 12:54:12 -0700702 static const char kKeyStringList[] = "alternative-colors";
Darin Petkov083047b2011-06-23 20:42:48 -0700703 static const char kKeyInt[] = "area";
704 static const char kKeyBool[] = "visible";
705 static const char kValueStringA[] = "blue";
706 static const char kValueStringB[] = "red";
707 static const char kValueStringC[] = "yellow";
708 static const char kValueStringCNew[] = "purple";
709 const int kValueIntA = 5;
710 const int kValueIntB = 10;
711 const int kValueIntBNew = 333;
712 WriteKeyFile(base::StringPrintf("[%s]\n"
713 "%s=%s\n"
Darin Petkovb2841fd2011-06-30 12:54:12 -0700714 "%s=%s;%s\n"
Darin Petkov083047b2011-06-23 20:42:48 -0700715 "%s=%d\n"
716 "[%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=true\n"
721 "[%s]\n"
722 "%s=%s\n"
723 "%s=false\n",
724 kGroupA,
725 kKeyString, kValueStringA,
Darin Petkovb2841fd2011-06-30 12:54:12 -0700726 kKeyStringList, kValueStringB, kValueStringC,
Darin Petkov083047b2011-06-23 20:42:48 -0700727 kKeyInt, kValueIntA,
728 kGroupB,
729 kKeyString, kValueStringB,
Darin Petkovb2841fd2011-06-30 12:54:12 -0700730 kKeyStringList, kValueStringA, kValueStringC,
Darin Petkov083047b2011-06-23 20:42:48 -0700731 kKeyInt, kValueIntB,
732 kKeyBool,
733 kGroupC,
734 kKeyString, kValueStringC,
735 kKeyBool));
736 ASSERT_TRUE(store_.Open());
737
738 EXPECT_TRUE(store_.ContainsGroup(kGroupA));
739 EXPECT_TRUE(store_.ContainsGroup(kGroupB));
740 EXPECT_TRUE(store_.ContainsGroup(kGroupC));
741 EXPECT_FALSE(store_.ContainsGroup(kGroupX));
742
743 set<string> groups = store_.GetGroups();
744 EXPECT_EQ(3, groups.size());
745 EXPECT_TRUE(ContainsKey(groups, kGroupA));
746 EXPECT_TRUE(ContainsKey(groups, kGroupB));
747 EXPECT_TRUE(ContainsKey(groups, kGroupC));
748 EXPECT_FALSE(ContainsKey(groups, kGroupX));
749
750 {
751 string value;
752 EXPECT_TRUE(store_.GetString(kGroupB, kKeyString, &value));
753 EXPECT_EQ(kValueStringB, value);
754 EXPECT_TRUE(store_.GetString(kGroupA, kKeyString, &value));
755 EXPECT_EQ(kValueStringA, value);
756 EXPECT_TRUE(store_.GetString(kGroupC, kKeyString, &value));
757 EXPECT_EQ(kValueStringC, value);
758 }
759 {
Darin Petkovb2841fd2011-06-30 12:54:12 -0700760 vector<string> value;
761 EXPECT_TRUE(store_.GetStringList(kGroupB, kKeyStringList, &value));
762 ASSERT_EQ(2, value.size());
763 EXPECT_EQ(kValueStringA, value[0]);
764 EXPECT_EQ(kValueStringC, value[1]);
765 EXPECT_TRUE(store_.GetStringList(kGroupA, kKeyStringList, &value));
766 ASSERT_EQ(2, value.size());
767 EXPECT_EQ(kValueStringB, value[0]);
768 EXPECT_EQ(kValueStringC, value[1]);
769 EXPECT_FALSE(store_.GetStringList(kGroupC, kKeyStringList, &value));
770 }
771 {
Darin Petkov083047b2011-06-23 20:42:48 -0700772 int value = 0;
773 EXPECT_TRUE(store_.GetInt(kGroupB, kKeyInt, &value));
774 EXPECT_EQ(kValueIntB, value);
775 EXPECT_TRUE(store_.GetInt(kGroupA, kKeyInt, &value));
776 EXPECT_EQ(kValueIntA, value);
777 EXPECT_FALSE(store_.GetInt(kGroupC, kKeyInt, &value));
778 }
779 {
780 bool value = false;
781 EXPECT_TRUE(store_.GetBool(kGroupB, kKeyBool, &value));
782 EXPECT_TRUE(value);
783 EXPECT_TRUE(store_.GetBool(kGroupC, kKeyBool, &value));
784 EXPECT_FALSE(value);
785 EXPECT_FALSE(store_.GetBool(kGroupA, kKeyBool, &value));
786 }
787
788 EXPECT_TRUE(store_.DeleteGroup(kGroupA));
Chris Masone9d779932011-08-25 16:33:41 -0700789 EXPECT_TRUE(store_.DeleteGroup(kGroupA));
Darin Petkov083047b2011-06-23 20:42:48 -0700790
791 EXPECT_FALSE(store_.ContainsGroup(kGroupA));
792 EXPECT_TRUE(store_.ContainsGroup(kGroupB));
793 EXPECT_TRUE(store_.ContainsGroup(kGroupC));
794
795 groups = store_.GetGroups();
796 EXPECT_EQ(2, groups.size());
797 EXPECT_FALSE(ContainsKey(groups, kGroupA));
798 EXPECT_TRUE(ContainsKey(groups, kGroupB));
799 EXPECT_TRUE(ContainsKey(groups, kGroupC));
800
801 EXPECT_TRUE(store_.SetBool(kGroupB, kKeyBool, false));
802 EXPECT_TRUE(store_.SetInt(kGroupB, kKeyInt, kValueIntBNew));
803 EXPECT_TRUE(store_.SetString(kGroupC, kKeyString, kValueStringCNew));
Darin Petkovb2841fd2011-06-30 12:54:12 -0700804 store_.SetStringList(kGroupB,
805 kKeyStringList,
806 vector<string>(1, kValueStringB));
Darin Petkov083047b2011-06-23 20:42:48 -0700807
808 EXPECT_TRUE(store_.DeleteKey(kGroupB, kKeyString));
Chris Masone9d779932011-08-25 16:33:41 -0700809 EXPECT_TRUE(store_.DeleteKey(kGroupB, kKeyString));
Darin Petkov083047b2011-06-23 20:42:48 -0700810
811 {
812 string value;
813 EXPECT_FALSE(store_.GetString(kGroupB, kKeyString, &value));
814 EXPECT_FALSE(store_.GetString(kGroupA, kKeyString, &value));
815 EXPECT_TRUE(store_.GetString(kGroupC, kKeyString, &value));
816 EXPECT_EQ(kValueStringCNew, value);
817 }
Darin Petkovb2841fd2011-06-30 12:54:12 -0700818 {
819 vector<string> value;
820 EXPECT_TRUE(store_.GetStringList(kGroupB, kKeyStringList, &value));
821 ASSERT_EQ(1, value.size());
822 EXPECT_EQ(kValueStringB, value[0]);
823 EXPECT_FALSE(store_.GetStringList(kGroupA, kKeyStringList, &value));
824 EXPECT_FALSE(store_.GetStringList(kGroupC, kKeyStringList, &value));
825 }
Darin Petkov083047b2011-06-23 20:42:48 -0700826 {
827 int value = 0;
828 EXPECT_TRUE(store_.GetInt(kGroupB, kKeyInt, &value));
829 EXPECT_EQ(kValueIntBNew, value);
830 EXPECT_FALSE(store_.GetInt(kGroupA, kKeyInt, &value));
831 EXPECT_FALSE(store_.GetInt(kGroupC, kKeyInt, &value));
832 }
Darin Petkov083047b2011-06-23 20:42:48 -0700833 {
834 bool value = false;
835 EXPECT_TRUE(store_.GetBool(kGroupB, kKeyBool, &value));
836 EXPECT_FALSE(value);
837 EXPECT_TRUE(store_.GetBool(kGroupC, kKeyBool, &value));
838 EXPECT_FALSE(value);
839 EXPECT_FALSE(store_.GetBool(kGroupA, kKeyBool, &value));
840 }
841
842 ASSERT_TRUE(store_.Close());
Ben Chana0ddf462014-02-06 11:32:42 -0800843 EXPECT_EQ(base::StringPrintf("[%s]\n"
Darin Petkovb2841fd2011-06-30 12:54:12 -0700844 "%s=%s;\n"
Darin Petkov083047b2011-06-23 20:42:48 -0700845 "%s=%d\n"
846 "%s=false\n"
847 "\n"
848 "[%s]\n"
849 "%s=%s\n"
850 "%s=false\n",
851 kGroupB,
Darin Petkovb2841fd2011-06-30 12:54:12 -0700852 kKeyStringList, kValueStringB,
Darin Petkov083047b2011-06-23 20:42:48 -0700853 kKeyInt, kValueIntBNew,
854 kKeyBool,
855 kGroupC,
856 kKeyString, kValueStringCNew,
857 kKeyBool),
858 ReadKeyFile());
859}
860
861} // namespace shill