Skip tests if not root and no setuid fusermount3.
authorNikolaus Rath <Nikolaus@rath.org>
Tue, 10 Jan 2017 22:34:42 +0000 (14:34 -0800)
committerNikolaus Rath <Nikolaus@rath.org>
Tue, 10 Jan 2017 22:42:26 +0000 (14:42 -0800)
test/pytest.ini
test/test_examples.py
test/util.py

index bc4af3664b909428208af82996eb7c21ca7f30b2..95161546e625a2ceb57a44ede688e774d9f30664 100644 (file)
@@ -1,2 +1,2 @@
 [pytest]
-addopts = --verbose --assert=rewrite --tb=native -x
+addopts = --verbose --assert=rewrite --tb=native -x -r a
index 95eeb9a5a5125890fbba893881d7586af42d8561..cfd6734c924d2636c52b87baf65adb72f1fd4848 100755 (executable)
@@ -17,11 +17,13 @@ import platform
 from distutils.version import LooseVersion
 from tempfile import NamedTemporaryFile
 from util import (wait_for_mount, umount, cleanup, base_cmdline,
-                  safe_sleep, basename)
+                  safe_sleep, basename, fuse_test_marker)
 from os.path import join as pjoin
 
 TEST_FILE = __file__
 
+pytestmark = fuse_test_marker()
+
 with open(TEST_FILE, 'rb') as fh:
     TEST_DATA = fh.read()
 
index 76b8ec1145a8af8758e5d842c644436c7b35ed39..6bba9e26e7ac53fbd9650fb870cf833e0712596d 100644 (file)
@@ -2,6 +2,7 @@
 import subprocess
 import pytest
 import os
+import stat
 import time
 from os.path import join as pjoin
 
@@ -68,6 +69,42 @@ def safe_sleep(secs):
         time.sleep(end - now)
         now = time.time()
 
+def fuse_test_marker():
+    '''Return a pytest.marker that indicates FUSE availability
+
+    If system/user/environment does not support FUSE, return
+    a `pytest.mark.skip` object with more details. If FUSE is
+    supported, return `pytest.mark.uses_fuse()`.
+    '''
+
+    skip = lambda x: pytest.mark.skip(reason=x)
+
+    with subprocess.Popen(['which', 'fusermount3'], stdout=subprocess.PIPE,
+                          universal_newlines=True) as which:
+        fusermount_path = which.communicate()[0].strip()
+
+    if not fusermount_path or which.returncode != 0:
+        return skip("Can't find fusermount executable")
+
+    if not os.path.exists('/dev/fuse'):
+        return skip("FUSE kernel module does not seem to be loaded")
+
+    if os.getuid() == 0:
+        return pytest.mark.uses_fuse()
+
+    mode = os.stat(fusermount_path).st_mode
+    if mode & stat.S_ISUID == 0:
+        return skip('fusermount executable not setuid, and we are not root.')
+
+    try:
+        fd = os.open('/dev/fuse', os.O_RDWR)
+    except OSError as exc:
+        return skip('Unable to open /dev/fuse: %s' % exc.strerror)
+    else:
+        os.close(fd)
+
+    return pytest.mark.uses_fuse()
+
 # If valgrind and libtool are available, use them
 def has_program(name):
     try: