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/file_util.h"
8 #include "base/files/scoped_temp_dir.h"
9 #include "base/logging.h"
10 #include "base/run_loop.h"
11 #include "base/thread_task_runner_handle.h"
12 #include "content/browser/browser_thread_impl.h"
13 #include "content/browser/service_worker/service_worker_context_core.h"
14 #include "content/browser/service_worker/service_worker_disk_cache.h"
15 #include "content/browser/service_worker/service_worker_registration.h"
16 #include "content/browser/service_worker/service_worker_storage.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/common/service_worker/service_worker_utils.h"
20 #include "content/public/test/test_browser_thread_bundle.h"
21 #include "ipc/ipc_message.h"
22 #include "net/base/io_buffer.h"
23 #include "net/base/net_errors.h"
24 #include "net/base/test_completion_callback.h"
25 #include "net/http/http_response_headers.h"
26 #include "testing/gtest/include/gtest/gtest.h"
29 using net::TestCompletionCallback
;
30 using net::WrappedIOBuffer
;
36 typedef ServiceWorkerDatabase::RegistrationData RegistrationData
;
37 typedef ServiceWorkerDatabase::ResourceRecord ResourceRecord
;
39 void StatusAndQuitCallback(ServiceWorkerStatusCode
* result
,
40 const base::Closure
& quit_closure
,
41 ServiceWorkerStatusCode status
) {
46 void StatusCallback(bool* was_called
,
47 ServiceWorkerStatusCode
* result
,
48 ServiceWorkerStatusCode status
) {
53 ServiceWorkerStorage::StatusCallback
MakeStatusCallback(
55 ServiceWorkerStatusCode
* result
) {
56 return base::Bind(&StatusCallback
, was_called
, result
);
61 ServiceWorkerStatusCode
* result
,
62 scoped_refptr
<ServiceWorkerRegistration
>* found
,
63 ServiceWorkerStatusCode status
,
64 const scoped_refptr
<ServiceWorkerRegistration
>& registration
) {
67 *found
= registration
;
70 ServiceWorkerStorage::FindRegistrationCallback
MakeFindCallback(
72 ServiceWorkerStatusCode
* result
,
73 scoped_refptr
<ServiceWorkerRegistration
>* found
) {
74 return base::Bind(&FindCallback
, was_called
, result
, found
);
79 std::vector
<scoped_refptr
<ServiceWorkerRegistration
>>* all_out
,
80 const std::vector
<scoped_refptr
<ServiceWorkerRegistration
>>& all
) {
85 void GetAllInfosCallback(
87 std::vector
<ServiceWorkerRegistrationInfo
>* all_out
,
88 const std::vector
<ServiceWorkerRegistrationInfo
>& all
) {
93 ServiceWorkerStorage::GetRegistrationsCallback
MakeGetRegistrationsCallback(
95 std::vector
<scoped_refptr
<ServiceWorkerRegistration
>>* all
) {
96 return base::Bind(&GetAllCallback
, was_called
, all
);
99 ServiceWorkerStorage::GetRegistrationsInfosCallback
100 MakeGetRegistrationsInfosCallback(
102 std::vector
<ServiceWorkerRegistrationInfo
>* all
) {
103 return base::Bind(&GetAllInfosCallback
, was_called
, all
);
106 void GetUserDataCallback(
108 std::string
* data_out
,
109 ServiceWorkerStatusCode
* status_out
,
110 const std::string
& data
,
111 ServiceWorkerStatusCode status
) {
114 *status_out
= status
;
117 void GetUserDataForAllRegistrationsCallback(
119 std::vector
<std::pair
<int64
, std::string
>>* data_out
,
120 ServiceWorkerStatusCode
* status_out
,
121 const std::vector
<std::pair
<int64
, std::string
>>& data
,
122 ServiceWorkerStatusCode status
) {
125 *status_out
= status
;
129 ServiceWorkerStorage
* storage
, int64 id
,
130 const std::string
& headers
,
131 IOBuffer
* body
, int length
) {
132 scoped_ptr
<ServiceWorkerResponseWriter
> writer
=
133 storage
->CreateResponseWriter(id
);
135 scoped_ptr
<net::HttpResponseInfo
> info(new net::HttpResponseInfo
);
136 info
->request_time
= base::Time::Now();
137 info
->response_time
= base::Time::Now();
138 info
->was_cached
= false;
139 info
->headers
= new net::HttpResponseHeaders(headers
);
140 scoped_refptr
<HttpResponseInfoIOBuffer
> info_buffer
=
141 new HttpResponseInfoIOBuffer(info
.release());
143 TestCompletionCallback cb
;
144 writer
->WriteInfo(info_buffer
.get(), cb
.callback());
145 int rv
= cb
.WaitForResult();
149 TestCompletionCallback cb
;
150 writer
->WriteData(body
, length
, cb
.callback());
151 int rv
= cb
.WaitForResult();
152 EXPECT_EQ(length
, rv
);
156 void WriteStringResponse(
157 ServiceWorkerStorage
* storage
, int64 id
,
158 const std::string
& headers
,
159 const std::string
& body
) {
160 scoped_refptr
<IOBuffer
> body_buffer(new WrappedIOBuffer(body
.data()));
161 WriteResponse(storage
, id
, headers
, body_buffer
.get(), body
.length());
164 void WriteBasicResponse(ServiceWorkerStorage
* storage
, int64 id
) {
165 scoped_ptr
<ServiceWorkerResponseWriter
> writer
=
166 storage
->CreateResponseWriter(id
);
168 const char kHttpHeaders
[] = "HTTP/1.0 200 HONKYDORY\0Content-Length: 5\0\0";
169 const char kHttpBody
[] = "Hello";
170 std::string
headers(kHttpHeaders
, arraysize(kHttpHeaders
));
171 WriteStringResponse(storage
, id
, headers
, std::string(kHttpBody
));
174 bool VerifyBasicResponse(ServiceWorkerStorage
* storage
, int64 id
,
175 bool expected_positive_result
) {
176 const std::string
kExpectedHttpBody("Hello");
177 scoped_ptr
<ServiceWorkerResponseReader
> reader
=
178 storage
->CreateResponseReader(id
);
179 scoped_refptr
<HttpResponseInfoIOBuffer
> info_buffer
=
180 new HttpResponseInfoIOBuffer();
182 TestCompletionCallback cb
;
183 reader
->ReadInfo(info_buffer
.get(), cb
.callback());
184 int rv
= cb
.WaitForResult();
185 if (expected_positive_result
)
191 std::string received_body
;
193 const int kBigEnough
= 512;
194 scoped_refptr
<net::IOBuffer
> buffer
= new IOBuffer(kBigEnough
);
195 TestCompletionCallback cb
;
196 reader
->ReadData(buffer
.get(), kBigEnough
, cb
.callback());
197 int rv
= cb
.WaitForResult();
198 EXPECT_EQ(static_cast<int>(kExpectedHttpBody
.size()), rv
);
201 received_body
.assign(buffer
->data(), rv
);
205 std::string("HONKYDORY") ==
206 info_buffer
->http_info
->headers
->GetStatusText();
207 bool data_match
= kExpectedHttpBody
== received_body
;
209 EXPECT_TRUE(status_match
);
210 EXPECT_TRUE(data_match
);
211 return status_match
&& data_match
;
214 int WriteResponseMetadata(ServiceWorkerStorage
* storage
,
216 const std::string
& metadata
) {
217 scoped_refptr
<IOBuffer
> body_buffer(new WrappedIOBuffer(metadata
.data()));
218 scoped_ptr
<ServiceWorkerResponseMetadataWriter
> metadata_writer
=
219 storage
->CreateResponseMetadataWriter(id
);
220 TestCompletionCallback cb
;
221 metadata_writer
->WriteMetadata(body_buffer
.get(), metadata
.length(),
223 return cb
.WaitForResult();
226 int WriteMetadata(ServiceWorkerVersion
* version
,
228 const std::string
& metadata
) {
229 const std::vector
<char> data(metadata
.begin(), metadata
.end());
230 EXPECT_TRUE(version
);
231 TestCompletionCallback cb
;
232 version
->script_cache_map()->WriteMetadata(url
, data
, cb
.callback());
233 return cb
.WaitForResult();
236 int ClearMetadata(ServiceWorkerVersion
* version
, const GURL
& url
) {
237 EXPECT_TRUE(version
);
238 TestCompletionCallback cb
;
239 version
->script_cache_map()->ClearMetadata(url
, cb
.callback());
240 return cb
.WaitForResult();
243 bool VerifyResponseMetadata(ServiceWorkerStorage
* storage
,
245 const std::string
& expected_metadata
) {
246 scoped_ptr
<ServiceWorkerResponseReader
> reader
=
247 storage
->CreateResponseReader(id
);
248 scoped_refptr
<HttpResponseInfoIOBuffer
> info_buffer
=
249 new HttpResponseInfoIOBuffer();
251 TestCompletionCallback cb
;
252 reader
->ReadInfo(info_buffer
.get(), cb
.callback());
253 int rv
= cb
.WaitForResult();
256 const net::HttpResponseInfo
* read_head
= info_buffer
->http_info
.get();
257 if (!read_head
->metadata
.get())
259 EXPECT_EQ(0, memcmp(expected_metadata
.data(), read_head
->metadata
->data(),
260 expected_metadata
.length()));
266 class ServiceWorkerStorageTest
: public testing::Test
{
268 ServiceWorkerStorageTest()
269 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP
) {
272 void SetUp() override
{
273 scoped_ptr
<ServiceWorkerDatabaseTaskManager
> database_task_manager(
274 new MockServiceWorkerDatabaseTaskManager(
275 base::ThreadTaskRunnerHandle::Get()));
277 new ServiceWorkerContextCore(GetUserDataDirectory(),
278 database_task_manager
.Pass(),
279 base::ThreadTaskRunnerHandle::Get(),
284 context_ptr_
= context_
->AsWeakPtr();
287 void TearDown() override
{ context_
.reset(); }
289 virtual base::FilePath
GetUserDataDirectory() { return base::FilePath(); }
291 ServiceWorkerStorage
* storage() { return context_
->storage(); }
293 // A static class method for friendliness.
294 static void VerifyPurgeableListStatusCallback(
295 ServiceWorkerDatabase
* database
,
296 std::set
<int64
> *purgeable_ids
,
298 ServiceWorkerStatusCode
* result
,
299 ServiceWorkerStatusCode status
) {
302 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
303 database
->GetPurgeableResourceIds(purgeable_ids
));
307 void LazyInitialize() {
308 storage()->LazyInitialize(base::Bind(&base::DoNothing
));
309 base::RunLoop().RunUntilIdle();
312 ServiceWorkerStatusCode
StoreRegistration(
313 scoped_refptr
<ServiceWorkerRegistration
> registration
,
314 scoped_refptr
<ServiceWorkerVersion
> version
) {
315 bool was_called
= false;
316 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
317 storage()->StoreRegistration(registration
.get(),
319 MakeStatusCallback(&was_called
, &result
));
320 EXPECT_FALSE(was_called
); // always async
321 base::RunLoop().RunUntilIdle();
322 EXPECT_TRUE(was_called
);
326 ServiceWorkerStatusCode
DeleteRegistration(
327 int64 registration_id
,
328 const GURL
& origin
) {
329 bool was_called
= false;
330 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
331 storage()->DeleteRegistration(
332 registration_id
, origin
, MakeStatusCallback(&was_called
, &result
));
333 EXPECT_FALSE(was_called
); // always async
334 base::RunLoop().RunUntilIdle();
335 EXPECT_TRUE(was_called
);
339 void GetAllRegistrationsInfos(
340 std::vector
<ServiceWorkerRegistrationInfo
>* registrations
) {
341 bool was_called
= false;
342 storage()->GetAllRegistrationsInfos(
343 MakeGetRegistrationsInfosCallback(&was_called
, registrations
));
344 EXPECT_FALSE(was_called
); // always async
345 base::RunLoop().RunUntilIdle();
346 EXPECT_TRUE(was_called
);
349 void GetRegistrationsForOrigin(
351 std::vector
<scoped_refptr
<ServiceWorkerRegistration
>>* registrations
) {
352 bool was_called
= false;
353 storage()->GetRegistrationsForOrigin(
354 origin
, MakeGetRegistrationsCallback(&was_called
, registrations
));
355 EXPECT_FALSE(was_called
); // always async
356 base::RunLoop().RunUntilIdle();
357 EXPECT_TRUE(was_called
);
360 ServiceWorkerStatusCode
GetUserData(
361 int64 registration_id
,
362 const std::string
& key
,
364 bool was_called
= false;
365 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
366 storage()->GetUserData(
367 registration_id
, key
,
368 base::Bind(&GetUserDataCallback
, &was_called
, data
, &result
));
369 EXPECT_FALSE(was_called
); // always async
370 base::RunLoop().RunUntilIdle();
371 EXPECT_TRUE(was_called
);
375 ServiceWorkerStatusCode
StoreUserData(
376 int64 registration_id
,
378 const std::string
& key
,
379 const std::string
& data
) {
380 bool was_called
= false;
381 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
382 storage()->StoreUserData(
383 registration_id
, origin
, key
, data
,
384 MakeStatusCallback(&was_called
, &result
));
385 EXPECT_FALSE(was_called
); // always async
386 base::RunLoop().RunUntilIdle();
387 EXPECT_TRUE(was_called
);
391 ServiceWorkerStatusCode
ClearUserData(
392 int64 registration_id
,
393 const std::string
& key
) {
394 bool was_called
= false;
395 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
396 storage()->ClearUserData(
397 registration_id
, key
, MakeStatusCallback(&was_called
, &result
));
398 EXPECT_FALSE(was_called
); // always async
399 base::RunLoop().RunUntilIdle();
400 EXPECT_TRUE(was_called
);
404 ServiceWorkerStatusCode
GetUserDataForAllRegistrations(
405 const std::string
& key
,
406 std::vector
<std::pair
<int64
, std::string
>>* data
) {
407 bool was_called
= false;
408 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
409 storage()->GetUserDataForAllRegistrations(
410 key
, base::Bind(&GetUserDataForAllRegistrationsCallback
, &was_called
,
412 EXPECT_FALSE(was_called
); // always async
413 base::RunLoop().RunUntilIdle();
414 EXPECT_TRUE(was_called
);
418 ServiceWorkerStatusCode
UpdateToActiveState(
419 scoped_refptr
<ServiceWorkerRegistration
> registration
) {
420 bool was_called
= false;
421 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
422 storage()->UpdateToActiveState(registration
.get(),
423 MakeStatusCallback(&was_called
, &result
));
424 EXPECT_FALSE(was_called
); // always async
425 base::RunLoop().RunUntilIdle();
426 EXPECT_TRUE(was_called
);
430 void UpdateLastUpdateCheckTime(ServiceWorkerRegistration
* registration
) {
431 storage()->UpdateLastUpdateCheckTime(registration
);
432 base::RunLoop().RunUntilIdle();
435 ServiceWorkerStatusCode
FindRegistrationForDocument(
436 const GURL
& document_url
,
437 scoped_refptr
<ServiceWorkerRegistration
>* registration
) {
438 bool was_called
= false;
439 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
440 storage()->FindRegistrationForDocument(
441 document_url
, MakeFindCallback(&was_called
, &result
, registration
));
442 base::RunLoop().RunUntilIdle();
443 EXPECT_TRUE(was_called
);
447 ServiceWorkerStatusCode
FindRegistrationForPattern(
449 scoped_refptr
<ServiceWorkerRegistration
>* registration
) {
450 bool was_called
= false;
451 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
452 storage()->FindRegistrationForPattern(
453 scope
, MakeFindCallback(&was_called
, &result
, registration
));
454 EXPECT_FALSE(was_called
); // always async
455 base::RunLoop().RunUntilIdle();
456 EXPECT_TRUE(was_called
);
460 ServiceWorkerStatusCode
FindRegistrationForId(
461 int64 registration_id
,
463 scoped_refptr
<ServiceWorkerRegistration
>* registration
) {
464 bool was_called
= false;
465 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
466 storage()->FindRegistrationForId(
467 registration_id
, origin
,
468 MakeFindCallback(&was_called
, &result
, registration
));
469 base::RunLoop().RunUntilIdle();
470 EXPECT_TRUE(was_called
);
474 ServiceWorkerStatusCode
FindRegistrationForIdOnly(
475 int64 registration_id
,
476 scoped_refptr
<ServiceWorkerRegistration
>* registration
) {
477 bool was_called
= false;
478 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
479 storage()->FindRegistrationForIdOnly(
480 registration_id
, MakeFindCallback(&was_called
, &result
, registration
));
481 base::RunLoop().RunUntilIdle();
482 EXPECT_TRUE(was_called
);
486 scoped_ptr
<ServiceWorkerContextCore
> context_
;
487 base::WeakPtr
<ServiceWorkerContextCore
> context_ptr_
;
488 TestBrowserThreadBundle browser_thread_bundle_
;
491 TEST_F(ServiceWorkerStorageTest
, StoreFindUpdateDeleteRegistration
) {
492 const GURL
kScope("http://www.test.not/scope/");
493 const GURL
kScript("http://www.test.not/script.js");
494 const GURL
kDocumentUrl("http://www.test.not/scope/document.html");
495 const GURL
kResource1("http://www.test.not/scope/resource1.js");
496 const int64 kResource1Size
= 1591234;
497 const GURL
kResource2("http://www.test.not/scope/resource2.js");
498 const int64 kResource2Size
= 51;
499 const int64 kRegistrationId
= 0;
500 const int64 kVersionId
= 0;
501 const base::Time kToday
= base::Time::Now();
502 const base::Time kYesterday
= kToday
- base::TimeDelta::FromDays(1);
504 scoped_refptr
<ServiceWorkerRegistration
> found_registration
;
506 // We shouldn't find anything without having stored anything.
507 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
508 FindRegistrationForDocument(kDocumentUrl
, &found_registration
));
509 EXPECT_FALSE(found_registration
.get());
511 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
512 FindRegistrationForPattern(kScope
, &found_registration
));
513 EXPECT_FALSE(found_registration
.get());
515 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
516 FindRegistrationForId(
517 kRegistrationId
, kScope
.GetOrigin(), &found_registration
));
518 EXPECT_FALSE(found_registration
.get());
520 std::vector
<ServiceWorkerDatabase::ResourceRecord
> resources
;
522 ServiceWorkerDatabase::ResourceRecord(1, kResource1
, kResource1Size
));
524 ServiceWorkerDatabase::ResourceRecord(2, kResource2
, kResource2Size
));
527 scoped_refptr
<ServiceWorkerRegistration
> live_registration
=
528 new ServiceWorkerRegistration(
529 kScope
, kRegistrationId
, context_ptr_
);
530 scoped_refptr
<ServiceWorkerVersion
> live_version
=
531 new ServiceWorkerVersion(
532 live_registration
.get(), kScript
, kVersionId
, context_ptr_
);
533 live_version
->SetStatus(ServiceWorkerVersion::INSTALLED
);
534 live_version
->script_cache_map()->SetResources(resources
);
535 live_registration
->SetWaitingVersion(live_version
);
536 live_registration
->set_last_update_check(kYesterday
);
537 EXPECT_EQ(SERVICE_WORKER_OK
,
538 StoreRegistration(live_registration
, live_version
));
540 // Now we should find it and get the live ptr back immediately.
541 EXPECT_EQ(SERVICE_WORKER_OK
,
542 FindRegistrationForDocument(kDocumentUrl
, &found_registration
));
543 EXPECT_EQ(live_registration
, found_registration
);
544 EXPECT_EQ(kResource1Size
+ kResource2Size
,
545 live_registration
->resources_total_size_bytes());
546 EXPECT_EQ(kResource1Size
+ kResource2Size
,
547 found_registration
->resources_total_size_bytes());
548 found_registration
= NULL
;
550 // But FindRegistrationForPattern is always async.
551 EXPECT_EQ(SERVICE_WORKER_OK
,
552 FindRegistrationForPattern(kScope
, &found_registration
));
553 EXPECT_EQ(live_registration
, found_registration
);
554 found_registration
= NULL
;
556 // Can be found by id too.
557 EXPECT_EQ(SERVICE_WORKER_OK
,
558 FindRegistrationForId(
559 kRegistrationId
, kScope
.GetOrigin(), &found_registration
));
560 ASSERT_TRUE(found_registration
.get());
561 EXPECT_EQ(kRegistrationId
, found_registration
->id());
562 EXPECT_EQ(live_registration
, found_registration
);
563 found_registration
= NULL
;
565 // Can be found by just the id too.
566 EXPECT_EQ(SERVICE_WORKER_OK
,
567 FindRegistrationForIdOnly(kRegistrationId
, &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 // Drop the live registration, but keep the version live.
574 live_registration
= NULL
;
576 // Now FindRegistrationForDocument should be async.
577 EXPECT_EQ(SERVICE_WORKER_OK
,
578 FindRegistrationForDocument(kDocumentUrl
, &found_registration
));
579 ASSERT_TRUE(found_registration
.get());
580 EXPECT_EQ(kRegistrationId
, found_registration
->id());
581 EXPECT_TRUE(found_registration
->HasOneRef());
583 // Check that sizes are populated correctly
584 EXPECT_EQ(live_version
.get(), found_registration
->waiting_version());
585 EXPECT_EQ(kResource1Size
+ kResource2Size
,
586 found_registration
->resources_total_size_bytes());
587 std::vector
<ServiceWorkerRegistrationInfo
> all_registrations
;
588 GetAllRegistrationsInfos(&all_registrations
);
589 EXPECT_EQ(1u, all_registrations
.size());
590 ServiceWorkerRegistrationInfo info
= all_registrations
[0];
591 EXPECT_EQ(kResource1Size
+ kResource2Size
, info
.stored_version_size_bytes
);
592 all_registrations
.clear();
594 // Finding by origin should provide the same result if origin is kScope.
595 std::vector
<scoped_refptr
<ServiceWorkerRegistration
>>
596 registrations_for_origin
;
597 GetRegistrationsForOrigin(kScope
.GetOrigin(), ®istrations_for_origin
);
598 EXPECT_EQ(1u, registrations_for_origin
.size());
599 registrations_for_origin
.clear();
601 GetRegistrationsForOrigin(GURL("http://example.com/").GetOrigin(),
602 ®istrations_for_origin
);
603 EXPECT_TRUE(registrations_for_origin
.empty());
605 found_registration
= NULL
;
607 // Drop the live version too.
610 // And FindRegistrationForPattern is always async.
611 EXPECT_EQ(SERVICE_WORKER_OK
,
612 FindRegistrationForPattern(kScope
, &found_registration
));
613 ASSERT_TRUE(found_registration
.get());
614 EXPECT_EQ(kRegistrationId
, found_registration
->id());
615 EXPECT_TRUE(found_registration
->HasOneRef());
616 EXPECT_FALSE(found_registration
->active_version());
617 ASSERT_TRUE(found_registration
->waiting_version());
618 EXPECT_EQ(kYesterday
, found_registration
->last_update_check());
619 EXPECT_EQ(ServiceWorkerVersion::INSTALLED
,
620 found_registration
->waiting_version()->status());
622 // Update to active and update the last check time.
623 scoped_refptr
<ServiceWorkerVersion
> temp_version
=
624 found_registration
->waiting_version();
625 temp_version
->SetStatus(ServiceWorkerVersion::ACTIVATED
);
626 found_registration
->SetActiveVersion(temp_version
);
628 EXPECT_EQ(SERVICE_WORKER_OK
, UpdateToActiveState(found_registration
));
629 found_registration
->set_last_update_check(kToday
);
630 UpdateLastUpdateCheckTime(found_registration
.get());
632 found_registration
= NULL
;
634 // Trying to update a unstored registration to active should fail.
635 scoped_refptr
<ServiceWorkerRegistration
> unstored_registration
=
636 new ServiceWorkerRegistration(
637 kScope
, kRegistrationId
+ 1, context_ptr_
);
638 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
639 UpdateToActiveState(unstored_registration
));
640 unstored_registration
= NULL
;
642 // The Find methods should return a registration with an active version
643 // and the expected update time.
644 EXPECT_EQ(SERVICE_WORKER_OK
,
645 FindRegistrationForDocument(kDocumentUrl
, &found_registration
));
646 ASSERT_TRUE(found_registration
.get());
647 EXPECT_EQ(kRegistrationId
, found_registration
->id());
648 EXPECT_TRUE(found_registration
->HasOneRef());
649 EXPECT_FALSE(found_registration
->waiting_version());
650 ASSERT_TRUE(found_registration
->active_version());
651 EXPECT_EQ(ServiceWorkerVersion::ACTIVATED
,
652 found_registration
->active_version()->status());
653 EXPECT_EQ(kToday
, found_registration
->last_update_check());
655 // Delete from storage but with a instance still live.
656 EXPECT_TRUE(context_
->GetLiveVersion(kRegistrationId
));
657 EXPECT_EQ(SERVICE_WORKER_OK
,
658 DeleteRegistration(kRegistrationId
, kScope
.GetOrigin()));
659 EXPECT_TRUE(context_
->GetLiveVersion(kRegistrationId
));
661 // Should no longer be found.
662 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
663 FindRegistrationForId(
664 kRegistrationId
, kScope
.GetOrigin(), &found_registration
));
665 EXPECT_FALSE(found_registration
.get());
666 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
667 FindRegistrationForIdOnly(kRegistrationId
, &found_registration
));
668 EXPECT_FALSE(found_registration
.get());
670 // Deleting an unstored registration should succeed.
671 EXPECT_EQ(SERVICE_WORKER_OK
,
672 DeleteRegistration(kRegistrationId
+ 1, kScope
.GetOrigin()));
675 TEST_F(ServiceWorkerStorageTest
, InstallingRegistrationsAreFindable
) {
676 const GURL
kScope("http://www.test.not/scope/");
677 const GURL
kScript("http://www.test.not/script.js");
678 const GURL
kDocumentUrl("http://www.test.not/scope/document.html");
679 const int64 kRegistrationId
= 0;
680 const int64 kVersionId
= 0;
682 scoped_refptr
<ServiceWorkerRegistration
> found_registration
;
684 // Create an unstored registration.
685 scoped_refptr
<ServiceWorkerRegistration
> live_registration
=
686 new ServiceWorkerRegistration(
687 kScope
, kRegistrationId
, context_ptr_
);
688 scoped_refptr
<ServiceWorkerVersion
> live_version
=
689 new ServiceWorkerVersion(
690 live_registration
.get(), kScript
, kVersionId
, context_ptr_
);
691 live_version
->SetStatus(ServiceWorkerVersion::INSTALLING
);
692 live_registration
->SetWaitingVersion(live_version
);
694 // Should not be findable, including by GetAllRegistrationsInfos.
695 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
696 FindRegistrationForId(
697 kRegistrationId
, kScope
.GetOrigin(), &found_registration
));
698 EXPECT_FALSE(found_registration
.get());
700 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
701 FindRegistrationForIdOnly(kRegistrationId
, &found_registration
));
702 EXPECT_FALSE(found_registration
.get());
704 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
705 FindRegistrationForDocument(kDocumentUrl
, &found_registration
));
706 EXPECT_FALSE(found_registration
.get());
708 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
709 FindRegistrationForPattern(kScope
, &found_registration
));
710 EXPECT_FALSE(found_registration
.get());
712 std::vector
<ServiceWorkerRegistrationInfo
> all_registrations
;
713 GetAllRegistrationsInfos(&all_registrations
);
714 EXPECT_TRUE(all_registrations
.empty());
716 std::vector
<scoped_refptr
<ServiceWorkerRegistration
>>
717 registrations_for_origin
;
718 GetRegistrationsForOrigin(kScope
.GetOrigin(), ®istrations_for_origin
);
719 EXPECT_TRUE(registrations_for_origin
.empty());
721 GetRegistrationsForOrigin(GURL("http://example.com/").GetOrigin(),
722 ®istrations_for_origin
);
723 EXPECT_TRUE(registrations_for_origin
.empty());
725 // Notify storage of it being installed.
726 storage()->NotifyInstallingRegistration(live_registration
.get());
728 // Now should be findable.
729 EXPECT_EQ(SERVICE_WORKER_OK
,
730 FindRegistrationForId(
731 kRegistrationId
, kScope
.GetOrigin(), &found_registration
));
732 EXPECT_EQ(live_registration
, found_registration
);
733 found_registration
= NULL
;
735 EXPECT_EQ(SERVICE_WORKER_OK
,
736 FindRegistrationForIdOnly(kRegistrationId
, &found_registration
));
737 EXPECT_EQ(live_registration
, found_registration
);
738 found_registration
= NULL
;
740 EXPECT_EQ(SERVICE_WORKER_OK
,
741 FindRegistrationForDocument(kDocumentUrl
, &found_registration
));
742 EXPECT_EQ(live_registration
, found_registration
);
743 found_registration
= NULL
;
745 EXPECT_EQ(SERVICE_WORKER_OK
,
746 FindRegistrationForPattern(kScope
, &found_registration
));
747 EXPECT_EQ(live_registration
, found_registration
);
748 found_registration
= NULL
;
750 GetAllRegistrationsInfos(&all_registrations
);
751 EXPECT_EQ(1u, all_registrations
.size());
752 all_registrations
.clear();
754 // Finding by origin should provide the same result if origin is kScope.
755 GetRegistrationsForOrigin(kScope
.GetOrigin(), ®istrations_for_origin
);
756 EXPECT_EQ(1u, registrations_for_origin
.size());
757 registrations_for_origin
.clear();
759 GetRegistrationsForOrigin(GURL("http://example.com/").GetOrigin(),
760 ®istrations_for_origin
);
761 EXPECT_TRUE(registrations_for_origin
.empty());
763 // Notify storage of installation no longer happening.
764 storage()->NotifyDoneInstallingRegistration(
765 live_registration
.get(), NULL
, SERVICE_WORKER_OK
);
767 // Once again, should not be findable.
768 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
769 FindRegistrationForId(
770 kRegistrationId
, kScope
.GetOrigin(), &found_registration
));
771 EXPECT_FALSE(found_registration
.get());
773 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
774 FindRegistrationForIdOnly(kRegistrationId
, &found_registration
));
775 EXPECT_FALSE(found_registration
.get());
777 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
778 FindRegistrationForDocument(kDocumentUrl
, &found_registration
));
779 EXPECT_FALSE(found_registration
.get());
781 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
782 FindRegistrationForPattern(kScope
, &found_registration
));
783 EXPECT_FALSE(found_registration
.get());
785 GetAllRegistrationsInfos(&all_registrations
);
786 EXPECT_TRUE(all_registrations
.empty());
788 GetRegistrationsForOrigin(kScope
.GetOrigin(), ®istrations_for_origin
);
789 EXPECT_TRUE(registrations_for_origin
.empty());
791 GetRegistrationsForOrigin(GURL("http://example.com/").GetOrigin(),
792 ®istrations_for_origin
);
793 EXPECT_TRUE(registrations_for_origin
.empty());
796 TEST_F(ServiceWorkerStorageTest
, StoreUserData
) {
797 const GURL
kScope("http://www.test.not/scope/");
798 const GURL
kScript("http://www.test.not/script.js");
799 const int64 kRegistrationId
= 0;
800 const int64 kVersionId
= 0;
804 // Store a registration.
805 scoped_refptr
<ServiceWorkerRegistration
> live_registration
=
806 new ServiceWorkerRegistration(
807 kScope
, kRegistrationId
, context_ptr_
);
808 scoped_refptr
<ServiceWorkerVersion
> live_version
=
809 new ServiceWorkerVersion(
810 live_registration
.get(), kScript
, kVersionId
, context_ptr_
);
811 std::vector
<ServiceWorkerDatabase::ResourceRecord
> records
;
812 records
.push_back(ServiceWorkerDatabase::ResourceRecord(
813 1, live_version
->script_url(), 100));
814 live_version
->script_cache_map()->SetResources(records
);
815 live_version
->SetStatus(ServiceWorkerVersion::INSTALLED
);
816 live_registration
->SetWaitingVersion(live_version
);
817 EXPECT_EQ(SERVICE_WORKER_OK
,
818 StoreRegistration(live_registration
, live_version
));
820 // Store user data associated with the registration.
821 std::string data_out
;
822 EXPECT_EQ(SERVICE_WORKER_OK
,
823 StoreUserData(kRegistrationId
, kScope
.GetOrigin(), "key", "data"));
824 EXPECT_EQ(SERVICE_WORKER_OK
, GetUserData(kRegistrationId
, "key", &data_out
));
825 EXPECT_EQ("data", data_out
);
826 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
827 GetUserData(kRegistrationId
, "unknown_key", &data_out
));
828 std::vector
<std::pair
<int64
, std::string
>> data_list_out
;
829 EXPECT_EQ(SERVICE_WORKER_OK
,
830 GetUserDataForAllRegistrations("key", &data_list_out
));
831 ASSERT_EQ(1u, data_list_out
.size());
832 EXPECT_EQ(kRegistrationId
, data_list_out
[0].first
);
833 EXPECT_EQ("data", data_list_out
[0].second
);
834 data_list_out
.clear();
835 EXPECT_EQ(SERVICE_WORKER_OK
,
836 GetUserDataForAllRegistrations("unknown_key", &data_list_out
));
837 EXPECT_EQ(0u, data_list_out
.size());
838 EXPECT_EQ(SERVICE_WORKER_OK
, ClearUserData(kRegistrationId
, "key"));
839 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
840 GetUserData(kRegistrationId
, "key", &data_out
));
842 // User data should be deleted when the associated registration is deleted.
843 ASSERT_EQ(SERVICE_WORKER_OK
,
844 StoreUserData(kRegistrationId
, kScope
.GetOrigin(), "key", "data"));
845 ASSERT_EQ(SERVICE_WORKER_OK
,
846 GetUserData(kRegistrationId
, "key", &data_out
));
847 ASSERT_EQ("data", data_out
);
849 EXPECT_EQ(SERVICE_WORKER_OK
,
850 DeleteRegistration(kRegistrationId
, kScope
.GetOrigin()));
851 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
852 GetUserData(kRegistrationId
, "key", &data_out
));
853 data_list_out
.clear();
854 EXPECT_EQ(SERVICE_WORKER_OK
,
855 GetUserDataForAllRegistrations("key", &data_list_out
));
856 EXPECT_EQ(0u, data_list_out
.size());
858 // Data access with an invalid registration id should be failed.
859 EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED
,
860 StoreUserData(kInvalidServiceWorkerRegistrationId
,
861 kScope
.GetOrigin(), "key", "data"));
862 EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED
,
863 GetUserData(kInvalidServiceWorkerRegistrationId
, "key", &data_out
));
864 EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED
,
865 ClearUserData(kInvalidServiceWorkerRegistrationId
, "key"));
867 // Data access with an empty key should be failed.
868 EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED
,
870 kRegistrationId
, kScope
.GetOrigin(), std::string(), "data"));
871 EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED
,
872 GetUserData(kRegistrationId
, std::string(), &data_out
));
873 EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED
,
874 ClearUserData(kRegistrationId
, std::string()));
875 data_list_out
.clear();
876 EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED
,
877 GetUserDataForAllRegistrations(std::string(), &data_list_out
));
880 class ServiceWorkerResourceStorageTest
: public ServiceWorkerStorageTest
{
882 void SetUp() override
{
883 ServiceWorkerStorageTest::SetUp();
885 storage()->LazyInitialize(base::Bind(&base::DoNothing
));
886 base::RunLoop().RunUntilIdle();
887 scope_
= GURL("http://www.test.not/scope/");
888 script_
= GURL("http://www.test.not/script.js");
889 import_
= GURL("http://www.test.not/import.js");
890 document_url_
= GURL("http://www.test.not/scope/document.html");
891 registration_id_
= storage()->NewRegistrationId();
892 version_id_
= storage()->NewVersionId();
893 resource_id1_
= storage()->NewResourceId();
894 resource_id2_
= storage()->NewResourceId();
895 resource_id1_size_
= 239193;
896 resource_id2_size_
= 59923;
898 // Cons up a new registration+version with two script resources.
899 RegistrationData data
;
900 data
.registration_id
= registration_id_
;
902 data
.script
= script_
;
903 data
.version_id
= version_id_
;
904 data
.is_active
= false;
905 std::vector
<ResourceRecord
> resources
;
907 ResourceRecord(resource_id1_
, script_
, resource_id1_size_
));
909 ResourceRecord(resource_id2_
, import_
, resource_id2_size_
));
910 registration_
= storage()->GetOrCreateRegistration(data
, resources
);
911 registration_
->waiting_version()->SetStatus(ServiceWorkerVersion::NEW
);
913 // Add the resources ids to the uncommitted list.
914 storage()->StoreUncommittedResponseId(resource_id1_
);
915 storage()->StoreUncommittedResponseId(resource_id2_
);
916 base::RunLoop().RunUntilIdle();
917 std::set
<int64
> verify_ids
;
918 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
919 storage()->database_
->GetUncommittedResourceIds(&verify_ids
));
920 EXPECT_EQ(2u, verify_ids
.size());
922 // And dump something in the disk cache for them.
923 WriteBasicResponse(storage(), resource_id1_
);
924 WriteBasicResponse(storage(), resource_id2_
);
925 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, true));
926 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id2_
, true));
928 // Storing the registration/version should take the resources ids out
929 // of the uncommitted list.
932 StoreRegistration(registration_
, registration_
->waiting_version()));
934 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
935 storage()->database_
->GetUncommittedResourceIds(&verify_ids
));
936 EXPECT_TRUE(verify_ids
.empty());
944 int64 registration_id_
;
947 uint64 resource_id1_size_
;
949 uint64 resource_id2_size_
;
950 scoped_refptr
<ServiceWorkerRegistration
> registration_
;
953 class ServiceWorkerResourceStorageDiskTest
954 : public ServiceWorkerResourceStorageTest
{
956 void SetUp() override
{
957 ASSERT_TRUE(user_data_directory_
.CreateUniqueTempDir());
958 ServiceWorkerResourceStorageTest::SetUp();
961 base::FilePath
GetUserDataDirectory() override
{
962 return user_data_directory_
.path();
966 base::ScopedTempDir user_data_directory_
;
969 TEST_F(ServiceWorkerResourceStorageTest
,
970 WriteMetadataWithServiceWorkerResponseMetadataWriter
) {
971 const char kMetadata1
[] = "Test metadata";
972 const char kMetadata2
[] = "small";
973 int64 new_resource_id_
= storage()->NewResourceId();
974 // Writing metadata to nonexistent resoirce ID must fail.
975 EXPECT_GE(0, WriteResponseMetadata(storage(), new_resource_id_
, kMetadata1
));
977 // Check metadata is written.
978 EXPECT_EQ(static_cast<int>(strlen(kMetadata1
)),
979 WriteResponseMetadata(storage(), resource_id1_
, kMetadata1
));
980 EXPECT_TRUE(VerifyResponseMetadata(storage(), resource_id1_
, kMetadata1
));
981 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, true));
983 // Check metadata is written and truncated.
984 EXPECT_EQ(static_cast<int>(strlen(kMetadata2
)),
985 WriteResponseMetadata(storage(), resource_id1_
, kMetadata2
));
986 EXPECT_TRUE(VerifyResponseMetadata(storage(), resource_id1_
, kMetadata2
));
987 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, true));
989 // Check metadata is deleted.
990 EXPECT_EQ(0, WriteResponseMetadata(storage(), resource_id1_
, ""));
991 EXPECT_FALSE(VerifyResponseMetadata(storage(), resource_id1_
, ""));
992 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, true));
995 TEST_F(ServiceWorkerResourceStorageTest
,
996 WriteMetadataWithServiceWorkerScriptCacheMap
) {
997 const char kMetadata1
[] = "Test metadata";
998 const char kMetadata2
[] = "small";
999 ServiceWorkerVersion
* version
= registration_
->waiting_version();
1000 EXPECT_TRUE(version
);
1002 // Writing metadata to nonexistent URL must fail.
1004 WriteMetadata(version
, GURL("http://www.test.not/nonexistent.js"),
1006 // Clearing metadata of nonexistent URL must fail.
1008 ClearMetadata(version
, GURL("http://www.test.not/nonexistent.js")));
1010 // Check metadata is written.
1011 EXPECT_EQ(static_cast<int>(strlen(kMetadata1
)),
1012 WriteMetadata(version
, script_
, kMetadata1
));
1013 EXPECT_TRUE(VerifyResponseMetadata(storage(), resource_id1_
, kMetadata1
));
1014 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, true));
1016 // Check metadata is written and truncated.
1017 EXPECT_EQ(static_cast<int>(strlen(kMetadata2
)),
1018 WriteMetadata(version
, script_
, kMetadata2
));
1019 EXPECT_TRUE(VerifyResponseMetadata(storage(), resource_id1_
, kMetadata2
));
1020 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, true));
1022 // Check metadata is deleted.
1023 EXPECT_EQ(0, ClearMetadata(version
, script_
));
1024 EXPECT_FALSE(VerifyResponseMetadata(storage(), resource_id1_
, ""));
1025 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, true));
1028 TEST_F(ServiceWorkerResourceStorageTest
, DeleteRegistration_NoLiveVersion
) {
1029 bool was_called
= false;
1030 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
1031 std::set
<int64
> verify_ids
;
1033 registration_
->SetWaitingVersion(NULL
);
1034 registration_
= NULL
;
1036 // Deleting the registration should result in the resources being added to the
1037 // purgeable list and then doomed in the disk cache and removed from that
1039 storage()->DeleteRegistration(
1042 base::Bind(&VerifyPurgeableListStatusCallback
,
1043 base::Unretained(storage()->database_
.get()),
1047 base::RunLoop().RunUntilIdle();
1048 ASSERT_TRUE(was_called
);
1049 EXPECT_EQ(SERVICE_WORKER_OK
, result
);
1050 EXPECT_EQ(2u, verify_ids
.size());
1052 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1053 storage()->database_
->GetPurgeableResourceIds(&verify_ids
));
1054 EXPECT_TRUE(verify_ids
.empty());
1056 EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id1_
, false));
1057 EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id2_
, false));
1060 TEST_F(ServiceWorkerResourceStorageTest
, DeleteRegistration_WaitingVersion
) {
1061 bool was_called
= false;
1062 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
1063 std::set
<int64
> verify_ids
;
1065 // Deleting the registration should result in the resources being added to the
1066 // purgeable list and then doomed in the disk cache and removed from that
1068 storage()->DeleteRegistration(
1069 registration_
->id(),
1071 base::Bind(&VerifyPurgeableListStatusCallback
,
1072 base::Unretained(storage()->database_
.get()),
1076 base::RunLoop().RunUntilIdle();
1077 ASSERT_TRUE(was_called
);
1078 EXPECT_EQ(SERVICE_WORKER_OK
, result
);
1079 EXPECT_EQ(2u, verify_ids
.size());
1081 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1082 storage()->database_
->GetPurgeableResourceIds(&verify_ids
));
1083 EXPECT_EQ(2u, verify_ids
.size());
1085 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, false));
1086 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id2_
, false));
1088 // Doom the version, now it happens.
1089 registration_
->waiting_version()->Doom();
1090 base::RunLoop().RunUntilIdle();
1091 EXPECT_EQ(SERVICE_WORKER_OK
, result
);
1092 EXPECT_EQ(2u, verify_ids
.size());
1094 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1095 storage()->database_
->GetPurgeableResourceIds(&verify_ids
));
1096 EXPECT_TRUE(verify_ids
.empty());
1098 EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id1_
, false));
1099 EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id2_
, false));
1102 TEST_F(ServiceWorkerResourceStorageTest
, DeleteRegistration_ActiveVersion
) {
1103 // Promote the worker to active and add a controllee.
1104 registration_
->SetActiveVersion(registration_
->waiting_version());
1105 storage()->UpdateToActiveState(
1106 registration_
.get(), base::Bind(&ServiceWorkerUtils::NoOpStatusCallback
));
1107 scoped_ptr
<ServiceWorkerProviderHost
> host(new ServiceWorkerProviderHost(
1108 33 /* dummy render process id */, MSG_ROUTING_NONE
,
1109 1 /* dummy provider_id */, SERVICE_WORKER_PROVIDER_FOR_WINDOW
,
1110 context_
->AsWeakPtr(), NULL
));
1111 registration_
->active_version()->AddControllee(host
.get());
1113 bool was_called
= false;
1114 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
1115 std::set
<int64
> verify_ids
;
1117 // Deleting the registration should move the resources to the purgeable list
1118 // but keep them available.
1119 storage()->DeleteRegistration(
1120 registration_
->id(),
1122 base::Bind(&VerifyPurgeableListStatusCallback
,
1123 base::Unretained(storage()->database_
.get()),
1127 base::RunLoop().RunUntilIdle();
1128 ASSERT_TRUE(was_called
);
1129 EXPECT_EQ(SERVICE_WORKER_OK
, result
);
1130 EXPECT_EQ(2u, verify_ids
.size());
1132 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1133 storage()->database_
->GetPurgeableResourceIds(&verify_ids
));
1134 EXPECT_EQ(2u, verify_ids
.size());
1136 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, true));
1137 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id2_
, true));
1139 // Removing the controllee should cause the resources to be deleted.
1140 registration_
->active_version()->RemoveControllee(host
.get());
1141 registration_
->active_version()->Doom();
1142 base::RunLoop().RunUntilIdle();
1144 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1145 storage()->database_
->GetPurgeableResourceIds(&verify_ids
));
1146 EXPECT_TRUE(verify_ids
.empty());
1148 EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id1_
, false));
1149 EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id2_
, false));
1152 TEST_F(ServiceWorkerResourceStorageDiskTest
, CleanupOnRestart
) {
1153 // Promote the worker to active and add a controllee.
1154 registration_
->SetActiveVersion(registration_
->waiting_version());
1155 registration_
->SetWaitingVersion(NULL
);
1156 storage()->UpdateToActiveState(
1157 registration_
.get(), base::Bind(&ServiceWorkerUtils::NoOpStatusCallback
));
1158 scoped_ptr
<ServiceWorkerProviderHost
> host(new ServiceWorkerProviderHost(
1159 33 /* dummy render process id */, MSG_ROUTING_NONE
,
1160 1 /* dummy provider_id */, SERVICE_WORKER_PROVIDER_FOR_WINDOW
,
1161 context_
->AsWeakPtr(), NULL
));
1162 registration_
->active_version()->AddControllee(host
.get());
1164 bool was_called
= false;
1165 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
1166 std::set
<int64
> verify_ids
;
1168 // Deleting the registration should move the resources to the purgeable list
1169 // but keep them available.
1170 storage()->DeleteRegistration(
1171 registration_
->id(),
1173 base::Bind(&VerifyPurgeableListStatusCallback
,
1174 base::Unretained(storage()->database_
.get()),
1178 base::RunLoop().RunUntilIdle();
1179 ASSERT_TRUE(was_called
);
1180 EXPECT_EQ(SERVICE_WORKER_OK
, result
);
1181 EXPECT_EQ(2u, verify_ids
.size());
1183 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1184 storage()->database_
->GetPurgeableResourceIds(&verify_ids
));
1185 EXPECT_EQ(2u, verify_ids
.size());
1187 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, true));
1188 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id2_
, true));
1190 // Also add an uncommitted resource.
1191 int64 kStaleUncommittedResourceId
= storage()->NewResourceId();
1192 storage()->StoreUncommittedResponseId(kStaleUncommittedResourceId
);
1193 base::RunLoop().RunUntilIdle();
1195 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1196 storage()->database_
->GetUncommittedResourceIds(&verify_ids
));
1197 EXPECT_EQ(1u, verify_ids
.size());
1198 WriteBasicResponse(storage(), kStaleUncommittedResourceId
);
1200 VerifyBasicResponse(storage(), kStaleUncommittedResourceId
, true));
1202 // Simulate browser shutdown. The purgeable and uncommitted resources are now
1205 scoped_ptr
<ServiceWorkerDatabaseTaskManager
> database_task_manager(
1206 new MockServiceWorkerDatabaseTaskManager(
1207 base::ThreadTaskRunnerHandle::Get()));
1209 new ServiceWorkerContextCore(GetUserDataDirectory(),
1210 database_task_manager
.Pass(),
1211 base::ThreadTaskRunnerHandle::Get(),
1216 storage()->LazyInitialize(base::Bind(&base::DoNothing
));
1217 base::RunLoop().RunUntilIdle();
1219 // Store a new uncommitted resource. This triggers stale resource cleanup.
1220 int64 kNewResourceId
= storage()->NewResourceId();
1221 WriteBasicResponse(storage(), kNewResourceId
);
1222 storage()->StoreUncommittedResponseId(kNewResourceId
);
1223 base::RunLoop().RunUntilIdle();
1225 // The stale resources should be purged, but the new resource should persist.
1227 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1228 storage()->database_
->GetUncommittedResourceIds(&verify_ids
));
1229 ASSERT_EQ(1u, verify_ids
.size());
1230 EXPECT_EQ(kNewResourceId
, *verify_ids
.begin());
1232 // Purging resources needs interactions with SimpleCache's worker thread,
1233 // so single RunUntilIdle() call may not be sufficient.
1234 while (storage()->is_purge_pending_
)
1235 base::RunLoop().RunUntilIdle();
1238 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1239 storage()->database_
->GetPurgeableResourceIds(&verify_ids
));
1240 EXPECT_TRUE(verify_ids
.empty());
1241 EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id1_
, false));
1242 EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id2_
, false));
1244 VerifyBasicResponse(storage(), kStaleUncommittedResourceId
, false));
1245 EXPECT_TRUE(VerifyBasicResponse(storage(), kNewResourceId
, true));
1248 TEST_F(ServiceWorkerResourceStorageDiskTest
, DeleteAndStartOver
) {
1249 EXPECT_FALSE(storage()->IsDisabled());
1250 ASSERT_TRUE(base::DirectoryExists(storage()->GetDiskCachePath()));
1251 ASSERT_TRUE(base::DirectoryExists(storage()->GetDatabasePath()));
1253 base::RunLoop run_loop
;
1254 ServiceWorkerStatusCode status
= SERVICE_WORKER_ERROR_ABORT
;
1255 storage()->DeleteAndStartOver(
1256 base::Bind(&StatusAndQuitCallback
, &status
, run_loop
.QuitClosure()));
1259 EXPECT_EQ(SERVICE_WORKER_OK
, status
);
1260 EXPECT_TRUE(storage()->IsDisabled());
1261 EXPECT_FALSE(base::DirectoryExists(storage()->GetDiskCachePath()));
1262 EXPECT_FALSE(base::DirectoryExists(storage()->GetDatabasePath()));
1265 TEST_F(ServiceWorkerResourceStorageDiskTest
,
1266 DeleteAndStartOver_UnrelatedFileExists
) {
1267 EXPECT_FALSE(storage()->IsDisabled());
1268 ASSERT_TRUE(base::DirectoryExists(storage()->GetDiskCachePath()));
1269 ASSERT_TRUE(base::DirectoryExists(storage()->GetDatabasePath()));
1271 // Create an unrelated file in the database directory to make sure such a file
1272 // does not prevent DeleteAndStartOver.
1273 base::FilePath file_path
;
1275 base::CreateTemporaryFileInDir(storage()->GetDatabasePath(), &file_path
));
1276 ASSERT_TRUE(base::PathExists(file_path
));
1278 base::RunLoop run_loop
;
1279 ServiceWorkerStatusCode status
= SERVICE_WORKER_ERROR_ABORT
;
1280 storage()->DeleteAndStartOver(
1281 base::Bind(&StatusAndQuitCallback
, &status
, run_loop
.QuitClosure()));
1284 EXPECT_EQ(SERVICE_WORKER_OK
, status
);
1285 EXPECT_TRUE(storage()->IsDisabled());
1286 EXPECT_FALSE(base::DirectoryExists(storage()->GetDiskCachePath()));
1287 EXPECT_FALSE(base::DirectoryExists(storage()->GetDatabasePath()));
1290 TEST_F(ServiceWorkerResourceStorageDiskTest
,
1291 DeleteAndStartOver_OpenedFileExists
) {
1292 EXPECT_FALSE(storage()->IsDisabled());
1293 ASSERT_TRUE(base::DirectoryExists(storage()->GetDiskCachePath()));
1294 ASSERT_TRUE(base::DirectoryExists(storage()->GetDatabasePath()));
1296 // Create an unrelated opened file in the database directory to make sure such
1297 // a file does not prevent DeleteAndStartOver on non-Windows platforms.
1298 base::FilePath file_path
;
1299 base::ScopedFILE
file(base::CreateAndOpenTemporaryFileInDir(
1300 storage()->GetDatabasePath(), &file_path
));
1302 ASSERT_TRUE(base::PathExists(file_path
));
1304 base::RunLoop run_loop
;
1305 ServiceWorkerStatusCode status
= SERVICE_WORKER_ERROR_ABORT
;
1306 storage()->DeleteAndStartOver(
1307 base::Bind(&StatusAndQuitCallback
, &status
, run_loop
.QuitClosure()));
1311 // On Windows, deleting the directory containing an opened file should fail.
1312 EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED
, status
);
1313 EXPECT_TRUE(storage()->IsDisabled());
1314 EXPECT_TRUE(base::DirectoryExists(storage()->GetDiskCachePath()));
1315 EXPECT_TRUE(base::DirectoryExists(storage()->GetDatabasePath()));
1317 EXPECT_EQ(SERVICE_WORKER_OK
, status
);
1318 EXPECT_TRUE(storage()->IsDisabled());
1319 EXPECT_FALSE(base::DirectoryExists(storage()->GetDiskCachePath()));
1320 EXPECT_FALSE(base::DirectoryExists(storage()->GetDatabasePath()));
1324 TEST_F(ServiceWorkerResourceStorageTest
, UpdateRegistration
) {
1325 // Promote the worker to active worker and add a controllee.
1326 registration_
->SetActiveVersion(registration_
->waiting_version());
1327 storage()->UpdateToActiveState(
1328 registration_
.get(), base::Bind(&ServiceWorkerUtils::NoOpStatusCallback
));
1329 scoped_ptr
<ServiceWorkerProviderHost
> host(new ServiceWorkerProviderHost(
1330 33 /* dummy render process id */, MSG_ROUTING_NONE
,
1331 1 /* dummy provider_id */, SERVICE_WORKER_PROVIDER_FOR_WINDOW
,
1332 context_
->AsWeakPtr(), NULL
));
1333 registration_
->active_version()->AddControllee(host
.get());
1335 bool was_called
= false;
1336 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
1337 std::set
<int64
> verify_ids
;
1339 // Make an updated registration.
1340 scoped_refptr
<ServiceWorkerVersion
> live_version
= new ServiceWorkerVersion(
1341 registration_
.get(), script_
, storage()->NewVersionId(), context_ptr_
);
1342 live_version
->SetStatus(ServiceWorkerVersion::NEW
);
1343 registration_
->SetWaitingVersion(live_version
);
1344 std::vector
<ServiceWorkerDatabase::ResourceRecord
> records
;
1345 records
.push_back(ServiceWorkerDatabase::ResourceRecord(
1346 10, live_version
->script_url(), 100));
1347 live_version
->script_cache_map()->SetResources(records
);
1349 // Writing the registration should move the old version's resources to the
1350 // purgeable list but keep them available.
1351 storage()->StoreRegistration(
1352 registration_
.get(),
1353 registration_
->waiting_version(),
1354 base::Bind(&VerifyPurgeableListStatusCallback
,
1355 base::Unretained(storage()->database_
.get()),
1359 base::RunLoop().RunUntilIdle();
1360 ASSERT_TRUE(was_called
);
1361 EXPECT_EQ(SERVICE_WORKER_OK
, result
);
1362 EXPECT_EQ(2u, verify_ids
.size());
1364 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1365 storage()->database_
->GetPurgeableResourceIds(&verify_ids
));
1366 EXPECT_EQ(2u, verify_ids
.size());
1368 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, false));
1369 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id2_
, false));
1371 // Removing the controllee should cause the old version's resources to be
1373 registration_
->active_version()->RemoveControllee(host
.get());
1374 registration_
->active_version()->Doom();
1375 base::RunLoop().RunUntilIdle();
1377 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1378 storage()->database_
->GetPurgeableResourceIds(&verify_ids
));
1379 EXPECT_TRUE(verify_ids
.empty());
1381 EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id1_
, false));
1382 EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id2_
, false));
1385 TEST_F(ServiceWorkerStorageTest
, FindRegistration_LongestScopeMatch
) {
1386 const GURL
kDocumentUrl("http://www.example.com/scope/foo");
1387 scoped_refptr
<ServiceWorkerRegistration
> found_registration
;
1389 // Registration for "/scope/".
1390 const GURL
kScope1("http://www.example.com/scope/");
1391 const GURL
kScript1("http://www.example.com/script1.js");
1392 const int64 kRegistrationId1
= 1;
1393 const int64 kVersionId1
= 1;
1394 scoped_refptr
<ServiceWorkerRegistration
> live_registration1
=
1395 new ServiceWorkerRegistration(
1396 kScope1
, kRegistrationId1
, context_ptr_
);
1397 scoped_refptr
<ServiceWorkerVersion
> live_version1
=
1398 new ServiceWorkerVersion(
1399 live_registration1
.get(), kScript1
, kVersionId1
, context_ptr_
);
1400 std::vector
<ServiceWorkerDatabase::ResourceRecord
> records1
;
1401 records1
.push_back(ServiceWorkerDatabase::ResourceRecord(
1402 1, live_version1
->script_url(), 100));
1403 live_version1
->script_cache_map()->SetResources(records1
);
1404 live_version1
->SetStatus(ServiceWorkerVersion::INSTALLED
);
1405 live_registration1
->SetWaitingVersion(live_version1
);
1407 // Registration for "/scope/foo".
1408 const GURL
kScope2("http://www.example.com/scope/foo");
1409 const GURL
kScript2("http://www.example.com/script2.js");
1410 const int64 kRegistrationId2
= 2;
1411 const int64 kVersionId2
= 2;
1412 scoped_refptr
<ServiceWorkerRegistration
> live_registration2
=
1413 new ServiceWorkerRegistration(
1414 kScope2
, kRegistrationId2
, context_ptr_
);
1415 scoped_refptr
<ServiceWorkerVersion
> live_version2
=
1416 new ServiceWorkerVersion(
1417 live_registration2
.get(), kScript2
, kVersionId2
, context_ptr_
);
1418 std::vector
<ServiceWorkerDatabase::ResourceRecord
> records2
;
1419 records2
.push_back(ServiceWorkerDatabase::ResourceRecord(
1420 2, live_version2
->script_url(), 100));
1421 live_version2
->script_cache_map()->SetResources(records2
);
1422 live_version2
->SetStatus(ServiceWorkerVersion::INSTALLED
);
1423 live_registration2
->SetWaitingVersion(live_version2
);
1425 // Registration for "/scope/foobar".
1426 const GURL
kScope3("http://www.example.com/scope/foobar");
1427 const GURL
kScript3("http://www.example.com/script3.js");
1428 const int64 kRegistrationId3
= 3;
1429 const int64 kVersionId3
= 3;
1430 scoped_refptr
<ServiceWorkerRegistration
> live_registration3
=
1431 new ServiceWorkerRegistration(
1432 kScope3
, kRegistrationId3
, context_ptr_
);
1433 scoped_refptr
<ServiceWorkerVersion
> live_version3
=
1434 new ServiceWorkerVersion(
1435 live_registration3
.get(), kScript3
, kVersionId3
, context_ptr_
);
1436 std::vector
<ServiceWorkerDatabase::ResourceRecord
> records3
;
1437 records3
.push_back(ServiceWorkerDatabase::ResourceRecord(
1438 3, live_version3
->script_url(), 100));
1439 live_version3
->script_cache_map()->SetResources(records3
);
1440 live_version3
->SetStatus(ServiceWorkerVersion::INSTALLED
);
1441 live_registration3
->SetWaitingVersion(live_version3
);
1443 // Notify storage of they being installed.
1444 storage()->NotifyInstallingRegistration(live_registration1
.get());
1445 storage()->NotifyInstallingRegistration(live_registration2
.get());
1446 storage()->NotifyInstallingRegistration(live_registration3
.get());
1448 // Find a registration among installing ones.
1449 EXPECT_EQ(SERVICE_WORKER_OK
,
1450 FindRegistrationForDocument(kDocumentUrl
, &found_registration
));
1451 EXPECT_EQ(live_registration2
, found_registration
);
1452 found_registration
= NULL
;
1454 // Store registrations.
1455 EXPECT_EQ(SERVICE_WORKER_OK
,
1456 StoreRegistration(live_registration1
, live_version1
));
1457 EXPECT_EQ(SERVICE_WORKER_OK
,
1458 StoreRegistration(live_registration2
, live_version2
));
1459 EXPECT_EQ(SERVICE_WORKER_OK
,
1460 StoreRegistration(live_registration3
, live_version3
));
1462 // Notify storage of installations no longer happening.
1463 storage()->NotifyDoneInstallingRegistration(
1464 live_registration1
.get(), NULL
, SERVICE_WORKER_OK
);
1465 storage()->NotifyDoneInstallingRegistration(
1466 live_registration2
.get(), NULL
, SERVICE_WORKER_OK
);
1467 storage()->NotifyDoneInstallingRegistration(
1468 live_registration3
.get(), NULL
, SERVICE_WORKER_OK
);
1470 // Find a registration among installed ones.
1471 EXPECT_EQ(SERVICE_WORKER_OK
,
1472 FindRegistrationForDocument(kDocumentUrl
, &found_registration
));
1473 EXPECT_EQ(live_registration2
, found_registration
);
1476 } // namespace content