-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This first commit is adding a first cmdline engine_module to execute a single fio command line. This commit is not functional yet but set the base of the logic to parse the engine. Signed-off-by: Erwan Velu <[email protected]>
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# This configuration will : | ||
# - load all cores with a matrixprod test during 15 sec. | ||
[global] | ||
runtime=15 | ||
monitor=all | ||
|
||
[randread_cmdline] | ||
engine=fio | ||
engine_module=cmdline | ||
engine_module_parameter_base="--filename=/dev/sdp --direct=1 --rw=randread --bs=4k --ioengine=libaio --iodepth=256 --numjobs=4 --time_based --group_reporting --readonly" | ||
hosting_cpu_cores=all | ||
hosting_cpu_cores_scaling=none | ||
stressor_range=auto | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
from . import test_benchmarks_common as tbc | ||
|
||
|
||
class TestFio(tbc.TestCommon): | ||
def __init__(self, *args, **kwargs): | ||
super().__init__(*args, **kwargs) | ||
self.load_mocked_hardware( | ||
cpucores="./tests/parsing/cpu_cores/v2321", | ||
cpuinfo="./tests/parsing/cpu_info/v2321", | ||
numa="./tests/parsing/numa/8domainsllc", | ||
) | ||
self.load_benches("./config/fio.conf") | ||
self.parse_jobs_config() | ||
self.QUADRANT0 = list(range(0, 16)) + list(range(64, 80)) | ||
self.QUADRANT1 = list(range(16, 32)) + list(range(80, 96)) | ||
self.ALL = list(range(0, 128)) | ||
|
||
def test_fio(self): | ||
"""Check fio syntax.""" | ||
assert self.benches.count_benchmarks() == 1 | ||
assert self.benches.count_jobs() == 1 | ||
assert self.benches.runtime() == 15 | ||
self.assertIsNone(self.benches.benchs[0].validate_parameters()) | ||
bench = self.get_bench_parameters(0) | ||
assert bench.get_name() == "randread_cmdline" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# This configuration will : | ||
# - load all cores with a matrixprod test during 15 sec. | ||
[global] | ||
runtime=15 | ||
monitor=all | ||
|
||
[randread_cmdline] | ||
engine=fio | ||
engine_module=cmdline | ||
engine_module_parameter_base="--filename=/dev/sdp --direct=1 --rw=randread --bs=4k --ioengine=libaio --iodepth=256 --numjobs=4 --time_based --group_reporting --readonly" | ||
hosting_cpu_cores=all | ||
hosting_cpu_cores_scaling=none | ||
stressor_range=auto | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import pathlib | ||
Check failure on line 1 in hwbench/config/test_parse_fio.py GitHub Actions / Check if every commit in the PR works (3.9)Ruff (F401)
Check failure on line 1 in hwbench/config/test_parse_fio.py GitHub Actions / Check if every commit in the PR works (3.10)Ruff (F401)
Check failure on line 1 in hwbench/config/test_parse_fio.py GitHub Actions / Check if every commit in the PR works (3.11)Ruff (F401)
|
||
from unittest.mock import patch | ||
from ..environment.mock import MockHardware | ||
from ..bench import test_benchmarks_common as tbc | ||
|
||
|
||
class TestParseConfig(tbc.TestCommon): | ||
def __init__(self, *args, **kwargs): | ||
super().__init__(*args, **kwargs) | ||
self.hw = MockHardware() | ||
self.load_benches("./config/fio.conf") | ||
|
||
def test_sections_name(self): | ||
"""Check if sections names are properly detected.""" | ||
sections = self.get_jobs_config().get_sections() | ||
assert sections == [ | ||
"randread_cmdline", | ||
] | ||
|
||
def test_keywords(self): | ||
"""Check if all keywords are valid.""" | ||
try: | ||
with patch("hwbench.utils.helpers.is_binary_available") as iba: | ||
iba.return_value = True | ||
self.get_jobs_config().validate_sections() | ||
except Exception as exc: | ||
assert False, f"'validate_sections' detected a syntax error {exc}" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
from ..bench.parameters import BenchmarkParameters | ||
from ..bench.engine import EngineBase, EngineModuleBase | ||
from ..bench.benchmark import ExternalBench | ||
|
||
|
||
class EngineModuleCmdline(EngineModuleBase): | ||
"""This class implements the EngineModuleBase for fio""" | ||
|
||
def __init__(self, engine: EngineBase, engine_module_name: str, fake_stdout=None): | ||
super().__init__(engine, engine_module_name) | ||
self.engine_module_name = engine_module_name | ||
self.load_module_parameter(fake_stdout) | ||
|
||
def load_module_parameter(self, fake_stdout=None): | ||
# if needed add module parameters to your module | ||
self.add_module_parameter("cmdline") | ||
|
||
def validate_module_parameters(self, p: BenchmarkParameters): | ||
msg = super().validate_module_parameters(p) | ||
Fio(self, p).parse_parameters() | ||
return msg | ||
|
||
def run_cmd(self, p: BenchmarkParameters): | ||
return Fio(self, p).run_cmd() | ||
|
||
def run(self, p: BenchmarkParameters): | ||
return Fio(self, p).run() | ||
|
||
def fully_skipped_job(self, p) -> bool: | ||
return Fio(self, p).fully_skipped_job() | ||
|
||
|
||
class Engine(EngineBase): | ||
"""The main fio class.""" | ||
|
||
def __init__(self, fake_stdout=None): | ||
super().__init__("fio", "fio") | ||
self.add_module(EngineModuleCmdline(self, "cmdline", fake_stdout)) | ||
|
||
def run_cmd_version(self) -> list[str]: | ||
return [ | ||
self.get_binary(), | ||
"--version", | ||
] | ||
|
||
def run_cmd(self) -> list[str]: | ||
return [] | ||
|
||
def parse_version(self, stdout: bytes, _stderr: bytes) -> bytes: | ||
print(stdout) | ||
self.version = stdout.split(b"-")[1] | ||
return self.version | ||
|
||
def version_major(self) -> int: | ||
if self.version: | ||
return int(self.version.split(b".")[0]) | ||
return 0 | ||
|
||
def version_minor(self) -> int: | ||
if self.version: | ||
return int(self.version.split(b".")[1]) | ||
return 0 | ||
|
||
def parse_cmd(self, stdout: bytes, stderr: bytes): | ||
return {} | ||
|
||
|
||
class Fio(ExternalBench): | ||
"""The Fio stressor.""" | ||
|
||
def __init__( | ||
self, engine_module: EngineModuleBase, parameters: BenchmarkParameters | ||
): | ||
ExternalBench.__init__(self, engine_module, parameters) | ||
self.parameters = parameters | ||
self.engine_module = engine_module | ||
self.parse_parameters() | ||
|
||
def parse_parameters(self): | ||
runtime = self.parameters.runtime | ||
Check failure on line 80 in hwbench/engines/fio.py GitHub Actions / Check if every commit in the PR works (3.9)Ruff (F841)
Check failure on line 80 in hwbench/engines/fio.py GitHub Actions / Check if every commit in the PR works (3.10)Ruff (F841)
Check failure on line 80 in hwbench/engines/fio.py GitHub Actions / Check if every commit in the PR works (3.11)Ruff (F841)
|
||
|
||
def run_cmd(self) -> list[str]: | ||
# Let's build the command line to run the tool | ||
args = [ | ||
self.engine_module.get_engine().get_binary(), | ||
str(self.parameters.get_runtime()), | ||
] | ||
|
||
return self.get_taskset(args) | ||
|
||
def parse_cmd(self, stdout: bytes, stderr: bytes): | ||
# Add the score to the global output | ||
return self.parameters.get_result_format() | { | ||
"bogo ops/s": self.parameters.get_runtime() | ||
} | ||
|
||
@property | ||
def name(self) -> str: | ||
return self.engine_module.get_engine().get_name() | ||
|
||
def run_cmd_version(self) -> list[str]: | ||
return self.engine_module.get_engine().run_cmd_version() | ||
|
||
def parse_version(self, stdout: bytes, _stderr: bytes) -> bytes: | ||
return self.engine_module.get_engine().parse_version(stdout, _stderr) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import pathlib | ||
import unittest | ||
from unittest.mock import patch | ||
|
||
from .fio import Engine as Fio | ||
|
||
|
||
def mock_engine() -> Fio: | ||
with patch("hwbench.utils.helpers.is_binary_available") as iba: | ||
iba.return_value = True | ||
return Fio() | ||
|
||
|
||
class TestParse(unittest.TestCase): | ||
def test_engine_parsing_version(self): | ||
test_dir = pathlib.Path("./tests/parsing/fio") | ||
for d in test_dir.iterdir(): | ||
test_target = mock_engine() | ||
if not d.is_dir(): | ||
continue | ||
ver_stdout = (d / "version-stdout").read_bytes() | ||
ver_stderr = (d / "version-stderr").read_bytes() | ||
version = test_target.parse_version(ver_stdout, ver_stderr) | ||
assert version == (d / "version").read_bytes().strip() | ||
assert test_target.version_major() == 3 | ||
assert test_target.version_minor() == 19 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
3.19 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
fio-3.19 |