OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/bind.h" | 5 #include "base/bind.h" |
6 #include "base/file_util.h" | 6 #include "base/file_util.h" |
7 #include "base/memory/ref_counted.h" | 7 #include "base/memory/ref_counted.h" |
8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
9 #include "base/scoped_temp_dir.h" | 9 #include "base/scoped_temp_dir.h" |
10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
11 #include "base/test/thread_test_helper.h" | 11 #include "base/test/thread_test_helper.h" |
12 #include "chrome/browser/net/sqlite_origin_bound_cert_store.h" | 12 #include "chrome/browser/net/sqlite_origin_bound_cert_store.h" |
13 #include "chrome/common/chrome_constants.h" | 13 #include "chrome/common/chrome_constants.h" |
14 #include "content/test/test_browser_thread.h" | 14 #include "content/test/test_browser_thread.h" |
15 #include "net/base/cert_test_util.h" | |
15 #include "sql/statement.h" | 16 #include "sql/statement.h" |
16 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
17 | 18 |
18 using content::BrowserThread; | 19 using content::BrowserThread; |
19 | 20 |
20 class SQLiteOriginBoundCertStoreTest : public testing::Test { | 21 class SQLiteOriginBoundCertStoreTest : public testing::Test { |
21 public: | 22 public: |
22 SQLiteOriginBoundCertStoreTest() | 23 SQLiteOriginBoundCertStoreTest() |
23 : db_thread_(BrowserThread::DB) { | 24 : db_thread_(BrowserThread::DB) { |
24 } | 25 } |
25 | 26 |
26 protected: | 27 protected: |
28 static void ReadTestKeyAndCert(std::string* key, std::string* cert) { | |
29 FilePath key_path = net::GetTestCertsDirectory().AppendASCII( | |
30 "unittest.originbound.key.der"); | |
31 FilePath cert_path = net::GetTestCertsDirectory().AppendASCII( | |
32 "unittest.originbound.der"); | |
33 ASSERT_TRUE(file_util::ReadFileToString(key_path, key)); | |
34 ASSERT_TRUE(file_util::ReadFileToString(cert_path, cert)); | |
35 } | |
36 | |
37 static base::Time GetTestCertExpirationTime() { | |
38 // Cert expiration time from 'dumpasn1 unittest.originbound.der': | |
39 // GeneralizedTime 19/11/2111 02:23:45 GMT | |
40 base::Time::Exploded exploded_time; | |
41 exploded_time.year = 2111; | |
42 exploded_time.month = 11; | |
43 exploded_time.day_of_week = 0; // Unused. | |
44 exploded_time.day_of_month = 19; | |
45 exploded_time.hour = 2; | |
46 exploded_time.minute = 23; | |
47 exploded_time.second = 45; | |
48 exploded_time.millisecond = 0; | |
49 return base::Time::FromUTCExploded(exploded_time); | |
50 } | |
51 | |
27 virtual void SetUp() { | 52 virtual void SetUp() { |
28 db_thread_.Start(); | 53 db_thread_.Start(); |
29 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); | 54 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
30 store_ = new SQLiteOriginBoundCertStore( | 55 store_ = new SQLiteOriginBoundCertStore( |
31 temp_dir_.path().Append(chrome::kOBCertFilename)); | 56 temp_dir_.path().Append(chrome::kOBCertFilename)); |
32 std::vector<net::DefaultOriginBoundCertStore::OriginBoundCert*> certs; | 57 std::vector<net::DefaultOriginBoundCertStore::OriginBoundCert*> certs; |
33 ASSERT_TRUE(store_->Load(&certs)); | 58 ASSERT_TRUE(store_->Load(&certs)); |
34 ASSERT_EQ(0u, certs.size()); | 59 ASSERT_EQ(0u, certs.size()); |
35 // Make sure the store gets written at least once. | 60 // Make sure the store gets written at least once. |
36 store_->AddOriginBoundCert( | 61 store_->AddOriginBoundCert( |
37 net::DefaultOriginBoundCertStore::OriginBoundCert( | 62 net::DefaultOriginBoundCertStore::OriginBoundCert( |
38 "https://encrypted.google.com:8443", | 63 "https://encrypted.google.com:8443", |
39 net::CLIENT_CERT_RSA_SIGN, "a", "b")); | 64 net::CLIENT_CERT_RSA_SIGN, |
65 base::Time(), | |
66 "a", "b")); | |
40 } | 67 } |
41 | 68 |
42 content::TestBrowserThread db_thread_; | 69 content::TestBrowserThread db_thread_; |
43 ScopedTempDir temp_dir_; | 70 ScopedTempDir temp_dir_; |
44 scoped_refptr<SQLiteOriginBoundCertStore> store_; | 71 scoped_refptr<SQLiteOriginBoundCertStore> store_; |
45 }; | 72 }; |
46 | 73 |
47 TEST_F(SQLiteOriginBoundCertStoreTest, KeepOnDestruction) { | 74 TEST_F(SQLiteOriginBoundCertStoreTest, KeepOnDestruction) { |
48 store_->SetClearLocalStateOnExit(false); | 75 store_->SetClearLocalStateOnExit(false); |
49 store_ = NULL; | 76 store_ = NULL; |
(...skipping 22 matching lines...) Expand all Loading... | |
72 ASSERT_TRUE(helper->Run()); | 99 ASSERT_TRUE(helper->Run()); |
73 | 100 |
74 ASSERT_FALSE(file_util::PathExists( | 101 ASSERT_FALSE(file_util::PathExists( |
75 temp_dir_.path().Append(chrome::kOBCertFilename))); | 102 temp_dir_.path().Append(chrome::kOBCertFilename))); |
76 } | 103 } |
77 | 104 |
78 // Test if data is stored as expected in the SQLite database. | 105 // Test if data is stored as expected in the SQLite database. |
79 TEST_F(SQLiteOriginBoundCertStoreTest, TestPersistence) { | 106 TEST_F(SQLiteOriginBoundCertStoreTest, TestPersistence) { |
80 store_->AddOriginBoundCert( | 107 store_->AddOriginBoundCert( |
81 net::DefaultOriginBoundCertStore::OriginBoundCert( | 108 net::DefaultOriginBoundCertStore::OriginBoundCert( |
82 "https://www.google.com/", net::CLIENT_CERT_ECDSA_SIGN, "c", "d")); | 109 "https://www.google.com/", |
110 net::CLIENT_CERT_ECDSA_SIGN, | |
111 base::Time(), | |
112 "c", "d")); | |
83 | 113 |
84 std::vector<net::DefaultOriginBoundCertStore::OriginBoundCert*> certs; | 114 std::vector<net::DefaultOriginBoundCertStore::OriginBoundCert*> certs; |
85 // Replace the store effectively destroying the current one and forcing it | 115 // Replace the store effectively destroying the current one and forcing it |
86 // to write it's data to disk. Then we can see if after loading it again it | 116 // to write it's data to disk. Then we can see if after loading it again it |
87 // is still there. | 117 // is still there. |
88 store_ = NULL; | 118 store_ = NULL; |
89 scoped_refptr<base::ThreadTestHelper> helper( | 119 scoped_refptr<base::ThreadTestHelper> helper( |
90 new base::ThreadTestHelper( | 120 new base::ThreadTestHelper( |
91 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB))); | 121 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB))); |
92 // Make sure we wait until the destructor has run. | 122 // Make sure we wait until the destructor has run. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
124 STLDeleteContainerPointers(certs.begin(), certs.end()); | 154 STLDeleteContainerPointers(certs.begin(), certs.end()); |
125 certs.clear(); | 155 certs.clear(); |
126 store_ = new SQLiteOriginBoundCertStore( | 156 store_ = new SQLiteOriginBoundCertStore( |
127 temp_dir_.path().Append(chrome::kOBCertFilename)); | 157 temp_dir_.path().Append(chrome::kOBCertFilename)); |
128 | 158 |
129 // Reload and check if the cert has been removed. | 159 // Reload and check if the cert has been removed. |
130 ASSERT_TRUE(store_->Load(&certs)); | 160 ASSERT_TRUE(store_->Load(&certs)); |
131 ASSERT_EQ(0U, certs.size()); | 161 ASSERT_EQ(0U, certs.size()); |
132 } | 162 } |
133 | 163 |
134 TEST_F(SQLiteOriginBoundCertStoreTest, TestUpgrade) { | 164 TEST_F(SQLiteOriginBoundCertStoreTest, TestUpgrade) { |
wtc
2011/12/15 23:34:28
Should we rename this test TestUpgradeV1?
mattm
2011/12/20 00:28:38
Done.
| |
135 // Reset the store. We'll be using a different database for this test. | 165 // Reset the store. We'll be using a different database for this test. |
136 store_ = NULL; | 166 store_ = NULL; |
137 | 167 |
138 FilePath v1_db_path(temp_dir_.path().AppendASCII("v1db")); | 168 FilePath v1_db_path(temp_dir_.path().AppendASCII("v1db")); |
139 | 169 |
170 std::string key_data; | |
171 std::string cert_data; | |
172 ReadTestKeyAndCert(&key_data, &cert_data); | |
173 | |
140 // Create a version 1 database. | 174 // Create a version 1 database. |
141 { | 175 { |
142 sql::Connection db; | 176 sql::Connection db; |
143 ASSERT_TRUE(db.Open(v1_db_path)); | 177 ASSERT_TRUE(db.Open(v1_db_path)); |
144 ASSERT_TRUE(db.Execute( | 178 ASSERT_TRUE(db.Execute( |
145 "CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY," | 179 "CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY," |
146 "value LONGVARCHAR);" | 180 "value LONGVARCHAR);" |
147 "INSERT INTO \"meta\" VALUES('version','1');" | 181 "INSERT INTO \"meta\" VALUES('version','1');" |
148 "INSERT INTO \"meta\" VALUES('last_compatible_version','1');" | 182 "INSERT INTO \"meta\" VALUES('last_compatible_version','1');" |
149 "CREATE TABLE origin_bound_certs (" | 183 "CREATE TABLE origin_bound_certs (" |
150 "origin TEXT NOT NULL UNIQUE PRIMARY KEY," | 184 "origin TEXT NOT NULL UNIQUE PRIMARY KEY," |
151 "private_key BLOB NOT NULL,cert BLOB NOT NULL);" | 185 "private_key BLOB NOT NULL,cert BLOB NOT NULL);")); |
152 "INSERT INTO \"origin_bound_certs\" VALUES(" | 186 |
153 "'https://google.com',X'AA',X'BB');" | 187 sql::Statement add_smt(db.GetUniqueStatement( |
188 "INSERT INTO origin_bound_certs (origin, private_key, cert) " | |
189 "VALUES (?,?,?)")); | |
190 add_smt.BindString(0, "https://www.google.com:443"); | |
wtc
2011/12/15 23:34:28
Nit: to be more realistic, should we omit the defa
mattm
2011/12/20 00:28:38
That's actually how the origin is stored by the co
| |
191 add_smt.BindBlob(1, key_data.data(), key_data.size()); | |
192 add_smt.BindBlob(2, cert_data.data(), cert_data.size()); | |
193 ASSERT_TRUE(add_smt.Run()); | |
194 | |
195 ASSERT_TRUE(db.Execute( | |
154 "INSERT INTO \"origin_bound_certs\" VALUES(" | 196 "INSERT INTO \"origin_bound_certs\" VALUES(" |
155 "'https://foo.com',X'CC',X'DD');" | 197 "'https://foo.com',X'CC',X'DD');" |
wtc
2011/12/15 23:34:28
Nit: this cert can use X'AA' and X'BB' now. This
mattm
2011/12/20 00:28:38
Done.
| |
156 )); | 198 )); |
157 } | 199 } |
158 | 200 |
159 std::vector<net::DefaultOriginBoundCertStore::OriginBoundCert*> certs; | 201 // Load and test the DB contents twice. First time ensures that we can use |
160 store_ = new SQLiteOriginBoundCertStore(v1_db_path); | 202 // the updated values immediately. Second time ensures that the updated |
203 // values are stored and read correctly on next load. | |
204 for (int i = 0; i < 2; ++i) { | |
205 SCOPED_TRACE(i); | |
161 | 206 |
162 // Load the database and ensure the certs can be read and are marked as RSA. | 207 std::vector<net::DefaultOriginBoundCertStore::OriginBoundCert*> certs; |
163 ASSERT_TRUE(store_->Load(&certs)); | 208 store_ = new SQLiteOriginBoundCertStore(v1_db_path); |
164 ASSERT_EQ(2U, certs.size()); | |
165 ASSERT_STREQ("https://google.com", certs[0]->origin().c_str()); | |
166 ASSERT_EQ(net::CLIENT_CERT_RSA_SIGN, certs[0]->type()); | |
167 ASSERT_STREQ("\xaa", certs[0]->private_key().c_str()); | |
168 ASSERT_STREQ("\xbb", certs[0]->cert().c_str()); | |
169 ASSERT_STREQ("https://foo.com", certs[1]->origin().c_str()); | |
170 ASSERT_EQ(net::CLIENT_CERT_RSA_SIGN, certs[1]->type()); | |
171 ASSERT_STREQ("\xcc", certs[1]->private_key().c_str()); | |
172 ASSERT_STREQ("\xdd", certs[1]->cert().c_str()); | |
173 | 209 |
174 STLDeleteContainerPointers(certs.begin(), certs.end()); | 210 // Load the database and ensure the certs can be read and are marked as RSA. |
175 certs.clear(); | 211 ASSERT_TRUE(store_->Load(&certs)); |
212 ASSERT_EQ(2U, certs.size()); | |
176 | 213 |
177 store_ = NULL; | 214 ASSERT_STREQ("https://www.google.com:443", certs[0]->origin().c_str()); |
178 // Make sure we wait until the destructor has run. | 215 ASSERT_EQ(net::CLIENT_CERT_RSA_SIGN, certs[0]->type()); |
179 scoped_refptr<base::ThreadTestHelper> helper( | 216 ASSERT_EQ(GetTestCertExpirationTime(), |
180 new base::ThreadTestHelper( | 217 certs[0]->not_valid_after()); |
181 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB))); | 218 ASSERT_EQ(key_data, certs[0]->private_key()); |
182 ASSERT_TRUE(helper->Run()); | 219 ASSERT_EQ(cert_data, certs[0]->cert()); |
183 | 220 |
184 // Verify the database version is updated. | 221 ASSERT_STREQ("https://foo.com", certs[1]->origin().c_str()); |
185 { | 222 ASSERT_EQ(net::CLIENT_CERT_RSA_SIGN, certs[1]->type()); |
186 sql::Connection db; | 223 // Undecodable cert, expiration time will be uninitialized. |
187 ASSERT_TRUE(db.Open(v1_db_path)); | 224 ASSERT_EQ(base::Time(), certs[1]->not_valid_after()); |
188 sql::Statement smt(db.GetUniqueStatement( | 225 ASSERT_STREQ("\xcc", certs[1]->private_key().c_str()); |
189 "SELECT value FROM meta WHERE key = \"version\"")); | 226 ASSERT_STREQ("\xdd", certs[1]->cert().c_str()); |
190 ASSERT_TRUE(smt); | 227 |
191 ASSERT_TRUE(smt.Step()); | 228 STLDeleteContainerPointers(certs.begin(), certs.end()); |
192 EXPECT_EQ(2, smt.ColumnInt(0)); | 229 certs.clear(); |
wtc
2011/12/15 23:34:28
I believe these two lines are equivalent to:
S
mattm
2011/12/20 00:28:38
Done.
| |
193 EXPECT_FALSE(smt.Step()); | 230 |
231 store_ = NULL; | |
232 // Make sure we wait until the destructor has run. | |
233 scoped_refptr<base::ThreadTestHelper> helper( | |
234 new base::ThreadTestHelper( | |
235 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB))); | |
236 ASSERT_TRUE(helper->Run()); | |
237 | |
238 // Verify the database version is updated. | |
239 { | |
240 sql::Connection db; | |
241 ASSERT_TRUE(db.Open(v1_db_path)); | |
242 sql::Statement smt(db.GetUniqueStatement( | |
243 "SELECT value FROM meta WHERE key = \"version\"")); | |
244 ASSERT_TRUE(smt); | |
245 ASSERT_TRUE(smt.Step()); | |
246 EXPECT_EQ(3, smt.ColumnInt(0)); | |
247 EXPECT_FALSE(smt.Step()); | |
248 } | |
194 } | 249 } |
195 } | 250 } |
196 | 251 |
252 TEST_F(SQLiteOriginBoundCertStoreTest, TestUpgradeV2) { | |
253 // Reset the store. We'll be using a different database for this test. | |
254 store_ = NULL; | |
255 | |
256 FilePath v2_db_path(temp_dir_.path().AppendASCII("v2db")); | |
257 | |
258 std::string key_data; | |
259 std::string cert_data; | |
260 ReadTestKeyAndCert(&key_data, &cert_data); | |
261 | |
262 // Create a version 2 database. | |
263 { | |
264 sql::Connection db; | |
265 ASSERT_TRUE(db.Open(v2_db_path)); | |
266 ASSERT_TRUE(db.Execute( | |
267 "CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY," | |
268 "value LONGVARCHAR);" | |
269 "INSERT INTO \"meta\" VALUES('version','2');" | |
270 "INSERT INTO \"meta\" VALUES('last_compatible_version','1');" | |
271 "CREATE TABLE origin_bound_certs (" | |
272 "origin TEXT NOT NULL UNIQUE PRIMARY KEY," | |
273 "private_key BLOB NOT NULL," | |
274 "cert BLOB NOT NULL," | |
275 "cert_type INTEGER);" | |
276 )); | |
277 | |
278 sql::Statement add_smt(db.GetUniqueStatement( | |
279 "INSERT INTO origin_bound_certs (origin, private_key, cert, cert_type) " | |
280 "VALUES (?,?,?,?)")); | |
281 add_smt.BindString(0, "https://www.google.com:443"); | |
282 add_smt.BindBlob(1, key_data.data(), key_data.size()); | |
283 add_smt.BindBlob(2, cert_data.data(), cert_data.size()); | |
284 add_smt.BindInt64(3, 1); | |
285 ASSERT_TRUE(add_smt.Run()); | |
286 | |
287 ASSERT_TRUE(db.Execute( | |
288 "INSERT INTO \"origin_bound_certs\" VALUES(" | |
289 "'https://foo.com',X'CC',X'DD',64);" | |
290 )); | |
291 } | |
292 | |
293 | |
wtc
2011/12/15 23:34:28
Nit: delete one blank line.
mattm
2011/12/20 00:28:38
Done.
| |
294 // Load and test the DB contents twice. First time ensures that we can use | |
295 // the updated values immediately. Second time ensures that the updated | |
296 // values are saved and read correctly on next load. | |
297 for (int i = 0; i < 2; ++i) { | |
298 SCOPED_TRACE(i); | |
299 | |
300 std::vector<net::DefaultOriginBoundCertStore::OriginBoundCert*> certs; | |
301 store_ = new SQLiteOriginBoundCertStore(v2_db_path); | |
302 | |
303 // Load the database and ensure the certs can be read and are marked as RSA. | |
304 ASSERT_TRUE(store_->Load(&certs)); | |
305 ASSERT_EQ(2U, certs.size()); | |
306 | |
307 ASSERT_STREQ("https://www.google.com:443", certs[0]->origin().c_str()); | |
308 ASSERT_EQ(net::CLIENT_CERT_RSA_SIGN, certs[0]->type()); | |
309 ASSERT_EQ(GetTestCertExpirationTime(), | |
310 certs[0]->not_valid_after()); | |
311 ASSERT_EQ(key_data, certs[0]->private_key()); | |
312 ASSERT_EQ(cert_data, certs[0]->cert()); | |
313 | |
314 ASSERT_STREQ("https://foo.com", certs[1]->origin().c_str()); | |
315 ASSERT_EQ(net::CLIENT_CERT_ECDSA_SIGN, certs[1]->type()); | |
316 // Undecodable cert, expiration time will be uninitialized. | |
317 ASSERT_EQ(base::Time(), certs[1]->not_valid_after()); | |
318 ASSERT_STREQ("\xcc", certs[1]->private_key().c_str()); | |
319 ASSERT_STREQ("\xdd", certs[1]->cert().c_str()); | |
320 | |
321 STLDeleteContainerPointers(certs.begin(), certs.end()); | |
322 certs.clear(); | |
323 | |
324 store_ = NULL; | |
325 // Make sure we wait until the destructor has run. | |
326 scoped_refptr<base::ThreadTestHelper> helper( | |
327 new base::ThreadTestHelper( | |
328 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB))); | |
329 ASSERT_TRUE(helper->Run()); | |
330 | |
331 // Verify the database version is updated. | |
332 { | |
333 sql::Connection db; | |
334 ASSERT_TRUE(db.Open(v2_db_path)); | |
335 sql::Statement smt(db.GetUniqueStatement( | |
336 "SELECT value FROM meta WHERE key = \"version\"")); | |
337 ASSERT_TRUE(smt); | |
338 ASSERT_TRUE(smt.Step()); | |
339 EXPECT_EQ(3, smt.ColumnInt(0)); | |
340 EXPECT_FALSE(smt.Step()); | |
341 } | |
342 } | |
343 } | |
344 | |
197 // Test that we can force the database to be written by calling Flush(). | 345 // Test that we can force the database to be written by calling Flush(). |
198 TEST_F(SQLiteOriginBoundCertStoreTest, TestFlush) { | 346 TEST_F(SQLiteOriginBoundCertStoreTest, TestFlush) { |
199 // File timestamps don't work well on all platforms, so we'll determine | 347 // File timestamps don't work well on all platforms, so we'll determine |
200 // whether the DB file has been modified by checking its size. | 348 // whether the DB file has been modified by checking its size. |
201 FilePath path = temp_dir_.path().Append(chrome::kOBCertFilename); | 349 FilePath path = temp_dir_.path().Append(chrome::kOBCertFilename); |
202 base::PlatformFileInfo info; | 350 base::PlatformFileInfo info; |
203 ASSERT_TRUE(file_util::GetFileInfo(path, &info)); | 351 ASSERT_TRUE(file_util::GetFileInfo(path, &info)); |
204 int64 base_size = info.size; | 352 int64 base_size = info.size; |
205 | 353 |
206 // Write some certs, so the DB will have to expand by several KB. | 354 // Write some certs, so the DB will have to expand by several KB. |
207 for (char c = 'a'; c < 'z'; ++c) { | 355 for (char c = 'a'; c < 'z'; ++c) { |
208 std::string origin(1, c); | 356 std::string origin(1, c); |
209 std::string private_key(1000, c); | 357 std::string private_key(1000, c); |
210 std::string cert(1000, c); | 358 std::string cert(1000, c); |
211 store_->AddOriginBoundCert( | 359 store_->AddOriginBoundCert( |
212 net::DefaultOriginBoundCertStore::OriginBoundCert( | 360 net::DefaultOriginBoundCertStore::OriginBoundCert( |
213 origin, | 361 origin, |
214 net::CLIENT_CERT_RSA_SIGN, | 362 net::CLIENT_CERT_RSA_SIGN, |
363 base::Time(), | |
215 private_key, | 364 private_key, |
216 cert)); | 365 cert)); |
217 } | 366 } |
218 | 367 |
219 // Call Flush() and wait until the DB thread is idle. | 368 // Call Flush() and wait until the DB thread is idle. |
220 store_->Flush(base::Closure()); | 369 store_->Flush(base::Closure()); |
221 scoped_refptr<base::ThreadTestHelper> helper( | 370 scoped_refptr<base::ThreadTestHelper> helper( |
222 new base::ThreadTestHelper( | 371 new base::ThreadTestHelper( |
223 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB))); | 372 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB))); |
224 ASSERT_TRUE(helper->Run()); | 373 ASSERT_TRUE(helper->Run()); |
(...skipping 30 matching lines...) Expand all Loading... | |
255 | 404 |
256 store_->Flush(base::Bind(&CallbackCounter::Callback, counter.get())); | 405 store_->Flush(base::Bind(&CallbackCounter::Callback, counter.get())); |
257 | 406 |
258 scoped_refptr<base::ThreadTestHelper> helper( | 407 scoped_refptr<base::ThreadTestHelper> helper( |
259 new base::ThreadTestHelper( | 408 new base::ThreadTestHelper( |
260 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB))); | 409 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::DB))); |
261 ASSERT_TRUE(helper->Run()); | 410 ASSERT_TRUE(helper->Run()); |
262 | 411 |
263 ASSERT_EQ(1, counter->callback_count()); | 412 ASSERT_EQ(1, counter->callback_count()); |
264 } | 413 } |
OLD | NEW |