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/path_service.h"
11 #include "base/thread_task_runner_handle.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
GenerateKey(bool same_length)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
CacheTestFillBuffer(char * buffer,size_t len,bool no_nulls)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
CreateCacheTestFile(const base::FilePath & name)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
DeleteCache(const base::FilePath & path)57 bool DeleteCache(const base::FilePath& path) {
58 disk_cache::DeleteCache(path, false);
59 return true;
60 }
61
CheckCacheIntegrity(const base::FilePath & path,bool new_eviction,uint32 mask)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::ThreadTaskRunnerHandle::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
MessageLoopHelper()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
~MessageLoopHelper()87 MessageLoopHelper::~MessageLoopHelper() {
88 }
89
WaitUntilCacheIoFinished(int num_callbacks)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).
TimerExpired()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
CallbackTest(MessageLoopHelper * helper,bool reuse)123 CallbackTest::CallbackTest(MessageLoopHelper* helper,
124 bool reuse)
125 : helper_(helper),
126 reuse_(reuse ? 0 : 1) {
127 }
128
~CallbackTest()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)
Run(int result)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