summaryrefslogtreecommitdiffhomepage
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--test/conftest.py86
-rw-r--r--test/perl/input_buffered_read/psgi.pl17
-rw-r--r--test/perl/input_close/psgi.pl8
-rw-r--r--test/php/opcache/index.php2
-rw-r--r--test/php/opcache/preload/chdir.php7
-rw-r--r--test/php/opcache/preload/fastcgi_finish_request.php5
-rw-r--r--test/python/204_no_content/asgi.py12
-rw-r--r--test/ruby/errors_write/config.ru2
-rw-r--r--test/ruby/input_gets/config.ru1
-rw-r--r--test/ruby/variables/config.ru1
-rw-r--r--test/test_asgi_application.py6
-rw-r--r--test/test_asgi_lifespan.py8
-rw-r--r--test/test_asgi_targets.py9
-rw-r--r--test/test_asgi_websockets.py98
-rw-r--r--test/test_client_ip.py28
-rw-r--r--test/test_go_application.py9
-rw-r--r--test/test_go_isolation.py4
-rw-r--r--test/test_http_header.py16
-rw-r--r--test/test_java_application.py46
-rw-r--r--test/test_java_isolation_rootfs.py5
-rw-r--r--test/test_java_websockets.py90
-rw-r--r--test/test_node_application.py4
-rw-r--r--test/test_node_es_modules.py5
-rw-r--r--test/test_node_websockets.py90
-rw-r--r--test/test_perl_application.py19
-rw-r--r--test/test_php_application.py94
-rw-r--r--test/test_php_targets.py4
-rw-r--r--test/test_proxy.py19
-rw-r--r--test/test_proxy_chunked.py14
-rw-r--r--test/test_python_application.py34
-rw-r--r--test/test_python_isolation.py7
-rw-r--r--test/test_python_isolation_chroot.py4
-rw-r--r--test/test_python_targets.py2
-rw-r--r--test/test_reconfigure.py53
-rw-r--r--test/test_reconfigure_tls.py105
-rw-r--r--test/test_respawn.py3
-rw-r--r--test/test_return.py42
-rw-r--r--test/test_routing.py57
-rw-r--r--test/test_ruby_application.py22
-rw-r--r--test/test_ruby_hooks.py5
-rw-r--r--test/test_ruby_isolation.py6
-rw-r--r--test/test_settings.py20
-rw-r--r--test/test_static.py59
-rw-r--r--test/test_static_chroot.py27
-rw-r--r--test/test_static_fallback.py5
-rw-r--r--test/test_static_mount.py4
-rw-r--r--test/test_static_types.py5
-rw-r--r--test/test_tls.py82
-rw-r--r--test/test_tls_sni.py7
-rw-r--r--test/test_tls_tickets.py7
-rw-r--r--test/test_upstreams_rr.py5
-rw-r--r--test/test_usr1.py4
-rw-r--r--test/test_variables.py21
-rw-r--r--test/unit/applications/lang/go.py44
-rw-r--r--test/unit/applications/tls.py15
-rw-r--r--test/unit/applications/websockets.py10
-rw-r--r--test/unit/check/go.py36
-rw-r--r--test/unit/control.py4
-rw-r--r--test/unit/http.py4
59 files changed, 871 insertions, 537 deletions
diff --git a/test/conftest.py b/test/conftest.py
index 689c857a..904abc32 100644
--- a/test/conftest.py
+++ b/test/conftest.py
@@ -159,9 +159,7 @@ def pytest_generate_tests(metafunc):
type + ' ' + available_versions[0]
)
elif callable(prereq_version):
- generate_tests(
- list(filter(prereq_version, available_versions))
- )
+ generate_tests(list(filter(prereq_version, available_versions)))
else:
raise ValueError(
@@ -203,9 +201,7 @@ def pytest_sessionstart(session):
# discover modules from check
option.available['modules']['openssl'] = check_openssl(unit['unitd'])
- option.available['modules']['go'] = check_go(
- option.current_dir, unit['temp_dir'], option.test_dir
- )
+ option.available['modules']['go'] = check_go()
option.available['modules']['node'] = check_node(option.current_dir)
option.available['modules']['regex'] = check_regex(unit['unitd'])
@@ -322,9 +318,7 @@ def run(request):
public_dir(path)
- if os.path.isfile(path) or stat.S_ISSOCK(
- os.stat(path).st_mode
- ):
+ if os.path.isfile(path) or stat.S_ISSOCK(os.stat(path).st_mode):
os.remove(path)
else:
for attempt in range(10):
@@ -340,6 +334,10 @@ def run(request):
_check_fds(log=log)
+ # check processes id's and amount
+
+ _check_processes()
+
# print unit.log in case of error
if hasattr(request.node, 'rep_call') and request.node.rep_call.failed:
@@ -439,6 +437,16 @@ def unit_stop():
return
+ # check zombies
+
+ out = subprocess.check_output(
+ ['ps', 'ax', '-o', 'state', '-o', 'ppid']
+ ).decode()
+ z_ppids = re.findall(r'Z\s*(\d+)', out)
+ assert unit_instance['pid'] not in z_ppids, 'no zombies'
+
+ # terminate unit
+
p = unit_instance['process']
if p.poll() is not None:
@@ -522,7 +530,7 @@ def _clear_conf(sock, *, log=None):
try:
certs = json.loads(
- http.get(url='/certificates', sock_type='unix', addr=sock,)['body']
+ http.get(url='/certificates', sock_type='unix', addr=sock)['body']
).keys()
except json.JSONDecodeError:
@@ -530,12 +538,58 @@ def _clear_conf(sock, *, log=None):
for cert in certs:
resp = http.delete(
- url='/certificates/' + cert, sock_type='unix', addr=sock,
+ url='/certificates/' + cert,
+ sock_type='unix',
+ addr=sock,
)['body']
assert 'success' in resp, 'remove certificate'
+def _check_processes():
+ router_pid = _fds_info['router']['pid']
+ controller_pid = _fds_info['controller']['pid']
+ unit_pid = unit_instance['pid']
+
+ for i in range(600):
+ out = (
+ subprocess.check_output(
+ ['ps', '-ax', '-o', 'pid', '-o', 'ppid', '-o', 'command']
+ )
+ .decode()
+ .splitlines()
+ )
+ out = [l for l in out if unit_pid in l]
+
+ if len(out) <= 3:
+ break
+
+ time.sleep(0.1)
+
+ assert len(out) == 3, 'main, router, and controller expected'
+
+ out = [l for l in out if 'unit: main' not in l]
+ assert len(out) == 2, 'one main'
+
+ out = [
+ l
+ for l in out
+ if re.search(router_pid + r'\s+' + unit_pid + r'.*unit: router', l)
+ is None
+ ]
+ assert len(out) == 1, 'one router'
+
+ out = [
+ l
+ for l in out
+ if re.search(
+ controller_pid + r'\s+' + unit_pid + r'.*unit: controller', l
+ )
+ is None
+ ]
+ assert len(out) == 0, 'one controller'
+
+
@print_log_on_assert
def _check_fds(*, log=None):
def waitforfds(diff):
@@ -556,9 +610,7 @@ def _check_fds(*, log=None):
)
ps['fds'] += fds_diff
- assert (
- fds_diff <= option.fds_threshold
- ), 'descriptors leak main process'
+ assert fds_diff <= option.fds_threshold, 'descriptors leak main process'
else:
ps['fds'] = _count_fds(unit_instance['pid'])
@@ -590,7 +642,8 @@ def _count_fds(pid):
try:
out = subprocess.check_output(
- ['procstat', '-f', pid], stderr=subprocess.STDOUT,
+ ['procstat', '-f', pid],
+ stderr=subprocess.STDOUT,
).decode()
return len(out.splitlines())
@@ -599,7 +652,8 @@ def _count_fds(pid):
try:
out = subprocess.check_output(
- ['lsof', '-n', '-p', pid], stderr=subprocess.STDOUT,
+ ['lsof', '-n', '-p', pid],
+ stderr=subprocess.STDOUT,
).decode()
return len(out.splitlines())
diff --git a/test/perl/input_buffered_read/psgi.pl b/test/perl/input_buffered_read/psgi.pl
new file mode 100644
index 00000000..4ca699d7
--- /dev/null
+++ b/test/perl/input_buffered_read/psgi.pl
@@ -0,0 +1,17 @@
+use FileHandle;
+
+my $app = sub {
+ my ($environ) = @_;
+
+ $environ->{'psgi.input'}->read(my $body, 1024);
+
+ open my $io, "<", \$body;
+
+ # This makes $io work as FileHandle under 5.8, .10 and .11.
+ bless $io, 'FileHandle';
+
+ $environ->{'psgix.input.buffered'} = 1;
+ $environ->{'psgi.input'} = $io;
+
+ return ['200', ['Content-Length' => length $body], [$body]];
+};
diff --git a/test/perl/input_close/psgi.pl b/test/perl/input_close/psgi.pl
new file mode 100644
index 00000000..4a2d9bb9
--- /dev/null
+++ b/test/perl/input_close/psgi.pl
@@ -0,0 +1,8 @@
+my $app = sub {
+ my ($environ) = @_;
+
+ $environ->{'psgi.input'}->read(my $body, 1024);
+ $environ->{'psgi.input'}->close();
+
+ return ['200', ['Content-Length' => length $body], [$body]];
+};
diff --git a/test/php/opcache/index.php b/test/php/opcache/index.php
index de4002bb..cf67c4c2 100644
--- a/test/php/opcache/index.php
+++ b/test/php/opcache/index.php
@@ -12,7 +12,7 @@ if (function_exists('opcache_is_script_cached')) {
opcache_compile_file(__DIR__ . '/test.php');
}
} else {
- header('X-Cached: -1');
+ header('X-OPcache: -1');
}
?>
diff --git a/test/php/opcache/preload/chdir.php b/test/php/opcache/preload/chdir.php
new file mode 100644
index 00000000..ad75e6ad
--- /dev/null
+++ b/test/php/opcache/preload/chdir.php
@@ -0,0 +1,7 @@
+<?php
+
+chdir(realpath(__DIR__ . '/..'));
+
+opcache_compile_file('index.php');
+
+?>
diff --git a/test/php/opcache/preload/fastcgi_finish_request.php b/test/php/opcache/preload/fastcgi_finish_request.php
new file mode 100644
index 00000000..31630cfa
--- /dev/null
+++ b/test/php/opcache/preload/fastcgi_finish_request.php
@@ -0,0 +1,5 @@
+<?php
+
+fastcgi_finish_request();
+
+?>
diff --git a/test/python/204_no_content/asgi.py b/test/python/204_no_content/asgi.py
index 634facc2..5dbb67d0 100644
--- a/test/python/204_no_content/asgi.py
+++ b/test/python/204_no_content/asgi.py
@@ -1,8 +1,10 @@
async def application(scope, receive, send):
assert scope['type'] == 'http'
- await send({
- 'type': 'http.response.start',
- 'status': 204,
- 'headers': [],
- })
+ await send(
+ {
+ 'type': 'http.response.start',
+ 'status': 204,
+ 'headers': [],
+ }
+ )
diff --git a/test/ruby/errors_write/config.ru b/test/ruby/errors_write/config.ru
index 47619d6b..79ee4d1d 100644
--- a/test/ruby/errors_write/config.ru
+++ b/test/ruby/errors_write/config.ru
@@ -1,5 +1,7 @@
app = Proc.new do |env|
env['rack.errors'].write('Error in application')
+ env['rack.errors'].flush
+ env['rack.errors'].close
['200', {'Content-Length' => '0'}, ['']]
end
diff --git a/test/ruby/input_gets/config.ru b/test/ruby/input_gets/config.ru
index 1a6633ab..151fe235 100644
--- a/test/ruby/input_gets/config.ru
+++ b/test/ruby/input_gets/config.ru
@@ -1,5 +1,6 @@
app = Proc.new do |env|
body = env['rack.input'].gets
+ env['rack.input'].close
['200', {
'Content-Length' => body.length.to_s
}, [body]]
diff --git a/test/ruby/variables/config.ru b/test/ruby/variables/config.ru
index 55d01796..e335e049 100644
--- a/test/ruby/variables/config.ru
+++ b/test/ruby/variables/config.ru
@@ -8,6 +8,7 @@ app = Proc.new do |env|
'Request-Method' => env['REQUEST_METHOD'],
'Request-Uri' => env['REQUEST_URI'],
'Http-Host' => env['HTTP_HOST'],
+ 'Script-Name' => env['SCRIPT_NAME'],
'Server-Protocol' => env['SERVER_PROTOCOL'],
'Server-Software' => env['SERVER_SOFTWARE'],
'Custom-Header' => env['HTTP_CUSTOM_HEADER'],
diff --git a/test/test_asgi_application.py b/test/test_asgi_application.py
index 021aa2b2..60fcffc1 100644
--- a/test/test_asgi_application.py
+++ b/test/test_asgi_application.py
@@ -1,14 +1,16 @@
import re
import time
-from distutils.version import LooseVersion
import pytest
+from packaging import version
from unit.applications.lang.python import TestApplicationPython
class TestASGIApplication(TestApplicationPython):
prerequisites = {
- 'modules': {'python': lambda v: LooseVersion(v) >= LooseVersion('3.5')}
+ 'modules': {
+ 'python': lambda v: version.parse(v) >= version.parse('3.5')
+ }
}
load_module = 'asgi'
diff --git a/test/test_asgi_lifespan.py b/test/test_asgi_lifespan.py
index 912d0d85..e295f7fa 100644
--- a/test/test_asgi_lifespan.py
+++ b/test/test_asgi_lifespan.py
@@ -1,14 +1,16 @@
import os
-from distutils.version import LooseVersion
from conftest import unit_stop
+from packaging import version
from unit.applications.lang.python import TestApplicationPython
from unit.option import option
class TestASGILifespan(TestApplicationPython):
prerequisites = {
- 'modules': {'python': lambda v: LooseVersion(v) >= LooseVersion('3.5')}
+ 'modules': {
+ 'python': lambda v: version.parse(v) >= version.parse('3.5')
+ }
}
load_module = 'asgi'
@@ -67,7 +69,7 @@ class TestASGILifespan(TestApplicationPython):
],
"applications": {
"targets": {
- "type": "python",
+ "type": self.get_application_type(),
"processes": {"spare": 0},
"working_directory": option.test_dir
+ "/python/lifespan/empty",
diff --git a/test/test_asgi_targets.py b/test/test_asgi_targets.py
index b9489cd3..c1e345ef 100644
--- a/test/test_asgi_targets.py
+++ b/test/test_asgi_targets.py
@@ -1,13 +1,14 @@
-from distutils.version import LooseVersion
-
import pytest
+from packaging import version
from unit.applications.lang.python import TestApplicationPython
from unit.option import option
class TestASGITargets(TestApplicationPython):
prerequisites = {
- 'modules': {'python': lambda v: LooseVersion(v) >= LooseVersion('3.5')}
+ 'modules': {
+ 'python': lambda v: version.parse(v) >= version.parse('3.5')
+ }
}
load_module = 'asgi'
@@ -28,7 +29,7 @@ class TestASGITargets(TestApplicationPython):
],
"applications": {
"targets": {
- "type": "python",
+ "type": self.get_application_type(),
"processes": {"spare": 0},
"working_directory": option.test_dir
+ "/python/targets/",
diff --git a/test/test_asgi_websockets.py b/test/test_asgi_websockets.py
index bad54e22..975be90a 100644
--- a/test/test_asgi_websockets.py
+++ b/test/test_asgi_websockets.py
@@ -1,8 +1,8 @@
import struct
import time
-from distutils.version import LooseVersion
import pytest
+from packaging import version
from unit.applications.lang.python import TestApplicationPython
from unit.applications.websockets import TestApplicationWebsocket
from unit.option import option
@@ -10,7 +10,9 @@ from unit.option import option
class TestASGIWebsockets(TestApplicationPython):
prerequisites = {
- 'modules': {'python': lambda v: LooseVersion(v) >= LooseVersion('3.5')}
+ 'modules': {
+ 'python': lambda v: version.parse(v) >= version.parse('3.5')
+ }
}
load_module = 'asgi'
@@ -162,7 +164,7 @@ class TestASGIWebsockets(TestApplicationPython):
self.ws.frame_write(sock, self.ws.OP_TEXT, 'fragment1', fin=False)
self.ws.frame_write(
- sock, self.ws.OP_CONT, 'fragment2', length=2 ** 64 - 1
+ sock, self.ws.OP_CONT, 'fragment2', length=2**64 - 1
)
self.check_close(sock, 1009) # 1009 - CLOSE_TOO_LARGE
@@ -940,9 +942,7 @@ class TestASGIWebsockets(TestApplicationPython):
frame = self.ws.frame_read(sock)
if frame['opcode'] == self.ws.OP_TEXT:
- self.check_frame(
- frame, True, self.ws.OP_TEXT, 'fragment1fragment2'
- )
+ self.check_frame(frame, True, self.ws.OP_TEXT, 'fragment1fragment2')
frame = None
self.check_close(sock, 1002, frame=frame)
@@ -1187,7 +1187,7 @@ class TestASGIWebsockets(TestApplicationPython):
_, sock, _ = self.ws.upgrade()
- self.ws.frame_write(sock, self.ws.OP_TEXT, 'BAsd7&jh23' * 26 * 2 ** 10)
+ self.ws.frame_write(sock, self.ws.OP_TEXT, 'BAsd7&jh23' * 26 * 2**10)
self.ws.frame_write(sock, self.ws.OP_TEXT, payload)
self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close())
@@ -1349,62 +1349,62 @@ class TestASGIWebsockets(TestApplicationPython):
def check_message(opcode, f_size):
if opcode == self.ws.OP_TEXT:
- payload = '*' * 4 * 2 ** 20
+ payload = '*' * 4 * 2**20
else:
- payload = b'*' * 4 * 2 ** 20
+ payload = b'*' * 4 * 2**20
self.ws.message(sock, opcode, payload, fragmention_size=f_size)
frame = self.ws.frame_read(sock, read_timeout=5)
self.check_frame(frame, True, opcode, payload)
- check_payload(op_text, 64 * 2 ** 10) # 9_1_1
- check_payload(op_text, 256 * 2 ** 10) # 9_1_2
- check_payload(op_text, 2 ** 20) # 9_1_3
- check_payload(op_text, 4 * 2 ** 20) # 9_1_4
- check_payload(op_text, 8 * 2 ** 20) # 9_1_5
- check_payload(op_text, 16 * 2 ** 20) # 9_1_6
+ check_payload(op_text, 64 * 2**10) # 9_1_1
+ check_payload(op_text, 256 * 2**10) # 9_1_2
+ check_payload(op_text, 2**20) # 9_1_3
+ check_payload(op_text, 4 * 2**20) # 9_1_4
+ check_payload(op_text, 8 * 2**20) # 9_1_5
+ check_payload(op_text, 16 * 2**20) # 9_1_6
- check_payload(op_binary, 64 * 2 ** 10) # 9_2_1
- check_payload(op_binary, 256 * 2 ** 10) # 9_2_2
- check_payload(op_binary, 2 ** 20) # 9_2_3
- check_payload(op_binary, 4 * 2 ** 20) # 9_2_4
- check_payload(op_binary, 8 * 2 ** 20) # 9_2_5
- check_payload(op_binary, 16 * 2 ** 20) # 9_2_6
+ check_payload(op_binary, 64 * 2**10) # 9_2_1
+ check_payload(op_binary, 256 * 2**10) # 9_2_2
+ check_payload(op_binary, 2**20) # 9_2_3
+ check_payload(op_binary, 4 * 2**20) # 9_2_4
+ check_payload(op_binary, 8 * 2**20) # 9_2_5
+ check_payload(op_binary, 16 * 2**20) # 9_2_6
if option.system != 'Darwin' and option.system != 'FreeBSD':
check_message(op_text, 64) # 9_3_1
check_message(op_text, 256) # 9_3_2
- check_message(op_text, 2 ** 10) # 9_3_3
- check_message(op_text, 4 * 2 ** 10) # 9_3_4
- check_message(op_text, 16 * 2 ** 10) # 9_3_5
- check_message(op_text, 64 * 2 ** 10) # 9_3_6
- check_message(op_text, 256 * 2 ** 10) # 9_3_7
- check_message(op_text, 2 ** 20) # 9_3_8
- check_message(op_text, 4 * 2 ** 20) # 9_3_9
+ check_message(op_text, 2**10) # 9_3_3
+ check_message(op_text, 4 * 2**10) # 9_3_4
+ check_message(op_text, 16 * 2**10) # 9_3_5
+ check_message(op_text, 64 * 2**10) # 9_3_6
+ check_message(op_text, 256 * 2**10) # 9_3_7
+ check_message(op_text, 2**20) # 9_3_8
+ check_message(op_text, 4 * 2**20) # 9_3_9
check_message(op_binary, 64) # 9_4_1
check_message(op_binary, 256) # 9_4_2
- check_message(op_binary, 2 ** 10) # 9_4_3
- check_message(op_binary, 4 * 2 ** 10) # 9_4_4
- check_message(op_binary, 16 * 2 ** 10) # 9_4_5
- check_message(op_binary, 64 * 2 ** 10) # 9_4_6
- check_message(op_binary, 256 * 2 ** 10) # 9_4_7
- check_message(op_binary, 2 ** 20) # 9_4_8
- check_message(op_binary, 4 * 2 ** 20) # 9_4_9
-
- check_payload(op_text, 2 ** 20, chopsize=64) # 9_5_1
- check_payload(op_text, 2 ** 20, chopsize=128) # 9_5_2
- check_payload(op_text, 2 ** 20, chopsize=256) # 9_5_3
- check_payload(op_text, 2 ** 20, chopsize=512) # 9_5_4
- check_payload(op_text, 2 ** 20, chopsize=1024) # 9_5_5
- check_payload(op_text, 2 ** 20, chopsize=2048) # 9_5_6
-
- check_payload(op_binary, 2 ** 20, chopsize=64) # 9_6_1
- check_payload(op_binary, 2 ** 20, chopsize=128) # 9_6_2
- check_payload(op_binary, 2 ** 20, chopsize=256) # 9_6_3
- check_payload(op_binary, 2 ** 20, chopsize=512) # 9_6_4
- check_payload(op_binary, 2 ** 20, chopsize=1024) # 9_6_5
- check_payload(op_binary, 2 ** 20, chopsize=2048) # 9_6_6
+ check_message(op_binary, 2**10) # 9_4_3
+ check_message(op_binary, 4 * 2**10) # 9_4_4
+ check_message(op_binary, 16 * 2**10) # 9_4_5
+ check_message(op_binary, 64 * 2**10) # 9_4_6
+ check_message(op_binary, 256 * 2**10) # 9_4_7
+ check_message(op_binary, 2**20) # 9_4_8
+ check_message(op_binary, 4 * 2**20) # 9_4_9
+
+ check_payload(op_text, 2**20, chopsize=64) # 9_5_1
+ check_payload(op_text, 2**20, chopsize=128) # 9_5_2
+ check_payload(op_text, 2**20, chopsize=256) # 9_5_3
+ check_payload(op_text, 2**20, chopsize=512) # 9_5_4
+ check_payload(op_text, 2**20, chopsize=1024) # 9_5_5
+ check_payload(op_text, 2**20, chopsize=2048) # 9_5_6
+
+ check_payload(op_binary, 2**20, chopsize=64) # 9_6_1
+ check_payload(op_binary, 2**20, chopsize=128) # 9_6_2
+ check_payload(op_binary, 2**20, chopsize=256) # 9_6_3
+ check_payload(op_binary, 2**20, chopsize=512) # 9_6_4
+ check_payload(op_binary, 2**20, chopsize=1024) # 9_6_5
+ check_payload(op_binary, 2**20, chopsize=2048) # 9_6_6
self.close_connection(sock)
diff --git a/test/test_client_ip.py b/test/test_client_ip.py
index 4b2b2fa1..53e52201 100644
--- a/test/test_client_ip.py
+++ b/test/test_client_ip.py
@@ -7,10 +7,14 @@ class TestClientIP(TestApplicationPython):
def client_ip(self, options):
assert 'success' in self.conf(
{
- "127.0.0.1:7081":
- {"client_ip": options, "pass": "applications/client_ip"},
- "[::1]:7082":
- {"client_ip": options, "pass": "applications/client_ip"},
+ "127.0.0.1:7081": {
+ "client_ip": options,
+ "pass": "applications/client_ip",
+ },
+ "[::1]:7082": {
+ "client_ip": options,
+ "pass": "applications/client_ip",
+ },
},
'listeners',
), 'listeners configure'
@@ -48,9 +52,7 @@ class TestClientIP(TestApplicationPython):
), 'ipv6 default 2'
assert self.get_xff('1.1.1.1') == '1.1.1.1', 'replace'
assert self.get_xff('blah') == '127.0.0.1', 'bad header 2'
- assert (
- self.get_xff('1.1.1.1', 'ipv6') == '::1'
- ), 'bad source ipv6 2'
+ assert self.get_xff('1.1.1.1', 'ipv6') == '::1', 'bad source ipv6 2'
self.client_ip({'header': 'X-Forwarded-For', 'source': '!127.0.0.1'})
@@ -118,10 +120,18 @@ class TestClientIP(TestApplicationPython):
def test_settings_client_ip_invalid(self):
assert 'error' in self.conf(
- {"http": {"client_ip": {'header': 'X-Forwarded-For', 'source': []}}},
+ {
+ "http": {
+ "client_ip": {'header': 'X-Forwarded-For', 'source': []}
+ }
+ },
'settings',
), 'empty array source'
assert 'error' in self.conf(
- {"http":{"client_ip": {'header': 'X-Forwarded-For', 'source': 'a'}}},
+ {
+ "http": {
+ "client_ip": {'header': 'X-Forwarded-For', 'source': 'a'}
+ }
+ },
'settings',
), 'empty source invalid'
diff --git a/test/test_go_application.py b/test/test_go_application.py
index 94da1aee..c8cf3e53 100644
--- a/test/test_go_application.py
+++ b/test/test_go_application.py
@@ -1,7 +1,6 @@
import re
import pytest
-
from unit.applications.lang.go import TestApplicationGo
@@ -158,9 +157,7 @@ class TestGoApplication(TestApplicationGo):
'applications/command_line_arguments/arguments',
)
- assert (
- self.get()['body'] == arg1 + ',' + arg2 + ',' + arg3
- ), 'arguments'
+ assert self.get()['body'] == arg1 + ',' + arg2 + ',' + arg3, 'arguments'
def test_go_application_command_line_arguments_change(self):
self.load('command_line_arguments')
@@ -177,6 +174,4 @@ class TestGoApplication(TestApplicationGo):
assert 'success' in self.conf('[]', args_path)
- assert (
- self.get()['headers']['Content-Length'] == '0'
- ), 'arguments empty'
+ assert self.get()['headers']['Content-Length'] == '0', 'arguments empty'
diff --git a/test/test_go_isolation.py b/test/test_go_isolation.py
index 72988a34..c3f92679 100644
--- a/test/test_go_isolation.py
+++ b/test/test_go_isolation.py
@@ -167,9 +167,7 @@ class TestGoIsolation(TestApplicationGo):
user='nobody',
isolation={
'namespaces': {'credential': True},
- 'uidmap': [
- {'container': 0, 'host': 0, 'size': nobody_uid + 1}
- ],
+ 'uidmap': [{'container': 0, 'host': 0, 'size': nobody_uid + 1}],
},
)
diff --git a/test/test_http_header.py b/test/test_http_header.py
index ca355eb7..6773c44f 100644
--- a/test/test_http_header.py
+++ b/test/test_http_header.py
@@ -213,7 +213,7 @@ Connection: close
self.post(
headers={
'Host': 'localhost',
- 'Content-Length': str(2 ** 64),
+ 'Content-Length': str(2**64),
'Connection': 'close',
},
body='X' * 1000,
@@ -325,9 +325,7 @@ Connection: close
def test_http_header_host_port_empty(self):
self.load('host')
- resp = self.get(
- headers={'Host': 'exmaple.com:', 'Connection': 'close'}
- )
+ resp = self.get(headers={'Host': 'exmaple.com:', 'Connection': 'close'})
assert resp['status'] == 200, 'Host port empty status'
assert (
@@ -376,9 +374,7 @@ Connection: close
def test_http_header_host_trailing_period_2(self):
self.load('host')
- resp = self.get(
- headers={'Host': 'EXAMPLE.COM.', 'Connection': 'close'}
- )
+ resp = self.get(headers={'Host': 'EXAMPLE.COM.', 'Connection': 'close'})
assert resp['status'] == 200, 'Host trailing period 2 status'
assert (
@@ -453,14 +449,16 @@ Connection: close
assert 'CUSTOM' not in resp['headers']['All-Headers']
assert 'success' in self.conf(
- {'http': {'discard_unsafe_fields': False}}, 'settings',
+ {'http': {'discard_unsafe_fields': False}},
+ 'settings',
)
resp = check_status("!#$%&'*+.^`|~Custom_Header")
assert 'CUSTOM' in resp['headers']['All-Headers']
assert 'success' in self.conf(
- {'http': {'discard_unsafe_fields': True}}, 'settings',
+ {'http': {'discard_unsafe_fields': True}},
+ 'settings',
)
resp = check_status("!Custom-Header")
diff --git a/test/test_java_application.py b/test/test_java_application.py
index 3fd5c26e..adcb4eca 100644
--- a/test/test_java_application.py
+++ b/test/test_java_application.py
@@ -22,7 +22,7 @@ class TestJavaApplication(TestApplicationJava):
"listeners": {"*:7080": {"pass": "applications/app"}},
"applications": {
"app": {
- "type": "java",
+ "type": self.get_application_type(),
"processes": 1,
"working_directory": option.test_dir + "/java/empty",
"webapp": temp_dir + "/java",
@@ -173,9 +173,7 @@ class TestJavaApplication(TestApplicationJava):
}
)
- assert (
- resp['headers']['X-Session-Id'] == session_id
- ), 'session active 2'
+ assert resp['headers']['X-Session-Id'] == session_id, 'session active 2'
time.sleep(2)
@@ -187,9 +185,7 @@ class TestJavaApplication(TestApplicationJava):
}
)
- assert (
- resp['headers']['X-Session-Id'] == session_id
- ), 'session active 3'
+ assert resp['headers']['X-Session-Id'] == session_id, 'session active 3'
def test_java_application_session_inactive(self):
self.load('session_inactive')
@@ -213,9 +209,7 @@ class TestJavaApplication(TestApplicationJava):
}
)
- assert (
- resp['headers']['X-Session-Id'] != session_id
- ), 'session inactive'
+ assert resp['headers']['X-Session-Id'] != session_id, 'session inactive'
def test_java_application_session_invalidate(self):
self.load('session_invalidate')
@@ -391,9 +385,7 @@ class TestJavaApplication(TestApplicationJava):
assert (
headers['X-Content-Type'] == 'text/plain;charset=utf-8'
), '#1 response Content-Type'
- assert (
- headers['X-Character-Encoding'] == 'utf-8'
- ), '#1 response charset'
+ assert headers['X-Character-Encoding'] == 'utf-8', '#1 response charset'
headers = self.get(url='/2')['headers']
@@ -445,15 +437,11 @@ class TestJavaApplication(TestApplicationJava):
headers = self.get(url='/6')['headers']
- assert (
- 'Content-Type' in headers
- ) == False, '#6 no Content-Type header'
+ assert ('Content-Type' in headers) == False, '#6 no Content-Type header'
assert (
'X-Content-Type' in headers
) == False, '#6 no response Content-Type'
- assert (
- headers['X-Character-Encoding'] == 'utf-8'
- ), '#6 response charset'
+ assert headers['X-Character-Encoding'] == 'utf-8', '#6 response charset'
headers = self.get(url='/7')['headers']
@@ -463,9 +451,7 @@ class TestJavaApplication(TestApplicationJava):
assert (
headers['X-Content-Type'] == 'text/plain;charset=utf-8'
), '#7 response Content-Type'
- assert (
- headers['X-Character-Encoding'] == 'utf-8'
- ), '#7 response charset'
+ assert headers['X-Character-Encoding'] == 'utf-8', '#7 response charset'
headers = self.get(url='/8')['headers']
@@ -475,9 +461,7 @@ class TestJavaApplication(TestApplicationJava):
assert (
headers['X-Content-Type'] == 'text/html;charset=utf-8'
), '#8 response Content-Type'
- assert (
- headers['X-Character-Encoding'] == 'utf-8'
- ), '#8 response charset'
+ assert headers['X-Character-Encoding'] == 'utf-8', '#8 response charset'
def test_java_application_welcome_files(self):
self.load('welcome_files')
@@ -490,9 +474,7 @@ class TestJavaApplication(TestApplicationJava):
resp = self.get(url='/dir1/')
- assert (
- 'This is index.txt.' in resp['body']
- ) == True, 'dir1 index body'
+ assert ('This is index.txt.' in resp['body']) == True, 'dir1 index body'
assert resp['headers']['X-TXT-Filter'] == '1', 'TXT Filter header'
headers = self.get(url='/dir2/')['headers']
@@ -655,9 +637,7 @@ class TestJavaApplication(TestApplicationJava):
assert (
headers['X-FORWARD-Id'] == 'data'
), 'forward request servlet mapping'
- assert (
- headers['X-FORWARD-Request-URI'] == '/fwd'
- ), 'forward request uri'
+ assert headers['X-FORWARD-Request-URI'] == '/fwd', 'forward request uri'
assert (
headers['X-FORWARD-Servlet-Path'] == '/fwd'
), 'forward request servlet path'
@@ -1003,9 +983,7 @@ class TestJavaApplication(TestApplicationJava):
)
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 (
self.search_in_log(
r'^Data from sample file$', name=reldst + '/sample.txt'
diff --git a/test/test_java_isolation_rootfs.py b/test/test_java_isolation_rootfs.py
index eac86a0c..3c6a45a3 100644
--- a/test/test_java_isolation_rootfs.py
+++ b/test/test_java_isolation_rootfs.py
@@ -11,7 +11,7 @@ class TestJavaIsolationRootfs(TestApplicationJava):
def setup_method(self, is_su):
if not is_su:
- return
+ pytest.skip('require root')
os.makedirs(option.temp_dir + '/jars')
os.makedirs(option.temp_dir + '/tmp')
@@ -61,7 +61,8 @@ class TestJavaIsolationRootfs(TestApplicationJava):
self.load('empty_war', isolation=isolation)
assert 'success' in self.conf(
- '"/"', '/config/applications/empty_war/working_directory',
+ '"/"',
+ '/config/applications/empty_war/working_directory',
)
assert 'success' in self.conf(
diff --git a/test/test_java_websockets.py b/test/test_java_websockets.py
index a80d3bf3..362c8619 100644
--- a/test/test_java_websockets.py
+++ b/test/test_java_websockets.py
@@ -869,9 +869,7 @@ class TestJavaWebsockets(TestApplicationJava):
frame = self.ws.frame_read(sock)
if frame['opcode'] == self.ws.OP_TEXT:
- self.check_frame(
- frame, True, self.ws.OP_TEXT, 'fragment1fragment2'
- )
+ self.check_frame(frame, True, self.ws.OP_TEXT, 'fragment1fragment2')
frame = None
self.check_close(sock, 1002, frame=frame)
@@ -1116,7 +1114,7 @@ class TestJavaWebsockets(TestApplicationJava):
_, sock, _ = self.ws.upgrade()
- self.ws.frame_write(sock, self.ws.OP_TEXT, 'BAsd7&jh23' * 26 * 2 ** 10)
+ self.ws.frame_write(sock, self.ws.OP_TEXT, 'BAsd7&jh23' * 26 * 2**10)
self.ws.frame_write(sock, self.ws.OP_TEXT, payload)
self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close())
@@ -1278,62 +1276,62 @@ class TestJavaWebsockets(TestApplicationJava):
def check_message(opcode, f_size):
if opcode == self.ws.OP_TEXT:
- payload = '*' * 4 * 2 ** 20
+ payload = '*' * 4 * 2**20
else:
- payload = b'*' * 4 * 2 ** 20
+ payload = b'*' * 4 * 2**20
self.ws.message(sock, opcode, payload, fragmention_size=f_size)
frame = self.ws.frame_read(sock, read_timeout=5)
self.check_frame(frame, True, opcode, payload)
- check_payload(op_text, 64 * 2 ** 10) # 9_1_1
- check_payload(op_text, 256 * 2 ** 10) # 9_1_2
- check_payload(op_text, 2 ** 20) # 9_1_3
- check_payload(op_text, 4 * 2 ** 20) # 9_1_4
- check_payload(op_text, 8 * 2 ** 20) # 9_1_5
- check_payload(op_text, 16 * 2 ** 20) # 9_1_6
+ check_payload(op_text, 64 * 2**10) # 9_1_1
+ check_payload(op_text, 256 * 2**10) # 9_1_2
+ check_payload(op_text, 2**20) # 9_1_3
+ check_payload(op_text, 4 * 2**20) # 9_1_4
+ check_payload(op_text, 8 * 2**20) # 9_1_5
+ check_payload(op_text, 16 * 2**20) # 9_1_6
- check_payload(op_binary, 64 * 2 ** 10) # 9_2_1
- check_payload(op_binary, 256 * 2 ** 10) # 9_2_2
- check_payload(op_binary, 2 ** 20) # 9_2_3
- check_payload(op_binary, 4 * 2 ** 20) # 9_2_4
- check_payload(op_binary, 8 * 2 ** 20) # 9_2_5
- check_payload(op_binary, 16 * 2 ** 20) # 9_2_6
+ check_payload(op_binary, 64 * 2**10) # 9_2_1
+ check_payload(op_binary, 256 * 2**10) # 9_2_2
+ check_payload(op_binary, 2**20) # 9_2_3
+ check_payload(op_binary, 4 * 2**20) # 9_2_4
+ check_payload(op_binary, 8 * 2**20) # 9_2_5
+ check_payload(op_binary, 16 * 2**20) # 9_2_6
if option.system != 'Darwin' and option.system != 'FreeBSD':
check_message(op_text, 64) # 9_3_1
check_message(op_text, 256) # 9_3_2
- check_message(op_text, 2 ** 10) # 9_3_3
- check_message(op_text, 4 * 2 ** 10) # 9_3_4
- check_message(op_text, 16 * 2 ** 10) # 9_3_5
- check_message(op_text, 64 * 2 ** 10) # 9_3_6
- check_message(op_text, 256 * 2 ** 10) # 9_3_7
- check_message(op_text, 2 ** 20) # 9_3_8
- check_message(op_text, 4 * 2 ** 20) # 9_3_9
+ check_message(op_text, 2**10) # 9_3_3
+ check_message(op_text, 4 * 2**10) # 9_3_4
+ check_message(op_text, 16 * 2**10) # 9_3_5
+ check_message(op_text, 64 * 2**10) # 9_3_6
+ check_message(op_text, 256 * 2**10) # 9_3_7
+ check_message(op_text, 2**20) # 9_3_8
+ check_message(op_text, 4 * 2**20) # 9_3_9
check_message(op_binary, 64) # 9_4_1
check_message(op_binary, 256) # 9_4_2
- check_message(op_binary, 2 ** 10) # 9_4_3
- check_message(op_binary, 4 * 2 ** 10) # 9_4_4
- check_message(op_binary, 16 * 2 ** 10) # 9_4_5
- check_message(op_binary, 64 * 2 ** 10) # 9_4_6
- check_message(op_binary, 256 * 2 ** 10) # 9_4_7
- check_message(op_binary, 2 ** 20) # 9_4_8
- check_message(op_binary, 4 * 2 ** 20) # 9_4_9
-
- check_payload(op_text, 2 ** 20, chopsize=64) # 9_5_1
- check_payload(op_text, 2 ** 20, chopsize=128) # 9_5_2
- check_payload(op_text, 2 ** 20, chopsize=256) # 9_5_3
- check_payload(op_text, 2 ** 20, chopsize=512) # 9_5_4
- check_payload(op_text, 2 ** 20, chopsize=1024) # 9_5_5
- check_payload(op_text, 2 ** 20, chopsize=2048) # 9_5_6
-
- check_payload(op_binary, 2 ** 20, chopsize=64) # 9_6_1
- check_payload(op_binary, 2 ** 20, chopsize=128) # 9_6_2
- check_payload(op_binary, 2 ** 20, chopsize=256) # 9_6_3
- check_payload(op_binary, 2 ** 20, chopsize=512) # 9_6_4
- check_payload(op_binary, 2 ** 20, chopsize=1024) # 9_6_5
- check_payload(op_binary, 2 ** 20, chopsize=2048) # 9_6_6
+ check_message(op_binary, 2**10) # 9_4_3
+ check_message(op_binary, 4 * 2**10) # 9_4_4
+ check_message(op_binary, 16 * 2**10) # 9_4_5
+ check_message(op_binary, 64 * 2**10) # 9_4_6
+ check_message(op_binary, 256 * 2**10) # 9_4_7
+ check_message(op_binary, 2**20) # 9_4_8
+ check_message(op_binary, 4 * 2**20) # 9_4_9
+
+ check_payload(op_text, 2**20, chopsize=64) # 9_5_1
+ check_payload(op_text, 2**20, chopsize=128) # 9_5_2
+ check_payload(op_text, 2**20, chopsize=256) # 9_5_3
+ check_payload(op_text, 2**20, chopsize=512) # 9_5_4
+ check_payload(op_text, 2**20, chopsize=1024) # 9_5_5
+ check_payload(op_text, 2**20, chopsize=2048) # 9_5_6
+
+ check_payload(op_binary, 2**20, chopsize=64) # 9_6_1
+ check_payload(op_binary, 2**20, chopsize=128) # 9_6_2
+ check_payload(op_binary, 2**20, chopsize=256) # 9_6_3
+ check_payload(op_binary, 2**20, chopsize=512) # 9_6_4
+ check_payload(op_binary, 2**20, chopsize=1024) # 9_6_5
+ check_payload(op_binary, 2**20, chopsize=2048) # 9_6_6
self.close_connection(sock)
diff --git a/test/test_node_application.py b/test/test_node_application.py
index 62a09c43..fc722582 100644
--- a/test/test_node_application.py
+++ b/test/test_node_application.py
@@ -218,9 +218,7 @@ class TestNodeApplication(TestApplicationNode):
def test_node_application_status_message(self):
self.load('status_message')
- assert re.search(
- r'200 blah', self.get(raw_resp=True)
- ), 'status message'
+ assert re.search(r'200 blah', self.get(raw_resp=True)), 'status message'
def test_node_application_get_header_type(self):
self.load('get_header_type')
diff --git a/test/test_node_es_modules.py b/test/test_node_es_modules.py
index 12788fa4..8a9cb181 100644
--- a/test/test_node_es_modules.py
+++ b/test/test_node_es_modules.py
@@ -1,5 +1,4 @@
-from distutils.version import LooseVersion
-
+from packaging import version
from unit.applications.lang.node import TestApplicationNode
from unit.applications.websockets import TestApplicationWebsocket
@@ -7,7 +6,7 @@ from unit.applications.websockets import TestApplicationWebsocket
class TestNodeESModules(TestApplicationNode):
prerequisites = {
'modules': {
- 'node': lambda v: LooseVersion(v) >= LooseVersion("14.16.0")
+ 'node': lambda v: version.parse(v) >= version.parse('14.16.0')
}
}
diff --git a/test/test_node_websockets.py b/test/test_node_websockets.py
index e4c8a05e..1f9a2e6b 100644
--- a/test/test_node_websockets.py
+++ b/test/test_node_websockets.py
@@ -888,9 +888,7 @@ class TestNodeWebsockets(TestApplicationNode):
frame = self.ws.frame_read(sock)
if frame['opcode'] == self.ws.OP_TEXT:
- self.check_frame(
- frame, True, self.ws.OP_TEXT, 'fragment1fragment2'
- )
+ self.check_frame(frame, True, self.ws.OP_TEXT, 'fragment1fragment2')
frame = None
self.check_close(sock, 1002, frame=frame)
@@ -1135,7 +1133,7 @@ class TestNodeWebsockets(TestApplicationNode):
_, sock, _ = self.ws.upgrade()
- self.ws.frame_write(sock, self.ws.OP_TEXT, 'BAsd7&jh23' * 26 * 2 ** 10)
+ self.ws.frame_write(sock, self.ws.OP_TEXT, 'BAsd7&jh23' * 26 * 2**10)
self.ws.frame_write(sock, self.ws.OP_TEXT, payload)
self.ws.frame_write(sock, self.ws.OP_CLOSE, self.ws.serialize_close())
@@ -1297,62 +1295,62 @@ class TestNodeWebsockets(TestApplicationNode):
def check_message(opcode, f_size):
if opcode == self.ws.OP_TEXT:
- payload = '*' * 4 * 2 ** 20
+ payload = '*' * 4 * 2**20
else:
- payload = b'*' * 4 * 2 ** 20
+ payload = b'*' * 4 * 2**20
self.ws.message(sock, opcode, payload, fragmention_size=f_size)
frame = self.ws.frame_read(sock, read_timeout=5)
self.check_frame(frame, True, opcode, payload)
- check_payload(op_text, 64 * 2 ** 10) # 9_1_1
- check_payload(op_text, 256 * 2 ** 10) # 9_1_2
- check_payload(op_text, 2 ** 20) # 9_1_3
- check_payload(op_text, 4 * 2 ** 20) # 9_1_4
- check_payload(op_text, 8 * 2 ** 20) # 9_1_5
- check_payload(op_text, 16 * 2 ** 20) # 9_1_6
+ check_payload(op_text, 64 * 2**10) # 9_1_1
+ check_payload(op_text, 256 * 2**10) # 9_1_2
+ check_payload(op_text, 2**20) # 9_1_3
+ check_payload(op_text, 4 * 2**20) # 9_1_4
+ check_payload(op_text, 8 * 2**20) # 9_1_5
+ check_payload(op_text, 16 * 2**20) # 9_1_6
- check_payload(op_binary, 64 * 2 ** 10) # 9_2_1
- check_payload(op_binary, 256 * 2 ** 10) # 9_2_2
- check_payload(op_binary, 2 ** 20) # 9_2_3
- check_payload(op_binary, 4 * 2 ** 20) # 9_2_4
- check_payload(op_binary, 8 * 2 ** 20) # 9_2_5
- check_payload(op_binary, 16 * 2 ** 20) # 9_2_6
+ check_payload(op_binary, 64 * 2**10) # 9_2_1
+ check_payload(op_binary, 256 * 2**10) # 9_2_2
+ check_payload(op_binary, 2**20) # 9_2_3
+ check_payload(op_binary, 4 * 2**20) # 9_2_4
+ check_payload(op_binary, 8 * 2**20) # 9_2_5
+ check_payload(op_binary, 16 * 2**20) # 9_2_6
if option.system != 'Darwin' and option.system != 'FreeBSD':
check_message(op_text, 64) # 9_3_1
check_message(op_text, 256) # 9_3_2
- check_message(op_text, 2 ** 10) # 9_3_3
- check_message(op_text, 4 * 2 ** 10) # 9_3_4
- check_message(op_text, 16 * 2 ** 10) # 9_3_5
- check_message(op_text, 64 * 2 ** 10) # 9_3_6
- check_message(op_text, 256 * 2 ** 10) # 9_3_7
- check_message(op_text, 2 ** 20) # 9_3_8
- check_message(op_text, 4 * 2 ** 20) # 9_3_9
+ check_message(op_text, 2**10) # 9_3_3
+ check_message(op_text, 4 * 2**10) # 9_3_4
+ check_message(op_text, 16 * 2**10) # 9_3_5
+ check_message(op_text, 64 * 2**10) # 9_3_6
+ check_message(op_text, 256 * 2**10) # 9_3_7
+ check_message(op_text, 2**20) # 9_3_8
+ check_message(op_text, 4 * 2**20) # 9_3_9
check_message(op_binary, 64) # 9_4_1
check_message(op_binary, 256) # 9_4_2
- check_message(op_binary, 2 ** 10) # 9_4_3
- check_message(op_binary, 4 * 2 ** 10) # 9_4_4
- check_message(op_binary, 16 * 2 ** 10) # 9_4_5
- check_message(op_binary, 64 * 2 ** 10) # 9_4_6
- check_message(op_binary, 256 * 2 ** 10) # 9_4_7
- check_message(op_binary, 2 ** 20) # 9_4_8
- check_message(op_binary, 4 * 2 ** 20) # 9_4_9
-
- check_payload(op_text, 2 ** 20, chopsize=64) # 9_5_1
- check_payload(op_text, 2 ** 20, chopsize=128) # 9_5_2
- check_payload(op_text, 2 ** 20, chopsize=256) # 9_5_3
- check_payload(op_text, 2 ** 20, chopsize=512) # 9_5_4
- check_payload(op_text, 2 ** 20, chopsize=1024) # 9_5_5
- check_payload(op_text, 2 ** 20, chopsize=2048) # 9_5_6
-
- check_payload(op_binary, 2 ** 20, chopsize=64) # 9_6_1
- check_payload(op_binary, 2 ** 20, chopsize=128) # 9_6_2
- check_payload(op_binary, 2 ** 20, chopsize=256) # 9_6_3
- check_payload(op_binary, 2 ** 20, chopsize=512) # 9_6_4
- check_payload(op_binary, 2 ** 20, chopsize=1024) # 9_6_5
- check_payload(op_binary, 2 ** 20, chopsize=2048) # 9_6_6
+ check_message(op_binary, 2**10) # 9_4_3
+ check_message(op_binary, 4 * 2**10) # 9_4_4
+ check_message(op_binary, 16 * 2**10) # 9_4_5
+ check_message(op_binary, 64 * 2**10) # 9_4_6
+ check_message(op_binary, 256 * 2**10) # 9_4_7
+ check_message(op_binary, 2**20) # 9_4_8
+ check_message(op_binary, 4 * 2**20) # 9_4_9
+
+ check_payload(op_text, 2**20, chopsize=64) # 9_5_1
+ check_payload(op_text, 2**20, chopsize=128) # 9_5_2
+ check_payload(op_text, 2**20, chopsize=256) # 9_5_3
+ check_payload(op_text, 2**20, chopsize=512) # 9_5_4
+ check_payload(op_text, 2**20, chopsize=1024) # 9_5_5
+ check_payload(op_text, 2**20, chopsize=2048) # 9_5_6
+
+ check_payload(op_binary, 2**20, chopsize=64) # 9_6_1
+ check_payload(op_binary, 2**20, chopsize=128) # 9_6_2
+ check_payload(op_binary, 2**20, chopsize=256) # 9_6_3
+ check_payload(op_binary, 2**20, chopsize=512) # 9_6_4
+ check_payload(op_binary, 2**20, chopsize=1024) # 9_6_5
+ check_payload(op_binary, 2**20, chopsize=2048) # 9_6_6
self.close_connection(sock)
diff --git a/test/test_perl_application.py b/test/test_perl_application.py
index dfd8be6c..0d1d7906 100644
--- a/test/test_perl_application.py
+++ b/test/test_perl_application.py
@@ -100,6 +100,22 @@ class TestPerlApplication(TestApplicationPerl):
self.post(body='0123456789')['body'] == '0123456789'
), 'input read parts'
+ def test_perl_application_input_buffered_read(self):
+ self.load('input_buffered_read')
+
+ assert self.post(body='012345')['body'] == '012345', 'buffered read #1'
+ assert (
+ self.post(body='9876543210')['body'] == '9876543210'
+ ), 'buffered read #2'
+
+ def test_perl_application_input_close(self):
+ self.load('input_close')
+
+ assert self.post(body='012345')['body'] == '012345', 'input close #1'
+ assert (
+ self.post(body='9876543210')['body'] == '9876543210'
+ ), 'input close #2'
+
@pytest.mark.skip('not yet')
def test_perl_application_input_read_offset(self):
self.load('input_read_offset')
@@ -118,8 +134,7 @@ class TestPerlApplication(TestApplicationPerl):
assert self.get()['body'] == '1', 'errors result'
assert (
- self.wait_for_record(r'\[error\].+Error in application')
- is not None
+ self.wait_for_record(r'\[error\].+Error in application') is not None
), 'errors print'
def test_perl_application_header_equal_names(self):
diff --git a/test/test_php_application.py b/test/test_php_application.py
index d9c16a6d..606ac723 100644
--- a/test/test_php_application.py
+++ b/test/test_php_application.py
@@ -1,3 +1,4 @@
+import getpass
import os
import re
import shutil
@@ -18,18 +19,43 @@ class TestPHPApplication(TestApplicationPHP):
assert re.search(r'time: \d+', body), 'disable_functions before time'
assert re.search(r'exec: \/\w+', body), 'disable_functions before exec'
+ def check_opcache(self):
+ resp = self.get()
+ assert resp['status'] == 200, 'status'
+
+ headers = resp['headers']
+ if 'X-OPcache' in headers and headers['X-OPcache'] == '-1':
+ pytest.skip('opcache is not supported')
+
+ return resp
+
def set_opcache(self, app, val):
assert 'success' in self.conf(
{"admin": {"opcache.enable": val, "opcache.enable_cli": val}},
'applications/' + app + '/options',
)
- opcache = self.get()['headers']['X-OPcache']
-
- if not opcache or opcache == '-1':
- pytest.skip('opcache is not supported')
+ r = self.check_opcache()
+ assert r['headers']['X-OPcache'] == val, 'opcache value'
+
+ def set_preload(self, preload):
+ with open(option.temp_dir + '/php.ini', 'w') as f:
+ f.write(
+ """opcache.preload = %(test_dir)s/php/opcache/preload\
+/%(preload)s
+opcache.preload_user = %(user)s
+"""
+ % {
+ 'test_dir': option.test_dir,
+ 'preload': preload,
+ 'user': option.user or getpass.getuser(),
+ }
+ )
- assert opcache == val, 'opcache value'
+ assert 'success' in self.conf(
+ {"file": option.temp_dir + "/php.ini"},
+ 'applications/opcache/options',
+ )
def test_php_application_variables(self):
self.load('variables')
@@ -294,20 +320,28 @@ class TestPHPApplication(TestApplicationPHP):
self.load('ini_precision')
assert 'success' in self.conf(
- {"file": "php.ini", "admin": {"precision": "5"}},
+ {"file": "ini/php.ini", "admin": {"precision": "5"}},
'applications/ini_precision/options',
)
+ assert (
+ self.get()['headers']['X-File']
+ == option.test_dir + '/php/ini_precision/ini/php.ini'
+ ), 'ini file'
assert self.get()['headers']['X-Precision'] == '5', 'ini value admin'
def test_php_application_ini_user(self):
self.load('ini_precision')
assert 'success' in self.conf(
- {"file": "php.ini", "user": {"precision": "5"}},
+ {"file": "ini/php.ini", "user": {"precision": "5"}},
'applications/ini_precision/options',
)
+ assert (
+ self.get()['headers']['X-File']
+ == option.test_dir + '/php/ini_precision/ini/php.ini'
+ ), 'ini file'
assert self.get()['headers']['X-Precision'] == '5', 'ini value user'
def test_php_application_ini_user_2(self):
@@ -385,9 +419,7 @@ class TestPHPApplication(TestApplicationPHP):
body = self.get()['body']
- assert not re.search(
- r'time: \d+', body
- ), 'disable_functions comma time'
+ assert not re.search(r'time: \d+', body), 'disable_functions comma time'
assert not re.search(
r'exec: \/\w+', body
), 'disable_functions comma exec'
@@ -464,9 +496,7 @@ class TestPHPApplication(TestApplicationPHP):
body = self.get()['body']
- assert not re.search(
- r'time: \d+', body
- ), 'disable_functions space time'
+ assert not re.search(r'time: \d+', body), 'disable_functions space time'
assert not re.search(
r'exec: \/\w+', body
), 'disable_functions space exec'
@@ -566,7 +596,7 @@ class TestPHPApplication(TestApplicationPHP):
"listeners": {"*:7080": {"pass": "applications/script"}},
"applications": {
"script": {
- "type": "php",
+ "type": self.get_application_type(),
"processes": {"spare": 0},
"root": option.test_dir + "/php/script",
"script": "phpinfo.php",
@@ -586,7 +616,7 @@ class TestPHPApplication(TestApplicationPHP):
"listeners": {"*:7080": {"pass": "applications/phpinfo"}},
"applications": {
"phpinfo": {
- "type": "php",
+ "type": self.get_application_type(),
"processes": {"spare": 0},
"root": option.test_dir + "/php/phpinfo",
}
@@ -613,7 +643,7 @@ class TestPHPApplication(TestApplicationPHP):
"listeners": {"*:7080": {"pass": "applications/phpinfo"}},
"applications": {
"phpinfo": {
- "type": "php",
+ "type": self.get_application_type(),
"processes": {"spare": 0},
"root": new_root,
"working_directory": new_root,
@@ -637,7 +667,8 @@ class TestPHPApplication(TestApplicationPHP):
assert resp['body'] == script_cwd, 'default cwd'
assert 'success' in self.conf(
- '"' + option.test_dir + '"', 'applications/cwd/working_directory',
+ '"' + option.test_dir + '"',
+ 'applications/cwd/working_directory',
)
resp = self.get()
@@ -717,16 +748,31 @@ class TestPHPApplication(TestApplicationPHP):
def test_php_application_shared_opcache(self):
self.load('opcache', limits={'requests': 1})
- r = self.get()
- cached = r['headers']['X-Cached']
- if cached == '-1':
- pytest.skip('opcache is not supported')
-
+ r = self.check_opcache()
pid = r['headers']['X-Pid']
-
- assert cached == '0', 'not cached'
+ assert r['headers']['X-Cached'] == '0', 'not cached'
r = self.get()
assert r['headers']['X-Pid'] != pid, 'new instance'
assert r['headers']['X-Cached'] == '1', 'cached'
+
+ def test_php_application_opcache_preload_chdir(self, temp_dir):
+ self.load('opcache')
+
+ self.check_opcache()
+
+ self.set_preload('chdir.php')
+
+ assert self.get()['headers']['X-Cached'] == '0', 'not cached'
+ assert self.get()['headers']['X-Cached'] == '1', 'cached'
+
+ def test_php_application_opcache_preload_ffr(self, temp_dir):
+ self.load('opcache')
+
+ self.check_opcache()
+
+ self.set_preload('fastcgi_finish_request.php')
+
+ assert self.get()['headers']['X-Cached'] == '0', 'not cached'
+ assert self.get()['headers']['X-Cached'] == '1', 'cached'
diff --git a/test/test_php_targets.py b/test/test_php_targets.py
index 76326131..918c5fda 100644
--- a/test/test_php_targets.py
+++ b/test/test_php_targets.py
@@ -22,7 +22,7 @@ class TestPHPTargets(TestApplicationPHP):
],
"applications": {
"targets": {
- "type": "php",
+ "type": self.get_application_type(),
"processes": {"spare": 0},
"targets": {
"1": {
@@ -66,7 +66,7 @@ class TestPHPTargets(TestApplicationPHP):
},
"applications": {
"targets": {
- "type": "php",
+ "type": self.get_application_type(),
"processes": {"spare": 0},
"targets": {
"default": {
diff --git a/test/test_proxy.py b/test/test_proxy.py
index 553cb07c..68ae2394 100644
--- a/test/test_proxy.py
+++ b/test/test_proxy.py
@@ -72,15 +72,14 @@ Content-Length: 10
"routes": [{"action": {"proxy": "http://127.0.0.1:7081"}}],
"applications": {
"mirror": {
- "type": "python",
+ "type": self.get_application_type(),
"processes": {"spare": 0},
"path": option.test_dir + "/python/mirror",
- "working_directory": option.test_dir
- + "/python/mirror",
+ "working_directory": option.test_dir + "/python/mirror",
"module": "wsgi",
},
"custom_header": {
- "type": "python",
+ "type": self.get_application_type(),
"processes": {"spare": 0},
"path": option.test_dir + "/python/custom_header",
"working_directory": option.test_dir
@@ -88,7 +87,7 @@ Content-Length: 10
"module": "wsgi",
},
"delayed": {
- "type": "python",
+ "type": self.get_application_type(),
"processes": {"spare": 0},
"path": option.test_dir + "/python/delayed",
"working_directory": option.test_dir
@@ -123,11 +122,10 @@ Content-Length: 10
},
"applications": {
"mirror": {
- "type": "python",
+ "type": self.get_application_type(),
"processes": {"spare": 0},
"path": option.test_dir + "/python/mirror",
- "working_directory": option.test_dir
- + "/python/mirror",
+ "working_directory": option.test_dir + "/python/mirror",
"module": "wsgi",
}
},
@@ -499,11 +497,10 @@ Content-Length: 10
"routes": [{"action": {"proxy": "http://127.0.0.1:7082"}}],
"applications": {
"mirror": {
- "type": "python",
+ "type": self.get_application_type(),
"processes": {"spare": 0},
"path": option.test_dir + "/python/mirror",
- "working_directory": option.test_dir
- + "/python/mirror",
+ "working_directory": option.test_dir + "/python/mirror",
"module": "wsgi",
},
},
diff --git a/test/test_proxy_chunked.py b/test/test_proxy_chunked.py
index 73d94332..f024eaf5 100644
--- a/test/test_proxy_chunked.py
+++ b/test/test_proxy_chunked.py
@@ -90,12 +90,13 @@ class TestProxyChunked(TestApplicationPython):
assert 'success' in self.conf(
{
- "listeners": {"*:7080": {"pass": "routes"},},
+ "listeners": {
+ "*:7080": {"pass": "routes"},
+ },
"routes": [
{
"action": {
- "proxy": "http://127.0.0.1:"
- + str(self.SERVER_PORT)
+ "proxy": "http://127.0.0.1:" + str(self.SERVER_PORT)
}
}
],
@@ -166,9 +167,7 @@ class TestProxyChunked(TestApplicationPython):
assert (
self.get_http10(
- body=self.chunks(
- [('1', hex(i % 16)[2:]) for i in range(4096)]
- ),
+ body=self.chunks([('1', hex(i % 16)[2:]) for i in range(4096)]),
)['body']
== part * 256
)
@@ -210,8 +209,7 @@ class TestProxyChunked(TestApplicationPython):
assert resp['body'][-5:] != '0\r\n\r\n', 'no zero chunk'
assert (
- self.get_http10(body='\r\n\r\n80000000\r\nA X 100')['status']
- == 200
+ self.get_http10(body='\r\n\r\n80000000\r\nA X 100')['status'] == 200
)
assert (
self.get_http10(body='\r\n\r\n10000000000000000\r\nA X 100')[
diff --git a/test/test_python_application.py b/test/test_python_application.py
index 7bd43664..befbd4d8 100644
--- a/test/test_python_application.py
+++ b/test/test_python_application.py
@@ -293,36 +293,6 @@ custom-header: BLAH
assert resp == {}, 'reconfigure 2 keep-alive 3'
- def test_python_keepalive_reconfigure_3(self):
- self.load('empty')
-
- assert self.get()['status'] == 200, 'init'
-
- (_, sock) = self.http(
- b"""GET / HTTP/1.1
-""",
- start=True,
- raw=True,
- no_recv=True,
- )
-
- assert self.get()['status'] == 200
-
- assert 'success' in self.conf(
- {"listeners": {}, "applications": {}}
- ), 'reconfigure 3 clear configuration'
-
- resp = self.http(
- b"""Host: localhost
-Connection: close
-
-""",
- sock=sock,
- raw=True,
- )
-
- assert resp['status'] == 200, 'reconfigure 3'
-
def test_python_atexit(self):
self.load('atexit')
@@ -735,9 +705,7 @@ last line: 987654321
'nobody uid user=nobody group=%s' % group
)
- assert obj['GID'] == group_id, (
- 'nobody gid user=nobody group=%s' % group
- )
+ assert obj['GID'] == group_id, 'nobody gid user=nobody group=%s' % group
self.load('user_group', group=group)
diff --git a/test/test_python_isolation.py b/test/test_python_isolation.py
index 53d28285..8cef6812 100644
--- a/test/test_python_isolation.py
+++ b/test/test_python_isolation.py
@@ -56,9 +56,7 @@ class TestPythonIsolation(TestApplicationPython):
ret = self.getjson(url='/?path=/app/python/ns_inspect')
- assert (
- ret['body']['FileExists'] == True
- ), 'application exists in rootfs'
+ assert ret['body']['FileExists'] == True, 'application exists in rootfs'
def test_python_isolation_rootfs_no_language_deps(self, is_su, temp_dir):
if not is_su:
@@ -93,8 +91,7 @@ class TestPythonIsolation(TestApplicationPython):
self.load('ns_inspect', isolation=isolation)
assert (
- self.getjson(url='/?path=/proc/self')['body']['FileExists']
- == False
+ self.getjson(url='/?path=/proc/self')['body']['FileExists'] == False
), 'no /proc/self'
isolation['automount']['procfs'] = True
diff --git a/test/test_python_isolation_chroot.py b/test/test_python_isolation_chroot.py
index 1554fb72..8e5b5fce 100644
--- a/test/test_python_isolation_chroot.py
+++ b/test/test_python_isolation_chroot.py
@@ -35,6 +35,4 @@ class TestPythonIsolation(TestApplicationPython):
ret = self.getjson(url='/?path=/app/python/ns_inspect')
- assert (
- ret['body']['FileExists'] == True
- ), 'application exists in rootfs'
+ assert ret['body']['FileExists'] == True, 'application exists in rootfs'
diff --git a/test/test_python_targets.py b/test/test_python_targets.py
index e5dca870..8e9ecb87 100644
--- a/test/test_python_targets.py
+++ b/test/test_python_targets.py
@@ -21,7 +21,7 @@ class TestPythonTargets(TestApplicationPython):
],
"applications": {
"targets": {
- "type": "python",
+ "type": self.get_application_type(),
"working_directory": option.test_dir
+ "/python/targets/",
"path": option.test_dir + '/python/targets/',
diff --git a/test/test_reconfigure.py b/test/test_reconfigure.py
new file mode 100644
index 00000000..ab05a1c8
--- /dev/null
+++ b/test/test_reconfigure.py
@@ -0,0 +1,53 @@
+import time
+
+import pytest
+from unit.applications.proto import TestApplicationProto
+
+
+class TestReconfigure(TestApplicationProto):
+ prerequisites = {}
+
+ @pytest.fixture(autouse=True)
+ def setup_method_fixture(self):
+ assert 'success' in self.conf(
+ {
+ "listeners": {"*:7080": {"pass": "routes"}},
+ "routes": [{"action": {"return": 200}}],
+ "applications": {},
+ }
+ )
+
+ def clear_conf(self):
+ assert 'success' in self.conf({"listeners": {}, "applications": {}})
+
+ def test_reconfigure(self):
+ (_, sock) = self.http(
+ b"""GET / HTTP/1.1
+""",
+ start=True,
+ raw=True,
+ no_recv=True,
+ )
+
+ self.clear_conf()
+
+ resp = self.http(
+ b"""Host: localhost
+Connection: close
+
+""",
+ sock=sock,
+ raw=True,
+ )
+ assert resp['status'] == 200, 'finish request'
+
+ def test_reconfigure_2(self):
+ (_, sock) = self.http(b'', raw=True, start=True, no_recv=True)
+
+ # Waiting for connection completion.
+ # Delay should be more than TCP_DEFER_ACCEPT.
+ time.sleep(1.5)
+
+ self.clear_conf()
+
+ assert self.get(sock=sock)['status'] == 408, 'request timeout'
diff --git a/test/test_reconfigure_tls.py b/test/test_reconfigure_tls.py
new file mode 100644
index 00000000..0f92a419
--- /dev/null
+++ b/test/test_reconfigure_tls.py
@@ -0,0 +1,105 @@
+import socket
+import ssl
+import time
+
+import pytest
+from unit.applications.tls import TestApplicationTLS
+
+
+class TestReconfigureTLS(TestApplicationTLS):
+ prerequisites = {'modules': {'openssl': 'any'}}
+
+ @pytest.fixture(autouse=True)
+ def setup_method_fixture(self):
+ if 'HAS_TLSv1_2' not in dir(ssl) or not ssl.HAS_TLSv1_2:
+ pytest.skip('OpenSSL too old')
+
+ self.certificate()
+
+ assert 'success' in self.conf(
+ {
+ "listeners": {
+ "*:7080": {
+ "pass": "routes",
+ "tls": {"certificate": "default"},
+ }
+ },
+ "routes": [{"action": {"return": 200}}],
+ "applications": {},
+ }
+ ), 'load application configuration'
+
+ def create_socket(self):
+ ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
+ ctx.check_hostname = False
+ ctx.verify_mode = ssl.CERT_NONE
+
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ ssl_sock = ctx.wrap_socket(
+ s, server_hostname='localhost', do_handshake_on_connect=False
+ )
+ ssl_sock.connect(('127.0.0.1', 7080))
+
+ return ssl_sock
+
+ def clear_conf(self):
+ assert 'success' in self.conf({"listeners": {}, "applications": {}})
+
+ @pytest.mark.skip('not yet')
+ def test_reconfigure_tls_switch(self):
+ assert 'success' in self.conf_delete('listeners/*:7080/tls')
+
+ (_, sock) = self.get(
+ headers={'Host': 'localhost', 'Connection': 'keep-alive'},
+ start=True,
+ read_timeout=1,
+ )
+
+ assert 'success' in self.conf(
+ {"pass": "routes", "tls": {"certificate": "default"}},
+ 'listeners/*:7080',
+ )
+
+ assert self.get(sock=sock)['status'] == 200, 'reconfigure'
+ assert self.get_ssl()['status'] == 200, 'reconfigure tls'
+
+ def test_reconfigure_tls(self):
+ ssl_sock = self.create_socket()
+
+ ssl_sock.sendall("""GET / HTTP/1.1\r\n""".encode())
+
+ self.clear_conf()
+
+ ssl_sock.sendall(
+ """Host: localhost\r\nConnection: close\r\n\r\n""".encode()
+ )
+
+ assert (
+ self.recvall(ssl_sock).decode().startswith('HTTP/1.1 200 OK')
+ ), 'finish request'
+
+ def test_reconfigure_tls_2(self):
+ ssl_sock = self.create_socket()
+
+ # Waiting for connection completion.
+ # Delay should be more than TCP_DEFER_ACCEPT.
+ time.sleep(1.5)
+
+ self.clear_conf()
+
+ try:
+ ssl_sock.do_handshake()
+ except ssl.SSLError:
+ ssl_sock.close()
+ success = True
+
+ if not success:
+ pytest.fail('Connection is not closed.')
+
+ def test_reconfigure_tls_3(self):
+ ssl_sock = self.create_socket()
+ ssl_sock.do_handshake()
+
+ self.clear_conf()
+
+ assert self.get(sock=ssl_sock)['status'] == 408, 'request timeout'
diff --git a/test/test_respawn.py b/test/test_respawn.py
index 5a5d6126..19d97d37 100644
--- a/test/test_respawn.py
+++ b/test/test_respawn.py
@@ -82,8 +82,7 @@ class TestRespawn(TestApplicationPython):
skip_alert(r'process %s exited on signal 9' % pid)
assert (
- self.wait_for_process(self.PATTERN_CONTROLLER, unit_pid)
- is not None
+ self.wait_for_process(self.PATTERN_CONTROLLER, unit_pid) is not None
)
assert self.get()['status'] == 200
diff --git a/test/test_return.py b/test/test_return.py
index 2f7b7ae4..82bf1e64 100644
--- a/test/test_return.py
+++ b/test/test_return.py
@@ -83,7 +83,7 @@ Connection: close
assert resp['body'] == ''
def test_return_location(self):
- reserved = ":/?#[]@!$&'()*+,;="
+ reserved = ":/?#[]@!&'()*+,;="
unreserved = (
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
"0123456789-._~"
@@ -107,15 +107,15 @@ Connection: close
check_location(reserved)
# After first "?" all other "?" encoded.
- check_location("/?" + reserved, "/?:/%3F#[]@!$&'()*+,;=")
+ check_location("/?" + reserved, "/?:/%3F#[]@!&'()*+,;=")
check_location("???", "?%3F%3F")
# After first "#" all other "?" or "#" encoded.
- check_location("/#" + reserved, "/#:/%3F%23[]@!$&'()*+,;=")
+ check_location("/#" + reserved, "/#:/%3F%23[]@!&'()*+,;=")
check_location("##?#?", "#%23%3F%23%3F")
# After first "?" next "#" not encoded.
- check_location("/?#" + reserved, "/?#:/%3F%23[]@!$&'()*+,;=")
+ check_location("/?#" + reserved, "/?#:/%3F%23[]@!&'()*+,;=")
check_location("??##", "?%3F#%23")
check_location("/?##?", "/?#%23%3F")
@@ -161,6 +161,38 @@ Connection: close
), 'location method not allowed'
assert self.get()['headers']['Location'] == 'blah'
+ assert 'success' in self.conf(
+ '"https://${host}${uri}"', 'routes/0/action/location'
+ ), 'location with variables'
+ assert self.get()['headers']['Location'] == 'https://localhost/'
+
+ assert 'success' in self.conf(
+ '"/#$host"', 'routes/0/action/location'
+ ), 'location with encoding and a variable'
+ assert self.get()['headers']['Location'] == '/#localhost'
+
+ assert (
+ self.get(headers={"Host": "#foo?bar", "Connection": "close"})[
+ 'headers'
+ ]['Location']
+ == "/#%23foo%3Fbar"
+ ), 'location with a variable with encoding'
+
+ assert 'success' in self.conf(
+ '""', 'routes/0/action/location'
+ ), 'location empty'
+ assert self.get()['headers']['Location'] == ''
+
+ assert 'success' in self.conf(
+ '"${host}"', 'routes/0/action/location'
+ ), 'location empty with variable'
+ assert (
+ self.get(headers={"Host": "", "Connection": "close"})['headers'][
+ 'Location'
+ ]
+ == ""
+ ), 'location with empty variable'
+
def test_return_invalid(self):
def check_error(conf):
assert 'error' in self.conf(conf, 'routes/0/action')
@@ -171,6 +203,8 @@ Connection: close
check_error({"return": 1000})
check_error({"return": -1})
check_error({"return": 200, "share": "/blah"})
+ check_error({"return": 200, "location": "$hos"})
+ check_error({"return": 200, "location": "$hostblah"})
assert 'error' in self.conf(
'001', 'routes/0/action/return'
diff --git a/test/test_routing.py b/test/test_routing.py
index 167d2640..fda429a4 100644
--- a/test/test_routing.py
+++ b/test/test_routing.py
@@ -1,10 +1,10 @@
# -*- coding: utf-8 -*-
import pytest
-from unit.applications.proto import TestApplicationProto
+from unit.applications.lang.python import TestApplicationPython
from unit.option import option
-class TestRouting(TestApplicationProto):
+class TestRouting(TestApplicationPython):
prerequisites = {'modules': {'python': 'any'}}
def setup_method(self):
@@ -12,7 +12,10 @@ class TestRouting(TestApplicationProto):
{
"listeners": {"*:7080": {"pass": "routes"}},
"routes": [
- {"match": {"method": "GET"}, "action": {"return": 200},}
+ {
+ "match": {"method": "GET"},
+ "action": {"return": 200},
+ }
],
"applications": {},
}
@@ -289,7 +292,7 @@ class TestRouting(TestApplicationProto):
"listeners": {"*:7080": {"pass": "applications/" + path}},
"applications": {
name: {
- "type": "python",
+ "type": self.get_application_type(),
"processes": {"spare": 0},
"path": option.test_dir + '/python/empty',
"working_directory": option.test_dir
@@ -313,7 +316,7 @@ class TestRouting(TestApplicationProto):
"listeners": {"*:7080": {"pass": "applications/" + path}},
"applications": {
name: {
- "type": "python",
+ "type": self.get_application_type(),
"processes": {"spare": 0},
"path": option.test_dir + '/python/empty',
"working_directory": option.test_dir
@@ -333,7 +336,7 @@ class TestRouting(TestApplicationProto):
"listeners": {"*:7081": {"pass": "applications/empty"}},
"applications": {
"empty": {
- "type": "python",
+ "type": self.get_application_type(),
"processes": {"spare": 0},
"path": option.test_dir + '/python/empty',
"working_directory": option.test_dir + '/python/empty',
@@ -387,7 +390,7 @@ class TestRouting(TestApplicationProto):
{
"applications": {
"app": {
- "type": "python",
+ "type": self.get_application_type(),
"processes": {"spare": 0},
"path": "/app",
"module": "wsgi",
@@ -430,7 +433,7 @@ class TestRouting(TestApplicationProto):
{
"applications": {
"app": {
- "type": "python",
+ "type": self.get_application_type(),
"processes": {"spare": 0},
"path": "/app",
"module": "wsgi",
@@ -476,7 +479,7 @@ class TestRouting(TestApplicationProto):
"routes": [{"action": {"proxy": "http://127.0.0.1:7081"}}],
"applications": {
"app": {
- "type": "python",
+ "type": self.get_application_type(),
"processes": {"spare": 0},
"path": "/app",
"module": "wsgi",
@@ -490,11 +493,15 @@ class TestRouting(TestApplicationProto):
'routes/0/action',
), 'proxy share'
assert 'error' in self.conf(
- {"proxy": "http://127.0.0.1:7081", "pass": "applications/app",},
+ {
+ "proxy": "http://127.0.0.1:7081",
+ "pass": "applications/app",
+ },
'routes/0/action',
), 'proxy pass'
assert 'error' in self.conf(
- {"share": temp_dir, "pass": "applications/app"}, 'routes/0/action',
+ {"share": temp_dir, "pass": "applications/app"},
+ 'routes/0/action',
), 'share pass'
def test_routes_rules_two(self):
@@ -693,7 +700,8 @@ class TestRouting(TestApplicationProto):
assert self.post()['status'] == 404, 'routes edit POST'
assert 'success' in self.conf_post(
- {"match": {"method": "POST"}, "action": {"return": 200}}, 'routes',
+ {"match": {"method": "POST"}, "action": {"return": 200}},
+ 'routes',
), 'routes edit configure 2'
assert 'GET' == self.conf_get(
'routes/0/match/method'
@@ -733,7 +741,8 @@ class TestRouting(TestApplicationProto):
assert self.post()['status'] == 404, 'routes edit POST 5'
assert 'success' in self.conf_post(
- {"match": {"method": "POST"}, "action": {"return": 200}}, 'routes',
+ {"match": {"method": "POST"}, "action": {"return": 200}},
+ 'routes',
), 'routes edit configure 6'
assert self.get()['status'] == 404, 'routes edit GET 6'
@@ -1042,9 +1051,7 @@ class TestRouting(TestApplicationProto):
def check_headers(hds):
hds = dict({"Host": "localhost", "Connection": "close"}, **hds)
- assert (
- self.get(headers=hds)['status'] == 200
- ), 'headers array match'
+ assert self.get(headers=hds)['status'] == 200, 'headers array match'
def check_headers_404(hds):
hds = dict({"Host": "localhost", "Connection": "close"}, **hds)
@@ -1262,9 +1269,7 @@ class TestRouting(TestApplicationProto):
self.get(url='/?foo=bar&blah=test')['status'] == 200
), 'multiple 2'
assert self.get(url='/?foo=bar&blah')['status'] == 404, 'multiple 3'
- assert (
- self.get(url='/?foo=bar&blah=tes')['status'] == 404
- ), 'multiple 4'
+ assert self.get(url='/?foo=bar&blah=tes')['status'] == 404, 'multiple 4'
assert (
self.get(url='/?foo=b%61r&bl%61h=t%65st')['status'] == 200
), 'multiple 5'
@@ -1494,9 +1499,7 @@ class TestRouting(TestApplicationProto):
sock, port = sock_port()
sock2, port2 = sock_port()
- self.route_match(
- {"source": "127.0.0.1:" + str(port) + "-" + str(port)}
- )
+ self.route_match({"source": "127.0.0.1:" + str(port) + "-" + str(port)})
assert self.get(sock=sock)['status'] == 200, 'range single'
assert self.get(sock=sock2)['status'] == 404, 'range single 2'
@@ -1544,7 +1547,10 @@ class TestRouting(TestApplicationProto):
def test_routes_source_addr(self):
assert 'success' in self.conf(
- {"*:7080": {"pass": "routes"}, "[::1]:7081": {"pass": "routes"},},
+ {
+ "*:7080": {"pass": "routes"},
+ "[::1]:7081": {"pass": "routes"},
+ },
'listeners',
), 'source listeners configure'
@@ -1650,7 +1656,10 @@ class TestRouting(TestApplicationProto):
def test_routes_source_cidr(self):
assert 'success' in self.conf(
- {"*:7080": {"pass": "routes"}, "[::1]:7081": {"pass": "routes"},},
+ {
+ "*:7080": {"pass": "routes"},
+ "[::1]:7081": {"pass": "routes"},
+ },
'listeners',
), 'source listeners configure'
diff --git a/test/test_ruby_application.py b/test/test_ruby_application.py
index ed0200d9..95c75d47 100644
--- a/test/test_ruby_application.py
+++ b/test/test_ruby_application.py
@@ -44,6 +44,7 @@ class TestRubyApplication(TestApplicationRuby):
'Request-Method': 'POST',
'Request-Uri': '/',
'Http-Host': 'localhost',
+ 'Script-Name': 'config.ru',
'Server-Protocol': 'HTTP/1.1',
'Custom-Header': 'blah',
'Rack-Version': '13',
@@ -172,17 +173,16 @@ class TestRubyApplication(TestApplicationRuby):
def test_ruby_application_errors_puts(self):
self.load('errors_puts')
- self.get()
+ assert self.get()['status'] == 200
assert (
- self.wait_for_record(r'\[error\].+Error in application')
- is not None
+ self.wait_for_record(r'\[error\].+Error in application') is not None
), 'errors puts'
def test_ruby_application_errors_puts_int(self):
self.load('errors_puts_int')
- self.get()
+ assert self.get()['status'] == 200
assert (
self.wait_for_record(r'\[error\].+1234567890') is not None
@@ -191,11 +191,9 @@ class TestRubyApplication(TestApplicationRuby):
def test_ruby_application_errors_write(self):
self.load('errors_write')
- self.get()
-
+ assert self.get()['status'] == 200
assert (
- self.wait_for_record(r'\[error\].+Error in application')
- is not None
+ self.wait_for_record(r'\[error\].+Error in application') is not None
), 'errors write'
def test_ruby_application_errors_write_to_s_custom(self):
@@ -206,8 +204,7 @@ class TestRubyApplication(TestApplicationRuby):
def test_ruby_application_errors_write_int(self):
self.load('errors_write_int')
- self.get()
-
+ assert self.get()['status'] == 200
assert (
self.wait_for_record(r'\[error\].+1234567890') is not None
), 'errors write int'
@@ -215,7 +212,7 @@ class TestRubyApplication(TestApplicationRuby):
def test_ruby_application_at_exit(self):
self.load('at_exit')
- self.get()
+ assert self.get()['status'] == 200
assert 'success' in self.conf({"listeners": {}, "applications": {}})
@@ -229,7 +226,8 @@ class TestRubyApplication(TestApplicationRuby):
try:
locales = (
subprocess.check_output(
- ['locale', '-a'], stderr=subprocess.STDOUT,
+ ['locale', '-a'],
+ stderr=subprocess.STDOUT,
)
.decode()
.split('\n')
diff --git a/test/test_ruby_hooks.py b/test/test_ruby_hooks.py
index 20980ad7..b4a79ebb 100644
--- a/test/test_ruby_hooks.py
+++ b/test/test_ruby_hooks.py
@@ -81,7 +81,10 @@ class TestRubyHooks(TestApplicationRuby):
threads = 1
self.load(
- 'hooks', processes=processes, threads=threads, hooks='multiple.rb',
+ 'hooks',
+ processes=processes,
+ threads=threads,
+ hooks='multiple.rb',
)
hooked = self._wait_cookie('worker_boot.*', processes)
diff --git a/test/test_ruby_isolation.py b/test/test_ruby_isolation.py
index 940427f1..ea208523 100644
--- a/test/test_ruby_isolation.py
+++ b/test/test_ruby_isolation.py
@@ -34,11 +34,13 @@ class TestRubyIsolation(TestApplicationRuby):
self.load('status_int', isolation=isolation)
assert 'success' in self.conf(
- '"/ruby/status_int/config.ru"', 'applications/status_int/script',
+ '"/ruby/status_int/config.ru"',
+ 'applications/status_int/script',
)
assert 'success' in self.conf(
- '"/ruby/status_int"', 'applications/status_int/working_directory',
+ '"/ruby/status_int"',
+ 'applications/status_int/working_directory',
)
assert self.get()['status'] == 200, 'status int'
diff --git a/test/test_settings.py b/test/test_settings.py
index a16e35e8..ea3cfb99 100644
--- a/test/test_settings.py
+++ b/test/test_settings.py
@@ -207,9 +207,7 @@ Connection: close
{"unix:" + addr: {'application': 'body_generate'}}, 'listeners'
)
- assert 'success' in self.conf(
- {'http': {'send_timeout': 1}}, 'settings'
- )
+ assert 'success' in self.conf({'http': {'send_timeout': 1}}, 'settings')
data = req(addr, data_len)
assert re.search(r'200 OK', data), 'send timeout status'
@@ -237,14 +235,10 @@ Connection: close
assert self.get()['status'] == 200, 'init'
- assert 'success' in self.conf(
- {'http': {'idle_timeout': 2}}, 'settings'
- )
+ assert 'success' in self.conf({'http': {'idle_timeout': 2}}, 'settings')
assert req()['status'] == 408, 'status idle timeout'
- assert 'success' in self.conf(
- {'http': {'idle_timeout': 7}}, 'settings'
- )
+ assert 'success' in self.conf({'http': {'idle_timeout': 7}}, 'settings')
assert req()['status'] == 200, 'status idle timeout 2'
def test_settings_idle_timeout_2(self):
@@ -259,14 +253,10 @@ Connection: close
assert self.get()['status'] == 200, 'init'
- assert 'success' in self.conf(
- {'http': {'idle_timeout': 1}}, 'settings'
- )
+ assert 'success' in self.conf({'http': {'idle_timeout': 1}}, 'settings')
assert req()['status'] == 408, 'status idle timeout'
- assert 'success' in self.conf(
- {'http': {'idle_timeout': 7}}, 'settings'
- )
+ assert 'success' in self.conf({'http': {'idle_timeout': 7}}, 'settings')
assert req()['status'] == 200, 'status idle timeout 2'
def test_settings_max_body_size(self):
diff --git a/test/test_static.py b/test/test_static.py
index 80f4c610..b9c78fdd 100644
--- a/test/test_static.py
+++ b/test/test_static.py
@@ -3,7 +3,8 @@ import shutil
import socket
import pytest
-from conftest import unit_run, unit_stop
+from conftest import unit_run
+from conftest import unit_stop
from unit.applications.proto import TestApplicationProto
from unit.option import option
from unit.utils import waitforfiles
@@ -86,6 +87,22 @@ class TestStatic(TestApplicationProto):
assert self.get(url='/')['body'] == '0123456789', 'before 1.26.0 2'
def test_static_index(self):
+ def set_index(index):
+ assert 'success' in self.conf(
+ {"share": option.temp_dir + "/assets$uri", "index": index},
+ 'routes/0/action',
+ ), 'configure index'
+
+ set_index('README')
+ assert self.get()['body'] == 'readme', 'index'
+
+ self.conf_delete('routes/0/action/index')
+ assert self.get()['body'] == '0123456789', 'delete index'
+
+ set_index('')
+ assert self.get()['status'] == 404, 'index empty'
+
+ def test_static_index_default(self):
assert self.get(url='/index.html')['body'] == '0123456789', 'index'
assert self.get(url='/')['body'] == '0123456789', 'index 2'
assert self.get(url='//')['body'] == '0123456789', 'index 3'
@@ -101,6 +118,18 @@ class TestStatic(TestApplicationProto):
resp['headers']['Content-Type'] == 'text/html'
), 'index not found 2 Content-Type'
+ def test_static_index_invalid(self, skip_alert):
+ skip_alert(r'failed to apply new conf')
+
+ def check_index(index):
+ assert 'error' in self.conf(
+ {"share": option.temp_dir + "/assets$uri", "index": index},
+ 'routes/0/action',
+ )
+
+ check_index({})
+ check_index(['index.html', '$blah'])
+
def test_static_large_file(self, temp_dir):
file_size = 32 * 1024 * 1024
with open(temp_dir + '/assets/large', 'wb') as f:
@@ -132,7 +161,8 @@ class TestStatic(TestApplicationProto):
def test_static_space_in_name(self, temp_dir):
os.rename(
- temp_dir + '/assets/dir/file', temp_dir + '/assets/dir/fi le',
+ temp_dir + '/assets/dir/file',
+ temp_dir + '/assets/dir/fi le',
)
assert waitforfiles(temp_dir + '/assets/dir/fi le')
assert self.get(url='/dir/fi le')['body'] == 'blah', 'file name'
@@ -153,9 +183,7 @@ class TestStatic(TestApplicationProto):
assert (
self.get(url='/ di r %2Ffi le')['body'] == 'blah'
), 'slash encoded'
- assert (
- self.get(url='/ di r /fi%20le')['body'] == 'blah'
- ), 'file encoded'
+ assert self.get(url='/ di r /fi%20le')['body'] == 'blah', 'file encoded'
assert (
self.get(url='/%20di%20r%20%2Ffi%20le')['body'] == 'blah'
), 'encoded'
@@ -194,7 +222,8 @@ class TestStatic(TestApplicationProto):
), 'file name 2'
os.rename(
- temp_dir + '/assets/ di r ', temp_dir + '/assets/ди ректория',
+ temp_dir + '/assets/ di r ',
+ temp_dir + '/assets/ди ректория',
)
assert waitforfiles(temp_dir + '/assets/ди ректория/фа йл')
assert (
@@ -265,13 +294,14 @@ class TestStatic(TestApplicationProto):
self.get(url='/')['headers']['Content-Type'] == 'text/plain'
), 'mime_types index default'
assert (
- self.get(url='/dir/file')['headers']['Content-Type']
- == 'text/plain'
+ self.get(url='/dir/file')['headers']['Content-Type'] == 'text/plain'
), 'mime_types file in dir'
def test_static_mime_types_partial_match(self):
assert 'success' in self.conf(
- {"text/x-blah": ["ile", "fil", "f", "e", ".file"],},
+ {
+ "text/x-blah": ["ile", "fil", "f", "e", ".file"],
+ },
'settings/http/static/mime_types',
), 'configure mime_types'
assert 'Content-Type' not in self.get(url='/dir/file'), 'partial match'
@@ -312,16 +342,14 @@ class TestStatic(TestApplicationProto):
'"file"', 'settings/http/static/mime_types/text%2Fplain'
), 'mime_types add array element'
assert (
- self.get(url='/dir/file')['headers']['Content-Type']
- == 'text/plain'
+ self.get(url='/dir/file')['headers']['Content-Type'] == 'text/plain'
), 'mime_types reverted'
assert 'success' in self.conf(
'"file"', 'settings/http/static/mime_types/text%2Fplain'
), 'configure mime_types update'
assert (
- self.get(url='/dir/file')['headers']['Content-Type']
- == 'text/plain'
+ self.get(url='/dir/file')['headers']['Content-Type'] == 'text/plain'
), 'mime_types updated'
assert (
'Content-Type' not in self.get(url='/log.log')['headers']
@@ -345,7 +373,10 @@ class TestStatic(TestApplicationProto):
'settings/http/static/mime_types',
), 'mime_types same extensions array'
assert 'error' in self.conf(
- {"text/x-code": [".h", ".c", "readme"], "text/plain": "README",},
+ {
+ "text/x-code": [".h", ".c", "readme"],
+ "text/plain": "README",
+ },
'settings/http/static/mime_types',
), 'mime_types same extensions case insensitive'
diff --git a/test/test_static_chroot.py b/test/test_static_chroot.py
index 62288807..b896a9b9 100644
--- a/test/test_static_chroot.py
+++ b/test/test_static_chroot.py
@@ -26,13 +26,14 @@ class TestStaticChroot(TestApplicationProto):
def update_action(self, share, chroot):
return self.conf(
- {"share": share, "chroot": chroot}, 'routes/0/action',
+ {"share": share, "chroot": chroot},
+ 'routes/0/action',
)
def get_custom(self, uri, host):
- return self.get(
- url=uri, headers={'Host': host, 'Connection': 'close'}
- )['status']
+ return self.get(url=uri, headers={'Host': host, 'Connection': 'close'})[
+ 'status'
+ ]
def test_static_chroot(self, temp_dir):
assert self.get(url='/dir/file')['status'] == 200, 'default chroot'
@@ -101,7 +102,8 @@ class TestStaticChroot(TestApplicationProto):
), 'chroot empty absolute'
assert 'success' in self.conf(
- {"share": ".$uri", "chroot": ""}, 'routes/0/action',
+ {"share": ".$uri", "chroot": ""},
+ 'routes/0/action',
), 'configure chroot empty relative'
assert (
@@ -120,13 +122,15 @@ class TestStaticChroot(TestApplicationProto):
assert self.get(url='/dir/file')['status'] == 403, 'relative chroot'
assert 'success' in self.conf(
- {"share": ".$uri"}, 'routes/0/action',
+ {"share": ".$uri"},
+ 'routes/0/action',
), 'configure relative share'
assert self.get(url=self.test_path)['status'] == 200, 'relative share'
assert 'success' in self.conf(
- {"share": ".$uri", "chroot": "."}, 'routes/0/action',
+ {"share": ".$uri", "chroot": "."},
+ 'routes/0/action',
), 'configure relative'
assert self.get(url=self.test_path)['status'] == 200, 'relative'
@@ -208,13 +212,16 @@ class TestStaticChroot(TestApplicationProto):
def test_static_chroot_invalid(self, temp_dir):
assert 'error' in self.conf(
- {"share": temp_dir, "chroot": True}, 'routes/0/action',
+ {"share": temp_dir, "chroot": True},
+ 'routes/0/action',
), 'configure chroot error'
assert 'error' in self.conf(
- {"share": temp_dir, "symlinks": "True"}, 'routes/0/action',
+ {"share": temp_dir, "symlinks": "True"},
+ 'routes/0/action',
), 'configure symlink error'
assert 'error' in self.conf(
- {"share": temp_dir, "mount": "True"}, 'routes/0/action',
+ {"share": temp_dir, "mount": "True"},
+ 'routes/0/action',
), 'configure mount error'
assert 'error' in self.update_action(
diff --git a/test/test_static_fallback.py b/test/test_static_fallback.py
index 71b268c8..1f1a1df7 100644
--- a/test/test_static_fallback.py
+++ b/test/test_static_fallback.py
@@ -82,7 +82,10 @@ class TestStaticFallback(TestApplicationProto):
def test_static_fallback_share(self, temp_dir):
self.action_update(
- {"share": "/blah", "fallback": {"share": temp_dir + "/assets$uri"},}
+ {
+ "share": "/blah",
+ "fallback": {"share": temp_dir + "/assets$uri"},
+ }
)
resp = self.get()
diff --git a/test/test_static_mount.py b/test/test_static_mount.py
index 82eda956..91cf836c 100644
--- a/test/test_static_mount.py
+++ b/test/test_static_mount.py
@@ -41,9 +41,7 @@ class TestStaticMount(TestApplicationProto):
self._load_conf(
{
"listeners": {"*:7080": {"pass": "routes"}},
- "routes": [
- {"action": {"share": temp_dir + "/assets/dir$uri"}}
- ],
+ "routes": [{"action": {"share": temp_dir + "/assets/dir$uri"}}],
}
)
diff --git a/test/test_static_types.py b/test/test_static_types.py
index 18564a21..0e86517b 100644
--- a/test/test_static_types.py
+++ b/test/test_static_types.py
@@ -85,7 +85,10 @@ class TestStaticTypes(TestApplicationProto):
def test_static_types_regex(self, temp_dir):
self.action_update(
- {"share": temp_dir + "/assets$uri", "types": ["~text/(html|plain)"]}
+ {
+ "share": temp_dir + "/assets$uri",
+ "types": ["~text/(html|plain)"],
+ }
)
assert self.get(url='/file.php')['status'] == 403, 'regex fail'
self.check_body('/file.html', '.html')
diff --git a/test/test_tls.py b/test/test_tls.py
index 01336765..56ee8298 100644
--- a/test/test_tls.py
+++ b/test/test_tls.py
@@ -175,11 +175,13 @@ basicConstraints = critical,CA:TRUE"""
self.add_tls()
- cert_old = self.get_server_certificate()
+ cert_old = ssl.get_server_certificate(('127.0.0.1', 7080))
self.certificate()
- assert cert_old != self.get_server_certificate(), 'update certificate'
+ assert cert_old != ssl.get_server_certificate(
+ ('127.0.0.1', 7080)
+ ), 'update certificate'
@pytest.mark.skip('not yet')
def test_tls_certificate_key_incorrect(self):
@@ -200,11 +202,13 @@ basicConstraints = critical,CA:TRUE"""
self.add_tls()
- cert_old = self.get_server_certificate()
+ cert_old = ssl.get_server_certificate(('127.0.0.1', 7080))
self.add_tls(cert='new')
- assert cert_old != self.get_server_certificate(), 'change certificate'
+ assert cert_old != ssl.get_server_certificate(
+ ('127.0.0.1', 7080)
+ ), 'change certificate'
def test_tls_certificate_key_rsa(self):
self.load('empty')
@@ -354,9 +358,7 @@ basicConstraints = critical,CA:TRUE"""
self.add_tls(cert='int')
- assert (
- self.get_ssl()['status'] == 200
- ), 'certificate chain intermediate'
+ assert self.get_ssl()['status'] == 200, 'certificate chain intermediate'
# intermediate server
@@ -385,6 +387,51 @@ basicConstraints = critical,CA:TRUE"""
self.get_ssl()['status'] == 200
), 'certificate chain intermediate server'
+ def test_tls_certificate_chain_long(self, temp_dir):
+ self.load('empty')
+
+ self.generate_ca_conf()
+
+ # Minimum chain length is 3.
+ chain_length = 10
+
+ for i in range(chain_length):
+ if i == 0:
+ self.certificate('root', False)
+ elif i == chain_length - 1:
+ self.req('end')
+ else:
+ self.req('int{}'.format(i))
+
+ for i in range(chain_length - 1):
+ if i == 0:
+ self.ca(cert='root', out='int1')
+ elif i == chain_length - 2:
+ self.ca(cert='int{}'.format(chain_length - 2), out='end')
+ else:
+ self.ca(cert='int{}'.format(i), out='int{}'.format(i + 1))
+
+ for i in range(chain_length - 1, 0, -1):
+ path = temp_dir + (
+ '/end.crt' if i == chain_length - 1 else '/int{}.crt'.format(i)
+ )
+
+ with open(temp_dir + '/all.crt', 'a') as chain, open(path) as cert:
+ chain.write(cert.read())
+
+ self.set_certificate_req_context()
+
+ assert 'success' in self.certificate_load(
+ 'all', 'end'
+ ), 'certificate chain upload'
+
+ chain = self.conf_get('/certificates/all/chain')
+ assert len(chain) == chain_length - 1, 'certificate chain length'
+
+ self.add_tls(cert='all')
+
+ assert self.get_ssl()['status'] == 200, 'certificate chain long'
+
def test_tls_certificate_empty_cn(self, temp_dir):
self.certificate('root', False)
@@ -446,27 +493,6 @@ basicConstraints = critical,CA:TRUE"""
}, 'subject alt_names'
assert cert['chain'][0]['issuer']['common_name'] == 'root', 'issuer'
- @pytest.mark.skip('not yet')
- def test_tls_reconfigure(self):
- self.load('empty')
-
- assert self.get()['status'] == 200, 'init'
-
- self.certificate()
-
- (resp, sock) = self.get(
- headers={'Host': 'localhost', 'Connection': 'keep-alive'},
- start=True,
- read_timeout=1,
- )
-
- assert resp['status'] == 200, 'initial status'
-
- self.add_tls()
-
- assert self.get(sock=sock)['status'] == 200, 'reconfigure status'
- assert self.get_ssl()['status'] == 200, 'reconfigure tls status'
-
def test_tls_keepalive(self):
self.load('mirror')
diff --git a/test/test_tls_sni.py b/test/test_tls_sni.py
index d5f205cf..dbd5d900 100644
--- a/test/test_tls_sni.py
+++ b/test/test_tls_sni.py
@@ -178,7 +178,8 @@ basicConstraints = critical,CA:TRUE"""
self.add_tls(["localhost.com", "example.com"])
resp, sock = self.get_ssl(
- headers={'Content-Length': '0', 'Connection': 'close'}, start=True,
+ headers={'Content-Length': '0', 'Connection': 'close'},
+ start=True,
)
assert resp['status'] == 200
assert (
@@ -272,9 +273,7 @@ basicConstraints = critical,CA:TRUE"""
)
assert resp['status'] == 200
- assert (
- sock.getpeercert()['subjectAltName'][0][1] == 'alt.localhost.com'
- )
+ assert sock.getpeercert()['subjectAltName'][0][1] == 'alt.localhost.com'
def test_tls_sni_invalid(self):
self.config_bundles({"localhost": {"subj": "subj1", "alt_names": ''}})
diff --git a/test/test_tls_tickets.py b/test/test_tls_tickets.py
index 6899eaa1..5399fae7 100644
--- a/test/test_tls_tickets.py
+++ b/test/test_tls_tickets.py
@@ -17,9 +17,7 @@ class TestTLSTicket(TestApplicationTLS):
prerequisites = {'modules': {'openssl': 'any'}}
ticket = 'U1oDTh11mMxODuw12gS0EXX1E/PkZG13cJNQ6m5+6BGlfPTjNlIEw7PSVU3X1gTE'
- ticket2 = (
- '5AV0DSYIYbZWZQB7fCnTHZmMxtotb/aXjam+n2XS79lTvX3Tq9xGqpC8XKNEF2lt'
- )
+ ticket2 = '5AV0DSYIYbZWZQB7fCnTHZmMxtotb/aXjam+n2XS79lTvX3Tq9xGqpC8XKNEF2lt'
ticket80 = '6Pfil8lv/k8zf8MndPpfXaO5EAV6dhME6zs6CfUyq2yziynQwSywtKQMqHGnJ2HR\
49TZXi/Y4/8RSIO7QPsU51/HLR1gWIMhVM2m9yh93Bw='
@@ -182,7 +180,8 @@ class TestTLSTicket(TestApplicationTLS):
def test_tls_ticket_invalid(self):
def check_tickets(tickets):
assert 'error' in self.conf(
- {"tickets": tickets}, 'listeners/*:7080/tls/session',
+ {"tickets": tickets},
+ 'listeners/*:7080/tls/session',
)
check_tickets({})
diff --git a/test/test_upstreams_rr.py b/test/test_upstreams_rr.py
index 163eb646..dd64e1d9 100644
--- a/test/test_upstreams_rr.py
+++ b/test/test_upstreams_rr.py
@@ -274,7 +274,7 @@ Connection: close
],
"applications": {
"delayed": {
- "type": "python",
+ "type": self.get_application_type(),
"processes": {"spare": 0},
"path": option.test_dir + "/python/delayed",
"working_directory": option.test_dir
@@ -342,7 +342,8 @@ Connection: close
assert self.get()['body'] == ''
assert 'success' in self.conf(
- {"127.0.0.1:7083": {"weight": 2}}, 'upstreams/one/servers',
+ {"127.0.0.1:7083": {"weight": 2}},
+ 'upstreams/one/servers',
), 'active req new server'
assert 'success' in self.conf_delete(
'upstreams/one/servers/127.0.0.1:7083'
diff --git a/test/test_usr1.py b/test/test_usr1.py
index 9a12b747..3d190935 100644
--- a/test/test_usr1.py
+++ b/test/test_usr1.py
@@ -59,9 +59,7 @@ class TestUSR1(TestApplicationPython):
body = 'body_for_a_log_new\n'
assert self.post(body=body)['status'] == 200
- assert (
- self.wait_for_record(body, log_new) is not None
- ), 'rename new'
+ assert self.wait_for_record(body, log_new) is not None, 'rename new'
assert not os.path.isfile(log_path), 'rename old'
os.kill(unit_pid, signal.SIGUSR1)
diff --git a/test/test_variables.py b/test/test_variables.py
index d8547b7b..71553685 100644
--- a/test/test_variables.py
+++ b/test/test_variables.py
@@ -17,6 +17,7 @@ class TestVariables(TestApplicationProto):
"5GET": [{"action": {"return": 206}}],
"GETGET": [{"action": {"return": 207}}],
"localhost": [{"action": {"return": 208}}],
+ "9?q#a": [{"action": {"return": 209}}],
},
},
), 'configure routes'
@@ -28,6 +29,14 @@ class TestVariables(TestApplicationProto):
assert self.get()['status'] == 201, 'method GET'
assert self.post()['status'] == 202, 'method POST'
+ def test_variables_request_uri(self):
+ self.conf_routes("\"routes$request_uri\"")
+
+ assert self.get(url='/3')['status'] == 203, 'request_uri'
+ assert self.get(url='/4*')['status'] == 204, 'request_uri 2'
+ assert self.get(url='/4%2A')['status'] == 204, 'request_uri 3'
+ assert self.get(url='/9?q#a')['status'] == 209, 'request_uri query'
+
def test_variables_uri(self):
self.conf_routes("\"routes$uri\"")
@@ -103,20 +112,16 @@ class TestVariables(TestApplicationProto):
def test_variables_empty(self):
def update_pass(prefix):
assert 'success' in self.conf(
- {
- "listeners": {
- "*:7080": {"pass": prefix + "/$method"},
- },
- },
+ {"listeners": {"*:7080": {"pass": prefix + "/$method"}}},
), 'variables empty'
- update_pass("routes");
+ update_pass("routes")
assert self.get(url='/1')['status'] == 404
- update_pass("upstreams");
+ update_pass("upstreams")
assert self.get(url='/2')['status'] == 404
- update_pass("applications");
+ update_pass("applications")
assert self.get(url='/3')['status'] == 404
def test_variables_invalid(self):
diff --git a/test/unit/applications/lang/go.py b/test/unit/applications/lang/go.py
index 367059e6..04af26e1 100644
--- a/test/unit/applications/lang/go.py
+++ b/test/unit/applications/lang/go.py
@@ -1,4 +1,5 @@
import os
+import shutil
import subprocess
from unit.applications.proto import TestApplicationProto
@@ -6,14 +7,25 @@ from unit.option import option
class TestApplicationGo(TestApplicationProto):
- def prepare_env(self, script, name, static=False):
- if not os.path.exists(option.temp_dir + '/go'):
- os.mkdir(option.temp_dir + '/go')
+ @staticmethod
+ def prepare_env(script, name='app', static=False):
+ temp_dir = option.temp_dir + '/go/'
+
+ if not os.path.exists(temp_dir):
+ os.mkdir(temp_dir)
+
+ cache_dir = option.cache_dir + '/go-build'
+
+ if not os.path.exists(cache_dir):
+ os.mkdir(cache_dir)
env = os.environ.copy()
env['GOPATH'] = option.current_dir + '/build/go'
- env['GOCACHE'] = option.cache_dir + '/go'
- env['GO111MODULE'] = 'auto'
+ env['GOCACHE'] = cache_dir
+
+ shutil.copy2(
+ option.test_dir + '/go/' + script + '/' + name + '.go', temp_dir
+ )
if static:
args = [
@@ -24,23 +36,33 @@ class TestApplicationGo(TestApplicationProto):
'-ldflags',
'-extldflags "-static"',
'-o',
- option.temp_dir + '/go/' + name,
- option.test_dir + '/go/' + script + '/' + name + '.go',
+ temp_dir + name,
+ temp_dir + name + '.go',
]
else:
args = [
'go',
'build',
'-o',
- option.temp_dir + '/go/' + name,
- option.test_dir + '/go/' + script + '/' + name + '.go',
+ temp_dir + name,
+ temp_dir + name + '.go',
]
+ replace_path = option.current_dir + '/build/go/src/unit.nginx.org/go'
+
+ with open(temp_dir + 'go.mod', 'w') as f:
+ f.write(
+ f"""module test/app
+require unit.nginx.org/go v0.0.0
+replace unit.nginx.org/go => {replace_path}
+"""
+ )
+
if option.detailed:
print("\n$ GOPATH=" + env['GOPATH'] + " " + " ".join(args))
try:
- process = subprocess.run(args, env=env)
+ process = subprocess.run(args, env=env, cwd=temp_dir)
except KeyboardInterrupt:
raise
@@ -61,7 +83,7 @@ class TestApplicationGo(TestApplicationProto):
executable = "/go/" + name
static_build = True
- self.prepare_env(script, name, static=static_build)
+ TestApplicationGo.prepare_env(script, name, static=static_build)
conf = {
"listeners": {"*:7080": {"pass": "applications/" + script}},
diff --git a/test/unit/applications/tls.py b/test/unit/applications/tls.py
index c7254235..93400328 100644
--- a/test/unit/applications/tls.py
+++ b/test/unit/applications/tls.py
@@ -52,21 +52,6 @@ class TestApplicationTLS(TestApplicationProto):
def post_ssl(self, **kwargs):
return self.post(wrapper=self.context.wrap_socket, **kwargs)
- def get_server_certificate(self, addr=('127.0.0.1', 7080)):
-
- ssl_list = dir(ssl)
-
- if 'PROTOCOL_TLS' in ssl_list:
- ssl_version = ssl.PROTOCOL_TLS
-
- elif 'PROTOCOL_TLSv1_2' in ssl_list:
- ssl_version = ssl.PROTOCOL_TLSv1_2
-
- else:
- ssl_version = ssl.PROTOCOL_TLSv1_1
-
- return ssl.get_server_certificate(addr, ssl_version=ssl_version)
-
def openssl_conf(self, rewrite=False, alt_names=[]):
conf_path = option.temp_dir + '/openssl.conf'
diff --git a/test/unit/applications/websockets.py b/test/unit/applications/websockets.py
index aa83339c..d647ce9b 100644
--- a/test/unit/applications/websockets.py
+++ b/test/unit/applications/websockets.py
@@ -43,7 +43,11 @@ class TestApplicationWebsocket(TestApplicationProto):
'Sec-WebSocket-Version': 13,
}
- _, sock = self.get(headers=headers, no_recv=True, start=True,)
+ _, sock = self.get(
+ headers=headers,
+ no_recv=True,
+ start=True,
+ )
resp = ''
while True:
@@ -218,9 +222,7 @@ class TestApplicationWebsocket(TestApplicationProto):
while pos < message_len:
end = min(pos + fragmention_size, message_len)
fin = end == message_len
- self.frame_write(
- sock, op_code, message[pos:end], fin=fin, **kwargs
- )
+ self.frame_write(sock, op_code, message[pos:end], fin=fin, **kwargs)
op_code = self.OP_CONT
pos = end
diff --git a/test/unit/check/go.py b/test/unit/check/go.py
index cc17f0fe..3d9d13e7 100644
--- a/test/unit/check/go.py
+++ b/test/unit/check/go.py
@@ -1,34 +1,8 @@
-import os
-import subprocess
+from unit.applications.lang.go import TestApplicationGo
-def check_go(current_dir, temp_dir, test_dir):
- if not os.path.exists(temp_dir + '/go'):
- os.mkdir(temp_dir + '/go')
+def check_go():
+ process = TestApplicationGo.prepare_env('empty')
- env = os.environ.copy()
- env['GOPATH'] = current_dir + '/build/go'
- env['GO111MODULE'] = 'auto'
-
- try:
- process = subprocess.run(
- [
- 'go',
- 'build',
- '-o',
- temp_dir + '/go/app',
- test_dir + '/go/empty/app.go',
- ],
- env=env,
- stderr=subprocess.STDOUT,
- stdout=subprocess.PIPE,
- )
-
- if process.returncode == 0:
- return True
-
- except KeyboardInterrupt:
- raise
-
- except subprocess.CalledProcessError:
- return None
+ if process != None and process.returncode == 0:
+ return True
diff --git a/test/unit/control.py b/test/unit/control.py
index 3008a64b..99436ca0 100644
--- a/test/unit/control.py
+++ b/test/unit/control.py
@@ -30,10 +30,6 @@ def args_handler(conf_func):
class TestControl(TestHTTP):
-
- # TODO socket reuse
- # TODO http client
-
@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 dcfcd232..b4a1a17b 100644
--- a/test/unit/http.py
+++ b/test/unit/http.py
@@ -328,9 +328,7 @@ class TestHTTP:
datatype = value['type']
if not isinstance(value['data'], io.IOBase):
- pytest.fail(
- 'multipart encoding of file requires a stream.'
- )
+ pytest.fail('multipart encoding of file requires a stream.')
data = value['data'].read()