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

Side by Side Diff: net/disk_cache/entry_unittest.cc

Issue 13907009: Support optimistic Create and Write operations on the SimpleCache. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/disk_cache/backend_unittest.cc ('k') | net/disk_cache/simple/simple_entry_impl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/basictypes.h" 5 #include "base/basictypes.h"
6 #include "base/bind.h" 6 #include "base/bind.h"
7 #include "base/bind_helpers.h" 7 #include "base/bind_helpers.h"
8 #include "base/file_util.h" 8 #include "base/file_util.h"
9 #include "base/string_util.h"
10 #include "base/stringprintf.h"
9 #include "base/threading/platform_thread.h" 11 #include "base/threading/platform_thread.h"
10 #include "base/timer.h" 12 #include "base/timer.h"
11 #include "base/string_util.h"
12 #include "base/stringprintf.h"
13 #include "net/base/completion_callback.h" 13 #include "net/base/completion_callback.h"
14 #include "net/base/io_buffer.h" 14 #include "net/base/io_buffer.h"
15 #include "net/base/net_errors.h" 15 #include "net/base/net_errors.h"
16 #include "net/base/test_completion_callback.h" 16 #include "net/base/test_completion_callback.h"
17 #include "net/disk_cache/backend_impl.h" 17 #include "net/disk_cache/backend_impl.h"
18 #include "net/disk_cache/disk_cache_test_base.h" 18 #include "net/disk_cache/disk_cache_test_base.h"
19 #include "net/disk_cache/disk_cache_test_util.h" 19 #include "net/disk_cache/disk_cache_test_util.h"
20 #include "net/disk_cache/entry_impl.h" 20 #include "net/disk_cache/entry_impl.h"
21 #include "net/disk_cache/mem_entry_impl.h" 21 #include "net/disk_cache/mem_entry_impl.h"
22 #include "net/disk_cache/simple/simple_entry_format.h" 22 #include "net/disk_cache/simple/simple_entry_format.h"
23 #include "net/disk_cache/simple/simple_entry_impl.h"
23 #include "net/disk_cache/simple/simple_util.h" 24 #include "net/disk_cache/simple/simple_util.h"
24 #include "testing/gtest/include/gtest/gtest.h" 25 #include "testing/gtest/include/gtest/gtest.h"
25 26
26 using base::Time; 27 using base::Time;
27 28
28 // Tests that can run with different types of caches. 29 // Tests that can run with different types of caches.
29 class DiskCacheEntryTest : public DiskCacheTestWithCache { 30 class DiskCacheEntryTest : public DiskCacheTestWithCache {
30 public: 31 public:
31 void InternalSyncIOBackground(disk_cache::Entry* entry); 32 void InternalSyncIOBackground(disk_cache::Entry* entry);
32 void ExternalSyncIOBackground(disk_cache::Entry* entry); 33 void ExternalSyncIOBackground(disk_cache::Entry* entry);
(...skipping 2385 matching lines...) Expand 10 before | Expand all | Expand 10 after
2418 const base::FilePath entry_path = cache_path_.AppendASCII( 2419 const base::FilePath entry_path = cache_path_.AppendASCII(
2419 disk_cache::simple_util::GetFilenameFromKeyAndIndex(key, 0)); 2420 disk_cache::simple_util::GetFilenameFromKeyAndIndex(key, 0));
2420 const int64 invalid_size = 2421 const int64 invalid_size =
2421 disk_cache::simple_util::GetFileSizeFromKeyAndDataSize(key, 2422 disk_cache::simple_util::GetFileSizeFromKeyAndDataSize(key,
2422 kTruncationBytes); 2423 kTruncationBytes);
2423 EXPECT_TRUE(TruncatePath(entry_path, invalid_size)); 2424 EXPECT_TRUE(TruncatePath(entry_path, invalid_size));
2424 EXPECT_EQ(net::ERR_FAILED, OpenEntry(key, &entry)); 2425 EXPECT_EQ(net::ERR_FAILED, OpenEntry(key, &entry));
2425 DisableIntegrityCheck(); 2426 DisableIntegrityCheck();
2426 } 2427 }
2427 2428
2429 TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic) {
2430 // Test sequence:
2431 // Create, Write, Read, Write, Read, Close.
2432 SetSimpleCacheMode();
2433 InitCache();
2434 disk_cache::Entry* null = NULL;
2435 const char key[] = "the first key";
2436
2437 MessageLoopHelper helper;
2438 CallbackTest callback1(&helper, false);
2439 CallbackTest callback2(&helper, false);
2440 CallbackTest callback3(&helper, false);
2441 CallbackTest callback4(&helper, false);
2442 CallbackTest callback5(&helper, false);
2443
2444 int expected = 0;
2445 const int kSize1 = 10;
2446 const int kSize2 = 20;
2447 scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1));
2448 scoped_refptr<net::IOBuffer> buffer1_read(new net::IOBuffer(kSize1));
2449 scoped_refptr<net::IOBuffer> buffer2(new net::IOBuffer(kSize2));
2450 scoped_refptr<net::IOBuffer> buffer2_read(new net::IOBuffer(kSize2));
2451 CacheTestFillBuffer(buffer1->data(), kSize1, false);
2452 CacheTestFillBuffer(buffer2->data(), kSize2, false);
2453
2454 disk_cache::Entry* entry = NULL;
2455 // Create is optimistic, must return OK.
2456 ASSERT_EQ(net::OK,
2457 cache_->CreateEntry(key, &entry,
2458 base::Bind(&CallbackTest::Run,
2459 base::Unretained(&callback1))));
2460 EXPECT_NE(null, entry);
2461
2462 // This write may or may not be optimistic (it depends if the previous
2463 // optimistic create already finished by the time we call the write here).
2464 int ret = entry->WriteData(
2465 0, 0, buffer1, kSize1,
2466 base::Bind(&CallbackTest::Run, base::Unretained(&callback2)), false);
2467 EXPECT_TRUE(kSize1 == ret || net::ERR_IO_PENDING == ret);
2468 if (net::ERR_IO_PENDING == ret)
2469 expected++;
2470
2471 // This Read must not be optimistic, since we don't support that yet.
2472 EXPECT_EQ(net::ERR_IO_PENDING, entry->ReadData(
2473 0, 0, buffer1_read, kSize1,
2474 base::Bind(&CallbackTest::Run, base::Unretained(&callback3))));
2475 expected++;
2476 EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
2477 EXPECT_EQ(0, memcmp(buffer1->data(), buffer1_read->data(), kSize1));
2478
2479 // At this point after waiting, the pending operations queue on the entry
2480 // should be empty, so the next Write operation must run as optimistic.
2481 EXPECT_EQ(kSize2,
2482 entry->WriteData(
2483 0, 0, buffer2, kSize2,
2484 base::Bind(&CallbackTest::Run,
2485 base::Unretained(&callback4)), false));
2486
2487 // Lets do another read so we block until both the write and the read
2488 // operation finishes and we can then test for HasOneRef() below.
2489 EXPECT_EQ(net::ERR_IO_PENDING, entry->ReadData(
2490 0, 0, buffer2_read, kSize2,
2491 base::Bind(&CallbackTest::Run, base::Unretained(&callback5))));
2492 expected++;
2493
2494 EXPECT_TRUE(helper.WaitUntilCacheIoFinished(expected));
2495 EXPECT_EQ(0, memcmp(buffer2->data(), buffer2_read->data(), kSize2));
2496
2497 // Check that we are not leaking.
2498 EXPECT_NE(entry, null);
2499 EXPECT_TRUE(
2500 static_cast<disk_cache::SimpleEntryImpl*>(entry)->HasOneRef());
2501 entry->Close();
2502 entry = NULL;
2503 }
2504
2505 TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic2) {
2506 // Test sequence:
2507 // Create, Open, Close, Close.
2508 SetSimpleCacheMode();
2509 InitCache();
2510 disk_cache::Entry* null = NULL;
2511 const char key[] = "the first key";
2512
2513 MessageLoopHelper helper;
2514 CallbackTest callback1(&helper, false);
2515 CallbackTest callback2(&helper, false);
2516
2517 disk_cache::Entry* entry = NULL;
2518 ASSERT_EQ(net::OK,
2519 cache_->CreateEntry(key, &entry,
2520 base::Bind(&CallbackTest::Run,
2521 base::Unretained(&callback1))));
2522 EXPECT_NE(null, entry);
2523
2524 disk_cache::Entry* entry2 = NULL;
2525 EXPECT_EQ(net::ERR_IO_PENDING,
2526 cache_->OpenEntry(key, &entry2,
2527 base::Bind(&CallbackTest::Run,
2528 base::Unretained(&callback2))));
2529 EXPECT_TRUE(helper.WaitUntilCacheIoFinished(1));
2530
2531 EXPECT_NE(null, entry2);
2532 EXPECT_EQ(entry, entry2);
2533
2534 // We have to call close twice, since we called create and open above.
2535 entry->Close();
2536
2537 // Check that we are not leaking.
2538 EXPECT_TRUE(
2539 static_cast<disk_cache::SimpleEntryImpl*>(entry)->HasOneRef());
2540 entry->Close();
2541 entry = NULL;
2542 }
2543
2544 TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic3) {
2545 // Test sequence:
2546 // Create, Close, Open, Close.
2547 SetSimpleCacheMode();
2548 InitCache();
2549 disk_cache::Entry* null = NULL;
2550 const char key[] = "the first key";
2551
2552 disk_cache::Entry* entry = NULL;
2553 ASSERT_EQ(net::OK,
2554 cache_->CreateEntry(key, &entry, net::CompletionCallback()));
2555 EXPECT_NE(null, entry);
2556 entry->Close();
2557
2558 net::TestCompletionCallback cb;
2559 disk_cache::Entry* entry2 = NULL;
2560 EXPECT_EQ(net::ERR_IO_PENDING,
2561 cache_->OpenEntry(key, &entry2, cb.callback()));
2562 EXPECT_EQ(net::OK, cb.GetResult(net::ERR_IO_PENDING));
2563
2564 EXPECT_NE(null, entry2);
2565 EXPECT_EQ(entry, entry2);
2566
2567 // Check that we are not leaking.
2568 EXPECT_TRUE(
2569 static_cast<disk_cache::SimpleEntryImpl*>(entry2)->HasOneRef());
2570 entry2->Close();
2571 }
2572
2573 TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic4) {
2574 // Test sequence:
2575 // Create, Close, Write, Open, Open, Close, Write, Read, Close.
2576 SetSimpleCacheMode();
2577 InitCache();
2578 disk_cache::Entry* null = NULL;
2579 const char key[] = "the first key";
2580
2581 net::TestCompletionCallback cb;
2582 const int kSize1 = 10;
2583 scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1));
2584 CacheTestFillBuffer(buffer1->data(), kSize1, false);
2585 disk_cache::Entry* entry = NULL;
2586
2587 ASSERT_EQ(net::OK,
2588 cache_->CreateEntry(key, &entry, net::CompletionCallback()));
2589 EXPECT_NE(null, entry);
2590 entry->Close();
2591
2592 // Lets do a Write so we block until both the Close and the Write
2593 // operation finishes. Write must fail since we are writing in a closed entry.
2594 EXPECT_EQ(net::ERR_IO_PENDING, entry->WriteData(
2595 0, 0, buffer1, kSize1, cb.callback(), false));
2596 EXPECT_EQ(net::ERR_FAILED, cb.GetResult(net::ERR_IO_PENDING));
2597
2598 // Finish running the pending tasks so that we fully complete the close
2599 // operation and destroy the entry object.
2600 MessageLoop::current()->RunUntilIdle();
2601
2602 // At this point the |entry| must have been destroyed, and called
2603 // RemoveSelfFromBackend().
2604 disk_cache::Entry* entry2 = NULL;
2605 EXPECT_EQ(net::ERR_IO_PENDING,
2606 cache_->OpenEntry(key, &entry2, cb.callback()));
2607 EXPECT_EQ(net::OK, cb.GetResult(net::ERR_IO_PENDING));
2608 EXPECT_NE(null, entry2);
2609
2610 disk_cache::Entry* entry3 = NULL;
2611 EXPECT_EQ(net::ERR_IO_PENDING,
2612 cache_->OpenEntry(key, &entry3, cb.callback()));
2613 EXPECT_EQ(net::OK, cb.GetResult(net::ERR_IO_PENDING));
2614 EXPECT_NE(null, entry3);
2615 EXPECT_EQ(entry2, entry3);
2616 entry3->Close();
2617
2618 // The previous Close doesn't actually closes the entry since we opened it
2619 // twice, so the next Write operation must succeed and it must be able to
2620 // perform it optimistically, since there is no operation running on this
2621 // entry.
2622 EXPECT_EQ(kSize1, entry2->WriteData(
2623 0, 0, buffer1, kSize1, net::CompletionCallback(), false));
2624
2625 // Lets do another read so we block until both the write and the read
2626 // operation finishes and we can then test for HasOneRef() below.
2627 EXPECT_EQ(net::ERR_IO_PENDING, entry2->ReadData(
2628 0, 0, buffer1, kSize1, cb.callback()));
2629 EXPECT_EQ(kSize1, cb.GetResult(net::ERR_IO_PENDING));
2630
2631 // Check that we are not leaking.
2632 EXPECT_TRUE(
2633 static_cast<disk_cache::SimpleEntryImpl*>(entry2)->HasOneRef());
2634 entry2->Close();
2635 }
2636
2637 // This test is flaky because of the race of Create followed by a Doom.
2638 // See test SimpleCacheCreateDoomRace.
2639 TEST_F(DiskCacheEntryTest, DISABLED_SimpleCacheOptimistic5) {
2640 // Test sequence:
2641 // Create, Doom, Write, Read, Close.
2642 SetSimpleCacheMode();
2643 InitCache();
2644 disk_cache::Entry* null = NULL;
2645 const char key[] = "the first key";
2646
2647 net::TestCompletionCallback cb;
2648 const int kSize1 = 10;
2649 scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1));
2650 CacheTestFillBuffer(buffer1->data(), kSize1, false);
2651 disk_cache::Entry* entry = NULL;
2652
2653 ASSERT_EQ(net::OK,
2654 cache_->CreateEntry(key, &entry, net::CompletionCallback()));
2655 EXPECT_NE(null, entry);
2656 entry->Doom();
2657
2658 EXPECT_EQ(net::ERR_IO_PENDING, entry->WriteData(
2659 0, 0, buffer1, kSize1, cb.callback(), false));
2660 EXPECT_EQ(kSize1, cb.GetResult(net::ERR_IO_PENDING));
2661
2662 EXPECT_EQ(net::ERR_IO_PENDING, entry->ReadData(
2663 0, 0, buffer1, kSize1, cb.callback()));
2664 EXPECT_EQ(kSize1, cb.GetResult(net::ERR_IO_PENDING));
2665
2666 // Check that we are not leaking.
2667 EXPECT_TRUE(
2668 static_cast<disk_cache::SimpleEntryImpl*>(entry)->HasOneRef());
2669 entry->Close();
2670 }
2671
2672 TEST_F(DiskCacheEntryTest, SimpleCacheOptimistic6) {
2673 // Test sequence:
2674 // Create, Write, Doom, Doom, Read, Doom, Close.
2675 SetSimpleCacheMode();
2676 InitCache();
2677 disk_cache::Entry* null = NULL;
2678 const char key[] = "the first key";
2679
2680 net::TestCompletionCallback cb;
2681 const int kSize1 = 10;
2682 scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1));
2683 scoped_refptr<net::IOBuffer> buffer1_read(new net::IOBuffer(kSize1));
2684 CacheTestFillBuffer(buffer1->data(), kSize1, false);
2685 disk_cache::Entry* entry = NULL;
2686
2687 ASSERT_EQ(net::OK,
2688 cache_->CreateEntry(key, &entry, net::CompletionCallback()));
2689 EXPECT_NE(null, entry);
2690
2691 EXPECT_EQ(net::ERR_IO_PENDING, entry->WriteData(
2692 0, 0, buffer1, kSize1, cb.callback(), false));
2693 EXPECT_EQ(kSize1, cb.GetResult(net::ERR_IO_PENDING));
2694
2695 entry->Doom();
2696 entry->Doom();
2697
2698 // This Read must not be optimistic, since we don't support that yet.
2699 EXPECT_EQ(net::ERR_IO_PENDING, entry->ReadData(
2700 0, 0, buffer1_read, kSize1, cb.callback()));
2701 EXPECT_EQ(kSize1, cb.GetResult(net::ERR_IO_PENDING));
2702 EXPECT_EQ(0, memcmp(buffer1->data(), buffer1_read->data(), kSize1));
2703
2704 entry->Doom();
2705
2706 // Check that we are not leaking.
2707 EXPECT_TRUE(
2708 static_cast<disk_cache::SimpleEntryImpl*>(entry)->HasOneRef());
2709 entry->Close();
2710 }
2711
2712 TEST_F(DiskCacheEntryTest, DISABLED_SimpleCacheCreateDoomRace) {
2713 // Test sequence:
2714 // Create, Doom, Write, Close, Check files are not on disk anymore.
2715 SetSimpleCacheMode();
2716 InitCache();
2717 disk_cache::Entry* null = NULL;
2718 const char key[] = "the first key";
2719
2720 net::TestCompletionCallback cb;
2721 const int kSize1 = 10;
2722 scoped_refptr<net::IOBuffer> buffer1(new net::IOBuffer(kSize1));
2723 CacheTestFillBuffer(buffer1->data(), kSize1, false);
2724 disk_cache::Entry* entry = NULL;
2725
2726 ASSERT_EQ(net::OK,
2727 cache_->CreateEntry(key, &entry, net::CompletionCallback()));
2728 EXPECT_NE(null, entry);
2729
2730 cache_->DoomEntry(key, cb.callback());
2731 EXPECT_EQ(net::OK, cb.GetResult(net::ERR_IO_PENDING));
2732
2733 // Lets do a Write so we block until all operations are done, so we can check
2734 // the HasOneRef() below. This call can't be optimistic and we are checking
2735 // that here.
2736 EXPECT_EQ(net::ERR_IO_PENDING, entry->WriteData(
2737 0, 0, buffer1, kSize1, cb.callback(), false));
2738 EXPECT_EQ(kSize1, cb.GetResult(net::ERR_IO_PENDING));
2739
2740 // Check that we are not leaking.
2741 EXPECT_TRUE(
2742 static_cast<disk_cache::SimpleEntryImpl*>(entry)->HasOneRef());
2743 entry->Close();
2744
2745 // Finish running the pending tasks so that we fully complete the close
2746 // operation and destroy the entry object.
2747 MessageLoop::current()->RunUntilIdle();
2748
2749 for (int i = 0; i < disk_cache::kSimpleEntryFileCount; ++i) {
2750 base::FilePath entry_file_path = cache_path_.AppendASCII(
2751 disk_cache::simple_util::GetFilenameFromKeyAndIndex(key, i));
2752 base::PlatformFileInfo info;
2753 EXPECT_FALSE(file_util::GetFileInfo(entry_file_path, &info));
2754 }
2755 }
2756
2428 // Tests that old entries are evicted while new entries remain in the index. 2757 // Tests that old entries are evicted while new entries remain in the index.
2429 // This test relies on non-mandatory properties of the simple Cache Backend: 2758 // This test relies on non-mandatory properties of the simple Cache Backend:
2430 // LRU eviction, specific values of high-watermark and low-watermark etc. 2759 // LRU eviction, specific values of high-watermark and low-watermark etc.
2431 // When changing the eviction algorithm, the test will have to be re-engineered. 2760 // When changing the eviction algorithm, the test will have to be re-engineered.
2432 TEST_F(DiskCacheEntryTest, SimpleCacheEvictOldEntries) { 2761 TEST_F(DiskCacheEntryTest, SimpleCacheEvictOldEntries) {
2433 const int kMaxSize = 200 * 1024; 2762 const int kMaxSize = 200 * 1024;
2434 const int kWriteSize = kMaxSize / 10; 2763 const int kWriteSize = kMaxSize / 10;
2435 const int kNumExtraEntries = 12; 2764 const int kNumExtraEntries = 12;
2436 SetSimpleCacheMode(); 2765 SetSimpleCacheMode();
2437 SetMaxSize(kMaxSize); 2766 SetMaxSize(kMaxSize);
(...skipping 24 matching lines...) Expand all
2462 // is finished. We are testing the positive case, i.e. when the eviction 2791 // is finished. We are testing the positive case, i.e. when the eviction
2463 // never reaches this entry, should be non-flaky. 2792 // never reaches this entry, should be non-flaky.
2464 ASSERT_EQ(net::OK, OpenEntry(key2 + base::StringPrintf("%d", entry_no), 2793 ASSERT_EQ(net::OK, OpenEntry(key2 + base::StringPrintf("%d", entry_no),
2465 &entry)) 2794 &entry))
2466 << "Should not have evicted fresh entry " << entry_no; 2795 << "Should not have evicted fresh entry " << entry_no;
2467 entry->Close(); 2796 entry->Close();
2468 } 2797 }
2469 } 2798 }
2470 2799
2471 #endif // defined(OS_POSIX) 2800 #endif // defined(OS_POSIX)
OLDNEW
« no previous file with comments | « net/disk_cache/backend_unittest.cc ('k') | net/disk_cache/simple/simple_entry_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698