ceph-devstack 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ceph_devstack/Dockerfile.selinux +20 -0
- ceph_devstack/__init__.py +187 -0
- ceph_devstack/ceph_devstack.pp +0 -0
- ceph_devstack/ceph_devstack.te +127 -0
- ceph_devstack/cli.py +64 -0
- ceph_devstack/config.toml +24 -0
- ceph_devstack/exec.py +93 -0
- ceph_devstack/host.py +154 -0
- ceph_devstack/logging.conf +30 -0
- ceph_devstack/py.typed +0 -0
- ceph_devstack/requirements.py +277 -0
- ceph_devstack/resources/__init__.py +115 -0
- ceph_devstack/resources/ceph/__init__.py +266 -0
- ceph_devstack/resources/ceph/containers.py +419 -0
- ceph_devstack/resources/ceph/exceptions.py +3 -0
- ceph_devstack/resources/ceph/requirements.py +90 -0
- ceph_devstack/resources/ceph/utils.py +45 -0
- ceph_devstack/resources/container.py +171 -0
- ceph_devstack/resources/misc.py +15 -0
- ceph_devstack-0.1.0.dist-info/METADATA +222 -0
- ceph_devstack-0.1.0.dist-info/RECORD +44 -0
- ceph_devstack-0.1.0.dist-info/WHEEL +5 -0
- ceph_devstack-0.1.0.dist-info/entry_points.txt +2 -0
- ceph_devstack-0.1.0.dist-info/licenses/LICENSE +21 -0
- ceph_devstack-0.1.0.dist-info/top_level.txt +2 -0
- tests/__init__.py +0 -0
- tests/conftest.py +9 -0
- tests/resources/__init__.py +0 -0
- tests/resources/ceph/__init__.py +0 -0
- tests/resources/ceph/fixtures/__init__.py +0 -0
- tests/resources/ceph/fixtures/testnode-config.toml +2 -0
- tests/resources/ceph/test_cephdevstack_core.py +459 -0
- tests/resources/ceph/test_devstack.py +182 -0
- tests/resources/ceph/test_env_vars.py +110 -0
- tests/resources/ceph/test_requirements_ceph.py +262 -0
- tests/resources/ceph/test_ssh_keypair.py +109 -0
- tests/resources/ceph/test_testnode.py +36 -0
- tests/resources/test_container.py +247 -0
- tests/resources/test_misc.py +46 -0
- tests/resources/test_podmanresource.py +59 -0
- tests/test_config.py +120 -0
- tests/test_deep_merge.py +71 -0
- tests/test_parse_args.py +228 -0
- tests/test_requirements_core.py +495 -0
|
@@ -0,0 +1,495 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import pytest
|
|
3
|
+
from packaging.version import parse as parse_version
|
|
4
|
+
from unittest.mock import AsyncMock, patch
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
from ceph_devstack import config, requirements
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@pytest.fixture(scope="class")
|
|
11
|
+
def cls():
|
|
12
|
+
return requirements.Requirement
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@pytest.fixture(scope="class")
|
|
16
|
+
def req(cls):
|
|
17
|
+
return cls()
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class TestRequirement:
|
|
21
|
+
@pytest.fixture(scope="class")
|
|
22
|
+
def cls(self):
|
|
23
|
+
class TestReq(requirements.Requirement):
|
|
24
|
+
check_cmd = ["test", "command"]
|
|
25
|
+
|
|
26
|
+
return TestReq
|
|
27
|
+
|
|
28
|
+
async def test_check_returns_true_on_zero_rc(self, req):
|
|
29
|
+
mock_proc = AsyncMock()
|
|
30
|
+
mock_proc.wait = AsyncMock(return_value=0)
|
|
31
|
+
with patch.object(req.host, "arun", return_value=mock_proc):
|
|
32
|
+
result = await req.check()
|
|
33
|
+
assert result is True
|
|
34
|
+
|
|
35
|
+
async def test_check_returns_false_on_nonzero_rc(self, req):
|
|
36
|
+
mock_proc = AsyncMock()
|
|
37
|
+
mock_proc.wait = AsyncMock(return_value=1)
|
|
38
|
+
with patch.object(req.host, "arun", return_value=mock_proc):
|
|
39
|
+
result = await req.check()
|
|
40
|
+
assert result is False
|
|
41
|
+
|
|
42
|
+
async def test_evaluate_delegates_to_check(self, req):
|
|
43
|
+
with patch.object(req, "check", return_value=True) as mock_check:
|
|
44
|
+
result = await req.evaluate()
|
|
45
|
+
mock_check.assert_called_once()
|
|
46
|
+
assert result is True
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class TestFixableRequirement:
|
|
50
|
+
@pytest.fixture(scope="class")
|
|
51
|
+
def cls(self):
|
|
52
|
+
class TestReq(requirements.FixableRequirement):
|
|
53
|
+
check_cmd = ["test", "-f", "/tmp/testfile"]
|
|
54
|
+
fix_cmd = ["touch", "/tmp/testfile"]
|
|
55
|
+
suggest_msg = "Test file missing"
|
|
56
|
+
|
|
57
|
+
return TestReq
|
|
58
|
+
|
|
59
|
+
async def test_evaluate_returns_true_when_check_passes(self, req):
|
|
60
|
+
with patch.object(req, "check", return_value=True):
|
|
61
|
+
result = await req.evaluate()
|
|
62
|
+
assert result is True
|
|
63
|
+
|
|
64
|
+
async def test_evaluate_returns_false_when_check_fails(self, req):
|
|
65
|
+
config.setdefault("args", {})
|
|
66
|
+
config["args"]["fix"] = False
|
|
67
|
+
with (
|
|
68
|
+
patch.object(req, "check", return_value=False),
|
|
69
|
+
patch.object(req, "suggest") as mock_suggest,
|
|
70
|
+
):
|
|
71
|
+
result = await req.evaluate()
|
|
72
|
+
assert result is False
|
|
73
|
+
mock_suggest.assert_called_once()
|
|
74
|
+
|
|
75
|
+
async def test_evaluate_calls_fix_when_fix_flag_set(self, req):
|
|
76
|
+
config.setdefault("args", {})
|
|
77
|
+
config["args"]["fix"] = True
|
|
78
|
+
with (
|
|
79
|
+
patch.object(req, "check", return_value=False),
|
|
80
|
+
patch.object(req, "fix", return_value=True) as mock_fix,
|
|
81
|
+
):
|
|
82
|
+
result = await req.evaluate()
|
|
83
|
+
assert result is True
|
|
84
|
+
mock_fix.assert_called_once()
|
|
85
|
+
|
|
86
|
+
async def test_evaluate_returns_false_when_fix_fails(self, req):
|
|
87
|
+
config.setdefault("args", {})
|
|
88
|
+
config["args"]["fix"] = True
|
|
89
|
+
with (
|
|
90
|
+
patch.object(req, "check", return_value=False),
|
|
91
|
+
patch.object(req, "fix", return_value=False) as mock_fix,
|
|
92
|
+
):
|
|
93
|
+
result = await req.evaluate()
|
|
94
|
+
assert result is False
|
|
95
|
+
mock_fix.assert_called_once()
|
|
96
|
+
|
|
97
|
+
async def test_fix_requires_fix_cmd(self, req):
|
|
98
|
+
req.fix_cmd = []
|
|
99
|
+
with pytest.raises(AssertionError):
|
|
100
|
+
await req.fix()
|
|
101
|
+
asyncio.run(req.fix())
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class TestLocalRequirement:
|
|
105
|
+
@pytest.fixture(scope="class")
|
|
106
|
+
def cls(self):
|
|
107
|
+
class TestReq(requirements.LocalRequirement):
|
|
108
|
+
check_cmd = ["test"]
|
|
109
|
+
|
|
110
|
+
return TestReq
|
|
111
|
+
|
|
112
|
+
def test_local_requirement_uses_local_host(self, req):
|
|
113
|
+
assert req.host == requirements.local_host
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
class TestPodmanVersionInit:
|
|
117
|
+
@pytest.fixture(scope="class")
|
|
118
|
+
def cls(self):
|
|
119
|
+
return requirements.PodmanVersion
|
|
120
|
+
|
|
121
|
+
@pytest.fixture(scope="class")
|
|
122
|
+
def req(self, cls):
|
|
123
|
+
return cls("4.0.0")
|
|
124
|
+
|
|
125
|
+
def test_podman_version_init_sets_version(self, req):
|
|
126
|
+
assert req.required_version == parse_version("4.0.0")
|
|
127
|
+
|
|
128
|
+
def test_podman_version_init_sets_msg(self, cls):
|
|
129
|
+
req = cls("4.0.0", "Custom message")
|
|
130
|
+
assert req.msg == "Custom message"
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
class TestSysctlValueInit:
|
|
134
|
+
@pytest.fixture(scope="class")
|
|
135
|
+
def cls(self):
|
|
136
|
+
return requirements.SysctlValue
|
|
137
|
+
|
|
138
|
+
@pytest.fixture(scope="class")
|
|
139
|
+
def req(self, cls):
|
|
140
|
+
return cls("fs.aio-max-nr", 2097152)
|
|
141
|
+
|
|
142
|
+
def test_sysctl_value_init_sets_key(self, req):
|
|
143
|
+
assert req.key == "fs.aio-max-nr"
|
|
144
|
+
|
|
145
|
+
def test_sysctl_value_init_sets_min_value(self, req):
|
|
146
|
+
assert req.min_value == 2097152
|
|
147
|
+
|
|
148
|
+
def test_sysctl_value_init_fix_cmd(self, req):
|
|
149
|
+
assert req.fix_cmd == ["sudo", "sysctl", "fs.aio-max-nr=2097152"]
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
class TestSELinuxBooleanInit:
|
|
153
|
+
@pytest.fixture(scope="class")
|
|
154
|
+
def cls(self):
|
|
155
|
+
return requirements.SELinuxBoolean
|
|
156
|
+
|
|
157
|
+
@pytest.fixture(scope="class")
|
|
158
|
+
def req(self, cls):
|
|
159
|
+
return cls("test_bool")
|
|
160
|
+
|
|
161
|
+
def test_selinux_boolean_init_sets_boolean_name(self, req):
|
|
162
|
+
assert req.boolean_name == "test_bool"
|
|
163
|
+
|
|
164
|
+
def test_selinux_boolean_init_fix_cmd(self, req):
|
|
165
|
+
assert req.fix_cmd == ["sudo", "setsebool", "-P", "test_bool=true"]
|
|
166
|
+
|
|
167
|
+
def test_selinux_boolean_init_suggest_msg(self, req):
|
|
168
|
+
assert "test_bool" in req.suggest_msg
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
class TestFuseOverlayfsPresence:
|
|
172
|
+
@pytest.fixture(scope="class")
|
|
173
|
+
def cls(self):
|
|
174
|
+
return requirements.FuseOverlayfsPresence
|
|
175
|
+
|
|
176
|
+
def test_fuse_overlayfs_presence_check_cmd(self, req):
|
|
177
|
+
assert req.check_cmd == ["command", "-v", "fuse-overlayfs"]
|
|
178
|
+
|
|
179
|
+
def test_fuse_overlayfs_presence_fix_cmd(self, req):
|
|
180
|
+
assert req.fix_cmd == ["sudo", "dnf", "install", "-y", "fuse-overlayfs"]
|
|
181
|
+
|
|
182
|
+
def test_fuse_overlayfs_presence_suggest_msg(self, req):
|
|
183
|
+
assert req.suggest_msg == "Could not find fuse-overlayfs"
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
class TestCgroupV2Properties:
|
|
187
|
+
@pytest.fixture(scope="class")
|
|
188
|
+
def cls(self):
|
|
189
|
+
return requirements.CgroupV2
|
|
190
|
+
|
|
191
|
+
def test_cgroup_v2_suggest_msg(self, req):
|
|
192
|
+
assert req.suggest_msg == "cgroup v2 is not enabled"
|
|
193
|
+
|
|
194
|
+
def test_cgroup_v2_fix_cmd(self, req):
|
|
195
|
+
assert req.fix_cmd == [
|
|
196
|
+
"sudo",
|
|
197
|
+
"grubby",
|
|
198
|
+
"--update-kernel=ALL",
|
|
199
|
+
"--args='systemd.unified_cgroup_hierarchy=1'",
|
|
200
|
+
]
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
class TestCgroupV2Check:
|
|
204
|
+
@pytest.fixture(scope="class")
|
|
205
|
+
def cls(self):
|
|
206
|
+
return requirements.CgroupV2
|
|
207
|
+
|
|
208
|
+
async def test_cgroup_v2_check_true(self, req):
|
|
209
|
+
mock_info = {"host": {"cgroupVersion": "v2"}}
|
|
210
|
+
with patch.object(req.host, "podman_info", return_value=mock_info):
|
|
211
|
+
result = await req.check()
|
|
212
|
+
assert result is True
|
|
213
|
+
|
|
214
|
+
async def test_cgroup_v2_check_false(self, req):
|
|
215
|
+
mock_info = {"host": {"cgroupVersion": "v1"}}
|
|
216
|
+
with patch.object(req.host, "podman_info", return_value=mock_info):
|
|
217
|
+
result = await req.check()
|
|
218
|
+
assert result is False
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
class TestPodmanDNSPluginInit:
|
|
222
|
+
@pytest.fixture(scope="class")
|
|
223
|
+
def cls(self):
|
|
224
|
+
return requirements.PodmanDNSPlugin
|
|
225
|
+
|
|
226
|
+
@pytest.fixture(scope="class", params=["centos", "ubuntu", "debian"])
|
|
227
|
+
def os_type(self, request):
|
|
228
|
+
return request.param
|
|
229
|
+
|
|
230
|
+
@pytest.fixture(scope="class")
|
|
231
|
+
def dns_plugin_path(self, os_type):
|
|
232
|
+
if os_type == "centos":
|
|
233
|
+
return "/usr/libexec/cni/dnsname"
|
|
234
|
+
elif os_type in ["ubuntu", "debian"]:
|
|
235
|
+
return "/usr/lib/cni/dnsname"
|
|
236
|
+
|
|
237
|
+
def test_podman_dns_plugin_config(self, cls, os_type, dns_plugin_path):
|
|
238
|
+
with patch.object(cls.host, "os_type", return_value=os_type):
|
|
239
|
+
req = cls()
|
|
240
|
+
assert req.check_cmd == ["test", "-x", dns_plugin_path]
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
class TestAppArmorProfile:
|
|
244
|
+
@pytest.fixture(scope="class")
|
|
245
|
+
def cls(self):
|
|
246
|
+
return requirements.AppArmorProfile
|
|
247
|
+
|
|
248
|
+
def test_apparmor_profile_check_cmd(self, req):
|
|
249
|
+
assert req.check_cmd == ["test", "-f", "/etc/apparmor.d/local/unix-chkpwd"]
|
|
250
|
+
|
|
251
|
+
def test_apparmor_profile_fix_cmd(self, req):
|
|
252
|
+
assert req.fix_cmd[-1].endswith("&& systemctl reload apparmor")
|
|
253
|
+
|
|
254
|
+
def test_apparmor_profile_suggest_msg(self, req):
|
|
255
|
+
assert req.suggest_msg == "Did not find required apparmor profile"
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
class TestFixableRequirementSuggestMsg:
|
|
259
|
+
@pytest.fixture(scope="class")
|
|
260
|
+
def cls(self):
|
|
261
|
+
class TestReq(requirements.FixableRequirement):
|
|
262
|
+
check_cmd = ["test"]
|
|
263
|
+
fix_cmd = ["fix"]
|
|
264
|
+
suggest_msg = "Please fix this"
|
|
265
|
+
|
|
266
|
+
return TestReq
|
|
267
|
+
|
|
268
|
+
def test_fixable_requirement_has_suggest_msg(self, req):
|
|
269
|
+
assert req.suggest_msg == "Please fix this"
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
class TestCheckRequirements:
|
|
273
|
+
async def test_check_requirements_returns_false_when_podman_not_platform(self):
|
|
274
|
+
with patch("ceph_devstack.requirements.PodmanPlatform") as MockPlatform:
|
|
275
|
+
mock_platform = AsyncMock()
|
|
276
|
+
mock_platform.evaluate = AsyncMock(return_value=False)
|
|
277
|
+
MockPlatform.return_value = mock_platform
|
|
278
|
+
result = await requirements.check_requirements()
|
|
279
|
+
assert result is False
|
|
280
|
+
mock_platform.evaluate.assert_called_once()
|
|
281
|
+
|
|
282
|
+
async def test_check_requirements_returns_false_on_overlay_failure(self):
|
|
283
|
+
with (
|
|
284
|
+
patch("ceph_devstack.requirements.PodmanPlatform") as MockPlatform,
|
|
285
|
+
patch("ceph_devstack.requirements.PodmanGraphDriver") as MockGraph,
|
|
286
|
+
):
|
|
287
|
+
mock_platform = AsyncMock()
|
|
288
|
+
mock_platform.evaluate = AsyncMock(return_value=True)
|
|
289
|
+
MockPlatform.return_value = mock_platform
|
|
290
|
+
|
|
291
|
+
mock_graph = AsyncMock()
|
|
292
|
+
mock_graph.evaluate = AsyncMock(return_value=False)
|
|
293
|
+
MockGraph.return_value = mock_graph
|
|
294
|
+
|
|
295
|
+
result = await requirements.check_requirements()
|
|
296
|
+
assert result is False
|
|
297
|
+
|
|
298
|
+
async def test_check_requirements_returns_true_when_all_pass(self):
|
|
299
|
+
with (
|
|
300
|
+
patch("ceph_devstack.requirements.PodmanPlatform") as MockPlatform,
|
|
301
|
+
patch("ceph_devstack.requirements.PodmanGraphDriver") as MockGraph,
|
|
302
|
+
patch("ceph_devstack.requirements.PodmanVersion") as MockVersion,
|
|
303
|
+
patch("ceph_devstack.requirements.KernelVersionForOverlay") as MockKernel,
|
|
304
|
+
patch("ceph_devstack.requirements.CgroupV2") as MockCgroup,
|
|
305
|
+
patch(
|
|
306
|
+
"ceph_devstack.requirements.KernelVersionForCgroupV2"
|
|
307
|
+
) as MockKernelCgroup,
|
|
308
|
+
patch("ceph_devstack.requirements.PodmanRuntime") as MockRuntime,
|
|
309
|
+
patch("ceph_devstack.requirements.host.selinux_enforcing") as mock_selinux,
|
|
310
|
+
patch("ceph_devstack.requirements.SysctlValue") as MockSysctl,
|
|
311
|
+
):
|
|
312
|
+
mock_platform = AsyncMock()
|
|
313
|
+
mock_platform.evaluate = AsyncMock(return_value=True)
|
|
314
|
+
MockPlatform.return_value = mock_platform
|
|
315
|
+
|
|
316
|
+
mock_graph = AsyncMock()
|
|
317
|
+
mock_graph.evaluate = AsyncMock(return_value=True)
|
|
318
|
+
MockGraph.return_value = mock_graph
|
|
319
|
+
|
|
320
|
+
mock_version = AsyncMock()
|
|
321
|
+
mock_version.evaluate = AsyncMock(return_value=True)
|
|
322
|
+
MockVersion.return_value = mock_version
|
|
323
|
+
|
|
324
|
+
mock_kernel = AsyncMock()
|
|
325
|
+
mock_kernel.evaluate = AsyncMock(return_value=True)
|
|
326
|
+
MockKernel.return_value = mock_kernel
|
|
327
|
+
|
|
328
|
+
mock_cgroup = AsyncMock()
|
|
329
|
+
mock_cgroup.evaluate = AsyncMock(return_value=True)
|
|
330
|
+
MockCgroup.return_value = mock_cgroup
|
|
331
|
+
|
|
332
|
+
mock_kernel_cgroup = AsyncMock()
|
|
333
|
+
mock_kernel_cgroup.evaluate = AsyncMock(return_value=True)
|
|
334
|
+
MockKernelCgroup.return_value = mock_kernel_cgroup
|
|
335
|
+
|
|
336
|
+
mock_runtime = AsyncMock()
|
|
337
|
+
mock_runtime.evaluate = AsyncMock(return_value=True)
|
|
338
|
+
MockRuntime.return_value = mock_runtime
|
|
339
|
+
|
|
340
|
+
mock_selinux.return_value = False
|
|
341
|
+
|
|
342
|
+
mock_sysctl = AsyncMock()
|
|
343
|
+
mock_sysctl.evaluate = AsyncMock(return_value=True)
|
|
344
|
+
MockSysctl.return_value = mock_sysctl
|
|
345
|
+
|
|
346
|
+
result = await requirements.check_requirements()
|
|
347
|
+
assert result is True
|
|
348
|
+
|
|
349
|
+
async def test_check_requirements_returns_false_on_runtime_failure(self):
|
|
350
|
+
with (
|
|
351
|
+
patch("ceph_devstack.requirements.PodmanPlatform") as MockPlatform,
|
|
352
|
+
patch("ceph_devstack.requirements.PodmanGraphDriver") as MockGraph,
|
|
353
|
+
patch("ceph_devstack.requirements.PodmanVersion") as MockVersion,
|
|
354
|
+
patch("ceph_devstack.requirements.KernelVersionForOverlay") as MockKernel,
|
|
355
|
+
patch("ceph_devstack.requirements.CgroupV2") as MockCgroup,
|
|
356
|
+
patch(
|
|
357
|
+
"ceph_devstack.requirements.KernelVersionForCgroupV2"
|
|
358
|
+
) as MockKernelCgroup,
|
|
359
|
+
patch("ceph_devstack.requirements.PodmanRuntime") as MockRuntime,
|
|
360
|
+
patch("ceph_devstack.requirements.host.selinux_enforcing") as mock_selinux,
|
|
361
|
+
):
|
|
362
|
+
mock_platform = AsyncMock()
|
|
363
|
+
mock_platform.evaluate = AsyncMock(return_value=True)
|
|
364
|
+
MockPlatform.return_value = mock_platform
|
|
365
|
+
|
|
366
|
+
mock_graph = AsyncMock()
|
|
367
|
+
mock_graph.evaluate = AsyncMock(return_value=True)
|
|
368
|
+
MockGraph.return_value = mock_graph
|
|
369
|
+
|
|
370
|
+
mock_version = AsyncMock()
|
|
371
|
+
mock_version.evaluate = AsyncMock(return_value=True)
|
|
372
|
+
MockVersion.return_value = mock_version
|
|
373
|
+
|
|
374
|
+
mock_kernel = AsyncMock()
|
|
375
|
+
mock_kernel.evaluate = AsyncMock(return_value=True)
|
|
376
|
+
MockKernel.return_value = mock_kernel
|
|
377
|
+
|
|
378
|
+
mock_cgroup = AsyncMock()
|
|
379
|
+
mock_cgroup.evaluate = AsyncMock(return_value=True)
|
|
380
|
+
MockCgroup.return_value = mock_cgroup
|
|
381
|
+
|
|
382
|
+
mock_kernel_cgroup = AsyncMock()
|
|
383
|
+
mock_kernel_cgroup.evaluate = AsyncMock(return_value=True)
|
|
384
|
+
MockKernelCgroup.return_value = mock_kernel_cgroup
|
|
385
|
+
|
|
386
|
+
mock_runtime = AsyncMock()
|
|
387
|
+
mock_runtime.evaluate = AsyncMock(return_value=False)
|
|
388
|
+
MockRuntime.return_value = mock_runtime
|
|
389
|
+
|
|
390
|
+
mock_selinux.return_value = False
|
|
391
|
+
|
|
392
|
+
result = await requirements.check_requirements()
|
|
393
|
+
assert result is False
|
|
394
|
+
|
|
395
|
+
async def test_check_requirements_returns_false_on_selinux_bool_failure(self):
|
|
396
|
+
with (
|
|
397
|
+
patch("ceph_devstack.requirements.PodmanPlatform") as MockPlatform,
|
|
398
|
+
patch("ceph_devstack.requirements.PodmanGraphDriver") as MockGraph,
|
|
399
|
+
patch("ceph_devstack.requirements.KernelVersionForOverlay") as MockKernel,
|
|
400
|
+
patch("ceph_devstack.requirements.CgroupV2") as MockCgroup,
|
|
401
|
+
patch(
|
|
402
|
+
"ceph_devstack.requirements.KernelVersionForCgroupV2"
|
|
403
|
+
) as MockKernelCgroup,
|
|
404
|
+
patch("ceph_devstack.requirements.PodmanRuntime") as MockRuntime,
|
|
405
|
+
patch("ceph_devstack.requirements.host.selinux_enforcing") as mock_selinux,
|
|
406
|
+
patch("ceph_devstack.requirements.SELinuxBoolean") as MockSELinuxBoolean,
|
|
407
|
+
):
|
|
408
|
+
mock_platform = AsyncMock()
|
|
409
|
+
mock_platform.evaluate = AsyncMock(return_value=True)
|
|
410
|
+
MockPlatform.return_value = mock_platform
|
|
411
|
+
|
|
412
|
+
mock_graph = AsyncMock()
|
|
413
|
+
mock_graph.evaluate = AsyncMock(return_value=True)
|
|
414
|
+
MockGraph.return_value = mock_graph
|
|
415
|
+
|
|
416
|
+
with patch("ceph_devstack.requirements.PodmanVersion") as MockVersion:
|
|
417
|
+
mock_version = AsyncMock()
|
|
418
|
+
mock_version.evaluate = AsyncMock(return_value=True)
|
|
419
|
+
MockVersion.return_value = mock_version
|
|
420
|
+
|
|
421
|
+
mock_kernel = AsyncMock()
|
|
422
|
+
mock_kernel.evaluate = AsyncMock(return_value=True)
|
|
423
|
+
MockKernel.return_value = mock_kernel
|
|
424
|
+
|
|
425
|
+
mock_cgroup = AsyncMock()
|
|
426
|
+
mock_cgroup.evaluate = AsyncMock(return_value=True)
|
|
427
|
+
MockCgroup.return_value = mock_cgroup
|
|
428
|
+
|
|
429
|
+
mock_kernel_cgroup = AsyncMock()
|
|
430
|
+
mock_kernel_cgroup.evaluate = AsyncMock(return_value=True)
|
|
431
|
+
MockKernelCgroup.return_value = mock_kernel_cgroup
|
|
432
|
+
|
|
433
|
+
mock_runtime = AsyncMock()
|
|
434
|
+
mock_runtime.evaluate = AsyncMock(return_value=True)
|
|
435
|
+
MockRuntime.return_value = mock_runtime
|
|
436
|
+
|
|
437
|
+
mock_selinux.return_value = True
|
|
438
|
+
|
|
439
|
+
mock_sel = AsyncMock()
|
|
440
|
+
mock_sel.evaluate = AsyncMock(return_value=False)
|
|
441
|
+
MockSELinuxBoolean.return_value = mock_sel
|
|
442
|
+
|
|
443
|
+
result = await requirements.check_requirements()
|
|
444
|
+
assert result is False
|
|
445
|
+
|
|
446
|
+
async def test_check_requirements_returns_false_on_sysctl_failure(self):
|
|
447
|
+
with (
|
|
448
|
+
patch("ceph_devstack.requirements.PodmanPlatform") as MockPlatform,
|
|
449
|
+
patch("ceph_devstack.requirements.PodmanGraphDriver") as MockGraph,
|
|
450
|
+
patch("ceph_devstack.requirements.PodmanVersion") as MockVersion,
|
|
451
|
+
patch("ceph_devstack.requirements.KernelVersionForOverlay") as MockKernel,
|
|
452
|
+
patch("ceph_devstack.requirements.CgroupV2") as MockCgroup,
|
|
453
|
+
patch(
|
|
454
|
+
"ceph_devstack.requirements.KernelVersionForCgroupV2"
|
|
455
|
+
) as MockKernelCgroup,
|
|
456
|
+
patch("ceph_devstack.requirements.PodmanRuntime") as MockRuntime,
|
|
457
|
+
patch("ceph_devstack.requirements.host.selinux_enforcing") as mock_selinux,
|
|
458
|
+
patch("ceph_devstack.requirements.SysctlValue") as MockSysctl,
|
|
459
|
+
):
|
|
460
|
+
mock_platform = AsyncMock()
|
|
461
|
+
mock_platform.evaluate = AsyncMock(return_value=True)
|
|
462
|
+
MockPlatform.return_value = mock_platform
|
|
463
|
+
|
|
464
|
+
mock_graph = AsyncMock()
|
|
465
|
+
mock_graph.evaluate = AsyncMock(return_value=True)
|
|
466
|
+
MockGraph.return_value = mock_graph
|
|
467
|
+
|
|
468
|
+
mock_version = AsyncMock()
|
|
469
|
+
mock_version.evaluate = AsyncMock(return_value=True)
|
|
470
|
+
MockVersion.return_value = mock_version
|
|
471
|
+
|
|
472
|
+
mock_kernel = AsyncMock()
|
|
473
|
+
mock_kernel.evaluate = AsyncMock(return_value=True)
|
|
474
|
+
MockKernel.return_value = mock_kernel
|
|
475
|
+
|
|
476
|
+
mock_cgroup = AsyncMock()
|
|
477
|
+
mock_cgroup.evaluate = AsyncMock(return_value=True)
|
|
478
|
+
MockCgroup.return_value = mock_cgroup
|
|
479
|
+
|
|
480
|
+
mock_kernel_cgroup = AsyncMock()
|
|
481
|
+
mock_kernel_cgroup.evaluate = AsyncMock(return_value=True)
|
|
482
|
+
MockKernelCgroup.return_value = mock_kernel_cgroup
|
|
483
|
+
|
|
484
|
+
mock_runtime = AsyncMock()
|
|
485
|
+
mock_runtime.evaluate = AsyncMock(return_value=True)
|
|
486
|
+
MockRuntime.return_value = mock_runtime
|
|
487
|
+
|
|
488
|
+
mock_selinux.return_value = False
|
|
489
|
+
|
|
490
|
+
mock_sysctl = AsyncMock()
|
|
491
|
+
mock_sysctl.evaluate = AsyncMock(return_value=False)
|
|
492
|
+
MockSysctl.return_value = mock_sysctl
|
|
493
|
+
|
|
494
|
+
result = await requirements.check_requirements()
|
|
495
|
+
assert result is False
|