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

Side by Side Diff: content/browser/background_sync/background_sync_manager_unittest.cc

Issue 950343006: [BackgroundSync] Initial land of the BackgroundSyncManager (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Mapped registrations, more tests, register overwrites existing, unique ids for registrations Created 5 years, 9 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
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/browser/background_sync/background_sync_manager.h"
6
7 #include "base/files/scoped_temp_dir.h"
8 #include "base/logging.h"
9 #include "base/run_loop.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "content/browser/browser_thread_impl.h"
12 #include "content/browser/service_worker/service_worker_context_wrapper.h"
13 #include "content/browser/service_worker/service_worker_storage.h"
14 #include "content/public/test/test_browser_thread_bundle.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16
17 namespace {
18 const char kOriginUrl[] = "https://example.com";
19 const int64 kServiceWorkerVersionId = 0;
20 const int64 kServiceWorkerId1 = 1;
21 const int64 kServiceWorkerId2 = 2;
22 }
23
24 namespace content {
25
26 // A BackgroundSyncManager that can simulate delaying and corrupting the
27 // backend. This class assumes (and verifies) that only one operation runs at a
28 // time.
29 class TestBackgroundSyncManager : public BackgroundSyncManager {
30 public:
31 explicit TestBackgroundSyncManager(
32 const scoped_refptr<ServiceWorkerContextWrapper>& service_worker_context)
33 : BackgroundSyncManager(service_worker_context) {}
34
35 void DoInit() { Init(); }
36
37 void StoreDataInBackendContinue(
38 int64 sw_registration_id,
39 const GURL& origin,
40 const std::string& key,
41 const std::string& data,
42 const ServiceWorkerStorage::StatusCallback& callback) {
43 BackgroundSyncManager::StoreDataInBackend(sw_registration_id, origin, key,
44 data, callback);
45 }
46
47 void GetDataFromBackendContinue(
48 const std::string& key,
49 const ServiceWorkerStorage::GetUserDataForAllRegistrationsCallback&
50 callback) {
51 BackgroundSyncManager::GetDataFromBackend(key, callback);
52 }
53
54 void Continue() {
55 continuation_.Run();
56 continuation_.Reset();
57 }
58
59 void set_corrupt_backend(bool corrupt_backend) {
60 corrupt_backend_ = corrupt_backend;
61 }
62 void set_delay_backend(bool delay_backend) { delay_backend_ = delay_backend; }
63
64 protected:
65 void StoreDataInBackend(
66 int64 sw_registration_id,
67 const GURL& origin,
68 const std::string& key,
69 const std::string& data,
70 const ServiceWorkerStorage::StatusCallback& callback) override {
71 EXPECT_TRUE(continuation_.is_null());
72 if (corrupt_backend_) {
73 callback.Run(SERVICE_WORKER_ERROR_FAILED);
davidben 2015/03/25 16:01:10 Nit: The real StoreDataInBackend never calls the c
jkarlin 2015/03/25 19:24:18 Done.
74 return;
75 }
76 continuation_ =
77 base::Bind(&TestBackgroundSyncManager::StoreDataInBackendContinue,
78 base::Unretained(this), sw_registration_id, origin, key,
79 data, callback);
80 if (delay_backend_)
81 return;
82
83 Continue();
84 }
85
86 void GetDataFromBackend(
87 const std::string& key,
88 const ServiceWorkerStorage::GetUserDataForAllRegistrationsCallback&
89 callback) override {
90 EXPECT_TRUE(continuation_.is_null());
91 if (corrupt_backend_) {
92 callback.Run(std::vector<std::pair<int64, std::string>>(),
davidben 2015/03/25 16:01:10 Nit: Ditto about it being reentrant.
jkarlin 2015/03/25 19:24:19 Done.
93 SERVICE_WORKER_ERROR_FAILED);
94 return;
95 }
96 continuation_ =
97 base::Bind(&TestBackgroundSyncManager::GetDataFromBackendContinue,
98 base::Unretained(this), key, callback);
99 if (delay_backend_)
100 return;
101
102 Continue();
103 }
104
105 private:
106 bool corrupt_backend_ = false;
107 bool delay_backend_ = false;
108 base::Closure continuation_;
109 };
110
111 class BackgroundSyncManagerTest : public testing::Test {
112 public:
113 BackgroundSyncManagerTest()
114 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP),
115 service_worker_context_(new ServiceWorkerContextWrapper(NULL)),
116 origin_(kOriginUrl),
117 sync_reg_1_(BackgroundSyncManager::BackgroundSyncRegistration("foo")),
118 sync_reg_2_(BackgroundSyncManager::BackgroundSyncRegistration("bar")),
119 callback_error_(BackgroundSyncManager::ERROR_TYPE_OK),
120 callback_sw_status_code_(SERVICE_WORKER_OK) {}
121
122 void SetUp() override {
123 scoped_ptr<ServiceWorkerDatabaseTaskManager> database_task_manager(
124 new MockServiceWorkerDatabaseTaskManager(
125 base::ThreadTaskRunnerHandle::Get()));
126
127 service_worker_context_->InitInternal(
128 base::FilePath(), base::ThreadTaskRunnerHandle::Get(),
129 database_task_manager.Pass(), base::ThreadTaskRunnerHandle::Get(), NULL,
130 NULL);
131 context_ptr_ = service_worker_context_->context()->AsWeakPtr();
132
133 background_sync_manager_ =
134 BackgroundSyncManager::Create(service_worker_context_);
135
136 // Wait for storage to finish initializing before registering service
137 // workers.
138 base::RunLoop().RunUntilIdle();
139
140 RegisterServiceWorker(kServiceWorkerId1);
141 RegisterServiceWorker(kServiceWorkerId2);
142 }
143
144 void StatusAndRegistrationCallback(
145 bool* was_called,
146 BackgroundSyncManager::ErrorType error,
147 const BackgroundSyncManager::BackgroundSyncRegistration& registration) {
148 *was_called = true;
149 callback_error_ = error;
150 callback_registration_ = registration;
151 }
152
153 void StatusCallback(bool* was_called,
154 BackgroundSyncManager::ErrorType error) {
155 *was_called = true;
156 callback_error_ = error;
157 }
158
159 protected:
160 TestBackgroundSyncManager* UseTestBackgroundSyncManager() {
161 TestBackgroundSyncManager* manager =
162 new TestBackgroundSyncManager(service_worker_context_);
163 background_sync_manager_.reset(manager);
164 manager->DoInit();
165 return manager;
166 }
167
168 bool Register(const BackgroundSyncManager::BackgroundSyncRegistration&
169 sync_registration) {
170 return RegisterWithServiceWorkerId(kServiceWorkerId1, sync_registration);
171 }
172
173 bool RegisterWithServiceWorkerId(
174 int64 sw_registration_id,
175 const BackgroundSyncManager::BackgroundSyncRegistration&
176 sync_registration) {
177 bool was_called = false;
178 background_sync_manager_->Register(
179 origin_, sw_registration_id, sync_registration,
180 base::Bind(&BackgroundSyncManagerTest::StatusAndRegistrationCallback,
181 base::Unretained(this), &was_called));
182 base::RunLoop().RunUntilIdle();
183 EXPECT_TRUE(was_called);
184 return callback_error_ == BackgroundSyncManager::ERROR_TYPE_OK;
185 }
186
187 bool Unregister(const BackgroundSyncManager::BackgroundSyncRegistration&
188 sync_registration) {
189 return UnregisterWithServiceWorkerId(kServiceWorkerId1, sync_registration);
190 }
191
192 bool UnregisterWithServiceWorkerId(
193 int64 sw_registration_id,
194 const BackgroundSyncManager::BackgroundSyncRegistration&
195 sync_registration) {
196 bool was_called = false;
197 background_sync_manager_->Unregister(
198 origin_, sw_registration_id, sync_registration.name,
199 sync_registration.id,
200 base::Bind(&BackgroundSyncManagerTest::StatusCallback,
201 base::Unretained(this), &was_called));
202 base::RunLoop().RunUntilIdle();
203 EXPECT_TRUE(was_called);
204 return callback_error_ == BackgroundSyncManager::ERROR_TYPE_OK;
205 }
206
207 bool GetRegistration(const std::string& sync_registration_name) {
208 return GetRegistrationWithServiceWorkerId(kServiceWorkerId1,
209 sync_registration_name);
210 }
211
212 bool GetRegistrationWithServiceWorkerId(
213 int64 sw_registration_id,
214 const std::string& sync_registration_name) {
215 bool was_called = false;
216 background_sync_manager_->GetRegistration(
217 origin_, sw_registration_id, sync_registration_name,
218 base::Bind(&BackgroundSyncManagerTest::StatusAndRegistrationCallback,
219 base::Unretained(this), &was_called));
220 base::RunLoop().RunUntilIdle();
221 EXPECT_TRUE(was_called);
222
223 if (callback_error_ == BackgroundSyncManager::ERROR_TYPE_OK)
224 EXPECT_TRUE(sync_registration_name == callback_registration_.name);
225
226 return callback_error_ == BackgroundSyncManager::ERROR_TYPE_OK;
227 }
228
229 void StorageRegistrationCallback(ServiceWorkerStatusCode result) {
230 callback_sw_status_code_ = result;
231 }
232
233 void RegisterServiceWorker(uint64 sw_registration_id) {
234 scoped_refptr<ServiceWorkerRegistration> live_registration =
235 new ServiceWorkerRegistration(origin_, sw_registration_id,
236 context_ptr_);
237
238 scoped_refptr<ServiceWorkerVersion> live_version = new ServiceWorkerVersion(
239 live_registration.get(), GURL(std::string(kOriginUrl) + "/script.js"),
240 kServiceWorkerVersionId, context_ptr_);
241 live_version->SetStatus(ServiceWorkerVersion::INSTALLED);
242 live_registration->SetWaitingVersion(live_version.get());
243
244 service_worker_context_->context()->storage()->StoreRegistration(
245 live_registration.get(), live_version.get(),
246 base::Bind(&BackgroundSyncManagerTest::StorageRegistrationCallback,
247 base::Unretained(this)));
248
249 base::RunLoop().RunUntilIdle();
250 EXPECT_EQ(SERVICE_WORKER_OK, callback_sw_status_code_);
251 }
252
253 TestBrowserThreadBundle browser_thread_bundle_;
254 scoped_refptr<ServiceWorkerContextWrapper> service_worker_context_;
255 scoped_ptr<BackgroundSyncManager> background_sync_manager_;
256 base::WeakPtr<ServiceWorkerContextCore> context_ptr_;
257
258 const GURL origin_;
259 BackgroundSyncManager::BackgroundSyncRegistration sync_reg_1_;
260 BackgroundSyncManager::BackgroundSyncRegistration sync_reg_2_;
261
262 // Callback values.
263 BackgroundSyncManager::ErrorType callback_error_;
264 BackgroundSyncManager::BackgroundSyncRegistration callback_registration_;
265 ServiceWorkerStatusCode callback_sw_status_code_;
266 };
267
268 TEST_F(BackgroundSyncManagerTest, Register) {
269 EXPECT_TRUE(Register(sync_reg_1_));
270 }
271
272 TEST_F(BackgroundSyncManagerTest, RegistractionIntact) {
273 EXPECT_TRUE(Register(sync_reg_1_));
274 EXPECT_STREQ(sync_reg_1_.name.c_str(), callback_registration_.name.c_str());
275 EXPECT_NE(sync_reg_1_.id, callback_registration_.id);
davidben 2015/03/25 16:01:10 Nit: I'd replace sync_reg_1_.id with BackgroundSyn
jkarlin 2015/03/25 19:24:18 Done.
276 }
277
278 TEST_F(BackgroundSyncManagerTest, RegisterExistingKeepsId) {
279 EXPECT_TRUE(Register(sync_reg_1_));
280 BackgroundSyncManager::BackgroundSyncRegistration first_registration =
281 callback_registration_;
282 EXPECT_TRUE(Register(sync_reg_1_));
283 EXPECT_TRUE(callback_registration_.Equals(first_registration));
284 EXPECT_EQ(first_registration.id, callback_registration_.id);
285 }
286
287 TEST_F(BackgroundSyncManagerTest, RegisterOverwrites) {
288 EXPECT_TRUE(Register(sync_reg_1_));
289 BackgroundSyncManager::BackgroundSyncRegistration first_registration =
290 callback_registration_;
291
292 sync_reg_1_.min_period = 100;
293 EXPECT_TRUE(Register(sync_reg_1_));
294 EXPECT_LT(first_registration.id, callback_registration_.id);
295 EXPECT_FALSE(callback_registration_.Equals(first_registration));
296 }
297
298 TEST_F(BackgroundSyncManagerTest, RegisterBadBackend) {
299 TestBackgroundSyncManager* manager = UseTestBackgroundSyncManager();
300 manager->set_corrupt_backend(true);
301 EXPECT_FALSE(Register(sync_reg_1_));
302 manager->set_corrupt_backend(false);
303 EXPECT_FALSE(GetRegistration(sync_reg_1_.name));
304 }
305
306 TEST_F(BackgroundSyncManagerTest, RegisterOverwriteBadBackend) {
307 TestBackgroundSyncManager* manager = UseTestBackgroundSyncManager();
308 EXPECT_TRUE(Register(sync_reg_1_));
309 BackgroundSyncManager::BackgroundSyncRegistration first_registration =
310 callback_registration_;
311
312 sync_reg_1_.min_period = 100;
313
314 manager->set_corrupt_backend(true);
315 EXPECT_FALSE(Register(sync_reg_1_));
316 EXPECT_TRUE(GetRegistration(sync_reg_1_.name));
317 EXPECT_EQ(callback_registration_.id, first_registration.id);
318 EXPECT_TRUE(callback_registration_.Equals(first_registration));
319 }
320
321 TEST_F(BackgroundSyncManagerTest, TwoRegistrations) {
322 EXPECT_TRUE(Register(sync_reg_1_));
323 EXPECT_TRUE(Register(sync_reg_2_));
324 }
325
326 TEST_F(BackgroundSyncManagerTest, GetRegistrationNonExisting) {
327 EXPECT_FALSE(GetRegistration(sync_reg_1_.name));
328 }
329
330 TEST_F(BackgroundSyncManagerTest, GetRegistrationExisting) {
331 EXPECT_TRUE(Register(sync_reg_1_));
332 EXPECT_TRUE(GetRegistration(sync_reg_1_.name));
333 EXPECT_FALSE(GetRegistration(sync_reg_2_.name));
334 }
335
336 TEST_F(BackgroundSyncManagerTest, GetRegistrationBadBackend) {
337 TestBackgroundSyncManager* manager = UseTestBackgroundSyncManager();
338 EXPECT_TRUE(Register(sync_reg_1_));
339 manager->set_corrupt_backend(true);
340 EXPECT_TRUE(GetRegistration(sync_reg_1_.name));
341 EXPECT_FALSE(GetRegistration(sync_reg_2_.name));
342 manager->set_corrupt_backend(false);
343 EXPECT_TRUE(GetRegistration(sync_reg_1_.name));
344 EXPECT_FALSE(GetRegistration(sync_reg_2_.name));
345 }
346
347 TEST_F(BackgroundSyncManagerTest, Unregister) {
348 EXPECT_TRUE(Register(sync_reg_1_));
349 EXPECT_TRUE(Unregister(callback_registration_));
350 EXPECT_FALSE(GetRegistration(sync_reg_1_.name));
351 }
352
353 TEST_F(BackgroundSyncManagerTest, UnregisterWrongId) {
354 EXPECT_TRUE(Register(sync_reg_1_));
355 callback_registration_.id = 10012310;
davidben 2015/03/25 16:01:10 Nit: That's a very weird number. :-) Maybe just ca
jkarlin 2015/03/25 19:24:18 Done.
356 EXPECT_FALSE(Unregister(callback_registration_));
357 }
358
359 TEST_F(BackgroundSyncManagerTest, Reregister) {
360 EXPECT_TRUE(Register(sync_reg_1_));
361 EXPECT_TRUE(Unregister(callback_registration_));
362 EXPECT_TRUE(Register(sync_reg_1_));
363 }
364
365 TEST_F(BackgroundSyncManagerTest, UnregisterNonExisting) {
366 EXPECT_FALSE(Unregister(sync_reg_1_));
367 EXPECT_EQ(BackgroundSyncManager::ERROR_TYPE_NOT_FOUND, callback_error_);
368 }
369
370 TEST_F(BackgroundSyncManagerTest, UnregisterSecond) {
371 EXPECT_TRUE(Register(sync_reg_1_));
372 EXPECT_TRUE(Register(sync_reg_2_));
373 EXPECT_TRUE(Unregister(callback_registration_));
374 EXPECT_TRUE(GetRegistration(sync_reg_1_.name));
375 EXPECT_TRUE(Register(sync_reg_2_));
376 }
377
378 TEST_F(BackgroundSyncManagerTest, UnregisterBadBackend) {
379 TestBackgroundSyncManager* manager = UseTestBackgroundSyncManager();
380 EXPECT_TRUE(Register(sync_reg_1_));
381 manager->set_corrupt_backend(true);
382 EXPECT_FALSE(Unregister(sync_reg_1_));
383 manager->set_corrupt_backend(false);
384 EXPECT_TRUE(GetRegistration(sync_reg_1_.name));
davidben 2015/03/25 16:01:10 Probably should add some assertions that callback_
jkarlin 2015/03/25 19:24:18 Yep, done. Verified that updated test fails withou
385 }
386
387 TEST_F(BackgroundSyncManagerTest, RegistrationIncreasesId) {
388 EXPECT_TRUE(Register(sync_reg_1_));
389 BackgroundSyncManager::BackgroundSyncRegistration registered_sync =
390 callback_registration_;
391 BackgroundSyncManager::BackgroundSyncRegistration::RegistrationId cur_id =
392 callback_registration_.id;
393
394 EXPECT_TRUE(GetRegistration(sync_reg_1_.name));
395 EXPECT_TRUE(Register(sync_reg_2_));
396 EXPECT_LT(cur_id, callback_registration_.id);
397 cur_id = callback_registration_.id;
398
399 EXPECT_TRUE(Unregister(registered_sync));
400 EXPECT_TRUE(Register(sync_reg_1_));
401 EXPECT_LT(cur_id, callback_registration_.id);
402 }
403
404 TEST_F(BackgroundSyncManagerTest, RebootRecovery) {
405 EXPECT_TRUE(Register(sync_reg_1_));
406
407 background_sync_manager_ =
408 BackgroundSyncManager::Create(service_worker_context_);
409
410 EXPECT_TRUE(GetRegistration(sync_reg_1_.name));
411 EXPECT_FALSE(GetRegistration(sync_reg_2_.name));
412 }
413
414 TEST_F(BackgroundSyncManagerTest, RebootRecoveryTwoServiceWorkers) {
415 EXPECT_TRUE(RegisterWithServiceWorkerId(kServiceWorkerId1, sync_reg_1_));
416 EXPECT_TRUE(RegisterWithServiceWorkerId(kServiceWorkerId2, sync_reg_2_));
417
418 background_sync_manager_ =
419 BackgroundSyncManager::Create(service_worker_context_);
420
421 EXPECT_TRUE(
422 GetRegistrationWithServiceWorkerId(kServiceWorkerId1, sync_reg_1_.name));
423 EXPECT_FALSE(
424 GetRegistrationWithServiceWorkerId(kServiceWorkerId1, sync_reg_2_.name));
425 EXPECT_FALSE(
426 GetRegistrationWithServiceWorkerId(kServiceWorkerId2, sync_reg_1_.name));
427 EXPECT_TRUE(
428 GetRegistrationWithServiceWorkerId(kServiceWorkerId2, sync_reg_2_.name));
429
430 EXPECT_TRUE(
431 GetRegistrationWithServiceWorkerId(kServiceWorkerId1, sync_reg_1_.name));
432 EXPECT_TRUE(
433 GetRegistrationWithServiceWorkerId(kServiceWorkerId2, sync_reg_2_.name));
434
435 EXPECT_TRUE(RegisterWithServiceWorkerId(kServiceWorkerId1, sync_reg_2_));
436 EXPECT_TRUE(RegisterWithServiceWorkerId(kServiceWorkerId2, sync_reg_1_));
437 }
438
439 TEST_F(BackgroundSyncManagerTest, InitWithCorruptBackend) {
440 TestBackgroundSyncManager* manager =
441 new TestBackgroundSyncManager(service_worker_context_);
442 background_sync_manager_.reset(manager);
443 manager->set_corrupt_backend(true);
444 manager->DoInit();
445
446 EXPECT_FALSE(Register(sync_reg_1_));
447 EXPECT_FALSE(GetRegistration(sync_reg_1_.name));
448 EXPECT_FALSE(Unregister(sync_reg_1_));
449 }
450
451 TEST_F(BackgroundSyncManagerTest, SequentialOperations) {
452 // Schedule Init and all of the operations on a delayed backend. Verify that
453 // the operations complete sequentially.
454 TestBackgroundSyncManager* manager =
455 new TestBackgroundSyncManager(service_worker_context_);
456 background_sync_manager_.reset(manager);
457 manager->set_delay_backend(true);
458 manager->DoInit();
459
460 const int64 kExpectedInitialId =
461 BackgroundSyncManager::BackgroundSyncRegistrations::kInitialCounterId;
462
463 bool register_called = false;
464 bool unregister_called = false;
465 bool get_registration_called = false;
466 manager->Register(
467 origin_, kServiceWorkerId1, sync_reg_1_,
468 base::Bind(&BackgroundSyncManagerTest::StatusAndRegistrationCallback,
469 base::Unretained(this), &register_called));
470 manager->Unregister(origin_, kServiceWorkerId1, sync_reg_1_.name,
471 kExpectedInitialId,
472 base::Bind(&BackgroundSyncManagerTest::StatusCallback,
473 base::Unretained(this), &unregister_called));
474 manager->GetRegistration(
475 origin_, kServiceWorkerId1, sync_reg_1_.name,
476 base::Bind(&BackgroundSyncManagerTest::StatusAndRegistrationCallback,
477 base::Unretained(this), &get_registration_called));
478
479 base::RunLoop().RunUntilIdle();
480 // Init should be blocked while loading from the backend.
481 EXPECT_FALSE(register_called || unregister_called || get_registration_called);
davidben 2015/03/25 16:01:10 Nit: I'd expand these out individually (and ditto
jkarlin 2015/03/25 19:24:18 Done.
482
483 manager->Continue();
484 base::RunLoop().RunUntilIdle();
485 // Register should be blocked while storing to the backend.
486 EXPECT_FALSE(register_called || unregister_called || get_registration_called);
487
488 manager->Continue();
489 base::RunLoop().RunUntilIdle();
490 EXPECT_TRUE(register_called);
491 EXPECT_EQ(kExpectedInitialId, callback_registration_.id);
492 EXPECT_EQ(BackgroundSyncManager::ERROR_TYPE_OK, callback_error_);
493 // Unregister should be blocked while storing to the backend.
494 EXPECT_FALSE(unregister_called || get_registration_called);
495
496 manager->Continue();
497 base::RunLoop().RunUntilIdle();
498 // Unregister should be done and since GetRegistration doesn't require the
499 // backend it should be done too.
500 EXPECT_EQ(BackgroundSyncManager::ERROR_TYPE_NOT_FOUND, callback_error_);
501 EXPECT_TRUE(unregister_called && get_registration_called);
502 }
503
504 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698