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/memory/scoped_ptr.h" 6 #include "net/disk_cache/disk_cache_test_util.h" 7 #include "net/disk_cache/flash/segment.h" 8 #include "net/disk_cache/flash/storage.h" 9 #include "net/disk_cache/flash/flash_cache_test_base.h" 10 #include "net/disk_cache/flash/format.h" 11 #include "testing/gtest/include/gtest/gtest.h" 12 13 namespace { 14 15 template<int SIZE> 16 struct Entry { 17 enum { size = SIZE }; 18 19 Entry() { CacheTestFillBuffer(data, size, false); } 20 21 bool operator==(const Entry& rhs) const { 22 return std::equal(data, data + size, rhs.data); 23 } 24 25 char data[size]; 26 }; 27 28 const int32 kSmallEntrySize = 100; 29 const int32 kLargeEntrySize = disk_cache::kFlashSegmentSize / 4; 30 31 typedef Entry<kSmallEntrySize> SmallEntry; 32 typedef Entry<kLargeEntrySize> LargeEntry; 33 34 const int32 kSegmentFreeSpace = disk_cache::kFlashSegmentSize - 35 disk_cache::kFlashSummarySize; 36 37 } // namespace 38 39 TEST_F(FlashCacheTest, SegmentUserTracking) { 40 disk_cache::Storage storage(path_, kStorageSize); 41 ASSERT_TRUE(storage.Init()); 42 43 scoped_ptr<disk_cache::Segment> segment( 44 new disk_cache::Segment(0, false, &storage)); 45 EXPECT_TRUE(segment->Init()); 46 47 EXPECT_TRUE(segment->HasNoUsers()); 48 segment->AddUser(); 49 segment->AddUser(); 50 EXPECT_FALSE(segment->HasNoUsers()); 51 52 segment->ReleaseUser(); 53 EXPECT_FALSE(segment->HasNoUsers()); 54 segment->ReleaseUser(); 55 EXPECT_TRUE(segment->HasNoUsers()); 56 57 EXPECT_TRUE(segment->Close()); 58 } 59 60 TEST_F(FlashCacheTest, SegmentCreateDestroy) { 61 disk_cache::Storage storage(path_, kStorageSize); 62 ASSERT_TRUE(storage.Init()); 63 64 int32 index = 0; 65 scoped_ptr<disk_cache::Segment> segment( 66 new disk_cache::Segment(index, false, &storage)); 67 EXPECT_TRUE(segment->Init()); 68 EXPECT_TRUE(segment->Close()); 69 70 index = kNumTestSegments - 1; 71 segment.reset(new disk_cache::Segment(index, false, &storage)); 72 EXPECT_TRUE(segment->Init()); 73 EXPECT_TRUE(segment->Close()); 74 75 int32 invalid_index = kNumTestSegments; 76 segment.reset(new disk_cache::Segment(invalid_index, false, &storage)); 77 EXPECT_FALSE(segment->Init()); 78 79 invalid_index = -1; 80 segment.reset(new disk_cache::Segment(invalid_index, false, &storage)); 81 EXPECT_FALSE(segment->Init()); 82 } 83 84 TEST_F(FlashCacheTest, SegmentWriteDataReadData) { 85 disk_cache::Storage storage(path_, kStorageSize); 86 ASSERT_TRUE(storage.Init()); 87 88 int32 index = rand() % kNumTestSegments; 89 scoped_ptr<disk_cache::Segment> segment( 90 new disk_cache::Segment(index, false, &storage)); 91 92 EXPECT_TRUE(segment->Init()); 93 SmallEntry entry1; 94 EXPECT_TRUE(segment->CanHold(entry1.size)); 95 int32 offset = segment->write_offset(); 96 EXPECT_TRUE(segment->WriteData(entry1.data, entry1.size)); 97 segment->StoreOffset(offset); 98 EXPECT_TRUE(segment->Close()); 99 100 segment.reset(new disk_cache::Segment(index, true, &storage)); 101 EXPECT_TRUE(segment->Init()); 102 SmallEntry entry2; 103 EXPECT_TRUE(segment->ReadData(entry2.data, entry2.size, offset)); 104 EXPECT_EQ(entry1, entry2); 105 EXPECT_TRUE(segment->Close()); 106 } 107 108 TEST_F(FlashCacheTest, SegmentFillWithSmallEntries) { 109 disk_cache::Storage storage(path_, kStorageSize); 110 ASSERT_TRUE(storage.Init()); 111 112 int32 index = rand() % kNumTestSegments; 113 scoped_ptr<disk_cache::Segment> segment( 114 new disk_cache::Segment(index, false, &storage)); 115 116 EXPECT_TRUE(segment->Init()); 117 SmallEntry entry; 118 int32 num_bytes_written = 0; 119 while (segment->CanHold(entry.size)) { 120 int32 offset = segment->write_offset(); 121 EXPECT_TRUE(segment->WriteData(entry.data, entry.size)); 122 segment->StoreOffset(offset); 123 num_bytes_written += entry.size; 124 } 125 int32 space_left = kSegmentFreeSpace - num_bytes_written; 126 EXPECT_GE(space_left, entry.size); 127 EXPECT_EQ(segment->GetOffsets().size(), disk_cache::kFlashMaxEntryCount); 128 EXPECT_TRUE(segment->Close()); 129 } 130 131 TEST_F(FlashCacheTest, SegmentFillWithLargeEntries) { 132 disk_cache::Storage storage(path_, kStorageSize); 133 ASSERT_TRUE(storage.Init()); 134 135 int32 index = rand() % kNumTestSegments; 136 scoped_ptr<disk_cache::Segment> segment( 137 new disk_cache::Segment(index, false, &storage)); 138 139 EXPECT_TRUE(segment->Init()); 140 scoped_ptr<LargeEntry> entry(new LargeEntry); 141 int32 num_bytes_written = 0; 142 while (segment->CanHold(entry->size)) { 143 int32 offset = segment->write_offset(); 144 EXPECT_TRUE(segment->WriteData(entry->data, entry->size)); 145 segment->StoreOffset(offset); 146 num_bytes_written += entry->size; 147 } 148 int32 space_left = kSegmentFreeSpace - num_bytes_written; 149 EXPECT_LT(space_left, entry->size); 150 EXPECT_LT(segment->GetOffsets().size(), disk_cache::kFlashMaxEntryCount); 151 EXPECT_TRUE(segment->Close()); 152 } 153