Tests: more fixtures.

Common methods from applications/proto.py converted to the fixtures.
sysctl check moved to the specific file where it is using.
Some options moved to the constructor to have early access.
This commit is contained in:
Andrei Zeliankou
2023-05-29 16:45:49 +01:00
parent f55818059c
commit 31ff94add9
24 changed files with 340 additions and 341 deletions

View File

@@ -2,7 +2,6 @@ import fcntl
import inspect import inspect
import json import json
import os import os
import platform
import re import re
import shutil import shutil
import signal import signal
@@ -109,8 +108,6 @@ def pytest_configure(config):
os.path.join(os.path.dirname(__file__), os.pardir) os.path.join(os.path.dirname(__file__), os.pardir)
) )
option.test_dir = f'{option.current_dir}/test' option.test_dir = f'{option.current_dir}/test'
option.architecture = platform.architecture()[0]
option.system = platform.system()
option.cache_dir = tempfile.mkdtemp(prefix='unit-test-cache-') option.cache_dir = tempfile.mkdtemp(prefix='unit-test-cache-')
public_dir(option.cache_dir) public_dir(option.cache_dir)
@@ -173,25 +170,15 @@ def pytest_sessionstart():
[unit['unitd'], '--version'], stderr=subprocess.STDOUT [unit['unitd'], '--version'], stderr=subprocess.STDOUT
).decode() ).decode()
# read unit.log if not _wait_for_record(r'controller started'):
Log.print_log()
for _ in range(50):
with open(Log.get_path(), 'r') as f:
log = f.read()
m = re.search('controller started', log)
if m is None:
time.sleep(0.1)
else:
break
if m is None:
Log.print_log(log)
exit("Unit is writing log too long") exit("Unit is writing log too long")
# discover available modules from unit.log # discover available modules from unit.log
for module in re.findall(r'module: ([a-zA-Z]+) (.*) ".*"$', log, re.M): for module in re.findall(
r'module: ([a-zA-Z]+) (.*) ".*"$', Log.read(), re.M
):
versions = option.available['modules'].setdefault(module[0], []) versions = option.available['modules'].setdefault(module[0], [])
if module[1] not in versions: if module[1] not in versions:
versions.append(module[1]) versions.append(module[1])
@@ -489,6 +476,7 @@ def _clear_conf(sock, *, log=None):
for script in scripts: for script in scripts:
assert 'success' in delete(f'/js_modules/{script}'), 'delete script' assert 'success' in delete(f'/js_modules/{script}'), 'delete script'
def _clear_temp_dir(): def _clear_temp_dir():
temp_dir = unit_instance['temp_dir'] temp_dir = unit_instance['temp_dir']
@@ -633,6 +621,19 @@ def _count_fds(pid):
return 0 return 0
def _wait_for_record(pattern, name='unit.log', wait=150, flags=re.M):
with Log.open(name) as file:
for _ in range(wait):
found = re.search(pattern, file.read(), flags)
if found is not None:
break
time.sleep(0.1)
return found
def run_process(target, *args): def run_process(target, *args):
global _processes global _processes
@@ -669,6 +670,61 @@ def find_proc(name, ps_output):
return re.findall(f'{unit_instance["pid"]}.*{name}', ps_output) return re.findall(f'{unit_instance["pid"]}.*{name}', ps_output)
def pytest_sessionfinish():
if not option.restart and option.save_log:
Log.print_path()
option.restart = True
unit_stop()
public_dir(option.cache_dir)
shutil.rmtree(option.cache_dir)
if not option.save_log and os.path.isdir(option.temp_dir):
public_dir(option.temp_dir)
shutil.rmtree(option.temp_dir)
@pytest.fixture
def date_to_sec_epoch():
def _date_to_sec_epoch(date, template='%a, %d %b %Y %X %Z'):
return time.mktime(time.strptime(date, template))
return _date_to_sec_epoch
@pytest.fixture
def findall():
def _findall(pattern, name='unit.log', flags=re.M):
return re.findall(pattern, Log.read(name), flags)
return _findall
@pytest.fixture
def is_su():
return option.is_privileged
@pytest.fixture
def is_unsafe(request):
return request.config.getoption("--unsafe")
@pytest.fixture
def search_in_file():
def _search_in_file(pattern, name='unit.log', flags=re.M):
return re.search(pattern, Log.read(name), flags)
return _search_in_file
@pytest.fixture
def sec_epoch():
return time.mktime(time.gmtime())
@pytest.fixture() @pytest.fixture()
def skip_alert(): def skip_alert():
def _skip(*alerts): def _skip(*alerts):
@@ -687,37 +743,21 @@ def skip_fds_check():
return _skip return _skip
@pytest.fixture()
def system():
return option.system
@pytest.fixture @pytest.fixture
def temp_dir(): def temp_dir():
return unit_instance['temp_dir'] return unit_instance['temp_dir']
@pytest.fixture
def is_unsafe(request):
return request.config.getoption("--unsafe")
@pytest.fixture
def is_su():
return os.geteuid() == 0
@pytest.fixture @pytest.fixture
def unit_pid(): def unit_pid():
return unit_instance['process'].pid return unit_instance['process'].pid
def pytest_sessionfinish(): @pytest.fixture
if not option.restart and option.save_log: def wait_for_record():
Log.print_path() return _wait_for_record
option.restart = True
unit_stop()
public_dir(option.cache_dir)
shutil.rmtree(option.cache_dir)
if not option.save_log and os.path.isdir(option.temp_dir):
public_dir(option.temp_dir)
shutil.rmtree(option.temp_dir)

View File

@@ -24,10 +24,7 @@ class TestAccessLog(TestApplicationPython):
'access_log', 'access_log',
), 'access_log format' ), 'access_log format'
def wait_for_record(self, pattern, name='access.log'): def test_access_log_keepalive(self, wait_for_record):
return super().wait_for_record(pattern, name)
def test_access_log_keepalive(self):
self.load('mirror') self.load('mirror')
assert self.get()['status'] == 200, 'init' assert self.get()['status'] == 200, 'init'
@@ -43,16 +40,18 @@ class TestAccessLog(TestApplicationPython):
) )
assert ( assert (
self.wait_for_record(r'"POST / HTTP/1.1" 200 5') is not None wait_for_record(r'"POST / HTTP/1.1" 200 5', 'access.log')
is not None
), 'keepalive 1' ), 'keepalive 1'
_ = self.post(sock=sock, body='0123456789') _ = self.post(sock=sock, body='0123456789')
assert ( assert (
self.wait_for_record(r'"POST / HTTP/1.1" 200 10') is not None wait_for_record(r'"POST / HTTP/1.1" 200 10', 'access.log')
is not None
), 'keepalive 2' ), 'keepalive 2'
def test_access_log_pipeline(self): def test_access_log_pipeline(self, wait_for_record):
self.load('empty') self.load('empty')
self.http( self.http(
@@ -75,19 +74,25 @@ Connection: close
) )
assert ( assert (
self.wait_for_record(r'"GET / HTTP/1.1" 200 0 "Referer-1" "-"') wait_for_record(
r'"GET / HTTP/1.1" 200 0 "Referer-1" "-"', 'access.log'
)
is not None is not None
), 'pipeline 1' ), 'pipeline 1'
assert ( assert (
self.wait_for_record(r'"GET / HTTP/1.1" 200 0 "Referer-2" "-"') wait_for_record(
r'"GET / HTTP/1.1" 200 0 "Referer-2" "-"', 'access.log'
)
is not None is not None
), 'pipeline 2' ), 'pipeline 2'
assert ( assert (
self.wait_for_record(r'"GET / HTTP/1.1" 200 0 "Referer-3" "-"') wait_for_record(
r'"GET / HTTP/1.1" 200 0 "Referer-3" "-"', 'access.log'
)
is not None is not None
), 'pipeline 3' ), 'pipeline 3'
def test_access_log_ipv6(self): def test_access_log_ipv6(self, wait_for_record):
self.load('empty') self.load('empty')
assert 'success' in self.conf( assert 'success' in self.conf(
@@ -97,13 +102,13 @@ Connection: close
self.get(sock_type='ipv6') self.get(sock_type='ipv6')
assert ( assert (
self.wait_for_record( wait_for_record(
r'::1 - - \[.+\] "GET / HTTP/1.1" 200 0 "-" "-"' r'::1 - - \[.+\] "GET / HTTP/1.1" 200 0 "-" "-"', 'access.log'
) )
is not None is not None
), 'ipv6' ), 'ipv6'
def test_access_log_unix(self, temp_dir): def test_access_log_unix(self, temp_dir, wait_for_record):
self.load('empty') self.load('empty')
addr = f'{temp_dir}/sock' addr = f'{temp_dir}/sock'
@@ -115,13 +120,13 @@ Connection: close
self.get(sock_type='unix', addr=addr) self.get(sock_type='unix', addr=addr)
assert ( assert (
self.wait_for_record( wait_for_record(
r'unix: - - \[.+\] "GET / HTTP/1.1" 200 0 "-" "-"' r'unix: - - \[.+\] "GET / HTTP/1.1" 200 0 "-" "-"', 'access.log'
) )
is not None is not None
), 'unix' ), 'unix'
def test_access_log_referer(self): def test_access_log_referer(self, wait_for_record):
self.load('empty') self.load('empty')
self.get( self.get(
@@ -133,11 +138,13 @@ Connection: close
) )
assert ( assert (
self.wait_for_record(r'"GET / HTTP/1.1" 200 0 "referer-value" "-"') wait_for_record(
r'"GET / HTTP/1.1" 200 0 "referer-value" "-"', 'access.log'
)
is not None is not None
), 'referer' ), 'referer'
def test_access_log_user_agent(self): def test_access_log_user_agent(self, wait_for_record):
self.load('empty') self.load('empty')
self.get( self.get(
@@ -149,22 +156,23 @@ Connection: close
) )
assert ( assert (
self.wait_for_record( wait_for_record(
r'"GET / HTTP/1.1" 200 0 "-" "user-agent-value"' r'"GET / HTTP/1.1" 200 0 "-" "user-agent-value"', 'access.log'
) )
is not None is not None
), 'user agent' ), 'user agent'
def test_access_log_http10(self): def test_access_log_http10(self, wait_for_record):
self.load('empty') self.load('empty')
self.get(http_10=True) self.get(http_10=True)
assert ( assert (
self.wait_for_record(r'"GET / HTTP/1.0" 200 0 "-" "-"') is not None wait_for_record(r'"GET / HTTP/1.0" 200 0 "-" "-"', 'access.log')
is not None
), 'http 1.0' ), 'http 1.0'
def test_access_log_partial(self): def test_access_log_partial(self, wait_for_record):
self.load('empty') self.load('empty')
assert self.post()['status'] == 200, 'init' assert self.post()['status'] == 200, 'init'
@@ -174,10 +182,10 @@ Connection: close
time.sleep(1) time.sleep(1)
assert ( assert (
self.wait_for_record(r'"-" 400 0 "-" "-"') is not None wait_for_record(r'"-" 400 0 "-" "-"', 'access.log') is not None
), 'partial' ), 'partial'
def test_access_log_partial_2(self): def test_access_log_partial_2(self, wait_for_record):
self.load('empty') self.load('empty')
assert self.post()['status'] == 200, 'init' assert self.post()['status'] == 200, 'init'
@@ -185,10 +193,10 @@ Connection: close
self.http(b"""GET /\n""", raw=True) self.http(b"""GET /\n""", raw=True)
assert ( assert (
self.wait_for_record(r'"-" 400 \d+ "-" "-"') is not None wait_for_record(r'"-" 400 \d+ "-" "-"', 'access.log') is not None
), 'partial 2' ), 'partial 2'
def test_access_log_partial_3(self): def test_access_log_partial_3(self, wait_for_record):
self.load('empty') self.load('empty')
assert self.post()['status'] == 200, 'init' assert self.post()['status'] == 200, 'init'
@@ -198,10 +206,10 @@ Connection: close
time.sleep(1) time.sleep(1)
assert ( assert (
self.wait_for_record(r'"-" 400 0 "-" "-"') is not None wait_for_record(r'"-" 400 0 "-" "-"', 'access.log') is not None
), 'partial 3' ), 'partial 3'
def test_access_log_partial_4(self): def test_access_log_partial_4(self, wait_for_record):
self.load('empty') self.load('empty')
assert self.post()['status'] == 200, 'init' assert self.post()['status'] == 200, 'init'
@@ -211,11 +219,11 @@ Connection: close
time.sleep(1) time.sleep(1)
assert ( assert (
self.wait_for_record(r'"-" 400 0 "-" "-"') is not None wait_for_record(r'"-" 400 0 "-" "-"', 'access.log') is not None
), 'partial 4' ), 'partial 4'
@pytest.mark.skip('not yet') @pytest.mark.skip('not yet')
def test_access_log_partial_5(self): def test_access_log_partial_5(self, wait_for_record):
self.load('empty') self.load('empty')
assert self.post()['status'] == 200, 'init' assert self.post()['status'] == 200, 'init'
@@ -223,32 +231,32 @@ Connection: close
self.get(headers={'Connection': 'close'}) self.get(headers={'Connection': 'close'})
assert ( assert (
self.wait_for_record(r'"GET / HTTP/1.1" 400 \d+ "-" "-"') wait_for_record(r'"GET / HTTP/1.1" 400 \d+ "-" "-"', 'access.log')
is not None is not None
), 'partial 5' ), 'partial 5'
def test_access_log_get_parameters(self): def test_access_log_get_parameters(self, wait_for_record):
self.load('empty') self.load('empty')
self.get(url='/?blah&var=val') self.get(url='/?blah&var=val')
assert ( assert (
self.wait_for_record( wait_for_record(
r'"GET /\?blah&var=val HTTP/1.1" 200 0 "-" "-"' r'"GET /\?blah&var=val HTTP/1.1" 200 0 "-" "-"', 'access.log'
) )
is not None is not None
), 'get parameters' ), 'get parameters'
def test_access_log_delete(self): def test_access_log_delete(self, search_in_file):
self.load('empty') self.load('empty')
assert 'success' in self.conf_delete('access_log') assert 'success' in self.conf_delete('access_log')
self.get(url='/delete') self.get(url='/delete')
assert self.search_in_log(r'/delete', 'access.log') is None, 'delete' assert search_in_file(r'/delete', 'access.log') is None, 'delete'
def test_access_log_change(self, temp_dir): def test_access_log_change(self, temp_dir, wait_for_record):
self.load('empty') self.load('empty')
self.get() self.get()
@@ -258,24 +266,24 @@ Connection: close
self.get() self.get()
assert ( assert (
self.wait_for_record(r'"GET / HTTP/1.1" 200 0 "-" "-"', 'new.log') wait_for_record(r'"GET / HTTP/1.1" 200 0 "-" "-"', 'new.log')
is not None is not None
), 'change' ), 'change'
def test_access_log_format(self): def test_access_log_format(self, wait_for_record):
self.load('empty') self.load('empty')
def check_format(format, expect, url='/'): def check_format(format, expect, url='/'):
self.set_format(format) self.set_format(format)
assert self.get(url=url)['status'] == 200 assert self.get(url=url)['status'] == 200
assert self.wait_for_record(expect) is not None, 'found' assert wait_for_record(expect, 'access.log') is not None, 'found'
format = 'BLAH\t0123456789' format = 'BLAH\t0123456789'
check_format(format, format) check_format(format, format)
check_format('$uri $status $uri $status', '/ 200 / 200') check_format('$uri $status $uri $status', '/ 200 / 200')
def test_access_log_variables(self): def test_access_log_variables(self, wait_for_record):
self.load('mirror') self.load('mirror')
# $body_bytes_sent # $body_bytes_sent
@@ -284,7 +292,7 @@ Connection: close
body = '0123456789' * 50 body = '0123456789' * 50
self.post(url='/bbs', body=body, read_timeout=1) self.post(url='/bbs', body=body, read_timeout=1)
assert ( assert (
self.wait_for_record(fr'^\/bbs {len(body)}$') is not None wait_for_record(fr'^\/bbs {len(body)}$', 'access.log') is not None
), '$body_bytes_sent' ), '$body_bytes_sent'
def test_access_log_incorrect(self, temp_dir, skip_alert): def test_access_log_incorrect(self, temp_dir, skip_alert):

View File

@@ -14,7 +14,7 @@ class TestASGIApplication(TestApplicationPython):
} }
load_module = 'asgi' load_module = 'asgi'
def test_asgi_application_variables(self): def test_asgi_application_variables(self, date_to_sec_epoch, sec_epoch):
self.load('variables') self.load('variables')
body = 'Test body string.' body = 'Test body string.'
@@ -40,9 +40,7 @@ custom-header: BLAH
date = headers.pop('Date') date = headers.pop('Date')
assert date[-4:] == ' GMT', 'date header timezone' assert date[-4:] == ' GMT', 'date header timezone'
assert ( assert abs(date_to_sec_epoch(date) - sec_epoch) < 5, 'date header'
abs(self.date_to_sec_epoch(date) - self.sec_epoch()) < 5
), 'date header'
assert headers == { assert headers == {
'Connection': 'close', 'Connection': 'close',
@@ -382,7 +380,7 @@ Connection: close
assert self.get()['status'] == 503, 'loading error' assert self.get()['status'] == 503, 'loading error'
def test_asgi_application_threading(self): def test_asgi_application_threading(self, wait_for_record):
"""wait_for_record() timeouts after 5s while every thread works at """wait_for_record() timeouts after 5s while every thread works at
least 3s. So without releasing GIL test should fail. least 3s. So without releasing GIL test should fail.
""" """
@@ -393,7 +391,7 @@ Connection: close
self.get(no_recv=True) self.get(no_recv=True)
assert ( assert (
self.wait_for_record(r'\(5\) Thread: 100', wait=50) is not None wait_for_record(r'\(5\) Thread: 100', wait=50) is not None
), 'last thread finished' ), 'last thread finished'
def test_asgi_application_threads(self): def test_asgi_application_threads(self):

View File

@@ -98,27 +98,27 @@ class TestASGILifespan(TestApplicationPython):
self.assert_cookies('') self.assert_cookies('')
self.assert_cookies('app2_') self.assert_cookies('app2_')
def test_asgi_lifespan_failed(self): def test_asgi_lifespan_failed(self, wait_for_record):
self.load('lifespan/failed') self.load('lifespan/failed')
assert self.get()['status'] == 503 assert self.get()['status'] == 503
assert ( assert (
self.wait_for_record(r'\[error\].*Application startup failed') wait_for_record(r'\[error\].*Application startup failed')
is not None is not None
), 'error message' ), 'error message'
assert self.wait_for_record(r'Exception blah') is not None, 'exception' assert wait_for_record(r'Exception blah') is not None, 'exception'
def test_asgi_lifespan_error(self): def test_asgi_lifespan_error(self, wait_for_record):
self.load('lifespan/error') self.load('lifespan/error')
self.get() self.get()
assert self.wait_for_record(r'Exception blah') is not None, 'exception' assert wait_for_record(r'Exception blah') is not None, 'exception'
def test_asgi_lifespan_error_auto(self): def test_asgi_lifespan_error_auto(self, wait_for_record):
self.load('lifespan/error_auto') self.load('lifespan/error_auto')
self.get() self.get()
assert self.wait_for_record(r'AssertionError') is not None, 'assertion' assert wait_for_record(r'AssertionError') is not None, 'assertion'

View File

@@ -5,7 +5,6 @@ import pytest
from packaging import version from packaging import version
from unit.applications.lang.python import TestApplicationPython from unit.applications.lang.python import TestApplicationPython
from unit.applications.websockets import TestApplicationWebsocket from unit.applications.websockets import TestApplicationWebsocket
from unit.option import option
class TestASGIWebsockets(TestApplicationPython): class TestASGIWebsockets(TestApplicationPython):
@@ -1314,7 +1313,7 @@ class TestASGIWebsockets(TestApplicationPython):
self.ws.frame_write(sock, self.ws.OP_CLOSE, payload) self.ws.frame_write(sock, self.ws.OP_CLOSE, payload)
self.check_close(sock, 1002) self.check_close(sock, 1002)
def test_asgi_websockets_9_1_1__9_6_6(self, is_unsafe): def test_asgi_websockets_9_1_1__9_6_6(self, is_unsafe, system):
if not is_unsafe: if not is_unsafe:
pytest.skip('unsafe, long run') pytest.skip('unsafe, long run')
@@ -1371,7 +1370,7 @@ class TestASGIWebsockets(TestApplicationPython):
check_payload(op_binary, 8 * 2**20) # 9_2_5 check_payload(op_binary, 8 * 2**20) # 9_2_5
check_payload(op_binary, 16 * 2**20) # 9_2_6 check_payload(op_binary, 16 * 2**20) # 9_2_6
if option.system != 'Darwin' and option.system != 'FreeBSD': if system not in ['Darwin', 'FreeBSD']:
check_message(op_text, 64) # 9_3_1 check_message(op_text, 64) # 9_3_1
check_message(op_text, 256) # 9_3_2 check_message(op_text, 256) # 9_3_2
check_message(op_text, 2**10) # 9_3_3 check_message(op_text, 2**10) # 9_3_3

View File

@@ -2,7 +2,6 @@ import socket
import pytest import pytest
from unit.control import TestControl from unit.control import TestControl
from unit.option import option
class TestConfiguration(TestControl): class TestConfiguration(TestControl):
@@ -227,8 +226,8 @@ class TestConfiguration(TestControl):
{"*:7080": {"pass": "applications/app"}}, 'listeners' {"*:7080": {"pass": "applications/app"}}, 'listeners'
), 'listeners no app' ), 'listeners no app'
def test_listeners_unix_abstract(self): def test_listeners_unix_abstract(self, system):
if option.system != 'Linux': if system != 'Linux':
assert 'error' in self.try_addr("unix:@sock"), 'abstract at' assert 'error' in self.try_addr("unix:@sock"), 'abstract at'
pytest.skip('not yet') pytest.skip('not yet')

View File

@@ -11,7 +11,7 @@ class TestGoApplication(TestApplicationGo):
def setup_method_fixture(self, skip_alert): def setup_method_fixture(self, skip_alert):
skip_alert(r'\[unit\] close\(\d+\) failed: Bad file descriptor') skip_alert(r'\[unit\] close\(\d+\) failed: Bad file descriptor')
def test_go_application_variables(self): def test_go_application_variables(self, date_to_sec_epoch, sec_epoch):
self.load('variables') self.load('variables')
body = 'Test body string.' body = 'Test body string.'
@@ -33,9 +33,7 @@ class TestGoApplication(TestApplicationGo):
date = headers.pop('Date') date = headers.pop('Date')
assert date[-4:] == ' GMT', 'date header timezone' assert date[-4:] == ' GMT', 'date header timezone'
assert ( assert abs(date_to_sec_epoch(date) - sec_epoch) < 5, 'date header'
abs(self.date_to_sec_epoch(date) - self.sec_epoch()) < 5
), 'date header'
assert headers == { assert headers == {
'Content-Length': str(len(body)), 'Content-Length': str(len(body)),

View File

@@ -128,7 +128,9 @@ class TestJavaApplication(TestApplicationJava):
assert headers['X-Session-New'] == 'false', 'session resume' assert headers['X-Session-New'] == 'false', 'session resume'
assert session_id == headers['X-Session-Id'], 'session same id' assert session_id == headers['X-Session-Id'], 'session same id'
def test_java_application_session_active(self): def test_java_application_session_active(
self, date_to_sec_epoch, sec_epoch
):
self.load('session_inactive') self.load('session_inactive')
resp = self.get( resp = self.get(
@@ -144,10 +146,8 @@ class TestJavaApplication(TestApplicationJava):
assert resp['headers']['X-Session-Interval'] == '4', 'session interval' assert resp['headers']['X-Session-Interval'] == '4', 'session interval'
assert ( assert (
abs( abs(
self.date_to_sec_epoch( date_to_sec_epoch(resp['headers']['X-Session-Last-Access-Time'])
resp['headers']['X-Session-Last-Access-Time'] - sec_epoch
)
- self.sec_epoch()
) )
< 5 < 5
), 'session last access time' ), 'session last access time'
@@ -943,7 +943,7 @@ class TestJavaApplication(TestApplicationJava):
), 'set date header' ), 'set date header'
assert headers['X-Get-Date'] == date, 'get date header' assert headers['X-Get-Date'] == date, 'get date header'
def test_java_application_multipart(self, temp_dir): def test_java_application_multipart(self, search_in_file, temp_dir):
self.load('multipart') self.load('multipart')
reldst = '/uploads' reldst = '/uploads'
@@ -979,7 +979,7 @@ class TestJavaApplication(TestApplicationJava):
assert resp['status'] == 200, 'multipart status' assert resp['status'] == 200, 'multipart status'
assert re.search(r'sample\.txt created', resp['body']), 'multipart body' assert re.search(r'sample\.txt created', resp['body']), 'multipart body'
assert ( assert (
self.search_in_log( search_in_file(
r'^Data from sample file$', name=f'{reldst}/sample.txt' r'^Data from sample file$', name=f'{reldst}/sample.txt'
) )
is not None is not None

View File

@@ -4,7 +4,6 @@ import time
import pytest import pytest
from unit.applications.lang.java import TestApplicationJava from unit.applications.lang.java import TestApplicationJava
from unit.applications.websockets import TestApplicationWebsocket from unit.applications.websockets import TestApplicationWebsocket
from unit.option import option
class TestJavaWebsockets(TestApplicationJava): class TestJavaWebsockets(TestApplicationJava):
@@ -1241,7 +1240,7 @@ class TestJavaWebsockets(TestApplicationJava):
self.ws.frame_write(sock, self.ws.OP_CLOSE, payload) self.ws.frame_write(sock, self.ws.OP_CLOSE, payload)
self.check_close(sock, 1002) self.check_close(sock, 1002)
def test_java_websockets_9_1_1__9_6_6(self, is_unsafe): def test_java_websockets_9_1_1__9_6_6(self, is_unsafe, system):
if not is_unsafe: if not is_unsafe:
pytest.skip('unsafe, long run') pytest.skip('unsafe, long run')
@@ -1298,7 +1297,7 @@ class TestJavaWebsockets(TestApplicationJava):
check_payload(op_binary, 8 * 2**20) # 9_2_5 check_payload(op_binary, 8 * 2**20) # 9_2_5
check_payload(op_binary, 16 * 2**20) # 9_2_6 check_payload(op_binary, 16 * 2**20) # 9_2_6
if option.system != 'Darwin' and option.system != 'FreeBSD': if system not in ['Darwin', 'FreeBSD']:
check_message(op_text, 64) # 9_3_1 check_message(op_text, 64) # 9_3_1
check_message(op_text, 256) # 9_3_2 check_message(op_text, 256) # 9_3_2
check_message(op_text, 2**10) # 9_3_3 check_message(op_text, 2**10) # 9_3_3

View File

@@ -34,7 +34,7 @@ class TestNodeApplication(TestApplicationNode):
assert self.get()['status'] == 200, 'seq' assert self.get()['status'] == 200, 'seq'
assert self.get()['status'] == 200, 'seq 2' assert self.get()['status'] == 200, 'seq 2'
def test_node_application_variables(self): def test_node_application_variables(self, date_to_sec_epoch, sec_epoch):
self.load('variables') self.load('variables')
body = 'Test body string.' body = 'Test body string.'
@@ -56,9 +56,7 @@ class TestNodeApplication(TestApplicationNode):
date = headers.pop('Date') date = headers.pop('Date')
assert date[-4:] == ' GMT', 'date header timezone' assert date[-4:] == ' GMT', 'date header timezone'
assert ( assert abs(date_to_sec_epoch(date) - sec_epoch) < 5, 'date header'
abs(self.date_to_sec_epoch(date) - self.sec_epoch()) < 5
), 'date header'
raw_headers = headers.pop('Request-Raw-Headers') raw_headers = headers.pop('Request-Raw-Headers')
assert re.search( assert re.search(

View File

@@ -4,7 +4,6 @@ import time
import pytest import pytest
from unit.applications.lang.node import TestApplicationNode from unit.applications.lang.node import TestApplicationNode
from unit.applications.websockets import TestApplicationWebsocket from unit.applications.websockets import TestApplicationWebsocket
from unit.option import option
class TestNodeWebsockets(TestApplicationNode): class TestNodeWebsockets(TestApplicationNode):
@@ -1260,7 +1259,7 @@ class TestNodeWebsockets(TestApplicationNode):
self.ws.frame_write(sock, self.ws.OP_CLOSE, payload) self.ws.frame_write(sock, self.ws.OP_CLOSE, payload)
self.check_close(sock, 1002) self.check_close(sock, 1002)
def test_node_websockets_9_1_1__9_6_6(self, is_unsafe): def test_node_websockets_9_1_1__9_6_6(self, is_unsafe, system):
if not is_unsafe: if not is_unsafe:
pytest.skip('unsafe, long run') pytest.skip('unsafe, long run')
@@ -1317,7 +1316,7 @@ class TestNodeWebsockets(TestApplicationNode):
check_payload(op_binary, 8 * 2**20) # 9_2_5 check_payload(op_binary, 8 * 2**20) # 9_2_5
check_payload(op_binary, 16 * 2**20) # 9_2_6 check_payload(op_binary, 16 * 2**20) # 9_2_6
if option.system != 'Darwin' and option.system != 'FreeBSD': if system not in ['Darwin', 'FreeBSD']:
check_message(op_text, 64) # 9_3_1 check_message(op_text, 64) # 9_3_1
check_message(op_text, 256) # 9_3_2 check_message(op_text, 256) # 9_3_2
check_message(op_text, 2**10) # 9_3_3 check_message(op_text, 2**10) # 9_3_3

View File

@@ -7,7 +7,7 @@ from unit.applications.lang.perl import TestApplicationPerl
class TestPerlApplication(TestApplicationPerl): class TestPerlApplication(TestApplicationPerl):
prerequisites = {'modules': {'perl': 'all'}} prerequisites = {'modules': {'perl': 'all'}}
def test_perl_application(self): def test_perl_application(self, date_to_sec_epoch, sec_epoch):
self.load('variables') self.load('variables')
body = 'Test body string.' body = 'Test body string.'
@@ -32,9 +32,7 @@ class TestPerlApplication(TestApplicationPerl):
date = headers.pop('Date') date = headers.pop('Date')
assert date[-4:] == ' GMT', 'date header timezone' assert date[-4:] == ' GMT', 'date header timezone'
assert ( assert abs(date_to_sec_epoch(date) - sec_epoch) < 5, 'date header'
abs(self.date_to_sec_epoch(date) - self.sec_epoch()) < 5
), 'date header'
assert headers == { assert headers == {
'Connection': 'close', 'Connection': 'close',
@@ -128,13 +126,13 @@ class TestPerlApplication(TestApplicationPerl):
body = '0123456789' body = '0123456789'
assert self.post(body=body)['body'] == body, 'input copy' assert self.post(body=body)['body'] == body, 'input copy'
def test_perl_application_errors_print(self): def test_perl_application_errors_print(self, wait_for_record):
self.load('errors_print') self.load('errors_print')
assert self.get()['body'] == '1', 'errors result' assert self.get()['body'] == '1', 'errors result'
assert ( assert (
self.wait_for_record(r'\[error\].+Error in application') is not None wait_for_record(r'\[error\].+Error in application') is not None
), 'errors print' ), 'errors print'
def test_perl_application_header_equal_names(self): def test_perl_application_header_equal_names(self):
@@ -223,19 +221,18 @@ class TestPerlApplication(TestApplicationPerl):
assert resp['body'] == body, 'keep-alive 2' assert resp['body'] == body, 'keep-alive 2'
def test_perl_body_io_fake(self): def test_perl_body_io_fake(self, wait_for_record):
self.load('body_io_fake') self.load('body_io_fake')
assert self.get()['body'] == '21', 'body io fake' assert self.get()['body'] == '21', 'body io fake'
assert ( assert (
self.wait_for_record(r'\[error\].+IOFake getline\(\) \$\/ is \d+') wait_for_record(r'\[error\].+IOFake getline\(\) \$\/ is \d+')
is not None is not None
), 'body io fake $/ value' ), 'body io fake $/ value'
assert ( assert (
self.wait_for_record(r'\[error\].+IOFake close\(\) called') wait_for_record(r'\[error\].+IOFake close\(\) called') is not None
is not None
), 'body io fake close' ), 'body io fake close'
def test_perl_delayed_response(self): def test_perl_delayed_response(self):

View File

@@ -53,7 +53,7 @@ opcache.preload_user = {option.user or getpass.getuser()}
'applications/opcache/options', 'applications/opcache/options',
) )
def test_php_application_variables(self): def test_php_application_variables(self, date_to_sec_epoch, sec_epoch):
self.load('variables') self.load('variables')
body = 'Test body string.' body = 'Test body string.'
@@ -79,9 +79,7 @@ opcache.preload_user = {option.user or getpass.getuser()}
date = headers.pop('Date') date = headers.pop('Date')
assert date[-4:] == ' GMT', 'date header timezone' assert date[-4:] == ' GMT', 'date header timezone'
assert ( assert abs(date_to_sec_epoch(date) - sec_epoch) < 5, 'date header'
abs(self.date_to_sec_epoch(date) - self.sec_epoch()) < 5
), 'date header'
if 'X-Powered-By' in headers: if 'X-Powered-By' in headers:
headers.pop('X-Powered-By') headers.pop('X-Powered-By')
@@ -116,7 +114,7 @@ opcache.preload_user = {option.user or getpass.getuser()}
assert resp['status'] == 200, 'query string empty status' assert resp['status'] == 200, 'query string empty status'
assert resp['headers']['Query-String'] == '', 'query string empty' assert resp['headers']['Query-String'] == '', 'query string empty'
def test_php_application_fastcgi_finish_request(self, unit_pid): def test_php_application_fastcgi_finish_request(self, findall, unit_pid):
self.load('fastcgi_finish_request') self.load('fastcgi_finish_request')
assert 'success' in self.conf( assert 'success' in self.conf(
@@ -128,11 +126,11 @@ opcache.preload_user = {option.user or getpass.getuser()}
os.kill(unit_pid, signal.SIGUSR1) os.kill(unit_pid, signal.SIGUSR1)
errs = self.findall(r'Error in fastcgi_finish_request') errs = findall(r'Error in fastcgi_finish_request')
assert len(errs) == 0, 'no error' assert len(errs) == 0, 'no error'
def test_php_application_fastcgi_finish_request_2(self, unit_pid): def test_php_application_fastcgi_finish_request_2(self, findall, unit_pid):
self.load('fastcgi_finish_request') self.load('fastcgi_finish_request')
assert 'success' in self.conf( assert 'success' in self.conf(
@@ -146,7 +144,7 @@ opcache.preload_user = {option.user or getpass.getuser()}
os.kill(unit_pid, signal.SIGUSR1) os.kill(unit_pid, signal.SIGUSR1)
errs = self.findall(r'Error in fastcgi_finish_request') errs = findall(r'Error in fastcgi_finish_request')
assert len(errs) == 0, 'no error' assert len(errs) == 0, 'no error'
@@ -556,7 +554,7 @@ opcache.preload_user = {option.user or getpass.getuser()}
r'012345', self.get()['body'] r'012345', self.get()['body']
), 'disable_classes before' ), 'disable_classes before'
def test_php_application_error_log(self): def test_php_application_error_log(self, findall, wait_for_record):
self.load('error_log') self.load('error_log')
assert self.get()['status'] == 200, 'status' assert self.get()['status'] == 200, 'status'
@@ -567,9 +565,9 @@ opcache.preload_user = {option.user or getpass.getuser()}
pattern = r'\d{4}\/\d\d\/\d\d\s\d\d:.+\[notice\].+Error in application' pattern = r'\d{4}\/\d\d\/\d\d\s\d\d:.+\[notice\].+Error in application'
assert self.wait_for_record(pattern) is not None, 'errors print' assert wait_for_record(pattern) is not None, 'errors print'
errs = self.findall(pattern) errs = findall(pattern)
assert len(errs) == 2, 'error_log count' assert len(errs) == 2, 'error_log count'

View File

@@ -14,7 +14,7 @@ from unit.applications.lang.python import TestApplicationPython
class TestPythonApplication(TestApplicationPython): class TestPythonApplication(TestApplicationPython):
prerequisites = {'modules': {'python': 'all'}} prerequisites = {'modules': {'python': 'all'}}
def test_python_application_variables(self): def test_python_application_variables(self, date_to_sec_epoch, sec_epoch):
self.load('variables') self.load('variables')
body = 'Test body string.' body = 'Test body string.'
@@ -43,9 +43,7 @@ custom-header: BLAH
date = headers.pop('Date') date = headers.pop('Date')
assert date[-4:] == ' GMT', 'date header timezone' assert date[-4:] == ' GMT', 'date header timezone'
assert ( assert abs(date_to_sec_epoch(date) - sec_epoch) < 5, 'date header'
abs(self.date_to_sec_epoch(date) - self.sec_epoch()) < 5
), 'date header'
assert headers == { assert headers == {
'Connection': 'close', 'Connection': 'close',
@@ -175,7 +173,7 @@ custom-header: BLAH
'Transfer-Encoding' not in self.get()['headers'] 'Transfer-Encoding' not in self.get()['headers']
), '204 header transfer encoding' ), '204 header transfer encoding'
def test_python_application_ctx_iter_atexit(self): def test_python_application_ctx_iter_atexit(self, wait_for_record):
self.load('ctx_iter_atexit') self.load('ctx_iter_atexit')
resp = self.post(body='0123456789') resp = self.post(body='0123456789')
@@ -185,9 +183,7 @@ custom-header: BLAH
assert 'success' in self.conf({"listeners": {}, "applications": {}}) assert 'success' in self.conf({"listeners": {}, "applications": {}})
assert ( assert wait_for_record(r'RuntimeError') is not None, 'ctx iter atexit'
self.wait_for_record(r'RuntimeError') is not None
), 'ctx iter atexit'
def test_python_keepalive_body(self): def test_python_keepalive_body(self):
self.load('mirror') self.load('mirror')
@@ -297,14 +293,14 @@ custom-header: BLAH
assert resp == {}, 'reconfigure 2 keep-alive 3' assert resp == {}, 'reconfigure 2 keep-alive 3'
def test_python_atexit(self): def test_python_atexit(self, wait_for_record):
self.load('atexit') self.load('atexit')
self.get() self.get()
assert 'success' in self.conf({"listeners": {}, "applications": {}}) assert 'success' in self.conf({"listeners": {}, "applications": {}})
assert self.wait_for_record(r'At exit called\.') is not None, 'atexit' assert wait_for_record(r'At exit called\.') is not None, 'atexit'
def test_python_process_switch(self): def test_python_process_switch(self):
self.load('delayed', processes=2) self.load('delayed', processes=2)
@@ -456,14 +452,13 @@ last line: 987654321
assert resp['body'] == body, 'input read length negative' assert resp['body'] == body, 'input read length negative'
@pytest.mark.skip('not yet') @pytest.mark.skip('not yet')
def test_python_application_errors_write(self): def test_python_application_errors_write(self, wait_for_record):
self.load('errors_write') self.load('errors_write')
self.get() self.get()
assert ( assert (
self.wait_for_record(r'\[error\].+Error in application\.') wait_for_record(r'\[error\].+Error in application\.') is not None
is not None
), 'errors write' ), 'errors write'
def test_python_application_body_array(self): def test_python_application_body_array(self):
@@ -495,29 +490,27 @@ last line: 987654321
assert self.get()['status'] == 503, 'loading error' assert self.get()['status'] == 503, 'loading error'
def test_python_application_close(self): def test_python_application_close(self, wait_for_record):
self.load('close') self.load('close')
self.get() self.get()
assert self.wait_for_record(r'Close called\.') is not None, 'close' assert wait_for_record(r'Close called\.') is not None, 'close'
def test_python_application_close_error(self): def test_python_application_close_error(self, wait_for_record):
self.load('close_error') self.load('close_error')
self.get() self.get()
assert ( assert wait_for_record(r'Close called\.') is not None, 'close error'
self.wait_for_record(r'Close called\.') is not None
), 'close error'
def test_python_application_not_iterable(self): def test_python_application_not_iterable(self, wait_for_record):
self.load('not_iterable') self.load('not_iterable')
self.get() self.get()
assert ( assert (
self.wait_for_record( wait_for_record(
r'\[error\].+the application returned not an iterable object' r'\[error\].+the application returned not an iterable object'
) )
is not None is not None
@@ -603,7 +596,7 @@ last line: 987654321
== 200 == 200
) )
def test_python_application_threading(self): def test_python_application_threading(self, wait_for_record):
"""wait_for_record() timeouts after 5s while every thread works at """wait_for_record() timeouts after 5s while every thread works at
least 3s. So without releasing GIL test should fail. least 3s. So without releasing GIL test should fail.
""" """
@@ -614,10 +607,10 @@ last line: 987654321
self.get(no_recv=True) self.get(no_recv=True)
assert ( assert (
self.wait_for_record(r'\(5\) Thread: 100', wait=50) is not None wait_for_record(r'\(5\) Thread: 100', wait=50) is not None
), 'last thread finished' ), 'last thread finished'
def test_python_application_iter_exception(self): def test_python_application_iter_exception(self, findall, wait_for_record):
self.load('iter_exception') self.load('iter_exception')
# Default request doesn't lead to the exception. # Default request doesn't lead to the exception.
@@ -637,12 +630,11 @@ last line: 987654321
assert self.get()['status'] == 503, 'error' assert self.get()['status'] == 503, 'error'
assert self.wait_for_record(r'Traceback') is not None, 'traceback' assert wait_for_record(r'Traceback') is not None, 'traceback'
assert ( assert (
self.wait_for_record(r"raise Exception\('first exception'\)") wait_for_record(r"raise Exception\('first exception'\)") is not None
is not None
), 'first exception raise' ), 'first exception raise'
assert len(self.findall(r'Traceback')) == 1, 'traceback count 1' assert len(findall(r'Traceback')) == 1, 'traceback count 1'
# Exception after start_response(), before first write(). # Exception after start_response(), before first write().
@@ -658,10 +650,10 @@ last line: 987654321
), 'error 2' ), 'error 2'
assert ( assert (
self.wait_for_record(r"raise Exception\('second exception'\)") wait_for_record(r"raise Exception\('second exception'\)")
is not None is not None
), 'exception raise second' ), 'exception raise second'
assert len(self.findall(r'Traceback')) == 2, 'traceback count 2' assert len(findall(r'Traceback')) == 2, 'traceback count 2'
# Exception after first write(), before first __next__(). # Exception after first write(), before first __next__().
@@ -675,10 +667,9 @@ last line: 987654321
) )
assert ( assert (
self.wait_for_record(r"raise Exception\('third exception'\)") wait_for_record(r"raise Exception\('third exception'\)") is not None
is not None
), 'exception raise third' ), 'exception raise third'
assert len(self.findall(r'Traceback')) == 3, 'traceback count 3' assert len(findall(r'Traceback')) == 3, 'traceback count 3'
assert self.get(sock=sock) == {}, 'closed connection' assert self.get(sock=sock) == {}, 'closed connection'
@@ -696,7 +687,7 @@ last line: 987654321
) )
if resp: if resp:
assert resp[-5:] != '0\r\n\r\n', 'incomplete body' assert resp[-5:] != '0\r\n\r\n', 'incomplete body'
assert len(self.findall(r'Traceback')) == 4, 'traceback count 4' assert len(findall(r'Traceback')) == 4, 'traceback count 4'
# Exception in __next__(). # Exception in __next__().
@@ -710,10 +701,9 @@ last line: 987654321
) )
assert ( assert (
self.wait_for_record(r"raise Exception\('next exception'\)") wait_for_record(r"raise Exception\('next exception'\)") is not None
is not None
), 'exception raise next' ), 'exception raise next'
assert len(self.findall(r'Traceback')) == 5, 'traceback count 5' assert len(findall(r'Traceback')) == 5, 'traceback count 5'
assert self.get(sock=sock) == {}, 'closed connection 2' assert self.get(sock=sock) == {}, 'closed connection 2'
@@ -730,7 +720,7 @@ last line: 987654321
) )
if resp: if resp:
assert resp[-5:] != '0\r\n\r\n', 'incomplete body 2' assert resp[-5:] != '0\r\n\r\n', 'incomplete body 2'
assert len(self.findall(r'Traceback')) == 6, 'traceback count 6' assert len(findall(r'Traceback')) == 6, 'traceback count 6'
# Exception before start_response() and in close(). # Exception before start_response() and in close().
@@ -746,10 +736,9 @@ last line: 987654321
), 'error' ), 'error'
assert ( assert (
self.wait_for_record(r"raise Exception\('close exception'\)") wait_for_record(r"raise Exception\('close exception'\)") is not None
is not None
), 'exception raise close' ), 'exception raise close'
assert len(self.findall(r'Traceback')) == 8, 'traceback count 8' assert len(findall(r'Traceback')) == 8, 'traceback count 8'
def test_python_user_group(self, is_su): def test_python_user_group(self, is_su):
if not is_su: if not is_su:

View File

@@ -37,14 +37,11 @@ class TestRewrite(TestApplicationProto):
'routes', 'routes',
) )
def test_rewrite(self): def test_rewrite(self, findall, wait_for_record):
assert self.get()['status'] == 200 assert self.get()['status'] == 200
assert ( assert wait_for_record(rf'\[notice\].*"routes/1" selected') is not None
self.wait_for_record(rf'\[notice\].*"routes/1" selected') assert len(findall(rf'\[notice\].*URI rewritten to "/new"')) == 1
is not None assert len(findall(rf'\[notice\].*URI rewritten')) == 1
)
assert len(self.findall(rf'\[notice\].*URI rewritten to "/new"')) == 1
assert len(self.findall(rf'\[notice\].*URI rewritten')) == 1
self.set_rewrite("", "") self.set_rewrite("", "")
assert self.get()['status'] == 200 assert self.get()['status'] == 200

View File

@@ -8,7 +8,7 @@ from unit.applications.lang.ruby import TestApplicationRuby
class TestRubyApplication(TestApplicationRuby): class TestRubyApplication(TestApplicationRuby):
prerequisites = {'modules': {'ruby': 'all'}} prerequisites = {'modules': {'ruby': 'all'}}
def test_ruby_application(self): def test_ruby_application(self, date_to_sec_epoch, sec_epoch):
self.load('variables') self.load('variables')
body = 'Test body string.' body = 'Test body string.'
@@ -33,9 +33,7 @@ class TestRubyApplication(TestApplicationRuby):
date = headers.pop('Date') date = headers.pop('Date')
assert date[-4:] == ' GMT', 'date header timezone' assert date[-4:] == ' GMT', 'date header timezone'
assert ( assert abs(date_to_sec_epoch(date) - sec_epoch) < 5, 'date header'
abs(self.date_to_sec_epoch(date) - self.sec_epoch()) < 5
), 'date header'
assert headers == { assert headers == {
'Connection': 'close', 'Connection': 'close',
@@ -170,30 +168,30 @@ class TestRubyApplication(TestApplicationRuby):
assert self.get()['status'] == 500, 'syntax error' assert self.get()['status'] == 500, 'syntax error'
def test_ruby_application_errors_puts(self): def test_ruby_application_errors_puts(self, wait_for_record):
self.load('errors_puts') self.load('errors_puts')
assert self.get()['status'] == 200 assert self.get()['status'] == 200
assert ( assert (
self.wait_for_record(r'\[error\].+Error in application') is not None wait_for_record(r'\[error\].+Error in application') is not None
), 'errors puts' ), 'errors puts'
def test_ruby_application_errors_puts_int(self): def test_ruby_application_errors_puts_int(self, wait_for_record):
self.load('errors_puts_int') self.load('errors_puts_int')
assert self.get()['status'] == 200 assert self.get()['status'] == 200
assert ( assert (
self.wait_for_record(r'\[error\].+1234567890') is not None wait_for_record(r'\[error\].+1234567890') is not None
), 'errors puts int' ), 'errors puts int'
def test_ruby_application_errors_write(self): def test_ruby_application_errors_write(self, wait_for_record):
self.load('errors_write') self.load('errors_write')
assert self.get()['status'] == 200 assert self.get()['status'] == 200
assert ( assert (
self.wait_for_record(r'\[error\].+Error in application') is not None wait_for_record(r'\[error\].+Error in application') is not None
), 'errors write' ), 'errors write'
def test_ruby_application_errors_write_to_s_custom(self): def test_ruby_application_errors_write_to_s_custom(self):
@@ -201,15 +199,15 @@ class TestRubyApplication(TestApplicationRuby):
assert self.get()['status'] == 200, 'errors write to_s custom' assert self.get()['status'] == 200, 'errors write to_s custom'
def test_ruby_application_errors_write_int(self): def test_ruby_application_errors_write_int(self, wait_for_record):
self.load('errors_write_int') self.load('errors_write_int')
assert self.get()['status'] == 200 assert self.get()['status'] == 200
assert ( assert (
self.wait_for_record(r'\[error\].+1234567890') is not None wait_for_record(r'\[error\].+1234567890') is not None
), 'errors write int' ), 'errors write int'
def test_ruby_application_at_exit(self): def test_ruby_application_at_exit(self, wait_for_record):
self.load('at_exit') self.load('at_exit')
assert self.get()['status'] == 200 assert self.get()['status'] == 200
@@ -217,7 +215,7 @@ class TestRubyApplication(TestApplicationRuby):
assert 'success' in self.conf({"listeners": {}, "applications": {}}) assert 'success' in self.conf({"listeners": {}, "applications": {}})
assert ( assert (
self.wait_for_record(r'\[error\].+At exit called\.') is not None wait_for_record(r'\[error\].+At exit called\.') is not None
), 'at exit' ), 'at exit'
def test_ruby_application_encoding(self): def test_ruby_application_encoding(self):
@@ -322,14 +320,13 @@ class TestRubyApplication(TestApplicationRuby):
assert self.post(body=body)['body'] == body, 'body large' assert self.post(body=body)['body'] == body, 'body large'
@pytest.mark.skip('not yet') @pytest.mark.skip('not yet')
def test_ruby_application_body_each_error(self): def test_ruby_application_body_each_error(self, wait_for_record):
self.load('body_each_error') self.load('body_each_error')
assert self.get()['status'] == 500, 'body each error status' assert self.get()['status'] == 500, 'body each error status'
assert ( assert (
self.wait_for_record(r'\[error\].+Failed to run ruby script') wait_for_record(r'\[error\].+Failed to run ruby script') is not None
is not None
), 'body each error' ), 'body each error'
def test_ruby_application_body_file(self): def test_ruby_application_body_file(self):

View File

@@ -1,15 +1,25 @@
import re import re
import socket import socket
import subprocess
import time import time
import pytest import pytest
from unit.applications.lang.python import TestApplicationPython from unit.applications.lang.python import TestApplicationPython
from unit.utils import sysctl
class TestSettings(TestApplicationPython): class TestSettings(TestApplicationPython):
prerequisites = {'modules': {'python': 'any'}} prerequisites = {'modules': {'python': 'any'}}
def sysctl(self):
try:
out = subprocess.check_output(
['sysctl', '-a'], stderr=subprocess.STDOUT
).decode()
except FileNotFoundError:
pytest.skip('requires sysctl')
return out
def test_settings_large_header_buffer_size(self): def test_settings_large_header_buffer_size(self):
self.load('empty') self.load('empty')
@@ -263,7 +273,7 @@ Connection: close
return data return data
sysctl_out = sysctl() sysctl_out = self.sysctl()
values = re.findall( values = re.findall(
r'net.core.[rw]mem_(?:max|default).*?(\d+)', sysctl_out r'net.core.[rw]mem_(?:max|default).*?(\d+)', sysctl_out
) )
@@ -409,15 +419,15 @@ Connection: close
assert resp['status'] == 200, 'status 4' assert resp['status'] == 200, 'status 4'
assert resp['body'] == body, 'body 4' assert resp['body'] == body, 'body 4'
def test_settings_log_route(self): def test_settings_log_route(self, findall, search_in_file, wait_for_record):
def count_fallbacks(): def count_fallbacks():
return len(self.findall(r'"fallback" taken')) return len(findall(r'"fallback" taken'))
def check_record(template): def check_record(template):
assert self.search_in_log(template) is not None assert search_in_file(template) is not None
def check_no_record(template): def check_no_record(template):
assert self.search_in_log(template) is None assert search_in_file(template) is None
def template_req_line(url): def template_req_line(url):
return rf'\[notice\].*http request line "GET {url} HTTP/1\.1"' return rf'\[notice\].*http request line "GET {url} HTTP/1\.1"'
@@ -430,8 +440,8 @@ Connection: close
def wait_for_request_log(status, uri, route): def wait_for_request_log(status, uri, route):
assert self.get(url=uri)['status'] == status assert self.get(url=uri)['status'] == status
assert self.wait_for_record(template_req_line(uri)) is not None assert wait_for_record(template_req_line(uri)) is not None
assert self.wait_for_record(template_selected(route)) is not None assert wait_for_record(template_selected(route)) is not None
# routes array # routes array
@@ -559,6 +569,6 @@ Connection: close
# total # total
assert len(self.findall(r'\[notice\].*http request line')) == 7 assert len(findall(r'\[notice\].*http request line')) == 7
assert len(self.findall(r'\[notice\].*selected')) == 10 assert len(findall(r'\[notice\].*selected')) == 10
assert len(self.findall(r'\[info\].*discarded')) == 2 assert len(findall(r'\[info\].*discarded')) == 2

View File

@@ -11,9 +11,6 @@ from unit.option import option
class TestTLS(TestApplicationTLS): class TestTLS(TestApplicationTLS):
prerequisites = {'modules': {'python': 'any', 'openssl': 'any'}} prerequisites = {'modules': {'python': 'any', 'openssl': 'any'}}
def openssl_date_to_sec_epoch(self, date):
return self.date_to_sec_epoch(date, '%b %d %X %Y %Z')
def add_tls(self, application='empty', cert='default', port=7080): def add_tls(self, application='empty', cert='default', port=7080):
assert 'success' in self.conf( assert 'success' in self.conf(
{ {
@@ -254,8 +251,9 @@ basicConstraints = critical,CA:TRUE"""
self.conf_get('/certificates/ec/key') == 'ECDH' self.conf_get('/certificates/ec/key') == 'ECDH'
), 'certificate key ec' ), 'certificate key ec'
def test_tls_certificate_chain_options(self): def test_tls_certificate_chain_options(self, date_to_sec_epoch, sec_epoch):
self.load('empty') self.load('empty')
date_format = '%b %d %X %Y %Z'
self.certificate() self.certificate()
@@ -274,14 +272,14 @@ basicConstraints = critical,CA:TRUE"""
assert ( assert (
abs( abs(
self.sec_epoch() sec_epoch
- self.openssl_date_to_sec_epoch(cert['validity']['since']) - date_to_sec_epoch(cert['validity']['since'], date_format)
) )
< 60 < 60
), 'certificate validity since' ), 'certificate validity since'
assert ( assert (
self.openssl_date_to_sec_epoch(cert['validity']['until']) date_to_sec_epoch(cert['validity']['until'], date_format)
- self.openssl_date_to_sec_epoch(cert['validity']['since']) - date_to_sec_epoch(cert['validity']['since'], date_format)
== 2592000 == 2592000
), 'certificate validity until' ), 'certificate validity until'
@@ -583,7 +581,9 @@ basicConstraints = critical,CA:TRUE"""
'/certificates' '/certificates'
), 'remove all certificates' ), 'remove all certificates'
def test_tls_application_respawn(self, skip_alert): def test_tls_application_respawn(
self, findall, skip_alert, wait_for_record
):
self.load('mirror') self.load('mirror')
self.certificate() self.certificate()
@@ -602,13 +602,13 @@ basicConstraints = critical,CA:TRUE"""
read_timeout=1, read_timeout=1,
) )
app_id = self.findall(r'(\d+)#\d+ "mirror" application started')[0] app_id = findall(r'(\d+)#\d+ "mirror" application started')[0]
subprocess.check_output(['kill', '-9', app_id]) subprocess.check_output(['kill', '-9', app_id])
skip_alert(fr'process {app_id} exited on signal 9') skip_alert(fr'process {app_id} exited on signal 9')
self.wait_for_record( wait_for_record(
fr' (?!{app_id}#)(\d+)#\d+ "mirror" application started' fr' (?!{app_id}#)(\d+)#\d+ "mirror" application started'
) )

View File

@@ -19,9 +19,6 @@ class TestTLSSNI(TestApplicationTLS):
} }
) )
def openssl_date_to_sec_epoch(self, date):
return self.date_to_sec_epoch(date, '%b %d %X %Y %Z')
def add_tls(self, cert='default'): def add_tls(self, cert='default'):
assert 'success' in self.conf( assert 'success' in self.conf(
{"pass": "routes", "tls": {"certificate": cert}}, {"pass": "routes", "tls": {"certificate": cert}},

View File

@@ -9,7 +9,9 @@ from unit.utils import waitforfiles
class TestUSR1(TestApplicationPython): class TestUSR1(TestApplicationPython):
prerequisites = {'modules': {'python': 'any'}} prerequisites = {'modules': {'python': 'any'}}
def test_usr1_access_log(self, temp_dir, unit_pid): def test_usr1_access_log(
self, search_in_file, temp_dir, unit_pid, wait_for_record
):
self.load('empty') self.load('empty')
log = 'access.log' log = 'access.log'
@@ -27,7 +29,7 @@ class TestUSR1(TestApplicationPython):
assert self.get()['status'] == 200 assert self.get()['status'] == 200
assert ( assert (
self.wait_for_record(r'"GET / HTTP/1.1" 200 0 "-" "-"', log_new) wait_for_record(r'"GET / HTTP/1.1" 200 0 "-" "-"', log_new)
is not None is not None
), 'rename new' ), 'rename new'
assert not os.path.isfile(log_path), 'rename old' assert not os.path.isfile(log_path), 'rename old'
@@ -39,12 +41,14 @@ class TestUSR1(TestApplicationPython):
assert self.get(url='/usr1')['status'] == 200 assert self.get(url='/usr1')['status'] == 200
assert ( assert (
self.wait_for_record(r'"GET /usr1 HTTP/1.1" 200 0 "-" "-"', log) wait_for_record(r'"GET /usr1 HTTP/1.1" 200 0 "-" "-"', log)
is not None is not None
), 'reopen 2' ), 'reopen 2'
assert self.search_in_log(r'/usr1', log_new) is None, 'rename new 2' assert search_in_file(r'/usr1', log_new) is None, 'rename new 2'
def test_usr1_unit_log(self, temp_dir, unit_pid): def test_usr1_unit_log(
self, search_in_file, temp_dir, unit_pid, wait_for_record
):
self.load('log_body') self.load('log_body')
log_new = 'new.log' log_new = 'new.log'
@@ -59,7 +63,7 @@ class TestUSR1(TestApplicationPython):
body = 'body_for_a_log_new\n' body = 'body_for_a_log_new\n'
assert self.post(body=body)['status'] == 200 assert self.post(body=body)['status'] == 200
assert self.wait_for_record(body, log_new) is not None, 'rename new' assert wait_for_record(body, log_new) is not None, 'rename new'
assert not os.path.isfile(log_path), 'rename old' assert not os.path.isfile(log_path), 'rename old'
os.kill(unit_pid, signal.SIGUSR1) os.kill(unit_pid, signal.SIGUSR1)
@@ -69,8 +73,8 @@ class TestUSR1(TestApplicationPython):
body = 'body_for_a_log_unit\n' body = 'body_for_a_log_unit\n'
assert self.post(body=body)['status'] == 200 assert self.post(body=body)['status'] == 200
assert self.wait_for_record(body) is not None, 'rename new' assert wait_for_record(body) is not None, 'rename new'
assert self.search_in_log(body, log_new) is None, 'rename new 2' assert search_in_file(body, log_new) is None, 'rename new 2'
finally: finally:
# merge two log files into unit.log to check alerts # merge two log files into unit.log to check alerts

View File

@@ -27,12 +27,6 @@ class TestVariables(TestApplicationProto):
'access_log', 'access_log',
), 'access_log format' ), 'access_log format'
def wait_for_record(self, pattern, name='access.log'):
return super().wait_for_record(pattern, name)
def search_in_log(self, pattern, name='access.log'):
return super().search_in_log(pattern, name)
def test_variables_dollar(self): def test_variables_dollar(self):
assert 'success' in self.conf("301", 'routes/0/action/return') assert 'success' in self.conf("301", 'routes/0/action/return')
@@ -49,7 +43,7 @@ class TestVariables(TestApplicationProto):
) )
check_dollar('path$dollar${dollar}', 'path$$') check_dollar('path$dollar${dollar}', 'path$$')
def test_variables_request_time(self): def test_variables_request_time(self, wait_for_record):
self.set_format('$uri $request_time') self.set_format('$uri $request_time')
sock = self.http(b'', raw=True, no_recv=True) sock = self.http(b'', raw=True, no_recv=True)
@@ -57,7 +51,7 @@ class TestVariables(TestApplicationProto):
time.sleep(1) time.sleep(1)
assert self.get(url='/r_time_1', sock=sock)['status'] == 200 assert self.get(url='/r_time_1', sock=sock)['status'] == 200
assert self.wait_for_record(r'\/r_time_1 0\.\d{3}') is not None assert wait_for_record(r'\/r_time_1 0\.\d{3}', 'access.log') is not None
sock = self.http( sock = self.http(
b"""G""", b"""G""",
@@ -76,67 +70,70 @@ Connection: close
sock=sock, sock=sock,
raw=True, raw=True,
) )
assert self.wait_for_record(r'\/r_time_2 [1-9]\.\d{3}') is not None assert (
wait_for_record(r'\/r_time_2 [1-9]\.\d{3}', 'access.log')
is not None
)
def test_variables_method(self): def test_variables_method(self, search_in_file, wait_for_record):
self.set_format('$method') self.set_format('$method')
reg = r'^GET$' reg = r'^GET$'
assert self.search_in_log(reg) is None assert search_in_file(reg, 'access.log') is None
assert self.get()['status'] == 200 assert self.get()['status'] == 200
assert self.wait_for_record(reg) is not None, 'method GET' assert wait_for_record(reg, 'access.log') is not None, 'method GET'
reg = r'^POST$' reg = r'^POST$'
assert self.search_in_log(reg) is None assert search_in_file(reg, 'access.log') is None
assert self.post()['status'] == 200 assert self.post()['status'] == 200
assert self.wait_for_record(reg) is not None, 'method POST' assert wait_for_record(reg, 'access.log') is not None, 'method POST'
def test_variables_request_uri(self): def test_variables_request_uri(self, search_in_file, wait_for_record):
self.set_format('$request_uri') self.set_format('$request_uri')
def check_request_uri(req_uri): def check_request_uri(req_uri):
reg = fr'^{re.escape(req_uri)}$' reg = fr'^{re.escape(req_uri)}$'
assert self.search_in_log(reg) is None assert search_in_file(reg, 'access.log') is None
assert self.get(url=req_uri)['status'] == 200 assert self.get(url=req_uri)['status'] == 200
assert self.wait_for_record(reg) is not None assert wait_for_record(reg, 'access.log') is not None
check_request_uri('/3') check_request_uri('/3')
check_request_uri('/4*') check_request_uri('/4*')
check_request_uri('/4%2A') check_request_uri('/4%2A')
check_request_uri('/9?q#a') check_request_uri('/9?q#a')
def test_variables_uri(self): def test_variables_uri(self, search_in_file, wait_for_record):
self.set_format('$uri') self.set_format('$uri')
def check_uri(uri, expect=None): def check_uri(uri, expect=None):
expect = uri if expect is None else expect expect = uri if expect is None else expect
reg = fr'^{re.escape(expect)}$' reg = fr'^{re.escape(expect)}$'
assert self.search_in_log(reg) is None assert search_in_file(reg, 'access.log') is None
assert self.get(url=uri)['status'] == 200 assert self.get(url=uri)['status'] == 200
assert self.wait_for_record(reg) is not None assert wait_for_record(reg, 'access.log') is not None
check_uri('/3') check_uri('/3')
check_uri('/4*') check_uri('/4*')
check_uri('/5%2A', '/5*') check_uri('/5%2A', '/5*')
check_uri('/9?q#a', '/9') check_uri('/9?q#a', '/9')
def test_variables_host(self): def test_variables_host(self, search_in_file, wait_for_record):
self.set_format('$host') self.set_format('$host')
def check_host(host, expect=None): def check_host(host, expect=None):
expect = host if expect is None else expect expect = host if expect is None else expect
reg = fr'^{re.escape(expect)}$' reg = fr'^{re.escape(expect)}$'
assert self.search_in_log(reg) is None assert search_in_file(reg, 'access.log') is None
assert ( assert (
self.get(headers={'Host': host, 'Connection': 'close'})[ self.get(headers={'Host': host, 'Connection': 'close'})[
'status' 'status'
] ]
== 200 == 200
) )
assert self.wait_for_record(reg) is not None assert wait_for_record(reg, 'access.log') is not None
check_host('localhost') check_host('localhost')
check_host('localhost1.', 'localhost1') check_host('localhost1.', 'localhost1')
@@ -144,63 +141,67 @@ Connection: close
check_host('.localhost') check_host('.localhost')
check_host('www.localhost') check_host('www.localhost')
def test_variables_remote_addr(self): def test_variables_remote_addr(self, search_in_file, wait_for_record):
self.set_format('$remote_addr') self.set_format('$remote_addr')
assert self.get()['status'] == 200 assert self.get()['status'] == 200
assert self.wait_for_record(r'^127\.0\.0\.1$') is not None assert wait_for_record(r'^127\.0\.0\.1$', 'access.log') is not None
assert 'success' in self.conf( assert 'success' in self.conf(
{"[::1]:7080": {"pass": "routes"}}, 'listeners' {"[::1]:7080": {"pass": "routes"}}, 'listeners'
) )
reg = r'^::1$' reg = r'^::1$'
assert self.search_in_log(reg) is None assert search_in_file(reg, 'access.log') is None
assert self.get(sock_type='ipv6')['status'] == 200 assert self.get(sock_type='ipv6')['status'] == 200
assert self.wait_for_record(reg) is not None assert wait_for_record(reg, 'access.log') is not None
def test_variables_time_local(self): def test_variables_time_local(
self, date_to_sec_epoch, search_in_file, wait_for_record
):
self.set_format('$uri $time_local $uri') self.set_format('$uri $time_local $uri')
assert self.search_in_log(r'/time_local') is None assert search_in_file(r'/time_local', 'access.log') is None
assert self.get(url='/time_local')['status'] == 200 assert self.get(url='/time_local')['status'] == 200
assert self.wait_for_record(r'/time_local') is not None, 'time log' assert (
date = self.search_in_log( wait_for_record(r'/time_local', 'access.log') is not None
), 'time log'
date = search_in_file(
r'^\/time_local (.*) \/time_local$', 'access.log' r'^\/time_local (.*) \/time_local$', 'access.log'
)[1] )[1]
assert ( assert (
abs( abs(
self.date_to_sec_epoch(date, '%d/%b/%Y:%X %z') date_to_sec_epoch(date, '%d/%b/%Y:%X %z')
- time.mktime(time.localtime()) - time.mktime(time.localtime())
) )
< 5 < 5
), '$time_local' ), '$time_local'
def test_variables_request_line(self): def test_variables_request_line(self, search_in_file, wait_for_record):
self.set_format('$request_line') self.set_format('$request_line')
reg = r'^GET \/r_line HTTP\/1\.1$' reg = r'^GET \/r_line HTTP\/1\.1$'
assert self.search_in_log(reg) is None assert search_in_file(reg, 'access.log') is None
assert self.get(url='/r_line')['status'] == 200 assert self.get(url='/r_line')['status'] == 200
assert self.wait_for_record(reg) is not None assert wait_for_record(reg, 'access.log') is not None
def test_variables_status(self): def test_variables_status(self, search_in_file, wait_for_record):
self.set_format('$status') self.set_format('$status')
assert 'success' in self.conf("418", 'routes/0/action/return') assert 'success' in self.conf("418", 'routes/0/action/return')
reg = r'^418$' reg = r'^418$'
assert self.search_in_log(reg) is None assert search_in_file(reg, 'access.log') is None
assert self.get()['status'] == 418 assert self.get()['status'] == 418
assert self.wait_for_record(reg) is not None assert wait_for_record(reg, 'access.log') is not None
def test_variables_header_referer(self): def test_variables_header_referer(self, search_in_file, wait_for_record):
self.set_format('$method $header_referer') self.set_format('$method $header_referer')
def check_referer(referer): def check_referer(referer):
reg = fr'^GET {re.escape(referer)}$' reg = fr'^GET {re.escape(referer)}$'
assert self.search_in_log(reg) is None assert search_in_file(reg, 'access.log') is None
assert ( assert (
self.get( self.get(
headers={ headers={
@@ -211,19 +212,19 @@ Connection: close
)['status'] )['status']
== 200 == 200
) )
assert self.wait_for_record(reg) is not None assert wait_for_record(reg, 'access.log') is not None
check_referer('referer-value') check_referer('referer-value')
check_referer('') check_referer('')
check_referer('no') check_referer('no')
def test_variables_header_user_agent(self): def test_variables_header_user_agent(self, search_in_file, wait_for_record):
self.set_format('$method $header_user_agent') self.set_format('$method $header_user_agent')
def check_user_agent(user_agent): def check_user_agent(user_agent):
reg = fr'^GET {re.escape(user_agent)}$' reg = fr'^GET {re.escape(user_agent)}$'
assert self.search_in_log(reg) is None assert search_in_file(reg, 'access.log') is None
assert ( assert (
self.get( self.get(
headers={ headers={
@@ -234,19 +235,19 @@ Connection: close
)['status'] )['status']
== 200 == 200
) )
assert self.wait_for_record(reg) is not None assert wait_for_record(reg, 'access.log') is not None
check_user_agent('MSIE') check_user_agent('MSIE')
check_user_agent('') check_user_agent('')
check_user_agent('no') check_user_agent('no')
def test_variables_many(self): def test_variables_many(self, search_in_file, wait_for_record):
def check_vars(uri, expect): def check_vars(uri, expect):
reg = fr'^{re.escape(expect)}$' reg = fr'^{re.escape(expect)}$'
assert self.search_in_log(reg) is None assert search_in_file(reg, 'access.log') is None
assert self.get(url=uri)['status'] == 200 assert self.get(url=uri)['status'] == 200
assert self.wait_for_record(reg) is not None assert wait_for_record(reg, 'access.log') is not None
self.set_format('$uri$method') self.set_format('$uri$method')
check_vars('/1', '/1GET') check_vars('/1', '/1GET')
@@ -260,7 +261,7 @@ Connection: close
self.set_format('$method$method') self.set_format('$method$method')
check_vars('/', 'GETGET') check_vars('/', 'GETGET')
def test_variables_dynamic(self): def test_variables_dynamic(self, wait_for_record):
self.set_format('$header_foo$cookie_foo$arg_foo') self.set_format('$header_foo$cookie_foo$arg_foo')
assert ( assert (
@@ -270,20 +271,20 @@ Connection: close
)['status'] )['status']
== 200 == 200
) )
assert self.wait_for_record(r'^blah$') is not None assert wait_for_record(r'^blah$', 'access.log') is not None
def test_variables_dynamic_arguments(self): def test_variables_dynamic_arguments(self, search_in_file, wait_for_record):
def check_arg(url, expect=None): def check_arg(url, expect=None):
expect = url if expect is None else expect expect = url if expect is None else expect
reg = fr'^{re.escape(expect)}$' reg = fr'^{re.escape(expect)}$'
assert self.search_in_log(reg) is None assert search_in_file(reg, 'access.log') is None
assert self.get(url=url)['status'] == 200 assert self.get(url=url)['status'] == 200
assert self.wait_for_record(reg) is not None assert wait_for_record(reg, 'access.log') is not None
def check_no_arg(url): def check_no_arg(url):
assert self.get(url=url)['status'] == 200 assert self.get(url=url)['status'] == 200
assert self.search_in_log(r'^0$') is None assert search_in_file(r'^0$', 'access.log') is None
self.set_format('$arg_foo_bar') self.set_format('$arg_foo_bar')
check_arg('/?foo_bar=1', '1') check_arg('/?foo_bar=1', '1')
@@ -304,25 +305,25 @@ Connection: close
check_no_arg('/?f=0') check_no_arg('/?f=0')
check_no_arg('/?f!~=0') check_no_arg('/?f!~=0')
def test_variables_dynamic_headers(self): def test_variables_dynamic_headers(self, search_in_file, wait_for_record):
def check_header(header, value): def check_header(header, value):
reg = fr'^{value}$' reg = fr'^{value}$'
assert self.search_in_log(reg) is None assert search_in_file(reg, 'access.log') is None
assert ( assert (
self.get(headers={header: value, 'Connection': 'close'})[ self.get(headers={header: value, 'Connection': 'close'})[
'status' 'status'
] ]
== 200 == 200
) )
assert self.wait_for_record(reg) is not None assert wait_for_record(reg, 'access.log') is not None
def check_no_header(header): def check_no_header(header):
assert ( assert (
self.get(headers={header: '0', 'Connection': 'close'})['status'] self.get(headers={header: '0', 'Connection': 'close'})['status']
== 200 == 200
) )
assert self.search_in_log(r'^0$') is None assert search_in_file(r'^0$', 'access.log') is None
self.set_format('$header_foo_bar') self.set_format('$header_foo_bar')
check_header('foo-bar', '1') check_header('foo-bar', '1')
@@ -336,7 +337,7 @@ Connection: close
check_no_header('foo_bar') check_no_header('foo_bar')
check_no_header('foobar') check_no_header('foobar')
def test_variables_dynamic_cookies(self): def test_variables_dynamic_cookies(self, search_in_file, wait_for_record):
def check_no_cookie(cookie): def check_no_cookie(cookie):
assert ( assert (
self.get( self.get(
@@ -348,12 +349,12 @@ Connection: close
)['status'] )['status']
== 200 == 200
) )
assert self.search_in_log(r'^0$') is None assert search_in_file(r'^0$', 'access.log') is None
self.set_format('$cookie_foo_bar') self.set_format('$cookie_foo_bar')
reg = r'^1$' reg = r'^1$'
assert self.search_in_log(reg) is None assert search_in_file(reg, 'access.log') is None
assert ( assert (
self.get( self.get(
headers={ headers={
@@ -364,7 +365,7 @@ Connection: close
)['status'] )['status']
== 200 == 200
) )
assert self.wait_for_record(reg) is not None assert wait_for_record(reg, 'access.log') is not None
check_no_cookie('fOo_bar=0') check_no_cookie('fOo_bar=0')
check_no_cookie('foo_bar=') check_no_cookie('foo_bar=')

View File

@@ -10,30 +10,6 @@ from unit.option import option
class TestApplicationProto(TestControl): class TestApplicationProto(TestControl):
application_type = None application_type = None
def sec_epoch(self):
return time.mktime(time.gmtime())
def date_to_sec_epoch(self, date, template='%a, %d %b %Y %X %Z'):
return time.mktime(time.strptime(date, template))
def findall(self, pattern, name='unit.log', flags=re.M):
return re.findall(pattern, Log.read(name), flags)
def search_in_log(self, pattern, name='unit.log', flags=re.M):
return re.search(pattern, Log.read(name), flags)
def wait_for_record(self, pattern, name='unit.log', wait=150, flags=re.M):
with Log.open(name) as f:
for _ in range(wait):
found = re.search(pattern, f.read(), flags)
if found is not None:
break
time.sleep(0.1)
return found
def get_application_type(self): def get_application_type(self):
current_test = ( current_test = (
os.environ.get('PYTEST_CURRENT_TEST').split(':')[-1].split(' ')[0] os.environ.get('PYTEST_CURRENT_TEST').split(':')[-1].split(' ')[0]

View File

@@ -1,7 +1,13 @@
import os
import platform
class Options: class Options:
_options = { _options = {
'architecture': platform.architecture()[0],
'is_privileged': os.geteuid() == 0,
'skip_alerts': [], 'skip_alerts': [],
'skip_sanitizer': False, 'skip_sanitizer': False,
'system': platform.system()
} }
def __setattr__(self, name, value): def __setattr__(self, name, value):

View File

@@ -90,17 +90,6 @@ def findmnt():
return out return out
def sysctl():
try:
out = subprocess.check_output(
['sysctl', '-a'], stderr=subprocess.STDOUT
).decode()
except FileNotFoundError:
pytest.skip('requires sysctl')
return out
def waitformount(template, timeout=50): def waitformount(template, timeout=50):
for _ in range(timeout): for _ in range(timeout):
if findmnt().find(template) != -1: if findmnt().find(template) != -1: