diff options
author | klarlund <klarlund@01de4be4-8c4a-0410-9132-4925637da917> | 2008-05-31 00:38:48 +0000 |
---|---|---|
committer | klarlund <klarlund@01de4be4-8c4a-0410-9132-4925637da917> | 2008-05-31 00:38:48 +0000 |
commit | 1a6d0aba13bf3f365b15e173b363edf893eed879 (patch) | |
tree | 54f180ce92fc53927aaf5f6e350b99c1aa3ab31b | |
parent | fe96c8cf1833b0a432cd8705bc27c7dbf42508e6 (diff) | |
download | distcc-1a6d0aba13bf3f365b15e173b363edf893eed879.tar.gz |
Tidy-up testing framework to overcome recently introduced bug.
Testing on cygwine revealed that as tests were being issued the temporary
testing directory would suffer from longer and longer prefixes until a 'filename
too long' error would stop the party. This is result of an earlier attempt to
avoid too much printing to stdout during tests, spefically during recursive test
invocations.
The problem is that the teardown mechanism of the comfychair enviroment is not
expressed -- by any name at all (it could be 'teardown' for example). So, I
added a name --- but because there's no expectation that the TestCase class
defined there has its teardown method called from derived classes --- I chose
the name CleanUps, which corresponds to the private variable.
I also made an abstraction for running a test. This new Comfychair.runtest
function can the conveniently by called to carry out a subtest.
With this CL, 'make pump-maintainer-check' now works on cygwin.
git-svn-id: http://distcc.googlecode.com/svn/trunk@434 01de4be4-8c4a-0410-9132-4925637da917
-rwxr-xr-x | test/comfychair.py | 122 | ||||
-rwxr-xr-x | test/testdistcc.py | 17 |
2 files changed, 88 insertions, 51 deletions
diff --git a/test/comfychair.py b/test/comfychair.py index 0528bb3..75e5c99 100755 --- a/test/comfychair.py +++ b/test/comfychair.py @@ -97,6 +97,25 @@ class TestCase: """Queue a cleanup to be run when the test is complete.""" self._cleanups.append(c) + def apply_cleanups(self, debugger): + """Apply cleanup functions and return error code. + + Returns: + 0 on success; 2 if a KeyboardInterrupt occurs; 1 if any other exception + occurs. + """ + while self._cleanups: + try: + apply(self._cleanups.pop()) + except KeyboardInterrupt: + print "interrupted during cleanups" + _report_error(self, debugger) + return 2 + except: + print "error during cleanups" + _report_error(self, debugger) + return 1 + return 0 def fail(self, reason = ""): """Say the test failed.""" @@ -299,6 +318,64 @@ def _report_error(case, debugger): debugger(tb) +def runtest(testcase_class, ret, verbose=0, debugger=None, subtest=0): + """Instantiate test class, run it, and catch and report exceptions. + + Inputs: + testcase_class a class derived from TestCase + ret return status, an integer + verbose an integer (used as boolean) + debugger debugger object to be applied to errors + subtest an integer (used as boolean) + Returns: + a new return status + Raises: + KeyboardInterrupt + + If subtest is true, then the ordinary information about the + test progress is not printed. + """ + if not subtest: + print "%-30s" % _test_name(testcase_class), + def failure_print(message): + print message + else: + def failure_print(message): + print '[%s %s]' % (_test_name(testcase_class), message) + + # flush now so that long running tests are easier to follow + sys.stdout.flush() + + obj = None + try: + try: + # run test and sometimes show result + obj = testcase_class() + obj.setup() + obj.runtest() + if not subtest: + print "OK" + except KeyboardInterrupt: + failure_print("INTERRUPT") + if obj: + _report_error(obj, debugger) + raise + except NotRunError, msg: + failure_print("NOTRUN, %s" % msg.value) + except: + failure_print("FAIL") + if obj: + _report_error(obj, debugger) + return 1 + finally: + if obj: + ret = obj.apply_cleanups(debugger) or ret + # Display log file if we're verbose + if ret == 0 and verbose: + obj.explain_failure() + return ret + + def runtests(test_list, verbose = 0, debugger = None): """Run a series of tests. @@ -312,46 +389,13 @@ def runtests(test_list, verbose = 0, debugger = None): """ import traceback ret = 0 - for test_class in test_list: - print "%-30s" % _test_name(test_class), - # flush now so that long running tests are easier to follow - sys.stdout.flush() - - obj = None + for testcase_class in test_list: try: - try: # run test and show result - obj = test_class() - obj.setup() - obj.runtest() - print "OK" - except KeyboardInterrupt: - print "INTERRUPT" - _report_error(obj, debugger) - ret = 2 - break - except NotRunError, msg: - print "NOTRUN, %s" % msg.value - except: - print "FAIL" - _report_error(obj, debugger) - ret = 1 - finally: - while obj and obj._cleanups: - try: - apply(obj._cleanups.pop()) - except KeyboardInterrupt: - print "interrupted during teardown" - _report_error(obj, debugger) - ret = 2 - break - except: - print "error during teardown" - _report_error(obj, debugger) - ret = 1 - # Display log file if we're verbose - if ret == 0 and verbose: - obj.explain_failure() - + ret = runtest(testcase_class, ret, verbose=verbose, + debugger=debugger) + except KeyboardInterrupt: + ret = 2 + break return ret diff --git a/test/testdistcc.py b/test/testdistcc.py index 871be8a..711584c 100755 --- a/test/testdistcc.py +++ b/test/testdistcc.py @@ -610,18 +610,11 @@ int main(char **argv) {}; glob_result = glob.glob(dep_glob) dotd_result.extend(glob_result) - # We explicit call setup(), runtest(), and teardown() to run the - # test, rather than just comfychair.runtests([TempCompile_Case]), - # because we don't want to see 10 test results for - # 'TempCompile_Case' in the output; we just want a single - # output line for 'DotD_Case'. - case = TempCompile_Case() - case.setup() - try: - case.runtest() - finally: - case.teardown() - + ret = comfychair.runtest(TempCompile_Case, 0, subtest=1) + if ret: + raise AssertionError( + "Case (args:%s, dep_glob:%s, how_many:%s, target:%s)" + % (args, dep_glob, how_many, target)) self.assert_equal(len(dotd_result), how_many) if how_many == 1: expected_dep_file = dotd_result[0] |