| 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
|
| index 7f3f030a3430331453efd75734da7ff18e4ee052..9e7b1a6a78de4e29afd7714d6c1076cadeaa8423 100644
|
| --- a/content/browser/service_worker/service_worker_disk_cache_migrator_unittest.cc
|
| +++ b/content/browser/service_worker/service_worker_disk_cache_migrator_unittest.cc
|
| @@ -4,9 +4,12 @@
|
|
|
| #include "content/browser/service_worker/service_worker_disk_cache_migrator.h"
|
|
|
| +#include "base/files/file_util.h"
|
| #include "base/files/scoped_temp_dir.h"
|
| #include "base/run_loop.h"
|
| #include "base/thread_task_runner_handle.h"
|
| +#include "content/browser/service_worker/service_worker_context_core.h"
|
| +#include "content/browser/service_worker/service_worker_storage.h"
|
| #include "content/public/test/test_browser_thread_bundle.h"
|
| #include "net/base/io_buffer.h"
|
| #include "net/base/net_errors.h"
|
| @@ -42,6 +45,13 @@ void OnDiskCacheMigrated(const base::Closure& callback,
|
| callback.Run();
|
| }
|
|
|
| +void OnRegistrationFound(
|
| + const base::Closure& callback,
|
| + ServiceWorkerStatusCode status,
|
| + const scoped_refptr<ServiceWorkerRegistration>& registration) {
|
| + callback.Run();
|
| +}
|
| +
|
| } // namespace
|
|
|
| class ServiceWorkerDiskCacheMigratorTest : public testing::Test {
|
| @@ -51,29 +61,47 @@ class ServiceWorkerDiskCacheMigratorTest : public testing::Test {
|
|
|
| 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");
|
| + scoped_ptr<ServiceWorkerDatabaseTaskManager> database_task_manager(
|
| + new MockServiceWorkerDatabaseTaskManager(
|
| + base::ThreadTaskRunnerHandle::Get()));
|
| +
|
| + context_.reset(new ServiceWorkerContextCore(
|
| + user_data_directory_.path(), database_task_manager.Pass(),
|
| + base::ThreadTaskRunnerHandle::Get(), nullptr, nullptr, nullptr,
|
| + nullptr));
|
| + }
|
|
|
| - // 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());
|
| + void TearDown() override {
|
| + context_.reset();
|
| + base::RunLoop().RunUntilIdle();
|
| + }
|
|
|
| - // 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());
|
| + scoped_ptr<ServiceWorkerDiskCache> CreateSrcDiskCache() {
|
| + scoped_ptr<ServiceWorkerDiskCache> src(
|
| + ServiceWorkerDiskCache::CreateWithBlockFileBackend());
|
| + net::TestCompletionCallback cb;
|
| + src->InitWithDiskBackend(
|
| + storage()->GetOldDiskCachePath(), kMaxDiskCacheSize, false /* force */,
|
| + base::ThreadTaskRunnerHandle::Get(), cb.callback());
|
| + EXPECT_EQ(net::OK, cb.WaitForResult());
|
| + return src.Pass();
|
| + }
|
| +
|
| + scoped_ptr<ServiceWorkerDiskCache> CreateDestDiskCache() {
|
| + scoped_ptr<ServiceWorkerDiskCache> dest(
|
| + ServiceWorkerDiskCache::CreateWithSimpleBackend());
|
| + net::TestCompletionCallback cb;
|
| + dest->InitWithDiskBackend(
|
| + storage()->GetDiskCachePath(), kMaxDiskCacheSize, false /* force */,
|
| + base::ThreadTaskRunnerHandle::Get(), cb.callback());
|
| + EXPECT_EQ(net::OK, cb.WaitForResult());
|
| + return dest.Pass();
|
| + }
|
|
|
| - migrator_.reset(
|
| - new ServiceWorkerDiskCacheMigrator(src_.get(), dest_.get()));
|
| + scoped_ptr<ServiceWorkerDiskCacheMigrator> CreateMigrator() {
|
| + return make_scoped_ptr(new ServiceWorkerDiskCacheMigrator(
|
| + storage()->GetOldDiskCachePath(), storage()->GetDiskCachePath(),
|
| + kMaxDiskCacheSize, base::ThreadTaskRunnerHandle::Get()));
|
| }
|
|
|
| bool WriteResponse(ServiceWorkerDiskCache* disk_cache,
|
| @@ -159,29 +187,20 @@ class ServiceWorkerDiskCacheMigratorTest : public testing::Test {
|
| 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);
|
| - }
|
| + ServiceWorkerStorage* storage() { return context_->storage(); }
|
|
|
| - protected:
|
| + private:
|
| TestBrowserThreadBundle browser_thread_bundle_;
|
| base::ScopedTempDir user_data_directory_;
|
| - scoped_ptr<ServiceWorkerDiskCache> src_;
|
| - scoped_ptr<ServiceWorkerDiskCache> dest_;
|
| - scoped_ptr<ServiceWorkerDiskCacheMigrator> migrator_;
|
| +
|
| + scoped_ptr<ServiceWorkerContextCore> context_;
|
| };
|
|
|
| -TEST_F(ServiceWorkerDiskCacheMigratorTest, Basic) {
|
| +TEST_F(ServiceWorkerDiskCacheMigratorTest, MigrateDiskCache) {
|
| 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", ""));
|
| @@ -194,24 +213,84 @@ TEST_F(ServiceWorkerDiskCacheMigratorTest, Basic) {
|
| 20, "HTTP/1.1 200 OK\0\0", std::string(256, 'a'), std::string(128, 'b')));
|
|
|
| // Populate initial data in the src diskcache.
|
| + scoped_ptr<ServiceWorkerDiskCache> src(CreateSrcDiskCache());
|
| for (const ResponseData& response : responses) {
|
| - ASSERT_TRUE(WriteResponse(src_.get(), response));
|
| - VerifyResponse(src_.get(), response);
|
| + ASSERT_TRUE(WriteResponse(src.get(), response));
|
| + VerifyResponse(src.get(), response);
|
| }
|
| - ASSERT_EQ(static_cast<int>(responses.size()), GetEntryCount(src_.get()));
|
| + ASSERT_EQ(static_cast<int>(responses.size()), GetEntryCount(src.get()));
|
| + src.reset();
|
|
|
| - Migrate();
|
| + // Start the migrator.
|
| + base::RunLoop run_loop;
|
| + scoped_ptr<ServiceWorkerDiskCacheMigrator> migrator(CreateMigrator());
|
| + migrator->Start(base::Bind(&OnDiskCacheMigrated, run_loop.QuitClosure()));
|
| + run_loop.Run();
|
|
|
| // Verify the migrated contents in the dest diskcache.
|
| + scoped_ptr<ServiceWorkerDiskCache> dest(CreateDestDiskCache());
|
| for (const ResponseData& response : responses)
|
| - VerifyResponse(dest_.get(), response);
|
| - EXPECT_EQ(static_cast<int>(responses.size()), GetEntryCount(dest_.get()));
|
| + 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()));
|
| + scoped_ptr<ServiceWorkerDiskCache> src(CreateSrcDiskCache());
|
| + ASSERT_EQ(0, GetEntryCount(src.get()));
|
| + src.reset();
|
| +
|
| + // Start the migrator.
|
| + base::RunLoop run_loop;
|
| + scoped_ptr<ServiceWorkerDiskCacheMigrator> migrator(CreateMigrator());
|
| + migrator->Start(base::Bind(&OnDiskCacheMigrated, run_loop.QuitClosure()));
|
| + run_loop.Run();
|
| +
|
| + scoped_ptr<ServiceWorkerDiskCache> dest(CreateDestDiskCache());
|
| + ASSERT_EQ(0, GetEntryCount(dest.get()));
|
| +}
|
| +
|
| +// Tests that the migrator properly removes existing resources in the dest
|
| +// diskcache before starting the migration.
|
| +TEST_F(ServiceWorkerDiskCacheMigratorTest, RemoveExistingResourcesFromDest) {
|
| + std::vector<ResponseData> responses1;
|
| + responses1.push_back(ResponseData(1, "HTTP/1.1 200 OK\0\0", "Hello", ""));
|
| + responses1.push_back(ResponseData(3, "HTTP/1.1 200 OK\0\0", "World", ""));
|
| +
|
| + std::vector<ResponseData> responses2;
|
| + responses2.push_back(ResponseData(10, "HTTP/1.1 200 OK\0\0", "Hello", ""));
|
| + responses2.push_back(ResponseData(11, "HTTP/1.1 200 OK\0\0", "Service", ""));
|
| + responses2.push_back(ResponseData(12, "HTTP/1.1 200 OK\0\0", "", "Worker"));
|
| +
|
| + // Populate initial resources in the src diskcache.
|
| + scoped_ptr<ServiceWorkerDiskCache> src(CreateSrcDiskCache());
|
| + for (const ResponseData& response : responses1) {
|
| + ASSERT_TRUE(WriteResponse(src.get(), response));
|
| + VerifyResponse(src.get(), response);
|
| + }
|
| + ASSERT_EQ(static_cast<int>(responses1.size()), GetEntryCount(src.get()));
|
| + src.reset();
|
| +
|
| + // Populate different resources in the dest diskcache in order to simulate
|
| + // a previous partial migration.
|
| + scoped_ptr<ServiceWorkerDiskCache> dest(CreateDestDiskCache());
|
| + for (const ResponseData& response : responses2) {
|
| + ASSERT_TRUE(WriteResponse(dest.get(), response));
|
| + VerifyResponse(dest.get(), response);
|
| + }
|
| + ASSERT_EQ(static_cast<int>(responses2.size()), GetEntryCount(dest.get()));
|
| + dest.reset();
|
| +
|
| + // Start the migrator.
|
| + base::RunLoop run_loop;
|
| + scoped_ptr<ServiceWorkerDiskCacheMigrator> migrator(CreateMigrator());
|
| + migrator->Start(base::Bind(&OnDiskCacheMigrated, run_loop.QuitClosure()));
|
| + run_loop.Run();
|
| +
|
| + // Verify that only newly migrated resources exist in the dest diskcache.
|
| + dest = CreateDestDiskCache();
|
| + for (const ResponseData& response : responses1)
|
| + VerifyResponse(dest.get(), response);
|
| + EXPECT_EQ(static_cast<int>(responses1.size()), GetEntryCount(dest.get()));
|
| }
|
|
|
| TEST_F(ServiceWorkerDiskCacheMigratorTest, ThrottleInflightTasks) {
|
| @@ -220,22 +299,108 @@ TEST_F(ServiceWorkerDiskCacheMigratorTest, ThrottleInflightTasks) {
|
| responses.push_back(ResponseData(i, "HTTP/1.1 200 OK\0\0", "foo", "bar"));
|
|
|
| // Populate initial data in the src diskcache.
|
| + scoped_ptr<ServiceWorkerDiskCache> src(CreateSrcDiskCache());
|
| for (const ResponseData& response : responses) {
|
| - ASSERT_TRUE(WriteResponse(src_.get(), response));
|
| - VerifyResponse(src_.get(), response);
|
| + ASSERT_TRUE(WriteResponse(src.get(), response));
|
| + VerifyResponse(src.get(), response);
|
| }
|
| - ASSERT_EQ(static_cast<int>(responses.size()), GetEntryCount(src_.get()));
|
| + ASSERT_EQ(static_cast<int>(responses.size()), GetEntryCount(src.get()));
|
| + src.reset();
|
| +
|
| + scoped_ptr<ServiceWorkerDiskCacheMigrator> migrator(CreateMigrator());
|
|
|
| // Tighten the max number of inflight tasks.
|
| - SetMaxNumberOfInflightTasks(2);
|
| + migrator->set_max_number_of_inflight_tasks(2);
|
|
|
| // Migration should hit the limit, but should successfully complete.
|
| - Migrate();
|
| + base::RunLoop run_loop;
|
| + migrator->Start(base::Bind(&OnDiskCacheMigrated, run_loop.QuitClosure()));
|
| + run_loop.Run();
|
|
|
| // Verify the migrated contents in the dest diskcache.
|
| + scoped_ptr<ServiceWorkerDiskCache> dest(CreateDestDiskCache());
|
| for (const ResponseData& response : responses)
|
| - VerifyResponse(dest_.get(), response);
|
| - EXPECT_EQ(static_cast<int>(responses.size()), GetEntryCount(dest_.get()));
|
| + VerifyResponse(dest.get(), response);
|
| + EXPECT_EQ(static_cast<int>(responses.size()), GetEntryCount(dest.get()));
|
| +}
|
| +
|
| +TEST_F(ServiceWorkerDiskCacheMigratorTest, MigrateOnDiskCacheAccess) {
|
| + 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"));
|
| +
|
| + // Populate initial resources in the src diskcache.
|
| + scoped_ptr<ServiceWorkerDiskCache> src(CreateSrcDiskCache());
|
| + 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()));
|
| + ASSERT_TRUE(base::DirectoryExists(storage()->GetOldDiskCachePath()));
|
| + src.reset();
|
| +
|
| + base::RunLoop run_loop;
|
| + storage()->LazyInitialize(run_loop.QuitClosure());
|
| + run_loop.Run();
|
| +
|
| + // Before the migration, the diskcache version should be 0.
|
| + EXPECT_EQ(0u, storage()->current_disk_cache_version_);
|
| +
|
| + // DiskCache access should start the migration.
|
| + ServiceWorkerDiskCache* dest = storage()->disk_cache();
|
| +
|
| + // Verify the migrated contents in the dest diskcache.
|
| + for (const ResponseData& response : responses)
|
| + VerifyResponse(dest, response);
|
| + EXPECT_EQ(static_cast<int>(responses.size()), GetEntryCount(dest));
|
| +
|
| + // The src diskcache should be deleted after the migration.
|
| + EXPECT_FALSE(base::DirectoryExists(storage()->GetOldDiskCachePath()));
|
| +
|
| + // After the migration, the diskcache version should be updated.
|
| + int64 disk_cache_version = -1;
|
| + EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
|
| + storage()->database_->ReadDiskCacheVersion(&disk_cache_version));
|
| + EXPECT_LT(0u, disk_cache_version);
|
| + EXPECT_EQ(storage()->current_disk_cache_version_, disk_cache_version);
|
| +
|
| + // After the migration, purgeable files should be empty.
|
| + std::vector<std::string> purgeable_files;
|
| + EXPECT_EQ(ServiceWorkerDatabase::STATUS_OK,
|
| + storage()->database_->GetPurgeableFiles(&purgeable_files));
|
| + EXPECT_TRUE(purgeable_files.empty());
|
| +}
|
| +
|
| +TEST_F(ServiceWorkerDiskCacheMigratorTest, NotMigrateOnDatabaseAccess) {
|
| + 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"));
|
| +
|
| + // Populate initial resources in the src diskcache.
|
| + scoped_ptr<ServiceWorkerDiskCache> src(CreateSrcDiskCache());
|
| + 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()));
|
| + ASSERT_TRUE(base::DirectoryExists(storage()->GetOldDiskCachePath()));
|
| +
|
| + // Database access should not start the migration.
|
| + base::RunLoop run_loop;
|
| + storage()->FindRegistrationForDocument(
|
| + GURL("http://example.com/"),
|
| + base::Bind(&OnRegistrationFound, run_loop.QuitClosure()));
|
| + run_loop.Run();
|
| +
|
| + // Verify that the migration didn't happen.
|
| + scoped_ptr<ServiceWorkerDiskCache> dest(CreateDestDiskCache());
|
| + EXPECT_EQ(static_cast<int>(responses.size()), GetEntryCount(src.get()));
|
| + EXPECT_EQ(0, GetEntryCount(dest.get()));
|
| + EXPECT_TRUE(base::DirectoryExists(storage()->GetOldDiskCachePath()));
|
| }
|
|
|
| } // namespace content
|
|
|