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

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: update comment 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 "base/files/file_util.h" 7 #include "base/files/file_util.h"
8 #include "base/files/scoped_temp_dir.h" 8 #include "base/files/scoped_temp_dir.h"
9 #include "base/run_loop.h" 9 #include "base/run_loop.h"
10 #include "base/thread_task_runner_handle.h" 10 #include "base/thread_task_runner_handle.h"
(...skipping 27 matching lines...) Expand all
38 body(body), 38 body(body),
39 metadata(metadata) {} 39 metadata(metadata) {}
40 }; 40 };
41 41
42 void OnDiskCacheMigrated(const base::Closure& callback, 42 void OnDiskCacheMigrated(const base::Closure& callback,
43 ServiceWorkerStatusCode status) { 43 ServiceWorkerStatusCode status) {
44 EXPECT_EQ(SERVICE_WORKER_OK, status); 44 EXPECT_EQ(SERVICE_WORKER_OK, status);
45 callback.Run(); 45 callback.Run();
46 } 46 }
47 47
48 void OnRegistrationFound(
49 const base::Closure& callback,
50 ServiceWorkerStatusCode status,
51 const scoped_refptr<ServiceWorkerRegistration>& registration) {
52 callback.Run();
53 }
54
48 } // namespace 55 } // namespace
49 56
50 class ServiceWorkerDiskCacheMigratorTest : public testing::Test { 57 class ServiceWorkerDiskCacheMigratorTest : public testing::Test {
51 public: 58 public:
52 ServiceWorkerDiskCacheMigratorTest() 59 ServiceWorkerDiskCacheMigratorTest()
53 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {} 60 : browser_thread_bundle_(TestBrowserThreadBundle::IO_MAINLOOP) {}
54 61
55 void SetUp() override { 62 void SetUp() override {
56 ASSERT_TRUE(user_data_directory_.CreateUniqueTempDir()); 63 ASSERT_TRUE(user_data_directory_.CreateUniqueTempDir());
57 scoped_ptr<ServiceWorkerDatabaseTaskManager> database_task_manager( 64 scoped_ptr<ServiceWorkerDatabaseTaskManager> database_task_manager(
58 new MockServiceWorkerDatabaseTaskManager( 65 new MockServiceWorkerDatabaseTaskManager(
59 base::ThreadTaskRunnerHandle::Get())); 66 base::ThreadTaskRunnerHandle::Get()));
60 67
61 context_.reset(new ServiceWorkerContextCore( 68 context_.reset(new ServiceWorkerContextCore(
62 user_data_directory_.path(), database_task_manager.Pass(), 69 user_data_directory_.path(), database_task_manager.Pass(),
63 base::ThreadTaskRunnerHandle::Get(), nullptr, nullptr, nullptr, 70 base::ThreadTaskRunnerHandle::Get(), nullptr, nullptr, nullptr,
64 nullptr)); 71 nullptr));
65 } 72 }
66 73
67 void TearDown() override { 74 void TearDown() override {
68 context_.reset(); 75 context_.reset();
69 base::RunLoop().RunUntilIdle(); 76 base::RunLoop().RunUntilIdle();
70 } 77 }
71 78
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() { 79 scoped_ptr<ServiceWorkerDiskCache> CreateSrcDiskCache() {
80 #if defined(OS_ANDROID) 80 #if defined(OS_ANDROID)
81 // Android has already used the Simple backend. 81 // Android has already used the Simple backend.
82 scoped_ptr<ServiceWorkerDiskCache> src( 82 scoped_ptr<ServiceWorkerDiskCache> src(
83 ServiceWorkerDiskCache::CreateWithSimpleBackend()); 83 ServiceWorkerDiskCache::CreateWithSimpleBackend());
84 #else 84 #else
85 scoped_ptr<ServiceWorkerDiskCache> src( 85 scoped_ptr<ServiceWorkerDiskCache> src(
86 ServiceWorkerDiskCache::CreateWithBlockFileBackend()); 86 ServiceWorkerDiskCache::CreateWithBlockFileBackend());
87 #endif // defined(OS_ANDROID) 87 #endif // defined(OS_ANDROID)
88 88
89 net::TestCompletionCallback cb; 89 net::TestCompletionCallback cb;
90 src->InitWithDiskBackend( 90 src->InitWithDiskBackend(
91 GetOldDiskCachePath(), kMaxDiskCacheSize, false /* force */, 91 storage()->GetOldDiskCachePath(), kMaxDiskCacheSize, false /* force */,
92 base::ThreadTaskRunnerHandle::Get(), cb.callback()); 92 base::ThreadTaskRunnerHandle::Get(), cb.callback());
93 EXPECT_EQ(net::OK, cb.WaitForResult()); 93 EXPECT_EQ(net::OK, cb.WaitForResult());
94 return src.Pass(); 94 return src.Pass();
95 } 95 }
96 96
97 scoped_ptr<ServiceWorkerDiskCache> CreateDestDiskCache() { 97 scoped_ptr<ServiceWorkerDiskCache> CreateDestDiskCache() {
98 scoped_ptr<ServiceWorkerDiskCache> dest( 98 scoped_ptr<ServiceWorkerDiskCache> dest(
99 ServiceWorkerDiskCache::CreateWithSimpleBackend()); 99 ServiceWorkerDiskCache::CreateWithSimpleBackend());
100 net::TestCompletionCallback cb; 100 net::TestCompletionCallback cb;
101 dest->InitWithDiskBackend( 101 dest->InitWithDiskBackend(
102 GetDiskCachePath(), kMaxDiskCacheSize, false /* force */, 102 storage()->GetDiskCachePath(), kMaxDiskCacheSize, false /* force */,
103 base::ThreadTaskRunnerHandle::Get(), cb.callback()); 103 base::ThreadTaskRunnerHandle::Get(), cb.callback());
104 EXPECT_EQ(net::OK, cb.WaitForResult()); 104 EXPECT_EQ(net::OK, cb.WaitForResult());
105 return dest.Pass(); 105 return dest.Pass();
106 } 106 }
107 107
108 scoped_ptr<ServiceWorkerDiskCacheMigrator> CreateMigrator() { 108 scoped_ptr<ServiceWorkerDiskCacheMigrator> CreateMigrator() {
109 return make_scoped_ptr(new ServiceWorkerDiskCacheMigrator( 109 return make_scoped_ptr(new ServiceWorkerDiskCacheMigrator(
110 GetOldDiskCachePath(), GetDiskCachePath(), kMaxDiskCacheSize, 110 storage()->GetOldDiskCachePath(), storage()->GetDiskCachePath(),
111 base::ThreadTaskRunnerHandle::Get())); 111 kMaxDiskCacheSize, base::ThreadTaskRunnerHandle::Get()));
112 } 112 }
113 113
114 bool WriteResponse(ServiceWorkerDiskCache* disk_cache, 114 bool WriteResponse(ServiceWorkerDiskCache* disk_cache,
115 const ResponseData& response) { 115 const ResponseData& response) {
116 scoped_ptr<ServiceWorkerResponseWriter> writer( 116 scoped_ptr<ServiceWorkerResponseWriter> writer(
117 new ServiceWorkerResponseWriter(response.resource_id, disk_cache)); 117 new ServiceWorkerResponseWriter(response.resource_id, disk_cache));
118 118
119 // Write the response info. 119 // Write the response info.
120 scoped_ptr<net::HttpResponseInfo> info(new net::HttpResponseInfo); 120 scoped_ptr<net::HttpResponseInfo> info(new net::HttpResponseInfo);
121 info->request_time = base::Time() + base::TimeDelta::FromSeconds(10); 121 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()); 191 reader->ReadData(body_buffer.get(), kBigEnough, cb2.callback());
192 rv = cb2.WaitForResult(); 192 rv = cb2.WaitForResult();
193 ASSERT_EQ(static_cast<int>(expected.body.length()), rv); 193 ASSERT_EQ(static_cast<int>(expected.body.length()), rv);
194 EXPECT_EQ(0, memcmp(expected.body.data(), body_buffer->data(), rv)); 194 EXPECT_EQ(0, memcmp(expected.body.data(), body_buffer->data(), rv));
195 } 195 }
196 196
197 int32 GetEntryCount(ServiceWorkerDiskCache* disk_cache) { 197 int32 GetEntryCount(ServiceWorkerDiskCache* disk_cache) {
198 return disk_cache->disk_cache()->GetEntryCount(); 198 return disk_cache->disk_cache()->GetEntryCount();
199 } 199 }
200 200
201 ServiceWorkerStorage* storage() { return context_->storage(); }
202
201 private: 203 private:
202 TestBrowserThreadBundle browser_thread_bundle_; 204 TestBrowserThreadBundle browser_thread_bundle_;
203 base::ScopedTempDir user_data_directory_; 205 base::ScopedTempDir user_data_directory_;
204 206
205 scoped_ptr<ServiceWorkerContextCore> context_; 207 scoped_ptr<ServiceWorkerContextCore> context_;
206 }; 208 };
207 209
208 TEST_F(ServiceWorkerDiskCacheMigratorTest, MigrateDiskCache) { 210 TEST_F(ServiceWorkerDiskCacheMigratorTest, MigrateDiskCache) {
209 std::vector<ResponseData> responses; 211 std::vector<ResponseData> responses;
210 responses.push_back(ResponseData(1, "HTTP/1.1 200 OK\0\0", "Hello", "")); 212 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())); 324 migrator->Start(base::Bind(&OnDiskCacheMigrated, run_loop.QuitClosure()));
323 run_loop.Run(); 325 run_loop.Run();
324 326
325 // Verify the migrated contents in the dest diskcache. 327 // Verify the migrated contents in the dest diskcache.
326 scoped_ptr<ServiceWorkerDiskCache> dest(CreateDestDiskCache()); 328 scoped_ptr<ServiceWorkerDiskCache> dest(CreateDestDiskCache());
327 for (const ResponseData& response : responses) 329 for (const ResponseData& response : responses)
328 VerifyResponse(dest.get(), response); 330 VerifyResponse(dest.get(), response);
329 EXPECT_EQ(static_cast<int>(responses.size()), GetEntryCount(dest.get())); 331 EXPECT_EQ(static_cast<int>(responses.size()), GetEntryCount(dest.get()));
330 } 332 }
331 333
334 TEST_F(ServiceWorkerDiskCacheMigratorTest, MigrateOnDiskCacheAccess) {
335 std::vector<ResponseData> responses;
336 responses.push_back(ResponseData(1, "HTTP/1.1 200 OK\0\0", "Hello", ""));
337 responses.push_back(ResponseData(2, "HTTP/1.1 200 OK\0\0", "Service", ""));
338 responses.push_back(ResponseData(5, "HTTP/1.1 200 OK\0\0", "Worker", ""));
339 responses.push_back(ResponseData(3, "HTTP/1.1 200 OK\0\0", "World", "meta"));
340
341 // Populate initial resources in the src diskcache.
342 scoped_ptr<ServiceWorkerDiskCache> src(CreateSrcDiskCache());
343 for (const ResponseData& response : responses) {
344 ASSERT_TRUE(WriteResponse(src.get(), response));
345 VerifyResponse(src.get(), response);
346 }
347 ASSERT_EQ(static_cast<int>(responses.size()), GetEntryCount(src.get()));
348 ASSERT_TRUE(base::DirectoryExists(storage()->GetOldDiskCachePath()));
349 src.reset();
350
351 scoped_ptr<ServiceWorkerDatabase> database(
352 new ServiceWorkerDatabase(storage()->GetDatabasePath()));
353
354 // This is necessary to make the storage schedule diskcache migration.
355 database->set_skip_writing_diskcache_migration_state_on_init();
356
357 // Simulatie an existing database.
falken 2015/06/16 04:28:10 Simulate
nhiroki 2015/06/16 07:12:16 Done.
358 std::vector<ServiceWorkerDatabase::ResourceRecord> resources;
359 resources.push_back(ServiceWorkerDatabase::ResourceRecord(
360 1, GURL("https://example.com/foo"), 10));
361 ServiceWorkerDatabase::RegistrationData deleted_version;
362 std::vector<int64> newly_purgeable_resources;
363 ServiceWorkerDatabase::RegistrationData data;
364 data.registration_id = 100;
365 data.scope = GURL("https://example.com/");
366 data.script = GURL("https://example.com/script.js");
367 data.version_id = 200;
368 data.resources_total_size_bytes = 10;
369 ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
370 database->WriteRegistration(data, resources, &deleted_version,
371 &newly_purgeable_resources));
372 database.reset();
373
374 // LazyInitialize() reads initial data and should schedule to migrate.
375 ASSERT_FALSE(storage()->disk_cache_migration_needed_);
376 base::RunLoop run_loop;
377 storage()->LazyInitialize(run_loop.QuitClosure());
378 run_loop.Run();
379 EXPECT_TRUE(storage()->disk_cache_migration_needed_);
380
381 // DiskCache access should start the migration.
382 ServiceWorkerDiskCache* dest = storage()->disk_cache();
383
384 // Verify the migrated contents in the dest diskcache.
385 for (const ResponseData& response : responses)
386 VerifyResponse(dest, response);
387 EXPECT_EQ(static_cast<int>(responses.size()), GetEntryCount(dest));
388
389 // After the migration, the src diskcache should be deleted.
390 EXPECT_FALSE(base::DirectoryExists(storage()->GetOldDiskCachePath()));
391
392 // After the migration, the migration state should be updated.
393 bool migration_needed = false;
394 EXPECT_EQ(
395 ServiceWorkerDatabase::STATUS_OK,
396 storage()->database_->IsDiskCacheMigrationNeeded(&migration_needed));
397 EXPECT_FALSE(migration_needed);
398 bool deletion_needed = false;
399 EXPECT_EQ(
400 ServiceWorkerDatabase::STATUS_OK,
401 storage()->database_->IsOldDiskCacheDeletionNeeded(&deletion_needed));
402 EXPECT_FALSE(deletion_needed);
403 }
404
405 TEST_F(ServiceWorkerDiskCacheMigratorTest, NotMigrateOnDatabaseAccess) {
406 std::vector<ResponseData> responses;
407 responses.push_back(ResponseData(1, "HTTP/1.1 200 OK\0\0", "Hello", ""));
408 responses.push_back(ResponseData(2, "HTTP/1.1 200 OK\0\0", "Service", ""));
409 responses.push_back(ResponseData(5, "HTTP/1.1 200 OK\0\0", "Worker", ""));
410 responses.push_back(ResponseData(3, "HTTP/1.1 200 OK\0\0", "World", "meta"));
411
412 // Populate initial resources in the src diskcache.
413 scoped_ptr<ServiceWorkerDiskCache> src(CreateSrcDiskCache());
414 for (const ResponseData& response : responses) {
415 ASSERT_TRUE(WriteResponse(src.get(), response));
416 VerifyResponse(src.get(), response);
417 }
418 ASSERT_EQ(static_cast<int>(responses.size()), GetEntryCount(src.get()));
419 ASSERT_TRUE(base::DirectoryExists(storage()->GetOldDiskCachePath()));
420
421 scoped_ptr<ServiceWorkerDatabase> database(
422 new ServiceWorkerDatabase(storage()->GetDatabasePath()));
423
424 // This is necessary to make the storage schedule diskcache migration.
425 database->set_skip_writing_diskcache_migration_state_on_init();
426
427 // Simulate an existing database.
428 std::vector<ServiceWorkerDatabase::ResourceRecord> resources;
429 resources.push_back(ServiceWorkerDatabase::ResourceRecord(
430 1, GURL("https://example.com/foo"), 10));
431 ServiceWorkerDatabase::RegistrationData deleted_version;
432 std::vector<int64> newly_purgeable_resources;
433 ServiceWorkerDatabase::RegistrationData data;
434 data.registration_id = 100;
435 data.scope = GURL("https://example.com/");
436 data.script = GURL("https://example.com/script.js");
437 data.version_id = 200;
438 data.resources_total_size_bytes = 10;
439 ASSERT_EQ(ServiceWorkerDatabase::STATUS_OK,
440 database->WriteRegistration(data, resources, &deleted_version,
441 &newly_purgeable_resources));
442 database.reset();
443
444 // LazyInitialize() reads initial data and should schedule to migrate.
445 ASSERT_FALSE(storage()->disk_cache_migration_needed_);
446 base::RunLoop run_loop1;
447 storage()->LazyInitialize(run_loop1.QuitClosure());
448 run_loop1.Run();
449 EXPECT_TRUE(storage()->disk_cache_migration_needed_);
450
451 // Database access should not start the migration.
452 base::RunLoop run_loop2;
453 storage()->FindRegistrationForDocument(
454 GURL("http://example.com/"),
455 base::Bind(&OnRegistrationFound, run_loop2.QuitClosure()));
456 run_loop2.Run();
457
458 // Verify that the migration didn't happen.
459 scoped_ptr<ServiceWorkerDiskCache> dest(CreateDestDiskCache());
460 EXPECT_EQ(static_cast<int>(responses.size()), GetEntryCount(src.get()));
461 EXPECT_EQ(0, GetEntryCount(dest.get()));
462 EXPECT_TRUE(base::DirectoryExists(storage()->GetOldDiskCachePath()));
463 }
464
465 TEST_F(ServiceWorkerDiskCacheMigratorTest, NotMigrateForEmptyDatabase) {
466 std::vector<ResponseData> responses;
467 responses.push_back(ResponseData(1, "HTTP/1.1 200 OK\0\0", "Hello", ""));
468 responses.push_back(ResponseData(2, "HTTP/1.1 200 OK\0\0", "Service", ""));
469 responses.push_back(ResponseData(5, "HTTP/1.1 200 OK\0\0", "Worker", ""));
470 responses.push_back(ResponseData(3, "HTTP/1.1 200 OK\0\0", "World", "meta"));
471
472 // Populate initial resources in the src diskcache.
473 scoped_ptr<ServiceWorkerDiskCache> src(CreateSrcDiskCache());
474 for (const ResponseData& response : responses) {
475 ASSERT_TRUE(WriteResponse(src.get(), response));
476 VerifyResponse(src.get(), response);
477 }
478 ASSERT_EQ(static_cast<int>(responses.size()), GetEntryCount(src.get()));
479 ASSERT_TRUE(base::DirectoryExists(storage()->GetOldDiskCachePath()));
480 src.reset();
481
482 // LazyInitialize() reads initial data and should not schedule to migrate
483 // because the database is empty.
484 ASSERT_FALSE(storage()->disk_cache_migration_needed_);
485 base::RunLoop run_loop;
486 storage()->LazyInitialize(run_loop.QuitClosure());
487 run_loop.Run();
488 EXPECT_FALSE(storage()->disk_cache_migration_needed_);
489
490 // DiskCache access should not start the migration.
491 ServiceWorkerDiskCache* dest = storage()->disk_cache();
492
493 // Verify that the migration didn't happen.
494 src = CreateSrcDiskCache();
495 for (const ResponseData& response : responses)
496 VerifyResponse(src.get(), response);
497 EXPECT_EQ(static_cast<int>(responses.size()), GetEntryCount(src.get()));
498 EXPECT_TRUE(base::DirectoryExists(storage()->GetOldDiskCachePath()));
falken 2015/06/16 04:28:10 Question: Is the old disk cache directory never de
nhiroki 2015/06/16 07:12:16 Yes, never deleted. I think we don't have to handl
michaeln 2015/06/16 20:50:24 If we're worried about being sure to clean up, may
nhiroki 2015/06/17 01:01:53 SGTM. Updated the database initialization and this
499 EXPECT_EQ(0, GetEntryCount(dest));
500
501 // After the diskcache initialization, the migration state should be updated.
502 bool migration_needed = false;
503 EXPECT_EQ(
504 ServiceWorkerDatabase::STATUS_OK,
505 storage()->database_->IsDiskCacheMigrationNeeded(&migration_needed));
506 EXPECT_FALSE(migration_needed);
507 bool deletion_needed = false;
508 EXPECT_EQ(
509 ServiceWorkerDatabase::STATUS_OK,
510 storage()->database_->IsOldDiskCacheDeletionNeeded(&deletion_needed));
511 EXPECT_FALSE(deletion_needed);
512 }
513
332 } // namespace content 514 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698