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

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

Issue 257003007: Introduce a new framework for back-and-forth tracked/protected preferences migration. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: comment nit Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/prefs/json_pref_store.cc ('k') | base/prefs/persistent_pref_store.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/prefs/json_pref_store.h" 5 #include "base/prefs/json_pref_store.h"
6 6
7 #include "base/bind.h"
7 #include "base/file_util.h" 8 #include "base/file_util.h"
8 #include "base/files/scoped_temp_dir.h" 9 #include "base/files/scoped_temp_dir.h"
9 #include "base/memory/ref_counted.h" 10 #include "base/memory/ref_counted.h"
10 #include "base/memory/scoped_ptr.h" 11 #include "base/memory/scoped_ptr.h"
12 #include "base/message_loop/message_loop.h"
11 #include "base/path_service.h" 13 #include "base/path_service.h"
12 #include "base/prefs/pref_filter.h" 14 #include "base/prefs/pref_filter.h"
13 #include "base/run_loop.h" 15 #include "base/run_loop.h"
14 #include "base/strings/string_number_conversions.h" 16 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/string_util.h" 17 #include "base/strings/string_util.h"
16 #include "base/strings/utf_string_conversions.h" 18 #include "base/strings/utf_string_conversions.h"
17 #include "base/threading/sequenced_worker_pool.h" 19 #include "base/threading/sequenced_worker_pool.h"
18 #include "base/threading/thread.h" 20 #include "base/threading/thread.h"
19 #include "base/values.h" 21 #include "base/values.h"
20 #include "testing/gmock/include/gmock/gmock.h" 22 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gtest/include/gtest/gtest.h" 23 #include "testing/gtest/include/gtest/gtest.h"
22 24
23 namespace base { 25 namespace base {
24 namespace { 26 namespace {
25 27
26 const char kHomePage[] = "homepage"; 28 const char kHomePage[] = "homepage";
27 29
30 // A PrefFilter that will intercept all calls to FilterOnLoad() and hold on
31 // to the |prefs| until explicitly asked to release them.
32 class InterceptingPrefFilter : public PrefFilter {
33 public:
34 InterceptingPrefFilter();
35 virtual ~InterceptingPrefFilter();
36
37 // PrefFilter implementation:
38 virtual void FilterOnLoad(
39 const PostFilterOnLoadCallback& post_filter_on_load_callback,
40 scoped_ptr<base::DictionaryValue> pref_store_contents) OVERRIDE;
41 virtual void FilterUpdate(const std::string& path) OVERRIDE {}
42 virtual void FilterSerializeData(
43 const base::DictionaryValue* pref_store_contents) OVERRIDE {}
44
45 bool has_intercepted_prefs() const { return intercepted_prefs_ != NULL; }
46
47 // Finalize an intercepted read, handing |intercept_prefs_| back to its
48 // JsonPrefStore.
49 void ReleasePrefs();
50
51 private:
52 PostFilterOnLoadCallback post_filter_on_load_callback_;
53 scoped_ptr<base::DictionaryValue> intercepted_prefs_;
54
55 DISALLOW_COPY_AND_ASSIGN(InterceptingPrefFilter);
56 };
57
58 InterceptingPrefFilter::InterceptingPrefFilter() {}
59 InterceptingPrefFilter::~InterceptingPrefFilter() {}
60
61 void InterceptingPrefFilter::FilterOnLoad(
62 const PostFilterOnLoadCallback& post_filter_on_load_callback,
63 scoped_ptr<base::DictionaryValue> pref_store_contents) {
64 post_filter_on_load_callback_ = post_filter_on_load_callback;
65 intercepted_prefs_ = pref_store_contents.Pass();
66 }
67
68 void InterceptingPrefFilter::ReleasePrefs() {
69 EXPECT_FALSE(post_filter_on_load_callback_.is_null());
70 post_filter_on_load_callback_.Run(intercepted_prefs_.Pass(), false);
71 post_filter_on_load_callback_.Reset();
72 }
73
28 class MockPrefStoreObserver : public PrefStore::Observer { 74 class MockPrefStoreObserver : public PrefStore::Observer {
29 public: 75 public:
30 MOCK_METHOD1(OnPrefValueChanged, void (const std::string&)); 76 MOCK_METHOD1(OnPrefValueChanged, void (const std::string&));
31 MOCK_METHOD1(OnInitializationCompleted, void (bool)); 77 MOCK_METHOD1(OnInitializationCompleted, void (bool));
32 }; 78 };
33 79
34 class MockReadErrorDelegate : public PersistentPrefStore::ReadErrorDelegate { 80 class MockReadErrorDelegate : public PersistentPrefStore::ReadErrorDelegate {
35 public: 81 public:
36 MOCK_METHOD1(OnError, void(PersistentPrefStore::PrefReadError)); 82 MOCK_METHOD1(OnError, void(PersistentPrefStore::PrefReadError));
37 }; 83 };
38 84
39 } // namespace 85 } // namespace
40 86
41 class JsonPrefStoreTest : public testing::Test { 87 class JsonPrefStoreTest : public testing::Test {
42 protected: 88 protected:
43 virtual void SetUp() OVERRIDE { 89 virtual void SetUp() OVERRIDE {
44 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 90 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
45 91
46 ASSERT_TRUE(PathService::Get(base::DIR_TEST_DATA, &data_dir_)); 92 ASSERT_TRUE(PathService::Get(base::DIR_TEST_DATA, &data_dir_));
47 data_dir_ = data_dir_.AppendASCII("prefs"); 93 data_dir_ = data_dir_.AppendASCII("prefs");
48 ASSERT_TRUE(PathExists(data_dir_)); 94 ASSERT_TRUE(PathExists(data_dir_));
49 } 95 }
50 96
97 virtual void TearDown() OVERRIDE {
98 // Make sure all pending tasks have been processed (e.g., deleting the
99 // JsonPrefStore may post write tasks).
100 message_loop_.PostTask(FROM_HERE, MessageLoop::QuitWhenIdleClosure());
101 message_loop_.Run();
102 }
103
51 // The path to temporary directory used to contain the test operations. 104 // The path to temporary directory used to contain the test operations.
52 base::ScopedTempDir temp_dir_; 105 base::ScopedTempDir temp_dir_;
53 // The path to the directory where the test data is stored. 106 // The path to the directory where the test data is stored.
54 base::FilePath data_dir_; 107 base::FilePath data_dir_;
55 // A message loop that we can use as the file thread message loop. 108 // A message loop that we can use as the file thread message loop.
56 MessageLoop message_loop_; 109 MessageLoop message_loop_;
57 }; 110 };
58 111
59 // Test fallback behavior for a nonexistent file. 112 // Test fallback behavior for a nonexistent file.
60 TEST_F(JsonPrefStoreTest, NonExistentFile) { 113 TEST_F(JsonPrefStoreTest, NonExistentFile) {
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 // Serialize and compare to expected output. 203 // Serialize and compare to expected output.
151 ASSERT_TRUE(PathExists(golden_output_file)); 204 ASSERT_TRUE(PathExists(golden_output_file));
152 pref_store->CommitPendingWrite(); 205 pref_store->CommitPendingWrite();
153 RunLoop().RunUntilIdle(); 206 RunLoop().RunUntilIdle();
154 EXPECT_TRUE(TextContentsEqual(golden_output_file, output_file)); 207 EXPECT_TRUE(TextContentsEqual(golden_output_file, output_file));
155 ASSERT_TRUE(base::DeleteFile(output_file, false)); 208 ASSERT_TRUE(base::DeleteFile(output_file, false));
156 } 209 }
157 210
158 TEST_F(JsonPrefStoreTest, Basic) { 211 TEST_F(JsonPrefStoreTest, Basic) {
159 ASSERT_TRUE(base::CopyFile(data_dir_.AppendASCII("read.json"), 212 ASSERT_TRUE(base::CopyFile(data_dir_.AppendASCII("read.json"),
160 temp_dir_.path().AppendASCII("write.json"))); 213 temp_dir_.path().AppendASCII("write.json")));
161 214
162 // Test that the persistent value can be loaded. 215 // Test that the persistent value can be loaded.
163 base::FilePath input_file = temp_dir_.path().AppendASCII("write.json"); 216 base::FilePath input_file = temp_dir_.path().AppendASCII("write.json");
164 ASSERT_TRUE(PathExists(input_file)); 217 ASSERT_TRUE(PathExists(input_file));
165 scoped_refptr<JsonPrefStore> pref_store = new JsonPrefStore( 218 scoped_refptr<JsonPrefStore> pref_store = new JsonPrefStore(
166 input_file, 219 input_file,
167 message_loop_.message_loop_proxy().get(), 220 message_loop_.message_loop_proxy().get(),
168 scoped_ptr<PrefFilter>()); 221 scoped_ptr<PrefFilter>());
169 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, pref_store->ReadPrefs()); 222 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, pref_store->ReadPrefs());
170 ASSERT_FALSE(pref_store->ReadOnly()); 223 EXPECT_FALSE(pref_store->ReadOnly());
224 EXPECT_TRUE(pref_store->IsInitializationComplete());
171 225
172 // The JSON file looks like this: 226 // The JSON file looks like this:
173 // { 227 // {
174 // "homepage": "http://www.cnn.com", 228 // "homepage": "http://www.cnn.com",
175 // "some_directory": "/usr/local/", 229 // "some_directory": "/usr/local/",
176 // "tabs": { 230 // "tabs": {
177 // "new_windows_in_tabs": true, 231 // "new_windows_in_tabs": true,
178 // "max_tabs": 20 232 // "max_tabs": 20
179 // } 233 // }
180 // } 234 // }
181 235
182 RunBasicJsonPrefStoreTest( 236 RunBasicJsonPrefStoreTest(
183 pref_store.get(), input_file, data_dir_.AppendASCII("write.golden.json")); 237 pref_store.get(), input_file, data_dir_.AppendASCII("write.golden.json"));
184 } 238 }
185 239
186 TEST_F(JsonPrefStoreTest, BasicAsync) { 240 TEST_F(JsonPrefStoreTest, BasicAsync) {
187 ASSERT_TRUE(base::CopyFile(data_dir_.AppendASCII("read.json"), 241 ASSERT_TRUE(base::CopyFile(data_dir_.AppendASCII("read.json"),
188 temp_dir_.path().AppendASCII("write.json"))); 242 temp_dir_.path().AppendASCII("write.json")));
189 243
190 // Test that the persistent value can be loaded. 244 // Test that the persistent value can be loaded.
191 base::FilePath input_file = temp_dir_.path().AppendASCII("write.json"); 245 base::FilePath input_file = temp_dir_.path().AppendASCII("write.json");
192 ASSERT_TRUE(PathExists(input_file)); 246 ASSERT_TRUE(PathExists(input_file));
193 scoped_refptr<JsonPrefStore> pref_store = new JsonPrefStore( 247 scoped_refptr<JsonPrefStore> pref_store = new JsonPrefStore(
194 input_file, 248 input_file,
195 message_loop_.message_loop_proxy().get(), 249 message_loop_.message_loop_proxy().get(),
196 scoped_ptr<PrefFilter>()); 250 scoped_ptr<PrefFilter>());
197 251
198 { 252 {
199 MockPrefStoreObserver mock_observer; 253 MockPrefStoreObserver mock_observer;
200 pref_store->AddObserver(&mock_observer); 254 pref_store->AddObserver(&mock_observer);
201 255
202 MockReadErrorDelegate* mock_error_delegate = new MockReadErrorDelegate; 256 MockReadErrorDelegate* mock_error_delegate = new MockReadErrorDelegate;
203 pref_store->ReadPrefsAsync(mock_error_delegate); 257 pref_store->ReadPrefsAsync(mock_error_delegate);
204 258
205 EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(1); 259 EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(1);
206 EXPECT_CALL(*mock_error_delegate, 260 EXPECT_CALL(*mock_error_delegate,
207 OnError(PersistentPrefStore::PREF_READ_ERROR_NONE)).Times(0); 261 OnError(PersistentPrefStore::PREF_READ_ERROR_NONE)).Times(0);
208 RunLoop().RunUntilIdle(); 262 RunLoop().RunUntilIdle();
209 pref_store->RemoveObserver(&mock_observer); 263 pref_store->RemoveObserver(&mock_observer);
210 264
211 ASSERT_FALSE(pref_store->ReadOnly()); 265 EXPECT_FALSE(pref_store->ReadOnly());
266 EXPECT_TRUE(pref_store->IsInitializationComplete());
212 } 267 }
213 268
214 // The JSON file looks like this: 269 // The JSON file looks like this:
215 // { 270 // {
216 // "homepage": "http://www.cnn.com", 271 // "homepage": "http://www.cnn.com",
217 // "some_directory": "/usr/local/", 272 // "some_directory": "/usr/local/",
218 // "tabs": { 273 // "tabs": {
219 // "new_windows_in_tabs": true, 274 // "new_windows_in_tabs": true,
220 // "max_tabs": 20 275 // "max_tabs": 20
221 // } 276 // }
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 349
295 EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(1); 350 EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(1);
296 EXPECT_CALL(*mock_error_delegate, 351 EXPECT_CALL(*mock_error_delegate,
297 OnError(PersistentPrefStore::PREF_READ_ERROR_NO_FILE)).Times(1); 352 OnError(PersistentPrefStore::PREF_READ_ERROR_NO_FILE)).Times(1);
298 RunLoop().RunUntilIdle(); 353 RunLoop().RunUntilIdle();
299 pref_store->RemoveObserver(&mock_observer); 354 pref_store->RemoveObserver(&mock_observer);
300 355
301 EXPECT_FALSE(pref_store->ReadOnly()); 356 EXPECT_FALSE(pref_store->ReadOnly());
302 } 357 }
303 358
359 TEST_F(JsonPrefStoreTest, ReadWithInterceptor) {
360 ASSERT_TRUE(base::CopyFile(data_dir_.AppendASCII("read.json"),
361 temp_dir_.path().AppendASCII("write.json")));
362
363 // Test that the persistent value can be loaded.
364 base::FilePath input_file = temp_dir_.path().AppendASCII("write.json");
365 ASSERT_TRUE(PathExists(input_file));
366
367 scoped_ptr<InterceptingPrefFilter> intercepting_pref_filter(
368 new InterceptingPrefFilter());
369 InterceptingPrefFilter* raw_intercepting_pref_filter_ =
370 intercepting_pref_filter.get();
371 scoped_refptr<JsonPrefStore> pref_store =
372 new JsonPrefStore(input_file,
373 message_loop_.message_loop_proxy().get(),
374 intercepting_pref_filter.PassAs<PrefFilter>());
375
376 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_ASYNCHRONOUS_TASK_INCOMPLETE,
377 pref_store->ReadPrefs());
378 EXPECT_FALSE(pref_store->ReadOnly());
379
380 // The store shouldn't be considered initialized until the interceptor
381 // returns.
382 EXPECT_TRUE(raw_intercepting_pref_filter_->has_intercepted_prefs());
383 EXPECT_FALSE(pref_store->IsInitializationComplete());
384 EXPECT_FALSE(pref_store->GetValue(kHomePage, NULL));
385
386 raw_intercepting_pref_filter_->ReleasePrefs();
387
388 EXPECT_FALSE(raw_intercepting_pref_filter_->has_intercepted_prefs());
389 EXPECT_TRUE(pref_store->IsInitializationComplete());
390 EXPECT_TRUE(pref_store->GetValue(kHomePage, NULL));
391
392 // The JSON file looks like this:
393 // {
394 // "homepage": "http://www.cnn.com",
395 // "some_directory": "/usr/local/",
396 // "tabs": {
397 // "new_windows_in_tabs": true,
398 // "max_tabs": 20
399 // }
400 // }
401
402 RunBasicJsonPrefStoreTest(
403 pref_store.get(), input_file, data_dir_.AppendASCII("write.golden.json"));
404 }
405
406 TEST_F(JsonPrefStoreTest, ReadAsyncWithInterceptor) {
407 ASSERT_TRUE(base::CopyFile(data_dir_.AppendASCII("read.json"),
408 temp_dir_.path().AppendASCII("write.json")));
409
410 // Test that the persistent value can be loaded.
411 base::FilePath input_file = temp_dir_.path().AppendASCII("write.json");
412 ASSERT_TRUE(PathExists(input_file));
413
414 scoped_ptr<InterceptingPrefFilter> intercepting_pref_filter(
415 new InterceptingPrefFilter());
416 InterceptingPrefFilter* raw_intercepting_pref_filter_ =
417 intercepting_pref_filter.get();
418 scoped_refptr<JsonPrefStore> pref_store =
419 new JsonPrefStore(input_file,
420 message_loop_.message_loop_proxy().get(),
421 intercepting_pref_filter.PassAs<PrefFilter>());
422
423 MockPrefStoreObserver mock_observer;
424 pref_store->AddObserver(&mock_observer);
425
426 // Ownership of the |mock_error_delegate| is handed to the |pref_store| below.
427 MockReadErrorDelegate* mock_error_delegate = new MockReadErrorDelegate;
428
429 {
430 pref_store->ReadPrefsAsync(mock_error_delegate);
431
432 EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(0);
433 // EXPECT_CALL(*mock_error_delegate,
434 // OnError(PersistentPrefStore::PREF_READ_ERROR_NONE)).Times(0);
435 RunLoop().RunUntilIdle();
436
437 EXPECT_FALSE(pref_store->ReadOnly());
438 EXPECT_TRUE(raw_intercepting_pref_filter_->has_intercepted_prefs());
439 EXPECT_FALSE(pref_store->IsInitializationComplete());
440 EXPECT_FALSE(pref_store->GetValue(kHomePage, NULL));
441 }
442
443 {
444 EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(1);
445 // EXPECT_CALL(*mock_error_delegate,
446 // OnError(PersistentPrefStore::PREF_READ_ERROR_NONE)).Times(0);
447
448 raw_intercepting_pref_filter_->ReleasePrefs();
449
450 EXPECT_FALSE(pref_store->ReadOnly());
451 EXPECT_FALSE(raw_intercepting_pref_filter_->has_intercepted_prefs());
452 EXPECT_TRUE(pref_store->IsInitializationComplete());
453 EXPECT_TRUE(pref_store->GetValue(kHomePage, NULL));
454 }
455
456 pref_store->RemoveObserver(&mock_observer);
457
458 // The JSON file looks like this:
459 // {
460 // "homepage": "http://www.cnn.com",
461 // "some_directory": "/usr/local/",
462 // "tabs": {
463 // "new_windows_in_tabs": true,
464 // "max_tabs": 20
465 // }
466 // }
467
468 RunBasicJsonPrefStoreTest(
469 pref_store.get(), input_file, data_dir_.AppendASCII("write.golden.json"));
470 }
471
304 } // namespace base 472 } // namespace base
OLDNEW
« no previous file with comments | « base/prefs/json_pref_store.cc ('k') | base/prefs/persistent_pref_store.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698