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