Add ability to query and allocate zero copy buffers.
[chromium-blink-merge.git] / base / prefs / json_pref_store_unittest.cc
blobdc4043e32bec3a20627ade7550ca3a2927821659
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/prefs/json_pref_store.h"
7 #include "base/bind.h"
8 #include "base/files/file_util.h"
9 #include "base/files/scoped_temp_dir.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/path_service.h"
14 #include "base/prefs/pref_filter.h"
15 #include "base/run_loop.h"
16 #include "base/strings/string_number_conversions.h"
17 #include "base/strings/string_util.h"
18 #include "base/strings/utf_string_conversions.h"
19 #include "base/threading/sequenced_worker_pool.h"
20 #include "base/threading/thread.h"
21 #include "base/values.h"
22 #include "testing/gmock/include/gmock/gmock.h"
23 #include "testing/gtest/include/gtest/gtest.h"
25 namespace base {
26 namespace {
28 const char kHomePage[] = "homepage";
30 // A PrefFilter that will intercept all calls to FilterOnLoad() and hold on
31 // to the |prefs| until explicitly asked to release them.
32 class InterceptingPrefFilter : public PrefFilter {
33 public:
34 InterceptingPrefFilter();
35 ~InterceptingPrefFilter() override;
37 // PrefFilter implementation:
38 void FilterOnLoad(
39 const PostFilterOnLoadCallback& post_filter_on_load_callback,
40 scoped_ptr<base::DictionaryValue> pref_store_contents) override;
41 void FilterUpdate(const std::string& path) override {}
42 void FilterSerializeData(
43 base::DictionaryValue* pref_store_contents) override {}
45 bool has_intercepted_prefs() const { return intercepted_prefs_ != NULL; }
47 // Finalize an intercepted read, handing |intercepted_prefs_| back to its
48 // JsonPrefStore.
49 void ReleasePrefs();
51 private:
52 PostFilterOnLoadCallback post_filter_on_load_callback_;
53 scoped_ptr<base::DictionaryValue> intercepted_prefs_;
55 DISALLOW_COPY_AND_ASSIGN(InterceptingPrefFilter);
58 InterceptingPrefFilter::InterceptingPrefFilter() {}
59 InterceptingPrefFilter::~InterceptingPrefFilter() {}
61 void InterceptingPrefFilter::FilterOnLoad(
62 const PostFilterOnLoadCallback& post_filter_on_load_callback,
63 scoped_ptr<base::DictionaryValue> pref_store_contents) {
64 post_filter_on_load_callback_ = post_filter_on_load_callback;
65 intercepted_prefs_ = pref_store_contents.Pass();
68 void InterceptingPrefFilter::ReleasePrefs() {
69 EXPECT_FALSE(post_filter_on_load_callback_.is_null());
70 post_filter_on_load_callback_.Run(intercepted_prefs_.Pass(), false);
71 post_filter_on_load_callback_.Reset();
74 class MockPrefStoreObserver : public PrefStore::Observer {
75 public:
76 MOCK_METHOD1(OnPrefValueChanged, void (const std::string&));
77 MOCK_METHOD1(OnInitializationCompleted, void (bool));
80 class MockReadErrorDelegate : public PersistentPrefStore::ReadErrorDelegate {
81 public:
82 MOCK_METHOD1(OnError, void(PersistentPrefStore::PrefReadError));
85 } // namespace
87 class JsonPrefStoreTest : public testing::Test {
88 protected:
89 virtual void SetUp() override {
90 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
92 ASSERT_TRUE(PathService::Get(base::DIR_TEST_DATA, &data_dir_));
93 data_dir_ = data_dir_.AppendASCII("prefs");
94 ASSERT_TRUE(PathExists(data_dir_));
97 virtual void TearDown() override {
98 // Make sure all pending tasks have been processed (e.g., deleting the
99 // JsonPrefStore may post write tasks).
100 message_loop_.PostTask(FROM_HERE, MessageLoop::QuitWhenIdleClosure());
101 message_loop_.Run();
104 // The path to temporary directory used to contain the test operations.
105 base::ScopedTempDir temp_dir_;
106 // The path to the directory where the test data is stored.
107 base::FilePath data_dir_;
108 // A message loop that we can use as the file thread message loop.
109 MessageLoop message_loop_;
112 // Test fallback behavior for a nonexistent file.
113 TEST_F(JsonPrefStoreTest, NonExistentFile) {
114 base::FilePath bogus_input_file = data_dir_.AppendASCII("read.txt");
115 ASSERT_FALSE(PathExists(bogus_input_file));
116 scoped_refptr<JsonPrefStore> pref_store = new JsonPrefStore(
117 bogus_input_file,
118 message_loop_.message_loop_proxy().get(),
119 scoped_ptr<PrefFilter>());
120 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE,
121 pref_store->ReadPrefs());
122 EXPECT_FALSE(pref_store->ReadOnly());
125 // Test fallback behavior for a nonexistent file and alternate file.
126 TEST_F(JsonPrefStoreTest, NonExistentFileAndAlternateFile) {
127 base::FilePath bogus_input_file = data_dir_.AppendASCII("read.txt");
128 base::FilePath bogus_alternate_input_file =
129 data_dir_.AppendASCII("read_alternate.txt");
130 ASSERT_FALSE(PathExists(bogus_input_file));
131 ASSERT_FALSE(PathExists(bogus_alternate_input_file));
132 scoped_refptr<JsonPrefStore> pref_store = new JsonPrefStore(
133 bogus_input_file,
134 bogus_alternate_input_file,
135 message_loop_.message_loop_proxy().get(),
136 scoped_ptr<PrefFilter>());
137 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE,
138 pref_store->ReadPrefs());
139 EXPECT_FALSE(pref_store->ReadOnly());
142 // Test fallback behavior for an invalid file.
143 TEST_F(JsonPrefStoreTest, InvalidFile) {
144 base::FilePath invalid_file_original = data_dir_.AppendASCII("invalid.json");
145 base::FilePath invalid_file = temp_dir_.path().AppendASCII("invalid.json");
146 ASSERT_TRUE(base::CopyFile(invalid_file_original, invalid_file));
147 scoped_refptr<JsonPrefStore> pref_store =
148 new JsonPrefStore(invalid_file,
149 message_loop_.message_loop_proxy().get(),
150 scoped_ptr<PrefFilter>());
151 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_JSON_PARSE,
152 pref_store->ReadPrefs());
153 EXPECT_FALSE(pref_store->ReadOnly());
155 // The file should have been moved aside.
156 EXPECT_FALSE(PathExists(invalid_file));
157 base::FilePath moved_aside = temp_dir_.path().AppendASCII("invalid.bad");
158 EXPECT_TRUE(PathExists(moved_aside));
159 EXPECT_TRUE(TextContentsEqual(invalid_file_original, moved_aside));
162 // This function is used to avoid code duplication while testing synchronous and
163 // asynchronous version of the JsonPrefStore loading.
164 void RunBasicJsonPrefStoreTest(JsonPrefStore* pref_store,
165 const base::FilePath& output_file,
166 const base::FilePath& golden_output_file) {
167 const char kNewWindowsInTabs[] = "tabs.new_windows_in_tabs";
168 const char kMaxTabs[] = "tabs.max_tabs";
169 const char kLongIntPref[] = "long_int.pref";
171 std::string cnn("http://www.cnn.com");
173 const Value* actual;
174 EXPECT_TRUE(pref_store->GetValue(kHomePage, &actual));
175 std::string string_value;
176 EXPECT_TRUE(actual->GetAsString(&string_value));
177 EXPECT_EQ(cnn, string_value);
179 const char kSomeDirectory[] = "some_directory";
181 EXPECT_TRUE(pref_store->GetValue(kSomeDirectory, &actual));
182 base::FilePath::StringType path;
183 EXPECT_TRUE(actual->GetAsString(&path));
184 EXPECT_EQ(base::FilePath::StringType(FILE_PATH_LITERAL("/usr/local/")), path);
185 base::FilePath some_path(FILE_PATH_LITERAL("/usr/sbin/"));
187 pref_store->SetValue(kSomeDirectory, new StringValue(some_path.value()));
188 EXPECT_TRUE(pref_store->GetValue(kSomeDirectory, &actual));
189 EXPECT_TRUE(actual->GetAsString(&path));
190 EXPECT_EQ(some_path.value(), path);
192 // Test reading some other data types from sub-dictionaries.
193 EXPECT_TRUE(pref_store->GetValue(kNewWindowsInTabs, &actual));
194 bool boolean = false;
195 EXPECT_TRUE(actual->GetAsBoolean(&boolean));
196 EXPECT_TRUE(boolean);
198 pref_store->SetValue(kNewWindowsInTabs, new FundamentalValue(false));
199 EXPECT_TRUE(pref_store->GetValue(kNewWindowsInTabs, &actual));
200 EXPECT_TRUE(actual->GetAsBoolean(&boolean));
201 EXPECT_FALSE(boolean);
203 EXPECT_TRUE(pref_store->GetValue(kMaxTabs, &actual));
204 int integer = 0;
205 EXPECT_TRUE(actual->GetAsInteger(&integer));
206 EXPECT_EQ(20, integer);
207 pref_store->SetValue(kMaxTabs, new FundamentalValue(10));
208 EXPECT_TRUE(pref_store->GetValue(kMaxTabs, &actual));
209 EXPECT_TRUE(actual->GetAsInteger(&integer));
210 EXPECT_EQ(10, integer);
212 pref_store->SetValue(kLongIntPref,
213 new StringValue(base::Int64ToString(214748364842LL)));
214 EXPECT_TRUE(pref_store->GetValue(kLongIntPref, &actual));
215 EXPECT_TRUE(actual->GetAsString(&string_value));
216 int64 value;
217 base::StringToInt64(string_value, &value);
218 EXPECT_EQ(214748364842LL, value);
220 // Serialize and compare to expected output.
221 ASSERT_TRUE(PathExists(golden_output_file));
222 pref_store->CommitPendingWrite();
223 RunLoop().RunUntilIdle();
224 EXPECT_TRUE(TextContentsEqual(golden_output_file, output_file));
225 ASSERT_TRUE(base::DeleteFile(output_file, false));
228 TEST_F(JsonPrefStoreTest, Basic) {
229 ASSERT_TRUE(base::CopyFile(data_dir_.AppendASCII("read.json"),
230 temp_dir_.path().AppendASCII("write.json")));
232 // Test that the persistent value can be loaded.
233 base::FilePath input_file = temp_dir_.path().AppendASCII("write.json");
234 ASSERT_TRUE(PathExists(input_file));
235 scoped_refptr<JsonPrefStore> pref_store = new JsonPrefStore(
236 input_file,
237 message_loop_.message_loop_proxy().get(),
238 scoped_ptr<PrefFilter>());
239 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, pref_store->ReadPrefs());
240 EXPECT_FALSE(pref_store->ReadOnly());
241 EXPECT_TRUE(pref_store->IsInitializationComplete());
243 // The JSON file looks like this:
244 // {
245 // "homepage": "http://www.cnn.com",
246 // "some_directory": "/usr/local/",
247 // "tabs": {
248 // "new_windows_in_tabs": true,
249 // "max_tabs": 20
250 // }
251 // }
253 RunBasicJsonPrefStoreTest(
254 pref_store.get(), input_file, data_dir_.AppendASCII("write.golden.json"));
257 TEST_F(JsonPrefStoreTest, BasicAsync) {
258 ASSERT_TRUE(base::CopyFile(data_dir_.AppendASCII("read.json"),
259 temp_dir_.path().AppendASCII("write.json")));
261 // Test that the persistent value can be loaded.
262 base::FilePath input_file = temp_dir_.path().AppendASCII("write.json");
263 ASSERT_TRUE(PathExists(input_file));
264 scoped_refptr<JsonPrefStore> pref_store = new JsonPrefStore(
265 input_file,
266 message_loop_.message_loop_proxy().get(),
267 scoped_ptr<PrefFilter>());
270 MockPrefStoreObserver mock_observer;
271 pref_store->AddObserver(&mock_observer);
273 MockReadErrorDelegate* mock_error_delegate = new MockReadErrorDelegate;
274 pref_store->ReadPrefsAsync(mock_error_delegate);
276 EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(1);
277 EXPECT_CALL(*mock_error_delegate,
278 OnError(PersistentPrefStore::PREF_READ_ERROR_NONE)).Times(0);
279 RunLoop().RunUntilIdle();
280 pref_store->RemoveObserver(&mock_observer);
282 EXPECT_FALSE(pref_store->ReadOnly());
283 EXPECT_TRUE(pref_store->IsInitializationComplete());
286 // The JSON file looks like this:
287 // {
288 // "homepage": "http://www.cnn.com",
289 // "some_directory": "/usr/local/",
290 // "tabs": {
291 // "new_windows_in_tabs": true,
292 // "max_tabs": 20
293 // }
294 // }
296 RunBasicJsonPrefStoreTest(
297 pref_store.get(), input_file, data_dir_.AppendASCII("write.golden.json"));
300 TEST_F(JsonPrefStoreTest, PreserveEmptyValues) {
301 FilePath pref_file = temp_dir_.path().AppendASCII("empty_values.json");
303 scoped_refptr<JsonPrefStore> pref_store = new JsonPrefStore(
304 pref_file,
305 message_loop_.message_loop_proxy(),
306 scoped_ptr<PrefFilter>());
308 // Set some keys with empty values.
309 pref_store->SetValue("list", new base::ListValue);
310 pref_store->SetValue("dict", new base::DictionaryValue);
312 // Write to file.
313 pref_store->CommitPendingWrite();
314 MessageLoop::current()->RunUntilIdle();
316 // Reload.
317 pref_store = new JsonPrefStore(
318 pref_file,
319 message_loop_.message_loop_proxy(),
320 scoped_ptr<PrefFilter>());
321 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, pref_store->ReadPrefs());
322 ASSERT_FALSE(pref_store->ReadOnly());
324 // Check values.
325 const Value* result = NULL;
326 EXPECT_TRUE(pref_store->GetValue("list", &result));
327 EXPECT_TRUE(ListValue().Equals(result));
328 EXPECT_TRUE(pref_store->GetValue("dict", &result));
329 EXPECT_TRUE(DictionaryValue().Equals(result));
332 // This test is just documenting some potentially non-obvious behavior. It
333 // shouldn't be taken as normative.
334 TEST_F(JsonPrefStoreTest, RemoveClearsEmptyParent) {
335 FilePath pref_file = temp_dir_.path().AppendASCII("empty_values.json");
337 scoped_refptr<JsonPrefStore> pref_store = new JsonPrefStore(
338 pref_file,
339 message_loop_.message_loop_proxy(),
340 scoped_ptr<PrefFilter>());
342 base::DictionaryValue* dict = new base::DictionaryValue;
343 dict->SetString("key", "value");
344 pref_store->SetValue("dict", dict);
346 pref_store->RemoveValue("dict.key");
348 const base::Value* retrieved_dict = NULL;
349 bool has_dict = pref_store->GetValue("dict", &retrieved_dict);
350 EXPECT_FALSE(has_dict);
353 // Tests asynchronous reading of the file when there is no file.
354 TEST_F(JsonPrefStoreTest, AsyncNonExistingFile) {
355 base::FilePath bogus_input_file = data_dir_.AppendASCII("read.txt");
356 ASSERT_FALSE(PathExists(bogus_input_file));
357 scoped_refptr<JsonPrefStore> pref_store = new JsonPrefStore(
358 bogus_input_file,
359 message_loop_.message_loop_proxy().get(),
360 scoped_ptr<PrefFilter>());
361 MockPrefStoreObserver mock_observer;
362 pref_store->AddObserver(&mock_observer);
364 MockReadErrorDelegate *mock_error_delegate = new MockReadErrorDelegate;
365 pref_store->ReadPrefsAsync(mock_error_delegate);
367 EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(1);
368 EXPECT_CALL(*mock_error_delegate,
369 OnError(PersistentPrefStore::PREF_READ_ERROR_NO_FILE)).Times(1);
370 RunLoop().RunUntilIdle();
371 pref_store->RemoveObserver(&mock_observer);
373 EXPECT_FALSE(pref_store->ReadOnly());
376 TEST_F(JsonPrefStoreTest, ReadWithInterceptor) {
377 ASSERT_TRUE(base::CopyFile(data_dir_.AppendASCII("read.json"),
378 temp_dir_.path().AppendASCII("write.json")));
380 // Test that the persistent value can be loaded.
381 base::FilePath input_file = temp_dir_.path().AppendASCII("write.json");
382 ASSERT_TRUE(PathExists(input_file));
384 scoped_ptr<InterceptingPrefFilter> intercepting_pref_filter(
385 new InterceptingPrefFilter());
386 InterceptingPrefFilter* raw_intercepting_pref_filter_ =
387 intercepting_pref_filter.get();
388 scoped_refptr<JsonPrefStore> pref_store =
389 new JsonPrefStore(input_file,
390 message_loop_.message_loop_proxy().get(),
391 intercepting_pref_filter.Pass());
393 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_ASYNCHRONOUS_TASK_INCOMPLETE,
394 pref_store->ReadPrefs());
395 EXPECT_FALSE(pref_store->ReadOnly());
397 // The store shouldn't be considered initialized until the interceptor
398 // returns.
399 EXPECT_TRUE(raw_intercepting_pref_filter_->has_intercepted_prefs());
400 EXPECT_FALSE(pref_store->IsInitializationComplete());
401 EXPECT_FALSE(pref_store->GetValue(kHomePage, NULL));
403 raw_intercepting_pref_filter_->ReleasePrefs();
405 EXPECT_FALSE(raw_intercepting_pref_filter_->has_intercepted_prefs());
406 EXPECT_TRUE(pref_store->IsInitializationComplete());
407 EXPECT_TRUE(pref_store->GetValue(kHomePage, NULL));
409 // The JSON file looks like this:
410 // {
411 // "homepage": "http://www.cnn.com",
412 // "some_directory": "/usr/local/",
413 // "tabs": {
414 // "new_windows_in_tabs": true,
415 // "max_tabs": 20
416 // }
417 // }
419 RunBasicJsonPrefStoreTest(
420 pref_store.get(), input_file, data_dir_.AppendASCII("write.golden.json"));
423 TEST_F(JsonPrefStoreTest, ReadAsyncWithInterceptor) {
424 ASSERT_TRUE(base::CopyFile(data_dir_.AppendASCII("read.json"),
425 temp_dir_.path().AppendASCII("write.json")));
427 // Test that the persistent value can be loaded.
428 base::FilePath input_file = temp_dir_.path().AppendASCII("write.json");
429 ASSERT_TRUE(PathExists(input_file));
431 scoped_ptr<InterceptingPrefFilter> intercepting_pref_filter(
432 new InterceptingPrefFilter());
433 InterceptingPrefFilter* raw_intercepting_pref_filter_ =
434 intercepting_pref_filter.get();
435 scoped_refptr<JsonPrefStore> pref_store =
436 new JsonPrefStore(input_file,
437 message_loop_.message_loop_proxy().get(),
438 intercepting_pref_filter.Pass());
440 MockPrefStoreObserver mock_observer;
441 pref_store->AddObserver(&mock_observer);
443 // Ownership of the |mock_error_delegate| is handed to the |pref_store| below.
444 MockReadErrorDelegate* mock_error_delegate = new MockReadErrorDelegate;
447 pref_store->ReadPrefsAsync(mock_error_delegate);
449 EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(0);
450 // EXPECT_CALL(*mock_error_delegate,
451 // OnError(PersistentPrefStore::PREF_READ_ERROR_NONE)).Times(0);
452 RunLoop().RunUntilIdle();
454 EXPECT_FALSE(pref_store->ReadOnly());
455 EXPECT_TRUE(raw_intercepting_pref_filter_->has_intercepted_prefs());
456 EXPECT_FALSE(pref_store->IsInitializationComplete());
457 EXPECT_FALSE(pref_store->GetValue(kHomePage, NULL));
461 EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(1);
462 // EXPECT_CALL(*mock_error_delegate,
463 // OnError(PersistentPrefStore::PREF_READ_ERROR_NONE)).Times(0);
465 raw_intercepting_pref_filter_->ReleasePrefs();
467 EXPECT_FALSE(pref_store->ReadOnly());
468 EXPECT_FALSE(raw_intercepting_pref_filter_->has_intercepted_prefs());
469 EXPECT_TRUE(pref_store->IsInitializationComplete());
470 EXPECT_TRUE(pref_store->GetValue(kHomePage, NULL));
473 pref_store->RemoveObserver(&mock_observer);
475 // The JSON file looks like this:
476 // {
477 // "homepage": "http://www.cnn.com",
478 // "some_directory": "/usr/local/",
479 // "tabs": {
480 // "new_windows_in_tabs": true,
481 // "max_tabs": 20
482 // }
483 // }
485 RunBasicJsonPrefStoreTest(
486 pref_store.get(), input_file, data_dir_.AppendASCII("write.golden.json"));
489 TEST_F(JsonPrefStoreTest, AlternateFile) {
490 ASSERT_TRUE(
491 base::CopyFile(data_dir_.AppendASCII("read.json"),
492 temp_dir_.path().AppendASCII("alternate.json")));
494 // Test that the alternate file is moved to the main file and read as-is from
495 // there.
496 base::FilePath input_file = temp_dir_.path().AppendASCII("write.json");
497 base::FilePath alternate_input_file =
498 temp_dir_.path().AppendASCII("alternate.json");
499 ASSERT_FALSE(PathExists(input_file));
500 ASSERT_TRUE(PathExists(alternate_input_file));
501 scoped_refptr<JsonPrefStore> pref_store = new JsonPrefStore(
502 input_file,
503 alternate_input_file,
504 message_loop_.message_loop_proxy().get(),
505 scoped_ptr<PrefFilter>());
507 ASSERT_FALSE(PathExists(input_file));
508 ASSERT_TRUE(PathExists(alternate_input_file));
509 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, pref_store->ReadPrefs());
511 ASSERT_TRUE(PathExists(input_file));
512 ASSERT_FALSE(PathExists(alternate_input_file));
514 EXPECT_FALSE(pref_store->ReadOnly());
515 EXPECT_TRUE(pref_store->IsInitializationComplete());
517 // The JSON file looks like this:
518 // {
519 // "homepage": "http://www.cnn.com",
520 // "some_directory": "/usr/local/",
521 // "tabs": {
522 // "new_windows_in_tabs": true,
523 // "max_tabs": 20
524 // }
525 // }
527 RunBasicJsonPrefStoreTest(
528 pref_store.get(), input_file, data_dir_.AppendASCII("write.golden.json"));
531 TEST_F(JsonPrefStoreTest, AlternateFileIgnoredWhenMainFileExists) {
532 ASSERT_TRUE(
533 base::CopyFile(data_dir_.AppendASCII("read.json"),
534 temp_dir_.path().AppendASCII("write.json")));
535 ASSERT_TRUE(
536 base::CopyFile(data_dir_.AppendASCII("invalid.json"),
537 temp_dir_.path().AppendASCII("alternate.json")));
539 // Test that the alternate file is ignored and that the read occurs from the
540 // existing main file. There is no attempt at even deleting the alternate
541 // file as this scenario should never happen in normal user-data-dirs.
542 base::FilePath input_file = temp_dir_.path().AppendASCII("write.json");
543 base::FilePath alternate_input_file =
544 temp_dir_.path().AppendASCII("alternate.json");
545 ASSERT_TRUE(PathExists(input_file));
546 ASSERT_TRUE(PathExists(alternate_input_file));
547 scoped_refptr<JsonPrefStore> pref_store = new JsonPrefStore(
548 input_file,
549 alternate_input_file,
550 message_loop_.message_loop_proxy().get(),
551 scoped_ptr<PrefFilter>());
553 ASSERT_TRUE(PathExists(input_file));
554 ASSERT_TRUE(PathExists(alternate_input_file));
555 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, pref_store->ReadPrefs());
557 ASSERT_TRUE(PathExists(input_file));
558 ASSERT_TRUE(PathExists(alternate_input_file));
560 EXPECT_FALSE(pref_store->ReadOnly());
561 EXPECT_TRUE(pref_store->IsInitializationComplete());
563 // The JSON file looks like this:
564 // {
565 // "homepage": "http://www.cnn.com",
566 // "some_directory": "/usr/local/",
567 // "tabs": {
568 // "new_windows_in_tabs": true,
569 // "max_tabs": 20
570 // }
571 // }
573 RunBasicJsonPrefStoreTest(
574 pref_store.get(), input_file, data_dir_.AppendASCII("write.golden.json"));
577 TEST_F(JsonPrefStoreTest, AlternateFileDNE) {
578 ASSERT_TRUE(
579 base::CopyFile(data_dir_.AppendASCII("read.json"),
580 temp_dir_.path().AppendASCII("write.json")));
582 // Test that the basic read works fine when an alternate file is specified but
583 // does not exist.
584 base::FilePath input_file = temp_dir_.path().AppendASCII("write.json");
585 base::FilePath alternate_input_file =
586 temp_dir_.path().AppendASCII("alternate.json");
587 ASSERT_TRUE(PathExists(input_file));
588 ASSERT_FALSE(PathExists(alternate_input_file));
589 scoped_refptr<JsonPrefStore> pref_store = new JsonPrefStore(
590 input_file,
591 alternate_input_file,
592 message_loop_.message_loop_proxy().get(),
593 scoped_ptr<PrefFilter>());
595 ASSERT_TRUE(PathExists(input_file));
596 ASSERT_FALSE(PathExists(alternate_input_file));
597 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, pref_store->ReadPrefs());
599 ASSERT_TRUE(PathExists(input_file));
600 ASSERT_FALSE(PathExists(alternate_input_file));
602 EXPECT_FALSE(pref_store->ReadOnly());
603 EXPECT_TRUE(pref_store->IsInitializationComplete());
605 // The JSON file looks like this:
606 // {
607 // "homepage": "http://www.cnn.com",
608 // "some_directory": "/usr/local/",
609 // "tabs": {
610 // "new_windows_in_tabs": true,
611 // "max_tabs": 20
612 // }
613 // }
615 RunBasicJsonPrefStoreTest(
616 pref_store.get(), input_file, data_dir_.AppendASCII("write.golden.json"));
619 TEST_F(JsonPrefStoreTest, BasicAsyncWithAlternateFile) {
620 ASSERT_TRUE(
621 base::CopyFile(data_dir_.AppendASCII("read.json"),
622 temp_dir_.path().AppendASCII("alternate.json")));
624 // Test that the alternate file is moved to the main file and read as-is from
625 // there even when the read is made asynchronously.
626 base::FilePath input_file = temp_dir_.path().AppendASCII("write.json");
627 base::FilePath alternate_input_file =
628 temp_dir_.path().AppendASCII("alternate.json");
629 ASSERT_FALSE(PathExists(input_file));
630 ASSERT_TRUE(PathExists(alternate_input_file));
631 scoped_refptr<JsonPrefStore> pref_store = new JsonPrefStore(
632 input_file,
633 alternate_input_file,
634 message_loop_.message_loop_proxy().get(),
635 scoped_ptr<PrefFilter>());
637 ASSERT_FALSE(PathExists(input_file));
638 ASSERT_TRUE(PathExists(alternate_input_file));
641 MockPrefStoreObserver mock_observer;
642 pref_store->AddObserver(&mock_observer);
644 MockReadErrorDelegate* mock_error_delegate = new MockReadErrorDelegate;
645 pref_store->ReadPrefsAsync(mock_error_delegate);
647 EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(1);
648 EXPECT_CALL(*mock_error_delegate,
649 OnError(PersistentPrefStore::PREF_READ_ERROR_NONE)).Times(0);
650 RunLoop().RunUntilIdle();
651 pref_store->RemoveObserver(&mock_observer);
653 EXPECT_FALSE(pref_store->ReadOnly());
654 EXPECT_TRUE(pref_store->IsInitializationComplete());
657 ASSERT_TRUE(PathExists(input_file));
658 ASSERT_FALSE(PathExists(alternate_input_file));
660 // The JSON file looks like this:
661 // {
662 // "homepage": "http://www.cnn.com",
663 // "some_directory": "/usr/local/",
664 // "tabs": {
665 // "new_windows_in_tabs": true,
666 // "max_tabs": 20
667 // }
668 // }
670 RunBasicJsonPrefStoreTest(
671 pref_store.get(), input_file, data_dir_.AppendASCII("write.golden.json"));
674 } // namespace base