Chromium Code Reviews| 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..9322bb845400937b3c0fc60c4a30c1f6f9a0f541 100644 |
| --- a/content/browser/service_worker/service_worker_storage_unittest.cc |
| +++ b/content/browser/service_worker/service_worker_storage_unittest.cc |
| @@ -2,22 +2,31 @@ |
| // 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/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 +72,78 @@ ServiceWorkerStorage::GetAllRegistrationInfosCallback MakeGetAllCallback( |
| return base::Bind(&GetAllCallback, was_called, all); |
| } |
| +void NoopCallback() { |
|
nhiroki
2014/05/22 01:20:13
You may want to use DoNothing() in bind_helpers.h.
michaeln
2014/05/22 02:02:37
Done, ty!
|
| +} |
| + |
| +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)); |
|
nhiroki
2014/05/22 01:20:13
indent-nit.
michaeln
2014/05/22 02:02:37
Done.
|
| + base::RunLoop().RunUntilIdle(); |
| + EXPECT_EQ(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); |
| + } |
|
nhiroki
2014/05/22 01:20:13
nit: you can remove "{}"
michaeln
2014/05/22 02:02:37
Done. (mysterious macro w/o brackets spooks me tho
nhiroki
2014/05/22 03:15:34
Ah... sorry, I unthoughtfully commented this after
|
| + 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(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 +169,18 @@ 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; |
| + database->GetPurgeableResourceIds(purgeable_ids); |
|
nhiroki
2014/05/22 01:20:13
Can you check a status code of GetPurgeableResourc
michaeln
2014/05/22 02:02:37
Done.
|
| + } |
| + |
| protected: |
| scoped_ptr<ServiceWorkerContextCore> context_; |
| base::WeakPtr<ServiceWorkerContextCore> context_ptr_; |
| @@ -442,4 +535,82 @@ TEST_F(ServiceWorkerStorageTest, InstallingRegistrationsAreFindable) { |
| was_called = false; |
| } |
| +TEST_F(ServiceWorkerStorageTest, ResourceIdsAreStoredAndPurged) { |
| + storage()->LazyInitialize(base::Bind(&NoopCallback)); |
| + base::RunLoop().RunUntilIdle(); |
| + const GURL kScope("http://www.test.com/scope/*"); |
|
nhiroki
2014/05/22 01:20:13
"www.test.com" seems to be a domain for an actual
michaeln
2014/05/22 02:02:37
does it matter? no network traffic is generated by
nhiroki
2014/05/22 03:15:34
Yes, this doesn't generate any traffic.
Probably
|
| + const GURL kScript("http://www.test.com/script.js"); |
| + const GURL kImport("http://www.test.com/import.js"); |
| + const GURL kDocumentUrl("http://www.test.com/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 = |
| + ServiceWorkerStatusCode::SERVICE_WORKER_ERROR_FAILED; |
| + storage()->StoreRegistration(registration, registration->pending_version(), |
| + MakeStatusCallback(&was_called, &result)); |
| + base::RunLoop().RunUntilIdle(); |
| + ASSERT_TRUE(was_called); |
| + EXPECT_EQ(ServiceWorkerStatusCode::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 |
| + // purgable list and then doomed in the disk cache and removed from |
|
nhiroki
2014/05/22 01:20:13
nit: s/purgable/purgeable/
michaeln
2014/05/22 02:02:37
Done.
|
| + // 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)); |
|
nhiroki
2014/05/22 01:20:13
indent-nit.
michaeln
2014/05/22 02:02:37
Done.
|
| + base::RunLoop().RunUntilIdle(); |
| + ASSERT_TRUE(was_called); |
| + EXPECT_EQ(ServiceWorkerStatusCode::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 |