- Core configuration lives under
lb_runner/(benchmark_config.py). - Runner code is under
lb_runner/; controller underlb_controller/; app-layer API underlb_app/; UI underlb_ui/. - Reporting and post-processing live under
lb_analytics/; shared utilities inlb_common/; provisioning helpers inlb_provisioner/. - Use the stable APIs from
lb_runner.api,lb_controller.api, andlb_app.apiinstead of importing deep modules. - UI layering:
lb_uimay import onlylb_app.api(andlb_common.apiwhen needed). Avoid any direct imports fromlb_controller,lb_runner,lb_plugins,lb_analytics, orlb_provisioner. - Collectors sit in
lb_runner/metric_collectors/(PSUtil, CLI, perf, eBPF) and workload plugins inlb_plugins/plugins/(stress-ng, dd, fio, hpl), each with base abstractions plus concrete implementations. - Tests are under
tests/; sample usage is inexample.py. Output artifacts are written tobenchmark_results/,reports/, anddata_exports/(these may be absent until generated).
- Create env and install:
uv sync --all-extras. Do not useuv pip install -e ".[dev]"for development: the lint/type/security toolchain (ruff, basedpyright, pre-commit, bandit, semgrep, deptry, yamllint, ansible-lint, import-linter) is declared in[dependency-groups].dev, whichuv syncinstalls and thedevextra does not. Then enable the hooks withuv run pre-commit install. - Run all tests locally:
uv run pytest tests/(pytest is configured with strict markers and minimal output). For coverage, use./scripts/run_tests_with_cov.sh. - Quick smoke run:
uv run python example.pyto execute the sample controller flow after dependencies are installed.
- Python 3.12+ (the
requires-pythonfloor; CI also runs 3.13). Linting and formatting are done by Ruff (line length 88) withbasedpyrightin standard mode for types (configured in[tool.basedpyright]; no untyped defs, no implicit Optional). Ruff also holds the pydocstyle rules that used to run via thepydocstyletool, with the missing-docstring family and D203/D213 ignored — keep concise docstrings for public APIs. - Use
snake_casefor functions/variables/modules,PascalCasefor classes, andUPPER_SNAKE_CASEfor constants. Prefer well-named dataclasses for configs and keep CLI/tool shelling confined to collectors/generators. - Logging policy: configure logging via
lb_common.configure_logging()in entrypoints.lb_runnerdoes not auto-configure logging; callers should opt in to keepLB_EVENToutput on stdout clean. - Run
uv run pre-commit run --all-filesbefore pushing: it is the same hook set CI runs, so a green local run means a green pipeline.
- Framework: pytest; tests live in
tests/with filestest_*.py, classesTest*, functionstest_*. Favor unit tests for collectors/generators with fake command outputs and small integration tests that exercise the controller. - Add coverage for new metrics, config validation, and error handling paths; when a test needs system tools, mark or skip so it is safe on CI/docker.
- Keep commits focused and present-tense (e.g.,
Add Docker support,Fix pyproject discoveryas seen in history). Include issue IDs when applicable. - For PRs, provide a short summary, how to reproduce/validate, and note any new dependencies or required privileges (perf/eBPF, stress-ng). Include logs or screenshots for report changes and mention impacts on output directories or config formats.
- Some collectors require root or Linux-only tooling; avoid running perf/eBPF-heavy commands on shared hosts without approval. Prefer the Docker flow for consistent system dependencies and to isolate high-load generators.
- If a worktree contains submodules, remove it with
scripts/remove_worktree_with_submodules.sh /path/to/worktree(this deinitializes submodules first, then force-removes the worktree).