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_service_impl.h"
8 #include "base/bind_helpers.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/power_monitor/power_monitor.h"
11 #include "base/power_monitor/power_monitor_source.h"
12 #include "base/run_loop.h"
13 #include "content/browser/background_sync/background_sync_context_impl.h"
14 #include "content/browser/service_worker/embedded_worker_test_helper.h"
15 #include "content/browser/service_worker/service_worker_context_wrapper.h"
16 #include "content/public/browser/browser_thread.h"
17 #include "content/public/test/test_browser_thread_bundle.h"
18 #include "mojo/public/cpp/bindings/interface_ptr.h"
19 #include "net/base/network_change_notifier.h"
20 #include "testing/gtest/include/gtest/gtest.h"
26 const char kServiceWorkerPattern
[] = "https://example.com/a";
27 const char kServiceWorkerScript
[] = "https://example.com/a/script.js";
28 const int kRenderProcessId
= 99;
30 // Callbacks from SetUp methods
32 void RegisterServiceWorkerCallback(bool* called
,
33 int64
* store_registration_id
,
34 ServiceWorkerStatusCode status
,
35 const std::string
& status_message
,
36 int64 registration_id
) {
37 EXPECT_EQ(SERVICE_WORKER_OK
, status
) << ServiceWorkerStatusToString(status
);
39 *store_registration_id
= registration_id
;
42 void FindServiceWorkerRegistrationCallback(
43 scoped_refptr
<ServiceWorkerRegistration
>* out_registration
,
44 ServiceWorkerStatusCode status
,
45 const scoped_refptr
<ServiceWorkerRegistration
>& registration
) {
46 EXPECT_EQ(SERVICE_WORKER_OK
, status
) << ServiceWorkerStatusToString(status
);
47 *out_registration
= registration
;
50 // Callbacks from BackgroundSyncServiceImpl methods
52 void ErrorAndRegistrationCallback(bool* called
,
53 BackgroundSyncError
* out_error
,
54 SyncRegistrationPtr
* out_registration
,
55 BackgroundSyncError error
,
56 const SyncRegistrationPtr
& registration
) {
59 *out_registration
= registration
.Clone();
62 void ErrorAndStateCallback(bool* called
,
63 BackgroundSyncError
* out_error
,
64 BackgroundSyncState
* out_state
,
65 BackgroundSyncError error
,
66 BackgroundSyncState state
) {
72 void ErrorCallback(bool* called
,
73 BackgroundSyncError
* out_error
,
74 BackgroundSyncError error
) {
79 void ErrorAndRegistrationListCallback(
81 BackgroundSyncError
* out_error
,
82 unsigned long* out_array_size
,
83 BackgroundSyncError error
,
84 mojo::Array
<content::SyncRegistrationPtr
> registrations
) {
87 if (error
== BackgroundSyncError::BACKGROUND_SYNC_ERROR_NONE
)
88 *out_array_size
= registrations
.size();
91 class MockPowerMonitorSource
: public base::PowerMonitorSource
{
93 // PowerMonitorSource overrides.
94 bool IsOnBatteryPowerImpl() final
{ return false; }
99 class BackgroundSyncServiceImplTest
: public testing::Test
{
101 BackgroundSyncServiceImplTest()
103 new TestBrowserThreadBundle(TestBrowserThreadBundle::IO_MAINLOOP
)),
104 network_change_notifier_(net::NetworkChangeNotifier::CreateMock()) {
105 default_sync_registration_
= SyncRegistration::New();
108 void SetUp() override
{
110 CreateBackgroundSyncContext();
111 CreateServiceWorkerRegistration();
112 CreateBackgroundSyncServiceImpl();
115 void TearDown() override
{
116 // This must be explicitly destroyed here to ensure that destruction
117 // of both the BackgroundSyncContext and the BackgroundSyncManager occurs on
118 // the correct thread.
119 background_sync_context_
->Shutdown();
120 base::RunLoop().RunUntilIdle();
121 background_sync_context_
= nullptr;
124 // SetUp helper methods
125 void CreateTestHelper() {
126 embedded_worker_helper_
.reset(
127 new EmbeddedWorkerTestHelper(base::FilePath(), kRenderProcessId
));
130 void CreateBackgroundSyncContext() {
131 power_monitor_
.reset(
132 new base::PowerMonitor(make_scoped_ptr(new MockPowerMonitorSource())));
134 background_sync_context_
= new BackgroundSyncContextImpl();
135 background_sync_context_
->Init(embedded_worker_helper_
->context_wrapper());
137 // Tests do not expect the sync event to fire immediately after
138 // register (and cleanup up the sync registrations). Prevent the sync
139 // event from firing by setting the network state to have no connection.
140 // NOTE: The setup of the network connection must happen after the
141 // BackgroundSyncManager has been setup, including any asynchronous
143 base::RunLoop().RunUntilIdle();
144 net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
145 net::NetworkChangeNotifier::CONNECTION_NONE
);
146 base::RunLoop().RunUntilIdle();
149 void CreateServiceWorkerRegistration() {
151 embedded_worker_helper_
->context()->RegisterServiceWorker(
152 GURL(kServiceWorkerPattern
), GURL(kServiceWorkerScript
), NULL
,
153 base::Bind(&RegisterServiceWorkerCallback
, &called
,
154 &sw_registration_id_
));
155 base::RunLoop().RunUntilIdle();
158 // Register window client for the service worker
159 provider_host_
.reset(new ServiceWorkerProviderHost(
160 34 /* dummy render proces id */, MSG_ROUTING_NONE
/* render_frame_id */,
161 1 /* dummy provider id */, SERVICE_WORKER_PROVIDER_FOR_WINDOW
,
162 embedded_worker_helper_
->context()->AsWeakPtr(), nullptr));
163 provider_host_
->SetDocumentUrl(GURL(kServiceWorkerPattern
));
165 embedded_worker_helper_
->context_wrapper()->FindRegistrationForId(
166 sw_registration_id_
, GURL(kServiceWorkerPattern
).GetOrigin(),
167 base::Bind(FindServiceWorkerRegistrationCallback
, &sw_registration_
));
168 base::RunLoop().RunUntilIdle();
169 EXPECT_TRUE(sw_registration_
);
171 sw_registration_
->active_version()->AddControllee(provider_host_
.get());
174 void RemoveWindowClient() {
175 sw_registration_
->active_version()->RemoveControllee(provider_host_
.get());
178 void CreateBackgroundSyncServiceImpl() {
179 // Create a dummy mojo channel so that the BackgroundSyncServiceImpl can be
181 mojo::InterfaceRequest
<BackgroundSyncService
> service_request
=
182 mojo::GetProxy(&service_ptr_
);
183 // Create a new BackgroundSyncServiceImpl bound to the dummy channel
184 background_sync_context_
->CreateService(service_request
.Pass());
185 base::RunLoop().RunUntilIdle();
187 service_impl_
= *background_sync_context_
->services_
.begin();
188 ASSERT_TRUE(service_impl_
);
191 // Helpers for testing BackgroundSyncServiceImpl methods
192 void RegisterOneShot(
193 SyncRegistrationPtr sync
,
194 const BackgroundSyncService::RegisterCallback
& callback
) {
195 service_impl_
->Register(sync
.Pass(), sw_registration_id_
,
196 true /* requested_from_service_worker */, callback
);
197 base::RunLoop().RunUntilIdle();
200 void RegisterOneShotFromDocument(
201 SyncRegistrationPtr sync
,
202 const BackgroundSyncService::RegisterCallback
& callback
) {
203 service_impl_
->Register(sync
.Pass(), sw_registration_id_
,
204 false /* requested_from_service_worker */,
206 base::RunLoop().RunUntilIdle();
209 void UnregisterOneShot(
211 const BackgroundSyncService::UnregisterCallback
& callback
) {
212 service_impl_
->Unregister(
213 BackgroundSyncPeriodicity::BACKGROUND_SYNC_PERIODICITY_ONE_SHOT
,
214 handle_id
, sw_registration_id_
, callback
);
215 base::RunLoop().RunUntilIdle();
218 void GetRegistrationOneShot(
219 const mojo::String
& tag
,
220 const BackgroundSyncService::RegisterCallback
& callback
) {
221 service_impl_
->GetRegistration(
222 BackgroundSyncPeriodicity::BACKGROUND_SYNC_PERIODICITY_ONE_SHOT
, tag
,
223 sw_registration_id_
, callback
);
224 base::RunLoop().RunUntilIdle();
227 void GetRegistrationsOneShot(
228 const BackgroundSyncService::GetRegistrationsCallback
& callback
) {
229 service_impl_
->GetRegistrations(
230 BackgroundSyncPeriodicity::BACKGROUND_SYNC_PERIODICITY_ONE_SHOT
,
231 sw_registration_id_
, callback
);
232 base::RunLoop().RunUntilIdle();
237 const BackgroundSyncService::NotifyWhenDoneCallback
& callback
) {
238 service_impl_
->NotifyWhenDone(handle_id
, callback
);
239 base::RunLoop().RunUntilIdle();
242 scoped_ptr
<TestBrowserThreadBundle
> thread_bundle_
;
243 scoped_ptr
<net::NetworkChangeNotifier
> network_change_notifier_
;
244 scoped_ptr
<EmbeddedWorkerTestHelper
> embedded_worker_helper_
;
245 scoped_ptr
<base::PowerMonitor
> power_monitor_
;
246 scoped_refptr
<BackgroundSyncContextImpl
> background_sync_context_
;
247 scoped_ptr
<ServiceWorkerProviderHost
> provider_host_
;
248 int64 sw_registration_id_
;
249 scoped_refptr
<ServiceWorkerRegistration
> sw_registration_
;
250 BackgroundSyncServicePtr service_ptr_
;
251 BackgroundSyncServiceImpl
*
252 service_impl_
; // Owned by background_sync_context_
253 SyncRegistrationPtr default_sync_registration_
;
258 TEST_F(BackgroundSyncServiceImplTest
, Register
) {
260 BackgroundSyncError error
;
261 SyncRegistrationPtr reg
;
263 default_sync_registration_
.Clone(),
264 base::Bind(&ErrorAndRegistrationCallback
, &called
, &error
, ®
));
266 EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NONE
, error
);
267 EXPECT_EQ("", reg
->tag
);
270 TEST_F(BackgroundSyncServiceImplTest
, RegisterWithoutWindow
) {
272 BackgroundSyncError error
;
273 SyncRegistrationPtr reg
;
274 RemoveWindowClient();
276 default_sync_registration_
.Clone(),
277 base::Bind(&ErrorAndRegistrationCallback
, &called
, &error
, ®
));
279 EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NOT_ALLOWED
, error
);
282 TEST_F(BackgroundSyncServiceImplTest
, RegisterFromControlledClient
) {
284 BackgroundSyncError error
;
285 SyncRegistrationPtr reg
;
286 RegisterOneShotFromDocument(
287 default_sync_registration_
.Clone(),
288 base::Bind(&ErrorAndRegistrationCallback
, &called
, &error
, ®
));
290 EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NONE
, error
);
291 EXPECT_EQ("", reg
->tag
);
294 TEST_F(BackgroundSyncServiceImplTest
, RegisterFromUncontrolledClient
) {
296 BackgroundSyncError error
;
297 SyncRegistrationPtr reg
;
298 RemoveWindowClient();
299 RegisterOneShotFromDocument(
300 default_sync_registration_
.Clone(),
301 base::Bind(&ErrorAndRegistrationCallback
, &called
, &error
, ®
));
303 EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NONE
, error
);
304 EXPECT_EQ("", reg
->tag
);
307 TEST_F(BackgroundSyncServiceImplTest
, Unregister
) {
308 bool unregister_called
= false;
309 BackgroundSyncError unregister_error
;
310 SyncRegistrationPtr reg
;
312 default_sync_registration_
->handle_id
,
313 base::Bind(&ErrorCallback
, &unregister_called
, &unregister_error
));
314 EXPECT_TRUE(unregister_called
);
315 EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NOT_ALLOWED
,
319 TEST_F(BackgroundSyncServiceImplTest
, UnregisterWithRegisteredSync
) {
320 bool register_called
= false;
321 bool unregister_called
= false;
322 BackgroundSyncError register_error
;
323 BackgroundSyncError unregister_error
;
324 SyncRegistrationPtr reg
;
325 RegisterOneShot(default_sync_registration_
.Clone(),
326 base::Bind(&ErrorAndRegistrationCallback
, ®ister_called
,
327 ®ister_error
, ®
));
328 EXPECT_TRUE(register_called
);
329 EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NONE
, register_error
);
332 base::Bind(&ErrorCallback
, &unregister_called
, &unregister_error
));
333 EXPECT_TRUE(unregister_called
);
334 EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NONE
, unregister_error
);
337 TEST_F(BackgroundSyncServiceImplTest
, GetRegistration
) {
339 BackgroundSyncError error
;
340 SyncRegistrationPtr reg
;
341 GetRegistrationOneShot(
342 "", base::Bind(&ErrorAndRegistrationCallback
, &called
, &error
, ®
));
344 EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NOT_FOUND
, error
);
347 TEST_F(BackgroundSyncServiceImplTest
, GetRegistrationWithRegisteredSync
) {
348 bool register_called
= false;
349 bool getregistration_called
= false;
350 BackgroundSyncError register_error
;
351 BackgroundSyncError getregistration_error
;
352 SyncRegistrationPtr register_reg
;
353 SyncRegistrationPtr getregistration_reg
;
354 RegisterOneShot(default_sync_registration_
.Clone(),
355 base::Bind(&ErrorAndRegistrationCallback
, ®ister_called
,
356 ®ister_error
, ®ister_reg
));
357 EXPECT_TRUE(register_called
);
358 EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NONE
, register_error
);
359 GetRegistrationOneShot(
361 base::Bind(&ErrorAndRegistrationCallback
, &getregistration_called
,
362 &getregistration_error
, &getregistration_reg
));
363 EXPECT_TRUE(getregistration_called
);
364 EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NONE
,
365 getregistration_error
);
368 TEST_F(BackgroundSyncServiceImplTest
, GetRegistrations
) {
370 BackgroundSyncError error
;
371 unsigned long array_size
= 0UL;
372 GetRegistrationsOneShot(base::Bind(&ErrorAndRegistrationListCallback
, &called
,
373 &error
, &array_size
));
375 EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NONE
, error
);
376 EXPECT_EQ(0UL, array_size
);
379 TEST_F(BackgroundSyncServiceImplTest
, GetRegistrationsWithRegisteredSync
) {
380 bool register_called
= false;
381 bool getregistrations_called
= false;
382 BackgroundSyncError register_error
;
383 BackgroundSyncError getregistrations_error
;
384 SyncRegistrationPtr register_reg
;
385 unsigned long array_size
= 0UL;
386 RegisterOneShot(default_sync_registration_
.Clone(),
387 base::Bind(&ErrorAndRegistrationCallback
, ®ister_called
,
388 ®ister_error
, ®ister_reg
));
389 EXPECT_TRUE(register_called
);
390 EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NONE
, register_error
);
391 GetRegistrationsOneShot(base::Bind(&ErrorAndRegistrationListCallback
,
392 &getregistrations_called
,
393 &getregistrations_error
, &array_size
));
394 EXPECT_TRUE(getregistrations_called
);
395 EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NONE
,
396 getregistrations_error
);
397 EXPECT_EQ(1UL, array_size
);
400 TEST_F(BackgroundSyncServiceImplTest
, NotifyWhenDone
) {
401 // Register a sync event.
402 bool register_called
= false;
403 BackgroundSyncError register_error
;
404 SyncRegistrationPtr reg
;
405 RegisterOneShot(default_sync_registration_
.Clone(),
406 base::Bind(&ErrorAndRegistrationCallback
, ®ister_called
,
407 ®ister_error
, ®
));
408 EXPECT_TRUE(register_called
);
409 EXPECT_EQ(BACKGROUND_SYNC_ERROR_NONE
, register_error
);
412 bool unregister_called
= false;
413 BackgroundSyncError unregister_error
;
416 base::Bind(&ErrorCallback
, &unregister_called
, &unregister_error
));
417 EXPECT_TRUE(unregister_called
);
418 EXPECT_EQ(BACKGROUND_SYNC_ERROR_NONE
, unregister_error
);
420 // Call NotifyWhenDone and verify that it calls back with unregistered.
421 bool notify_done_called
= false;
422 BackgroundSyncError notify_done_error
= BACKGROUND_SYNC_ERROR_NONE
;
423 BackgroundSyncState notify_done_sync_state
= BACKGROUND_SYNC_STATE_SUCCESS
;
425 NotifyWhenDone(reg
->handle_id
,
426 base::Bind(&ErrorAndStateCallback
, ¬ify_done_called
,
427 ¬ify_done_error
, ¬ify_done_sync_state
));
428 EXPECT_TRUE(notify_done_called
);
429 EXPECT_EQ(BACKGROUND_SYNC_ERROR_NONE
, notify_done_error
);
430 EXPECT_EQ(BACKGROUND_SYNC_STATE_UNREGISTERED
, notify_done_sync_state
);
433 } // namespace content