testRock.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2023 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
73
74static char cwd[MAXPATHLEN];
75
76static void
78{
82}
83
84void
86{
87 CPPUNIT_NS::TestFixture::setUp();
88
89 if (0 > system ("rm -rf " TESTDIR))
90 throw std::runtime_error("Failed to clean test work directory");
91
94
95 // use current directory for shared segments (on path-based OSes)
97 if (Ipc::Mem::Segment::BasePath == nullptr)
99
100 Store::Init();
101
102 store = new Rock::SwapDir();
103
105
106 commonInit();
107
108 char *path=xstrdup(TESTDIR);
109
110 char *config_line=xstrdup("10 max-size=16384");
111
112 ConfigParser::SetCfgLine(config_line);
113
114 store->parse(0, path);
115 store_maxobjsize = 1024*1024*2;
116
117 safe_free(path);
118
119 safe_free(config_line);
120
121 /* ok, ready to create */
122 store->create();
123
124 rr = new Rock::SwapDirRr;
125 rr->useConfig();
126}
127
128void
130{
131 CPPUNIT_NS::TestFixture::tearDown();
132
134
135 store = nullptr;
136
138
139 rr->finishShutdown(); // deletes rr
140 rr = nullptr;
141
142 // TODO: do this once, or each time.
143 // safe_free(Config.replPolicy->type);
144 // delete Config.replPolicy;
145
146 if (0 > system ("rm -rf " TESTDIR))
147 throw std::runtime_error("Failed to clean test work directory");
148}
149
150void
152{
153 static bool inited = false;
154
155 if (inited)
156 return;
157
161
163
165 Config.replPolicy->type = xstrdup("lru");
166 Config.replPolicy->args = nullptr;
167
168 /* garh garh */
170
172
173 Mem::Init();
174
175 fde::Init();
176
177 comm_init();
178
179 httpHeaderInitModule(); /* must go before any header processing (e.g. the one in errorInitialize) */
180
182
183 inited = true;
184}
185
186void
188{
189 /* ok, ready to use */
190 Store::Root().init();
191
192 /* rebuild is a scheduled event */
193 StockEventLoop loop;
194
195 /* our swapdir must be scheduled to rebuild */
196 CPPUNIT_ASSERT_EQUAL(2, StoreController::store_dirs_rebuilding);
197
198 loop.run();
199
200 /* cannot use loop.run(); as the loop will never idle: the store-dir
201 * clean() scheduled event prevents it
202 */
203
204 /* nothing left to rebuild */
205 CPPUNIT_ASSERT_EQUAL(0, StoreController::store_dirs_rebuilding);
206}
207
208static const char *
209storeId(const int i)
210{
211 static char buf[64];
212 snprintf(buf, sizeof(buf), "dummy url %i", i);
213 buf[sizeof(buf) - 1] = '\0';
214 return buf;
215}
216
219{
220 RequestFlags flags;
221 flags.cachable.support();
222 StoreEntry *const pe =
223 storeCreateEntry(storeId(i), "dummy log url", flags, Http::METHOD_GET);
224 auto &rep = pe->mem().adjustableBaseReply();
225 rep.setHeaders(Http::scOkay, "dummy test object", "x-squid-internal/test", 0, -1, squid_curtime + 100000);
226
227 pe->setPublicKey();
228
229 return pe;
230}
231
234{
235 StoreEntry *const pe = createEntry(i);
236
237 pe->buffer();
239 pe->flush();
240 pe->timestampsSet();
241 pe->complete();
242 pe->swapOut();
243
244 return pe;
245}
246
249{
251}
252
253void
255{
256 struct stat sb;
257
258 CPPUNIT_ASSERT_EQUAL(0, ::stat(TESTDIR, &sb));
259
260 /* TODO: check the size */
261
262 /* TODO: test rebuild */
263}
264
265void
267{
268 storeInit();
269
270 // add few entries to prime the database
271 for (int i = 0; i < 5; ++i) {
272 CPPUNIT_ASSERT_EQUAL((uint64_t)i, store->currentCount());
273
274 StoreEntry *const pe = addEntry(i);
275
276 CPPUNIT_ASSERT_EQUAL(SWAPOUT_WRITING, pe->swap_status);
277 CPPUNIT_ASSERT_EQUAL(0, pe->swap_dirn);
278 CPPUNIT_ASSERT(pe->swap_filen >= 0);
279
280 // Rock::IoState::finishedWriting() schedules an AsyncCall
281 // storeSwapOutFileClosed(). Let it fire.
282 StockEventLoop loop;
283 loop.run();
284
285 CPPUNIT_ASSERT_EQUAL(SWAPOUT_DONE, pe->swap_status);
286
287 pe->unlock("TestRock::testRockSwapOut priming");
288 }
289
290 CPPUNIT_ASSERT_EQUAL((uint64_t)5, store->currentCount());
291
292 // try to swap out entry to a used unlocked slot
293 {
294 // without marking the old entry as deleted
295 StoreEntry *const pe = addEntry(3);
296
297 CPPUNIT_ASSERT_EQUAL(SWAPOUT_NONE, pe->swap_status);
298 CPPUNIT_ASSERT_EQUAL(-1, pe->swap_dirn);
299 CPPUNIT_ASSERT_EQUAL(-1, pe->swap_filen);
300 pe->unlock("TestRock::testRockSwapOut e#3");
301
302 // after marking the old entry as deleted
303 StoreEntry *const pe2 = getEntry(4);
304 CPPUNIT_ASSERT(pe2 != nullptr);
305 pe2->release();
306
307 StoreEntry *const pe3 = addEntry(4);
308 CPPUNIT_ASSERT_EQUAL(SWAPOUT_WRITING, pe3->swap_status);
309 CPPUNIT_ASSERT_EQUAL(0, pe3->swap_dirn);
310 CPPUNIT_ASSERT(pe3->swap_filen >= 0);
311
312 StockEventLoop loop;
313 loop.run();
314
315 CPPUNIT_ASSERT_EQUAL(SWAPOUT_DONE, pe3->swap_status);
316
317 pe->unlock("TestRock::testRockSwapOut e#4");
318 }
319
320 // try to swap out entry to a used locked slot
321 {
322 StoreEntry *const pe = addEntry(5);
323
324 CPPUNIT_ASSERT_EQUAL(SWAPOUT_WRITING, pe->swap_status);
325 CPPUNIT_ASSERT_EQUAL(0, pe->swap_dirn);
326 CPPUNIT_ASSERT(pe->swap_filen >= 0);
327
328 // the slot is locked here because the async calls have not run yet
329 StoreEntry *const pe2 = addEntry(5);
330 CPPUNIT_ASSERT_EQUAL(SWAPOUT_NONE, pe2->swap_status);
331 CPPUNIT_ASSERT_EQUAL(MemObject::SwapOut::swImpossible, pe2->mem_obj->swapout.decision);
332 CPPUNIT_ASSERT_EQUAL(-1, pe2->swap_dirn);
333 CPPUNIT_ASSERT_EQUAL(-1, pe2->swap_filen);
334
335 StockEventLoop loop;
336 loop.run();
337
338 pe->unlock("TestRock::testRockSwapOut e#5.1");
339 pe2->unlock("TestRock::testRockSwapOut e#5.2");
340
341 // pe2 has the same public key as pe so it marks old pe for release
342 // here, we add another entry #5 into the now-available slot
343 StoreEntry *const pe3 = addEntry(5);
344 CPPUNIT_ASSERT_EQUAL(SWAPOUT_WRITING, pe3->swap_status);
345 CPPUNIT_ASSERT_EQUAL(0, pe3->swap_dirn);
346 CPPUNIT_ASSERT(pe3->swap_filen >= 0);
347 loop.run();
348 CPPUNIT_ASSERT_EQUAL(SWAPOUT_DONE, pe3->swap_status);
349 pe3->unlock("TestRock::testRockSwapOut e#5.3");
350 }
351
352 CPPUNIT_ASSERT_EQUAL((uint64_t)6, store->currentCount());
353
354 // try to get and release all entries
355 for (int i = 0; i < 6; ++i) {
356 StoreEntry *const pe = getEntry(i);
357 CPPUNIT_ASSERT(pe != nullptr);
358
359 pe->release(); // destroys pe
360
361 StoreEntry *const pe2 = getEntry(i);
362 CPPUNIT_ASSERT_EQUAL(static_cast<StoreEntry *>(nullptr), pe2);
363 }
364}
365
void free_cachedir(Store::DiskConfig *swap)
Definition: Disks.cc:805
void allocate_new_swapdir(Store::DiskConfig &swap)
Definition: Disks.cc:786
void httpHeaderInitModule(void)
Definition: HttpHeader.cc:121
RemovalPolicy * mem_policy
Definition: MemObject.cc:44
time_t squid_curtime
Definition: stub_libtime.cc:20
RemovalPolicy * REMOVALPOLICYCREATE(wordlist *args)
Definition: RemovalPolicy.h:80
RemovalPolicy * createRemovalPolicy(RemovalPolicySettings *settings)
Definition: store.cc:1639
class SquidConfig Config
Definition: SquidConfig.cc:12
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:167
void packHeadersUsingSlowPacker(Packable &p) const
same as packHeadersUsingFastPacker() but assumes that p cannot quickly process small additions
Definition: HttpReply.cc:93
void useConfig() override
Definition: Segment.cc:377
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:156
SwapOut swapout
Definition: MemObject.h:159
const HttpReply & freshestReply() const
Definition: MemObject.h:67
HttpReply & adjustableBaseReply()
Definition: MemObject.cc:121
C * getRaw() const
Definition: RefCount.h:80
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
Definition: RequestFlags.h:35
initializes shared memory segments used by Rock::SwapDir
Definition: RockSwapDir.h:156
uint64_t currentCount() const override
the total number of objects stored right now
Definition: RockSwapDir.cc:156
void parse(int index, char *path) override
Definition: RockSwapDir.cc:320
void create() override
create system resources needed for this store to operate in the future
Definition: RockSwapDir.cc:211
int objectsPerBucket
Definition: SquidConfig.h:262
int64_t avgObjectSize
Definition: SquidConfig.h:263
RemovalPolicySettings * replPolicy
Definition: SquidConfig.h:97
Store::DiskConfig cacheSwap
Definition: SquidConfig.h:421
YesNoNone shmLocking
shared_memory_locking
Definition: SquidConfig.h:88
struct SquidConfig::@104 Store
int64_t maxObjectSize
Definition: SquidConfig.h:264
char * store_dir_select_algorithm
Definition: SquidConfig.h:508
YesNoNone memShared
whether the memory cache is shared among workers
Definition: SquidConfig.h:87
MemObject & mem()
Definition: Store.h:51
sdirno swap_dirn
Definition: Store.h:238
int unlock(const char *context)
Definition: store.cc:443
void complete()
Definition: store.cc:1005
void release(const bool shareable=false)
Definition: store.cc:1120
swap_status_t swap_status
Definition: Store.h:246
void flush() override
Definition: store.cc:1580
bool timestampsSet()
Definition: store.cc:1361
sfileno swap_filen
unique ID inside a cache_dir for swapped out entries; -1 for others
Definition: Store.h:236
MemObject * mem_obj
Definition: Store.h:221
void buffer() override
Definition: store.cc:1569
bool setPublicKey(const KeyScope keyScope=ksDefault)
Definition: store.cc:549
void swapOut()
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:58
RefCount< SwapDir > * swapDirs
Definition: SquidConfig.h:66
void commonInit()
Definition: testRock.cc:151
RefCount< Rock::SwapDir > SwapDirPointer
Definition: testRock.cc:55
StoreEntry * addEntry(const int i)
Definition: testRock.cc:233
CPPUNIT_TEST(testRockCreate)
StoreEntry * createEntry(const int i)
Definition: testRock.cc:218
void testRockCreate()
Definition: testRock.cc:254
void storeInit()
Definition: testRock.cc:187
void setUp() override
Definition: testRock.cc:85
StoreEntry * getEntry(const int i)
Definition: testRock.cc:248
CPPUNIT_TEST_SUITE(TestRock)
void testRockSwapOut()
Definition: testRock.cc:266
Rock::SwapDirRr * rr
Definition: testRock.cc:68
CPPUNIT_TEST_SUITE_END()
TestRock()
Definition: testRock.cc:51
void tearDown() override
Definition: testRock.cc:129
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:1166
@ SWAPOUT_NONE
Definition: enums.h:58
@ SWAPOUT_WRITING
Definition: enums.h:61
@ SWAPOUT_DONE
Definition: enums.h:64
char const * visible_appname_string
int64_t store_maxobjsize
@ scOkay
Definition: StatusCode.h:26
@ METHOD_GET
Definition: MethodType.h:25
void Init()
Definition: old_api.cc:425
Controller & Root()
safely access controller singleton
Definition: Controller.cc:931
void FreeMemory()
undo Init()
Definition: Controller.cc:944
void Init(Controller *root=nullptr)
initialize the storage module; a custom root is used by unit tests only
Definition: Controller.cc:938
#define xstrdup
static struct stat sb
Definition: squidclient.cc:71
#define MAXPATHLEN
Definition: stdio.h:62
Store::Disk SwapDir
Definition: forward.h:58
StoreEntry * storeCreateEntry(const char *url, const char *logUrl, const RequestFlags &flags, const HttpRequestMethod &method)
Definition: store.cc:733
StoreEntry * storeGetPublic(const char *uri, const HttpRequestMethod &method)
Definition: store.cc:478
void storeReplAdd(const char *type, REMOVALPOLICYCREATE *create)
Definition: store.cc:1613
static void addSwapDir(TestRock::SwapDirPointer aStore)
Definition: testRock.cc:77
CPPUNIT_TEST_SUITE_REGISTRATION(TestRock)
static const char * storeId(const int i)
Definition: testRock.cc:209
REMOVALPOLICYCREATE createRemovalPolicy_lru
#define TESTDIR
Definition: testRock.cc:37
static char cwd[MAXPATHLEN]
Definition: testRock.cc:74
#define APP_FULLNAME
Definition: version.h:25
#define safe_free(x)
Definition: xalloc.h:73

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors