| Index: net/disk_cache/backend_unittest.cc
|
| ===================================================================
|
| --- net/disk_cache/backend_unittest.cc (revision 51874)
|
| +++ net/disk_cache/backend_unittest.cc (working copy)
|
| @@ -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 @@
|
| 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,33 +267,80 @@
|
| 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();
|
| +}
|
| +
|
| TEST_F(DiskCacheTest, TruncatedIndex) {
|
| FilePath path = GetCacheFilePath();
|
| ASSERT_TRUE(DeleteCache(path));
|
| @@ -344,6 +391,7 @@
|
| 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 @@
|
|
|
| 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";
|
| + NULL, false));
|
| +
|
| + 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();
|
| -
|
| - EXPECT_NE(net::OK, OpenEntry(first, &entry));
|
| ASSERT_EQ(net::OK, OpenEntry(second, &entry));
|
| EXPECT_EQ(cache_size / 10, entry->GetDataSize(0));
|
| entry->Close();
|
| @@ -402,6 +460,7 @@
|
| entries[i]->Doom();
|
| entries[i]->Close();
|
| }
|
| + FlushQueueForTest();
|
| EXPECT_EQ(0, cache_->GetEntryCount());
|
| }
|
|
|
| @@ -625,6 +684,7 @@
|
| 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 @@
|
| }
|
|
|
| entry->Close(); // Trim the cache.
|
| + FlushQueueForTest();
|
|
|
| // We may abort the eviction before cleaning up everything.
|
| MessageLoop::current()->RunAllPending();
|
| @@ -1259,7 +1320,7 @@
|
| 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 @@
|
| 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 @@
|
| ASSERT_LT(count, 9);
|
| };
|
|
|
| - MessageLoop::current()->RunAllPending();
|
| + FlushQueueForTest();
|
| EXPECT_EQ(0, cache_->GetEntryCount());
|
| }
|
|
|
| @@ -1414,7 +1476,7 @@
|
| 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 @@
|
| 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());
|
| }
|
|
|