summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormandyke@gmail.com <mandyke@gmail.com@01de4be4-8c4a-0410-9132-4925637da917>2013-05-27 08:10:06 +0000
committermandyke@gmail.com <mandyke@gmail.com@01de4be4-8c4a-0410-9132-4925637da917>2013-05-27 08:10:06 +0000
commite570c1041545c47044861d47b87bf7b206cf454a (patch)
treec1464464748746bfb505207af18bbb5fc140bfc2
parentb6b94e63a08128f88b833b089583fa3d6dd66667 (diff)
downloaddistcc-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-xtest/comfychair.py24
-rwxr-xr-xtest/testdistcc.py57
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):