15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/files/file_enumerator.h" 61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "net/disk_cache/blockfile/block_files.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/disk_cache/disk_cache.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/disk_cache/disk_cache_test_base.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/disk_cache/disk_cache_test_util.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::Time; 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the number of files in this folder. 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int NumberOfFiles(const base::FilePath& path) { 19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::FileEnumerator iter(path, false, base::FileEnumerator::FILES); 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int count = 0; 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (base::FilePath file = iter.Next(); !file.value().empty(); 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) file = iter.Next()) { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) count++; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return count; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace disk_cache { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DiskCacheTest, BlockFiles_Grow) { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(CleanupCacheDir()); 34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ASSERT_TRUE(base::CreateDirectory(cache_path_)); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BlockFiles files(cache_path_); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(files.Init(true)); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kMaxSize = 35000; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Addr address[kMaxSize]; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fill up the 32-byte block file (use three files). 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kMaxSize; i++) { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(files.CreateBlock(RANKINGS, 4, &address[i])); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(6, NumberOfFiles(cache_path_)); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure we don't keep adding files. 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kMaxSize * 4; i += 2) { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int target = i % kMaxSize; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) files.DeleteBlock(address[target], false); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(files.CreateBlock(RANKINGS, 4, &address[target])); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(6, NumberOfFiles(cache_path_)); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We should be able to delete empty block files. 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DiskCacheTest, BlockFiles_Shrink) { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(CleanupCacheDir()); 60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ASSERT_TRUE(base::CreateDirectory(cache_path_)); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BlockFiles files(cache_path_); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(files.Init(true)); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kMaxSize = 35000; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Addr address[kMaxSize]; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fill up the 32-byte block file (use three files). 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kMaxSize; i++) { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(files.CreateBlock(RANKINGS, 4, &address[i])); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now delete all the blocks, so that we can delete the two extra files. 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kMaxSize; i++) { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) files.DeleteBlock(address[i], false); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(4, NumberOfFiles(cache_path_)); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Handling of block files not properly closed. 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DiskCacheTest, BlockFiles_Recover) { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(CleanupCacheDir()); 83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ASSERT_TRUE(base::CreateDirectory(cache_path_)); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BlockFiles files(cache_path_); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(files.Init(true)); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kNumEntries = 2000; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CacheAddr entries[kNumEntries]; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int seed = static_cast<int>(Time::Now().ToInternalValue()); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) srand(seed); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kNumEntries; i++) { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Addr address(0); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int size = (rand() % 4) + 1; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(files.CreateBlock(RANKINGS, size, &address)); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries[i] = address.value(); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kNumEntries; i++) { 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int source1 = rand() % kNumEntries; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int source2 = rand() % kNumEntries; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CacheAddr temp = entries[source1]; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries[source1] = entries[source2]; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entries[source2] = temp; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kNumEntries / 2; i++) { 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Addr address(entries[i]); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) files.DeleteBlock(address, false); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // At this point, there are kNumEntries / 2 entries on the file, randomly 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // distributed both on location and size. 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Addr address(entries[kNumEntries / 2]); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MappedFile* file = files.GetFile(address); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(NULL != file); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BlockFileHeader* header = 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<BlockFileHeader*>(file->buffer()); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(NULL != header); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0, header->updating); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int max_entries = header->max_entries; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int empty_1 = header->empty[0]; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int empty_2 = header->empty[1]; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int empty_3 = header->empty[2]; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int empty_4 = header->empty[3]; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Corrupt the file. 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header->max_entries = header->empty[0] = 0; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header->empty[1] = header->empty[2] = header->empty[3] = 0; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header->updating = -1; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) files.CloseFiles(); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(files.Init(false)); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The file must have been fixed. 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file = files.GetFile(address); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(NULL != file); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header = reinterpret_cast<BlockFileHeader*>(file->buffer()); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(NULL != header); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0, header->updating); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(max_entries, header->max_entries); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(empty_1, header->empty[0]); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(empty_2, header->empty[1]); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(empty_3, header->empty[2]); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(empty_4, header->empty[3]); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Handling of truncated files. 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DiskCacheTest, BlockFiles_ZeroSizeFile) { 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(CleanupCacheDir()); 160a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ASSERT_TRUE(base::CreateDirectory(cache_path_)); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BlockFiles files(cache_path_); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(files.Init(true)); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath filename = files.Name(0); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) files.CloseFiles(); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Truncate one of the files. 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<File> file(new File); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(file->Init(filename)); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(file->SetLength(0)); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initializing should fail, not crash. 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(files.Init(false)); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Handling of truncated files (non empty). 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DiskCacheTest, BlockFiles_TruncatedFile) { 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(CleanupCacheDir()); 181a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ASSERT_TRUE(base::CreateDirectory(cache_path_)); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BlockFiles files(cache_path_); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(files.Init(true)); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Addr address; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(files.CreateBlock(RANKINGS, 2, &address)); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath filename = files.Name(0); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) files.CloseFiles(); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Truncate one of the files. 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<File> file(new File); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(file->Init(filename)); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(file->SetLength(15000)); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initializing should fail, not crash. 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(files.Init(false)); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests detection of out of sync counters. 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DiskCacheTest, BlockFiles_Counters) { 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(CleanupCacheDir()); 204a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ASSERT_TRUE(base::CreateDirectory(cache_path_)); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BlockFiles files(cache_path_); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(files.Init(true)); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a block of size 2. 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Addr address(0); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(files.CreateBlock(RANKINGS, 2, &address)); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MappedFile* file = files.GetFile(address); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(NULL != file); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BlockFileHeader* header = reinterpret_cast<BlockFileHeader*>(file->buffer()); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(NULL != header); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0, header->updating); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Alter the counters so that the free space doesn't add up. 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header->empty[2] = 50; // 50 free blocks of size 3. 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) files.CloseFiles(); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(files.Init(false)); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file = files.GetFile(address); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(NULL != file); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header = reinterpret_cast<BlockFileHeader*>(file->buffer()); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(NULL != header); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The file must have been fixed. 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0, header->empty[2]); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Change the number of entries. 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header->num_entries = 3; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header->updating = 1; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) files.CloseFiles(); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(files.Init(false)); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file = files.GetFile(address); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(NULL != file); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header = reinterpret_cast<BlockFileHeader*>(file->buffer()); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(NULL != header); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The file must have been "fixed". 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(2, header->num_entries); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Change the number of entries. 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header->num_entries = -1; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) header->updating = 1; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) files.CloseFiles(); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Detect the error. 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_FALSE(files.Init(false)); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// An invalid file can be detected after init. 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DiskCacheTest, BlockFiles_InvalidFile) { 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(CleanupCacheDir()); 259a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ASSERT_TRUE(base::CreateDirectory(cache_path_)); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BlockFiles files(cache_path_); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(files.Init(true)); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Let's access block 10 of file 5. (There is no file). 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Addr addr(BLOCK_256, 1, 5, 10); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(NULL == files.GetFile(addr)); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Let's create an invalid file. 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath filename(files.Name(5)); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char header[kBlockHeaderSize]; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(header, 'a', kBlockHeaderSize); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(kBlockHeaderSize, 273a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::WriteFile(filename, header, kBlockHeaderSize)); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(NULL == files.GetFile(addr)); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The file should not have been changed (it is still invalid). 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(NULL == files.GetFile(addr)); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that we generate the correct file stats. 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DiskCacheTest, BlockFiles_Stats) { 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(CopyTestCache("remove_load1")); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BlockFiles files(cache_path_); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(files.Init(false)); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int used, load; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) files.GetFileStats(0, &used, &load); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(101, used); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(9, load); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) files.GetFileStats(1, &used, &load); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(203, used); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(19, load); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) files.GetFileStats(2, &used, &load); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, used); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, load); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that we add and remove blocks correctly. 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(DiskCacheTest, AllocationMap) { 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(CleanupCacheDir()); 305a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ASSERT_TRUE(base::CreateDirectory(cache_path_)); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BlockFiles files(cache_path_); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(files.Init(true)); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a bunch of entries. 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kSize = 100; 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Addr address[kSize]; 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kSize; i++) { 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SCOPED_TRACE(i); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int block_size = i % 4 + 1; 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(files.CreateBlock(BLOCK_1K, block_size, &address[i])); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(BLOCK_1K, address[i].file_type()); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(block_size, address[i].num_blocks()); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int start = address[i].start_block(); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(start / 4, (start + block_size - 1) / 4); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kSize; i++) { 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SCOPED_TRACE(i); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(files.IsValid(address[i])); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The first part of the allocation map should be completely filled. We used 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 10 bits per each four entries, so 250 bits total. 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BlockFileHeader* header = 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<BlockFileHeader*>(files.GetFile(address[0])->buffer()); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8* buffer = reinterpret_cast<uint8*>(&header->allocation_map); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i =0; i < 29; i++) { 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SCOPED_TRACE(i); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0xff, buffer[i]); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kSize; i++) { 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SCOPED_TRACE(i); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) files.DeleteBlock(address[i], false); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The allocation map should be empty. 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i =0; i < 50; i++) { 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SCOPED_TRACE(i); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, buffer[i]); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace disk_cache 351