Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(59)

Side by Side Diff: net/disk_cache/simple/simple_index_file_unittest.cc

Issue 17265007: Unlink corrupt SimpleCache index files immediately after load. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rdsmith remediation Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698