Permalink
Browse files

Added unit tests and travis integration

  • Loading branch information...
Nikratio committed Jun 20, 2017
1 parent b66ecb9 commit 5f4619bac33a544af4da6e7d28bb4d7dbe45ae92
Showing with 698 additions and 6 deletions.
  1. +1 −2 .gitignore
  2. +20 −0 .travis.yml
  3. +1 −0 ChangeLog.rst
  4. +9 −4 README.rst
  5. +3 −0 meson.build
  6. +1 −0 test/.gitignore
  7. +89 −0 test/conftest.py
  8. +11 −0 test/lsan_suppress.txt
  9. +11 −0 test/meson.build
  10. +2 −0 test/pytest.ini
  11. +372 −0 test/test_sshfs.py
  12. +48 −0 test/travis-build.sh
  13. +21 −0 test/travis-install.sh
  14. +100 −0 test/util.py
  15. +9 −0 test/wrong_command.c
View
@@ -6,8 +6,6 @@
# NOTE! Please use 'git ls-files -i --exclude-standard'
# command after changing this file, to see if there are
# any tracked files which get ignored after the change.
.*
!.gitignore
*.o
*.lo
*.la
@@ -35,3 +33,4 @@ sshfs.1
/.pc
/patches
/m4
.deps/
View
@@ -0,0 +1,20 @@
sudo: required
dist: trusty
language:
- c
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- valgrind
- clang
- gcc
- gcc-6
- fuse
- libfuse2
- libfuse-dev
install: test/travis-install.sh
script: test/travis-build.sh
View
@@ -1,6 +1,7 @@
Unreleased Changes
------------------
* Added unit tests
* Documented limited hardlink support.
* Added support for building with Meson.
* Added support for more SSH options.
View
@@ -48,26 +48,31 @@ be available from your operating system's package manager).
To build and install, we recommend to use Meson_ (version 0.38 or
newer) and Ninja_. After extracting the sshfs tarball, create a
(temporary) build directory and run Meson and Ninja::
(temporary) build directory and run Meson::
$ md build; cd build
$ meson ..
$ ninja
$ sudo ninja install
Normally, the default build options will work fine. If you
nevertheless want to adjust them, you can do so with the *mesonconf*
command::
$ mesonconf # list options
$ mesonconf -D strip=true # set an option
$ ninja # rebuild
To build, test and install SSHFS, you then use Ninja (running the
tests requires the `py.test`_ Python module)::
$ ninja
$ python3 -m pytest test/ # optional, but recommended
$ sudo ninja install
.. _libfuse: http://github.com/libfuse/libfuse
.. _OSXFUSE: https://osxfuse.github.io/
.. _Glib: https://developer.gnome.org/glib/stable/
.. _Meson: http://mesonbuild.com/
.. _Ninja: https://ninja-build.org/
.. _`py.test`: http://www.pytest.org/
Alternate Installation
----------------------
View
@@ -59,3 +59,6 @@ executable('sshfs', sshfs_sources,
# This is a little ugly. Is there a better way to tell Meson that the
# manpage is in the build directory?
install_man(join_paths(meson.current_build_dir(), 'sshfs.1'))
subdir('test')
View
@@ -0,0 +1 @@
__pycache__/
View
@@ -0,0 +1,89 @@
import sys
import pytest
import time
import re
# If a test fails, wait a moment before retrieving the captured
# stdout/stderr. When using a server process, this makes sure that we capture
# any potential output of the server that comes *after* a test has failed. For
# example, if a request handler raises an exception, the server first signals an
# error to FUSE (causing the test to fail), and then logs the exception. Without
# the extra delay, the exception will go into nowhere.
@pytest.mark.hookwrapper
def pytest_pyfunc_call(pyfuncitem):
outcome = yield
failed = outcome.excinfo is not None
if failed:
time.sleep(1)
@pytest.fixture()
def pass_capfd(request, capfd):
'''Provide capfd object to UnitTest instances'''
request.instance.capfd = capfd
def check_test_output(capfd):
(stdout, stderr) = capfd.readouterr()
# Write back what we've read (so that it will still be printed.
sys.stdout.write(stdout)
sys.stderr.write(stderr)
# Strip out false positives
for (pattern, flags, count) in capfd.false_positives:
cp = re.compile(pattern, flags)
(stdout, cnt) = cp.subn('', stdout, count=count)
if count == 0 or count - cnt > 0:
stderr = cp.sub('', stderr, count=count - cnt)
patterns = [ r'\b{}\b'.format(x) for x in
('exception', 'error', 'warning', 'fatal', 'traceback',
'fault', 'crash(?:ed)?', 'abort(?:ed)',
'uninitiali[zs]ed') ]
patterns += ['^==[0-9]+== ']
for pattern in patterns:
cp = re.compile(pattern, re.IGNORECASE | re.MULTILINE)
hit = cp.search(stderr)
if hit:
raise AssertionError('Suspicious output to stderr (matched "%s")' % hit.group(0))
hit = cp.search(stdout)
if hit:
raise AssertionError('Suspicious output to stdout (matched "%s")' % hit.group(0))
def register_output(self, pattern, count=1, flags=re.MULTILINE):
'''Register *pattern* as false positive for output checking
This prevents the test from failing because the output otherwise
appears suspicious.
'''
self.false_positives.append((pattern, flags, count))
# This is a terrible hack that allows us to access the fixtures from the
# pytest_runtest_call hook. Among a lot of other hidden assumptions, it probably
# relies on tests running sequential (i.e., don't dare to use e.g. the xdist
# plugin)
current_capfd = None
@pytest.yield_fixture(autouse=True)
def save_cap_fixtures(request, capfd):
global current_capfd
capfd.false_positives = []
# Monkeypatch in a function to register false positives
type(capfd).register_output = register_output
if request.config.getoption('capture') == 'no':
capfd = None
current_capfd = capfd
bak = current_capfd
yield
# Try to catch problems with this hack (e.g. when running tests
# simultaneously)
assert bak is current_capfd
current_capfd = None
@pytest.hookimpl(trylast=True)
def pytest_runtest_call(item):
capfd = current_capfd
if capfd is not None:
check_test_output(capfd)
View
@@ -0,0 +1,11 @@
# Suppression file for address sanitizer.
# There are some leaks in command line option parsing. They should be
# fixed at some point, but are harmless since the consume just a small,
# constant amount of memory and do not grow.
leak:fuse_opt_parse
# Leaks in fusermount3 are harmless as well (it's a short-lived
# process) - but patches are welcome!
leak:fusermount.c
View
@@ -0,0 +1,11 @@
test_scripts = [ 'conftest.py', 'pytest.ini', 'test_sshfs.py',
'util.py' ]
custom_target('test_scripts', input: test_scripts,
output: test_scripts, build_by_default: true,
command: ['cp', '-fPu', '--preserve=mode',
'@INPUT@', meson.current_build_dir() ])
# Provide something helpful when running 'ninja test'
wrong_cmd = executable('wrong_command', 'wrong_command.c',
install: false)
test('wrong_cmd', wrong_cmd)
View
@@ -0,0 +1,2 @@
[pytest]
addopts = --verbose --assert=rewrite --tb=native -x -r a
Oops, something went wrong.

0 comments on commit 5f4619b

Please sign in to comment.