1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "base/basictypes.h" 6 #include "base/bind.h" 7 #include "base/bind_helpers.h" 8 #include "base/file_util.h" 9 #include "base/strings/string_util.h" 10 #include "base/strings/stringprintf.h" 11 #include "base/threading/platform_thread.h" 12 #include "base/timer/timer.h" 13 #include "net/base/completion_callback.h" 14 #include "net/base/io_buffer.h" 15 #include "net/base/net_errors.h" 16 #include "net/base/test_completion_callback.h" 17 #include "net/disk_cache/backend_impl.h" 18 #include "net/disk_cache/disk_cache_test_base.h" 19 #include "net/disk_cache/disk_cache_test_util.h" 20 #include "net/disk_cache/entry_impl.h" 21 #include "net/disk_cache/mem_entry_impl.h" 22 #include "net/disk_cache/simple/simple_entry_format.h" 23 #include "net/disk_cache/simple/simple_entry_impl.h" 24 #include "net/disk_cache/simple/simple_synchronous_entry.h" 25 #include "net/disk_cache/simple/simple_test_util.h" 26 #include "net/disk_cache/simple/simple_util.h" 27 #include "testing/gtest/include/gtest/gtest.h" 28 29 using base::Time; 30 using disk_cache::ScopedEntryPtr; 31 32 // Tests that can run with different types of caches. 33 class DiskCacheEntryTest : public DiskCacheTestWithCache { 34 public: 35 void InternalSyncIOBackground(disk_cache::Entry* entry); 36 void ExternalSyncIOBackground(disk_cache::Entry* entry); 37 38 protected: 39 void InternalSyncIO(); 40 void InternalAsyncIO(); 41 void ExternalSyncIO(); 42 void ExternalAsyncIO(); 43 void ReleaseBuffer(); 44 void StreamAccess(); 45 void GetKey(); 46 void GetTimes(); 47 void GrowData(); 48 void TruncateData(); 49 void ZeroLengthIO(); 50 void Buffering(); 51 void SizeAtCreate(); 52 void SizeChanges(); 53 void ReuseEntry(int size); 54 void InvalidData(); 55 void ReadWriteDestroyBuffer(); 56 void DoomNormalEntry(); 57 void DoomEntryNextToOpenEntry(); 58 void DoomedEntry(); 59 void BasicSparseIO(); 60 void HugeSparseIO(); 61 void GetAvailableRange(); 62 void CouldBeSparse(); 63 void UpdateSparseEntry(); 64 void DoomSparseEntry(); 65 void PartialSparseEntry(); 66 bool SimpleCacheMakeBadChecksumEntry(const std::string& key, int* data_size); 67 bool SimpleCacheThirdStreamFileExists(const char* key); 68 void SyncDoomEntry(const char* key); 69 }; 70 71 // This part of the test runs on the background thread. 72 void DiskCacheEntryTest::InternalSyncIOBackground(disk_cache::Entry* entry) { 73 const int kSize1 = 10; 74 scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1)); 75 CacheTestFillBuffer(buffer1->data(), kSize1, false); 76 EXPECT_EQ( 77 0, 78 entry->ReadData(0, 0, buffer1.get(), kSize1, net::CompletionCallback())); 79 base::strlcpy(buffer1->data(), "the data", kSize1); 80 EXPECT_EQ(10, 81 entry->WriteData( 82 0, 0, buffer1.get(), kSize1, net::CompletionCallback(), false)); 83 memset(buffer1->data(), 0, kSize1); 84 EXPECT_EQ( 85 10, 86 entry->ReadData(0, 0, buffer1.get(), kSize1, net::CompletionCallback())); 87 EXPECT_STREQ("the data", buffer1->data()); 88 89 const int kSize2 = 5000; 90 const int kSize3 = 10000; 91 scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize2)); 92 scoped_refptr<net::IOBuffer> buffer3(new net::IOBuffer(kSize3)); 93 memset(buffer3->data(), 0, kSize3); 94 CacheTestFillBuffer(buffer2->data(), kSize2, false); 95 base::strlcpy(buffer2->data(), "The really big data goes here", kSize2); 96 EXPECT_EQ( 97 5000, 98 entry->WriteData( 99 1, 1500, buffer2.get(), kSize2, net::CompletionCallback(), false)); 100 memset(buffer2->data(), 0, kSize2); 101 EXPECT_EQ(4989, 102 entry->ReadData( 103 1, 1511, buffer2.get(), kSize2, net::CompletionCallback())); 104 EXPECT_STREQ("big data goes here", buffer2->data()); 105 EXPECT_EQ( 106 5000, 107 entry->ReadData(1, 0, buffer2.get(), kSize2, net::CompletionCallback())); 108 EXPECT_EQ(0, memcmp(buffer2->data(), buffer3->data(), 1500)); 109 EXPECT_EQ(1500, 110 entry->ReadData( 111 1, 5000, buffer2.get(), kSize2, net::CompletionCallback())); 112 113 EXPECT_EQ(0, 114 entry->ReadData( 115 1, 6500, buffer2.get(), kSize2, net::CompletionCallback())); 116 EXPECT_EQ( 117 6500, 118 entry->ReadData(1, 0, buffer3.get(), kSize3, net::CompletionCallback())); 119 EXPECT_EQ(8192, 120 entry->WriteData( 121 1, 0, buffer3.get(), 8192, net::CompletionCallback(), false)); 122 EXPECT_EQ( 123 8192, 124 entry->ReadData(1, 0, buffer3.get(), kSize3, net::CompletionCallback())); 125 EXPECT_EQ(8192, entry->GetDataSize(1)); 126 127 // We need to delete the memory buffer on this thread. 128 EXPECT_EQ(0, entry->WriteData( 129 0, 0, NULL, 0, net::CompletionCallback(), true)); 130 EXPECT_EQ(0, entry->WriteData( 131 1, 0, NULL, 0, net::CompletionCallback(), true)); 132 } 133 134 // We need to support synchronous IO even though it is not a supported operation 135 // from the point of view of the disk cache's public interface, because we use 136 // it internally, not just by a few tests, but as part of the implementation 137 // (see sparse_control.cc, for example). 138 void DiskCacheEntryTest::InternalSyncIO() { 139 disk_cache::Entry* entry = NULL; 140 ASSERT_EQ(net::OK, CreateEntry("the first key", &entry)); 141 ASSERT_TRUE(NULL != entry); 142 143 // The bulk of the test runs from within the callback, on the cache thread. 144 RunTaskForTest(base::Bind(&DiskCacheEntryTest::InternalSyncIOBackground, 145 base::Unretained(this), 146 entry)); 147 148 149 entry->Doom(); 150 entry->Close(); 151 FlushQueueForTest(); 152 EXPECT_EQ(0, cache_->GetEntryCount()); 153 } 154 155 TEST_F(DiskCacheEntryTest, InternalSyncIO) { 156 InitCache(); 157 InternalSyncIO(); 158 } 159 160 TEST_F(DiskCacheEntryTest, MemoryOnlyInternalSyncIO) { 161 SetMemoryOnlyMode(); 162 InitCache(); 163 InternalSyncIO(); 164 } 165 166 void DiskCacheEntryTest::InternalAsyncIO() { 167 disk_cache::Entry* entry = NULL; 168 ASSERT_EQ(net::OK, CreateEntry("the first key", &entry)); 169 ASSERT_TRUE(NULL != entry); 170 171 // Avoid using internal buffers for the test. We have to write something to 172 // the entry and close it so that we flush the internal buffer to disk. After 173 // that, IO operations will be really hitting the disk. We don't care about 174 // the content, so just extending the entry is enough (all extensions zero- 175 // fill any holes). 176 EXPECT_EQ(0, WriteData(entry, 0, 15 * 1024, NULL, 0, false)); 177 EXPECT_EQ(0, WriteData(entry, 1, 15 * 1024, NULL, 0, false)); 178 entry->Close(); 179 ASSERT_EQ(net::OK, OpenEntry("the first key", &entry)); 180 181 MessageLoopHelper helper; 182 // Let's verify that each IO goes to the right callback object. 183 CallbackTest callback1(&helper, false); 184 CallbackTest callback2(&helper, false); 185 CallbackTest callback3(&helper, false); 186 CallbackTest callback4(&helper, false); 187 CallbackTest callback5(&helper, false); 188 CallbackTest callback6(&helper, false); 189 CallbackTest callback7(&helper, false); 190 CallbackTest callback8(&helper, false); 191 CallbackTest callback9(&helper, false); 192 CallbackTest callback10(&helper, false); 193 CallbackTest callback11(&helper, false); 194 CallbackTest callback12(&helper, false); 195 CallbackTest callback13(&helper, false); 196 197 const int kSize1 = 10; 198 const int kSize2 = 5000; 199 const int kSize3 = 10000; 200 scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1)); 201 scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize2)); 202 scoped_refptr<net::IOBuffer> buffer3(new net::IOBuffer(kSize3)); 203 CacheTestFillBuffer(buffer1->data(), kSize1, false); 204 CacheTestFillBuffer(buffer2->data(), kSize2, false); 205 CacheTestFillBuffer(buffer3->data(), kSize3, false); 206 207 EXPECT_EQ(0, 208 entry->ReadData( 209 0, 210 15 * 1024, 211 buffer1.get(), 212 kSize1, 213 base::Bind(&CallbackTest::Run, base::Unretained(&callback1)))); 214 base::strlcpy(buffer1->data(), "the data", kSize1); 215 int expected = 0; 216 int ret = entry->WriteData( 217 0, 218 0, 219 buffer1.get(), 220 kSize1, 221 base::Bind(&CallbackTest::Run, base::Unretained(&callback2)), 222 false); 223 EXPECT_TRUE(10 == ret || net::ERR_IO_PENDING == ret); 224 if (net::ERR_IO_PENDING == ret) 225 expected++; 226 227 EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected)); 228 memset(buffer2->data(), 0, kSize2); 229 ret = entry->ReadData( 230 0, 231 0, 232 buffer2.get(), 233 kSize1, 234 base::Bind(&CallbackTest::Run, base::Unretained(&callback3))); 235 EXPECT_TRUE(10 == ret || net::ERR_IO_PENDING == ret); 236 if (net::ERR_IO_PENDING == ret) 237 expected++; 238 239 EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected)); 240 EXPECT_STREQ("the data", buffer2->data()); 241 242 base::strlcpy(buffer2->data(), "The really big data goes here", kSize2); 243 ret = entry->WriteData( 244 1, 245 1500, 246 buffer2.get(), 247 kSize2, 248 base::Bind(&CallbackTest::Run, base::Unretained(&callback4)), 249 true); 250 EXPECT_TRUE(5000 == ret || net::ERR_IO_PENDING == ret); 251 if (net::ERR_IO_PENDING == ret) 252 expected++; 253 254 EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected)); 255 memset(buffer3->data(), 0, kSize3); 256 ret = entry->ReadData( 257 1, 258 1511, 259 buffer3.get(), 260 kSize2, 261 base::Bind(&CallbackTest::Run, base::Unretained(&callback5))); 262 EXPECT_TRUE(4989 == ret || net::ERR_IO_PENDING == ret); 263 if (net::ERR_IO_PENDING == ret) 264 expected++; 265 266 EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected)); 267 EXPECT_STREQ("big data goes here", buffer3->data()); 268 ret = entry->ReadData( 269 1, 270 0, 271 buffer2.get(), 272 kSize2, 273 base::Bind(&CallbackTest::Run, base::Unretained(&callback6))); 274 EXPECT_TRUE(5000 == ret || net::ERR_IO_PENDING == ret); 275 if (net::ERR_IO_PENDING == ret) 276 expected++; 277 278 memset(buffer3->data(), 0, kSize3); 279 280 EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected)); 281 EXPECT_EQ(0, memcmp(buffer2->data(), buffer3->data(), 1500)); 282 ret = entry->ReadData( 283 1, 284 5000, 285 buffer2.get(), 286 kSize2, 287 base::Bind(&CallbackTest::Run, base::Unretained(&callback7))); 288 EXPECT_TRUE(1500 == ret || net::ERR_IO_PENDING == ret); 289 if (net::ERR_IO_PENDING == ret) 290 expected++; 291 292 ret = entry->ReadData( 293 1, 294 0, 295 buffer3.get(), 296 kSize3, 297 base::Bind(&CallbackTest::Run, base::Unretained(&callback9))); 298 EXPECT_TRUE(6500 == ret || net::ERR_IO_PENDING == ret); 299 if (net::ERR_IO_PENDING == ret) 300 expected++; 301 302 ret = entry->WriteData( 303 1, 304 0, 305 buffer3.get(), 306 8192, 307 base::Bind(&CallbackTest::Run, base::Unretained(&callback10)), 308 true); 309 EXPECT_TRUE(8192 == ret || net::ERR_IO_PENDING == ret); 310 if (net::ERR_IO_PENDING == ret) 311 expected++; 312 313 EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected)); 314 ret = entry->ReadData( 315 1, 316 0, 317 buffer3.get(), 318 kSize3, 319 base::Bind(&CallbackTest::Run, base::Unretained(&callback11))); 320 EXPECT_TRUE(8192 == ret || net::ERR_IO_PENDING == ret); 321 if (net::ERR_IO_PENDING == ret) 322 expected++; 323 324 EXPECT_EQ(8192, entry->GetDataSize(1)); 325 326 ret = entry->ReadData( 327 0, 328 0, 329 buffer1.get(), 330 kSize1, 331 base::Bind(&CallbackTest::Run, base::Unretained(&callback12))); 332 EXPECT_TRUE(10 == ret || net::ERR_IO_PENDING == ret); 333 if (net::ERR_IO_PENDING == ret) 334 expected++; 335 336 ret = entry->ReadData( 337 1, 338 0, 339 buffer2.get(), 340 kSize2, 341 base::Bind(&CallbackTest::Run, base::Unretained(&callback13))); 342 EXPECT_TRUE(5000 == ret || net::ERR_IO_PENDING == ret); 343 if (net::ERR_IO_PENDING == ret) 344 expected++; 345 346 EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected)); 347 348 EXPECT_FALSE(helper.callback_reused_error()); 349 350 entry->Doom(); 351 entry->Close(); 352 FlushQueueForTest(); 353 EXPECT_EQ(0, cache_->GetEntryCount()); 354 } 355 356 TEST_F(DiskCacheEntryTest, InternalAsyncIO) { 357 InitCache(); 358 InternalAsyncIO(); 359 } 360 361 TEST_F(DiskCacheEntryTest, MemoryOnlyInternalAsyncIO) { 362 SetMemoryOnlyMode(); 363 InitCache(); 364 InternalAsyncIO(); 365 } 366 367 // This part of the test runs on the background thread. 368 void DiskCacheEntryTest::ExternalSyncIOBackground(disk_cache::Entry* entry) { 369 const int kSize1 = 17000; 370 const int kSize2 = 25000; 371 scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1)); 372 scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize2)); 373 CacheTestFillBuffer(buffer1->data(), kSize1, false); 374 CacheTestFillBuffer(buffer2->data(), kSize2, false); 375 base::strlcpy(buffer1->data(), "the data", kSize1); 376 EXPECT_EQ(17000, 377 entry->WriteData( 378 0, 0, buffer1.get(), kSize1, net::CompletionCallback(), false)); 379 memset(buffer1->data(), 0, kSize1); 380 EXPECT_EQ( 381 17000, 382 entry->ReadData(0, 0, buffer1.get(), kSize1, net::CompletionCallback())); 383 EXPECT_STREQ("the data", buffer1->data()); 384 385 base::strlcpy(buffer2->data(), "The really big data goes here", kSize2); 386 EXPECT_EQ( 387 25000, 388 entry->WriteData( 389 1, 10000, buffer2.get(), kSize2, net::CompletionCallback(), false)); 390 memset(buffer2->data(), 0, kSize2); 391 EXPECT_EQ(24989, 392 entry->ReadData( 393 1, 10011, buffer2.get(), kSize2, net::CompletionCallback())); 394 EXPECT_STREQ("big data goes here", buffer2->data()); 395 EXPECT_EQ( 396 25000, 397 entry->ReadData(1, 0, buffer2.get(), kSize2, net::CompletionCallback())); 398 EXPECT_EQ(5000, 399 entry->ReadData( 400 1, 30000, buffer2.get(), kSize2, net::CompletionCallback())); 401 402 EXPECT_EQ(0, 403 entry->ReadData( 404 1, 35000, buffer2.get(), kSize2, net::CompletionCallback())); 405 EXPECT_EQ( 406 17000, 407 entry->ReadData(1, 0, buffer1.get(), kSize1, net::CompletionCallback())); 408 EXPECT_EQ( 409 17000, 410 entry->WriteData( 411 1, 20000, buffer1.get(), kSize1, net::CompletionCallback(), false)); 412 EXPECT_EQ(37000, entry->GetDataSize(1)); 413 414 // We need to delete the memory buffer on this thread. 415 EXPECT_EQ(0, entry->WriteData( 416 0, 0, NULL, 0, net::CompletionCallback(), true)); 417 EXPECT_EQ(0, entry->WriteData( 418 1, 0, NULL, 0, net::CompletionCallback(), true)); 419 } 420 421 void DiskCacheEntryTest::ExternalSyncIO() { 422 disk_cache::Entry* entry; 423 ASSERT_EQ(net::OK, CreateEntry("the first key", &entry)); 424 425 // The bulk of the test runs from within the callback, on the cache thread. 426 RunTaskForTest(base::Bind(&DiskCacheEntryTest::ExternalSyncIOBackground, 427 base::Unretained(this), 428 entry)); 429 430 entry->Doom(); 431 entry->Close(); 432 FlushQueueForTest(); 433 EXPECT_EQ(0, cache_->GetEntryCount()); 434 } 435 436 TEST_F(DiskCacheEntryTest, ExternalSyncIO) { 437 InitCache(); 438 ExternalSyncIO(); 439 } 440 441 TEST_F(DiskCacheEntryTest, ExternalSyncIONoBuffer) { 442 InitCache(); 443 cache_impl_->SetFlags(disk_cache::kNoBuffering); 444 ExternalSyncIO(); 445 } 446 447 TEST_F(DiskCacheEntryTest, MemoryOnlyExternalSyncIO) { 448 SetMemoryOnlyMode(); 449 InitCache(); 450 ExternalSyncIO(); 451 } 452 453 void DiskCacheEntryTest::ExternalAsyncIO() { 454 disk_cache::Entry* entry; 455 ASSERT_EQ(net::OK, CreateEntry("the first key", &entry)); 456 457 int expected = 0; 458 459 MessageLoopHelper helper; 460 // Let's verify that each IO goes to the right callback object. 461 CallbackTest callback1(&helper, false); 462 CallbackTest callback2(&helper, false); 463 CallbackTest callback3(&helper, false); 464 CallbackTest callback4(&helper, false); 465 CallbackTest callback5(&helper, false); 466 CallbackTest callback6(&helper, false); 467 CallbackTest callback7(&helper, false); 468 CallbackTest callback8(&helper, false); 469 CallbackTest callback9(&helper, false); 470 471 const int kSize1 = 17000; 472 const int kSize2 = 25000; 473 const int kSize3 = 25000; 474 scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1)); 475 scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize2)); 476 scoped_refptr<net::IOBuffer> buffer3(new net::IOBuffer(kSize3)); 477 CacheTestFillBuffer(buffer1->data(), kSize1, false); 478 CacheTestFillBuffer(buffer2->data(), kSize2, false); 479 CacheTestFillBuffer(buffer3->data(), kSize3, false); 480 base::strlcpy(buffer1->data(), "the data", kSize1); 481 int ret = entry->WriteData( 482 0, 483 0, 484 buffer1.get(), 485 kSize1, 486 base::Bind(&CallbackTest::Run, base::Unretained(&callback1)), 487 false); 488 EXPECT_TRUE(17000 == ret || net::ERR_IO_PENDING == ret); 489 if (net::ERR_IO_PENDING == ret) 490 expected++; 491 492 EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected)); 493 494 memset(buffer2->data(), 0, kSize1); 495 ret = entry->ReadData( 496 0, 497 0, 498 buffer2.get(), 499 kSize1, 500 base::Bind(&CallbackTest::Run, base::Unretained(&callback2))); 501 EXPECT_TRUE(17000 == ret || net::ERR_IO_PENDING == ret); 502 if (net::ERR_IO_PENDING == ret) 503 expected++; 504 505 EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected)); 506 EXPECT_STREQ("the data", buffer2->data()); 507 508 base::strlcpy(buffer2->data(), "The really big data goes here", kSize2); 509 ret = entry->WriteData( 510 1, 511 10000, 512 buffer2.get(), 513 kSize2, 514 base::Bind(&CallbackTest::Run, base::Unretained(&callback3)), 515 false); 516 EXPECT_TRUE(25000 == ret || net::ERR_IO_PENDING == ret); 517 if (net::ERR_IO_PENDING == ret) 518 expected++; 519 520 EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected)); 521 522 memset(buffer3->data(), 0, kSize3); 523 ret = entry->ReadData( 524 1, 525 10011, 526 buffer3.get(), 527 kSize3, 528 base::Bind(&CallbackTest::Run, base::Unretained(&callback4))); 529 EXPECT_TRUE(24989 == ret || net::ERR_IO_PENDING == ret); 530 if (net::ERR_IO_PENDING == ret) 531 expected++; 532 533 EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected)); 534 EXPECT_STREQ("big data goes here", buffer3->data()); 535 ret = entry->ReadData( 536 1, 537 0, 538 buffer2.get(), 539 kSize2, 540 base::Bind(&CallbackTest::Run, base::Unretained(&callback5))); 541 EXPECT_TRUE(25000 == ret || net::ERR_IO_PENDING == ret); 542 if (net::ERR_IO_PENDING == ret) 543 expected++; 544 545 EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected)); 546 memset(buffer3->data(), 0, kSize3); 547 EXPECT_EQ(0, memcmp(buffer2->data(), buffer3->data(), 10000)); 548 ret = entry->ReadData( 549 1, 550 30000, 551 buffer2.get(), 552 kSize2, 553 base::Bind(&CallbackTest::Run, base::Unretained(&callback6))); 554 EXPECT_TRUE(5000 == ret || net::ERR_IO_PENDING == ret); 555 if (net::ERR_IO_PENDING == ret) 556 expected++; 557 558 EXPECT_EQ(0, 559 entry->ReadData( 560 1, 561 35000, 562 buffer2.get(), 563 kSize2, 564 base::Bind(&CallbackTest::Run, base::Unretained(&callback7)))); 565 ret = entry->ReadData( 566 1, 567 0, 568 buffer1.get(), 569 kSize1, 570 base::Bind(&CallbackTest::Run, base::Unretained(&callback8))); 571 EXPECT_TRUE(17000 == ret || net::ERR_IO_PENDING == ret); 572 if (net::ERR_IO_PENDING == ret) 573 expected++; 574 ret = entry->WriteData( 575 1, 576 20000, 577 buffer3.get(), 578 kSize1, 579 base::Bind(&CallbackTest::Run, base::Unretained(&callback9)), 580 false); 581 EXPECT_TRUE(17000 == ret || net::ERR_IO_PENDING == ret); 582 if (net::ERR_IO_PENDING == ret) 583 expected++; 584 585 EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected)); 586 EXPECT_EQ(37000, entry->GetDataSize(1)); 587 588 EXPECT_FALSE(helper.callback_reused_error()); 589 590 entry->Doom(); 591 entry->Close(); 592 FlushQueueForTest(); 593 EXPECT_EQ(0, cache_->GetEntryCount()); 594 } 595 596 TEST_F(DiskCacheEntryTest, ExternalAsyncIO) { 597 InitCache(); 598 ExternalAsyncIO(); 599 } 600 601 TEST_F(DiskCacheEntryTest, ExternalAsyncIONoBuffer) { 602 InitCache(); 603 cache_impl_->SetFlags(disk_cache::kNoBuffering); 604 ExternalAsyncIO(); 605 } 606 607 TEST_F(DiskCacheEntryTest, MemoryOnlyExternalAsyncIO) { 608 SetMemoryOnlyMode(); 609 InitCache(); 610 ExternalAsyncIO(); 611 } 612 613 // Tests that IOBuffers are not referenced after IO completes. 614 void DiskCacheEntryTest::ReleaseBuffer() { 615 disk_cache::Entry* entry = NULL; 616 ASSERT_EQ(net::OK, CreateEntry("the first key", &entry)); 617 ASSERT_TRUE(NULL != entry); 618 619 const int kBufferSize = 1024; 620 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kBufferSize)); 621 CacheTestFillBuffer(buffer->data(), kBufferSize, false); 622 623 net::ReleaseBufferCompletionCallback cb(buffer.get()); 624 int rv = 625 entry->WriteData(0, 0, buffer.get(), kBufferSize, cb.callback(), false); 626 EXPECT_EQ(kBufferSize, cb.GetResult(rv)); 627 entry->Close(); 628 } 629 630 TEST_F(DiskCacheEntryTest, ReleaseBuffer) { 631 InitCache(); 632 cache_impl_->SetFlags(disk_cache::kNoBuffering); 633 ReleaseBuffer(); 634 } 635 636 TEST_F(DiskCacheEntryTest, MemoryOnlyReleaseBuffer) { 637 SetMemoryOnlyMode(); 638 InitCache(); 639 ReleaseBuffer(); 640 } 641 642 void DiskCacheEntryTest::StreamAccess() { 643 disk_cache::Entry* entry = NULL; 644 ASSERT_EQ(net::OK, CreateEntry("the first key", &entry)); 645 ASSERT_TRUE(NULL != entry); 646 647 const int kBufferSize = 1024; 648 const int kNumStreams = 3; 649 scoped_refptr<net::IOBuffer> reference_buffers[kNumStreams]; 650 for (int i = 0; i < kNumStreams; i++) { 651 reference_buffers[i] = new net::IOBuffer(kBufferSize); 652 CacheTestFillBuffer(reference_buffers[i]->data(), kBufferSize, false); 653 } 654 scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kBufferSize)); 655 for (int i = 0; i < kNumStreams; i++) { 656 EXPECT_EQ( 657 kBufferSize, 658 WriteData(entry, i, 0, reference_buffers[i].get(), kBufferSize, false)); 659 memset(buffer1->data(), 0, kBufferSize); 660 EXPECT_EQ(kBufferSize, ReadData(entry, i, 0, buffer1.get(), kBufferSize)); 661 EXPECT_EQ( 662 0, memcmp(reference_buffers[i]->data(), buffer1->data(), kBufferSize)); 663 } 664 EXPECT_EQ(net::ERR_INVALID_ARGUMENT, 665 ReadData(entry, kNumStreams, 0, buffer1.get(), kBufferSize)); 666 entry->Close(); 667 668 // Open the entry and read it in chunks, including a read past the end. 669 ASSERT_EQ(net::OK, OpenEntry("the first key", &entry)); 670 ASSERT_TRUE(NULL != entry); 671 const int kReadBufferSize = 600; 672 const int kFinalReadSize = kBufferSize - kReadBufferSize; 673 COMPILE_ASSERT(kFinalReadSize < kReadBufferSize, should_be_exactly_two_reads); 674 scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kReadBufferSize)); 675 for (int i = 0; i < kNumStreams; i++) { 676 memset(buffer2->data(), 0, kReadBufferSize); 677 EXPECT_EQ(kReadBufferSize, 678 ReadData(entry, i, 0, buffer2.get(), kReadBufferSize)); 679 EXPECT_EQ( 680 0, 681 memcmp(reference_buffers[i]->data(), buffer2->data(), kReadBufferSize)); 682 683 memset(buffer2->data(), 0, kReadBufferSize); 684 EXPECT_EQ( 685 kFinalReadSize, 686 ReadData(entry, i, kReadBufferSize, buffer2.get(), kReadBufferSize)); 687 EXPECT_EQ(0, 688 memcmp(reference_buffers[i]->data() + kReadBufferSize, 689 buffer2->data(), 690 kFinalReadSize)); 691 } 692 693 entry->Close(); 694 } 695 696 TEST_F(DiskCacheEntryTest, StreamAccess) { 697 InitCache(); 698 StreamAccess(); 699 } 700 701 TEST_F(DiskCacheEntryTest, MemoryOnlyStreamAccess) { 702 SetMemoryOnlyMode(); 703 InitCache(); 704 StreamAccess(); 705 } 706 707 void DiskCacheEntryTest::GetKey() { 708 std::string key("the first key"); 709 disk_cache::Entry* entry; 710 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 711 EXPECT_EQ(key, entry->GetKey()) << "short key"; 712 entry->Close(); 713 714 int seed = static_cast<int>(Time::Now().ToInternalValue()); 715 srand(seed); 716 char key_buffer[20000]; 717 718 CacheTestFillBuffer(key_buffer, 3000, true); 719 key_buffer[1000] = '\0'; 720 721 key = key_buffer; 722 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 723 EXPECT_TRUE(key == entry->GetKey()) << "1000 bytes key"; 724 entry->Close(); 725 726 key_buffer[1000] = 'p'; 727 key_buffer[3000] = '\0'; 728 key = key_buffer; 729 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 730 EXPECT_TRUE(key == entry->GetKey()) << "medium size key"; 731 entry->Close(); 732 733 CacheTestFillBuffer(key_buffer, sizeof(key_buffer), true); 734 key_buffer[19999] = '\0'; 735 736 key = key_buffer; 737 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 738 EXPECT_TRUE(key == entry->GetKey()) << "long key"; 739 entry->Close(); 740 741 CacheTestFillBuffer(key_buffer, 0x4000, true); 742 key_buffer[0x4000] = '\0'; 743 744 key = key_buffer; 745 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 746 EXPECT_TRUE(key == entry->GetKey()) << "16KB key"; 747 entry->Close(); 748 } 749 750 TEST_F(DiskCacheEntryTest, GetKey) { 751 InitCache(); 752 GetKey(); 753 } 754 755 TEST_F(DiskCacheEntryTest, MemoryOnlyGetKey) { 756 SetMemoryOnlyMode(); 757 InitCache(); 758 GetKey(); 759 } 760 761 void DiskCacheEntryTest::GetTimes() { 762 std::string key("the first key"); 763 disk_cache::Entry* entry; 764 765 Time t1 = Time::Now(); 766 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 767 EXPECT_TRUE(entry->GetLastModified() >= t1); 768 EXPECT_TRUE(entry->GetLastModified() == entry->GetLastUsed()); 769 770 AddDelay(); 771 Time t2 = Time::Now(); 772 EXPECT_TRUE(t2 > t1); 773 EXPECT_EQ(0, WriteData(entry, 0, 200, NULL, 0, false)); 774 if (type_ == net::APP_CACHE) { 775 EXPECT_TRUE(entry->GetLastModified() < t2); 776 } else { 777 EXPECT_TRUE(entry->GetLastModified() >= t2); 778 } 779 EXPECT_TRUE(entry->GetLastModified() == entry->GetLastUsed()); 780 781 AddDelay(); 782 Time t3 = Time::Now(); 783 EXPECT_TRUE(t3 > t2); 784 const int kSize = 200; 785 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize)); 786 EXPECT_EQ(kSize, ReadData(entry, 0, 0, buffer.get(), kSize)); 787 if (type_ == net::APP_CACHE) { 788 EXPECT_TRUE(entry->GetLastUsed() < t2); 789 EXPECT_TRUE(entry->GetLastModified() < t2); 790 } else if (type_ == net::SHADER_CACHE) { 791 EXPECT_TRUE(entry->GetLastUsed() < t3); 792 EXPECT_TRUE(entry->GetLastModified() < t3); 793 } else { 794 EXPECT_TRUE(entry->GetLastUsed() >= t3); 795 EXPECT_TRUE(entry->GetLastModified() < t3); 796 } 797 entry->Close(); 798 } 799 800 TEST_F(DiskCacheEntryTest, GetTimes) { 801 InitCache(); 802 GetTimes(); 803 } 804 805 TEST_F(DiskCacheEntryTest, MemoryOnlyGetTimes) { 806 SetMemoryOnlyMode(); 807 InitCache(); 808 GetTimes(); 809 } 810 811 TEST_F(DiskCacheEntryTest, AppCacheGetTimes) { 812 SetCacheType(net::APP_CACHE); 813 InitCache(); 814 GetTimes(); 815 } 816 817 TEST_F(DiskCacheEntryTest, ShaderCacheGetTimes) { 818 SetCacheType(net::SHADER_CACHE); 819 InitCache(); 820 GetTimes(); 821 } 822 823 void DiskCacheEntryTest::GrowData() { 824 std::string key1("the first key"); 825 disk_cache::Entry* entry; 826 ASSERT_EQ(net::OK, CreateEntry(key1, &entry)); 827 828 const int kSize = 20000; 829 scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize)); 830 scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize)); 831 CacheTestFillBuffer(buffer1->data(), kSize, false); 832 memset(buffer2->data(), 0, kSize); 833 834 base::strlcpy(buffer1->data(), "the data", kSize); 835 EXPECT_EQ(10, WriteData(entry, 0, 0, buffer1.get(), 10, false)); 836 EXPECT_EQ(10, ReadData(entry, 0, 0, buffer2.get(), 10)); 837 EXPECT_STREQ("the data", buffer2->data()); 838 EXPECT_EQ(10, entry->GetDataSize(0)); 839 840 EXPECT_EQ(2000, WriteData(entry, 0, 0, buffer1.get(), 2000, false)); 841 EXPECT_EQ(2000, entry->GetDataSize(0)); 842 EXPECT_EQ(2000, ReadData(entry, 0, 0, buffer2.get(), 2000)); 843 EXPECT_TRUE(!memcmp(buffer1->data(), buffer2->data(), 2000)); 844 845 EXPECT_EQ(20000, WriteData(entry, 0, 0, buffer1.get(), kSize, false)); 846 EXPECT_EQ(20000, entry->GetDataSize(0)); 847 EXPECT_EQ(20000, ReadData(entry, 0, 0, buffer2.get(), kSize)); 848 EXPECT_TRUE(!memcmp(buffer1->data(), buffer2->data(), kSize)); 849 entry->Close(); 850 851 memset(buffer2->data(), 0, kSize); 852 std::string key2("Second key"); 853 ASSERT_EQ(net::OK, CreateEntry(key2, &entry)); 854 EXPECT_EQ(10, WriteData(entry, 0, 0, buffer1.get(), 10, false)); 855 EXPECT_EQ(10, entry->GetDataSize(0)); 856 entry->Close(); 857 858 // Go from an internal address to a bigger block size. 859 ASSERT_EQ(net::OK, OpenEntry(key2, &entry)); 860 EXPECT_EQ(2000, WriteData(entry, 0, 0, buffer1.get(), 2000, false)); 861 EXPECT_EQ(2000, entry->GetDataSize(0)); 862 EXPECT_EQ(2000, ReadData(entry, 0, 0, buffer2.get(), 2000)); 863 EXPECT_TRUE(!memcmp(buffer1->data(), buffer2->data(), 2000)); 864 entry->Close(); 865 memset(buffer2->data(), 0, kSize); 866 867 // Go from an internal address to an external one. 868 ASSERT_EQ(net::OK, OpenEntry(key2, &entry)); 869 EXPECT_EQ(20000, WriteData(entry, 0, 0, buffer1.get(), kSize, false)); 870 EXPECT_EQ(20000, entry->GetDataSize(0)); 871 EXPECT_EQ(20000, ReadData(entry, 0, 0, buffer2.get(), kSize)); 872 EXPECT_TRUE(!memcmp(buffer1->data(), buffer2->data(), kSize)); 873 entry->Close(); 874 875 // Double check the size from disk. 876 ASSERT_EQ(net::OK, OpenEntry(key2, &entry)); 877 EXPECT_EQ(20000, entry->GetDataSize(0)); 878 879 // Now extend the entry without actual data. 880 EXPECT_EQ(0, WriteData(entry, 0, 45500, buffer1.get(), 0, false)); 881 entry->Close(); 882 883 // And check again from disk. 884 ASSERT_EQ(net::OK, OpenEntry(key2, &entry)); 885 EXPECT_EQ(45500, entry->GetDataSize(0)); 886 entry->Close(); 887 } 888 889 TEST_F(DiskCacheEntryTest, GrowData) { 890 InitCache(); 891 GrowData(); 892 } 893 894 TEST_F(DiskCacheEntryTest, GrowDataNoBuffer) { 895 InitCache(); 896 cache_impl_->SetFlags(disk_cache::kNoBuffering); 897 GrowData(); 898 } 899 900 TEST_F(DiskCacheEntryTest, MemoryOnlyGrowData) { 901 SetMemoryOnlyMode(); 902 InitCache(); 903 GrowData(); 904 } 905 906 void DiskCacheEntryTest::TruncateData() { 907 std::string key("the first key"); 908 disk_cache::Entry* entry; 909 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 910 911 const int kSize1 = 20000; 912 const int kSize2 = 20000; 913 scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1)); 914 scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize2)); 915 916 CacheTestFillBuffer(buffer1->data(), kSize1, false); 917 memset(buffer2->data(), 0, kSize2); 918 919 // Simple truncation: 920 EXPECT_EQ(200, WriteData(entry, 0, 0, buffer1.get(), 200, false)); 921 EXPECT_EQ(200, entry->GetDataSize(0)); 922 EXPECT_EQ(100, WriteData(entry, 0, 0, buffer1.get(), 100, false)); 923 EXPECT_EQ(200, entry->GetDataSize(0)); 924 EXPECT_EQ(100, WriteData(entry, 0, 0, buffer1.get(), 100, true)); 925 EXPECT_EQ(100, entry->GetDataSize(0)); 926 EXPECT_EQ(0, WriteData(entry, 0, 50, buffer1.get(), 0, true)); 927 EXPECT_EQ(50, entry->GetDataSize(0)); 928 EXPECT_EQ(0, WriteData(entry, 0, 0, buffer1.get(), 0, true)); 929 EXPECT_EQ(0, entry->GetDataSize(0)); 930 entry->Close(); 931 ASSERT_EQ(net::OK, OpenEntry(key, &entry)); 932 933 // Go to an external file. 934 EXPECT_EQ(20000, WriteData(entry, 0, 0, buffer1.get(), 20000, true)); 935 EXPECT_EQ(20000, entry->GetDataSize(0)); 936 EXPECT_EQ(20000, ReadData(entry, 0, 0, buffer2.get(), 20000)); 937 EXPECT_TRUE(!memcmp(buffer1->data(), buffer2->data(), 20000)); 938 memset(buffer2->data(), 0, kSize2); 939 940 // External file truncation 941 EXPECT_EQ(18000, WriteData(entry, 0, 0, buffer1.get(), 18000, false)); 942 EXPECT_EQ(20000, entry->GetDataSize(0)); 943 EXPECT_EQ(18000, WriteData(entry, 0, 0, buffer1.get(), 18000, true)); 944 EXPECT_EQ(18000, entry->GetDataSize(0)); 945 EXPECT_EQ(0, WriteData(entry, 0, 17500, buffer1.get(), 0, true)); 946 EXPECT_EQ(17500, entry->GetDataSize(0)); 947 948 // And back to an internal block. 949 EXPECT_EQ(600, WriteData(entry, 0, 1000, buffer1.get(), 600, true)); 950 EXPECT_EQ(1600, entry->GetDataSize(0)); 951 EXPECT_EQ(600, ReadData(entry, 0, 1000, buffer2.get(), 600)); 952 EXPECT_TRUE(!memcmp(buffer1->data(), buffer2->data(), 600)); 953 EXPECT_EQ(1000, ReadData(entry, 0, 0, buffer2.get(), 1000)); 954 EXPECT_TRUE(!memcmp(buffer1->data(), buffer2->data(), 1000)) 955 << "Preserves previous data"; 956 957 // Go from external file to zero length. 958 EXPECT_EQ(20000, WriteData(entry, 0, 0, buffer1.get(), 20000, true)); 959 EXPECT_EQ(20000, entry->GetDataSize(0)); 960 EXPECT_EQ(0, WriteData(entry, 0, 0, buffer1.get(), 0, true)); 961 EXPECT_EQ(0, entry->GetDataSize(0)); 962 963 entry->Close(); 964 } 965 966 TEST_F(DiskCacheEntryTest, TruncateData) { 967 InitCache(); 968 TruncateData(); 969 } 970 971 TEST_F(DiskCacheEntryTest, TruncateDataNoBuffer) { 972 InitCache(); 973 cache_impl_->SetFlags(disk_cache::kNoBuffering); 974 TruncateData(); 975 } 976 977 TEST_F(DiskCacheEntryTest, MemoryOnlyTruncateData) { 978 SetMemoryOnlyMode(); 979 InitCache(); 980 TruncateData(); 981 } 982 983 void DiskCacheEntryTest::ZeroLengthIO() { 984 std::string key("the first key"); 985 disk_cache::Entry* entry; 986 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 987 988 EXPECT_EQ(0, ReadData(entry, 0, 0, NULL, 0)); 989 EXPECT_EQ(0, WriteData(entry, 0, 0, NULL, 0, false)); 990 991 // This write should extend the entry. 992 EXPECT_EQ(0, WriteData(entry, 0, 1000, NULL, 0, false)); 993 EXPECT_EQ(0, ReadData(entry, 0, 500, NULL, 0)); 994 EXPECT_EQ(0, ReadData(entry, 0, 2000, NULL, 0)); 995 EXPECT_EQ(1000, entry->GetDataSize(0)); 996 997 EXPECT_EQ(0, WriteData(entry, 0, 100000, NULL, 0, true)); 998 EXPECT_EQ(0, ReadData(entry, 0, 50000, NULL, 0)); 999 EXPECT_EQ(100000, entry->GetDataSize(0)); 1000 1001 // Let's verify the actual content. 1002 const int kSize = 20; 1003 const char zeros[kSize] = {}; 1004 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize)); 1005 1006 CacheTestFillBuffer(buffer->data(), kSize, false); 1007 EXPECT_EQ(kSize, ReadData(entry, 0, 500, buffer.get(), kSize)); 1008 EXPECT_TRUE(!memcmp(buffer->data(), zeros, kSize)); 1009 1010 CacheTestFillBuffer(buffer->data(), kSize, false); 1011 EXPECT_EQ(kSize, ReadData(entry, 0, 5000, buffer.get(), kSize)); 1012 EXPECT_TRUE(!memcmp(buffer->data(), zeros, kSize)); 1013 1014 CacheTestFillBuffer(buffer->data(), kSize, false); 1015 EXPECT_EQ(kSize, ReadData(entry, 0, 50000, buffer.get(), kSize)); 1016 EXPECT_TRUE(!memcmp(buffer->data(), zeros, kSize)); 1017 1018 entry->Close(); 1019 } 1020 1021 TEST_F(DiskCacheEntryTest, ZeroLengthIO) { 1022 InitCache(); 1023 ZeroLengthIO(); 1024 } 1025 1026 TEST_F(DiskCacheEntryTest, ZeroLengthIONoBuffer) { 1027 InitCache(); 1028 cache_impl_->SetFlags(disk_cache::kNoBuffering); 1029 ZeroLengthIO(); 1030 } 1031 1032 TEST_F(DiskCacheEntryTest, MemoryOnlyZeroLengthIO) { 1033 SetMemoryOnlyMode(); 1034 InitCache(); 1035 ZeroLengthIO(); 1036 } 1037 1038 // Tests that we handle the content correctly when buffering, a feature of the 1039 // standard cache that permits fast responses to certain reads. 1040 void DiskCacheEntryTest::Buffering() { 1041 std::string key("the first key"); 1042 disk_cache::Entry* entry; 1043 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 1044 1045 const int kSize = 200; 1046 scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize)); 1047 scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize)); 1048 CacheTestFillBuffer(buffer1->data(), kSize, true); 1049 CacheTestFillBuffer(buffer2->data(), kSize, true); 1050 1051 EXPECT_EQ(kSize, WriteData(entry, 1, 0, buffer1.get(), kSize, false)); 1052 entry->Close(); 1053 1054 // Write a little more and read what we wrote before. 1055 ASSERT_EQ(net::OK, OpenEntry(key, &entry)); 1056 EXPECT_EQ(kSize, WriteData(entry, 1, 5000, buffer1.get(), kSize, false)); 1057 EXPECT_EQ(kSize, ReadData(entry, 1, 0, buffer2.get(), kSize)); 1058 EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data(), kSize)); 1059 1060 // Now go to an external file. 1061 EXPECT_EQ(kSize, WriteData(entry, 1, 18000, buffer1.get(), kSize, false)); 1062 entry->Close(); 1063 1064 // Write something else and verify old data. 1065 ASSERT_EQ(net::OK, OpenEntry(key, &entry)); 1066 EXPECT_EQ(kSize, WriteData(entry, 1, 10000, buffer1.get(), kSize, false)); 1067 CacheTestFillBuffer(buffer2->data(), kSize, true); 1068 EXPECT_EQ(kSize, ReadData(entry, 1, 5000, buffer2.get(), kSize)); 1069 EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data(), kSize)); 1070 CacheTestFillBuffer(buffer2->data(), kSize, true); 1071 EXPECT_EQ(kSize, ReadData(entry, 1, 0, buffer2.get(), kSize)); 1072 EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data(), kSize)); 1073 CacheTestFillBuffer(buffer2->data(), kSize, true); 1074 EXPECT_EQ(kSize, ReadData(entry, 1, 18000, buffer2.get(), kSize)); 1075 EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data(), kSize)); 1076 1077 // Extend the file some more. 1078 EXPECT_EQ(kSize, WriteData(entry, 1, 23000, buffer1.get(), kSize, false)); 1079 entry->Close(); 1080 1081 // And now make sure that we can deal with data in both places (ram/disk). 1082 ASSERT_EQ(net::OK, OpenEntry(key, &entry)); 1083 EXPECT_EQ(kSize, WriteData(entry, 1, 17000, buffer1.get(), kSize, false)); 1084 1085 // We should not overwrite the data at 18000 with this. 1086 EXPECT_EQ(kSize, WriteData(entry, 1, 19000, buffer1.get(), kSize, false)); 1087 CacheTestFillBuffer(buffer2->data(), kSize, true); 1088 EXPECT_EQ(kSize, ReadData(entry, 1, 18000, buffer2.get(), kSize)); 1089 EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data(), kSize)); 1090 CacheTestFillBuffer(buffer2->data(), kSize, true); 1091 EXPECT_EQ(kSize, ReadData(entry, 1, 17000, buffer2.get(), kSize)); 1092 EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data(), kSize)); 1093 1094 EXPECT_EQ(kSize, WriteData(entry, 1, 22900, buffer1.get(), kSize, false)); 1095 CacheTestFillBuffer(buffer2->data(), kSize, true); 1096 EXPECT_EQ(100, ReadData(entry, 1, 23000, buffer2.get(), kSize)); 1097 EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data() + 100, 100)); 1098 1099 CacheTestFillBuffer(buffer2->data(), kSize, true); 1100 EXPECT_EQ(100, ReadData(entry, 1, 23100, buffer2.get(), kSize)); 1101 EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data() + 100, 100)); 1102 1103 // Extend the file again and read before without closing the entry. 1104 EXPECT_EQ(kSize, WriteData(entry, 1, 25000, buffer1.get(), kSize, false)); 1105 EXPECT_EQ(kSize, WriteData(entry, 1, 45000, buffer1.get(), kSize, false)); 1106 CacheTestFillBuffer(buffer2->data(), kSize, true); 1107 EXPECT_EQ(kSize, ReadData(entry, 1, 25000, buffer2.get(), kSize)); 1108 EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data(), kSize)); 1109 CacheTestFillBuffer(buffer2->data(), kSize, true); 1110 EXPECT_EQ(kSize, ReadData(entry, 1, 45000, buffer2.get(), kSize)); 1111 EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data(), kSize)); 1112 1113 entry->Close(); 1114 } 1115 1116 TEST_F(DiskCacheEntryTest, Buffering) { 1117 InitCache(); 1118 Buffering(); 1119 } 1120 1121 TEST_F(DiskCacheEntryTest, BufferingNoBuffer) { 1122 InitCache(); 1123 cache_impl_->SetFlags(disk_cache::kNoBuffering); 1124 Buffering(); 1125 } 1126 1127 // Checks that entries are zero length when created. 1128 void DiskCacheEntryTest::SizeAtCreate() { 1129 const char key[] = "the first key"; 1130 disk_cache::Entry* entry; 1131 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 1132 1133 const int kNumStreams = 3; 1134 for (int i = 0; i < kNumStreams; ++i) 1135 EXPECT_EQ(0, entry->GetDataSize(i)); 1136 entry->Close(); 1137 } 1138 1139 TEST_F(DiskCacheEntryTest, SizeAtCreate) { 1140 InitCache(); 1141 SizeAtCreate(); 1142 } 1143 1144 TEST_F(DiskCacheEntryTest, MemoryOnlySizeAtCreate) { 1145 SetMemoryOnlyMode(); 1146 InitCache(); 1147 SizeAtCreate(); 1148 } 1149 1150 // Some extra tests to make sure that buffering works properly when changing 1151 // the entry size. 1152 void DiskCacheEntryTest::SizeChanges() { 1153 std::string key("the first key"); 1154 disk_cache::Entry* entry; 1155 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 1156 1157 const int kSize = 200; 1158 const char zeros[kSize] = {}; 1159 scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize)); 1160 scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize)); 1161 CacheTestFillBuffer(buffer1->data(), kSize, true); 1162 CacheTestFillBuffer(buffer2->data(), kSize, true); 1163 1164 EXPECT_EQ(kSize, WriteData(entry, 1, 0, buffer1.get(), kSize, true)); 1165 EXPECT_EQ(kSize, WriteData(entry, 1, 17000, buffer1.get(), kSize, true)); 1166 EXPECT_EQ(kSize, WriteData(entry, 1, 23000, buffer1.get(), kSize, true)); 1167 entry->Close(); 1168 1169 // Extend the file and read between the old size and the new write. 1170 ASSERT_EQ(net::OK, OpenEntry(key, &entry)); 1171 EXPECT_EQ(23000 + kSize, entry->GetDataSize(1)); 1172 EXPECT_EQ(kSize, WriteData(entry, 1, 25000, buffer1.get(), kSize, true)); 1173 EXPECT_EQ(25000 + kSize, entry->GetDataSize(1)); 1174 EXPECT_EQ(kSize, ReadData(entry, 1, 24000, buffer2.get(), kSize)); 1175 EXPECT_TRUE(!memcmp(buffer2->data(), zeros, kSize)); 1176 1177 // Read at the end of the old file size. 1178 EXPECT_EQ(kSize, 1179 ReadData(entry, 1, 23000 + kSize - 35, buffer2.get(), kSize)); 1180 EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data() + kSize - 35, 35)); 1181 1182 // Read slightly before the last write. 1183 CacheTestFillBuffer(buffer2->data(), kSize, true); 1184 EXPECT_EQ(kSize, ReadData(entry, 1, 24900, buffer2.get(), kSize)); 1185 EXPECT_TRUE(!memcmp(buffer2->data(), zeros, 100)); 1186 EXPECT_TRUE(!memcmp(buffer2->data() + 100, buffer1->data(), kSize - 100)); 1187 1188 // Extend the entry a little more. 1189 EXPECT_EQ(kSize, WriteData(entry, 1, 26000, buffer1.get(), kSize, true)); 1190 EXPECT_EQ(26000 + kSize, entry->GetDataSize(1)); 1191 CacheTestFillBuffer(buffer2->data(), kSize, true); 1192 EXPECT_EQ(kSize, ReadData(entry, 1, 25900, buffer2.get(), kSize)); 1193 EXPECT_TRUE(!memcmp(buffer2->data(), zeros, 100)); 1194 EXPECT_TRUE(!memcmp(buffer2->data() + 100, buffer1->data(), kSize - 100)); 1195 1196 // And now reduce the size. 1197 EXPECT_EQ(kSize, WriteData(entry, 1, 25000, buffer1.get(), kSize, true)); 1198 EXPECT_EQ(25000 + kSize, entry->GetDataSize(1)); 1199 EXPECT_EQ(28, ReadData(entry, 1, 25000 + kSize - 28, buffer2.get(), kSize)); 1200 EXPECT_TRUE(!memcmp(buffer2->data(), buffer1->data() + kSize - 28, 28)); 1201 1202 // Reduce the size with a buffer that is not extending the size. 1203 EXPECT_EQ(kSize, WriteData(entry, 1, 24000, buffer1.get(), kSize, false)); 1204 EXPECT_EQ(25000 + kSize, entry->GetDataSize(1)); 1205 EXPECT_EQ(kSize, WriteData(entry, 1, 24500, buffer1.get(), kSize, true)); 1206 EXPECT_EQ(24500 + kSize, entry->GetDataSize(1)); 1207 EXPECT_EQ(kSize, ReadData(entry, 1, 23900, buffer2.get(), kSize)); 1208 EXPECT_TRUE(!memcmp(buffer2->data(), zeros, 100)); 1209 EXPECT_TRUE(!memcmp(buffer2->data() + 100, buffer1->data(), kSize - 100)); 1210 1211 // And now reduce the size below the old size. 1212 EXPECT_EQ(kSize, WriteData(entry, 1, 19000, buffer1.get(), kSize, true)); 1213 EXPECT_EQ(19000 + kSize, entry->GetDataSize(1)); 1214 EXPECT_EQ(kSize, ReadData(entry, 1, 18900, buffer2.get(), kSize)); 1215 EXPECT_TRUE(!memcmp(buffer2->data(), zeros, 100)); 1216 EXPECT_TRUE(!memcmp(buffer2->data() + 100, buffer1->data(), kSize - 100)); 1217 1218 // Verify that the actual file is truncated. 1219 entry->Close(); 1220 ASSERT_EQ(net::OK, OpenEntry(key, &entry)); 1221 EXPECT_EQ(19000 + kSize, entry->GetDataSize(1)); 1222 1223 // Extend the newly opened file with a zero length write, expect zero fill. 1224 EXPECT_EQ(0, WriteData(entry, 1, 20000 + kSize, buffer1.get(), 0, false)); 1225 EXPECT_EQ(kSize, ReadData(entry, 1, 19000 + kSize, buffer1.get(), kSize)); 1226 EXPECT_EQ(0, memcmp(buffer1->data(), zeros, kSize)); 1227 1228 entry->Close(); 1229 } 1230 1231 TEST_F(DiskCacheEntryTest, SizeChanges) { 1232 InitCache(); 1233 SizeChanges(); 1234 } 1235 1236 TEST_F(DiskCacheEntryTest, SizeChangesNoBuffer) { 1237 InitCache(); 1238 cache_impl_->SetFlags(disk_cache::kNoBuffering); 1239 SizeChanges(); 1240 } 1241 1242 // Write more than the total cache capacity but to a single entry. |size| is the 1243 // amount of bytes to write each time. 1244 void DiskCacheEntryTest::ReuseEntry(int size) { 1245 std::string key1("the first key"); 1246 disk_cache::Entry* entry; 1247 ASSERT_EQ(net::OK, CreateEntry(key1, &entry)); 1248 1249 entry->Close(); 1250 std::string key2("the second key"); 1251 ASSERT_EQ(net::OK, CreateEntry(key2, &entry)); 1252 1253 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(size)); 1254 CacheTestFillBuffer(buffer->data(), size, false); 1255 1256 for (int i = 0; i < 15; i++) { 1257 EXPECT_EQ(0, WriteData(entry, 0, 0, buffer.get(), 0, true)); 1258 EXPECT_EQ(size, WriteData(entry, 0, 0, buffer.get(), size, false)); 1259 entry->Close(); 1260 ASSERT_EQ(net::OK, OpenEntry(key2, &entry)); 1261 } 1262 1263 entry->Close(); 1264 ASSERT_EQ(net::OK, OpenEntry(key1, &entry)) << "have not evicted this entry"; 1265 entry->Close(); 1266 } 1267 1268 TEST_F(DiskCacheEntryTest, ReuseExternalEntry) { 1269 SetMaxSize(200 * 1024); 1270 InitCache(); 1271 ReuseEntry(20 * 1024); 1272 } 1273 1274 TEST_F(DiskCacheEntryTest, MemoryOnlyReuseExternalEntry) { 1275 SetMemoryOnlyMode(); 1276 SetMaxSize(200 * 1024); 1277 InitCache(); 1278 ReuseEntry(20 * 1024); 1279 } 1280 1281 TEST_F(DiskCacheEntryTest, ReuseInternalEntry) { 1282 SetMaxSize(100 * 1024); 1283 InitCache(); 1284 ReuseEntry(10 * 1024); 1285 } 1286 1287 TEST_F(DiskCacheEntryTest, MemoryOnlyReuseInternalEntry) { 1288 SetMemoryOnlyMode(); 1289 SetMaxSize(100 * 1024); 1290 InitCache(); 1291 ReuseEntry(10 * 1024); 1292 } 1293 1294 // Reading somewhere that was not written should return zeros. 1295 void DiskCacheEntryTest::InvalidData() { 1296 std::string key("the first key"); 1297 disk_cache::Entry* entry; 1298 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 1299 1300 const int kSize1 = 20000; 1301 const int kSize2 = 20000; 1302 const int kSize3 = 20000; 1303 scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1)); 1304 scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize2)); 1305 scoped_refptr<net::IOBuffer> buffer3(new net::IOBuffer(kSize3)); 1306 1307 CacheTestFillBuffer(buffer1->data(), kSize1, false); 1308 memset(buffer2->data(), 0, kSize2); 1309 1310 // Simple data grow: 1311 EXPECT_EQ(200, WriteData(entry, 0, 400, buffer1.get(), 200, false)); 1312 EXPECT_EQ(600, entry->GetDataSize(0)); 1313 EXPECT_EQ(100, ReadData(entry, 0, 300, buffer3.get(), 100)); 1314 EXPECT_TRUE(!memcmp(buffer3->data(), buffer2->data(), 100)); 1315 entry->Close(); 1316 ASSERT_EQ(net::OK, OpenEntry(key, &entry)); 1317 1318 // The entry is now on disk. Load it and extend it. 1319 EXPECT_EQ(200, WriteData(entry, 0, 800, buffer1.get(), 200, false)); 1320 EXPECT_EQ(1000, entry->GetDataSize(0)); 1321 EXPECT_EQ(100, ReadData(entry, 0, 700, buffer3.get(), 100)); 1322 EXPECT_TRUE(!memcmp(buffer3->data(), buffer2->data(), 100)); 1323 entry->Close(); 1324 ASSERT_EQ(net::OK, OpenEntry(key, &entry)); 1325 1326 // This time using truncate. 1327 EXPECT_EQ(200, WriteData(entry, 0, 1800, buffer1.get(), 200, true)); 1328 EXPECT_EQ(2000, entry->GetDataSize(0)); 1329 EXPECT_EQ(100, ReadData(entry, 0, 1500, buffer3.get(), 100)); 1330 EXPECT_TRUE(!memcmp(buffer3->data(), buffer2->data(), 100)); 1331 1332 // Go to an external file. 1333 EXPECT_EQ(200, WriteData(entry, 0, 19800, buffer1.get(), 200, false)); 1334 EXPECT_EQ(20000, entry->GetDataSize(0)); 1335 EXPECT_EQ(4000, ReadData(entry, 0, 14000, buffer3.get(), 4000)); 1336 EXPECT_TRUE(!memcmp(buffer3->data(), buffer2->data(), 4000)); 1337 1338 // And back to an internal block. 1339 EXPECT_EQ(600, WriteData(entry, 0, 1000, buffer1.get(), 600, true)); 1340 EXPECT_EQ(1600, entry->GetDataSize(0)); 1341 EXPECT_EQ(600, ReadData(entry, 0, 1000, buffer3.get(), 600)); 1342 EXPECT_TRUE(!memcmp(buffer3->data(), buffer1->data(), 600)); 1343 1344 // Extend it again. 1345 EXPECT_EQ(600, WriteData(entry, 0, 2000, buffer1.get(), 600, false)); 1346 EXPECT_EQ(2600, entry->GetDataSize(0)); 1347 EXPECT_EQ(200, ReadData(entry, 0, 1800, buffer3.get(), 200)); 1348 EXPECT_TRUE(!memcmp(buffer3->data(), buffer2->data(), 200)); 1349 1350 // And again (with truncation flag). 1351 EXPECT_EQ(600, WriteData(entry, 0, 3000, buffer1.get(), 600, true)); 1352 EXPECT_EQ(3600, entry->GetDataSize(0)); 1353 EXPECT_EQ(200, ReadData(entry, 0, 2800, buffer3.get(), 200)); 1354 EXPECT_TRUE(!memcmp(buffer3->data(), buffer2->data(), 200)); 1355 1356 entry->Close(); 1357 } 1358 1359 TEST_F(DiskCacheEntryTest, InvalidData) { 1360 InitCache(); 1361 InvalidData(); 1362 } 1363 1364 TEST_F(DiskCacheEntryTest, InvalidDataNoBuffer) { 1365 InitCache(); 1366 cache_impl_->SetFlags(disk_cache::kNoBuffering); 1367 InvalidData(); 1368 } 1369 1370 TEST_F(DiskCacheEntryTest, MemoryOnlyInvalidData) { 1371 SetMemoryOnlyMode(); 1372 InitCache(); 1373 InvalidData(); 1374 } 1375 1376 // Tests that the cache preserves the buffer of an IO operation. 1377 void DiskCacheEntryTest::ReadWriteDestroyBuffer() { 1378 std::string key("the first key"); 1379 disk_cache::Entry* entry; 1380 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 1381 1382 const int kSize = 200; 1383 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize)); 1384 CacheTestFillBuffer(buffer->data(), kSize, false); 1385 1386 net::TestCompletionCallback cb; 1387 EXPECT_EQ(net::ERR_IO_PENDING, 1388 entry->WriteData(0, 0, buffer.get(), kSize, cb.callback(), false)); 1389 1390 // Release our reference to the buffer. 1391 buffer = NULL; 1392 EXPECT_EQ(kSize, cb.WaitForResult()); 1393 1394 // And now test with a Read(). 1395 buffer = new net::IOBuffer(kSize); 1396 CacheTestFillBuffer(buffer->data(), kSize, false); 1397 1398 EXPECT_EQ(net::ERR_IO_PENDING, 1399 entry->ReadData(0, 0, buffer.get(), kSize, cb.callback())); 1400 buffer = NULL; 1401 EXPECT_EQ(kSize, cb.WaitForResult()); 1402 1403 entry->Close(); 1404 } 1405 1406 TEST_F(DiskCacheEntryTest, ReadWriteDestroyBuffer) { 1407 InitCache(); 1408 ReadWriteDestroyBuffer(); 1409 } 1410 1411 void DiskCacheEntryTest::DoomNormalEntry() { 1412 std::string key("the first key"); 1413 disk_cache::Entry* entry; 1414 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 1415 entry->Doom(); 1416 entry->Close(); 1417 1418 const int kSize = 20000; 1419 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize)); 1420 CacheTestFillBuffer(buffer->data(), kSize, true); 1421 buffer->data()[19999] = '\0'; 1422 1423 key = buffer->data(); 1424 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 1425 EXPECT_EQ(20000, WriteData(entry, 0, 0, buffer.get(), kSize, false)); 1426 EXPECT_EQ(20000, WriteData(entry, 1, 0, buffer.get(), kSize, false)); 1427 entry->Doom(); 1428 entry->Close(); 1429 1430 FlushQueueForTest(); 1431 EXPECT_EQ(0, cache_->GetEntryCount()); 1432 } 1433 1434 TEST_F(DiskCacheEntryTest, DoomEntry) { 1435 InitCache(); 1436 DoomNormalEntry(); 1437 } 1438 1439 TEST_F(DiskCacheEntryTest, MemoryOnlyDoomEntry) { 1440 SetMemoryOnlyMode(); 1441 InitCache(); 1442 DoomNormalEntry(); 1443 } 1444 1445 // Tests dooming an entry that's linked to an open entry. 1446 void DiskCacheEntryTest::DoomEntryNextToOpenEntry() { 1447 disk_cache::Entry* entry1; 1448 disk_cache::Entry* entry2; 1449 ASSERT_EQ(net::OK, CreateEntry("fixed", &entry1)); 1450 entry1->Close(); 1451 ASSERT_EQ(net::OK, CreateEntry("foo", &entry1)); 1452 entry1->Close(); 1453 ASSERT_EQ(net::OK, CreateEntry("bar", &entry1)); 1454 entry1->Close(); 1455 1456 ASSERT_EQ(net::OK, OpenEntry("foo", &entry1)); 1457 ASSERT_EQ(net::OK, OpenEntry("bar", &entry2)); 1458 entry2->Doom(); 1459 entry2->Close(); 1460 1461 ASSERT_EQ(net::OK, OpenEntry("foo", &entry2)); 1462 entry2->Doom(); 1463 entry2->Close(); 1464 entry1->Close(); 1465 1466 ASSERT_EQ(net::OK, OpenEntry("fixed", &entry1)); 1467 entry1->Close(); 1468 } 1469 1470 TEST_F(DiskCacheEntryTest, DoomEntryNextToOpenEntry) { 1471 InitCache(); 1472 DoomEntryNextToOpenEntry(); 1473 } 1474 1475 TEST_F(DiskCacheEntryTest, NewEvictionDoomEntryNextToOpenEntry) { 1476 SetNewEviction(); 1477 InitCache(); 1478 DoomEntryNextToOpenEntry(); 1479 } 1480 1481 TEST_F(DiskCacheEntryTest, AppCacheDoomEntryNextToOpenEntry) { 1482 SetCacheType(net::APP_CACHE); 1483 InitCache(); 1484 DoomEntryNextToOpenEntry(); 1485 } 1486 1487 // Verify that basic operations work as expected with doomed entries. 1488 void DiskCacheEntryTest::DoomedEntry() { 1489 std::string key("the first key"); 1490 disk_cache::Entry* entry; 1491 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 1492 entry->Doom(); 1493 1494 FlushQueueForTest(); 1495 EXPECT_EQ(0, cache_->GetEntryCount()); 1496 Time initial = Time::Now(); 1497 AddDelay(); 1498 1499 const int kSize1 = 2000; 1500 const int kSize2 = 2000; 1501 scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1)); 1502 scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize2)); 1503 CacheTestFillBuffer(buffer1->data(), kSize1, false); 1504 memset(buffer2->data(), 0, kSize2); 1505 1506 EXPECT_EQ(2000, WriteData(entry, 0, 0, buffer1.get(), 2000, false)); 1507 EXPECT_EQ(2000, ReadData(entry, 0, 0, buffer2.get(), 2000)); 1508 EXPECT_EQ(0, memcmp(buffer1->data(), buffer2->data(), kSize1)); 1509 EXPECT_EQ(key, entry->GetKey()); 1510 EXPECT_TRUE(initial < entry->GetLastModified()); 1511 EXPECT_TRUE(initial < entry->GetLastUsed()); 1512 1513 entry->Close(); 1514 } 1515 1516 TEST_F(DiskCacheEntryTest, DoomedEntry) { 1517 InitCache(); 1518 DoomedEntry(); 1519 } 1520 1521 TEST_F(DiskCacheEntryTest, MemoryOnlyDoomedEntry) { 1522 SetMemoryOnlyMode(); 1523 InitCache(); 1524 DoomedEntry(); 1525 } 1526 1527 // Tests that we discard entries if the data is missing. 1528 TEST_F(DiskCacheEntryTest, MissingData) { 1529 InitCache(); 1530 1531 std::string key("the first key"); 1532 disk_cache::Entry* entry; 1533 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 1534 1535 // Write to an external file. 1536 const int kSize = 20000; 1537 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize)); 1538 CacheTestFillBuffer(buffer->data(), kSize, false); 1539 EXPECT_EQ(kSize, WriteData(entry, 0, 0, buffer.get(), kSize, false)); 1540 entry->Close(); 1541 FlushQueueForTest(); 1542 1543 disk_cache::Addr address(0x80000001); 1544 base::FilePath name = cache_impl_->GetFileName(address); 1545 EXPECT_TRUE(base::DeleteFile(name, false)); 1546 1547 // Attempt to read the data. 1548 ASSERT_EQ(net::OK, OpenEntry(key, &entry)); 1549 EXPECT_EQ(net::ERR_FILE_NOT_FOUND, 1550 ReadData(entry, 0, 0, buffer.get(), kSize)); 1551 entry->Close(); 1552 1553 // The entry should be gone. 1554 ASSERT_NE(net::OK, OpenEntry(key, &entry)); 1555 } 1556 1557 // Test that child entries in a memory cache backend are not visible from 1558 // enumerations. 1559 TEST_F(DiskCacheEntryTest, MemoryOnlyEnumerationWithSparseEntries) { 1560 SetMemoryOnlyMode(); 1561 InitCache(); 1562 1563 const int kSize = 4096; 1564 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize)); 1565 CacheTestFillBuffer(buf->data(), kSize, false); 1566 1567 std::string key("the first key"); 1568 disk_cache::Entry* parent_entry; 1569 ASSERT_EQ(net::OK, CreateEntry(key, &parent_entry)); 1570 1571 // Writes to the parent entry. 1572 EXPECT_EQ(kSize, 1573 parent_entry->WriteSparseData( 1574 0, buf.get(), kSize, net::CompletionCallback())); 1575 1576 // This write creates a child entry and writes to it. 1577 EXPECT_EQ(kSize, 1578 parent_entry->WriteSparseData( 1579 8192, buf.get(), kSize, net::CompletionCallback())); 1580 1581 parent_entry->Close(); 1582 1583 // Perform the enumerations. 1584 void* iter = NULL; 1585 disk_cache::Entry* entry = NULL; 1586 int count = 0; 1587 while (OpenNextEntry(&iter, &entry) == net::OK) { 1588 ASSERT_TRUE(entry != NULL); 1589 ++count; 1590 disk_cache::MemEntryImpl* mem_entry = 1591 reinterpret_cast<disk_cache::MemEntryImpl*>(entry); 1592 EXPECT_EQ(disk_cache::MemEntryImpl::kParentEntry, mem_entry->type()); 1593 mem_entry->Close(); 1594 } 1595 EXPECT_EQ(1, count); 1596 } 1597 1598 // Writes |buf_1| to offset and reads it back as |buf_2|. 1599 void VerifySparseIO(disk_cache::Entry* entry, int64 offset, 1600 net::IOBuffer* buf_1, int size, net::IOBuffer* buf_2) { 1601 net::TestCompletionCallback cb; 1602 1603 memset(buf_2->data(), 0, size); 1604 int ret = entry->ReadSparseData(offset, buf_2, size, cb.callback()); 1605 EXPECT_EQ(0, cb.GetResult(ret)); 1606 1607 ret = entry->WriteSparseData(offset, buf_1, size, cb.callback()); 1608 EXPECT_EQ(size, cb.GetResult(ret)); 1609 1610 ret = entry->ReadSparseData(offset, buf_2, size, cb.callback()); 1611 EXPECT_EQ(size, cb.GetResult(ret)); 1612 1613 EXPECT_EQ(0, memcmp(buf_1->data(), buf_2->data(), size)); 1614 } 1615 1616 // Reads |size| bytes from |entry| at |offset| and verifies that they are the 1617 // same as the content of the provided |buffer|. 1618 void VerifyContentSparseIO(disk_cache::Entry* entry, int64 offset, char* buffer, 1619 int size) { 1620 net::TestCompletionCallback cb; 1621 1622 scoped_refptr<net::IOBuffer> buf_1(new net::IOBuffer(size)); 1623 memset(buf_1->data(), 0, size); 1624 int ret = entry->ReadSparseData(offset, buf_1.get(), size, cb.callback()); 1625 EXPECT_EQ(size, cb.GetResult(ret)); 1626 EXPECT_EQ(0, memcmp(buf_1->data(), buffer, size)); 1627 } 1628 1629 void DiskCacheEntryTest::BasicSparseIO() { 1630 std::string key("the first key"); 1631 disk_cache::Entry* entry; 1632 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 1633 1634 const int kSize = 2048; 1635 scoped_refptr<net::IOBuffer> buf_1(new net::IOBuffer(kSize)); 1636 scoped_refptr<net::IOBuffer> buf_2(new net::IOBuffer(kSize)); 1637 CacheTestFillBuffer(buf_1->data(), kSize, false); 1638 1639 // Write at offset 0. 1640 VerifySparseIO(entry, 0, buf_1.get(), kSize, buf_2.get()); 1641 1642 // Write at offset 0x400000 (4 MB). 1643 VerifySparseIO(entry, 0x400000, buf_1.get(), kSize, buf_2.get()); 1644 1645 // Write at offset 0x800000000 (32 GB). 1646 VerifySparseIO(entry, 0x800000000LL, buf_1.get(), kSize, buf_2.get()); 1647 1648 entry->Close(); 1649 1650 // Check everything again. 1651 ASSERT_EQ(net::OK, OpenEntry(key, &entry)); 1652 VerifyContentSparseIO(entry, 0, buf_1->data(), kSize); 1653 VerifyContentSparseIO(entry, 0x400000, buf_1->data(), kSize); 1654 VerifyContentSparseIO(entry, 0x800000000LL, buf_1->data(), kSize); 1655 entry->Close(); 1656 } 1657 1658 TEST_F(DiskCacheEntryTest, BasicSparseIO) { 1659 InitCache(); 1660 BasicSparseIO(); 1661 } 1662 1663 TEST_F(DiskCacheEntryTest, MemoryOnlyBasicSparseIO) { 1664 SetMemoryOnlyMode(); 1665 InitCache(); 1666 BasicSparseIO(); 1667 } 1668 1669 void DiskCacheEntryTest::HugeSparseIO() { 1670 std::string key("the first key"); 1671 disk_cache::Entry* entry; 1672 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 1673 1674 // Write 1.2 MB so that we cover multiple entries. 1675 const int kSize = 1200 * 1024; 1676 scoped_refptr<net::IOBuffer> buf_1(new net::IOBuffer(kSize)); 1677 scoped_refptr<net::IOBuffer> buf_2(new net::IOBuffer(kSize)); 1678 CacheTestFillBuffer(buf_1->data(), kSize, false); 1679 1680 // Write at offset 0x20F0000 (33 MB - 64 KB). 1681 VerifySparseIO(entry, 0x20F0000, buf_1.get(), kSize, buf_2.get()); 1682 entry->Close(); 1683 1684 // Check it again. 1685 ASSERT_EQ(net::OK, OpenEntry(key, &entry)); 1686 VerifyContentSparseIO(entry, 0x20F0000, buf_1->data(), kSize); 1687 entry->Close(); 1688 } 1689 1690 TEST_F(DiskCacheEntryTest, HugeSparseIO) { 1691 InitCache(); 1692 HugeSparseIO(); 1693 } 1694 1695 TEST_F(DiskCacheEntryTest, MemoryOnlyHugeSparseIO) { 1696 SetMemoryOnlyMode(); 1697 InitCache(); 1698 HugeSparseIO(); 1699 } 1700 1701 void DiskCacheEntryTest::GetAvailableRange() { 1702 std::string key("the first key"); 1703 disk_cache::Entry* entry; 1704 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 1705 1706 const int kSize = 16 * 1024; 1707 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize)); 1708 CacheTestFillBuffer(buf->data(), kSize, false); 1709 1710 // Write at offset 0x20F0000 (33 MB - 64 KB), and 0x20F4400 (33 MB - 47 KB). 1711 EXPECT_EQ(kSize, WriteSparseData(entry, 0x20F0000, buf.get(), kSize)); 1712 EXPECT_EQ(kSize, WriteSparseData(entry, 0x20F4400, buf.get(), kSize)); 1713 1714 // We stop at the first empty block. 1715 int64 start; 1716 net::TestCompletionCallback cb; 1717 int rv = entry->GetAvailableRange( 1718 0x20F0000, kSize * 2, &start, cb.callback()); 1719 EXPECT_EQ(kSize, cb.GetResult(rv)); 1720 EXPECT_EQ(0x20F0000, start); 1721 1722 start = 0; 1723 rv = entry->GetAvailableRange(0, kSize, &start, cb.callback()); 1724 EXPECT_EQ(0, cb.GetResult(rv)); 1725 rv = entry->GetAvailableRange( 1726 0x20F0000 - kSize, kSize, &start, cb.callback()); 1727 EXPECT_EQ(0, cb.GetResult(rv)); 1728 rv = entry->GetAvailableRange(0, 0x2100000, &start, cb.callback()); 1729 EXPECT_EQ(kSize, cb.GetResult(rv)); 1730 EXPECT_EQ(0x20F0000, start); 1731 1732 // We should be able to Read based on the results of GetAvailableRange. 1733 start = -1; 1734 rv = entry->GetAvailableRange(0x2100000, kSize, &start, cb.callback()); 1735 EXPECT_EQ(0, cb.GetResult(rv)); 1736 rv = entry->ReadSparseData(start, buf.get(), kSize, cb.callback()); 1737 EXPECT_EQ(0, cb.GetResult(rv)); 1738 1739 start = 0; 1740 rv = entry->GetAvailableRange(0x20F2000, kSize, &start, cb.callback()); 1741 EXPECT_EQ(0x2000, cb.GetResult(rv)); 1742 EXPECT_EQ(0x20F2000, start); 1743 EXPECT_EQ(0x2000, ReadSparseData(entry, start, buf.get(), kSize)); 1744 1745 // Make sure that we respect the |len| argument. 1746 start = 0; 1747 rv = entry->GetAvailableRange( 1748 0x20F0001 - kSize, kSize, &start, cb.callback()); 1749 EXPECT_EQ(1, cb.GetResult(rv)); 1750 EXPECT_EQ(0x20F0000, start); 1751 1752 entry->Close(); 1753 } 1754 1755 TEST_F(DiskCacheEntryTest, GetAvailableRange) { 1756 InitCache(); 1757 GetAvailableRange(); 1758 } 1759 1760 TEST_F(DiskCacheEntryTest, MemoryOnlyGetAvailableRange) { 1761 SetMemoryOnlyMode(); 1762 InitCache(); 1763 GetAvailableRange(); 1764 } 1765 1766 void DiskCacheEntryTest::CouldBeSparse() { 1767 std::string key("the first key"); 1768 disk_cache::Entry* entry; 1769 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 1770 1771 const int kSize = 16 * 1024; 1772 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize)); 1773 CacheTestFillBuffer(buf->data(), kSize, false); 1774 1775 // Write at offset 0x20F0000 (33 MB - 64 KB). 1776 EXPECT_EQ(kSize, WriteSparseData(entry, 0x20F0000, buf.get(), kSize)); 1777 1778 EXPECT_TRUE(entry->CouldBeSparse()); 1779 entry->Close(); 1780 1781 ASSERT_EQ(net::OK, OpenEntry(key, &entry)); 1782 EXPECT_TRUE(entry->CouldBeSparse()); 1783 entry->Close(); 1784 1785 // Now verify a regular entry. 1786 key.assign("another key"); 1787 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 1788 EXPECT_FALSE(entry->CouldBeSparse()); 1789 1790 EXPECT_EQ(kSize, WriteData(entry, 0, 0, buf.get(), kSize, false)); 1791 EXPECT_EQ(kSize, WriteData(entry, 1, 0, buf.get(), kSize, false)); 1792 EXPECT_EQ(kSize, WriteData(entry, 2, 0, buf.get(), kSize, false)); 1793 1794 EXPECT_FALSE(entry->CouldBeSparse()); 1795 entry->Close(); 1796 1797 ASSERT_EQ(net::OK, OpenEntry(key, &entry)); 1798 EXPECT_FALSE(entry->CouldBeSparse()); 1799 entry->Close(); 1800 } 1801 1802 TEST_F(DiskCacheEntryTest, CouldBeSparse) { 1803 InitCache(); 1804 CouldBeSparse(); 1805 } 1806 1807 TEST_F(DiskCacheEntryTest, MemoryCouldBeSparse) { 1808 SetMemoryOnlyMode(); 1809 InitCache(); 1810 CouldBeSparse(); 1811 } 1812 1813 TEST_F(DiskCacheEntryTest, MemoryOnlyMisalignedSparseIO) { 1814 SetMemoryOnlyMode(); 1815 InitCache(); 1816 1817 const int kSize = 8192; 1818 scoped_refptr<net::IOBuffer> buf_1(new net::IOBuffer(kSize)); 1819 scoped_refptr<net::IOBuffer> buf_2(new net::IOBuffer(kSize)); 1820 CacheTestFillBuffer(buf_1->data(), kSize, false); 1821 1822 std::string key("the first key"); 1823 disk_cache::Entry* entry; 1824 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 1825 1826 // This loop writes back to back starting from offset 0 and 9000. 1827 for (int i = 0; i < kSize; i += 1024) { 1828 scoped_refptr<net::WrappedIOBuffer> buf_3( 1829 new net::WrappedIOBuffer(buf_1->data() + i)); 1830 VerifySparseIO(entry, i, buf_3.get(), 1024, buf_2.get()); 1831 VerifySparseIO(entry, 9000 + i, buf_3.get(), 1024, buf_2.get()); 1832 } 1833 1834 // Make sure we have data written. 1835 VerifyContentSparseIO(entry, 0, buf_1->data(), kSize); 1836 VerifyContentSparseIO(entry, 9000, buf_1->data(), kSize); 1837 1838 // This tests a large write that spans 3 entries from a misaligned offset. 1839 VerifySparseIO(entry, 20481, buf_1.get(), 8192, buf_2.get()); 1840 1841 entry->Close(); 1842 } 1843 1844 TEST_F(DiskCacheEntryTest, MemoryOnlyMisalignedGetAvailableRange) { 1845 SetMemoryOnlyMode(); 1846 InitCache(); 1847 1848 const int kSize = 8192; 1849 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize)); 1850 CacheTestFillBuffer(buf->data(), kSize, false); 1851 1852 disk_cache::Entry* entry; 1853 std::string key("the first key"); 1854 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 1855 1856 // Writes in the middle of an entry. 1857 EXPECT_EQ( 1858 1024, 1859 entry->WriteSparseData(0, buf.get(), 1024, net::CompletionCallback())); 1860 EXPECT_EQ( 1861 1024, 1862 entry->WriteSparseData(5120, buf.get(), 1024, net::CompletionCallback())); 1863 EXPECT_EQ(1024, 1864 entry->WriteSparseData( 1865 10000, buf.get(), 1024, net::CompletionCallback())); 1866 1867 // Writes in the middle of an entry and spans 2 child entries. 1868 EXPECT_EQ(8192, 1869 entry->WriteSparseData( 1870 50000, buf.get(), 8192, net::CompletionCallback())); 1871 1872 int64 start; 1873 net::TestCompletionCallback cb; 1874 // Test that we stop at a discontinuous child at the second block. 1875 int rv = entry->GetAvailableRange(0, 10000, &start, cb.callback()); 1876 EXPECT_EQ(1024, cb.GetResult(rv)); 1877 EXPECT_EQ(0, start); 1878 1879 // Test that number of bytes is reported correctly when we start from the 1880 // middle of a filled region. 1881 rv = entry->GetAvailableRange(512, 10000, &start, cb.callback()); 1882 EXPECT_EQ(512, cb.GetResult(rv)); 1883 EXPECT_EQ(512, start); 1884 1885 // Test that we found bytes in the child of next block. 1886 rv = entry->GetAvailableRange(1024, 10000, &start, cb.callback()); 1887 EXPECT_EQ(1024, cb.GetResult(rv)); 1888 EXPECT_EQ(5120, start); 1889 1890 // Test that the desired length is respected. It starts within a filled 1891 // region. 1892 rv = entry->GetAvailableRange(5500, 512, &start, cb.callback()); 1893 EXPECT_EQ(512, cb.GetResult(rv)); 1894 EXPECT_EQ(5500, start); 1895 1896 // Test that the desired length is respected. It starts before a filled 1897 // region. 1898 rv = entry->GetAvailableRange(5000, 620, &start, cb.callback()); 1899 EXPECT_EQ(500, cb.GetResult(rv)); 1900 EXPECT_EQ(5120, start); 1901 1902 // Test that multiple blocks are scanned. 1903 rv = entry->GetAvailableRange(40000, 20000, &start, cb.callback()); 1904 EXPECT_EQ(8192, cb.GetResult(rv)); 1905 EXPECT_EQ(50000, start); 1906 1907 entry->Close(); 1908 } 1909 1910 void DiskCacheEntryTest::UpdateSparseEntry() { 1911 std::string key("the first key"); 1912 disk_cache::Entry* entry1; 1913 ASSERT_EQ(net::OK, CreateEntry(key, &entry1)); 1914 1915 const int kSize = 2048; 1916 scoped_refptr<net::IOBuffer> buf_1(new net::IOBuffer(kSize)); 1917 scoped_refptr<net::IOBuffer> buf_2(new net::IOBuffer(kSize)); 1918 CacheTestFillBuffer(buf_1->data(), kSize, false); 1919 1920 // Write at offset 0. 1921 VerifySparseIO(entry1, 0, buf_1.get(), kSize, buf_2.get()); 1922 entry1->Close(); 1923 1924 // Write at offset 2048. 1925 ASSERT_EQ(net::OK, OpenEntry(key, &entry1)); 1926 VerifySparseIO(entry1, 2048, buf_1.get(), kSize, buf_2.get()); 1927 1928 disk_cache::Entry* entry2; 1929 ASSERT_EQ(net::OK, CreateEntry("the second key", &entry2)); 1930 1931 entry1->Close(); 1932 entry2->Close(); 1933 FlushQueueForTest(); 1934 if (memory_only_ || simple_cache_mode_) 1935 EXPECT_EQ(2, cache_->GetEntryCount()); 1936 else 1937 EXPECT_EQ(3, cache_->GetEntryCount()); 1938 } 1939 1940 TEST_F(DiskCacheEntryTest, UpdateSparseEntry) { 1941 SetCacheType(net::MEDIA_CACHE); 1942 InitCache(); 1943 UpdateSparseEntry(); 1944 } 1945 1946 TEST_F(DiskCacheEntryTest, MemoryOnlyUpdateSparseEntry) { 1947 SetMemoryOnlyMode(); 1948 SetCacheType(net::MEDIA_CACHE); 1949 InitCache(); 1950 UpdateSparseEntry(); 1951 } 1952 1953 void DiskCacheEntryTest::DoomSparseEntry() { 1954 std::string key1("the first key"); 1955 std::string key2("the second key"); 1956 disk_cache::Entry *entry1, *entry2; 1957 ASSERT_EQ(net::OK, CreateEntry(key1, &entry1)); 1958 ASSERT_EQ(net::OK, CreateEntry(key2, &entry2)); 1959 1960 const int kSize = 4 * 1024; 1961 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize)); 1962 CacheTestFillBuffer(buf->data(), kSize, false); 1963 1964 int64 offset = 1024; 1965 // Write to a bunch of ranges. 1966 for (int i = 0; i < 12; i++) { 1967 EXPECT_EQ(kSize, WriteSparseData(entry1, offset, buf.get(), kSize)); 1968 // Keep the second map under the default size. 1969 if (i < 9) 1970 EXPECT_EQ(kSize, WriteSparseData(entry2, offset, buf.get(), kSize)); 1971 1972 offset *= 4; 1973 } 1974 1975 if (memory_only_ || simple_cache_mode_) 1976 EXPECT_EQ(2, cache_->GetEntryCount()); 1977 else 1978 EXPECT_EQ(15, cache_->GetEntryCount()); 1979 1980 // Doom the first entry while it's still open. 1981 entry1->Doom(); 1982 entry1->Close(); 1983 entry2->Close(); 1984 1985 // Doom the second entry after it's fully saved. 1986 EXPECT_EQ(net::OK, DoomEntry(key2)); 1987 1988 // Make sure we do all needed work. This may fail for entry2 if between Close 1989 // and DoomEntry the system decides to remove all traces of the file from the 1990 // system cache so we don't see that there is pending IO. 1991 base::MessageLoop::current()->RunUntilIdle(); 1992 1993 if (memory_only_) { 1994 EXPECT_EQ(0, cache_->GetEntryCount()); 1995 } else { 1996 if (5 == cache_->GetEntryCount()) { 1997 // Most likely we are waiting for the result of reading the sparse info 1998 // (it's always async on Posix so it is easy to miss). Unfortunately we 1999 // don't have any signal to watch for so we can only wait. 2000 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(500)); 2001 base::MessageLoop::current()->RunUntilIdle(); 2002 } 2003 EXPECT_EQ(0, cache_->GetEntryCount()); 2004 } 2005 } 2006 2007 TEST_F(DiskCacheEntryTest, DoomSparseEntry) { 2008 UseCurrentThread(); 2009 InitCache(); 2010 DoomSparseEntry(); 2011 } 2012 2013 TEST_F(DiskCacheEntryTest, MemoryOnlyDoomSparseEntry) { 2014 SetMemoryOnlyMode(); 2015 InitCache(); 2016 DoomSparseEntry(); 2017 } 2018 2019 // A CompletionCallback wrapper that deletes the cache from within the callback. 2020 // The way a CompletionCallback works means that all tasks (even new ones) 2021 // are executed by the message loop before returning to the caller so the only 2022 // way to simulate a race is to execute what we want on the callback. 2023 class SparseTestCompletionCallback: public net::TestCompletionCallback { 2024 public: 2025 explicit SparseTestCompletionCallback(scoped_ptr<disk_cache::Backend> cache) 2026 : cache_(cache.Pass()) { 2027 } 2028 2029 private: 2030 virtual void SetResult(int result) OVERRIDE { 2031 cache_.reset(); 2032 TestCompletionCallback::SetResult(result); 2033 } 2034 2035 scoped_ptr<disk_cache::Backend> cache_; 2036 DISALLOW_COPY_AND_ASSIGN(SparseTestCompletionCallback); 2037 }; 2038 2039 // Tests that we don't crash when the backend is deleted while we are working 2040 // deleting the sub-entries of a sparse entry. 2041 TEST_F(DiskCacheEntryTest, DoomSparseEntry2) { 2042 UseCurrentThread(); 2043 InitCache(); 2044 std::string key("the key"); 2045 disk_cache::Entry* entry; 2046 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 2047 2048 const int kSize = 4 * 1024; 2049 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize)); 2050 CacheTestFillBuffer(buf->data(), kSize, false); 2051 2052 int64 offset = 1024; 2053 // Write to a bunch of ranges. 2054 for (int i = 0; i < 12; i++) { 2055 EXPECT_EQ(kSize, 2056 entry->WriteSparseData( 2057 offset, buf.get(), kSize, net::CompletionCallback())); 2058 offset *= 4; 2059 } 2060 EXPECT_EQ(9, cache_->GetEntryCount()); 2061 2062 entry->Close(); 2063 disk_cache::Backend* cache = cache_.get(); 2064 SparseTestCompletionCallback cb(cache_.Pass()); 2065 int rv = cache->DoomEntry(key, cb.callback()); 2066 EXPECT_EQ(net::ERR_IO_PENDING, rv); 2067 EXPECT_EQ(net::OK, cb.WaitForResult()); 2068 } 2069 2070 void DiskCacheEntryTest::PartialSparseEntry() { 2071 std::string key("the first key"); 2072 disk_cache::Entry* entry; 2073 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 2074 2075 // We should be able to deal with IO that is not aligned to the block size 2076 // of a sparse entry, at least to write a big range without leaving holes. 2077 const int kSize = 4 * 1024; 2078 const int kSmallSize = 128; 2079 scoped_refptr<net::IOBuffer> buf1(new net::IOBuffer(kSize)); 2080 CacheTestFillBuffer(buf1->data(), kSize, false); 2081 2082 // The first write is just to extend the entry. The third write occupies 2083 // a 1KB block partially, it may not be written internally depending on the 2084 // implementation. 2085 EXPECT_EQ(kSize, WriteSparseData(entry, 20000, buf1.get(), kSize)); 2086 EXPECT_EQ(kSize, WriteSparseData(entry, 500, buf1.get(), kSize)); 2087 EXPECT_EQ(kSmallSize, 2088 WriteSparseData(entry, 1080321, buf1.get(), kSmallSize)); 2089 entry->Close(); 2090 ASSERT_EQ(net::OK, OpenEntry(key, &entry)); 2091 2092 scoped_refptr<net::IOBuffer> buf2(new net::IOBuffer(kSize)); 2093 memset(buf2->data(), 0, kSize); 2094 EXPECT_EQ(0, ReadSparseData(entry, 8000, buf2.get(), kSize)); 2095 2096 EXPECT_EQ(500, ReadSparseData(entry, kSize, buf2.get(), kSize)); 2097 EXPECT_EQ(0, memcmp(buf2->data(), buf1->data() + kSize - 500, 500)); 2098 EXPECT_EQ(0, ReadSparseData(entry, 0, buf2.get(), kSize)); 2099 2100 // This read should not change anything. 2101 EXPECT_EQ(96, ReadSparseData(entry, 24000, buf2.get(), kSize)); 2102 EXPECT_EQ(500, ReadSparseData(entry, kSize, buf2.get(), kSize)); 2103 EXPECT_EQ(0, ReadSparseData(entry, 99, buf2.get(), kSize)); 2104 2105 int rv; 2106 int64 start; 2107 net::TestCompletionCallback cb; 2108 if (memory_only_ || simple_cache_mode_) { 2109 rv = entry->GetAvailableRange(0, 600, &start, cb.callback()); 2110 EXPECT_EQ(100, cb.GetResult(rv)); 2111 EXPECT_EQ(500, start); 2112 } else { 2113 rv = entry->GetAvailableRange(0, 2048, &start, cb.callback()); 2114 EXPECT_EQ(1024, cb.GetResult(rv)); 2115 EXPECT_EQ(1024, start); 2116 } 2117 rv = entry->GetAvailableRange(kSize, kSize, &start, cb.callback()); 2118 EXPECT_EQ(500, cb.GetResult(rv)); 2119 EXPECT_EQ(kSize, start); 2120 rv = entry->GetAvailableRange(20 * 1024, 10000, &start, cb.callback()); 2121 EXPECT_EQ(3616, cb.GetResult(rv)); 2122 EXPECT_EQ(20 * 1024, start); 2123 2124 // 1. Query before a filled 1KB block. 2125 // 2. Query within a filled 1KB block. 2126 // 3. Query beyond a filled 1KB block. 2127 if (memory_only_ || simple_cache_mode_) { 2128 rv = entry->GetAvailableRange(19400, kSize, &start, cb.callback()); 2129 EXPECT_EQ(3496, cb.GetResult(rv)); 2130 EXPECT_EQ(20000, start); 2131 } else { 2132 rv = entry->GetAvailableRange(19400, kSize, &start, cb.callback()); 2133 EXPECT_EQ(3016, cb.GetResult(rv)); 2134 EXPECT_EQ(20480, start); 2135 } 2136 rv = entry->GetAvailableRange(3073, kSize, &start, cb.callback()); 2137 EXPECT_EQ(1523, cb.GetResult(rv)); 2138 EXPECT_EQ(3073, start); 2139 rv = entry->GetAvailableRange(4600, kSize, &start, cb.callback()); 2140 EXPECT_EQ(0, cb.GetResult(rv)); 2141 EXPECT_EQ(4600, start); 2142 2143 // Now make another write and verify that there is no hole in between. 2144 EXPECT_EQ(kSize, WriteSparseData(entry, 500 + kSize, buf1.get(), kSize)); 2145 rv = entry->GetAvailableRange(1024, 10000, &start, cb.callback()); 2146 EXPECT_EQ(7 * 1024 + 500, cb.GetResult(rv)); 2147 EXPECT_EQ(1024, start); 2148 EXPECT_EQ(kSize, ReadSparseData(entry, kSize, buf2.get(), kSize)); 2149 EXPECT_EQ(0, memcmp(buf2->data(), buf1->data() + kSize - 500, 500)); 2150 EXPECT_EQ(0, memcmp(buf2->data() + 500, buf1->data(), kSize - 500)); 2151 2152 entry->Close(); 2153 } 2154 2155 TEST_F(DiskCacheEntryTest, PartialSparseEntry) { 2156 InitCache(); 2157 PartialSparseEntry(); 2158 } 2159 2160 TEST_F(DiskCacheEntryTest, MemoryPartialSparseEntry) { 2161 SetMemoryOnlyMode(); 2162 InitCache(); 2163 PartialSparseEntry(); 2164 } 2165 2166 // Tests that corrupt sparse children are removed automatically. 2167 TEST_F(DiskCacheEntryTest, CleanupSparseEntry) { 2168 InitCache(); 2169 std::string key("the first key"); 2170 disk_cache::Entry* entry; 2171 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 2172 2173 const int kSize = 4 * 1024; 2174 scoped_refptr<net::IOBuffer> buf1(new net::IOBuffer(kSize)); 2175 CacheTestFillBuffer(buf1->data(), kSize, false); 2176 2177 const int k1Meg = 1024 * 1024; 2178 EXPECT_EQ(kSize, WriteSparseData(entry, 8192, buf1.get(), kSize)); 2179 EXPECT_EQ(kSize, WriteSparseData(entry, k1Meg + 8192, buf1.get(), kSize)); 2180 EXPECT_EQ(kSize, WriteSparseData(entry, 2 * k1Meg + 8192, buf1.get(), kSize)); 2181 entry->Close(); 2182 EXPECT_EQ(4, cache_->GetEntryCount()); 2183 2184 void* iter = NULL; 2185 int count = 0; 2186 std::string child_key[2]; 2187 while (OpenNextEntry(&iter, &entry) == net::OK) { 2188 ASSERT_TRUE(entry != NULL); 2189 // Writing to an entry will alter the LRU list and invalidate the iterator. 2190 if (entry->GetKey() != key && count < 2) 2191 child_key[count++] = entry->GetKey(); 2192 entry->Close(); 2193 } 2194 for (int i = 0; i < 2; i++) { 2195 ASSERT_EQ(net::OK, OpenEntry(child_key[i], &entry)); 2196 // Overwrite the header's magic and signature. 2197 EXPECT_EQ(12, WriteData(entry, 2, 0, buf1.get(), 12, false)); 2198 entry->Close(); 2199 } 2200 2201 EXPECT_EQ(4, cache_->GetEntryCount()); 2202 ASSERT_EQ(net::OK, OpenEntry(key, &entry)); 2203 2204 // Two children should be gone. One while reading and one while writing. 2205 EXPECT_EQ(0, ReadSparseData(entry, 2 * k1Meg + 8192, buf1.get(), kSize)); 2206 EXPECT_EQ(kSize, WriteSparseData(entry, k1Meg + 16384, buf1.get(), kSize)); 2207 EXPECT_EQ(0, ReadSparseData(entry, k1Meg + 8192, buf1.get(), kSize)); 2208 2209 // We never touched this one. 2210 EXPECT_EQ(kSize, ReadSparseData(entry, 8192, buf1.get(), kSize)); 2211 entry->Close(); 2212 2213 // We re-created one of the corrupt children. 2214 EXPECT_EQ(3, cache_->GetEntryCount()); 2215 } 2216 2217 TEST_F(DiskCacheEntryTest, CancelSparseIO) { 2218 UseCurrentThread(); 2219 InitCache(); 2220 std::string key("the first key"); 2221 disk_cache::Entry* entry; 2222 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 2223 2224 const int kSize = 40 * 1024; 2225 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kSize)); 2226 CacheTestFillBuffer(buf->data(), kSize, false); 2227 2228 // This will open and write two "real" entries. 2229 net::TestCompletionCallback cb1, cb2, cb3, cb4, cb5; 2230 int rv = entry->WriteSparseData( 2231 1024 * 1024 - 4096, buf.get(), kSize, cb1.callback()); 2232 EXPECT_EQ(net::ERR_IO_PENDING, rv); 2233 2234 int64 offset = 0; 2235 rv = entry->GetAvailableRange(offset, kSize, &offset, cb5.callback()); 2236 rv = cb5.GetResult(rv); 2237 if (!cb1.have_result()) { 2238 // We may or may not have finished writing to the entry. If we have not, 2239 // we cannot start another operation at this time. 2240 EXPECT_EQ(net::ERR_CACHE_OPERATION_NOT_SUPPORTED, rv); 2241 } 2242 2243 // We cancel the pending operation, and register multiple notifications. 2244 entry->CancelSparseIO(); 2245 EXPECT_EQ(net::ERR_IO_PENDING, entry->ReadyForSparseIO(cb2.callback())); 2246 EXPECT_EQ(net::ERR_IO_PENDING, entry->ReadyForSparseIO(cb3.callback())); 2247 entry->CancelSparseIO(); // Should be a no op at this point. 2248 EXPECT_EQ(net::ERR_IO_PENDING, entry->ReadyForSparseIO(cb4.callback())); 2249 2250 if (!cb1.have_result()) { 2251 EXPECT_EQ(net::ERR_CACHE_OPERATION_NOT_SUPPORTED, 2252 entry->ReadSparseData( 2253 offset, buf.get(), kSize, net::CompletionCallback())); 2254 EXPECT_EQ(net::ERR_CACHE_OPERATION_NOT_SUPPORTED, 2255 entry->WriteSparseData( 2256 offset, buf.get(), kSize, net::CompletionCallback())); 2257 } 2258 2259 // Now see if we receive all notifications. Note that we should not be able 2260 // to write everything (unless the timing of the system is really weird). 2261 rv = cb1.WaitForResult(); 2262 EXPECT_TRUE(rv == 4096 || rv == kSize); 2263 EXPECT_EQ(net::OK, cb2.WaitForResult()); 2264 EXPECT_EQ(net::OK, cb3.WaitForResult()); 2265 EXPECT_EQ(net::OK, cb4.WaitForResult()); 2266 2267 rv = entry->GetAvailableRange(offset, kSize, &offset, cb5.callback()); 2268 EXPECT_EQ(0, cb5.GetResult(rv)); 2269 entry->Close(); 2270 } 2271 2272 // Tests that we perform sanity checks on an entry's key. Note that there are 2273 // other tests that exercise sanity checks by using saved corrupt files. 2274 TEST_F(DiskCacheEntryTest, KeySanityCheck) { 2275 UseCurrentThread(); 2276 InitCache(); 2277 std::string key("the first key"); 2278 disk_cache::Entry* entry; 2279 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 2280 2281 disk_cache::EntryImpl* entry_impl = 2282 static_cast<disk_cache::EntryImpl*>(entry); 2283 disk_cache::EntryStore* store = entry_impl->entry()->Data(); 2284 2285 // We have reserved space for a short key (one block), let's say that the key 2286 // takes more than one block, and remove the NULLs after the actual key. 2287 store->key_len = 800; 2288 memset(store->key + key.size(), 'k', sizeof(store->key) - key.size()); 2289 entry_impl->entry()->set_modified(); 2290 entry->Close(); 2291 2292 // We have a corrupt entry. Now reload it. We should NOT read beyond the 2293 // allocated buffer here. 2294 ASSERT_NE(net::OK, OpenEntry(key, &entry)); 2295 DisableIntegrityCheck(); 2296 } 2297 2298 // The Simple Cache backend requires a few guarantees from the filesystem like 2299 // atomic renaming of recently open files. Those guarantees are not provided in 2300 // general on Windows. 2301 #if defined(OS_POSIX) 2302 2303 TEST_F(DiskCacheEntryTest, SimpleCacheInternalAsyncIO) { 2304 SetSimpleCacheMode(); 2305 InitCache(); 2306 InternalAsyncIO(); 2307 } 2308 2309 TEST_F(DiskCacheEntryTest, SimpleCacheExternalAsyncIO) { 2310 SetSimpleCacheMode(); 2311 InitCache(); 2312 ExternalAsyncIO(); 2313 } 2314 2315 TEST_F(DiskCacheEntryTest, SimpleCacheReleaseBuffer) { 2316 SetSimpleCacheMode(); 2317 InitCache(); 2318 ReleaseBuffer(); 2319 } 2320 2321 TEST_F(DiskCacheEntryTest, SimpleCacheStreamAccess) { 2322 SetSimpleCacheMode(); 2323 InitCache(); 2324 StreamAccess(); 2325 } 2326 2327 TEST_F(DiskCacheEntryTest, SimpleCacheGetKey) { 2328 SetSimpleCacheMode(); 2329 InitCache(); 2330 GetKey(); 2331 } 2332 2333 TEST_F(DiskCacheEntryTest, SimpleCacheGetTimes) { 2334 SetSimpleCacheMode(); 2335 InitCache(); 2336 GetTimes(); 2337 } 2338 2339 TEST_F(DiskCacheEntryTest, SimpleCacheGrowData) { 2340 SetSimpleCacheMode(); 2341 InitCache(); 2342 GrowData(); 2343 } 2344 2345 TEST_F(DiskCacheEntryTest, SimpleCacheTruncateData) { 2346 SetSimpleCacheMode(); 2347 InitCache(); 2348 TruncateData(); 2349 } 2350 2351 TEST_F(DiskCacheEntryTest, SimpleCacheZeroLengthIO) { 2352 SetSimpleCacheMode(); 2353 InitCache(); 2354 ZeroLengthIO(); 2355 } 2356 2357 TEST_F(DiskCacheEntryTest, SimpleCacheSizeAtCreate) { 2358 SetSimpleCacheMode(); 2359 InitCache(); 2360 SizeAtCreate(); 2361 } 2362 2363 TEST_F(DiskCacheEntryTest, SimpleCacheReuseExternalEntry) { 2364 SetSimpleCacheMode(); 2365 SetMaxSize(200 * 1024); 2366 InitCache(); 2367 ReuseEntry(20 * 1024); 2368 } 2369 2370 TEST_F(DiskCacheEntryTest, SimpleCacheReuseInternalEntry) { 2371 SetSimpleCacheMode(); 2372 SetMaxSize(100 * 1024); 2373 InitCache(); 2374 ReuseEntry(10 * 1024); 2375 } 2376 2377 TEST_F(DiskCacheEntryTest, SimpleCacheSizeChanges) { 2378 SetSimpleCacheMode(); 2379 InitCache(); 2380 SizeChanges(); 2381 } 2382 2383 TEST_F(DiskCacheEntryTest, SimpleCacheInvalidData) { 2384 SetSimpleCacheMode(); 2385 InitCache(); 2386 InvalidData(); 2387 } 2388 2389 TEST_F(DiskCacheEntryTest, SimpleCacheReadWriteDestroyBuffer) { 2390 SetSimpleCacheMode(); 2391 InitCache(); 2392 ReadWriteDestroyBuffer(); 2393 } 2394 2395 TEST_F(DiskCacheEntryTest, SimpleCacheDoomEntry) { 2396 SetSimpleCacheMode(); 2397 InitCache(); 2398 DoomNormalEntry(); 2399 } 2400 2401 TEST_F(DiskCacheEntryTest, SimpleCacheDoomEntryNextToOpenEntry) { 2402 SetSimpleCacheMode(); 2403 InitCache(); 2404 DoomEntryNextToOpenEntry(); 2405 } 2406 2407 TEST_F(DiskCacheEntryTest, SimpleCacheDoomedEntry) { 2408 SetSimpleCacheMode(); 2409 InitCache(); 2410 DoomedEntry(); 2411 } 2412 2413 // Creates an entry with corrupted last byte in stream 0. 2414 // Requires SimpleCacheMode. 2415 bool DiskCacheEntryTest::SimpleCacheMakeBadChecksumEntry(const std::string& key, 2416 int* data_size) { 2417 disk_cache::Entry* entry = NULL; 2418 2419 if (CreateEntry(key, &entry) != net::OK || !entry) { 2420 LOG(ERROR) << "Could not create entry"; 2421 return false; 2422 } 2423 2424 const char data[] = "this is very good data"; 2425 const int kDataSize = arraysize(data); 2426 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kDataSize)); 2427 base::strlcpy(buffer->data(), data, kDataSize); 2428 2429 EXPECT_EQ(kDataSize, WriteData(entry, 1, 0, buffer.get(), kDataSize, false)); 2430 entry->Close(); 2431 entry = NULL; 2432 2433 // Corrupt the last byte of the data. 2434 base::FilePath entry_file0_path = cache_path_.AppendASCII( 2435 disk_cache::simple_util::GetFilenameFromKeyAndFileIndex(key, 0)); 2436 int flags = base::PLATFORM_FILE_WRITE | base::PLATFORM_FILE_OPEN; 2437 base::PlatformFile entry_file0 = 2438 base::CreatePlatformFile(entry_file0_path, flags, NULL, NULL); 2439 if (entry_file0 == base::kInvalidPlatformFileValue) 2440 return false; 2441 2442 int64 file_offset = 2443 sizeof(disk_cache::SimpleFileHeader) + key.size() + kDataSize - 2; 2444 EXPECT_EQ(1, base::WritePlatformFile(entry_file0, file_offset, "X", 1)); 2445 if (!base::ClosePlatformFile(entry_file0)) 2446 return false; 2447 *data_size = kDataSize; 2448 return true; 2449 } 2450 2451 // Tests that the simple cache can detect entries that have bad data. 2452 TEST_F(DiskCacheEntryTest, SimpleCacheBadChecksum) { 2453 SetSimpleCacheMode(); 2454 InitCache(); 2455 2456 const char key[] = "the first key"; 2457 int size_unused; 2458 ASSERT_TRUE(SimpleCacheMakeBadChecksumEntry(key, &size_unused)); 2459 2460 disk_cache::Entry* entry = NULL; 2461 2462 // Open the entry. 2463 ASSERT_EQ(net::OK, OpenEntry(key, &entry)); 2464 ScopedEntryPtr entry_closer(entry); 2465 2466 const int kReadBufferSize = 200; 2467 EXPECT_GE(kReadBufferSize, entry->GetDataSize(1)); 2468 scoped_refptr<net::IOBuffer> read_buffer(new net::IOBuffer(kReadBufferSize)); 2469 EXPECT_EQ(net::ERR_CACHE_CHECKSUM_MISMATCH, 2470 ReadData(entry, 1, 0, read_buffer.get(), kReadBufferSize)); 2471 } 2472 2473 // Tests that an entry that has had an IO error occur can still be Doomed(). 2474 TEST_F(DiskCacheEntryTest, SimpleCacheErrorThenDoom) { 2475 SetSimpleCacheMode(); 2476 InitCache(); 2477 2478 const char key[] = "the first key"; 2479 int size_unused; 2480 ASSERT_TRUE(SimpleCacheMakeBadChecksumEntry(key, &size_unused)); 2481 2482 disk_cache::Entry* entry = NULL; 2483 2484 // Open the entry, forcing an IO error. 2485 ASSERT_EQ(net::OK, OpenEntry(key, &entry)); 2486 ScopedEntryPtr entry_closer(entry); 2487 2488 const int kReadBufferSize = 200; 2489 EXPECT_GE(kReadBufferSize, entry->GetDataSize(1)); 2490 scoped_refptr<net::IOBuffer> read_buffer(new net::IOBuffer(kReadBufferSize)); 2491 EXPECT_EQ(net::ERR_CACHE_CHECKSUM_MISMATCH, 2492 ReadData(entry, 1, 0, read_buffer.get(), kReadBufferSize)); 2493 2494 entry->Doom(); // Should not crash. 2495 } 2496 2497 bool TruncatePath(const base::FilePath& file_path, int64 length) { 2498 const int flags = base::PLATFORM_FILE_WRITE | base::PLATFORM_FILE_OPEN; 2499 base::PlatformFile file = 2500 base::CreatePlatformFile(file_path, flags, NULL, NULL); 2501 if (base::kInvalidPlatformFileValue == file) 2502 return false; 2503 const bool result = base::TruncatePlatformFile(file, length); 2504 base::ClosePlatformFile(file); 2505 return result; 2506 } 2507 2508 TEST_F(DiskCacheEntryTest, SimpleCacheNoEOF) { 2509 SetSimpleCacheMode(); 2510 InitCache(); 2511 2512 const char key[] = "the first key"; 2513 2514 disk_cache::Entry* entry = NULL; 2515 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 2516 disk_cache::Entry* null = NULL; 2517 EXPECT_NE(null, entry); 2518 entry->Close(); 2519 entry = NULL; 2520 2521 // Force the entry to flush to disk, so subsequent platform file operations 2522 // succed. 2523 ASSERT_EQ(net::OK, OpenEntry(key, &entry)); 2524 entry->Close(); 2525 entry = NULL; 2526 2527 // Truncate the file such that the length isn't sufficient to have an EOF 2528 // record. 2529 int kTruncationBytes = -implicit_cast<int>(sizeof(disk_cache::SimpleFileEOF)); 2530 const base::FilePath entry_path = cache_path_.AppendASCII( 2531 disk_cache::simple_util::GetFilenameFromKeyAndFileIndex(key, 0)); 2532 const int64 invalid_size = 2533 disk_cache::simple_util::GetFileSizeFromKeyAndDataSize(key, 2534 kTruncationBytes); 2535 EXPECT_TRUE(TruncatePath(entry_path, invalid_size)); 2536 EXPECT_EQ(net::ERR_FAILED, OpenEntry(key, &entry)); 2537 DisableIntegrityCheck(); 2538 } 2539 2540 TEST_F(DiskCacheEntryTest, SimpleCacheNonOptimisticOperationsBasic) { 2541 // Test sequence: 2542 // Create, Write, Read, Close. 2543 SetCacheType(net::APP_CACHE); // APP_CACHE doesn't use optimistic operations. 2544 SetSimpleCacheMode(); 2545 InitCache(); 2546 disk_cache::Entry* const null_entry = NULL; 2547 2548 disk_cache::Entry* entry = NULL; 2549 EXPECT_EQ(net::OK, CreateEntry("my key", &entry)); 2550 ASSERT_NE(null_entry, entry); 2551 ScopedEntryPtr entry_closer(entry); 2552 2553 const int kBufferSize = 10; 2554 scoped_refptr<net::IOBufferWithSize> write_buffer( 2555 new net::IOBufferWithSize(kBufferSize)); 2556 CacheTestFillBuffer(write_buffer->data(), write_buffer->size(), false); 2557 EXPECT_EQ( 2558 write_buffer->size(), 2559 WriteData(entry, 1, 0, write_buffer.get(), write_buffer->size(), false)); 2560 2561 scoped_refptr<net::IOBufferWithSize> read_buffer( 2562 new net::IOBufferWithSize(kBufferSize)); 2563 EXPECT_EQ(read_buffer->size(), 2564 ReadData(entry, 1, 0, read_buffer.get(), read_buffer->size())); 2565 } 2566 2567 TEST_F(DiskCacheEntryTest, SimpleCacheNonOptimisticOperationsDontBlock) { 2568 // Test sequence: 2569 // Create, Write, Close. 2570 SetCacheType(net::APP_CACHE); // APP_CACHE doesn't use optimistic operations. 2571 SetSimpleCacheMode(); 2572 InitCache(); 2573 disk_cache::Entry* const null_entry = NULL; 2574 2575 MessageLoopHelper helper; 2576 CallbackTest create_callback(&helper, false); 2577 2578 int expected_callback_runs = 0; 2579 const int kBufferSize = 10; 2580 scoped_refptr<net::IOBufferWithSize> write_buffer( 2581 new net::IOBufferWithSize(kBufferSize)); 2582 2583 disk_cache::Entry* entry = NULL; 2584 EXPECT_EQ(net::OK, CreateEntry("my key", &entry)); 2585 ASSERT_NE(null_entry, entry); 2586 ScopedEntryPtr entry_closer(entry); 2587 2588 CacheTestFillBuffer(write_buffer->data(), write_buffer->size(), false); 2589 CallbackTest write_callback(&helper, false); 2590 int ret = entry->WriteData( 2591 1, 2592 0, 2593 write_buffer.get(), 2594 write_buffer->size(), 2595 base::Bind(&CallbackTest::Run, base::Unretained(&write_callback)), 2596 false); 2597 ASSERT_EQ(net::ERR_IO_PENDING, ret); 2598 helper.WaitUntilCacheIoFinished(++expected_callback_runs); 2599 } 2600 2601 TEST_F(DiskCacheEntryTest, 2602 SimpleCacheNonOptimisticOperationsBasicsWithoutWaiting) { 2603 // Test sequence: 2604 // Create, Write, Read, Close. 2605 SetCacheType(net::APP_CACHE); // APP_CACHE doesn't use optimistic operations. 2606 SetSimpleCacheMode(); 2607 InitCache(); 2608 disk_cache::Entry* const null_entry = NULL; 2609 MessageLoopHelper helper; 2610 2611 disk_cache::Entry* entry = NULL; 2612 // Note that |entry| is only set once CreateEntry() completed which is why we 2613 // have to wait (i.e. use the helper CreateEntry() function). 2614 EXPECT_EQ(net::OK, CreateEntry("my key", &entry)); 2615 ASSERT_NE(null_entry, entry); 2616 ScopedEntryPtr entry_closer(entry); 2617 2618 const int kBufferSize = 10; 2619 scoped_refptr<net::IOBufferWithSize> write_buffer( 2620 new net::IOBufferWithSize(kBufferSize)); 2621 CacheTestFillBuffer(write_buffer->data(), write_buffer->size(), false); 2622 CallbackTest write_callback(&helper, false); 2623 int ret = entry->WriteData( 2624 1, 2625 0, 2626 write_buffer.get(), 2627 write_buffer->size(), 2628 base::Bind(&CallbackTest::Run, base::Unretained(&write_callback)), 2629 false); 2630 EXPECT_EQ(net::ERR_IO_PENDING, ret); 2631 int expected_callback_runs = 1; 2632 2633 scoped_refptr<net::IOBufferWithSize> read_buffer( 2634 new net::IOBufferWithSize(kBufferSize)); 2635 CallbackTest read_callback(&helper, false); 2636 ret = entry->ReadData( 2637 1, 2638 0, 2639 read_buffer.get(), 2640 read_buffer->size(), 2641 base::Bind(&CallbackTest::Run, base::Unretained(&read_callback))); 2642 EXPECT_EQ(net::ERR_IO_PENDING, ret); 2643 ++expected_callback_runs; 2644 2645 helper.WaitUntilCacheIoFinished(expected_callback_runs); 2646 ASSERT_EQ(read_buffer->size(), write_buffer->size()); 2647 EXPECT_EQ( 2648 0, 2649 memcmp(read_buffer->data(), write_buffer->data(), read_buffer->size())); 2650 } 2651 2652 TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic) { 2653 // Test sequence: 2654 // Create, Write, Read, Write, Read, Close. 2655 SetSimpleCacheMode(); 2656 InitCache(); 2657 disk_cache::Entry* null = NULL; 2658 const char key[] = "the first key"; 2659 2660 MessageLoopHelper helper; 2661 CallbackTest callback1(&helper, false); 2662 CallbackTest callback2(&helper, false); 2663 CallbackTest callback3(&helper, false); 2664 CallbackTest callback4(&helper, false); 2665 CallbackTest callback5(&helper, false); 2666 2667 int expected = 0; 2668 const int kSize1 = 10; 2669 const int kSize2 = 20; 2670 scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1)); 2671 scoped_refptr<net::IOBuffer> buffer1_read(new net::IOBuffer(kSize1)); 2672 scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize2)); 2673 scoped_refptr<net::IOBuffer> buffer2_read(new net::IOBuffer(kSize2)); 2674 CacheTestFillBuffer(buffer1->data(), kSize1, false); 2675 CacheTestFillBuffer(buffer2->data(), kSize2, false); 2676 2677 disk_cache::Entry* entry = NULL; 2678 // Create is optimistic, must return OK. 2679 ASSERT_EQ(net::OK, 2680 cache_->CreateEntry(key, &entry, 2681 base::Bind(&CallbackTest::Run, 2682 base::Unretained(&callback1)))); 2683 EXPECT_NE(null, entry); 2684 ScopedEntryPtr entry_closer(entry); 2685 2686 // This write may or may not be optimistic (it depends if the previous 2687 // optimistic create already finished by the time we call the write here). 2688 int ret = entry->WriteData( 2689 1, 2690 0, 2691 buffer1.get(), 2692 kSize1, 2693 base::Bind(&CallbackTest::Run, base::Unretained(&callback2)), 2694 false); 2695 EXPECT_TRUE(kSize1 == ret || net::ERR_IO_PENDING == ret); 2696 if (net::ERR_IO_PENDING == ret) 2697 expected++; 2698 2699 // This Read must not be optimistic, since we don't support that yet. 2700 EXPECT_EQ(net::ERR_IO_PENDING, 2701 entry->ReadData( 2702 1, 2703 0, 2704 buffer1_read.get(), 2705 kSize1, 2706 base::Bind(&CallbackTest::Run, base::Unretained(&callback3)))); 2707 expected++; 2708 EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected)); 2709 EXPECT_EQ(0, memcmp(buffer1->data(), buffer1_read->data(), kSize1)); 2710 2711 // At this point after waiting, the pending operations queue on the entry 2712 // should be empty, so the next Write operation must run as optimistic. 2713 EXPECT_EQ(kSize2, 2714 entry->WriteData( 2715 1, 2716 0, 2717 buffer2.get(), 2718 kSize2, 2719 base::Bind(&CallbackTest::Run, base::Unretained(&callback4)), 2720 false)); 2721 2722 // Lets do another read so we block until both the write and the read 2723 // operation finishes and we can then test for HasOneRef() below. 2724 EXPECT_EQ(net::ERR_IO_PENDING, 2725 entry->ReadData( 2726 1, 2727 0, 2728 buffer2_read.get(), 2729 kSize2, 2730 base::Bind(&CallbackTest::Run, base::Unretained(&callback5)))); 2731 expected++; 2732 2733 EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected)); 2734 EXPECT_EQ(0, memcmp(buffer2->data(), buffer2_read->data(), kSize2)); 2735 2736 // Check that we are not leaking. 2737 EXPECT_NE(entry, null); 2738 EXPECT_TRUE( 2739 static_cast<disk_cache::SimpleEntryImpl*>(entry)->HasOneRef()); 2740 } 2741 2742 TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic2) { 2743 // Test sequence: 2744 // Create, Open, Close, Close. 2745 SetSimpleCacheMode(); 2746 InitCache(); 2747 disk_cache::Entry* null = NULL; 2748 const char key[] = "the first key"; 2749 2750 MessageLoopHelper helper; 2751 CallbackTest callback1(&helper, false); 2752 CallbackTest callback2(&helper, false); 2753 2754 disk_cache::Entry* entry = NULL; 2755 ASSERT_EQ(net::OK, 2756 cache_->CreateEntry(key, &entry, 2757 base::Bind(&CallbackTest::Run, 2758 base::Unretained(&callback1)))); 2759 EXPECT_NE(null, entry); 2760 ScopedEntryPtr entry_closer(entry); 2761 2762 disk_cache::Entry* entry2 = NULL; 2763 ASSERT_EQ(net::ERR_IO_PENDING, 2764 cache_->OpenEntry(key, &entry2, 2765 base::Bind(&CallbackTest::Run, 2766 base::Unretained(&callback2)))); 2767 ASSERT_TRUE(helper.WaitUntilCacheIoFinished(1)); 2768 2769 EXPECT_NE(null, entry2); 2770 EXPECT_EQ(entry, entry2); 2771 2772 // We have to call close twice, since we called create and open above. 2773 entry->Close(); 2774 2775 // Check that we are not leaking. 2776 EXPECT_TRUE( 2777 static_cast<disk_cache::SimpleEntryImpl*>(entry)->HasOneRef()); 2778 } 2779 2780 TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic3) { 2781 // Test sequence: 2782 // Create, Close, Open, Close. 2783 SetSimpleCacheMode(); 2784 InitCache(); 2785 disk_cache::Entry* null = NULL; 2786 const char key[] = "the first key"; 2787 2788 disk_cache::Entry* entry = NULL; 2789 ASSERT_EQ(net::OK, 2790 cache_->CreateEntry(key, &entry, net::CompletionCallback())); 2791 EXPECT_NE(null, entry); 2792 entry->Close(); 2793 2794 net::TestCompletionCallback cb; 2795 disk_cache::Entry* entry2 = NULL; 2796 ASSERT_EQ(net::ERR_IO_PENDING, 2797 cache_->OpenEntry(key, &entry2, cb.callback())); 2798 ASSERT_EQ(net::OK, cb.GetResult(net::ERR_IO_PENDING)); 2799 ScopedEntryPtr entry_closer(entry2); 2800 2801 EXPECT_NE(null, entry2); 2802 EXPECT_EQ(entry, entry2); 2803 2804 // Check that we are not leaking. 2805 EXPECT_TRUE( 2806 static_cast<disk_cache::SimpleEntryImpl*>(entry2)->HasOneRef()); 2807 } 2808 2809 TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic4) { 2810 // Test sequence: 2811 // Create, Close, Write, Open, Open, Close, Write, Read, Close. 2812 SetSimpleCacheMode(); 2813 InitCache(); 2814 disk_cache::Entry* null = NULL; 2815 const char key[] = "the first key"; 2816 2817 net::TestCompletionCallback cb; 2818 const int kSize1 = 10; 2819 scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1)); 2820 CacheTestFillBuffer(buffer1->data(), kSize1, false); 2821 disk_cache::Entry* entry = NULL; 2822 2823 ASSERT_EQ(net::OK, 2824 cache_->CreateEntry(key, &entry, net::CompletionCallback())); 2825 EXPECT_NE(null, entry); 2826 entry->Close(); 2827 2828 // Lets do a Write so we block until both the Close and the Write 2829 // operation finishes. Write must fail since we are writing in a closed entry. 2830 EXPECT_EQ( 2831 net::ERR_IO_PENDING, 2832 entry->WriteData(1, 0, buffer1.get(), kSize1, cb.callback(), false)); 2833 EXPECT_EQ(net::ERR_FAILED, cb.GetResult(net::ERR_IO_PENDING)); 2834 2835 // Finish running the pending tasks so that we fully complete the close 2836 // operation and destroy the entry object. 2837 base::MessageLoop::current()->RunUntilIdle(); 2838 2839 // At this point the |entry| must have been destroyed, and called 2840 // RemoveSelfFromBackend(). 2841 disk_cache::Entry* entry2 = NULL; 2842 ASSERT_EQ(net::ERR_IO_PENDING, 2843 cache_->OpenEntry(key, &entry2, cb.callback())); 2844 ASSERT_EQ(net::OK, cb.GetResult(net::ERR_IO_PENDING)); 2845 EXPECT_NE(null, entry2); 2846 2847 disk_cache::Entry* entry3 = NULL; 2848 ASSERT_EQ(net::ERR_IO_PENDING, 2849 cache_->OpenEntry(key, &entry3, cb.callback())); 2850 ASSERT_EQ(net::OK, cb.GetResult(net::ERR_IO_PENDING)); 2851 EXPECT_NE(null, entry3); 2852 EXPECT_EQ(entry2, entry3); 2853 entry3->Close(); 2854 2855 // The previous Close doesn't actually closes the entry since we opened it 2856 // twice, so the next Write operation must succeed and it must be able to 2857 // perform it optimistically, since there is no operation running on this 2858 // entry. 2859 EXPECT_EQ(kSize1, 2860 entry2->WriteData( 2861 1, 0, buffer1.get(), kSize1, net::CompletionCallback(), false)); 2862 2863 // Lets do another read so we block until both the write and the read 2864 // operation finishes and we can then test for HasOneRef() below. 2865 EXPECT_EQ(net::ERR_IO_PENDING, 2866 entry2->ReadData(1, 0, buffer1.get(), kSize1, cb.callback())); 2867 EXPECT_EQ(kSize1, cb.GetResult(net::ERR_IO_PENDING)); 2868 2869 // Check that we are not leaking. 2870 EXPECT_TRUE( 2871 static_cast<disk_cache::SimpleEntryImpl*>(entry2)->HasOneRef()); 2872 entry2->Close(); 2873 } 2874 2875 TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic5) { 2876 // Test sequence: 2877 // Create, Doom, Write, Read, Close. 2878 SetSimpleCacheMode(); 2879 InitCache(); 2880 disk_cache::Entry* null = NULL; 2881 const char key[] = "the first key"; 2882 2883 net::TestCompletionCallback cb; 2884 const int kSize1 = 10; 2885 scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1)); 2886 CacheTestFillBuffer(buffer1->data(), kSize1, false); 2887 disk_cache::Entry* entry = NULL; 2888 2889 ASSERT_EQ(net::OK, 2890 cache_->CreateEntry(key, &entry, net::CompletionCallback())); 2891 EXPECT_NE(null, entry); 2892 ScopedEntryPtr entry_closer(entry); 2893 entry->Doom(); 2894 2895 EXPECT_EQ( 2896 net::ERR_IO_PENDING, 2897 entry->WriteData(1, 0, buffer1.get(), kSize1, cb.callback(), false)); 2898 EXPECT_EQ(kSize1, cb.GetResult(net::ERR_IO_PENDING)); 2899 2900 EXPECT_EQ(net::ERR_IO_PENDING, 2901 entry->ReadData(1, 0, buffer1.get(), kSize1, cb.callback())); 2902 EXPECT_EQ(kSize1, cb.GetResult(net::ERR_IO_PENDING)); 2903 2904 // Check that we are not leaking. 2905 EXPECT_TRUE( 2906 static_cast<disk_cache::SimpleEntryImpl*>(entry)->HasOneRef()); 2907 } 2908 2909 TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic6) { 2910 // Test sequence: 2911 // Create, Write, Doom, Doom, Read, Doom, Close. 2912 SetSimpleCacheMode(); 2913 InitCache(); 2914 disk_cache::Entry* null = NULL; 2915 const char key[] = "the first key"; 2916 2917 net::TestCompletionCallback cb; 2918 const int kSize1 = 10; 2919 scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1)); 2920 scoped_refptr<net::IOBuffer> buffer1_read(new net::IOBuffer(kSize1)); 2921 CacheTestFillBuffer(buffer1->data(), kSize1, false); 2922 disk_cache::Entry* entry = NULL; 2923 2924 ASSERT_EQ(net::OK, 2925 cache_->CreateEntry(key, &entry, net::CompletionCallback())); 2926 EXPECT_NE(null, entry); 2927 ScopedEntryPtr entry_closer(entry); 2928 2929 EXPECT_EQ( 2930 net::ERR_IO_PENDING, 2931 entry->WriteData(1, 0, buffer1.get(), kSize1, cb.callback(), false)); 2932 EXPECT_EQ(kSize1, cb.GetResult(net::ERR_IO_PENDING)); 2933 2934 entry->Doom(); 2935 entry->Doom(); 2936 2937 // This Read must not be optimistic, since we don't support that yet. 2938 EXPECT_EQ(net::ERR_IO_PENDING, 2939 entry->ReadData(1, 0, buffer1_read.get(), kSize1, cb.callback())); 2940 EXPECT_EQ(kSize1, cb.GetResult(net::ERR_IO_PENDING)); 2941 EXPECT_EQ(0, memcmp(buffer1->data(), buffer1_read->data(), kSize1)); 2942 2943 entry->Doom(); 2944 } 2945 2946 // Confirm that IO buffers are not referenced by the Simple Cache after a write 2947 // completes. 2948 TEST_F(DiskCacheEntryTest, SimpleCacheOptimisticWriteReleases) { 2949 SetSimpleCacheMode(); 2950 InitCache(); 2951 2952 const char key[] = "the first key"; 2953 disk_cache::Entry* entry = NULL; 2954 2955 // First, an optimistic create. 2956 ASSERT_EQ(net::OK, 2957 cache_->CreateEntry(key, &entry, net::CompletionCallback())); 2958 ASSERT_TRUE(entry); 2959 ScopedEntryPtr entry_closer(entry); 2960 2961 const int kWriteSize = 512; 2962 scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kWriteSize)); 2963 EXPECT_TRUE(buffer1->HasOneRef()); 2964 CacheTestFillBuffer(buffer1->data(), kWriteSize, false); 2965 2966 // An optimistic write happens only when there is an empty queue of pending 2967 // operations. To ensure the queue is empty, we issue a write and wait until 2968 // it completes. 2969 EXPECT_EQ(kWriteSize, 2970 WriteData(entry, 1, 0, buffer1.get(), kWriteSize, false)); 2971 EXPECT_TRUE(buffer1->HasOneRef()); 2972 2973 // Finally, we should perform an optimistic write and confirm that all 2974 // references to the IO buffer have been released. 2975 EXPECT_EQ( 2976 kWriteSize, 2977 entry->WriteData( 2978 1, 0, buffer1.get(), kWriteSize, net::CompletionCallback(), false)); 2979 EXPECT_TRUE(buffer1->HasOneRef()); 2980 } 2981 2982 TEST_F(DiskCacheEntryTest, SimpleCacheCreateDoomRace) { 2983 // Test sequence: 2984 // Create, Doom, Write, Close, Check files are not on disk anymore. 2985 SetSimpleCacheMode(); 2986 InitCache(); 2987 disk_cache::Entry* null = NULL; 2988 const char key[] = "the first key"; 2989 2990 net::TestCompletionCallback cb; 2991 const int kSize1 = 10; 2992 scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1)); 2993 CacheTestFillBuffer(buffer1->data(), kSize1, false); 2994 disk_cache::Entry* entry = NULL; 2995 2996 ASSERT_EQ(net::OK, 2997 cache_->CreateEntry(key, &entry, net::CompletionCallback())); 2998 EXPECT_NE(null, entry); 2999 3000 EXPECT_EQ(net::ERR_IO_PENDING, cache_->DoomEntry(key, cb.callback())); 3001 EXPECT_EQ(net::OK, cb.GetResult(net::ERR_IO_PENDING)); 3002 3003 EXPECT_EQ( 3004 kSize1, 3005 entry->WriteData(0, 0, buffer1.get(), kSize1, cb.callback(), false)); 3006 3007 entry->Close(); 3008 3009 // Finish running the pending tasks so that we fully complete the close 3010 // operation and destroy the entry object. 3011 base::MessageLoop::current()->RunUntilIdle(); 3012 3013 for (int i = 0; i < disk_cache::kSimpleEntryFileCount; ++i) { 3014 base::FilePath entry_file_path = cache_path_.AppendASCII( 3015 disk_cache::simple_util::GetFilenameFromKeyAndFileIndex(key, i)); 3016 base::PlatformFileInfo info; 3017 EXPECT_FALSE(base::GetFileInfo(entry_file_path, &info)); 3018 } 3019 } 3020 3021 TEST_F(DiskCacheEntryTest, SimpleCacheDoomCreateRace) { 3022 // This test runs as APP_CACHE to make operations more synchronous. Test 3023 // sequence: 3024 // Create, Doom, Create. 3025 SetCacheType(net::APP_CACHE); 3026 SetSimpleCacheMode(); 3027 InitCache(); 3028 disk_cache::Entry* null = NULL; 3029 const char key[] = "the first key"; 3030 3031 net::TestCompletionCallback create_callback; 3032 3033 disk_cache::Entry* entry1 = NULL; 3034 ASSERT_EQ(net::OK, 3035 create_callback.GetResult( 3036 cache_->CreateEntry(key, &entry1, create_callback.callback()))); 3037 ScopedEntryPtr entry1_closer(entry1); 3038 EXPECT_NE(null, entry1); 3039 3040 net::TestCompletionCallback doom_callback; 3041 EXPECT_EQ(net::ERR_IO_PENDING, 3042 cache_->DoomEntry(key, doom_callback.callback())); 3043 3044 disk_cache::Entry* entry2 = NULL; 3045 ASSERT_EQ(net::OK, 3046 create_callback.GetResult( 3047 cache_->CreateEntry(key, &entry2, create_callback.callback()))); 3048 ScopedEntryPtr entry2_closer(entry2); 3049 EXPECT_EQ(net::OK, doom_callback.GetResult(net::ERR_IO_PENDING)); 3050 } 3051 3052 TEST_F(DiskCacheEntryTest, SimpleCacheDoomDoom) { 3053 // Test sequence: 3054 // Create, Doom, Create, Doom (1st entry), Open. 3055 SetSimpleCacheMode(); 3056 InitCache(); 3057 disk_cache::Entry* null = NULL; 3058 3059 const char key[] = "the first key"; 3060 3061 disk_cache::Entry* entry1 = NULL; 3062 ASSERT_EQ(net::OK, CreateEntry(key, &entry1)); 3063 ScopedEntryPtr entry1_closer(entry1); 3064 EXPECT_NE(null, entry1); 3065 3066 EXPECT_EQ(net::OK, DoomEntry(key)); 3067 3068 disk_cache::Entry* entry2 = NULL; 3069 ASSERT_EQ(net::OK, CreateEntry(key, &entry2)); 3070 ScopedEntryPtr entry2_closer(entry2); 3071 EXPECT_NE(null, entry2); 3072 3073 // Redundantly dooming entry1 should not delete entry2. 3074 disk_cache::SimpleEntryImpl* simple_entry1 = 3075 static_cast<disk_cache::SimpleEntryImpl*>(entry1); 3076 net::TestCompletionCallback cb; 3077 EXPECT_EQ(net::OK, 3078 cb.GetResult(simple_entry1->DoomEntry(cb.callback()))); 3079 3080 disk_cache::Entry* entry3 = NULL; 3081 ASSERT_EQ(net::OK, OpenEntry(key, &entry3)); 3082 ScopedEntryPtr entry3_closer(entry3); 3083 EXPECT_NE(null, entry3); 3084 } 3085 3086 TEST_F(DiskCacheEntryTest, SimpleCacheDoomCreateDoom) { 3087 // Test sequence: 3088 // Create, Doom, Create, Doom. 3089 SetSimpleCacheMode(); 3090 InitCache(); 3091 3092 disk_cache::Entry* null = NULL; 3093 3094 const char key[] = "the first key"; 3095 3096 disk_cache::Entry* entry1 = NULL; 3097 ASSERT_EQ(net::OK, CreateEntry(key, &entry1)); 3098 ScopedEntryPtr entry1_closer(entry1); 3099 EXPECT_NE(null, entry1); 3100 3101 entry1->Doom(); 3102 3103 disk_cache::Entry* entry2 = NULL; 3104 ASSERT_EQ(net::OK, CreateEntry(key, &entry2)); 3105 ScopedEntryPtr entry2_closer(entry2); 3106 EXPECT_NE(null, entry2); 3107 3108 entry2->Doom(); 3109 3110 // This test passes if it doesn't crash. 3111 } 3112 3113 // Checks that an optimistic Create would fail later on a racing Open. 3114 TEST_F(DiskCacheEntryTest, SimpleCacheOptimisticCreateFailsOnOpen) { 3115 SetSimpleCacheMode(); 3116 InitCache(); 3117 3118 // Create a corrupt file in place of a future entry. Optimistic create should 3119 // initially succeed, but realize later that creation failed. 3120 const std::string key = "the key"; 3121 net::TestCompletionCallback cb; 3122 disk_cache::Entry* entry = NULL; 3123 disk_cache::Entry* entry2 = NULL; 3124 3125 EXPECT_TRUE(disk_cache::simple_util::CreateCorruptFileForTests( 3126 key, cache_path_)); 3127 EXPECT_EQ(net::OK, cache_->CreateEntry(key, &entry, cb.callback())); 3128 ASSERT_TRUE(entry); 3129 ScopedEntryPtr entry_closer(entry); 3130 ASSERT_NE(net::OK, OpenEntry(key, &entry2)); 3131 3132 // Check that we are not leaking. 3133 EXPECT_TRUE( 3134 static_cast<disk_cache::SimpleEntryImpl*>(entry)->HasOneRef()); 3135 3136 DisableIntegrityCheck(); 3137 } 3138 3139 // Tests that old entries are evicted while new entries remain in the index. 3140 // This test relies on non-mandatory properties of the simple Cache Backend: 3141 // LRU eviction, specific values of high-watermark and low-watermark etc. 3142 // When changing the eviction algorithm, the test will have to be re-engineered. 3143 TEST_F(DiskCacheEntryTest, SimpleCacheEvictOldEntries) { 3144 const int kMaxSize = 200 * 1024; 3145 const int kWriteSize = kMaxSize / 10; 3146 const int kNumExtraEntries = 12; 3147 SetSimpleCacheMode(); 3148 SetMaxSize(kMaxSize); 3149 InitCache(); 3150 3151 std::string key1("the first key"); 3152 disk_cache::Entry* entry; 3153 ASSERT_EQ(net::OK, CreateEntry(key1, &entry)); 3154 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kWriteSize)); 3155 CacheTestFillBuffer(buffer->data(), kWriteSize, false); 3156 EXPECT_EQ(kWriteSize, 3157 WriteData(entry, 1, 0, buffer.get(), kWriteSize, false)); 3158 entry->Close(); 3159 AddDelay(); 3160 3161 std::string key2("the key prefix"); 3162 for (int i = 0; i < kNumExtraEntries; i++) { 3163 ASSERT_EQ(net::OK, CreateEntry(key2 + base::StringPrintf("%d", i), &entry)); 3164 ScopedEntryPtr entry_closer(entry); 3165 EXPECT_EQ(kWriteSize, 3166 WriteData(entry, 1, 0, buffer.get(), kWriteSize, false)); 3167 } 3168 3169 // TODO(pasko): Find a way to wait for the eviction task(s) to finish by using 3170 // the internal knowledge about |SimpleBackendImpl|. 3171 ASSERT_NE(net::OK, OpenEntry(key1, &entry)) 3172 << "Should have evicted the old entry"; 3173 for (int i = 0; i < 2; i++) { 3174 int entry_no = kNumExtraEntries - i - 1; 3175 // Generally there is no guarantee that at this point the backround eviction 3176 // is finished. We are testing the positive case, i.e. when the eviction 3177 // never reaches this entry, should be non-flaky. 3178 ASSERT_EQ(net::OK, OpenEntry(key2 + base::StringPrintf("%d", entry_no), 3179 &entry)) 3180 << "Should not have evicted fresh entry " << entry_no; 3181 entry->Close(); 3182 } 3183 } 3184 3185 // Tests that if a read and a following in-flight truncate are both in progress 3186 // simultaniously that they both can occur successfully. See 3187 // http://crbug.com/239223 3188 TEST_F(DiskCacheEntryTest, SimpleCacheInFlightTruncate) { 3189 SetSimpleCacheMode(); 3190 InitCache(); 3191 3192 const char key[] = "the first key"; 3193 3194 const int kBufferSize = 1024; 3195 scoped_refptr<net::IOBuffer> write_buffer(new net::IOBuffer(kBufferSize)); 3196 CacheTestFillBuffer(write_buffer->data(), kBufferSize, false); 3197 3198 disk_cache::Entry* entry = NULL; 3199 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 3200 3201 EXPECT_EQ(kBufferSize, 3202 WriteData(entry, 1, 0, write_buffer.get(), kBufferSize, false)); 3203 entry->Close(); 3204 entry = NULL; 3205 3206 ASSERT_EQ(net::OK, OpenEntry(key, &entry)); 3207 ScopedEntryPtr entry_closer(entry); 3208 3209 MessageLoopHelper helper; 3210 int expected = 0; 3211 3212 // Make a short read. 3213 const int kReadBufferSize = 512; 3214 scoped_refptr<net::IOBuffer> read_buffer(new net::IOBuffer(kReadBufferSize)); 3215 CallbackTest read_callback(&helper, false); 3216 EXPECT_EQ(net::ERR_IO_PENDING, 3217 entry->ReadData(1, 3218 0, 3219 read_buffer.get(), 3220 kReadBufferSize, 3221 base::Bind(&CallbackTest::Run, 3222 base::Unretained(&read_callback)))); 3223 ++expected; 3224 3225 // Truncate the entry to the length of that read. 3226 scoped_refptr<net::IOBuffer> 3227 truncate_buffer(new net::IOBuffer(kReadBufferSize)); 3228 CacheTestFillBuffer(truncate_buffer->data(), kReadBufferSize, false); 3229 CallbackTest truncate_callback(&helper, false); 3230 EXPECT_EQ(net::ERR_IO_PENDING, 3231 entry->WriteData(1, 3232 0, 3233 truncate_buffer.get(), 3234 kReadBufferSize, 3235 base::Bind(&CallbackTest::Run, 3236 base::Unretained(&truncate_callback)), 3237 true)); 3238 ++expected; 3239 3240 // Wait for both the read and truncation to finish, and confirm that both 3241 // succeeded. 3242 EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected)); 3243 EXPECT_EQ(kReadBufferSize, read_callback.last_result()); 3244 EXPECT_EQ(kReadBufferSize, truncate_callback.last_result()); 3245 EXPECT_EQ(0, 3246 memcmp(write_buffer->data(), read_buffer->data(), kReadBufferSize)); 3247 } 3248 3249 // Tests that if a write and a read dependant on it are both in flight 3250 // simultaneiously that they both can complete successfully without erroneous 3251 // early returns. See http://crbug.com/239223 3252 TEST_F(DiskCacheEntryTest, SimpleCacheInFlightRead) { 3253 SetSimpleCacheMode(); 3254 InitCache(); 3255 3256 const char key[] = "the first key"; 3257 disk_cache::Entry* entry = NULL; 3258 ASSERT_EQ(net::OK, 3259 cache_->CreateEntry(key, &entry, net::CompletionCallback())); 3260 ScopedEntryPtr entry_closer(entry); 3261 3262 const int kBufferSize = 1024; 3263 scoped_refptr<net::IOBuffer> write_buffer(new net::IOBuffer(kBufferSize)); 3264 CacheTestFillBuffer(write_buffer->data(), kBufferSize, false); 3265 3266 MessageLoopHelper helper; 3267 int expected = 0; 3268 3269 CallbackTest write_callback(&helper, false); 3270 EXPECT_EQ(net::ERR_IO_PENDING, 3271 entry->WriteData(1, 3272 0, 3273 write_buffer.get(), 3274 kBufferSize, 3275 base::Bind(&CallbackTest::Run, 3276 base::Unretained(&write_callback)), 3277 true)); 3278 ++expected; 3279 3280 scoped_refptr<net::IOBuffer> read_buffer(new net::IOBuffer(kBufferSize)); 3281 CallbackTest read_callback(&helper, false); 3282 EXPECT_EQ(net::ERR_IO_PENDING, 3283 entry->ReadData(1, 3284 0, 3285 read_buffer.get(), 3286 kBufferSize, 3287 base::Bind(&CallbackTest::Run, 3288 base::Unretained(&read_callback)))); 3289 ++expected; 3290 3291 EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected)); 3292 EXPECT_EQ(kBufferSize, write_callback.last_result()); 3293 EXPECT_EQ(kBufferSize, read_callback.last_result()); 3294 EXPECT_EQ(0, memcmp(write_buffer->data(), read_buffer->data(), kBufferSize)); 3295 } 3296 3297 TEST_F(DiskCacheEntryTest, SimpleCacheOpenCreateRaceWithNoIndex) { 3298 SetSimpleCacheMode(); 3299 DisableSimpleCacheWaitForIndex(); 3300 DisableIntegrityCheck(); 3301 InitCache(); 3302 3303 // Assume the index is not initialized, which is likely, since we are blocking 3304 // the IO thread from executing the index finalization step. 3305 disk_cache::Entry* entry1; 3306 net::TestCompletionCallback cb1; 3307 disk_cache::Entry* entry2; 3308 net::TestCompletionCallback cb2; 3309 int rv1 = cache_->OpenEntry("key", &entry1, cb1.callback()); 3310 int rv2 = cache_->CreateEntry("key", &entry2, cb2.callback()); 3311 3312 EXPECT_EQ(net::ERR_FAILED, cb1.GetResult(rv1)); 3313 ASSERT_EQ(net::OK, cb2.GetResult(rv2)); 3314 entry2->Close(); 3315 } 3316 3317 // Checks that reading two entries simultaneously does not discard a CRC check. 3318 // TODO(pasko): make it work with Simple Cache. 3319 TEST_F(DiskCacheEntryTest, DISABLED_SimpleCacheMultipleReadersCheckCRC) { 3320 SetSimpleCacheMode(); 3321 InitCache(); 3322 3323 const char key[] = "key"; 3324 3325 int size; 3326 ASSERT_TRUE(SimpleCacheMakeBadChecksumEntry(key, &size)); 3327 3328 scoped_refptr<net::IOBuffer> read_buffer1(new net::IOBuffer(size)); 3329 scoped_refptr<net::IOBuffer> read_buffer2(new net::IOBuffer(size)); 3330 3331 // Advance the first reader a little. 3332 disk_cache::Entry* entry = NULL; 3333 ASSERT_EQ(net::OK, OpenEntry(key, &entry)); 3334 EXPECT_EQ(1, ReadData(entry, 0, 0, read_buffer1.get(), 1)); 3335 3336 // Make the second reader pass the point where the first one is, and close. 3337 disk_cache::Entry* entry2 = NULL; 3338 EXPECT_EQ(net::OK, OpenEntry(key, &entry2)); 3339 EXPECT_EQ(1, ReadData(entry2, 0, 0, read_buffer2.get(), 1)); 3340 EXPECT_EQ(1, ReadData(entry2, 0, 1, read_buffer2.get(), 1)); 3341 entry2->Close(); 3342 3343 // Read the data till the end should produce an error. 3344 EXPECT_GT(0, ReadData(entry, 0, 1, read_buffer1.get(), size)); 3345 entry->Close(); 3346 DisableIntegrityCheck(); 3347 } 3348 3349 // Checking one more scenario of overlapped reading of a bad entry. 3350 // Differs from the |SimpleCacheMultipleReadersCheckCRC| only by the order of 3351 // last two reads. 3352 TEST_F(DiskCacheEntryTest, SimpleCacheMultipleReadersCheckCRC2) { 3353 SetSimpleCacheMode(); 3354 InitCache(); 3355 3356 const char key[] = "key"; 3357 int size; 3358 ASSERT_TRUE(SimpleCacheMakeBadChecksumEntry(key, &size)); 3359 3360 scoped_refptr<net::IOBuffer> read_buffer1(new net::IOBuffer(size)); 3361 scoped_refptr<net::IOBuffer> read_buffer2(new net::IOBuffer(size)); 3362 3363 // Advance the first reader a little. 3364 disk_cache::Entry* entry = NULL; 3365 ASSERT_EQ(net::OK, OpenEntry(key, &entry)); 3366 ScopedEntryPtr entry_closer(entry); 3367 EXPECT_EQ(1, ReadData(entry, 1, 0, read_buffer1.get(), 1)); 3368 3369 // Advance the 2nd reader by the same amount. 3370 disk_cache::Entry* entry2 = NULL; 3371 EXPECT_EQ(net::OK, OpenEntry(key, &entry2)); 3372 ScopedEntryPtr entry2_closer(entry2); 3373 EXPECT_EQ(1, ReadData(entry2, 1, 0, read_buffer2.get(), 1)); 3374 3375 // Continue reading 1st. 3376 EXPECT_GT(0, ReadData(entry, 1, 1, read_buffer1.get(), size)); 3377 3378 // This read should fail as well because we have previous read failures. 3379 EXPECT_GT(0, ReadData(entry2, 1, 1, read_buffer2.get(), 1)); 3380 DisableIntegrityCheck(); 3381 } 3382 3383 // Test if we can sequentially read each subset of the data until all the data 3384 // is read, then the CRC is calculated correctly and the reads are successful. 3385 TEST_F(DiskCacheEntryTest, SimpleCacheReadCombineCRC) { 3386 // Test sequence: 3387 // Create, Write, Read (first half of data), Read (second half of data), 3388 // Close. 3389 SetSimpleCacheMode(); 3390 InitCache(); 3391 disk_cache::Entry* null = NULL; 3392 const char key[] = "the first key"; 3393 3394 const int kHalfSize = 200; 3395 const int kSize = 2 * kHalfSize; 3396 scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize)); 3397 CacheTestFillBuffer(buffer1->data(), kSize, false); 3398 disk_cache::Entry* entry = NULL; 3399 3400 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 3401 EXPECT_NE(null, entry); 3402 3403 EXPECT_EQ(kSize, WriteData(entry, 1, 0, buffer1.get(), kSize, false)); 3404 entry->Close(); 3405 3406 disk_cache::Entry* entry2 = NULL; 3407 ASSERT_EQ(net::OK, OpenEntry(key, &entry2)); 3408 EXPECT_EQ(entry, entry2); 3409 3410 // Read the first half of the data. 3411 int offset = 0; 3412 int buf_len = kHalfSize; 3413 scoped_refptr<net::IOBuffer> buffer1_read1(new net::IOBuffer(buf_len)); 3414 EXPECT_EQ(buf_len, ReadData(entry2, 1, offset, buffer1_read1.get(), buf_len)); 3415 EXPECT_EQ(0, memcmp(buffer1->data(), buffer1_read1->data(), buf_len)); 3416 3417 // Read the second half of the data. 3418 offset = buf_len; 3419 buf_len = kHalfSize; 3420 scoped_refptr<net::IOBuffer> buffer1_read2(new net::IOBuffer(buf_len)); 3421 EXPECT_EQ(buf_len, ReadData(entry2, 1, offset, buffer1_read2.get(), buf_len)); 3422 char* buffer1_data = buffer1->data() + offset; 3423 EXPECT_EQ(0, memcmp(buffer1_data, buffer1_read2->data(), buf_len)); 3424 3425 // Check that we are not leaking. 3426 EXPECT_NE(entry, null); 3427 EXPECT_TRUE( 3428 static_cast<disk_cache::SimpleEntryImpl*>(entry)->HasOneRef()); 3429 entry->Close(); 3430 entry = NULL; 3431 } 3432 3433 // Test if we can write the data not in sequence and read correctly. In 3434 // this case the CRC will not be present. 3435 TEST_F(DiskCacheEntryTest, SimpleCacheNonSequentialWrite) { 3436 // Test sequence: 3437 // Create, Write (second half of data), Write (first half of data), Read, 3438 // Close. 3439 SetSimpleCacheMode(); 3440 InitCache(); 3441 disk_cache::Entry* null = NULL; 3442 const char key[] = "the first key"; 3443 3444 const int kHalfSize = 200; 3445 const int kSize = 2 * kHalfSize; 3446 scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize)); 3447 scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize)); 3448 CacheTestFillBuffer(buffer1->data(), kSize, false); 3449 char* buffer1_data = buffer1->data() + kHalfSize; 3450 memcpy(buffer2->data(), buffer1_data, kHalfSize); 3451 disk_cache::Entry* entry = NULL; 3452 3453 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 3454 EXPECT_NE(null, entry); 3455 3456 int offset = kHalfSize; 3457 int buf_len = kHalfSize; 3458 3459 EXPECT_EQ(buf_len, 3460 WriteData(entry, 0, offset, buffer2.get(), buf_len, false)); 3461 offset = 0; 3462 buf_len = kHalfSize; 3463 EXPECT_EQ(buf_len, 3464 WriteData(entry, 0, offset, buffer1.get(), buf_len, false)); 3465 entry->Close(); 3466 3467 disk_cache::Entry* entry2 = NULL; 3468 ASSERT_EQ(net::OK, OpenEntry(key, &entry2)); 3469 EXPECT_EQ(entry, entry2); 3470 3471 scoped_refptr<net::IOBuffer> buffer1_read1(new net::IOBuffer(kSize)); 3472 EXPECT_EQ(kSize, ReadData(entry2, 0, 0, buffer1_read1.get(), kSize)); 3473 EXPECT_EQ(0, memcmp(buffer1->data(), buffer1_read1->data(), kSize)); 3474 3475 // Check that we are not leaking. 3476 ASSERT_NE(entry, null); 3477 EXPECT_TRUE( 3478 static_cast<disk_cache::SimpleEntryImpl*>(entry)->HasOneRef()); 3479 entry->Close(); 3480 entry = NULL; 3481 } 3482 3483 // Test that changing stream1 size does not affect stream0 (stream0 and stream1 3484 // are stored in the same file in Simple Cache). 3485 TEST_F(DiskCacheEntryTest, SimpleCacheStream1SizeChanges) { 3486 SetSimpleCacheMode(); 3487 InitCache(); 3488 disk_cache::Entry* entry = NULL; 3489 const char key[] = "the key"; 3490 const int kSize = 100; 3491 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize)); 3492 scoped_refptr<net::IOBuffer> buffer_read(new net::IOBuffer(kSize)); 3493 CacheTestFillBuffer(buffer->data(), kSize, false); 3494 3495 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 3496 EXPECT_TRUE(entry); 3497 3498 // Write something into stream0. 3499 EXPECT_EQ(kSize, WriteData(entry, 0, 0, buffer.get(), kSize, false)); 3500 EXPECT_EQ(kSize, ReadData(entry, 0, 0, buffer_read.get(), kSize)); 3501 EXPECT_EQ(0, memcmp(buffer->data(), buffer_read->data(), kSize)); 3502 entry->Close(); 3503 3504 // Extend stream1. 3505 ASSERT_EQ(net::OK, OpenEntry(key, &entry)); 3506 int stream1_size = 100; 3507 EXPECT_EQ(0, WriteData(entry, 1, stream1_size, buffer.get(), 0, false)); 3508 EXPECT_EQ(stream1_size, entry->GetDataSize(1)); 3509 entry->Close(); 3510 3511 // Check that stream0 data has not been modified and that the EOF record for 3512 // stream 0 contains a crc. 3513 // The entry needs to be reopened before checking the crc: Open will perform 3514 // the synchronization with the previous Close. This ensures the EOF records 3515 // have been written to disk before we attempt to read them independently. 3516 ASSERT_EQ(net::OK, OpenEntry(key, &entry)); 3517 base::FilePath entry_file0_path = cache_path_.AppendASCII( 3518 disk_cache::simple_util::GetFilenameFromKeyAndFileIndex(key, 0)); 3519 int flags = base::PLATFORM_FILE_READ | base::PLATFORM_FILE_OPEN; 3520 base::PlatformFile entry_file0 = 3521 base::CreatePlatformFile(entry_file0_path, flags, NULL, NULL); 3522 ASSERT_TRUE(entry_file0 != base::kInvalidPlatformFileValue); 3523 3524 int data_size[disk_cache::kSimpleEntryStreamCount] = {kSize, stream1_size, 0}; 3525 int sparse_data_size = 0; 3526 disk_cache::SimpleEntryStat entry_stat( 3527 base::Time::Now(), base::Time::Now(), data_size, sparse_data_size); 3528 int eof_offset = entry_stat.GetEOFOffsetInFile(key, 0); 3529 disk_cache::SimpleFileEOF eof_record; 3530 ASSERT_EQ(static_cast<int>(sizeof(eof_record)), base::ReadPlatformFile( 3531 entry_file0, 3532 eof_offset, 3533 reinterpret_cast<char*>(&eof_record), 3534 sizeof(eof_record))); 3535 EXPECT_EQ(disk_cache::kSimpleFinalMagicNumber, eof_record.final_magic_number); 3536 EXPECT_TRUE((eof_record.flags & disk_cache::SimpleFileEOF::FLAG_HAS_CRC32) == 3537 disk_cache::SimpleFileEOF::FLAG_HAS_CRC32); 3538 3539 buffer_read = new net::IOBuffer(kSize); 3540 EXPECT_EQ(kSize, ReadData(entry, 0, 0, buffer_read.get(), kSize)); 3541 EXPECT_EQ(0, memcmp(buffer->data(), buffer_read->data(), kSize)); 3542 3543 // Shrink stream1. 3544 stream1_size = 50; 3545 EXPECT_EQ(0, WriteData(entry, 1, stream1_size, buffer.get(), 0, true)); 3546 EXPECT_EQ(stream1_size, entry->GetDataSize(1)); 3547 entry->Close(); 3548 3549 // Check that stream0 data has not been modified. 3550 buffer_read = new net::IOBuffer(kSize); 3551 ASSERT_EQ(net::OK, OpenEntry(key, &entry)); 3552 EXPECT_EQ(kSize, ReadData(entry, 0, 0, buffer_read.get(), kSize)); 3553 EXPECT_EQ(0, memcmp(buffer->data(), buffer_read->data(), kSize)); 3554 entry->Close(); 3555 entry = NULL; 3556 } 3557 3558 // Test that writing within the range for which the crc has already been 3559 // computed will properly invalidate the computed crc. 3560 TEST_F(DiskCacheEntryTest, SimpleCacheCRCRewrite) { 3561 // Test sequence: 3562 // Create, Write (big data), Write (small data in the middle), Close. 3563 // Open, Read (all), Close. 3564 SetSimpleCacheMode(); 3565 InitCache(); 3566 disk_cache::Entry* null = NULL; 3567 const char key[] = "the first key"; 3568 3569 const int kHalfSize = 200; 3570 const int kSize = 2 * kHalfSize; 3571 scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize)); 3572 scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kHalfSize)); 3573 CacheTestFillBuffer(buffer1->data(), kSize, false); 3574 CacheTestFillBuffer(buffer2->data(), kHalfSize, false); 3575 3576 disk_cache::Entry* entry = NULL; 3577 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 3578 EXPECT_NE(null, entry); 3579 entry->Close(); 3580 3581 for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) { 3582 ASSERT_EQ(net::OK, OpenEntry(key, &entry)); 3583 int offset = 0; 3584 int buf_len = kSize; 3585 3586 EXPECT_EQ(buf_len, 3587 WriteData(entry, i, offset, buffer1.get(), buf_len, false)); 3588 offset = kHalfSize; 3589 buf_len = kHalfSize; 3590 EXPECT_EQ(buf_len, 3591 WriteData(entry, i, offset, buffer2.get(), buf_len, false)); 3592 entry->Close(); 3593 3594 ASSERT_EQ(net::OK, OpenEntry(key, &entry)); 3595 3596 scoped_refptr<net::IOBuffer> buffer1_read1(new net::IOBuffer(kSize)); 3597 EXPECT_EQ(kSize, ReadData(entry, i, 0, buffer1_read1.get(), kSize)); 3598 EXPECT_EQ(0, memcmp(buffer1->data(), buffer1_read1->data(), kHalfSize)); 3599 EXPECT_EQ( 3600 0, 3601 memcmp(buffer2->data(), buffer1_read1->data() + kHalfSize, kHalfSize)); 3602 3603 entry->Close(); 3604 } 3605 } 3606 3607 bool DiskCacheEntryTest::SimpleCacheThirdStreamFileExists(const char* key) { 3608 int third_stream_file_index = 3609 disk_cache::simple_util::GetFileIndexFromStreamIndex(2); 3610 base::FilePath third_stream_file_path = cache_path_.AppendASCII( 3611 disk_cache::simple_util::GetFilenameFromKeyAndFileIndex( 3612 key, third_stream_file_index)); 3613 return PathExists(third_stream_file_path); 3614 } 3615 3616 void DiskCacheEntryTest::SyncDoomEntry(const char* key) { 3617 net::TestCompletionCallback callback; 3618 cache_->DoomEntry(key, callback.callback()); 3619 callback.WaitForResult(); 3620 } 3621 3622 // Check that a newly-created entry with no third-stream writes omits the 3623 // third stream file. 3624 TEST_F(DiskCacheEntryTest, SimpleCacheOmittedThirdStream1) { 3625 SetSimpleCacheMode(); 3626 InitCache(); 3627 3628 const char key[] = "key"; 3629 3630 disk_cache::Entry* entry; 3631 3632 // Create entry and close without writing: third stream file should be 3633 // omitted, since the stream is empty. 3634 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 3635 entry->Close(); 3636 EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key)); 3637 3638 SyncDoomEntry(key); 3639 EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key)); 3640 } 3641 3642 // Check that a newly-created entry with only a single zero-offset, zero-length 3643 // write omits the third stream file. 3644 TEST_F(DiskCacheEntryTest, SimpleCacheOmittedThirdStream2) { 3645 SetSimpleCacheMode(); 3646 InitCache(); 3647 3648 const int kHalfSize = 8; 3649 const int kSize = kHalfSize * 2; 3650 const char key[] = "key"; 3651 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize)); 3652 CacheTestFillBuffer(buffer->data(), kHalfSize, false); 3653 3654 disk_cache::Entry* entry; 3655 3656 // Create entry, write empty buffer to third stream, and close: third stream 3657 // should still be omitted, since the entry ignores writes that don't modify 3658 // data or change the length. 3659 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 3660 EXPECT_EQ(0, WriteData(entry, 2, 0, buffer, 0, true)); 3661 entry->Close(); 3662 EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key)); 3663 3664 SyncDoomEntry(key); 3665 EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key)); 3666 } 3667 3668 // Check that we can read back data written to the third stream. 3669 TEST_F(DiskCacheEntryTest, SimpleCacheOmittedThirdStream3) { 3670 SetSimpleCacheMode(); 3671 InitCache(); 3672 3673 const int kHalfSize = 8; 3674 const int kSize = kHalfSize * 2; 3675 const char key[] = "key"; 3676 scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize)); 3677 scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize)); 3678 CacheTestFillBuffer(buffer1->data(), kHalfSize, false); 3679 3680 disk_cache::Entry* entry; 3681 3682 // Create entry, write data to third stream, and close: third stream should 3683 // not be omitted, since it contains data. Re-open entry and ensure there 3684 // are that many bytes in the third stream. 3685 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 3686 EXPECT_EQ(kHalfSize, WriteData(entry, 2, 0, buffer1, kHalfSize, true)); 3687 entry->Close(); 3688 EXPECT_TRUE(SimpleCacheThirdStreamFileExists(key)); 3689 3690 ASSERT_EQ(net::OK, OpenEntry(key, &entry)); 3691 EXPECT_EQ(kHalfSize, ReadData(entry, 2, 0, buffer2, kSize)); 3692 EXPECT_EQ(0, memcmp(buffer1->data(), buffer2->data(), kHalfSize)); 3693 entry->Close(); 3694 EXPECT_TRUE(SimpleCacheThirdStreamFileExists(key)); 3695 3696 SyncDoomEntry(key); 3697 EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key)); 3698 } 3699 3700 // Check that we remove the third stream file upon opening an entry and finding 3701 // the third stream empty. (This is the upgrade path for entries written 3702 // before the third stream was optional.) 3703 TEST_F(DiskCacheEntryTest, SimpleCacheOmittedThirdStream4) { 3704 SetSimpleCacheMode(); 3705 InitCache(); 3706 3707 const int kHalfSize = 8; 3708 const int kSize = kHalfSize * 2; 3709 const char key[] = "key"; 3710 scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize)); 3711 scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize)); 3712 CacheTestFillBuffer(buffer1->data(), kHalfSize, false); 3713 3714 disk_cache::Entry* entry; 3715 3716 // Create entry, write data to third stream, truncate third stream back to 3717 // empty, and close: third stream will not initially be omitted, since entry 3718 // creates the file when the first significant write comes in, and only 3719 // removes it on open if it is empty. Reopen, ensure that the file is 3720 // deleted, and that there's no data in the third stream. 3721 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 3722 EXPECT_EQ(kHalfSize, WriteData(entry, 2, 0, buffer1, kHalfSize, true)); 3723 EXPECT_EQ(0, WriteData(entry, 2, 0, buffer1, 0, true)); 3724 entry->Close(); 3725 EXPECT_TRUE(SimpleCacheThirdStreamFileExists(key)); 3726 3727 ASSERT_EQ(net::OK, OpenEntry(key, &entry)); 3728 EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key)); 3729 EXPECT_EQ(0, ReadData(entry, 2, 0, buffer2, kSize)); 3730 entry->Close(); 3731 EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key)); 3732 3733 SyncDoomEntry(key); 3734 EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key)); 3735 } 3736 3737 // Check that we don't accidentally create the third stream file once the entry 3738 // has been doomed. 3739 TEST_F(DiskCacheEntryTest, SimpleCacheOmittedThirdStream5) { 3740 SetSimpleCacheMode(); 3741 InitCache(); 3742 3743 const int kHalfSize = 8; 3744 const int kSize = kHalfSize * 2; 3745 const char key[] = "key"; 3746 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize)); 3747 CacheTestFillBuffer(buffer->data(), kHalfSize, false); 3748 3749 disk_cache::Entry* entry; 3750 3751 // Create entry, doom entry, write data to third stream, and close: third 3752 // stream should not exist. (Note: We don't care if the write fails, just 3753 // that it doesn't cause the file to be created on disk.) 3754 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 3755 entry->Doom(); 3756 WriteData(entry, 2, 0, buffer, kHalfSize, true); 3757 entry->Close(); 3758 EXPECT_FALSE(SimpleCacheThirdStreamFileExists(key)); 3759 } 3760 3761 // There could be a race between Doom and an optimistic write. 3762 TEST_F(DiskCacheEntryTest, SimpleCacheDoomOptimisticWritesRace) { 3763 // Test sequence: 3764 // Create, first Write, second Write, Close. 3765 // Open, Close. 3766 SetSimpleCacheMode(); 3767 InitCache(); 3768 disk_cache::Entry* null = NULL; 3769 const char key[] = "the first key"; 3770 3771 const int kSize = 200; 3772 scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize)); 3773 scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize)); 3774 CacheTestFillBuffer(buffer1->data(), kSize, false); 3775 CacheTestFillBuffer(buffer2->data(), kSize, false); 3776 3777 // The race only happens on stream 1 and stream 2. 3778 for (int i = 0; i < disk_cache::kSimpleEntryStreamCount; ++i) { 3779 ASSERT_EQ(net::OK, DoomAllEntries()); 3780 disk_cache::Entry* entry = NULL; 3781 3782 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 3783 EXPECT_NE(null, entry); 3784 entry->Close(); 3785 entry = NULL; 3786 3787 ASSERT_EQ(net::OK, DoomAllEntries()); 3788 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 3789 EXPECT_NE(null, entry); 3790 3791 int offset = 0; 3792 int buf_len = kSize; 3793 // This write should not be optimistic (since create is). 3794 EXPECT_EQ(buf_len, 3795 WriteData(entry, i, offset, buffer1.get(), buf_len, false)); 3796 3797 offset = kSize; 3798 // This write should be optimistic. 3799 EXPECT_EQ(buf_len, 3800 WriteData(entry, i, offset, buffer2.get(), buf_len, false)); 3801 entry->Close(); 3802 3803 ASSERT_EQ(net::OK, OpenEntry(key, &entry)); 3804 EXPECT_NE(null, entry); 3805 3806 entry->Close(); 3807 entry = NULL; 3808 } 3809 } 3810 3811 TEST_F(DiskCacheEntryTest, SimpleCacheBasicSparseIO) { 3812 SetSimpleCacheMode(); 3813 InitCache(); 3814 BasicSparseIO(); 3815 } 3816 3817 TEST_F(DiskCacheEntryTest, SimpleCacheHugeSparseIO) { 3818 SetSimpleCacheMode(); 3819 InitCache(); 3820 HugeSparseIO(); 3821 } 3822 3823 TEST_F(DiskCacheEntryTest, SimpleCacheGetAvailableRange) { 3824 SetSimpleCacheMode(); 3825 InitCache(); 3826 GetAvailableRange(); 3827 } 3828 3829 TEST_F(DiskCacheEntryTest, DISABLED_SimpleCacheCouldBeSparse) { 3830 SetSimpleCacheMode(); 3831 InitCache(); 3832 CouldBeSparse(); 3833 } 3834 3835 TEST_F(DiskCacheEntryTest, SimpleCacheUpdateSparseEntry) { 3836 SetSimpleCacheMode(); 3837 InitCache(); 3838 UpdateSparseEntry(); 3839 } 3840 3841 TEST_F(DiskCacheEntryTest, SimpleCacheDoomSparseEntry) { 3842 SetSimpleCacheMode(); 3843 InitCache(); 3844 DoomSparseEntry(); 3845 } 3846 3847 TEST_F(DiskCacheEntryTest, SimpleCachePartialSparseEntry) { 3848 SetSimpleCacheMode(); 3849 InitCache(); 3850 PartialSparseEntry(); 3851 } 3852 3853 TEST_F(DiskCacheEntryTest, SimpleCacheTruncateLargeSparseFile) { 3854 const int kSize = 1024; 3855 3856 SetSimpleCacheMode(); 3857 // An entry is allowed sparse data 1/10 the size of the cache, so this size 3858 // allows for one |kSize|-sized range plus overhead, but not two ranges. 3859 SetMaxSize(kSize * 15); 3860 InitCache(); 3861 3862 const char key[] = "key"; 3863 disk_cache::Entry* null = NULL; 3864 disk_cache::Entry* entry; 3865 ASSERT_EQ(net::OK, CreateEntry(key, &entry)); 3866 EXPECT_NE(null, entry); 3867 3868 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(kSize)); 3869 CacheTestFillBuffer(buffer->data(), kSize, false); 3870 net::TestCompletionCallback callback; 3871 int ret; 3872 3873 // Verify initial conditions. 3874 ret = entry->ReadSparseData(0, buffer, kSize, callback.callback()); 3875 EXPECT_EQ(0, callback.GetResult(ret)); 3876 3877 ret = entry->ReadSparseData(kSize, buffer, kSize, callback.callback()); 3878 EXPECT_EQ(0, callback.GetResult(ret)); 3879 3880 // Write a range and make sure it reads back. 3881 ret = entry->WriteSparseData(0, buffer, kSize, callback.callback()); 3882 EXPECT_EQ(kSize, callback.GetResult(ret)); 3883 3884 ret = entry->ReadSparseData(0, buffer, kSize, callback.callback()); 3885 EXPECT_EQ(kSize, callback.GetResult(ret)); 3886 3887 // Write another range and make sure it reads back. 3888 ret = entry->WriteSparseData(kSize, buffer, kSize, callback.callback()); 3889 EXPECT_EQ(kSize, callback.GetResult(ret)); 3890 3891 ret = entry->ReadSparseData(kSize, buffer, kSize, callback.callback()); 3892 EXPECT_EQ(kSize, callback.GetResult(ret)); 3893 3894 // Make sure the first range was removed when the second was written. 3895 ret = entry->ReadSparseData(0, buffer, kSize, callback.callback()); 3896 EXPECT_EQ(0, callback.GetResult(ret)); 3897 3898 entry->Close(); 3899 } 3900 3901 #endif // defined(OS_POSIX) 3902