1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
'''
conftest.py - this file is part of S3QL.
Copyright © 2008 Nikolaus Rath <Nikolaus@rath.org>
This work can be distributed under the terms of the GNU GPLv3.
This module is loaded automatically by py.test and is used to
initialize logging and adjust the load path before running
any tests.
'''
# Python version check
import sys
if sys.version_info < (3,3):
raise SystemExit('Python version is %d.%d.%d, but S3QL requires Python 3.3 or newer'
% sys.version_info[:3])
import logging.handlers
import sys
import os.path
import pytest
import faulthandler
import signal
import gc
import time
# If a test fails, wait a moment before retrieving the captured
# stdout/stderr. When using a server process (like in t4_fuse.py), 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(scope="class")
def s3ql_cmd_argv(request):
'''Provide argument list to execute s3ql commands in tests'''
if request.config.getoption('installed'):
request.cls.s3ql_cmd_argv = lambda self, cmd: [ cmd ]
else:
basedir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
request.cls.s3ql_cmd_argv = lambda self, cmd: [ sys.executable,
os.path.join(basedir, 'bin', cmd) ]
# Enable output checks
pytest_plugins = ('pytest_checklogs')
# Ignore DeprecationWarnings when running unit tests. They are
# unfortunately quite often a result of indirect imports via third party
# modules, so we can't actually fix them.
@pytest.fixture(autouse=True)
def ignore_depreciation_warnings(reg_output):
reg_output(r'(Pending)?DeprecationWarning', count=0)
@pytest.fixture()
def pass_reg_output(request, reg_output):
'''Provide reg_output function to UnitTest instances'''
request.instance.reg_output = reg_output
def pytest_addoption(parser):
group = parser.getgroup("terminal reporting")
group._addoption("--logdebug", action="append", metavar='<module>',
help="Activate debugging output from <module> for tests. Use `all` "
"to get debug messages from all modules. This option can be "
"specified multiple times.")
group = parser.getgroup("general")
group._addoption("--installed", action="store_true", default=False,
help="Test the installed package.")
def pytest_configure(config):
# If we are running from the S3QL source directory, make sure that we
# load modules from here
basedir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
if not config.getoption('installed'):
if (os.path.exists(os.path.join(basedir, 'setup.py')) and
os.path.exists(os.path.join(basedir, 'src', 's3ql', '__init__.py'))):
sys.path = [os.path.join(basedir, 'src')] + sys.path
# When running from HG repo, enable all warnings
if os.path.exists(os.path.join(basedir, 'MANIFEST.in')):
import warnings
warnings.resetwarnings()
warnings.simplefilter('default')
# Enable faulthandler
global faultlog_fh
faultlog_fh = open(os.path.join(basedir, 'tests', 'test_crit.log'), 'a')
faulthandler.enable(faultlog_fh)
faulthandler.register(signal.SIGUSR1, file=faultlog_fh)
# Configure logging. We don't set a default handler but rely on
# the catchlog pytest plugin.
logdebug = config.getoption('logdebug')
root_logger = logging.getLogger()
if logdebug is not None:
logging.disable(logging.NOTSET)
if 'all' in logdebug:
root_logger.setLevel(logging.DEBUG)
else:
for module in logdebug:
logging.getLogger(module).setLevel(logging.DEBUG)
else:
root_logger.setLevel(logging.INFO)
logging.disable(logging.DEBUG)
logging.captureWarnings(capture=True)
# Run gc.collect() at the end of every test, so that we get ResourceWarnings
# as early as possible.
def pytest_runtest_teardown(item, nextitem):
gc.collect()
|