]> git.ipfire.org Git - thirdparty/squid.git/blame - src/tests/testRock.cc
Removed squid-old.h
[thirdparty/squid.git] / src / tests / testRock.cc
CommitLineData
9bb01611 1#define SQUID_UNIT_TEST 1
f7f3304a 2#include "squid.h"
9bb01611
AR
3
4#include "DiskIO/DiskIOModule.h"
582c2af2
FC
5#include "fs/rock/RockSwapDir.h"
6#include "globals.h"
9bb01611
AR
7#include "HttpHeader.h"
8#include "HttpReply.h"
9#include "Mem.h"
10#include "MemObject.h"
582c2af2 11#include "protos.h"
9bb01611
AR
12#include "Store.h"
13#include "StoreFileSystem.h"
14#include "StoreSearch.h"
15#include "SwapDir.h"
9bb01611
AR
16#include "testRock.h"
17#include "testStoreSupport.h"
18
582c2af2
FC
19#if HAVE_SYS_STAT_H
20#include <sys/stat.h>
21#endif
9bb01611
AR
22#if HAVE_STDEXCEPT
23#include <stdexcept>
24#endif
25
26#define TESTDIR "testRock__testRockSearch"
27
28CPPUNIT_TEST_SUITE_REGISTRATION( testRock );
29
30extern REMOVALPOLICYCREATE createRemovalPolicy_lru;
31
32static void
33addSwapDir(testRock::SwapDirPointer aStore)
34{
35 allocate_new_swapdir(&Config.cacheSwap);
36 Config.cacheSwap.swapDirs[Config.cacheSwap.n_configured] = aStore.getRaw();
37 ++Config.cacheSwap.n_configured;
38}
39
40void
41testRock::setUp()
42{
43 CPPUNIT_NS::TestFixture::setUp();
44
45 if (0 > system ("rm -rf " TESTDIR))
46 throw std::runtime_error("Failed to clean test work directory");
47
ef8de464 48 // use current directory for shared segments (on path-based OSes)
d9677bcd 49 Ipc::Mem::Segment::BasePath = ".";
ef8de464 50
9bb01611
AR
51 Store::Root(new StoreController);
52
53 store = new Rock::SwapDir();
54
55 addSwapDir(store);
56
57 commonInit();
58
59 char *path=xstrdup(TESTDIR);
60
fda15c05 61 char *config_line=xstrdup("foo 10 max-size=16384");
9bb01611
AR
62
63 strtok(config_line, w_space);
64
65 store->parse(0, path);
66
67 safe_free(path);
68
69 safe_free(config_line);
70
71 /* ok, ready to create */
72 store->create();
73
74 rr = new Rock::SwapDirRr;
75 rr->run(rrAfterConfig);
76}
77
78void
79testRock::tearDown()
80{
81 CPPUNIT_NS::TestFixture::tearDown();
82
83 Store::Root(NULL);
84
85 store = NULL;
86
87 free_cachedir(&Config.cacheSwap);
88
89 delete rr;
90
91 // TODO: do this once, or each time.
92 // safe_free(Config.replPolicy->type);
93 // delete Config.replPolicy;
94
95 if (0 > system ("rm -rf " TESTDIR))
96 throw std::runtime_error("Failed to clean test work directory");
97}
98
99void
100testRock::commonInit()
101{
102 static bool inited = false;
103
104 if (inited)
105 return;
106
107 StoreFileSystem::SetupAllFs();
108
109 Config.Store.avgObjectSize = 1024;
110
111 Config.Store.objectsPerBucket = 20;
112
113 Config.Store.maxObjectSize = 2048;
114
115 Config.store_dir_select_algorithm = xstrdup("round-robin");
116
117 Config.replPolicy = new RemovalPolicySettings;
118
119 Config.replPolicy->type = xstrdup ("lru");
120
121 Config.replPolicy->args = NULL;
122
123 /* garh garh */
124 storeReplAdd("lru", createRemovalPolicy_lru);
125
126 visible_appname_string = xstrdup(APP_FULLNAME);
127
128 Mem::Init();
129
130 comm_init();
131
132 httpHeaderInitModule(); /* must go before any header processing (e.g. the one in errorInitialize) */
133
134 httpReplyInitModule(); /* must go before accepting replies */
135
136 mem_policy = createRemovalPolicy(Config.replPolicy);
137
138 inited = true;
139}
140
141void
142testRock::storeInit()
143{
144 /* ok, ready to use */
145 Store::Root().init();
146
147 /* rebuild is a scheduled event */
148 StockEventLoop loop;
149
150 /* our swapdir must be scheduled to rebuild */
151 CPPUNIT_ASSERT_EQUAL(2, StoreController::store_dirs_rebuilding);
152
153 loop.run();
154
155 /* cannot use loop.run(); as the loop will never idle: the store-dir
156 * clean() scheduled event prevents it
157 */
158
159 /* nothing left to rebuild */
160 CPPUNIT_ASSERT_EQUAL(1, StoreController::store_dirs_rebuilding);
161}
162
163StoreEntry *
164testRock::createEntry(const int i)
165{
166 request_flags flags;
167 flags.cachable = 1;
168 char url[64];
169 snprintf(url, sizeof(url), "dummy url %i", i);
170 url[sizeof(url) - 1] = '\0';
171 StoreEntry *const pe =
172 storeCreateEntry(url, "dummy log url", flags, METHOD_GET);
173 HttpReply *const rep = const_cast<HttpReply *>(pe->getReply());
174 rep->setHeaders(HTTP_OK, "dummy test object", "x-squid-internal/test",
175 -1, -1, squid_curtime + 100000);
176
177 pe->setPublicKey();
178
179 return pe;
180}
181
182StoreEntry *
183testRock::addEntry(const int i)
184{
185 StoreEntry *const pe = createEntry(i);
186
187 pe->buffer();
188 /* TODO: remove this when the metadata is separated */
189 {
190 Packer p;
191 packerToStoreInit(&p, pe);
192 pe->getReply()->packHeadersInto(&p);
193 packerClean(&p);
194 }
195
196 pe->flush();
197 pe->timestampsSet();
198 pe->complete();
199 pe->swapOut();
200
201 return pe;
202}
203
204StoreEntry *
205testRock::getEntry(const int i)
206{
207 StoreEntry *const pe = createEntry(i);
208 return store->get(reinterpret_cast<const cache_key *>(pe->key));
209}
210
211void
212testRock::testRockCreate()
213{
214 struct stat sb;
215
216 CPPUNIT_ASSERT(::stat(TESTDIR, &sb) == 0);
217
218 /* TODO: check the size */
219
220 /* TODO: test rebuild */
221}
222
223void
224testRock::testRockSwapOut()
225{
226 storeInit();
227
228 // add few entries to prime the database
229 for (int i = 0; i < 5; ++i) {
230 CPPUNIT_ASSERT_EQUAL((uint64_t)i, store->currentCount());
231
232 StoreEntry *const pe = addEntry(i);
233
234 CPPUNIT_ASSERT(pe->swap_status == SWAPOUT_WRITING);
235 CPPUNIT_ASSERT(pe->swap_dirn == 0);
236 CPPUNIT_ASSERT(pe->swap_filen >= 0);
237
238 // Rock::IoState::finishedWriting() schedules an AsyncCall
239 // storeSwapOutFileClosed(). Let it fire.
240 StockEventLoop loop;
241 loop.run();
242
243 CPPUNIT_ASSERT(pe->swap_status == SWAPOUT_DONE);
244
245 pe->unlock();
246 }
247
248 CPPUNIT_ASSERT_EQUAL((uint64_t)5, store->currentCount());
249
250 // try to swap out entry to a used unlocked slot
251 {
252 StoreEntry *const pe = addEntry(4);
253
254 CPPUNIT_ASSERT(pe->swap_status == SWAPOUT_WRITING);
255 CPPUNIT_ASSERT(pe->swap_dirn == 0);
256 CPPUNIT_ASSERT(pe->swap_filen >= 0);
257
258 StockEventLoop loop;
259 loop.run();
260
261 CPPUNIT_ASSERT(pe->swap_status == SWAPOUT_DONE);
262 }
263
264 // try to swap out entry to a used locked slot
265 {
266 StoreEntry *const pe = addEntry(5);
267
268 CPPUNIT_ASSERT(pe->swap_status == SWAPOUT_WRITING);
269 CPPUNIT_ASSERT(pe->swap_dirn == 0);
270 CPPUNIT_ASSERT(pe->swap_filen >= 0);
271
272 // the slot is locked here because the async calls have not run yet
273 StoreEntry *const pe2 = addEntry(5);
274 CPPUNIT_ASSERT(pe2->swap_status == SWAPOUT_NONE);
275 CPPUNIT_ASSERT(pe2->mem_obj->swapout.decision ==
276 MemObject::SwapOut::swImpossible);
277 CPPUNIT_ASSERT(pe2->swap_dirn == -1);
278 CPPUNIT_ASSERT(pe2->swap_filen == -1);
279
280 StockEventLoop loop;
281 loop.run();
282 }
283
284 CPPUNIT_ASSERT_EQUAL((uint64_t)6, store->currentCount());
285
286 // try to get and unlink entries
287 for (int i = 0; i < 6; ++i) {
288 StoreEntry *const pe = getEntry(i);
289 CPPUNIT_ASSERT(pe != NULL);
290
291 pe->unlink();
292
293 StoreEntry *const pe2 = getEntry(i);
294 CPPUNIT_ASSERT(pe2 == NULL);
295 }
296}