xref: /unit/test/test_python_isolation.py (revision 1673:883f2f79c2f6)
1import shutil
2
3import pytest
4
5from conftest import option
6from conftest import unit_run
7from conftest import unit_stop
8from unit.applications.lang.python import TestApplicationPython
9from unit.feature.isolation import TestFeatureIsolation
10
11
12class TestPythonIsolation(TestApplicationPython):
13    prerequisites = {'modules': {'python': 'any'}, 'features': ['isolation']}
14
15    @classmethod
16    def setup_class(cls, complete_check=True):
17        check = super().setup_class(complete_check=False)
18
19        unit = unit_run()
20        option.temp_dir = unit['temp_dir']
21
22        TestFeatureIsolation().check(option.available, unit['temp_dir'])
23
24        assert unit_stop() is None
25        shutil.rmtree(unit['temp_dir'])
26
27        return check if not complete_check else check()
28
29    def test_python_isolation_rootfs(self, is_su, temp_dir):
30        isolation_features = option.available['features']['isolation'].keys()
31
32        if not is_su:
33            if not 'unprivileged_userns_clone' in isolation_features:
34                pytest.skip('requires unprivileged userns or root')
35
36            if 'user' not in isolation_features:
37                pytest.skip('user namespace is not supported')
38
39            if 'mnt' not in isolation_features:
40                pytest.skip('mnt namespace is not supported')
41
42            if 'pid' not in isolation_features:
43                pytest.skip('pid namespace is not supported')
44
45        isolation = {'rootfs': temp_dir}
46
47        if not is_su:
48            isolation['namespaces'] = {
49                'mount': True,
50                'credential': True,
51                'pid': True
52            }
53
54        self.load('ns_inspect', isolation=isolation)
55
56        assert (
57            self.getjson(url='/?path=' + temp_dir)['body']['FileExists']
58            == False
59        ), 'temp_dir does not exists in rootfs'
60
61        assert (
62            self.getjson(url='/?path=/proc/self')['body']['FileExists']
63            == True
64        ), 'no /proc/self'
65
66        assert (
67            self.getjson(url='/?path=/dev/pts')['body']['FileExists'] == False
68        ), 'no /dev/pts'
69
70        assert (
71            self.getjson(url='/?path=/sys/kernel')['body']['FileExists']
72            == False
73        ), 'no /sys/kernel'
74
75        ret = self.getjson(url='/?path=/app/python/ns_inspect')
76
77        assert (
78            ret['body']['FileExists'] == True
79        ), 'application exists in rootfs'
80
81    def test_python_isolation_rootfs_no_language_deps(self, is_su, temp_dir):
82        isolation_features = option.available['features']['isolation'].keys()
83
84        if not is_su:
85            if not 'unprivileged_userns_clone' in isolation_features:
86                pytest.skip('requires unprivileged userns or root')
87
88            if 'user' not in isolation_features:
89                pytest.skip('user namespace is not supported')
90
91            if 'mnt' not in isolation_features:
92                pytest.skip('mnt namespace is not supported')
93
94            if 'pid' not in isolation_features:
95                pytest.skip('pid namespace is not supported')
96
97        isolation = {
98            'rootfs': temp_dir,
99            'automount': {'language_deps': False}
100        }
101
102        if not is_su:
103            isolation['namespaces'] = {
104                'mount': True,
105                'credential': True,
106                'pid': True
107            }
108
109        self.load('empty', isolation=isolation)
110
111        assert (self.get()['status'] != 200), 'disabled language_deps'
112
113        isolation['automount']['language_deps'] = True
114
115        self.load('empty', isolation=isolation)
116
117        assert (self.get()['status'] == 200), 'enabled language_deps'
118