8 #include "DiskIO/DiskIOModule.h"
9 #include "fs/ufs/ufscommon.h"
11 #include "MemObject.h"
12 #include "HttpHeader.h"
13 #include "HttpReply.h"
14 #include "testStoreSupport.h"
16 #define TESTDIR "testUfs__testUfsSearch"
18 CPPUNIT_TEST_SUITE_REGISTRATION( testUfs
);
20 typedef RefCount
<UFSSwapDir
> SwapDirPointer
;
21 extern REMOVALPOLICYCREATE createRemovalPolicy_lru
; /* XXX fails with --enable-removal-policies=heap */
24 addSwapDir(SwapDirPointer aStore
)
26 allocate_new_swapdir(&Config
.cacheSwap
);
27 Config
.cacheSwap
.swapDirs
[Config
.cacheSwap
.n_configured
] = aStore
.getRaw();
28 ++Config
.cacheSwap
.n_configured
;
31 /* TODO make this a cbdata class */
36 searchCallback(void *cbdata
)
44 static bool inited
= false;
49 Config
.Store
.avgObjectSize
= 1024;
51 Config
.Store
.objectsPerBucket
= 20;
53 Config
.Store
.maxObjectSize
= 2048;
55 Config
.store_dir_select_algorithm
= xstrdup("round-robin");
57 Config
.replPolicy
= new RemovalPolicySettings
;
59 Config
.replPolicy
->type
= xstrdup ("lru");
62 storeReplAdd("lru", createRemovalPolicy_lru
);
68 httpHeaderInitModule(); /* must go before any header processing (e.g. the one in errorInitialize) */
70 httpReplyInitModule(); /* must go before accepting replies */
76 testUfs::testUfsSearch()
79 * make a valid working ufs swapdir
80 * put two entries in it and sync logs
82 * check the entries we find are what we want
85 if (0 > system ("rm -rf " TESTDIR
))
86 throw std::runtime_error("Failed to clean test work directory");
88 StorePointer
aRoot (new StoreController
);
92 SwapDirPointer
aStore (new UFSSwapDir("ufs", "Blocking"));
94 aStore
->IO
= new UFSStrategy(DiskIOModule::Find("Blocking")->createStrategy());
99 mem_policy
= createRemovalPolicy(Config
.replPolicy
);
102 char *path
=xstrdup(TESTDIR
);
104 char *config_line
=xstrdup("foo 100 1 1");
106 visible_appname_string
= xstrdup(PACKAGE
"/" VERSION
);
108 strtok(config_line
, w_space
);
110 aStore
->parse(0, path
);
114 safe_free(config_line
);
116 /* ok, ready to create */
119 /* ok, ready to use - inits store & hash too */
120 Store::Root().init();
122 /* our swapdir must be scheduled to rebuild */
123 CPPUNIT_ASSERT_EQUAL(2, StoreController::store_dirs_rebuilding
);
125 /* rebuild is a scheduled event */
128 while (StoreController::store_dirs_rebuilding
> 1)
131 /* cannot use loop.run(); as the loop will never idle: the store-dir
132 * clean() scheduled event prevents it
135 /* nothing left to rebuild */
136 CPPUNIT_ASSERT_EQUAL(1, StoreController::store_dirs_rebuilding
);
140 /* Create "vary" base object */
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);
151 /* TODO: remove this when the metadata is separated */
154 packerToStoreInit(&p
, pe
);
155 pe
->getReply()->packHeadersInto(&p
);
163 CPPUNIT_ASSERT(pe
->swap_dirn
== 0);
164 CPPUNIT_ASSERT(pe
->swap_filen
== 0);
168 storeDirWriteCleanLogs(0);
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.
173 StoreSearchPointer search
= aStore
->search (NULL
, NULL
); /* search for everything in the store */
175 /* nothing should be immediately available */
178 CPPUNIT_ASSERT(search
->next() == false);
181 CPPUNIT_ASSERT(search
->error() == false);
182 CPPUNIT_ASSERT(search
->isDone() == false);
183 CPPUNIT_ASSERT(search
->currentItem() == NULL
);
185 /* trigger a callback */
187 search
->next(searchCallback
, NULL
);
188 CPPUNIT_ASSERT(cbcalled
== true);
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
);
196 /* trigger another callback */
198 search
->next(searchCallback
, NULL
);
199 CPPUNIT_ASSERT(cbcalled
== true);
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
);
207 free_cachedir(&Config
.cacheSwap
);
209 /* todo: here we should test a dirty rebuild */
212 safe_free(Config
.replPolicy
->type
);
213 delete Config
.replPolicy
;
215 if (0 > system ("rm -rf " TESTDIR
))
216 throw std::runtime_error("Failed to clean test work directory");
219 /* The UFS store should always configure an IO engine even if none is
220 * supplied on the configuration line.
223 testUfs::testUfsDefaultEngine()
225 /* boring common test boilerplate */
226 if (0 > system ("rm -rf " TESTDIR
))
227 throw std::runtime_error("Failed to clean test work directory");
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
234 StorePointer
aRoot (new StoreController
);
236 SwapDirPointer
aStore (new UFSSwapDir("ufs", "Blocking"));
239 Config
.replPolicy
= new RemovalPolicySettings
;
240 Config
.replPolicy
->type
= xstrdup ("lru");
241 mem_policy
= createRemovalPolicy(Config
.replPolicy
);
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
);
248 safe_free(config_line
);
249 CPPUNIT_ASSERT(aStore
->IO
->io
!= NULL
);
251 free_cachedir(&Config
.cacheSwap
);
253 safe_free(Config
.replPolicy
->type
);
254 delete Config
.replPolicy
;
256 if (0 > system ("rm -rf " TESTDIR
))
257 throw std::runtime_error("Failed to clean test work directory");