Index: net/disk_cache/backend_tests.cc |
diff --git a/net/disk_cache/backend_tests.cc b/net/disk_cache/backend_tests.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..45fbf75be55046d1bb78d0fa64d7900bbca61e02 |
--- /dev/null |
+++ b/net/disk_cache/backend_tests.cc |
@@ -0,0 +1,468 @@ |
+// Copyright (c) 2014 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "net/disk_cache/backend_tests.h" |
+ |
+#include <string> |
+ |
+#include "base/strings/string_util.h" |
+#include "base/strings/stringprintf.h" |
+#include "net/base/io_buffer.h" |
+#include "net/base/net_errors.h" |
+#include "net/base/test_completion_callback.h" |
+#include "base/time/time.h" |
+#include "net/disk_cache/disk_cache.h" |
+#include "net/disk_cache/disk_cache_test.h" |
+#include "net/disk_cache/disk_cache_test_util.h" |
+ |
+using base::Time; |
+ |
+namespace disk_cache { |
+ |
+namespace { |
+ |
+TEST_P(DiskCacheBackendTest, BackendBasics) { |
+ InitCache(); |
+ disk_cache::Entry *entry1 = NULL, *entry2 = NULL; |
+ EXPECT_NE(net::OK, OpenEntry("the first key", &entry1)); |
+ ASSERT_EQ(net::OK, CreateEntry("the first key", &entry1)); |
+ ASSERT_TRUE(NULL != entry1); |
+ entry1->Close(); |
+ entry1 = NULL; |
+ |
+ ASSERT_EQ(net::OK, OpenEntry("the first key", &entry1)); |
+ ASSERT_TRUE(NULL != entry1); |
+ entry1->Close(); |
+ entry1 = NULL; |
+ |
+ EXPECT_NE(net::OK, CreateEntry("the first key", &entry1)); |
+ ASSERT_EQ(net::OK, OpenEntry("the first key", &entry1)); |
+ EXPECT_NE(net::OK, OpenEntry("some other key", &entry2)); |
+ ASSERT_EQ(net::OK, CreateEntry("some other key", &entry2)); |
+ ASSERT_TRUE(NULL != entry1); |
+ ASSERT_TRUE(NULL != entry2); |
+ EXPECT_EQ(2, cache()->GetEntryCount()); |
+ |
+ disk_cache::Entry* entry3 = NULL; |
+ ASSERT_EQ(net::OK, OpenEntry("some other key", &entry3)); |
+ ASSERT_TRUE(NULL != entry3); |
+ EXPECT_TRUE(entry2 == entry3); |
+ EXPECT_EQ(2, cache()->GetEntryCount()); |
+ |
+ EXPECT_EQ(net::OK, DoomEntry("some other key")); |
+ EXPECT_EQ(1, cache()->GetEntryCount()); |
+ entry1->Close(); |
+ entry2->Close(); |
+ entry3->Close(); |
+ |
+ EXPECT_EQ(net::OK, DoomEntry("the first key")); |
+ EXPECT_EQ(0, cache()->GetEntryCount()); |
+ |
+ ASSERT_EQ(net::OK, CreateEntry("the first key", &entry1)); |
+ ASSERT_EQ(net::OK, CreateEntry("some other key", &entry2)); |
+ entry1->Doom(); |
+ entry1->Close(); |
+ EXPECT_EQ(net::OK, DoomEntry("some other key")); |
+ EXPECT_EQ(0, cache()->GetEntryCount()); |
+ entry2->Close(); |
+} |
+ |
+TEST_P(DiskCacheBackendTest, Keying) { |
+ InitCache(); |
+ const char* kName1 = "the first key"; |
+ const char* kName2 = "the first Key"; |
+ disk_cache::Entry *entry1, *entry2; |
+ ASSERT_EQ(net::OK, CreateEntry(kName1, &entry1)); |
+ |
+ ASSERT_EQ(net::OK, CreateEntry(kName2, &entry2)); |
+ EXPECT_TRUE(entry1 != entry2) << "Case sensitive"; |
+ entry2->Close(); |
+ |
+ char buffer[30]; |
+ base::strlcpy(buffer, kName1, arraysize(buffer)); |
+ ASSERT_EQ(net::OK, OpenEntry(buffer, &entry2)); |
+ EXPECT_TRUE(entry1 == entry2); |
+ entry2->Close(); |
+ |
+ base::strlcpy(buffer + 1, kName1, arraysize(buffer) - 1); |
+ ASSERT_EQ(net::OK, OpenEntry(buffer + 1, &entry2)); |
+ EXPECT_TRUE(entry1 == entry2); |
+ entry2->Close(); |
+ |
+ base::strlcpy(buffer + 3, kName1, arraysize(buffer) - 3); |
+ ASSERT_EQ(net::OK, OpenEntry(buffer + 3, &entry2)); |
+ EXPECT_TRUE(entry1 == entry2); |
+ entry2->Close(); |
+ |
+ // Now verify long keys. |
+ char buffer2[20000]; |
+ memset(buffer2, 's', sizeof(buffer2)); |
+ buffer2[1023] = '\0'; |
+ ASSERT_EQ(net::OK, CreateEntry(buffer2, &entry2)) << "key on block file"; |
+ entry2->Close(); |
+ |
+ buffer2[1023] = 'g'; |
+ buffer2[19999] = '\0'; |
+ ASSERT_EQ(net::OK, CreateEntry(buffer2, &entry2)) << "key on external file"; |
+ entry2->Close(); |
+ entry1->Close(); |
+} |
+ |
+// XYZZY make less lame |
+TEST_P(DiskCacheTest, CreateBackend) { |
+ net::TestCompletionCallback cb; |
+ |
+ { |
+ scoped_ptr<disk_cache::Backend> cache; |
+ |
+ base::Thread cache_thread("CacheThread"); |
+ ASSERT_TRUE(cache_thread.StartWithOptions( |
+ base::Thread::Options(base::MessageLoop::TYPE_IO, 0))); |
+ |
+ // Now test the public API. |
+ int rv = |
+ disk_cache::CreateCacheBackend(net::DISK_CACHE, |
+ net::CACHE_BACKEND_DEFAULT, |
+ cache_path(), |
+ 0, |
+ false, |
+ cache_thread.message_loop_proxy().get(), |
+ NULL, |
+ &cache, |
+ cb.callback()); |
+ ASSERT_EQ(net::OK, cb.GetResult(rv)); |
+ ASSERT_TRUE(cache.get()); |
+ cache.reset(); |
+ |
+ rv = disk_cache::CreateCacheBackend(net::MEMORY_CACHE, |
+ net::CACHE_BACKEND_DEFAULT, |
+ base::FilePath(), 0, |
+ false, NULL, NULL, &cache, |
+ cb.callback()); |
+ ASSERT_EQ(net::OK, cb.GetResult(rv)); |
+ ASSERT_TRUE(cache.get()); |
+ cache.reset(); |
+ } |
+ |
+ base::MessageLoop::current()->RunUntilIdle(); |
+} |
+ |
+TEST_P(DiskCacheBackendTest, SetSize) { |
+ const int cache_size = 0x10000; |
+ SetMaxSize(cache_size); |
+ InitCache(); |
+ |
+ std::string first("some key"); |
+ std::string second("something else"); |
+ disk_cache::Entry* entry; |
+ ASSERT_EQ(net::OK, CreateEntry(first, &entry)); |
+ |
+ scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(cache_size)); |
+ memset(buffer->data(), 0, cache_size); |
+ EXPECT_EQ(cache_size / 10, |
+ WriteData(entry, 0, 0, buffer.get(), cache_size / 10, false)) |
+ << "normal file"; |
+ |
+ EXPECT_EQ(net::ERR_FAILED, |
+ WriteData(entry, 1, 0, buffer.get(), cache_size / 5, false)) |
+ << "file size above the limit"; |
+ |
+ // By doubling the total size, we make this file cacheable. |
+ SetMaxSize(cache_size * 2); |
+ EXPECT_EQ(cache_size / 5, |
+ WriteData(entry, 1, 0, buffer.get(), cache_size / 5, false)); |
+ |
+ // Let's fill up the cache!. |
+ SetMaxSize(cache_size * 10); |
+ EXPECT_EQ(cache_size * 3 / 4, |
+ WriteData(entry, 0, 0, buffer.get(), cache_size * 3 / 4, false)); |
+ entry->Close(); |
+ FlushQueueForTest(); |
+ |
+ SetMaxSize(cache_size); |
+ |
+ // The cache is 95% full. |
+ |
+ ASSERT_EQ(net::OK, CreateEntry(second, &entry)); |
+ EXPECT_EQ(cache_size / 10, |
+ WriteData(entry, 0, 0, buffer.get(), cache_size / 10, false)); |
+ |
+ disk_cache::Entry* entry2; |
+ ASSERT_EQ(net::OK, CreateEntry("an extra key", &entry2)); |
+ EXPECT_EQ(cache_size / 10, |
+ WriteData(entry2, 0, 0, buffer.get(), cache_size / 10, 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(); |
+} |
+ |
+TEST_P(DiskCacheBackendTest, BackendLoad) { |
+ // TODO(gavinp) mask?? ugh. |
+ SetMaxSize(0x100000); |
+ InitCache(); |
+ int seed = static_cast<int>(Time::Now().ToInternalValue()); |
+ srand(seed); |
+ |
+ disk_cache::Entry* entries[100]; |
+ for (int i = 0; i < 100; i++) { |
+ std::string key = GenerateKey(true); |
+ ASSERT_EQ(net::OK, CreateEntry(key, &entries[i])); |
+ } |
+ EXPECT_EQ(100, cache()->GetEntryCount()); |
+ |
+ for (int i = 0; i < 100; i++) { |
+ int source1 = rand() % 100; |
+ int source2 = rand() % 100; |
+ disk_cache::Entry* temp = entries[source1]; |
+ entries[source1] = entries[source2]; |
+ entries[source2] = temp; |
+ } |
+ |
+ for (int i = 0; i < 100; i++) { |
+ disk_cache::Entry* entry; |
+ ASSERT_EQ(net::OK, OpenEntry(entries[i]->GetKey(), &entry)); |
+ EXPECT_TRUE(entry == entries[i]); |
+ entry->Close(); |
+ entries[i]->Doom(); |
+ entries[i]->Close(); |
+ } |
+ FlushQueueForTest(); |
+ EXPECT_EQ(0, cache()->GetEntryCount()); |
+} |
+ |
+TEST_P(DiskCacheBackendTest, DoomRecent) { |
+ InitCache(); |
+ |
+ disk_cache::Entry *entry; |
+ ASSERT_EQ(net::OK, CreateEntry("first", &entry)); |
+ entry->Close(); |
+ ASSERT_EQ(net::OK, CreateEntry("second", &entry)); |
+ entry->Close(); |
+ FlushQueueForTest(); |
+ |
+ AddDelay(); |
+ Time middle = Time::Now(); |
+ |
+ ASSERT_EQ(net::OK, CreateEntry("third", &entry)); |
+ entry->Close(); |
+ ASSERT_EQ(net::OK, CreateEntry("fourth", &entry)); |
+ entry->Close(); |
+ FlushQueueForTest(); |
+ |
+ AddDelay(); |
+ Time final = Time::Now(); |
+ |
+ ASSERT_EQ(4, cache()->GetEntryCount()); |
+ EXPECT_EQ(net::OK, DoomEntriesSince(final)); |
+ ASSERT_EQ(4, cache()->GetEntryCount()); |
+ |
+ EXPECT_EQ(net::OK, DoomEntriesSince(middle)); |
+ ASSERT_EQ(2, cache()->GetEntryCount()); |
+ |
+ ASSERT_EQ(net::OK, OpenEntry("second", &entry)); |
+ entry->Close(); |
+} |
+ |
+void InitSparseCache(DiskCacheTest* test, |
+ base::Time* doomed_start, |
+ base::Time* doomed_end) { |
+ test->InitCache(); |
+ |
+ const int kSize = 50; |
+ // This must be greater then MemEntryImpl::kMaxSparseEntrySize. |
+ const int kOffset = 10 + 1024 * 1024; |
+ |
+ disk_cache::Entry* entry0 = NULL; |
+ disk_cache::Entry* entry1 = NULL; |
+ disk_cache::Entry* entry2 = NULL; |
+ |
+ scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize)); |
+ CacheTestFillBuffer(buffer->data(), kSize, false); |
+ |
+ ASSERT_EQ(net::OK, test->CreateEntry("zeroth", &entry0)); |
+ ASSERT_EQ(kSize, test->WriteSparseData(entry0, 0, buffer.get(), kSize)); |
+ ASSERT_EQ(kSize, |
+ test->WriteSparseData(entry0, kOffset + kSize, buffer.get(), kSize)); |
+ entry0->Close(); |
+ |
+ test->FlushQueueForTest(); |
+ test->AddDelay(); |
+ if (doomed_start) |
+ *doomed_start = base::Time::Now(); |
+ |
+ // Order in rankings list: |
+ // first_part1, first_part2, second_part1, second_part2 |
+ ASSERT_EQ(net::OK, test->CreateEntry("first", &entry1)); |
+ ASSERT_EQ(kSize, test->WriteSparseData(entry1, 0, buffer.get(), kSize)); |
+ ASSERT_EQ(kSize, |
+ test->WriteSparseData(entry1, kOffset + kSize, buffer.get(), kSize)); |
+ entry1->Close(); |
+ |
+ ASSERT_EQ(net::OK, test->CreateEntry("second", &entry2)); |
+ ASSERT_EQ(kSize, test->WriteSparseData(entry2, 0, buffer.get(), kSize)); |
+ ASSERT_EQ(kSize, |
+ test->WriteSparseData(entry2, kOffset + kSize, buffer.get(), kSize)); |
+ entry2->Close(); |
+ |
+ test->FlushQueueForTest(); |
+ test->AddDelay(); |
+ if (doomed_end) |
+ *doomed_end = base::Time::Now(); |
+ test->AddDelay(); |
+ |
+ // Order in rankings list: |
+ // third_part1, fourth_part1, third_part2, fourth_part2 |
+ disk_cache::Entry* entry3 = NULL; |
+ disk_cache::Entry* entry4 = NULL; |
+ ASSERT_EQ(net::OK, test->CreateEntry("third", &entry3)); |
+ ASSERT_EQ(kSize, test->WriteSparseData(entry3, 0, buffer.get(), kSize)); |
+ ASSERT_EQ(net::OK, test->CreateEntry("fourth", &entry4)); |
+ ASSERT_EQ(kSize, test->WriteSparseData(entry4, 0, buffer.get(), kSize)); |
+ ASSERT_EQ(kSize, |
+ test->WriteSparseData(entry3, kOffset + kSize, buffer.get(), kSize)); |
+ ASSERT_EQ(kSize, |
+ test->WriteSparseData(entry4, kOffset + kSize, buffer.get(), kSize)); |
+ entry3->Close(); |
+ entry4->Close(); |
+ |
+ test->FlushQueueForTest(); |
+ test->AddDelay(); |
+} |
+ |
+TEST_P(DiskCacheBackendTest, DoomEntriesSinceSparse) { |
+ base::Time start; |
+ InitSparseCache(this, &start, NULL); |
+ DoomEntriesSince(start); |
+ if (traits()->EntryCountIncludesSparseRanges()) |
+ EXPECT_EQ(3, cache()->GetEntryCount()); |
+ else |
+ EXPECT_EQ(1, cache()->GetEntryCount()); |
+} |
+ |
+TEST_P(DiskCacheBackendTest, DoomAllSparse) { |
+ InitSparseCache(this, NULL, NULL); |
+ EXPECT_EQ(net::OK, DoomAllEntries()); |
+ EXPECT_EQ(0, cache()->GetEntryCount()); |
+} |
+ |
+TEST_P(DiskCacheBackendTest, DoomBetween) { |
+ InitCache(); |
+ |
+ disk_cache::Entry *entry; |
+ ASSERT_EQ(net::OK, CreateEntry("first", &entry)); |
+ entry->Close(); |
+ FlushQueueForTest(); |
+ |
+ AddDelay(); |
+ Time middle_start = Time::Now(); |
+ |
+ ASSERT_EQ(net::OK, CreateEntry("second", &entry)); |
+ entry->Close(); |
+ ASSERT_EQ(net::OK, CreateEntry("third", &entry)); |
+ entry->Close(); |
+ FlushQueueForTest(); |
+ |
+ AddDelay(); |
+ Time middle_end = Time::Now(); |
+ AddDelay(); |
+ |
+ ASSERT_EQ(net::OK, CreateEntry("fourth", &entry)); |
+ entry->Close(); |
+ ASSERT_EQ(net::OK, OpenEntry("fourth", &entry)); |
+ entry->Close(); |
+ FlushQueueForTest(); |
+ |
+ AddDelay(); |
+ Time final = Time::Now(); |
+ |
+ ASSERT_EQ(4, cache()->GetEntryCount()); |
+ EXPECT_EQ(net::OK, DoomEntriesBetween(middle_start, middle_end)); |
+ ASSERT_EQ(2, cache()->GetEntryCount()); |
+ |
+ ASSERT_EQ(net::OK, OpenEntry("fourth", &entry)); |
+ entry->Close(); |
+ |
+ EXPECT_EQ(net::OK, DoomEntriesBetween(middle_start, final)); |
+ ASSERT_EQ(1, cache()->GetEntryCount()); |
+ |
+ ASSERT_EQ(net::OK, OpenEntry("first", &entry)); |
+ entry->Close(); |
+} |
+ |
+TEST_P(DiskCacheBackendTest, DoomEntriesBetweenSparse) { |
+ base::Time start, end; |
+ InitSparseCache(this, &start, &end); |
+ DoomEntriesBetween(start, end); |
+ if (traits()->EntryCountIncludesSparseRanges()) |
+ EXPECT_EQ(9, cache()->GetEntryCount()); |
+ else |
+ EXPECT_EQ(3, cache()->GetEntryCount()); |
+ |
+ start = end; |
+ end = base::Time::Now(); |
+ DoomEntriesBetween(start, end); |
+ if (traits()->EntryCountIncludesSparseRanges()) |
+ EXPECT_EQ(3, cache()->GetEntryCount()); |
+ else |
+ EXPECT_EQ(1, cache()->GetEntryCount()); |
+} |
+ |
+ |
+TEST_P(DiskCacheBackendTest, DoomAll) { |
+ InitCache(); |
+ |
+ disk_cache::Entry *entry1, *entry2; |
+ ASSERT_EQ(net::OK, CreateEntry("first", &entry1)); |
+ ASSERT_EQ(net::OK, CreateEntry("second", &entry2)); |
+ entry1->Close(); |
+ entry2->Close(); |
+ |
+ ASSERT_EQ(net::OK, CreateEntry("third", &entry1)); |
+ ASSERT_EQ(net::OK, CreateEntry("fourth", &entry2)); |
+ |
+ ASSERT_EQ(4, cache()->GetEntryCount()); |
+ EXPECT_EQ(net::OK, DoomAllEntries()); |
+ ASSERT_EQ(0, cache()->GetEntryCount()); |
+ |
+ // We should stop posting tasks at some point (if we post any). |
+ base::MessageLoop::current()->RunUntilIdle(); |
+ |
+ disk_cache::Entry *entry3, *entry4; |
+ EXPECT_NE(net::OK, OpenEntry("third", &entry3)); |
+ ASSERT_EQ(net::OK, CreateEntry("third", &entry3)); |
+ ASSERT_EQ(net::OK, CreateEntry("fourth", &entry4)); |
+ |
+ EXPECT_EQ(net::OK, DoomAllEntries()); |
+ ASSERT_EQ(0, cache()->GetEntryCount()); |
+ |
+ entry1->Close(); |
+ entry2->Close(); |
+ entry3->Doom(); // The entry should be already doomed, but this must work. |
+ entry3->Close(); |
+ entry4->Close(); |
+ |
+ // Now try with all references released. |
+ ASSERT_EQ(net::OK, CreateEntry("third", &entry1)); |
+ ASSERT_EQ(net::OK, CreateEntry("fourth", &entry2)); |
+ entry1->Close(); |
+ entry2->Close(); |
+ |
+ ASSERT_EQ(2, cache()->GetEntryCount()); |
+ EXPECT_EQ(net::OK, DoomAllEntries()); |
+ ASSERT_EQ(0, cache()->GetEntryCount()); |
+ |
+ EXPECT_EQ(net::OK, DoomAllEntries()); |
+} |
+ |
+} // namespace |
+ |
+} // namespace disk_cache |