diff --git configure.ac configure.ac index 273d89c..586864c 100644 --- configure.ac +++ configure.ac @@ -769,40 +769,41 @@ for fs in $squid_storeio_module_candidates none; do aufs) if test "x$squid_disk_module_candidates_Blocking" != "xyes" -a \ "$squid_disk_module_candidates_DiskThreads" != "yes" ; then AC_MSG_ERROR([Storage module aufs requires DiskIO module: Blocking or DiskThreads]) fi ;; coss) AC_MSG_WARN([COSS Support is not stable yet in Squid-3. Please do not use.]) if ! test "x$squid_disk_module_candidates_AIO" = "xyes"; then AC_MSG_ERROR([COSS requires POSIX AIO which is not available.]) fi # Automake on MinGW needs explicit exe extension # for STORE_TESTS substition STORE_TESTS="$STORE_TESTS tests/testCoss$EXEEXT" ;; rock) if test "x$squid_disk_module_candidates_IpcIo" != "xyes" -a \ "x$squid_disk_module_candidates_Blocking" != "xyes"; then AC_MSG_ERROR([Storage module Rock requires IpcIo or Blocking DiskIO module]) fi + STORE_TESTS="$STORE_TESTS tests/testRock$EXEEXT" ;; ufs) STORE_TESTS="$STORE_TESTS tests/testUfs$EXEEXT" esac done dnl hack: need to define those even if not used in the build system to dnl make sure that global FS objects are linked to the squid binary. AH_TEMPLATE(HAVE_FS_UFS, "Define to 1 if ufs filesystem module is build") AH_TEMPLATE(HAVE_FS_AUFS, "Define to 1 if aufs filesystem module is build") AH_TEMPLATE(HAVE_FS_DISKD, "Define to 1 if diskd filesystem module is build") AH_TEMPLATE(HAVE_FS_COSS, "Define to 1 if coss filesystem module is build") AH_TEMPLATE(HAVE_FS_ROCK, "Define to 1 if rock filesystem module is build") dnl got final squid_storeio_module_candidates, build library lists dnl This list will not be needed when each fs library has its own Makefile STORE_LIBS_TO_BUILD= dnl File system libraries to link executables with. dnl These are the same as STORE_LIBS_TO_BUILD, but with a path diff --git src/Makefile.am src/Makefile.am index 8d80a0e..96072e2 100644 --- src/Makefile.am +++ src/Makefile.am @@ -169,40 +169,41 @@ AIO_WIN32_SOURCES = endif if USE_AIOPS_WIN32 AIOPS_SOURCE = DiskIO/DiskThreads/aiops_win32.cc else AIOPS_SOURCE = DiskIO/DiskThreads/aiops.cc endif EXTRA_LIBRARIES = libAIO.a libBlocking.a libDiskDaemon.a libDiskThreads.a \ libMmapped.a libIpcIo.a noinst_LIBRARIES = $(DISK_LIBS) noinst_LTLIBRARIES = libsquid.la EXTRA_PROGRAMS = \ DiskIO/DiskDaemon/diskd \ unlinkd \ dnsserver \ recv-announce \ tests/testUfs \ tests/testCoss \ + tests/testRock \ tests/testNull \ ufsdump ## cfgen is used when building squid ## ufsdump is a debug utility, it is possibly useful for end users with cache ## corruption, but at this point we do not install it. noinst_PROGRAMS = \ cf_gen sbin_PROGRAMS = \ squid bin_PROGRAMS = libexec_PROGRAMS = \ $(DNSSERVER) \ $(DISK_PROGRAMS) \ $(UNLINKD) @@ -2612,40 +2613,157 @@ tests_testUfs_LDADD = \ $(DISK_LIBS) \ $(DISK_OS_LIBS) \ acl/libapi.la \ ipc/libipc.la \ $(SSL_LIBS) \ comm/libcomm.la \ base/libbase.la \ ip/libip.la \ $(top_builddir)/lib/libmisccontainers.la \ $(top_builddir)/lib/libmiscencoding.la \ $(top_builddir)/lib/libmiscutil.la \ $(REGEXLIB) \ $(SQUID_CPPUNIT_LIBS) \ $(SSLLIB) \ $(COMPAT_LIB) \ $(XTRA_LIBS) tests_testUfs_LDFLAGS = $(LIBADD_DL) tests_testUfs_DEPENDENCIES = \ $(SWAP_TEST_DS) +tests_testRock_SOURCES = \ + cbdata.cc \ + CacheDigest.cc \ + ConfigOption.cc \ + ConfigParser.cc \ + disk.cc \ + ETag.cc \ + EventLoop.cc \ + event.cc \ + fd.cc \ + HttpBody.cc \ + HttpHdrCc.cc \ + HttpHdrContRange.cc \ + HttpHdrRange.cc \ + HttpHdrSc.cc \ + HttpHdrScTarget.cc \ + HttpHeader.cc \ + HttpHeaderTools.cc \ + HttpMsg.cc \ + HttpReply.cc \ + HttpRequestMethod.cc \ + HttpStatusLine.cc \ + int.cc \ + mem.cc \ + MemBuf.cc \ + MemObject.cc \ + mem_node.cc \ + Packer.cc \ + Parsing.cc \ + RemovalPolicy.cc \ + StatHist.cc \ + stmem.cc \ + store.cc \ + StoreFileSystem.cc \ + StoreIOState.cc \ + StoreMeta.cc \ + StoreMetaMD5.cc \ + StoreMetaSTD.cc \ + StoreMetaSTDLFS.cc \ + StoreMetaURL.cc \ + StoreMetaUnpacker.cc \ + StoreMetaVary.cc \ + store_dir.cc \ + store_io.cc \ + store_key_md5.cc \ + store_swapmeta.cc \ + store_swapout.cc \ + String.cc \ + SwapDir.cc \ + tests/testRock.cc \ + tests/testMain.cc \ + tests/testRock.h \ + tests/testStoreSupport.cc \ + tests/testStoreSupport.h \ + tests/stub_access_log.cc \ + tests/stub_cache_cf.cc \ + tests/stub_cache_manager.cc \ + tests/stub_client_db.cc \ + tests/stub_client_side_request.cc \ + tests/stub_debug.cc \ + tests/stub_errorpage.cc \ + tests/stub_HelperChildConfig.cc \ + tests/stub_http.cc \ + tests/stub_HttpRequest.cc \ + tests/stub_ipc.cc \ + tests/stub_MemStore.cc \ + tests/stub_mime.cc \ + tests/stub_Port.cc \ + tests/stub_pconn.cc \ + tests/stub_store_client.cc \ + tests/stub_store_rebuild.cc \ + tests/stub_tools.cc \ + tests/stub_UdsOp.cc \ + time.cc \ + url.cc \ + URLScheme.cc \ + wordlist.cc \ + $(DELAY_POOL_SOURCE) \ + $(DISKIO_SOURCE) \ + $(UNLINKDSOURCE) +nodist_tests_testRock_SOURCES = \ + $(DISKIO_GEN_SOURCE) \ + swap_log_op.cc \ + SquidMath.cc \ + SquidMath.h \ + $(TESTSOURCES) +tests_testRock_LDADD = \ + anyp/libanyp.la \ + libsquid.la \ + comm/libcomm.la \ + ip/libip.la \ + fs/libfs.la \ + $(AUTH_LIBS) \ + $(COMMON_LIBS) \ + $(REPL_OBJS) \ + $(DISK_LIBS) \ + $(DISK_OS_LIBS) \ + acl/libacls.la \ + acl/libapi.la \ + acl/libstate.la \ + eui/libeui.la \ + ipc/libipc.la \ + mgr/libmgr.la \ + base/libbase.la \ + $(SSL_LIBS) \ + $(top_builddir)/lib/libmisccontainers.la \ + $(top_builddir)/lib/libmiscencoding.la \ + $(top_builddir)/lib/libmiscutil.la \ + $(REGEXLIB) \ + $(SQUID_CPPUNIT_LIBS) \ + $(SSLLIB) \ + $(COMPAT_LIB) \ + $(XTRA_LIBS) +tests_testRock_LDFLAGS = $(LIBADD_DL) +tests_testRock_DEPENDENCIES = \ + $(SWAP_TEST_DS) + tests_testCoss_SOURCES = \ tests/testCoss.cc \ tests/testMain.cc \ tests/testCoss.h \ tests/stub_cache_manager.cc \ tests/stub_client_db.cc \ tests/stub_debug.cc \ tests/stub_HelperChildConfig.cc \ tests/stub_internal.cc \ tests/stub_ipc.cc \ tests/stub_pconn.cc \ tests/stub_store_rebuild.cc \ fd.cc \ disk.cc \ filemap.cc \ HttpBody.cc \ HttpReply.cc \ HttpStatusLine.cc \ int.cc \ list.cc \ diff --git src/fs/rock/RockSwapDir.cc src/fs/rock/RockSwapDir.cc index 9673712..600f143 100644 --- src/fs/rock/RockSwapDir.cc +++ src/fs/rock/RockSwapDir.cc @@ -1,28 +1,27 @@ /* * $Id$ * * DEBUG: section 47 Store Directory Routines */ #include "config.h" -#include "base/RunnersRegistry.h" #include "ConfigOption.h" #include "DiskIO/DiskIOModule.h" #include "DiskIO/DiskIOStrategy.h" #include "DiskIO/ReadRequest.h" #include "DiskIO/WriteRequest.h" #include "fs/rock/RockSwapDir.h" #include "fs/rock/RockIoState.h" #include "fs/rock/RockIoRequests.h" #include "fs/rock/RockRebuild.h" #include "ipc/mem/Pages.h" #include "MemObject.h" #include "Parsing.h" #include "SquidMath.h" #include const int64_t Rock::SwapDir::HeaderSize = 16*1024; Rock::SwapDir::SwapDir(): ::SwapDir("rock"), filePath(NULL), io(NULL), map(NULL) { } @@ -753,55 +752,43 @@ Rock::SwapDir::statfs(StoreEntry &e) const } } } storeAppendPrintf(&e, "Pending operations: %d out of %d\n", store_open_disk_fd, Config.max_open_disk_fds); storeAppendPrintf(&e, "Flags:"); if (flags.selected) storeAppendPrintf(&e, " SELECTED"); if (flags.read_only) storeAppendPrintf(&e, " READ-ONLY"); storeAppendPrintf(&e, "\n"); } -/// initializes shared memory segments used by Rock::SwapDir -class RockSwapDirRr: public Ipc::Mem::RegisteredRunner +namespace Rock { -public: - /* RegisteredRunner API */ - virtual ~RockSwapDirRr(); - -protected: - virtual void create(const RunnerRegistry &); - -private: - Vector owners; -}; - -RunnerRegistrationEntry(rrAfterConfig, RockSwapDirRr); - + RunnerRegistrationEntry(rrAfterConfig, SwapDirRr); +} -void RockSwapDirRr::create(const RunnerRegistry &) +void Rock::SwapDirRr::create(const RunnerRegistry &) { Must(owners.empty()); for (int i = 0; i < Config.cacheSwap.n_configured; ++i) { if (const Rock::SwapDir *const sd = dynamic_cast(INDEXSD(i))) { // TODO: check whether entryLimitAllowed() has map here Rock::SwapDir::DirMap::Owner *const owner = Rock::SwapDir::DirMap::Init(sd->path, sd->entryLimitAllowed()); owners.push_back(owner); } } } -RockSwapDirRr::~RockSwapDirRr() +Rock::SwapDirRr::~SwapDirRr() { for (size_t i = 0; i < owners.size(); ++i) delete owners[i]; } diff --git src/fs/rock/RockSwapDir.h src/fs/rock/RockSwapDir.h index 4e56c42..b89927b 100644 --- src/fs/rock/RockSwapDir.h +++ src/fs/rock/RockSwapDir.h @@ -16,84 +16,98 @@ namespace Rock class Rebuild; /// \ingroup Rock class SwapDir: public ::SwapDir, public IORequestor { public: SwapDir(); virtual ~SwapDir(); /* public ::SwapDir API */ virtual void reconfigure(); virtual StoreSearch *search(String const url, HttpRequest *); virtual StoreEntry *get(const cache_key *key); virtual void get(String const, STOREGETCLIENT, void * cbdata); virtual void disconnect(StoreEntry &e); virtual uint64_t currentSize() const; virtual uint64_t currentCount() const; virtual bool doReportStat() const; virtual void swappedOut(const StoreEntry &e); + virtual void create(); + virtual void parse(int index, char *path); int64_t entryLimitHigh() const { return SwapFilenMax; } ///< Core limit int64_t entryLimitAllowed() const; typedef Ipc::StoreMapWithExtras DirMap; protected: /* protected ::SwapDir API */ virtual bool needsDiskStrand() const; - virtual void create(); virtual void init(); virtual ConfigOption *getOptionTree() const; virtual bool allowOptionReconfigure(const char *const option) const; virtual bool canStore(const StoreEntry &e, int64_t diskSpaceNeeded, int &load) const; virtual StoreIOState::Pointer createStoreIO(StoreEntry &, StoreIOState::STFNCB *, StoreIOState::STIOCB *, void *); virtual StoreIOState::Pointer openStoreIO(StoreEntry &, StoreIOState::STFNCB *, StoreIOState::STIOCB *, void *); virtual void maintain(); virtual void diskFull(); virtual void reference(StoreEntry &e); virtual bool dereference(StoreEntry &e); virtual void unlink(StoreEntry &e); virtual void statfs(StoreEntry &e) const; /* IORequestor API */ virtual void ioCompletedNotification(); virtual void closeCompleted(); virtual void readCompleted(const char *buf, int len, int errflag, RefCount< ::ReadRequest>); virtual void writeCompleted(int errflag, size_t len, RefCount< ::WriteRequest>); - virtual void parse(int index, char *path); void parseSize(const bool reconfiguring); ///< parses anonymous cache_dir size option void validateOptions(); ///< warns of configuration problems; may quit bool parseTimeOption(char const *option, const char *value, int reconfiguring); void dumpTimeOption(StoreEntry * e) const; void rebuild(); ///< starts loading and validating stored entry metadata ///< used to add entries successfully loaded during rebuild bool addEntry(const int fileno, const DbCellHeader &header, const StoreEntry &from); bool full() const; ///< no more entries can be stored without purging void trackReferences(StoreEntry &e); ///< add to replacement policy scope void ignoreReferences(StoreEntry &e); ///< delete from repl policy scope int64_t diskOffset(int filen) const; int64_t diskOffsetLimit() const; int entryLimit() const { return map->entryLimit(); } friend class Rebuild; const char *filePath; ///< location of cache storage file inside path/ private: DiskIOStrategy *io; RefCount theFile; ///< cache storage for this cache_dir DirMap *map; /* configurable options */ DiskFile::Config fileConfig; ///< file-level configuration options static const int64_t HeaderSize; ///< on-disk db header size }; +/// initializes shared memory segments used by Rock::SwapDir +class SwapDirRr: public Ipc::Mem::RegisteredRunner +{ +public: + /* RegisteredRunner API */ + virtual ~SwapDirRr(); + +protected: + virtual void create(const RunnerRegistry &); + +private: + Vector owners; +}; + } // namespace Rock #endif /* SQUID_FS_ROCK_SWAP_DIR_H */ diff --git src/tests/stub_store_rebuild.cc src/tests/stub_store_rebuild.cc index 22c567a..608cbdd 100644 --- src/tests/stub_store_rebuild.cc +++ src/tests/stub_store_rebuild.cc @@ -19,43 +19,41 @@ * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. * */ #include "squid.h" void storeRebuildProgress(int sd_index, int total, int sofar) -{ - fatal ("Not implemented"); -} +{} void storeRebuildComplete(struct _store_rebuild_data *dc) {} bool storeRebuildLoadEntry(int, int, MemBuf&, _store_rebuild_data&) { return false; } bool storeRebuildKeepEntry(const StoreEntry &tmpe, const cache_key *key, struct _store_rebuild_data &counts) { return false; } bool diff --git src/tests/stub_tools.cc src/tests/stub_tools.cc index f86d0d7..27afd55 100644 --- src/tests/stub_tools.cc +++ src/tests/stub_tools.cc @@ -55,41 +55,44 @@ xmemset(void* dst, int val, size_t sz) } bool IamWorkerProcess() { fprintf(stderr, "Not implemented"); return true; } bool IamDiskProcess() { fprintf(stderr, "Not implemented"); return false; } bool IamMasterProcess() { fprintf(stderr, "Not implemented"); - return false; + // Since most tests run as a single process, this is the best default. + // TODO: If some test case uses multiple processes and cares about + // its role, we may need to parameterize or remove this stub. + return true; } bool InDaemonMode() { fprintf(stderr, "Not implemented"); return false; } bool UsingSmp() { fprintf(stderr, "Not implemented"); return false; } void logsFlush(void) { fatal("tools.cc required"); diff --git src/tests/testRock.cc src/tests/testRock.cc new file mode 100644 index 0000000..4fbd233 --- /dev/null +++ src/tests/testRock.cc @@ -0,0 +1,288 @@ +#define SQUID_UNIT_TEST 1 +#include "config.h" + +#include "DiskIO/DiskIOModule.h" +#include "HttpHeader.h" +#include "HttpReply.h" +#include "Mem.h" +#include "MemObject.h" +#include "Store.h" +#include "StoreFileSystem.h" +#include "StoreSearch.h" +#include "SwapDir.h" +#include "fs/rock/RockSwapDir.h" +#include "testRock.h" +#include "testStoreSupport.h" + +#if HAVE_STDEXCEPT +#include +#endif + +#define TESTDIR "testRock__testRockSearch" + +CPPUNIT_TEST_SUITE_REGISTRATION( testRock ); + +extern REMOVALPOLICYCREATE createRemovalPolicy_lru; + +static void +addSwapDir(testRock::SwapDirPointer aStore) +{ + allocate_new_swapdir(&Config.cacheSwap); + Config.cacheSwap.swapDirs[Config.cacheSwap.n_configured] = aStore.getRaw(); + ++Config.cacheSwap.n_configured; +} + +void +testRock::setUp() +{ + CPPUNIT_NS::TestFixture::setUp(); + + if (0 > system ("rm -rf " TESTDIR)) + throw std::runtime_error("Failed to clean test work directory"); + + Store::Root(new StoreController); + + store = new Rock::SwapDir(); + + addSwapDir(store); + + commonInit(); + + char *path=xstrdup(TESTDIR); + + char *config_line=xstrdup("foo 100 max-size=16384"); + + strtok(config_line, w_space); + + store->parse(0, path); + + safe_free(path); + + safe_free(config_line); + + /* ok, ready to create */ + store->create(); + + rr = new Rock::SwapDirRr; + rr->run(rrAfterConfig); +} + +void +testRock::tearDown() +{ + CPPUNIT_NS::TestFixture::tearDown(); + + Store::Root(NULL); + + store = NULL; + + free_cachedir(&Config.cacheSwap); + + delete rr; + + // TODO: do this once, or each time. + // safe_free(Config.replPolicy->type); + // delete Config.replPolicy; + + if (0 > system ("rm -rf " TESTDIR)) + throw std::runtime_error("Failed to clean test work directory"); +} + +void +testRock::commonInit() +{ + static bool inited = false; + + if (inited) + return; + + 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->args = NULL; + + /* garh garh */ + storeReplAdd("lru", createRemovalPolicy_lru); + + visible_appname_string = xstrdup(APP_FULLNAME); + + Mem::Init(); + + comm_init(); + + httpHeaderInitModule(); /* must go before any header processing (e.g. the one in errorInitialize) */ + + httpReplyInitModule(); /* must go before accepting replies */ + + mem_policy = createRemovalPolicy(Config.replPolicy); + + inited = true; +} + +void +testRock::storeInit() +{ + /* ok, ready to use */ + Store::Root().init(); + + /* rebuild is a scheduled event */ + StockEventLoop loop; + + /* our swapdir must be scheduled to rebuild */ + CPPUNIT_ASSERT_EQUAL(2, StoreController::store_dirs_rebuilding); + + loop.run(); + + /* cannot use loop.run(); as the loop will never idle: the store-dir + * clean() scheduled event prevents it + */ + + /* nothing left to rebuild */ + CPPUNIT_ASSERT_EQUAL(1, StoreController::store_dirs_rebuilding); +} + +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'; + StoreEntry *const pe = + storeCreateEntry(url, "dummy log url", flags, METHOD_GET); + HttpReply *const rep = const_cast(pe->getReply()); + rep->setHeaders(HTTP_OK, "dummy test object", "x-squid-internal/test", + -1, -1, squid_curtime + 100000); + + pe->setPublicKey(); + + return pe; +} + +StoreEntry * +testRock::addEntry(const int i) +{ + 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->flush(); + pe->timestampsSet(); + pe->complete(); + pe->swapOut(); + + return pe; +} + +StoreEntry * +testRock::getEntry(const int i) +{ + StoreEntry *const pe = createEntry(i); + return store->get(reinterpret_cast(pe->key)); +} + +void +testRock::testRockCreate() +{ + struct stat sb; + + CPPUNIT_ASSERT(::stat(TESTDIR, &sb) == 0); + + /* TODO: check the size */ + + /* TODO: test rebuild */ +} + +void +testRock::testRockSwapOut() +{ + storeInit(); + + // add few entries to prime the database + for (int i = 0; i < 5; ++i) { + CPPUNIT_ASSERT_EQUAL((uint64_t)i, store->currentCount()); + + StoreEntry *const pe = addEntry(i); + + CPPUNIT_ASSERT(pe->swap_status == SWAPOUT_WRITING); + CPPUNIT_ASSERT(pe->swap_dirn == 0); + CPPUNIT_ASSERT(pe->swap_filen >= 0); + + // Rock::IoState::finishedWriting() schedules an AsyncCall + // storeSwapOutFileClosed(). Let it fire. + StockEventLoop loop; + loop.run(); + + CPPUNIT_ASSERT(pe->swap_status == SWAPOUT_DONE); + + pe->unlock(); + } + + CPPUNIT_ASSERT_EQUAL((uint64_t)5, store->currentCount()); + + // try to swap out entry to a used unlocked slot + { + StoreEntry *const pe = addEntry(4); + + CPPUNIT_ASSERT(pe->swap_status == SWAPOUT_WRITING); + CPPUNIT_ASSERT(pe->swap_dirn == 0); + CPPUNIT_ASSERT(pe->swap_filen >= 0); + + StockEventLoop loop; + loop.run(); + + CPPUNIT_ASSERT(pe->swap_status == SWAPOUT_DONE); + } + + // 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(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); + + StockEventLoop loop; + loop.run(); + } + + CPPUNIT_ASSERT_EQUAL((uint64_t)6, store->currentCount()); + + // try to get and unlink entries + for (int i = 0; i < 6; ++i) { + StoreEntry *const pe = getEntry(i); + CPPUNIT_ASSERT(pe != NULL); + + pe->unlink(); + + StoreEntry *const pe2 = getEntry(i); + CPPUNIT_ASSERT(pe2 == NULL); + } +} diff --git src/tests/testRock.h src/tests/testRock.h new file mode 100644 index 0000000..2951d8f --- /dev/null +++ src/tests/testRock.h @@ -0,0 +1,37 @@ +#ifndef SQUID_SRC_TEST_TESTROCK_H +#define SQUID_SRC_TEST_TESTROCK_H + +#include + +/* + * test the store framework + */ + +class testRock : public CPPUNIT_NS::TestFixture +{ + CPPUNIT_TEST_SUITE( testRock ); + CPPUNIT_TEST( testRockCreate ); + CPPUNIT_TEST( testRockSwapOut ); + CPPUNIT_TEST_SUITE_END(); + +public: + virtual void setUp(); + virtual void tearDown(); + + typedef RefCount SwapDirPointer; + +protected: + void commonInit(); + void storeInit(); + StoreEntry *createEntry(const int i); + StoreEntry *addEntry(const int i); + StoreEntry *getEntry(const int i); + void testRockCreate(); + void testRockSwapOut(); + +private: + SwapDirPointer store; + Rock::SwapDirRr *rr; +}; + +#endif /* SQUID_SRC_TEST_TESTROCK_H */