Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Side by Side Diff: content/browser/service_worker/service_worker_disk_cache_migrator_unittest.cc

Issue 1152543002: ServiceWorker: Migrate the script cache backend from BlockFile to Simple (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: address falken@'s comments Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/service_worker/service_worker_disk_cache_migrator.h" 5 #include "content/browser/service_worker/service_worker_disk_cache_migrator.h"
6 6
7 #include <string>
8 #include <vector>
9
7 #include "base/files/file_util.h" 10 #include "base/files/file_util.h"
8 #include "base/files/scoped_temp_dir.h" 11 #include "base/files/scoped_temp_dir.h"
9 #include "base/run_loop.h" 12 #include "base/run_loop.h"
10 #include "base/thread_task_runner_handle.h" 13 #include "base/thread_task_runner_handle.h"
11 #include "content/browser/service_worker/service_worker_context_core.h" 14 #include "content/browser/service_worker/service_worker_context_core.h"
12 #include "content/browser/service_worker/service_worker_storage.h" 15 #include "content/browser/service_worker/service_worker_storage.h"
13 #include "content/public/test/test_browser_thread_bundle.h" 16 #include "content/public/test/test_browser_thread_bundle.h"
14 #include "net/base/io_buffer.h" 17 #include "net/base/io_buffer.h"
15 #include "net/base/net_errors.h" 18 #include "net/base/net_errors.h"
16 #include "net/base/test_completion_callback.h" 19 #include "net/base/test_completion_callback.h"
(...skipping 21 matching lines...) Expand all
38 body(body), 41 body(body),
39 metadata(metadata) {} 42 metadata(metadata) {}
40 }; 43 };
41 44
42 void OnDiskCacheMigrated(const base::Closure& callback, 45 void OnDiskCacheMigrated(const base::Closure& callback,
43 ServiceWorkerStatusCode status) { 46 ServiceWorkerStatusCode status) {
44 EXPECT_EQ(SERVICE_WORKER_OK, status); 47 EXPECT_EQ(SERVICE_WORKER_OK, status);
45 callback.Run(); 48 callback.Run();
46 } 49 }
47 50
51 void OnRegistrationFound(
52 const base::Closure& callback,
53 ServiceWorkerStatusCode status,
54 const scoped_refptr<ServiceWorkerRegistration>& registration) {
55 callback.Run();
56 }
57
48 } // namespace 58 } // namespace
49 59
50 class ServiceWorkerDiskCacheMigratorTest : public testing::Test { 60 class ServiceWorkerDiskCacheMigratorTest : public testing::Test {
51 public: 61 public:
52 ServiceWorkerDiskCacheMigratorTest() 62 ServiceWorkerDiskCacheMigratorTest()
53 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {} 63 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {}
54 64
55 void SetUp() override { 65 void SetUp() override {
56 ASSERT_TRUE(user_data_directory_.CreateUniqueTempDir()); 66 ASSERT_TRUE(user_data_directory_.CreateUniqueTempDir());
57 scoped_ptr<ServiceWorkerDatabaseTaskManager> database_task_manager( 67 scoped_ptr<ServiceWorkerDatabaseTaskManager> database_task_manager(
58 new MockServiceWorkerDatabaseTaskManager( 68 new MockServiceWorkerDatabaseTaskManager(
59 base::ThreadTaskRunnerHandle::Get())); 69 base::ThreadTaskRunnerHandle::Get()));
60 70
61 context_.reset(new ServiceWorkerContextCore( 71 context_.reset(new ServiceWorkerContextCore(
62 user_data_directory_.path(), database_task_manager.Pass(), 72 user_data_directory_.path(), database_task_manager.Pass(),
63 base::ThreadTaskRunnerHandle::Get(), nullptr, nullptr, nullptr, 73 base::ThreadTaskRunnerHandle::Get(), nullptr, nullptr, nullptr,
64 nullptr)); 74 nullptr));
65 } 75 }
66 76
67 void TearDown() override { 77 void TearDown() override {
68 context_.reset(); 78 context_.reset();
69 base::RunLoop().RunUntilIdle(); 79 base::RunLoop().RunUntilIdle();
70 } 80 }
71 81
72 base::FilePath GetOldDiskCachePath() {
73 return user_data_directory_.path().AppendASCII("SrcCache");
74 }
75 base::FilePath GetDiskCachePath() {
76 return user_data_directory_.path().AppendASCII("DestCache");
77 }
78
79 scoped_ptr<ServiceWorkerDiskCache> CreateSrcDiskCache() { 82 scoped_ptr<ServiceWorkerDiskCache> CreateSrcDiskCache() {
80 #if defined(OS_ANDROID) 83 #if defined(OS_ANDROID)
81 // Android has already used the Simple backend. 84 // Android has already used the Simple backend.
82 scoped_ptr<ServiceWorkerDiskCache> src( 85 scoped_ptr<ServiceWorkerDiskCache> src(
83 ServiceWorkerDiskCache::CreateWithSimpleBackend()); 86 ServiceWorkerDiskCache::CreateWithSimpleBackend());
84 #else 87 #else
85 scoped_ptr<ServiceWorkerDiskCache> src( 88 scoped_ptr<ServiceWorkerDiskCache> src(
86 ServiceWorkerDiskCache::CreateWithBlockFileBackend()); 89 ServiceWorkerDiskCache::CreateWithBlockFileBackend());
87 #endif // defined(OS_ANDROID) 90 #endif // defined(OS_ANDROID)
88 91
89 net::TestCompletionCallback cb; 92 net::TestCompletionCallback cb;
90 src->InitWithDiskBackend( 93 src->InitWithDiskBackend(
91 GetOldDiskCachePath(), kMaxDiskCacheSize, false /* force */, 94 storage()->GetOldDiskCachePath(), kMaxDiskCacheSize, false /* force */,
92 base::ThreadTaskRunnerHandle::Get(), cb.callback()); 95 base::ThreadTaskRunnerHandle::Get(), cb.callback());
93 EXPECT_EQ(net::OK, cb.WaitForResult()); 96 EXPECT_EQ(net::OK, cb.WaitForResult());
94 return src.Pass(); 97 return src.Pass();
95 } 98 }
96 99
97 scoped_ptr<ServiceWorkerDiskCache> CreateDestDiskCache() { 100 scoped_ptr<ServiceWorkerDiskCache> CreateDestDiskCache() {
98 scoped_ptr<ServiceWorkerDiskCache> dest( 101 scoped_ptr<ServiceWorkerDiskCache> dest(
99 ServiceWorkerDiskCache::CreateWithSimpleBackend()); 102 ServiceWorkerDiskCache::CreateWithSimpleBackend());
100 net::TestCompletionCallback cb; 103 net::TestCompletionCallback cb;
101 dest->InitWithDiskBackend( 104 dest->InitWithDiskBackend(
102 GetDiskCachePath(), kMaxDiskCacheSize, false /* force */, 105 storage()->GetDiskCachePath(), kMaxDiskCacheSize, false /* force */,
103 base::ThreadTaskRunnerHandle::Get(), cb.callback()); 106 base::ThreadTaskRunnerHandle::Get(), cb.callback());
104 EXPECT_EQ(net::OK, cb.WaitForResult()); 107 EXPECT_EQ(net::OK, cb.WaitForResult());
105 return dest.Pass(); 108 return dest.Pass();
106 } 109 }
107 110
108 scoped_ptr<ServiceWorkerDiskCacheMigrator> CreateMigrator() { 111 scoped_ptr<ServiceWorkerDiskCacheMigrator> CreateMigrator() {
109 return make_scoped_ptr(new ServiceWorkerDiskCacheMigrator( 112 return make_scoped_ptr(new ServiceWorkerDiskCacheMigrator(
110 GetOldDiskCachePath(), GetDiskCachePath(), kMaxDiskCacheSize, 113 storage()->GetOldDiskCachePath(), storage()->GetDiskCachePath(),
111 base::ThreadTaskRunnerHandle::Get())); 114 kMaxDiskCacheSize, base::ThreadTaskRunnerHandle::Get()));
112 } 115 }
113 116
114 bool WriteResponse(ServiceWorkerDiskCache* disk_cache, 117 bool WriteResponse(ServiceWorkerDiskCache* disk_cache,
115 const ResponseData& response) { 118 const ResponseData& response) {
116 scoped_ptr<ServiceWorkerResponseWriter> writer( 119 scoped_ptr<ServiceWorkerResponseWriter> writer(
117 new ServiceWorkerResponseWriter(response.resource_id, disk_cache)); 120 new ServiceWorkerResponseWriter(response.resource_id, disk_cache));
118 121
119 // Write the response info. 122 // Write the response info.
120 scoped_ptr<net::HttpResponseInfo> info(new net::HttpResponseInfo); 123 scoped_ptr<net::HttpResponseInfo> info(new net::HttpResponseInfo);
121 info->request_time = base::Time() + base::TimeDelta::FromSeconds(10); 124 info->request_time = base::Time() + base::TimeDelta::FromSeconds(10);
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 reader->ReadData(body_buffer.get(), kBigEnough, cb2.callback()); 194 reader->ReadData(body_buffer.get(), kBigEnough, cb2.callback());
192 rv = cb2.WaitForResult(); 195 rv = cb2.WaitForResult();
193 ASSERT_EQ(static_cast<int>(expected.body.length()), rv); 196 ASSERT_EQ(static_cast<int>(expected.body.length()), rv);
194 EXPECT_EQ(0, memcmp(expected.body.data(), body_buffer->data(), rv)); 197 EXPECT_EQ(0, memcmp(expected.body.data(), body_buffer->data(), rv));
195 } 198 }
196 199
197 int32 GetEntryCount(ServiceWorkerDiskCache* disk_cache) { 200 int32 GetEntryCount(ServiceWorkerDiskCache* disk_cache) {
198 return disk_cache->disk_cache()->GetEntryCount(); 201 return disk_cache->disk_cache()->GetEntryCount();
199 } 202 }
200 203
204 ServiceWorkerStorage* storage() { return context_->storage(); }
205
201 private: 206 private:
202 TestBrowserThreadBundle browser_thread_bundle_; 207 TestBrowserThreadBundle browser_thread_bundle_;
203 base::ScopedTempDir user_data_directory_; 208 base::ScopedTempDir user_data_directory_;
204 209
205 scoped_ptr<ServiceWorkerContextCore> context_; 210 scoped_ptr<ServiceWorkerContextCore> context_;
206 }; 211 };
207 212
208 TEST_F(ServiceWorkerDiskCacheMigratorTest, MigrateDiskCache) { 213 TEST_F(ServiceWorkerDiskCacheMigratorTest, MigrateDiskCache) {
209 std::vector<ResponseData> responses; 214 std::vector<ResponseData> responses;
210 responses.push_back(ResponseData(1, "HTTP/1.1 200 OK\0\0", "Hello", "")); 215 responses.push_back(ResponseData(1, "HTTP/1.1 200 OK\0\0", "Hello", ""));
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 migrator->Start(base::Bind(&OnDiskCacheMigrated, run_loop.QuitClosure())); 327 migrator->Start(base::Bind(&OnDiskCacheMigrated, run_loop.QuitClosure()));
323 run_loop.Run(); 328 run_loop.Run();
324 329
325 // Verify the migrated contents in the dest diskcache. 330 // Verify the migrated contents in the dest diskcache.
326 scoped_ptr<ServiceWorkerDiskCache> dest(CreateDestDiskCache()); 331 scoped_ptr<ServiceWorkerDiskCache> dest(CreateDestDiskCache());
327 for (const ResponseData& response : responses) 332 for (const ResponseData& response : responses)
328 VerifyResponse(dest.get(), response); 333 VerifyResponse(dest.get(), response);
329 EXPECT_EQ(static_cast<int>(responses.size()), GetEntryCount(dest.get())); 334 EXPECT_EQ(static_cast<int>(responses.size()), GetEntryCount(dest.get()));
330 } 335 }
331 336
337 TEST_F(ServiceWorkerDiskCacheMigratorTest, MigrateOnDiskCacheAccess) {
338 std::vector<ResponseData> responses;
339 responses.push_back(ResponseData(1, "HTTP/1.1 200 OK\0\0", "Hello", ""));
340 responses.push_back(ResponseData(2, "HTTP/1.1 200 OK\0\0", "Service", ""));
341 responses.push_back(ResponseData(5, "HTTP/1.1 200 OK\0\0", "Worker", ""));
342 responses.push_back(ResponseData(3, "HTTP/1.1 200 OK\0\0", "World", "meta"));
343
344 // Populate initial resources in the src diskcache.
345 scoped_ptr<ServiceWorkerDiskCache> src(CreateSrcDiskCache());
346 for (const ResponseData& response : responses) {
347 ASSERT_TRUE(WriteResponse(src.get(), response));
348 VerifyResponse(src.get(), response);
349 }
350 ASSERT_EQ(static_cast<int>(responses.size()), GetEntryCount(src.get()));
351 ASSERT_TRUE(base::DirectoryExists(storage()->GetOldDiskCachePath()));
352 src.reset();
353
354 scoped_ptr<ServiceWorkerDatabase> database(
355 new ServiceWorkerDatabase(storage()->GetDatabasePath()));
356
357 // This is necessary to make the storage schedule diskcache migration.
358 database->set_skip_writing_diskcache_migration_state_on_init_for_testing();
359
360 // Simulate an existing database.
361 std::vector<ServiceWorkerDatabase::ResourceRecord> resources;
362 resources.push_back(ServiceWorkerDatabase::ResourceRecord(
363 1, GURL("https://example.com/foo"), 10));
364 ServiceWorkerDatabase::RegistrationData deleted_version;
365 std::vector<int64> newly_purgeable_resources;
366 ServiceWorkerDatabase::RegistrationData data;
367 data.registration_id = 100;
368 data.scope = GURL("https://example.com/");
369 data.script = GURL("https://example.com/script.js");
370 data.version_id = 200;
371 data.resources_total_size_bytes = 10;
372 ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
373 database->WriteRegistration(data, resources, &deleted_version,
374 &newly_purgeable_resources));
375 database.reset();
376
377 // LazyInitialize() reads initial data and should schedule to migrate.
378 ASSERT_FALSE(storage()->disk_cache_migration_needed_);
379 base::RunLoop run_loop;
380 storage()->LazyInitialize(run_loop.QuitClosure());
381 run_loop.Run();
382 EXPECT_TRUE(storage()->disk_cache_migration_needed_);
383
384 // DiskCache access should start the migration.
385 ServiceWorkerDiskCache* dest = storage()->disk_cache();
386
387 // Verify the migrated contents in the dest diskcache.
388 for (const ResponseData& response : responses)
389 VerifyResponse(dest, response);
390 EXPECT_EQ(static_cast<int>(responses.size()), GetEntryCount(dest));
391
392 // After the migration, the src diskcache should be deleted.
393 EXPECT_FALSE(base::DirectoryExists(storage()->GetOldDiskCachePath()));
394
395 // After the migration, the migration state should be updated.
396 bool migration_needed = false;
397 EXPECT_EQ(
398 ServiceWorkerDatabase::STATUS_OK,
399 storage()->database_->IsDiskCacheMigrationNeeded(&migration_needed));
400 EXPECT_FALSE(migration_needed);
401 bool deletion_needed = false;
402 EXPECT_EQ(
403 ServiceWorkerDatabase::STATUS_OK,
404 storage()->database_->IsOldDiskCacheDeletionNeeded(&deletion_needed));
405 EXPECT_FALSE(deletion_needed);
406 }
407
408 TEST_F(ServiceWorkerDiskCacheMigratorTest, NotMigrateOnDatabaseAccess) {
409 std::vector<ResponseData> responses;
410 responses.push_back(ResponseData(1, "HTTP/1.1 200 OK\0\0", "Hello", ""));
411 responses.push_back(ResponseData(2, "HTTP/1.1 200 OK\0\0", "Service", ""));
412 responses.push_back(ResponseData(5, "HTTP/1.1 200 OK\0\0", "Worker", ""));
413 responses.push_back(ResponseData(3, "HTTP/1.1 200 OK\0\0", "World", "meta"));
414
415 // Populate initial resources in the src diskcache.
416 scoped_ptr<ServiceWorkerDiskCache> src(CreateSrcDiskCache());
417 for (const ResponseData& response : responses) {
418 ASSERT_TRUE(WriteResponse(src.get(), response));
419 VerifyResponse(src.get(), response);
420 }
421 ASSERT_EQ(static_cast<int>(responses.size()), GetEntryCount(src.get()));
422 ASSERT_TRUE(base::DirectoryExists(storage()->GetOldDiskCachePath()));
423
424 scoped_ptr<ServiceWorkerDatabase> database(
425 new ServiceWorkerDatabase(storage()->GetDatabasePath()));
426
427 // This is necessary to make the storage schedule diskcache migration.
428 database->set_skip_writing_diskcache_migration_state_on_init_for_testing();
429
430 // Simulate an existing database.
431 std::vector<ServiceWorkerDatabase::ResourceRecord> resources;
432 resources.push_back(ServiceWorkerDatabase::ResourceRecord(
433 1, GURL("https://example.com/foo"), 10));
434 ServiceWorkerDatabase::RegistrationData deleted_version;
435 std::vector<int64> newly_purgeable_resources;
436 ServiceWorkerDatabase::RegistrationData data;
437 data.registration_id = 100;
438 data.scope = GURL("https://example.com/");
439 data.script = GURL("https://example.com/script.js");
440 data.version_id = 200;
441 data.resources_total_size_bytes = 10;
442 ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
443 database->WriteRegistration(data, resources, &deleted_version,
444 &newly_purgeable_resources));
445 database.reset();
446
447 // LazyInitialize() reads initial data and should schedule to migrate.
448 ASSERT_FALSE(storage()->disk_cache_migration_needed_);
449 base::RunLoop run_loop1;
450 storage()->LazyInitialize(run_loop1.QuitClosure());
451 run_loop1.Run();
452 EXPECT_TRUE(storage()->disk_cache_migration_needed_);
453
454 // Database access should not start the migration.
455 base::RunLoop run_loop2;
456 storage()->FindRegistrationForDocument(
457 GURL("http://example.com/"),
458 base::Bind(&OnRegistrationFound, run_loop2.QuitClosure()));
459 run_loop2.Run();
460
461 // Verify that the migration didn't happen.
462 scoped_ptr<ServiceWorkerDiskCache> dest(CreateDestDiskCache());
463 EXPECT_EQ(static_cast<int>(responses.size()), GetEntryCount(src.get()));
464 EXPECT_EQ(0, GetEntryCount(dest.get()));
465 EXPECT_TRUE(base::DirectoryExists(storage()->GetOldDiskCachePath()));
466 }
467
468 TEST_F(ServiceWorkerDiskCacheMigratorTest, NotMigrateForEmptyDatabase) {
469 std::vector<ResponseData> responses;
470 responses.push_back(ResponseData(1, "HTTP/1.1 200 OK\0\0", "Hello", ""));
471 responses.push_back(ResponseData(2, "HTTP/1.1 200 OK\0\0", "Service", ""));
472 responses.push_back(ResponseData(5, "HTTP/1.1 200 OK\0\0", "Worker", ""));
473 responses.push_back(ResponseData(3, "HTTP/1.1 200 OK\0\0", "World", "meta"));
474
475 // Populate initial resources in the src diskcache.
476 scoped_ptr<ServiceWorkerDiskCache> src(CreateSrcDiskCache());
477 for (const ResponseData& response : responses) {
478 ASSERT_TRUE(WriteResponse(src.get(), response));
479 VerifyResponse(src.get(), response);
480 }
481 ASSERT_EQ(static_cast<int>(responses.size()), GetEntryCount(src.get()));
482 ASSERT_TRUE(base::DirectoryExists(storage()->GetOldDiskCachePath()));
483 src.reset();
484
485 // LazyInitialize() reads initial data and should not schedule to migrate
486 // because the database is empty.
487 ASSERT_FALSE(storage()->disk_cache_migration_needed_);
488 base::RunLoop run_loop;
489 storage()->LazyInitialize(run_loop.QuitClosure());
490 run_loop.Run();
491 EXPECT_FALSE(storage()->disk_cache_migration_needed_);
492
493 // DiskCache access should not start the migration.
494 ServiceWorkerDiskCache* dest = storage()->disk_cache();
495
496 // Verify that the migration didn't happen.
497 src = CreateSrcDiskCache();
498 for (const ResponseData& response : responses)
499 VerifyResponse(src.get(), response);
500 EXPECT_EQ(static_cast<int>(responses.size()), GetEntryCount(src.get()));
501 EXPECT_TRUE(base::DirectoryExists(storage()->GetOldDiskCachePath()));
502 EXPECT_EQ(0, GetEntryCount(dest));
503
504 // After the diskcache initialization, the migration state should be updated.
505 bool migration_needed = false;
506 EXPECT_EQ(
507 ServiceWorkerDatabase::STATUS_OK,
508 storage()->database_->IsDiskCacheMigrationNeeded(&migration_needed));
509 EXPECT_FALSE(migration_needed);
510 bool deletion_needed = false;
511 EXPECT_EQ(
512 ServiceWorkerDatabase::STATUS_OK,
513 storage()->database_->IsOldDiskCacheDeletionNeeded(&deletion_needed));
514 EXPECT_FALSE(deletion_needed);
515 }
516
332 } // namespace content 517 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698