blob: 91051413e3e496f2964c0b601c34315c4bb8b512 [file] [log] [blame]
// Copyright (c) 2011 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 "base/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/hash.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/pickle.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/time/time.h"
#include "net/disk_cache/simple/simple_entry_format.h"
#include "net/disk_cache/simple/simple_index.h"
#include "net/disk_cache/simple/simple_index_file.h"
#include "net/disk_cache/simple/simple_util.h"
#include "testing/gtest/include/gtest/gtest.h"
using base::Time;
using disk_cache::SimpleIndexFile;
using disk_cache::SimpleIndex;
namespace disk_cache {
TEST(IndexMetadataTest, Basics) {
SimpleIndexFile::IndexMetadata index_metadata;
EXPECT_EQ(disk_cache::kSimpleIndexMagicNumber, index_metadata.magic_number_);
EXPECT_EQ(disk_cache::kSimpleVersion, index_metadata.version_);
EXPECT_EQ(0U, index_metadata.GetNumberOfEntries());
EXPECT_EQ(0U, index_metadata.cache_size_);
EXPECT_TRUE(index_metadata.CheckIndexMetadata());
}
TEST(IndexMetadataTest, Serialize) {
SimpleIndexFile::IndexMetadata index_metadata(123, 456);
Pickle pickle;
index_metadata.Serialize(&pickle);
PickleIterator it(pickle);
SimpleIndexFile::IndexMetadata new_index_metadata;
new_index_metadata.Deserialize(&it);
EXPECT_EQ(new_index_metadata.magic_number_, index_metadata.magic_number_);
EXPECT_EQ(new_index_metadata.version_, index_metadata.version_);
EXPECT_EQ(new_index_metadata.GetNumberOfEntries(),
index_metadata.GetNumberOfEntries());
EXPECT_EQ(new_index_metadata.cache_size_, index_metadata.cache_size_);
EXPECT_TRUE(new_index_metadata.CheckIndexMetadata());
}
// This friend derived class is able to reexport its ancestors private methods
// as public, for use in tests.
class WrappedSimpleIndexFile : public SimpleIndexFile {
public:
using SimpleIndexFile::Deserialize;
using SimpleIndexFile::IsIndexFileStale;
using SimpleIndexFile::Serialize;
explicit WrappedSimpleIndexFile(const base::FilePath& index_file_directory)
: SimpleIndexFile(base::MessageLoopProxy::current().get(),
base::MessageLoopProxy::current().get(),
index_file_directory) {}
virtual ~WrappedSimpleIndexFile() {
}
const base::FilePath& GetIndexFilePath() const {
return index_file_;
}
};
class SimpleIndexFileTest : public testing::Test {
public:
bool CompareTwoEntryMetadata(const EntryMetadata& a, const EntryMetadata& b) {
return
a.last_used_time_seconds_since_epoch_ ==
b.last_used_time_seconds_since_epoch_ &&
a.entry_size_ == b.entry_size_;
}
protected:
SimpleIndexFileTest() : callback_called_(false) {}
base::Closure GetCallback() {
return base::Bind(&SimpleIndexFileTest::LoadIndexEntriesCallback,
base::Unretained(this));
}
bool callback_called() { return callback_called_; }
private:
void LoadIndexEntriesCallback() {
EXPECT_FALSE(callback_called_);
callback_called_ = true;
}
bool callback_called_;
};
TEST_F(SimpleIndexFileTest, Serialize) {
SimpleIndex::EntrySet entries;
static const uint64 kHashes[] = { 11, 22, 33 };
static const size_t kNumHashes = arraysize(kHashes);
EntryMetadata metadata_entries[kNumHashes];
SimpleIndexFile::IndexMetadata index_metadata(static_cast<uint64>(kNumHashes),
456);
for (size_t i = 0; i < kNumHashes; ++i) {
uint64 hash = kHashes[i];
metadata_entries[i] = EntryMetadata(Time(), hash);
SimpleIndex::InsertInEntrySet(hash, metadata_entries[i], &entries);
}
scoped_ptr<Pickle> pickle = WrappedSimpleIndexFile::Serialize(
index_metadata, entries);
EXPECT_TRUE(pickle.get() != NULL);
SimpleIndexLoadResult deserialize_result;
WrappedSimpleIndexFile::Deserialize(static_cast<const char*>(pickle->data()),
pickle->size(),
&deserialize_result);
EXPECT_TRUE(deserialize_result.did_load);
const SimpleIndex::EntrySet& new_entries = deserialize_result.entries;
EXPECT_EQ(entries.size(), new_entries.size());
for (size_t i = 0; i < kNumHashes; ++i) {
SimpleIndex::EntrySet::const_iterator it = new_entries.find(kHashes[i]);
EXPECT_TRUE(new_entries.end() != it);
EXPECT_TRUE(CompareTwoEntryMetadata(it->second, metadata_entries[i]));
}
}
TEST_F(SimpleIndexFileTest, IsIndexFileStale) {
base::ScopedTempDir cache_dir;
ASSERT_TRUE(cache_dir.CreateUniqueTempDir());
base::PlatformFileInfo file_info;
const base::FilePath cache_path = cache_dir.path();
ASSERT_TRUE(file_util::GetFileInfo(cache_path, &file_info));
WrappedSimpleIndexFile simple_index_file(cache_path);
const base::FilePath& index_path = simple_index_file.GetIndexFilePath();
EXPECT_TRUE(WrappedSimpleIndexFile::IsIndexFileStale(file_info.last_modified,
index_path));
const std::string kDummyData = "nothing to be seen here";
EXPECT_EQ(static_cast<int>(kDummyData.size()),
file_util::WriteFile(index_path,
kDummyData.data(),
kDummyData.size()));
ASSERT_TRUE(file_util::GetFileInfo(cache_path, &file_info));
EXPECT_FALSE(WrappedSimpleIndexFile::IsIndexFileStale(file_info.last_modified,
index_path));
const base::Time past_time = base::Time::Now() -
base::TimeDelta::FromSeconds(10);
EXPECT_TRUE(file_util::TouchFile(index_path, past_time, past_time));
EXPECT_TRUE(file_util::TouchFile(cache_path, past_time, past_time));
ASSERT_TRUE(file_util::GetFileInfo(cache_path, &file_info));
EXPECT_FALSE(WrappedSimpleIndexFile::IsIndexFileStale(file_info.last_modified,
index_path));
const base::Time even_older =
past_time - base::TimeDelta::FromSeconds(10);
EXPECT_TRUE(file_util::TouchFile(index_path, even_older, even_older));
EXPECT_TRUE(WrappedSimpleIndexFile::IsIndexFileStale(file_info.last_modified,
index_path));
}
TEST_F(SimpleIndexFileTest, WriteThenLoadIndex) {
base::ScopedTempDir cache_dir;
ASSERT_TRUE(cache_dir.CreateUniqueTempDir());
SimpleIndex::EntrySet entries;
static const uint64 kHashes[] = { 11, 22, 33 };
static const size_t kNumHashes = arraysize(kHashes);
EntryMetadata metadata_entries[kNumHashes];
for (size_t i = 0; i < kNumHashes; ++i) {
uint64 hash = kHashes[i];
metadata_entries[i] = EntryMetadata(Time(), hash);
SimpleIndex::InsertInEntrySet(hash, metadata_entries[i], &entries);
}
const uint64 kCacheSize = 456U;
{
WrappedSimpleIndexFile simple_index_file(cache_dir.path());
simple_index_file.WriteToDisk(entries, kCacheSize,
base::TimeTicks(), false);
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(base::PathExists(simple_index_file.GetIndexFilePath()));
}
WrappedSimpleIndexFile simple_index_file(cache_dir.path());
base::PlatformFileInfo file_info;
ASSERT_TRUE(file_util::GetFileInfo(simple_index_file.GetIndexFilePath(),
&file_info));
SimpleIndexLoadResult load_index_result;
simple_index_file.LoadIndexEntries(file_info.last_modified,
GetCallback(),
&load_index_result);
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(base::PathExists(simple_index_file.GetIndexFilePath()));
ASSERT_TRUE(callback_called());
EXPECT_TRUE(load_index_result.did_load);
EXPECT_FALSE(load_index_result.flush_required);
EXPECT_EQ(kNumHashes, load_index_result.entries.size());
for (size_t i = 0; i < kNumHashes; ++i)
EXPECT_EQ(1U, load_index_result.entries.count(kHashes[i]));
}
TEST_F(SimpleIndexFileTest, LoadCorruptIndex) {
base::ScopedTempDir cache_dir;
ASSERT_TRUE(cache_dir.CreateUniqueTempDir());
WrappedSimpleIndexFile simple_index_file(cache_dir.path());
const base::FilePath& index_path = simple_index_file.GetIndexFilePath();
const std::string kDummyData = "nothing to be seen here";
EXPECT_EQ(static_cast<int>(kDummyData.size()),
file_util::WriteFile(index_path,
kDummyData.data(),
kDummyData.size()));
base::PlatformFileInfo file_info;
ASSERT_TRUE(file_util::GetFileInfo(simple_index_file.GetIndexFilePath(),
&file_info));
EXPECT_FALSE(WrappedSimpleIndexFile::IsIndexFileStale(file_info.last_modified,
index_path));
SimpleIndexLoadResult load_index_result;
simple_index_file.LoadIndexEntries(file_info.last_modified,
GetCallback(),
&load_index_result);
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(base::PathExists(index_path));
ASSERT_TRUE(callback_called());
EXPECT_TRUE(load_index_result.did_load);
EXPECT_TRUE(load_index_result.flush_required);
}
} // namespace disk_cache