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.
9 #include "base/command_line.h"
10 #include "base/strings/string_split.h"
11 #include "base/strings/stringprintf.h"
12 #include "base/task_runner_util.h"
13 #include "content/browser/background_sync/background_sync_manager.h"
14 #include "content/browser/background_sync/background_sync_registration_handle.h"
15 #include "content/browser/background_sync/background_sync_status.h"
16 #include "content/browser/service_worker/service_worker_context_wrapper.h"
17 #include "content/browser/service_worker/service_worker_registration.h"
18 #include "content/public/browser/background_sync_context.h"
19 #include "content/public/browser/browser_context.h"
20 #include "content/public/browser/storage_partition.h"
21 #include "content/public/browser/web_contents.h"
22 #include "content/public/common/content_switches.h"
23 #include "content/public/test/browser_test_utils.h"
24 #include "content/public/test/content_browser_test.h"
25 #include "content/public/test/content_browser_test_utils.h"
26 #include "content/public/test/test_utils.h"
27 #include "content/shell/browser/shell.h"
28 #include "net/base/network_change_notifier.h"
29 #include "testing/gtest/include/gtest/gtest.h"
31 using net::NetworkChangeNotifier
;
37 const char kDefaultTestURL
[] = "files/background_sync/test.html";
39 const char kSuccessfulOperationPrefix
[] = "ok - ";
41 std::string
BuildScriptString(const std::string
& function
,
42 const std::string
& argument
) {
43 return base::StringPrintf("%s('%s');", function
.c_str(), argument
.c_str());
46 std::string
BuildExpectedResult(const std::string
& tag
,
47 const std::string
& action
) {
48 return base::StringPrintf("%s%s %s", kSuccessfulOperationPrefix
, tag
.c_str(),
52 void OneShotPendingCallback(
53 const base::Closure
& quit
,
54 const scoped_refptr
<base::SingleThreadTaskRunner
>& task_runner
,
58 task_runner
->PostTask(FROM_HERE
, quit
);
61 void OneShotPendingDidGetSyncRegistration(
62 const base::Callback
<void(bool)>& callback
,
63 BackgroundSyncStatus error_type
,
64 scoped_ptr
<BackgroundSyncRegistrationHandle
> registration_handle
) {
65 ASSERT_EQ(BACKGROUND_SYNC_STATUS_OK
, error_type
);
66 callback
.Run(registration_handle
->sync_state() ==
67 BACKGROUND_SYNC_STATE_PENDING
);
70 void OneShotPendingDidGetSWRegistration(
71 const scoped_refptr
<BackgroundSyncContext
> sync_context
,
72 const std::string
& tag
,
73 const base::Callback
<void(bool)>& callback
,
74 ServiceWorkerStatusCode status
,
75 const scoped_refptr
<ServiceWorkerRegistration
>& registration
) {
76 ASSERT_EQ(SERVICE_WORKER_OK
, status
);
77 int64 service_worker_id
= registration
->id();
78 BackgroundSyncManager
* sync_manager
= sync_context
->background_sync_manager();
79 sync_manager
->GetRegistration(
80 service_worker_id
, tag
, SYNC_ONE_SHOT
,
81 base::Bind(&OneShotPendingDidGetSyncRegistration
, callback
));
84 void OneShotPendingOnIOThread(
85 const scoped_refptr
<BackgroundSyncContext
> sync_context
,
86 const scoped_refptr
<ServiceWorkerContextWrapper
> sw_context
,
87 const std::string
& tag
,
89 const base::Callback
<void(bool)>& callback
) {
90 sw_context
->FindRegistrationForDocument(
91 url
, base::Bind(&OneShotPendingDidGetSWRegistration
, sync_context
, tag
,
95 class BackgroundSyncBrowserTest
: public ContentBrowserTest
{
97 BackgroundSyncBrowserTest() {}
98 ~BackgroundSyncBrowserTest() override
{}
100 void SetUp() override
{
101 NetworkChangeNotifier::SetTestNotificationsOnly(true);
103 #if defined(OS_CHROMEOS)
104 // ChromeOS's NetworkChangeNotifier doesn't get created in
105 // content_browsertests, so make one now.
106 net::NetworkChangeNotifier::CreateMock();
109 ContentBrowserTest::SetUp();
112 void SetIncognitoMode(bool incognito
) {
113 shell_
= incognito
? CreateOffTheRecordBrowser() : shell();
116 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
117 // TODO(jkarlin): Remove this once background sync is no longer
119 command_line
->AppendSwitch(
120 switches::kEnableExperimentalWebPlatformFeatures
);
123 void SetUpOnMainThread() override
{
124 https_server_
.reset(new net::SpawnedTestServer(
125 net::SpawnedTestServer::TYPE_HTTPS
,
126 net::BaseTestServer::SSLOptions(
127 net::BaseTestServer::SSLOptions::CERT_OK
),
128 base::FilePath(FILE_PATH_LITERAL("content/test/data/"))));
129 ASSERT_TRUE(https_server_
->Start());
133 SetIncognitoMode(false);
135 ASSERT_TRUE(LoadTestPage(kDefaultTestURL
));
137 ContentBrowserTest::SetUpOnMainThread();
140 void TearDownOnMainThread() override
{ https_server_
.reset(); }
142 bool LoadTestPage(const std::string
& path
) {
143 return NavigateToURL(shell_
, https_server_
->GetURL(path
));
146 bool RunScript(const std::string
& script
, std::string
* result
) {
147 return content::ExecuteScriptAndExtractString(shell_
->web_contents(),
151 void SetOnline(bool online
);
153 // Returns true if the one-shot sync with tag is currently pending. Fails
154 // (assertion failure) if the tag isn't registered.
155 bool OneShotPending(const std::string
& tag
);
157 bool PopConsole(const std::string
& expected_msg
);
158 bool RegisterServiceWorker();
159 bool RegisterOneShot(const std::string
& tag
);
160 bool UnregisterOneShot(const std::string
& tag
);
161 bool UnregisterOneShotTwice(const std::string
& tag
);
162 bool GetRegistrationOneShot(const std::string
& tag
);
163 bool GetRegistrationsOneShot(const std::vector
<std::string
>& expected_tags
);
164 bool CompleteDelayedOneShot();
165 bool RejectDelayedOneShot();
166 bool NotifyWhenDoneOneShot(const std::string
& tag
);
167 bool NotifyWhenDoneImmediateOneShot(const std::string
& expected_msg
);
168 bool StoreRegistrationOneShot(const std::string
& tag
);
171 scoped_ptr
<net::SpawnedTestServer
> https_server_
;
172 Shell
* shell_
= nullptr;
174 DISALLOW_COPY_AND_ASSIGN(BackgroundSyncBrowserTest
);
177 void BackgroundSyncBrowserTest::SetOnline(bool online
) {
179 NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
180 NetworkChangeNotifier::CONNECTION_WIFI
);
182 NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
183 NetworkChangeNotifier::CONNECTION_NONE
);
185 base::RunLoop().RunUntilIdle();
188 bool BackgroundSyncBrowserTest::OneShotPending(const std::string
& tag
) {
190 base::RunLoop run_loop
;
192 StoragePartition
* storage
= BrowserContext::GetDefaultStoragePartition(
193 shell_
->web_contents()->GetBrowserContext());
194 BackgroundSyncContext
* sync_context
= storage
->GetBackgroundSyncContext();
195 ServiceWorkerContextWrapper
* service_worker_context
=
196 static_cast<ServiceWorkerContextWrapper
*>(
197 storage
->GetServiceWorkerContext());
199 base::Callback
<void(bool)> callback
=
200 base::Bind(&OneShotPendingCallback
, run_loop
.QuitClosure(),
201 base::ThreadTaskRunnerHandle::Get(), &is_pending
);
203 BrowserThread::PostTask(
204 BrowserThread::IO
, FROM_HERE
,
205 base::Bind(&OneShotPendingOnIOThread
, make_scoped_refptr(sync_context
),
206 make_scoped_refptr(service_worker_context
), tag
,
207 https_server_
->GetURL(kDefaultTestURL
), callback
));
214 bool BackgroundSyncBrowserTest::PopConsole(const std::string
& expected_msg
) {
215 std::string script_result
;
216 EXPECT_TRUE(RunScript("resultQueue.pop()", &script_result
));
217 return script_result
== expected_msg
;
220 bool BackgroundSyncBrowserTest::RegisterServiceWorker() {
221 std::string script_result
;
222 EXPECT_TRUE(RunScript("registerServiceWorker()", &script_result
));
223 return script_result
== BuildExpectedResult("service worker", "registered");
226 bool BackgroundSyncBrowserTest::RegisterOneShot(const std::string
& tag
) {
227 std::string script_result
;
229 RunScript(BuildScriptString("registerOneShot", tag
), &script_result
));
230 return script_result
== BuildExpectedResult(tag
, "registered");
233 bool BackgroundSyncBrowserTest::UnregisterOneShot(const std::string
& tag
) {
234 std::string script_result
;
236 RunScript(BuildScriptString("unregisterOneShot", tag
), &script_result
));
237 return script_result
== BuildExpectedResult(tag
, "unregistered");
240 bool BackgroundSyncBrowserTest::UnregisterOneShotTwice(const std::string
& tag
) {
241 std::string script_result
;
242 EXPECT_TRUE(RunScript(BuildScriptString("unregisterOneShotTwice", tag
),
244 return script_result
==
245 BuildExpectedResult(tag
, "failed to unregister twice");
248 bool BackgroundSyncBrowserTest::GetRegistrationOneShot(const std::string
& tag
) {
249 std::string script_result
;
250 EXPECT_TRUE(RunScript(BuildScriptString("getRegistrationOneShot", tag
),
252 return script_result
== BuildExpectedResult(tag
, "found");
255 bool BackgroundSyncBrowserTest::GetRegistrationsOneShot(
256 const std::vector
<std::string
>& expected_tags
) {
257 std::string script_result
;
258 EXPECT_TRUE(RunScript("getRegistrationsOneShot()", &script_result
));
260 EXPECT_TRUE(base::StartsWith(script_result
, kSuccessfulOperationPrefix
,
261 base::CompareCase::INSENSITIVE_ASCII
));
262 script_result
= script_result
.substr(strlen(kSuccessfulOperationPrefix
));
263 std::vector
<std::string
> result_tags
= base::SplitString(
264 script_result
, ",", base::KEEP_WHITESPACE
, base::SPLIT_WANT_ALL
);
266 return std::set
<std::string
>(expected_tags
.begin(), expected_tags
.end()) ==
267 std::set
<std::string
>(result_tags
.begin(), result_tags
.end());
270 bool BackgroundSyncBrowserTest::CompleteDelayedOneShot() {
271 std::string script_result
;
272 EXPECT_TRUE(RunScript("completeDelayedOneShot()", &script_result
));
273 return script_result
== BuildExpectedResult("delay", "completing");
276 bool BackgroundSyncBrowserTest::RejectDelayedOneShot() {
277 std::string script_result
;
278 EXPECT_TRUE(RunScript("rejectDelayedOneShot()", &script_result
));
279 return script_result
== BuildExpectedResult("delay", "rejecting");
282 bool BackgroundSyncBrowserTest::NotifyWhenDoneOneShot(const std::string
& tag
) {
283 EXPECT_TRUE(content::ExecuteScript(
284 shell_
->web_contents(), BuildScriptString("notifyWhenDoneOneShot", tag
)));
285 return PopConsole(BuildExpectedResult(tag
, "done"));
288 bool BackgroundSyncBrowserTest::NotifyWhenDoneImmediateOneShot(
289 const std::string
& expected_msg
) {
290 std::string script_result
;
291 EXPECT_TRUE(RunScript("notifyWhenDoneImmediateOneShot()", &script_result
));
292 return script_result
== expected_msg
;
295 bool BackgroundSyncBrowserTest::StoreRegistrationOneShot(
296 const std::string
& tag
) {
297 std::string script_result
;
299 RunScript(BuildScriptString("storeRegistration", tag
), &script_result
));
300 return script_result
== BuildExpectedResult(tag
, "stored");
303 IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest
, OneShotFires
) {
304 EXPECT_TRUE(RegisterServiceWorker());
305 EXPECT_TRUE(LoadTestPage(kDefaultTestURL
)); // Control the page.
307 EXPECT_TRUE(RegisterOneShot("foo"));
308 EXPECT_TRUE(PopConsole("foo fired"));
309 EXPECT_FALSE(GetRegistrationOneShot("foo"));
312 IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest
, OneShotDelaysForNetwork
) {
313 EXPECT_TRUE(RegisterServiceWorker());
314 EXPECT_TRUE(LoadTestPage(kDefaultTestURL
)); // Control the page.
316 // Prevent firing by going offline.
318 EXPECT_TRUE(RegisterOneShot("foo"));
319 EXPECT_TRUE(GetRegistrationOneShot("foo"));
320 EXPECT_TRUE(OneShotPending("foo"));
322 // Resume firing by going online.
324 EXPECT_TRUE(PopConsole("foo fired"));
325 EXPECT_FALSE(GetRegistrationOneShot("foo"));
328 IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest
, WaitUntil
) {
329 EXPECT_TRUE(RegisterServiceWorker());
330 EXPECT_TRUE(LoadTestPage(kDefaultTestURL
)); // Control the page.
333 EXPECT_TRUE(RegisterOneShot("delay"));
335 // Verify that it is firing.
336 EXPECT_TRUE(GetRegistrationOneShot("delay"));
337 EXPECT_FALSE(OneShotPending("delay"));
339 // Complete the task.
340 EXPECT_TRUE(CompleteDelayedOneShot());
341 EXPECT_TRUE(PopConsole("ok - delay completed"));
343 // Verify that it finished firing.
344 // TODO(jkarlin): Use registration.done to verify that the event actually
345 // completed successfully.
346 EXPECT_FALSE(GetRegistrationOneShot("delay"));
349 IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest
, WaitUntilReject
) {
350 EXPECT_TRUE(RegisterServiceWorker());
351 EXPECT_TRUE(LoadTestPage(kDefaultTestURL
)); // Control the page.
354 EXPECT_TRUE(RegisterOneShot("delay"));
356 // Verify that it is firing.
357 EXPECT_TRUE(GetRegistrationOneShot("delay"));
358 EXPECT_FALSE(OneShotPending("delay"));
360 // Complete the task.
361 EXPECT_TRUE(RejectDelayedOneShot());
362 EXPECT_TRUE(PopConsole("ok - delay rejected"));
364 // Since the event failed the registration should still be there.
365 // TODO(jkarlin): Use registration.done to verify that the event actually
367 EXPECT_TRUE(GetRegistrationOneShot("delay"));
370 IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest
, Incognito
) {
371 EXPECT_TRUE(RegisterServiceWorker());
372 EXPECT_TRUE(LoadTestPage(kDefaultTestURL
)); // Control the page.
375 EXPECT_TRUE(RegisterOneShot("normal"));
376 EXPECT_TRUE(OneShotPending("normal"));
378 // Go incognito and verify that incognito doesn't see the registration.
379 SetIncognitoMode(true);
381 // Tell the new network observer that we're offline (it initializes from
382 // NetworkChangeNotifier::GetCurrentConnectionType() which is not mocked out
386 EXPECT_TRUE(LoadTestPage(kDefaultTestURL
));
387 EXPECT_TRUE(RegisterServiceWorker());
388 EXPECT_TRUE(LoadTestPage(kDefaultTestURL
)); // Control the page.
390 EXPECT_FALSE(GetRegistrationOneShot("normal"));
392 EXPECT_TRUE(RegisterOneShot("incognito"));
393 EXPECT_TRUE(OneShotPending("incognito"));
395 // Switch back and make sure the registration is still there.
396 SetIncognitoMode(false);
397 EXPECT_TRUE(LoadTestPage(kDefaultTestURL
)); // Should be controlled.
399 EXPECT_TRUE(GetRegistrationOneShot("normal"));
400 EXPECT_FALSE(GetRegistrationOneShot("incognito"));
403 IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest
, GetRegistrations
) {
404 EXPECT_TRUE(RegisterServiceWorker());
405 EXPECT_TRUE(LoadTestPage(kDefaultTestURL
)); // Control the page.
407 std::vector
<std::string
> registered_tags
;
408 EXPECT_TRUE(GetRegistrationsOneShot(registered_tags
));
411 registered_tags
.push_back("foo");
412 registered_tags
.push_back("bar");
414 for (const std::string
& tag
: registered_tags
)
415 EXPECT_TRUE(RegisterOneShot(tag
));
417 EXPECT_TRUE(GetRegistrationsOneShot(registered_tags
));
420 IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest
, Unregister
) {
421 EXPECT_TRUE(RegisterServiceWorker());
422 EXPECT_TRUE(LoadTestPage(kDefaultTestURL
)); // Control the page.
425 EXPECT_TRUE(RegisterOneShot("foo"));
426 EXPECT_TRUE(UnregisterOneShot("foo"));
427 EXPECT_FALSE(GetRegistrationOneShot("foo"));
430 IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest
, UnregisterTwice
) {
431 EXPECT_TRUE(RegisterServiceWorker());
432 EXPECT_TRUE(LoadTestPage(kDefaultTestURL
)); // Control the page.
435 EXPECT_TRUE(RegisterOneShot("foo"));
436 EXPECT_TRUE(UnregisterOneShotTwice("foo"));
437 EXPECT_FALSE(GetRegistrationOneShot("foo"));
440 IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest
, UnregisterMidSync
) {
441 EXPECT_TRUE(RegisterServiceWorker());
442 EXPECT_TRUE(LoadTestPage(kDefaultTestURL
)); // Control the page.
444 EXPECT_TRUE(RegisterOneShot("unregister"));
445 EXPECT_TRUE(PopConsole("ok - unregister completed"));
448 IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest
, CallDoneBeforeSyncSucceeds
) {
449 EXPECT_TRUE(RegisterServiceWorker());
450 EXPECT_TRUE(LoadTestPage(kDefaultTestURL
)); // Control the page.
453 EXPECT_TRUE(RegisterOneShot("foo"));
454 EXPECT_TRUE(NotifyWhenDoneOneShot("foo"));
457 // The ordering of PopConsole messages tells us that the event fired
458 // before done resolved.
459 EXPECT_TRUE(PopConsole("foo fired"));
460 EXPECT_TRUE(PopConsole("foo done result: true"));
463 IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest
, CallDoneBeforeSyncFails
) {
464 EXPECT_TRUE(RegisterServiceWorker());
465 EXPECT_TRUE(LoadTestPage(kDefaultTestURL
)); // Control the page.
468 EXPECT_TRUE(RegisterOneShot("delay"));
469 EXPECT_FALSE(OneShotPending("delay"));
470 EXPECT_TRUE(NotifyWhenDoneOneShot("delay"));
472 EXPECT_TRUE(RejectDelayedOneShot());
473 // The ordering of PopConsole messages tells us that the event fired
474 // before done resolved.
475 EXPECT_TRUE(PopConsole("ok - delay rejected"));
476 EXPECT_TRUE(PopConsole("delay done result: false"));
479 IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest
, CallDoneAfterSyncSuceeds
) {
480 EXPECT_TRUE(RegisterServiceWorker());
481 EXPECT_TRUE(LoadTestPage(kDefaultTestURL
)); // Control the page.
484 EXPECT_TRUE(RegisterOneShot("foo"));
485 EXPECT_TRUE(StoreRegistrationOneShot("foo"));
488 EXPECT_TRUE(PopConsole("foo fired"));
489 EXPECT_FALSE(GetRegistrationOneShot("foo"));
490 EXPECT_TRUE(NotifyWhenDoneImmediateOneShot("ok - foo result: true"));
493 IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest
,
494 CallDoneAfterSyncUnregistered
) {
495 EXPECT_TRUE(RegisterServiceWorker());
496 EXPECT_TRUE(LoadTestPage(kDefaultTestURL
)); // Control the page.
499 EXPECT_TRUE(RegisterOneShot("foo"));
500 EXPECT_TRUE(StoreRegistrationOneShot("foo"));
501 EXPECT_TRUE(UnregisterOneShot("foo"));
502 EXPECT_FALSE(GetRegistrationOneShot("foo"));
503 EXPECT_TRUE(NotifyWhenDoneImmediateOneShot("ok - foo result: false"));
506 IN_PROC_BROWSER_TEST_F(BackgroundSyncBrowserTest
, CallDoneAfterSyncFails
) {
507 EXPECT_TRUE(RegisterServiceWorker());
508 EXPECT_TRUE(LoadTestPage(kDefaultTestURL
)); // Control the page.
511 EXPECT_TRUE(RegisterOneShot("delay"));
512 EXPECT_FALSE(OneShotPending("delay"));
513 EXPECT_TRUE(StoreRegistrationOneShot("delay"));
515 EXPECT_TRUE(RejectDelayedOneShot());
516 EXPECT_TRUE(PopConsole("ok - delay rejected"));
517 EXPECT_TRUE(NotifyWhenDoneImmediateOneShot("ok - delay result: false"));
522 } // namespace content