OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/file_util.h" | 5 #include "base/file_util.h" |
6 #include "base/files/scoped_temp_dir.h" | 6 #include "base/files/scoped_temp_dir.h" |
7 #include "base/hash.h" | 7 #include "base/hash.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
10 #include "base/message_loop/message_loop_proxy.h" | 10 #include "base/message_loop/message_loop_proxy.h" |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 | 44 |
45 EXPECT_EQ(new_index_metadata.magic_number_, index_metadata.magic_number_); | 45 EXPECT_EQ(new_index_metadata.magic_number_, index_metadata.magic_number_); |
46 EXPECT_EQ(new_index_metadata.version_, index_metadata.version_); | 46 EXPECT_EQ(new_index_metadata.version_, index_metadata.version_); |
47 EXPECT_EQ(new_index_metadata.GetNumberOfEntries(), | 47 EXPECT_EQ(new_index_metadata.GetNumberOfEntries(), |
48 index_metadata.GetNumberOfEntries()); | 48 index_metadata.GetNumberOfEntries()); |
49 EXPECT_EQ(new_index_metadata.cache_size_, index_metadata.cache_size_); | 49 EXPECT_EQ(new_index_metadata.cache_size_, index_metadata.cache_size_); |
50 | 50 |
51 EXPECT_TRUE(new_index_metadata.CheckIndexMetadata()); | 51 EXPECT_TRUE(new_index_metadata.CheckIndexMetadata()); |
52 } | 52 } |
53 | 53 |
| 54 // This friend derived class is able to reexport its ancestors private methods |
| 55 // as public, for use in tests. |
| 56 class TestSimpleIndexFile : public SimpleIndexFile { |
| 57 public: |
| 58 using SimpleIndexFile::Deserialize; |
| 59 using SimpleIndexFile::IsIndexFileStale; |
| 60 using SimpleIndexFile::kIndexFileName; |
| 61 using SimpleIndexFile::LoadFromDisk; |
| 62 using SimpleIndexFile::Serialize; |
| 63 |
| 64 explicit TestSimpleIndexFile(const base::FilePath& index_file_directory) |
| 65 : SimpleIndexFile(base::MessageLoopProxy::current(), |
| 66 base::MessageLoopProxy::current(), |
| 67 index_file_directory) { |
| 68 } |
| 69 virtual ~TestSimpleIndexFile() { |
| 70 } |
| 71 }; |
| 72 |
54 class SimpleIndexFileTest : public testing::Test { | 73 class SimpleIndexFileTest : public testing::Test { |
55 public: | 74 public: |
56 bool CompareTwoEntryMetadata(const EntryMetadata& a, const EntryMetadata& b) { | 75 bool CompareTwoEntryMetadata(const EntryMetadata& a, const EntryMetadata& b) { |
57 return a.last_used_time_ == b.last_used_time_ && | 76 return a.last_used_time_ == b.last_used_time_ && |
58 a.entry_size_ == b.entry_size_; | 77 a.entry_size_ == b.entry_size_; |
59 } | 78 } |
60 | 79 |
61 void IndexCompletionCallback( | |
62 scoped_ptr<SimpleIndex::EntrySet> index_file_entries, | |
63 bool force_index_flush) { | |
64 EXPECT_FALSE(callback_result_); | |
65 callback_result_.reset( | |
66 new IndexCompletionCallbackResult(index_file_entries.Pass(), | |
67 force_index_flush)); | |
68 } | |
69 | |
70 protected: | 80 protected: |
71 struct IndexCompletionCallbackResult { | 81 struct IndexCompletionCallbackResult { |
72 IndexCompletionCallbackResult( | 82 IndexCompletionCallbackResult( |
73 scoped_ptr<SimpleIndex::EntrySet> index_file_entries, | 83 scoped_ptr<SimpleIndex::EntrySet> index_file_entries, |
74 bool force_index_flush) | 84 bool force_index_flush) |
75 : index_file_entries(index_file_entries.Pass()), | 85 : index_file_entries(index_file_entries.Pass()), |
76 force_index_flush(force_index_flush) { | 86 force_index_flush(force_index_flush) { |
77 } | 87 } |
78 | 88 |
79 const scoped_ptr<SimpleIndex::EntrySet> index_file_entries; | 89 const scoped_ptr<SimpleIndex::EntrySet> index_file_entries; |
80 const bool force_index_flush; | 90 const bool force_index_flush; |
81 }; | 91 }; |
82 | 92 |
| 93 SimpleIndexFile::IndexCompletionCallback GetCallback() { |
| 94 return base::Bind(&SimpleIndexFileTest::IndexCompletionCallback, |
| 95 base::Unretained(this)); |
| 96 } |
| 97 |
83 IndexCompletionCallbackResult* callback_result() { | 98 IndexCompletionCallbackResult* callback_result() { |
84 return callback_result_.get(); | 99 return callback_result_.get(); |
85 } | 100 } |
86 | 101 |
87 private: | 102 private: |
| 103 void IndexCompletionCallback( |
| 104 scoped_ptr<SimpleIndex::EntrySet> index_file_entries, |
| 105 bool force_index_flush) { |
| 106 EXPECT_FALSE(callback_result_); |
| 107 callback_result_.reset( |
| 108 new IndexCompletionCallbackResult(index_file_entries.Pass(), |
| 109 force_index_flush)); |
| 110 } |
| 111 |
88 scoped_ptr<IndexCompletionCallbackResult> callback_result_; | 112 scoped_ptr<IndexCompletionCallbackResult> callback_result_; |
89 }; | 113 }; |
90 | 114 |
91 TEST_F(SimpleIndexFileTest, Serialize) { | 115 TEST_F(SimpleIndexFileTest, Serialize) { |
92 SimpleIndex::EntrySet entries; | 116 SimpleIndex::EntrySet entries; |
93 static const uint64 kHashes[] = { 11, 22, 33 }; | 117 static const uint64 kHashes[] = { 11, 22, 33 }; |
94 static const size_t kNumHashes = arraysize(kHashes); | 118 static const size_t kNumHashes = arraysize(kHashes); |
95 EntryMetadata metadata_entries[kNumHashes]; | 119 EntryMetadata metadata_entries[kNumHashes]; |
96 | 120 |
97 SimpleIndexFile::IndexMetadata index_metadata(static_cast<uint64>(kNumHashes), | 121 SimpleIndexFile::IndexMetadata index_metadata(static_cast<uint64>(kNumHashes), |
98 456); | 122 456); |
99 for (size_t i = 0; i < kNumHashes; ++i) { | 123 for (size_t i = 0; i < kNumHashes; ++i) { |
100 uint64 hash = kHashes[i]; | 124 uint64 hash = kHashes[i]; |
101 metadata_entries[i] = | 125 metadata_entries[i] = |
102 EntryMetadata(Time::FromInternalValue(hash), hash); | 126 EntryMetadata(Time::FromInternalValue(hash), hash); |
103 SimpleIndex::InsertInEntrySet(hash, metadata_entries[i], &entries); | 127 SimpleIndex::InsertInEntrySet(hash, metadata_entries[i], &entries); |
104 } | 128 } |
105 | 129 |
106 scoped_ptr<Pickle> pickle = SimpleIndexFile::Serialize( | 130 scoped_ptr<Pickle> pickle = TestSimpleIndexFile::Serialize( |
107 index_metadata, entries); | 131 index_metadata, entries); |
108 EXPECT_TRUE(pickle.get() != NULL); | 132 EXPECT_TRUE(pickle.get() != NULL); |
109 | 133 |
110 scoped_ptr<SimpleIndex::EntrySet> new_entries = SimpleIndexFile::Deserialize( | 134 scoped_ptr<SimpleIndex::EntrySet> new_entries = |
111 reinterpret_cast<const char*>(pickle->data()), | 135 TestSimpleIndexFile::Deserialize(static_cast<const char*>(pickle->data()), |
112 pickle->size()); | 136 pickle->size()); |
113 EXPECT_TRUE(new_entries.get() != NULL); | 137 EXPECT_TRUE(new_entries.get() != NULL); |
114 EXPECT_EQ(entries.size(), new_entries->size()); | 138 EXPECT_EQ(entries.size(), new_entries->size()); |
115 | 139 |
116 for (size_t i = 0; i < kNumHashes; ++i) { | 140 for (size_t i = 0; i < kNumHashes; ++i) { |
117 SimpleIndex::EntrySet::iterator it = new_entries->find(kHashes[i]); | 141 SimpleIndex::EntrySet::iterator it = new_entries->find(kHashes[i]); |
118 EXPECT_TRUE(new_entries->end() != it); | 142 EXPECT_TRUE(new_entries->end() != it); |
119 EXPECT_TRUE(CompareTwoEntryMetadata(it->second, metadata_entries[i])); | 143 EXPECT_TRUE(CompareTwoEntryMetadata(it->second, metadata_entries[i])); |
120 } | 144 } |
121 } | 145 } |
122 | 146 |
123 TEST_F(SimpleIndexFileTest, IsIndexFileStale) { | 147 TEST_F(SimpleIndexFileTest, IsIndexFileStale) { |
124 base::ScopedTempDir temp_dir; | 148 base::ScopedTempDir temp_dir; |
125 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | 149 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
126 | 150 |
127 const std::string kIndexFileName = "simple-index"; | 151 const std::string kIndexFileName = "simple-index"; |
128 const base::FilePath index_path = | 152 const base::FilePath index_path = |
129 temp_dir.path().AppendASCII(kIndexFileName); | 153 temp_dir.path().AppendASCII(kIndexFileName); |
130 EXPECT_TRUE(SimpleIndexFile::IsIndexFileStale(index_path)); | 154 EXPECT_TRUE(TestSimpleIndexFile::IsIndexFileStale(index_path)); |
131 const std::string kDummyData = "nothing to be seen here"; | 155 const std::string kDummyData = "nothing to be seen here"; |
132 EXPECT_EQ(static_cast<int>(kDummyData.size()), | 156 EXPECT_EQ(static_cast<int>(kDummyData.size()), |
133 file_util::WriteFile(index_path, | 157 file_util::WriteFile(index_path, |
134 kDummyData.data(), | 158 kDummyData.data(), |
135 kDummyData.size())); | 159 kDummyData.size())); |
136 EXPECT_FALSE(SimpleIndexFile::IsIndexFileStale(index_path)); | 160 EXPECT_FALSE(TestSimpleIndexFile::IsIndexFileStale(index_path)); |
137 | 161 |
138 const base::Time past_time = base::Time::Now() - | 162 const base::Time past_time = base::Time::Now() - |
139 base::TimeDelta::FromSeconds(10); | 163 base::TimeDelta::FromSeconds(10); |
140 EXPECT_TRUE(file_util::TouchFile(index_path, past_time, past_time)); | 164 EXPECT_TRUE(file_util::TouchFile(index_path, past_time, past_time)); |
141 EXPECT_TRUE(file_util::TouchFile(temp_dir.path(), past_time, past_time)); | 165 EXPECT_TRUE(file_util::TouchFile(temp_dir.path(), past_time, past_time)); |
142 EXPECT_FALSE(SimpleIndexFile::IsIndexFileStale(index_path)); | 166 EXPECT_FALSE(TestSimpleIndexFile::IsIndexFileStale(index_path)); |
143 | 167 |
144 EXPECT_EQ(static_cast<int>(kDummyData.size()), | 168 EXPECT_EQ(static_cast<int>(kDummyData.size()), |
145 file_util::WriteFile(temp_dir.path().AppendASCII("other_file"), | 169 file_util::WriteFile(temp_dir.path().AppendASCII("other_file"), |
146 kDummyData.data(), | 170 kDummyData.data(), |
147 kDummyData.size())); | 171 kDummyData.size())); |
148 | 172 |
149 EXPECT_TRUE(SimpleIndexFile::IsIndexFileStale(index_path)); | 173 EXPECT_TRUE(TestSimpleIndexFile::IsIndexFileStale(index_path)); |
150 } | 174 } |
151 | 175 |
152 TEST_F(SimpleIndexFileTest, IsIndexFileCorrupt) { | 176 TEST_F(SimpleIndexFileTest, WriteThenLoadIndex) { |
153 base::ScopedTempDir temp_dir; | 177 base::ScopedTempDir temp_dir; |
154 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); | 178 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
155 | 179 |
156 const base::FilePath index_path = | 180 const base::FilePath index_path = |
157 temp_dir.path().AppendASCII(SimpleIndexFile::kIndexFileName); | 181 temp_dir.path().AppendASCII(TestSimpleIndexFile::kIndexFileName); |
158 EXPECT_TRUE(SimpleIndexFile::IsIndexFileStale(index_path)); | 182 EXPECT_TRUE(TestSimpleIndexFile::IsIndexFileStale(index_path)); |
| 183 |
| 184 SimpleIndex::EntrySet entries; |
| 185 static const uint64 kHashes[] = { 11, 22, 33 }; |
| 186 static const size_t kNumHashes = arraysize(kHashes); |
| 187 EntryMetadata metadata_entries[kNumHashes]; |
| 188 for (size_t i = 0; i < kNumHashes; ++i) { |
| 189 uint64 hash = kHashes[i]; |
| 190 metadata_entries[i] = |
| 191 EntryMetadata(Time::FromInternalValue(hash), hash); |
| 192 SimpleIndex::InsertInEntrySet(hash, metadata_entries[i], &entries); |
| 193 } |
| 194 |
| 195 const uint64 kCacheSize = 456U; |
| 196 { |
| 197 TestSimpleIndexFile simple_index_file(temp_dir.path()); |
| 198 simple_index_file.WriteToDisk(entries, kCacheSize, |
| 199 base::TimeTicks(), false); |
| 200 base::RunLoop().RunUntilIdle(); |
| 201 EXPECT_TRUE(file_util::PathExists(index_path)); |
| 202 } |
| 203 |
| 204 TestSimpleIndexFile simple_index_file(temp_dir.path()); |
| 205 simple_index_file.LoadIndexEntries(base::MessageLoopProxy::current(), |
| 206 GetCallback()); |
| 207 base::RunLoop().RunUntilIdle(); |
| 208 |
| 209 EXPECT_TRUE(file_util::PathExists(index_path)); |
| 210 ASSERT_TRUE(callback_result()); |
| 211 EXPECT_FALSE(callback_result()->force_index_flush); |
| 212 const SimpleIndex::EntrySet* read_entries = |
| 213 callback_result()->index_file_entries.get(); |
| 214 ASSERT_TRUE(read_entries); |
| 215 |
| 216 EXPECT_EQ(kNumHashes, read_entries->size()); |
| 217 for (size_t i = 0; i < kNumHashes; ++i) |
| 218 EXPECT_EQ(1U, read_entries->count(kHashes[i])); |
| 219 } |
| 220 |
| 221 TEST_F(SimpleIndexFileTest, LoadCorruptIndex) { |
| 222 base::ScopedTempDir temp_dir; |
| 223 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); |
| 224 |
| 225 const base::FilePath index_path = |
| 226 temp_dir.path().AppendASCII(TestSimpleIndexFile::kIndexFileName); |
| 227 EXPECT_TRUE(TestSimpleIndexFile::IsIndexFileStale(index_path)); |
159 const std::string kDummyData = "nothing to be seen here"; | 228 const std::string kDummyData = "nothing to be seen here"; |
160 EXPECT_EQ(static_cast<int>(kDummyData.size()), | 229 EXPECT_EQ(static_cast<int>(kDummyData.size()), |
161 file_util::WriteFile(index_path, | 230 file_util::WriteFile(index_path, |
162 kDummyData.data(), | 231 kDummyData.data(), |
163 kDummyData.size())); | 232 kDummyData.size())); |
164 EXPECT_FALSE(SimpleIndexFile::IsIndexFileStale(index_path)); | 233 EXPECT_FALSE(TestSimpleIndexFile::IsIndexFileStale(index_path)); |
165 | 234 |
166 SimpleIndexFile simple_index_file(base::MessageLoopProxy::current(), | 235 TestSimpleIndexFile simple_index_file(temp_dir.path()); |
167 base::MessageLoopProxy::current(), | |
168 temp_dir.path()); | |
169 | |
170 SimpleIndexFile::IndexCompletionCallback callback = | |
171 base::Bind(&SimpleIndexFileTest::IndexCompletionCallback, | |
172 base::Unretained(this)); | |
173 | |
174 simple_index_file.LoadIndexEntries(base::MessageLoopProxy::current(), | 236 simple_index_file.LoadIndexEntries(base::MessageLoopProxy::current(), |
175 callback); | 237 GetCallback()); |
176 base::RunLoop().RunUntilIdle(); | 238 base::RunLoop().RunUntilIdle(); |
177 | 239 |
| 240 EXPECT_FALSE(file_util::PathExists(index_path)); |
178 ASSERT_TRUE(callback_result()); | 241 ASSERT_TRUE(callback_result()); |
| 242 EXPECT_TRUE(callback_result()->force_index_flush); |
179 EXPECT_TRUE(callback_result()->index_file_entries); | 243 EXPECT_TRUE(callback_result()->index_file_entries); |
180 EXPECT_TRUE(callback_result()->force_index_flush); | |
181 } | 244 } |
182 | 245 |
183 } // namespace disk_cache | 246 } // namespace disk_cache |
OLD | NEW |