xref: /unit/test/test_php_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.php import TestApplicationPHP
9from unit.feature.isolation import TestFeatureIsolation
10
11
12class TestPHPIsolation(TestApplicationPHP):
13    prerequisites = {'modules': {'php': '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_php_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('phpinfo', isolation=isolation)
55
56        assert 'success' in self.conf(
57            '"/app/php/phpinfo"', 'applications/phpinfo/root'
58        )
59        assert 'success' in self.conf(
60            '"/app/php/phpinfo"', 'applications/phpinfo/working_directory'
61        )
62
63        assert self.get()['status'] == 200, 'empty rootfs'
64
65    def test_php_isolation_rootfs_extensions(self, is_su, temp_dir):
66        isolation_features = option.available['features']['isolation'].keys()
67
68        if not is_su:
69            if not 'unprivileged_userns_clone' in isolation_features:
70                pytest.skip('requires unprivileged userns or root')
71
72            if 'user' not in isolation_features:
73                pytest.skip('user namespace is not supported')
74
75            if 'mnt' not in isolation_features:
76                pytest.skip('mnt namespace is not supported')
77
78            if 'pid' not in isolation_features:
79                pytest.skip('pid namespace is not supported')
80
81        isolation = {'rootfs': temp_dir}
82
83        if not is_su:
84            isolation['namespaces'] = {
85                'mount': True,
86                'credential': True,
87                'pid': True
88            }
89
90        self.load('list-extensions', isolation=isolation)
91
92        assert 'success' in self.conf(
93            '"/app/php/list-extensions"', 'applications/list-extensions/root'
94        )
95
96        assert 'success' in self.conf(
97            {'file': '/php/list-extensions/php.ini'},
98            'applications/list-extensions/options',
99        )
100
101        assert 'success' in self.conf(
102            '"/app/php/list-extensions"',
103            'applications/list-extensions/working_directory',
104        )
105
106        extensions = self.getjson()['body']
107
108        assert 'json' in extensions, 'json in extensions list'
109        assert 'unit' in extensions, 'unit in extensions list'
110