Tests: refactored prerequisites model.
This commit is contained in:
@@ -7,7 +7,7 @@ from unit.applications.lang.python import TestApplicationPython
|
|||||||
|
|
||||||
|
|
||||||
class TestAccessLog(TestApplicationPython):
|
class TestAccessLog(TestApplicationPython):
|
||||||
prerequisites = ['python']
|
prerequisites = {'modules': ['python']}
|
||||||
|
|
||||||
def load(self, script):
|
def load(self, script):
|
||||||
super().load(script)
|
super().load(script)
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from unit.control import TestControl
|
|||||||
|
|
||||||
|
|
||||||
class TestConfiguration(TestControl):
|
class TestConfiguration(TestControl):
|
||||||
prerequisites = ['python']
|
prerequisites = {'modules': ['python']}
|
||||||
|
|
||||||
def test_json_empty(self):
|
def test_json_empty(self):
|
||||||
self.assertIn('error', self.conf(''), 'empty')
|
self.assertIn('error', self.conf(''), 'empty')
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ from unit.applications.lang.go import TestApplicationGo
|
|||||||
|
|
||||||
|
|
||||||
class TestGoApplication(TestApplicationGo):
|
class TestGoApplication(TestApplicationGo):
|
||||||
prerequisites = ['go']
|
prerequisites = {'modules': ['go']}
|
||||||
|
|
||||||
def test_go_application_variables(self):
|
def test_go_application_variables(self):
|
||||||
self.load('variables')
|
self.load('variables')
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from unit.applications.lang.python import TestApplicationPython
|
|||||||
|
|
||||||
|
|
||||||
class TestHTTPHeader(TestApplicationPython):
|
class TestHTTPHeader(TestApplicationPython):
|
||||||
prerequisites = ['python']
|
prerequisites = {'modules': ['python']}
|
||||||
|
|
||||||
def test_http_header_value_leading_sp(self):
|
def test_http_header_value_leading_sp(self):
|
||||||
self.load('custom_header')
|
self.load('custom_header')
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ from unit.applications.lang.java import TestApplicationJava
|
|||||||
|
|
||||||
|
|
||||||
class TestJavaApplication(TestApplicationJava):
|
class TestJavaApplication(TestApplicationJava):
|
||||||
prerequisites = ['java']
|
prerequisites = {'modules': ['java']}
|
||||||
|
|
||||||
def test_java_conf_error(self):
|
def test_java_conf_error(self):
|
||||||
self.skip_alerts.extend(
|
self.skip_alerts.extend(
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from unit.applications.websockets import TestApplicationWebsocket
|
|||||||
|
|
||||||
|
|
||||||
class TestJavaWebsockets(TestApplicationJava):
|
class TestJavaWebsockets(TestApplicationJava):
|
||||||
prerequisites = ['java']
|
prerequisites = {'modules': ['java']}
|
||||||
|
|
||||||
ws = TestApplicationWebsocket(True)
|
ws = TestApplicationWebsocket(True)
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from unit.applications.lang.node import TestApplicationNode
|
|||||||
|
|
||||||
|
|
||||||
class TestNodeApplication(TestApplicationNode):
|
class TestNodeApplication(TestApplicationNode):
|
||||||
prerequisites = ['node']
|
prerequisites = {'modules': ['node']}
|
||||||
|
|
||||||
def test_node_application_basic(self):
|
def test_node_application_basic(self):
|
||||||
self.load('basic')
|
self.load('basic')
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from unit.applications.websockets import TestApplicationWebsocket
|
|||||||
|
|
||||||
|
|
||||||
class TestNodeWebsockets(TestApplicationNode):
|
class TestNodeWebsockets(TestApplicationNode):
|
||||||
prerequisites = ['node']
|
prerequisites = {'modules': ['node']}
|
||||||
|
|
||||||
ws = TestApplicationWebsocket()
|
ws = TestApplicationWebsocket()
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from unit.applications.lang.perl import TestApplicationPerl
|
|||||||
|
|
||||||
|
|
||||||
class TestPerlApplication(TestApplicationPerl):
|
class TestPerlApplication(TestApplicationPerl):
|
||||||
prerequisites = ['perl']
|
prerequisites = {'modules': ['perl']}
|
||||||
|
|
||||||
def test_perl_application(self):
|
def test_perl_application(self):
|
||||||
self.load('variables')
|
self.load('variables')
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import unittest
|
|||||||
from unit.applications.lang.php import TestApplicationPHP
|
from unit.applications.lang.php import TestApplicationPHP
|
||||||
|
|
||||||
class TestPHPApplication(TestApplicationPHP):
|
class TestPHPApplication(TestApplicationPHP):
|
||||||
prerequisites = ['php']
|
prerequisites = {'modules': ['php']}
|
||||||
|
|
||||||
def before_disable_functions(self):
|
def before_disable_functions(self):
|
||||||
body = self.get()['body']
|
body = self.get()['body']
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ from unit.control import TestControl
|
|||||||
|
|
||||||
|
|
||||||
class TestPHPBasic(TestControl):
|
class TestPHPBasic(TestControl):
|
||||||
prerequisites = ['php']
|
prerequisites = {'modules': ['php']}
|
||||||
|
|
||||||
conf_app = {
|
conf_app = {
|
||||||
"app": {
|
"app": {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ from unit.applications.lang.python import TestApplicationPython
|
|||||||
|
|
||||||
|
|
||||||
class TestPythonApplication(TestApplicationPython):
|
class TestPythonApplication(TestApplicationPython):
|
||||||
prerequisites = ['python']
|
prerequisites = {'modules': ['python']}
|
||||||
|
|
||||||
def test_python_application_variables(self):
|
def test_python_application_variables(self):
|
||||||
self.load('variables')
|
self.load('variables')
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ from unit.control import TestControl
|
|||||||
|
|
||||||
|
|
||||||
class TestPythonBasic(TestControl):
|
class TestPythonBasic(TestControl):
|
||||||
prerequisites = ['python']
|
prerequisites = {'modules': ['python']}
|
||||||
|
|
||||||
conf_app = {
|
conf_app = {
|
||||||
"app": {
|
"app": {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ from unit.applications.lang.python import TestApplicationPython
|
|||||||
|
|
||||||
|
|
||||||
class TestPythonEnvironment(TestApplicationPython):
|
class TestPythonEnvironment(TestApplicationPython):
|
||||||
prerequisites = ['python']
|
prerequisites = {'modules': ['python']}
|
||||||
|
|
||||||
def test_python_environment_name_null(self):
|
def test_python_environment_name_null(self):
|
||||||
self.load('environment')
|
self.load('environment')
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from unit.applications.lang.python import TestApplicationPython
|
|||||||
|
|
||||||
|
|
||||||
class TestPythonProcman(TestApplicationPython):
|
class TestPythonProcman(TestApplicationPython):
|
||||||
prerequisites = ['python']
|
prerequisites = {'modules': ['python']}
|
||||||
|
|
||||||
def pids_for_process(self):
|
def pids_for_process(self):
|
||||||
time.sleep(0.2)
|
time.sleep(0.2)
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from unit.applications.proto import TestApplicationProto
|
|||||||
|
|
||||||
|
|
||||||
class TestRouting(TestApplicationProto):
|
class TestRouting(TestApplicationProto):
|
||||||
prerequisites = ['python']
|
prerequisites = {'modules': ['python']}
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super().setUp()
|
super().setUp()
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ from unit.applications.tls import TestApplicationTLS
|
|||||||
|
|
||||||
|
|
||||||
class TestRoutingTLS(TestApplicationTLS):
|
class TestRoutingTLS(TestApplicationTLS):
|
||||||
prerequisites = ['python', 'openssl']
|
prerequisites = {'modules': ['python', 'openssl']}
|
||||||
|
|
||||||
def test_routes_match_scheme(self):
|
def test_routes_match_scheme(self):
|
||||||
self.certificate()
|
self.certificate()
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from unit.applications.lang.ruby import TestApplicationRuby
|
|||||||
|
|
||||||
|
|
||||||
class TestRubyApplication(TestApplicationRuby):
|
class TestRubyApplication(TestApplicationRuby):
|
||||||
prerequisites = ['ruby']
|
prerequisites = {'modules': ['ruby']}
|
||||||
|
|
||||||
def test_ruby_application(self):
|
def test_ruby_application(self):
|
||||||
self.load('variables')
|
self.load('variables')
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ from unit.applications.lang.python import TestApplicationPython
|
|||||||
|
|
||||||
|
|
||||||
class TestSettings(TestApplicationPython):
|
class TestSettings(TestApplicationPython):
|
||||||
prerequisites = ['python']
|
prerequisites = {'modules': ['python']}
|
||||||
|
|
||||||
def test_settings_header_read_timeout(self):
|
def test_settings_header_read_timeout(self):
|
||||||
self.load('empty')
|
self.load('empty')
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from unit.applications.tls import TestApplicationTLS
|
|||||||
|
|
||||||
|
|
||||||
class TestTLS(TestApplicationTLS):
|
class TestTLS(TestApplicationTLS):
|
||||||
prerequisites = ['python', 'openssl']
|
prerequisites = {'modules': ['python', 'openssl']}
|
||||||
|
|
||||||
def findall(self, pattern):
|
def findall(self, pattern):
|
||||||
with open(self.testdir + '/unit.log', 'r', errors='ignore') as f:
|
with open(self.testdir + '/unit.log', 'r', errors='ignore') as f:
|
||||||
|
|||||||
@@ -4,6 +4,19 @@ from unit.applications.proto import TestApplicationProto
|
|||||||
|
|
||||||
|
|
||||||
class TestApplicationGo(TestApplicationProto):
|
class TestApplicationGo(TestApplicationProto):
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls, complete_check=True):
|
||||||
|
unit = super().setUpClass(complete_check=False)
|
||||||
|
|
||||||
|
# check go module
|
||||||
|
|
||||||
|
go_app = TestApplicationGo()
|
||||||
|
go_app.testdir = unit.testdir
|
||||||
|
if go_app.prepare_env('empty', 'app').returncode == 0:
|
||||||
|
cls.available['modules']['go'] = []
|
||||||
|
|
||||||
|
return unit if not complete_check else unit.complete()
|
||||||
|
|
||||||
def prepare_env(self, script, name):
|
def prepare_env(self, script, name):
|
||||||
if not os.path.exists(self.testdir + '/go'):
|
if not os.path.exists(self.testdir + '/go'):
|
||||||
os.mkdir(self.testdir + '/go')
|
os.mkdir(self.testdir + '/go')
|
||||||
|
|||||||
@@ -4,6 +4,17 @@ from unit.applications.proto import TestApplicationProto
|
|||||||
|
|
||||||
|
|
||||||
class TestApplicationNode(TestApplicationProto):
|
class TestApplicationNode(TestApplicationProto):
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls, complete_check=True):
|
||||||
|
unit = super().setUpClass(complete_check=False)
|
||||||
|
|
||||||
|
# check node module
|
||||||
|
|
||||||
|
if os.path.exists(unit.pardir + '/node/node_modules'):
|
||||||
|
cls.available['modules']['node'] = []
|
||||||
|
|
||||||
|
return unit if not complete_check else unit.complete()
|
||||||
|
|
||||||
def load(self, script, name='app.js'):
|
def load(self, script, name='app.js'):
|
||||||
# copy application
|
# copy application
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import ssl
|
import ssl
|
||||||
import subprocess
|
import subprocess
|
||||||
from unit.applications.proto import TestApplicationProto
|
from unit.applications.proto import TestApplicationProto
|
||||||
@@ -12,6 +13,27 @@ class TestApplicationTLS(TestApplicationProto):
|
|||||||
self.context.check_hostname = False
|
self.context.check_hostname = False
|
||||||
self.context.verify_mode = ssl.CERT_NONE
|
self.context.verify_mode = ssl.CERT_NONE
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls, complete_check=True):
|
||||||
|
unit = super().setUpClass(complete_check=False)
|
||||||
|
|
||||||
|
# check tls module
|
||||||
|
|
||||||
|
try:
|
||||||
|
subprocess.check_output(['which', 'openssl'])
|
||||||
|
|
||||||
|
output = subprocess.check_output(
|
||||||
|
[unit.unitd, '--version'], stderr=subprocess.STDOUT
|
||||||
|
)
|
||||||
|
|
||||||
|
if re.search('--openssl', output.decode()):
|
||||||
|
cls.available['modules']['openssl'] = []
|
||||||
|
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return unit if not complete_check else unit.complete()
|
||||||
|
|
||||||
def certificate(self, name='default', load=True):
|
def certificate(self, name='default', load=True):
|
||||||
self.openssl_conf()
|
self.openssl_conf()
|
||||||
|
|
||||||
|
|||||||
@@ -12,8 +12,6 @@ import subprocess
|
|||||||
from multiprocessing import Process
|
from multiprocessing import Process
|
||||||
|
|
||||||
|
|
||||||
available_modules = {}
|
|
||||||
|
|
||||||
class TestUnit(unittest.TestCase):
|
class TestUnit(unittest.TestCase):
|
||||||
|
|
||||||
current_dir = os.path.abspath(
|
current_dir = os.path.abspath(
|
||||||
@@ -45,9 +43,9 @@ class TestUnit(unittest.TestCase):
|
|||||||
# rerun test for each available module version
|
# rerun test for each available module version
|
||||||
|
|
||||||
type = self.application_type
|
type = self.application_type
|
||||||
for prerequisite in self.prerequisites:
|
for module in self.prerequisites['modules']:
|
||||||
if prerequisite in available_modules:
|
if module in self.available['modules']:
|
||||||
for version in available_modules[prerequisite]:
|
for version in self.available['modules'][module]:
|
||||||
self.application_type = type + ' ' + version
|
self.application_type = type + ' ' + version
|
||||||
super().run(result)
|
super().run(result)
|
||||||
|
|
||||||
@@ -66,8 +64,83 @@ class TestUnit(unittest.TestCase):
|
|||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls):
|
def setUpClass(cls, complete_check=True):
|
||||||
TestUnit().check_modules(*cls.prerequisites)
|
cls.available = {'modules': {}, 'features': {}}
|
||||||
|
unit = TestUnit()
|
||||||
|
|
||||||
|
unit._run()
|
||||||
|
|
||||||
|
# read unit.log
|
||||||
|
|
||||||
|
for i in range(50):
|
||||||
|
with open(unit.testdir + '/unit.log', '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:
|
||||||
|
unit.stop()
|
||||||
|
exit("Unit is writing log too long")
|
||||||
|
|
||||||
|
# discover available modules from unit.log
|
||||||
|
|
||||||
|
for module in re.findall(r'module: ([a-zA-Z]+) (.*) ".*"$', log, re.M):
|
||||||
|
if module[0] not in cls.available['modules']:
|
||||||
|
cls.available['modules'][module[0]] = [module[1]]
|
||||||
|
else:
|
||||||
|
cls.available['modules'][module[0]].append(module[1])
|
||||||
|
|
||||||
|
def check(available, prerequisites):
|
||||||
|
missed = []
|
||||||
|
|
||||||
|
# check modules
|
||||||
|
|
||||||
|
if 'modules' in prerequisites:
|
||||||
|
available_modules = list(available['modules'].keys())
|
||||||
|
|
||||||
|
for module in prerequisites['modules']:
|
||||||
|
if module in available_modules:
|
||||||
|
continue
|
||||||
|
|
||||||
|
missed.append(module)
|
||||||
|
|
||||||
|
if missed:
|
||||||
|
print('Unit has no ' + ', '.join(missed) + ' module(s)')
|
||||||
|
raise unittest.SkipTest()
|
||||||
|
|
||||||
|
# check features
|
||||||
|
|
||||||
|
if 'features' in prerequisites:
|
||||||
|
available_features = list(available['modules'].keys())
|
||||||
|
|
||||||
|
for feature in prerequisites['features']:
|
||||||
|
if feature in available_features:
|
||||||
|
continue
|
||||||
|
|
||||||
|
missed.append(feature)
|
||||||
|
|
||||||
|
if missed:
|
||||||
|
print(', '.join(missed) + ' feature(s) not supported')
|
||||||
|
raise unittest.SkipTest()
|
||||||
|
|
||||||
|
def destroy():
|
||||||
|
unit.stop()
|
||||||
|
unit._check_alerts(log)
|
||||||
|
shutil.rmtree(unit.testdir)
|
||||||
|
|
||||||
|
def complete():
|
||||||
|
destroy()
|
||||||
|
check(cls.available, cls.prerequisites)
|
||||||
|
|
||||||
|
if complete_check:
|
||||||
|
complete()
|
||||||
|
else:
|
||||||
|
unit.complete = complete
|
||||||
|
return unit
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self._run()
|
self._run()
|
||||||
@@ -108,92 +181,6 @@ class TestUnit(unittest.TestCase):
|
|||||||
else:
|
else:
|
||||||
self._print_path_to_log()
|
self._print_path_to_log()
|
||||||
|
|
||||||
def check_modules(self, *modules):
|
|
||||||
self._run()
|
|
||||||
|
|
||||||
for i in range(50):
|
|
||||||
with open(self.testdir + '/unit.log', '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:
|
|
||||||
self.stop()
|
|
||||||
exit("Unit is writing log too long")
|
|
||||||
|
|
||||||
# discover all available modules
|
|
||||||
|
|
||||||
global available_modules
|
|
||||||
available_modules = {}
|
|
||||||
for module in re.findall(r'module: ([a-zA-Z]+) (.*) ".*"$', log, re.M):
|
|
||||||
if module[0] not in available_modules:
|
|
||||||
available_modules[module[0]] = [module[1]]
|
|
||||||
else:
|
|
||||||
available_modules[module[0]].append(module[1])
|
|
||||||
|
|
||||||
missed_module = ''
|
|
||||||
for module in modules:
|
|
||||||
if module == 'go':
|
|
||||||
env = os.environ.copy()
|
|
||||||
env['GOPATH'] = self.pardir + '/go'
|
|
||||||
|
|
||||||
try:
|
|
||||||
process = subprocess.Popen(
|
|
||||||
[
|
|
||||||
'go',
|
|
||||||
'build',
|
|
||||||
'-o',
|
|
||||||
self.testdir + '/go/check_module',
|
|
||||||
self.current_dir + '/go/empty/app.go',
|
|
||||||
],
|
|
||||||
env=env,
|
|
||||||
)
|
|
||||||
process.communicate()
|
|
||||||
|
|
||||||
m = module if process.returncode == 0 else None
|
|
||||||
|
|
||||||
except:
|
|
||||||
m = None
|
|
||||||
|
|
||||||
elif module == 'node':
|
|
||||||
if os.path.isdir(self.pardir + '/node/node_modules'):
|
|
||||||
m = module
|
|
||||||
else:
|
|
||||||
m = None
|
|
||||||
|
|
||||||
elif module == 'openssl':
|
|
||||||
try:
|
|
||||||
subprocess.check_output(['which', 'openssl'])
|
|
||||||
|
|
||||||
output = subprocess.check_output(
|
|
||||||
[self.unitd, '--version'],
|
|
||||||
stderr=subprocess.STDOUT,
|
|
||||||
)
|
|
||||||
|
|
||||||
m = re.search('--openssl', output.decode())
|
|
||||||
|
|
||||||
except:
|
|
||||||
m = None
|
|
||||||
|
|
||||||
else:
|
|
||||||
if module not in available_modules:
|
|
||||||
m = None
|
|
||||||
|
|
||||||
if m is None:
|
|
||||||
missed_module = module
|
|
||||||
break
|
|
||||||
|
|
||||||
self.stop()
|
|
||||||
self._check_alerts(log)
|
|
||||||
shutil.rmtree(self.testdir)
|
|
||||||
|
|
||||||
if missed_module:
|
|
||||||
raise unittest.SkipTest('Unit has no ' + missed_module + ' module')
|
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
if self._started:
|
if self._started:
|
||||||
self._stop()
|
self._stop()
|
||||||
|
|||||||
Reference in New Issue
Block a user