diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index dfb0cf71ed2fd0964bcc2954821d7d54499c650e..7a6fd895fdb87adf0b4bfc61a57c8216988938d8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -145,18 +145,6 @@ test truncate: paths: - "${LOG_PATH}" -test path resolution: - stage: test - script: - - mkdir -p "${LOG_PATH}" - - ${INSTALL_PATH}/bin/gkfs_daemon --mount /tmp/mountdir --root /tmp/root & - - sleep 4 - - LD_PRELOAD=${INSTALL_PATH}/lib/libgkfs_intercept.so ${TESTS_BUILD_PATH}/gkfs_test_path_resolution - artifacts: - when: on_failure - paths: - - "${LOG_PATH}" - test lseek: stage: test script: diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0d41a4d79cd4ed8e2b728b9a134713fe9772a978..6238bfcdee1bcc1701d21f42db19a092e53f0233 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -26,8 +26,6 @@ add_executable(gkfs_test_truncate truncate.cpp) add_executable(gkfs_test_lseek lseek.cpp) add_executable(gkfs_test_symlink symlink_test.cpp) -add_executable(gkfs_test_path_resolution path_resolution.cpp) - find_package(MPI) if(${MPI_FOUND}) set(SOURCE_FILES_MPI main_MPI.cpp) diff --git a/test/path_resolution.cpp b/test/path_resolution.cpp deleted file mode 100644 index 930f600cd98fc6067584aa17e6d5cdd7476844bf..0000000000000000000000000000000000000000 --- a/test/path_resolution.cpp +++ /dev/null @@ -1,161 +0,0 @@ - -#include -#include -#include -#include -#include -#include -#include - - -static const std::string extdir = "/tmp/ext.tmp"; -static const std::string ext_linkdir = "/tmp/link.tmp"; -static const std::string nodir = "/tmp/notexistent"; -static const std::string mountdir = "/tmp/mountdir"; -static const std::string intdir = mountdir + "/int"; - - -void setup() { - int ret; - - // Clean external dir - ret = rmdir(extdir.c_str()); - if (ret != 0) { - if (errno != ENOENT) { - std::cerr << "ERROR: cannot remove external dir: " << - strerror(errno) << std::endl; - std::exit(EXIT_FAILURE); - } - } - ret = mkdir(extdir.c_str(), 0770); - if (ret != 0) { - std::cerr << "ERROR: cannot create external dir: " - << strerror(errno) << std::endl; - std::exit(EXIT_FAILURE); - } - - // Clean internal dir - ret = rmdir(intdir.c_str()); - if (ret != 0) { - if (errno != ENOENT) { - std::cerr << "ERROR: cannot remove internal dir: " << - strerror(errno) << std::endl; - std::exit(EXIT_FAILURE); - } - } - ret = mkdir(intdir.c_str(), 0770); - if (ret != 0) { - std::cerr << "ERROR: cannot create internal dir: " - << strerror(errno) << std::endl; - std::exit(EXIT_FAILURE); - } -} - - -void teardown() { - // Clean external link - if (unlink(ext_linkdir.c_str())) { - if (errno != ENOENT) { - std::cerr << "ERROR: cannot remove external dir: " << - strerror(errno) << std::endl; - } - } - - // Clean external dir - if (rmdir(extdir.c_str())) { - if (errno != ENOENT) { - std::cerr << "ERROR: cannot remove external dir: " << - strerror(errno) << std::endl; - } - } - - // Clean internal dir - if (rmdir(intdir.c_str())) { - if (errno != ENOENT) { - std::cerr << "ERROR: cannot remove internal dir: " << - strerror(errno) << std::endl; - } - } - -} - -void test_chdir(const std::string& dst, const std::string& expected) { - char path[125]; - int ret = chdir(dst.c_str()); - if (ret != 0) { - throw std::system_error(errno, std::system_category(), - "ERROR: Failed to chdir into: " + dst); - } - - char * cwd = getcwd(path, sizeof(path)); - if (cwd == NULL) { - throw std::system_error(errno, std::system_category(), - "ERROR: Failed to get current cwd"); - } - - if (std::string(path) != expected) { - throw std::system_error(errno, std::system_category(), - "ERROR: Expected path do not match"); - } -} - - -int main(int argc, char* argv[]) { - - if(std::atexit(teardown)) { - std::cerr << "Teardown function registration failed" << std::endl; - return EXIT_FAILURE; - } - - setup(); - - char buffIn[] = "oops."; - char *buffOut = new char[strlen(buffIn) + 1 + 20 ]; - char path[125]; - - struct stat st; - int fd; - int ret; - - // change to unexistent dir - assert(stat(nodir.c_str(), &st) != 0); - ret = chdir(nodir.c_str()); - if (ret == 0) { - std::cerr << "ERROR: Succeeded on chdir to a non-existing dir" << std::endl; - return EXIT_FAILURE; - } - if (errno != ENOENT) { - std::cerr << "ERROR: wrong error number while opening non-existing file: " << - errno << std::endl; - return EXIT_FAILURE; - } - - // change to external dir - ret = chdir(extdir.c_str()); - if (ret != 0) { - std::cerr << "ERROR: Failed to chdir into external dir: " << - strerror(errno) << std::endl; - return EXIT_FAILURE; - } - - // test path resolution: from outside to inside - test_chdir("../mountdir/int", intdir); - - // test path resolution: from inside to outside - test_chdir("../../ext.tmp", extdir); - - // test complex path resolution - test_chdir(mountdir + "/int/..//./int//../../../tmp/mountdir/../mountdir/./int/.//", intdir); - - // Create external link - ret = symlink(extdir.c_str(), ext_linkdir.c_str()); - if (ret != 0) { - std::cerr << "ERROR: Failed to make symbolic link: " << - strerror(errno) << std::endl; - return EXIT_FAILURE; - } - - test_chdir("../../link.tmp", extdir); - - test_chdir("../link.tmp/../link.tmp/../mountdir/int", intdir); -} diff --git a/tests/integration/CMakeLists.txt b/tests/integration/CMakeLists.txt index 1321a2a2f885d33014cfb568f83ba64fdc67f196..4d7f3ed7c9e1c91db9bbaa64ca6e95e312d654e3 100644 --- a/tests/integration/CMakeLists.txt +++ b/tests/integration/CMakeLists.txt @@ -14,7 +14,7 @@ gkfs_add_python_test( NAME test_directories PYTHON_VERSION 3.6 WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/tests/integration - SOURCE directories/test_directories.py + SOURCE directories/ ) if (GLIBC_HAS_STATX) @@ -75,13 +75,25 @@ if(GKFS_INSTALL_TESTS) PATTERN "gkfs.io" EXCLUDE ) - install(DIRECTORY directories + if(SYMLINK_SUPPORT) + install(DIRECTORY directories + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/gkfs/tests/integration + FILES_MATCHING + REGEX ".*\\.py" + PATTERN "__pycache__" EXCLUDE + PATTERN ".pytest_cache" EXCLUDE + ) + else() + install(DIRECTORY directories DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/gkfs/tests/integration FILES_MATCHING - REGEX ".*\\.py" - PATTERN "__pycache__" EXCLUDE - PATTERN ".pytest_cache" EXCLUDE + REGEX ".*\\.py" + PATTERN "__pycache__" EXCLUDE + PATTERN ".pytest_cache" EXCLUDE + PATTERN "test_symlink.py" EXCLUDE + ) + endif() install(DIRECTORY status DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/gkfs/tests/integration diff --git a/tests/integration/directories/test_pathresolution.py b/tests/integration/directories/test_pathresolution.py new file mode 100644 index 0000000000000000000000000000000000000000..0413e369dedbb9114a5ba03cea5778f70a5f533c --- /dev/null +++ b/tests/integration/directories/test_pathresolution.py @@ -0,0 +1,97 @@ +################################################################################ +# Copyright 2018-2020, Barcelona Supercomputing Center (BSC), Spain # +# Copyright 2015-2020, Johannes Gutenberg Universitaet Mainz, Germany # +# # +# This software was partially supported by the # +# EC H2020 funded project NEXTGenIO (Project ID: 671951, www.nextgenio.eu). # +# # +# This software was partially supported by the # +# ADA-FS project under the SPPEXA project funded by the DFG. # +# # +# SPDX-License-Identifier: MIT # +################################################################################ + +import harness +from pathlib import Path +import errno +import stat +import os +import ctypes +import sh +import sys +import pytest +from harness.logger import logger + +nonexisting = "nonexisting" + +#@pytest.mark.xfail(reason="invalid errno returned on success") +def test_pathresolution(gkfs_daemon, gkfs_client): + """Testing different path resolution capabilities""" + + mountdir = gkfs_daemon.mountdir + extdir = "/tmp/ext.tmp" + ext_linkdir = "/tmp/link.tmp" + nodir = "/tmp/notexistent" + intdir = mountdir / "int" + + # Just clean if it exists, due to a failed test + + ret = gkfs_client.rmdir(extdir) + try: + os.unlink(ext_linkdir) # it is external + except Exception as e: + pass + + ret = gkfs_client.mkdir( + extdir, + stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO) + + assert ret.retval == 0 + + ret = gkfs_client.mkdir( + intdir, + stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO) + + assert ret.retval == 0 + + + # test stat on existing dir + ret = gkfs_client.stat(nodir) + + assert ret.retval == -1 + assert ret.errno == errno.ENOENT + + ret = gkfs_client.chdir(nodir) + assert ret.retval == -1 + assert ret.errno == errno.ENOENT + + + # Chdir to external dir + + ret = gkfs_client.chdir(extdir) + assert ret.retval == 0 + + ret = gkfs_client.getcwd_validate(str(intdir)+"../../../../../../../../../../../../../../../../../../.."+str(intdir)) + assert ret.path == str(intdir) + assert ret.retval == 0 + + # test path resolution: from inside to outside + ret = gkfs_client.getcwd_validate("../../../../../../../../../../../.." + str(extdir)) + assert ret.path == str(extdir) + assert ret.retval == 0 + + # test complex path resolution + ret = gkfs_client.getcwd_validate("../../../../../../../../../../../.." + str(extdir) + "/../../../../../../../../../../../.." + str(intdir)) + assert ret.path == str(intdir) + assert ret.retval == 0 + + # Teardown + + ret = gkfs_client.rmdir(extdir) + assert ret.retval == 0 + + # Clean internal dir + ret = gkfs_client.rmdir(intdir) + assert ret.retval == 0 + + return diff --git a/tests/integration/directories/test_symlink.py b/tests/integration/directories/test_symlink.py new file mode 100644 index 0000000000000000000000000000000000000000..b88b4b683660e31fe77921a710ac0a1ad7e0a622 --- /dev/null +++ b/tests/integration/directories/test_symlink.py @@ -0,0 +1,82 @@ +################################################################################ +# Copyright 2018-2020, Barcelona Supercomputing Center (BSC), Spain # +# Copyright 2015-2020, Johannes Gutenberg Universitaet Mainz, Germany # +# # +# This software was partially supported by the # +# EC H2020 funded project NEXTGenIO (Project ID: 671951, www.nextgenio.eu). # +# # +# This software was partially supported by the # +# ADA-FS project under the SPPEXA project funded by the DFG. # +# # +# SPDX-License-Identifier: MIT # +################################################################################ + +import harness +from pathlib import Path +import errno +import stat +import os +import ctypes +import sh +import sys +import pytest +from harness.logger import logger + +nonexisting = "nonexisting" + +#@pytest.mark.xfail(reason="invalid errno returned on success") +def test_symlink(gkfs_daemon, gkfs_client): + """Testing different path resolution capabilities: symlinks""" + + mountdir = gkfs_daemon.mountdir + extdir = "/tmp/ext.tmp" + ext_linkdir = "/tmp/link.tmp" + nodir = "/tmp/notexistent" + intdir = mountdir / "int" + + # Just clean if it exists, due to a failed test + + ret = gkfs_client.rmdir(extdir) + try: + os.unlink(ext_linkdir) # it is external + except Exception as e: + pass + + ret = gkfs_client.mkdir( + extdir, + stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO) + + assert ret.retval == 0 + + ret = gkfs_client.mkdir( + intdir, + stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO) + + assert ret.retval == 0 + + #Test external symlink + + ret = gkfs_client.symlink(extdir, ext_linkdir) + assert ret.retval == 0 + + ret = gkfs_client.getcwd_validate(str(extdir) + "/../link.tmp") + assert ret.path == str(extdir) + assert ret.retval == 0 + + ret = gkfs_client.getcwd_validate(str(intdir) + "/../../../../../../../../../../../../../../../../../../../.."+str(extdir) + "/../link.tmp/../link.tmp/../../../../../../../../../../../../../../../../../../../../.." + str(intdir)) + assert ret.path == str(intdir) + assert ret.retval == 0 + + # Teardown + + # Clean external link + os.unlink(ext_linkdir) + + ret = gkfs_client.rmdir(extdir) + assert ret.retval == 0 + + # Clean internal dir + ret = gkfs_client.rmdir(intdir) + assert ret.retval == 0 + + return diff --git a/tests/integration/harness/CMakeLists.txt b/tests/integration/harness/CMakeLists.txt index dd0c4201d3232cdd61d1a3dc6544953cec07073c..3a9d47f056e16246af8a97728f8d305dc19eb9eb 100644 --- a/tests/integration/harness/CMakeLists.txt +++ b/tests/integration/harness/CMakeLists.txt @@ -30,6 +30,9 @@ add_executable(gkfs.io gkfs.io/write_random.cpp gkfs.io/truncate.cpp gkfs.io/util/file_compare.cpp + gkfs.io/chdir.cpp + gkfs.io/getcwd_validate.cpp + gkfs.io/symlink.cpp ) include(FetchContent) diff --git a/tests/integration/harness/gkfs.io/binary_buffer.hpp b/tests/integration/harness/gkfs.io/binary_buffer.hpp index 3806aaa9e0d56925b3870a6f8450459cff964eb8..e5c7182e0ad90873eac3e9aaeb5161399703ef39 100644 --- a/tests/integration/harness/gkfs.io/binary_buffer.hpp +++ b/tests/integration/harness/gkfs.io/binary_buffer.hpp @@ -22,10 +22,9 @@ namespace io { struct buffer { - buffer(::size_t size = 0) : - m_data(size) { } + buffer(::size_t size = 0) : m_data(size) {} - buffer(nullptr_t p) { } + buffer(nullptr_t p) {} buffer(const std::string& s) { m_data.clear(); @@ -63,15 +62,13 @@ struct buffer { }; inline void -to_json(nlohmann::json& record, - const buffer& out) { +to_json(nlohmann::json& record, const buffer& out) { if(out == nullptr) { record = nullptr; - } - else { + } else { -// record = fmt::format("x{:2x}", fmt::join(out, "x")); + // record = fmt::format("x{:2x}", fmt::join(out, "x")); record = out.storage(); } } diff --git a/tests/integration/harness/gkfs.io/chdir.cpp b/tests/integration/harness/gkfs.io/chdir.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2940c5bf78710c2ba6e72ee6424ce2175d5b156e --- /dev/null +++ b/tests/integration/harness/gkfs.io/chdir.cpp @@ -0,0 +1,80 @@ +/* + Copyright 2018-2020, Barcelona Supercomputing Center (BSC), Spain + Copyright 2015-2020, Johannes Gutenberg Universitaet Mainz, Germany + + This software was partially supported by the + EC H2020 funded project NEXTGenIO (Project ID: 671951, www.nextgenio.eu). + + This software was partially supported by the + ADA-FS project under the SPPEXA project funded by the DFG. + + SPDX-License-Identifier: MIT +*/ + +/* C++ includes */ +#include +#include +#include +#include +#include +#include +#include + +/* C includes */ +#include + +using json = nlohmann::json; + +struct chdir_options { + bool verbose{}; + std::string pathname; + + REFL_DECL_STRUCT(chdir_options, REFL_DECL_MEMBER(bool, verbose), + REFL_DECL_MEMBER(std::string, pathname)); +}; + +struct chdir_output { + int retval; + int errnum; + + REFL_DECL_STRUCT(chdir_output, REFL_DECL_MEMBER(int, retval), + REFL_DECL_MEMBER(int, errnum)); +}; + +void +to_json(json& record, const chdir_output& out) { + record = serialize(out); +} + +void +chdir_exec(const chdir_options& opts) { + + auto rv = ::chdir(opts.pathname.c_str()); + + if(opts.verbose) { + fmt::print("chdir(pathname=\"{}\") = {}, errno: {} [{}]\n", + opts.pathname, rv, errno, ::strerror(errno)); + return; + } + + json out = chdir_output{rv, errno}; + fmt::print("{}\n", out.dump(2)); +} + +void +chdir_init(CLI::App& app) { + + // Create the option and subcommand objects + auto opts = std::make_shared(); + auto* cmd = app.add_subcommand("chdir", "Execute the chdir() system call"); + + // Add options to cmd, binding them to opts + cmd->add_flag("-v,--verbose", opts->verbose, + "Produce human readable output"); + + cmd->add_option("pathname", opts->pathname, "Directory name") + ->required() + ->type_name(""); + + cmd->callback([opts]() { chdir_exec(*opts); }); +} diff --git a/tests/integration/harness/gkfs.io/commands.hpp b/tests/integration/harness/gkfs.io/commands.hpp index 91bac7a3ae4080e1c673d743fc840c5348fd7b7e..4f2d79b320f9bfe3618fb5082c72696d0ce0e2fb 100644 --- a/tests/integration/harness/gkfs.io/commands.hpp +++ b/tests/integration/harness/gkfs.io/commands.hpp @@ -15,7 +15,9 @@ #define IO_COMMANDS_HPP // forward declare CLI::App -namespace CLI { struct App; } +namespace CLI { +struct App; +} void mkdir_init(CLI::App& app); @@ -79,5 +81,13 @@ truncate_init(CLI::App& app); // UTIL void file_compare_init(CLI::App& app); +void +chdir_init(CLI::App& app); + +void +getcwd_validate_init(CLI::App& app); + +void +symlink_init(CLI::App& app); #endif // IO_COMMANDS_HPP diff --git a/tests/integration/harness/gkfs.io/getcwd_validate.cpp b/tests/integration/harness/gkfs.io/getcwd_validate.cpp new file mode 100644 index 0000000000000000000000000000000000000000..de8b3edf3d273cb5cc62ee2ba3c4f07abdfe0359 --- /dev/null +++ b/tests/integration/harness/gkfs.io/getcwd_validate.cpp @@ -0,0 +1,95 @@ +/* + Copyright 2018-2020, Barcelona Supercomputing Center (BSC), Spain + Copyright 2015-2020, Johannes Gutenberg Universitaet Mainz, Germany + + This software was partially supported by the + EC H2020 funded project NEXTGenIO (Project ID: 671951, www.nextgenio.eu). + + This software was partially supported by the + ADA-FS project under the SPPEXA project funded by the DFG. + + SPDX-License-Identifier: MIT +*/ + +/* C++ includes */ +#include +#include +#include +#include +#include +#include +#include + +/* C includes */ +#include + +using json = nlohmann::json; + +struct getcwd_validate_options { + bool verbose{}; + std::string pathname; + + REFL_DECL_STRUCT(getcwd_validate_options, REFL_DECL_MEMBER(bool, verbose), + REFL_DECL_MEMBER(std::string, pathname)); +}; + +struct getcwd_validate_output { + int retval; + std::string path; + int errnum; + + REFL_DECL_STRUCT(getcwd_validate_output, REFL_DECL_MEMBER(int, retval), + REFL_DECL_MEMBER(std::string, path), + REFL_DECL_MEMBER(int, errnum)); +}; + +void +to_json(json& record, const getcwd_validate_output& out) { + record = serialize(out); +} + +void +getcwd_validate_exec(const getcwd_validate_options& opts) { + + + char path[1024]; + auto rv = ::chdir(opts.pathname.c_str()); + if(rv == 0) { + + char* cwd = ::getcwd(path, sizeof(path)); + + if(cwd == nullptr) { + rv = -1; + } + + if(path == opts.pathname) + if(opts.verbose) { + fmt::print( + "getcwd_validate(pathname=\"{}\") = {}, errno: {} [{}]\n", + opts.pathname, cwd, errno, ::strerror(errno)); + return; + } + } + + json out = getcwd_validate_output{rv, path, errno}; + fmt::print("{}\n", out.dump(2)); +} + +void +getcwd_validate_init(CLI::App& app) { + + // Create the option and subcommand objects + auto opts = std::make_shared(); + auto* cmd = app.add_subcommand("getcwd_validate", + "Execute the getcwd_validate() system call"); + + // Add options to cmd, binding them to opts + cmd->add_flag("-v,--verbose", opts->verbose, + "Produce human readable output"); + + cmd->add_option("pathname", opts->pathname, "Directory name") + ->required() + ->type_name(""); + + cmd->callback([opts]() { getcwd_validate_exec(*opts); }); +} diff --git a/tests/integration/harness/gkfs.io/lseek.cpp b/tests/integration/harness/gkfs.io/lseek.cpp index f779c44c98fa2962b1ed39d29ff909662ae96c44..828c13d538a755926921bbc7b976a925357e1f0a 100644 --- a/tests/integration/harness/gkfs.io/lseek.cpp +++ b/tests/integration/harness/gkfs.io/lseek.cpp @@ -30,55 +30,54 @@ using json = nlohmann::json; struct lseek_options { - bool verbose; + bool verbose{}; std::string pathname; ::off_t offset; int whence; - REFL_DECL_STRUCT(lseek_options, - REFL_DECL_MEMBER(bool, verbose), - REFL_DECL_MEMBER(std::string, pathname), - REFL_DECL_MEMBER(::off_t, offset), - REFL_DECL_MEMBER(int, whence) - ); + REFL_DECL_STRUCT(lseek_options, REFL_DECL_MEMBER(bool, verbose), + REFL_DECL_MEMBER(std::string, pathname), + REFL_DECL_MEMBER(::off_t, offset), + REFL_DECL_MEMBER(int, whence)); }; struct lseek_output { ::off_t retval; int errnum; - REFL_DECL_STRUCT(lseek_output, - REFL_DECL_MEMBER(::off_t, retval), - REFL_DECL_MEMBER(int, errnum) - ); + REFL_DECL_STRUCT(lseek_output, REFL_DECL_MEMBER(::off_t, retval), + REFL_DECL_MEMBER(int, errnum)); }; void -to_json(json& record, - const lseek_output& out) { +to_json(json& record, const lseek_output& out) { record = serialize(out); } -std::string +std::string whence2str(int whence) { - switch (whence) { - case SEEK_SET : return "SEEK_SET"; - case SEEK_CUR : return "SEEK_CUR"; - case SEEK_END : return "SEEK_END"; - default : return "UNKNOWN"; - } + switch(whence) { + case SEEK_SET: + return "SEEK_SET"; + case SEEK_CUR: + return "SEEK_CUR"; + case SEEK_END: + return "SEEK_END"; + default: + return "UNKNOWN"; + } return "UNKNOWN"; } -void +void lseek_exec(const lseek_options& opts) { int fd = ::open(opts.pathname.c_str(), O_RDONLY); if(fd == -1) { if(opts.verbose) { - fmt::print("open(pathname=\"{}\") = {}, errno: {} [{}]\n", - opts.pathname, fd, errno, ::strerror(errno)); + fmt::print("open(pathname=\"{}\") = {}, errno: {} [{}]\n", + opts.pathname, fd, errno, ::strerror(errno)); return; } @@ -91,8 +90,10 @@ lseek_exec(const lseek_options& opts) { int rv = ::lseek(fd, opts.offset, opts.whence); if(opts.verbose) { - fmt::print("lseek(pathname=\"{}\", offset='{}', whence='{}') = {}, errno: {} [{}]\n", - opts.pathname, opts.offset, whence2str(opts.whence), rv, errno, ::strerror(errno)); + fmt::print( + "lseek(pathname=\"{}\", offset='{}', whence='{}') = {}, errno: {} [{}]\n", + opts.pathname, opts.offset, whence2str(opts.whence), rv, errno, + ::strerror(errno)); return; } @@ -105,44 +106,23 @@ lseek_init(CLI::App& app) { // Create the option and subcommand objects auto opts = std::make_shared(); - auto* cmd = app.add_subcommand( - "lseek", - "Execute the lseek() system call"); + auto* cmd = app.add_subcommand("lseek", "Execute the lseek() system call"); // Add options to cmd, binding them to opts - cmd->add_flag( - "-v,--verbose", - opts->verbose, - "Produce human writeable output" - ); - - cmd->add_option( - "pathname", - opts->pathname, - "Directory name" - ) - ->required() - ->type_name(""); - - cmd->add_option( - "offset", - opts->offset, - "offset used" - ) - ->required() - ->type_name(""); - - cmd->add_option( - "whence", - opts->whence, - "Whence the action is done" - ) - ->required() - ->type_name(""); - - cmd->callback([opts]() { - lseek_exec(*opts); - }); -} + cmd->add_flag("-v,--verbose", opts->verbose, + "Produce human writeable output"); + cmd->add_option("pathname", opts->pathname, "Directory name") + ->required() + ->type_name(""); + cmd->add_option("offset", opts->offset, "offset used") + ->required() + ->type_name(""); + + cmd->add_option("whence", opts->whence, "Whence the action is done") + ->required() + ->type_name(""); + + cmd->callback([opts]() { lseek_exec(*opts); }); +} diff --git a/tests/integration/harness/gkfs.io/main.cpp b/tests/integration/harness/gkfs.io/main.cpp index b82233d3cbcfc34544e9a0f753624f438332dfa4..c0353ff092286d5361f2923b76823c7aff986115 100644 --- a/tests/integration/harness/gkfs.io/main.cpp +++ b/tests/integration/harness/gkfs.io/main.cpp @@ -34,19 +34,21 @@ init_commands(CLI::App& app) { pwrite_init(app); writev_init(app); pwritev_init(app); - #ifdef STATX_TYPE +#ifdef STATX_TYPE statx_init(app); - #endif +#endif lseek_init(app); write_validate_init(app); write_random_init(app); truncate_init(app); // utils file_compare_init(app); + chdir_init(app); + getcwd_validate_init(app); + symlink_init(app); } - int main(int argc, char* argv[]) { diff --git a/tests/integration/harness/gkfs.io/mkdir.cpp b/tests/integration/harness/gkfs.io/mkdir.cpp index f542c03a094030838a775248cbfec6e977a23799..f2265617696ad164507a26f9b52c68ad219e1324 100644 --- a/tests/integration/harness/gkfs.io/mkdir.cpp +++ b/tests/integration/harness/gkfs.io/mkdir.cpp @@ -27,41 +27,37 @@ using json = nlohmann::json; struct mkdir_options { - bool verbose; + bool verbose{}; std::string pathname; ::mode_t mode; - REFL_DECL_STRUCT(mkdir_options, - REFL_DECL_MEMBER(bool, verbose), - REFL_DECL_MEMBER(std::string, pathname), - REFL_DECL_MEMBER(::mode_t, mode) - ); + REFL_DECL_STRUCT(mkdir_options, REFL_DECL_MEMBER(bool, verbose), + REFL_DECL_MEMBER(std::string, pathname), + REFL_DECL_MEMBER(::mode_t, mode)); }; struct mkdir_output { int retval; int errnum; - REFL_DECL_STRUCT(mkdir_output, - REFL_DECL_MEMBER(int, retval), - REFL_DECL_MEMBER(int, errnum) - ); + REFL_DECL_STRUCT(mkdir_output, REFL_DECL_MEMBER(int, retval), + REFL_DECL_MEMBER(int, errnum)); }; void -to_json(json& record, - const mkdir_output& out) { +to_json(json& record, const mkdir_output& out) { record = serialize(out); } -void +void mkdir_exec(const mkdir_options& opts) { - int rv = ::mkdir(opts.pathname.c_str(), opts.mode); + auto rv = ::mkdir(opts.pathname.c_str(), opts.mode); if(opts.verbose) { - fmt::print("mkdir(pathname=\"{}\", mode={:#04o}) = {}, errno: {} [{}]\n", - opts.pathname, opts.mode, rv, errno, ::strerror(errno)); + fmt::print( + "mkdir(pathname=\"{}\", mode={:#04o}) = {}, errno: {} [{}]\n", + opts.pathname, opts.mode, rv, errno, ::strerror(errno)); return; } @@ -74,34 +70,20 @@ mkdir_init(CLI::App& app) { // Create the option and subcommand objects auto opts = std::make_shared(); - auto* cmd = app.add_subcommand( - "mkdir", - "Execute the mkdir() system call"); + auto* cmd = app.add_subcommand("mkdir", "Execute the mkdir() system call"); // Add options to cmd, binding them to opts - cmd->add_flag( - "-v,--verbose", - opts->verbose, - "Produce human readable output" - ); - - cmd->add_option( - "pathname", - opts->pathname, - "Directory name" - ) - ->required() - ->type_name(""); - - cmd->add_option( - "mode", - opts->mode, - "Octal mode specified for the new directory (e.g. 0664)" - ) - ->required() - ->type_name(""); - - cmd->callback([opts]() { - mkdir_exec(*opts); - }); + cmd->add_flag("-v,--verbose", opts->verbose, + "Produce human readable output"); + + cmd->add_option("pathname", opts->pathname, "Directory name") + ->required() + ->type_name(""); + + cmd->add_option("mode", opts->mode, + "Octal mode specified for the new directory (e.g. 0664)") + ->required() + ->type_name(""); + + cmd->callback([opts]() { mkdir_exec(*opts); }); } diff --git a/tests/integration/harness/gkfs.io/open.cpp b/tests/integration/harness/gkfs.io/open.cpp index e2d40306d35b01bd3af3bf480045d8e1fdffc549..6ba1dc99a58191be3b9e27b7b8e28eee10f7ffe0 100644 --- a/tests/integration/harness/gkfs.io/open.cpp +++ b/tests/integration/harness/gkfs.io/open.cpp @@ -30,43 +30,40 @@ using json = nlohmann::json; struct open_options { - bool verbose; + bool verbose{}; std::string pathname; int flags; ::mode_t mode; - REFL_DECL_STRUCT(open_options, - REFL_DECL_MEMBER(bool, verbose), - REFL_DECL_MEMBER(std::string, pathname), - REFL_DECL_MEMBER(int, flags), - REFL_DECL_MEMBER(::mode_t, mode) - ); + REFL_DECL_STRUCT(open_options, REFL_DECL_MEMBER(bool, verbose), + REFL_DECL_MEMBER(std::string, pathname), + REFL_DECL_MEMBER(int, flags), + REFL_DECL_MEMBER(::mode_t, mode)); }; struct open_output { int retval; int errnum; - REFL_DECL_STRUCT(open_output, - REFL_DECL_MEMBER(int, retval), - REFL_DECL_MEMBER(int, errnum) - ); + REFL_DECL_STRUCT(open_output, REFL_DECL_MEMBER(int, retval), + REFL_DECL_MEMBER(int, errnum)); }; void -to_json(json& record, - const open_output& out) { +to_json(json& record, const open_output& out) { record = serialize(out); } -void +void open_exec(const open_options& opts) { - int fd = ::open(opts.pathname.c_str(), opts.flags, opts.mode); + auto fd = ::open(opts.pathname.c_str(), opts.flags, opts.mode); if(opts.verbose) { - fmt::print("open(pathname=\"{}\", flags={}, mode={:#04o}) = {}, errno: {} [{}]\n", - opts.pathname, opts.flags, opts.mode, fd, errno, ::strerror(errno)); + fmt::print( + "open(pathname=\"{}\", flags={}, mode={:#04o}) = {}, errno: {} [{}]\n", + opts.pathname, opts.flags, opts.mode, fd, errno, + ::strerror(errno)); return; } @@ -81,48 +78,28 @@ open_init(CLI::App& app) { // Create the option and subcommand objects auto opts = std::make_shared(); - auto* cmd = app.add_subcommand( - "open", - "Execute the open() system call"); + auto* cmd = app.add_subcommand("open", "Execute the open() system call"); // Add options to cmd, binding them to opts - cmd->add_flag( - "-v,--verbose", - opts->verbose, - "Produce human readable output" - ); - - cmd->add_option( - "pathname", - opts->pathname, - "Directory name" - ) - ->required() - ->type_name(""); - - cmd->add_option( - "flags", - opts->flags, - "Open flags" - ) - ->required() - ->type_name("") - ->check(CLI::NonNegativeNumber); - - cmd->add_option( - "mode", - opts->mode, - "Octal mode specified for the new directory (e.g. 0664)" - ) - //->required() - ->default_val(0) - ->type_name("") - ->check(CLI::NonNegativeNumber); - - - cmd->callback([opts]() { - open_exec(*opts); - }); -} + cmd->add_flag("-v,--verbose", opts->verbose, + "Produce human readable output"); + + cmd->add_option("pathname", opts->pathname, "Directory name") + ->required() + ->type_name(""); + cmd->add_option("flags", opts->flags, "Open flags") + ->required() + ->type_name("") + ->check(CLI::NonNegativeNumber); + cmd->add_option("mode", opts->mode, + "Octal mode specified for the new directory (e.g. 0664)") + //->required() + ->default_val(0) + ->type_name("") + ->check(CLI::NonNegativeNumber); + + + cmd->callback([opts]() { open_exec(*opts); }); +} diff --git a/tests/integration/harness/gkfs.io/opendir.cpp b/tests/integration/harness/gkfs.io/opendir.cpp index 069c0bf14b0d11b1d7cb8096925fb628cf284786..561b92f254f5491301148c7c7b0ed8e204088768 100644 --- a/tests/integration/harness/gkfs.io/opendir.cpp +++ b/tests/integration/harness/gkfs.io/opendir.cpp @@ -27,39 +27,34 @@ using json = nlohmann::json; struct opendir_options { - bool verbose; + bool verbose{}; std::string dirname; - REFL_DECL_STRUCT(opendir_options, - REFL_DECL_MEMBER(bool, verbose), - REFL_DECL_MEMBER(std::string, dirname) - ); + REFL_DECL_STRUCT(opendir_options, REFL_DECL_MEMBER(bool, verbose), + REFL_DECL_MEMBER(std::string, dirname)); }; struct opendir_output { ::DIR* dirp; int errnum; - REFL_DECL_STRUCT(opendir_output, - REFL_DECL_MEMBER(::DIR*, dirp), - REFL_DECL_MEMBER(int, errnum) - ); + REFL_DECL_STRUCT(opendir_output, REFL_DECL_MEMBER(::DIR*, dirp), + REFL_DECL_MEMBER(int, errnum)); }; void -to_json(json& record, - const opendir_output& out) { +to_json(json& record, const opendir_output& out) { record = serialize(out); } -void +void opendir_exec(const opendir_options& opts) { ::DIR* dirp = ::opendir(opts.dirname.c_str()); if(opts.verbose) { - fmt::print("opendir(name=\"{}\") = {}, errno: {} [{}]\n", - opts.dirname, fmt::ptr(dirp), errno, ::strerror(errno)); + fmt::print("opendir(name=\"{}\") = {}, errno: {} [{}]\n", opts.dirname, + fmt::ptr(dirp), errno, ::strerror(errno)); return; } @@ -71,27 +66,16 @@ void opendir_init(CLI::App& app) { // Create the option and subcommand objects auto opts = std::make_shared(); - auto* cmd = app.add_subcommand( - "opendir", - "Execute the opendir() glibc function"); + auto* cmd = app.add_subcommand("opendir", + "Execute the opendir() glibc function"); // Add options to cmd, binding them to opts - cmd->add_flag( - "-v,--verbose", - opts->verbose, - "Produce human readable output" - ); - - cmd->add_option( - "dirname", - opts->dirname, - "Directory name" - ) - ->required() - ->type_name(""); - - cmd->callback([opts]() { - opendir_exec(*opts); - }); -} + cmd->add_flag("-v,--verbose", opts->verbose, + "Produce human readable output"); + cmd->add_option("dirname", opts->dirname, "Directory name") + ->required() + ->type_name(""); + + cmd->callback([opts]() { opendir_exec(*opts); }); +} diff --git a/tests/integration/harness/gkfs.io/pread.cpp b/tests/integration/harness/gkfs.io/pread.cpp index 0fac6c6380d37797cbca2d513369b0c5fb0785df..974893801850c9afd7126e2243899e9e14c5f7d6 100644 --- a/tests/integration/harness/gkfs.io/pread.cpp +++ b/tests/integration/harness/gkfs.io/pread.cpp @@ -30,17 +30,15 @@ using json = nlohmann::json; struct pread_options { - bool verbose; + bool verbose{}; std::string pathname; ::size_t count; ::size_t offset; - REFL_DECL_STRUCT(pread_options, - REFL_DECL_MEMBER(bool, verbose), - REFL_DECL_MEMBER(std::string, pathname), - REFL_DECL_MEMBER(::size_t, count), - REFL_DECL_MEMBER(::size_t, offset) - ); + REFL_DECL_STRUCT(pread_options, REFL_DECL_MEMBER(bool, verbose), + REFL_DECL_MEMBER(std::string, pathname), + REFL_DECL_MEMBER(::size_t, count), + REFL_DECL_MEMBER(::size_t, offset)); }; struct pread_output { @@ -48,28 +46,27 @@ struct pread_output { io::buffer buf; int errnum; - REFL_DECL_STRUCT(pread_output, - REFL_DECL_MEMBER(::size_t, retval), - REFL_DECL_MEMBER(void*, buf), - REFL_DECL_MEMBER(int, errnum) - ); + REFL_DECL_STRUCT(pread_output, REFL_DECL_MEMBER(::size_t, retval), + REFL_DECL_MEMBER(void*, buf), + REFL_DECL_MEMBER(int, errnum)); }; void -to_json(json& record, - const pread_output& out) { +to_json(json& record, const pread_output& out) { record = serialize(out); } -void +void pread_exec(const pread_options& opts) { - int fd = ::open(opts.pathname.c_str(), O_RDONLY); + auto fd = ::open(opts.pathname.c_str(), O_RDONLY); if(fd == -1) { if(opts.verbose) { - fmt::print("pread(pathname=\"{}\", count={}, offset={}) = {}, errno: {} [{}]\n", - opts.pathname, opts.count, opts.offset, fd, errno, ::strerror(errno)); + fmt::print( + "pread(pathname=\"{}\", count={}, offset={}) = {}, errno: {} [{}]\n", + opts.pathname, opts.count, opts.offset, fd, errno, + ::strerror(errno)); return; } @@ -84,8 +81,10 @@ pread_exec(const pread_options& opts) { int rv = ::pread(fd, buf.data(), opts.count, opts.offset); if(opts.verbose) { - fmt::print("pread(pathname=\"{}\", count={}, offset={}) = {}, errno: {} [{}]\n", - opts.pathname, opts.count, opts.offset, rv, errno, ::strerror(errno)); + fmt::print( + "pread(pathname=\"{}\", count={}, offset={}) = {}, errno: {} [{}]\n", + opts.pathname, opts.count, opts.offset, rv, errno, + ::strerror(errno)); return; } @@ -98,43 +97,23 @@ pread_init(CLI::App& app) { // Create the option and subcommand objects auto opts = std::make_shared(); - auto* cmd = app.add_subcommand( - "pread", - "Execute the pread() system call"); + auto* cmd = app.add_subcommand("pread", "Execute the pread() system call"); // Add options to cmd, binding them to opts - cmd->add_flag( - "-v,--verbose", - opts->verbose, - "Produce human readable output" - ); - - cmd->add_option( - "pathname", - opts->pathname, - "Directory name" - ) - ->required() - ->type_name(""); - - cmd->add_option( - "count", - opts->count, - "Number of bytes to read" - ) - ->required() - ->type_name(""); - - cmd->add_option( - "offset", - opts->offset, - "Offset to read" - ) - ->required() - ->type_name(""); - - cmd->callback([opts]() { - pread_exec(*opts); - }); -} + cmd->add_flag("-v,--verbose", opts->verbose, + "Produce human readable output"); + + cmd->add_option("pathname", opts->pathname, "Directory name") + ->required() + ->type_name(""); + cmd->add_option("count", opts->count, "Number of bytes to read") + ->required() + ->type_name(""); + + cmd->add_option("offset", opts->offset, "Offset to read") + ->required() + ->type_name(""); + + cmd->callback([opts]() { pread_exec(*opts); }); +} diff --git a/tests/integration/harness/gkfs.io/preadv.cpp b/tests/integration/harness/gkfs.io/preadv.cpp index 480e7bf3cbc1dac8a24040bcd51ae2e507b2e9d1..88522fbbf9c76c3460236f9273b2a22fbab12825 100644 --- a/tests/integration/harness/gkfs.io/preadv.cpp +++ b/tests/integration/harness/gkfs.io/preadv.cpp @@ -31,19 +31,17 @@ using json = nlohmann::json; struct preadv_options { - bool verbose; + bool verbose{}; std::string pathname; ::size_t count_0; ::size_t count_1; ::size_t offset; - REFL_DECL_STRUCT(preadv_options, - REFL_DECL_MEMBER(bool, verbose), - REFL_DECL_MEMBER(std::string, pathname), - REFL_DECL_MEMBER(::size_t, count_0), - REFL_DECL_MEMBER(::size_t, count_1), - REFL_DECL_MEMBER(::size_t, offset) - ); + REFL_DECL_STRUCT(preadv_options, REFL_DECL_MEMBER(bool, verbose), + REFL_DECL_MEMBER(std::string, pathname), + REFL_DECL_MEMBER(::size_t, count_0), + REFL_DECL_MEMBER(::size_t, count_1), + REFL_DECL_MEMBER(::size_t, offset)); }; struct preadv_output { @@ -52,29 +50,28 @@ struct preadv_output { io::buffer buf_1; int errnum; - REFL_DECL_STRUCT(preadv_output, - REFL_DECL_MEMBER(::size_t, retval), - REFL_DECL_MEMBER(void*, buf_0), - REFL_DECL_MEMBER(void*, buf_1), - REFL_DECL_MEMBER(int, errnum) - ); + REFL_DECL_STRUCT(preadv_output, REFL_DECL_MEMBER(::size_t, retval), + REFL_DECL_MEMBER(void*, buf_0), + REFL_DECL_MEMBER(void*, buf_1), + REFL_DECL_MEMBER(int, errnum)); }; void -to_json(json& record, - const preadv_output& out) { +to_json(json& record, const preadv_output& out) { record = serialize(out); } -void +void preadv_exec(const preadv_options& opts) { - int fd = ::open(opts.pathname.c_str(), O_RDONLY); + auto fd = ::open(opts.pathname.c_str(), O_RDONLY); if(fd == -1) { if(opts.verbose) { - fmt::print("preadv(pathname=\"{}\", count_0={}, count_1={}, offset={}) = {}, errno: {} [{}]\n", - opts.pathname, opts.count_0, opts.count_1, opts.offset, fd, errno, ::strerror(errno)); + fmt::print( + "preadv(pathname=\"{}\", count_0={}, count_1={}, offset={}) = {}, errno: {} [{}]\n", + opts.pathname, opts.count_0, opts.count_1, opts.offset, fd, + errno, ::strerror(errno)); return; } @@ -98,12 +95,15 @@ preadv_exec(const preadv_options& opts) { int rv = ::preadv(fd, iov, 2, opts.offset); if(opts.verbose) { - fmt::print("preadv(pathname=\"{}\", count_0={}, count_1={}, offset={}) = {}, errno: {} [{}]\n", - opts.pathname, opts.count_0, opts.count_1, opts.offset, rv, errno, ::strerror(errno)); + fmt::print( + "preadv(pathname=\"{}\", count_0={}, count_1={}, offset={}) = {}, errno: {} [{}]\n", + opts.pathname, opts.count_0, opts.count_1, opts.offset, rv, + errno, ::strerror(errno)); return; } - json out = preadv_output{rv, (rv != -1 ? buf_0 : nullptr), (rv != -1 ? buf_1 : nullptr), errno}; + json out = preadv_output{rv, (rv != -1 ? buf_0 : nullptr), + (rv != -1 ? buf_1 : nullptr), errno}; fmt::print("{}\n", out.dump(2)); } @@ -112,51 +112,30 @@ preadv_init(CLI::App& app) { // Create the option and subcommand objects auto opts = std::make_shared(); - auto* cmd = app.add_subcommand( - "preadv", - "Execute the preadv() system call"); + auto* cmd = + app.add_subcommand("preadv", "Execute the preadv() system call"); // Add options to cmd, binding them to opts - cmd->add_flag( - "-v,--verbose", - opts->verbose, - "Produce human readable output" - ); - - cmd->add_option( - "pathname", - opts->pathname, - "Directory name" - ) - ->required() - ->type_name(""); - - cmd->add_option( - "count_0", - opts->count_0, - "Number of bytes to read to buffer 0" - ) - ->required() - ->type_name(""); - - cmd->add_option( - "count_1", - opts->count_1, - "Number of bytes to read to buffer 1" - ) - ->required() - ->type_name(""); - - cmd->add_option( - "offset", - opts->offset, - "Offset to read" - ) - ->required() - ->type_name(""); - - cmd->callback([opts]() { - preadv_exec(*opts); - }); -} + cmd->add_flag("-v,--verbose", opts->verbose, + "Produce human readable output"); + + cmd->add_option("pathname", opts->pathname, "Directory name") + ->required() + ->type_name(""); + + cmd->add_option("count_0", opts->count_0, + "Number of bytes to read to buffer 0") + ->required() + ->type_name(""); + cmd->add_option("count_1", opts->count_1, + "Number of bytes to read to buffer 1") + ->required() + ->type_name(""); + + cmd->add_option("offset", opts->offset, "Offset to read") + ->required() + ->type_name(""); + + cmd->callback([opts]() { preadv_exec(*opts); }); +} diff --git a/tests/integration/harness/gkfs.io/pwrite.cpp b/tests/integration/harness/gkfs.io/pwrite.cpp index e098624b00c8ec69123e6b0ea8b514115adfa53d..bc55f131e595c07250009575de6e50ad995a90cc 100644 --- a/tests/integration/harness/gkfs.io/pwrite.cpp +++ b/tests/integration/harness/gkfs.io/pwrite.cpp @@ -30,46 +30,43 @@ using json = nlohmann::json; struct pwrite_options { - bool verbose; + bool verbose{}; std::string pathname; std::string data; ::size_t count; ::size_t offset; - REFL_DECL_STRUCT(pwrite_options, - REFL_DECL_MEMBER(bool, verbose), - REFL_DECL_MEMBER(std::string, pathname), - REFL_DECL_MEMBER(std::string, data), - REFL_DECL_MEMBER(::size_t, count), - REFL_DECL_MEMBER(::size_t, offset) - ); + REFL_DECL_STRUCT(pwrite_options, REFL_DECL_MEMBER(bool, verbose), + REFL_DECL_MEMBER(std::string, pathname), + REFL_DECL_MEMBER(std::string, data), + REFL_DECL_MEMBER(::size_t, count), + REFL_DECL_MEMBER(::size_t, offset)); }; struct pwrite_output { ::ssize_t retval; int errnum; - REFL_DECL_STRUCT(pwrite_output, - REFL_DECL_MEMBER(::size_t, retval), - REFL_DECL_MEMBER(int, errnum) - ); + REFL_DECL_STRUCT(pwrite_output, REFL_DECL_MEMBER(::size_t, retval), + REFL_DECL_MEMBER(int, errnum)); }; void -to_json(json& record, - const pwrite_output& out) { +to_json(json& record, const pwrite_output& out) { record = serialize(out); } -void +void pwrite_exec(const pwrite_options& opts) { - int fd = ::open(opts.pathname.c_str(), O_WRONLY); + auto fd = ::open(opts.pathname.c_str(), O_WRONLY); if(fd == -1) { if(opts.verbose) { - fmt::print("pwrite(pathname=\"{}\", buf=\"{}\" count={}, offset={}) = {}, errno: {} [{}]\n", - opts.pathname, opts.data, opts.count, opts.offset, fd, errno, ::strerror(errno)); + fmt::print( + "pwrite(pathname=\"{}\", buf=\"{}\" count={}, offset={}) = {}, errno: {} [{}]\n", + opts.pathname, opts.data, opts.count, opts.offset, fd, + errno, ::strerror(errno)); return; } @@ -83,8 +80,10 @@ pwrite_exec(const pwrite_options& opts) { int rv = ::pwrite(fd, buf.data(), opts.count, opts.offset); if(opts.verbose) { - fmt::print("pwrite(pathname=\"{}\", count={}, offset={}) = {}, errno: {} [{}]\n", - opts.pathname, opts.count, opts.offset, rv, errno, ::strerror(errno)); + fmt::print( + "pwrite(pathname=\"{}\", count={}, offset={}) = {}, errno: {} [{}]\n", + opts.pathname, opts.count, opts.offset, rv, errno, + ::strerror(errno)); return; } @@ -97,52 +96,28 @@ pwrite_init(CLI::App& app) { // Create the option and subcommand objects auto opts = std::make_shared(); - auto* cmd = app.add_subcommand( - "pwrite", - "Execute the pwrite() system call"); + auto* cmd = + app.add_subcommand("pwrite", "Execute the pwrite() system call"); // Add options to cmd, binding them to opts - cmd->add_flag( - "-v,--verbose", - opts->verbose, - "Produce human writeable output" - ); - - cmd->add_option( - "pathname", - opts->pathname, - "Directory name" - ) - ->required() - ->type_name(""); - - cmd->add_option( - "data", - opts->data, - "Data to write" - ) - ->required() - ->type_name(""); - - cmd->add_option( - "count", - opts->count, - "Number of bytes to write" - ) - ->required() - ->type_name(""); - - cmd->add_option( - "offset", - opts->offset, - "Offset to read" - ) - ->required() - ->type_name(""); - - cmd->callback([opts]() { - pwrite_exec(*opts); - }); -} + cmd->add_flag("-v,--verbose", opts->verbose, + "Produce human writeable output"); + + cmd->add_option("pathname", opts->pathname, "Directory name") + ->required() + ->type_name(""); + cmd->add_option("data", opts->data, "Data to write") + ->required() + ->type_name(""); + cmd->add_option("count", opts->count, "Number of bytes to write") + ->required() + ->type_name(""); + + cmd->add_option("offset", opts->offset, "Offset to read") + ->required() + ->type_name(""); + + cmd->callback([opts]() { pwrite_exec(*opts); }); +} diff --git a/tests/integration/harness/gkfs.io/pwritev.cpp b/tests/integration/harness/gkfs.io/pwritev.cpp index 76e2ec1900ec771cdf86698177fc534f0b774165..dd3f020d5b4c838a6598ea73839d27ed7fafa731 100644 --- a/tests/integration/harness/gkfs.io/pwritev.cpp +++ b/tests/integration/harness/gkfs.io/pwritev.cpp @@ -31,47 +31,44 @@ using json = nlohmann::json; struct pwritev_options { - bool verbose; + bool verbose{}; std::string pathname; std::string data_0, data_1; ::size_t count; ::size_t offset; - REFL_DECL_STRUCT(pwritev_options, - REFL_DECL_MEMBER(bool, verbose), - REFL_DECL_MEMBER(std::string, pathname), - REFL_DECL_MEMBER(std::string, data_0), - REFL_DECL_MEMBER(std::string, data_1), - REFL_DECL_MEMBER(::size_t, count), - REFL_DECL_MEMBER(::size_t, offset) - ); + REFL_DECL_STRUCT(pwritev_options, REFL_DECL_MEMBER(bool, verbose), + REFL_DECL_MEMBER(std::string, pathname), + REFL_DECL_MEMBER(std::string, data_0), + REFL_DECL_MEMBER(std::string, data_1), + REFL_DECL_MEMBER(::size_t, count), + REFL_DECL_MEMBER(::size_t, offset)); }; struct pwritev_output { ::ssize_t retval; int errnum; - REFL_DECL_STRUCT(pwritev_output, - REFL_DECL_MEMBER(::size_t, retval), - REFL_DECL_MEMBER(int, errnum) - ); + REFL_DECL_STRUCT(pwritev_output, REFL_DECL_MEMBER(::size_t, retval), + REFL_DECL_MEMBER(int, errnum)); }; void -to_json(json& record, - const pwritev_output& out) { +to_json(json& record, const pwritev_output& out) { record = serialize(out); } -void +void pwritev_exec(const pwritev_options& opts) { - int fd = ::open(opts.pathname.c_str(), O_WRONLY); + auto fd = ::open(opts.pathname.c_str(), O_WRONLY); if(fd == -1) { if(opts.verbose) { - fmt::print("pwritev(pathname=\"{}\", buf_0=\"{}\" buf_1=\"{}\" count={}, offset={}) = {}, errno: {} [{}]\n", - opts.pathname, opts.data_0, opts.data_1, opts.count, opts.offset, fd, errno, ::strerror(errno)); + fmt::print( + "pwritev(pathname=\"{}\", buf_0=\"{}\" buf_1=\"{}\" count={}, offset={}) = {}, errno: {} [{}]\n", + opts.pathname, opts.data_0, opts.data_1, opts.count, + opts.offset, fd, errno, ::strerror(errno)); return; } @@ -83,7 +80,7 @@ pwritev_exec(const pwritev_options& opts) { io::buffer buf_0(opts.data_0); io::buffer buf_1(opts.data_1); - + struct iovec iov[2]; iov[0].iov_base = buf_0.data(); @@ -95,8 +92,10 @@ pwritev_exec(const pwritev_options& opts) { int rv = ::pwritev(fd, iov, opts.count, opts.offset); if(opts.verbose) { - fmt::print("pwritev(pathname=\"{}\", count={}, offset={}) = {}, errno: {} [{}]\n", - opts.pathname, opts.count, opts.offset, rv, errno, ::strerror(errno)); + fmt::print( + "pwritev(pathname=\"{}\", count={}, offset={}) = {}, errno: {} [{}]\n", + opts.pathname, opts.count, opts.offset, rv, errno, + ::strerror(errno)); return; } @@ -109,60 +108,32 @@ pwritev_init(CLI::App& app) { // Create the option and subcommand objects auto opts = std::make_shared(); - auto* cmd = app.add_subcommand( - "pwritev", - "Execute the pwritev() system call"); + auto* cmd = + app.add_subcommand("pwritev", "Execute the pwritev() system call"); // Add options to cmd, binding them to opts - cmd->add_flag( - "-v,--verbose", - opts->verbose, - "Produce human writeable output" - ); - - cmd->add_option( - "pathname", - opts->pathname, - "Directory name" - ) - ->required() - ->type_name(""); - - cmd->add_option( - "data_0", - opts->data_0, - "Data 0 to write" - ) - ->required() - ->type_name(""); - - cmd->add_option( - "data_1", - opts->data_1, - "Data 1 to write" - ) - ->required() - ->type_name(""); - - cmd->add_option( - "count", - opts->count, - "Number of bytes to write" - ) - ->required() - ->type_name(""); - - cmd->add_option( - "offset", - opts->offset, - "Offset to read" - ) - ->required() - ->type_name(""); - - cmd->callback([opts]() { - pwritev_exec(*opts); - }); -} + cmd->add_flag("-v,--verbose", opts->verbose, + "Produce human writeable output"); + + cmd->add_option("pathname", opts->pathname, "Directory name") + ->required() + ->type_name(""); + cmd->add_option("data_0", opts->data_0, "Data 0 to write") + ->required() + ->type_name(""); + cmd->add_option("data_1", opts->data_1, "Data 1 to write") + ->required() + ->type_name(""); + + cmd->add_option("count", opts->count, "Number of bytes to write") + ->required() + ->type_name(""); + + cmd->add_option("offset", opts->offset, "Offset to read") + ->required() + ->type_name(""); + + cmd->callback([opts]() { pwritev_exec(*opts); }); +} diff --git a/tests/integration/harness/gkfs.io/read.cpp b/tests/integration/harness/gkfs.io/read.cpp index fe5057df18606bdf1ea6337c0c4a8444e9e2ef4f..224c904b8f6ce3893aed4390b6120412d7b52eaa 100644 --- a/tests/integration/harness/gkfs.io/read.cpp +++ b/tests/integration/harness/gkfs.io/read.cpp @@ -30,15 +30,13 @@ using json = nlohmann::json; struct read_options { - bool verbose; + bool verbose{}; std::string pathname; ::size_t count; - REFL_DECL_STRUCT(read_options, - REFL_DECL_MEMBER(bool, verbose), - REFL_DECL_MEMBER(std::string, pathname), - REFL_DECL_MEMBER(::size_t, count) - ); + REFL_DECL_STRUCT(read_options, REFL_DECL_MEMBER(bool, verbose), + REFL_DECL_MEMBER(std::string, pathname), + REFL_DECL_MEMBER(::size_t, count)); }; struct read_output { @@ -46,28 +44,25 @@ struct read_output { io::buffer buf; int errnum; - REFL_DECL_STRUCT(read_output, - REFL_DECL_MEMBER(::size_t, retval), - REFL_DECL_MEMBER(void*, buf), - REFL_DECL_MEMBER(int, errnum) - ); + REFL_DECL_STRUCT(read_output, REFL_DECL_MEMBER(::size_t, retval), + REFL_DECL_MEMBER(void*, buf), + REFL_DECL_MEMBER(int, errnum)); }; void -to_json(json& record, - const read_output& out) { +to_json(json& record, const read_output& out) { record = serialize(out); } -void +void read_exec(const read_options& opts) { - int fd = ::open(opts.pathname.c_str(), O_RDONLY); + auto fd = ::open(opts.pathname.c_str(), O_RDONLY); if(fd == -1) { if(opts.verbose) { - fmt::print("read(pathname=\"{}\", count={}) = {}, errno: {} [{}]\n", - opts.pathname, opts.count, fd, errno, ::strerror(errno)); + fmt::print("read(pathname=\"{}\", count={}) = {}, errno: {} [{}]\n", + opts.pathname, opts.count, fd, errno, ::strerror(errno)); return; } @@ -79,10 +74,10 @@ read_exec(const read_options& opts) { io::buffer buf(opts.count); - int rv = ::read(fd, buf.data(), opts.count); + auto rv = ::read(fd, buf.data(), opts.count); if(opts.verbose) { - fmt::print("read(pathname=\"{}\", count={}) = {}, errno: {} [{}]\n", + fmt::print("read(pathname=\"{}\", count={}) = {}, errno: {} [{}]\n", opts.pathname, opts.count, rv, errno, ::strerror(errno)); return; } @@ -96,35 +91,19 @@ read_init(CLI::App& app) { // Create the option and subcommand objects auto opts = std::make_shared(); - auto* cmd = app.add_subcommand( - "read", - "Execute the read() system call"); + auto* cmd = app.add_subcommand("read", "Execute the read() system call"); // Add options to cmd, binding them to opts - cmd->add_flag( - "-v,--verbose", - opts->verbose, - "Produce human readable output" - ); - - cmd->add_option( - "pathname", - opts->pathname, - "Directory name" - ) - ->required() - ->type_name(""); - - cmd->add_option( - "count", - opts->count, - "Number of bytes to read" - ) - ->required() - ->type_name(""); - - cmd->callback([opts]() { - read_exec(*opts); - }); -} + cmd->add_flag("-v,--verbose", opts->verbose, + "Produce human readable output"); + + cmd->add_option("pathname", opts->pathname, "Directory name") + ->required() + ->type_name(""); + cmd->add_option("count", opts->count, "Number of bytes to read") + ->required() + ->type_name(""); + + cmd->callback([opts]() { read_exec(*opts); }); +} diff --git a/tests/integration/harness/gkfs.io/readdir.cpp b/tests/integration/harness/gkfs.io/readdir.cpp index 163bf7723d25068e9eb2c0329ce6b0ecbb76e7e7..3fdbadf6bf40257f0a8bddb119c2f1c80b82d980 100644 --- a/tests/integration/harness/gkfs.io/readdir.cpp +++ b/tests/integration/harness/gkfs.io/readdir.cpp @@ -28,15 +28,13 @@ using json = nlohmann::json; struct readdir_options { - bool verbose; + bool verbose{}; std::string pathname; ::size_t count; - REFL_DECL_STRUCT(readdir_options, - REFL_DECL_MEMBER(bool, verbose), - REFL_DECL_MEMBER(std::string, pathname), - REFL_DECL_MEMBER(::size_t, count) - ); + REFL_DECL_STRUCT(readdir_options, REFL_DECL_MEMBER(bool, verbose), + REFL_DECL_MEMBER(std::string, pathname), + REFL_DECL_MEMBER(::size_t, count)); }; struct readdir_output { @@ -44,26 +42,24 @@ struct readdir_output { int errnum; REFL_DECL_STRUCT(readdir_output, - REFL_DECL_MEMBER(std::vector, dirents), - REFL_DECL_MEMBER(int, errnum) - ); + REFL_DECL_MEMBER(std::vector, dirents), + REFL_DECL_MEMBER(int, errnum)); }; void -to_json(json& record, - const readdir_output& out) { +to_json(json& record, const readdir_output& out) { record = serialize(out); } -void +void readdir_exec(const readdir_options& opts) { ::DIR* dirp = ::opendir(opts.pathname.c_str()); if(dirp == NULL) { if(opts.verbose) { - fmt::print("readdir(pathname=\"{}\") = {}, errno: {} [{}]\n", - opts.pathname, "NULL", errno, ::strerror(errno)); + fmt::print("readdir(pathname=\"{}\") = {}, errno: {} [{}]\n", + opts.pathname, "NULL", errno, ::strerror(errno)); return; } @@ -83,8 +79,9 @@ readdir_exec(const readdir_options& opts) { } if(opts.verbose) { - fmt::print("readdir(pathname=\"{}\") = [\n{}],\nerrno: {} [{}]\n", - opts.pathname, fmt::join(entries, ",\n"), errno, ::strerror(errno)); + fmt::print("readdir(pathname=\"{}\") = [\n{}],\nerrno: {} [{}]\n", + opts.pathname, fmt::join(entries, ",\n"), errno, + ::strerror(errno)); return; } @@ -97,28 +94,16 @@ readdir_init(CLI::App& app) { // Create the option and subcommand objects auto opts = std::make_shared(); - auto* cmd = app.add_subcommand( - "readdir", - "Execute the readdir() system call"); + auto* cmd = + app.add_subcommand("readdir", "Execute the readdir() system call"); // Add options to cmd, binding them to opts - cmd->add_flag( - "-v,--verbose", - opts->verbose, - "Produce human readable output" - ); - - cmd->add_option( - "pathname", - opts->pathname, - "Directory name" - ) - ->required() - ->type_name(""); - - cmd->callback([opts]() { - readdir_exec(*opts); - }); -} + cmd->add_flag("-v,--verbose", opts->verbose, + "Produce human readable output"); + cmd->add_option("pathname", opts->pathname, "Directory name") + ->required() + ->type_name(""); + cmd->callback([opts]() { readdir_exec(*opts); }); +} diff --git a/tests/integration/harness/gkfs.io/readv.cpp b/tests/integration/harness/gkfs.io/readv.cpp index 00ea9926f3dd953ca1e07a5e3a429bf162d8a918..a47b1dda16483a5eee7cd7c3bbc8aa1c5309e314 100644 --- a/tests/integration/harness/gkfs.io/readv.cpp +++ b/tests/integration/harness/gkfs.io/readv.cpp @@ -31,17 +31,15 @@ using json = nlohmann::json; struct readv_options { - bool verbose; + bool verbose{}; std::string pathname; ::size_t count_0; ::size_t count_1; - REFL_DECL_STRUCT(readv_options, - REFL_DECL_MEMBER(bool, verbose), - REFL_DECL_MEMBER(std::string, pathname), - REFL_DECL_MEMBER(::size_t, count_0), - REFL_DECL_MEMBER(::size_t, count_1) - ); + REFL_DECL_STRUCT(readv_options, REFL_DECL_MEMBER(bool, verbose), + REFL_DECL_MEMBER(std::string, pathname), + REFL_DECL_MEMBER(::size_t, count_0), + REFL_DECL_MEMBER(::size_t, count_1)); }; struct readv_output { @@ -50,29 +48,28 @@ struct readv_output { io::buffer buf_1; int errnum; - REFL_DECL_STRUCT(readv_output, - REFL_DECL_MEMBER(::size_t, retval), - REFL_DECL_MEMBER(void*, buf_0), - REFL_DECL_MEMBER(void*, buf_1), - REFL_DECL_MEMBER(int, errnum) - ); + REFL_DECL_STRUCT(readv_output, REFL_DECL_MEMBER(::size_t, retval), + REFL_DECL_MEMBER(void*, buf_0), + REFL_DECL_MEMBER(void*, buf_1), + REFL_DECL_MEMBER(int, errnum)); }; void -to_json(json& record, - const readv_output& out) { +to_json(json& record, const readv_output& out) { record = serialize(out); } -void +void readv_exec(const readv_options& opts) { - int fd = ::open(opts.pathname.c_str(), O_RDONLY); + auto fd = ::open(opts.pathname.c_str(), O_RDONLY); if(fd == -1) { if(opts.verbose) { - fmt::print("readv(pathname=\"{}\", count_0={}, count_1={}) = {}, errno: {} [{}]\n", - opts.pathname, opts.count_0, opts.count_1, fd, errno, ::strerror(errno)); + fmt::print( + "readv(pathname=\"{}\", count_0={}, count_1={}) = {}, errno: {} [{}]\n", + opts.pathname, opts.count_0, opts.count_1, fd, errno, + ::strerror(errno)); return; } @@ -93,15 +90,18 @@ readv_exec(const readv_options& opts) { iov[0].iov_len = opts.count_0; iov[1].iov_len = opts.count_1; - int rv = ::readv(fd, iov, 2); + auto rv = ::readv(fd, iov, 2); if(opts.verbose) { - fmt::print("readv(pathname=\"{}\", count_0={}, count_1={}) = {}, errno: {} [{}]\n", - opts.pathname, opts.count_0, opts.count_1, rv, errno, ::strerror(errno)); + fmt::print( + "readv(pathname=\"{}\", count_0={}, count_1={}) = {}, errno: {} [{}]\n", + opts.pathname, opts.count_0, opts.count_1, rv, errno, + ::strerror(errno)); return; } - json out = readv_output{rv, (rv != -1 ? buf_0 : nullptr), (rv != -1 ? buf_1 : nullptr), errno}; + json out = readv_output{rv, (rv != -1 ? buf_0 : nullptr), + (rv != -1 ? buf_1 : nullptr), errno}; fmt::print("{}\n", out.dump(2)); } @@ -110,43 +110,25 @@ readv_init(CLI::App& app) { // Create the option and subcommand objects auto opts = std::make_shared(); - auto* cmd = app.add_subcommand( - "readv", - "Execute the readv() system call"); + auto* cmd = app.add_subcommand("readv", "Execute the readv() system call"); // Add options to cmd, binding them to opts - cmd->add_flag( - "-v,--verbose", - opts->verbose, - "Produce human readable output" - ); - - cmd->add_option( - "pathname", - opts->pathname, - "Directory name" - ) - ->required() - ->type_name(""); - - cmd->add_option( - "count_0", - opts->count_0, - "Number of bytes to read to buffer 0" - ) - ->required() - ->type_name(""); - - cmd->add_option( - "count_1", - opts->count_1, - "Number of bytes to read to buffer 1" - ) - ->required() - ->type_name(""); - - cmd->callback([opts]() { - readv_exec(*opts); - }); -} + cmd->add_flag("-v,--verbose", opts->verbose, + "Produce human readable output"); + + cmd->add_option("pathname", opts->pathname, "Directory name") + ->required() + ->type_name(""); + cmd->add_option("count_0", opts->count_0, + "Number of bytes to read to buffer 0") + ->required() + ->type_name(""); + + cmd->add_option("count_1", opts->count_1, + "Number of bytes to read to buffer 1") + ->required() + ->type_name(""); + + cmd->callback([opts]() { readv_exec(*opts); }); +} diff --git a/tests/integration/harness/gkfs.io/reflection.hpp b/tests/integration/harness/gkfs.io/reflection.hpp index 1375a801054eb7e38e2843857607261a4e9d8c30..b4f6e23e2cfea87a6cbce8321e030f0d3f543fe7 100644 --- a/tests/integration/harness/gkfs.io/reflection.hpp +++ b/tests/integration/harness/gkfs.io/reflection.hpp @@ -28,10 +28,8 @@ namespace detail { template struct property_impl { constexpr property_impl(T Class::*aMember, const char* aType, - const char* aName) : - member{aMember}, - type{aType}, - name{aName} {} + const char* aName) + : member{aMember}, type{aType}, name{aName} {} using Type = T; @@ -42,48 +40,47 @@ struct property_impl { } // namespace detail -template -constexpr auto +template +constexpr auto property(T Class::*member, const char* type, const char* name) { return detail::property_impl{member, type, name}; } template -constexpr void for_sequence(std::integer_sequence, F&& f) { +constexpr void +for_sequence(std::integer_sequence, F&& f) { using unpack_t = int[]; - (void) unpack_t{(static_cast(f(std::integral_constant{})), 0)..., 0}; + (void) unpack_t{ + (static_cast(f(std::integral_constant{})), 0)..., 0}; } } // namespace refl /* private helper macros, do not call directly */ -#define _REFL_STRUCT_NAME(t) BOOST_PP_TUPLE_ELEM(0, t) +#define _REFL_STRUCT_NAME(t) BOOST_PP_TUPLE_ELEM(0, t) #define _REFL_STRUCT_MEMBER_COUNT(t) BOOST_PP_TUPLE_ELEM(1, t) -#define _REFL_MEMBER_TYPE(t) BOOST_PP_TUPLE_ELEM(0, t) -#define _REFL_MEMBER_NAME(t) BOOST_PP_TUPLE_ELEM(1, t) - -#define _REFL_GEN_FIELD(r, data, index, elem) \ - refl::property( \ - &_REFL_STRUCT_NAME(data)::_REFL_MEMBER_NAME(elem), \ - BOOST_PP_STRINGIZE(_REFL_MEMBER_TYPE(elem)), \ - BOOST_PP_STRINGIZE(_REFL_MEMBER_NAME(elem)) \ - ) \ - BOOST_PP_COMMA_IF( \ - BOOST_PP_NOT_EQUAL(index, \ - BOOST_PP_DEC(_REFL_STRUCT_MEMBER_COUNT(data)))) +#define _REFL_MEMBER_TYPE(t) BOOST_PP_TUPLE_ELEM(0, t) +#define _REFL_MEMBER_NAME(t) BOOST_PP_TUPLE_ELEM(1, t) + +#define _REFL_GEN_FIELD(r, data, index, elem) \ + refl::property( \ + &_REFL_STRUCT_NAME(data)::_REFL_MEMBER_NAME(elem), \ + BOOST_PP_STRINGIZE(_REFL_MEMBER_TYPE(elem)), \ + BOOST_PP_STRINGIZE(_REFL_MEMBER_NAME(elem))) \ + BOOST_PP_COMMA_IF(BOOST_PP_NOT_EQUAL( \ + index, \ + BOOST_PP_DEC(_REFL_STRUCT_MEMBER_COUNT(data)))) /* public interface */ -#define REFL_DECL_MEMBER(type, name) \ - (type, name) - -#define REFL_DECL_STRUCT(struct_name, ...) \ - constexpr static auto properties = std::make_tuple( \ - BOOST_PP_SEQ_FOR_EACH_I( \ - _REFL_GEN_FIELD, \ - ( struct_name, BOOST_PP_VARIADIC_SIZE(__VA_ARGS__ ) ), \ - BOOST_PP_TUPLE_TO_SEQ( ( __VA_ARGS__ ) )) \ - );\ +#define REFL_DECL_MEMBER(type, name) (type, name) + +#define REFL_DECL_STRUCT(struct_name, ...) \ + constexpr static auto properties = \ + std::make_tuple(BOOST_PP_SEQ_FOR_EACH_I( \ + _REFL_GEN_FIELD, \ + (struct_name, BOOST_PP_VARIADIC_SIZE(__VA_ARGS__)), \ + BOOST_PP_TUPLE_TO_SEQ((__VA_ARGS__)))); \ static_assert(true, "") #endif // GKFS_IO_REFLECTION_HPP diff --git a/tests/integration/harness/gkfs.io/rmdir.cpp b/tests/integration/harness/gkfs.io/rmdir.cpp index 00620c2c01150f5817ffe338b02f3fec9819616f..0f00440a89389fb828c567df0cb32fa05ef0f370 100644 --- a/tests/integration/harness/gkfs.io/rmdir.cpp +++ b/tests/integration/harness/gkfs.io/rmdir.cpp @@ -27,39 +27,34 @@ using json = nlohmann::json; struct rmdir_options { - bool verbose; + bool verbose{}; std::string pathname; - REFL_DECL_STRUCT(rmdir_options, - REFL_DECL_MEMBER(bool, verbose), - REFL_DECL_MEMBER(std::string, pathname) - ); + REFL_DECL_STRUCT(rmdir_options, REFL_DECL_MEMBER(bool, verbose), + REFL_DECL_MEMBER(std::string, pathname)); }; struct rmdir_output { int retval; int errnum; - REFL_DECL_STRUCT(rmdir_output, - REFL_DECL_MEMBER(int, retval), - REFL_DECL_MEMBER(int, errnum) - ); + REFL_DECL_STRUCT(rmdir_output, REFL_DECL_MEMBER(int, retval), + REFL_DECL_MEMBER(int, errnum)); }; void -to_json(json& record, - const rmdir_output& out) { +to_json(json& record, const rmdir_output& out) { record = serialize(out); } -void +void rmdir_exec(const rmdir_options& opts) { - int fd = ::rmdir(opts.pathname.c_str()); + auto fd = ::rmdir(opts.pathname.c_str()); if(opts.verbose) { fmt::print("rmdir(pathname=\"{}\") = {}, errno: {} [{}]\n", - opts.pathname, errno, ::strerror(errno)); + opts.pathname, errno, ::strerror(errno)); return; } @@ -74,29 +69,15 @@ rmdir_init(CLI::App& app) { // Create the option and subcommand objects auto opts = std::make_shared(); - auto* cmd = app.add_subcommand( - "rmdir", - "Execute the rmdir() system call"); + auto* cmd = app.add_subcommand("rmdir", "Execute the rmdir() system call"); // Add options to cmd, binding them to opts - cmd->add_flag( - "-v,--verbose", - opts->verbose, - "Produce human readable output" - ); - - cmd->add_option( - "pathname", - opts->pathname, - "Directory name" - ) - ->required() - ->type_name(""); - - cmd->callback([opts]() { - rmdir_exec(*opts); - }); -} - + cmd->add_flag("-v,--verbose", opts->verbose, + "Produce human readable output"); + cmd->add_option("pathname", opts->pathname, "Directory name") + ->required() + ->type_name(""); + cmd->callback([opts]() { rmdir_exec(*opts); }); +} diff --git a/tests/integration/harness/gkfs.io/serialize.hpp b/tests/integration/harness/gkfs.io/serialize.hpp index 7ee43c4b65154bcedeb86087784fc3c7f4198c10..9cc096337d8959cfe1d1fc39be99d049feaebd3e 100644 --- a/tests/integration/harness/gkfs.io/serialize.hpp +++ b/tests/integration/harness/gkfs.io/serialize.hpp @@ -31,30 +31,29 @@ serialize(const T& object) { constexpr auto n = std::tuple_size::value; - refl::for_sequence(std::make_index_sequence{}, - [&](auto i) { - constexpr auto p = std::get(T::properties); + refl::for_sequence(std::make_index_sequence{}, [&](auto i) { + constexpr auto p = std::get(T::properties); - //j[p.name] = json { - // { "type" , p.type }, - // { "value" , object.*(p.member) } - //}; + // j[p.name] = json { + // { "type" , p.type }, + // { "value" , object.*(p.member) } + //}; - j[p.name] = object.*(p.member); - } - ); + j[p.name] = object.*(p.member); + }); return j; } namespace nlohmann { -// ADL specialization for pointers to complete types that +// ADL specialization for pointers to complete types that // we want serialized template struct adl_serializer { - static void to_json(json& j, const T* opt) { - if (opt) { + static void + to_json(json& j, const T* opt) { + if(opt) { j = *opt; } else { j = nullptr; @@ -65,8 +64,9 @@ struct adl_serializer { // ADL specialization for C strings template <> struct adl_serializer { - static void to_json(json& j, const char* opt) { - if (opt) { + static void + to_json(json& j, const char* opt) { + if(opt) { j = std::string{opt}; } else { j = std::string{}; @@ -77,8 +77,9 @@ struct adl_serializer { // base serializer for opaque pointers template struct opaque_ptr_serializer { - static void to_json(json& j, const T opt) { - if (opt) { + static void + to_json(json& j, const T opt) { + if(opt) { j = reinterpret_cast(opt); } else { j = nullptr; @@ -101,12 +102,10 @@ struct adl_serializer : public opaque_ptr_serializer { // ADL specialization for struct ::timespec type template <> struct adl_serializer { - static void to_json(json& j, const struct ::timespec opt) { + static void + to_json(json& j, const struct ::timespec opt) { - j = json { - { "tv_sec", opt.tv_sec }, - { "tv_nsec", opt.tv_nsec } - }; + j = json{{"tv_sec", opt.tv_sec}, {"tv_nsec", opt.tv_nsec}}; } }; @@ -114,12 +113,10 @@ struct adl_serializer { // ADL specialization for struct ::statx_timestamp type template <> struct adl_serializer { - static void to_json(json& j, const struct ::statx_timestamp opt) { + static void + to_json(json& j, const struct ::statx_timestamp opt) { - j = json { - { "tv_sec", opt.tv_sec }, - { "tv_nsec", opt.tv_nsec } - }; + j = json{{"tv_sec", opt.tv_sec}, {"tv_nsec", opt.tv_nsec}}; } }; #endif @@ -127,43 +124,35 @@ struct adl_serializer { // ADL specialization for struct ::dirent type template <> struct adl_serializer { - static void to_json(json& j, const struct ::dirent opt) { - - j = json { - { "d_ino", opt.d_ino }, - { "d_off", opt.d_off }, - { "d_reclen", opt.d_reclen }, - { "d_type", opt.d_type }, - { "d_name", opt.d_name }, + static void + to_json(json& j, const struct ::dirent opt) { + + j = json{ + {"d_ino", opt.d_ino}, {"d_off", opt.d_off}, + {"d_reclen", opt.d_reclen}, {"d_type", opt.d_type}, + {"d_name", opt.d_name}, }; } }; -//std::ostream& -//operator<<(std::ostream& os, const struct ::dirent& d) { +// std::ostream& +// operator<<(std::ostream& os, const struct ::dirent& d) { // return os << "hello there!\n"; //} // ADL specialization for struct ::stat type template <> struct adl_serializer { - static void to_json(json& j, const struct ::stat opt) { - - j = json { - { "st_dev", opt.st_dev }, - { "st_ino", opt.st_ino }, - { "st_mode", opt.st_mode }, - { "st_nlink", opt.st_nlink }, - { "st_uid", opt.st_uid }, - { "st_gid", opt.st_gid }, - { "st_rdev", opt.st_rdev }, - { "st_size", opt.st_size }, - { "st_blksize", opt.st_blksize }, - { "st_blocks", opt.st_blocks }, - { "st_atim", opt.st_atim }, - { "st_mtim", opt.st_mtim }, - { "st_ctim", opt.st_ctim } - }; + static void + to_json(json& j, const struct ::stat opt) { + + j = json{{"st_dev", opt.st_dev}, {"st_ino", opt.st_ino}, + {"st_mode", opt.st_mode}, {"st_nlink", opt.st_nlink}, + {"st_uid", opt.st_uid}, {"st_gid", opt.st_gid}, + {"st_rdev", opt.st_rdev}, {"st_size", opt.st_size}, + {"st_blksize", opt.st_blksize}, {"st_blocks", opt.st_blocks}, + {"st_atim", opt.st_atim}, {"st_mtim", opt.st_mtim}, + {"st_ctim", opt.st_ctim}}; } }; @@ -171,30 +160,30 @@ struct adl_serializer { // ADL specialization for struct ::statx type template <> struct adl_serializer { - static void to_json(json& j, const struct ::statx opt) { - - j = json { - { "stx_mask", opt.stx_mask }, - { "stx_blksize", opt.stx_blksize }, - { "stx_attributes", opt.stx_attributes}, - { "stx_nlink", opt.stx_nlink }, - { "stx_uid", opt.stx_uid }, - { "stx_gid", opt.stx_gid }, - { "stx_mode", opt.stx_mode }, - { "stx_ino", opt.stx_ino }, - { "stx_size", opt.stx_size }, - { "stx_blocks", opt.stx_blocks }, - { "stx_attributes_mask", opt.stx_attributes_mask}, - { "stx_atime", opt.stx_atime }, - { "stx_btime", opt.stx_btime }, - { "stx_ctime", opt.stx_ctime }, - { "stx_mtime", opt.stx_mtime }, - - { "stx_rdev_major", opt.stx_rdev_major }, - { "stx_rdev_minor", opt.stx_rdev_minor }, - { "stx_dev_major", opt.stx_dev_major }, - { "stx_dev_minor", opt.stx_dev_minor } - + static void + to_json(json& j, const struct ::statx opt) { + + j = json{{"stx_mask", opt.stx_mask}, + {"stx_blksize", opt.stx_blksize}, + {"stx_attributes", opt.stx_attributes}, + {"stx_nlink", opt.stx_nlink}, + {"stx_uid", opt.stx_uid}, + {"stx_gid", opt.stx_gid}, + {"stx_mode", opt.stx_mode}, + {"stx_ino", opt.stx_ino}, + {"stx_size", opt.stx_size}, + {"stx_blocks", opt.stx_blocks}, + {"stx_attributes_mask", opt.stx_attributes_mask}, + {"stx_atime", opt.stx_atime}, + {"stx_btime", opt.stx_btime}, + {"stx_ctime", opt.stx_ctime}, + {"stx_mtime", opt.stx_mtime}, + + {"stx_rdev_major", opt.stx_rdev_major}, + {"stx_rdev_minor", opt.stx_rdev_minor}, + {"stx_dev_major", opt.stx_dev_major}, + {"stx_dev_minor", opt.stx_dev_minor} + }; } }; @@ -204,11 +193,13 @@ struct adl_serializer { namespace fmt { -template <> struct formatter { - constexpr auto parse(format_parse_context &ctx) { +template <> +struct formatter { + constexpr auto + parse(format_parse_context& ctx) { // [ctx.begin(), ctx.end()) is a character range that contains a part of - // the format string starting from the format specifications to be parsed, - // e.g. in + // the format string starting from the format specifications to be + // parsed, e.g. in // // fmt::format("{:f} - point of interest", point{1, 2}); // @@ -221,31 +212,29 @@ template <> struct formatter { auto it = ctx.begin(), end = ctx.end(); // Check if reached the end of the range: - if (it != end && *it != '}') - throw format_error("invalid format"); + if(it != end && *it != '}') + throw format_error("invalid format"); // Return an iterator past the end of the parsed range: return it; } template - auto format(const struct ::dirent &dirent, FormatContext &ctx) { - return format_to(ctx.out(), - "struct dirent {{\n" - " d_ino = {};\n" - " d_off = {};\n" - " d_reclen = {};\n" - " d_type = {};\n" - " d_name = {};\n" - "}}", - dirent.d_ino, - dirent.d_off, - dirent.d_reclen, - dirent.d_type, - dirent.d_name); - } + auto + format(const struct ::dirent& dirent, FormatContext& ctx) { + return format_to(ctx.out(), + "struct dirent {{\n" + " d_ino = {};\n" + " d_off = {};\n" + " d_reclen = {};\n" + " d_type = {};\n" + " d_name = {};\n" + "}}", + dirent.d_ino, dirent.d_off, dirent.d_reclen, + dirent.d_type, dirent.d_name); + } }; -} +} // namespace fmt #endif // GKFS_IO_SERIALIZE_HPP diff --git a/tests/integration/harness/gkfs.io/stat.cpp b/tests/integration/harness/gkfs.io/stat.cpp index 6f3d03740541d7039549be37da50967a2a9ee9d0..bab1745c331b648af8282d5bb273437f711feddc 100644 --- a/tests/integration/harness/gkfs.io/stat.cpp +++ b/tests/integration/harness/gkfs.io/stat.cpp @@ -28,13 +28,11 @@ using json = nlohmann::json; struct stat_options { - bool verbose; + bool verbose{}; std::string pathname; - REFL_DECL_STRUCT(stat_options, - REFL_DECL_MEMBER(bool, verbose), - REFL_DECL_MEMBER(std::string, pathname) - ); + REFL_DECL_STRUCT(stat_options, REFL_DECL_MEMBER(bool, verbose), + REFL_DECL_MEMBER(std::string, pathname)); }; struct stat_output { @@ -42,28 +40,25 @@ struct stat_output { int errnum; struct ::stat statbuf; - REFL_DECL_STRUCT(stat_output, - REFL_DECL_MEMBER(int, retval), - REFL_DECL_MEMBER(int, errnum), - REFL_DECL_MEMBER(struct ::stat, statbuf) - ); + REFL_DECL_STRUCT(stat_output, REFL_DECL_MEMBER(int, retval), + REFL_DECL_MEMBER(int, errnum), + REFL_DECL_MEMBER(struct ::stat, statbuf)); }; void -to_json(json& record, - const stat_output& out) { +to_json(json& record, const stat_output& out) { record = serialize(out); } -void +void stat_exec(const stat_options& opts) { struct ::stat statbuf; - int rv = ::stat(opts.pathname.c_str(), &statbuf); + auto rv = ::stat(opts.pathname.c_str(), &statbuf); if(opts.verbose) { - fmt::print("stat(pathname=\"{}\") = {}, errno: {} [{}]\n", + fmt::print("stat(pathname=\"{}\") = {}, errno: {} [{}]\n", opts.pathname, rv, errno, ::strerror(errno)); return; } @@ -77,27 +72,15 @@ stat_init(CLI::App& app) { // Create the option and subcommand objects auto opts = std::make_shared(); - auto* cmd = app.add_subcommand( - "stat", - "Execute the stat() system call"); + auto* cmd = app.add_subcommand("stat", "Execute the stat() system call"); // Add options to cmd, binding them to opts - cmd->add_flag( - "-v,--verbose", - opts->verbose, - "Produce human readable output" - ); - - cmd->add_option( - "pathname", - opts->pathname, - "Directory name" - ) - ->required() - ->type_name(""); - - cmd->callback([opts]() { - stat_exec(*opts); - }); -} + cmd->add_flag("-v,--verbose", opts->verbose, + "Produce human readable output"); + cmd->add_option("pathname", opts->pathname, "Directory name") + ->required() + ->type_name(""); + + cmd->callback([opts]() { stat_exec(*opts); }); +} diff --git a/tests/integration/harness/gkfs.io/statx.cpp b/tests/integration/harness/gkfs.io/statx.cpp index 1882b1c8c0061ec9b5446d7d710ec5f5202d7b76..b0b252f9444024ed9d7d4cd95b201e457ec468c8 100644 --- a/tests/integration/harness/gkfs.io/statx.cpp +++ b/tests/integration/harness/gkfs.io/statx.cpp @@ -24,7 +24,7 @@ #include #include #include -#include /* Definition of AT_* constants */ +#include /* Definition of AT_* constants */ using json = nlohmann::json; @@ -34,19 +34,17 @@ using json = nlohmann::json; #ifdef STATX_TYPE struct statx_options { - bool verbose; + bool verbose{}; int dirfd; std::string pathname; int flags; unsigned int mask; - REFL_DECL_STRUCT(statx_options, - REFL_DECL_MEMBER(bool, verbose), - REFL_DECL_MEMBER(int, dirfd), - REFL_DECL_MEMBER(std::string, pathname), - REFL_DECL_MEMBER(int, flags), - REFL_DECL_MEMBER(unsigned int, mask) - ); + REFL_DECL_STRUCT(statx_options, REFL_DECL_MEMBER(bool, verbose), + REFL_DECL_MEMBER(int, dirfd), + REFL_DECL_MEMBER(std::string, pathname), + REFL_DECL_MEMBER(int, flags), + REFL_DECL_MEMBER(unsigned int, mask)); }; struct statx_output { @@ -54,29 +52,29 @@ struct statx_output { int errnum; struct ::statx statbuf; - REFL_DECL_STRUCT(statx_output, - REFL_DECL_MEMBER(int, retval), - REFL_DECL_MEMBER(int, errnum), - REFL_DECL_MEMBER(struct ::statx, statbuf) - ); + REFL_DECL_STRUCT(statx_output, REFL_DECL_MEMBER(int, retval), + REFL_DECL_MEMBER(int, errnum), + REFL_DECL_MEMBER(struct ::statx, statbuf)); }; void -to_json(json& record, - const statx_output& out) { +to_json(json& record, const statx_output& out) { record = serialize(out); } -void +void statx_exec(const statx_options& opts) { struct ::statx statbuf; - int rv = ::statx(opts.dirfd, opts.pathname.c_str(), opts.flags, opts.mask, &statbuf); + auto rv = ::statx(opts.dirfd, opts.pathname.c_str(), opts.flags, opts.mask, + &statbuf); if(opts.verbose) { - fmt::print("statx(dirfd={}, pathname=\"{}\", flags={}, mask={}) = {}, errno: {} [{}]\n", - opts.dirfd, opts.pathname, opts.flags, opts.mask, rv, errno, ::strerror(errno)); + fmt::print( + "statx(dirfd={}, pathname=\"{}\", flags={}, mask={}) = {}, errno: {} [{}]\n", + opts.dirfd, opts.pathname, opts.flags, opts.mask, rv, errno, + ::strerror(errno)); return; } @@ -89,51 +87,24 @@ statx_init(CLI::App& app) { // Create the option and subcommand objects auto opts = std::make_shared(); - auto* cmd = app.add_subcommand( - "statx", - "Execute the statx() system call"); + auto* cmd = app.add_subcommand("statx", "Execute the statx() system call"); // Add options to cmd, binding them to opts - cmd->add_flag( - "-v,--verbose", - opts->verbose, - "Produce human readable output" - ); - - cmd->add_option( - "dirfd", - opts->dirfd, - "file descritor" - ) - ->required() - ->type_name(""); - - cmd->add_option( - "pathname", - opts->pathname, - "Directory name" - ) - ->required() - ->type_name(""); - - cmd->add_option( - "flags", - opts->flags, - "Flags" - ) - ->required() - ->type_name(""); - - cmd->add_option( - "mask", - opts->mask, - "Mask" - ) - ->required() - ->type_name(""); - - cmd->callback([opts]() { - statx_exec(*opts); - }); + cmd->add_flag("-v,--verbose", opts->verbose, + "Produce human readable output"); + + cmd->add_option("dirfd", opts->dirfd, "file descritor") + ->required() + ->type_name(""); + + cmd->add_option("pathname", opts->pathname, "Directory name") + ->required() + ->type_name(""); + + cmd->add_option("flags", opts->flags, "Flags")->required()->type_name(""); + + cmd->add_option("mask", opts->mask, "Mask")->required()->type_name(""); + + cmd->callback([opts]() { statx_exec(*opts); }); } #endif diff --git a/tests/integration/harness/gkfs.io/symlink.cpp b/tests/integration/harness/gkfs.io/symlink.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c4dff2ccdd7380862bff6d60865b4dfeec6c0210 --- /dev/null +++ b/tests/integration/harness/gkfs.io/symlink.cpp @@ -0,0 +1,88 @@ +/* + Copyright 2018-2020, Barcelona Supercomputing Center (BSC), Spain + Copyright 2015-2020, Johannes Gutenberg Universitaet Mainz, Germany + + This software was partially supported by the + EC H2020 funded project NEXTGenIO (Project ID: 671951, www.nextgenio.eu). + + This software was partially supported by the + ADA-FS project under the SPPEXA project funded by the DFG. + + SPDX-License-Identifier: MIT +*/ + +/* C++ includes */ +#include +#include +#include +#include +#include +#include +#include + +/* C includes */ +#include + +using json = nlohmann::json; + +struct symlink_options { + bool verbose{}; + std::string pathname; + std::string linkpath; + + REFL_DECL_STRUCT(symlink_options, REFL_DECL_MEMBER(bool, verbose), + REFL_DECL_MEMBER(std::string, pathname), + REFL_DECL_MEMBER(std::string, linkpath)); +}; + +struct symlink_output { + int retval; + int errnum; + + REFL_DECL_STRUCT(symlink_output, REFL_DECL_MEMBER(int, retval), + REFL_DECL_MEMBER(int, errnum)); +}; + +void +to_json(json& record, const symlink_output& out) { + record = serialize(out); +} + +void +symlink_exec(const symlink_options& opts) { + + auto rv = ::symlink(opts.pathname.c_str(), opts.linkpath.c_str()); + + if(opts.verbose) { + fmt::print( + "symlink(pathname=\"{}\", linkpath=\"{}\") = {}, errno: {} [{}]\n", + opts.pathname, opts.linkpath, rv, errno, ::strerror(errno)); + return; + } + + json out = symlink_output{rv, errno}; + fmt::print("{}\n", out.dump(2)); +} + +void +symlink_init(CLI::App& app) { + + // Create the option and subcommand objects + auto opts = std::make_shared(); + auto* cmd = + app.add_subcommand("symlink", "Execute the symlink() system call"); + + // Add options to cmd, binding them to opts + cmd->add_flag("-v,--verbose", opts->verbose, + "Produce human readable output"); + + cmd->add_option("pathname", opts->pathname, "Directory name") + ->required() + ->type_name(""); + + cmd->add_option("linkpath", opts->linkpath, "link path name") + ->required() + ->type_name(""); + + cmd->callback([opts]() { symlink_exec(*opts); }); +} diff --git a/tests/integration/harness/gkfs.io/truncate.cpp b/tests/integration/harness/gkfs.io/truncate.cpp index db6c6156e0caae6e52c77ac227273909772f54b5..eaf33a49e165080b2a739e667a176a60fc1451c4 100644 --- a/tests/integration/harness/gkfs.io/truncate.cpp +++ b/tests/integration/harness/gkfs.io/truncate.cpp @@ -30,37 +30,33 @@ struct truncate_options { std::string path{}; ::off_t length{}; - REFL_DECL_STRUCT(truncate_options, - REFL_DECL_MEMBER(bool, verbose), - REFL_DECL_MEMBER(std::string, path), - REFL_DECL_MEMBER(::off_t, length) - ); + REFL_DECL_STRUCT(truncate_options, REFL_DECL_MEMBER(bool, verbose), + REFL_DECL_MEMBER(std::string, path), + REFL_DECL_MEMBER(::off_t, length)); }; struct truncate_output { int retval; int errnum; - REFL_DECL_STRUCT(truncate_output, - REFL_DECL_MEMBER(int, retval), - REFL_DECL_MEMBER(int, errnum) - ); + REFL_DECL_STRUCT(truncate_output, REFL_DECL_MEMBER(int, retval), + REFL_DECL_MEMBER(int, errnum)); }; void -to_json(json& record, - const truncate_output& out) { +to_json(json& record, const truncate_output& out) { record = serialize(out); } -void +void truncate_exec(const truncate_options& opts) { auto rv = ::truncate(opts.path.c_str(), opts.length); - if (rv == -1) { - if (opts.verbose) { - fmt::print("truncate(path=\"{}\", length={}) = {}, errno: {} [{}]\n", - opts.path, opts.length, rv, errno, ::strerror(errno)); + if(rv == -1) { + if(opts.verbose) { + fmt::print( + "truncate(path=\"{}\", length={}) = {}, errno: {} [{}]\n", + opts.path, opts.length, rv, errno, ::strerror(errno)); return; } } @@ -74,36 +70,21 @@ truncate_init(CLI::App& app) { // Create the option and subcommand objects auto opts = std::make_shared(); - auto* cmd = app.add_subcommand( - "truncate", - "Execute the truncate() system call"); + auto* cmd = app.add_subcommand("truncate", + "Execute the truncate() system call"); // Add options to cmd, binding them to opts - cmd->add_flag( - "-v,--verbose", - opts->verbose, - "Produce human writeable output" - ); - - cmd->add_option( - "path", - opts->path, - "Path to file" - ) - ->required() - ->type_name(""); - - cmd->add_option( - "length", - opts->length, - "Truncate to a size precisely length bytes" - ) - ->required() - ->type_name(""); - - cmd->callback([opts]() { - truncate_exec(*opts); - }); -} + cmd->add_flag("-v,--verbose", opts->verbose, + "Produce human writeable output"); + cmd->add_option("path", opts->path, "Path to file") + ->required() + ->type_name(""); + cmd->add_option("length", opts->length, + "Truncate to a size precisely length bytes") + ->required() + ->type_name(""); + + cmd->callback([opts]() { truncate_exec(*opts); }); +} diff --git a/tests/integration/harness/gkfs.io/util/file_compare.cpp b/tests/integration/harness/gkfs.io/util/file_compare.cpp index 4c1234fb76fc2b0d0fe477813b559f939cd1aca0..d983d55c69857ce4e865b0559af630502a989aa1 100644 --- a/tests/integration/harness/gkfs.io/util/file_compare.cpp +++ b/tests/integration/harness/gkfs.io/util/file_compare.cpp @@ -33,36 +33,32 @@ struct file_compare_options { std::string path_2{}; size_t count{}; - REFL_DECL_STRUCT(file_compare_options, - REFL_DECL_MEMBER(bool, verbose), + REFL_DECL_STRUCT(file_compare_options, REFL_DECL_MEMBER(bool, verbose), REFL_DECL_MEMBER(std::string, path_1), REFL_DECL_MEMBER(std::string, path_2), - REFL_DECL_MEMBER(size_t, count) - ); + REFL_DECL_MEMBER(size_t, count)); }; struct file_compare_output { int retval; int errnum; - REFL_DECL_STRUCT(file_compare_output, - REFL_DECL_MEMBER(int, retval), - REFL_DECL_MEMBER(int, errnum) - ); + REFL_DECL_STRUCT(file_compare_output, REFL_DECL_MEMBER(int, retval), + REFL_DECL_MEMBER(int, errnum)); }; void -to_json(json& record, - const file_compare_output& out) { +to_json(json& record, const file_compare_output& out) { record = serialize(out); } -int open_file(const std::string& path, bool verbose) { +int +open_file(const std::string& path, bool verbose) { auto fd = ::open(path.c_str(), O_RDONLY); - if (fd == -1) { - if (verbose) { - fmt::print("open(pathname=\"{}\") = {}, errno: {} [{}]\n", - path, fd, errno, ::strerror(errno)); + if(fd == -1) { + if(verbose) { + fmt::print("open(pathname=\"{}\") = {}, errno: {} [{}]\n", path, fd, + errno, ::strerror(errno)); return -1; } json out = file_compare_output{fd, errno}; @@ -72,15 +68,16 @@ int open_file(const std::string& path, bool verbose) { return fd; } -size_t read_file(io::buffer& buf, int fd, size_t count) { +size_t +read_file(io::buffer& buf, int fd, size_t count) { ssize_t rv{}; size_t total{}; do { rv = ::read(fd, buf.data(), count - total); total += rv; - } while (rv > 0 && total < count); + } while(rv > 0 && total < count); - if (rv < 0 && total != count) { + if(rv < 0 && total != count) { json out = file_compare_output{(int) rv, errno}; fmt::print("{}\n", out.dump(2)); return 0; @@ -93,29 +90,29 @@ file_compare_exec(const file_compare_options& opts) { // Open both files auto fd_1 = open_file(opts.path_1, opts.verbose); - if (fd_1 == -1) { + if(fd_1 == -1) { return; } auto fd_2 = open_file(opts.path_2, opts.verbose); - if (fd_2 == -1) { + if(fd_2 == -1) { return; } // read both files io::buffer buf_1(opts.count); auto rv = read_file(buf_1, fd_1, opts.count); - if (rv == 0) + if(rv == 0) return; io::buffer buf_2(opts.count); rv = read_file(buf_2, fd_2, opts.count); - if (rv == 0) + if(rv == 0) return; // memcmp both files to check if they're equal auto comp_rv = memcmp(buf_1.data(), buf_2.data(), opts.count); - if (comp_rv != 0) { - if (opts.verbose) { + if(comp_rv != 0) { + if(opts.verbose) { fmt::print("memcmp(path_1='{}', path_2='{}', count='{}') = '{}'\n", opts.path_1, opts.path_2, opts.count, comp_rv); return; @@ -131,42 +128,25 @@ file_compare_init(CLI::App& app) { // Create the option and subcommand objects auto opts = std::make_shared(); - auto* cmd = app.add_subcommand( - "file_compare", - "Execute the truncate() system call"); + auto* cmd = app.add_subcommand("file_compare", + "Execute the truncate() system call"); // Add options to cmd, binding them to opts - cmd->add_flag( - "-v,--verbose", - opts->verbose, - "Produce human writeable output" - ); - - cmd->add_option( - "path_1", - opts->path_1, - "Path to first file" - ) + cmd->add_flag("-v,--verbose", opts->verbose, + "Produce human writeable output"); + + cmd->add_option("path_1", opts->path_1, "Path to first file") ->required() ->type_name(""); - cmd->add_option( - "path_2", - opts->path_2, - "Path to second file" - ) + cmd->add_option("path_2", opts->path_2, "Path to second file") ->required() ->type_name(""); - cmd->add_option( - "count", - opts->count, - "How many bytes to compare of each file" - ) + cmd->add_option("count", opts->count, + "How many bytes to compare of each file") ->required() ->type_name(""); - cmd->callback([opts]() { - file_compare_exec(*opts); - }); + cmd->callback([opts]() { file_compare_exec(*opts); }); } \ No newline at end of file diff --git a/tests/integration/harness/gkfs.io/write.cpp b/tests/integration/harness/gkfs.io/write.cpp index fff2534140ef0ccd6ef0558bccd5b464d11a0560..081f8fea820ba324a703cd2fb8fa189c25446a4b 100644 --- a/tests/integration/harness/gkfs.io/write.cpp +++ b/tests/integration/harness/gkfs.io/write.cpp @@ -30,44 +30,41 @@ using json = nlohmann::json; struct write_options { - bool verbose; + bool verbose{}; std::string pathname; std::string data; ::size_t count; - REFL_DECL_STRUCT(write_options, - REFL_DECL_MEMBER(bool, verbose), - REFL_DECL_MEMBER(std::string, pathname), - REFL_DECL_MEMBER(std::string, data), - REFL_DECL_MEMBER(::size_t, count) - ); + REFL_DECL_STRUCT(write_options, REFL_DECL_MEMBER(bool, verbose), + REFL_DECL_MEMBER(std::string, pathname), + REFL_DECL_MEMBER(std::string, data), + REFL_DECL_MEMBER(::size_t, count)); }; struct write_output { ::ssize_t retval; int errnum; - REFL_DECL_STRUCT(write_output, - REFL_DECL_MEMBER(::size_t, retval), - REFL_DECL_MEMBER(int, errnum) - ); + REFL_DECL_STRUCT(write_output, REFL_DECL_MEMBER(::size_t, retval), + REFL_DECL_MEMBER(int, errnum)); }; void -to_json(json& record, - const write_output& out) { +to_json(json& record, const write_output& out) { record = serialize(out); } -void +void write_exec(const write_options& opts) { - int fd = ::open(opts.pathname.c_str(), O_WRONLY); + auto fd = ::open(opts.pathname.c_str(), O_WRONLY); if(fd == -1) { if(opts.verbose) { - fmt::print("open(pathname=\"{}\", buf=\"{}\" count={}) = {}, errno: {} [{}]\n", - opts.pathname, opts.data, opts.count, fd, errno, ::strerror(errno)); + fmt::print( + "open(pathname=\"{}\", buf=\"{}\" count={}) = {}, errno: {} [{}]\n", + opts.pathname, opts.data, opts.count, fd, errno, + ::strerror(errno)); return; } @@ -78,10 +75,10 @@ write_exec(const write_options& opts) { } io::buffer buf(opts.data); - int rv = ::write(fd, buf.data(), opts.count); + auto rv = ::write(fd, buf.data(), opts.count); if(opts.verbose) { - fmt::print("write(pathname=\"{}\", count={}) = {}, errno: {} [{}]\n", + fmt::print("write(pathname=\"{}\", count={}) = {}, errno: {} [{}]\n", opts.pathname, opts.count, rv, errno, ::strerror(errno)); return; } @@ -95,44 +92,23 @@ write_init(CLI::App& app) { // Create the option and subcommand objects auto opts = std::make_shared(); - auto* cmd = app.add_subcommand( - "write", - "Execute the write() system call"); + auto* cmd = app.add_subcommand("write", "Execute the write() system call"); // Add options to cmd, binding them to opts - cmd->add_flag( - "-v,--verbose", - opts->verbose, - "Produce human writeable output" - ); - - cmd->add_option( - "pathname", - opts->pathname, - "Directory name" - ) - ->required() - ->type_name(""); - - cmd->add_option( - "data", - opts->data, - "Data to write" - ) - ->required() - ->type_name(""); - - cmd->add_option( - "count", - opts->count, - "Number of bytes to write" - ) - ->required() - ->type_name(""); - - cmd->callback([opts]() { - write_exec(*opts); - }); -} + cmd->add_flag("-v,--verbose", opts->verbose, + "Produce human writeable output"); + + cmd->add_option("pathname", opts->pathname, "Directory name") + ->required() + ->type_name(""); + cmd->add_option("data", opts->data, "Data to write") + ->required() + ->type_name(""); + cmd->add_option("count", opts->count, "Number of bytes to write") + ->required() + ->type_name(""); + + cmd->callback([opts]() { write_exec(*opts); }); +} diff --git a/tests/integration/harness/gkfs.io/write_random.cpp b/tests/integration/harness/gkfs.io/write_random.cpp index bafc14d3ec1258ca16000c503a2f62ebbfb21151..5df7001b97bac8921d812d081502849dafa30193 100644 --- a/tests/integration/harness/gkfs.io/write_random.cpp +++ b/tests/integration/harness/gkfs.io/write_random.cpp @@ -40,25 +40,21 @@ struct write_random_options { std::string pathname{}; ::size_t count{}; - REFL_DECL_STRUCT(write_random_options, - REFL_DECL_MEMBER(bool, verbose), + REFL_DECL_STRUCT(write_random_options, REFL_DECL_MEMBER(bool, verbose), REFL_DECL_MEMBER(std::string, pathname), - REFL_DECL_MEMBER(::size_t, count) - ); + REFL_DECL_MEMBER(::size_t, count)); }; struct write_random_output { ::ssize_t retval; int errnum; - REFL_DECL_STRUCT(write_random_output, - REFL_DECL_MEMBER(::size_t, retval), - REFL_DECL_MEMBER(int, errnum) - ); + REFL_DECL_STRUCT(write_random_output, REFL_DECL_MEMBER(::size_t, retval), + REFL_DECL_MEMBER(int, errnum)); }; -void to_json(json& record, - const write_random_output& out) { +void +to_json(json& record, const write_random_output& out) { record = serialize(out); } @@ -66,12 +62,13 @@ void to_json(json& record, * Writes `count` random bytes to file * @param opts */ -void write_random_exec(const write_random_options& opts) { +void +write_random_exec(const write_random_options& opts) { - int fd = ::open(opts.pathname.c_str(), O_WRONLY); + auto fd = ::open(opts.pathname.c_str(), O_WRONLY); - if (fd == -1) { - if (opts.verbose) { + if(fd == -1) { + if(opts.verbose) { fmt::print("open(pathname=\"{}\", count={}) = {}, errno: {} [{}]\n", opts.pathname, opts.count, fd, errno, ::strerror(errno)); return; @@ -82,7 +79,9 @@ void write_random_exec(const write_random_options& opts) { return; } // random number generator with seed - std::independent_bits_engine engine{seed}; + std::independent_bits_engine + engine{seed}; // create buffer for opts.count std::vector data(opts.count); std::generate(begin(data), end(data), std::ref(engine)); @@ -91,7 +90,7 @@ void write_random_exec(const write_random_options& opts) { int rv = ::write(fd, buf.data(), opts.count); - if (opts.verbose) { + if(opts.verbose) { fmt::print("write(pathname=\"{}\", count={}) = {}, errno: {} [{}]\n", opts.pathname, opts.count, rv, errno, ::strerror(errno)); return; @@ -101,38 +100,25 @@ void write_random_exec(const write_random_options& opts) { fmt::print("{}\n", out.dump(2)); } -void write_random_init(CLI::App& app) { +void +write_random_init(CLI::App& app) { // Create the option and subcommand objects auto opts = std::make_shared(); - auto* cmd = app.add_subcommand( - "write_random", - "Execute the write() system call "); + auto* cmd = app.add_subcommand("write_random", + "Execute the write() system call "); // Add options to cmd, binding them to opts - cmd->add_flag( - "-v,--verbose", - opts->verbose, - "Produce human writeable output" - ); - - cmd->add_option( - "pathname", - opts->pathname, - "File name" - ) + cmd->add_flag("-v,--verbose", opts->verbose, + "Produce human writeable output"); + + cmd->add_option("pathname", opts->pathname, "File name") ->required() ->type_name(""); - cmd->add_option( - "count", - opts->count, - "Number of random bytes to write" - ) + cmd->add_option("count", opts->count, "Number of random bytes to write") ->required() ->type_name(""); - cmd->callback([opts]() { - write_random_exec(*opts); - }); -} \ No newline at end of file + cmd->callback([opts]() { write_random_exec(*opts); }); +} diff --git a/tests/integration/harness/gkfs.io/write_validate.cpp b/tests/integration/harness/gkfs.io/write_validate.cpp index 54e9d10bab49ff14515bd8921e605da4f51e722f..6783f41c311340339780cdf1bc1eca6264e9b864 100644 --- a/tests/integration/harness/gkfs.io/write_validate.cpp +++ b/tests/integration/harness/gkfs.io/write_validate.cpp @@ -30,41 +30,37 @@ using json = nlohmann::json; struct write_validate_options { - bool verbose; + bool verbose{}; std::string pathname; ::size_t count; - REFL_DECL_STRUCT(write_validate_options, - REFL_DECL_MEMBER(bool, verbose), - REFL_DECL_MEMBER(std::string, pathname), - REFL_DECL_MEMBER(::size_t, count) - ); + REFL_DECL_STRUCT(write_validate_options, REFL_DECL_MEMBER(bool, verbose), + REFL_DECL_MEMBER(std::string, pathname), + REFL_DECL_MEMBER(::size_t, count)); }; struct write_validate_output { int retval; int errnum; - REFL_DECL_STRUCT(write_validate_output, - REFL_DECL_MEMBER(int, retval), - REFL_DECL_MEMBER(int, errnum) - ); + REFL_DECL_STRUCT(write_validate_output, REFL_DECL_MEMBER(int, retval), + REFL_DECL_MEMBER(int, errnum)); }; void -to_json(json& record, - const write_validate_output& out) { +to_json(json& record, const write_validate_output& out) { record = serialize(out); } -void +void write_validate_exec(const write_validate_options& opts) { int fd = ::open(opts.pathname.c_str(), O_WRONLY); if(fd == -1) { if(opts.verbose) { - fmt::print("write_validate(pathname=\"{}\", count={}) = {}, errno: {} [{}]\n", + fmt::print( + "write_validate(pathname=\"{}\", count={}) = {}, errno: {} [{}]\n", opts.pathname, opts.count, fd, errno, ::strerror(errno)); return; } @@ -77,9 +73,8 @@ write_validate_exec(const write_validate_options& opts) { std::string data = ""; - for (::size_t i = 0 ; i < opts.count; i++) - { - data += char((i%10)+'0'); + for(::size_t i = 0; i < opts.count; i++) { + data += char((i % 10) + '0'); } io::buffer buf(data); @@ -87,13 +82,14 @@ write_validate_exec(const write_validate_options& opts) { auto rv = ::write(fd, buf.data(), opts.count); if(opts.verbose) { - fmt::print("write_validate(pathname=\"{}\", count={}) = {}, errno: {} [{}]\n", - opts.pathname, opts.count, rv, errno, ::strerror(errno)); + fmt::print( + "write_validate(pathname=\"{}\", count={}) = {}, errno: {} [{}]\n", + opts.pathname, opts.count, rv, errno, ::strerror(errno)); return; } - if (rv < 0 or ::size_t(rv) != opts.count) { - json out = write_validate_output{(int)rv, errno}; + if(rv < 0 or ::size_t(rv) != opts.count) { + json out = write_validate_output{(int) rv, errno}; fmt::print("{}\n", out.dump(2)); return; } @@ -102,31 +98,29 @@ write_validate_exec(const write_validate_options& opts) { io::buffer bufread(opts.count); size_t total = 0; - do{ - rv = ::read(fd, bufread.data(), opts.count-total); + do { + rv = ::read(fd, bufread.data(), opts.count - total); total += rv; - } while (rv > 0 and total < opts.count); + } while(rv > 0 and total < opts.count); - if (rv < 0 and total != opts.count) { - json out = write_validate_output{(int)rv, errno}; + if(rv < 0 and total != opts.count) { + json out = write_validate_output{(int) rv, errno}; fmt::print("{}\n", out.dump(2)); return; } - if ( memcmp(buf.data(),bufread.data(),opts.count) ) { + if(memcmp(buf.data(), bufread.data(), opts.count)) { rv = 1; errno = 0; - json out = write_validate_output{(int)rv, errno}; + json out = write_validate_output{(int) rv, errno}; fmt::print("{}\n", out.dump(2)); return; - } - else { + } else { rv = 2; errno = EINVAL; - json out = write_validate_output{(int)-1, errno}; + json out = write_validate_output{(int) -1, errno}; fmt::print("{}\n", out.dump(2)); } - } void @@ -135,35 +129,20 @@ write_validate_init(CLI::App& app) { // Create the option and subcommand objects auto opts = std::make_shared(); auto* cmd = app.add_subcommand( - "write_validate", + "write_validate", "Execute the write()-read() system call and compare the content of the buffer"); // Add options to cmd, binding them to opts - cmd->add_flag( - "-v,--verbose", - opts->verbose, - "Produce human writeable output" - ); - - cmd->add_option( - "pathname", - opts->pathname, - "Directory name" - ) - ->required() - ->type_name(""); - - cmd->add_option( - "count", - opts->count, - "Number of bytes to test" - ) - ->required() - ->type_name(""); - - cmd->callback([opts]() { - write_validate_exec(*opts); - }); -} + cmd->add_flag("-v,--verbose", opts->verbose, + "Produce human writeable output"); + + cmd->add_option("pathname", opts->pathname, "Directory name") + ->required() + ->type_name(""); + cmd->add_option("count", opts->count, "Number of bytes to test") + ->required() + ->type_name(""); + cmd->callback([opts]() { write_validate_exec(*opts); }); +} diff --git a/tests/integration/harness/gkfs.io/writev.cpp b/tests/integration/harness/gkfs.io/writev.cpp index d57507f305077d716e88bf705d6a94f8dc4be7b7..475b3cba1f32661b370036f0e809d50e428790ce 100644 --- a/tests/integration/harness/gkfs.io/writev.cpp +++ b/tests/integration/harness/gkfs.io/writev.cpp @@ -31,45 +31,42 @@ using json = nlohmann::json; struct writev_options { - bool verbose; + bool verbose{}; std::string pathname; std::string data_0, data_1; ::size_t count; - REFL_DECL_STRUCT(writev_options, - REFL_DECL_MEMBER(bool, verbose), - REFL_DECL_MEMBER(std::string, pathname), - REFL_DECL_MEMBER(std::string, data_0), - REFL_DECL_MEMBER(std::string, data_1), - REFL_DECL_MEMBER(::size_t, count) - ); + REFL_DECL_STRUCT(writev_options, REFL_DECL_MEMBER(bool, verbose), + REFL_DECL_MEMBER(std::string, pathname), + REFL_DECL_MEMBER(std::string, data_0), + REFL_DECL_MEMBER(std::string, data_1), + REFL_DECL_MEMBER(::size_t, count)); }; struct writev_output { ::ssize_t retval; int errnum; - REFL_DECL_STRUCT(writev_output, - REFL_DECL_MEMBER(::size_t, retval), - REFL_DECL_MEMBER(int, errnum) - ); + REFL_DECL_STRUCT(writev_output, REFL_DECL_MEMBER(::size_t, retval), + REFL_DECL_MEMBER(int, errnum)); }; void -to_json(json& record, - const writev_output& out) { +to_json(json& record, const writev_output& out) { record = serialize(out); } -void +void writev_exec(const writev_options& opts) { - int fd = ::open(opts.pathname.c_str(), O_WRONLY); + auto fd = ::open(opts.pathname.c_str(), O_WRONLY); if(fd == -1) { if(opts.verbose) { - fmt::print("writev(pathname=\"{}\", buf_0=\"{}\" buf_1=\"{}\" count={}) = {}, errno: {} [{}]\n", - opts.pathname, opts.data_0, opts.data_1, opts.count, fd, errno, ::strerror(errno)); + fmt::print( + "writev(pathname=\"{}\", buf_0=\"{}\" buf_1=\"{}\" count={}) = {}, errno: {} [{}]\n", + opts.pathname, opts.data_0, opts.data_1, opts.count, fd, + errno, ::strerror(errno)); return; } @@ -81,7 +78,7 @@ writev_exec(const writev_options& opts) { io::buffer buf_0(opts.data_0); io::buffer buf_1(opts.data_1); - + struct iovec iov[2]; iov[0].iov_base = buf_0.data(); @@ -90,10 +87,10 @@ writev_exec(const writev_options& opts) { iov[0].iov_len = buf_0.size(); iov[1].iov_len = buf_1.size(); - int rv = ::writev(fd, iov, opts.count); + auto rv = ::writev(fd, iov, opts.count); if(opts.verbose) { - fmt::print("writev(pathname=\"{}\", count={}) = {}, errno: {} [{}]\n", + fmt::print("writev(pathname=\"{}\", count={}) = {}, errno: {} [{}]\n", opts.pathname, opts.count, rv, errno, ::strerror(errno)); return; } @@ -107,52 +104,28 @@ writev_init(CLI::App& app) { // Create the option and subcommand objects auto opts = std::make_shared(); - auto* cmd = app.add_subcommand( - "writev", - "Execute the writev() system call"); + auto* cmd = + app.add_subcommand("writev", "Execute the writev() system call"); // Add options to cmd, binding them to opts - cmd->add_flag( - "-v,--verbose", - opts->verbose, - "Produce human writeable output" - ); - - cmd->add_option( - "pathname", - opts->pathname, - "Directory name" - ) - ->required() - ->type_name(""); - - cmd->add_option( - "data_0", - opts->data_0, - "Data 0 to write" - ) - ->required() - ->type_name(""); - - cmd->add_option( - "data_1", - opts->data_1, - "Data 1 to write" - ) - ->required() - ->type_name(""); - - cmd->add_option( - "count", - opts->count, - "Number of bytes to write" - ) - ->required() - ->type_name(""); - - cmd->callback([opts]() { - writev_exec(*opts); - }); -} + cmd->add_flag("-v,--verbose", opts->verbose, + "Produce human writeable output"); + + cmd->add_option("pathname", opts->pathname, "Directory name") + ->required() + ->type_name(""); + cmd->add_option("data_0", opts->data_0, "Data 0 to write") + ->required() + ->type_name(""); + cmd->add_option("data_1", opts->data_1, "Data 1 to write") + ->required() + ->type_name(""); + + cmd->add_option("count", opts->count, "Number of bytes to write") + ->required() + ->type_name(""); + + cmd->callback([opts]() { writev_exec(*opts); }); +} diff --git a/tests/integration/harness/io.py b/tests/integration/harness/io.py index a9fca62c52be3877a9ed0e770c5f086d73561ee4..992e55e3db894aef9d6283d7537b7e49278eaedc 100644 --- a/tests/integration/harness/io.py +++ b/tests/integration/harness/io.py @@ -109,7 +109,7 @@ class StructStatxSchema(Schema): return namedtuple('StructStatx', ['stx_mask', 'stx_blksize', 'stx_attributes', 'stx_nlink', 'stx_uid', 'stx_gid', 'stx_mode', 'stx_ino', 'stx_size', 'stx_blocks', 'stx_attributes_mask', - 'stx_atime', 'stx_btime', 'stx_ctime', 'stx_mtime', 'stx_rdev_major', + 'stx_atime', 'stx_btime', 'stx_ctime', 'stx_mtime', 'stx_rdev_major', 'stx_rdev_minor', 'stx_dev_major', 'stx_dev_minor'])(**data) class DirentStruct(Schema): @@ -211,7 +211,7 @@ class ReaddirOutputSchema(Schema): return namedtuple('ReaddirReturn', ['dirents', 'errno'])(**data) class RmdirOutputSchema(Schema): - """Schema to deserialize the results of an opendir() execution""" + """Schema to deserialize the results of an rmdir() execution""" retval = fields.Integer(required=True) errno = Errno(data_key='errnum', required=True) @@ -325,6 +325,40 @@ class TruncateOutputSchema(Schema): def make_object(self, data, **kwargs): return namedtuple('TruncateReturn', ['retval', 'errno'])(**data) +class ChdirOutputSchema(Schema): + """Schema to deserialize the results of an chdir() execution""" + + retval = fields.Integer(required=True) + errno = Errno(data_key='errnum', required=True) + + @post_load + def make_object(self, data, **kwargs): + return namedtuple('ChdirReturn', ['retval', 'errno'])(**data) + + +class GetcwdvalidateOutputSchema(Schema): + """Schema to deserialize the results of an GetCwd execution""" + + retval = fields.Integer(required=True) + path = fields.String(required=True) + errno = Errno(data_key='errnum', required=True) + + @post_load + def make_object(self, data, **kwargs): + return namedtuple('GetcwdvalidateReturn', ['retval', 'path', 'errno'])(**data) + + + +class SymlinkOutputSchema(Schema): + """Schema to deserialize the results of an symlink execution""" + + retval = fields.Integer(required=True) + errno = Errno(data_key='errnum', required=True) + + @post_load + def make_object(self, data, **kwargs): + return namedtuple('SymlinkReturn', ['retval', 'errno'])(**data) + # UTIL class FileCompareOutputSchema(Schema): @@ -336,6 +370,8 @@ class FileCompareOutputSchema(Schema): def make_object(self, data, **kwargs): return namedtuple('FileCompareReturn', ['retval', 'errno'])(**data) + + class IOParser: OutputSchemas = { @@ -360,6 +396,9 @@ class IOParser: 'truncate': TruncateOutputSchema(), # UTIL 'file_compare': FileCompareOutputSchema(), + 'chdir' : ChdirOutputSchema(), + 'getcwd_validate' : GetcwdvalidateOutputSchema(), + 'symlink' : SymlinkOutputSchema(), } def parse(self, command, output):