Loading .gitlab-ci.yml +1 −1 Original line number Diff line number Diff line Loading @@ -131,7 +131,7 @@ gkfs:integration: needs: ['gkfs'] parallel: matrix: - SUBTEST: [ data, directories, operations, position, shell, status, coverage ] - SUBTEST: [ data, status, coverage, directories, operations, position, shell ] script: ## run tests Loading tests/integration/coverage/test_error_operations.py +46 −2 Original line number Diff line number Diff line Loading @@ -76,8 +76,52 @@ def test_open_error(gkfs_daemon, gkfs_client): # Open unexistent file ret = ret = gkfs_client.open(file3, os.O_WRONLY) ret = gkfs_client.open(file3, os.O_WRONLY) assert ret.retval == -1 assert ret.errno == errno.ENOENT def test_access_error(gkfs_daemon, gkfs_client): file = gkfs_daemon.mountdir / "file" file2 = gkfs_daemon.mountdir / "file2" ret = gkfs_client.open(file, os.O_CREAT | os.O_WRONLY) assert ret.retval == 10000 # Access, flags are not being used ret = gkfs_client.access(file2, os.R_OK) assert ret.retval == -1 assert ret.errno == errno.ENOENT ret = gkfs_client.access(file, os.R_OK) assert ret.retval != -1 def test_stat_error(gkfs_daemon, gkfs_client): # Stat non existing file file = gkfs_daemon.mountdir / "file" ret = gkfs_client.stat(file) assert ret.retval == -1 assert ret.errno == errno.ENOENT # test statx on existing file ret = gkfs_client.statx(0, file, 0, 0) assert ret.retval == -1 assert ret.errno == errno.ENOENT def test_statfs(gkfs_daemon, gkfs_client): # Statfs check most of the outputs ret = gkfs_client.statfs(gkfs_daemon.mountdir) assert ret.retval == 0 assert ret.statfsbuf.f_type == 0 assert ret.statfsbuf.f_bsize != 0 assert ret.statfsbuf.f_blocks != 0 assert ret.statfsbuf.f_bfree != 0 assert ret.statfsbuf.f_bavail != 0 assert ret.statfsbuf.f_files == 0 assert ret.statfsbuf.f_ffree == 0 No newline at end of file tests/integration/harness/CMakeLists.txt +2 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,8 @@ add_executable(gkfs.io gkfs.io/symlink.cpp gkfs.io/directory_validate.cpp gkfs.io/unlink.cpp gkfs.io/access.cpp gkfs.io/statfs.cpp ) include(FetchContent) Loading tests/unit/test_example_00.cpp→tests/integration/harness/gkfs.io/access.cpp +105 −0 Original line number Diff line number Diff line Loading @@ -26,20 +26,80 @@ SPDX-License-Identifier: GPL-3.0-or-later */ #include <catch2/catch.hpp> /* C++ includes */ #include <CLI11/CLI11.hpp> #include <nlohmann/json.hpp> #include <memory> #include <fmt/format.h> #include <reflection.hpp> #include <serialize.hpp> unsigned int Factorial( unsigned int number ) { return number <= 1 ? number : Factorial(number-1)*number; /* C includes */ #include <sys/types.h> #include <unistd.h> using json = nlohmann::json; struct access_options { bool verbose{}; std::string path{}; int mask{}; REFL_DECL_STRUCT(access_options, REFL_DECL_MEMBER(bool, verbose), REFL_DECL_MEMBER(std::string, path), REFL_DECL_MEMBER(int, mask)); }; struct access_output { int retval; int errnum; REFL_DECL_STRUCT(access_output, REFL_DECL_MEMBER(int, retval), REFL_DECL_MEMBER(int, errnum)); }; void to_json(json& record, const access_output& out) { record = serialize(out); } TEST_CASE( "Factorials are computed", "[factorial]" ) { REQUIRE( Factorial(1) == 1 ); REQUIRE( Factorial(2) == 2 ); REQUIRE( Factorial(3) == 6 ); REQUIRE( Factorial(10) == 3628800 ); void access_exec(const access_options& opts) { auto rv = ::access(opts.path.c_str(), opts.mask); if(rv == -1) { if(opts.verbose) { fmt::print( "access(path=\"{}\", mask={}) = {}, errno: {} [{}]\n", opts.path, opts.mask, rv, errno, ::strerror(errno)); return; } } TEST_CASE( "Two and Two is Four", "[2+2=4]" ) { REQUIRE( 2+2 == 4 ); json out = access_output{rv, errno}; fmt::print("{}\n", out.dump(2)); } void access_init(CLI::App& app) { // Create the option and subcommand objects auto opts = std::make_shared<access_options>(); auto* cmd = app.add_subcommand("access", "Execute the access() 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("mask", opts->mask, "Mask to apply to the access check") ->required() ->type_name(""); cmd->callback([opts]() { access_exec(*opts); }); } tests/integration/harness/gkfs.io/commands.hpp +6 −0 Original line number Diff line number Diff line Loading @@ -96,6 +96,12 @@ write_random_init(CLI::App& app); void truncate_init(CLI::App& app); void access_init(CLI::App& app); void statfs_init(CLI::App& app); // UTIL void file_compare_init(CLI::App& app); Loading Loading
.gitlab-ci.yml +1 −1 Original line number Diff line number Diff line Loading @@ -131,7 +131,7 @@ gkfs:integration: needs: ['gkfs'] parallel: matrix: - SUBTEST: [ data, directories, operations, position, shell, status, coverage ] - SUBTEST: [ data, status, coverage, directories, operations, position, shell ] script: ## run tests Loading
tests/integration/coverage/test_error_operations.py +46 −2 Original line number Diff line number Diff line Loading @@ -76,8 +76,52 @@ def test_open_error(gkfs_daemon, gkfs_client): # Open unexistent file ret = ret = gkfs_client.open(file3, os.O_WRONLY) ret = gkfs_client.open(file3, os.O_WRONLY) assert ret.retval == -1 assert ret.errno == errno.ENOENT def test_access_error(gkfs_daemon, gkfs_client): file = gkfs_daemon.mountdir / "file" file2 = gkfs_daemon.mountdir / "file2" ret = gkfs_client.open(file, os.O_CREAT | os.O_WRONLY) assert ret.retval == 10000 # Access, flags are not being used ret = gkfs_client.access(file2, os.R_OK) assert ret.retval == -1 assert ret.errno == errno.ENOENT ret = gkfs_client.access(file, os.R_OK) assert ret.retval != -1 def test_stat_error(gkfs_daemon, gkfs_client): # Stat non existing file file = gkfs_daemon.mountdir / "file" ret = gkfs_client.stat(file) assert ret.retval == -1 assert ret.errno == errno.ENOENT # test statx on existing file ret = gkfs_client.statx(0, file, 0, 0) assert ret.retval == -1 assert ret.errno == errno.ENOENT def test_statfs(gkfs_daemon, gkfs_client): # Statfs check most of the outputs ret = gkfs_client.statfs(gkfs_daemon.mountdir) assert ret.retval == 0 assert ret.statfsbuf.f_type == 0 assert ret.statfsbuf.f_bsize != 0 assert ret.statfsbuf.f_blocks != 0 assert ret.statfsbuf.f_bfree != 0 assert ret.statfsbuf.f_bavail != 0 assert ret.statfsbuf.f_files == 0 assert ret.statfsbuf.f_ffree == 0 No newline at end of file
tests/integration/harness/CMakeLists.txt +2 −0 Original line number Diff line number Diff line Loading @@ -63,6 +63,8 @@ add_executable(gkfs.io gkfs.io/symlink.cpp gkfs.io/directory_validate.cpp gkfs.io/unlink.cpp gkfs.io/access.cpp gkfs.io/statfs.cpp ) include(FetchContent) Loading
tests/unit/test_example_00.cpp→tests/integration/harness/gkfs.io/access.cpp +105 −0 Original line number Diff line number Diff line Loading @@ -26,20 +26,80 @@ SPDX-License-Identifier: GPL-3.0-or-later */ #include <catch2/catch.hpp> /* C++ includes */ #include <CLI11/CLI11.hpp> #include <nlohmann/json.hpp> #include <memory> #include <fmt/format.h> #include <reflection.hpp> #include <serialize.hpp> unsigned int Factorial( unsigned int number ) { return number <= 1 ? number : Factorial(number-1)*number; /* C includes */ #include <sys/types.h> #include <unistd.h> using json = nlohmann::json; struct access_options { bool verbose{}; std::string path{}; int mask{}; REFL_DECL_STRUCT(access_options, REFL_DECL_MEMBER(bool, verbose), REFL_DECL_MEMBER(std::string, path), REFL_DECL_MEMBER(int, mask)); }; struct access_output { int retval; int errnum; REFL_DECL_STRUCT(access_output, REFL_DECL_MEMBER(int, retval), REFL_DECL_MEMBER(int, errnum)); }; void to_json(json& record, const access_output& out) { record = serialize(out); } TEST_CASE( "Factorials are computed", "[factorial]" ) { REQUIRE( Factorial(1) == 1 ); REQUIRE( Factorial(2) == 2 ); REQUIRE( Factorial(3) == 6 ); REQUIRE( Factorial(10) == 3628800 ); void access_exec(const access_options& opts) { auto rv = ::access(opts.path.c_str(), opts.mask); if(rv == -1) { if(opts.verbose) { fmt::print( "access(path=\"{}\", mask={}) = {}, errno: {} [{}]\n", opts.path, opts.mask, rv, errno, ::strerror(errno)); return; } } TEST_CASE( "Two and Two is Four", "[2+2=4]" ) { REQUIRE( 2+2 == 4 ); json out = access_output{rv, errno}; fmt::print("{}\n", out.dump(2)); } void access_init(CLI::App& app) { // Create the option and subcommand objects auto opts = std::make_shared<access_options>(); auto* cmd = app.add_subcommand("access", "Execute the access() 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("mask", opts->mask, "Mask to apply to the access check") ->required() ->type_name(""); cmd->callback([opts]() { access_exec(*opts); }); }
tests/integration/harness/gkfs.io/commands.hpp +6 −0 Original line number Diff line number Diff line Loading @@ -96,6 +96,12 @@ write_random_init(CLI::App& app); void truncate_init(CLI::App& app); void access_init(CLI::App& app); void statfs_init(CLI::App& app); // UTIL void file_compare_init(CLI::App& app); Loading