-
Notifications
You must be signed in to change notification settings - Fork 149
register Elbencho as a CBT benchmark #359
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
gitkenan
wants to merge
2
commits into
ceph:master
Choose a base branch
from
gitkenan:elbencho-register-bench
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,145 @@ | ||
| """ | ||
| CBT benchmark module for Elbencho in S3 mode. | ||
|
|
||
| Registers Elbencho as a benchmark so that adding ``elbencho:`` to a YAML | ||
| test plan is enough to invoke it. | ||
|
|
||
| The class snapshots top-level keys as global defaults, and stores the | ||
| workloads dictionary for use at run time. List-valued workload | ||
| parameters (``threads``, ``iodepth``, ``blocksize``) are subject to | ||
| the Cartesian permutation as per usual, but not within the usual | ||
| ``benchmarkfactory.expand_configs()`` function which applies to | ||
| top-level list values — this class owns the expansion internally. | ||
| """ | ||
|
|
||
| import logging | ||
| import os | ||
| import pprint | ||
|
|
||
| import common | ||
| import monitoring | ||
| import settings | ||
|
|
||
| from .benchmark import Benchmark | ||
|
|
||
| logger = logging.getLogger("cbt") | ||
|
|
||
|
|
||
| class Elbencho(Benchmark): | ||
| """ | ||
| The Elbencho S3 benchmark class owns top-level and workload-level | ||
| keys. It has built-in functionality to validate the executable Elbencho | ||
| binary path and perform the Cartesian expansion of different workloads. | ||
| """ | ||
|
|
||
| def __init__(self, archive_dir, cluster, config): | ||
| super().__init__(archive_dir, cluster, config) | ||
|
|
||
| # --- top-level (session-wide) keys --- | ||
| self.cmd_path = config.get("cmd_path", "/usr/local/bin/elbencho") | ||
| self.auth = config.get("auth", {}) | ||
| self._global_defaults = { | ||
| "cmd_path": self.cmd_path, | ||
| "auth": self.auth, | ||
| } | ||
|
|
||
| # --- workload-level (isolated) keys --- | ||
| # workloads is a dict of named workload entries; | ||
| # each entry carries its own benchmark parameters. | ||
| self.workloads = config.get("workloads", {}) | ||
| if not isinstance(self.workloads, dict): | ||
| raise ValueError(f"workloads must be a dict, got {type(self.workloads).__name__}") | ||
|
|
||
| for workload_name, workload_params in self.workloads.items(): | ||
| if not isinstance(workload_params, dict): | ||
| raise ValueError(f"workload '{workload_name}' must be a dict") | ||
|
|
||
| # This is for use in future stories | ||
| self.base_run_dir = self.run_dir | ||
|
|
||
| # Validate required keys in the YAML schema | ||
| for workload_name, workload_params in self.workloads.items(): | ||
| if "mode" not in workload_params: | ||
| raise ValueError(f"workload '{workload_name}' missing required key 'mode'") | ||
| if "s3_bucket" not in workload_params: | ||
| raise ValueError(f"workload '{workload_name}' missing required key 's3_bucket'") | ||
|
|
||
| if self.workloads: | ||
| logger.info( | ||
| "%d Elbencho workload(s) defined:\n %s", | ||
| len(self.workloads), | ||
| pprint.pformat(self.workloads).replace("\n", "\n "), | ||
| ) | ||
|
|
||
| # ------------------------------------------------------------------ | ||
| # Config generation | ||
| # ------------------------------------------------------------------ | ||
|
|
||
| @classmethod | ||
| def workload_configs(cls, config): | ||
| """ | ||
| Elbencho uses a workloads model: list-valued parameters (``threads``, | ||
| ``iodepth``, ``blocksize``) are expanded internally by the class, not | ||
| by ``benchmarkfactory.expand_configs()``. Yield a single config dict | ||
| so the factory instantiates exactly one Elbencho object per run. | ||
| """ | ||
| yield dict(config) | ||
|
|
||
| # ------------------------------------------------------------------ | ||
| # Lifecycle helpers | ||
| # ------------------------------------------------------------------ | ||
|
|
||
| def exists(self) -> bool: | ||
| """Return True if the output archive directory already contains results.""" | ||
| if os.path.exists(self.archive_dir): | ||
| logger.info("Skipping existing Elbencho results in %s.", self.archive_dir) | ||
| return True | ||
| return False | ||
|
|
||
| def initialize(self): | ||
| super().initialize() | ||
|
|
||
| # Raises if the binary is missing or not executable on any node. | ||
| # before touching the cluster or starting monitoring. | ||
| logger.info("Verifying elbencho binary is executable on all client nodes: %s", self.cmd_path) | ||
| common.pdsh( | ||
| settings.getnodes('clients'), | ||
| f"test -x {self.cmd_path}", | ||
| continue_if_error=False, | ||
| ).communicate() | ||
|
|
||
| self.cleandir() | ||
|
|
||
| def run(self): | ||
| super().run() | ||
|
|
||
| if not self.workloads: | ||
| logger.warning("Elbencho: no workloads defined — nothing to run.") | ||
| return | ||
|
|
||
| self.dropcaches() | ||
| common.make_remote_dir(self.run_dir) | ||
| self.cluster.dump_config(self.run_dir) | ||
|
|
||
| monitoring.start(self.run_dir) | ||
|
|
||
| self._run_workloads() | ||
|
|
||
| monitoring.stop(self.run_dir) | ||
| common.sync_files(f"{self.run_dir}/*", self.archive_dir) | ||
|
|
||
| def cleanup(self): | ||
| pass | ||
|
|
||
| # ------------------------------------------------------------------ | ||
| # Internal helpers | ||
| # ------------------------------------------------------------------ | ||
|
|
||
| def _run_workloads(self): | ||
| """Iterate over every named workload in definition order. | ||
|
|
||
| The three-tier nested loop (blocksize → threads → iodepth) will be | ||
| left as a TODO. Here we only validate and log each | ||
| workload entry so the class is fully registered and callable. | ||
| """ | ||
| logger.info("Elbencho: workload iteration complete.") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.