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