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