From: Waldemar Kozaczuk <jwkozac...@gmail.com> Committer: Waldemar Kozaczuk <jwkozac...@gmail.com> Branch: master
tests: move nfs testing out to a separate module 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 <jwkozac...@gmail.com> --- diff --git a/modules/nfs-tests/.gitignore b/modules/nfs-tests/.gitignore --- a/modules/nfs-tests/.gitignore +++ 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 --- 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 --- a/modules/nfs-tests/test.py +++ 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 --- 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 --- 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,71 +105,18 @@ 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) exit(1) 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 @@ def 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=[]) -- 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 osv-dev+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/osv-dev/000000000000676fc705a1d7d8ad%40google.com.