OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2010 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 // This command-line program generates the set of files needed for the crash- | 5 // This command-line program generates the set of files needed for the crash- |
6 // cache unit tests (DiskCacheTest,CacheBackend_Recover*). This program only | 6 // cache unit tests (DiskCacheTest,CacheBackend_Recover*). This program only |
7 // works properly on debug mode, because the crash functionality is not compiled | 7 // works properly on debug mode, because the crash functionality is not compiled |
8 // on release builds of the cache. | 8 // on release builds of the cache. |
9 | 9 |
10 #include <string> | 10 #include <string> |
11 | 11 |
12 #include "base/at_exit.h" | 12 #include "base/at_exit.h" |
13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
14 #include "base/file_util.h" | 14 #include "base/file_util.h" |
15 #include "base/logging.h" | 15 #include "base/logging.h" |
16 #include "base/message_loop.h" | 16 #include "base/message_loop.h" |
17 #include "base/path_service.h" | 17 #include "base/path_service.h" |
18 #include "base/process_util.h" | 18 #include "base/process_util.h" |
19 #include "base/string_util.h" | 19 #include "base/string_util.h" |
20 | 20 #include "base/thread.h" |
| 21 #include "net/base/net_errors.h" |
| 22 #include "net/base/test_completion_callback.h" |
21 #include "net/disk_cache/backend_impl.h" | 23 #include "net/disk_cache/backend_impl.h" |
22 #include "net/disk_cache/disk_cache.h" | 24 #include "net/disk_cache/disk_cache.h" |
23 #include "net/disk_cache/disk_cache_test_util.h" | 25 #include "net/disk_cache/disk_cache_test_util.h" |
24 #include "net/disk_cache/rankings.h" | 26 #include "net/disk_cache/rankings.h" |
25 | 27 |
26 using base::Time; | 28 using base::Time; |
27 | 29 |
28 enum Errors { | 30 enum Errors { |
29 GENERIC = -1, | 31 GENERIC = -1, |
30 ALL_GOOD = 0, | 32 ALL_GOOD = 0, |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 | 112 |
111 *full_path = path.AppendASCII(folders[action]); | 113 *full_path = path.AppendASCII(folders[action]); |
112 | 114 |
113 if (file_util::PathExists(*full_path)) | 115 if (file_util::PathExists(*full_path)) |
114 return false; | 116 return false; |
115 | 117 |
116 return file_util::CreateDirectory(*full_path); | 118 return file_util::CreateDirectory(*full_path); |
117 } | 119 } |
118 | 120 |
119 // Generates the files for an empty and one item cache. | 121 // Generates the files for an empty and one item cache. |
120 int SimpleInsert(const FilePath& path, RankCrashes action) { | 122 int SimpleInsert(const FilePath& path, RankCrashes action, |
121 disk_cache::Backend* cache = disk_cache::CreateCacheBackend(path, false, 0, | 123 base::Thread* cache_thread) { |
122 net::DISK_CACHE); | 124 TestCompletionCallback cb; |
123 if (!cache || cache->GetEntryCount()) | 125 disk_cache::Backend* cache; |
| 126 int rv = disk_cache::CreateCacheBackend(net::DISK_CACHE, path, 0, false, |
| 127 cache_thread->message_loop_proxy(), |
| 128 &cache, &cb); |
| 129 if (cb.GetResult(rv) != net::OK || cache->GetEntryCount()) |
124 return GENERIC; | 130 return GENERIC; |
125 | 131 |
126 const char* test_name = "some other key"; | 132 const char* test_name = "some other key"; |
127 | 133 |
128 if (action <= disk_cache::INSERT_EMPTY_3) { | 134 if (action <= disk_cache::INSERT_EMPTY_3) { |
129 test_name = kCrashEntryName; | 135 test_name = kCrashEntryName; |
130 g_rankings_crash = action; | 136 g_rankings_crash = action; |
131 } | 137 } |
132 | 138 |
133 disk_cache::Entry* entry; | 139 disk_cache::Entry* entry; |
134 if (!cache->CreateEntry(test_name, &entry)) | 140 rv = cache->CreateEntry(test_name, &entry, &cb); |
| 141 if (cb.GetResult(rv) != net::OK) |
135 return GENERIC; | 142 return GENERIC; |
136 | 143 |
137 entry->Close(); | 144 entry->Close(); |
138 | 145 |
139 DCHECK(action <= disk_cache::INSERT_ONE_3); | 146 DCHECK(action <= disk_cache::INSERT_ONE_3); |
140 g_rankings_crash = action; | 147 g_rankings_crash = action; |
141 test_name = kCrashEntryName; | 148 test_name = kCrashEntryName; |
142 | 149 |
143 if (!cache->CreateEntry(test_name, &entry)) | 150 rv = cache->CreateEntry(test_name, &entry, &cb); |
| 151 if (cb.GetResult(rv) != net::OK) |
144 return GENERIC; | 152 return GENERIC; |
145 | 153 |
146 return NOT_REACHED; | 154 return NOT_REACHED; |
147 } | 155 } |
148 | 156 |
149 // Generates the files for a one item cache, and removing the head. | 157 // Generates the files for a one item cache, and removing the head. |
150 int SimpleRemove(const FilePath& path, RankCrashes action) { | 158 int SimpleRemove(const FilePath& path, RankCrashes action, |
| 159 base::Thread* cache_thread) { |
151 DCHECK(action >= disk_cache::REMOVE_ONE_1); | 160 DCHECK(action >= disk_cache::REMOVE_ONE_1); |
152 DCHECK(action <= disk_cache::REMOVE_TAIL_3); | 161 DCHECK(action <= disk_cache::REMOVE_TAIL_3); |
153 | 162 |
154 disk_cache::Backend* cache = disk_cache::CreateCacheBackend(path, false, 0, | 163 TestCompletionCallback cb; |
155 net::DISK_CACHE); | 164 disk_cache::Backend* cache; |
156 if (!cache || cache->GetEntryCount()) | 165 int rv = disk_cache::CreateCacheBackend(net::DISK_CACHE, path, 0, false, |
| 166 cache_thread->message_loop_proxy(), |
| 167 &cache, &cb); |
| 168 if (cb.GetResult(rv) != net::OK || cache->GetEntryCount()) |
157 return GENERIC; | 169 return GENERIC; |
158 | 170 |
159 disk_cache::Entry* entry; | 171 disk_cache::Entry* entry; |
160 if (!cache->CreateEntry(kCrashEntryName, &entry)) | 172 rv = cache->CreateEntry(kCrashEntryName, &entry, &cb); |
| 173 if (cb.GetResult(rv) != net::OK) |
161 return GENERIC; | 174 return GENERIC; |
162 | 175 |
163 entry->Close(); | 176 entry->Close(); |
164 | 177 |
165 if (action >= disk_cache::REMOVE_TAIL_1) { | 178 if (action >= disk_cache::REMOVE_TAIL_1) { |
166 if (!cache->CreateEntry("some other key", &entry)) | 179 rv = cache->CreateEntry("some other key", &entry, &cb); |
| 180 if (cb.GetResult(rv) != net::OK) |
167 return GENERIC; | 181 return GENERIC; |
168 | 182 |
169 entry->Close(); | 183 entry->Close(); |
170 } | 184 } |
171 | 185 |
172 if (!cache->OpenEntry(kCrashEntryName, &entry)) | 186 rv = cache->OpenEntry(kCrashEntryName, &entry, &cb); |
| 187 if (cb.GetResult(rv) != net::OK) |
173 return GENERIC; | 188 return GENERIC; |
174 | 189 |
175 g_rankings_crash = action; | 190 g_rankings_crash = action; |
176 entry->Doom(); | 191 entry->Doom(); |
177 entry->Close(); | 192 entry->Close(); |
178 | 193 |
179 return NOT_REACHED; | 194 return NOT_REACHED; |
180 } | 195 } |
181 | 196 |
182 int HeadRemove(const FilePath& path, RankCrashes action) { | 197 int HeadRemove(const FilePath& path, RankCrashes action, |
| 198 base::Thread* cache_thread) { |
183 DCHECK(action >= disk_cache::REMOVE_HEAD_1); | 199 DCHECK(action >= disk_cache::REMOVE_HEAD_1); |
184 DCHECK(action <= disk_cache::REMOVE_HEAD_4); | 200 DCHECK(action <= disk_cache::REMOVE_HEAD_4); |
185 | 201 |
186 disk_cache::Backend* cache = disk_cache::CreateCacheBackend(path, false, 0, | 202 TestCompletionCallback cb; |
187 net::DISK_CACHE); | 203 disk_cache::Backend* cache; |
188 if (!cache || cache->GetEntryCount()) | 204 int rv = disk_cache::CreateCacheBackend(net::DISK_CACHE, path, 0, false, |
| 205 cache_thread->message_loop_proxy(), |
| 206 &cache, &cb); |
| 207 if (cb.GetResult(rv) != net::OK || cache->GetEntryCount()) |
189 return GENERIC; | 208 return GENERIC; |
190 | 209 |
191 disk_cache::Entry* entry; | 210 disk_cache::Entry* entry; |
192 if (!cache->CreateEntry("some other key", &entry)) | 211 rv = cache->CreateEntry("some other key", &entry, &cb); |
| 212 if (cb.GetResult(rv) != net::OK) |
193 return GENERIC; | 213 return GENERIC; |
194 | 214 |
195 entry->Close(); | 215 entry->Close(); |
196 if (!cache->CreateEntry(kCrashEntryName, &entry)) | 216 rv = cache->CreateEntry(kCrashEntryName, &entry, &cb); |
| 217 if (cb.GetResult(rv) != net::OK) |
197 return GENERIC; | 218 return GENERIC; |
198 | 219 |
199 entry->Close(); | 220 entry->Close(); |
200 | 221 |
201 if (!cache->OpenEntry(kCrashEntryName, &entry)) | 222 rv = cache->OpenEntry(kCrashEntryName, &entry, &cb); |
| 223 if (cb.GetResult(rv) != net::OK) |
202 return GENERIC; | 224 return GENERIC; |
203 | 225 |
204 g_rankings_crash = action; | 226 g_rankings_crash = action; |
205 entry->Doom(); | 227 entry->Doom(); |
206 entry->Close(); | 228 entry->Close(); |
207 | 229 |
208 return NOT_REACHED; | 230 return NOT_REACHED; |
209 } | 231 } |
210 | 232 |
211 // Generates the files for insertion and removals on heavy loaded caches. | 233 // Generates the files for insertion and removals on heavy loaded caches. |
212 int LoadOperations(const FilePath& path, RankCrashes action) { | 234 int LoadOperations(const FilePath& path, RankCrashes action, |
| 235 base::Thread* cache_thread) { |
213 DCHECK(action >= disk_cache::INSERT_LOAD_1); | 236 DCHECK(action >= disk_cache::INSERT_LOAD_1); |
214 | 237 |
215 // Work with a tiny index table (16 entries) | 238 // Work with a tiny index table (16 entries). |
216 disk_cache::BackendImpl* cache = | 239 disk_cache::BackendImpl* cache = new disk_cache::BackendImpl( |
217 new disk_cache::BackendImpl(path, 0xf); | 240 path, 0xf, cache_thread->message_loop_proxy()); |
218 if (!cache || !cache->SetMaxSize(0x100000) || !cache->Init() || | 241 if (!cache || !cache->SetMaxSize(0x100000)) |
219 cache->GetEntryCount()) | 242 return GENERIC; |
| 243 |
| 244 if (!cache->Init() || cache->GetEntryCount()) |
220 return GENERIC; | 245 return GENERIC; |
221 | 246 |
222 int seed = static_cast<int>(Time::Now().ToInternalValue()); | 247 int seed = static_cast<int>(Time::Now().ToInternalValue()); |
223 srand(seed); | 248 srand(seed); |
224 | 249 |
| 250 TestCompletionCallback cb; |
| 251 int rv; |
225 disk_cache::Entry* entry; | 252 disk_cache::Entry* entry; |
226 for (int i = 0; i < 100; i++) { | 253 for (int i = 0; i < 100; i++) { |
227 std::string key = GenerateKey(true); | 254 std::string key = GenerateKey(true); |
228 if (!cache->CreateEntry(key, &entry)) | 255 rv = cache->CreateEntry(key, &entry, &cb); |
| 256 if (cb.GetResult(rv) != net::OK) |
229 return GENERIC; | 257 return GENERIC; |
230 entry->Close(); | 258 entry->Close(); |
231 if (50 == i && action >= disk_cache::REMOVE_LOAD_1) { | 259 if (50 == i && action >= disk_cache::REMOVE_LOAD_1) { |
232 if (!cache->CreateEntry(kCrashEntryName, &entry)) | 260 rv = cache->CreateEntry(kCrashEntryName, &entry, &cb); |
| 261 if (cb.GetResult(rv) != net::OK) |
233 return GENERIC; | 262 return GENERIC; |
234 entry->Close(); | 263 entry->Close(); |
235 } | 264 } |
236 } | 265 } |
237 | 266 |
238 if (action <= disk_cache::INSERT_LOAD_2) { | 267 if (action <= disk_cache::INSERT_LOAD_2) { |
239 g_rankings_crash = action; | 268 g_rankings_crash = action; |
240 | 269 |
241 if (!cache->CreateEntry(kCrashEntryName, &entry)) | 270 rv = cache->CreateEntry(kCrashEntryName, &entry, &cb); |
| 271 if (cb.GetResult(rv) != net::OK) |
242 return GENERIC; | 272 return GENERIC; |
243 } | 273 } |
244 | 274 |
245 if (!cache->OpenEntry(kCrashEntryName, &entry)) | 275 rv = cache->OpenEntry(kCrashEntryName, &entry, &cb); |
| 276 if (cb.GetResult(rv) != net::OK) |
246 return GENERIC; | 277 return GENERIC; |
247 | 278 |
248 g_rankings_crash = action; | 279 g_rankings_crash = action; |
249 | 280 |
250 entry->Doom(); | 281 entry->Doom(); |
251 entry->Close(); | 282 entry->Close(); |
252 | 283 |
253 return NOT_REACHED; | 284 return NOT_REACHED; |
254 } | 285 } |
255 | 286 |
256 // Main function on the child process. | 287 // Main function on the child process. |
257 int SlaveCode(const FilePath& path, RankCrashes action) { | 288 int SlaveCode(const FilePath& path, RankCrashes action) { |
258 MessageLoop message_loop; | 289 MessageLoopForIO message_loop; |
259 | 290 |
260 FilePath full_path; | 291 FilePath full_path; |
261 if (!CreateTargetFolder(path, action, &full_path)) { | 292 if (!CreateTargetFolder(path, action, &full_path)) { |
262 printf("Destination folder found, please remove it.\n"); | 293 printf("Destination folder found, please remove it.\n"); |
263 return CRASH_OVERWRITE; | 294 return CRASH_OVERWRITE; |
264 } | 295 } |
265 | 296 |
| 297 base::Thread cache_thread("CacheThread"); |
| 298 if (!cache_thread.StartWithOptions( |
| 299 base::Thread::Options(MessageLoop::TYPE_IO, 0))) |
| 300 return GENERIC; |
| 301 |
266 if (action <= disk_cache::INSERT_ONE_3) | 302 if (action <= disk_cache::INSERT_ONE_3) |
267 return SimpleInsert(full_path, action); | 303 return SimpleInsert(full_path, action, &cache_thread); |
268 | 304 |
269 if (action <= disk_cache::INSERT_LOAD_2) | 305 if (action <= disk_cache::INSERT_LOAD_2) |
270 return LoadOperations(full_path, action); | 306 return LoadOperations(full_path, action, &cache_thread); |
271 | 307 |
272 if (action <= disk_cache::REMOVE_ONE_4) | 308 if (action <= disk_cache::REMOVE_ONE_4) |
273 return SimpleRemove(full_path, action); | 309 return SimpleRemove(full_path, action, &cache_thread); |
274 | 310 |
275 if (action <= disk_cache::REMOVE_HEAD_4) | 311 if (action <= disk_cache::REMOVE_HEAD_4) |
276 return HeadRemove(full_path, action); | 312 return HeadRemove(full_path, action, &cache_thread); |
277 | 313 |
278 if (action <= disk_cache::REMOVE_TAIL_3) | 314 if (action <= disk_cache::REMOVE_TAIL_3) |
279 return SimpleRemove(full_path, action); | 315 return SimpleRemove(full_path, action, &cache_thread); |
280 | 316 |
281 if (action <= disk_cache::REMOVE_LOAD_3) | 317 if (action <= disk_cache::REMOVE_LOAD_3) |
282 return LoadOperations(full_path, action); | 318 return LoadOperations(full_path, action, &cache_thread); |
283 | 319 |
284 return NOT_REACHED; | 320 return NOT_REACHED; |
285 } | 321 } |
286 | 322 |
287 // ----------------------------------------------------------------------- | 323 // ----------------------------------------------------------------------- |
288 | 324 |
289 int main(int argc, const char* argv[]) { | 325 int main(int argc, const char* argv[]) { |
290 // Setup an AtExitManager so Singleton objects will be destructed. | 326 // Setup an AtExitManager so Singleton objects will be destructed. |
291 base::AtExitManager at_exit_manager; | 327 base::AtExitManager at_exit_manager; |
292 | 328 |
293 if (argc < 2) | 329 if (argc < 2) |
294 return MasterCode(); | 330 return MasterCode(); |
295 | 331 |
296 char* end; | 332 char* end; |
297 RankCrashes action = static_cast<RankCrashes>(strtol(argv[1], &end, 0)); | 333 RankCrashes action = static_cast<RankCrashes>(strtol(argv[1], &end, 0)); |
298 if (action <= disk_cache::NO_CRASH || action >= disk_cache::MAX_CRASH) { | 334 if (action <= disk_cache::NO_CRASH || action >= disk_cache::MAX_CRASH) { |
299 printf("Invalid action\n"); | 335 printf("Invalid action\n"); |
300 return INVALID_ARGUMENT; | 336 return INVALID_ARGUMENT; |
301 } | 337 } |
302 | 338 |
303 FilePath path; | 339 FilePath path; |
304 PathService::Get(base::DIR_SOURCE_ROOT, &path); | 340 PathService::Get(base::DIR_SOURCE_ROOT, &path); |
305 path = path.AppendASCII("net"); | 341 path = path.AppendASCII("net"); |
306 path = path.AppendASCII("data"); | 342 path = path.AppendASCII("data"); |
307 path = path.AppendASCII("cache_tests"); | 343 path = path.AppendASCII("cache_tests"); |
308 path = path.AppendASCII("new_crashes"); | 344 path = path.AppendASCII("new_crashes"); |
309 | 345 |
310 return SlaveCode(path, action); | 346 return SlaveCode(path, action); |
311 } | 347 } |
OLD | NEW |