diff options
Diffstat (limited to 'QMTest')
-rw-r--r-- | QMTest/SConscript | 8 | ||||
-rw-r--r-- | QMTest/TestCommon.py | 32 | ||||
-rw-r--r-- | QMTest/TestRuntest.py | 30 | ||||
-rw-r--r-- | QMTest/TestSCons.py | 161 | ||||
-rw-r--r-- | QMTest/TestSCons_time.py | 30 | ||||
-rw-r--r-- | QMTest/scons_tdb.py | 2 |
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. |