| Index: content/browser/service_worker/service_worker_storage_unittest.cc
|
| diff --git a/content/browser/service_worker/service_worker_storage_unittest.cc b/content/browser/service_worker/service_worker_storage_unittest.cc
|
| index de20af395e3b8d3fec87f9e74183d451fb630255..b95c25ff687cf693eee2e2c6d970d684b13300c5 100644
|
| --- a/content/browser/service_worker/service_worker_storage_unittest.cc
|
| +++ b/content/browser/service_worker/service_worker_storage_unittest.cc
|
| @@ -2,22 +2,32 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| -#include "content/browser/service_worker/service_worker_storage.h"
|
| -
|
| #include "base/logging.h"
|
| #include "base/message_loop/message_loop.h"
|
| #include "base/run_loop.h"
|
| #include "content/browser/browser_thread_impl.h"
|
| #include "content/browser/service_worker/service_worker_context_core.h"
|
| +#include "content/browser/service_worker/service_worker_disk_cache.h"
|
| #include "content/browser/service_worker/service_worker_registration.h"
|
| +#include "content/browser/service_worker/service_worker_storage.h"
|
| #include "content/browser/service_worker/service_worker_version.h"
|
| +#include "content/common/service_worker/service_worker_status_code.h"
|
| #include "content/public/test/test_browser_thread_bundle.h"
|
| +#include "net/base/io_buffer.h"
|
| +#include "net/base/net_errors.h"
|
| +#include "net/http/http_response_headers.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
|
|
| +using net::IOBuffer;
|
| +using net::WrappedIOBuffer;
|
| +
|
| namespace content {
|
|
|
| namespace {
|
|
|
| +typedef ServiceWorkerDatabase::RegistrationData RegistrationData;
|
| +typedef ServiceWorkerDatabase::ResourceRecord ResourceRecord;
|
| +
|
| void StatusCallback(bool* was_called,
|
| ServiceWorkerStatusCode* result,
|
| ServiceWorkerStatusCode status) {
|
| @@ -63,6 +73,74 @@ ServiceWorkerStorage::GetAllRegistrationInfosCallback MakeGetAllCallback(
|
| return base::Bind(&GetAllCallback, was_called, all);
|
| }
|
|
|
| +void OnIOComplete(int* rv_out, int rv) {
|
| + *rv_out = rv;
|
| +}
|
| +
|
| +void WriteBasicResponse(ServiceWorkerStorage* storage, int64 id) {
|
| + scoped_ptr<ServiceWorkerResponseWriter> writer =
|
| + storage->CreateResponseWriter(id);
|
| +
|
| + const char kHttpHeaders[] =
|
| + "HTTP/1.0 200 HONKYDORY\0Content-Length: 6\0\0";
|
| + const char kHttpBody[] = "Hello\0";
|
| + scoped_refptr<IOBuffer> body(new WrappedIOBuffer(kHttpBody));
|
| + std::string raw_headers(kHttpHeaders, arraysize(kHttpHeaders));
|
| + scoped_ptr<net::HttpResponseInfo> info(new net::HttpResponseInfo);
|
| + info->request_time = base::Time::Now();
|
| + info->response_time = base::Time::Now();
|
| + info->was_cached = false;
|
| + info->headers = new net::HttpResponseHeaders(raw_headers);
|
| + scoped_refptr<HttpResponseInfoIOBuffer> info_buffer =
|
| + new HttpResponseInfoIOBuffer(info.release());
|
| +
|
| + int rv = -1234;
|
| + writer->WriteInfo(info_buffer, base::Bind(&OnIOComplete, &rv));
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_LT(0, rv);
|
| +
|
| + rv = -1234;
|
| + writer->WriteData(body, arraysize(kHttpBody),
|
| + base::Bind(&OnIOComplete, &rv));
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_EQ(static_cast<int>(arraysize(kHttpBody)), rv);
|
| +}
|
| +
|
| +bool VerifyBasicResponse(ServiceWorkerStorage* storage, int64 id,
|
| + bool expected_positive_result) {
|
| + const char kExpectedHttpBody[] = "Hello\0";
|
| + scoped_ptr<ServiceWorkerResponseReader> reader =
|
| + storage->CreateResponseReader(id);
|
| + scoped_refptr<HttpResponseInfoIOBuffer> info_buffer =
|
| + new HttpResponseInfoIOBuffer();
|
| + int rv = -1234;
|
| + reader->ReadInfo(info_buffer, base::Bind(&OnIOComplete, &rv));
|
| + base::RunLoop().RunUntilIdle();
|
| + if (expected_positive_result)
|
| + EXPECT_LT(0, rv);
|
| + if (rv <= 0)
|
| + return false;
|
| +
|
| + const int kBigEnough = 512;
|
| + scoped_refptr<net::IOBuffer> buffer = new IOBuffer(kBigEnough);
|
| + rv = -1234;
|
| + reader->ReadData(buffer, kBigEnough, base::Bind(&OnIOComplete, &rv));
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_EQ(static_cast<int>(arraysize(kExpectedHttpBody)), rv);
|
| + if (rv <= 0)
|
| + return false;
|
| +
|
| + bool status_match =
|
| + std::string("HONKYDORY") ==
|
| + info_buffer->http_info->headers->GetStatusText();
|
| + bool data_match =
|
| + std::string(kExpectedHttpBody) == std::string(buffer->data());
|
| +
|
| + EXPECT_TRUE(status_match);
|
| + EXPECT_TRUE(data_match);
|
| + return status_match && data_match;
|
| +}
|
| +
|
| } // namespace
|
|
|
| class ServiceWorkerStorageTest : public testing::Test {
|
| @@ -88,6 +166,19 @@ class ServiceWorkerStorageTest : public testing::Test {
|
|
|
| ServiceWorkerStorage* storage() { return context_->storage(); }
|
|
|
| + // A static class method for friendliness.
|
| + static void VerifyPurgeableListStatusCallback(
|
| + ServiceWorkerDatabase* database,
|
| + std::set<int64> *purgeable_ids,
|
| + bool* was_called,
|
| + ServiceWorkerStatusCode* result,
|
| + ServiceWorkerStatusCode status) {
|
| + *was_called = true;
|
| + *result = status;
|
| + EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
|
| + database->GetPurgeableResourceIds(purgeable_ids));
|
| + }
|
| +
|
| protected:
|
| scoped_ptr<ServiceWorkerContextCore> context_;
|
| base::WeakPtr<ServiceWorkerContextCore> context_ptr_;
|
| @@ -95,9 +186,9 @@ class ServiceWorkerStorageTest : public testing::Test {
|
| };
|
|
|
| TEST_F(ServiceWorkerStorageTest, StoreFindUpdateDeleteRegistration) {
|
| - const GURL kScope("http://www.test.com/scope/*");
|
| - const GURL kScript("http://www.test.com/script.js");
|
| - const GURL kDocumentUrl("http://www.test.com/scope/document.html");
|
| + const GURL kScope("http://www.test.not/scope/*");
|
| + const GURL kScript("http://www.test.not/script.js");
|
| + const GURL kDocumentUrl("http://www.test.not/scope/document.html");
|
| const int64 kRegistrationId = 0;
|
| const int64 kVersionId = 0;
|
|
|
| @@ -310,9 +401,9 @@ TEST_F(ServiceWorkerStorageTest, StoreFindUpdateDeleteRegistration) {
|
| }
|
|
|
| TEST_F(ServiceWorkerStorageTest, InstallingRegistrationsAreFindable) {
|
| - const GURL kScope("http://www.test.com/scope/*");
|
| - const GURL kScript("http://www.test.com/script.js");
|
| - const GURL kDocumentUrl("http://www.test.com/scope/document.html");
|
| + const GURL kScope("http://www.test.not/scope/*");
|
| + const GURL kScript("http://www.test.not/script.js");
|
| + const GURL kDocumentUrl("http://www.test.not/scope/document.html");
|
| const int64 kRegistrationId = 0;
|
| const int64 kVersionId = 0;
|
|
|
| @@ -442,4 +533,80 @@ TEST_F(ServiceWorkerStorageTest, InstallingRegistrationsAreFindable) {
|
| was_called = false;
|
| }
|
|
|
| +TEST_F(ServiceWorkerStorageTest, ResourceIdsAreStoredAndPurged) {
|
| + storage()->LazyInitialize(base::Bind(&base::DoNothing));
|
| + base::RunLoop().RunUntilIdle();
|
| + const GURL kScope("http://www.test.not/scope/*");
|
| + const GURL kScript("http://www.test.not/script.js");
|
| + const GURL kImport("http://www.test.not/import.js");
|
| + const GURL kDocumentUrl("http://www.test.not/scope/document.html");
|
| + const int64 kRegistrationId = storage()->NewRegistrationId();
|
| + const int64 kVersionId = storage()->NewVersionId();
|
| + const int64 kResourceId1 = storage()->NewResourceId();
|
| + const int64 kResourceId2 = storage()->NewResourceId();
|
| +
|
| + // Cons up a new registration+version with two script resources.
|
| + RegistrationData data;
|
| + data.registration_id = kRegistrationId;
|
| + data.scope = kScope;
|
| + data.script = kScript;
|
| + data.version_id = kVersionId;
|
| + data.is_active = false;
|
| + std::vector<ResourceRecord> resources;
|
| + resources.push_back(ResourceRecord(kResourceId1, kScript));
|
| + resources.push_back(ResourceRecord(kResourceId2, kImport));
|
| + scoped_refptr<ServiceWorkerRegistration> registration =
|
| + storage()->GetOrCreateRegistration(data, resources);
|
| + registration->pending_version()->SetStatus(ServiceWorkerVersion::NEW);
|
| +
|
| + // Add the resources ids to the uncommitted list.
|
| + std::set<int64> resource_ids;
|
| + resource_ids.insert(kResourceId1);
|
| + resource_ids.insert(kResourceId2);
|
| + EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
|
| + storage()->database_->WriteUncommittedResourceIds(resource_ids));
|
| +
|
| + // And dump something in the disk cache for them.
|
| + WriteBasicResponse(storage(), kResourceId1);
|
| + WriteBasicResponse(storage(), kResourceId2);
|
| + EXPECT_TRUE(VerifyBasicResponse(storage(), kResourceId1, true));
|
| + EXPECT_TRUE(VerifyBasicResponse(storage(), kResourceId2, true));
|
| +
|
| + // Storing the registration/version should take the resources ids out
|
| + // of the uncommitted list.
|
| + bool was_called = false;
|
| + ServiceWorkerStatusCode result = SERVICE_WORKER_ERROR_FAILED;
|
| + storage()->StoreRegistration(registration, registration->pending_version(),
|
| + MakeStatusCallback(&was_called, &result));
|
| + base::RunLoop().RunUntilIdle();
|
| + ASSERT_TRUE(was_called);
|
| + EXPECT_EQ(SERVICE_WORKER_OK, result);
|
| + std::set<int64> verify_ids;
|
| + EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
|
| + storage()->database_->GetUncommittedResourceIds(&verify_ids));
|
| + EXPECT_TRUE(verify_ids.empty());
|
| +
|
| + // Deleting it should result in the resources being added to the
|
| + // purgeable list and then doomed in the disk cache and removed from
|
| + // that list.
|
| + was_called = false;
|
| + verify_ids.clear();
|
| + storage()->DeleteRegistration(
|
| + registration->id(), kScope.GetOrigin(),
|
| + base::Bind(&VerifyPurgeableListStatusCallback,
|
| + base::Unretained(storage()->database_.get()),
|
| + &verify_ids, &was_called, &result));
|
| + base::RunLoop().RunUntilIdle();
|
| + ASSERT_TRUE(was_called);
|
| + EXPECT_EQ(SERVICE_WORKER_OK, result);
|
| + EXPECT_EQ(2u, verify_ids.size());
|
| + verify_ids.clear();
|
| + EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
|
| + storage()->database_->GetPurgeableResourceIds(&verify_ids));
|
| + EXPECT_TRUE(verify_ids.empty());
|
| +
|
| + EXPECT_FALSE(VerifyBasicResponse(storage(), kResourceId1, false));
|
| + EXPECT_FALSE(VerifyBasicResponse(storage(), kResourceId2, false));
|
| +}
|
| +
|
| } // namespace content
|
|
|