Home | History | Annotate | Download | only in disk_cache
      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 
     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 
     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 
     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 
     58 FilePath GetCacheFilePath() {
     59   return BuildCachePath("cache_test");
     60 }
     61 
     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 
     76 bool DeleteCache(const FilePath& path) {
     77   disk_cache::DeleteCache(path, false);
     78   return true;
     79 }
     80 
     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 
     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 
    108 ScopedTestCache::ScopedTestCache() : path_(GetCacheFilePath()) {
    109   bool result = DeleteCache(path_);
    110   DCHECK(result);
    111 }
    112 
    113 ScopedTestCache::ScopedTestCache(const std::string& name)
    114     : path_(BuildCachePath(name)) {
    115   bool result = DeleteCache(path_);
    116   DCHECK(result);
    117 }
    118 
    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 
    128 CallbackTest::CallbackTest(bool reuse) : result_(-1), reuse_(reuse ? 0 : 1) {}
    129 
    130 CallbackTest::~CallbackTest() {}
    131 
    132 // On the actual callback, increase the number of tests received and check for
    133 // errors (an unexpected test received)
    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 
    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 
    158 MessageLoopHelper::~MessageLoopHelper() {
    159 }
    160 
    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).
    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