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