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