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

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

Issue 90563003: Fix a race condition in preference metric reporting. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Also filter 'empty loads' as in new run or corrupted pref file scenarios. Created 7 years 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/pref_filter.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/file_util.h" 7 #include "base/file_util.h"
8 #include "base/files/scoped_temp_dir.h" 8 #include "base/files/scoped_temp_dir.h"
9 #include "base/memory/ref_counted.h" 9 #include "base/memory/ref_counted.h"
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
11 #include "base/path_service.h" 11 #include "base/path_service.h"
12 #include "base/prefs/pref_filter.h"
12 #include "base/run_loop.h" 13 #include "base/run_loop.h"
13 #include "base/strings/string_number_conversions.h" 14 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/string_util.h" 15 #include "base/strings/string_util.h"
15 #include "base/strings/utf_string_conversions.h" 16 #include "base/strings/utf_string_conversions.h"
16 #include "base/threading/sequenced_worker_pool.h" 17 #include "base/threading/sequenced_worker_pool.h"
17 #include "base/threading/thread.h" 18 #include "base/threading/thread.h"
18 #include "base/values.h" 19 #include "base/values.h"
19 #include "testing/gmock/include/gmock/gmock.h" 20 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h" 21 #include "testing/gtest/include/gtest/gtest.h"
21 22
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 base::FilePath data_dir_; 54 base::FilePath data_dir_;
54 // A message loop that we can use as the file thread message loop. 55 // A message loop that we can use as the file thread message loop.
55 MessageLoop message_loop_; 56 MessageLoop message_loop_;
56 }; 57 };
57 58
58 // Test fallback behavior for a nonexistent file. 59 // Test fallback behavior for a nonexistent file.
59 TEST_F(JsonPrefStoreTest, NonExistentFile) { 60 TEST_F(JsonPrefStoreTest, NonExistentFile) {
60 base::FilePath bogus_input_file = data_dir_.AppendASCII("read.txt"); 61 base::FilePath bogus_input_file = data_dir_.AppendASCII("read.txt");
61 ASSERT_FALSE(PathExists(bogus_input_file)); 62 ASSERT_FALSE(PathExists(bogus_input_file));
62 scoped_refptr<JsonPrefStore> pref_store = new JsonPrefStore( 63 scoped_refptr<JsonPrefStore> pref_store = new JsonPrefStore(
63 bogus_input_file, message_loop_.message_loop_proxy().get()); 64 bogus_input_file,
65 message_loop_.message_loop_proxy().get(),
66 scoped_ptr<PrefFilter>());
64 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE, 67 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_NO_FILE,
65 pref_store->ReadPrefs()); 68 pref_store->ReadPrefs());
66 EXPECT_FALSE(pref_store->ReadOnly()); 69 EXPECT_FALSE(pref_store->ReadOnly());
67 } 70 }
68 71
69 // Test fallback behavior for an invalid file. 72 // Test fallback behavior for an invalid file.
70 TEST_F(JsonPrefStoreTest, InvalidFile) { 73 TEST_F(JsonPrefStoreTest, InvalidFile) {
71 base::FilePath invalid_file_original = data_dir_.AppendASCII("invalid.json"); 74 base::FilePath invalid_file_original = data_dir_.AppendASCII("invalid.json");
72 base::FilePath invalid_file = temp_dir_.path().AppendASCII("invalid.json"); 75 base::FilePath invalid_file = temp_dir_.path().AppendASCII("invalid.json");
73 ASSERT_TRUE(base::CopyFile(invalid_file_original, invalid_file)); 76 ASSERT_TRUE(base::CopyFile(invalid_file_original, invalid_file));
74 scoped_refptr<JsonPrefStore> pref_store = 77 scoped_refptr<JsonPrefStore> pref_store =
75 new JsonPrefStore(invalid_file, message_loop_.message_loop_proxy().get()); 78 new JsonPrefStore(invalid_file,
79 message_loop_.message_loop_proxy().get(),
80 scoped_ptr<PrefFilter>());
76 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_JSON_PARSE, 81 EXPECT_EQ(PersistentPrefStore::PREF_READ_ERROR_JSON_PARSE,
77 pref_store->ReadPrefs()); 82 pref_store->ReadPrefs());
78 EXPECT_FALSE(pref_store->ReadOnly()); 83 EXPECT_FALSE(pref_store->ReadOnly());
79 84
80 // The file should have been moved aside. 85 // The file should have been moved aside.
81 EXPECT_FALSE(PathExists(invalid_file)); 86 EXPECT_FALSE(PathExists(invalid_file));
82 base::FilePath moved_aside = temp_dir_.path().AppendASCII("invalid.bad"); 87 base::FilePath moved_aside = temp_dir_.path().AppendASCII("invalid.bad");
83 EXPECT_TRUE(PathExists(moved_aside)); 88 EXPECT_TRUE(PathExists(moved_aside));
84 EXPECT_TRUE(TextContentsEqual(invalid_file_original, moved_aside)); 89 EXPECT_TRUE(TextContentsEqual(invalid_file_original, moved_aside));
85 } 90 }
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 ASSERT_TRUE(base::DeleteFile(output_file, false)); 155 ASSERT_TRUE(base::DeleteFile(output_file, false));
151 } 156 }
152 157
153 TEST_F(JsonPrefStoreTest, Basic) { 158 TEST_F(JsonPrefStoreTest, Basic) {
154 ASSERT_TRUE(base::CopyFile(data_dir_.AppendASCII("read.json"), 159 ASSERT_TRUE(base::CopyFile(data_dir_.AppendASCII("read.json"),
155 temp_dir_.path().AppendASCII("write.json"))); 160 temp_dir_.path().AppendASCII("write.json")));
156 161
157 // Test that the persistent value can be loaded. 162 // Test that the persistent value can be loaded.
158 base::FilePath input_file = temp_dir_.path().AppendASCII("write.json"); 163 base::FilePath input_file = temp_dir_.path().AppendASCII("write.json");
159 ASSERT_TRUE(PathExists(input_file)); 164 ASSERT_TRUE(PathExists(input_file));
160 scoped_refptr<JsonPrefStore> pref_store = 165 scoped_refptr<JsonPrefStore> pref_store = new JsonPrefStore(
161 new JsonPrefStore(input_file, message_loop_.message_loop_proxy().get()); 166 input_file,
167 message_loop_.message_loop_proxy().get(),
168 scoped_ptr<PrefFilter>());
162 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, pref_store->ReadPrefs()); 169 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, pref_store->ReadPrefs());
163 ASSERT_FALSE(pref_store->ReadOnly()); 170 ASSERT_FALSE(pref_store->ReadOnly());
164 171
165 // The JSON file looks like this: 172 // The JSON file looks like this:
166 // { 173 // {
167 // "homepage": "http://www.cnn.com", 174 // "homepage": "http://www.cnn.com",
168 // "some_directory": "/usr/local/", 175 // "some_directory": "/usr/local/",
169 // "tabs": { 176 // "tabs": {
170 // "new_windows_in_tabs": true, 177 // "new_windows_in_tabs": true,
171 // "max_tabs": 20 178 // "max_tabs": 20
172 // } 179 // }
173 // } 180 // }
174 181
175 RunBasicJsonPrefStoreTest( 182 RunBasicJsonPrefStoreTest(
176 pref_store.get(), input_file, data_dir_.AppendASCII("write.golden.json")); 183 pref_store.get(), input_file, data_dir_.AppendASCII("write.golden.json"));
177 } 184 }
178 185
179 TEST_F(JsonPrefStoreTest, BasicAsync) { 186 TEST_F(JsonPrefStoreTest, BasicAsync) {
180 ASSERT_TRUE(base::CopyFile(data_dir_.AppendASCII("read.json"), 187 ASSERT_TRUE(base::CopyFile(data_dir_.AppendASCII("read.json"),
181 temp_dir_.path().AppendASCII("write.json"))); 188 temp_dir_.path().AppendASCII("write.json")));
182 189
183 // Test that the persistent value can be loaded. 190 // Test that the persistent value can be loaded.
184 base::FilePath input_file = temp_dir_.path().AppendASCII("write.json"); 191 base::FilePath input_file = temp_dir_.path().AppendASCII("write.json");
185 ASSERT_TRUE(PathExists(input_file)); 192 ASSERT_TRUE(PathExists(input_file));
186 scoped_refptr<JsonPrefStore> pref_store = 193 scoped_refptr<JsonPrefStore> pref_store = new JsonPrefStore(
187 new JsonPrefStore(input_file, message_loop_.message_loop_proxy().get()); 194 input_file,
195 message_loop_.message_loop_proxy().get(),
196 scoped_ptr<PrefFilter>());
188 197
189 { 198 {
190 MockPrefStoreObserver mock_observer; 199 MockPrefStoreObserver mock_observer;
191 pref_store->AddObserver(&mock_observer); 200 pref_store->AddObserver(&mock_observer);
192 201
193 MockReadErrorDelegate* mock_error_delegate = new MockReadErrorDelegate; 202 MockReadErrorDelegate* mock_error_delegate = new MockReadErrorDelegate;
194 pref_store->ReadPrefsAsync(mock_error_delegate); 203 pref_store->ReadPrefsAsync(mock_error_delegate);
195 204
196 EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(1); 205 EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(1);
197 EXPECT_CALL(*mock_error_delegate, 206 EXPECT_CALL(*mock_error_delegate,
(...skipping 14 matching lines...) Expand all
212 // } 221 // }
213 // } 222 // }
214 223
215 RunBasicJsonPrefStoreTest( 224 RunBasicJsonPrefStoreTest(
216 pref_store.get(), input_file, data_dir_.AppendASCII("write.golden.json")); 225 pref_store.get(), input_file, data_dir_.AppendASCII("write.golden.json"));
217 } 226 }
218 227
219 TEST_F(JsonPrefStoreTest, PreserveEmptyValues) { 228 TEST_F(JsonPrefStoreTest, PreserveEmptyValues) {
220 FilePath pref_file = temp_dir_.path().AppendASCII("empty_values.json"); 229 FilePath pref_file = temp_dir_.path().AppendASCII("empty_values.json");
221 230
222 scoped_refptr<JsonPrefStore> pref_store = 231 scoped_refptr<JsonPrefStore> pref_store = new JsonPrefStore(
223 new JsonPrefStore(pref_file, message_loop_.message_loop_proxy()); 232 pref_file,
233 message_loop_.message_loop_proxy(),
234 scoped_ptr<PrefFilter>());
224 235
225 // Set some keys with empty values. 236 // Set some keys with empty values.
226 pref_store->SetValue("list", new base::ListValue); 237 pref_store->SetValue("list", new base::ListValue);
227 pref_store->SetValue("dict", new base::DictionaryValue); 238 pref_store->SetValue("dict", new base::DictionaryValue);
228 239
229 // Write to file. 240 // Write to file.
230 pref_store->CommitPendingWrite(); 241 pref_store->CommitPendingWrite();
231 MessageLoop::current()->RunUntilIdle(); 242 MessageLoop::current()->RunUntilIdle();
232 243
233 // Reload. 244 // Reload.
234 pref_store = new JsonPrefStore(pref_file, message_loop_.message_loop_proxy()); 245 pref_store = new JsonPrefStore(
246 pref_file,
247 message_loop_.message_loop_proxy(),
248 scoped_ptr<PrefFilter>());
235 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, pref_store->ReadPrefs()); 249 ASSERT_EQ(PersistentPrefStore::PREF_READ_ERROR_NONE, pref_store->ReadPrefs());
236 ASSERT_FALSE(pref_store->ReadOnly()); 250 ASSERT_FALSE(pref_store->ReadOnly());
237 251
238 // Check values. 252 // Check values.
239 const Value* result = NULL; 253 const Value* result = NULL;
240 EXPECT_TRUE(pref_store->GetValue("list", &result)); 254 EXPECT_TRUE(pref_store->GetValue("list", &result));
241 EXPECT_TRUE(ListValue().Equals(result)); 255 EXPECT_TRUE(ListValue().Equals(result));
242 EXPECT_TRUE(pref_store->GetValue("dict", &result)); 256 EXPECT_TRUE(pref_store->GetValue("dict", &result));
243 EXPECT_TRUE(DictionaryValue().Equals(result)); 257 EXPECT_TRUE(DictionaryValue().Equals(result));
244 } 258 }
245 259
246 // Tests asynchronous reading of the file when there is no file. 260 // Tests asynchronous reading of the file when there is no file.
247 TEST_F(JsonPrefStoreTest, AsyncNonExistingFile) { 261 TEST_F(JsonPrefStoreTest, AsyncNonExistingFile) {
248 base::FilePath bogus_input_file = data_dir_.AppendASCII("read.txt"); 262 base::FilePath bogus_input_file = data_dir_.AppendASCII("read.txt");
249 ASSERT_FALSE(PathExists(bogus_input_file)); 263 ASSERT_FALSE(PathExists(bogus_input_file));
250 scoped_refptr<JsonPrefStore> pref_store = new JsonPrefStore( 264 scoped_refptr<JsonPrefStore> pref_store = new JsonPrefStore(
251 bogus_input_file, message_loop_.message_loop_proxy().get()); 265 bogus_input_file,
266 message_loop_.message_loop_proxy().get(),
267 scoped_ptr<PrefFilter>());
252 MockPrefStoreObserver mock_observer; 268 MockPrefStoreObserver mock_observer;
253 pref_store->AddObserver(&mock_observer); 269 pref_store->AddObserver(&mock_observer);
254 270
255 MockReadErrorDelegate *mock_error_delegate = new MockReadErrorDelegate; 271 MockReadErrorDelegate *mock_error_delegate = new MockReadErrorDelegate;
256 pref_store->ReadPrefsAsync(mock_error_delegate); 272 pref_store->ReadPrefsAsync(mock_error_delegate);
257 273
258 EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(1); 274 EXPECT_CALL(mock_observer, OnInitializationCompleted(true)).Times(1);
259 EXPECT_CALL(*mock_error_delegate, 275 EXPECT_CALL(*mock_error_delegate,
260 OnError(PersistentPrefStore::PREF_READ_ERROR_NO_FILE)).Times(1); 276 OnError(PersistentPrefStore::PREF_READ_ERROR_NO_FILE)).Times(1);
261 RunLoop().RunUntilIdle(); 277 RunLoop().RunUntilIdle();
262 pref_store->RemoveObserver(&mock_observer); 278 pref_store->RemoveObserver(&mock_observer);
263 279
264 EXPECT_FALSE(pref_store->ReadOnly()); 280 EXPECT_FALSE(pref_store->ReadOnly());
265 } 281 }
266 282
267 } // namespace base 283 } // namespace base
OLDNEW
« no previous file with comments | « base/prefs/json_pref_store.cc ('k') | base/prefs/pref_filter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698