Tests: print_log_on_assert() decorator introduced.
This commit is contained in:
155
test/conftest.py
155
test/conftest.py
@@ -74,7 +74,7 @@ def pytest_addoption(parser):
|
|||||||
|
|
||||||
unit_instance = {}
|
unit_instance = {}
|
||||||
_processes = []
|
_processes = []
|
||||||
_fds_check = {
|
_fds_info = {
|
||||||
'main': {'fds': 0, 'skip': False},
|
'main': {'fds': 0, 'skip': False},
|
||||||
'router': {'name': 'unit: router', 'pid': -1, 'fds': 0, 'skip': False},
|
'router': {'name': 'unit: router', 'pid': -1, 'fds': 0, 'skip': False},
|
||||||
'controller': {
|
'controller': {
|
||||||
@@ -115,6 +115,17 @@ def pytest_configure(config):
|
|||||||
fcntl.fcntl(sys.stdout.fileno(), fcntl.F_SETFL, 0)
|
fcntl.fcntl(sys.stdout.fileno(), fcntl.F_SETFL, 0)
|
||||||
|
|
||||||
|
|
||||||
|
def print_log_on_assert(func):
|
||||||
|
def inner_function(*args, **kwargs):
|
||||||
|
try:
|
||||||
|
func(*args, **kwargs)
|
||||||
|
except AssertionError as e:
|
||||||
|
_print_log(kwargs.get('log', None))
|
||||||
|
raise e
|
||||||
|
|
||||||
|
return inner_function
|
||||||
|
|
||||||
|
|
||||||
def pytest_generate_tests(metafunc):
|
def pytest_generate_tests(metafunc):
|
||||||
cls = metafunc.cls
|
cls = metafunc.cls
|
||||||
if (
|
if (
|
||||||
@@ -275,9 +286,9 @@ def run(request):
|
|||||||
]
|
]
|
||||||
option.skip_sanitizer = False
|
option.skip_sanitizer = False
|
||||||
|
|
||||||
_fds_check['main']['skip'] = False
|
_fds_info['main']['skip'] = False
|
||||||
_fds_check['router']['skip'] = False
|
_fds_info['router']['skip'] = False
|
||||||
_fds_check['controller']['skip'] = False
|
_fds_info['controller']['skip'] = False
|
||||||
|
|
||||||
yield
|
yield
|
||||||
|
|
||||||
@@ -299,7 +310,7 @@ def run(request):
|
|||||||
# clean temp_dir before the next test
|
# clean temp_dir before the next test
|
||||||
|
|
||||||
if not option.restart:
|
if not option.restart:
|
||||||
_clear_conf(unit['temp_dir'] + '/control.unit.sock', log)
|
_clear_conf(unit['temp_dir'] + '/control.unit.sock', log=log)
|
||||||
|
|
||||||
for item in os.listdir(unit['temp_dir']):
|
for item in os.listdir(unit['temp_dir']):
|
||||||
if item not in [
|
if item not in [
|
||||||
@@ -319,51 +330,9 @@ def run(request):
|
|||||||
else:
|
else:
|
||||||
shutil.rmtree(path)
|
shutil.rmtree(path)
|
||||||
|
|
||||||
# check descriptors (wait for some time before check)
|
# check descriptors
|
||||||
|
|
||||||
def waitforfds(diff):
|
_check_fds(log=log)
|
||||||
for i in range(600):
|
|
||||||
fds_diff = diff()
|
|
||||||
|
|
||||||
if fds_diff <= option.fds_threshold:
|
|
||||||
break
|
|
||||||
|
|
||||||
time.sleep(0.1)
|
|
||||||
|
|
||||||
return fds_diff
|
|
||||||
|
|
||||||
ps = _fds_check['main']
|
|
||||||
if not ps['skip']:
|
|
||||||
fds_diff = waitforfds(
|
|
||||||
lambda: _count_fds(unit_instance['pid']) - ps['fds']
|
|
||||||
)
|
|
||||||
ps['fds'] += fds_diff
|
|
||||||
|
|
||||||
assert (
|
|
||||||
fds_diff <= option.fds_threshold
|
|
||||||
), 'descriptors leak main process'
|
|
||||||
|
|
||||||
else:
|
|
||||||
ps['fds'] = _count_fds(unit_instance['pid'])
|
|
||||||
|
|
||||||
for name in ['controller', 'router']:
|
|
||||||
ps = _fds_check[name]
|
|
||||||
ps_pid = ps['pid']
|
|
||||||
ps['pid'] = pid_by_name(ps['name'])
|
|
||||||
|
|
||||||
if not ps['skip']:
|
|
||||||
fds_diff = waitforfds(lambda: _count_fds(ps['pid']) - ps['fds'])
|
|
||||||
ps['fds'] += fds_diff
|
|
||||||
|
|
||||||
if not option.restart:
|
|
||||||
assert ps['pid'] == ps_pid, 'same pid %s' % name
|
|
||||||
|
|
||||||
assert fds_diff <= option.fds_threshold, (
|
|
||||||
'descriptors leak %s' % name
|
|
||||||
)
|
|
||||||
|
|
||||||
else:
|
|
||||||
ps['fds'] = _count_fds(ps['pid'])
|
|
||||||
|
|
||||||
# print unit.log in case of error
|
# print unit.log in case of error
|
||||||
|
|
||||||
@@ -440,13 +409,13 @@ def unit_run():
|
|||||||
|
|
||||||
_clear_conf(unit_instance['temp_dir'] + '/control.unit.sock')
|
_clear_conf(unit_instance['temp_dir'] + '/control.unit.sock')
|
||||||
|
|
||||||
_fds_check['main']['fds'] = _count_fds(unit_instance['pid'])
|
_fds_info['main']['fds'] = _count_fds(unit_instance['pid'])
|
||||||
|
|
||||||
router = _fds_check['router']
|
router = _fds_info['router']
|
||||||
router['pid'] = pid_by_name(router['name'])
|
router['pid'] = pid_by_name(router['name'])
|
||||||
router['fds'] = _count_fds(router['pid'])
|
router['fds'] = _count_fds(router['pid'])
|
||||||
|
|
||||||
controller = _fds_check['controller']
|
controller = _fds_info['controller']
|
||||||
controller['pid'] = pid_by_name(controller['name'])
|
controller['pid'] = pid_by_name(controller['name'])
|
||||||
controller['fds'] = _count_fds(controller['pid'])
|
controller['fds'] = _count_fds(controller['pid'])
|
||||||
|
|
||||||
@@ -481,7 +450,8 @@ def unit_stop():
|
|||||||
return 'Could not terminate unit'
|
return 'Could not terminate unit'
|
||||||
|
|
||||||
|
|
||||||
def _check_alerts(log=None):
|
@print_log_on_assert
|
||||||
|
def _check_alerts(*, log=None):
|
||||||
if log is None:
|
if log is None:
|
||||||
with Log.open(encoding='utf-8') as f:
|
with Log.open(encoding='utf-8') as f:
|
||||||
log = f.read()
|
log = f.read()
|
||||||
@@ -499,22 +469,18 @@ def _check_alerts(log=None):
|
|||||||
for skip in option.skip_alerts:
|
for skip in option.skip_alerts:
|
||||||
alerts = [al for al in alerts if re.search(skip, al) is None]
|
alerts = [al for al in alerts if re.search(skip, al) is None]
|
||||||
|
|
||||||
if alerts:
|
assert not alerts, 'alert(s)'
|
||||||
_print_log(log)
|
|
||||||
assert not alerts, 'alert(s)'
|
|
||||||
|
|
||||||
if not option.skip_sanitizer:
|
if not option.skip_sanitizer:
|
||||||
sanitizer_errors = re.findall('.+Sanitizer.+', log)
|
sanitizer_errors = re.findall('.+Sanitizer.+', log)
|
||||||
|
|
||||||
if sanitizer_errors:
|
assert not sanitizer_errors, 'sanitizer error(s)'
|
||||||
_print_log(log)
|
|
||||||
assert not sanitizer_errors, 'sanitizer error(s)'
|
|
||||||
|
|
||||||
if found:
|
if found:
|
||||||
print('skipped.')
|
print('skipped.')
|
||||||
|
|
||||||
|
|
||||||
def _print_log(data=None):
|
def _print_log(log):
|
||||||
path = Log.get_path()
|
path = Log.get_path()
|
||||||
|
|
||||||
print('Path to unit.log:\n' + path + '\n')
|
print('Path to unit.log:\n' + path + '\n')
|
||||||
@@ -523,19 +489,15 @@ def _print_log(data=None):
|
|||||||
os.set_blocking(sys.stdout.fileno(), True)
|
os.set_blocking(sys.stdout.fileno(), True)
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
|
|
||||||
if data is None:
|
if log is None:
|
||||||
with open(path, 'r', encoding='utf-8', errors='ignore') as f:
|
with open(path, 'r', encoding='utf-8', errors='ignore') as f:
|
||||||
shutil.copyfileobj(f, sys.stdout)
|
shutil.copyfileobj(f, sys.stdout)
|
||||||
else:
|
else:
|
||||||
sys.stdout.write(data)
|
sys.stdout.write(log)
|
||||||
|
|
||||||
|
|
||||||
def _clear_conf(sock, log=None):
|
@print_log_on_assert
|
||||||
def check_success(resp):
|
def _clear_conf(sock, *, log=None):
|
||||||
if 'success' not in resp:
|
|
||||||
_print_log(log)
|
|
||||||
assert 'success' in resp
|
|
||||||
|
|
||||||
resp = http.put(
|
resp = http.put(
|
||||||
url='/config',
|
url='/config',
|
||||||
sock_type='unix',
|
sock_type='unix',
|
||||||
@@ -543,7 +505,7 @@ def _clear_conf(sock, log=None):
|
|||||||
body=json.dumps({"listeners": {}, "applications": {}}),
|
body=json.dumps({"listeners": {}, "applications": {}}),
|
||||||
)['body']
|
)['body']
|
||||||
|
|
||||||
check_success(resp)
|
assert 'success' in resp, 'clear conf'
|
||||||
|
|
||||||
if 'openssl' not in option.available['modules']:
|
if 'openssl' not in option.available['modules']:
|
||||||
return
|
return
|
||||||
@@ -561,7 +523,54 @@ def _clear_conf(sock, log=None):
|
|||||||
url='/certificates/' + cert, sock_type='unix', addr=sock,
|
url='/certificates/' + cert, sock_type='unix', addr=sock,
|
||||||
)['body']
|
)['body']
|
||||||
|
|
||||||
check_success(resp)
|
assert 'success' in resp, 'remove certificate'
|
||||||
|
|
||||||
|
|
||||||
|
@print_log_on_assert
|
||||||
|
def _check_fds(*, log=None):
|
||||||
|
def waitforfds(diff):
|
||||||
|
for i in range(600):
|
||||||
|
fds_diff = diff()
|
||||||
|
|
||||||
|
if fds_diff <= option.fds_threshold:
|
||||||
|
break
|
||||||
|
|
||||||
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
return fds_diff
|
||||||
|
|
||||||
|
ps = _fds_info['main']
|
||||||
|
if not ps['skip']:
|
||||||
|
fds_diff = waitforfds(
|
||||||
|
lambda: _count_fds(unit_instance['pid']) - ps['fds']
|
||||||
|
)
|
||||||
|
ps['fds'] += fds_diff
|
||||||
|
|
||||||
|
assert (
|
||||||
|
fds_diff <= option.fds_threshold
|
||||||
|
), 'descriptors leak main process'
|
||||||
|
|
||||||
|
else:
|
||||||
|
ps['fds'] = _count_fds(unit_instance['pid'])
|
||||||
|
|
||||||
|
for name in ['controller', 'router']:
|
||||||
|
ps = _fds_info[name]
|
||||||
|
ps_pid = ps['pid']
|
||||||
|
ps['pid'] = pid_by_name(ps['name'])
|
||||||
|
|
||||||
|
if not ps['skip']:
|
||||||
|
fds_diff = waitforfds(lambda: _count_fds(ps['pid']) - ps['fds'])
|
||||||
|
ps['fds'] += fds_diff
|
||||||
|
|
||||||
|
if not option.restart:
|
||||||
|
assert ps['pid'] == ps_pid, 'same pid %s' % name
|
||||||
|
|
||||||
|
assert fds_diff <= option.fds_threshold, (
|
||||||
|
'descriptors leak %s' % name
|
||||||
|
)
|
||||||
|
|
||||||
|
else:
|
||||||
|
ps['fds'] = _count_fds(ps['pid'])
|
||||||
|
|
||||||
|
|
||||||
def _count_fds(pid):
|
def _count_fds(pid):
|
||||||
@@ -639,9 +648,9 @@ def skip_alert():
|
|||||||
@pytest.fixture()
|
@pytest.fixture()
|
||||||
def skip_fds_check():
|
def skip_fds_check():
|
||||||
def _skip(main=False, router=False, controller=False):
|
def _skip(main=False, router=False, controller=False):
|
||||||
_fds_check['main']['skip'] = main
|
_fds_info['main']['skip'] = main
|
||||||
_fds_check['router']['skip'] = router
|
_fds_info['router']['skip'] = router
|
||||||
_fds_check['controller']['skip'] = controller
|
_fds_info['controller']['skip'] = controller
|
||||||
|
|
||||||
return _skip
|
return _skip
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user