Coverage for tests/unit_tests/commands/test_apio_raw.py: 100%
81 statements
« prev ^ index » next coverage.py v7.17.2, created at 2026-11-07 05:08 +0000
« prev ^ index » next coverage.py v7.17.2, created at 2026-11-07 05:08 +0000
1# This file is part of the Apio project
2# (C) 2016-present FPGAwars
3# Project authors:
4# * Jesús Arroyo (Jesus89) (2016-2019)
5# * Juan Gonzalez (obijuan) (2019-2024)
6# * The Apio Team (2024-present)
7# License: GPLv2
9"""Test for the "apio raw" command."""
11import os
12import sys
13import re
14from tests.conftest import ApioRunner
15from apio.commands.apio import apio_top_cli as apio
18def test_raw(apio_runner: ApioRunner):
19 """Test "apio raw" with different parameters"""
21 with apio_runner.in_sandbox() as sb:
23 # -- NOTE: We run the apio raw command in a sub process to have a
24 # -- proper sys.argv for it for the '--' separator validation.
26 # -- Execute "apio raw"
27 result = sb.invoke_apio_cmd(apio, ["raw"], in_subprocess=True)
28 assert result.exit_code != 0, result.output
29 assert (
30 "at least one of --verbose or COMMAND must be specified"
31 in result.output
32 )
34 # -- Execute "apio raw -v"
35 result = sb.invoke_apio_cmd(apio, ["raw", "-v"], in_subprocess=True)
36 sb.assert_result_ok(result)
37 assert "Environment settings:" in result.output
38 assert "PATH" in result.output
39 assert "VERILATOR_ROOT" in result.output
41 # -- Run 'apio raw -- echo hello'.
42 result = sb.invoke_apio_cmd(
43 apio, ["raw", "--", "echo", "hello"], in_subprocess=True
44 )
45 sb.assert_result_ok(result, bad_words=[])
46 assert "hello" in result.output
48 # -- Run a command without the required '--'
49 result = sb.invoke_apio_cmd(apio, ["raw", "echo"], in_subprocess=True)
50 assert result.exit_code != 0, result.output
51 assert "command separator '--' was not found" in result.output
53 # -- Run a command with a token before the '--' separator.
54 result = sb.invoke_apio_cmd(
55 apio, ["raw", "echo", "--", "--help"], in_subprocess=True
56 )
57 assert result.exit_code != 0, result.output
58 assert "Invalid arguments: ['echo']" in result.output
60 # -- Run 'apio raw -v'
61 result = sb.invoke_apio_cmd(apio, ["raw", "-v"], in_subprocess=True)
62 sb.assert_result_ok(result)
63 assert "Environment settings:" in result.output
64 assert "VERILATOR_ROOT" in result.output
67def test_raw_preserves_argv_and_cwd(apio_runner: ApioRunner):
68 """Tests that 'apio raw' passes the wrapped command's arguments
69 verbatim as an argv list (no re-splitting at spaces, no quote
70 mangling) and runs it in the caller's current directory. This is
71 a regression test for a Windows bug where the args were joined with
72 POSIX quoting and re-tokenized by cmd.exe, breaking paths with
73 spaces or backslashes."""
75 with apio_runner.in_sandbox() as sb:
77 # -- A probe command that reports its cwd and its argv, one
78 # -- element per line. Note that the sandbox's current directory
79 # -- ('apio proj') contains a space.
80 probe = (
81 "import os, sys; "
82 "print('PROBE-CWD=<' + os.getcwd() + '>'); "
83 "[print('PROBE-ARG-%d=<%s>' % (i, a)) "
84 "for i, a in enumerate(sys.argv[1:])]"
85 )
87 result = sb.invoke_apio_cmd(
88 apio,
89 [
90 "raw",
91 "--",
92 sys.executable,
93 "-c",
94 probe,
95 "a b c.txt",
96 r"_build\default\hardware.bit",
97 ],
98 in_subprocess=True,
99 )
100 sb.assert_result_ok(result, bad_words=[])
102 # -- The wrapped command must inherit the caller's cwd.
103 assert f"PROBE-CWD=<{os.getcwd()}>" in result.output
105 # -- An arg with spaces must arrive as a single argv element.
106 assert "PROBE-ARG-0=<a b c.txt>" in result.output
108 # -- An arg with backslashes must arrive verbatim, without
109 # -- added quotes.
110 assert "PROBE-ARG-1=<_build\\default\\hardware.bit>" in result.output
112 # -- There must be no extra args from re-splitting.
113 assert "PROBE-ARG-2" not in result.output
116def test_raw_icepll(apio_runner: ApioRunner):
117 """Tests that the icepll raw command works"""
119 with apio_runner.in_sandbox() as sb:
121 # -- Run 'apio raw -- icepll -i 20 -i 60 -m -f pll.v'
122 result = sb.invoke_apio_cmd(
123 apio,
124 [
125 "raw",
126 "--",
127 "icepll",
128 "-i",
129 "20",
130 "-o",
131 "60",
132 "-m",
133 "-f",
134 "pll.v",
135 ],
136 in_subprocess=True,
137 )
138 print(result.output)
139 sb.assert_result_ok(result)
140 module = sb.read_file_text("pll.v")
141 print(module)
143 assert "module pll" in module
144 assert "SB_PLL40_CORE" in module
145 assert re.search(r"Achieved.+60.000", module)
146 assert "endmodule" in module
149def test_raw_ecppll(apio_runner: ApioRunner):
150 """Tests that the ecppll raw command works"""
152 with apio_runner.in_sandbox() as sb:
154 # -- Run 'apio raw -- ecppll -i 25 -o 120 -f ecppll.v'
155 result = sb.invoke_apio_cmd(
156 apio,
157 ["raw", "--", "ecppll", "-i", "20", "-o", "60", "-f", "pll.v"],
158 in_subprocess=True,
159 )
160 print(result.output)
161 sb.assert_result_ok(result)
162 module = sb.read_file_text("pll.v")
163 print(module)
165 assert "module pll" in module
166 assert "EHXPLLL" in module
167 assert re.search(r"clkout0.+60 MHz", module)
168 assert "endmodule" in module
171def test_raw_gowin_pll(apio_runner: ApioRunner):
172 """Tests that the gowin_pll raw command works"""
174 with apio_runner.in_sandbox() as sb:
176 # -- Run the command
177 # 'apio raw -- gowin_pll -d "GW1NR-LV9QN88PC6/I5"
178 # -i 27 -o 75 -f pll.v'
179 result = sb.invoke_apio_cmd(
180 apio,
181 [
182 "raw",
183 "--",
184 "gowin_pll",
185 "-d",
186 '"GW1NR-LV9QN88PC6/I5"',
187 "-i",
188 "20",
189 "-o",
190 "60",
191 "-f",
192 "pll.v",
193 ],
194 in_subprocess=True,
195 )
196 print(result.output)
197 sb.assert_result_ok(result)
198 module = sb.read_file_text("pll.v")
199 print(module)
201 assert "module pll" in module
202 assert "rPLL" in module
203 assert re.search(r"Achieved.+60.000", module)
204 assert "endmodule" in module
207def test_raw_xc7pll(apio_runner: ApioRunner):
208 """Tests that the xc7pll raw command works"""
210 with apio_runner.in_sandbox() as sb:
212 # -- Run 'apio raw -- xc7pll -i 100 -o 200 -f pll.v'
213 result = sb.invoke_apio_cmd(
214 apio,
215 [
216 "raw",
217 "--",
218 "xc7pll",
219 "-i",
220 "100",
221 "-o",
222 "200",
223 "-f",
224 "pll.v",
225 ],
226 in_subprocess=True,
227 )
228 print(result.output)
229 sb.assert_result_ok(result)
230 module = sb.read_file_text("pll.v")
231 print(module)
233 assert "module pll" in module
234 assert "PLLE2_BASE" in module
235 assert "requested 200 MHz, exact" in module
236 assert "endmodule" in module