2 #include "DiskIO/DiskIOModule.h"
3 #include "fs/ufs/UFSSwapDir.h"
5 #include "HttpHeader.h"
9 #include "RequestFlags.h"
10 #include "SquidConfig.h"
13 #include "testStoreSupport.h"
18 #define TESTDIR "testUfs_Store"
20 CPPUNIT_TEST_SUITE_REGISTRATION( testUfs
);
22 typedef RefCount
<Fs::Ufs::UFSSwapDir
> SwapDirPointer
;
23 extern REMOVALPOLICYCREATE createRemovalPolicy_lru
; /* XXX fails with --enable-removal-policies=heap */
26 addSwapDir(SwapDirPointer aStore
)
28 allocate_new_swapdir(&Config
.cacheSwap
);
29 Config
.cacheSwap
.swapDirs
[Config
.cacheSwap
.n_configured
] = aStore
.getRaw();
30 ++Config
.cacheSwap
.n_configured
;
33 /* TODO make this a cbdata class */
38 searchCallback(void *cbdata
)
46 static bool inited
= false;
51 Config
.Store
.avgObjectSize
= 1024;
52 Config
.Store
.objectsPerBucket
= 20;
53 Config
.Store
.maxObjectSize
= 2048;
55 Config
.store_dir_select_algorithm
= xstrdup("round-robin");
57 Config
.replPolicy
= new RemovalPolicySettings
;
58 Config
.replPolicy
->type
= xstrdup("lru");
61 storeReplAdd("lru", createRemovalPolicy_lru
);
67 httpHeaderInitModule(); /* must go before any header processing (e.g. the one in errorInitialize) */
69 httpReplyInitModule(); /* must go before accepting replies */
75 testUfs::testUfsSearch()
78 * make a valid working ufs swapdir
79 * put two entries in it and sync logs
81 * check the entries we find are what we want
84 if (0 > system ("rm -rf " TESTDIR
))
85 throw std::runtime_error("Failed to clean test work directory");
87 Store::Root(new StoreController
);
89 SwapDirPointer
aStore (new Fs::Ufs::UFSSwapDir("ufs", "Blocking"));
91 aStore
->IO
= new Fs::Ufs::UFSStrategy(DiskIOModule::Find("Blocking")->createStrategy());
96 mem_policy
= createRemovalPolicy(Config
.replPolicy
);
98 char *path
=xstrdup(TESTDIR
);
100 char *config_line
=xstrdup("100 1 1");
102 visible_appname_string
= xstrdup(PACKAGE
"/" VERSION
);
104 ConfigParser::SetCfgLine(config_line
);
106 aStore
->parse(0, path
);
107 store_maxobjsize
= 1024*1024*2;
111 safe_free(config_line
);
113 /* ok, ready to create */
116 /* ok, ready to use - inits store & hash too */
117 Store::Root().init();
119 /* our swapdir must be scheduled to rebuild */
120 CPPUNIT_ASSERT_EQUAL(2, StoreController::store_dirs_rebuilding
);
122 /* rebuild is a scheduled event */
125 while (StoreController::store_dirs_rebuilding
)
128 /* cannot use loop.run(); as the loop will never idle: the store-dir
129 * clean() scheduled event prevents it
132 /* nothing left to rebuild */
133 CPPUNIT_ASSERT_EQUAL(0, StoreController::store_dirs_rebuilding
);
137 /* Create "vary" base object */
139 flags
.cachable
= true;
140 StoreEntry
*pe
= storeCreateEntry("dummy url", "dummy log url", flags
, Http::METHOD_GET
);
141 HttpReply
*rep
= (HttpReply
*) pe
->getReply(); // bypass const
142 rep
->setHeaders(Http::scOkay
, "dummy test object", "x-squid-internal/test", 0, -1, squid_curtime
+ 100000);
147 /* TODO: remove this when the metadata is separated */
150 packerToStoreInit(&p
, pe
);
151 pe
->getReply()->packHeadersInto(&p
);
159 CPPUNIT_ASSERT_EQUAL(0, pe
->swap_dirn
);
160 CPPUNIT_ASSERT_EQUAL(0, pe
->swap_filen
);
161 pe
->unlock("testUfs::testUfsSearch vary");
164 storeDirWriteCleanLogs(0);
166 /* here we cheat: we know that UFSSwapDirs search off disk. If we did an init call to a new
167 * swapdir instance, we'd not be testing a clean build.
169 StoreSearchPointer search
= aStore
->search (NULL
, NULL
); /* search for everything in the store */
171 /* nothing should be immediately available */
174 CPPUNIT_ASSERT_EQUAL(false, search
->next());
177 CPPUNIT_ASSERT_EQUAL(false, search
->error());
178 CPPUNIT_ASSERT_EQUAL(false, search
->isDone());
179 CPPUNIT_ASSERT_EQUAL(static_cast<StoreEntry
*>(NULL
), search
->currentItem());
181 /* trigger a callback */
183 search
->next(searchCallback
, NULL
);
184 CPPUNIT_ASSERT_EQUAL(true, cbcalled
);
186 /* we should have access to a entry now, that matches the entry we had before */
187 //CPPUNIT_ASSERT_EQUAL(false, search->next());
188 CPPUNIT_ASSERT_EQUAL(false, search
->error());
189 CPPUNIT_ASSERT_EQUAL(false, search
->isDone());
190 CPPUNIT_ASSERT(search
->currentItem() != NULL
);
192 /* trigger another callback */
194 search
->next(searchCallback
, NULL
);
195 CPPUNIT_ASSERT_EQUAL(true, cbcalled
);
197 /* now we should have no error, we should have finished and have no current item */
198 //CPPUNIT_ASSERT_EQUAL(false, search->next());
199 CPPUNIT_ASSERT_EQUAL(false, search
->error());
200 CPPUNIT_ASSERT_EQUAL(true, search
->isDone());
201 CPPUNIT_ASSERT_EQUAL(static_cast<StoreEntry
*>(NULL
), search
->currentItem());
205 free_cachedir(&Config
.cacheSwap
);
207 /* todo: here we should test a dirty rebuild */
209 safe_free(Config
.replPolicy
->type
);
210 delete Config
.replPolicy
;
212 if (0 > system ("rm -rf " TESTDIR
))
213 throw std::runtime_error("Failed to clean test work directory");
216 /* The UFS store should always configure an IO engine even if none is
217 * supplied on the configuration line.
220 testUfs::testUfsDefaultEngine()
222 /* boring common test boilerplate */
223 if (0 > system ("rm -rf " TESTDIR
))
224 throw std::runtime_error("Failed to clean test work directory");
226 // This assertion may fail if previous test cases fail.
227 // Apparently, CPPUNIT_ASSERT* failure may prevent destructors of local
228 // objects such as "StorePointer aRoot" from being called.
229 CPPUNIT_ASSERT(!store_table
); // or StoreHashIndex ctor will abort below
231 Store::Root(new StoreController
);
232 SwapDirPointer
aStore (new Fs::Ufs::UFSSwapDir("ufs", "Blocking"));
235 Config
.replPolicy
= new RemovalPolicySettings
;
236 Config
.replPolicy
->type
= xstrdup("lru");
237 mem_policy
= createRemovalPolicy(Config
.replPolicy
);
239 char *path
=xstrdup(TESTDIR
);
240 char *config_line
=xstrdup("100 1 1");
241 ConfigParser::SetCfgLine(config_line
);
242 aStore
->parse(0, path
);
244 safe_free(config_line
);
245 CPPUNIT_ASSERT(aStore
->IO
->io
!= NULL
);
248 free_cachedir(&Config
.cacheSwap
);
249 safe_free(Config
.replPolicy
->type
);
250 delete Config
.replPolicy
;
252 if (0 > system ("rm -rf " TESTDIR
))
253 throw std::runtime_error("Failed to clean test work directory");