testUfs.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 "DiskIO/DiskIOModule.h"
12 #include "fde.h"
13 #include "fs/ufs/UFSSwapDir.h"
14 #include "globals.h"
15 #include "HttpHeader.h"
16 #include "HttpReply.h"
17 #include "MemObject.h"
18 #include "RequestFlags.h"
19 #include "SquidConfig.h"
20 #include "Store.h"
21 #include "store/Disks.h"
22 #include "testStoreSupport.h"
23 #include "unitTestMain.h"
24 
25 #include <stdexcept>
26 
27 #define TESTDIR "TestUfs_Store"
28 
29 /*
30  * test the store framework
31  */
32 
33 class TestUfs : public CPPUNIT_NS::TestFixture
34 {
39 
40 public:
41 protected:
42  void commonInit();
43  void testUfsSearch();
44  void testUfsDefaultEngine();
45 };
47 
49 extern REMOVALPOLICYCREATE createRemovalPolicy_lru; /* XXX fails with --enable-removal-policies=heap */
50 
51 static void
53 {
57 }
58 
59 static bool cbcalled;
60 
61 static void
63 {
64  cbcalled = true;
65 }
66 
67 void
69 {
70  static bool inited = false;
71 
72  if (inited)
73  return;
74 
75  Config.Store.avgObjectSize = 1024;
77  Config.Store.maxObjectSize = 2048;
78 
79  Config.store_dir_select_algorithm = xstrdup("round-robin");
80 
82  Config.replPolicy->type = xstrdup("lru");
83 
84  Config.memShared.defaultTo(false);
85 
86  /* garh garh */
88 
89  Mem::Init();
90 
91  fde::Init();
92 
93  comm_init();
94 
95  httpHeaderInitModule(); /* must go before any header processing (e.g. the one in errorInitialize) */
96 
97  inited = true;
98 }
99 
100 void
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 
113  MySwapDirPointer aStore (new Fs::Ufs::UFSSwapDir("ufs", "Blocking"));
114 
115  aStore->IO = new Fs::Ufs::UFSStrategy(DiskIOModule::Find("Blocking")->createStrategy());
116 
117  addSwapDir(aStore);
118 
119  commonInit();
121 
122  char *path=xstrdup(TESTDIR);
123 
124  char *config_line=xstrdup("100 1 1");
125 
126  visible_appname_string = xstrdup(PACKAGE "/" VERSION);
127 
128  ConfigParser::SetCfgLine(config_line);
129 
130  aStore->parse(0, path);
131  store_maxobjsize = 1024*1024*2;
132 
133  safe_free(path);
134 
135  safe_free(config_line);
136 
137  /* ok, ready to create */
138  aStore->create();
139 
140  /* ok, ready to use - inits store & hash too */
141  Store::Root().init();
142 
143  /* our swapdir must be scheduled to rebuild */
144  CPPUNIT_ASSERT_EQUAL(2, StoreController::store_dirs_rebuilding);
145 
146  /* rebuild is a scheduled event */
147  StockEventLoop loop;
148 
150  loop.runOnce();
151 
152  /* cannot use loop.run(); as the loop will never idle: the store-dir
153  * clean() scheduled event prevents it
154  */
155 
156  /* nothing left to rebuild */
157  CPPUNIT_ASSERT_EQUAL(0, StoreController::store_dirs_rebuilding);
158 
159  /* add an entry */
160  {
161  /* Create "vary" base object */
162  RequestFlags flags;
163  flags.cachable.support();
164  StoreEntry *pe = storeCreateEntry("dummy url", "dummy log url", flags, Http::METHOD_GET);
165  auto &reply = pe->mem().adjustableBaseReply();
166  reply.setHeaders(Http::scOkay, "dummy test object", "x-squid-internal/test", 0, -1, squid_curtime + 100000);
167 
168  pe->setPublicKey();
169 
170  pe->buffer();
172  pe->flush();
173  pe->timestampsSet();
174  pe->complete();
175  pe->swapOut();
176  CPPUNIT_ASSERT_EQUAL(0, pe->swap_dirn);
177  CPPUNIT_ASSERT_EQUAL(0, pe->swap_filen);
178  pe->unlock("TestUfs::testUfsSearch vary");
179  }
180 
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  */
186  StoreSearchPointer search = Store::Root().search(); /* search for everything in the store */
187 
188  CPPUNIT_ASSERT_EQUAL(false, search->error());
189  CPPUNIT_ASSERT_EQUAL(false, search->isDone());
190  CPPUNIT_ASSERT_EQUAL(static_cast<StoreEntry *>(nullptr), search->currentItem());
191 
192  /* trigger a callback */
193  cbcalled = false;
194  search->next(searchCallback, nullptr);
195  CPPUNIT_ASSERT_EQUAL(true, cbcalled);
196 
197  /* we should have access to a entry now, that matches the entry we had before */
198  //CPPUNIT_ASSERT_EQUAL(false, search->next());
199  CPPUNIT_ASSERT_EQUAL(false, search->error());
200  CPPUNIT_ASSERT_EQUAL(false, search->isDone());
201  CPPUNIT_ASSERT(search->currentItem() != nullptr);
202 
203  /* trigger another callback */
204  cbcalled = false;
205  search->next(searchCallback, nullptr);
206  CPPUNIT_ASSERT_EQUAL(true, cbcalled);
207 
208  /* now we should have no error, we should have finished and have no current item */
209  //CPPUNIT_ASSERT_EQUAL(false, search->next());
210  CPPUNIT_ASSERT_EQUAL(false, search->error());
211  CPPUNIT_ASSERT_EQUAL(true, search->isDone());
212  CPPUNIT_ASSERT_EQUAL(static_cast<StoreEntry *>(nullptr), search->currentItem());
213 
215 
216  // TODO: here we should test a dirty rebuild
217 
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 
225 /* The UFS store should always configure an IO engine even if none is
226  * supplied on the configuration line.
227  */
228 void
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 
235  MySwapDirPointer aStore (new Fs::Ufs::UFSSwapDir("ufs", "Blocking"));
236  addSwapDir(aStore);
237  commonInit();
239  Config.replPolicy->type = xstrdup("lru");
241 
242  char *path=xstrdup(TESTDIR);
243  char *config_line=xstrdup("100 1 1");
244  ConfigParser::SetCfgLine(config_line);
245  aStore->parse(0, path);
246  safe_free(path);
247  safe_free(config_line);
248  CPPUNIT_ASSERT(aStore->IO->io != nullptr);
249 
252  delete Config.replPolicy;
253 
254  if (0 > system ("rm -rf " TESTDIR))
255  throw std::runtime_error("Failed to clean test work directory");
256 }
257 
258 int
259 main(int argc, char *argv[])
260 {
261  return TestProgram().run(argc, argv);
262 }
263 
HttpReply & adjustableBaseReply()
Definition: MemObject.cc:121
CPPUNIT_TEST_SUITE(TestUfs)
void testUfsDefaultEngine()
Definition: testUfs.cc:229
void storeReplAdd(const char *type, REMOVALPOLICYCREATE *create)
Definition: store.cc:1645
CPPUNIT_TEST(testUfsSearch)
SupportOrVeto cachable
whether the response may be stored in the cache
Definition: RequestFlags.h:35
MemObject & mem()
Definition: Store.h:47
implements test program's main() function while enabling customization
Definition: unitTestMain.h:25
RemovalPolicySettings * replPolicy
Definition: SquidConfig.h:99
void init() override
Definition: Controller.cc:53
int objectsPerBucket
Definition: SquidConfig.h:264
#define xstrdup
bool setPublicKey(const KeyScope keyScope=ksDefault)
Definition: store.cc:575
C * getRaw() const
Definition: RefCount.h:89
RefCount< Fs::Ufs::UFSSwapDir > MySwapDirPointer
Definition: testUfs.cc:48
void packHeadersUsingSlowPacker(Packable &p) const
same as packHeadersUsingFastPacker() but assumes that p cannot quickly process small additions
Definition: HttpReply.cc:95
Store::DiskConfig cacheSwap
Definition: SquidConfig.h:423
RemovalPolicy * mem_policy
Definition: MemObject.cc:44
void parse(int index, char *path) override
Definition: UFSSwapDir.cc:180
int run(int argc, char *argv[])
Definition: unitTestMain.h:44
static void addSwapDir(MySwapDirPointer aStore)
Definition: testUfs.cc:52
virtual bool error() const =0
char * store_dir_select_algorithm
Definition: SquidConfig.h:500
void comm_init(void)
Definition: comm.cc:1151
bool runOnce()
Definition: EventLoop.cc:89
void create() override
create system resources needed for this store to operate in the future
Definition: UFSSwapDir.cc:300
Fs::Ufs::UFSStrategy * IO
Definition: UFSSwapDir.h:83
CPPUNIT_TEST_SUITE_END()
static void searchCallback(void *)
Definition: testUfs.cc:62
sdirno swap_dirn
Definition: Store.h:237
static void Init()
Definition: fde.cc:141
void free_cachedir(Store::DiskConfig *swap)
Definition: Disks.cc:806
void httpHeaderInitModule(void)
Definition: HttpHeader.cc:121
int unlock(const char *context)
Definition: store.cc:469
#define safe_free(x)
Definition: xalloc.h:73
struct SquidConfig::@95 Store
const char * visible_appname_string
void commonInit()
Definition: testUfs.cc:68
RemovalPolicy * createRemovalPolicy(RemovalPolicySettings *settings)
Definition: store.cc:1671
YesNoNone memShared
whether the memory cache is shared among workers
Definition: SquidConfig.h:89
virtual void next(void(callback)(void *cbdata), void *cbdata)=0
static bool cbcalled
Definition: testUfs.cc:59
void buffer() override
Definition: store.cc:1601
virtual bool isDone() const =0
virtual StoreEntry * currentItem()=0
void flush() override
Definition: store.cc:1612
void allocate_new_swapdir(Store::DiskConfig &swap)
Definition: Disks.cc:787
StoreSearch * search()
Definition: Controller.cc:205
static int store_dirs_rebuilding
the number of cache_dirs being rebuilt; TODO: move to Disks::Rebuilding
Definition: Controller.h:133
time_t squid_curtime
Definition: stub_libtime.cc:20
void swapOut()
StoreEntry * storeCreateEntry(const char *url, const char *logUrl, const RequestFlags &flags, const HttpRequestMethod &method)
Definition: store.cc:759
DiskIOStrategy * io
Definition: UFSStrategy.h:51
int64_t store_maxobjsize
#define TESTDIR
Definition: testUfs.cc:27
int storeDirWriteCleanLogs(int reopen)
Definition: Disks.cc:700
void complete()
Definition: store.cc:1031
void testUfsSearch()
Definition: testUfs.cc:101
REMOVALPOLICYCREATE createRemovalPolicy_lru
bool timestampsSet()
Definition: store.cc:1387
static void SetCfgLine(char *line)
Set the configuration file line to parse.
void Init()
Definition: old_api.cc:281
int64_t maxObjectSize
Definition: SquidConfig.h:266
int64_t avgObjectSize
Definition: SquidConfig.h:265
static DiskIOModule * Find(char const *type)
const HttpReply & freshestReply() const
Definition: MemObject.h:68
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 defaultTo(bool beSet)
enables or disables the option; updating to 'implicit' state
Definition: YesNoNone.h:59
#define VERSION
RemovalPolicy * REMOVALPOLICYCREATE(wordlist *args)
Definition: RemovalPolicy.h:80
@ scOkay
Definition: StatusCode.h:27
@ METHOD_GET
Definition: MethodType.h:25
class SquidConfig Config
Definition: SquidConfig.cc:12
sfileno swap_filen
unique ID inside a cache_dir for swapped out entries; -1 for others
Definition: Store.h:235
int main(int argc, char *argv[])
Definition: testUfs.cc:259
CPPUNIT_TEST_SUITE_REGISTRATION(TestUfs)
Controller & Root()
safely access controller singleton
Definition: Controller.cc:926
RefCount< SwapDir > * swapDirs
Definition: SquidConfig.h:68

 

Introduction

Documentation

Support

Miscellaneous