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 base::ThreadTaskRunnerHandle::Get(),
272 database_task_manager
.Pass(),
273 base::ThreadTaskRunnerHandle::Get(),
278 context_ptr_
= context_
->AsWeakPtr();
281 void TearDown() override
{ context_
.reset(); }
283 virtual base::FilePath
GetUserDataDirectory() { return base::FilePath(); }
285 ServiceWorkerStorage
* storage() { return context_
->storage(); }
287 // A static class method for friendliness.
288 static void VerifyPurgeableListStatusCallback(
289 ServiceWorkerDatabase
* database
,
290 std::set
<int64
> *purgeable_ids
,
292 ServiceWorkerStatusCode
* result
,
293 ServiceWorkerStatusCode status
) {
296 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
297 database
->GetPurgeableResourceIds(purgeable_ids
));
301 void LazyInitialize() {
302 storage()->LazyInitialize(base::Bind(&base::DoNothing
));
303 base::RunLoop().RunUntilIdle();
306 ServiceWorkerStatusCode
StoreRegistration(
307 scoped_refptr
<ServiceWorkerRegistration
> registration
,
308 scoped_refptr
<ServiceWorkerVersion
> version
) {
309 bool was_called
= false;
310 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
311 storage()->StoreRegistration(registration
.get(),
313 MakeStatusCallback(&was_called
, &result
));
314 EXPECT_FALSE(was_called
); // always async
315 base::RunLoop().RunUntilIdle();
316 EXPECT_TRUE(was_called
);
320 ServiceWorkerStatusCode
DeleteRegistration(
321 int64 registration_id
,
322 const GURL
& origin
) {
323 bool was_called
= false;
324 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
325 storage()->DeleteRegistration(
326 registration_id
, origin
, MakeStatusCallback(&was_called
, &result
));
327 EXPECT_FALSE(was_called
); // always async
328 base::RunLoop().RunUntilIdle();
329 EXPECT_TRUE(was_called
);
333 void GetAllRegistrations(
334 std::vector
<ServiceWorkerRegistrationInfo
>* registrations
) {
335 bool was_called
= false;
336 storage()->GetAllRegistrations(
337 MakeGetRegistrationsCallback(&was_called
, registrations
));
338 EXPECT_FALSE(was_called
); // always async
339 base::RunLoop().RunUntilIdle();
340 EXPECT_TRUE(was_called
);
343 void GetRegistrationsForOrigin(
345 std::vector
<ServiceWorkerRegistrationInfo
>* registrations
) {
346 bool was_called
= false;
347 storage()->GetRegistrationsForOrigin(
349 MakeGetRegistrationsCallback(&was_called
, registrations
));
350 EXPECT_FALSE(was_called
); // always async
351 base::RunLoop().RunUntilIdle();
352 EXPECT_TRUE(was_called
);
355 ServiceWorkerStatusCode
GetUserData(
356 int64 registration_id
,
357 const std::string
& key
,
359 bool was_called
= false;
360 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
361 storage()->GetUserData(
362 registration_id
, key
,
363 base::Bind(&GetUserDataCallback
, &was_called
, data
, &result
));
364 EXPECT_FALSE(was_called
); // always async
365 base::RunLoop().RunUntilIdle();
366 EXPECT_TRUE(was_called
);
370 ServiceWorkerStatusCode
StoreUserData(
371 int64 registration_id
,
373 const std::string
& key
,
374 const std::string
& data
) {
375 bool was_called
= false;
376 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
377 storage()->StoreUserData(
378 registration_id
, origin
, key
, data
,
379 MakeStatusCallback(&was_called
, &result
));
380 EXPECT_FALSE(was_called
); // always async
381 base::RunLoop().RunUntilIdle();
382 EXPECT_TRUE(was_called
);
386 ServiceWorkerStatusCode
ClearUserData(
387 int64 registration_id
,
388 const std::string
& key
) {
389 bool was_called
= false;
390 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
391 storage()->ClearUserData(
392 registration_id
, key
, MakeStatusCallback(&was_called
, &result
));
393 EXPECT_FALSE(was_called
); // always async
394 base::RunLoop().RunUntilIdle();
395 EXPECT_TRUE(was_called
);
399 ServiceWorkerStatusCode
GetUserDataForAllRegistrations(
400 const std::string
& key
,
401 std::vector
<std::pair
<int64
, std::string
>>* data
) {
402 bool was_called
= false;
403 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
404 storage()->GetUserDataForAllRegistrations(
405 key
, base::Bind(&GetUserDataForAllRegistrationsCallback
, &was_called
,
407 EXPECT_FALSE(was_called
); // always async
408 base::RunLoop().RunUntilIdle();
409 EXPECT_TRUE(was_called
);
413 ServiceWorkerStatusCode
UpdateToActiveState(
414 scoped_refptr
<ServiceWorkerRegistration
> registration
) {
415 bool was_called
= false;
416 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
417 storage()->UpdateToActiveState(registration
.get(),
418 MakeStatusCallback(&was_called
, &result
));
419 EXPECT_FALSE(was_called
); // always async
420 base::RunLoop().RunUntilIdle();
421 EXPECT_TRUE(was_called
);
425 void UpdateLastUpdateCheckTime(ServiceWorkerRegistration
* registration
) {
426 storage()->UpdateLastUpdateCheckTime(registration
);
427 base::RunLoop().RunUntilIdle();
430 ServiceWorkerStatusCode
FindRegistrationForDocument(
431 const GURL
& document_url
,
432 scoped_refptr
<ServiceWorkerRegistration
>* registration
) {
433 bool was_called
= false;
434 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
435 storage()->FindRegistrationForDocument(
436 document_url
, MakeFindCallback(&was_called
, &result
, registration
));
437 base::RunLoop().RunUntilIdle();
438 EXPECT_TRUE(was_called
);
442 ServiceWorkerStatusCode
FindRegistrationForPattern(
444 scoped_refptr
<ServiceWorkerRegistration
>* registration
) {
445 bool was_called
= false;
446 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
447 storage()->FindRegistrationForPattern(
448 scope
, MakeFindCallback(&was_called
, &result
, registration
));
449 EXPECT_FALSE(was_called
); // always async
450 base::RunLoop().RunUntilIdle();
451 EXPECT_TRUE(was_called
);
455 ServiceWorkerStatusCode
FindRegistrationForId(
456 int64 registration_id
,
458 scoped_refptr
<ServiceWorkerRegistration
>* registration
) {
459 bool was_called
= false;
460 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
461 storage()->FindRegistrationForId(
462 registration_id
, origin
,
463 MakeFindCallback(&was_called
, &result
, registration
));
464 base::RunLoop().RunUntilIdle();
465 EXPECT_TRUE(was_called
);
469 ServiceWorkerStatusCode
FindRegistrationForIdOnly(
470 int64 registration_id
,
471 scoped_refptr
<ServiceWorkerRegistration
>* registration
) {
472 bool was_called
= false;
473 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
474 storage()->FindRegistrationForIdOnly(
475 registration_id
, MakeFindCallback(&was_called
, &result
, registration
));
476 base::RunLoop().RunUntilIdle();
477 EXPECT_TRUE(was_called
);
481 scoped_ptr
<ServiceWorkerContextCore
> context_
;
482 base::WeakPtr
<ServiceWorkerContextCore
> context_ptr_
;
483 TestBrowserThreadBundle browser_thread_bundle_
;
486 TEST_F(ServiceWorkerStorageTest
, StoreFindUpdateDeleteRegistration
) {
487 const GURL
kScope("http://www.test.not/scope/");
488 const GURL
kScript("http://www.test.not/script.js");
489 const GURL
kDocumentUrl("http://www.test.not/scope/document.html");
490 const GURL
kResource1("http://www.test.not/scope/resource1.js");
491 const int64 kResource1Size
= 1591234;
492 const GURL
kResource2("http://www.test.not/scope/resource2.js");
493 const int64 kResource2Size
= 51;
494 const int64 kRegistrationId
= 0;
495 const int64 kVersionId
= 0;
496 const base::Time kToday
= base::Time::Now();
497 const base::Time kYesterday
= kToday
- base::TimeDelta::FromDays(1);
499 scoped_refptr
<ServiceWorkerRegistration
> found_registration
;
501 // We shouldn't find anything without having stored anything.
502 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
503 FindRegistrationForDocument(kDocumentUrl
, &found_registration
));
504 EXPECT_FALSE(found_registration
.get());
506 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
507 FindRegistrationForPattern(kScope
, &found_registration
));
508 EXPECT_FALSE(found_registration
.get());
510 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
511 FindRegistrationForId(
512 kRegistrationId
, kScope
.GetOrigin(), &found_registration
));
513 EXPECT_FALSE(found_registration
.get());
515 std::vector
<ServiceWorkerDatabase::ResourceRecord
> resources
;
517 ServiceWorkerDatabase::ResourceRecord(1, kResource1
, kResource1Size
));
519 ServiceWorkerDatabase::ResourceRecord(2, kResource2
, kResource2Size
));
522 scoped_refptr
<ServiceWorkerRegistration
> live_registration
=
523 new ServiceWorkerRegistration(
524 kScope
, kRegistrationId
, context_ptr_
);
525 scoped_refptr
<ServiceWorkerVersion
> live_version
=
526 new ServiceWorkerVersion(
527 live_registration
.get(), kScript
, kVersionId
, context_ptr_
);
528 live_version
->SetStatus(ServiceWorkerVersion::INSTALLED
);
529 live_version
->script_cache_map()->SetResources(resources
);
530 live_registration
->SetWaitingVersion(live_version
.get());
531 live_registration
->set_last_update_check(kYesterday
);
532 EXPECT_EQ(SERVICE_WORKER_OK
,
533 StoreRegistration(live_registration
, live_version
));
535 // Now we should find it and get the live ptr back immediately.
536 EXPECT_EQ(SERVICE_WORKER_OK
,
537 FindRegistrationForDocument(kDocumentUrl
, &found_registration
));
538 EXPECT_EQ(live_registration
, found_registration
);
539 EXPECT_EQ(kResource1Size
+ kResource2Size
,
540 live_registration
->resources_total_size_bytes());
541 EXPECT_EQ(kResource1Size
+ kResource2Size
,
542 found_registration
->resources_total_size_bytes());
543 found_registration
= NULL
;
545 // But FindRegistrationForPattern is always async.
546 EXPECT_EQ(SERVICE_WORKER_OK
,
547 FindRegistrationForPattern(kScope
, &found_registration
));
548 EXPECT_EQ(live_registration
, found_registration
);
549 found_registration
= NULL
;
551 // Can be found by id too.
552 EXPECT_EQ(SERVICE_WORKER_OK
,
553 FindRegistrationForId(
554 kRegistrationId
, kScope
.GetOrigin(), &found_registration
));
555 ASSERT_TRUE(found_registration
.get());
556 EXPECT_EQ(kRegistrationId
, found_registration
->id());
557 EXPECT_EQ(live_registration
, found_registration
);
558 found_registration
= NULL
;
560 // Can be found by just the id too.
561 EXPECT_EQ(SERVICE_WORKER_OK
,
562 FindRegistrationForIdOnly(kRegistrationId
, &found_registration
));
563 ASSERT_TRUE(found_registration
.get());
564 EXPECT_EQ(kRegistrationId
, found_registration
->id());
565 EXPECT_EQ(live_registration
, found_registration
);
566 found_registration
= NULL
;
568 // Drop the live registration, but keep the version live.
569 live_registration
= NULL
;
571 // Now FindRegistrationForDocument should be async.
572 EXPECT_EQ(SERVICE_WORKER_OK
,
573 FindRegistrationForDocument(kDocumentUrl
, &found_registration
));
574 ASSERT_TRUE(found_registration
.get());
575 EXPECT_EQ(kRegistrationId
, found_registration
->id());
576 EXPECT_TRUE(found_registration
->HasOneRef());
578 // Check that sizes are populated correctly
579 EXPECT_EQ(live_version
.get(), found_registration
->waiting_version());
580 EXPECT_EQ(kResource1Size
+ kResource2Size
,
581 found_registration
->resources_total_size_bytes());
582 std::vector
<ServiceWorkerRegistrationInfo
> all_registrations
;
583 GetAllRegistrations(&all_registrations
);
584 EXPECT_EQ(1u, all_registrations
.size());
585 ServiceWorkerRegistrationInfo info
= all_registrations
[0];
586 EXPECT_EQ(kResource1Size
+ kResource2Size
, info
.stored_version_size_bytes
);
587 all_registrations
.clear();
589 // Finding by origin should provide the same result iif origin is kScope.
590 std::vector
<ServiceWorkerRegistrationInfo
> registrations_origin
;
591 GetRegistrationsForOrigin(kScope
.GetOrigin(), ®istrations_origin
);
592 EXPECT_EQ(1u, registrations_origin
.size());
593 registrations_origin
.clear();
595 GetRegistrationsForOrigin(
596 GURL("http://example.com/").GetOrigin(),
597 ®istrations_origin
);
598 EXPECT_TRUE(registrations_origin
.empty());
600 found_registration
= NULL
;
602 // Drop the live version too.
605 // And FindRegistrationForPattern is always async.
606 EXPECT_EQ(SERVICE_WORKER_OK
,
607 FindRegistrationForPattern(kScope
, &found_registration
));
608 ASSERT_TRUE(found_registration
.get());
609 EXPECT_EQ(kRegistrationId
, found_registration
->id());
610 EXPECT_TRUE(found_registration
->HasOneRef());
611 EXPECT_FALSE(found_registration
->active_version());
612 ASSERT_TRUE(found_registration
->waiting_version());
613 EXPECT_EQ(kYesterday
, found_registration
->last_update_check());
614 EXPECT_EQ(ServiceWorkerVersion::INSTALLED
,
615 found_registration
->waiting_version()->status());
617 // Update to active and update the last check time.
618 scoped_refptr
<ServiceWorkerVersion
> temp_version
=
619 found_registration
->waiting_version();
620 temp_version
->SetStatus(ServiceWorkerVersion::ACTIVATED
);
621 found_registration
->SetActiveVersion(temp_version
.get());
623 EXPECT_EQ(SERVICE_WORKER_OK
, UpdateToActiveState(found_registration
));
624 found_registration
->set_last_update_check(kToday
);
625 UpdateLastUpdateCheckTime(found_registration
.get());
627 found_registration
= NULL
;
629 // Trying to update a unstored registration to active should fail.
630 scoped_refptr
<ServiceWorkerRegistration
> unstored_registration
=
631 new ServiceWorkerRegistration(
632 kScope
, kRegistrationId
+ 1, context_ptr_
);
633 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
634 UpdateToActiveState(unstored_registration
));
635 unstored_registration
= NULL
;
637 // The Find methods should return a registration with an active version
638 // and the expected update time.
639 EXPECT_EQ(SERVICE_WORKER_OK
,
640 FindRegistrationForDocument(kDocumentUrl
, &found_registration
));
641 ASSERT_TRUE(found_registration
.get());
642 EXPECT_EQ(kRegistrationId
, found_registration
->id());
643 EXPECT_TRUE(found_registration
->HasOneRef());
644 EXPECT_FALSE(found_registration
->waiting_version());
645 ASSERT_TRUE(found_registration
->active_version());
646 EXPECT_EQ(ServiceWorkerVersion::ACTIVATED
,
647 found_registration
->active_version()->status());
648 EXPECT_EQ(kToday
, found_registration
->last_update_check());
650 // Delete from storage but with a instance still live.
651 EXPECT_TRUE(context_
->GetLiveVersion(kRegistrationId
));
652 EXPECT_EQ(SERVICE_WORKER_OK
,
653 DeleteRegistration(kRegistrationId
, kScope
.GetOrigin()));
654 EXPECT_TRUE(context_
->GetLiveVersion(kRegistrationId
));
656 // Should no longer be found.
657 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
658 FindRegistrationForId(
659 kRegistrationId
, kScope
.GetOrigin(), &found_registration
));
660 EXPECT_FALSE(found_registration
.get());
661 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
662 FindRegistrationForIdOnly(kRegistrationId
, &found_registration
));
663 EXPECT_FALSE(found_registration
.get());
665 // Deleting an unstored registration should succeed.
666 EXPECT_EQ(SERVICE_WORKER_OK
,
667 DeleteRegistration(kRegistrationId
+ 1, kScope
.GetOrigin()));
670 TEST_F(ServiceWorkerStorageTest
, InstallingRegistrationsAreFindable
) {
671 const GURL
kScope("http://www.test.not/scope/");
672 const GURL
kScript("http://www.test.not/script.js");
673 const GURL
kDocumentUrl("http://www.test.not/scope/document.html");
674 const int64 kRegistrationId
= 0;
675 const int64 kVersionId
= 0;
677 scoped_refptr
<ServiceWorkerRegistration
> found_registration
;
679 // Create an unstored registration.
680 scoped_refptr
<ServiceWorkerRegistration
> live_registration
=
681 new ServiceWorkerRegistration(
682 kScope
, kRegistrationId
, context_ptr_
);
683 scoped_refptr
<ServiceWorkerVersion
> live_version
=
684 new ServiceWorkerVersion(
685 live_registration
.get(), kScript
, kVersionId
, context_ptr_
);
686 live_version
->SetStatus(ServiceWorkerVersion::INSTALLING
);
687 live_registration
->SetWaitingVersion(live_version
.get());
689 // Should not be findable, including by GetAllRegistrations.
690 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
691 FindRegistrationForId(
692 kRegistrationId
, kScope
.GetOrigin(), &found_registration
));
693 EXPECT_FALSE(found_registration
.get());
695 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
696 FindRegistrationForIdOnly(kRegistrationId
, &found_registration
));
697 EXPECT_FALSE(found_registration
.get());
699 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
700 FindRegistrationForDocument(kDocumentUrl
, &found_registration
));
701 EXPECT_FALSE(found_registration
.get());
703 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
704 FindRegistrationForPattern(kScope
, &found_registration
));
705 EXPECT_FALSE(found_registration
.get());
707 std::vector
<ServiceWorkerRegistrationInfo
> all_registrations
;
708 GetAllRegistrations(&all_registrations
);
709 EXPECT_TRUE(all_registrations
.empty());
711 std::vector
<ServiceWorkerRegistrationInfo
> registrations_origin
;
712 GetRegistrationsForOrigin(kScope
.GetOrigin(), ®istrations_origin
);
713 EXPECT_TRUE(registrations_origin
.empty());
715 GetRegistrationsForOrigin(
716 GURL("http://example.com/").GetOrigin(),
717 ®istrations_origin
);
718 EXPECT_TRUE(registrations_origin
.empty());
720 // Notify storage of it being installed.
721 storage()->NotifyInstallingRegistration(live_registration
.get());
723 // Now should be findable.
724 EXPECT_EQ(SERVICE_WORKER_OK
,
725 FindRegistrationForId(
726 kRegistrationId
, kScope
.GetOrigin(), &found_registration
));
727 EXPECT_EQ(live_registration
, found_registration
);
728 found_registration
= NULL
;
730 EXPECT_EQ(SERVICE_WORKER_OK
,
731 FindRegistrationForIdOnly(kRegistrationId
, &found_registration
));
732 EXPECT_EQ(live_registration
, found_registration
);
733 found_registration
= NULL
;
735 EXPECT_EQ(SERVICE_WORKER_OK
,
736 FindRegistrationForDocument(kDocumentUrl
, &found_registration
));
737 EXPECT_EQ(live_registration
, found_registration
);
738 found_registration
= NULL
;
740 EXPECT_EQ(SERVICE_WORKER_OK
,
741 FindRegistrationForPattern(kScope
, &found_registration
));
742 EXPECT_EQ(live_registration
, found_registration
);
743 found_registration
= NULL
;
745 GetAllRegistrations(&all_registrations
);
746 EXPECT_EQ(1u, all_registrations
.size());
747 all_registrations
.clear();
749 // Finding by origin should provide the same result iif origin is kScope.
750 GetRegistrationsForOrigin(kScope
.GetOrigin(), ®istrations_origin
);
751 EXPECT_EQ(1u, registrations_origin
.size());
752 registrations_origin
.clear();
754 GetRegistrationsForOrigin(
755 GURL("http://example.com/").GetOrigin(),
756 ®istrations_origin
);
757 EXPECT_TRUE(registrations_origin
.empty());
759 // Notify storage of installation no longer happening.
760 storage()->NotifyDoneInstallingRegistration(
761 live_registration
.get(), NULL
, SERVICE_WORKER_OK
);
763 // Once again, should not be findable.
764 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
765 FindRegistrationForId(
766 kRegistrationId
, kScope
.GetOrigin(), &found_registration
));
767 EXPECT_FALSE(found_registration
.get());
769 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
770 FindRegistrationForIdOnly(kRegistrationId
, &found_registration
));
771 EXPECT_FALSE(found_registration
.get());
773 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
774 FindRegistrationForDocument(kDocumentUrl
, &found_registration
));
775 EXPECT_FALSE(found_registration
.get());
777 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
778 FindRegistrationForPattern(kScope
, &found_registration
));
779 EXPECT_FALSE(found_registration
.get());
781 GetAllRegistrations(&all_registrations
);
782 EXPECT_TRUE(all_registrations
.empty());
784 GetRegistrationsForOrigin(kScope
.GetOrigin(), ®istrations_origin
);
785 EXPECT_TRUE(registrations_origin
.empty());
787 GetRegistrationsForOrigin(
788 GURL("http://example.com/").GetOrigin(),
789 ®istrations_origin
);
790 EXPECT_TRUE(registrations_origin
.empty());
793 TEST_F(ServiceWorkerStorageTest
, StoreUserData
) {
794 const GURL
kScope("http://www.test.not/scope/");
795 const GURL
kScript("http://www.test.not/script.js");
796 const int64 kRegistrationId
= 0;
797 const int64 kVersionId
= 0;
801 // Store a registration.
802 scoped_refptr
<ServiceWorkerRegistration
> live_registration
=
803 new ServiceWorkerRegistration(
804 kScope
, kRegistrationId
, context_ptr_
);
805 scoped_refptr
<ServiceWorkerVersion
> live_version
=
806 new ServiceWorkerVersion(
807 live_registration
.get(), kScript
, kVersionId
, context_ptr_
);
808 live_version
->SetStatus(ServiceWorkerVersion::INSTALLED
);
809 live_registration
->SetWaitingVersion(live_version
.get());
810 EXPECT_EQ(SERVICE_WORKER_OK
,
811 StoreRegistration(live_registration
, live_version
));
813 // Store user data associated with the registration.
814 std::string data_out
;
815 EXPECT_EQ(SERVICE_WORKER_OK
,
816 StoreUserData(kRegistrationId
, kScope
.GetOrigin(), "key", "data"));
817 EXPECT_EQ(SERVICE_WORKER_OK
, GetUserData(kRegistrationId
, "key", &data_out
));
818 EXPECT_EQ("data", data_out
);
819 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
820 GetUserData(kRegistrationId
, "unknown_key", &data_out
));
821 std::vector
<std::pair
<int64
, std::string
>> data_list_out
;
822 EXPECT_EQ(SERVICE_WORKER_OK
,
823 GetUserDataForAllRegistrations("key", &data_list_out
));
824 ASSERT_EQ(1u, data_list_out
.size());
825 EXPECT_EQ(kRegistrationId
, data_list_out
[0].first
);
826 EXPECT_EQ("data", data_list_out
[0].second
);
827 data_list_out
.clear();
828 EXPECT_EQ(SERVICE_WORKER_OK
,
829 GetUserDataForAllRegistrations("unknown_key", &data_list_out
));
830 EXPECT_EQ(0u, data_list_out
.size());
831 EXPECT_EQ(SERVICE_WORKER_OK
, ClearUserData(kRegistrationId
, "key"));
832 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
833 GetUserData(kRegistrationId
, "key", &data_out
));
835 // User data should be deleted when the associated registration is deleted.
836 ASSERT_EQ(SERVICE_WORKER_OK
,
837 StoreUserData(kRegistrationId
, kScope
.GetOrigin(), "key", "data"));
838 ASSERT_EQ(SERVICE_WORKER_OK
,
839 GetUserData(kRegistrationId
, "key", &data_out
));
840 ASSERT_EQ("data", data_out
);
842 EXPECT_EQ(SERVICE_WORKER_OK
,
843 DeleteRegistration(kRegistrationId
, kScope
.GetOrigin()));
844 EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND
,
845 GetUserData(kRegistrationId
, "key", &data_out
));
846 data_list_out
.clear();
847 EXPECT_EQ(SERVICE_WORKER_OK
,
848 GetUserDataForAllRegistrations("key", &data_list_out
));
849 EXPECT_EQ(0u, data_list_out
.size());
851 // Data access with an invalid registration id should be failed.
852 EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED
,
853 StoreUserData(kInvalidServiceWorkerRegistrationId
,
854 kScope
.GetOrigin(), "key", "data"));
855 EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED
,
856 GetUserData(kInvalidServiceWorkerRegistrationId
, "key", &data_out
));
857 EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED
,
858 ClearUserData(kInvalidServiceWorkerRegistrationId
, "key"));
860 // Data access with an empty key should be failed.
861 EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED
,
863 kRegistrationId
, kScope
.GetOrigin(), std::string(), "data"));
864 EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED
,
865 GetUserData(kRegistrationId
, std::string(), &data_out
));
866 EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED
,
867 ClearUserData(kRegistrationId
, std::string()));
868 data_list_out
.clear();
869 EXPECT_EQ(SERVICE_WORKER_ERROR_FAILED
,
870 GetUserDataForAllRegistrations(std::string(), &data_list_out
));
873 class ServiceWorkerResourceStorageTest
: public ServiceWorkerStorageTest
{
875 void SetUp() override
{
876 ServiceWorkerStorageTest::SetUp();
878 storage()->LazyInitialize(base::Bind(&base::DoNothing
));
879 base::RunLoop().RunUntilIdle();
880 scope_
= GURL("http://www.test.not/scope/");
881 script_
= GURL("http://www.test.not/script.js");
882 import_
= GURL("http://www.test.not/import.js");
883 document_url_
= GURL("http://www.test.not/scope/document.html");
884 registration_id_
= storage()->NewRegistrationId();
885 version_id_
= storage()->NewVersionId();
886 resource_id1_
= storage()->NewResourceId();
887 resource_id2_
= storage()->NewResourceId();
888 resource_id1_size_
= 239193;
889 resource_id2_size_
= 59923;
891 // Cons up a new registration+version with two script resources.
892 RegistrationData data
;
893 data
.registration_id
= registration_id_
;
895 data
.script
= script_
;
896 data
.version_id
= version_id_
;
897 data
.is_active
= false;
898 std::vector
<ResourceRecord
> resources
;
900 ResourceRecord(resource_id1_
, script_
, resource_id1_size_
));
902 ResourceRecord(resource_id2_
, import_
, resource_id2_size_
));
903 registration_
= storage()->GetOrCreateRegistration(data
, resources
);
904 registration_
->waiting_version()->SetStatus(ServiceWorkerVersion::NEW
);
906 // Add the resources ids to the uncommitted list.
907 storage()->StoreUncommittedResponseId(resource_id1_
);
908 storage()->StoreUncommittedResponseId(resource_id2_
);
909 base::RunLoop().RunUntilIdle();
910 std::set
<int64
> verify_ids
;
911 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
912 storage()->database_
->GetUncommittedResourceIds(&verify_ids
));
913 EXPECT_EQ(2u, verify_ids
.size());
915 // And dump something in the disk cache for them.
916 WriteBasicResponse(storage(), resource_id1_
);
917 WriteBasicResponse(storage(), resource_id2_
);
918 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, true));
919 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id2_
, true));
921 // Storing the registration/version should take the resources ids out
922 // of the uncommitted list.
925 StoreRegistration(registration_
, registration_
->waiting_version()));
927 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
928 storage()->database_
->GetUncommittedResourceIds(&verify_ids
));
929 EXPECT_TRUE(verify_ids
.empty());
937 int64 registration_id_
;
940 uint64 resource_id1_size_
;
942 uint64 resource_id2_size_
;
943 scoped_refptr
<ServiceWorkerRegistration
> registration_
;
946 class ServiceWorkerResourceStorageDiskTest
947 : public ServiceWorkerResourceStorageTest
{
949 void SetUp() override
{
950 ASSERT_TRUE(user_data_directory_
.CreateUniqueTempDir());
951 ServiceWorkerResourceStorageTest::SetUp();
954 base::FilePath
GetUserDataDirectory() override
{
955 return user_data_directory_
.path();
959 base::ScopedTempDir user_data_directory_
;
962 TEST_F(ServiceWorkerResourceStorageTest
,
963 WriteMetadataWithServiceWorkerResponseMetadataWriter
) {
964 const char kMetadata1
[] = "Test metadata";
965 const char kMetadata2
[] = "small";
966 int64 new_resource_id_
= storage()->NewResourceId();
967 // Writing metadata to nonexistent resoirce ID must fail.
968 EXPECT_GE(0, WriteResponseMetadata(storage(), new_resource_id_
, kMetadata1
));
970 // Check metadata is written.
971 EXPECT_EQ(static_cast<int>(strlen(kMetadata1
)),
972 WriteResponseMetadata(storage(), resource_id1_
, kMetadata1
));
973 EXPECT_TRUE(VerifyResponseMetadata(storage(), resource_id1_
, kMetadata1
));
974 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, true));
976 // Check metadata is written and truncated.
977 EXPECT_EQ(static_cast<int>(strlen(kMetadata2
)),
978 WriteResponseMetadata(storage(), resource_id1_
, kMetadata2
));
979 EXPECT_TRUE(VerifyResponseMetadata(storage(), resource_id1_
, kMetadata2
));
980 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, true));
982 // Check metadata is deleted.
983 EXPECT_EQ(0, WriteResponseMetadata(storage(), resource_id1_
, ""));
984 EXPECT_FALSE(VerifyResponseMetadata(storage(), resource_id1_
, ""));
985 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, true));
988 TEST_F(ServiceWorkerResourceStorageTest
,
989 WriteMetadataWithServiceWorkerScriptCacheMap
) {
990 const char kMetadata1
[] = "Test metadata";
991 const char kMetadata2
[] = "small";
992 ServiceWorkerVersion
* version
= registration_
->waiting_version();
993 EXPECT_TRUE(version
);
995 // Writing metadata to nonexistent URL must fail.
997 WriteMetadata(version
, GURL("http://www.test.not/nonexistent.js"),
999 // Clearing metadata of nonexistent URL must fail.
1001 ClearMetadata(version
, GURL("http://www.test.not/nonexistent.js")));
1003 // Check metadata is written.
1004 EXPECT_EQ(static_cast<int>(strlen(kMetadata1
)),
1005 WriteMetadata(version
, script_
, kMetadata1
));
1006 EXPECT_TRUE(VerifyResponseMetadata(storage(), resource_id1_
, kMetadata1
));
1007 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, true));
1009 // Check metadata is written and truncated.
1010 EXPECT_EQ(static_cast<int>(strlen(kMetadata2
)),
1011 WriteMetadata(version
, script_
, kMetadata2
));
1012 EXPECT_TRUE(VerifyResponseMetadata(storage(), resource_id1_
, kMetadata2
));
1013 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, true));
1015 // Check metadata is deleted.
1016 EXPECT_EQ(0, ClearMetadata(version
, script_
));
1017 EXPECT_FALSE(VerifyResponseMetadata(storage(), resource_id1_
, ""));
1018 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, true));
1021 TEST_F(ServiceWorkerResourceStorageTest
, DeleteRegistration_NoLiveVersion
) {
1022 bool was_called
= false;
1023 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
1024 std::set
<int64
> verify_ids
;
1026 registration_
->SetWaitingVersion(NULL
);
1027 registration_
= NULL
;
1029 // Deleting the registration should result in the resources being added to the
1030 // purgeable list and then doomed in the disk cache and removed from that
1032 storage()->DeleteRegistration(
1035 base::Bind(&VerifyPurgeableListStatusCallback
,
1036 base::Unretained(storage()->database_
.get()),
1040 base::RunLoop().RunUntilIdle();
1041 ASSERT_TRUE(was_called
);
1042 EXPECT_EQ(SERVICE_WORKER_OK
, result
);
1043 EXPECT_EQ(2u, verify_ids
.size());
1045 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1046 storage()->database_
->GetPurgeableResourceIds(&verify_ids
));
1047 EXPECT_TRUE(verify_ids
.empty());
1049 EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id1_
, false));
1050 EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id2_
, false));
1053 TEST_F(ServiceWorkerResourceStorageTest
, DeleteRegistration_WaitingVersion
) {
1054 bool was_called
= false;
1055 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
1056 std::set
<int64
> verify_ids
;
1058 // Deleting the registration should result in the resources being added to the
1059 // purgeable list and then doomed in the disk cache and removed from that
1061 storage()->DeleteRegistration(
1062 registration_
->id(),
1064 base::Bind(&VerifyPurgeableListStatusCallback
,
1065 base::Unretained(storage()->database_
.get()),
1069 base::RunLoop().RunUntilIdle();
1070 ASSERT_TRUE(was_called
);
1071 EXPECT_EQ(SERVICE_WORKER_OK
, result
);
1072 EXPECT_EQ(2u, verify_ids
.size());
1074 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1075 storage()->database_
->GetPurgeableResourceIds(&verify_ids
));
1076 EXPECT_EQ(2u, verify_ids
.size());
1078 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, false));
1079 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id2_
, false));
1081 // Doom the version, now it happens.
1082 registration_
->waiting_version()->Doom();
1083 base::RunLoop().RunUntilIdle();
1084 EXPECT_EQ(SERVICE_WORKER_OK
, result
);
1085 EXPECT_EQ(2u, verify_ids
.size());
1087 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1088 storage()->database_
->GetPurgeableResourceIds(&verify_ids
));
1089 EXPECT_TRUE(verify_ids
.empty());
1091 EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id1_
, false));
1092 EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id2_
, false));
1095 TEST_F(ServiceWorkerResourceStorageTest
, DeleteRegistration_ActiveVersion
) {
1096 // Promote the worker to active and add a controllee.
1097 registration_
->SetActiveVersion(registration_
->waiting_version());
1098 storage()->UpdateToActiveState(
1099 registration_
.get(), base::Bind(&ServiceWorkerUtils::NoOpStatusCallback
));
1100 scoped_ptr
<ServiceWorkerProviderHost
> host(
1101 new ServiceWorkerProviderHost(33 /* dummy render process id */,
1103 1 /* dummy provider_id */,
1104 SERVICE_WORKER_PROVIDER_FOR_CONTROLLEE
,
1105 context_
->AsWeakPtr(),
1107 registration_
->active_version()->AddControllee(host
.get());
1109 bool was_called
= false;
1110 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
1111 std::set
<int64
> verify_ids
;
1113 // Deleting the registration should move the resources to the purgeable list
1114 // but keep them available.
1115 storage()->DeleteRegistration(
1116 registration_
->id(),
1118 base::Bind(&VerifyPurgeableListStatusCallback
,
1119 base::Unretained(storage()->database_
.get()),
1123 registration_
->active_version()->Doom();
1124 base::RunLoop().RunUntilIdle();
1125 ASSERT_TRUE(was_called
);
1126 EXPECT_EQ(SERVICE_WORKER_OK
, result
);
1127 EXPECT_EQ(2u, verify_ids
.size());
1129 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1130 storage()->database_
->GetPurgeableResourceIds(&verify_ids
));
1131 EXPECT_EQ(2u, verify_ids
.size());
1133 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, true));
1134 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id2_
, true));
1136 // Removing the controllee should cause the resources to be deleted.
1137 registration_
->active_version()->RemoveControllee(host
.get());
1138 base::RunLoop().RunUntilIdle();
1140 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1141 storage()->database_
->GetPurgeableResourceIds(&verify_ids
));
1142 EXPECT_TRUE(verify_ids
.empty());
1144 EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id1_
, false));
1145 EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id2_
, false));
1148 TEST_F(ServiceWorkerResourceStorageDiskTest
, CleanupOnRestart
) {
1149 // Promote the worker to active and add a controllee.
1150 registration_
->SetActiveVersion(registration_
->waiting_version());
1151 registration_
->SetWaitingVersion(NULL
);
1152 storage()->UpdateToActiveState(
1153 registration_
.get(), base::Bind(&ServiceWorkerUtils::NoOpStatusCallback
));
1154 scoped_ptr
<ServiceWorkerProviderHost
> host(
1155 new ServiceWorkerProviderHost(33 /* dummy render process id */,
1157 1 /* dummy provider_id */,
1158 SERVICE_WORKER_PROVIDER_FOR_CONTROLLEE
,
1159 context_
->AsWeakPtr(),
1161 registration_
->active_version()->AddControllee(host
.get());
1163 bool was_called
= false;
1164 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
1165 std::set
<int64
> verify_ids
;
1167 // Deleting the registration should move the resources to the purgeable list
1168 // but keep them available.
1169 storage()->DeleteRegistration(
1170 registration_
->id(),
1172 base::Bind(&VerifyPurgeableListStatusCallback
,
1173 base::Unretained(storage()->database_
.get()),
1177 base::RunLoop().RunUntilIdle();
1178 ASSERT_TRUE(was_called
);
1179 EXPECT_EQ(SERVICE_WORKER_OK
, result
);
1180 EXPECT_EQ(2u, verify_ids
.size());
1182 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1183 storage()->database_
->GetPurgeableResourceIds(&verify_ids
));
1184 EXPECT_EQ(2u, verify_ids
.size());
1186 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, true));
1187 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id2_
, true));
1189 // Also add an uncommitted resource.
1190 int64 kStaleUncommittedResourceId
= storage()->NewResourceId();
1191 storage()->StoreUncommittedResponseId(kStaleUncommittedResourceId
);
1192 base::RunLoop().RunUntilIdle();
1194 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1195 storage()->database_
->GetUncommittedResourceIds(&verify_ids
));
1196 EXPECT_EQ(1u, verify_ids
.size());
1197 WriteBasicResponse(storage(), kStaleUncommittedResourceId
);
1199 VerifyBasicResponse(storage(), kStaleUncommittedResourceId
, true));
1201 // Simulate browser shutdown. The purgeable and uncommitted resources are now
1204 scoped_ptr
<ServiceWorkerDatabaseTaskManager
> database_task_manager(
1205 new MockServiceWorkerDatabaseTaskManager(
1206 base::ThreadTaskRunnerHandle::Get()));
1208 new ServiceWorkerContextCore(GetUserDataDirectory(),
1209 base::ThreadTaskRunnerHandle::Get(),
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(ServiceWorkerResourceStorageTest
, UpdateRegistration
) {
1249 // Promote the worker to active worker and add a controllee.
1250 registration_
->SetActiveVersion(registration_
->waiting_version());
1251 storage()->UpdateToActiveState(
1252 registration_
.get(), base::Bind(&ServiceWorkerUtils::NoOpStatusCallback
));
1253 scoped_ptr
<ServiceWorkerProviderHost
> host(
1254 new ServiceWorkerProviderHost(33 /* dummy render process id */,
1256 1 /* dummy provider_id */,
1257 SERVICE_WORKER_PROVIDER_FOR_CONTROLLEE
,
1258 context_
->AsWeakPtr(),
1260 registration_
->active_version()->AddControllee(host
.get());
1262 bool was_called
= false;
1263 ServiceWorkerStatusCode result
= SERVICE_WORKER_ERROR_FAILED
;
1264 std::set
<int64
> verify_ids
;
1266 // Make an updated registration.
1267 scoped_refptr
<ServiceWorkerVersion
> live_version
= new ServiceWorkerVersion(
1268 registration_
.get(), script_
, storage()->NewVersionId(), context_ptr_
);
1269 live_version
->SetStatus(ServiceWorkerVersion::NEW
);
1270 registration_
->SetWaitingVersion(live_version
.get());
1272 // Writing the registration should move the old version's resources to the
1273 // purgeable list but keep them available.
1274 storage()->StoreRegistration(
1275 registration_
.get(),
1276 registration_
->waiting_version(),
1277 base::Bind(&VerifyPurgeableListStatusCallback
,
1278 base::Unretained(storage()->database_
.get()),
1282 registration_
->active_version()->Doom();
1283 base::RunLoop().RunUntilIdle();
1284 ASSERT_TRUE(was_called
);
1285 EXPECT_EQ(SERVICE_WORKER_OK
, result
);
1286 EXPECT_EQ(2u, verify_ids
.size());
1288 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1289 storage()->database_
->GetPurgeableResourceIds(&verify_ids
));
1290 EXPECT_EQ(2u, verify_ids
.size());
1292 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_
, false));
1293 EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id2_
, false));
1295 // Removing the controllee should cause the old version's resources to be
1297 registration_
->active_version()->RemoveControllee(host
.get());
1298 base::RunLoop().RunUntilIdle();
1300 EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK
,
1301 storage()->database_
->GetPurgeableResourceIds(&verify_ids
));
1302 EXPECT_TRUE(verify_ids
.empty());
1304 EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id1_
, false));
1305 EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id2_
, false));
1308 TEST_F(ServiceWorkerStorageTest
, FindRegistration_LongestScopeMatch
) {
1309 const GURL
kDocumentUrl("http://www.example.com/scope/foo");
1310 scoped_refptr
<ServiceWorkerRegistration
> found_registration
;
1312 // Registration for "/scope/".
1313 const GURL
kScope1("http://www.example.com/scope/");
1314 const GURL
kScript1("http://www.example.com/script1.js");
1315 const int64 kRegistrationId1
= 1;
1316 const int64 kVersionId1
= 1;
1317 scoped_refptr
<ServiceWorkerRegistration
> live_registration1
=
1318 new ServiceWorkerRegistration(
1319 kScope1
, kRegistrationId1
, context_ptr_
);
1320 scoped_refptr
<ServiceWorkerVersion
> live_version1
=
1321 new ServiceWorkerVersion(
1322 live_registration1
.get(), kScript1
, kVersionId1
, context_ptr_
);
1323 live_version1
->SetStatus(ServiceWorkerVersion::INSTALLED
);
1324 live_registration1
->SetWaitingVersion(live_version1
.get());
1326 // Registration for "/scope/foo".
1327 const GURL
kScope2("http://www.example.com/scope/foo");
1328 const GURL
kScript2("http://www.example.com/script2.js");
1329 const int64 kRegistrationId2
= 2;
1330 const int64 kVersionId2
= 2;
1331 scoped_refptr
<ServiceWorkerRegistration
> live_registration2
=
1332 new ServiceWorkerRegistration(
1333 kScope2
, kRegistrationId2
, context_ptr_
);
1334 scoped_refptr
<ServiceWorkerVersion
> live_version2
=
1335 new ServiceWorkerVersion(
1336 live_registration2
.get(), kScript2
, kVersionId2
, context_ptr_
);
1337 live_version2
->SetStatus(ServiceWorkerVersion::INSTALLED
);
1338 live_registration2
->SetWaitingVersion(live_version2
.get());
1340 // Registration for "/scope/foobar".
1341 const GURL
kScope3("http://www.example.com/scope/foobar");
1342 const GURL
kScript3("http://www.example.com/script3.js");
1343 const int64 kRegistrationId3
= 3;
1344 const int64 kVersionId3
= 3;
1345 scoped_refptr
<ServiceWorkerRegistration
> live_registration3
=
1346 new ServiceWorkerRegistration(
1347 kScope3
, kRegistrationId3
, context_ptr_
);
1348 scoped_refptr
<ServiceWorkerVersion
> live_version3
=
1349 new ServiceWorkerVersion(
1350 live_registration3
.get(), kScript3
, kVersionId3
, context_ptr_
);
1351 live_version3
->SetStatus(ServiceWorkerVersion::INSTALLED
);
1352 live_registration3
->SetWaitingVersion(live_version3
.get());
1354 // Notify storage of they being installed.
1355 storage()->NotifyInstallingRegistration(live_registration1
.get());
1356 storage()->NotifyInstallingRegistration(live_registration2
.get());
1357 storage()->NotifyInstallingRegistration(live_registration3
.get());
1359 // Find a registration among installing ones.
1360 EXPECT_EQ(SERVICE_WORKER_OK
,
1361 FindRegistrationForDocument(kDocumentUrl
, &found_registration
));
1362 EXPECT_EQ(live_registration2
, found_registration
);
1363 found_registration
= NULL
;
1365 // Store registrations.
1366 EXPECT_EQ(SERVICE_WORKER_OK
,
1367 StoreRegistration(live_registration1
, live_version1
));
1368 EXPECT_EQ(SERVICE_WORKER_OK
,
1369 StoreRegistration(live_registration2
, live_version2
));
1370 EXPECT_EQ(SERVICE_WORKER_OK
,
1371 StoreRegistration(live_registration3
, live_version3
));
1373 // Notify storage of installations no longer happening.
1374 storage()->NotifyDoneInstallingRegistration(
1375 live_registration1
.get(), NULL
, SERVICE_WORKER_OK
);
1376 storage()->NotifyDoneInstallingRegistration(
1377 live_registration2
.get(), NULL
, SERVICE_WORKER_OK
);
1378 storage()->NotifyDoneInstallingRegistration(
1379 live_registration3
.get(), NULL
, SERVICE_WORKER_OK
);
1381 // Find a registration among installed ones.
1382 EXPECT_EQ(SERVICE_WORKER_OK
,
1383 FindRegistrationForDocument(kDocumentUrl
, &found_registration
));
1384 EXPECT_EQ(live_registration2
, found_registration
);
1387 TEST_F(ServiceWorkerStorageTest
, CompareResources
) {
1388 // Compare two small responses containing the same data.
1389 WriteBasicResponse(storage(), 1);
1390 WriteBasicResponse(storage(), 2);
1391 ServiceWorkerStatusCode status
= static_cast<ServiceWorkerStatusCode
>(-1);
1392 bool are_equal
= false;
1393 storage()->CompareScriptResources(
1395 base::Bind(&OnCompareComplete
, &status
, &are_equal
));
1396 base::RunLoop().RunUntilIdle();
1397 EXPECT_EQ(SERVICE_WORKER_OK
, status
);
1398 EXPECT_TRUE(are_equal
);
1400 // Compare two small responses with different data.
1401 const char kHttpHeaders
[] = "HTTP/1.0 200 HONKYDORY\0\0";
1402 const char kHttpBody
[] = "Goodbye";
1403 std::string
headers(kHttpHeaders
, arraysize(kHttpHeaders
));
1404 WriteStringResponse(storage(), 3, headers
, std::string(kHttpBody
));
1405 status
= static_cast<ServiceWorkerStatusCode
>(-1);
1407 storage()->CompareScriptResources(
1409 base::Bind(&OnCompareComplete
, &status
, &are_equal
));
1410 base::RunLoop().RunUntilIdle();
1411 EXPECT_EQ(SERVICE_WORKER_OK
, status
);
1412 EXPECT_FALSE(are_equal
);
1414 // Compare two large responses with the same data.
1415 const int k32K
= 32 * 1024;
1416 WriteResponseOfSize(storage(), 4, 'a', k32K
);
1417 WriteResponseOfSize(storage(), 5, 'a', k32K
);
1418 status
= static_cast<ServiceWorkerStatusCode
>(-1);
1420 storage()->CompareScriptResources(
1422 base::Bind(&OnCompareComplete
, &status
, &are_equal
));
1423 base::RunLoop().RunUntilIdle();
1424 EXPECT_EQ(SERVICE_WORKER_OK
, status
);
1425 EXPECT_TRUE(are_equal
);
1427 // Compare a large and small response.
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
);
1437 // Compare two large responses with different data.
1438 WriteResponseOfSize(storage(), 6, 'b', k32K
);
1439 status
= static_cast<ServiceWorkerStatusCode
>(-1);
1441 storage()->CompareScriptResources(
1443 base::Bind(&OnCompareComplete
, &status
, &are_equal
));
1444 base::RunLoop().RunUntilIdle();
1445 EXPECT_EQ(SERVICE_WORKER_OK
, status
);
1446 EXPECT_FALSE(are_equal
);
1449 } // namespace content