-
Notifications
You must be signed in to change notification settings - Fork 26
Expand file tree
/
Copy pathtest_base.py
More file actions
287 lines (251 loc) · 8.96 KB
/
test_base.py
File metadata and controls
287 lines (251 loc) · 8.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
"""Tests for the base container itself (the one that is already present on
registry.suse.com)
"""
## Maintainer: BCI team (#proj-bci)
from typing import Dict
import pytest
from pytest_container import DerivedContainer
from pytest_container.container import ContainerData
from pytest_container.container import container_and_marks_from_pytest_param
from pytest_container.runtime import LOCALHOST
from bci_tester.data import BASE_CONTAINER
from bci_tester.data import BASE_FIPS_CONTAINERS
from bci_tester.data import LTSS_BASE_CONTAINERS
from bci_tester.data import LTSS_BASE_FIPS_CONTAINERS
from bci_tester.data import OS_VERSION
from bci_tester.data import TARGET
from bci_tester.fips import ALL_DIGESTS
from bci_tester.fips import FIPS_DIGESTS
from bci_tester.fips import host_fips_enabled
from bci_tester.fips import target_fips_enforced
from bci_tester.runtime_choice import DOCKER_SELECTED
from bci_tester.runtime_choice import PODMAN_SELECTED
from tests.test_fips import openssl_fips_hashes_test_fnct
CONTAINER_IMAGES = [
BASE_CONTAINER,
*BASE_FIPS_CONTAINERS,
*LTSS_BASE_CONTAINERS,
*LTSS_BASE_FIPS_CONTAINERS,
]
def test_passwd_present(auto_container):
"""Generic test that :file:`/etc/passwd` exists"""
assert auto_container.connection.file("/etc/passwd").exists
@pytest.mark.skipif(
OS_VERSION not in ("tumbleweed", "16.0"),
reason="requires gconv modules",
)
def test_iconv_working(auto_container):
"""Generic test iconv works for UTF8 and ISO-8859-15 locale"""
assert (
auto_container.connection.check_output(
"echo -n 'SüSE' | iconv -f UTF8 -t ISO_8859-15 | wc -c"
)
== "4"
)
@pytest.mark.skipif(
OS_VERSION in ("15.3", "15.4", "15.5"),
reason="unfixed in LTSS codestreams",
)
def test_group_nobody_working(auto_container):
"""Test that nobody group is available in the container (bsc#1212118)."""
assert auto_container.connection.check_output("getent group nobody")
@pytest.mark.skipif(
not PODMAN_SELECTED,
reason="docker size reporting is dependent on underlying filesystem",
)
@pytest.mark.parametrize(
"container",
[c for c in CONTAINER_IMAGES if c not in BASE_FIPS_CONTAINERS],
indirect=True,
)
def test_base_size(container: ContainerData, container_runtime):
"""Ensure that the container's size is below the limits specified in
:py:const:`base_container_max_size`
"""
# the FIPS container is bigger too than the 15 SP3 base image
is_fips_ctr = (
container.container.baseurl
and container.container.baseurl.rpartition("/")[2].startswith(
"bci-base-fips"
)
or TARGET in ("dso",)
)
#: size limits of the base container per arch in MiB
if is_fips_ctr:
# SP4+ is a lot larger as it pulls in python3 and
# the FIPS crypto policy scripts
base_container_max_size: Dict[str, int] = {
"x86_64": 130 if OS_VERSION in ("15.3",) else 169,
}
if TARGET in ("dso",):
# the dso container is larger than the bci-base-fips container
base_container_max_size["x86_64"] += 10
elif OS_VERSION in ("tumbleweed",):
base_container_max_size: Dict[str, int] = {
"x86_64": 100,
"aarch64": 126,
"ppc64le": 138,
"s390x": 99,
}
elif OS_VERSION in ("16.0",):
base_container_max_size: Dict[str, int] = {
"x86_64": 101,
"aarch64": 126,
"ppc64le": 138,
"s390x": 99,
}
elif OS_VERSION in ("15.7",):
base_container_max_size: Dict[str, int] = {
"x86_64": 121,
"aarch64": 135,
"ppc64le": 159,
"s390x": 122,
}
elif OS_VERSION in ("15.6",):
base_container_max_size: Dict[str, int] = {
"x86_64": 120,
"aarch64": 134,
"ppc64le": 155,
"s390x": 121,
}
elif OS_VERSION in ("15.5",):
# pick the sizes from sles15-ltss-image which is larger than sles15-ltsss
base_container_max_size: Dict[str, int] = {
"x86_64": 126,
"aarch64": 146,
"ppc64le": 170,
"s390x": 130,
}
elif OS_VERSION in ("15.4",):
# pick the sizes from sles15-ltss-image which is larger than sles15-ltsss
base_container_max_size: Dict[str, int] = {
"x86_64": 121,
"aarch64": 142,
"ppc64le": 162,
"s390x": 125,
}
else:
base_container_max_size: Dict[str, int] = {
"x86_64": 120,
"aarch64": 140,
"ppc64le": 160,
"s390x": 125,
}
container_size = container_runtime.get_image_size(
container.image_url_or_id
) // (1024 * 1024)
max_container_size = base_container_max_size[LOCALHOST.system_info.arch]
assert container_size <= max_container_size, (
f"Base container size is {container_size} MiB for {LOCALHOST.system_info.arch} "
f"(expected max of {base_container_max_size[LOCALHOST.system_info.arch]} MiB)"
)
without_fips = pytest.mark.skipif(
host_fips_enabled() or target_fips_enforced(),
reason="host running in FIPS 140 mode",
)
def test_gost_digest_disable(auto_container):
"""Checks that the gost message digest is not known to openssl."""
openssl_error_message = (
"Invalid command 'gost'"
if OS_VERSION not in ("15.3", "15.4", "15.5")
else "gost is not a known digest"
)
assert (
openssl_error_message
in auto_container.connection.run_expect(
[1], "openssl gost /dev/null"
).stderr.strip()
)
@without_fips
@pytest.mark.parametrize(
"container",
[
c
for c in CONTAINER_IMAGES
if c not in (*LTSS_BASE_FIPS_CONTAINERS, *BASE_FIPS_CONTAINERS)
],
indirect=True,
)
def test_openssl_hashes(container):
"""If the host is not running in fips mode, then we check that all hash
algorithms work via :command:`openssl $digest /dev/null`.
"""
for digest in ALL_DIGESTS:
container.connection.run_expect([0], f"openssl {digest} /dev/null")
@pytest.mark.parametrize(
"container_per_test",
[*LTSS_BASE_FIPS_CONTAINERS, *BASE_FIPS_CONTAINERS]
+ ([BASE_CONTAINER] if TARGET in ("dso",) else []),
indirect=True,
)
def test_openssl_fips_hashes(container_per_test):
"""Check that all FIPS allowed hashes perform correctly."""
openssl_fips_hashes_test_fnct(container_per_test)
def test_all_openssl_hashes_known(auto_container):
"""Sanity test that all openssl digests are saved in
:py:const:`bci_tester.fips.ALL_DIGESTS`.
"""
fips_mode: bool = (
auto_container.connection.check_output(
"echo ${OPENSSL_FIPS:-0}"
).strip()
== "1"
)
hashes = (
auto_container.connection.check_output(
"openssl list --digest-commands"
)
.strip()
.split()
)
expected_digest_list = ALL_DIGESTS
# openssl-3 reduces the listed digests in FIPS mode, openssl 1.x does not
if OS_VERSION not in ("15.3", "15.4", "15.5"):
if host_fips_enabled() or target_fips_enforced() or fips_mode:
expected_digest_list = FIPS_DIGESTS
# gost is not supported to generate digests, but it appears in:
# openssl list --digest-commands
if OS_VERSION in ("15.3", "15.4", "15.5"):
expected_digest_list += ("gost",)
assert len(hashes) == len(expected_digest_list)
assert set(hashes) == set(expected_digest_list)
#: This is the base container with additional launch arguments applied to it so
#: that docker can be launched inside the container
DIND_CONTAINER = pytest.param(
DerivedContainer(
base=container_and_marks_from_pytest_param(BASE_CONTAINER)[0],
**{
x: getattr(BASE_CONTAINER.values[0], x)
for x in BASE_CONTAINER.values[0].__dict__
if x not in ("extra_launch_args", "base")
},
extra_launch_args=[
"--privileged=true",
"-v",
"/var/run/docker.sock:/var/run/docker.sock",
],
),
)
@pytest.mark.parametrize("container_per_test", [DIND_CONTAINER], indirect=True)
@pytest.mark.xfail(
OS_VERSION in ("16.0",),
reason="SLE BCI repository not yet available",
)
@pytest.mark.skipif(
not DOCKER_SELECTED,
reason="Docker in docker can only be tested when using the docker runtime",
)
def test_dind(container_per_test):
"""Check that we can install :command:`docker` in the container and launch the
latest Tumbleweed container inside it.
This requires additional settings for the docker command line (see
:py:const:`DIND_CONTAINER`).
"""
container_per_test.connection.run_expect([0], "zypper -n in docker")
container_per_test.connection.run_expect([0], "docker ps")
res = container_per_test.connection.run_expect(
[0],
"docker run --rm registry.opensuse.org/opensuse/tumbleweed:latest "
"/usr/bin/ls",
)
assert "etc" in res.stdout