diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 28705e6da..b428bf3cc 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -87,7 +87,7 @@ jobs: # run: pushd ci/cluster && ./multi_node_ci_test.sh # - name: Generate coverage file -# run: bash ci/coverage.sh +# run: bash ci/coverage.sh "${GITHUB_WORKSPACE}/coverage" "${GITHUB_WORKSPACE}/build" # - name: Coveralls # uses: coverallsapp/github-action@master diff --git a/CMakeLists.txt b/CMakeLists.txt index d25fdf0e8..0ab8153ce 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,12 +11,13 @@ option(HERMES_ENABLE_COVERAGE "Check how well tests cover code" OFF) option(HERMES_ENABLE_DOXYGEN "Check how well the code is documented" OFF) option(HERMES_ENABLE_POSIX_ADAPTER "Build the Hermes POSIX adapter." ON) -option(HERMES_ENABLE_STDIO_ADAPTER "Build the Hermes stdio adapter." ON) +option(HERMES_ENABLE_STDIO_ADAPTER "Build the Hermes stdio adapter." OFF) option(HERMES_ENABLE_MPIIO_ADAPTER "Build the Hermes MPI-IO adapter." OFF) option(HERMES_ENABLE_VFD "Build the Hermes HDF5 Virtual File Driver" OFF) option(HERMES_ENABLE_PUBSUB_ADAPTER "Build the Hermes pub/sub adapter." OFF) option(HERMES_ENABLE_KVSTORE "Build the Hermes KVStore adapter." OFF) option(HERMES_ENABLE_PYTHON "Build the Hermes Python wrapper" ON) +option(HERMES_ENABLE_ADIOS "Build the Hermes Python wrapper" ON) option(HERMES_MPICH "Specify that this a MPICH build" OFF) option(HERMES_OPENMPI "Specify that this a OpenMPI build" OFF) @@ -46,6 +47,30 @@ if(NOT HERMES_EXPORTED_TARGETS) set(HERMES_EXPORTED_TARGETS "hrun-targets") endif() +#----------------------------------------------------------------------------- +# Coverage +#----------------------------------------------------------------------------- +if(HERMES_ENABLE_COVERAGE) + set(COVERAGE_FLAGS "-fprofile-arcs -ftest-coverage --coverage" CACHE STRING + "Flags to the coverage program to perform coverage inspection" + ) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COVERAGE_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${COVERAGE_FLAGS}") + + mark_as_advanced(COVERAGE_FLAGS) + + macro(set_coverage_flags target) + target_link_libraries(${target} gcov) +# set_target_properties(${target} +# PROPERTIES +# COMPILE_FLAGS ${COVERAGE_FLAGS} +# LINK_FLAGS ${COVERAGE_FLAGS} +# ) + endmacro() +endif() +add_custom_target(coverage COMMAND bash ${CMAKE_SOURCE_DIR}/ci/coverage.sh + ${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}) + #----------------------------------------------------------------------------- # Find Packages #----------------------------------------------------------------------------- diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index ee640a1ae..7963dd82c 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -62,5 +62,5 @@ install(TARGETS #----------------------------------------------------------------------------- if(HERMES_ENABLE_COVERAGE) set_coverage_flags(test_performance_exec) - set_coverage_flags(test_hermes_api) + set_coverage_flags(hermes_api_bench) endif() diff --git a/benchmark/test_latency.cc b/benchmark/test_latency.cc index a3042c317..ab3cb3dc1 100644 --- a/benchmark/test_latency.cc +++ b/benchmark/test_latency.cc @@ -94,7 +94,7 @@ TEST_CASE("TestHshmQueueEmplacePop") { hrun::QueueId qid(0, 3); u32 ops = (1 << 20); std::vector queue_info = { - {16, 16, ops, 0} + {TaskPrio::kAdmin, 16, 16, ops, 0} }; auto queue = hipc::make_uptr( qid, queue_info); @@ -119,7 +119,7 @@ TEST_CASE("TestHshmQueueEmplacePop") { TEST_CASE("TestHshmQueueGetLane") { hrun::QueueId qid(0, 3); std::vector queue_info = { - {16, 16, 256, 0} + {TaskPrio::kAdmin, 16, 16, 256, 0} }; auto queue = hipc::make_uptr( qid, queue_info); @@ -141,7 +141,7 @@ TEST_CASE("TestHshmQueueAllocateEmplacePop") { TRANSPARENT_HERMES(); hrun::QueueId qid(0, 3); std::vector queue_info = { - {16, 16, 256, 0} + {TaskPrio::kAdmin, 16, 16, 256, 0} }; auto queue = hipc::make_uptr( qid, queue_info); @@ -209,7 +209,7 @@ void TestWorkerIterationLatency(u32 num_queues, u32 num_lanes) { for (u32 i = 0; i < num_queues; ++i) { hrun::QueueId qid(0, i + 1); std::vector queue_info = { - {num_lanes, num_lanes, 256, 0} + {TaskPrio::kAdmin, num_lanes, num_lanes, 256, 0} }; auto queue = hipc::make_uptr( qid, queue_info); @@ -233,7 +233,7 @@ void TestWorkerIterationLatency(u32 num_queues, u32 num_lanes) { task = client.AsyncMdPushEmplace(queues[num_queues - 1].get(), task_node, hrun::DomainId::GetLocal()); - worker.Run(); + worker.Run(false); HRUN_CLIENT->DelTask(task); } t.Pause(); diff --git a/ci/coverage.sh b/ci/coverage.sh index 59e8dbd01..a017eca20 100644 --- a/ci/coverage.sh +++ b/ci/coverage.sh @@ -1,7 +1,9 @@ #!/bin/bash -COVERAGE_DIR="${GITHUB_WORKSPACE}/coverage" +COVERAGE_DIR="$1" +BUILD_DIR="$2" mkdir -p "${COVERAGE_DIR}" -cd "${GITHUB_WORKSPACE}/build" +cd "${BUILD_DIR}" +echo $BUILD_DIR lcov -c -d . -o "${COVERAGE_DIR}/tmp.info" lcov --remove "${COVERAGE_DIR}/tmp.info" \ "/usr/*" \ diff --git a/ci/hermes/packages/hermes/package.py b/ci/hermes/packages/hermes/package.py index 3106d7f48..aa41fe218 100644 --- a/ci/hermes/packages/hermes/package.py +++ b/ci/hermes/packages/hermes/package.py @@ -28,7 +28,7 @@ class Hermes(CMakePackage): version("0.4.0-beta", sha256="06020836e203b2f680bea24007dc73760dfb977eb61e442b795b264f0267c16b") version("0.3.0-beta...v0.4.0-beta", sha256="7729b115598277adcab019dee24e5276698fb595066bca758bfa59dc8d51c5a4") - depends_on('hermes_shm') + depends_on('hermes_shm@master') # Common across hermes_shm and hermes variant('mpiio', default=True, description='Enable MPI I/O adapter') diff --git a/ci/hermes/packages/hermes_shm/package.py b/ci/hermes/packages/hermes_shm/package.py index bd19884ba..f2fee6b6d 100644 --- a/ci/hermes/packages/hermes_shm/package.py +++ b/ci/hermes/packages/hermes_shm/package.py @@ -6,6 +6,7 @@ class HermesShm(CMakePackage): url = "https://github.com/lukemartinlogan/hermes_shm/archive/refs/tags/v1.0.0.tar.gz" version('master', branch='master') + version("1.1.0", sha256="080d5361cff22794b670e4544c532926ca8b6d6ec695af25596efe035bfffea5") version("1.0.0", sha256="a79f01d531ce89985ad59a2f62b41d74c2385e48d929e2f4ad895ae34137573b") variant('mpiio', default=True, description='Enable MPI I/O adapter') @@ -15,6 +16,7 @@ class HermesShm(CMakePackage): variant('only_verbs', default=False, description='Only verbs') variant('debug', default=False, description='Build shared libraries') variant('zmq', default=False, description='Build ZeroMQ tests') + variant('adios', default=False, description='Build Adios tests') depends_on('mochi-thallium~cereal@0.10.1') depends_on('catch2@3.0.1') @@ -30,6 +32,7 @@ class HermesShm(CMakePackage): when='+only_verbs') depends_on('libzmq', '+zmq') depends_on('hdf5@1.14.0', when='+vfd') + depends_on('adios2', when='+adios') def cmake_args(self): args = [] diff --git a/ci/install_deps.sh b/ci/install_deps.sh index 03958f316..ae79ee683 100755 --- a/ci/install_deps.sh +++ b/ci/install_deps.sh @@ -14,7 +14,7 @@ set -o pipefail # Change this especially when your $HOME doesn't have enough disk space. INSTALL_DIR="${HOME}" SPACK_DIR=${INSTALL_DIR}/spack -SPACK_VERSION=0.18.1 +SPACK_VERSION=0.20.2 echo "Installing dependencies at ${INSTALL_DIR}" mkdir -p ${INSTALL_DIR} @@ -29,6 +29,11 @@ set +x . ${SPACK_DIR}/share/spack/setup-env.sh set -x +# Install jarvis-cd +git clone https://github.com/grc-iit/jarvis-cd.git +cd jarvis-cd +pip install -e . -r requirements.txt + # This will allow Spack to skip building some packages that are directly # available from the system. For example, autoconf, cmake, m4, etc. # Modify ci/pckages.yaml to skip building compilers or build tools via Spack. @@ -38,4 +43,4 @@ cp ci/packages.yaml ${SPACK_DIR}/etc/spack/packages.yaml # Install hermes_shm (needed for dependencies) # spack repo add ci/hermes -spack install hermes_shm +spack install hermes_shm@master+vfd+mpiio^mpich@3.3.2 diff --git a/hermes_adapters/filesystem/CMakeLists.txt b/hermes_adapters/filesystem/CMakeLists.txt index d9ea0f618..aa3a82686 100644 --- a/hermes_adapters/filesystem/CMakeLists.txt +++ b/hermes_adapters/filesystem/CMakeLists.txt @@ -7,8 +7,6 @@ include_directories( # Create the metadata manager singleton + FS base class add_library(hermes_fs_base SHARED - ${CMAKE_CURRENT_SOURCE_DIR}/filesystem.cc - ${CMAKE_CURRENT_SOURCE_DIR}/filesystem_mdm.cc ${CMAKE_CURRENT_SOURCE_DIR}/filesystem_mdm_singleton.cc) add_dependencies(hermes_fs_base hermes) diff --git a/hermes_adapters/filesystem/filesystem.cc b/hermes_adapters/filesystem/filesystem.cc deleted file mode 100644 index 62abd311c..000000000 --- a/hermes_adapters/filesystem/filesystem.cc +++ /dev/null @@ -1,573 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include "filesystem.h" -#include "hermes_shm/util/singleton.h" -#include "filesystem_mdm.h" -#include "hermes_adapters/mapper/mapper_factory.h" -#include "data_stager/factory/stager_factory.h" - -#include -#include - -namespace stdfs = std::filesystem; - -namespace hermes::adapter::fs { - -File Filesystem::Open(AdapterStat &stat, const std::string &path) { - File f; - auto mdm = HERMES_FS_METADATA_MANAGER; - if (stat.adapter_mode_ == AdapterMode::kNone) { - stat.adapter_mode_ = mdm->GetAdapterMode(path); - } - io_client_->RealOpen(f, stat, path); - if (!f.status_) { - return f; - } - Open(stat, f, path); - return f; -} - -void Filesystem::Open(AdapterStat &stat, File &f, const std::string &path) { - auto mdm = HERMES_FS_METADATA_MANAGER; - Context ctx; - std::shared_ptr exists = mdm->Find(f); - if (!exists) { - HILOG(kDebug, "File not opened before by adapter") - // Normalize path strings - stat.path_ = stdfs::absolute(path).string(); - auto path_shm = hipc::make_uptr(stat.path_); - // Verify the bucket exists if not in CREATE mode - if (stat.adapter_mode_ == AdapterMode::kScratch && - !stat.hflags_.Any(HERMES_FS_EXISTS) && - !stat.hflags_.Any(HERMES_FS_CREATE)) { - TagId bkt_id = HERMES->GetTagId(stat.path_); - if (bkt_id.IsNull()) { - f.status_ = false; - return; - } - } - // Update page size - stat.page_size_ = mdm->GetAdapterPageSize(path); - // Get or create the bucket - hshm::charbuf url = hermes::data_stager::BinaryFileStager::BuildFileUrl( - stat.path_, stat.page_size_); - if (stat.hflags_.Any(HERMES_FS_TRUNC)) { - // The file was opened with TRUNCATION - stat.bkt_id_ = HERMES->GetBucket(url.str(), ctx, 0, HERMES_IS_FILE); - stat.bkt_id_.Clear(); - } else { - // The file was opened regularly - stat.file_size_ = io_client_->GetSize(*path_shm); - stat.bkt_id_ = HERMES->GetBucket(url.str(), ctx, stat.file_size_, HERMES_IS_FILE); - } - HILOG(kDebug, "File has size: {}", stat.bkt_id_.GetSize()); - // Update file position pointer - if (stat.hflags_.Any(HERMES_FS_APPEND)) { - stat.st_ptr_ = std::numeric_limits::max(); - } else { - stat.st_ptr_ = 0; - } - // Allocate internal hermes data - auto stat_ptr = std::make_shared(stat); - FilesystemIoClientState fs_ctx(&mdm->fs_mdm_, (void*)stat_ptr.get()); - io_client_->HermesOpen(f, stat, fs_ctx); - mdm->Create(f, stat_ptr); - } else { - HILOG(kDebug, "File already opened by adapter") - exists->UpdateTime(); - } -} - -size_t Filesystem::Write(File &f, AdapterStat &stat, const void *ptr, - size_t off, size_t total_size, - IoStatus &io_status, FsIoOptions opts) { - (void) f; - hapi::Bucket &bkt = stat.bkt_id_; - std::string filename = bkt.GetName(); - bool is_append = stat.st_ptr_ == std::numeric_limits::max(); - - HILOG(kDebug, "Write called for filename: {}" - " on offset: {}" - " from position: {}" - " and size: {}" - " and adapter mode: {}", - filename, off, stat.st_ptr_, total_size, - AdapterModeConv::str(stat.adapter_mode_)) - if (stat.adapter_mode_ == AdapterMode::kBypass) { - // Bypass mode is handled differently - opts.backend_size_ = total_size; - opts.backend_off_ = off; - Blob blob_wrap((char*)ptr, total_size); - io_client_->WriteBlob(bkt.GetName(), blob_wrap, opts, io_status); - if (!io_status.success_) { - HILOG(kDebug, "Failed to write blob of size {} to backend", - opts.backend_size_) - return 0; - } - if (opts.DoSeek() && !is_append) { - stat.st_ptr_ = off + total_size; - } - return total_size; - } - Context ctx; - ctx.page_size_ = stat.page_size_; - ctx.flags_.SetBits(HERMES_IS_FILE); - - if (is_append) { - // Perform append - const Blob page((const char*)ptr, total_size); - bkt.Append(page, stat.page_size_, ctx); - } else { - // Fragment I/O request into pages - BlobPlacements mapping; - auto mapper = MapperFactory::Get(MapperType::kBalancedMapper); - mapper->map(off, total_size, stat.page_size_, mapping); - size_t data_offset = 0; - - // Perform a PartialPut for each page - for (const BlobPlacement &p : mapping) { - const Blob page((const char*)ptr + data_offset, p.blob_size_); - std::string blob_name(p.CreateBlobName().str()); - bkt.AsyncPartialPut(blob_name, page, p.blob_off_, ctx); - data_offset += p.blob_size_; - } - if (opts.DoSeek()) { - stat.st_ptr_ = off + total_size; - } - } - stat.UpdateTime(); - - HILOG(kDebug, "The size of file after write: {}", - GetSize(f, stat)) - return total_size; -} - -size_t Filesystem::Read(File &f, AdapterStat &stat, void *ptr, - size_t off, size_t total_size, - IoStatus &io_status, FsIoOptions opts) { - (void) f; - hapi::Bucket &bkt = stat.bkt_id_; - - HILOG(kDebug, "Read called for filename: {}" - " on offset: {}" - " from position: {}" - " and size: {}", - stat.path_, off, stat.st_ptr_, total_size) - - // SEEK_END is not a valid read position - if (off == std::numeric_limits::max()) { - return 0; - } - - // Ensure the amount being read makes sense - if (total_size == 0) { - return 0; - } - - if (stat.adapter_mode_ == AdapterMode::kBypass) { - // Bypass mode is handled differently - opts.backend_size_ = total_size; - opts.backend_off_ = off; - Blob blob_wrap((char*)ptr, total_size); - io_client_->ReadBlob(bkt.GetName(), blob_wrap, opts, io_status); - if (!io_status.success_) { - HILOG(kDebug, "Failed to read blob of size {} from backend", - opts.backend_size_) - return 0; - } - if (opts.DoSeek()) { - stat.st_ptr_ = off + total_size; - } - return total_size; - } - - // Fragment I/O request into pages - BlobPlacements mapping; - auto mapper = MapperFactory::Get(MapperType::kBalancedMapper); - mapper->map(off, total_size, stat.page_size_, mapping); - size_t data_offset = 0; - - // Perform a PartialPut for each page - Context ctx; - ctx.flags_.SetBits(HERMES_IS_FILE); - for (const BlobPlacement &p : mapping) { - Blob page((const char*)ptr + data_offset, p.blob_size_); - std::string blob_name(p.CreateBlobName().str()); - bkt.PartialGet(blob_name, page, p.blob_off_, ctx); - data_offset += p.blob_size_; - } - if (opts.DoSeek()) { - stat.st_ptr_ = off + total_size; - } - stat.UpdateTime(); - return data_offset; -} - -Task* Filesystem::AWrite(File &f, AdapterStat &stat, const void *ptr, - size_t off, size_t total_size, size_t req_id, - IoStatus &io_status, FsIoOptions opts) { - HILOG(kDebug, "Starting an asynchronous write", - opts.backend_size_); - return nullptr; -} - -Task* Filesystem::ARead(File &f, AdapterStat &stat, void *ptr, - size_t off, size_t total_size, size_t req_id, - IoStatus &io_status, FsIoOptions opts) { - return nullptr; -} - -size_t Filesystem::Wait(uint64_t req_id) { - return 0; -} - -void Filesystem::Wait(std::vector &req_ids, - std::vector &ret) { - for (auto &req_id : req_ids) { - ret.emplace_back(Wait(req_id)); - } -} - -size_t Filesystem::GetSize(File &f, AdapterStat &stat) { - (void) stat; - if (stat.adapter_mode_ != AdapterMode::kBypass) { - return stat.bkt_id_.GetSize(); - } else { - return stdfs::file_size(stat.path_); - } -} - -size_t Filesystem::Seek(File &f, AdapterStat &stat, - SeekMode whence, off64_t offset) { - auto mdm = HERMES_FS_METADATA_MANAGER; - switch (whence) { - case SeekMode::kSet: { - stat.st_ptr_ = offset; - break; - } - case SeekMode::kCurrent: { - if (stat.st_ptr_ != std::numeric_limits::max()) { - stat.st_ptr_ = (off64_t)stat.st_ptr_ + offset; - offset = stat.st_ptr_; - } else { - stat.st_ptr_ = (off64_t)stat.bkt_id_.GetSize() + offset; - offset = stat.st_ptr_; - } - break; - } - case SeekMode::kEnd: { - if (offset == 0) { - stat.st_ptr_ = std::numeric_limits::max(); - offset = stat.bkt_id_.GetSize(); - } else { - stat.st_ptr_ = (off64_t)stat.bkt_id_.GetSize() + offset; - offset = stat.st_ptr_; - } - break; - } - default: { - HELOG(kError, "Invalid seek mode"); - return -1; - } - } - mdm->Update(f, stat); - return offset; -} - -size_t Filesystem::Tell(File &f, AdapterStat &stat) { - (void) f; - if (stat.st_ptr_ != std::numeric_limits::max()) { - return stat.st_ptr_; - } else { - return stat.bkt_id_.GetSize(); - } -} - -int Filesystem::Sync(File &f, AdapterStat &stat) { - if (HERMES_CLIENT_CONF.flushing_mode_ == FlushingMode::kSync) { - // NOTE(llogan): only for the unit tests - // Please don't enable synchronous flushing - HRUN_ADMIN->FlushRoot(DomainId::GetGlobal()); - } - return 0; -} - -int Filesystem::Truncate(File &f, AdapterStat &stat, size_t new_size) { - // hapi::Bucket &bkt = stat.bkt_id_; - // TODO(llogan) - return 0; -} - -int Filesystem::Close(File &f, AdapterStat &stat) { - Sync(f, stat); - auto mdm = HERMES_FS_METADATA_MANAGER; - FilesystemIoClientState fs_ctx(&mdm->fs_mdm_, (void*)&stat); - io_client_->HermesClose(f, stat, fs_ctx); - io_client_->RealClose(f, stat); - mdm->Delete(stat.path_, f); - if (stat.amode_ & MPI_MODE_DELETE_ON_CLOSE) { - Remove(stat.path_); - } - if (HERMES_CLIENT_CONF.flushing_mode_ == FlushingMode::kSync) { - // NOTE(llogan): only for the unit tests - // Please don't enable synchronous flushing - // stat.bkt_id_.Destroy(); - } - return 0; -} - -int Filesystem::Remove(const std::string &pathname) { - auto mdm = HERMES_FS_METADATA_MANAGER; - int ret = io_client_->RealRemove(pathname); - // Destroy the bucket. It's created if it doesn't exist - auto bkt = HERMES->GetBucket(pathname); - HILOG(kDebug, "Destroying the bucket: {}", bkt.GetName()); - bkt.Destroy(); - // Destroy all file descriptors - std::list* filesp = mdm->Find(pathname); - if (filesp == nullptr) { - return ret; - } - HILOG(kDebug, "Destroying the file descriptors: {}", pathname); - std::list files = *filesp; - for (File &f : files) { - auto stat = mdm->Find(f); - if (stat == nullptr) { continue; } - auto mdm = HERMES_FS_METADATA_MANAGER; - FilesystemIoClientState fs_ctx(&mdm->fs_mdm_, (void *)&stat); - io_client_->HermesClose(f, *stat, fs_ctx); - io_client_->RealClose(f, *stat); - mdm->Delete(stat->path_, f); - if (stat->adapter_mode_ == AdapterMode::kScratch) { - ret = 0; - } - } - return ret; -} - - -/** - * Variants of Read and Write which do not take an offset as - * input. - * */ - -size_t Filesystem::Write(File &f, AdapterStat &stat, const void *ptr, - size_t total_size, IoStatus &io_status, - FsIoOptions opts) { - size_t off = stat.st_ptr_; - return Write(f, stat, ptr, off, total_size, io_status, opts); -} - -size_t Filesystem::Read(File &f, AdapterStat &stat, void *ptr, - size_t total_size, - IoStatus &io_status, FsIoOptions opts) { - size_t off = stat.st_ptr_; - return Read(f, stat, ptr, off, total_size, io_status, opts); -} - -Task* Filesystem::AWrite(File &f, AdapterStat &stat, const void *ptr, - size_t total_size, size_t req_id, - IoStatus &io_status, FsIoOptions opts) { - size_t off = stat.st_ptr_; - return AWrite(f, stat, ptr, off, total_size, req_id, io_status, opts); -} - -Task* Filesystem::ARead(File &f, AdapterStat &stat, void *ptr, - size_t total_size, size_t req_id, - IoStatus &io_status, FsIoOptions opts) { - size_t off = stat.st_ptr_; - return ARead(f, stat, ptr, off, total_size, req_id, io_status, opts); -} - - -/** - * Variants of the above functions which retrieve the AdapterStat - * data structure internally. - * */ - -size_t Filesystem::Write(File &f, bool &stat_exists, const void *ptr, - size_t total_size, - IoStatus &io_status, FsIoOptions opts) { - auto mdm = HERMES_FS_METADATA_MANAGER; - auto stat = mdm->Find(f); - if (!stat) { - stat_exists = false; - return 0; - } - stat_exists = true; - return Write(f, *stat, ptr, total_size, io_status, opts); -} - -size_t Filesystem::Read(File &f, bool &stat_exists, void *ptr, - size_t total_size, - IoStatus &io_status, FsIoOptions opts) { - auto mdm = HERMES_FS_METADATA_MANAGER; - auto stat = mdm->Find(f); - if (!stat) { - stat_exists = false; - return 0; - } - stat_exists = true; - return Read(f, *stat, ptr, total_size, io_status, opts); -} - -size_t Filesystem::Write(File &f, bool &stat_exists, const void *ptr, - size_t off, size_t total_size, - IoStatus &io_status, FsIoOptions opts) { - auto mdm = HERMES_FS_METADATA_MANAGER; - auto stat = mdm->Find(f); - if (!stat) { - stat_exists = false; - return 0; - } - stat_exists = true; - opts.UnsetSeek(); - return Write(f, *stat, ptr, off, total_size, io_status, opts); -} - -size_t Filesystem::Read(File &f, bool &stat_exists, void *ptr, - size_t off, size_t total_size, - IoStatus &io_status, FsIoOptions opts) { - auto mdm = HERMES_FS_METADATA_MANAGER; - auto stat = mdm->Find(f); - if (!stat) { - stat_exists = false; - return 0; - } - stat_exists = true; - opts.UnsetSeek(); - return Read(f, *stat, ptr, off, total_size, io_status, opts); -} - -Task* Filesystem::AWrite(File &f, bool &stat_exists, const void *ptr, - size_t total_size, size_t req_id, - IoStatus &io_status, FsIoOptions opts) { - auto mdm = HERMES_FS_METADATA_MANAGER; - auto stat = mdm->Find(f); - if (!stat) { - stat_exists = false; - return 0; - } - stat_exists = true; - return AWrite(f, *stat, ptr, total_size, req_id, io_status, opts); -} - -Task* Filesystem::ARead(File &f, bool &stat_exists, void *ptr, - size_t total_size, size_t req_id, - IoStatus &io_status, FsIoOptions opts) { - auto mdm = HERMES_FS_METADATA_MANAGER; - auto stat = mdm->Find(f); - if (!stat) { - stat_exists = false; - return 0; - } - stat_exists = true; - return ARead(f, *stat, ptr, total_size, req_id, io_status, opts); -} - -Task* Filesystem::AWrite(File &f, bool &stat_exists, const void *ptr, - size_t off, size_t total_size, size_t req_id, - IoStatus &io_status, FsIoOptions opts) { - auto mdm = HERMES_FS_METADATA_MANAGER; - auto stat = mdm->Find(f); - if (!stat) { - stat_exists = false; - return 0; - } - stat_exists = true; - opts.UnsetSeek(); - return AWrite(f, *stat, ptr, off, total_size, req_id, io_status, opts); -} - -Task* Filesystem::ARead(File &f, bool &stat_exists, void *ptr, - size_t off, size_t total_size, size_t req_id, - IoStatus &io_status, FsIoOptions opts) { - auto mdm = HERMES_FS_METADATA_MANAGER; - auto stat = mdm->Find(f); - if (!stat) { - stat_exists = false; - return 0; - } - stat_exists = true; - opts.UnsetSeek(); - return ARead(f, *stat, ptr, off, total_size, req_id, io_status, opts); -} - -size_t Filesystem::Seek(File &f, bool &stat_exists, - SeekMode whence, size_t offset) { - auto mdm = HERMES_FS_METADATA_MANAGER; - auto stat = mdm->Find(f); - if (!stat) { - stat_exists = false; - return -1; - } - stat_exists = true; - return Seek(f, *stat, whence, offset); -} - -size_t Filesystem::GetSize(File &f, bool &stat_exists) { - auto mdm = HERMES_FS_METADATA_MANAGER; - auto stat = mdm->Find(f); - if (!stat) { - stat_exists = false; - return -1; - } - stat_exists = true; - return GetSize(f, *stat); -} - -size_t Filesystem::Tell(File &f, bool &stat_exists) { - auto mdm = HERMES_FS_METADATA_MANAGER; - auto stat = mdm->Find(f); - if (!stat) { - stat_exists = false; - return -1; - } - stat_exists = true; - return Tell(f, *stat); -} - -int Filesystem::Sync(File &f, bool &stat_exists) { - auto mdm = HERMES_FS_METADATA_MANAGER; - auto stat = mdm->Find(f); - if (!stat) { - stat_exists = false; - return -1; - } - stat_exists = true; - return Sync(f, *stat); -} - -int Filesystem::Truncate(File &f, bool &stat_exists, size_t new_size) { - auto mdm = HERMES_FS_METADATA_MANAGER; - auto stat = mdm->Find(f); - if (!stat) { - stat_exists = false; - return -1; - } - stat_exists = true; - return Truncate(f, *stat, new_size); -} - -int Filesystem::Close(File &f, bool &stat_exists) { - auto mdm = HERMES_FS_METADATA_MANAGER; - auto stat = mdm->Find(f); - if (!stat) { - stat_exists = false; - return -1; - } - stat_exists = true; - return Close(f, *stat); -} - -} // namespace hermes::adapter::fs diff --git a/hermes_adapters/filesystem/filesystem.h b/hermes_adapters/filesystem/filesystem.h index 2f5aef452..6d3261245 100644 --- a/hermes_adapters/filesystem/filesystem.h +++ b/hermes_adapters/filesystem/filesystem.h @@ -26,11 +26,14 @@ #include "hermes/bucket.h" #include "hermes/hermes.h" +#include "filesystem_mdm.h" #include "filesystem_io_client.h" +#include "hermes_adapters/mapper/mapper_factory.h" +#include "data_stager/factory/binary_stager.h" #include -namespace hermes::adapter::fs { +namespace hermes::adapter { /** The maximum length of a posix path */ static inline const int kMaxPathLen = 4096; @@ -44,60 +47,414 @@ enum class SeekMode { }; /** A class to represent file system */ -class Filesystem { +class Filesystem : public FilesystemIoClient { public: - FilesystemIoClient *io_client_; AdapterType type_; public: /** Constructor */ - explicit Filesystem(FilesystemIoClient *io_client, AdapterType type) - : io_client_(io_client), type_(type) {} + explicit Filesystem(AdapterType type) + : type_(type) {} /** open \a path */ - File Open(AdapterStat &stat, const std::string &path); + File Open(AdapterStat &stat, const std::string &path) { + File f; + auto mdm = HERMES_FS_METADATA_MANAGER; + if (stat.adapter_mode_ == AdapterMode::kNone) { + stat.adapter_mode_ = mdm->GetAdapterMode(path); + } + RealOpen(f, stat, path); + if (!f.status_) { + return f; + } + Open(stat, f, path); + return f; + } /** open \a f File in \a path*/ - void Open(AdapterStat &stat, File &f, const std::string &path); + void Open(AdapterStat &stat, File &f, const std::string &path) { + auto mdm = HERMES_FS_METADATA_MANAGER; + Context ctx; + ctx.flags_.SetBits(HERMES_SHOULD_STAGE); + + std::shared_ptr exists = mdm->Find(f); + if (!exists) { + HILOG(kDebug, "File not opened before by adapter") + // Normalize path strings + stat.path_ = stdfs::absolute(path).string(); + auto path_shm = hipc::make_uptr(stat.path_); + // Verify the bucket exists if not in CREATE mode + if (stat.adapter_mode_ == AdapterMode::kScratch && + !stat.hflags_.Any(HERMES_FS_EXISTS) && + !stat.hflags_.Any(HERMES_FS_CREATE)) { + TagId bkt_id = HERMES->GetTagId(stat.path_); + if (bkt_id.IsNull()) { + f.status_ = false; + return; + } + } + // Update page size + stat.page_size_ = mdm->GetAdapterPageSize(path); + // Bucket parameters + ctx.bkt_params_ = hermes::data_stager::BinaryFileStager::BuildFileParams(stat.page_size_); + // Get or create the bucket + if (stat.hflags_.Any(HERMES_FS_TRUNC)) { + // The file was opened with TRUNCATION + stat.bkt_id_ = HERMES->GetBucket(stat.path_, ctx, 0, HERMES_SHOULD_STAGE); + stat.bkt_id_.Clear(); + } else { + // The file was opened regularly + stat.file_size_ = GetBackendSize(*path_shm); + stat.bkt_id_ = HERMES->GetBucket(stat.path_, ctx, stat.file_size_, HERMES_SHOULD_STAGE); + } + HILOG(kDebug, "BKT vs file size: {} {}", stat.bkt_id_.GetSize(), stat.file_size_); + // Update file position pointer + if (stat.hflags_.Any(HERMES_FS_APPEND)) { + stat.st_ptr_ = std::numeric_limits::max(); + } else { + stat.st_ptr_ = 0; + } + // Allocate internal hermes data + auto stat_ptr = std::make_shared(stat); + FilesystemIoClientState fs_ctx(&mdm->fs_mdm_, (void*)stat_ptr.get()); + HermesOpen(f, stat, fs_ctx); + mdm->Create(f, stat_ptr); + } else { + HILOG(kDebug, "File already opened by adapter") + exists->UpdateTime(); + } + } /** write */ size_t Write(File &f, AdapterStat &stat, const void *ptr, size_t off, size_t total_size, IoStatus &io_status, - FsIoOptions opts = FsIoOptions()); + FsIoOptions opts = FsIoOptions()) { + (void) f; + hapi::Bucket &bkt = stat.bkt_id_; + std::string filename = bkt.GetName(); + bool is_append = stat.st_ptr_ == std::numeric_limits::max(); + + HILOG(kDebug, "Write called for filename: {}" + " on offset: {}" + " from position: {}" + " and size: {}" + " and adapter mode: {}", + filename, off, stat.st_ptr_, total_size, + AdapterModeConv::str(stat.adapter_mode_)) + if (stat.adapter_mode_ == AdapterMode::kBypass) { + // Bypass mode is handled differently + opts.backend_size_ = total_size; + opts.backend_off_ = off; + Blob blob_wrap((char*)ptr, total_size); + WriteBlob(bkt.GetName(), blob_wrap, opts, io_status); + if (!io_status.success_) { + HILOG(kDebug, "Failed to write blob of size {} to backend", + opts.backend_size_) + return 0; + } + if (opts.DoSeek() && !is_append) { + stat.st_ptr_ = off + total_size; + } + return total_size; + } + Context ctx; + ctx.flags_.SetBits(HERMES_SHOULD_STAGE); + + if (is_append) { + // Perform append + const Blob page((const char*)ptr, total_size); + bkt.Append(page, stat.page_size_, ctx); + } else { + // Fragment I/O request into pages + BlobPlacements mapping; + auto mapper = MapperFactory::Get(MapperType::kBalancedMapper); + mapper->map(off, total_size, stat.page_size_, mapping); + size_t data_offset = 0; + + // Perform a PartialPut for each page + for (const BlobPlacement &p : mapping) { + const Blob page((const char*)ptr + data_offset, p.blob_size_); + std::string blob_name(p.CreateBlobName().str()); + bkt.AsyncPartialPut(blob_name, page, p.blob_off_, ctx); + data_offset += p.blob_size_; + } + if (opts.DoSeek()) { + stat.st_ptr_ = off + total_size; + } + } + stat.UpdateTime(); + io_status.size_ = total_size; + UpdateIoStatus(opts, io_status); + + HILOG(kDebug, "The size of file after write: {}", + GetSize(f, stat)) + return total_size; + } + + /** base read function */ + template + size_t BaseRead(File &f, AdapterStat &stat, void *ptr, size_t off, + size_t total_size, size_t req_id, + std::vector>> &tasks, + IoStatus &io_status, FsIoOptions opts = FsIoOptions()) { + (void) f; + hapi::Bucket &bkt = stat.bkt_id_; + + HILOG(kDebug, "Read called for filename: {}" + " on offset: {}" + " from position: {}" + " and size: {}", + stat.path_, off, stat.st_ptr_, total_size) + + // SEEK_END is not a valid read position + if (off == std::numeric_limits::max()) { + io_status.size_ = 0; + UpdateIoStatus(opts, io_status); + return 0; + } + + // Ensure the amount being read makes sense + if (total_size == 0) { + io_status.size_ = 0; + UpdateIoStatus(opts, io_status); + return 0; + } + + if constexpr (!ASYNC) { + if (stat.adapter_mode_ == AdapterMode::kBypass) { + // Bypass mode is handled differently + opts.backend_size_ = total_size; + opts.backend_off_ = off; + Blob blob_wrap((char *) ptr, total_size); + ReadBlob(bkt.GetName(), blob_wrap, opts, io_status); + if (!io_status.success_) { + HILOG(kDebug, "Failed to read blob of size {} from backend", + opts.backend_size_) + return 0; + } + if (opts.DoSeek()) { + stat.st_ptr_ = off + total_size; + } + return total_size; + } + } + + // Fragment I/O request into pages + BlobPlacements mapping; + auto mapper = MapperFactory::Get(MapperType::kBalancedMapper); + mapper->map(off, total_size, stat.page_size_, mapping); + size_t data_offset = 0; + + // Perform a PartialPut for each page + Context ctx; + ctx.flags_.SetBits(HERMES_SHOULD_STAGE); + for (const BlobPlacement &p : mapping) { + Blob page((const char*)ptr + data_offset, p.blob_size_); + std::string blob_name(p.CreateBlobName().str()); + if constexpr (ASYNC) { + LPointer> task = + bkt.AsyncPartialGet(blob_name, page, p.blob_off_, ctx); + tasks.emplace_back(task); + } else { + bkt.PartialGet(blob_name, page, p.blob_off_, ctx); + } + data_offset += page.size(); + if (page.size() != p.blob_size_) { + break; + } + } + if (opts.DoSeek()) { + stat.st_ptr_ = off + data_offset; + } + stat.UpdateTime(); + io_status.size_ = data_offset; + UpdateIoStatus(opts, io_status); + return data_offset; + } /** read */ size_t Read(File &f, AdapterStat &stat, void *ptr, size_t off, size_t total_size, - IoStatus &io_status, FsIoOptions opts = FsIoOptions()); + IoStatus &io_status, FsIoOptions opts = FsIoOptions()) { + std::vector>> tasks; + return BaseRead(f, stat, ptr, off, total_size, 0, tasks, io_status, opts); + } /** write asynchronously */ - Task* AWrite(File &f, AdapterStat &stat, const void *ptr, size_t off, - size_t total_size, size_t req_id, IoStatus &io_status, - FsIoOptions opts = FsIoOptions()); + FsAsyncTask* AWrite(File &f, AdapterStat &stat, const void *ptr, size_t off, + size_t total_size, size_t req_id, IoStatus &io_status, + FsIoOptions opts = FsIoOptions()) { + // Writes are completely async at this time + FsAsyncTask *fstask = new FsAsyncTask(); + Write(f, stat, ptr, off, total_size, io_status, opts); + fstask->io_status_.Copy(io_status); + fstask->opts_ = opts; + return fstask; + } + /** read asynchronously */ - Task* ARead(File &f, AdapterStat &stat, void *ptr, size_t off, - size_t total_size, size_t req_id, IoStatus &io_status, - FsIoOptions opts = FsIoOptions()); + FsAsyncTask* ARead(File &f, AdapterStat &stat, void *ptr, size_t off, + size_t total_size, size_t req_id, + IoStatus &io_status, FsIoOptions opts = FsIoOptions()) { + FsAsyncTask *fstask = new FsAsyncTask(); + BaseRead(f, stat, ptr, off, total_size, req_id, fstask->get_tasks_, io_status, opts); + fstask->io_status_ = io_status; + fstask->opts_ = opts; + return fstask; + } + /** wait for \a req_id request ID */ - size_t Wait(uint64_t req_id); + size_t Wait(FsAsyncTask *fstask) { + for (LPointer> &push_task : fstask->put_tasks_) { + push_task->Wait(); + HRUN_CLIENT->DelTask(push_task); + } + + // Update I/O status for gets + if (!fstask->get_tasks_.empty()) { + size_t get_size = 0; + for (LPointer> &push_task : fstask->get_tasks_) { + push_task->Wait(); + GetBlobTask *task = push_task->get(); + get_size += task->data_size_; + HRUN_CLIENT->DelTask(task); + } + fstask->io_status_.size_ = get_size; + UpdateIoStatus(fstask->opts_, fstask->io_status_); + } + return 0; + } + /** wait for request IDs in \a req_id vector */ - void Wait(std::vector &req_id, std::vector &ret); + void Wait(std::vector &req_ids, std::vector &ret) { + for (auto &req_id : req_ids) { + ret.emplace_back(Wait(req_id)); + } + } + /** seek */ - size_t Seek(File &f, AdapterStat &stat, SeekMode whence, off64_t offset); + size_t Seek(File &f, AdapterStat &stat, SeekMode whence, off64_t offset) { + auto mdm = HERMES_FS_METADATA_MANAGER; + switch (whence) { + case SeekMode::kSet: { + stat.st_ptr_ = offset; + break; + } + case SeekMode::kCurrent: { + if (stat.st_ptr_ != std::numeric_limits::max()) { + stat.st_ptr_ = (off64_t)stat.st_ptr_ + offset; + offset = stat.st_ptr_; + } else { + stat.st_ptr_ = (off64_t)stat.bkt_id_.GetSize() + offset; + offset = stat.st_ptr_; + } + break; + } + case SeekMode::kEnd: { + if (offset == 0) { + stat.st_ptr_ = std::numeric_limits::max(); + offset = stat.bkt_id_.GetSize(); + } else { + stat.st_ptr_ = (off64_t)stat.bkt_id_.GetSize() + offset; + offset = stat.st_ptr_; + } + break; + } + default: { + HELOG(kError, "Invalid seek mode"); + return -1; + } + } + mdm->Update(f, stat); + return offset; + } + /** file size */ - size_t GetSize(File &f, AdapterStat &stat); + size_t GetSize(File &f, AdapterStat &stat) { + (void) stat; + if (stat.adapter_mode_ != AdapterMode::kBypass) { + return stat.bkt_id_.GetSize(); + } else { + return stdfs::file_size(stat.path_); + } + } + /** tell */ - size_t Tell(File &f, AdapterStat &stat); + size_t Tell(File &f, AdapterStat &stat) { + (void) f; + if (stat.st_ptr_ != std::numeric_limits::max()) { + return stat.st_ptr_; + } else { + return stat.bkt_id_.GetSize(); + } + } + /** sync */ - int Sync(File &f, AdapterStat &stat); + int Sync(File &f, AdapterStat &stat) { + if (HERMES_CLIENT_CONF.flushing_mode_ == FlushingMode::kSync) { + // NOTE(llogan): only for the unit tests + // Please don't enable synchronous flushing + HRUN_ADMIN->FlushRoot(DomainId::GetGlobal()); + } + return 0; + } + /** truncate */ - int Truncate(File &f, AdapterStat &stat, size_t new_size); + int Truncate(File &f, AdapterStat &stat, size_t new_size) { + // hapi::Bucket &bkt = stat.bkt_id_; + // TODO(llogan) + return 0; + } + /** close */ - int Close(File &f, AdapterStat &stat); + int Close(File &f, AdapterStat &stat) { + Sync(f, stat); + auto mdm = HERMES_FS_METADATA_MANAGER; + FilesystemIoClientState fs_ctx(&mdm->fs_mdm_, (void*)&stat); + HermesClose(f, stat, fs_ctx); + RealClose(f, stat); + mdm->Delete(stat.path_, f); + if (stat.amode_ & MPI_MODE_DELETE_ON_CLOSE) { + Remove(stat.path_); + } + if (HERMES_CLIENT_CONF.flushing_mode_ == FlushingMode::kSync) { + // NOTE(llogan): only for the unit tests + // Please don't enable synchronous flushing + // stat.bkt_id_.Destroy(); + } + return 0; + } + /** remove */ - int Remove(const std::string &pathname); + int Remove(const std::string &pathname) { + auto mdm = HERMES_FS_METADATA_MANAGER; + int ret = RealRemove(pathname); + // Destroy the bucket + std::string canon_path = stdfs::absolute(pathname).string(); + Bucket bkt = HERMES->GetBucket(canon_path); + bkt.Destroy(); + // Destroy all file descriptors + std::list* filesp = mdm->Find(pathname); + if (filesp == nullptr) { + return ret; + } + HILOG(kDebug, "Destroying the file descriptors: {}", pathname); + std::list files = *filesp; + for (File &f : files) { + std::shared_ptr stat = mdm->Find(f); + if (stat == nullptr) { continue; } + FilesystemIoClientState fs_ctx(&mdm->fs_mdm_, (void *)&stat); + HermesClose(f, *stat, fs_ctx); + RealClose(f, *stat); + mdm->Delete(stat->path_, f); + if (stat->adapter_mode_ == AdapterMode::kScratch) { + ret = 0; + } + } + return ret; + } - /* + /** * I/O APIs which seek based on the internal AdapterStat st_ptr, * instead of taking an offset as input. */ @@ -105,19 +462,35 @@ class Filesystem { public: /** write */ size_t Write(File &f, AdapterStat &stat, const void *ptr, size_t total_size, - IoStatus &io_status, FsIoOptions opts); + IoStatus &io_status, FsIoOptions opts) { + size_t off = stat.st_ptr_; + return Write(f, stat, ptr, off, total_size, io_status, opts); + } + /** read */ size_t Read(File &f, AdapterStat &stat, void *ptr, size_t total_size, - IoStatus &io_status, FsIoOptions opts); + IoStatus &io_status, FsIoOptions opts) { + size_t off = stat.st_ptr_; + return Read(f, stat, ptr, off, total_size, io_status, opts); + } + /** write asynchronously */ - Task* AWrite(File &f, AdapterStat &stat, const void *ptr, - size_t total_size, size_t req_id, IoStatus &io_status, - FsIoOptions opts); + FsAsyncTask* AWrite(File &f, AdapterStat &stat, const void *ptr, + size_t total_size, size_t req_id, IoStatus &io_status, + FsIoOptions opts) { + size_t off = stat.st_ptr_; + return AWrite(f, stat, ptr, off, total_size, req_id, io_status, opts); + } + /** read asynchronously */ - Task* ARead(File &f, AdapterStat &stat, void *ptr, size_t total_size, - size_t req_id, IoStatus &io_status, FsIoOptions opts); + FsAsyncTask* ARead(File &f, AdapterStat &stat, void *ptr, size_t total_size, + size_t req_id, + IoStatus &io_status, FsIoOptions opts) { + size_t off = stat.st_ptr_; + return ARead(f, stat, ptr, off, total_size, req_id, io_status, opts); + } - /* + /** * Locates the AdapterStat data structure internally, and * call the underlying APIs which take AdapterStat as input. */ @@ -125,45 +498,189 @@ class Filesystem { public: /** write */ size_t Write(File &f, bool &stat_exists, const void *ptr, size_t total_size, - IoStatus &io_status, FsIoOptions opts = FsIoOptions()); + IoStatus &io_status, FsIoOptions opts = FsIoOptions()) { + auto mdm = HERMES_FS_METADATA_MANAGER; + auto stat = mdm->Find(f); + if (!stat) { + stat_exists = false; + return 0; + } + stat_exists = true; + return Write(f, *stat, ptr, total_size, io_status, opts); + } + /** read */ size_t Read(File &f, bool &stat_exists, void *ptr, size_t total_size, - IoStatus &io_status, FsIoOptions opts = FsIoOptions()); + IoStatus &io_status, FsIoOptions opts = FsIoOptions()) { + auto mdm = HERMES_FS_METADATA_MANAGER; + auto stat = mdm->Find(f); + if (!stat) { + stat_exists = false; + return 0; + } + stat_exists = true; + return Read(f, *stat, ptr, total_size, io_status, opts); + } + /** write \a off offset */ size_t Write(File &f, bool &stat_exists, const void *ptr, size_t off, size_t total_size, IoStatus &io_status, - FsIoOptions opts = FsIoOptions()); + FsIoOptions opts = FsIoOptions()) { + auto mdm = HERMES_FS_METADATA_MANAGER; + auto stat = mdm->Find(f); + if (!stat) { + stat_exists = false; + return 0; + } + stat_exists = true; + opts.UnsetSeek(); + return Write(f, *stat, ptr, off, total_size, io_status, opts); + } + /** read \a off offset */ size_t Read(File &f, bool &stat_exists, void *ptr, size_t off, size_t total_size, IoStatus &io_status, - FsIoOptions opts = FsIoOptions()); + FsIoOptions opts = FsIoOptions()) { + auto mdm = HERMES_FS_METADATA_MANAGER; + auto stat = mdm->Find(f); + if (!stat) { + stat_exists = false; + return 0; + } + stat_exists = true; + opts.UnsetSeek(); + return Read(f, *stat, ptr, off, total_size, io_status, opts); + } + /** write asynchronously */ - Task* AWrite(File &f, bool &stat_exists, const void *ptr, - size_t total_size, size_t req_id, IoStatus &io_status, - FsIoOptions opts); + FsAsyncTask* AWrite(File &f, bool &stat_exists, const void *ptr, + size_t total_size, size_t req_id, + std::vector &tasks, + IoStatus &io_status, FsIoOptions opts) { + auto mdm = HERMES_FS_METADATA_MANAGER; + auto stat = mdm->Find(f); + if (!stat) { + stat_exists = false; + return 0; + } + stat_exists = true; + return AWrite(f, *stat, ptr, total_size, req_id, io_status, opts); + } + /** read asynchronously */ - Task* ARead(File &f, bool &stat_exists, void *ptr, size_t total_size, - size_t req_id, IoStatus &io_status, FsIoOptions opts); + FsAsyncTask* ARead(File &f, bool &stat_exists, void *ptr, size_t total_size, + size_t req_id, IoStatus &io_status, FsIoOptions opts) { + auto mdm = HERMES_FS_METADATA_MANAGER; + auto stat = mdm->Find(f); + if (!stat) { + stat_exists = false; + return 0; + } + stat_exists = true; + return ARead(f, *stat, ptr, total_size, req_id, io_status, opts); + } + /** write \a off offset asynchronously */ - Task* AWrite(File &f, bool &stat_exists, const void *ptr, size_t off, - size_t total_size, size_t req_id, IoStatus &io_status, - FsIoOptions opts); + FsAsyncTask* AWrite(File &f, bool &stat_exists, const void *ptr, size_t off, + size_t total_size, size_t req_id, IoStatus &io_status, + FsIoOptions opts) { + auto mdm = HERMES_FS_METADATA_MANAGER; + auto stat = mdm->Find(f); + if (!stat) { + stat_exists = false; + return 0; + } + stat_exists = true; + opts.UnsetSeek(); + return AWrite(f, *stat, ptr, off, total_size, req_id, io_status, opts); + } + /** read \a off offset asynchronously */ - Task* ARead(File &f, bool &stat_exists, void *ptr, size_t off, - size_t total_size, size_t req_id, IoStatus &io_status, - FsIoOptions opts); + FsAsyncTask* ARead(File &f, bool &stat_exists, void *ptr, size_t off, + size_t total_size, size_t req_id, IoStatus &io_status, + FsIoOptions opts) { + auto mdm = HERMES_FS_METADATA_MANAGER; + auto stat = mdm->Find(f); + if (!stat) { + stat_exists = false; + return 0; + } + stat_exists = true; + opts.UnsetSeek(); + return ARead(f, *stat, ptr, off, total_size, req_id, io_status, opts); + } + /** seek */ - size_t Seek(File &f, bool &stat_exists, SeekMode whence, size_t offset); + size_t Seek(File &f, bool &stat_exists, SeekMode whence, size_t offset) { + auto mdm = HERMES_FS_METADATA_MANAGER; + auto stat = mdm->Find(f); + if (!stat) { + stat_exists = false; + return -1; + } + stat_exists = true; + return Seek(f, *stat, whence, offset); + } + /** file sizes */ - size_t GetSize(File &f, bool &stat_exists); + size_t GetSize(File &f, bool &stat_exists) { + auto mdm = HERMES_FS_METADATA_MANAGER; + auto stat = mdm->Find(f); + if (!stat) { + stat_exists = false; + return -1; + } + stat_exists = true; + return GetSize(f, *stat); + } + /** tell */ - size_t Tell(File &f, bool &stat_exists); + size_t Tell(File &f, bool &stat_exists) { + auto mdm = HERMES_FS_METADATA_MANAGER; + auto stat = mdm->Find(f); + if (!stat) { + stat_exists = false; + return -1; + } + stat_exists = true; + return Tell(f, *stat); + } + /** sync */ - int Sync(File &f, bool &stat_exists); + int Sync(File &f, bool &stat_exists) { + auto mdm = HERMES_FS_METADATA_MANAGER; + auto stat = mdm->Find(f); + if (!stat) { + stat_exists = false; + return -1; + } + stat_exists = true; + return Sync(f, *stat); + } + /** truncate */ - int Truncate(File &f, bool &stat_exists, size_t new_size); + int Truncate(File &f, bool &stat_exists, size_t new_size) { + auto mdm = HERMES_FS_METADATA_MANAGER; + auto stat = mdm->Find(f); + if (!stat) { + stat_exists = false; + return -1; + } + stat_exists = true; + return Truncate(f, *stat, new_size); + } + /** close */ - int Close(File &f, bool &stat_exists); + int Close(File &f, bool &stat_exists) { + auto mdm = HERMES_FS_METADATA_MANAGER; + auto stat = mdm->Find(f); + if (!stat) { + stat_exists = false; + return -1; + } + stat_exists = true; + return Close(f, *stat); + } public: /** Whether or not \a path PATH is tracked by Hermes */ @@ -188,6 +705,6 @@ class Filesystem { } }; -} // namespace hermes::adapter::fs +} // namespace hermes::adapter #endif // HERMES_ADAPTER_FILESYSTEM_FILESYSTEM_H_ diff --git a/hermes_adapters/filesystem/filesystem_io_client.h b/hermes_adapters/filesystem/filesystem_io_client.h index dab208fcd..8e504501e 100644 --- a/hermes_adapters/filesystem/filesystem_io_client.h +++ b/hermes_adapters/filesystem/filesystem_io_client.h @@ -23,7 +23,7 @@ namespace stdfs = std::filesystem; -namespace hermes::adapter::fs { +namespace hermes::adapter { /** Put or get data directly from I/O client */ #define HERMES_IO_CLIENT_BYPASS BIT_OPT(uint32_t, 0) @@ -53,12 +53,19 @@ struct IoStatus { mpi_ret_(MPI_SUCCESS), mpi_status_ptr_(&mpi_status_), success_(true) {} -}; -/** A structure to represent Hermes request */ -struct HermesRequest { - std::future return_future; /**< future result of async op. */ - IoStatus io_status; /**< IO status */ + /** Copy constructor */ + void Copy(const IoStatus &other) { + size_ = other.size_; + mpi_ret_ = other.mpi_ret_; + mpi_status_ = other.mpi_status_; + if (other.mpi_status_ptr_ == &other.mpi_status_) { + mpi_status_ptr_ = &mpi_status_; + } else { + mpi_status_ptr_ = other.mpi_status_ptr_; + } + success_ = other.success_; + } }; /** @@ -66,19 +73,18 @@ struct HermesRequest { * For now, nothing additional than the typical FsIoOptions. * */ struct FsIoOptions { - AdapterMode adapter_mode_; /**< Current adapter mode for this obj */ - hapi::PlacementPolicy dpe_; /**< data placement policy */ - bitfield32_t flags_; /**< various I/O flags */ - MPI_Datatype mpi_type_; /**< MPI data type */ - int mpi_count_; /**< The number of types */ - size_t backend_off_; /**< Offset in the backend to begin I/O */ - size_t backend_size_; /**< Size of I/O to perform at backend */ + bitfield32_t flags_; /**< various I/O flags */ + MPI_Datatype mpi_type_; /**< MPI data type */ + int mpi_count_; /**< The number of types */ + int type_size_; /**< The size of type */ + size_t backend_off_; /**< Offset in the backend to begin I/O */ + size_t backend_size_; /**< Size of I/O to perform at backend */ /** Default constructor */ - FsIoOptions() : dpe_(hapi::PlacementPolicy::kNone), - flags_(), + FsIoOptions() : flags_(), mpi_type_(MPI_CHAR), mpi_count_(0), + type_size_(1), backend_off_(0), backend_size_(0) { SetSeek(); @@ -116,13 +122,14 @@ struct FsIoOptions { if (!seek) { opts.UnsetSeek(); } return opts; } +}; - /** Return Io options with \a DPE */ - static FsIoOptions WithDpe(hapi::PlacementPolicy dpe) { - FsIoOptions opts; - opts.dpe_ = dpe; - return opts; - } +/** A structure to represent Hermes request */ +struct FsAsyncTask { + std::vector>> put_tasks_; + std::vector>> get_tasks_; + IoStatus io_status_; + FsIoOptions opts_; }; /** Represents an object in the I/O client (e.g., a file) */ @@ -301,7 +308,7 @@ class FilesystemIoClient { virtual ~FilesystemIoClient() = default; /** Get initial statistics from the backend */ - virtual size_t GetSize(const hipc::charbuf &bkt_name) = 0; + virtual size_t GetBackendSize(const hipc::charbuf &bkt_name) = 0; /** Write blob to backend */ virtual void WriteBlob(const std::string &bkt_name, @@ -348,16 +355,19 @@ class FilesystemIoClient { virtual void HermesClose(File &f, const AdapterStat &stat, FilesystemIoClientState &fs_mdm) = 0; + + /** Updates I/O status after read/write operations */ + virtual void UpdateIoStatus(const FsIoOptions &opts, IoStatus &status) = 0; }; -} // namespace hermes::adapter::fs +} // namespace hermes::adapter namespace std { /** A structure to represent hash */ template <> -struct hash<::hermes::adapter::fs::File> { +struct hash<::hermes::adapter::File> { /** hash creator functor */ - std::size_t operator()(const hermes::adapter::fs::File &key) const { + std::size_t operator()(const hermes::adapter::File &key) const { return key.hash(); } }; diff --git a/hermes_adapters/filesystem/filesystem_mdm.cc b/hermes_adapters/filesystem/filesystem_mdm.cc deleted file mode 100644 index 69da5379d..000000000 --- a/hermes_adapters/filesystem/filesystem_mdm.cc +++ /dev/null @@ -1,80 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include "filesystem_mdm.h" -#include "hermes/hermes.h" -#include - -namespace hermes::adapter::fs { - -bool MetadataManager::Create(const File &f, - std::shared_ptr &stat) { - HILOG(kDebug, "Create metadata for file handler") - ScopedRwWriteLock md_lock(lock_, kMDM_Create); - if (path_to_hermes_file_.find(stat->path_) == path_to_hermes_file_.end()) { - path_to_hermes_file_.emplace(stat->path_, std::list()); - } - path_to_hermes_file_[stat->path_].emplace_back(f); - auto ret = hermes_file_to_stat_.emplace(f, std::move(stat)); - return ret.second; -} - -bool MetadataManager::Update(const File &f, const AdapterStat &stat) { - HILOG(kDebug, "Update metadata for file handler") - ScopedRwWriteLock md_lock(lock_, kMDM_Update); - auto iter = hermes_file_to_stat_.find(f); - if (iter != hermes_file_to_stat_.end()) { - *(*iter).second = stat; - return true; - } else { - return false; - } -} - -std::list* MetadataManager::Find(const std::string &path) { - std::string canon_path = stdfs::absolute(path).string(); - ScopedRwReadLock md_lock(lock_, kMDM_Find); - auto iter = path_to_hermes_file_.find(canon_path); - if (iter == path_to_hermes_file_.end()) - return nullptr; - else - return &iter->second; -} - -std::shared_ptr MetadataManager::Find(const File &f) { - ScopedRwReadLock md_lock(lock_, kMDM_Find2); - auto iter = hermes_file_to_stat_.find(f); - if (iter == hermes_file_to_stat_.end()) - return nullptr; - else - return iter->second; -} - -bool MetadataManager::Delete(const std::string &path, const File &f) { - HILOG(kDebug, "Delete metadata for file handler") - ScopedRwWriteLock md_lock(lock_, kMDM_Delete); - auto iter = hermes_file_to_stat_.find(f); - if (iter != hermes_file_to_stat_.end()) { - hermes_file_to_stat_.erase(iter); - auto &list = path_to_hermes_file_[path]; - auto f_iter = std::find(list.begin(), list.end(), f); - path_to_hermes_file_[path].erase(f_iter); - if (list.size() == 0) { - path_to_hermes_file_.erase(path); - } - return true; - } else { - return false; - } -} - -} // namespace hermes::adapter::fs diff --git a/hermes_adapters/filesystem/filesystem_mdm.h b/hermes_adapters/filesystem/filesystem_mdm.h index a4f8a6430..06cf65784 100644 --- a/hermes_adapters/filesystem/filesystem_mdm.h +++ b/hermes_adapters/filesystem/filesystem_mdm.h @@ -16,9 +16,8 @@ #include #include #include "filesystem_io_client.h" -#include "filesystem.h" -namespace hermes::adapter::fs { +namespace hermes::adapter { /** * Metadata manager for POSIX adapter @@ -26,15 +25,15 @@ namespace hermes::adapter::fs { class MetadataManager { private: std::unordered_map> - path_to_hermes_file_; /**< Map to determine if path is buffered. */ + path_to_hermes_file_; /**< Map to determine if path is buffered. */ std::unordered_map> - hermes_file_to_stat_; /**< Map for metadata */ - RwLock lock_; /**< Lock to synchronize MD updates*/ + hermes_file_to_stat_; /**< Map for metadata */ + RwLock lock_; /**< Lock to synchronize MD updates*/ public: - /** map for Hermes request */ - std::unordered_map request_map; - FsIoClientMetadata fs_mdm_; /**< Context needed for I/O clients */ + std::unordered_map + request_map_; /**< Map for async FS requests */ + FsIoClientMetadata fs_mdm_; /**< Context needed for I/O clients */ /** Constructor */ MetadataManager() = default; @@ -65,7 +64,16 @@ class MetadataManager { * @return true, if operation was successful. * false, if operation was unsuccessful. */ - bool Create(const File& f, std::shared_ptr &stat); + bool Create(const File& f, std::shared_ptr &stat) { + HILOG(kDebug, "Create metadata for file handler") + ScopedRwWriteLock md_lock(lock_, kMDM_Create); + if (path_to_hermes_file_.find(stat->path_) == path_to_hermes_file_.end()) { + path_to_hermes_file_.emplace(stat->path_, std::list()); + } + path_to_hermes_file_[stat->path_].emplace_back(f); + auto ret = hermes_file_to_stat_.emplace(f, std::move(stat)); + return ret.second; + } /** * Update existing metadata entry for filesystem adapters. @@ -74,7 +82,17 @@ class MetadataManager { * @return true, if operation was successful. * false, if operation was unsuccessful or entry doesn't exist. */ - bool Update(const File& f, const AdapterStat& stat); + bool Update(const File& f, const AdapterStat& stat) { + HILOG(kDebug, "Update metadata for file handler") + ScopedRwWriteLock md_lock(lock_, kMDM_Update); + auto iter = hermes_file_to_stat_.find(f); + if (iter != hermes_file_to_stat_.end()) { + *(*iter).second = stat; + return true; + } else { + return false; + } + } /** * Delete existing metadata entry for for filesystem adapters. @@ -82,14 +100,38 @@ class MetadataManager { * @return true, if operation was successful. * false, if operation was unsuccessful. */ - bool Delete(const std::string &path, const File& f); + bool Delete(const std::string &path, const File& f) { + HILOG(kDebug, "Delete metadata for file handler") + ScopedRwWriteLock md_lock(lock_, kMDM_Delete); + auto iter = hermes_file_to_stat_.find(f); + if (iter != hermes_file_to_stat_.end()) { + hermes_file_to_stat_.erase(iter); + auto &list = path_to_hermes_file_[path]; + auto f_iter = std::find(list.begin(), list.end(), f); + path_to_hermes_file_[path].erase(f_iter); + if (list.size() == 0) { + path_to_hermes_file_.erase(path); + } + return true; + } else { + return false; + } + } /** * Find the hermes file relating to a path. * @param path the path being checked * @return The hermes file. * */ - std::list* Find(const std::string &path); + std::list* Find(const std::string &path) { + std::string canon_path = stdfs::absolute(path).string(); + ScopedRwReadLock md_lock(lock_, kMDM_Find); + auto iter = path_to_hermes_file_.find(canon_path); + if (iter == path_to_hermes_file_.end()) + return nullptr; + else + return &iter->second; + } /** * Find existing metadata entry for filesystem adapters. @@ -97,16 +139,55 @@ class MetadataManager { * @return The metadata entry if exist. * The bool in pair indicated whether metadata entry exists. */ - std::shared_ptr Find(const File& f); + std::shared_ptr Find(const File& f) { + ScopedRwReadLock md_lock(lock_, kMDM_Find2); + auto iter = hermes_file_to_stat_.find(f); + if (iter == hermes_file_to_stat_.end()) + return nullptr; + else + return iter->second; + } + + /** + * Add a request to the request map. + * */ + void EmplaceTask(uint64_t id, FsAsyncTask* task) { + ScopedRwWriteLock md_lock(lock_, 0); + request_map_.emplace(id, task); + } + + /** + * Find a request in the request map. + * */ + FsAsyncTask* FindTask(uint64_t id) { + ScopedRwReadLock md_lock(lock_, 0); + auto iter = request_map_.find(id); + if (iter == request_map_.end()) { + return nullptr; + } else { + return iter->second; + } + } + + /** + * Delete a request in the request map. + * */ + void DeleteTask(uint64_t id) { + ScopedRwWriteLock md_lock(lock_, 0); + auto iter = request_map_.find(id); + if (iter != request_map_.end()) { + request_map_.erase(iter); + } + } }; -} // namespace hermes::adapter::fs +} // namespace hermes::adapter // Singleton macros #include "hermes_shm/util/singleton.h" #define HERMES_FS_METADATA_MANAGER \ - hshm::Singleton<::hermes::adapter::fs::MetadataManager>::GetInstance() -#define HERMES_FS_METADATA_MANAGER_T hermes::adapter::fs::MetadataManager* + hshm::Singleton<::hermes::adapter::MetadataManager>::GetInstance() +#define HERMES_FS_METADATA_MANAGER_T hermes::adapter::MetadataManager* #endif // HERMES_ADAPTER_METADATA_MANAGER_H diff --git a/hermes_adapters/filesystem/filesystem_mdm_singleton.cc b/hermes_adapters/filesystem/filesystem_mdm_singleton.cc index a729e4b0f..f706821e7 100644 --- a/hermes_adapters/filesystem/filesystem_mdm_singleton.cc +++ b/hermes_adapters/filesystem/filesystem_mdm_singleton.cc @@ -13,4 +13,4 @@ #include "hermes_shm/util/singleton.h" #include "filesystem_mdm.h" -DEFINE_SINGLETON_CC(hermes::adapter::fs::MetadataManager) +DEFINE_SINGLETON_CC(hermes::adapter::MetadataManager) diff --git a/hermes_adapters/mpiio/CMakeLists.txt b/hermes_adapters/mpiio/CMakeLists.txt index 60cbee153..cfd2c664a 100644 --- a/hermes_adapters/mpiio/CMakeLists.txt +++ b/hermes_adapters/mpiio/CMakeLists.txt @@ -5,12 +5,7 @@ include_directories( ${HERMES_IO_CLIENT_DIR} .) -# Create the MPIIO I/O client -add_library(hermes_mpiio_io_client SHARED mpiio_io_client.cc) -add_dependencies(hermes_mpiio_io_client - hermes hermes_fs_base) -target_link_libraries(hermes_mpiio_io_client - hermes hermes_fs_base MPI::MPI_CXX stdc++fs dl) +# Create the MPIIO interceptor if (HERMES_MPICH) message(STATUS "Using HERMES_MPICH") add_definitions(-DHERMES_MPICH) @@ -18,22 +13,18 @@ elseif(HERMES_OPENMPI) message(STATUS "Using HERMES_OPENMPI") add_definitions(-DHERMES_OPENMPI) endif() - -# Create the MPIIO interceptor set(INTERCEPTOR_DEPS - hermes - hermes_mpiio_io_client) + hermes hermes_fs_base) add_library(hermes_mpiio SHARED ${CMAKE_CURRENT_SOURCE_DIR}/mpiio_api.cc) add_dependencies(hermes_mpiio ${INTERCEPTOR_DEPS}) -target_link_libraries(hermes_mpiio ${INTERCEPTOR_DEPS}) +target_link_libraries(hermes_mpiio MPI::MPI_CXX stdc++fs dl ${INTERCEPTOR_DEPS}) #----------------------------------------------------------------------------- # Add Target(s) to CMake Install #----------------------------------------------------------------------------- install( TARGETS - hermes_mpiio_io_client hermes_mpiio EXPORT ${HERMES_EXPORTED_TARGETS} @@ -59,6 +50,5 @@ install( # Add Target(s) to Coverage #----------------------------------------------------------------------------- if(HERMES_ENABLE_COVERAGE) - set_coverage_flags(hermes_mpiio_io_client) - #set_coverage_flags(hermes_mpiio) + set_coverage_flags(hermes_mpiio) endif() \ No newline at end of file diff --git a/hermes_adapters/mpiio/mpiio_api.cc b/hermes_adapters/mpiio/mpiio_api.cc index e9dbb397d..e7b9b4a83 100644 --- a/hermes_adapters/mpiio/mpiio_api.cc +++ b/hermes_adapters/mpiio/mpiio_api.cc @@ -19,18 +19,19 @@ bool mpiio_intercepted = true; #include "mpiio_fs_api.h" #include "hermes_shm/util/singleton.h" -#include "hermes_adapters/interceptor.h" /** * Namespace declarations */ -using hermes::adapter::fs::MetadataManager; -using hermes::adapter::fs::File; -using hermes::adapter::fs::AdapterStat; -using hermes::adapter::fs::MpiioApi; -using hermes::adapter::fs::MpiioFs; -using hermes::adapter::fs::MpiioSeekModeConv; - +using hermes::adapter::MetadataManager; +using hermes::adapter::File; +using hermes::adapter::AdapterStat; +using hermes::adapter::SeekMode; +using hermes::adapter::IoStatus; +using hermes::adapter::FsIoOptions; +using hermes::adapter::MpiioApi; +using hermes::adapter::MpiioFs; +using hermes::adapter::MpiioSeekModeConv; extern "C" { diff --git a/hermes_adapters/mpiio/mpiio_api.h b/hermes_adapters/mpiio/mpiio_api.h index 6d9424971..283050e21 100644 --- a/hermes_adapters/mpiio/mpiio_api.h +++ b/hermes_adapters/mpiio/mpiio_api.h @@ -57,7 +57,7 @@ typedef int (*MPI_File_iwrite_shared_t)(MPI_File fh, const void * buf, int count typedef int (*MPI_File_sync_t)(MPI_File fh); } -namespace hermes::adapter::fs { +namespace hermes::adapter { /** Pointers to the real mpiio API */ class MpiioApi : public RealApi { @@ -184,7 +184,7 @@ class MpiioApi : public RealApi { /** Simplify access to the stateless MpiioFs Singleton */ #define HERMES_MPIIO_API \ - hshm::EasySingleton<::hermes::adapter::fs::MpiioApi>::GetInstance() -#define HERMES_MPIIO_API_T hermes::adapter::fs::MpiioApi* + hshm::EasySingleton<::hermes::adapter::MpiioApi>::GetInstance() +#define HERMES_MPIIO_API_T hermes::adapter::MpiioApi* #endif // HERMES_ADAPTER_MPIIO_H diff --git a/hermes_adapters/mpiio/mpiio_fs_api.h b/hermes_adapters/mpiio/mpiio_fs_api.h index 6e98b7b41..a9b79bfe0 100644 --- a/hermes_adapters/mpiio/mpiio_fs_api.h +++ b/hermes_adapters/mpiio/mpiio_fs_api.h @@ -18,9 +18,8 @@ #include "hermes_adapters/filesystem/filesystem.h" #include "hermes_adapters/filesystem/filesystem_mdm.h" #include "mpiio_api.h" -#include "mpiio_io_client.h" -namespace hermes::adapter::fs { +namespace hermes::adapter { /** A class to represent MPI IO seek mode conversion */ class MpiioSeekModeConv { @@ -43,9 +42,21 @@ class MpiioSeekModeConv { /** A class to represent POSIX IO file system */ class MpiioFs : public Filesystem { public: - MpiioFs() - : Filesystem(HERMES_MPIIO_IO_CLIENT, - AdapterType::kMpiio) {} + HERMES_MPIIO_API_T real_api_; /**< pointer to real APIs */ + + MpiioFs() : Filesystem(AdapterType::kMpiio) { + real_api_ = HERMES_MPIIO_API; + } + + /** Initialize I/O opts using count + datatype */ + static size_t IoSizeFromCount(int count, + MPI_Datatype datatype, + FsIoOptions &opts) { + opts.mpi_type_ = datatype; + opts.mpi_count_ = count; + MPI_Type_size(datatype, &opts.type_size_); + return static_cast(count * opts.type_size_); + } inline bool IsMpiFpTracked(MPI_File *fh, std::shared_ptr &stat) { auto mdm = HERMES_FS_METADATA_MANAGER; @@ -62,27 +73,26 @@ class MpiioFs : public Filesystem { int Read(File &f, AdapterStat &stat, void *ptr, size_t offset, int count, MPI_Datatype datatype, MPI_Status *status, FsIoOptions opts) { - opts.mpi_type_ = datatype; IoStatus io_status; io_status.mpi_status_ptr_ = status; - size_t total_size = MpiioIoClient::IoSizeFromCount(count, datatype, opts); + size_t total_size = IoSizeFromCount(count, datatype, opts); Filesystem::Read(f, stat, ptr, offset, total_size, io_status, opts); return io_status.mpi_ret_; } int ARead(File &f, AdapterStat &stat, void *ptr, size_t offset, int count, MPI_Datatype datatype, MPI_Request *request, FsIoOptions opts) { - opts.mpi_type_ = datatype; + auto mdm = HERMES_FS_METADATA_MANAGER; IoStatus io_status; - size_t total_size = MpiioIoClient::IoSizeFromCount(count, datatype, opts); - Filesystem::ARead(f, stat, ptr, offset, total_size, - reinterpret_cast(request), io_status, opts); + size_t total_size = IoSizeFromCount(count, datatype, opts); + FsAsyncTask *fstask = Filesystem::ARead(f, stat, ptr, offset, total_size, + reinterpret_cast(request), io_status, opts); + mdm->EmplaceTask(reinterpret_cast(request), fstask); return io_status.mpi_ret_; } int ReadAll(File &f, AdapterStat &stat, void *ptr, size_t offset, int count, MPI_Datatype datatype, MPI_Status *status, FsIoOptions opts) { - opts.mpi_type_ = datatype; MPI_Barrier(stat.comm_); size_t ret = Read(f, stat, ptr, offset, count, datatype, status, opts); MPI_Barrier(stat.comm_); @@ -104,10 +114,9 @@ class MpiioFs : public Filesystem { int Write(File &f, AdapterStat &stat, const void *ptr, size_t offset, int count, MPI_Datatype datatype, MPI_Status *status, FsIoOptions opts) { - opts.mpi_type_ = datatype; IoStatus io_status; io_status.mpi_status_ptr_ = status; - size_t total_size = MpiioIoClient::IoSizeFromCount(count, datatype, opts); + size_t total_size = IoSizeFromCount(count, datatype, opts); Filesystem::Write(f, stat, ptr, offset, total_size, io_status, opts); return io_status.mpi_ret_; } @@ -115,72 +124,85 @@ class MpiioFs : public Filesystem { int AWrite(File &f, AdapterStat &stat, const void *ptr, size_t offset, int count, MPI_Datatype datatype, MPI_Request *request, FsIoOptions opts) { - opts.mpi_type_ = datatype; + auto mdm = HERMES_FS_METADATA_MANAGER; IoStatus io_status; - size_t total_size = MpiioIoClient::IoSizeFromCount(count, datatype, opts); - Filesystem::AWrite(f, stat, ptr, offset, total_size, - reinterpret_cast(request), io_status, opts); + size_t total_size = IoSizeFromCount(count, datatype, opts); + FsAsyncTask *fstask = Filesystem::AWrite(f, stat, ptr, offset, total_size, + reinterpret_cast(request), io_status, opts); + mdm->EmplaceTask(reinterpret_cast(request), fstask); return io_status.mpi_ret_; } + template + int BaseWriteAll(File &f, AdapterStat &stat, const void *ptr, size_t offset, + int count, MPI_Datatype datatype, MPI_Status *status, + MPI_Request *request, FsIoOptions opts) { + if constexpr(!ASYNC) { + MPI_Barrier(stat.comm_); + int ret = Write(f, stat, ptr, offset, count, datatype, status, opts); + MPI_Barrier(stat.comm_); + return ret; + } else { + return AWrite(f, stat, ptr, offset, count, datatype, request, opts); + } + } + int WriteAll(File &f, AdapterStat &stat, const void *ptr, size_t offset, int count, MPI_Datatype datatype, MPI_Status *status, FsIoOptions opts) { - opts.mpi_type_ = datatype; - MPI_Barrier(stat.comm_); - int ret = Write(f, stat, ptr, offset, count, datatype, status, opts); - MPI_Barrier(stat.comm_); - return ret; + return BaseWriteAll(f, stat, ptr, offset, count, datatype, status, + nullptr, opts); } - int WriteOrdered(File &f, AdapterStat &stat, const void *ptr, int count, - MPI_Datatype datatype, - MPI_Status *status, FsIoOptions opts) { - opts.mpi_type_ = datatype; + int AWriteAll(File &f, AdapterStat &stat, const void *ptr, size_t offset, + int count, MPI_Datatype datatype, MPI_Request *request, + FsIoOptions opts) { + return BaseWriteAll(f, stat, ptr, offset, count, datatype, nullptr, + request, opts); + } + + template + int BaseWriteOrdered(File &f, AdapterStat &stat, const void *ptr, int count, + MPI_Datatype datatype, MPI_Status *status, + MPI_Request *request, FsIoOptions opts) { int total; MPI_Scan(&count, &total, 1, MPI_INT, MPI_SUM, stat.comm_); MPI_Offset my_offset = total - count; - size_t ret = - WriteAll(f, stat, ptr, my_offset, count, datatype, status, opts); - return ret; + if constexpr(!ASYNC) { + size_t ret = + WriteAll(f, stat, ptr, my_offset, count, datatype, status, opts); + return ret; + } else { + return AWriteAll(f, stat, ptr, my_offset, count, datatype, request, opts); + } + } + + int WriteOrdered(File &f, AdapterStat &stat, const void *ptr, int count, + MPI_Datatype datatype, + MPI_Status *status, FsIoOptions opts) { + return BaseWriteOrdered(f, stat, ptr, count, datatype, status, + nullptr, opts); } int AWriteOrdered(File &f, AdapterStat &stat, const void *ptr, int count, MPI_Datatype datatype, MPI_Request *request, FsIoOptions opts) { HILOG(kDebug, "Starting an asynchronous write") - // TODO(llogan): FIX - /*auto mdm = HERMES_FS_METADATA_MANAGER; - auto pool = HERMES_FS_THREAD_POOL; - Task* hreq = new HermesRequest(); - auto lambda = [](MpiioFs *fs, File &f, AdapterStat &stat, const void *ptr, - int count, MPI_Datatype datatype, MPI_Status *status, - FsIoOptions opts) { - int ret = fs->WriteOrdered(f, stat, ptr, count, datatype, status, opts); - return static_cast(ret); - }; - auto func = std::bind(lambda, this, f, stat, ptr, count, datatype, - &hreq->io_status.mpi_status_, opts); - hreq->return_future = pool->run(func); - mdm->request_map.emplace(reinterpret_cast(request), hreq);*/ - return MPI_SUCCESS; + return BaseWriteOrdered(f, stat, ptr, count, datatype, nullptr, + request, opts); } int Wait(MPI_Request *req, MPI_Status *status) { - // TODO(llogan): FIX - /*auto mdm = HERMES_FS_METADATA_MANAGER; - auto real_api = HERMES_MPIIO_API; - auto iter = mdm->request_map.find(reinterpret_cast(req)); - if (iter != mdm->request_map.end()) { - Task* hreq = iter->second; - hreq->return_future.get(); - memcpy(status, hreq->io_status.mpi_status_ptr_, sizeof(MPI_Status)); - mdm->request_map.erase(iter); - delete (hreq); + auto mdm = HERMES_FS_METADATA_MANAGER; + FsAsyncTask *fstask = mdm->FindTask(reinterpret_cast(req)); + if (fstask) { + Filesystem::Wait(fstask); + memcpy(status, fstask->io_status_.mpi_status_ptr_, sizeof(MPI_Status)); + mdm->DeleteTask(reinterpret_cast(req)); + delete (fstask); return MPI_SUCCESS; } - return real_api->MPI_Wait(req, status);*/ - return 0; + return real_api_->MPI_Wait(req, status); } int WaitAll(int count, MPI_Request *req, MPI_Status *status) { @@ -473,13 +495,214 @@ class MpiioFs : public Filesystem { stat_exists = true; return SeekShared(f, *stat, offset, whence); } + + public: + /** Allocate an fd for the file f */ + void RealOpen(File &f, + AdapterStat &stat, + const std::string &path) override { + if (stat.amode_ & MPI_MODE_CREATE) { + stat.hflags_.SetBits(HERMES_FS_CREATE); + stat.hflags_.SetBits(HERMES_FS_TRUNC); + } + if (stat.amode_ & MPI_MODE_APPEND) { + stat.hflags_.SetBits(HERMES_FS_APPEND); + } + + // NOTE(llogan): Allowing scratch mode to create empty files for MPI to + // satisfy IOR. + f.mpi_status_ = real_api_->MPI_File_open( + stat.comm_, path.c_str(), stat.amode_, stat.info_, &stat.mpi_fh_); + if (f.mpi_status_ != MPI_SUCCESS) { + f.status_ = false; + } + + /*if (stat.hflags_.Any(HERMES_FS_CREATE)) { + if (stat.adapter_mode_ != AdapterMode::kScratch) { + f.mpi_status_ = real_api_->MPI_File_open( + stat.comm_, path.c_str(), stat.amode_, stat.info_, &stat.mpi_fh_); + } + } else { + f.mpi_status_ = real_api_->MPI_File_open( + stat.comm_, path.c_str(), stat.amode_, stat.info_, &stat.mpi_fh_); + } + + if (f.mpi_status_ == MPI_SUCCESS) { + stat.hflags_.SetBits(HERMES_FS_EXISTS); + } + if (f.mpi_status_ != MPI_SUCCESS && + stat.adapter_mode_ != AdapterMode::kScratch) { + f.status_ = false; + }*/ + } + + /** + * Called after real open. Allocates the Hermes representation of + * identifying file information, such as a hermes file descriptor + * and hermes file handler. These are not the same as STDIO file + * descriptor and STDIO file handler. + * */ + void HermesOpen(File &f, + const AdapterStat &stat, + FilesystemIoClientState &fs_mdm) override { + // f.hermes_mpi_fh_ = (MPI_File)fs_mdm.stat_; + f.hermes_mpi_fh_ = stat.mpi_fh_; + } + + /** Synchronize \a file FILE f */ + int RealSync(const File &f, + const AdapterStat &stat) override { + return real_api_->MPI_File_sync(stat.mpi_fh_); + } + + /** Close \a file FILE f */ + int RealClose(const File &f, + AdapterStat &stat) override { + return real_api_->MPI_File_close(&stat.mpi_fh_); + } + + /** + * Called before RealClose. Releases information provisioned during + * the allocation phase. + * */ + void HermesClose(File &f, + const AdapterStat &stat, + FilesystemIoClientState &fs_mdm) override { + (void) f; (void) stat; (void) fs_mdm; + } + + /** Remove \a file FILE f */ + int RealRemove(const std::string &path) override { + return remove(path.c_str()); + } + + /** Get initial statistics from the backend */ + size_t GetBackendSize(const hipc::charbuf &bkt_name) override { + size_t true_size = 0; + std::string filename = bkt_name.str(); + int fd = open(filename.c_str(), O_RDONLY); + if (fd < 0) { return 0; } + struct stat buf; + fstat(fd, &buf); + true_size = buf.st_size; + close(fd); + + HILOG(kDebug, "The size of the file {} on disk is {} bytes", + filename, true_size) + return true_size; + } + + /** Write blob to backend */ + void WriteBlob(const std::string &bkt_name, + const Blob &full_blob, + const FsIoOptions &opts, + IoStatus &status) override { + status.success_ = true; + HILOG(kDebug, + "Write called for: {}" + " on offset: {}" + " and size: {}", + bkt_name, opts.backend_off_, full_blob.size()) + MPI_File fh; + int write_count = 0; + status.mpi_ret_ = real_api_->MPI_File_open(MPI_COMM_SELF, bkt_name.c_str(), + MPI_MODE_RDONLY, + MPI_INFO_NULL, &fh); + if (status.mpi_ret_ != MPI_SUCCESS) { + status.success_ = false; + return; + } + + status.mpi_ret_ = real_api_->MPI_File_seek(fh, opts.backend_off_, + MPI_SEEK_SET); + if (status.mpi_ret_ != MPI_SUCCESS) { + status.success_ = false; + goto ERROR; + } + status.mpi_ret_ = real_api_->MPI_File_write(fh, + full_blob.data(), + opts.mpi_count_, + opts.mpi_type_, + status.mpi_status_ptr_); + MPI_Get_count(status.mpi_status_ptr_, + opts.mpi_type_, &write_count); + if (write_count != opts.mpi_count_) { + status.success_ = false; + HELOG(kError, "writing failed: wrote {} / {}", + write_count, opts.mpi_count_) + } + + ERROR: + real_api_->MPI_File_close(&fh); + status.size_ = full_blob.size(); + UpdateIoStatus(opts, status); + } + + /** Read blob from the backend */ + void ReadBlob(const std::string &bkt_name, + Blob &full_blob, + const FsIoOptions &opts, + IoStatus &status) override { + status.success_ = true; + HILOG(kDebug, + "Reading from: {}" + " on offset: {}" + " and size: {}", + bkt_name, opts.backend_off_, full_blob.size()) + MPI_File fh; + int read_count = 0; + status.mpi_ret_ = real_api_->MPI_File_open(MPI_COMM_SELF, bkt_name.c_str(), + MPI_MODE_RDONLY, MPI_INFO_NULL, + &fh); + if (status.mpi_ret_ != MPI_SUCCESS) { + status.success_ = false; + return; + } + + status.mpi_ret_ = real_api_->MPI_File_seek(fh, opts.backend_off_, + MPI_SEEK_SET); + if (status.mpi_ret_ != MPI_SUCCESS) { + status.success_ = false; + goto ERROR; + } + status.mpi_ret_ = real_api_->MPI_File_read(fh, + full_blob.data(), + opts.mpi_count_, + opts.mpi_type_, + status.mpi_status_ptr_); + MPI_Get_count(status.mpi_status_ptr_, + opts.mpi_type_, &read_count); + if (read_count != opts.mpi_count_) { + status.success_ = false; + HELOG(kError, "reading failed: read {} / {}", + read_count, opts.mpi_count_) + } + + ERROR: + real_api_->MPI_File_close(&fh); + status.size_ = full_blob.size(); + UpdateIoStatus(opts, status); + } + + /** Update the I/O status after a ReadBlob or WriteBlob */ + void UpdateIoStatus(const FsIoOptions &opts, IoStatus &status) override { +#ifdef HERMES_OPENMPI + status.mpi_status_ptr_->_cancelled = 0; + status.mpi_status_ptr_->_ucount = (int) (status.size_ / opts.type_size_); +#elif defined(HERMES_MPICH) + status.mpi_status_ptr_->count_hi_and_cancelled = 0; + status.mpi_status_ptr_->count_lo = (int) (status.size_ / opts.type_size_); +#else +#error "No MPI implementation specified for MPIIO adapter" +#endif + } }; -} // namespace hermes::adapter::fs +} // namespace hermes::adapter /** Simplify access to the stateless StdioFs Singleton */ #define HERMES_MPIIO_FS \ - hshm::EasySingleton<::hermes::adapter::fs::MpiioFs>::GetInstance() -#define HERMES_STDIO_FS_T hermes::adapter::fs::MpiioFs* + hshm::EasySingleton<::hermes::adapter::MpiioFs>::GetInstance() +#define HERMES_STDIO_FS_T hermes::adapter::MpiioFs* #endif // HERMES_ADAPTER_MPIIO_MPIIO_FS_API_H_ diff --git a/hermes_adapters/mpiio/mpiio_io_client.cc b/hermes_adapters/mpiio/mpiio_io_client.cc deleted file mode 100644 index b42f4e18b..000000000 --- a/hermes_adapters/mpiio/mpiio_io_client.cc +++ /dev/null @@ -1,228 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include "mpiio_io_client.h" - -namespace hermes::adapter::fs { - -/** Allocate an fd for the file f */ -void MpiioIoClient::RealOpen(File &f, - AdapterStat &stat, - const std::string &path) { - if (stat.amode_ & MPI_MODE_CREATE) { - stat.hflags_.SetBits(HERMES_FS_CREATE); - stat.hflags_.SetBits(HERMES_FS_TRUNC); - } - if (stat.amode_ & MPI_MODE_APPEND) { - stat.hflags_.SetBits(HERMES_FS_APPEND); - } - - // NOTE(llogan): Allowing scratch mode to create empty files for MPI to - // satisfy IOR. - f.mpi_status_ = real_api->MPI_File_open( - stat.comm_, path.c_str(), stat.amode_, stat.info_, &stat.mpi_fh_); - if (f.mpi_status_ != MPI_SUCCESS) { - f.status_ = false; - } - - /*if (stat.hflags_.Any(HERMES_FS_CREATE)) { - if (stat.adapter_mode_ != AdapterMode::kScratch) { - f.mpi_status_ = real_api->MPI_File_open( - stat.comm_, path.c_str(), stat.amode_, stat.info_, &stat.mpi_fh_); - } - } else { - f.mpi_status_ = real_api->MPI_File_open( - stat.comm_, path.c_str(), stat.amode_, stat.info_, &stat.mpi_fh_); - } - - if (f.mpi_status_ == MPI_SUCCESS) { - stat.hflags_.SetBits(HERMES_FS_EXISTS); - } - if (f.mpi_status_ != MPI_SUCCESS && - stat.adapter_mode_ != AdapterMode::kScratch) { - f.status_ = false; - }*/ -} - -/** - * Called after real open. Allocates the Hermes representation of - * identifying file information, such as a hermes file descriptor - * and hermes file handler. These are not the same as POSIX file - * descriptor and STDIO file handler. - * */ -void MpiioIoClient::HermesOpen(File &f, - const AdapterStat &stat, - FilesystemIoClientState &fs_mdm) { - // f.hermes_mpi_fh_ = (MPI_File)fs_mdm.stat_; - f.hermes_mpi_fh_ = stat.mpi_fh_; -} - -/** Synchronize \a file FILE f */ -int MpiioIoClient::RealSync(const File &f, - const AdapterStat &stat) { - return real_api->MPI_File_sync(stat.mpi_fh_); -} - -/** Close \a file FILE f */ -int MpiioIoClient::RealClose(const File &f, - AdapterStat &stat) { - return real_api->MPI_File_close(&stat.mpi_fh_); -} - -/** - * Called before RealClose. Releases information provisioned during - * the allocation phase. - * */ -void MpiioIoClient::HermesClose(File &f, - const AdapterStat &stat, - FilesystemIoClientState &fs_mdm) { - (void) f; (void) stat; (void) fs_mdm; -} - -/** Remove \a file FILE f */ -int MpiioIoClient::RealRemove(const std::string &path) { - return remove(path.c_str()); -} - -/** Get initial statistics from the backend */ -size_t MpiioIoClient::GetSize(const hipc::charbuf &bkt_name) { - size_t true_size = 0; - std::string filename = bkt_name.str(); - int fd = open(filename.c_str(), O_RDONLY); - if (fd < 0) { return 0; } - struct stat buf; - fstat(fd, &buf); - true_size = buf.st_size; - close(fd); - - HILOG(kDebug, "The size of the file {} on disk is {} bytes", - filename, true_size) - return true_size; -} - -/** Initialize I/O context using count + datatype */ -size_t MpiioIoClient::IoSizeFromCount(int count, - MPI_Datatype datatype, - FsIoOptions &opts) { - int datatype_size; - opts.mpi_type_ = datatype; - opts.mpi_count_ = count; - MPI_Type_size(datatype, &datatype_size); - return static_cast(count * datatype_size); -} - -/** Write blob to backend */ -void MpiioIoClient::WriteBlob(const std::string &bkt_name, - const Blob &full_blob, - const FsIoOptions &opts, - IoStatus &status) { - status.success_ = true; - HILOG(kDebug, - "Write called for: {}" - " on offset: {}" - " and size: {}", - bkt_name, opts.backend_off_, full_blob.size()) - MPI_File fh; - int write_count = 0; - status.mpi_ret_ = real_api->MPI_File_open(MPI_COMM_SELF, bkt_name.c_str(), - MPI_MODE_RDONLY, - MPI_INFO_NULL, &fh); - if (status.mpi_ret_ != MPI_SUCCESS) { - status.success_ = false; - return; - } - - status.mpi_ret_ = real_api->MPI_File_seek(fh, opts.backend_off_, - MPI_SEEK_SET); - if (status.mpi_ret_ != MPI_SUCCESS) { - status.success_ = false; - goto ERROR; - } - status.mpi_ret_ = real_api->MPI_File_write(fh, - full_blob.data(), - opts.mpi_count_, - opts.mpi_type_, - status.mpi_status_ptr_); - MPI_Get_count(status.mpi_status_ptr_, - opts.mpi_type_, &write_count); - if (write_count != opts.mpi_count_) { - status.success_ = false; - HELOG(kError, "writing failed: wrote {} / {}", - write_count, opts.mpi_count_) - } - -ERROR: - real_api->MPI_File_close(&fh); - status.size_ = full_blob.size(); - UpdateIoStatus(opts.mpi_count_, status); -} - -/** Read blob from the backend */ -void MpiioIoClient::ReadBlob(const std::string &bkt_name, - Blob &full_blob, - const FsIoOptions &opts, - IoStatus &status) { - status.success_ = true; - HILOG(kDebug, - "Reading from: {}" - " on offset: {}" - " and size: {}", - bkt_name, opts.backend_off_, full_blob.size()) - MPI_File fh; - int read_count = 0; - status.mpi_ret_ = real_api->MPI_File_open(MPI_COMM_SELF, bkt_name.c_str(), - MPI_MODE_RDONLY, MPI_INFO_NULL, - &fh); - if (status.mpi_ret_ != MPI_SUCCESS) { - status.success_ = false; - return; - } - - status.mpi_ret_ = real_api->MPI_File_seek(fh, opts.backend_off_, - MPI_SEEK_SET); - if (status.mpi_ret_ != MPI_SUCCESS) { - status.success_ = false; - goto ERROR; - } - status.mpi_ret_ = real_api->MPI_File_read(fh, - full_blob.data(), - opts.mpi_count_, - opts.mpi_type_, - status.mpi_status_ptr_); - MPI_Get_count(status.mpi_status_ptr_, - opts.mpi_type_, &read_count); - if (read_count != opts.mpi_count_) { - status.success_ = false; - HELOG(kError, "reading failed: read {} / {}", - read_count, opts.mpi_count_) - } - -ERROR: - real_api->MPI_File_close(&fh); - status.size_ = full_blob.size(); - UpdateIoStatus(opts.mpi_count_, status); -} - -/** Update the I/O status after a ReadBlob or WriteBlob */ -void MpiioIoClient::UpdateIoStatus(size_t count, IoStatus &status) { -#ifdef HERMES_OPENMPI - status.mpi_status_ptr_->_cancelled = 0; - status.mpi_status_ptr_->_ucount = count; -#elif defined(HERMES_MPICH) - status.mpi_status_ptr_->count_hi_and_cancelled = 0; - status.mpi_status_ptr_->count_lo = count; -#else -#error "No MPI implementation specified for MPIIO adapter" -#endif -} - -} // namespace hermes::adapter::fs diff --git a/hermes_adapters/mpiio/mpiio_io_client.h b/hermes_adapters/mpiio/mpiio_io_client.h deleted file mode 100644 index e9f7dd2b3..000000000 --- a/hermes_adapters/mpiio/mpiio_io_client.h +++ /dev/null @@ -1,108 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef HERMES_ADAPTER_MPIIO_MPIIO_IO_CLIENT_H_ -#define HERMES_ADAPTER_MPIIO_MPIIO_IO_CLIENT_H_ - -#include - -#include "hermes_adapters/filesystem/filesystem_io_client.h" -#include "mpiio_api.h" - -using hermes::adapter::fs::AdapterStat; -using hermes::adapter::fs::FsIoOptions; -using hermes::adapter::fs::IoStatus; -using hermes::adapter::fs::MpiioApi; - -namespace hermes::adapter::fs { - -/** A class to represent STDIO IO file system */ -class MpiioIoClient : public hermes::adapter::fs::FilesystemIoClient { - private: - HERMES_MPIIO_API_T real_api; /**< pointer to real APIs */ - - public: - /** Default constructor */ - MpiioIoClient() { - real_api = HERMES_MPIIO_API; - } - - /** Virtual destructor */ - virtual ~MpiioIoClient() = default; - - public: - /** Allocate an fd for the file f */ - void RealOpen(File &f, - AdapterStat &stat, - const std::string &path) override; - - /** - * Called after real open. Allocates the Hermes representation of - * identifying file information, such as a hermes file descriptor - * and hermes file handler. These are not the same as STDIO file - * descriptor and STDIO file handler. - * */ - void HermesOpen(File &f, - const AdapterStat &stat, - FilesystemIoClientState &fs_mdm) override; - - /** Synchronize \a file FILE f */ - int RealSync(const File &f, - const AdapterStat &stat) override; - - /** Close \a file FILE f */ - int RealClose(const File &f, - AdapterStat &stat) override; - - /** - * Called before RealClose. Releases information provisioned during - * the allocation phase. - * */ - void HermesClose(File &f, - const AdapterStat &stat, - FilesystemIoClientState &fs_mdm) override; - - /** Remove \a file FILE f */ - int RealRemove(const std::string &path) override; - - /** Get initial statistics from the backend */ - size_t GetSize(const hipc::charbuf &bkt_name) override; - - /** Initialize I/O context using count + datatype */ - static size_t IoSizeFromCount(int count, - MPI_Datatype datatype, - FsIoOptions &opts); - - /** Write blob to backend */ - void WriteBlob(const std::string &bkt_name, - const Blob &full_blob, - const FsIoOptions &opts, - IoStatus &status) override; - - /** Read blob from the backend */ - void ReadBlob(const std::string &bkt_name, - Blob &full_blob, - const FsIoOptions &opts, - IoStatus &status) override; - - /** Update the I/O status after a ReadBlob or WriteBlob */ - void UpdateIoStatus(size_t count, IoStatus &status); -}; - -} // namespace hermes::adapter::fs - -/** Simplify access to the stateless StdioIoClient Singleton */ -#define HERMES_MPIIO_IO_CLIENT \ - hshm::EasySingleton<::hermes::adapter::fs::MpiioIoClient>::GetInstance() -#define HERMES_MPIIO_IO_CLIENT_T hermes::adapter::fs::MpiioIoClient* - -#endif // HERMES_ADAPTER_MPIIO_MPIIO_IO_CLIENT_H_ diff --git a/hermes_adapters/posix/CMakeLists.txt b/hermes_adapters/posix/CMakeLists.txt index bcc973f3c..c0e412a99 100644 --- a/hermes_adapters/posix/CMakeLists.txt +++ b/hermes_adapters/posix/CMakeLists.txt @@ -5,29 +5,19 @@ include_directories( ${HERMES_IO_CLIENT_DIR} .) -# Creates the POSIX I/O client -add_library(hermes_posix_io_client SHARED posix_io_client.cc) -add_dependencies(hermes_posix_io_client - hermes hermes_fs_base) -target_link_libraries(hermes_posix_io_client - hermes hermes_fs_base - MPI::MPI_CXX stdc++fs dl) - # Create the POSIX interceptor set(INTERCEPTOR_DEPS - hermes - hermes_posix_io_client) + hermes hermes_fs_base) add_library(hermes_posix SHARED ${CMAKE_CURRENT_SOURCE_DIR}/posix_api.cc) add_dependencies(hermes_posix ${INTERCEPTOR_DEPS}) -target_link_libraries(hermes_posix ${INTERCEPTOR_DEPS}) +target_link_libraries(hermes_posix MPI::MPI_CXX stdc++fs dl ${INTERCEPTOR_DEPS}) #----------------------------------------------------------------------------- # Add Target(s) to CMake Install #----------------------------------------------------------------------------- install( TARGETS - hermes_posix_io_client hermes_posix EXPORT ${HERMES_EXPORTED_TARGETS} @@ -40,7 +30,6 @@ install( # Export all exported targets to the build tree for use by parent project #----------------------------------------------------------------------------- set(HERMES_EXPORTED_LIBS - hermes_posix_io_client hermes_posix ${HERMES_EXPORTED_LIBS}) if(NOT HERMES_EXTERNALLY_CONFIGURED) @@ -69,6 +58,5 @@ install( # Add Target(s) to Coverage #----------------------------------------------------------------------------- if(HERMES_ENABLE_COVERAGE) - set_coverage_flags(hermes_posix_io_client) - #set_coverage_flags(hermes_posix) + set_coverage_flags(hermes_posix) endif() diff --git a/hermes_adapters/posix/posix_api.cc b/hermes_adapters/posix/posix_api.cc index 2360ced2e..a6cc7836f 100644 --- a/hermes_adapters/posix/posix_api.cc +++ b/hermes_adapters/posix/posix_api.cc @@ -21,16 +21,17 @@ bool posix_intercepted = true; #include "hermes/hermes_types.h" #include "hermes_shm/util/singleton.h" -#include "hermes_adapters/interceptor.h" #include "posix_api.h" #include "posix_fs_api.h" #include "hermes_adapters/filesystem/filesystem.h" -using hermes::adapter::fs::AdapterStat; -using hermes::adapter::fs::IoStatus; -using hermes::adapter::fs::File; -using hermes::adapter::fs::SeekMode; +using hermes::adapter::MetadataManager; +using hermes::adapter::SeekMode; +using hermes::adapter::AdapterStat; +using hermes::adapter::File; +using hermes::adapter::IoStatus; +using hermes::adapter::FsIoOptions; namespace stdfs = std::filesystem; diff --git a/hermes_adapters/posix/posix_api.h b/hermes_adapters/posix/posix_api.h index 8bd62f133..9b8e44b66 100644 --- a/hermes_adapters/posix/posix_api.h +++ b/hermes_adapters/posix/posix_api.h @@ -89,8 +89,7 @@ typedef int (*remove_t)(const char *pathname); typedef int (*unlink_t)(const char *pathname); } -namespace hermes::adapter::fs { - +namespace hermes::adapter { /** Used for compatability with older kernel versions */ static int fxstat_to_fstat(int fd, struct stat * stbuf); @@ -225,22 +224,22 @@ class PosixApi : public RealApi { } }; -} // namespace hermes::adapter::fs +} // namespace hermes::adapter // Singleton macros #include "hermes_shm/util/singleton.h" #define HERMES_POSIX_API \ - hshm::EasySingleton<::hermes::adapter::fs::PosixApi>::GetInstance() -#define HERMES_POSIX_API_T hermes::adapter::fs::PosixApi* + hshm::EasySingleton<::hermes::adapter::PosixApi>::GetInstance() +#define HERMES_POSIX_API_T hermes::adapter::PosixApi* -namespace hermes::adapter::fs { +namespace hermes::adapter { /** Used for compatability with older kernel versions */ static int fxstat_to_fstat(int fd, struct stat *stbuf) { #ifdef _STAT_VER return HERMES_POSIX_API->__fxstat(_STAT_VER, fd, stbuf); #endif } -} // namespace hermes::adapter::fs +} // namespace hermes::adapter #endif // HERMES_ADAPTER_POSIX_H diff --git a/hermes_adapters/posix/posix_fs_api.h b/hermes_adapters/posix/posix_fs_api.h index 77ed16c94..89f20d1db 100644 --- a/hermes_adapters/posix/posix_fs_api.h +++ b/hermes_adapters/posix/posix_fs_api.h @@ -18,15 +18,18 @@ #include "hermes_adapters/filesystem/filesystem.h" #include "hermes_adapters/filesystem/filesystem_mdm.h" #include "posix_api.h" -#include "posix_io_client.h" -namespace hermes::adapter::fs { +namespace hermes::adapter { /** A class to represent POSIX IO file system */ -class PosixFs : public hermes::adapter::fs::Filesystem { +class PosixFs : public hermes::adapter::Filesystem { public: - PosixFs() : hermes::adapter::fs::Filesystem(HERMES_POSIX_IO_CLIENT, - AdapterType::kPosix) {} + HERMES_POSIX_API_T real_api_; /**< pointer to real APIs */ + + public: + PosixFs() : Filesystem(AdapterType::kPosix) { + real_api_ = HERMES_POSIX_API; + } template int Stat(File &f, StatT *buf) { @@ -80,7 +83,7 @@ class PosixFs : public hermes::adapter::fs::Filesystem { if (!HERMES->IsInitialized() || fd < 8192) { return false; } - hermes::adapter::fs::File f; + hermes::adapter::File f; f.hermes_fd_ = fd; stat = HERMES_FS_METADATA_MANAGER->Find(f); return stat != nullptr; @@ -100,13 +103,168 @@ class PosixFs : public hermes::adapter::fs::Filesystem { size_t r = readlink(proclnk.data(), filename.data(), kMaxPathLen); return std::string(filename.data(), r); } + + public: + /** Allocate an fd for the file f */ + void RealOpen(File &f, + AdapterStat &stat, + const std::string &path) override { + if (stat.flags_ & O_APPEND) { + stat.hflags_.SetBits(HERMES_FS_APPEND); + } + if (stat.flags_ & O_CREAT || stat.flags_ & O_TMPFILE) { + stat.hflags_.SetBits(HERMES_FS_CREATE); + } + if (stat.flags_ & O_TRUNC) { + stat.hflags_.SetBits(HERMES_FS_TRUNC); + } + + if (stat.hflags_.Any(HERMES_FS_CREATE)) { + if (stat.adapter_mode_ != AdapterMode::kScratch) { + stat.fd_ = real_api_->open(path.c_str(), stat.flags_, stat.st_mode_); + } + } else { + stat.fd_ = real_api_->open(path.c_str(), stat.flags_); + } + + if (stat.fd_ >= 0) { + stat.hflags_.SetBits(HERMES_FS_EXISTS); + } + if (stat.fd_ < 0 && stat.adapter_mode_ != AdapterMode::kScratch) { + f.status_ = false; + } + } + + /** + * Called after real open. Allocates the Hermes representation of + * identifying file information, such as a hermes file descriptor + * and hermes file handler. These are not the same as POSIX file + * descriptor and STDIO file handler. + * */ + void HermesOpen(File &f, + const AdapterStat &stat, + FilesystemIoClientState &fs_mdm) override { + f.hermes_fd_ = fs_mdm.mdm_->AllocateFd(); + } + + /** Synchronize \a file FILE f */ + int RealSync(const File &f, + const AdapterStat &stat) override { + (void) f; + if (stat.adapter_mode_ == AdapterMode::kScratch && + stat.fd_ == -1) { + return 0; + } + return real_api_->fsync(stat.fd_); + } + + /** Close \a file FILE f */ + int RealClose(const File &f, + AdapterStat &stat) override { + (void) f; + if (stat.adapter_mode_ == AdapterMode::kScratch && + stat.fd_ == -1) { + return 0; + } + return real_api_->close(stat.fd_); + } + + /** + * Called before RealClose. Releases information provisioned during + * the allocation phase. + * */ + void HermesClose(File &f, + const AdapterStat &stat, + FilesystemIoClientState &fs_mdm) override { + fs_mdm.mdm_->ReleaseFd(f.hermes_fd_); + } + + /** Remove \a file FILE f */ + int RealRemove(const std::string &path) override { + return real_api_->remove(path.c_str()); + } + + /** Get initial statistics from the backend */ + size_t GetBackendSize(const hipc::charbuf &bkt_name) override { + size_t true_size = 0; + std::string filename = bkt_name.str(); + int fd = real_api_->open(filename.c_str(), O_RDONLY); + if (fd < 0) { return 0; } + struct stat buf; + real_api_->fstat(fd, &buf); + true_size = buf.st_size; + real_api_->close(fd); + + HILOG(kDebug, "The size of the file {} on disk is {}", + filename, true_size) + return true_size; + } + + /** Write blob to backend */ + void WriteBlob(const std::string &bkt_name, + const Blob &full_blob, + const FsIoOptions &opts, + IoStatus &status) override { + (void) opts; + status.success_ = true; + HILOG(kDebug, "Writing to file: {}" + " offset: {}" + " size: {}", + bkt_name, opts.backend_off_, full_blob.size()) + int fd = real_api_->open(bkt_name.c_str(), O_RDWR | O_CREAT); + if (fd < 0) { + status.size_ = 0; + status.success_ = false; + return; + } + status.size_ = real_api_->pwrite(fd, + full_blob.data(), + full_blob.size(), + opts.backend_off_); + if (status.size_ != full_blob.size()) { + status.success_ = false; + } + real_api_->close(fd); + } + + /** Read blob from the backend */ + void ReadBlob(const std::string &bkt_name, + Blob &full_blob, + const FsIoOptions &opts, + IoStatus &status) override { + (void) opts; + status.success_ = true; + HILOG(kDebug, "Reading from file: {}" + " offset: {}" + " size: {}", + bkt_name, opts.backend_off_, full_blob.size()) + int fd = real_api_->open(bkt_name.c_str(), O_RDONLY); + if (fd < 0) { + status.size_ = 0; + status.success_ = false; + return; + } + status.size_ = real_api_->pread(fd, + full_blob.data(), + full_blob.size(), + opts.backend_off_); + if (status.size_ != full_blob.size()) { + status.success_ = false; + } + real_api_->close(fd); + } + + void UpdateIoStatus(const FsIoOptions &opts, IoStatus &status) override { + (void) opts; + (void) status; + } }; /** Simplify access to the stateless PosixFs Singleton */ #define HERMES_POSIX_FS \ - hshm::EasySingleton<::hermes::adapter::fs::PosixFs>::GetInstance() -#define HERMES_POSIX_FS_T hermes::adapter::fs::PosixFs* + hshm::EasySingleton<::hermes::adapter::PosixFs>::GetInstance() +#define HERMES_POSIX_FS_T hermes::adapter::PosixFs* -} // namespace hermes::adapter::fs +} // namespace hermes::adapter #endif // HERMES_ADAPTER_POSIX_NATIVE_H_ diff --git a/hermes_adapters/posix/posix_io_client.cc b/hermes_adapters/posix/posix_io_client.cc deleted file mode 100644 index 5fecbaef5..000000000 --- a/hermes_adapters/posix/posix_io_client.cc +++ /dev/null @@ -1,167 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include "posix_io_client.h" - -namespace hermes::adapter::fs { - -/** Allocate an fd for the file f */ -void PosixIoClient::RealOpen(File &f, - AdapterStat &stat, - const std::string &path) { - if (stat.flags_ & O_APPEND) { - stat.hflags_.SetBits(HERMES_FS_APPEND); - } - if (stat.flags_ & O_CREAT || stat.flags_ & O_TMPFILE) { - stat.hflags_.SetBits(HERMES_FS_CREATE); - } - if (stat.flags_ & O_TRUNC) { - stat.hflags_.SetBits(HERMES_FS_TRUNC); - } - - if (stat.hflags_.Any(HERMES_FS_CREATE)) { - if (stat.adapter_mode_ != AdapterMode::kScratch) { - stat.fd_ = real_api->open(path.c_str(), stat.flags_, stat.st_mode_); - } - } else { - stat.fd_ = real_api->open(path.c_str(), stat.flags_); - } - - if (stat.fd_ >= 0) { - stat.hflags_.SetBits(HERMES_FS_EXISTS); - } - if (stat.fd_ < 0 && stat.adapter_mode_ != AdapterMode::kScratch) { - f.status_ = false; - } -} - -/** - * Called after real open. Allocates the Hermes representation of - * identifying file information, such as a hermes file descriptor - * and hermes file handler. These are not the same as POSIX file - * descriptor and STDIO file handler. - * */ -void PosixIoClient::HermesOpen(File &f, - const AdapterStat &stat, - FilesystemIoClientState &fs_mdm) { - f.hermes_fd_ = fs_mdm.mdm_->AllocateFd(); -} - -/** Synchronize \a file FILE f */ -int PosixIoClient::RealSync(const File &f, - const AdapterStat &stat) { - (void) f; - if (stat.adapter_mode_ == AdapterMode::kScratch && - stat.fd_ == -1) { - return 0; - } - return real_api->fsync(stat.fd_); -} - -/** Close \a file FILE f */ -int PosixIoClient::RealClose(const File &f, - AdapterStat &stat) { - (void) f; - if (stat.adapter_mode_ == AdapterMode::kScratch && - stat.fd_ == -1) { - return 0; - } - return real_api->close(stat.fd_); -} - -/** - * Called before RealClose. Releases information provisioned during - * the allocation phase. - * */ -void PosixIoClient::HermesClose(File &f, - const AdapterStat &stat, - FilesystemIoClientState &fs_mdm) { - fs_mdm.mdm_->ReleaseFd(f.hermes_fd_); -} - -/** Remo - * ve \a file FILE f */ -int PosixIoClient::RealRemove(const std::string &path) { - return real_api->remove(path.c_str()); -} - -/** Get initial statistics from the backend */ -size_t PosixIoClient::GetSize(const hipc::charbuf &bkt_name) { - size_t true_size = 0; - std::string filename = bkt_name.str(); - int fd = real_api->open(filename.c_str(), O_RDONLY); - if (fd < 0) { return 0; } - struct stat buf; - real_api->fstat(fd, &buf); - true_size = buf.st_size; - real_api->close(fd); - - HILOG(kDebug, "The size of the file {} on disk is {}", - filename, true_size) - return true_size; -} - -/** Write blob to backend */ -void PosixIoClient::WriteBlob(const std::string &bkt_name, - const Blob &full_blob, - const FsIoOptions &opts, - IoStatus &status) { - (void) opts; - status.success_ = true; - HILOG(kDebug, "Writing to file: {}" - " offset: {}" - " size: {}", - bkt_name, opts.backend_off_, full_blob.size()) - int fd = real_api->open(bkt_name.c_str(), O_RDWR | O_CREAT); - if (fd < 0) { - status.size_ = 0; - status.success_ = false; - return; - } - status.size_ = real_api->pwrite(fd, - full_blob.data(), - full_blob.size(), - opts.backend_off_); - if (status.size_ != full_blob.size()) { - status.success_ = false; - } - real_api->close(fd); -} - -/** Read blob from the backend */ -void PosixIoClient::ReadBlob(const std::string &bkt_name, - Blob &full_blob, - const FsIoOptions &opts, - IoStatus &status) { - (void) opts; - status.success_ = true; - HILOG(kDebug, "Reading from file: {}" - " offset: {}" - " size: {}", - bkt_name, opts.backend_off_, full_blob.size()) - int fd = real_api->open(bkt_name.c_str(), O_RDONLY); - if (fd < 0) { - status.size_ = 0; - status.success_ = false; - return; - } - status.size_ = real_api->pread(fd, - full_blob.data(), - full_blob.size(), - opts.backend_off_); - if (status.size_ != full_blob.size()) { - status.success_ = false; - } - real_api->close(fd); -} - -} // namespace hermes::adapter::fs diff --git a/hermes_adapters/posix/posix_io_client.h b/hermes_adapters/posix/posix_io_client.h deleted file mode 100644 index 907443144..000000000 --- a/hermes_adapters/posix/posix_io_client.h +++ /dev/null @@ -1,101 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef HERMES_ADAPTER_POSIX_POSIX_IO_CLIENT_H_ -#define HERMES_ADAPTER_POSIX_POSIX_IO_CLIENT_H_ - -#include - -#include "hermes_adapters/filesystem/filesystem_io_client.h" -#include "posix_api.h" - -using hshm::Singleton; -using hermes::adapter::fs::AdapterStat; -using hermes::adapter::fs::FsIoOptions; -using hermes::adapter::fs::IoStatus; -using hermes::adapter::fs::PosixApi; - -namespace hermes::adapter::fs { - -/** A class to represent POSIX IO file system */ -class PosixIoClient : public hermes::adapter::fs::FilesystemIoClient { - private: - HERMES_POSIX_API_T real_api; /**< pointer to real APIs */ - - public: - /** Default constructor */ - PosixIoClient() { - real_api = HERMES_POSIX_API; - } - - /** Virtual destructor */ - virtual ~PosixIoClient() = default; - - public: - /** Allocate an fd for the file f */ - void RealOpen(File &f, - AdapterStat &stat, - const std::string &path) override; - - /** - * Called after real open. Allocates the Hermes representation of - * identifying file information, such as a hermes file descriptor - * and hermes file handler. These are not the same as POSIX file - * descriptor and STDIO file handler. - * */ - void HermesOpen(File &f, - const AdapterStat &stat, - FilesystemIoClientState &fs_mdm) override; - - /** Synchronize \a file FILE f */ - int RealSync(const File &f, - const AdapterStat &stat) override; - - /** Close \a file FILE f */ - int RealClose(const File &f, - AdapterStat &stat) override; - - /** - * Called before RealClose. Releases information provisioned during - * the allocation phase. - * */ - void HermesClose(File &f, - const AdapterStat &stat, - FilesystemIoClientState &fs_mdm) override; - - /** Remove \a file FILE f */ - int RealRemove(const std::string &path) override; - - /** Get initial statistics from the backend */ - size_t GetSize(const hipc::charbuf &bkt_name) override; - - /** Write blob to backend */ - void WriteBlob(const std::string &bkt_name, - const Blob &full_blob, - const FsIoOptions &opts, - IoStatus &status) override; - - /** Read blob from the backend */ - void ReadBlob(const std::string &bkt_name, - Blob &full_blob, - const FsIoOptions &opts, - IoStatus &status) override; -}; - -} // namespace hermes::adapter::fs - -/** Simplify access to the stateless PosixIoClient Singleton */ -#define HERMES_POSIX_IO_CLIENT \ - hshm::EasySingleton<::hermes::adapter::fs::PosixIoClient>::GetInstance() -#define HERMES_POSIX_IO_CLIENT_T hermes::adapter::fs::PosixIoClient* - -#endif // HERMES_ADAPTER_POSIX_POSIX_IO_CLIENT_H_ diff --git a/hermes_adapters/real_api.h b/hermes_adapters/real_api.h index ca1691bef..9aba4cb40 100644 --- a/hermes_adapters/real_api.h +++ b/hermes_adapters/real_api.h @@ -16,6 +16,10 @@ #include #include +namespace stdfs = std::filesystem; + +#define HERMES_DECL(F) F + #define REQUIRE_API(api_name) \ if (!(api_name)) { \ HELOG(kFatal, "HERMES Adapter failed to map symbol: {}", #api_name); \ diff --git a/hermes_adapters/stdio/CMakeLists.txt b/hermes_adapters/stdio/CMakeLists.txt index a2da0baf1..da729b02c 100644 --- a/hermes_adapters/stdio/CMakeLists.txt +++ b/hermes_adapters/stdio/CMakeLists.txt @@ -5,29 +5,19 @@ include_directories( ${HERMES_IO_CLIENT_DIR} .) -# Creates the STDIO I/O client -add_library(hermes_stdio_io_client SHARED stdio_io_client.cc) -add_dependencies(hermes_stdio_io_client - hermes hermes_fs_base) -target_link_libraries(hermes_stdio_io_client - hermes hermes_fs_base - MPI::MPI_CXX stdc++fs dl) - # Create the STDIO interceptor set(INTERCEPTOR_DEPS - hermes - hermes_stdio_io_client) + hermes hermes_fs_base) add_library(hermes_stdio SHARED ${CMAKE_CURRENT_SOURCE_DIR}/stdio_api.cc) add_dependencies(hermes_stdio ${INTERCEPTOR_DEPS}) -target_link_libraries(hermes_stdio ${INTERCEPTOR_DEPS}) +target_link_libraries(hermes_stdio MPI::MPI_CXX stdc++fs dl ${INTERCEPTOR_DEPS}) #----------------------------------------------------------------------------- # Add Target(s) to CMake Install #----------------------------------------------------------------------------- install( TARGETS - hermes_stdio_io_client hermes_stdio EXPORT ${HERMES_EXPORTED_TARGETS} @@ -40,7 +30,6 @@ install( # Export all exported targets to the build tree for use by parent project #----------------------------------------------------------------------------- set(HERMES_EXPORTED_LIBS - hermes_stdio_io_client hermes_stdio ${HERMES_EXPORTED_LIBS}) if(NOT HERMES_EXTERNALLY_CONFIGURED) @@ -69,6 +58,5 @@ install( # Add Target(s) to Coverage #----------------------------------------------------------------------------- if(HERMES_ENABLE_COVERAGE) - set_coverage_flags(hermes_stdio_io_client) - #set_coverage_flags(hermes_stdio) + set_coverage_flags(hermes_stdio) endif() diff --git a/hermes_adapters/stdio/stdio_api.cc b/hermes_adapters/stdio/stdio_api.cc index b88d7ea03..50db93efa 100644 --- a/hermes_adapters/stdio/stdio_api.cc +++ b/hermes_adapters/stdio/stdio_api.cc @@ -17,12 +17,13 @@ bool stdio_intercepted = true; #include #include "stdio_api.h" #include "stdio_fs_api.h" -#include "hermes_adapters/interceptor.h" -using hermes::adapter::fs::MetadataManager; -using hermes::adapter::fs::SeekMode; -using hermes::adapter::fs::AdapterStat; -using hermes::adapter::fs::File; +using hermes::adapter::MetadataManager; +using hermes::adapter::SeekMode; +using hermes::adapter::AdapterStat; +using hermes::adapter::File; +using hermes::adapter::IoStatus; +using hermes::adapter::FsIoOptions; namespace stdfs = std::filesystem; diff --git a/hermes_adapters/stdio/stdio_api.h b/hermes_adapters/stdio/stdio_api.h index 12de1ad83..92c914675 100644 --- a/hermes_adapters/stdio/stdio_api.h +++ b/hermes_adapters/stdio/stdio_api.h @@ -48,7 +48,7 @@ typedef int (*fsetpos64_t)(FILE * stream, const fpos64_t * pos); typedef long int (*ftell_t)(FILE * fp); } -namespace hermes::adapter::fs { +namespace hermes::adapter { /** Pointers to the real stdio API */ class StdioApi : public RealApi { @@ -161,13 +161,13 @@ class StdioApi : public RealApi { REQUIRE_API(ftell) } }; -} // namespace hermes::adapter::fs +} // namespace hermes::adapter #include "hermes_shm/util/singleton.h" // Singleton macros #define HERMES_STDIO_API \ - hshm::EasySingleton<::hermes::adapter::fs::StdioApi>::GetInstance() -#define HERMES_STDIO_API_T hermes::adapter::fs::StdioApi* + hshm::EasySingleton<::hermes::adapter::StdioApi>::GetInstance() +#define HERMES_STDIO_API_T hermes::adapter::StdioApi* #endif // HERMES_ADAPTER_STDIO_H diff --git a/hermes_adapters/stdio/stdio_fs_api.h b/hermes_adapters/stdio/stdio_fs_api.h index 5fb5531f6..3d2c9b4fb 100644 --- a/hermes_adapters/stdio/stdio_fs_api.h +++ b/hermes_adapters/stdio/stdio_fs_api.h @@ -19,22 +19,25 @@ #include "hermes_adapters/filesystem/filesystem_mdm.h" #include "hermes_adapters/posix/posix_fs_api.h" #include "stdio_api.h" -#include "stdio_io_client.h" -namespace hermes::adapter::fs { +namespace hermes::adapter { /** A class to represent POSIX IO file system */ -class StdioFs : public hermes::adapter::fs::Filesystem { +class StdioFs : public hermes::adapter::Filesystem { public: - StdioFs() : hermes::adapter::fs::Filesystem(HERMES_STDIO_IO_CLIENT, - AdapterType::kStdio) {} + HERMES_STDIO_API_T real_api_; /**< pointer to real APIs */ + + public: + StdioFs() : Filesystem(AdapterType::kStdio) { + real_api_ = HERMES_STDIO_API; + } /** Close an existing stream and then open with new path */ FILE* Reopen(const std::string &user_path, const char *mode, AdapterStat &stat) { - auto real_api = HERMES_STDIO_API; + auto real_api_ = HERMES_STDIO_API; FILE *ret; - ret = real_api->freopen(user_path.c_str(), mode, stat.fh_); + ret = real_api_->freopen(user_path.c_str(), mode, stat.fh_); if (!ret) { return ret; } @@ -48,9 +51,9 @@ class StdioFs : public hermes::adapter::fs::Filesystem { /** fdopen */ FILE* FdOpen(const std::string &mode, std::shared_ptr &stat) { - auto real_api = HERMES_STDIO_API; + auto real_api_ = HERMES_STDIO_API; auto mdm = HERMES_FS_METADATA_MANAGER; - stat->fh_ = real_api->fdopen(stat->fd_, mode.c_str()); + stat->fh_ = real_api_->fdopen(stat->fd_, mode.c_str()); stat->mode_str_ = mode; File f; f.hermes_fh_ = (FILE*)stat.get(); mdm->Create(f, stat); @@ -72,7 +75,7 @@ class StdioFs : public hermes::adapter::fs::Filesystem { if (!fp || !HERMES->IsInitialized()) { return false; } - hermes::adapter::fs::File f; + hermes::adapter::File f; f.hermes_fh_ = fp; stat = HERMES_FS_METADATA_MANAGER->Find(f); return stat != nullptr; @@ -94,13 +97,166 @@ class StdioFs : public hermes::adapter::fs::Filesystem { filename[r] = '\0'; return filename; } + + public: + /** Allocate an fd for the file f */ + void RealOpen(File &f, + AdapterStat &stat, + const std::string &path) override { + if (stat.mode_str_.find('w') != std::string::npos) { + stat.hflags_.SetBits(HERMES_FS_TRUNC); + stat.hflags_.SetBits(HERMES_FS_CREATE); + } + if (stat.mode_str_.find('a') != std::string::npos) { + stat.hflags_.SetBits(HERMES_FS_APPEND); + stat.hflags_.SetBits(HERMES_FS_CREATE); + } + + if (stat.hflags_.Any(HERMES_FS_CREATE)) { + if (stat.adapter_mode_ != AdapterMode::kScratch) { + stat.fh_ = real_api_->fopen(path.c_str(), stat.mode_str_.c_str()); + } + } else { + stat.fh_ = real_api_->fopen(path.c_str(), stat.mode_str_.c_str()); + } + + if (stat.fh_ != nullptr) { + stat.hflags_.SetBits(HERMES_FS_EXISTS); + } + if (stat.fh_ == nullptr && stat.adapter_mode_ != AdapterMode::kScratch) { + f.status_ = false; + } + } + + /** + * Called after real open. Allocates the Hermes representation of + * identifying file information, such as a hermes file descriptor + * and hermes file handler. These are not the same as STDIO file + * descriptor and STDIO file handler. + * */ + void HermesOpen(File &f, + const AdapterStat &stat, + FilesystemIoClientState &fs_mdm) override { + f.hermes_fh_ = (FILE*)fs_mdm.stat_; + } + + /** Synchronize \a file FILE f */ + int RealSync(const File &f, + const AdapterStat &stat) override { + (void) f; + if (stat.adapter_mode_ == AdapterMode::kScratch && + stat.fh_ == nullptr) { + return 0; + } + return real_api_->fflush(stat.fh_); + } + + /** Close \a file FILE f */ + int RealClose(const File &f, + AdapterStat &stat) override { + if (stat.adapter_mode_ == AdapterMode::kScratch && + stat.fh_ == nullptr) { + return 0; + } + return real_api_->fclose(stat.fh_); + } + + /** + * Called before RealClose. Releases information provisioned during + * the allocation phase. + * */ + void HermesClose(File &f, + const AdapterStat &stat, + FilesystemIoClientState &fs_mdm) override { + (void) f; (void) stat; (void) fs_mdm; + } + + /** Remove \a file FILE f */ + int RealRemove(const std::string &path) override { + return remove(path.c_str()); + } + + /** Get initial statistics from the backend */ + size_t GetBackendSize(const hipc::charbuf &bkt_name) override { + size_t true_size = 0; + std::string filename = bkt_name.str(); + int fd = open(filename.c_str(), O_RDONLY); + if (fd < 0) { return 0; } + struct stat buf; + fstat(fd, &buf); + true_size = buf.st_size; + close(fd); + + HILOG(kDebug, "The size of the file {} on disk is {}", + filename, true_size) + return true_size; + } + + /** Write blob to backend */ + void WriteBlob(const std::string &bkt_name, + const Blob &full_blob, + const FsIoOptions &opts, + IoStatus &status) override { + status.success_ = true; + HILOG(kDebug, "Writing to file: {}" + " offset: {}" + " size: {}", + bkt_name, opts.backend_off_, full_blob.size()) + FILE *fh = real_api_->fopen(bkt_name.c_str(), "r+"); + if (fh == nullptr) { + status.size_ = 0; + status.success_ = false; + return; + } + real_api_->fseek(fh, opts.backend_off_, SEEK_SET); + status.size_ = real_api_->fwrite(full_blob.data(), + sizeof(char), + full_blob.size(), + fh); + if (status.size_ != full_blob.size()) { + status.success_ = false; + } + real_api_->fclose(fh); + } + + /** Read blob from the backend */ + void ReadBlob(const std::string &bkt_name, + Blob &full_blob, + const FsIoOptions &opts, + IoStatus &status) override { + status.success_ = true; + HILOG(kDebug, "Reading from file: {}" + " offset: {}" + " size: {}", + bkt_name, opts.backend_off_, full_blob.size()) + FILE *fh = real_api_->fopen(bkt_name.c_str(), "r"); + if (fh == nullptr) { + status.size_ = 0; + status.success_ = false; + return; + } + real_api_->fseek(fh, opts.backend_off_, SEEK_SET); + status.size_ = real_api_->fread(full_blob.data(), + sizeof(char), + full_blob.size(), + fh); + if (status.size_ != full_blob.size()) { + status.success_ = false; + } + real_api_->fclose(fh); + } + + void UpdateIoStatus(const FsIoOptions &opts, IoStatus &status) override { + (void) opts; + (void) status; + } }; /** Simplify access to the stateless StdioFs Singleton */ #define HERMES_STDIO_FS \ - hshm::EasySingleton<::hermes::adapter::fs::StdioFs>::GetInstance() -#define HERMES_STDIO_FS_T hermes::adapter::fs::StdioFs* + hshm::EasySingleton<::hermes::adapter::StdioFs>::GetInstance() +#define HERMES_STDIO_FS_T hermes::adapter::StdioFs* -} // namespace hermes::adapter::fs +} // namespace hermes::adapter #endif // HERMES_ADAPTER_STDIO_NATIVE_H_ diff --git a/hermes_adapters/stdio/stdio_io_client.cc b/hermes_adapters/stdio/stdio_io_client.cc deleted file mode 100644 index 6793115da..000000000 --- a/hermes_adapters/stdio/stdio_io_client.cc +++ /dev/null @@ -1,164 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include "stdio_io_client.h" - -namespace hermes::adapter::fs { - -/** Allocate an fd for the file f */ -void StdioIoClient::RealOpen(File &f, - AdapterStat &stat, - const std::string &path) { - if (stat.mode_str_.find('w') != std::string::npos) { - stat.hflags_.SetBits(HERMES_FS_TRUNC); - stat.hflags_.SetBits(HERMES_FS_CREATE); - } - if (stat.mode_str_.find('a') != std::string::npos) { - stat.hflags_.SetBits(HERMES_FS_APPEND); - stat.hflags_.SetBits(HERMES_FS_CREATE); - } - - if (stat.hflags_.Any(HERMES_FS_CREATE)) { - if (stat.adapter_mode_ != AdapterMode::kScratch) { - stat.fh_ = real_api->fopen(path.c_str(), stat.mode_str_.c_str()); - } - } else { - stat.fh_ = real_api->fopen(path.c_str(), stat.mode_str_.c_str()); - } - - if (stat.fh_ != nullptr) { - stat.hflags_.SetBits(HERMES_FS_EXISTS); - } - if (stat.fh_ == nullptr && stat.adapter_mode_ != AdapterMode::kScratch) { - f.status_ = false; - } -} - -/** - * Called after real open. Allocates the Hermes representation of - * identifying file information, such as a hermes file descriptor - * and hermes file handler. These are not the same as POSIX file - * descriptor and STDIO file handler. - * */ -void StdioIoClient::HermesOpen(File &f, - const AdapterStat &stat, - FilesystemIoClientState &fs_mdm) { - f.hermes_fh_ = (FILE*)fs_mdm.stat_; -} - -/** Synchronize \a file FILE f */ -int StdioIoClient::RealSync(const File &f, - const AdapterStat &stat) { - (void) f; - if (stat.adapter_mode_ == AdapterMode::kScratch && - stat.fh_ == nullptr) { - return 0; - } - return real_api->fflush(stat.fh_); -} - -/** Close \a file FILE f */ -int StdioIoClient::RealClose(const File &f, - AdapterStat &stat) { - if (stat.adapter_mode_ == AdapterMode::kScratch && - stat.fh_ == nullptr) { - return 0; - } - return real_api->fclose(stat.fh_); -} - -/** - * Called before RealClose. Releases information provisioned during - * the allocation phase. - * */ -void StdioIoClient::HermesClose(File &f, - const AdapterStat &stat, - FilesystemIoClientState &fs_mdm) { - (void) f; (void) stat; (void) fs_mdm; -} - -/** Remove \a file FILE f */ -int StdioIoClient::RealRemove(const std::string &path) { - return remove(path.c_str()); -} - -/** Get initial statistics from the backend */ -size_t StdioIoClient::GetSize(const hipc::charbuf &bkt_name) { - size_t true_size = 0; - std::string filename = bkt_name.str(); - int fd = open(filename.c_str(), O_RDONLY); - if (fd < 0) { return 0; } - struct stat buf; - fstat(fd, &buf); - true_size = buf.st_size; - close(fd); - - HILOG(kDebug, "The size of the file {} on disk is {}", - filename, true_size) - return true_size; -} - -/** Write blob to backend */ -void StdioIoClient::WriteBlob(const std::string &bkt_name, - const Blob &full_blob, - const FsIoOptions &opts, - IoStatus &status) { - status.success_ = true; - HILOG(kDebug, "Writing to file: {}" - " offset: {}" - " size: {}", - bkt_name, opts.backend_off_, full_blob.size()) - FILE *fh = real_api->fopen(bkt_name.c_str(), "r+"); - if (fh == nullptr) { - status.size_ = 0; - status.success_ = false; - return; - } - real_api->fseek(fh, opts.backend_off_, SEEK_SET); - status.size_ = real_api->fwrite(full_blob.data(), - sizeof(char), - full_blob.size(), - fh); - if (status.size_ != full_blob.size()) { - status.success_ = false; - } - real_api->fclose(fh); -} - -/** Read blob from the backend */ -void StdioIoClient::ReadBlob(const std::string &bkt_name, - Blob &full_blob, - const FsIoOptions &opts, - IoStatus &status) { - status.success_ = true; - HILOG(kDebug, "Reading from file: {}" - " offset: {}" - " size: {}", - bkt_name, opts.backend_off_, full_blob.size()) - FILE *fh = real_api->fopen(bkt_name.c_str(), "r"); - if (fh == nullptr) { - status.size_ = 0; - status.success_ = false; - return; - } - real_api->fseek(fh, opts.backend_off_, SEEK_SET); - status.size_ = real_api->fread(full_blob.data(), - sizeof(char), - full_blob.size(), - fh); - if (status.size_ != full_blob.size()) { - status.success_ = false; - } - real_api->fclose(fh); -} - -} // namespace hermes::adapter::fs diff --git a/hermes_adapters/stdio/stdio_io_client.h b/hermes_adapters/stdio/stdio_io_client.h deleted file mode 100644 index be5d2077c..000000000 --- a/hermes_adapters/stdio/stdio_io_client.h +++ /dev/null @@ -1,100 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef HERMES_ADAPTER_STDIO_STDIO_IO_CLIENT_H_ -#define HERMES_ADAPTER_STDIO_STDIO_IO_CLIENT_H_ - -#include - -#include "hermes_adapters/filesystem/filesystem_io_client.h" -#include "stdio_api.h" - -using hermes::adapter::fs::AdapterStat; -using hermes::adapter::fs::FsIoOptions; -using hermes::adapter::fs::IoStatus; -using hermes::adapter::fs::StdioApi; - -namespace hermes::adapter::fs { - -/** A class to represent STDIO IO file system */ -class StdioIoClient : public hermes::adapter::fs::FilesystemIoClient { - private: - HERMES_STDIO_API_T real_api; /**< pointer to real APIs */ - - public: - /** Default constructor */ - StdioIoClient() { - real_api = HERMES_STDIO_API; - } - - /** Virtual destructor */ - virtual ~StdioIoClient() = default; - - public: - /** Allocate an fd for the file f */ - void RealOpen(File &f, - AdapterStat &stat, - const std::string &path) override; - - /** - * Called after real open. Allocates the Hermes representation of - * identifying file information, such as a hermes file descriptor - * and hermes file handler. These are not the same as STDIO file - * descriptor and STDIO file handler. - * */ - void HermesOpen(File &f, - const AdapterStat &stat, - FilesystemIoClientState &fs_mdm) override; - - /** Synchronize \a file FILE f */ - int RealSync(const File &f, - const AdapterStat &stat) override; - - /** Close \a file FILE f */ - int RealClose(const File &f, - AdapterStat &stat) override; - - /** - * Called before RealClose. Releases information provisioned during - * the allocation phase. - * */ - void HermesClose(File &f, - const AdapterStat &stat, - FilesystemIoClientState &fs_mdm) override; - - /** Remove \a file FILE f */ - int RealRemove(const std::string &path) override; - - /** Get initial statistics from the backend */ - size_t GetSize(const hipc::charbuf &bkt_name) override; - - /** Write blob to backend */ - void WriteBlob(const std::string &bkt_name, - const Blob &full_blob, - const FsIoOptions &opts, - IoStatus &status) override; - - /** Read blob from the backend */ - void ReadBlob(const std::string &bkt_name, - Blob &full_blob, - const FsIoOptions &opts, - IoStatus &status) override; -}; - -} // namespace hermes::adapter::fs - -/** Simplify access to the stateless StdioIoClient Singleton */ -#define HERMES_STDIO_IO_CLIENT \ - hshm::EasySingleton<::hermes::adapter::fs::StdioIoClient>::GetInstance() -#define HERMES_STDIO_IO_CLIENT_T hermes::adapter::fs::StdioIoClient* - -#endif // HERMES_ADAPTER_STDIO_STDIO_IO_CLIENT_H_ diff --git a/hermes_adapters/vfd/CMakeLists.txt b/hermes_adapters/vfd/CMakeLists.txt index 6ac9e99cd..dd8d8bbaf 100644 --- a/hermes_adapters/vfd/CMakeLists.txt +++ b/hermes_adapters/vfd/CMakeLists.txt @@ -30,9 +30,9 @@ target_include_directories(hdf5_hermes_vfd SYSTEM PUBLIC ${HDF5_HERMES_VFD_EXT_INCLUDE_DEPENDENCIES} ) add_dependencies(hdf5_hermes_vfd - hermes hermes_posix_io_client) + hermes hermes_fs_base) target_link_libraries(hdf5_hermes_vfd - hermes hermes_posix_io_client + hermes hermes_fs_base MPI::MPI_CXX ${HDF5_HERMES_VFD_EXT_LIB_DEPENDENCIES}) @@ -42,8 +42,7 @@ set(HDF5_HERMES_VFD_EXPORTED_LIBS hdf5_hermes_vfd ${HDF5_HERMES_VFD_EXPORTED_LIB # Specify project header files to be installed #----------------------------------------------------------------------------- set(HDF5_HERMES_VFD_HEADERS - ${CMAKE_CURRENT_SOURCE_DIR}/H5FDhermes.h - ) + ${CMAKE_CURRENT_SOURCE_DIR}/H5FDhermes.h) #----------------------------------------------------------------------------- # Add file(s) to CMake Install diff --git a/hermes_adapters/vfd/H5FDhermes.cc b/hermes_adapters/vfd/H5FDhermes.cc index d8ad22a68..8734f8c45 100644 --- a/hermes_adapters/vfd/H5FDhermes.cc +++ b/hermes_adapters/vfd/H5FDhermes.cc @@ -39,7 +39,6 @@ #include "H5PLextern.h" #include "H5FDhermes.h" /* Hermes file driver */ -#include "hermes_adapters/posix/posix_io_client.h" #include "hermes_adapters/posix/posix_fs_api.h" /** @@ -60,8 +59,9 @@ hid_t H5FDhermes_err_class_g = H5I_INVALID_HID; #define OP_READ 1 #define OP_WRITE 2 -using hermes::adapter::fs::AdapterStat; -using hermes::adapter::fs::File; +using hermes::adapter::AdapterStat; +using hermes::adapter::File; +using hermes::adapter::IoStatus; /* POSIX I/O mode used as the third parameter to open/_open * when creating a new file (O_CREAT is set). */ diff --git a/hrun/include/hrun/api/hrun_client.h b/hrun/include/hrun/api/hrun_client.h index 2587f0d97..a9c199dbd 100644 --- a/hrun/include/hrun/api/hrun_client.h +++ b/hrun/include/hrun/api/hrun_client.h @@ -263,9 +263,9 @@ class Client : public ConfigurationManager { auto alloc = HERMES_MEMORY_MANAGER->GetAllocator(p.allocator_id_); alloc->Free(p); HILOG(kDebug, "Heap size (1) for {}/{}: {}", - p.allocator_id_.bits_.major_, - p.allocator_id_.bits_.minor_, - data_alloc_->GetCurrentlyAllocatedSize()); + alloc->GetId().bits_.major_, + alloc->GetId().bits_.minor_, + alloc->GetCurrentlyAllocatedSize()); } /** Free a buffer */ @@ -276,7 +276,7 @@ class Client : public ConfigurationManager { HILOG(kDebug, "Heap size (2) for {}/{}: {}", alloc->GetId().bits_.major_, alloc->GetId().bits_.minor_, - data_alloc_->GetCurrentlyAllocatedSize()); + alloc->GetCurrentlyAllocatedSize()); } /** Convert pointer to char* */ diff --git a/hrun/include/hrun/hrun_types.h b/hrun/include/hrun/hrun_types.h index 2e0952d9d..7ac5251fc 100644 --- a/hrun/include/hrun/hrun_types.h +++ b/hrun/include/hrun/hrun_types.h @@ -13,6 +13,14 @@ #ifndef HRUN_INCLUDE_HRUN_HRUN_TYPES_H_ #define HRUN_INCLUDE_HRUN_HRUN_TYPES_H_ +#include +#include +#include +#include +#include +#include +#include + #include #include #include diff --git a/hrun/include/hrun/network/local_serialize.h b/hrun/include/hrun/network/local_serialize.h index f0a870be9..2f950ac5a 100644 --- a/hrun/include/hrun/network/local_serialize.h +++ b/hrun/include/hrun/network/local_serialize.h @@ -26,6 +26,16 @@ class LocalSerialize { LocalSerialize(DataT &data) : data_(data) { data_.resize(0); } + LocalSerialize(DataT &data, bool) : data_(data) {} + + /** left shift operator */ + template + HSHM_ALWAYS_INLINE + LocalSerialize& operator<<(const UniqueId &obj) { + (*this) << obj.unique_; + (*this) << obj.node_id_; + return *this; + } /** left shift operator */ template @@ -36,10 +46,13 @@ class LocalSerialize { size_t off = data_.size(); data_.resize(off + size); memcpy(data_.data() + off, &obj, size); - } else if constexpr (std::is_same::value || std::is_same::value) { - size_t size = obj.size(); + } else if constexpr (std::is_same::value || + std::is_same::value) { + size_t size = sizeof(size_t) + obj.size(); size_t off = data_.size(); data_.resize(off + size); + memcpy(data_.data() + off, &size, sizeof(size_t)); + off += sizeof(size_t); memcpy(data_.data() + off, obj.data(), size); } else { throw std::runtime_error("Cannot serialize object"); @@ -59,6 +72,15 @@ class LocalDeserialize { cur_off_ = 0; } + /** right shift operator */ + template + HSHM_ALWAYS_INLINE + LocalDeserialize& operator<<(const UniqueId &obj) { + (*this) >> obj.unique_; + (*this) >> obj.node_id_; + return *this; + } + /** right shift operator */ template HSHM_ALWAYS_INLINE @@ -69,8 +91,11 @@ class LocalDeserialize { size = sizeof(T); memcpy(&obj, data_.data() + off, size); } else if constexpr (std::is_same::value || std::is_same::value) { - size = obj.size(); - memcpy(obj.data(), data_.data() + off, size); + memcpy(&size, data_.data() + off, sizeof(size_t)); + size_t str_size = size - sizeof(size_t); + off += sizeof(size_t); + obj.resize(str_size); + memcpy(obj.data(), data_.data() + off, str_size); } else { throw std::runtime_error("Cannot serialize object"); } diff --git a/hrun/include/hrun/network/serialize.h b/hrun/include/hrun/network/serialize.h index d775de7c8..1bd7c9d37 100644 --- a/hrun/include/hrun/network/serialize.h +++ b/hrun/include/hrun/network/serialize.h @@ -16,13 +16,6 @@ #include "hrun/hrun_types.h" #include "hrun/task_registry/task.h" #include -#include -#include -#include -#include -#include -#include -#include namespace hrun { diff --git a/hrun/include/hrun/queue_manager/queue.h b/hrun/include/hrun/queue_manager/queue.h index 2eef37c9f..0dcf40a06 100644 --- a/hrun/include/hrun/queue_manager/queue.h +++ b/hrun/include/hrun/queue_manager/queue.h @@ -30,59 +30,75 @@ /** Requests in this queue are long-running */ #define QUEUE_LONG_RUNNING BIT_OPT(u32, 5) /** Requests in this queue should not be scheduled on a traditional worker */ -#define QUEUE_DISABLED BIT_OPT(u32, 5) +#define QUEUE_DISABLED BIT_OPT(u32, 6) +/** This queue is tethered to another queue */ +#define QUEUE_TETHERED BIT_OPT(u32, 7) namespace hrun { /** Prioritization info needed to be set by client */ struct PriorityInfo { + u32 prio_; /**< Priority ID */ u32 max_lanes_; /**< Maximum number of lanes in the queue */ u32 num_lanes_; /**< Current number of lanes in use */ u32 depth_; /**< The maximum depth of individual lanes */ bitfield32_t flags_; /**< Scheduling hints for the queue */ + u32 tether_; /**< Lanes should be pinned to the same workers as the tether */ /** Default constructor */ PriorityInfo() = default; /** Emplace constructor */ - PriorityInfo(u32 num_lanes, u32 max_lanes, u32 depth, u32 flags) { + PriorityInfo(u32 prio, u32 num_lanes, u32 max_lanes, + u32 depth, u32 flags, u32 tether = 0) { + prio_ = prio; max_lanes_ = max_lanes; num_lanes_ = num_lanes; depth_ = depth; flags_ = bitfield32_t(flags); + tether_ = tether; } /** Emplace constructor */ - PriorityInfo(u32 num_lanes, u32 max_lanes, u32 depth, bitfield32_t flags) { + PriorityInfo(u32 prio, u32 num_lanes, u32 max_lanes, u32 depth, + bitfield32_t flags, u32 tether = 0) { + prio_ = prio; max_lanes_ = max_lanes; num_lanes_ = num_lanes; depth_ = depth; flags_ = flags; + tether_ = tether; } /** Copy constructor */ PriorityInfo(const PriorityInfo &priority) { + prio_ = priority.prio_; max_lanes_ = priority.max_lanes_; num_lanes_ = priority.num_lanes_; depth_ = priority.depth_; flags_ = priority.flags_; + tether_ = priority.tether_; } /** Move constructor */ PriorityInfo(PriorityInfo &&priority) noexcept { + prio_ = priority.prio_; max_lanes_ = priority.max_lanes_; num_lanes_ = priority.num_lanes_; depth_ = priority.depth_; flags_ = priority.flags_; + tether_ = priority.tether_; } /** Copy assignment operator */ PriorityInfo& operator=(const PriorityInfo &priority) { if (this != &priority) { + prio_ = priority.prio_; max_lanes_ = priority.max_lanes_; num_lanes_ = priority.num_lanes_; depth_ = priority.depth_; flags_ = priority.flags_; + tether_ = priority.tether_; } return *this; } @@ -90,10 +106,12 @@ struct PriorityInfo { /** Move assignment operator */ PriorityInfo& operator=(PriorityInfo &&priority) noexcept { if (this != &priority) { + prio_ = priority.prio_; max_lanes_ = priority.max_lanes_; num_lanes_ = priority.num_lanes_; depth_ = priority.depth_; flags_ = priority.flags_; + tether_ = priority.tether_; } return *this; } @@ -101,10 +119,12 @@ struct PriorityInfo { /** Serialize Priority Info */ template void serialize(Ar &ar) { + ar & prio_; ar & max_lanes_; ar & num_lanes_; ar & depth_; ar & flags_; + ar & tether_; } }; diff --git a/hrun/include/hrun/queue_manager/queue_manager_runtime.h b/hrun/include/hrun/queue_manager/queue_manager_runtime.h index faf674da6..f950649c3 100644 --- a/hrun/include/hrun/queue_manager/queue_manager_runtime.h +++ b/hrun/include/hrun/queue_manager/queue_manager_runtime.h @@ -56,13 +56,13 @@ class QueueManagerRuntime : public QueueManager { // Create the admin queue MultiQueue *queue; queue = CreateQueue(admin_queue_, { - {1, 1, qm.queue_depth_, QUEUE_UNORDERED} + {TaskPrio::kAdmin, 1, 1, qm.queue_depth_, QUEUE_UNORDERED} }); queue->flags_.SetBits(QUEUE_READY); queue = CreateQueue(process_queue_, { - {1, 1, qm.queue_depth_, QUEUE_UNORDERED}, - {1, 1, qm.queue_depth_, QUEUE_LONG_RUNNING}, - {qm.max_lanes_, qm.max_lanes_, qm.queue_depth_, QUEUE_LOW_LATENCY} + {TaskPrio::kAdmin, 1, 1, qm.queue_depth_, QUEUE_UNORDERED}, + {TaskPrio::kLongRunning, 1, 1, qm.queue_depth_, QUEUE_LONG_RUNNING}, + {TaskPrio::kLowLatency, qm.max_lanes_, qm.max_lanes_, qm.queue_depth_, QUEUE_LOW_LATENCY} }); queue->flags_.SetBits(QUEUE_READY); } diff --git a/hrun/include/hrun/queue_manager/queues/hshm_queue.h b/hrun/include/hrun/queue_manager/queues/hshm_queue.h index 61a23cfbb..907ce422d 100644 --- a/hrun/include/hrun/queue_manager/queues/hshm_queue.h +++ b/hrun/include/hrun/queue_manager/queues/hshm_queue.h @@ -12,9 +12,8 @@ namespace hrun { /** The data stored in a lane */ struct LaneData { - hipc::Pointer p_; - bool complete_; - ABT_thread thread_; + hipc::Pointer p_; /**< Pointer to SHM request */ + bool complete_; /**< Whether request is complete */ LaneData() = default; @@ -32,6 +31,7 @@ struct LaneGroup : public PriorityInfo { u32 prio_; /**< The priority of the lane group */ u32 num_scheduled_; /**< The number of lanes currently scheduled on workers */ hipc::ShmArchive> lanes_; /**< The lanes of the queue */ + u32 tether_; /**< Lanes should be pinned to the same workers as the tether's prio group */ /** Default constructor */ HSHM_ALWAYS_INLINE @@ -40,34 +40,43 @@ struct LaneGroup : public PriorityInfo { /** Set priority info */ HSHM_ALWAYS_INLINE LaneGroup(const PriorityInfo &priority) { + prio_ = priority.prio_; max_lanes_ = priority.max_lanes_; num_lanes_ = priority.num_lanes_; num_scheduled_ = 0; depth_ = priority.depth_; flags_ = priority.flags_; - // prio_ is set externally + tether_ = priority.tether_; } /** Copy constructor. Should never actually be called. */ HSHM_ALWAYS_INLINE LaneGroup(const LaneGroup &priority) { + prio_ = priority.prio_; max_lanes_ = priority.max_lanes_; num_lanes_ = priority.num_lanes_; num_scheduled_ = priority.num_scheduled_; depth_ = priority.depth_; flags_ = priority.flags_; - // prio_ is set externally + tether_ = priority.tether_; } /** Move constructor. Should never actually be called. */ HSHM_ALWAYS_INLINE LaneGroup(LaneGroup &&priority) noexcept { + prio_ = priority.prio_; max_lanes_ = priority.max_lanes_; num_lanes_ = priority.num_lanes_; num_scheduled_ = priority.num_scheduled_; depth_ = priority.depth_; flags_ = priority.flags_; - // prio_ is set externally + tether_ = priority.tether_; + } + + /** Check if this group is tethered */ + HSHM_ALWAYS_INLINE + bool IsTethered() { + return flags_.Any(QUEUE_TETHERED); } /** Check if this group is long-running or ADMIN */ @@ -117,16 +126,13 @@ struct MultiQueueT : public hipc::ShmContainer { const std::vector &prios) { shm_init_container(alloc); id_ = id; - HSHM_MAKE_AR0(groups_, GetAllocator()); - groups_->reserve(prios.size()); - for (u32 prio = 0; prio < prios.size(); ++prio) { - const PriorityInfo &prio_info = prios[prio]; - groups_->emplace_back(prio_info); - LaneGroup &lane_group = (*groups_)[prio]; + HSHM_MAKE_AR(groups_, GetAllocator(), prios.size()); + for (const PriorityInfo &prio_info : prios) { + groups_->replace(groups_->begin() + prio_info.prio_, prio_info); + LaneGroup &lane_group = (*groups_)[prio_info.prio_]; // Initialize lanes HSHM_MAKE_AR0(lane_group.lanes_, GetAllocator()); lane_group.lanes_->reserve(prio_info.max_lanes_); - lane_group.prio_ = prio; for (u32 lane_id = 0; lane_id < lane_group.num_lanes_; ++lane_id) { lane_group.lanes_->emplace_back(lane_group.depth_, id_); Lane &lane = lane_group.lanes_->back(); diff --git a/hrun/include/hrun/queue_manager/queues/mpsc_queue.h b/hrun/include/hrun/queue_manager/queues/mpsc_queue.h index 642a0987c..abf459b32 100644 --- a/hrun/include/hrun/queue_manager/queues/mpsc_queue.h +++ b/hrun/include/hrun/queue_manager/queues/mpsc_queue.h @@ -57,6 +57,7 @@ class mpsc_queue : public ShmContainer { std::atomic<_qtok_t> head_; bitfield32_t flags_; QueueId id_; + u32 worker_id_; public: /**==================================== diff --git a/hrun/include/hrun/task_registry/task.h b/hrun/include/hrun/task_registry/task.h index d3ab5de8c..5a92f2e27 100644 --- a/hrun/include/hrun/task_registry/task.h +++ b/hrun/include/hrun/task_registry/task.h @@ -53,8 +53,6 @@ class TaskLib; #define TASK_DATA_OWNER BIT_OPT(u32, 14) /** This task uses co-routine wait */ #define TASK_COROUTINE BIT_OPT(u32, 15) -/** This task uses argobot wait */ -#define TASK_PREEMPTIVE BIT_OPT(u32, 17) /** This task can be scheduled on any lane */ #define TASK_LANE_ANY BIT_OPT(u32, 18) /** This task should be scheduled on all lanes */ @@ -239,15 +237,15 @@ class TaskPrio { /** Used to indicate the amount of work remaining to do when flushing */ struct WorkPending { bool flushing_; - std::atomic pending_; + std::atomic count_; /** Default constructor */ WorkPending() - : flushing_(false), pending_(0) {} + : flushing_(false), count_(0) {} /** Copy constructor */ WorkPending(const WorkPending &other) - : flushing_(other.flushing_), pending_(other.pending_.load()) {} + : flushing_(other.flushing_), count_(other.count_.load()) {} }; /** Context passed to the Run method of a task */ @@ -393,11 +391,6 @@ struct Task : public hipc::ShmContainer { task_flags_.UnsetBits(TASK_COROUTINE); } - /** Set this task as blocking */ - HSHM_ALWAYS_INLINE bool IsPreemptive() { - return task_flags_.Any(TASK_PREEMPTIVE); - } - /** This task should be dispersed across all lanes */ HSHM_ALWAYS_INLINE bool IsLaneAll() { return task_flags_.Any(TASK_LANE_ALL); diff --git a/hrun/include/hrun/work_orchestrator/affinity.h b/hrun/include/hrun/work_orchestrator/affinity.h index fcd578a09..7e6106308 100644 --- a/hrun/include/hrun/work_orchestrator/affinity.h +++ b/hrun/include/hrun/work_orchestrator/affinity.h @@ -38,18 +38,14 @@ class ProcessAffiner { private: int n_cpu_; - cpu_set_t *cpus_; + std::vector cpus_; std::vector ignore_pids_; public: ProcessAffiner() { n_cpu_ = get_nprocs_conf(); - cpus_ = new cpu_set_t[n_cpu_]; - CPU_ZERO(cpus_); - } - - ~ProcessAffiner() { - delete cpus_; + cpus_.resize(n_cpu_); + Clear(); } inline bool isdigit(char digit) { @@ -61,7 +57,7 @@ class ProcessAffiner { } inline void SetCpu(int cpu) { - CPU_SET(cpu, cpus_); + CPU_SET(cpu, cpus_.data()); } inline void SetCpus(int off, int len) { @@ -77,7 +73,7 @@ class ProcessAffiner { } inline void ClearCpu(int cpu) { - CPU_CLR(cpu, cpus_); + CPU_CLR(cpu, cpus_.data()); } void IgnorePids(const std::vector &pids) { @@ -91,7 +87,9 @@ class ProcessAffiner { } inline void Clear() { - CPU_ZERO(cpus_); + for (cpu_set_t &cpu : cpus_) { + CPU_ZERO(&cpu); + } } int AffineAll(void) { @@ -136,7 +134,7 @@ class ProcessAffiner { return count; } int Affine(int pid) { - return SetAffinitySafe(pid, n_cpu_, cpus_); + return SetAffinitySafe(pid, n_cpu_, cpus_.data()); } void PrintAffinity(int pid) { diff --git a/hrun/include/hrun/work_orchestrator/scheduler.h b/hrun/include/hrun/work_orchestrator/scheduler.h index 25bdca4c8..56b69dd76 100644 --- a/hrun/include/hrun/work_orchestrator/scheduler.h +++ b/hrun/include/hrun/work_orchestrator/scheduler.h @@ -43,7 +43,7 @@ struct ScheduleTask : public Task, TaskFlags { task_state_ = state_id; method_ = SchedulerMethod::kSchedule; task_flags_.SetBits(TASK_LONG_RUNNING | TASK_REMOTE_DEBUG_MARK); - SetPeriodSec(1); + SetPeriodMs(5); domain_id_ = domain_id; // Custom params diff --git a/hrun/include/hrun/work_orchestrator/worker.h b/hrun/include/hrun/work_orchestrator/worker.h index a7a018ccd..18e7555c1 100644 --- a/hrun/include/hrun/work_orchestrator/worker.h +++ b/hrun/include/hrun/work_orchestrator/worker.h @@ -310,9 +310,9 @@ class Worker { now_.Now(); while (orchestrator->IsAlive()) { try { - flush_.pending_ = 0; - Run(); - if (flush_.flushing_ && flush_.pending_ == 0) { + bool flushing = flush_.flushing_; + Run(flushing); + if (flushing) { flush_.flushing_ = false; } } catch (hshm::Error &e) { @@ -322,11 +322,11 @@ class Worker { Yield(); } } - Run(); + Run(true); } /** Run a single iteration over all queues */ - void Run() { + void Run(bool flushing) { if (poll_queues_.size() > 0) { _PollQueues(); } @@ -337,11 +337,11 @@ class Worker { now_.Now(); for (WorkEntry &work_entry : work_queue_) { work_entry.cur_time_ = now_; - PollGrouped(work_entry); + PollGrouped(work_entry, flushing); } } else { for (WorkEntry &work_entry : work_queue_) { - PollGrouped(work_entry); + PollGrouped(work_entry, flushing); } } @@ -349,7 +349,7 @@ class Worker { /** Run an iteration over a particular queue */ HSHM_ALWAYS_INLINE - void PollGrouped(WorkEntry &work_entry) { + void PollGrouped(WorkEntry &work_entry, bool flushing) { int off = 0; Lane *&lane = work_entry.lane_; Task *task; @@ -383,11 +383,20 @@ class Worker { EndTask(lane, exec, task, off); continue; } - // Attempt to run the task if it's ready and runnable + // Get task properties bool is_remote = task->domain_id_.IsRemote(HRUN_RPC->GetNumHosts(), HRUN_CLIENT->node_id_); - if (!task->IsRunDisabled() && - CheckTaskGroup(task, exec, work_entry.lane_id_, task->task_node_, is_remote) && - task->ShouldRun(work_entry.cur_time_, flush_.flushing_)) { + bool group_avail = CheckTaskGroup(task, exec, work_entry.lane_id_, task->task_node_, is_remote); + bool should_run = task->ShouldRun(work_entry.cur_time_, flushing); + // Verify tasks + if (flushing && !task->IsFlush()) { + if (task->IsLongRunning()) { + exec->Monitor(MonitorMode::kFlushStat, task, rctx); + } else { + flush_.count_ += 1; + } + } + // Attempt to run the task if it's ready and runnable + if (!task->IsRunDisabled() && group_avail && should_run) { // #define REMOTE_DEBUG #ifdef REMOTE_DEBUG if (task->task_state_ != HRUN_QM_CLIENT->admin_task_state_ && @@ -435,20 +444,6 @@ class Worker { } task->DidRun(work_entry.cur_time_); } - // Verify tasks - if (flush_.flushing_ && !task->IsModuleComplete() && !task->IsFlush()) { - int pend_prior = flush_.pending_; - if (task->IsLongRunning()) { - exec->Monitor(MonitorMode::kFlushStat, task, rctx); - } else { - flush_.pending_ += 1; - } - if (pend_prior != flush_.pending_) { - HILOG(kInfo, "(node {}) Pending on task={} state={} method={} is_remote={} worker={}", - HRUN_CLIENT->node_id_, task->task_node_, task->task_state_, task->method_, - is_remote, id_) - } - } // Cleanup on task completion if (task->IsModuleComplete()) { // HILOG(kDebug, "(node {}) Ending task: task_node={} task_state={} worker={}", @@ -456,8 +451,6 @@ class Worker { entry->complete_ = true; if (task->IsCoroutine()) { free(rctx.stack_ptr_); - } else if (task->IsPreemptive()) { - ABT_thread_join(entry->thread_); } RemoveTaskGroup(task, exec, work_entry.lane_id_, is_remote); EndTask(lane, exec, task, off); @@ -483,7 +476,7 @@ class Worker { * =============================================================== */ /** Check if two tasks can execute concurrently */ - HSHM_ALWAYS_INLINE + // HSHM_ALWAYS_INLINE bool CheckTaskGroup(Task *task, TaskState *exec, u32 lane_id, TaskNode node, const bool &is_remote) { @@ -497,33 +490,23 @@ class Worker { return true; } -#ifdef DEBUG - // TODO(llogan): remove - std::stringstream ss; - for (int i = 0; i < group_.size(); ++i) { - ss << std::to_string((int)group_[i]); - } -#endif - // Ensure that concurrent requests are not serialized - LocalSerialize srl(group_); + LocalSerialize srl(group_, false); srl << lane_id; auto it = group_map_.find(group_); if (it == group_map_.end()) { node.node_depth_ = 1; group_map_.emplace(group_, node); -// HILOG(kDebug, "(node {}) Increasing depth of (task_state={} method={} name={}) group to {} worker={}", -// HRUN_CLIENT->node_id_, task->task_state_, task->method_, exec->name_, -// node.node_depth_, id_); +// HILOG(kDebug, "(node {}) Increasing depth of group {} to {} (worker={})", +// HRUN_CLIENT->node_id_, std::hash{}(group_), node.node_depth_, id_); return true; } TaskNode &node_cmp = it->second; if (node_cmp.root_ == node.root_) { node_cmp.node_depth_ += 1; -// HILOG(kDebug, "(node {}) Increasing depth of (task_state={} method={} name={}) group to {} worker={}", -// HRUN_CLIENT->node_id_, task->task_state_, task->method_, exec->name_, -// node.node_depth_, id_); +// HILOG(kDebug, "(node {}) Increasing depth of group {} to {} (worker={})", +// HRUN_CLIENT->node_id_, std::hash{}(group_), node.node_depth_, id_); return true; } return false; @@ -543,21 +526,14 @@ class Worker { return; } -#ifdef DEBUG - // TODO(llogan): remove - std::stringstream ss; - for (int i = 0; i < group_.size(); ++i) { - ss << std::to_string((int)group_[i]); - } -#endif // Ensure that concurrent requests are not serialized - LocalSerialize srl(group_); + LocalSerialize srl(group_, false); srl << lane_id; TaskNode &node_cmp = group_map_[group_]; if (node_cmp.node_depth_ == 0) { HELOG(kFatal, "(node {}) Group {} depth is already 0 (task_node={} worker={})", - HRUN_CLIENT->node_id_, task->task_node_, id_); + HRUN_CLIENT->node_id_, std::hash{}(group_), task->task_node_, id_); } node_cmp.node_depth_ -= 1; // HILOG(kDebug, "(node {}) Decreasing depth of to {} (task_node={} worker={})", diff --git a/hrun/src/config_server.cc b/hrun/src/config_server.cc index 108df2649..1e21ad9e6 100644 --- a/hrun/src/config_server.cc +++ b/hrun/src/config_server.cc @@ -49,8 +49,8 @@ void ServerConfig::ParseQueueManager(YAML::Node yaml_conf) { queue_manager_.shm_allocator_ = yaml_conf["shm_allocator"].as(); } if (yaml_conf["shm_name"]) { - queue_manager_.shm_name_ = yaml_conf["shm_name"].as(); - queue_manager_.data_shm_name_ = queue_manager_.shm_name_ + "_data"; + queue_manager_.shm_name_ = hshm::ConfigParse::ExpandPath(yaml_conf["shm_name"].as()); + queue_manager_.data_shm_name_ = hshm::ConfigParse::ExpandPath(queue_manager_.shm_name_ + "_data"); } if (yaml_conf["shm_size"]) { queue_manager_.shm_size_ = hshm::ConfigParse::ParseSize( diff --git a/hrun/src/hrun_runtime.cc b/hrun/src/hrun_runtime.cc index c1eef9917..254bf66f0 100644 --- a/hrun/src/hrun_runtime.cc +++ b/hrun/src/hrun_runtime.cc @@ -32,9 +32,13 @@ Runtime* Runtime::Create(std::string server_config_path) { /** Initialize */ void Runtime::ServerInit(std::string server_config_path) { LoadServerConfig(server_config_path); + HILOG(kInfo, "Initializing shared memory") InitSharedMemory(); + HILOG(kInfo, "Initializing RPC") rpc_.ServerInit(&server_config_); + HILOG(kInfo, "Initializing thallium") thallium_.ServerInit(&rpc_); + HILOG(kInfo, "Initializing queues + workers") header_->node_id_ = rpc_.node_id_; header_->unique_ = 0; header_->num_nodes_ = server_config_.rpc_.host_names_.size(); @@ -113,6 +117,7 @@ void Runtime::InitSharedMemory() { mem_mngr->CreateBackend( qm.shm_size_, qm.shm_name_); + hipc::MemoryBackend *backend = mem_mngr->GetBackend(qm.shm_name_); main_alloc_ = mem_mngr->CreateAllocator( qm.shm_name_, diff --git a/hrun/src/hrun_stop_runtime.cc b/hrun/src/hrun_stop_runtime.cc index 079533cab..f5cb33d02 100644 --- a/hrun/src/hrun_stop_runtime.cc +++ b/hrun/src/hrun_stop_runtime.cc @@ -14,5 +14,5 @@ int main() { TRANSPARENT_HRUN(); - HRUN_ADMIN->AsyncStopRuntimeRoot(hrun::DomainId::GetLocal()); + HRUN_ADMIN->StopRuntimeRoot(hrun::DomainId::GetLocal()); } \ No newline at end of file diff --git a/hrun/tasks_required/TASK_NAME/include/TASK_NAME/TASK_NAME.h b/hrun/tasks_required/TASK_NAME/include/TASK_NAME/TASK_NAME.h index e2f541956..9edd34e59 100644 --- a/hrun/tasks_required/TASK_NAME/include/TASK_NAME/TASK_NAME.h +++ b/hrun/tasks_required/TASK_NAME/include/TASK_NAME/TASK_NAME.h @@ -35,9 +35,9 @@ class Client : public TaskLibClient { id_ = TaskStateId::GetNull(); QueueManagerInfo &qm = HRUN_CLIENT->server_config_.queue_manager_; std::vector queue_info = { - {1, 1, qm.queue_depth_, 0}, - {1, 1, qm.queue_depth_, QUEUE_LONG_RUNNING}, - {qm.max_lanes_, qm.max_lanes_, qm.queue_depth_, QUEUE_LOW_LATENCY} + {TaskPrio::kAdmin, 1, 1, qm.queue_depth_, 0}, + {TaskPrio::kLongRunning, 1, 1, qm.queue_depth_, QUEUE_LONG_RUNNING}, + {TaskPrio::kLowLatency, qm.max_lanes_, qm.max_lanes_, qm.queue_depth_, QUEUE_LOW_LATENCY} }; return HRUN_ADMIN->AsyncCreateTaskState( task_node, domain_id, state_name, id_, queue_info); diff --git a/hrun/tasks_required/hrun_admin/include/hrun_admin/hrun_admin.h b/hrun/tasks_required/hrun_admin/include/hrun_admin/hrun_admin.h index a6718df88..2ec64d51b 100644 --- a/hrun/tasks_required/hrun_admin/include/hrun_admin/hrun_admin.h +++ b/hrun/tasks_required/hrun_admin/include/hrun_admin/hrun_admin.h @@ -177,6 +177,10 @@ class Client : public TaskLibClient { task, task_node, domain_id); } HRUN_TASK_NODE_ADMIN_ROOT(StopRuntime); + void StopRuntimeRoot(const DomainId &domain_id) { + FlushRoot(domain_id); + AsyncStopRuntimeRoot(domain_id); + } /** Set work orchestrator queue policy */ void AsyncSetWorkOrchQueuePolicyConstruct(SetWorkOrchQueuePolicyTask *task, @@ -242,7 +246,7 @@ class Client : public TaskLibClient { } // FlushRoot(DomainId::GetLocal()); HRUN_CLIENT->Yield(); - // HILOG(kInfo, "{} Could not allocate buffer of size {} (1)?", THREAD_MODEL, size); + HILOG(kDebug, "{} Waiting to allocate buffer of size {} (1)?", size); } return p; } diff --git a/hrun/tasks_required/hrun_admin/include/hrun_admin/hrun_admin_tasks.h b/hrun/tasks_required/hrun_admin/include/hrun_admin/hrun_admin_tasks.h index 4dd5e24ab..48e208849 100644 --- a/hrun/tasks_required/hrun_admin/include/hrun_admin/hrun_admin_tasks.h +++ b/hrun/tasks_required/hrun_admin/include/hrun_admin/hrun_admin_tasks.h @@ -464,7 +464,9 @@ struct FlushTask : public Task, TaskFlags { /** Create group */ HSHM_ALWAYS_INLINE u32 GetGroup(hshm::charbuf &group) { - return TASK_UNORDERED; + hrun::LocalSerialize srl(group); + srl << task_state_; + return 0; } }; diff --git a/hrun/tasks_required/hrun_admin/src/hrun_admin.cc b/hrun/tasks_required/hrun_admin/src/hrun_admin.cc index e1c955828..b0547b109 100644 --- a/hrun/tasks_required/hrun_admin/src/hrun_admin.cc +++ b/hrun/tasks_required/hrun_admin/src/hrun_admin.cc @@ -99,6 +99,7 @@ class Server : public TaskLib { task->id_, task); queue->flags_.SetBits(QUEUE_READY); + task->method_ = Method::kCreateTaskState; task->SetModuleComplete(); } void MonitorCreateTaskState(u32 mode, CreateTaskStateTask *task, RunContext &rctx) { @@ -170,21 +171,21 @@ class Server : public TaskLib { /** Flush the runtime */ void Flush(FlushTask *task, RunContext &rctx) { HILOG(kDebug, "Beginning to flush runtime"); - for (std::unique_ptr &worker : HRUN_WORK_ORCHESTRATOR->workers_) { - worker->flush_.flushing_ = true; - worker->flush_.pending_ = 1; - } while (true) { + // Make all workers flush locally int count = 0; - for (std::unique_ptr &worker : HRUN_WORK_ORCHESTRATOR->workers_) { - if (worker->flush_.flushing_) { - count += 1; - break; + for (int i = 0; i < 2; ++i) { + for (std::unique_ptr + &worker : HRUN_WORK_ORCHESTRATOR->workers_) { + worker->flush_.count_ = 0; + worker->flush_.flushing_ = true; + while (worker->flush_.flushing_) { + task->Yield(); + } + count += worker->flush_.count_; } } - if (count) { - task->Yield(); - } else { + if (!count) { break; } } diff --git a/hrun/tasks_required/proc_queue/include/proc_queue/proc_queue.h b/hrun/tasks_required/proc_queue/include/proc_queue/proc_queue.h index 948fc7464..abeca1d7f 100644 --- a/hrun/tasks_required/proc_queue/include/proc_queue/proc_queue.h +++ b/hrun/tasks_required/proc_queue/include/proc_queue/proc_queue.h @@ -37,10 +37,10 @@ class Client : public TaskLibClient { id_ = TaskStateId::GetNull(); QueueManagerInfo &qm = HRUN_CLIENT->server_config_.queue_manager_; std::vector queue_info = { - {1, 1, qm.queue_depth_, 0}, - {1, 1, qm.queue_depth_, QUEUE_LONG_RUNNING}, + {TaskPrio::kAdmin, 1, 1, qm.queue_depth_, 0}, + {TaskPrio::kLongRunning, 1, 1, qm.queue_depth_, QUEUE_LONG_RUNNING}, // TODO(llogan): Specify different depth for proc queue - {qm.max_lanes_, qm.max_lanes_, 16, QUEUE_LOW_LATENCY} + {TaskPrio::kLowLatency, qm.max_lanes_, qm.max_lanes_, 16, QUEUE_LOW_LATENCY} }; return HRUN_ADMIN->AsyncCreateTaskState( task_node, domain_id, state_name, id_, queue_info); diff --git a/hrun/tasks_required/remote_queue/include/remote_queue/remote_queue.h b/hrun/tasks_required/remote_queue/include/remote_queue/remote_queue.h index c9457a3d6..d048bb4bb 100644 --- a/hrun/tasks_required/remote_queue/include/remote_queue/remote_queue.h +++ b/hrun/tasks_required/remote_queue/include/remote_queue/remote_queue.h @@ -34,10 +34,10 @@ class Client : public TaskLibClient { QueueManagerInfo &qm = HRUN_CLIENT->server_config_.queue_manager_; // NOTE(llogan): 32x queue depth b/c default num rpc threads is 32 std::vector queue_info = { - {1, 1, qm.queue_depth_, 0}, - {1, 1, qm.queue_depth_, QUEUE_LONG_RUNNING}, + {TaskPrio::kAdmin, 1, 1, qm.queue_depth_, 0}, + {TaskPrio::kLongRunning, 1, 1, qm.queue_depth_, QUEUE_LONG_RUNNING}, // {qm.max_lanes_, qm.max_lanes_, qm.queue_depth_, QUEUE_LOW_LATENCY} - {1, 1, qm.queue_depth_, QUEUE_LOW_LATENCY}, + {TaskPrio::kLowLatency, 1, 1, qm.queue_depth_, QUEUE_LOW_LATENCY}, }; return HRUN_ADMIN->AsyncCreateTaskState( task_node, domain_id, state_name, id_, queue_info); diff --git a/hrun/tasks_required/small_message/include/small_message/small_message.h b/hrun/tasks_required/small_message/include/small_message/small_message.h index f66d120f2..05d10e5ac 100644 --- a/hrun/tasks_required/small_message/include/small_message/small_message.h +++ b/hrun/tasks_required/small_message/include/small_message/small_message.h @@ -26,9 +26,9 @@ class Client : public TaskLibClient { id_ = TaskStateId::GetNull(); QueueManagerInfo &qm = HRUN_CLIENT->server_config_.queue_manager_; std::vector queue_info = { - {1, 1, qm.queue_depth_, 0}, - {1, 1, qm.queue_depth_, QUEUE_LONG_RUNNING}, - {qm.max_lanes_, qm.max_lanes_, qm.queue_depth_, QUEUE_LOW_LATENCY} + {TaskPrio::kAdmin, 1, 1, qm.queue_depth_, 0}, + {TaskPrio::kLongRunning, 1, 1, qm.queue_depth_, QUEUE_LONG_RUNNING}, + {TaskPrio::kLowLatency, qm.max_lanes_, qm.max_lanes_, qm.queue_depth_, QUEUE_LOW_LATENCY} }; id_ = HRUN_ADMIN->CreateTaskStateRoot( domain_id, state_name, id_, queue_info); diff --git a/hrun/tasks_required/worch_proc_round_robin/include/worch_proc_round_robin/worch_proc_round_robin.h b/hrun/tasks_required/worch_proc_round_robin/include/worch_proc_round_robin/worch_proc_round_robin.h index f57feabaa..4673369cb 100644 --- a/hrun/tasks_required/worch_proc_round_robin/include/worch_proc_round_robin/worch_proc_round_robin.h +++ b/hrun/tasks_required/worch_proc_round_robin/include/worch_proc_round_robin/worch_proc_round_robin.h @@ -25,7 +25,7 @@ class Client : public TaskLibClient { const std::string &state_name) { id_ = TaskStateId::GetNull(); std::vector queue_info = { - {1, 1, 4, 0}, + {TaskPrio::kAdmin, 1, 1, 4, 0}, }; id_ = HRUN_ADMIN->CreateTaskStateRoot( domain_id, state_name, id_, queue_info); diff --git a/hrun/tasks_required/worch_queue_round_robin/include/worch_queue_round_robin/worch_queue_round_robin.h b/hrun/tasks_required/worch_queue_round_robin/include/worch_queue_round_robin/worch_queue_round_robin.h index 539f96fb3..d4a161f87 100644 --- a/hrun/tasks_required/worch_queue_round_robin/include/worch_queue_round_robin/worch_queue_round_robin.h +++ b/hrun/tasks_required/worch_queue_round_robin/include/worch_queue_round_robin/worch_queue_round_robin.h @@ -25,7 +25,7 @@ class Client : public TaskLibClient { const std::string &state_name) { id_ = TaskStateId::GetNull(); std::vector queue_info = { - {1, 1, 4, 0}, + {TaskPrio::kAdmin, 1, 1, 4, 0}, }; id_ = HRUN_ADMIN->CreateTaskStateRoot( domain_id, state_name, id_, queue_info); diff --git a/hrun/tasks_required/worch_queue_round_robin/src/worch_queue_round_robin.cc b/hrun/tasks_required/worch_queue_round_robin/src/worch_queue_round_robin.cc index 38471ffb8..d058b8673 100644 --- a/hrun/tasks_required/worch_queue_round_robin/src/worch_queue_round_robin.cc +++ b/hrun/tasks_required/worch_queue_round_robin/src/worch_queue_round_robin.cc @@ -46,24 +46,40 @@ class Server : public TaskLib { continue; } for (LaneGroup &lane_group : *queue.groups_) { - for (u32 lane_id = lane_group.num_scheduled_; lane_id < lane_group.num_lanes_; ++lane_id) { - if (lane_group.IsLowLatency()) { + u32 num_lanes = lane_group.num_lanes_; + if (lane_group.IsTethered()) { + LaneGroup &tether_group = queue.GetGroup(lane_group.tether_); + num_lanes = tether_group.num_scheduled_; + } + for (u32 lane_id = lane_group.num_scheduled_; lane_id < num_lanes; ++lane_id) { + Lane &lane = lane_group.GetLane(lane_id); + if (lane_group.IsTethered()) { + LaneGroup &tether_group = queue.GetGroup(lane_group.tether_); + Lane &tether_lane = tether_group.GetLane(lane_id); + Worker &worker = *HRUN_WORK_ORCHESTRATOR->workers_[tether_lane.worker_id_]; + worker.PollQueues({WorkEntry(lane_group.prio_, lane_id, &queue)}); + lane.worker_id_ = worker.id_; + HILOG(kDebug, "(node {}) Scheduling the queue {} (prio {}, lane {}, worker {})", + HRUN_CLIENT->node_id_, queue.id_, lane_group.prio_, lane_id, worker.id_); + } else if (lane_group.IsLowLatency()) { u32 worker_off = count_lowlat_ % HRUN_WORK_ORCHESTRATOR->dworkers_.size(); count_lowlat_ += 1; Worker &worker = *HRUN_WORK_ORCHESTRATOR->dworkers_[worker_off]; worker.PollQueues({WorkEntry(lane_group.prio_, lane_id, &queue)}); - HILOG(kDebug, "(node {}) Scheduling the queue {} (lane {}, worker {})", - HRUN_CLIENT->node_id_, queue.id_, lane_id, worker.id_); + lane.worker_id_ = worker.id_; + HILOG(kDebug, "(node {}) Scheduling the queue {} (prio {}, lane {}, worker {})", + HRUN_CLIENT->node_id_, queue.id_, lane_group.prio_, lane_id, worker.id_); } else { u32 worker_off = count_highlat_ % HRUN_WORK_ORCHESTRATOR->oworkers_.size(); count_highlat_ += 1; Worker &worker = *HRUN_WORK_ORCHESTRATOR->oworkers_[worker_off]; worker.PollQueues({WorkEntry(lane_group.prio_, lane_id, &queue)}); - HILOG(kDebug, "(node {}) Scheduling the queue {} (lane {}, worker {})", - HRUN_CLIENT->node_id_, queue.id_, lane_id, worker_off); + HILOG(kDebug, "(node {}) Scheduling the queue {} (prio {}, lane {}, worker {})", + HRUN_CLIENT->node_id_, queue.id_, lane_group.prio_, lane_id, worker_off); + lane.worker_id_ = worker.id_; } } - lane_group.num_scheduled_ = lane_group.num_lanes_; + lane_group.num_scheduled_ = num_lanes; } } } diff --git a/include/hermes/bucket.h b/include/hermes/bucket.h index 10dbf7103..113198653 100644 --- a/include/hermes/bucket.h +++ b/include/hermes/bucket.h @@ -71,7 +71,7 @@ class Bucket { bkt_mdm_ = &HERMES_CONF->bkt_mdm_; id_ = bkt_mdm_->GetOrCreateTagRoot( hshm::charbuf(bkt_name), true, - std::vector(), backend_size, flags); + std::vector(), backend_size, flags, ctx); name_ = bkt_name; } @@ -477,7 +477,8 @@ class Bucket { GetBlobTask *task = push_task->get(); blob_id = task->blob_id_; char *data = HRUN_CLIENT->GetDataPointer(task->data_); - memcpy(blob.data(), data, data_size); + memcpy(blob.data(), data, task->data_size_); + blob.resize(task->data_size_); HRUN_CLIENT->FreeBuffer(task->data_); HRUN_CLIENT->DelTask(push_task); return blob_id; diff --git a/include/hermes/hermes_types.h b/include/hermes/hermes_types.h index c92adb6db..de8fd8cbe 100644 --- a/include/hermes/hermes_types.h +++ b/include/hermes/hermes_types.h @@ -119,12 +119,12 @@ struct Context { /** The blob's score */ float blob_score_; - /** Page size to use for FS reads / writes*/ - size_t page_size_; - /** Flags */ bitfield32_t flags_; + /** Custom bucket parameters */ + std::string bkt_params_; + /** The node id the blob will be accessed from */ u32 node_id_; diff --git a/tasks/bdev/include/bdev/bdev.h b/tasks/bdev/include/bdev/bdev.h index 9e4b89490..8b26d056b 100644 --- a/tasks/bdev/include/bdev/bdev.h +++ b/tasks/bdev/include/bdev/bdev.h @@ -50,10 +50,10 @@ class Client : public TaskLibClient { CopyDevInfo(dev_info); QueueManagerInfo &qm = HRUN_CLIENT->server_config_.queue_manager_; std::vector queue_info = { - {1, 1, qm.queue_depth_, 0}, - {1, 1, qm.queue_depth_, QUEUE_LONG_RUNNING}, - {qm.max_lanes_, qm.max_lanes_, qm.queue_depth_, QUEUE_LOW_LATENCY}, - {qm.max_lanes_, qm.max_lanes_, qm.queue_depth_, 0} + {TaskPrio::kAdmin, 1, 1, qm.queue_depth_, 0}, + {TaskPrio::kLongRunning, 1, 1, qm.queue_depth_, QUEUE_LONG_RUNNING}, + {TaskPrio::kLowLatency, qm.max_lanes_, qm.max_lanes_, qm.queue_depth_, QUEUE_LOW_LATENCY}, + {TaskPrio::kHighLatency, qm.max_lanes_, qm.max_lanes_, qm.queue_depth_, 0} }; return HRUN_ADMIN->AsyncCreateTaskState( task_node, domain_id, state_name, lib_name, id_, diff --git a/tasks/data_stager/include/data_stager/data_stager.h b/tasks/data_stager/include/data_stager/data_stager.h index dd7fdbc7c..a0cd397dc 100644 --- a/tasks/data_stager/include/data_stager/data_stager.h +++ b/tasks/data_stager/include/data_stager/data_stager.h @@ -27,9 +27,9 @@ class Client : public TaskLibClient { id_ = TaskStateId::GetNull(); QueueManagerInfo &qm = HRUN_CLIENT->server_config_.queue_manager_; std::vector queue_info = { - {1, 1, qm.queue_depth_, 0}, - {1, 1, qm.queue_depth_, QUEUE_LONG_RUNNING}, - {qm.max_lanes_, qm.max_lanes_, qm.queue_depth_, QUEUE_LOW_LATENCY} + {TaskPrio::kAdmin, 1, 1, qm.queue_depth_, 0}, + {TaskPrio::kLongRunning, 1, 1, qm.queue_depth_, QUEUE_LONG_RUNNING}, + {TaskPrio::kLowLatency, qm.max_lanes_, qm.max_lanes_, qm.queue_depth_, QUEUE_LOW_LATENCY} }; return HRUN_ADMIN->AsyncCreateTaskState( task_node, domain_id, state_name, id_, queue_info, blob_mdm); @@ -57,15 +57,17 @@ class Client : public TaskLibClient { void AsyncRegisterStagerConstruct(RegisterStagerTask *task, const TaskNode &task_node, const BucketId &bkt_id, - const hshm::charbuf &url) { + const hshm::charbuf &path, + const hshm::charbuf ¶ms) { HRUN_CLIENT->ConstructTask( - task, task_node, id_, bkt_id, url); + task, task_node, id_, bkt_id, path, params); } HSHM_ALWAYS_INLINE void RegisterStagerRoot(const BucketId &bkt_id, - const hshm::charbuf &url) { + const hshm::charbuf &path, + const hshm::charbuf params) { LPointer> task = - AsyncRegisterStagerRoot(bkt_id, url); + AsyncRegisterStagerRoot(bkt_id, path, params); task.ptr_->Wait(); } HRUN_TASK_NODE_PUSH_ROOT(RegisterStager); diff --git a/tasks/data_stager/include/data_stager/data_stager_tasks.h b/tasks/data_stager/include/data_stager/data_stager_tasks.h index a9bcb44f9..8a2bdd03c 100644 --- a/tasks/data_stager/include/data_stager/data_stager_tasks.h +++ b/tasks/data_stager/include/data_stager/data_stager_tasks.h @@ -93,7 +93,8 @@ struct DestructTask : public DestroyTaskStateTask { * */ struct RegisterStagerTask : public Task, TaskFlags { hermes::BucketId bkt_id_; - hipc::ShmArchive url_; + hipc::ShmArchive tag_name_; + hipc::ShmArchive params_; /** SHM default constructor */ HSHM_ALWAYS_INLINE explicit @@ -105,7 +106,8 @@ struct RegisterStagerTask : public Task, TaskFlags { const TaskNode &task_node, const TaskStateId &state_id, hermes::BucketId bkt_id, - const hshm::charbuf &url) : Task(alloc) { + const hshm::charbuf &tag_name, + const hshm::charbuf ¶ms) : Task(alloc) { // Initialize task task_node_ = task_node; lane_hash_ = bkt_id.hash_; @@ -117,13 +119,15 @@ struct RegisterStagerTask : public Task, TaskFlags { // Custom params bkt_id_ = bkt_id; - HSHM_MAKE_AR(url_, alloc, url); + HSHM_MAKE_AR(tag_name_, alloc, tag_name); + HSHM_MAKE_AR(params_, alloc, params); } /** Destructor */ HSHM_ALWAYS_INLINE ~RegisterStagerTask() { - HSHM_DESTROY_AR(url_) + HSHM_DESTROY_AR(tag_name_) + HSHM_DESTROY_AR(params_) } /** Duplicate message */ @@ -139,7 +143,7 @@ struct RegisterStagerTask : public Task, TaskFlags { template void SerializeStart(Ar &ar) { task_serialize(ar); - ar(bkt_id_, url_); + ar(bkt_id_, tag_name_, params_); } /** (De)serialize message return */ diff --git a/tasks/data_stager/include/data_stager/factory/abstract_stager.h b/tasks/data_stager/include/data_stager/factory/abstract_stager.h index 2c5dca484..02483101c 100644 --- a/tasks/data_stager/include/data_stager/factory/abstract_stager.h +++ b/tasks/data_stager/include/data_stager/factory/abstract_stager.h @@ -11,7 +11,8 @@ namespace hermes::data_stager { class AbstractStager { public: - std::string url_; + std::string path_; + std::string params_; AbstractStager() = default; ~AbstractStager() = default; diff --git a/tasks/data_stager/include/data_stager/factory/binary_stager.h b/tasks/data_stager/include/data_stager/factory/binary_stager.h index 1e3a3bedb..957ca4ea7 100644 --- a/tasks/data_stager/include/data_stager/factory/binary_stager.h +++ b/tasks/data_stager/include/data_stager/factory/binary_stager.h @@ -12,7 +12,6 @@ namespace hermes::data_stager { class BinaryFileStager : public AbstractStager { public: - int fd_ = -1; size_t page_size_; std::string path_; @@ -23,29 +22,31 @@ class BinaryFileStager : public AbstractStager { /** Destructor */ ~BinaryFileStager() {} - /** Build file url */ - static hshm::charbuf BuildFileUrl(const std::string &path, size_t page_size) { - std::stringstream ss; - ss << "file://" << path << ":" << page_size; - return hshm::charbuf(ss.str()); + /** Build context for staging */ + static Context BuildContext(size_t page_size) { + Context ctx; + ctx.flags_.SetBits(HERMES_SHOULD_STAGE); + ctx.bkt_params_ = BuildFileParams(page_size); + return ctx; } - /** Parse file url */ - static void ParseFileUrl(const std::string &url, std::string &path, size_t &page_size) { - // Parse url - std::string protocol, action; - std::vector tokens; - Client::GetUrlProtocolAndAction(url, protocol, action, tokens); - // file://[path]:[page_size] - if (protocol == "file") { - path = tokens[0]; - page_size = std::stoul(tokens[1]); - } + /** Build serialized file parameter pack */ + static std::string BuildFileParams(size_t page_size) { + std::string params; + hrun::LocalSerialize srl(params); + srl << std::string("file"); + srl << page_size; + return params; } /** Create the data stager payload */ void RegisterStager(RegisterStagerTask *task, RunContext &rctx) override { - ParseFileUrl(task->url_->str(), path_, page_size_); + std::string params = task->params_->str(); + std::string protocol; + hrun::LocalDeserialize srl(params); + srl >> protocol; + srl >> page_size_; + path_ = task->tag_name_->str(); } /** Stage data in from remote source */ @@ -53,30 +54,31 @@ class BinaryFileStager : public AbstractStager { adapter::BlobPlacement plcmnt; plcmnt.DecodeBlobName(*task->blob_name_, page_size_); HILOG(kDebug, "Attempting to stage {} bytes from the backend file {} at offset {}", - page_size_, url_, plcmnt.bucket_off_); + page_size_, path_, plcmnt.bucket_off_); LPointer blob = HRUN_CLIENT->AllocateBufferServer(page_size_); - fd_ = HERMES_POSIX_API->open(path_.c_str(), O_CREAT | O_RDWR, 0666); - if (fd_ < 0) { + int fd = HERMES_POSIX_API->open(path_.c_str(), O_CREAT | O_RDWR, 0666); + if (fd < 0) { HELOG(kError, "Failed to open file {}", path_); return; } - ssize_t real_size = HERMES_POSIX_API->pread(fd_, + ssize_t real_size = HERMES_POSIX_API->pread(fd, blob.ptr_, page_size_, (off_t)plcmnt.bucket_off_); + HERMES_POSIX_API->close(fd); if (real_size < 0) { HELOG(kError, "Failed to stage in {} bytes from {}", - page_size_, url_); + page_size_, path_); return; } else if (real_size == 0) { return; } HILOG(kDebug, "Staged {} bytes from the backend file {}", - real_size, url_); + real_size, path_); HILOG(kDebug, "Submitting put blob {} ({}) to blob mdm ({})", task->blob_name_->str(), task->bkt_id_, blob_mdm.id_) hapi::Context ctx; - ctx.flags_.SetBits(HERMES_IS_FILE); + ctx.flags_.SetBits(HERMES_SHOULD_STAGE); LPointer put_task = blob_mdm.AsyncPutBlob(task->task_node_ + 1, task->bkt_id_, @@ -93,24 +95,24 @@ class BinaryFileStager : public AbstractStager { adapter::BlobPlacement plcmnt; plcmnt.DecodeBlobName(*task->blob_name_, page_size_); HILOG(kDebug, "Attempting to stage {} bytes to the backend file {} at offset {}", - page_size_, url_, plcmnt.bucket_off_); + page_size_, path_, plcmnt.bucket_off_); char *data = HRUN_CLIENT->GetDataPointer(task->data_); - fd_ = HERMES_POSIX_API->open(path_.c_str(), O_CREAT | O_RDWR, 0666); - if (fd_ < 0) { + int fd = HERMES_POSIX_API->open(path_.c_str(), O_CREAT | O_RDWR, 0666); + if (fd < 0) { HELOG(kError, "Failed to open file {}", path_); return; } - ssize_t real_size = HERMES_POSIX_API->pwrite(fd_, + ssize_t real_size = HERMES_POSIX_API->pwrite(fd, data, task->data_size_, (off_t)plcmnt.bucket_off_); - HERMES_POSIX_API->close(fd_); + HERMES_POSIX_API->close(fd); if (real_size < 0) { HELOG(kError, "Failed to stage out {} bytes from {}", - task->data_size_, url_); + task->data_size_, path_); } HILOG(kDebug, "Staged out {} bytes to the backend file {}", - real_size, url_); + real_size, path_); } }; diff --git a/tasks/data_stager/include/data_stager/factory/stager_factory.h b/tasks/data_stager/include/data_stager/factory/stager_factory.h index 341b55964..ba37e5282 100644 --- a/tasks/data_stager/include/data_stager/factory/stager_factory.h +++ b/tasks/data_stager/include/data_stager/factory/stager_factory.h @@ -13,16 +13,22 @@ namespace hermes::data_stager { class StagerFactory { public: - static std::unique_ptr Get(const std::string &url) { + static std::unique_ptr Get(const std::string &path, + const std::string ¶ms) { + std::string protocol; + hrun::LocalDeserialize srl(params); + srl >> protocol; + std::unique_ptr stager; - if (url.find("file://") == 0) { + if (protocol == "file") { stager = std::make_unique(); - } else if (url.find("parquet://")) { - } else if (url.find("hdf5://")) { + } else if (protocol == "parquet") { + } else if (protocol == "hdf5") { } else { throw std::runtime_error("Unknown stager type"); } - stager->url_ = url; + stager->path_ = path; + stager->params_ = params; return stager; } }; diff --git a/tasks/data_stager/src/data_stager.cc b/tasks/data_stager/src/data_stager.cc index 348ed0ec3..710658748 100644 --- a/tasks/data_stager/src/data_stager.cc +++ b/tasks/data_stager/src/data_stager.cc @@ -40,8 +40,10 @@ class Server : public TaskLib { /** Register a stager */ void RegisterStager(RegisterStagerTask *task, RunContext &rctx) { - std::string url = task->url_->str(); - std::unique_ptr stager = StagerFactory::Get(url); + std::string tag_name = task->tag_name_->str(); + std::string params = task->params_->str(); + HILOG(kDebug, "Registering stager {}: {}", task->bkt_id_, tag_name); + std::unique_ptr stager = StagerFactory::Get(tag_name, params); stager->RegisterStager(task, rctx); url_map_[rctx.lane_id_].emplace(task->bkt_id_, std::move(stager)); task->SetModuleComplete(); @@ -51,6 +53,7 @@ class Server : public TaskLib { /** Unregister stager */ void UnregisterStager(UnregisterStagerTask *task, RunContext &rctx) { + HILOG(kDebug, "Unregistering stager {}", task->bkt_id_); if (url_map_[rctx.lane_id_].find(task->bkt_id_) == url_map_[rctx.lane_id_].end()) { task->SetModuleComplete(); return; @@ -63,6 +66,7 @@ class Server : public TaskLib { /** Stage in data */ void StageIn(StageInTask *task, RunContext &rctx) { + // HILOG(kDebug, "Beginning stage in"); std::unordered_map>::iterator it = url_map_[rctx.lane_id_].find(task->bkt_id_); if (it == url_map_[rctx.lane_id_].end()) { diff --git a/tasks/hermes_blob_mdm/include/hermes_blob_mdm/hermes_blob_mdm.h b/tasks/hermes_blob_mdm/include/hermes_blob_mdm/hermes_blob_mdm.h index ba38e0d83..0e10d9b24 100644 --- a/tasks/hermes_blob_mdm/include/hermes_blob_mdm/hermes_blob_mdm.h +++ b/tasks/hermes_blob_mdm/include/hermes_blob_mdm/hermes_blob_mdm.h @@ -33,9 +33,10 @@ class Client : public TaskLibClient { id_ = TaskStateId::GetNull(); QueueManagerInfo &qm = HRUN_CLIENT->server_config_.queue_manager_; std::vector queue_info = { - {1, 1, qm.queue_depth_, 0}, - {1, 1, qm.queue_depth_, QUEUE_LONG_RUNNING}, - {qm.max_lanes_, qm.max_lanes_, qm.queue_depth_, QUEUE_LOW_LATENCY} + {TaskPrio::kAdmin, 1, 1, qm.queue_depth_, 0}, + {TaskPrio::kLongRunning, qm.max_lanes_, qm.max_lanes_, qm.queue_depth_, + QUEUE_LONG_RUNNING | QUEUE_TETHERED, TaskPrio::kLowLatency}, + {TaskPrio::kLowLatency, qm.max_lanes_, qm.max_lanes_, qm.queue_depth_, QUEUE_LOW_LATENCY} }; return HRUN_ADMIN->AsyncCreateTaskState( task_node, domain_id, state_name, id_, queue_info); diff --git a/tasks/hermes_blob_mdm/include/hermes_blob_mdm/hermes_blob_mdm_tasks.h b/tasks/hermes_blob_mdm/include/hermes_blob_mdm/hermes_blob_mdm_tasks.h index 29ac920f2..e7c662ecb 100644 --- a/tasks/hermes_blob_mdm/include/hermes_blob_mdm/hermes_blob_mdm_tasks.h +++ b/tasks/hermes_blob_mdm/include/hermes_blob_mdm/hermes_blob_mdm_tasks.h @@ -228,7 +228,7 @@ class PutBlobPhase { #define HERMES_BLOB_REPLACE BIT_OPT(u32, 0) #define HERMES_BLOB_APPEND BIT_OPT(u32, 1) #define HERMES_DID_STAGE_IN BIT_OPT(u32, 2) -#define HERMES_IS_FILE BIT_OPT(u32, 3) +#define HERMES_SHOULD_STAGE BIT_OPT(u32, 3) #define HERMES_BLOB_DID_CREATE BIT_OPT(u32, 4) #define HERMES_GET_BLOB_ID BIT_OPT(u32, 5) #define HERMES_HAS_DERIVED BIT_OPT(u32, 6) @@ -334,8 +334,8 @@ struct PutBlobTask : public Task, TaskFlags HSHM_ALWAYS_INLINE u32 GetGroup(hshm::charbuf &group) { hrun::LocalSerialize srl(group); - srl << tag_id_.unique_; - srl << tag_id_.node_id_; + srl << std::string("blob_op"); + srl << tag_id_; return 0; } }; @@ -354,7 +354,7 @@ struct GetBlobTask : public Task, TaskFlags INOUT BlobId blob_id_; IN size_t blob_off_; IN hipc::Pointer data_; - INOUT ssize_t data_size_; + INOUT size_t data_size_; IN bitfield32_t flags_; /** SHM default constructor */ @@ -371,7 +371,7 @@ struct GetBlobTask : public Task, TaskFlags const hshm::charbuf &blob_name, const BlobId &blob_id, size_t off, - ssize_t data_size, + size_t data_size, hipc::Pointer &data, const Context &ctx, u32 flags) : Task(alloc) { @@ -449,14 +449,15 @@ struct GetBlobTask : public Task, TaskFlags if (flags_.Any(HERMES_GET_BLOB_ID)) { ar(blob_id_); } + ar(data_size_); } /** Create group */ HSHM_ALWAYS_INLINE u32 GetGroup(hshm::charbuf &group) { hrun::LocalSerialize srl(group); - srl << tag_id_.unique_; - srl << tag_id_.node_id_; + srl << std::string("blob_op"); + srl << tag_id_; return 0; } }; @@ -511,8 +512,8 @@ struct TagBlobTask : public Task, TaskFlags { HSHM_ALWAYS_INLINE u32 GetGroup(hshm::charbuf &group) { hrun::LocalSerialize srl(group); - srl << tag_id_.unique_; - srl << tag_id_.node_id_; + srl << std::string("blob_op"); + srl << tag_id_; return 0; } }; @@ -572,8 +573,8 @@ struct BlobHasTagTask : public Task, TaskFlags { HSHM_ALWAYS_INLINE u32 GetGroup(hshm::charbuf &group) { hrun::LocalSerialize srl(group); - srl << tag_id_.unique_; - srl << tag_id_.node_id_; + srl << std::string("blob_op"); + srl << tag_id_; return 0; } }; @@ -634,8 +635,8 @@ struct GetBlobIdTask : public Task, TaskFlags { HSHM_ALWAYS_INLINE u32 GetGroup(hshm::charbuf &group) { hrun::LocalSerialize srl(group); - srl << tag_id_.unique_; - srl << tag_id_.node_id_; + srl << std::string("blob_op"); + srl << tag_id_; return 0; } }; @@ -697,8 +698,8 @@ struct GetBlobNameTask : public Task, TaskFlags { HSHM_ALWAYS_INLINE u32 GetGroup(hshm::charbuf &group) { hrun::LocalSerialize srl(group); - srl << tag_id_.unique_; - srl << tag_id_.node_id_; + srl << std::string("blob_op"); + srl << tag_id_; return 0; } }; @@ -765,8 +766,8 @@ struct GetBlobSizeTask : public Task, TaskFlags { HSHM_ALWAYS_INLINE u32 GetGroup(hshm::charbuf &group) { hrun::LocalSerialize srl(group); - srl << tag_id_.unique_; - srl << tag_id_.node_id_; + srl << std::string("blob_op"); + srl << tag_id_; return 0; } }; @@ -820,8 +821,8 @@ struct GetBlobScoreTask : public Task, TaskFlags { HSHM_ALWAYS_INLINE u32 GetGroup(hshm::charbuf &group) { hrun::LocalSerialize srl(group); - srl << tag_id_.unique_; - srl << tag_id_.node_id_; + srl << std::string("blob_op"); + srl << tag_id_; return 0; } }; @@ -881,8 +882,8 @@ struct GetBlobBuffersTask : public Task, TaskFlags { HSHM_ALWAYS_INLINE u32 GetGroup(hshm::charbuf &group) { hrun::LocalSerialize srl(group); - srl << tag_id_.unique_; - srl << tag_id_.node_id_; + srl << std::string("blob_op"); + srl << tag_id_; return 0; } }; @@ -946,8 +947,8 @@ struct RenameBlobTask : public Task, TaskFlags { HSHM_ALWAYS_INLINE u32 GetGroup(hshm::charbuf &group) { hrun::LocalSerialize srl(group); - srl << tag_id_.unique_; - srl << tag_id_.node_id_; + srl << std::string("blob_op"); + srl << tag_id_; return 0; } }; @@ -1002,8 +1003,8 @@ struct TruncateBlobTask : public Task, TaskFlags { HSHM_ALWAYS_INLINE u32 GetGroup(hshm::charbuf &group) { hrun::LocalSerialize srl(group); - srl << tag_id_.unique_; - srl << tag_id_.node_id_; + srl << std::string("blob_op"); + srl << tag_id_; return 0; } }; @@ -1066,8 +1067,8 @@ struct DestroyBlobTask : public Task, TaskFlags { HSHM_ALWAYS_INLINE u32 GetGroup(hshm::charbuf &group) { hrun::LocalSerialize srl(group); - srl << tag_id_.unique_; - srl << tag_id_.node_id_; + srl << std::string("blob_op"); + srl << tag_id_; return 0; } }; @@ -1141,8 +1142,8 @@ struct ReorganizeBlobTask : public Task, TaskFlags { HSHM_ALWAYS_INLINE u32 GetGroup(hshm::charbuf &group) { hrun::LocalSerialize srl(group); - srl << tag_id_.unique_; - srl << tag_id_.node_id_; + srl << std::string("blob_op"); + srl << tag_id_; return 0; } }; @@ -1170,7 +1171,7 @@ struct FlushDataTask : public Task, TaskFlags { TASK_LONG_RUNNING | TASK_COROUTINE | TASK_REMOTE_DEBUG_MARK); - SetPeriodMs(5); // TODO(llogan): don't hardcode this + SetPeriodSec(5); // TODO(llogan): don't hardcode this domain_id_ = DomainId::GetLocal(); } diff --git a/tasks/hermes_blob_mdm/src/hermes_blob_mdm.cc b/tasks/hermes_blob_mdm/src/hermes_blob_mdm.cc index b16307abd..2f156f265 100644 --- a/tasks/hermes_blob_mdm/src/hermes_blob_mdm.cc +++ b/tasks/hermes_blob_mdm/src/hermes_blob_mdm.cc @@ -125,8 +125,7 @@ class Server : public TaskLib { const hshm::charbuf GetBlobNameWithBucket(TagId tag_id, const hshm::charbuf &blob_name) { hshm::charbuf new_name(sizeof(TagId) + blob_name.size()); hrun::LocalSerialize srl(new_name); - srl << tag_id.node_id_; - srl << tag_id.unique_; + srl << tag_id; srl << blob_name; return new_name; } @@ -254,11 +253,18 @@ class Server : public TaskLib { * Long-running task to stage out data periodically and * reorganize blobs * */ + struct FlushInfo { + BlobInfo *blob_info_; + LPointer stage_task_; + size_t mod_count_; + }; void FlushData(FlushDataTask *task, RunContext &rctx) { hshm::Timepoint now; now.Now(); // Get the blob info data structure BLOB_MAP_T &blob_map = blob_map_[rctx.lane_id_]; + std::vector stage_tasks; + stage_tasks.reserve(256); for (auto &it : blob_map) { BlobInfo &blob_info = it.second; // Update blob scores @@ -277,11 +283,13 @@ class Server : public TaskLib { blob_info.access_freq_ = 0; // Flush data - size_t mod_count = blob_info.mod_count_; + FlushInfo flush_info; + flush_info.blob_info_ = &blob_info; + flush_info.mod_count_ = blob_info.mod_count_; if (blob_info.last_flush_ > 0 && - mod_count > blob_info.last_flush_) { + flush_info.mod_count_ > blob_info.last_flush_) { HILOG(kDebug, "Flushing blob {} (mod_count={}, last_flush={})", - blob_info.blob_id_, blob_info.mod_count_, blob_info.last_flush_); + blob_info.blob_id_, flush_info.mod_count_, blob_info.last_flush_); LPointer data = HRUN_CLIENT->AllocateBufferServer( blob_info.blob_size_, task); LPointer get_blob = @@ -292,13 +300,25 @@ class Server : public TaskLib { 0, blob_info.blob_size_, data.shm_); get_blob->Wait(task); - stager_mdm_.AsyncStageOut(task->task_node_ + 1, - blob_info.tag_id_, - blob_info.name_, - data.shm_, blob_info.blob_size_, - TASK_DATA_OWNER | TASK_FIRE_AND_FORGET); - blob_info.last_flush_ = mod_count; + HRUN_CLIENT->DelTask(get_blob); + flush_info.stage_task_ = + stager_mdm_.AsyncStageOut(task->task_node_ + 1, + blob_info.tag_id_, + blob_info.name_, + data.shm_, blob_info.blob_size_, + TASK_DATA_OWNER); + stage_tasks.emplace_back(flush_info); } + if (stage_tasks.size() == 256) { + break; + } + } + + for (FlushInfo &flush_info : stage_tasks) { + BlobInfo &blob_info = *flush_info.blob_info_; + flush_info.stage_task_->Wait(task); + blob_info.last_flush_ = flush_info.mod_count_; + HRUN_CLIENT->DelTask(flush_info.stage_task_); } } void MonitorFlushData(u32 mode, FlushDataTask *task, RunContext &rctx) { @@ -307,7 +327,7 @@ class Server : public TaskLib { BlobInfo &blob_info = it.second; if (blob_info.last_flush_ > 0 && blob_info.mod_count_ > blob_info.last_flush_) { - rctx.flush_->pending_ += 1; + rctx.flush_->count_ += 1; return; } } @@ -323,15 +343,16 @@ class Server : public TaskLib { task->blob_id_ = GetOrCreateBlobId(task->tag_id_, task->lane_hash_, blob_name, rctx, task->flags_); } - HILOG(kDebug, "Beginning PUT for {}", blob_name.str()); + HILOG(kDebug, "Beginning PUT for (hash: {}) {}", + std::hash{}(blob_name), blob_name.str()); BLOB_MAP_T &blob_map = blob_map_[rctx.lane_id_]; BlobInfo &blob_info = blob_map[task->blob_id_]; blob_info.score_ = task->score_; blob_info.user_score_ = task->score_; // Stage Blob - if (task->flags_.Any(HERMES_IS_FILE) && blob_info.last_flush_ == 0) { - blob_info.mod_count_ = 1; + if (task->flags_.Any(HERMES_SHOULD_STAGE) && blob_info.last_flush_ == 0) { + HILOG(kDebug, "This file has not yet been flushed"); blob_info.last_flush_ = 1; LPointer stage_task = stager_mdm_.AsyncStageIn(task->task_node_ + 1, @@ -339,8 +360,13 @@ class Server : public TaskLib { blob_info.name_, task->score_, 0); stage_task->Wait(task); + blob_info.mod_count_ = 1; HRUN_CLIENT->DelTask(stage_task); } + if (task->flags_.Any(HERMES_SHOULD_STAGE)) { + HILOG(kDebug, "This is marked as a file: {} {}", + blob_info.mod_count_, blob_info.last_flush_); + } ssize_t bkt_size_diff = 0; if (task->flags_.Any(HERMES_BLOB_REPLACE)) { bkt_size_diff -= blob_info.blob_size_; @@ -440,7 +466,7 @@ class Server : public TaskLib { } // Update information - if (task->flags_.Any(HERMES_IS_FILE)) { + if (task->flags_.Any(HERMES_SHOULD_STAGE)) { // TODO(llogan): Move to data stager adapter::BlobPlacement p; std::string blob_name_str = task->blob_name_->str(); @@ -502,9 +528,8 @@ class Server : public TaskLib { BlobInfo &blob_info = blob_map[task->blob_id_]; // Stage Blob - if (task->flags_.Any(HERMES_IS_FILE) && blob_info.last_flush_ == 0) { + if (task->flags_.Any(HERMES_SHOULD_STAGE) && blob_info.last_flush_ == 0) { // TODO(llogan): Don't hardcore score = 1 - blob_info.mod_count_ = 1; blob_info.last_flush_ = 1; LPointer stage_task = stager_mdm_.AsyncStageIn(task->task_node_ + 1, @@ -556,6 +581,7 @@ class Server : public TaskLib { read_task->Wait(task); HRUN_CLIENT->DelTask(read_task); } + task->data_size_ = buf_off; task->SetModuleComplete(); } void MonitorGetBlob(u32 mode, GetBlobTask *task, RunContext &rctx) { @@ -613,7 +639,7 @@ class Server : public TaskLib { BLOB_MAP_T &blob_map = blob_map_[rctx.lane_id_]; blob_map.emplace(blob_id, BlobInfo()); BlobInfo &blob_info = blob_map[blob_id]; - blob_info.name_ = std::move(blob_name); + blob_info.name_ = blob_name; blob_info.blob_id_ = blob_id; blob_info.tag_id_ = tag_id; blob_info.blob_size_ = 0; @@ -622,7 +648,6 @@ class Server : public TaskLib { blob_info.mod_count_ = 0; blob_info.access_freq_ = 0; blob_info.last_flush_ = 0; - blob_info.UpdateWriteStats(); return blob_id; } return it->second; diff --git a/tasks/hermes_bucket_mdm/include/hermes_bucket_mdm/hermes_bucket_mdm.h b/tasks/hermes_bucket_mdm/include/hermes_bucket_mdm/hermes_bucket_mdm.h index 985e95436..fac654df6 100644 --- a/tasks/hermes_bucket_mdm/include/hermes_bucket_mdm/hermes_bucket_mdm.h +++ b/tasks/hermes_bucket_mdm/include/hermes_bucket_mdm/hermes_bucket_mdm.h @@ -25,9 +25,9 @@ class Client : public TaskLibClient { id_ = TaskStateId::GetNull(); QueueManagerInfo &qm = HRUN_CLIENT->server_config_.queue_manager_; std::vector queue_info = { - {1, 1, qm.queue_depth_, 0}, - {1, 1, qm.queue_depth_, QUEUE_LONG_RUNNING}, - {qm.max_lanes_, qm.max_lanes_, qm.queue_depth_, QUEUE_LOW_LATENCY} + {TaskPrio::kAdmin, 1, 1, qm.queue_depth_, 0}, + {TaskPrio::kLongRunning, 1, 1, qm.queue_depth_, QUEUE_LONG_RUNNING}, + {TaskPrio::kLowLatency, qm.max_lanes_, qm.max_lanes_, qm.queue_depth_, QUEUE_LOW_LATENCY} }; id_ = HRUN_ADMIN->CreateTaskStateRoot( domain_id, state_name, id_, queue_info); @@ -125,21 +125,22 @@ class Client : public TaskLibClient { bool blob_owner, const std::vector &traits, size_t backend_size, - u32 flags) { + u32 flags, + const Context &ctx = Context()) { HILOG(kDebug, "Creating a tag {}", tag_name.str()); - u32 hash = std::hash{}(tag_name); HRUN_CLIENT->ConstructTask( - task, task_node, DomainId::GetNode(HASH_TO_NODE_ID(hash)), id_, - tag_name, blob_owner, traits, backend_size, flags); + task, task_node, id_, + tag_name, blob_owner, traits, backend_size, flags, ctx); } HSHM_ALWAYS_INLINE TagId GetOrCreateTagRoot(const hshm::charbuf &tag_name, bool blob_owner, const std::vector &traits, size_t backend_size, - u32 flags) { + u32 flags, + const Context &ctx = Context()) { LPointer> push_task = - AsyncGetOrCreateTagRoot(tag_name, blob_owner, traits, backend_size, flags); + AsyncGetOrCreateTagRoot(tag_name, blob_owner, traits, backend_size, flags, ctx); push_task->Wait(); GetOrCreateTagTask *task = push_task->get(); TagId tag_id = task->tag_id_; diff --git a/tasks/hermes_bucket_mdm/include/hermes_bucket_mdm/hermes_bucket_mdm_tasks.h b/tasks/hermes_bucket_mdm/include/hermes_bucket_mdm/hermes_bucket_mdm_tasks.h index b56d79a11..1abbbc12e 100644 --- a/tasks/hermes_bucket_mdm/include/hermes_bucket_mdm/hermes_bucket_mdm_tasks.h +++ b/tasks/hermes_bucket_mdm/include/hermes_bucket_mdm/hermes_bucket_mdm_tasks.h @@ -15,12 +15,14 @@ #include "hrun/api/hrun_client.h" #include "hrun/hrun_namespace.h" #include "proc_queue/proc_queue.h" +#include "data_stager/data_stager.h" namespace hermes::bucket_mdm { #include "hermes_bucket_mdm_methods.h" #include "hrun/hrun_namespace.h" + /** * A task to create hermes_bucket_mdm * */ @@ -190,8 +192,8 @@ struct UpdateSizeTask : public Task, TaskFlags { HSHM_ALWAYS_INLINE u32 GetGroup(hshm::charbuf &group) { hrun::LocalSerialize srl(group); - srl << tag_id_.unique_; - srl << tag_id_.node_id_; + srl << task_state_; + srl << lane_hash_; return 0; } }; @@ -275,8 +277,8 @@ struct AppendBlobSchemaTask : public Task, TaskFlags { HSHM_ALWAYS_INLINE u32 GetGroup(hshm::charbuf &group) { hrun::LocalSerialize srl(group); - srl << tag_id_.unique_; - srl << tag_id_.node_id_; + srl << std::string("blob_op"); + srl << tag_id_; return 0; } }; @@ -338,8 +340,8 @@ struct AppendBlobTask : public Task, TaskFlags { HSHM_ALWAYS_INLINE u32 GetGroup(hshm::charbuf &group) { hrun::LocalSerialize srl(group); - srl << tag_id_.unique_; - srl << tag_id_.node_id_; + srl << std::string("blob_op"); + srl << tag_id_; return 0; } }; @@ -347,6 +349,7 @@ struct AppendBlobTask : public Task, TaskFlags { /** A task to get or create a tag */ struct GetOrCreateTagTask : public Task, TaskFlags { IN hipc::ShmArchive tag_name_; + IN hipc::ShmArchive params_; IN bool blob_owner_; IN hipc::ShmArchive> traits_; IN size_t backend_size_; @@ -361,13 +364,13 @@ struct GetOrCreateTagTask : public Task, TaskFlags { HSHM_ALWAYS_INLINE explicit GetOrCreateTagTask(hipc::Allocator *alloc, const TaskNode &task_node, - const DomainId &domain_id, const TaskStateId &state_id, const hshm::charbuf &tag_name, bool blob_owner, const std::vector &traits, size_t backend_size, - u32 flags) : Task(alloc) { + u32 flags, + const Context &ctx) : Task(alloc) { // Initialize task task_node_ = task_node; lane_hash_ = std::hash{}(tag_name); @@ -375,20 +378,22 @@ struct GetOrCreateTagTask : public Task, TaskFlags { task_state_ = state_id; method_ = Method::kGetOrCreateTag; task_flags_.SetBits(TASK_LOW_LATENCY); - domain_id_ = domain_id; + domain_id_ = DomainId::GetNode(HASH_TO_NODE_ID(lane_hash_)); // Custom params blob_owner_ = blob_owner; backend_size_ = backend_size; HSHM_MAKE_AR(tag_name_, alloc, tag_name) HSHM_MAKE_AR(traits_, alloc, traits) - flags_ = bitfield32_t(flags); + HSHM_MAKE_AR(params_, alloc, ctx.bkt_params_) + flags_ = bitfield32_t(flags | ctx.flags_.bits_); } /** Destructor */ ~GetOrCreateTagTask() { HSHM_DESTROY_AR(tag_name_) HSHM_DESTROY_AR(traits_) + HSHM_DESTROY_AR(params_) } /** (De)serialize message call */ @@ -407,8 +412,9 @@ struct GetOrCreateTagTask : public Task, TaskFlags { /** Create group */ HSHM_ALWAYS_INLINE u32 GetGroup(hshm::charbuf &group) { - group.resize(tag_name_->size()); - memcpy(group.data(), tag_name_->data(), tag_name_->size()); + hrun::LocalSerialize srl(group); + srl << task_state_; + srl << lane_hash_; return 0; } }; @@ -463,8 +469,9 @@ struct GetTagIdTask : public Task, TaskFlags { /** Create group */ HSHM_ALWAYS_INLINE u32 GetGroup(hshm::charbuf &group) { - group.resize(tag_name_->size()); - memcpy(group.data(), tag_name_->data(), tag_name_->size()); + hrun::LocalSerialize srl(group); + srl << task_state_; + srl << lane_hash_; return 0; } }; @@ -520,8 +527,8 @@ struct GetTagNameTask : public Task, TaskFlags { HSHM_ALWAYS_INLINE u32 GetGroup(hshm::charbuf &group) { hrun::LocalSerialize srl(group); - srl << tag_id_.unique_; - srl << tag_id_.node_id_; + srl << task_state_; + srl << lane_hash_; return 0; } }; @@ -579,8 +586,8 @@ struct RenameTagTask : public Task, TaskFlags { HSHM_ALWAYS_INLINE u32 GetGroup(hshm::charbuf &group) { hrun::LocalSerialize srl(group); - srl << tag_id_.unique_; - srl << tag_id_.node_id_; + srl << task_state_; + srl << lane_hash_; return 0; } }; @@ -607,7 +614,7 @@ struct DestroyTagTask : public Task, TaskFlags { const TaskNode &task_node, const DomainId &domain_id, const TaskStateId &state_id, - TagId tag_id) : Task(alloc) { + const TagId &tag_id) : Task(alloc) { // Initialize task task_node_ = task_node; lane_hash_ = tag_id.hash_; @@ -636,8 +643,8 @@ struct DestroyTagTask : public Task, TaskFlags { HSHM_ALWAYS_INLINE u32 GetGroup(hshm::charbuf &group) { hrun::LocalSerialize srl(group); - srl << tag_id_.unique_; - srl << tag_id_.node_id_; + srl << task_state_; + srl << lane_hash_; return 0; } }; @@ -688,8 +695,8 @@ struct TagAddBlobTask : public Task, TaskFlags { HSHM_ALWAYS_INLINE u32 GetGroup(hshm::charbuf &group) { hrun::LocalSerialize srl(group); - srl << tag_id_.unique_; - srl << tag_id_.node_id_; + srl << task_state_; + srl << lane_hash_; return 0; } }; @@ -740,8 +747,8 @@ struct TagRemoveBlobTask : public Task, TaskFlags { HSHM_ALWAYS_INLINE u32 GetGroup(hshm::charbuf &group) { hrun::LocalSerialize srl(group); - srl << tag_id_.unique_; - srl << tag_id_.node_id_; + srl << task_state_; + srl << lane_hash_; return 0; } }; @@ -798,8 +805,8 @@ struct TagClearBlobsTask : public Task, TaskFlags { HSHM_ALWAYS_INLINE u32 GetGroup(hshm::charbuf &group) { hrun::LocalSerialize srl(group); - srl << tag_id_.unique_; - srl << tag_id_.node_id_; + srl << task_state_; + srl << lane_hash_; return 0; } }; @@ -850,8 +857,8 @@ struct GetSizeTask : public Task, TaskFlags { HSHM_ALWAYS_INLINE u32 GetGroup(hshm::charbuf &group) { hrun::LocalSerialize srl(group); - srl << tag_id_.unique_; - srl << tag_id_.node_id_; + srl << task_state_; + srl << lane_hash_; return 0; } }; @@ -908,8 +915,8 @@ struct GetContainedBlobIdsTask : public Task, TaskFlags { HSHM_ALWAYS_INLINE u32 GetGroup(hshm::charbuf &group) { hrun::LocalSerialize srl(group); - srl << tag_id_.unique_; - srl << tag_id_.node_id_; + srl << task_state_; + srl << lane_hash_; return 0; } }; diff --git a/tasks/hermes_bucket_mdm/src/hermes_bucket_mdm.cc b/tasks/hermes_bucket_mdm/src/hermes_bucket_mdm.cc index 3a93ad8a8..e0b79bc4c 100644 --- a/tasks/hermes_bucket_mdm/src/hermes_bucket_mdm.cc +++ b/tasks/hermes_bucket_mdm/src/hermes_bucket_mdm.cc @@ -168,8 +168,8 @@ class Server : public TaskLib { HRUN_CLIENT->node_id_, append.blob_name_.str(), append.data_size_, task->tag_id_, task->task_node_, blob_mdm_.id_); Context ctx; - if (tag_info.flags_.Any(HERMES_IS_FILE)) { - ctx.flags_.SetBits(HERMES_IS_FILE); + if (tag_info.flags_.Any(HERMES_SHOULD_STAGE)) { + ctx.flags_.SetBits(HERMES_SHOULD_STAGE); } append.put_task_ = blob_mdm_.AsyncPutBlob(task->task_node_ + 1, task->tag_id_, @@ -236,11 +236,12 @@ class Server : public TaskLib { tag_info.tag_id_ = tag_id; tag_info.owner_ = task->blob_owner_; tag_info.internal_size_ = task->backend_size_; - if (task->flags_.Any(HERMES_IS_FILE)) { + if (task->flags_.Any(HERMES_SHOULD_STAGE)) { stager_mdm_.AsyncRegisterStager(task->task_node_ + 1, tag_id, - hshm::charbuf(task->tag_name_->str())); - tag_info.flags_.SetBits(HERMES_IS_FILE); + hshm::charbuf(task->tag_name_->str()), + hshm::charbuf(task->params_->str())); + tag_info.flags_.SetBits(HERMES_SHOULD_STAGE); } } else { if (tag_name.size()) { @@ -322,6 +323,7 @@ class Server : public TaskLib { } stager_mdm_.AsyncUnregisterStager(task->task_node_ + 1, task->tag_id_); + HILOG(kInfo, "Destroying the tag: {}", tag.name_.str()); task->phase_ = DestroyTagPhase::kWaitDestroyBlobs; return; } @@ -338,6 +340,7 @@ class Server : public TaskLib { HSHM_DESTROY_AR(task->destroy_blob_tasks_); TAG_MAP_T &tag_map = tag_map_[rctx.lane_id_]; tag_map.erase(task->tag_id_); + HILOG(kInfo, "Finished destroying the tag"); task->SetModuleComplete(); } } diff --git a/tasks/hermes_data_op/include/hermes_data_op/hermes_data_op.h b/tasks/hermes_data_op/include/hermes_data_op/hermes_data_op.h index 54c583f2d..2f503f6c4 100644 --- a/tasks/hermes_data_op/include/hermes_data_op/hermes_data_op.h +++ b/tasks/hermes_data_op/include/hermes_data_op/hermes_data_op.h @@ -29,9 +29,9 @@ class Client : public TaskLibClient { id_ = TaskStateId::GetNull(); QueueManagerInfo &qm = HRUN_CLIENT->server_config_.queue_manager_; std::vector queue_info = { - {1, 1, qm.queue_depth_, 0}, - {1, 1, qm.queue_depth_, QUEUE_LONG_RUNNING}, - {qm.max_lanes_, qm.max_lanes_, qm.queue_depth_, QUEUE_LOW_LATENCY} + {TaskPrio::kAdmin, 1, 1, qm.queue_depth_, 0}, + {TaskPrio::kLongRunning, 1, 1, qm.queue_depth_, QUEUE_LONG_RUNNING}, + {TaskPrio::kLowLatency, qm.max_lanes_, qm.max_lanes_, qm.queue_depth_, QUEUE_LOW_LATENCY} }; return HRUN_ADMIN->AsyncCreateTaskState( task_node, domain_id, state_name, id_, queue_info, diff --git a/tasks/hermes_mdm/include/hermes_mdm/hermes_mdm.h b/tasks/hermes_mdm/include/hermes_mdm/hermes_mdm.h index 0420c3629..c3deddb71 100644 --- a/tasks/hermes_mdm/include/hermes_mdm/hermes_mdm.h +++ b/tasks/hermes_mdm/include/hermes_mdm/hermes_mdm.h @@ -24,7 +24,7 @@ class Client : public TaskLibClient { const std::string &state_name) { id_ = TaskStateId::GetNull(); std::vector queue_info = { - {1, 1, 1, 0}, + {TaskPrio::kAdmin, 1, 1, 1, 0}, }; id_ = HRUN_ADMIN->CreateTaskStateRoot( domain_id, state_name, id_, queue_info); diff --git a/test/unit/hermes/CMakeLists.txt b/test/unit/hermes/CMakeLists.txt index a0ab24237..e74e0d63f 100644 --- a/test/unit/hermes/CMakeLists.txt +++ b/test/unit/hermes/CMakeLists.txt @@ -16,6 +16,7 @@ add_dependencies(test_hermes_exec ${Hermes_CLIENT_DEPS} hermes) target_link_libraries(test_hermes_exec ${Hermes_CLIENT_LIBRARIES} hermes Catch2::Catch2 MPI::MPI_CXX) +jarvis_test(test_hermes test_hermes) #------------------------------------------------------------------------------ # Test Cases @@ -40,5 +41,5 @@ install(TARGETS # Coverage #----------------------------------------------------------------------------- if(HERMES_ENABLE_COVERAGE) - set_coverage_flags(test_messages) + set_coverage_flags(test_hermes_exec) endif() diff --git a/test/unit/hermes/test_bucket.cc b/test/unit/hermes/test_bucket.cc index ec8d09dd9..6f5a60ce6 100644 --- a/test/unit/hermes/test_bucket.cc +++ b/test/unit/hermes/test_bucket.cc @@ -120,36 +120,6 @@ TEST_CASE("TestHermesAsyncPut") { HRUN_ADMIN->FlushRoot(DomainId::GetGlobal()); } -TEST_CASE("TestHermesAsyncPutLocalFlush") { - int rank, nprocs; - MPI_Barrier(MPI_COMM_WORLD); - MPI_Comm_rank(MPI_COMM_WORLD, &rank); - MPI_Comm_size(MPI_COMM_WORLD, &nprocs); - - // Initialize Hermes on all nodes - HERMES->ClientInit(); - - // Create a bucket - hermes::Context ctx; - hermes::Bucket bkt("hello"); - - size_t count_per_proc = 256; - size_t off = rank * count_per_proc; - size_t proc_count = off + count_per_proc; - for (size_t i = off; i < proc_count; ++i) { - HILOG(kInfo, "Iteration: {}", i); - // Put a blob - hermes::Blob blob(MEGABYTES(1)); - memset(blob.data(), i % 256, blob.size()); - bkt.AsyncPut(std::to_string(i), blob, ctx); - } - MPI_Barrier(MPI_COMM_WORLD); - if (rank == 0) { - HRUN_ADMIN->FlushRoot(DomainId::GetLocal()); - } - MPI_Barrier(MPI_COMM_WORLD); -} - TEST_CASE("TestHermesPutGet") { int rank, nprocs; MPI_Barrier(MPI_COMM_WORLD); @@ -523,11 +493,8 @@ TEST_CASE("TestHermesDataStager") { // Create a stageable bucket using hermes::data_stager::BinaryFileStager; - hermes::Context ctx; - ctx.flags_.SetBits(HERMES_IS_FILE); - hshm::charbuf url = - BinaryFileStager::BuildFileUrl(path, page_size); - hermes::Bucket bkt(url.str(), file_size, HERMES_IS_FILE); + hermes::Context ctx = BinaryFileStager::BuildContext(page_size); + hermes::Bucket bkt(path, ctx, file_size); // Put a few blobs in the bucket for (size_t i = off; i < proc_count; ++i) { @@ -567,7 +534,6 @@ TEST_CASE("TestHermesDataOp") { HERMES->ClientInit(); // Create a bucket that supports derived quantities - using hermes::data_stager::BinaryFileStager; hermes::Context ctx; ctx.flags_.SetBits(HERMES_HAS_DERIVED); std::string url = "data_bkt"; @@ -605,19 +571,12 @@ TEST_CASE("TestHermesDataOp") { } MPI_Barrier(MPI_COMM_WORLD); - // HRUN_ADMIN->FlushRoot(DomainId::GetGlobal()); + HRUN_ADMIN->FlushRoot(DomainId::GetGlobal()); // Verify derived operator happens hermes::Bucket bkt_min("data_bkt_min", 0, 0); - size_t size; - do { - size = bkt_min.GetSize(); - if (size != sizeof(float) * count_per_proc * nprocs) { - HILOG(kInfo, "Waiting for derived data"); - sleep(1); - } else { - break; - } - } while (true); + HRUN_ADMIN->FlushRoot(DomainId::GetGlobal()); + size_t size = bkt_min.GetSize(); + REQUIRE(size == sizeof(float) * count_per_proc * nprocs); hermes::Blob blob2; bkt_min.Get(std::to_string(0), blob2, ctx); @@ -655,10 +614,11 @@ TEST_CASE("TestHermesCollectMetadata") { hermes::MetadataTable table = HERMES->CollectMetadataSnapshot(); REQUIRE(table.blob_info_.size() == 1024 * nprocs); REQUIRE(table.bkt_info_.size() == nprocs); - REQUIRE(table.target_info_.size() >= 4); + // REQUIRE(table.target_info_.size() >= 4); MPI_Barrier(MPI_COMM_WORLD); } +/* TEST_CASE("TestHermesDataPlacement") { int rank, nprocs; MPI_Barrier(MPI_COMM_WORLD); @@ -757,3 +717,4 @@ TEST_CASE("TestHermesDataPlacementFancy") { count += 1; } } +*/ diff --git a/test/unit/hermes_adapters/CMakeLists.txt b/test/unit/hermes_adapters/CMakeLists.txt index 839f6f6c3..a16722b6c 100644 --- a/test/unit/hermes_adapters/CMakeLists.txt +++ b/test/unit/hermes_adapters/CMakeLists.txt @@ -1,5 +1,4 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DHERMES_PRELOAD -DHERMES_RPC_THALLIUM") -set(ADAPTER_COMMON ${CMAKE_CURRENT_SOURCE_DIR}/catch_config.h) set(HERMES_ADAPTER_TEST_DIR ${HERMES_ADAPTER_DIR}/test) include_directories(${CMAKE_CURRENT_SOURCE_DIR}) @@ -19,7 +18,7 @@ if(HERMES_ENABLE_STDIO_ADAPTER) endif() if(HERMES_ENABLE_MPIIO_ADAPTER) - # add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/mpiio) + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/mpiio) endif() if(HERMES_ENABLE_PUBSUB_ADAPTER) @@ -27,5 +26,5 @@ if(HERMES_ENABLE_PUBSUB_ADAPTER) endif() if(HERMES_ENABLE_VFD) - # add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/vfd) + add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/vfd) endif() \ No newline at end of file diff --git a/test/unit/hermes_adapters/adapter_test_utils.h b/test/unit/hermes_adapters/adapter_test_utils.h index bfdfe9f7d..e2f76d4fe 100644 --- a/test/unit/hermes_adapters/adapter_test_utils.h +++ b/test/unit/hermes_adapters/adapter_test_utils.h @@ -17,45 +17,8 @@ #include #include -bool FilesystemSupportsTmpfile() { - bool result = false; - -#if O_TMPFILE - // NOTE(chogan): Even if O_TMPFILE is defined, the underlying filesystem might - // not support it. - int tmp_fd = open("/tmp", O_WRONLY | O_TMPFILE, 0600); - if (tmp_fd > 0) { - result = true; - close(tmp_fd); - } -#endif - - return result; -} - -size_t GetRandomOffset(size_t i, unsigned int offset_seed, size_t stride, - size_t total_size) { - return abs((int)(((i * rand_r(&offset_seed)) % stride) % total_size)); -} - -std::string GenRandom(const int len) { - std::string tmp_s; - static const char alphanum[] = - "0123456789" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz"; - - srand(100); - - tmp_s.reserve(len); - - for (int i = 0; i < len; ++i) { - tmp_s += alphanum[rand() % (sizeof(alphanum) - 1)]; - } - - tmp_s[len - 1] = '\n'; - - return tmp_s; -} +#define CATCH_CONFIG_RUNNER +#include +namespace cl = Catch::Clara; #endif // HERMES_ADAPTER_TEST_UTILS_H diff --git a/test/unit/hermes_adapters/binary_file_tests.h b/test/unit/hermes_adapters/binary_file_tests.h new file mode 100644 index 000000000..829d4dc40 --- /dev/null +++ b/test/unit/hermes_adapters/binary_file_tests.h @@ -0,0 +1,77 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Distributed under BSD 3-Clause license. * + * Copyright by The HDF Group. * + * Copyright by the Illinois Institute of Technology. * + * All rights reserved. * + * * + * This file is part of Hermes. The full Hermes copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the top directory. If you do not * + * have access to the file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef HERMES_TEST_UNIT_HERMES_ADAPTERS_BINARY_FILE_TESTS_H_ +#define HERMES_TEST_UNIT_HERMES_ADAPTERS_BINARY_FILE_TESTS_H_ + +#include "filesystem_tests.h" + +namespace hermes::adapter::test { + +class BinaryFileTests : public FilesystemTests { + public: + std::vector GenerateData() override { + return GenRandom(total_size_, 200); + } + + void CreateFile(const std::string &path, + std::vector &data) override { + int fd = open(path.c_str(), O_CREAT | O_TRUNC | O_RDWR, 0666); + if (fd == -1) { + HELOG(kFatal, "Failed to open file: {}", path); + } + int ret = write(fd, data.data(), data.size()); + if (ret != data.size()) { + return; + } + close(fd); + REQUIRE(stdfs::file_size(path) == data.size()); + HILOG(kInfo, "Created file {}", path); + } + + void CompareFiles(FileInfo &info) override { + size_t cmp_size = stdfs::file_size(info.cmp_); + size_t hermes_size = stdfs::file_size(info.hermes_); + REQUIRE(cmp_size == hermes_size); + std::vector d1(cmp_size, '0'); + std::vector d2(hermes_size, '1'); + LoadFile(info.cmp_, d1); + LoadFile(info.hermes_, d2); + CompareBuffers(d1, d2); + } + + private: + void LoadFile(const std::string &path, std::vector &data) { + FILE* fh = fopen(path.c_str(), "r"); + if (fh == nullptr) { + HELOG(kFatal, "Failed to open file: {}", path); + } + REQUIRE(fh != nullptr); + size_t load_size = fread(data.data(), 1, data.size(), fh); + REQUIRE(load_size == data.size()); + int status = fclose(fh); + REQUIRE(status == 0); + } + + void CompareBuffers(const std::vector &d1, + const std::vector &d2) { + size_t char_mismatch = 0; + for (size_t pos = 0; pos < d1.size(); ++pos) { + if (d1[pos] != d2[pos]) char_mismatch++; + } + REQUIRE(char_mismatch == 0); + } +}; + +} // namespace hermes::adapter::test + +#endif // HERMES_TEST_UNIT_HERMES_ADAPTERS_BINARY_FILE_TESTS_H_ diff --git a/test/unit/hermes_adapters/catch_config.h b/test/unit/hermes_adapters/catch_config.h deleted file mode 100644 index 1317e1e50..000000000 --- a/test/unit/hermes_adapters/catch_config.h +++ /dev/null @@ -1,42 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef HERMES_CATCH_CONFIG_H -#define HERMES_CATCH_CONFIG_H - -#define CATCH_CONFIG_RUNNER -#include - -#include - -namespace cl = Catch::Clara; - -cl::Parser define_options(); - -int init(int* argc, char*** argv); -int finalize(); - -int main(int argc, char* argv[]) { - Catch::Session session; - auto cli = session.cli() | define_options(); - int returnCode = init(&argc, &argv); - if (returnCode != 0) return returnCode; - session.cli(cli); - returnCode = session.applyCommandLine(argc, argv); - if (returnCode != 0) return returnCode; - int test_return_code = session.run(); - returnCode = finalize(); - if (returnCode != 0) return returnCode; - return test_return_code; -} - -#endif diff --git a/test/unit/hermes_adapters/filesystem_tests.h b/test/unit/hermes_adapters/filesystem_tests.h index 95661f7e6..12f0aa10c 100644 --- a/test/unit/hermes_adapters/filesystem_tests.h +++ b/test/unit/hermes_adapters/filesystem_tests.h @@ -1,6 +1,14 @@ -// -// Created by lukemartinlogan on 11/3/23. -// +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Distributed under BSD 3-Clause license. * + * Copyright by The HDF Group. * + * Copyright by the Illinois Institute of Technology. * + * All rights reserved. * + * * + * This file is part of Hermes. The full Hermes copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the top directory. If you do not * + * have access to the file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef HERMES_TEST_UNIT_HERMES_ADAPTERS_FILESYSTEM_TESTS_H_ #define HERMES_TEST_UNIT_HERMES_ADAPTERS_FILESYSTEM_TESTS_H_ @@ -25,7 +33,7 @@ #include #include -namespace hermes::adapter::fs::test { +namespace hermes::adapter::test { /** Pre-create the Hermes file */ #define TEST_DO_CREATE BIT_OPT(u32, 0) @@ -40,11 +48,12 @@ struct FileInfo { bitfield32_t flags_; /** Various flags */ }; +template class FilesystemTests { public: bool supports_tmpfile; - std::vector write_data_; - std::vector read_data_; + std::vector write_data_; + std::vector read_data_; std::list files_; int pid_; std::string pid_str_; @@ -77,18 +86,20 @@ class FilesystemTests { int rc = session.applyCommandLine(argc, argv); if (rc != 0) return rc; +#if HERMES_INTERCEPT == 1 + TRANSPARENT_HERMES(); + setenv("HERMES_FLUSH_MODE", "kSync", 1); + HERMES_CLIENT_CONF.flushing_mode_ = hermes::FlushingMode::kSync; +#endif + total_size_ = request_size_ * num_iterations_; write_data_ = GenRandom(request_size_); - read_data_ = std::vector(request_size_, 'r'); + read_data_ = std::vector(request_size_, 'r'); supports_tmpfile = FilesystemSupportsTmpfile(); pid_ = getpid(); pid_str_ = std::to_string(pid_); RegisterFiles(); -#if HERMES_INTERCEPT == 1 - setenv("HERMES_FLUSH_MODE", "kSync", 1); - HERMES_CLIENT_CONF.flushing_mode_ = hermes::FlushingMode::kSync; -#endif rc = session.run(); MPI_Finalize(); return rc; @@ -99,11 +110,11 @@ class FilesystemTests { FileInfo &info) { info.hermes_ = dir_ + "/" + filename_ + "_" + basename + "_"; info.cmp_ = info.hermes_ + "cmp_"; + info.flags_.SetBits(flags | TEST_WITH_HERMES); if (!info.flags_.Any(TEST_FILE_SHARED)) { info.hermes_ += pid_str_; info.cmp_ += pid_str_; } - info.flags_.SetBits(flags | TEST_WITH_HERMES); files_.push_back(info); } @@ -123,8 +134,8 @@ class FilesystemTests { void TrackAllFiles() { for (const FileInfo &info : files_) { - HERMES_CLIENT_CONF.SetAdapterPathTracking(info.hermes_, - info.flags_.Any(TEST_WITH_HERMES)); + HERMES_CLIENT_CONF.SetAdapterPathTracking( + info.hermes_, info.flags_.Any(TEST_WITH_HERMES)); } } @@ -133,13 +144,13 @@ class FilesystemTests { if (info.flags_.Any(TEST_WITH_HERMES)) { RemoveFile(info.hermes_); RemoveFile(info.cmp_); - // HILOG(kInfo, "Removing files: {} {}", info.hermes_, info.cmp_); + HILOG(kInfo, "Removing files: {} {}", info.hermes_, info.cmp_); } } } void CreateFiles() { - std::vector data = GenRandom(total_size_, 200); + std::vector data = GenerateData(); for (const FileInfo &info : files_) { if (!info.flags_.Any(TEST_WITH_HERMES)) { continue; @@ -157,7 +168,7 @@ class FilesystemTests { void Flush() { #if HERMES_INTERCEPT == 1 // HERMES->Clear(); - HRUN_ADMIN->FlushRoot(DomainId::GetGlobal()); + HRUN_ADMIN->FlushRoot(DomainId::GetGlobal()); #endif } @@ -165,12 +176,14 @@ class FilesystemTests { MPI_Barrier(MPI_COMM_WORLD); IgnoreAllFiles(); RemoveAllFiles(); + MPI_Barrier(MPI_COMM_WORLD); CreateFiles(); TrackAllFiles(); MPI_Barrier(MPI_COMM_WORLD); } void Posttest(bool compare_data = true) { + MPI_Barrier(MPI_COMM_WORLD); Flush(); IgnoreAllFiles(); if (compare_data) { @@ -179,24 +192,22 @@ class FilesystemTests { continue; } if (stdfs::exists(info.hermes_) && stdfs::exists(info.cmp_)) { - size_t cmp_size = stdfs::file_size(info.cmp_); - size_t hermes_size = stdfs::file_size(info.hermes_); - REQUIRE(cmp_size == hermes_size); - std::vector d1(cmp_size, '0'); - std::vector d2(hermes_size, '1'); - LoadFile(info.cmp_, d1); - LoadFile(info.hermes_, d2); - CompareBuffers(d1, d2); + CompareFiles(info); } } } /* Delete the files from both Hermes and the backend. */ + MPI_Barrier(MPI_COMM_WORLD); TrackAllFiles(); RemoveAllFiles(); Flush(); + MPI_Barrier(MPI_COMM_WORLD); } virtual void RegisterFiles() = 0; + virtual void CreateFile(const std::string &path, std::vector &data) = 0; + virtual std::vector GenerateData() = 0; + virtual void CompareFiles(FileInfo &info) = 0; static size_t GetRandomOffset( size_t i, unsigned int offset_seed, @@ -204,26 +215,8 @@ class FilesystemTests { return abs((int)(((i * rand_r(&offset_seed)) % stride) % total_size)); } - private: - void LoadFile(const std::string &path, std::vector &data) { - FILE* fh = fopen(path.c_str(), "r"); - REQUIRE(fh != nullptr); - size_t load_size = fread(data.data(), 1, data.size(), fh); - REQUIRE(load_size == data.size()); - int status = fclose(fh); - REQUIRE(status == 0); - } - - void CompareBuffers(const std::vector &d1, const std::vector &d2) { - size_t char_mismatch = 0; - for (size_t pos = 0; pos < d1.size(); ++pos) { - if (d1[pos] != d2[pos]) char_mismatch++; - } - REQUIRE(char_mismatch == 0); - } - - std::vector GenRandom(const size_t len, int seed = 100) { - auto tmp_s = std::vector(len); + std::vector GenRandom(const size_t len, int seed = 100) { + auto tmp_s = std::vector(len); static const char alphanum[] = "0123456789" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" @@ -235,33 +228,59 @@ class FilesystemTests { return tmp_s; } - void CreateFile(const std::string &path, - const std::vector &data) { - int fd = open(path.c_str(), O_CREAT | O_TRUNC | O_RDWR, 0666); - if (fd == -1) { - HELOG(kFatal, "Failed to open file: {}", path); - } - int ret = write(fd, data.data(), data.size()); - if (ret != data.size()) { - return; - } - close(fd); - REQUIRE(stdfs::file_size(path) == data.size()); + static inline u32 RotateLeft(const u32 x, int k) { + u32 result = (x << k) | (x >> (32 - k)); + + return result; + } + + u32 GenNextRandom() { + static u32 random_state[4] = {111, 222, 333, 444}; + const u32 random = random_state[0] + random_state[3]; + + const u32 t = random_state[1] << 9; + + random_state[2] ^= random_state[0]; + random_state[3] ^= random_state[1]; + random_state[1] ^= random_state[2]; + random_state[0] ^= random_state[3]; + + random_state[2] ^= t; + + random_state[3] = RotateLeft(random_state[3], 11); + + return random; } + /** + * Return a random float in the range [0.0f, 1.0f] + * */ + f32 GenRandom0to1() { + u32 random_u32 = GenNextRandom(); + + f32 result = (random_u32 >> 8) * 0x1.0p-24f; + + return result; + } + + private: void RemoveFile(const std::string &path) { stdfs::remove(path); if (stdfs::exists(path)) { HELOG(kFatal, "Failed to remove: {}", path) } +#ifdef HERMES_INTERCEPT + hermes::Bucket bkt = HERMES->GetBucket(path); + bkt.Destroy(); +#endif } bool FilesystemSupportsTmpfile() { bool result = false; #if O_TMPFILE - // NOTE(chogan): Even if O_TMPFILE is defined, the underlying filesystem might - // not support it. + // NOTE(chogan): Even if O_TMPFILE is defined, the underlying filesystem + // might not support it. int tmp_fd = open("/tmp", O_WRONLY | O_TMPFILE, 0600); if (tmp_fd > 0) { result = true; @@ -273,6 +292,6 @@ class FilesystemTests { } }; -} +} // namespace hermes::adapter::test #endif // HERMES_TEST_UNIT_HERMES_ADAPTERS_FILESYSTEM_TESTS_H_ diff --git a/test/unit/hermes_adapters/mpiio/CMakeLists.txt b/test/unit/hermes_adapters/mpiio/CMakeLists.txt index 7fafaf3f0..cca4d820e 100644 --- a/test/unit/hermes_adapters/mpiio/CMakeLists.txt +++ b/test/unit/hermes_adapters/mpiio/CMakeLists.txt @@ -1,12 +1,27 @@ -add_executable(mpiio_adapter_test mpiio_adapter_test.cpp ${ADAPTER_COMMON}) -# pytest(mpiio test_mpiio_basic) +# MPI adapter tests without hermes +add_executable(mpiio_adapter_test + mpiio_adapter_test.cc + mpiio_adapter_basic_test.cc) +target_link_libraries(mpiio_adapter_test + hermes) +add_dependencies(mpiio_adapter_test + hermes) +target_compile_definitions(mpiio_adapter_test PUBLIC + HERMES_MPI_TESTS=true) +jarvis_test(mpiio test_mpiio_basic) -add_executable(hermes_mpiio_adapter_test mpiio_adapter_test.cpp ${ADAPTER_COMMON}) -target_link_libraries(hermes_mpiio_adapter_test hermes_mpiio) -add_dependencies(hermes_mpiio_adapter_test hermes_mpiio) -set_target_properties(hermes_mpiio_adapter_test PROPERTIES COMPILE_FLAGS "-DHERMES_INTERCEPT=1") -pytest(mpiio test_hermes_mpiio_basic_sync) -pytest(mpiio test_hermes_mpiio_basic_async) +# MPI adapter tests with hermes +add_executable(hermes_mpiio_adapter_test + mpiio_adapter_test.cc + mpiio_adapter_basic_test.cc) +target_link_libraries(hermes_mpiio_adapter_test + hermes_mpiio) +add_dependencies(hermes_mpiio_adapter_test + hermes_mpiio) +target_compile_definitions(hermes_mpiio_adapter_test PUBLIC + HERMES_INTERCEPT=1 HERMES_MPI_TESTS=true) +jarvis_test(mpiio test_hermes_mpiio_basic_sync) +jarvis_test(mpiio test_hermes_mpiio_basic_async) set(MPIIO_TESTS mpiio_adapter_test diff --git a/test/unit/hermes_adapters/mpiio/mpiio_adapter_basic_test.cc b/test/unit/hermes_adapters/mpiio/mpiio_adapter_basic_test.cc new file mode 100644 index 000000000..918ae11ac --- /dev/null +++ b/test/unit/hermes_adapters/mpiio/mpiio_adapter_basic_test.cc @@ -0,0 +1,1114 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Distributed under BSD 3-Clause license. * + * Copyright by The HDF Group. * + * Copyright by the Illinois Institute of Technology. * + * All rights reserved. * + * * + * This file is part of Hermes. The full Hermes copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the top directory. If you do not * + * have access to the file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#include "mpiio_adapter_test.h" + +TEST_CASE("Open", "[process=" + std::to_string(TESTER->comm_size_) + + "]" + "[coordination=independent]" + "[synchronicity=sync]" + "[operation=single_open]" + "[repetition=1][file=1]") { + TESTER->Pretest(); + SECTION("open non-existant file") { + TESTER->test_open(TESTER->new_file_, MPI_MODE_RDONLY, MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ != MPI_SUCCESS); + TESTER->test_open(TESTER->new_file_, MPI_MODE_RDWR | MPI_MODE_EXCL, + MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ != MPI_SUCCESS); + } + + SECTION("opening existing file write-only") { + TESTER->test_open(TESTER->existing_file_, MPI_MODE_WRONLY | MPI_MODE_EXCL, + MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + } + SECTION("opening existing file and read/write") { + TESTER->test_open(TESTER->existing_file_, MPI_MODE_RDWR | MPI_MODE_CREATE, + MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + } + + SECTION("open existing file") { + TESTER->test_open(TESTER->existing_file_, MPI_MODE_RDONLY | MPI_MODE_EXCL, + MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ != MPI_SUCCESS); + TESTER->test_open(TESTER->existing_file_, MPI_MODE_RDWR, MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_open(TESTER->existing_file_, MPI_MODE_RDONLY, MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + } + + SECTION("append write existing file") { + TESTER->test_open(TESTER->existing_file_, MPI_MODE_APPEND | MPI_MODE_EXCL, + MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ != MPI_SUCCESS); + TESTER->test_open(TESTER->existing_file_, MPI_MODE_APPEND, MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ != MPI_SUCCESS); + TESTER->test_open(TESTER->existing_file_, + MPI_MODE_WRONLY | MPI_MODE_APPEND, MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_open(TESTER->existing_file_, + MPI_MODE_RDONLY | MPI_MODE_APPEND, MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_open(TESTER->existing_file_, MPI_MODE_RDWR | MPI_MODE_APPEND, + MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + } + + SECTION("append write and read new file") { + TESTER->test_open(TESTER->existing_file_, + MPI_MODE_RDWR | MPI_MODE_APPEND | MPI_MODE_CREATE, + MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + } + + SECTION("delete on close mode") { + TESTER->test_open( + TESTER->new_file_, + MPI_MODE_WRONLY | MPI_MODE_CREATE | MPI_MODE_DELETE_ON_CLOSE, + MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + REQUIRE(stdfs::exists(TESTER->new_file_.hermes_)); + TESTER->test_close(); + REQUIRE(!stdfs::exists(TESTER->new_file_.hermes_)); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + } + TESTER->Posttest(); +} + +TEST_CASE("OpenCollective", "[process=" + std::to_string(TESTER->comm_size_) + + "]" + "[coordination=collective]" + "[synchronicity=sync]" + "[operation=single_open]" + "[repetition=1][file=1]") { + TESTER->Pretest(); + SECTION("open on non-existant shared file") { + TESTER->test_open(TESTER->shared_new_file_, + MPI_MODE_RDONLY | MPI_MODE_EXCL, MPI_COMM_WORLD); + REQUIRE(TESTER->status_orig_ != MPI_SUCCESS); + TESTER->test_open(TESTER->shared_new_file_, + MPI_MODE_RDONLY | MPI_MODE_CREATE, MPI_COMM_WORLD); + REQUIRE(TESTER->status_orig_ != MPI_SUCCESS); + TESTER->test_open(TESTER->shared_new_file_, MPI_MODE_RDWR | MPI_MODE_EXCL, + MPI_COMM_WORLD); + REQUIRE(TESTER->status_orig_ != MPI_SUCCESS); + TESTER->test_open(TESTER->shared_new_file_, + MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_COMM_WORLD); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_open(TESTER->shared_new_file_, + MPI_MODE_RDWR | MPI_MODE_CREATE, MPI_COMM_WORLD); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + } + + SECTION("open on shared existing file") { + TESTER->test_open(TESTER->shared_existing_file_, + MPI_MODE_WRONLY | MPI_MODE_EXCL, MPI_COMM_WORLD); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_open(TESTER->shared_existing_file_, + MPI_MODE_RDWR | MPI_MODE_EXCL, MPI_COMM_WORLD); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_open(TESTER->shared_existing_file_, + MPI_MODE_RDONLY | MPI_MODE_EXCL, MPI_COMM_WORLD); + REQUIRE(TESTER->status_orig_ != MPI_SUCCESS); + TESTER->test_open(TESTER->shared_existing_file_, MPI_MODE_RDONLY, + MPI_COMM_WORLD); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_open(TESTER->shared_existing_file_, MPI_MODE_RDWR, + MPI_COMM_WORLD); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + } + + SECTION("append write/read on shared existing file") { + TESTER->test_open(TESTER->shared_existing_file_, + MPI_MODE_RDWR | MPI_MODE_APPEND, MPI_COMM_WORLD); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + } + + SECTION("append write and read on shared new file") { + TESTER->test_open(TESTER->shared_new_file_, + MPI_MODE_RDWR | MPI_MODE_APPEND | MPI_MODE_CREATE, + MPI_COMM_WORLD); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + } + + SECTION("delete on close mode on new file") { + TESTER->test_open( + TESTER->shared_new_file_, + MPI_MODE_WRONLY | MPI_MODE_CREATE | MPI_MODE_DELETE_ON_CLOSE, + MPI_COMM_WORLD); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + REQUIRE(!stdfs::exists(TESTER->shared_new_file_.hermes_)); + } + TESTER->Posttest(); +} + +TEST_CASE("SingleWrite", "[process=" + std::to_string(TESTER->comm_size_) + + "]" + "[operation=single_write]" + "[synchronicity=sync]" + "[coordination=independent]" + "[request_size=type-fixed][repetition=1]" + "[file=1]") { + TESTER->Pretest(); + bool check_bytes = true; + SECTION("write to existing file") { + TESTER->test_open(TESTER->existing_file_, MPI_MODE_RDWR, MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_seek(TESTER->rank_ * TESTER->request_size_, MPI_SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_write(TESTER->write_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + } + + SECTION("write to new file") { + TESTER->test_open(TESTER->new_file_, MPI_MODE_WRONLY | MPI_MODE_CREATE, + MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_write(TESTER->write_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_) == + (size_t)TESTER->size_written_orig_); + } + + SECTION("write to new file with allocate") { + TESTER->test_open(TESTER->new_file_, + MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_preallocate(TESTER->request_size_ * TESTER->comm_size_); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_seek(TESTER->request_size_ * TESTER->rank_, MPI_SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_write(TESTER->write_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + MPI_Barrier(MPI_COMM_WORLD); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_) == + (size_t)TESTER->size_written_orig_ * TESTER->comm_size_); + } + + SECTION("append to existing file") { + auto existing_size = stdfs::file_size(TESTER->existing_file_.hermes_); + TESTER->test_open(TESTER->existing_file_, + MPI_MODE_WRONLY | MPI_MODE_APPEND | MPI_MODE_EXCL, + MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_write(TESTER->write_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + REQUIRE(stdfs::file_size(TESTER->existing_file_.hermes_) == + existing_size + TESTER->size_written_orig_); + } + + SECTION("append to new file") { + TESTER->test_open(TESTER->new_file_, + MPI_MODE_WRONLY | MPI_MODE_APPEND | MPI_MODE_CREATE, + MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_write(TESTER->write_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_) == + (size_t)TESTER->size_written_orig_); + } + + SECTION("write_at to existing file") { + TESTER->test_open(TESTER->existing_file_, MPI_MODE_RDWR, MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_write_at(TESTER->write_data_.data(), + TESTER->request_size_, MPI_CHAR, + TESTER->rank_ * TESTER->request_size_); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + } + + SECTION("write_at to new file") { + TESTER->test_open(TESTER->new_file_, MPI_MODE_WRONLY | MPI_MODE_CREATE, + MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_write_at(TESTER->write_data_.data(), + TESTER->request_size_, MPI_CHAR, + 0); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_) == + (size_t)TESTER->size_written_orig_); + } + + SECTION("delete on close mode on new file") { + TESTER->test_open( + TESTER->new_file_, + MPI_MODE_WRONLY | MPI_MODE_CREATE | MPI_MODE_DELETE_ON_CLOSE, + MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_seek(0, MPI_SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_write(TESTER->write_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + REQUIRE(stdfs::exists(TESTER->new_file_.hermes_)); + TESTER->test_close(); + REQUIRE(!stdfs::exists(TESTER->new_file_.hermes_)); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + } + + SECTION("delete on close mode on existing file") { + auto original_size = stdfs::file_size(TESTER->existing_file_.hermes_); + TESTER->test_open(TESTER->existing_file_, + MPI_MODE_WRONLY | MPI_MODE_EXCL | + MPI_MODE_DELETE_ON_CLOSE, MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_seek(TESTER->rank_ * TESTER->request_size_, MPI_SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_write(TESTER->write_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + REQUIRE(stdfs::exists(TESTER->existing_file_.hermes_)); + auto new_size = + original_size > (size_t)TESTER->size_written_orig_ * TESTER->comm_size_ + ? original_size + : TESTER->size_written_orig_ * TESTER->comm_size_; + REQUIRE(stdfs::file_size(TESTER->existing_file_.hermes_) == + (size_t)new_size); + TESTER->test_close(); + REQUIRE(!stdfs::exists(TESTER->existing_file_.hermes_)); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + check_bytes = false; + } + TESTER->Posttest(check_bytes); +} + +TEST_CASE("SingleWriteCollective", + "[process=" + std::to_string(TESTER->comm_size_) + + "]" + "[operation=single_write]" + "[synchronicity=sync]" + "[coordination=collective]" + "[request_size=type-fixed][repetition=1]" + "[file=1]") { + TESTER->Pretest(); + bool check_bytes = true; + SECTION("write to existing file") { + TESTER->test_open(TESTER->shared_existing_file_, MPI_MODE_RDWR, + MPI_COMM_WORLD); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_seek(TESTER->rank_ * TESTER->request_size_, MPI_SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_write(TESTER->write_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + } + + SECTION("write to new file") { + TESTER->test_open(TESTER->shared_new_file_, + MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_COMM_WORLD); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_seek(0, MPI_SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_write(TESTER->write_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + REQUIRE(stdfs::file_size(TESTER->shared_new_file_.hermes_) == + (size_t)TESTER->size_written_orig_); + } + + // TODO(chogan): This test fails intermittently. Needs diagnosis. + // https://github.com/HDFGroup/hermes/issues/209 + SECTION("write to new file using shared ptr") { + TESTER->test_open(TESTER->shared_new_file_, + MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_COMM_WORLD); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_seek_shared(0, MPI_SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_write_shared(TESTER->write_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + REQUIRE(stdfs::file_size(TESTER->shared_new_file_.hermes_) == + (size_t)TESTER->size_written_orig_ * TESTER->comm_size_); + } + + SECTION("write to new file with allocate") { + TESTER->test_open(TESTER->shared_new_file_, + MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_COMM_WORLD); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_preallocate(TESTER->request_size_ * TESTER->comm_size_); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_seek(TESTER->request_size_ * TESTER->rank_, MPI_SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_write(TESTER->write_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + MPI_Barrier(MPI_COMM_WORLD); + REQUIRE(stdfs::file_size(TESTER->shared_new_file_.hermes_) == + (size_t)TESTER->size_written_orig_ * TESTER->comm_size_); + } + + SECTION("write_at_all to existing file") { + TESTER->test_open(TESTER->existing_file_, MPI_MODE_RDWR, MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_write_at_all(TESTER->write_data_.data(), TESTER->request_size_, + MPI_CHAR, TESTER->rank_ * TESTER->request_size_); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + } + + SECTION("write_at_all to new file") { + TESTER->test_open(TESTER->new_file_, MPI_MODE_WRONLY | MPI_MODE_CREATE, + MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_write_at_all(TESTER->write_data_.data(), + TESTER->request_size_, + MPI_CHAR, 0); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_) == + (size_t)TESTER->size_written_orig_); + } + + SECTION("append to existing file") { + auto existing_size = stdfs::file_size(TESTER->existing_file_.hermes_); + TESTER->test_open(TESTER->shared_existing_file_, + MPI_MODE_WRONLY | MPI_MODE_APPEND | MPI_MODE_EXCL, + MPI_COMM_WORLD); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_write_all(TESTER->write_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + REQUIRE(stdfs::file_size(TESTER->shared_existing_file_.hermes_) == + existing_size + TESTER->size_written_orig_); + } + + SECTION("append to new file") { + TESTER->test_open(TESTER->shared_new_file_, + MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_COMM_WORLD); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_write_all(TESTER->write_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + REQUIRE(stdfs::file_size(TESTER->shared_new_file_.hermes_) == + (size_t)TESTER->size_written_orig_); + } + + SECTION("write_ordered to existing file") { + TESTER->test_open(TESTER->existing_file_, MPI_MODE_RDWR, MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_write_ordered(TESTER->write_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + } + + SECTION("write_ordered to new file") { + TESTER->test_open(TESTER->new_file_, MPI_MODE_WRONLY | MPI_MODE_CREATE, + MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_write_ordered(TESTER->write_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_) == + (size_t)TESTER->size_written_orig_); + } + SECTION("delete on close mode on new file") { + TESTER->test_open( + TESTER->shared_new_file_, + MPI_MODE_WRONLY | MPI_MODE_CREATE | MPI_MODE_DELETE_ON_CLOSE, + MPI_COMM_WORLD); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_seek(TESTER->rank_ * TESTER->request_size_, MPI_SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_write(TESTER->write_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + REQUIRE(stdfs::exists(TESTER->shared_new_file_.hermes_)); + MPI_Barrier(MPI_COMM_WORLD); + TESTER->test_close(); + REQUIRE(!stdfs::exists(TESTER->shared_new_file_.hermes_)); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + } + + SECTION("delete on close mode on existing file") { + auto original_size = stdfs::file_size( + TESTER->shared_existing_file_.hermes_); + TESTER->test_open(TESTER->shared_existing_file_, + MPI_MODE_WRONLY | MPI_MODE_EXCL | + MPI_MODE_DELETE_ON_CLOSE, MPI_COMM_WORLD); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_seek(TESTER->rank_ * TESTER->request_size_, MPI_SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_write(TESTER->write_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + REQUIRE(stdfs::exists(TESTER->shared_existing_file_.hermes_)); + auto new_size = + original_size > (size_t)TESTER->size_written_orig_ * TESTER->comm_size_ + ? original_size + : TESTER->size_written_orig_ * TESTER->comm_size_; + REQUIRE(stdfs::file_size(TESTER->shared_existing_file_.hermes_) == + (size_t)new_size); + TESTER->test_close(); + REQUIRE(!stdfs::exists(TESTER->shared_existing_file_.hermes_)); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + check_bytes = false; + } + TESTER->Posttest(check_bytes); +} + +TEST_CASE("SingleAsyncWrite", "[process=" + std::to_string(TESTER->comm_size_) + + "]" + "[operation=single_write]" + "[coordination=independent]" + "[synchronicity=async]" + "[request_size=type-fixed][repetition=1]" + "[file=1]") { + TESTER->Pretest(); + bool check_bytes = true; + SECTION("write to existing file") { + TESTER->test_open(TESTER->existing_file_, MPI_MODE_RDWR, MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_seek(TESTER->rank_ * TESTER->request_size_, MPI_SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_iwrite(TESTER->write_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + } + + SECTION("write to new file") { + TESTER->test_open(TESTER->new_file_, MPI_MODE_WRONLY | MPI_MODE_CREATE, + MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_seek(0, MPI_SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_iwrite(TESTER->write_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_) == + (size_t)TESTER->size_written_orig_); + } + + SECTION("write to new file using shared ptr") { + TESTER->test_open(TESTER->shared_new_file_, + MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_COMM_WORLD); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_seek_shared(0, MPI_SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_iwrite_shared(TESTER->write_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + REQUIRE(stdfs::file_size(TESTER->shared_new_file_.hermes_) == + (size_t)TESTER->size_written_orig_ * TESTER->comm_size_); + } + + SECTION("write to new file with allocate") { + TESTER->test_open(TESTER->shared_new_file_, + MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_COMM_WORLD); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_preallocate(TESTER->request_size_ * TESTER->comm_size_); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_seek(TESTER->request_size_ * TESTER->rank_, MPI_SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_write(TESTER->write_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + MPI_Barrier(MPI_COMM_WORLD); + REQUIRE(stdfs::file_size(TESTER->shared_new_file_.hermes_) == + (size_t)TESTER->size_written_orig_ * TESTER->comm_size_); + } + + SECTION("append to existing file") { + auto existing_size = stdfs::file_size(TESTER->existing_file_.hermes_); + TESTER->test_open(TESTER->existing_file_, + MPI_MODE_WRONLY | MPI_MODE_APPEND | MPI_MODE_EXCL, + MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_iwrite(TESTER->write_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + REQUIRE(stdfs::file_size(TESTER->existing_file_.hermes_) == + existing_size + TESTER->size_written_orig_); + } + + SECTION("append to new file") { + TESTER->test_open(TESTER->new_file_, + MPI_MODE_WRONLY | MPI_MODE_APPEND | MPI_MODE_CREATE, + MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_iwrite(TESTER->write_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_) == + (size_t)TESTER->size_written_orig_); + } + + SECTION("write_at to existing file") { + TESTER->test_open(TESTER->existing_file_, MPI_MODE_RDWR, MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_iwrite_at(TESTER->write_data_.data(), + TESTER->request_size_, MPI_CHAR, + TESTER->rank_ * TESTER->request_size_); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + } + + SECTION("write_at to new file") { + TESTER->test_open(TESTER->new_file_, MPI_MODE_WRONLY | MPI_MODE_CREATE, + MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_iwrite_at(TESTER->write_data_.data(), + TESTER->request_size_, MPI_CHAR, + 0); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_) == + (size_t)TESTER->size_written_orig_); + } + + SECTION("delete on close mode on new file") { + TESTER->test_open( + TESTER->new_file_, + MPI_MODE_WRONLY | MPI_MODE_CREATE | MPI_MODE_DELETE_ON_CLOSE, + MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_seek(0, MPI_SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_iwrite(TESTER->write_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + REQUIRE(stdfs::exists(TESTER->new_file_.hermes_)); + TESTER->test_close(); + REQUIRE(!stdfs::exists(TESTER->new_file_.hermes_)); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + } + + SECTION("delete on close mode on existing file") { + TESTER->test_open(TESTER->existing_file_, + MPI_MODE_WRONLY | MPI_MODE_EXCL | + MPI_MODE_DELETE_ON_CLOSE, + MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_seek(TESTER->rank_ * TESTER->request_size_, MPI_SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_iwrite(TESTER->write_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + REQUIRE(stdfs::exists(TESTER->existing_file_.hermes_)); + TESTER->test_close(); + REQUIRE(!stdfs::exists(TESTER->existing_file_.hermes_)); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + check_bytes = false; + } + TESTER->Posttest(check_bytes); +} + +TEST_CASE("SingleAsyncWriteCollective", + "[process=" + std::to_string(TESTER->comm_size_) + + "]" + "[operation=single_write]" + "[synchronicity=async]" + "[coordination=collective]" + "[request_size=type-fixed][repetition=1]" + "[file=1]") { + TESTER->Pretest(); + bool check_bytes = true; + SECTION("write to existing file") { + TESTER->test_open(TESTER->shared_existing_file_, MPI_MODE_RDWR, + MPI_COMM_WORLD); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_seek(TESTER->rank_ * TESTER->request_size_, MPI_SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_iwrite(TESTER->write_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + } + + SECTION("write to new file") { + TESTER->test_open(TESTER->shared_new_file_, + MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_COMM_WORLD); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_seek(0, MPI_SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_iwrite(TESTER->write_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + REQUIRE(stdfs::file_size(TESTER->shared_new_file_.hermes_) == + (size_t)TESTER->size_written_orig_); + } + + SECTION("write to new file using shared ptr") { + TESTER->test_open(TESTER->shared_new_file_, + MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_COMM_WORLD); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_seek_shared(0, MPI_SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_iwrite_shared(TESTER->write_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + REQUIRE(stdfs::file_size(TESTER->shared_new_file_.hermes_) == + (size_t)TESTER->size_written_orig_ * TESTER->comm_size_); + } + + SECTION("write to new file with allocate") { + TESTER->test_open(TESTER->shared_new_file_, + MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_COMM_WORLD); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_preallocate(TESTER->request_size_ * TESTER->comm_size_); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_seek(TESTER->request_size_ * TESTER->rank_, MPI_SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_iwrite(TESTER->write_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + MPI_Barrier(MPI_COMM_WORLD); + REQUIRE(stdfs::file_size(TESTER->shared_new_file_.hermes_) == + (size_t)TESTER->size_written_orig_ * TESTER->comm_size_); + } + + SECTION("write_at_all to existing file") { + TESTER->test_open(TESTER->existing_file_, MPI_MODE_RDWR, MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_iwrite_at_all(TESTER->write_data_.data(), + TESTER->request_size_, + MPI_CHAR, TESTER->rank_ * TESTER->request_size_); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + } + + SECTION("write_at_all to new file") { + TESTER->test_open(TESTER->new_file_, MPI_MODE_WRONLY | MPI_MODE_CREATE, + MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_iwrite_at_all(TESTER->write_data_.data(), + TESTER->request_size_, MPI_CHAR, 0); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_) == + (size_t)TESTER->size_written_orig_); + } + SECTION("append to existing file") { + auto existing_size = stdfs::file_size(TESTER->existing_file_.hermes_); + TESTER->test_open(TESTER->shared_existing_file_, + MPI_MODE_WRONLY | MPI_MODE_APPEND | MPI_MODE_EXCL, + MPI_COMM_WORLD); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_iwrite_all(TESTER->write_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + REQUIRE(stdfs::file_size(TESTER->shared_existing_file_.hermes_) == + existing_size + TESTER->size_written_orig_); + } + + SECTION("append to new file") { + TESTER->test_open(TESTER->shared_new_file_, + MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_COMM_WORLD); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_iwrite_all(TESTER->write_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + REQUIRE(stdfs::file_size(TESTER->shared_new_file_.hermes_) == + (size_t)TESTER->size_written_orig_); + } + SECTION("delete on close mode on new file") { + TESTER->test_open( + TESTER->shared_new_file_, + MPI_MODE_WRONLY | MPI_MODE_CREATE | MPI_MODE_DELETE_ON_CLOSE, + MPI_COMM_WORLD); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_seek(0, MPI_SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_iwrite(TESTER->write_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + REQUIRE(stdfs::exists(TESTER->shared_new_file_.hermes_)); + TESTER->test_close(); + REQUIRE(!stdfs::exists(TESTER->shared_new_file_.hermes_)); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + } + + SECTION("delete on close mode on existing file") { + auto original_size = stdfs::file_size( + TESTER->shared_existing_file_.hermes_); + TESTER->test_open(TESTER->shared_existing_file_, + MPI_MODE_WRONLY | MPI_MODE_EXCL | + MPI_MODE_DELETE_ON_CLOSE, + MPI_COMM_WORLD); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_seek(TESTER->rank_ * TESTER->request_size_, MPI_SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_iwrite(TESTER->write_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_written_orig_ == TESTER->request_size_); + REQUIRE(stdfs::exists(TESTER->shared_existing_file_.hermes_)); + auto new_size = + original_size > (size_t)TESTER->size_written_orig_ * TESTER->comm_size_ + ? original_size + : TESTER->size_written_orig_ * TESTER->comm_size_; + REQUIRE(stdfs::file_size(TESTER->shared_existing_file_.hermes_) == + (size_t)new_size); + TESTER->test_close(); + REQUIRE(!stdfs::exists(TESTER->shared_existing_file_.hermes_)); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + check_bytes = false; + } + TESTER->Posttest(check_bytes); +} + +TEST_CASE("SingleRead", "[process=" + std::to_string(TESTER->comm_size_) + + "]" + "[operation=single_read]" + "[synchronicity=sync]" + "[coordination=independent]" + "[request_size=type-fixed][repetition=1]" + "[file=1]") { + TESTER->Pretest(); + SECTION("read from non-existing file") { + TESTER->test_open(TESTER->new_file_, MPI_MODE_RDONLY | MPI_MODE_EXCL, + MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ != MPI_SUCCESS); + } + + SECTION("read from existing file") { + TESTER->test_open(TESTER->existing_file_, MPI_MODE_RDONLY, MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_seek(TESTER->rank_ * TESTER->request_size_, MPI_SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_read(TESTER->read_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_read_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + } + + SECTION("read from existing file using shared ptr") { + TESTER->test_open(TESTER->shared_existing_file_, MPI_MODE_RDONLY, + MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_seek_shared(0, MPI_SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_read_shared(TESTER->read_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_read_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + } + + SECTION("read at the end of existing file") { + TESTER->test_open(TESTER->existing_file_, MPI_MODE_RDONLY, MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_seek(0, MPI_SEEK_END); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + MPI_Offset offset; + MPI_File_get_position(TESTER->fh_orig_, &offset); + REQUIRE(offset == + (long long)(TESTER->request_size_ * TESTER->num_iterations_)); + TESTER->test_read(TESTER->read_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE(TESTER->size_read_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + } + + SECTION("read_at from existing file") { + TESTER->test_open(TESTER->existing_file_, MPI_MODE_RDONLY, MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_read_at(TESTER->read_data_.data(), + TESTER->request_size_, MPI_CHAR, + TESTER->rank_ * TESTER->request_size_); + REQUIRE((size_t)TESTER->size_read_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + } + + TESTER->Posttest(); +} + +TEST_CASE("SingleReadCollective", "[process=" + + std::to_string(TESTER->comm_size_) + + "]" + "[operation=single_read]" + "[synchronicity=sync]" + "[coordination=collective]" + "[request_size=type-fixed][repetition=1]" + "[file=1]") { + TESTER->Pretest(); + SECTION("read from non-existing file") { + TESTER->test_open(TESTER->shared_new_file_, MPI_MODE_RDONLY, + MPI_COMM_WORLD); + REQUIRE(TESTER->status_orig_ != MPI_SUCCESS); + } + + SECTION("read from existing file") { + TESTER->test_open(TESTER->shared_existing_file_, MPI_MODE_RDONLY, + MPI_COMM_WORLD); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_seek(TESTER->rank_ * TESTER->request_size_, MPI_SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_read_all(TESTER->read_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_read_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + } + + SECTION("read from existing file using shared ptr") { + TESTER->test_open(TESTER->shared_existing_file_, MPI_MODE_RDONLY, + MPI_COMM_WORLD); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_seek_shared(0, MPI_SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_read_shared(TESTER->read_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_read_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + } + + SECTION("read_at_all from existing file") { + TESTER->test_open(TESTER->existing_file_, MPI_MODE_RDONLY, MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_read_at_all(TESTER->read_data_.data(), + TESTER->request_size_, MPI_CHAR, + TESTER->rank_ * TESTER->request_size_); + REQUIRE((size_t)TESTER->size_read_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + } + + SECTION("read_ordered from existing file") { + TESTER->test_open(TESTER->existing_file_, MPI_MODE_RDONLY, + MPI_COMM_WORLD); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_read_ordered(TESTER->read_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_read_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + } + TESTER->Posttest(); +} + +TEST_CASE("SingleAsyncRead", "[process=" + std::to_string(TESTER->comm_size_) + + "]" + "[operation=single_read]" + "[synchronicity=async]" + "[coordination=independent]" + "[request_size=type-fixed][repetition=1]" + "[file=1]") { + TESTER->Pretest(); + SECTION("read from non-existing file") { + TESTER->test_open(TESTER->new_file_, MPI_MODE_RDONLY | MPI_MODE_EXCL, + MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ != MPI_SUCCESS); + } + + SECTION("read from existing file") { + TESTER->test_open(TESTER->existing_file_, MPI_MODE_RDONLY, MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_seek(TESTER->rank_ * TESTER->request_size_, MPI_SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_iread(TESTER->read_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_read_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + } + + SECTION("read from existing file using shared ptr") { + TESTER->test_open(TESTER->shared_existing_file_, MPI_MODE_RDONLY, + MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_seek_shared(0, MPI_SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_iread_shared(TESTER->read_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_read_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + } + + SECTION("read at the end of existing file") { + TESTER->test_open(TESTER->existing_file_, MPI_MODE_RDONLY, MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_seek(0, MPI_SEEK_END); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + MPI_Offset offset; + MPI_File_get_position(TESTER->fh_orig_, &offset); + REQUIRE(offset == + (long long)(TESTER->request_size_ * TESTER->num_iterations_)); + TESTER->test_iread(TESTER->read_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE(TESTER->size_read_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + } + + SECTION("read_at from existing file") { + TESTER->test_open(TESTER->existing_file_, MPI_MODE_RDONLY, MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_iread_at(TESTER->read_data_.data(), + TESTER->request_size_, MPI_CHAR, + TESTER->rank_ * TESTER->request_size_); + REQUIRE((size_t)TESTER->size_read_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + } + + TESTER->Posttest(); +} + +// TODO(chogan): This test fails sporadically. +// https://github.com/HDFGroup/hermes/issues/413 +TEST_CASE("SingleAsyncReadCollective", + "[process=" + std::to_string(TESTER->comm_size_) + + "]" + "[operation=single_read]" + "[synchronicity=async]" + "[coordination=collective]" + "[request_size=type-fixed][repetition=1]" + "[file=1]") { + TESTER->Pretest(); + SECTION("read from non-existing file") { + TESTER->test_open(TESTER->shared_new_file_, MPI_MODE_RDONLY, + MPI_COMM_WORLD); + REQUIRE(TESTER->status_orig_ != MPI_SUCCESS); + } + + SECTION("read from existing file") { + TESTER->test_open(TESTER->shared_existing_file_, MPI_MODE_RDONLY, + MPI_COMM_WORLD); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_seek(TESTER->rank_ * TESTER->request_size_, MPI_SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_iread_all(TESTER->read_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_read_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + } + + SECTION("read from existing file using shared ptr") { + TESTER->test_open(TESTER->shared_existing_file_, MPI_MODE_RDONLY, + MPI_COMM_WORLD); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_seek_shared(0, MPI_SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_iread_shared(TESTER->read_data_.data(), + TESTER->request_size_, MPI_CHAR); + REQUIRE((size_t)TESTER->size_read_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + } + + SECTION("read_at_all from existing file") { + TESTER->test_open(TESTER->existing_file_, MPI_MODE_RDONLY, MPI_COMM_SELF); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + TESTER->test_iread_at_all(TESTER->read_data_.data(), + TESTER->request_size_, MPI_CHAR, + TESTER->rank_ * TESTER->request_size_); + REQUIRE((size_t)TESTER->size_read_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == MPI_SUCCESS); + } + TESTER->Posttest(); +} diff --git a/test/unit/hermes_adapters/mpiio/mpiio_adapter_basic_test.cpp b/test/unit/hermes_adapters/mpiio/mpiio_adapter_basic_test.cpp deleted file mode 100644 index 9035bd5d4..000000000 --- a/test/unit/hermes_adapters/mpiio/mpiio_adapter_basic_test.cpp +++ /dev/null @@ -1,1044 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -TEST_CASE("Open", "[process=" + std::to_string(info.comm_size) + - "]" - "[coordination=independent]" - "[synchronicity=sync]" - "[operation=single_open]" - "[repetition=1][file=1]") { - pretest(); - SECTION("open non-existant file") { - test::test_open(info.new_file.c_str(), MPI_MODE_RDONLY, MPI_COMM_SELF); - REQUIRE(test::status_orig != MPI_SUCCESS); - test::test_open(info.new_file.c_str(), MPI_MODE_RDWR | MPI_MODE_EXCL, - MPI_COMM_SELF); - REQUIRE(test::status_orig != MPI_SUCCESS); - } - - SECTION("opening existing file write-only") { - test::test_open(info.existing_file.c_str(), MPI_MODE_WRONLY | MPI_MODE_EXCL, - MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - } - SECTION("opening existing file and read/write") { - test::test_open(info.existing_file.c_str(), MPI_MODE_RDWR | MPI_MODE_CREATE, - MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - } - - SECTION("open existing file") { - test::test_open(info.existing_file.c_str(), MPI_MODE_RDONLY | MPI_MODE_EXCL, - MPI_COMM_SELF); - REQUIRE(test::status_orig != MPI_SUCCESS); - test::test_open(info.existing_file.c_str(), MPI_MODE_RDWR, MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_open(info.existing_file.c_str(), MPI_MODE_RDONLY, MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - } - - SECTION("append write existing file") { - test::test_open(info.existing_file.c_str(), MPI_MODE_APPEND | MPI_MODE_EXCL, - MPI_COMM_SELF); - REQUIRE(test::status_orig != MPI_SUCCESS); - test::test_open(info.existing_file.c_str(), MPI_MODE_APPEND, MPI_COMM_SELF); - REQUIRE(test::status_orig != MPI_SUCCESS); - test::test_open(info.existing_file.c_str(), - MPI_MODE_WRONLY | MPI_MODE_APPEND, MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_open(info.existing_file.c_str(), - MPI_MODE_RDONLY | MPI_MODE_APPEND, MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_open(info.existing_file.c_str(), MPI_MODE_RDWR | MPI_MODE_APPEND, - MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - } - - SECTION("append write and read new file") { - test::test_open(info.existing_file.c_str(), - MPI_MODE_RDWR | MPI_MODE_APPEND | MPI_MODE_CREATE, - MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - } - - SECTION("delete on close mode") { - test::test_open( - info.new_file.c_str(), - MPI_MODE_WRONLY | MPI_MODE_CREATE | MPI_MODE_DELETE_ON_CLOSE, - MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - REQUIRE(stdfs::exists(info.new_file.c_str())); - test::test_close(); - REQUIRE(!stdfs::exists(info.new_file.c_str())); - REQUIRE(test::status_orig == MPI_SUCCESS); - } - posttest(); -} - -TEST_CASE("OpenCollective", "[process=" + std::to_string(info.comm_size) + - "]" - "[coordination=collective]" - "[synchronicity=sync]" - "[operation=single_open]" - "[repetition=1][file=1]") { - pretest(); - SECTION("open on non-existant shared file") { - test::test_open(info.shared_new_file.c_str(), - MPI_MODE_RDONLY | MPI_MODE_EXCL, MPI_COMM_WORLD); - REQUIRE(test::status_orig != MPI_SUCCESS); - test::test_open(info.shared_new_file.c_str(), - MPI_MODE_RDONLY | MPI_MODE_CREATE, MPI_COMM_WORLD); - REQUIRE(test::status_orig != MPI_SUCCESS); - test::test_open(info.shared_new_file.c_str(), MPI_MODE_RDWR | MPI_MODE_EXCL, - MPI_COMM_WORLD); - REQUIRE(test::status_orig != MPI_SUCCESS); - test::test_open(info.shared_new_file.c_str(), - MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_COMM_WORLD); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_open(info.shared_new_file.c_str(), - MPI_MODE_RDWR | MPI_MODE_CREATE, MPI_COMM_WORLD); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - } - - SECTION("open on shared existing file") { - test::test_open(info.shared_existing_file.c_str(), - MPI_MODE_WRONLY | MPI_MODE_EXCL, MPI_COMM_WORLD); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_open(info.shared_existing_file.c_str(), - MPI_MODE_RDWR | MPI_MODE_EXCL, MPI_COMM_WORLD); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_open(info.shared_existing_file.c_str(), - MPI_MODE_RDONLY | MPI_MODE_EXCL, MPI_COMM_WORLD); - REQUIRE(test::status_orig != MPI_SUCCESS); - test::test_open(info.shared_existing_file.c_str(), MPI_MODE_RDONLY, - MPI_COMM_WORLD); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_open(info.shared_existing_file.c_str(), MPI_MODE_RDWR, - MPI_COMM_WORLD); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - } - - SECTION("append write/read on shared existing file") { - test::test_open(info.shared_existing_file.c_str(), - MPI_MODE_RDWR | MPI_MODE_APPEND, MPI_COMM_WORLD); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - } - - SECTION("append write and read on shared new file") { - test::test_open(info.shared_new_file.c_str(), - MPI_MODE_RDWR | MPI_MODE_APPEND | MPI_MODE_CREATE, - MPI_COMM_WORLD); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - } - - SECTION("delete on close mode on new file") { - test::test_open( - info.shared_new_file.c_str(), - MPI_MODE_WRONLY | MPI_MODE_CREATE | MPI_MODE_DELETE_ON_CLOSE, - MPI_COMM_WORLD); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - REQUIRE(!stdfs::exists(info.shared_new_file.c_str())); - } - posttest(); -} - -TEST_CASE("SingleWrite", "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=single_write]" - "[synchronicity=sync]" - "[coordination=independent]" - "[request_size=type-fixed][repetition=1]" - "[file=1]") { - pretest(); - bool check_bytes = true; - SECTION("write to existing file") { - test::test_open(info.existing_file.c_str(), MPI_MODE_RDWR, MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_seek(info.rank * args.request_size, MPI_SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_write(info.write_data.c_str(), args.request_size, MPI_CHAR); - REQUIRE((size_t)test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - } - - SECTION("write to new file") { - test::test_open(info.new_file.c_str(), MPI_MODE_WRONLY | MPI_MODE_CREATE, - MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_write(info.write_data.c_str(), args.request_size, MPI_CHAR); - REQUIRE((size_t)test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - REQUIRE(stdfs::file_size(info.new_file) == (size_t)test::size_written_orig); - } - - SECTION("write to new file with allocate") { - test::test_open(info.shared_new_file.c_str(), - MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_preallocate(args.request_size * info.comm_size); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_seek(args.request_size * info.rank, MPI_SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_write(info.write_data.c_str(), args.request_size, MPI_CHAR); - REQUIRE((size_t)test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - MPI_Barrier(MPI_COMM_WORLD); - REQUIRE(stdfs::file_size(info.shared_new_file) == - (size_t)test::size_written_orig * info.comm_size); - } - - SECTION("append to existing file") { - auto existing_size = stdfs::file_size(info.existing_file); - test::test_open(info.existing_file.c_str(), - MPI_MODE_WRONLY | MPI_MODE_APPEND | MPI_MODE_EXCL, - MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_write(info.write_data.c_str(), args.request_size, MPI_CHAR); - REQUIRE((size_t)test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - REQUIRE(stdfs::file_size(info.existing_file) == - existing_size + test::size_written_orig); - } - - SECTION("append to new file") { - test::test_open(info.new_file.c_str(), - MPI_MODE_WRONLY | MPI_MODE_APPEND | MPI_MODE_CREATE, - MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_write(info.write_data.c_str(), args.request_size, MPI_CHAR); - REQUIRE((size_t)test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - REQUIRE(stdfs::file_size(info.new_file) == (size_t)test::size_written_orig); - } - - SECTION("write_at to existing file") { - test::test_open(info.existing_file.c_str(), MPI_MODE_RDWR, MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_write_at(info.write_data.c_str(), args.request_size, MPI_CHAR, - info.rank * args.request_size); - REQUIRE((size_t)test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - } - - SECTION("write_at to new file") { - test::test_open(info.new_file.c_str(), MPI_MODE_WRONLY | MPI_MODE_CREATE, - MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_write_at(info.write_data.c_str(), args.request_size, MPI_CHAR, - 0); - REQUIRE((size_t)test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - REQUIRE(stdfs::file_size(info.new_file) == (size_t)test::size_written_orig); - } - - SECTION("delete on close mode on new file") { - test::test_open( - info.new_file.c_str(), - MPI_MODE_WRONLY | MPI_MODE_CREATE | MPI_MODE_DELETE_ON_CLOSE, - MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_seek(0, MPI_SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_write(info.write_data.c_str(), args.request_size, MPI_CHAR); - REQUIRE((size_t)test::size_written_orig == args.request_size); - REQUIRE(stdfs::exists(info.new_file.c_str())); - test::test_close(); - REQUIRE(!stdfs::exists(info.new_file.c_str())); - REQUIRE(test::status_orig == MPI_SUCCESS); - } - - SECTION("delete on close mode on existing file") { - auto original_size = stdfs::file_size(info.existing_file); - test::test_open(info.existing_file.c_str(), - MPI_MODE_WRONLY | MPI_MODE_EXCL | MPI_MODE_DELETE_ON_CLOSE, - MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_seek(info.rank * args.request_size, MPI_SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_write(info.write_data.c_str(), args.request_size, MPI_CHAR); - REQUIRE((size_t)test::size_written_orig == args.request_size); - REQUIRE(stdfs::exists(info.existing_file.c_str())); - auto new_size = - original_size > (size_t)test::size_written_orig * info.comm_size - ? original_size - : test::size_written_orig * info.comm_size; - REQUIRE(stdfs::file_size(info.existing_file) == (size_t)new_size); - test::test_close(); - REQUIRE(!stdfs::exists(info.existing_file.c_str())); - REQUIRE(test::status_orig == MPI_SUCCESS); - check_bytes = false; - } - posttest(check_bytes); -} - -TEST_CASE("SingleWriteCollective", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=single_write]" - "[synchronicity=sync]" - "[coordination=collective]" - "[request_size=type-fixed][repetition=1]" - "[file=1]") { - pretest(); - bool check_bytes = true; - SECTION("write to existing file") { - test::test_open(info.shared_existing_file.c_str(), MPI_MODE_RDWR, - MPI_COMM_WORLD); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_seek(info.rank * args.request_size, MPI_SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_write(info.write_data.c_str(), args.request_size, MPI_CHAR); - REQUIRE((size_t)test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - } - - SECTION("write to new file") { - test::test_open(info.shared_new_file.c_str(), - MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_COMM_WORLD); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_seek(0, MPI_SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_write(info.write_data.c_str(), args.request_size, MPI_CHAR); - REQUIRE((size_t)test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - REQUIRE(stdfs::file_size(info.shared_new_file) == - (size_t)test::size_written_orig); - } - - // TODO(chogan): This test fails intermittently. Needs diagnosis. - // https://github.com/HDFGroup/hermes/issues/209 - SECTION("write to new file using shared ptr") { - test::test_open(info.shared_new_file.c_str(), - MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_COMM_WORLD); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_seek_shared(0, MPI_SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_write_shared(info.write_data.c_str(), args.request_size, - MPI_CHAR); - REQUIRE((size_t)test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - REQUIRE(stdfs::file_size(info.shared_new_file) == - (size_t)test::size_written_orig * info.comm_size); - } - - SECTION("write to new file with allocate") { - test::test_open(info.shared_new_file.c_str(), - MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_COMM_WORLD); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_preallocate(args.request_size * info.comm_size); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_seek(args.request_size * info.rank, MPI_SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_write(info.write_data.c_str(), args.request_size, MPI_CHAR); - REQUIRE((size_t)test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - MPI_Barrier(MPI_COMM_WORLD); - REQUIRE(stdfs::file_size(info.shared_new_file) == - (size_t)test::size_written_orig * info.comm_size); - } - - SECTION("write_at_all to existing file") { - test::test_open(info.existing_file.c_str(), MPI_MODE_RDWR, MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_write_at_all(info.write_data.c_str(), args.request_size, - MPI_CHAR, info.rank * args.request_size); - REQUIRE((size_t)test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - } - - SECTION("write_at_all to new file") { - test::test_open(info.new_file.c_str(), MPI_MODE_WRONLY | MPI_MODE_CREATE, - MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_write_at_all(info.write_data.c_str(), args.request_size, - MPI_CHAR, 0); - REQUIRE((size_t)test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - REQUIRE(stdfs::file_size(info.new_file) == (size_t)test::size_written_orig); - } - - SECTION("append to existing file") { - auto existing_size = stdfs::file_size(info.existing_file); - test::test_open(info.shared_existing_file.c_str(), - MPI_MODE_WRONLY | MPI_MODE_APPEND | MPI_MODE_EXCL, - MPI_COMM_WORLD); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_write_all(info.write_data.c_str(), args.request_size, MPI_CHAR); - REQUIRE((size_t)test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - REQUIRE(stdfs::file_size(info.shared_existing_file) == - existing_size + test::size_written_orig); - } - - SECTION("append to new file") { - test::test_open(info.shared_new_file.c_str(), - MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_COMM_WORLD); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_write_all(info.write_data.c_str(), args.request_size, MPI_CHAR); - REQUIRE((size_t)test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - REQUIRE(stdfs::file_size(info.shared_new_file) == - (size_t)test::size_written_orig); - } - - SECTION("write_ordered to existing file") { - test::test_open(info.existing_file.c_str(), MPI_MODE_RDWR, MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_write_ordered(info.write_data.c_str(), args.request_size, - MPI_CHAR); - REQUIRE((size_t)test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - } - - SECTION("write_ordered to new file") { - test::test_open(info.new_file.c_str(), MPI_MODE_WRONLY | MPI_MODE_CREATE, - MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_write_ordered(info.write_data.c_str(), args.request_size, - MPI_CHAR); - REQUIRE((size_t)test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - REQUIRE(stdfs::file_size(info.new_file) == (size_t)test::size_written_orig); - } - SECTION("delete on close mode on new file") { - test::test_open( - info.shared_new_file.c_str(), - MPI_MODE_WRONLY | MPI_MODE_CREATE | MPI_MODE_DELETE_ON_CLOSE, - MPI_COMM_WORLD); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_seek(info.rank * args.request_size, MPI_SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_write(info.write_data.c_str(), args.request_size, MPI_CHAR); - REQUIRE((size_t)test::size_written_orig == args.request_size); - REQUIRE(stdfs::exists(info.shared_new_file.c_str())); - MPI_Barrier(MPI_COMM_WORLD); - test::test_close(); - REQUIRE(!stdfs::exists(info.shared_new_file.c_str())); - REQUIRE(test::status_orig == MPI_SUCCESS); - } - - SECTION("delete on close mode on existing file") { - auto original_size = stdfs::file_size(info.shared_existing_file); - test::test_open(info.shared_existing_file.c_str(), - MPI_MODE_WRONLY | MPI_MODE_EXCL | MPI_MODE_DELETE_ON_CLOSE, - MPI_COMM_WORLD); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_seek(info.rank * args.request_size, MPI_SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_write(info.write_data.c_str(), args.request_size, MPI_CHAR); - REQUIRE((size_t)test::size_written_orig == args.request_size); - REQUIRE(stdfs::exists(info.shared_existing_file.c_str())); - auto new_size = - original_size > (size_t)test::size_written_orig * info.comm_size - ? original_size - : test::size_written_orig * info.comm_size; - REQUIRE(stdfs::file_size(info.shared_existing_file) == (size_t)new_size); - test::test_close(); - REQUIRE(!stdfs::exists(info.shared_existing_file.c_str())); - REQUIRE(test::status_orig == MPI_SUCCESS); - check_bytes = false; - } - posttest(check_bytes); -} - -TEST_CASE("SingleAsyncWrite", "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=single_write]" - "[coordination=independent]" - "[synchronicity=async]" - "[request_size=type-fixed][repetition=1]" - "[file=1]") { - pretest(); - bool check_bytes = true; - SECTION("write to existing file") { - test::test_open(info.existing_file.c_str(), MPI_MODE_RDWR, MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_seek(info.rank * args.request_size, MPI_SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_iwrite(info.write_data.c_str(), args.request_size, MPI_CHAR); - REQUIRE((size_t)test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - } - - SECTION("write to new file") { - test::test_open(info.new_file.c_str(), MPI_MODE_WRONLY | MPI_MODE_CREATE, - MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_seek(0, MPI_SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_iwrite(info.write_data.c_str(), args.request_size, MPI_CHAR); - REQUIRE((size_t)test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - REQUIRE(stdfs::file_size(info.new_file) == (size_t)test::size_written_orig); - } - - SECTION("write to new file using shared ptr") { - test::test_open(info.shared_new_file.c_str(), - MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_COMM_WORLD); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_seek_shared(0, MPI_SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_iwrite_shared(info.write_data.c_str(), args.request_size, - MPI_CHAR); - REQUIRE((size_t)test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - REQUIRE(stdfs::file_size(info.shared_new_file) == - (size_t)test::size_written_orig * info.comm_size); - } - - SECTION("write to new file with allocate") { - test::test_open(info.shared_new_file.c_str(), - MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_COMM_WORLD); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_preallocate(args.request_size * info.comm_size); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_seek(args.request_size * info.rank, MPI_SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_write(info.write_data.c_str(), args.request_size, MPI_CHAR); - REQUIRE((size_t)test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - MPI_Barrier(MPI_COMM_WORLD); - REQUIRE(stdfs::file_size(info.shared_new_file) == - (size_t)test::size_written_orig * info.comm_size); - } - - SECTION("append to existing file") { - auto existing_size = stdfs::file_size(info.existing_file); - test::test_open(info.existing_file.c_str(), - MPI_MODE_WRONLY | MPI_MODE_APPEND | MPI_MODE_EXCL, - MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_iwrite(info.write_data.c_str(), args.request_size, MPI_CHAR); - REQUIRE((size_t)test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - REQUIRE(stdfs::file_size(info.existing_file) == - existing_size + test::size_written_orig); - } - - SECTION("append to new file") { - test::test_open(info.new_file.c_str(), - MPI_MODE_WRONLY | MPI_MODE_APPEND | MPI_MODE_CREATE, - MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_iwrite(info.write_data.c_str(), args.request_size, MPI_CHAR); - REQUIRE((size_t)test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - REQUIRE(stdfs::file_size(info.new_file) == (size_t)test::size_written_orig); - } - - SECTION("write_at to existing file") { - test::test_open(info.existing_file.c_str(), MPI_MODE_RDWR, MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_iwrite_at(info.write_data.c_str(), args.request_size, MPI_CHAR, - info.rank * args.request_size); - REQUIRE((size_t)test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - } - - SECTION("write_at to new file") { - test::test_open(info.new_file.c_str(), MPI_MODE_WRONLY | MPI_MODE_CREATE, - MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_iwrite_at(info.write_data.c_str(), args.request_size, MPI_CHAR, - 0); - REQUIRE((size_t)test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - REQUIRE(stdfs::file_size(info.new_file) == (size_t)test::size_written_orig); - } - - SECTION("delete on close mode on new file") { - test::test_open( - info.new_file.c_str(), - MPI_MODE_WRONLY | MPI_MODE_CREATE | MPI_MODE_DELETE_ON_CLOSE, - MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_seek(0, MPI_SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_iwrite(info.write_data.c_str(), args.request_size, MPI_CHAR); - REQUIRE((size_t)test::size_written_orig == args.request_size); - REQUIRE(stdfs::exists(info.new_file.c_str())); - test::test_close(); - REQUIRE(!stdfs::exists(info.new_file.c_str())); - REQUIRE(test::status_orig == MPI_SUCCESS); - } - - SECTION("delete on close mode on existing file") { - test::test_open(info.existing_file.c_str(), - MPI_MODE_WRONLY | MPI_MODE_EXCL | MPI_MODE_DELETE_ON_CLOSE, - MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_seek(info.rank * args.request_size, MPI_SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_iwrite(info.write_data.c_str(), args.request_size, MPI_CHAR); - REQUIRE((size_t)test::size_written_orig == args.request_size); - REQUIRE(stdfs::exists(info.existing_file.c_str())); - test::test_close(); - REQUIRE(!stdfs::exists(info.existing_file.c_str())); - REQUIRE(test::status_orig == MPI_SUCCESS); - check_bytes = false; - } - posttest(check_bytes); -} - -TEST_CASE("SingleAsyncWriteCollective", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=single_write]" - "[synchronicity=async]" - "[coordination=collective]" - "[request_size=type-fixed][repetition=1]" - "[file=1]") { - pretest(); - bool check_bytes = true; - SECTION("write to existing file") { - test::test_open(info.shared_existing_file.c_str(), MPI_MODE_RDWR, - MPI_COMM_WORLD); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_seek(info.rank * args.request_size, MPI_SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_iwrite(info.write_data.c_str(), args.request_size, MPI_CHAR); - REQUIRE((size_t)test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - } - - SECTION("write to new file") { - test::test_open(info.shared_new_file.c_str(), - MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_COMM_WORLD); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_seek(0, MPI_SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_iwrite(info.write_data.c_str(), args.request_size, MPI_CHAR); - REQUIRE((size_t)test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - REQUIRE(stdfs::file_size(info.shared_new_file) == - (size_t)test::size_written_orig); - } - - SECTION("write to new file using shared ptr") { - test::test_open(info.shared_new_file.c_str(), - MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_COMM_WORLD); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_seek_shared(0, MPI_SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_iwrite_shared(info.write_data.c_str(), args.request_size, - MPI_CHAR); - REQUIRE((size_t)test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - REQUIRE(stdfs::file_size(info.shared_new_file) == - (size_t)test::size_written_orig * info.comm_size); - } - - SECTION("write to new file with allocate") { - test::test_open(info.shared_new_file.c_str(), - MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_COMM_WORLD); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_preallocate(args.request_size * info.comm_size); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_seek(args.request_size * info.rank, MPI_SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_iwrite(info.write_data.c_str(), args.request_size, MPI_CHAR); - REQUIRE((size_t)test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - MPI_Barrier(MPI_COMM_WORLD); - REQUIRE(stdfs::file_size(info.shared_new_file) == - (size_t)test::size_written_orig * info.comm_size); - } - - SECTION("write_at_all to existing file") { - test::test_open(info.existing_file.c_str(), MPI_MODE_RDWR, MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_iwrite_at_all(info.write_data.c_str(), args.request_size, - MPI_CHAR, info.rank * args.request_size); - REQUIRE((size_t)test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - } - - SECTION("write_at_all to new file") { - test::test_open(info.new_file.c_str(), MPI_MODE_WRONLY | MPI_MODE_CREATE, - MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_iwrite_at_all(info.write_data.c_str(), args.request_size, - MPI_CHAR, 0); - REQUIRE((size_t)test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - REQUIRE(stdfs::file_size(info.new_file) == (size_t)test::size_written_orig); - } - SECTION("append to existing file") { - auto existing_size = stdfs::file_size(info.existing_file); - test::test_open(info.shared_existing_file.c_str(), - MPI_MODE_WRONLY | MPI_MODE_APPEND | MPI_MODE_EXCL, - MPI_COMM_WORLD); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_iwrite_all(info.write_data.c_str(), args.request_size, MPI_CHAR); - REQUIRE((size_t)test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - REQUIRE(stdfs::file_size(info.shared_existing_file) == - existing_size + test::size_written_orig); - } - - SECTION("append to new file") { - test::test_open(info.shared_new_file.c_str(), - MPI_MODE_WRONLY | MPI_MODE_CREATE, MPI_COMM_WORLD); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_iwrite_all(info.write_data.c_str(), args.request_size, MPI_CHAR); - REQUIRE((size_t)test::size_written_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - REQUIRE(stdfs::file_size(info.shared_new_file) == - (size_t)test::size_written_orig); - } - SECTION("delete on close mode on new file") { - test::test_open( - info.shared_new_file.c_str(), - MPI_MODE_WRONLY | MPI_MODE_CREATE | MPI_MODE_DELETE_ON_CLOSE, - MPI_COMM_WORLD); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_seek(0, MPI_SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_iwrite(info.write_data.c_str(), args.request_size, MPI_CHAR); - REQUIRE((size_t)test::size_written_orig == args.request_size); - REQUIRE(stdfs::exists(info.shared_new_file.c_str())); - test::test_close(); - REQUIRE(!stdfs::exists(info.shared_new_file.c_str())); - REQUIRE(test::status_orig == MPI_SUCCESS); - } - - SECTION("delete on close mode on existing file") { - auto original_size = stdfs::file_size(info.shared_existing_file); - test::test_open(info.shared_existing_file.c_str(), - MPI_MODE_WRONLY | MPI_MODE_EXCL | MPI_MODE_DELETE_ON_CLOSE, - MPI_COMM_WORLD); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_seek(info.rank * args.request_size, MPI_SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_iwrite(info.write_data.c_str(), args.request_size, MPI_CHAR); - REQUIRE((size_t)test::size_written_orig == args.request_size); - REQUIRE(stdfs::exists(info.shared_existing_file.c_str())); - auto new_size = - original_size > (size_t)test::size_written_orig * info.comm_size - ? original_size - : test::size_written_orig * info.comm_size; - REQUIRE(stdfs::file_size(info.shared_existing_file) == (size_t)new_size); - test::test_close(); - REQUIRE(!stdfs::exists(info.shared_existing_file.c_str())); - REQUIRE(test::status_orig == MPI_SUCCESS); - check_bytes = false; - } - posttest(check_bytes); -} - -TEST_CASE("SingleRead", "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=single_read]" - "[synchronicity=sync]" - "[coordination=independent]" - "[request_size=type-fixed][repetition=1]" - "[file=1]") { - pretest(); - SECTION("read from non-existing file") { - test::test_open(info.new_file.c_str(), MPI_MODE_RDONLY | MPI_MODE_EXCL, - MPI_COMM_SELF); - REQUIRE(test::status_orig != MPI_SUCCESS); - } - - SECTION("read from existing file") { - test::test_open(info.existing_file.c_str(), MPI_MODE_RDONLY, MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_seek(info.rank * args.request_size, MPI_SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_read(info.read_data.data(), args.request_size, MPI_CHAR); - REQUIRE((size_t)test::size_read_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - } - - SECTION("read from existing file using shared ptr") { - test::test_open(info.shared_existing_file.c_str(), MPI_MODE_RDONLY, - MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_seek_shared(0, MPI_SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_read_shared(info.read_data.data(), args.request_size, MPI_CHAR); - REQUIRE((size_t)test::size_read_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - } - - SECTION("read at the end of existing file") { - test::test_open(info.existing_file.c_str(), MPI_MODE_RDONLY, MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_seek(0, MPI_SEEK_END); - REQUIRE(test::status_orig == MPI_SUCCESS); - MPI_Offset offset; - MPI_File_get_position(test::fh_orig, &offset); - REQUIRE(offset == (long long)(args.request_size * info.num_iterations)); - test::test_read(info.read_data.data(), args.request_size, MPI_CHAR); - REQUIRE(test::size_read_orig == 0); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - } - - SECTION("read_at from existing file") { - test::test_open(info.existing_file.c_str(), MPI_MODE_RDONLY, MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_read_at(info.read_data.data(), args.request_size, MPI_CHAR, - info.rank * args.request_size); - REQUIRE((size_t)test::size_read_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - } - - posttest(); -} - -TEST_CASE("SingleReadCollective", "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=single_read]" - "[synchronicity=sync]" - "[coordination=collective]" - "[request_size=type-fixed][repetition=1]" - "[file=1]") { - pretest(); - SECTION("read from non-existing file") { - test::test_open(info.shared_new_file.c_str(), MPI_MODE_RDONLY, - MPI_COMM_WORLD); - REQUIRE(test::status_orig != MPI_SUCCESS); - } - - SECTION("read from existing file") { - test::test_open(info.shared_existing_file.c_str(), MPI_MODE_RDONLY, - MPI_COMM_WORLD); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_seek(info.rank * args.request_size, MPI_SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_read_all(info.read_data.data(), args.request_size, MPI_CHAR); - REQUIRE((size_t)test::size_read_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - } - - SECTION("read from existing file using shared ptr") { - test::test_open(info.shared_existing_file.c_str(), MPI_MODE_RDONLY, - MPI_COMM_WORLD); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_seek_shared(0, MPI_SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_read_shared(info.read_data.data(), args.request_size, MPI_CHAR); - REQUIRE((size_t)test::size_read_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - } - - SECTION("read_at_all from existing file") { - test::test_open(info.existing_file.c_str(), MPI_MODE_RDONLY, MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_read_at_all(info.read_data.data(), args.request_size, MPI_CHAR, - info.rank * args.request_size); - REQUIRE((size_t)test::size_read_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - } - - SECTION("read_ordered from existing file") { - test::test_open(info.existing_file.c_str(), MPI_MODE_RDONLY, - MPI_COMM_WORLD); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_read_ordered(info.read_data.data(), args.request_size, MPI_CHAR); - REQUIRE((size_t)test::size_read_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - } - posttest(); -} - -TEST_CASE("SingleAsyncRead", "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=single_read]" - "[synchronicity=async]" - "[coordination=independent]" - "[request_size=type-fixed][repetition=1]" - "[file=1]") { - pretest(); - SECTION("read from non-existing file") { - test::test_open(info.new_file.c_str(), MPI_MODE_RDONLY | MPI_MODE_EXCL, - MPI_COMM_SELF); - REQUIRE(test::status_orig != MPI_SUCCESS); - } - - SECTION("read from existing file") { - test::test_open(info.existing_file.c_str(), MPI_MODE_RDONLY, MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_seek(info.rank * args.request_size, MPI_SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_iread(info.read_data.data(), args.request_size, MPI_CHAR); - REQUIRE((size_t)test::size_read_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - } - - SECTION("read from existing file using shared ptr") { - test::test_open(info.shared_existing_file.c_str(), MPI_MODE_RDONLY, - MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_seek_shared(0, MPI_SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_iread_shared(info.read_data.data(), args.request_size, MPI_CHAR); - REQUIRE((size_t)test::size_read_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - } - - SECTION("read at the end of existing file") { - test::test_open(info.existing_file.c_str(), MPI_MODE_RDONLY, MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_seek(0, MPI_SEEK_END); - REQUIRE(test::status_orig == MPI_SUCCESS); - MPI_Offset offset; - MPI_File_get_position(test::fh_orig, &offset); - REQUIRE(offset == (long long)(args.request_size * info.num_iterations)); - test::test_iread(info.read_data.data(), args.request_size, MPI_CHAR); - REQUIRE(test::size_read_orig == 0); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - } - - SECTION("read_at from existing file") { - test::test_open(info.existing_file.c_str(), MPI_MODE_RDONLY, MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_iread_at(info.read_data.data(), args.request_size, MPI_CHAR, - info.rank * args.request_size); - REQUIRE((size_t)test::size_read_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - } - - posttest(); -} - -// TODO(chogan): This test fails sporadically. -// https://github.com/HDFGroup/hermes/issues/413 -TEST_CASE("SingleAsyncReadCollective", - "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=single_read]" - "[synchronicity=async]" - "[coordination=collective]" - "[request_size=type-fixed][repetition=1]" - "[file=1]") { - pretest(); - SECTION("read from non-existing file") { - test::test_open(info.shared_new_file.c_str(), MPI_MODE_RDONLY, - MPI_COMM_WORLD); - REQUIRE(test::status_orig != MPI_SUCCESS); - } - - SECTION("read from existing file") { - test::test_open(info.shared_existing_file.c_str(), MPI_MODE_RDONLY, - MPI_COMM_WORLD); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_seek(info.rank * args.request_size, MPI_SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_iread_all(info.read_data.data(), args.request_size, MPI_CHAR); - REQUIRE((size_t)test::size_read_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - } - - SECTION("read from existing file using shared ptr") { - test::test_open(info.shared_existing_file.c_str(), MPI_MODE_RDONLY, - MPI_COMM_WORLD); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_seek_shared(0, MPI_SEEK_SET); - REQUIRE(test::status_orig == 0); - test::test_iread_shared(info.read_data.data(), args.request_size, MPI_CHAR); - REQUIRE((size_t)test::size_read_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - } - - SECTION("read_at_all from existing file") { - test::test_open(info.existing_file.c_str(), MPI_MODE_RDONLY, MPI_COMM_SELF); - REQUIRE(test::status_orig == MPI_SUCCESS); - test::test_iread_at_all(info.read_data.data(), args.request_size, MPI_CHAR, - info.rank * args.request_size); - REQUIRE((size_t)test::size_read_orig == args.request_size); - test::test_close(); - REQUIRE(test::status_orig == MPI_SUCCESS); - } - posttest(); -} diff --git a/hermes_adapters/interceptor.h b/test/unit/hermes_adapters/mpiio/mpiio_adapter_test.cc similarity index 68% rename from hermes_adapters/interceptor.h rename to test/unit/hermes_adapters/mpiio/mpiio_adapter_test.cc index ba62e256a..bebec2019 100644 --- a/hermes_adapters/interceptor.h +++ b/test/unit/hermes_adapters/mpiio/mpiio_adapter_test.cc @@ -10,21 +10,8 @@ * have access to the file, you may request a copy from help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#ifndef HERMES_ADAPTER_UTILS_H_ -#define HERMES_ADAPTER_UTILS_H_ +#include "mpiio_adapter_test.h" -#include "hermes/hermes.h" -#include "hermes_adapters/filesystem/filesystem_mdm.h" - -namespace stdfs = std::filesystem; - -namespace hermes::adapter { - -#define HERMES_DECL(F) F - -/** The maximum length of a POSIX path */ -static inline const int kMaxPathLen = 4096; - -} // namespace hermes::adapter - -#endif // HERMES_ADAPTER_UTILS_H_ +int main(int argc, char **argv) { + TESTER->Init(argc, argv); +} diff --git a/test/unit/hermes_adapters/mpiio/mpiio_adapter_test.cpp b/test/unit/hermes_adapters/mpiio/mpiio_adapter_test.cpp deleted file mode 100644 index 0b5c40f44..000000000 --- a/test/unit/hermes_adapters/mpiio/mpiio_adapter_test.cpp +++ /dev/null @@ -1,687 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include - -#include -#include - -#include "adapter_test_utils.h" -#include "catch_config.h" -#if HERMES_INTERCEPT == 1 -#include "hermes_adapters/filesystem/filesystem.h" -#endif - -#include "adapter_test_utils.h" - -namespace stdfs = std::filesystem; - -namespace hermes::adapter::mpiio::test { -struct Arguments { - std::string filename = "test.dat"; - std::string directory = "/tmp/test_hermes"; - size_t request_size = 65536; -}; -struct Info { - bool debug = false; - int rank = 0; - int comm_size = 1; - std::string write_data; - std::string read_data; - std::string new_file; - std::string existing_file; - std::string shared_new_file; - std::string shared_existing_file; - std::string new_file_cmp; - std::string existing_file_cmp; - std::string shared_new_file_cmp; - std::string shared_existing_file_cmp; - size_t num_iterations = 64; - unsigned int offset_seed = 1; - unsigned int rs_seed = 1; - unsigned int temporal_interval_seed = 5; - size_t total_size; - size_t stride_size = 512; - unsigned int temporal_interval_ms = 1; - size_t small_min = 1, small_max = 4 * 1024; - size_t medium_min = 4 * 1024 + 1, medium_max = 256 * 1024; - size_t large_min = 256 * 1024 + 1, large_max = 3 * 1024 * 1024; -}; -} // namespace hermes::adapter::mpiio::test -hermes::adapter::mpiio::test::Arguments args; -hermes::adapter::mpiio::test::Info info; - -int init(int* argc, char*** argv) { -#if HERMES_INTERCEPT == 1 - setenv("HERMES_FLUSH_MODE", "kSync", 1); - HERMES_CLIENT_CONF.flushing_mode_ = hermes::FlushingMode::kSync; -#endif - MPI_Init(argc, argv); - info.write_data = GenRandom(args.request_size); - info.read_data = std::string(args.request_size, 'r'); - MPI_Comm_rank(MPI_COMM_WORLD, &info.rank); - MPI_Comm_size(MPI_COMM_WORLD, &info.comm_size); - if (info.debug && info.rank == 0) { - printf("ready for attach\n"); - fflush(stdout); - sleep(30); - } - MPI_Barrier(MPI_COMM_WORLD); - return 0; -} -int finalize() { - MPI_Finalize(); - return 0; -} - -const char* kUser = "USER"; - -int pretest() { - stdfs::path fullpath = args.directory; - fullpath /= args.filename + "_" + std::string(getenv(kUser)); - info.new_file = fullpath.string() + "_new_" + std::to_string(getpid()); - info.existing_file = fullpath.string() + "_ext_" + std::to_string(getpid()); - info.new_file_cmp = - fullpath.string() + "_new_cmp" + "_" + std::to_string(getpid()); - info.existing_file_cmp = - fullpath.string() + "_ext_cmp" + "_" + std::to_string(getpid()); - info.shared_new_file = - fullpath.string() + "_shared_new_" + std::to_string(info.comm_size); - info.shared_existing_file = - fullpath.string() + "_shared_ext_" + std::to_string(info.comm_size); - info.shared_new_file_cmp = - fullpath.string() + "_shared_new_cmp_" + std::to_string(info.comm_size); - info.shared_existing_file_cmp = - fullpath.string() + "_shared_ext_cmp_" + std::to_string(info.comm_size); - if (stdfs::exists(info.new_file)) stdfs::remove(info.new_file); - if (stdfs::exists(info.new_file_cmp)) stdfs::remove(info.new_file_cmp); - if (stdfs::exists(info.existing_file)) stdfs::remove(info.existing_file); - if (stdfs::exists(info.existing_file_cmp)) - stdfs::remove(info.existing_file_cmp); - if (!stdfs::exists(info.existing_file)) { - std::string cmd = "{ tr -dc '[:alnum:]' < /dev/urandom | head -c " + - std::to_string(args.request_size * info.num_iterations) + - "; } > " + info.existing_file + " 2> /dev/null"; - int status = system(cmd.c_str()); - REQUIRE(status != -1); - REQUIRE(stdfs::file_size(info.existing_file) == - args.request_size * info.num_iterations); - info.total_size = stdfs::file_size(info.existing_file); - } - MPI_Barrier(MPI_COMM_WORLD); - if (!stdfs::exists(info.existing_file_cmp)) { - std::string cmd = "cp " + info.existing_file + " " + info.existing_file_cmp; - int status = system(cmd.c_str()); - REQUIRE(status != -1); - REQUIRE(stdfs::file_size(info.existing_file_cmp) == - args.request_size * info.num_iterations); - } - MPI_Barrier(MPI_COMM_WORLD); - if (info.rank == 0) { - if (stdfs::exists(info.shared_new_file)) - stdfs::remove(info.shared_new_file); - if (stdfs::exists(info.shared_existing_file)) - stdfs::remove(info.shared_existing_file); - if (!stdfs::exists(info.shared_existing_file)) { - std::string cmd = - "cp " + info.existing_file + " " + info.shared_existing_file; - int status = system(cmd.c_str()); - REQUIRE(status != -1); - REQUIRE(stdfs::file_size(info.shared_existing_file) == - args.request_size * info.num_iterations); - } - if (stdfs::exists(info.shared_new_file_cmp)) - stdfs::remove(info.shared_new_file_cmp); - if (stdfs::exists(info.shared_existing_file_cmp)) - stdfs::remove(info.shared_existing_file_cmp); - if (!stdfs::exists(info.shared_existing_file_cmp)) { - std::string cmd = - "cp " + info.existing_file + " " + info.shared_existing_file_cmp; - int status = system(cmd.c_str()); - REQUIRE(status != -1); - REQUIRE(stdfs::file_size(info.shared_existing_file_cmp) == - args.request_size * info.num_iterations); - } - } - MPI_Barrier(MPI_COMM_WORLD); - REQUIRE(info.total_size > 0); -#if HERMES_INTERCEPT == 1 - HERMES_CLIENT_CONF.SetAdapterPathTracking(info.existing_file_cmp, false); - HERMES_CLIENT_CONF.SetAdapterPathTracking(info.new_file_cmp, false); - HERMES_CLIENT_CONF.SetAdapterPathTracking( - info.shared_new_file_cmp, false); - HERMES_CLIENT_CONF.SetAdapterPathTracking( - info.shared_existing_file_cmp, false); -#endif - return 0; -} - -void Clear() { -#if HERMES_INTERCEPT == 1 - HERMES->Clear(); -// RemoveFiles(); -// HRUN_ADMIN->FlushRoot(DomainId::GetGlobal()); -#endif -} - -int posttest(bool compare_data = true) { -#if HERMES_INTERCEPT == 1 - HERMES_CLIENT_CONF.SetAdapterPathTracking(info.existing_file, false); - HERMES_CLIENT_CONF.SetAdapterPathTracking(info.new_file, false); -#endif - if (compare_data && stdfs::exists(info.new_file) && - stdfs::exists(info.new_file_cmp)) { - size_t size = stdfs::file_size(info.new_file); - REQUIRE(size == stdfs::file_size(info.new_file_cmp)); - if (size > 0) { - std::vector d1(size, '0'); - std::vector d2(size, '1'); - - FILE* fh1 = fopen(info.new_file.c_str(), "r"); - REQUIRE(fh1 != nullptr); - size_t read_d1 = fread(d1.data(), size, sizeof(unsigned char), fh1); - REQUIRE(read_d1 == sizeof(unsigned char)); - int status = fclose(fh1); - REQUIRE(status == 0); - - FILE* fh2 = fopen(info.new_file_cmp.c_str(), "r"); - REQUIRE(fh2 != nullptr); - size_t read_d2 = fread(d2.data(), size, sizeof(unsigned char), fh2); - REQUIRE(read_d2 == sizeof(unsigned char)); - status = fclose(fh2); - REQUIRE(status == 0); - - size_t char_mismatch = 0; - for (size_t pos = 0; pos < size; ++pos) { - if (d1[pos] != d2[pos]) char_mismatch++; - } - REQUIRE(char_mismatch == 0); - } - } - if (compare_data && stdfs::exists(info.existing_file) && - stdfs::exists(info.existing_file_cmp)) { - size_t size = stdfs::file_size(info.existing_file); - if (size != stdfs::file_size(info.existing_file_cmp)) sleep(1); - REQUIRE(size == stdfs::file_size(info.existing_file_cmp)); - if (size > 0) { - std::vector d1(size, '0'); - std::vector d2(size, '1'); - - FILE* fh1 = fopen(info.existing_file.c_str(), "r"); - REQUIRE(fh1 != nullptr); - size_t read_d1 = fread(d1.data(), size, sizeof(unsigned char), fh1); - REQUIRE(read_d1 == sizeof(unsigned char)); - int status = fclose(fh1); - REQUIRE(status == 0); - - FILE* fh2 = fopen(info.existing_file_cmp.c_str(), "r"); - REQUIRE(fh2 != nullptr); - size_t read_d2 = fread(d2.data(), size, sizeof(unsigned char), fh2); - REQUIRE(read_d2 == sizeof(unsigned char)); - status = fclose(fh2); - REQUIRE(status == 0); - size_t char_mismatch = 0; - for (size_t pos = 0; pos < size; ++pos) { - if (d1[pos] != d2[pos]) char_mismatch++; - } - REQUIRE(char_mismatch == 0); - } - } - /* Clean up. */ - if (stdfs::exists(info.new_file)) stdfs::remove(info.new_file); - if (stdfs::exists(info.existing_file)) stdfs::remove(info.existing_file); - if (stdfs::exists(info.new_file_cmp)) stdfs::remove(info.new_file_cmp); - if (stdfs::exists(info.existing_file_cmp)) - stdfs::remove(info.existing_file_cmp); - Clear(); - -#if HERMES_INTERCEPT == 1 - HERMES_CLIENT_CONF.SetAdapterPathTracking(info.existing_file_cmp, true); - HERMES_CLIENT_CONF.SetAdapterPathTracking(info.new_file_cmp, true); - HERMES_CLIENT_CONF.SetAdapterPathTracking(info.new_file, true); - HERMES_CLIENT_CONF.SetAdapterPathTracking(info.existing_file, true); -#endif - return 0; -} - -cl::Parser define_options() { - return cl::Opt(args.filename, "filename")["-f"]["--filename"]( - "Filename used for performing I/O") | - cl::Opt(args.directory, "dir")["-d"]["--directory"]( - "Directory used for performing I/O") | - cl::Opt(args.request_size, "request_size")["-s"]["--request_size"]( - "Request size used for performing I/O"); -} - -namespace test { -MPI_File fh_orig; -MPI_File fh_cmp; -int status_orig; -int size_read_orig; -int size_written_orig; - -void test_read_data(size_t size_read, size_t count, int type_size, - char* read_data, char* ptr) { - if (size_read > 0) { - size_t unmatching_chars = 0; - for (size_t i = 0; i < count * type_size; ++i) { - if (read_data[i] != ptr[i]) { - unmatching_chars = i; - break; - } - } - REQUIRE(unmatching_chars == 0); - } -} - -void test_open(const char* path, int mode, MPI_Comm comm) { - std::string cmp_path; - if (strcmp(path, info.new_file.c_str()) == 0) { - cmp_path = info.new_file_cmp; - } else if (strcmp(path, info.existing_file.c_str()) == 0) { - cmp_path = info.existing_file_cmp; - } else if (strcmp(path, info.shared_new_file.c_str()) == 0) { - cmp_path = info.shared_new_file_cmp; - } else { - cmp_path = info.shared_existing_file_cmp; - } - status_orig = MPI_File_open(comm, path, mode, MPI_INFO_NULL, &fh_orig); - auto status_cmp = - MPI_File_open(comm, cmp_path.c_str(), mode, MPI_INFO_NULL, &fh_cmp); - bool is_same = (status_orig != MPI_SUCCESS && status_cmp != MPI_SUCCESS) || - (status_orig == MPI_SUCCESS && status_cmp == MPI_SUCCESS); - REQUIRE(is_same); -} -void test_close() { - status_orig = MPI_File_close(&fh_orig); - int status = MPI_File_close(&fh_cmp); - REQUIRE(status == status_orig); -} - -void test_preallocate(MPI_Offset size) { - status_orig = MPI_File_preallocate(fh_orig, size); - int status = MPI_File_preallocate(fh_cmp, size); - REQUIRE(status == status_orig); -} - -void test_write(const void* ptr, size_t count, MPI_Datatype datatype) { - MPI_Status stat_orig, stat_cmp; - auto ret_orig = MPI_File_write(fh_orig, ptr, count, datatype, &stat_orig); - int size_written; - auto ret_cmp = MPI_File_write(fh_cmp, ptr, count, datatype, &stat_cmp); - REQUIRE(ret_orig == ret_cmp); - MPI_Get_count(&stat_orig, datatype, &size_written_orig); - MPI_Get_count(&stat_cmp, datatype, &size_written); - REQUIRE(size_written == size_written_orig); -} - -void test_iwrite(const void* ptr, size_t count, MPI_Datatype datatype) { - MPI_Status stat[2]; - MPI_Request request[2]; - auto ret_orig = MPI_File_iwrite(fh_orig, ptr, count, datatype, &request[0]); - int size_written; - auto ret_cmp = MPI_File_iwrite(fh_cmp, ptr, count, datatype, &request[1]); - REQUIRE(ret_orig == ret_cmp); - MPI_Waitall(2, request, stat); - MPI_Get_count(&stat[0], datatype, &size_written_orig); - MPI_Get_count(&stat[1], datatype, &size_written); - REQUIRE(size_written == size_written_orig); -} - -void test_write_shared(const void* ptr, size_t count, MPI_Datatype datatype) { - MPI_Status stat_orig, stat_cmp; - auto ret_orig = - MPI_File_write_shared(fh_orig, ptr, count, datatype, &stat_orig); - int size_written; - auto ret_cmp = MPI_File_write_shared(fh_cmp, ptr, count, datatype, &stat_cmp); - REQUIRE(ret_orig == ret_cmp); - MPI_Get_count(&stat_orig, datatype, &size_written_orig); - MPI_Get_count(&stat_cmp, datatype, &size_written); - REQUIRE(size_written == size_written_orig); -} - -void test_iwrite_shared(const void* ptr, size_t count, MPI_Datatype datatype) { - MPI_Status stat[2]; - MPI_Request request[2]; - auto ret_orig = - MPI_File_iwrite_shared(fh_orig, ptr, count, datatype, &request[0]); - int size_written; - auto ret_cmp = - MPI_File_iwrite_shared(fh_cmp, ptr, count, datatype, &request[1]); - REQUIRE(ret_orig == ret_cmp); - MPI_Waitall(2, request, stat); - MPI_Get_count(&stat[0], datatype, &size_written_orig); - MPI_Get_count(&stat[1], datatype, &size_written); - REQUIRE(size_written == size_written_orig); -} - -void test_write_all(const void* ptr, size_t count, MPI_Datatype datatype) { - MPI_Status stat_orig, stat_cmp; - auto ret_orig = MPI_File_write_all(fh_orig, ptr, count, datatype, &stat_orig); - int size_written; - auto ret_cmp = MPI_File_write_all(fh_cmp, ptr, count, datatype, &stat_cmp); - REQUIRE(ret_orig == ret_cmp); - MPI_Get_count(&stat_orig, datatype, &size_written_orig); - MPI_Get_count(&stat_cmp, datatype, &size_written); - REQUIRE(size_written == size_written_orig); -} - -void test_iwrite_all(const void* ptr, size_t count, MPI_Datatype datatype) { - MPI_Status stat[2]; - MPI_Request request[2]; - auto ret_orig = - MPI_File_iwrite_all(fh_orig, ptr, count, datatype, &request[0]); - int size_written; - auto ret_cmp = MPI_File_iwrite_all(fh_cmp, ptr, count, datatype, &request[1]); - REQUIRE(ret_orig == ret_cmp); - MPI_Waitall(2, request, stat); - MPI_Get_count(&stat[0], datatype, &size_written_orig); - MPI_Get_count(&stat[1], datatype, &size_written); - REQUIRE(size_written == size_written_orig); -} - -void test_write_at(const void* ptr, size_t count, MPI_Datatype datatype, - MPI_Offset offset) { - MPI_Status stat_orig, stat_cmp; - auto ret_orig = - MPI_File_write_at(fh_orig, offset, ptr, count, datatype, &stat_orig); - int size_written; - auto ret_cmp = - MPI_File_write_at(fh_cmp, offset, ptr, count, datatype, &stat_cmp); - REQUIRE(ret_orig == ret_cmp); - MPI_Get_count(&stat_orig, datatype, &size_written_orig); - MPI_Get_count(&stat_cmp, datatype, &size_written); - REQUIRE(size_written == size_written_orig); -} - -void test_iwrite_at(const void* ptr, size_t count, MPI_Datatype datatype, - MPI_Offset offset) { - MPI_Status stat[2]; - MPI_Request request[2]; - auto ret_orig = - MPI_File_iwrite_at(fh_orig, offset, ptr, count, datatype, &request[0]); - int size_written; - auto ret_cmp = - MPI_File_iwrite_at(fh_cmp, offset, ptr, count, datatype, &request[1]); - REQUIRE(ret_orig == ret_cmp); - MPI_Waitall(2, request, stat); - MPI_Get_count(&stat[0], datatype, &size_written_orig); - MPI_Get_count(&stat[0], datatype, &size_written); - REQUIRE(size_written == size_written_orig); -} - -void test_write_at_all(const void* ptr, size_t count, MPI_Datatype datatype, - MPI_Offset offset) { - MPI_Status stat_orig, stat_cmp; - auto ret_orig = - MPI_File_write_at_all(fh_orig, offset, ptr, count, datatype, &stat_orig); - int size_written; - auto ret_cmp = - MPI_File_write_at_all(fh_cmp, offset, ptr, count, datatype, &stat_cmp); - REQUIRE(ret_orig == ret_cmp); - MPI_Get_count(&stat_orig, datatype, &size_written_orig); - MPI_Get_count(&stat_cmp, datatype, &size_written); - REQUIRE(size_written == size_written_orig); -} - -void test_iwrite_at_all(const void* ptr, size_t count, MPI_Datatype datatype, - MPI_Offset offset) { - MPI_Status stat[2]; - MPI_Request request[2]; - auto ret_orig = MPI_File_iwrite_at_all(fh_orig, offset, ptr, count, datatype, - &request[0]); - int size_written; - auto ret_cmp = - MPI_File_iwrite_at_all(fh_cmp, offset, ptr, count, datatype, &request[1]); - REQUIRE(ret_orig == ret_cmp); - MPI_Waitall(2, request, stat); - MPI_Get_count(&stat[0], datatype, &size_written_orig); - MPI_Get_count(&stat[1], datatype, &size_written); - REQUIRE(size_written == size_written_orig); -} - -void test_write_ordered(const void* ptr, size_t count, MPI_Datatype datatype) { - MPI_Status stat_orig, stat_cmp; - auto ret_orig = - MPI_File_write_ordered(fh_orig, ptr, count, datatype, &stat_orig); - int size_written; - auto ret_cmp = - MPI_File_write_ordered(fh_cmp, ptr, count, datatype, &stat_cmp); - REQUIRE(ret_orig == ret_cmp); - MPI_Get_count(&stat_orig, datatype, &size_written_orig); - MPI_Get_count(&stat_cmp, datatype, &size_written); - REQUIRE(size_written == size_written_orig); -} - -void test_read(char* ptr, size_t count, MPI_Datatype datatype) { - MPI_Status stat_orig, stat_cmp; - auto ret_orig = MPI_File_read(fh_orig, ptr, count, datatype, &stat_orig); - int type_size; - MPI_Type_size(datatype, &type_size); - std::vector read_data(count * type_size, 'r'); - int size_read; - auto ret_cmp = - MPI_File_read(fh_cmp, read_data.data(), count, datatype, &stat_cmp); - REQUIRE(ret_orig == ret_cmp); - MPI_Get_count(&stat_orig, datatype, &size_read_orig); - MPI_Get_count(&stat_cmp, datatype, &size_read); - REQUIRE(size_read == size_read_orig); - test_read_data(size_read, count, type_size, - reinterpret_cast(read_data.data()), ptr); -} - -void test_iread(char* ptr, size_t count, MPI_Datatype datatype) { - MPI_Status stat[2]; - MPI_Request request[2]; - auto ret_orig = MPI_File_iread(fh_orig, ptr, count, datatype, &request[0]); - int type_size; - MPI_Type_size(datatype, &type_size); - std::vector read_data(count * type_size, 'r'); - int size_read; - auto ret_cmp = - MPI_File_iread(fh_cmp, read_data.data(), count, datatype, &request[1]); - REQUIRE(ret_orig == ret_cmp); - MPI_Waitall(2, request, stat); - MPI_Get_count(&stat[0], datatype, &size_read_orig); - MPI_Get_count(&stat[1], datatype, &size_read); - REQUIRE(size_read == size_read_orig); - test_read_data(size_read, count, type_size, - reinterpret_cast(read_data.data()), ptr); -} - -void test_read_shared(char* ptr, size_t count, MPI_Datatype datatype) { - MPI_Status stat_orig, stat_cmp; - auto ret_orig = - MPI_File_read_shared(fh_orig, ptr, count, datatype, &stat_orig); - int type_size; - MPI_Type_size(datatype, &type_size); - std::vector read_data(count * type_size, 'r'); - int size_read; - auto ret_cmp = MPI_File_read_shared(fh_cmp, read_data.data(), count, datatype, - &stat_cmp); - REQUIRE(ret_orig == ret_cmp); - MPI_Get_count(&stat_orig, datatype, &size_read_orig); - MPI_Get_count(&stat_cmp, datatype, &size_read); - REQUIRE(size_read == size_read_orig); - test_read_data(size_read, count, type_size, - reinterpret_cast(read_data.data()), ptr); -} - -void test_iread_shared(char* ptr, size_t count, MPI_Datatype datatype) { - MPI_Status stat[2]; - MPI_Request request[2]; - auto ret_orig = - MPI_File_iread_shared(fh_orig, ptr, count, datatype, &request[0]); - int type_size; - MPI_Type_size(datatype, &type_size); - std::vector read_data(count * type_size, 'r'); - int size_read; - auto ret_cmp = MPI_File_iread_shared(fh_cmp, read_data.data(), count, - datatype, &request[1]); - REQUIRE(ret_orig == ret_cmp); - MPI_Waitall(2, request, stat); - MPI_Get_count(&stat[0], datatype, &size_read_orig); - MPI_Get_count(&stat[1], datatype, &size_read); - REQUIRE(size_read == size_read_orig); - test_read_data(size_read, count, type_size, - reinterpret_cast(read_data.data()), ptr); -} - -void test_read_all(char* ptr, size_t count, MPI_Datatype datatype) { - MPI_Status stat_orig, stat_cmp; - auto ret_orig = MPI_File_read_all(fh_orig, ptr, count, datatype, &stat_orig); - int type_size; - MPI_Type_size(datatype, &type_size); - std::vector read_data(count * type_size, 'r'); - int size_read; - auto ret_cmp = - MPI_File_read_all(fh_cmp, read_data.data(), count, datatype, &stat_cmp); - REQUIRE(ret_orig == ret_cmp); - MPI_Get_count(&stat_orig, datatype, &size_read_orig); - MPI_Get_count(&stat_cmp, datatype, &size_read); - REQUIRE(size_read == size_read_orig); - test_read_data(size_read, count, type_size, - reinterpret_cast(read_data.data()), ptr); -} - -void test_iread_all(char* ptr, size_t count, MPI_Datatype datatype) { - MPI_Status stat[2]; - MPI_Request request[2]; - auto ret_orig = - MPI_File_iread_all(fh_orig, ptr, count, datatype, &request[0]); - int type_size; - MPI_Type_size(datatype, &type_size); - std::vector read_data(count * type_size, 'r'); - int size_read; - auto ret_cmp = MPI_File_iread_all(fh_cmp, read_data.data(), count, datatype, - &request[1]); - REQUIRE(ret_orig == ret_cmp); - MPI_Waitall(2, request, stat); - MPI_Get_count(&stat[0], datatype, &size_read_orig); - MPI_Get_count(&stat[1], datatype, &size_read); - REQUIRE(size_read == size_read_orig); - test_read_data(size_read, count, type_size, - reinterpret_cast(read_data.data()), ptr); -} - -void test_read_ordered(char* ptr, size_t count, MPI_Datatype datatype) { - MPI_Status stat_orig, stat_cmp; - auto ret_orig = - MPI_File_read_ordered(fh_orig, ptr, count, datatype, &stat_orig); - int type_size; - MPI_Type_size(datatype, &type_size); - std::vector read_data(count * type_size, 'r'); - int size_read; - auto ret_cmp = MPI_File_read_ordered(fh_cmp, read_data.data(), count, - datatype, &stat_cmp); - REQUIRE(ret_orig == ret_cmp); - MPI_Get_count(&stat_orig, datatype, &size_read_orig); - MPI_Get_count(&stat_cmp, datatype, &size_read); - REQUIRE(size_read == size_read_orig); - test_read_data(size_read, count, type_size, - reinterpret_cast(read_data.data()), ptr); -} - -void test_read_at(char* ptr, size_t count, MPI_Datatype datatype, - MPI_Offset offset) { - MPI_Status stat_orig, stat_cmp; - auto ret_orig = - MPI_File_read_at(fh_orig, offset, ptr, count, datatype, &stat_orig); - int type_size; - MPI_Type_size(datatype, &type_size); - std::vector read_data(count * type_size, 'r'); - int size_read; - auto ret_cmp = MPI_File_read_at(fh_cmp, offset, read_data.data(), count, - datatype, &stat_cmp); - REQUIRE(ret_orig == ret_cmp); - MPI_Get_count(&stat_orig, datatype, &size_read_orig); - MPI_Get_count(&stat_cmp, datatype, &size_read); - REQUIRE(size_read == size_read_orig); - test_read_data(size_read, count, type_size, - reinterpret_cast(read_data.data()), ptr); -} - -void test_iread_at(char* ptr, size_t count, MPI_Datatype datatype, - MPI_Offset offset) { - MPI_Status stat[2]; - MPI_Request request[2]; - auto ret_orig = - MPI_File_iread_at(fh_orig, offset, ptr, count, datatype, &request[0]); - int type_size; - MPI_Type_size(datatype, &type_size); - std::vector read_data(count * type_size, 'r'); - int size_read; - auto ret_cmp = MPI_File_iread_at(fh_cmp, offset, read_data.data(), count, - datatype, &request[1]); - REQUIRE(ret_orig == ret_cmp); - MPI_Waitall(2, request, stat); - MPI_Get_count(&stat[0], datatype, &size_read_orig); - MPI_Get_count(&stat[1], datatype, &size_read); - REQUIRE(size_read == size_read_orig); - test_read_data(size_read, count, type_size, - reinterpret_cast(read_data.data()), ptr); -} - -void test_read_at_all(char* ptr, size_t count, MPI_Datatype datatype, - MPI_Offset offset) { - MPI_Status stat_orig, stat_cmp; - auto ret_orig = - MPI_File_read_at_all(fh_orig, offset, ptr, count, datatype, &stat_orig); - int type_size; - MPI_Type_size(datatype, &type_size); - std::vector read_data(count * type_size, 'r'); - int size_read; - auto ret_cmp = MPI_File_read_at_all(fh_cmp, offset, read_data.data(), count, - datatype, &stat_cmp); - REQUIRE(ret_orig == ret_cmp); - MPI_Get_count(&stat_orig, datatype, &size_read_orig); - MPI_Get_count(&stat_cmp, datatype, &size_read); - REQUIRE(size_read == size_read_orig); - test_read_data(size_read, count, type_size, - reinterpret_cast(read_data.data()), ptr); -} - -void test_iread_at_all(char* ptr, size_t count, MPI_Datatype datatype, - MPI_Offset offset) { - MPI_Status stat[2]; - MPI_Request request[2]; - auto ret_orig = - MPI_File_iread_at_all(fh_orig, offset, ptr, count, datatype, &request[0]); - int type_size; - MPI_Type_size(datatype, &type_size); - std::vector read_data(count * type_size, 'r'); - int size_read; - auto ret_cmp = MPI_File_iread_at_all(fh_cmp, offset, read_data.data(), count, - datatype, &request[1]); - REQUIRE(ret_orig == ret_cmp); - MPI_Waitall(2, request, stat); - MPI_Get_count(&stat[0], datatype, &size_read_orig); - MPI_Get_count(&stat[1], datatype, &size_read); - REQUIRE(size_read == size_read_orig); - test_read_data(size_read, count, type_size, - reinterpret_cast(read_data.data()), ptr); -} - -void test_seek(MPI_Offset offset, int whence) { - status_orig = MPI_File_seek(fh_orig, offset, whence); - int status = MPI_File_seek(fh_cmp, offset, whence); - REQUIRE(status == status_orig); -} - -void test_seek_shared(MPI_Offset offset, int whence) { - status_orig = MPI_File_seek_shared(fh_orig, offset, whence); - int status = MPI_File_seek_shared(fh_cmp, offset, whence); - REQUIRE(status == status_orig); -} -} // namespace test - -#include "mpiio_adapter_basic_test.cpp" diff --git a/test/unit/hermes_adapters/mpiio/mpiio_adapter_test.h b/test/unit/hermes_adapters/mpiio/mpiio_adapter_test.h new file mode 100644 index 000000000..a8512e4d0 --- /dev/null +++ b/test/unit/hermes_adapters/mpiio/mpiio_adapter_test.h @@ -0,0 +1,496 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Distributed under BSD 3-Clause license. * + * Copyright by The HDF Group. * + * Copyright by the Illinois Institute of Technology. * + * All rights reserved. * + * * + * This file is part of Hermes. The full Hermes copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the top directory. If you do not * + * have access to the file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef HERMES_TEST_UNIT_HERMES_ADAPTERS_POSIX_POSIX_ADAPTER_BASE_TEST_H_ +#define HERMES_TEST_UNIT_HERMES_ADAPTERS_POSIX_POSIX_ADAPTER_BASE_TEST_H_ + +#include "binary_file_tests.h" + +namespace hermes::adapter::test { +template +class MpiioTest : public BinaryFileTests { + public: + FileInfo new_file_; + FileInfo existing_file_; + FileInfo shared_new_file_; + FileInfo shared_existing_file_; + FileInfo tmp_file_; + unsigned int offset_seed_ = 1; + unsigned int rs_seed_ = 1; + unsigned int temporal_interval_seed_ = 5; + size_t stride_size_ = 1024; + unsigned int temporal_interval_ms_ = 1; + size_t small_min_ = 1; + size_t small_max_ = 4 * 1024; + size_t medium_min_ = 4 * 1024 + 1; + size_t medium_max_ = 256 * 1024; + size_t large_min_ = 256 * 1024 + 1; + size_t large_max_ = 3 * 1024 * 1024; + + MPI_File fh_orig_; + MPI_File fh_cmp_; + int status_orig_; + int size_read_orig_; + int size_written_orig_; + + public: + void RegisterFiles() override { + RegisterPath("new", 0, new_file_); + RegisterPath("ext", TEST_DO_CREATE, existing_file_); + if constexpr(WITH_MPI) { + RegisterPath("shared_new", TEST_FILE_SHARED, shared_new_file_); + RegisterPath("shared_ext", TEST_DO_CREATE | TEST_FILE_SHARED, + shared_existing_file_); + } + RegisterTmpPath(tmp_file_); + } + + void test_read_data(size_t size_read, size_t count, int type_size, + char* read_data, char* ptr) { + if (size_read > 0) { + size_t unmatching_chars = 0; + for (size_t i = 0; i < count * type_size; ++i) { + if (read_data[i] != ptr[i]) { + unmatching_chars = i; + break; + } + } + REQUIRE(unmatching_chars == 0); + } + } + + void test_open(FileInfo &info, int mode, MPI_Comm comm) { + status_orig_ = MPI_File_open(comm, info.hermes_.c_str(), + mode, MPI_INFO_NULL, &fh_orig_); + auto status_cmp = + MPI_File_open(comm, info.cmp_.c_str(), mode, MPI_INFO_NULL, &fh_cmp_); + bool is_same = (status_orig_ != MPI_SUCCESS && status_cmp != MPI_SUCCESS) || + (status_orig_ == MPI_SUCCESS && status_cmp == MPI_SUCCESS); + REQUIRE(is_same); + } + void test_close() { + status_orig_ = MPI_File_close(&fh_orig_); + int status = MPI_File_close(&fh_cmp_); + REQUIRE(status == status_orig_); + } + + void test_preallocate(MPI_Offset size) { + status_orig_ = MPI_File_preallocate(fh_orig_, size); + int status = MPI_File_preallocate(fh_cmp_, size); + REQUIRE(status == status_orig_); + } + + void test_write(const void* ptr, size_t count, MPI_Datatype datatype) { + MPI_Status stat_orig, stat_cmp; + auto ret_orig = MPI_File_write(fh_orig_, ptr, count, datatype, &stat_orig); + int size_written; + auto ret_cmp = MPI_File_write(fh_cmp_, ptr, count, datatype, &stat_cmp); + REQUIRE(ret_orig == ret_cmp); + MPI_Get_count(&stat_orig, datatype, &size_written_orig_); + MPI_Get_count(&stat_cmp, datatype, &size_written); + REQUIRE(size_written == size_written_orig_); + } + + void test_iwrite(const void* ptr, size_t count, MPI_Datatype datatype) { + MPI_Status stat[2]; + MPI_Request request[2]; + auto ret_orig = MPI_File_iwrite(fh_orig_, ptr, count, + datatype, &request[0]); + int size_written; + auto ret_cmp = MPI_File_iwrite(fh_cmp_, ptr, count, + datatype, &request[1]); + REQUIRE(ret_orig == ret_cmp); + MPI_Waitall(2, request, stat); + MPI_Get_count(&stat[0], datatype, &size_written_orig_); + MPI_Get_count(&stat[1], datatype, &size_written); + REQUIRE(size_written == size_written_orig_); + } + + void test_write_shared(const void* ptr, size_t count, + MPI_Datatype datatype) { + MPI_Status stat_orig, stat_cmp; + auto ret_orig = + MPI_File_write_shared(fh_orig_, ptr, count, datatype, &stat_orig); + int size_written; + auto ret_cmp = MPI_File_write_shared(fh_cmp_, ptr, count, + datatype, &stat_cmp); + REQUIRE(ret_orig == ret_cmp); + MPI_Get_count(&stat_orig, datatype, &size_written_orig_); + MPI_Get_count(&stat_cmp, datatype, &size_written); + REQUIRE(size_written == size_written_orig_); + } + + void test_iwrite_shared(const void* ptr, size_t count, + MPI_Datatype datatype) { + MPI_Status stat[2]; + MPI_Request request[2]; + auto ret_orig = + MPI_File_iwrite_shared(fh_orig_, ptr, count, datatype, &request[0]); + int size_written; + auto ret_cmp = + MPI_File_iwrite_shared(fh_cmp_, ptr, count, datatype, &request[1]); + REQUIRE(ret_orig == ret_cmp); + MPI_Waitall(2, request, stat); + MPI_Get_count(&stat[0], datatype, &size_written_orig_); + MPI_Get_count(&stat[1], datatype, &size_written); + REQUIRE(size_written == size_written_orig_); + } + + void test_write_all(const void* ptr, size_t count, MPI_Datatype datatype) { + MPI_Status stat_orig, stat_cmp; + auto ret_orig = MPI_File_write_all(fh_orig_, ptr, count, + datatype, &stat_orig); + int size_written; + auto ret_cmp = MPI_File_write_all(fh_cmp_, ptr, count, + datatype, &stat_cmp); + REQUIRE(ret_orig == ret_cmp); + MPI_Get_count(&stat_orig, datatype, &size_written_orig_); + MPI_Get_count(&stat_cmp, datatype, &size_written); + REQUIRE(size_written == size_written_orig_); + } + + void test_iwrite_all(const void* ptr, size_t count, MPI_Datatype datatype) { + MPI_Status stat[2]; + MPI_Request request[2]; + auto ret_orig = + MPI_File_iwrite_all(fh_orig_, ptr, count, datatype, &request[0]); + int size_written; + auto ret_cmp = MPI_File_iwrite_all(fh_cmp_, ptr, count, + datatype, &request[1]); + REQUIRE(ret_orig == ret_cmp); + MPI_Waitall(2, request, stat); + MPI_Get_count(&stat[0], datatype, &size_written_orig_); + MPI_Get_count(&stat[1], datatype, &size_written); + REQUIRE(size_written == size_written_orig_); + } + + void test_write_at(const void* ptr, size_t count, MPI_Datatype datatype, + MPI_Offset offset) { + MPI_Status stat_orig, stat_cmp; + auto ret_orig = + MPI_File_write_at(fh_orig_, offset, ptr, count, datatype, &stat_orig); + int size_written; + auto ret_cmp = + MPI_File_write_at(fh_cmp_, offset, ptr, count, datatype, &stat_cmp); + REQUIRE(ret_orig == ret_cmp); + MPI_Get_count(&stat_orig, datatype, &size_written_orig_); + MPI_Get_count(&stat_cmp, datatype, &size_written); + REQUIRE(size_written == size_written_orig_); + } + + void test_iwrite_at(const void* ptr, size_t count, MPI_Datatype datatype, + MPI_Offset offset) { + MPI_Status stat[2]; + MPI_Request request[2]; + auto ret_orig = + MPI_File_iwrite_at(fh_orig_, offset, ptr, count, datatype, &request[0]); + int size_written; + auto ret_cmp = + MPI_File_iwrite_at(fh_cmp_, offset, ptr, count, datatype, &request[1]); + REQUIRE(ret_orig == ret_cmp); + MPI_Waitall(2, request, stat); + MPI_Get_count(&stat[0], datatype, &size_written_orig_); + MPI_Get_count(&stat[0], datatype, &size_written); + REQUIRE(size_written == size_written_orig_); + } + + void test_write_at_all(const void* ptr, size_t count, + MPI_Datatype datatype, + MPI_Offset offset) { + MPI_Status stat_orig, stat_cmp; + auto ret_orig = + MPI_File_write_at_all(fh_orig_, offset, ptr, count, + datatype, &stat_orig); + int size_written; + auto ret_cmp = + MPI_File_write_at_all(fh_cmp_, offset, ptr, count, + datatype, &stat_cmp); + REQUIRE(ret_orig == ret_cmp); + MPI_Get_count(&stat_orig, datatype, &size_written_orig_); + MPI_Get_count(&stat_cmp, datatype, &size_written); + REQUIRE(size_written == size_written_orig_); + } + + void test_iwrite_at_all(const void* ptr, size_t count, + MPI_Datatype datatype, + MPI_Offset offset) { + MPI_Status stat[2]; + MPI_Request request[2]; + auto ret_orig = MPI_File_iwrite_at_all(fh_orig_, offset, ptr, + count, datatype, + &request[0]); + int size_written; + auto ret_cmp = + MPI_File_iwrite_at_all(fh_cmp_, offset, ptr, count, + datatype, &request[1]); + REQUIRE(ret_orig == ret_cmp); + MPI_Waitall(2, request, stat); + MPI_Get_count(&stat[0], datatype, &size_written_orig_); + MPI_Get_count(&stat[1], datatype, &size_written); + REQUIRE(size_written == size_written_orig_); + } + + void test_write_ordered(const void* ptr, size_t count, + MPI_Datatype datatype) { + MPI_Status stat_orig, stat_cmp; + auto ret_orig = + MPI_File_write_ordered(fh_orig_, ptr, count, datatype, &stat_orig); + int size_written; + auto ret_cmp = + MPI_File_write_ordered(fh_cmp_, ptr, count, datatype, &stat_cmp); + REQUIRE(ret_orig == ret_cmp); + MPI_Get_count(&stat_orig, datatype, &size_written_orig_); + MPI_Get_count(&stat_cmp, datatype, &size_written); + REQUIRE(size_written == size_written_orig_); + } + + void test_read(char* ptr, size_t count, MPI_Datatype datatype) { + MPI_Status stat_orig, stat_cmp; + auto ret_orig = MPI_File_read(fh_orig_, ptr, count, + datatype, &stat_orig); + int type_size; + MPI_Type_size(datatype, &type_size); + std::vector read_data(count * type_size, 'r'); + int size_read; + auto ret_cmp = + MPI_File_read(fh_cmp_, read_data.data(), count, + datatype, &stat_cmp); + REQUIRE(ret_orig == ret_cmp); + MPI_Get_count(&stat_orig, datatype, &size_read_orig_); + MPI_Get_count(&stat_cmp, datatype, &size_read); + REQUIRE(size_read == size_read_orig_); + test_read_data(size_read, count, type_size, + reinterpret_cast(read_data.data()), ptr); + } + + void test_iread(char* ptr, size_t count, MPI_Datatype datatype) { + MPI_Status stat[2]; + MPI_Request request[2]; + auto ret_orig = MPI_File_iread(fh_orig_, ptr, count, + datatype, &request[0]); + int type_size; + MPI_Type_size(datatype, &type_size); + std::vector read_data(count * type_size, 'r'); + int size_read; + auto ret_cmp = + MPI_File_iread(fh_cmp_, read_data.data(), count, + datatype, &request[1]); + REQUIRE(ret_orig == ret_cmp); + MPI_Waitall(2, request, stat); + MPI_Get_count(&stat[0], datatype, &size_read_orig_); + MPI_Get_count(&stat[1], datatype, &size_read); + REQUIRE(size_read == size_read_orig_); + test_read_data(size_read, count, type_size, + reinterpret_cast(read_data.data()), ptr); + } + + void test_read_shared(char* ptr, size_t count, MPI_Datatype datatype) { + MPI_Status stat_orig, stat_cmp; + auto ret_orig = + MPI_File_read_shared(fh_orig_, ptr, count, datatype, &stat_orig); + int type_size; + MPI_Type_size(datatype, &type_size); + std::vector read_data(count * type_size, 'r'); + int size_read; + auto ret_cmp = MPI_File_read_shared(fh_cmp_, read_data.data(), + count, datatype, + &stat_cmp); + REQUIRE(ret_orig == ret_cmp); + MPI_Get_count(&stat_orig, datatype, &size_read_orig_); + MPI_Get_count(&stat_cmp, datatype, &size_read); + REQUIRE(size_read == size_read_orig_); + test_read_data(size_read, count, type_size, + reinterpret_cast(read_data.data()), ptr); + } + + void test_iread_shared(char* ptr, size_t count, MPI_Datatype datatype) { + MPI_Status stat[2]; + MPI_Request request[2]; + auto ret_orig = + MPI_File_iread_shared(fh_orig_, ptr, count, datatype, &request[0]); + int type_size; + MPI_Type_size(datatype, &type_size); + std::vector read_data(count * type_size, 'r'); + int size_read; + auto ret_cmp = MPI_File_iread_shared(fh_cmp_, + read_data.data(), count, + datatype, &request[1]); + REQUIRE(ret_orig == ret_cmp); + MPI_Waitall(2, request, stat); + MPI_Get_count(&stat[0], datatype, &size_read_orig_); + MPI_Get_count(&stat[1], datatype, &size_read); + REQUIRE(size_read == size_read_orig_); + test_read_data(size_read, count, type_size, + reinterpret_cast(read_data.data()), ptr); + } + + void test_read_all(char* ptr, size_t count, MPI_Datatype datatype) { + MPI_Status stat_orig, stat_cmp; + auto ret_orig = MPI_File_read_all(fh_orig_, ptr, count, + datatype, &stat_orig); + int type_size; + MPI_Type_size(datatype, &type_size); + std::vector read_data(count * type_size, 'r'); + int size_read; + auto ret_cmp = + MPI_File_read_all(fh_cmp_, read_data.data(), count, + datatype, &stat_cmp); + REQUIRE(ret_orig == ret_cmp); + MPI_Get_count(&stat_orig, datatype, &size_read_orig_); + MPI_Get_count(&stat_cmp, datatype, &size_read); + REQUIRE(size_read == size_read_orig_); + test_read_data(size_read, count, type_size, + reinterpret_cast(read_data.data()), ptr); + } + + void test_iread_all(char* ptr, size_t count, MPI_Datatype datatype) { + MPI_Status stat[2]; + MPI_Request request[2]; + auto ret_orig = + MPI_File_iread_all(fh_orig_, ptr, count, datatype, &request[0]); + int type_size; + MPI_Type_size(datatype, &type_size); + std::vector read_data(count * type_size, 'r'); + int size_read; + auto ret_cmp = MPI_File_iread_all(fh_cmp_, read_data.data(), + count, datatype, + &request[1]); + REQUIRE(ret_orig == ret_cmp); + MPI_Waitall(2, request, stat); + MPI_Get_count(&stat[0], datatype, &size_read_orig_); + MPI_Get_count(&stat[1], datatype, &size_read); + REQUIRE(size_read == size_read_orig_); + test_read_data(size_read, count, type_size, + reinterpret_cast(read_data.data()), ptr); + } + + void test_read_ordered(char* ptr, size_t count, MPI_Datatype datatype) { + MPI_Status stat_orig, stat_cmp; + auto ret_orig = + MPI_File_read_ordered(fh_orig_, ptr, count, datatype, &stat_orig); + int type_size; + MPI_Type_size(datatype, &type_size); + std::vector read_data(count * type_size, 'r'); + int size_read; + auto ret_cmp = MPI_File_read_ordered(fh_cmp_, read_data.data(), count, + datatype, &stat_cmp); + REQUIRE(ret_orig == ret_cmp); + MPI_Get_count(&stat_orig, datatype, &size_read_orig_); + MPI_Get_count(&stat_cmp, datatype, &size_read); + REQUIRE(size_read == size_read_orig_); + test_read_data(size_read, count, type_size, + reinterpret_cast(read_data.data()), ptr); + } + + void test_read_at(char* ptr, size_t count, MPI_Datatype datatype, + MPI_Offset offset) { + MPI_Status stat_orig, stat_cmp; + auto ret_orig = + MPI_File_read_at(fh_orig_, offset, ptr, count, datatype, &stat_orig); + int type_size; + MPI_Type_size(datatype, &type_size); + std::vector read_data(count * type_size, 'r'); + int size_read; + auto ret_cmp = MPI_File_read_at(fh_cmp_, offset, read_data.data(), count, + datatype, &stat_cmp); + REQUIRE(ret_orig == ret_cmp); + MPI_Get_count(&stat_orig, datatype, &size_read_orig_); + MPI_Get_count(&stat_cmp, datatype, &size_read); + REQUIRE(size_read == size_read_orig_); + test_read_data(size_read, count, type_size, + reinterpret_cast(read_data.data()), ptr); + } + + void test_iread_at(char* ptr, size_t count, MPI_Datatype datatype, + MPI_Offset offset) { + MPI_Status stat[2]; + MPI_Request request[2]; + auto ret_orig = + MPI_File_iread_at(fh_orig_, offset, ptr, count, datatype, &request[0]); + int type_size; + MPI_Type_size(datatype, &type_size); + std::vector read_data(count * type_size, 'r'); + int size_read; + auto ret_cmp = MPI_File_iread_at(fh_cmp_, offset, read_data.data(), count, + datatype, &request[1]); + REQUIRE(ret_orig == ret_cmp); + MPI_Waitall(2, request, stat); + MPI_Get_count(&stat[0], datatype, &size_read_orig_); + MPI_Get_count(&stat[1], datatype, &size_read); + REQUIRE(size_read == size_read_orig_); + test_read_data(size_read, count, type_size, + reinterpret_cast(read_data.data()), ptr); + } + + void test_read_at_all(char* ptr, size_t count, MPI_Datatype datatype, + MPI_Offset offset) { + MPI_Status stat_orig, stat_cmp; + auto ret_orig = + MPI_File_read_at_all(fh_orig_, offset, ptr, count, + datatype, &stat_orig); + int type_size; + MPI_Type_size(datatype, &type_size); + std::vector read_data(count * type_size, 'r'); + int size_read; + auto ret_cmp = MPI_File_read_at_all(fh_cmp_, offset, + read_data.data(), count, + datatype, &stat_cmp); + REQUIRE(ret_orig == ret_cmp); + MPI_Get_count(&stat_orig, datatype, &size_read_orig_); + MPI_Get_count(&stat_cmp, datatype, &size_read); + REQUIRE(size_read == size_read_orig_); + test_read_data(size_read, count, type_size, + reinterpret_cast(read_data.data()), ptr); + } + + void test_iread_at_all(char* ptr, size_t count, MPI_Datatype datatype, + MPI_Offset offset) { + MPI_Status stat[2]; + MPI_Request request[2]; + auto ret_orig = + MPI_File_iread_at_all(fh_orig_, offset, ptr, count, + datatype, &request[0]); + int type_size; + MPI_Type_size(datatype, &type_size); + std::vector read_data(count * type_size, 'r'); + int size_read; + auto ret_cmp = MPI_File_iread_at_all(fh_cmp_, offset, + read_data.data(), count, + datatype, &request[1]); + REQUIRE(ret_orig == ret_cmp); + MPI_Waitall(2, request, stat); + MPI_Get_count(&stat[0], datatype, &size_read_orig_); + MPI_Get_count(&stat[1], datatype, &size_read); + REQUIRE(size_read == size_read_orig_); + test_read_data(size_read, count, type_size, + reinterpret_cast(read_data.data()), ptr); + } + + void test_seek(MPI_Offset offset, int whence) { + status_orig_ = MPI_File_seek(fh_orig_, offset, whence); + int status = MPI_File_seek(fh_cmp_, offset, whence); + REQUIRE(status == status_orig_); + } + + void test_seek_shared(MPI_Offset offset, int whence) { + status_orig_ = MPI_File_seek_shared(fh_orig_, offset, whence); + int status = MPI_File_seek_shared(fh_cmp_, offset, whence); + REQUIRE(status == status_orig_); + } +}; + +} // namespace hermes::adapter::test + +#define TESTER \ + hshm::EasySingleton>::GetInstance() + +#endif // HERMES_TEST_UNIT_HERMES_ADAPTERS_POSIX_POSIX_ADAPTER_BASE_TEST_H_ diff --git a/test/unit/hermes_adapters/mpiio/tests.py b/test/unit/hermes_adapters/mpiio/tests.py deleted file mode 100644 index 26c575672..000000000 --- a/test/unit/hermes_adapters/mpiio/tests.py +++ /dev/null @@ -1,35 +0,0 @@ -from py_hermes_ci.test_manager import TestManager -from jarvis_util import * - - -class MpiioTestManager(TestManager): - def spawn_all_nodes(self): - return self.spawn_info() - - def set_paths(self): - self.MPIIO_CMD = f"{self.CMAKE_BINARY_DIR}/bin/mpiio_adapter_test" - self.HERMES_MPIIO_CMD = f"{self.CMAKE_BINARY_DIR}/bin/hermes_mpiio_adapter_test" - - self.disable_testing = False - - def test_hermes_mpiio_basic_sync(self): - mpiio_cmd = f"{self.HERMES_MPIIO_CMD} " \ - f"[synchronicity=sync] " \ - f"--reporter compact -d yes" - spawn_info = self.spawn_info(nprocs=2, - hermes_conf='hermes_server') - self.start_daemon(spawn_info) - node = Exec(mpiio_cmd, spawn_info) - self.stop_daemon(spawn_info) - return node.exit_code - - def test_hermes_mpiio_basic_async(self): - mpiio_cmd = f"{self.HERMES_MPIIO_CMD} " \ - f"[synchronicity=async] " \ - f"--reporter compact -d yes" - spawn_info = self.spawn_info(nprocs=2, - hermes_conf='hermes_server') - self.start_daemon(spawn_info) - node = Exec(mpiio_cmd, spawn_info) - self.stop_daemon(spawn_info) - return node.exit_code \ No newline at end of file diff --git a/test/unit/hermes_adapters/posix/CMakeLists.txt b/test/unit/hermes_adapters/posix/CMakeLists.txt index 7ade82ef1..f2b8c28cf 100644 --- a/test/unit/hermes_adapters/posix/CMakeLists.txt +++ b/test/unit/hermes_adapters/posix/CMakeLists.txt @@ -8,8 +8,7 @@ include_directories(${CMAKE_SOURCE_DIR}/src) add_executable(posix_adapter_test posix_adapter_test.cc posix_adapter_basic_test.cc - posix_adapter_rs_test.cc - ${ADAPTER_COMMON}) + posix_adapter_rs_test.cc) add_dependencies(posix_adapter_test hermes) target_link_libraries(posix_adapter_test @@ -21,8 +20,7 @@ jarvis_test(posix test_posix_basic) add_executable(hermes_posix_adapter_test posix_adapter_test.cc posix_adapter_basic_test.cc - posix_adapter_rs_test.cc - ${ADAPTER_COMMON}) + posix_adapter_rs_test.cc) add_dependencies(hermes_posix_adapter_test hermes_posix) target_link_libraries(hermes_posix_adapter_test @@ -37,7 +35,7 @@ add_executable(posix_adapter_mpi_test posix_adapter_basic_test.cc posix_adapter_rs_test.cc # posix_adapter_shared_test.cc - ${ADAPTER_COMMON}) +) add_dependencies(posix_adapter_mpi_test hermes) target_link_libraries(posix_adapter_mpi_test @@ -51,7 +49,7 @@ add_executable(hermes_posix_adapter_mpi_test posix_adapter_basic_test.cc posix_adapter_rs_test.cc # posix_adapter_shared_test.cc - ${ADAPTER_COMMON}) +) add_dependencies(hermes_posix_adapter_mpi_test hermes_posix) target_link_libraries(hermes_posix_adapter_mpi_test @@ -85,8 +83,8 @@ jarvis_test(posix test_hermes_posix_simple_io_omp) set(POSIX_TESTS posix_adapter_test hermes_posix_adapter_test -# posix_adapter_mpi_test -# hermes_posix_adapter_mpi_test + posix_adapter_mpi_test + hermes_posix_adapter_mpi_test posix_simple_io_mpi posix_simple_io_omp ) diff --git a/test/unit/hermes_adapters/posix/posix_adapter_basic_test.cc b/test/unit/hermes_adapters/posix/posix_adapter_basic_test.cc index a17f0f248..943323dae 100644 --- a/test/unit/hermes_adapters/posix/posix_adapter_basic_test.cc +++ b/test/unit/hermes_adapters/posix/posix_adapter_basic_test.cc @@ -13,1134 +13,1174 @@ #include #include "posix_adapter_test.h" -TEST_CASE("Open", "[process=" + std::to_string(TEST_INFO->comm_size_) + +TEST_CASE("Open", "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=single_open]" "[repetition=1][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("open non-existant file") { - TEST_INFO->test_open(TEST_INFO->new_file_, O_WRONLY); - REQUIRE(TEST_INFO->fh_orig_ == -1); - TEST_INFO->test_open(TEST_INFO->new_file_, O_RDONLY); - REQUIRE(TEST_INFO->fh_orig_ == -1); - TEST_INFO->test_open(TEST_INFO->new_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ == -1); + TESTER->test_open(TESTER->new_file_, O_WRONLY); + REQUIRE(TESTER->fh_orig_ == -1); + TESTER->test_open(TESTER->new_file_, O_RDONLY); + REQUIRE(TESTER->fh_orig_ == -1); + TESTER->test_open(TESTER->new_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ == -1); } SECTION("truncate existing file and write-only") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_WRONLY | O_TRUNC); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_open(TESTER->existing_file_, O_WRONLY | O_TRUNC); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("truncate existing file and read/write") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR | O_TRUNC); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_open(TESTER->existing_file_, O_RDWR | O_TRUNC); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("open existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_WRONLY); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDONLY); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_open(TESTER->existing_file_, O_WRONLY); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_open(TESTER->existing_file_, O_RDONLY); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("append write existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_APPEND); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_open(TESTER->existing_file_, O_APPEND); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("create a new file") { - TEST_INFO->test_open(TEST_INFO->new_file_, O_WRONLY | O_CREAT, 0600); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - stdfs::remove(TEST_INFO->new_file_.hermes_); - - TEST_INFO->test_open(TEST_INFO->new_file_, O_RDONLY | O_CREAT, 0600); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - stdfs::remove(TEST_INFO->new_file_.hermes_); - - TEST_INFO->test_open(TEST_INFO->new_file_, O_RDWR | O_CREAT, 0600); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_open(TESTER->new_file_, O_WRONLY | O_CREAT, 0600); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + stdfs::remove(TESTER->new_file_.hermes_); + + TESTER->test_open(TESTER->new_file_, O_RDONLY | O_CREAT, 0600); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + stdfs::remove(TESTER->new_file_.hermes_); + + TESTER->test_open(TESTER->new_file_, O_RDWR | O_CREAT, 0600); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("create a existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_WRONLY | O_CREAT, 0600); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDONLY | O_CREAT, 0600); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR | O_CREAT, 0600); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - - TEST_INFO->test_open(TEST_INFO->existing_file_, O_WRONLY | O_CREAT | O_EXCL, - 0600); - REQUIRE(TEST_INFO->fh_orig_ == -1); - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDONLY | O_CREAT | O_EXCL, - 0600); - REQUIRE(TEST_INFO->fh_orig_ == -1); - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR | O_CREAT | O_EXCL, - 0600); - REQUIRE(TEST_INFO->fh_orig_ == -1); + TESTER->test_open(TESTER->existing_file_, O_WRONLY | O_CREAT, 0600); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_open(TESTER->existing_file_, O_RDONLY | O_CREAT, 0600); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_open(TESTER->existing_file_, O_RDWR | O_CREAT, 0600); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + + TESTER->test_open(TESTER->existing_file_, O_WRONLY | O_CREAT | O_EXCL, + 0600); + REQUIRE(TESTER->fh_orig_ == -1); + TESTER->test_open(TESTER->existing_file_, O_RDONLY | O_CREAT | O_EXCL, + 0600); + REQUIRE(TESTER->fh_orig_ == -1); + TESTER->test_open(TESTER->existing_file_, O_RDWR | O_CREAT | O_EXCL, + 0600); + REQUIRE(TESTER->fh_orig_ == -1); } SECTION("Async I/O") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_WRONLY | O_ASYNC); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDONLY | O_ASYNC); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR | O_ASYNC); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_open(TEST_INFO->existing_file_, O_APPEND | O_ASYNC); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - - TEST_INFO->test_open(TEST_INFO->existing_file_, O_WRONLY | O_NONBLOCK); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDONLY | O_NONBLOCK); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR | O_NONBLOCK); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_open(TEST_INFO->existing_file_, O_APPEND | O_NONBLOCK); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - - TEST_INFO->test_open(TEST_INFO->existing_file_, O_WRONLY | O_NDELAY); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDONLY | O_NDELAY); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR | O_NDELAY); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_open(TEST_INFO->existing_file_, O_APPEND | O_NDELAY); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_open(TESTER->existing_file_, O_WRONLY | O_ASYNC); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_open(TESTER->existing_file_, O_RDONLY | O_ASYNC); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_open(TESTER->existing_file_, O_RDWR | O_ASYNC); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_open(TESTER->existing_file_, O_APPEND | O_ASYNC); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + + TESTER->test_open(TESTER->existing_file_, O_WRONLY | O_NONBLOCK); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_open(TESTER->existing_file_, O_RDONLY | O_NONBLOCK); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_open(TESTER->existing_file_, O_RDWR | O_NONBLOCK); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_open(TESTER->existing_file_, O_APPEND | O_NONBLOCK); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + + TESTER->test_open(TESTER->existing_file_, O_WRONLY | O_NDELAY); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_open(TESTER->existing_file_, O_RDONLY | O_NDELAY); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_open(TESTER->existing_file_, O_RDWR | O_NDELAY); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_open(TESTER->existing_file_, O_APPEND | O_NDELAY); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("Async I/O") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_WRONLY | O_DIRECT); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDONLY | O_DIRECT); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR | O_DIRECT); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_open(TEST_INFO->existing_file_, O_APPEND | O_DIRECT); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_open(TESTER->existing_file_, O_WRONLY | O_DIRECT); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_open(TESTER->existing_file_, O_RDONLY | O_DIRECT); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_open(TESTER->existing_file_, O_RDWR | O_DIRECT); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_open(TESTER->existing_file_, O_APPEND | O_DIRECT); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("Write Synchronize") { /* File synchronicity */ - TEST_INFO->test_open(TEST_INFO->existing_file_, O_WRONLY | O_DSYNC); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDONLY | O_DSYNC); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR | O_DSYNC); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_open(TEST_INFO->existing_file_, O_APPEND | O_DSYNC); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_open(TESTER->existing_file_, O_WRONLY | O_DSYNC); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_open(TESTER->existing_file_, O_RDONLY | O_DSYNC); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_open(TESTER->existing_file_, O_RDWR | O_DSYNC); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_open(TESTER->existing_file_, O_APPEND | O_DSYNC); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); /* Write synchronicity */ - TEST_INFO->test_open(TEST_INFO->existing_file_, O_WRONLY | O_SYNC); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDONLY | O_SYNC); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR | O_SYNC); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_open(TEST_INFO->existing_file_, O_APPEND | O_SYNC); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_open(TESTER->existing_file_, O_WRONLY | O_SYNC); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_open(TESTER->existing_file_, O_RDONLY | O_SYNC); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_open(TESTER->existing_file_, O_RDWR | O_SYNC); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_open(TESTER->existing_file_, O_APPEND | O_SYNC); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("Temporary file") { - if (TEST_INFO->supports_tmpfile) { - TEST_INFO->test_open(TEST_INFO->tmp_file_, O_WRONLY | O_TMPFILE, 0600); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDONLY | O_TMPFILE, 0600); - REQUIRE(TEST_INFO->fh_orig_ == -1); - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR | O_TMPFILE, 0600); - REQUIRE(TEST_INFO->fh_orig_ == -1); - TEST_INFO->test_open(TEST_INFO->existing_file_, O_APPEND | O_TMPFILE, 0600); - REQUIRE(TEST_INFO->fh_orig_ == -1); - - TEST_INFO->test_open(TEST_INFO->existing_file_, O_WRONLY | O_TMPFILE, 0600); - REQUIRE(TEST_INFO->fh_orig_ == -1); - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDONLY | O_TMPFILE, 0600); - REQUIRE(TEST_INFO->fh_orig_ == -1); - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR | O_TMPFILE, 0600); - REQUIRE(TEST_INFO->fh_orig_ == -1); + if (TESTER->supports_tmpfile) { + TESTER->test_open(TESTER->tmp_file_, O_WRONLY | O_TMPFILE, 0600); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_open(TESTER->existing_file_, O_RDONLY | O_TMPFILE, 0600); + REQUIRE(TESTER->fh_orig_ == -1); + TESTER->test_open(TESTER->existing_file_, O_RDWR | O_TMPFILE, 0600); + REQUIRE(TESTER->fh_orig_ == -1); + TESTER->test_open(TESTER->existing_file_, O_APPEND | O_TMPFILE, 0600); + REQUIRE(TESTER->fh_orig_ == -1); + + TESTER->test_open(TESTER->existing_file_, O_WRONLY | O_TMPFILE, 0600); + REQUIRE(TESTER->fh_orig_ == -1); + TESTER->test_open(TESTER->existing_file_, O_RDONLY | O_TMPFILE, 0600); + REQUIRE(TESTER->fh_orig_ == -1); + TESTER->test_open(TESTER->existing_file_, O_RDWR | O_TMPFILE, 0600); + REQUIRE(TESTER->fh_orig_ == -1); } } - TEST_INFO->Posttest(); + TESTER->Posttest(); } -TEST_CASE("SingleWrite", "[process=" + std::to_string(TEST_INFO->comm_size_) + +// TEST_CASE("Remove") { +// TESTER->test_open(TESTER->existing_file_, O_WRONLY | O_TRUNC); +// TESTER->test_write(TESTER->write_data_.data(), TESTER->request_size_); +// stdfs::remove(TESTER->existing_file_.hermes_); +// hermes::Bucket bkt = HERMES->GetBucket(TESTER->existing_file_.hermes_); +// bkt.Destroy(); +// } + +TEST_CASE("SingleWrite", "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=single_write]" "[request_size=type-fixed][repetition=1]" "[file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("write to existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_seek(0, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_write(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); - TEST_INFO->test_close(); - int status = TEST_INFO->status_orig_; - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_seek(0, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_write(TESTER->write_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + int status = TESTER->status_orig_; + REQUIRE(TESTER->status_orig_ == 0); } SECTION("write to new file") { - TEST_INFO->test_open(TEST_INFO->new_file_, O_WRONLY | O_CREAT | O_EXCL, 0600); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_write(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - int size = stdfs::file_size(TEST_INFO->new_file_.hermes_); - int orig_size = TEST_INFO->size_written_orig_; - REQUIRE(stdfs::file_size(TEST_INFO->new_file_.hermes_) == TEST_INFO->size_written_orig_); + TESTER->test_open(TESTER->new_file_, O_WRONLY | O_CREAT | O_EXCL, 0600); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_write(TESTER->write_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + int size = stdfs::file_size(TESTER->new_file_.hermes_); + int orig_size = TESTER->size_written_orig_; + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_) == + TESTER->size_written_orig_); } - SECTION("write to existing file with truncate") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_WRONLY | O_TRUNC); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_write(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - REQUIRE(stdfs::file_size(TEST_INFO->existing_file_.hermes_) == TEST_INFO->size_written_orig_); + TESTER->test_open(TESTER->existing_file_, O_WRONLY | O_TRUNC); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_write(TESTER->write_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->existing_file_.hermes_) == + TESTER->size_written_orig_); } SECTION("write to existing file at the end") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_seek(0, SEEK_END); - REQUIRE(((size_t)TEST_INFO->status_orig_) == - TEST_INFO->request_size_ * TEST_INFO->num_iterations_); - TEST_INFO->test_write(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - REQUIRE(stdfs::file_size(TEST_INFO->existing_file_.hermes_) == - TEST_INFO->size_written_orig_ + TEST_INFO->request_size_ * TEST_INFO->num_iterations_); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_seek(0, SEEK_END); + REQUIRE(((size_t)TESTER->status_orig_) == + TESTER->request_size_ * TESTER->num_iterations_); + TESTER->test_write(TESTER->write_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->existing_file_.hermes_) == + TESTER->size_written_orig_ + + TESTER->request_size_ * TESTER->num_iterations_); } SECTION("append to existing file") { - auto existing_size = stdfs::file_size(TEST_INFO->existing_file_.hermes_); - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR | O_APPEND); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_write(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - REQUIRE(stdfs::file_size(TEST_INFO->existing_file_.hermes_) == - existing_size + TEST_INFO->size_written_orig_); + auto existing_size = stdfs::file_size(TESTER->existing_file_.hermes_); + TESTER->test_open(TESTER->existing_file_, O_RDWR | O_APPEND); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_write(TESTER->write_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->existing_file_.hermes_) == + existing_size + TESTER->size_written_orig_); } SECTION("append to new file") { - TEST_INFO->test_open(TEST_INFO->new_file_, O_WRONLY | O_CREAT | O_EXCL, 0600); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_write(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - REQUIRE(stdfs::file_size(TEST_INFO->new_file_.hermes_) == TEST_INFO->size_written_orig_); - } - TEST_INFO->Posttest(); + TESTER->test_open(TESTER->new_file_, O_WRONLY | O_CREAT | O_EXCL, 0600); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_write(TESTER->write_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_) == + TESTER->size_written_orig_); + } + TESTER->Posttest(); } -TEST_CASE("SingleRead", "[process=" + std::to_string(TEST_INFO->comm_size_) + +TEST_CASE("SingleRead", "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=single_read]" "[request_size=type-fixed][repetition=1]" "[file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from non-existing file") { - TEST_INFO->test_open(TEST_INFO->new_file_, O_RDONLY); - REQUIRE(TEST_INFO->fh_orig_ == -1); + TESTER->test_open(TESTER->new_file_, O_RDONLY); + REQUIRE(TESTER->fh_orig_ == -1); } SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDONLY); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_seek(0, SEEK_CUR); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_read(TEST_INFO->read_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_open(TESTER->existing_file_, O_RDONLY); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_seek(0, SEEK_CUR); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_read(TESTER->read_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("read at the end of existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDONLY); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_seek(0, SEEK_END); - REQUIRE(((size_t)TEST_INFO->status_orig_) == - TEST_INFO->request_size_ * TEST_INFO->num_iterations_); - TEST_INFO->test_read(TEST_INFO->read_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == 0); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - } - TEST_INFO->Posttest(); + TESTER->test_open(TESTER->existing_file_, O_RDONLY); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_seek(0, SEEK_END); + REQUIRE(((size_t)TESTER->status_orig_) == + TESTER->request_size_ * TESTER->num_iterations_); + TESTER->test_read(TESTER->read_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + } + TESTER->Posttest(); } TEST_CASE("BatchedWriteSequential", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=type-fixed][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("write to new file") { - TEST_INFO->test_open(TEST_INFO->new_file_, O_WRONLY | O_CREAT | O_EXCL, 0600); - REQUIRE(TEST_INFO->fh_orig_ != -1); - - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - TEST_INFO->test_seek(0, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_write(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); + TESTER->test_open(TESTER->new_file_, O_WRONLY | O_CREAT | O_EXCL, 0600); + REQUIRE(TESTER->fh_orig_ != -1); + + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_seek(0, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_write(TESTER->write_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - REQUIRE(stdfs::file_size(TEST_INFO->new_file_.hermes_) == TEST_INFO->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_) == + TESTER->request_size_); } SECTION("write to new file always at start") { - TEST_INFO->test_open(TEST_INFO->new_file_, O_WRONLY | O_CREAT | O_EXCL, 0600); - REQUIRE(TEST_INFO->fh_orig_ != -1); + TESTER->test_open(TESTER->new_file_, O_WRONLY | O_CREAT | O_EXCL, 0600); + REQUIRE(TESTER->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - TEST_INFO->test_write(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_write(TESTER->write_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - REQUIRE(stdfs::file_size(TEST_INFO->new_file_.hermes_) == - TEST_INFO->num_iterations_ * TEST_INFO->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_) == + TESTER->num_iterations_ * TESTER->request_size_); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadSequential", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=type-fixed][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - std::string data(TEST_INFO->request_size_, '1'); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - TEST_INFO->test_read(data.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + std::string data(TESTER->request_size_, '1'); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_read(data.data(), TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("read from existing file always at start") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); for (size_t i = 0; i < 1; ++i) { - TEST_INFO->test_seek(0, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->is_scase_ = true; - TEST_INFO->test_write(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); + TESTER->test_seek(0, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->is_scase_ = true; + TESTER->test_write(TESTER->write_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } -TEST_CASE("BatchedReadRandom", "[process=" + std::to_string(TEST_INFO->comm_size_) + +TEST_CASE("BatchedReadRandom", "[process=" + + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=type-fixed]" "[repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "][pattern=random][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - std::string data(TEST_INFO->request_size_, '1'); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + std::string data(TESTER->request_size_, '1'); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t offset = - rand_r(&TEST_INFO->offset_seed_) % (TEST_INFO->total_size_ - TEST_INFO->request_size_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); - TEST_INFO->test_read(data.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); + rand_r(&TESTER->offset_seed_) % + (TESTER->total_size_ - TESTER->request_size_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); + TESTER->test_read(data.data(), TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } -TEST_CASE("BatchedUpdateRandom", "[process=" + std::to_string(TEST_INFO->comm_size_) + +TEST_CASE("BatchedUpdateRandom", "[process=" + + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=type-fixed][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=random][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("update into existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t offset = - rand_r(&TEST_INFO->offset_seed_) % (TEST_INFO->total_size_ - TEST_INFO->request_size_ - 1); - TEST_INFO->test_seek(offset, SEEK_SET); // 630978 - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); - TEST_INFO->test_write(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); - fsync(TEST_INFO->fh_orig_); + rand_r(&TESTER->offset_seed_) % + (TESTER->total_size_ - TESTER->request_size_ - 1); + TESTER->test_seek(offset, SEEK_SET); // 630978 + REQUIRE(((size_t)TESTER->status_orig_) == offset); + TESTER->test_write(TESTER->write_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); + fsync(TESTER->fh_orig_); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadStrideFixed", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=type-fixed][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_fixed][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - std::string data(TEST_INFO->request_size_, '1'); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - size_t offset = (i * TEST_INFO->stride_size_) % TEST_INFO->total_size_; - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); - TEST_INFO->test_read(data.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + std::string data(TESTER->request_size_, '1'); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + size_t offset = (i * TESTER->stride_size_) % TESTER->total_size_; + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); + TESTER->test_read(data.data(), TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStrideFixed", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=type-fixed][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_fixed][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - std::string data(TEST_INFO->request_size_, '1'); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - size_t offset = (i * TEST_INFO->stride_size_) % TEST_INFO->total_size_; - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); - TEST_INFO->test_read(data.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + std::string data(TESTER->request_size_, '1'); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + size_t offset = (i * TESTER->stride_size_) % TESTER->total_size_; + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); + TESTER->test_read(data.data(), TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadStrideDynamic", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=type-fixed][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_dynamic][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - std::string data(TEST_INFO->request_size_, '1'); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - size_t offset = TEST_INFO->GetRandomOffset(i, TEST_INFO->offset_seed_, TEST_INFO->stride_size_, - TEST_INFO->total_size_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); - TEST_INFO->test_read(data.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + std::string data(TESTER->request_size_, '1'); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + size_t offset = TESTER->GetRandomOffset( + i, TESTER->offset_seed_, TESTER->stride_size_, + TESTER->total_size_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); + TESTER->test_read(data.data(), TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStrideDynamic", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=type-fixed][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_dynamic][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - std::string data(TEST_INFO->request_size_, '1'); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - size_t offset = TEST_INFO->GetRandomOffset(i, TEST_INFO->offset_seed_, TEST_INFO->stride_size_, - TEST_INFO->total_size_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); - TEST_INFO->test_read(data.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + std::string data(TESTER->request_size_, '1'); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + size_t offset = TESTER->GetRandomOffset( + i, TESTER->offset_seed_, TESTER->stride_size_, + TESTER->total_size_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); + TESTER->test_read(data.data(), TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedWriteRSVariable", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=type-variable][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("write to new file always at the start") { - TEST_INFO->test_open(TEST_INFO->new_file_, O_WRONLY | O_CREAT | O_EXCL, 0600); - REQUIRE(TEST_INFO->fh_orig_ != -1); + TESTER->test_open(TESTER->new_file_, O_WRONLY | O_CREAT | O_EXCL, 0600); + REQUIRE(TESTER->fh_orig_ != -1); size_t biggest_size_written = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - TEST_INFO->test_seek(0, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_seek(0, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->request_size_ + (rand_r(&TEST_INFO->offset_seed_) % TEST_INFO->request_size_); + TESTER->request_size_ + + (rand_r(&TESTER->offset_seed_) % TESTER->request_size_); std::string data(request_size, '1'); - TEST_INFO->test_write(data.c_str(), request_size); - REQUIRE(TEST_INFO->size_written_orig_ == request_size); + TESTER->test_write(data.c_str(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); if (biggest_size_written < request_size) biggest_size_written = request_size; } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - REQUIRE(stdfs::file_size(TEST_INFO->new_file_.hermes_) == biggest_size_written); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_) == + biggest_size_written); } SECTION("write to new file") { - TEST_INFO->test_open(TEST_INFO->new_file_, O_WRONLY | O_CREAT | O_EXCL, 0600); - REQUIRE(TEST_INFO->fh_orig_ != -1); + TESTER->test_open(TESTER->new_file_, O_WRONLY | O_CREAT | O_EXCL, 0600); + REQUIRE(TESTER->fh_orig_ != -1); size_t total_size_written = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t request_size = - TEST_INFO->request_size_ + (rand_r(&TEST_INFO->offset_seed_) % TEST_INFO->request_size_); + TESTER->request_size_ + + (rand_r(&TESTER->offset_seed_) % TESTER->request_size_); std::string data(request_size, '1'); - TEST_INFO->test_write(data.c_str(), request_size); - REQUIRE(TEST_INFO->size_written_orig_ == request_size); - total_size_written += TEST_INFO->size_written_orig_; + TESTER->test_write(data.c_str(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); + total_size_written += TESTER->size_written_orig_; } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - REQUIRE(stdfs::file_size(TEST_INFO->new_file_.hermes_) == total_size_written); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_) == total_size_written); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadSequentialRSVariable", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=type-variable][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDONLY); - REQUIRE(TEST_INFO->fh_orig_ != -1); - std::string data(TEST_INFO->request_size_, '1'); + TESTER->test_open(TESTER->existing_file_, O_RDONLY); + REQUIRE(TESTER->fh_orig_ != -1); + std::string data(TESTER->request_size_, '1'); size_t current_offset = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - size_t request_size = (TEST_INFO->request_size_ + - (rand_r(&TEST_INFO->offset_seed_) % TEST_INFO->request_size_)) % - (TEST_INFO->total_size_ - current_offset); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + size_t request_size = (TESTER->request_size_ + + (rand_r(&TESTER->offset_seed_) % TESTER->request_size_)) % + (TESTER->total_size_ - current_offset); std::string data(request_size, '1'); - TEST_INFO->test_read(data.data(), request_size); - REQUIRE(TEST_INFO->size_read_orig_ == request_size); - current_offset += TEST_INFO->size_read_orig_; + TESTER->test_read(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); + current_offset += TESTER->size_read_orig_; } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("read from existing file always at start") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDONLY); - REQUIRE(TEST_INFO->fh_orig_ != -1); + TESTER->test_open(TESTER->existing_file_, O_RDONLY); + REQUIRE(TESTER->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - TEST_INFO->test_seek(0, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_seek(0, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->request_size_ + (rand_r(&TEST_INFO->offset_seed_) % TEST_INFO->request_size_); + TESTER->request_size_ + + (rand_r(&TESTER->offset_seed_) % TESTER->request_size_); std::string data(request_size, '1'); - TEST_INFO->test_read(data.data(), request_size); - REQUIRE(TEST_INFO->size_read_orig_ == request_size); + TESTER->test_read(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadRandomRSVariable", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=type-variable]" "[repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "][pattern=random][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - std::string data(TEST_INFO->request_size_, '1'); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + std::string data(TESTER->request_size_, '1'); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t offset = - rand_r(&TEST_INFO->offset_seed_) % (TEST_INFO->total_size_ - TEST_INFO->request_size_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + rand_r(&TESTER->offset_seed_) % + (TESTER->total_size_ - TESTER->request_size_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - (TEST_INFO->request_size_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->request_size_)) % - (TEST_INFO->total_size_ - offset); + (TESTER->request_size_ + + (rand_r(&TESTER->rs_seed_) % TESTER->request_size_)) % + (TESTER->total_size_ - offset); std::string data(request_size, '1'); - TEST_INFO->test_read(data.data(), request_size); - REQUIRE(TEST_INFO->size_read_orig_ == request_size); + TESTER->test_read(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateRandomRSVariable", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=type-variable][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=random][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - std::string data(TEST_INFO->request_size_, '1'); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + std::string data(TESTER->request_size_, '1'); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t offset = - rand_r(&TEST_INFO->offset_seed_) % (TEST_INFO->total_size_ - TEST_INFO->request_size_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + rand_r(&TESTER->offset_seed_) % + (TESTER->total_size_ - TESTER->request_size_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - TEST_INFO->request_size_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->request_size_); + TESTER->request_size_ + + (rand_r(&TESTER->rs_seed_) % TESTER->request_size_); std::string data(request_size, '1'); - TEST_INFO->test_write(data.c_str(), request_size); - REQUIRE(TEST_INFO->size_written_orig_ == request_size); + TESTER->test_write(data.c_str(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadStrideFixedRSVariable", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=type-variable][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_fixed][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - size_t offset = (i * TEST_INFO->stride_size_) % TEST_INFO->total_size_; - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + size_t offset = (i * TESTER->stride_size_) % TESTER->total_size_; + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - (TEST_INFO->request_size_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->request_size_)) % - (TEST_INFO->total_size_ - offset); + (TESTER->request_size_ + + (rand_r(&TESTER->rs_seed_) % TESTER->request_size_)) % + (TESTER->total_size_ - offset); std::string data(request_size, '1'); - TEST_INFO->test_read(data.data(), request_size); - REQUIRE(TEST_INFO->size_read_orig_ == request_size); + TESTER->test_read(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStrideFixedRSVariable", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=type-variable][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_fixed][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("write to existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - std::string data(TEST_INFO->request_size_, '1'); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - size_t offset = (i * TEST_INFO->stride_size_) % TEST_INFO->total_size_; - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + std::string data(TESTER->request_size_, '1'); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + size_t offset = (i * TESTER->stride_size_) % TESTER->total_size_; + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - TEST_INFO->request_size_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->request_size_); + TESTER->request_size_ + + (rand_r(&TESTER->rs_seed_) % TESTER->request_size_); std::string data(request_size, '1'); - TEST_INFO->test_write(data.c_str(), request_size); - REQUIRE(TEST_INFO->size_written_orig_ == request_size); + TESTER->test_write(data.c_str(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadStrideDynamicRSVariable", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=type-variable][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_dynamic][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - size_t offset = TEST_INFO->GetRandomOffset(i, TEST_INFO->offset_seed_, TEST_INFO->stride_size_, - TEST_INFO->total_size_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + size_t offset = TESTER->GetRandomOffset( + i, TESTER->offset_seed_, TESTER->stride_size_, + TESTER->total_size_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - TEST_INFO->request_size_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->request_size_); + TESTER->request_size_ + + (rand_r(&TESTER->rs_seed_) % TESTER->request_size_); std::string data(request_size, '1'); - TEST_INFO->test_read(data.data(), request_size); - REQUIRE(TEST_INFO->size_read_orig_ == request_size); + TESTER->test_read(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStrideDynamicRSVariable", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=type-variable][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_dynamic][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - size_t offset = TEST_INFO->GetRandomOffset(i, TEST_INFO->offset_seed_, TEST_INFO->stride_size_, - TEST_INFO->total_size_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + size_t offset = TESTER->GetRandomOffset( + i, TESTER->offset_seed_, TESTER->stride_size_, + TESTER->total_size_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - TEST_INFO->request_size_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->request_size_); + TESTER->request_size_ + + (rand_r(&TESTER->rs_seed_) % TESTER->request_size_); std::string data(request_size, '1'); - TEST_INFO->test_write(data.c_str(), request_size); - REQUIRE(TEST_INFO->size_written_orig_ == request_size); + TESTER->test_write(data.c_str(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadStrideNegative", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=type-fixed][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_negative][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - std::string data(TEST_INFO->request_size_, '1'); - size_t prev_offset = TEST_INFO->total_size_ + 1; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - auto stride_offset = TEST_INFO->total_size_ - i * TEST_INFO->stride_size_; + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + std::string data(TESTER->request_size_, '1'); + size_t prev_offset = TESTER->total_size_ + 1; + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + auto stride_offset = TESTER->total_size_ - i * TESTER->stride_size_; REQUIRE(prev_offset > stride_offset); prev_offset = stride_offset; - size_t offset = (stride_offset) % (TEST_INFO->total_size_ - TEST_INFO->request_size_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); - TEST_INFO->test_read(data.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); + size_t offset = (stride_offset) % + (TESTER->total_size_ - TESTER->request_size_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); + TESTER->test_read(data.data(), TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStrideNegative", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=type-fixed][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_negative][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - std::string data(TEST_INFO->request_size_, '1'); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + std::string data(TESTER->request_size_, '1'); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t offset = - TEST_INFO->total_size_ - ((i * TEST_INFO->stride_size_) % TEST_INFO->total_size_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); - TEST_INFO->test_write(data.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); + TESTER->total_size_ - ((i * TESTER->stride_size_) % + TESTER->total_size_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); + TESTER->test_write(data.data(), TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadStrideNegativeRSVariable", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=type-variable][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_negative][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - size_t offset = (TEST_INFO->total_size_ - i * TEST_INFO->stride_size_) % - (TEST_INFO->total_size_ - 2 * TEST_INFO->request_size_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + size_t offset = (TESTER->total_size_ - i * TESTER->stride_size_) % + (TESTER->total_size_ - 2 * TESTER->request_size_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - (TEST_INFO->request_size_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->request_size_)) % - (TEST_INFO->total_size_ - offset); + (TESTER->request_size_ + (rand_r(&TESTER->rs_seed_) % + TESTER->request_size_)) % + (TESTER->total_size_ - offset); std::string data(request_size, '1'); - TEST_INFO->test_read(data.data(), request_size); - REQUIRE(TEST_INFO->size_read_orig_ == request_size); + TESTER->test_read(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStrideNegativeRSVariable", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=type-variable][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_negative][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("write to existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - std::string data(TEST_INFO->request_size_, '1'); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + std::string data(TESTER->request_size_, '1'); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t offset = - TEST_INFO->total_size_ - ((i * TEST_INFO->stride_size_) % TEST_INFO->total_size_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + TESTER->total_size_ - ((i * TESTER->stride_size_) % + TESTER->total_size_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - TEST_INFO->request_size_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->request_size_); + TESTER->request_size_ + (rand_r(&TESTER->rs_seed_) % + TESTER->request_size_); std::string data(request_size, '1'); - TEST_INFO->test_write(data.c_str(), request_size); - REQUIRE(TEST_INFO->size_written_orig_ == request_size); + TESTER->test_write(data.c_str(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } -TEST_CASE("BatchedReadStride2D", "[process=" + std::to_string(TEST_INFO->comm_size_) + +TEST_CASE("BatchedReadStride2D", "[process=" + + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=type-fixed][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_2d][file=1]") { - TEST_INFO->Pretest(); - size_t rows = sqrt(TEST_INFO->total_size_); + TESTER->Pretest(); + size_t rows = sqrt(TESTER->total_size_); size_t cols = rows; - REQUIRE(rows * cols == TEST_INFO->total_size_); + REQUIRE(rows * cols == TESTER->total_size_); size_t cell_size = 128; - size_t cell_stride = rows * cols / cell_size / TEST_INFO->num_iterations_; + size_t cell_stride = rows * cols / cell_size / TESTER->num_iterations_; SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - std::string data(TEST_INFO->request_size_, '1'); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + std::string data(TESTER->request_size_, '1'); size_t prev_cell_col = 0, prev_cell_row = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t current_cell_col = (prev_cell_col + cell_stride) % cols; size_t current_cell_row = prev_cell_col + cell_stride > cols ? prev_cell_row + 1 : prev_cell_row; prev_cell_row = current_cell_row; size_t offset = (current_cell_col * cell_stride + prev_cell_row * cols) % - (TEST_INFO->total_size_ - TEST_INFO->request_size_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); - TEST_INFO->test_read(data.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); + (TESTER->total_size_ - TESTER->request_size_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); + TESTER->test_read(data.data(), TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStride2D", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=type-fixed][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_2d][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); - size_t rows = sqrt(TEST_INFO->total_size_); + size_t rows = sqrt(TESTER->total_size_); size_t cols = rows; - REQUIRE(rows * cols == TEST_INFO->total_size_); + REQUIRE(rows * cols == TESTER->total_size_); size_t cell_size = 128; - size_t cell_stride = rows * cols / cell_size / TEST_INFO->num_iterations_; + size_t cell_stride = rows * cols / cell_size / TESTER->num_iterations_; SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - std::string data(TEST_INFO->request_size_, '1'); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + std::string data(TESTER->request_size_, '1'); size_t prev_cell_col = 0, prev_cell_row = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t current_cell_col = (prev_cell_col + cell_stride) % cols; size_t current_cell_row = prev_cell_col + cell_stride > cols ? prev_cell_row + 1 : prev_cell_row; prev_cell_row = current_cell_row; size_t offset = (current_cell_col * cell_stride + prev_cell_row * cols) % - (TEST_INFO->total_size_ - TEST_INFO->request_size_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); - TEST_INFO->test_write(data.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); + (TESTER->total_size_ - TESTER->request_size_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); + TESTER->test_write(data.data(), TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadStride2DRSVariable", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=type-variable][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_2d][file=1]") { - TEST_INFO->Pretest(); - size_t rows = sqrt(TEST_INFO->total_size_); + TESTER->Pretest(); + size_t rows = sqrt(TESTER->total_size_); size_t cols = rows; - REQUIRE(rows * cols == TEST_INFO->total_size_); + REQUIRE(rows * cols == TESTER->total_size_); size_t cell_size = 128; - size_t cell_stride = rows * cols / cell_size / TEST_INFO->num_iterations_; + size_t cell_stride = rows * cols / cell_size / TESTER->num_iterations_; SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); size_t prev_cell_col = 0, prev_cell_row = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t current_cell_col = (prev_cell_col + cell_stride) % cols; size_t current_cell_row = prev_cell_col + cell_stride > cols ? prev_cell_row + 1 : prev_cell_row; prev_cell_row = current_cell_row; size_t offset = (current_cell_col * cell_stride + prev_cell_row * cols) % - (TEST_INFO->total_size_ - 2 * TEST_INFO->request_size_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + (TESTER->total_size_ - 2 * TESTER->request_size_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - (TEST_INFO->request_size_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->request_size_)) % - (TEST_INFO->total_size_ - offset); + (TESTER->request_size_ + (rand_r(&TESTER->rs_seed_) % + TESTER->request_size_)) % + (TESTER->total_size_ - offset); std::string data(request_size, '1'); - TEST_INFO->test_read(data.data(), request_size); - REQUIRE(TEST_INFO->size_read_orig_ == request_size); + TESTER->test_read(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStride2DRSVariable", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=type-variable][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_2d][file=1]") { - TEST_INFO->Pretest(); - size_t rows = sqrt(TEST_INFO->total_size_); + TESTER->Pretest(); + size_t rows = sqrt(TESTER->total_size_); size_t cols = rows; - REQUIRE(rows * cols == TEST_INFO->total_size_); + REQUIRE(rows * cols == TESTER->total_size_); size_t cell_size = 128; - size_t cell_stride = rows * cols / cell_size / TEST_INFO->num_iterations_; + size_t cell_stride = rows * cols / cell_size / TESTER->num_iterations_; SECTION("write to existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - std::string data(TEST_INFO->request_size_, '1'); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + std::string data(TESTER->request_size_, '1'); size_t prev_cell_col = 0, prev_cell_row = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t current_cell_col = (prev_cell_col + cell_stride) % cols; size_t current_cell_row = prev_cell_col + cell_stride > cols ? prev_cell_row + 1 : prev_cell_row; prev_cell_row = current_cell_row; size_t offset = (current_cell_col * cell_stride + prev_cell_row * cols) % - (TEST_INFO->total_size_ - 2 * TEST_INFO->request_size_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + (TESTER->total_size_ - 2 * TESTER->request_size_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - TEST_INFO->request_size_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->request_size_); + TESTER->request_size_ + (rand_r(&TESTER->rs_seed_) % + TESTER->request_size_); std::string data(request_size, '1'); - TEST_INFO->test_write(data.c_str(), request_size); - REQUIRE(TEST_INFO->size_written_orig_ == request_size); + TESTER->test_write(data.c_str(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } /** @@ -1148,336 +1188,342 @@ TEST_CASE("BatchedUpdateStride2DRSVariable", */ TEST_CASE("BatchedWriteTemporalFixed", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=type-fixed][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1][temporal=fixed]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("write to new file") { - TEST_INFO->test_open(TEST_INFO->new_file_, O_WRONLY | O_CREAT | O_EXCL, 0600); - REQUIRE(TEST_INFO->fh_orig_ != -1); - - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - usleep(TEST_INFO->temporal_interval_ms_ * 1000); - TEST_INFO->test_seek(0, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_write(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); + TESTER->test_open(TESTER->new_file_, O_WRONLY | O_CREAT | O_EXCL, 0600); + REQUIRE(TESTER->fh_orig_ != -1); + + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + usleep(TESTER->temporal_interval_ms_ * 1000); + TESTER->test_seek(0, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_write(TESTER->write_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - REQUIRE(stdfs::file_size(TEST_INFO->new_file_.hermes_) == TEST_INFO->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_) == + TESTER->request_size_); } SECTION("write to new file always at start") { - TEST_INFO->test_open(TEST_INFO->new_file_, O_WRONLY | O_CREAT | O_EXCL, 0600); - REQUIRE(TEST_INFO->fh_orig_ != -1); + TESTER->test_open(TESTER->new_file_, O_WRONLY | O_CREAT | O_EXCL, 0600); + REQUIRE(TESTER->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - usleep(TEST_INFO->temporal_interval_ms_ * 1000); - TEST_INFO->test_write(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + usleep(TESTER->temporal_interval_ms_ * 1000); + TESTER->test_write(TESTER->write_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - REQUIRE(stdfs::file_size(TEST_INFO->new_file_.hermes_) == - TEST_INFO->num_iterations_ * TEST_INFO->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_) == + TESTER->num_iterations_ * TESTER->request_size_); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadSequentialTemporalFixed", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=type-fixed][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1][temporal=fixed]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - std::string data(TEST_INFO->request_size_, '1'); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - usleep(TEST_INFO->temporal_interval_ms_ * 1000); - TEST_INFO->test_read(data.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + std::string data(TESTER->request_size_, '1'); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + usleep(TESTER->temporal_interval_ms_ * 1000); + TESTER->test_read(data.data(), TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - std::string data(TEST_INFO->request_size_, '1'); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - usleep(TEST_INFO->temporal_interval_ms_ * 1000); - TEST_INFO->test_seek(0, SEEK_SET); - TEST_INFO->test_read(data.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + std::string data(TESTER->request_size_, '1'); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + usleep(TESTER->temporal_interval_ms_ * 1000); + TESTER->test_seek(0, SEEK_SET); + TESTER->test_read(data.data(), TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedWriteTemporalVariable", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=type-fixed][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1][temporal=variable]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("write to existing file") { - TEST_INFO->test_open(TEST_INFO->new_file_, O_WRONLY | O_CREAT | O_EXCL, 0600); - REQUIRE(TEST_INFO->fh_orig_ != -1); - - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - TEST_INFO->temporal_interval_ms_ = - rand_r(&TEST_INFO->temporal_interval_seed_) % TEST_INFO->temporal_interval_ms_ + 1; - usleep(TEST_INFO->temporal_interval_ms_ * 1000); - TEST_INFO->test_seek(0, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_write(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); + TESTER->test_open(TESTER->new_file_, O_WRONLY | O_CREAT | O_EXCL, 0600); + REQUIRE(TESTER->fh_orig_ != -1); + + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->temporal_interval_ms_ = + rand_r(&TESTER->temporal_interval_seed_) % + TESTER->temporal_interval_ms_ + 1; + usleep(TESTER->temporal_interval_ms_ * 1000); + TESTER->test_seek(0, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_write(TESTER->write_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - REQUIRE(stdfs::file_size(TEST_INFO->new_file_.hermes_) == TEST_INFO->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_) == + TESTER->request_size_); } SECTION("write to new file always at start") { - TEST_INFO->test_open(TEST_INFO->new_file_, O_WRONLY | O_CREAT | O_EXCL, 0600); - REQUIRE(TEST_INFO->fh_orig_ != -1); - - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - TEST_INFO->temporal_interval_ms_ = - rand_r(&TEST_INFO->temporal_interval_seed_) % TEST_INFO->temporal_interval_ms_ + 1; - usleep(TEST_INFO->temporal_interval_ms_ * 1000); - TEST_INFO->test_write(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); + TESTER->test_open(TESTER->new_file_, O_WRONLY | O_CREAT | O_EXCL, 0600); + REQUIRE(TESTER->fh_orig_ != -1); + + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->temporal_interval_ms_ = + rand_r(&TESTER->temporal_interval_seed_) % + TESTER->temporal_interval_ms_ + 1; + usleep(TESTER->temporal_interval_ms_ * 1000); + TESTER->test_write(TESTER->write_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - REQUIRE(stdfs::file_size(TEST_INFO->new_file_.hermes_) == - TEST_INFO->num_iterations_ * TEST_INFO->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_) == + TESTER->num_iterations_ * TESTER->request_size_); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadSequentialTemporalVariable", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=type-fixed][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1][temporal=variable]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - std::string data(TEST_INFO->request_size_, '1'); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - TEST_INFO->temporal_interval_ms_ = - rand_r(&TEST_INFO->temporal_interval_seed_) % TEST_INFO->temporal_interval_ms_ + 1; - usleep(TEST_INFO->temporal_interval_ms_ * 1000); - TEST_INFO->test_read(data.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + std::string data(TESTER->request_size_, '1'); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->temporal_interval_ms_ = + rand_r(&TESTER->temporal_interval_seed_) % + TESTER->temporal_interval_ms_ + 1; + usleep(TESTER->temporal_interval_ms_ * 1000); + TESTER->test_read(data.data(), TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("read from existing file always at start") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_WRONLY); - REQUIRE(TEST_INFO->fh_orig_ != -1); - - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - TEST_INFO->temporal_interval_ms_ = - rand_r(&TEST_INFO->temporal_interval_seed_) % TEST_INFO->temporal_interval_ms_ + 1; - usleep(TEST_INFO->temporal_interval_ms_ * 1000); - TEST_INFO->test_seek(0, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_write(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); + TESTER->test_open(TESTER->existing_file_, O_WRONLY); + REQUIRE(TESTER->fh_orig_ != -1); + + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->temporal_interval_ms_ = + rand_r(&TESTER->temporal_interval_seed_) % + TESTER->temporal_interval_ms_ + 1; + usleep(TESTER->temporal_interval_ms_ * 1000); + TESTER->test_seek(0, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_write(TESTER->write_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedMixedSequential", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_mixed]" "[request_size=type-fixed][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read after write on new file") { - TEST_INFO->test_open(TEST_INFO->new_file_, O_RDWR | O_CREAT | O_EXCL, 0600); - REQUIRE(TEST_INFO->fh_orig_ != -1); + TESTER->test_open(TESTER->new_file_, O_RDWR | O_CREAT | O_EXCL, 0600); + REQUIRE(TESTER->fh_orig_ != -1); size_t last_offset = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - TEST_INFO->test_write(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); - TEST_INFO->test_seek(last_offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == last_offset); - TEST_INFO->test_read(TEST_INFO->read_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); - last_offset += TEST_INFO->request_size_; + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_write(TESTER->write_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_seek(last_offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == last_offset); + TESTER->test_read(TESTER->read_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); + last_offset += TESTER->request_size_; } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("write and read alternative existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { if (i % 2 == 0) { - TEST_INFO->test_write(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); + TESTER->test_write(TESTER->write_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); } else { - TEST_INFO->test_read(TEST_INFO->read_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); + TESTER->test_read(TESTER->read_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); } } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("update after read existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); size_t last_offset = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - TEST_INFO->test_read(TEST_INFO->read_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); - TEST_INFO->test_seek(last_offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == last_offset); - TEST_INFO->test_write(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); - last_offset += TEST_INFO->request_size_; + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_read(TESTER->read_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); + TESTER->test_seek(last_offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == last_offset); + TESTER->test_write(TESTER->write_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); + last_offset += TESTER->request_size_; } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("read all after write all on new file in single open") { - TEST_INFO->test_open(TEST_INFO->new_file_, O_RDWR | O_CREAT | O_EXCL, 0600); - REQUIRE(TEST_INFO->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - TEST_INFO->test_write(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); + TESTER->test_open(TESTER->new_file_, O_RDWR | O_CREAT | O_EXCL, 0600); + REQUIRE(TESTER->fh_orig_ != -1); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_write(TESTER->write_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); } - TEST_INFO->test_seek(0, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - TEST_INFO->test_read(TEST_INFO->read_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); + TESTER->test_seek(0, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_read(TESTER->read_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("read all after write all on new file in different open") { - TEST_INFO->test_open(TEST_INFO->new_file_, O_RDWR | O_CREAT, S_IRWXU | S_IRWXG); - REQUIRE(TEST_INFO->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - TEST_INFO->test_write(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); + TESTER->test_open(TESTER->new_file_, O_RDWR | O_CREAT, S_IRWXU | S_IRWXG); + REQUIRE(TESTER->fh_orig_ != -1); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_write(TESTER->write_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_open(TEST_INFO->new_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - TEST_INFO->test_read(TEST_INFO->read_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_open(TESTER->new_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_read(TESTER->read_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } -TEST_CASE("SingleMixed", "[process=" + std::to_string(TEST_INFO->comm_size_) + +TEST_CASE("SingleMixed", "[process=" + std::to_string(TESTER->comm_size_) + "][operation=single_mixed]" "[request_size=type-fixed][repetition=1]" "[file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read after write from new file") { - TEST_INFO->test_open(TEST_INFO->new_file_, O_RDWR | O_CREAT | O_EXCL, 0600); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_write(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); - TEST_INFO->test_seek(0, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_read(TEST_INFO->read_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_open(TESTER->new_file_, O_RDWR | O_CREAT | O_EXCL, 0600); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_write(TESTER->write_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_seek(0, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_read(TESTER->read_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("update after read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_read(TEST_INFO->read_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); - TEST_INFO->test_seek(0, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_write(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); - - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_read(TESTER->read_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); + TESTER->test_seek(0, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_write(TESTER->write_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); + + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("read after write from new file different opens") { - TEST_INFO->test_open(TEST_INFO->new_file_, O_RDWR | O_CREAT | O_EXCL, 0600); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_write(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_open(TEST_INFO->new_file_, O_RDWR); - TEST_INFO->test_read(TEST_INFO->read_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - } - TEST_INFO->Posttest(); + TESTER->test_open(TESTER->new_file_, O_RDWR | O_CREAT | O_EXCL, 0600); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_write(TESTER->write_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_open(TESTER->new_file_, O_RDWR); + TESTER->test_read(TESTER->read_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + } + TESTER->Posttest(); } TEST_CASE("fstat") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("fstat on new file") { - TEST_INFO->test_open(TEST_INFO->new_file_, O_WRONLY | O_CREAT | O_EXCL, 0600); - REQUIRE(TEST_INFO->fh_orig_ != -1); - TEST_INFO->test_write(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); + TESTER->test_open(TESTER->new_file_, O_WRONLY | O_CREAT | O_EXCL, 0600); + REQUIRE(TESTER->fh_orig_ != -1); + TESTER->test_write(TESTER->write_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); struct stat buf = {}; - int result = fstat(TEST_INFO->fh_orig_, &buf); + int result = fstat(TESTER->fh_orig_, &buf); REQUIRE(result == 0); - REQUIRE(buf.st_size == (off_t)TEST_INFO->size_written_orig_); + REQUIRE(buf.st_size == (off_t)TESTER->size_written_orig_); - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } diff --git a/test/unit/hermes_adapters/posix/posix_adapter_rs_test.cc b/test/unit/hermes_adapters/posix/posix_adapter_rs_test.cc index 3c3410517..a0c66c0e9 100644 --- a/test/unit/hermes_adapters/posix/posix_adapter_rs_test.cc +++ b/test/unit/hermes_adapters/posix/posix_adapter_rs_test.cc @@ -13,1229 +13,1282 @@ #include "posix_adapter_test.h" TEST_CASE("BatchedWriteRSRangeSmall", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=range-small][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("write to new file always at the start") { - TEST_INFO->test_open(TEST_INFO->new_file_, O_WRONLY | O_CREAT, 0600); - REQUIRE(TEST_INFO->fh_orig_ != -1); + TESTER->test_open(TESTER->new_file_, O_WRONLY | O_CREAT, 0600); + REQUIRE(TESTER->fh_orig_ != -1); size_t biggest_size_written = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - TEST_INFO->test_seek(0, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_seek(0, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->small_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->small_max_); + TESTER->small_min_ + (rand_r(&TESTER->rs_seed_) % TESTER->small_max_); std::string data(request_size, '1'); - TEST_INFO->test_write(data.c_str(), request_size); - REQUIRE(TEST_INFO->size_written_orig_ == request_size); + TESTER->test_write(data.c_str(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); if (biggest_size_written < request_size) biggest_size_written = request_size; } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - REQUIRE(stdfs::file_size(TEST_INFO->new_file_.hermes_.c_str()) == biggest_size_written); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_.c_str()) == + biggest_size_written); } SECTION("write to new file") { - TEST_INFO->test_open(TEST_INFO->new_file_, O_WRONLY | O_CREAT, 0600); - REQUIRE(TEST_INFO->fh_orig_ != -1); + TESTER->test_open(TESTER->new_file_, O_WRONLY | O_CREAT, 0600); + REQUIRE(TESTER->fh_orig_ != -1); size_t total_size_written = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t request_size = - TEST_INFO->small_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->small_max_); + TESTER->small_min_ + (rand_r(&TESTER->rs_seed_) % TESTER->small_max_); std::string data(request_size, '1'); - TEST_INFO->test_write(data.c_str(), request_size); - REQUIRE(TEST_INFO->size_written_orig_ == request_size); - total_size_written += TEST_INFO->size_written_orig_; + TESTER->test_write(data.c_str(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); + total_size_written += TESTER->size_written_orig_; } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - REQUIRE(stdfs::file_size(TEST_INFO->new_file_.hermes_.c_str()) == total_size_written); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_.c_str()) == + total_size_written); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadSequentialRSRangeSmall", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=range-small][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDONLY); - REQUIRE(TEST_INFO->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + TESTER->test_open(TESTER->existing_file_, O_RDONLY); + REQUIRE(TESTER->fh_orig_ != -1); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t request_size = - TEST_INFO->small_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->small_max_); + TESTER->small_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->small_max_); std::string data(request_size, '1'); - TEST_INFO->test_read(data.data(), request_size); - REQUIRE(TEST_INFO->size_read_orig_ == request_size); + TESTER->test_read(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("read from existing file always at start") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDONLY); - REQUIRE(TEST_INFO->fh_orig_ != -1); + TESTER->test_open(TESTER->existing_file_, O_RDONLY); + REQUIRE(TESTER->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - TEST_INFO->test_seek(0, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_seek(0, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->small_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->small_max_); + TESTER->small_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->small_max_); std::string data(request_size, '1'); - TEST_INFO->test_read(data.data(), request_size); - REQUIRE(TEST_INFO->size_read_orig_ == request_size); + TESTER->test_read(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadRandomRSRangeSmall", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=range-small]" "[repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "][pattern=random][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t offset = - rand_r(&TEST_INFO->offset_seed_) % (TEST_INFO->total_size_ - TEST_INFO->small_max_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + rand_r(&TESTER->offset_seed_) % + (TESTER->total_size_ - TESTER->small_max_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - TEST_INFO->small_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->small_max_); + TESTER->small_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->small_max_); std::string data(request_size, '1'); - TEST_INFO->test_read(data.data(), request_size); - REQUIRE(TEST_INFO->size_read_orig_ == request_size); + TESTER->test_read(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateRandomRSRangeSmall", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=range-small][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=random][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t offset = - rand_r(&TEST_INFO->offset_seed_) % (TEST_INFO->total_size_ - TEST_INFO->small_max_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + rand_r(&TESTER->offset_seed_) % + (TESTER->total_size_ - TESTER->small_max_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - TEST_INFO->small_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->small_max_); + TESTER->small_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->small_max_); std::string data(request_size, '1'); - TEST_INFO->test_write(data.c_str(), request_size); - REQUIRE(TEST_INFO->size_written_orig_ == request_size); + TESTER->test_write(data.c_str(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadStrideFixedRSRangeSmall", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=range-small][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_fixed][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t offset = - (i * TEST_INFO->stride_size_) % (TEST_INFO->total_size_ - TEST_INFO->small_max_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + (i * TESTER->stride_size_) % + (TESTER->total_size_ - TESTER->small_max_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - TEST_INFO->small_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->small_max_); + TESTER->small_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->small_max_); std::string data(request_size, '1'); - TEST_INFO->test_read(data.data(), request_size); - REQUIRE(TEST_INFO->size_read_orig_ == request_size); + TESTER->test_read(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStrideFixedRSRangeSmall", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=range-small][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_fixed][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("write to existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t offset = - (i * TEST_INFO->stride_size_) % (TEST_INFO->total_size_ - TEST_INFO->small_max_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + (i * TESTER->stride_size_) % + (TESTER->total_size_ - TESTER->small_max_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - TEST_INFO->small_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->small_max_); + TESTER->small_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->small_max_); std::string data(request_size, '1'); - TEST_INFO->test_write(data.c_str(), request_size); - REQUIRE(TEST_INFO->size_written_orig_ == request_size); + TESTER->test_write(data.c_str(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadStrideDynamicRSRangeSmall", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=range-small][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_dynamic][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - size_t offset = TEST_INFO->GetRandomOffset(i, TEST_INFO->offset_seed_, TEST_INFO->stride_size_, - TEST_INFO->total_size_ - TEST_INFO->small_max_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + size_t offset = TESTER->GetRandomOffset( + i, TESTER->offset_seed_, TESTER->stride_size_, + TESTER->total_size_ - TESTER->small_max_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - TEST_INFO->small_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->small_max_); + TESTER->small_min_ + (rand_r(&TESTER->rs_seed_) % TESTER->small_max_); std::string data(request_size, '1'); - TEST_INFO->test_read(data.data(), request_size); - REQUIRE(TEST_INFO->size_read_orig_ == request_size); + TESTER->test_read(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStrideDynamicRSRangeSmall", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=range-small][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_dynamic][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - size_t offset = TEST_INFO->GetRandomOffset(i, TEST_INFO->offset_seed_, TEST_INFO->stride_size_, - TEST_INFO->total_size_ - TEST_INFO->small_max_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + size_t offset = TESTER->GetRandomOffset( + i, TESTER->offset_seed_, TESTER->stride_size_, + TESTER->total_size_ - TESTER->small_max_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - TEST_INFO->small_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->small_max_); + TESTER->small_min_ + (rand_r(&TESTER->rs_seed_) % TESTER->small_max_); std::string data(request_size, '1'); - TEST_INFO->test_write(data.c_str(), request_size); - REQUIRE(TEST_INFO->size_written_orig_ == request_size); + TESTER->test_write(data.c_str(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadStrideNegativeRSRangeSmall", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=range-small][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_negative][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - size_t offset = (TEST_INFO->total_size_ - i * TEST_INFO->stride_size_) % - (TEST_INFO->total_size_ - TEST_INFO->small_max_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + size_t offset = (TESTER->total_size_ - i * TESTER->stride_size_) % + (TESTER->total_size_ - TESTER->small_max_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - TEST_INFO->small_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->small_max_); + TESTER->small_min_ + (rand_r(&TESTER->rs_seed_) % TESTER->small_max_); std::string data(request_size, '1'); - TEST_INFO->test_read(data.data(), request_size); - REQUIRE(TEST_INFO->size_read_orig_ == request_size); + TESTER->test_read(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStrideNegativeRSRangeSmall", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=range-small][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_negative][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("write to existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - size_t offset = TEST_INFO->total_size_ - ((i * TEST_INFO->stride_size_) % - (TEST_INFO->total_size_ - TEST_INFO->small_max_)); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + size_t offset = TESTER->total_size_ - ((i * TESTER->stride_size_) % + (TESTER->total_size_ - TESTER->small_max_)); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - TEST_INFO->small_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->small_max_); + TESTER->small_min_ + (rand_r(&TESTER->rs_seed_) % TESTER->small_max_); std::string data(request_size, '1'); - TEST_INFO->test_write(data.c_str(), request_size); - REQUIRE(TEST_INFO->size_written_orig_ == request_size); + TESTER->test_write(data.c_str(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadStride2DRSRangeSmall", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=range-small][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_2d][file=1]") { - TEST_INFO->Pretest(); - size_t rows = sqrt(TEST_INFO->total_size_); + TESTER->Pretest(); + size_t rows = sqrt(TESTER->total_size_); size_t cols = rows; - REQUIRE(rows * cols == TEST_INFO->total_size_); + REQUIRE(rows * cols == TESTER->total_size_); size_t cell_size = 128; - size_t cell_stride = rows * cols / cell_size / TEST_INFO->num_iterations_; + size_t cell_stride = rows * cols / cell_size / TESTER->num_iterations_; SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); size_t prev_cell_col = 0, prev_cell_row = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t current_cell_col = (prev_cell_col + cell_stride) % cols; size_t current_cell_row = prev_cell_col + cell_stride > cols ? prev_cell_row + 1 : prev_cell_row; prev_cell_row = current_cell_row; size_t offset = (current_cell_col * cell_stride + prev_cell_row * cols) % - (TEST_INFO->total_size_ - TEST_INFO->small_max_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + (TESTER->total_size_ - TESTER->small_max_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - TEST_INFO->small_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->small_max_); + TESTER->small_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->small_max_); std::string data(request_size, '1'); - TEST_INFO->test_read(data.data(), request_size); - REQUIRE(TEST_INFO->size_read_orig_ == request_size); + TESTER->test_read(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStride2DRSRangeSmall", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=range-small][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_2d][file=1]") { - TEST_INFO->Pretest(); - size_t rows = sqrt(TEST_INFO->total_size_); + TESTER->Pretest(); + size_t rows = sqrt(TESTER->total_size_); size_t cols = rows; - REQUIRE(rows * cols == TEST_INFO->total_size_); + REQUIRE(rows * cols == TESTER->total_size_); size_t cell_size = 128; - size_t cell_stride = rows * cols / cell_size / TEST_INFO->num_iterations_; + size_t cell_stride = rows * cols / cell_size / TESTER->num_iterations_; SECTION("write to existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); size_t prev_cell_col = 0, prev_cell_row = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t current_cell_col = (prev_cell_col + cell_stride) % cols; size_t current_cell_row = prev_cell_col + cell_stride > cols ? prev_cell_row + 1 : prev_cell_row; prev_cell_row = current_cell_row; size_t offset = (current_cell_col * cell_stride + prev_cell_row * cols) % - (TEST_INFO->total_size_ - TEST_INFO->small_max_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + (TESTER->total_size_ - TESTER->small_max_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - TEST_INFO->small_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->small_max_); + TESTER->small_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->small_max_); std::string data(request_size, '1'); - TEST_INFO->test_write(data.c_str(), request_size); - REQUIRE(TEST_INFO->size_written_orig_ == request_size); + TESTER->test_write(data.c_str(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } /** * Medium RS **/ TEST_CASE("BatchedWriteRSRangeMedium", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=range-medium][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("write to new file always at the start") { - TEST_INFO->test_open(TEST_INFO->new_file_, O_WRONLY | O_CREAT, 0600); - REQUIRE(TEST_INFO->fh_orig_ != -1); + TESTER->test_open(TESTER->new_file_, O_WRONLY | O_CREAT, 0600); + REQUIRE(TESTER->fh_orig_ != -1); size_t biggest_size_written = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - TEST_INFO->test_seek(0, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_seek(0, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->medium_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->medium_max_); + TESTER->medium_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->medium_max_); std::string data(request_size, '1'); - TEST_INFO->test_write(data.c_str(), request_size); - REQUIRE(TEST_INFO->size_written_orig_ == request_size); + TESTER->test_write(data.c_str(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); if (biggest_size_written < request_size) biggest_size_written = request_size; } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - REQUIRE(stdfs::file_size(TEST_INFO->new_file_.hermes_.c_str()) == biggest_size_written); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_.c_str()) == + biggest_size_written); } SECTION("write to new file") { - TEST_INFO->test_open(TEST_INFO->new_file_, O_WRONLY | O_CREAT, 0600); - REQUIRE(TEST_INFO->fh_orig_ != -1); + TESTER->test_open(TESTER->new_file_, O_WRONLY | O_CREAT, 0600); + REQUIRE(TESTER->fh_orig_ != -1); size_t total_size_written = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t request_size = - TEST_INFO->medium_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->medium_max_); + TESTER->medium_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->medium_max_); std::string data(request_size, '1'); - TEST_INFO->test_write(data.c_str(), request_size); - REQUIRE(TEST_INFO->size_written_orig_ == request_size); - total_size_written += TEST_INFO->size_written_orig_; + TESTER->test_write(data.c_str(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); + total_size_written += TESTER->size_written_orig_; } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - REQUIRE(stdfs::file_size(TEST_INFO->new_file_.hermes_.c_str()) == total_size_written); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_.c_str()) == + total_size_written); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadSequentialRSRangeMedium", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=range-medium][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDONLY); - REQUIRE(TEST_INFO->fh_orig_ != -1); - std::string data(TEST_INFO->request_size_, '1'); + TESTER->test_open(TESTER->existing_file_, O_RDONLY); + REQUIRE(TESTER->fh_orig_ != -1); + std::string data(TESTER->request_size_, '1'); size_t current_offset = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t request_size = - (TEST_INFO->medium_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->medium_max_)) % - (TEST_INFO->total_size_ - current_offset); + (TESTER->medium_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->medium_max_)) % + (TESTER->total_size_ - current_offset); std::string data(request_size, '1'); - TEST_INFO->test_read(data.data(), request_size); - REQUIRE(TEST_INFO->size_read_orig_ == request_size); - current_offset += TEST_INFO->size_read_orig_; + TESTER->test_read(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); + current_offset += TESTER->size_read_orig_; } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("read from existing file always at start") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDONLY); - REQUIRE(TEST_INFO->fh_orig_ != -1); + TESTER->test_open(TESTER->existing_file_, O_RDONLY); + REQUIRE(TESTER->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - TEST_INFO->test_seek(0, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_seek(0, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->medium_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->medium_max_); + TESTER->medium_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->medium_max_); std::string data(request_size, '1'); - TEST_INFO->test_read(data.data(), request_size); - REQUIRE(TEST_INFO->size_read_orig_ == request_size); + TESTER->test_read(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadRandomRSRangeMedium", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=range-medium]" "[repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "][pattern=random][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t offset = - rand_r(&TEST_INFO->offset_seed_) % (TEST_INFO->total_size_ - TEST_INFO->medium_max_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + rand_r(&TESTER->offset_seed_) % + (TESTER->total_size_ - TESTER->medium_max_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - TEST_INFO->medium_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->medium_max_); + TESTER->medium_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->medium_max_); std::string data(request_size, '1'); - TEST_INFO->test_read(data.data(), request_size); - REQUIRE(TEST_INFO->size_read_orig_ == request_size); + TESTER->test_read(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateRandomRSRangeMedium", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=range-medium][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=random][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t offset = - rand_r(&TEST_INFO->offset_seed_) % (TEST_INFO->total_size_ - TEST_INFO->medium_max_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + rand_r(&TESTER->offset_seed_) % + (TESTER->total_size_ - TESTER->medium_max_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - TEST_INFO->medium_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->medium_max_); + TESTER->medium_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->medium_max_); std::string data(request_size, '1'); - TEST_INFO->test_write(data.c_str(), request_size); - REQUIRE(TEST_INFO->size_written_orig_ == request_size); + TESTER->test_write(data.c_str(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadStrideFixedRSRangeMedium", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=range-medium][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_fixed][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t offset = - (i * TEST_INFO->stride_size_) % (TEST_INFO->total_size_ - TEST_INFO->medium_max_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + (i * TESTER->stride_size_) % + (TESTER->total_size_ - TESTER->medium_max_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - TEST_INFO->medium_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->medium_max_); + TESTER->medium_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->medium_max_); std::string data(request_size, '1'); - TEST_INFO->test_read(data.data(), request_size); - REQUIRE(TEST_INFO->size_read_orig_ == request_size); + TESTER->test_read(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStrideFixedRSRangeMedium", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=range-medium][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_fixed][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("write to existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t offset = - (i * TEST_INFO->stride_size_) % (TEST_INFO->total_size_ - TEST_INFO->medium_max_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + (i * TESTER->stride_size_) % + (TESTER->total_size_ - TESTER->medium_max_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - TEST_INFO->medium_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->medium_max_); + TESTER->medium_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->medium_max_); std::string data(request_size, '1'); - TEST_INFO->test_write(data.c_str(), request_size); - REQUIRE(TEST_INFO->size_written_orig_ == request_size); + TESTER->test_write(data.c_str(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadStrideDynamicRSRangeMedium", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=range-medium][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_dynamic][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - size_t offset = TEST_INFO->GetRandomOffset(i, TEST_INFO->offset_seed_, TEST_INFO->stride_size_, - TEST_INFO->total_size_ - TEST_INFO->medium_max_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + size_t offset = TESTER->GetRandomOffset( + i, TESTER->offset_seed_, TESTER->stride_size_, + TESTER->total_size_ - TESTER->medium_max_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - TEST_INFO->medium_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->medium_max_); + TESTER->medium_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->medium_max_); std::string data(request_size, '1'); - TEST_INFO->test_read(data.data(), request_size); - REQUIRE(TEST_INFO->size_read_orig_ == request_size); + TESTER->test_read(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStrideDynamicRSRangeMedium", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=range-medium][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_dynamic][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - size_t offset = TEST_INFO->GetRandomOffset(i, TEST_INFO->offset_seed_, TEST_INFO->stride_size_, - TEST_INFO->total_size_ - TEST_INFO->medium_max_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + size_t offset = TESTER->GetRandomOffset( + i, TESTER->offset_seed_, TESTER->stride_size_, + TESTER->total_size_ - TESTER->medium_max_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - TEST_INFO->medium_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->medium_max_); + TESTER->medium_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->medium_max_); std::string data(request_size, '1'); - TEST_INFO->test_write(data.c_str(), request_size); - REQUIRE(TEST_INFO->size_written_orig_ == request_size); + TESTER->test_write(data.c_str(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadStrideNegativeRSRangeMedium", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=range-medium][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_negative][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - size_t offset = (TEST_INFO->total_size_ - i * TEST_INFO->stride_size_) % - (TEST_INFO->total_size_ - TEST_INFO->medium_max_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + size_t offset = (TESTER->total_size_ - i * TESTER->stride_size_) % + (TESTER->total_size_ - TESTER->medium_max_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - TEST_INFO->medium_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->medium_max_); + TESTER->medium_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->medium_max_); std::string data(request_size, '1'); - TEST_INFO->test_read(data.data(), request_size); - REQUIRE(TEST_INFO->size_read_orig_ == request_size); + TESTER->test_read(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStrideNegativeRSRangeMedium", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=range-medium][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_negative][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("write to existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - size_t offset = TEST_INFO->total_size_ - ((i * TEST_INFO->stride_size_) % - (TEST_INFO->total_size_ - TEST_INFO->medium_max_)); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + size_t offset = TESTER->total_size_ - ((i * TESTER->stride_size_) % + (TESTER->total_size_ - TESTER->medium_max_)); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - TEST_INFO->medium_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->medium_max_); + TESTER->medium_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->medium_max_); std::string data(request_size, '1'); - TEST_INFO->test_write(data.c_str(), request_size); - REQUIRE(TEST_INFO->size_written_orig_ == request_size); + TESTER->test_write(data.c_str(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadStride2DRSRangeMedium", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=range-medium][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_2d][file=1]") { - TEST_INFO->Pretest(); - size_t rows = sqrt(TEST_INFO->total_size_); + TESTER->Pretest(); + size_t rows = sqrt(TESTER->total_size_); size_t cols = rows; - REQUIRE(rows * cols == TEST_INFO->total_size_); + REQUIRE(rows * cols == TESTER->total_size_); size_t cell_size = 128; - size_t cell_stride = rows * cols / cell_size / TEST_INFO->num_iterations_; + size_t cell_stride = rows * cols / cell_size / TESTER->num_iterations_; SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); size_t prev_cell_col = 0, prev_cell_row = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t current_cell_col = (prev_cell_col + cell_stride) % cols; size_t current_cell_row = prev_cell_col + cell_stride > cols ? prev_cell_row + 1 : prev_cell_row; prev_cell_row = current_cell_row; size_t offset = (current_cell_col * cell_stride + prev_cell_row * cols) % - (TEST_INFO->total_size_ - TEST_INFO->medium_max_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + (TESTER->total_size_ - TESTER->medium_max_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - TEST_INFO->medium_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->medium_max_); + TESTER->medium_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->medium_max_); std::string data(request_size, '1'); - TEST_INFO->test_read(data.data(), request_size); - REQUIRE(TEST_INFO->size_read_orig_ == request_size); + TESTER->test_read(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStride2DRSRangeMedium", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=range-medium][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_2d][file=1]") { - TEST_INFO->Pretest(); - size_t rows = sqrt(TEST_INFO->total_size_); + TESTER->Pretest(); + size_t rows = sqrt(TESTER->total_size_); size_t cols = rows; - REQUIRE(rows * cols == TEST_INFO->total_size_); + REQUIRE(rows * cols == TESTER->total_size_); size_t cell_size = 128; - size_t cell_stride = rows * cols / cell_size / TEST_INFO->num_iterations_; + size_t cell_stride = rows * cols / cell_size / TESTER->num_iterations_; SECTION("write to existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); size_t prev_cell_col = 0, prev_cell_row = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t current_cell_col = (prev_cell_col + cell_stride) % cols; size_t current_cell_row = prev_cell_col + cell_stride > cols ? prev_cell_row + 1 : prev_cell_row; prev_cell_row = current_cell_row; size_t offset = (current_cell_col * cell_stride + prev_cell_row * cols) % - (TEST_INFO->total_size_ - TEST_INFO->medium_max_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + (TESTER->total_size_ - TESTER->medium_max_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - TEST_INFO->medium_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->medium_max_); + TESTER->medium_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->medium_max_); std::string data(request_size, '1'); - TEST_INFO->test_write(data.c_str(), request_size); - REQUIRE(TEST_INFO->size_written_orig_ == request_size); + TESTER->test_write(data.c_str(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } /** * Large RS **/ TEST_CASE("BatchedWriteRSRangeLarge", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=range-large][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("write to new file always at the start") { - TEST_INFO->test_open(TEST_INFO->new_file_, O_WRONLY | O_CREAT, 0600); - REQUIRE(TEST_INFO->fh_orig_ != -1); + TESTER->test_open(TESTER->new_file_, O_WRONLY | O_CREAT, 0600); + REQUIRE(TESTER->fh_orig_ != -1); size_t biggest_size_written = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - TEST_INFO->test_seek(0, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_seek(0, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->large_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->large_max_); + TESTER->large_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->large_max_); std::string data(request_size, '1'); - TEST_INFO->test_write(data.c_str(), request_size); - REQUIRE(TEST_INFO->size_written_orig_ == request_size); + TESTER->test_write(data.c_str(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); if (biggest_size_written < request_size) biggest_size_written = request_size; } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - REQUIRE(stdfs::file_size(TEST_INFO->new_file_.hermes_.c_str()) == biggest_size_written); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_.c_str()) == + biggest_size_written); } SECTION("write to new file") { - TEST_INFO->test_open(TEST_INFO->new_file_, O_WRONLY | O_CREAT, 0600); - REQUIRE(TEST_INFO->fh_orig_ != -1); + TESTER->test_open(TESTER->new_file_, O_WRONLY | O_CREAT, 0600); + REQUIRE(TESTER->fh_orig_ != -1); size_t total_size_written = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t request_size = - TEST_INFO->large_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->large_max_); + TESTER->large_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->large_max_); std::string data(request_size, '1'); - TEST_INFO->test_write(data.c_str(), request_size); - REQUIRE(TEST_INFO->size_written_orig_ == request_size); - total_size_written += TEST_INFO->size_written_orig_; + TESTER->test_write(data.c_str(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); + total_size_written += TESTER->size_written_orig_; } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); - REQUIRE(stdfs::file_size(TEST_INFO->new_file_.hermes_.c_str()) == total_size_written); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_.c_str()) == + total_size_written); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadSequentialRSRangeLarge", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=range-large][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDONLY); - REQUIRE(TEST_INFO->fh_orig_ != -1); - std::string data(TEST_INFO->request_size_, '1'); + TESTER->test_open(TESTER->existing_file_, O_RDONLY); + REQUIRE(TESTER->fh_orig_ != -1); + std::string data(TESTER->request_size_, '1'); size_t current_offset = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t request_size = - (TEST_INFO->large_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->large_max_)) % - (TEST_INFO->total_size_ - current_offset); + (TESTER->large_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->large_max_)) % + (TESTER->total_size_ - current_offset); std::string data(request_size, '1'); - TEST_INFO->test_read(data.data(), request_size); - REQUIRE(TEST_INFO->size_read_orig_ == request_size); - current_offset += TEST_INFO->size_read_orig_; + TESTER->test_read(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); + current_offset += TESTER->size_read_orig_; } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("read from existing file always at start") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDONLY); - REQUIRE(TEST_INFO->fh_orig_ != -1); + TESTER->test_open(TESTER->existing_file_, O_RDONLY); + REQUIRE(TESTER->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - TEST_INFO->test_seek(0, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_seek(0, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->large_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->large_max_); + TESTER->large_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->large_max_); std::string data(request_size, '1'); - TEST_INFO->test_read(data.data(), request_size); - REQUIRE(TEST_INFO->size_read_orig_ == request_size); + TESTER->test_read(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadRandomRSRangeLarge", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=range-large]" "[repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "][pattern=random][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t offset = - rand_r(&TEST_INFO->offset_seed_) % (TEST_INFO->total_size_ - TEST_INFO->large_max_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + rand_r(&TESTER->offset_seed_) % + (TESTER->total_size_ - TESTER->large_max_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - (TEST_INFO->large_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->large_max_)) % - (TEST_INFO->total_size_ - TEST_INFO->status_orig_); + (TESTER->large_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->large_max_)) % + (TESTER->total_size_ - TESTER->status_orig_); std::string data(request_size, '1'); - TEST_INFO->test_read(data.data(), request_size); - REQUIRE(TEST_INFO->size_read_orig_ == request_size); + TESTER->test_read(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateRandomRSRangeLarge", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=range-large][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=random][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t offset = - rand_r(&TEST_INFO->offset_seed_) % (TEST_INFO->total_size_ - TEST_INFO->large_max_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + rand_r(&TESTER->offset_seed_) % + (TESTER->total_size_ - TESTER->large_max_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - TEST_INFO->large_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->large_max_); + TESTER->large_min_ + (rand_r(&TESTER->rs_seed_) % TESTER->large_max_); std::string data(request_size, '1'); - TEST_INFO->test_write(data.c_str(), request_size); - REQUIRE(TEST_INFO->size_written_orig_ == request_size); + TESTER->test_write(data.c_str(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadStrideFixedRSRangeLarge", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=range-large][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_fixed][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t offset = - (i * TEST_INFO->stride_size_) % (TEST_INFO->total_size_ - TEST_INFO->large_max_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + (i * TESTER->stride_size_) % + (TESTER->total_size_ - TESTER->large_max_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - TEST_INFO->large_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->large_max_); + TESTER->large_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->large_max_); std::string data(request_size, '1'); - TEST_INFO->test_read(data.data(), request_size); - REQUIRE(TEST_INFO->size_read_orig_ == request_size); + TESTER->test_read(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStrideFixedRSRangeLarge", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=range-large][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_fixed][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("write to existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t offset = - (i * TEST_INFO->stride_size_) % (TEST_INFO->total_size_ - TEST_INFO->large_max_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + (i * TESTER->stride_size_) % + (TESTER->total_size_ - TESTER->large_max_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - TEST_INFO->large_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->large_max_); + TESTER->large_min_ + (rand_r(&TESTER->rs_seed_) % TESTER->large_max_); std::string data(request_size, '1'); - TEST_INFO->test_write(data.c_str(), request_size); - REQUIRE(TEST_INFO->size_written_orig_ == request_size); + TESTER->test_write(data.c_str(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadStrideDynamicRSRangeLarge", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=range-large][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_dynamic][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - size_t offset = TEST_INFO->GetRandomOffset(i, TEST_INFO->offset_seed_, TEST_INFO->stride_size_, - TEST_INFO->total_size_ - TEST_INFO->large_max_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + size_t offset = TESTER->GetRandomOffset( + i, TESTER->offset_seed_, TESTER->stride_size_, + TESTER->total_size_ - TESTER->large_max_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - TEST_INFO->large_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->large_max_); + TESTER->large_min_ + (rand_r(&TESTER->rs_seed_) % TESTER->large_max_); std::string data(request_size, '1'); - TEST_INFO->test_read(data.data(), request_size); - REQUIRE(TEST_INFO->size_read_orig_ == request_size); + TESTER->test_read(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStrideDynamicRSRangeLarge", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=range-large][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_dynamic][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - size_t offset = TEST_INFO->GetRandomOffset(i, TEST_INFO->offset_seed_, TEST_INFO->stride_size_, - TEST_INFO->total_size_ - TEST_INFO->large_max_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + size_t offset = TESTER->GetRandomOffset( + i, TESTER->offset_seed_, TESTER->stride_size_, + TESTER->total_size_ - TESTER->large_max_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - TEST_INFO->large_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->large_max_); + TESTER->large_min_ + (rand_r(&TESTER->rs_seed_) % TESTER->large_max_); std::string data(request_size, '1'); - TEST_INFO->test_write(data.c_str(), request_size); - REQUIRE(TEST_INFO->size_written_orig_ == request_size); + TESTER->test_write(data.c_str(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadStrideNegativeRSRangeLarge", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=range-large][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_negative][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - size_t offset = (TEST_INFO->total_size_ - i * TEST_INFO->stride_size_) % - (TEST_INFO->total_size_ - TEST_INFO->large_max_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + size_t offset = (TESTER->total_size_ - i * TESTER->stride_size_) % + (TESTER->total_size_ - TESTER->large_max_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - (TEST_INFO->large_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->large_max_)) % - (TEST_INFO->total_size_ - TEST_INFO->large_max_); + (TESTER->large_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->large_max_)) % + (TESTER->total_size_ - TESTER->large_max_); std::string data(request_size, '1'); - TEST_INFO->test_read(data.data(), request_size); - REQUIRE(TEST_INFO->size_read_orig_ == request_size); + TESTER->test_read(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStrideNegativeRSRangeLarge", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=range-large][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_negative][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("write to existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - size_t offset = TEST_INFO->total_size_ - ((i * TEST_INFO->stride_size_) % - (TEST_INFO->total_size_ - TEST_INFO->large_max_)); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + size_t offset = TESTER->total_size_ - ((i * TESTER->stride_size_) % + (TESTER->total_size_ - TESTER->large_max_)); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - TEST_INFO->large_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->large_max_); + TESTER->large_min_ + (rand_r(&TESTER->rs_seed_) % TESTER->large_max_); std::string data(request_size, '1'); - TEST_INFO->test_write(data.c_str(), request_size); - REQUIRE(TEST_INFO->size_written_orig_ == request_size); + TESTER->test_write(data.c_str(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadStride2DRSRangeLarge", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=range-large][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_2d][file=1]") { - TEST_INFO->Pretest(); - size_t rows = sqrt(TEST_INFO->total_size_); + TESTER->Pretest(); + size_t rows = sqrt(TESTER->total_size_); size_t cols = rows; - REQUIRE(rows * cols == TEST_INFO->total_size_); + REQUIRE(rows * cols == TESTER->total_size_); size_t cell_size = 128; - size_t cell_stride = rows * cols / cell_size / TEST_INFO->num_iterations_; + size_t cell_stride = rows * cols / cell_size / TESTER->num_iterations_; SECTION("read from existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); size_t prev_cell_col = 0, prev_cell_row = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t current_cell_col = (prev_cell_col + cell_stride) % cols; size_t current_cell_row = prev_cell_col + cell_stride > cols ? prev_cell_row + 1 : prev_cell_row; prev_cell_row = current_cell_row; size_t offset = (current_cell_col * cell_stride + prev_cell_row * cols) % - (TEST_INFO->total_size_ - TEST_INFO->large_max_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + (TESTER->total_size_ - TESTER->large_max_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - TEST_INFO->large_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->large_max_); + TESTER->large_min_ + (rand_r(&TESTER->rs_seed_) % TESTER->large_max_); std::string data(request_size, '1'); - TEST_INFO->test_read(data.data(), request_size); - REQUIRE(TEST_INFO->size_read_orig_ == request_size); + TESTER->test_read(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStride2DRSRangeLarge", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=range-large][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_2d][file=1]") { - TEST_INFO->Pretest(); - size_t rows = sqrt(TEST_INFO->total_size_); + TESTER->Pretest(); + size_t rows = sqrt(TESTER->total_size_); size_t cols = rows; - REQUIRE(rows * cols == TEST_INFO->total_size_); + REQUIRE(rows * cols == TESTER->total_size_); size_t cell_size = 128; - size_t cell_stride = rows * cols / cell_size / TEST_INFO->num_iterations_; + size_t cell_stride = rows * cols / cell_size / TESTER->num_iterations_; SECTION("write to existing file") { - TEST_INFO->test_open(TEST_INFO->existing_file_, O_RDWR); - REQUIRE(TEST_INFO->fh_orig_ != -1); + TESTER->test_open(TESTER->existing_file_, O_RDWR); + REQUIRE(TESTER->fh_orig_ != -1); size_t prev_cell_col = 0, prev_cell_row = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t current_cell_col = (prev_cell_col + cell_stride) % cols; size_t current_cell_row = prev_cell_col + cell_stride > cols ? prev_cell_row + 1 : prev_cell_row; prev_cell_row = current_cell_row; size_t offset = (current_cell_col * cell_stride + prev_cell_row * cols) % - (TEST_INFO->total_size_ - TEST_INFO->large_max_); - TEST_INFO->test_seek(offset, SEEK_SET); - REQUIRE(((size_t)TEST_INFO->status_orig_) == offset); + (TESTER->total_size_ - TESTER->large_max_); + TESTER->test_seek(offset, SEEK_SET); + REQUIRE(((size_t)TESTER->status_orig_) == offset); size_t request_size = - TEST_INFO->large_min_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->large_max_); + TESTER->large_min_ + (rand_r(&TESTER->rs_seed_) % TESTER->large_max_); std::string data(request_size, '1'); - TEST_INFO->test_write(data.c_str(), request_size); - REQUIRE(TEST_INFO->size_written_orig_ == request_size); + TESTER->test_write(data.c_str(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - TEST_INFO->test_close(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_close(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } diff --git a/test/unit/hermes_adapters/posix/posix_adapter_shared_test.cc b/test/unit/hermes_adapters/posix/posix_adapter_shared_test.cc index a7c771d17..9ce490641 100644 --- a/test/unit/hermes_adapters/posix/posix_adapter_shared_test.cc +++ b/test/unit/hermes_adapters/posix/posix_adapter_shared_test.cc @@ -12,18 +12,18 @@ #include "posix_adapter_test.h" -TEST_CASE("SharedFile", "[process=" + std::to_string(TEST_INFO->comm_size_) + +TEST_CASE("SharedFile", "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=range-small][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[mode=shared]" "[pattern=sequential][file=1]") { - TEST_INFO->Pretest(); - REQUIRE(TEST_INFO->comm_size_ == 2); + TESTER->Pretest(); + REQUIRE(TESTER->comm_size_ == 2); SECTION("producer-consumer") { - bool producer = TEST_INFO->rank_ % 2 == 0; + bool producer = TESTER->rank_ % 2 == 0; struct flock lock; lock.l_type = F_WRLCK; lock.l_whence = SEEK_SET; @@ -31,16 +31,17 @@ TEST_CASE("SharedFile", "[process=" + std::to_string(TEST_INFO->comm_size_) + lock.l_len = 0; lock.l_pid = getpid(); if (producer) { - int fd = open(TEST_INFO->shared_new_file_.hermes_.c_str(), O_RDWR | O_CREAT, 0666); + int fd = open(TESTER->shared_new_file_.hermes_.c_str(), + O_RDWR | O_CREAT, 0666); REQUIRE(fd != -1); MPI_Barrier(MPI_COMM_WORLD); int status = -1; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { status = fcntl(fd, F_SETLKW, &lock); REQUIRE(status != -1); size_t write_bytes = - write(fd, TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(write_bytes == TEST_INFO->request_size_); + write(fd, TESTER->write_data_.data(), TESTER->request_size_); + REQUIRE(write_bytes == TESTER->request_size_); lock.l_type = F_UNLCK; status = fcntl(fd, F_SETLK, &lock); REQUIRE(status != -1); @@ -49,11 +50,11 @@ TEST_CASE("SharedFile", "[process=" + std::to_string(TEST_INFO->comm_size_) + REQUIRE(status != -1); } else { MPI_Barrier(MPI_COMM_WORLD); - int fd = open(TEST_INFO->shared_new_file_.hermes_.c_str(), O_RDONLY); + int fd = open(TESTER->shared_new_file_.hermes_.c_str(), O_RDONLY); REQUIRE(fd != -1); int status = -1; size_t bytes_read = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { lock.l_type = F_RDLCK; status = fcntl(fd, F_SETLKW, &lock); REQUIRE(status != -1); @@ -61,10 +62,10 @@ TEST_CASE("SharedFile", "[process=" + std::to_string(TEST_INFO->comm_size_) + size_t cur_offset = lseek(fd, bytes_read, SEEK_SET); REQUIRE(cur_offset == bytes_read); if (file_size > bytes_read) { - size_t read_size = TEST_INFO->request_size_ < file_size - bytes_read - ? TEST_INFO->request_size_ + size_t read_size = TESTER->request_size_ < file_size - bytes_read + ? TESTER->request_size_ : file_size - bytes_read; - size_t read_bytes = read(fd, TEST_INFO->read_data_.data(), read_size); + size_t read_bytes = read(fd, TESTER->read_data_.data(), read_size); REQUIRE(read_bytes == read_size); bytes_read += read_bytes; } @@ -76,5 +77,5 @@ TEST_CASE("SharedFile", "[process=" + std::to_string(TEST_INFO->comm_size_) + REQUIRE(status != -1); } } - TEST_INFO->Posttest(); + TESTER->Posttest(); } diff --git a/test/unit/hermes_adapters/posix/posix_adapter_test.cc b/test/unit/hermes_adapters/posix/posix_adapter_test.cc index d27256daa..a4bd24213 100644 --- a/test/unit/hermes_adapters/posix/posix_adapter_test.cc +++ b/test/unit/hermes_adapters/posix/posix_adapter_test.cc @@ -13,5 +13,5 @@ #include "posix_adapter_test.h" int main(int argc, char **argv) { - TEST_INFO->Init(argc, argv); + TESTER->Init(argc, argv); } diff --git a/test/unit/hermes_adapters/posix/posix_adapter_test.h b/test/unit/hermes_adapters/posix/posix_adapter_test.h index a232bf8f6..cf4625d7a 100644 --- a/test/unit/hermes_adapters/posix/posix_adapter_test.h +++ b/test/unit/hermes_adapters/posix/posix_adapter_test.h @@ -13,11 +13,11 @@ #ifndef HERMES_TEST_UNIT_HERMES_ADAPTERS_POSIX_POSIX_ADAPTER_BASE_TEST_H_ #define HERMES_TEST_UNIT_HERMES_ADAPTERS_POSIX_POSIX_ADAPTER_BASE_TEST_H_ -#include "filesystem_tests.h" +#include "binary_file_tests.h" -namespace hermes::adapter::fs::test { +namespace hermes::adapter::test { template -class PosixTest : public FilesystemTests { +class PosixTest : public BinaryFileTests { public: FileInfo new_file_; FileInfo existing_file_; @@ -48,12 +48,13 @@ class PosixTest : public FilesystemTests { RegisterPath("new", 0, new_file_); RegisterPath("ext", TEST_DO_CREATE, existing_file_); if constexpr(WITH_MPI) { - RegisterPath("shared_new", TEST_DO_CREATE | TEST_FILE_SHARED, shared_new_file_); - RegisterPath("shared_ext", TEST_DO_CREATE | TEST_FILE_SHARED, shared_existing_file_); + RegisterPath("shared_new", TEST_FILE_SHARED, shared_new_file_); + RegisterPath("shared_ext", TEST_DO_CREATE | TEST_FILE_SHARED, + shared_existing_file_); } RegisterTmpPath(tmp_file_); } - + void test_open(FileInfo &info, int flags, ...) { int mode = 0; if (flags & O_CREAT || flags & O_TMPFILE) { @@ -114,14 +115,15 @@ class PosixTest : public FilesystemTests { } }; -} // namespace hermes::adapter::fs::test +} // namespace hermes::adapter::test #if defined(HERMES_MPI_TESTS) -#define TEST_INFO \ - hshm::EasySingleton>::GetInstance() +#define TESTER \ + hshm::EasySingleton< \ + hermes::adapter::test::PosixTest>::GetInstance() #else -#define TEST_INFO \ - hshm::EasySingleton>::GetInstance() +#define TESTER \ + hshm::EasySingleton>::GetInstance() #endif #endif // HERMES_TEST_UNIT_HERMES_ADAPTERS_POSIX_POSIX_ADAPTER_BASE_TEST_H_ diff --git a/test/unit/hermes_adapters/posix/tests.py b/test/unit/hermes_adapters/posix/tests.py deleted file mode 100644 index b29b4300f..000000000 --- a/test/unit/hermes_adapters/posix/tests.py +++ /dev/null @@ -1,110 +0,0 @@ -from py_hermes_ci.test_manager import TestManager -from jarvis_util import * - - -class PosixTestManager(TestManager): - def spawn_all_nodes(self): - return self.spawn_info() - - def set_paths(self): - self.POSIX_CMD = f"{self.CMAKE_BINARY_DIR}/bin/posix_adapter_test" - self.HERMES_POSIX_CMD = f"{self.CMAKE_BINARY_DIR}/bin/hermes_posix_adapter_test" - self.POSIX_MPI_CMD = f"{self.CMAKE_BINARY_DIR}/bin/posix_adapter_mpi_test" - self.HERMES_POSIX_MPI_CMD = f"{self.CMAKE_BINARY_DIR}/bin/hermes_posix_adapter_mpi_test" - self.POSIX_SIMPLE_IO_CMD = f"{self.CMAKE_BINARY_DIR}/bin/posix_simple_io_omp" - self.HERMES_POSIX_SIMPLE_IO_CMD = f"{self.CMAKE_BINARY_DIR}/bin/hermes_posix_simple_io_omp" - - self.disable_testing = False - - def test_posix_basic(self): - return - posix_cmd = f"{self.POSIX_CMD}" - node = Exec(posix_cmd) - return node.exit_code - - def test_hermes_posix_basic_small(self): - posix_cmd = f"{self.HERMES_POSIX_CMD} " \ - f"~[request_size=range-small] " \ - f"--reporter compact -d yes" - - spawn_info = self.spawn_info(nprocs=1, - hermes_conf='hermes_server') - self.start_daemon(spawn_info) - node = Exec(posix_cmd, spawn_info) - self.stop_daemon(spawn_info) - return node.exit_code - - def test_hermes_posix_basic_large(self): - posix_cmd = f"{self.HERMES_POSIX_CMD} " \ - f"[request_size=range-large] " \ - f"--reporter compact -d yes" - spawn_info = self.spawn_info(nprocs=1, - hermes_conf='hermes_server') - self.start_daemon(spawn_info) - node = Exec(posix_cmd, spawn_info) - self.stop_daemon(spawn_info) - return node.exit_code - - def test_posix_basic_mpi(self): - return - posix_cmd = f"{self.POSIX_MPI_CMD}" - spawn_info = self.spawn_info(nprocs=2) - node = Exec(posix_cmd, spawn_info) - return node.exit_code - - def test_hermes_posix_basic_mpi_small(self): - posix_cmd = f"{self.HERMES_POSIX_MPI_CMD} " \ - f"~[request_size=range-large] " \ - f"--reporter compact -d yes" - spawn_info = self.spawn_info(nprocs=2, - hermes_conf='hermes_server') - self.start_daemon(spawn_info) - node = Exec(posix_cmd, spawn_info) - self.stop_daemon(spawn_info) - return node.exit_code - - def test_hermes_posix_basic_mpi_large(self): - posix_cmd = f"{self.HERMES_POSIX_MPI_CMD} " \ - f"[request_size=range-large] " \ - f"--reporter compact -d yes" - spawn_info = self.spawn_info(nprocs=2, - hermes_conf='hermes_server') - self.start_daemon(spawn_info) - node = Exec(posix_cmd, spawn_info) - self.stop_daemon(spawn_info) - return node.exit_code - - def test_hermes_posix_simple_io_omp_default(self): - posix_cmd = f"{self.HERMES_POSIX_SIMPLE_IO_CMD} " \ - f"/tmp/test_hermes/hi.txt 0 1024 8 0" - spawn_info = self.spawn_info(nprocs=2, - hermes_conf='hermes_server', - hermes_mode='kDefault') - self.start_daemon(spawn_info) - node = Exec(posix_cmd, spawn_info) - self.stop_daemon(spawn_info) - return node.exit_code - - def test_hermes_posix_simple_io_omp_scratch(self): - posix_cmd = f"{self.HERMES_POSIX_SIMPLE_IO_CMD} " \ - f"/tmp/test_hermes/hi.txt 0 1024 8 0" - spawn_info = self.spawn_info(nprocs=2, - hermes_conf='hermes_server', - hermes_mode='kScratch') - self.start_daemon(spawn_info) - node = Exec(posix_cmd, spawn_info) - self.stop_daemon(spawn_info) - return node.exit_code - - def test_hermes_posix_simple_io_omp_preload(self): - return - posix_cmd = f"{self.POSIX_SIMPLE_IO_CMD} " \ - f"/tmp/test_hermes/hi.txt 0 1024 8 0" - spawn_info = self.spawn_info(nprocs=2, - hermes_conf='hermes_server', - hermes_mode='kScratch', - api='posix') - self.start_daemon(spawn_info) - node = Exec(posix_cmd, spawn_info) - self.stop_daemon(spawn_info) - return node.exit_code diff --git a/test/unit/hermes_adapters/stdio/CMakeLists.txt b/test/unit/hermes_adapters/stdio/CMakeLists.txt index 49c3da24f..8bc02b7b4 100644 --- a/test/unit/hermes_adapters/stdio/CMakeLists.txt +++ b/test/unit/hermes_adapters/stdio/CMakeLists.txt @@ -5,20 +5,26 @@ include_directories( #------------------------------------------------------------------------------ # STDIO Adapter Internal tests #------------------------------------------------------------------------------ -#add_executable(stdio_adapter_mapper_test stdio_adapter_mapper_test.cc ${ADAPTER_COMMON}) -#target_link_libraries(stdio_adapter_mapper_test stdc++fs hermes_stdio) -#add_dependencies(stdio_adapter_mapper_test hermes_stdio) -#pytest(stdio test_hermes_stdio_mapper) +add_executable(hermes_stdio_adapter_mapper_test + stdio_adapter_test.cc + stdio_adapter_mapper_test.cc) +add_dependencies(hermes_stdio_adapter_mapper_test + hermes_stdio) +target_link_libraries(hermes_stdio_adapter_mapper_test + hermes_stdio) +target_compile_definitions(hermes_stdio_adapter_mapper_test PUBLIC + HERMES_INTERCEPT=1 HERMES_MPI_TESTS=false) +jarvis_test(stdio test_hermes_stdio_mapper) #------------------------------------------------------------------------------ # STDIO Adapter End to End tests #------------------------------------------------------------------------------ +# Non-Hermes, None-MPI STDIO basic add_executable(stdio_adapter_test stdio_adapter_test.cc stdio_adapter_basic_test.cc stdio_adapter_func_test.cc -# stdio_adapter_rs_test.cc - ${ADAPTER_COMMON}) + stdio_adapter_rs_test.cc) add_dependencies(stdio_adapter_test hermes) target_link_libraries(stdio_adapter_test @@ -27,11 +33,11 @@ target_compile_definitions(stdio_adapter_test PUBLIC HERMES_MPI_TESTS=false) jarvis_test(stdio test_stdio_basic) +# Hermes, None-MPI STDIO basic add_executable(hermes_stdio_adapter_test stdio_adapter_test.cc stdio_adapter_basic_test.cc -# stdio_adapter_rs_test.cc - ${ADAPTER_COMMON}) + stdio_adapter_rs_test.cc) add_dependencies(hermes_stdio_adapter_test hermes_stdio) target_link_libraries(hermes_stdio_adapter_test @@ -41,48 +47,67 @@ target_compile_definitions(hermes_stdio_adapter_test PUBLIC jarvis_test(stdio test_hermes_stdio_basic_small) jarvis_test(stdio test_hermes_stdio_basic_large) -#add_executable(stdio_adapter_mpi_test -# stdio_adapter_mpi_test.cpp -# ${ADAPTER_COMMON}) -# pytest(stdio test_stdio_basic_mpi 2 "") +# Non-Hermes, MPI STDIO basic +add_executable(stdio_adapter_mpi_test + stdio_adapter_test.cc + stdio_adapter_basic_test.cc + stdio_adapter_rs_test.cc + stdio_adapter_shared_test.cc) +add_dependencies(stdio_adapter_mpi_test + hermes) +target_link_libraries(stdio_adapter_mpi_test + hermes) +target_compile_definitions(stdio_adapter_mpi_test PUBLIC + HERMES_MPI_TESTS=true) +jarvis_test(stdio test_stdio_basic_mpi) + +# Hermes, MPI STDIO basic +add_executable(hermes_stdio_adapter_mpi_test + stdio_adapter_test.cc + stdio_adapter_basic_test.cc + stdio_adapter_rs_test.cc + stdio_adapter_shared_test.cc) +target_link_libraries(hermes_stdio_adapter_mpi_test + hermes_stdio) +add_dependencies(hermes_stdio_adapter_mpi_test + hermes_stdio) +target_compile_definitions(hermes_stdio_adapter_mpi_test PUBLIC + HERMES_INTERCEPT=1 HERMES_MPI_TESTS=true) +jarvis_test(stdio test_hermes_stdio_basic_mpi_small) +jarvis_test(stdio test_hermes_stdio_basic_mpi_large) + +# Hermes, Low buffer space +add_executable(hermes_stdio_low_buf_adapter_test + stdio_adapter_test.cc + stdio_adapter_low_buffer_space_test.cc) +target_link_libraries(hermes_stdio_low_buf_adapter_test hermes_stdio) +add_dependencies(hermes_stdio_low_buf_adapter_test hermes_stdio) +target_compile_definitions(hermes_stdio_low_buf_adapter_test PUBLIC + HERMES_INTERCEPT=1 HERMES_MPI_TESTS=false) +jarvis_test(stdio test_hermes_stdio_low_buf) -#add_executable(hermes_stdio_adapter_mpi_test -# stdio_adapter_mpi_test.cpp -# ${ADAPTER_COMMON}) -#target_link_libraries(hermes_stdio_adapter_mpi_test hermes_stdio) -#add_dependencies(hermes_stdio_adapter_mpi_test hermes_stdio) -#set_target_properties(hermes_stdio_adapter_mpi_test PROPERTIES COMPILE_FLAGS "-DHERMES_INTERCEPT=1") -#pytest(stdio test_hermes_stdio_mpi_small) -#pytest(stdio test_hermes_stdio_mpi_large) -# -#add_executable(hermes_stdio_low_buf_adapter_test -# stdio_adapter_low_buffer_space_test.cpp -# ${ADAPTER_COMMON}) -#target_link_libraries(hermes_stdio_low_buf_adapter_test hermes_stdio) -#add_dependencies(hermes_stdio_low_buf_adapter_test hermes_stdio) -#set_target_properties(hermes_stdio_low_buf_adapter_test PROPERTIES COMPILE_FLAGS "-DHERMES_INTERCEPT=1") -#pytest(stdio test_hermes_stdio_low_buf) -# -#add_executable(hermes_stdio_adapter_mode_test -# stdio_adapter_mode_test.cpp -# ${ADAPTER_COMMON}) -#target_link_libraries(hermes_stdio_adapter_mode_test -# hermes_stdio) -#add_dependencies(hermes_stdio_adapter_mode_test -# hermes_stdio) -#set_target_properties(hermes_stdio_adapter_mode_test PROPERTIES COMPILE_FLAGS "-DHERMES_INTERCEPT=1") -#pytest(stdio test_hermes_stdio_bypass) -#pytest(stdio test_hermes_stdio_default) -#pytest(stdio test_hermes_stdio_scratch) +# Hermes, Adapter mode +add_executable(hermes_stdio_adapter_mode_test + stdio_adapter_test.cc + stdio_adapter_mode_test.cc) +target_link_libraries(hermes_stdio_adapter_mode_test + hermes_stdio) +add_dependencies(hermes_stdio_adapter_mode_test + hermes_stdio) +target_compile_definitions(hermes_stdio_adapter_mode_test PUBLIC + HERMES_INTERCEPT=1 HERMES_MPI_TESTS=false) +jarvis_test(stdio test_hermes_stdio_adapter_bypass) +jarvis_test(stdio test_hermes_stdio_adapter_default) +jarvis_test(stdio test_hermes_stdio_adapter_scratch) set(STDIO_TESTS -# stdio_adapter_mapper_test - stdio_adapter_test - hermes_stdio_adapter_test -# hermes_stdio_low_buf_adapter_test -# hermes_stdio_adapter_mode_test -# stdio_adapter_mpi_test -# hermes_stdio_adapter_mpi_test + stdio_adapter_test + hermes_stdio_adapter_test + hermes_stdio_low_buf_adapter_test + hermes_stdio_adapter_mapper_test + hermes_stdio_adapter_mode_test + stdio_adapter_mpi_test + hermes_stdio_adapter_mpi_test ) foreach(program ${STDIO_TESTS}) diff --git a/test/unit/hermes_adapters/stdio/stdio_adapter_basic_test.cc b/test/unit/hermes_adapters/stdio/stdio_adapter_basic_test.cc index c26a2dab7..ca2f300d0 100644 --- a/test/unit/hermes_adapters/stdio/stdio_adapter_basic_test.cc +++ b/test/unit/hermes_adapters/stdio/stdio_adapter_basic_test.cc @@ -12,972 +12,1004 @@ #include "stdio_adapter_test.h" -TEST_CASE("Open", "[process=" + std::to_string(TEST_INFO->comm_size_) + +TEST_CASE("Open", "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=single_open]" "[repetition=1][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("open non-existant file") { - TEST_INFO->test_fopen(TEST_INFO->new_file_, "r"); - REQUIRE(TEST_INFO->fh_orig_ == nullptr); - TEST_INFO->test_fopen(TEST_INFO->new_file_, "r+"); - REQUIRE(TEST_INFO->fh_orig_ == nullptr); + TESTER->test_fopen(TESTER->new_file_, "r"); + REQUIRE(TESTER->fh_orig_ == nullptr); + TESTER->test_fopen(TESTER->new_file_, "r+"); + REQUIRE(TESTER->fh_orig_ == nullptr); } SECTION("truncate existing file and write-only") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "w"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fopen(TESTER->existing_file_, "w"); + REQUIRE(TESTER->fh_orig_ != nullptr); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("truncate existing file and read/write") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "w+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fopen(TESTER->existing_file_, "w+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("open existing file") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "r+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "r"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_fopen(TESTER->existing_file_, "r"); + REQUIRE(TESTER->fh_orig_ != nullptr); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("append write existing file") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "a"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fopen(TESTER->existing_file_, "a"); + REQUIRE(TESTER->fh_orig_ != nullptr); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("append write and read existing file") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "a+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fopen(TESTER->existing_file_, "a+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } -TEST_CASE("SingleWrite", "[process=" + std::to_string(TEST_INFO->comm_size_) + +TEST_CASE("SingleWrite", "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=single_write]" "[request_size=type-fixed][repetition=1]" "[file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("write to existing file") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "r+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - TEST_INFO->test_fseek(0, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_fwrite(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + TESTER->test_fseek(0, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_fwrite(TESTER->write_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("write to new file") { - TEST_INFO->test_fopen(TEST_INFO->new_file_, "w+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - TEST_INFO->test_fwrite(TEST_INFO->write_data_.data(), - TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); - REQUIRE(stdfs::file_size(TEST_INFO->new_file_.hermes_) == TEST_INFO->size_written_orig_); + TESTER->test_fopen(TESTER->new_file_, "w+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + TESTER->test_fwrite(TESTER->write_data_.data(), + TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_) == + TESTER->size_written_orig_); } SECTION("write to existing file with truncate") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "w"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - TEST_INFO->test_fwrite(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); - REQUIRE(stdfs::file_size(TEST_INFO->existing_file_.hermes_) == TEST_INFO->size_written_orig_); + TESTER->test_fopen(TESTER->existing_file_, "w"); + REQUIRE(TESTER->fh_orig_ != nullptr); + TESTER->test_fwrite(TESTER->write_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->existing_file_.hermes_) == + TESTER->size_written_orig_); } SECTION("write to existing file at the end") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "r+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - TEST_INFO->test_fseek(0, SEEK_END); - REQUIRE(TEST_INFO->status_orig_ == 0); - size_t offset = ftell(TEST_INFO->fh_orig_); - REQUIRE(offset == TEST_INFO->request_size_ * TEST_INFO->num_iterations_); - TEST_INFO->test_fwrite(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); - REQUIRE(stdfs::file_size(TEST_INFO->existing_file_.hermes_) == - TEST_INFO->size_written_orig_ + offset); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + TESTER->test_fseek(0, SEEK_END); + REQUIRE(TESTER->status_orig_ == 0); + size_t offset = ftell(TESTER->fh_orig_); + REQUIRE(offset == TESTER->request_size_ * TESTER->num_iterations_); + TESTER->test_fwrite(TESTER->write_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->existing_file_.hermes_) == + TESTER->size_written_orig_ + offset); } SECTION("append to existing file") { - auto existing_size = stdfs::file_size(TEST_INFO->existing_file_.hermes_); - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "a+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - TEST_INFO->test_fwrite(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); - REQUIRE(stdfs::file_size(TEST_INFO->existing_file_.hermes_) == - existing_size + TEST_INFO->size_written_orig_); + auto existing_size = stdfs::file_size(TESTER->existing_file_.hermes_); + TESTER->test_fopen(TESTER->existing_file_, "a+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + TESTER->test_fwrite(TESTER->write_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->existing_file_.hermes_) == + existing_size + TESTER->size_written_orig_); } SECTION("append to new file") { - TEST_INFO->test_fopen(TEST_INFO->new_file_, "w+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - TEST_INFO->test_fwrite(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); - REQUIRE(stdfs::file_size(TEST_INFO->new_file_.hermes_) == TEST_INFO->size_written_orig_); + TESTER->test_fopen(TESTER->new_file_, "w+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + TESTER->test_fwrite(TESTER->write_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_) == + TESTER->size_written_orig_); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } -TEST_CASE("SingleRead", "[process=" + std::to_string(TEST_INFO->comm_size_) + +TEST_CASE("SingleRead", "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=single_read]" "[request_size=type-fixed][repetition=1]" "[file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from non-existing file") { - TEST_INFO->test_fopen(TEST_INFO->new_file_, "r"); - REQUIRE(TEST_INFO->fh_orig_ == nullptr); + TESTER->test_fopen(TESTER->new_file_, "r"); + REQUIRE(TESTER->fh_orig_ == nullptr); } SECTION("read from existing file") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "r"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - size_t offset = ftell(TEST_INFO->fh_orig_); + TESTER->test_fopen(TESTER->existing_file_, "r"); + REQUIRE(TESTER->fh_orig_ != nullptr); + size_t offset = ftell(TESTER->fh_orig_); REQUIRE(offset == 0); - TEST_INFO->test_fread(TEST_INFO->read_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fread(TESTER->read_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("read at the end of existing file") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "r"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - TEST_INFO->test_fseek(0, SEEK_END); - REQUIRE(TEST_INFO->status_orig_ == 0); - size_t offset = ftell(TEST_INFO->fh_orig_); - REQUIRE(offset == TEST_INFO->request_size_ * TEST_INFO->num_iterations_); - TEST_INFO->test_fread(TEST_INFO->read_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == 0); - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fopen(TESTER->existing_file_, "r"); + REQUIRE(TESTER->fh_orig_ != nullptr); + TESTER->test_fseek(0, SEEK_END); + REQUIRE(TESTER->status_orig_ == 0); + size_t offset = ftell(TESTER->fh_orig_); + REQUIRE(offset == TESTER->request_size_ * TESTER->num_iterations_); + TESTER->test_fread(TESTER->read_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedWriteSequential", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=type-fixed][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("write to new file always at beginning") { - TEST_INFO->test_fopen(TEST_INFO->new_file_, "w+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); + TESTER->test_fopen(TESTER->new_file_, "w+"); + REQUIRE(TESTER->fh_orig_ != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - TEST_INFO->test_fseek(0, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); - size_t offset = ftell(TEST_INFO->fh_orig_); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_fseek(0, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + size_t offset = ftell(TESTER->fh_orig_); REQUIRE(offset == 0); - TEST_INFO->test_fwrite(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); + TESTER->test_fwrite(TESTER->write_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); - REQUIRE(stdfs::file_size(TEST_INFO->new_file_.hermes_) == TEST_INFO->request_size_); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_) == + TESTER->request_size_); } SECTION("write to new file sequentially") { - TEST_INFO->test_fopen(TEST_INFO->new_file_, "w+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); + TESTER->test_fopen(TESTER->new_file_, "w+"); + REQUIRE(TESTER->fh_orig_ != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - TEST_INFO->test_fwrite(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_fwrite(TESTER->write_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); - REQUIRE(stdfs::file_size(TEST_INFO->new_file_.hermes_) == - TEST_INFO->num_iterations_ * TEST_INFO->request_size_); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_) == + TESTER->num_iterations_ * TESTER->request_size_); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadSequential", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=type-fixed][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "r+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - std::string data(TEST_INFO->request_size_, '1'); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - TEST_INFO->test_fread(data.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + std::string data(TESTER->request_size_, '1'); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_fread(data.data(), TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("read from existing file always at start") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "w+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); + TESTER->test_fopen(TESTER->existing_file_, "w+"); + REQUIRE(TESTER->fh_orig_ != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - TEST_INFO->test_fseek(0, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); - size_t offset = ftell(TEST_INFO->fh_orig_); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_fseek(0, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + size_t offset = ftell(TESTER->fh_orig_); REQUIRE(offset == 0); - TEST_INFO->test_fwrite(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); + TESTER->test_fwrite(TESTER->write_data_.data(), + TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } -TEST_CASE("BatchedReadRandom", "[process=" + std::to_string(TEST_INFO->comm_size_) + +TEST_CASE("BatchedReadRandom", "[process=" + + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=type-fixed]" "[repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "][pattern=random][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "r+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - std::string data(TEST_INFO->request_size_, '1'); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + std::string data(TESTER->request_size_, '1'); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { auto offset = - rand_r(&TEST_INFO->offset_seed_) % (TEST_INFO->total_size_ - TEST_INFO->request_size_); - TEST_INFO->test_fseek(offset, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_fread(data.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); + rand_r(&TESTER->offset_seed_) % + (TESTER->total_size_ - TESTER->request_size_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_fread(data.data(), TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } -TEST_CASE("BatchedUpdateRandom", "[process=" + std::to_string(TEST_INFO->comm_size_) + +TEST_CASE("BatchedUpdateRandom", "[process=" + + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_update]" "[request_size=type-fixed][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=random][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("update into existing file") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "r+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { auto offset = - rand_r(&TEST_INFO->offset_seed_) % (TEST_INFO->total_size_ - TEST_INFO->request_size_); - TEST_INFO->test_fseek(offset, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_fwrite(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); - fflush(TEST_INFO->fh_orig_); + rand_r(&TESTER->offset_seed_) % + (TESTER->total_size_ - TESTER->request_size_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_fwrite(TESTER->write_data_.data(), + TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); + fflush(TESTER->fh_orig_); } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadStrideFixed", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=type-fixed][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_fixed][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "r+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - std::string data(TEST_INFO->request_size_, '1'); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - auto offset = (i * TEST_INFO->stride_size_) % TEST_INFO->total_size_; - TEST_INFO->test_fseek(offset, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_fread(data.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + std::string data(TESTER->request_size_, '1'); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + auto offset = (i * TESTER->stride_size_) % TESTER->total_size_; + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_fread(data.data(), TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStrideFixed", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_update]" "[request_size=type-fixed][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_fixed][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("update from existing file") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "r+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - std::string data(TEST_INFO->request_size_, '1'); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - auto offset = (i * TEST_INFO->stride_size_) % TEST_INFO->total_size_; - TEST_INFO->test_fseek(offset, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_fread(data.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + std::string data(TESTER->request_size_, '1'); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + auto offset = (i * TESTER->stride_size_) % TESTER->total_size_; + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_fread(data.data(), TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadStrideDynamic", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=type-fixed][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_dynamic][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "r+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - std::string data(TEST_INFO->request_size_, '1'); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - auto offset = TEST_INFO->GetRandomOffset( - i, TEST_INFO->offset_seed_, TEST_INFO->stride_size_, - TEST_INFO->total_size_); - TEST_INFO->test_fseek(offset, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_fread(data.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + std::string data(TESTER->request_size_, '1'); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + auto offset = TESTER->GetRandomOffset( + i, TESTER->offset_seed_, TESTER->stride_size_, + TESTER->total_size_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_fread(data.data(), TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStrideDynamic", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_update]" "[request_size=type-fixed][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_dynamic][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("update from existing file") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "r+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - std::string data(TEST_INFO->request_size_, '1'); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - auto offset = TEST_INFO->GetRandomOffset(i, TEST_INFO->offset_seed_, TEST_INFO->stride_size_, - TEST_INFO->total_size_); - TEST_INFO->test_fseek(offset, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_fread(data.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + std::string data(TESTER->request_size_, '1'); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + auto offset = TESTER->GetRandomOffset(i, TESTER->offset_seed_, + TESTER->stride_size_, + TESTER->total_size_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_fread(data.data(), TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedWriteRSVariable", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=type-variable][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("write to new file always at the start") { - TEST_INFO->test_fopen(TEST_INFO->new_file_, "w+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); + TESTER->test_fopen(TESTER->new_file_, "w+"); + REQUIRE(TESTER->fh_orig_ != nullptr); size_t biggest_written = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - TEST_INFO->test_fseek(0, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); - size_t offset = ftell(TEST_INFO->fh_orig_); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_fseek(0, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + size_t offset = ftell(TESTER->fh_orig_); REQUIRE(offset == 0); size_t request_size = - TEST_INFO->request_size_ + (rand_r(&TEST_INFO->offset_seed_) % TEST_INFO->request_size_); + TESTER->request_size_ + + (rand_r(&TESTER->offset_seed_) % TESTER->request_size_); std::string data(request_size, '1'); - TEST_INFO->test_fwrite(data.c_str(), request_size); - REQUIRE(TEST_INFO->size_written_orig_ == request_size); + TESTER->test_fwrite(data.c_str(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); if (biggest_written < request_size) biggest_written = request_size; } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); - REQUIRE(stdfs::file_size(TEST_INFO->new_file_.hermes_) == biggest_written); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_) == biggest_written); } SECTION("write to new file") { - TEST_INFO->test_fopen(TEST_INFO->new_file_, "w+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); + TESTER->test_fopen(TESTER->new_file_, "w+"); + REQUIRE(TESTER->fh_orig_ != nullptr); size_t total_test_written = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t request_size = - TEST_INFO->request_size_ + (rand_r(&TEST_INFO->offset_seed_) % TEST_INFO->request_size_); + TESTER->request_size_ + + (rand_r(&TESTER->offset_seed_) % TESTER->request_size_); std::string data(request_size, '1'); - TEST_INFO->test_fwrite(data.c_str(), request_size); - REQUIRE(TEST_INFO->size_written_orig_ == request_size); - total_test_written += TEST_INFO->size_written_orig_; + TESTER->test_fwrite(data.c_str(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); + total_test_written += TESTER->size_written_orig_; } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); - REQUIRE(stdfs::file_size(TEST_INFO->new_file_.hermes_) == total_test_written); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_) == + total_test_written); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadSequentialRSVariable", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=type-variable][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "r"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - std::string data(TEST_INFO->request_size_, '1'); + TESTER->test_fopen(TESTER->existing_file_, "r"); + REQUIRE(TESTER->fh_orig_ != nullptr); + std::string data(TESTER->request_size_, '1'); size_t current_offset = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - size_t request_size = (TEST_INFO->request_size_ + - (rand_r(&TEST_INFO->offset_seed_) % TEST_INFO->request_size_)) % - (TEST_INFO->total_size_ - current_offset); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + size_t request_size = (TESTER->request_size_ + + (rand_r(&TESTER->offset_seed_) % TESTER->request_size_)) % + (TESTER->total_size_ - current_offset); std::string data(request_size, '1'); - TEST_INFO->test_fread(data.data(), request_size); - REQUIRE(TEST_INFO->size_read_orig_ == request_size); - current_offset += TEST_INFO->size_read_orig_; + TESTER->test_fread(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); + current_offset += TESTER->size_read_orig_; } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("read from existing file always at start") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "r"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); + TESTER->test_fopen(TESTER->existing_file_, "r"); + REQUIRE(TESTER->fh_orig_ != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - TEST_INFO->test_fseek(0, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); - size_t offset = ftell(TEST_INFO->fh_orig_); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_fseek(0, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + size_t offset = ftell(TESTER->fh_orig_); REQUIRE(offset == 0); size_t request_size = - TEST_INFO->request_size_ + (rand_r(&TEST_INFO->offset_seed_) % TEST_INFO->request_size_); + TESTER->request_size_ + + (rand_r(&TESTER->offset_seed_) % TESTER->request_size_); std::string data(request_size, '1'); - TEST_INFO->test_fread(data.data(), request_size); - REQUIRE(TEST_INFO->size_read_orig_ == request_size); + TESTER->test_fread(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadRandomRSVariable", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=type-variable]" "[repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "][pattern=random][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "r+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - std::string data(TEST_INFO->request_size_, '1'); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + std::string data(TESTER->request_size_, '1'); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { auto offset = - rand_r(&TEST_INFO->offset_seed_) % (TEST_INFO->total_size_ - TEST_INFO->request_size_); - TEST_INFO->test_fseek(offset, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); + rand_r(&TESTER->offset_seed_) % + (TESTER->total_size_ - TESTER->request_size_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - (TEST_INFO->request_size_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->request_size_)) % - (TEST_INFO->total_size_ - offset); + (TESTER->request_size_ + + (rand_r(&TESTER->rs_seed_) % TESTER->request_size_)) % + (TESTER->total_size_ - offset); std::string data(request_size, '1'); - TEST_INFO->test_fread(data.data(), request_size); - REQUIRE(TEST_INFO->size_read_orig_ == request_size); + TESTER->test_fread(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateRandomRSVariable", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_update]" "[request_size=type-variable][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=random][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "r+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - std::string data(TEST_INFO->request_size_, '1'); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + std::string data(TESTER->request_size_, '1'); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { auto offset = - rand_r(&TEST_INFO->offset_seed_) % (TEST_INFO->total_size_ - TEST_INFO->request_size_); - TEST_INFO->test_fseek(offset, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); + rand_r(&TESTER->offset_seed_) % + (TESTER->total_size_ - TESTER->request_size_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->request_size_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->request_size_); + TESTER->request_size_ + + (rand_r(&TESTER->rs_seed_) % TESTER->request_size_); std::string data(request_size, '1'); - TEST_INFO->test_fwrite(data.c_str(), request_size); - REQUIRE(TEST_INFO->size_written_orig_ == request_size); + TESTER->test_fwrite(data.c_str(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadStrideFixedRSVariable", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=type-variable][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_fixed][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "r+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - auto offset = (i * TEST_INFO->stride_size_) % TEST_INFO->total_size_; - TEST_INFO->test_fseek(offset, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + auto offset = (i * TESTER->stride_size_) % TESTER->total_size_; + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - (TEST_INFO->request_size_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->request_size_)) % - (TEST_INFO->total_size_ - offset); + (TESTER->request_size_ + + (rand_r(&TESTER->rs_seed_) % TESTER->request_size_)) % + (TESTER->total_size_ - offset); std::string data(request_size, '1'); - TEST_INFO->test_fread(data.data(), request_size); - REQUIRE(TEST_INFO->size_read_orig_ == request_size); + TESTER->test_fread(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStrideFixedRSVariable", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_update]" "[request_size=type-variable][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_fixed][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("write to existing file") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "r+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - std::string data(TEST_INFO->request_size_, '1'); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - auto offset = (i * TEST_INFO->stride_size_) % TEST_INFO->total_size_; - TEST_INFO->test_fseek(offset, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + std::string data(TESTER->request_size_, '1'); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + auto offset = (i * TESTER->stride_size_) % TESTER->total_size_; + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->request_size_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->request_size_); + TESTER->request_size_ + + (rand_r(&TESTER->rs_seed_) % TESTER->request_size_); std::string data(request_size, '1'); - TEST_INFO->test_fwrite(data.c_str(), request_size); - REQUIRE(TEST_INFO->size_written_orig_ == request_size); + TESTER->test_fwrite(data.c_str(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadStrideDynamicRSVariable", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=type-variable][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_dynamic][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "r+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - auto offset = TEST_INFO->GetRandomOffset(i, TEST_INFO->offset_seed_, TEST_INFO->stride_size_, - TEST_INFO->total_size_); - TEST_INFO->test_fseek(offset, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + auto offset = TESTER->GetRandomOffset(i, TESTER->offset_seed_, + TESTER->stride_size_, + TESTER->total_size_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->request_size_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->request_size_); + TESTER->request_size_ + + (rand_r(&TESTER->rs_seed_) % TESTER->request_size_); std::string data(request_size, '1'); - TEST_INFO->test_fread(data.data(), request_size); - REQUIRE(TEST_INFO->size_read_orig_ == request_size); + TESTER->test_fread(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStrideDynamicRSVariable", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_update]" "[request_size=type-variable][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_dynamic][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "r+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - auto offset = TEST_INFO->GetRandomOffset(i, TEST_INFO->offset_seed_, TEST_INFO->stride_size_, - TEST_INFO->total_size_); - TEST_INFO->test_fseek(offset, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + auto offset = TESTER->GetRandomOffset(i, TESTER->offset_seed_, + TESTER->stride_size_, + TESTER->total_size_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->request_size_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->request_size_); + TESTER->request_size_ + + (rand_r(&TESTER->rs_seed_) % TESTER->request_size_); std::string data(request_size, '1'); - TEST_INFO->test_fwrite(data.c_str(), request_size); - REQUIRE(TEST_INFO->size_written_orig_ == request_size); + TESTER->test_fwrite(data.c_str(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadStrideNegative", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=type-fixed][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_negative][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "r+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - std::string data(TEST_INFO->request_size_, '1'); - size_t prev_offset = TEST_INFO->total_size_ + 1; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - auto stride_offset = TEST_INFO->total_size_ - i * TEST_INFO->stride_size_; + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + std::string data(TESTER->request_size_, '1'); + size_t prev_offset = TESTER->total_size_ + 1; + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + auto stride_offset = TESTER->total_size_ - i * TESTER->stride_size_; REQUIRE(prev_offset > stride_offset); prev_offset = stride_offset; - auto offset = (stride_offset) % (TEST_INFO->total_size_ - TEST_INFO->request_size_); - TEST_INFO->test_fseek(offset, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_fread(data.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); + auto offset = (stride_offset) % + (TESTER->total_size_ - TESTER->request_size_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_fread(data.data(), TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStrideNegative", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_update]" "[request_size=type-fixed][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_negative][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "r+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - std::string data(TEST_INFO->request_size_, '1'); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + std::string data(TESTER->request_size_, '1'); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { auto offset = - TEST_INFO->total_size_ - TEST_INFO->request_size_ - - ((i * TEST_INFO->stride_size_) % TEST_INFO->total_size_); - TEST_INFO->test_fseek(offset, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_fread(data.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); + TESTER->total_size_ - TESTER->request_size_ - + ((i * TESTER->stride_size_) % TESTER->total_size_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_fread(data.data(), TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadStrideNegativeRSVariable", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=type-variable][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_negative][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "r+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - auto offset = (TEST_INFO->total_size_ - i * TEST_INFO->stride_size_) % - (TEST_INFO->total_size_ - 2 * TEST_INFO->request_size_); - TEST_INFO->test_fseek(offset, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + auto offset = (TESTER->total_size_ - i * TESTER->stride_size_) % + (TESTER->total_size_ - 2 * TESTER->request_size_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - (TEST_INFO->request_size_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->request_size_)) % - (TEST_INFO->total_size_ - offset); + (TESTER->request_size_ + (rand_r(&TESTER->rs_seed_) % + TESTER->request_size_)) % + (TESTER->total_size_ - offset); std::string data(request_size, '1'); - TEST_INFO->test_fread(data.data(), request_size); - REQUIRE(TEST_INFO->size_read_orig_ == request_size); + TESTER->test_fread(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStrideNegativeRSVariable", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_update]" "[request_size=type-variable][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_negative][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("write to existing file") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "r+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - std::string data(TEST_INFO->request_size_, '1'); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + std::string data(TESTER->request_size_, '1'); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { auto offset = - TEST_INFO->total_size_ - ((i * TEST_INFO->stride_size_) % TEST_INFO->total_size_); - TEST_INFO->test_fseek(offset, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->total_size_ - ((i * TESTER->stride_size_) % + TESTER->total_size_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->request_size_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->request_size_); + TESTER->request_size_ + (rand_r(&TESTER->rs_seed_) % + TESTER->request_size_); std::string data(request_size, '1'); - TEST_INFO->test_fwrite(data.c_str(), request_size); - REQUIRE(TEST_INFO->size_written_orig_ == request_size); + TESTER->test_fwrite(data.c_str(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } -TEST_CASE("BatchedReadStride2D", "[process=" + std::to_string(TEST_INFO->comm_size_) + +TEST_CASE("BatchedReadStride2D", "[process=" + + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=type-fixed][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_2d][file=1]") { - TEST_INFO->Pretest(); - size_t rows = sqrt(TEST_INFO->total_size_); + TESTER->Pretest(); + size_t rows = sqrt(TESTER->total_size_); size_t cols = rows; - REQUIRE(rows * cols == TEST_INFO->total_size_); + REQUIRE(rows * cols == TESTER->total_size_); size_t cell_size = 128; - size_t cell_stride = rows * cols / cell_size / TEST_INFO->num_iterations_; + size_t cell_stride = rows * cols / cell_size / TESTER->num_iterations_; SECTION("read from existing file") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "r+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - std::string data(TEST_INFO->request_size_, '1'); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + std::string data(TESTER->request_size_, '1'); size_t prev_cell_col = 0, prev_cell_row = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t current_cell_col = (prev_cell_col + cell_stride) % cols; size_t current_cell_row = prev_cell_col + cell_stride > cols ? prev_cell_row + 1 : prev_cell_row; prev_cell_row = current_cell_row; auto offset = (current_cell_col * cell_stride + prev_cell_row * cols) % - (TEST_INFO->total_size_ - TEST_INFO->request_size_); - TEST_INFO->test_fseek(offset, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_fread(data.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); + (TESTER->total_size_ - TESTER->request_size_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_fread(data.data(), TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStride2D", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_update]" "[request_size=type-fixed][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_2d][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); - size_t rows = sqrt(TEST_INFO->total_size_); + size_t rows = sqrt(TESTER->total_size_); size_t cols = rows; - REQUIRE(rows * cols == TEST_INFO->total_size_); + REQUIRE(rows * cols == TESTER->total_size_); size_t cell_size = 128; - size_t cell_stride = rows * cols / cell_size / TEST_INFO->num_iterations_; + size_t cell_stride = rows * cols / cell_size / TESTER->num_iterations_; SECTION("read from existing file") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "r+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - std::string data(TEST_INFO->request_size_, '1'); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + std::string data(TESTER->request_size_, '1'); size_t prev_cell_col = 0, prev_cell_row = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t current_cell_col = (prev_cell_col + cell_stride) % cols; size_t current_cell_row = prev_cell_col + cell_stride > cols ? prev_cell_row + 1 : prev_cell_row; prev_cell_row = current_cell_row; auto offset = (current_cell_col * cell_stride + prev_cell_row * cols) % - (TEST_INFO->total_size_ - TEST_INFO->request_size_); - TEST_INFO->test_fseek(offset, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_fread(data.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); + (TESTER->total_size_ - TESTER->request_size_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_fread(data.data(), TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadStride2DRSVariable", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "" "[operation=batched_read]" "[request_size=type-variable][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_2d][file=1]") { - TEST_INFO->Pretest(); - size_t rows = sqrt(TEST_INFO->total_size_); + TESTER->Pretest(); + size_t rows = sqrt(TESTER->total_size_); size_t cols = rows; - REQUIRE(rows * cols == TEST_INFO->total_size_); + REQUIRE(rows * cols == TESTER->total_size_); size_t cell_size = 128; - size_t cell_stride = rows * cols / cell_size / TEST_INFO->num_iterations_; + size_t cell_stride = rows * cols / cell_size / TESTER->num_iterations_; SECTION("read from existing file") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "r+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); size_t prev_cell_col = 0, prev_cell_row = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t current_cell_col = (prev_cell_col + cell_stride) % cols; size_t current_cell_row = prev_cell_col + cell_stride > cols ? prev_cell_row + 1 : prev_cell_row; prev_cell_row = current_cell_row; auto offset = (current_cell_col * cell_stride + prev_cell_row * cols) % - (TEST_INFO->total_size_ - 2 * TEST_INFO->request_size_); - TEST_INFO->test_fseek(offset, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); + (TESTER->total_size_ - 2 * TESTER->request_size_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - (TEST_INFO->request_size_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->request_size_)) % - (TEST_INFO->total_size_ - offset); + (TESTER->request_size_ + (rand_r(&TESTER->rs_seed_) % + TESTER->request_size_)) % + (TESTER->total_size_ - offset); std::string data(request_size, '1'); - TEST_INFO->test_fread(data.data(), request_size); - REQUIRE(TEST_INFO->size_read_orig_ == request_size); + TESTER->test_fread(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStride2DRSVariable", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_update]" "[request_size=type-variable][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_2d][file=1]") { - TEST_INFO->Pretest(); - size_t rows = sqrt(TEST_INFO->total_size_); + TESTER->Pretest(); + size_t rows = sqrt(TESTER->total_size_); size_t cols = rows; - REQUIRE(rows * cols == TEST_INFO->total_size_); + REQUIRE(rows * cols == TESTER->total_size_); size_t cell_size = 128; - size_t cell_stride = rows * cols / cell_size / TEST_INFO->num_iterations_; + size_t cell_stride = rows * cols / cell_size / TESTER->num_iterations_; SECTION("write to existing file") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "r+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - std::string data(TEST_INFO->request_size_, '1'); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + std::string data(TESTER->request_size_, '1'); size_t prev_cell_col = 0, prev_cell_row = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t current_cell_col = (prev_cell_col + cell_stride) % cols; size_t current_cell_row = prev_cell_col + cell_stride > cols ? prev_cell_row + 1 : prev_cell_row; prev_cell_row = current_cell_row; auto offset = (current_cell_col * cell_stride + prev_cell_row * cols) % - (TEST_INFO->total_size_ - 2 * TEST_INFO->request_size_); - TEST_INFO->test_fseek(offset, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); + (TESTER->total_size_ - 2 * TESTER->request_size_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->request_size_ + (rand_r(&TEST_INFO->rs_seed_) % TEST_INFO->request_size_); + TESTER->request_size_ + (rand_r(&TESTER->rs_seed_) % + TESTER->request_size_); std::string data(request_size, '1'); - TEST_INFO->test_fwrite(data.c_str(), request_size); - REQUIRE(TEST_INFO->size_written_orig_ == request_size); + TESTER->test_fwrite(data.c_str(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } /** @@ -985,329 +1017,361 @@ TEST_CASE("BatchedUpdateStride2DRSVariable", */ TEST_CASE("BatchedWriteTemporalFixed", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=type-fixed][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1][temporal=fixed]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); - SECTION("write to existing file") { - TEST_INFO->test_fopen(TEST_INFO->new_file_, "w+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - usleep(TEST_INFO->temporal_interval_ms_ * 1000); - TEST_INFO->test_fseek(0, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); - size_t offset = ftell(TEST_INFO->fh_orig_); + SECTION("write to existing file always at start") { + TESTER->test_fopen(TESTER->existing_file_, "w+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + usleep(TESTER->temporal_interval_ms_ * 1000); + TESTER->test_fseek(0, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + size_t offset = ftell(TESTER->fh_orig_); REQUIRE(offset == 0); - TEST_INFO->test_fwrite(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); + TESTER->test_fwrite(TESTER->write_data_.data(), + TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); - REQUIRE(stdfs::file_size(TEST_INFO->new_file_.hermes_) == TEST_INFO->request_size_); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->existing_file_.hermes_) == + TESTER->request_size_); } SECTION("write to new file always at start") { - TEST_INFO->test_fopen(TEST_INFO->new_file_, "w+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - usleep(TEST_INFO->temporal_interval_ms_ * 1000); - TEST_INFO->test_fwrite(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); + TESTER->test_fopen(TESTER->new_file_, "w+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + usleep(TESTER->temporal_interval_ms_ * 1000); + TESTER->test_fseek(0, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + size_t offset = ftell(TESTER->fh_orig_); + REQUIRE(offset == 0); + TESTER->test_fwrite(TESTER->write_data_.data(), + TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); - REQUIRE(stdfs::file_size(TEST_INFO->new_file_.hermes_) == - TEST_INFO->num_iterations_ * TEST_INFO->request_size_); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_) == + TESTER->request_size_); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadSequentialTemporalFixed", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=type-fixed][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1][temporal=fixed]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "r+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - std::string data(TEST_INFO->request_size_, '1'); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - usleep(TEST_INFO->temporal_interval_ms_ * 1000); - TEST_INFO->test_fread(data.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + std::string data(TESTER->request_size_, '1'); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + usleep(TESTER->temporal_interval_ms_ * 1000); + TESTER->test_fread(data.data(), TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("read from existing file always at start") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "w+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - usleep(TEST_INFO->temporal_interval_ms_ * 1000); - TEST_INFO->test_fseek(0, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); - size_t offset = ftell(TEST_INFO->fh_orig_); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + usleep(TESTER->temporal_interval_ms_ * 1000); + TESTER->test_fseek(0, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + size_t offset = ftell(TESTER->fh_orig_); REQUIRE(offset == 0); - TEST_INFO->test_fwrite(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); + TESTER->test_fread(TESTER->read_data_.data(), + TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedWriteTemporalVariable", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=type-fixed][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1][temporal=variable]") { - TEST_INFO->Pretest(); - - SECTION("write to existing file") { - TEST_INFO->test_fopen(TEST_INFO->new_file_, "w+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - TEST_INFO->temporal_interval_ms_ = - rand_r(&TEST_INFO->temporal_interval_seed_) % TEST_INFO->temporal_interval_ms_ + 1; - usleep(TEST_INFO->temporal_interval_ms_ * 1000); - TEST_INFO->test_fseek(0, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); - size_t offset = ftell(TEST_INFO->fh_orig_); + TESTER->Pretest(); + + SECTION("write to existing file always at start") { + TESTER->test_fopen(TESTER->existing_file_, "w+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->temporal_interval_ms_ = + rand_r(&TESTER->temporal_interval_seed_) % + TESTER->temporal_interval_ms_ + 1; + usleep(TESTER->temporal_interval_ms_ * 1000); + TESTER->test_fseek(0, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + size_t offset = ftell(TESTER->fh_orig_); REQUIRE(offset == 0); - TEST_INFO->test_fwrite(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); + TESTER->test_fwrite(TESTER->write_data_.data(), + TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); - REQUIRE(stdfs::file_size(TEST_INFO->new_file_.hermes_) == TEST_INFO->request_size_); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->existing_file_.hermes_) == + TESTER->request_size_); } - SECTION("write to new file always at start") { - TEST_INFO->test_fopen(TEST_INFO->new_file_, "w+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - TEST_INFO->temporal_interval_ms_ = - rand_r(&TEST_INFO->temporal_interval_seed_) % TEST_INFO->temporal_interval_ms_ + 1; - usleep(TEST_INFO->temporal_interval_ms_ * 1000); - TEST_INFO->test_fwrite(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); + SECTION("write to new file") { + TESTER->test_fopen(TESTER->new_file_, "w+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->temporal_interval_ms_ = + rand_r(&TESTER->temporal_interval_seed_) % + TESTER->temporal_interval_ms_ + 1; + usleep(TESTER->temporal_interval_ms_ * 1000); + TESTER->test_fwrite(TESTER->write_data_.data(), + TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); - REQUIRE(stdfs::file_size(TEST_INFO->new_file_.hermes_) == - TEST_INFO->num_iterations_ * TEST_INFO->request_size_); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_) == + TESTER->num_iterations_ * TESTER->request_size_); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadSequentialTemporalVariable", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=type-fixed][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1][temporal=variable]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "r+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - std::string data(TEST_INFO->request_size_, '1'); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - TEST_INFO->temporal_interval_ms_ = - rand_r(&TEST_INFO->temporal_interval_seed_) % TEST_INFO->temporal_interval_ms_ + 1; - usleep(TEST_INFO->temporal_interval_ms_ * 1000); - TEST_INFO->test_fread(data.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + std::string data(TESTER->request_size_, '1'); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->temporal_interval_ms_ = + rand_r(&TESTER->temporal_interval_seed_) % + TESTER->temporal_interval_ms_ + 1; + usleep(TESTER->temporal_interval_ms_ * 1000); + TESTER->test_fread(data.data(), TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("read from existing file always at start") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "w+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - TEST_INFO->temporal_interval_ms_ = - rand_r(&TEST_INFO->temporal_interval_seed_) % TEST_INFO->temporal_interval_ms_ + 1; - usleep(TEST_INFO->temporal_interval_ms_ * 1000); - TEST_INFO->test_fseek(0, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); - size_t offset = ftell(TEST_INFO->fh_orig_); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->temporal_interval_ms_ = + rand_r(&TESTER->temporal_interval_seed_) % + TESTER->temporal_interval_ms_ + 1; + usleep(TESTER->temporal_interval_ms_ * 1000); + TESTER->test_fseek(0, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + size_t offset = ftell(TESTER->fh_orig_); REQUIRE(offset == 0); - TEST_INFO->test_fwrite(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); + TESTER->test_fread(TESTER->read_data_.data(), + TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedMixedSequential", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_mixed]" "[request_size=type-fixed][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read after write on new file") { - TEST_INFO->test_fopen(TEST_INFO->new_file_, "w+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); + TESTER->test_fopen(TESTER->new_file_, "w+"); + REQUIRE(TESTER->fh_orig_ != nullptr); size_t last_offset = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - TEST_INFO->test_fwrite(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); - TEST_INFO->test_fseek(last_offset, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_fread(TEST_INFO->read_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); - last_offset += TEST_INFO->request_size_; + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_fwrite(TESTER->write_data_.data(), + TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_fseek(last_offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_fread(TESTER->read_data_.data(), + TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); + last_offset += TESTER->request_size_; } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("write and read alternative existing file") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "r+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { if (i % 2 == 0) { - TEST_INFO->test_fwrite(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); + TESTER->test_fwrite(TESTER->write_data_.data(), + TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); } else { - TEST_INFO->test_fread(TEST_INFO->read_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); + TESTER->test_fread(TESTER->read_data_.data(), + TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); } } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("update after read existing file") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "r+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); size_t last_offset = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - TEST_INFO->test_fread(TEST_INFO->read_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); - TEST_INFO->test_fseek(last_offset, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_fwrite(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); - last_offset += TEST_INFO->request_size_; + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_fread(TESTER->read_data_.data(), + TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); + TESTER->test_fseek(last_offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_fwrite(TESTER->write_data_.data(), + TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); + last_offset += TESTER->request_size_; } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("read all after write all on new file in single open") { - TEST_INFO->test_fopen(TEST_INFO->new_file_, "w+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - TEST_INFO->test_fwrite(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); + TESTER->test_fopen(TESTER->new_file_, "w+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_fwrite(TESTER->write_data_.data(), + TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); } - TEST_INFO->test_fseek(0, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - TEST_INFO->test_fread(TEST_INFO->read_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); + TESTER->test_fseek(0, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_fread(TESTER->read_data_.data(), + TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("read all after write all on new file in different open") { - TEST_INFO->test_fopen(TEST_INFO->new_file_, "w+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - TEST_INFO->test_fwrite(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); + TESTER->test_fopen(TESTER->new_file_, "w+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_fwrite(TESTER->write_data_.data(), + TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_fopen(TEST_INFO->new_file_, "r"); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - TEST_INFO->test_fread(TEST_INFO->read_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_fopen(TESTER->new_file_, "r"); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_fread(TESTER->read_data_.data(), + TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); } - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } -TEST_CASE("SingleMixed", "[process=" + std::to_string(TEST_INFO->comm_size_) + +TEST_CASE("SingleMixed", "[process=" + std::to_string(TESTER->comm_size_) + "][operation=single_mixed]" "[request_size=type-fixed][repetition=1]" "[file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read after write from new file") { - TEST_INFO->test_fopen(TEST_INFO->new_file_, "w+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - size_t offset = ftell(TEST_INFO->fh_orig_); + TESTER->test_fopen(TESTER->new_file_, "w+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + size_t offset = ftell(TESTER->fh_orig_); REQUIRE(offset == 0); - TEST_INFO->test_fwrite(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); - TEST_INFO->test_fseek(0, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_fread(TEST_INFO->read_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fwrite(TESTER->write_data_.data(), + TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_fseek(0, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_fread(TESTER->read_data_.data(), + TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("update after read from existing file") { - TEST_INFO->test_fopen(TEST_INFO->existing_file_, "r+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - size_t offset = ftell(TEST_INFO->fh_orig_); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + size_t offset = ftell(TESTER->fh_orig_); REQUIRE(offset == 0); - TEST_INFO->test_fread(TEST_INFO->read_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); - TEST_INFO->test_fseek(0, SEEK_SET); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_fwrite(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); - - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fread(TESTER->read_data_.data(), + TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); + TESTER->test_fseek(0, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_fwrite(TESTER->write_data_.data(), + TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); + + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("read after write from new file different opens") { - TEST_INFO->test_fopen(TEST_INFO->new_file_, "w+"); - REQUIRE(TEST_INFO->fh_orig_ != nullptr); - size_t offset = ftell(TEST_INFO->fh_orig_); + TESTER->test_fopen(TESTER->new_file_, "w+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + size_t offset = ftell(TESTER->fh_orig_); REQUIRE(offset == 0); - TEST_INFO->test_fwrite(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_written_orig_ == TEST_INFO->request_size_); - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); - TEST_INFO->test_fopen(TEST_INFO->new_file_, "r+"); - TEST_INFO->test_fread(TEST_INFO->read_data_.data(), TEST_INFO->request_size_); - REQUIRE(TEST_INFO->size_read_orig_ == TEST_INFO->request_size_); - TEST_INFO->test_fclose(); - REQUIRE(TEST_INFO->status_orig_ == 0); + TESTER->test_fwrite(TESTER->write_data_.data(), + TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); + TESTER->test_fopen(TESTER->new_file_, "r+"); + TESTER->test_fread(TESTER->read_data_.data(), + TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - TEST_INFO->Posttest(); + TESTER->Posttest(); } diff --git a/test/unit/hermes_adapters/stdio/stdio_adapter_func_test.cc b/test/unit/hermes_adapters/stdio/stdio_adapter_func_test.cc index cbe03fa53..597dcf244 100644 --- a/test/unit/hermes_adapters/stdio/stdio_adapter_func_test.cc +++ b/test/unit/hermes_adapters/stdio/stdio_adapter_func_test.cc @@ -12,48 +12,48 @@ #include "stdio_adapter_test.h" -TEST_CASE("FFlush", "[process=" + std::to_string(TEST_INFO->comm_size_) + - "]" - "[operation=single_fflush]" - "[repetition=1][file=1]") { - TEST_INFO->Pretest(); +TEST_CASE("FFlush", "[process=" + std::to_string(TESTER->comm_size_) + + "]" + "[operation=single_fflush]" + "[repetition=1][file=1]") { + TESTER->Pretest(); SECTION("Flushing contents of file in different modes") { - FILE* fd = fopen(TEST_INFO->existing_file_.hermes_.c_str(), "w"); + FILE* fd = fopen(TESTER->existing_file_.hermes_.c_str(), "w"); REQUIRE(fd != nullptr); int status = fflush(fd); REQUIRE(status == 0); status = fclose(fd); REQUIRE(status == 0); - fd = fopen(TEST_INFO->existing_file_.hermes_.c_str(), "w+"); + fd = fopen(TESTER->existing_file_.hermes_.c_str(), "w+"); REQUIRE(fd != nullptr); status = fflush(fd); REQUIRE(status == 0); status = fclose(fd); REQUIRE(status == 0); - fd = fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r+"); + fd = fopen(TESTER->existing_file_.hermes_.c_str(), "r+"); REQUIRE(fd != nullptr); status = fflush(fd); REQUIRE(status == 0); status = fclose(fd); REQUIRE(status == 0); - fd = fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r"); + fd = fopen(TESTER->existing_file_.hermes_.c_str(), "r"); REQUIRE(fd != nullptr); status = fflush(fd); REQUIRE(status == 0); status = fclose(fd); REQUIRE(status == 0); - fd = fopen(TEST_INFO->existing_file_.hermes_.c_str(), "a"); + fd = fopen(TESTER->existing_file_.hermes_.c_str(), "a"); REQUIRE(fd != nullptr); status = fflush(fd); REQUIRE(status == 0); status = fclose(fd); REQUIRE(status == 0); - fd = fopen(TEST_INFO->existing_file_.hermes_.c_str(), "a+"); + fd = fopen(TESTER->existing_file_.hermes_.c_str(), "a+"); REQUIRE(fd != nullptr); status = fflush(fd); REQUIRE(status == 0); @@ -64,23 +64,24 @@ TEST_CASE("FFlush", "[process=" + std::to_string(TEST_INFO->comm_size_) + int status = fflush(nullptr); REQUIRE(status == 0); } - TEST_INFO->Posttest(false); + TESTER->Posttest(false); } -TEST_CASE("Fdopen", "[process=" + std::to_string(TEST_INFO->comm_size_) + - "]" - "[operation=single_fdopen]" - "[repetition=1][file=1]") { - TEST_INFO->Pretest(); +TEST_CASE("Fdopen", "[process=" + std::to_string(TESTER->comm_size_) + + "]" + "[operation=single_fdopen]" + "[repetition=1][file=1]") { + TESTER->Pretest(); SECTION("Associate a FILE ptr with read mode") { - int fd = open(TEST_INFO->existing_file_.hermes_.c_str(), O_RDWR); + int fd = open(TESTER->existing_file_.hermes_.c_str(), O_RDWR); REQUIRE(fd != -1); FILE* fh = fdopen(fd, "r"); REQUIRE(fh != nullptr); size_t read_size = - fread(TEST_INFO->read_data_.data(), sizeof(char), TEST_INFO->request_size_, fh); - REQUIRE(read_size == TEST_INFO->request_size_); + fread(TESTER->read_data_.data(), + sizeof(char), TESTER->request_size_, fh); + REQUIRE(read_size == TESTER->request_size_); int status = fclose(fh); REQUIRE(status == 0); @@ -91,14 +92,15 @@ TEST_CASE("Fdopen", "[process=" + std::to_string(TEST_INFO->comm_size_) + REQUIRE(status == -1); } SECTION("Associate a FILE ptr with write mode") { - int fd = open(TEST_INFO->existing_file_.hermes_.c_str(), O_RDWR); + int fd = open(TESTER->existing_file_.hermes_.c_str(), O_RDWR); REQUIRE(fd != -1); FILE* fh = fdopen(fd, "w"); REQUIRE(fh != nullptr); size_t write_size = - fwrite(TEST_INFO->write_data_.data(), sizeof(char), TEST_INFO->request_size_, fh); - REQUIRE(write_size == TEST_INFO->request_size_); + fwrite(TESTER->write_data_.data(), + sizeof(char), TESTER->request_size_, fh); + REQUIRE(write_size == TESTER->request_size_); int status = fclose(fh); REQUIRE(status == 0); @@ -106,14 +108,15 @@ TEST_CASE("Fdopen", "[process=" + std::to_string(TEST_INFO->comm_size_) + REQUIRE(status == -1); } SECTION("Associate a FILE ptr with read plus mode") { - int fd = open(TEST_INFO->existing_file_.hermes_.c_str(), O_RDWR); + int fd = open(TESTER->existing_file_.hermes_.c_str(), O_RDWR); REQUIRE(fd != -1); FILE* fh = fdopen(fd, "r"); REQUIRE(fh != nullptr); size_t read_size = - fread(TEST_INFO->read_data_.data(), sizeof(char), TEST_INFO->request_size_, fh); - REQUIRE(read_size == TEST_INFO->request_size_); + fread(TESTER->read_data_.data(), + sizeof(char), TESTER->request_size_, fh); + REQUIRE(read_size == TESTER->request_size_); int status = fclose(fh); REQUIRE(status == 0); @@ -124,14 +127,15 @@ TEST_CASE("Fdopen", "[process=" + std::to_string(TEST_INFO->comm_size_) + REQUIRE(status == -1); } SECTION("Associate a FILE ptr with write plus mode") { - int fd = open(TEST_INFO->existing_file_.hermes_.c_str(), O_RDWR); + int fd = open(TESTER->existing_file_.hermes_.c_str(), O_RDWR); REQUIRE(fd != -1); FILE* fh = fdopen(fd, "w+"); REQUIRE(fh != nullptr); size_t write_size = - fwrite(TEST_INFO->write_data_.data(), sizeof(char), TEST_INFO->request_size_, fh); - REQUIRE(write_size == TEST_INFO->request_size_); + fwrite(TESTER->write_data_.data(), + sizeof(char), TESTER->request_size_, fh); + REQUIRE(write_size == TESTER->request_size_); int status = fclose(fh); REQUIRE(status == 0); @@ -142,14 +146,15 @@ TEST_CASE("Fdopen", "[process=" + std::to_string(TEST_INFO->comm_size_) + REQUIRE(status == -1); } SECTION("Associate a FILE ptr with append mode") { - int fd = open(TEST_INFO->existing_file_.hermes_.c_str(), O_RDWR | O_APPEND); + int fd = open(TESTER->existing_file_.hermes_.c_str(), O_RDWR | O_APPEND); REQUIRE(fd != -1); FILE* fh = fdopen(fd, "a"); REQUIRE(fh != nullptr); size_t write_size = - fwrite(TEST_INFO->write_data_.data(), sizeof(char), TEST_INFO->request_size_, fh); - REQUIRE(write_size == TEST_INFO->request_size_); + fwrite(TESTER->write_data_.data(), + sizeof(char), TESTER->request_size_, fh); + REQUIRE(write_size == TESTER->request_size_); int status = fclose(fh); REQUIRE(status == 0); @@ -160,14 +165,15 @@ TEST_CASE("Fdopen", "[process=" + std::to_string(TEST_INFO->comm_size_) + REQUIRE(status == -1); } SECTION("Associate a FILE ptr with append plus mode") { - int fd = open(TEST_INFO->existing_file_.hermes_.c_str(), O_RDWR | O_APPEND); + int fd = open(TESTER->existing_file_.hermes_.c_str(), O_RDWR | O_APPEND); REQUIRE(fd != -1); FILE* fh = fdopen(fd, "a+"); REQUIRE(fh != nullptr); size_t write_size = - fwrite(TEST_INFO->write_data_.data(), sizeof(char), TEST_INFO->request_size_, fh); - REQUIRE(write_size == TEST_INFO->request_size_); + fwrite(TESTER->write_data_.data(), + sizeof(char), TESTER->request_size_, fh); + REQUIRE(write_size == TESTER->request_size_); int status = fclose(fh); REQUIRE(status == 0); @@ -178,14 +184,15 @@ TEST_CASE("Fdopen", "[process=" + std::to_string(TEST_INFO->comm_size_) + REQUIRE(status == -1); } SECTION("Associate a FILE ptr with read mode twice") { - int fd = open(TEST_INFO->existing_file_.hermes_.c_str(), O_RDWR); + int fd = open(TESTER->existing_file_.hermes_.c_str(), O_RDWR); REQUIRE(fd != -1); FILE* fh = fdopen(fd, "r"); REQUIRE(fh != nullptr); size_t read_size = - fread(TEST_INFO->read_data_.data(), sizeof(char), TEST_INFO->request_size_, fh); - REQUIRE(read_size == TEST_INFO->request_size_); + fread(TESTER->read_data_.data(), + sizeof(char), TESTER->request_size_, fh); + REQUIRE(read_size == TESTER->request_size_); int status = fclose(fh); REQUIRE(status == 0); @@ -194,14 +201,15 @@ TEST_CASE("Fdopen", "[process=" + std::to_string(TEST_INFO->comm_size_) + REQUIRE(status == -1); } SECTION("Associate a FILE ptr with read mode twice after one closes") { - int fd = open(TEST_INFO->existing_file_.hermes_.c_str(), O_RDWR); + int fd = open(TESTER->existing_file_.hermes_.c_str(), O_RDWR); REQUIRE(fd != -1); FILE* fh = fdopen(fd, "r"); REQUIRE(fh != nullptr); size_t read_size = - fread(TEST_INFO->read_data_.data(), sizeof(char), TEST_INFO->request_size_, fh); - REQUIRE(read_size == TEST_INFO->request_size_); + fread(TESTER->read_data_.data(), + sizeof(char), TESTER->request_size_, fh); + REQUIRE(read_size == TESTER->request_size_); int status = fcntl(fd, F_GETFD); REQUIRE(fd != -1); @@ -215,144 +223,148 @@ TEST_CASE("Fdopen", "[process=" + std::to_string(TEST_INFO->comm_size_) + status = close(fd); REQUIRE(status == -1); } - TEST_INFO->Posttest(false); + TESTER->Posttest(false); } -TEST_CASE("Freopen", "[process=" + std::to_string(TEST_INFO->comm_size_) + - "]" - "[operation=single_freopen]" - "[repetition=1][file=1]") { - TEST_INFO->Pretest(); +TEST_CASE("Freopen", "[process=" + std::to_string(TESTER->comm_size_) + + "]" + "[operation=single_freopen]" + "[repetition=1][file=1]") { + TESTER->Pretest(); SECTION("change different modes") { - FILE* fhr = fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r"); + FILE* fhr = fopen(TESTER->existing_file_.hermes_.c_str(), "r"); REQUIRE(fhr != nullptr); - FILE* fhw = freopen(TEST_INFO->existing_file_.hermes_.c_str(), "w", fhr); + FILE* fhw = freopen(TESTER->existing_file_.hermes_.c_str(), "w", fhr); REQUIRE(fhw != nullptr); size_t write_size = - fwrite(TEST_INFO->write_data_.data(), sizeof(char), TEST_INFO->request_size_, fhw); - REQUIRE(write_size == TEST_INFO->request_size_); + fwrite(TESTER->write_data_.data(), + sizeof(char), TESTER->request_size_, fhw); + REQUIRE(write_size == TESTER->request_size_); - FILE* fhwp = freopen(TEST_INFO->existing_file_.hermes_.c_str(), "w+", fhw); + FILE* fhwp = freopen(TESTER->existing_file_.hermes_.c_str(), "w+", fhw); REQUIRE(fhwp != nullptr); write_size = - fwrite(TEST_INFO->write_data_.data(), sizeof(char), TEST_INFO->request_size_, fhwp); - REQUIRE(write_size == TEST_INFO->request_size_); + fwrite(TESTER->write_data_.data(), + sizeof(char), TESTER->request_size_, fhwp); + REQUIRE(write_size == TESTER->request_size_); - FILE* fha = freopen(TEST_INFO->existing_file_.hermes_.c_str(), "a", fhwp); + FILE* fha = freopen(TESTER->existing_file_.hermes_.c_str(), "a", fhwp); REQUIRE(fha != nullptr); write_size = - fwrite(TEST_INFO->write_data_.data(), sizeof(char), TEST_INFO->request_size_, fhwp); - REQUIRE(write_size == TEST_INFO->request_size_); + fwrite(TESTER->write_data_.data(), + sizeof(char), TESTER->request_size_, fhwp); + REQUIRE(write_size == TESTER->request_size_); - FILE* fhap = freopen(TEST_INFO->existing_file_.hermes_.c_str(), "a+", fha); + FILE* fhap = freopen(TESTER->existing_file_.hermes_.c_str(), "a+", fha); REQUIRE(fhap != nullptr); write_size = - fwrite(TEST_INFO->write_data_.data(), sizeof(char), TEST_INFO->request_size_, fhap); - REQUIRE(write_size == TEST_INFO->request_size_); + fwrite(TESTER->write_data_.data(), + sizeof(char), TESTER->request_size_, fhap); + REQUIRE(write_size == TESTER->request_size_); int status = fclose(fhap); REQUIRE(status == 0); } - TEST_INFO->Posttest(false); + TESTER->Posttest(false); } -TEST_CASE("fgetc", "[process=" + std::to_string(TEST_INFO->comm_size_) + - "]" - "[operation=batched_fgetc]" - "[repetition=" + - std::to_string(TEST_INFO->num_iterations_) + "][file=1]") { - TEST_INFO->Pretest(); +TEST_CASE("fgetc", "[process=" + std::to_string(TESTER->comm_size_) + + "]" + "[operation=batched_fgetc]" + "[repetition=" + + std::to_string(TESTER->num_iterations_) + "][file=1]") { + TESTER->Pretest(); SECTION("iterate and get all characters") { - FILE* fh = fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r"); + FILE* fh = fopen(TESTER->existing_file_.hermes_.c_str(), "r"); REQUIRE(fh != nullptr); size_t total_chars = 0; int c = '0'; do { c = fgetc(fh); total_chars++; - if (total_chars >= TEST_INFO->num_iterations_) break; + if (total_chars >= TESTER->num_iterations_) break; } while (c != EOF); - REQUIRE(total_chars == TEST_INFO->num_iterations_); + REQUIRE(total_chars == TESTER->num_iterations_); int status = fclose(fh); REQUIRE(status == 0); } - TEST_INFO->Posttest(false); + TESTER->Posttest(false); } -TEST_CASE("getc", "[process=" + std::to_string(TEST_INFO->comm_size_) + - "]" - "[operation=batched_getc]" - "[repetition=" + - std::to_string(TEST_INFO->num_iterations_) + "][file=1]") { - TEST_INFO->Pretest(); +TEST_CASE("getc", "[process=" + std::to_string(TESTER->comm_size_) + + "]" + "[operation=batched_getc]" + "[repetition=" + + std::to_string(TESTER->num_iterations_) + "][file=1]") { + TESTER->Pretest(); SECTION("iterate and get all characters") { - FILE* fh = fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r"); + FILE* fh = fopen(TESTER->existing_file_.hermes_.c_str(), "r"); REQUIRE(fh != nullptr); size_t total_chars = 0; int c = '0'; do { c = getc(fh); total_chars++; - if (total_chars >= TEST_INFO->num_iterations_) break; + if (total_chars >= TESTER->num_iterations_) break; } while (c != EOF); - REQUIRE(total_chars == TEST_INFO->num_iterations_); + REQUIRE(total_chars == TESTER->num_iterations_); int status = fclose(fh); REQUIRE(status == 0); } - TEST_INFO->Posttest(false); + TESTER->Posttest(false); } -TEST_CASE("getw", "[process=" + std::to_string(TEST_INFO->comm_size_) + - "]" - "[operation=batched_getw]" - "[repetition=" + - std::to_string(TEST_INFO->num_iterations_) + "][file=1]") { - TEST_INFO->Pretest(); +TEST_CASE("getw", "[process=" + std::to_string(TESTER->comm_size_) + + "]" + "[operation=batched_getw]" + "[repetition=" + + std::to_string(TESTER->num_iterations_) + "][file=1]") { + TESTER->Pretest(); SECTION("iterate and get all characters") { - FILE* fh = fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r"); + FILE* fh = fopen(TESTER->existing_file_.hermes_.c_str(), "r"); REQUIRE(fh != nullptr); size_t total_chars = 0; int c = '0'; do { c = getw(fh); total_chars++; - if (total_chars >= TEST_INFO->num_iterations_) break; + if (total_chars >= TESTER->num_iterations_) break; } while (c != EOF); - REQUIRE(total_chars == TEST_INFO->num_iterations_); + REQUIRE(total_chars == TESTER->num_iterations_); int status = fclose(fh); REQUIRE(status == 0); } - TEST_INFO->Posttest(false); + TESTER->Posttest(false); } -TEST_CASE("fgets", "[process=" + std::to_string(TEST_INFO->comm_size_) + - "]" - "[operation=single_fgets]" - "[repetition=1][file=1]") { - TEST_INFO->Pretest(); +TEST_CASE("fgets", "[process=" + std::to_string(TESTER->comm_size_) + + "]" + "[operation=single_fgets]" + "[repetition=1][file=1]") { + TESTER->Pretest(); SECTION("iterate and get all characters") { - FILE* fh = fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r"); + FILE* fh = fopen(TESTER->existing_file_.hermes_.c_str(), "r"); REQUIRE(fh != nullptr); - auto ret_str = fgets(TEST_INFO->read_data_.data(), TEST_INFO->request_size_, fh); + auto ret_str = fgets(TESTER->read_data_.data(), TESTER->request_size_, fh); REQUIRE(ret_str != NULL); - REQUIRE(strlen(ret_str) == TEST_INFO->request_size_ - 1); + REQUIRE(strlen(ret_str) == TESTER->request_size_ - 1); int status = fclose(fh); REQUIRE(status == 0); } - TEST_INFO->Posttest(false); + TESTER->Posttest(false); } -TEST_CASE("fputc", "[process=" + std::to_string(TEST_INFO->comm_size_) + - "]" - "[operation=batched_fputc]" - "[repetition=" + - std::to_string(TEST_INFO->num_iterations_) + "][file=1]") { - TEST_INFO->Pretest(); +TEST_CASE("fputc", "[process=" + std::to_string(TESTER->comm_size_) + + "]" + "[operation=batched_fputc]" + "[repetition=" + + std::to_string(TESTER->num_iterations_) + "][file=1]") { + TESTER->Pretest(); SECTION("iterate and get all characters") { - FILE* fh = fopen(TEST_INFO->new_file_.hermes_.c_str(), "w+"); + FILE* fh = fopen(TESTER->new_file_.hermes_.c_str(), "w+"); REQUIRE(fh != nullptr); - size_t total_chars = TEST_INFO->num_iterations_; + size_t total_chars = TESTER->num_iterations_; char c = 'w'; for (size_t i = 0; i < total_chars; ++i) { int ret_char = fputc(c, fh); @@ -361,19 +373,19 @@ TEST_CASE("fputc", "[process=" + std::to_string(TEST_INFO->comm_size_) + int status = fclose(fh); REQUIRE(status == 0); } - TEST_INFO->Posttest(false); + TESTER->Posttest(false); } -TEST_CASE("putc", "[process=" + std::to_string(TEST_INFO->comm_size_) + - "]" - "[operation=batched_putc]" - "[repetition=" + - std::to_string(TEST_INFO->num_iterations_) + "][file=1]") { - TEST_INFO->Pretest(); +TEST_CASE("putc", "[process=" + std::to_string(TESTER->comm_size_) + + "]" + "[operation=batched_putc]" + "[repetition=" + + std::to_string(TESTER->num_iterations_) + "][file=1]") { + TESTER->Pretest(); SECTION("iterate and get all characters") { - FILE* fh = fopen(TEST_INFO->new_file_.hermes_.c_str(), "w+"); + FILE* fh = fopen(TESTER->new_file_.hermes_.c_str(), "w+"); REQUIRE(fh != nullptr); - size_t total_chars = TEST_INFO->num_iterations_; + size_t total_chars = TESTER->num_iterations_; char c = 'w'; for (size_t i = 0; i < total_chars; ++i) { int ret_char = putc(c, fh); @@ -382,18 +394,18 @@ TEST_CASE("putc", "[process=" + std::to_string(TEST_INFO->comm_size_) + int status = fclose(fh); REQUIRE(status == 0); } - TEST_INFO->Posttest(false); + TESTER->Posttest(false); } -TEST_CASE("putw", "[process=" + std::to_string(TEST_INFO->comm_size_) + - "]" - "[operation=batched_putw]" - "[repetition=" + - std::to_string(TEST_INFO->num_iterations_) + "][file=1]") { - TEST_INFO->Pretest(); +TEST_CASE("putw", "[process=" + std::to_string(TESTER->comm_size_) + + "]" + "[operation=batched_putw]" + "[repetition=" + + std::to_string(TESTER->num_iterations_) + "][file=1]") { + TESTER->Pretest(); SECTION("iterate and get all characters") { - FILE* fh = fopen(TEST_INFO->new_file_.hermes_.c_str(), "w+"); + FILE* fh = fopen(TESTER->new_file_.hermes_.c_str(), "w+"); REQUIRE(fh != nullptr); - size_t total_chars = TEST_INFO->num_iterations_; + size_t total_chars = TESTER->num_iterations_; int c = 'w'; for (size_t i = 0; i < total_chars; ++i) { int ret = putw(c, fh); @@ -402,32 +414,32 @@ TEST_CASE("putw", "[process=" + std::to_string(TEST_INFO->comm_size_) + int status = fclose(fh); REQUIRE(status == 0); } - TEST_INFO->Posttest(false); + TESTER->Posttest(false); } -TEST_CASE("fputs", "[process=" + std::to_string(TEST_INFO->comm_size_) + - "]" - "[operation=single_fputs]" - "[repetition=1][file=1]") { - TEST_INFO->Pretest(); +TEST_CASE("fputs", "[process=" + std::to_string(TESTER->comm_size_) + + "]" + "[operation=single_fputs]" + "[repetition=1][file=1]") { + TESTER->Pretest(); SECTION("iterate and get all characters") { - FILE* fh = fopen(TEST_INFO->existing_file_.hermes_.c_str(), "w+"); + FILE* fh = fopen(TESTER->existing_file_.hermes_.c_str(), "w+"); REQUIRE(fh != nullptr); - int status = fputs(TEST_INFO->write_data_.data(), fh); + int status = fputs(TESTER->write_data_.data(), fh); REQUIRE(status != -1); status = fclose(fh); REQUIRE(status == 0); } - TEST_INFO->Posttest(false); + TESTER->Posttest(false); } -TEST_CASE("fseek", "[process=" + std::to_string(TEST_INFO->comm_size_) + - "]" - "[operation=single_fseek]" - "[repetition=1][file=1]") { - TEST_INFO->Pretest(); +TEST_CASE("fseek", "[process=" + std::to_string(TESTER->comm_size_) + + "]" + "[operation=single_fseek]" + "[repetition=1][file=1]") { + TESTER->Pretest(); SECTION("test all seek modes") { - FILE* fh = fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r"); + FILE* fh = fopen(TESTER->existing_file_.hermes_.c_str(), "r"); REQUIRE(fh != nullptr); int status = fseek(fh, 0, SEEK_SET); REQUIRE(status == 0); @@ -442,26 +454,26 @@ TEST_CASE("fseek", "[process=" + std::to_string(TEST_INFO->comm_size_) + status = fseek(fh, 0, SEEK_END); REQUIRE(status == 0); offset = ftell(fh); - REQUIRE(offset == TEST_INFO->total_size_); + REQUIRE(offset == TESTER->total_size_); status = fseek(fh, 0, SEEK_CUR); REQUIRE(status == 0); offset = ftell(fh); - REQUIRE(offset == TEST_INFO->total_size_); + REQUIRE(offset == TESTER->total_size_); status = fclose(fh); REQUIRE(status == 0); } - TEST_INFO->Posttest(false); + TESTER->Posttest(false); } -TEST_CASE("fseeko", "[process=" + std::to_string(TEST_INFO->comm_size_) + - "]" - "[operation=single_fseeko]" - "[repetition=1][file=1]") { - TEST_INFO->Pretest(); +TEST_CASE("fseeko", "[process=" + std::to_string(TESTER->comm_size_) + + "]" + "[operation=single_fseeko]" + "[repetition=1][file=1]") { + TESTER->Pretest(); SECTION("test all seek modes") { - FILE* fh = fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r"); + FILE* fh = fopen(TESTER->existing_file_.hermes_.c_str(), "r"); REQUIRE(fh != nullptr); int status = fseeko(fh, 0, SEEK_SET); REQUIRE(status == 0); @@ -476,26 +488,26 @@ TEST_CASE("fseeko", "[process=" + std::to_string(TEST_INFO->comm_size_) + status = fseeko(fh, 0, SEEK_END); REQUIRE(status == 0); offset = ftell(fh); - REQUIRE(offset == TEST_INFO->total_size_); + REQUIRE(offset == TESTER->total_size_); status = fseeko(fh, 0, SEEK_CUR); REQUIRE(status == 0); offset = ftell(fh); - REQUIRE(offset == TEST_INFO->total_size_); + REQUIRE(offset == TESTER->total_size_); status = fclose(fh); REQUIRE(status == 0); } - TEST_INFO->Posttest(false); + TESTER->Posttest(false); } -TEST_CASE("fseeko64", "[process=" + std::to_string(TEST_INFO->comm_size_) + - "]" - "[operation=single_fseeko64]" - "[repetition=1][file=1]") { - TEST_INFO->Pretest(); +TEST_CASE("fseeko64", "[process=" + std::to_string(TESTER->comm_size_) + + "]" + "[operation=single_fseeko64]" + "[repetition=1][file=1]") { + TESTER->Pretest(); SECTION("test all seek modes") { - FILE* fh = fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r"); + FILE* fh = fopen(TESTER->existing_file_.hermes_.c_str(), "r"); REQUIRE(fh != nullptr); int status = fseeko64(fh, 0, SEEK_SET); REQUIRE(status == 0); @@ -510,26 +522,26 @@ TEST_CASE("fseeko64", "[process=" + std::to_string(TEST_INFO->comm_size_) + status = fseeko64(fh, 0, SEEK_END); REQUIRE(status == 0); offset = ftell(fh); - REQUIRE(offset == TEST_INFO->total_size_); + REQUIRE(offset == TESTER->total_size_); status = fseeko64(fh, 0, SEEK_CUR); REQUIRE(status == 0); offset = ftell(fh); - REQUIRE(offset == TEST_INFO->total_size_); + REQUIRE(offset == TESTER->total_size_); status = fclose(fh); REQUIRE(status == 0); } - TEST_INFO->Posttest(false); + TESTER->Posttest(false); } -TEST_CASE("rewind", "[process=" + std::to_string(TEST_INFO->comm_size_) + - "]" - "[operation=single_rewind]" - "[repetition=1][file=1]") { - TEST_INFO->Pretest(); +TEST_CASE("rewind", "[process=" + std::to_string(TESTER->comm_size_) + + "]" + "[operation=single_rewind]" + "[repetition=1][file=1]") { + TESTER->Pretest(); SECTION("test all seek modes") { - FILE* fh = fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r"); + FILE* fh = fopen(TESTER->existing_file_.hermes_.c_str(), "r"); REQUIRE(fh != nullptr); int status = fseeko(fh, 0, SEEK_SET); REQUIRE(status == 0); @@ -542,7 +554,7 @@ TEST_CASE("rewind", "[process=" + std::to_string(TEST_INFO->comm_size_) + status = fseeko(fh, 0, SEEK_END); REQUIRE(status == 0); offset = ftell(fh); - REQUIRE(offset == TEST_INFO->total_size_); + REQUIRE(offset == TESTER->total_size_); rewind(fh); offset = ftell(fh); REQUIRE(offset == 0); @@ -550,16 +562,16 @@ TEST_CASE("rewind", "[process=" + std::to_string(TEST_INFO->comm_size_) + status = fclose(fh); REQUIRE(status == 0); } - TEST_INFO->Posttest(false); + TESTER->Posttest(false); } -TEST_CASE("fsetpos", "[process=" + std::to_string(TEST_INFO->comm_size_) + - "]" - "[operation=single_fsetpos]" - "[repetition=1][file=1]") { - TEST_INFO->Pretest(); +TEST_CASE("fsetpos", "[process=" + std::to_string(TESTER->comm_size_) + + "]" + "[operation=single_fsetpos]" + "[repetition=1][file=1]") { + TESTER->Pretest(); SECTION("test all seek modes") { - FILE* fh = fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r"); + FILE* fh = fopen(TESTER->existing_file_.hermes_.c_str(), "r"); REQUIRE(fh != nullptr); fpos_t position; fgetpos(fh, &position); @@ -570,25 +582,25 @@ TEST_CASE("fsetpos", "[process=" + std::to_string(TEST_INFO->comm_size_) + size_t offset = ftell(fh); REQUIRE(offset == 0); - position.__pos = TEST_INFO->total_size_; + position.__pos = TESTER->total_size_; status = fsetpos(fh, &position); REQUIRE(status == 0); offset = ftell(fh); - REQUIRE(offset == TEST_INFO->total_size_); + REQUIRE(offset == TESTER->total_size_); status = fclose(fh); REQUIRE(status == 0); } - TEST_INFO->Posttest(false); + TESTER->Posttest(false); } -TEST_CASE("fsetpos64", "[process=" + std::to_string(TEST_INFO->comm_size_) + - "]" - "[operation=single_fsetpos64]" - "[repetition=1][file=1]") { - TEST_INFO->Pretest(); +TEST_CASE("fsetpos64", "[process=" + std::to_string(TESTER->comm_size_) + + "]" + "[operation=single_fsetpos64]" + "[repetition=1][file=1]") { + TESTER->Pretest(); SECTION("test all seek modes") { - FILE* fh = fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r"); + FILE* fh = fopen(TESTER->existing_file_.hermes_.c_str(), "r"); REQUIRE(fh != nullptr); fpos64_t position; fgetpos64(fh, &position); @@ -599,25 +611,25 @@ TEST_CASE("fsetpos64", "[process=" + std::to_string(TEST_INFO->comm_size_) + size_t offset = ftell(fh); REQUIRE(offset == 0); - position.__pos = TEST_INFO->total_size_; + position.__pos = TESTER->total_size_; status = fsetpos64(fh, &position); REQUIRE(status == 0); offset = ftell(fh); - REQUIRE(offset == TEST_INFO->total_size_); + REQUIRE(offset == TESTER->total_size_); status = fclose(fh); REQUIRE(status == 0); } - TEST_INFO->Posttest(false); + TESTER->Posttest(false); } -TEST_CASE("fgetpos", "[process=" + std::to_string(TEST_INFO->comm_size_) + - "]" - "[operation=single_fgetpos]" - "[repetition=1][file=1]") { - TEST_INFO->Pretest(); +TEST_CASE("fgetpos", "[process=" + std::to_string(TESTER->comm_size_) + + "]" + "[operation=single_fgetpos]" + "[repetition=1][file=1]") { + TESTER->Pretest(); SECTION("test all seek modes") { - FILE* fh = fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r"); + FILE* fh = fopen(TESTER->existing_file_.hermes_.c_str(), "r"); REQUIRE(fh != nullptr); fpos_t position; @@ -629,21 +641,21 @@ TEST_CASE("fgetpos", "[process=" + std::to_string(TEST_INFO->comm_size_) + status = fseek(fh, 0, SEEK_END); REQUIRE(status == 0); status = fgetpos(fh, &position); - REQUIRE(position.__pos == (long int)TEST_INFO->total_size_); + REQUIRE(position.__pos == (long int)TESTER->total_size_); status = fclose(fh); REQUIRE(status == 0); } - TEST_INFO->Posttest(false); + TESTER->Posttest(false); } -TEST_CASE("fgetpos64", "[process=" + std::to_string(TEST_INFO->comm_size_) + - "]" - "[operation=single_fgetpos64]" - "[repetition=1][file=1]") { - TEST_INFO->Pretest(); +TEST_CASE("fgetpos64", "[process=" + std::to_string(TESTER->comm_size_) + + "]" + "[operation=single_fgetpos64]" + "[repetition=1][file=1]") { + TESTER->Pretest(); SECTION("test all seek modes") { - FILE* fh = fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r"); + FILE* fh = fopen(TESTER->existing_file_.hermes_.c_str(), "r"); REQUIRE(fh != nullptr); fpos64_t position; @@ -655,119 +667,123 @@ TEST_CASE("fgetpos64", "[process=" + std::to_string(TEST_INFO->comm_size_) + status = fseek(fh, 0, SEEK_END); REQUIRE(status == 0); status = fgetpos64(fh, &position); - REQUIRE(position.__pos == (long int)TEST_INFO->total_size_); + REQUIRE(position.__pos == (long int)TESTER->total_size_); status = fclose(fh); REQUIRE(status == 0); } - TEST_INFO->Posttest(false); + TESTER->Posttest(false); } -TEST_CASE("Open64", "[process=" + std::to_string(TEST_INFO->comm_size_) + - "]" - "[operation=single_open]" - "[repetition=1][file=1]") { - TEST_INFO->Pretest(); +TEST_CASE("Open64", "[process=" + std::to_string(TESTER->comm_size_) + + "]" + "[operation=single_open]" + "[repetition=1][file=1]") { + TESTER->Pretest(); SECTION("open non-existant file") { - FILE* fh = fopen64(TEST_INFO->new_file_.hermes_.c_str(), "r"); + FILE* fh = fopen64(TESTER->new_file_.hermes_.c_str(), "r"); REQUIRE(fh == nullptr); - fh = fopen64(TEST_INFO->new_file_.hermes_.c_str(), "r+"); + fh = fopen64(TESTER->new_file_.hermes_.c_str(), "r+"); REQUIRE(fh == nullptr); } SECTION("truncate existing file and write-only") { - FILE* fh = fopen64(TEST_INFO->existing_file_.hermes_.c_str(), "w"); + FILE* fh = fopen64(TESTER->existing_file_.hermes_.c_str(), "w"); REQUIRE(fh != nullptr); int status = fclose(fh); REQUIRE(status == 0); } SECTION("truncate existing file and read/write") { - FILE* fh = fopen64(TEST_INFO->existing_file_.hermes_.c_str(), "w+"); + FILE* fh = fopen64(TESTER->existing_file_.hermes_.c_str(), "w+"); REQUIRE(fh != nullptr); int status = fclose(fh); REQUIRE(status == 0); } SECTION("open existing file") { - FILE* fh = fopen64(TEST_INFO->existing_file_.hermes_.c_str(), "r+"); + FILE* fh = fopen64(TESTER->existing_file_.hermes_.c_str(), "r+"); REQUIRE(fh != nullptr); int status = fclose(fh); REQUIRE(status == 0); - fh = fopen64(TEST_INFO->existing_file_.hermes_.c_str(), "r"); + fh = fopen64(TESTER->existing_file_.hermes_.c_str(), "r"); REQUIRE(fh != nullptr); status = fclose(fh); REQUIRE(status == 0); } SECTION("append write existing file") { - FILE* fh = fopen64(TEST_INFO->existing_file_.hermes_.c_str(), "a"); + FILE* fh = fopen64(TESTER->existing_file_.hermes_.c_str(), "a"); REQUIRE(fh != nullptr); int status = fclose(fh); REQUIRE(status == 0); } SECTION("append write and read existing file") { - FILE* fh = fopen64(TEST_INFO->existing_file_.hermes_.c_str(), "a+"); + FILE* fh = fopen64(TESTER->existing_file_.hermes_.c_str(), "a+"); REQUIRE(fh != nullptr); int status = fclose(fh); REQUIRE(status == 0); } - TEST_INFO->Posttest(false); + TESTER->Posttest(false); } -TEST_CASE("Freopen64", "[process=" + std::to_string(TEST_INFO->comm_size_) + - "]" - "[operation=single_freopen]" - "[repetition=1][file=1]") { - TEST_INFO->Pretest(); +TEST_CASE("Freopen64", "[process=" + std::to_string(TESTER->comm_size_) + + "]" + "[operation=single_freopen]" + "[repetition=1][file=1]") { + TESTER->Pretest(); SECTION("change different modes") { - FILE* fhr = fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r"); + FILE* fhr = fopen(TESTER->existing_file_.hermes_.c_str(), "r"); REQUIRE(fhr != nullptr); - FILE* fhw = freopen64(TEST_INFO->existing_file_.hermes_.c_str(), "w", fhr); + FILE* fhw = freopen64(TESTER->existing_file_.hermes_.c_str(), "w", fhr); REQUIRE(fhw != nullptr); size_t write_size = - fwrite(TEST_INFO->write_data_.data(), sizeof(char), TEST_INFO->request_size_, fhw); - REQUIRE(write_size == TEST_INFO->request_size_); + fwrite(TESTER->write_data_.data(), + sizeof(char), TESTER->request_size_, fhw); + REQUIRE(write_size == TESTER->request_size_); - FILE* fhwp = freopen64(TEST_INFO->existing_file_.hermes_.c_str(), "w+", fhw); + FILE* fhwp = freopen64(TESTER->existing_file_.hermes_.c_str(), "w+", fhw); REQUIRE(fhwp != nullptr); write_size = - fwrite(TEST_INFO->write_data_.data(), sizeof(char), TEST_INFO->request_size_, fhwp); - REQUIRE(write_size == TEST_INFO->request_size_); + fwrite(TESTER->write_data_.data(), + sizeof(char), TESTER->request_size_, fhwp); + REQUIRE(write_size == TESTER->request_size_); - FILE* fha = freopen64(TEST_INFO->existing_file_.hermes_.c_str(), "a", fhwp); + FILE* fha = freopen64(TESTER->existing_file_.hermes_.c_str(), "a", fhwp); REQUIRE(fha != nullptr); write_size = - fwrite(TEST_INFO->write_data_.data(), sizeof(char), TEST_INFO->request_size_, fhwp); - REQUIRE(write_size == TEST_INFO->request_size_); + fwrite(TESTER->write_data_.data(), + sizeof(char), TESTER->request_size_, fhwp); + REQUIRE(write_size == TESTER->request_size_); - FILE* fhap = freopen64(TEST_INFO->existing_file_.hermes_.c_str(), "a+", fha); + FILE* fhap = freopen64(TESTER->existing_file_.hermes_.c_str(), "a+", fha); REQUIRE(fhap != nullptr); write_size = - fwrite(TEST_INFO->write_data_.data(), sizeof(char), TEST_INFO->request_size_, fhap); - REQUIRE(write_size == TEST_INFO->request_size_); + fwrite(TESTER->write_data_.data(), + sizeof(char), TESTER->request_size_, fhap); + REQUIRE(write_size == TESTER->request_size_); int status = fclose(fhap); REQUIRE(status == 0); } - TEST_INFO->Posttest(false); + TESTER->Posttest(false); } -TEST_CASE("MultiOpen", "[process=" + std::to_string(TEST_INFO->comm_size_) + - "]" - "[operation=multi_open]" - "[repetition=1][file=1]") { - TEST_INFO->Pretest(); +TEST_CASE("MultiOpen", "[process=" + std::to_string(TESTER->comm_size_) + + "]" + "[operation=multi_open]" + "[repetition=1][file=1]") { + TESTER->Pretest(); SECTION("Open same file twice and then close both fps") { - FILE* fh1 = fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r"); + FILE* fh1 = fopen(TESTER->existing_file_.hermes_.c_str(), "r"); REQUIRE(fh1 != nullptr); - FILE* fh2 = fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r"); + FILE* fh2 = fopen(TESTER->existing_file_.hermes_.c_str(), "r"); REQUIRE(fh2 != nullptr); int status = fclose(fh1); REQUIRE(status == 0); status = fclose(fh2); REQUIRE(status == 0); } - TEST_INFO->Posttest(false); + TESTER->Posttest(false); } diff --git a/test/unit/hermes_adapters/stdio/stdio_adapter_low_buffer_space_test.cc b/test/unit/hermes_adapters/stdio/stdio_adapter_low_buffer_space_test.cc index 8d43eab73..c471a338e 100644 --- a/test/unit/hermes_adapters/stdio/stdio_adapter_low_buffer_space_test.cc +++ b/test/unit/hermes_adapters/stdio/stdio_adapter_low_buffer_space_test.cc @@ -10,288 +10,40 @@ * have access to the file, you may request a copy from help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#include -#include -#include +#include "stdio_adapter_test.h" -#include -#include - -#include "adapter_test_utils.h" -#include "catch_config.h" -#if HERMES_INTERCEPT == 1 -#include "hermes_adapters/stdio/stdio_api.h" -#include "hermes_adapters/stdio/stdio_fs_api.h" -#endif - -namespace stdfs = std::filesystem; - -namespace hermes::adapter::stdio::test { -struct Arguments { - std::string filename = "test.dat"; - std::string directory = "/tmp/test_hermes"; - size_t request_size = 65536; -}; -struct Info { - int rank = 0; - int comm_size = 1; - std::string write_data; - std::string read_data; - std::string new_file; - std::string existing_file; - std::string new_file_cmp; - std::string existing_file_cmp; - size_t num_iterations = 64; - unsigned int offset_seed = 1; - unsigned int rs_seed = 1; - unsigned int temporal_interval_seed = 5; - size_t total_size; - size_t stride_size = 512; - unsigned int temporal_interval_ms = 1; - size_t small_min = 1, small_max = 4 * 1024; - size_t medium_min = 4 * 1024 + 1, medium_max = 256 * 1024; - size_t large_min = 256 * 1024 + 1, large_max = 3 * 1024 * 1024; -}; -} // namespace hermes::adapter::stdio::test -hermes::adapter::stdio::test::Arguments args; -hermes::adapter::stdio::test::Info info; - -int init(int* argc, char*** argv) { -#if HERMES_INTERCEPT == 1 - setenv("HERMES_FLUSH_MODE", "kSync", 1); - HERMES_CLIENT_CONF.flushing_mode_ = hermes::FlushingMode::kSync; -#endif - MPI_Init(argc, argv); - TEST_INFO->write_data_ = GenRandom(TEST_INFO->request_size_); - TEST_INFO->read_data_ = std::string(TEST_INFO->request_size_, 'r'); - return 0; -} -int finalize() { - MPI_Finalize(); - return 0; -} - -int pretest() { - stdfs::path fullpath = args.directory; - fullpath /= args.filename; - TEST_INFO->new_file = fullpath.string() + "_new_" + std::to_string(getpid()); - TEST_INFO->existing_file = fullpath.string() + "_ext_" + std::to_string(getpid()); - TEST_INFO->new_file_cmp = - fullpath.string() + "_new_cmp" + "_" + std::to_string(getpid()); - TEST_INFO->existing_file_cmp = - fullpath.string() + "_ext_cmp" + "_" + std::to_string(getpid()); - if (stdfs::exists(TEST_INFO->new_file)) stdfs::remove(TEST_INFO->new_file); - if (stdfs::exists(TEST_INFO->new_file_cmp)) stdfs::remove(TEST_INFO->new_file_cmp); - if (stdfs::exists(TEST_INFO->existing_file)) stdfs::remove(TEST_INFO->existing_file); - if (stdfs::exists(TEST_INFO->existing_file_cmp)) - stdfs::remove(TEST_INFO->existing_file_cmp); - if (!stdfs::exists(TEST_INFO->existing_file)) { - std::string cmd = "{ tr -dc '[:alnum:]' < /dev/urandom | head -c " + - std::to_string(TEST_INFO->request_size_ * TEST_INFO->num_iterations_) + - "; } > " + TEST_INFO->existing_file + " 2> /dev/null"; - int status = system(cmd.c_str()); - REQUIRE(status != -1); - REQUIRE(stdfs::file_size(TEST_INFO->existing_file) == - TEST_INFO->request_size_ * TEST_INFO->num_iterations_); - TEST_INFO->total_size_ = stdfs::file_size(TEST_INFO->existing_file); - } - if (!stdfs::exists(TEST_INFO->existing_file_cmp)) { - std::string cmd = "cp " + TEST_INFO->existing_file + " " + TEST_INFO->existing_file_cmp; - int status = system(cmd.c_str()); - REQUIRE(status != -1); - REQUIRE(stdfs::file_size(TEST_INFO->existing_file_cmp) == - TEST_INFO->request_size_ * TEST_INFO->num_iterations_); - } - REQUIRE(TEST_INFO->total_size_ > 0); -#if HERMES_INTERCEPT == 1 - HERMES_CLIENT_CONF.SetAdapterPathTracking(TEST_INFO->existing_file_cmp, false); - HERMES_CLIENT_CONF.SetAdapterPathTracking(TEST_INFO->new_file_cmp, false); -#endif - return 0; -} - -void Clear() { -#if HERMES_INTERCEPT == 1 - HERMES->Clear(); -#endif -} - -int posttest(bool compare_data = true) { -#if HERMES_INTERCEPT == 1 - HERMES_CLIENT_CONF.SetAdapterPathTracking(TEST_INFO->existing_file, false); - HERMES_CLIENT_CONF.SetAdapterPathTracking(TEST_INFO->new_file, false); -#endif - if (compare_data && stdfs::exists(TEST_INFO->new_file) && - stdfs::exists(TEST_INFO->new_file_cmp)) { - size_t size = stdfs::file_size(TEST_INFO->new_file); - REQUIRE(size == stdfs::file_size(TEST_INFO->new_file_cmp)); - if (size > 0) { - std::vector d1(size, '0'); - std::vector d2(size, '1'); - - FILE* fh1 = fopen(TEST_INFO->new_file_.hermes_.c_str(), "r"); - REQUIRE(fh1 != nullptr); - size_t read_d1 = fread(d1.data(), size, sizeof(unsigned char), fh1); - REQUIRE(read_d1 == sizeof(unsigned char)); - int status = fclose(fh1); - REQUIRE(status == 0); - - FILE* fh2 = fopen(TEST_INFO->new_file_cmp.c_str(), "r"); - REQUIRE(fh2 != nullptr); - size_t read_d2 = fread(d2.data(), size, sizeof(unsigned char), fh2); - REQUIRE(read_d2 == sizeof(unsigned char)); - status = fclose(fh2); - REQUIRE(status == 0); - - size_t char_mismatch = 0; - for (size_t pos = 0; pos < size; ++pos) { - if (d1[pos] != d2[pos]) { - char_mismatch = pos; - break; - } - } - REQUIRE(char_mismatch == 0); - } - } - if (compare_data && stdfs::exists(TEST_INFO->existing_file) && - stdfs::exists(TEST_INFO->existing_file_cmp)) { - size_t size = stdfs::file_size(TEST_INFO->existing_file); - if (size != stdfs::file_size(TEST_INFO->existing_file_cmp)) sleep(1); - REQUIRE(size == stdfs::file_size(TEST_INFO->existing_file_cmp)); - if (size > 0) { - std::vector d1(size, '0'); - std::vector d2(size, '1'); - - FILE* fh1 = fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r"); - REQUIRE(fh1 != nullptr); - size_t read_d1 = fread(d1.data(), size, sizeof(unsigned char), fh1); - REQUIRE(read_d1 == sizeof(unsigned char)); - int status = fclose(fh1); - REQUIRE(status == 0); - - FILE* fh2 = fopen(TEST_INFO->existing_file_cmp.c_str(), "r"); - REQUIRE(fh2 != nullptr); - size_t read_d2 = fread(d2.data(), size, sizeof(unsigned char), fh2); - REQUIRE(read_d2 == sizeof(unsigned char)); - status = fclose(fh2); - REQUIRE(status == 0); - size_t char_mismatch = 0; - for (size_t pos = 0; pos < size; ++pos) { - if (d1[pos] != d2[pos]) char_mismatch++; - } - REQUIRE(char_mismatch == 0); - } - } - /* Clean up. */ - if (stdfs::exists(TEST_INFO->new_file)) stdfs::remove(TEST_INFO->new_file); - if (stdfs::exists(TEST_INFO->existing_file)) stdfs::remove(TEST_INFO->existing_file); - if (stdfs::exists(TEST_INFO->new_file_cmp)) stdfs::remove(TEST_INFO->new_file_cmp); - if (stdfs::exists(TEST_INFO->existing_file_cmp)) - stdfs::remove(TEST_INFO->existing_file_cmp); - Clear(); - -#if HERMES_INTERCEPT == 1 - HERMES_CLIENT_CONF.SetAdapterPathTracking(TEST_INFO->existing_file_cmp, true); - HERMES_CLIENT_CONF.SetAdapterPathTracking(TEST_INFO->new_file_cmp, true); - HERMES_CLIENT_CONF.SetAdapterPathTracking(TEST_INFO->new_file, true); - HERMES_CLIENT_CONF.SetAdapterPathTracking(TEST_INFO->existing_file, true); -#endif - return 0; -} - -cl::Parser define_options() { - return cl::Opt(args.filename, "filename")["-f"]["--filename"]( - "Filename used for performing I/O") | - cl::Opt(args.directory, "dir")["-d"]["--directory"]( - "Directory used for performing I/O") | - cl::Opt(TEST_INFO->request_size_, "request_size")["-s"]["--request_size"]( - "Request size used for performing I/O"); -} - -namespace test { -FILE* fh_orig; -FILE* fh_cmp; -int status_orig; -size_t size_read_orig; -size_t size_written_orig; -void test_fopen(const char* path, const char* mode) { - std::string cmp_path; - if (strcmp(path, TEST_INFO->new_file.c_str()) == 0) { - cmp_path = TEST_INFO->new_file_cmp; - } else { - cmp_path = TEST_INFO->existing_file_cmp; - } - fh_orig = fopen(path, mode); - fh_cmp = fopen(cmp_path.c_str(), mode); - bool is_same = (fh_cmp != nullptr && fh_orig != nullptr) || - (fh_cmp == nullptr && fh_orig == nullptr); - REQUIRE(is_same); -} -void test_fclose() { - status_orig = fclose(fh_orig); - int status = fclose(fh_cmp); - REQUIRE(status == status_orig); -} -void test_fwrite(const void* ptr, size_t size) { - size_written_orig = fwrite(ptr, sizeof(char), size, fh_orig); - size_t size_written = fwrite(ptr, sizeof(char), size, fh_cmp); - REQUIRE(size_written == size_written_orig); -} -void test_fread(char* ptr, size_t size) { - size_read_orig = fread(ptr, sizeof(char), size, fh_orig); - std::vector read_data(size, 'r'); - size_t size_read = fread(read_data.data(), sizeof(char), size, fh_cmp); - REQUIRE(size_read == size_read_orig); - if (size_read > 0) { - size_t unmatching_chars = 0; - for (size_t i = 0; i < size; ++i) { - if (read_data[i] != ptr[i]) { - unmatching_chars = i; - break; - } - } - REQUIRE(unmatching_chars == 0); - } -} -void test_fseek(long offset, int whence) { - status_orig = fseek(fh_orig, offset, whence); - int status = fseek(fh_cmp, offset, whence); - REQUIRE(status == status_orig); -} -} // namespace test - -TEST_CASE("BatchedWriteSequential", - "[process=" + std::to_string(TEST_INFO->comm_size_) + +TEST_CASE("LowBufferSpace", + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=type-fixed][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("write to new file one big write") { - test::test_fopen(TEST_INFO->new_file_.hermes_.c_str(), "w+"); - REQUIRE(test::fh_orig != nullptr); - auto write_size = TEST_INFO->request_size_ * (TEST_INFO->num_iterations_ + 1); - TEST_INFO->write_data_ = GenRandom(write_size); - test::test_fwrite(TEST_INFO->write_data_.data(), write_size); - REQUIRE(test::size_written_orig == write_size); - test::test_fclose(); - REQUIRE(test::status_orig == 0); - REQUIRE(stdfs::file_size(TEST_INFO->new_file) == write_size); + TESTER->test_fopen(TESTER->new_file_, "w+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + auto write_size = TESTER->request_size_ * (TESTER->num_iterations_ + 1); + TESTER->write_data_ = TESTER->GenRandom(write_size); + TESTER->test_fwrite(TESTER->write_data_.data(), write_size); + REQUIRE(TESTER->size_written_orig_ == write_size); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_) == write_size); } SECTION("write to new file multiple write") { - test::test_fopen(TEST_INFO->new_file_.hermes_.c_str(), "w+"); - REQUIRE(test::fh_orig != nullptr); - for (size_t i = 0; i <= TEST_INFO->num_iterations_; ++i) { - test::test_fwrite(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(test::size_written_orig == TEST_INFO->request_size_); + TESTER->test_fopen(TESTER->new_file_, "w+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + for (size_t i = 0; i <= TESTER->num_iterations_; ++i) { + TESTER->test_fwrite(TESTER->write_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); } - REQUIRE(test::size_written_orig == TEST_INFO->request_size_); - test::test_fclose(); - REQUIRE(test::status_orig == 0); - REQUIRE(stdfs::file_size(TEST_INFO->new_file) == - TEST_INFO->request_size_ * (TEST_INFO->num_iterations_ + 1)); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_) == + TESTER->request_size_ * (TESTER->num_iterations_ + 1)); } - posttest(); + TESTER->Posttest(); } diff --git a/test/unit/hermes_adapters/stdio/stdio_adapter_mapper_test.cc b/test/unit/hermes_adapters/stdio/stdio_adapter_mapper_test.cc index b0e3399ed..0ca1337c7 100644 --- a/test/unit/hermes_adapters/stdio/stdio_adapter_mapper_test.cc +++ b/test/unit/hermes_adapters/stdio/stdio_adapter_mapper_test.cc @@ -10,118 +10,26 @@ * have access to the file, you may request a copy from help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#include - -#include "catch_config.h" -#include "hermes/hermes_types.h" -#include "hermes_adapters/adapter_constants.h" +#include "stdio_adapter_test.h" +#include "hermes_adapters/mapper/mapper_factory.h" #include "hermes_adapters/mapper/mapper_factory.h" -#include "hermes_adapters/stdio/stdio_fs_api.h" +#include "hermes_adapters/adapter_constants.h" -using hermes::adapter::BlobPlacements; using hermes::adapter::MapperFactory; -using hermes::adapter::MapperType; +using hermes::adapter::BlobPlacements; using hermes::adapter::kMapperType; -using hermes::adapter::fs::MetadataManager; -namespace stdfs = std::filesystem; - -namespace hermes::adapter::stdio::test { -struct Arguments { - std::string filename = "test.dat"; - std::string directory = "/tmp/test_hermes"; - size_t request_size = 65536; - size_t num_iterations = 1024; -}; -struct Info { - int rank = 0; - int comm_size = 1; - std::string new_file; - std::string existing_file; - unsigned int offset_seed = 1; - unsigned int rs_seed = 1; - size_t total_size; - size_t stride_size = 1024; - size_t small_min = 1, small_max = 4 * 1024; - size_t medium_min = 4 * 1024 + 1, medium_max = 256 * 1024; - size_t large_min = 256 * 1024 + 1, large_max = 4 * 1024 * 1024; -}; -} // namespace hermes::adapter::stdio::test -hermes::adapter::stdio::test::Arguments args; -hermes::adapter::stdio::test::Info info; - -int init(int* argc, char*** argv) { -#if HERMES_INTERCEPT == 1 - setenv("HERMES_FLUSH_MODE", "kSync", 1); - HERMES_CLIENT_CONF.flushing_mode_ = hermes::FlushingMode::kSync; -#endif - MPI_Init(argc, argv); - - return 0; -} -int finalize() { - MPI_Finalize(); - - return 0; -} - -int pretest() { - stdfs::path fullpath = args.directory; - fullpath /= args.filename; - TEST_INFO->new_file = fullpath.string() + "_new"; - TEST_INFO->existing_file = fullpath.string() + "_ext"; - if (stdfs::exists(TEST_INFO->new_file)) stdfs::remove(TEST_INFO->new_file); - if (stdfs::exists(TEST_INFO->existing_file)) stdfs::remove(TEST_INFO->existing_file); - if (!stdfs::exists(TEST_INFO->existing_file)) { - std::string cmd = "dd if=/dev/zero of=" + TEST_INFO->existing_file + - " bs=1 count=0 seek=" + - std::to_string(TEST_INFO->request_size_ * args.num_iterations) + - " > /dev/null 2>&1"; - int status = system(cmd.c_str()); - REQUIRE(status != -1); - REQUIRE(stdfs::file_size(TEST_INFO->existing_file) == - TEST_INFO->request_size_ * args.num_iterations); - TEST_INFO->total_size_ = stdfs::file_size(TEST_INFO->existing_file); - } - REQUIRE(TEST_INFO->total_size_ > 0); - return 0; -} - -void Clear() { -#if HERMES_INTERCEPT == 1 - HERMES->Clear(); -#endif -} - -int posttest() { - Clear(); - if (stdfs::exists(TEST_INFO->new_file)) stdfs::remove(TEST_INFO->new_file); - if (stdfs::exists(TEST_INFO->existing_file)) stdfs::remove(TEST_INFO->existing_file); - return 0; -} - -cl::Parser define_options() { - return cl::Opt(args.filename, "filename")["-f"]["--filename"]( - "Filename used for performing I/O") | - cl::Opt(args.directory, "dir")["-d"]["--directory"]( - "Directory used for performing I/O") | - cl::Opt(TEST_INFO->request_size_, "request_size")["-s"]["--request_size"]( - "Request size used for performing I/O") | - cl::Opt(args.num_iterations, "iterations")["-n"]["--iterations"]( - "Number of iterations of requests"); -} - -TEST_CASE("SingleWrite", "[process=" + std::to_string(TEST_INFO->comm_size_) + - "]" - "[operation=single_write]" - "[request_size=type-fixed][repetition=1]" - "[pattern=sequential][file=1]") { - TEST_INFO->Pretest(); +TEST_CASE("SingleWrite", "[process=" + std::to_string(TESTER->comm_size_) + + "]" + "[operation=single_write]" + "[request_size=type-fixed][repetition=1]" + "[pattern=sequential][file=1]") { + TESTER->Pretest(); const size_t kPageSize = MEGABYTES(1); SECTION("Map a one request") { - auto mapper = MapperFactory().Get(kMapperType); - size_t total_size = TEST_INFO->request_size_; - FILE* fp = fopen(TEST_INFO->new_file_.hermes_.c_str(), "w+"); + auto mapper = hermes::adapter::MapperFactory().Get(kMapperType); + size_t total_size = TESTER->request_size_; + FILE* fp = fopen(TESTER->new_file_.hermes_.c_str(), "w+"); REQUIRE(fp != nullptr); size_t offset = 0; REQUIRE(kPageSize > total_size + offset); @@ -136,8 +44,8 @@ TEST_CASE("SingleWrite", "[process=" + std::to_string(TEST_INFO->comm_size_) + } SECTION("Map a one big request") { auto mapper = MapperFactory().Get(kMapperType); - size_t total_size = TEST_INFO->request_size_ * args.num_iterations; - FILE* fp = fopen(TEST_INFO->new_file_.hermes_.c_str(), "w+"); + size_t total_size = TESTER->request_size_ * TESTER->num_iterations_; + FILE* fp = fopen(TESTER->new_file_.hermes_.c_str(), "w+"); REQUIRE(fp != nullptr); size_t offset = 0; BlobPlacements mapping; @@ -156,8 +64,8 @@ TEST_CASE("SingleWrite", "[process=" + std::to_string(TEST_INFO->comm_size_) + } SECTION("Map a one large unaligned request") { auto mapper = MapperFactory().Get(kMapperType); - size_t total_size = TEST_INFO->request_size_ * args.num_iterations; - FILE* fp = fopen(TEST_INFO->new_file_.hermes_.c_str(), "w+"); + size_t total_size = TESTER->request_size_ * TESTER->num_iterations_; + FILE* fp = fopen(TESTER->new_file_.hermes_.c_str(), "w+"); REQUIRE(fp != nullptr); size_t offset = 1; BlobPlacements mapping; @@ -191,8 +99,8 @@ TEST_CASE("SingleWrite", "[process=" + std::to_string(TEST_INFO->comm_size_) + } SECTION("Map a one small unaligned request") { auto mapper = MapperFactory().Get(kMapperType); - size_t total_size = TEST_INFO->request_size_; - FILE* fp = fopen(TEST_INFO->new_file_.hermes_.c_str(), "w+"); + size_t total_size = TESTER->request_size_; + FILE* fp = fopen(TESTER->new_file_.hermes_.c_str(), "w+"); REQUIRE(fp != nullptr); size_t offset = 1; REQUIRE(kPageSize > total_size + offset); @@ -205,5 +113,5 @@ TEST_CASE("SingleWrite", "[process=" + std::to_string(TEST_INFO->comm_size_) + int status = fclose(fp); REQUIRE(status == 0); } - posttest(); + TESTER->Posttest(); } diff --git a/test/unit/hermes_adapters/stdio/stdio_adapter_mode_test.cc b/test/unit/hermes_adapters/stdio/stdio_adapter_mode_test.cc index 915e5a52c..b36ccc197 100644 --- a/test/unit/hermes_adapters/stdio/stdio_adapter_mode_test.cc +++ b/test/unit/hermes_adapters/stdio/stdio_adapter_mode_test.cc @@ -10,354 +10,90 @@ * have access to the file, you may request a copy from help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#include -#include -#include -#include - -#include -#include - -#if HERMES_INTERCEPT == 1 -#include "hermes_adapters/stdio/stdio_api.h" -#endif - -#include "adapter_test_utils.h" -#include "hermes_adapters/adapter_types.h" -#include "hermes/hermes.h" - -namespace stdfs = std::filesystem; -using hermes::adapter::AdapterMode; - -namespace hermes::adapter::stdio::test { -struct Arguments { - std::string filename = "test.dat"; - std::string directory = "/tmp/test_hermes"; - size_t request_size = 65536; -}; -struct Info { - int rank = 0; - int comm_size = 1; - std::string write_data; - std::string read_data; - std::string new_file; - std::string existing_file; - std::string new_file_cmp; - std::string existing_file_cmp; - size_t num_iterations = 64; - unsigned int offset_seed = 1; - unsigned int rs_seed = 1; - unsigned int temporal_interval_seed = 5; - size_t total_size; - size_t stride_size = 512; - unsigned int temporal_interval_ms = 1; - size_t small_min = 1, small_max = 4 * 1024; - size_t medium_min = 4 * 1024 + 1, medium_max = 256 * 1024; - size_t large_min = 256 * 1024 + 1, large_max = 3 * 1024 * 1024; -}; -} // namespace hermes::adapter::stdio::test -hermes::adapter::stdio::test::Arguments args; -hermes::adapter::stdio::test::Info info; - -int init(int* argc, char*** argv) { -#if HERMES_INTERCEPT == 1 - setenv("HERMES_FLUSH_MODE", "kSync", 1); - HERMES_CLIENT_CONF.flushing_mode_ = hermes::FlushingMode::kSync; -#endif - stdfs::path fullpath = args.directory; - fullpath /= args.filename; - TEST_INFO->new_file = fullpath.string() + "_new" + std::to_string(getpid()); - TEST_INFO->existing_file = fullpath.string() + "_ext" + std::to_string(getpid()); - TEST_INFO->new_file_cmp = fullpath.string() + "_new_cmp" + std::to_string(getpid()); - TEST_INFO->existing_file_cmp = - fullpath.string() + "_ext_cmp" + std::to_string(getpid()); - char* set_path = getenv("SET_PATH"); - if (set_path && strcmp(set_path, "1") == 0) { - HERMES_CLIENT_CONF.SetAdapterPathTracking(TEST_INFO->new_file, false); - HERMES_CLIENT_CONF.SetAdapterPathTracking(TEST_INFO->existing_file, false); - } - MPI_Init(argc, argv); - TEST_INFO->write_data_ = GenRandom(TEST_INFO->request_size_); - TEST_INFO->read_data_ = std::string(TEST_INFO->request_size_, 'r'); - return 0; -} -int finalize() { - MPI_Finalize(); - return 0; -} - -void IgnoreAllFiles() { -#if HERMES_INTERCEPT == 1 - HERMES_CLIENT_CONF.SetAdapterPathTracking(TEST_INFO->existing_file_cmp, false); - HERMES_CLIENT_CONF.SetAdapterPathTracking(TEST_INFO->new_file_cmp, false); - HERMES_CLIENT_CONF.SetAdapterPathTracking(TEST_INFO->new_file, false); - HERMES_CLIENT_CONF.SetAdapterPathTracking(TEST_INFO->existing_file, false); -#endif -} - -void TrackFiles() { -#if HERMES_INTERCEPT == 1 - HERMES_CLIENT_CONF.SetAdapterPathTracking(TEST_INFO->new_file, true); - HERMES_CLIENT_CONF.SetAdapterPathTracking(TEST_INFO->existing_file, true); -#endif -} - -void RemoveFile(const std::string &path) { - stdfs::remove(path); - if (stdfs::exists(path)) { - HELOG(kFatal, "Failed to remove: {}", path) - } -} - -void RemoveFiles() { - RemoveFile(TEST_INFO->new_file); - RemoveFile(TEST_INFO->new_file_cmp); - RemoveFile(TEST_INFO->existing_file); - RemoveFile(TEST_INFO->existing_file_cmp); -} - -void Clear() { -#if HERMES_INTERCEPT == 1 - HERMES->Clear(); -#endif -} - -int pretest() { - IgnoreAllFiles(); - RemoveFiles(); - - if (!stdfs::exists(TEST_INFO->existing_file)) { - std::string cmd = "{ tr -dc '[:alnum:]' < /dev/urandom | head -c " + - std::to_string(TEST_INFO->request_size_ * TEST_INFO->num_iterations_) + - "; } > " + TEST_INFO->existing_file + " 2> /dev/null"; - int status = system(cmd.c_str()); - REQUIRE(status != -1); - REQUIRE(stdfs::file_size(TEST_INFO->existing_file) == - TEST_INFO->request_size_ * TEST_INFO->num_iterations_); - TEST_INFO->total_size_ = stdfs::file_size(TEST_INFO->existing_file); - } - if (!stdfs::exists(TEST_INFO->existing_file_cmp)) { - std::string cmd = "cp " + TEST_INFO->existing_file + " " + TEST_INFO->existing_file_cmp; - int status = system(cmd.c_str()); - REQUIRE(status != -1); - REQUIRE(stdfs::file_size(TEST_INFO->existing_file_cmp) == - TEST_INFO->request_size_ * TEST_INFO->num_iterations_); - } - REQUIRE(TEST_INFO->total_size_ > 0); - - TrackFiles(); - return 0; -} - -int posttest(bool compare_data = true) { - IgnoreAllFiles(); - if (compare_data && stdfs::exists(TEST_INFO->new_file) && - stdfs::exists(TEST_INFO->new_file_cmp)) { - size_t size = stdfs::file_size(TEST_INFO->new_file); - REQUIRE(size == stdfs::file_size(TEST_INFO->new_file_cmp)); - if (size > 0) { - std::vector d1(size, '0'); - std::vector d2(size, '1'); - - FILE* fh1 = fopen(TEST_INFO->new_file_.hermes_.c_str(), "r"); - REQUIRE(fh1 != nullptr); - size_t read_d1 = fread(d1.data(), size, sizeof(unsigned char), fh1); - REQUIRE(read_d1 == sizeof(unsigned char)); - int status = fclose(fh1); - REQUIRE(status == 0); - - FILE* fh2 = fopen(TEST_INFO->new_file_cmp.c_str(), "r"); - REQUIRE(fh2 != nullptr); - size_t read_d2 = fread(d2.data(), size, sizeof(unsigned char), fh2); - REQUIRE(read_d2 == sizeof(unsigned char)); - status = fclose(fh2); - REQUIRE(status == 0); - - size_t char_mismatch = 0; - for (size_t pos = 0; pos < size; ++pos) { - if (d1[pos] != d2[pos]) char_mismatch++; - } - REQUIRE(char_mismatch == 0); - } - } - if (compare_data && stdfs::exists(TEST_INFO->existing_file) && - stdfs::exists(TEST_INFO->existing_file_cmp)) { - size_t size = stdfs::file_size(TEST_INFO->existing_file); - if (size != stdfs::file_size(TEST_INFO->existing_file_cmp)) sleep(1); - REQUIRE(size == stdfs::file_size(TEST_INFO->existing_file_cmp)); - if (size > 0) { - std::vector d1(size, '0'); - std::vector d2(size, '1'); - - FILE* fh1 = fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r"); - REQUIRE(fh1 != nullptr); - size_t read_d1 = fread(d1.data(), size, sizeof(unsigned char), fh1); - REQUIRE(read_d1 == sizeof(unsigned char)); - int status = fclose(fh1); - REQUIRE(status == 0); - - FILE* fh2 = fopen(TEST_INFO->existing_file_cmp.c_str(), "r"); - REQUIRE(fh2 != nullptr); - size_t read_d2 = fread(d2.data(), size, sizeof(unsigned char), fh2); - REQUIRE(read_d2 == sizeof(unsigned char)); - status = fclose(fh2); - REQUIRE(status == 0); - size_t char_mismatch = 0; - for (size_t pos = 0; pos < size; ++pos) { - if (d1[pos] != d2[pos]) char_mismatch++; - } - REQUIRE(char_mismatch == 0); - } - } - /* Clean up. */ - TrackFiles(); - RemoveFiles(); - Clear(); - return 0; -} - -cl::Parser define_options() { - return cl::Opt(args.filename, "filename")["-f"]["--filename"]( - "Filename used for performing I/O") | - cl::Opt(args.directory, "dir")["-d"]["--directory"]( - "Directory used for performing I/O") | - cl::Opt(TEST_INFO->request_size_, "request_size")["-s"]["--request_size"]( - "Request size used for performing I/O"); -} - -namespace test { -FILE* fh_orig; -FILE* fh_cmp; -int status_orig; -size_t size_read_orig; -size_t size_written_orig; -void test_fopen(const char* path, const char* mode) { - std::string cmp_path; - if (strcmp(path, TEST_INFO->new_file.c_str()) == 0) { - cmp_path = TEST_INFO->new_file_cmp; - } else { - cmp_path = TEST_INFO->existing_file_cmp; - } - fh_orig = fopen(path, mode); - fh_cmp = fopen(cmp_path.c_str(), mode); - bool is_same = (fh_cmp != nullptr && fh_orig != nullptr) || - (fh_cmp == nullptr && fh_orig == nullptr); - REQUIRE(is_same); -} -void test_fclose() { - status_orig = fclose(fh_orig); - int status = fclose(fh_cmp); - REQUIRE(status == status_orig); -} -void test_fwrite(const void* ptr, size_t size) { - size_written_orig = fwrite(ptr, sizeof(char), size, fh_orig); - size_t size_written = fwrite(ptr, sizeof(char), size, fh_cmp); - REQUIRE(size_written == size_written_orig); -} -void test_fread(char* ptr, size_t size) { - size_read_orig = fread(ptr, sizeof(char), size, fh_orig); - std::vector read_data(size, 'r'); - size_t size_read = fread(read_data.data(), sizeof(char), size, fh_cmp); - REQUIRE(size_read == size_read_orig); - if (size_read > 0) { - size_t unmatching_chars = 0; - for (size_t i = 0; i < size; ++i) { - if (read_data[i] != ptr[i]) { - unmatching_chars = i; - break; - } - } - REQUIRE(unmatching_chars == 0); - } -} -void test_fseek(long offset, int whence) { - status_orig = fseek(fh_orig, offset, whence); - int status = fseek(fh_cmp, offset, whence); - REQUIRE(status == status_orig); -} -} // namespace test +#include "stdio_adapter_test.h" TEST_CASE("BatchedWriteSequentialPersistent", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[hermes_mode=persistent]" "[request_size=type-fixed][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1]") { - HERMES_CLIENT_CONF.SetBaseAdapterMode(AdapterMode::kDefault); - REQUIRE(HERMES_CLIENT_CONF.GetBaseAdapterMode() == AdapterMode::kDefault); - TEST_INFO->Pretest(); + HERMES_CLIENT_CONF.SetBaseAdapterMode(hermes::adapter::AdapterMode::kDefault); + REQUIRE(HERMES_CLIENT_CONF.GetBaseAdapterMode() == + hermes::adapter::AdapterMode::kDefault); + TESTER->Pretest(); SECTION("write to new file always at end") { - test::test_fopen(TEST_INFO->new_file_.hermes_.c_str(), "w+"); - REQUIRE(test::fh_orig != nullptr); + TESTER->test_fopen(TESTER->new_file_, "w+"); + REQUIRE(TESTER->fh_orig_ != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - test::test_fwrite(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(test::size_written_orig == TEST_INFO->request_size_); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_fwrite(TESTER->write_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - REQUIRE(stdfs::file_size(TEST_INFO->new_file) == - TEST_INFO->num_iterations_ * TEST_INFO->request_size_); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_) == + TESTER->num_iterations_ * TESTER->request_size_); } - posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedWriteSequentialBypass", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[hermes_mode=bypass]" "[request_size=type-fixed][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1]") { - HERMES_CLIENT_CONF.SetBaseAdapterMode(AdapterMode::kBypass); - REQUIRE(HERMES_CLIENT_CONF.GetBaseAdapterMode() == AdapterMode::kBypass); - TEST_INFO->Pretest(); + HERMES_CLIENT_CONF.SetBaseAdapterMode(hermes::adapter::AdapterMode::kBypass); + REQUIRE(HERMES_CLIENT_CONF.GetBaseAdapterMode() == + hermes::adapter::AdapterMode::kBypass); + TESTER->Pretest(); SECTION("write to new file always at end") { - test::test_fopen(TEST_INFO->new_file_.hermes_.c_str(), "w+"); - REQUIRE(test::fh_orig != nullptr); + TESTER->test_fopen(TESTER->new_file_, "w+"); + REQUIRE(TESTER->fh_orig_ != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - test::test_fwrite(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(test::size_written_orig == TEST_INFO->request_size_); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_fwrite(TESTER->write_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - REQUIRE(stdfs::file_size(TEST_INFO->new_file) == - TEST_INFO->num_iterations_ * TEST_INFO->request_size_); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_) == + TESTER->num_iterations_ * TESTER->request_size_); } - posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedWriteSequentialScratch", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[hermes_mode=scratch]" "[request_size=type-fixed][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1]") { - HERMES_CLIENT_CONF.SetBaseAdapterMode(AdapterMode::kScratch); - REQUIRE(HERMES_CLIENT_CONF.GetBaseAdapterMode() == AdapterMode::kScratch); - TEST_INFO->Pretest(); + HERMES_CLIENT_CONF.SetBaseAdapterMode(hermes::adapter::AdapterMode::kScratch); + REQUIRE(HERMES_CLIENT_CONF.GetBaseAdapterMode() == + hermes::adapter::AdapterMode::kScratch); + TESTER->Pretest(); SECTION("write to new file always at end") { - test::test_fopen(TEST_INFO->new_file_.hermes_.c_str(), "w+"); - REQUIRE(test::fh_orig != nullptr); + TESTER->test_fopen(TESTER->new_file_, "w+"); + REQUIRE(TESTER->fh_orig_ != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - test::test_fwrite(TEST_INFO->write_data_.data(), TEST_INFO->request_size_); - REQUIRE(test::size_written_orig == TEST_INFO->request_size_); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_fwrite(TESTER->write_data_.data(), TESTER->request_size_); + REQUIRE(TESTER->size_written_orig_ == TESTER->request_size_); } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - IgnoreAllFiles(); - REQUIRE(stdfs::exists(TEST_INFO->new_file) == 0); - TrackFiles(); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::exists(TESTER->new_file_.hermes_) == 0); } - TEST_INFO->Posttest(false); + TESTER->Posttest(false); } diff --git a/test/unit/hermes_adapters/stdio/stdio_adapter_mpi_test.cc b/test/unit/hermes_adapters/stdio/stdio_adapter_mpi_test.cc deleted file mode 100644 index ab3f5a9b7..000000000 --- a/test/unit/hermes_adapters/stdio/stdio_adapter_mpi_test.cc +++ /dev/null @@ -1,362 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Distributed under BSD 3-Clause license. * - * Copyright by The HDF Group. * - * Copyright by the Illinois Institute of Technology. * - * All rights reserved. * - * * - * This file is part of Hermes. The full Hermes copyright notice, including * - * terms governing use, modification, and redistribution, is contained in * - * the COPYING file, which can be found at the top directory. If you do not * - * have access to the file, you may request a copy from help@hdfgroup.org. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#include -#include -#include -#include -#include - -#include -#include -#if HERMES_INTERCEPT == 1 -#include "hermes_adapters/stdio/stdio_api.h" -#include "hermes_adapters/stdio/stdio_fs_api.h" -#endif - -namespace stdfs = std::filesystem; - -namespace hermes::adapter::stdio::test { -struct Arguments { - std::string filename = "test.dat"; - std::string directory = "/tmp/test_hermes"; - size_t request_size = 65536; -}; -struct Info { - bool debug = false; - int rank = 0; - int comm_size = 1; - std::string write_data; - std::string read_data; - std::string new_file; - std::string existing_file; - std::string existing_shared_file; - std::string new_file_cmp; - std::string existing_file_cmp; - std::string existing_shared_file_cmp; - size_t num_iterations = 64; - unsigned int offset_seed = 1; - unsigned int rs_seed = 1; - unsigned int temporal_interval_seed = 1; - size_t total_size; - size_t stride_size = 4 * 1024; - unsigned int temporal_interval_ms = 5; - size_t small_min = 1, small_max = 4 * 1024; - size_t medium_min = 4 * 1024 + 1, medium_max = 512 * 1024; - size_t large_min = 512 * 1024 + 1, large_max = 3 * 1024 * 1024; -}; -} // namespace hermes::adapter::stdio::test - -hermes::adapter::stdio::test::Arguments args; -hermes::adapter::stdio::test::Info info; - -int init(int* argc, char*** argv) { -#if HERMES_INTERCEPT == 1 - setenv("HERMES_FLUSH_MODE", "kSync", 1); - HERMES_CLIENT_CONF.flushing_mode_ = hermes::FlushingMode::kSync; -#endif - MPI_Init(argc, argv); - TEST_INFO->write_data_ = GenRandom(TEST_INFO->request_size_); - TEST_INFO->read_data_ = std::string(TEST_INFO->request_size_, 'r'); - MPI_Comm_rank(MPI_COMM_WORLD, &TEST_INFO->rank); - MPI_Comm_size(MPI_COMM_WORLD, &TEST_INFO->comm_size_); - if (TEST_INFO->debug && TEST_INFO->rank == 0) { - printf("%d ready for attach\n", TEST_INFO->comm_size_); - fflush(stdout); - sleep(30); - } - MPI_Barrier(MPI_COMM_WORLD); - return 0; -} -int finalize() { - MPI_Finalize(); - return 0; -} - -namespace test { -FILE* fh_orig; -FILE* fh_cmp; -int status_orig; -size_t size_read_orig; -size_t size_written_orig; -void test_fopen(const char* path, const char* mode) { - std::string cmp_path; - if (strcmp(path, TEST_INFO->new_file.c_str()) == 0) { - cmp_path = TEST_INFO->new_file_cmp; - } else if (strcmp(path, TEST_INFO->existing_file.c_str()) == 0) { - cmp_path = TEST_INFO->existing_file_cmp; - } else { - cmp_path = TEST_INFO->existing_shared_file_cmp; - } - fh_orig = fopen(path, mode); - fh_cmp = fopen(cmp_path.c_str(), mode); - bool is_same = (fh_cmp != nullptr && fh_orig != nullptr) || - (fh_cmp == nullptr && fh_orig == nullptr); - REQUIRE(is_same); -} -void test_fclose() { - status_orig = fclose(fh_orig); - int status = fclose(fh_cmp); - REQUIRE(status == status_orig); -} -void test_fwrite(const void* ptr, size_t size) { - size_written_orig = fwrite(ptr, sizeof(char), size, fh_orig); - size_t size_written = fwrite(ptr, sizeof(char), size, fh_cmp); - REQUIRE(size_written == size_written_orig); -} -void test_fread(char* ptr, size_t size) { - size_read_orig = fread(ptr, sizeof(char), size, fh_orig); - std::vector read_data(size, 'r'); - size_t size_read = fread(read_data.data(), sizeof(char), size, fh_cmp); - REQUIRE(size_read == size_read_orig); - if (size_read > 0) { - size_t unmatching_chars = 0; - for (size_t i = 0; i < size; ++i) { - if (read_data[i] != ptr[i]) unmatching_chars++; - } - REQUIRE(unmatching_chars == 0); - } -} -void test_fseek(long offset, int whence) { - status_orig = fseek(fh_orig, offset, whence); - int status = fseek(fh_cmp, offset, whence); - REQUIRE(status == status_orig); -} -} // namespace test - -int pretest() { - stdfs::path fullpath = args.directory; - fullpath /= args.filename; - TEST_INFO->new_file = fullpath.string() + "_new_" + std::to_string(TEST_INFO->rank) + - "_of_" + std::to_string(TEST_INFO->comm_size_) + "_" + - std::to_string(getpid()); - TEST_INFO->existing_file = fullpath.string() + "_ext_" + std::to_string(TEST_INFO->rank) + - "_of_" + std::to_string(TEST_INFO->comm_size_) + "_" + - std::to_string(getpid()); - TEST_INFO->new_file_cmp = - fullpath.string() + "_new_cmp_" + std::to_string(TEST_INFO->rank) + "_of_" + - std::to_string(TEST_INFO->comm_size_) + "_" + std::to_string(getpid()); - TEST_INFO->existing_file_cmp = - fullpath.string() + "_ext_cmp_" + std::to_string(TEST_INFO->rank) + "_of_" + - std::to_string(TEST_INFO->comm_size_) + "_" + std::to_string(getpid()); - TEST_INFO->existing_shared_file = - fullpath.string() + "_ext_" + std::to_string(TEST_INFO->comm_size_); - TEST_INFO->existing_shared_file_cmp = - fullpath.string() + "_ext_cmp_" + std::to_string(TEST_INFO->comm_size_); - if (stdfs::exists(TEST_INFO->new_file)) stdfs::remove(TEST_INFO->new_file); - if (stdfs::exists(TEST_INFO->existing_file)) stdfs::remove(TEST_INFO->existing_file); - if (stdfs::exists(TEST_INFO->existing_file)) stdfs::remove(TEST_INFO->existing_file); - if (stdfs::exists(TEST_INFO->existing_file_cmp)) - stdfs::remove(TEST_INFO->existing_file_cmp); - if (stdfs::exists(TEST_INFO->existing_shared_file)) - stdfs::remove(TEST_INFO->existing_shared_file); - if (stdfs::exists(TEST_INFO->existing_shared_file_cmp)) - stdfs::remove(TEST_INFO->existing_shared_file_cmp); - stdfs::path temp_fullpath = "/tmp"; - temp_fullpath /= args.filename; - std::string temp_ext_file = - temp_fullpath.string() + "_temp_" + std::to_string(TEST_INFO->rank) + "_of_" + - std::to_string(TEST_INFO->comm_size_) + "_" + std::to_string(getpid()); - if (stdfs::exists(temp_ext_file)) stdfs::remove(temp_ext_file); - if (!stdfs::exists(temp_ext_file)) { - std::string cmd = "{ tr -dc '[:alnum:]' < /dev/urandom | head -c " + - std::to_string(TEST_INFO->request_size_ * TEST_INFO->num_iterations_) + - "; } > " + temp_ext_file + " 2> /dev/null"; - int status = system(cmd.c_str()); - REQUIRE(status != -1); - REQUIRE(stdfs::file_size(temp_ext_file) == - TEST_INFO->request_size_ * TEST_INFO->num_iterations_); - TEST_INFO->total_size_ = stdfs::file_size(temp_ext_file); - } - if (TEST_INFO->rank == 0 && !stdfs::exists(TEST_INFO->existing_shared_file)) { - std::string cmd = "cp " + temp_ext_file + " " + TEST_INFO->existing_shared_file; - int status = system(cmd.c_str()); - REQUIRE(status != -1); - REQUIRE(stdfs::file_size(TEST_INFO->existing_shared_file) == - TEST_INFO->request_size_ * TEST_INFO->num_iterations_); - } - if (TEST_INFO->rank == 0 && !stdfs::exists(TEST_INFO->existing_shared_file_cmp)) { - std::string cmd = - "cp " + temp_ext_file + " " + TEST_INFO->existing_shared_file_cmp; - int status = system(cmd.c_str()); - REQUIRE(status != -1); - REQUIRE(stdfs::file_size(TEST_INFO->existing_shared_file_cmp) == - TEST_INFO->request_size_ * TEST_INFO->num_iterations_); - } - if (!stdfs::exists(TEST_INFO->existing_file)) { - std::string cmd = "cp " + temp_ext_file + " " + TEST_INFO->existing_file; - int status = system(cmd.c_str()); - REQUIRE(status != -1); - REQUIRE(stdfs::file_size(TEST_INFO->existing_file) == - TEST_INFO->request_size_ * TEST_INFO->num_iterations_); - TEST_INFO->total_size_ = stdfs::file_size(TEST_INFO->existing_file); - } - if (!stdfs::exists(TEST_INFO->existing_file_cmp)) { - std::string cmd = "cp " + TEST_INFO->existing_file + " " + TEST_INFO->existing_file_cmp; - int status = system(cmd.c_str()); - REQUIRE(status != -1); - REQUIRE(stdfs::file_size(TEST_INFO->existing_file_cmp) == - TEST_INFO->request_size_ * TEST_INFO->num_iterations_); - } - if (stdfs::exists(temp_ext_file)) stdfs::remove(temp_ext_file); - REQUIRE(TEST_INFO->total_size_ > 0); - MPI_Barrier(MPI_COMM_WORLD); -#if HERMES_INTERCEPT == 1 - HERMES_CLIENT_CONF.SetAdapterPathTracking(TEST_INFO->existing_file_cmp, false); - HERMES_CLIENT_CONF.SetAdapterPathTracking(TEST_INFO->new_file_cmp, false); - HERMES_CLIENT_CONF.SetAdapterPathTracking( - TEST_INFO->existing_shared_file_cmp, false); -#endif - return 0; -} - -void Clear() { -#if HERMES_INTERCEPT == 1 - HERMES->Clear(); -#endif -} - -int posttest(bool compare_data = true) { -#if HERMES_INTERCEPT == 1 - HERMES_CLIENT_CONF.SetAdapterPathTracking(TEST_INFO->existing_file, false); - HERMES_CLIENT_CONF.SetAdapterPathTracking(TEST_INFO->new_file, false); - HERMES_CLIENT_CONF.SetAdapterPathTracking( - TEST_INFO->existing_shared_file, false); -#endif - if (compare_data && stdfs::exists(TEST_INFO->new_file) && - stdfs::exists(TEST_INFO->new_file_cmp)) { - size_t size = stdfs::file_size(TEST_INFO->new_file); - REQUIRE(size == stdfs::file_size(TEST_INFO->new_file_cmp)); - if (size > 0) { - std::vector d1(size, '0'); - std::vector d2(size, '1'); - - FILE* fh1 = fopen(TEST_INFO->new_file_.hermes_.c_str(), "r"); - REQUIRE(fh1 != nullptr); - size_t read_d1 = fread(d1.data(), size, sizeof(unsigned char), fh1); - REQUIRE(read_d1 == sizeof(unsigned char)); - int status = fclose(fh1); - REQUIRE(status == 0); - - FILE* fh2 = fopen(TEST_INFO->new_file_cmp.c_str(), "r"); - REQUIRE(fh2 != nullptr); - size_t read_d2 = fread(d2.data(), size, sizeof(unsigned char), fh2); - REQUIRE(read_d2 == sizeof(unsigned char)); - status = fclose(fh2); - REQUIRE(status == 0); - - size_t char_mismatch = 0; - for (size_t pos = 0; pos < size; ++pos) { - if (d1[pos] != d2[pos]) char_mismatch++; - } - REQUIRE(char_mismatch == 0); - } - } - if (compare_data && stdfs::exists(TEST_INFO->existing_file) && - stdfs::exists(TEST_INFO->existing_file_cmp)) { - size_t size = stdfs::file_size(TEST_INFO->existing_file); - if (size != stdfs::file_size(TEST_INFO->existing_file_cmp)) sleep(1); - REQUIRE(size == stdfs::file_size(TEST_INFO->existing_file_cmp)); - if (size > 0) { - std::vector d1(size, '0'); - std::vector d2(size, '1'); - - FILE* fh1 = fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r"); - REQUIRE(fh1 != nullptr); - size_t read_d1 = fread(d1.data(), size, sizeof(unsigned char), fh1); - REQUIRE(read_d1 == sizeof(unsigned char)); - int status = fclose(fh1); - REQUIRE(status == 0); - - FILE* fh2 = fopen(TEST_INFO->existing_file_cmp.c_str(), "r"); - REQUIRE(fh2 != nullptr); - size_t read_d2 = fread(d2.data(), size, sizeof(unsigned char), fh2); - REQUIRE(read_d2 == sizeof(unsigned char)); - status = fclose(fh2); - REQUIRE(status == 0); - size_t char_mismatch = 0; - for (size_t pos = 0; pos < size; ++pos) { - if (d1[pos] != d2[pos]) char_mismatch++; - } - REQUIRE(char_mismatch == 0); - } - } - if (compare_data && stdfs::exists(TEST_INFO->existing_shared_file) && - stdfs::exists(TEST_INFO->existing_shared_file_cmp)) { - size_t size = stdfs::file_size(TEST_INFO->existing_shared_file); - if (size != stdfs::file_size(TEST_INFO->existing_shared_file_cmp)) sleep(1); - REQUIRE(size == stdfs::file_size(TEST_INFO->existing_shared_file_cmp)); - if (size > 0) { - std::vector d1(size, '0'); - std::vector d2(size, '1'); - - FILE* fh1 = fopen(TEST_INFO->existing_shared_file.c_str(), "r"); - REQUIRE(fh1 != nullptr); - size_t read_d1 = fread(d1.data(), size, sizeof(unsigned char), fh1); - REQUIRE(read_d1 == sizeof(unsigned char)); - int status = fclose(fh1); - REQUIRE(status == 0); - - FILE* fh2 = fopen(TEST_INFO->existing_shared_file_cmp.c_str(), "r"); - REQUIRE(fh2 != nullptr); - size_t read_d2 = fread(d2.data(), size, sizeof(unsigned char), fh2); - REQUIRE(read_d2 == sizeof(unsigned char)); - status = fclose(fh2); - REQUIRE(status == 0); - size_t char_mismatch = 0; - for (size_t pos = 0; pos < size; ++pos) { - if (d1[pos] != d2[pos]) char_mismatch++; - } - REQUIRE(char_mismatch == 0); - } - } - /* Clean up. */ - if (stdfs::exists(TEST_INFO->new_file)) stdfs::remove(TEST_INFO->new_file); - if (stdfs::exists(TEST_INFO->existing_file)) stdfs::remove(TEST_INFO->existing_file); - if (stdfs::exists(TEST_INFO->new_file_cmp)) stdfs::remove(TEST_INFO->new_file_cmp); - if (stdfs::exists(TEST_INFO->existing_file_cmp)) - stdfs::remove(TEST_INFO->existing_file_cmp); - MPI_Barrier(MPI_COMM_WORLD); - if (TEST_INFO->rank == 0) { - if (stdfs::exists(TEST_INFO->existing_shared_file)) - stdfs::remove(TEST_INFO->existing_shared_file); - if (stdfs::exists(TEST_INFO->existing_shared_file_cmp)) - stdfs::remove(TEST_INFO->existing_shared_file_cmp); - } - Clear(); - -#if HERMES_INTERCEPT == 1 - HERMES_CLIENT_CONF.SetAdapterPathTracking(TEST_INFO->existing_file_cmp, true); - HERMES_CLIENT_CONF.SetAdapterPathTracking(TEST_INFO->new_file_cmp, true); - HERMES_CLIENT_CONF.SetAdapterPathTracking(TEST_INFO->new_file, true); - HERMES_CLIENT_CONF.SetAdapterPathTracking(TEST_INFO->existing_file, true); - HERMES_CLIENT_CONF.SetAdapterPathTracking( - TEST_INFO->existing_shared_file, true); - HERMES_CLIENT_CONF.SetAdapterPathTracking( - TEST_INFO->existing_shared_file_cmp, true); -#endif - return 0; -} - -cl::Parser define_options() { - return cl::Opt(args.filename, "filename")["-f"]["--filename"]( - "Filename used for performing I/O") | - cl::Opt(args.directory, "dir")["-d"]["--directory"]( - "Directory used for performing I/O") | - cl::Opt(TEST_INFO->request_size_, "request_size")["-s"]["--request_size"]( - "Request size used for performing I/O"); -} - -#include "stdio_adapter_basic_test.cc" -#include "stdio_adapter_func_test.cc" -#include "stdio_adapter_rs_test.cc" -// #include "stdio_adapter_shared_test.cpp" diff --git a/test/unit/hermes_adapters/stdio/stdio_adapter_rs_test.cc b/test/unit/hermes_adapters/stdio/stdio_adapter_rs_test.cc index 324d8dfe6..179924ea4 100644 --- a/test/unit/hermes_adapters/stdio/stdio_adapter_rs_test.cc +++ b/test/unit/hermes_adapters/stdio/stdio_adapter_rs_test.cc @@ -9,1239 +9,1279 @@ * the COPYING file, which can be found at the top directory. If you do not * * have access to the file, you may request a copy from help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +#include "stdio_adapter_test.h" TEST_CASE("BatchedWriteRSRangeSmall", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "" "[operation=batched_write]" "[request_size=range-small][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("write to new file always at the start") { - test::test_fopen(TEST_INFO->new_file_.hermes_.c_str(), "w+"); - REQUIRE(test::fh_orig != nullptr); + TESTER->test_fopen(TESTER->new_file_, "w+"); + REQUIRE(TESTER->fh_orig_ != nullptr); size_t biggest_written = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - test::test_fseek(0, SEEK_SET); - REQUIRE(test::status_orig == 0); - size_t offset = ftell(test::fh_orig); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_fseek(0, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + size_t offset = ftell(TESTER->fh_orig_); REQUIRE(offset == 0); size_t request_size = - TEST_INFO->small_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->small_max); + TESTER->small_min_ + (rand_r(&TESTER->rs_seed_) % TESTER->small_max_); std::string data(request_size, '1'); - test::test_fwrite(data.data(), request_size); - REQUIRE(test::size_written_orig == request_size); + TESTER->test_fwrite(data.data(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); if (biggest_written < request_size) biggest_written = request_size; } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - REQUIRE(stdfs::file_size(TEST_INFO->new_file) == biggest_written); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_) == biggest_written); } SECTION("write to new file") { - test::test_fopen(TEST_INFO->new_file_.hermes_.c_str(), "w+"); - REQUIRE(test::fh_orig != nullptr); + TESTER->test_fopen(TESTER->new_file_, "w+"); + REQUIRE(TESTER->fh_orig_ != nullptr); size_t total_written = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t request_size = - TEST_INFO->small_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->small_max); + TESTER->small_min_ + (rand_r(&TESTER->rs_seed_) % TESTER->small_max_); std::string data(request_size, '1'); - test::test_fwrite(data.data(), request_size); - REQUIRE(test::size_written_orig == request_size); - total_written += test::size_written_orig; + TESTER->test_fwrite(data.data(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); + total_written += TESTER->size_written_orig_; } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - REQUIRE(stdfs::file_size(TEST_INFO->new_file) == total_written); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_) == total_written); } - posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadSequentialRSRangeSmall", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=range-small][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - test::test_fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r"); - REQUIRE(test::fh_orig != nullptr); - std::string data(TEST_INFO->request_size_, '1'); + TESTER->test_fopen(TESTER->existing_file_, "r"); + REQUIRE(TESTER->fh_orig_ != nullptr); + std::string data(TESTER->request_size_, '1'); size_t current_offset = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t request_size = - TEST_INFO->small_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->small_max); + TESTER->small_min_ + (rand_r(&TESTER->rs_seed_) % TESTER->small_max_); std::string data(request_size, '1'); - test::test_fread(data.data(), request_size); - REQUIRE(test::size_read_orig == request_size); - current_offset += test::size_read_orig; + TESTER->test_fread(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); + current_offset += TESTER->size_read_orig_; } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("read from existing file always at start") { - test::test_fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r"); - REQUIRE(test::fh_orig != nullptr); + TESTER->test_fopen(TESTER->existing_file_, "r"); + REQUIRE(TESTER->fh_orig_ != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - test::test_fseek(0, SEEK_SET); - REQUIRE(test::status_orig == 0); - size_t offset = ftell(test::fh_orig); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_fseek(0, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + size_t offset = ftell(TESTER->fh_orig_); REQUIRE(offset == 0); size_t request_size = - TEST_INFO->small_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->small_max); + TESTER->small_min_ + (rand_r(&TESTER->rs_seed_) % TESTER->small_max_); std::string data(request_size, '1'); - test::test_fread(data.data(), request_size); - REQUIRE(test::size_read_orig == request_size); + TESTER->test_fread(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadRandomRSRangeSmall", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=range-small]" "[repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "][pattern=random][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - test::test_fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { auto offset = - rand_r(&TEST_INFO->offset_seed) % (TEST_INFO->total_size_ - TEST_INFO->small_max); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); + rand_r(&TESTER->offset_seed_) % + (TESTER->total_size_ - TESTER->small_max_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->small_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->small_max); + TESTER->small_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->small_max_); std::string data(request_size, '1'); - test::test_fread(data.data(), request_size); - REQUIRE(test::size_read_orig == request_size); + TESTER->test_fread(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateRandomRSRangeSmall", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=range-small][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=random][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - test::test_fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { auto offset = - rand_r(&TEST_INFO->offset_seed) % (TEST_INFO->total_size_ - TEST_INFO->small_max); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); + rand_r(&TESTER->offset_seed_) % + (TESTER->total_size_ - TESTER->small_max_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->small_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->small_max); + TESTER->small_min_ + (rand_r(&TESTER->rs_seed_) % TESTER->small_max_); std::string data(request_size, '1'); - test::test_fwrite(data.data(), request_size); - REQUIRE(test::size_written_orig == request_size); + TESTER->test_fwrite(data.data(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadStrideFixedRSRangeSmall", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=range-small][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_fixed][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - test::test_fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - auto offset = (i * TEST_INFO->stride_size) % (TEST_INFO->total_size_ - TEST_INFO->small_max); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + auto offset = (i * TESTER->stride_size_) % + (TESTER->total_size_ - TESTER->small_max_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->small_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->small_max); + TESTER->small_min_ + (rand_r(&TESTER->rs_seed_) % TESTER->small_max_); std::string data(request_size, '1'); - test::test_fread(data.data(), request_size); - REQUIRE(test::size_read_orig == request_size); + TESTER->test_fread(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStrideFixedRSRangeSmall", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=range-small][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_fixed][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("write to existing file") { - test::test_fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - auto offset = (i * TEST_INFO->stride_size) % (TEST_INFO->total_size_ - TEST_INFO->small_max); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + auto offset = (i * TESTER->stride_size_) % + (TESTER->total_size_ - TESTER->small_max_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->small_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->small_max); + TESTER->small_min_ + (rand_r(&TESTER->rs_seed_) % TESTER->small_max_); std::string data(request_size, '1'); - test::test_fwrite(data.data(), request_size); - REQUIRE(test::size_written_orig == request_size); + TESTER->test_fwrite(data.data(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadStrideDynamicRSRangeSmall", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=range-small][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_dynamic][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - test::test_fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - auto offset = GetRandomOffset(i, TEST_INFO->offset_seed, TEST_INFO->stride_size, - TEST_INFO->total_size_ - TEST_INFO->small_max); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + auto offset = TESTER->GetRandomOffset( + i, TESTER->offset_seed_, TESTER->stride_size_, + TESTER->total_size_ - TESTER->small_max_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->small_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->small_max); + TESTER->small_min_ + (rand_r(&TESTER->rs_seed_) % TESTER->small_max_); std::string data(request_size, '1'); - test::test_fread(data.data(), request_size); - REQUIRE(test::size_read_orig == request_size); + TESTER->test_fread(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStrideDynamicRSRangeSmall", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=range-small][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_dynamic][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - test::test_fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - auto offset = GetRandomOffset(i, TEST_INFO->offset_seed, TEST_INFO->stride_size, - TEST_INFO->total_size_ - TEST_INFO->small_max); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + auto offset = TESTER->GetRandomOffset( + i, TESTER->offset_seed_, TESTER->stride_size_, + TESTER->total_size_ - TESTER->small_max_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->small_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->small_max); + TESTER->small_min_ + (rand_r(&TESTER->rs_seed_) % TESTER->small_max_); std::string data(request_size, '1'); - test::test_fwrite(data.data(), request_size); - REQUIRE(test::size_written_orig == request_size); + TESTER->test_fwrite(data.data(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadStrideNegativeRSRangeSmall", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=range-small][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_negative][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - test::test_fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - auto offset = (TEST_INFO->total_size_ - i * TEST_INFO->stride_size) % - (TEST_INFO->total_size_ - TEST_INFO->small_max); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + auto offset = (TESTER->total_size_ - i * TESTER->stride_size_) % + (TESTER->total_size_ - TESTER->small_max_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->small_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->small_max); + TESTER->small_min_ + (rand_r(&TESTER->rs_seed_) % TESTER->small_max_); std::string data(request_size, '1'); - test::test_fread(data.data(), request_size); - REQUIRE(test::size_read_orig == request_size); + TESTER->test_fread(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStrideNegativeRSRangeSmall", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "" "[operation=batched_write]" "[request_size=range-small][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_negative][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("write to existing file") { - test::test_fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - auto offset = TEST_INFO->total_size_ - ((i * TEST_INFO->stride_size) % - (TEST_INFO->total_size_ - TEST_INFO->small_max)); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + auto offset = TESTER->total_size_ - ((i * TESTER->stride_size_) % + (TESTER->total_size_ - TESTER->small_max_)); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->small_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->small_max); + TESTER->small_min_ + (rand_r(&TESTER->rs_seed_) % TESTER->small_max_); std::string data(request_size, '1'); - test::test_fwrite(data.data(), request_size); - REQUIRE(test::size_written_orig == request_size); + TESTER->test_fwrite(data.data(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadStride2DRSRangeSmall", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=range-small][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_2d][file=1]") { - TEST_INFO->Pretest(); - size_t rows = sqrt(TEST_INFO->total_size_); + TESTER->Pretest(); + size_t rows = sqrt(TESTER->total_size_); size_t cols = rows; - REQUIRE(rows * cols == TEST_INFO->total_size_); + REQUIRE(rows * cols == TESTER->total_size_); size_t cell_size = 128; - size_t cell_stride = rows * cols / cell_size / TEST_INFO->num_iterations_; + size_t cell_stride = rows * cols / cell_size / TESTER->num_iterations_; SECTION("read from existing file") { - test::test_fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); size_t prev_cell_col = 0, prev_cell_row = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t current_cell_col = (prev_cell_col + cell_stride) % cols; size_t current_cell_row = prev_cell_col + cell_stride > cols - ? prev_cell_row + 1 - : prev_cell_row; + ? prev_cell_row + 1 + : prev_cell_row; prev_cell_row = current_cell_row; auto offset = (current_cell_col * cell_stride + prev_cell_row * cols) % - (TEST_INFO->total_size_ - TEST_INFO->small_max); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); + (TESTER->total_size_ - TESTER->small_max_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->small_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->small_max); + TESTER->small_min_ + (rand_r(&TESTER->rs_seed_) % TESTER->small_max_); std::string data(request_size, '1'); - test::test_fread(data.data(), request_size); - REQUIRE(test::size_read_orig == request_size); + TESTER->test_fread(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStride2DRSRangeSmall", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=range-small][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_2d][file=1]") { - TEST_INFO->Pretest(); - size_t rows = sqrt(TEST_INFO->total_size_); + TESTER->Pretest(); + size_t rows = sqrt(TESTER->total_size_); size_t cols = rows; - REQUIRE(rows * cols == TEST_INFO->total_size_); + REQUIRE(rows * cols == TESTER->total_size_); size_t cell_size = 128; - size_t cell_stride = rows * cols / cell_size / TEST_INFO->num_iterations_; + size_t cell_stride = rows * cols / cell_size / TESTER->num_iterations_; SECTION("write to existing file") { - test::test_fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); size_t prev_cell_col = 0, prev_cell_row = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t current_cell_col = (prev_cell_col + cell_stride) % cols; size_t current_cell_row = prev_cell_col + cell_stride > cols - ? prev_cell_row + 1 - : prev_cell_row; + ? prev_cell_row + 1 + : prev_cell_row; prev_cell_row = current_cell_row; auto offset = (current_cell_col * cell_stride + prev_cell_row * cols) % - (TEST_INFO->total_size_ - TEST_INFO->small_max); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); + (TESTER->total_size_ - TESTER->small_max_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->small_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->small_max); + TESTER->small_min_ + (rand_r(&TESTER->rs_seed_) % TESTER->small_max_); std::string data(request_size, '1'); - test::test_fwrite(data.data(), request_size); - REQUIRE(test::size_written_orig == request_size); + TESTER->test_fwrite(data.data(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - posttest(); + TESTER->Posttest(); } /** * Medium RS **/ TEST_CASE("BatchedWriteRSRangeMedium", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=range-medium][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("write to new file always at the start") { - test::test_fopen(TEST_INFO->new_file_.hermes_.c_str(), "w+"); - REQUIRE(test::fh_orig != nullptr); + TESTER->test_fopen(TESTER->new_file_, "w+"); + REQUIRE(TESTER->fh_orig_ != nullptr); size_t biggest_written = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - test::test_fseek(0, SEEK_SET); - REQUIRE(test::status_orig == 0); - size_t offset = ftell(test::fh_orig); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_fseek(0, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + size_t offset = ftell(TESTER->fh_orig_); REQUIRE(offset == 0); size_t request_size = - TEST_INFO->medium_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->medium_max); + TESTER->medium_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->medium_max_); std::string data(request_size, '1'); - test::test_fwrite(data.data(), request_size); - REQUIRE(test::size_written_orig == request_size); + TESTER->test_fwrite(data.data(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); if (biggest_written < request_size) biggest_written = request_size; } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - REQUIRE(stdfs::file_size(TEST_INFO->new_file) == biggest_written); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_) == biggest_written); } SECTION("write to new file") { - test::test_fopen(TEST_INFO->new_file_.hermes_.c_str(), "w+"); - REQUIRE(test::fh_orig != nullptr); + TESTER->test_fopen(TESTER->new_file_, "w+"); + REQUIRE(TESTER->fh_orig_ != nullptr); size_t total_written = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t request_size = - TEST_INFO->medium_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->medium_max); + TESTER->medium_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->medium_max_); std::string data(request_size, '1'); - test::test_fwrite(data.data(), request_size); - REQUIRE(test::size_written_orig == request_size); - total_written += test::size_written_orig; + TESTER->test_fwrite(data.data(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); + total_written += TESTER->size_written_orig_; } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadSequentialRSRangeMedium", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=range-medium][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - test::test_fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r"); - REQUIRE(test::fh_orig != nullptr); - std::string data(TEST_INFO->request_size_, '1'); + TESTER->test_fopen(TESTER->existing_file_, "r"); + REQUIRE(TESTER->fh_orig_ != nullptr); + std::string data(TESTER->request_size_, '1'); size_t current_offset = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t request_size = - (TEST_INFO->medium_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->medium_max)) % - (TEST_INFO->total_size_ - current_offset); + (TESTER->medium_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->medium_max_)) % + (TESTER->total_size_ - current_offset); std::string data(request_size, '1'); - test::test_fread(data.data(), request_size); - REQUIRE(test::size_read_orig == request_size); - current_offset += test::size_read_orig; + TESTER->test_fread(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); + current_offset += TESTER->size_read_orig_; } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("read from existing file always at start") { - test::test_fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r"); - REQUIRE(test::fh_orig != nullptr); + TESTER->test_fopen(TESTER->existing_file_, "r"); + REQUIRE(TESTER->fh_orig_ != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - test::test_fseek(0, SEEK_SET); - REQUIRE(test::status_orig == 0); - size_t offset = ftell(test::fh_orig); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_fseek(0, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + size_t offset = ftell(TESTER->fh_orig_); REQUIRE(offset == 0); size_t request_size = - TEST_INFO->medium_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->medium_max); + TESTER->medium_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->medium_max_); std::string data(request_size, '1'); - test::test_fread(data.data(), request_size); - REQUIRE(test::size_read_orig == request_size); + TESTER->test_fread(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadRandomRSRangeMedium", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=range-medium]" "[repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "][pattern=random][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - test::test_fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { auto offset = - rand_r(&TEST_INFO->offset_seed) % (TEST_INFO->total_size_ - TEST_INFO->medium_max); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); + rand_r(&TESTER->offset_seed_) % + (TESTER->total_size_ - TESTER->medium_max_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->medium_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->medium_max); + TESTER->medium_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->medium_max_); std::string data(request_size, '1'); - test::test_fread(data.data(), request_size); - REQUIRE(test::size_read_orig == request_size); + TESTER->test_fread(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateRandomRSRangeMedium", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=range-medium][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=random][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - test::test_fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { auto offset = - rand_r(&TEST_INFO->offset_seed) % (TEST_INFO->total_size_ - TEST_INFO->medium_max); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); + rand_r(&TESTER->offset_seed_) % + (TESTER->total_size_ - TESTER->medium_max_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->medium_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->medium_max); + TESTER->medium_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->medium_max_); std::string data(request_size, '1'); - test::test_fwrite(data.data(), request_size); - REQUIRE(test::size_written_orig == request_size); + TESTER->test_fwrite(data.data(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadStrideFixedRSRangeMedium", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=range-medium][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_fixed][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - test::test_fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { auto offset = - (i * TEST_INFO->stride_size) % (TEST_INFO->total_size_ - TEST_INFO->medium_max); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); + (i * TESTER->stride_size_) % + (TESTER->total_size_ - TESTER->medium_max_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->medium_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->medium_max); + TESTER->medium_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->medium_max_); std::string data(request_size, '1'); - test::test_fread(data.data(), request_size); - REQUIRE(test::size_read_orig == request_size); + TESTER->test_fread(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStrideFixedRSRangeMedium", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=range-medium][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_fixed][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("write to existing file") { - test::test_fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { auto offset = - (i * TEST_INFO->stride_size) % (TEST_INFO->total_size_ - TEST_INFO->medium_max); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); + (i * TESTER->stride_size_) % + (TESTER->total_size_ - TESTER->medium_max_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->medium_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->medium_max); + TESTER->medium_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->medium_max_); std::string data(request_size, '1'); - test::test_fwrite(data.data(), request_size); - REQUIRE(test::size_written_orig == request_size); + TESTER->test_fwrite(data.data(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadStrideDynamicRSRangeMedium", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=range-medium][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_dynamic][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - test::test_fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - auto offset = GetRandomOffset(i, TEST_INFO->offset_seed, TEST_INFO->stride_size, - TEST_INFO->total_size_ - TEST_INFO->medium_max); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + auto offset = TESTER->GetRandomOffset( + i, TESTER->offset_seed_, TESTER->stride_size_, + TESTER->total_size_ - TESTER->medium_max_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->medium_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->medium_max); + TESTER->medium_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->medium_max_); std::string data(request_size, '1'); - test::test_fread(data.data(), request_size); - REQUIRE(test::size_read_orig == request_size); + TESTER->test_fread(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStrideDynamicRSRangeMedium", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=range-medium][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_dynamic][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - test::test_fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - auto offset = GetRandomOffset(i, TEST_INFO->offset_seed, TEST_INFO->stride_size, - TEST_INFO->total_size_ - TEST_INFO->medium_max); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + auto offset = TESTER->GetRandomOffset( + i, TESTER->offset_seed_, TESTER->stride_size_, + TESTER->total_size_ - TESTER->medium_max_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->medium_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->medium_max); + TESTER->medium_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->medium_max_); std::string data(request_size, '1'); - test::test_fwrite(data.data(), request_size); - REQUIRE(test::size_written_orig == request_size); + TESTER->test_fwrite(data.data(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadStrideNegativeRSRangeMedium", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=range-medium][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_negative][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - test::test_fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - auto offset = (TEST_INFO->total_size_ - i * TEST_INFO->stride_size) % - (TEST_INFO->total_size_ - TEST_INFO->medium_max); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + auto offset = (TESTER->total_size_ - i * TESTER->stride_size_) % + (TESTER->total_size_ - TESTER->medium_max_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->medium_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->medium_max); + TESTER->medium_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->medium_max_); std::string data(request_size, '1'); - test::test_fread(data.data(), request_size); - REQUIRE(test::size_read_orig == request_size); + TESTER->test_fread(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStrideNegativeRSRangeMedium", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=range-medium][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_negative][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("write to existing file") { - test::test_fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - auto offset = TEST_INFO->total_size_ - ((i * TEST_INFO->stride_size) % - (TEST_INFO->total_size_ - TEST_INFO->medium_max)); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + auto offset = TESTER->total_size_ - ((i * TESTER->stride_size_) % + (TESTER->total_size_ - TESTER->medium_max_)); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->medium_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->medium_max); + TESTER->medium_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->medium_max_); std::string data(request_size, '1'); - test::test_fwrite(data.data(), request_size); - REQUIRE(test::size_written_orig == request_size); + TESTER->test_fwrite(data.data(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadStride2DRSRangeMedium", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=range-medium][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_2d][file=1]") { - TEST_INFO->Pretest(); - size_t rows = sqrt(TEST_INFO->total_size_); + TESTER->Pretest(); + size_t rows = sqrt(TESTER->total_size_); size_t cols = rows; - REQUIRE(rows * cols == TEST_INFO->total_size_); + REQUIRE(rows * cols == TESTER->total_size_); size_t cell_size = 128; - size_t cell_stride = rows * cols / cell_size / TEST_INFO->num_iterations_; + size_t cell_stride = rows * cols / cell_size / TESTER->num_iterations_; SECTION("read from existing file") { - test::test_fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); size_t prev_cell_col = 0, prev_cell_row = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t current_cell_col = (prev_cell_col + cell_stride) % cols; size_t current_cell_row = prev_cell_col + cell_stride > cols - ? prev_cell_row + 1 - : prev_cell_row; + ? prev_cell_row + 1 + : prev_cell_row; prev_cell_row = current_cell_row; auto offset = (current_cell_col * cell_stride + prev_cell_row * cols) % - (TEST_INFO->total_size_ - TEST_INFO->medium_max); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); + (TESTER->total_size_ - TESTER->medium_max_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->medium_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->medium_max); + TESTER->medium_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->medium_max_); std::string data(request_size, '1'); - test::test_fread(data.data(), request_size); - REQUIRE(test::size_read_orig == request_size); + TESTER->test_fread(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStride2DRSRangeMedium", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=range-medium][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_2d][file=1]") { - TEST_INFO->Pretest(); - size_t rows = sqrt(TEST_INFO->total_size_); + TESTER->Pretest(); + size_t rows = sqrt(TESTER->total_size_); size_t cols = rows; - REQUIRE(rows * cols == TEST_INFO->total_size_); + REQUIRE(rows * cols == TESTER->total_size_); size_t cell_size = 128; - size_t cell_stride = rows * cols / cell_size / TEST_INFO->num_iterations_; + size_t cell_stride = rows * cols / cell_size / TESTER->num_iterations_; SECTION("write to existing file") { - test::test_fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); size_t prev_cell_col = 0, prev_cell_row = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t current_cell_col = (prev_cell_col + cell_stride) % cols; size_t current_cell_row = prev_cell_col + cell_stride > cols - ? prev_cell_row + 1 - : prev_cell_row; + ? prev_cell_row + 1 + : prev_cell_row; prev_cell_row = current_cell_row; auto offset = (current_cell_col * cell_stride + prev_cell_row * cols) % - (TEST_INFO->total_size_ - TEST_INFO->medium_max); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); + (TESTER->total_size_ - TESTER->medium_max_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->medium_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->medium_max); + TESTER->medium_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->medium_max_); std::string data(request_size, '1'); - test::test_fwrite(data.data(), request_size); - REQUIRE(test::size_written_orig == request_size); + TESTER->test_fwrite(data.data(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - posttest(); + TESTER->Posttest(); } /** * Large RS **/ TEST_CASE("BatchedWriteRSRangeLarge", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=range-large][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("write to new file always at the start") { - test::test_fopen(TEST_INFO->new_file_.hermes_.c_str(), "w+"); - REQUIRE(test::fh_orig != nullptr); + TESTER->test_fopen(TESTER->new_file_, "w+"); + REQUIRE(TESTER->fh_orig_ != nullptr); size_t biggest_written = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - test::test_fseek(0, SEEK_SET); - REQUIRE(test::status_orig == 0); - size_t offset = ftell(test::fh_orig); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_fseek(0, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + size_t offset = ftell(TESTER->fh_orig_); REQUIRE(offset == 0); size_t request_size = - TEST_INFO->large_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->large_max); + TESTER->large_min_ + (rand_r(&TESTER->rs_seed_) % TESTER->large_max_); std::string data(request_size, '1'); - test::test_fwrite(data.data(), request_size); - REQUIRE(test::size_written_orig == request_size); + TESTER->test_fwrite(data.data(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); if (biggest_written < request_size) biggest_written = request_size; } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("write to new file") { - test::test_fopen(TEST_INFO->new_file_.hermes_.c_str(), "w+"); - REQUIRE(test::fh_orig != nullptr); + TESTER->test_fopen(TESTER->new_file_, "w+"); + REQUIRE(TESTER->fh_orig_ != nullptr); size_t total_written = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t request_size = - TEST_INFO->large_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->large_max); + TESTER->large_min_ + (rand_r(&TESTER->rs_seed_) % TESTER->large_max_); std::string data(request_size, '1'); - test::test_fwrite(data.data(), request_size); - REQUIRE(test::size_written_orig == request_size); - total_written += test::size_written_orig; + TESTER->test_fwrite(data.data(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); + total_written += TESTER->size_written_orig_; } - test::test_fclose(); - REQUIRE(test::status_orig == 0); - REQUIRE(stdfs::file_size(TEST_INFO->new_file) == total_written); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); + REQUIRE(stdfs::file_size(TESTER->new_file_.hermes_) == total_written); } - posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadSequentialRSRangeLarge", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=range-large][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - test::test_fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r"); - REQUIRE(test::fh_orig != nullptr); - std::string data(TEST_INFO->request_size_, '1'); + TESTER->test_fopen(TESTER->existing_file_, "r"); + REQUIRE(TESTER->fh_orig_ != nullptr); + std::string data(TESTER->request_size_, '1'); size_t current_offset = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t request_size = - (TEST_INFO->large_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->large_max)) % - (TEST_INFO->total_size_ - current_offset); + (TESTER->large_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->large_max_)) % + (TESTER->total_size_ - current_offset); std::string data(request_size, '1'); - test::test_fread(data.data(), request_size); - REQUIRE(test::size_read_orig == request_size); - current_offset += test::size_read_orig; + TESTER->test_fread(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); + current_offset += TESTER->size_read_orig_; } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } SECTION("read from existing file always at start") { - test::test_fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r"); - REQUIRE(test::fh_orig != nullptr); + TESTER->test_fopen(TESTER->existing_file_, "r"); + REQUIRE(TESTER->fh_orig_ != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - test::test_fseek(0, SEEK_SET); - REQUIRE(test::status_orig == 0); - size_t offset = ftell(test::fh_orig); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_fseek(0, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); + size_t offset = ftell(TESTER->fh_orig_); REQUIRE(offset == 0); size_t request_size = - TEST_INFO->large_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->large_max); + TESTER->large_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->large_max_); std::string data(request_size, '1'); - test::test_fread(data.data(), request_size); - REQUIRE(test::size_read_orig == request_size); + TESTER->test_fread(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadRandomRSRangeLarge", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=range-large]" "[repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "][pattern=random][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - test::test_fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { auto offset = - rand_r(&TEST_INFO->offset_seed) % (TEST_INFO->total_size_ - TEST_INFO->large_max); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); + rand_r(&TESTER->offset_seed_) % + (TESTER->total_size_ - TESTER->large_max_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - (TEST_INFO->large_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->large_max)) % - (TEST_INFO->total_size_ - offset); + (TESTER->large_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->large_max_)) % + (TESTER->total_size_ - offset); std::string data(request_size, '1'); - test::test_fread(data.data(), request_size); - REQUIRE(test::size_read_orig == request_size); + TESTER->test_fread(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateRandomRSRangeLarge", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=range-large][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=random][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("write into existing file") { - test::test_fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { auto offset = - rand_r(&TEST_INFO->offset_seed) % (TEST_INFO->total_size_ - TEST_INFO->large_max); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); + rand_r(&TESTER->offset_seed_) % + (TESTER->total_size_ - TESTER->large_max_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->large_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->large_max); - std::string data = GenRandom(request_size); - test::test_fwrite(data.data(), request_size); - REQUIRE(test::size_written_orig == request_size); + TESTER->large_min_ + (rand_r(&TESTER->rs_seed_) % TESTER->large_max_); + std::vector data = TESTER->GenRandom(request_size); + TESTER->test_fwrite(data.data(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadStrideFixedRSRangeLarge", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=range-large][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_fixed][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - test::test_fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - auto offset = (i * TEST_INFO->stride_size) % (TEST_INFO->total_size_ - TEST_INFO->large_max); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + auto offset = (i * TESTER->stride_size_) % + (TESTER->total_size_ - TESTER->large_max_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->large_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->large_max); + TESTER->large_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->large_max_); std::string data(request_size, '1'); - test::test_fread(data.data(), request_size); - REQUIRE(test::size_read_orig == request_size); + TESTER->test_fread(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStrideFixedRSRangeLarge", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=range-large][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_fixed][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("write to existing file") { - test::test_fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - auto offset = (i * TEST_INFO->stride_size) % (TEST_INFO->total_size_ - TEST_INFO->large_max); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + auto offset = (i * TESTER->stride_size_) % + (TESTER->total_size_ - TESTER->large_max_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->large_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->large_max); + TESTER->large_min_ + (rand_r(&TESTER->rs_seed_) % TESTER->large_max_); std::string data(request_size, '1'); - test::test_fwrite(data.data(), request_size); - REQUIRE(test::size_written_orig == request_size); + TESTER->test_fwrite(data.data(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadStrideDynamicRSRangeLarge", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=range-large][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_dynamic][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - test::test_fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - auto offset = GetRandomOffset(i, TEST_INFO->offset_seed, TEST_INFO->stride_size, - TEST_INFO->total_size_ - TEST_INFO->large_max); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + auto offset = TESTER->GetRandomOffset( + i, TESTER->offset_seed_, TESTER->stride_size_, + TESTER->total_size_ - TESTER->large_max_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->large_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->large_max); + TESTER->large_min_ + (rand_r(&TESTER->rs_seed_) % TESTER->large_max_); std::string data(request_size, '1'); - test::test_fread(data.data(), request_size); - REQUIRE(test::size_read_orig == request_size); + TESTER->test_fread(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStrideDynamicRSRangeLarge", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=range-large][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_dynamic][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - test::test_fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - auto offset = GetRandomOffset(i, TEST_INFO->offset_seed, TEST_INFO->stride_size, - TEST_INFO->total_size_ - TEST_INFO->large_max); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + auto offset = TESTER->GetRandomOffset( + i, TESTER->offset_seed_, + TESTER->stride_size_, + TESTER->total_size_ - TESTER->large_max_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->large_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->large_max); + TESTER->large_min_ + (rand_r(&TESTER->rs_seed_) % TESTER->large_max_); std::string data(request_size, '1'); - test::test_fwrite(data.data(), request_size); - REQUIRE(test::size_written_orig == request_size); + TESTER->test_fwrite(data.data(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadStrideNegativeRSRangeLarge", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=range-large][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_negative][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - test::test_fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - auto offset = (TEST_INFO->total_size_ - i * TEST_INFO->stride_size) % - (TEST_INFO->total_size_ - TEST_INFO->large_max); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + auto offset = (TESTER->total_size_ - i * TESTER->stride_size_) % + (TESTER->total_size_ - TESTER->large_max_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - (TEST_INFO->large_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->large_max)) % - (TEST_INFO->total_size_ - TEST_INFO->large_max); + (TESTER->large_min_ + + (rand_r(&TESTER->rs_seed_) % TESTER->large_max_)) % + (TESTER->total_size_ - TESTER->large_max_); std::string data(request_size, '1'); - test::test_fread(data.data(), request_size); - REQUIRE(test::size_read_orig == request_size); + TESTER->test_fread(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStrideNegativeRSRangeLarge", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=range-large][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_negative][file=1]") { - TEST_INFO->Pretest(); + TESTER->Pretest(); SECTION("write to existing file") { - test::test_fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - auto offset = TEST_INFO->total_size_ - ((i * TEST_INFO->stride_size) % - (TEST_INFO->total_size_ - TEST_INFO->large_max)); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + auto offset = TESTER->total_size_ - ((i * TESTER->stride_size_) % + (TESTER->total_size_ - TESTER->large_max_)); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->large_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->large_max); + TESTER->large_min_ + (rand_r(&TESTER->rs_seed_) % TESTER->large_max_); std::string data(request_size, '1'); - test::test_fwrite(data.data(), request_size); - REQUIRE(test::size_written_orig == request_size); + TESTER->test_fwrite(data.data(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadStride2DRSRangeLarge", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=range-large][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_2d][file=1]") { - TEST_INFO->Pretest(); - size_t rows = sqrt(TEST_INFO->total_size_); + TESTER->Pretest(); + size_t rows = sqrt(TESTER->total_size_); size_t cols = rows; - REQUIRE(rows * cols == TEST_INFO->total_size_); + REQUIRE(rows * cols == TESTER->total_size_); size_t cell_size = 128; - size_t cell_stride = rows * cols / cell_size / TEST_INFO->num_iterations_; + size_t cell_stride = rows * cols / cell_size / TESTER->num_iterations_; SECTION("read from existing file") { - test::test_fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); size_t prev_cell_col = 0, prev_cell_row = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t current_cell_col = (prev_cell_col + cell_stride) % cols; size_t current_cell_row = prev_cell_col + cell_stride > cols - ? prev_cell_row + 1 - : prev_cell_row; + ? prev_cell_row + 1 + : prev_cell_row; prev_cell_row = current_cell_row; auto offset = (current_cell_col * cell_stride + prev_cell_row * cols) % - (TEST_INFO->total_size_ - TEST_INFO->large_max); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); + (TESTER->total_size_ - TESTER->large_max_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->large_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->large_max); + TESTER->large_min_ + (rand_r(&TESTER->rs_seed_) % TESTER->large_max_); std::string data(request_size, '1'); - test::test_fread(data.data(), request_size); - REQUIRE(test::size_read_orig == request_size); + TESTER->test_fread(data.data(), request_size); + REQUIRE(TESTER->size_read_orig_ == request_size); } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateStride2DRSRangeLarge", - "[process=" + std::to_string(TEST_INFO->comm_size_) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "" "[operation=batched_write]" "[request_size=range-large][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=stride_2d][file=1]") { - TEST_INFO->Pretest(); - size_t rows = sqrt(TEST_INFO->total_size_); + TESTER->Pretest(); + size_t rows = sqrt(TESTER->total_size_); size_t cols = rows; - REQUIRE(rows * cols == TEST_INFO->total_size_); + REQUIRE(rows * cols == TESTER->total_size_); size_t cell_size = 128; - size_t cell_stride = rows * cols / cell_size / TEST_INFO->num_iterations_; + size_t cell_stride = rows * cols / cell_size / TESTER->num_iterations_; SECTION("write to existing file") { - test::test_fopen(TEST_INFO->existing_file_.hermes_.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); + TESTER->test_fopen(TESTER->existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); size_t prev_cell_col = 0, prev_cell_row = 0; - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t current_cell_col = (prev_cell_col + cell_stride) % cols; size_t current_cell_row = prev_cell_col + cell_stride > cols - ? prev_cell_row + 1 - : prev_cell_row; + ? prev_cell_row + 1 + : prev_cell_row; prev_cell_row = current_cell_row; auto offset = (current_cell_col * cell_stride + prev_cell_row * cols) % - (TEST_INFO->total_size_ - TEST_INFO->large_max); - test::test_fseek(offset, SEEK_SET); - REQUIRE(test::status_orig == 0); + (TESTER->total_size_ - TESTER->large_max_); + TESTER->test_fseek(offset, SEEK_SET); + REQUIRE(TESTER->status_orig_ == 0); size_t request_size = - TEST_INFO->large_min + (rand_r(&TEST_INFO->rs_seed) % TEST_INFO->large_max); + TESTER->large_min_ + (rand_r(&TESTER->rs_seed_) % TESTER->large_max_); std::string data(request_size, '1'); - test::test_fwrite(data.data(), request_size); - REQUIRE(test::size_written_orig == request_size); + TESTER->test_fwrite(data.data(), request_size); + REQUIRE(TESTER->size_written_orig_ == request_size); } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - posttest(); + TESTER->Posttest(); } diff --git a/test/unit/hermes_adapters/stdio/stdio_adapter_shared_test.cc b/test/unit/hermes_adapters/stdio/stdio_adapter_shared_test.cc index b0c7a4cb2..5d06c6dd0 100644 --- a/test/unit/hermes_adapters/stdio/stdio_adapter_shared_test.cc +++ b/test/unit/hermes_adapters/stdio/stdio_adapter_shared_test.cc @@ -10,26 +10,28 @@ * have access to the file, you may request a copy from help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -TEST_CASE("SharedSTDIORead", "[process=" + std::to_string(TEST_INFO->comm_size_) + - "]" - "[operation=batched_read]" - "[request_size=type-fixed][repetition=" + - std::to_string(TEST_INFO->num_iterations_) + - "]" - "[mode=shared]" - "[pattern=sequential][file=1]") { - TEST_INFO->Pretest(); +#include "stdio_adapter_test.h" + +TEST_CASE("SharedSTDIORead", "[process=" + std::to_string(TESTER->comm_size_) + + "]" + "[operation=batched_read]" + "[request_size=type-fixed][repetition=" + + std::to_string(TESTER->num_iterations_) + + "]" + "[mode=shared]" + "[pattern=sequential][file=1]") { + TESTER->Pretest(); SECTION("read from existing file") { - test::test_fopen(TEST_INFO->existing_shared_file.c_str(), "r+"); - REQUIRE(test::fh_orig != nullptr); - std::string data(TEST_INFO->request_size_, '1'); - for (size_t i = 0; i < TEST_INFO->num_iterations_; ++i) { - test::test_fread(data.data(), TEST_INFO->request_size_); - REQUIRE(test::size_read_orig == TEST_INFO->request_size_); + TESTER->test_fopen(TESTER->shared_existing_file_, "r+"); + REQUIRE(TESTER->fh_orig_ != nullptr); + std::string data(TESTER->request_size_, '1'); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->test_fread(data.data(), TESTER->request_size_); + REQUIRE(TESTER->size_read_orig_ == TESTER->request_size_); } - test::test_fclose(); - REQUIRE(test::status_orig == 0); + TESTER->test_fclose(); + REQUIRE(TESTER->status_orig_ == 0); } - posttest(); + TESTER->Posttest(); } diff --git a/test/unit/hermes_adapters/stdio/stdio_adapter_test.cc b/test/unit/hermes_adapters/stdio/stdio_adapter_test.cc index b516c69ac..a1a264f6f 100644 --- a/test/unit/hermes_adapters/stdio/stdio_adapter_test.cc +++ b/test/unit/hermes_adapters/stdio/stdio_adapter_test.cc @@ -13,6 +13,6 @@ #include "stdio_adapter_test.h" int main(int argc, char **argv) { - TEST_INFO->Init(argc, argv); + TESTER->Init(argc, argv); } diff --git a/test/unit/hermes_adapters/stdio/stdio_adapter_test.h b/test/unit/hermes_adapters/stdio/stdio_adapter_test.h index 21d10889a..f31bff7f4 100644 --- a/test/unit/hermes_adapters/stdio/stdio_adapter_test.h +++ b/test/unit/hermes_adapters/stdio/stdio_adapter_test.h @@ -1,15 +1,23 @@ -// -// Created by lukemartinlogan on 11/4/23. -// +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Distributed under BSD 3-Clause license. * + * Copyright by The HDF Group. * + * Copyright by the Illinois Institute of Technology. * + * All rights reserved. * + * * + * This file is part of Hermes. The full Hermes copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the top directory. If you do not * + * have access to the file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #ifndef HERMES_TEST_UNIT_HERMES_ADAPTERS_STDIO_STDIO_ADAPTER_TEST_H_ #define HERMES_TEST_UNIT_HERMES_ADAPTERS_STDIO_STDIO_ADAPTER_TEST_H_ -#include "filesystem_tests.h" +#include "binary_file_tests.h" -namespace hermes::adapter::fs::test { +namespace hermes::adapter::test { template -class StdioTest : public FilesystemTests { +class StdioTest : public BinaryFileTests { public: FileInfo new_file_; FileInfo existing_file_; @@ -33,13 +41,15 @@ class StdioTest : public FilesystemTests { int status_orig_; size_t size_read_orig_; size_t size_written_orig_; + public: void RegisterFiles() override { RegisterPath("new", 0, new_file_); RegisterPath("ext", TEST_DO_CREATE, existing_file_); if constexpr(WITH_MPI) { - RegisterPath("shared_new", TEST_DO_CREATE | TEST_FILE_SHARED, shared_new_file_); - RegisterPath("shared_ext", TEST_DO_CREATE | TEST_FILE_SHARED, shared_existing_file_); + RegisterPath("shared_new", TEST_FILE_SHARED, shared_new_file_); + RegisterPath("shared_ext", TEST_DO_CREATE | TEST_FILE_SHARED, + shared_existing_file_); } RegisterTmpPath(tmp_file_); } @@ -84,14 +94,15 @@ class StdioTest : public FilesystemTests { } }; -} // namespace hermes::adapter::fs::test +} // namespace hermes::adapter::test #if defined(HERMES_MPI_TESTS) -#define TEST_INFO \ - hshm::EasySingleton>::GetInstance() +#define TESTER \ + hshm::EasySingleton< \ + hermes::adapter::test::StdioTest>::GetInstance() #else -#define TEST_INFO \ - hshm::EasySingleton>::GetInstance() +#define TESTER \ + hshm::EasySingleton>::GetInstance() #endif -#endif //HERMES_TEST_UNIT_HERMES_ADAPTERS_STDIO_STDIO_ADAPTER_TEST_H_ +#endif // HERMES_TEST_UNIT_HERMES_ADAPTERS_STDIO_STDIO_ADAPTER_TEST_H_ diff --git a/test/unit/hermes_adapters/stdio/tests.py b/test/unit/hermes_adapters/stdio/tests.py deleted file mode 100644 index bbcf12ce8..000000000 --- a/test/unit/hermes_adapters/stdio/tests.py +++ /dev/null @@ -1,120 +0,0 @@ -from py_hermes_ci.test_manager import TestManager -from jarvis_util import * - - -class StdioTestManager(TestManager): - def spawn_all_nodes(self): - return self.spawn_info() - - def set_paths(self): - self.STDIO_CMD = f"{self.CMAKE_BINARY_DIR}/bin/stdio_adapter_test" - self.HERMES_STDIO_CMD = f"{self.CMAKE_BINARY_DIR}/bin/hermes_stdio_adapter_test" - self.STDIO_MPI_CMD = f"{self.CMAKE_BINARY_DIR}/bin/stdio_adapter_mpi_test" - self.HERMES_STDIO_MPI_CMD = f"{self.CMAKE_BINARY_DIR}/bin/hermes_stdio_adapter_mpi_test" - self.STDIO_SIMPLE_IO_CMD = f"{self.CMAKE_BINARY_DIR}/bin/stdio_simple_io" - self.HERMES_STDIO_SIMPLE_IO_CMD = f"{self.CMAKE_BINARY_DIR}/bin/hermes_stdio_simple_io" - - self.HERMES_STDIO_MAPPER_CMD = f"{self.CMAKE_BINARY_DIR}/bin/stdio_adapter_mapper_test" - self.HERMES_STDIO_LOW_BUF_CMD = f"{self.CMAKE_BINARY_DIR}/bin/hermes_stdio_low_buf_adapter_test" - self.HERMES_STDIO_MODE_CMD = f"{self.CMAKE_BINARY_DIR}/bin/hermes_stdio_adapter_mode_test" - - self.disable_testing = False - - def test_stdio_basic(self): - return - stdio_cmd = f"{self.STDIO_CMD}" - node = Exec(stdio_cmd) - return node.exit_code - - def test_hermes_stdio_mapper(self): - stdio_cmd = f"{self.HERMES_STDIO_MAPPER_CMD} " - spawn_info = self.spawn_info(nprocs=1, - hermes_conf='hermes_server') - self.start_daemon(spawn_info) - node = Exec(stdio_cmd, spawn_info) - self.stop_daemon(spawn_info) - return node.exit_code - - def test_hermes_stdio_basic_small(self): - stdio_cmd = f"{self.HERMES_STDIO_CMD} " \ - f"~[request_size=range-large] " \ - f"--reporter compact -d yes" - spawn_info = self.spawn_info(nprocs=1, - hermes_conf='hermes_server') - self.start_daemon(spawn_info) - node = Exec(stdio_cmd, spawn_info) - self.stop_daemon(spawn_info) - return node.exit_code - - def test_hermes_stdio_basic_large(self): - stdio_cmd = f"{self.HERMES_STDIO_CMD} " \ - f"[request_size=range-large] " \ - f"--reporter compact -d yes" - spawn_info = self.spawn_info(nprocs=1, - hermes_conf='hermes_server') - self.start_daemon(spawn_info) - node = Exec(stdio_cmd, spawn_info) - self.stop_daemon(spawn_info) - return node.exit_code - - def test_hermes_stdio_mpi_small(self): - stdio_cmd = f"{self.HERMES_STDIO_MPI_CMD} " \ - f"~[request_size=range-large] " \ - f"--reporter compact -d yes" - spawn_info = self.spawn_info(nprocs=2, - hermes_conf='hermes_server') - self.start_daemon(spawn_info) - node = Exec(stdio_cmd, spawn_info) - self.stop_daemon(spawn_info) - return node.exit_code - - def test_hermes_stdio_mpi_large(self): - stdio_cmd = f"{self.HERMES_STDIO_MPI_CMD} " \ - f"[request_size=range-large] " \ - f"--reporter compact -d yes" - spawn_info = self.spawn_info(nprocs=2, - hermes_conf='hermes_server') - self.start_daemon(spawn_info) - node = Exec(stdio_cmd, spawn_info) - self.stop_daemon(spawn_info) - return node.exit_code - - def test_hermes_stdio_low_buf(self): - stdio_cmd = f"{self.HERMES_STDIO_LOW_BUF_CMD} " - spawn_info = self.spawn_info(nprocs=1, - hermes_conf='hermes_server') - self.start_daemon(spawn_info) - node = Exec(stdio_cmd, spawn_info) - self.stop_daemon(spawn_info) - return node.exit_code - - def test_hermes_stdio_bypass(self): - stdio_cmd = f"{self.HERMES_STDIO_MODE_CMD} [hermes_mode=bypass]" - spawn_info = self.spawn_info(nprocs=1, - hermes_conf='hermes_server', - hermes_mode='kBypass') - self.start_daemon(spawn_info) - node = Exec(stdio_cmd, spawn_info) - self.stop_daemon(spawn_info) - return node.exit_code - - def test_hermes_stdio_default(self): - stdio_cmd = f"{self.HERMES_STDIO_MODE_CMD} [hermes_mode=persistent]" - spawn_info = self.spawn_info(nprocs=1, - hermes_conf='hermes_server', - hermes_mode='kDefault') - self.start_daemon(spawn_info) - node = Exec(stdio_cmd, spawn_info) - self.stop_daemon(spawn_info) - return node.exit_code - - def test_hermes_stdio_scratch(self): - stdio_cmd = f"{self.HERMES_STDIO_MODE_CMD} [hermes_mode=scratch]" - spawn_info = self.spawn_info(nprocs=1, - hermes_conf='hermes_server', - hermes_mode='kScratch') - self.start_daemon(spawn_info) - node = Exec(stdio_cmd, spawn_info) - self.stop_daemon(spawn_info) - return node.exit_code - diff --git a/test/unit/hermes_adapters/vfd/CMakeLists.txt b/test/unit/hermes_adapters/vfd/CMakeLists.txt index 6d40c8625..030843d1e 100644 --- a/test/unit/hermes_adapters/vfd/CMakeLists.txt +++ b/test/unit/hermes_adapters/vfd/CMakeLists.txt @@ -4,14 +4,16 @@ set(hermes_vfd_tests hermes_vfd_adapter_test ) -add_executable(hermes_vfd_adapter_test ${CMAKE_CURRENT_SOURCE_DIR}/hermes_vfd_test.cc) +add_executable(hermes_vfd_adapter_test + ${CMAKE_CURRENT_SOURCE_DIR}/hermes_vfd_test.cc + ${CMAKE_CURRENT_SOURCE_DIR}/hermes_vfd_basic_test.cc) target_include_directories(hermes_vfd_adapter_test PRIVATE ${HERMES_VFD_DIR}) target_include_directories(hermes_vfd_adapter_test PRIVATE ${HERMES_ADAPTER_TEST_DIR}) target_include_directories(hermes_vfd_adapter_test SYSTEM PRIVATE ${HDF5_HERMES_VFD_EXT_INCLUDE_DEPENDENCIES} ) -set_target_properties(hermes_vfd_adapter_test - PROPERTIES COMPILE_FLAGS "-DHERMES_INTERCEPT=1") +target_compile_definitions(hermes_vfd_adapter_test PUBLIC + HERMES_INTERCEPT=1 HERMES_MPI_TESTS=true) add_dependencies(hermes_vfd_adapter_test hermes) target_link_libraries(hermes_vfd_adapter_test hermes @@ -20,5 +22,5 @@ target_link_libraries(hermes_vfd_adapter_test stdc++fs ${HDF5_HERMES_VFD_EXT_LIB_DEPENDENCIES}) -pytest(vfd test_hermes_vfd_default) -pytest(vfd test_hermes_vfd_scratch) \ No newline at end of file +jarvis_test(vfd test_hermes_vfd_basic) +jarvis_test(vfd test_hermes_vfd_scratch) \ No newline at end of file diff --git a/test/unit/hermes_adapters/vfd/hermes_vfd_basic_test.cc b/test/unit/hermes_adapters/vfd/hermes_vfd_basic_test.cc index f0c2eca7f..bde7cba2b 100644 --- a/test/unit/hermes_adapters/vfd/hermes_vfd_basic_test.cc +++ b/test/unit/hermes_adapters/vfd/hermes_vfd_basic_test.cc @@ -10,11 +10,12 @@ * have access to the file, you may request a copy from help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -using hermes::adapter::vfd::test::MuteHdf5Errors; +#include "hermes_vfd_test.h" +using hermes::adapter::test::MuteHdf5Errors; /** Returns a number in the range [1, upper_bound] */ static inline size_t Random1ToUpperBound(size_t upper_bound) { - size_t result = ((size_t)GenNextRandom() % upper_bound) + 1; + size_t result = ((size_t)TESTER->GenNextRandom() % upper_bound) + 1; return result; } @@ -27,693 +28,717 @@ static inline std::string RandomDatasetName(size_t upper_bound) { return result; } -TEST_CASE("H5FOpen", "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=single_open]" - "[repetition=1][file=1]") { - Pretest(); +TEST_CASE("H5FOpen", "[process=" + std::to_string(TESTER->comm_size_) + + "]" + "[operation=single_open]" + "[repetition=1][file=1]") { + TESTER->Pretest(); SECTION("open non-existent file") { MuteHdf5Errors mute; - test::TestOpen(info.new_file, H5F_ACC_RDONLY); - REQUIRE(test::hermes_hid == H5I_INVALID_HID); - test::TestOpen(info.new_file, H5F_ACC_RDWR); - REQUIRE(test::hermes_hid == H5I_INVALID_HID); + TESTER->TestOpen(TESTER->new_file_, H5F_ACC_RDONLY); + REQUIRE(TESTER->hermes_hid_ == H5I_INVALID_HID); + TESTER->TestOpen(TESTER->new_file_, H5F_ACC_RDWR); + REQUIRE(TESTER->hermes_hid_ == H5I_INVALID_HID); } SECTION("truncate existing file") { - test::TestOpen(info.existing_file, H5F_ACC_TRUNC, true); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); + TESTER->TestOpen(TESTER->existing_file_, H5F_ACC_TRUNC, true); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); } SECTION("open existing file") { - test::TestOpen(info.existing_file, H5F_ACC_RDWR); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); + TESTER->TestOpen(TESTER->existing_file_, H5F_ACC_RDWR); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); - test::TestOpen(info.existing_file, H5F_ACC_RDONLY); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); + TESTER->TestOpen(TESTER->existing_file_, H5F_ACC_RDONLY); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); } SECTION("create existing file exclusively") { MuteHdf5Errors mute; - test::TestOpen(info.existing_file, H5F_ACC_EXCL, true); - REQUIRE(test::hermes_hid == H5I_INVALID_HID); + TESTER->TestOpen(TESTER->existing_file_, H5F_ACC_EXCL, true); + REQUIRE(TESTER->hermes_hid_ == H5I_INVALID_HID); } - Posttest(); + TESTER->Posttest(); } -TEST_CASE("SingleWrite", "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=single_write]" - "[request_size=type-fixed][repetition=1]" - "[file=1]") { - Pretest(); +TEST_CASE("SingleWrite", "[process=" + std::to_string(TESTER->comm_size_) + + "]" + "[operation=single_write]" + "[request_size=type-fixed][repetition=1]" + "[file=1]") { + TESTER->Pretest(); SECTION("overwrite dataset in existing file") { - test::TestOpen(info.existing_file, H5F_ACC_RDWR); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); - test::TestWritePartial1d("0", info.write_data.data(), 0, - info.nelems_per_dataset); - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); + TESTER->TestOpen(TESTER->existing_file_, H5F_ACC_RDWR); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); + TESTER->TestWritePartial1d("0", TESTER->write_data_.data(), 0, + TESTER->request_size_); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); } SECTION("write to new file") { - test::TestOpen(info.new_file, H5F_ACC_EXCL, true); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); - test::TestWriteDataset("0", info.write_data); - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); + TESTER->TestOpen(TESTER->new_file_, H5F_ACC_EXCL, true); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); + TESTER->TestWriteDataset("0", TESTER->write_data_); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); } SECTION("write to existing file with truncate") { - test::TestOpen(info.existing_file, H5F_ACC_TRUNC, true); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); - test::TestWriteDataset("0", info.write_data); - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); + TESTER->TestOpen(TESTER->existing_file_, H5F_ACC_TRUNC, true); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); + TESTER->TestWriteDataset("0", TESTER->write_data_); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); } SECTION("add dataset to existing file") { - test::TestOpen(info.existing_file, H5F_ACC_RDWR); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); - test::TestWriteDataset(std::to_string(info.num_iterations), - info.write_data); - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); + TESTER->TestOpen(TESTER->existing_file_, H5F_ACC_RDWR); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); + TESTER->TestWriteDataset(std::to_string(TESTER->num_iterations_), + TESTER->write_data_); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); } - Posttest(); + TESTER->Posttest(); } -TEST_CASE("SingleRead", "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=single_read]" - "[request_size=type-fixed][repetition=1]" - "[file=1]") { - Pretest(); +TEST_CASE("SingleRead", "[process=" + std::to_string(TESTER->comm_size_) + + "]" + "[operation=single_read]" + "[request_size=type-fixed][repetition=1]" + "[file=1]") { + TESTER->Pretest(); SECTION("read from non-existing file") { MuteHdf5Errors mute; - test::TestOpen(info.new_file, H5F_ACC_RDONLY); - REQUIRE(test::hermes_hid == H5I_INVALID_HID); + TESTER->TestOpen(TESTER->new_file_, H5F_ACC_RDONLY); + REQUIRE(TESTER->hermes_hid_ == H5I_INVALID_HID); } SECTION("read first dataset from existing file") { - test::TestOpen(info.existing_file, H5F_ACC_RDONLY); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); - test::TestRead("0", info.read_data, 0, info.nelems_per_dataset); - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); + TESTER->TestOpen(TESTER->existing_file_, H5F_ACC_RDONLY); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); + TESTER->TestRead("0", TESTER->read_data_, 0, + TESTER->request_size_); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); } SECTION("read last dataset of existing file") { - test::TestOpen(info.existing_file, H5F_ACC_RDONLY); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); - test::TestRead(std::to_string(info.num_iterations - 1), info.read_data, 0, - info.nelems_per_dataset); - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); - } - Posttest(); + TESTER->TestOpen(TESTER->existing_file_, H5F_ACC_RDONLY); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); + TESTER->TestRead(std::to_string(TESTER->num_iterations_ - 1), + TESTER->read_data_, 0, + TESTER->request_size_); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); + } + TESTER->Posttest(); } TEST_CASE("BatchedWriteSequential", - "[process=" + std::to_string(info.comm_size) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1]") { - Pretest(); + TESTER->Pretest(); SECTION("write to new file") { - test::TestOpen(info.new_file, H5F_ACC_EXCL, true); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); + TESTER->TestOpen(TESTER->new_file_, H5F_ACC_EXCL, true); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); - for (size_t i = 0; i < info.num_iterations; ++i) { - test::TestWriteDataset(std::to_string(i), info.write_data); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->TestWriteDataset(std::to_string(i), TESTER->write_data_); } - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); } SECTION("overwrite first dataset") { - test::TestOpen(info.new_file, H5F_ACC_EXCL, true); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); + TESTER->TestOpen(TESTER->new_file_, H5F_ACC_EXCL, true); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); - test::TestWriteDataset("0", info.write_data); - for (size_t i = 0; i < info.num_iterations; ++i) { - test::TestWritePartial1d("0", info.write_data.data(), 0, - info.nelems_per_dataset); + TESTER->TestWriteDataset("0", TESTER->write_data_); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->TestWritePartial1d("0", TESTER->write_data_.data(), 0, + TESTER->request_size_); } - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); } - Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadSequential", - "[process=" + std::to_string(info.comm_size) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1]") { - Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - test::TestOpen(info.existing_file, H5F_ACC_RDWR); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); + TESTER->TestOpen(TESTER->existing_file_, H5F_ACC_RDWR); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); - std::vector buf(info.nelems_per_dataset, 0.0f); - for (size_t i = 0; i < info.num_iterations; ++i) { - test::TestRead(std::to_string(i), buf, 0, info.nelems_per_dataset); + std::vector buf(TESTER->request_size_, 0.0f); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->TestRead(std::to_string(i), buf, 0, + TESTER->request_size_); } - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); } SECTION("read from existing file always at start") { - test::TestOpen(info.existing_file, H5F_ACC_RDWR); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); + TESTER->TestOpen(TESTER->existing_file_, H5F_ACC_RDWR); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); - for (size_t i = 0; i < info.num_iterations; ++i) { - test::TestRead("0", info.read_data, 0, info.nelems_per_dataset); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->TestRead("0", TESTER->read_data_, 0, + TESTER->request_size_); } - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); } - Posttest(); + TESTER->Posttest(); } -TEST_CASE("BatchedReadRandom", "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_read]" - "[request_size=type-fixed]" - "[repetition=" + - std::to_string(info.num_iterations) + - "][pattern=random][file=1]") { - Pretest(); +TEST_CASE("BatchedReadRandom", "[process=" + + std::to_string(TESTER->comm_size_) + + "]" + "[operation=batched_read]" + "[request_size=type-fixed]" + "[repetition=" + + std::to_string(TESTER->num_iterations_) + + "][pattern=random][file=1]") { + TESTER->Pretest(); SECTION("read from existing file") { - test::TestOpen(info.existing_file, H5F_ACC_RDWR); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); + TESTER->TestOpen(TESTER->existing_file_, H5F_ACC_RDWR); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); - std::vector buf(info.nelems_per_dataset, 0.0f); - for (size_t i = 0; i < info.num_iterations; ++i) { - u32 dataset = GenNextRandom() % info.num_iterations; - test::TestRead(std::to_string(dataset), buf, 0, info.nelems_per_dataset); + std::vector buf(TESTER->request_size_, 0.0f); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + u32 dataset = TESTER->GenNextRandom() % TESTER->num_iterations_; + TESTER->TestRead(std::to_string(dataset), buf, 0, TESTER->request_size_); } - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); } - Posttest(); + TESTER->Posttest(); } -TEST_CASE("BatchedUpdateRandom", "[process=" + std::to_string(info.comm_size) + - "]" - "[operation=batched_write]" - "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + - "]" - "[pattern=random][file=1]") { - Pretest(); +TEST_CASE("BatchedUpdateRandom", "[process=" + + std::to_string(TESTER->comm_size_) + + "]" + "[operation=batched_write]" + "[request_size=type-fixed][repetition=" + + std::to_string(TESTER->num_iterations_) + + "]" + "[pattern=random][file=1]") { + TESTER->Pretest(); SECTION("update entire dataset in existing file") { - test::TestOpen(info.existing_file, H5F_ACC_RDWR); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); - - for (size_t i = 0; i < info.num_iterations; ++i) { - u32 dataset = GenNextRandom() % info.num_iterations; - test::TestWritePartial1d(std::to_string(dataset), info.write_data.data(), - 0, info.nelems_per_dataset); + TESTER->TestOpen(TESTER->existing_file_, H5F_ACC_RDWR); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); + + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + u32 dataset = TESTER->GenNextRandom() % TESTER->num_iterations_; + TESTER->TestWritePartial1d(std::to_string(dataset), + TESTER->write_data_.data(), + 0, TESTER->request_size_); } - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); } SECTION("update partial dataset in existing file") { - test::TestOpen(info.existing_file, H5F_ACC_RDWR); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); + TESTER->TestOpen(TESTER->existing_file_, H5F_ACC_RDWR); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); - for (size_t i = 0; i < info.num_iterations; ++i) { - u32 dataset = GenNextRandom() % info.num_iterations; + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + u32 dataset = TESTER->GenNextRandom() % TESTER->num_iterations_; // NOTE(chogan): Subtract 1 from size so we're always writing at least 1 // element - hsize_t offset = GenNextRandom() % (info.write_data.size() - 1); - hsize_t elements_to_write = info.write_data.size() - offset; - test::TestWritePartial1d(std::to_string(dataset), info.write_data.data(), - offset, elements_to_write); + hsize_t offset = TESTER->GenNextRandom() % + (TESTER->write_data_.size() - 1); + hsize_t elements_to_write = TESTER->write_data_.size() - offset; + TESTER->TestWritePartial1d(std::to_string(dataset), + TESTER->write_data_.data(), + offset, elements_to_write); } - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); } - Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedWriteRSVariable", - "[process=" + std::to_string(info.comm_size) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=type-variable][repetition=" + - std::to_string(info.num_iterations) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1]") { - Pretest(); + TESTER->Pretest(); SECTION("write to new file always at the start") { MuteHdf5Errors mute; - test::TestOpen(info.new_file, H5F_ACC_EXCL, true); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); + TESTER->TestOpen(TESTER->new_file_, H5F_ACC_EXCL, true); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); - for (size_t i = 0; i < info.num_iterations; ++i) { - size_t request_size = Random1ToUpperBound(info.nelems_per_dataset); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + size_t request_size = Random1ToUpperBound(TESTER->request_size_); std::vector data(request_size, 2.0f); - test::TestWritePartial1d(std::to_string(i), data.data(), 0, request_size); + TESTER->TestWritePartial1d(std::to_string(i), data.data(), + 0, request_size); } - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); } - Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadSequentialRSVariable", - "[process=" + std::to_string(info.comm_size) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=type-variable][repetition=" + - std::to_string(info.num_iterations) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1]") { - Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - test::TestOpen(info.existing_file, H5F_ACC_RDONLY); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); + TESTER->TestOpen(TESTER->existing_file_, H5F_ACC_RDONLY); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); - for (size_t i = 0; i < info.num_iterations; ++i) { - size_t request_size = Random1ToUpperBound(info.nelems_per_dataset); - size_t starting_element = info.nelems_per_dataset - request_size; + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + size_t request_size = Random1ToUpperBound(TESTER->request_size_); + size_t starting_element = TESTER->request_size_ - request_size; std::vector data(request_size, 1.5f); - test::TestRead(std::to_string(i), data, starting_element, request_size); + TESTER->TestRead(std::to_string(i), data, + starting_element, request_size); } - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); } SECTION("read from existing file always at start") { - test::TestOpen(info.existing_file, H5F_ACC_RDONLY); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); + TESTER->TestOpen(TESTER->existing_file_, H5F_ACC_RDONLY); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); - for (size_t i = 0; i < info.num_iterations; ++i) { - size_t request_size = Random1ToUpperBound(info.nelems_per_dataset); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + size_t request_size = Random1ToUpperBound(TESTER->request_size_); std::vector data(request_size, 3.0f); - test::TestRead(std::to_string(i), data, 0, request_size); + TESTER->TestRead(std::to_string(i), data, 0, request_size); } - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); } - Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedReadRandomRSVariable", - "[process=" + std::to_string(info.comm_size) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_read]" "[request_size=type-variable]" "[repetition=" + - std::to_string(info.num_iterations) + + std::to_string(TESTER->num_iterations_) + "][pattern=random][file=1]") { - Pretest(); + TESTER->Pretest(); SECTION("read from existing file") { - test::TestOpen(info.existing_file, H5F_ACC_RDWR); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); + TESTER->TestOpen(TESTER->existing_file_, H5F_ACC_RDWR); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); - std::vector data(info.nelems_per_dataset, 5.0f); - for (size_t i = 0; i < info.num_iterations; ++i) { - std::string dset_name = RandomDatasetName(info.num_iterations); - size_t starting_element = Random1ToUpperBound(info.nelems_per_dataset); + std::vector data(TESTER->request_size_, 5.0f); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + std::string dset_name = RandomDatasetName(TESTER->num_iterations_); + size_t starting_element = Random1ToUpperBound(TESTER->request_size_); size_t request_elements = - Random1ToUpperBound(info.nelems_per_dataset - starting_element); + Random1ToUpperBound(TESTER->request_size_ - starting_element); std::vector data(request_elements, 3.8f); - test::TestRead(dset_name, data, starting_element, request_elements); + TESTER->TestRead(dset_name, data, starting_element, request_elements); } - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); } - Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedUpdateRandomRSVariable", - "[process=" + std::to_string(info.comm_size) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=type-variable][repetition=" + - std::to_string(info.num_iterations) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=random][file=1]") { - Pretest(); + TESTER->Pretest(); SECTION("write to existing file") { - test::TestOpen(info.existing_file, H5F_ACC_RDWR); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); - - std::vector data(info.nelems_per_dataset, 8.0f); - for (size_t i = 0; i < info.num_iterations; ++i) { - std::string dset_name = RandomDatasetName(info.num_iterations); - size_t request_size = Random1ToUpperBound(info.nelems_per_dataset); - test::TestWritePartial1d(dset_name, data.data(), 0, request_size); + TESTER->TestOpen(TESTER->existing_file_, H5F_ACC_RDWR); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); + + std::vector data(TESTER->request_size_, 8.0f); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + std::string dset_name = RandomDatasetName(TESTER->num_iterations_); + size_t request_size = Random1ToUpperBound(TESTER->request_size_); + TESTER->TestWritePartial1d(dset_name, data.data(), 0, request_size); } - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); } - Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedWriteTemporalFixed", - "[process=" + std::to_string(info.comm_size) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1][temporal=fixed]") { - Pretest(); + TESTER->Pretest(); SECTION("write to existing file") { - test::TestOpen(info.existing_file, H5F_ACC_RDWR); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); - - for (size_t i = 0; i < info.num_iterations; ++i) { - usleep(info.temporal_interval_ms * 1000); - test::TestWritePartial1d(std::to_string(i), info.write_data.data(), 0, - info.nelems_per_dataset); + TESTER->TestOpen(TESTER->existing_file_, H5F_ACC_RDWR); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); + + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + usleep(TESTER->temporal_interval_ms_ * 1000); + TESTER->TestWritePartial1d(std::to_string(i), + TESTER->write_data_.data(), 0, + TESTER->request_size_); } - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); } SECTION("write to new file always at start") { - test::TestOpen(info.new_file, H5F_ACC_EXCL, true); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); + TESTER->TestOpen(TESTER->new_file_, H5F_ACC_EXCL, true); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); - for (size_t i = 0; i < info.num_iterations; ++i) { - usleep(info.temporal_interval_ms * 1000); - test::TestWriteDataset(std::to_string(i), info.write_data); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + usleep(TESTER->temporal_interval_ms_ * 1000); + TESTER->TestWriteDataset(std::to_string(i), TESTER->write_data_); } - test::TestClose(); + TESTER->TestClose(); } - Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedWriteTemporalVariable", - "[process=" + std::to_string(info.comm_size) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_write]" "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1][temporal=variable]") { - Pretest(); + TESTER->Pretest(); SECTION("write to existing file") { - test::TestOpen(info.existing_file, H5F_ACC_RDWR); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); + TESTER->TestOpen(TESTER->existing_file_, H5F_ACC_RDWR); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); - for (size_t i = 0; i < info.num_iterations; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t sleep_interval_ms = - GenNextRandom() % (info.temporal_interval_ms + 2); + TESTER->GenNextRandom() % (TESTER->temporal_interval_ms_ + 2); usleep(sleep_interval_ms * 1000); - test::TestWritePartial1d(std::to_string(i), info.write_data.data(), 0, - info.nelems_per_dataset); + TESTER->TestWritePartial1d(std::to_string(i), + TESTER->write_data_.data(), 0, + TESTER->request_size_); } - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); } SECTION("write to new file always at start") { - test::TestOpen(info.new_file, H5F_ACC_EXCL, true); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); + TESTER->TestOpen(TESTER->new_file_, H5F_ACC_EXCL, true); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); - for (size_t i = 0; i < info.num_iterations; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { size_t sleep_interval_ms = - GenNextRandom() % (info.temporal_interval_ms + 2); + TESTER->GenNextRandom() % (TESTER->temporal_interval_ms_ + 2); usleep(sleep_interval_ms * 1000); - test::TestWriteDataset(std::to_string(i), info.write_data); + TESTER->TestWriteDataset(std::to_string(i), TESTER->write_data_); } - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); } - Posttest(); + TESTER->Posttest(); } TEST_CASE("BatchedMixedSequential", - "[process=" + std::to_string(info.comm_size) + + "[process=" + std::to_string(TESTER->comm_size_) + "]" "[operation=batched_mixed]" "[request_size=type-fixed][repetition=" + - std::to_string(info.num_iterations) + + std::to_string(TESTER->num_iterations_) + "]" "[pattern=sequential][file=1]") { - Pretest(); + TESTER->Pretest(); SECTION("read after write on new file") { - test::TestOpen(info.new_file, H5F_ACC_EXCL, true); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); + TESTER->TestOpen(TESTER->new_file_, H5F_ACC_EXCL, true); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); - for (size_t i = 0; i < info.num_iterations; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { std::string dset_name = std::to_string(i); - test::TestWriteDataset(dset_name, info.write_data); - test::TestRead(dset_name, info.read_data, 0, info.nelems_per_dataset); + TESTER->TestWriteDataset(dset_name, TESTER->write_data_); + TESTER->TestRead(dset_name, TESTER->read_data_, + 0, TESTER->request_size_); } - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); } SECTION("alternate write and read existing file") { - test::TestOpen(info.existing_file, H5F_ACC_RDWR); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); + TESTER->TestOpen(TESTER->existing_file_, H5F_ACC_RDWR); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); - for (size_t i = 0; i < info.num_iterations; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { std::string dset_name = std::to_string(i); if (i % 2 == 0) { - test::TestWritePartial1d(dset_name, info.write_data.data(), 0, - info.nelems_per_dataset); + TESTER->TestWritePartial1d(dset_name, TESTER->write_data_.data(), + 0, TESTER->request_size_); } else { - test::TestRead(dset_name, info.read_data, 0, info.nelems_per_dataset); + TESTER->TestRead(dset_name, TESTER->read_data_, + 0, TESTER->request_size_); } } - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); } SECTION("update after read existing file") { - test::TestOpen(info.existing_file, H5F_ACC_RDWR); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); + TESTER->TestOpen(TESTER->existing_file_, H5F_ACC_RDWR); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); - for (size_t i = 0; i < info.num_iterations; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { std::string dset_name = std::to_string(i); - test::TestRead(dset_name, info.read_data, 0, info.nelems_per_dataset); - test::TestWritePartial1d(dset_name, info.write_data.data(), 0, - info.nelems_per_dataset); + TESTER->TestRead(dset_name, TESTER->read_data_, + 0, TESTER->request_size_); + TESTER->TestWritePartial1d(dset_name, TESTER->write_data_.data(), 0, + TESTER->request_size_); } - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); } SECTION("read all after write all on new file in single open") { - test::TestOpen(info.new_file, H5F_ACC_EXCL, true); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); + TESTER->TestOpen(TESTER->new_file_, H5F_ACC_EXCL, true); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); - for (size_t i = 0; i < info.num_iterations; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { std::string dset_name = std::to_string(i); - test::TestWriteDataset(dset_name, info.write_data); + TESTER->TestWriteDataset(dset_name, TESTER->write_data_); } - for (size_t i = 0; i < info.num_iterations; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { std::string dset_name = std::to_string(i); - test::TestRead(dset_name, info.read_data, 0, info.nelems_per_dataset); + TESTER->TestRead(dset_name, TESTER->read_data_, + 0, TESTER->request_size_); } - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); } SECTION("read all after write all on new file in different open") { - test::TestOpen(info.new_file, H5F_ACC_EXCL, true); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); + TESTER->TestOpen(TESTER->new_file_, H5F_ACC_EXCL, true); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); - for (size_t i = 0; i < info.num_iterations; ++i) { - test::TestWriteDataset(std::to_string(i), info.write_data); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->TestWriteDataset(std::to_string(i), TESTER->write_data_); } - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); - test::TestOpen(info.new_file, H5F_ACC_RDWR); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); + TESTER->TestOpen(TESTER->new_file_, H5F_ACC_RDWR); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); - for (size_t i = 0; i < info.num_iterations; ++i) { - test::TestRead(std::to_string(i), info.read_data, 0, - info.nelems_per_dataset); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->TestRead(std::to_string(i), TESTER->read_data_, 0, + TESTER->request_size_); } - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); } - Posttest(); + TESTER->Posttest(); } -TEST_CASE("SingleMixed", "[process=" + std::to_string(info.comm_size) + - "][operation=single_mixed]" - "[request_size=type-fixed][repetition=1]" - "[file=1]") { - Pretest(); +TEST_CASE("SingleMixed", "[process=" + std::to_string(TESTER->comm_size_) + + "][operation=single_mixed]" + "[request_size=type-fixed][repetition=1]" + "[file=1]") { + TESTER->Pretest(); SECTION("read after write from new file") { - test::TestOpen(info.new_file, H5F_ACC_EXCL, true); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); + TESTER->TestOpen(TESTER->new_file_, H5F_ACC_EXCL, true); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); std::string dset_name("0"); - test::TestWriteDataset(dset_name, info.write_data); - test::TestRead(dset_name, info.read_data, 0, info.nelems_per_dataset); - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); + TESTER->TestWriteDataset(dset_name, TESTER->write_data_); + TESTER->TestRead(dset_name, TESTER->read_data_, + 0, TESTER->request_size_); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); } SECTION("update after read from existing file") { - test::TestOpen(info.existing_file, H5F_ACC_RDWR); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); + TESTER->TestOpen(TESTER->existing_file_, H5F_ACC_RDWR); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); std::string dset_name("0"); - test::TestRead(dset_name, info.read_data, 0, info.nelems_per_dataset); - test::TestWritePartial1d(dset_name, info.write_data.data(), 0, - info.nelems_per_dataset); - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); + TESTER->TestRead(dset_name, TESTER->read_data_, + 0, TESTER->request_size_); + TESTER->TestWritePartial1d(dset_name, TESTER->write_data_.data(), 0, + TESTER->request_size_); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); } SECTION("read after write from new file different opens") { - test::TestOpen(info.new_file, H5F_ACC_EXCL, true); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); + TESTER->TestOpen(TESTER->new_file_, H5F_ACC_EXCL, true); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); std::string dset_name("0"); - test::TestWriteDataset(dset_name, info.write_data); - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); + TESTER->TestWriteDataset(dset_name, TESTER->write_data_); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); - test::TestOpen(info.new_file, H5F_ACC_RDWR); - test::TestRead(dset_name, info.read_data, 0, info.nelems_per_dataset); - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); + TESTER->TestOpen(TESTER->new_file_, H5F_ACC_RDWR); + TESTER->TestRead(dset_name, TESTER->read_data_, + 0, TESTER->request_size_); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); } - Posttest(); + TESTER->Posttest(); } TEST_CASE("CompactDatasets") { - Pretest(); + TESTER->Pretest(); SECTION("create many and read randomly") { - test::TestOpen(info.new_file, H5F_ACC_EXCL, true); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); + TESTER->TestOpen(TESTER->new_file_, H5F_ACC_EXCL, true); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); size_t num_elements = KILOBYTES(32) / sizeof(f32); - for (size_t i = 0; i < info.num_iterations; ++i) { + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { std::vector data(num_elements); for (size_t i = 0; i < data.size(); ++i) { - data[i] = GenRandom0to1(); + data[i] = TESTER->GenRandom0to1(); } - test::TestMakeCompactDataset(std::to_string(i), data); + TESTER->TestMakeCompactDataset(std::to_string(i), data); } std::vector read_buf(num_elements, 0.0f); - for (size_t i = 0; i < info.num_iterations; ++i) { - std::string dset_name = RandomDatasetName(info.num_iterations); - test::TestRead(dset_name, read_buf, 0, num_elements); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + std::string dset_name = RandomDatasetName(TESTER->num_iterations_); + TESTER->TestRead(dset_name, read_buf, 0, num_elements); } - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); } - Posttest(); + TESTER->Posttest(); } TEST_CASE("PartialUpdateToLastPage") { - Pretest(); + TESTER->Pretest(); SECTION("beginning of last page") { - test::TestOpen(info.existing_file, H5F_ACC_RDWR); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); - test::TestWritePartial1d(std::to_string(info.num_iterations - 1), - info.write_data.data(), 0, - info.nelems_per_dataset / 2); - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); + TESTER->TestOpen(TESTER->existing_file_, H5F_ACC_RDWR); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); + TESTER->TestWritePartial1d( + std::to_string(TESTER->num_iterations_ - 1), + TESTER->write_data_.data(), 0, + TESTER->request_size_ / 2); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); } SECTION("in middle of last page") { - test::TestOpen(info.existing_file, H5F_ACC_RDWR); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); - test::TestWritePartial1d(std::to_string(info.num_iterations - 1), - info.write_data.data(), - info.nelems_per_dataset / 4, - info.nelems_per_dataset / 2); - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); + TESTER->TestOpen(TESTER->existing_file_, H5F_ACC_RDWR); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); + TESTER->TestWritePartial1d( + std::to_string(TESTER->num_iterations_ - 1), + TESTER->write_data_.data(), + TESTER->request_size_ / 4, + TESTER->request_size_ / 2); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); } SECTION("at end of last page") { - test::TestOpen(info.existing_file, H5F_ACC_RDWR); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); - test::TestWritePartial1d(std::to_string(info.num_iterations - 1), - info.write_data.data(), - info.nelems_per_dataset / 2, - info.nelems_per_dataset / 2); - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); - } - - Posttest(); + TESTER->TestOpen(TESTER->existing_file_, H5F_ACC_RDWR); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); + TESTER->TestWritePartial1d( + std::to_string(TESTER->num_iterations_ - 1), + TESTER->write_data_.data(), + TESTER->request_size_ / 2, + TESTER->request_size_ / 2); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); + } + + TESTER->Posttest(); } -TEST_CASE("ScratchMode", "[scratch]") { - Pretest(); +TEST_CASE("ScratchMode", "[mode=scratch]") { + TESTER->Pretest(); SECTION("created files shouldn't persist") { - test::TestOpen(info.new_file, H5F_ACC_EXCL, true); - REQUIRE(test::hermes_hid != H5I_INVALID_HID); + TESTER->TestOpen(TESTER->new_file_, H5F_ACC_EXCL, true); + REQUIRE(TESTER->hermes_hid_ != H5I_INVALID_HID); - for (size_t i = 0; i < info.num_iterations; ++i) { - test::TestWriteDataset(std::to_string(i), info.write_data); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + TESTER->TestWriteDataset(std::to_string(i), TESTER->write_data_); } - for (size_t i = 0; i < info.num_iterations; ++i) { - std::string dset_name = RandomDatasetName(info.num_iterations); - test::TestRead(dset_name, info.read_data, 0, info.nelems_per_dataset); + for (size_t i = 0; i < TESTER->num_iterations_; ++i) { + std::string dset_name = RandomDatasetName(TESTER->num_iterations_); + TESTER->TestRead(dset_name, TESTER->read_data_, + 0, TESTER->request_size_); } - test::TestClose(); - REQUIRE(test::hermes_herr >= 0); + TESTER->TestClose(); + REQUIRE(TESTER->hermes_herr_ >= 0); if (HERMES_CLIENT_CONF.GetBaseAdapterMode() == hermes::adapter::AdapterMode::kScratch) { - REQUIRE(!stdfs::exists(info.new_file)); + REQUIRE(!stdfs::exists(TESTER->new_file_.hermes_)); } } - Posttest(); + TESTER->Posttest(); } diff --git a/test/unit/hermes_adapters/vfd/hermes_vfd_test.cc b/test/unit/hermes_adapters/vfd/hermes_vfd_test.cc index 4356c526d..3e9da19f1 100644 --- a/test/unit/hermes_adapters/vfd/hermes_vfd_test.cc +++ b/test/unit/hermes_adapters/vfd/hermes_vfd_test.cc @@ -10,593 +10,8 @@ * have access to the file, you may request a copy from help@hdfgroup.org. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#include -#include -#include -#include -#include +#include "hermes_vfd_test.h" -#include -#include - -#include -#include - -#include "hermes/hermes.h" -#include "hermes/hermes_types.h" -#include "adapter_test_utils.h" -#include "catch_config.h" - -namespace stdfs = std::filesystem; - -namespace hermes::adapter::vfd::test { - -/** - A structure to represent test arguments -*/ -struct Arguments { - std::string filename = "test"; /**< test file name */ - std::string directory = "/tmp/test_hermes"; /**< test directory name */ - size_t request_size = 65536; /**< test request size */ -}; - -/** - A structure to represent test information -*/ -struct TestInfo { - static inline const int element_size = sizeof(f32); /**< test element size */ - - // int rank = 0; - int comm_size = 1; /**< communicator size */ - std::vector write_data; /**< test data for writing */ - std::vector read_data; /**< test data for reading */ - std::string new_file; /**< new file name */ - std::string existing_file; /**< existing file name */ - std::string new_file_cmp; /**< new file name to compare */ - std::string existing_file_cmp; /**< existing file name to compare */ - std::string hdf5_extension = ".h5"; /**< HDF5 file extention to use */ - size_t num_iterations = 64; /**< number of iterations */ - // int offset_seed = 1; - // unsigned int rs_seed = 1; - // unsigned int temporal_interval_seed = 5; - size_t total_size; /**< total size */ - // size_t stride_size = 512; - unsigned int temporal_interval_ms = 1; /**< interval in milliseconds */ - // size_t small_min = 1; - // size_t small_max = KILOBYTES(4); - // size_t medium_min = KILOBYTES(4) + 1; - // size_t medium_max = KILOBYTES(256); - // size_t large_min = KILOBYTES(256) + 1; - // size_t large_max = MEGABYTES(3); - size_t nelems_per_dataset; /**< number of elements per dataset */ -}; - -/** - * Temporarily disable printing of the HDF5 error stack. - * - * Some tests intentionally trigger HDF5 errors, and in those cases we don't - * want to clutter the output with HDF5 error messages. - */ -class MuteHdf5Errors { - H5E_auto2_t old_func; /**< error handler callback function */ - void *old_client_data; /**< pointer to client data for old_func */ - - public: - MuteHdf5Errors() { - // Save old error handler - H5Eget_auto(H5E_DEFAULT, &old_func, &old_client_data); - - // Turn off error stack printing - H5Eset_auto(H5E_DEFAULT, NULL, NULL); - } - - ~MuteHdf5Errors() { - // Restore previous error handler - H5Eset_auto(H5E_DEFAULT, old_func, old_client_data); - } -}; - -/** - * HDF5 identifiers required for reads and writes. - */ -struct RwIds { - hid_t dset_id; /**< dataset ID */ - hid_t dspace_id; /**< data space ID */ - hid_t mspace_id; /**< memory space ID */ -}; - -/** - * The I/O API for this adapter layer. - * - * Ideally we would have a high level Adapter I/O API that each adapter inherits - * from so that the adapter tests can reuse more code. This is a step in that - * direction. - */ -struct Hdf5Api { - /** - * A file access property list representing the sec2 (POSIX) VFD. - */ - hid_t sec2_fapl; - - Hdf5Api() : sec2_fapl(H5I_INVALID_HID) { - sec2_fapl = H5Pcreate(H5P_FILE_ACCESS); - REQUIRE(sec2_fapl != H5I_INVALID_HID); - REQUIRE(H5Pset_fapl_sec2(sec2_fapl) >= 0); - } - - ~Hdf5Api() { - REQUIRE(H5Pclose(sec2_fapl) >= 0); - sec2_fapl = H5I_INVALID_HID; - } - - /** - * Open an existing file using the default VFD. Since the tests are run with - * HDF5_DRIVER=hermes, the default VFD will be the Hermes VFD. - */ - hid_t Open(const std::string &fname, unsigned flags) { - hid_t result = H5Fopen(fname.c_str(), flags, H5P_DEFAULT); - - return result; - } - - /** - * Open an existing file using the POSIX VFD. This will bypass Hermes. - */ - hid_t OpenPosix(const std::string &fname, unsigned flags) { - hid_t result = H5Fopen(fname.c_str(), flags, sec2_fapl); - - return result; - } - - /** - * Create a file using the default VFD. - */ - hid_t Create(const std::string &fname, unsigned flags) { - hid_t result = H5Fcreate(fname.c_str(), flags, H5P_DEFAULT, H5P_DEFAULT); - - return result; - } - - /** - * Create a file using the POSIX VFD. - */ - hid_t CreatePosix(const std::string &fname, unsigned flags) { - hid_t result = H5Fcreate(fname.c_str(), flags, H5P_DEFAULT, sec2_fapl); - - return result; - } - - /** - * Boilerplate necessary before calling H5Dread or H5Dwrite. - */ - RwIds RwPreamble(hid_t hid, const std::string &dset_name, hsize_t offset, - hsize_t nelems, hsize_t stride = 1) { - hid_t dset_id = H5Dopen2(hid, dset_name.c_str(), H5P_DEFAULT); - - hid_t memspace_id = H5Screate_simple(1, &nelems, NULL); - REQUIRE(memspace_id != H5I_INVALID_HID); - - if (dset_id == H5I_INVALID_HID) { - dset_id = H5Dcreate2(hid, dset_name.c_str(), H5T_NATIVE_FLOAT, - memspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - } - - REQUIRE(dset_id != H5I_INVALID_HID); - hid_t dspace_id = H5Dget_space(dset_id); - REQUIRE(dspace_id != H5I_INVALID_HID); - herr_t status = H5Sselect_hyperslab(dspace_id, H5S_SELECT_SET, &offset, - &stride, &nelems, NULL); - REQUIRE(status >= 0); - - RwIds result = {dset_id, dspace_id, memspace_id}; - - return result; - } - - /** - * Cleanup code required after H5Dread and H5Dwrite. - */ - void RwCleanup(RwIds *ids) { - REQUIRE(H5Sclose(ids->mspace_id) >= 0); - REQUIRE(H5Sclose(ids->dspace_id) >= 0); - REQUIRE(H5Dclose(ids->dset_id) >= 0); - } - - /** - * Reads @p nelems elements from the object represented by @p hid into @p buf, - * starting at element @p offset. - */ - void Read(hid_t hid, const std::string &dset_name, std::vector &buf, - hsize_t offset, hsize_t nelems) { - RwIds ids = RwPreamble(hid, dset_name, offset, nelems); - herr_t status = H5Dread(ids.dset_id, H5T_NATIVE_FLOAT, ids.mspace_id, - ids.dspace_id, H5P_DEFAULT, buf.data()); - REQUIRE(status >= 0); - - RwCleanup(&ids); - } - /** - Create a 1-dimensional dataset using \a data vector. - */ - void MakeDataset(hid_t hid, const std::string &dset_name, - const std::vector &data, bool compact = false) { - MakeDataset(hid, dset_name, data.data(), data.size(), compact); - } - - /** - * Create a 1-dimensional dataset named @p dset_name in object @p hid with @p - * nelems elements from the array @p data. - */ - void MakeDataset(hid_t hid, const std::string &dset_name, const f32 *data, - hsize_t nelems, bool compact = false) { - hid_t dcpl = H5P_DEFAULT; - herr_t status = 0; - - if (compact) { - REQUIRE(nelems * sizeof(f32) <= KILOBYTES(64)); - dcpl = H5Pcreate(H5P_DATASET_CREATE); - REQUIRE(dcpl != H5I_INVALID_HID); - status = H5Pset_layout(dcpl, H5D_COMPACT); - REQUIRE(status >= 0); - } - - hid_t memspace_id = H5Screate_simple(1, &nelems, NULL); - REQUIRE(memspace_id != H5I_INVALID_HID); - - hid_t dset_id = H5Dcreate2(hid, dset_name.c_str(), H5T_NATIVE_FLOAT, - memspace_id, H5P_DEFAULT, dcpl, H5P_DEFAULT); - REQUIRE(dset_id != H5I_INVALID_HID); - - hid_t dspace_id = H5Dget_space(dset_id); - REQUIRE(dspace_id != H5I_INVALID_HID); - - status = H5Dwrite(dset_id, H5T_NATIVE_FLOAT, memspace_id, - dspace_id, H5P_DEFAULT, data); - REQUIRE(status >= 0); - REQUIRE(H5Sclose(memspace_id) >= 0); - REQUIRE(H5Sclose(dspace_id) >= 0); - REQUIRE(H5Dclose(dset_id) >= 0); - - if (compact) { - REQUIRE(H5Pclose(dcpl) >= 0); - } - } - - /** - * Write @p nelems elements to the dataset @p dset_name in file @p hid - * starting at element @p offset. The dataset will be created if it doesn't - * already exist. - */ - void WritePartial1d(hid_t hid, const std::string &dset_name, - const f32 *data, hsize_t offset, hsize_t nelems) { - RwIds ids = RwPreamble(hid, dset_name, offset, nelems); - herr_t status = H5Dwrite(ids.dset_id, H5T_NATIVE_FLOAT, ids.mspace_id, - ids.dspace_id, H5P_DEFAULT, data); - REQUIRE(status >= 0); - - RwCleanup(&ids); - } - /** - Close HDF5 file. - */ - herr_t Close(hid_t id) { - herr_t result = H5Fclose(id); - - return result; - } -}; - -// xoshiro128+ random number generation. 2x speedup over std::mt19937: -// https://prng.di.unimi.it/xoshiro128plus.c - -static inline u32 RotateLeft(const u32 x, int k) { - u32 result = (x << k) | (x >> (32 - k)); - - return result; -} - -static u32 random_state[4] = {111, 222, 333, 444}; - -u32 GenNextRandom() { - const u32 random = random_state[0] + random_state[3]; - - const u32 t = random_state[1] << 9; - - random_state[2] ^= random_state[0]; - random_state[3] ^= random_state[1]; - random_state[1] ^= random_state[2]; - random_state[0] ^= random_state[3]; - - random_state[2] ^= t; - - random_state[3] = RotateLeft(random_state[3], 11); - - return random; -} - -/** - * Return a random float in the range [0.0f, 1.0f] - */ -f32 GenRandom0to1() { - u32 random_u32 = GenNextRandom(); - - f32 result = (random_u32 >> 8) * 0x1.0p-24f; - - return result; +int main(int argc, char **argv) { + TESTER->Init(argc, argv); } - -/** - * Create an HDF5 file called @p fname with @p num_datasets datasets, each with - * @p num_dataset_elems elements. - */ -void GenHdf5File(std::string fname, size_t num_dataset_elems, - size_t num_datasets) { - std::vector data(num_dataset_elems * num_datasets); - - for (size_t i = 0; i < data.size(); ++i) { - data[i] = GenRandom0to1(); - } - - Hdf5Api api; - f32 *at = data.data(); - - hid_t file_id = api.CreatePosix(fname, H5F_ACC_TRUNC); - REQUIRE(file_id != H5I_INVALID_HID); - - for (size_t i = 0; i < num_datasets; ++i) { - api.MakeDataset(file_id, std::to_string(i), at, num_dataset_elems); - at += num_dataset_elems; - } - - REQUIRE(api.Close(file_id) > -1); -} - -} // namespace hermes::adapter::vfd::test - -hermes::adapter::vfd::test::Arguments args; -hermes::adapter::vfd::test::TestInfo info; - -using hermes::adapter::vfd::test::GenHdf5File; -using hermes::adapter::vfd::test::GenNextRandom; -using hermes::adapter::vfd::test::GenRandom0to1; - -void IgnoreAllFiles() { -#if HERMES_INTERCEPT == 1 - HERMES_CLIENT_CONF.SetAdapterPathTracking(info.existing_file_cmp, false); - HERMES_CLIENT_CONF.SetAdapterPathTracking(info.new_file_cmp, false); - HERMES_CLIENT_CONF.SetAdapterPathTracking(info.new_file, false); - HERMES_CLIENT_CONF.SetAdapterPathTracking(info.existing_file, false); -#endif -} - -void TrackFiles() { -#if HERMES_INTERCEPT == 1 - HERMES_CLIENT_CONF.SetAdapterPathTracking(info.new_file, true); - HERMES_CLIENT_CONF.SetAdapterPathTracking(info.existing_file, true); -#endif -} - -void RemoveFile(const std::string &path) { - stdfs::remove(path); - if (stdfs::exists(path)) { - HELOG(kFatal, "Failed to remove: {}", path) - } -} - -void RemoveFiles() { - RemoveFile(info.new_file); - RemoveFile(info.new_file_cmp); - RemoveFile(info.existing_file); - RemoveFile(info.existing_file_cmp); -} - -/** - * Called in the Catch2 main function (see catch_config.h) before any tests are - * run. Initialize sizes, filenames, and read/write buffers. - */ -int init(int* argc, char*** argv) { -#if HERMES_INTERCEPT == 1 - setenv("HERMES_FLUSH_MODE", "kSync", 1); - TRANSPARENT_HERMES(); - HERMES_CLIENT_CONF.flushing_mode_ = hermes::FlushingMode::kSync; -#endif - MPI_Init(argc, argv); - - if (args.request_size % info.element_size != 0) { - HELOG(kFatal, "request_size must be a multiple of: {}", info.element_size) - } - info.nelems_per_dataset = args.request_size / info.element_size; - - info.write_data.resize(info.nelems_per_dataset); - for (size_t i = 0; i < info.write_data.size(); ++i) { - info.write_data[i] = GenRandom0to1(); - } - info.read_data.resize(info.nelems_per_dataset); - for (size_t i = 0; i < info.read_data.size(); ++i) { - info.read_data[i] = 0.0f; - } - - stdfs::path fullpath = args.directory; - fullpath /= args.filename; - std::string suffix = std::to_string(getpid()) + info.hdf5_extension; - info.new_file = fullpath.string() + "_new_" + suffix; - info.existing_file = fullpath.string() + "_ext_" + suffix; - info.new_file_cmp = fullpath.string() + "_new_cmp_" + suffix; - info.existing_file_cmp = fullpath.string() + "_ext_cmp_" + suffix; - IgnoreAllFiles(); - RemoveFiles(); - return 0; -} - -/** - * Called from catch_config.h after all tests are run. - */ -int finalize() { - MPI_Finalize(); - return 0; -} - -/** - * Called before each individual test. - * - * Generates files for tests that operate on existing files. - */ -int Pretest() { - IgnoreAllFiles(); - RemoveFiles(); - - GenHdf5File(info.existing_file, info.nelems_per_dataset, info.num_iterations); - info.total_size = stdfs::file_size(info.existing_file); - std::string cmd = "cp " + info.existing_file + " " + info.existing_file_cmp; - int status = system(cmd.c_str()); - REQUIRE(status != -1); - REQUIRE(info.total_size > 0); - - TrackFiles(); - return 0; -} - -/** - * Use h5diff to ensure that the resulting files from the Hermes VFD and the - * POSIX VFD are the same. - */ -void CheckResults(const std::string &file1, const std::string &file2) { - if (stdfs::exists(file1) && stdfs::exists(file2)) { - std::string h5diff_cmd = "h5diff " + file1 + " " + file2; - int status = system(h5diff_cmd.c_str()); - if (status != 0) { - HELOG(kError, "Failing h5diff command: {}", h5diff_cmd) - } - REQUIRE(status == 0); - } -} - -/** - * Called after each individual test. - */ -int Posttest() { - if (HERMES_CLIENT_CONF.GetBaseAdapterMode() - != hermes::adapter::AdapterMode::kScratch) { - // NOTE(chogan): This is necessary so that h5diff doesn't use the Hermes VFD - // in CheckResults. We don't need to reset LD_PRELOAD because it only has an - // effect when an application first starts. - unsetenv("HDF5_DRIVER"); - // CheckResults(info.new_file, info.new_file_cmp); - // CheckResults(info.existing_file, info.existing_file_cmp); - setenv("HDF5_DRIVER", "hdf5_hermes_vfd", 1); - } - - RemoveFiles(); -#if HERMES_INTERCEPT == 1 - HERMES->Clear(); -#endif - - return 0; -} - -cl::Parser define_options() { - return cl::Opt(args.filename, "filename")["-f"]["--filename"]( - "Filename used for performing I/O") | - cl::Opt(args.directory, "dir")["-d"]["--directory"]( - "Directory used for performing I/O") | - cl::Opt(args.request_size, "request_size")["-s"]["--request_size"]( - "Request size used for performing I/O"); -} - -using hermes::adapter::vfd::test::Hdf5Api; - -/** - * The functions in this namespace perform operations on 2 files: the "main" - * file, which is the one going through the Hermes VFD, and a comparison file - * (with a "_cmp" suffix) which goes through the POSIX VFD. The idea is to - * perfrom each test on 2 files (Hermes VFD and POSIX VFD) and then compare the - * results at the end with h5diff. In persistent mode, the file produced by the - * Hermes VFD should be exactly the same as the one produced by the POSIX VFD. - */ -namespace test { - -hid_t hermes_hid; /**< Hermes handle ID */ -hid_t sec2_hid; /**< POSIX driver handle ID */ -herr_t hermes_herr; /**< Hermes error return value */ -/** - Test creating and opening a new file. -*/ -void TestOpen(const std::string &path, unsigned flags, bool create = false) { - Hdf5Api api; - - std::string cmp_path; - if (path == info.new_file) { - cmp_path = info.new_file_cmp; - } else { - cmp_path = info.existing_file_cmp; - } - - if (create) { - hermes_hid = api.Create(path, flags); - sec2_hid = api.CreatePosix(cmp_path, flags); - } else { - hermes_hid = api.Open(path, flags); - sec2_hid = api.OpenPosix(cmp_path, flags); - } - bool is_same = - (sec2_hid != H5I_INVALID_HID && hermes_hid != H5I_INVALID_HID) || - (sec2_hid == H5I_INVALID_HID && hermes_hid == H5I_INVALID_HID); - - REQUIRE(is_same); -} -/** - Test Close() calls. -*/ -void TestClose() { - Hdf5Api api; - hermes_herr = api.Close(hermes_hid); - herr_t status = api.Close(sec2_hid); - REQUIRE(status == hermes_herr); -} - -/** - Test writing partial 1-D dataset. -*/ -void TestWritePartial1d(const std::string &dset_name, const f32 *data, - hsize_t offset, hsize_t nelems) { - Hdf5Api api; - api.WritePartial1d(test::hermes_hid, dset_name, data, offset, nelems); - api.WritePartial1d(test::sec2_hid, dset_name, data, offset, nelems); -} - -/** - Test making dataset. -*/ -void TestWriteDataset(const std::string &dset_name, - const std::vector &data) { - Hdf5Api api; - api.MakeDataset(test::hermes_hid, dset_name, data); - api.MakeDataset(test::sec2_hid, dset_name, data); -} - - -/** - Test making compact dataset. -*/ -void TestMakeCompactDataset(const std::string &dset_name, - const std::vector &data) { - Hdf5Api api; - api.MakeDataset(test::hermes_hid, dset_name, data, true); - api.MakeDataset(test::sec2_hid, dset_name, data, true); -} - -/** - Test reading dataset. -*/ -void TestRead(const std::string &dset_name, std::vector &buf, - hsize_t offset, hsize_t nelems) { - Hdf5Api api; - api.Read(test::hermes_hid, dset_name, buf, offset, nelems); - std::vector sec2_read_buf(nelems, 0.0f); - api.Read(test::sec2_hid, dset_name, sec2_read_buf, offset, nelems); - - REQUIRE(std::equal(buf.begin(), buf.begin() + nelems, sec2_read_buf.begin())); -} -} // namespace test - -#include "hermes_vfd_basic_test.cc" diff --git a/test/unit/hermes_adapters/vfd/hermes_vfd_test.h b/test/unit/hermes_adapters/vfd/hermes_vfd_test.h new file mode 100644 index 000000000..4742a4164 --- /dev/null +++ b/test/unit/hermes_adapters/vfd/hermes_vfd_test.h @@ -0,0 +1,409 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Distributed under BSD 3-Clause license. * + * Copyright by The HDF Group. * + * Copyright by the Illinois Institute of Technology. * + * All rights reserved. * + * * + * This file is part of Hermes. The full Hermes copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the COPYING file, which can be found at the top directory. If you do not * + * have access to the file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#ifndef HERMES_TEST_UNIT_HERMES_ADAPTERS_HDF5_VFD_TESTS_H_ +#define HERMES_TEST_UNIT_HERMES_ADAPTERS_HDF5_VFD_TESTS_H_ + +#include "filesystem_tests.h" +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "hermes_shm/util/singleton.h" +#include "hermes/hermes.h" + +#define CATCH_CONFIG_RUNNER +#include +#include + +namespace hermes::adapter::test { + +/** + * Temporarily disable printing of the HDF5 error stack. + * + * Some tests intentionally trigger HDF5 errors, and in those cases we don't + * want to clutter the output with HDF5 error messages. + */ +class MuteHdf5Errors { + H5E_auto2_t old_func; /**< error handler callback function */ + void *old_client_data; /**< pointer to client data for old_func */ + + public: + MuteHdf5Errors() { + // Save old error handler + H5Eget_auto(H5E_DEFAULT, &old_func, &old_client_data); + + // Turn off error stack printing + H5Eset_auto(H5E_DEFAULT, NULL, NULL); + } + + ~MuteHdf5Errors() { + // Restore previous error handler + H5Eset_auto(H5E_DEFAULT, old_func, old_client_data); + } +}; + +/** + * HDF5 identifiers required for reads and writes. + */ +struct RwIds { + hid_t dset_id; /**< dataset ID */ + hid_t dspace_id; /**< data space ID */ + hid_t mspace_id; /**< memory space ID */ +}; + +/** + * The I/O API for this adapter layer. + * + * Ideally we would have a high level Adapter I/O API that each adapter inherits + * from so that the adapter tests can reuse more code. This is a step in that + * direction. + */ +struct Hdf5Api { + /** + * A file access property list representing the sec2 (POSIX) VFD. + */ + hid_t sec2_fapl; + + Hdf5Api() : sec2_fapl(H5I_INVALID_HID) { + sec2_fapl = H5Pcreate(H5P_FILE_ACCESS); + REQUIRE(sec2_fapl != H5I_INVALID_HID); + REQUIRE(H5Pset_fapl_sec2(sec2_fapl) >= 0); + } + + ~Hdf5Api() { + REQUIRE(H5Pclose(sec2_fapl) >= 0); + sec2_fapl = H5I_INVALID_HID; + } + + /** + * Open an existing file using the default VFD. Since the tests are run with + * HDF5_DRIVER=hermes, the default VFD will be the Hermes VFD. + */ + hid_t Open(const std::string &fname, unsigned flags) { + hid_t result = H5Fopen(fname.c_str(), flags, H5P_DEFAULT); + + return result; + } + + /** + * Open an existing file using the POSIX VFD. This will bypass Hermes. + */ + hid_t OpenPosix(const std::string &fname, unsigned flags) { + hid_t result = H5Fopen(fname.c_str(), flags, sec2_fapl); + + return result; + } + + /** + * Create a file using the default VFD. + */ + hid_t Create(const std::string &fname, unsigned flags) { + hid_t result = H5Fcreate(fname.c_str(), flags, H5P_DEFAULT, H5P_DEFAULT); + + return result; + } + + /** + * Create a file using the POSIX VFD. + */ + hid_t CreatePosix(const std::string &fname, unsigned flags) { + hid_t result = H5Fcreate(fname.c_str(), flags, H5P_DEFAULT, sec2_fapl); + + return result; + } + + /** + * Boilerplate necessary before calling H5Dread or H5Dwrite. + */ + RwIds RwPreamble(hid_t hid, const std::string &dset_name, hsize_t offset, + hsize_t nelems, hsize_t stride = 1) { + hid_t dset_id = H5Dopen2(hid, dset_name.c_str(), H5P_DEFAULT); + + hid_t memspace_id = H5Screate_simple(1, &nelems, NULL); + REQUIRE(memspace_id != H5I_INVALID_HID); + + if (dset_id == H5I_INVALID_HID) { + dset_id = H5Dcreate2(hid, dset_name.c_str(), H5T_NATIVE_FLOAT, + memspace_id, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); + } + + REQUIRE(dset_id != H5I_INVALID_HID); + hid_t dspace_id = H5Dget_space(dset_id); + REQUIRE(dspace_id != H5I_INVALID_HID); + herr_t status = H5Sselect_hyperslab(dspace_id, H5S_SELECT_SET, &offset, + &stride, &nelems, NULL); + REQUIRE(status >= 0); + + RwIds result = {dset_id, dspace_id, memspace_id}; + + return result; + } + + /** + * Cleanup code required after H5Dread and H5Dwrite. + */ + void RwCleanup(RwIds *ids) { + REQUIRE(H5Sclose(ids->mspace_id) >= 0); + REQUIRE(H5Sclose(ids->dspace_id) >= 0); + REQUIRE(H5Dclose(ids->dset_id) >= 0); + } + + /** + * Reads @p nelems elements from the object represented by @p hid into @p buf, + * starting at element @p offset. + */ + void Read(hid_t hid, const std::string &dset_name, std::vector &buf, + hsize_t offset, hsize_t nelems) { + RwIds ids = RwPreamble(hid, dset_name, offset, nelems); + herr_t status = H5Dread(ids.dset_id, H5T_NATIVE_FLOAT, ids.mspace_id, + ids.dspace_id, H5P_DEFAULT, buf.data()); + REQUIRE(status >= 0); + + RwCleanup(&ids); + } + /** + Create a 1-dimensional dataset using \a data vector. + */ + void MakeDataset(hid_t hid, const std::string &dset_name, + const std::vector &data, bool compact = false) { + MakeDataset(hid, dset_name, data.data(), data.size(), compact); + } + + /** + * Create a 1-dimensional dataset named @p dset_name in object @p hid with @p + * nelems elements from the array @p data. + */ + void MakeDataset(hid_t hid, const std::string &dset_name, const f32 *data, + hsize_t nelems, bool compact = false) { + hid_t dcpl = H5P_DEFAULT; + herr_t status = 0; + + if (compact) { + REQUIRE(nelems * sizeof(f32) <= KILOBYTES(64)); + dcpl = H5Pcreate(H5P_DATASET_CREATE); + REQUIRE(dcpl != H5I_INVALID_HID); + status = H5Pset_layout(dcpl, H5D_COMPACT); + REQUIRE(status >= 0); + } + + hid_t memspace_id = H5Screate_simple(1, &nelems, NULL); + REQUIRE(memspace_id != H5I_INVALID_HID); + + hid_t dset_id = H5Dcreate2(hid, dset_name.c_str(), H5T_NATIVE_FLOAT, + memspace_id, H5P_DEFAULT, dcpl, H5P_DEFAULT); + REQUIRE(dset_id != H5I_INVALID_HID); + + hid_t dspace_id = H5Dget_space(dset_id); + REQUIRE(dspace_id != H5I_INVALID_HID); + + status = H5Dwrite(dset_id, H5T_NATIVE_FLOAT, memspace_id, + dspace_id, H5P_DEFAULT, data); + REQUIRE(status >= 0); + REQUIRE(H5Sclose(memspace_id) >= 0); + REQUIRE(H5Sclose(dspace_id) >= 0); + REQUIRE(H5Dclose(dset_id) >= 0); + + if (compact) { + REQUIRE(H5Pclose(dcpl) >= 0); + } + } + + /** + * Write @p nelems elements to the dataset @p dset_name in file @p hid + * starting at element @p offset. The dataset will be created if it doesn't + * already exist. + */ + void WritePartial1d(hid_t hid, const std::string &dset_name, + const f32 *data, hsize_t offset, hsize_t nelems) { + RwIds ids = RwPreamble(hid, dset_name, offset, nelems); + herr_t status = H5Dwrite(ids.dset_id, H5T_NATIVE_FLOAT, ids.mspace_id, + ids.dspace_id, H5P_DEFAULT, data); + REQUIRE(status >= 0); + + RwCleanup(&ids); + } + /** + Close HDF5 file. + */ + herr_t Close(hid_t id) { + herr_t result = H5Fclose(id); + + return result; + } +}; + +template +class Hdf5VfdTests : public FilesystemTests { + public: + FileInfo new_file_; + FileInfo existing_file_; + FileInfo shared_new_file_; + FileInfo shared_existing_file_; + // int offset_seed = 1; + // unsigned int rs_seed = 1; + // unsigned int temporal_interval_seed = 5; + // size_t stride_size = 512; + unsigned int temporal_interval_ms_ = 1; /**< interval in milliseconds */ + // size_t small_min = 1; + // size_t small_max = KILOBYTES(4); + // size_t medium_min = KILOBYTES(4) + 1; + // size_t medium_max = KILOBYTES(256); + // size_t large_min = KILOBYTES(256) + 1; + // size_t large_max = MEGABYTES(3); + + hid_t hermes_hid_; /**< Hermes handle ID */ + hid_t sec2_hid_; /**< POSIX driver handle ID */ + herr_t hermes_herr_; /**< Hermes error return value */ + + public: + void RegisterFiles() override { + RegisterPath("new", 0, new_file_); + RegisterPath("ext", TEST_DO_CREATE, existing_file_); + if constexpr(WITH_MPI) { + RegisterPath("shared_new", TEST_FILE_SHARED, shared_new_file_); + RegisterPath("shared_ext", TEST_DO_CREATE | TEST_FILE_SHARED, + shared_existing_file_); + } + } + + void CompareFiles(FileInfo &info) override { + const char *driver = getenv("HDF5_DRIVER"); + if (driver != nullptr) { + unsetenv("HDF5_DRIVER"); + } + std::string h5diff_cmd = "h5diff " + info.hermes_ + " " + info.cmp_; + int status = system(h5diff_cmd.c_str()); + if (status != 0) { + HELOG(kError, "Failing h5diff command: {}", h5diff_cmd) + } + if (driver != nullptr) { + setenv("HDF5_DRIVER", driver, 1); + } + REQUIRE(status == 0); + } + + std::vector GenerateData() override { + std::vector data(request_size_ * num_iterations_); + for (size_t i = 0; i < data.size(); ++i) { + data[i] = GenRandom0to1(); + } + return data; + } + + /** + * Create an HDF5 file called @p fname with @p num_datasets datasets, each with + * @p num_dataset_elems elements. + * */ + void CreateFile(const std::string &path, + std::vector &data) override { + Hdf5Api api; + f32 *at = (f32*)data.data(); + hid_t file_id = api.CreatePosix(path, H5F_ACC_TRUNC); + REQUIRE(file_id != H5I_INVALID_HID); + for (size_t i = 0; i < num_iterations_; ++i) { + api.MakeDataset(file_id, std::to_string(i), at, request_size_); + at += request_size_; + } + REQUIRE(api.Close(file_id) > -1); + } + + public: + /** + * Test creating and opening a new file. + * */ + void TestOpen(FileInfo &info, unsigned flags, bool create = false) { + Hdf5Api api; + if (create) { + hermes_hid_ = api.Create(info.hermes_, flags); + sec2_hid_ = api.CreatePosix(info.cmp_, flags); + } else { + hermes_hid_ = api.Open(info.hermes_, flags); + sec2_hid_ = api.OpenPosix(info.cmp_, flags); + } + bool is_same = + (sec2_hid_ != H5I_INVALID_HID && hermes_hid_ != H5I_INVALID_HID) || + (sec2_hid_ == H5I_INVALID_HID && hermes_hid_ == H5I_INVALID_HID); + + REQUIRE(is_same); + } + /** + * @return Test Close() calls + * */ + void TestClose() { + Hdf5Api api; + hermes_herr_ = api.Close(hermes_hid_); + herr_t status = api.Close(sec2_hid_); + REQUIRE(status == hermes_herr_); + } + + /** + * Test writing partial 1-D dataset. + * */ + void TestWritePartial1d(const std::string &dset_name, const f32 *data, + hsize_t offset, hsize_t nelems) { + Hdf5Api api; + api.WritePartial1d(hermes_hid_, dset_name, data, offset, nelems); + api.WritePartial1d(sec2_hid_, dset_name, data, offset, nelems); + } + + /** + * Test making dataset. + * */ + void TestWriteDataset(const std::string &dset_name, + const std::vector &data) { + Hdf5Api api; + api.MakeDataset(hermes_hid_, dset_name, data); + api.MakeDataset(sec2_hid_, dset_name, data); + } + + + /** + * Test making compact dataset. + * */ + void TestMakeCompactDataset(const std::string &dset_name, + const std::vector &data) { + Hdf5Api api; + api.MakeDataset(hermes_hid_, dset_name, data, true); + api.MakeDataset(sec2_hid_, dset_name, data, true); + } + + /** + * Test reading dataset. + * */ + void TestRead(const std::string &dset_name, std::vector &buf, + hsize_t offset, hsize_t nelems) { + Hdf5Api api; + api.Read(hermes_hid_, dset_name, buf, offset, nelems); + std::vector sec2_read_buf(nelems, 0.0f); + api.Read(sec2_hid_, dset_name, sec2_read_buf, offset, nelems); + REQUIRE(std::equal(buf.begin(), buf.begin() + nelems, + sec2_read_buf.begin())); + } +}; + +} // namespace hermes::adapter::test + +#define TESTER \ + hshm::EasySingleton>::GetInstance() + +#endif // HERMES_TEST_UNIT_HERMES_ADAPTERS_HDF5_VFD_TESTS_H_ diff --git a/test/unit/hermes_adapters/vfd/tests.py b/test/unit/hermes_adapters/vfd/tests.py deleted file mode 100644 index 132a1a545..000000000 --- a/test/unit/hermes_adapters/vfd/tests.py +++ /dev/null @@ -1,39 +0,0 @@ -from py_hermes_ci.test_manager import TestManager -from jarvis_util import * - - -class VfdTestManager(TestManager): - def spawn_all_nodes(self): - return self.spawn_info() - - def set_paths(self): - self.VFD_CMD = f"{self.CMAKE_BINARY_DIR}/bin/vfd_adapter_test" - self.HERMES_VFD_CMD = f"{self.CMAKE_BINARY_DIR}/bin/hermes_vfd_adapter_test" - self.disable_testing = False - - def test_vfd_basic(self): - vfd_cmd = f"{self.VFD_CMD}" - node = Exec(vfd_cmd) - return node.exit_code - - def test_hermes_vfd_default(self): - vfd_cmd = f"{self.HERMES_VFD_CMD} SingleWrite" - spawn_info = self.spawn_info(nprocs=1, - hermes_conf='hermes_server', - hermes_mode='kDefault', - api='vfd') - self.start_daemon(spawn_info) - node = Exec(vfd_cmd, spawn_info) - self.stop_daemon(spawn_info) - return node.exit_code - - def test_hermes_vfd_scratch(self): - vfd_cmd = f"{self.HERMES_VFD_CMD} [scratch]" - spawn_info = self.spawn_info(nprocs=1, - hermes_conf='hermes_server', - hermes_mode='kScratch', - api='vfd') - self.start_daemon(spawn_info) - node = Exec(vfd_cmd, spawn_info) - self.stop_daemon(spawn_info) - return node.exit_code \ No newline at end of file diff --git a/test/unit/ipc/CMakeLists.txt b/test/unit/ipc/CMakeLists.txt index d6eff102a..d62f05703 100644 --- a/test/unit/ipc/CMakeLists.txt +++ b/test/unit/ipc/CMakeLists.txt @@ -42,5 +42,5 @@ install(TARGETS # Coverage #----------------------------------------------------------------------------- if(HERMES_ENABLE_COVERAGE) - set_coverage_flags(test_messages) + set_coverage_flags(test_ipc_exec) endif() diff --git a/test/unit/pipelines/hermes/test_hermes.yaml b/test/unit/pipelines/hermes/test_hermes.yaml new file mode 100644 index 000000000..4050a8f22 --- /dev/null +++ b/test/unit/pipelines/hermes/test_hermes.yaml @@ -0,0 +1,10 @@ +name: hermes_unit_hermes_mpiio_basic_large +env: hermes +pkgs: + - pkg_type: hermes_run + pkg_name: hermes_run + ram: 16m + sleep: 5 + - pkg_type: hermes_unit_tests + pkg_name: hermes_unit_tests + TEST_CASE: hermes diff --git a/test/unit/pipelines/mpiio/test_hermes_mpiio_basic_async.yaml b/test/unit/pipelines/mpiio/test_hermes_mpiio_basic_async.yaml new file mode 100644 index 000000000..2e3635c6c --- /dev/null +++ b/test/unit/pipelines/mpiio/test_hermes_mpiio_basic_async.yaml @@ -0,0 +1,11 @@ +name: hermes_unit_hermes_mpiio_basic_large +env: hermes +pkgs: + - pkg_type: hermes_run + pkg_name: hermes_run + sleep: 5 + - pkg_type: hermes_mpiio_tests + pkg_name: hermes_mpiio_tests + test_file: mpiio_basic + hermes: true + size: large diff --git a/test/unit/pipelines/mpiio/test_hermes_mpiio_basic_sync.yaml b/test/unit/pipelines/mpiio/test_hermes_mpiio_basic_sync.yaml new file mode 100644 index 000000000..ba639d2ff --- /dev/null +++ b/test/unit/pipelines/mpiio/test_hermes_mpiio_basic_sync.yaml @@ -0,0 +1,11 @@ +name: hermes_unit_hermes_mpiio_basic_async +env: hermes +pkgs: + - pkg_type: hermes_run + pkg_name: hermes_run + sleep: 2 + - pkg_type: hermes_mpiio_tests + pkg_name: hermes_mpiio_tests + test_file: mpiio_basic + hermes: true + sync: async \ No newline at end of file diff --git a/test/unit/pipelines/mpiio/test_mpiio_basic.yaml b/test/unit/pipelines/mpiio/test_mpiio_basic.yaml new file mode 100644 index 000000000..576f92ab2 --- /dev/null +++ b/test/unit/pipelines/mpiio/test_mpiio_basic.yaml @@ -0,0 +1,7 @@ +name: hermes_unit_mpiio_basic +env: hermes +pkgs: + - pkg_type: hermes_mpiio_tests + pkg_name: hermes_mpiio_tests + test_file: mpiio_basic + hermes: false \ No newline at end of file diff --git a/test/unit/pipelines/posix/test_hermes_posix_basic_large.yaml b/test/unit/pipelines/posix/test_hermes_posix_basic_large.yaml index 369b03506..8b95a425f 100644 --- a/test/unit/pipelines/posix/test_hermes_posix_basic_large.yaml +++ b/test/unit/pipelines/posix/test_hermes_posix_basic_large.yaml @@ -1,11 +1,9 @@ name: hermes_unit_hermes_posix_basic_large env: hermes pkgs: - - pkg_type: asan - pkg_name: asan - pkg_type: hermes_run pkg_name: hermes_run - sleep: 2 + sleep: 5 - pkg_type: hermes_posix_tests pkg_name: hermes_posix_tests test_file: posix_basic diff --git a/test/unit/pipelines/posix/test_hermes_posix_basic_mpi_large.yaml b/test/unit/pipelines/posix/test_hermes_posix_basic_mpi_large.yaml index b6e79d66d..51a6f4d46 100644 --- a/test/unit/pipelines/posix/test_hermes_posix_basic_mpi_large.yaml +++ b/test/unit/pipelines/posix/test_hermes_posix_basic_mpi_large.yaml @@ -1,8 +1,6 @@ name: hermes_unit_hermes_posix_basic_mpi_large env: hermes pkgs: - - pkg_type: asan - pkg_name: asan - pkg_type: hermes_run pkg_name: hermes_run sleep: 2 diff --git a/test/unit/pipelines/posix/test_hermes_posix_basic_mpi_small.yaml b/test/unit/pipelines/posix/test_hermes_posix_basic_mpi_small.yaml index 5d0a72a69..a461c79f2 100644 --- a/test/unit/pipelines/posix/test_hermes_posix_basic_mpi_small.yaml +++ b/test/unit/pipelines/posix/test_hermes_posix_basic_mpi_small.yaml @@ -1,8 +1,6 @@ name: hermes_unit_hermes_posix_basic_mpi_small env: hermes pkgs: - - pkg_type: asan - pkg_name: asan - pkg_type: hermes_run pkg_name: hermes_run sleep: 2 diff --git a/test/unit/pipelines/posix/test_hermes_posix_basic_small.yaml b/test/unit/pipelines/posix/test_hermes_posix_basic_small.yaml index d392bbfa6..26f6b0f63 100644 --- a/test/unit/pipelines/posix/test_hermes_posix_basic_small.yaml +++ b/test/unit/pipelines/posix/test_hermes_posix_basic_small.yaml @@ -1,8 +1,6 @@ name: hermes_unit_hermes_posix_basic_small env: hermes pkgs: - - pkg_type: asan - pkg_name: asan - pkg_type: hermes_run pkg_name: hermes_run sleep: 2 diff --git a/test/unit/pipelines/posix/test_hermes_posix_simple_io_omp.yaml b/test/unit/pipelines/posix/test_hermes_posix_simple_io_omp.yaml index 94f6db766..6a41a707b 100644 --- a/test/unit/pipelines/posix/test_hermes_posix_simple_io_omp.yaml +++ b/test/unit/pipelines/posix/test_hermes_posix_simple_io_omp.yaml @@ -1,8 +1,6 @@ name: hermes_unit_hermes_posix_simple_io_omp env: hermes pkgs: - - pkg_type: asan - pkg_name: asan - pkg_type: hermes_run pkg_name: hermes_run sleep: 2 diff --git a/test/unit/pipelines/posix/test_posix_basic.yaml b/test/unit/pipelines/posix/test_posix_basic.yaml index eae820b6c..eb9bb1a41 100644 --- a/test/unit/pipelines/posix/test_posix_basic.yaml +++ b/test/unit/pipelines/posix/test_posix_basic.yaml @@ -1,8 +1,6 @@ name: hermes_unit_posix_basic env: hermes pkgs: - - pkg_type: asan - pkg_name: asan - pkg_type: hermes_posix_tests pkg_name: hermes_posix_tests test_file: posix_basic diff --git a/test/unit/pipelines/posix/test_posix_basic_mpi.yaml b/test/unit/pipelines/posix/test_posix_basic_mpi.yaml index dd0a8f348..99bcd3db4 100644 --- a/test/unit/pipelines/posix/test_posix_basic_mpi.yaml +++ b/test/unit/pipelines/posix/test_posix_basic_mpi.yaml @@ -1,8 +1,6 @@ name: hermes_unit_posix_basic_mpi env: hermes pkgs: - - pkg_type: asan - pkg_name: asan - pkg_type: hermes_posix_tests pkg_name: hermes_posix_tests test_file: posix_basic_mpi diff --git a/test/unit/pipelines/posix/test_posix_simple_io_omp.yaml b/test/unit/pipelines/posix/test_posix_simple_io_omp.yaml index 022964bd7..09a34ff39 100644 --- a/test/unit/pipelines/posix/test_posix_simple_io_omp.yaml +++ b/test/unit/pipelines/posix/test_posix_simple_io_omp.yaml @@ -1,8 +1,6 @@ name: hermes_unit_posix_simple_io_omp env: hermes pkgs: - - pkg_type: asan - pkg_name: asan - pkg_type: hermes_posix_tests pkg_name: hermes_posix_tests test_file: posix_simple_io_omp diff --git a/test/unit/pipelines/stdio/test_hermes_stdio_adapter_bypass.yaml b/test/unit/pipelines/stdio/test_hermes_stdio_adapter_bypass.yaml new file mode 100644 index 000000000..f70b30757 --- /dev/null +++ b/test/unit/pipelines/stdio/test_hermes_stdio_adapter_bypass.yaml @@ -0,0 +1,12 @@ +name: hermes_unit_hermes_stdio_basic_small +env: hermes +pkgs: + - pkg_type: hermes_run + pkg_name: hermes_run + sleep: 2 + - pkg_type: hermes_stdio_tests + pkg_name: hermes_stdio_tests + test_file: stdio_adapter_mode + test_case: BatchedWriteSequentialBypass + hermes: true + size: small \ No newline at end of file diff --git a/test/unit/pipelines/stdio/test_hermes_stdio_adapter_default.yaml b/test/unit/pipelines/stdio/test_hermes_stdio_adapter_default.yaml new file mode 100644 index 000000000..e8b56d196 --- /dev/null +++ b/test/unit/pipelines/stdio/test_hermes_stdio_adapter_default.yaml @@ -0,0 +1,12 @@ +name: hermes_unit_hermes_stdio_basic_small +env: hermes +pkgs: + - pkg_type: hermes_run + pkg_name: hermes_run + sleep: 2 + - pkg_type: hermes_stdio_tests + pkg_name: hermes_stdio_tests + test_file: stdio_adapter_mode + test_case: BatchedWriteSequentialPersistent + hermes: true + size: small \ No newline at end of file diff --git a/test/unit/pipelines/stdio/test_hermes_stdio_adapter_scratch.yaml b/test/unit/pipelines/stdio/test_hermes_stdio_adapter_scratch.yaml new file mode 100644 index 000000000..c4fa8f3a3 --- /dev/null +++ b/test/unit/pipelines/stdio/test_hermes_stdio_adapter_scratch.yaml @@ -0,0 +1,12 @@ +name: hermes_unit_hermes_stdio_basic_small +env: hermes +pkgs: + - pkg_type: hermes_run + pkg_name: hermes_run + sleep: 2 + - pkg_type: hermes_stdio_tests + pkg_name: hermes_stdio_tests + test_file: stdio_adapter_mode + test_case: BatchedWriteSequentialScratch + hermes: true + size: small \ No newline at end of file diff --git a/test/unit/pipelines/stdio/test_hermes_stdio_basic_large.yaml b/test/unit/pipelines/stdio/test_hermes_stdio_basic_large.yaml index 6398b6e19..c4972f1b1 100644 --- a/test/unit/pipelines/stdio/test_hermes_stdio_basic_large.yaml +++ b/test/unit/pipelines/stdio/test_hermes_stdio_basic_large.yaml @@ -1,8 +1,6 @@ name: hermes_unit_hermes_stdio_basic_large env: hermes pkgs: - - pkg_type: asan - pkg_name: asan - pkg_type: hermes_run pkg_name: hermes_run sleep: 2 diff --git a/test/unit/pipelines/stdio/test_hermes_stdio_basic_mpi_large.yaml b/test/unit/pipelines/stdio/test_hermes_stdio_basic_mpi_large.yaml new file mode 100644 index 000000000..126926539 --- /dev/null +++ b/test/unit/pipelines/stdio/test_hermes_stdio_basic_mpi_large.yaml @@ -0,0 +1,11 @@ +name: hermes_unit_hermes_stdio_basic_mpi_large +env: hermes +pkgs: + - pkg_type: hermes_run + pkg_name: hermes_run + sleep: 2 + - pkg_type: hermes_stdio_tests + pkg_name: hermes_stdio_tests + test_file: stdio_basic_mpi + hermes: true + size: large diff --git a/test/unit/pipelines/stdio/test_hermes_stdio_basic_mpi_small.yaml b/test/unit/pipelines/stdio/test_hermes_stdio_basic_mpi_small.yaml new file mode 100644 index 000000000..24fce5ea9 --- /dev/null +++ b/test/unit/pipelines/stdio/test_hermes_stdio_basic_mpi_small.yaml @@ -0,0 +1,11 @@ +name: hermes_unit_hermes_stdio_basic_mpi_small +env: hermes +pkgs: + - pkg_type: hermes_run + pkg_name: hermes_run + sleep: 2 + - pkg_type: hermes_stdio_tests + pkg_name: hermes_stdio_tests + test_file: stdio_basic_mpi + hermes: true + size: small \ No newline at end of file diff --git a/test/unit/pipelines/stdio/test_hermes_stdio_basic_small.yaml b/test/unit/pipelines/stdio/test_hermes_stdio_basic_small.yaml index 8b795dbfb..ae626a913 100644 --- a/test/unit/pipelines/stdio/test_hermes_stdio_basic_small.yaml +++ b/test/unit/pipelines/stdio/test_hermes_stdio_basic_small.yaml @@ -1,8 +1,6 @@ name: hermes_unit_hermes_stdio_basic_small env: hermes pkgs: - - pkg_type: asan - pkg_name: asan - pkg_type: hermes_run pkg_name: hermes_run sleep: 2 diff --git a/test/unit/pipelines/stdio/test_hermes_stdio_low_buf.yaml b/test/unit/pipelines/stdio/test_hermes_stdio_low_buf.yaml new file mode 100644 index 000000000..47036fbb5 --- /dev/null +++ b/test/unit/pipelines/stdio/test_hermes_stdio_low_buf.yaml @@ -0,0 +1,10 @@ +name: hermes_unit_hermes_stdio_basic_small +env: hermes +pkgs: + - pkg_type: hermes_run + pkg_name: hermes_run + sleep: 2 + - pkg_type: hermes_stdio_tests + pkg_name: hermes_stdio_tests + test_file: stdio_low_buf + hermes: true \ No newline at end of file diff --git a/test/unit/pipelines/stdio/test_hermes_stdio_mapper.yaml b/test/unit/pipelines/stdio/test_hermes_stdio_mapper.yaml new file mode 100644 index 000000000..27259caa9 --- /dev/null +++ b/test/unit/pipelines/stdio/test_hermes_stdio_mapper.yaml @@ -0,0 +1,10 @@ +name: hermes_unit_hermes_stdio_basic_small +env: hermes +pkgs: + - pkg_type: hermes_run + pkg_name: hermes_run + sleep: 2 + - pkg_type: hermes_stdio_tests + pkg_name: hermes_stdio_tests + test_file: stdio_mapper + hermes: true \ No newline at end of file diff --git a/test/unit/pipelines/stdio/test_stdio_basic.yaml b/test/unit/pipelines/stdio/test_stdio_basic.yaml index cda53786e..b4ad4fbc9 100644 --- a/test/unit/pipelines/stdio/test_stdio_basic.yaml +++ b/test/unit/pipelines/stdio/test_stdio_basic.yaml @@ -1,8 +1,6 @@ name: hermes_unit_stdio_basic env: hermes pkgs: - - pkg_type: asan - pkg_name: asan - pkg_type: hermes_stdio_tests pkg_name: hermes_stdio_tests test_file: stdio_basic diff --git a/test/unit/pipelines/stdio/test_stdio_basic_mpi.yaml b/test/unit/pipelines/stdio/test_stdio_basic_mpi.yaml new file mode 100644 index 000000000..751697a15 --- /dev/null +++ b/test/unit/pipelines/stdio/test_stdio_basic_mpi.yaml @@ -0,0 +1,7 @@ +name: hermes_unit_stdio_basic_mpi +env: hermes +pkgs: + - pkg_type: hermes_stdio_tests + pkg_name: hermes_stdio_tests + test_file: stdio_basic_mpi + hermes: false \ No newline at end of file diff --git a/test/unit/pipelines/vfd/test_hermes_vfd_basic.yaml b/test/unit/pipelines/vfd/test_hermes_vfd_basic.yaml new file mode 100644 index 000000000..5ddd84d05 --- /dev/null +++ b/test/unit/pipelines/vfd/test_hermes_vfd_basic.yaml @@ -0,0 +1,14 @@ +name: hermes_unit_hermes_vfd_basic +env: hermes +pkgs: + - pkg_type: hermes_run + pkg_name: hermes_run + sleep: 5 + - pkg_type: hermes_api + pkg_name: hermes_api + vfd: true + - pkg_type: hermes_vfd_tests + pkg_name: hermes_vfd_tests + test_file: vfd_basic + hermes: true + mode: default diff --git a/test/unit/pipelines/vfd/test_hermes_vfd_scratch.yaml b/test/unit/pipelines/vfd/test_hermes_vfd_scratch.yaml new file mode 100644 index 000000000..69cdcccc8 --- /dev/null +++ b/test/unit/pipelines/vfd/test_hermes_vfd_scratch.yaml @@ -0,0 +1,11 @@ +name: hermes_unit_hermes_vfd_basic +env: hermes +pkgs: + - pkg_type: hermes_run + pkg_name: hermes_run + sleep: 5 + - pkg_type: hermes_vfd_tests + pkg_name: hermes_vfd_tests + test_file: vfd_basic + hermes: true + mode: scratch