diff options
author | Andrei Zeliankou <zelenkov@nginx.com> | 2022-12-14 19:00:14 +0000 |
---|---|---|
committer | Andrei Zeliankou <zelenkov@nginx.com> | 2022-12-14 19:00:14 +0000 |
commit | 4b39cb1fc75b42e944e41a522dbdf3d539eff8db (patch) | |
tree | 84c1c3909675bd27e87a483c33d753da76ab5cb3 /test/test_python_isolation.py | |
parent | 24e3f171029da265ee8cc20fe1a8846a0b49cb43 (diff) | |
download | unit-4b39cb1fc75b42e944e41a522dbdf3d539eff8db.tar.gz unit-4b39cb1fc75b42e944e41a522dbdf3d539eff8db.tar.bz2 |
Tests: added tests for "path" option in isolation/cgroup.
Diffstat (limited to '')
-rw-r--r-- | test/test_python_isolation.py | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/test/test_python_isolation.py b/test/test_python_isolation.py index db398444..6d4ffaf3 100644 --- a/test/test_python_isolation.py +++ b/test/test_python_isolation.py @@ -1,3 +1,8 @@ +import os +import re +import subprocess +from pathlib import Path + import pytest from unit.applications.lang.python import TestApplicationPython from unit.option import option @@ -9,6 +14,23 @@ from unit.utils import waitforunmount class TestPythonIsolation(TestApplicationPython): prerequisites = {'modules': {'python': 'any'}, 'features': ['isolation']} + def get_cgroup(self, app_name): + output = subprocess.check_output( + ['ps', 'ax', '-o', 'pid', '-o', 'cmd'] + ).decode() + + pid = re.search( + r'(\d+)\s*unit: "' + app_name + '" application', output + ).group(1) + + cgroup = '/proc/' + pid + '/cgroup' + + if not os.path.isfile(cgroup): + pytest.skip('no cgroup at ' + cgroup) + + with open(cgroup, 'r') as f: + return f.read().rstrip() + def test_python_isolation_rootfs(self, is_su, temp_dir): isolation_features = option.available['features']['isolation'].keys() @@ -102,3 +124,104 @@ class TestPythonIsolation(TestApplicationPython): assert ( self.getjson(url='/?path=/proc/self')['body']['FileExists'] == True ), '/proc/self' + + def test_python_isolation_cgroup(self, is_su, temp_dir): + if not is_su: + pytest.skip('requires root') + + if not 'cgroup' in option.available['features']['isolation']: + pytest.skip('cgroup is not supported') + + def set_cgroup_path(path): + isolation = {'cgroup': {'path': path}} + self.load('empty', processes=1, isolation=isolation) + + set_cgroup_path('scope/python') + + cgroup_rel = Path(self.get_cgroup('empty')) + assert cgroup_rel.parts[-2:] == ('scope', 'python'), 'cgroup rel' + + set_cgroup_path('/scope2/python') + + cgroup_abs = Path(self.get_cgroup('empty')) + assert cgroup_abs.parts[-2:] == ('scope2', 'python'), 'cgroup abs' + + assert len(cgroup_rel.parts) >= len(cgroup_abs.parts) + + def test_python_isolation_cgroup_two(self, is_su, temp_dir): + if not is_su: + pytest.skip('requires root') + + if not 'cgroup' in option.available['features']['isolation']: + pytest.skip('cgroup is not supported') + + def set_two_cgroup_path(path, path2): + script_path = option.test_dir + '/python/empty' + + assert 'success' in self.conf( + { + "listeners": { + "*:7080": {"pass": "applications/one"}, + "*:7081": {"pass": "applications/two"}, + }, + "applications": { + "one": { + "type": "python", + "processes": 1, + "path": script_path, + "working_directory": script_path, + "module": "wsgi", + "isolation": { + 'cgroup': {'path': path}, + }, + }, + "two": { + "type": "python", + "processes": 1, + "path": script_path, + "working_directory": script_path, + "module": "wsgi", + "isolation": { + 'cgroup': {'path': path2}, + }, + }, + }, + } + ) + + set_two_cgroup_path('/scope/python', '/scope/python') + assert self.get_cgroup('one') == self.get_cgroup('two') + + set_two_cgroup_path('/scope/python', '/scope2/python') + assert self.get_cgroup('one') != self.get_cgroup('two') + + def test_python_isolation_cgroup_invalid(self, is_su): + if not is_su: + pytest.skip('requires root') + + if not 'cgroup' in option.available['features']['isolation']: + pytest.skip('cgroup is not supported') + + def check_invalid(path): + script_path = option.test_dir + '/python/empty' + assert 'error' in self.conf( + { + "listeners": {"*:7080": {"pass": "applications/empty"}}, + "applications": { + "empty": { + "type": "python", + "processes": {"spare": 0}, + "path": script_path, + "working_directory": script_path, + "module": "wsgi", + "isolation": { + 'cgroup': {'path': path}, + }, + } + }, + } + ) + + check_invalid('') + check_invalid('../scope') + check_invalid('scope/../python') |