| 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
|
|
|