OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/prefs/json_pref_store.h" | 5 #include "base/prefs/json_pref_store.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
9 #include "base/files/scoped_temp_dir.h" | 9 #include "base/files/scoped_temp_dir.h" |
10 #include "base/memory/ref_counted.h" | 10 #include "base/memory/ref_counted.h" |
(...skipping 26 matching lines...) Expand all Loading... |
37 // PrefFilter implementation: | 37 // PrefFilter implementation: |
38 virtual void FilterOnLoad( | 38 virtual void FilterOnLoad( |
39 const PostFilterOnLoadCallback& post_filter_on_load_callback, | 39 const PostFilterOnLoadCallback& post_filter_on_load_callback, |
40 scoped_ptr<base::DictionaryValue> pref_store_contents) OVERRIDE; | 40 scoped_ptr<base::DictionaryValue> pref_store_contents) OVERRIDE; |
41 virtual void FilterUpdate(const std::string& path) OVERRIDE {} | 41 virtual void FilterUpdate(const std::string& path) OVERRIDE {} |
42 virtual void FilterSerializeData( | 42 virtual void FilterSerializeData( |
43 const base::DictionaryValue* pref_store_contents) OVERRIDE {} | 43 const base::DictionaryValue* pref_store_contents) OVERRIDE {} |
44 | 44 |
45 bool has_intercepted_prefs() const { return intercepted_prefs_ != NULL; } | 45 bool has_intercepted_prefs() const { return intercepted_prefs_ != NULL; } |
46 | 46 |
47 // Finalize an intercepted read, handing |intercept_prefs_| back to its | 47 // Finalize an intercepted read, handing |intercepted_prefs_| back to its |
48 // JsonPrefStore. | 48 // JsonPrefStore. |
49 void ReleasePrefs(); | 49 void ReleasePrefs(); |
50 | 50 |
51 private: | 51 private: |
52 PostFilterOnLoadCallback post_filter_on_load_callback_; | 52 PostFilterOnLoadCallback post_filter_on_load_callback_; |
53 scoped_ptr<base::DictionaryValue> intercepted_prefs_; | 53 scoped_ptr<base::DictionaryValue> intercepted_prefs_; |
54 | 54 |
55 DISALLOW_COPY_AND_ASSIGN(InterceptingPrefFilter); | 55 DISALLOW_COPY_AND_ASSIGN(InterceptingPrefFilter); |
56 }; | 56 }; |
57 | 57 |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 ASSERT_FALSE(PathExists(bogus_input_file)); | 115 ASSERT_FALSE(PathExists(bogus_input_file)); |
116 scoped_refptr<JsonPrefStore> pref_store = new JsonPrefStore( | 116 scoped_refptr<JsonPrefStore> pref_store = new JsonPrefStore( |
117 bogus_input_file, | 117 bogus_input_file, |
118 message_loop_.message_loop_proxy().get(), | 118 message_loop_.message_loop_proxy().get(), |
119 scoped_ptr<PrefFilter>()); | 119 scoped_ptr<PrefFilter>()); |
120 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE, | 120 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE, |
121 pref_store->ReadPrefs()); | 121 pref_store->ReadPrefs()); |
122 EXPECT_FALSE(pref_store->ReadOnly()); | 122 EXPECT_FALSE(pref_store->ReadOnly()); |
123 } | 123 } |
124 | 124 |
| 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()); |
| 140 } |
| 141 |
125 // Test fallback behavior for an invalid file. | 142 // Test fallback behavior for an invalid file. |
126 TEST_F(JsonPrefStoreTest, InvalidFile) { | 143 TEST_F(JsonPrefStoreTest, InvalidFile) { |
127 base::FilePath invalid_file_original = data_dir_.AppendASCII("invalid.json"); | 144 base::FilePath invalid_file_original = data_dir_.AppendASCII("invalid.json"); |
128 base::FilePath invalid_file = temp_dir_.path().AppendASCII("invalid.json"); | 145 base::FilePath invalid_file = temp_dir_.path().AppendASCII("invalid.json"); |
129 ASSERT_TRUE(base::CopyFile(invalid_file_original, invalid_file)); | 146 ASSERT_TRUE(base::CopyFile(invalid_file_original, invalid_file)); |
130 scoped_refptr<JsonPrefStore> pref_store = | 147 scoped_refptr<JsonPrefStore> pref_store = |
131 new JsonPrefStore(invalid_file, | 148 new JsonPrefStore(invalid_file, |
132 message_loop_.message_loop_proxy().get(), | 149 message_loop_.message_loop_proxy().get(), |
133 scoped_ptr<PrefFilter>()); | 150 scoped_ptr<PrefFilter>()); |
134 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_JSON_PARSE, | 151 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_JSON_PARSE, |
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
462 // "tabs": { | 479 // "tabs": { |
463 // "new_windows_in_tabs": true, | 480 // "new_windows_in_tabs": true, |
464 // "max_tabs": 20 | 481 // "max_tabs": 20 |
465 // } | 482 // } |
466 // } | 483 // } |
467 | 484 |
468 RunBasicJsonPrefStoreTest( | 485 RunBasicJsonPrefStoreTest( |
469 pref_store.get(), input_file, data_dir_.AppendASCII("write.golden.json")); | 486 pref_store.get(), input_file, data_dir_.AppendASCII("write.golden.json")); |
470 } | 487 } |
471 | 488 |
| 489 TEST_F(JsonPrefStoreTest, AlternateFile) { |
| 490 ASSERT_TRUE( |
| 491 base::CopyFile(data_dir_.AppendASCII("read.json"), |
| 492 temp_dir_.path().AppendASCII("alternate.json"))); |
| 493 |
| 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>()); |
| 506 |
| 507 ASSERT_FALSE(PathExists(input_file)); |
| 508 ASSERT_TRUE(PathExists(alternate_input_file)); |
| 509 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, pref_store->ReadPrefs()); |
| 510 |
| 511 ASSERT_TRUE(PathExists(input_file)); |
| 512 ASSERT_FALSE(PathExists(alternate_input_file)); |
| 513 |
| 514 EXPECT_FALSE(pref_store->ReadOnly()); |
| 515 EXPECT_TRUE(pref_store->IsInitializationComplete()); |
| 516 |
| 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 // } |
| 526 |
| 527 RunBasicJsonPrefStoreTest( |
| 528 pref_store.get(), input_file, data_dir_.AppendASCII("write.golden.json")); |
| 529 } |
| 530 |
| 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"))); |
| 538 |
| 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>()); |
| 552 |
| 553 ASSERT_TRUE(PathExists(input_file)); |
| 554 ASSERT_TRUE(PathExists(alternate_input_file)); |
| 555 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, pref_store->ReadPrefs()); |
| 556 |
| 557 ASSERT_TRUE(PathExists(input_file)); |
| 558 ASSERT_TRUE(PathExists(alternate_input_file)); |
| 559 |
| 560 EXPECT_FALSE(pref_store->ReadOnly()); |
| 561 EXPECT_TRUE(pref_store->IsInitializationComplete()); |
| 562 |
| 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 // } |
| 572 |
| 573 RunBasicJsonPrefStoreTest( |
| 574 pref_store.get(), input_file, data_dir_.AppendASCII("write.golden.json")); |
| 575 } |
| 576 |
| 577 TEST_F(JsonPrefStoreTest, AlternateFileDNE) { |
| 578 ASSERT_TRUE( |
| 579 base::CopyFile(data_dir_.AppendASCII("read.json"), |
| 580 temp_dir_.path().AppendASCII("write.json"))); |
| 581 |
| 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>()); |
| 594 |
| 595 ASSERT_TRUE(PathExists(input_file)); |
| 596 ASSERT_FALSE(PathExists(alternate_input_file)); |
| 597 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, pref_store->ReadPrefs()); |
| 598 |
| 599 ASSERT_TRUE(PathExists(input_file)); |
| 600 ASSERT_FALSE(PathExists(alternate_input_file)); |
| 601 |
| 602 EXPECT_FALSE(pref_store->ReadOnly()); |
| 603 EXPECT_TRUE(pref_store->IsInitializationComplete()); |
| 604 |
| 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 // } |
| 614 |
| 615 RunBasicJsonPrefStoreTest( |
| 616 pref_store.get(), input_file, data_dir_.AppendASCII("write.golden.json")); |
| 617 } |
| 618 |
| 619 TEST_F(JsonPrefStoreTest, BasicAsyncWithAlternateFile) { |
| 620 ASSERT_TRUE( |
| 621 base::CopyFile(data_dir_.AppendASCII("read.json"), |
| 622 temp_dir_.path().AppendASCII("alternate.json"))); |
| 623 |
| 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>()); |
| 636 |
| 637 ASSERT_FALSE(PathExists(input_file)); |
| 638 ASSERT_TRUE(PathExists(alternate_input_file)); |
| 639 |
| 640 { |
| 641 MockPrefStoreObserver mock_observer; |
| 642 pref_store->AddObserver(&mock_observer); |
| 643 |
| 644 MockReadErrorDelegate* mock_error_delegate = new MockReadErrorDelegate; |
| 645 pref_store->ReadPrefsAsync(mock_error_delegate); |
| 646 |
| 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); |
| 652 |
| 653 EXPECT_FALSE(pref_store->ReadOnly()); |
| 654 EXPECT_TRUE(pref_store->IsInitializationComplete()); |
| 655 } |
| 656 |
| 657 ASSERT_TRUE(PathExists(input_file)); |
| 658 ASSERT_FALSE(PathExists(alternate_input_file)); |
| 659 |
| 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 // } |
| 669 |
| 670 RunBasicJsonPrefStoreTest( |
| 671 pref_store.get(), input_file, data_dir_.AppendASCII("write.golden.json")); |
| 672 } |
| 673 |
472 } // namespace base | 674 } // namespace base |
OLD | NEW |