diff options
author | Andrei Belov <defan@nginx.com> | 2020-11-19 21:19:57 +0300 |
---|---|---|
committer | Andrei Belov <defan@nginx.com> | 2020-11-19 21:19:57 +0300 |
commit | 7f9079a3cd4cdb6ac3fea53f10bd34fe8b82fe9c (patch) | |
tree | c79dc48a3260156f3f824ecd299e5a4934d749c5 /test/test_go_isolation.py | |
parent | 646d047e5d12515ceac02279b373601ce0752982 (diff) | |
parent | 806a9b2515c60b12a68cd97af04f7fa5cb4dffed (diff) | |
download | unit-1.21.0-1.tar.gz unit-1.21.0-1.tar.bz2 |
Merged with the default branch.1.21.0-1
Diffstat (limited to 'test/test_go_isolation.py')
-rw-r--r-- | test/test_go_isolation.py | 135 |
1 files changed, 98 insertions, 37 deletions
diff --git a/test/test_go_isolation.py b/test/test_go_isolation.py index 1e7243f6..8c4a6b9c 100644 --- a/test/test_go_isolation.py +++ b/test/test_go_isolation.py @@ -1,9 +1,13 @@ import grp import os import pwd +import shutil import pytest +from conftest import option +from conftest import unit_run +from conftest import unit_stop from unit.applications.lang.go import TestApplicationGo from unit.feature.isolation import TestFeatureIsolation @@ -14,11 +18,17 @@ class TestGoIsolation(TestApplicationGo): @classmethod def setup_class(cls, complete_check=True): - unit = super().setup_class(complete_check=False) + check = super().setup_class(complete_check=False) - TestFeatureIsolation().check(cls.available, unit.temp_dir) + unit = unit_run() + option.temp_dir = unit['temp_dir'] - return unit if not complete_check else unit.complete() + TestFeatureIsolation().check(option.available, unit['temp_dir']) + + assert unit_stop() is None + shutil.rmtree(unit['temp_dir']) + + return check if not complete_check else check() def unpriv_creds(self): nobody_uid = pwd.getpwnam('nobody').pw_uid @@ -26,21 +36,21 @@ class TestGoIsolation(TestApplicationGo): try: nogroup_gid = grp.getgrnam('nogroup').gr_gid nogroup = 'nogroup' - except: + except KeyError: nogroup_gid = grp.getgrnam('nobody').gr_gid nogroup = 'nobody' return (nobody_uid, nogroup_gid, nogroup) def isolation_key(self, key): - return key in self.available['features']['isolation'].keys() + return key in option.available['features']['isolation'].keys() def test_isolation_values(self): self.load('ns_inspect') obj = self.getjson()['body'] - for ns, ns_value in self.available['features']['isolation'].items(): + for ns, ns_value in option.available['features']['isolation'].items(): if ns.upper() in obj['NS']: assert obj['NS'][ns.upper()] == ns_value, '%s match' % ns @@ -198,7 +208,7 @@ class TestGoIsolation(TestApplicationGo): obj = self.getjson()['body'] # all but user and mnt - allns = list(self.available['features']['isolation'].keys()) + allns = list(option.available['features']['isolation'].keys()) allns.remove('user') allns.remove('mnt') @@ -206,7 +216,7 @@ class TestGoIsolation(TestApplicationGo): if ns.upper() in obj['NS']: assert ( obj['NS'][ns.upper()] - == self.available['features']['isolation'][ns] + == option.available['features']['isolation'][ns] ), ('%s match' % ns) assert obj['NS']['MNT'] != self.isolation.getns('mnt'), 'mnt set' @@ -216,13 +226,23 @@ class TestGoIsolation(TestApplicationGo): if not self.isolation_key('pid'): pytest.skip('pid namespace is not supported') - if not (is_su or self.isolation_key('unprivileged_userns_clone')): - pytest.skip('requires root or unprivileged_userns_clone') + if not is_su: + if not self.isolation_key('unprivileged_userns_clone'): + pytest.skip('unprivileged clone is not available') - self.load( - 'ns_inspect', - isolation={'namespaces': {'pid': True, 'credential': True}}, - ) + if not self.isolation_key('user'): + pytest.skip('user namespace is not supported') + + if not self.isolation_key('mnt'): + pytest.skip('mnt namespace is not supported') + + isolation = {'namespaces': {'pid': True}} + + if not is_su: + isolation['namespaces']['mount'] = True + isolation['namespaces']['credential'] = True + + self.load('ns_inspect', isolation=isolation) obj = self.getjson()['body'] @@ -230,7 +250,7 @@ class TestGoIsolation(TestApplicationGo): def test_isolation_namespace_false(self): self.load('ns_inspect') - allns = list(self.available['features']['isolation'].keys()) + allns = list(option.available['features']['isolation'].keys()) remove_list = ['unprivileged_userns_clone', 'ipc', 'cgroup'] allns = [ns for ns in allns if ns not in remove_list] @@ -256,20 +276,31 @@ class TestGoIsolation(TestApplicationGo): if ns.upper() in obj['NS']: assert ( obj['NS'][ns.upper()] - == self.available['features']['isolation'][ns] + == option.available['features']['isolation'][ns] ), ('%s match' % ns) - def test_go_isolation_rootfs_container(self): - if not self.isolation_key('unprivileged_userns_clone'): - pytest.skip('unprivileged clone is not available') + def test_go_isolation_rootfs_container(self, is_su, temp_dir): + if not is_su: + if not self.isolation_key('unprivileged_userns_clone'): + pytest.skip('unprivileged clone is not available') - if not self.isolation_key('mnt'): - pytest.skip('mnt namespace is not supported') + if not self.isolation_key('user'): + pytest.skip('user namespace is not supported') - isolation = { - 'namespaces': {'mount': True, 'credential': True}, - 'rootfs': self.temp_dir, - } + if not self.isolation_key('mnt'): + pytest.skip('mnt namespace is not supported') + + if not self.isolation_key('pid'): + pytest.skip('pid namespace is not supported') + + isolation = {'rootfs': temp_dir} + + if not is_su: + isolation['namespaces'] = { + 'mount': True, + 'credential': True, + 'pid': True + } self.load('ns_inspect', isolation=isolation) @@ -280,7 +311,7 @@ class TestGoIsolation(TestApplicationGo): obj = self.getjson(url='/?file=/bin/sh')['body'] assert obj['FileExists'] == False, 'file should not exists' - def test_go_isolation_rootfs_container_priv(self, is_su): + def test_go_isolation_rootfs_container_priv(self, is_su, temp_dir): if not is_su: pytest.skip('requires root') @@ -289,7 +320,7 @@ class TestGoIsolation(TestApplicationGo): isolation = { 'namespaces': {'mount': True}, - 'rootfs': self.temp_dir, + 'rootfs': temp_dir, } self.load('ns_inspect', isolation=isolation) @@ -301,20 +332,50 @@ class TestGoIsolation(TestApplicationGo): obj = self.getjson(url='/?file=/bin/sh')['body'] assert obj['FileExists'] == False, 'file should not exists' - def test_go_isolation_rootfs_default_tmpfs(self): - if not self.isolation_key('unprivileged_userns_clone'): - pytest.skip('unprivileged clone is not available') + def test_go_isolation_rootfs_automount_tmpfs(self, is_su, temp_dir): + try: + open("/proc/self/mountinfo") + except: + pytest.skip('The system lacks /proc/self/mountinfo file') - if not self.isolation_key('mnt'): - pytest.skip('mnt namespace is not supported') + if not is_su: + if not self.isolation_key('unprivileged_userns_clone'): + pytest.skip('unprivileged clone is not available') - isolation = { - 'namespaces': {'mount': True, 'credential': True}, - 'rootfs': self.temp_dir, + if not self.isolation_key('user'): + pytest.skip('user namespace is not supported') + + if not self.isolation_key('mnt'): + pytest.skip('mnt namespace is not supported') + + if not self.isolation_key('pid'): + pytest.skip('pid namespace is not supported') + + isolation = {'rootfs': temp_dir} + + if not is_su: + isolation['namespaces'] = { + 'mount': True, + 'credential': True, + 'pid': True + } + + self.load('ns_inspect', isolation=isolation) + + obj = self.getjson(url='/?mounts=true')['body'] + + assert ( + "/ /tmp" in obj['Mounts'] and "tmpfs" in obj['Mounts'] + ), 'app has /tmp mounted on /' + + isolation['automount'] = { + 'tmpfs': False } self.load('ns_inspect', isolation=isolation) - obj = self.getjson(url='/?file=/tmp')['body'] + obj = self.getjson(url='/?mounts=true')['body'] - assert obj['FileExists'] == True, 'app has /tmp' + assert ( + "/ /tmp" not in obj['Mounts'] and "tmpfs" not in obj['Mounts'] + ), 'app has no /tmp mounted' |