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

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

2 

3import os 

4import sys 

5import re 

6from tests.conftest import ApioRunner 

7from apio.commands.apio import apio_top_cli as apio 

8 

9 

10def test_raw(apio_runner: ApioRunner): 

11 """Test "apio raw" with different parameters""" 

12 

13 with apio_runner.in_sandbox() as sb: 

14 

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. 

17 

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 ) 

25 

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 

32 

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 

39 

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 

44 

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 

51 

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 

57 

58 

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

66 

67 with apio_runner.in_sandbox() as sb: 

68 

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 ) 

78 

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

93 

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

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

96 

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

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

99 

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

101 # -- added quotes. 

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

103 

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

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

106 

107 

108def test_raw_icepll(apio_runner: ApioRunner): 

109 """Tests that the icepll raw command works""" 

110 

111 with apio_runner.in_sandbox() as sb: 

112 

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) 

134 

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 

139 

140 

141def test_raw_ecppll(apio_runner: ApioRunner): 

142 """Tests that the ecppll raw command works""" 

143 

144 with apio_runner.in_sandbox() as sb: 

145 

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) 

156 

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 

161 

162 

163def test_raw_gowin_pll(apio_runner: ApioRunner): 

164 """Tests that the gowin_pll raw command works""" 

165 

166 with apio_runner.in_sandbox() as sb: 

167 

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) 

192 

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 

197 

198 

199def test_raw_xc7pll(apio_runner: ApioRunner): 

200 """Tests that the xc7pll raw command works""" 

201 

202 with apio_runner.in_sandbox() as sb: 

203 

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) 

224 

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