blob: 15e2872c1d7a49abd449ab7ac26c3a1b7a7a514b [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>(
Gabriel Charette1f53ca32018-08-07 21:31:17455 input_file, std::move(intercepting_pref_filter));
[email protected]e33c9512014-05-12 02:24:13456
457 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_ASYNCHRONOUS_TASK_INCOMPLETE,
458 pref_store->ReadPrefs());
459 EXPECT_FALSE(pref_store->ReadOnly());
460
461 // The store shouldn't be considered initialized until the interceptor
462 // returns.
463 EXPECT_TRUE(raw_intercepting_pref_filter_->has_intercepted_prefs());
464 EXPECT_FALSE(pref_store->IsInitializationComplete());
Ivan Kotenkov75b1c3a2017-10-24 14:47:24465 EXPECT_FALSE(pref_store->GetValue(kHomePage, nullptr));
[email protected]e33c9512014-05-12 02:24:13466
467 raw_intercepting_pref_filter_->ReleasePrefs();
468
469 EXPECT_FALSE(raw_intercepting_pref_filter_->has_intercepted_prefs());
470 EXPECT_TRUE(pref_store->IsInitializationComplete());
Ivan Kotenkov75b1c3a2017-10-24 14:47:24471 EXPECT_TRUE(pref_store->GetValue(kHomePage, nullptr));
[email protected]e33c9512014-05-12 02:24:13472
473 // The JSON file looks like this:
474 // {
475 // "homepage": "http://www.cnn.com",
476 // "some_directory": "/usr/local/",
477 // "tabs": {
478 // "new_windows_in_tabs": true,
479 // "max_tabs": 20
480 // }
481 // }
482
Francois Doray405dd2d2017-06-09 15:23:33483 RunBasicJsonPrefStoreTest(pref_store.get(), input_file, GetParam(),
484 &scoped_task_environment_);
[email protected]e33c9512014-05-12 02:24:13485}
486
Francois Doray405dd2d2017-06-09 15:23:33487TEST_P(JsonPrefStoreTest, ReadAsyncWithInterceptor) {
vabr8023d872016-09-15 08:12:22488 base::FilePath input_file = temp_dir_.GetPath().AppendASCII("write.json");
brettw58cd1f12016-01-30 05:56:05489 ASSERT_LT(0, base::WriteFile(input_file,
490 kReadJson, arraysize(kReadJson) - 1));
[email protected]e33c9512014-05-12 02:24:13491
dcheng5f043bc2016-04-22 19:09:06492 std::unique_ptr<InterceptingPrefFilter> intercepting_pref_filter(
[email protected]e33c9512014-05-12 02:24:13493 new InterceptingPrefFilter());
494 InterceptingPrefFilter* raw_intercepting_pref_filter_ =
495 intercepting_pref_filter.get();
Francois Doray405dd2d2017-06-09 15:23:33496 auto pref_store = base::MakeRefCounted<JsonPrefStore>(
Gabriel Charette1f53ca32018-08-07 21:31:17497 input_file, std::move(intercepting_pref_filter));
[email protected]e33c9512014-05-12 02:24:13498
499 MockPrefStoreObserver mock_observer;
500 pref_store->AddObserver(&mock_observer);
501
502 // Ownership of the |mock_error_delegate| is handed to the |pref_store| below.
503 MockReadErrorDelegate* mock_error_delegate = new MockReadErrorDelegate;
504
505 {
506 pref_store->ReadPrefsAsync(mock_error_delegate);
507
508 EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(0);
509 // EXPECT_CALL(*mock_error_delegate,
510 // OnError(PersistentPrefStore::PREF_READ_ERROR_NONE)).Times(0);
Francois Doray405dd2d2017-06-09 15:23:33511 scoped_task_environment_.RunUntilIdle();
[email protected]e33c9512014-05-12 02:24:13512
513 EXPECT_FALSE(pref_store->ReadOnly());
514 EXPECT_TRUE(raw_intercepting_pref_filter_->has_intercepted_prefs());
515 EXPECT_FALSE(pref_store->IsInitializationComplete());
Ivan Kotenkov75b1c3a2017-10-24 14:47:24516 EXPECT_FALSE(pref_store->GetValue(kHomePage, nullptr));
[email protected]e33c9512014-05-12 02:24:13517 }
518
519 {
520 EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(1);
521 // EXPECT_CALL(*mock_error_delegate,
522 // OnError(PersistentPrefStore::PREF_READ_ERROR_NONE)).Times(0);
523
524 raw_intercepting_pref_filter_->ReleasePrefs();
525
526 EXPECT_FALSE(pref_store->ReadOnly());
527 EXPECT_FALSE(raw_intercepting_pref_filter_->has_intercepted_prefs());
528 EXPECT_TRUE(pref_store->IsInitializationComplete());
Ivan Kotenkov75b1c3a2017-10-24 14:47:24529 EXPECT_TRUE(pref_store->GetValue(kHomePage, nullptr));
[email protected]e33c9512014-05-12 02:24:13530 }
531
532 pref_store->RemoveObserver(&mock_observer);
533
534 // The JSON file looks like this:
535 // {
536 // "homepage": "http://www.cnn.com",
537 // "some_directory": "/usr/local/",
538 // "tabs": {
539 // "new_windows_in_tabs": true,
540 // "max_tabs": 20
541 // }
542 // }
543
Francois Doray405dd2d2017-06-09 15:23:33544 RunBasicJsonPrefStoreTest(pref_store.get(), input_file, GetParam(),
545 &scoped_task_environment_);
[email protected]e33c9512014-05-12 02:24:13546}
547
Gabriel Charette788eaf62018-08-07 20:11:46548TEST_P(JsonPrefStoreTest, WriteCountHistogramTestBasic) {
brettw58cd1f12016-01-30 05:56:05549 base::HistogramTester histogram_tester;
550
raymesbfb910a2015-04-29 07:43:09551 SimpleTestClock* test_clock = new SimpleTestClock;
552 SetCurrentTimeInMinutes(0, test_clock);
553 JsonPrefStore::WriteCountHistogram histogram(
554 base::TimeDelta::FromSeconds(10),
555 base::FilePath(FILE_PATH_LITERAL("/tmp/Local State")),
dcheng5f043bc2016-04-22 19:09:06556 std::unique_ptr<base::Clock>(test_clock));
avi9ef8bb02015-12-24 05:29:36557 int32_t report_interval =
raymesbfb910a2015-04-29 07:43:09558 JsonPrefStore::WriteCountHistogram::kHistogramWriteReportIntervalMins;
559
560 histogram.RecordWriteOccured();
561
562 SetCurrentTimeInMinutes(1.5 * report_interval, test_clock);
563 histogram.ReportOutstandingWrites();
dcheng5f043bc2016-04-22 19:09:06564 std::unique_ptr<HistogramSamples> samples =
raymesbfb910a2015-04-29 07:43:09565 histogram.GetHistogram()->SnapshotSamples();
brettw58cd1f12016-01-30 05:56:05566
567 std::string histogram_name = histogram.GetHistogram()->histogram_name();
568 histogram_tester.ExpectBucketCount(histogram_name, 1, 1);
569 histogram_tester.ExpectTotalCount(histogram_name, 1);
raymesbfb910a2015-04-29 07:43:09570
571 ASSERT_EQ("Settings.JsonDataWriteCount.Local_State",
Brian Whited1c91082017-11-03 14:46:42572 std::string(histogram.GetHistogram()->histogram_name()));
raymesbfb910a2015-04-29 07:43:09573 ASSERT_TRUE(histogram.GetHistogram()->HasConstructionArguments(1, 30, 31));
574}
575
Gabriel Charette788eaf62018-08-07 20:11:46576TEST_P(JsonPrefStoreTest, WriteCountHistogramTestSinglePeriod) {
brettw58cd1f12016-01-30 05:56:05577 base::HistogramTester histogram_tester;
578
raymesbfb910a2015-04-29 07:43:09579 SimpleTestClock* test_clock = new SimpleTestClock;
580 SetCurrentTimeInMinutes(0, test_clock);
581 JsonPrefStore::WriteCountHistogram histogram(
582 base::TimeDelta::FromSeconds(10),
583 base::FilePath(FILE_PATH_LITERAL("/tmp/Local State")),
dcheng5f043bc2016-04-22 19:09:06584 std::unique_ptr<base::Clock>(test_clock));
avi9ef8bb02015-12-24 05:29:36585 int32_t report_interval =
raymesbfb910a2015-04-29 07:43:09586 JsonPrefStore::WriteCountHistogram::kHistogramWriteReportIntervalMins;
587
588 histogram.RecordWriteOccured();
589 SetCurrentTimeInMinutes(0.5 * report_interval, test_clock);
590 histogram.RecordWriteOccured();
591 SetCurrentTimeInMinutes(0.7 * report_interval, test_clock);
592 histogram.RecordWriteOccured();
593
594 // Nothing should be recorded until the report period has elapsed.
brettw58cd1f12016-01-30 05:56:05595 std::string histogram_name = histogram.GetHistogram()->histogram_name();
596 histogram_tester.ExpectTotalCount(histogram_name, 0);
raymesbfb910a2015-04-29 07:43:09597
598 SetCurrentTimeInMinutes(1.3 * report_interval, test_clock);
599 histogram.RecordWriteOccured();
600
601 // Now the report period has elapsed.
brettw58cd1f12016-01-30 05:56:05602 histogram_tester.ExpectBucketCount(histogram_name, 3, 1);
603 histogram_tester.ExpectTotalCount(histogram_name, 1);
raymesbfb910a2015-04-29 07:43:09604
605 // The last write won't be recorded because the second count period hasn't
606 // fully elapsed.
607 SetCurrentTimeInMinutes(1.5 * report_interval, test_clock);
608 histogram.ReportOutstandingWrites();
609
brettw58cd1f12016-01-30 05:56:05610 histogram_tester.ExpectBucketCount(histogram_name, 3, 1);
611 histogram_tester.ExpectTotalCount(histogram_name, 1);
raymesbfb910a2015-04-29 07:43:09612}
613
Gabriel Charette788eaf62018-08-07 20:11:46614TEST_P(JsonPrefStoreTest, WriteCountHistogramTestMultiplePeriods) {
brettw58cd1f12016-01-30 05:56:05615 base::HistogramTester histogram_tester;
616
raymesbfb910a2015-04-29 07:43:09617 SimpleTestClock* test_clock = new SimpleTestClock;
618 SetCurrentTimeInMinutes(0, test_clock);
619 JsonPrefStore::WriteCountHistogram histogram(
620 base::TimeDelta::FromSeconds(10),
621 base::FilePath(FILE_PATH_LITERAL("/tmp/Local State")),
dcheng5f043bc2016-04-22 19:09:06622 std::unique_ptr<base::Clock>(test_clock));
avi9ef8bb02015-12-24 05:29:36623 int32_t report_interval =
raymesbfb910a2015-04-29 07:43:09624 JsonPrefStore::WriteCountHistogram::kHistogramWriteReportIntervalMins;
625
626 histogram.RecordWriteOccured();
627 SetCurrentTimeInMinutes(0.5 * report_interval, test_clock);
628 histogram.RecordWriteOccured();
629 SetCurrentTimeInMinutes(0.7 * report_interval, test_clock);
630 histogram.RecordWriteOccured();
631 SetCurrentTimeInMinutes(1.3 * report_interval, test_clock);
632 histogram.RecordWriteOccured();
633 SetCurrentTimeInMinutes(1.5 * report_interval, test_clock);
634 histogram.RecordWriteOccured();
635 SetCurrentTimeInMinutes(2.1 * report_interval, test_clock);
636 histogram.RecordWriteOccured();
637 SetCurrentTimeInMinutes(2.5 * report_interval, test_clock);
638 histogram.RecordWriteOccured();
639 SetCurrentTimeInMinutes(2.7 * report_interval, test_clock);
640 histogram.RecordWriteOccured();
641 SetCurrentTimeInMinutes(3.3 * report_interval, test_clock);
642 histogram.RecordWriteOccured();
643
644 // The last write won't be recorded because the second count period hasn't
645 // fully elapsed
646 SetCurrentTimeInMinutes(3.5 * report_interval, test_clock);
647 histogram.ReportOutstandingWrites();
brettw58cd1f12016-01-30 05:56:05648 std::string histogram_name = histogram.GetHistogram()->histogram_name();
649 histogram_tester.ExpectBucketCount(histogram_name, 3, 2);
650 histogram_tester.ExpectBucketCount(histogram_name, 2, 1);
651 histogram_tester.ExpectTotalCount(histogram_name, 3);
raymesbfb910a2015-04-29 07:43:09652}
653
Gabriel Charette788eaf62018-08-07 20:11:46654TEST_P(JsonPrefStoreTest, WriteCountHistogramTestPeriodWithGaps) {
brettw58cd1f12016-01-30 05:56:05655 base::HistogramTester histogram_tester;
656
raymesbfb910a2015-04-29 07:43:09657 SimpleTestClock* test_clock = new SimpleTestClock;
658 SetCurrentTimeInMinutes(0, test_clock);
659 JsonPrefStore::WriteCountHistogram histogram(
660 base::TimeDelta::FromSeconds(10),
661 base::FilePath(FILE_PATH_LITERAL("/tmp/Local State")),
dcheng5f043bc2016-04-22 19:09:06662 std::unique_ptr<base::Clock>(test_clock));
avi9ef8bb02015-12-24 05:29:36663 int32_t report_interval =
raymesbfb910a2015-04-29 07:43:09664 JsonPrefStore::WriteCountHistogram::kHistogramWriteReportIntervalMins;
665
666 // 1 write in the first period.
667 histogram.RecordWriteOccured();
668
669 // No writes in the second and third periods.
670
671 // 2 writes in the fourth period.
672 SetCurrentTimeInMinutes(3.1 * report_interval, test_clock);
673 histogram.RecordWriteOccured();
674 SetCurrentTimeInMinutes(3.3 * report_interval, test_clock);
675 histogram.RecordWriteOccured();
676
677 // No writes in the fifth period.
678
679 // 3 writes in the sixth period.
680 SetCurrentTimeInMinutes(5.1 * report_interval, test_clock);
681 histogram.RecordWriteOccured();
682 SetCurrentTimeInMinutes(5.3 * report_interval, test_clock);
683 histogram.RecordWriteOccured();
684 SetCurrentTimeInMinutes(5.5 * report_interval, test_clock);
685 histogram.RecordWriteOccured();
686
687 SetCurrentTimeInMinutes(6.1 * report_interval, test_clock);
688 histogram.ReportOutstandingWrites();
brettw58cd1f12016-01-30 05:56:05689 std::string histogram_name = histogram.GetHistogram()->histogram_name();
690 histogram_tester.ExpectBucketCount(histogram_name, 0, 3);
691 histogram_tester.ExpectBucketCount(histogram_name, 1, 1);
692 histogram_tester.ExpectBucketCount(histogram_name, 2, 1);
693 histogram_tester.ExpectBucketCount(histogram_name, 3, 1);
694 histogram_tester.ExpectTotalCount(histogram_name, 6);
raymesbfb910a2015-04-29 07:43:09695}
696
Francois Doray405dd2d2017-06-09 15:23:33697INSTANTIATE_TEST_CASE_P(
698 WithoutCallback,
699 JsonPrefStoreTest,
700 ::testing::Values(CommitPendingWriteMode::WITHOUT_CALLBACK));
701INSTANTIATE_TEST_CASE_P(
702 WithCallback,
703 JsonPrefStoreTest,
704 ::testing::Values(CommitPendingWriteMode::WITH_CALLBACK));
Gabriel Charette788eaf62018-08-07 20:11:46705INSTANTIATE_TEST_CASE_P(
706 WithSynchronousCallback,
707 JsonPrefStoreTest,
708 ::testing::Values(CommitPendingWriteMode::WITH_SYNCHRONOUS_CALLBACK));
Francois Doray405dd2d2017-06-09 15:23:33709
raymes4b6e14e2015-05-12 00:10:30710class JsonPrefStoreLossyWriteTest : public JsonPrefStoreTest {
probergefc46ac12016-09-21 18:03:00711 public:
712 JsonPrefStoreLossyWriteTest() = default;
713
raymes4b6e14e2015-05-12 00:10:30714 protected:
715 void SetUp() override {
716 JsonPrefStoreTest::SetUp();
vabr8023d872016-09-15 08:12:22717 test_file_ = temp_dir_.GetPath().AppendASCII("test.json");
raymes4b6e14e2015-05-12 00:10:30718 }
719
raymes4b6e14e2015-05-12 00:10:30720 scoped_refptr<JsonPrefStore> CreatePrefStore() {
Francois Doray405dd2d2017-06-09 15:23:33721 return base::MakeRefCounted<JsonPrefStore>(test_file_);
raymes4b6e14e2015-05-12 00:10:30722 }
723
724 // Return the ImportantFileWriter for a given JsonPrefStore.
probergefc46ac12016-09-21 18:03:00725 ImportantFileWriter* GetImportantFileWriter(JsonPrefStore* pref_store) {
raymes4b6e14e2015-05-12 00:10:30726 return &(pref_store->writer_);
727 }
728
729 // Get the contents of kTestFile. Pumps the message loop before returning the
730 // result.
731 std::string GetTestFileContents() {
Francois Doray405dd2d2017-06-09 15:23:33732 scoped_task_environment_.RunUntilIdle();
raymes4b6e14e2015-05-12 00:10:30733 std::string file_contents;
734 ReadFileToString(test_file_, &file_contents);
735 return file_contents;
736 }
737
738 private:
739 base::FilePath test_file_;
probergefc46ac12016-09-21 18:03:00740
741 DISALLOW_COPY_AND_ASSIGN(JsonPrefStoreLossyWriteTest);
raymes4b6e14e2015-05-12 00:10:30742};
743
Gabriel Charette788eaf62018-08-07 20:11:46744TEST_P(JsonPrefStoreLossyWriteTest, LossyWriteBasic) {
raymes4b6e14e2015-05-12 00:10:30745 scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore();
probergefc46ac12016-09-21 18:03:00746 ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store.get());
raymes4b6e14e2015-05-12 00:10:30747
748 // Set a normal pref and check that it gets scheduled to be written.
749 ASSERT_FALSE(file_writer->HasPendingWrite());
Jinho Bang84b58bd2018-01-01 21:44:48750 pref_store->SetValue("normal", std::make_unique<base::Value>("normal"),
raymes4b6e14e2015-05-12 00:10:30751 WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
752 ASSERT_TRUE(file_writer->HasPendingWrite());
753 file_writer->DoScheduledWrite();
754 ASSERT_EQ("{\"normal\":\"normal\"}", GetTestFileContents());
755 ASSERT_FALSE(file_writer->HasPendingWrite());
756
757 // Set a lossy pref and check that it is not scheduled to be written.
758 // SetValue/RemoveValue.
Jinho Bang84b58bd2018-01-01 21:44:48759 pref_store->SetValue("lossy", std::make_unique<base::Value>("lossy"),
raymes4b6e14e2015-05-12 00:10:30760 WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
761 ASSERT_FALSE(file_writer->HasPendingWrite());
762 pref_store->RemoveValue("lossy", WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
763 ASSERT_FALSE(file_writer->HasPendingWrite());
764
765 // SetValueSilently/RemoveValueSilently.
Jinho Bang84b58bd2018-01-01 21:44:48766 pref_store->SetValueSilently("lossy", std::make_unique<base::Value>("lossy"),
raymes4b6e14e2015-05-12 00:10:30767 WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
768 ASSERT_FALSE(file_writer->HasPendingWrite());
769 pref_store->RemoveValueSilently("lossy",
770 WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
771 ASSERT_FALSE(file_writer->HasPendingWrite());
772
773 // ReportValueChanged.
Jinho Bang84b58bd2018-01-01 21:44:48774 pref_store->SetValue("lossy", std::make_unique<base::Value>("lossy"),
raymes4b6e14e2015-05-12 00:10:30775 WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
776 ASSERT_FALSE(file_writer->HasPendingWrite());
777 pref_store->ReportValueChanged("lossy",
778 WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
779 ASSERT_FALSE(file_writer->HasPendingWrite());
780
781 // Call CommitPendingWrite and check that the lossy pref and the normal pref
782 // are there with the last values set above.
Francois Doray405dd2d2017-06-09 15:23:33783 pref_store->CommitPendingWrite(base::OnceClosure());
raymes4b6e14e2015-05-12 00:10:30784 ASSERT_FALSE(file_writer->HasPendingWrite());
785 ASSERT_EQ("{\"lossy\":\"lossy\",\"normal\":\"normal\"}",
786 GetTestFileContents());
787}
788
Gabriel Charette788eaf62018-08-07 20:11:46789TEST_P(JsonPrefStoreLossyWriteTest, LossyWriteMixedLossyFirst) {
raymes4b6e14e2015-05-12 00:10:30790 scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore();
probergefc46ac12016-09-21 18:03:00791 ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store.get());
raymes4b6e14e2015-05-12 00:10:30792
793 // Set a lossy pref and check that it is not scheduled to be written.
794 ASSERT_FALSE(file_writer->HasPendingWrite());
Jinho Bang84b58bd2018-01-01 21:44:48795 pref_store->SetValue("lossy", std::make_unique<base::Value>("lossy"),
raymes4b6e14e2015-05-12 00:10:30796 WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
797 ASSERT_FALSE(file_writer->HasPendingWrite());
798
799 // Set a normal pref and check that it is scheduled to be written.
Jinho Bang84b58bd2018-01-01 21:44:48800 pref_store->SetValue("normal", std::make_unique<base::Value>("normal"),
raymes4b6e14e2015-05-12 00:10:30801 WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
802 ASSERT_TRUE(file_writer->HasPendingWrite());
803
804 // Call DoScheduledWrite and check both prefs get written.
805 file_writer->DoScheduledWrite();
806 ASSERT_EQ("{\"lossy\":\"lossy\",\"normal\":\"normal\"}",
807 GetTestFileContents());
808 ASSERT_FALSE(file_writer->HasPendingWrite());
809}
810
Gabriel Charette788eaf62018-08-07 20:11:46811TEST_P(JsonPrefStoreLossyWriteTest, LossyWriteMixedLossySecond) {
raymes4b6e14e2015-05-12 00:10:30812 scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore();
probergefc46ac12016-09-21 18:03:00813 ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store.get());
raymes4b6e14e2015-05-12 00:10:30814
815 // Set a normal pref and check that it is scheduled to be written.
816 ASSERT_FALSE(file_writer->HasPendingWrite());
Jinho Bang84b58bd2018-01-01 21:44:48817 pref_store->SetValue("normal", std::make_unique<base::Value>("normal"),
raymes4b6e14e2015-05-12 00:10:30818 WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
819 ASSERT_TRUE(file_writer->HasPendingWrite());
820
821 // Set a lossy pref and check that the write is still scheduled.
Jinho Bang84b58bd2018-01-01 21:44:48822 pref_store->SetValue("lossy", std::make_unique<base::Value>("lossy"),
raymes4b6e14e2015-05-12 00:10:30823 WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
824 ASSERT_TRUE(file_writer->HasPendingWrite());
825
826 // Call DoScheduledWrite and check both prefs get written.
827 file_writer->DoScheduledWrite();
828 ASSERT_EQ("{\"lossy\":\"lossy\",\"normal\":\"normal\"}",
829 GetTestFileContents());
830 ASSERT_FALSE(file_writer->HasPendingWrite());
831}
832
Gabriel Charette788eaf62018-08-07 20:11:46833TEST_P(JsonPrefStoreLossyWriteTest, ScheduleLossyWrite) {
benwells26730592015-05-28 13:08:08834 scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore();
probergefc46ac12016-09-21 18:03:00835 ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store.get());
benwells26730592015-05-28 13:08:08836
837 // Set a lossy pref and check that it is not scheduled to be written.
Jinho Bang84b58bd2018-01-01 21:44:48838 pref_store->SetValue("lossy", std::make_unique<base::Value>("lossy"),
benwells26730592015-05-28 13:08:08839 WriteablePrefStore::LOSSY_PREF_WRITE_FLAG);
840 ASSERT_FALSE(file_writer->HasPendingWrite());
841
842 // Schedule pending lossy writes and check that it is scheduled.
843 pref_store->SchedulePendingLossyWrites();
844 ASSERT_TRUE(file_writer->HasPendingWrite());
845
846 // Call CommitPendingWrite and check that the lossy pref is there with the
847 // last value set above.
Francois Doray405dd2d2017-06-09 15:23:33848 pref_store->CommitPendingWrite(base::OnceClosure());
benwells26730592015-05-28 13:08:08849 ASSERT_FALSE(file_writer->HasPendingWrite());
850 ASSERT_EQ("{\"lossy\":\"lossy\"}", GetTestFileContents());
851}
852
Gabriel Charette788eaf62018-08-07 20:11:46853INSTANTIATE_TEST_CASE_P(
854 WithoutCallback,
855 JsonPrefStoreLossyWriteTest,
856 ::testing::Values(CommitPendingWriteMode::WITHOUT_CALLBACK));
857INSTANTIATE_TEST_CASE_P(
858 WithReply,
859 JsonPrefStoreLossyWriteTest,
860 ::testing::Values(CommitPendingWriteMode::WITH_CALLBACK));
861INSTANTIATE_TEST_CASE_P(
862 WithNotify,
863 JsonPrefStoreLossyWriteTest,
864 ::testing::Values(CommitPendingWriteMode::WITH_SYNCHRONOUS_CALLBACK));
865
probergefc46ac12016-09-21 18:03:00866class SuccessfulWriteReplyObserver {
867 public:
868 SuccessfulWriteReplyObserver() = default;
869
870 // Returns true if a successful write was observed via on_successful_write()
871 // and resets the observation state to false regardless.
872 bool GetAndResetObservationState() {
873 bool was_successful_write_observed = successful_write_reply_observed_;
874 successful_write_reply_observed_ = false;
875 return was_successful_write_observed;
876 }
877
878 // Register OnWrite() to be called on the next write of |json_pref_store|.
879 void ObserveNextWriteCallback(JsonPrefStore* json_pref_store);
880
881 void OnSuccessfulWrite() {
882 EXPECT_FALSE(successful_write_reply_observed_);
883 successful_write_reply_observed_ = true;
884 }
885
886 private:
887 bool successful_write_reply_observed_ = false;
888
889 DISALLOW_COPY_AND_ASSIGN(SuccessfulWriteReplyObserver);
890};
891
892void SuccessfulWriteReplyObserver::ObserveNextWriteCallback(
893 JsonPrefStore* json_pref_store) {
894 json_pref_store->RegisterOnNextSuccessfulWriteReply(
895 base::Bind(&SuccessfulWriteReplyObserver::OnSuccessfulWrite,
896 base::Unretained(this)));
897}
898
899enum WriteCallbackObservationState {
900 NOT_CALLED,
901 CALLED_WITH_ERROR,
902 CALLED_WITH_SUCCESS,
903};
904
probergec503d692016-09-28 19:51:05905class WriteCallbacksObserver {
probergefc46ac12016-09-21 18:03:00906 public:
probergec503d692016-09-28 19:51:05907 WriteCallbacksObserver() = default;
probergefc46ac12016-09-21 18:03:00908
909 // Register OnWrite() to be called on the next write of |json_pref_store|.
910 void ObserveNextWriteCallback(JsonPrefStore* json_pref_store);
911
probergec503d692016-09-28 19:51:05912 // Returns whether OnPreWrite() was called, and resets the observation state
913 // to false.
914 bool GetAndResetPreWriteObservationState();
probergefc46ac12016-09-21 18:03:00915
probergec503d692016-09-28 19:51:05916 // Returns the |WriteCallbackObservationState| which was observed, then resets
917 // it to |NOT_CALLED|.
918 WriteCallbackObservationState GetAndResetPostWriteObservationState();
919
920 JsonPrefStore::OnWriteCallbackPair GetCallbackPair() {
921 return std::make_pair(
922 base::Bind(&WriteCallbacksObserver::OnPreWrite, base::Unretained(this)),
923 base::Bind(&WriteCallbacksObserver::OnPostWrite,
924 base::Unretained(this)));
925 }
926
927 void OnPreWrite() {
928 EXPECT_FALSE(pre_write_called_);
929 pre_write_called_ = true;
930 }
931
932 void OnPostWrite(bool success) {
933 EXPECT_EQ(NOT_CALLED, post_write_observation_state_);
934 post_write_observation_state_ =
935 success ? CALLED_WITH_SUCCESS : CALLED_WITH_ERROR;
probergefc46ac12016-09-21 18:03:00936 }
937
938 private:
probergec503d692016-09-28 19:51:05939 bool pre_write_called_ = false;
940 WriteCallbackObservationState post_write_observation_state_ = NOT_CALLED;
probergefc46ac12016-09-21 18:03:00941
probergec503d692016-09-28 19:51:05942 DISALLOW_COPY_AND_ASSIGN(WriteCallbacksObserver);
probergefc46ac12016-09-21 18:03:00943};
944
probergec503d692016-09-28 19:51:05945void WriteCallbacksObserver::ObserveNextWriteCallback(JsonPrefStore* writer) {
946 writer->RegisterOnNextWriteSynchronousCallbacks(GetCallbackPair());
947}
948
949bool WriteCallbacksObserver::GetAndResetPreWriteObservationState() {
950 bool observation_state = pre_write_called_;
951 pre_write_called_ = false;
952 return observation_state;
probergefc46ac12016-09-21 18:03:00953}
954
955WriteCallbackObservationState
probergec503d692016-09-28 19:51:05956WriteCallbacksObserver::GetAndResetPostWriteObservationState() {
957 WriteCallbackObservationState state = post_write_observation_state_;
958 pre_write_called_ = false;
959 post_write_observation_state_ = NOT_CALLED;
probergefc46ac12016-09-21 18:03:00960 return state;
961}
962
Gabriel Charette788eaf62018-08-07 20:11:46963class JsonPrefStoreCallbackTest : public testing::Test {
probergefc46ac12016-09-21 18:03:00964 public:
965 JsonPrefStoreCallbackTest() = default;
966
967 protected:
968 void SetUp() override {
Gabriel Charette788eaf62018-08-07 20:11:46969 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
vabr5d919d62016-09-30 08:55:36970 test_file_ = temp_dir_.GetPath().AppendASCII("test.json");
probergefc46ac12016-09-21 18:03:00971 }
972
973 scoped_refptr<JsonPrefStore> CreatePrefStore() {
Francois Doray405dd2d2017-06-09 15:23:33974 return base::MakeRefCounted<JsonPrefStore>(test_file_);
probergefc46ac12016-09-21 18:03:00975 }
976
977 // Return the ImportantFileWriter for a given JsonPrefStore.
978 ImportantFileWriter* GetImportantFileWriter(JsonPrefStore* pref_store) {
979 return &(pref_store->writer_);
980 }
981
982 void TriggerFakeWriteForCallback(JsonPrefStore* pref_store, bool success) {
983 JsonPrefStore::PostWriteCallback(
984 base::Bind(&JsonPrefStore::RunOrScheduleNextSuccessfulWriteCallback,
985 pref_store->AsWeakPtr()),
probergec503d692016-09-28 19:51:05986 base::Bind(&WriteCallbacksObserver::OnPostWrite,
probergefc46ac12016-09-21 18:03:00987 base::Unretained(&write_callback_observer_)),
988 base::SequencedTaskRunnerHandle::Get(), success);
989 }
990
991 SuccessfulWriteReplyObserver successful_write_reply_observer_;
probergec503d692016-09-28 19:51:05992 WriteCallbacksObserver write_callback_observer_;
probergefc46ac12016-09-21 18:03:00993
Gabriel Charette788eaf62018-08-07 20:11:46994 protected:
995 base::test::ScopedTaskEnvironment scoped_task_environment_{
996 base::test::ScopedTaskEnvironment::MainThreadType::DEFAULT,
997 base::test::ScopedTaskEnvironment::ExecutionMode::QUEUED};
998
999 base::ScopedTempDir temp_dir_;
1000
probergefc46ac12016-09-21 18:03:001001 private:
1002 base::FilePath test_file_;
1003
1004 DISALLOW_COPY_AND_ASSIGN(JsonPrefStoreCallbackTest);
1005};
1006
Francois Doray5f547952017-07-25 21:02:051007TEST_F(JsonPrefStoreCallbackTest, TestSerializeDataCallbacks) {
probergec503d692016-09-28 19:51:051008 base::FilePath input_file = temp_dir_.GetPath().AppendASCII("write.json");
1009 ASSERT_LT(0,
1010 base::WriteFile(input_file, kReadJson, arraysize(kReadJson) - 1));
1011
1012 std::unique_ptr<InterceptingPrefFilter> intercepting_pref_filter(
1013 new InterceptingPrefFilter(write_callback_observer_.GetCallbackPair()));
Francois Doray405dd2d2017-06-09 15:23:331014 auto pref_store = base::MakeRefCounted<JsonPrefStore>(
Gabriel Charette1f53ca32018-08-07 21:31:171015 input_file, std::move(intercepting_pref_filter));
probergec503d692016-09-28 19:51:051016 ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store.get());
1017
1018 EXPECT_EQ(NOT_CALLED,
1019 write_callback_observer_.GetAndResetPostWriteObservationState());
Jinho Bang84b58bd2018-01-01 21:44:481020 pref_store->SetValue("normal", std::make_unique<base::Value>("normal"),
probergec503d692016-09-28 19:51:051021 WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
1022 file_writer->DoScheduledWrite();
1023
1024 // The observer should not be invoked right away.
1025 EXPECT_FALSE(write_callback_observer_.GetAndResetPreWriteObservationState());
1026 EXPECT_EQ(NOT_CALLED,
1027 write_callback_observer_.GetAndResetPostWriteObservationState());
1028
Francois Doray405dd2d2017-06-09 15:23:331029 scoped_task_environment_.RunUntilIdle();
probergec503d692016-09-28 19:51:051030
1031 EXPECT_TRUE(write_callback_observer_.GetAndResetPreWriteObservationState());
1032 EXPECT_EQ(CALLED_WITH_SUCCESS,
1033 write_callback_observer_.GetAndResetPostWriteObservationState());
1034}
1035
1036TEST_F(JsonPrefStoreCallbackTest, TestPostWriteCallbacks) {
probergefc46ac12016-09-21 18:03:001037 scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore();
1038 ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store.get());
1039
probergec503d692016-09-28 19:51:051040 // Test RegisterOnNextWriteSynchronousCallbacks after
probergefc46ac12016-09-21 18:03:001041 // RegisterOnNextSuccessfulWriteReply.
1042 successful_write_reply_observer_.ObserveNextWriteCallback(pref_store.get());
1043 write_callback_observer_.ObserveNextWriteCallback(pref_store.get());
Jinho Bang84b58bd2018-01-01 21:44:481044 file_writer->WriteNow(std::make_unique<std::string>("foo"));
Francois Doray405dd2d2017-06-09 15:23:331045 scoped_task_environment_.RunUntilIdle();
probergefc46ac12016-09-21 18:03:001046 EXPECT_TRUE(successful_write_reply_observer_.GetAndResetObservationState());
probergec503d692016-09-28 19:51:051047 EXPECT_TRUE(write_callback_observer_.GetAndResetPreWriteObservationState());
1048 EXPECT_EQ(CALLED_WITH_SUCCESS,
1049 write_callback_observer_.GetAndResetPostWriteObservationState());
probergefc46ac12016-09-21 18:03:001050
1051 // Test RegisterOnNextSuccessfulWriteReply after
probergec503d692016-09-28 19:51:051052 // RegisterOnNextWriteSynchronousCallbacks.
probergefc46ac12016-09-21 18:03:001053 successful_write_reply_observer_.ObserveNextWriteCallback(pref_store.get());
1054 write_callback_observer_.ObserveNextWriteCallback(pref_store.get());
Jinho Bang84b58bd2018-01-01 21:44:481055 file_writer->WriteNow(std::make_unique<std::string>("foo"));
Francois Doray405dd2d2017-06-09 15:23:331056 scoped_task_environment_.RunUntilIdle();
probergefc46ac12016-09-21 18:03:001057 EXPECT_TRUE(successful_write_reply_observer_.GetAndResetObservationState());
probergec503d692016-09-28 19:51:051058 EXPECT_TRUE(write_callback_observer_.GetAndResetPreWriteObservationState());
1059 EXPECT_EQ(CALLED_WITH_SUCCESS,
1060 write_callback_observer_.GetAndResetPostWriteObservationState());
probergefc46ac12016-09-21 18:03:001061
1062 // Test RegisterOnNextSuccessfulWriteReply only.
1063 successful_write_reply_observer_.ObserveNextWriteCallback(pref_store.get());
Jinho Bang84b58bd2018-01-01 21:44:481064 file_writer->WriteNow(std::make_unique<std::string>("foo"));
Francois Doray405dd2d2017-06-09 15:23:331065 scoped_task_environment_.RunUntilIdle();
probergefc46ac12016-09-21 18:03:001066 EXPECT_TRUE(successful_write_reply_observer_.GetAndResetObservationState());
probergec503d692016-09-28 19:51:051067 EXPECT_FALSE(write_callback_observer_.GetAndResetPreWriteObservationState());
1068 EXPECT_EQ(NOT_CALLED,
1069 write_callback_observer_.GetAndResetPostWriteObservationState());
probergefc46ac12016-09-21 18:03:001070
probergec503d692016-09-28 19:51:051071 // Test RegisterOnNextWriteSynchronousCallbacks only.
probergefc46ac12016-09-21 18:03:001072 write_callback_observer_.ObserveNextWriteCallback(pref_store.get());
Jinho Bang84b58bd2018-01-01 21:44:481073 file_writer->WriteNow(std::make_unique<std::string>("foo"));
Francois Doray405dd2d2017-06-09 15:23:331074 scoped_task_environment_.RunUntilIdle();
probergefc46ac12016-09-21 18:03:001075 EXPECT_FALSE(successful_write_reply_observer_.GetAndResetObservationState());
probergec503d692016-09-28 19:51:051076 EXPECT_TRUE(write_callback_observer_.GetAndResetPreWriteObservationState());
1077 EXPECT_EQ(CALLED_WITH_SUCCESS,
1078 write_callback_observer_.GetAndResetPostWriteObservationState());
probergefc46ac12016-09-21 18:03:001079}
1080
probergec503d692016-09-28 19:51:051081TEST_F(JsonPrefStoreCallbackTest, TestPostWriteCallbacksWithFakeFailure) {
probergefc46ac12016-09-21 18:03:001082 scoped_refptr<JsonPrefStore> pref_store = CreatePrefStore();
1083
1084 // Confirm that the observers are invoked.
1085 successful_write_reply_observer_.ObserveNextWriteCallback(pref_store.get());
1086 TriggerFakeWriteForCallback(pref_store.get(), true);
Francois Doray405dd2d2017-06-09 15:23:331087 scoped_task_environment_.RunUntilIdle();
probergefc46ac12016-09-21 18:03:001088 EXPECT_TRUE(successful_write_reply_observer_.GetAndResetObservationState());
1089 EXPECT_EQ(CALLED_WITH_SUCCESS,
probergec503d692016-09-28 19:51:051090 write_callback_observer_.GetAndResetPostWriteObservationState());
probergefc46ac12016-09-21 18:03:001091
1092 // Confirm that the observation states were reset.
1093 EXPECT_FALSE(successful_write_reply_observer_.GetAndResetObservationState());
probergec503d692016-09-28 19:51:051094 EXPECT_EQ(NOT_CALLED,
1095 write_callback_observer_.GetAndResetPostWriteObservationState());
probergefc46ac12016-09-21 18:03:001096
1097 // Confirm that re-installing the observers works for another write.
1098 successful_write_reply_observer_.ObserveNextWriteCallback(pref_store.get());
1099 TriggerFakeWriteForCallback(pref_store.get(), true);
Francois Doray405dd2d2017-06-09 15:23:331100 scoped_task_environment_.RunUntilIdle();
probergefc46ac12016-09-21 18:03:001101 EXPECT_TRUE(successful_write_reply_observer_.GetAndResetObservationState());
1102 EXPECT_EQ(CALLED_WITH_SUCCESS,
probergec503d692016-09-28 19:51:051103 write_callback_observer_.GetAndResetPostWriteObservationState());
probergefc46ac12016-09-21 18:03:001104
1105 // Confirm that the successful observer is not invoked by an unsuccessful
1106 // write, and that the synchronous observer is invoked.
1107 successful_write_reply_observer_.ObserveNextWriteCallback(pref_store.get());
1108 TriggerFakeWriteForCallback(pref_store.get(), false);
Francois Doray405dd2d2017-06-09 15:23:331109 scoped_task_environment_.RunUntilIdle();
probergefc46ac12016-09-21 18:03:001110 EXPECT_FALSE(successful_write_reply_observer_.GetAndResetObservationState());
1111 EXPECT_EQ(CALLED_WITH_ERROR,
probergec503d692016-09-28 19:51:051112 write_callback_observer_.GetAndResetPostWriteObservationState());
probergefc46ac12016-09-21 18:03:001113
1114 // Do a real write, and confirm that the successful observer was invoked after
1115 // being set by |PostWriteCallback| by the last TriggerFakeWriteCallback.
1116 ImportantFileWriter* file_writer = GetImportantFileWriter(pref_store.get());
Jinho Bang84b58bd2018-01-01 21:44:481117 file_writer->WriteNow(std::make_unique<std::string>("foo"));
Francois Doray405dd2d2017-06-09 15:23:331118 scoped_task_environment_.RunUntilIdle();
probergefc46ac12016-09-21 18:03:001119 EXPECT_TRUE(successful_write_reply_observer_.GetAndResetObservationState());
probergec503d692016-09-28 19:51:051120 EXPECT_EQ(NOT_CALLED,
1121 write_callback_observer_.GetAndResetPostWriteObservationState());
probergefc46ac12016-09-21 18:03:001122}
1123
probergec503d692016-09-28 19:51:051124TEST_F(JsonPrefStoreCallbackTest, TestPostWriteCallbacksDuringProfileDeath) {
probergefc46ac12016-09-21 18:03:001125 // Create a JsonPrefStore and attach observers to it, then delete it by making
1126 // it go out of scope to simulate profile switch or Chrome shutdown.
1127 {
1128 scoped_refptr<JsonPrefStore> soon_out_of_scope_pref_store =
1129 CreatePrefStore();
1130 ImportantFileWriter* file_writer =
1131 GetImportantFileWriter(soon_out_of_scope_pref_store.get());
1132 successful_write_reply_observer_.ObserveNextWriteCallback(
1133 soon_out_of_scope_pref_store.get());
1134 write_callback_observer_.ObserveNextWriteCallback(
1135 soon_out_of_scope_pref_store.get());
Jinho Bang84b58bd2018-01-01 21:44:481136 file_writer->WriteNow(std::make_unique<std::string>("foo"));
probergefc46ac12016-09-21 18:03:001137 }
Francois Doray405dd2d2017-06-09 15:23:331138 scoped_task_environment_.RunUntilIdle();
probergefc46ac12016-09-21 18:03:001139 EXPECT_FALSE(successful_write_reply_observer_.GetAndResetObservationState());
probergec503d692016-09-28 19:51:051140 EXPECT_TRUE(write_callback_observer_.GetAndResetPreWriteObservationState());
probergefc46ac12016-09-21 18:03:001141 EXPECT_EQ(CALLED_WITH_SUCCESS,
probergec503d692016-09-28 19:51:051142 write_callback_observer_.GetAndResetPostWriteObservationState());
probergefc46ac12016-09-21 18:03:001143}
1144
vabr5d919d62016-09-30 08:55:361145} // namespace base