forked from cleveragents/cleveragents-core
f2be43dcc2
Centralize CLI output through shared renderers module with get_console() and get_err_console() accessors. Introduce ColumnSpec-based table rendering for plan list, resource list, and actor list commands. Add _FORMAT_HELP constant and fmt= parameter threading for consistent format handling. Includes Behave BDD tests for format output validation, Robot Framework integration tests for CLI formatting consistency, and CHANGELOG entry. ISSUES CLOSED: #210
190 lines
5.3 KiB
Python
190 lines
5.3 KiB
Python
"""ASV benchmarks for CLI output rendering overhead (issue #210).
|
|
|
|
Measures render_detail, render_list, render_error, and render_success
|
|
across all six output formats.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import importlib
|
|
import io
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
_SRC = str(Path(__file__).resolve().parents[1] / "src")
|
|
if _SRC not in sys.path:
|
|
sys.path.insert(0, _SRC)
|
|
|
|
import cleveragents # noqa: E402
|
|
|
|
importlib.reload(cleveragents)
|
|
|
|
from rich.console import Console # noqa: E402
|
|
|
|
import cleveragents.cli.renderers as _renderers_mod # noqa: E402
|
|
from cleveragents.cli.renderers import ( # noqa: E402
|
|
ColumnSpec,
|
|
render_detail,
|
|
render_error,
|
|
render_list,
|
|
render_success,
|
|
)
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Shared sample data
|
|
# ---------------------------------------------------------------------------
|
|
|
|
_DETAIL_DATA = {
|
|
"name": "bench-item",
|
|
"count": 42,
|
|
"active": True,
|
|
"description": "A benchmark test item for measuring renderer overhead",
|
|
}
|
|
|
|
_LIST_COLUMNS = [
|
|
ColumnSpec(key="name", label="Name"),
|
|
ColumnSpec(key="value", label="Value"),
|
|
ColumnSpec(key="status", label="Status"),
|
|
]
|
|
|
|
_LIST_ROWS_10 = [
|
|
{
|
|
"name": f"item-{i}",
|
|
"value": i * 10,
|
|
"status": "active" if i % 2 == 0 else "inactive",
|
|
}
|
|
for i in range(10)
|
|
]
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Console buffer helpers
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
def _install_buffer_consoles() -> None:
|
|
"""Replace module-level consoles with buffer-backed instances."""
|
|
_renderers_mod._console = Console(
|
|
file=io.StringIO(), no_color=True, highlight=False
|
|
)
|
|
_renderers_mod._err_console = Console(
|
|
file=io.StringIO(), no_color=True, highlight=False
|
|
)
|
|
|
|
|
|
def _reset_buffers() -> None:
|
|
"""Seek to start and truncate the console buffers between iterations."""
|
|
for attr in ("_console", "_err_console"):
|
|
console = getattr(_renderers_mod, attr)
|
|
if console is not None and hasattr(console, "file"):
|
|
console.file.seek(0)
|
|
console.file.truncate()
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# RenderDetailSuite
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
class RenderDetailSuite:
|
|
"""Benchmark render_detail across formats."""
|
|
|
|
def setup(self) -> None:
|
|
_install_buffer_consoles()
|
|
|
|
def teardown(self) -> None:
|
|
_renderers_mod._console = None
|
|
_renderers_mod._err_console = None
|
|
|
|
def time_render_detail_json(self) -> None:
|
|
_reset_buffers()
|
|
render_detail(_DETAIL_DATA, fmt="json")
|
|
|
|
def time_render_detail_yaml(self) -> None:
|
|
_reset_buffers()
|
|
render_detail(_DETAIL_DATA, fmt="yaml")
|
|
|
|
def time_render_detail_plain(self) -> None:
|
|
_reset_buffers()
|
|
render_detail(_DETAIL_DATA, fmt="plain")
|
|
|
|
def time_render_detail_rich(self) -> None:
|
|
_reset_buffers()
|
|
render_detail(_DETAIL_DATA, fmt="rich")
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# RenderListSuite
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
class RenderListSuite:
|
|
"""Benchmark render_list across formats."""
|
|
|
|
def setup(self) -> None:
|
|
_install_buffer_consoles()
|
|
|
|
def teardown(self) -> None:
|
|
_renderers_mod._console = None
|
|
_renderers_mod._err_console = None
|
|
|
|
def time_render_list_json_10_rows(self) -> None:
|
|
_reset_buffers()
|
|
render_list(_LIST_ROWS_10, columns=_LIST_COLUMNS, fmt="json")
|
|
|
|
def time_render_list_plain_10_rows(self) -> None:
|
|
_reset_buffers()
|
|
render_list(_LIST_ROWS_10, columns=_LIST_COLUMNS, fmt="plain")
|
|
|
|
def time_render_list_rich_10_rows(self) -> None:
|
|
_reset_buffers()
|
|
render_list(_LIST_ROWS_10, columns=_LIST_COLUMNS, fmt="rich")
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# RenderErrorSuite
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
class RenderErrorSuite:
|
|
"""Benchmark render_error across formats."""
|
|
|
|
def setup(self) -> None:
|
|
_install_buffer_consoles()
|
|
|
|
def teardown(self) -> None:
|
|
_renderers_mod._console = None
|
|
_renderers_mod._err_console = None
|
|
|
|
def time_render_error_rich(self) -> None:
|
|
_reset_buffers()
|
|
render_error("BenchError", "something went wrong", fmt="rich")
|
|
|
|
def time_render_error_json(self) -> None:
|
|
_reset_buffers()
|
|
render_error("BenchError", "something went wrong", fmt="json")
|
|
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# RenderSuccessSuite
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
class RenderSuccessSuite:
|
|
"""Benchmark render_success across formats."""
|
|
|
|
def setup(self) -> None:
|
|
_install_buffer_consoles()
|
|
|
|
def teardown(self) -> None:
|
|
_renderers_mod._console = None
|
|
_renderers_mod._err_console = None
|
|
|
|
def time_render_success_rich(self) -> None:
|
|
_reset_buffers()
|
|
render_success("Benchmark complete", fmt="rich")
|
|
|
|
def time_render_success_plain(self) -> None:
|
|
_reset_buffers()
|
|
render_success("Benchmark complete", fmt="plain")
|