Skip to content

Commit

Permalink
test improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
h4sh committed Sep 23, 2023
1 parent e5f4fca commit 47a580d
Show file tree
Hide file tree
Showing 4 changed files with 247 additions and 139 deletions.
65 changes: 44 additions & 21 deletions test/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,28 @@
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
# 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.hookimpl(hookwrapper=True)
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'''
"""Provide capfd object to UnitTest instances"""
request.instance.capfd = capfd


def check_test_output(capfd):
(stdout, stderr) = capfd.readouterr()

Expand All @@ -31,47 +35,65 @@ def check_test_output(capfd):
# Strip out false positives
for (pattern, flags, count) in capfd.false_positives:
cp = re.compile(pattern, flags)
(stdout, cnt) = cp.subn('', stdout, count=count)
(stdout, cnt) = cp.subn("", stdout, count=count)
if count == 0 or count - cnt > 0:
stderr = cp.sub('', stderr, count=count - cnt)
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]+== ']
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))
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))
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
"""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)


@pytest.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':
if request.config.getoption("capture") == "no":
capfd = None
current_capfd = capfd
bak = current_capfd
Expand All @@ -82,6 +104,7 @@ def save_cap_fixtures(request, capfd):
assert bak is current_capfd
current_capfd = None


@pytest.hookimpl(trylast=True)
def pytest_runtest_call(item):
capfd = current_capfd
Expand Down
2 changes: 2 additions & 0 deletions test/pytest.ini
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
[pytest]
addopts = --verbose --assert=rewrite --tb=native -x -r a

markers = uses_fuse: Mark to indicate that FUSE is available on the system running the test
Loading

0 comments on commit 47a580d

Please sign in to comment.