diff options
Diffstat (limited to 'net/disk_cache/backend_unittest.cc')
-rw-r--r-- | net/disk_cache/backend_unittest.cc | 97 |
1 files changed, 80 insertions, 17 deletions
diff --git a/net/disk_cache/backend_unittest.cc b/net/disk_cache/backend_unittest.cc index efb7925..a9ab2a2 100644 --- a/net/disk_cache/backend_unittest.cc +++ b/net/disk_cache/backend_unittest.cc @@ -7,7 +7,6 @@ #include "base/path_service.h" #include "base/platform_thread.h" #include "base/string_util.h" -#include "base/thread.h" #include "net/base/io_buffer.h" #include "net/base/net_errors.h" #include "net/base/test_completion_callback.h" @@ -254,8 +253,9 @@ TEST_F(DiskCacheBackendTest, ExternalFiles) { EXPECT_EQ(0, memcmp(buffer1->data(), buffer2->data(), kSize)); } +// Tests that we deal with file-level pending operations at destruction time. TEST_F(DiskCacheTest, ShutdownWithPendingIO) { - TestCompletionCallback callback; + TestCompletionCallback cb; { FilePath path = GetCacheFilePath(); @@ -267,28 +267,75 @@ TEST_F(DiskCacheTest, ShutdownWithPendingIO) { disk_cache::Backend* cache; int rv = disk_cache::BackendImpl::CreateBackend( path, false, 0, net::DISK_CACHE, disk_cache::kNoRandom, - cache_thread.message_loop_proxy(), &cache, &callback); - ASSERT_EQ(net::OK, callback.GetResult(rv)); + base::MessageLoopProxy::CreateForCurrentThread(), &cache, &cb); + ASSERT_EQ(net::OK, cb.GetResult(rv)); - disk_cache::Entry* entry; - rv = cache->CreateEntry("some key", &entry, &callback); - ASSERT_EQ(net::OK, callback.GetResult(rv)); + disk_cache::EntryImpl* entry; + rv = cache->CreateEntry("some key", + reinterpret_cast<disk_cache::Entry**>(&entry), &cb); + ASSERT_EQ(net::OK, cb.GetResult(rv)); const int kSize = 25000; scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kSize); CacheTestFillBuffer(buffer->data(), kSize, false); for (int i = 0; i < 10 * 1024 * 1024; i += 64 * 1024) { - int rv = entry->WriteData(0, i, buffer, kSize, &callback, false); + // We are using the current thread as the cache thread because we want to + // be able to call directly this method to make sure that the OS (instead + // of us switching thread) is returning IO pending. + rv = entry->WriteDataImpl(0, i, buffer, kSize, &cb, false); if (rv == net::ERR_IO_PENDING) break; EXPECT_EQ(kSize, rv); } - entry->Close(); + // Don't call Close() to avoid going through the queue or we'll deadlock + // waiting for the operation to finish. + entry->Release(); // The cache destructor will see one pending operation here. delete cache; + + if (rv == net::ERR_IO_PENDING) { + EXPECT_TRUE(cb.have_result()); + } + } + + MessageLoop::current()->RunAllPending(); +} + +// Tests that we deal with background-thread pending operations. +TEST_F(DiskCacheTest, ShutdownWithPendingIO2) { + TestCompletionCallback cb; + + { + FilePath path = GetCacheFilePath(); + ASSERT_TRUE(DeleteCache(path)); + base::Thread cache_thread("CacheThread"); + ASSERT_TRUE(cache_thread.StartWithOptions( + base::Thread::Options(MessageLoop::TYPE_IO, 0))); + + disk_cache::Backend* cache; + int rv = disk_cache::BackendImpl::CreateBackend( + path, false, 0, net::DISK_CACHE, disk_cache::kNoRandom, + cache_thread.message_loop_proxy(), &cache, &cb); + ASSERT_EQ(net::OK, cb.GetResult(rv)); + + disk_cache::Entry* entry; + rv = cache->CreateEntry("some key", &entry, &cb); + ASSERT_EQ(net::OK, cb.GetResult(rv)); + + const int kSize = 25000; + scoped_refptr<net::IOBuffer> buffer = new net::IOBuffer(kSize); + CacheTestFillBuffer(buffer->data(), kSize, false); + + rv = entry->WriteData(0, 0, buffer, kSize, &cb, false); + EXPECT_EQ(net::ERR_IO_PENDING, rv); + + entry->Close(); + + // The cache destructor will see two pending operations here. + delete cache; } MessageLoop::current()->RunAllPending(); @@ -344,6 +391,7 @@ void DiskCacheBackendTest::BackendSetSize() { EXPECT_EQ(cache_size * 3 / 4, entry->WriteData(0, 0, buffer, cache_size * 3 / 4, NULL, false)); entry->Close(); + FlushQueueForTest(); SetMaxSize(cache_size); @@ -351,10 +399,20 @@ void DiskCacheBackendTest::BackendSetSize() { ASSERT_EQ(net::OK, CreateEntry(second, &entry)); EXPECT_EQ(cache_size / 10, entry->WriteData(0, 0, buffer, cache_size / 10, - NULL, false)) << "trim the cache"; - entry->Close(); + NULL, false)); - EXPECT_NE(net::OK, OpenEntry(first, &entry)); + disk_cache::Entry* entry2; + ASSERT_EQ(net::OK, CreateEntry("an extra key", &entry2)); + EXPECT_EQ(cache_size / 10, entry2->WriteData(0, 0, buffer, cache_size / 10, + NULL, false)); + entry2->Close(); // This will trigger the cache trim. + + EXPECT_NE(net::OK, OpenEntry(first, &entry2)); + + FlushQueueForTest(); // Make sure that we are done trimming the cache. + FlushQueueForTest(); // We may have posted two tasks to evict stuff. + + entry->Close(); ASSERT_EQ(net::OK, OpenEntry(second, &entry)); EXPECT_EQ(cache_size / 10, entry->GetDataSize(0)); entry->Close(); @@ -402,6 +460,7 @@ void DiskCacheBackendTest::BackendLoad() { entries[i]->Doom(); entries[i]->Close(); } + FlushQueueForTest(); EXPECT_EQ(0, cache_->GetEntryCount()); } @@ -625,6 +684,7 @@ void DiskCacheBackendTest::BackendTrimInvalidEntry() { EXPECT_EQ(2, cache_->GetEntryCount()); SetMaxSize(kSize); entry->Close(); // Trim the cache. + FlushQueueForTest(); // If we evicted the entry in less than 20mS, we have one entry in the cache; // if it took more than that, we posted a task and we'll delete the second @@ -685,6 +745,7 @@ void DiskCacheBackendTest::BackendTrimInvalidEntry2() { } entry->Close(); // Trim the cache. + FlushQueueForTest(); // We may abort the eviction before cleaning up everything. MessageLoop::current()->RunAllPending(); @@ -1259,7 +1320,7 @@ void DiskCacheBackendTest::BackendInvalidRankings() { EXPECT_EQ(2, cache_->GetEntryCount()); EXPECT_NE(net::OK, OpenNextEntry(&iter, &entry)); - MessageLoop::current()->RunAllPending(); + FlushQueueForTest(); // Allow the restart to finish. EXPECT_EQ(0, cache_->GetEntryCount()); } @@ -1310,7 +1371,8 @@ void DiskCacheBackendTest::BackendDisable() { EXPECT_NE(net::OK, CreateEntry("Something new", &entry2)); entry1->Close(); - MessageLoop::current()->RunAllPending(); + FlushQueueForTest(); // Flushing the Close posts a task to restart the cache. + FlushQueueForTest(); // This one actually allows that task to complete. EXPECT_EQ(0, cache_->GetEntryCount()); } @@ -1365,7 +1427,7 @@ void DiskCacheBackendTest::BackendDisable2() { ASSERT_LT(count, 9); }; - MessageLoop::current()->RunAllPending(); + FlushQueueForTest(); EXPECT_EQ(0, cache_->GetEntryCount()); } @@ -1414,7 +1476,7 @@ void DiskCacheBackendTest::BackendDisable3() { entry1->Close(); EXPECT_NE(net::OK, OpenNextEntry(&iter, &entry2)); - MessageLoop::current()->RunAllPending(); + FlushQueueForTest(); ASSERT_EQ(net::OK, CreateEntry("Something new", &entry2)); entry2->Close(); @@ -1482,7 +1544,8 @@ void DiskCacheBackendTest::BackendDisable4() { entry1->Close(); entry2->Close(); entry3->Close(); - MessageLoop::current()->RunAllPending(); + FlushQueueForTest(); // Flushing the Close posts a task to restart the cache. + FlushQueueForTest(); // This one actually allows that task to complete. EXPECT_EQ(0, cache_->GetEntryCount()); } |