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