1 // Copyright (c) 2006-2009 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 "net/disk_cache/disk_cache_test_util.h" 6 7 #include "base/logging.h" 8 #include "base/file_util.h" 9 #include "base/path_service.h" 10 #include "net/disk_cache/backend_impl.h" 11 #include "net/disk_cache/cache_util.h" 12 #include "net/disk_cache/file.h" 13 14 using base::Time; 15 using base::TimeDelta; 16 17 namespace { 18 19 FilePath BuildCachePath(const std::string& name) { 20 FilePath path; 21 PathService::Get(base::DIR_TEMP, &path); // Ignore return value; 22 path = path.AppendASCII(name); 23 if (!file_util::PathExists(path)) 24 file_util::CreateDirectory(path); 25 26 return path; 27 } 28 29 } // namespace. 30 31 std::string GenerateKey(bool same_length) { 32 char key[200]; 33 CacheTestFillBuffer(key, sizeof(key), same_length); 34 35 key[199] = '\0'; 36 return std::string(key); 37 } 38 39 void CacheTestFillBuffer(char* buffer, size_t len, bool no_nulls) { 40 static bool called = false; 41 if (!called) { 42 called = true; 43 int seed = static_cast<int>(Time::Now().ToInternalValue()); 44 srand(seed); 45 } 46 47 for (size_t i = 0; i < len; i++) { 48 buffer[i] = static_cast<char>(rand()); 49 if (!buffer[i] && no_nulls) 50 buffer[i] = 'g'; 51 } 52 if (len && !buffer[0]) 53 buffer[0] = 'g'; 54 } 55 56 FilePath GetCacheFilePath() { 57 return BuildCachePath("cache_test"); 58 } 59 60 bool CreateCacheTestFile(const FilePath& name) { 61 int flags = base::PLATFORM_FILE_CREATE_ALWAYS | 62 base::PLATFORM_FILE_READ | 63 base::PLATFORM_FILE_WRITE; 64 65 scoped_refptr<disk_cache::File> file(new disk_cache::File( 66 base::CreatePlatformFile(name, flags, NULL))); 67 if (!file->IsValid()) 68 return false; 69 70 file->SetLength(4 * 1024 * 1024); 71 return true; 72 } 73 74 bool DeleteCache(const FilePath& path) { 75 disk_cache::DeleteCache(path, false); 76 return true; 77 } 78 79 bool CheckCacheIntegrity(const FilePath& path, bool new_eviction) { 80 scoped_ptr<disk_cache::BackendImpl> cache(new disk_cache::BackendImpl(path)); 81 if (!cache.get()) 82 return false; 83 if (new_eviction) 84 cache->SetNewEviction(); 85 cache->SetFlags(disk_cache::kNoRandom); 86 if (!cache->Init()) 87 return false; 88 return cache->SelfCheck() >= 0; 89 } 90 91 ScopedTestCache::ScopedTestCache() : path_(GetCacheFilePath()) { 92 bool result = DeleteCache(path_); 93 DCHECK(result); 94 } 95 96 ScopedTestCache::ScopedTestCache(const std::string& name) 97 : path_(BuildCachePath(name)) { 98 bool result = DeleteCache(path_); 99 DCHECK(result); 100 } 101 102 ScopedTestCache::~ScopedTestCache() { 103 file_util::Delete(path(), true); 104 } 105 106 // ----------------------------------------------------------------------- 107 108 volatile int g_cache_tests_received = 0; 109 volatile bool g_cache_tests_error = 0; 110 111 // On the actual callback, increase the number of tests received and check for 112 // errors (an unexpected test received) 113 void CallbackTest::RunWithParams(const Tuple1<int>& params) { 114 if (reuse_) { 115 DCHECK(1 == reuse_); 116 if (2 == reuse_) 117 g_cache_tests_error = true; 118 reuse_++; 119 } 120 121 result_ = params.a; 122 g_cache_tests_received++; 123 } 124 125 // ----------------------------------------------------------------------- 126 127 MessageLoopHelper::MessageLoopHelper() 128 : num_callbacks_(0), 129 num_iterations_(0), 130 last_(0), 131 completed_(false) { 132 // Create a recurrent timer of 50 mS. 133 timer_.Start( 134 TimeDelta::FromMilliseconds(50), this, &MessageLoopHelper::TimerExpired); 135 } 136 137 bool MessageLoopHelper::WaitUntilCacheIoFinished(int num_callbacks) { 138 if (num_callbacks == g_cache_tests_received) 139 return true; 140 141 ExpectCallbacks(num_callbacks); 142 MessageLoop::current()->Run(); 143 return completed_; 144 } 145 146 // Quits the message loop when all callbacks are called or we've been waiting 147 // too long for them (2 secs without a callback). 148 void MessageLoopHelper::TimerExpired() { 149 if (g_cache_tests_received > num_callbacks_) { 150 NOTREACHED(); 151 } else if (g_cache_tests_received == num_callbacks_) { 152 completed_ = true; 153 MessageLoop::current()->Quit(); 154 } else { 155 // Not finished yet. See if we have to abort. 156 if (last_ == g_cache_tests_received) 157 num_iterations_++; 158 else 159 last_ = g_cache_tests_received; 160 if (40 == num_iterations_) 161 MessageLoop::current()->Quit(); 162 } 163 } 164