Coverage for tests/unit_tests/commands/test_apio_raw.py: 100%
81 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"""Test for the "apio raw" command."""
3import os
4import sys
5import re
6from tests.conftest import ApioRunner
7from apio.commands.apio import apio_top_cli as apio
10def test_raw(apio_runner: ApioRunner):
11 """Test "apio raw" with different parameters"""
13 with apio_runner.in_sandbox() as sb:
15 # -- NOTE: We run the apio raw command in a sub process to have a
16 # -- proper sys.argv for it for the '--' separator validation.
18 # -- Execute "apio raw"
19 result = sb.invoke_apio_cmd(apio, ["raw"], in_subprocess=True)
20 assert result.exit_code != 0, result.output
21 assert (
22 "at least one of --verbose or COMMAND must be specified"
23 in result.output
24 )
26 # -- Execute "apio raw -v"
27 result = sb.invoke_apio_cmd(apio, ["raw", "-v"], in_subprocess=True)
28 sb.assert_result_ok(result)
29 assert "Environment settings:" in result.output
30 assert "PATH" in result.output
31 assert "VERILATOR_ROOT" in result.output
33 # -- Run 'apio raw -- echo hello'.
34 result = sb.invoke_apio_cmd(
35 apio, ["raw", "--", "echo", "hello"], in_subprocess=True
36 )
37 sb.assert_result_ok(result, bad_words=[])
38 assert "hello" in result.output
40 # -- Run a command without the required '--'
41 result = sb.invoke_apio_cmd(apio, ["raw", "echo"], in_subprocess=True)
42 assert result.exit_code != 0, result.output
43 assert "command separator '--' was not found" in result.output
45 # -- Run a command with a token before the '--' separator.
46 result = sb.invoke_apio_cmd(
47 apio, ["raw", "echo", "--", "--help"], in_subprocess=True
48 )
49 assert result.exit_code != 0, result.output
50 assert "Invalid arguments: ['echo']" in result.output
52 # -- Run 'apio raw -v'
53 result = sb.invoke_apio_cmd(apio, ["raw", "-v"], in_subprocess=True)
54 sb.assert_result_ok(result)
55 assert "Environment settings:" in result.output
56 assert "VERILATOR_ROOT" in result.output
59def test_raw_preserves_argv_and_cwd(apio_runner: ApioRunner):
60 """Tests that 'apio raw' passes the wrapped command's arguments
61 verbatim as an argv list (no re-splitting at spaces, no quote
62 mangling) and runs it in the caller's current directory. This is
63 a regression test for a Windows bug where the args were joined with
64 POSIX quoting and re-tokenized by cmd.exe, breaking paths with
65 spaces or backslashes."""
67 with apio_runner.in_sandbox() as sb:
69 # -- A probe command that reports its cwd and its argv, one
70 # -- element per line. Note that the sandbox's current directory
71 # -- ('apio proj') contains a space.
72 probe = (
73 "import os, sys; "
74 "print('PROBE-CWD=<' + os.getcwd() + '>'); "
75 "[print('PROBE-ARG-%d=<%s>' % (i, a)) "
76 "for i, a in enumerate(sys.argv[1:])]"
77 )
79 result = sb.invoke_apio_cmd(
80 apio,
81 [
82 "raw",
83 "--",
84 sys.executable,
85 "-c",
86 probe,
87 "a b c.txt",
88 r"_build\default\hardware.bit",
89 ],
90 in_subprocess=True,
91 )
92 sb.assert_result_ok(result, bad_words=[])
94 # -- The wrapped command must inherit the caller's cwd.
95 assert f"PROBE-CWD=<{os.getcwd()}>" in result.output
97 # -- An arg with spaces must arrive as a single argv element.
98 assert "PROBE-ARG-0=<a b c.txt>" in result.output
100 # -- An arg with backslashes must arrive verbatim, without
101 # -- added quotes.
102 assert "PROBE-ARG-1=<_build\\default\\hardware.bit>" in result.output
104 # -- There must be no extra args from re-splitting.
105 assert "PROBE-ARG-2" not in result.output
108def test_raw_icepll(apio_runner: ApioRunner):
109 """Tests that the icepll raw command works"""
111 with apio_runner.in_sandbox() as sb:
113 # -- Run 'apio raw -- icepll -i 20 -i 60 -m -f pll.v'
114 result = sb.invoke_apio_cmd(
115 apio,
116 [
117 "raw",
118 "--",
119 "icepll",
120 "-i",
121 "20",
122 "-o",
123 "60",
124 "-m",
125 "-f",
126 "pll.v",
127 ],
128 in_subprocess=True,
129 )
130 print(result.output)
131 sb.assert_result_ok(result)
132 module = sb.read_file_text("pll.v")
133 print(module)
135 assert "module pll" in module
136 assert "SB_PLL40_CORE" in module
137 assert re.search(r"Achieved.+60.000", module)
138 assert "endmodule" in module
141def test_raw_ecppll(apio_runner: ApioRunner):
142 """Tests that the ecppll raw command works"""
144 with apio_runner.in_sandbox() as sb:
146 # -- Run 'apio raw -- ecppll -i 25 -o 120 -f ecppll.v'
147 result = sb.invoke_apio_cmd(
148 apio,
149 ["raw", "--", "ecppll", "-i", "20", "-o", "60", "-f", "pll.v"],
150 in_subprocess=True,
151 )
152 print(result.output)
153 sb.assert_result_ok(result)
154 module = sb.read_file_text("pll.v")
155 print(module)
157 assert "module pll" in module
158 assert "EHXPLLL" in module
159 assert re.search(r"clkout0.+60 MHz", module)
160 assert "endmodule" in module
163def test_raw_gowin_pll(apio_runner: ApioRunner):
164 """Tests that the gowin_pll raw command works"""
166 with apio_runner.in_sandbox() as sb:
168 # -- Run the command
169 # 'apio raw -- gowin_pll -d "GW1NR-LV9QN88PC6/I5"
170 # -i 27 -o 75 -f pll.v'
171 result = sb.invoke_apio_cmd(
172 apio,
173 [
174 "raw",
175 "--",
176 "gowin_pll",
177 "-d",
178 '"GW1NR-LV9QN88PC6/I5"',
179 "-i",
180 "20",
181 "-o",
182 "60",
183 "-f",
184 "pll.v",
185 ],
186 in_subprocess=True,
187 )
188 print(result.output)
189 sb.assert_result_ok(result)
190 module = sb.read_file_text("pll.v")
191 print(module)
193 assert "module pll" in module
194 assert "rPLL" in module
195 assert re.search(r"Achieved.+60.000", module)
196 assert "endmodule" in module
199def test_raw_xc7pll(apio_runner: ApioRunner):
200 """Tests that the xc7pll raw command works"""
202 with apio_runner.in_sandbox() as sb:
204 # -- Run 'apio raw -- xc7pll -i 100 -o 200 -f pll.v'
205 result = sb.invoke_apio_cmd(
206 apio,
207 [
208 "raw",
209 "--",
210 "xc7pll",
211 "-i",
212 "100",
213 "-o",
214 "200",
215 "-f",
216 "pll.v",
217 ],
218 in_subprocess=True,
219 )
220 print(result.output)
221 sb.assert_result_ok(result)
222 module = sb.read_file_text("pll.v")
223 print(module)
225 assert "module pll" in module
226 assert "PLLE2_BASE" in module
227 assert "requested 200 MHz, exact" in module
228 assert "endmodule" in module