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

1"""Test for the "apio raw" command.""" 

2 

3import os 

4import sys 

5from tests.conftest import ApioRunner 

6from apio.commands.apio import apio_top_cli as apio 

7 

8 

9def test_raw(apio_runner: ApioRunner): 

10 """Test "apio raw" with different parameters""" 

11 

12 with apio_runner.in_sandbox() as sb: 

13 

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. 

16 

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 ) 

24 

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 

31 

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 

38 

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 

43 

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 

50 

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 

56 

57 

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.""" 

65 

66 with apio_runner.in_sandbox() as sb: 

67 

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 ) 

77 

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=[]) 

92 

93 # -- The wrapped command must inherit the caller's cwd. 

94 assert f"PROBE-CWD=<{os.getcwd()}>" in result.output 

95 

96 # -- An arg with spaces must arrive as a single argv element. 

97 assert "PROBE-ARG-0=<a b c.txt>" in result.output 

98 

99 # -- An arg with backslashes must arrive verbatim, without 

100 # -- added quotes. 

101 assert "PROBE-ARG-1=<_build\\default\\hardware.bit>" in result.output 

102 

103 # -- There must be no extra args from re-splitting. 

104 assert "PROBE-ARG-2" not in result.output