From 8e5519ec478ea8a19c86649ef3ba84f80808cd86 Mon Sep 17 00:00:00 2001 From: Patrick LeBlanc Date: Fri, 29 Mar 2019 10:16:11 -0500 Subject: [PATCH] Updated IOC::listdirectory & its unit test. --- src/IOCoordinator.cpp | 40 +++++++++++++++++++++++++++----- src/IOCoordinator.h | 8 ++++++- src/unit_tests.cpp | 54 ++++++++++++++++++++++++++----------------- 3 files changed, 74 insertions(+), 28 deletions(-) diff --git a/src/IOCoordinator.cpp b/src/IOCoordinator.cpp index a1e6028db..f997adda9 100755 --- a/src/IOCoordinator.cpp +++ b/src/IOCoordinator.cpp @@ -34,17 +34,32 @@ IOCoordinator::IOCoordinator() cache = Cache::get(); logger = SMLogging::get(); replicator = Replicator::get(); - objectSize = 5 * (1<<20); + try { objectSize = stoul(config->getValue("ObjectStorage", "object_size")); } catch (...) { - cerr << "ObjectStorage/object_size must be set to a numeric value" << endl; - throw; + logger->log(LOG_ERR, "ObjectStorage/object_size must be set to a numeric value"); + throw runtime_error("Please set ObjectStorage/object_size in the storagemanager.cnf file"); } + try + { + metaPath = config->getValue("ObjectStorage", "metadata_path"); + if (metaPath.empty()) + { + logger->log(LOG_ERR, "ObjectStorage/journal_path is not set"); + throw runtime_error("Please set ObjectStorage/journal_path in the storagemanager.cnf file"); + } + } + catch (...) + { + logger->log(LOG_ERR, "ObjectStorage/metadata_path is not set"); + throw runtime_error("Please set ObjectStorage/metadata_path in the storagemanager.cnf file"); + } + cachePath = cache->getCachePath(); journalPath = cache->getJournalPath(); } @@ -360,7 +375,7 @@ int IOCoordinator::open(const char *filename, int openmode, struct stat *out) int IOCoordinator::listDirectory(const char *filename, vector *listing) { - bf::path p(filename); + bf::path p(metaPath / filename); listing->clear(); if (!bf::exists(p)) @@ -410,8 +425,6 @@ int IOCoordinator::unlink(const char *path) ret = -1; } return ret; - - //return ::unlink(path); } int IOCoordinator::copyFile(const char *filename1, const char *filename2) @@ -435,6 +448,21 @@ int IOCoordinator::copyFile(const char *filename1, const char *filename2) return err; } +const bf::path &IOCoordinator::getCachePath() const +{ + return cachePath; +} + +const bf::path &IOCoordinator::getJournalPath() const +{ + return journalPath; +} + +const bf::path &IOCoordinator::getMetadataPath() const +{ + return metaPath; +} + // this is not generic by any means. This is assuming a version 1 journal header, and is looking // for the end of it, which is the first \0 char. It returns with fd pointing at the // first byte after the header. diff --git a/src/IOCoordinator.h b/src/IOCoordinator.h index df30e3044..231b76d84 100644 --- a/src/IOCoordinator.h +++ b/src/IOCoordinator.h @@ -62,7 +62,12 @@ class IOCoordinator : public boost::noncopyable bool writeLock(const std::string &filename); void readUnlock(const std::string &filename); void writeUnlock(const std::string &filename); - + + // some accessors... + const boost::filesystem::path &getCachePath() const; + const boost::filesystem::path &getJournalPath() const; + const boost::filesystem::path &getMetadataPath() const; + private: IOCoordinator(); Config *config; @@ -72,6 +77,7 @@ class IOCoordinator : public boost::noncopyable size_t objectSize; boost::filesystem::path journalPath; boost::filesystem::path cachePath; + boost::filesystem::path metaPath; std::map locks; boost::mutex lockMutex; // lol diff --git a/src/unit_tests.cpp b/src/unit_tests.cpp index 38b41c1de..69e98925d 100755 --- a/src/unit_tests.cpp +++ b/src/unit_tests.cpp @@ -14,6 +14,7 @@ #include "MetadataFile.h" #include "Replicator.h" #include "S3Storage.h" +#include "Utilities.h" #include #include @@ -517,19 +518,31 @@ bool truncatetask() bool listdirtask() { - // make a file, make sure it's in the list returned. - const char *filename = "listdirtest1"; - ::unlink(filename); - int fd = ::open(filename, O_CREAT | O_RDWR, 0666); - assert(fd > 0); - scoped_closer f(fd); + IOCoordinator *ioc = IOCoordinator::get(); + const bf::path metaPath = ioc->getMetadataPath(); + const char *relPath = "listdirtask"; + bf::path tmpPath = metaPath/relPath; + + // make some dummy files, make sure they are in the list returned. + set files; + int err; + vector fdMinders; + + bf::create_directories(tmpPath); + for (int i = 0; i < 10; i++) { + string file(tmpPath.string() + "/dummy" + to_string(i)); + files.insert(file); + err = ::open(file.c_str(), O_CREAT | O_WRONLY, 0600); + assert(err >= 0); + fdMinders.push_back(err); + } uint8_t buf[8192]; listdir_cmd *cmd = (listdir_cmd *) buf; cmd->opcode = LIST_DIRECTORY; - cmd->plen = 1; - cmd->path[0] = '.'; + cmd->plen = strlen(relPath); + memcpy(cmd->path, relPath, cmd->plen); ::write(sessionSock, cmd, sizeof(*cmd) + cmd->plen); ListDirectoryTask l(clientSock, sizeof(*cmd) + cmd->plen); @@ -537,32 +550,31 @@ bool listdirtask() /* going to keep this simple. Don't run this in a big dir. */ /* maybe later I'll make a dir, put a file in it, and etc. For now run it in a small dir. */ - int err = ::recv(sessionSock, buf, 8192, MSG_DONTWAIT); + err = ::recv(sessionSock, buf, 8192, MSG_DONTWAIT); sm_response *resp = (sm_response *) buf; assert(err > 0); assert(resp->header.type == SM_MSG_START); assert(resp->header.flags == 0); assert(resp->returnCode == 0); listdir_resp *r = (listdir_resp *) resp->payload; - //cout << "resp has " << r->elements << " elements" << endl; + cout << "resp has " << r->elements << " elements" << endl; + assert(r->elements == 10); int off = sizeof(sm_response) + sizeof(listdir_resp); + int fileCounter = 0; while (off < err) { listdir_resp_entry *e = (listdir_resp_entry *) &buf[off]; //cout << "len = " << e->flen << endl; - assert(off + e->flen + sizeof(listdir_resp_entry) < 1024); - if (!strncmp(e->filename, filename, strlen(filename))) { - cout << "listdirtask OK" << endl; - ::unlink(filename); - return true; - } - //string name(e->filename, e->flen); - //cout << "name = " << name << endl; + assert(off + e->flen + sizeof(listdir_resp_entry) < 8092); + string file(e->filename, e->flen); + assert(files.find((tmpPath/file).string()) != files.end()); + fileCounter++; + //cout << "name = " << file << endl; off += e->flen + sizeof(listdir_resp_entry); } - cout << "listdirtask(). Didn't find '" << filename << " in the listing. Dir too large for this test?" << endl; - assert(1); - return false; + assert(fileCounter == r->elements); + bf::remove_all(tmpPath); + return true; } bool pingtask()