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.
5 #include "content/browser/background_sync/background_sync_manager.h"
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"
18 const char kOriginUrl
[] = "https://example.com";
19 const int64 kServiceWorkerVersionId
= 0;
20 const int64 kServiceWorkerId1
= 1;
21 const int64 kServiceWorkerId2
= 2;
26 // A BackgroundSyncManager that can simulate delaying and corrupting the
27 // backend. This class assumes (and verifies) that only one operation runs at a
29 class TestBackgroundSyncManager
: public BackgroundSyncManager
{
31 explicit TestBackgroundSyncManager(
32 const scoped_refptr
<ServiceWorkerContextWrapper
>& service_worker_context
)
33 : BackgroundSyncManager(service_worker_context
) {}
35 void DoInit() { Init(); }
37 void StoreDataInBackendContinue(
38 int64 sw_registration_id
,
40 const std::string
& key
,
41 const std::string
& data
,
42 const ServiceWorkerStorage::StatusCallback
& callback
) {
43 BackgroundSyncManager::StoreDataInBackend(sw_registration_id
, origin
, key
,
47 void GetDataFromBackendContinue(
48 const std::string
& key
,
49 const ServiceWorkerStorage::GetUserDataForAllRegistrationsCallback
&
51 BackgroundSyncManager::GetDataFromBackend(key
, callback
);
56 continuation_
.Reset();
59 void set_corrupt_backend(bool corrupt_backend
) {
60 corrupt_backend_
= corrupt_backend
;
62 void set_delay_backend(bool delay_backend
) { delay_backend_
= delay_backend
; }
65 void StoreDataInBackend(
66 int64 sw_registration_id
,
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 base::MessageLoop::current()->PostTask(
74 FROM_HERE
, base::Bind(callback
, SERVICE_WORKER_ERROR_FAILED
));
78 base::Bind(&TestBackgroundSyncManager::StoreDataInBackendContinue
,
79 base::Unretained(this), sw_registration_id
, origin
, key
,
87 void GetDataFromBackend(
88 const std::string
& key
,
89 const ServiceWorkerStorage::GetUserDataForAllRegistrationsCallback
&
91 EXPECT_TRUE(continuation_
.is_null());
92 if (corrupt_backend_
) {
93 base::MessageLoop::current()->PostTask(
95 base::Bind(callback
, std::vector
<std::pair
<int64
, std::string
>>(),
96 SERVICE_WORKER_ERROR_FAILED
));
100 base::Bind(&TestBackgroundSyncManager::GetDataFromBackendContinue
,
101 base::Unretained(this), key
, callback
);
109 bool corrupt_backend_
= false;
110 bool delay_backend_
= false;
111 base::Closure continuation_
;
114 class BackgroundSyncManagerTest
: public testing::Test
{
116 BackgroundSyncManagerTest()
117 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP
),
118 service_worker_context_(new ServiceWorkerContextWrapper(NULL
)),
120 sync_reg_1_(BackgroundSyncManager::BackgroundSyncRegistration("foo")),
121 sync_reg_2_(BackgroundSyncManager::BackgroundSyncRegistration("bar")),
122 callback_error_(BackgroundSyncManager::ERROR_TYPE_OK
),
123 callback_sw_status_code_(SERVICE_WORKER_OK
) {}
125 void SetUp() override
{
126 scoped_ptr
<ServiceWorkerDatabaseTaskManager
> database_task_manager(
127 new MockServiceWorkerDatabaseTaskManager(
128 base::ThreadTaskRunnerHandle::Get()));
130 service_worker_context_
->InitInternal(
131 base::FilePath(), database_task_manager
.Pass(),
132 base::ThreadTaskRunnerHandle::Get(), NULL
, NULL
);
133 context_ptr_
= service_worker_context_
->context()->AsWeakPtr();
135 background_sync_manager_
=
136 BackgroundSyncManager::Create(service_worker_context_
);
138 // Wait for storage to finish initializing before registering service
140 base::RunLoop().RunUntilIdle();
142 RegisterServiceWorker(kServiceWorkerId1
);
143 RegisterServiceWorker(kServiceWorkerId2
);
146 void StatusAndRegistrationCallback(
148 BackgroundSyncManager::ErrorType error
,
149 const BackgroundSyncManager::BackgroundSyncRegistration
& registration
) {
151 callback_error_
= error
;
152 callback_registration_
= registration
;
155 void StatusCallback(bool* was_called
,
156 BackgroundSyncManager::ErrorType error
) {
158 callback_error_
= error
;
162 TestBackgroundSyncManager
* UseTestBackgroundSyncManager() {
163 TestBackgroundSyncManager
* manager
=
164 new TestBackgroundSyncManager(service_worker_context_
);
165 background_sync_manager_
.reset(manager
);
170 bool Register(const BackgroundSyncManager::BackgroundSyncRegistration
&
172 return RegisterWithServiceWorkerId(kServiceWorkerId1
, sync_registration
);
175 bool RegisterWithServiceWorkerId(
176 int64 sw_registration_id
,
177 const BackgroundSyncManager::BackgroundSyncRegistration
&
179 bool was_called
= false;
180 background_sync_manager_
->Register(
181 origin_
, sw_registration_id
, sync_registration
,
182 base::Bind(&BackgroundSyncManagerTest::StatusAndRegistrationCallback
,
183 base::Unretained(this), &was_called
));
184 base::RunLoop().RunUntilIdle();
185 EXPECT_TRUE(was_called
);
186 return callback_error_
== BackgroundSyncManager::ERROR_TYPE_OK
;
189 bool Unregister(const BackgroundSyncManager::BackgroundSyncRegistration
&
191 return UnregisterWithServiceWorkerId(kServiceWorkerId1
, sync_registration
);
194 bool UnregisterWithServiceWorkerId(
195 int64 sw_registration_id
,
196 const BackgroundSyncManager::BackgroundSyncRegistration
&
198 bool was_called
= false;
199 background_sync_manager_
->Unregister(
200 origin_
, sw_registration_id
, sync_registration
.name
,
201 sync_registration
.id
,
202 base::Bind(&BackgroundSyncManagerTest::StatusCallback
,
203 base::Unretained(this), &was_called
));
204 base::RunLoop().RunUntilIdle();
205 EXPECT_TRUE(was_called
);
206 return callback_error_
== BackgroundSyncManager::ERROR_TYPE_OK
;
209 bool GetRegistration(const std::string
& sync_registration_name
) {
210 return GetRegistrationWithServiceWorkerId(kServiceWorkerId1
,
211 sync_registration_name
);
214 bool GetRegistrationWithServiceWorkerId(
215 int64 sw_registration_id
,
216 const std::string
& sync_registration_name
) {
217 bool was_called
= false;
218 background_sync_manager_
->GetRegistration(
219 origin_
, sw_registration_id
, sync_registration_name
,
220 base::Bind(&BackgroundSyncManagerTest::StatusAndRegistrationCallback
,
221 base::Unretained(this), &was_called
));
222 base::RunLoop().RunUntilIdle();
223 EXPECT_TRUE(was_called
);
225 if (callback_error_
== BackgroundSyncManager::ERROR_TYPE_OK
)
226 EXPECT_TRUE(sync_registration_name
== callback_registration_
.name
);
228 return callback_error_
== BackgroundSyncManager::ERROR_TYPE_OK
;
231 void StorageRegistrationCallback(ServiceWorkerStatusCode result
) {
232 callback_sw_status_code_
= result
;
235 void RegisterServiceWorker(uint64 sw_registration_id
) {
236 scoped_refptr
<ServiceWorkerRegistration
> live_registration
=
237 new ServiceWorkerRegistration(origin_
, sw_registration_id
,
240 scoped_refptr
<ServiceWorkerVersion
> live_version
= new ServiceWorkerVersion(
241 live_registration
.get(), GURL(std::string(kOriginUrl
) + "/script.js"),
242 kServiceWorkerVersionId
, context_ptr_
);
243 live_version
->SetStatus(ServiceWorkerVersion::INSTALLED
);
244 live_registration
->SetWaitingVersion(live_version
.get());
246 service_worker_context_
->context()->storage()->StoreRegistration(
247 live_registration
.get(), live_version
.get(),
248 base::Bind(&BackgroundSyncManagerTest::StorageRegistrationCallback
,
249 base::Unretained(this)));
251 base::RunLoop().RunUntilIdle();
252 EXPECT_EQ(SERVICE_WORKER_OK
, callback_sw_status_code_
);
255 TestBrowserThreadBundle browser_thread_bundle_
;
256 scoped_refptr
<ServiceWorkerContextWrapper
> service_worker_context_
;
257 scoped_ptr
<BackgroundSyncManager
> background_sync_manager_
;
258 base::WeakPtr
<ServiceWorkerContextCore
> context_ptr_
;
261 BackgroundSyncManager::BackgroundSyncRegistration sync_reg_1_
;
262 BackgroundSyncManager::BackgroundSyncRegistration sync_reg_2_
;
265 BackgroundSyncManager::ErrorType callback_error_
;
266 BackgroundSyncManager::BackgroundSyncRegistration callback_registration_
;
267 ServiceWorkerStatusCode callback_sw_status_code_
;
270 TEST_F(BackgroundSyncManagerTest
, Register
) {
271 EXPECT_TRUE(Register(sync_reg_1_
));
274 TEST_F(BackgroundSyncManagerTest
, RegistractionIntact
) {
275 EXPECT_TRUE(Register(sync_reg_1_
));
276 EXPECT_STREQ(sync_reg_1_
.name
.c_str(), callback_registration_
.name
.c_str());
278 BackgroundSyncManager::BackgroundSyncRegistration::kInvalidRegistrationId
,
279 callback_registration_
.id
);
282 TEST_F(BackgroundSyncManagerTest
, RegisterExistingKeepsId
) {
283 EXPECT_TRUE(Register(sync_reg_1_
));
284 BackgroundSyncManager::BackgroundSyncRegistration first_registration
=
285 callback_registration_
;
286 EXPECT_TRUE(Register(sync_reg_1_
));
287 EXPECT_TRUE(callback_registration_
.Equals(first_registration
));
288 EXPECT_EQ(first_registration
.id
, callback_registration_
.id
);
291 TEST_F(BackgroundSyncManagerTest
, RegisterOverwrites
) {
292 EXPECT_TRUE(Register(sync_reg_1_
));
293 BackgroundSyncManager::BackgroundSyncRegistration first_registration
=
294 callback_registration_
;
296 sync_reg_1_
.min_period
= 100;
297 EXPECT_TRUE(Register(sync_reg_1_
));
298 EXPECT_LT(first_registration
.id
, callback_registration_
.id
);
299 EXPECT_FALSE(callback_registration_
.Equals(first_registration
));
302 TEST_F(BackgroundSyncManagerTest
, RegisterBadBackend
) {
303 TestBackgroundSyncManager
* manager
= UseTestBackgroundSyncManager();
304 manager
->set_corrupt_backend(true);
305 EXPECT_FALSE(Register(sync_reg_1_
));
306 manager
->set_corrupt_backend(false);
307 EXPECT_FALSE(GetRegistration(sync_reg_1_
.name
));
310 TEST_F(BackgroundSyncManagerTest
, RegisterOverwriteBadBackend
) {
311 TestBackgroundSyncManager
* manager
= UseTestBackgroundSyncManager();
312 EXPECT_TRUE(Register(sync_reg_1_
));
313 BackgroundSyncManager::BackgroundSyncRegistration first_registration
=
314 callback_registration_
;
316 sync_reg_1_
.min_period
= 100;
318 manager
->set_corrupt_backend(true);
319 EXPECT_FALSE(Register(sync_reg_1_
));
320 EXPECT_TRUE(GetRegistration(sync_reg_1_
.name
));
321 EXPECT_EQ(callback_registration_
.id
, first_registration
.id
);
322 EXPECT_TRUE(callback_registration_
.Equals(first_registration
));
325 TEST_F(BackgroundSyncManagerTest
, TwoRegistrations
) {
326 EXPECT_TRUE(Register(sync_reg_1_
));
327 EXPECT_TRUE(Register(sync_reg_2_
));
330 TEST_F(BackgroundSyncManagerTest
, GetRegistrationNonExisting
) {
331 EXPECT_FALSE(GetRegistration(sync_reg_1_
.name
));
334 TEST_F(BackgroundSyncManagerTest
, GetRegistrationExisting
) {
335 EXPECT_TRUE(Register(sync_reg_1_
));
336 EXPECT_TRUE(GetRegistration(sync_reg_1_
.name
));
337 EXPECT_FALSE(GetRegistration(sync_reg_2_
.name
));
340 TEST_F(BackgroundSyncManagerTest
, GetRegistrationBadBackend
) {
341 TestBackgroundSyncManager
* manager
= UseTestBackgroundSyncManager();
342 EXPECT_TRUE(Register(sync_reg_1_
));
343 manager
->set_corrupt_backend(true);
344 EXPECT_TRUE(GetRegistration(sync_reg_1_
.name
));
345 EXPECT_FALSE(GetRegistration(sync_reg_2_
.name
));
346 manager
->set_corrupt_backend(false);
347 EXPECT_TRUE(GetRegistration(sync_reg_1_
.name
));
348 EXPECT_FALSE(GetRegistration(sync_reg_2_
.name
));
351 TEST_F(BackgroundSyncManagerTest
, Unregister
) {
352 EXPECT_TRUE(Register(sync_reg_1_
));
353 EXPECT_TRUE(Unregister(callback_registration_
));
354 EXPECT_FALSE(GetRegistration(sync_reg_1_
.name
));
357 TEST_F(BackgroundSyncManagerTest
, UnregisterWrongId
) {
358 EXPECT_TRUE(Register(sync_reg_1_
));
359 callback_registration_
.id
+= 1;
360 EXPECT_FALSE(Unregister(callback_registration_
));
363 TEST_F(BackgroundSyncManagerTest
, Reregister
) {
364 EXPECT_TRUE(Register(sync_reg_1_
));
365 EXPECT_TRUE(Unregister(callback_registration_
));
366 EXPECT_TRUE(Register(sync_reg_1_
));
369 TEST_F(BackgroundSyncManagerTest
, UnregisterNonExisting
) {
370 EXPECT_FALSE(Unregister(sync_reg_1_
));
371 EXPECT_EQ(BackgroundSyncManager::ERROR_TYPE_NOT_FOUND
, callback_error_
);
374 TEST_F(BackgroundSyncManagerTest
, UnregisterSecond
) {
375 EXPECT_TRUE(Register(sync_reg_1_
));
376 EXPECT_TRUE(Register(sync_reg_2_
));
377 EXPECT_TRUE(Unregister(callback_registration_
));
378 EXPECT_TRUE(GetRegistration(sync_reg_1_
.name
));
379 EXPECT_TRUE(Register(sync_reg_2_
));
382 TEST_F(BackgroundSyncManagerTest
, UnregisterBadBackend
) {
383 TestBackgroundSyncManager
* manager
= UseTestBackgroundSyncManager();
384 sync_reg_1_
.min_period
+= 1;
385 EXPECT_TRUE(Register(sync_reg_1_
));
386 manager
->set_corrupt_backend(true);
387 EXPECT_FALSE(Unregister(callback_registration_
));
388 manager
->set_corrupt_backend(false);
389 EXPECT_TRUE(GetRegistration(sync_reg_1_
.name
));
390 EXPECT_TRUE(callback_registration_
.Equals(sync_reg_1_
));
393 TEST_F(BackgroundSyncManagerTest
, RegistrationIncreasesId
) {
394 EXPECT_TRUE(Register(sync_reg_1_
));
395 BackgroundSyncManager::BackgroundSyncRegistration registered_sync
=
396 callback_registration_
;
397 BackgroundSyncManager::BackgroundSyncRegistration::RegistrationId cur_id
=
398 callback_registration_
.id
;
400 EXPECT_TRUE(GetRegistration(sync_reg_1_
.name
));
401 EXPECT_TRUE(Register(sync_reg_2_
));
402 EXPECT_LT(cur_id
, callback_registration_
.id
);
403 cur_id
= callback_registration_
.id
;
405 EXPECT_TRUE(Unregister(registered_sync
));
406 EXPECT_TRUE(Register(sync_reg_1_
));
407 EXPECT_LT(cur_id
, callback_registration_
.id
);
410 TEST_F(BackgroundSyncManagerTest
, RebootRecovery
) {
411 EXPECT_TRUE(Register(sync_reg_1_
));
413 background_sync_manager_
=
414 BackgroundSyncManager::Create(service_worker_context_
);
416 EXPECT_TRUE(GetRegistration(sync_reg_1_
.name
));
417 EXPECT_FALSE(GetRegistration(sync_reg_2_
.name
));
420 TEST_F(BackgroundSyncManagerTest
, RebootRecoveryTwoServiceWorkers
) {
421 EXPECT_TRUE(RegisterWithServiceWorkerId(kServiceWorkerId1
, sync_reg_1_
));
422 EXPECT_TRUE(RegisterWithServiceWorkerId(kServiceWorkerId2
, sync_reg_2_
));
424 background_sync_manager_
=
425 BackgroundSyncManager::Create(service_worker_context_
);
428 GetRegistrationWithServiceWorkerId(kServiceWorkerId1
, sync_reg_1_
.name
));
430 GetRegistrationWithServiceWorkerId(kServiceWorkerId1
, sync_reg_2_
.name
));
432 GetRegistrationWithServiceWorkerId(kServiceWorkerId2
, sync_reg_1_
.name
));
434 GetRegistrationWithServiceWorkerId(kServiceWorkerId2
, sync_reg_2_
.name
));
437 GetRegistrationWithServiceWorkerId(kServiceWorkerId1
, sync_reg_1_
.name
));
439 GetRegistrationWithServiceWorkerId(kServiceWorkerId2
, sync_reg_2_
.name
));
441 EXPECT_TRUE(RegisterWithServiceWorkerId(kServiceWorkerId1
, sync_reg_2_
));
442 EXPECT_TRUE(RegisterWithServiceWorkerId(kServiceWorkerId2
, sync_reg_1_
));
445 TEST_F(BackgroundSyncManagerTest
, InitWithCorruptBackend
) {
446 TestBackgroundSyncManager
* manager
=
447 new TestBackgroundSyncManager(service_worker_context_
);
448 background_sync_manager_
.reset(manager
);
449 manager
->set_corrupt_backend(true);
452 EXPECT_FALSE(Register(sync_reg_1_
));
453 EXPECT_FALSE(GetRegistration(sync_reg_1_
.name
));
456 TEST_F(BackgroundSyncManagerTest
, SequentialOperations
) {
457 // Schedule Init and all of the operations on a delayed backend. Verify that
458 // the operations complete sequentially.
459 TestBackgroundSyncManager
* manager
=
460 new TestBackgroundSyncManager(service_worker_context_
);
461 background_sync_manager_
.reset(manager
);
462 manager
->set_delay_backend(true);
465 const int64 kExpectedInitialId
=
466 BackgroundSyncManager::BackgroundSyncRegistrations::kInitialId
;
468 bool register_called
= false;
469 bool unregister_called
= false;
470 bool get_registration_called
= false;
472 origin_
, kServiceWorkerId1
, sync_reg_1_
,
473 base::Bind(&BackgroundSyncManagerTest::StatusAndRegistrationCallback
,
474 base::Unretained(this), ®ister_called
));
475 manager
->Unregister(origin_
, kServiceWorkerId1
, sync_reg_1_
.name
,
477 base::Bind(&BackgroundSyncManagerTest::StatusCallback
,
478 base::Unretained(this), &unregister_called
));
479 manager
->GetRegistration(
480 origin_
, kServiceWorkerId1
, sync_reg_1_
.name
,
481 base::Bind(&BackgroundSyncManagerTest::StatusAndRegistrationCallback
,
482 base::Unretained(this), &get_registration_called
));
484 base::RunLoop().RunUntilIdle();
485 // Init should be blocked while loading from the backend.
486 EXPECT_FALSE(register_called
);
487 EXPECT_FALSE(unregister_called
);
488 EXPECT_FALSE(get_registration_called
);
491 base::RunLoop().RunUntilIdle();
492 // Register should be blocked while storing to the backend.
493 EXPECT_FALSE(register_called
);
494 EXPECT_FALSE(unregister_called
);
495 EXPECT_FALSE(get_registration_called
);
498 base::RunLoop().RunUntilIdle();
499 EXPECT_TRUE(register_called
);
500 EXPECT_EQ(kExpectedInitialId
, callback_registration_
.id
);
501 EXPECT_EQ(BackgroundSyncManager::ERROR_TYPE_OK
, callback_error_
);
502 // Unregister should be blocked while storing to the backend.
503 EXPECT_FALSE(unregister_called
);
504 EXPECT_FALSE(get_registration_called
);
507 base::RunLoop().RunUntilIdle();
508 // Unregister should be done and since GetRegistration doesn't require the
509 // backend it should be done too.
510 EXPECT_EQ(BackgroundSyncManager::ERROR_TYPE_NOT_FOUND
, callback_error_
);
511 EXPECT_TRUE(unregister_called
);
512 EXPECT_TRUE(get_registration_called
);
515 } // namespace content