Coverage for apio/commands/apio_test.py: 100%
29 statements
« prev ^ index » next coverage.py v7.16.1, created at 2026-09-23 03:53 +0000
« prev ^ index » next coverage.py v7.16.1, created at 2026-09-23 03:53 +0000
1# -*- coding: utf-8 -*-
2# -- This file is part of the Apio project
3# -- (C) 2016-2024 FPGAwars
4# -- Authors
5# -- * Jesús Arroyo (2016-2019)
6# -- * Juan Gonzalez (obijuan) (2019-2024)
7# -- License GPLv2
8"""Implementation of 'apio test' command"""
10import sys
11from pathlib import Path
12import click
13from apio.common.apio_console import cout
14from apio.common.apio_styles import EMPH1
15from apio.managers.scons_manager import SConsManager
16from apio.commands import options
17from apio.common.proto.apio_scons_pb2 import ApioTestParams
18from apio.utils import cmd_util
19from apio.apio_context import (
20 ApioContext,
21 PackagesPolicy,
22 ProjectPolicy,
23 RemoteConfigPolicy,
24)
27# --------- apio test
30# -- Text in the rich-text format of the python rich library.
31APIO_TEST_HELP = """
32The command 'apio test' simulates one or all the testbenches in the project \
33and is useful for automated testing of your design. Testbenches are expected \
34to have names ending with _tb (e.g., my_module_tb.v) and should exit with the \
35'$fatal' directive if an error is detected.
37Examples:[code]
38 apio test # Run all *_tb.v and *_tb.sv testbenches.
39 apio test my_module_tb.v # Run a single testbench.
40 apio test my_module_tb.sv # Run a single System Verilog testbench.
41 apio test util/led_tb.v # Run a testbench in a sub-folder.
42 apio test --default # Run only the default testbench.[/code]
44[NOTE] Testbench specification is always the testbench file path relative to \
45the project directory, even if using the '--project-dir' option.
47[IMPORTANT] Do not call the Verilog '$dumpfile()' function in your \
48testbenches: Apio treats it as a fatal error because it would override \
49the default name and location Apio sets for the generated .vcd file.
51The default testbench is the same that is used by the 'apio sim' command \
52which is the one specified in 'apio.ini' using the 'default-testbench' \
53option, or the only testbench, if the project contains exactly one \
54testbnech.
56For a sample testbench compatible with Apio features, see: \
57https://github.com/FPGAwars/apio-examples/tree/master/upduino31/testbench
59[b][Hint][/b] To simulate a testbench with a graphical visualization \
60of the signals, refer to the 'apio sim' command.
61"""
63option_default = click.option(
64 "default",
65 "-d",
66 "--default",
67 is_flag=True,
68 help="Test only the default testbench",
69 cls=cmd_util.ApioOption,
70)
73@click.command(
74 name="test",
75 cls=cmd_util.ApioCommand,
76 short_help="Test all or a single verilog testbench module.",
77 help=APIO_TEST_HELP,
78)
79@click.pass_context
80@click.argument(
81 "testbench-path",
82 metavar="[TESTBENCH-PATH]",
83 nargs=1,
84 required=False,
85)
86@option_default
87@options.env_option_gen()
88@options.project_dir_option
89def cli(
90 cmd_ctx: click.Context,
91 *,
92 # Arguments
93 testbench_path: str,
94 # Options
95 default: bool,
96 env: str | None,
97 project_dir: Path | None,
98):
99 """Implements the test command."""
101 cmd_util.check_at_most_one_param(cmd_ctx, ["default", "testbench_path"])
103 # -- Create the apio context.
104 apio_ctx = ApioContext(
105 project_policy=ProjectPolicy.PROJECT_REQUIRED,
106 remote_config_policy=RemoteConfigPolicy.CACHED_OK,
107 packages_policy=PackagesPolicy.ENSURE_PACKAGES,
108 project_dir_arg=project_dir,
109 env_arg=env,
110 )
112 # -- Create the scons manager.
113 scons = SConsManager(apio_ctx)
115 # -- If default is specified, try to get the default file from apio.ini,
116 # -- note that if that is not define, we pass this command invocation
117 # -- anyway to scons, in case there is exactly one testbench file.
118 if default:
119 # -- If the option is not specified, testbench is set to None and
120 # -- we issue an error message in the scons process.
121 testbench_path = apio_ctx.project.get_str_option(
122 "default-testbench", None
123 )
124 if testbench_path:
125 cout(f"Using default testbench: {testbench_path}", style=EMPH1)
127 # -- Construct the test params
128 test_params = ApioTestParams(
129 testbench_path=testbench_path if testbench_path else None,
130 default_option=default,
131 )
133 exit_code = scons.test(test_params)
134 sys.exit(exit_code)