]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/tools/build/test/core_nt_cmd_line.py
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / tools / build / test / core_nt_cmd_line.py
CommitLineData
7c673cae
FG
1#!/usr/bin/python
2
3# Copyright 2001 Dave Abrahams
4# Copyright 2011 Steven Watanabe
5# Distributed under the Boost Software License, Version 1.0.
1e59de90
TL
6# (See accompanying file LICENSE.txt or copy at
7# https://www.bfgroup.xyz/b2/LICENSE.txt)
7c673cae
FG
8
9# Tests Windows command line construction.
10#
11# Note that the regular 'echo' is an internal shell command on Windows and
12# therefore can not be called directly as a standalone Windows process.
13
14import BoostBuild
15import os
16import re
17import sys
18
19
20executable = sys.executable.replace("\\", "/")
21if " " in executable:
22 executable = '"%s"' % executable
23
24
25def string_of_length(n):
26 if n <= 0:
27 return ""
28 n -= 1
29 y = ['', '$(1x10-1)', '$(10x10-1)', '$(100x10-1)', '$(1000x10-1)']
30 result = []
92f5a8d4 31 for i in reversed(range(5)):
7c673cae
FG
32 x, n = divmod(n, 10 ** i)
33 result += [y[i]] * x
34 result.append('x')
35 return " ".join(result)
36
37
38# Boost Jam currently does not allow preparing actions with completely empty
39# content and always requires at least a single whitespace after the opening
40# brace in order to satisfy its Boost Jam language grammar rules.
41def test_raw_empty():
42 whitespace_in = " \n\n\r\r\v\v\t\t \t \r\r \n\n"
43
44 # We tell the testing system to read its child process output as raw
45 # binary data but the bjam process we run will read its input file and
46 # write out its output as text, i.e. convert all of our "\r\n" sequences to
47 # "\n" on input and all of its "\n" characters back to "\r\n" on output.
48 # This means that any lone "\n" input characters not preceded by "\r" will
49 # get an extra "\r" added in front of it on output.
50 whitespace_out = whitespace_in.replace("\r\n", "\n").replace("\n", "\r\n")
51
11fdf7f2 52 t = BoostBuild.Tester(["-d2", "-d+4"], pass_toolset=0,
7c673cae
FG
53 use_test_config=False)
54 t.write("file.jam", """\
55actions do_empty {%s}
56JAMSHELL = %% ;
57do_empty all ;
58""" % (whitespace_in))
59 t.run_build_system(["-ffile.jam"], universal_newlines=False)
60 t.expect_output_lines("do_empty all")
61 t.expect_output_lines("Executing raw command directly", False)
62 if "\r\n%s\r\n" % whitespace_out not in t.stdout():
63 BoostBuild.annotation("failure", "Whitespace action content not found "
64 "on stdout.")
65 t.fail_test(1, dump_difference=False)
66 t.cleanup()
67
68
69def test_raw_nt(n=None, error=False):
11fdf7f2 70 t = BoostBuild.Tester(["-d1", "-d+4"], pass_toolset=0,
7c673cae
FG
71 use_test_config=False)
72
73 cmd_prefix = "%s -c \"print('XXX: " % executable
74 cmd_suffix = "')\""
75 cmd_extra_length = len(cmd_prefix) + len(cmd_suffix)
76
77 if n == None:
78 n = cmd_extra_length
79
80 data_length = n - cmd_extra_length
81 if data_length < 0:
82 BoostBuild.annotation("failure", """\
83Can not construct Windows command of desired length. Requested command length
84too short for the current test configuration.
85 Requested command length: %d
86 Minimal supported command length: %d
87""" % (n, cmd_extra_length))
88 t.fail_test(1, dump_difference=False)
89
90 # Each $(Xx10-1) variable contains X words of 9 characters each, which,
91 # including spaces between words, brings the total number of characters in
92 # its string representation to X * 10 - 1 (X * 9 characters + (X - 1)
93 # spaces).
94 t.write("file.jam", """\
95ten = 0 1 2 3 4 5 6 7 8 9 ;
96
971x10-1 = 123456789 ;
9810x10-1 = $(ten)12345678 ;
99100x10-1 = $(ten)$(ten)1234567 ;
1001000x10-1 = $(ten)$(ten)$(ten)123456 ;
101
102actions do_echo
103{
104 %s%s%s
105}
106JAMSHELL = %% ;
107do_echo all ;
108""" % (cmd_prefix, string_of_length(data_length), cmd_suffix))
109 if error:
110 expected_status = 1
111 else:
112 expected_status = 0
113 t.run_build_system(["-ffile.jam"], status=expected_status)
114 if error:
115 t.expect_output_lines("Executing raw command directly", False)
116 t.expect_output_lines("do_echo action is too long (%d, max 32766):" % n
117 )
118 t.expect_output_lines("XXX: *", False)
119 else:
120 t.expect_output_lines("Executing raw command directly")
121 t.expect_output_lines("do_echo action is too long*", False)
122
123 m = re.search("^XXX: (.*)$", t.stdout(), re.MULTILINE)
124 if not m:
125 BoostBuild.annotation("failure", "Expected output line starting "
126 "with 'XXX: ' not found.")
127 t.fail_test(1, dump_difference=False)
128 if len(m.group(1)) != data_length:
129 BoostBuild.annotation("failure", """Unexpected output data length.
130 Expected: %d
131 Received: %d""" % (n, len(m.group(1))))
132 t.fail_test(1, dump_difference=False)
133
134 t.cleanup()
135
136
137def test_raw_to_shell_fallback_nt():
11fdf7f2 138 t = BoostBuild.Tester(["-d1", "-d+4"], pass_toolset=0,
7c673cae
FG
139 use_test_config=False)
140
141 cmd_prefix = '%s -c print(' % executable
142 cmd_suffix = ')'
143
144 t.write("file_multiline.jam", """\
145actions do_multiline
146{
147 echo one
148
149
150 echo two
151}
152JAMSHELL = % ;
153do_multiline all ;
154""")
155 t.run_build_system(["-ffile_multiline.jam"])
156 t.expect_output_lines("do_multiline all")
157 t.expect_output_lines("one")
158 t.expect_output_lines("two")
159 t.expect_output_lines("Executing raw command directly", False)
160 t.expect_output_lines("Executing using a command file and the shell: "
161 "cmd.exe /Q/C")
162
163 t.write("file_redirect.jam", """\
164actions do_redirect { echo one > two.txt }
165JAMSHELL = % ;
166do_redirect all ;
167""")
168 t.run_build_system(["-ffile_redirect.jam"])
169 t.expect_output_lines("do_redirect all")
170 t.expect_output_lines("one", False)
171 t.expect_output_lines("Executing raw command directly", False)
172 t.expect_output_lines("Executing using a command file and the shell: "
173 "cmd.exe /Q/C")
174 t.expect_addition("two.txt")
175
176 t.write("file_pipe.jam", """\
177actions do_pipe
178{
179 echo one | echo two
180}
181JAMSHELL = % ;
182do_pipe all ;
183""")
184 t.run_build_system(["-ffile_pipe.jam"])
185 t.expect_output_lines("do_pipe all")
186 t.expect_output_lines("one*", False)
187 t.expect_output_lines("two")
188 t.expect_output_lines("Executing raw command directly", False)
189 t.expect_output_lines("Executing using a command file and the shell: "
190 "cmd.exe /Q/C")
191
192 t.write("file_single_quoted.jam", """\
193actions do_single_quoted { %s'5>10'%s }
194JAMSHELL = %% ;
195do_single_quoted all ;
196""" % (cmd_prefix, cmd_suffix))
197 t.run_build_system(["-ffile_single_quoted.jam"])
198 t.expect_output_lines("do_single_quoted all")
199 t.expect_output_lines("5>10")
200 t.expect_output_lines("Executing raw command directly")
201 t.expect_output_lines("Executing using a command file and the shell: "
202 "cmd.exe /Q/C", False)
203 t.expect_nothing_more()
204
205 t.write("file_double_quoted.jam", """\
206actions do_double_quoted { %s"5>10"%s }
207JAMSHELL = %% ;
208do_double_quoted all ;
209""" % (cmd_prefix, cmd_suffix))
210 t.run_build_system(["-ffile_double_quoted.jam"])
211 t.expect_output_lines("do_double_quoted all")
212 # The difference between this example and the similar previous one using
213 # single instead of double quotes stems from how the used Python executable
214 # parses the command-line string received from Windows.
215 t.expect_output_lines("False")
216 t.expect_output_lines("Executing raw command directly")
217 t.expect_output_lines("Executing using a command file and the shell: "
218 "cmd.exe /Q/C", False)
219 t.expect_nothing_more()
220
221 t.write("file_escaped_quote.jam", """\
222actions do_escaped_quote { %s\\"5>10\\"%s }
223JAMSHELL = %% ;
224do_escaped_quote all ;
225""" % (cmd_prefix, cmd_suffix))
226 t.run_build_system(["-ffile_escaped_quote.jam"])
227 t.expect_output_lines("do_escaped_quote all")
228 t.expect_output_lines("5>10")
229 t.expect_output_lines("Executing raw command directly", False)
230 t.expect_output_lines("Executing using a command file and the shell: "
231 "cmd.exe /Q/C")
232 t.expect_nothing_more()
233
234 t.cleanup()
235
236
237###############################################################################
238#
239# main()
240# ------
241#
242###############################################################################
243
244if os.name == 'nt':
245 test_raw_empty()
246
247 # Can not test much shorter lengths as the shortest possible command line
248 # line length constructed in this depends on the runtime environment, e.g.
249 # path to the Panther executable running this test.
250 test_raw_nt()
251 test_raw_nt(255)
252 test_raw_nt(1000)
253 test_raw_nt(8000)
254 test_raw_nt(8191)
255 test_raw_nt(8192)
256 test_raw_nt(10000)
257 test_raw_nt(30000)
258 test_raw_nt(32766)
259 # CreateProcessA() Windows API places a limit of 32768 on the allowed
260 # command-line length, including a trailing Unicode (2-byte) nul-terminator
261 # character.
262 test_raw_nt(32767, error=True)
263 test_raw_nt(40000, error=True)
264 test_raw_nt(100001, error=True)
265
266 test_raw_to_shell_fallback_nt()