Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(654)

Side by Side Diff: components/prefs/json_pref_store_unittest.cc

Issue 2299523003: Add synchronous callback support to important_file_writer.cc (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Try move logic from ImportantFileWriter to JsonPrefStore Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 912 matching lines...) Expand 10 before | Expand all | Expand 10 after
951 pref_store->SchedulePendingLossyWrites(); 952 pref_store->SchedulePendingLossyWrites();
952 ASSERT_TRUE(file_writer->HasPendingWrite()); 953 ASSERT_TRUE(file_writer->HasPendingWrite());
953 954
954 // Call CommitPendingWrite and check that the lossy pref is there with the 955 // Call CommitPendingWrite and check that the lossy pref is there with the
955 // last value set above. 956 // last value set above.
956 pref_store->CommitPendingWrite(); 957 pref_store->CommitPendingWrite();
957 ASSERT_FALSE(file_writer->HasPendingWrite()); 958 ASSERT_FALSE(file_writer->HasPendingWrite());
958 ASSERT_EQ("{\"lossy\":\"lossy\"}", GetTestFileContents()); 959 ASSERT_EQ("{\"lossy\":\"lossy\"}", GetTestFileContents());
959 } 960 }
960 961
961 } // namespace base 962 class SuccessfulWriteReplyObserver {
963 public:
964 SuccessfulWriteReplyObserver() : successful_write_reply_observed_(false) {}
965
966 // Returns true if a successful write was observed via on_successful_write()
967 // and resets the observation state to false regardless.
968 bool GetAndResetObservationState() {
969 bool was_successful_write_observed = successful_write_reply_observed_;
970 successful_write_reply_observed_ = false;
971 return was_successful_write_observed;
972 }
973
974 // Register OnWrite() to be called on the next write of |json_pref_store|.
975 void ObserveNextWriteCallback(JsonPrefStore* json_pref_store);
976
977 void OnSuccessfulWrite() {
978 EXPECT_FALSE(successful_write_reply_observed_);
979 successful_write_reply_observed_ = true;
980 }
981
982 private:
983 bool successful_write_reply_observed_;
gab 2016/09/19 18:01:30 Use C++11 member initialization (i.e. = false here
proberge 2016/09/19 21:24:26 Done.
984
985 DISALLOW_COPY_AND_ASSIGN(SuccessfulWriteReplyObserver);
986 };
987
988 void SuccessfulWriteReplyObserver::ObserveNextWriteCallback(
989 JsonPrefStore* json_pref_store) {
990 json_pref_store->RegisterOnNextSuccessfulWriteReply(
991 base::Bind(&SuccessfulWriteReplyObserver::OnSuccessfulWrite,
992 base::Unretained(this)));
993 }
994
995 enum WriteCallbackObservationState {
996 NOT_CALLED,
997 CALLED_WITH_ERROR,
998 CALLED_WITH_SUCCESS,
999 };
1000
1001 class WriteCallbackObserver {
1002 public:
1003 WriteCallbackObserver() : observation_state_(NOT_CALLED) {}
1004
1005 // Register OnWrite() to be called on the next write of |json_pref_store|.
1006 void ObserveNextWriteCallback(JsonPrefStore* json_pref_store);
1007
1008 // Returns true if a write was observed via OnWrite()
1009 // and resets the observation state to false regardless.
1010 WriteCallbackObservationState GetAndResetObservationState();
1011
1012 void OnWrite(bool success) {
1013 EXPECT_EQ(NOT_CALLED, observation_state_);
1014 observation_state_ = success ? CALLED_WITH_SUCCESS : CALLED_WITH_ERROR;
1015 }
1016
1017 private:
1018 WriteCallbackObservationState observation_state_;
gab 2016/09/19 18:01:31 C++11 member init here too
proberge 2016/09/19 21:24:25 Done.
1019
1020 DISALLOW_COPY_AND_ASSIGN(WriteCallbackObserver);
1021 };
1022
1023 void WriteCallbackObserver::ObserveNextWriteCallback(JsonPrefStore* writer) {
1024 writer->RegisterOnNextWriteCallback(
1025 base::Bind(&WriteCallbackObserver::OnWrite, base::Unretained(this)));
1026 }
1027
1028 WriteCallbackObservationState
1029 WriteCallbackObserver::GetAndResetObservationState() {
1030 WriteCallbackObservationState state = observation_state_;
1031 observation_state_ = NOT_CALLED;
1032 return state;
1033 }
1034
1035 class JsonPrefStoreCallbackTest : public JsonPrefStoreTest {
1036 protected:
1037 void SetUp() override {
1038 JsonPrefStoreTest::SetUp();
1039 test_file_ = temp_dir_.path().AppendASCII("test.json");
1040 }
1041
1042 // Creates a JsonPrefStore with the given |file_writer|.
gab 2016/09/19 18:01:31 |file_writer| refers to nothing?
proberge 2016/09/19 21:24:26 Copied the comment from line 827. Removed the comm
1043 scoped_refptr<JsonPrefStore> CreatePrefStore() {
1044 return new JsonPrefStore(test_file_, message_loop_.task_runner(),
1045 std::unique_ptr<PrefFilter>());
1046 }
1047
1048 // As above, but with a custom SequencedTaskRunner.
1049 scoped_refptr<JsonPrefStore> CreatePrefStore(
1050 scoped_refptr<SequencedTaskRunner> task_runner) {
gab 2016/09/19 18:01:30 Unused? Should there be a test with an independent
proberge 2016/09/19 21:24:26 I thought I needed it for TestPostWriteCallbackDur
gab 2016/09/20 01:27:41 I guess it wouldn't do much more than re-test Impo
1051 return new JsonPrefStore(test_file_, task_runner,
1052 std::unique_ptr<PrefFilter>());
1053 }
1054
1055 // Return the ImportantFileWriter for a given JsonPrefStore.
1056 ImportantFileWriter* GetImportantFileWriter(
1057 scoped_refptr<JsonPrefStore> pref_store) {
gab 2016/09/19 18:01:30 scoped_refptr<JsonPrefStore> as a parameter implic
proberge 2016/09/19 21:24:26 Was copied from line 834. Updated there as well.
1058 return &(pref_store->writer_);
1059 }
1060
1061 void TriggerFakeWriteForCallback(scoped_refptr<JsonPrefStore> pref_store,
gab 2016/09/19 18:01:30 Same here
proberge 2016/09/19 21:24:25 Done.
1062 bool success) {
1063 JsonPrefStore::PostWriteCallback(
1064 pref_store->AsWeakPtr(),
1065 base::Bind(&WriteCallbackObserver::OnWrite,
1066 base::Unretained(&write_callback_observer_)),
1067 base::SequencedTaskRunnerHandle::Get(), success);
1068 }
1069
1070 SuccessfulWriteReplyObserver successful_write_reply_observer_;
1071 WriteCallbackObserver write_callback_observer_;
1072
1073 private:
1074 base::FilePath test_file_;
1075 };
gab 2016/09/19 18:01:30 DISALLOW_COPY_AND_ASSIGN
proberge 2016/09/19 21:24:26 Looks like DISALLOW_COPY_AND_ASSIGN isn't happy wi
dcheng 2016/09/20 01:08:57 You'll have to give the test an explicit default c
gab 2016/09/20 01:27:41 This is because DISALLOW_COPY_AND_ASSIGN is implem
proberge 2016/09/20 15:15:52 Done.
1076
1077 TEST_F(JsonPrefStoreCallbackTest, TestPostWriteCallback) {
1078 scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore();
1079 ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store);
1080
1081 // Test RegisterOnNextWriteCallback after RegisterOnNextSuccessfulWriteReply.
1082 successful_write_reply_observer_.ObserveNextWriteCallback(pref_store.get());
1083 write_callback_observer_.ObserveNextWriteCallback(pref_store.get());
1084 file_writer->WriteNow(WrapUnique(new std::string("foo")));
1085 RunLoop().RunUntilIdle();
1086 EXPECT_TRUE(successful_write_reply_observer_.GetAndResetObservationState());
1087 EXPECT_TRUE(write_callback_observer_.GetAndResetObservationState());
1088
1089 // Test RegisterOnNextSuccessfulWriteReply after RegisterOnNextWriteCallback.
1090 successful_write_reply_observer_.ObserveNextWriteCallback(pref_store.get());
1091 write_callback_observer_.ObserveNextWriteCallback(pref_store.get());
1092 file_writer->WriteNow(WrapUnique(new std::string("foo")));
1093 RunLoop().RunUntilIdle();
1094 EXPECT_TRUE(successful_write_reply_observer_.GetAndResetObservationState());
1095 EXPECT_TRUE(write_callback_observer_.GetAndResetObservationState());
1096
1097 // Test RegisterOnNextSuccessfulWriteReply only.
1098 successful_write_reply_observer_.ObserveNextWriteCallback(pref_store.get());
1099 file_writer->WriteNow(WrapUnique(new std::string("foo")));
1100 RunLoop().RunUntilIdle();
1101 EXPECT_TRUE(successful_write_reply_observer_.GetAndResetObservationState());
1102 EXPECT_FALSE(write_callback_observer_.GetAndResetObservationState());
1103
1104 // Test RegisterOnNextWriteCallback only.
1105 write_callback_observer_.ObserveNextWriteCallback(pref_store.get());
1106 file_writer->WriteNow(WrapUnique(new std::string("foo")));
1107 RunLoop().RunUntilIdle();
1108 EXPECT_FALSE(successful_write_reply_observer_.GetAndResetObservationState());
1109 EXPECT_TRUE(write_callback_observer_.GetAndResetObservationState());
1110 }
1111
1112 TEST_F(JsonPrefStoreCallbackTest, TestPostWriteCallbackWithFakeFailure) {
1113 scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore();
1114
1115 // Confirm that the observers are invoked.
1116 successful_write_reply_observer_.ObserveNextWriteCallback(pref_store.get());
1117 TriggerFakeWriteForCallback(pref_store, true);
1118 RunLoop().RunUntilIdle();
1119 EXPECT_TRUE(successful_write_reply_observer_.GetAndResetObservationState());
1120 EXPECT_EQ(CALLED_WITH_SUCCESS,
1121 write_callback_observer_.GetAndResetObservationState());
1122
1123 // Confirm that the observation states were reset.
1124 EXPECT_FALSE(successful_write_reply_observer_.GetAndResetObservationState());
1125 EXPECT_EQ(NOT_CALLED, write_callback_observer_.GetAndResetObservationState());
1126
1127 // Confirm that re-installing the observers works for another write.
1128 successful_write_reply_observer_.ObserveNextWriteCallback(pref_store.get());
1129 TriggerFakeWriteForCallback(pref_store, true);
1130 RunLoop().RunUntilIdle();
1131 EXPECT_TRUE(successful_write_reply_observer_.GetAndResetObservationState());
1132 EXPECT_EQ(CALLED_WITH_SUCCESS,
1133 write_callback_observer_.GetAndResetObservationState());
1134
1135 // Confirm that the successful observer is not invoked by an unsuccessful
1136 // write, and that the synchronous observer is invoked.
1137 successful_write_reply_observer_.ObserveNextWriteCallback(pref_store.get());
1138 TriggerFakeWriteForCallback(pref_store, false);
1139 RunLoop().RunUntilIdle();
1140 EXPECT_FALSE(successful_write_reply_observer_.GetAndResetObservationState());
1141 EXPECT_EQ(CALLED_WITH_ERROR,
1142 write_callback_observer_.GetAndResetObservationState());
1143
1144 // Do a real write, and confirm that the successful observer was invoked after
1145 // being set by |PostWriteCallback| by the last TriggerFakeWriteCallback.
1146 ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store);
1147 file_writer->WriteNow(WrapUnique(new std::string("foo")));
1148 RunLoop().RunUntilIdle();
1149 EXPECT_TRUE(successful_write_reply_observer_.GetAndResetObservationState());
1150 EXPECT_EQ(NOT_CALLED, write_callback_observer_.GetAndResetObservationState());
1151 }
1152
1153 TEST_F(JsonPrefStoreCallbackTest, TestPostWriteCallbackDuringProfileDeath) {
1154 // Create a JsonPrefStore and attach observers to it, then delete it by making
1155 // it go out of scope to simulate profile switch or Chrome shutdown.
1156 {
1157 scoped_refptr<JsonPrefStore> soon_out_of_scope_pref_store =
1158 CreatePrefStore();
1159 ImportantFileWriter* file_writer =
1160 GetImportantFileWriter(soon_out_of_scope_pref_store);
1161 successful_write_reply_observer_.ObserveNextWriteCallback(
1162 soon_out_of_scope_pref_store.get());
1163 write_callback_observer_.ObserveNextWriteCallback(
1164 soon_out_of_scope_pref_store.get());
1165 file_writer->WriteNow(WrapUnique(new std::string("foo")));
1166 }
1167 RunLoop().RunUntilIdle();
1168 EXPECT_FALSE(successful_write_reply_observer_.GetAndResetObservationState());
1169 EXPECT_EQ(CALLED_WITH_SUCCESS,
1170 write_callback_observer_.GetAndResetObservationState());
1171 }
1172
1173 } // namespace base
OLDNEW
« components/prefs/json_pref_store.cc ('K') | « components/prefs/json_pref_store.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698