1 // Copyright (c) 2011 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/files/file.h" 8 #include "base/files/file_path.h" 9 #include "base/logging.h" 10 #include "base/message_loop/message_loop_proxy.h" 11 #include "base/path_service.h" 12 #include "net/base/net_errors.h" 13 #include "net/disk_cache/blockfile/backend_impl.h" 14 #include "net/disk_cache/blockfile/file.h" 15 #include "net/disk_cache/cache_util.h" 16 17 using base::Time; 18 using base::TimeDelta; 19 20 std::string GenerateKey(bool same_length) { 21 char key[200]; 22 CacheTestFillBuffer(key, sizeof(key), same_length); 23 24 key[199] = '\0'; 25 return std::string(key); 26 } 27 28 void CacheTestFillBuffer(char* buffer, size_t len, bool no_nulls) { 29 static bool called = false; 30 if (!called) { 31 called = true; 32 int seed = static_cast<int>(Time::Now().ToInternalValue()); 33 srand(seed); 34 } 35 36 for (size_t i = 0; i < len; i++) { 37 buffer[i] = static_cast<char>(rand()); 38 if (!buffer[i] && no_nulls) 39 buffer[i] = 'g'; 40 } 41 if (len && !buffer[0]) 42 buffer[0] = 'g'; 43 } 44 45 bool CreateCacheTestFile(const base::FilePath& name) { 46 int flags = base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_READ | 47 base::File::FLAG_WRITE; 48 49 base::File file(name, flags); 50 if (!file.IsValid()) 51 return false; 52 53 file.SetLength(4 * 1024 * 1024); 54 return true; 55 } 56 57 bool DeleteCache(const base::FilePath& path) { 58 disk_cache::DeleteCache(path, false); 59 return true; 60 } 61 62 bool CheckCacheIntegrity(const base::FilePath& path, bool new_eviction, 63 uint32 mask) { 64 scoped_ptr<disk_cache::BackendImpl> cache(new disk_cache::BackendImpl( 65 path, mask, base::MessageLoopProxy::current().get(), NULL)); 66 if (!cache.get()) 67 return false; 68 if (new_eviction) 69 cache->SetNewEviction(); 70 cache->SetFlags(disk_cache::kNoRandom); 71 if (cache->SyncInit() != net::OK) 72 return false; 73 return cache->SelfCheck() >= 0; 74 } 75 76 // ----------------------------------------------------------------------- 77 78 MessageLoopHelper::MessageLoopHelper() 79 : num_callbacks_(0), 80 num_iterations_(0), 81 last_(0), 82 completed_(false), 83 callback_reused_error_(false), 84 callbacks_called_(0) { 85 } 86 87 MessageLoopHelper::~MessageLoopHelper() { 88 } 89 90 bool MessageLoopHelper::WaitUntilCacheIoFinished(int num_callbacks) { 91 if (num_callbacks == callbacks_called_) 92 return true; 93 94 ExpectCallbacks(num_callbacks); 95 // Create a recurrent timer of 50 mS. 96 if (!timer_.IsRunning()) 97 timer_.Start(FROM_HERE, TimeDelta::FromMilliseconds(50), this, 98 &MessageLoopHelper::TimerExpired); 99 base::MessageLoop::current()->Run(); 100 return completed_; 101 } 102 103 // Quits the message loop when all callbacks are called or we've been waiting 104 // too long for them (2 secs without a callback). 105 void MessageLoopHelper::TimerExpired() { 106 CHECK_LE(callbacks_called_, num_callbacks_); 107 if (callbacks_called_ == num_callbacks_) { 108 completed_ = true; 109 base::MessageLoop::current()->Quit(); 110 } else { 111 // Not finished yet. See if we have to abort. 112 if (last_ == callbacks_called_) 113 num_iterations_++; 114 else 115 last_ = callbacks_called_; 116 if (40 == num_iterations_) 117 base::MessageLoop::current()->Quit(); 118 } 119 } 120 121 // ----------------------------------------------------------------------- 122 123 CallbackTest::CallbackTest(MessageLoopHelper* helper, 124 bool reuse) 125 : helper_(helper), 126 reuse_(reuse ? 0 : 1) { 127 } 128 129 CallbackTest::~CallbackTest() { 130 } 131 132 // On the actual callback, increase the number of tests received and check for 133 // errors (an unexpected test received) 134 void CallbackTest::Run(int result) { 135 last_result_ = result; 136 137 if (reuse_) { 138 DCHECK_EQ(1, reuse_); 139 if (2 == reuse_) 140 helper_->set_callback_reused_error(true); 141 reuse_++; 142 } 143 144 helper_->CallbackWasCalled(); 145 } 146