blob: 5673942a64ea82f3d3b2f3ff0e063ca08f4ae634 [file] [log] [blame]
[email protected]ea3e4972012-04-12 03:41:371// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]277404c22010-04-22 13:09:452// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
brettwf00b9b42016-02-01 22:11:385#include "components/prefs/json_pref_store.h"
[email protected]00c87822012-11-27 19:09:176
avi9ef8bb02015-12-24 05:29:367#include <stdint.h>
8
dcheng5f043bc2016-04-22 19:09:069#include <memory>
danakj0c8d4aa2015-11-25 05:29:5810#include <utility>
11
[email protected]e33c9512014-05-12 02:24:1312#include "base/bind.h"
Gabriel Charette788eaf62018-08-07 20:11:4613#include "base/compiler_specific.h"
[email protected]e3177dd52014-08-13 20:22:1414#include "base/files/file_util.h"
[email protected]ea1a3f62012-11-16 20:34:2315#include "base/files/scoped_temp_dir.h"
skyostil054861d2015-04-30 19:06:1516#include "base/location.h"
avi9ef8bb02015-12-24 05:29:3617#include "base/macros.h"
[email protected]3b63f8f42011-03-28 01:54:1518#include "base/memory/ref_counted.h"
raymesbfb910a2015-04-29 07:43:0919#include "base/metrics/histogram_samples.h"
[email protected]277404c22010-04-22 13:09:4520#include "base/path_service.h"
[email protected]f7b98b32013-02-05 08:14:1521#include "base/run_loop.h"
skyostil054861d2015-04-30 19:06:1522#include "base/single_thread_task_runner.h"
[email protected]dfa049e2013-02-07 02:57:2223#include "base/strings/string_number_conversions.h"
[email protected]d529cb02013-06-10 19:06:5724#include "base/strings/string_util.h"
[email protected]a4ea1f12013-06-07 18:37:0725#include "base/strings/utf_string_conversions.h"
Gabriel Charette788eaf62018-08-07 20:11:4626#include "base/synchronization/waitable_event.h"
Devlin Cronin69228f42018-06-01 17:25:1027#include "base/test/metrics/histogram_tester.h"
Francois Doray405dd2d2017-06-09 15:23:3328#include "base/test/scoped_task_environment.h"
raymesbfb910a2015-04-29 07:43:0929#include "base/test/simple_test_clock.h"
probergefc46ac12016-09-21 18:03:0030#include "base/threading/sequenced_task_runner_handle.h"
[email protected]34b99632011-01-01 01:01:0631#include "base/threading/thread.h"
[email protected]277404c22010-04-22 13:09:4532#include "base/values.h"
Francois Doray405dd2d2017-06-09 15:23:3333#include "components/prefs/persistent_pref_store_unittest.h"
brettwf00b9b42016-02-01 22:11:3834#include "components/prefs/pref_filter.h"
[email protected]845b43a82011-05-11 10:14:4335#include "testing/gmock/include/gmock/gmock.h"
[email protected]277404c22010-04-22 13:09:4536#include "testing/gtest/include/gtest/gtest.h"
37
[email protected]7e3ec42c2012-12-16 05:13:2138namespace base {
[email protected]845b43a82011-05-11 10:14:4339namespace {
40
[email protected]5bfdcfd2012-11-22 22:08:2441const char kHomePage[] = "homepage";
42
brettw58cd1f12016-01-30 05:56:0543const char kReadJson[] =
44 "{\n"
45 " \"homepage\": \"http://www.cnn.com\",\n"
46 " \"some_directory\": \"/usr/local/\",\n"
47 " \"tabs\": {\n"
48 " \"new_windows_in_tabs\": true,\n"
49 " \"max_tabs\": 20\n"
50 " }\n"
51 "}";
52
53const char kInvalidJson[] = "!@#$%^&";
54
55// Expected output for tests using RunBasicJsonPrefStoreTest().
56const char kWriteGolden[] =
57 "{\"homepage\":\"http://www.cnn.com\","
58 "\"long_int\":{\"pref\":\"214748364842\"},"
59 "\"some_directory\":\"/usr/sbin/\","
60 "\"tabs\":{\"max_tabs\":10,\"new_windows_in_tabs\":false}}";
61
raymesbfb910a2015-04-29 07:43:0962// Set the time on the given SimpleTestClock to the given time in minutes.
63void SetCurrentTimeInMinutes(double minutes, base::SimpleTestClock* clock) {
64 const int32_t kBaseTimeMins = 100;
65 clock->SetNow(base::Time::FromDoubleT((kBaseTimeMins + minutes) * 60));
66}
67
[email protected]e33c9512014-05-12 02:24:1368// A PrefFilter that will intercept all calls to FilterOnLoad() and hold on
69// to the |prefs| until explicitly asked to release them.
70class InterceptingPrefFilter : public PrefFilter {
71 public:
72 InterceptingPrefFilter();
probergec503d692016-09-28 19:51:0573 InterceptingPrefFilter(OnWriteCallbackPair callback_pair);
dcheng56488182014-10-21 10:54:5174 ~InterceptingPrefFilter() override;
[email protected]e33c9512014-05-12 02:24:1375
76 // PrefFilter implementation:
dcheng56488182014-10-21 10:54:5177 void FilterOnLoad(
[email protected]e33c9512014-05-12 02:24:1378 const PostFilterOnLoadCallback& post_filter_on_load_callback,
dcheng5f043bc2016-04-22 19:09:0679 std::unique_ptr<base::DictionaryValue> pref_store_contents) override;
dcheng56488182014-10-21 10:54:5180 void FilterUpdate(const std::string& path) override {}
probergec503d692016-09-28 19:51:0581 OnWriteCallbackPair FilterSerializeData(
82 base::DictionaryValue* pref_store_contents) override {
83 return on_write_callback_pair_;
84 }
proberge45e347282017-08-16 21:24:0585 void OnStoreDeletionFromDisk() override {}
[email protected]e33c9512014-05-12 02:24:1386
Ivan Kotenkov75b1c3a2017-10-24 14:47:2487 bool has_intercepted_prefs() const { return intercepted_prefs_ != nullptr; }
[email protected]e33c9512014-05-12 02:24:1388
[email protected]cfcf0e52014-06-20 18:29:4789 // Finalize an intercepted read, handing |intercepted_prefs_| back to its
[email protected]e33c9512014-05-12 02:24:1390 // JsonPrefStore.
91 void ReleasePrefs();
92
93 private:
94 PostFilterOnLoadCallback post_filter_on_load_callback_;
dcheng5f043bc2016-04-22 19:09:0695 std::unique_ptr<base::DictionaryValue> intercepted_prefs_;
probergec503d692016-09-28 19:51:0596 OnWriteCallbackPair on_write_callback_pair_;
[email protected]e33c9512014-05-12 02:24:1397
98 DISALLOW_COPY_AND_ASSIGN(InterceptingPrefFilter);
99};
100
101InterceptingPrefFilter::InterceptingPrefFilter() {}
probergec503d692016-09-28 19:51:05102
103InterceptingPrefFilter::InterceptingPrefFilter(
104 OnWriteCallbackPair callback_pair) {
105 on_write_callback_pair_ = callback_pair;
106}
107
[email protected]e33c9512014-05-12 02:24:13108InterceptingPrefFilter::~InterceptingPrefFilter() {}
109
110void InterceptingPrefFilter::FilterOnLoad(
111 const PostFilterOnLoadCallback& post_filter_on_load_callback,
dcheng5f043bc2016-04-22 19:09:06112 std::unique_ptr<base::DictionaryValue> pref_store_contents) {
[email protected]e33c9512014-05-12 02:24:13113 post_filter_on_load_callback_ = post_filter_on_load_callback;
danakj0c8d4aa2015-11-25 05:29:58114 intercepted_prefs_ = std::move(pref_store_contents);
[email protected]e33c9512014-05-12 02:24:13115}
116
117void InterceptingPrefFilter::ReleasePrefs() {
118 EXPECT_FALSE(post_filter_on_load_callback_.is_null());
danakj0c8d4aa2015-11-25 05:29:58119 post_filter_on_load_callback_.Run(std::move(intercepted_prefs_), false);
[email protected]e33c9512014-05-12 02:24:13120 post_filter_on_load_callback_.Reset();
121}
122
[email protected]845b43a82011-05-11 10:14:43123class MockPrefStoreObserver : public PrefStore::Observer {
124 public:
125 MOCK_METHOD1(OnPrefValueChanged, void (const std::string&));
126 MOCK_METHOD1(OnInitializationCompleted, void (bool));
127};
128
129class MockReadErrorDelegate : public PersistentPrefStore::ReadErrorDelegate {
130 public:
131 MOCK_METHOD1(OnError, void(PersistentPrefStore::PrefReadError));
132};
133
Francois Doray405dd2d2017-06-09 15:23:33134enum class CommitPendingWriteMode {
Gabriel Charette788eaf62018-08-07 20:11:46135 // Basic mode.
Francois Doray405dd2d2017-06-09 15:23:33136 WITHOUT_CALLBACK,
Gabriel Charette788eaf62018-08-07 20:11:46137 // With reply callback.
Francois Doray405dd2d2017-06-09 15:23:33138 WITH_CALLBACK,
Gabriel Charette788eaf62018-08-07 20:11:46139 // With synchronous notify callback (synchronous after the write -- shouldn't
140 // require pumping messages to observe).
141 WITH_SYNCHRONOUS_CALLBACK,
Francois Doray405dd2d2017-06-09 15:23:33142};
[email protected]845b43a82011-05-11 10:14:43143
Gabriel Charette788eaf62018-08-07 20:11:46144base::test::ScopedTaskEnvironment::ExecutionMode GetExecutionMode(
145 CommitPendingWriteMode commit_mode) {
146 switch (commit_mode) {
147 case CommitPendingWriteMode::WITHOUT_CALLBACK:
148 FALLTHROUGH;
149 case CommitPendingWriteMode::WITH_CALLBACK:
150 return base::test::ScopedTaskEnvironment::ExecutionMode::QUEUED;
151 case CommitPendingWriteMode::WITH_SYNCHRONOUS_CALLBACK:
152 // Synchronous callbacks require async tasks to run on their own.
153 return base::test::ScopedTaskEnvironment::ExecutionMode::ASYNC;
154 }
155}
156
Francois Doray405dd2d2017-06-09 15:23:33157void CommitPendingWrite(
158 JsonPrefStore* pref_store,
159 CommitPendingWriteMode commit_pending_write_mode,
160 base::test::ScopedTaskEnvironment* scoped_task_environment) {
Gabriel Charette788eaf62018-08-07 20:11:46161 switch (commit_pending_write_mode) {
162 case CommitPendingWriteMode::WITHOUT_CALLBACK: {
163 pref_store->CommitPendingWrite();
164 scoped_task_environment->RunUntilIdle();
165 break;
166 }
167 case CommitPendingWriteMode::WITH_CALLBACK: {
168 TestCommitPendingWriteWithCallback(pref_store, scoped_task_environment);
169 break;
170 }
171 case CommitPendingWriteMode::WITH_SYNCHRONOUS_CALLBACK: {
172 base::WaitableEvent written;
173 pref_store->CommitPendingWrite(
174 base::OnceClosure(),
175 base::BindOnce(&base::WaitableEvent::Signal, Unretained(&written)));
176 written.Wait();
177 break;
178 }
Francois Doray405dd2d2017-06-09 15:23:33179 }
180}
181
182class JsonPrefStoreTest
183 : public testing::TestWithParam<CommitPendingWriteMode> {
probergefc46ac12016-09-21 18:03:00184 public:
Francois Doray5f547952017-07-25 21:02:05185 JsonPrefStoreTest()
186 : scoped_task_environment_(
187 base::test::ScopedTaskEnvironment::MainThreadType::DEFAULT,
Gabriel Charette788eaf62018-08-07 20:11:46188 GetExecutionMode(GetParam())) {}
probergefc46ac12016-09-21 18:03:00189
[email protected]277404c22010-04-22 13:09:45190 protected:
dcheng8aef37612014-12-23 02:56:47191 void SetUp() override {
[email protected]3a305db2011-04-12 13:40:53192 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
[email protected]277404c22010-04-22 13:09:45193 }
194
Francois Doray405dd2d2017-06-09 15:23:33195 base::test::ScopedTaskEnvironment scoped_task_environment_;
[email protected]e33c9512014-05-12 02:24:13196
[email protected]3a305db2011-04-12 13:40:53197 // The path to temporary directory used to contain the test operations.
[email protected]ea1a3f62012-11-16 20:34:23198 base::ScopedTempDir temp_dir_;
probergefc46ac12016-09-21 18:03:00199
200 DISALLOW_COPY_AND_ASSIGN(JsonPrefStoreTest);
[email protected]277404c22010-04-22 13:09:45201};
202
Francois Doray405dd2d2017-06-09 15:23:33203} // namespace
204
[email protected]277404c22010-04-22 13:09:45205// Test fallback behavior for a nonexistent file.
Gabriel Charette788eaf62018-08-07 20:11:46206TEST_P(JsonPrefStoreTest, NonExistentFile) {
vabr8023d872016-09-15 08:12:22207 base::FilePath bogus_input_file = temp_dir_.GetPath().AppendASCII("read.txt");
[email protected]7567484142013-07-11 17:36:07208 ASSERT_FALSE(PathExists(bogus_input_file));
Francois Doray405dd2d2017-06-09 15:23:33209 auto pref_store = base::MakeRefCounted<JsonPrefStore>(bogus_input_file);
[email protected]f2d1f612010-12-09 15:10:17210 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE,
[email protected]9a8c4022011-01-25 14:25:33211 pref_store->ReadPrefs());
212 EXPECT_FALSE(pref_store->ReadOnly());
[email protected]277404c22010-04-22 13:09:45213}
214
215// Test fallback behavior for an invalid file.
Gabriel Charette788eaf62018-08-07 20:11:46216TEST_P(JsonPrefStoreTest, InvalidFile) {
vabr8023d872016-09-15 08:12:22217 base::FilePath invalid_file = temp_dir_.GetPath().AppendASCII("invalid.json");
brettw58cd1f12016-01-30 05:56:05218 ASSERT_LT(0, base::WriteFile(invalid_file,
219 kInvalidJson, arraysize(kInvalidJson) - 1));
220
Francois Doray405dd2d2017-06-09 15:23:33221 auto pref_store = base::MakeRefCounted<JsonPrefStore>(invalid_file);
[email protected]f2d1f612010-12-09 15:10:17222 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_JSON_PARSE,
[email protected]9a8c4022011-01-25 14:25:33223 pref_store->ReadPrefs());
224 EXPECT_FALSE(pref_store->ReadOnly());
[email protected]277404c22010-04-22 13:09:45225
226 // The file should have been moved aside.
[email protected]7567484142013-07-11 17:36:07227 EXPECT_FALSE(PathExists(invalid_file));
vabr8023d872016-09-15 08:12:22228 base::FilePath moved_aside = temp_dir_.GetPath().AppendASCII("invalid.bad");
[email protected]7567484142013-07-11 17:36:07229 EXPECT_TRUE(PathExists(moved_aside));
brettw58cd1f12016-01-30 05:56:05230
231 std::string moved_aside_contents;
232 ASSERT_TRUE(base::ReadFileToString(moved_aside, &moved_aside_contents));
233 EXPECT_EQ(kInvalidJson, moved_aside_contents);
[email protected]277404c22010-04-22 13:09:45234}
235
brettw58cd1f12016-01-30 05:56:05236// This function is used to avoid code duplication while testing synchronous
237// and asynchronous version of the JsonPrefStore loading. It validates that the
238// given output file's contents matches kWriteGolden.
Francois Doray405dd2d2017-06-09 15:23:33239void RunBasicJsonPrefStoreTest(
240 JsonPrefStore* pref_store,
241 const base::FilePath& output_file,
242 CommitPendingWriteMode commit_pending_write_mode,
243 base::test::ScopedTaskEnvironment* scoped_task_environment) {
[email protected]57ecc4b2010-08-11 03:02:51244 const char kNewWindowsInTabs[] = "tabs.new_windows_in_tabs";
245 const char kMaxTabs[] = "tabs.max_tabs";
246 const char kLongIntPref[] = "long_int.pref";
[email protected]277404c22010-04-22 13:09:45247
[email protected]57ecc4b2010-08-11 03:02:51248 std::string cnn("http://www.cnn.com");
[email protected]277404c22010-04-22 13:09:45249
[email protected]68bf41a2011-03-25 16:38:31250 const Value* actual;
[email protected]5bfdcfd2012-11-22 22:08:24251 EXPECT_TRUE(pref_store->GetValue(kHomePage, &actual));
[email protected]57ecc4b2010-08-11 03:02:51252 std::string string_value;
[email protected]f2d1f612010-12-09 15:10:17253 EXPECT_TRUE(actual->GetAsString(&string_value));
[email protected]277404c22010-04-22 13:09:45254 EXPECT_EQ(cnn, string_value);
255
[email protected]57ecc4b2010-08-11 03:02:51256 const char kSomeDirectory[] = "some_directory";
[email protected]277404c22010-04-22 13:09:45257
[email protected]892f1d62012-11-08 18:24:34258 EXPECT_TRUE(pref_store->GetValue(kSomeDirectory, &actual));
[email protected]023ad6ab2013-02-17 05:07:23259 base::FilePath::StringType path;
[email protected]f2d1f612010-12-09 15:10:17260 EXPECT_TRUE(actual->GetAsString(&path));
[email protected]023ad6ab2013-02-17 05:07:23261 EXPECT_EQ(base::FilePath::StringType(FILE_PATH_LITERAL("/usr/local/")), path);
262 base::FilePath some_path(FILE_PATH_LITERAL("/usr/sbin/"));
[email protected]f2d1f612010-12-09 15:10:17263
estade0bd407f2015-06-26 18:16:18264 pref_store->SetValue(kSomeDirectory,
Jinho Bang84b58bd2018-01-01 21:44:48265 std::make_unique<Value>(some_path.value()),
raymes76de1af2015-05-06 03:22:21266 WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
[email protected]892f1d62012-11-08 18:24:34267 EXPECT_TRUE(pref_store->GetValue(kSomeDirectory, &actual));
[email protected]f2d1f612010-12-09 15:10:17268 EXPECT_TRUE(actual->GetAsString(&path));
[email protected]277404c22010-04-22 13:09:45269 EXPECT_EQ(some_path.value(), path);
270
271 // Test reading some other data types from sub-dictionaries.
[email protected]892f1d62012-11-08 18:24:34272 EXPECT_TRUE(pref_store->GetValue(kNewWindowsInTabs, &actual));
[email protected]f2d1f612010-12-09 15:10:17273 bool boolean = false;
274 EXPECT_TRUE(actual->GetAsBoolean(&boolean));
[email protected]277404c22010-04-22 13:09:45275 EXPECT_TRUE(boolean);
276
Jinho Bang84b58bd2018-01-01 21:44:48277 pref_store->SetValue(kNewWindowsInTabs, std::make_unique<Value>(false),
raymes76de1af2015-05-06 03:22:21278 WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
[email protected]892f1d62012-11-08 18:24:34279 EXPECT_TRUE(pref_store->GetValue(kNewWindowsInTabs, &actual));
[email protected]f2d1f612010-12-09 15:10:17280 EXPECT_TRUE(actual->GetAsBoolean(&boolean));
[email protected]277404c22010-04-22 13:09:45281 EXPECT_FALSE(boolean);
282
[email protected]892f1d62012-11-08 18:24:34283 EXPECT_TRUE(pref_store->GetValue(kMaxTabs, &actual));
[email protected]f2d1f612010-12-09 15:10:17284 int integer = 0;
285 EXPECT_TRUE(actual->GetAsInteger(&integer));
[email protected]277404c22010-04-22 13:09:45286 EXPECT_EQ(20, integer);
Jinho Bang84b58bd2018-01-01 21:44:48287 pref_store->SetValue(kMaxTabs, std::make_unique<Value>(10),
raymes76de1af2015-05-06 03:22:21288 WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
[email protected]892f1d62012-11-08 18:24:34289 EXPECT_TRUE(pref_store->GetValue(kMaxTabs, &actual));
[email protected]f2d1f612010-12-09 15:10:17290 EXPECT_TRUE(actual->GetAsInteger(&integer));
[email protected]277404c22010-04-22 13:09:45291 EXPECT_EQ(10, integer);
292
jdoerrie122c4da2017-03-06 11:12:04293 pref_store->SetValue(
294 kLongIntPref,
Jinho Bang84b58bd2018-01-01 21:44:48295 std::make_unique<Value>(base::Int64ToString(214748364842LL)),
jdoerrie122c4da2017-03-06 11:12:04296 WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
[email protected]892f1d62012-11-08 18:24:34297 EXPECT_TRUE(pref_store->GetValue(kLongIntPref, &actual));
[email protected]f2d1f612010-12-09 15:10:17298 EXPECT_TRUE(actual->GetAsString(&string_value));
avi9ef8bb02015-12-24 05:29:36299 int64_t value;
[email protected]57ecc4b2010-08-11 03:02:51300 base::StringToInt64(string_value, &value);
[email protected]e83326f2010-07-31 17:29:25301 EXPECT_EQ(214748364842LL, value);
[email protected]277404c22010-04-22 13:09:45302
303 // Serialize and compare to expected output.
Francois Doray405dd2d2017-06-09 15:23:33304 CommitPendingWrite(pref_store, commit_pending_write_mode,
305 scoped_task_environment);
brettw58cd1f12016-01-30 05:56:05306
307 std::string output_contents;
308 ASSERT_TRUE(base::ReadFileToString(output_file, &output_contents));
309 EXPECT_EQ(kWriteGolden, output_contents);
[email protected]dd3aa792013-07-16 19:10:23310 ASSERT_TRUE(base::DeleteFile(output_file, false));
[email protected]277404c22010-04-22 13:09:45311}
[email protected]845b43a82011-05-11 10:14:43312
Francois Doray405dd2d2017-06-09 15:23:33313TEST_P(JsonPrefStoreTest, Basic) {
vabr8023d872016-09-15 08:12:22314 base::FilePath input_file = temp_dir_.GetPath().AppendASCII("write.json");
brettw58cd1f12016-01-30 05:56:05315 ASSERT_LT(0, base::WriteFile(input_file,
316 kReadJson, arraysize(kReadJson) - 1));
[email protected]845b43a82011-05-11 10:14:43317
318 // Test that the persistent value can be loaded.
[email protected]7567484142013-07-11 17:36:07319 ASSERT_TRUE(PathExists(input_file));
Francois Doray405dd2d2017-06-09 15:23:33320 auto pref_store = base::MakeRefCounted<JsonPrefStore>(input_file);
[email protected]845b43a82011-05-11 10:14:43321 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, pref_store->ReadPrefs());
[email protected]e33c9512014-05-12 02:24:13322 EXPECT_FALSE(pref_store->ReadOnly());
323 EXPECT_TRUE(pref_store->IsInitializationComplete());
[email protected]845b43a82011-05-11 10:14:43324
325 // The JSON file looks like this:
326 // {
327 // "homepage": "http://www.cnn.com",
328 // "some_directory": "/usr/local/",
329 // "tabs": {
330 // "new_windows_in_tabs": true,
331 // "max_tabs": 20
332 // }
333 // }
334
Francois Doray405dd2d2017-06-09 15:23:33335 RunBasicJsonPrefStoreTest(pref_store.get(), input_file, GetParam(),
336 &scoped_task_environment_);
[email protected]845b43a82011-05-11 10:14:43337}
338
Francois Doray405dd2d2017-06-09 15:23:33339TEST_P(JsonPrefStoreTest, BasicAsync) {
vabr8023d872016-09-15 08:12:22340 base::FilePath input_file = temp_dir_.GetPath().AppendASCII("write.json");
brettw58cd1f12016-01-30 05:56:05341 ASSERT_LT(0, base::WriteFile(input_file,
342 kReadJson, arraysize(kReadJson) - 1));
[email protected]845b43a82011-05-11 10:14:43343
344 // Test that the persistent value can be loaded.
Francois Doray405dd2d2017-06-09 15:23:33345 auto pref_store = base::MakeRefCounted<JsonPrefStore>(input_file);
[email protected]845b43a82011-05-11 10:14:43346
[email protected]0de615a2012-11-08 04:40:59347 {
348 MockPrefStoreObserver mock_observer;
349 pref_store->AddObserver(&mock_observer);
[email protected]845b43a82011-05-11 10:14:43350
[email protected]0de615a2012-11-08 04:40:59351 MockReadErrorDelegate* mock_error_delegate = new MockReadErrorDelegate;
352 pref_store->ReadPrefsAsync(mock_error_delegate);
[email protected]845b43a82011-05-11 10:14:43353
[email protected]0de615a2012-11-08 04:40:59354 EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(1);
355 EXPECT_CALL(*mock_error_delegate,
356 OnError(PersistentPrefStore::PREF_READ_ERROR_NONE)).Times(0);
Francois Doray405dd2d2017-06-09 15:23:33357 scoped_task_environment_.RunUntilIdle();
[email protected]0de615a2012-11-08 04:40:59358 pref_store->RemoveObserver(&mock_observer);
[email protected]845b43a82011-05-11 10:14:43359
[email protected]e33c9512014-05-12 02:24:13360 EXPECT_FALSE(pref_store->ReadOnly());
361 EXPECT_TRUE(pref_store->IsInitializationComplete());
[email protected]0de615a2012-11-08 04:40:59362 }
[email protected]845b43a82011-05-11 10:14:43363
364 // The JSON file looks like this:
365 // {
366 // "homepage": "http://www.cnn.com",
367 // "some_directory": "/usr/local/",
368 // "tabs": {
369 // "new_windows_in_tabs": true,
370 // "max_tabs": 20
371 // }
372 // }
373
Francois Doray405dd2d2017-06-09 15:23:33374 RunBasicJsonPrefStoreTest(pref_store.get(), input_file, GetParam(),
375 &scoped_task_environment_);
[email protected]845b43a82011-05-11 10:14:43376}
377
Francois Doray405dd2d2017-06-09 15:23:33378TEST_P(JsonPrefStoreTest, PreserveEmptyValues) {
vabr8023d872016-09-15 08:12:22379 FilePath pref_file = temp_dir_.GetPath().AppendASCII("empty_values.json");
[email protected]aa3283392013-11-27 01:38:24380
Francois Doray405dd2d2017-06-09 15:23:33381 auto pref_store = base::MakeRefCounted<JsonPrefStore>(pref_file);
[email protected]aa3283392013-11-27 01:38:24382
383 // Set some keys with empty values.
Jinho Bang84b58bd2018-01-01 21:44:48384 pref_store->SetValue("list", std::make_unique<base::ListValue>(),
raymes76de1af2015-05-06 03:22:21385 WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
Jinho Bang84b58bd2018-01-01 21:44:48386 pref_store->SetValue("dict", std::make_unique<base::DictionaryValue>(),
raymes76de1af2015-05-06 03:22:21387 WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
[email protected]aa3283392013-11-27 01:38:24388
389 // Write to file.
Francois Doray405dd2d2017-06-09 15:23:33390 CommitPendingWrite(pref_store.get(), GetParam(), &scoped_task_environment_);
[email protected]aa3283392013-11-27 01:38:24391
392 // Reload.
Francois Doray405dd2d2017-06-09 15:23:33393 pref_store = base::MakeRefCounted<JsonPrefStore>(pref_file);
[email protected]aa3283392013-11-27 01:38:24394 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, pref_store->ReadPrefs());
395 ASSERT_FALSE(pref_store->ReadOnly());
396
397 // Check values.
Ivan Kotenkov75b1c3a2017-10-24 14:47:24398 const Value* result = nullptr;
[email protected]aa3283392013-11-27 01:38:24399 EXPECT_TRUE(pref_store->GetValue("list", &result));
400 EXPECT_TRUE(ListValue().Equals(result));
401 EXPECT_TRUE(pref_store->GetValue("dict", &result));
402 EXPECT_TRUE(DictionaryValue().Equals(result));
403}
404
[email protected]eeedaa692014-01-30 09:22:27405// This test is just documenting some potentially non-obvious behavior. It
406// shouldn't be taken as normative.
Gabriel Charette788eaf62018-08-07 20:11:46407TEST_P(JsonPrefStoreTest, RemoveClearsEmptyParent) {
vabr8023d872016-09-15 08:12:22408 FilePath pref_file = temp_dir_.GetPath().AppendASCII("empty_values.json");
[email protected]eeedaa692014-01-30 09:22:27409
Francois Doray405dd2d2017-06-09 15:23:33410 auto pref_store = base::MakeRefCounted<JsonPrefStore>(pref_file);
[email protected]eeedaa692014-01-30 09:22:27411
dcheng5f043bc2016-04-22 19:09:06412 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
[email protected]eeedaa692014-01-30 09:22:27413 dict->SetString("key", "value");
danakj0c8d4aa2015-11-25 05:29:58414 pref_store->SetValue("dict", std::move(dict),
raymes76de1af2015-05-06 03:22:21415 WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
[email protected]eeedaa692014-01-30 09:22:27416
raymes76de1af2015-05-06 03:22:21417 pref_store->RemoveValue("dict.key",
418 WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
[email protected]eeedaa692014-01-30 09:22:27419
Ivan Kotenkov75b1c3a2017-10-24 14:47:24420 const base::Value* retrieved_dict = nullptr;
[email protected]eeedaa692014-01-30 09:22:27421 bool has_dict = pref_store->GetValue("dict", &retrieved_dict);
422 EXPECT_FALSE(has_dict);
423}
424
[email protected]845b43a82011-05-11 10:14:43425// Tests asynchronous reading of the file when there is no file.
Gabriel Charette788eaf62018-08-07 20:11:46426TEST_P(JsonPrefStoreTest, AsyncNonExistingFile) {
vabr8023d872016-09-15 08:12:22427 base::FilePath bogus_input_file = temp_dir_.GetPath().AppendASCII("read.txt");
[email protected]7567484142013-07-11 17:36:07428 ASSERT_FALSE(PathExists(bogus_input_file));
Francois Doray405dd2d2017-06-09 15:23:33429 auto pref_store = base::MakeRefCounted<JsonPrefStore>(bogus_input_file);
[email protected]845b43a82011-05-11 10:14:43430 MockPrefStoreObserver mock_observer;
431 pref_store->AddObserver(&mock_observer);
432
433 MockReadErrorDelegate *mock_error_delegate = new MockReadErrorDelegate;
434 pref_store->ReadPrefsAsync(mock_error_delegate);
435
436 EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(1);
437 EXPECT_CALL(*mock_error_delegate,
438 OnError(PersistentPrefStore::PREF_READ_ERROR_NO_FILE)).Times(1);
Francois Doray405dd2d2017-06-09 15:23:33439 scoped_task_environment_.RunUntilIdle();
[email protected]845b43a82011-05-11 10:14:43440 pref_store->RemoveObserver(&mock_observer);
441
442 EXPECT_FALSE(pref_store->ReadOnly());
443}
[email protected]ea3e4972012-04-12 03:41:37444
Francois Doray405dd2d2017-06-09 15:23:33445TEST_P(JsonPrefStoreTest, ReadWithInterceptor) {
vabr8023d872016-09-15 08:12:22446 base::FilePath input_file = temp_dir_.GetPath().AppendASCII("write.json");
brettw58cd1f12016-01-30 05:56:05447 ASSERT_LT(0, base::WriteFile(input_file,
448 kReadJson, arraysize(kReadJson) - 1));
[email protected]e33c9512014-05-12 02:24:13449
dcheng5f043bc2016-04-22 19:09:06450 std::unique_ptr<InterceptingPrefFilter> intercepting_pref_filter(
[email protected]e33c9512014-05-12 02:24:13451 new InterceptingPrefFilter());
452 InterceptingPrefFilter* raw_intercepting_pref_filter_ =
453 intercepting_pref_filter.get();
Francois Doray405dd2d2017-06-09 15:23:33454 auto pref_store = base::MakeRefCounted<JsonPrefStore>(
455 input_file, base::CreateSequencedTaskRunnerWithTraits({base::MayBlock()}),
456 std::move(intercepting_pref_filter));
[email protected]e33c9512014-05-12 02:24:13457
458 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_ASYNCHRONOUS_TASK_INCOMPLETE,
459 pref_store->ReadPrefs());
460 EXPECT_FALSE(pref_store->ReadOnly());
461
462 // The store shouldn't be considered initialized until the interceptor
463 // returns.
464 EXPECT_TRUE(raw_intercepting_pref_filter_->has_intercepted_prefs());
465 EXPECT_FALSE(pref_store->IsInitializationComplete());
Ivan Kotenkov75b1c3a2017-10-24 14:47:24466 EXPECT_FALSE(pref_store->GetValue(kHomePage, nullptr));
[email protected]e33c9512014-05-12 02:24:13467
468 raw_intercepting_pref_filter_->ReleasePrefs();
469
470 EXPECT_FALSE(raw_intercepting_pref_filter_->has_intercepted_prefs());
471 EXPECT_TRUE(pref_store->IsInitializationComplete());
Ivan Kotenkov75b1c3a2017-10-24 14:47:24472 EXPECT_TRUE(pref_store->GetValue(kHomePage, nullptr));
[email protected]e33c9512014-05-12 02:24:13473
474 // The JSON file looks like this:
475 // {
476 // "homepage": "http://www.cnn.com",
477 // "some_directory": "/usr/local/",
478 // "tabs": {
479 // "new_windows_in_tabs": true,
480 // "max_tabs": 20
481 // }
482 // }
483
Francois Doray405dd2d2017-06-09 15:23:33484 RunBasicJsonPrefStoreTest(pref_store.get(), input_file, GetParam(),
485 &scoped_task_environment_);
[email protected]e33c9512014-05-12 02:24:13486}
487
Francois Doray405dd2d2017-06-09 15:23:33488TEST_P(JsonPrefStoreTest, ReadAsyncWithInterceptor) {
vabr8023d872016-09-15 08:12:22489 base::FilePath input_file = temp_dir_.GetPath().AppendASCII("write.json");
brettw58cd1f12016-01-30 05:56:05490 ASSERT_LT(0, base::WriteFile(input_file,
491 kReadJson, arraysize(kReadJson) - 1));
[email protected]e33c9512014-05-12 02:24:13492
dcheng5f043bc2016-04-22 19:09:06493 std::unique_ptr<InterceptingPrefFilter> intercepting_pref_filter(
[email protected]e33c9512014-05-12 02:24:13494 new InterceptingPrefFilter());
495 InterceptingPrefFilter* raw_intercepting_pref_filter_ =
496 intercepting_pref_filter.get();
Francois Doray405dd2d2017-06-09 15:23:33497 auto pref_store = base::MakeRefCounted<JsonPrefStore>(
498 input_file, base::CreateSequencedTaskRunnerWithTraits({base::MayBlock()}),
499 std::move(intercepting_pref_filter));
[email protected]e33c9512014-05-12 02:24:13500
501 MockPrefStoreObserver mock_observer;
502 pref_store->AddObserver(&mock_observer);
503
504 // Ownership of the |mock_error_delegate| is handed to the |pref_store| below.
505 MockReadErrorDelegate* mock_error_delegate = new MockReadErrorDelegate;
506
507 {
508 pref_store->ReadPrefsAsync(mock_error_delegate);
509
510 EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(0);
511 // EXPECT_CALL(*mock_error_delegate,
512 // OnError(PersistentPrefStore::PREF_READ_ERROR_NONE)).Times(0);
Francois Doray405dd2d2017-06-09 15:23:33513 scoped_task_environment_.RunUntilIdle();
[email protected]e33c9512014-05-12 02:24:13514
515 EXPECT_FALSE(pref_store->ReadOnly());
516 EXPECT_TRUE(raw_intercepting_pref_filter_->has_intercepted_prefs());
517 EXPECT_FALSE(pref_store->IsInitializationComplete());
Ivan Kotenkov75b1c3a2017-10-24 14:47:24518 EXPECT_FALSE(pref_store->GetValue(kHomePage, nullptr));
[email protected]e33c9512014-05-12 02:24:13519 }
520
521 {
522 EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(1);
523 // EXPECT_CALL(*mock_error_delegate,
524 // OnError(PersistentPrefStore::PREF_READ_ERROR_NONE)).Times(0);
525
526 raw_intercepting_pref_filter_->ReleasePrefs();
527
528 EXPECT_FALSE(pref_store->ReadOnly());
529 EXPECT_FALSE(raw_intercepting_pref_filter_->has_intercepted_prefs());
530 EXPECT_TRUE(pref_store->IsInitializationComplete());
Ivan Kotenkov75b1c3a2017-10-24 14:47:24531 EXPECT_TRUE(pref_store->GetValue(kHomePage, nullptr));
[email protected]e33c9512014-05-12 02:24:13532 }
533
534 pref_store->RemoveObserver(&mock_observer);
535
536 // The JSON file looks like this:
537 // {
538 // "homepage": "http://www.cnn.com",
539 // "some_directory": "/usr/local/",
540 // "tabs": {
541 // "new_windows_in_tabs": true,
542 // "max_tabs": 20
543 // }
544 // }
545
Francois Doray405dd2d2017-06-09 15:23:33546 RunBasicJsonPrefStoreTest(pref_store.get(), input_file, GetParam(),
547 &scoped_task_environment_);
[email protected]e33c9512014-05-12 02:24:13548}
549
Gabriel Charette788eaf62018-08-07 20:11:46550TEST_P(JsonPrefStoreTest, WriteCountHistogramTestBasic) {
brettw58cd1f12016-01-30 05:56:05551 base::HistogramTester histogram_tester;
552
raymesbfb910a2015-04-29 07:43:09553 SimpleTestClock* test_clock = new SimpleTestClock;
554 SetCurrentTimeInMinutes(0, test_clock);
555 JsonPrefStore::WriteCountHistogram histogram(
556 base::TimeDelta::FromSeconds(10),
557 base::FilePath(FILE_PATH_LITERAL("/tmp/Local State")),
dcheng5f043bc2016-04-22 19:09:06558 std::unique_ptr<base::Clock>(test_clock));
avi9ef8bb02015-12-24 05:29:36559 int32_t report_interval =
raymesbfb910a2015-04-29 07:43:09560 JsonPrefStore::WriteCountHistogram::kHistogramWriteReportIntervalMins;
561
562 histogram.RecordWriteOccured();
563
564 SetCurrentTimeInMinutes(1.5 * report_interval, test_clock);
565 histogram.ReportOutstandingWrites();
dcheng5f043bc2016-04-22 19:09:06566 std::unique_ptr<HistogramSamples> samples =
raymesbfb910a2015-04-29 07:43:09567 histogram.GetHistogram()->SnapshotSamples();
brettw58cd1f12016-01-30 05:56:05568
569 std::string histogram_name = histogram.GetHistogram()->histogram_name();
570 histogram_tester.ExpectBucketCount(histogram_name, 1, 1);
571 histogram_tester.ExpectTotalCount(histogram_name, 1);
raymesbfb910a2015-04-29 07:43:09572
573 ASSERT_EQ("Settings.JsonDataWriteCount.Local_State",
Brian Whited1c91082017-11-03 14:46:42574 std::string(histogram.GetHistogram()->histogram_name()));
raymesbfb910a2015-04-29 07:43:09575 ASSERT_TRUE(histogram.GetHistogram()->HasConstructionArguments(1, 30, 31));
576}
577
Gabriel Charette788eaf62018-08-07 20:11:46578TEST_P(JsonPrefStoreTest, WriteCountHistogramTestSinglePeriod) {
brettw58cd1f12016-01-30 05:56:05579 base::HistogramTester histogram_tester;
580
raymesbfb910a2015-04-29 07:43:09581 SimpleTestClock* test_clock = new SimpleTestClock;
582 SetCurrentTimeInMinutes(0, test_clock);
583 JsonPrefStore::WriteCountHistogram histogram(
584 base::TimeDelta::FromSeconds(10),
585 base::FilePath(FILE_PATH_LITERAL("/tmp/Local State")),
dcheng5f043bc2016-04-22 19:09:06586 std::unique_ptr<base::Clock>(test_clock));
avi9ef8bb02015-12-24 05:29:36587 int32_t report_interval =
raymesbfb910a2015-04-29 07:43:09588 JsonPrefStore::WriteCountHistogram::kHistogramWriteReportIntervalMins;
589
590 histogram.RecordWriteOccured();
591 SetCurrentTimeInMinutes(0.5 * report_interval, test_clock);
592 histogram.RecordWriteOccured();
593 SetCurrentTimeInMinutes(0.7 * report_interval, test_clock);
594 histogram.RecordWriteOccured();
595
596 // Nothing should be recorded until the report period has elapsed.
brettw58cd1f12016-01-30 05:56:05597 std::string histogram_name = histogram.GetHistogram()->histogram_name();
598 histogram_tester.ExpectTotalCount(histogram_name, 0);
raymesbfb910a2015-04-29 07:43:09599
600 SetCurrentTimeInMinutes(1.3 * report_interval, test_clock);
601 histogram.RecordWriteOccured();
602
603 // Now the report period has elapsed.
brettw58cd1f12016-01-30 05:56:05604 histogram_tester.ExpectBucketCount(histogram_name, 3, 1);
605 histogram_tester.ExpectTotalCount(histogram_name, 1);
raymesbfb910a2015-04-29 07:43:09606
607 // The last write won't be recorded because the second count period hasn't
608 // fully elapsed.
609 SetCurrentTimeInMinutes(1.5 * report_interval, test_clock);
610 histogram.ReportOutstandingWrites();
611
brettw58cd1f12016-01-30 05:56:05612 histogram_tester.ExpectBucketCount(histogram_name, 3, 1);
613 histogram_tester.ExpectTotalCount(histogram_name, 1);
raymesbfb910a2015-04-29 07:43:09614}
615
Gabriel Charette788eaf62018-08-07 20:11:46616TEST_P(JsonPrefStoreTest, WriteCountHistogramTestMultiplePeriods) {
brettw58cd1f12016-01-30 05:56:05617 base::HistogramTester histogram_tester;
618
raymesbfb910a2015-04-29 07:43:09619 SimpleTestClock* test_clock = new SimpleTestClock;
620 SetCurrentTimeInMinutes(0, test_clock);
621 JsonPrefStore::WriteCountHistogram histogram(
622 base::TimeDelta::FromSeconds(10),
623 base::FilePath(FILE_PATH_LITERAL("/tmp/Local State")),
dcheng5f043bc2016-04-22 19:09:06624 std::unique_ptr<base::Clock>(test_clock));
avi9ef8bb02015-12-24 05:29:36625 int32_t report_interval =
raymesbfb910a2015-04-29 07:43:09626 JsonPrefStore::WriteCountHistogram::kHistogramWriteReportIntervalMins;
627
628 histogram.RecordWriteOccured();
629 SetCurrentTimeInMinutes(0.5 * report_interval, test_clock);
630 histogram.RecordWriteOccured();
631 SetCurrentTimeInMinutes(0.7 * report_interval, test_clock);
632 histogram.RecordWriteOccured();
633 SetCurrentTimeInMinutes(1.3 * report_interval, test_clock);
634 histogram.RecordWriteOccured();
635 SetCurrentTimeInMinutes(1.5 * report_interval, test_clock);
636 histogram.RecordWriteOccured();
637 SetCurrentTimeInMinutes(2.1 * report_interval, test_clock);
638 histogram.RecordWriteOccured();
639 SetCurrentTimeInMinutes(2.5 * report_interval, test_clock);
640 histogram.RecordWriteOccured();
641 SetCurrentTimeInMinutes(2.7 * report_interval, test_clock);
642 histogram.RecordWriteOccured();
643 SetCurrentTimeInMinutes(3.3 * report_interval, test_clock);
644 histogram.RecordWriteOccured();
645
646 // The last write won't be recorded because the second count period hasn't
647 // fully elapsed
648 SetCurrentTimeInMinutes(3.5 * report_interval, test_clock);
649 histogram.ReportOutstandingWrites();
brettw58cd1f12016-01-30 05:56:05650 std::string histogram_name = histogram.GetHistogram()->histogram_name();
651 histogram_tester.ExpectBucketCount(histogram_name, 3, 2);
652 histogram_tester.ExpectBucketCount(histogram_name, 2, 1);
653 histogram_tester.ExpectTotalCount(histogram_name, 3);
raymesbfb910a2015-04-29 07:43:09654}
655
Gabriel Charette788eaf62018-08-07 20:11:46656TEST_P(JsonPrefStoreTest, WriteCountHistogramTestPeriodWithGaps) {
brettw58cd1f12016-01-30 05:56:05657 base::HistogramTester histogram_tester;
658
raymesbfb910a2015-04-29 07:43:09659 SimpleTestClock* test_clock = new SimpleTestClock;
660 SetCurrentTimeInMinutes(0, test_clock);
661 JsonPrefStore::WriteCountHistogram histogram(
662 base::TimeDelta::FromSeconds(10),
663 base::FilePath(FILE_PATH_LITERAL("/tmp/Local State")),
dcheng5f043bc2016-04-22 19:09:06664 std::unique_ptr<base::Clock>(test_clock));
avi9ef8bb02015-12-24 05:29:36665 int32_t report_interval =
raymesbfb910a2015-04-29 07:43:09666 JsonPrefStore::WriteCountHistogram::kHistogramWriteReportIntervalMins;
667
668 // 1 write in the first period.
669 histogram.RecordWriteOccured();
670
671 // No writes in the second and third periods.
672
673 // 2 writes in the fourth period.
674 SetCurrentTimeInMinutes(3.1 * report_interval, test_clock);
675 histogram.RecordWriteOccured();
676 SetCurrentTimeInMinutes(3.3 * report_interval, test_clock);
677 histogram.RecordWriteOccured();
678
679 // No writes in the fifth period.
680
681 // 3 writes in the sixth period.
682 SetCurrentTimeInMinutes(5.1 * report_interval, test_clock);
683 histogram.RecordWriteOccured();
684 SetCurrentTimeInMinutes(5.3 * report_interval, test_clock);
685 histogram.RecordWriteOccured();
686 SetCurrentTimeInMinutes(5.5 * report_interval, test_clock);
687 histogram.RecordWriteOccured();
688
689 SetCurrentTimeInMinutes(6.1 * report_interval, test_clock);
690 histogram.ReportOutstandingWrites();
brettw58cd1f12016-01-30 05:56:05691 std::string histogram_name = histogram.GetHistogram()->histogram_name();
692 histogram_tester.ExpectBucketCount(histogram_name, 0, 3);
693 histogram_tester.ExpectBucketCount(histogram_name, 1, 1);
694 histogram_tester.ExpectBucketCount(histogram_name, 2, 1);
695 histogram_tester.ExpectBucketCount(histogram_name, 3, 1);
696 histogram_tester.ExpectTotalCount(histogram_name, 6);
raymesbfb910a2015-04-29 07:43:09697}
698
Francois Doray405dd2d2017-06-09 15:23:33699INSTANTIATE_TEST_CASE_P(
700 WithoutCallback,
701 JsonPrefStoreTest,
702 ::testing::Values(CommitPendingWriteMode::WITHOUT_CALLBACK));
703INSTANTIATE_TEST_CASE_P(
704 WithCallback,
705 JsonPrefStoreTest,
706 ::testing::Values(CommitPendingWriteMode::WITH_CALLBACK));
Gabriel Charette788eaf62018-08-07 20:11:46707INSTANTIATE_TEST_CASE_P(
708 WithSynchronousCallback,
709 JsonPrefStoreTest,
710 ::testing::Values(CommitPendingWriteMode::WITH_SYNCHRONOUS_CALLBACK));
Francois Doray405dd2d2017-06-09 15:23:33711
raymes4b6e14e2015-05-12 00:10:30712class JsonPrefStoreLossyWriteTest : public JsonPrefStoreTest {
probergefc46ac12016-09-21 18:03:00713 public:
714 JsonPrefStoreLossyWriteTest() = default;
715
raymes4b6e14e2015-05-12 00:10:30716 protected:
717 void SetUp() override {
718 JsonPrefStoreTest::SetUp();
vabr8023d872016-09-15 08:12:22719 test_file_ = temp_dir_.GetPath().AppendASCII("test.json");
raymes4b6e14e2015-05-12 00:10:30720 }
721
raymes4b6e14e2015-05-12 00:10:30722 scoped_refptr<JsonPrefStore> CreatePrefStore() {
Francois Doray405dd2d2017-06-09 15:23:33723 return base::MakeRefCounted<JsonPrefStore>(test_file_);
raymes4b6e14e2015-05-12 00:10:30724 }
725
726 // Return the ImportantFileWriter for a given JsonPrefStore.
probergefc46ac12016-09-21 18:03:00727 ImportantFileWriter* GetImportantFileWriter(JsonPrefStore* pref_store) {
raymes4b6e14e2015-05-12 00:10:30728 return &(pref_store->writer_);
729 }
730
731 // Get the contents of kTestFile. Pumps the message loop before returning the
732 // result.
733 std::string GetTestFileContents() {
Francois Doray405dd2d2017-06-09 15:23:33734 scoped_task_environment_.RunUntilIdle();
raymes4b6e14e2015-05-12 00:10:30735 std::string file_contents;
736 ReadFileToString(test_file_, &file_contents);
737 return file_contents;
738 }
739
740 private:
741 base::FilePath test_file_;
probergefc46ac12016-09-21 18:03:00742
743 DISALLOW_COPY_AND_ASSIGN(JsonPrefStoreLossyWriteTest);
raymes4b6e14e2015-05-12 00:10:30744};
745
Gabriel Charette788eaf62018-08-07 20:11:46746TEST_P(JsonPrefStoreLossyWriteTest, LossyWriteBasic) {
raymes4b6e14e2015-05-12 00:10:30747 scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore();
probergefc46ac12016-09-21 18:03:00748 ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store.get());
raymes4b6e14e2015-05-12 00:10:30749
750 // Set a normal pref and check that it gets scheduled to be written.
751 ASSERT_FALSE(file_writer->HasPendingWrite());
Jinho Bang84b58bd2018-01-01 21:44:48752 pref_store->SetValue("normal", std::make_unique<base::Value>("normal"),
raymes4b6e14e2015-05-12 00:10:30753 WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
754 ASSERT_TRUE(file_writer->HasPendingWrite());
755 file_writer->DoScheduledWrite();
756 ASSERT_EQ("{\"normal\":\"normal\"}", GetTestFileContents());
757 ASSERT_FALSE(file_writer->HasPendingWrite());
758
759 // Set a lossy pref and check that it is not scheduled to be written.
760 // SetValue/RemoveValue.
Jinho Bang84b58bd2018-01-01 21:44:48761 pref_store->SetValue("lossy", std::make_unique<base::Value>("lossy"),
raymes4b6e14e2015-05-12 00:10:30762 WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
763 ASSERT_FALSE(file_writer->HasPendingWrite());
764 pref_store->RemoveValue("lossy", WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
765 ASSERT_FALSE(file_writer->HasPendingWrite());
766
767 // SetValueSilently/RemoveValueSilently.
Jinho Bang84b58bd2018-01-01 21:44:48768 pref_store->SetValueSilently("lossy", std::make_unique<base::Value>("lossy"),
raymes4b6e14e2015-05-12 00:10:30769 WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
770 ASSERT_FALSE(file_writer->HasPendingWrite());
771 pref_store->RemoveValueSilently("lossy",
772 WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
773 ASSERT_FALSE(file_writer->HasPendingWrite());
774
775 // ReportValueChanged.
Jinho Bang84b58bd2018-01-01 21:44:48776 pref_store->SetValue("lossy", std::make_unique<base::Value>("lossy"),
raymes4b6e14e2015-05-12 00:10:30777 WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
778 ASSERT_FALSE(file_writer->HasPendingWrite());
779 pref_store->ReportValueChanged("lossy",
780 WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
781 ASSERT_FALSE(file_writer->HasPendingWrite());
782
783 // Call CommitPendingWrite and check that the lossy pref and the normal pref
784 // are there with the last values set above.
Francois Doray405dd2d2017-06-09 15:23:33785 pref_store->CommitPendingWrite(base::OnceClosure());
raymes4b6e14e2015-05-12 00:10:30786 ASSERT_FALSE(file_writer->HasPendingWrite());
787 ASSERT_EQ("{\"lossy\":\"lossy\",\"normal\":\"normal\"}",
788 GetTestFileContents());
789}
790
Gabriel Charette788eaf62018-08-07 20:11:46791TEST_P(JsonPrefStoreLossyWriteTest, LossyWriteMixedLossyFirst) {
raymes4b6e14e2015-05-12 00:10:30792 scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore();
probergefc46ac12016-09-21 18:03:00793 ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store.get());
raymes4b6e14e2015-05-12 00:10:30794
795 // Set a lossy pref and check that it is not scheduled to be written.
796 ASSERT_FALSE(file_writer->HasPendingWrite());
Jinho Bang84b58bd2018-01-01 21:44:48797 pref_store->SetValue("lossy", std::make_unique<base::Value>("lossy"),
raymes4b6e14e2015-05-12 00:10:30798 WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
799 ASSERT_FALSE(file_writer->HasPendingWrite());
800
801 // Set a normal pref and check that it is scheduled to be written.
Jinho Bang84b58bd2018-01-01 21:44:48802 pref_store->SetValue("normal", std::make_unique<base::Value>("normal"),
raymes4b6e14e2015-05-12 00:10:30803 WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
804 ASSERT_TRUE(file_writer->HasPendingWrite());
805
806 // Call DoScheduledWrite and check both prefs get written.
807 file_writer->DoScheduledWrite();
808 ASSERT_EQ("{\"lossy\":\"lossy\",\"normal\":\"normal\"}",
809 GetTestFileContents());
810 ASSERT_FALSE(file_writer->HasPendingWrite());
811}
812
Gabriel Charette788eaf62018-08-07 20:11:46813TEST_P(JsonPrefStoreLossyWriteTest, LossyWriteMixedLossySecond) {
raymes4b6e14e2015-05-12 00:10:30814 scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore();
probergefc46ac12016-09-21 18:03:00815 ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store.get());
raymes4b6e14e2015-05-12 00:10:30816
817 // Set a normal pref and check that it is scheduled to be written.
818 ASSERT_FALSE(file_writer->HasPendingWrite());
Jinho Bang84b58bd2018-01-01 21:44:48819 pref_store->SetValue("normal", std::make_unique<base::Value>("normal"),
raymes4b6e14e2015-05-12 00:10:30820 WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
821 ASSERT_TRUE(file_writer->HasPendingWrite());
822
823 // Set a lossy pref and check that the write is still scheduled.
Jinho Bang84b58bd2018-01-01 21:44:48824 pref_store->SetValue("lossy", std::make_unique<base::Value>("lossy"),
raymes4b6e14e2015-05-12 00:10:30825 WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
826 ASSERT_TRUE(file_writer->HasPendingWrite());
827
828 // Call DoScheduledWrite and check both prefs get written.
829 file_writer->DoScheduledWrite();
830 ASSERT_EQ("{\"lossy\":\"lossy\",\"normal\":\"normal\"}",
831 GetTestFileContents());
832 ASSERT_FALSE(file_writer->HasPendingWrite());
833}
834
Gabriel Charette788eaf62018-08-07 20:11:46835TEST_P(JsonPrefStoreLossyWriteTest, ScheduleLossyWrite) {
benwells26730592015-05-28 13:08:08836 scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore();
probergefc46ac12016-09-21 18:03:00837 ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store.get());
benwells26730592015-05-28 13:08:08838
839 // Set a lossy pref and check that it is not scheduled to be written.
Jinho Bang84b58bd2018-01-01 21:44:48840 pref_store->SetValue("lossy", std::make_unique<base::Value>("lossy"),
benwells26730592015-05-28 13:08:08841 WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
842 ASSERT_FALSE(file_writer->HasPendingWrite());
843
844 // Schedule pending lossy writes and check that it is scheduled.
845 pref_store->SchedulePendingLossyWrites();
846 ASSERT_TRUE(file_writer->HasPendingWrite());
847
848 // Call CommitPendingWrite and check that the lossy pref is there with the
849 // last value set above.
Francois Doray405dd2d2017-06-09 15:23:33850 pref_store->CommitPendingWrite(base::OnceClosure());
benwells26730592015-05-28 13:08:08851 ASSERT_FALSE(file_writer->HasPendingWrite());
852 ASSERT_EQ("{\"lossy\":\"lossy\"}", GetTestFileContents());
853}
854
Gabriel Charette788eaf62018-08-07 20:11:46855INSTANTIATE_TEST_CASE_P(
856 WithoutCallback,
857 JsonPrefStoreLossyWriteTest,
858 ::testing::Values(CommitPendingWriteMode::WITHOUT_CALLBACK));
859INSTANTIATE_TEST_CASE_P(
860 WithReply,
861 JsonPrefStoreLossyWriteTest,
862 ::testing::Values(CommitPendingWriteMode::WITH_CALLBACK));
863INSTANTIATE_TEST_CASE_P(
864 WithNotify,
865 JsonPrefStoreLossyWriteTest,
866 ::testing::Values(CommitPendingWriteMode::WITH_SYNCHRONOUS_CALLBACK));
867
probergefc46ac12016-09-21 18:03:00868class SuccessfulWriteReplyObserver {
869 public:
870 SuccessfulWriteReplyObserver() = default;
871
872 // Returns true if a successful write was observed via on_successful_write()
873 // and resets the observation state to false regardless.
874 bool GetAndResetObservationState() {
875 bool was_successful_write_observed = successful_write_reply_observed_;
876 successful_write_reply_observed_ = false;
877 return was_successful_write_observed;
878 }
879
880 // Register OnWrite() to be called on the next write of |json_pref_store|.
881 void ObserveNextWriteCallback(JsonPrefStore* json_pref_store);
882
883 void OnSuccessfulWrite() {
884 EXPECT_FALSE(successful_write_reply_observed_);
885 successful_write_reply_observed_ = true;
886 }
887
888 private:
889 bool successful_write_reply_observed_ = false;
890
891 DISALLOW_COPY_AND_ASSIGN(SuccessfulWriteReplyObserver);
892};
893
894void SuccessfulWriteReplyObserver::ObserveNextWriteCallback(
895 JsonPrefStore* json_pref_store) {
896 json_pref_store->RegisterOnNextSuccessfulWriteReply(
897 base::Bind(&SuccessfulWriteReplyObserver::OnSuccessfulWrite,
898 base::Unretained(this)));
899}
900
901enum WriteCallbackObservationState {
902 NOT_CALLED,
903 CALLED_WITH_ERROR,
904 CALLED_WITH_SUCCESS,
905};
906
probergec503d692016-09-28 19:51:05907class WriteCallbacksObserver {
probergefc46ac12016-09-21 18:03:00908 public:
probergec503d692016-09-28 19:51:05909 WriteCallbacksObserver() = default;
probergefc46ac12016-09-21 18:03:00910
911 // Register OnWrite() to be called on the next write of |json_pref_store|.
912 void ObserveNextWriteCallback(JsonPrefStore* json_pref_store);
913
probergec503d692016-09-28 19:51:05914 // Returns whether OnPreWrite() was called, and resets the observation state
915 // to false.
916 bool GetAndResetPreWriteObservationState();
probergefc46ac12016-09-21 18:03:00917
probergec503d692016-09-28 19:51:05918 // Returns the |WriteCallbackObservationState| which was observed, then resets
919 // it to |NOT_CALLED|.
920 WriteCallbackObservationState GetAndResetPostWriteObservationState();
921
922 JsonPrefStore::OnWriteCallbackPair GetCallbackPair() {
923 return std::make_pair(
924 base::Bind(&WriteCallbacksObserver::OnPreWrite, base::Unretained(this)),
925 base::Bind(&WriteCallbacksObserver::OnPostWrite,
926 base::Unretained(this)));
927 }
928
929 void OnPreWrite() {
930 EXPECT_FALSE(pre_write_called_);
931 pre_write_called_ = true;
932 }
933
934 void OnPostWrite(bool success) {
935 EXPECT_EQ(NOT_CALLED, post_write_observation_state_);
936 post_write_observation_state_ =
937 success ? CALLED_WITH_SUCCESS : CALLED_WITH_ERROR;
probergefc46ac12016-09-21 18:03:00938 }
939
940 private:
probergec503d692016-09-28 19:51:05941 bool pre_write_called_ = false;
942 WriteCallbackObservationState post_write_observation_state_ = NOT_CALLED;
probergefc46ac12016-09-21 18:03:00943
probergec503d692016-09-28 19:51:05944 DISALLOW_COPY_AND_ASSIGN(WriteCallbacksObserver);
probergefc46ac12016-09-21 18:03:00945};
946
probergec503d692016-09-28 19:51:05947void WriteCallbacksObserver::ObserveNextWriteCallback(JsonPrefStore* writer) {
948 writer->RegisterOnNextWriteSynchronousCallbacks(GetCallbackPair());
949}
950
951bool WriteCallbacksObserver::GetAndResetPreWriteObservationState() {
952 bool observation_state = pre_write_called_;
953 pre_write_called_ = false;
954 return observation_state;
probergefc46ac12016-09-21 18:03:00955}
956
957WriteCallbackObservationState
probergec503d692016-09-28 19:51:05958WriteCallbacksObserver::GetAndResetPostWriteObservationState() {
959 WriteCallbackObservationState state = post_write_observation_state_;
960 pre_write_called_ = false;
961 post_write_observation_state_ = NOT_CALLED;
probergefc46ac12016-09-21 18:03:00962 return state;
963}
964
Gabriel Charette788eaf62018-08-07 20:11:46965class JsonPrefStoreCallbackTest : public testing::Test {
probergefc46ac12016-09-21 18:03:00966 public:
967 JsonPrefStoreCallbackTest() = default;
968
969 protected:
970 void SetUp() override {
Gabriel Charette788eaf62018-08-07 20:11:46971 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
vabr5d919d62016-09-30 08:55:36972 test_file_ = temp_dir_.GetPath().AppendASCII("test.json");
probergefc46ac12016-09-21 18:03:00973 }
974
975 scoped_refptr<JsonPrefStore> CreatePrefStore() {
Francois Doray405dd2d2017-06-09 15:23:33976 return base::MakeRefCounted<JsonPrefStore>(test_file_);
probergefc46ac12016-09-21 18:03:00977 }
978
979 // Return the ImportantFileWriter for a given JsonPrefStore.
980 ImportantFileWriter* GetImportantFileWriter(JsonPrefStore* pref_store) {
981 return &(pref_store->writer_);
982 }
983
984 void TriggerFakeWriteForCallback(JsonPrefStore* pref_store, bool success) {
985 JsonPrefStore::PostWriteCallback(
986 base::Bind(&JsonPrefStore::RunOrScheduleNextSuccessfulWriteCallback,
987 pref_store->AsWeakPtr()),
probergec503d692016-09-28 19:51:05988 base::Bind(&WriteCallbacksObserver::OnPostWrite,
probergefc46ac12016-09-21 18:03:00989 base::Unretained(&write_callback_observer_)),
990 base::SequencedTaskRunnerHandle::Get(), success);
991 }
992
993 SuccessfulWriteReplyObserver successful_write_reply_observer_;
probergec503d692016-09-28 19:51:05994 WriteCallbacksObserver write_callback_observer_;
probergefc46ac12016-09-21 18:03:00995
Gabriel Charette788eaf62018-08-07 20:11:46996 protected:
997 base::test::ScopedTaskEnvironment scoped_task_environment_{
998 base::test::ScopedTaskEnvironment::MainThreadType::DEFAULT,
999 base::test::ScopedTaskEnvironment::ExecutionMode::QUEUED};
1000
1001 base::ScopedTempDir temp_dir_;
1002
probergefc46ac12016-09-21 18:03:001003 private:
1004 base::FilePath test_file_;
1005
1006 DISALLOW_COPY_AND_ASSIGN(JsonPrefStoreCallbackTest);
1007};
1008
Francois Doray5f547952017-07-25 21:02:051009TEST_F(JsonPrefStoreCallbackTest, TestSerializeDataCallbacks) {
probergec503d692016-09-28 19:51:051010 base::FilePath input_file = temp_dir_.GetPath().AppendASCII("write.json");
1011 ASSERT_LT(0,
1012 base::WriteFile(input_file, kReadJson, arraysize(kReadJson) - 1));
1013
1014 std::unique_ptr<InterceptingPrefFilter> intercepting_pref_filter(
1015 new InterceptingPrefFilter(write_callback_observer_.GetCallbackPair()));
Francois Doray405dd2d2017-06-09 15:23:331016 auto pref_store = base::MakeRefCounted<JsonPrefStore>(
1017 input_file, base::CreateSequencedTaskRunnerWithTraits({base::MayBlock()}),
1018 std::move(intercepting_pref_filter));
probergec503d692016-09-28 19:51:051019 ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store.get());
1020
1021 EXPECT_EQ(NOT_CALLED,
1022 write_callback_observer_.GetAndResetPostWriteObservationState());
Jinho Bang84b58bd2018-01-01 21:44:481023 pref_store->SetValue("normal", std::make_unique<base::Value>("normal"),
probergec503d692016-09-28 19:51:051024 WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
1025 file_writer->DoScheduledWrite();
1026
1027 // The observer should not be invoked right away.
1028 EXPECT_FALSE(write_callback_observer_.GetAndResetPreWriteObservationState());
1029 EXPECT_EQ(NOT_CALLED,
1030 write_callback_observer_.GetAndResetPostWriteObservationState());
1031
Francois Doray405dd2d2017-06-09 15:23:331032 scoped_task_environment_.RunUntilIdle();
probergec503d692016-09-28 19:51:051033
1034 EXPECT_TRUE(write_callback_observer_.GetAndResetPreWriteObservationState());
1035 EXPECT_EQ(CALLED_WITH_SUCCESS,
1036 write_callback_observer_.GetAndResetPostWriteObservationState());
1037}
1038
1039TEST_F(JsonPrefStoreCallbackTest, TestPostWriteCallbacks) {
probergefc46ac12016-09-21 18:03:001040 scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore();
1041 ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store.get());
1042
probergec503d692016-09-28 19:51:051043 // Test RegisterOnNextWriteSynchronousCallbacks after
probergefc46ac12016-09-21 18:03:001044 // RegisterOnNextSuccessfulWriteReply.
1045 successful_write_reply_observer_.ObserveNextWriteCallback(pref_store.get());
1046 write_callback_observer_.ObserveNextWriteCallback(pref_store.get());
Jinho Bang84b58bd2018-01-01 21:44:481047 file_writer->WriteNow(std::make_unique<std::string>("foo"));
Francois Doray405dd2d2017-06-09 15:23:331048 scoped_task_environment_.RunUntilIdle();
probergefc46ac12016-09-21 18:03:001049 EXPECT_TRUE(successful_write_reply_observer_.GetAndResetObservationState());
probergec503d692016-09-28 19:51:051050 EXPECT_TRUE(write_callback_observer_.GetAndResetPreWriteObservationState());
1051 EXPECT_EQ(CALLED_WITH_SUCCESS,
1052 write_callback_observer_.GetAndResetPostWriteObservationState());
probergefc46ac12016-09-21 18:03:001053
1054 // Test RegisterOnNextSuccessfulWriteReply after
probergec503d692016-09-28 19:51:051055 // RegisterOnNextWriteSynchronousCallbacks.
probergefc46ac12016-09-21 18:03:001056 successful_write_reply_observer_.ObserveNextWriteCallback(pref_store.get());
1057 write_callback_observer_.ObserveNextWriteCallback(pref_store.get());
Jinho Bang84b58bd2018-01-01 21:44:481058 file_writer->WriteNow(std::make_unique<std::string>("foo"));
Francois Doray405dd2d2017-06-09 15:23:331059 scoped_task_environment_.RunUntilIdle();
probergefc46ac12016-09-21 18:03:001060 EXPECT_TRUE(successful_write_reply_observer_.GetAndResetObservationState());
probergec503d692016-09-28 19:51:051061 EXPECT_TRUE(write_callback_observer_.GetAndResetPreWriteObservationState());
1062 EXPECT_EQ(CALLED_WITH_SUCCESS,
1063 write_callback_observer_.GetAndResetPostWriteObservationState());
probergefc46ac12016-09-21 18:03:001064
1065 // Test RegisterOnNextSuccessfulWriteReply only.
1066 successful_write_reply_observer_.ObserveNextWriteCallback(pref_store.get());
Jinho Bang84b58bd2018-01-01 21:44:481067 file_writer->WriteNow(std::make_unique<std::string>("foo"));
Francois Doray405dd2d2017-06-09 15:23:331068 scoped_task_environment_.RunUntilIdle();
probergefc46ac12016-09-21 18:03:001069 EXPECT_TRUE(successful_write_reply_observer_.GetAndResetObservationState());
probergec503d692016-09-28 19:51:051070 EXPECT_FALSE(write_callback_observer_.GetAndResetPreWriteObservationState());
1071 EXPECT_EQ(NOT_CALLED,
1072 write_callback_observer_.GetAndResetPostWriteObservationState());
probergefc46ac12016-09-21 18:03:001073
probergec503d692016-09-28 19:51:051074 // Test RegisterOnNextWriteSynchronousCallbacks only.
probergefc46ac12016-09-21 18:03:001075 write_callback_observer_.ObserveNextWriteCallback(pref_store.get());
Jinho Bang84b58bd2018-01-01 21:44:481076 file_writer->WriteNow(std::make_unique<std::string>("foo"));
Francois Doray405dd2d2017-06-09 15:23:331077 scoped_task_environment_.RunUntilIdle();
probergefc46ac12016-09-21 18:03:001078 EXPECT_FALSE(successful_write_reply_observer_.GetAndResetObservationState());
probergec503d692016-09-28 19:51:051079 EXPECT_TRUE(write_callback_observer_.GetAndResetPreWriteObservationState());
1080 EXPECT_EQ(CALLED_WITH_SUCCESS,
1081 write_callback_observer_.GetAndResetPostWriteObservationState());
probergefc46ac12016-09-21 18:03:001082}
1083
probergec503d692016-09-28 19:51:051084TEST_F(JsonPrefStoreCallbackTest, TestPostWriteCallbacksWithFakeFailure) {
probergefc46ac12016-09-21 18:03:001085 scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore();
1086
1087 // Confirm that the observers are invoked.
1088 successful_write_reply_observer_.ObserveNextWriteCallback(pref_store.get());
1089 TriggerFakeWriteForCallback(pref_store.get(), true);
Francois Doray405dd2d2017-06-09 15:23:331090 scoped_task_environment_.RunUntilIdle();
probergefc46ac12016-09-21 18:03:001091 EXPECT_TRUE(successful_write_reply_observer_.GetAndResetObservationState());
1092 EXPECT_EQ(CALLED_WITH_SUCCESS,
probergec503d692016-09-28 19:51:051093 write_callback_observer_.GetAndResetPostWriteObservationState());
probergefc46ac12016-09-21 18:03:001094
1095 // Confirm that the observation states were reset.
1096 EXPECT_FALSE(successful_write_reply_observer_.GetAndResetObservationState());
probergec503d692016-09-28 19:51:051097 EXPECT_EQ(NOT_CALLED,
1098 write_callback_observer_.GetAndResetPostWriteObservationState());
probergefc46ac12016-09-21 18:03:001099
1100 // Confirm that re-installing the observers works for another write.
1101 successful_write_reply_observer_.ObserveNextWriteCallback(pref_store.get());
1102 TriggerFakeWriteForCallback(pref_store.get(), true);
Francois Doray405dd2d2017-06-09 15:23:331103 scoped_task_environment_.RunUntilIdle();
probergefc46ac12016-09-21 18:03:001104 EXPECT_TRUE(successful_write_reply_observer_.GetAndResetObservationState());
1105 EXPECT_EQ(CALLED_WITH_SUCCESS,
probergec503d692016-09-28 19:51:051106 write_callback_observer_.GetAndResetPostWriteObservationState());
probergefc46ac12016-09-21 18:03:001107
1108 // Confirm that the successful observer is not invoked by an unsuccessful
1109 // write, and that the synchronous observer is invoked.
1110 successful_write_reply_observer_.ObserveNextWriteCallback(pref_store.get());
1111 TriggerFakeWriteForCallback(pref_store.get(), false);
Francois Doray405dd2d2017-06-09 15:23:331112 scoped_task_environment_.RunUntilIdle();
probergefc46ac12016-09-21 18:03:001113 EXPECT_FALSE(successful_write_reply_observer_.GetAndResetObservationState());
1114 EXPECT_EQ(CALLED_WITH_ERROR,
probergec503d692016-09-28 19:51:051115 write_callback_observer_.GetAndResetPostWriteObservationState());
probergefc46ac12016-09-21 18:03:001116
1117 // Do a real write, and confirm that the successful observer was invoked after
1118 // being set by |PostWriteCallback| by the last TriggerFakeWriteCallback.
1119 ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store.get());
Jinho Bang84b58bd2018-01-01 21:44:481120 file_writer->WriteNow(std::make_unique<std::string>("foo"));
Francois Doray405dd2d2017-06-09 15:23:331121 scoped_task_environment_.RunUntilIdle();
probergefc46ac12016-09-21 18:03:001122 EXPECT_TRUE(successful_write_reply_observer_.GetAndResetObservationState());
probergec503d692016-09-28 19:51:051123 EXPECT_EQ(NOT_CALLED,
1124 write_callback_observer_.GetAndResetPostWriteObservationState());
probergefc46ac12016-09-21 18:03:001125}
1126
probergec503d692016-09-28 19:51:051127TEST_F(JsonPrefStoreCallbackTest, TestPostWriteCallbacksDuringProfileDeath) {
probergefc46ac12016-09-21 18:03:001128 // Create a JsonPrefStore and attach observers to it, then delete it by making
1129 // it go out of scope to simulate profile switch or Chrome shutdown.
1130 {
1131 scoped_refptr<JsonPrefStore> soon_out_of_scope_pref_store =
1132 CreatePrefStore();
1133 ImportantFileWriter* file_writer =
1134 GetImportantFileWriter(soon_out_of_scope_pref_store.get());
1135 successful_write_reply_observer_.ObserveNextWriteCallback(
1136 soon_out_of_scope_pref_store.get());
1137 write_callback_observer_.ObserveNextWriteCallback(
1138 soon_out_of_scope_pref_store.get());
Jinho Bang84b58bd2018-01-01 21:44:481139 file_writer->WriteNow(std::make_unique<std::string>("foo"));
probergefc46ac12016-09-21 18:03:001140 }
Francois Doray405dd2d2017-06-09 15:23:331141 scoped_task_environment_.RunUntilIdle();
probergefc46ac12016-09-21 18:03:001142 EXPECT_FALSE(successful_write_reply_observer_.GetAndResetObservationState());
probergec503d692016-09-28 19:51:051143 EXPECT_TRUE(write_callback_observer_.GetAndResetPreWriteObservationState());
probergefc46ac12016-09-21 18:03:001144 EXPECT_EQ(CALLED_WITH_SUCCESS,
probergec503d692016-09-28 19:51:051145 write_callback_observer_.GetAndResetPostWriteObservationState());
probergefc46ac12016-09-21 18:03:001146}
1147
vabr5d919d62016-09-30 08:55:361148} // namespace base