summaryrefslogtreecommitdiff
path: root/testing
diff options
context:
space:
mode:
Diffstat (limited to 'testing')
-rw-r--r--testing/framework/README.txt2
-rw-r--r--testing/framework/SConscript13
-rw-r--r--testing/framework/TestCmd.py165
-rw-r--r--testing/framework/TestCmdTests.py543
-rw-r--r--testing/framework/TestRuntest.py4
-rw-r--r--testing/framework/TestSCons.py130
-rw-r--r--testing/framework/TestSConsMSVS.py678
-rw-r--r--testing/framework/TestSCons_time.py5
-rw-r--r--testing/framework/TestSConsign.py2
9 files changed, 641 insertions, 901 deletions
diff --git a/testing/framework/README.txt b/testing/framework/README.txt
index 0e0f2bb..817cb3f 100644
--- a/testing/framework/README.txt
+++ b/testing/framework/README.txt
@@ -47,4 +47,4 @@ the pieces here are local to SCons.
Test infrastructure for the sconsign.py script.
Copyright (c) 2001 - 2019 The SCons Foundation
-testing/framework/README.txt 103260fce95bf5db1c35fb2371983087d85dd611 2019-07-13 18:25:30 bdbaddog
+testing/framework/README.txt e724ae812eb96f4858a132f5b8c769724744faf6 2019-07-21 00:04:47 bdeegan
diff --git a/testing/framework/SConscript b/testing/framework/SConscript
index 535f187..f79a254 100644
--- a/testing/framework/SConscript
+++ b/testing/framework/SConscript
@@ -41,12 +41,13 @@ files = [
def copy(target, source, env):
t = str(target[0])
s = str(source[0])
- c = open(s, 'r').read()
- # Note: We construct the __ VERSION __ substitution string at
- # run-time so it doesn't get replaced when this file gets copied
- # into the tree for packaging.
- c = c.replace('__' + 'VERSION' + '__', env['VERSION'])
- open(t, 'w').write(c)
+ with open(s, 'r') as i, open(t, 'w') as o:
+ c = i.read()
+ # Note: We construct the __ VERSION __ substitution string at
+ # run-time so it doesn't get replaced when this file gets copied
+ # into the tree for packaging.
+ c = c.replace('__' + 'VERSION' + '__', env['VERSION'])
+ o.write(c)
for file in files:
# Guarantee that real copies of these files always exist in
diff --git a/testing/framework/TestCmd.py b/testing/framework/TestCmd.py
index a6a8045..81e03f3 100644
--- a/testing/framework/TestCmd.py
+++ b/testing/framework/TestCmd.py
@@ -366,13 +366,11 @@ else:
def is_String(e):
return isinstance(e, (str, unicode, UserString))
-tempfile.template = 'testcmd.'
+testprefix = 'testcmd.'
if os.name in ('posix', 'nt'):
- tempfile.template = 'testcmd.' + str(os.getpid()) + '.'
-else:
- tempfile.template = 'testcmd.'
+ testprefix += "%s." % str(os.getpid())
-re_space = re.compile('\s')
+re_space = re.compile(r'\s')
def _caller(tblist, skip):
@@ -470,6 +468,14 @@ def pass_test(self=None, condition=1, function=None):
def match_exact(lines=None, matches=None, newline=os.sep):
"""
+ Match function using exact match.
+
+ :param lines: data lines
+ :type lines: str or list[str]
+ :param matches: expected lines to match
+ :type matches: str or list[str]
+ :param newline: line separator
+ :returns: an object (1) on match, else None, like re.match
"""
if isinstance(lines, bytes) or bytes is str:
@@ -480,30 +486,51 @@ def match_exact(lines=None, matches=None, newline=os.sep):
if not is_List(matches):
matches = matches.split(newline)
if len(lines) != len(matches):
- return
- for i in range(len(lines)):
- if lines[i] != matches[i]:
- return
+ return None
+ for line, match in zip(lines, matches):
+ if line != match:
+ return None
return 1
def match_caseinsensitive(lines=None, matches=None):
"""
+ Match function using case-insensitive matching.
+
+ Only a simplistic comparison is done, based on lowercasing the
+ strings. This has plenty of holes for unicode data using
+ non-English languages.
+
+ TODO: casefold() is better than lower() if we don't need Py2 support.
+
+ :param lines: data lines
+ :type lines: str or list[str]
+ :param matches: expected lines to match
+ :type matches: str or list[str]
+ :returns: True or False
+ :returns: an object (1) on match, else None, like re.match
"""
if not is_List(lines):
lines = lines.split("\n")
if not is_List(matches):
matches = matches.split("\n")
if len(lines) != len(matches):
- return
- for i in range(len(lines)):
- if lines[i].lower() != matches[i].lower():
- return
+ return None
+ for line, match in zip(lines, matches):
+ if line.lower() != match.lower():
+ return None
return 1
def match_re(lines=None, res=None):
"""
+ Match function using line-by-line regular expression match.
+
+ :param lines: data lines
+ :type lines: str or list[str]
+ :param res: regular expression(s) for matching
+ :type res: str or list[str]
+ :returns: an object (1) on match, else None, like re.match
"""
if not is_List(lines):
# CRs mess up matching (Windows) so split carefully
@@ -512,29 +539,39 @@ def match_re(lines=None, res=None):
res = res.split("\n")
if len(lines) != len(res):
print("match_re: expected %d lines, found %d" % (len(res), len(lines)))
- return
- for i in range(len(lines)):
- s = "^" + res[i] + "$"
+ return None
+ for i, (line, regex) in enumerate(zip(lines, res)):
+ s = r"^{}$".format(regex)
try:
expr = re.compile(s)
except re.error as e:
msg = "Regular expression error in %s: %s"
raise re.error(msg % (repr(s), e.args[0]))
- if not expr.search(lines[i]):
- print("match_re: mismatch at line %d:\n search re='%s'\n line='%s'" % (
- i, s, lines[i]))
- return
+ if not expr.search(line):
+ miss_tmpl = "match_re: mismatch at line {}:\n search re='{}'\n line='{}'"
+ print(miss_tmpl.format(i, s, line))
+ return None
return 1
def match_re_dotall(lines=None, res=None):
"""
+ Match function using regular expression match.
+
+ Unlike match_re, the arguments are converted to strings (if necessary)
+ and must match exactly.
+
+ :param lines: data lines
+ :type lines: str or list[str]
+ :param res: regular expression(s) for matching
+ :type res: str or list[str]
+ :returns: a match object, or None as for re.match
"""
if not isinstance(lines, str):
lines = "\n".join(lines)
if not isinstance(res, str):
res = "\n".join(res)
- s = "^" + res + "$"
+ s = r"^{}$".format(res)
try:
expr = re.compile(s, re.DOTALL)
except re.error as e:
@@ -544,11 +581,32 @@ def match_re_dotall(lines=None, res=None):
def simple_diff(a, b, fromfile='', tofile='',
- fromfiledate='', tofiledate='', n=3, lineterm='\n'):
- """
- A function with the same calling signature as difflib.context_diff
- (diff -c) and difflib.unified_diff (diff -u) but which prints
- output like the simple, unadorned 'diff" command.
+ fromfiledate='', tofiledate='', n=0, lineterm=''):
+ r"""
+ Compare two sequences of lines; generate the delta as a simple diff.
+
+ Similar to difflib.context_diff and difflib.unified_diff but
+ output is like from the 'diff" command without arguments. The function
+ keeps the same signature as the difflib ones so they will be
+ interchangeable, but except for lineterm, the arguments beyond the
+ two sequences are ignored in this version. By default, the
+ diff is not created with trailing newlines, set the lineterm
+ argument to '\n' to do so.
+
+ :raises re.error: if a regex fails to compile
+
+ Example:
+
+ >>> print(''.join(simple_diff('one\ntwo\nthree\nfour\n'.splitlines(True),
+ ... 'zero\none\ntree\nfour\n'.splitlines(True), lineterm='\n')))
+ 0a1
+ > zero
+ 2,3c3
+ < two
+ < three
+ ---
+ > tree
+
"""
a = [to_str(q) for q in a]
b = [to_str(q) for q in b]
@@ -556,25 +614,30 @@ def simple_diff(a, b, fromfile='', tofile='',
def comma(x1, x2):
return x1 + 1 == x2 and str(x2) or '%s,%s' % (x1 + 1, x2)
- result = []
+
for op, a1, a2, b1, b2 in sm.get_opcodes():
if op == 'delete':
- result.append("%sd%d" % (comma(a1, a2), b1))
- result.extend(['< ' + l for l in a[a1:a2]])
+ yield "{}d{}{}".format(comma(a1, a2), b1, lineterm)
+ for l in a[a1:a2]:
+ yield '< ' + l
elif op == 'insert':
- result.append("%da%s" % (a1, comma(b1, b2)))
- result.extend(['> ' + l for l in b[b1:b2]])
+ yield "{}a{}{}".format(a1, comma(b1, b2), lineterm)
+ for l in b[b1:b2]:
+ yield '> ' + l
elif op == 'replace':
- result.append("%sc%s" % (comma(a1, a2), comma(b1, b2)))
- result.extend(['< ' + l for l in a[a1:a2]])
- result.append('---')
- result.extend(['> ' + l for l in b[b1:b2]])
- return result
+ yield "{}c{}{}".format(comma(a1, a2), comma(b1, b2), lineterm)
+ for l in a[a1:a2]:
+ yield '< ' + l
+ yield '---{}'.format(lineterm)
+ for l in b[b1:b2]:
+ yield '> ' + l
def diff_re(a, b, fromfile='', tofile='',
fromfiledate='', tofiledate='', n=3, lineterm='\n'):
"""
+ Compare a and b (lists of strings) where a are regexes.
+
A simple "diff" of two sets of lines when the expected lines
are regular expressions. This is a really dumb thing that
just compares each line in turn, so it doesn't look for
@@ -587,9 +650,8 @@ def diff_re(a, b, fromfile='', tofile='',
a = a + [''] * (-diff)
elif diff > 0:
b = b + [''] * diff
- i = 0
- for aline, bline in zip(a, b):
- s = "^" + aline + "$"
+ for i, (aline, bline) in enumerate(zip(a, b)):
+ s = r"^{}$".format(aline)
try:
expr = re.compile(s)
except re.error as e:
@@ -600,7 +662,6 @@ def diff_re(a, b, fromfile='', tofile='',
result.append('< ' + repr(a[i]))
result.append('---')
result.append('> ' + repr(b[i]))
- i = i + 1
return result
@@ -974,6 +1035,12 @@ class TestCmd(object):
self.subdir(subdir)
self.fixture_dirs = []
+ try:
+ self.fixture_dirs = (os.environ['FIXTURE_DIRS']).split(os.pathsep)
+ except KeyError:
+ pass
+
+
def __del__(self):
self.cleanup()
@@ -1026,7 +1093,7 @@ class TestCmd(object):
condition = self.condition
if self._preserve[condition]:
for dir in self._dirlist:
- print(u"Preserved directory " + dir + "\n")
+ print(u"Preserved directory " + dir)
else:
list = self._dirlist[:]
list.reverse()
@@ -1242,6 +1309,7 @@ class TestCmd(object):
def read(self, file, mode='rb', newline=None):
"""Reads and returns the contents of the specified file name.
+
The file name may be a list, in which case the elements are
concatenated with the os.path.join() method. The file is
assumed to be under the temporary working directory unless it
@@ -1261,6 +1329,7 @@ class TestCmd(object):
def rmdir(self, dir):
"""Removes the specified dir name.
+
The dir name may be a list, in which case the elements are
concatenated with the os.path.join() method. The dir is
assumed to be under the temporary working directory unless it
@@ -1302,6 +1371,7 @@ class TestCmd(object):
"""Copies the contents of the specified folder srcdir from
the directory of the called script, to the current
working directory.
+
The srcdir name may be a list, in which case the elements are
concatenated with the os.path.join() method. The dstdir is
assumed to be under the temporary working directory, it gets
@@ -1343,6 +1413,7 @@ class TestCmd(object):
def file_fixture(self, srcfile, dstfile=None):
"""Copies the file srcfile from the directory of
the called script, to the current working directory.
+
The dstfile is assumed to be under the temporary working
directory unless it is an absolute path name.
If dstfile is specified its target directory gets created
@@ -1439,6 +1510,7 @@ class TestCmd(object):
def fix_binary_stream(stream):
"""
Handle stdout/stderr from popen when we specify universal_newlines = False.
+
This will read from the pipes in binary mode, not decode the output,
and not convert line endings to \n.
We do this because in py3 (3.5) with universal_newlines=True, it will
@@ -1455,7 +1527,7 @@ class TestCmd(object):
return stream
# TODO: Run full tests on both platforms and see if this fixes failures
# It seems that py3.6 still sets text mode if you set encoding.
- elif sys.version_info[0] == 3:# TODO and sys.version_info[1] < 6:
+ elif sys.version_info[0] == 3: # TODO and sys.version_info[1] < 6:
stream = stream.decode('utf-8')
stream = stream.replace('\r\n', '\n')
elif sys.version_info[0] == 2:
@@ -1629,7 +1701,7 @@ class TestCmd(object):
try:
os.mkdir(new)
except OSError as e:
- print("Got error :%s"%e)
+ print("Got error creating dir: %s :%s" % (sub, e))
pass
else:
count = count + 1
@@ -1662,10 +1734,11 @@ class TestCmd(object):
"""
if path is None:
try:
- path = tempfile.mktemp(prefix=tempfile.template)
+ path = tempfile.mkdtemp(prefix=testprefix)
except TypeError:
- path = tempfile.mktemp()
- os.mkdir(path)
+ path = tempfile.mkdtemp()
+ else:
+ os.mkdir(path)
# Symlinks in the path will report things
# differently from os.getcwd(), so chdir there
diff --git a/testing/framework/TestCmdTests.py b/testing/framework/TestCmdTests.py
index b9226fd..ef76228 100644
--- a/testing/framework/TestCmdTests.py
+++ b/testing/framework/TestCmdTests.py
@@ -26,13 +26,22 @@ import os
import shutil
import signal
import stat
-from StringIO import StringIO
+try:
+ from cStringIO import StringIO
+except ImportError:
+ from io import StringIO
+from contextlib import closing
import sys
import tempfile
import time
import types
import unittest
-from UserList import UserList
+try:
+ from collections import UserList
+except ImportError:
+ from UserList import UserList
+
+from SCons.Util import to_bytes, to_str
# Strip the current directory so we get the right TestCmd.py module.
@@ -55,7 +64,7 @@ def _is_executable(path):
def _clear_dict(dict, *keys):
for key in keys:
try:
- dict[key] = '' # del dict[key]
+ del dict[key]
except KeyError:
pass
@@ -156,9 +165,9 @@ class TestCmdTestCase(unittest.TestCase):
stdin=subprocess.PIPE,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE)
- stdout, stderr = p.communicate(input)
- stdout = self.translate_newlines(stdout)
- stderr = self.translate_newlines(stderr)
+ stdout, stderr = p.communicate(to_bytes(input))
+ stdout = self.translate_newlines(to_str(stdout))
+ stderr = self.translate_newlines(to_str(stderr))
return stdout, stderr, p.returncode
def popen_python(self, input, status=0, stdout="", stderr="", python=None):
@@ -181,7 +190,7 @@ class TestCmdTestCase(unittest.TestCase):
def run_match(self, content, *args):
expect = "%s: %s: %s: %s\n" % args
- content = self.translate_newlines(content)
+ content = self.translate_newlines(to_str(content))
assert content == expect, \
"Expected %s ==========\n" % args[1] + expect + \
"Actual %s ============\n" % args[1] + content
@@ -257,6 +266,7 @@ result = TestCmd.TestCmd(workdir = '')
sys.exit(0)
""" % self.orig_cwd, stdout='my_exitfunc()\n')
+ @unittest.skipIf(TestCmd.IS_PY3, "No sys.exitfunc in Python 3")
def test_exitfunc(self):
"""Test cleanup() when sys.exitfunc is set"""
self.popen_python("""from __future__ import print_function
@@ -271,7 +281,6 @@ sys.exit(0)
""" % self.orig_cwd, stdout='my_exitfunc()\n')
-
class chmod_TestCase(TestCmdTestCase):
def test_chmod(self):
"""Test chmod()"""
@@ -280,8 +289,10 @@ class chmod_TestCase(TestCmdTestCase):
wdir_file1 = os.path.join(test.workdir, 'file1')
wdir_sub_file2 = os.path.join(test.workdir, 'sub', 'file2')
- open(wdir_file1, 'w').write("")
- open(wdir_sub_file2, 'w').write("")
+ with open(wdir_file1, 'w') as f:
+ f.write("")
+ with open(wdir_sub_file2, 'w') as f:
+ f.write("")
if sys.platform == 'win32':
@@ -349,11 +360,8 @@ sys.stderr.write("run2 STDERR third line\\n")
test = TestCmd.TestCmd(interpreter = 'python',
workdir = '',
combine = 1)
- try:
- output = test.stdout()
- except IndexError:
- pass
- else:
+ output = test.stdout()
+ if output is not None:
raise IndexError("got unexpected output:\n\t`%s'\n" % output)
# The underlying system subprocess implementations can combine
@@ -422,10 +430,13 @@ class diff_TestCase(TestCmdTestCase):
def test_diff_re(self):
"""Test diff_re()"""
result = TestCmd.diff_re(["abcde"], ["abcde"])
+ result = list(result)
assert result == [], result
result = TestCmd.diff_re(["a.*e"], ["abcde"])
+ result = list(result)
assert result == [], result
result = TestCmd.diff_re(["a.*e"], ["xxx"])
+ result = list(result)
assert result == ['1c1', "< 'a.*e'", '---', "> 'xxx'"], result
def test_diff_custom_function(self):
@@ -475,13 +486,13 @@ STDOUT==========================================================================
script_input = """import sys
sys.path = ['%s'] + sys.path
import TestCmd
-assert TestCmd.diff_re(["a.*(e"], ["abcde"])
+assert TestCmd.diff_re([r"a.*(e"], ["abcde"])
sys.exit(0)
""" % self.orig_cwd
stdout, stderr, status = self.call_python(script_input)
assert status == 1, status
- expect1 = "Regular expression error in '^a.*(e$': missing )\n"
- expect2 = "Regular expression error in '^a.*(e$': unbalanced parenthesis\n"
+ expect1 = "Regular expression error in '^a.*(e$': missing )"
+ expect2 = "Regular expression error in '^a.*(e$': unbalanced parenthesis"
assert (stderr.find(expect1) != -1 or
stderr.find(expect2) != -1), repr(stderr)
@@ -492,6 +503,7 @@ sys.path = ['%s'] + sys.path
import TestCmd
result = TestCmd.TestCmd.simple_diff(['a', 'b', 'c', 'e', 'f1'],
['a', 'c', 'd', 'e', 'f2'])
+result = list(result)
expect = ['2d1', '< b', '3a3', '> d', '5c5', '< f1', '---', '> f2']
assert result == expect, result
sys.exit(0)
@@ -557,6 +569,7 @@ sys.path = ['%s'] + sys.path
import TestCmd
result = TestCmd.TestCmd.diff_re(['a', 'b', 'c', '.', 'f1'],
['a', 'c', 'd', 'e', 'f2'])
+result = list(result)
expect = [
'2c2',
"< 'b'",
@@ -844,22 +857,22 @@ test.%s()
_test_it(cwd, 'dir04', 'pass_test', 1)
_test_it(cwd, 'dir05', 'fail_test', 1)
_test_it(cwd, 'dir06', 'no_result', 1)
- os.environ['PRESERVE'] = '' # del os.environ['PRESERVE']
+ del os.environ['PRESERVE']
os.environ['PRESERVE_PASS'] = '1'
_test_it(cwd, 'dir07', 'pass_test', 1)
_test_it(cwd, 'dir08', 'fail_test', 0)
_test_it(cwd, 'dir09', 'no_result', 0)
- os.environ['PRESERVE_PASS'] = '' # del os.environ['PRESERVE_PASS']
+ del os.environ['PRESERVE_PASS']
os.environ['PRESERVE_FAIL'] = '1'
_test_it(cwd, 'dir10', 'pass_test', 0)
_test_it(cwd, 'dir11', 'fail_test', 1)
_test_it(cwd, 'dir12', 'no_result', 0)
- os.environ['PRESERVE_FAIL'] = '' # del os.environ['PRESERVE_FAIL']
+ del os.environ['PRESERVE_FAIL']
os.environ['PRESERVE_NO_RESULT'] = '1'
_test_it(cwd, 'dir13', 'pass_test', 0)
_test_it(cwd, 'dir14', 'fail_test', 0)
_test_it(cwd, 'dir15', 'no_result', 1)
- os.environ['PRESERVE_NO_RESULT'] = '' # del os.environ['PRESERVE_NO_RESULT']
+ del os.environ['PRESERVE_NO_RESULT']
finally:
_clear_dict(os.environ, 'PRESERVE', 'PRESERVE_PASS', 'PRESERVE_FAIL', 'PRESERVE_NO_RESULT')
@@ -980,10 +993,10 @@ class match_TestCase(TestCmdTestCase):
test = TestCmd.TestCmd(match = TestCmd.match_exact)
assert not test.match("abcde\n", "a.*e\n")
assert test.match("abcde\n", "abcde\n")
- assert not test.match("12345\nabcde\n", "1\d+5\na.*e\n")
+ assert not test.match("12345\nabcde\n", "1\\d+5\na.*e\n")
assert test.match("12345\nabcde\n", "12345\nabcde\n")
lines = ["vwxyz\n", "67890\n"]
- regexes = ["v[^a-u]*z\n", "6[^ ]+0\n"]
+ regexes = [r"v[^a-u]*z\n", r"6[^ ]+0\n"]
assert not test.match(lines, regexes)
assert test.match(lines, lines)
@@ -992,10 +1005,10 @@ class match_TestCase(TestCmdTestCase):
test = TestCmd.TestCmd(match=TestCmd.TestCmd.match_exact)
assert not test.match("abcde\n", "a.*e\n")
assert test.match("abcde\n", "abcde\n")
- assert not test.match("12345\nabcde\n", "1\d+5\na.*e\n")
+ assert not test.match("12345\nabcde\n", "1\\d+5\na.*e\n")
assert test.match("12345\nabcde\n", "12345\nabcde\n")
lines = ["vwxyz\n", "67890\n"]
- regexes = ["v[^a-u]*z\n", "6[^ ]+0\n"]
+ regexes = [r"v[^a-u]*z\n", r"6[^ ]+0\n"]
assert not test.match(lines, regexes)
assert test.match(lines, lines)
@@ -1004,10 +1017,10 @@ class match_TestCase(TestCmdTestCase):
test = TestCmd.TestCmd(match='match_exact')
assert not test.match("abcde\n", "a.*e\n")
assert test.match("abcde\n", "abcde\n")
- assert not test.match("12345\nabcde\n", "1\d+5\na.*e\n")
+ assert not test.match("12345\nabcde\n", "1\\d+5\na.*e\n")
assert test.match("12345\nabcde\n", "12345\nabcde\n")
lines = ["vwxyz\n", "67890\n"]
- regexes = ["v[^a-u]*z\n", "6[^ ]+0\n"]
+ regexes = [r"v[^a-u]*z\n", r"6[^ ]+0\n"]
assert not test.match(lines, regexes)
assert test.match(lines, lines)
@@ -1057,16 +1070,16 @@ class match_exact_TestCase(TestCmdTestCase):
class match_re_dotall_TestCase(TestCmdTestCase):
def test_match_re_dotall_function(self):
"""Test calling the TestCmd.match_re_dotall() function"""
- assert TestCmd.match_re_dotall("abcde\nfghij\n", "a.*j\n")
+ assert TestCmd.match_re_dotall("abcde\nfghij\n", r"a.*j\n")
def test_match_re_dotall_instance_method(self):
"""Test calling the TestCmd.TestCmd().match_re_dotall() instance method"""
test = TestCmd.TestCmd()
- test.match_re_dotall("abcde\\nfghij\\n", "a.*j\\n")
+ test.match_re_dotall("abcde\\nfghij\\n", r"a.*j\\n")
def test_match_re_dotall_static_method(self):
"""Test calling the TestCmd.TestCmd.match_re_dotall() static method"""
- assert TestCmd.TestCmd.match_re_dotall("abcde\nfghij\n", "a.*j\n")
+ assert TestCmd.TestCmd.match_re_dotall("abcde\nfghij\n", r"a.*j\n")
def test_error(self):
"""Test handling a compilation error in TestCmd.match_re_dotall()"""
@@ -1079,13 +1092,13 @@ class match_re_dotall_TestCase(TestCmdTestCase):
script_input = """import sys
sys.path = ['%s'] + sys.path
import TestCmd
-assert TestCmd.match_re_dotall("abcde", "a.*(e")
+assert TestCmd.match_re_dotall("abcde", r"a.*(e")
sys.exit(0)
""" % cwd
stdout, stderr, status = self.call_python(script_input)
assert status == 1, status
- expect1 = "Regular expression error in '^a.*(e$': missing )\n"
- expect2 = "Regular expression error in '^a.*(e$': unbalanced parenthesis\n"
+ expect1 = "Regular expression error in '^a.*(e$': missing )"
+ expect2 = "Regular expression error in '^a.*(e$': unbalanced parenthesis"
assert (stderr.find(expect1) != -1 or
stderr.find(expect2) != -1), repr(stderr)
finally:
@@ -1094,44 +1107,34 @@ sys.exit(0)
def test_evaluation(self):
"""Test match_re_dotall() evaluation"""
test = TestCmd.TestCmd()
- assert test.match_re_dotall("abcde\nfghij\n", "a.*e\nf.*j\n")
- assert test.match_re_dotall("abcde\nfghij\n", "a[^j]*j\n")
- assert test.match_re_dotall("abcde\nfghij\n", "abcde\nfghij\n")
+ assert test.match_re_dotall("abcde\nfghij\n", r"a.*e\nf.*j\n")
+ assert test.match_re_dotall("abcde\nfghij\n", r"a[^j]*j\n")
+ assert test.match_re_dotall("abcde\nfghij\n", r"abcde\nfghij\n")
assert test.match_re_dotall(["12345\n", "abcde\n", "fghij\n"],
- ["1[0-9]*5\n", "a.*e\n", "f.*j\n"])
+ [r"1[0-9]*5\n", r"a.*e\n", r"f.*j\n"])
assert test.match_re_dotall(["12345\n", "abcde\n", "fghij\n"],
- ["1.*j\n"])
+ [r"1.*j\n"])
assert test.match_re_dotall(["12345\n", "abcde\n", "fghij\n"],
- ["12345\n", "abcde\n", "fghij\n"])
- assert test.match_re_dotall(UserList(["12345\n",
- "abcde\n",
- "fghij\n"]),
- ["1[0-9]*5\n", "a.*e\n", "f.*j\n"])
- assert test.match_re_dotall(UserList(["12345\n",
- "abcde\n",
- "fghij\n"]),
- ["1.*j\n"])
- assert test.match_re_dotall(UserList(["12345\n",
- "abcde\n",
- "fghij\n"]),
- ["12345\n", "abcde\n", "fghij\n"])
+ [r"12345\n", r"abcde\n", r"fghij\n"])
+ assert test.match_re_dotall(UserList(["12345\n", "abcde\n", "fghij\n"]),
+ [r"1[0-9]*5\n", r"a.*e\n", r"f.*j\n"])
+ assert test.match_re_dotall(UserList(["12345\n", "abcde\n", "fghij\n"]),
+ [r"1.*j\n"])
+ assert test.match_re_dotall(UserList(["12345\n", "abcde\n", "fghij\n"]),
+ [r"12345\n", r"abcde\n", r"fghij\n"])
assert test.match_re_dotall(["12345\n", "abcde\n", "fghij\n"],
- UserList(["1[0-9]*5\n",
- "a.*e\n",
- "f.*j\n"]))
+ UserList([r"1[0-9]*5\n", r"a.*e\n", r"f.*j\n"]))
assert test.match_re_dotall(["12345\n", "abcde\n", "fghij\n"],
- UserList(["1.*j\n"]))
+ UserList([r"1.*j\n"]))
assert test.match_re_dotall(["12345\n", "abcde\n", "fghij\n"],
- UserList(["12345\n",
- "abcde\n",
- "fghij\n"]))
+ UserList([r"12345\n", r"abcde\n", r"fghij\n"]))
assert test.match_re_dotall("12345\nabcde\nfghij\n",
- "1[0-9]*5\na.*e\nf.*j\n")
- assert test.match_re_dotall("12345\nabcde\nfghij\n", "1.*j\n")
+ r"1[0-9]*5\na.*e\nf.*j\n")
+ assert test.match_re_dotall("12345\nabcde\nfghij\n", r"1.*j\n")
assert test.match_re_dotall("12345\nabcde\nfghij\n",
- "12345\nabcde\nfghij\n")
+ r"12345\nabcde\nfghij\n")
lines = ["vwxyz\n", "67890\n"]
- regexes = ["v[^a-u]*z\n", "6[^ ]+0\n"]
+ regexes = [r"v[^a-u]*z\n", r"6[^ ]+0\n"]
assert test.match_re_dotall(lines, regexes)
assert test.match_re_dotall(lines, lines)
@@ -1167,8 +1170,8 @@ sys.exit(0)
""" % cwd
stdout, stderr, status = self.call_python(script_input)
assert status == 1, status
- expect1 = "Regular expression error in '^a.*(e$': missing )\n"
- expect2 = "Regular expression error in '^a.*(e$': unbalanced parenthesis\n"
+ expect1 = "Regular expression error in '^a.*(e$': missing )"
+ expect2 = "Regular expression error in '^a.*(e$': unbalanced parenthesis"
assert (stderr.find(expect1) != -1 or
stderr.find(expect2) != -1), repr(stderr)
finally:
@@ -1192,7 +1195,7 @@ sys.exit(0)
assert test.match_re("12345\nabcde\n", "1[0-9]*5\na.*e\n")
assert test.match_re("12345\nabcde\n", "12345\nabcde\n")
lines = ["vwxyz\n", "67890\n"]
- regexes = ["v[^a-u]*z\n", "6[^ ]+0\n"]
+ regexes = [r"v[^a-u]*z\n", r"6[^ ]+0\n"]
assert test.match_re(lines, regexes)
assert test.match_re(lines, lines)
@@ -1205,7 +1208,7 @@ class match_stderr_TestCase(TestCmdTestCase):
assert test.match_stderr("abcde\n", "a.*e\n")
assert test.match_stderr("12345\nabcde\n", "1\\d+5\na.*e\n")
lines = ["vwxyz\n", "67890\n"]
- regexes = ["v[^a-u]*z\n", "6[^ ]+0\n"]
+ regexes = [r"v[^a-u]*z\n", r"6[^ ]+0\n"]
assert test.match_stderr(lines, regexes)
def test_match_stderr_not_affecting_match_stdout(self):
@@ -1217,14 +1220,14 @@ class match_stderr_TestCase(TestCmdTestCase):
assert not test.match_stderr("12345\nabcde\n", "1\\d+5\na.*e\n")
assert test.match_stderr("12345\nabcde\n", "12345\nabcde\n")
lines = ["vwxyz\n", "67890\n"]
- regexes = ["v[^a-u]*z\n", "6[^ ]+0\n"]
+ regexes = [r"v[^a-u]*z\n", r"6[^ ]+0\n"]
assert not test.match_stderr(lines, regexes)
assert test.match_stderr(lines, lines)
assert test.match_stdout("abcde\n", "a.*e\n")
assert test.match_stdout("12345\nabcde\n", "1\\d+5\na.*e\n")
lines = ["vwxyz\n", "67890\n"]
- regexes = ["v[^a-u]*z\n", "6[^ ]+0\n"]
+ regexes = [r"v[^a-u]*z\n", r"6[^ ]+0\n"]
assert test.match_stdout(lines, regexes)
def test_match_stderr_custom_function(self):
@@ -1237,7 +1240,7 @@ class match_stderr_TestCase(TestCmdTestCase):
assert not test.match_stderr("123\n123\n", "1\n1\n")
assert test.match_stderr("123\n123\n", "111\n111\n")
lines = ["123\n", "123\n"]
- regexes = ["1\n", "1\n"]
+ regexes = [r"1\n", r"1\n"]
assert test.match_stderr(lines, regexes) # equal numbers of lines
def test_match_stderr_TestCmd_function(self):
@@ -1245,10 +1248,10 @@ class match_stderr_TestCase(TestCmdTestCase):
test = TestCmd.TestCmd(match_stderr = TestCmd.match_exact)
assert not test.match_stderr("abcde\n", "a.*e\n")
assert test.match_stderr("abcde\n", "abcde\n")
- assert not test.match_stderr("12345\nabcde\n", "1\d+5\na.*e\n")
+ assert not test.match_stderr("12345\nabcde\n", "1\\d+5\na.*e\n")
assert test.match_stderr("12345\nabcde\n", "12345\nabcde\n")
lines = ["vwxyz\n", "67890\n"]
- regexes = ["v[^a-u]*z\n", "6[^ ]+0\n"]
+ regexes = [r"v[^a-u]*z\n", r"6[^ ]+0\n"]
assert not test.match_stderr(lines, regexes)
assert test.match_stderr(lines, lines)
@@ -1257,10 +1260,10 @@ class match_stderr_TestCase(TestCmdTestCase):
test = TestCmd.TestCmd(match_stderr=TestCmd.TestCmd.match_exact)
assert not test.match_stderr("abcde\n", "a.*e\n")
assert test.match_stderr("abcde\n", "abcde\n")
- assert not test.match_stderr("12345\nabcde\n", "1\d+5\na.*e\n")
+ assert not test.match_stderr("12345\nabcde\n", "1\\d+5\na.*e\n")
assert test.match_stderr("12345\nabcde\n", "12345\nabcde\n")
lines = ["vwxyz\n", "67890\n"]
- regexes = ["v[^a-u]*z\n", "6[^ ]+0\n"]
+ regexes = [r"v[^a-u]*z\n", r"6[^ ]+0\n"]
assert not test.match_stderr(lines, regexes)
assert test.match_stderr(lines, lines)
@@ -1269,10 +1272,10 @@ class match_stderr_TestCase(TestCmdTestCase):
test = TestCmd.TestCmd(match_stderr='match_exact')
assert not test.match_stderr("abcde\n", "a.*e\n")
assert test.match_stderr("abcde\n", "abcde\n")
- assert not test.match_stderr("12345\nabcde\n", "1\d+5\na.*e\n")
+ assert not test.match_stderr("12345\nabcde\n", "1\\d+5\na.*e\n")
assert test.match_stderr("12345\nabcde\n", "12345\nabcde\n")
lines = ["vwxyz\n", "67890\n"]
- regexes = ["v[^a-u]*z\n", "6[^ ]+0\n"]
+ regexes = [r"v[^a-u]*z\n", r"6[^ ]+0\n"]
assert not test.match_stderr(lines, regexes)
assert test.match_stderr(lines, lines)
@@ -1285,7 +1288,7 @@ class match_stdout_TestCase(TestCmdTestCase):
assert test.match_stdout("abcde\n", "a.*e\n")
assert test.match_stdout("12345\nabcde\n", "1\\d+5\na.*e\n")
lines = ["vwxyz\n", "67890\n"]
- regexes = ["v[^a-u]*z\n", "6[^ ]+0\n"]
+ regexes = [r"v[^a-u]*z\n", r"6[^ ]+0\n"]
assert test.match_stdout(lines, regexes)
def test_match_stdout_not_affecting_match_stderr(self):
@@ -1297,14 +1300,14 @@ class match_stdout_TestCase(TestCmdTestCase):
assert not test.match_stdout("12345\nabcde\n", "1\\d+5\na.*e\n")
assert test.match_stdout("12345\nabcde\n", "12345\nabcde\n")
lines = ["vwxyz\n", "67890\n"]
- regexes = ["v[^a-u]*z\n", "6[^ ]+0\n"]
+ regexes = [r"v[^a-u]*z\n", r"6[^ ]+0\n"]
assert not test.match_stdout(lines, regexes)
assert test.match_stdout(lines, lines)
assert test.match_stderr("abcde\n", "a.*e\n")
assert test.match_stderr("12345\nabcde\n", "1\\d+5\na.*e\n")
lines = ["vwxyz\n", "67890\n"]
- regexes = ["v[^a-u]*z\n", "6[^ ]+0\n"]
+ regexes = [r"v[^a-u]*z\n", r"6[^ ]+0\n"]
assert test.match_stderr(lines, regexes)
def test_match_stdout_custom_function(self):
@@ -1317,7 +1320,7 @@ class match_stdout_TestCase(TestCmdTestCase):
assert not test.match_stdout("123\n123\n", "1\n1\n")
assert test.match_stdout("123\n123\n", "111\n111\n")
lines = ["123\n", "123\n"]
- regexes = ["1\n", "1\n"]
+ regexes = [r"1\n", r"1\n"]
assert test.match_stdout(lines, regexes) # equal numbers of lines
def test_match_stdout_TestCmd_function(self):
@@ -1325,10 +1328,10 @@ class match_stdout_TestCase(TestCmdTestCase):
test = TestCmd.TestCmd(match_stdout = TestCmd.match_exact)
assert not test.match_stdout("abcde\n", "a.*e\n")
assert test.match_stdout("abcde\n", "abcde\n")
- assert not test.match_stdout("12345\nabcde\n", "1\d+5\na.*e\n")
+ assert not test.match_stdout("12345\nabcde\n", "1\\d+5\na.*e\n")
assert test.match_stdout("12345\nabcde\n", "12345\nabcde\n")
lines = ["vwxyz\n", "67890\n"]
- regexes = ["v[^a-u]*z\n", "6[^ ]+0\n"]
+ regexes = [r"v[^a-u]*z\n", r"6[^ ]+0\n"]
assert not test.match_stdout(lines, regexes)
assert test.match_stdout(lines, lines)
@@ -1337,10 +1340,10 @@ class match_stdout_TestCase(TestCmdTestCase):
test = TestCmd.TestCmd(match_stdout=TestCmd.TestCmd.match_exact)
assert not test.match_stdout("abcde\n", "a.*e\n")
assert test.match_stdout("abcde\n", "abcde\n")
- assert not test.match_stdout("12345\nabcde\n", "1\d+5\na.*e\n")
+ assert not test.match_stdout("12345\nabcde\n", "1\\d+5\na.*e\n")
assert test.match_stdout("12345\nabcde\n", "12345\nabcde\n")
lines = ["vwxyz\n", "67890\n"]
- regexes = ["v[^a-u]*z\n", "6[^ ]+0\n"]
+ regexes = [r"v[^a-u]*z\n", r"6[^ ]+0\n"]
assert not test.match_stdout(lines, regexes)
assert test.match_stdout(lines, lines)
@@ -1349,10 +1352,10 @@ class match_stdout_TestCase(TestCmdTestCase):
test = TestCmd.TestCmd(match_stdout='match_exact')
assert not test.match_stdout("abcde\n", "a.*e\n")
assert test.match_stdout("abcde\n", "abcde\n")
- assert not test.match_stdout("12345\nabcde\n", "1\d+5\na.*e\n")
+ assert not test.match_stdout("12345\nabcde\n", "1\\d+5\na.*e\n")
assert test.match_stdout("12345\nabcde\n", "12345\nabcde\n")
lines = ["vwxyz\n", "67890\n"]
- regexes = ["v[^a-u]*z\n", "6[^ ]+0\n"]
+ regexes = [r"v[^a-u]*z\n", r"6[^ ]+0\n"]
assert not test.match_stdout(lines, regexes)
assert test.match_stdout(lines, lines)
@@ -1468,20 +1471,20 @@ class preserve_TestCase(TestCmdTestCase):
def test_preserve(self):
"""Test preserve()"""
def cleanup_test(test, cond=None, stdout=""):
- io = StringIO()
save = sys.stdout
- sys.stdout = io
- try:
- if cond:
- test.cleanup(cond)
- else:
- test.cleanup()
- o = io.getvalue()
- assert o == stdout, "o = `%s', stdout = `%s'" % (o, stdout)
- finally:
- sys.stdout = save
-
- test = TestCmd.TestCmd(workdir = '')
+ with closing(StringIO()) as io:
+ sys.stdout = io
+ try:
+ if cond:
+ test.cleanup(cond)
+ else:
+ test.cleanup()
+ o = io.getvalue()
+ assert o == stdout, "o = `%s', stdout = `%s'" % (o, stdout)
+ finally:
+ sys.stdout = save
+
+ test = TestCmd.TestCmd(workdir='')
wdir = test.workdir
try:
test.write('file1', "Test file #1\n")
@@ -1490,10 +1493,10 @@ class preserve_TestCase(TestCmdTestCase):
assert not os.path.exists(wdir)
finally:
if os.path.exists(wdir):
- shutil.rmtree(wdir, ignore_errors = 1)
+ shutil.rmtree(wdir, ignore_errors=1)
test._dirlist.remove(wdir)
- test = TestCmd.TestCmd(workdir = '')
+ test = TestCmd.TestCmd(workdir='')
wdir = test.workdir
try:
test.write('file2', "Test file #2\n")
@@ -1576,11 +1579,16 @@ class read_TestCase(TestCmdTestCase):
wdir_file4 = os.path.join(test.workdir, 'file4')
wdir_file5 = os.path.join(test.workdir, 'file5')
- open(wdir_file1, 'wb').write("")
- open(wdir_file2, 'wb').write("Test\nfile\n#2.\n")
- open(wdir_foo_file3, 'wb').write("Test\nfile\n#3.\n")
- open(wdir_file4, 'wb').write("Test\nfile\n#4.\n")
- open(wdir_file5, 'wb').write("Test\r\nfile\r\n#5.\r\n")
+ with open(wdir_file1, 'wb') as f:
+ f.write(to_bytes(""))
+ with open(wdir_file2, 'wb') as f:
+ f.write(to_bytes("Test\nfile\n#2.\n"))
+ with open(wdir_foo_file3, 'wb') as f:
+ f.write(to_bytes("Test\nfile\n#3.\n"))
+ with open(wdir_file4, 'wb') as f:
+ f.write(to_bytes("Test\nfile\n#4.\n"))
+ with open(wdir_file5, 'wb') as f:
+ f.write(to_bytes("Test\r\nfile\r\n#5.\r\n"))
try:
contents = test.read('no_file')
@@ -1597,6 +1605,7 @@ class read_TestCase(TestCmdTestCase):
raise
def _file_matches(file, contents, expected):
+ contents = to_str(contents)
assert contents == expected, \
"Expected contents of " + str(file) + "==========\n" + \
expected + \
@@ -1627,7 +1636,7 @@ class rmdir_TestCase(TestCmdTestCase):
except EnvironmentError:
pass
else:
- raise Exception("did not catch expected EnvironmentError")
+ raise Exception("did not catch expected SConsEnvironmentError")
test.subdir(['sub'],
['sub', 'dir'],
@@ -1642,7 +1651,7 @@ class rmdir_TestCase(TestCmdTestCase):
except EnvironmentError:
pass
else:
- raise Exception("did not catch expected EnvironmentError")
+ raise Exception("did not catch expected SConsEnvironmentError")
assert os.path.isdir(s_d_o), "%s is gone?" % s_d_o
@@ -1651,7 +1660,7 @@ class rmdir_TestCase(TestCmdTestCase):
except EnvironmentError:
pass
else:
- raise Exception("did not catch expected EnvironmentError")
+ raise Exception("did not catch expected SConsEnvironmentError")
assert os.path.isdir(s_d_o), "%s is gone?" % s_d_o
@@ -1867,29 +1876,25 @@ class run_verbose_TestCase(TestCmdTestCase):
workdir = '',
verbose = 1)
- sys.stdout = StringIO()
- sys.stderr = StringIO()
-
- test.run(arguments = ['arg1 arg2'])
- o = sys.stdout.getvalue()
- assert o == '', o
- e = sys.stderr.getvalue()
- expect = 'python "%s" "arg1 arg2"\n' % t.script_path
- assert expect == e, (expect, e)
+ with closing(StringIO()) as sys.stdout, closing(StringIO()) as sys.stderr:
+ test.run(arguments = ['arg1 arg2'])
+ o = sys.stdout.getvalue()
+ assert o == '', o
+ e = sys.stderr.getvalue()
+ expect = 'python "%s" "arg1 arg2"\n' % t.script_path
+ assert expect == e, (expect, e)
testx = TestCmd.TestCmd(program = t.scriptx,
workdir = '',
verbose = 1)
- sys.stdout = StringIO()
- sys.stderr = StringIO()
-
- testx.run(arguments = ['arg1 arg2'])
- expect = '"%s" "arg1 arg2"\n' % t.scriptx_path
- o = sys.stdout.getvalue()
- assert o == '', o
- e = sys.stderr.getvalue()
- assert expect == e, (expect, e)
+ with closing(StringIO()) as sys.stdout, closing(StringIO()) as sys.stderr:
+ testx.run(arguments = ['arg1 arg2'])
+ expect = '"%s" "arg1 arg2"\n' % t.scriptx_path
+ o = sys.stdout.getvalue()
+ assert o == '', o
+ e = sys.stderr.getvalue()
+ assert expect == e, (expect, e)
# Test calling TestCmd() with an explicit verbose = 2.
@@ -1918,43 +1923,39 @@ class run_verbose_TestCase(TestCmdTestCase):
workdir = '',
verbose = 2)
- sys.stdout = StringIO()
- sys.stderr = StringIO()
+ with closing(StringIO()) as sys.stdout, closing(StringIO()) as sys.stderr:
+ test.run(arguments = ['arg1 arg2'])
- test.run(arguments = ['arg1 arg2'])
+ line_fmt = "script: %s: %s: ['arg1 arg2']\n"
+ stdout_line = line_fmt % ('STDOUT', t.sub_dir)
+ stderr_line = line_fmt % ('STDERR', t.sub_dir)
+ expect = outerr_fmt % (len(stdout_line), stdout_line,
+ len(stderr_line), stderr_line)
+ o = sys.stdout.getvalue()
+ assert expect == o, (expect, o)
- line_fmt = "script: %s: %s: ['arg1 arg2']\n"
- stdout_line = line_fmt % ('STDOUT', t.sub_dir)
- stderr_line = line_fmt % ('STDERR', t.sub_dir)
- expect = outerr_fmt % (len(stdout_line), stdout_line,
- len(stderr_line), stderr_line)
- o = sys.stdout.getvalue()
- assert expect == o, (expect, o)
-
- expect = 'python "%s" "arg1 arg2"\n' % t.script_path
- e = sys.stderr.getvalue()
- assert e == expect, (e, expect)
+ expect = 'python "%s" "arg1 arg2"\n' % t.script_path
+ e = sys.stderr.getvalue()
+ assert e == expect, (e, expect)
testx = TestCmd.TestCmd(program = t.scriptx,
workdir = '',
verbose = 2)
- sys.stdout = StringIO()
- sys.stderr = StringIO()
-
- testx.run(arguments = ['arg1 arg2'])
+ with closing(StringIO()) as sys.stdout, closing(StringIO()) as sys.stderr:
+ testx.run(arguments = ['arg1 arg2'])
- line_fmt = "scriptx.bat: %s: %s: ['arg1 arg2']\n"
- stdout_line = line_fmt % ('STDOUT', t.sub_dir)
- stderr_line = line_fmt % ('STDERR', t.sub_dir)
- expect = outerr_fmt % (len(stdout_line), stdout_line,
- len(stderr_line), stderr_line)
- o = sys.stdout.getvalue()
- assert expect == o, (expect, o)
+ line_fmt = "scriptx.bat: %s: %s: ['arg1 arg2']\n"
+ stdout_line = line_fmt % ('STDOUT', t.sub_dir)
+ stderr_line = line_fmt % ('STDERR', t.sub_dir)
+ expect = outerr_fmt % (len(stdout_line), stdout_line,
+ len(stderr_line), stderr_line)
+ o = sys.stdout.getvalue()
+ assert expect == o, (expect, o)
- expect = '"%s" "arg1 arg2"\n' % t.scriptx_path
- e = sys.stderr.getvalue()
- assert e == expect, (e, expect)
+ expect = '"%s" "arg1 arg2"\n' % t.scriptx_path
+ e = sys.stderr.getvalue()
+ assert e == expect, (e, expect)
# Test calling TestCmd() with an explicit verbose = 3.
@@ -1963,41 +1964,37 @@ class run_verbose_TestCase(TestCmdTestCase):
workdir = '',
verbose = 2)
- sys.stdout = StringIO()
- sys.stderr = StringIO()
+ with closing(StringIO()) as sys.stdout, closing(StringIO()) as sys.stderr:
+ test.run(arguments = ['arg1 arg2'])
- test.run(arguments = ['arg1 arg2'])
+ line_fmt = "scriptout: %s: %s: ['arg1 arg2']\n"
+ stdout_line = line_fmt % ('STDOUT', t.sub_dir)
+ expect = out_fmt % (len(stdout_line), stdout_line)
+ o = sys.stdout.getvalue()
+ assert expect == o, (expect, o)
- line_fmt = "scriptout: %s: %s: ['arg1 arg2']\n"
- stdout_line = line_fmt % ('STDOUT', t.sub_dir)
- expect = out_fmt % (len(stdout_line), stdout_line)
- o = sys.stdout.getvalue()
- assert expect == o, (expect, o)
-
- e = sys.stderr.getvalue()
- expect = 'python "%s" "arg1 arg2"\n' % (t.scriptout_path)
- assert e == expect, (e, expect)
+ e = sys.stderr.getvalue()
+ expect = 'python "%s" "arg1 arg2"\n' % (t.scriptout_path)
+ assert e == expect, (e, expect)
test = TestCmd.TestCmd(program = t.scriptout,
interpreter = 'python',
workdir = '',
verbose = 3)
- sys.stdout = StringIO()
- sys.stderr = StringIO()
-
- test.run(arguments = ['arg1 arg2'])
+ with closing(StringIO()) as sys.stdout, closing(StringIO()) as sys.stderr:
+ test.run(arguments = ['arg1 arg2'])
- line_fmt = "scriptout: %s: %s: ['arg1 arg2']\n"
- stdout_line = line_fmt % ('STDOUT', t.sub_dir)
- expect = outerr_fmt % (len(stdout_line), stdout_line,
- '0', '')
- o = sys.stdout.getvalue()
- assert expect == o, (expect, o)
+ line_fmt = "scriptout: %s: %s: ['arg1 arg2']\n"
+ stdout_line = line_fmt % ('STDOUT', t.sub_dir)
+ expect = outerr_fmt % (len(stdout_line), stdout_line,
+ '0', '')
+ o = sys.stdout.getvalue()
+ assert expect == o, (expect, o)
- e = sys.stderr.getvalue()
- expect = 'python "%s" "arg1 arg2"\n' % (t.scriptout_path)
- assert e == expect, (e, expect)
+ e = sys.stderr.getvalue()
+ expect = 'python "%s" "arg1 arg2"\n' % (t.scriptout_path)
+ assert e == expect, (e, expect)
# Test letting TestCmd() pick up verbose = 2 from the environment.
@@ -2007,42 +2004,38 @@ class run_verbose_TestCase(TestCmdTestCase):
interpreter = 'python',
workdir = '')
- sys.stdout = StringIO()
- sys.stderr = StringIO()
+ with closing(StringIO()) as sys.stdout, closing(StringIO()) as sys.stderr:
+ test.run(arguments = ['arg1 arg2'])
- test.run(arguments = ['arg1 arg2'])
+ line_fmt = "script: %s: %s: ['arg1 arg2']\n"
+ stdout_line = line_fmt % ('STDOUT', t.sub_dir)
+ stderr_line = line_fmt % ('STDERR', t.sub_dir)
+ expect = outerr_fmt % (len(stdout_line), stdout_line,
+ len(stderr_line), stderr_line)
+ o = sys.stdout.getvalue()
+ assert expect == o, (expect, o)
- line_fmt = "script: %s: %s: ['arg1 arg2']\n"
- stdout_line = line_fmt % ('STDOUT', t.sub_dir)
- stderr_line = line_fmt % ('STDERR', t.sub_dir)
- expect = outerr_fmt % (len(stdout_line), stdout_line,
- len(stderr_line), stderr_line)
- o = sys.stdout.getvalue()
- assert expect == o, (expect, o)
-
- expect = 'python "%s" "arg1 arg2"\n' % t.script_path
- e = sys.stderr.getvalue()
- assert e == expect, (e, expect)
+ expect = 'python "%s" "arg1 arg2"\n' % t.script_path
+ e = sys.stderr.getvalue()
+ assert e == expect, (e, expect)
testx = TestCmd.TestCmd(program = t.scriptx,
workdir = '')
- sys.stdout = StringIO()
- sys.stderr = StringIO()
-
- testx.run(arguments = ['arg1 arg2'])
+ with closing(StringIO()) as sys.stdout, closing(StringIO()) as sys.stderr:
+ testx.run(arguments = ['arg1 arg2'])
- line_fmt = "scriptx.bat: %s: %s: ['arg1 arg2']\n"
- stdout_line = line_fmt % ('STDOUT', t.sub_dir)
- stderr_line = line_fmt % ('STDERR', t.sub_dir)
- expect = outerr_fmt % (len(stdout_line), stdout_line,
- len(stderr_line), stderr_line)
- o = sys.stdout.getvalue()
- assert expect == o, (expect, o)
+ line_fmt = "scriptx.bat: %s: %s: ['arg1 arg2']\n"
+ stdout_line = line_fmt % ('STDOUT', t.sub_dir)
+ stderr_line = line_fmt % ('STDERR', t.sub_dir)
+ expect = outerr_fmt % (len(stdout_line), stdout_line,
+ len(stderr_line), stderr_line)
+ o = sys.stdout.getvalue()
+ assert expect == o, (expect, o)
- expect = '"%s" "arg1 arg2"\n' % t.scriptx_path
- e = sys.stderr.getvalue()
- assert e == expect, (e, expect)
+ expect = '"%s" "arg1 arg2"\n' % t.scriptx_path
+ e = sys.stderr.getvalue()
+ assert e == expect, (e, expect)
# Test letting TestCmd() pick up verbose = 1 from the environment.
@@ -2053,29 +2046,25 @@ class run_verbose_TestCase(TestCmdTestCase):
workdir = '',
verbose = 1)
- sys.stdout = StringIO()
- sys.stderr = StringIO()
-
- test.run(arguments = ['arg1 arg2'])
- o = sys.stdout.getvalue()
- assert o == '', o
- e = sys.stderr.getvalue()
- expect = 'python "%s" "arg1 arg2"\n' % t.script_path
- assert expect == e, (expect, e)
+ with closing(StringIO()) as sys.stdout, closing(StringIO()) as sys.stderr:
+ test.run(arguments = ['arg1 arg2'])
+ o = sys.stdout.getvalue()
+ assert o == '', o
+ e = sys.stderr.getvalue()
+ expect = 'python "%s" "arg1 arg2"\n' % t.script_path
+ assert expect == e, (expect, e)
testx = TestCmd.TestCmd(program = t.scriptx,
workdir = '',
verbose = 1)
- sys.stdout = StringIO()
- sys.stderr = StringIO()
-
- testx.run(arguments = ['arg1 arg2'])
- expect = '"%s" "arg1 arg2"\n' % t.scriptx_path
- o = sys.stdout.getvalue()
- assert o == '', o
- e = sys.stderr.getvalue()
- assert expect == e, (expect, e)
+ with closing(StringIO()) as sys.stdout, closing(StringIO()) as sys.stderr:
+ testx.run(arguments = ['arg1 arg2'])
+ expect = '"%s" "arg1 arg2"\n' % t.scriptx_path
+ o = sys.stdout.getvalue()
+ assert o == '', o
+ e = sys.stderr.getvalue()
+ assert expect == e, (expect, e)
finally:
sys.stdout = save_stdout
@@ -2343,16 +2332,15 @@ sys.stderr = Unbuffered(sys.stderr)
sys.stdout.write('script_recv: STDOUT\\n')
sys.stderr.write('script_recv: STDERR\\n')
-logfp = open(r'%s', 'wb')
-while 1:
- line = sys.stdin.readline()
- if not line:
- break
- logfp.write('script_recv: ' + line)
- sys.stdout.write('script_recv: STDOUT: ' + line)
- sys.stderr.write('script_recv: STDERR: ' + line)
-logfp.close()
- """ % t.recv_out_path
+with open(r'%s', 'wb') as logfp:
+ while 1:
+ line = sys.stdin.readline()
+ if not line:
+ break
+ logfp.write('script_recv: ' + line)
+ sys.stdout.write('script_recv: STDOUT: ' + line)
+ sys.stderr.write('script_recv: STDERR: ' + line)
+""" % t.recv_out_path
t.run_env.write(t.recv_script_path, text)
os.chmod(t.recv_script_path, 0o644) # XXX UNIX-specific
return t
@@ -2618,10 +2606,11 @@ script_recv: STDERR: input
p = test.start(stdin=1)
input = 'stdin.write() input to the receive script\n'
- p.stdin.write(input)
+ p.stdin.write(to_bytes(input))
p.stdin.close()
p.wait()
- result = open(t.recv_out_path, 'rb').read()
+ with open(t.recv_out_path, 'rb') as f:
+ result = to_str(f.read())
expect = 'script_recv: ' + input
assert result == expect, repr(result)
@@ -2630,7 +2619,8 @@ script_recv: STDERR: input
p.send(input)
p.stdin.close()
p.wait()
- result = open(t.recv_out_path, 'rb').read()
+ with open(t.recv_out_path, 'rb') as f:
+ result = to_str(f.read())
expect = 'script_recv: ' + input
assert result == expect, repr(result)
@@ -2689,7 +2679,8 @@ script_recv: STDERR: input to the receive script
"""
assert stdout == expect_stdout, stdout
assert stderr == expect_stderr, stderr
- result = open(t.recv_out_path, 'rb').read()
+ with open(t.recv_out_path, 'rb') as f:
+ result = f.read()
expect = ('script_recv: ' + input) * 2
assert result == expect, (result, stdout, stderr)
@@ -2745,11 +2736,8 @@ sys.stderr.write("run2 STDERR second line\\n")
# Everything before this prepared our "source directory."
# Now do the real test.
test = TestCmd.TestCmd(interpreter = 'python', workdir = '')
- try:
- output = test.stdout()
- except IndexError:
- pass
- else:
+ output = test.stdout()
+ if output is not None:
raise IndexError("got unexpected output:\n\t`%s'\n" % output)
test.program_set('run1')
test.run(arguments = 'foo bar')
@@ -2807,15 +2795,18 @@ class symlink_TestCase(TestCmdTestCase):
test.symlink('target1', 'file1')
assert os.path.islink(wdir_file1)
assert not os.path.exists(wdir_file1)
- open(wdir_target1, 'w').write("")
+ with open(wdir_target1, 'w') as f:
+ f.write("")
assert os.path.exists(wdir_file1)
test.symlink('target2', ['foo', 'file2'])
assert os.path.islink(wdir_foo_file2)
assert not os.path.exists(wdir_foo_file2)
- open(wdir_target2, 'w').write("")
+ with open(wdir_target2, 'w') as f:
+ f.write("")
assert not os.path.exists(wdir_foo_file2)
- open(wdir_foo_target2, 'w').write("")
+ with open(wdir_foo_target2, 'w') as f:
+ f.write("")
assert os.path.exists(wdir_foo_file2)
@@ -2947,12 +2938,18 @@ class unlink_TestCase(TestCmdTestCase):
wdir_foo_file4 = os.path.join(test.workdir, 'foo', 'file4')
wdir_file5 = os.path.join(test.workdir, 'file5')
- open(wdir_file1, 'w').write("")
- open(wdir_file2, 'w').write("")
- open(wdir_foo_file3a, 'w').write("")
- open(wdir_foo_file3b, 'w').write("")
- open(wdir_foo_file4, 'w').write("")
- open(wdir_file5, 'w').write("")
+ with open(wdir_file1, 'w') as f:
+ f.write("")
+ with open(wdir_file2, 'w') as f:
+ f.write("")
+ with open(wdir_foo_file3a, 'w') as f:
+ f.write("")
+ with open(wdir_foo_file3b, 'w') as f:
+ f.write("")
+ with open(wdir_foo_file4, 'w') as f:
+ f.write("")
+ with open(wdir_file5, 'w') as f:
+ f.write("")
try:
contents = test.unlink('no_file')
@@ -2981,20 +2978,17 @@ class unlink_TestCase(TestCmdTestCase):
# For Windows, open the file.
os.chmod(test.workdir, 0o500)
os.chmod(wdir_file5, 0o400)
- f = open(wdir_file5, 'r')
-
- try:
+ with open(wdir_file5, 'r'):
try:
- test.unlink('file5')
- except OSError: # expect "Permission denied"
- pass
- except:
- raise
- finally:
- os.chmod(test.workdir, 0o700)
- os.chmod(wdir_file5, 0o600)
- f.close()
-
+ try:
+ test.unlink('file5')
+ except OSError: # expect "Permission denied"
+ pass
+ except:
+ raise
+ finally:
+ os.chmod(test.workdir, 0o700)
+ os.chmod(wdir_file5, 0o600)
class touch_TestCase(TestCmdTestCase):
@@ -3005,8 +2999,10 @@ class touch_TestCase(TestCmdTestCase):
wdir_file1 = os.path.join(test.workdir, 'file1')
wdir_sub_file2 = os.path.join(test.workdir, 'sub', 'file2')
- open(wdir_file1, 'w').write("")
- open(wdir_sub_file2, 'w').write("")
+ with open(wdir_file1, 'w') as f:
+ f.write("")
+ with open(wdir_sub_file2, 'w') as f:
+ f.write("")
file1_old_time = os.path.getmtime(wdir_file1)
file2_old_time = os.path.getmtime(wdir_sub_file2)
@@ -3312,9 +3308,12 @@ class write_TestCase(TestCmdTestCase):
if os.name != "nt":
assert not os.path.exists(test.workpath('file10'))
- assert open(test.workpath('file8'), 'r').read() == "Test file #8.\n"
- assert open(test.workpath('file9'), 'rb').read() == "Test file #9.\r\n"
-
+ with open(test.workpath('file8'), 'r') as f:
+ res = f.read()
+ assert res == "Test file #8.\n", res
+ with open(test.workpath('file9'), 'rb') as f:
+ res = to_str(f.read())
+ assert res == "Test file #9.\r\n", res
class variables_TestCase(TestCmdTestCase):
diff --git a/testing/framework/TestRuntest.py b/testing/framework/TestRuntest.py
index 64dcf17..e9ca524 100644
--- a/testing/framework/TestRuntest.py
+++ b/testing/framework/TestRuntest.py
@@ -14,7 +14,7 @@ attributes defined in this subclass.
# Copyright (c) 2001 - 2019 The SCons Foundation
-__revision__ = "testing/framework/TestRuntest.py 103260fce95bf5db1c35fb2371983087d85dd611 2019-07-13 18:25:30 bdbaddog"
+__revision__ = "testing/framework/TestRuntest.py e724ae812eb96f4858a132f5b8c769724744faf6 2019-07-21 00:04:47 bdeegan"
import os
import os.path
@@ -30,7 +30,7 @@ __all__.extend([ 'TestRuntest',
'pythonflags',
])
-if re.search('\s', python):
+if re.search(r'\s', python):
pythonstring = _python_
else:
pythonstring = python
diff --git a/testing/framework/TestSCons.py b/testing/framework/TestSCons.py
index e415291..2228423 100644
--- a/testing/framework/TestSCons.py
+++ b/testing/framework/TestSCons.py
@@ -15,7 +15,7 @@ attributes defined in this subclass.
# Copyright (c) 2001 - 2019 The SCons Foundation
from __future__ import division, print_function
-__revision__ = "testing/framework/TestSCons.py 103260fce95bf5db1c35fb2371983087d85dd611 2019-07-13 18:25:30 bdbaddog"
+__revision__ = "testing/framework/TestSCons.py e724ae812eb96f4858a132f5b8c769724744faf6 2019-07-21 00:04:47 bdeegan"
import os
import re
@@ -35,7 +35,7 @@ from TestCmd import PIPE
# here provides some independent verification that what we packaged
# conforms to what we expect.
-default_version = '3.0.5'
+default_version = '3.1.0'
python_version_unsupported = (2, 6, 0)
python_version_deprecated = (2, 7, 0)
@@ -44,7 +44,7 @@ python_version_deprecated = (2, 7, 0)
# line must remain "__ VERSION __" (without the spaces) so the built
# version in build/testing/framework/TestSCons.py contains the actual version
# string of the packages that have been built.
-SConsVersion = '3.0.5'
+SConsVersion = '3.1.0'
if SConsVersion == '__' + 'VERSION' + '__':
SConsVersion = default_version
@@ -682,6 +682,9 @@ class TestSCons(TestCommon):
"""
Initialize with a default external environment that uses a local
Java SDK in preference to whatever's found in the default PATH.
+
+ :param version: if set, match only that version
+ :return: the new env.
"""
if not self.external:
try:
@@ -698,11 +701,11 @@ class TestSCons(TestCommon):
if version:
if sys.platform == 'win32':
patterns = [
- 'C:/Program Files*/Java/jdk%s*/bin'%version,
+ 'C:/Program Files*/Java/jdk*%s*/bin' % version,
]
else:
patterns = [
- '/usr/java/jdk%s*/bin' % version,
+ '/usr/java/jdk%s*/bin' % version,
'/usr/lib/jvm/*-%s*/bin' % version,
'/usr/local/j2sdk%s*/bin' % version,
]
@@ -727,7 +730,10 @@ class TestSCons(TestCommon):
def java_where_includes(self,version=None):
"""
- Return java include paths compiling java jni code
+ Find include path needed for compiling java jni code.
+
+ :param version: if set, match only that version
+ :return: path to java headers
"""
import sys
@@ -761,6 +767,14 @@ class TestSCons(TestCommon):
return result
def java_where_java_home(self, version=None):
+ """
+ Find path to what would be JAVA_HOME.
+
+ SCons does not read JAVA_HOME from the environment, so deduce it.
+
+ :param version: if set, match only that version
+ :return: path where JDK components live
+ """
if sys.platform[:6] == 'darwin':
# osx 10.11, 10.12
home_tool = '/usr/libexec/java_home'
@@ -807,6 +821,12 @@ class TestSCons(TestCommon):
self.skip_test("Could not find Java " + java_bin_name + ", skipping test(s).\n")
def java_where_jar(self, version=None):
+ """
+ Find java archiver jar.
+
+ :param version: if set, match only that version
+ :return: path to jar
+ """
ENV = self.java_ENV(version)
if self.detect_tool('jar', ENV=ENV):
where_jar = self.detect('JAR', 'jar', ENV=ENV)
@@ -821,7 +841,10 @@ class TestSCons(TestCommon):
def java_where_java(self, version=None):
"""
- Return a path to the java executable.
+ Find java executable.
+
+ :param version: if set, match only that version
+ :return: path to the java rutime
"""
ENV = self.java_ENV(version)
where_java = self.where_is('java', ENV['PATH'])
@@ -835,7 +858,10 @@ class TestSCons(TestCommon):
def java_where_javac(self, version=None):
"""
- Return a path to the javac compiler.
+ Find java compiler.
+
+ :param version: if set, match only that version
+ :return: path to javac
"""
ENV = self.java_ENV(version)
if self.detect_tool('javac'):
@@ -851,15 +877,17 @@ class TestSCons(TestCommon):
arguments = '-version',
stderr=None,
status=None)
+ # Note recent versions output version info to stdout instead of stderr
if version:
- if self.stderr().find('javac %s' % version) == -1:
+ verf = 'javac %s' % version
+ if self.stderr().find(verf) == -1 and self.stdout().find(verf) == -1:
fmt = "Could not find javac for Java version %s, skipping test(s).\n"
self.skip_test(fmt % version)
else:
- m = re.search(r'javac (\d\.*\d)', self.stderr())
- # Java 11 outputs this to stdout
+ version_re = r'javac (\d*\.*\d)'
+ m = re.search(version_re, self.stderr())
if not m:
- m = re.search(r'javac (\d\.*\d)', self.stdout())
+ m = re.search(version_re, self.stdout())
if m:
version = m.group(1)
@@ -873,6 +901,16 @@ class TestSCons(TestCommon):
return where_javac, version
def java_where_javah(self, version=None):
+ """
+ Find java header generation tool.
+
+ TODO issue #3347 since JDK10, there is no separate javah command,
+ 'javac -h' is used. We should not return a javah from a different
+ installed JDK - how to detect and what to return in this case?
+
+ :param version: if set, match only that version
+ :return: path to javah
+ """
ENV = self.java_ENV(version)
if self.detect_tool('javah'):
where_javah = self.detect('JAVAH', 'javah', ENV=ENV)
@@ -883,6 +921,12 @@ class TestSCons(TestCommon):
return where_javah
def java_where_rmic(self, version=None):
+ """
+ Find java rmic tool.
+
+ :param version: if set, match only that version
+ :return: path to rmic
+ """
ENV = self.java_ENV(version)
if self.detect_tool('rmic'):
where_rmic = self.detect('RMIC', 'rmic', ENV=ENV)
@@ -905,7 +949,7 @@ class TestSCons(TestCommon):
def Qt_dummy_installation(self, dir='qt'):
# create a dummy qt installation
- self.subdir( dir, [dir, 'bin'], [dir, 'include'], [dir, 'lib'] )
+ self.subdir(dir, [dir, 'bin'], [dir, 'include'], [dir, 'lib'])
self.write([dir, 'bin', 'mymoc.py'], """\
import getopt
@@ -913,23 +957,23 @@ import sys
import re
# -w and -z are fake options used in test/QT/QTFLAGS.py
cmd_opts, args = getopt.getopt(sys.argv[1:], 'io:wz', [])
-output = None
impl = 0
opt_string = ''
for opt, arg in cmd_opts:
- if opt == '-o': output = open(arg, 'w')
+ if opt == '-o': outfile = arg
elif opt == '-i': impl = 1
else: opt_string = opt_string + ' ' + opt
-output.write("/* mymoc.py%s */\\n" % opt_string)
-for a in args:
- with open(a, 'r') as f:
- contents = f.read()
- a = a.replace('\\\\', '\\\\\\\\')
- subst = r'{ my_qt_symbol( "' + a + '\\\\n" ); }'
- if impl:
- contents = re.sub( r'#include.*', '', contents )
- output.write(contents.replace('Q_OBJECT', subst))
-output.close()
+
+with open(outfile, 'w') as ofp:
+ ofp.write("/* mymoc.py%s */\\n" % opt_string)
+ for a in args:
+ with open(a, 'r') as ifp:
+ contents = ifp.read()
+ a = a.replace('\\\\', '\\\\\\\\')
+ subst = r'{ my_qt_symbol( "' + a + '\\\\n" ); }'
+ if impl:
+ contents = re.sub(r'#include.*', '', contents)
+ ofp.write(contents.replace('Q_OBJECT', subst))
sys.exit(0)
""")
@@ -944,7 +988,7 @@ source = None
opt_string = ''
for arg in sys.argv[1:]:
if output_arg:
- output = open(arg, 'w')
+ outfile = arg
output_arg = 0
elif impl_arg:
impl = arg
@@ -958,19 +1002,19 @@ for arg in sys.argv[1:]:
else:
if source:
sys.exit(1)
- source = open(arg, 'r')
- sourceFile = arg
-output.write("/* myuic.py%s */\\n" % opt_string)
-if impl:
- output.write( '#include "' + impl + '"\\n' )
- includes = re.findall('<include.*?>(.*?)</include>', source.read())
- for incFile in includes:
- # this is valid for ui.h files, at least
- if os.path.exists(incFile):
- output.write('#include "' + incFile + '"\\n')
-else:
- output.write( '#include "my_qobject.h"\\n' + source.read() + " Q_OBJECT \\n" )
-output.close()
+ source = sourceFile = arg
+
+with open(outfile, 'w') as ofp, open(source, 'r') as ifp:
+ ofp.write("/* myuic.py%s */\\n" % opt_string)
+ if impl:
+ ofp.write('#include "' + impl + '"\\n')
+ includes = re.findall('<include.*?>(.*?)</include>', ifp.read())
+ for incFile in includes:
+ # this is valid for ui.h files, at least
+ if os.path.exists(incFile):
+ ofp.write('#include "' + incFile + '"\\n')
+ else:
+ ofp.write('#include "my_qobject.h"\\n' + ifp.read() + " Q_OBJECT \\n")
sys.exit(0)
""" )
@@ -983,7 +1027,7 @@ void my_qt_symbol(const char *arg);
#include "../include/my_qobject.h"
#include <stdio.h>
void my_qt_symbol(const char *arg) {
- fputs( arg, stdout );
+ fputs(arg, stdout);
}
""")
@@ -991,9 +1035,9 @@ void my_qt_symbol(const char *arg) {
env = Environment()
import sys
if sys.platform == 'win32':
- env.StaticLibrary( 'myqt', 'my_qobject.cpp' )
+ env.StaticLibrary('myqt', 'my_qobject.cpp')
else:
- env.SharedLibrary( 'myqt', 'my_qobject.cpp' )
+ env.SharedLibrary('myqt', 'my_qobject.cpp')
""")
self.run(chdir = self.workpath(dir, 'lib'),
@@ -1036,7 +1080,7 @@ if ARGUMENTS.get('variant_dir', 0):
else:
sconscript = File('SConscript')
Export("env dup")
-SConscript( sconscript )
+SConscript(sconscript)
""" % (self.QT, self.QT_LIB, self.QT_MOC, self.QT_UIC))
diff --git a/testing/framework/TestSConsMSVS.py b/testing/framework/TestSConsMSVS.py
index 09cb5ee..86935fd 100644
--- a/testing/framework/TestSConsMSVS.py
+++ b/testing/framework/TestSConsMSVS.py
@@ -15,7 +15,7 @@ in this subclass.
# Copyright (c) 2001 - 2019 The SCons Foundation
-__revision__ = "testing/framework/TestSConsMSVS.py 103260fce95bf5db1c35fb2371983087d85dd611 2019-07-13 18:25:30 bdbaddog"
+__revision__ = "testing/framework/TestSConsMSVS.py e724ae812eb96f4858a132f5b8c769724744faf6 2019-07-21 00:04:47 bdeegan"
import os
import sys
@@ -23,6 +23,7 @@ import platform
import traceback
from xml.etree import ElementTree
+import SCons.Errors
from TestSCons import *
from TestSCons import __all__
@@ -38,18 +39,18 @@ expected_dspfile_6_0 = '''\
CFG=Test - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "Test.mak".
-!MESSAGE
+!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
+!MESSAGE
!MESSAGE NMAKE /f "Test.mak" CFG="Test - Win32 Release"
-!MESSAGE
+!MESSAGE
!MESSAGE Possible choices for configuration are:
-!MESSAGE
+!MESSAGE
!MESSAGE "Test - Win32 Release" (based on "Win32 (x86) External Target")
-!MESSAGE
+!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
@@ -85,7 +86,7 @@ CFG=Test - Win32 Release
!IF "$(CFG)" == "Test - Win32 Release"
-!ENDIF
+!ENDIF
# Begin Group "Header Files"
@@ -435,31 +436,10 @@ env.MSVSProject(target = 'Test.vcproj',
"""
-
-expected_slnfile_8_0 = """\
-Microsoft Visual Studio Solution File, Format Version 9.00
-# Visual Studio 2005
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Test", "Test.vcproj", "<PROJECT_GUID>"
-EndProject
-Global
-<SCC_SLN_INFO>
-\tGlobalSection(SolutionConfigurationPlatforms) = preSolution
-\t\tRelease|Win32 = Release|Win32
-\tEndGlobalSection
-\tGlobalSection(ProjectConfigurationPlatforms) = postSolution
-\t\t<PROJECT_GUID>.Release|Win32.ActiveCfg = Release|Win32
-\t\t<PROJECT_GUID>.Release|Win32.Build.0 = Release|Win32
-\tEndGlobalSection
-\tGlobalSection(SolutionProperties) = preSolution
-\t\tHideSolutionNode = FALSE
-\tEndGlobalSection
-EndGlobal
-"""
-
-expected_slnfile_9_0 = """\
-Microsoft Visual Studio Solution File, Format Version 10.00
-# Visual Studio 2008
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Test", "Test.vcproj", "<PROJECT_GUID>"
+expected_slnfile_fmt = """\
+Microsoft Visual Studio Solution File, Format Version %(FORMAT_VERSION)s
+# Visual Studio %(VS_NUMBER)s
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "%(PROJECT_NAME)s", "%(PROJECT_FILE)s", "<PROJECT_GUID>"
EndProject
Global
<SCC_SLN_INFO>
@@ -476,91 +456,11 @@ Global
EndGlobal
"""
-expected_slnfile_10_0 = """\
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Test.vcxproj", "Test.vcxproj", "{39A97E1F-1A52-8954-A0B1-A10A8487545E}"
-EndProject
-Global
-<SCC_SLN_INFO>
-\tGlobalSection(SolutionConfigurationPlatforms) = preSolution
-\t\tRelease|Win32 = Release|Win32
-\tEndGlobalSection
-\tGlobalSection(ProjectConfigurationPlatforms) = postSolution
-\t\t{39A97E1F-1A52-8954-A0B1-A10A8487545E}.Release|Win32.ActiveCfg = Release|Win32
-\t\t{39A97E1F-1A52-8954-A0B1-A10A8487545E}.Release|Win32.Build.0 = Release|Win32
-\tEndGlobalSection
-\tGlobalSection(SolutionProperties) = preSolution
-\t\tHideSolutionNode = FALSE
-\tEndGlobalSection
-EndGlobal
-"""
-
-expected_slnfile_11_0 = """\
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 11
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Test.vcxproj", "Test.vcxproj", "{39A97E1F-1A52-8954-A0B1-A10A8487545E}"
-EndProject
-Global
-<SCC_SLN_INFO>
-\tGlobalSection(SolutionConfigurationPlatforms) = preSolution
-\t\tRelease|Win32 = Release|Win32
-\tEndGlobalSection
-\tGlobalSection(ProjectConfigurationPlatforms) = postSolution
-\t\t{39A97E1F-1A52-8954-A0B1-A10A8487545E}.Release|Win32.ActiveCfg = Release|Win32
-\t\t{39A97E1F-1A52-8954-A0B1-A10A8487545E}.Release|Win32.Build.0 = Release|Win32
-\tEndGlobalSection
-\tGlobalSection(SolutionProperties) = preSolution
-\t\tHideSolutionNode = FALSE
-\tEndGlobalSection
-EndGlobal
-"""
-
-expected_slnfile_14_0 = """\
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 14
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Test.vcxproj", "Test.vcxproj", "{39A97E1F-1A52-8954-A0B1-A10A8487545E}"
-EndProject
-Global
-<SCC_SLN_INFO>
-\tGlobalSection(SolutionConfigurationPlatforms) = preSolution
-\t\tRelease|Win32 = Release|Win32
-\tEndGlobalSection
-\tGlobalSection(ProjectConfigurationPlatforms) = postSolution
-\t\t{39A97E1F-1A52-8954-A0B1-A10A8487545E}.Release|Win32.ActiveCfg = Release|Win32
-\t\t{39A97E1F-1A52-8954-A0B1-A10A8487545E}.Release|Win32.Build.0 = Release|Win32
-\tEndGlobalSection
-\tGlobalSection(SolutionProperties) = preSolution
-\t\tHideSolutionNode = FALSE
-\tEndGlobalSection
-EndGlobal
-"""
-
-expected_slnfile_14_1 = """\
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 15
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Test.vcxproj", "Test.vcxproj", "{39A97E1F-1A52-8954-A0B1-A10A8487545E}"
-EndProject
-Global
-<SCC_SLN_INFO>
-\tGlobalSection(SolutionConfigurationPlatforms) = preSolution
-\t\tRelease|Win32 = Release|Win32
-\tEndGlobalSection
-\tGlobalSection(ProjectConfigurationPlatforms) = postSolution
-\t\t{39A97E1F-1A52-8954-A0B1-A10A8487545E}.Release|Win32.ActiveCfg = Release|Win32
-\t\t{39A97E1F-1A52-8954-A0B1-A10A8487545E}.Release|Win32.Build.0 = Release|Win32
-\tEndGlobalSection
-\tGlobalSection(SolutionProperties) = preSolution
-\t\tHideSolutionNode = FALSE
-\tEndGlobalSection
-EndGlobal
-"""
-
-expected_vcprojfile_8_0 = """\
+expected_vcprojfile_fmt = """\
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
\tProjectType="Visual C++"
-\tVersion="8.00"
+\tVersion="%(TOOLS_VERSION)s"
\tName="Test"
\tProjectGUID="<PROJECT_GUID>"
\tRootNamespace="Test"
@@ -586,7 +486,7 @@ expected_vcprojfile_8_0 = """\
\t\t\t\tCleanCommandLine="echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct -c &quot;Test.exe&quot;"
\t\t\t\tOutput="Test.exe"
\t\t\t\tPreprocessorDefinitions="DEF1;DEF2;DEF3=1234"
-\t\t\t\tIncludeSearchPath="inc1;inc2"
+\t\t\t\tIncludeSearchPath="%(INCLUDE_DIRS)s"
\t\t\t\tForcedIncludes=""
\t\t\t\tAssemblySearchPath=""
\t\t\t\tForcedUsingAssemblies=""
@@ -601,7 +501,7 @@ expected_vcprojfile_8_0 = """\
\t\t\tName="Header Files"
\t\t\tFilter="h;hpp;hxx;hm;inl">
\t\t\t<File
-\t\t\t\tRelativePath="sdk.h">
+\t\t\t\tRelativePath="sdk_dir\\sdk.h">
\t\t\t</File>
\t\t</Filter>
\t\t<Filter
@@ -644,97 +544,9 @@ expected_vcprojfile_8_0 = """\
</VisualStudioProject>
"""
-expected_vcprojfile_9_0 = """\
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
-\tProjectType="Visual C++"
-\tVersion="9.00"
-\tName="Test"
-\tProjectGUID="<PROJECT_GUID>"
-\tRootNamespace="Test"
-<SCC_VCPROJ_INFO>
-\tKeyword="MakeFileProj">
-\t<Platforms>
-\t\t<Platform
-\t\t\tName="Win32"/>
-\t</Platforms>
-\t<ToolFiles>
-\t</ToolFiles>
-\t<Configurations>
-\t\t<Configuration
-\t\t\tName="Release|Win32"
-\t\t\tConfigurationType="0"
-\t\t\tUseOfMFC="0"
-\t\t\tATLMinimizesCRunTimeLibraryUsage="false"
-\t\t\t>
-\t\t\t<Tool
-\t\t\t\tName="VCNMakeTool"
-\t\t\t\tBuildCommandLine="echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct &quot;Test.exe&quot;"
-\t\t\t\tReBuildCommandLine="echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct &quot;Test.exe&quot;"
-\t\t\t\tCleanCommandLine="echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct -c &quot;Test.exe&quot;"
-\t\t\t\tOutput="Test.exe"
-\t\t\t\tPreprocessorDefinitions="DEF1;DEF2;DEF3=1234"
-\t\t\t\tIncludeSearchPath="inc1;inc2"
-\t\t\t\tForcedIncludes=""
-\t\t\t\tAssemblySearchPath=""
-\t\t\t\tForcedUsingAssemblies=""
-\t\t\t\tCompileAsManaged=""
-\t\t\t/>
-\t\t</Configuration>
-\t</Configurations>
-\t<References>
-\t</References>
-\t<Files>
-\t\t<Filter
-\t\t\tName="Header Files"
-\t\t\tFilter="h;hpp;hxx;hm;inl">
-\t\t\t<File
-\t\t\t\tRelativePath="sdk.h">
-\t\t\t</File>
-\t\t</Filter>
-\t\t<Filter
-\t\t\tName="Local Headers"
-\t\t\tFilter="h;hpp;hxx;hm;inl">
-\t\t\t<File
-\t\t\t\tRelativePath="test.h">
-\t\t\t</File>
-\t\t</Filter>
-\t\t<Filter
-\t\t\tName="Other Files"
-\t\t\tFilter="">
-\t\t\t<File
-\t\t\t\tRelativePath="readme.txt">
-\t\t\t</File>
-\t\t</Filter>
-\t\t<Filter
-\t\t\tName="Resource Files"
-\t\t\tFilter="r;rc;ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe">
-\t\t\t<File
-\t\t\t\tRelativePath="test.rc">
-\t\t\t</File>
-\t\t</Filter>
-\t\t<Filter
-\t\t\tName="Source Files"
-\t\t\tFilter="cpp;c;cxx;l;y;def;odl;idl;hpj;bat">
-\t\t\t<File
-\t\t\t\tRelativePath="test1.cpp">
-\t\t\t</File>
-\t\t\t<File
-\t\t\t\tRelativePath="test2.cpp">
-\t\t\t</File>
-\t\t</Filter>
-\t\t<File
-\t\t\tRelativePath="<SCONSCRIPT>">
-\t\t</File>
-\t</Files>
-\t<Globals>
-\t</Globals>
-</VisualStudioProject>
-"""
-
-expected_vcprojfile_10_0 = """\
+expected_vcxprojfile_fmt = """\
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" ToolsVersion="%(TOOLS_VERSION)s" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
\t<ItemGroup Label="ProjectConfigurations">
\t\t<ProjectConfiguration Include="Release|Win32">
\t\t\t<Configuration>Release</Configuration>
@@ -746,6 +558,7 @@ expected_vcprojfile_10_0 = """\
<SCC_VCPROJ_INFO>
\t\t<RootNamespace>Test</RootNamespace>
\t\t<Keyword>MakeFileProj</Keyword>
+\t\t<VCProjectUpgraderObjectName>NoUpgrade</VCProjectUpgraderObjectName>
\t</PropertyGroup>
\t<Import Project="$(VCTargetsPath)\\Microsoft.Cpp.Default.props" />
\t<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
@@ -767,13 +580,13 @@ expected_vcprojfile_10_0 = """\
\t\t<NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct -c &quot;Test.exe&quot;</NMakeCleanCommandLine>
\t\t<NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Test.exe</NMakeOutput>
\t\t<NMakePreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">DEF1;DEF2;DEF3=1234</NMakePreprocessorDefinitions>
-\t\t<NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">inc1;inc2</NMakeIncludeSearchPath>
+\t\t<NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(INCLUDE_DIRS)s</NMakeIncludeSearchPath>
\t\t<NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(NMakeForcedIncludes)</NMakeForcedIncludes>
\t\t<NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(NMakeAssemblySearchPath)</NMakeAssemblySearchPath>
\t\t<NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(NMakeForcedUsingAssemblies)</NMakeForcedUsingAssemblies>
\t</PropertyGroup>
\t<ItemGroup>
-\t\t<ClInclude Include="sdk_dir\sdk.h" />
+\t\t<ClInclude Include="sdk_dir\\sdk.h" />
\t</ItemGroup>
\t<ItemGroup>
\t\t<ClInclude Include="test.h" />
@@ -797,237 +610,19 @@ expected_vcprojfile_10_0 = """\
</Project>
"""
-expected_vcprojfile_11_0 = """\
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-\t<ItemGroup Label="ProjectConfigurations">
-\t\t<ProjectConfiguration Include="Release|Win32">
-\t\t\t<Configuration>Release</Configuration>
-\t\t\t<Platform>Win32</Platform>
-\t\t</ProjectConfiguration>
-\t</ItemGroup>
-\t<PropertyGroup Label="Globals">
-\t\t<ProjectGuid>{39A97E1F-1A52-8954-A0B1-A10A8487545E}</ProjectGuid>
-<SCC_VCPROJ_INFO>
-\t\t<RootNamespace>Test</RootNamespace>
-\t\t<Keyword>MakeFileProj</Keyword>
-\t</PropertyGroup>
-\t<Import Project="$(VCTargetsPath)\\Microsoft.Cpp.Default.props" />
-\t<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-\t\t<ConfigurationType>Makefile</ConfigurationType>
-\t\t<UseOfMfc>false</UseOfMfc>
-\t\t<PlatformToolset>v110</PlatformToolset>
-\t</PropertyGroup>
-\t<Import Project="$(VCTargetsPath)\\Microsoft.Cpp.props" />
-\t<ImportGroup Label="ExtensionSettings">
-\t</ImportGroup>
-\t<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
-\t\t<Import Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-\t</ImportGroup>
-\t<PropertyGroup Label="UserMacros" />
-\t<PropertyGroup>
-\t<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
-\t\t<NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct &quot;Test.exe&quot;</NMakeBuildCommandLine>
-\t\t<NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct &quot;Test.exe&quot;</NMakeReBuildCommandLine>
-\t\t<NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct -c &quot;Test.exe&quot;</NMakeCleanCommandLine>
-\t\t<NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Test.exe</NMakeOutput>
-\t\t<NMakePreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">DEF1;DEF2;DEF3=1234</NMakePreprocessorDefinitions>
-\t\t<NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">inc1;inc2</NMakeIncludeSearchPath>
-\t\t<NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(NMakeForcedIncludes)</NMakeForcedIncludes>
-\t\t<NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(NMakeAssemblySearchPath)</NMakeAssemblySearchPath>
-\t\t<NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(NMakeForcedUsingAssemblies)</NMakeForcedUsingAssemblies>
-\t</PropertyGroup>
-\t<ItemGroup>
-\t\t<ClInclude Include="sdk_dir\sdk.h" />
-\t</ItemGroup>
-\t<ItemGroup>
-\t\t<ClInclude Include="test.h" />
-\t</ItemGroup>
-\t<ItemGroup>
-\t\t<None Include="readme.txt" />
-\t</ItemGroup>
-\t<ItemGroup>
-\t\t<None Include="test.rc" />
-\t</ItemGroup>
-\t<ItemGroup>
-\t\t<ClCompile Include="test1.cpp" />
-\t\t<ClCompile Include="test2.cpp" />
-\t</ItemGroup>
-\t<ItemGroup>
-\t\t<None Include="SConstruct" />
-\t</ItemGroup>
-\t<Import Project="$(VCTargetsPath)\\Microsoft.Cpp.targets" />
-\t<ImportGroup Label="ExtensionTargets">
-\t</ImportGroup>
-</Project>
-"""
-
-expected_vcprojfile_14_0 = """\
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-\t<ItemGroup Label="ProjectConfigurations">
-\t\t<ProjectConfiguration Include="Release|Win32">
-\t\t\t<Configuration>Release</Configuration>
-\t\t\t<Platform>Win32</Platform>
-\t\t</ProjectConfiguration>
-\t</ItemGroup>
-\t<PropertyGroup Label="Globals">
-\t\t<ProjectGuid>{39A97E1F-1A52-8954-A0B1-A10A8487545E}</ProjectGuid>
-<SCC_VCPROJ_INFO>
-\t\t<RootNamespace>Test</RootNamespace>
-\t\t<Keyword>MakeFileProj</Keyword>
-\t</PropertyGroup>
-\t<Import Project="$(VCTargetsPath)\\Microsoft.Cpp.Default.props" />
-\t<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-\t\t<ConfigurationType>Makefile</ConfigurationType>
-\t\t<UseOfMfc>false</UseOfMfc>
-\t\t<PlatformToolset>v140</PlatformToolset>
-\t</PropertyGroup>
-\t<Import Project="$(VCTargetsPath)\\Microsoft.Cpp.props" />
-\t<ImportGroup Label="ExtensionSettings">
-\t</ImportGroup>
-\t<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
-\t\t<Import Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-\t</ImportGroup>
-\t<PropertyGroup Label="UserMacros" />
-\t<PropertyGroup>
-\t<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
-\t\t<NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct &quot;Test.exe&quot;</NMakeBuildCommandLine>
-\t\t<NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct &quot;Test.exe&quot;</NMakeReBuildCommandLine>
-\t\t<NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct -c &quot;Test.exe&quot;</NMakeCleanCommandLine>
-\t\t<NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Test.exe</NMakeOutput>
-\t\t<NMakePreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">DEF1;DEF2;DEF3=1234</NMakePreprocessorDefinitions>
-\t\t<NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">inc1;inc2</NMakeIncludeSearchPath>
-\t\t<NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(NMakeForcedIncludes)</NMakeForcedIncludes>
-\t\t<NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(NMakeAssemblySearchPath)</NMakeAssemblySearchPath>
-\t\t<NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(NMakeForcedUsingAssemblies)</NMakeForcedUsingAssemblies>
-\t</PropertyGroup>
-\t<ItemGroup>
-\t\t<ClInclude Include="sdk_dir\sdk.h" />
-\t</ItemGroup>
-\t<ItemGroup>
-\t\t<ClInclude Include="test.h" />
-\t</ItemGroup>
-\t<ItemGroup>
-\t\t<None Include="readme.txt" />
-\t</ItemGroup>
-\t<ItemGroup>
-\t\t<None Include="test.rc" />
-\t</ItemGroup>
-\t<ItemGroup>
-\t\t<ClCompile Include="test1.cpp" />
-\t\t<ClCompile Include="test2.cpp" />
-\t</ItemGroup>
-\t<ItemGroup>
-\t\t<None Include="SConstruct" />
-\t</ItemGroup>
-\t<Import Project="$(VCTargetsPath)\\Microsoft.Cpp.targets" />
-\t<ImportGroup Label="ExtensionTargets">
-\t</ImportGroup>
-</Project>
-"""
-
-expected_vcprojfile_14_1 = """\
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-\t<ItemGroup Label="ProjectConfigurations">
-\t\t<ProjectConfiguration Include="Release|Win32">
-\t\t\t<Configuration>Release</Configuration>
-\t\t\t<Platform>Win32</Platform>
-\t\t</ProjectConfiguration>
-\t</ItemGroup>
-\t<PropertyGroup Label="Globals">
-\t\t<ProjectGuid>{39A97E1F-1A52-8954-A0B1-A10A8487545E}</ProjectGuid>
-<SCC_VCPROJ_INFO>
-\t\t<RootNamespace>Test</RootNamespace>
-\t\t<Keyword>MakeFileProj</Keyword>
-\t</PropertyGroup>
-\t<Import Project="$(VCTargetsPath)\\Microsoft.Cpp.Default.props" />
-\t<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
-\t\t<ConfigurationType>Makefile</ConfigurationType>
-\t\t<UseOfMfc>false</UseOfMfc>
-\t\t<PlatformToolset>v141</PlatformToolset>
-\t</PropertyGroup>
-\t<Import Project="$(VCTargetsPath)\\Microsoft.Cpp.props" />
-\t<ImportGroup Label="ExtensionSettings">
-\t</ImportGroup>
-\t<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
-\t\t<Import Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
-\t</ImportGroup>
-\t<PropertyGroup Label="UserMacros" />
-\t<PropertyGroup>
-\t<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
-\t\t<NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct &quot;Test.exe&quot;</NMakeBuildCommandLine>
-\t\t<NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct &quot;Test.exe&quot;</NMakeReBuildCommandLine>
-\t\t<NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">echo Starting SCons &amp;&amp; &quot;<PYTHON>&quot; -c &quot;<SCONS_SCRIPT_MAIN_XML>&quot; -C &quot;<WORKPATH>&quot; -f SConstruct -c &quot;Test.exe&quot;</NMakeCleanCommandLine>
-\t\t<NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Test.exe</NMakeOutput>
-\t\t<NMakePreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">DEF1;DEF2;DEF3=1234</NMakePreprocessorDefinitions>
-\t\t<NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">inc1;inc2</NMakeIncludeSearchPath>
-\t\t<NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(NMakeForcedIncludes)</NMakeForcedIncludes>
-\t\t<NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(NMakeAssemblySearchPath)</NMakeAssemblySearchPath>
-\t\t<NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(NMakeForcedUsingAssemblies)</NMakeForcedUsingAssemblies>
-\t</PropertyGroup>
-\t<ItemGroup>
-\t\t<ClInclude Include="sdk_dir\sdk.h" />
-\t</ItemGroup>
-\t<ItemGroup>
-\t\t<ClInclude Include="test.h" />
-\t</ItemGroup>
-\t<ItemGroup>
-\t\t<None Include="readme.txt" />
-\t</ItemGroup>
-\t<ItemGroup>
-\t\t<None Include="test.rc" />
-\t</ItemGroup>
-\t<ItemGroup>
-\t\t<ClCompile Include="test1.cpp" />
-\t\t<ClCompile Include="test2.cpp" />
-\t</ItemGroup>
-\t<ItemGroup>
-\t\t<None Include="SConstruct" />
-\t</ItemGroup>
-\t<Import Project="$(VCTargetsPath)\\Microsoft.Cpp.targets" />
-\t<ImportGroup Label="ExtensionTargets">
-\t</ImportGroup>
-</Project>
-"""
-
-SConscript_contents_8_0 = """\
-env=Environment(platform='win32', tools=['msvs'], MSVS_VERSION='8.0',
- CPPDEFINES=['DEF1', 'DEF2',('DEF3','1234')],
- CPPPATH=['inc1', 'inc2'],
- HOST_ARCH='%(HOST_ARCH)s')
-
-testsrc = ['test1.cpp', 'test2.cpp']
-testincs = ['sdk.h']
-testlocalincs = ['test.h']
-testresources = ['test.rc']
-testmisc = ['readme.txt']
-
-env.MSVSProject(target = 'Test.vcproj',
- slnguid = '{SLNGUID}',
- srcs = testsrc,
- incs = testincs,
- localincs = testlocalincs,
- resources = testresources,
- misc = testmisc,
- buildtarget = 'Test.exe',
- variant = 'Release')
-"""
-
-SConscript_contents_9_0 = """\
-env=Environment(platform='win32', tools=['msvs'], MSVS_VERSION='9.0',
+SConscript_contents_fmt = """\
+env=Environment(platform='win32', tools=['msvs'], MSVS_VERSION='%(MSVS_VERSION)s',
CPPDEFINES=['DEF1', 'DEF2',('DEF3','1234')],
CPPPATH=['inc1', 'inc2'],
HOST_ARCH='%(HOST_ARCH)s')
testsrc = ['test1.cpp', 'test2.cpp']
-testincs = ['sdk.h']
+testincs = [r'sdk_dir\\sdk.h']
testlocalincs = ['test.h']
testresources = ['test.rc']
testmisc = ['readme.txt']
-env.MSVSProject(target = 'Test.vcproj',
+env.MSVSProject(target = '%(PROJECT_FILE)s',
slnguid = '{SLNGUID}',
srcs = testsrc,
incs = testincs,
@@ -1038,97 +633,13 @@ env.MSVSProject(target = 'Test.vcproj',
variant = 'Release')
"""
-SConscript_contents_10_0 = """\
-env=Environment(platform='win32', tools=['msvs'], MSVS_VERSION='10.0',
- CPPDEFINES=['DEF1', 'DEF2',('DEF3','1234')],
- CPPPATH=['inc1', 'inc2'],
- HOST_ARCH='%(HOST_ARCH)s')
-testsrc = ['test1.cpp', 'test2.cpp']
-testincs = ['sdk_dir\sdk.h']
-testlocalincs = ['test.h']
-testresources = ['test.rc']
-testmisc = ['readme.txt']
+def get_tested_proj_file_vc_versions():
+ """
+ Returns all MSVC versions that we want to test project file creation for.
+ """
+ return ['8.0', '9.0', '10.0', '11.0', '12.0', '14.0', '14.1', '14.2']
-env.MSVSProject(target = 'Test.vcxproj',
- slnguid = '{SLNGUID}',
- srcs = testsrc,
- incs = testincs,
- localincs = testlocalincs,
- resources = testresources,
- misc = testmisc,
- buildtarget = 'Test.exe',
- variant = 'Release')
-"""
-
-SConscript_contents_11_0 = """\
-env=Environment(platform='win32', tools=['msvs'], MSVS_VERSION='11.0',
- CPPDEFINES=['DEF1', 'DEF2',('DEF3','1234')],
- CPPPATH=['inc1', 'inc2'],
- HOST_ARCH='%(HOST_ARCH)s')
-
-testsrc = ['test1.cpp', 'test2.cpp']
-testincs = ['sdk_dir\sdk.h']
-testlocalincs = ['test.h']
-testresources = ['test.rc']
-testmisc = ['readme.txt']
-
-env.MSVSProject(target = 'Test.vcxproj',
- slnguid = '{SLNGUID}',
- srcs = testsrc,
- incs = testincs,
- localincs = testlocalincs,
- resources = testresources,
- misc = testmisc,
- buildtarget = 'Test.exe',
- variant = 'Release')
-"""
-
-SConscript_contents_14_0 = """\
-env=Environment(platform='win32', tools=['msvs'], MSVS_VERSION='14.0',
- CPPDEFINES=['DEF1', 'DEF2',('DEF3','1234')],
- CPPPATH=['inc1', 'inc2'],
- HOST_ARCH='%(HOST_ARCH)s')
-
-testsrc = ['test1.cpp', 'test2.cpp']
-testincs = ['sdk_dir\sdk.h']
-testlocalincs = ['test.h']
-testresources = ['test.rc']
-testmisc = ['readme.txt']
-
-env.MSVSProject(target = 'Test.vcxproj',
- slnguid = '{SLNGUID}',
- srcs = testsrc,
- incs = testincs,
- localincs = testlocalincs,
- resources = testresources,
- misc = testmisc,
- buildtarget = 'Test.exe',
- variant = 'Release')
-"""
-
-SConscript_contents_14_1 = """\
-env=Environment(platform='win32', tools=['msvs'], MSVS_VERSION='14.1',
- CPPDEFINES=['DEF1', 'DEF2',('DEF3','1234')],
- CPPPATH=['inc1', 'inc2'],
- HOST_ARCH='%(HOST_ARCH)s')
-
-testsrc = ['test1.cpp', 'test2.cpp']
-testincs = ['sdk_dir\sdk.h']
-testlocalincs = ['test.h']
-testresources = ['test.rc']
-testmisc = ['readme.txt']
-
-env.MSVSProject(target = 'Test.vcxproj',
- slnguid = '{SLNGUID}',
- srcs = testsrc,
- incs = testincs,
- localincs = testlocalincs,
- resources = testresources,
- misc = testmisc,
- buildtarget = 'Test.exe',
- variant = 'Release')
-"""
class TestSConsMSVS(TestSCons):
"""Subclass for testing MSVS-specific portions of SCons."""
@@ -1150,7 +661,7 @@ import SCons.Tool.MSCommon
print("self.scons_version =%%s"%%repr(SCons.__%s__))
print("self._msvs_versions =%%s"%%str(SCons.Tool.MSCommon.query_versions()))
""" % 'version'
-
+
self.run(arguments = '-n -q -Q -f -', stdin = input)
exec(self.stdout())
@@ -1233,11 +744,11 @@ print("self._msvs_versions =%%s"%%str(SCons.Tool.MSCommon.query_versions()))
finally:
os.environ['SCONSFLAGS'] = save_sconsflags or ''
return result
-
+
def get_vs_host_arch(self):
""" Get an MSVS, SDK , and/or MSVS acceptable platform arch
"""
-
+
# Dict to 'canonalize' the arch
_ARCH_TO_CANONICAL = {
"x86": "x86",
@@ -1255,21 +766,19 @@ print("self._msvs_versions =%%s"%%str(SCons.Tool.MSCommon.query_versions()))
# PROCESSOR_ARCHITECTURE.
if not host_platform:
host_platform = os.environ.get('PROCESSOR_ARCHITECTURE', '')
-
-
+
try:
host = _ARCH_TO_CANONICAL[host_platform]
except KeyError as e:
# Default to x86 for all other platforms
host = 'x86'
-
-
+
return host
def validate_msvs_file(self, file):
try:
x = ElementTree.parse(file)
- except:
+ except:
print("--------------------------------------------------------------")
print("--------------------------------------------------------------")
print(traceback.format_exc())
@@ -1278,6 +787,119 @@ print("self._msvs_versions =%%s"%%str(SCons.Tool.MSCommon.query_versions()))
print("--------------------------------------------------------------")
print("--------------------------------------------------------------")
self.fail_test()
+
+ def parse_vc_version(self, vc_version):
+ """
+ Parses the string vc_version to determine the major and minor version
+ included.
+ """
+ components = vc_version.split('.')
+ major = int(components[0])
+ minor = 0 if len(components) < 2 else int(components[1])
+ return major, minor
+
+ def _get_solution_file_format_version(self, vc_version):
+ """
+ Returns the Visual Studio format version expected in the .sln file.
+ """
+ major, _ = self.parse_vc_version(vc_version)
+ if major == 8:
+ return '9.00'
+ elif major == 9:
+ return '10.00'
+ elif major == 10:
+ return '11.00'
+ elif major > 10:
+ return '12.00'
+ else:
+ raise SCons.Errors.UserError('Received unexpected VC version %s' % vc_version)
+
+ def _get_solution_file_vs_number(self, vc_version):
+ """
+ Returns the Visual Studio number expected in the .sln file.
+ """
+ major, minor = self.parse_vc_version(vc_version)
+ if major == 8:
+ return '2005'
+ elif major == 9:
+ return '2008'
+ if major == 10:
+ return '2010'
+ elif major == 11:
+ return '11'
+ elif major == 12:
+ return '14'
+ elif major == 14 and (minor == 0 or minor == 1):
+ # Visual Studio 2015 and 2017 both use 15 in this entry.
+ return '15'
+ elif major == 14 and minor == 2:
+ return '16'
+ else:
+ raise SCons.Errors.UserError('Received unexpected VC version %s' % vc_version)
+
+ def _get_vcxproj_file_tools_version(self, vc_version):
+ """
+ Returns the version entry expected in the project file.
+ For .vcxproj files, this goes is ToolsVersion.
+ For .vcproj files, this goes in Version.
+ """
+ major, minor = self.parse_vc_version(vc_version)
+ if major == 8:
+ # Version="8.00"
+ return '8.00'
+ elif major == 9:
+ # Version="9.00"
+ return '9.00'
+ elif major < 14:
+ # ToolsVersion='4.0'
+ return '4.0'
+ elif major == 14 and minor == 0:
+ # ToolsVersion='14.0'
+ return '14.0'
+ elif major == 14 and minor == 1:
+ # ToolsVersion='15.0'
+ return '15.0'
+ elif vc_version == '14.2':
+ # ToolsVersion='16'
+ return '16.0'
+ else:
+ raise SCons.Errors.UserError('Received unexpected VC version %s' % vc_version)
+
+ def _get_vcxproj_file_cpp_path(self, dirs):
+ """Returns the include paths expected in the .vcxproj file"""
+ return ';'.join([self.workpath(dir) for dir in dirs])
+
+ def get_expected_sln_file_contents(self, vc_version, project_file):
+ """
+ Returns the expected .sln file contents.
+ Currently this function only supports the newer VC versions that use
+ the .vcxproj file format.
+ """
+ return expected_slnfile_fmt % {
+ 'FORMAT_VERSION': self._get_solution_file_format_version(vc_version),
+ 'VS_NUMBER': self._get_solution_file_vs_number(vc_version),
+ 'PROJECT_NAME': project_file.split('.')[0],
+ 'PROJECT_FILE': project_file,
+ }
+
+ def get_expected_proj_file_contents(self, vc_version, dirs, project_file):
+ """Returns the expected .vcxproj file contents"""
+ if project_file.endswith('.vcxproj'):
+ fmt = expected_vcxprojfile_fmt
+ else:
+ fmt = expected_vcprojfile_fmt
+ return fmt % {
+ 'TOOLS_VERSION': self._get_vcxproj_file_tools_version(vc_version),
+ 'INCLUDE_DIRS': self._get_vcxproj_file_cpp_path(dirs),
+ }
+
+ def get_expected_sconscript_file_contents(self, vc_version, project_file):
+ return SConscript_contents_fmt % {
+ 'HOST_ARCH': self.get_vs_host_arch(),
+ 'MSVS_VERSION': vc_version,
+ 'PROJECT_FILE': project_file,
+ }
+
# Local Variables:
# tab-width:4
# indent-tabs-mode:nil
diff --git a/testing/framework/TestSCons_time.py b/testing/framework/TestSCons_time.py
index 624eb4c..547e264 100644
--- a/testing/framework/TestSCons_time.py
+++ b/testing/framework/TestSCons_time.py
@@ -13,7 +13,7 @@ attributes defined in this subclass.
# Copyright (c) 2001 - 2019 The SCons Foundation
-__revision__ = "testing/framework/TestSCons_time.py 103260fce95bf5db1c35fb2371983087d85dd611 2019-07-13 18:25:30 bdbaddog"
+__revision__ = "testing/framework/TestSCons_time.py e724ae812eb96f4858a132f5b8c769724744faf6 2019-07-21 00:04:47 bdeegan"
import os
import os.path
@@ -272,7 +272,8 @@ class TestSCons_time(TestCommon):
d, f = os.path.split(path)
if not os.path.isdir(d):
os.makedirs(d)
- open(path, 'w').write(content)
+ with open(path, 'w') as f:
+ f.write(content)
return dir
def write_sample_tarfile(self, archive, dir, files):
diff --git a/testing/framework/TestSConsign.py b/testing/framework/TestSConsign.py
index fc72aa4..8f992ef 100644
--- a/testing/framework/TestSConsign.py
+++ b/testing/framework/TestSConsign.py
@@ -1,7 +1,7 @@
# Copyright (c) 2001 - 2019 The SCons Foundation
from __future__ import print_function
-__revision__ = "testing/framework/TestSConsign.py 103260fce95bf5db1c35fb2371983087d85dd611 2019-07-13 18:25:30 bdbaddog"
+__revision__ = "testing/framework/TestSConsign.py e724ae812eb96f4858a132f5b8c769724744faf6 2019-07-21 00:04:47 bdeegan"
__doc__ = """
TestSConsign.py: a testing framework for the "sconsign" script