2
2
# SPDX-License-Identifier: Apache-2.0
3
3
"""Tests that verify the jailer's behavior."""
4
4
5
- import functools
6
5
import http .client as http_client
7
6
import os
8
7
import resource
@@ -196,24 +195,30 @@ def test_arbitrary_usocket_location(test_microvm_with_api):
196
195
)
197
196
198
197
199
- @functools .lru_cache (maxsize = None )
200
- def cgroup_v2_available ():
201
- """Check if cgroup-v2 is enabled on the system."""
202
- # https://rootlesscontaine.rs/getting-started/common/cgroup2/#checking-whether-cgroup-v2-is-already-enabled
203
- return os .path .isfile ("/sys/fs/cgroup/cgroup.controllers" )
198
+ class Cgroups :
199
+ """Helper class to work with cgroups"""
204
200
201
+ def __init__ (self ):
202
+ self .root = Path ("/sys/fs/cgroup" )
203
+ self .version = 2
204
+ # https://rootlesscontaine.rs/getting-started/common/cgroup2/#checking-whether-cgroup-v2-is-already-enabled
205
+ if not self .root .joinpath ("cgroup.controllers" ).exists ():
206
+ self .version = 1
205
207
206
- @ pytest . fixture ( scope = "session" , autouse = True )
207
- def sys_setup_cgroups ():
208
- """Configure cgroupfs in order to run the tests.
208
+ def new_cgroup ( self , cgname ):
209
+ """Create a new cgroup"""
210
+ self . root . joinpath ( cgname ). mkdir ( parents = True )
209
211
210
- This fixture sets up the cgroups on the system to enable processes
211
- spawned by the tests be able to create cgroups successfully.
212
- This set-up is important to do when running from inside a Docker
213
- container while the system is using cgroup-v2.
214
- """
215
- cgroup_version = 2 if cgroup_v2_available () else 1
216
- yield cgroup_version
212
+ def move_pid (self , cgname , pid ):
213
+ """Move a PID to a cgroup"""
214
+ cg_pids = self .root .joinpath (f"{ cgname } /cgroup.procs" )
215
+ cg_pids .write_text (f"{ pid } \n " , encoding = "ascii" )
216
+
217
+
218
+ @pytest .fixture (scope = "session" , autouse = True )
219
+ def cgroups_info ():
220
+ """Return a fixture with the cgroups available in the system"""
221
+ return Cgroups ()
217
222
218
223
219
224
def check_cgroups_v1 (cgroups , jailer_id , parent_cgroup = FC_BINARY_NAME ):
@@ -237,13 +242,12 @@ def check_cgroups_v1(cgroups, jailer_id, parent_cgroup=FC_BINARY_NAME):
237
242
238
243
def check_cgroups_v2 (vm ):
239
244
"""Assert that every cgroupv2 in cgroups is correctly set."""
240
- # We assume sysfs cgroups are mounted here.
241
- cg_root = Path ("/sys/fs/cgroup" )
242
- assert cg_root .is_dir ()
245
+ cg = Cgroups ()
246
+ assert cg .root .is_dir ()
243
247
parent_cgroup = vm .jailer .parent_cgroup
244
248
if parent_cgroup is None :
245
249
parent_cgroup = FC_BINARY_NAME
246
- cg_parent = cg_root / parent_cgroup
250
+ cg_parent = cg . root / parent_cgroup
247
251
cg_jail = cg_parent / vm .jailer .jailer_id
248
252
for cgroup in vm .jailer .cgroups :
249
253
controller = cgroup .split ("." )[0 ]
@@ -256,7 +260,7 @@ def check_cgroups_v2(vm):
256
260
assert all (x .isnumeric () for x in procs )
257
261
assert str (vm .firecracker_pid ) in procs
258
262
259
- for cgroup in [cg_root , cg_parent , cg_jail ]:
263
+ for cgroup in [cg . root , cg_parent , cg_jail ]:
260
264
assert controller in cgroup .joinpath ("cgroup.controllers" ).read_text (
261
265
encoding = "ascii"
262
266
)
@@ -290,12 +294,12 @@ def check_limits(pid, no_file, fsize):
290
294
assert hard == fsize
291
295
292
296
293
- def test_cgroups (test_microvm_with_api , sys_setup_cgroups ):
297
+ def test_cgroups (test_microvm_with_api , cgroups_info ):
294
298
"""
295
299
Test the cgroups are correctly set by the jailer.
296
300
"""
297
301
test_microvm = test_microvm_with_api
298
- test_microvm .jailer .cgroup_ver = sys_setup_cgroups
302
+ test_microvm .jailer .cgroup_ver = cgroups_info . version
299
303
if test_microvm .jailer .cgroup_ver == 2 :
300
304
test_microvm .jailer .cgroups = ["cpu.weight.nice=10" ]
301
305
else :
@@ -318,12 +322,12 @@ def test_cgroups(test_microvm_with_api, sys_setup_cgroups):
318
322
check_cgroups_v2 (test_microvm )
319
323
320
324
321
- def test_cgroups_custom_parent (test_microvm_with_api , sys_setup_cgroups ):
325
+ def test_cgroups_custom_parent (test_microvm_with_api , cgroups_info ):
322
326
"""
323
327
Test cgroups when a custom parent cgroup is used.
324
328
"""
325
329
test_microvm = test_microvm_with_api
326
- test_microvm .jailer .cgroup_ver = sys_setup_cgroups
330
+ test_microvm .jailer .cgroup_ver = cgroups_info . version
327
331
test_microvm .jailer .parent_cgroup = "custom_cgroup/group2"
328
332
if test_microvm .jailer .cgroup_ver == 2 :
329
333
test_microvm .jailer .cgroups = ["cpu.weight=2" ]
@@ -350,12 +354,12 @@ def test_cgroups_custom_parent(test_microvm_with_api, sys_setup_cgroups):
350
354
check_cgroups_v2 (test_microvm )
351
355
352
356
353
- def test_node_cgroups (test_microvm_with_api , sys_setup_cgroups ):
357
+ def test_node_cgroups (test_microvm_with_api , cgroups_info ):
354
358
"""
355
359
Test the numa node cgroups are correctly set by the jailer.
356
360
"""
357
361
test_microvm = test_microvm_with_api
358
- test_microvm .jailer .cgroup_ver = sys_setup_cgroups
362
+ test_microvm .jailer .cgroup_ver = cgroups_info . version
359
363
360
364
# Retrieve CPUs from NUMA node 0.
361
365
node_cpus = get_cpus (0 )
@@ -371,12 +375,12 @@ def test_node_cgroups(test_microvm_with_api, sys_setup_cgroups):
371
375
check_cgroups_v2 (test_microvm )
372
376
373
377
374
- def test_cgroups_without_numa (test_microvm_with_api , sys_setup_cgroups ):
378
+ def test_cgroups_without_numa (test_microvm_with_api , cgroups_info ):
375
379
"""
376
380
Test the cgroups are correctly set by the jailer, without numa assignment.
377
381
"""
378
382
test_microvm = test_microvm_with_api
379
- test_microvm .jailer .cgroup_ver = sys_setup_cgroups
383
+ test_microvm .jailer .cgroup_ver = cgroups_info . version
380
384
if test_microvm .jailer .cgroup_ver == 2 :
381
385
test_microvm .jailer .cgroups = ["cpu.weight=2" ]
382
386
else :
@@ -390,18 +394,15 @@ def test_cgroups_without_numa(test_microvm_with_api, sys_setup_cgroups):
390
394
check_cgroups_v2 (test_microvm )
391
395
392
396
393
- @pytest .mark .skipif (
394
- cgroup_v2_available () is True , reason = "Requires system with cgroup-v1 enabled."
395
- )
396
- def test_v1_default_cgroups (test_microvm_with_api ):
397
+ def test_v1_default_cgroups (test_microvm_with_api , cgroups_info ):
397
398
"""
398
399
Test if the jailer is using cgroup-v1 by default.
399
400
"""
401
+ if cgroups_info .version != 1 :
402
+ pytest .skip (reason = "Requires system with cgroup-v1 enabled." )
400
403
test_microvm = test_microvm_with_api
401
404
test_microvm .jailer .cgroups = ["cpu.shares=2" ]
402
-
403
405
test_microvm .spawn ()
404
-
405
406
check_cgroups_v1 (test_microvm .jailer .cgroups , test_microvm .jailer .jailer_id )
406
407
407
408
0 commit comments