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