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 "components/prefs/json_pref_store.h" | 5 #include "components/prefs/json_pref_store.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <memory> | 9 #include <memory> |
10 #include <utility> | 10 #include <utility> |
11 | 11 |
12 #include "base/bind.h" | 12 #include "base/bind.h" |
13 #include "base/files/file_util.h" | 13 #include "base/files/file_util.h" |
14 #include "base/files/scoped_temp_dir.h" | 14 #include "base/files/scoped_temp_dir.h" |
15 #include "base/location.h" | 15 #include "base/location.h" |
16 #include "base/macros.h" | 16 #include "base/macros.h" |
17 #include "base/memory/ptr_util.h" | 17 #include "base/memory/ptr_util.h" |
18 #include "base/memory/ref_counted.h" | 18 #include "base/memory/ref_counted.h" |
19 #include "base/message_loop/message_loop.h" | 19 #include "base/message_loop/message_loop.h" |
20 #include "base/metrics/histogram_samples.h" | 20 #include "base/metrics/histogram_samples.h" |
21 #include "base/path_service.h" | 21 #include "base/path_service.h" |
22 #include "base/run_loop.h" | 22 #include "base/run_loop.h" |
23 #include "base/single_thread_task_runner.h" | 23 #include "base/single_thread_task_runner.h" |
24 #include "base/strings/string_number_conversions.h" | 24 #include "base/strings/string_number_conversions.h" |
25 #include "base/strings/string_util.h" | 25 #include "base/strings/string_util.h" |
26 #include "base/strings/utf_string_conversions.h" | 26 #include "base/strings/utf_string_conversions.h" |
27 #include "base/test/histogram_tester.h" | 27 #include "base/test/histogram_tester.h" |
28 #include "base/test/simple_test_clock.h" | 28 #include "base/test/simple_test_clock.h" |
| 29 #include "base/threading/sequenced_task_runner_handle.h" |
29 #include "base/threading/sequenced_worker_pool.h" | 30 #include "base/threading/sequenced_worker_pool.h" |
30 #include "base/threading/thread.h" | 31 #include "base/threading/thread.h" |
31 #include "base/values.h" | 32 #include "base/values.h" |
32 #include "components/prefs/pref_filter.h" | 33 #include "components/prefs/pref_filter.h" |
33 #include "testing/gmock/include/gmock/gmock.h" | 34 #include "testing/gmock/include/gmock/gmock.h" |
34 #include "testing/gtest/include/gtest/gtest.h" | 35 #include "testing/gtest/include/gtest/gtest.h" |
35 | 36 |
36 namespace base { | 37 namespace base { |
37 namespace { | 38 namespace { |
38 | 39 |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 }; | 115 }; |
115 | 116 |
116 class MockReadErrorDelegate : public PersistentPrefStore::ReadErrorDelegate { | 117 class MockReadErrorDelegate : public PersistentPrefStore::ReadErrorDelegate { |
117 public: | 118 public: |
118 MOCK_METHOD1(OnError, void(PersistentPrefStore::PrefReadError)); | 119 MOCK_METHOD1(OnError, void(PersistentPrefStore::PrefReadError)); |
119 }; | 120 }; |
120 | 121 |
121 } // namespace | 122 } // namespace |
122 | 123 |
123 class JsonPrefStoreTest : public testing::Test { | 124 class JsonPrefStoreTest : public testing::Test { |
| 125 public: |
| 126 JsonPrefStoreTest() = default; |
| 127 |
124 protected: | 128 protected: |
125 void SetUp() override { | 129 void SetUp() override { |
126 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); | 130 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
127 } | 131 } |
128 | 132 |
129 void TearDown() override { | 133 void TearDown() override { |
130 // Make sure all pending tasks have been processed (e.g., deleting the | 134 // Make sure all pending tasks have been processed (e.g., deleting the |
131 // JsonPrefStore may post write tasks). | 135 // JsonPrefStore may post write tasks). |
132 RunLoop().RunUntilIdle(); | 136 RunLoop().RunUntilIdle(); |
133 } | 137 } |
134 | 138 |
135 // The path to temporary directory used to contain the test operations. | 139 // The path to temporary directory used to contain the test operations. |
136 base::ScopedTempDir temp_dir_; | 140 base::ScopedTempDir temp_dir_; |
137 // A message loop that we can use as the file thread message loop. | 141 // A message loop that we can use as the file thread message loop. |
138 MessageLoop message_loop_; | 142 MessageLoop message_loop_; |
| 143 |
| 144 DISALLOW_COPY_AND_ASSIGN(JsonPrefStoreTest); |
139 }; | 145 }; |
140 | 146 |
141 // Test fallback behavior for a nonexistent file. | 147 // Test fallback behavior for a nonexistent file. |
142 TEST_F(JsonPrefStoreTest, NonExistentFile) { | 148 TEST_F(JsonPrefStoreTest, NonExistentFile) { |
143 base::FilePath bogus_input_file = temp_dir_.path().AppendASCII("read.txt"); | 149 base::FilePath bogus_input_file = temp_dir_.path().AppendASCII("read.txt"); |
144 ASSERT_FALSE(PathExists(bogus_input_file)); | 150 ASSERT_FALSE(PathExists(bogus_input_file)); |
145 scoped_refptr<JsonPrefStore> pref_store = | 151 scoped_refptr<JsonPrefStore> pref_store = |
146 new JsonPrefStore(bogus_input_file, message_loop_.task_runner(), | 152 new JsonPrefStore(bogus_input_file, message_loop_.task_runner(), |
147 std::unique_ptr<PrefFilter>()); | 153 std::unique_ptr<PrefFilter>()); |
148 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE, | 154 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE, |
(...skipping 661 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
810 histogram.ReportOutstandingWrites(); | 816 histogram.ReportOutstandingWrites(); |
811 std::string histogram_name = histogram.GetHistogram()->histogram_name(); | 817 std::string histogram_name = histogram.GetHistogram()->histogram_name(); |
812 histogram_tester.ExpectBucketCount(histogram_name, 0, 3); | 818 histogram_tester.ExpectBucketCount(histogram_name, 0, 3); |
813 histogram_tester.ExpectBucketCount(histogram_name, 1, 1); | 819 histogram_tester.ExpectBucketCount(histogram_name, 1, 1); |
814 histogram_tester.ExpectBucketCount(histogram_name, 2, 1); | 820 histogram_tester.ExpectBucketCount(histogram_name, 2, 1); |
815 histogram_tester.ExpectBucketCount(histogram_name, 3, 1); | 821 histogram_tester.ExpectBucketCount(histogram_name, 3, 1); |
816 histogram_tester.ExpectTotalCount(histogram_name, 6); | 822 histogram_tester.ExpectTotalCount(histogram_name, 6); |
817 } | 823 } |
818 | 824 |
819 class JsonPrefStoreLossyWriteTest : public JsonPrefStoreTest { | 825 class JsonPrefStoreLossyWriteTest : public JsonPrefStoreTest { |
| 826 public: |
| 827 JsonPrefStoreLossyWriteTest() = default; |
| 828 |
820 protected: | 829 protected: |
821 void SetUp() override { | 830 void SetUp() override { |
822 JsonPrefStoreTest::SetUp(); | 831 JsonPrefStoreTest::SetUp(); |
823 test_file_ = temp_dir_.path().AppendASCII("test.json"); | 832 test_file_ = temp_dir_.path().AppendASCII("test.json"); |
824 } | 833 } |
825 | 834 |
826 // Creates a JsonPrefStore with the given |file_writer|. | |
827 scoped_refptr<JsonPrefStore> CreatePrefStore() { | 835 scoped_refptr<JsonPrefStore> CreatePrefStore() { |
828 return new JsonPrefStore(test_file_, message_loop_.task_runner(), | 836 return new JsonPrefStore(test_file_, message_loop_.task_runner(), |
829 std::unique_ptr<PrefFilter>()); | 837 std::unique_ptr<PrefFilter>()); |
830 } | 838 } |
831 | 839 |
832 // Return the ImportantFileWriter for a given JsonPrefStore. | 840 // Return the ImportantFileWriter for a given JsonPrefStore. |
833 ImportantFileWriter* GetImportantFileWriter( | 841 ImportantFileWriter* GetImportantFileWriter(JsonPrefStore* pref_store) { |
834 scoped_refptr<JsonPrefStore> pref_store) { | |
835 return &(pref_store->writer_); | 842 return &(pref_store->writer_); |
836 } | 843 } |
837 | 844 |
838 // Get the contents of kTestFile. Pumps the message loop before returning the | 845 // Get the contents of kTestFile. Pumps the message loop before returning the |
839 // result. | 846 // result. |
840 std::string GetTestFileContents() { | 847 std::string GetTestFileContents() { |
841 RunLoop().RunUntilIdle(); | 848 RunLoop().RunUntilIdle(); |
842 std::string file_contents; | 849 std::string file_contents; |
843 ReadFileToString(test_file_, &file_contents); | 850 ReadFileToString(test_file_, &file_contents); |
844 return file_contents; | 851 return file_contents; |
845 } | 852 } |
846 | 853 |
847 private: | 854 private: |
848 base::FilePath test_file_; | 855 base::FilePath test_file_; |
| 856 |
| 857 DISALLOW_COPY_AND_ASSIGN(JsonPrefStoreLossyWriteTest); |
849 }; | 858 }; |
850 | 859 |
851 TEST_F(JsonPrefStoreLossyWriteTest, LossyWriteBasic) { | 860 TEST_F(JsonPrefStoreLossyWriteTest, LossyWriteBasic) { |
852 scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore(); | 861 scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore(); |
853 ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store); | 862 ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store.get()); |
854 | 863 |
855 // Set a normal pref and check that it gets scheduled to be written. | 864 // Set a normal pref and check that it gets scheduled to be written. |
856 ASSERT_FALSE(file_writer->HasPendingWrite()); | 865 ASSERT_FALSE(file_writer->HasPendingWrite()); |
857 pref_store->SetValue("normal", base::MakeUnique<base::StringValue>("normal"), | 866 pref_store->SetValue("normal", base::MakeUnique<base::StringValue>("normal"), |
858 WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS); | 867 WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS); |
859 ASSERT_TRUE(file_writer->HasPendingWrite()); | 868 ASSERT_TRUE(file_writer->HasPendingWrite()); |
860 file_writer->DoScheduledWrite(); | 869 file_writer->DoScheduledWrite(); |
861 ASSERT_EQ("{\"normal\":\"normal\"}", GetTestFileContents()); | 870 ASSERT_EQ("{\"normal\":\"normal\"}", GetTestFileContents()); |
862 ASSERT_FALSE(file_writer->HasPendingWrite()); | 871 ASSERT_FALSE(file_writer->HasPendingWrite()); |
863 | 872 |
(...skipping 25 matching lines...) Expand all Loading... |
889 // Call CommitPendingWrite and check that the lossy pref and the normal pref | 898 // Call CommitPendingWrite and check that the lossy pref and the normal pref |
890 // are there with the last values set above. | 899 // are there with the last values set above. |
891 pref_store->CommitPendingWrite(); | 900 pref_store->CommitPendingWrite(); |
892 ASSERT_FALSE(file_writer->HasPendingWrite()); | 901 ASSERT_FALSE(file_writer->HasPendingWrite()); |
893 ASSERT_EQ("{\"lossy\":\"lossy\",\"normal\":\"normal\"}", | 902 ASSERT_EQ("{\"lossy\":\"lossy\",\"normal\":\"normal\"}", |
894 GetTestFileContents()); | 903 GetTestFileContents()); |
895 } | 904 } |
896 | 905 |
897 TEST_F(JsonPrefStoreLossyWriteTest, LossyWriteMixedLossyFirst) { | 906 TEST_F(JsonPrefStoreLossyWriteTest, LossyWriteMixedLossyFirst) { |
898 scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore(); | 907 scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore(); |
899 ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store); | 908 ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store.get()); |
900 | 909 |
901 // Set a lossy pref and check that it is not scheduled to be written. | 910 // Set a lossy pref and check that it is not scheduled to be written. |
902 ASSERT_FALSE(file_writer->HasPendingWrite()); | 911 ASSERT_FALSE(file_writer->HasPendingWrite()); |
903 pref_store->SetValue("lossy", base::MakeUnique<base::StringValue>("lossy"), | 912 pref_store->SetValue("lossy", base::MakeUnique<base::StringValue>("lossy"), |
904 WriteablePrefStore::LOSSY_PREF_WRITE_FLAG); | 913 WriteablePrefStore::LOSSY_PREF_WRITE_FLAG); |
905 ASSERT_FALSE(file_writer->HasPendingWrite()); | 914 ASSERT_FALSE(file_writer->HasPendingWrite()); |
906 | 915 |
907 // Set a normal pref and check that it is scheduled to be written. | 916 // Set a normal pref and check that it is scheduled to be written. |
908 pref_store->SetValue("normal", base::MakeUnique<base::StringValue>("normal"), | 917 pref_store->SetValue("normal", base::MakeUnique<base::StringValue>("normal"), |
909 WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS); | 918 WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS); |
910 ASSERT_TRUE(file_writer->HasPendingWrite()); | 919 ASSERT_TRUE(file_writer->HasPendingWrite()); |
911 | 920 |
912 // Call DoScheduledWrite and check both prefs get written. | 921 // Call DoScheduledWrite and check both prefs get written. |
913 file_writer->DoScheduledWrite(); | 922 file_writer->DoScheduledWrite(); |
914 ASSERT_EQ("{\"lossy\":\"lossy\",\"normal\":\"normal\"}", | 923 ASSERT_EQ("{\"lossy\":\"lossy\",\"normal\":\"normal\"}", |
915 GetTestFileContents()); | 924 GetTestFileContents()); |
916 ASSERT_FALSE(file_writer->HasPendingWrite()); | 925 ASSERT_FALSE(file_writer->HasPendingWrite()); |
917 } | 926 } |
918 | 927 |
919 TEST_F(JsonPrefStoreLossyWriteTest, LossyWriteMixedLossySecond) { | 928 TEST_F(JsonPrefStoreLossyWriteTest, LossyWriteMixedLossySecond) { |
920 scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore(); | 929 scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore(); |
921 ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store); | 930 ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store.get()); |
922 | 931 |
923 // Set a normal pref and check that it is scheduled to be written. | 932 // Set a normal pref and check that it is scheduled to be written. |
924 ASSERT_FALSE(file_writer->HasPendingWrite()); | 933 ASSERT_FALSE(file_writer->HasPendingWrite()); |
925 pref_store->SetValue("normal", base::MakeUnique<base::StringValue>("normal"), | 934 pref_store->SetValue("normal", base::MakeUnique<base::StringValue>("normal"), |
926 WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS); | 935 WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS); |
927 ASSERT_TRUE(file_writer->HasPendingWrite()); | 936 ASSERT_TRUE(file_writer->HasPendingWrite()); |
928 | 937 |
929 // Set a lossy pref and check that the write is still scheduled. | 938 // Set a lossy pref and check that the write is still scheduled. |
930 pref_store->SetValue("lossy", base::MakeUnique<base::StringValue>("lossy"), | 939 pref_store->SetValue("lossy", base::MakeUnique<base::StringValue>("lossy"), |
931 WriteablePrefStore::LOSSY_PREF_WRITE_FLAG); | 940 WriteablePrefStore::LOSSY_PREF_WRITE_FLAG); |
932 ASSERT_TRUE(file_writer->HasPendingWrite()); | 941 ASSERT_TRUE(file_writer->HasPendingWrite()); |
933 | 942 |
934 // Call DoScheduledWrite and check both prefs get written. | 943 // Call DoScheduledWrite and check both prefs get written. |
935 file_writer->DoScheduledWrite(); | 944 file_writer->DoScheduledWrite(); |
936 ASSERT_EQ("{\"lossy\":\"lossy\",\"normal\":\"normal\"}", | 945 ASSERT_EQ("{\"lossy\":\"lossy\",\"normal\":\"normal\"}", |
937 GetTestFileContents()); | 946 GetTestFileContents()); |
938 ASSERT_FALSE(file_writer->HasPendingWrite()); | 947 ASSERT_FALSE(file_writer->HasPendingWrite()); |
939 } | 948 } |
940 | 949 |
941 TEST_F(JsonPrefStoreLossyWriteTest, ScheduleLossyWrite) { | 950 TEST_F(JsonPrefStoreLossyWriteTest, ScheduleLossyWrite) { |
942 scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore(); | 951 scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore(); |
943 ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store); | 952 ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store.get()); |
944 | 953 |
945 // Set a lossy pref and check that it is not scheduled to be written. | 954 // Set a lossy pref and check that it is not scheduled to be written. |
946 pref_store->SetValue("lossy", base::MakeUnique<base::StringValue>("lossy"), | 955 pref_store->SetValue("lossy", base::MakeUnique<base::StringValue>("lossy"), |
947 WriteablePrefStore::LOSSY_PREF_WRITE_FLAG); | 956 WriteablePrefStore::LOSSY_PREF_WRITE_FLAG); |
948 ASSERT_FALSE(file_writer->HasPendingWrite()); | 957 ASSERT_FALSE(file_writer->HasPendingWrite()); |
949 | 958 |
950 // Schedule pending lossy writes and check that it is scheduled. | 959 // Schedule pending lossy writes and check that it is scheduled. |
951 pref_store->SchedulePendingLossyWrites(); | 960 pref_store->SchedulePendingLossyWrites(); |
952 ASSERT_TRUE(file_writer->HasPendingWrite()); | 961 ASSERT_TRUE(file_writer->HasPendingWrite()); |
953 | 962 |
954 // Call CommitPendingWrite and check that the lossy pref is there with the | 963 // Call CommitPendingWrite and check that the lossy pref is there with the |
955 // last value set above. | 964 // last value set above. |
956 pref_store->CommitPendingWrite(); | 965 pref_store->CommitPendingWrite(); |
957 ASSERT_FALSE(file_writer->HasPendingWrite()); | 966 ASSERT_FALSE(file_writer->HasPendingWrite()); |
958 ASSERT_EQ("{\"lossy\":\"lossy\"}", GetTestFileContents()); | 967 ASSERT_EQ("{\"lossy\":\"lossy\"}", GetTestFileContents()); |
959 } | 968 } |
960 | 969 |
961 } // namespace base | 970 class SuccessfulWriteReplyObserver { |
| 971 public: |
| 972 SuccessfulWriteReplyObserver() = default; |
| 973 |
| 974 // Returns true if a successful write was observed via on_successful_write() |
| 975 // and resets the observation state to false regardless. |
| 976 bool GetAndResetObservationState() { |
| 977 bool was_successful_write_observed = successful_write_reply_observed_; |
| 978 successful_write_reply_observed_ = false; |
| 979 return was_successful_write_observed; |
| 980 } |
| 981 |
| 982 // Register OnWrite() to be called on the next write of |json_pref_store|. |
| 983 void ObserveNextWriteCallback(JsonPrefStore* json_pref_store); |
| 984 |
| 985 void OnSuccessfulWrite() { |
| 986 EXPECT_FALSE(successful_write_reply_observed_); |
| 987 successful_write_reply_observed_ = true; |
| 988 } |
| 989 |
| 990 private: |
| 991 bool successful_write_reply_observed_ = false; |
| 992 |
| 993 DISALLOW_COPY_AND_ASSIGN(SuccessfulWriteReplyObserver); |
| 994 }; |
| 995 |
| 996 void SuccessfulWriteReplyObserver::ObserveNextWriteCallback( |
| 997 JsonPrefStore* json_pref_store) { |
| 998 json_pref_store->RegisterOnNextSuccessfulWriteReply( |
| 999 base::Bind(&SuccessfulWriteReplyObserver::OnSuccessfulWrite, |
| 1000 base::Unretained(this))); |
| 1001 } |
| 1002 |
| 1003 enum WriteCallbackObservationState { |
| 1004 NOT_CALLED, |
| 1005 CALLED_WITH_ERROR, |
| 1006 CALLED_WITH_SUCCESS, |
| 1007 }; |
| 1008 |
| 1009 class WriteCallbackObserver { |
| 1010 public: |
| 1011 WriteCallbackObserver() = default; |
| 1012 |
| 1013 // Register OnWrite() to be called on the next write of |json_pref_store|. |
| 1014 void ObserveNextWriteCallback(JsonPrefStore* json_pref_store); |
| 1015 |
| 1016 // Returns true if a write was observed via OnWrite() |
| 1017 // and resets the observation state to false regardless. |
| 1018 WriteCallbackObservationState GetAndResetObservationState(); |
| 1019 |
| 1020 void OnWrite(bool success) { |
| 1021 EXPECT_EQ(NOT_CALLED, observation_state_); |
| 1022 observation_state_ = success ? CALLED_WITH_SUCCESS : CALLED_WITH_ERROR; |
| 1023 } |
| 1024 |
| 1025 private: |
| 1026 WriteCallbackObservationState observation_state_ = NOT_CALLED; |
| 1027 |
| 1028 DISALLOW_COPY_AND_ASSIGN(WriteCallbackObserver); |
| 1029 }; |
| 1030 |
| 1031 void WriteCallbackObserver::ObserveNextWriteCallback(JsonPrefStore* writer) { |
| 1032 writer->RegisterOnNextWriteSynchronousCallback( |
| 1033 base::Bind(&WriteCallbackObserver::OnWrite, base::Unretained(this))); |
| 1034 } |
| 1035 |
| 1036 WriteCallbackObservationState |
| 1037 WriteCallbackObserver::GetAndResetObservationState() { |
| 1038 WriteCallbackObservationState state = observation_state_; |
| 1039 observation_state_ = NOT_CALLED; |
| 1040 return state; |
| 1041 } |
| 1042 |
| 1043 class JsonPrefStoreCallbackTest : public JsonPrefStoreTest { |
| 1044 public: |
| 1045 JsonPrefStoreCallbackTest() = default; |
| 1046 |
| 1047 protected: |
| 1048 void SetUp() override { |
| 1049 JsonPrefStoreTest::SetUp(); |
| 1050 test_file_ = temp_dir_.path().AppendASCII("test.json"); |
| 1051 } |
| 1052 |
| 1053 scoped_refptr<JsonPrefStore> CreatePrefStore() { |
| 1054 return new JsonPrefStore(test_file_, message_loop_.task_runner(), |
| 1055 std::unique_ptr<PrefFilter>()); |
| 1056 } |
| 1057 |
| 1058 // Return the ImportantFileWriter for a given JsonPrefStore. |
| 1059 ImportantFileWriter* GetImportantFileWriter(JsonPrefStore* pref_store) { |
| 1060 return &(pref_store->writer_); |
| 1061 } |
| 1062 |
| 1063 void TriggerFakeWriteForCallback(JsonPrefStore* pref_store, bool success) { |
| 1064 JsonPrefStore::PostWriteCallback( |
| 1065 base::Bind(&JsonPrefStore::RunOrScheduleNextSuccessfulWriteCallback, |
| 1066 pref_store->AsWeakPtr()), |
| 1067 base::Bind(&WriteCallbackObserver::OnWrite, |
| 1068 base::Unretained(&write_callback_observer_)), |
| 1069 base::SequencedTaskRunnerHandle::Get(), success); |
| 1070 } |
| 1071 |
| 1072 SuccessfulWriteReplyObserver successful_write_reply_observer_; |
| 1073 WriteCallbackObserver write_callback_observer_; |
| 1074 |
| 1075 private: |
| 1076 base::FilePath test_file_; |
| 1077 |
| 1078 DISALLOW_COPY_AND_ASSIGN(JsonPrefStoreCallbackTest); |
| 1079 }; |
| 1080 |
| 1081 TEST_F(JsonPrefStoreCallbackTest, TestPostWriteCallback) { |
| 1082 scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore(); |
| 1083 ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store.get()); |
| 1084 |
| 1085 // Test RegisterOnNextWriteSynchronousCallback after |
| 1086 // RegisterOnNextSuccessfulWriteReply. |
| 1087 successful_write_reply_observer_.ObserveNextWriteCallback(pref_store.get()); |
| 1088 write_callback_observer_.ObserveNextWriteCallback(pref_store.get()); |
| 1089 file_writer->WriteNow(MakeUnique<std::string>("foo")); |
| 1090 RunLoop().RunUntilIdle(); |
| 1091 EXPECT_TRUE(successful_write_reply_observer_.GetAndResetObservationState()); |
| 1092 EXPECT_TRUE(write_callback_observer_.GetAndResetObservationState()); |
| 1093 |
| 1094 // Test RegisterOnNextSuccessfulWriteReply after |
| 1095 // RegisterOnNextWriteSynchronousCallback. |
| 1096 successful_write_reply_observer_.ObserveNextWriteCallback(pref_store.get()); |
| 1097 write_callback_observer_.ObserveNextWriteCallback(pref_store.get()); |
| 1098 file_writer->WriteNow(MakeUnique<std::string>("foo")); |
| 1099 RunLoop().RunUntilIdle(); |
| 1100 EXPECT_TRUE(successful_write_reply_observer_.GetAndResetObservationState()); |
| 1101 EXPECT_TRUE(write_callback_observer_.GetAndResetObservationState()); |
| 1102 |
| 1103 // Test RegisterOnNextSuccessfulWriteReply only. |
| 1104 successful_write_reply_observer_.ObserveNextWriteCallback(pref_store.get()); |
| 1105 file_writer->WriteNow(MakeUnique<std::string>("foo")); |
| 1106 RunLoop().RunUntilIdle(); |
| 1107 EXPECT_TRUE(successful_write_reply_observer_.GetAndResetObservationState()); |
| 1108 EXPECT_FALSE(write_callback_observer_.GetAndResetObservationState()); |
| 1109 |
| 1110 // Test RegisterOnNextWriteSynchronousCallback only. |
| 1111 write_callback_observer_.ObserveNextWriteCallback(pref_store.get()); |
| 1112 file_writer->WriteNow(MakeUnique<std::string>("foo")); |
| 1113 RunLoop().RunUntilIdle(); |
| 1114 EXPECT_FALSE(successful_write_reply_observer_.GetAndResetObservationState()); |
| 1115 EXPECT_TRUE(write_callback_observer_.GetAndResetObservationState()); |
| 1116 } |
| 1117 |
| 1118 TEST_F(JsonPrefStoreCallbackTest, TestPostWriteCallbackWithFakeFailure) { |
| 1119 scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore(); |
| 1120 |
| 1121 // Confirm that the observers are invoked. |
| 1122 successful_write_reply_observer_.ObserveNextWriteCallback(pref_store.get()); |
| 1123 TriggerFakeWriteForCallback(pref_store.get(), true); |
| 1124 RunLoop().RunUntilIdle(); |
| 1125 EXPECT_TRUE(successful_write_reply_observer_.GetAndResetObservationState()); |
| 1126 EXPECT_EQ(CALLED_WITH_SUCCESS, |
| 1127 write_callback_observer_.GetAndResetObservationState()); |
| 1128 |
| 1129 // Confirm that the observation states were reset. |
| 1130 EXPECT_FALSE(successful_write_reply_observer_.GetAndResetObservationState()); |
| 1131 EXPECT_EQ(NOT_CALLED, write_callback_observer_.GetAndResetObservationState()); |
| 1132 |
| 1133 // Confirm that re-installing the observers works for another write. |
| 1134 successful_write_reply_observer_.ObserveNextWriteCallback(pref_store.get()); |
| 1135 TriggerFakeWriteForCallback(pref_store.get(), true); |
| 1136 RunLoop().RunUntilIdle(); |
| 1137 EXPECT_TRUE(successful_write_reply_observer_.GetAndResetObservationState()); |
| 1138 EXPECT_EQ(CALLED_WITH_SUCCESS, |
| 1139 write_callback_observer_.GetAndResetObservationState()); |
| 1140 |
| 1141 // Confirm that the successful observer is not invoked by an unsuccessful |
| 1142 // write, and that the synchronous observer is invoked. |
| 1143 successful_write_reply_observer_.ObserveNextWriteCallback(pref_store.get()); |
| 1144 TriggerFakeWriteForCallback(pref_store.get(), false); |
| 1145 RunLoop().RunUntilIdle(); |
| 1146 EXPECT_FALSE(successful_write_reply_observer_.GetAndResetObservationState()); |
| 1147 EXPECT_EQ(CALLED_WITH_ERROR, |
| 1148 write_callback_observer_.GetAndResetObservationState()); |
| 1149 |
| 1150 // Do a real write, and confirm that the successful observer was invoked after |
| 1151 // being set by |PostWriteCallback| by the last TriggerFakeWriteCallback. |
| 1152 ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store.get()); |
| 1153 file_writer->WriteNow(MakeUnique<std::string>("foo")); |
| 1154 RunLoop().RunUntilIdle(); |
| 1155 EXPECT_TRUE(successful_write_reply_observer_.GetAndResetObservationState()); |
| 1156 EXPECT_EQ(NOT_CALLED, write_callback_observer_.GetAndResetObservationState()); |
| 1157 } |
| 1158 |
| 1159 TEST_F(JsonPrefStoreCallbackTest, TestPostWriteCallbackDuringProfileDeath) { |
| 1160 // Create a JsonPrefStore and attach observers to it, then delete it by making |
| 1161 // it go out of scope to simulate profile switch or Chrome shutdown. |
| 1162 { |
| 1163 scoped_refptr<JsonPrefStore> soon_out_of_scope_pref_store = |
| 1164 CreatePrefStore(); |
| 1165 ImportantFileWriter* file_writer = |
| 1166 GetImportantFileWriter(soon_out_of_scope_pref_store.get()); |
| 1167 successful_write_reply_observer_.ObserveNextWriteCallback( |
| 1168 soon_out_of_scope_pref_store.get()); |
| 1169 write_callback_observer_.ObserveNextWriteCallback( |
| 1170 soon_out_of_scope_pref_store.get()); |
| 1171 file_writer->WriteNow(MakeUnique<std::string>("foo")); |
| 1172 } |
| 1173 RunLoop().RunUntilIdle(); |
| 1174 EXPECT_FALSE(successful_write_reply_observer_.GetAndResetObservationState()); |
| 1175 EXPECT_EQ(CALLED_WITH_SUCCESS, |
| 1176 write_callback_observer_.GetAndResetObservationState()); |
| 1177 } |
| 1178 |
| 1179 } // namespace base |
OLD | NEW |