summaryrefslogtreecommitdiffhomepage
path: root/test/unit
diff options
context:
space:
mode:
Diffstat (limited to 'test/unit')
-rw-r--r--test/unit/applications/lang/go.py6
-rw-r--r--test/unit/applications/lang/java.py9
-rw-r--r--test/unit/applications/lang/node.py9
-rw-r--r--test/unit/applications/lang/perl.py7
-rw-r--r--test/unit/applications/lang/php.py7
-rw-r--r--test/unit/applications/lang/python.py9
-rw-r--r--test/unit/applications/lang/ruby.py7
-rw-r--r--test/unit/applications/proto.py33
-rw-r--r--test/unit/applications/tls.py18
-rw-r--r--test/unit/applications/websockets.py4
-rw-r--r--test/unit/check/check_prerequisites.py63
-rw-r--r--test/unit/check/chroot.py44
-rw-r--r--test/unit/check/discover_available.py47
-rw-r--r--test/unit/check/go.py5
-rw-r--r--test/unit/check/isolation.py37
-rw-r--r--test/unit/check/njs.py3
-rw-r--r--test/unit/check/node.py10
-rw-r--r--test/unit/check/regex.py5
-rw-r--r--test/unit/check/tls.py5
-rw-r--r--test/unit/check/unix_abstract.py34
-rw-r--r--test/unit/control.py4
-rw-r--r--test/unit/http.py2
-rw-r--r--test/unit/log.py104
-rw-r--r--test/unit/option.py8
-rw-r--r--test/unit/status.py4
-rw-r--r--test/unit/utils.py23
26 files changed, 338 insertions, 169 deletions
diff --git a/test/unit/applications/lang/go.py b/test/unit/applications/lang/go.py
index 557753a4..93e0738b 100644
--- a/test/unit/applications/lang/go.py
+++ b/test/unit/applications/lang/go.py
@@ -2,11 +2,11 @@ import os
import shutil
import subprocess
-from unit.applications.proto import TestApplicationProto
+from unit.applications.proto import ApplicationProto
from unit.option import option
-class TestApplicationGo(TestApplicationProto):
+class ApplicationGo(ApplicationProto):
@staticmethod
def prepare_env(script, name='app', static=False):
try:
@@ -88,7 +88,7 @@ replace unit.nginx.org/go => {replace_path}
executable = f"/go/{name}"
static_build = True
- TestApplicationGo.prepare_env(script, name, static=static_build)
+ ApplicationGo.prepare_env(script, name, static=static_build)
conf = {
"listeners": {"*:7080": {"pass": f"applications/{script}"}},
diff --git a/test/unit/applications/lang/java.py b/test/unit/applications/lang/java.py
index b6382cfe..a253aea5 100644
--- a/test/unit/applications/lang/java.py
+++ b/test/unit/applications/lang/java.py
@@ -4,12 +4,13 @@ import shutil
import subprocess
import pytest
-from unit.applications.proto import TestApplicationProto
+from unit.applications.proto import ApplicationProto
from unit.option import option
-class TestApplicationJava(TestApplicationProto):
- application_type = "java"
+class ApplicationJava(ApplicationProto):
+ def __init__(self, application_type='java'):
+ self.application_type = application_type
def prepare_env(self, script):
app_path = f'{option.temp_dir}/java'
@@ -52,7 +53,7 @@ class TestApplicationJava(TestApplicationProto):
os.makedirs(classes_path)
classpath = (
- f'{option.current_dir}/build/tomcat-servlet-api-9.0.70.jar'
+ f'{option.current_dir}/build/tomcat-servlet-api-9.0.75.jar'
)
ws_jars = glob.glob(
diff --git a/test/unit/applications/lang/node.py b/test/unit/applications/lang/node.py
index 87d5a19c..4f18c780 100644
--- a/test/unit/applications/lang/node.py
+++ b/test/unit/applications/lang/node.py
@@ -1,14 +1,15 @@
import shutil
from urllib.parse import quote
-from unit.applications.proto import TestApplicationProto
+from unit.applications.proto import ApplicationProto
from unit.option import option
from unit.utils import public_dir
-class TestApplicationNode(TestApplicationProto):
- application_type = "node"
- es_modules = False
+class ApplicationNode(ApplicationProto):
+ def __init__(self, application_type='node', es_modules=False):
+ self.application_type = application_type
+ self.es_modules = es_modules
def prepare_env(self, script):
# copy application
diff --git a/test/unit/applications/lang/perl.py b/test/unit/applications/lang/perl.py
index 19852363..037e98e8 100644
--- a/test/unit/applications/lang/perl.py
+++ b/test/unit/applications/lang/perl.py
@@ -1,9 +1,10 @@
-from unit.applications.proto import TestApplicationProto
+from unit.applications.proto import ApplicationProto
from unit.option import option
-class TestApplicationPerl(TestApplicationProto):
- application_type = "perl"
+class ApplicationPerl(ApplicationProto):
+ def __init__(self, application_type='perl'):
+ self.application_type = application_type
def load(self, script, name='psgi.pl', **kwargs):
script_path = f'{option.test_dir}/perl/{script}'
diff --git a/test/unit/applications/lang/php.py b/test/unit/applications/lang/php.py
index 1b94c3ae..b9b6dbf1 100644
--- a/test/unit/applications/lang/php.py
+++ b/test/unit/applications/lang/php.py
@@ -1,12 +1,13 @@
import os
import shutil
-from unit.applications.proto import TestApplicationProto
+from unit.applications.proto import ApplicationProto
from unit.option import option
-class TestApplicationPHP(TestApplicationProto):
- application_type = "php"
+class ApplicationPHP(ApplicationProto):
+ def __init__(self, application_type='php'):
+ self.application_type = application_type
def load(self, script, index='index.php', **kwargs):
script_path = f'{option.test_dir}/php/{script}'
diff --git a/test/unit/applications/lang/python.py b/test/unit/applications/lang/python.py
index 0bb69992..4e1fd897 100644
--- a/test/unit/applications/lang/python.py
+++ b/test/unit/applications/lang/python.py
@@ -2,13 +2,14 @@ import os
import shutil
from urllib.parse import quote
-from unit.applications.proto import TestApplicationProto
+from unit.applications.proto import ApplicationProto
from unit.option import option
-class TestApplicationPython(TestApplicationProto):
- application_type = "python"
- load_module = "wsgi"
+class ApplicationPython(ApplicationProto):
+ def __init__(self, application_type='python', load_module='wsgi'):
+ self.application_type = application_type
+ self.load_module = load_module
def load(self, script, name=None, module=None, **kwargs):
if name is None:
diff --git a/test/unit/applications/lang/ruby.py b/test/unit/applications/lang/ruby.py
index e0712fc6..f6c4f6c3 100644
--- a/test/unit/applications/lang/ruby.py
+++ b/test/unit/applications/lang/ruby.py
@@ -1,12 +1,13 @@
import shutil
-from unit.applications.proto import TestApplicationProto
+from unit.applications.proto import ApplicationProto
from unit.option import option
from unit.utils import public_dir
-class TestApplicationRuby(TestApplicationProto):
- application_type = "ruby"
+class ApplicationRuby(ApplicationProto):
+ def __init__(self, application_type='ruby'):
+ self.application_type = application_type
def prepare_env(self, script):
shutil.copytree(
diff --git a/test/unit/applications/proto.py b/test/unit/applications/proto.py
index f04ee408..7a1636c6 100644
--- a/test/unit/applications/proto.py
+++ b/test/unit/applications/proto.py
@@ -1,41 +1,12 @@
import os
-import re
-import time
-from unit.control import TestControl
-from unit.log import Log
+from unit.control import Control
from unit.option import option
-class TestApplicationProto(TestControl):
+class ApplicationProto(Control):
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):
- with Log.open(name) as f:
- return re.findall(pattern, f.read(), flags)
-
- def search_in_log(self, pattern, name='unit.log', flags=re.M):
- with Log.open(name) as f:
- return re.search(pattern, f.read(), flags)
-
- def wait_for_record(self, pattern, name='unit.log', wait=150, flags=re.M):
- with Log.open(name) as f:
- for i 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):
current_test = (
os.environ.get('PYTEST_CURRENT_TEST').split(':')[-1].split(' ')[0]
diff --git a/test/unit/applications/tls.py b/test/unit/applications/tls.py
index e5813312..e9bcc514 100644
--- a/test/unit/applications/tls.py
+++ b/test/unit/applications/tls.py
@@ -2,15 +2,15 @@ import os
import ssl
import subprocess
-from unit.applications.proto import TestApplicationProto
+from unit.applications.proto import ApplicationProto
from unit.option import option
-class TestApplicationTLS(TestApplicationProto):
- def setup_method(self):
- self.context = ssl.create_default_context()
- self.context.check_hostname = False
- self.context.verify_mode = ssl.CERT_NONE
+class ApplicationTLS(ApplicationProto):
+ def __init__(self):
+ self._default_context = ssl.create_default_context()
+ self._default_context.check_hostname = False
+ self._default_context.verify_mode = ssl.CERT_NONE
def certificate(self, name='default', load=True):
self.openssl_conf()
@@ -47,10 +47,12 @@ class TestApplicationTLS(TestApplicationProto):
return self.conf(k.read() + c.read(), f'/certificates/{crt}')
def get_ssl(self, **kwargs):
- return self.get(wrapper=self.context.wrap_socket, **kwargs)
+ context = kwargs.get('context', self._default_context)
+ return self.get(wrapper=context.wrap_socket, **kwargs)
def post_ssl(self, **kwargs):
- return self.post(wrapper=self.context.wrap_socket, **kwargs)
+ context = kwargs.get('context', self._default_context)
+ return self.post(wrapper=context.wrap_socket, **kwargs)
def openssl_conf(self, rewrite=False, alt_names=None):
alt_names = alt_names or []
diff --git a/test/unit/applications/websockets.py b/test/unit/applications/websockets.py
index a4b9287d..29725943 100644
--- a/test/unit/applications/websockets.py
+++ b/test/unit/applications/websockets.py
@@ -6,12 +6,12 @@ import select
import struct
import pytest
-from unit.applications.proto import TestApplicationProto
+from unit.applications.proto import ApplicationProto
GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
-class TestApplicationWebsocket(TestApplicationProto):
+class ApplicationWebsocket(ApplicationProto):
OP_CONT = 0x00
OP_TEXT = 0x01
diff --git a/test/unit/check/check_prerequisites.py b/test/unit/check/check_prerequisites.py
new file mode 100644
index 00000000..44c3f10f
--- /dev/null
+++ b/test/unit/check/check_prerequisites.py
@@ -0,0 +1,63 @@
+import pytest
+from unit.option import option
+
+
+def check_prerequisites(prerequisites):
+ if 'privileged_user' in prerequisites:
+ if prerequisites['privileged_user'] and not option.is_privileged:
+ pytest.skip(
+ 'privileged user required',
+ allow_module_level=True,
+ )
+ elif not prerequisites['privileged_user'] and option.is_privileged:
+ pytest.skip(
+ 'unprivileged user required',
+ allow_module_level=True,
+ )
+
+ missed = []
+
+ # check modules
+
+ if 'modules' in prerequisites:
+ available = option.available['modules']
+
+ for module in prerequisites['modules']:
+ if module in available and available[module]:
+ continue
+
+ missed.append(module)
+
+ if missed:
+ pytest.skip(
+ f'Unit has no {", ".join(missed)} module(s)',
+ allow_module_level=True,
+ )
+
+ # check features
+
+ if 'features' in prerequisites:
+ available = option.available['features']
+ require = prerequisites['features']
+
+ for feature in require:
+ avail_feature = available[feature]
+
+ if feature in available and avail_feature:
+ if isinstance(require[feature], list) and isinstance(
+ avail_feature, dict
+ ):
+ avail_keys = avail_feature.keys()
+
+ for key in require[feature]:
+ if key not in avail_keys:
+ missed.append(f'{feature}/{key}')
+ continue
+
+ missed.append(feature)
+
+ if missed:
+ pytest.skip(
+ f'{", ".join(missed)} feature(s) not supported',
+ allow_module_level=True,
+ )
diff --git a/test/unit/check/chroot.py b/test/unit/check/chroot.py
index 1b7aae90..b749fab6 100644
--- a/test/unit/check/chroot.py
+++ b/test/unit/check/chroot.py
@@ -1,32 +1,30 @@
import json
-from unit.http import TestHTTP
+from unit.http import HTTP1
from unit.option import option
-http = TestHTTP()
+http = HTTP1()
def check_chroot():
- available = option.available
-
- resp = http.put(
- url='/config',
- sock_type='unix',
- addr=f'{option.temp_dir}/control.unit.sock',
- body=json.dumps(
- {
- "listeners": {"*:7080": {"pass": "routes"}},
- "routes": [
- {
- "action": {
- "share": option.temp_dir,
- "chroot": option.temp_dir,
+ return (
+ 'success'
+ in http.put(
+ url='/config',
+ sock_type='unix',
+ addr=f'{option.temp_dir}/control.unit.sock',
+ body=json.dumps(
+ {
+ "listeners": {"*:7080": {"pass": "routes"}},
+ "routes": [
+ {
+ "action": {
+ "share": option.temp_dir,
+ "chroot": option.temp_dir,
+ }
}
- }
- ],
- }
- ),
+ ],
+ }
+ ),
+ )['body']
)
-
- if 'success' in resp['body']:
- available['features']['chroot'] = True
diff --git a/test/unit/check/discover_available.py b/test/unit/check/discover_available.py
new file mode 100644
index 00000000..0942581b
--- /dev/null
+++ b/test/unit/check/discover_available.py
@@ -0,0 +1,47 @@
+import subprocess
+import sys
+
+from unit.check.chroot import check_chroot
+from unit.check.go import check_go
+from unit.check.isolation import check_isolation
+from unit.check.njs import check_njs
+from unit.check.node import check_node
+from unit.check.regex import check_regex
+from unit.check.tls import check_openssl
+from unit.check.unix_abstract import check_unix_abstract
+from unit.log import Log
+from unit.option import option
+
+
+def discover_available(unit):
+ output_version = subprocess.check_output(
+ [unit['unitd'], '--version'], stderr=subprocess.STDOUT
+ ).decode()
+
+ # wait for controller start
+
+ if Log.wait_for_record(r'controller started') is None:
+ Log.print_log()
+ sys.exit("controller didn't start")
+
+ # discover modules from log file
+
+ for module in Log.findall(r'module: ([a-zA-Z]+) (.*) ".*"$'):
+ versions = option.available['modules'].setdefault(module[0], [])
+ if module[1] not in versions:
+ versions.append(module[1])
+
+ # discover modules using check
+
+ option.available['modules']['go'] = check_go()
+ option.available['modules']['njs'] = check_njs(output_version)
+ option.available['modules']['node'] = check_node()
+ option.available['modules']['openssl'] = check_openssl(output_version)
+ option.available['modules']['regex'] = check_regex(output_version)
+
+ # Discover features using check. Features should be discovered after
+ # modules since some features can require modules.
+
+ option.available['features']['chroot'] = check_chroot()
+ option.available['features']['isolation'] = check_isolation()
+ option.available['features']['unix_abstract'] = check_unix_abstract()
diff --git a/test/unit/check/go.py b/test/unit/check/go.py
index 09ae641d..1ecd429b 100644
--- a/test/unit/check/go.py
+++ b/test/unit/check/go.py
@@ -1,6 +1,5 @@
-from unit.applications.lang.go import TestApplicationGo
+from unit.applications.lang.go import ApplicationGo
def check_go():
- if TestApplicationGo.prepare_env('empty') is not None:
- return True
+ return ApplicationGo.prepare_env('empty') is not None
diff --git a/test/unit/check/isolation.py b/test/unit/check/isolation.py
index 4ebce893..e4674f4d 100644
--- a/test/unit/check/isolation.py
+++ b/test/unit/check/isolation.py
@@ -1,25 +1,24 @@
import json
import os
-from unit.applications.lang.go import TestApplicationGo
-from unit.applications.lang.java import TestApplicationJava
-from unit.applications.lang.node import TestApplicationNode
-from unit.applications.lang.ruby import TestApplicationRuby
-from unit.http import TestHTTP
+from unit.applications.lang.go import ApplicationGo
+from unit.applications.lang.java import ApplicationJava
+from unit.applications.lang.node import ApplicationNode
+from unit.applications.lang.ruby import ApplicationRuby
+from unit.http import HTTP1
from unit.option import option
from unit.utils import getns
allns = ['pid', 'mnt', 'ipc', 'uts', 'cgroup', 'net']
-http = TestHTTP()
+http = HTTP1()
def check_isolation():
- test_conf = {"namespaces": {"credential": True}}
available = option.available
conf = ''
if 'go' in available['modules']:
- TestApplicationGo().prepare_env('empty', 'app')
+ ApplicationGo().prepare_env('empty', 'app')
conf = {
"listeners": {"*:7080": {"pass": "applications/empty"}},
@@ -65,7 +64,7 @@ def check_isolation():
}
elif 'ruby' in available['modules']:
- TestApplicationRuby().prepare_env('empty')
+ ApplicationRuby().prepare_env('empty')
conf = {
"listeners": {"*:7080": {"pass": "applications/empty"}},
@@ -81,7 +80,7 @@ def check_isolation():
}
elif 'java' in available['modules']:
- TestApplicationJava().prepare_env('empty')
+ ApplicationJava().prepare_env('empty')
conf = {
"listeners": {"*:7080": {"pass": "applications/empty"}},
@@ -98,7 +97,7 @@ def check_isolation():
}
elif 'node' in available['modules']:
- TestApplicationNode().prepare_env('basic')
+ ApplicationNode().prepare_env('basic')
conf = {
"listeners": {"*:7080": {"pass": "applications/basic"}},
@@ -128,7 +127,7 @@ def check_isolation():
}
else:
- return
+ return False
resp = http.put(
url='/config',
@@ -138,23 +137,23 @@ def check_isolation():
)
if 'success' not in resp['body']:
- return
+ return False
userns = getns('user')
if not userns:
- return
+ return False
- available['features']['isolation'] = {'user': userns}
+ isolation = {'user': userns}
unp_clone_path = '/proc/sys/kernel/unprivileged_userns_clone'
if os.path.exists(unp_clone_path):
with open(unp_clone_path, 'r') as f:
if str(f.read()).rstrip() == '1':
- available['features']['isolation'][
- 'unprivileged_userns_clone'
- ] = True
+ isolation['unprivileged_userns_clone'] = True
for ns in allns:
ns_value = getns(ns)
if ns_value:
- available['features']['isolation'][ns] = ns_value
+ isolation[ns] = ns_value
+
+ return isolation
diff --git a/test/unit/check/njs.py b/test/unit/check/njs.py
index 433473a1..363a1b62 100644
--- a/test/unit/check/njs.py
+++ b/test/unit/check/njs.py
@@ -2,5 +2,4 @@ import re
def check_njs(output_version):
- if re.search('--njs', output_version):
- return True
+ return re.search('--njs', output_version)
diff --git a/test/unit/check/node.py b/test/unit/check/node.py
index dd59e7a4..6a3d581f 100644
--- a/test/unit/check/node.py
+++ b/test/unit/check/node.py
@@ -1,10 +1,12 @@
import os
import subprocess
+from unit.option import option
-def check_node(current_dir):
- if not os.path.exists(f'{current_dir}/node/node_modules'):
- return None
+
+def check_node():
+ if not os.path.exists(f'{option.current_dir}/node/node_modules'):
+ return False
try:
v_bytes = subprocess.check_output(['/usr/bin/env', 'node', '-v'])
@@ -12,4 +14,4 @@ def check_node(current_dir):
return [str(v_bytes, 'utf-8').lstrip('v').rstrip()]
except subprocess.CalledProcessError:
- return None
+ return False
diff --git a/test/unit/check/regex.py b/test/unit/check/regex.py
index 51cf966b..83e93f2d 100644
--- a/test/unit/check/regex.py
+++ b/test/unit/check/regex.py
@@ -2,7 +2,4 @@ import re
def check_regex(output_version):
- if re.search('--no-regex', output_version):
- return False
-
- return True
+ return not re.search('--no-regex', output_version)
diff --git a/test/unit/check/tls.py b/test/unit/check/tls.py
index 53ce5ffc..9cc2a5f9 100644
--- a/test/unit/check/tls.py
+++ b/test/unit/check/tls.py
@@ -6,7 +6,6 @@ def check_openssl(output_version):
try:
subprocess.check_output(['which', 'openssl'])
except subprocess.CalledProcessError:
- return None
+ return False
- if re.search('--openssl', output_version):
- return True
+ return re.search('--openssl', output_version)
diff --git a/test/unit/check/unix_abstract.py b/test/unit/check/unix_abstract.py
index aadde43a..8fc7dd84 100644
--- a/test/unit/check/unix_abstract.py
+++ b/test/unit/check/unix_abstract.py
@@ -1,25 +1,25 @@
import json
-from unit.http import TestHTTP
+from unit.http import HTTP1
from unit.option import option
-http = TestHTTP()
+http = HTTP1()
def check_unix_abstract():
- available = option.available
-
- resp = http.put(
- url='/config',
- sock_type='unix',
- addr=f'{option.temp_dir}/control.unit.sock',
- body=json.dumps(
- {
- "listeners": {"unix:@sock": {"pass": "routes"}},
- "routes": [],
- }
- ),
+ return (
+ 'success'
+ in http.put(
+ url='/config',
+ sock_type='unix',
+ addr=f'{option.temp_dir}/control.unit.sock',
+ body=json.dumps(
+ {
+ "listeners": {
+ f'unix:@{option.temp_dir}/sock': {"pass": "routes"}
+ },
+ "routes": [],
+ }
+ ),
+ )['body']
)
-
- if 'success' in resp['body']:
- available['features']['unix_abstract'] = True
diff --git a/test/unit/control.py b/test/unit/control.py
index 61b6edf4..164d0e60 100644
--- a/test/unit/control.py
+++ b/test/unit/control.py
@@ -1,6 +1,6 @@
import json
-from unit.http import TestHTTP
+from unit.http import HTTP1
from unit.option import option
@@ -29,7 +29,7 @@ def args_handler(conf_func):
return args_wrapper
-class TestControl(TestHTTP):
+class Control(HTTP1):
@args_handler
def conf(self, conf, url):
return self.put(**self._get_args(url, conf))['body']
diff --git a/test/unit/http.py b/test/unit/http.py
index 6a267e26..347382f5 100644
--- a/test/unit/http.py
+++ b/test/unit/http.py
@@ -10,7 +10,7 @@ import pytest
from unit.option import option
-class TestHTTP:
+class HTTP1:
def http(self, start_str, **kwargs):
sock_type = kwargs.get('sock_type', 'ipv4')
port = kwargs.get('port', 7080)
diff --git a/test/unit/log.py b/test/unit/log.py
index f984d7a1..7d7e355a 100644
--- a/test/unit/log.py
+++ b/test/unit/log.py
@@ -1,23 +1,113 @@
+import os
+import re
+import sys
+import time
+
+from unit.option import option
+
UNIT_LOG = 'unit.log'
+def print_log_on_assert(func):
+ def inner_function(*args, **kwargs):
+ try:
+ func(*args, **kwargs)
+ except AssertionError as exception:
+ Log.print_log(*args, **kwargs)
+ raise exception
+
+ return inner_function
+
+
class Log:
- temp_dir = None
pos = {}
- def open(name=UNIT_LOG, encoding=None):
- f = open(Log.get_path(name), 'r', encoding=encoding, errors='ignore')
- f.seek(Log.pos.get(name, 0))
+ @staticmethod
+ @print_log_on_assert
+ def check_alerts(log=None):
+ if log is None:
+ log = Log.read()
+
+ found = False
+ alerts = re.findall(r'.+\[alert\].+', log)
+
+ if alerts:
+ found = True
- return f
+ if option.detailed:
+ print('\nAll alerts/sanitizer errors found in log:')
+ _ = [print(alert) for alert in alerts]
+ if option.skip_alerts:
+ for skip in option.skip_alerts:
+ alerts = [al for al in alerts if re.search(skip, al) is None]
+
+ assert not alerts, 'alert(s)'
+
+ if not option.skip_sanitizer:
+ sanitizer_errors = re.findall('.+Sanitizer.+', log)
+
+ assert not sanitizer_errors, 'sanitizer error(s)'
+
+ if found and option.detailed:
+ print('skipped.')
+
+ @staticmethod
+ def findall(pattern, name=UNIT_LOG, flags=re.M):
+ return re.findall(pattern, Log.read(name), flags)
+
+ @staticmethod
+ def get_path(name=UNIT_LOG):
+ return f'{option.temp_dir}/{name}'
+
+ @staticmethod
+ def open(name=UNIT_LOG, encoding='utf-8'):
+ file = open(Log.get_path(name), 'r', encoding=encoding, errors='ignore')
+ file.seek(Log.pos.get(name, 0))
+
+ return file
+
+ @staticmethod
+ def print_log(log=None):
+ Log.print_path()
+
+ if option.print_log:
+ os.set_blocking(sys.stdout.fileno(), True)
+ sys.stdout.flush()
+
+ if log is None:
+ log = Log.read()
+
+ sys.stdout.write(log)
+
+ @staticmethod
+ def print_path():
+ print(f'Path to {UNIT_LOG}:\n{Log.get_path()}\n')
+
+ @staticmethod
+ def read(*args, **kwargs):
+ with Log.open(*args, **kwargs) as file:
+ return file.read()
+
+ @staticmethod
def set_pos(pos, name=UNIT_LOG):
Log.pos[name] = pos
+ @staticmethod
def swap(name):
pos = Log.pos.get(UNIT_LOG, 0)
Log.pos[UNIT_LOG] = Log.pos.get(name, 0)
Log.pos[name] = pos
- def get_path(name=UNIT_LOG):
- return f'{Log.temp_dir}/{name}'
+ @staticmethod
+ 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
diff --git a/test/unit/option.py b/test/unit/option.py
index cb3803dc..ee1f46dd 100644
--- a/test/unit/option.py
+++ b/test/unit/option.py
@@ -1,7 +1,15 @@
+import os
+import platform
+
+
class Options:
_options = {
+ 'architecture': platform.architecture()[0],
+ 'available': {'modules': {}, 'features': {}},
+ 'is_privileged': os.geteuid() == 0,
'skip_alerts': [],
'skip_sanitizer': False,
+ 'system': platform.system(),
}
def __setattr__(self, name, value):
diff --git a/test/unit/status.py b/test/unit/status.py
index 17416f17..84c958a3 100644
--- a/test/unit/status.py
+++ b/test/unit/status.py
@@ -1,9 +1,9 @@
-from unit.control import TestControl
+from unit.control import Control
class Status:
_status = None
- control = TestControl()
+ control = Control()
def _check_zeros():
assert Status.control.conf_get('/status') == {
diff --git a/test/unit/utils.py b/test/unit/utils.py
index 985801e2..cd823e27 100644
--- a/test/unit/utils.py
+++ b/test/unit/utils.py
@@ -24,7 +24,7 @@ def public_dir(path):
def waitforfiles(*files, timeout=50):
- for i in range(timeout):
+ for _ in range(timeout):
wait = False
for f in files:
@@ -41,10 +41,10 @@ def waitforfiles(*files, timeout=50):
def waitforglob(pattern, count=1, timeout=50):
- for i in range(timeout):
+ for _ in range(timeout):
n = 0
- for f in glob.glob(pattern):
+ for _ in glob.glob(pattern):
n += 1
if n == count:
@@ -56,7 +56,7 @@ def waitforglob(pattern, count=1, timeout=50):
def waitforsocket(port):
- for i in range(50):
+ for _ in range(50):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
try:
sock.settimeout(5)
@@ -90,19 +90,8 @@ def findmnt():
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):
- for i in range(timeout):
+ for _ in range(timeout):
if findmnt().find(template) != -1:
return True
@@ -112,7 +101,7 @@ def waitformount(template, timeout=50):
def waitforunmount(template, timeout=50):
- for i in range(timeout):
+ for _ in range(timeout):
if findmnt().find(template) == -1:
return True