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

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

Issue 165174: Try again: Check blockfile size before attempting to read the header. (Closed)
Patch Set: Created 11 years, 4 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
« no previous file with comments | « net/disk_cache/block_files.cc ('k') | no next file » | 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) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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/file_util.h" 5 #include "base/file_util.h"
6 #include "net/disk_cache/block_files.h" 6 #include "net/disk_cache/block_files.h"
7 #include "net/disk_cache/disk_cache.h" 7 #include "net/disk_cache/disk_cache.h"
8 #include "net/disk_cache/disk_cache_test_base.h" 8 #include "net/disk_cache/disk_cache_test_base.h"
9 #include "net/disk_cache/disk_cache_test_util.h" 9 #include "net/disk_cache/disk_cache_test_util.h"
10 #include "testing/gtest/include/gtest/gtest.h" 10 #include "testing/gtest/include/gtest/gtest.h"
11 11
12 using base::Time; 12 using base::Time;
13 13
14 namespace { 14 namespace {
15 15
16 // Returns the number of files in this folder. 16 // Returns the number of files in this folder.
17 int NumberOfFiles(const std::wstring& path) { 17 int NumberOfFiles(const std::wstring& path) {
18 file_util::FileEnumerator iter(FilePath::FromWStringHack(path), false, 18 file_util::FileEnumerator iter(FilePath::FromWStringHack(path), false,
19 file_util::FileEnumerator::FILES); 19 file_util::FileEnumerator::FILES);
20 int count = 0; 20 int count = 0;
21 for (FilePath file = iter.Next(); !file.value().empty(); file = iter.Next()) { 21 for (FilePath file = iter.Next(); !file.value().empty(); file = iter.Next()) {
22 count++; 22 count++;
23 } 23 }
24 return count; 24 return count;
25 } 25 }
26 26
27 } // namespace; 27 } // namespace;
28 28
29 namespace disk_cache {
30
29 TEST_F(DiskCacheTest, BlockFiles_Grow) { 31 TEST_F(DiskCacheTest, BlockFiles_Grow) {
30 std::wstring path = GetCachePath(); 32 std::wstring path = GetCachePath();
31 ASSERT_TRUE(DeleteCache(path.c_str())); 33 ASSERT_TRUE(DeleteCache(path.c_str()));
32 ASSERT_TRUE(file_util::CreateDirectory(path)); 34 ASSERT_TRUE(file_util::CreateDirectory(path));
33 35
34 disk_cache::BlockFiles files(path); 36 BlockFiles files(path);
35 ASSERT_TRUE(files.Init(true)); 37 ASSERT_TRUE(files.Init(true));
36 38
37 const int kMaxSize = 35000; 39 const int kMaxSize = 35000;
38 disk_cache::Addr address[kMaxSize]; 40 Addr address[kMaxSize];
39 41
40 // Fill up the 32-byte block file (use three files). 42 // Fill up the 32-byte block file (use three files).
41 for (int i = 0; i < kMaxSize; i++) { 43 for (int i = 0; i < kMaxSize; i++) {
42 EXPECT_TRUE(files.CreateBlock(disk_cache::RANKINGS, 4, &address[i])); 44 EXPECT_TRUE(files.CreateBlock(RANKINGS, 4, &address[i]));
43 } 45 }
44 EXPECT_EQ(6, NumberOfFiles(path)); 46 EXPECT_EQ(6, NumberOfFiles(path));
45 47
46 // Make sure we don't keep adding files. 48 // Make sure we don't keep adding files.
47 for (int i = 0; i < kMaxSize * 4; i += 2) { 49 for (int i = 0; i < kMaxSize * 4; i += 2) {
48 int target = i % kMaxSize; 50 int target = i % kMaxSize;
49 files.DeleteBlock(address[target], false); 51 files.DeleteBlock(address[target], false);
50 EXPECT_TRUE(files.CreateBlock(disk_cache::RANKINGS, 4, &address[target])); 52 EXPECT_TRUE(files.CreateBlock(RANKINGS, 4, &address[target]));
51 } 53 }
52 EXPECT_EQ(6, NumberOfFiles(path)); 54 EXPECT_EQ(6, NumberOfFiles(path));
53 } 55 }
54 56
55 // We should be able to delete empty block files. 57 // We should be able to delete empty block files.
56 TEST_F(DiskCacheTest, BlockFiles_Shrink) { 58 TEST_F(DiskCacheTest, BlockFiles_Shrink) {
57 std::wstring path = GetCachePath(); 59 std::wstring path = GetCachePath();
58 ASSERT_TRUE(DeleteCache(path.c_str())); 60 ASSERT_TRUE(DeleteCache(path.c_str()));
59 ASSERT_TRUE(file_util::CreateDirectory(path)); 61 ASSERT_TRUE(file_util::CreateDirectory(path));
60 62
61 disk_cache::BlockFiles files(path); 63 BlockFiles files(path);
62 ASSERT_TRUE(files.Init(true)); 64 ASSERT_TRUE(files.Init(true));
63 65
64 const int kMaxSize = 35000; 66 const int kMaxSize = 35000;
65 disk_cache::Addr address[kMaxSize]; 67 Addr address[kMaxSize];
66 68
67 // Fill up the 32-byte block file (use three files). 69 // Fill up the 32-byte block file (use three files).
68 for (int i = 0; i < kMaxSize; i++) { 70 for (int i = 0; i < kMaxSize; i++) {
69 EXPECT_TRUE(files.CreateBlock(disk_cache::RANKINGS, 4, &address[i])); 71 EXPECT_TRUE(files.CreateBlock(RANKINGS, 4, &address[i]));
70 } 72 }
71 73
72 // Now delete all the blocks, so that we can delete the two extra files. 74 // Now delete all the blocks, so that we can delete the two extra files.
73 for (int i = 0; i < kMaxSize; i++) { 75 for (int i = 0; i < kMaxSize; i++) {
74 files.DeleteBlock(address[i], false); 76 files.DeleteBlock(address[i], false);
75 } 77 }
76 EXPECT_EQ(4, NumberOfFiles(path)); 78 EXPECT_EQ(4, NumberOfFiles(path));
77 } 79 }
78 80
79 // Handling of block files not properly closed. 81 // Handling of block files not properly closed.
80 TEST_F(DiskCacheTest, BlockFiles_Recover) { 82 TEST_F(DiskCacheTest, BlockFiles_Recover) {
81 std::wstring path = GetCachePath(); 83 std::wstring path = GetCachePath();
82 ASSERT_TRUE(DeleteCache(path.c_str())); 84 ASSERT_TRUE(DeleteCache(path.c_str()));
83 ASSERT_TRUE(file_util::CreateDirectory(path)); 85 ASSERT_TRUE(file_util::CreateDirectory(path));
84 86
85 disk_cache::BlockFiles files(path); 87 BlockFiles files(path);
86 ASSERT_TRUE(files.Init(true)); 88 ASSERT_TRUE(files.Init(true));
87 89
88 const int kNumEntries = 2000; 90 const int kNumEntries = 2000;
89 disk_cache::CacheAddr entries[kNumEntries]; 91 CacheAddr entries[kNumEntries];
90 92
91 int seed = static_cast<int>(Time::Now().ToInternalValue()); 93 int seed = static_cast<int>(Time::Now().ToInternalValue());
92 srand(seed); 94 srand(seed);
93 for (int i = 0; i < kNumEntries; i++) { 95 for (int i = 0; i < kNumEntries; i++) {
94 disk_cache::Addr address(0); 96 Addr address(0);
95 int size = (rand() % 4) + 1; 97 int size = (rand() % 4) + 1;
96 EXPECT_TRUE(files.CreateBlock(disk_cache::RANKINGS, size, &address)); 98 EXPECT_TRUE(files.CreateBlock(RANKINGS, size, &address));
97 entries[i] = address.value(); 99 entries[i] = address.value();
98 } 100 }
99 101
100 for (int i = 0; i < kNumEntries; i++) { 102 for (int i = 0; i < kNumEntries; i++) {
101 int source1 = rand() % kNumEntries; 103 int source1 = rand() % kNumEntries;
102 int source2 = rand() % kNumEntries; 104 int source2 = rand() % kNumEntries;
103 disk_cache::CacheAddr temp = entries[source1]; 105 CacheAddr temp = entries[source1];
104 entries[source1] = entries[source2]; 106 entries[source1] = entries[source2];
105 entries[source2] = temp; 107 entries[source2] = temp;
106 } 108 }
107 109
108 for (int i = 0; i < kNumEntries / 2; i++) { 110 for (int i = 0; i < kNumEntries / 2; i++) {
109 disk_cache::Addr address(entries[i]); 111 Addr address(entries[i]);
110 files.DeleteBlock(address, false); 112 files.DeleteBlock(address, false);
111 } 113 }
112 114
113 // At this point, there are kNumEntries / 2 entries on the file, randomly 115 // At this point, there are kNumEntries / 2 entries on the file, randomly
114 // distributed both on location and size. 116 // distributed both on location and size.
115 117
116 disk_cache::Addr address(entries[kNumEntries / 2]); 118 Addr address(entries[kNumEntries / 2]);
117 disk_cache::MappedFile* file = files.GetFile(address); 119 MappedFile* file = files.GetFile(address);
118 ASSERT_TRUE(NULL != file); 120 ASSERT_TRUE(NULL != file);
119 121
120 disk_cache::BlockFileHeader* header = 122 BlockFileHeader* header =
121 reinterpret_cast<disk_cache::BlockFileHeader*>(file->buffer()); 123 reinterpret_cast<BlockFileHeader*>(file->buffer());
122 ASSERT_TRUE(NULL != header); 124 ASSERT_TRUE(NULL != header);
123 125
124 ASSERT_EQ(0, header->updating); 126 ASSERT_EQ(0, header->updating);
125 127
126 int max_entries = header->max_entries; 128 int max_entries = header->max_entries;
127 int empty_1 = header->empty[0]; 129 int empty_1 = header->empty[0];
128 int empty_2 = header->empty[1]; 130 int empty_2 = header->empty[1];
129 int empty_3 = header->empty[2]; 131 int empty_3 = header->empty[2];
130 int empty_4 = header->empty[3]; 132 int empty_4 = header->empty[3];
131 133
132 // Corrupt the file. 134 // Corrupt the file.
133 header->max_entries = header->empty[0] = 0; 135 header->max_entries = header->empty[0] = 0;
134 header->empty[1] = header->empty[2] = header->empty[3] = 0; 136 header->empty[1] = header->empty[2] = header->empty[3] = 0;
135 header->updating = -1; 137 header->updating = -1;
136 138
137 files.CloseFiles(); 139 files.CloseFiles();
138 140
139 ASSERT_TRUE(files.Init(false)); 141 ASSERT_TRUE(files.Init(false));
140 142
141 // The file must have been fixed. 143 // The file must have been fixed.
142 file = files.GetFile(address); 144 file = files.GetFile(address);
143 ASSERT_TRUE(NULL != file); 145 ASSERT_TRUE(NULL != file);
144 146
145 header = reinterpret_cast<disk_cache::BlockFileHeader*>(file->buffer()); 147 header = reinterpret_cast<BlockFileHeader*>(file->buffer());
146 ASSERT_TRUE(NULL != header); 148 ASSERT_TRUE(NULL != header);
147 149
148 ASSERT_EQ(0, header->updating); 150 ASSERT_EQ(0, header->updating);
149 151
150 EXPECT_EQ(max_entries, header->max_entries); 152 EXPECT_EQ(max_entries, header->max_entries);
151 EXPECT_EQ(empty_1, header->empty[0]); 153 EXPECT_EQ(empty_1, header->empty[0]);
152 EXPECT_EQ(empty_2, header->empty[1]); 154 EXPECT_EQ(empty_2, header->empty[1]);
153 EXPECT_EQ(empty_3, header->empty[2]); 155 EXPECT_EQ(empty_3, header->empty[2]);
154 EXPECT_EQ(empty_4, header->empty[3]); 156 EXPECT_EQ(empty_4, header->empty[3]);
155 } 157 }
158
159 // Handling of truncated files.
160 TEST_F(DiskCacheTest, BlockFiles_ZeroSizeFile) {
161 std::wstring path = GetCachePath();
162 ASSERT_TRUE(DeleteCache(path.c_str()));
163 ASSERT_TRUE(file_util::CreateDirectory(path));
164
165 BlockFiles files(path);
166 ASSERT_TRUE(files.Init(true));
167
168 std::wstring filename = files.Name(0);
169 files.CloseFiles();
170 // Truncate one of the files.
171 {
172 scoped_refptr<File> file(new File);
173 ASSERT_TRUE(file->Init(filename));
174 EXPECT_TRUE(file->SetLength(0));
175 }
176
177 // Initializing should fail, not crash.
178 ASSERT_FALSE(files.Init(false));
179 }
180
181 } // namespace disk_cache
OLDNEW
« no previous file with comments | « net/disk_cache/block_files.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698