1d129b9e5870dc7fa49745121bf987e1b6ead1b51Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Use of this source code is governed by a BSD-style license that can be 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// found in the LICENSE file. 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "base/file_util.h" 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/disk_cache/block_files.h" 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/disk_cache/disk_cache.h" 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/disk_cache/disk_cache_test_base.h" 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/disk_cache/disk_cache_test_util.h" 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "testing/gtest/include/gtest/gtest.h" 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottusing base::Time; 13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace { 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Returns the number of files in this folder. 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottint NumberOfFiles(const FilePath& path) { 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott file_util::FileEnumerator iter(path, false, file_util::FileEnumerator::FILES); 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int count = 0; 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (FilePath file = iter.Next(); !file.value().empty(); file = iter.Next()) { 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott count++; 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return count; 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace; 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace disk_cache { 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(DiskCacheTest, BlockFiles_Grow) { 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath path = GetCacheFilePath(); 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ASSERT_TRUE(DeleteCache(path)); 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ASSERT_TRUE(file_util::CreateDirectory(path)); 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott BlockFiles files(path); 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ASSERT_TRUE(files.Init(true)); 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const int kMaxSize = 35000; 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Addr address[kMaxSize]; 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Fill up the 32-byte block file (use three files). 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int i = 0; i < kMaxSize; i++) { 43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(files.CreateBlock(RANKINGS, 4, &address[i])); 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(6, NumberOfFiles(path)); 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Make sure we don't keep adding files. 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int i = 0; i < kMaxSize * 4; i += 2) { 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int target = i % kMaxSize; 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott files.DeleteBlock(address[target], false); 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(files.CreateBlock(RANKINGS, 4, &address[target])); 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(6, NumberOfFiles(path)); 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// We should be able to delete empty block files. 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(DiskCacheTest, BlockFiles_Shrink) { 58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath path = GetCacheFilePath(); 59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ASSERT_TRUE(DeleteCache(path)); 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ASSERT_TRUE(file_util::CreateDirectory(path)); 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott BlockFiles files(path); 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ASSERT_TRUE(files.Init(true)); 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const int kMaxSize = 35000; 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Addr address[kMaxSize]; 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Fill up the 32-byte block file (use three files). 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int i = 0; i < kMaxSize; i++) { 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(files.CreateBlock(RANKINGS, 4, &address[i])); 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Now delete all the blocks, so that we can delete the two extra files. 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int i = 0; i < kMaxSize; i++) { 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott files.DeleteBlock(address[i], false); 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(4, NumberOfFiles(path)); 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Handling of block files not properly closed. 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(DiskCacheTest, BlockFiles_Recover) { 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath path = GetCacheFilePath(); 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ASSERT_TRUE(DeleteCache(path)); 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ASSERT_TRUE(file_util::CreateDirectory(path)); 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott BlockFiles files(path); 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ASSERT_TRUE(files.Init(true)); 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const int kNumEntries = 2000; 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CacheAddr entries[kNumEntries]; 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int seed = static_cast<int>(Time::Now().ToInternalValue()); 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott srand(seed); 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int i = 0; i < kNumEntries; i++) { 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Addr address(0); 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int size = (rand() % 4) + 1; 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(files.CreateBlock(RANKINGS, size, &address)); 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott entries[i] = address.value(); 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int i = 0; i < kNumEntries; i++) { 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int source1 = rand() % kNumEntries; 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int source2 = rand() % kNumEntries; 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CacheAddr temp = entries[source1]; 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott entries[source1] = entries[source2]; 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott entries[source2] = temp; 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott for (int i = 0; i < kNumEntries / 2; i++) { 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Addr address(entries[i]); 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott files.DeleteBlock(address, false); 112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // At this point, there are kNumEntries / 2 entries on the file, randomly 115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // distributed both on location and size. 116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Addr address(entries[kNumEntries / 2]); 118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MappedFile* file = files.GetFile(address); 119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ASSERT_TRUE(NULL != file); 120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott BlockFileHeader* header = 122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott reinterpret_cast<BlockFileHeader*>(file->buffer()); 123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ASSERT_TRUE(NULL != header); 124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ASSERT_EQ(0, header->updating); 126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int max_entries = header->max_entries; 128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int empty_1 = header->empty[0]; 129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int empty_2 = header->empty[1]; 130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int empty_3 = header->empty[2]; 131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott int empty_4 = header->empty[3]; 132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Corrupt the file. 134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott header->max_entries = header->empty[0] = 0; 135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott header->empty[1] = header->empty[2] = header->empty[3] = 0; 136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott header->updating = -1; 137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott files.CloseFiles(); 139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ASSERT_TRUE(files.Init(false)); 141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The file must have been fixed. 143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott file = files.GetFile(address); 144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ASSERT_TRUE(NULL != file); 145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott header = reinterpret_cast<BlockFileHeader*>(file->buffer()); 147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ASSERT_TRUE(NULL != header); 148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ASSERT_EQ(0, header->updating); 150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(max_entries, header->max_entries); 152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(empty_1, header->empty[0]); 153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(empty_2, header->empty[1]); 154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(empty_3, header->empty[2]); 155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(empty_4, header->empty[3]); 156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// Handling of truncated files. 159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(DiskCacheTest, BlockFiles_ZeroSizeFile) { 160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath path = GetCacheFilePath(); 161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ASSERT_TRUE(DeleteCache(path)); 162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ASSERT_TRUE(file_util::CreateDirectory(path)); 163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott BlockFiles files(path); 165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ASSERT_TRUE(files.Init(true)); 166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath filename = files.Name(0); 168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott files.CloseFiles(); 169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Truncate one of the files. 170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott { 171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott scoped_refptr<File> file(new File); 172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ASSERT_TRUE(file->Init(filename)); 173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(file->SetLength(0)); 174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Initializing should fail, not crash. 177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ASSERT_FALSE(files.Init(false)); 178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 180d129b9e5870dc7fa49745121bf987e1b6ead1b51Kristian Monsen// Handling of truncated files (non empty). 181d129b9e5870dc7fa49745121bf987e1b6ead1b51Kristian MonsenTEST_F(DiskCacheTest, BlockFiles_TruncatedFile) { 182d129b9e5870dc7fa49745121bf987e1b6ead1b51Kristian Monsen FilePath path = GetCacheFilePath(); 183d129b9e5870dc7fa49745121bf987e1b6ead1b51Kristian Monsen ASSERT_TRUE(DeleteCache(path)); 184d129b9e5870dc7fa49745121bf987e1b6ead1b51Kristian Monsen ASSERT_TRUE(file_util::CreateDirectory(path)); 185d129b9e5870dc7fa49745121bf987e1b6ead1b51Kristian Monsen 186d129b9e5870dc7fa49745121bf987e1b6ead1b51Kristian Monsen BlockFiles files(path); 187d129b9e5870dc7fa49745121bf987e1b6ead1b51Kristian Monsen ASSERT_TRUE(files.Init(true)); 188d129b9e5870dc7fa49745121bf987e1b6ead1b51Kristian Monsen Addr address; 189d129b9e5870dc7fa49745121bf987e1b6ead1b51Kristian Monsen EXPECT_TRUE(files.CreateBlock(RANKINGS, 2, &address)); 190d129b9e5870dc7fa49745121bf987e1b6ead1b51Kristian Monsen 191d129b9e5870dc7fa49745121bf987e1b6ead1b51Kristian Monsen FilePath filename = files.Name(0); 192d129b9e5870dc7fa49745121bf987e1b6ead1b51Kristian Monsen files.CloseFiles(); 193d129b9e5870dc7fa49745121bf987e1b6ead1b51Kristian Monsen // Truncate one of the files. 194d129b9e5870dc7fa49745121bf987e1b6ead1b51Kristian Monsen { 195d129b9e5870dc7fa49745121bf987e1b6ead1b51Kristian Monsen scoped_refptr<File> file(new File); 196d129b9e5870dc7fa49745121bf987e1b6ead1b51Kristian Monsen ASSERT_TRUE(file->Init(filename)); 197d129b9e5870dc7fa49745121bf987e1b6ead1b51Kristian Monsen EXPECT_TRUE(file->SetLength(15000)); 198d129b9e5870dc7fa49745121bf987e1b6ead1b51Kristian Monsen } 199d129b9e5870dc7fa49745121bf987e1b6ead1b51Kristian Monsen 200d129b9e5870dc7fa49745121bf987e1b6ead1b51Kristian Monsen // Initializing should fail, not crash. 201d129b9e5870dc7fa49745121bf987e1b6ead1b51Kristian Monsen ASSERT_FALSE(files.Init(false)); 202d129b9e5870dc7fa49745121bf987e1b6ead1b51Kristian Monsen} 203d129b9e5870dc7fa49745121bf987e1b6ead1b51Kristian Monsen 204c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// An invalid file can be detected after init. 205c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick ScottTEST_F(DiskCacheTest, BlockFiles_InvalidFile) { 206c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath path = GetCacheFilePath(); 207c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ASSERT_TRUE(DeleteCache(path)); 208c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ASSERT_TRUE(file_util::CreateDirectory(path)); 209c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 210c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott BlockFiles files(path); 211c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ASSERT_TRUE(files.Init(true)); 212c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 213c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Let's access block 10 of file 5. (There is no file). 214c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Addr addr(BLOCK_256, 1, 5, 10); 215c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(NULL == files.GetFile(addr)); 216c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 217c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Let's create an invalid file. 218c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott FilePath filename(files.Name(5)); 219c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott char header[kBlockHeaderSize]; 220c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott memset(header, 'a', kBlockHeaderSize); 221c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_EQ(kBlockHeaderSize, 222c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott file_util::WriteFile(filename, header, kBlockHeaderSize)); 223c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 224c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(NULL == files.GetFile(addr)); 225c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 226c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // The file should not have been cached (it is still invalid). 227c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott EXPECT_TRUE(NULL == files.GetFile(addr)); 228c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} 229c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests that we generate the correct file stats. 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(DiskCacheTest, BlockFiles_Stats) { 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(CopyTestCache("remove_load1")); 233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch FilePath path = GetCacheFilePath(); 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch BlockFiles files(path); 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASSERT_TRUE(files.Init(false)); 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int used, load; 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch files.GetFileStats(0, &used, &load); 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(101, used); 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(9, load); 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch files.GetFileStats(1, &used, &load); 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(203, used); 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(19, load); 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch files.GetFileStats(2, &used, &load); 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(0, used); 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXPECT_EQ(0, load); 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Tests that we add and remove blocks correctly. 2533345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTEST_F(DiskCacheTest, AllocationMap) { 2543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick FilePath path = GetCacheFilePath(); 2553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(DeleteCache(path)); 2563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(file_util::CreateDirectory(path)); 2573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BlockFiles files(path); 2593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT_TRUE(files.Init(true)); 2603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Create a bunch of entries. 2623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const int kSize = 100; 2633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick Addr address[kSize]; 2643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (int i = 0; i < kSize; i++) { 2653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SCOPED_TRACE(i); 2663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int block_size = i % 4 + 1; 2673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(files.CreateBlock(BLOCK_1K, block_size, &address[i])); 2683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(BLOCK_1K, address[i].file_type()); 2693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(block_size, address[i].num_blocks()); 2703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int start = address[i].start_block(); 2713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(start / 4, (start + block_size - 1) / 4); 2723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (int i = 0; i < kSize; i++) { 2753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SCOPED_TRACE(i); 2763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_TRUE(files.IsValid(address[i])); 2773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // The first part of the allocation map should be completely filled. We used 2803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // 10 bits per each four entries, so 250 bits total. 2813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick BlockFileHeader* header = 2823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick reinterpret_cast<BlockFileHeader*>(files.GetFile(address[0])->buffer()); 2833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick uint8* buffer = reinterpret_cast<uint8*>(&header->allocation_map); 2843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (int i =0; i < 29; i++) { 2853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SCOPED_TRACE(i); 2863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(0xff, buffer[i]); 2873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (int i = 0; i < kSize; i++) { 2903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SCOPED_TRACE(i); 2913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick files.DeleteBlock(address[i], false); 2923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // The allocation map should be empty. 2953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (int i =0; i < 50; i++) { 2963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SCOPED_TRACE(i); 2973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXPECT_EQ(0, buffer[i]); 2983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 2993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 3003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 301c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott} // namespace disk_cache 302