Squid Web Cache master
Loading...
Searching...
No Matches
testRock.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2025 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 "compat/cppunit.h"
11#include "ConfigParser.h"
12#include "DiskIO/DiskIOModule.h"
13#include "fde.h"
14#include "fs/rock/RockSwapDir.h"
15#include "globals.h"
16#include "HttpHeader.h"
17#include "HttpReply.h"
18#include "MemObject.h"
19#include "RequestFlags.h"
20#include "SquidConfig.h"
21#include "Store.h"
22#include "store/Disk.h"
23#include "store/Disks.h"
24#include "StoreFileSystem.h"
25#include "StoreSearch.h"
26#include "testStoreSupport.h"
27#include "unitTestMain.h"
28
29#include <stdexcept>
30#if HAVE_SYS_STAT_H
31#include <sys/stat.h>
32#endif
33#if HAVE_UNISTD_H
34#include <unistd.h>
35#endif
36
37#define TESTDIR "tr"
38
39/*
40 * test the store framework
41 */
42
43class TestRock : public CPPUNIT_NS::TestFixture
44{
49
50public:
51 TestRock() : rr(nullptr) {}
52 void setUp() override;
53 void tearDown() override;
54
56
57protected:
58 void commonInit();
59 void storeInit();
60 StoreEntry *createEntry(const int i);
61 StoreEntry *addEntry(const int i);
62 StoreEntry *getEntry(const int i);
63 void testRockCreate();
64 void testRockSwapOut();
65
66private:
69};
71
72static void
79
80void
82{
83 CPPUNIT_NS::TestFixture::setUp();
84
85 if (0 > system ("rm -rf " TESTDIR))
86 throw std::runtime_error("Failed to clean test work directory");
87
88 store = new Rock::SwapDir();
89
91
92 char *path=xstrdup(TESTDIR);
93
94 char *config_line=xstrdup("10 max-size=16384");
95
96 ConfigParser::SetCfgLine(config_line);
97
98 store->parse(0, path);
99 store_maxobjsize = 1024*1024*2;
100
101 safe_free(path);
102
103 safe_free(config_line);
104
105 /* ok, ready to create */
106 store->create();
107
108 rr = new Rock::SwapDirRr;
109 rr->useConfig();
110}
111
112void
114{
115 CPPUNIT_NS::TestFixture::tearDown();
116
117 store = nullptr;
118
120
121 rr->finishShutdown(); // deletes rr
122 rr = nullptr;
123
124 // TODO: do this once, or each time.
125 // safe_free(Config.replPolicy->type);
126 // delete Config.replPolicy;
127
128 if (0 > system ("rm -rf " TESTDIR))
129 throw std::runtime_error("Failed to clean test work directory");
130}
131
132void
134{
135 /* ok, ready to use */
136 Store::Root().init();
137
138 /* rebuild is a scheduled event */
139 StockEventLoop loop;
140
141 /* our swapdir must be scheduled to rebuild */
142 CPPUNIT_ASSERT_EQUAL(2, StoreController::store_dirs_rebuilding);
143
144 loop.run();
145
146 /* cannot use loop.run(); as the loop will never idle: the store-dir
147 * clean() scheduled event prevents it
148 */
149
150 /* nothing left to rebuild */
151 CPPUNIT_ASSERT_EQUAL(0, StoreController::store_dirs_rebuilding);
152}
153
154static const char *
155storeId(const int i)
156{
157 static char buf[64];
158 snprintf(buf, sizeof(buf), "dummy url %i", i);
159 buf[sizeof(buf) - 1] = '\0';
160 return buf;
161}
162
165{
166 RequestFlags flags;
167 flags.cachable.support();
168 StoreEntry *const pe =
169 storeCreateEntry(storeId(i), "dummy log url", flags, Http::METHOD_GET);
170 auto &rep = pe->mem().adjustableBaseReply();
171 rep.setHeaders(Http::scOkay, "dummy test object", "x-squid-internal/test", 0, -1, squid_curtime + 100000);
172
173 pe->setPublicKey();
174
175 return pe;
176}
177
180{
181 StoreEntry *const pe = createEntry(i);
182
183 pe->buffer();
185 pe->flush();
186 pe->timestampsSet();
187 pe->complete();
188 pe->swapOut();
189
190 return pe;
191}
192
195{
197}
198
199void
201{
202 struct stat sb;
203
204 CPPUNIT_ASSERT_EQUAL(0, ::stat(TESTDIR, &sb));
205
206 /* TODO: check the size */
207
208 /* TODO: test rebuild */
209}
210
211void
213{
214 storeInit();
215
216 // add few entries to prime the database
217 for (int i = 0; i < 5; ++i) {
218 CPPUNIT_ASSERT_EQUAL((uint64_t)i, store->currentCount());
219
220 StoreEntry *const pe = addEntry(i);
221
222 CPPUNIT_ASSERT_EQUAL(SWAPOUT_WRITING, pe->swap_status);
223 CPPUNIT_ASSERT_EQUAL(0, pe->swap_dirn);
224 CPPUNIT_ASSERT(pe->swap_filen >= 0);
225
226 // Rock::IoState::finishedWriting() schedules an AsyncCall
227 // storeSwapOutFileClosed(). Let it fire.
228 StockEventLoop loop;
229 loop.run();
230
231 CPPUNIT_ASSERT_EQUAL(SWAPOUT_DONE, pe->swap_status);
232
233 pe->unlock("TestRock::testRockSwapOut priming");
234 }
235
236 CPPUNIT_ASSERT_EQUAL((uint64_t)5, store->currentCount());
237
238 // try to swap out entry to a used unlocked slot
239 {
240 // without marking the old entry as deleted
241 StoreEntry *const pe = addEntry(3);
242
243 CPPUNIT_ASSERT_EQUAL(SWAPOUT_NONE, pe->swap_status);
244 CPPUNIT_ASSERT_EQUAL(-1, pe->swap_dirn);
245 CPPUNIT_ASSERT_EQUAL(-1, pe->swap_filen);
246 pe->unlock("TestRock::testRockSwapOut e#3");
247
248 // after marking the old entry as deleted
249 StoreEntry *const pe2 = getEntry(4);
250 CPPUNIT_ASSERT(pe2 != nullptr);
251 pe2->release();
252
253 StoreEntry *const pe3 = addEntry(4);
254 CPPUNIT_ASSERT_EQUAL(SWAPOUT_WRITING, pe3->swap_status);
255 CPPUNIT_ASSERT_EQUAL(0, pe3->swap_dirn);
256 CPPUNIT_ASSERT(pe3->swap_filen >= 0);
257
258 StockEventLoop loop;
259 loop.run();
260
261 CPPUNIT_ASSERT_EQUAL(SWAPOUT_DONE, pe3->swap_status);
262
263 pe->unlock("TestRock::testRockSwapOut e#4");
264 }
265
266 // try to swap out entry to a used locked slot
267 {
268 StoreEntry *const pe = addEntry(5);
269
270 CPPUNIT_ASSERT_EQUAL(SWAPOUT_WRITING, pe->swap_status);
271 CPPUNIT_ASSERT_EQUAL(0, pe->swap_dirn);
272 CPPUNIT_ASSERT(pe->swap_filen >= 0);
273
274 // the slot is locked here because the async calls have not run yet
275 StoreEntry *const pe2 = addEntry(5);
276 CPPUNIT_ASSERT_EQUAL(SWAPOUT_NONE, pe2->swap_status);
277 CPPUNIT_ASSERT_EQUAL(MemObject::SwapOut::swImpossible, pe2->mem_obj->swapout.decision);
278 CPPUNIT_ASSERT_EQUAL(-1, pe2->swap_dirn);
279 CPPUNIT_ASSERT_EQUAL(-1, pe2->swap_filen);
280
281 StockEventLoop loop;
282 loop.run();
283
284 pe->unlock("TestRock::testRockSwapOut e#5.1");
285 pe2->unlock("TestRock::testRockSwapOut e#5.2");
286
287 // pe2 has the same public key as pe so it marks old pe for release
288 // here, we add another entry #5 into the now-available slot
289 StoreEntry *const pe3 = addEntry(5);
290 CPPUNIT_ASSERT_EQUAL(SWAPOUT_WRITING, pe3->swap_status);
291 CPPUNIT_ASSERT_EQUAL(0, pe3->swap_dirn);
292 CPPUNIT_ASSERT(pe3->swap_filen >= 0);
293 loop.run();
294 CPPUNIT_ASSERT_EQUAL(SWAPOUT_DONE, pe3->swap_status);
295 pe3->unlock("TestRock::testRockSwapOut e#5.3");
296 }
297
298 CPPUNIT_ASSERT_EQUAL((uint64_t)6, store->currentCount());
299
300 // try to get and release all entries
301 for (int i = 0; i < 6; ++i) {
302 StoreEntry *const pe = getEntry(i);
303 CPPUNIT_ASSERT(pe != nullptr);
304
305 pe->release(); // destroys pe
306
307 StoreEntry *const pe2 = getEntry(i);
308 CPPUNIT_ASSERT_EQUAL(static_cast<StoreEntry *>(nullptr), pe2);
309 }
310}
311
313class MyTestProgram: public TestProgram
314{
315public:
316 /* TestProgram API */
317 void startup() override;
318};
319
320void
322{
325
326 // use current directory for shared segments (on path-based OSes)
327 static char cwd[MAXPATHLEN];
331
335
337
339 Config.replPolicy->type = xstrdup("lru");
340 Config.replPolicy->args = nullptr;
341
342 /* garh garh */
345
347
348 Mem::Init();
349 fde::Init();
350 comm_init();
351 httpHeaderInitModule(); /* must go before any header processing (e.g. the one in errorInitialize) */
352
354}
355
356int
357main(int argc, char *argv[])
358{
359 return MyTestProgram().run(argc, argv);
360}
361
void free_cachedir(Store::DiskConfig *swap)
Definition Disks.cc:800
void allocate_new_swapdir(Store::DiskConfig &swap)
Definition Disks.cc:781
void httpHeaderInitModule(void)
RemovalPolicy * mem_policy
Definition MemObject.cc:44
time_t squid_curtime
RemovalPolicy * REMOVALPOLICYCREATE(wordlist *args)
RemovalPolicy * createRemovalPolicy(RemovalPolicySettings *settings)
Definition store.cc:1671
class SquidConfig Config
static void SetCfgLine(char *line)
Set the configuration file line to parse.
void run()
Definition EventLoop.cc:76
void setHeaders(Http::StatusCode status, const char *reason, const char *ctype, int64_t clen, time_t lmt, time_t expires)
Definition HttpReply.cc:170
void packHeadersUsingSlowPacker(Packable &p) const
same as packHeadersUsingFastPacker() but assumes that p cannot quickly process small additions
Definition HttpReply.cc:95
void useConfig() override
Definition Segment.cc:375
static const char * BasePath
common path of all segment names in path-based environments
Definition Segment.h:45
Decision decision
current decision state
Definition MemObject.h:166
SwapOut swapout
Definition MemObject.h:169
const HttpReply & freshestReply() const
Definition MemObject.h:68
HttpReply & adjustableBaseReply()
Definition MemObject.cc:121
customizes our test setup
void startup() override
C * getRaw() const
Definition RefCount.h:89
virtual void finishShutdown()
Meant for cleanup of services needed by the already destroyed objects.
SupportOrVeto cachable
whether the response may be stored in the cache
initializes shared memory segments used by Rock::SwapDir
uint64_t currentCount() const override
the total number of objects stored right now
void parse(int index, char *path) override
void create() override
create system resources needed for this store to operate in the future
int objectsPerBucket
int64_t avgObjectSize
RemovalPolicySettings * replPolicy
Definition SquidConfig.h:99
Store::DiskConfig cacheSwap
YesNoNone shmLocking
shared_memory_locking
Definition SquidConfig.h:90
int64_t maxObjectSize
char * store_dir_select_algorithm
struct SquidConfig::@88 Store
YesNoNone memShared
whether the memory cache is shared among workers
Definition SquidConfig.h:89
MemObject & mem()
Definition Store.h:47
sdirno swap_dirn
Definition Store.h:237
int unlock(const char *context)
Definition store.cc:469
void complete()
Definition store.cc:1031
void release(const bool shareable=false)
Definition store.cc:1146
swap_status_t swap_status
Definition Store.h:245
void flush() override
Definition store.cc:1612
bool timestampsSet()
Definition store.cc:1387
sfileno swap_filen
unique ID inside a cache_dir for swapped out entries; -1 for others
Definition Store.h:235
MemObject * mem_obj
Definition Store.h:220
void buffer() override
Definition store.cc:1601
bool setPublicKey(const KeyScope keyScope=ksDefault)
Definition store.cc:575
static int store_dirs_rebuilding
the number of cache_dirs being rebuilt; TODO: move to Disks::Rebuilding
Definition Controller.h:133
void init() override
Definition Controller.cc:53
RefCount< SwapDir > * swapDirs
Definition SquidConfig.h:68
implements test program's main() function while enabling customization
int run(int argc, char *argv[])
void commonInit()
RefCount< Rock::SwapDir > SwapDirPointer
Definition testRock.cc:55
StoreEntry * addEntry(const int i)
Definition testRock.cc:179
CPPUNIT_TEST(testRockCreate)
StoreEntry * createEntry(const int i)
Definition testRock.cc:164
void testRockCreate()
Definition testRock.cc:200
void storeInit()
Definition testRock.cc:133
void setUp() override
Definition testRock.cc:81
StoreEntry * getEntry(const int i)
Definition testRock.cc:194
CPPUNIT_TEST_SUITE(TestRock)
void testRockSwapOut()
Definition testRock.cc:212
Rock::SwapDirRr * rr
Definition testRock.cc:68
CPPUNIT_TEST_SUITE_END()
void tearDown() override
Definition testRock.cc:113
CPPUNIT_TEST(testRockSwapOut)
SwapDirPointer store
Definition testRock.cc:67
void defaultTo(bool beSet)
enables or disables the option; updating to 'implicit' state
Definition YesNoNone.h:59
static void Init()
Definition fde.cc:141
void comm_init(void)
Definition comm.cc:1141
@ SWAPOUT_NONE
Definition enums.h:53
@ SWAPOUT_WRITING
Definition enums.h:56
@ SWAPOUT_DONE
Definition enums.h:59
char const * visible_appname_string
int64_t store_maxobjsize
int main()
@ scOkay
Definition StatusCode.h:27
@ METHOD_GET
Definition MethodType.h:25
void Init()
Definition old_api.cc:281
Controller & Root()
safely access controller singleton
#define xstrdup
#define MAXPATHLEN
Definition stdio.h:62
StoreEntry * storeCreateEntry(const char *url, const char *logUrl, const RequestFlags &flags, const HttpRequestMethod &method)
Definition store.cc:759
StoreEntry * storeGetPublic(const char *uri, const HttpRequestMethod &method)
Definition store.cc:504
void storeReplAdd(const char *type, REMOVALPOLICYCREATE *create)
Definition store.cc:1645
REMOVALPOLICYCREATE createRemovalPolicy_lru
static void addSwapDir(TestRock::SwapDirPointer aStore)
Definition testRock.cc:73
CPPUNIT_TEST_SUITE_REGISTRATION(TestRock)
static const char * storeId(const int i)
Definition testRock.cc:155
#define TESTDIR
Definition testRock.cc:37
#define APP_FULLNAME
Definition version.h:25
#define safe_free(x)
Definition xalloc.h:73