diff options
Diffstat (limited to 'test')
-rwxr-xr-x | test/test_examples.py | 38 | ||||
-rwxr-xr-x | test/travis-build.sh | 25 | ||||
-rw-r--r-- | test/util.py | 9 |
3 files changed, 56 insertions, 16 deletions
diff --git a/test/test_examples.py b/test/test_examples.py index 12fe6d7..0224bac 100755 --- a/test/test_examples.py +++ b/test/test_examples.py @@ -19,7 +19,7 @@ from tempfile import NamedTemporaryFile from contextlib import contextmanager from util import (wait_for_mount, umount, cleanup, base_cmdline, safe_sleep, basename, fuse_test_marker, test_printcap, - fuse_proto) + fuse_proto, powerset) from os.path import join as pjoin pytestmark = fuse_test_marker() @@ -33,20 +33,36 @@ def name_generator(__ctr=[0]): __ctr[0] += 1 return 'testfile_%d' % __ctr[0] -options = [ [] ] +options = [] if sys.platform == 'linux': - options.append(['-o', 'clone_fd']) -@pytest.mark.parametrize("options", options) -@pytest.mark.parametrize("name", ('hello', 'hello_ll')) -def test_hello(tmpdir, name, options): - mnt_dir = str(tmpdir) - cmdline = base_cmdline + \ - [ pjoin(basename, 'example', name), - '-f', mnt_dir ] + options + options.append('clone_fd') + +def invoke_directly(mnt_dir, name, options): + cmdline = base_cmdline + [ pjoin(basename, 'example', name), + '-f', mnt_dir, '-o', ','.join(options) ] if name == 'hello_ll': # supports single-threading only cmdline.append('-s') - mount_process = subprocess.Popen(cmdline) + + return cmdline + +def invoke_mount_fuse(mnt_dir, name, options): + return base_cmdline + [ pjoin(basename, 'util', 'mount.fuse3'), + name, mnt_dir, '-o', ','.join(options) ] + +def invoke_mount_fuse_drop_privileges(mnt_dir, name, options): + if os.getuid() != 0: + pytest.skip('drop_privileges requires root, skipping.') + + return invoke_mount_fuse(mnt_dir, name, options + ('drop_privileges',)) + +@pytest.mark.parametrize("cmdline_builder", (invoke_directly, invoke_mount_fuse, + invoke_mount_fuse_drop_privileges)) +@pytest.mark.parametrize("options", powerset(options)) +@pytest.mark.parametrize("name", ('hello', 'hello_ll')) +def test_hello(tmpdir, name, options, cmdline_builder): + mnt_dir = str(tmpdir) + mount_process = subprocess.Popen(cmdline_builder(mnt_dir, name, options)) try: wait_for_mount(mount_process, mnt_dir) assert os.listdir(mnt_dir) == [ 'hello' ] diff --git a/test/travis-build.sh b/test/travis-build.sh index dae1a10..6232e74 100755 --- a/test/travis-build.sh +++ b/test/travis-build.sh @@ -11,6 +11,19 @@ export CC TEST_CMD="python3 -m pytest --maxfail=99 test/" +# Make sure binaries can be accessed when invoked by root. +umask 0022 + +# There are tests that run as root but without CAP_DAC_OVERRIDE. To allow these +# to launch built binaries, the directory tree must be accessible to the root +# user. Since the source directory isn't necessarily accessible to root, we +# build and run tests in a temporary directory that we can set up to be world +# readable/executable. +SOURCE_DIR="$(readlink -f .)" +TEST_DIR="$(mktemp -dt libfuse-build-XXXXXX)" +chmod 0755 "${TEST_DIR}" +cd "${TEST_DIR}" + # Standard build for CC in gcc gcc-6 clang; do mkdir build-${CC}; cd build-${CC} @@ -19,7 +32,7 @@ for CC in gcc gcc-6 clang; do else build_opts='' fi - meson -D werror=true ${build_opts} ../ + meson -D werror=true ${build_opts} "${SOURCE_DIR}" ninja sudo chown root:root util/fusermount3 @@ -35,7 +48,7 @@ for san in undefined address; do mkdir build-${san}; cd build-${san} # b_lundef=false is required to work around clang # bug, cf. https://groups.google.com/forum/#!topic/mesonbuild/tgEdAXIIdC4 - meson -D b_sanitize=${san} -D b_lundef=false -D werror=true .. + meson -D b_sanitize=${san} -D b_lundef=false -D werror=true "${SOURCE_DIR}" ninja # Test as root and regular user @@ -43,12 +56,14 @@ for san in undefined address; do sudo chown root:root util/fusermount3 sudo chmod 4755 util/fusermount3 # Cleanup temporary files (since they're now owned by root) - sudo rm -rf test/.pytest_cache/ + sudo rm -rf test/.pytest_cache/ test/__pycache__ ${TEST_CMD} cd .. done -# Documentation -doxygen doc/Doxyfile +# Documentation. +(cd "${SOURCE_DIR}"; doxygen doc/Doxyfile) +# Clean up. +rm -rf "${TEST_DIR}" diff --git a/test/util.py b/test/util.py index b9c1b0c..ba02b9f 100644 --- a/test/util.py +++ b/test/util.py @@ -7,6 +7,7 @@ import time from os.path import join as pjoin import sys import re +import itertools basename = pjoin(os.path.dirname(__file__), '..') @@ -138,6 +139,12 @@ def fuse_test_marker(): return pytest.mark.uses_fuse() +def powerset(iterable): + s = list(iterable) + return itertools.chain.from_iterable( + itertools.combinations(s, r) for r in range(len(s)+1)) + + # Use valgrind if requested if os.environ.get('TEST_WITH_VALGRIND', 'no').lower().strip() \ not in ('no', 'false', '0'): @@ -147,6 +154,8 @@ else: # Try to use local fusermount3 os.environ['PATH'] = '%s:%s' % (pjoin(basename, 'util'), os.environ['PATH']) +# Put example binaries on PATH +os.environ['PATH'] = '%s:%s' % (pjoin(basename, 'example'), os.environ['PATH']) try: (fuse_proto, fuse_caps) = test_printcap() |