-#define SQUID_UNIT_TEST 1
-#include "squid.h"
+/*
+ * Copyright (C) 1996-2016 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+#include "squid.h"
+#include "ConfigParser.h"
#include "DiskIO/DiskIOModule.h"
#include "fs/rock/RockSwapDir.h"
#include "globals.h"
#include "HttpHeader.h"
#include "HttpReply.h"
-#include "Mem.h"
#include "MemObject.h"
+#include "RequestFlags.h"
#include "SquidConfig.h"
#include "Store.h"
+#include "store/Disk.h"
+#include "store/Disks.h"
#include "StoreFileSystem.h"
#include "StoreSearch.h"
-#include "SwapDir.h"
#include "testRock.h"
#include "testStoreSupport.h"
+#include "unitTestMain.h"
+#include <stdexcept>
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
-#if HAVE_STDEXCEPT
-#include <stdexcept>
+#if HAVE_UNISTD_H
+#include <unistd.h>
#endif
-#define TESTDIR "testRock__testRockSearch"
+#define TESTDIR "testRock_Store"
CPPUNIT_TEST_SUITE_REGISTRATION( testRock );
extern REMOVALPOLICYCREATE createRemovalPolicy_lru;
+static char cwd[MAXPATHLEN];
+
static void
addSwapDir(testRock::SwapDirPointer aStore)
{
if (0 > system ("rm -rf " TESTDIR))
throw std::runtime_error("Failed to clean test work directory");
+ Config.memShared.defaultTo(false);
+
// use current directory for shared segments (on path-based OSes)
- Ipc::Mem::Segment::BasePath = ".";
+ Ipc::Mem::Segment::BasePath = getcwd(cwd,MAXPATHLEN);
+ if (Ipc::Mem::Segment::BasePath == NULL)
+ Ipc::Mem::Segment::BasePath = ".";
- Store::Root(new StoreController);
+ Store::Init();
store = new Rock::SwapDir();
char *path=xstrdup(TESTDIR);
- char *config_line=xstrdup("foo 10 max-size=16384");
+ char *config_line=xstrdup("10 max-size=16384");
- strtok(config_line, w_space);
+ ConfigParser::SetCfgLine(config_line);
store->parse(0, path);
+ store_maxobjsize = 1024*1024*2;
safe_free(path);
store->create();
rr = new Rock::SwapDirRr;
- rr->run(rrAfterConfig);
+ rr->useConfig();
}
void
{
CPPUNIT_NS::TestFixture::tearDown();
- Store::Root(NULL);
+ Store::FreeMemory();
store = NULL;
free_cachedir(&Config.cacheSwap);
- delete rr;
+ rr->finishShutdown(); // deletes rr
+ rr = NULL;
// TODO: do this once, or each time.
// safe_free(Config.replPolicy->type);
StoreFileSystem::SetupAllFs();
Config.Store.avgObjectSize = 1024;
-
Config.Store.objectsPerBucket = 20;
-
Config.Store.maxObjectSize = 2048;
Config.store_dir_select_algorithm = xstrdup("round-robin");
Config.replPolicy = new RemovalPolicySettings;
-
- Config.replPolicy->type = xstrdup ("lru");
-
+ Config.replPolicy->type = xstrdup("lru");
Config.replPolicy->args = NULL;
/* garh garh */
comm_init();
- httpHeaderInitModule(); /* must go before any header processing (e.g. the one in errorInitialize) */
+ httpHeaderInitModule(); /* must go before any header processing (e.g. the one in errorInitialize) */
- httpReplyInitModule(); /* must go before accepting replies */
+ httpReplyInitModule(); /* must go before accepting replies */
mem_policy = createRemovalPolicy(Config.replPolicy);
*/
/* nothing left to rebuild */
- CPPUNIT_ASSERT_EQUAL(1, StoreController::store_dirs_rebuilding);
+ CPPUNIT_ASSERT_EQUAL(0, StoreController::store_dirs_rebuilding);
+}
+
+static const char *
+storeId(const int i)
+{
+ static char buf[64];
+ snprintf(buf, sizeof(buf), "dummy url %i", i);
+ buf[sizeof(buf) - 1] = '\0';
+ return buf;
}
StoreEntry *
testRock::createEntry(const int i)
{
- request_flags flags;
- flags.cachable = 1;
- char url[64];
- snprintf(url, sizeof(url), "dummy url %i", i);
- url[sizeof(url) - 1] = '\0';
+ RequestFlags flags;
+ flags.cachable = true;
StoreEntry *const pe =
- storeCreateEntry(url, "dummy log url", flags, METHOD_GET);
+ storeCreateEntry(storeId(i), "dummy log url", flags, Http::METHOD_GET);
HttpReply *const rep = const_cast<HttpReply *>(pe->getReply());
- rep->setHeaders(HTTP_OK, "dummy test object", "x-squid-internal/test",
- -1, -1, squid_curtime + 100000);
+ rep->setHeaders(Http::scOkay, "dummy test object", "x-squid-internal/test", 0, -1, squid_curtime + 100000);
pe->setPublicKey();
StoreEntry *const pe = createEntry(i);
pe->buffer();
- /* TODO: remove this when the metadata is separated */
- {
- Packer p;
- packerToStoreInit(&p, pe);
- pe->getReply()->packHeadersInto(&p);
- packerClean(&p);
- }
-
+ pe->getReply()->packHeadersInto(pe);
pe->flush();
pe->timestampsSet();
pe->complete();
StoreEntry *
testRock::getEntry(const int i)
{
- StoreEntry *const pe = createEntry(i);
- return store->get(reinterpret_cast<const cache_key *>(pe->key));
+ return storeGetPublic(storeId(i), Http::METHOD_GET);
}
void
{
struct stat sb;
- CPPUNIT_ASSERT(::stat(TESTDIR, &sb) == 0);
+ CPPUNIT_ASSERT_EQUAL(0, ::stat(TESTDIR, &sb));
/* TODO: check the size */
StoreEntry *const pe = addEntry(i);
- CPPUNIT_ASSERT(pe->swap_status == SWAPOUT_WRITING);
- CPPUNIT_ASSERT(pe->swap_dirn == 0);
+ CPPUNIT_ASSERT_EQUAL(SWAPOUT_WRITING, pe->swap_status);
+ CPPUNIT_ASSERT_EQUAL(0, pe->swap_dirn);
CPPUNIT_ASSERT(pe->swap_filen >= 0);
// Rock::IoState::finishedWriting() schedules an AsyncCall
StockEventLoop loop;
loop.run();
- CPPUNIT_ASSERT(pe->swap_status == SWAPOUT_DONE);
+ CPPUNIT_ASSERT_EQUAL(SWAPOUT_DONE, pe->swap_status);
- pe->unlock();
+ pe->unlock("testRock::testRockSwapOut priming");
}
CPPUNIT_ASSERT_EQUAL((uint64_t)5, store->currentCount());
{
StoreEntry *const pe = addEntry(4);
- CPPUNIT_ASSERT(pe->swap_status == SWAPOUT_WRITING);
- CPPUNIT_ASSERT(pe->swap_dirn == 0);
+ CPPUNIT_ASSERT_EQUAL(SWAPOUT_WRITING, pe->swap_status);
+ CPPUNIT_ASSERT_EQUAL(0, pe->swap_dirn);
CPPUNIT_ASSERT(pe->swap_filen >= 0);
StockEventLoop loop;
loop.run();
- CPPUNIT_ASSERT(pe->swap_status == SWAPOUT_DONE);
+ CPPUNIT_ASSERT_EQUAL(SWAPOUT_DONE, pe->swap_status);
+
+ pe->unlock("testRock::testRockSwapOut e#4");
}
// try to swap out entry to a used locked slot
{
StoreEntry *const pe = addEntry(5);
- CPPUNIT_ASSERT(pe->swap_status == SWAPOUT_WRITING);
- CPPUNIT_ASSERT(pe->swap_dirn == 0);
+ CPPUNIT_ASSERT_EQUAL(SWAPOUT_WRITING, pe->swap_status);
+ CPPUNIT_ASSERT_EQUAL(0, pe->swap_dirn);
CPPUNIT_ASSERT(pe->swap_filen >= 0);
// the slot is locked here because the async calls have not run yet
StoreEntry *const pe2 = addEntry(5);
- CPPUNIT_ASSERT(pe2->swap_status == SWAPOUT_NONE);
- CPPUNIT_ASSERT(pe2->mem_obj->swapout.decision ==
- MemObject::SwapOut::swImpossible);
- CPPUNIT_ASSERT(pe2->swap_dirn == -1);
- CPPUNIT_ASSERT(pe2->swap_filen == -1);
+ CPPUNIT_ASSERT_EQUAL(SWAPOUT_NONE, pe2->swap_status);
+ CPPUNIT_ASSERT_EQUAL(MemObject::SwapOut::swImpossible, pe2->mem_obj->swapout.decision);
+ CPPUNIT_ASSERT_EQUAL(-1, pe2->swap_dirn);
+ CPPUNIT_ASSERT_EQUAL(-1, pe2->swap_filen);
StockEventLoop loop;
loop.run();
+
+ pe->unlock("testRock::testRockSwapOut e#5.1");
+ pe2->unlock("testRock::testRockSwapOut e#5.2");
+
+ // pe2 has the same public key as pe so it marks old pe for release
+ // here, we add another entry #5 into the now-available slot
+ StoreEntry *const pe3 = addEntry(5);
+ CPPUNIT_ASSERT_EQUAL(SWAPOUT_WRITING, pe3->swap_status);
+ CPPUNIT_ASSERT_EQUAL(0, pe3->swap_dirn);
+ CPPUNIT_ASSERT(pe3->swap_filen >= 0);
+ loop.run();
+ CPPUNIT_ASSERT_EQUAL(SWAPOUT_DONE, pe3->swap_status);
+ pe3->unlock("testRock::testRockSwapOut e#5.3");
}
CPPUNIT_ASSERT_EQUAL((uint64_t)6, store->currentCount());
- // try to get and unlink entries
+ // try to get and release all entries
for (int i = 0; i < 6; ++i) {
StoreEntry *const pe = getEntry(i);
CPPUNIT_ASSERT(pe != NULL);
- pe->unlink();
+ pe->release(); // destroys pe
StoreEntry *const pe2 = getEntry(i);
- CPPUNIT_ASSERT(pe2 == NULL);
+ CPPUNIT_ASSERT_EQUAL(static_cast<StoreEntry *>(NULL), pe2);
}
}
+