Tests: fixed unit.log print.
This commit is contained in:
137
test/conftest.py
137
test/conftest.py
@@ -4,11 +4,13 @@ import platform
|
||||
import re
|
||||
import shutil
|
||||
import signal
|
||||
import socket
|
||||
import stat
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import time
|
||||
from multiprocessing import Process
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -45,6 +47,7 @@ def pytest_addoption(parser):
|
||||
|
||||
|
||||
unit_instance = {}
|
||||
_processes = []
|
||||
option = None
|
||||
|
||||
|
||||
@@ -66,6 +69,10 @@ def pytest_configure(config):
|
||||
fcntl.fcntl(sys.stdout.fileno(), fcntl.F_SETFL, 0)
|
||||
|
||||
|
||||
def skip_alert(*alerts):
|
||||
option.skip_alerts.extend(alerts)
|
||||
|
||||
|
||||
def pytest_generate_tests(metafunc):
|
||||
cls = metafunc.cls
|
||||
if not hasattr(cls, 'application_type'):
|
||||
@@ -127,7 +134,7 @@ def pytest_sessionstart(session):
|
||||
break
|
||||
|
||||
if m is None:
|
||||
_print_log()
|
||||
_print_log(log)
|
||||
exit("Unit is writing log too long")
|
||||
|
||||
# discover available modules from unit.log
|
||||
@@ -154,8 +161,26 @@ def pytest_sessionstart(session):
|
||||
|
||||
unit_stop()
|
||||
|
||||
shutil.rmtree(unit_instance['temp_dir'])
|
||||
|
||||
|
||||
@pytest.hookimpl(tryfirst=True, hookwrapper=True)
|
||||
def pytest_runtest_makereport(item, call):
|
||||
# execute all other hooks to obtain the report object
|
||||
outcome = yield
|
||||
rep = outcome.get_result()
|
||||
|
||||
# set a report attribute for each phase of a call, which can
|
||||
# be "setup", "call", "teardown"
|
||||
|
||||
setattr(item, "rep_" + rep.when, rep)
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def run(request):
|
||||
unit = unit_run()
|
||||
option.temp_dir = unit['temp_dir']
|
||||
|
||||
def setup_method(self):
|
||||
option.skip_alerts = [
|
||||
r'read signalfd\(4\) failed',
|
||||
r'sendmsg.+failed',
|
||||
@@ -163,6 +188,40 @@ def setup_method(self):
|
||||
]
|
||||
option.skip_sanitizer = False
|
||||
|
||||
yield
|
||||
|
||||
# stop unit
|
||||
|
||||
error = unit_stop()
|
||||
|
||||
if error:
|
||||
_print_log()
|
||||
|
||||
assert error is None, 'stop unit'
|
||||
|
||||
# stop all processes
|
||||
|
||||
error = stop_processes()
|
||||
|
||||
if error:
|
||||
_print_log()
|
||||
|
||||
assert error is None, 'stop unit'
|
||||
|
||||
# check unit.log for alerts
|
||||
|
||||
_check_alerts()
|
||||
|
||||
# print unit.log in case of error
|
||||
|
||||
if request.node.rep_call.failed:
|
||||
_print_log()
|
||||
|
||||
# remove unit.log
|
||||
|
||||
if not option.save_log:
|
||||
shutil.rmtree(unit['temp_dir'])
|
||||
|
||||
def unit_run():
|
||||
global unit_instance
|
||||
build_dir = option.current_dir + '/build'
|
||||
@@ -204,14 +263,6 @@ def unit_run():
|
||||
_print_log()
|
||||
exit('Could not start unit')
|
||||
|
||||
# dumb (TODO: remove)
|
||||
option.skip_alerts = [
|
||||
r'read signalfd\(4\) failed',
|
||||
r'sendmsg.+failed',
|
||||
r'recvmsg.+failed',
|
||||
]
|
||||
option.skip_sanitizer = False
|
||||
|
||||
unit_instance['temp_dir'] = temp_dir
|
||||
unit_instance['log'] = temp_dir + '/unit.log'
|
||||
unit_instance['control_sock'] = temp_dir + '/control.unit.sock'
|
||||
@@ -236,8 +287,6 @@ def unit_stop():
|
||||
p.kill()
|
||||
return 'Could not terminate unit'
|
||||
|
||||
shutil.rmtree(unit_instance['temp_dir'])
|
||||
|
||||
def public_dir(path):
|
||||
os.chmod(path, 0o777)
|
||||
|
||||
@@ -267,11 +316,14 @@ def waitforfiles(*files):
|
||||
return ret
|
||||
|
||||
|
||||
def skip_alert(*alerts):
|
||||
option.skip_alerts.extend(alerts)
|
||||
|
||||
def _check_alerts(path=None):
|
||||
if path is None:
|
||||
path = unit_instance['log']
|
||||
|
||||
with open(path, 'r', encoding='utf-8', errors='ignore') as f:
|
||||
log = f.read()
|
||||
|
||||
def _check_alerts(log):
|
||||
found = False
|
||||
|
||||
alerts = re.findall(r'.+\[alert\].+', log)
|
||||
@@ -286,23 +338,22 @@ def _check_alerts(log):
|
||||
alerts = [al for al in alerts if re.search(skip, al) is None]
|
||||
|
||||
if alerts:
|
||||
_print_log(data=log)
|
||||
_print_log(log)
|
||||
assert not alerts, 'alert(s)'
|
||||
|
||||
if not option.skip_sanitizer:
|
||||
sanitizer_errors = re.findall('.+Sanitizer.+', log)
|
||||
|
||||
if sanitizer_errors:
|
||||
_print_log(data=log)
|
||||
_print_log(log)
|
||||
assert not sanitizer_errors, 'sanitizer error(s)'
|
||||
|
||||
if found:
|
||||
print('skipped.')
|
||||
|
||||
|
||||
def _print_log(path=None, data=None):
|
||||
if path is None:
|
||||
path = unit_instance['log']
|
||||
def _print_log(data=None):
|
||||
path = unit_instance['log']
|
||||
|
||||
print('Path to unit.log:\n' + path + '\n')
|
||||
|
||||
@@ -317,6 +368,52 @@ def _print_log(path=None, data=None):
|
||||
sys.stdout.write(data)
|
||||
|
||||
|
||||
def run_process(target, *args):
|
||||
global _processes
|
||||
|
||||
process = Process(target=target, args=args)
|
||||
process.start()
|
||||
|
||||
_processes.append(process)
|
||||
|
||||
def stop_processes():
|
||||
if not _processes:
|
||||
return
|
||||
|
||||
fail = False
|
||||
for process in _processes:
|
||||
if process.is_alive():
|
||||
process.terminate()
|
||||
process.join(timeout=15)
|
||||
|
||||
if process.is_alive():
|
||||
fail = True
|
||||
|
||||
if fail:
|
||||
return 'Fail to stop process(es)'
|
||||
|
||||
|
||||
def waitforsocket(port):
|
||||
ret = False
|
||||
|
||||
for i in range(50):
|
||||
try:
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
sock.connect(('127.0.0.1', port))
|
||||
ret = True
|
||||
break
|
||||
except:
|
||||
sock.close()
|
||||
time.sleep(0.1)
|
||||
|
||||
sock.close()
|
||||
|
||||
assert ret, 'socket connected'
|
||||
|
||||
@pytest.fixture
|
||||
def temp_dir(request):
|
||||
return unit_instance['temp_dir']
|
||||
|
||||
@pytest.fixture
|
||||
def is_unsafe(request):
|
||||
return request.config.getoption("--unsafe")
|
||||
|
||||
Reference in New Issue
Block a user