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
<ServiceWorkerRegistrationInfo
>* all_out
,
72 const std::vector
<ServiceWorkerRegistrationInfo
>& all
) {
77 ServiceWorkerStorage::GetRegistrationsInfosCallback
78 MakeGetRegistrationsCallback(bool* was_called
,
79 std::vector
<ServiceWorkerRegistrationInfo
>* all
) {
80 return base::Bind(&GetAllCallback
, was_called
, all
);
83 void GetUserDataCallback(
85 std::string
* data_out
,
86 ServiceWorkerStatusCode
* status_out
,
87 const std::string
& data
,
88 ServiceWorkerStatusCode status
) {
94 void GetUserDataForAllRegistrationsCallback(
96 std::vector
<std::pair
<int64
, std::string
>>* data_out
,
97 ServiceWorkerStatusCode
* status_out
,
98 const std::vector
<std::pair
<int64
, std::string
>>& data
,
99 ServiceWorkerStatusCode status
) {
102 *status_out
= status
;
105 void OnCompareComplete(
106 ServiceWorkerStatusCode
* status_out
, bool* are_equal_out
,
107 ServiceWorkerStatusCode status
, bool are_equal
) {
108 *status_out
= status
;
109 *are_equal_out
= are_equal
;
113 ServiceWorkerStorage
* storage
, int64 id
,
114 const std::string
& headers
,
115 IOBuffer
* body
, int length
) {
116 scoped_ptr
<ServiceWorkerResponseWriter
> writer
=
117 storage
->CreateResponseWriter(id
);
119 scoped_ptr
<net::HttpResponseInfo
> info(new net::HttpResponseInfo
);
120 info
->request_time
= base::Time::Now();
121 info
->response_time
= base::Time::Now();
122 info
->was_cached
= false;
123 info
->headers
= new net::HttpResponseHeaders(headers
);
124 scoped_refptr
<HttpResponseInfoIOBuffer
> info_buffer
=
125 new HttpResponseInfoIOBuffer(info
.release());
127 TestCompletionCallback cb
;
128 writer
->WriteInfo(info_buffer
.get(), cb
.callback());
129 int rv
= cb
.WaitForResult();
133 TestCompletionCallback cb
;
134 writer
->WriteData(body
, length
, cb
.callback());
135 int rv
= cb
.WaitForResult();
136 EXPECT_EQ(length
, rv
);
140 void WriteStringResponse(
141 ServiceWorkerStorage
* storage
, int64 id
,
142 const std::string
& headers
,
143 const std::string
& body
) {
144 scoped_refptr
<IOBuffer
> body_buffer(new WrappedIOBuffer(body
.data()));
145 WriteResponse(storage
, id
, headers
, body_buffer
.get(), body
.length());
148 void WriteBasicResponse(ServiceWorkerStorage
* storage
, int64 id
) {
149 scoped_ptr
<ServiceWorkerResponseWriter
> writer
=
150 storage
->CreateResponseWriter(id
);
152 const char kHttpHeaders
[] = "HTTP/1.0 200 HONKYDORY\0Content-Length: 5\0\0";
153 const char kHttpBody
[] = "Hello";
154 std::string
headers(kHttpHeaders
, arraysize(kHttpHeaders
));
155 WriteStringResponse(storage
, id
, headers
, std::string(kHttpBody
));
158 bool VerifyBasicResponse(ServiceWorkerStorage
* storage
, int64 id
,
159 bool expected_positive_result
) {
160 const std::string
kExpectedHttpBody("Hello");
161 scoped_ptr
<ServiceWorkerResponseReader
> reader
=
162 storage
->CreateResponseReader(id
);
163 scoped_refptr
<HttpResponseInfoIOBuffer
> info_buffer
=
164 new HttpResponseInfoIOBuffer();
166 TestCompletionCallback cb
;
167 reader
->ReadInfo(info_buffer
.get(), cb
.callback());
168 int rv
= cb
.WaitForResult();
169 if (expected_positive_result
)
175 std::string received_body
;
177 const int kBigEnough
= 512;
178 scoped_refptr
<net::IOBuffer
> buffer
= new IOBuffer(kBigEnough
);
179 TestCompletionCallback cb
;
180 reader
->ReadData(buffer
.get(), kBigEnough
, cb
.callback());
181 int rv
= cb
.WaitForResult();
182 EXPECT_EQ(static_cast<int>(kExpectedHttpBody
.size()), rv
);
185 received_body
.assign(buffer
->data(), rv
);
189 std::string("HONKYDORY") ==
190 info_buffer
->http_info
->headers
->GetStatusText();
191 bool data_match
= kExpectedHttpBody
== received_body
;
193 EXPECT_TRUE(status_match
);
194 EXPECT_TRUE(data_match
);
195 return status_match
&& data_match
;
198 void WriteResponseOfSize(ServiceWorkerStorage
* storage
, int64 id
,
199 char val
, int size
) {
200 const char kHttpHeaders
[] = "HTTP/1.0 200 HONKYDORY\00";
201 std::string
headers(kHttpHeaders
, arraysize(kHttpHeaders
));
202 scoped_refptr
<net::IOBuffer
> buffer
= new net::IOBuffer(size
);
203 memset(buffer
->data(), val
, size
);
204 WriteResponse(storage
, id
, headers
, buffer
.get(), size
);
207 int WriteResponseMetadata(ServiceWorkerStorage
* storage
,
209 const std::string
& metadata
) {
210 scoped_refptr
<IOBuffer
> body_buffer(new WrappedIOBuffer(metadata
.data()));
211 scoped_ptr
<ServiceWorkerResponseMetadataWriter
> metadata_writer
=
212 storage
->CreateResponseMetadataWriter(id
);
213 TestCompletionCallback cb
;
214 metadata_writer
->WriteMetadata(body_buffer
.get(), metadata
.length(),
216 return cb
.WaitForResult();
219 int WriteMetadata(ServiceWorkerVersion
* version
,
221 const std::string
& metadata
) {
222 const std::vector
<char> data(metadata
.begin(), metadata
.end());
223 EXPECT_TRUE(version
);
224 TestCompletionCallback cb
;
225 version
->script_cache_map()->WriteMetadata(url
, data
, cb
.callback());
226 return cb
.WaitForResult();
229 int ClearMetadata(ServiceWorkerVersion
* version
, const GURL
& url
) {
230 EXPECT_TRUE(version
);
231 TestCompletionCallback cb
;
232 version
->script_cache_map()->ClearMetadata(url
, cb
.callback());
233 return cb
.WaitForResult();
236 bool VerifyResponseMetadata(ServiceWorkerStorage
* storage
,
238 const std::string
& expected_metadata
) {
239 scoped_ptr
<ServiceWorkerResponseReader
> reader
=
240 storage
->CreateResponseReader(id
);
241 scoped_refptr
<HttpResponseInfoIOBuffer
> info_buffer
=
242 new HttpResponseInfoIOBuffer();
244 TestCompletionCallback cb
;
245 reader
->ReadInfo(info_buffer
.get(), cb
.callback());
246 int rv
= cb
.WaitForResult();
249 const net::HttpResponseInfo
* read_head
= info_buffer
->http_info
.get();
250 if (!read_head
->metadata
.get())
252 EXPECT_EQ(0, memcmp(expected_metadata
.data(), read_head
->metadata
->data(),
253 expected_metadata
.length()));
259 class ServiceWorkerStorageTest
: public testing::Test
{
261 ServiceWorkerStorageTest()
262 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP
) {
265 void SetUp() override
{
266 scoped_ptr
<ServiceWorkerDatabaseTaskManager
> database_task_manager(
267 new MockServiceWorkerDatabaseTaskManager(
268 base::ThreadTaskRunnerHandle::Get()));
270 new ServiceWorkerContextCore(GetUserDataDirectory(),
271 database_task_manager
.Pass(),
272 base::ThreadTaskRunnerHandle::Get(),
277 context_ptr_
= context_
->AsWeakPtr();
280 void TearDown() override
{ context_
.reset(); }
282 virtual base::FilePath
GetUserDataDirectory() { return base::FilePath(); }
284 ServiceWorkerStorage
* storage() { return context_
->storage(); }
286 // A static class method for friendliness.
287 static void VerifyPurgeableListStatusCallback(
288 ServiceWorkerDatabase
* database
,
289 std::set
<int64
> *purgeable_ids
,
291 ServiceWorkerStatusCode
* result
,
292 ServiceWorkerStatusCode status
) {
295 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
296 database
->GetPurgeableResourceIds(purgeable_ids
));
300 void LazyInitialize() {
301 storage()->LazyInitialize(base::Bind(&base::DoNothing
));
302 base::RunLoop().RunUntilIdle();
305 ServiceWorkerStatusCode
StoreRegistration(
306 scoped_refptr
<ServiceWorkerRegistration
> registration
,
307 scoped_refptr
<ServiceWorkerVersion
> version
) {
308 bool was_called
= false;
309 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
310 storage()->StoreRegistration(registration
.get(),
312 MakeStatusCallback(&was_called
, &result
));
313 EXPECT_FALSE(was_called
); // always async
314 base::RunLoop().RunUntilIdle();
315 EXPECT_TRUE(was_called
);
319 ServiceWorkerStatusCode
DeleteRegistration(
320 int64 registration_id
,
321 const GURL
& origin
) {
322 bool was_called
= false;
323 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
324 storage()->DeleteRegistration(
325 registration_id
, origin
, MakeStatusCallback(&was_called
, &result
));
326 EXPECT_FALSE(was_called
); // always async
327 base::RunLoop().RunUntilIdle();
328 EXPECT_TRUE(was_called
);
332 void GetAllRegistrations(
333 std::vector
<ServiceWorkerRegistrationInfo
>* registrations
) {
334 bool was_called
= false;
335 storage()->GetAllRegistrations(
336 MakeGetRegistrationsCallback(&was_called
, registrations
));
337 EXPECT_FALSE(was_called
); // always async
338 base::RunLoop().RunUntilIdle();
339 EXPECT_TRUE(was_called
);
342 void GetRegistrationsForOrigin(
344 std::vector
<ServiceWorkerRegistrationInfo
>* registrations
) {
345 bool was_called
= false;
346 storage()->GetRegistrationsForOrigin(
348 MakeGetRegistrationsCallback(&was_called
, registrations
));
349 EXPECT_FALSE(was_called
); // always async
350 base::RunLoop().RunUntilIdle();
351 EXPECT_TRUE(was_called
);
354 ServiceWorkerStatusCode
GetUserData(
355 int64 registration_id
,
356 const std::string
& key
,
358 bool was_called
= false;
359 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
360 storage()->GetUserData(
361 registration_id
, key
,
362 base::Bind(&GetUserDataCallback
, &was_called
, data
, &result
));
363 EXPECT_FALSE(was_called
); // always async
364 base::RunLoop().RunUntilIdle();
365 EXPECT_TRUE(was_called
);
369 ServiceWorkerStatusCode
StoreUserData(
370 int64 registration_id
,
372 const std::string
& key
,
373 const std::string
& data
) {
374 bool was_called
= false;
375 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
376 storage()->StoreUserData(
377 registration_id
, origin
, key
, data
,
378 MakeStatusCallback(&was_called
, &result
));
379 EXPECT_FALSE(was_called
); // always async
380 base::RunLoop().RunUntilIdle();
381 EXPECT_TRUE(was_called
);
385 ServiceWorkerStatusCode
ClearUserData(
386 int64 registration_id
,
387 const std::string
& key
) {
388 bool was_called
= false;
389 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
390 storage()->ClearUserData(
391 registration_id
, key
, MakeStatusCallback(&was_called
, &result
));
392 EXPECT_FALSE(was_called
); // always async
393 base::RunLoop().RunUntilIdle();
394 EXPECT_TRUE(was_called
);
398 ServiceWorkerStatusCode
GetUserDataForAllRegistrations(
399 const std::string
& key
,
400 std::vector
<std::pair
<int64
, std::string
>>* data
) {
401 bool was_called
= false;
402 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
403 storage()->GetUserDataForAllRegistrations(
404 key
, base::Bind(&GetUserDataForAllRegistrationsCallback
, &was_called
,
406 EXPECT_FALSE(was_called
); // always async
407 base::RunLoop().RunUntilIdle();
408 EXPECT_TRUE(was_called
);
412 ServiceWorkerStatusCode
UpdateToActiveState(
413 scoped_refptr
<ServiceWorkerRegistration
> registration
) {
414 bool was_called
= false;
415 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
416 storage()->UpdateToActiveState(registration
.get(),
417 MakeStatusCallback(&was_called
, &result
));
418 EXPECT_FALSE(was_called
); // always async
419 base::RunLoop().RunUntilIdle();
420 EXPECT_TRUE(was_called
);
424 void UpdateLastUpdateCheckTime(ServiceWorkerRegistration
* registration
) {
425 storage()->UpdateLastUpdateCheckTime(registration
);
426 base::RunLoop().RunUntilIdle();
429 ServiceWorkerStatusCode
FindRegistrationForDocument(
430 const GURL
& document_url
,
431 scoped_refptr
<ServiceWorkerRegistration
>* registration
) {
432 bool was_called
= false;
433 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
434 storage()->FindRegistrationForDocument(
435 document_url
, MakeFindCallback(&was_called
, &result
, registration
));
436 base::RunLoop().RunUntilIdle();
437 EXPECT_TRUE(was_called
);
441 ServiceWorkerStatusCode
FindRegistrationForPattern(
443 scoped_refptr
<ServiceWorkerRegistration
>* registration
) {
444 bool was_called
= false;
445 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
446 storage()->FindRegistrationForPattern(
447 scope
, MakeFindCallback(&was_called
, &result
, registration
));
448 EXPECT_FALSE(was_called
); // always async
449 base::RunLoop().RunUntilIdle();
450 EXPECT_TRUE(was_called
);
454 ServiceWorkerStatusCode
FindRegistrationForId(
455 int64 registration_id
,
457 scoped_refptr
<ServiceWorkerRegistration
>* registration
) {
458 bool was_called
= false;
459 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
460 storage()->FindRegistrationForId(
461 registration_id
, origin
,
462 MakeFindCallback(&was_called
, &result
, registration
));
463 base::RunLoop().RunUntilIdle();
464 EXPECT_TRUE(was_called
);
468 ServiceWorkerStatusCode
FindRegistrationForIdOnly(
469 int64 registration_id
,
470 scoped_refptr
<ServiceWorkerRegistration
>* registration
) {
471 bool was_called
= false;
472 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
473 storage()->FindRegistrationForIdOnly(
474 registration_id
, MakeFindCallback(&was_called
, &result
, registration
));
475 base::RunLoop().RunUntilIdle();
476 EXPECT_TRUE(was_called
);
480 scoped_ptr
<ServiceWorkerContextCore
> context_
;
481 base::WeakPtr
<ServiceWorkerContextCore
> context_ptr_
;
482 TestBrowserThreadBundle browser_thread_bundle_
;
485 TEST_F(ServiceWorkerStorageTest
, StoreFindUpdateDeleteRegistration
) {
486 const GURL
kScope("http://www.test.not/scope/");
487 const GURL
kScript("http://www.test.not/script.js");
488 const GURL
kDocumentUrl("http://www.test.not/scope/document.html");
489 const GURL
kResource1("http://www.test.not/scope/resource1.js");
490 const int64 kResource1Size
= 1591234;
491 const GURL
kResource2("http://www.test.not/scope/resource2.js");
492 const int64 kResource2Size
= 51;
493 const int64 kRegistrationId
= 0;
494 const int64 kVersionId
= 0;
495 const base::Time kToday
= base::Time::Now();
496 const base::Time kYesterday
= kToday
- base::TimeDelta::FromDays(1);
498 scoped_refptr
<ServiceWorkerRegistration
> found_registration
;
500 // We shouldn't find anything without having stored anything.
501 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
502 FindRegistrationForDocument(kDocumentUrl
, &found_registration
));
503 EXPECT_FALSE(found_registration
.get());
505 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
506 FindRegistrationForPattern(kScope
, &found_registration
));
507 EXPECT_FALSE(found_registration
.get());
509 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
510 FindRegistrationForId(
511 kRegistrationId
, kScope
.GetOrigin(), &found_registration
));
512 EXPECT_FALSE(found_registration
.get());
514 std::vector
<ServiceWorkerDatabase::ResourceRecord
> resources
;
516 ServiceWorkerDatabase::ResourceRecord(1, kResource1
, kResource1Size
));
518 ServiceWorkerDatabase::ResourceRecord(2, kResource2
, kResource2Size
));
521 scoped_refptr
<ServiceWorkerRegistration
> live_registration
=
522 new ServiceWorkerRegistration(
523 kScope
, kRegistrationId
, context_ptr_
);
524 scoped_refptr
<ServiceWorkerVersion
> live_version
=
525 new ServiceWorkerVersion(
526 live_registration
.get(), kScript
, kVersionId
, context_ptr_
);
527 live_version
->SetStatus(ServiceWorkerVersion::INSTALLED
);
528 live_version
->script_cache_map()->SetResources(resources
);
529 live_registration
->SetWaitingVersion(live_version
.get());
530 live_registration
->set_last_update_check(kYesterday
);
531 EXPECT_EQ(SERVICE_WORKER_OK
,
532 StoreRegistration(live_registration
, live_version
));
534 // Now we should find it and get the live ptr back immediately.
535 EXPECT_EQ(SERVICE_WORKER_OK
,
536 FindRegistrationForDocument(kDocumentUrl
, &found_registration
));
537 EXPECT_EQ(live_registration
, found_registration
);
538 EXPECT_EQ(kResource1Size
+ kResource2Size
,
539 live_registration
->resources_total_size_bytes());
540 EXPECT_EQ(kResource1Size
+ kResource2Size
,
541 found_registration
->resources_total_size_bytes());
542 found_registration
= NULL
;
544 // But FindRegistrationForPattern is always async.
545 EXPECT_EQ(SERVICE_WORKER_OK
,
546 FindRegistrationForPattern(kScope
, &found_registration
));
547 EXPECT_EQ(live_registration
, found_registration
);
548 found_registration
= NULL
;
550 // Can be found by id too.
551 EXPECT_EQ(SERVICE_WORKER_OK
,
552 FindRegistrationForId(
553 kRegistrationId
, kScope
.GetOrigin(), &found_registration
));
554 ASSERT_TRUE(found_registration
.get());
555 EXPECT_EQ(kRegistrationId
, found_registration
->id());
556 EXPECT_EQ(live_registration
, found_registration
);
557 found_registration
= NULL
;
559 // Can be found by just the id too.
560 EXPECT_EQ(SERVICE_WORKER_OK
,
561 FindRegistrationForIdOnly(kRegistrationId
, &found_registration
));
562 ASSERT_TRUE(found_registration
.get());
563 EXPECT_EQ(kRegistrationId
, found_registration
->id());
564 EXPECT_EQ(live_registration
, found_registration
);
565 found_registration
= NULL
;
567 // Drop the live registration, but keep the version live.
568 live_registration
= NULL
;
570 // Now FindRegistrationForDocument should be async.
571 EXPECT_EQ(SERVICE_WORKER_OK
,
572 FindRegistrationForDocument(kDocumentUrl
, &found_registration
));
573 ASSERT_TRUE(found_registration
.get());
574 EXPECT_EQ(kRegistrationId
, found_registration
->id());
575 EXPECT_TRUE(found_registration
->HasOneRef());
577 // Check that sizes are populated correctly
578 EXPECT_EQ(live_version
.get(), found_registration
->waiting_version());
579 EXPECT_EQ(kResource1Size
+ kResource2Size
,
580 found_registration
->resources_total_size_bytes());
581 std::vector
<ServiceWorkerRegistrationInfo
> all_registrations
;
582 GetAllRegistrations(&all_registrations
);
583 EXPECT_EQ(1u, all_registrations
.size());
584 ServiceWorkerRegistrationInfo info
= all_registrations
[0];
585 EXPECT_EQ(kResource1Size
+ kResource2Size
, info
.stored_version_size_bytes
);
586 all_registrations
.clear();
588 // Finding by origin should provide the same result iif origin is kScope.
589 std::vector
<ServiceWorkerRegistrationInfo
> registrations_origin
;
590 GetRegistrationsForOrigin(kScope
.GetOrigin(), ®istrations_origin
);
591 EXPECT_EQ(1u, registrations_origin
.size());
592 registrations_origin
.clear();
594 GetRegistrationsForOrigin(
595 GURL("http://example.com/").GetOrigin(),
596 ®istrations_origin
);
597 EXPECT_TRUE(registrations_origin
.empty());
599 found_registration
= NULL
;
601 // Drop the live version too.
604 // And FindRegistrationForPattern is always async.
605 EXPECT_EQ(SERVICE_WORKER_OK
,
606 FindRegistrationForPattern(kScope
, &found_registration
));
607 ASSERT_TRUE(found_registration
.get());
608 EXPECT_EQ(kRegistrationId
, found_registration
->id());
609 EXPECT_TRUE(found_registration
->HasOneRef());
610 EXPECT_FALSE(found_registration
->active_version());
611 ASSERT_TRUE(found_registration
->waiting_version());
612 EXPECT_EQ(kYesterday
, found_registration
->last_update_check());
613 EXPECT_EQ(ServiceWorkerVersion::INSTALLED
,
614 found_registration
->waiting_version()->status());
616 // Update to active and update the last check time.
617 scoped_refptr
<ServiceWorkerVersion
> temp_version
=
618 found_registration
->waiting_version();
619 temp_version
->SetStatus(ServiceWorkerVersion::ACTIVATED
);
620 found_registration
->SetActiveVersion(temp_version
.get());
622 EXPECT_EQ(SERVICE_WORKER_OK
, UpdateToActiveState(found_registration
));
623 found_registration
->set_last_update_check(kToday
);
624 UpdateLastUpdateCheckTime(found_registration
.get());
626 found_registration
= NULL
;
628 // Trying to update a unstored registration to active should fail.
629 scoped_refptr
<ServiceWorkerRegistration
> unstored_registration
=
630 new ServiceWorkerRegistration(
631 kScope
, kRegistrationId
+ 1, context_ptr_
);
632 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
633 UpdateToActiveState(unstored_registration
));
634 unstored_registration
= NULL
;
636 // The Find methods should return a registration with an active version
637 // and the expected update time.
638 EXPECT_EQ(SERVICE_WORKER_OK
,
639 FindRegistrationForDocument(kDocumentUrl
, &found_registration
));
640 ASSERT_TRUE(found_registration
.get());
641 EXPECT_EQ(kRegistrationId
, found_registration
->id());
642 EXPECT_TRUE(found_registration
->HasOneRef());
643 EXPECT_FALSE(found_registration
->waiting_version());
644 ASSERT_TRUE(found_registration
->active_version());
645 EXPECT_EQ(ServiceWorkerVersion::ACTIVATED
,
646 found_registration
->active_version()->status());
647 EXPECT_EQ(kToday
, found_registration
->last_update_check());
649 // Delete from storage but with a instance still live.
650 EXPECT_TRUE(context_
->GetLiveVersion(kRegistrationId
));
651 EXPECT_EQ(SERVICE_WORKER_OK
,
652 DeleteRegistration(kRegistrationId
, kScope
.GetOrigin()));
653 EXPECT_TRUE(context_
->GetLiveVersion(kRegistrationId
));
655 // Should no longer be found.
656 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
657 FindRegistrationForId(
658 kRegistrationId
, kScope
.GetOrigin(), &found_registration
));
659 EXPECT_FALSE(found_registration
.get());
660 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
661 FindRegistrationForIdOnly(kRegistrationId
, &found_registration
));
662 EXPECT_FALSE(found_registration
.get());
664 // Deleting an unstored registration should succeed.
665 EXPECT_EQ(SERVICE_WORKER_OK
,
666 DeleteRegistration(kRegistrationId
+ 1, kScope
.GetOrigin()));
669 TEST_F(ServiceWorkerStorageTest
, InstallingRegistrationsAreFindable
) {
670 const GURL
kScope("http://www.test.not/scope/");
671 const GURL
kScript("http://www.test.not/script.js");
672 const GURL
kDocumentUrl("http://www.test.not/scope/document.html");
673 const int64 kRegistrationId
= 0;
674 const int64 kVersionId
= 0;
676 scoped_refptr
<ServiceWorkerRegistration
> found_registration
;
678 // Create an unstored registration.
679 scoped_refptr
<ServiceWorkerRegistration
> live_registration
=
680 new ServiceWorkerRegistration(
681 kScope
, kRegistrationId
, context_ptr_
);
682 scoped_refptr
<ServiceWorkerVersion
> live_version
=
683 new ServiceWorkerVersion(
684 live_registration
.get(), kScript
, kVersionId
, context_ptr_
);
685 live_version
->SetStatus(ServiceWorkerVersion::INSTALLING
);
686 live_registration
->SetWaitingVersion(live_version
.get());
688 // Should not be findable, including by GetAllRegistrations.
689 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
690 FindRegistrationForId(
691 kRegistrationId
, kScope
.GetOrigin(), &found_registration
));
692 EXPECT_FALSE(found_registration
.get());
694 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
695 FindRegistrationForIdOnly(kRegistrationId
, &found_registration
));
696 EXPECT_FALSE(found_registration
.get());
698 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
699 FindRegistrationForDocument(kDocumentUrl
, &found_registration
));
700 EXPECT_FALSE(found_registration
.get());
702 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
703 FindRegistrationForPattern(kScope
, &found_registration
));
704 EXPECT_FALSE(found_registration
.get());
706 std::vector
<ServiceWorkerRegistrationInfo
> all_registrations
;
707 GetAllRegistrations(&all_registrations
);
708 EXPECT_TRUE(all_registrations
.empty());
710 std::vector
<ServiceWorkerRegistrationInfo
> registrations_origin
;
711 GetRegistrationsForOrigin(kScope
.GetOrigin(), ®istrations_origin
);
712 EXPECT_TRUE(registrations_origin
.empty());
714 GetRegistrationsForOrigin(
715 GURL("http://example.com/").GetOrigin(),
716 ®istrations_origin
);
717 EXPECT_TRUE(registrations_origin
.empty());
719 // Notify storage of it being installed.
720 storage()->NotifyInstallingRegistration(live_registration
.get());
722 // Now should be findable.
723 EXPECT_EQ(SERVICE_WORKER_OK
,
724 FindRegistrationForId(
725 kRegistrationId
, kScope
.GetOrigin(), &found_registration
));
726 EXPECT_EQ(live_registration
, found_registration
);
727 found_registration
= NULL
;
729 EXPECT_EQ(SERVICE_WORKER_OK
,
730 FindRegistrationForIdOnly(kRegistrationId
, &found_registration
));
731 EXPECT_EQ(live_registration
, found_registration
);
732 found_registration
= NULL
;
734 EXPECT_EQ(SERVICE_WORKER_OK
,
735 FindRegistrationForDocument(kDocumentUrl
, &found_registration
));
736 EXPECT_EQ(live_registration
, found_registration
);
737 found_registration
= NULL
;
739 EXPECT_EQ(SERVICE_WORKER_OK
,
740 FindRegistrationForPattern(kScope
, &found_registration
));
741 EXPECT_EQ(live_registration
, found_registration
);
742 found_registration
= NULL
;
744 GetAllRegistrations(&all_registrations
);
745 EXPECT_EQ(1u, all_registrations
.size());
746 all_registrations
.clear();
748 // Finding by origin should provide the same result iif origin is kScope.
749 GetRegistrationsForOrigin(kScope
.GetOrigin(), ®istrations_origin
);
750 EXPECT_EQ(1u, registrations_origin
.size());
751 registrations_origin
.clear();
753 GetRegistrationsForOrigin(
754 GURL("http://example.com/").GetOrigin(),
755 ®istrations_origin
);
756 EXPECT_TRUE(registrations_origin
.empty());
758 // Notify storage of installation no longer happening.
759 storage()->NotifyDoneInstallingRegistration(
760 live_registration
.get(), NULL
, SERVICE_WORKER_OK
);
762 // Once again, should not be findable.
763 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
764 FindRegistrationForId(
765 kRegistrationId
, kScope
.GetOrigin(), &found_registration
));
766 EXPECT_FALSE(found_registration
.get());
768 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
769 FindRegistrationForIdOnly(kRegistrationId
, &found_registration
));
770 EXPECT_FALSE(found_registration
.get());
772 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
773 FindRegistrationForDocument(kDocumentUrl
, &found_registration
));
774 EXPECT_FALSE(found_registration
.get());
776 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
777 FindRegistrationForPattern(kScope
, &found_registration
));
778 EXPECT_FALSE(found_registration
.get());
780 GetAllRegistrations(&all_registrations
);
781 EXPECT_TRUE(all_registrations
.empty());
783 GetRegistrationsForOrigin(kScope
.GetOrigin(), ®istrations_origin
);
784 EXPECT_TRUE(registrations_origin
.empty());
786 GetRegistrationsForOrigin(
787 GURL("http://example.com/").GetOrigin(),
788 ®istrations_origin
);
789 EXPECT_TRUE(registrations_origin
.empty());
792 TEST_F(ServiceWorkerStorageTest
, StoreUserData
) {
793 const GURL
kScope("http://www.test.not/scope/");
794 const GURL
kScript("http://www.test.not/script.js");
795 const int64 kRegistrationId
= 0;
796 const int64 kVersionId
= 0;
800 // Store a registration.
801 scoped_refptr
<ServiceWorkerRegistration
> live_registration
=
802 new ServiceWorkerRegistration(
803 kScope
, kRegistrationId
, context_ptr_
);
804 scoped_refptr
<ServiceWorkerVersion
> live_version
=
805 new ServiceWorkerVersion(
806 live_registration
.get(), kScript
, kVersionId
, context_ptr_
);
807 live_version
->SetStatus(ServiceWorkerVersion::INSTALLED
);
808 live_registration
->SetWaitingVersion(live_version
.get());
809 EXPECT_EQ(SERVICE_WORKER_OK
,
810 StoreRegistration(live_registration
, live_version
));
812 // Store user data associated with the registration.
813 std::string data_out
;
814 EXPECT_EQ(SERVICE_WORKER_OK
,
815 StoreUserData(kRegistrationId
, kScope
.GetOrigin(), "key", "data"));
816 EXPECT_EQ(SERVICE_WORKER_OK
, GetUserData(kRegistrationId
, "key", &data_out
));
817 EXPECT_EQ("data", data_out
);
818 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
819 GetUserData(kRegistrationId
, "unknown_key", &data_out
));
820 std::vector
<std::pair
<int64
, std::string
>> data_list_out
;
821 EXPECT_EQ(SERVICE_WORKER_OK
,
822 GetUserDataForAllRegistrations("key", &data_list_out
));
823 ASSERT_EQ(1u, data_list_out
.size());
824 EXPECT_EQ(kRegistrationId
, data_list_out
[0].first
);
825 EXPECT_EQ("data", data_list_out
[0].second
);
826 data_list_out
.clear();
827 EXPECT_EQ(SERVICE_WORKER_OK
,
828 GetUserDataForAllRegistrations("unknown_key", &data_list_out
));
829 EXPECT_EQ(0u, data_list_out
.size());
830 EXPECT_EQ(SERVICE_WORKER_OK
, ClearUserData(kRegistrationId
, "key"));
831 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
832 GetUserData(kRegistrationId
, "key", &data_out
));
834 // User data should be deleted when the associated registration is deleted.
835 ASSERT_EQ(SERVICE_WORKER_OK
,
836 StoreUserData(kRegistrationId
, kScope
.GetOrigin(), "key", "data"));
837 ASSERT_EQ(SERVICE_WORKER_OK
,
838 GetUserData(kRegistrationId
, "key", &data_out
));
839 ASSERT_EQ("data", data_out
);
841 EXPECT_EQ(SERVICE_WORKER_OK
,
842 DeleteRegistration(kRegistrationId
, kScope
.GetOrigin()));
843 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
844 GetUserData(kRegistrationId
, "key", &data_out
));
845 data_list_out
.clear();
846 EXPECT_EQ(SERVICE_WORKER_OK
,
847 GetUserDataForAllRegistrations("key", &data_list_out
));
848 EXPECT_EQ(0u, data_list_out
.size());
850 // Data access with an invalid registration id should be failed.
851 EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED
,
852 StoreUserData(kInvalidServiceWorkerRegistrationId
,
853 kScope
.GetOrigin(), "key", "data"));
854 EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED
,
855 GetUserData(kInvalidServiceWorkerRegistrationId
, "key", &data_out
));
856 EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED
,
857 ClearUserData(kInvalidServiceWorkerRegistrationId
, "key"));
859 // Data access with an empty key should be failed.
860 EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED
,
862 kRegistrationId
, kScope
.GetOrigin(), std::string(), "data"));
863 EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED
,
864 GetUserData(kRegistrationId
, std::string(), &data_out
));
865 EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED
,
866 ClearUserData(kRegistrationId
, std::string()));
867 data_list_out
.clear();
868 EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED
,
869 GetUserDataForAllRegistrations(std::string(), &data_list_out
));
872 class ServiceWorkerResourceStorageTest
: public ServiceWorkerStorageTest
{
874 void SetUp() override
{
875 ServiceWorkerStorageTest::SetUp();
877 storage()->LazyInitialize(base::Bind(&base::DoNothing
));
878 base::RunLoop().RunUntilIdle();
879 scope_
= GURL("http://www.test.not/scope/");
880 script_
= GURL("http://www.test.not/script.js");
881 import_
= GURL("http://www.test.not/import.js");
882 document_url_
= GURL("http://www.test.not/scope/document.html");
883 registration_id_
= storage()->NewRegistrationId();
884 version_id_
= storage()->NewVersionId();
885 resource_id1_
= storage()->NewResourceId();
886 resource_id2_
= storage()->NewResourceId();
887 resource_id1_size_
= 239193;
888 resource_id2_size_
= 59923;
890 // Cons up a new registration+version with two script resources.
891 RegistrationData data
;
892 data
.registration_id
= registration_id_
;
894 data
.script
= script_
;
895 data
.version_id
= version_id_
;
896 data
.is_active
= false;
897 std::vector
<ResourceRecord
> resources
;
899 ResourceRecord(resource_id1_
, script_
, resource_id1_size_
));
901 ResourceRecord(resource_id2_
, import_
, resource_id2_size_
));
902 registration_
= storage()->GetOrCreateRegistration(data
, resources
);
903 registration_
->waiting_version()->SetStatus(ServiceWorkerVersion::NEW
);
905 // Add the resources ids to the uncommitted list.
906 storage()->StoreUncommittedResponseId(resource_id1_
);
907 storage()->StoreUncommittedResponseId(resource_id2_
);
908 base::RunLoop().RunUntilIdle();
909 std::set
<int64
> verify_ids
;
910 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
911 storage()->database_
->GetUncommittedResourceIds(&verify_ids
));
912 EXPECT_EQ(2u, verify_ids
.size());
914 // And dump something in the disk cache for them.
915 WriteBasicResponse(storage(), resource_id1_
);
916 WriteBasicResponse(storage(), resource_id2_
);
917 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, true));
918 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id2_
, true));
920 // Storing the registration/version should take the resources ids out
921 // of the uncommitted list.
924 StoreRegistration(registration_
, registration_
->waiting_version()));
926 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
927 storage()->database_
->GetUncommittedResourceIds(&verify_ids
));
928 EXPECT_TRUE(verify_ids
.empty());
936 int64 registration_id_
;
939 uint64 resource_id1_size_
;
941 uint64 resource_id2_size_
;
942 scoped_refptr
<ServiceWorkerRegistration
> registration_
;
945 class ServiceWorkerResourceStorageDiskTest
946 : public ServiceWorkerResourceStorageTest
{
948 void SetUp() override
{
949 ASSERT_TRUE(user_data_directory_
.CreateUniqueTempDir());
950 ServiceWorkerResourceStorageTest::SetUp();
953 base::FilePath
GetUserDataDirectory() override
{
954 return user_data_directory_
.path();
958 base::ScopedTempDir user_data_directory_
;
961 TEST_F(ServiceWorkerResourceStorageTest
,
962 WriteMetadataWithServiceWorkerResponseMetadataWriter
) {
963 const char kMetadata1
[] = "Test metadata";
964 const char kMetadata2
[] = "small";
965 int64 new_resource_id_
= storage()->NewResourceId();
966 // Writing metadata to nonexistent resoirce ID must fail.
967 EXPECT_GE(0, WriteResponseMetadata(storage(), new_resource_id_
, kMetadata1
));
969 // Check metadata is written.
970 EXPECT_EQ(static_cast<int>(strlen(kMetadata1
)),
971 WriteResponseMetadata(storage(), resource_id1_
, kMetadata1
));
972 EXPECT_TRUE(VerifyResponseMetadata(storage(), resource_id1_
, kMetadata1
));
973 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, true));
975 // Check metadata is written and truncated.
976 EXPECT_EQ(static_cast<int>(strlen(kMetadata2
)),
977 WriteResponseMetadata(storage(), resource_id1_
, kMetadata2
));
978 EXPECT_TRUE(VerifyResponseMetadata(storage(), resource_id1_
, kMetadata2
));
979 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, true));
981 // Check metadata is deleted.
982 EXPECT_EQ(0, WriteResponseMetadata(storage(), resource_id1_
, ""));
983 EXPECT_FALSE(VerifyResponseMetadata(storage(), resource_id1_
, ""));
984 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, true));
987 TEST_F(ServiceWorkerResourceStorageTest
,
988 WriteMetadataWithServiceWorkerScriptCacheMap
) {
989 const char kMetadata1
[] = "Test metadata";
990 const char kMetadata2
[] = "small";
991 ServiceWorkerVersion
* version
= registration_
->waiting_version();
992 EXPECT_TRUE(version
);
994 // Writing metadata to nonexistent URL must fail.
996 WriteMetadata(version
, GURL("http://www.test.not/nonexistent.js"),
998 // Clearing metadata of nonexistent URL must fail.
1000 ClearMetadata(version
, GURL("http://www.test.not/nonexistent.js")));
1002 // Check metadata is written.
1003 EXPECT_EQ(static_cast<int>(strlen(kMetadata1
)),
1004 WriteMetadata(version
, script_
, kMetadata1
));
1005 EXPECT_TRUE(VerifyResponseMetadata(storage(), resource_id1_
, kMetadata1
));
1006 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, true));
1008 // Check metadata is written and truncated.
1009 EXPECT_EQ(static_cast<int>(strlen(kMetadata2
)),
1010 WriteMetadata(version
, script_
, kMetadata2
));
1011 EXPECT_TRUE(VerifyResponseMetadata(storage(), resource_id1_
, kMetadata2
));
1012 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, true));
1014 // Check metadata is deleted.
1015 EXPECT_EQ(0, ClearMetadata(version
, script_
));
1016 EXPECT_FALSE(VerifyResponseMetadata(storage(), resource_id1_
, ""));
1017 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, true));
1020 TEST_F(ServiceWorkerResourceStorageTest
, DeleteRegistration_NoLiveVersion
) {
1021 bool was_called
= false;
1022 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
1023 std::set
<int64
> verify_ids
;
1025 registration_
->SetWaitingVersion(NULL
);
1026 registration_
= NULL
;
1028 // Deleting the registration should result in the resources being added to the
1029 // purgeable list and then doomed in the disk cache and removed from that
1031 storage()->DeleteRegistration(
1034 base::Bind(&VerifyPurgeableListStatusCallback
,
1035 base::Unretained(storage()->database_
.get()),
1039 base::RunLoop().RunUntilIdle();
1040 ASSERT_TRUE(was_called
);
1041 EXPECT_EQ(SERVICE_WORKER_OK
, result
);
1042 EXPECT_EQ(2u, verify_ids
.size());
1044 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1045 storage()->database_
->GetPurgeableResourceIds(&verify_ids
));
1046 EXPECT_TRUE(verify_ids
.empty());
1048 EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id1_
, false));
1049 EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id2_
, false));
1052 TEST_F(ServiceWorkerResourceStorageTest
, DeleteRegistration_WaitingVersion
) {
1053 bool was_called
= false;
1054 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
1055 std::set
<int64
> verify_ids
;
1057 // Deleting the registration should result in the resources being added to the
1058 // purgeable list and then doomed in the disk cache and removed from that
1060 storage()->DeleteRegistration(
1061 registration_
->id(),
1063 base::Bind(&VerifyPurgeableListStatusCallback
,
1064 base::Unretained(storage()->database_
.get()),
1068 base::RunLoop().RunUntilIdle();
1069 ASSERT_TRUE(was_called
);
1070 EXPECT_EQ(SERVICE_WORKER_OK
, result
);
1071 EXPECT_EQ(2u, verify_ids
.size());
1073 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1074 storage()->database_
->GetPurgeableResourceIds(&verify_ids
));
1075 EXPECT_EQ(2u, verify_ids
.size());
1077 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, false));
1078 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id2_
, false));
1080 // Doom the version, now it happens.
1081 registration_
->waiting_version()->Doom();
1082 base::RunLoop().RunUntilIdle();
1083 EXPECT_EQ(SERVICE_WORKER_OK
, result
);
1084 EXPECT_EQ(2u, verify_ids
.size());
1086 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1087 storage()->database_
->GetPurgeableResourceIds(&verify_ids
));
1088 EXPECT_TRUE(verify_ids
.empty());
1090 EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id1_
, false));
1091 EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id2_
, false));
1094 TEST_F(ServiceWorkerResourceStorageTest
, DeleteRegistration_ActiveVersion
) {
1095 // Promote the worker to active and add a controllee.
1096 registration_
->SetActiveVersion(registration_
->waiting_version());
1097 storage()->UpdateToActiveState(
1098 registration_
.get(), base::Bind(&ServiceWorkerUtils::NoOpStatusCallback
));
1099 scoped_ptr
<ServiceWorkerProviderHost
> host(new ServiceWorkerProviderHost(
1100 33 /* dummy render process id */, MSG_ROUTING_NONE
,
1101 1 /* dummy provider_id */, SERVICE_WORKER_PROVIDER_FOR_WINDOW
,
1102 context_
->AsWeakPtr(), NULL
));
1103 registration_
->active_version()->AddControllee(host
.get());
1105 bool was_called
= false;
1106 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
1107 std::set
<int64
> verify_ids
;
1109 // Deleting the registration should move the resources to the purgeable list
1110 // but keep them available.
1111 storage()->DeleteRegistration(
1112 registration_
->id(),
1114 base::Bind(&VerifyPurgeableListStatusCallback
,
1115 base::Unretained(storage()->database_
.get()),
1119 base::RunLoop().RunUntilIdle();
1120 ASSERT_TRUE(was_called
);
1121 EXPECT_EQ(SERVICE_WORKER_OK
, result
);
1122 EXPECT_EQ(2u, verify_ids
.size());
1124 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1125 storage()->database_
->GetPurgeableResourceIds(&verify_ids
));
1126 EXPECT_EQ(2u, verify_ids
.size());
1128 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, true));
1129 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id2_
, true));
1131 // Removing the controllee should cause the resources to be deleted.
1132 registration_
->active_version()->RemoveControllee(host
.get());
1133 registration_
->active_version()->Doom();
1134 base::RunLoop().RunUntilIdle();
1136 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1137 storage()->database_
->GetPurgeableResourceIds(&verify_ids
));
1138 EXPECT_TRUE(verify_ids
.empty());
1140 EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id1_
, false));
1141 EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id2_
, false));
1144 TEST_F(ServiceWorkerResourceStorageDiskTest
, CleanupOnRestart
) {
1145 // Promote the worker to active and add a controllee.
1146 registration_
->SetActiveVersion(registration_
->waiting_version());
1147 registration_
->SetWaitingVersion(NULL
);
1148 storage()->UpdateToActiveState(
1149 registration_
.get(), base::Bind(&ServiceWorkerUtils::NoOpStatusCallback
));
1150 scoped_ptr
<ServiceWorkerProviderHost
> host(new ServiceWorkerProviderHost(
1151 33 /* dummy render process id */, MSG_ROUTING_NONE
,
1152 1 /* dummy provider_id */, SERVICE_WORKER_PROVIDER_FOR_WINDOW
,
1153 context_
->AsWeakPtr(), NULL
));
1154 registration_
->active_version()->AddControllee(host
.get());
1156 bool was_called
= false;
1157 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
1158 std::set
<int64
> verify_ids
;
1160 // Deleting the registration should move the resources to the purgeable list
1161 // but keep them available.
1162 storage()->DeleteRegistration(
1163 registration_
->id(),
1165 base::Bind(&VerifyPurgeableListStatusCallback
,
1166 base::Unretained(storage()->database_
.get()),
1170 base::RunLoop().RunUntilIdle();
1171 ASSERT_TRUE(was_called
);
1172 EXPECT_EQ(SERVICE_WORKER_OK
, result
);
1173 EXPECT_EQ(2u, verify_ids
.size());
1175 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1176 storage()->database_
->GetPurgeableResourceIds(&verify_ids
));
1177 EXPECT_EQ(2u, verify_ids
.size());
1179 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, true));
1180 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id2_
, true));
1182 // Also add an uncommitted resource.
1183 int64 kStaleUncommittedResourceId
= storage()->NewResourceId();
1184 storage()->StoreUncommittedResponseId(kStaleUncommittedResourceId
);
1185 base::RunLoop().RunUntilIdle();
1187 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1188 storage()->database_
->GetUncommittedResourceIds(&verify_ids
));
1189 EXPECT_EQ(1u, verify_ids
.size());
1190 WriteBasicResponse(storage(), kStaleUncommittedResourceId
);
1192 VerifyBasicResponse(storage(), kStaleUncommittedResourceId
, true));
1194 // Simulate browser shutdown. The purgeable and uncommitted resources are now
1197 scoped_ptr
<ServiceWorkerDatabaseTaskManager
> database_task_manager(
1198 new MockServiceWorkerDatabaseTaskManager(
1199 base::ThreadTaskRunnerHandle::Get()));
1201 new ServiceWorkerContextCore(GetUserDataDirectory(),
1202 database_task_manager
.Pass(),
1203 base::ThreadTaskRunnerHandle::Get(),
1208 storage()->LazyInitialize(base::Bind(&base::DoNothing
));
1209 base::RunLoop().RunUntilIdle();
1211 // Store a new uncommitted resource. This triggers stale resource cleanup.
1212 int64 kNewResourceId
= storage()->NewResourceId();
1213 WriteBasicResponse(storage(), kNewResourceId
);
1214 storage()->StoreUncommittedResponseId(kNewResourceId
);
1215 base::RunLoop().RunUntilIdle();
1217 // The stale resources should be purged, but the new resource should persist.
1219 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1220 storage()->database_
->GetUncommittedResourceIds(&verify_ids
));
1221 ASSERT_EQ(1u, verify_ids
.size());
1222 EXPECT_EQ(kNewResourceId
, *verify_ids
.begin());
1224 // Purging resources needs interactions with SimpleCache's worker thread,
1225 // so single RunUntilIdle() call may not be sufficient.
1226 while (storage()->is_purge_pending_
)
1227 base::RunLoop().RunUntilIdle();
1230 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1231 storage()->database_
->GetPurgeableResourceIds(&verify_ids
));
1232 EXPECT_TRUE(verify_ids
.empty());
1233 EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id1_
, false));
1234 EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id2_
, false));
1236 VerifyBasicResponse(storage(), kStaleUncommittedResourceId
, false));
1237 EXPECT_TRUE(VerifyBasicResponse(storage(), kNewResourceId
, true));
1240 TEST_F(ServiceWorkerResourceStorageTest
, UpdateRegistration
) {
1241 // Promote the worker to active worker and add a controllee.
1242 registration_
->SetActiveVersion(registration_
->waiting_version());
1243 storage()->UpdateToActiveState(
1244 registration_
.get(), base::Bind(&ServiceWorkerUtils::NoOpStatusCallback
));
1245 scoped_ptr
<ServiceWorkerProviderHost
> host(new ServiceWorkerProviderHost(
1246 33 /* dummy render process id */, MSG_ROUTING_NONE
,
1247 1 /* dummy provider_id */, SERVICE_WORKER_PROVIDER_FOR_WINDOW
,
1248 context_
->AsWeakPtr(), NULL
));
1249 registration_
->active_version()->AddControllee(host
.get());
1251 bool was_called
= false;
1252 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
1253 std::set
<int64
> verify_ids
;
1255 // Make an updated registration.
1256 scoped_refptr
<ServiceWorkerVersion
> live_version
= new ServiceWorkerVersion(
1257 registration_
.get(), script_
, storage()->NewVersionId(), context_ptr_
);
1258 live_version
->SetStatus(ServiceWorkerVersion::NEW
);
1259 registration_
->SetWaitingVersion(live_version
.get());
1261 // Writing the registration should move the old version's resources to the
1262 // purgeable list but keep them available.
1263 storage()->StoreRegistration(
1264 registration_
.get(),
1265 registration_
->waiting_version(),
1266 base::Bind(&VerifyPurgeableListStatusCallback
,
1267 base::Unretained(storage()->database_
.get()),
1271 base::RunLoop().RunUntilIdle();
1272 ASSERT_TRUE(was_called
);
1273 EXPECT_EQ(SERVICE_WORKER_OK
, result
);
1274 EXPECT_EQ(2u, verify_ids
.size());
1276 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1277 storage()->database_
->GetPurgeableResourceIds(&verify_ids
));
1278 EXPECT_EQ(2u, verify_ids
.size());
1280 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, false));
1281 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id2_
, false));
1283 // Removing the controllee should cause the old version's resources to be
1285 registration_
->active_version()->RemoveControllee(host
.get());
1286 registration_
->active_version()->Doom();
1287 base::RunLoop().RunUntilIdle();
1289 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1290 storage()->database_
->GetPurgeableResourceIds(&verify_ids
));
1291 EXPECT_TRUE(verify_ids
.empty());
1293 EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id1_
, false));
1294 EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id2_
, false));
1297 TEST_F(ServiceWorkerStorageTest
, FindRegistration_LongestScopeMatch
) {
1298 const GURL
kDocumentUrl("http://www.example.com/scope/foo");
1299 scoped_refptr
<ServiceWorkerRegistration
> found_registration
;
1301 // Registration for "/scope/".
1302 const GURL
kScope1("http://www.example.com/scope/");
1303 const GURL
kScript1("http://www.example.com/script1.js");
1304 const int64 kRegistrationId1
= 1;
1305 const int64 kVersionId1
= 1;
1306 scoped_refptr
<ServiceWorkerRegistration
> live_registration1
=
1307 new ServiceWorkerRegistration(
1308 kScope1
, kRegistrationId1
, context_ptr_
);
1309 scoped_refptr
<ServiceWorkerVersion
> live_version1
=
1310 new ServiceWorkerVersion(
1311 live_registration1
.get(), kScript1
, kVersionId1
, context_ptr_
);
1312 live_version1
->SetStatus(ServiceWorkerVersion::INSTALLED
);
1313 live_registration1
->SetWaitingVersion(live_version1
.get());
1315 // Registration for "/scope/foo".
1316 const GURL
kScope2("http://www.example.com/scope/foo");
1317 const GURL
kScript2("http://www.example.com/script2.js");
1318 const int64 kRegistrationId2
= 2;
1319 const int64 kVersionId2
= 2;
1320 scoped_refptr
<ServiceWorkerRegistration
> live_registration2
=
1321 new ServiceWorkerRegistration(
1322 kScope2
, kRegistrationId2
, context_ptr_
);
1323 scoped_refptr
<ServiceWorkerVersion
> live_version2
=
1324 new ServiceWorkerVersion(
1325 live_registration2
.get(), kScript2
, kVersionId2
, context_ptr_
);
1326 live_version2
->SetStatus(ServiceWorkerVersion::INSTALLED
);
1327 live_registration2
->SetWaitingVersion(live_version2
.get());
1329 // Registration for "/scope/foobar".
1330 const GURL
kScope3("http://www.example.com/scope/foobar");
1331 const GURL
kScript3("http://www.example.com/script3.js");
1332 const int64 kRegistrationId3
= 3;
1333 const int64 kVersionId3
= 3;
1334 scoped_refptr
<ServiceWorkerRegistration
> live_registration3
=
1335 new ServiceWorkerRegistration(
1336 kScope3
, kRegistrationId3
, context_ptr_
);
1337 scoped_refptr
<ServiceWorkerVersion
> live_version3
=
1338 new ServiceWorkerVersion(
1339 live_registration3
.get(), kScript3
, kVersionId3
, context_ptr_
);
1340 live_version3
->SetStatus(ServiceWorkerVersion::INSTALLED
);
1341 live_registration3
->SetWaitingVersion(live_version3
.get());
1343 // Notify storage of they being installed.
1344 storage()->NotifyInstallingRegistration(live_registration1
.get());
1345 storage()->NotifyInstallingRegistration(live_registration2
.get());
1346 storage()->NotifyInstallingRegistration(live_registration3
.get());
1348 // Find a registration among installing ones.
1349 EXPECT_EQ(SERVICE_WORKER_OK
,
1350 FindRegistrationForDocument(kDocumentUrl
, &found_registration
));
1351 EXPECT_EQ(live_registration2
, found_registration
);
1352 found_registration
= NULL
;
1354 // Store registrations.
1355 EXPECT_EQ(SERVICE_WORKER_OK
,
1356 StoreRegistration(live_registration1
, live_version1
));
1357 EXPECT_EQ(SERVICE_WORKER_OK
,
1358 StoreRegistration(live_registration2
, live_version2
));
1359 EXPECT_EQ(SERVICE_WORKER_OK
,
1360 StoreRegistration(live_registration3
, live_version3
));
1362 // Notify storage of installations no longer happening.
1363 storage()->NotifyDoneInstallingRegistration(
1364 live_registration1
.get(), NULL
, SERVICE_WORKER_OK
);
1365 storage()->NotifyDoneInstallingRegistration(
1366 live_registration2
.get(), NULL
, SERVICE_WORKER_OK
);
1367 storage()->NotifyDoneInstallingRegistration(
1368 live_registration3
.get(), NULL
, SERVICE_WORKER_OK
);
1370 // Find a registration among installed ones.
1371 EXPECT_EQ(SERVICE_WORKER_OK
,
1372 FindRegistrationForDocument(kDocumentUrl
, &found_registration
));
1373 EXPECT_EQ(live_registration2
, found_registration
);
1376 TEST_F(ServiceWorkerStorageTest
, CompareResources
) {
1377 // Compare two small responses containing the same data.
1378 WriteBasicResponse(storage(), 1);
1379 WriteBasicResponse(storage(), 2);
1380 ServiceWorkerStatusCode status
= static_cast<ServiceWorkerStatusCode
>(-1);
1381 bool are_equal
= false;
1382 storage()->CompareScriptResources(
1384 base::Bind(&OnCompareComplete
, &status
, &are_equal
));
1385 base::RunLoop().RunUntilIdle();
1386 EXPECT_EQ(SERVICE_WORKER_OK
, status
);
1387 EXPECT_TRUE(are_equal
);
1389 // Compare two small responses with different data.
1390 const char kHttpHeaders
[] = "HTTP/1.0 200 HONKYDORY\0\0";
1391 const char kHttpBody
[] = "Goodbye";
1392 std::string
headers(kHttpHeaders
, arraysize(kHttpHeaders
));
1393 WriteStringResponse(storage(), 3, headers
, std::string(kHttpBody
));
1394 status
= static_cast<ServiceWorkerStatusCode
>(-1);
1396 storage()->CompareScriptResources(
1398 base::Bind(&OnCompareComplete
, &status
, &are_equal
));
1399 base::RunLoop().RunUntilIdle();
1400 EXPECT_EQ(SERVICE_WORKER_OK
, status
);
1401 EXPECT_FALSE(are_equal
);
1403 // Compare two large responses with the same data.
1404 const int k32K
= 32 * 1024;
1405 WriteResponseOfSize(storage(), 4, 'a', k32K
);
1406 WriteResponseOfSize(storage(), 5, 'a', k32K
);
1407 status
= static_cast<ServiceWorkerStatusCode
>(-1);
1409 storage()->CompareScriptResources(
1411 base::Bind(&OnCompareComplete
, &status
, &are_equal
));
1412 base::RunLoop().RunUntilIdle();
1413 EXPECT_EQ(SERVICE_WORKER_OK
, status
);
1414 EXPECT_TRUE(are_equal
);
1416 // Compare a large and small response.
1417 status
= static_cast<ServiceWorkerStatusCode
>(-1);
1419 storage()->CompareScriptResources(
1421 base::Bind(&OnCompareComplete
, &status
, &are_equal
));
1422 base::RunLoop().RunUntilIdle();
1423 EXPECT_EQ(SERVICE_WORKER_OK
, status
);
1424 EXPECT_FALSE(are_equal
);
1426 // Compare two large responses with different data.
1427 WriteResponseOfSize(storage(), 6, 'b', k32K
);
1428 status
= static_cast<ServiceWorkerStatusCode
>(-1);
1430 storage()->CompareScriptResources(
1432 base::Bind(&OnCompareComplete
, &status
, &are_equal
));
1433 base::RunLoop().RunUntilIdle();
1434 EXPECT_EQ(SERVICE_WORKER_OK
, status
);
1435 EXPECT_FALSE(are_equal
);
1438 } // namespace content