summaryrefslogtreecommitdiffstats
path: root/QMTest
diff options
context:
space:
mode:
Diffstat (limited to 'QMTest')
-rw-r--r--QMTest/SConscript8
-rw-r--r--QMTest/TestCommon.py32
-rw-r--r--QMTest/TestRuntest.py30
-rw-r--r--QMTest/TestSCons.py161
-rw-r--r--QMTest/TestSCons_time.py30
-rw-r--r--QMTest/scons_tdb.py2
6 files changed, 167 insertions, 96 deletions
diff --git a/QMTest/SConscript b/QMTest/SConscript
index 3aa7d9c..e141a51 100644
--- a/QMTest/SConscript
+++ b/QMTest/SConscript
@@ -26,6 +26,7 @@
#
import os.path
+import string
Import('build_dir', 'env')
@@ -45,7 +46,12 @@ files = [
def copy(target, source, env):
t = str(target[0])
s = str(source[0])
- open(t, 'wb').write(open(s, 'rb').read())
+ c = open(s, 'rb').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 = string.replace(c, '__' + 'VERSION' + '__', env['VERSION'])
+ open(t, 'wb').write(c)
for file in files:
# Guarantee that real copies of these files always exist in
diff --git a/QMTest/TestCommon.py b/QMTest/TestCommon.py
index b215a26..b8fb5cd 100644
--- a/QMTest/TestCommon.py
+++ b/QMTest/TestCommon.py
@@ -427,3 +427,35 @@ class TestCommon(TestCmd):
print self.stdout()
self.diff(stderr, self.stderr(), 'STDERR ')
raise TestFailed
+
+ def skip_test(self, message="Skipping test.\n"):
+ """Skips a test.
+
+ Proper test-skipping behavior is dependent on the external
+ TESTCOMMON_PASS_SKIPS environment variable. If set, we treat
+ the skip as a PASS (exit 0), and otherwise treat it as NO RESULT.
+ In either case, we print the specified message as an indication
+ that the substance of the test was skipped.
+
+ (This was originally added to support development under Aegis.
+ Technically, skipping a test is a NO RESULT, but Aegis would
+ treat that as a test failure and prevent the change from going to
+ the next step. Since we ddn't want to force anyone using Aegis
+ to have to install absolutely every tool used by the tests, we
+ would actually report to Aegis that a skipped test has PASSED
+ so that the workflow isn't held up.)
+ """
+ if message:
+ sys.stdout.write(message)
+ sys.stdout.flush()
+ pass_skips = os.environ.get('TESTCOMMON_PASS_SKIPS')
+ if pass_skips in [None, 0, '0']:
+ # skip=1 means skip this function when showing where this
+ # result came from. They only care about the line where the
+ # script called test.skip_test(), not the line number where
+ # we call test.no_result().
+ self.no_result(skip=1)
+ else:
+ # We're under the development directory for this change,
+ # so this is an Aegis invocation; pass the test (exit 0).
+ self.pass_test()
diff --git a/QMTest/TestRuntest.py b/QMTest/TestRuntest.py
index 9452746..ee33b25 100644
--- a/QMTest/TestRuntest.py
+++ b/QMTest/TestRuntest.py
@@ -158,36 +158,6 @@ class TestRuntest(TestCommon):
os.environ['PYTHONPATH'] = ''
os.environ['SCONS_SOURCE_PATH_EXECUTABLE'] = ''
- def skip_test(self, message="Skipping test.\n"):
- """Skips a test.
-
- Proper test-skipping behavior is dependent on whether we're being
- executed as part of development of a change under Aegis.
-
- Technically, skipping a test is a NO RESULT, but Aegis will
- treat that as a test failure and prevent the change from going
- to the next step. We don't want to force anyone using Aegis
- to have to install absolutely every tool used by the tests,
- so we actually report to Aegis that a skipped test has PASSED
- so that the workflow isn't held up.
- """
- if message:
- sys.stdout.write(message)
- sys.stdout.flush()
- devdir = os.popen("aesub '$dd' 2>/dev/null", "r").read()[:-1]
- intdir = os.popen("aesub '$intd' 2>/dev/null", "r").read()[:-1]
- if devdir and self._cwd[:len(devdir)] == devdir or \
- intdir and self._cwd[:len(intdir)] == intdir:
- # We're under the development directory for this change,
- # so this is an Aegis invocation; pass the test (exit 0).
- self.pass_test()
- else:
- # skip=1 means skip this function when showing where this
- # result came from. They only care about the line where the
- # script called test.skip_test(), not the line number where
- # we call test.no_result().
- self.no_result(skip=1)
-
def write_fake_scons_source_tree(self):
os.mkdir('src')
os.mkdir('src/script')
diff --git a/QMTest/TestSCons.py b/QMTest/TestSCons.py
index 100d8ba..9c270fa 100644
--- a/QMTest/TestSCons.py
+++ b/QMTest/TestSCons.py
@@ -38,11 +38,14 @@ from TestCommon import __all__
# Some tests which verify that SCons has been packaged properly need to
# look for specific version file names. Replicating the version number
-# here provides independent verification that what we packaged conforms
-# to what we expect. (If we derived the version number from the same
-# data driving the build we might miss errors if the logic breaks.)
+# here provides some independent verification that what we packaged
+# conforms to what we expect.
-SConsVersion = '0.97'
+default_version = '0.97.0'
+
+SConsVersion = '__VERSION__'
+if SConsVersion == '__' + 'VERSION' + '__':
+ SConsVersion = default_version
__all__.extend([ 'TestSCons',
'machine',
@@ -186,6 +189,10 @@ class TestSCons(TestCommon):
kw['workdir'] = ''
apply(TestCommon.__init__, [self], kw)
+ import SCons.Node.FS
+ if SCons.Node.FS.default_fs is None:
+ SCons.Node.FS.default_fs = SCons.Node.FS.FS()
+
def Environment(self, ENV=None, *args, **kw):
"""
Return a construction Environment that optionally overrides
@@ -292,36 +299,6 @@ class TestSCons(TestCommon):
kw['match'] = self.match_re_dotall
apply(self.run, [], kw)
- def skip_test(self, message="Skipping test.\n"):
- """Skips a test.
-
- Proper test-skipping behavior is dependent on whether we're being
- executed as part of development of a change under Aegis.
-
- Technically, skipping a test is a NO RESULT, but Aegis will
- treat that as a test failure and prevent the change from going
- to the next step. We don't want to force anyone using Aegis
- to have to install absolutely every tool used by the tests,
- so we actually report to Aegis that a skipped test has PASSED
- so that the workflow isn't held up.
- """
- if message:
- sys.stdout.write(message)
- sys.stdout.flush()
- devdir = os.popen("aesub '$dd' 2>/dev/null", "r").read()[:-1]
- intdir = os.popen("aesub '$intd' 2>/dev/null", "r").read()[:-1]
- if devdir and self._cwd[:len(devdir)] == devdir or \
- intdir and self._cwd[:len(intdir)] == intdir:
- # We're under the development directory for this change,
- # so this is an Aegis invocation; pass the test (exit 0).
- self.pass_test()
- else:
- # skip=1 means skip this function when showing where this
- # result came from. They only care about the line where the
- # script called test.skip_test(), not the line number where
- # we call test.no_result().
- self.no_result(skip=1)
-
def diff_substr(self, expect, actual, prelen=20, postlen=40):
i = 0
for x, y in zip(expect, actual):
@@ -361,6 +338,44 @@ class TestSCons(TestCommon):
r'/CreationDate (D:XXXX)', s)
s = re.sub(r'/ID \[<[0-9a-fA-F]*> <[0-9a-fA-F]*>\]',
r'/ID [<XXXX> <XXXX>]', s)
+ s = re.sub(r'/(BaseFont|FontName) /[A-Z]{6}',
+ r'/\1 /XXXXXX', s)
+ s = re.sub(r'/Length \d+ *\n/Filter /FlateDecode\n',
+ r'/Length XXXX\n/Filter /FlateDecode\n', s)
+
+
+ try:
+ import zlib
+ except ImportError:
+ pass
+ else:
+ begin_marker = '/FlateDecode\n>>\nstream\n'
+ end_marker = 'endstream\nendobj'
+
+ encoded = []
+ b = string.find(s, begin_marker, 0)
+ while b != -1:
+ b = b + len(begin_marker)
+ e = string.find(s, end_marker, b)
+ encoded.append((b, e))
+ b = string.find(s, begin_marker, e + len(end_marker))
+
+ x = 0
+ r = []
+ for b, e in encoded:
+ r.append(s[x:b])
+ d = zlib.decompress(s[b:e])
+ d = re.sub(r'%%CreationDate: [^\n]*\n',
+ r'%%CreationDate: 1970 Jan 01 00:00:00\n', d)
+ d = re.sub(r'%DVIPSSource: TeX output \d\d\d\d\.\d\d\.\d\d:\d\d\d\d',
+ r'%DVIPSSource: TeX output 1970.01.01:0000', d)
+ d = re.sub(r'/(BaseFont|FontName) /[A-Z]{6}',
+ r'/\1 /XXXXXX', d)
+ r.append(d)
+ x = e
+ r.append(s[x:])
+ s = string.join(r, '')
+
return s
def java_ENV(self):
@@ -744,6 +759,84 @@ print "self._msvs_versions =", str(env['MSVS']['VERSIONS'])
print "-----------------------------------------------------"
self.fail_test()
+ def get_python_version(self):
+ """
+ Returns the Python version (just so everyone doesn't have to
+ hand-code slicing the right number of characters).
+ """
+ # see also sys.prefix documentation
+ return sys.version[:3]
+
+ def get_platform_python(self):
+ """
+ Returns a path to a Python executable suitable for testing on
+ this platform.
+
+ Mac OS X has no static libpython for SWIG to link against,
+ so we have to link against Apple's framwork version. However,
+ testing must use the executable version that corresponds to the
+ framework we link against, or else we get interpreter errors.
+ """
+ if sys.platform == 'darwin':
+ return '/System/Library/Frameworks/Python.framework/Versions/Current/bin/python'
+ else:
+ global python
+ return python
+
+ def get_quoted_platform_python(self):
+ """
+ Returns a quoted path to a Python executable suitable for testing on
+ this platform.
+
+ Mac OS X has no static libpython for SWIG to link against,
+ so we have to link against Apple's framwork version. However,
+ testing must use the executable version that corresponds to the
+ framework we link against, or else we get interpreter errors.
+ """
+ if sys.platform == 'darwin':
+ return '"' + self.get_platform_python() + '"'
+ else:
+ global _python_
+ return _python_
+
+ def get_platform_sys_prefix(self):
+ """
+ Returns a "sys.prefix" value suitable for linking on this platform.
+
+ Mac OS X has a built-in Python but no static libpython,
+ so we must link to it using Apple's 'framework' scheme.
+ """
+ if sys.platform == 'darwin':
+ fmt = '/System/Library/Frameworks/Python.framework/Versions/%s/'
+ return fmt % self.get_python_version()
+ else:
+ return sys.prefix
+
+ def get_python_frameworks_flags(self):
+ """
+ Returns a FRAMEWORKSFLAGS value for linking with Python.
+
+ Mac OS X has a built-in Python but no static libpython,
+ so we must link to it using Apple's 'framework' scheme.
+ """
+ if sys.platform == 'darwin':
+ return '-framework Python'
+ else:
+ return ''
+
+ def get_python_inc(self):
+ """
+ Returns a path to the Python include directory.
+ """
+ try:
+ import distutils.sysconfig
+ except ImportError:
+ return os.path.join(self.get_platform_sys_prefix(),
+ 'include',
+ 'python' + self.get_python_version())
+ else:
+ return distutils.sysconfig.get_python_inc()
+
# In some environments, $AR will generate a warning message to stderr
# if the library doesn't previously exist and is being created. One
# way to fix this is to tell AR to be quiet (sometimes the 'c' flag),
diff --git a/QMTest/TestSCons_time.py b/QMTest/TestSCons_time.py
index 1ceb529..102181e 100644
--- a/QMTest/TestSCons_time.py
+++ b/QMTest/TestSCons_time.py
@@ -246,36 +246,6 @@ class TestSCons_time(TestCommon):
self.write(python_name, profile_py % d)
self.run(program = python_name, interpreter = sys.executable)
- def skip_test(self, message="Skipping test.\n"):
- """Skips a test.
-
- Proper test-skipping behavior is dependent on whether we're being
- executed as part of development of a change under Aegis.
-
- Technically, skipping a test is a NO RESULT, but Aegis will
- treat that as a test failure and prevent the change from going
- to the next step. We don't want to force anyone using Aegis
- to have to install absolutely every tool used by the tests,
- so we actually report to Aegis that a skipped test has PASSED
- so that the workflow isn't held up.
- """
- if message:
- sys.stdout.write(message)
- sys.stdout.flush()
- devdir = os.popen("aesub '$dd' 2>/dev/null", "r").read()[:-1]
- intdir = os.popen("aesub '$intd' 2>/dev/null", "r").read()[:-1]
- if devdir and self._cwd[:len(devdir)] == devdir or \
- intdir and self._cwd[:len(intdir)] == intdir:
- # We're under the development directory for this change,
- # so this is an Aegis invocation; pass the test (exit 0).
- self.pass_test()
- else:
- # skip=1 means skip this function when showing where this
- # result came from. They only care about the line where the
- # script called test.skip_test(), not the line number where
- # we call test.no_result().
- self.no_result(skip=1)
-
def write_fake_aegis_py(self, name):
name = self.workpath(name)
self.write(name, aegis_py)
diff --git a/QMTest/scons_tdb.py b/QMTest/scons_tdb.py
index e0d7683..954b8df 100644
--- a/QMTest/scons_tdb.py
+++ b/QMTest/scons_tdb.py
@@ -429,7 +429,7 @@ class Test(AegisTest):
and fails otherwise. The program output is logged, but not validated."""
command = RedirectedExecutable()
- args = [context.get('python', sys.executable), self.script]
+ args = [context.get('python', sys.executable), '-tt', self.script]
status = command.Run(args, os.environ)
if not check_exit_status(result, 'Test.', self.script, status):
# In case of failure record exit code, stdout, and stderr.