| 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 f1397d2262f0f4327d19a5ad382cb33d19ea73e5..3564e333d5d5d262426d0762241f5934bef9580c 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,6 +4,9 @@
|
|
|
| #include "content/browser/service_worker/service_worker_disk_cache_migrator.h"
|
|
|
| +#include <string>
|
| +#include <vector>
|
| +
|
| #include "base/files/file_util.h"
|
| #include "base/files/scoped_temp_dir.h"
|
| #include "base/run_loop.h"
|
| @@ -45,6 +48,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 {
|
| @@ -69,13 +79,6 @@ class ServiceWorkerDiskCacheMigratorTest : public testing::Test {
|
| base::RunLoop().RunUntilIdle();
|
| }
|
|
|
| - base::FilePath GetOldDiskCachePath() {
|
| - return user_data_directory_.path().AppendASCII("SrcCache");
|
| - }
|
| - base::FilePath GetDiskCachePath() {
|
| - return user_data_directory_.path().AppendASCII("DestCache");
|
| - }
|
| -
|
| scoped_ptr<ServiceWorkerDiskCache> CreateSrcDiskCache() {
|
| #if defined(OS_ANDROID)
|
| // Android has already used the Simple backend.
|
| @@ -88,7 +91,7 @@ class ServiceWorkerDiskCacheMigratorTest : public testing::Test {
|
|
|
| net::TestCompletionCallback cb;
|
| src->InitWithDiskBackend(
|
| - GetOldDiskCachePath(), kMaxDiskCacheSize, false /* force */,
|
| + storage()->GetOldDiskCachePath(), kMaxDiskCacheSize, false /* force */,
|
| base::ThreadTaskRunnerHandle::Get(), cb.callback());
|
| EXPECT_EQ(net::OK, cb.WaitForResult());
|
| return src.Pass();
|
| @@ -99,7 +102,7 @@ class ServiceWorkerDiskCacheMigratorTest : public testing::Test {
|
| ServiceWorkerDiskCache::CreateWithSimpleBackend());
|
| net::TestCompletionCallback cb;
|
| dest->InitWithDiskBackend(
|
| - GetDiskCachePath(), kMaxDiskCacheSize, false /* force */,
|
| + storage()->GetDiskCachePath(), kMaxDiskCacheSize, false /* force */,
|
| base::ThreadTaskRunnerHandle::Get(), cb.callback());
|
| EXPECT_EQ(net::OK, cb.WaitForResult());
|
| return dest.Pass();
|
| @@ -107,8 +110,8 @@ class ServiceWorkerDiskCacheMigratorTest : public testing::Test {
|
|
|
| scoped_ptr<ServiceWorkerDiskCacheMigrator> CreateMigrator() {
|
| return make_scoped_ptr(new ServiceWorkerDiskCacheMigrator(
|
| - GetOldDiskCachePath(), GetDiskCachePath(), kMaxDiskCacheSize,
|
| - base::ThreadTaskRunnerHandle::Get()));
|
| + storage()->GetOldDiskCachePath(), storage()->GetDiskCachePath(),
|
| + kMaxDiskCacheSize, base::ThreadTaskRunnerHandle::Get()));
|
| }
|
|
|
| bool WriteResponse(ServiceWorkerDiskCache* disk_cache,
|
| @@ -198,6 +201,8 @@ class ServiceWorkerDiskCacheMigratorTest : public testing::Test {
|
| return disk_cache->disk_cache()->GetEntryCount();
|
| }
|
|
|
| + ServiceWorkerStorage* storage() { return context_->storage(); }
|
| +
|
| private:
|
| TestBrowserThreadBundle browser_thread_bundle_;
|
| base::ScopedTempDir user_data_directory_;
|
| @@ -329,4 +334,184 @@ TEST_F(ServiceWorkerDiskCacheMigratorTest, ThrottleInflightTasks) {
|
| 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();
|
| +
|
| + scoped_ptr<ServiceWorkerDatabase> database(
|
| + new ServiceWorkerDatabase(storage()->GetDatabasePath()));
|
| +
|
| + // This is necessary to make the storage schedule diskcache migration.
|
| + database->set_skip_writing_diskcache_migration_state_on_init_for_testing();
|
| +
|
| + // Simulate an existing database.
|
| + std::vector<ServiceWorkerDatabase::ResourceRecord> resources;
|
| + resources.push_back(ServiceWorkerDatabase::ResourceRecord(
|
| + 1, GURL("https://example.com/foo"), 10));
|
| + ServiceWorkerDatabase::RegistrationData deleted_version;
|
| + std::vector<int64> newly_purgeable_resources;
|
| + ServiceWorkerDatabase::RegistrationData data;
|
| + data.registration_id = 100;
|
| + data.scope = GURL("https://example.com/");
|
| + data.script = GURL("https://example.com/script.js");
|
| + data.version_id = 200;
|
| + data.resources_total_size_bytes = 10;
|
| + ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
|
| + database->WriteRegistration(data, resources, &deleted_version,
|
| + &newly_purgeable_resources));
|
| + database.reset();
|
| +
|
| + // LazyInitialize() reads initial data and should schedule to migrate.
|
| + ASSERT_FALSE(storage()->disk_cache_migration_needed_);
|
| + base::RunLoop run_loop;
|
| + storage()->LazyInitialize(run_loop.QuitClosure());
|
| + run_loop.Run();
|
| + EXPECT_TRUE(storage()->disk_cache_migration_needed_);
|
| +
|
| + // 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));
|
| +
|
| + // After the migration, the src diskcache should be deleted.
|
| + EXPECT_FALSE(base::DirectoryExists(storage()->GetOldDiskCachePath()));
|
| +
|
| + // After the migration, the migration state should be updated.
|
| + bool migration_needed = false;
|
| + EXPECT_EQ(
|
| + ServiceWorkerDatabase::STATUS_OK,
|
| + storage()->database_->IsDiskCacheMigrationNeeded(&migration_needed));
|
| + EXPECT_FALSE(migration_needed);
|
| + bool deletion_needed = false;
|
| + EXPECT_EQ(
|
| + ServiceWorkerDatabase::STATUS_OK,
|
| + storage()->database_->IsOldDiskCacheDeletionNeeded(&deletion_needed));
|
| + EXPECT_FALSE(deletion_needed);
|
| +}
|
| +
|
| +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()));
|
| +
|
| + scoped_ptr<ServiceWorkerDatabase> database(
|
| + new ServiceWorkerDatabase(storage()->GetDatabasePath()));
|
| +
|
| + // This is necessary to make the storage schedule diskcache migration.
|
| + database->set_skip_writing_diskcache_migration_state_on_init_for_testing();
|
| +
|
| + // Simulate an existing database.
|
| + std::vector<ServiceWorkerDatabase::ResourceRecord> resources;
|
| + resources.push_back(ServiceWorkerDatabase::ResourceRecord(
|
| + 1, GURL("https://example.com/foo"), 10));
|
| + ServiceWorkerDatabase::RegistrationData deleted_version;
|
| + std::vector<int64> newly_purgeable_resources;
|
| + ServiceWorkerDatabase::RegistrationData data;
|
| + data.registration_id = 100;
|
| + data.scope = GURL("https://example.com/");
|
| + data.script = GURL("https://example.com/script.js");
|
| + data.version_id = 200;
|
| + data.resources_total_size_bytes = 10;
|
| + ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
|
| + database->WriteRegistration(data, resources, &deleted_version,
|
| + &newly_purgeable_resources));
|
| + database.reset();
|
| +
|
| + // LazyInitialize() reads initial data and should schedule to migrate.
|
| + ASSERT_FALSE(storage()->disk_cache_migration_needed_);
|
| + base::RunLoop run_loop1;
|
| + storage()->LazyInitialize(run_loop1.QuitClosure());
|
| + run_loop1.Run();
|
| + EXPECT_TRUE(storage()->disk_cache_migration_needed_);
|
| +
|
| + // Database access should not start the migration.
|
| + base::RunLoop run_loop2;
|
| + storage()->FindRegistrationForDocument(
|
| + GURL("http://example.com/"),
|
| + base::Bind(&OnRegistrationFound, run_loop2.QuitClosure()));
|
| + run_loop2.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()));
|
| +}
|
| +
|
| +TEST_F(ServiceWorkerDiskCacheMigratorTest, NotMigrateForEmptyDatabase) {
|
| + 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();
|
| +
|
| + // LazyInitialize() reads initial data and should not schedule to migrate
|
| + // because the database is empty.
|
| + ASSERT_FALSE(storage()->disk_cache_migration_needed_);
|
| + base::RunLoop run_loop;
|
| + storage()->LazyInitialize(run_loop.QuitClosure());
|
| + run_loop.Run();
|
| + EXPECT_FALSE(storage()->disk_cache_migration_needed_);
|
| +
|
| + // DiskCache access should not start the migration.
|
| + ServiceWorkerDiskCache* dest = storage()->disk_cache();
|
| +
|
| + // Verify that the migration didn't happen.
|
| + src = CreateSrcDiskCache();
|
| + for (const ResponseData& response : responses)
|
| + VerifyResponse(src.get(), response);
|
| + EXPECT_EQ(static_cast<int>(responses.size()), GetEntryCount(src.get()));
|
| + EXPECT_TRUE(base::DirectoryExists(storage()->GetOldDiskCachePath()));
|
| + EXPECT_EQ(0, GetEntryCount(dest));
|
| +
|
| + // After the diskcache initialization, the migration state should be updated.
|
| + bool migration_needed = false;
|
| + EXPECT_EQ(
|
| + ServiceWorkerDatabase::STATUS_OK,
|
| + storage()->database_->IsDiskCacheMigrationNeeded(&migration_needed));
|
| + EXPECT_FALSE(migration_needed);
|
| + bool deletion_needed = false;
|
| + EXPECT_EQ(
|
| + ServiceWorkerDatabase::STATUS_OK,
|
| + storage()->database_->IsOldDiskCacheDeletionNeeded(&deletion_needed));
|
| + EXPECT_FALSE(deletion_needed);
|
| +}
|
| +
|
| } // namespace content
|
|
|