diff options
author | mandyke@gmail.com <mandyke@gmail.com@01de4be4-8c4a-0410-9132-4925637da917> | 2013-05-27 08:10:06 +0000 |
---|---|---|
committer | mandyke@gmail.com <mandyke@gmail.com@01de4be4-8c4a-0410-9132-4925637da917> | 2013-05-27 08:10:06 +0000 |
commit | e570c1041545c47044861d47b87bf7b206cf454a (patch) | |
tree | c1464464748746bfb505207af18bbb5fc140bfc2 | |
parent | b6b94e63a08128f88b833b089583fa3d6dd66667 (diff) | |
download | distcc-e570c1041545c47044861d47b87bf7b206cf454a.tar.gz |
Improve reliability of tests
* test/testdistcc.py: Remove stale and duplicate TODO items.
(_Touch): New function, acts like touch(1).
(Compile_c_Case): makeFile is not sufficient to reliably update
modification time on all systems (e.g. GNU/Hurd), so replace it with
calls to _Touch.
(Gdb_Case): Use _Touch.
(SyntaxError_Case): Look for pattern anywhere in the output using
re.search as warnings and other noise can be present.
* test/comfychair.py: Also set LC_ALL, which has a higher priority,
and make it so LANG and LC_ALL are set after saving the environment.
Clean up some stray import statements.
git-svn-id: http://distcc.googlecode.com/svn/trunk@781 01de4be4-8c4a-0410-9132-4925637da917
-rwxr-xr-x | test/comfychair.py | 24 | ||||
-rwxr-xr-x | test/testdistcc.py | 57 |
2 files changed, 27 insertions, 54 deletions
diff --git a/test/comfychair.py b/test/comfychair.py index 75e5c99..2e5a111 100755 --- a/test/comfychair.py +++ b/test/comfychair.py @@ -31,7 +31,7 @@ For more information, see the file README.comfychair. To run a test suite based on ComfyChair, just run it as a program. """ -import sys, re, shutil +import sys, os, re, shutil class TestCase: @@ -46,12 +46,15 @@ class TestCase: self._enter_rundir() self._save_environment() self.add_cleanup(self.teardown) - + # Prevent localizations interfering with attempts to parse + # program output and error messages. LC_ALL has higher + # priority (see locale(7)), but set both just in case. + os.environ['LANG'] = 'C' + os.environ['LC_ALL'] = 'C' # -------------------------------------------------- # Save and restore directory def _enter_rundir(self): - import os self.basedir = os.getcwd() self.add_cleanup(self._restore_directory) self.rundir = os.path.join(self.basedir, @@ -61,21 +64,17 @@ class TestCase: shutil.rmtree(self.rundir, ignore_errors=1) os.makedirs(self.tmpdir) os.chdir(self.rundir) - os.environ['LANG'] = 'C' def _restore_directory(self): - import os os.chdir(self.basedir) # -------------------------------------------------- # Save and restore environment def _save_environment(self): - import os self._saved_environ = os.environ.copy() self.add_cleanup(self._restore_environment) def _restore_environment(self): - import os os.environ.clear() os.environ.update(self._saved_environ) @@ -135,7 +134,6 @@ why.""" def require_root(self): """Skip this test unless run by root.""" - import os self.require(os.getuid() == 0, "must be root to run this test") @@ -186,7 +184,6 @@ why.""" def assert_no_file(self, filename): - import os.path assert not os.path.exists(filename), ("file exists but should not: %s" % filename) @@ -194,7 +191,6 @@ why.""" # Methods for running programs def runcmd_background(self, cmd): - import os self.test_log = self.test_log + "Run in background:\n" + `cmd` + "\n" pid = os.fork() if pid == 0: @@ -227,7 +223,7 @@ stderr: Based in part on popen2.py Returns (waitstatus, stdout, stderr).""" - import os, types + import types pid = os.fork() if pid == 0: # child @@ -259,7 +255,6 @@ stderr: def runcmd_unchecked(self, cmd, skip_on_noexec = 0): """Invoke a command; return (exitcode, stdout, stderr)""" - import os waitstatus, stdout, stderr = self.run_captured(cmd) assert not os.WIFSIGNALED(waitstatus), \ ("%s terminated with signal %d" % (`cmd`, os.WTERMSIG(waitstatus))) @@ -304,7 +299,6 @@ def _report_error(case, debugger): case TestCase instance debugger if true, a debugger function to be applied to the traceback """ - import sys ex = sys.exc_info() print "-----------------------------------------------------------------" if ex: @@ -410,7 +404,6 @@ def _test_name(test_class): def print_help(): """Help for people running tests""" - import sys print """%s: software test suite based on ComfyChair usage: @@ -449,13 +442,12 @@ by default runs all tests in the suggested order. Calls sys.exit() on completion. """ - from sys import argv import getopt, sys opt_verbose = 0 debugger = None - opts, args = getopt.getopt(argv[1:], 'pv', + opts, args = getopt.getopt(sys.argv[1:], 'pv', ['help', 'list', 'verbose', 'post-mortem']) for opt, opt_arg in opts: if opt == '--help': diff --git a/test/testdistcc.py b/test/testdistcc.py index 782dde6..619cb5e 100755 --- a/test/testdistcc.py +++ b/test/testdistcc.py @@ -50,8 +50,6 @@ Example: # abstract superclasses just provide methods that can be called, # rather than establishing default behaviour. -# TODO: Run the server in a different directory from the clients - # TODO: Some kind of direct test of the host selection algorithm. # TODO: Test host files containing \r. @@ -84,22 +82,11 @@ Example: # Check that without DISTCC_SAVE_TEMPS temporary files are cleaned up. -# TODO: Test compiling a really large source file that produces a -# large object file. Perhaps need to generate it at run time -- just -# one big array? - # TODO: Perhaps redirect stdout, stderr to a temporary file while # running? Use os.open(), os.dup2(). -# TODO: Test "distcc gcc -c foo.c bar.c". gcc would actually compile -# both of them. We could split it into multiple compiler invocations, -# but this is so rare that it's probably not worth the complexity. So -# at the moment is just handled locally. - # TODO: Test crazy option arguments like "distcc -o -output -c foo.c" -# TODO: Test attempt to compile a nonexistent file. - # TODO: Add test harnesses that just exercise the bulk file transfer # routines. @@ -111,9 +98,6 @@ Example: # TODO: Run "sleep" as a compiler, then kill the client and make sure # that the server and "sleep" promptly terminate. -# TODO: Set umask 0, then check that the files are created with mode -# 0644. - # TODO: Perhaps have a little compiler that crashes. Check that the # signal gets properly reported back. @@ -133,11 +117,6 @@ Example: # TODO: Test a compiler that sleeps for a long time; try killing the # server and make sure it goes away. -# TODO: Set LANG=C before running all tests, to try to make sure that -# localizations don't break attempts to parse error messages. Is -# setting LANG enough, or do we also need LC_*? (Thanks to Oscar -# Esteban.) - # TODO: Test scheduler. Perhaps run really slow jobs to make things # deterministic, and test that they're dispatched in a reasonable way. @@ -168,6 +147,9 @@ Example: # TODO: Test with DISTCC_DIR set, and not set. +# TODO: Using --lifetime does cause sporadic failures. Ensure that +# teardown kills all daemon processes and then stop using --lifetime. + import time, sys, string, os, glob, re, socket import signal, os.path @@ -238,6 +220,16 @@ def _IsPE(filename): contents = _FirstBytes(filename, 5) return contents.startswith('MZ') +def _Touch(filename): + '''Update the access and modification time of the given file, + creating an empty file if it does not exist. + ''' + f = open(filename, 'a') + try: + os.utime(filename, None) + finally: + f.close() + class SimpleDistCC_Case(comfychair.TestCase): '''Abstract base class for distcc tests''' @@ -679,14 +671,6 @@ class Compile_c_Case(SimpleDistCC_Case): assert m_obj, line return m_obj.group(1) - def makeFile(self, f): - fd = open(f, "w") - fd.close() - - def makeFiles(self, files): - for f in files: - self.makeFile(f) - def runtest(self): # Test dcc_discrepancy_filename @@ -722,7 +706,8 @@ foo_bar""", ] for dotd_contents, deps in dotd_cases: - self.makeFiles(deps) + for dep in deps: + _Touch(dep) # Now postulate the time that is the beginning of build. This time # is after that of all the dependencies. time_ref = time.time() + 1 @@ -752,12 +737,9 @@ foo_bar""", # Let's try to touch, say the last dep file. Then, we should expect # the name of that very file as the output because there's a fresh - # file. We'll have to advance real time beyond time_ref before doing - # this. - while time.time() <= time_ref: - time.sleep(1) + # file. if deps: - self.makeFile(deps[-1]) + _Touch(deps[-1]) out, err = self.runcmd( "h_compile dcc_fresh_dependency_exists dotd '' %i" % time_ref) @@ -1232,8 +1214,7 @@ class Gdb_Case(CompileHello_Case): # Create an empty .gdbinit, so that we insulate this test # from the ~/.gdbinit file of the user running it. filename = ".gdbinit" - f = open(filename, 'w') - f.close() + _Touch(filename) def compiler(self): """Command for compiling and linking.""" @@ -1847,7 +1828,7 @@ class SyntaxError_Case(Compilation_Case): def compile(self): rc, msgs, errs = self.runcmd_unchecked(self.compileCmd()) self.assert_notequal(rc, 0) - self.assert_re_match(r'testtmp.c:1:.*error', errs) + self.assert_re_search(r'testtmp.c:1:.*error', errs) self.assert_equal(msgs, '') def runtest(self): |