From c07f3d3ff693025fc90a72e9c9947bfd457da11e Mon Sep 17 00:00:00 2001 From: Max Romanov Date: Mon, 20 Sep 2021 09:01:08 +0300 Subject: Fixed WebSocket connection hang issue after listener reconfigure. Because the configuration values were read from the listener's configuration, an established WebSocket connection was unable to work properly (i. e. stuck) if the listener was removed. The correct source of configuration values is the request config joint. This is related to issue #581 on GitHub. --- test/test_asgi_websockets.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'test') diff --git a/test/test_asgi_websockets.py b/test/test_asgi_websockets.py index 140bcb9a..7da2d9ce 100644 --- a/test/test_asgi_websockets.py +++ b/test/test_asgi_websockets.py @@ -1481,3 +1481,20 @@ class TestASGIWebsockets(TestApplicationPython): self.check_frame(frame, True, self.ws.OP_PING, '') # PING frame sock.close() + + def test_asgi_websockets_client_locks_app(self): + self.load('websockets/mirror') + + message = 'blah' + + _, sock, _ = self.ws.upgrade() + + assert 'success' in self.conf({}), 'remove app' + + self.ws.frame_write(sock, self.ws.OP_TEXT, message) + + frame = self.ws.frame_read(sock) + + assert message == frame['data'].decode('utf-8'), 'client' + + sock.close() -- cgit From c5220944d2acdb912c129fc82ac8a83d24e9845d Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Thu, 30 Sep 2021 22:17:28 +0800 Subject: Static: variables in the "share" option. This commit supports variable in the "share" option, the finding path to file serve is the value from "share". An example: { "share": "/www/data/static$uri" } --- test/test_static.py | 4 +++- test/test_static_chroot.py | 18 ++++++++++-------- test/test_static_fallback.py | 6 +++--- test/test_static_mount.py | 14 +++++++------- test/test_static_symlink.py | 12 ++++++------ test/test_static_types.py | 37 +++++++++++++++++++------------------ 6 files changed, 48 insertions(+), 43 deletions(-) (limited to 'test') diff --git a/test/test_static.py b/test/test_static.py index 669e265d..fa0a81a2 100644 --- a/test/test_static.py +++ b/test/test_static.py @@ -28,7 +28,9 @@ class TestStatic(TestApplicationProto): self._load_conf( { "listeners": {"*:7080": {"pass": "routes"}}, - "routes": [{"action": {"share": option.temp_dir + "/assets"}}], + "routes": [ + {"action": {"share": option.temp_dir + "/assets$uri"}} + ], "settings": { "http": { "static": { diff --git a/test/test_static_chroot.py b/test/test_static_chroot.py index f9bc93a8..aa2952a1 100644 --- a/test/test_static_chroot.py +++ b/test/test_static_chroot.py @@ -21,7 +21,7 @@ class TestStaticChroot(TestApplicationProto): self._load_conf( { "listeners": {"*:7080": {"pass": "routes"}}, - "routes": [{"action": {"share": temp_dir + "/assets"}}], + "routes": [{"action": {"share": temp_dir + "/assets$uri"}}], } ) @@ -31,7 +31,7 @@ class TestStaticChroot(TestApplicationProto): assert 'success' in self.conf( { - "share": temp_dir + "/assets", + "share": temp_dir + "/assets$uri", "chroot": temp_dir + "/assets/dir", }, 'routes/0/action', @@ -49,7 +49,7 @@ class TestStaticChroot(TestApplicationProto): assert 'success' in self.conf( { - "share": temp_dir + "/assets", + "share": temp_dir + "/assets$uri", "chroot": temp_dir + "/assets/dir", }, 'routes/0/action', @@ -59,7 +59,8 @@ class TestStaticChroot(TestApplicationProto): def test_static_chroot_empty(self, temp_dir): assert 'success' in self.conf( - {"share": temp_dir + "/assets", "chroot": ""}, 'routes/0/action', + {"share": temp_dir + "/assets$uri", "chroot": ""}, + 'routes/0/action', ), 'configure chroot empty absolute' assert ( @@ -67,7 +68,7 @@ class TestStaticChroot(TestApplicationProto): ), 'chroot empty absolute' assert 'success' in self.conf( - {"share": ".", "chroot": ""}, 'routes/0/action', + {"share": ".$uri", "chroot": ""}, 'routes/0/action', ), 'configure chroot empty relative' assert ( @@ -79,19 +80,20 @@ class TestStaticChroot(TestApplicationProto): pytest.skip('does\'t work under root') assert 'success' in self.conf( - {"share": temp_dir + "/assets", "chroot": "."}, 'routes/0/action', + {"share": temp_dir + "/assets$uri", "chroot": "."}, + 'routes/0/action', ), 'configure relative chroot' assert self.get(url='/dir/file')['status'] == 403, 'relative chroot' assert 'success' in self.conf( - {"share": "."}, '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": ".", "chroot": "."}, 'routes/0/action', + {"share": ".$uri", "chroot": "."}, 'routes/0/action', ), 'configure relative' assert self.get(url=self.test_path)['status'] == 200, 'relative' diff --git a/test/test_static_fallback.py b/test/test_static_fallback.py index dc9056b9..4cfebcec 100644 --- a/test/test_static_fallback.py +++ b/test/test_static_fallback.py @@ -23,7 +23,7 @@ class TestStaticFallback(TestApplicationProto): "*:7080": {"pass": "routes"}, "*:7081": {"pass": "routes"}, }, - "routes": [{"action": {"share": temp_dir + "/assets"}}], + "routes": [{"action": {"share": temp_dir + "/assets$uri"}}], "applications": {}, } ) @@ -50,7 +50,7 @@ class TestStaticFallback(TestApplicationProto): def test_static_fallback_valid_path(self, temp_dir): self.action_update( - {"share": temp_dir + "/assets", "fallback": {"return": 200}} + {"share": temp_dir + "/assets$uri", "fallback": {"return": 200}} ) resp = self.get() assert resp['status'] == 200, 'fallback status' @@ -83,7 +83,7 @@ class TestStaticFallback(TestApplicationProto): def test_static_fallback_share(self, temp_dir): self.action_update( - {"share": "/blah", "fallback": {"share": temp_dir + "/assets"},} + {"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 570f6439..fb4fbe4b 100644 --- a/test/test_static_mount.py +++ b/test/test_static_mount.py @@ -44,7 +44,7 @@ class TestStaticMount(TestApplicationProto): self._load_conf( { "listeners": {"*:7080": {"pass": "routes"}}, - "routes": [{"action": {"share": temp_dir + "/assets/dir"}}], + "routes": [{"action": {"share": temp_dir + "/assets/dir$uri"}}], } ) @@ -72,14 +72,14 @@ class TestStaticMount(TestApplicationProto): assert resp['body'] == 'mount' assert 'success' in self.conf( - {"share": temp_dir + "/assets/dir", "traverse_mounts": False}, + {"share": temp_dir + "/assets/dir$uri", "traverse_mounts": False}, 'routes/0/action', ), 'configure mount disable' assert self.get(url='/mount/')['status'] == 403 assert 'success' in self.conf( - {"share": temp_dir + "/assets/dir", "traverse_mounts": True}, + {"share": temp_dir + "/assets/dir$uri", "traverse_mounts": True}, 'routes/0/action', ), 'configure mount enable' @@ -97,14 +97,14 @@ class TestStaticMount(TestApplicationProto): { "match": {"method": "HEAD"}, "action": { - "share": temp_dir + "/assets/dir", + "share": temp_dir + "/assets/dir$uri", "traverse_mounts": False, }, }, { "match": {"method": "GET"}, "action": { - "share": temp_dir + "/assets/dir", + "share": temp_dir + "/assets/dir$uri", "traverse_mounts": True, }, }, @@ -120,7 +120,7 @@ class TestStaticMount(TestApplicationProto): assert 'success' in self.conf( { - "share": temp_dir + "/assets/dir", + "share": temp_dir + "/assets/dir$uri", "chroot": temp_dir + "/assets", }, 'routes/0/action', @@ -130,7 +130,7 @@ class TestStaticMount(TestApplicationProto): assert 'success' in self.conf( { - "share": temp_dir + "/assets/dir", + "share": temp_dir + "/assets/dir$uri", "chroot": temp_dir + "/assets", "traverse_mounts": False, }, diff --git a/test/test_static_symlink.py b/test/test_static_symlink.py index 35eb402a..e0fd7277 100644 --- a/test/test_static_symlink.py +++ b/test/test_static_symlink.py @@ -18,7 +18,7 @@ class TestStaticSymlink(TestApplicationProto): self._load_conf( { "listeners": {"*:7080": {"pass": "routes"}}, - "routes": [{"action": {"share": temp_dir + "/assets"}}], + "routes": [{"action": {"share": temp_dir + "/assets$uri"}}], } ) @@ -33,14 +33,14 @@ class TestStaticSymlink(TestApplicationProto): assert self.get(url='/link/file')['status'] == 200, 'symlink file' assert 'success' in self.conf( - {"share": temp_dir + "/assets", "follow_symlinks": False}, + {"share": temp_dir + "/assets$uri", "follow_symlinks": False}, 'routes/0/action', ), 'configure symlink disable' assert self.get(url='/link/file')['status'] == 403, 'symlink disabled' assert 'success' in self.conf( - {"share": temp_dir + "/assets", "follow_symlinks": True}, + {"share": temp_dir + "/assets$uri", "follow_symlinks": True}, 'routes/0/action', ), 'configure symlink enable' @@ -56,14 +56,14 @@ class TestStaticSymlink(TestApplicationProto): { "match": {"method": "HEAD"}, "action": { - "share": temp_dir + "/assets", + "share": temp_dir + "/assets$uri", "follow_symlinks": False, }, }, { "match": {"method": "GET"}, "action": { - "share": temp_dir + "/assets", + "share": temp_dir + "/assets$uri", "follow_symlinks": True, }, }, @@ -85,7 +85,7 @@ class TestStaticSymlink(TestApplicationProto): assert 'success' in self.conf( { - "share": temp_dir + "/assets", + "share": temp_dir + "/assets$uri", "chroot": temp_dir + "/assets/dir/dir", }, 'routes/0/action', diff --git a/test/test_static_types.py b/test/test_static_types.py index 20defddf..41ab7368 100644 --- a/test/test_static_types.py +++ b/test/test_static_types.py @@ -22,7 +22,7 @@ class TestStaticTypes(TestApplicationProto): "*:7080": {"pass": "routes"}, "*:7081": {"pass": "routes"}, }, - "routes": [{"action": {"share": temp_dir + "/assets"}}], + "routes": [{"action": {"share": temp_dir + "/assets$uri"}}], "applications": {}, } ) @@ -36,39 +36,39 @@ class TestStaticTypes(TestApplicationProto): assert resp['body'] == body, 'body' def test_static_types_basic(self, temp_dir): - self.action_update({"share": temp_dir + "/assets"}) + self.action_update({"share": temp_dir + "/assets$uri"}) self.check_body('/index.html', 'index') self.check_body('/file.xml', '.xml') self.action_update( - {"share": temp_dir + "/assets", "types": "application/xml"} + {"share": temp_dir + "/assets$uri", "types": "application/xml"} ) self.check_body('/file.xml', '.xml') self.action_update( - {"share": temp_dir + "/assets", "types": ["application/xml"]} + {"share": temp_dir + "/assets$uri", "types": ["application/xml"]} ) self.check_body('/file.xml', '.xml') - self.action_update({"share": temp_dir + "/assets", "types": [""]}) + self.action_update({"share": temp_dir + "/assets$uri", "types": [""]}) assert self.get(url='/file.xml')['status'] == 403, 'no mtype' def test_static_types_wildcard(self, temp_dir): self.action_update( - {"share": temp_dir + "/assets", "types": ["application/*"]} + {"share": temp_dir + "/assets$uri", "types": ["application/*"]} ) self.check_body('/file.xml', '.xml') assert self.get(url='/file.mp4')['status'] == 403, 'app * mtype mp4' self.action_update( - {"share": temp_dir + "/assets", "types": ["video/*"]} + {"share": temp_dir + "/assets$uri", "types": ["video/*"]} ) assert self.get(url='/file.xml')['status'] == 403, 'video * mtype xml' self.check_body('/file.mp4', '.mp4') def test_static_types_negation(self, temp_dir): self.action_update( - {"share": temp_dir + "/assets", "types": ["!application/xml"]} + {"share": temp_dir + "/assets$uri", "types": ["!application/xml"]} ) assert self.get(url='/file.xml')['status'] == 403, 'forbidden negation' self.check_body('/file.mp4', '.mp4') @@ -76,7 +76,7 @@ class TestStaticTypes(TestApplicationProto): # sorting negation self.action_update( { - "share": temp_dir + "/assets", + "share": temp_dir + "/assets$uri", "types": ["!video/*", "image/png", "!image/jpg"], } ) @@ -86,7 +86,7 @@ class TestStaticTypes(TestApplicationProto): def test_static_types_regex(self, temp_dir): self.action_update( - {"share": temp_dir + "/assets", "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') @@ -94,7 +94,7 @@ class TestStaticTypes(TestApplicationProto): def test_static_types_case(self, temp_dir): self.action_update( - {"share": temp_dir + "/assets", "types": ["!APpliCaTiOn/xMl"]} + {"share": temp_dir + "/assets$uri", "types": ["!APpliCaTiOn/xMl"]} ) self.check_body('/file.mp4', '.mp4') assert ( @@ -102,7 +102,7 @@ class TestStaticTypes(TestApplicationProto): ), 'mixed case xml negation' self.action_update( - {"share": temp_dir + "/assets", "types": ["vIdEo/mp4"]} + {"share": temp_dir + "/assets$uri", "types": ["vIdEo/mp4"]} ) assert self.get(url='/file.mp4')['status'] == 200, 'mixed case' assert ( @@ -110,7 +110,7 @@ class TestStaticTypes(TestApplicationProto): ), 'mixed case video negation' self.action_update( - {"share": temp_dir + "/assets", "types": ["vIdEo/*"]} + {"share": temp_dir + "/assets$uri", "types": ["vIdEo/*"]} ) self.check_body('/file.mp4', '.mp4') assert ( @@ -126,7 +126,7 @@ class TestStaticTypes(TestApplicationProto): }, { "action": { - "share": temp_dir + "/assets", + "share": temp_dir + "/assets$uri", "types": ["!application/x-httpd-php"], "fallback": {"proxy": "http://127.0.0.1:7081"}, } @@ -140,17 +140,18 @@ class TestStaticTypes(TestApplicationProto): def test_static_types_index(self, temp_dir): self.action_update( - {"share": temp_dir + "/assets", "types": "application/xml"} + {"share": temp_dir + "/assets$uri", "types": "application/xml"} ) self.check_body('/', 'index') self.check_body('/file.xml', '.xml') + assert self.get(url='/index.html')['status'] == 403, 'forbidden mtype' assert self.get(url='/file.mp4')['status'] == 403, 'forbidden mtype' def test_static_types_custom_mime(self, temp_dir): self._load_conf( { "listeners": {"*:7080": {"pass": "routes"}}, - "routes": [{"action": {"share": temp_dir + "/assets"}}], + "routes": [{"action": {"share": temp_dir + "/assets$uri"}}], "applications": {}, "settings": { "http": { @@ -160,10 +161,10 @@ class TestStaticTypes(TestApplicationProto): } ) - self.action_update({"share": temp_dir + "/assets", "types": [""]}) + self.action_update({"share": temp_dir + "/assets$uri", "types": [""]}) assert self.get(url='/file')['status'] == 403, 'forbidden custom mime' self.action_update( - {"share": temp_dir + "/assets", "types": ["test/mime-type"]} + {"share": temp_dir + "/assets$uri", "types": ["test/mime-type"]} ) self.check_body('/file', '') -- cgit From 22028549c6172d8514b32ad2e31fc5512496dab6 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Tue, 5 Oct 2021 03:24:56 +0100 Subject: Tests: added tests for "share" option with arrays. --- test/test_static_share.py | 73 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 test/test_static_share.py (limited to 'test') diff --git a/test/test_static_share.py b/test/test_static_share.py new file mode 100644 index 00000000..ad97cc3e --- /dev/null +++ b/test/test_static_share.py @@ -0,0 +1,73 @@ +import os +from pathlib import Path + +import pytest + +from unit.applications.proto import TestApplicationProto + + +class TestStaticShare(TestApplicationProto): + prerequisites = {} + + @pytest.fixture(autouse=True) + def setup_method_fixture(self, temp_dir): + os.makedirs(temp_dir + '/assets/dir') + os.makedirs(temp_dir + '/assets/dir2') + + Path(temp_dir + '/assets/dir/file').write_text('1') + Path(temp_dir + '/assets/dir2/file2').write_text('2') + + assert 'success' in self.conf( + { + "listeners": {"*:7080": {"pass": "routes"}}, + "routes": [{"action": {"share": temp_dir + "/assets$uri"}}], + "applications": {}, + } + ) + + def action_update(self, conf): + assert 'success' in self.conf(conf, 'routes/0/action') + + def test_share_array(self, temp_dir): + assert self.get(url='/dir/file')['body'] == '1' + assert self.get(url='/dir2/file2')['body'] == '2' + + self.action_update({"share": [temp_dir + "/assets/dir$uri"]}) + + assert self.get(url='/file')['body'] == '1' + assert self.get(url='/file2')['status'] == 404 + + self.action_update( + { + "share": [ + temp_dir + "/assets/dir$uri", + temp_dir + "/assets/dir2$uri", + ] + } + ) + + assert self.get(url='/file')['body'] == '1' + assert self.get(url='/file2')['body'] == '2' + + self.action_update( + { + "share": [ + temp_dir + "/assets/dir2$uri", + temp_dir + "/assets/dir3$uri", + ] + } + ) + + assert self.get(url='/file')['status'] == 404 + assert self.get(url='/file2')['body'] == '2' + + def test_share_array_fallback(self): + self.action_update( + {"share": ["/blah", "/blah2"], "fallback": {"return": 201}} + ) + + assert self.get()['status'] == 201 + + def test_share_array_invalid(self): + assert 'error' in self.conf({"share": []}, 'routes/0/action') + assert 'error' in self.conf({"share": {}}, 'routes/0/action') -- cgit From a59557ccd73d32422143fba2ee7cc91400759330 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Tue, 5 Oct 2021 12:42:41 +0100 Subject: Tests: added tests for variables in "share". --- test/test_static_variables.py | 80 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 test/test_static_variables.py (limited to 'test') diff --git a/test/test_static_variables.py b/test/test_static_variables.py new file mode 100644 index 00000000..80673b28 --- /dev/null +++ b/test/test_static_variables.py @@ -0,0 +1,80 @@ +import os +from pathlib import Path + +import pytest + +from unit.applications.proto import TestApplicationProto + + +class TestStaticVariables(TestApplicationProto): + prerequisites = {} + + @pytest.fixture(autouse=True) + def setup_method_fixture(self, temp_dir): + os.makedirs(temp_dir + '/assets/dir') + os.makedirs(temp_dir + '/assets/d$r') + Path(temp_dir + '/assets/index.html').write_text('0123456789') + Path(temp_dir + '/assets/dir/file').write_text('file') + Path(temp_dir + '/assets/d$r/file').write_text('d$r') + + self._load_conf( + { + "listeners": {"*:7080": {"pass": "routes"}}, + "routes": [{"action": {"share": temp_dir + "/assets$uri"}}], + } + ) + + def update_share(self, share): + if isinstance(share, list): + return self.conf(share, 'routes/0/action/share') + + return self.conf('"' + share + '"', 'routes/0/action/share') + + def test_static_varibales(self, temp_dir): + assert self.get(url='/index.html')['status'] == 200 + assert self.get(url='/d$r/file')['status'] == 200 + + assert 'success' in self.update_share('$uri') + assert self.get(url=temp_dir + '/assets/index.html')['status'] == 200 + + assert 'success' in self.update_share(temp_dir + '/assets${uri}') + assert self.get(url='/index.html')['status'] == 200 + + def test_static_varibales_array(self, temp_dir): + assert 'success' in self.update_share( + [temp_dir + '/assets$uri', '$uri'] + ) + + assert self.get(url='/dir/file')['status'] == 200 + assert self.get(url=temp_dir + '/assets/index.html')['status'] == 200 + assert self.get(url='/blah')['status'] == 404 + + assert 'success' in self.conf( + { + "share": [temp_dir + '/assets$uri', '$uri'], + "fallback": {"return": 201}, + }, + 'routes/0/action', + ) + + assert self.get(url='/dir/file')['status'] == 200 + assert self.get(url=temp_dir + '/assets/index.html')['status'] == 200 + assert self.get(url='/dir/blah')['status'] == 201 + + def test_static_varibales_buildin_start(self, temp_dir): + assert 'success' in self.update_share('$uri/assets/index.html') + assert self.get(url=temp_dir)['status'] == 200 + + def test_static_varibales_buildin_mid(self, temp_dir): + assert 'success' in self.update_share(temp_dir + '$uri/index.html') + assert self.get(url='/assets')['status'] == 200 + + def test_static_varibales_buildin_end(self): + assert self.get(url='/index.html')['status'] == 200 + + def test_static_varibales_invalid(self, temp_dir): + assert 'error' in self.update_share(temp_dir + '/assets/d$r$uri') + assert 'error' in self.update_share(temp_dir + '/assets/$$uri') + assert 'error' in self.update_share( + [temp_dir + '/assets$uri', temp_dir + '/assets/dir', '$$uri'] + ) -- cgit From 5c20d43effd950a92ec48c085342a868aaaab353 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Tue, 5 Oct 2021 12:43:05 +0100 Subject: Tests: added tests for variables in "chroot". --- test/test_static_chroot.py | 116 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) (limited to 'test') diff --git a/test/test_static_chroot.py b/test/test_static_chroot.py index aa2952a1..4b9d745a 100644 --- a/test/test_static_chroot.py +++ b/test/test_static_chroot.py @@ -25,6 +25,16 @@ class TestStaticChroot(TestApplicationProto): } ) + def update_action(self, share, chroot): + return self.conf( + {"share": share, "chroot": chroot}, 'routes/0/action', + ) + + def get_custom(self, uri, host): + 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' assert self.get(url='/index.html')['status'] == 200, 'default chroot 2' @@ -41,6 +51,30 @@ class TestStaticChroot(TestApplicationProto): assert self.get(url='/index.html')['status'] == 403, 'chroot 403 2' assert self.get(url='/file')['status'] == 403, 'chroot 403' + def test_share_chroot_array(self, temp_dir): + assert 'success' in self.conf( + { + "share": ["/blah", temp_dir + "/assets$uri"], + "chroot": temp_dir + "/assets/dir", + }, + 'routes/0/action', + ), 'configure share array' + assert self.get(url='/dir/file')['status'] == 200, 'share array' + + assert 'success' in self.update_action( + ["/blah", temp_dir + '/assets$uri'], temp_dir + '/assets/$host' + ) + assert self.get_custom('/dir/file', 'dir') == 200, 'array variable' + + assert 'success' in self.conf( + { + "share": ["/blah", "/blah2"], + "chroot": temp_dir + "/assets/dir", + }, + 'routes/0/action', + ), 'configure share array bad' + assert self.get()['status'] != 200, 'share array bad' + def test_static_chroot_permission(self, is_su, temp_dir): if is_su: pytest.skip('does\'t work under root') @@ -98,6 +132,81 @@ class TestStaticChroot(TestApplicationProto): assert self.get(url=self.test_path)['status'] == 200, 'relative' + def test_static_chroot_varibales(self, temp_dir): + assert 'success' in self.update_action( + temp_dir + '/assets$uri', temp_dir + '/assets/$host' + ) + assert self.get_custom('/dir/file', 'dir') == 200 + + assert 'success' in self.update_action( + temp_dir + '/assets$uri', temp_dir + '/assets/${host}' + ) + assert self.get_custom('/dir/file', 'dir') == 200 + + def test_static_chroot_varibales_buildin_start(self, temp_dir): + assert 'success' in self.update_action( + temp_dir + '/assets/dir/$host', '$uri/assets/dir' + ) + + assert self.get_custom(temp_dir, 'file') == 200 + + def test_static_chroot_varibales_buildin_mid(self, temp_dir): + assert 'success' in self.update_action( + temp_dir + '/assets$uri', temp_dir + '/$host/dir' + ) + + assert self.get_custom('/dir/file', 'assets') == 200 + + def test_static_chroot_varibales_buildin_end(self, temp_dir): + assert 'success' in self.update_action( + temp_dir + '/assets$uri', temp_dir + '/assets/$host' + ) + + assert self.get_custom('/dir/file', 'dir') == 200 + + def test_static_chroot_slash(self, temp_dir): + assert 'success' in self.conf( + { + "share": temp_dir + "/assets$uri", + "chroot": temp_dir + "/assets/dir/", + }, + 'routes/0/action', + ), 'configure chroot slash end' + + assert self.get(url='/dir/file')['status'] == 200, 'slash end' + assert self.get(url='/dirxfile')['status'] == 403, 'slash end bad' + + assert 'success' in self.conf( + { + "share": temp_dir + "/assets$uri", + "chroot": temp_dir + "/assets/dir", + }, + 'routes/0/action', + ), 'configure chroot no slash end' + + assert self.get(url='/dir/file')['status'] == 200, 'no slash end' + + assert 'success' in self.conf( + { + "share": temp_dir + "/assets$uri", + "chroot": temp_dir + "/assets/dir/", + }, + 'routes/0/action', + ), 'configure chroot slash end 2' + + assert self.get(url='/dir/file')['status'] == 200, 'slash end 2' + assert self.get(url='/dirxfile')['status'] == 403, 'slash end 2 bad' + + assert 'success' in self.conf( + { + "share": temp_dir + "///assets/////$uri", + "chroot": temp_dir + "//assets////dir///", + }, + 'routes/0/action', + ), 'configure chroot multiple slashes' + + assert self.get(url='/dir/file')['status'] == 200, 'multiple slashes' + def test_static_chroot_invalid(self, temp_dir): assert 'error' in self.conf( {"share": temp_dir, "chroot": True}, 'routes/0/action', @@ -108,3 +217,10 @@ class TestStaticChroot(TestApplicationProto): assert 'error' in self.conf( {"share": temp_dir, "mount": "True"}, 'routes/0/action', ), 'configure mount error' + + assert 'error' in self.update_action( + temp_dir + '/assets$uri', temp_dir + '/assets/d$r$uri' + ) + assert 'error' in self.update_action( + temp_dir + '/assets$uri', temp_dir + '/assets/$$uri' + ) -- cgit From 39adb292d54403d17f86f6852e87b0bda1d49946 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Mon, 18 Oct 2021 01:10:11 +0100 Subject: Tests: style. --- test/conftest.py | 1 - test/python/restart/v1.py | 2 -- test/python/restart/v2.py | 2 -- test/python/threading/asgi.py | 3 +-- test/python/threading/wsgi.py | 2 +- test/python/threads/asgi.py | 3 +-- test/python/threads/wsgi.py | 2 +- test/python/upload/wsgi.py | 2 +- test/test_access_log.py | 1 - test/test_asgi_application.py | 1 - test/test_asgi_lifespan.py | 1 - test/test_asgi_targets.py | 1 - test/test_asgi_websockets.py | 1 - test/test_client_ip.py | 1 - test/test_configuration.py | 1 - test/test_go_isolation.py | 1 - test/test_go_isolation_rootfs.py | 1 - test/test_http_header.py | 1 - test/test_java_isolation_rootfs.py | 1 - test/test_java_websockets.py | 1 - test/test_node_application.py | 1 - test/test_node_es_modules.py | 1 - test/test_node_websockets.py | 1 - test/test_perl_application.py | 1 - test/test_php_application.py | 1 - test/test_php_isolation.py | 1 - test/test_proxy.py | 1 - test/test_python_application.py | 1 - test/test_python_isolation.py | 1 - test/test_python_isolation_chroot.py | 1 - test/test_python_procman.py | 4 ++-- test/test_python_targets.py | 1 - test/test_routing.py | 1 - test/test_ruby_application.py | 1 - test/test_ruby_hooks.py | 5 ----- test/test_ruby_isolation.py | 4 ---- test/test_settings.py | 1 - test/test_static.py | 1 - test/test_static_chroot.py | 9 ++++----- test/test_static_fallback.py | 1 - test/test_static_mount.py | 1 - test/test_static_share.py | 1 - test/test_static_symlink.py | 1 - test/test_static_types.py | 1 - test/test_static_variables.py | 13 ++++++------- test/test_tls.py | 2 -- test/test_tls_conf_command.py | 1 - test/test_tls_sni.py | 1 - test/unit/applications/lang/ruby.py | 1 - test/unit/applications/proto.py | 2 +- test/unit/check/isolation.py | 2 +- 51 files changed, 19 insertions(+), 74 deletions(-) (limited to 'test') diff --git a/test/conftest.py b/test/conftest.py index 4d46e2fc..36061f8c 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -14,7 +14,6 @@ import time from multiprocessing import Process import pytest - from unit.check.chroot import check_chroot from unit.check.go import check_go from unit.check.isolation import check_isolation diff --git a/test/python/restart/v1.py b/test/python/restart/v1.py index 2e45b269..08f7dd64 100644 --- a/test/python/restart/v1.py +++ b/test/python/restart/v1.py @@ -1,5 +1,3 @@ -import os - def application(environ, start_response): body = "v1".encode() diff --git a/test/python/restart/v2.py b/test/python/restart/v2.py index 59e3d30f..163d0d17 100644 --- a/test/python/restart/v2.py +++ b/test/python/restart/v2.py @@ -1,5 +1,3 @@ -import os - def application(environ, start_response): body = "v2".encode() diff --git a/test/python/threading/asgi.py b/test/python/threading/asgi.py index c4169a24..fed6fcce 100644 --- a/test/python/threading/asgi.py +++ b/test/python/threading/asgi.py @@ -1,7 +1,6 @@ -import asyncio import sys -import time import threading +import time class Foo(threading.Thread): diff --git a/test/python/threading/wsgi.py b/test/python/threading/wsgi.py index adaa2a37..48a73afd 100644 --- a/test/python/threading/wsgi.py +++ b/test/python/threading/wsgi.py @@ -1,6 +1,6 @@ import sys -import time import threading +import time class Foo(threading.Thread): diff --git a/test/python/threads/asgi.py b/test/python/threads/asgi.py index ff4e52ad..0537f59b 100644 --- a/test/python/threads/asgi.py +++ b/test/python/threads/asgi.py @@ -1,6 +1,5 @@ -import asyncio -import time import threading +import time async def application(scope, receive, send): diff --git a/test/python/threads/wsgi.py b/test/python/threads/wsgi.py index cc283cfe..35db2d07 100644 --- a/test/python/threads/wsgi.py +++ b/test/python/threads/wsgi.py @@ -1,5 +1,5 @@ -import time import threading +import time def application(environ, start_response): diff --git a/test/python/upload/wsgi.py b/test/python/upload/wsgi.py index 953c5ecc..2c820d06 100644 --- a/test/python/upload/wsgi.py +++ b/test/python/upload/wsgi.py @@ -1,5 +1,5 @@ +import cgi from tempfile import TemporaryFile -import os, cgi def read(environ): diff --git a/test/test_access_log.py b/test/test_access_log.py index ba254c5e..5d242a1a 100644 --- a/test/test_access_log.py +++ b/test/test_access_log.py @@ -1,7 +1,6 @@ import time import pytest - from unit.applications.lang.python import TestApplicationPython from unit.option import option diff --git a/test/test_asgi_application.py b/test/test_asgi_application.py index f503fa82..4c8a2e77 100644 --- a/test/test_asgi_application.py +++ b/test/test_asgi_application.py @@ -3,7 +3,6 @@ import time from distutils.version import LooseVersion import pytest - from unit.applications.lang.python import TestApplicationPython from unit.option import option diff --git a/test/test_asgi_lifespan.py b/test/test_asgi_lifespan.py index 90866ec3..2109a746 100644 --- a/test/test_asgi_lifespan.py +++ b/test/test_asgi_lifespan.py @@ -2,7 +2,6 @@ import os from distutils.version import LooseVersion import pytest - from conftest import unit_stop from unit.applications.lang.python import TestApplicationPython from unit.option import option diff --git a/test/test_asgi_targets.py b/test/test_asgi_targets.py index a0eb1f84..b9489cd3 100644 --- a/test/test_asgi_targets.py +++ b/test/test_asgi_targets.py @@ -1,7 +1,6 @@ from distutils.version import LooseVersion import pytest - from unit.applications.lang.python import TestApplicationPython from unit.option import option diff --git a/test/test_asgi_websockets.py b/test/test_asgi_websockets.py index 7da2d9ce..bad54e22 100644 --- a/test/test_asgi_websockets.py +++ b/test/test_asgi_websockets.py @@ -3,7 +3,6 @@ import time from distutils.version import LooseVersion import pytest - from unit.applications.lang.python import TestApplicationPython from unit.applications.websockets import TestApplicationWebsocket from unit.option import option diff --git a/test/test_client_ip.py b/test/test_client_ip.py index 0084574e..8b89b418 100644 --- a/test/test_client_ip.py +++ b/test/test_client_ip.py @@ -1,5 +1,4 @@ import pytest - from unit.applications.lang.python import TestApplicationPython diff --git a/test/test_configuration.py b/test/test_configuration.py index 8655968f..4a9d9840 100644 --- a/test/test_configuration.py +++ b/test/test_configuration.py @@ -1,7 +1,6 @@ import socket import pytest - from unit.control import TestControl diff --git a/test/test_go_isolation.py b/test/test_go_isolation.py index e02ef1cf..0530dfdf 100644 --- a/test/test_go_isolation.py +++ b/test/test_go_isolation.py @@ -3,7 +3,6 @@ import os import pwd import pytest - from unit.applications.lang.go import TestApplicationGo from unit.option import option from unit.utils import getns diff --git a/test/test_go_isolation_rootfs.py b/test/test_go_isolation_rootfs.py index 1cc59c67..2bded5ec 100644 --- a/test/test_go_isolation_rootfs.py +++ b/test/test_go_isolation_rootfs.py @@ -1,7 +1,6 @@ import os import pytest - from unit.applications.lang.go import TestApplicationGo diff --git a/test/test_http_header.py b/test/test_http_header.py index fdb557cf..ca355eb7 100644 --- a/test/test_http_header.py +++ b/test/test_http_header.py @@ -1,5 +1,4 @@ import pytest - from unit.applications.lang.python import TestApplicationPython diff --git a/test/test_java_isolation_rootfs.py b/test/test_java_isolation_rootfs.py index a401e23b..91773981 100644 --- a/test/test_java_isolation_rootfs.py +++ b/test/test_java_isolation_rootfs.py @@ -2,7 +2,6 @@ import os import subprocess import pytest - from unit.applications.lang.java import TestApplicationJava from unit.option import option diff --git a/test/test_java_websockets.py b/test/test_java_websockets.py index df0f76e8..a80d3bf3 100644 --- a/test/test_java_websockets.py +++ b/test/test_java_websockets.py @@ -2,7 +2,6 @@ import struct import time import pytest - from unit.applications.lang.java import TestApplicationJava from unit.applications.websockets import TestApplicationWebsocket from unit.option import option diff --git a/test/test_node_application.py b/test/test_node_application.py index 48ed8d3d..62a09c43 100644 --- a/test/test_node_application.py +++ b/test/test_node_application.py @@ -1,7 +1,6 @@ import re import pytest - from unit.applications.lang.node import TestApplicationNode from unit.utils import waitforfiles diff --git a/test/test_node_es_modules.py b/test/test_node_es_modules.py index 5464d4a6..47b066d5 100644 --- a/test/test_node_es_modules.py +++ b/test/test_node_es_modules.py @@ -1,7 +1,6 @@ from distutils.version import LooseVersion import pytest - from unit.applications.lang.node import TestApplicationNode from unit.applications.websockets import TestApplicationWebsocket diff --git a/test/test_node_websockets.py b/test/test_node_websockets.py index 51515f4e..e4c8a05e 100644 --- a/test/test_node_websockets.py +++ b/test/test_node_websockets.py @@ -2,7 +2,6 @@ import struct import time import pytest - from unit.applications.lang.node import TestApplicationNode from unit.applications.websockets import TestApplicationWebsocket from unit.option import option diff --git a/test/test_perl_application.py b/test/test_perl_application.py index e906aaca..dfd8be6c 100644 --- a/test/test_perl_application.py +++ b/test/test_perl_application.py @@ -1,7 +1,6 @@ import re import pytest - from unit.applications.lang.perl import TestApplicationPerl diff --git a/test/test_php_application.py b/test/test_php_application.py index 66e2ef7d..bb7d978c 100644 --- a/test/test_php_application.py +++ b/test/test_php_application.py @@ -5,7 +5,6 @@ import signal import time import pytest - from unit.applications.lang.php import TestApplicationPHP from unit.option import option diff --git a/test/test_php_isolation.py b/test/test_php_isolation.py index 8db6b590..aebeefa6 100644 --- a/test/test_php_isolation.py +++ b/test/test_php_isolation.py @@ -1,5 +1,4 @@ import pytest - from unit.applications.lang.php import TestApplicationPHP from unit.option import option diff --git a/test/test_proxy.py b/test/test_proxy.py index 3d59cf24..553cb07c 100644 --- a/test/test_proxy.py +++ b/test/test_proxy.py @@ -3,7 +3,6 @@ import socket import time import pytest - from conftest import run_process from unit.applications.lang.python import TestApplicationPython from unit.option import option diff --git a/test/test_python_application.py b/test/test_python_application.py index 48c3d603..7bd43664 100644 --- a/test/test_python_application.py +++ b/test/test_python_application.py @@ -5,7 +5,6 @@ import re import time import pytest - from unit.applications.lang.python import TestApplicationPython diff --git a/test/test_python_isolation.py b/test/test_python_isolation.py index 93f85264..53d28285 100644 --- a/test/test_python_isolation.py +++ b/test/test_python_isolation.py @@ -1,5 +1,4 @@ import pytest - from unit.applications.lang.python import TestApplicationPython from unit.option import option from unit.utils import findmnt diff --git a/test/test_python_isolation_chroot.py b/test/test_python_isolation_chroot.py index 54fbad12..1554fb72 100644 --- a/test/test_python_isolation_chroot.py +++ b/test/test_python_isolation_chroot.py @@ -1,5 +1,4 @@ import pytest - from unit.applications.lang.python import TestApplicationPython diff --git a/test/test_python_procman.py b/test/test_python_procman.py index a95c5680..389d0747 100644 --- a/test/test_python_procman.py +++ b/test/test_python_procman.py @@ -4,7 +4,6 @@ import subprocess import time import pytest - from unit.applications.lang.python import TestApplicationPython from unit.option import option @@ -265,7 +264,8 @@ class TestPythonProcman(TestApplicationPython): assert len(self.pids_for_process()) == 1, 'longstarts == 1' - pid = self.get()['body'] + self.get() + pids = self.pids_for_process() assert len(pids) == 2, 'longstarts == 2' diff --git a/test/test_python_targets.py b/test/test_python_targets.py index ca736c0d..6e5488ee 100644 --- a/test/test_python_targets.py +++ b/test/test_python_targets.py @@ -1,5 +1,4 @@ import pytest - from unit.applications.lang.python import TestApplicationPython from unit.option import option diff --git a/test/test_routing.py b/test/test_routing.py index ef5622c2..7c3b56f8 100644 --- a/test/test_routing.py +++ b/test/test_routing.py @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- import pytest - from unit.applications.proto import TestApplicationProto from unit.option import option diff --git a/test/test_ruby_application.py b/test/test_ruby_application.py index ddd31f59..ed0200d9 100644 --- a/test/test_ruby_application.py +++ b/test/test_ruby_application.py @@ -2,7 +2,6 @@ import re import subprocess import pytest - from unit.applications.lang.ruby import TestApplicationRuby diff --git a/test/test_ruby_hooks.py b/test/test_ruby_hooks.py index af8ce337..306ffa4b 100644 --- a/test/test_ruby_hooks.py +++ b/test/test_ruby_hooks.py @@ -1,9 +1,4 @@ -import os -import time -from pathlib import Path - import pytest - from conftest import unit_stop from unit.applications.lang.ruby import TestApplicationRuby from unit.option import option diff --git a/test/test_ruby_isolation.py b/test/test_ruby_isolation.py index f414d610..940427f1 100644 --- a/test/test_ruby_isolation.py +++ b/test/test_ruby_isolation.py @@ -1,8 +1,4 @@ -import os -import shutil - import pytest - from unit.applications.lang.ruby import TestApplicationRuby from unit.option import option diff --git a/test/test_settings.py b/test/test_settings.py index 49041b62..a16e35e8 100644 --- a/test/test_settings.py +++ b/test/test_settings.py @@ -3,7 +3,6 @@ import socket import time import pytest - from unit.applications.lang.python import TestApplicationPython from unit.utils import sysctl diff --git a/test/test_static.py b/test/test_static.py index fa0a81a2..94f790da 100644 --- a/test/test_static.py +++ b/test/test_static.py @@ -2,7 +2,6 @@ import os import socket import pytest - from unit.applications.proto import TestApplicationProto from unit.option import option from unit.utils import waitforfiles diff --git a/test/test_static_chroot.py b/test/test_static_chroot.py index 4b9d745a..62288807 100644 --- a/test/test_static_chroot.py +++ b/test/test_static_chroot.py @@ -2,7 +2,6 @@ import os from pathlib import Path import pytest - from unit.applications.proto import TestApplicationProto @@ -132,7 +131,7 @@ class TestStaticChroot(TestApplicationProto): assert self.get(url=self.test_path)['status'] == 200, 'relative' - def test_static_chroot_varibales(self, temp_dir): + def test_static_chroot_variables(self, temp_dir): assert 'success' in self.update_action( temp_dir + '/assets$uri', temp_dir + '/assets/$host' ) @@ -143,21 +142,21 @@ class TestStaticChroot(TestApplicationProto): ) assert self.get_custom('/dir/file', 'dir') == 200 - def test_static_chroot_varibales_buildin_start(self, temp_dir): + def test_static_chroot_variables_buildin_start(self, temp_dir): assert 'success' in self.update_action( temp_dir + '/assets/dir/$host', '$uri/assets/dir' ) assert self.get_custom(temp_dir, 'file') == 200 - def test_static_chroot_varibales_buildin_mid(self, temp_dir): + def test_static_chroot_variables_buildin_mid(self, temp_dir): assert 'success' in self.update_action( temp_dir + '/assets$uri', temp_dir + '/$host/dir' ) assert self.get_custom('/dir/file', 'assets') == 200 - def test_static_chroot_varibales_buildin_end(self, temp_dir): + def test_static_chroot_variables_buildin_end(self, temp_dir): assert 'success' in self.update_action( temp_dir + '/assets$uri', temp_dir + '/assets/$host' ) diff --git a/test/test_static_fallback.py b/test/test_static_fallback.py index 4cfebcec..71b268c8 100644 --- a/test/test_static_fallback.py +++ b/test/test_static_fallback.py @@ -2,7 +2,6 @@ import os from pathlib import Path import pytest - from unit.applications.proto import TestApplicationProto diff --git a/test/test_static_mount.py b/test/test_static_mount.py index fb4fbe4b..e34a8a07 100644 --- a/test/test_static_mount.py +++ b/test/test_static_mount.py @@ -3,7 +3,6 @@ import subprocess from pathlib import Path import pytest - from unit.applications.proto import TestApplicationProto diff --git a/test/test_static_share.py b/test/test_static_share.py index ad97cc3e..5384866e 100644 --- a/test/test_static_share.py +++ b/test/test_static_share.py @@ -2,7 +2,6 @@ import os from pathlib import Path import pytest - from unit.applications.proto import TestApplicationProto diff --git a/test/test_static_symlink.py b/test/test_static_symlink.py index e0fd7277..24638e20 100644 --- a/test/test_static_symlink.py +++ b/test/test_static_symlink.py @@ -2,7 +2,6 @@ import os from pathlib import Path import pytest - from unit.applications.proto import TestApplicationProto diff --git a/test/test_static_types.py b/test/test_static_types.py index 41ab7368..18564a21 100644 --- a/test/test_static_types.py +++ b/test/test_static_types.py @@ -1,7 +1,6 @@ from pathlib import Path import pytest - from unit.applications.proto import TestApplicationProto diff --git a/test/test_static_variables.py b/test/test_static_variables.py index 80673b28..e7e1629c 100644 --- a/test/test_static_variables.py +++ b/test/test_static_variables.py @@ -2,7 +2,6 @@ import os from pathlib import Path import pytest - from unit.applications.proto import TestApplicationProto @@ -30,7 +29,7 @@ class TestStaticVariables(TestApplicationProto): return self.conf('"' + share + '"', 'routes/0/action/share') - def test_static_varibales(self, temp_dir): + def test_static_variables(self, temp_dir): assert self.get(url='/index.html')['status'] == 200 assert self.get(url='/d$r/file')['status'] == 200 @@ -40,7 +39,7 @@ class TestStaticVariables(TestApplicationProto): assert 'success' in self.update_share(temp_dir + '/assets${uri}') assert self.get(url='/index.html')['status'] == 200 - def test_static_varibales_array(self, temp_dir): + def test_static_variables_array(self, temp_dir): assert 'success' in self.update_share( [temp_dir + '/assets$uri', '$uri'] ) @@ -61,18 +60,18 @@ class TestStaticVariables(TestApplicationProto): assert self.get(url=temp_dir + '/assets/index.html')['status'] == 200 assert self.get(url='/dir/blah')['status'] == 201 - def test_static_varibales_buildin_start(self, temp_dir): + def test_static_variables_buildin_start(self, temp_dir): assert 'success' in self.update_share('$uri/assets/index.html') assert self.get(url=temp_dir)['status'] == 200 - def test_static_varibales_buildin_mid(self, temp_dir): + def test_static_variables_buildin_mid(self, temp_dir): assert 'success' in self.update_share(temp_dir + '$uri/index.html') assert self.get(url='/assets')['status'] == 200 - def test_static_varibales_buildin_end(self): + def test_static_variables_buildin_end(self): assert self.get(url='/index.html')['status'] == 200 - def test_static_varibales_invalid(self, temp_dir): + def test_static_variables_invalid(self, temp_dir): assert 'error' in self.update_share(temp_dir + '/assets/d$r$uri') assert 'error' in self.update_share(temp_dir + '/assets/$$uri') assert 'error' in self.update_share( diff --git a/test/test_tls.py b/test/test_tls.py index 546f0f89..a91a3760 100644 --- a/test/test_tls.py +++ b/test/test_tls.py @@ -5,7 +5,6 @@ import subprocess import time import pytest - from unit.applications.tls import TestApplicationTLS from unit.option import option @@ -677,4 +676,3 @@ basicConstraints = critical,CA:TRUE""" assert self.get_ssl()['status'] == 200, 'listener #1' assert self.get_ssl(port=7081)['status'] == 200, 'listener #2' - diff --git a/test/test_tls_conf_command.py b/test/test_tls_conf_command.py index ccae09ad..b414b5a0 100644 --- a/test/test_tls_conf_command.py +++ b/test/test_tls_conf_command.py @@ -1,7 +1,6 @@ import ssl import pytest - from unit.applications.tls import TestApplicationTLS diff --git a/test/test_tls_sni.py b/test/test_tls_sni.py index eba6140a..28ab875b 100644 --- a/test/test_tls_sni.py +++ b/test/test_tls_sni.py @@ -2,7 +2,6 @@ import ssl import subprocess import pytest - from unit.applications.tls import TestApplicationTLS from unit.option import option diff --git a/test/unit/applications/lang/ruby.py b/test/unit/applications/lang/ruby.py index 61d50558..824bfe7f 100644 --- a/test/unit/applications/lang/ruby.py +++ b/test/unit/applications/lang/ruby.py @@ -1,4 +1,3 @@ -import os import shutil from unit.applications.proto import TestApplicationProto diff --git a/test/unit/applications/proto.py b/test/unit/applications/proto.py index e30d21ff..cd8672ba 100644 --- a/test/unit/applications/proto.py +++ b/test/unit/applications/proto.py @@ -3,8 +3,8 @@ import re import time from unit.control import TestControl -from unit.option import option from unit.log import Log +from unit.option import option class TestApplicationProto(TestControl): diff --git a/test/unit/check/isolation.py b/test/unit/check/isolation.py index 43c8842f..7f98e685 100644 --- a/test/unit/check/isolation.py +++ b/test/unit/check/isolation.py @@ -3,8 +3,8 @@ import os from unit.applications.lang.go import TestApplicationGo from unit.applications.lang.java import TestApplicationJava -from unit.applications.lang.ruby import TestApplicationRuby from unit.applications.lang.node import TestApplicationNode +from unit.applications.lang.ruby import TestApplicationRuby from unit.applications.proto import TestApplicationProto from unit.http import TestHTTP from unit.option import option -- cgit From e428f2cf7a2f995e41bf7c8877ef1c966411db4d Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Thu, 28 Oct 2021 17:15:38 +0100 Subject: Tests: added tests for TLS sessions. --- test/test_tls_session.py | 129 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 test/test_tls_session.py (limited to 'test') diff --git a/test/test_tls_session.py b/test/test_tls_session.py new file mode 100644 index 00000000..7854fad6 --- /dev/null +++ b/test/test_tls_session.py @@ -0,0 +1,129 @@ +import socket +import time + +import pytest +from OpenSSL.SSL import ( + TLSv1_2_METHOD, + SESS_CACHE_CLIENT, + OP_NO_TICKET, + Context, + Connection, + _lib, +) +from unit.applications.tls import TestApplicationTLS +from unit.option import option + + +class TestTLSSession(TestApplicationTLS): + prerequisites = {'modules': {'openssl': 'any'}} + + @pytest.fixture(autouse=True) + def setup_method_fixture(self, request): + self.certificate() + + assert 'success' in self.conf( + { + "listeners": { + "*:7080": { + "pass": "routes", + "tls": {"certificate": "default", "session": {}}, + } + }, + "routes": [{"action": {"return": 200}}], + "applications": {}, + } + ), 'load application configuration' + + def add_session(self, cache_size=None, timeout=None): + session = {} + + if cache_size is not None: + session['cache_size'] = cache_size + if timeout is not None: + session['timeout'] = timeout + + return self.conf(session, 'listeners/*:7080/tls/session') + + def connect(self, ctx=None, session=None): + sock = socket.create_connection(('127.0.0.1', 7080)) + + if ctx is None: + ctx = Context(TLSv1_2_METHOD) + ctx.set_session_cache_mode(SESS_CACHE_CLIENT) + ctx.set_options(OP_NO_TICKET) + + client = Connection(ctx, sock) + client.set_connect_state() + + if session is not None: + client.set_session(session) + + client.do_handshake() + client.shutdown() + + return ( + client, + client.get_session(), + ctx, + _lib.SSL_session_reused(client._ssl), + ) + + def test_tls_session(self): + client, sess, ctx, reused = self.connect() + assert not reused, 'new connection' + + client, _, _, reused = self.connect(ctx, sess) + assert not reused, 'no cache' + + assert 'success' in self.add_session(cache_size=1) + + client, sess, ctx, reused = self.connect() + assert not reused, 'new connection cache' + + client, _, _, reused = self.connect(ctx, sess) + assert reused, 'cache' + + client, _, _, reused = self.connect(ctx, sess) + assert reused, 'cache 2' + + # check that at least one session of two is not reused + + client, sess, ctx, reused = self.connect() + client2, sess2, ctx2, reused2 = self.connect() + assert True not in [reused, reused2], 'new connection cache small' + + client, _, _, reused = self.connect(ctx, sess) + client2, _, _, reused2 = self.connect(ctx2, sess2) + assert False in [reused, reused2], 'cache small' + + # both sessions are reused + + assert 'success' in self.add_session(cache_size=2) + + client, sess, ctx, reused = self.connect() + client2, sess2, ctx2, reused2 = self.connect() + assert True not in [reused, reused2], 'new connection cache big' + + client, _, _, reused = self.connect(ctx, sess) + client2, _, _, reused2 = self.connect(ctx2, sess2) + assert False not in [reused, reused2], 'cache big' + + def test_tls_session_timeout(self): + assert 'success' in self.add_session(cache_size=1, timeout=1) + + client, sess, ctx, reused = self.connect() + assert not reused, 'new connection' + + client, _, _, reused = self.connect(ctx, sess) + assert reused, 'no timeout' + + time.sleep(3) + + client, _, _, reused = self.connect(ctx, sess) + assert not reused, 'timeout' + + def test_tls_session_invalid(self): + assert 'error' in self.add_session(cache_size=-1) + assert 'error' in self.add_session(cache_size={}) + assert 'error' in self.add_session(timeout=-1) + assert 'error' in self.add_session(timeout={}) -- cgit From bd9da8bc8cedb152a15977c85339ae0a4226f0c4 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Thu, 28 Oct 2021 18:30:37 +0100 Subject: Tests: added tests for TLS session tickets. --- test/test_tls_tickets.py | 195 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 195 insertions(+) create mode 100644 test/test_tls_tickets.py (limited to 'test') diff --git a/test/test_tls_tickets.py b/test/test_tls_tickets.py new file mode 100644 index 00000000..0ea113f5 --- /dev/null +++ b/test/test_tls_tickets.py @@ -0,0 +1,195 @@ +import socket + +import pytest +from OpenSSL.SSL import ( + TLSv1_2_METHOD, + Context, + Connection, + Session, + _lib, +) +from unit.applications.tls import TestApplicationTLS +from unit.option import option + + +class TestTLSTicket(TestApplicationTLS): + prerequisites = {'modules': {'openssl': 'any'}} + + ticket = 'U1oDTh11mMxODuw12gS0EXX1E/PkZG13cJNQ6m5+6BGlfPTjNlIEw7PSVU3X1gTE' + ticket2 = ( + '5AV0DSYIYbZWZQB7fCnTHZmMxtotb/aXjam+n2XS79lTvX3Tq9xGqpC8XKNEF2lt' + ) + ticket80 = '6Pfil8lv/k8zf8MndPpfXaO5EAV6dhME6zs6CfUyq2yziynQwSywtKQMqHGnJ2HR\ +49TZXi/Y4/8RSIO7QPsU51/HLR1gWIMhVM2m9yh93Bw=' + + @pytest.fixture(autouse=True) + def setup_method_fixture(self, request): + self.certificate() + + listener_conf = { + "pass": "routes", + "tls": { + "certificate": "default", + "session": {"cache_size": 0, "tickets": True}, + }, + } + + assert 'success' in self.conf( + { + "listeners": { + "*:7080": listener_conf, + "*:7081": listener_conf, + "*:7082": listener_conf, + }, + "routes": [{"action": {"return": 200}}], + "applications": {}, + } + ), 'load application configuration' + + def set_tickets(self, tickets=True, port=7080): + assert 'success' in self.conf( + {"cache_size": 0, "tickets": tickets}, + 'listeners/*:' + str(port) + '/tls/session', + ) + + def connect(self, ctx=None, session=None, port=7080): + sock = socket.create_connection(('127.0.0.1', port)) + + if ctx is None: + ctx = Context(TLSv1_2_METHOD) + + client = Connection(ctx, sock) + client.set_connect_state() + + if session is not None: + client.set_session(session) + + client.do_handshake() + client.shutdown() + + return ( + client.get_session(), + ctx, + _lib.SSL_session_reused(client._ssl), + ) + + def has_ticket(self, sess): + return _lib.SSL_SESSION_has_ticket(sess._session) + + @pytest.mark.skipif( + not hasattr(_lib, 'SSL_SESSION_has_ticket'), + reason='ticket check is not supported', + ) + def test_tls_ticket(self): + sess, ctx, reused = self.connect() + assert self.has_ticket(sess), 'tickets True' + assert not reused, 'tickets True not reused' + + sess, ctx, reused = self.connect(ctx, sess) + assert self.has_ticket(sess), 'tickets True reconnect' + assert reused, 'tickets True reused' + + self.set_tickets(tickets=False) + + sess, _, _ = self.connect() + assert not self.has_ticket(sess), 'tickets False' + + assert 'success' in self.conf_delete( + 'listeners/*:7080/tls/session/tickets' + ), 'tickets default configure' + + sess, _, _ = self.connect() + assert not self.has_ticket(sess), 'tickets default (false)' + + @pytest.mark.skipif( + not hasattr(_lib, 'SSL_SESSION_has_ticket'), + reason='ticket check is not supported', + ) + def test_tls_ticket_string(self): + self.set_tickets(self.ticket) + sess, ctx, _ = self.connect() + assert self.has_ticket(sess), 'tickets string' + + sess2, _, reused = self.connect(ctx, sess) + assert self.has_ticket(sess2), 'tickets string reconnect' + assert reused, 'tickets string reused' + + sess2, _, reused = self.connect(ctx, sess, port=7081) + assert self.has_ticket(sess2), 'connect True' + assert not reused, 'connect True not reused' + + self.set_tickets(self.ticket2, port=7081) + + sess2, _, reused = self.connect(ctx, sess, port=7081) + assert self.has_ticket(sess2), 'wrong ticket' + assert not reused, 'wrong ticket not reused' + + self.set_tickets(self.ticket80) + + sess, ctx, _ = self.connect() + assert self.has_ticket(sess), 'tickets string 80' + + sess2, _, reused = self.connect(ctx, sess) + assert self.has_ticket(sess2), 'tickets string 80 reconnect' + assert reused, 'tickets string 80 reused' + + sess2, _, reused = self.connect(ctx, sess, port=7081) + assert self.has_ticket(sess2), 'wrong ticket 80' + assert not reused, 'wrong ticket 80 not reused' + + @pytest.mark.skipif( + not hasattr(_lib, 'SSL_SESSION_has_ticket'), + reason='ticket check is not supported', + ) + def test_tls_ticket_array(self): + self.set_tickets([]) + + sess, ctx, _ = self.connect() + assert not self.has_ticket(sess), 'tickets array empty' + + self.set_tickets([self.ticket, self.ticket2]) + self.set_tickets(self.ticket, port=7081) + self.set_tickets(self.ticket2, port=7082) + + sess, ctx, _ = self.connect() + _, _, reused = self.connect(ctx, sess, port=7081) + assert not reused, 'not last ticket' + _, _, reused = self.connect(ctx, sess, port=7082) + assert reused, 'last ticket' + + sess, ctx, _ = self.connect(port=7081) + _, _, reused = self.connect(ctx, sess) + assert reused, 'first ticket' + + sess, ctx, _ = self.connect(port=7082) + _, _, reused = self.connect(ctx, sess) + assert reused, 'second ticket' + + assert 'success' in self.conf_delete( + 'listeners/*:7080/tls/session/tickets/0' + ), 'removed first ticket' + assert 'success' in self.conf_post( + '"' + self.ticket + '"', 'listeners/*:7080/tls/session/tickets' + ), 'add new ticket to the end of array' + + sess, ctx, _ = self.connect() + _, _, reused = self.connect(ctx, sess, port=7082) + assert not reused, 'not last ticket 2' + _, _, reused = self.connect(ctx, sess, port=7081) + assert reused, 'last ticket 2' + + def test_tls_ticket_invalid(self): + def check_tickets(tickets): + assert 'error' in self.conf( + {"tickets": tickets}, 'listeners/*:7080/tls/session', + ) + + check_tickets({}) + check_tickets('!?&^' * 16) + check_tickets(self.ticket[:-2] + '!' + self.ticket[3:]) + check_tickets(self.ticket[:-1]) + check_tickets(self.ticket + 'b') + check_tickets(self.ticket + 'blah') + check_tickets([True, self.ticket, self.ticket2]) + check_tickets([self.ticket, 'blah', self.ticket2]) + check_tickets([self.ticket, self.ticket2, []]) -- cgit From c27d0fe7bd9b56ee20f01124d72800ded7ccca9c Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Tue, 2 Nov 2021 17:53:28 +0000 Subject: Tests: removed unused imports. --- test/test_asgi_application.py | 1 - test/test_asgi_lifespan.py | 1 - test/test_client_ip.py | 1 - test/test_node_es_modules.py | 1 - test/test_python_targets.py | 1 - test/test_ruby_hooks.py | 2 -- test/test_tls_session.py | 1 - test/test_tls_sni.py | 1 - test/test_tls_tickets.py | 1 - test/unit/applications/lang/python.py | 1 - test/unit/check/isolation.py | 1 - 11 files changed, 12 deletions(-) (limited to 'test') diff --git a/test/test_asgi_application.py b/test/test_asgi_application.py index 4c8a2e77..021aa2b2 100644 --- a/test/test_asgi_application.py +++ b/test/test_asgi_application.py @@ -4,7 +4,6 @@ from distutils.version import LooseVersion import pytest from unit.applications.lang.python import TestApplicationPython -from unit.option import option class TestASGIApplication(TestApplicationPython): diff --git a/test/test_asgi_lifespan.py b/test/test_asgi_lifespan.py index 2109a746..912d0d85 100644 --- a/test/test_asgi_lifespan.py +++ b/test/test_asgi_lifespan.py @@ -1,7 +1,6 @@ import os from distutils.version import LooseVersion -import pytest from conftest import unit_stop from unit.applications.lang.python import TestApplicationPython from unit.option import option diff --git a/test/test_client_ip.py b/test/test_client_ip.py index 8b89b418..4b2b2fa1 100644 --- a/test/test_client_ip.py +++ b/test/test_client_ip.py @@ -1,4 +1,3 @@ -import pytest from unit.applications.lang.python import TestApplicationPython diff --git a/test/test_node_es_modules.py b/test/test_node_es_modules.py index 47b066d5..12788fa4 100644 --- a/test/test_node_es_modules.py +++ b/test/test_node_es_modules.py @@ -1,6 +1,5 @@ from distutils.version import LooseVersion -import pytest from unit.applications.lang.node import TestApplicationNode from unit.applications.websockets import TestApplicationWebsocket diff --git a/test/test_python_targets.py b/test/test_python_targets.py index 6e5488ee..e5dca870 100644 --- a/test/test_python_targets.py +++ b/test/test_python_targets.py @@ -1,4 +1,3 @@ -import pytest from unit.applications.lang.python import TestApplicationPython from unit.option import option diff --git a/test/test_ruby_hooks.py b/test/test_ruby_hooks.py index 306ffa4b..20980ad7 100644 --- a/test/test_ruby_hooks.py +++ b/test/test_ruby_hooks.py @@ -1,5 +1,3 @@ -import pytest -from conftest import unit_stop from unit.applications.lang.ruby import TestApplicationRuby from unit.option import option from unit.utils import waitforglob diff --git a/test/test_tls_session.py b/test/test_tls_session.py index 7854fad6..0c5f0248 100644 --- a/test/test_tls_session.py +++ b/test/test_tls_session.py @@ -11,7 +11,6 @@ from OpenSSL.SSL import ( _lib, ) from unit.applications.tls import TestApplicationTLS -from unit.option import option class TestTLSSession(TestApplicationTLS): diff --git a/test/test_tls_sni.py b/test/test_tls_sni.py index 28ab875b..e3aee4e3 100644 --- a/test/test_tls_sni.py +++ b/test/test_tls_sni.py @@ -1,7 +1,6 @@ import ssl import subprocess -import pytest from unit.applications.tls import TestApplicationTLS from unit.option import option diff --git a/test/test_tls_tickets.py b/test/test_tls_tickets.py index 0ea113f5..7214f77f 100644 --- a/test/test_tls_tickets.py +++ b/test/test_tls_tickets.py @@ -9,7 +9,6 @@ from OpenSSL.SSL import ( _lib, ) from unit.applications.tls import TestApplicationTLS -from unit.option import option class TestTLSTicket(TestApplicationTLS): diff --git a/test/unit/applications/lang/python.py b/test/unit/applications/lang/python.py index 215aa332..1e38f3fa 100644 --- a/test/unit/applications/lang/python.py +++ b/test/unit/applications/lang/python.py @@ -2,7 +2,6 @@ import os import shutil from urllib.parse import quote -import pytest from unit.applications.proto import TestApplicationProto from unit.option import option diff --git a/test/unit/check/isolation.py b/test/unit/check/isolation.py index 7f98e685..9bd835a3 100644 --- a/test/unit/check/isolation.py +++ b/test/unit/check/isolation.py @@ -5,7 +5,6 @@ from unit.applications.lang.go import TestApplicationGo from unit.applications.lang.java import TestApplicationJava from unit.applications.lang.node import TestApplicationNode from unit.applications.lang.ruby import TestApplicationRuby -from unit.applications.proto import TestApplicationProto from unit.http import TestHTTP from unit.option import option from unit.utils import getns -- cgit From 2359c4056c38bfb10569ec03da895c8e6e9dfbd2 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Tue, 2 Nov 2021 18:39:03 +0000 Subject: Tests: added pyOpenSSL module check were necessary. --- test/test_tls_session.py | 2 ++ test/test_tls_tickets.py | 2 ++ 2 files changed, 4 insertions(+) (limited to 'test') diff --git a/test/test_tls_session.py b/test/test_tls_session.py index 0c5f0248..f173913b 100644 --- a/test/test_tls_session.py +++ b/test/test_tls_session.py @@ -2,6 +2,8 @@ import socket import time import pytest + +pytest.importorskip('OpenSSL.SSL') from OpenSSL.SSL import ( TLSv1_2_METHOD, SESS_CACHE_CLIENT, diff --git a/test/test_tls_tickets.py b/test/test_tls_tickets.py index 7214f77f..6899eaa1 100644 --- a/test/test_tls_tickets.py +++ b/test/test_tls_tickets.py @@ -1,6 +1,8 @@ import socket import pytest + +pytest.importorskip('OpenSSL.SSL') from OpenSSL.SSL import ( TLSv1_2_METHOD, Context, -- cgit From bc95fcc324dc55d07547ccb85389465e5db70d68 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Thu, 4 Nov 2021 13:05:53 +0000 Subject: Tests: added migration test for "share". --- test/conftest.py | 11 +++++++---- test/test_static.py | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 4 deletions(-) (limited to 'test') diff --git a/test/conftest.py b/test/conftest.py index 36061f8c..689c857a 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -356,7 +356,7 @@ def run(request): _check_alerts(log=log) -def unit_run(): +def unit_run(state_dir=None): global unit_instance if not option.restart and 'unitd' in unit_instance: @@ -374,7 +374,9 @@ def unit_run(): if oct(stat.S_IMODE(os.stat(build_dir).st_mode)) != '0o777': public_dir(build_dir) - os.mkdir(temp_dir + '/state') + state = temp_dir + '/state' if state_dir is None else state_dir + if not os.path.isdir(state): + os.mkdir(state) unitd_args = [ unitd, @@ -382,7 +384,7 @@ def unit_run(): '--modules', build_dir, '--state', - temp_dir + '/state', + state, '--pid', temp_dir + '/unit.pid', '--log', @@ -414,7 +416,8 @@ def unit_run(): with open(temp_dir + '/unit.pid', 'r') as f: unit_instance['pid'] = f.read().rstrip() - _clear_conf(unit_instance['temp_dir'] + '/control.unit.sock') + if state_dir is None: + _clear_conf(unit_instance['temp_dir'] + '/control.unit.sock') _fds_info['main']['fds'] = _count_fds(unit_instance['pid']) diff --git a/test/test_static.py b/test/test_static.py index 94f790da..80f4c610 100644 --- a/test/test_static.py +++ b/test/test_static.py @@ -1,7 +1,9 @@ import os +import shutil import socket import pytest +from conftest import unit_run, unit_stop from unit.applications.proto import TestApplicationProto from unit.option import option from unit.utils import waitforfiles @@ -40,6 +42,49 @@ class TestStatic(TestApplicationProto): } ) + def test_static_migration(self, skip_fds_check, temp_dir): + skip_fds_check(True, True, True) + + def set_conf_version(path, version): + with open(path, 'w+') as f: + f.write(str(version)) + + with open(temp_dir + '/state/version', 'r') as f: + assert int(f.read().rstrip()) > 12500, 'current version' + + assert 'success' in self.conf( + {"share": temp_dir + "/assets"}, 'routes/0/action' + ), 'configure migration 12500' + + shutil.copytree(temp_dir + '/state', temp_dir + '/state_copy_12500') + set_conf_version(temp_dir + '/state_copy_12500/version', 12500) + + assert 'success' in self.conf( + {"share": temp_dir + "/assets$uri"}, 'routes/0/action' + ), 'configure migration 12600' + shutil.copytree(temp_dir + '/state', temp_dir + '/state_copy_12600') + set_conf_version(temp_dir + '/state_copy_12600/version', 12600) + + assert 'success' in self.conf( + {"share": temp_dir + "/assets"}, 'routes/0/action' + ), 'configure migration no version' + shutil.copytree( + temp_dir + '/state', temp_dir + '/state_copy_no_version' + ) + os.remove(temp_dir + '/state_copy_no_version/version') + + unit_stop() + unit_run(temp_dir + '/state_copy_12500') + assert self.get(url='/')['body'] == '0123456789', 'before 1.26.0' + + unit_stop() + unit_run(temp_dir + '/state_copy_12600') + assert self.get(url='/')['body'] == '0123456789', 'after 1.26.0' + + unit_stop() + unit_run(temp_dir + '/state_copy_no_version') + assert self.get(url='/')['body'] == '0123456789', 'before 1.26.0 2' + def test_static_index(self): assert self.get(url='/index.html')['body'] == '0123456789', 'index' assert self.get(url='/')['body'] == '0123456789', 'index 2' -- cgit From 8c253631d90b338b02f9c997df8dfbe7d9ed0c28 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Thu, 4 Nov 2021 18:13:19 +0000 Subject: Tests: added "requirements.txt". --- test/requirements.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 test/requirements.txt (limited to 'test') diff --git a/test/requirements.txt b/test/requirements.txt new file mode 100644 index 00000000..5f94fad2 --- /dev/null +++ b/test/requirements.txt @@ -0,0 +1,2 @@ +pyOpenSSL>=20.0.1 +pytest>=6.0.1 -- cgit From aee908bcbd6ae160ab8e470ea6a373148649968b Mon Sep 17 00:00:00 2001 From: Zhidao HONG Date: Fri, 5 Nov 2021 22:56:34 +0800 Subject: Router: matching query string support. The "query" option matches decoded arguments, including plus ('+') to space (' '). Like "uri", it can be a string or an array of strings. --- test/test_routing.py | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'test') diff --git a/test/test_routing.py b/test/test_routing.py index 7c3b56f8..c031d768 100644 --- a/test/test_routing.py +++ b/test/test_routing.py @@ -1320,6 +1320,50 @@ class TestRouting(TestApplicationProto): self.route_match_invalid({"arguments": {"%%1F": ""}}) self.route_match_invalid({"arguments": {"%7%F": ""}}) + def test_routes_match_query(self): + self.route_match({"query": "!"}) + assert self.get(url='/')['status'] == 404 + assert self.get(url='/?')['status'] == 404 + assert self.get(url='/?foo')['status'] == 200 + assert self.get(url='/?foo=')['status'] == 200 + assert self.get(url='/?foo=baz')['status'] == 200 + + self.route_match({"query": "foo=%26"}) + assert self.get(url='/?foo=&')['status'] == 200 + + self.route_match({"query": "a=b&c=d"}) + assert self.get(url='/?a=b&c=d')['status'] == 200 + + self.route_match({"query": "a=b%26c%3Dd"}) + assert self.get(url='/?a=b%26c%3Dd')['status'] == 200 + assert self.get(url='/?a=b&c=d')['status'] == 200 + + self.route_match({"query": "a=b%26c%3Dd+e"}) + assert self.get(url='/?a=b&c=d e')['status'] == 200 + + def test_routes_match_query_array(self): + self.route_match({ + "query": ["foo", "bar"] + }) + + assert self.get()['status'] == 404, 'arr' + assert self.get(url='/?foo')['status'] == 200, 'arr 1' + assert self.get(url='/?bar')['status'] == 200, 'arr 2' + + assert 'success' in self.conf_delete( + 'routes/0/match/query/1' + ), 'match query array configure 2' + + assert self.get(url='/?bar')['status'] == 404, 'arr 2' + + def test_routes_match_query_invalid(self): + self.route_match_invalid({"query": [1]}) + self.route_match_invalid({"query": "%"}) + self.route_match_invalid({"query": "%1G"}) + self.route_match_invalid({"query": "%0"}) + self.route_match_invalid({"query": "%%1F"}) + self.route_match_invalid({"query": ["foo", "%3D", "%%1F"]}) + def test_routes_match_cookies(self): self.route_match({"cookies": {"foO": "bar"}}) -- cgit From 506ec2b8258cfe03d0d7e3b19eb79d1075a6174c Mon Sep 17 00:00:00 2001 From: Max Romanov Date: Tue, 9 Nov 2021 15:48:44 +0300 Subject: Tests: app prototype related fixes. --- test/test_go_application.py | 6 ++++++ test/test_go_isolation.py | 6 +++++- test/test_go_isolation_rootfs.py | 4 ++++ test/test_python_procman.py | 4 +++- test/test_tls.py | 2 +- 5 files changed, 19 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/test_go_application.py b/test/test_go_application.py index 438ce2e0..94da1aee 100644 --- a/test/test_go_application.py +++ b/test/test_go_application.py @@ -1,11 +1,17 @@ import re +import pytest + from unit.applications.lang.go import TestApplicationGo class TestGoApplication(TestApplicationGo): prerequisites = {'modules': {'go': 'all'}} + @pytest.fixture(autouse=True) + def setup_method_fixture(self, request, skip_alert): + skip_alert(r'\[unit\] close\(\d+\) failed: Bad file descriptor') + def test_go_application_variables(self): self.load('variables') diff --git a/test/test_go_isolation.py b/test/test_go_isolation.py index 0530dfdf..72988a34 100644 --- a/test/test_go_isolation.py +++ b/test/test_go_isolation.py @@ -11,6 +11,10 @@ from unit.utils import getns class TestGoIsolation(TestApplicationGo): prerequisites = {'modules': {'go': 'any'}, 'features': ['isolation']} + @pytest.fixture(autouse=True) + def setup_method_fixture(self, request, skip_alert): + skip_alert(r'\[unit\] close\(\d+\) failed: Bad file descriptor') + def unpriv_creds(self): nobody_uid = pwd.getpwnam('nobody').pw_uid @@ -227,7 +231,7 @@ class TestGoIsolation(TestApplicationGo): obj = self.getjson()['body'] - assert obj['PID'] == 1, 'pid of container is 1' + assert obj['PID'] == 2, 'pid of container is 2' def test_isolation_namespace_false(self): self.load('ns_inspect') diff --git a/test/test_go_isolation_rootfs.py b/test/test_go_isolation_rootfs.py index 2bded5ec..d246a48d 100644 --- a/test/test_go_isolation_rootfs.py +++ b/test/test_go_isolation_rootfs.py @@ -7,6 +7,10 @@ from unit.applications.lang.go import TestApplicationGo class TestGoIsolationRootfs(TestApplicationGo): prerequisites = {'modules': {'go': 'all'}} + @pytest.fixture(autouse=True) + def setup_method_fixture(self, request, skip_alert): + skip_alert(r'\[unit\] close\(\d+\) failed: Bad file descriptor') + def test_go_isolation_rootfs_chroot(self, is_su, temp_dir): if not is_su: pytest.skip('requires root') diff --git a/test/test_python_procman.py b/test/test_python_procman.py index 389d0747..a25b84ec 100644 --- a/test/test_python_procman.py +++ b/test/test_python_procman.py @@ -22,7 +22,9 @@ class TestPythonProcman(TestApplicationPython): output = subprocess.check_output(['ps', 'ax']) pids = set() - for m in re.findall('.*' + self.app_name, output.decode()): + for m in re.findall( + '.*unit: "' + self.app_name + '" application', output.decode() + ): pids.add(re.search(r'^\s*(\d+)', m).group(1)) return pids diff --git a/test/test_tls.py b/test/test_tls.py index a91a3760..d2d71141 100644 --- a/test/test_tls.py +++ b/test/test_tls.py @@ -591,7 +591,7 @@ basicConstraints = critical,CA:TRUE""" subprocess.call(['kill', '-9', app_id]) - skip_alert(r'process %s exited on signal 9' % app_id) + skip_alert(r'process .* %s.* exited on signal 9' % app_id) self.wait_for_record( re.compile( -- cgit From b424a00ec5746884f8ebb1d75b3f0fec0b3a05ff Mon Sep 17 00:00:00 2001 From: Max Romanov Date: Tue, 9 Nov 2021 15:48:44 +0300 Subject: Tests: PHP shared opcache test added. --- test/php/opcache/index.php | 18 ++++++++++++++++++ test/php/opcache/test.php | 1 + test/test_php_application.py | 17 +++++++++++++++++ test/unit/applications/lang/php.py | 27 ++++++++++++++++++--------- 4 files changed, 54 insertions(+), 9 deletions(-) create mode 100644 test/php/opcache/index.php create mode 100644 test/php/opcache/test.php (limited to 'test') diff --git a/test/php/opcache/index.php b/test/php/opcache/index.php new file mode 100644 index 00000000..de4002bb --- /dev/null +++ b/test/php/opcache/index.php @@ -0,0 +1,18 @@ + diff --git a/test/php/opcache/test.php b/test/php/opcache/test.php new file mode 100644 index 00000000..147cebcd --- /dev/null +++ b/test/php/opcache/test.php @@ -0,0 +1 @@ + diff --git a/test/test_php_application.py b/test/test_php_application.py index bb7d978c..d9c16a6d 100644 --- a/test/test_php_application.py +++ b/test/test_php_application.py @@ -713,3 +713,20 @@ class TestPHPApplication(TestApplicationPHP): ), 'relative path w/ chdir' assert self.get()['body'] == 'test', 'relative path 2' + + 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') + + pid = r['headers']['X-Pid'] + + assert cached == '0', 'not cached' + + r = self.get() + + assert r['headers']['X-Pid'] != pid, 'new instance' + assert r['headers']['X-Cached'] == '1', 'cached' diff --git a/test/unit/applications/lang/php.py b/test/unit/applications/lang/php.py index 90c0078c..5319d2ca 100644 --- a/test/unit/applications/lang/php.py +++ b/test/unit/applications/lang/php.py @@ -22,18 +22,27 @@ class TestApplicationPHP(TestApplicationProto): script_path = '/app/php/' + script + app = { + "type": self.get_application_type(), + "processes": kwargs.pop('processes', {"spare": 0}), + "root": script_path, + "working_directory": script_path, + "index": index, + } + + for attr in ( + 'environment', + 'limits', + 'options', + 'targets', + ): + if attr in kwargs: + app[attr] = kwargs.pop(attr) + self._load_conf( { "listeners": {"*:7080": {"pass": "applications/" + script}}, - "applications": { - script: { - "type": self.get_application_type(), - "processes": {"spare": 0}, - "root": script_path, - "working_directory": script_path, - "index": index, - } - }, + "applications": {script: app}, }, **kwargs ) -- cgit From 6961de1d64acf1780ee0d4b08b7c9614e481a338 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Wed, 10 Nov 2021 15:43:24 +0000 Subject: Tests: added more tests for "query" routing pattern. --- test/test_routing.py | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'test') diff --git a/test/test_routing.py b/test/test_routing.py index c031d768..167d2640 100644 --- a/test/test_routing.py +++ b/test/test_routing.py @@ -1342,19 +1342,27 @@ class TestRouting(TestApplicationProto): assert self.get(url='/?a=b&c=d e')['status'] == 200 def test_routes_match_query_array(self): - self.route_match({ - "query": ["foo", "bar"] - }) + self.route_match({"query": ["foo", "bar"]}) - assert self.get()['status'] == 404, 'arr' - assert self.get(url='/?foo')['status'] == 200, 'arr 1' - assert self.get(url='/?bar')['status'] == 200, 'arr 2' + assert self.get()['status'] == 404, 'no args' + assert self.get(url='/?foo')['status'] == 200, 'arg first' + assert self.get(url='/?bar')['status'] == 200, 'arg second' assert 'success' in self.conf_delete( 'routes/0/match/query/1' - ), 'match query array configure 2' + ), 'query array remove second' + + assert self.get(url='/?foo')['status'] == 200, 'still arg first' + assert self.get(url='/?bar')['status'] == 404, 'no arg second' + + self.route_match({"query": ["!f", "foo"]}) + + assert self.get(url='/?f')['status'] == 404, 'negative arg' + assert self.get(url='/?fo')['status'] == 404, 'negative arg 2' + assert self.get(url='/?foo')['status'] == 200, 'negative arg 3' - assert self.get(url='/?bar')['status'] == 404, 'arr 2' + self.route_match({"query": []}) + assert self.get()['status'] == 200, 'empty array' def test_routes_match_query_invalid(self): self.route_match_invalid({"query": [1]}) -- cgit From ae035852385032cc6c502c0e560fc682cacdbf34 Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Mon, 15 Nov 2021 12:13:54 +0000 Subject: Tests: refactored working with processes. --- test/test_java_isolation_rootfs.py | 14 +++++--------- test/test_static_mount.py | 16 +++++++--------- test/test_tls.py | 10 +++++----- test/test_tls_sni.py | 4 ++-- test/unit/applications/lang/go.py | 5 ++--- test/unit/applications/lang/java.py | 20 +++++++++++++------- test/unit/applications/tls.py | 2 +- test/unit/check/go.py | 7 ++++--- 8 files changed, 39 insertions(+), 39 deletions(-) (limited to 'test') diff --git a/test/test_java_isolation_rootfs.py b/test/test_java_isolation_rootfs.py index 91773981..eac86a0c 100644 --- a/test/test_java_isolation_rootfs.py +++ b/test/test_java_isolation_rootfs.py @@ -18,7 +18,7 @@ class TestJavaIsolationRootfs(TestApplicationJava): os.chmod(option.temp_dir + '/tmp', 0o777) try: - process = subprocess.Popen( + subprocess.run( [ "mount", "--bind", @@ -28,12 +28,10 @@ class TestJavaIsolationRootfs(TestApplicationJava): stderr=subprocess.STDOUT, ) - process.communicate() - except KeyboardInterrupt: raise - except: + except subprocess.CalledProcessError: pytest.fail('Can\'t run mount process.') def teardown_method(self, is_su): @@ -41,18 +39,16 @@ class TestJavaIsolationRootfs(TestApplicationJava): return try: - process = subprocess.Popen( + subprocess.run( ["umount", "--lazy", option.temp_dir + "/jars"], stderr=subprocess.STDOUT, ) - process.communicate() - except KeyboardInterrupt: raise - except: - pytest.fail('Can\'t run mount process.') + except subprocess.CalledProcessError: + pytest.fail('Can\'t run umount process.') def test_java_isolation_rootfs_chroot_war(self, is_su, temp_dir): if not is_su: diff --git a/test/test_static_mount.py b/test/test_static_mount.py index e34a8a07..82eda956 100644 --- a/test/test_static_mount.py +++ b/test/test_static_mount.py @@ -22,7 +22,7 @@ class TestStaticMount(TestApplicationProto): Path(temp_dir + '/assets/mount/index.html').write_text('mount') try: - process = subprocess.Popen( + subprocess.check_output( [ "mount", "--bind", @@ -32,35 +32,33 @@ class TestStaticMount(TestApplicationProto): stderr=subprocess.STDOUT, ) - process.communicate() - except KeyboardInterrupt: raise - except: + except subprocess.CalledProcessError: pytest.fail('Can\'t run mount process.') self._load_conf( { "listeners": {"*:7080": {"pass": "routes"}}, - "routes": [{"action": {"share": temp_dir + "/assets/dir$uri"}}], + "routes": [ + {"action": {"share": temp_dir + "/assets/dir$uri"}} + ], } ) yield try: - process = subprocess.Popen( + subprocess.check_output( ["umount", "--lazy", temp_dir + "/assets/dir/mount"], stderr=subprocess.STDOUT, ) - process.communicate() - except KeyboardInterrupt: raise - except: + except subprocess.CalledProcessError: pytest.fail('Can\'t run umount process.') def test_static_mount(self, temp_dir, skip_alert): diff --git a/test/test_tls.py b/test/test_tls.py index d2d71141..01336765 100644 --- a/test/test_tls.py +++ b/test/test_tls.py @@ -32,7 +32,7 @@ class TestTLS(TestApplicationTLS): def req(self, name='localhost', subject=None, x509=False): subj = subject if subject is not None else '/CN=' + name + '/' - subprocess.call( + subprocess.check_output( [ 'openssl', 'req', @@ -87,7 +87,7 @@ basicConstraints = critical,CA:TRUE""" f.write('') def ca(self, cert='root', out='localhost'): - subprocess.call( + subprocess.check_output( [ 'openssl', 'ca', @@ -220,7 +220,7 @@ basicConstraints = critical,CA:TRUE""" self.openssl_conf() - subprocess.call( + subprocess.check_output( [ 'openssl', 'ecparam', @@ -234,7 +234,7 @@ basicConstraints = critical,CA:TRUE""" stderr=subprocess.STDOUT, ) - subprocess.call( + subprocess.check_output( [ 'openssl', 'req', @@ -589,7 +589,7 @@ basicConstraints = critical,CA:TRUE""" app_id = self.findall(r'(\d+)#\d+ "mirror" application started')[0] - subprocess.call(['kill', '-9', app_id]) + subprocess.check_output(['kill', '-9', app_id]) skip_alert(r'process .* %s.* exited on signal 9' % app_id) diff --git a/test/test_tls_sni.py b/test/test_tls_sni.py index e3aee4e3..d5f205cf 100644 --- a/test/test_tls_sni.py +++ b/test/test_tls_sni.py @@ -74,7 +74,7 @@ basicConstraints = critical,CA:TRUE""" else '/' ) - subprocess.call( + subprocess.check_output( [ 'openssl', 'req', @@ -100,7 +100,7 @@ basicConstraints = critical,CA:TRUE""" else '/' ) - subprocess.call( + subprocess.check_output( [ 'openssl', 'ca', diff --git a/test/unit/applications/lang/go.py b/test/unit/applications/lang/go.py index 6be1667b..367059e6 100644 --- a/test/unit/applications/lang/go.py +++ b/test/unit/applications/lang/go.py @@ -40,13 +40,12 @@ class TestApplicationGo(TestApplicationProto): print("\n$ GOPATH=" + env['GOPATH'] + " " + " ".join(args)) try: - process = subprocess.Popen(args, env=env) - process.communicate() + process = subprocess.run(args, env=env) except KeyboardInterrupt: raise - except: + except subprocess.CalledProcessError: return None return process diff --git a/test/unit/applications/lang/java.py b/test/unit/applications/lang/java.py index 53b27b07..50998978 100644 --- a/test/unit/applications/lang/java.py +++ b/test/unit/applications/lang/java.py @@ -64,10 +64,17 @@ class TestApplicationJava(TestApplicationProto): javac = [ 'javac', - '-target', '8', '-source', '8', '-nowarn', - '-encoding', 'utf-8', - '-d', classes_path, - '-classpath', classpath + ':' + ws_jars[0], + '-target', + '8', + '-source', + '8', + '-nowarn', + '-encoding', + 'utf-8', + '-d', + classes_path, + '-classpath', + classpath + ':' + ws_jars[0], ] javac.extend(src) @@ -75,13 +82,12 @@ class TestApplicationJava(TestApplicationProto): print("\n$ " + " ".join(javac)) try: - process = subprocess.Popen(javac, stderr=subprocess.STDOUT) - process.communicate() + subprocess.check_output(javac, stderr=subprocess.STDOUT) except KeyboardInterrupt: raise - except: + except subprocess.CalledProcessError: pytest.fail('Can\'t run javac process.') def load(self, script, **kwargs): diff --git a/test/unit/applications/tls.py b/test/unit/applications/tls.py index 583b618f..c7254235 100644 --- a/test/unit/applications/tls.py +++ b/test/unit/applications/tls.py @@ -15,7 +15,7 @@ class TestApplicationTLS(TestApplicationProto): def certificate(self, name='default', load=True): self.openssl_conf() - subprocess.call( + subprocess.check_output( [ 'openssl', 'req', diff --git a/test/unit/check/go.py b/test/unit/check/go.py index 309091c0..cc17f0fe 100644 --- a/test/unit/check/go.py +++ b/test/unit/check/go.py @@ -11,7 +11,7 @@ def check_go(current_dir, temp_dir, test_dir): env['GO111MODULE'] = 'auto' try: - process = subprocess.Popen( + process = subprocess.run( [ 'go', 'build', @@ -20,8 +20,9 @@ def check_go(current_dir, temp_dir, test_dir): test_dir + '/go/empty/app.go', ], env=env, + stderr=subprocess.STDOUT, + stdout=subprocess.PIPE, ) - process.communicate() if process.returncode == 0: return True @@ -29,5 +30,5 @@ def check_go(current_dir, temp_dir, test_dir): except KeyboardInterrupt: raise - except: + except subprocess.CalledProcessError: return None -- cgit From bcff62d267b5294777a738b2cd1b35f943e20f2f Mon Sep 17 00:00:00 2001 From: Andrei Zeliankou Date: Mon, 15 Nov 2021 12:15:23 +0000 Subject: Tests: fixed session reuse tests. Since SSL_CTX_sess_set_cache_size() can't guarantee the size of the cache there is no need to test edge "cache_size" values. --- test/test_tls_session.py | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) (limited to 'test') diff --git a/test/test_tls_session.py b/test/test_tls_session.py index f173913b..58f11f2d 100644 --- a/test/test_tls_session.py +++ b/test/test_tls_session.py @@ -76,7 +76,7 @@ class TestTLSSession(TestApplicationTLS): client, _, _, reused = self.connect(ctx, sess) assert not reused, 'no cache' - assert 'success' in self.add_session(cache_size=1) + assert 'success' in self.add_session(cache_size=2) client, sess, ctx, reused = self.connect() assert not reused, 'new connection cache' @@ -87,30 +87,26 @@ class TestTLSSession(TestApplicationTLS): client, _, _, reused = self.connect(ctx, sess) assert reused, 'cache 2' - # check that at least one session of two is not reused + # check that at least one session of four is not reused - client, sess, ctx, reused = self.connect() - client2, sess2, ctx2, reused2 = self.connect() - assert True not in [reused, reused2], 'new connection cache small' + clients = [self.connect() for _ in range(4)] + assert True not in [c[-1] for c in clients], 'cache small all new' - client, _, _, reused = self.connect(ctx, sess) - client2, _, _, reused2 = self.connect(ctx2, sess2) - assert False in [reused, reused2], 'cache small' + clients_again = [self.connect(c[2], c[1]) for c in clients] + assert False in [c[-1] for c in clients_again], 'cache small no reuse' - # both sessions are reused + # all four sessions are reused - assert 'success' in self.add_session(cache_size=2) + assert 'success' in self.add_session(cache_size=8) - client, sess, ctx, reused = self.connect() - client2, sess2, ctx2, reused2 = self.connect() - assert True not in [reused, reused2], 'new connection cache big' + clients = [self.connect() for _ in range(4)] + assert True not in [c[-1] for c in clients], 'cache big all new' - client, _, _, reused = self.connect(ctx, sess) - client2, _, _, reused2 = self.connect(ctx2, sess2) - assert False not in [reused, reused2], 'cache big' + clients_again = [self.connect(c[2], c[1]) for c in clients] + assert False not in [c[-1] for c in clients_again], 'cache big reuse' def test_tls_session_timeout(self): - assert 'success' in self.add_session(cache_size=1, timeout=1) + assert 'success' in self.add_session(cache_size=5, timeout=1) client, sess, ctx, reused = self.connect() assert not reused, 'new connection' -- cgit