CIRCT 23.0.0git
Loading...
Searching...
No Matches
Classes | Functions | Variables
pytest Namespace Reference

Classes

class  _ChildResult
 
class  _ClassCompileCache
 
class  CosimPytestConfig
 

Functions

bool _get_env_bool (str var_name, bool default)
 
Optional[Path] _get_env_path (str var_name)
 
str _get_pytest_run_id ()
 
Optional[str] _get_xdist_worker_id ()
 
str _get_test_dir_name (CosimPytestConfig config)
 
 _chdir (Path path)
 
bool _line_matches (LogMatcher matcher, str line, str stream)
 
tuple[list[str], list[str]] _scan_logs (Sequence[str] stdout_lines, Sequence[str] stderr_lines, CosimPytestConfig config)
 
list[str] _render_args (Sequence[str] args, Path tmp_dir)
 
Path _generate_sources (CosimPytestConfig config, Path tmp_dir)
 
Simulator _create_simulator (CosimPytestConfig config, Path sources_dir, Path run_dir)
 
Path _run_hw_script (Union[str, Path] script_path, CosimPytestConfig config, Path tmp_dir)
 
bool _is_injected_param (str name, Any annotation)
 
Dict[str, Any] _resolve_injected_params (Callable[..., Any] target, Dict[str, Any] kwargs, str host, int port, Optional[Path] sources_dir=None)
 
inspect.Signature _visible_signature (Callable[..., Any] target)
 
 _copy_compiled_artifacts (Optional[Path] compile_dir, Path run_dir)
 
_ClassCompileCache _compile_once_for_class (CosimPytestConfig config)
 
 _run_child (multiprocessing.connection.Connection result_pipe, Callable[..., Any] target, CosimPytestConfig config, Sequence[Any] args, Dict[str, Any] kwargs, Optional[_ClassCompileCache] class_cache)
 
 _run_isolated (Callable[..., Any] target, CosimPytestConfig config, Sequence[Any] args, Dict[str, Any] kwargs, Optional[_ClassCompileCache] class_cache=None)
 
Callable[..., Any] _decorate_function (Callable[..., Any] target, CosimPytestConfig config, Optional[Callable[[], _ClassCompileCache]] class_cache_getter=None)
 
type _decorate_class (type target_cls, CosimPytestConfig config)
 
 cosim_test (SourceGeneratorArg source_generator, Sequence[str] args=("{tmp_dir}",), str simulator="verilator", str top="ESI_Cosim_Top", Optional[bool] debug=None, float timeout_s=_DEFAULT_TIMEOUT_S, Optional[LogMatcher] failure_matcher=_DEFAULT_FAILURE_PATTERN, Optional[LogMatcher] warning_matcher=_DEFAULT_WARN_PATTERN, Optional[Path] tmp_dir_root=None, Optional[bool] delete_tmp_dir=None, Optional[bool] save_waveform=None)
 

Variables

 LogMatcher = Union[str, Pattern[str], Callable[[str, str], bool]]
 
 SourceGeneratorFunc = Callable[["CosimPytestConfig", Path], Path]
 
 SourceGeneratorArg = Union[str, Path, SourceGeneratorFunc]
 
 _logger = logging.getLogger("esiaccel.cosim.pytest")
 
 _DEFAULT_FAILURE_PATTERN = re.compile(r"\berror\b", re.IGNORECASE)
 
 _DEFAULT_WARN_PATTERN = re.compile(r"\bwarn(ing)?\b", re.IGNORECASE)
 
float _DEFAULT_TIMEOUT_S = 120.0
 
dict _INJECTED_NAMES
 
 _INJECTED_ANNOTATIONS = frozenset({Accelerator, AcceleratorConnection})
 

Detailed Description

Pytest integration for ESI cosimulation tests.

Provides the ``@cosim_test`` decorator which automates the full lifecycle of a
cosimulation test: running a PyCDE hardware script, compiling the design with
a simulator (e.g. Verilator), launching the simulator, injecting connection
parameters into the test function, and tearing everything down afterwards.

Decorated functions run in an isolated child process (via ``fork``) so that
simulator state never leaks between tests.  When applied to a class, the
hardware compilation is performed once and shared across all ``test_*`` methods.

Typical usage::

    from esiaccel.cosim.pytest import cosim_test

    @cosim_test("path/to/hw_script.py")
    def test_my_design(conn: AcceleratorConnection):
        # conn is already connected to the running simulator
        ...

Function Documentation

◆ _chdir()

pytest._chdir ( Path  path)
protected
Context manager that temporarily changes the working directory.

Definition at line 201 of file pytest.py.

Referenced by _compile_once_for_class(), and _run_hw_script().

◆ _compile_once_for_class()

_ClassCompileCache pytest._compile_once_for_class ( CosimPytestConfig  config)
protected
Run the hw script and compile the simulator once for a whole test class.

The resulting ``_ClassCompileCache`` is reused by each test method to avoid
redundant compilations.

Definition at line 397 of file pytest.py.

References _chdir(), _create_simulator(), _generate_sources(), and _get_test_dir_name().

Referenced by _decorate_class().

◆ _copy_compiled_artifacts()

pytest._copy_compiled_artifacts ( Optional[Path]  compile_dir,
Path  run_dir 
)
protected
Copy pre-compiled simulator artifacts into the per-test run directory.

Copies the *entire* compile directory so that all backends (Verilator,
Questa, etc.) find their artefacts regardless of internal layout.

Definition at line 380 of file pytest.py.

Referenced by _run_child().

◆ _create_simulator()

Simulator pytest._create_simulator ( CosimPytestConfig  config,
Path  sources_dir,
Path  run_dir 
)
protected
Instantiate a ``Simulator`` from the generated source files.

Definition at line 272 of file pytest.py.

Referenced by _compile_once_for_class(), and _run_child().

◆ _decorate_class()

type pytest._decorate_class ( type  target_cls,
CosimPytestConfig  config 
)
protected
Wrap every ``test_*`` method of a class with cosim isolation.

Compilation is performed once (lazily, on first method invocation) and
the resulting artifacts are shared across all methods via a thread-safe
cache.

Definition at line 619 of file pytest.py.

References _compile_once_for_class(), and _decorate_function().

Referenced by cosim_test().

◆ _decorate_function()

Callable[..., Any] pytest._decorate_function ( Callable[..., Any]  target,
CosimPytestConfig  config,
Optional[Callable[[], _ClassCompileCache]]   class_cache_getter = None 
)
protected
Wrap a single test function so it runs inside ``_run_isolated``.

Definition at line 601 of file pytest.py.

References _run_isolated(), and _visible_signature().

Referenced by _decorate_class(), and cosim_test().

◆ _generate_sources()

Path pytest._generate_sources ( CosimPytestConfig  config,
Path  tmp_dir 
)
protected
Generate hardware sources via a normalized source-generator callable.

If ``config.source_generator`` is a string/path, it is wrapped into a callable
that runs the PyCDE script. If it is already callable, it is used directly.

Definition at line 256 of file pytest.py.

References _run_hw_script().

Referenced by _compile_once_for_class(), and _run_child().

◆ _get_env_bool()

bool pytest._get_env_bool ( str  var_name,
bool  default 
)
protected
Read a boolean environment variable.

Args:
  var_name: Name of the environment variable to read.
  default: Default value if the variable is not set.

Returns:
  The boolean value of the environment variable, or the default value.

Definition at line 62 of file pytest.py.

Referenced by cosim_test().

◆ _get_env_path()

Optional[Path] pytest._get_env_path ( str  var_name)
protected
Read a path environment variable.

Args:
  var_name: Name of the environment variable to read.

Returns:
  The path value of the environment variable, or None if not set.

Definition at line 78 of file pytest.py.

Referenced by cosim_test().

◆ _get_pytest_run_id()

str pytest._get_pytest_run_id ( )
protected
Get a unique identifier for this pytest invocation.

For normal runs, uses the current process PID (the pytest process itself).
For xdist workers, uses the parent PID (the main pytest controller) so that
all workers share the same top-level run directory.

Definition at line 91 of file pytest.py.

Referenced by cosim_test().

◆ _get_test_dir_name()

str pytest._get_test_dir_name ( CosimPytestConfig  config)
protected
Build a test directory path including pytest run ID and xdist worker (if present).

For class-based tests with xdist: "pytest-{pid}/gw{n}/ClassName/test_method".
For class-based tests without xdist: "pytest-{pid}/ClassName/test_method".
For function tests with xdist: "pytest-{pid}/gw{n}/test_function".
For function tests without xdist: "pytest-{pid}/test_function".

Definition at line 112 of file pytest.py.

Referenced by _compile_once_for_class(), and _run_child().

◆ _get_xdist_worker_id()

Optional[str] pytest._get_xdist_worker_id ( )
protected
Get the xdist worker ID if running under pytest-xdist.

Returns the worker ID (e.g., "gw0", "gw1") or None if not using xdist.

Definition at line 104 of file pytest.py.

Referenced by cosim_test().

◆ _is_injected_param()

bool pytest._is_injected_param ( str  name,
Any  annotation 
)
protected
Return True if *name*/*annotation* will be supplied by the decorator.

Definition at line 325 of file pytest.py.

Referenced by _visible_signature().

◆ _line_matches()

bool pytest._line_matches ( LogMatcher  matcher,
str  line,
str  stream 
)
protected
Return True if *line* matches the given matcher.

The matcher may be a plain string (regex search), a compiled regex,
or a callable ``(line, stream) -> bool``.

Definition at line 211 of file pytest.py.

Referenced by _scan_logs().

◆ _render_args()

list[str] pytest._render_args ( Sequence[str]  args,
Path  tmp_dir 
)
protected
Interpolate ``{tmp_dir}`` placeholders in script arguments.

Definition at line 251 of file pytest.py.

Referenced by _run_hw_script().

◆ _resolve_injected_params()

Dict[str, Any] pytest._resolve_injected_params ( Callable[..., Any]  target,
Dict[str, Any]  kwargs,
str  host,
int  port,
Optional[Path]   sources_dir = None 
)
protected
Build the keyword arguments to inject into the test function.

Inspects the target's signature and automatically supplies ``host``,
``port``, ``sources_dir``, ``AcceleratorConnection``, or ``Accelerator``
parameters that the test declares but the caller did not provide.

Definition at line 330 of file pytest.py.

References esiaccel.connect().

Referenced by _run_child().

◆ _run_child()

pytest._run_child ( multiprocessing.connection.Connection  result_pipe,
Callable[..., Any]  target,
CosimPytestConfig  config,
Sequence[Any]  args,
Dict[str, Any]  kwargs,
Optional[_ClassCompileCache class_cache 
)
protected
Entry point for the forked child process.

Compiles (or reuses cached compilation), starts the simulator, injects
connection parameters, calls the test function, scans logs for failures,
and sends a ``_ChildResult`` through *result_pipe*.

Definition at line 427 of file pytest.py.

References _copy_compiled_artifacts(), _create_simulator(), _generate_sources(), _get_test_dir_name(), _resolve_injected_params(), and _scan_logs().

◆ _run_hw_script()

Path pytest._run_hw_script ( Union[str, Path]  script_path,
CosimPytestConfig  config,
Path  tmp_dir 
)
protected
Execute the PyCDE hardware script and run codegen if a manifest exists.

Returns:
  The directory containing the generated sources (same as *tmp_dir*).

Definition at line 283 of file pytest.py.

References _chdir(), _render_args(), and resolve().

Referenced by _generate_sources().

◆ _run_isolated()

pytest._run_isolated ( Callable[..., Any]  target,
CosimPytestConfig  config,
Sequence[Any]  args,
Dict[str, Any]  kwargs,
Optional[_ClassCompileCache]   class_cache = None 
)
protected
Fork a child process to run *target* and wait for its result.

Handles timeouts, collects warnings, and re-raises any failure from
the child as an ``AssertionError`` in the parent.

Definition at line 538 of file pytest.py.

Referenced by _decorate_function().

◆ _scan_logs()

tuple[list[str], list[str]] pytest._scan_logs ( Sequence[str]  stdout_lines,
Sequence[str]  stderr_lines,
CosimPytestConfig  config 
)
protected
Scan simulator output for failures and warnings.

Returns:
  A ``(failures, warnings)`` tuple of tagged log lines.

Definition at line 225 of file pytest.py.

References _line_matches().

Referenced by _run_child().

◆ _visible_signature()

inspect.Signature pytest._visible_signature ( Callable[..., Any]  target)
protected
Return a signature with injected parameters removed.

Pytest uses function signatures to determine fixture requirements.  This
hides the parameters that the decorator injects (``host``, ``port``,
``conn``, etc.) so pytest does not try to resolve them as fixtures.
Uses :func:`_is_injected_param` as the single source of truth.

Definition at line 364 of file pytest.py.

References _is_injected_param().

Referenced by _decorate_function().

◆ cosim_test()

pytest.cosim_test ( SourceGeneratorArg  source_generator,
Sequence[str]   args = ("{tmp_dir}",),
str   simulator = "verilator",
str   top = "ESI_Cosim_Top",
Optional[bool]   debug = None,
float   timeout_s = _DEFAULT_TIMEOUT_S,
Optional[LogMatcher]   failure_matcher = _DEFAULT_FAILURE_PATTERN,
Optional[LogMatcher]   warning_matcher = _DEFAULT_WARN_PATTERN,
Optional[Path]   tmp_dir_root = None,
Optional[bool]   delete_tmp_dir = None,
Optional[bool]   save_waveform = None 
)
Decorator that turns a function or class into a cosimulation test.

The decorated target is executed in a forked child process with a freshly
compiled and running simulator.  Connection parameters (``host``, ``port``,
``acc``, etc.) are injected automatically based on the function signature.

When applied to a class, the hardware script is run and compiled once;
each ``test_*`` method gets its own simulator process but skips
recompilation.

Args:
  source_generator: Path to the PyCDE script that generates the hardware, or
    a callable ``(config, tmp_dir) -> sources_dir`` that generates
    sources directly.
  args: Arguments forwarded to the script; ``{tmp_dir}`` is interpolated
      with the temporary build directory.
  simulator: Simulator backend (default ``"verilator"``).
  top: Top-level module name.
  debug: Enable verbose simulator output. Defaults to the value of the
    ``ESIACCEL_PYTEST_DEBUG`` environment variable if set, otherwise False.
  timeout_s: Wall-clock timeout in seconds (default 120).
  failure_matcher: Pattern to detect errors in simulator output.
  warning_matcher: Pattern to detect warnings in simulator output.
  tmp_dir_root: Root directory for temporary test files. Defaults to the value
    of the ``ESIACCEL_PYTEST_TMP_DIR`` environment variable if set, otherwise
    uses the system temporary directory. Run directories are organized in a
    hierarchy to avoid collisions during parallel execution:

    - Normal run: ``pytest-{pid}/ClassName/test_method/`` or
      ``pytest-{pid}/test_function/``
    - xdist parallel: ``pytest-{pid}/gw0/ClassName/test_method/`` (gw0, gw1, etc.
      for different workers)
  delete_tmp_dir: Whether to delete temporary directories after test
    completion. When tmp_dir_root is set (custom debugging directory),
    directories are kept by default; set ``ESIACCEL_PYTEST_DELETE_TMP_DIR=true``
    to delete them. When using the system temp directory, defaults to True
    (delete to avoid clutter). Always False when debug mode is enabled.
  save_waveform: Whether to save waveform dumps (format depends on the
    simulator backend, e.g. FST for Verilator, VCD for Questa). Requires
    debug mode to be enabled. Defaults to the value of the
    ``ESIACCEL_PYTEST_SAVE_WAVEFORM`` environment variable if set, otherwise
    False.

Definition at line 649 of file pytest.py.

References _decorate_class(), _decorate_function(), _get_env_bool(), _get_env_path(), _get_pytest_run_id(), and _get_xdist_worker_id().

Variable Documentation

◆ _DEFAULT_FAILURE_PATTERN

pytest._DEFAULT_FAILURE_PATTERN = re.compile(r"\berror\b", re.IGNORECASE)
protected

Definition at line 55 of file pytest.py.

◆ _DEFAULT_TIMEOUT_S

float pytest._DEFAULT_TIMEOUT_S = 120.0
protected

Definition at line 59 of file pytest.py.

◆ _DEFAULT_WARN_PATTERN

pytest._DEFAULT_WARN_PATTERN = re.compile(r"\bwarn(ing)?\b", re.IGNORECASE)
protected

Definition at line 56 of file pytest.py.

◆ _INJECTED_ANNOTATIONS

pytest._INJECTED_ANNOTATIONS = frozenset({Accelerator, AcceleratorConnection})
protected

Definition at line 322 of file pytest.py.

◆ _INJECTED_NAMES

dict pytest._INJECTED_NAMES
protected
Initial value:
1= {
2 "host", "hostname", "port", "sources_dir", "conn", "accelerator"
3}

Definition at line 319 of file pytest.py.

◆ _logger

pytest._logger = logging.getLogger("esiaccel.cosim.pytest")
protected

Definition at line 54 of file pytest.py.

◆ LogMatcher

pytest.LogMatcher = Union[str, Pattern[str], Callable[[str, str], bool]]

Definition at line 50 of file pytest.py.

◆ SourceGeneratorArg

pytest.SourceGeneratorArg = Union[str, Path, SourceGeneratorFunc]

Definition at line 52 of file pytest.py.

◆ SourceGeneratorFunc

pytest.SourceGeneratorFunc = Callable[["CosimPytestConfig", Path], Path]

Definition at line 51 of file pytest.py.