mirror of
https://github.com/JakeHillion/scx.git
synced 2024-11-22 09:51:49 +00:00
Merge pull request #292 from hodgesds/stress-ng-ci
Add stress-ng to scheduler tests
This commit is contained in:
commit
3219d15e3d
6
.github/workflows/build-scheds.yml
vendored
6
.github/workflows/build-scheds.yml
vendored
@ -16,7 +16,7 @@ jobs:
|
||||
### DOWNLOAD AND INSTALL DEPENDENCIES ###
|
||||
|
||||
# Download dependencies packaged by Ubuntu
|
||||
- run: sudo apt -y install bison busybox-static cargo cmake coreutils cpio elfutils file flex gcc gcc-multilib git iproute2 jq kbd kmod libcap-dev libelf-dev libunwind-dev libvirt-clients libzstd-dev linux-headers-generic linux-tools-common linux-tools-generic make ninja-build pahole pkg-config python3-dev python3-pip python3-requests qemu-kvm rsync rustc udev zstd
|
||||
- run: sudo apt -y install bison busybox-static cargo cmake coreutils cpio elfutils file flex gcc gcc-multilib git iproute2 jq kbd kmod libcap-dev libelf-dev libunwind-dev libvirt-clients libzstd-dev linux-headers-generic linux-tools-common linux-tools-generic make ninja-build pahole pkg-config python3-dev python3-pip python3-requests qemu-kvm rsync rustc stress-ng udev zstd
|
||||
|
||||
# clang 17
|
||||
# Use a custom llvm.sh script which includes the -y flag for
|
||||
@ -54,7 +54,7 @@ jobs:
|
||||
### END DEPENDENCIES ###
|
||||
|
||||
# The actual build:
|
||||
- run: meson setup build -Dkernel=$(pwd)/linux -Dkernel_headers=./linux/usr/include
|
||||
- run: meson setup build -Dkernel=$(pwd)/linux -Dkernel_headers=./linux/usr/include -Denable_stress=true
|
||||
- run: meson compile -C build --jobs=1
|
||||
|
||||
# Print CPU model before running the tests (this can be useful for
|
||||
@ -69,3 +69,5 @@ jobs:
|
||||
|
||||
# Test schedulers
|
||||
- run: meson compile -C build test_sched
|
||||
# Stress schedulers
|
||||
- run: meson compile -C build stress_tests
|
||||
|
113
meson-scripts/run_stress_tests
Executable file
113
meson-scripts/run_stress_tests
Executable file
@ -0,0 +1,113 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Small wrapper for running stress tests. Do not make this more complicated and
|
||||
assume any libraries besides Python3 stdlib.
|
||||
"""
|
||||
import logging
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
|
||||
from pathlib import PurePath
|
||||
from typing import List
|
||||
from argparse import ArgumentParser, Namespace
|
||||
from configparser import ConfigParser
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
SCRIPT_DIR: str = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
def get_exe_path(exe: str) -> str:
|
||||
path = subprocess.check_output(["which", exe])
|
||||
return path.decode("utf-8").replace("\n", "")
|
||||
|
||||
def sched_path(path: str, sched: str) -> str:
|
||||
rel_path = subprocess.check_output(
|
||||
["find", path, "-type", "f", "-executable", "-name", sched]).decode("utf-8").replace("\n", "")
|
||||
full_path = subprocess.check_output(["readlink", "-f", rel_path]).decode("utf-8").replace("\n", "")
|
||||
logger.debug(f"found scheduler {sched} in path: {full_path}")
|
||||
return full_path
|
||||
|
||||
def load_config(path: str) -> ConfigParser:
|
||||
config = ConfigParser()
|
||||
config.read(path)
|
||||
return config
|
||||
|
||||
def run_stress_test(
|
||||
config,
|
||||
build_dir: str,
|
||||
output: str,
|
||||
vng_path: str,
|
||||
kernel: str,
|
||||
verbose: bool,
|
||||
) -> int:
|
||||
scheduler_args = config.get('scheduler_args')
|
||||
stress_cmd = config.get('stress_cmd')
|
||||
s_path = sched_path(build_dir, config.get('sched'))
|
||||
sched_cmd = s_path + " " + config.get('sched_args')
|
||||
timeout_sec = int(config.get("timeout_sec"))
|
||||
if vng_path:
|
||||
vm_input = f"{stress_cmd} & timeout --foreground --preserve-status {timeout_sec} {sched_cmd}"
|
||||
cmd = [vng_path, "--user", "root", "--force-9p", "-v", "--", vm_input]
|
||||
err = sys.stderr if output == "-" else open(output, "w")
|
||||
out = sys.stdout if output == "-" else err
|
||||
proc = subprocess.Popen(
|
||||
cmd, env=os.environ, cwd=kernel, shell=False, stdout=out,
|
||||
stderr=err, stdin=subprocess.PIPE, text=True)
|
||||
proc.wait()
|
||||
return proc.returncode
|
||||
|
||||
|
||||
def stress_tests(args: Namespace) -> None:
|
||||
configs = load_config(args.config)
|
||||
vng_path = ""
|
||||
if args.vng:
|
||||
try:
|
||||
vng_path = get_exe_path("vng")
|
||||
except Exception:
|
||||
raise OSError(
|
||||
"Please install `vng` to run, see:\n"
|
||||
"https://github.com/arighi/virtme-ng?tab=readme-ov-file#installation")
|
||||
|
||||
return_codes = {}
|
||||
for test_name in configs.sections():
|
||||
if args.stress_test and test_name != args.stress_test:
|
||||
continue
|
||||
return_codes[test_name] = run_stress_test(
|
||||
configs[test_name],
|
||||
args.build_dir,
|
||||
args.output,
|
||||
vng_path,
|
||||
args.kernel,
|
||||
args.verbose,
|
||||
)
|
||||
for test_name, ret in return_codes.items():
|
||||
if ret not in (143, 0):
|
||||
logging.error(f"Failed stress tests for {test_name}: exit {ret}")
|
||||
sys.exit(ret)
|
||||
logging.info("All stress tests passed!")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = ArgumentParser(prog=__file__)
|
||||
parser.add_argument(
|
||||
'-c', '--config',
|
||||
default=os.path.join(SCRIPT_DIR, "stress_tests.ini"),
|
||||
help='Path to config file'
|
||||
)
|
||||
parser.add_argument('-o', '--output', default='-', help='Scheduler output')
|
||||
parser.add_argument(
|
||||
'-t', '--stress-test', default='', help='Name of the stress test (default: all)')
|
||||
parser.add_argument(
|
||||
'-b', '--build-dir', default='build', help='Meson build dir')
|
||||
parser.add_argument(
|
||||
'-k', '--kernel', default='', help='Kernel path for vng')
|
||||
parser.add_argument(
|
||||
'-v', '--verbose', action='store_true', help='Verbose output')
|
||||
parser.add_argument(
|
||||
'--vng', action='store_true', default=True, help='Run in vng')
|
||||
|
||||
args = parser.parse_args()
|
||||
if args.verbose:
|
||||
logger.setLevel(logging.DEBUG)
|
||||
stress_tests(args)
|
17
meson-scripts/stress_tests.ini
Normal file
17
meson-scripts/stress_tests.ini
Normal file
@ -0,0 +1,17 @@
|
||||
[scx_lavd]
|
||||
sched: scx_lavd
|
||||
sched_args:
|
||||
stress_cmd: stress-ng -t 14 --aggressive -M -c `nproc` -f `nproc`
|
||||
timeout_sec: 15
|
||||
|
||||
[scx_rusty]
|
||||
sched: scx_rusty
|
||||
sched_args:
|
||||
stress_cmd: stress-ng -t 14 --aggressive -M -c `nproc` -f `nproc`
|
||||
timeout_sec: 15
|
||||
|
||||
[scx_rustland]
|
||||
sched: scx_rustland
|
||||
sched_args:
|
||||
stress_cmd: stress-ng -t 14 --aggressive -M -c `nproc` -f `nproc`
|
||||
timeout_sec: 15
|
11
meson.build
11
meson.build
@ -14,10 +14,16 @@ enable_rust = get_option('enable_rust')
|
||||
|
||||
bpf_clang = find_program(get_option('bpf_clang'))
|
||||
|
||||
enable_stress = get_option('enable_stress')
|
||||
|
||||
if enable_rust
|
||||
cargo = find_program(get_option('cargo'))
|
||||
endif
|
||||
|
||||
if enable_stress
|
||||
run_stress_tests = find_program(join_paths(meson.current_source_dir(),
|
||||
'meson-scripts/run_stress_tests'))
|
||||
endif
|
||||
|
||||
get_clang_ver = find_program(join_paths(meson.current_source_dir(),
|
||||
'meson-scripts/get_clang_ver'))
|
||||
@ -320,6 +326,11 @@ if enable_rust
|
||||
endif
|
||||
subdir('scheds')
|
||||
|
||||
if enable_stress
|
||||
run_target('stress_tests', command: [run_stress_tests, '-k', kernel, '-b',
|
||||
meson.current_build_dir()])
|
||||
endif
|
||||
|
||||
systemd = dependency('systemd', required: get_option('systemd'))
|
||||
|
||||
if systemd.found()
|
||||
|
@ -14,6 +14,8 @@ option('offline', type: 'boolean', value: 'false',
|
||||
description: 'Compilation step should not access the internet')
|
||||
option('enable_rust', type: 'boolean', value: 'true',
|
||||
description: 'Enable rust sub-projects')
|
||||
option('enable_stress', type: 'boolean', value: 'true',
|
||||
description: 'Enable stress tests')
|
||||
option('kernel', type: 'string', value: 'vmlinuz',
|
||||
description: 'kernel image used to test schedulers')
|
||||
option('kernel_headers', type: 'string', value: '',
|
||||
|
Loading…
Reference in New Issue
Block a user