]> git.ipfire.org Git - thirdparty/squid.git/blame - src/tests/testUfs.cc
Fix Controller.cc TheRoot assertion during shutdown (#1707)
[thirdparty/squid.git] / src / tests / testUfs.cc
CommitLineData
4e0938ef 1/*
b8ae064d 2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
4e0938ef
AJ
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
f7f3304a 9#include "squid.h"
ae022809 10#include "compat/cppunit.h"
c8f4eac4 11#include "DiskIO/DiskIOModule.h"
d7ca82e6 12#include "fde.h"
582c2af2
FC
13#include "fs/ufs/UFSSwapDir.h"
14#include "globals.h"
c8f4eac4 15#include "HttpHeader.h"
16#include "HttpReply.h"
58373ff8 17#include "MemObject.h"
f206b652 18#include "RequestFlags.h"
4d5904f7 19#include "SquidConfig.h"
58373ff8 20#include "Store.h"
2745fea5 21#include "store/Disks.h"
582c2af2 22#include "testStoreSupport.h"
7f861c77
AJ
23#include "unitTestMain.h"
24
27e059d4 25#include <stdexcept>
27e059d4 26
41e9c9f0 27#define TESTDIR "TestUfs_Store"
2e050051 28
ae022809
FC
29/*
30 * test the store framework
31 */
32
33class TestUfs : public CPPUNIT_NS::TestFixture
34{
35 CPPUNIT_TEST_SUITE(TestUfs);
36 CPPUNIT_TEST(testUfsSearch);
37 CPPUNIT_TEST(testUfsDefaultEngine);
38 CPPUNIT_TEST_SUITE_END();
39
40public:
41protected:
42 void commonInit();
43 void testUfsSearch();
44 void testUfsDefaultEngine();
45};
46CPPUNIT_TEST_SUITE_REGISTRATION(TestUfs);
c8f4eac4 47
2745fea5 48typedef RefCount<Fs::Ufs::UFSSwapDir> MySwapDirPointer;
f53969cc 49extern REMOVALPOLICYCREATE createRemovalPolicy_lru; /* XXX fails with --enable-removal-policies=heap */
c8f4eac4 50
51static void
2745fea5 52addSwapDir(MySwapDirPointer aStore)
c8f4eac4 53{
5d84beb5 54 allocate_new_swapdir(Config.cacheSwap);
c8f4eac4 55 Config.cacheSwap.swapDirs[Config.cacheSwap.n_configured] = aStore.getRaw();
56 ++Config.cacheSwap.n_configured;
57}
58
c8f4eac4 59static bool cbcalled;
60
61static void
8b082ed9 62searchCallback(void *)
c8f4eac4 63{
64 cbcalled = true;
65}
66
67void
41e9c9f0 68TestUfs::commonInit()
c8f4eac4 69{
b7717b61 70 static bool inited = false;
c8f4eac4 71
b7717b61 72 if (inited)
73 return;
c8f4eac4 74
75 Config.Store.avgObjectSize = 1024;
c8f4eac4 76 Config.Store.objectsPerBucket = 20;
c8f4eac4 77 Config.Store.maxObjectSize = 2048;
78
79 Config.store_dir_select_algorithm = xstrdup("round-robin");
80
81 Config.replPolicy = new RemovalPolicySettings;
86c63190 82 Config.replPolicy->type = xstrdup("lru");
c8f4eac4 83
c50b35b5
AJ
84 Config.memShared.defaultTo(false);
85
c8f4eac4 86 /* garh garh */
87 storeReplAdd("lru", createRemovalPolicy_lru);
88
89 Mem::Init();
90
d7ca82e6
EB
91 fde::Init();
92
c8f4eac4 93 comm_init();
94
f53969cc 95 httpHeaderInitModule(); /* must go before any header processing (e.g. the one in errorInitialize) */
c8f4eac4 96
b7717b61 97 inited = true;
98}
99
100void
41e9c9f0 101TestUfs::testUfsSearch()
b7717b61 102{
103 /* test sequence
104 * make a valid working ufs swapdir
105 * put two entries in it and sync logs
106 * search the ufs dir
107 * check the entries we find are what we want
108 */
109
110 if (0 > system ("rm -rf " TESTDIR))
111 throw std::runtime_error("Failed to clean test work directory");
112
2745fea5 113 MySwapDirPointer aStore (new Fs::Ufs::UFSSwapDir("ufs", "Blocking"));
b7717b61 114
58373ff8 115 aStore->IO = new Fs::Ufs::UFSStrategy(DiskIOModule::Find("Blocking")->createStrategy());
b7717b61 116
117 addSwapDir(aStore);
118
119 commonInit();
c8f4eac4 120 mem_policy = createRemovalPolicy(Config.replPolicy);
121
2e050051 122 char *path=xstrdup(TESTDIR);
c8f4eac4 123
2eceb328 124 char *config_line=xstrdup("100 1 1");
c8f4eac4 125
474dfa84 126 visible_appname_string = xstrdup(PACKAGE "/" VERSION);
127
2eceb328 128 ConfigParser::SetCfgLine(config_line);
c8f4eac4 129
130 aStore->parse(0, path);
b51ec8c8 131 store_maxobjsize = 1024*1024*2;
c8f4eac4 132
133 safe_free(path);
134
135 safe_free(config_line);
136
137 /* ok, ready to create */
138 aStore->create();
139
8ff3fa2e 140 /* ok, ready to use - inits store & hash too */
c8f4eac4 141 Store::Root().init();
142
bef81ea5 143 /* our swapdir must be scheduled to rebuild */
1f8dc0fb 144 CPPUNIT_ASSERT_EQUAL(2, StoreController::store_dirs_rebuilding);
bef81ea5 145
8ff3fa2e 146 /* rebuild is a scheduled event */
147 StockEventLoop loop;
148
02c267b0 149 while (StoreController::store_dirs_rebuilding)
bef81ea5 150 loop.runOnce();
c8f4eac4 151
bef81ea5 152 /* cannot use loop.run(); as the loop will never idle: the store-dir
26ac0430 153 * clean() scheduled event prevents it
bef81ea5 154 */
c8f4eac4 155
bef81ea5 156 /* nothing left to rebuild */
02c267b0 157 CPPUNIT_ASSERT_EQUAL(0, StoreController::store_dirs_rebuilding);
c8f4eac4 158
159 /* add an entry */
160 {
161 /* Create "vary" base object */
f206b652 162 RequestFlags flags;
aeeff7fd 163 flags.cachable.support();
c2a7cefd 164 StoreEntry *pe = storeCreateEntry("dummy url", "dummy log url", flags, Http::METHOD_GET);
66d51f4f
AR
165 auto &reply = pe->mem().adjustableBaseReply();
166 reply.setHeaders(Http::scOkay, "dummy test object", "x-squid-internal/test", 0, -1, squid_curtime + 100000);
c8f4eac4 167
d88e3c49 168 pe->setPublicKey();
c8f4eac4 169
3900307b 170 pe->buffer();
66d51f4f 171 pe->mem().freshestReply().packHeadersUsingSlowPacker(*pe);
3900307b 172 pe->flush();
173 pe->timestampsSet();
c8f4eac4 174 pe->complete();
c07cbbf4 175 pe->swapOut();
5d1dff27
FC
176 CPPUNIT_ASSERT_EQUAL(0, pe->swap_dirn);
177 CPPUNIT_ASSERT_EQUAL(0, pe->swap_filen);
41e9c9f0 178 pe->unlock("TestUfs::testUfsSearch vary");
c8f4eac4 179 }
180
181 storeDirWriteCleanLogs(0);
182
183 /* here we cheat: we know that UFSSwapDirs search off disk. If we did an init call to a new
184 * swapdir instance, we'd not be testing a clean build.
185 */
2745fea5 186 StoreSearchPointer search = Store::Root().search(); /* search for everything in the store */
c8f4eac4 187
5d1dff27
FC
188 CPPUNIT_ASSERT_EQUAL(false, search->error());
189 CPPUNIT_ASSERT_EQUAL(false, search->isDone());
aee3523a 190 CPPUNIT_ASSERT_EQUAL(static_cast<StoreEntry *>(nullptr), search->currentItem());
c8f4eac4 191
192 /* trigger a callback */
193 cbcalled = false;
aee3523a 194 search->next(searchCallback, nullptr);
5d1dff27 195 CPPUNIT_ASSERT_EQUAL(true, cbcalled);
c8f4eac4 196
197 /* we should have access to a entry now, that matches the entry we had before */
5d1dff27
FC
198 //CPPUNIT_ASSERT_EQUAL(false, search->next());
199 CPPUNIT_ASSERT_EQUAL(false, search->error());
200 CPPUNIT_ASSERT_EQUAL(false, search->isDone());
aee3523a 201 CPPUNIT_ASSERT(search->currentItem() != nullptr);
c8f4eac4 202
203 /* trigger another callback */
204 cbcalled = false;
aee3523a 205 search->next(searchCallback, nullptr);
5d1dff27 206 CPPUNIT_ASSERT_EQUAL(true, cbcalled);
c8f4eac4 207
208 /* now we should have no error, we should have finished and have no current item */
5d1dff27
FC
209 //CPPUNIT_ASSERT_EQUAL(false, search->next());
210 CPPUNIT_ASSERT_EQUAL(false, search->error());
211 CPPUNIT_ASSERT_EQUAL(true, search->isDone());
aee3523a 212 CPPUNIT_ASSERT_EQUAL(static_cast<StoreEntry *>(nullptr), search->currentItem());
c8f4eac4 213
214 free_cachedir(&Config.cacheSwap);
215
9837567d 216 // TODO: here we should test a dirty rebuild
c8f4eac4 217
b7717b61 218 safe_free(Config.replPolicy->type);
219 delete Config.replPolicy;
220
221 if (0 > system ("rm -rf " TESTDIR))
222 throw std::runtime_error("Failed to clean test work directory");
223}
224
26ac0430 225/* The UFS store should always configure an IO engine even if none is
b7717b61 226 * supplied on the configuration line.
227 */
228void
41e9c9f0 229TestUfs::testUfsDefaultEngine()
b7717b61 230{
231 /* boring common test boilerplate */
232 if (0 > system ("rm -rf " TESTDIR))
233 throw std::runtime_error("Failed to clean test work directory");
234
2745fea5 235 MySwapDirPointer aStore (new Fs::Ufs::UFSSwapDir("ufs", "Blocking"));
b7717b61 236 addSwapDir(aStore);
237 commonInit();
238 Config.replPolicy = new RemovalPolicySettings;
86c63190 239 Config.replPolicy->type = xstrdup("lru");
b7717b61 240 mem_policy = createRemovalPolicy(Config.replPolicy);
241
242 char *path=xstrdup(TESTDIR);
2eceb328
CT
243 char *config_line=xstrdup("100 1 1");
244 ConfigParser::SetCfgLine(config_line);
b7717b61 245 aStore->parse(0, path);
246 safe_free(path);
247 safe_free(config_line);
aee3523a 248 CPPUNIT_ASSERT(aStore->IO->io != nullptr);
b7717b61 249
d5d5493b 250 free_cachedir(&Config.cacheSwap);
c8f4eac4 251 safe_free(Config.replPolicy->type);
252 delete Config.replPolicy;
253
2e050051 254 if (0 > system ("rm -rf " TESTDIR))
c8f4eac4 255 throw std::runtime_error("Failed to clean test work directory");
256}
f53969cc 257
53a5a6de
AR
258int
259main(int argc, char *argv[])
260{
261 return TestProgram().run(argc, argv);
262}
263