| 
 | 1 | +# Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.  | 
 | 2 | +# SPDX-License-Identifier: Apache-2.0  | 
 | 3 | +"""Performance benchmark for the jailer."""  | 
 | 4 | + | 
 | 5 | +from framework.jailer import JailerContext, DEFAULT_CHROOT_PATH  | 
 | 6 | +from framework import defs  | 
 | 7 | + | 
 | 8 | +import subprocess  | 
 | 9 | +import os  | 
 | 10 | +import shutil  | 
 | 11 | + | 
 | 12 | +import numpy as np  | 
 | 13 | +import pytest  | 
 | 14 | + | 
 | 15 | +@pytest.mark.nonci  | 
 | 16 | +@pytest.mark.parametrize("jailers", [1, 100, 200, 300, 400])  | 
 | 17 | +@pytest.mark.parametrize("mounts", [0, 100, 300, 500])  | 
 | 18 | +def test_jailer_startup(jailer_time_bin, microvm_factory, jailers, mounts, metrics):  | 
 | 19 | +    """  | 
 | 20 | +    Test the overhead of jailer startup without and with bind mounts  | 
 | 21 | +    """  | 
 | 22 | + | 
 | 23 | +    jailer_binary = microvm_factory.jailer_binary_path  | 
 | 24 | + | 
 | 25 | +    # Create bind mount points. The exact location of them  | 
 | 26 | +    # does not matter, they just need to exist.  | 
 | 27 | +    mounts_paths = f"/tmp/mounts"  | 
 | 28 | +    os.makedirs(mounts_paths)  | 
 | 29 | +    for m in range(mounts):  | 
 | 30 | +        mount_path = f"{mounts_paths}/mount{m}"  | 
 | 31 | +        os.makedirs(mount_path)  | 
 | 32 | +        subprocess.run(["mount", "--bind", f"{mount_path}", f"{mount_path}"])  | 
 | 33 | + | 
 | 34 | +    processes = []  | 
 | 35 | +    for i in range(jailers):  | 
 | 36 | +        jailer = JailerContext(  | 
 | 37 | +            jailer_id=f"fakefc{i}",  | 
 | 38 | +            exec_file=jailer_time_bin,  | 
 | 39 | +            # Don't deamonize to get the stdout  | 
 | 40 | +            daemonize=False,  | 
 | 41 | +        )  | 
 | 42 | +        jailer.setup()  | 
 | 43 | + | 
 | 44 | +        cmd = [str(jailer_binary), *jailer.construct_param_list()]  | 
 | 45 | +        processes.append(subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False))  | 
 | 46 | + | 
 | 47 | +    deltas = []  | 
 | 48 | +    for (i, p) in enumerate(processes):  | 
 | 49 | +        r = p.communicate()[0]  | 
 | 50 | +        e, s = r.split()  | 
 | 51 | +        deltas.append(int(e) - int(s))  | 
 | 52 | +      | 
 | 53 | +    p50 = np.percentile(deltas, 50)  | 
 | 54 | +    p90 = np.percentile(deltas, 90)  | 
 | 55 | + | 
 | 56 | +    metrics.set_dimensions(  | 
 | 57 | +        {  | 
 | 58 | +            "performance_test": "test_boottime",  | 
 | 59 | +            "jailers": jailers,  | 
 | 60 | +            "mounts": mounts,  | 
 | 61 | +        }  | 
 | 62 | +    )  | 
 | 63 | +    metrics.put_metric(  | 
 | 64 | +        "p50",  | 
 | 65 | +        p50,  | 
 | 66 | +        unit="Microseconds",  | 
 | 67 | +    )  | 
 | 68 | +    metrics.put_metric(  | 
 | 69 | +        "p90",  | 
 | 70 | +        p90,  | 
 | 71 | +        unit="Microseconds",  | 
 | 72 | +    )  | 
 | 73 | + | 
 | 74 | +    # Cleanup mounts and jailer dirs  | 
 | 75 | +    for d in os.listdir(mounts_paths):  | 
 | 76 | +        subprocess.run(["umount", f"{mounts_paths}/{d}"])  | 
 | 77 | +    shutil.rmtree(mounts_paths)  | 
 | 78 | +    shutil.rmtree(DEFAULT_CHROOT_PATH)  | 
 | 79 | + | 
0 commit comments