This patch moves nfs testing logic from ./scripts/test.py into ./modules/nfs-tests/test.py.
It also refreshes nfs-tests to pull and build UNFS3 (NFS in user space) from a new repo. Eventually it adds new 'check' target that builds the test image (nfs,nfs-tests) and runs test.py against it. Signed-off-by: Waldemar Kozaczuk <[email protected]> --- modules/nfs-tests/.gitignore | 4 ++ modules/nfs-tests/Makefile | 32 +++++++++---- modules/nfs-tests/test.py | 90 ++++++++++++++++++++++++++++++++++++ modules/nfs-tests/tst-nfs.cc | 64 ++++++++++++++----------- scripts/test.py | 62 ++----------------------- 5 files changed, 157 insertions(+), 95 deletions(-) create mode 100644 modules/nfs-tests/.gitignore create mode 100755 modules/nfs-tests/test.py diff --git a/modules/nfs-tests/.gitignore b/modules/nfs-tests/.gitignore new file mode 100644 index 00000000..a2666565 --- /dev/null +++ b/modules/nfs-tests/.gitignore @@ -0,0 +1,4 @@ +*.so +*.d +unfsd.bin +upstream diff --git a/modules/nfs-tests/Makefile b/modules/nfs-tests/Makefile index 852df8bd..86379e81 100644 --- a/modules/nfs-tests/Makefile +++ b/modules/nfs-tests/Makefile @@ -1,17 +1,18 @@ quiet = $(if $V, $1, @echo " $2"; $1) -UNFS_URL="https://github.com/benoit-canet/unfsd.git" +UNFS_URL="https://github.com/unfs3/unfs3.git" autodepend = -MD -MT $@ -MP -src := $(OSV_BASE) -out := $(OSV_BUILD_PATH) +src = $(shell readlink -f ../..) arch := $(ARCH) -INCLUDES = -I$(src)/arch/$(ARCH) -I$(src) -I$(src)/include \ - -I$(src)/arch/common -isystem $(src)/include/glibc-compat \ - -isystem $(src)/include/api -isystem $(src)/include/api/$(ARCH) \ - -isystem $(out)/gen/include +INCLUDES = -I../../include +INCLUDES += -I../../arch/$(ARCH) -I../.. -I../../build/$(mode)/gen/include +INCLUDES += -isystem ../../include/glibc-compat +INCLUDES += $(shell $(CXX) -E -xc++ - -v </dev/null 2>&1 | awk '/^End/ {exit} /^ .*c\+\+/ {print "-isystem" $$0}') +INCLUDES += -isystem ../../include/api -isystem ../../include/api/$(ARCH) -isystem ../../build/$(mode)/gen/include +INCLUDES += -isystem ../../bsd/sys -isystem ../../bsd/ -isystem ../../bsd/$(ARCH) CORE = $(autodepend) $(INCLUDES) -g -O2 -fPIC COMMON = $(CORE) -DBOOST_TEST_DYN_LINK \ @@ -24,14 +25,25 @@ CFLAGS = -std=gnu99 $(COMMON) module: unfsd.bin tst-nfs fsx-linux unfsd.bin: - $(call quiet, git clone $(UNFS_URL)) && \ - $(call quiet, cd unfsd) && \ + $(call quiet, mkdir -p upstream) && \ + $(call quiet, git clone $(UNFS_URL) upstream/unfs3) && \ + $(call quiet, cd upstream/unfs3) && \ + $(call quiet, ./bootstrap) && \ $(call quiet, ./configure) && \ $(call quiet, make) - $(call quiet, cp unfsd/unfsd unfsd.bin) + $(call quiet, cp upstream/unfs3/unfsd unfsd.bin) tst-nfs: $(call quiet, $(CXX) $(CXXFLAGS) -shared -o tst-nfs.so tst-nfs.cc, LINK $@) fsx-linux: $(call quiet, $(CC) $(CORE) -shared -o fsx-linux.so fsx-linux.c, LINK $@) + +check: + cd $(src) && \ + make image=nfs,nfs-tests && \ + PYTHONPATH=$(src)/scripts modules/nfs-tests/test.py + +clean: + $(call quiet, rm -rf upstream, RM upstream) + $(call quiet, rm -f *.so unfsd.bin *.d, RM *.so) diff --git a/modules/nfs-tests/test.py b/modules/nfs-tests/test.py new file mode 100755 index 00000000..b4797bf6 --- /dev/null +++ b/modules/nfs-tests/test.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python3 + +import time +import tempfile +import atexit +from tests.testing import * + +def make_export_and_conf(): + export_dir = tempfile.mkdtemp(prefix='share') + os.chmod(export_dir, 0o777) + (conf_fd, conf_path) = tempfile.mkstemp(prefix='export') + conf = os.fdopen(conf_fd, "w") + conf.write("%s 127.0.0.1(insecure,rw)\n" % export_dir) + conf.flush() + conf.close() + return (conf_path, export_dir) + +proc = None +conf_path = None +export_dir = None + +def kill_unfsd(): + global proc, conf_path, export_dir + proc.kill() + proc.wait() + if conf_path and os.path.exists(conf_path): + os.unlink(conf_path) + if export_dir and os.path.exists(export_dir): + import shutil + shutil.rmtree(export_dir, ignore_errors=True) + +dirname = os.path.dirname(os.path.abspath(__file__)) +UNFSD = dirname + "/unfsd.bin" + +def run_test(): + global proc, conf_path, export_dir + start = time.time() + + if not os.path.exists(UNFSD): + print("Please do:\n\tmake nfs-server") + sys.exit(1) + + (conf_path, export_dir) = make_export_and_conf() + + ret = subprocess.call(['rpcinfo']) + if ret != 0: + print('Please install rpcbind!') + exit(-1) + + proc = subprocess.Popen([os.path.join(os.getcwd(), UNFSD), + "-t", + "-d", + "-s", + "-l", "127.0.0.1", + "-e", conf_path ], + stdin = sys.stdin, + stdout = subprocess.PIPE, + stderr = sys.stderr, + shell = False) + atexit.register(kill_unfsd) + test = SingleCommandTest('nfs-test', + "/tst-nfs.so --server 192.168.122.1 --share %s" % + export_dir) + + line = proc.stdout.readline().decode() + while line: + print(line) + if "/tmp" in line: + break + line = proc.stdout.readline().decode() + + sys.stdout.write("NFS Test \n") + sys.stdout.write("Shared directory: [%s]\n" % export_dir) + sys.stdout.flush() + + try: + test.run() + except: + sys.stdout.write("NFS Test FAILED\n") + sys.stdout.flush() + raise + end = time.time() + + duration = end - start + sys.stdout.write("OK (%.3f s)\n" % duration) + sys.stdout.flush() + kill_unfsd() + +set_verbose_output(True) +run_test() diff --git a/modules/nfs-tests/tst-nfs.cc b/modules/nfs-tests/tst-nfs.cc index dbc0026b..f41c5f77 100644 --- a/modules/nfs-tests/tst-nfs.cc +++ b/modules/nfs-tests/tst-nfs.cc @@ -10,13 +10,11 @@ #include <fstream> #include <string> #include <thread> - -#include <boost/program_options.hpp> +#include <set> #include <osv/app.hh> #include <osv/run.hh> - -namespace po = boost::program_options; +#include <osv/options.hh> void assert_mount_error(int ret) { @@ -121,7 +119,7 @@ static void test_rename(std::string mount_point, std::string src, static void test_truncate(std::string mount_point, std::string path) { std::string full_path = mount_point + "/" + path; - int fd = creat(full_path.c_str(), 0500); + int fd = creat(full_path.c_str(), 0700); struct stat st; assert(fd != -1); @@ -305,37 +303,51 @@ void test_trunc(std::string mount_point, std::string path) assert(0 == fclose(ff)); } +static void usage() +{ + std::cout << "Allowed options:\n"; + std::cout << " --help produce help message\n"; + std::cout << " --server arg set server ip\n"; + std::cout << " --share arg set remote share\n\n"; +} + +static void handle_parse_error(const std::string &message) +{ + std::cout << message << std::endl; + usage(); + exit(1); +} + int main(int argc, char **argv) { - po::options_description desc("Allowed options"); - desc.add_options() - ("help", "produce help message") - ("server", po::value<std::string>(), "set server ip") - ("share", po::value<std::string>(), "set remote share") - ; - - po::variables_map vm; - po::store(po::parse_command_line(argc, argv, desc), vm); - po::notify(vm); - - if (vm.count("help")) { - std::cout << desc << std::endl; + auto options_values = options::parse_options_values(argc - 1, argv + 1, handle_parse_error); + + if (options::extract_option_flag(options_values, "help", handle_parse_error)) { + usage(); return 1; } - std::string server; - if (vm.count("server")) { - server = vm["server"].as<std::string>(); + std::string server, share; + if (options::option_value_exists(options_values, "server")) { + server = options::extract_option_value(options_values, "server"); } else { - std::cout << desc << std::endl; + usage(); return 1; } - std::string share; - if (vm.count("share")) { - share = vm["share"].as<std::string>(); + if (options::option_value_exists(options_values, "share")) { + share = options::extract_option_value(options_values, "share"); } else { - std::cout << desc << std::endl; + usage(); + return 1; + } + + if (!options_values.empty()) { + for (auto other_option : options_values) { + std::cout << "Unrecognized option: " << other_option.first << std::endl; + } + + usage(); return 1; } diff --git a/scripts/test.py b/scripts/test.py index 1dea288a..0cf787fd 100755 --- a/scripts/test.py +++ b/scripts/test.py @@ -1,8 +1,6 @@ #!/usr/bin/env python3 -import atexit import subprocess import argparse -import tempfile import glob import time import sys @@ -107,32 +105,10 @@ def pluralize(word, count): return word return word + 's' -def make_export_and_conf(): - export_dir = tempfile.mkdtemp(prefix='share') - os.chmod(export_dir, 0o777) - (conf_fd, conf_path) = tempfile.mkstemp(prefix='export') - conf = os.fdopen(conf_fd, "w") - conf.write("%s 127.0.0.1(insecure,rw)\n" % export_dir) - conf.flush() - conf.close() - return (conf_path, export_dir) - -proc = None - -def kill_unfsd(): - global proc - subprocess.call(["sudo", "kill", str(proc.pid + 1)]) - proc.wait() - -UNFSD = "./modules/nfs-tests/unfsd.bin" - def run_tests(): - global proc start = time.time() - if cmdargs.nfs: - pass - elif cmdargs.name: + if cmdargs.name: tests_to_run = list((t for t in tests if re.match('^' + cmdargs.name + '$', t.name))) if not tests_to_run: print('No test matches: ' + cmdargs.name) @@ -140,38 +116,7 @@ def run_tests(): else: tests_to_run = tests - if cmdargs.nfs: - if not os.path.exists(UNFSD): - print("Please do:\n\tmake nfs-server") - sys.exit(1) - (conf_path, export_dir) = make_export_and_conf() - proc = subprocess.Popen([ "sudo", - os.path.join(os.getcwd(), UNFSD), - "-t", - "-d", - "-s", - "-l", "127.0.0.1", - "-e", conf_path ], - stdin = sys.stdin, - stdout = subprocess.PIPE, - stderr = sys.stderr, - shell = False) - atexit.register(kill_unfsd) - tests_to_run = [ SingleCommandTest('nfs-test', - "/tst-nfs.so --server 192.168.122.1 --share %s" % - export_dir) ] - - line = proc.stdout.readline().decode() - while line: - print(line) - if "/tmp" in line: - break - line = proc.stdout.readline().decode() - - - run(tests_to_run) - kill_unfsd() - elif cmdargs.single: + if cmdargs.single: if tests_to_run != tests: print('Cannot restrict the set of tests when --single option is used') exit(1) @@ -196,9 +141,8 @@ if __name__ == "__main__": parser.add_argument("-v", "--verbose", action="store_true", help="verbose test output") parser.add_argument("-r", "--repeat", action="store_true", help="repeat until test fails") parser.add_argument("-s", "--single", action="store_true", help="run as much tests as possible in a single OSv instance") - parser.add_argument("-n", "--nfs", action="store_true", help="run nfs test in a single OSv instance") parser.add_argument("-p", "--hypervisor", action="store", default="qemu", help="choose hypervisor to run: qemu, firecracker") - parser.add_argument("--name", action="store", help="run all tests whose names match given regular expression") + parser.add_argument("-n", "--name", action="store", help="run all tests whose names match given regular expression") parser.add_argument("--run_options", action="store", help="pass extra options to run.py") parser.add_argument("-m", "--manifest", action="store", default="modules/tests/usr.manifest", help="test manifest") parser.add_argument("-b", "--blacklist", action="append", help="test to be blacklisted", default=[]) -- 2.20.1 -- You received this message because you are subscribed to the Google Groups "OSv Development" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/osv-dev/20200322163158.13376-2-jwkozaczuk%40gmail.com.
