OLD | NEW |
1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2009 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/basictypes.h" | 5 #include "base/basictypes.h" |
6 #include "base/platform_thread.h" | 6 #include "base/platform_thread.h" |
7 #include "base/timer.h" | 7 #include "base/timer.h" |
8 #include "base/string_util.h" | 8 #include "base/string_util.h" |
9 #include "net/base/io_buffer.h" | 9 #include "net/base/io_buffer.h" |
10 #include "net/base/net_errors.h" | 10 #include "net/base/net_errors.h" |
(...skipping 21 matching lines...) Expand all Loading... |
32 void TruncateData(); | 32 void TruncateData(); |
33 void ZeroLengthIO(); | 33 void ZeroLengthIO(); |
34 void ReuseEntry(int size); | 34 void ReuseEntry(int size); |
35 void InvalidData(); | 35 void InvalidData(); |
36 void DoomEntry(); | 36 void DoomEntry(); |
37 void DoomedEntry(); | 37 void DoomedEntry(); |
38 void BasicSparseIO(bool async); | 38 void BasicSparseIO(bool async); |
39 void HugeSparseIO(bool async); | 39 void HugeSparseIO(bool async); |
40 void GetAvailableRange(); | 40 void GetAvailableRange(); |
41 void DoomSparseEntry(); | 41 void DoomSparseEntry(); |
| 42 void PartialSparseEntry(); |
42 }; | 43 }; |
43 | 44 |
44 void DiskCacheEntryTest::InternalSyncIO() { | 45 void DiskCacheEntryTest::InternalSyncIO() { |
45 disk_cache::Entry *entry1 = NULL; | 46 disk_cache::Entry *entry1 = NULL; |
46 ASSERT_TRUE(cache_->CreateEntry("the first key", &entry1)); | 47 ASSERT_TRUE(cache_->CreateEntry("the first key", &entry1)); |
47 ASSERT_TRUE(NULL != entry1); | 48 ASSERT_TRUE(NULL != entry1); |
48 | 49 |
49 const int kSize1 = 10; | 50 const int kSize1 = 10; |
50 scoped_refptr<net::IOBuffer> buffer1 = new net::IOBuffer(kSize1); | 51 scoped_refptr<net::IOBuffer> buffer1 = new net::IOBuffer(kSize1); |
51 CacheTestFillBuffer(buffer1->data(), kSize1, false); | 52 CacheTestFillBuffer(buffer1->data(), kSize1, false); |
(...skipping 1126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1178 TEST_F(DiskCacheEntryTest, DoomSparseEntry) { | 1179 TEST_F(DiskCacheEntryTest, DoomSparseEntry) { |
1179 InitCache(); | 1180 InitCache(); |
1180 DoomSparseEntry(); | 1181 DoomSparseEntry(); |
1181 } | 1182 } |
1182 | 1183 |
1183 TEST_F(DiskCacheEntryTest, DISABLED_MemoryOnlyDoomSparseEntry) { | 1184 TEST_F(DiskCacheEntryTest, DISABLED_MemoryOnlyDoomSparseEntry) { |
1184 SetMemoryOnlyMode(); | 1185 SetMemoryOnlyMode(); |
1185 InitCache(); | 1186 InitCache(); |
1186 DoomSparseEntry(); | 1187 DoomSparseEntry(); |
1187 } | 1188 } |
| 1189 |
| 1190 void DiskCacheEntryTest::PartialSparseEntry() { |
| 1191 std::string key("the first key"); |
| 1192 disk_cache::Entry* entry; |
| 1193 ASSERT_TRUE(cache_->CreateEntry(key, &entry)); |
| 1194 |
| 1195 // We should be able to deal with IO that is not aligned to the block size |
| 1196 // of a sparse entry, at least to write a big range without leaving holes. |
| 1197 const int kSize = 4 * 1024; |
| 1198 scoped_refptr<net::IOBuffer> buf1 = new net::IOBuffer(kSize); |
| 1199 CacheTestFillBuffer(buf1->data(), kSize, false); |
| 1200 |
| 1201 // The first write is just to extend the entry. |
| 1202 EXPECT_EQ(kSize, entry->WriteSparseData(20000, buf1, kSize, NULL)); |
| 1203 EXPECT_EQ(kSize, entry->WriteSparseData(500, buf1, kSize, NULL)); |
| 1204 entry->Close(); |
| 1205 ASSERT_TRUE(cache_->OpenEntry(key, &entry)); |
| 1206 |
| 1207 scoped_refptr<net::IOBuffer> buf2 = new net::IOBuffer(kSize); |
| 1208 memset(buf2->data(), 0, kSize); |
| 1209 EXPECT_EQ(0, entry->ReadSparseData(8000, buf2, kSize, NULL)); |
| 1210 |
| 1211 EXPECT_EQ(500, entry->ReadSparseData(kSize, buf2, kSize, NULL)); |
| 1212 EXPECT_EQ(0, memcmp(buf2->data(), buf1->data() + kSize - 500, 500)); |
| 1213 EXPECT_EQ(0, entry->ReadSparseData(0, buf2, kSize, NULL)); |
| 1214 |
| 1215 // This read should not change anything. |
| 1216 EXPECT_EQ(96, entry->ReadSparseData(24000, buf2, kSize, NULL)); |
| 1217 EXPECT_EQ(500, entry->ReadSparseData(kSize, buf2, kSize, NULL)); |
| 1218 EXPECT_EQ(0, entry->ReadSparseData(499, buf2, kSize, NULL)); |
| 1219 |
| 1220 int64 start; |
| 1221 if (memory_only_) { |
| 1222 EXPECT_EQ(100, entry->GetAvailableRange(0, 600, &start)); |
| 1223 EXPECT_EQ(500, start); |
| 1224 } else { |
| 1225 EXPECT_EQ(1024, entry->GetAvailableRange(0, 2048, &start)); |
| 1226 EXPECT_EQ(1024, start); |
| 1227 } |
| 1228 EXPECT_EQ(500, entry->GetAvailableRange(kSize, kSize, &start)); |
| 1229 EXPECT_EQ(kSize, start); |
| 1230 EXPECT_EQ(3616, entry->GetAvailableRange(20 * 1024, 10000, &start)); |
| 1231 EXPECT_EQ(20 * 1024, start); |
| 1232 |
| 1233 // Now make another write and verify that there is no hole in between. |
| 1234 EXPECT_EQ(kSize, entry->WriteSparseData(500 + kSize, buf1, kSize, NULL)); |
| 1235 EXPECT_EQ(7 * 1024 + 500, entry->GetAvailableRange(1024, 10000, &start)); |
| 1236 EXPECT_EQ(1024, start); |
| 1237 EXPECT_EQ(kSize, entry->ReadSparseData(kSize, buf2, kSize, NULL)); |
| 1238 EXPECT_EQ(0, memcmp(buf2->data(), buf1->data() + kSize - 500, 500)); |
| 1239 EXPECT_EQ(0, memcmp(buf2->data() + 500, buf1->data(), kSize - 500)); |
| 1240 |
| 1241 entry->Close(); |
| 1242 } |
| 1243 |
| 1244 TEST_F(DiskCacheEntryTest, PartialSparseEntry) { |
| 1245 InitCache(); |
| 1246 PartialSparseEntry(); |
| 1247 } |
| 1248 |
| 1249 TEST_F(DiskCacheEntryTest, MemoryPartialSparseEntry) { |
| 1250 SetMemoryOnlyMode(); |
| 1251 InitCache(); |
| 1252 PartialSparseEntry(); |
| 1253 } |
| 1254 |
| 1255 TEST_F(DiskCacheEntryTest, CleanupSparseEntry) { |
| 1256 InitCache(); |
| 1257 std::string key("the first key"); |
| 1258 disk_cache::Entry* entry; |
| 1259 ASSERT_TRUE(cache_->CreateEntry(key, &entry)); |
| 1260 |
| 1261 // Corrupt sparse children should be removed automatically. |
| 1262 const int kSize = 4 * 1024; |
| 1263 scoped_refptr<net::IOBuffer> buf1 = new net::IOBuffer(kSize); |
| 1264 CacheTestFillBuffer(buf1->data(), kSize, false); |
| 1265 |
| 1266 const int k1Meg = 1024 * 1024; |
| 1267 EXPECT_EQ(kSize, entry->WriteSparseData(8192, buf1, kSize, NULL)); |
| 1268 EXPECT_EQ(kSize, entry->WriteSparseData(k1Meg + 8192, buf1, kSize, NULL)); |
| 1269 EXPECT_EQ(kSize, entry->WriteSparseData(2 * k1Meg + 8192, buf1, kSize, NULL)); |
| 1270 entry->Close(); |
| 1271 EXPECT_EQ(4, cache_->GetEntryCount()); |
| 1272 |
| 1273 void* iter = NULL; |
| 1274 int count = 0; |
| 1275 std::string child_key[2]; |
| 1276 while (cache_->OpenNextEntry(&iter, &entry)) { |
| 1277 ASSERT_TRUE(entry != NULL); |
| 1278 // Writing to an entry will alter the LRU list and invalidate the iterator. |
| 1279 if (entry->GetKey() != key && count < 2) |
| 1280 child_key[count++] = entry->GetKey(); |
| 1281 entry->Close(); |
| 1282 } |
| 1283 for (int i = 0; i < 2; i++) { |
| 1284 ASSERT_TRUE(cache_->OpenEntry(child_key[i], &entry)); |
| 1285 // Overwrite the header's magic and signature. |
| 1286 EXPECT_EQ(12, entry->WriteData(2, 0, buf1, 12, NULL, false)); |
| 1287 entry->Close(); |
| 1288 } |
| 1289 |
| 1290 EXPECT_EQ(4, cache_->GetEntryCount()); |
| 1291 ASSERT_TRUE(cache_->OpenEntry(key, &entry)); |
| 1292 |
| 1293 // Two children should be gone. One while reading and one while writing. |
| 1294 EXPECT_EQ(0, entry->ReadSparseData(2 * k1Meg + 8192, buf1, kSize, NULL)); |
| 1295 EXPECT_EQ(kSize, entry->WriteSparseData(k1Meg + 16384, buf1, kSize, NULL)); |
| 1296 EXPECT_EQ(0, entry->ReadSparseData(k1Meg + 8192, buf1, kSize, NULL)); |
| 1297 |
| 1298 // We never touched this one. |
| 1299 EXPECT_EQ(kSize, entry->ReadSparseData(8192, buf1, kSize, NULL)); |
| 1300 entry->Close(); |
| 1301 |
| 1302 // We re-created one of the corrupt children. |
| 1303 EXPECT_EQ(3, cache_->GetEntryCount()); |
| 1304 } |
OLD | NEW |