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
72static void
74{
78}
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
89
90 store = new Rock::SwapDir();
91
93
94 char *path=xstrdup(TESTDIR);
95
96 char *config_line=xstrdup("10 max-size=16384");
97
98 ConfigParser::SetCfgLine(config_line);
99
100 store->parse(0, path);
101 store_maxobjsize = 1024*1024*2;
102
103 safe_free(path);
104
105 safe_free(config_line);
106
107 /* ok, ready to create */
108 store->create();
109
110 rr = new Rock::SwapDirRr;
111 rr->useConfig();
112}
113
114void
116{
117 CPPUNIT_NS::TestFixture::tearDown();
118
120
121 store = nullptr;
122
124
125 rr->finishShutdown(); // deletes rr
126 rr = nullptr;
127
128 // TODO: do this once, or each time.
129 // safe_free(Config.replPolicy->type);
130 // delete Config.replPolicy;
131
132 if (0 > system ("rm -rf " TESTDIR))
133 throw std::runtime_error("Failed to clean test work directory");
134}
135
136void
138{
139 /* ok, ready to use */
140 Store::Root().init();
141
142 /* rebuild is a scheduled event */
143 StockEventLoop loop;
144
145 /* our swapdir must be scheduled to rebuild */
146 CPPUNIT_ASSERT_EQUAL(2, StoreController::store_dirs_rebuilding);
147
148 loop.run();
149
150 /* cannot use loop.run(); as the loop will never idle: the store-dir
151 * clean() scheduled event prevents it
152 */
153
154 /* nothing left to rebuild */
155 CPPUNIT_ASSERT_EQUAL(0, StoreController::store_dirs_rebuilding);
156}
157
158static const char *
159storeId(const int i)
160{
161 static char buf[64];
162 snprintf(buf, sizeof(buf), "dummy url %i", i);
163 buf[sizeof(buf) - 1] = '\0';
164 return buf;
165}
166
169{
170 RequestFlags flags;
171 flags.cachable.support();
172 StoreEntry *const pe =
173 storeCreateEntry(storeId(i), "dummy log url", flags, Http::METHOD_GET);
174 auto &rep = pe->mem().adjustableBaseReply();
175 rep.setHeaders(Http::scOkay, "dummy test object", "x-squid-internal/test", 0, -1, squid_curtime + 100000);
176
177 pe->setPublicKey();
178
179 return pe;
180}
181
184{
185 StoreEntry *const pe = createEntry(i);
186
187 pe->buffer();
189 pe->flush();
190 pe->timestampsSet();
191 pe->complete();
192 pe->swapOut();
193
194 return pe;
195}
196
199{
201}
202
203void
205{
206 struct stat sb;
207
208 CPPUNIT_ASSERT_EQUAL(0, ::stat(TESTDIR, &sb));
209
210 /* TODO: check the size */
211
212 /* TODO: test rebuild */
213}
214
215void
217{
218 storeInit();
219
220 // add few entries to prime the database
221 for (int i = 0; i < 5; ++i) {
222 CPPUNIT_ASSERT_EQUAL((uint64_t)i, store->currentCount());
223
224 StoreEntry *const pe = addEntry(i);
225
226 CPPUNIT_ASSERT_EQUAL(SWAPOUT_WRITING, pe->swap_status);
227 CPPUNIT_ASSERT_EQUAL(0, pe->swap_dirn);
228 CPPUNIT_ASSERT(pe->swap_filen >= 0);
229
230 // Rock::IoState::finishedWriting() schedules an AsyncCall
231 // storeSwapOutFileClosed(). Let it fire.
232 StockEventLoop loop;
233 loop.run();
234
235 CPPUNIT_ASSERT_EQUAL(SWAPOUT_DONE, pe->swap_status);
236
237 pe->unlock("TestRock::testRockSwapOut priming");
238 }
239
240 CPPUNIT_ASSERT_EQUAL((uint64_t)5, store->currentCount());
241
242 // try to swap out entry to a used unlocked slot
243 {
244 // without marking the old entry as deleted
245 StoreEntry *const pe = addEntry(3);
246
247 CPPUNIT_ASSERT_EQUAL(SWAPOUT_NONE, pe->swap_status);
248 CPPUNIT_ASSERT_EQUAL(-1, pe->swap_dirn);
249 CPPUNIT_ASSERT_EQUAL(-1, pe->swap_filen);
250 pe->unlock("TestRock::testRockSwapOut e#3");
251
252 // after marking the old entry as deleted
253 StoreEntry *const pe2 = getEntry(4);
254 CPPUNIT_ASSERT(pe2 != nullptr);
255 pe2->release();
256
257 StoreEntry *const pe3 = addEntry(4);
258 CPPUNIT_ASSERT_EQUAL(SWAPOUT_WRITING, pe3->swap_status);
259 CPPUNIT_ASSERT_EQUAL(0, pe3->swap_dirn);
260 CPPUNIT_ASSERT(pe3->swap_filen >= 0);
261
262 StockEventLoop loop;
263 loop.run();
264
265 CPPUNIT_ASSERT_EQUAL(SWAPOUT_DONE, pe3->swap_status);
266
267 pe->unlock("TestRock::testRockSwapOut e#4");
268 }
269
270 // try to swap out entry to a used locked slot
271 {
272 StoreEntry *const pe = addEntry(5);
273
274 CPPUNIT_ASSERT_EQUAL(SWAPOUT_WRITING, pe->swap_status);
275 CPPUNIT_ASSERT_EQUAL(0, pe->swap_dirn);
276 CPPUNIT_ASSERT(pe->swap_filen >= 0);
277
278 // the slot is locked here because the async calls have not run yet
279 StoreEntry *const pe2 = addEntry(5);
280 CPPUNIT_ASSERT_EQUAL(SWAPOUT_NONE, pe2->swap_status);
281 CPPUNIT_ASSERT_EQUAL(MemObject::SwapOut::swImpossible, pe2->mem_obj->swapout.decision);
282 CPPUNIT_ASSERT_EQUAL(-1, pe2->swap_dirn);
283 CPPUNIT_ASSERT_EQUAL(-1, pe2->swap_filen);
284
285 StockEventLoop loop;
286 loop.run();
287
288 pe->unlock("TestRock::testRockSwapOut e#5.1");
289 pe2->unlock("TestRock::testRockSwapOut e#5.2");
290
291 // pe2 has the same public key as pe so it marks old pe for release
292 // here, we add another entry #5 into the now-available slot
293 StoreEntry *const pe3 = addEntry(5);
294 CPPUNIT_ASSERT_EQUAL(SWAPOUT_WRITING, pe3->swap_status);
295 CPPUNIT_ASSERT_EQUAL(0, pe3->swap_dirn);
296 CPPUNIT_ASSERT(pe3->swap_filen >= 0);
297 loop.run();
298 CPPUNIT_ASSERT_EQUAL(SWAPOUT_DONE, pe3->swap_status);
299 pe3->unlock("TestRock::testRockSwapOut e#5.3");
300 }
301
302 CPPUNIT_ASSERT_EQUAL((uint64_t)6, store->currentCount());
303
304 // try to get and release all entries
305 for (int i = 0; i < 6; ++i) {
306 StoreEntry *const pe = getEntry(i);
307 CPPUNIT_ASSERT(pe != nullptr);
308
309 pe->release(); // destroys pe
310
311 StoreEntry *const pe2 = getEntry(i);
312 CPPUNIT_ASSERT_EQUAL(static_cast<StoreEntry *>(nullptr), pe2);
313 }
314}
315
317class MyTestProgram: public TestProgram
318{
319public:
320 /* TestProgram API */
321 void startup() override;
322};
323
324void
326{
329
330 // use current directory for shared segments (on path-based OSes)
331 static char cwd[MAXPATHLEN];
335
339
341
343 Config.replPolicy->type = xstrdup("lru");
344 Config.replPolicy->args = nullptr;
345
346 /* garh garh */
349
351
352 Mem::Init();
353 fde::Init();
354 comm_init();
355 httpHeaderInitModule(); /* must go before any header processing (e.g. the one in errorInitialize) */
356
358}
359
360int
361main(int argc, char *argv[])
362{
363 return MyTestProgram().run(argc, argv);
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:1657
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: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: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: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
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:264
int64_t avgObjectSize
Definition: SquidConfig.h:265
RemovalPolicySettings * replPolicy
Definition: SquidConfig.h:99
Store::DiskConfig cacheSwap
Definition: SquidConfig.h:423
YesNoNone shmLocking
shared_memory_locking
Definition: SquidConfig.h:90
struct SquidConfig::@104 Store
int64_t maxObjectSize
Definition: SquidConfig.h:266
char * store_dir_select_algorithm
Definition: SquidConfig.h:500
YesNoNone memShared
whether the memory cache is shared among workers
Definition: SquidConfig.h:89
MemObject & mem()
Definition: Store.h:51
sdirno swap_dirn
Definition: Store.h:238
int unlock(const char *context)
Definition: store.cc:455
void complete()
Definition: store.cc:1017
void release(const bool shareable=false)
Definition: store.cc:1132
swap_status_t swap_status
Definition: Store.h:246
void flush() override
Definition: store.cc:1598
bool timestampsSet()
Definition: store.cc:1373
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:1587
bool setPublicKey(const KeyScope keyScope=ksDefault)
Definition: store.cc:561
void swapOut()
static int store_dirs_rebuilding
the number of cache_dirs being rebuilt; TODO: move to Disks::Rebuilding
Definition: Controller.h:134
void init() override
Definition: Controller.cc:58
RefCount< SwapDir > * swapDirs
Definition: SquidConfig.h:68
implements test program's main() function while enabling customization
Definition: unitTestMain.h:26
int run(int argc, char *argv[])
Definition: unitTestMain.h:44
void commonInit()
RefCount< Rock::SwapDir > SwapDirPointer
Definition: testRock.cc:55
StoreEntry * addEntry(const int i)
Definition: testRock.cc:183
CPPUNIT_TEST(testRockCreate)
StoreEntry * createEntry(const int i)
Definition: testRock.cc:168
void testRockCreate()
Definition: testRock.cc:204
void storeInit()
Definition: testRock.cc:137
void setUp() override
Definition: testRock.cc:81
StoreEntry * getEntry(const int i)
Definition: testRock.cc:198
CPPUNIT_TEST_SUITE(TestRock)
void testRockSwapOut()
Definition: testRock.cc:216
Rock::SwapDirRr * rr
Definition: testRock.cc:68
CPPUNIT_TEST_SUITE_END()
TestRock()
Definition: testRock.cc:51
void tearDown() override
Definition: testRock.cc:115
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:938
void FreeMemory()
undo Init()
Definition: Controller.cc:951
void Init(Controller *root=nullptr)
initialize the storage module; a custom root is used by unit tests only
Definition: Controller.cc:945
#define xstrdup
static struct stat sb
Definition: squidclient.cc:71
#define MAXPATHLEN
Definition: stdio.h:62
Store::Disk SwapDir
Definition: forward.h:59
StoreEntry * storeCreateEntry(const char *url, const char *logUrl, const RequestFlags &flags, const HttpRequestMethod &method)
Definition: store.cc:745
StoreEntry * storeGetPublic(const char *uri, const HttpRequestMethod &method)
Definition: store.cc:490
void storeReplAdd(const char *type, REMOVALPOLICYCREATE *create)
Definition: store.cc:1631
REMOVALPOLICYCREATE createRemovalPolicy_lru
int main(int argc, char *argv[])
Definition: testRock.cc:361
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:159
#define TESTDIR
Definition: testRock.cc:37
#define APP_FULLNAME
Definition: version.h:25
#define safe_free(x)
Definition: xalloc.h:73

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors