Home | History | Annotate | Download | only in service_worker
      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.
      4 
      5 #include <string>
      6 
      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 "net/base/io_buffer.h"
     21 #include "net/base/net_errors.h"
     22 #include "net/base/test_completion_callback.h"
     23 #include "net/http/http_response_headers.h"
     24 #include "testing/gtest/include/gtest/gtest.h"
     25 
     26 using net::IOBuffer;
     27 using net::TestCompletionCallback;
     28 using net::WrappedIOBuffer;
     29 
     30 namespace content {
     31 
     32 namespace {
     33 
     34 typedef ServiceWorkerDatabase::RegistrationData RegistrationData;
     35 typedef ServiceWorkerDatabase::ResourceRecord ResourceRecord;
     36 
     37 void StatusCallback(bool* was_called,
     38                     ServiceWorkerStatusCode* result,
     39                     ServiceWorkerStatusCode status) {
     40   *was_called = true;
     41   *result = status;
     42 }
     43 
     44 ServiceWorkerStorage::StatusCallback MakeStatusCallback(
     45     bool* was_called,
     46     ServiceWorkerStatusCode* result) {
     47   return base::Bind(&StatusCallback, was_called, result);
     48 }
     49 
     50 void FindCallback(
     51     bool* was_called,
     52     ServiceWorkerStatusCode* result,
     53     scoped_refptr<ServiceWorkerRegistration>* found,
     54     ServiceWorkerStatusCode status,
     55     const scoped_refptr<ServiceWorkerRegistration>& registration) {
     56   *was_called = true;
     57   *result = status;
     58   *found = registration;
     59 }
     60 
     61 ServiceWorkerStorage::FindRegistrationCallback MakeFindCallback(
     62     bool* was_called,
     63     ServiceWorkerStatusCode* result,
     64     scoped_refptr<ServiceWorkerRegistration>* found) {
     65   return base::Bind(&FindCallback, was_called, result, found);
     66 }
     67 
     68 void GetAllCallback(
     69     bool* was_called,
     70     std::vector<ServiceWorkerRegistrationInfo>* all_out,
     71     const std::vector<ServiceWorkerRegistrationInfo>& all) {
     72   *was_called = true;
     73   *all_out = all;
     74 }
     75 
     76 ServiceWorkerStorage::GetAllRegistrationInfosCallback MakeGetAllCallback(
     77     bool* was_called,
     78     std::vector<ServiceWorkerRegistrationInfo>* all) {
     79   return base::Bind(&GetAllCallback, was_called, all);
     80 }
     81 
     82 void OnIOComplete(int* rv_out, int rv) {
     83   *rv_out = rv;
     84 }
     85 
     86 void OnCompareComplete(
     87     ServiceWorkerStatusCode* status_out, bool* are_equal_out,
     88     ServiceWorkerStatusCode status, bool are_equal) {
     89   *status_out = status;
     90   *are_equal_out = are_equal;
     91 }
     92 
     93 void WriteResponse(
     94     ServiceWorkerStorage* storage, int64 id,
     95     const std::string& headers,
     96     IOBuffer* body, int length) {
     97   scoped_ptr<ServiceWorkerResponseWriter> writer =
     98       storage->CreateResponseWriter(id);
     99 
    100   scoped_ptr<net::HttpResponseInfo> info(new net::HttpResponseInfo);
    101   info->request_time = base::Time::Now();
    102   info->response_time = base::Time::Now();
    103   info->was_cached = false;
    104   info->headers = new net::HttpResponseHeaders(headers);
    105   scoped_refptr<HttpResponseInfoIOBuffer> info_buffer =
    106       new HttpResponseInfoIOBuffer(info.release());
    107 
    108   int rv = -1234;
    109   writer->WriteInfo(info_buffer.get(), base::Bind(&OnIOComplete, &rv));
    110   base::RunLoop().RunUntilIdle();
    111   EXPECT_LT(0, rv);
    112 
    113   rv = -1234;
    114   writer->WriteData(body, length, base::Bind(&OnIOComplete, &rv));
    115   base::RunLoop().RunUntilIdle();
    116   EXPECT_EQ(length, rv);
    117 }
    118 
    119 void WriteStringResponse(
    120     ServiceWorkerStorage* storage, int64 id,
    121     const std::string& headers,
    122     const std::string& body) {
    123   scoped_refptr<IOBuffer> body_buffer(new WrappedIOBuffer(body.data()));
    124   WriteResponse(storage, id, headers, body_buffer.get(), body.length());
    125 }
    126 
    127 void WriteBasicResponse(ServiceWorkerStorage* storage, int64 id) {
    128   scoped_ptr<ServiceWorkerResponseWriter> writer =
    129       storage->CreateResponseWriter(id);
    130 
    131   const char kHttpHeaders[] = "HTTP/1.0 200 HONKYDORY\0Content-Length: 5\0\0";
    132   const char kHttpBody[] = "Hello";
    133   std::string headers(kHttpHeaders, arraysize(kHttpHeaders));
    134   WriteStringResponse(storage, id, headers, std::string(kHttpBody));
    135 }
    136 
    137 bool VerifyBasicResponse(ServiceWorkerStorage* storage, int64 id,
    138                          bool expected_positive_result) {
    139   const std::string kExpectedHttpBody("Hello");
    140   scoped_ptr<ServiceWorkerResponseReader> reader =
    141       storage->CreateResponseReader(id);
    142   scoped_refptr<HttpResponseInfoIOBuffer> info_buffer =
    143       new HttpResponseInfoIOBuffer();
    144   {
    145     TestCompletionCallback cb;
    146     reader->ReadInfo(info_buffer.get(), cb.callback());
    147     int rv = cb.WaitForResult();
    148     if (expected_positive_result)
    149       EXPECT_LT(0, rv);
    150     if (rv <= 0)
    151       return false;
    152   }
    153 
    154   std::string received_body;
    155   {
    156     const int kBigEnough = 512;
    157     scoped_refptr<net::IOBuffer> buffer = new IOBuffer(kBigEnough);
    158     TestCompletionCallback cb;
    159     reader->ReadData(buffer.get(), kBigEnough, cb.callback());
    160     int rv = cb.WaitForResult();
    161     EXPECT_EQ(static_cast<int>(kExpectedHttpBody.size()), rv);
    162     if (rv <= 0)
    163       return false;
    164     received_body.assign(buffer->data(), rv);
    165   }
    166 
    167   bool status_match =
    168       std::string("HONKYDORY") ==
    169           info_buffer->http_info->headers->GetStatusText();
    170   bool data_match = kExpectedHttpBody == received_body;
    171 
    172   EXPECT_TRUE(status_match);
    173   EXPECT_TRUE(data_match);
    174   return status_match && data_match;
    175 }
    176 
    177 void WriteResponseOfSize(ServiceWorkerStorage* storage, int64 id,
    178                          char val, int size) {
    179   const char kHttpHeaders[] = "HTTP/1.0 200 HONKYDORY\00";
    180   std::string headers(kHttpHeaders, arraysize(kHttpHeaders));
    181   scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(size);
    182   memset(buffer->data(), val, size);
    183   WriteResponse(storage, id, headers, buffer.get(), size);
    184 }
    185 
    186 }  // namespace
    187 
    188 class ServiceWorkerStorageTest : public testing::Test {
    189  public:
    190   ServiceWorkerStorageTest()
    191       : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {
    192   }
    193 
    194   virtual void SetUp() OVERRIDE {
    195     context_.reset(
    196         new ServiceWorkerContextCore(GetUserDataDirectory(),
    197                                      base::ThreadTaskRunnerHandle::Get(),
    198                                      base::ThreadTaskRunnerHandle::Get(),
    199                                      base::ThreadTaskRunnerHandle::Get(),
    200                                      NULL,
    201                                      NULL,
    202                                      NULL));
    203     context_ptr_ = context_->AsWeakPtr();
    204   }
    205 
    206   virtual void TearDown() OVERRIDE {
    207     context_.reset();
    208   }
    209 
    210   virtual base::FilePath GetUserDataDirectory() { return base::FilePath(); }
    211 
    212   ServiceWorkerStorage* storage() { return context_->storage(); }
    213 
    214   // A static class method for friendliness.
    215   static void VerifyPurgeableListStatusCallback(
    216       ServiceWorkerDatabase* database,
    217       std::set<int64> *purgeable_ids,
    218       bool* was_called,
    219       ServiceWorkerStatusCode* result,
    220       ServiceWorkerStatusCode status) {
    221     *was_called = true;
    222     *result = status;
    223     EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
    224               database->GetPurgeableResourceIds(purgeable_ids));
    225   }
    226 
    227  protected:
    228   ServiceWorkerStatusCode StoreRegistration(
    229       scoped_refptr<ServiceWorkerRegistration> registration,
    230       scoped_refptr<ServiceWorkerVersion> version) {
    231     bool was_called = false;
    232     ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_FAILED;
    233     storage()->StoreRegistration(registration.get(),
    234                                  version.get(),
    235                                  MakeStatusCallback(&was_called, &result));
    236     EXPECT_FALSE(was_called);  // always async
    237     base::RunLoop().RunUntilIdle();
    238     EXPECT_TRUE(was_called);
    239     return result;
    240   }
    241 
    242   ServiceWorkerStatusCode DeleteRegistration(
    243       int64 registration_id,
    244       const GURL& origin) {
    245     bool was_called = false;
    246     ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_FAILED;
    247     storage()->DeleteRegistration(
    248         registration_id, origin, MakeStatusCallback(&was_called, &result));
    249     EXPECT_FALSE(was_called);  // always async
    250     base::RunLoop().RunUntilIdle();
    251     EXPECT_TRUE(was_called);
    252     return result;
    253   }
    254 
    255   void GetAllRegistrations(
    256       std::vector<ServiceWorkerRegistrationInfo>* registrations) {
    257     bool was_called = false;
    258     storage()->GetAllRegistrations(
    259         MakeGetAllCallback(&was_called, registrations));
    260     EXPECT_FALSE(was_called);  // always async
    261     base::RunLoop().RunUntilIdle();
    262     EXPECT_TRUE(was_called);
    263   }
    264 
    265   ServiceWorkerStatusCode UpdateToActiveState(
    266       scoped_refptr<ServiceWorkerRegistration> registration) {
    267     bool was_called = false;
    268     ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_FAILED;
    269     storage()->UpdateToActiveState(registration.get(),
    270                                    MakeStatusCallback(&was_called, &result));
    271     EXPECT_FALSE(was_called);  // always async
    272     base::RunLoop().RunUntilIdle();
    273     EXPECT_TRUE(was_called);
    274     return result;
    275   }
    276 
    277   void UpdateLastUpdateCheckTime(ServiceWorkerRegistration* registration) {
    278     storage()->UpdateLastUpdateCheckTime(registration);
    279     base::RunLoop().RunUntilIdle();
    280   }
    281 
    282   ServiceWorkerStatusCode FindRegistrationForDocument(
    283       const GURL& document_url,
    284       scoped_refptr<ServiceWorkerRegistration>* registration) {
    285     bool was_called = false;
    286     ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_FAILED;
    287     storage()->FindRegistrationForDocument(
    288         document_url, MakeFindCallback(&was_called, &result, registration));
    289     base::RunLoop().RunUntilIdle();
    290     EXPECT_TRUE(was_called);
    291     return result;
    292   }
    293 
    294   ServiceWorkerStatusCode FindRegistrationForPattern(
    295       const GURL& scope,
    296       scoped_refptr<ServiceWorkerRegistration>* registration) {
    297     bool was_called = false;
    298     ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_FAILED;
    299     storage()->FindRegistrationForPattern(
    300         scope, MakeFindCallback(&was_called, &result, registration));
    301     EXPECT_FALSE(was_called);  // always async
    302     base::RunLoop().RunUntilIdle();
    303     EXPECT_TRUE(was_called);
    304     return result;
    305   }
    306 
    307   ServiceWorkerStatusCode FindRegistrationForId(
    308       int64 registration_id,
    309       const GURL& origin,
    310       scoped_refptr<ServiceWorkerRegistration>* registration) {
    311     bool was_called = false;
    312     ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_FAILED;
    313     storage()->FindRegistrationForId(
    314         registration_id, origin,
    315         MakeFindCallback(&was_called, &result, registration));
    316     base::RunLoop().RunUntilIdle();
    317     EXPECT_TRUE(was_called);
    318     return result;
    319   }
    320 
    321   scoped_ptr<ServiceWorkerContextCore> context_;
    322   base::WeakPtr<ServiceWorkerContextCore> context_ptr_;
    323   TestBrowserThreadBundle browser_thread_bundle_;
    324 };
    325 
    326 TEST_F(ServiceWorkerStorageTest, StoreFindUpdateDeleteRegistration) {
    327   const GURL kScope("http://www.test.not/scope/");
    328   const GURL kScript("http://www.test.not/script.js");
    329   const GURL kDocumentUrl("http://www.test.not/scope/document.html");
    330   const int64 kRegistrationId = 0;
    331   const int64 kVersionId = 0;
    332   const base::Time kToday = base::Time::Now();
    333   const base::Time kYesterday = kToday - base::TimeDelta::FromDays(1);
    334 
    335   scoped_refptr<ServiceWorkerRegistration> found_registration;
    336 
    337   // We shouldn't find anything without having stored anything.
    338   EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
    339             FindRegistrationForDocument(kDocumentUrl, &found_registration));
    340   EXPECT_FALSE(found_registration.get());
    341 
    342   EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
    343             FindRegistrationForPattern(kScope, &found_registration));
    344   EXPECT_FALSE(found_registration.get());
    345 
    346   EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
    347             FindRegistrationForId(
    348                 kRegistrationId, kScope.GetOrigin(), &found_registration));
    349   EXPECT_FALSE(found_registration.get());
    350 
    351   // Store something.
    352   scoped_refptr<ServiceWorkerRegistration> live_registration =
    353       new ServiceWorkerRegistration(
    354           kScope, kRegistrationId, context_ptr_);
    355   scoped_refptr<ServiceWorkerVersion> live_version =
    356       new ServiceWorkerVersion(
    357           live_registration.get(), kScript, kVersionId, context_ptr_);
    358   live_version->SetStatus(ServiceWorkerVersion::INSTALLED);
    359   live_registration->SetWaitingVersion(live_version.get());
    360   live_registration->set_last_update_check(kYesterday);
    361   EXPECT_EQ(SERVICE_WORKER_OK,
    362             StoreRegistration(live_registration, live_version));
    363 
    364   // Now we should find it and get the live ptr back immediately.
    365   EXPECT_EQ(SERVICE_WORKER_OK,
    366             FindRegistrationForDocument(kDocumentUrl, &found_registration));
    367   EXPECT_EQ(live_registration, found_registration);
    368   found_registration = NULL;
    369 
    370   // But FindRegistrationForPattern is always async.
    371   EXPECT_EQ(SERVICE_WORKER_OK,
    372             FindRegistrationForPattern(kScope, &found_registration));
    373   EXPECT_EQ(live_registration, found_registration);
    374   found_registration = NULL;
    375 
    376   // Can be found by id too.
    377   EXPECT_EQ(SERVICE_WORKER_OK,
    378             FindRegistrationForId(
    379                 kRegistrationId, kScope.GetOrigin(), &found_registration));
    380   ASSERT_TRUE(found_registration.get());
    381   EXPECT_EQ(kRegistrationId, found_registration->id());
    382   EXPECT_EQ(live_registration, found_registration);
    383   found_registration = NULL;
    384 
    385   // Drop the live registration, but keep the version live.
    386   live_registration = NULL;
    387 
    388   // Now FindRegistrationForDocument should be async.
    389   EXPECT_EQ(SERVICE_WORKER_OK,
    390             FindRegistrationForDocument(kDocumentUrl, &found_registration));
    391   ASSERT_TRUE(found_registration.get());
    392   EXPECT_EQ(kRegistrationId, found_registration->id());
    393   EXPECT_TRUE(found_registration->HasOneRef());
    394   EXPECT_EQ(live_version.get(), found_registration->waiting_version());
    395   found_registration = NULL;
    396 
    397   // Drop the live version too.
    398   live_version = NULL;
    399 
    400   // And FindRegistrationForPattern is always async.
    401   EXPECT_EQ(SERVICE_WORKER_OK,
    402             FindRegistrationForPattern(kScope, &found_registration));
    403   ASSERT_TRUE(found_registration.get());
    404   EXPECT_EQ(kRegistrationId, found_registration->id());
    405   EXPECT_TRUE(found_registration->HasOneRef());
    406   EXPECT_FALSE(found_registration->active_version());
    407   ASSERT_TRUE(found_registration->waiting_version());
    408   EXPECT_EQ(kYesterday, found_registration->last_update_check());
    409   EXPECT_EQ(ServiceWorkerVersion::INSTALLED,
    410             found_registration->waiting_version()->status());
    411 
    412   // Update to active and update the last check time.
    413   scoped_refptr<ServiceWorkerVersion> temp_version =
    414       found_registration->waiting_version();
    415   temp_version->SetStatus(ServiceWorkerVersion::ACTIVATED);
    416   found_registration->SetActiveVersion(temp_version.get());
    417   temp_version = NULL;
    418   EXPECT_EQ(SERVICE_WORKER_OK, UpdateToActiveState(found_registration));
    419   found_registration->set_last_update_check(kToday);
    420   UpdateLastUpdateCheckTime(found_registration.get());
    421 
    422   found_registration = NULL;
    423 
    424   // Trying to update a unstored registration to active should fail.
    425   scoped_refptr<ServiceWorkerRegistration> unstored_registration =
    426       new ServiceWorkerRegistration(
    427           kScope, kRegistrationId + 1, context_ptr_);
    428   EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
    429             UpdateToActiveState(unstored_registration));
    430   unstored_registration = NULL;
    431 
    432   // The Find methods should return a registration with an active version
    433   // and the expected update time.
    434   EXPECT_EQ(SERVICE_WORKER_OK,
    435             FindRegistrationForDocument(kDocumentUrl, &found_registration));
    436   ASSERT_TRUE(found_registration.get());
    437   EXPECT_EQ(kRegistrationId, found_registration->id());
    438   EXPECT_TRUE(found_registration->HasOneRef());
    439   EXPECT_FALSE(found_registration->waiting_version());
    440   ASSERT_TRUE(found_registration->active_version());
    441   EXPECT_EQ(ServiceWorkerVersion::ACTIVATED,
    442             found_registration->active_version()->status());
    443   EXPECT_EQ(kToday, found_registration->last_update_check());
    444 
    445   // Delete from storage but with a instance still live.
    446   EXPECT_TRUE(context_->GetLiveVersion(kRegistrationId));
    447   EXPECT_EQ(SERVICE_WORKER_OK,
    448             DeleteRegistration(kRegistrationId, kScope.GetOrigin()));
    449   EXPECT_TRUE(context_->GetLiveVersion(kRegistrationId));
    450 
    451   // Should no longer be found.
    452   EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
    453             FindRegistrationForId(
    454                 kRegistrationId, kScope.GetOrigin(), &found_registration));
    455   EXPECT_FALSE(found_registration.get());
    456 
    457   // Deleting an unstored registration should succeed.
    458   EXPECT_EQ(SERVICE_WORKER_OK,
    459             DeleteRegistration(kRegistrationId + 1, kScope.GetOrigin()));
    460 }
    461 
    462 TEST_F(ServiceWorkerStorageTest, InstallingRegistrationsAreFindable) {
    463   const GURL kScope("http://www.test.not/scope/");
    464   const GURL kScript("http://www.test.not/script.js");
    465   const GURL kDocumentUrl("http://www.test.not/scope/document.html");
    466   const int64 kRegistrationId = 0;
    467   const int64 kVersionId = 0;
    468 
    469   scoped_refptr<ServiceWorkerRegistration> found_registration;
    470 
    471   // Create an unstored registration.
    472   scoped_refptr<ServiceWorkerRegistration> live_registration =
    473       new ServiceWorkerRegistration(
    474           kScope, kRegistrationId, context_ptr_);
    475   scoped_refptr<ServiceWorkerVersion> live_version =
    476       new ServiceWorkerVersion(
    477           live_registration.get(), kScript, kVersionId, context_ptr_);
    478   live_version->SetStatus(ServiceWorkerVersion::INSTALLING);
    479   live_registration->SetWaitingVersion(live_version.get());
    480 
    481   // Should not be findable, including by GetAllRegistrations.
    482   EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
    483             FindRegistrationForId(
    484                 kRegistrationId, kScope.GetOrigin(), &found_registration));
    485   EXPECT_FALSE(found_registration.get());
    486 
    487   EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
    488             FindRegistrationForDocument(kDocumentUrl, &found_registration));
    489   EXPECT_FALSE(found_registration.get());
    490 
    491   EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
    492             FindRegistrationForPattern(kScope, &found_registration));
    493   EXPECT_FALSE(found_registration.get());
    494 
    495   std::vector<ServiceWorkerRegistrationInfo> all_registrations;
    496   GetAllRegistrations(&all_registrations);
    497   EXPECT_TRUE(all_registrations.empty());
    498 
    499   // Notify storage of it being installed.
    500   storage()->NotifyInstallingRegistration(live_registration.get());
    501 
    502   // Now should be findable.
    503   EXPECT_EQ(SERVICE_WORKER_OK,
    504             FindRegistrationForId(
    505                 kRegistrationId, kScope.GetOrigin(), &found_registration));
    506   EXPECT_EQ(live_registration, found_registration);
    507   found_registration = NULL;
    508 
    509   EXPECT_EQ(SERVICE_WORKER_OK,
    510             FindRegistrationForDocument(kDocumentUrl, &found_registration));
    511   EXPECT_EQ(live_registration, found_registration);
    512   found_registration = NULL;
    513 
    514   EXPECT_EQ(SERVICE_WORKER_OK,
    515             FindRegistrationForPattern(kScope, &found_registration));
    516   EXPECT_EQ(live_registration, found_registration);
    517   found_registration = NULL;
    518 
    519   GetAllRegistrations(&all_registrations);
    520   EXPECT_EQ(1u, all_registrations.size());
    521   all_registrations.clear();
    522 
    523   // Notify storage of installation no longer happening.
    524   storage()->NotifyDoneInstallingRegistration(
    525       live_registration.get(), NULL, SERVICE_WORKER_OK);
    526 
    527   // Once again, should not be findable.
    528   EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
    529             FindRegistrationForId(
    530                 kRegistrationId, kScope.GetOrigin(), &found_registration));
    531   EXPECT_FALSE(found_registration.get());
    532 
    533   EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
    534             FindRegistrationForDocument(kDocumentUrl, &found_registration));
    535   EXPECT_FALSE(found_registration.get());
    536 
    537   EXPECT_EQ(SERVICE_WORKER_ERROR_NOT_FOUND,
    538             FindRegistrationForPattern(kScope, &found_registration));
    539   EXPECT_FALSE(found_registration.get());
    540 
    541   GetAllRegistrations(&all_registrations);
    542   EXPECT_TRUE(all_registrations.empty());
    543 }
    544 
    545 class ServiceWorkerResourceStorageTest : public ServiceWorkerStorageTest {
    546  public:
    547   virtual void SetUp() OVERRIDE {
    548     ServiceWorkerStorageTest::SetUp();
    549 
    550     storage()->LazyInitialize(base::Bind(&base::DoNothing));
    551     base::RunLoop().RunUntilIdle();
    552     scope_ = GURL("http://www.test.not/scope/");
    553     script_ = GURL("http://www.test.not/script.js");
    554     import_ = GURL("http://www.test.not/import.js");
    555     document_url_ = GURL("http://www.test.not/scope/document.html");
    556     registration_id_ = storage()->NewRegistrationId();
    557     version_id_ = storage()->NewVersionId();
    558     resource_id1_ = storage()->NewResourceId();
    559     resource_id2_ = storage()->NewResourceId();
    560 
    561     // Cons up a new registration+version with two script resources.
    562     RegistrationData data;
    563     data.registration_id = registration_id_;
    564     data.scope = scope_;
    565     data.script = script_;
    566     data.version_id = version_id_;
    567     data.is_active = false;
    568     std::vector<ResourceRecord> resources;
    569     resources.push_back(ResourceRecord(resource_id1_, script_));
    570     resources.push_back(ResourceRecord(resource_id2_, import_));
    571     registration_ = storage()->GetOrCreateRegistration(data, resources);
    572     registration_->waiting_version()->SetStatus(ServiceWorkerVersion::NEW);
    573 
    574     // Add the resources ids to the uncommitted list.
    575     storage()->StoreUncommittedResponseId(resource_id1_);
    576     storage()->StoreUncommittedResponseId(resource_id2_);
    577     base::RunLoop().RunUntilIdle();
    578     std::set<int64> verify_ids;
    579     EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
    580               storage()->database_->GetUncommittedResourceIds(&verify_ids));
    581     EXPECT_EQ(2u, verify_ids.size());
    582 
    583     // And dump something in the disk cache for them.
    584     WriteBasicResponse(storage(), resource_id1_);
    585     WriteBasicResponse(storage(), resource_id2_);
    586     EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_, true));
    587     EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id2_, true));
    588 
    589     // Storing the registration/version should take the resources ids out
    590     // of the uncommitted list.
    591     EXPECT_EQ(
    592         SERVICE_WORKER_OK,
    593         StoreRegistration(registration_, registration_->waiting_version()));
    594     verify_ids.clear();
    595     EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
    596               storage()->database_->GetUncommittedResourceIds(&verify_ids));
    597     EXPECT_TRUE(verify_ids.empty());
    598   }
    599 
    600  protected:
    601   GURL scope_;
    602   GURL script_;
    603   GURL import_;
    604   GURL document_url_;
    605   int64 registration_id_;
    606   int64 version_id_;
    607   int64 resource_id1_;
    608   int64 resource_id2_;
    609   scoped_refptr<ServiceWorkerRegistration> registration_;
    610 };
    611 
    612 class ServiceWorkerResourceStorageDiskTest
    613     : public ServiceWorkerResourceStorageTest {
    614  public:
    615   virtual void SetUp() OVERRIDE {
    616     ASSERT_TRUE(user_data_directory_.CreateUniqueTempDir());
    617     ServiceWorkerResourceStorageTest::SetUp();
    618   }
    619 
    620   virtual base::FilePath GetUserDataDirectory() OVERRIDE {
    621     return user_data_directory_.path();
    622   }
    623 
    624  protected:
    625   base::ScopedTempDir user_data_directory_;
    626 };
    627 
    628 TEST_F(ServiceWorkerResourceStorageTest, DeleteRegistration_NoLiveVersion) {
    629   bool was_called = false;
    630   ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_FAILED;
    631   std::set<int64> verify_ids;
    632 
    633   registration_->SetWaitingVersion(NULL);
    634   registration_ = NULL;
    635 
    636   // Deleting the registration should result in the resources being added to the
    637   // purgeable list and then doomed in the disk cache and removed from that
    638   // list.
    639   storage()->DeleteRegistration(
    640       registration_id_,
    641       scope_.GetOrigin(),
    642       base::Bind(&VerifyPurgeableListStatusCallback,
    643                  base::Unretained(storage()->database_.get()),
    644                  &verify_ids,
    645                  &was_called,
    646                  &result));
    647   base::RunLoop().RunUntilIdle();
    648   ASSERT_TRUE(was_called);
    649   EXPECT_EQ(SERVICE_WORKER_OK, result);
    650   EXPECT_EQ(2u, verify_ids.size());
    651   verify_ids.clear();
    652   EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
    653             storage()->database_->GetPurgeableResourceIds(&verify_ids));
    654   EXPECT_TRUE(verify_ids.empty());
    655 
    656   EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id1_, false));
    657   EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id2_, false));
    658 }
    659 
    660 TEST_F(ServiceWorkerResourceStorageTest, DeleteRegistration_WaitingVersion) {
    661   bool was_called = false;
    662   ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_FAILED;
    663   std::set<int64> verify_ids;
    664 
    665   // Deleting the registration should result in the resources being added to the
    666   // purgeable list and then doomed in the disk cache and removed from that
    667   // list.
    668   storage()->DeleteRegistration(
    669       registration_->id(),
    670       scope_.GetOrigin(),
    671       base::Bind(&VerifyPurgeableListStatusCallback,
    672                  base::Unretained(storage()->database_.get()),
    673                  &verify_ids,
    674                  &was_called,
    675                  &result));
    676   base::RunLoop().RunUntilIdle();
    677   ASSERT_TRUE(was_called);
    678   EXPECT_EQ(SERVICE_WORKER_OK, result);
    679   EXPECT_EQ(2u, verify_ids.size());
    680   verify_ids.clear();
    681   EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
    682             storage()->database_->GetPurgeableResourceIds(&verify_ids));
    683   EXPECT_EQ(2u, verify_ids.size());
    684 
    685   EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_, false));
    686   EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id2_, false));
    687 
    688   // Doom the version, now it happens.
    689   registration_->waiting_version()->Doom();
    690   base::RunLoop().RunUntilIdle();
    691   EXPECT_EQ(SERVICE_WORKER_OK, result);
    692   EXPECT_EQ(2u, verify_ids.size());
    693   verify_ids.clear();
    694   EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
    695             storage()->database_->GetPurgeableResourceIds(&verify_ids));
    696   EXPECT_TRUE(verify_ids.empty());
    697 
    698   EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id1_, false));
    699   EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id2_, false));
    700 }
    701 
    702 TEST_F(ServiceWorkerResourceStorageTest, DeleteRegistration_ActiveVersion) {
    703   // Promote the worker to active and add a controllee.
    704   registration_->SetActiveVersion(registration_->waiting_version());
    705   storage()->UpdateToActiveState(
    706       registration_.get(), base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
    707   scoped_ptr<ServiceWorkerProviderHost> host(
    708       new ServiceWorkerProviderHost(33 /* dummy render process id */,
    709                                     1 /* dummy provider_id */,
    710                                     context_->AsWeakPtr(),
    711                                     NULL));
    712   registration_->active_version()->AddControllee(host.get());
    713 
    714   bool was_called = false;
    715   ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_FAILED;
    716   std::set<int64> verify_ids;
    717 
    718   // Deleting the registration should move the resources to the purgeable list
    719   // but keep them available.
    720   storage()->DeleteRegistration(
    721       registration_->id(),
    722       scope_.GetOrigin(),
    723       base::Bind(&VerifyPurgeableListStatusCallback,
    724                  base::Unretained(storage()->database_.get()),
    725                  &verify_ids,
    726                  &was_called,
    727                  &result));
    728   registration_->active_version()->Doom();
    729   base::RunLoop().RunUntilIdle();
    730   ASSERT_TRUE(was_called);
    731   EXPECT_EQ(SERVICE_WORKER_OK, result);
    732   EXPECT_EQ(2u, verify_ids.size());
    733   verify_ids.clear();
    734   EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
    735             storage()->database_->GetPurgeableResourceIds(&verify_ids));
    736   EXPECT_EQ(2u, verify_ids.size());
    737 
    738   EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_, true));
    739   EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id2_, true));
    740 
    741   // Removing the controllee should cause the resources to be deleted.
    742   registration_->active_version()->RemoveControllee(host.get());
    743   base::RunLoop().RunUntilIdle();
    744   verify_ids.clear();
    745   EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
    746             storage()->database_->GetPurgeableResourceIds(&verify_ids));
    747   EXPECT_TRUE(verify_ids.empty());
    748 
    749   EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id1_, false));
    750   EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id2_, false));
    751 }
    752 
    753 // Android has flaky IO error: http://crbug.com/387045
    754 #if defined(OS_ANDROID)
    755 #define MAYBE_CleanupOnRestart DISABLED_CleanupOnRestart
    756 #else
    757 #define MAYBE_CleanupOnRestart CleanupOnRestart
    758 #endif
    759 TEST_F(ServiceWorkerResourceStorageDiskTest, MAYBE_CleanupOnRestart) {
    760   // Promote the worker to active and add a controllee.
    761   registration_->SetActiveVersion(registration_->waiting_version());
    762   registration_->SetWaitingVersion(NULL);
    763   storage()->UpdateToActiveState(
    764       registration_.get(), base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
    765   scoped_ptr<ServiceWorkerProviderHost> host(
    766       new ServiceWorkerProviderHost(33 /* dummy render process id */,
    767                                     1 /* dummy provider_id */,
    768                                     context_->AsWeakPtr(),
    769                                     NULL));
    770   registration_->active_version()->AddControllee(host.get());
    771 
    772   bool was_called = false;
    773   ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_FAILED;
    774   std::set<int64> verify_ids;
    775 
    776   // Deleting the registration should move the resources to the purgeable list
    777   // but keep them available.
    778   storage()->DeleteRegistration(
    779       registration_->id(),
    780       scope_.GetOrigin(),
    781       base::Bind(&VerifyPurgeableListStatusCallback,
    782                  base::Unretained(storage()->database_.get()),
    783                  &verify_ids,
    784                  &was_called,
    785                  &result));
    786   base::RunLoop().RunUntilIdle();
    787   ASSERT_TRUE(was_called);
    788   EXPECT_EQ(SERVICE_WORKER_OK, result);
    789   EXPECT_EQ(2u, verify_ids.size());
    790   verify_ids.clear();
    791   EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
    792             storage()->database_->GetPurgeableResourceIds(&verify_ids));
    793   EXPECT_EQ(2u, verify_ids.size());
    794 
    795   EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_, true));
    796   EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id2_, true));
    797 
    798   // Also add an uncommitted resource.
    799   int64 kStaleUncommittedResourceId = storage()->NewResourceId();
    800   storage()->StoreUncommittedResponseId(kStaleUncommittedResourceId);
    801   base::RunLoop().RunUntilIdle();
    802   verify_ids.clear();
    803   EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
    804             storage()->database_->GetUncommittedResourceIds(&verify_ids));
    805   EXPECT_EQ(1u, verify_ids.size());
    806   WriteBasicResponse(storage(), kStaleUncommittedResourceId);
    807   EXPECT_TRUE(
    808       VerifyBasicResponse(storage(), kStaleUncommittedResourceId, true));
    809 
    810   // Simulate browser shutdown. The purgeable and uncommitted resources are now
    811   // stale.
    812   context_.reset();
    813   context_.reset(
    814       new ServiceWorkerContextCore(GetUserDataDirectory(),
    815                                    base::ThreadTaskRunnerHandle::Get(),
    816                                    base::ThreadTaskRunnerHandle::Get(),
    817                                    base::ThreadTaskRunnerHandle::Get(),
    818                                    NULL,
    819                                    NULL,
    820                                    NULL));
    821   storage()->LazyInitialize(base::Bind(&base::DoNothing));
    822   base::RunLoop().RunUntilIdle();
    823 
    824   // Store a new uncommitted resource. This triggers stale resource cleanup.
    825   int64 kNewResourceId = storage()->NewResourceId();
    826   WriteBasicResponse(storage(), kNewResourceId);
    827   storage()->StoreUncommittedResponseId(kNewResourceId);
    828   base::RunLoop().RunUntilIdle();
    829 
    830   // The stale resources should be purged, but the new resource should persist.
    831   verify_ids.clear();
    832   EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
    833             storage()->database_->GetUncommittedResourceIds(&verify_ids));
    834   ASSERT_EQ(1u, verify_ids.size());
    835   EXPECT_EQ(kNewResourceId, *verify_ids.begin());
    836 
    837   verify_ids.clear();
    838   EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
    839             storage()->database_->GetPurgeableResourceIds(&verify_ids));
    840   EXPECT_TRUE(verify_ids.empty());
    841   EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id1_, false));
    842   EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id2_, false));
    843   EXPECT_FALSE(
    844       VerifyBasicResponse(storage(), kStaleUncommittedResourceId, false));
    845   EXPECT_TRUE(VerifyBasicResponse(storage(), kNewResourceId, true));
    846 }
    847 
    848 TEST_F(ServiceWorkerResourceStorageTest, UpdateRegistration) {
    849   // Promote the worker to active worker and add a controllee.
    850   registration_->SetActiveVersion(registration_->waiting_version());
    851   storage()->UpdateToActiveState(
    852       registration_.get(), base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
    853   scoped_ptr<ServiceWorkerProviderHost> host(
    854       new ServiceWorkerProviderHost(33 /* dummy render process id */,
    855                                     1 /* dummy provider_id */,
    856                                     context_->AsWeakPtr(),
    857                                     NULL));
    858   registration_->active_version()->AddControllee(host.get());
    859 
    860   bool was_called = false;
    861   ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_FAILED;
    862   std::set<int64> verify_ids;
    863 
    864   // Make an updated registration.
    865   scoped_refptr<ServiceWorkerVersion> live_version = new ServiceWorkerVersion(
    866       registration_.get(), script_, storage()->NewVersionId(), context_ptr_);
    867   live_version->SetStatus(ServiceWorkerVersion::NEW);
    868   registration_->SetWaitingVersion(live_version.get());
    869 
    870   // Writing the registration should move the old version's resources to the
    871   // purgeable list but keep them available.
    872   storage()->StoreRegistration(
    873       registration_.get(),
    874       registration_->waiting_version(),
    875       base::Bind(&VerifyPurgeableListStatusCallback,
    876                  base::Unretained(storage()->database_.get()),
    877                  &verify_ids,
    878                  &was_called,
    879                  &result));
    880   registration_->active_version()->Doom();
    881   base::RunLoop().RunUntilIdle();
    882   ASSERT_TRUE(was_called);
    883   EXPECT_EQ(SERVICE_WORKER_OK, result);
    884   EXPECT_EQ(2u, verify_ids.size());
    885   verify_ids.clear();
    886   EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
    887             storage()->database_->GetPurgeableResourceIds(&verify_ids));
    888   EXPECT_EQ(2u, verify_ids.size());
    889 
    890   EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_, false));
    891   EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id2_, false));
    892 
    893   // Removing the controllee should cause the old version's resources to be
    894   // deleted.
    895   registration_->active_version()->RemoveControllee(host.get());
    896   base::RunLoop().RunUntilIdle();
    897   verify_ids.clear();
    898   EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
    899             storage()->database_->GetPurgeableResourceIds(&verify_ids));
    900   EXPECT_TRUE(verify_ids.empty());
    901 
    902   EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id1_, false));
    903   EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id2_, false));
    904 }
    905 
    906 TEST_F(ServiceWorkerStorageTest, FindRegistration_LongestScopeMatch) {
    907   const GURL kDocumentUrl("http://www.example.com/scope/foo");
    908   scoped_refptr<ServiceWorkerRegistration> found_registration;
    909 
    910   // Registration for "/scope/".
    911   const GURL kScope1("http://www.example.com/scope/");
    912   const GURL kScript1("http://www.example.com/script1.js");
    913   const int64 kRegistrationId1 = 1;
    914   const int64 kVersionId1 = 1;
    915   scoped_refptr<ServiceWorkerRegistration> live_registration1 =
    916       new ServiceWorkerRegistration(
    917           kScope1, kRegistrationId1, context_ptr_);
    918   scoped_refptr<ServiceWorkerVersion> live_version1 =
    919       new ServiceWorkerVersion(
    920           live_registration1.get(), kScript1, kVersionId1, context_ptr_);
    921   live_version1->SetStatus(ServiceWorkerVersion::INSTALLED);
    922   live_registration1->SetWaitingVersion(live_version1.get());
    923 
    924   // Registration for "/scope/foo".
    925   const GURL kScope2("http://www.example.com/scope/foo");
    926   const GURL kScript2("http://www.example.com/script2.js");
    927   const int64 kRegistrationId2 = 2;
    928   const int64 kVersionId2 = 2;
    929   scoped_refptr<ServiceWorkerRegistration> live_registration2 =
    930       new ServiceWorkerRegistration(
    931           kScope2, kRegistrationId2, context_ptr_);
    932   scoped_refptr<ServiceWorkerVersion> live_version2 =
    933       new ServiceWorkerVersion(
    934           live_registration2.get(), kScript2, kVersionId2, context_ptr_);
    935   live_version2->SetStatus(ServiceWorkerVersion::INSTALLED);
    936   live_registration2->SetWaitingVersion(live_version2.get());
    937 
    938   // Registration for "/scope/foobar".
    939   const GURL kScope3("http://www.example.com/scope/foobar");
    940   const GURL kScript3("http://www.example.com/script3.js");
    941   const int64 kRegistrationId3 = 3;
    942   const int64 kVersionId3 = 3;
    943   scoped_refptr<ServiceWorkerRegistration> live_registration3 =
    944       new ServiceWorkerRegistration(
    945           kScope3, kRegistrationId3, context_ptr_);
    946   scoped_refptr<ServiceWorkerVersion> live_version3 =
    947       new ServiceWorkerVersion(
    948           live_registration3.get(), kScript3, kVersionId3, context_ptr_);
    949   live_version3->SetStatus(ServiceWorkerVersion::INSTALLED);
    950   live_registration3->SetWaitingVersion(live_version3.get());
    951 
    952   // Notify storage of they being installed.
    953   storage()->NotifyInstallingRegistration(live_registration1.get());
    954   storage()->NotifyInstallingRegistration(live_registration2.get());
    955   storage()->NotifyInstallingRegistration(live_registration3.get());
    956 
    957   // Find a registration among installing ones.
    958   EXPECT_EQ(SERVICE_WORKER_OK,
    959             FindRegistrationForDocument(kDocumentUrl, &found_registration));
    960   EXPECT_EQ(live_registration2, found_registration);
    961   found_registration = NULL;
    962 
    963   // Store registrations.
    964   EXPECT_EQ(SERVICE_WORKER_OK,
    965             StoreRegistration(live_registration1, live_version1));
    966   EXPECT_EQ(SERVICE_WORKER_OK,
    967             StoreRegistration(live_registration2, live_version2));
    968   EXPECT_EQ(SERVICE_WORKER_OK,
    969             StoreRegistration(live_registration3, live_version3));
    970 
    971   // Notify storage of installations no longer happening.
    972   storage()->NotifyDoneInstallingRegistration(
    973       live_registration1.get(), NULL, SERVICE_WORKER_OK);
    974   storage()->NotifyDoneInstallingRegistration(
    975       live_registration2.get(), NULL, SERVICE_WORKER_OK);
    976   storage()->NotifyDoneInstallingRegistration(
    977       live_registration3.get(), NULL, SERVICE_WORKER_OK);
    978 
    979   // Find a registration among installed ones.
    980   EXPECT_EQ(SERVICE_WORKER_OK,
    981             FindRegistrationForDocument(kDocumentUrl, &found_registration));
    982   EXPECT_EQ(live_registration2, found_registration);
    983 }
    984 
    985 TEST_F(ServiceWorkerStorageTest, CompareResources) {
    986   // Compare two small responses containing the same data.
    987   WriteBasicResponse(storage(), 1);
    988   WriteBasicResponse(storage(), 2);
    989   ServiceWorkerStatusCode status = static_cast<ServiceWorkerStatusCode>(-1);
    990   bool are_equal = false;
    991   storage()->CompareScriptResources(
    992       1, 2,
    993       base::Bind(&OnCompareComplete, &status, &are_equal));
    994   base::RunLoop().RunUntilIdle();
    995   EXPECT_EQ(SERVICE_WORKER_OK, status);
    996   EXPECT_TRUE(are_equal);
    997 
    998   // Compare two small responses with different data.
    999   const char kHttpHeaders[] = "HTTP/1.0 200 HONKYDORY\0\0";
   1000   const char kHttpBody[] = "Goodbye";
   1001   std::string headers(kHttpHeaders, arraysize(kHttpHeaders));
   1002   WriteStringResponse(storage(), 3, headers, std::string(kHttpBody));
   1003   status = static_cast<ServiceWorkerStatusCode>(-1);
   1004   are_equal = true;
   1005   storage()->CompareScriptResources(
   1006       1, 3,
   1007       base::Bind(&OnCompareComplete, &status, &are_equal));
   1008   base::RunLoop().RunUntilIdle();
   1009   EXPECT_EQ(SERVICE_WORKER_OK, status);
   1010   EXPECT_FALSE(are_equal);
   1011 
   1012   // Compare two large responses with the same data.
   1013   const int k32K = 32 * 1024;
   1014   WriteResponseOfSize(storage(), 4, 'a', k32K);
   1015   WriteResponseOfSize(storage(), 5, 'a', k32K);
   1016   status = static_cast<ServiceWorkerStatusCode>(-1);
   1017   are_equal = false;
   1018   storage()->CompareScriptResources(
   1019       4, 5,
   1020       base::Bind(&OnCompareComplete, &status, &are_equal));
   1021   base::RunLoop().RunUntilIdle();
   1022   EXPECT_EQ(SERVICE_WORKER_OK, status);
   1023   EXPECT_TRUE(are_equal);
   1024 
   1025   // Compare a large and small response.
   1026   status = static_cast<ServiceWorkerStatusCode>(-1);
   1027   are_equal = true;
   1028   storage()->CompareScriptResources(
   1029       1, 5,
   1030       base::Bind(&OnCompareComplete, &status, &are_equal));
   1031   base::RunLoop().RunUntilIdle();
   1032   EXPECT_EQ(SERVICE_WORKER_OK, status);
   1033   EXPECT_FALSE(are_equal);
   1034 
   1035   // Compare two large responses with different data.
   1036   WriteResponseOfSize(storage(), 6, 'b', k32K);
   1037   status = static_cast<ServiceWorkerStatusCode>(-1);
   1038   are_equal = true;
   1039   storage()->CompareScriptResources(
   1040       5, 6,
   1041       base::Bind(&OnCompareComplete, &status, &are_equal));
   1042   base::RunLoop().RunUntilIdle();
   1043   EXPECT_EQ(SERVICE_WORKER_OK, status);
   1044   EXPECT_FALSE(are_equal);
   1045 }
   1046 
   1047 }  // namespace content
   1048