Coverage for apio / commands / apio_test.py: 100%

30 statements  

« prev     ^ index     » next       coverage.py v7.13.3, created at 2026-02-08 02:47 +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""" 

9 

10import sys 

11from typing import Optional 

12from pathlib import Path 

13import click 

14from apio.common.apio_console import cout 

15from apio.common.apio_styles import EMPH1 

16from apio.managers.scons_manager import SConsManager 

17from apio.commands import options 

18from apio.common.proto.apio_pb2 import ApioTestParams 

19from apio.utils import cmd_util 

20from apio.apio_context import ( 

21 ApioContext, 

22 PackagesPolicy, 

23 ProjectPolicy, 

24 RemoteConfigPolicy, 

25) 

26 

27 

28# --------- apio test 

29 

30 

31# -- Text in the rich-text format of the python rich library. 

32APIO_TEST_HELP = """ 

33The command 'apio test' simulates one or all the testbenches in the project \ 

34and is useful for automated testing of your design. Testbenches are expected \ 

35to have names ending with _tb (e.g., my_module_tb.v) and should exit with the \ 

36'$fatal' directive if an error is detected. 

37 

38Examples:[code] 

39 apio test # Run all *_tb.v and *_tb.sv testbenches. 

40 apio test my_module_tb.v # Run a single testbench. 

41 apio test my_module_tb.sv # Run a single System Verilog testbench. 

42 apio test util/led_tb.v # Run a testbench in a sub-folder. 

43 apio test --default # Run only the default testbench.[/code] 

44 

45[NOTE] Testbench specification is always the testbench file path relative to \ 

46the project directory, even if using the '--project-dir' option. 

47 

48[IMPORTANT] Do not use the Verilog '$dumpfile()' function in your \ 

49testbenches, as this may override the default name and location Apio sets \ 

50for the generated .vcd file. 

51 

52The default testbench is the same that is used by the 'apio sim' command \ 

53which is the one specified in 'apio.ini' using the 'default-testbench' \ 

54option, or the only testbench, if the project contains exactly one \ 

55testbnech. 

56 

57For a sample testbench compatible with Apio features, see: \ 

58https://github.com/FPGAwars/apio-examples/tree/master/upduino31/testbench 

59 

60[b][Hint][/b] To simulate a testbench with a graphical visualization \ 

61of the signals, refer to the 'apio sim' command. 

62""" 

63 

64option_default = click.option( 

65 "default", 

66 "-d", 

67 "--default", 

68 is_flag=True, 

69 help="Test only the default testbench", 

70 cls=cmd_util.ApioOption, 

71) 

72 

73 

74@click.command( 

75 name="test", 

76 cls=cmd_util.ApioCommand, 

77 short_help="Test all or a single verilog testbench module.", 

78 help=APIO_TEST_HELP, 

79) 

80@click.pass_context 

81@click.argument( 

82 "testbench-path", 

83 metavar="[TESTBENCH-PATH]", 

84 nargs=1, 

85 required=False, 

86) 

87@option_default 

88@options.env_option_gen() 

89@options.project_dir_option 

90def cli( 

91 cmd_ctx: click.Context, 

92 # Arguments 

93 testbench_path: str, 

94 # Options 

95 default: bool, 

96 env: Optional[str], 

97 project_dir: Optional[Path], 

98): 

99 """Implements the test command.""" 

100 

101 cmd_util.check_at_most_one_param(cmd_ctx, ["default", "testbench_path"]) 

102 

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 ) 

111 

112 # -- Create the scons manager. 

113 scons = SConsManager(apio_ctx) 

114 

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) 

126 

127 # -- Construct the test params 

128 test_params = ApioTestParams( 

129 testbench_path=testbench_path if testbench_path else None, 

130 default_option=default, 

131 ) 

132 

133 exit_code = scons.test(test_params) 

134 sys.exit(exit_code)