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 ErrorCallback(bool* called
,
63 BackgroundSyncError
* out_error
,
64 BackgroundSyncError error
) {
69 void ErrorAndRegistrationListCallback(
71 BackgroundSyncError
* out_error
,
72 unsigned long* out_array_size
,
73 BackgroundSyncError error
,
74 mojo::Array
<content::SyncRegistrationPtr
> registrations
) {
77 if (error
== BackgroundSyncError::BACKGROUND_SYNC_ERROR_NONE
)
78 *out_array_size
= registrations
.size();
81 class MockPowerMonitorSource
: public base::PowerMonitorSource
{
83 // PowerMonitorSource overrides.
84 bool IsOnBatteryPowerImpl() final
{ return false; }
89 class BackgroundSyncServiceImplTest
: public testing::Test
{
91 BackgroundSyncServiceImplTest()
93 new TestBrowserThreadBundle(TestBrowserThreadBundle::IO_MAINLOOP
)),
94 network_change_notifier_(net::NetworkChangeNotifier::CreateMock()) {
95 default_sync_registration_
= SyncRegistration::New();
98 void SetUp() override
{
100 CreateBackgroundSyncContext();
101 CreateServiceWorkerRegistration();
102 CreateBackgroundSyncServiceImpl();
105 void TearDown() override
{
106 // This must be explicitly destroyed here to ensure that destruction
107 // of both the BackgroundSyncContext and the BackgroundSyncManager occurs on
108 // the correct thread.
109 background_sync_context_
->Shutdown();
110 base::RunLoop().RunUntilIdle();
111 background_sync_context_
= nullptr;
114 // SetUp helper methods
115 void CreateTestHelper() {
116 embedded_worker_helper_
.reset(
117 new EmbeddedWorkerTestHelper(base::FilePath(), kRenderProcessId
));
120 void CreateBackgroundSyncContext() {
121 power_monitor_
.reset(
122 new base::PowerMonitor(make_scoped_ptr(new MockPowerMonitorSource())));
124 background_sync_context_
= new BackgroundSyncContextImpl();
125 background_sync_context_
->Init(embedded_worker_helper_
->context_wrapper());
127 // Tests do not expect the sync event to fire immediately after
128 // register (and cleanup up the sync registrations). Prevent the sync
129 // event from firing by setting the network state to have no connection.
130 // NOTE: The setup of the network connection must happen after the
131 // BackgroundSyncManager has been setup, including any asynchronous
133 base::RunLoop().RunUntilIdle();
134 net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
135 net::NetworkChangeNotifier::CONNECTION_NONE
);
136 base::RunLoop().RunUntilIdle();
139 void CreateServiceWorkerRegistration() {
141 embedded_worker_helper_
->context()->RegisterServiceWorker(
142 GURL(kServiceWorkerPattern
), GURL(kServiceWorkerScript
), NULL
,
143 base::Bind(&RegisterServiceWorkerCallback
, &called
,
144 &sw_registration_id_
));
145 base::RunLoop().RunUntilIdle();
148 // Register window client for the service worker
149 provider_host_
.reset(new ServiceWorkerProviderHost(
150 34 /* dummy render proces id */, MSG_ROUTING_NONE
/* render_frame_id */,
151 1 /* dummy provider id */, SERVICE_WORKER_PROVIDER_FOR_WINDOW
,
152 embedded_worker_helper_
->context()->AsWeakPtr(), nullptr));
153 provider_host_
->SetDocumentUrl(GURL(kServiceWorkerPattern
));
155 embedded_worker_helper_
->context_wrapper()->FindRegistrationForId(
156 sw_registration_id_
, GURL(kServiceWorkerPattern
).GetOrigin(),
157 base::Bind(FindServiceWorkerRegistrationCallback
, &sw_registration_
));
158 base::RunLoop().RunUntilIdle();
159 EXPECT_TRUE(sw_registration_
);
161 sw_registration_
->active_version()->AddControllee(provider_host_
.get());
164 void RemoveWindowClient() {
165 sw_registration_
->active_version()->RemoveControllee(provider_host_
.get());
168 void CreateBackgroundSyncServiceImpl() {
169 // Create a dummy mojo channel so that the BackgroundSyncServiceImpl can be
171 mojo::InterfaceRequest
<BackgroundSyncService
> service_request
=
172 mojo::GetProxy(&service_ptr_
);
173 // Create a new BackgroundSyncServiceImpl bound to the dummy channel
174 service_impl_
.reset(new BackgroundSyncServiceImpl(
175 background_sync_context_
.get(), service_request
.Pass()));
176 base::RunLoop().RunUntilIdle();
179 // Helpers for testing BackgroundSyncServiceImpl methods
180 void RegisterOneShot(
181 SyncRegistrationPtr sync
,
182 const BackgroundSyncService::RegisterCallback
& callback
) {
183 service_impl_
->Register(sync
.Pass(), sw_registration_id_
,
184 true /* requested_from_service_worker */, callback
);
185 base::RunLoop().RunUntilIdle();
188 void RegisterOneShotFromDocument(
189 SyncRegistrationPtr sync
,
190 const BackgroundSyncService::RegisterCallback
& callback
) {
191 service_impl_
->Register(sync
.Pass(), sw_registration_id_
,
192 false /* requested_from_service_worker */,
194 base::RunLoop().RunUntilIdle();
197 void UnregisterOneShot(
198 SyncRegistrationPtr sync
,
199 const BackgroundSyncService::UnregisterCallback
& callback
) {
200 service_impl_
->Unregister(
201 BackgroundSyncPeriodicity::BACKGROUND_SYNC_PERIODICITY_ONE_SHOT
,
202 sync
->id
, sync
->tag
, sw_registration_id_
, callback
);
203 base::RunLoop().RunUntilIdle();
206 void GetRegistrationOneShot(
207 const mojo::String
& tag
,
208 const BackgroundSyncService::RegisterCallback
& callback
) {
209 service_impl_
->GetRegistration(
210 BackgroundSyncPeriodicity::BACKGROUND_SYNC_PERIODICITY_ONE_SHOT
, tag
,
211 sw_registration_id_
, callback
);
212 base::RunLoop().RunUntilIdle();
215 void GetRegistrationsOneShot(
216 const BackgroundSyncService::GetRegistrationsCallback
& callback
) {
217 service_impl_
->GetRegistrations(
218 BackgroundSyncPeriodicity::BACKGROUND_SYNC_PERIODICITY_ONE_SHOT
,
219 sw_registration_id_
, callback
);
220 base::RunLoop().RunUntilIdle();
223 scoped_ptr
<TestBrowserThreadBundle
> thread_bundle_
;
224 scoped_ptr
<net::NetworkChangeNotifier
> network_change_notifier_
;
225 scoped_ptr
<EmbeddedWorkerTestHelper
> embedded_worker_helper_
;
226 scoped_ptr
<base::PowerMonitor
> power_monitor_
;
227 scoped_refptr
<BackgroundSyncContextImpl
> background_sync_context_
;
228 scoped_ptr
<ServiceWorkerProviderHost
> provider_host_
;
229 int64 sw_registration_id_
;
230 scoped_refptr
<ServiceWorkerRegistration
> sw_registration_
;
231 BackgroundSyncServicePtr service_ptr_
;
232 scoped_ptr
<BackgroundSyncServiceImpl
> service_impl_
;
233 SyncRegistrationPtr default_sync_registration_
;
238 TEST_F(BackgroundSyncServiceImplTest
, Register
) {
240 BackgroundSyncError error
;
241 SyncRegistrationPtr reg
;
243 default_sync_registration_
.Clone(),
244 base::Bind(&ErrorAndRegistrationCallback
, &called
, &error
, ®
));
246 EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NONE
, error
);
247 EXPECT_EQ("", reg
->tag
);
250 TEST_F(BackgroundSyncServiceImplTest
, RegisterWithoutWindow
) {
252 BackgroundSyncError error
;
253 SyncRegistrationPtr reg
;
254 RemoveWindowClient();
256 default_sync_registration_
.Clone(),
257 base::Bind(&ErrorAndRegistrationCallback
, &called
, &error
, ®
));
259 EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NOT_ALLOWED
, error
);
262 TEST_F(BackgroundSyncServiceImplTest
, RegisterFromControlledClient
) {
264 BackgroundSyncError error
;
265 SyncRegistrationPtr reg
;
266 RegisterOneShotFromDocument(
267 default_sync_registration_
.Clone(),
268 base::Bind(&ErrorAndRegistrationCallback
, &called
, &error
, ®
));
270 EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NONE
, error
);
271 EXPECT_EQ("", reg
->tag
);
274 TEST_F(BackgroundSyncServiceImplTest
, RegisterFromUncontrolledClient
) {
276 BackgroundSyncError error
;
277 SyncRegistrationPtr reg
;
278 RemoveWindowClient();
279 RegisterOneShotFromDocument(
280 default_sync_registration_
.Clone(),
281 base::Bind(&ErrorAndRegistrationCallback
, &called
, &error
, ®
));
283 EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NONE
, error
);
284 EXPECT_EQ("", reg
->tag
);
287 TEST_F(BackgroundSyncServiceImplTest
, Unregister
) {
288 bool unregister_called
= false;
289 BackgroundSyncError unregister_error
;
290 SyncRegistrationPtr reg
;
292 default_sync_registration_
.Clone(),
293 base::Bind(&ErrorCallback
, &unregister_called
, &unregister_error
));
294 EXPECT_TRUE(unregister_called
);
295 EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NOT_FOUND
,
299 TEST_F(BackgroundSyncServiceImplTest
, UnregisterWithRegisteredSync
) {
300 bool register_called
= false;
301 bool unregister_called
= false;
302 BackgroundSyncError register_error
;
303 BackgroundSyncError unregister_error
;
304 SyncRegistrationPtr reg
;
305 RegisterOneShot(default_sync_registration_
.Clone(),
306 base::Bind(&ErrorAndRegistrationCallback
, ®ister_called
,
307 ®ister_error
, ®
));
308 EXPECT_TRUE(register_called
);
309 EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NONE
, register_error
);
310 UnregisterOneShot(reg
.Pass(), base::Bind(&ErrorCallback
, &unregister_called
,
312 EXPECT_TRUE(unregister_called
);
313 EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NONE
, unregister_error
);
316 TEST_F(BackgroundSyncServiceImplTest
, GetRegistration
) {
318 BackgroundSyncError error
;
319 SyncRegistrationPtr reg
;
320 GetRegistrationOneShot(
321 "", base::Bind(&ErrorAndRegistrationCallback
, &called
, &error
, ®
));
323 EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NOT_FOUND
, error
);
326 TEST_F(BackgroundSyncServiceImplTest
, GetRegistrationWithRegisteredSync
) {
327 bool register_called
= false;
328 bool getregistration_called
= false;
329 BackgroundSyncError register_error
;
330 BackgroundSyncError getregistration_error
;
331 SyncRegistrationPtr register_reg
;
332 SyncRegistrationPtr getregistration_reg
;
333 RegisterOneShot(default_sync_registration_
.Clone(),
334 base::Bind(&ErrorAndRegistrationCallback
, ®ister_called
,
335 ®ister_error
, ®ister_reg
));
336 EXPECT_TRUE(register_called
);
337 EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NONE
, register_error
);
338 GetRegistrationOneShot(
340 base::Bind(&ErrorAndRegistrationCallback
, &getregistration_called
,
341 &getregistration_error
, &getregistration_reg
));
342 EXPECT_TRUE(getregistration_called
);
343 EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NONE
,
344 getregistration_error
);
347 TEST_F(BackgroundSyncServiceImplTest
, GetRegistrations
) {
349 BackgroundSyncError error
;
350 unsigned long array_size
= 0UL;
351 GetRegistrationsOneShot(base::Bind(&ErrorAndRegistrationListCallback
, &called
,
352 &error
, &array_size
));
354 EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NONE
, error
);
355 EXPECT_EQ(0UL, array_size
);
358 TEST_F(BackgroundSyncServiceImplTest
, GetRegistrationsWithRegisteredSync
) {
359 bool register_called
= false;
360 bool getregistrations_called
= false;
361 BackgroundSyncError register_error
;
362 BackgroundSyncError getregistrations_error
;
363 SyncRegistrationPtr register_reg
;
364 unsigned long array_size
= 0UL;
365 RegisterOneShot(default_sync_registration_
.Clone(),
366 base::Bind(&ErrorAndRegistrationCallback
, ®ister_called
,
367 ®ister_error
, ®ister_reg
));
368 EXPECT_TRUE(register_called
);
369 EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NONE
, register_error
);
370 GetRegistrationsOneShot(base::Bind(&ErrorAndRegistrationListCallback
,
371 &getregistrations_called
,
372 &getregistrations_error
, &array_size
));
373 EXPECT_TRUE(getregistrations_called
);
374 EXPECT_EQ(BackgroundSyncError::BACKGROUND_SYNC_ERROR_NONE
,
375 getregistrations_error
);
376 EXPECT_EQ(1UL, array_size
);
379 } // namespace content