]> git.ipfire.org Git - thirdparty/squid.git/blob - src/tests/testUfs.cc
SourceFormat: Main reformat push
[thirdparty/squid.git] / src / tests / testUfs.cc
1 #include "config.h"
2
3 #include <stdexcept>
4
5 #include "testUfs.h"
6 #include "Store.h"
7 #include "SwapDir.h"
8 #include "DiskIO/DiskIOModule.h"
9 #include "fs/ufs/ufscommon.h"
10 #include "Mem.h"
11 #include "MemObject.h"
12 #include "HttpHeader.h"
13 #include "HttpReply.h"
14 #include "testStoreSupport.h"
15
16 #define TESTDIR "testUfs__testUfsSearch"
17
18 CPPUNIT_TEST_SUITE_REGISTRATION( testUfs );
19
20 typedef RefCount<UFSSwapDir> SwapDirPointer;
21 extern REMOVALPOLICYCREATE createRemovalPolicy_lru; /* XXX fails with --enable-removal-policies=heap */
22
23 static void
24 addSwapDir(SwapDirPointer aStore)
25 {
26 allocate_new_swapdir(&Config.cacheSwap);
27 Config.cacheSwap.swapDirs[Config.cacheSwap.n_configured] = aStore.getRaw();
28 ++Config.cacheSwap.n_configured;
29 }
30
31 /* TODO make this a cbdata class */
32
33 static bool cbcalled;
34
35 static void
36 searchCallback(void *cbdata)
37 {
38 cbcalled = true;
39 }
40
41 void
42 testUfs::commonInit()
43 {
44 static bool inited = false;
45
46 if (inited)
47 return;
48
49 Config.Store.avgObjectSize = 1024;
50
51 Config.Store.objectsPerBucket = 20;
52
53 Config.Store.maxObjectSize = 2048;
54
55 Config.store_dir_select_algorithm = xstrdup("round-robin");
56
57 Config.replPolicy = new RemovalPolicySettings;
58
59 Config.replPolicy->type = xstrdup ("lru");
60
61 /* garh garh */
62 storeReplAdd("lru", createRemovalPolicy_lru);
63
64 Mem::Init();
65
66 comm_init();
67
68 httpHeaderInitModule(); /* must go before any header processing (e.g. the one in errorInitialize) */
69
70 httpReplyInitModule(); /* must go before accepting replies */
71
72 inited = true;
73 }
74
75 void
76 testUfs::testUfsSearch()
77 {
78 /* test sequence
79 * make a valid working ufs swapdir
80 * put two entries in it and sync logs
81 * search the ufs dir
82 * check the entries we find are what we want
83 */
84
85 if (0 > system ("rm -rf " TESTDIR))
86 throw std::runtime_error("Failed to clean test work directory");
87
88 StorePointer aRoot (new StoreController);
89
90 Store::Root(aRoot);
91
92 SwapDirPointer aStore (new UFSSwapDir("ufs", "Blocking"));
93
94 aStore->IO = new UFSStrategy(DiskIOModule::Find("Blocking")->createStrategy());
95
96 addSwapDir(aStore);
97
98 commonInit();
99 mem_policy = createRemovalPolicy(Config.replPolicy);
100
101
102 char *path=xstrdup(TESTDIR);
103
104 char *config_line=xstrdup("foo 100 1 1");
105
106 visible_appname_string = xstrdup(PACKAGE "/" VERSION);
107
108 strtok(config_line, w_space);
109
110 aStore->parse(0, path);
111
112 safe_free(path);
113
114 safe_free(config_line);
115
116 /* ok, ready to create */
117 aStore->create();
118
119 /* ok, ready to use - inits store & hash too */
120 Store::Root().init();
121
122 /* our swapdir must be scheduled to rebuild */
123 CPPUNIT_ASSERT_EQUAL(2, StoreController::store_dirs_rebuilding);
124
125 /* rebuild is a scheduled event */
126 StockEventLoop loop;
127
128 while (StoreController::store_dirs_rebuilding > 1)
129 loop.runOnce();
130
131 /* cannot use loop.run(); as the loop will never idle: the store-dir
132 * clean() scheduled event prevents it
133 */
134
135 /* nothing left to rebuild */
136 CPPUNIT_ASSERT_EQUAL(1, StoreController::store_dirs_rebuilding);
137
138 /* add an entry */
139 {
140 /* Create "vary" base object */
141 request_flags flags;
142 flags.cachable = 1;
143 StoreEntry *pe = storeCreateEntry("dummy url", "dummy log url", flags, METHOD_GET);
144 HttpVersion version(1, 0);
145 HttpReply *rep = (HttpReply *) pe->getReply(); // bypass const
146 rep->setHeaders(version, HTTP_OK, "dummy test object", "x-squid-internal/test", -1, -1, squid_curtime + 100000);
147
148 pe->setPublicKey();
149
150 pe->buffer();
151 /* TODO: remove this when the metadata is separated */
152 {
153 Packer p;
154 packerToStoreInit(&p, pe);
155 pe->getReply()->packHeadersInto(&p);
156 packerClean(&p);
157 }
158
159 pe->flush();
160 pe->timestampsSet();
161 pe->complete();
162 pe->swapOut();
163 CPPUNIT_ASSERT(pe->swap_dirn == 0);
164 CPPUNIT_ASSERT(pe->swap_filen == 0);
165 pe->unlock();
166 }
167
168 storeDirWriteCleanLogs(0);
169
170 /* here we cheat: we know that UFSSwapDirs search off disk. If we did an init call to a new
171 * swapdir instance, we'd not be testing a clean build.
172 */
173 StoreSearchPointer search = aStore->search (NULL, NULL); /* search for everything in the store */
174
175 /* nothing should be immediately available */
176 #if 0
177
178 CPPUNIT_ASSERT(search->next() == false);
179 #endif
180
181 CPPUNIT_ASSERT(search->error() == false);
182 CPPUNIT_ASSERT(search->isDone() == false);
183 CPPUNIT_ASSERT(search->currentItem() == NULL);
184
185 /* trigger a callback */
186 cbcalled = false;
187 search->next(searchCallback, NULL);
188 CPPUNIT_ASSERT(cbcalled == true);
189
190 /* we should have access to a entry now, that matches the entry we had before */
191 //CPPUNIT_ASSERT(search->next() == false);
192 CPPUNIT_ASSERT(search->error() == false);
193 CPPUNIT_ASSERT(search->isDone() == false);
194 CPPUNIT_ASSERT(search->currentItem() != NULL);
195
196 /* trigger another callback */
197 cbcalled = false;
198 search->next(searchCallback, NULL);
199 CPPUNIT_ASSERT(cbcalled == true);
200
201 /* now we should have no error, we should have finished and have no current item */
202 //CPPUNIT_ASSERT(search->next() == false);
203 CPPUNIT_ASSERT(search->error() == false);
204 CPPUNIT_ASSERT(search->isDone() == true);
205 CPPUNIT_ASSERT(search->currentItem() == NULL);
206
207 free_cachedir(&Config.cacheSwap);
208
209 /* todo: here we should test a dirty rebuild */
210
211 Store::Root(NULL);
212 safe_free(Config.replPolicy->type);
213 delete Config.replPolicy;
214
215 if (0 > system ("rm -rf " TESTDIR))
216 throw std::runtime_error("Failed to clean test work directory");
217 }
218
219 /* The UFS store should always configure an IO engine even if none is
220 * supplied on the configuration line.
221 */
222 void
223 testUfs::testUfsDefaultEngine()
224 {
225 /* boring common test boilerplate */
226 if (0 > system ("rm -rf " TESTDIR))
227 throw std::runtime_error("Failed to clean test work directory");
228
229 // This assertion may fail if previous test cases fail.
230 // Apparently, CPPUNIT_ASSERT* failure may prevent destructors of local
231 // objects such as "StorePointer aRoot" from being called.
232 CPPUNIT_ASSERT(!store_table); // or StoreHashIndex ctor will abort below
233
234 StorePointer aRoot (new StoreController);
235 Store::Root(aRoot);
236 SwapDirPointer aStore (new UFSSwapDir("ufs", "Blocking"));
237 addSwapDir(aStore);
238 commonInit();
239 Config.replPolicy = new RemovalPolicySettings;
240 Config.replPolicy->type = xstrdup ("lru");
241 mem_policy = createRemovalPolicy(Config.replPolicy);
242
243 char *path=xstrdup(TESTDIR);
244 char *config_line=xstrdup("foo 100 1 1");
245 strtok(config_line, w_space);
246 aStore->parse(0, path);
247 safe_free(path);
248 safe_free(config_line);
249 CPPUNIT_ASSERT(aStore->IO->io != NULL);
250
251 free_cachedir(&Config.cacheSwap);
252 Store::Root(NULL);
253 safe_free(Config.replPolicy->type);
254 delete Config.replPolicy;
255
256 if (0 > system ("rm -rf " TESTDIR))
257 throw std::runtime_error("Failed to clean test work directory");
258 }