| Index: content/browser/service_worker/service_worker_disk_cache_migrator_unittest.cc
|
| diff --git a/content/browser/service_worker/service_worker_disk_cache_migrator_unittest.cc b/content/browser/service_worker/service_worker_disk_cache_migrator_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..7f3f030a3430331453efd75734da7ff18e4ee052
|
| --- /dev/null
|
| +++ b/content/browser/service_worker/service_worker_disk_cache_migrator_unittest.cc
|
| @@ -0,0 +1,241 @@
|
| +// Copyright 2015 The Chromium Authors. All rights reserved.
|
| +// 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_disk_cache_migrator.h"
|
| +
|
| +#include "base/files/scoped_temp_dir.h"
|
| +#include "base/run_loop.h"
|
| +#include "base/thread_task_runner_handle.h"
|
| +#include "content/public/test/test_browser_thread_bundle.h"
|
| +#include "net/base/io_buffer.h"
|
| +#include "net/base/net_errors.h"
|
| +#include "net/base/test_completion_callback.h"
|
| +#include "net/http/http_response_headers.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +namespace content {
|
| +
|
| +namespace {
|
| +
|
| +const int kMaxDiskCacheSize = 250 * 1024 * 1024;
|
| +
|
| +struct ResponseData {
|
| + int64 resource_id;
|
| + std::string headers;
|
| + std::string body;
|
| + std::string metadata;
|
| +
|
| + ResponseData(int64 resource_id,
|
| + const std::string& headers,
|
| + const std::string& body,
|
| + const std::string& metadata)
|
| + : resource_id(resource_id),
|
| + headers(headers),
|
| + body(body),
|
| + metadata(metadata) {}
|
| +};
|
| +
|
| +void OnDiskCacheMigrated(const base::Closure& callback,
|
| + ServiceWorkerStatusCode status) {
|
| + EXPECT_EQ(SERVICE_WORKER_OK, status);
|
| + callback.Run();
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +class ServiceWorkerDiskCacheMigratorTest : public testing::Test {
|
| + public:
|
| + ServiceWorkerDiskCacheMigratorTest()
|
| + : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {}
|
| +
|
| + void SetUp() override {
|
| + ASSERT_TRUE(user_data_directory_.CreateUniqueTempDir());
|
| + const base::FilePath kSrcDiskCachePath =
|
| + user_data_directory_.path().AppendASCII("SrcCache");
|
| + const base::FilePath kDestDiskCachePath =
|
| + user_data_directory_.path().AppendASCII("DestCache");
|
| +
|
| + // Initialize the src BlockFile diskcache.
|
| + src_ = ServiceWorkerDiskCache::CreateWithBlockFileBackend();
|
| + net::TestCompletionCallback cb1;
|
| + src_->InitWithDiskBackend(
|
| + kSrcDiskCachePath, kMaxDiskCacheSize, false /* force */,
|
| + base::ThreadTaskRunnerHandle::Get(), cb1.callback());
|
| + ASSERT_EQ(net::OK, cb1.WaitForResult());
|
| +
|
| + // Initialize the dest Simple diskcache.
|
| + dest_ = ServiceWorkerDiskCache::CreateWithSimpleBackend();
|
| + net::TestCompletionCallback cb2;
|
| + dest_->InitWithDiskBackend(
|
| + kDestDiskCachePath, kMaxDiskCacheSize, false /* force */,
|
| + base::ThreadTaskRunnerHandle::Get(), cb2.callback());
|
| + ASSERT_EQ(net::OK, cb2.WaitForResult());
|
| +
|
| + migrator_.reset(
|
| + new ServiceWorkerDiskCacheMigrator(src_.get(), dest_.get()));
|
| + }
|
| +
|
| + bool WriteResponse(ServiceWorkerDiskCache* disk_cache,
|
| + const ResponseData& response) {
|
| + scoped_ptr<ServiceWorkerResponseWriter> writer(
|
| + new ServiceWorkerResponseWriter(response.resource_id, disk_cache));
|
| +
|
| + // Write the response info.
|
| + scoped_ptr<net::HttpResponseInfo> info(new net::HttpResponseInfo);
|
| + info->request_time = base::Time() + base::TimeDelta::FromSeconds(10);
|
| + info->response_time = info->request_time + base::TimeDelta::FromSeconds(10);
|
| + info->was_cached = false;
|
| + info->headers = new net::HttpResponseHeaders(response.headers);
|
| + scoped_refptr<HttpResponseInfoIOBuffer> info_buffer =
|
| + new HttpResponseInfoIOBuffer(info.release());
|
| + net::TestCompletionCallback cb1;
|
| + writer->WriteInfo(info_buffer.get(), cb1.callback());
|
| + int rv = cb1.WaitForResult();
|
| + EXPECT_LT(0, rv);
|
| + if (rv < 0)
|
| + return false;
|
| +
|
| + // Write the response metadata.
|
| + scoped_ptr<ServiceWorkerResponseMetadataWriter> metadata_writer(
|
| + new ServiceWorkerResponseMetadataWriter(response.resource_id,
|
| + disk_cache));
|
| + scoped_refptr<net::IOBuffer> metadata_buffer(
|
| + new net::WrappedIOBuffer(response.metadata.data()));
|
| + const int metadata_length = response.metadata.length();
|
| + net::TestCompletionCallback cb2;
|
| + metadata_writer->WriteMetadata(metadata_buffer.get(), metadata_length,
|
| + cb2.callback());
|
| + rv = cb2.WaitForResult();
|
| + EXPECT_EQ(metadata_length, rv);
|
| + if (metadata_length != rv)
|
| + return false;
|
| +
|
| + // Write the response body.
|
| + scoped_refptr<net::IOBuffer> body_buffer(
|
| + new net::WrappedIOBuffer(response.body.data()));
|
| + const int body_length = response.body.length();
|
| + net::TestCompletionCallback cb3;
|
| + writer->WriteData(body_buffer.get(), body_length, cb3.callback());
|
| + rv = cb3.WaitForResult();
|
| + EXPECT_EQ(body_length, rv);
|
| + if (body_length != rv)
|
| + return false;
|
| +
|
| + return true;
|
| + }
|
| +
|
| + void VerifyResponse(ServiceWorkerDiskCache* disk_cache,
|
| + const ResponseData& expected) {
|
| + scoped_ptr<ServiceWorkerResponseReader> reader(
|
| + new ServiceWorkerResponseReader(expected.resource_id, disk_cache));
|
| +
|
| + // Verify the response info.
|
| + scoped_refptr<HttpResponseInfoIOBuffer> info_buffer =
|
| + new HttpResponseInfoIOBuffer;
|
| + net::TestCompletionCallback cb1;
|
| + reader->ReadInfo(info_buffer.get(), cb1.callback());
|
| + int rv = cb1.WaitForResult();
|
| + EXPECT_LT(0, rv);
|
| + EXPECT_EQ("OK", info_buffer->http_info->headers->GetStatusText());
|
| +
|
| + // Verify the response metadata.
|
| + if (!expected.metadata.empty()) {
|
| + ASSERT_TRUE(info_buffer->http_info->metadata);
|
| + const int data_size = info_buffer->http_info->metadata->size();
|
| + ASSERT_EQ(static_cast<int>(expected.metadata.length()), data_size);
|
| + EXPECT_EQ(0, memcmp(expected.metadata.data(),
|
| + info_buffer->http_info->metadata->data(),
|
| + expected.metadata.length()));
|
| + }
|
| +
|
| + // Verify the response body.
|
| + const int kBigEnough = 512;
|
| + scoped_refptr<net::IOBuffer> body_buffer = new net::IOBuffer(kBigEnough);
|
| + net::TestCompletionCallback cb2;
|
| + reader->ReadData(body_buffer.get(), kBigEnough, cb2.callback());
|
| + rv = cb2.WaitForResult();
|
| + ASSERT_EQ(static_cast<int>(expected.body.length()), rv);
|
| + EXPECT_EQ(0, memcmp(expected.body.data(), body_buffer->data(), rv));
|
| + }
|
| +
|
| + void Migrate() {
|
| + base::RunLoop run_loop;
|
| + migrator_->Start(base::Bind(&OnDiskCacheMigrated, run_loop.QuitClosure()));
|
| + run_loop.Run();
|
| + }
|
| +
|
| + int32 GetEntryCount(ServiceWorkerDiskCache* disk_cache) {
|
| + return disk_cache->disk_cache()->GetEntryCount();
|
| + }
|
| +
|
| + void SetMaxNumberOfInflightTasks(size_t max_number) {
|
| + migrator_->set_max_number_of_inflight_tasks(max_number);
|
| + }
|
| +
|
| + protected:
|
| + TestBrowserThreadBundle browser_thread_bundle_;
|
| + base::ScopedTempDir user_data_directory_;
|
| + scoped_ptr<ServiceWorkerDiskCache> src_;
|
| + scoped_ptr<ServiceWorkerDiskCache> dest_;
|
| + scoped_ptr<ServiceWorkerDiskCacheMigrator> migrator_;
|
| +};
|
| +
|
| +TEST_F(ServiceWorkerDiskCacheMigratorTest, Basic) {
|
| + std::vector<ResponseData> responses;
|
| + responses.push_back(ResponseData(1, "HTTP/1.1 200 OK\0\0", "Hello", ""));
|
| + responses.push_back(ResponseData(2, "HTTP/1.1 200 OK\0\0", "Service", ""));
|
| + responses.push_back(ResponseData(5, "HTTP/1.1 200 OK\0\0", "Worker", ""));
|
| + responses.push_back(ResponseData(3, "HTTP/1.1 200 OK\0\0", "World", "meta"));
|
| + responses.push_back(ResponseData(10, "HTTP/1.1 200 OK\0\0", "", "meta"));
|
| + responses.push_back(ResponseData(11, "HTTP/1.1 200 OK\0\0", "body", ""));
|
| + responses.push_back(ResponseData(12, "HTTP/1.1 200 OK\0\0", "", ""));
|
| + responses.push_back(ResponseData(
|
| + 20, "HTTP/1.1 200 OK\0\0", std::string(256, 'a'), std::string(128, 'b')));
|
| +
|
| + // Populate initial data in the src diskcache.
|
| + for (const ResponseData& response : responses) {
|
| + ASSERT_TRUE(WriteResponse(src_.get(), response));
|
| + VerifyResponse(src_.get(), response);
|
| + }
|
| + ASSERT_EQ(static_cast<int>(responses.size()), GetEntryCount(src_.get()));
|
| +
|
| + Migrate();
|
| +
|
| + // Verify the migrated contents in the dest diskcache.
|
| + for (const ResponseData& response : responses)
|
| + VerifyResponse(dest_.get(), response);
|
| + EXPECT_EQ(static_cast<int>(responses.size()), GetEntryCount(dest_.get()));
|
| +}
|
| +
|
| +TEST_F(ServiceWorkerDiskCacheMigratorTest, MigrateEmptyDiskCache) {
|
| + ASSERT_EQ(0, GetEntryCount(src_.get()));
|
| + Migrate();
|
| + EXPECT_EQ(0, GetEntryCount(dest_.get()));
|
| +}
|
| +
|
| +TEST_F(ServiceWorkerDiskCacheMigratorTest, ThrottleInflightTasks) {
|
| + std::vector<ResponseData> responses;
|
| + for (int i = 0; i < 10; ++i)
|
| + responses.push_back(ResponseData(i, "HTTP/1.1 200 OK\0\0", "foo", "bar"));
|
| +
|
| + // Populate initial data in the src diskcache.
|
| + for (const ResponseData& response : responses) {
|
| + ASSERT_TRUE(WriteResponse(src_.get(), response));
|
| + VerifyResponse(src_.get(), response);
|
| + }
|
| + ASSERT_EQ(static_cast<int>(responses.size()), GetEntryCount(src_.get()));
|
| +
|
| + // Tighten the max number of inflight tasks.
|
| + SetMaxNumberOfInflightTasks(2);
|
| +
|
| + // Migration should hit the limit, but should successfully complete.
|
| + Migrate();
|
| +
|
| + // Verify the migrated contents in the dest diskcache.
|
| + for (const ResponseData& response : responses)
|
| + VerifyResponse(dest_.get(), response);
|
| + EXPECT_EQ(static_cast<int>(responses.size()), GetEntryCount(dest_.get()));
|
| +}
|
| +
|
| +} // namespace content
|
|
|