85e5a2caa8
Now that the tests work in py2 or p3 we don't set py version in AP. This allows for dealing with the AP images that don't have a way to set the py version.
266 lines
8.6 KiB
Python
Executable File
266 lines
8.6 KiB
Python
Executable File
#!/usr/bin/python
|
|
|
|
# Copyright 2001 Dave Abrahams
|
|
# Copyright 2011 Steven Watanabe
|
|
# Distributed under the Boost Software License, Version 1.0.
|
|
# (See accompanying file LICENSE_1_0.txt or copy at
|
|
# http://www.boost.org/LICENSE_1_0.txt)
|
|
|
|
# Tests Windows command line construction.
|
|
#
|
|
# Note that the regular 'echo' is an internal shell command on Windows and
|
|
# therefore can not be called directly as a standalone Windows process.
|
|
|
|
import BoostBuild
|
|
import os
|
|
import re
|
|
import sys
|
|
|
|
|
|
executable = sys.executable.replace("\\", "/")
|
|
if " " in executable:
|
|
executable = '"%s"' % executable
|
|
|
|
|
|
def string_of_length(n):
|
|
if n <= 0:
|
|
return ""
|
|
n -= 1
|
|
y = ['', '$(1x10-1)', '$(10x10-1)', '$(100x10-1)', '$(1000x10-1)']
|
|
result = []
|
|
for i in reversed(range(5)):
|
|
x, n = divmod(n, 10 ** i)
|
|
result += [y[i]] * x
|
|
result.append('x')
|
|
return " ".join(result)
|
|
|
|
|
|
# Boost Jam currently does not allow preparing actions with completely empty
|
|
# content and always requires at least a single whitespace after the opening
|
|
# brace in order to satisfy its Boost Jam language grammar rules.
|
|
def test_raw_empty():
|
|
whitespace_in = " \n\n\r\r\v\v\t\t \t \r\r \n\n"
|
|
|
|
# We tell the testing system to read its child process output as raw
|
|
# binary data but the bjam process we run will read its input file and
|
|
# write out its output as text, i.e. convert all of our "\r\n" sequences to
|
|
# "\n" on input and all of its "\n" characters back to "\r\n" on output.
|
|
# This means that any lone "\n" input characters not preceded by "\r" will
|
|
# get an extra "\r" added in front of it on output.
|
|
whitespace_out = whitespace_in.replace("\r\n", "\n").replace("\n", "\r\n")
|
|
|
|
t = BoostBuild.Tester(["-d2", "-d+4"], pass_toolset=0,
|
|
use_test_config=False)
|
|
t.write("file.jam", """\
|
|
actions do_empty {%s}
|
|
JAMSHELL = %% ;
|
|
do_empty all ;
|
|
""" % (whitespace_in))
|
|
t.run_build_system(["-ffile.jam"], universal_newlines=False)
|
|
t.expect_output_lines("do_empty all")
|
|
t.expect_output_lines("Executing raw command directly", False)
|
|
if "\r\n%s\r\n" % whitespace_out not in t.stdout():
|
|
BoostBuild.annotation("failure", "Whitespace action content not found "
|
|
"on stdout.")
|
|
t.fail_test(1, dump_difference=False)
|
|
t.cleanup()
|
|
|
|
|
|
def test_raw_nt(n=None, error=False):
|
|
t = BoostBuild.Tester(["-d1", "-d+4"], pass_toolset=0,
|
|
use_test_config=False)
|
|
|
|
cmd_prefix = "%s -c \"print('XXX: " % executable
|
|
cmd_suffix = "')\""
|
|
cmd_extra_length = len(cmd_prefix) + len(cmd_suffix)
|
|
|
|
if n == None:
|
|
n = cmd_extra_length
|
|
|
|
data_length = n - cmd_extra_length
|
|
if data_length < 0:
|
|
BoostBuild.annotation("failure", """\
|
|
Can not construct Windows command of desired length. Requested command length
|
|
too short for the current test configuration.
|
|
Requested command length: %d
|
|
Minimal supported command length: %d
|
|
""" % (n, cmd_extra_length))
|
|
t.fail_test(1, dump_difference=False)
|
|
|
|
# Each $(Xx10-1) variable contains X words of 9 characters each, which,
|
|
# including spaces between words, brings the total number of characters in
|
|
# its string representation to X * 10 - 1 (X * 9 characters + (X - 1)
|
|
# spaces).
|
|
t.write("file.jam", """\
|
|
ten = 0 1 2 3 4 5 6 7 8 9 ;
|
|
|
|
1x10-1 = 123456789 ;
|
|
10x10-1 = $(ten)12345678 ;
|
|
100x10-1 = $(ten)$(ten)1234567 ;
|
|
1000x10-1 = $(ten)$(ten)$(ten)123456 ;
|
|
|
|
actions do_echo
|
|
{
|
|
%s%s%s
|
|
}
|
|
JAMSHELL = %% ;
|
|
do_echo all ;
|
|
""" % (cmd_prefix, string_of_length(data_length), cmd_suffix))
|
|
if error:
|
|
expected_status = 1
|
|
else:
|
|
expected_status = 0
|
|
t.run_build_system(["-ffile.jam"], status=expected_status)
|
|
if error:
|
|
t.expect_output_lines("Executing raw command directly", False)
|
|
t.expect_output_lines("do_echo action is too long (%d, max 32766):" % n
|
|
)
|
|
t.expect_output_lines("XXX: *", False)
|
|
else:
|
|
t.expect_output_lines("Executing raw command directly")
|
|
t.expect_output_lines("do_echo action is too long*", False)
|
|
|
|
m = re.search("^XXX: (.*)$", t.stdout(), re.MULTILINE)
|
|
if not m:
|
|
BoostBuild.annotation("failure", "Expected output line starting "
|
|
"with 'XXX: ' not found.")
|
|
t.fail_test(1, dump_difference=False)
|
|
if len(m.group(1)) != data_length:
|
|
BoostBuild.annotation("failure", """Unexpected output data length.
|
|
Expected: %d
|
|
Received: %d""" % (n, len(m.group(1))))
|
|
t.fail_test(1, dump_difference=False)
|
|
|
|
t.cleanup()
|
|
|
|
|
|
def test_raw_to_shell_fallback_nt():
|
|
t = BoostBuild.Tester(["-d1", "-d+4"], pass_toolset=0,
|
|
use_test_config=False)
|
|
|
|
cmd_prefix = '%s -c print(' % executable
|
|
cmd_suffix = ')'
|
|
|
|
t.write("file_multiline.jam", """\
|
|
actions do_multiline
|
|
{
|
|
echo one
|
|
|
|
|
|
echo two
|
|
}
|
|
JAMSHELL = % ;
|
|
do_multiline all ;
|
|
""")
|
|
t.run_build_system(["-ffile_multiline.jam"])
|
|
t.expect_output_lines("do_multiline all")
|
|
t.expect_output_lines("one")
|
|
t.expect_output_lines("two")
|
|
t.expect_output_lines("Executing raw command directly", False)
|
|
t.expect_output_lines("Executing using a command file and the shell: "
|
|
"cmd.exe /Q/C")
|
|
|
|
t.write("file_redirect.jam", """\
|
|
actions do_redirect { echo one > two.txt }
|
|
JAMSHELL = % ;
|
|
do_redirect all ;
|
|
""")
|
|
t.run_build_system(["-ffile_redirect.jam"])
|
|
t.expect_output_lines("do_redirect all")
|
|
t.expect_output_lines("one", False)
|
|
t.expect_output_lines("Executing raw command directly", False)
|
|
t.expect_output_lines("Executing using a command file and the shell: "
|
|
"cmd.exe /Q/C")
|
|
t.expect_addition("two.txt")
|
|
|
|
t.write("file_pipe.jam", """\
|
|
actions do_pipe
|
|
{
|
|
echo one | echo two
|
|
}
|
|
JAMSHELL = % ;
|
|
do_pipe all ;
|
|
""")
|
|
t.run_build_system(["-ffile_pipe.jam"])
|
|
t.expect_output_lines("do_pipe all")
|
|
t.expect_output_lines("one*", False)
|
|
t.expect_output_lines("two")
|
|
t.expect_output_lines("Executing raw command directly", False)
|
|
t.expect_output_lines("Executing using a command file and the shell: "
|
|
"cmd.exe /Q/C")
|
|
|
|
t.write("file_single_quoted.jam", """\
|
|
actions do_single_quoted { %s'5>10'%s }
|
|
JAMSHELL = %% ;
|
|
do_single_quoted all ;
|
|
""" % (cmd_prefix, cmd_suffix))
|
|
t.run_build_system(["-ffile_single_quoted.jam"])
|
|
t.expect_output_lines("do_single_quoted all")
|
|
t.expect_output_lines("5>10")
|
|
t.expect_output_lines("Executing raw command directly")
|
|
t.expect_output_lines("Executing using a command file and the shell: "
|
|
"cmd.exe /Q/C", False)
|
|
t.expect_nothing_more()
|
|
|
|
t.write("file_double_quoted.jam", """\
|
|
actions do_double_quoted { %s"5>10"%s }
|
|
JAMSHELL = %% ;
|
|
do_double_quoted all ;
|
|
""" % (cmd_prefix, cmd_suffix))
|
|
t.run_build_system(["-ffile_double_quoted.jam"])
|
|
t.expect_output_lines("do_double_quoted all")
|
|
# The difference between this example and the similar previous one using
|
|
# single instead of double quotes stems from how the used Python executable
|
|
# parses the command-line string received from Windows.
|
|
t.expect_output_lines("False")
|
|
t.expect_output_lines("Executing raw command directly")
|
|
t.expect_output_lines("Executing using a command file and the shell: "
|
|
"cmd.exe /Q/C", False)
|
|
t.expect_nothing_more()
|
|
|
|
t.write("file_escaped_quote.jam", """\
|
|
actions do_escaped_quote { %s\\"5>10\\"%s }
|
|
JAMSHELL = %% ;
|
|
do_escaped_quote all ;
|
|
""" % (cmd_prefix, cmd_suffix))
|
|
t.run_build_system(["-ffile_escaped_quote.jam"])
|
|
t.expect_output_lines("do_escaped_quote all")
|
|
t.expect_output_lines("5>10")
|
|
t.expect_output_lines("Executing raw command directly", False)
|
|
t.expect_output_lines("Executing using a command file and the shell: "
|
|
"cmd.exe /Q/C")
|
|
t.expect_nothing_more()
|
|
|
|
t.cleanup()
|
|
|
|
|
|
###############################################################################
|
|
#
|
|
# main()
|
|
# ------
|
|
#
|
|
###############################################################################
|
|
|
|
if os.name == 'nt':
|
|
test_raw_empty()
|
|
|
|
# Can not test much shorter lengths as the shortest possible command line
|
|
# line length constructed in this depends on the runtime environment, e.g.
|
|
# path to the Panther executable running this test.
|
|
test_raw_nt()
|
|
test_raw_nt(255)
|
|
test_raw_nt(1000)
|
|
test_raw_nt(8000)
|
|
test_raw_nt(8191)
|
|
test_raw_nt(8192)
|
|
test_raw_nt(10000)
|
|
test_raw_nt(30000)
|
|
test_raw_nt(32766)
|
|
# CreateProcessA() Windows API places a limit of 32768 on the allowed
|
|
# command-line length, including a trailing Unicode (2-byte) nul-terminator
|
|
# character.
|
|
test_raw_nt(32767, error=True)
|
|
test_raw_nt(40000, error=True)
|
|
test_raw_nt(100001, error=True)
|
|
|
|
test_raw_to_shell_fallback_nt() |