Coverage for tests/unit_tests/commands/test_apio_raw.py: 100%
36 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-09 01:55 +0000
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-09 01:55 +0000
1"""Test for the "apio raw" command."""
3import os
4import sys
5from tests.conftest import ApioRunner
6from apio.commands.apio import apio_top_cli as apio
9def test_raw(apio_runner: ApioRunner):
10 """Test "apio raw" with different parameters"""
12 with apio_runner.in_sandbox() as sb:
14 # -- NOTE: We run the apio raw command in a sub process to have a
15 # -- proper sys.argv for it for the '--' separator validation.
17 # -- Execute "apio raw"
18 result = sb.invoke_apio_cmd(apio, ["raw"], in_subprocess=True)
19 assert result.exit_code != 0, result.output
20 assert (
21 "at least one of --verbose or COMMAND must be specified"
22 in result.output
23 )
25 # -- Execute "apio raw -v"
26 result = sb.invoke_apio_cmd(apio, ["raw", "-v"], in_subprocess=True)
27 sb.assert_result_ok(result)
28 assert "Environment settings:" in result.output
29 assert "PATH" in result.output
30 assert "YOSYS_LIB" in result.output
32 # -- Run 'apio raw -- echo hello'.
33 result = sb.invoke_apio_cmd(
34 apio, ["raw", "--", "echo", "hello"], in_subprocess=True
35 )
36 sb.assert_result_ok(result, bad_words=[])
37 assert "hello" in result.output
39 # -- Run a command without the required '--'
40 result = sb.invoke_apio_cmd(apio, ["raw", "echo"], in_subprocess=True)
41 assert result.exit_code != 0, result.output
42 assert "command separator '--' was not found" in result.output
44 # -- Run a command with a token before the '--' separator.
45 result = sb.invoke_apio_cmd(
46 apio, ["raw", "echo", "--", "--help"], in_subprocess=True
47 )
48 assert result.exit_code != 0, result.output
49 assert "Invalid arguments: ['echo']" in result.output
51 # -- Run 'apio raw -v'
52 result = sb.invoke_apio_cmd(apio, ["raw", "-v"], in_subprocess=True)
53 sb.assert_result_ok(result)
54 assert "Environment settings:" in result.output
55 assert "YOSYS_LIB" in result.output
58def test_raw_preserves_argv_and_cwd(apio_runner: ApioRunner):
59 """Tests that 'apio raw' passes the wrapped command's arguments
60 verbatim as an argv list (no re-splitting at spaces, no quote
61 mangling) and runs it in the caller's current directory. This is
62 a regression test for a Windows bug where the args were joined with
63 POSIX quoting and re-tokenized by cmd.exe, breaking paths with
64 spaces or backslashes."""
66 with apio_runner.in_sandbox() as sb:
68 # -- A probe command that reports its cwd and its argv, one
69 # -- element per line. Note that the sandbox's current directory
70 # -- ('apio proj') contains a space.
71 probe = (
72 "import os, sys; "
73 "print('PROBE-CWD=<' + os.getcwd() + '>'); "
74 "[print('PROBE-ARG-%d=<%s>' % (i, a)) "
75 "for i, a in enumerate(sys.argv[1:])]"
76 )
78 result = sb.invoke_apio_cmd(
79 apio,
80 [
81 "raw",
82 "--",
83 sys.executable,
84 "-c",
85 probe,
86 "a b c.txt",
87 r"_build\default\hardware.bit",
88 ],
89 in_subprocess=True,
90 )
91 sb.assert_result_ok(result, bad_words=[])
93 # -- The wrapped command must inherit the caller's cwd.
94 assert f"PROBE-CWD=<{os.getcwd()}>" in result.output
96 # -- An arg with spaces must arrive as a single argv element.
97 assert "PROBE-ARG-0=<a b c.txt>" in result.output
99 # -- An arg with backslashes must arrive verbatim, without
100 # -- added quotes.
101 assert "PROBE-ARG-1=<_build\\default\\hardware.bit>" in result.output
103 # -- There must be no extra args from re-splitting.
104 assert "PROBE-ARG-2" not in result.output