Skip to content

Commit 4c1a8f7

Browse files
committed
feat: add jailer startup test with parallelism
Add another test of jailer startup time, now with variable number of parallel launches of the jailer process. Signed-off-by: Egor Lazarchuk <yegorlz@amazon.co.uk>
1 parent 9718f9a commit 4c1a8f7

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed

tests/integration_tests/performance/test_jailer.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import os
66
import shutil
77
import subprocess
8+
from concurrent.futures import ProcessPoolExecutor
89

910
import pytest
1011

@@ -83,3 +84,83 @@ def test_jailer_startup(
8384
for d in os.listdir(mounts_paths):
8485
subprocess.run(["umount", f"{mounts_paths}/{d}"], check=True)
8586
shutil.rmtree(DEFAULT_CHROOT_PATH)
87+
88+
89+
def run_command(cmd):
90+
"""
91+
Run the cmd in subprocess. Needs to be outside
92+
other functions, otherwise the ProcessPoolExecutor
93+
will not be able to pickle it.
94+
"""
95+
return subprocess.run(
96+
cmd,
97+
capture_output=True,
98+
text=True,
99+
check=True,
100+
)
101+
102+
103+
@pytest.mark.nonci
104+
@pytest.mark.parametrize("parallel", [1, 5, 10])
105+
@pytest.mark.parametrize("mounts", [0, 100, 300, 500])
106+
def test_jailer_startup_parallel(
107+
jailer_time_bin, tmp_path, microvm_factory, parallel, mounts, metrics
108+
):
109+
"""
110+
Test the overhead of jailer startup without and with bind mounts
111+
with different parallelism options.
112+
"""
113+
114+
jailer_binary = microvm_factory.jailer_binary_path
115+
116+
# Create bind mount points. The exact location of them
117+
# does not matter, they just need to exist.
118+
mounts_paths = tmp_path / "mounts"
119+
os.makedirs(mounts_paths)
120+
for m in range(mounts):
121+
mount_path = f"{mounts_paths}/mount{m}"
122+
os.makedirs(mount_path)
123+
subprocess.run(
124+
["mount", "--bind", f"{mount_path}", f"{mount_path}"], check=True
125+
)
126+
127+
metrics.set_dimensions(
128+
{
129+
"instance": global_props.instance,
130+
"cpu_model": global_props.cpu_model,
131+
"performance_test": "test_jailer_startup_parallel",
132+
"parallel": str(parallel),
133+
"mounts": str(mounts),
134+
}
135+
)
136+
137+
cmds = []
138+
for i in range(500):
139+
jailer = JailerContext(
140+
jailer_id=f"fakefc{i}",
141+
exec_file=jailer_time_bin,
142+
# Don't deamonize to get the stdout
143+
daemonize=False,
144+
)
145+
jailer.setup()
146+
147+
cmd = [str(jailer_binary), *jailer.construct_param_list()]
148+
cmds.append(cmd)
149+
150+
with ProcessPoolExecutor(max_workers=parallel) as executor:
151+
# Submit all commands and get results
152+
results = list(executor.map(run_command, cmds))
153+
154+
# Get results as they complete
155+
for result in results:
156+
e, s = result.stdout.split()
157+
metrics.put_metric(
158+
"startup",
159+
int(e) - int(s),
160+
unit="Microseconds",
161+
)
162+
163+
# Cleanup mounts and jailer dirs
164+
for d in os.listdir(mounts_paths):
165+
subprocess.run(["umount", f"{mounts_paths}/{d}"], check=True)
166+
shutil.rmtree(DEFAULT_CHROOT_PATH)

0 commit comments

Comments
 (0)