1 // Copyright 2013 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.
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_core.h"
13 #include "content/browser/service_worker/service_worker_disk_cache.h"
14 #include "content/browser/service_worker/service_worker_registration.h"
15 #include "content/browser/service_worker/service_worker_storage.h"
16 #include "content/browser/service_worker/service_worker_utils.h"
17 #include "content/browser/service_worker/service_worker_version.h"
18 #include "content/common/service_worker/service_worker_status_code.h"
19 #include "content/public/test/test_browser_thread_bundle.h"
20 #include "ipc/ipc_message.h"
21 #include "net/base/io_buffer.h"
22 #include "net/base/net_errors.h"
23 #include "net/base/test_completion_callback.h"
24 #include "net/http/http_response_headers.h"
25 #include "testing/gtest/include/gtest/gtest.h"
28 using net::TestCompletionCallback
;
29 using net::WrappedIOBuffer
;
35 typedef ServiceWorkerDatabase::RegistrationData RegistrationData
;
36 typedef ServiceWorkerDatabase::ResourceRecord ResourceRecord
;
38 void StatusCallback(bool* was_called
,
39 ServiceWorkerStatusCode
* result
,
40 ServiceWorkerStatusCode status
) {
45 ServiceWorkerStorage::StatusCallback
MakeStatusCallback(
47 ServiceWorkerStatusCode
* result
) {
48 return base::Bind(&StatusCallback
, was_called
, result
);
53 ServiceWorkerStatusCode
* result
,
54 scoped_refptr
<ServiceWorkerRegistration
>* found
,
55 ServiceWorkerStatusCode status
,
56 const scoped_refptr
<ServiceWorkerRegistration
>& registration
) {
59 *found
= registration
;
62 ServiceWorkerStorage::FindRegistrationCallback
MakeFindCallback(
64 ServiceWorkerStatusCode
* result
,
65 scoped_refptr
<ServiceWorkerRegistration
>* found
) {
66 return base::Bind(&FindCallback
, was_called
, result
, found
);
71 std::vector
<scoped_refptr
<ServiceWorkerRegistration
>>* all_out
,
72 const std::vector
<scoped_refptr
<ServiceWorkerRegistration
>>& all
) {
77 void GetAllInfosCallback(
79 std::vector
<ServiceWorkerRegistrationInfo
>* all_out
,
80 const std::vector
<ServiceWorkerRegistrationInfo
>& all
) {
85 ServiceWorkerStorage::GetRegistrationsCallback
MakeGetRegistrationsCallback(
87 std::vector
<scoped_refptr
<ServiceWorkerRegistration
>>* all
) {
88 return base::Bind(&GetAllCallback
, was_called
, all
);
91 ServiceWorkerStorage::GetRegistrationsInfosCallback
92 MakeGetRegistrationsInfosCallback(
94 std::vector
<ServiceWorkerRegistrationInfo
>* all
) {
95 return base::Bind(&GetAllInfosCallback
, was_called
, all
);
98 void GetUserDataCallback(
100 std::string
* data_out
,
101 ServiceWorkerStatusCode
* status_out
,
102 const std::string
& data
,
103 ServiceWorkerStatusCode status
) {
106 *status_out
= status
;
109 void GetUserDataForAllRegistrationsCallback(
111 std::vector
<std::pair
<int64
, std::string
>>* data_out
,
112 ServiceWorkerStatusCode
* status_out
,
113 const std::vector
<std::pair
<int64
, std::string
>>& data
,
114 ServiceWorkerStatusCode status
) {
117 *status_out
= status
;
120 void OnCompareComplete(
121 ServiceWorkerStatusCode
* status_out
, bool* are_equal_out
,
122 ServiceWorkerStatusCode status
, bool are_equal
) {
123 *status_out
= status
;
124 *are_equal_out
= are_equal
;
128 ServiceWorkerStorage
* storage
, int64 id
,
129 const std::string
& headers
,
130 IOBuffer
* body
, int length
) {
131 scoped_ptr
<ServiceWorkerResponseWriter
> writer
=
132 storage
->CreateResponseWriter(id
);
134 scoped_ptr
<net::HttpResponseInfo
> info(new net::HttpResponseInfo
);
135 info
->request_time
= base::Time::Now();
136 info
->response_time
= base::Time::Now();
137 info
->was_cached
= false;
138 info
->headers
= new net::HttpResponseHeaders(headers
);
139 scoped_refptr
<HttpResponseInfoIOBuffer
> info_buffer
=
140 new HttpResponseInfoIOBuffer(info
.release());
142 TestCompletionCallback cb
;
143 writer
->WriteInfo(info_buffer
.get(), cb
.callback());
144 int rv
= cb
.WaitForResult();
148 TestCompletionCallback cb
;
149 writer
->WriteData(body
, length
, cb
.callback());
150 int rv
= cb
.WaitForResult();
151 EXPECT_EQ(length
, rv
);
155 void WriteStringResponse(
156 ServiceWorkerStorage
* storage
, int64 id
,
157 const std::string
& headers
,
158 const std::string
& body
) {
159 scoped_refptr
<IOBuffer
> body_buffer(new WrappedIOBuffer(body
.data()));
160 WriteResponse(storage
, id
, headers
, body_buffer
.get(), body
.length());
163 void WriteBasicResponse(ServiceWorkerStorage
* storage
, int64 id
) {
164 scoped_ptr
<ServiceWorkerResponseWriter
> writer
=
165 storage
->CreateResponseWriter(id
);
167 const char kHttpHeaders
[] = "HTTP/1.0 200 HONKYDORY\0Content-Length: 5\0\0";
168 const char kHttpBody
[] = "Hello";
169 std::string
headers(kHttpHeaders
, arraysize(kHttpHeaders
));
170 WriteStringResponse(storage
, id
, headers
, std::string(kHttpBody
));
173 bool VerifyBasicResponse(ServiceWorkerStorage
* storage
, int64 id
,
174 bool expected_positive_result
) {
175 const std::string
kExpectedHttpBody("Hello");
176 scoped_ptr
<ServiceWorkerResponseReader
> reader
=
177 storage
->CreateResponseReader(id
);
178 scoped_refptr
<HttpResponseInfoIOBuffer
> info_buffer
=
179 new HttpResponseInfoIOBuffer();
181 TestCompletionCallback cb
;
182 reader
->ReadInfo(info_buffer
.get(), cb
.callback());
183 int rv
= cb
.WaitForResult();
184 if (expected_positive_result
)
190 std::string received_body
;
192 const int kBigEnough
= 512;
193 scoped_refptr
<net::IOBuffer
> buffer
= new IOBuffer(kBigEnough
);
194 TestCompletionCallback cb
;
195 reader
->ReadData(buffer
.get(), kBigEnough
, cb
.callback());
196 int rv
= cb
.WaitForResult();
197 EXPECT_EQ(static_cast<int>(kExpectedHttpBody
.size()), rv
);
200 received_body
.assign(buffer
->data(), rv
);
204 std::string("HONKYDORY") ==
205 info_buffer
->http_info
->headers
->GetStatusText();
206 bool data_match
= kExpectedHttpBody
== received_body
;
208 EXPECT_TRUE(status_match
);
209 EXPECT_TRUE(data_match
);
210 return status_match
&& data_match
;
213 void WriteResponseOfSize(ServiceWorkerStorage
* storage
, int64 id
,
214 char val
, int size
) {
215 const char kHttpHeaders
[] = "HTTP/1.0 200 HONKYDORY\00";
216 std::string
headers(kHttpHeaders
, arraysize(kHttpHeaders
));
217 scoped_refptr
<net::IOBuffer
> buffer
= new net::IOBuffer(size
);
218 memset(buffer
->data(), val
, size
);
219 WriteResponse(storage
, id
, headers
, buffer
.get(), size
);
222 int WriteResponseMetadata(ServiceWorkerStorage
* storage
,
224 const std::string
& metadata
) {
225 scoped_refptr
<IOBuffer
> body_buffer(new WrappedIOBuffer(metadata
.data()));
226 scoped_ptr
<ServiceWorkerResponseMetadataWriter
> metadata_writer
=
227 storage
->CreateResponseMetadataWriter(id
);
228 TestCompletionCallback cb
;
229 metadata_writer
->WriteMetadata(body_buffer
.get(), metadata
.length(),
231 return cb
.WaitForResult();
234 int WriteMetadata(ServiceWorkerVersion
* version
,
236 const std::string
& metadata
) {
237 const std::vector
<char> data(metadata
.begin(), metadata
.end());
238 EXPECT_TRUE(version
);
239 TestCompletionCallback cb
;
240 version
->script_cache_map()->WriteMetadata(url
, data
, cb
.callback());
241 return cb
.WaitForResult();
244 int ClearMetadata(ServiceWorkerVersion
* version
, const GURL
& url
) {
245 EXPECT_TRUE(version
);
246 TestCompletionCallback cb
;
247 version
->script_cache_map()->ClearMetadata(url
, cb
.callback());
248 return cb
.WaitForResult();
251 bool VerifyResponseMetadata(ServiceWorkerStorage
* storage
,
253 const std::string
& expected_metadata
) {
254 scoped_ptr
<ServiceWorkerResponseReader
> reader
=
255 storage
->CreateResponseReader(id
);
256 scoped_refptr
<HttpResponseInfoIOBuffer
> info_buffer
=
257 new HttpResponseInfoIOBuffer();
259 TestCompletionCallback cb
;
260 reader
->ReadInfo(info_buffer
.get(), cb
.callback());
261 int rv
= cb
.WaitForResult();
264 const net::HttpResponseInfo
* read_head
= info_buffer
->http_info
.get();
265 if (!read_head
->metadata
.get())
267 EXPECT_EQ(0, memcmp(expected_metadata
.data(), read_head
->metadata
->data(),
268 expected_metadata
.length()));
274 class ServiceWorkerStorageTest
: public testing::Test
{
276 ServiceWorkerStorageTest()
277 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP
) {
280 void SetUp() override
{
281 scoped_ptr
<ServiceWorkerDatabaseTaskManager
> database_task_manager(
282 new MockServiceWorkerDatabaseTaskManager(
283 base::ThreadTaskRunnerHandle::Get()));
285 new ServiceWorkerContextCore(GetUserDataDirectory(),
286 database_task_manager
.Pass(),
287 base::ThreadTaskRunnerHandle::Get(),
292 context_ptr_
= context_
->AsWeakPtr();
295 void TearDown() override
{ context_
.reset(); }
297 virtual base::FilePath
GetUserDataDirectory() { return base::FilePath(); }
299 ServiceWorkerStorage
* storage() { return context_
->storage(); }
301 // A static class method for friendliness.
302 static void VerifyPurgeableListStatusCallback(
303 ServiceWorkerDatabase
* database
,
304 std::set
<int64
> *purgeable_ids
,
306 ServiceWorkerStatusCode
* result
,
307 ServiceWorkerStatusCode status
) {
310 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
311 database
->GetPurgeableResourceIds(purgeable_ids
));
315 void LazyInitialize() {
316 storage()->LazyInitialize(base::Bind(&base::DoNothing
));
317 base::RunLoop().RunUntilIdle();
320 ServiceWorkerStatusCode
StoreRegistration(
321 scoped_refptr
<ServiceWorkerRegistration
> registration
,
322 scoped_refptr
<ServiceWorkerVersion
> version
) {
323 bool was_called
= false;
324 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
325 storage()->StoreRegistration(registration
.get(),
327 MakeStatusCallback(&was_called
, &result
));
328 EXPECT_FALSE(was_called
); // always async
329 base::RunLoop().RunUntilIdle();
330 EXPECT_TRUE(was_called
);
334 ServiceWorkerStatusCode
DeleteRegistration(
335 int64 registration_id
,
336 const GURL
& origin
) {
337 bool was_called
= false;
338 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
339 storage()->DeleteRegistration(
340 registration_id
, origin
, MakeStatusCallback(&was_called
, &result
));
341 EXPECT_FALSE(was_called
); // always async
342 base::RunLoop().RunUntilIdle();
343 EXPECT_TRUE(was_called
);
347 void GetAllRegistrationsInfos(
348 std::vector
<ServiceWorkerRegistrationInfo
>* registrations
) {
349 bool was_called
= false;
350 storage()->GetAllRegistrationsInfos(
351 MakeGetRegistrationsInfosCallback(&was_called
, registrations
));
352 EXPECT_FALSE(was_called
); // always async
353 base::RunLoop().RunUntilIdle();
354 EXPECT_TRUE(was_called
);
357 void GetRegistrationsForOrigin(
359 std::vector
<scoped_refptr
<ServiceWorkerRegistration
>>* registrations
) {
360 bool was_called
= false;
361 storage()->GetRegistrationsForOrigin(
362 origin
, MakeGetRegistrationsCallback(&was_called
, registrations
));
363 EXPECT_FALSE(was_called
); // always async
364 base::RunLoop().RunUntilIdle();
365 EXPECT_TRUE(was_called
);
368 ServiceWorkerStatusCode
GetUserData(
369 int64 registration_id
,
370 const std::string
& key
,
372 bool was_called
= false;
373 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
374 storage()->GetUserData(
375 registration_id
, key
,
376 base::Bind(&GetUserDataCallback
, &was_called
, data
, &result
));
377 EXPECT_FALSE(was_called
); // always async
378 base::RunLoop().RunUntilIdle();
379 EXPECT_TRUE(was_called
);
383 ServiceWorkerStatusCode
StoreUserData(
384 int64 registration_id
,
386 const std::string
& key
,
387 const std::string
& data
) {
388 bool was_called
= false;
389 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
390 storage()->StoreUserData(
391 registration_id
, origin
, key
, data
,
392 MakeStatusCallback(&was_called
, &result
));
393 EXPECT_FALSE(was_called
); // always async
394 base::RunLoop().RunUntilIdle();
395 EXPECT_TRUE(was_called
);
399 ServiceWorkerStatusCode
ClearUserData(
400 int64 registration_id
,
401 const std::string
& key
) {
402 bool was_called
= false;
403 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
404 storage()->ClearUserData(
405 registration_id
, key
, MakeStatusCallback(&was_called
, &result
));
406 EXPECT_FALSE(was_called
); // always async
407 base::RunLoop().RunUntilIdle();
408 EXPECT_TRUE(was_called
);
412 ServiceWorkerStatusCode
GetUserDataForAllRegistrations(
413 const std::string
& key
,
414 std::vector
<std::pair
<int64
, std::string
>>* data
) {
415 bool was_called
= false;
416 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
417 storage()->GetUserDataForAllRegistrations(
418 key
, base::Bind(&GetUserDataForAllRegistrationsCallback
, &was_called
,
420 EXPECT_FALSE(was_called
); // always async
421 base::RunLoop().RunUntilIdle();
422 EXPECT_TRUE(was_called
);
426 ServiceWorkerStatusCode
UpdateToActiveState(
427 scoped_refptr
<ServiceWorkerRegistration
> registration
) {
428 bool was_called
= false;
429 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
430 storage()->UpdateToActiveState(registration
.get(),
431 MakeStatusCallback(&was_called
, &result
));
432 EXPECT_FALSE(was_called
); // always async
433 base::RunLoop().RunUntilIdle();
434 EXPECT_TRUE(was_called
);
438 void UpdateLastUpdateCheckTime(ServiceWorkerRegistration
* registration
) {
439 storage()->UpdateLastUpdateCheckTime(registration
);
440 base::RunLoop().RunUntilIdle();
443 ServiceWorkerStatusCode
FindRegistrationForDocument(
444 const GURL
& document_url
,
445 scoped_refptr
<ServiceWorkerRegistration
>* registration
) {
446 bool was_called
= false;
447 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
448 storage()->FindRegistrationForDocument(
449 document_url
, MakeFindCallback(&was_called
, &result
, registration
));
450 base::RunLoop().RunUntilIdle();
451 EXPECT_TRUE(was_called
);
455 ServiceWorkerStatusCode
FindRegistrationForPattern(
457 scoped_refptr
<ServiceWorkerRegistration
>* registration
) {
458 bool was_called
= false;
459 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
460 storage()->FindRegistrationForPattern(
461 scope
, MakeFindCallback(&was_called
, &result
, registration
));
462 EXPECT_FALSE(was_called
); // always async
463 base::RunLoop().RunUntilIdle();
464 EXPECT_TRUE(was_called
);
468 ServiceWorkerStatusCode
FindRegistrationForId(
469 int64 registration_id
,
471 scoped_refptr
<ServiceWorkerRegistration
>* registration
) {
472 bool was_called
= false;
473 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
474 storage()->FindRegistrationForId(
475 registration_id
, origin
,
476 MakeFindCallback(&was_called
, &result
, registration
));
477 base::RunLoop().RunUntilIdle();
478 EXPECT_TRUE(was_called
);
482 ServiceWorkerStatusCode
FindRegistrationForIdOnly(
483 int64 registration_id
,
484 scoped_refptr
<ServiceWorkerRegistration
>* registration
) {
485 bool was_called
= false;
486 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
487 storage()->FindRegistrationForIdOnly(
488 registration_id
, MakeFindCallback(&was_called
, &result
, registration
));
489 base::RunLoop().RunUntilIdle();
490 EXPECT_TRUE(was_called
);
494 scoped_ptr
<ServiceWorkerContextCore
> context_
;
495 base::WeakPtr
<ServiceWorkerContextCore
> context_ptr_
;
496 TestBrowserThreadBundle browser_thread_bundle_
;
499 TEST_F(ServiceWorkerStorageTest
, StoreFindUpdateDeleteRegistration
) {
500 const GURL
kScope("http://www.test.not/scope/");
501 const GURL
kScript("http://www.test.not/script.js");
502 const GURL
kDocumentUrl("http://www.test.not/scope/document.html");
503 const GURL
kResource1("http://www.test.not/scope/resource1.js");
504 const int64 kResource1Size
= 1591234;
505 const GURL
kResource2("http://www.test.not/scope/resource2.js");
506 const int64 kResource2Size
= 51;
507 const int64 kRegistrationId
= 0;
508 const int64 kVersionId
= 0;
509 const base::Time kToday
= base::Time::Now();
510 const base::Time kYesterday
= kToday
- base::TimeDelta::FromDays(1);
512 scoped_refptr
<ServiceWorkerRegistration
> found_registration
;
514 // We shouldn't find anything without having stored anything.
515 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
516 FindRegistrationForDocument(kDocumentUrl
, &found_registration
));
517 EXPECT_FALSE(found_registration
.get());
519 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
520 FindRegistrationForPattern(kScope
, &found_registration
));
521 EXPECT_FALSE(found_registration
.get());
523 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
524 FindRegistrationForId(
525 kRegistrationId
, kScope
.GetOrigin(), &found_registration
));
526 EXPECT_FALSE(found_registration
.get());
528 std::vector
<ServiceWorkerDatabase::ResourceRecord
> resources
;
530 ServiceWorkerDatabase::ResourceRecord(1, kResource1
, kResource1Size
));
532 ServiceWorkerDatabase::ResourceRecord(2, kResource2
, kResource2Size
));
535 scoped_refptr
<ServiceWorkerRegistration
> live_registration
=
536 new ServiceWorkerRegistration(
537 kScope
, kRegistrationId
, context_ptr_
);
538 scoped_refptr
<ServiceWorkerVersion
> live_version
=
539 new ServiceWorkerVersion(
540 live_registration
.get(), kScript
, kVersionId
, context_ptr_
);
541 live_version
->SetStatus(ServiceWorkerVersion::INSTALLED
);
542 live_version
->script_cache_map()->SetResources(resources
);
543 live_registration
->SetWaitingVersion(live_version
);
544 live_registration
->set_last_update_check(kYesterday
);
545 EXPECT_EQ(SERVICE_WORKER_OK
,
546 StoreRegistration(live_registration
, live_version
));
548 // Now we should find it and get the live ptr back immediately.
549 EXPECT_EQ(SERVICE_WORKER_OK
,
550 FindRegistrationForDocument(kDocumentUrl
, &found_registration
));
551 EXPECT_EQ(live_registration
, found_registration
);
552 EXPECT_EQ(kResource1Size
+ kResource2Size
,
553 live_registration
->resources_total_size_bytes());
554 EXPECT_EQ(kResource1Size
+ kResource2Size
,
555 found_registration
->resources_total_size_bytes());
556 found_registration
= NULL
;
558 // But FindRegistrationForPattern is always async.
559 EXPECT_EQ(SERVICE_WORKER_OK
,
560 FindRegistrationForPattern(kScope
, &found_registration
));
561 EXPECT_EQ(live_registration
, found_registration
);
562 found_registration
= NULL
;
564 // Can be found by id too.
565 EXPECT_EQ(SERVICE_WORKER_OK
,
566 FindRegistrationForId(
567 kRegistrationId
, kScope
.GetOrigin(), &found_registration
));
568 ASSERT_TRUE(found_registration
.get());
569 EXPECT_EQ(kRegistrationId
, found_registration
->id());
570 EXPECT_EQ(live_registration
, found_registration
);
571 found_registration
= NULL
;
573 // Can be found by just the id too.
574 EXPECT_EQ(SERVICE_WORKER_OK
,
575 FindRegistrationForIdOnly(kRegistrationId
, &found_registration
));
576 ASSERT_TRUE(found_registration
.get());
577 EXPECT_EQ(kRegistrationId
, found_registration
->id());
578 EXPECT_EQ(live_registration
, found_registration
);
579 found_registration
= NULL
;
581 // Drop the live registration, but keep the version live.
582 live_registration
= NULL
;
584 // Now FindRegistrationForDocument should be async.
585 EXPECT_EQ(SERVICE_WORKER_OK
,
586 FindRegistrationForDocument(kDocumentUrl
, &found_registration
));
587 ASSERT_TRUE(found_registration
.get());
588 EXPECT_EQ(kRegistrationId
, found_registration
->id());
589 EXPECT_TRUE(found_registration
->HasOneRef());
591 // Check that sizes are populated correctly
592 EXPECT_EQ(live_version
.get(), found_registration
->waiting_version());
593 EXPECT_EQ(kResource1Size
+ kResource2Size
,
594 found_registration
->resources_total_size_bytes());
595 std::vector
<ServiceWorkerRegistrationInfo
> all_registrations
;
596 GetAllRegistrationsInfos(&all_registrations
);
597 EXPECT_EQ(1u, all_registrations
.size());
598 ServiceWorkerRegistrationInfo info
= all_registrations
[0];
599 EXPECT_EQ(kResource1Size
+ kResource2Size
, info
.stored_version_size_bytes
);
600 all_registrations
.clear();
602 // Finding by origin should provide the same result if origin is kScope.
603 std::vector
<scoped_refptr
<ServiceWorkerRegistration
>>
604 registrations_for_origin
;
605 GetRegistrationsForOrigin(kScope
.GetOrigin(), ®istrations_for_origin
);
606 EXPECT_EQ(1u, registrations_for_origin
.size());
607 registrations_for_origin
.clear();
609 GetRegistrationsForOrigin(GURL("http://example.com/").GetOrigin(),
610 ®istrations_for_origin
);
611 EXPECT_TRUE(registrations_for_origin
.empty());
613 found_registration
= NULL
;
615 // Drop the live version too.
618 // And FindRegistrationForPattern is always async.
619 EXPECT_EQ(SERVICE_WORKER_OK
,
620 FindRegistrationForPattern(kScope
, &found_registration
));
621 ASSERT_TRUE(found_registration
.get());
622 EXPECT_EQ(kRegistrationId
, found_registration
->id());
623 EXPECT_TRUE(found_registration
->HasOneRef());
624 EXPECT_FALSE(found_registration
->active_version());
625 ASSERT_TRUE(found_registration
->waiting_version());
626 EXPECT_EQ(kYesterday
, found_registration
->last_update_check());
627 EXPECT_EQ(ServiceWorkerVersion::INSTALLED
,
628 found_registration
->waiting_version()->status());
630 // Update to active and update the last check time.
631 scoped_refptr
<ServiceWorkerVersion
> temp_version
=
632 found_registration
->waiting_version();
633 temp_version
->SetStatus(ServiceWorkerVersion::ACTIVATED
);
634 found_registration
->SetActiveVersion(temp_version
);
636 EXPECT_EQ(SERVICE_WORKER_OK
, UpdateToActiveState(found_registration
));
637 found_registration
->set_last_update_check(kToday
);
638 UpdateLastUpdateCheckTime(found_registration
.get());
640 found_registration
= NULL
;
642 // Trying to update a unstored registration to active should fail.
643 scoped_refptr
<ServiceWorkerRegistration
> unstored_registration
=
644 new ServiceWorkerRegistration(
645 kScope
, kRegistrationId
+ 1, context_ptr_
);
646 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
647 UpdateToActiveState(unstored_registration
));
648 unstored_registration
= NULL
;
650 // The Find methods should return a registration with an active version
651 // and the expected update time.
652 EXPECT_EQ(SERVICE_WORKER_OK
,
653 FindRegistrationForDocument(kDocumentUrl
, &found_registration
));
654 ASSERT_TRUE(found_registration
.get());
655 EXPECT_EQ(kRegistrationId
, found_registration
->id());
656 EXPECT_TRUE(found_registration
->HasOneRef());
657 EXPECT_FALSE(found_registration
->waiting_version());
658 ASSERT_TRUE(found_registration
->active_version());
659 EXPECT_EQ(ServiceWorkerVersion::ACTIVATED
,
660 found_registration
->active_version()->status());
661 EXPECT_EQ(kToday
, found_registration
->last_update_check());
663 // Delete from storage but with a instance still live.
664 EXPECT_TRUE(context_
->GetLiveVersion(kRegistrationId
));
665 EXPECT_EQ(SERVICE_WORKER_OK
,
666 DeleteRegistration(kRegistrationId
, kScope
.GetOrigin()));
667 EXPECT_TRUE(context_
->GetLiveVersion(kRegistrationId
));
669 // Should no longer be found.
670 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
671 FindRegistrationForId(
672 kRegistrationId
, kScope
.GetOrigin(), &found_registration
));
673 EXPECT_FALSE(found_registration
.get());
674 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
675 FindRegistrationForIdOnly(kRegistrationId
, &found_registration
));
676 EXPECT_FALSE(found_registration
.get());
678 // Deleting an unstored registration should succeed.
679 EXPECT_EQ(SERVICE_WORKER_OK
,
680 DeleteRegistration(kRegistrationId
+ 1, kScope
.GetOrigin()));
683 TEST_F(ServiceWorkerStorageTest
, InstallingRegistrationsAreFindable
) {
684 const GURL
kScope("http://www.test.not/scope/");
685 const GURL
kScript("http://www.test.not/script.js");
686 const GURL
kDocumentUrl("http://www.test.not/scope/document.html");
687 const int64 kRegistrationId
= 0;
688 const int64 kVersionId
= 0;
690 scoped_refptr
<ServiceWorkerRegistration
> found_registration
;
692 // Create an unstored registration.
693 scoped_refptr
<ServiceWorkerRegistration
> live_registration
=
694 new ServiceWorkerRegistration(
695 kScope
, kRegistrationId
, context_ptr_
);
696 scoped_refptr
<ServiceWorkerVersion
> live_version
=
697 new ServiceWorkerVersion(
698 live_registration
.get(), kScript
, kVersionId
, context_ptr_
);
699 live_version
->SetStatus(ServiceWorkerVersion::INSTALLING
);
700 live_registration
->SetWaitingVersion(live_version
);
702 // Should not be findable, including by GetAllRegistrationsInfos.
703 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
704 FindRegistrationForId(
705 kRegistrationId
, kScope
.GetOrigin(), &found_registration
));
706 EXPECT_FALSE(found_registration
.get());
708 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
709 FindRegistrationForIdOnly(kRegistrationId
, &found_registration
));
710 EXPECT_FALSE(found_registration
.get());
712 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
713 FindRegistrationForDocument(kDocumentUrl
, &found_registration
));
714 EXPECT_FALSE(found_registration
.get());
716 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
717 FindRegistrationForPattern(kScope
, &found_registration
));
718 EXPECT_FALSE(found_registration
.get());
720 std::vector
<ServiceWorkerRegistrationInfo
> all_registrations
;
721 GetAllRegistrationsInfos(&all_registrations
);
722 EXPECT_TRUE(all_registrations
.empty());
724 std::vector
<scoped_refptr
<ServiceWorkerRegistration
>>
725 registrations_for_origin
;
726 GetRegistrationsForOrigin(kScope
.GetOrigin(), ®istrations_for_origin
);
727 EXPECT_TRUE(registrations_for_origin
.empty());
729 GetRegistrationsForOrigin(GURL("http://example.com/").GetOrigin(),
730 ®istrations_for_origin
);
731 EXPECT_TRUE(registrations_for_origin
.empty());
733 // Notify storage of it being installed.
734 storage()->NotifyInstallingRegistration(live_registration
.get());
736 // Now should be findable.
737 EXPECT_EQ(SERVICE_WORKER_OK
,
738 FindRegistrationForId(
739 kRegistrationId
, kScope
.GetOrigin(), &found_registration
));
740 EXPECT_EQ(live_registration
, found_registration
);
741 found_registration
= NULL
;
743 EXPECT_EQ(SERVICE_WORKER_OK
,
744 FindRegistrationForIdOnly(kRegistrationId
, &found_registration
));
745 EXPECT_EQ(live_registration
, found_registration
);
746 found_registration
= NULL
;
748 EXPECT_EQ(SERVICE_WORKER_OK
,
749 FindRegistrationForDocument(kDocumentUrl
, &found_registration
));
750 EXPECT_EQ(live_registration
, found_registration
);
751 found_registration
= NULL
;
753 EXPECT_EQ(SERVICE_WORKER_OK
,
754 FindRegistrationForPattern(kScope
, &found_registration
));
755 EXPECT_EQ(live_registration
, found_registration
);
756 found_registration
= NULL
;
758 GetAllRegistrationsInfos(&all_registrations
);
759 EXPECT_EQ(1u, all_registrations
.size());
760 all_registrations
.clear();
762 // Finding by origin should provide the same result if origin is kScope.
763 GetRegistrationsForOrigin(kScope
.GetOrigin(), ®istrations_for_origin
);
764 EXPECT_EQ(1u, registrations_for_origin
.size());
765 registrations_for_origin
.clear();
767 GetRegistrationsForOrigin(GURL("http://example.com/").GetOrigin(),
768 ®istrations_for_origin
);
769 EXPECT_TRUE(registrations_for_origin
.empty());
771 // Notify storage of installation no longer happening.
772 storage()->NotifyDoneInstallingRegistration(
773 live_registration
.get(), NULL
, SERVICE_WORKER_OK
);
775 // Once again, should not be findable.
776 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
777 FindRegistrationForId(
778 kRegistrationId
, kScope
.GetOrigin(), &found_registration
));
779 EXPECT_FALSE(found_registration
.get());
781 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
782 FindRegistrationForIdOnly(kRegistrationId
, &found_registration
));
783 EXPECT_FALSE(found_registration
.get());
785 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
786 FindRegistrationForDocument(kDocumentUrl
, &found_registration
));
787 EXPECT_FALSE(found_registration
.get());
789 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
790 FindRegistrationForPattern(kScope
, &found_registration
));
791 EXPECT_FALSE(found_registration
.get());
793 GetAllRegistrationsInfos(&all_registrations
);
794 EXPECT_TRUE(all_registrations
.empty());
796 GetRegistrationsForOrigin(kScope
.GetOrigin(), ®istrations_for_origin
);
797 EXPECT_TRUE(registrations_for_origin
.empty());
799 GetRegistrationsForOrigin(GURL("http://example.com/").GetOrigin(),
800 ®istrations_for_origin
);
801 EXPECT_TRUE(registrations_for_origin
.empty());
804 TEST_F(ServiceWorkerStorageTest
, StoreUserData
) {
805 const GURL
kScope("http://www.test.not/scope/");
806 const GURL
kScript("http://www.test.not/script.js");
807 const int64 kRegistrationId
= 0;
808 const int64 kVersionId
= 0;
812 // Store a registration.
813 scoped_refptr
<ServiceWorkerRegistration
> live_registration
=
814 new ServiceWorkerRegistration(
815 kScope
, kRegistrationId
, context_ptr_
);
816 scoped_refptr
<ServiceWorkerVersion
> live_version
=
817 new ServiceWorkerVersion(
818 live_registration
.get(), kScript
, kVersionId
, context_ptr_
);
819 std::vector
<ServiceWorkerDatabase::ResourceRecord
> records
;
820 records
.push_back(ServiceWorkerDatabase::ResourceRecord(
821 1, live_version
->script_url(), 100));
822 live_version
->script_cache_map()->SetResources(records
);
823 live_version
->SetStatus(ServiceWorkerVersion::INSTALLED
);
824 live_registration
->SetWaitingVersion(live_version
);
825 EXPECT_EQ(SERVICE_WORKER_OK
,
826 StoreRegistration(live_registration
, live_version
));
828 // Store user data associated with the registration.
829 std::string data_out
;
830 EXPECT_EQ(SERVICE_WORKER_OK
,
831 StoreUserData(kRegistrationId
, kScope
.GetOrigin(), "key", "data"));
832 EXPECT_EQ(SERVICE_WORKER_OK
, GetUserData(kRegistrationId
, "key", &data_out
));
833 EXPECT_EQ("data", data_out
);
834 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
835 GetUserData(kRegistrationId
, "unknown_key", &data_out
));
836 std::vector
<std::pair
<int64
, std::string
>> data_list_out
;
837 EXPECT_EQ(SERVICE_WORKER_OK
,
838 GetUserDataForAllRegistrations("key", &data_list_out
));
839 ASSERT_EQ(1u, data_list_out
.size());
840 EXPECT_EQ(kRegistrationId
, data_list_out
[0].first
);
841 EXPECT_EQ("data", data_list_out
[0].second
);
842 data_list_out
.clear();
843 EXPECT_EQ(SERVICE_WORKER_OK
,
844 GetUserDataForAllRegistrations("unknown_key", &data_list_out
));
845 EXPECT_EQ(0u, data_list_out
.size());
846 EXPECT_EQ(SERVICE_WORKER_OK
, ClearUserData(kRegistrationId
, "key"));
847 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
848 GetUserData(kRegistrationId
, "key", &data_out
));
850 // User data should be deleted when the associated registration is deleted.
851 ASSERT_EQ(SERVICE_WORKER_OK
,
852 StoreUserData(kRegistrationId
, kScope
.GetOrigin(), "key", "data"));
853 ASSERT_EQ(SERVICE_WORKER_OK
,
854 GetUserData(kRegistrationId
, "key", &data_out
));
855 ASSERT_EQ("data", data_out
);
857 EXPECT_EQ(SERVICE_WORKER_OK
,
858 DeleteRegistration(kRegistrationId
, kScope
.GetOrigin()));
859 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
860 GetUserData(kRegistrationId
, "key", &data_out
));
861 data_list_out
.clear();
862 EXPECT_EQ(SERVICE_WORKER_OK
,
863 GetUserDataForAllRegistrations("key", &data_list_out
));
864 EXPECT_EQ(0u, data_list_out
.size());
866 // Data access with an invalid registration id should be failed.
867 EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED
,
868 StoreUserData(kInvalidServiceWorkerRegistrationId
,
869 kScope
.GetOrigin(), "key", "data"));
870 EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED
,
871 GetUserData(kInvalidServiceWorkerRegistrationId
, "key", &data_out
));
872 EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED
,
873 ClearUserData(kInvalidServiceWorkerRegistrationId
, "key"));
875 // Data access with an empty key should be failed.
876 EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED
,
878 kRegistrationId
, kScope
.GetOrigin(), std::string(), "data"));
879 EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED
,
880 GetUserData(kRegistrationId
, std::string(), &data_out
));
881 EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED
,
882 ClearUserData(kRegistrationId
, std::string()));
883 data_list_out
.clear();
884 EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED
,
885 GetUserDataForAllRegistrations(std::string(), &data_list_out
));
888 class ServiceWorkerResourceStorageTest
: public ServiceWorkerStorageTest
{
890 void SetUp() override
{
891 ServiceWorkerStorageTest::SetUp();
893 storage()->LazyInitialize(base::Bind(&base::DoNothing
));
894 base::RunLoop().RunUntilIdle();
895 scope_
= GURL("http://www.test.not/scope/");
896 script_
= GURL("http://www.test.not/script.js");
897 import_
= GURL("http://www.test.not/import.js");
898 document_url_
= GURL("http://www.test.not/scope/document.html");
899 registration_id_
= storage()->NewRegistrationId();
900 version_id_
= storage()->NewVersionId();
901 resource_id1_
= storage()->NewResourceId();
902 resource_id2_
= storage()->NewResourceId();
903 resource_id1_size_
= 239193;
904 resource_id2_size_
= 59923;
906 // Cons up a new registration+version with two script resources.
907 RegistrationData data
;
908 data
.registration_id
= registration_id_
;
910 data
.script
= script_
;
911 data
.version_id
= version_id_
;
912 data
.is_active
= false;
913 std::vector
<ResourceRecord
> resources
;
915 ResourceRecord(resource_id1_
, script_
, resource_id1_size_
));
917 ResourceRecord(resource_id2_
, import_
, resource_id2_size_
));
918 registration_
= storage()->GetOrCreateRegistration(data
, resources
);
919 registration_
->waiting_version()->SetStatus(ServiceWorkerVersion::NEW
);
921 // Add the resources ids to the uncommitted list.
922 storage()->StoreUncommittedResponseId(resource_id1_
);
923 storage()->StoreUncommittedResponseId(resource_id2_
);
924 base::RunLoop().RunUntilIdle();
925 std::set
<int64
> verify_ids
;
926 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
927 storage()->database_
->GetUncommittedResourceIds(&verify_ids
));
928 EXPECT_EQ(2u, verify_ids
.size());
930 // And dump something in the disk cache for them.
931 WriteBasicResponse(storage(), resource_id1_
);
932 WriteBasicResponse(storage(), resource_id2_
);
933 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, true));
934 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id2_
, true));
936 // Storing the registration/version should take the resources ids out
937 // of the uncommitted list.
940 StoreRegistration(registration_
, registration_
->waiting_version()));
942 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
943 storage()->database_
->GetUncommittedResourceIds(&verify_ids
));
944 EXPECT_TRUE(verify_ids
.empty());
952 int64 registration_id_
;
955 uint64 resource_id1_size_
;
957 uint64 resource_id2_size_
;
958 scoped_refptr
<ServiceWorkerRegistration
> registration_
;
961 class ServiceWorkerResourceStorageDiskTest
962 : public ServiceWorkerResourceStorageTest
{
964 void SetUp() override
{
965 ASSERT_TRUE(user_data_directory_
.CreateUniqueTempDir());
966 ServiceWorkerResourceStorageTest::SetUp();
969 base::FilePath
GetUserDataDirectory() override
{
970 return user_data_directory_
.path();
974 base::ScopedTempDir user_data_directory_
;
977 TEST_F(ServiceWorkerResourceStorageTest
,
978 WriteMetadataWithServiceWorkerResponseMetadataWriter
) {
979 const char kMetadata1
[] = "Test metadata";
980 const char kMetadata2
[] = "small";
981 int64 new_resource_id_
= storage()->NewResourceId();
982 // Writing metadata to nonexistent resoirce ID must fail.
983 EXPECT_GE(0, WriteResponseMetadata(storage(), new_resource_id_
, kMetadata1
));
985 // Check metadata is written.
986 EXPECT_EQ(static_cast<int>(strlen(kMetadata1
)),
987 WriteResponseMetadata(storage(), resource_id1_
, kMetadata1
));
988 EXPECT_TRUE(VerifyResponseMetadata(storage(), resource_id1_
, kMetadata1
));
989 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, true));
991 // Check metadata is written and truncated.
992 EXPECT_EQ(static_cast<int>(strlen(kMetadata2
)),
993 WriteResponseMetadata(storage(), resource_id1_
, kMetadata2
));
994 EXPECT_TRUE(VerifyResponseMetadata(storage(), resource_id1_
, kMetadata2
));
995 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, true));
997 // Check metadata is deleted.
998 EXPECT_EQ(0, WriteResponseMetadata(storage(), resource_id1_
, ""));
999 EXPECT_FALSE(VerifyResponseMetadata(storage(), resource_id1_
, ""));
1000 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, true));
1003 TEST_F(ServiceWorkerResourceStorageTest
,
1004 WriteMetadataWithServiceWorkerScriptCacheMap
) {
1005 const char kMetadata1
[] = "Test metadata";
1006 const char kMetadata2
[] = "small";
1007 ServiceWorkerVersion
* version
= registration_
->waiting_version();
1008 EXPECT_TRUE(version
);
1010 // Writing metadata to nonexistent URL must fail.
1012 WriteMetadata(version
, GURL("http://www.test.not/nonexistent.js"),
1014 // Clearing metadata of nonexistent URL must fail.
1016 ClearMetadata(version
, GURL("http://www.test.not/nonexistent.js")));
1018 // Check metadata is written.
1019 EXPECT_EQ(static_cast<int>(strlen(kMetadata1
)),
1020 WriteMetadata(version
, script_
, kMetadata1
));
1021 EXPECT_TRUE(VerifyResponseMetadata(storage(), resource_id1_
, kMetadata1
));
1022 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, true));
1024 // Check metadata is written and truncated.
1025 EXPECT_EQ(static_cast<int>(strlen(kMetadata2
)),
1026 WriteMetadata(version
, script_
, kMetadata2
));
1027 EXPECT_TRUE(VerifyResponseMetadata(storage(), resource_id1_
, kMetadata2
));
1028 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, true));
1030 // Check metadata is deleted.
1031 EXPECT_EQ(0, ClearMetadata(version
, script_
));
1032 EXPECT_FALSE(VerifyResponseMetadata(storage(), resource_id1_
, ""));
1033 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, true));
1036 TEST_F(ServiceWorkerResourceStorageTest
, DeleteRegistration_NoLiveVersion
) {
1037 bool was_called
= false;
1038 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
1039 std::set
<int64
> verify_ids
;
1041 registration_
->SetWaitingVersion(NULL
);
1042 registration_
= NULL
;
1044 // Deleting the registration should result in the resources being added to the
1045 // purgeable list and then doomed in the disk cache and removed from that
1047 storage()->DeleteRegistration(
1050 base::Bind(&VerifyPurgeableListStatusCallback
,
1051 base::Unretained(storage()->database_
.get()),
1055 base::RunLoop().RunUntilIdle();
1056 ASSERT_TRUE(was_called
);
1057 EXPECT_EQ(SERVICE_WORKER_OK
, result
);
1058 EXPECT_EQ(2u, verify_ids
.size());
1060 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1061 storage()->database_
->GetPurgeableResourceIds(&verify_ids
));
1062 EXPECT_TRUE(verify_ids
.empty());
1064 EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id1_
, false));
1065 EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id2_
, false));
1068 TEST_F(ServiceWorkerResourceStorageTest
, DeleteRegistration_WaitingVersion
) {
1069 bool was_called
= false;
1070 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
1071 std::set
<int64
> verify_ids
;
1073 // Deleting the registration should result in the resources being added to the
1074 // purgeable list and then doomed in the disk cache and removed from that
1076 storage()->DeleteRegistration(
1077 registration_
->id(),
1079 base::Bind(&VerifyPurgeableListStatusCallback
,
1080 base::Unretained(storage()->database_
.get()),
1084 base::RunLoop().RunUntilIdle();
1085 ASSERT_TRUE(was_called
);
1086 EXPECT_EQ(SERVICE_WORKER_OK
, result
);
1087 EXPECT_EQ(2u, verify_ids
.size());
1089 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1090 storage()->database_
->GetPurgeableResourceIds(&verify_ids
));
1091 EXPECT_EQ(2u, verify_ids
.size());
1093 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, false));
1094 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id2_
, false));
1096 // Doom the version, now it happens.
1097 registration_
->waiting_version()->Doom();
1098 base::RunLoop().RunUntilIdle();
1099 EXPECT_EQ(SERVICE_WORKER_OK
, result
);
1100 EXPECT_EQ(2u, verify_ids
.size());
1102 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1103 storage()->database_
->GetPurgeableResourceIds(&verify_ids
));
1104 EXPECT_TRUE(verify_ids
.empty());
1106 EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id1_
, false));
1107 EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id2_
, false));
1110 TEST_F(ServiceWorkerResourceStorageTest
, DeleteRegistration_ActiveVersion
) {
1111 // Promote the worker to active and add a controllee.
1112 registration_
->SetActiveVersion(registration_
->waiting_version());
1113 storage()->UpdateToActiveState(
1114 registration_
.get(), base::Bind(&ServiceWorkerUtils::NoOpStatusCallback
));
1115 scoped_ptr
<ServiceWorkerProviderHost
> host(new ServiceWorkerProviderHost(
1116 33 /* dummy render process id */, MSG_ROUTING_NONE
,
1117 1 /* dummy provider_id */, SERVICE_WORKER_PROVIDER_FOR_WINDOW
,
1118 context_
->AsWeakPtr(), NULL
));
1119 registration_
->active_version()->AddControllee(host
.get());
1121 bool was_called
= false;
1122 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
1123 std::set
<int64
> verify_ids
;
1125 // Deleting the registration should move the resources to the purgeable list
1126 // but keep them available.
1127 storage()->DeleteRegistration(
1128 registration_
->id(),
1130 base::Bind(&VerifyPurgeableListStatusCallback
,
1131 base::Unretained(storage()->database_
.get()),
1135 base::RunLoop().RunUntilIdle();
1136 ASSERT_TRUE(was_called
);
1137 EXPECT_EQ(SERVICE_WORKER_OK
, result
);
1138 EXPECT_EQ(2u, verify_ids
.size());
1140 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1141 storage()->database_
->GetPurgeableResourceIds(&verify_ids
));
1142 EXPECT_EQ(2u, verify_ids
.size());
1144 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, true));
1145 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id2_
, true));
1147 // Removing the controllee should cause the resources to be deleted.
1148 registration_
->active_version()->RemoveControllee(host
.get());
1149 registration_
->active_version()->Doom();
1150 base::RunLoop().RunUntilIdle();
1152 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1153 storage()->database_
->GetPurgeableResourceIds(&verify_ids
));
1154 EXPECT_TRUE(verify_ids
.empty());
1156 EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id1_
, false));
1157 EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id2_
, false));
1160 TEST_F(ServiceWorkerResourceStorageDiskTest
, CleanupOnRestart
) {
1161 // Promote the worker to active and add a controllee.
1162 registration_
->SetActiveVersion(registration_
->waiting_version());
1163 registration_
->SetWaitingVersion(NULL
);
1164 storage()->UpdateToActiveState(
1165 registration_
.get(), base::Bind(&ServiceWorkerUtils::NoOpStatusCallback
));
1166 scoped_ptr
<ServiceWorkerProviderHost
> host(new ServiceWorkerProviderHost(
1167 33 /* dummy render process id */, MSG_ROUTING_NONE
,
1168 1 /* dummy provider_id */, SERVICE_WORKER_PROVIDER_FOR_WINDOW
,
1169 context_
->AsWeakPtr(), NULL
));
1170 registration_
->active_version()->AddControllee(host
.get());
1172 bool was_called
= false;
1173 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
1174 std::set
<int64
> verify_ids
;
1176 // Deleting the registration should move the resources to the purgeable list
1177 // but keep them available.
1178 storage()->DeleteRegistration(
1179 registration_
->id(),
1181 base::Bind(&VerifyPurgeableListStatusCallback
,
1182 base::Unretained(storage()->database_
.get()),
1186 base::RunLoop().RunUntilIdle();
1187 ASSERT_TRUE(was_called
);
1188 EXPECT_EQ(SERVICE_WORKER_OK
, result
);
1189 EXPECT_EQ(2u, verify_ids
.size());
1191 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1192 storage()->database_
->GetPurgeableResourceIds(&verify_ids
));
1193 EXPECT_EQ(2u, verify_ids
.size());
1195 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, true));
1196 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id2_
, true));
1198 // Also add an uncommitted resource.
1199 int64 kStaleUncommittedResourceId
= storage()->NewResourceId();
1200 storage()->StoreUncommittedResponseId(kStaleUncommittedResourceId
);
1201 base::RunLoop().RunUntilIdle();
1203 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1204 storage()->database_
->GetUncommittedResourceIds(&verify_ids
));
1205 EXPECT_EQ(1u, verify_ids
.size());
1206 WriteBasicResponse(storage(), kStaleUncommittedResourceId
);
1208 VerifyBasicResponse(storage(), kStaleUncommittedResourceId
, true));
1210 // Simulate browser shutdown. The purgeable and uncommitted resources are now
1213 scoped_ptr
<ServiceWorkerDatabaseTaskManager
> database_task_manager(
1214 new MockServiceWorkerDatabaseTaskManager(
1215 base::ThreadTaskRunnerHandle::Get()));
1217 new ServiceWorkerContextCore(GetUserDataDirectory(),
1218 database_task_manager
.Pass(),
1219 base::ThreadTaskRunnerHandle::Get(),
1224 storage()->LazyInitialize(base::Bind(&base::DoNothing
));
1225 base::RunLoop().RunUntilIdle();
1227 // Store a new uncommitted resource. This triggers stale resource cleanup.
1228 int64 kNewResourceId
= storage()->NewResourceId();
1229 WriteBasicResponse(storage(), kNewResourceId
);
1230 storage()->StoreUncommittedResponseId(kNewResourceId
);
1231 base::RunLoop().RunUntilIdle();
1233 // The stale resources should be purged, but the new resource should persist.
1235 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1236 storage()->database_
->GetUncommittedResourceIds(&verify_ids
));
1237 ASSERT_EQ(1u, verify_ids
.size());
1238 EXPECT_EQ(kNewResourceId
, *verify_ids
.begin());
1240 // Purging resources needs interactions with SimpleCache's worker thread,
1241 // so single RunUntilIdle() call may not be sufficient.
1242 while (storage()->is_purge_pending_
)
1243 base::RunLoop().RunUntilIdle();
1246 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1247 storage()->database_
->GetPurgeableResourceIds(&verify_ids
));
1248 EXPECT_TRUE(verify_ids
.empty());
1249 EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id1_
, false));
1250 EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id2_
, false));
1252 VerifyBasicResponse(storage(), kStaleUncommittedResourceId
, false));
1253 EXPECT_TRUE(VerifyBasicResponse(storage(), kNewResourceId
, true));
1256 TEST_F(ServiceWorkerResourceStorageTest
, UpdateRegistration
) {
1257 // Promote the worker to active worker and add a controllee.
1258 registration_
->SetActiveVersion(registration_
->waiting_version());
1259 storage()->UpdateToActiveState(
1260 registration_
.get(), base::Bind(&ServiceWorkerUtils::NoOpStatusCallback
));
1261 scoped_ptr
<ServiceWorkerProviderHost
> host(new ServiceWorkerProviderHost(
1262 33 /* dummy render process id */, MSG_ROUTING_NONE
,
1263 1 /* dummy provider_id */, SERVICE_WORKER_PROVIDER_FOR_WINDOW
,
1264 context_
->AsWeakPtr(), NULL
));
1265 registration_
->active_version()->AddControllee(host
.get());
1267 bool was_called
= false;
1268 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
1269 std::set
<int64
> verify_ids
;
1271 // Make an updated registration.
1272 scoped_refptr
<ServiceWorkerVersion
> live_version
= new ServiceWorkerVersion(
1273 registration_
.get(), script_
, storage()->NewVersionId(), context_ptr_
);
1274 live_version
->SetStatus(ServiceWorkerVersion::NEW
);
1275 registration_
->SetWaitingVersion(live_version
);
1276 std::vector
<ServiceWorkerDatabase::ResourceRecord
> records
;
1277 records
.push_back(ServiceWorkerDatabase::ResourceRecord(
1278 10, live_version
->script_url(), 100));
1279 live_version
->script_cache_map()->SetResources(records
);
1281 // Writing the registration should move the old version's resources to the
1282 // purgeable list but keep them available.
1283 storage()->StoreRegistration(
1284 registration_
.get(),
1285 registration_
->waiting_version(),
1286 base::Bind(&VerifyPurgeableListStatusCallback
,
1287 base::Unretained(storage()->database_
.get()),
1291 base::RunLoop().RunUntilIdle();
1292 ASSERT_TRUE(was_called
);
1293 EXPECT_EQ(SERVICE_WORKER_OK
, result
);
1294 EXPECT_EQ(2u, verify_ids
.size());
1296 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1297 storage()->database_
->GetPurgeableResourceIds(&verify_ids
));
1298 EXPECT_EQ(2u, verify_ids
.size());
1300 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, false));
1301 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id2_
, false));
1303 // Removing the controllee should cause the old version's resources to be
1305 registration_
->active_version()->RemoveControllee(host
.get());
1306 registration_
->active_version()->Doom();
1307 base::RunLoop().RunUntilIdle();
1309 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1310 storage()->database_
->GetPurgeableResourceIds(&verify_ids
));
1311 EXPECT_TRUE(verify_ids
.empty());
1313 EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id1_
, false));
1314 EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id2_
, false));
1317 TEST_F(ServiceWorkerStorageTest
, FindRegistration_LongestScopeMatch
) {
1318 const GURL
kDocumentUrl("http://www.example.com/scope/foo");
1319 scoped_refptr
<ServiceWorkerRegistration
> found_registration
;
1321 // Registration for "/scope/".
1322 const GURL
kScope1("http://www.example.com/scope/");
1323 const GURL
kScript1("http://www.example.com/script1.js");
1324 const int64 kRegistrationId1
= 1;
1325 const int64 kVersionId1
= 1;
1326 scoped_refptr
<ServiceWorkerRegistration
> live_registration1
=
1327 new ServiceWorkerRegistration(
1328 kScope1
, kRegistrationId1
, context_ptr_
);
1329 scoped_refptr
<ServiceWorkerVersion
> live_version1
=
1330 new ServiceWorkerVersion(
1331 live_registration1
.get(), kScript1
, kVersionId1
, context_ptr_
);
1332 std::vector
<ServiceWorkerDatabase::ResourceRecord
> records1
;
1333 records1
.push_back(ServiceWorkerDatabase::ResourceRecord(
1334 1, live_version1
->script_url(), 100));
1335 live_version1
->script_cache_map()->SetResources(records1
);
1336 live_version1
->SetStatus(ServiceWorkerVersion::INSTALLED
);
1337 live_registration1
->SetWaitingVersion(live_version1
);
1339 // Registration for "/scope/foo".
1340 const GURL
kScope2("http://www.example.com/scope/foo");
1341 const GURL
kScript2("http://www.example.com/script2.js");
1342 const int64 kRegistrationId2
= 2;
1343 const int64 kVersionId2
= 2;
1344 scoped_refptr
<ServiceWorkerRegistration
> live_registration2
=
1345 new ServiceWorkerRegistration(
1346 kScope2
, kRegistrationId2
, context_ptr_
);
1347 scoped_refptr
<ServiceWorkerVersion
> live_version2
=
1348 new ServiceWorkerVersion(
1349 live_registration2
.get(), kScript2
, kVersionId2
, context_ptr_
);
1350 std::vector
<ServiceWorkerDatabase::ResourceRecord
> records2
;
1351 records2
.push_back(ServiceWorkerDatabase::ResourceRecord(
1352 2, live_version2
->script_url(), 100));
1353 live_version2
->script_cache_map()->SetResources(records2
);
1354 live_version2
->SetStatus(ServiceWorkerVersion::INSTALLED
);
1355 live_registration2
->SetWaitingVersion(live_version2
);
1357 // Registration for "/scope/foobar".
1358 const GURL
kScope3("http://www.example.com/scope/foobar");
1359 const GURL
kScript3("http://www.example.com/script3.js");
1360 const int64 kRegistrationId3
= 3;
1361 const int64 kVersionId3
= 3;
1362 scoped_refptr
<ServiceWorkerRegistration
> live_registration3
=
1363 new ServiceWorkerRegistration(
1364 kScope3
, kRegistrationId3
, context_ptr_
);
1365 scoped_refptr
<ServiceWorkerVersion
> live_version3
=
1366 new ServiceWorkerVersion(
1367 live_registration3
.get(), kScript3
, kVersionId3
, context_ptr_
);
1368 std::vector
<ServiceWorkerDatabase::ResourceRecord
> records3
;
1369 records3
.push_back(ServiceWorkerDatabase::ResourceRecord(
1370 3, live_version3
->script_url(), 100));
1371 live_version3
->script_cache_map()->SetResources(records3
);
1372 live_version3
->SetStatus(ServiceWorkerVersion::INSTALLED
);
1373 live_registration3
->SetWaitingVersion(live_version3
);
1375 // Notify storage of they being installed.
1376 storage()->NotifyInstallingRegistration(live_registration1
.get());
1377 storage()->NotifyInstallingRegistration(live_registration2
.get());
1378 storage()->NotifyInstallingRegistration(live_registration3
.get());
1380 // Find a registration among installing ones.
1381 EXPECT_EQ(SERVICE_WORKER_OK
,
1382 FindRegistrationForDocument(kDocumentUrl
, &found_registration
));
1383 EXPECT_EQ(live_registration2
, found_registration
);
1384 found_registration
= NULL
;
1386 // Store registrations.
1387 EXPECT_EQ(SERVICE_WORKER_OK
,
1388 StoreRegistration(live_registration1
, live_version1
));
1389 EXPECT_EQ(SERVICE_WORKER_OK
,
1390 StoreRegistration(live_registration2
, live_version2
));
1391 EXPECT_EQ(SERVICE_WORKER_OK
,
1392 StoreRegistration(live_registration3
, live_version3
));
1394 // Notify storage of installations no longer happening.
1395 storage()->NotifyDoneInstallingRegistration(
1396 live_registration1
.get(), NULL
, SERVICE_WORKER_OK
);
1397 storage()->NotifyDoneInstallingRegistration(
1398 live_registration2
.get(), NULL
, SERVICE_WORKER_OK
);
1399 storage()->NotifyDoneInstallingRegistration(
1400 live_registration3
.get(), NULL
, SERVICE_WORKER_OK
);
1402 // Find a registration among installed ones.
1403 EXPECT_EQ(SERVICE_WORKER_OK
,
1404 FindRegistrationForDocument(kDocumentUrl
, &found_registration
));
1405 EXPECT_EQ(live_registration2
, found_registration
);
1408 TEST_F(ServiceWorkerStorageTest
, CompareResources
) {
1409 // Compare two small responses containing the same data.
1410 WriteBasicResponse(storage(), 1);
1411 WriteBasicResponse(storage(), 2);
1412 ServiceWorkerStatusCode status
= static_cast<ServiceWorkerStatusCode
>(-1);
1413 bool are_equal
= false;
1414 storage()->CompareScriptResources(
1416 base::Bind(&OnCompareComplete
, &status
, &are_equal
));
1417 base::RunLoop().RunUntilIdle();
1418 EXPECT_EQ(SERVICE_WORKER_OK
, status
);
1419 EXPECT_TRUE(are_equal
);
1421 // Compare two small responses with different data.
1422 const char kHttpHeaders
[] = "HTTP/1.0 200 HONKYDORY\0\0";
1423 const char kHttpBody
[] = "Goodbye";
1424 std::string
headers(kHttpHeaders
, arraysize(kHttpHeaders
));
1425 WriteStringResponse(storage(), 3, headers
, std::string(kHttpBody
));
1426 status
= static_cast<ServiceWorkerStatusCode
>(-1);
1428 storage()->CompareScriptResources(
1430 base::Bind(&OnCompareComplete
, &status
, &are_equal
));
1431 base::RunLoop().RunUntilIdle();
1432 EXPECT_EQ(SERVICE_WORKER_OK
, status
);
1433 EXPECT_FALSE(are_equal
);
1435 // Compare two large responses with the same data.
1436 const int k32K
= 32 * 1024;
1437 WriteResponseOfSize(storage(), 4, 'a', k32K
);
1438 WriteResponseOfSize(storage(), 5, 'a', k32K
);
1439 status
= static_cast<ServiceWorkerStatusCode
>(-1);
1441 storage()->CompareScriptResources(
1443 base::Bind(&OnCompareComplete
, &status
, &are_equal
));
1444 base::RunLoop().RunUntilIdle();
1445 EXPECT_EQ(SERVICE_WORKER_OK
, status
);
1446 EXPECT_TRUE(are_equal
);
1448 // Compare a large and small response.
1449 status
= static_cast<ServiceWorkerStatusCode
>(-1);
1451 storage()->CompareScriptResources(
1453 base::Bind(&OnCompareComplete
, &status
, &are_equal
));
1454 base::RunLoop().RunUntilIdle();
1455 EXPECT_EQ(SERVICE_WORKER_OK
, status
);
1456 EXPECT_FALSE(are_equal
);
1458 // Compare two large responses with different data.
1459 WriteResponseOfSize(storage(), 6, 'b', k32K
);
1460 status
= static_cast<ServiceWorkerStatusCode
>(-1);
1462 storage()->CompareScriptResources(
1464 base::Bind(&OnCompareComplete
, &status
, &are_equal
));
1465 base::RunLoop().RunUntilIdle();
1466 EXPECT_EQ(SERVICE_WORKER_OK
, status
);
1467 EXPECT_FALSE(are_equal
);
1470 } // namespace content