[Zope3-checkins] SVN: zope.testing/trunk/ Fixed bug: post-mortem
debugging wasn't working for errors in layer
Jim Fulton
jim at zope.com
Tue Aug 14 18:11:05 EDT 2007
Log message for revision 78821:
Fixed bug: post-mortem debugging wasn't working for errors in layer
setup.
Changed:
U zope.testing/trunk/README.txt
A zope.testing/trunk/src/zope/testing/testrunner-debugging-layer-setup.test
U zope.testing/trunk/src/zope/testing/testrunner.py
-=-
Modified: zope.testing/trunk/README.txt
===================================================================
--- zope.testing/trunk/README.txt 2007-08-14 19:20:39 UTC (rev 78820)
+++ zope.testing/trunk/README.txt 2007-08-14 22:11:05 UTC (rev 78821)
@@ -70,6 +70,14 @@
- Added --no-progress and --auto-progress options.
+3.5.1 (2007/08/14)
+==================
+
+Bugs Fixed:
+-----------
+
+- Post-mortem debugging wasn't invoked for layer-setup failures.
+
3.5.0 (2007/07/19)
==================
Added: zope.testing/trunk/src/zope/testing/testrunner-debugging-layer-setup.test
===================================================================
--- zope.testing/trunk/src/zope/testing/testrunner-debugging-layer-setup.test (rev 0)
+++ zope.testing/trunk/src/zope/testing/testrunner-debugging-layer-setup.test 2007-08-14 22:11:05 UTC (rev 78821)
@@ -0,0 +1,133 @@
+Post-mortem debugging also works when there is a failure in layer
+setup.
+
+ >>> import os, shutil, sys, tempfile
+ >>> tdir = tempfile.mkdtemp()
+ >>> dir = os.path.join(tdir, 'TESTS-DIR')
+ >>> os.mkdir(dir)
+ >>> open(os.path.join(dir, 'tests.py'), 'w').write(
+ ... '''
+ ... import doctest
+ ...
+ ... class Layer:
+ ... @classmethod
+ ... def setUp(self):
+ ... x = 1
+ ... raise ValueError
+ ...
+ ... def a_test():
+ ... """
+ ... >>> None
+ ... """
+ ... def test_suite():
+ ... suite = doctest.DocTestSuite()
+ ... suite.layer = Layer
+ ... return suite
+ ...
+ ... ''')
+
+ >>> class Input:
+ ... def __init__(self, src):
+ ... self.lines = src.split('\n')
+ ... def readline(self):
+ ... line = self.lines.pop(0)
+ ... print line
+ ... return line+'\n'
+
+ >>> real_stdin = sys.stdin
+ >>> if sys.version_info[:2] == (2, 3):
+ ... sys.stdin = Input('n\np x\nc')
+ ... else:
+ ... sys.stdin = Input('p x\nc')
+
+ >>> sys.argv = [testrunner_script]
+ >>> import zope.testing.testrunner
+ >>> try:
+ ... zope.testing.testrunner.run(['--path', dir, '-D'])
+ ... finally: sys.stdin = real_stdin
+ ... # doctest: +ELLIPSIS
+ Running tests.Layer tests:
+ Set up tests.Layer exceptions.ValueError:
+ <BLANKLINE>
+ > ...tests.py(8)setUp()
+ -> raise ValueError
+ (Pdb) p x
+ 1
+ (Pdb) c
+ True
+
+Note that post-mortem debugging doesn't work when the layer is run in
+a subprocess:
+
+ >>> if sys.version_info[:2] == (2, 3):
+ ... sys.stdin = Input('n\np x\nc')
+ ... else:
+ ... sys.stdin = Input('p x\nc')
+
+ >>> open(os.path.join(dir, 'tests2.py'), 'w').write(
+ ... '''
+ ... import doctest, unittest
+ ...
+ ... class Layer1:
+ ... @classmethod
+ ... def setUp(self):
+ ... pass
+ ...
+ ... @classmethod
+ ... def tearDown(self):
+ ... raise NotImplementedError
+ ...
+ ... class Layer2:
+ ... @classmethod
+ ... def setUp(self):
+ ... x = 1
+ ... raise ValueError
+ ...
+ ... def a_test():
+ ... """
+ ... >>> None
+ ... """
+ ... def test_suite():
+ ... suite1 = doctest.DocTestSuite()
+ ... suite1.layer = Layer1
+ ... suite2 = doctest.DocTestSuite()
+ ... suite2.layer = Layer2
+ ... return unittest.TestSuite((suite1, suite2))
+ ...
+ ... ''')
+
+ >>> try:
+ ... zope.testing.testrunner.run(
+ ... ['--path', dir, '-Dvv', '--tests-pattern', 'tests2'])
+ ... finally: sys.stdin = real_stdin
+ ... # doctest: +ELLIPSIS
+ Running tests at level 1
+ Running tests2.Layer1 tests:
+ Set up tests2.Layer1 in 0.000 seconds.
+ Running:
+ a_test (tests2)
+ Ran 1 tests with 0 failures and 0 errors in 0.001 seconds.
+ Running tests2.Layer2 tests:
+ Tear down tests2.Layer1 ... not supported
+ Running in a subprocess.
+ Set up tests2.Layer2
+ **********************************************************************
+ <BLANKLINE>
+ Can't post-mortem debug when running a layer as a subprocess!
+ Try running layer 'tests2.Layer2' by itself.
+ <BLANKLINE>
+ **********************************************************************
+ <BLANKLINE>
+ Traceback (most recent call last):
+ ...
+ raise ValueError
+ ValueError
+ <BLANKLINE>
+ <BLANKLINE>
+ Tests with errors:
+ runTest (__main__.SetUpLayerFailure)
+ Total: 1 tests, 0 failures, 1 errors in 0.210 seconds.
+ True
+
+ >>> shutil.rmtree(tdir)
+
Property changes on: zope.testing/trunk/src/zope/testing/testrunner-debugging-layer-setup.test
___________________________________________________________________
Name: svn:eol-style
+ native
Modified: zope.testing/trunk/src/zope/testing/testrunner.py
===================================================================
--- zope.testing/trunk/src/zope/testing/testrunner.py 2007-08-14 19:20:39 UTC (rev 78820)
+++ zope.testing/trunk/src/zope/testing/testrunner.py 2007-08-14 22:11:05 UTC (rev 78821)
@@ -19,6 +19,7 @@
# Too bad: For now, we depend on zope.testing. This is because
# we want to use the latest, greatest doctest, which zope.testing
# provides. Then again, zope.testing is generally useful.
+
import gc
import glob
import logging
@@ -27,6 +28,7 @@
import errno
import pdb
import re
+import cStringIO
import sys
import tempfile
import threading
@@ -1246,9 +1248,23 @@
if options.resume_layer != None:
output.info_suboptimal( " Running in a subprocess.")
- setup_layer(options, layer, setup_layers)
- return run_tests(options, tests, layer_name, failures, errors)
+ try:
+ setup_layer(options, layer, setup_layers)
+ except EndRun:
+ raise
+ except Exception:
+ f = cStringIO.StringIO()
+ traceback.print_exc(file=f)
+ output.error(f.getvalue())
+ errors.append((SetUpLayerFailure(), sys.exc_info()))
+ return 0
+ else:
+ return run_tests(options, tests, layer_name, failures, errors)
+class SetUpLayerFailure(unittest.TestCase):
+ def runTest(self):
+ "Layer set up failure."
+
def resume_tests(options, layer_name, layers, failures, errors):
output = options.output
layers = [l for (l, _, _) in layers]
@@ -1341,6 +1357,12 @@
output.stop_tear_down(time.time() - t)
del setup_layers[l]
+
+cant_pm_in_subprocess_message = """
+Can't post-mortem debug when running a layer as a subprocess!
+Try running layer %r by itself.
+"""
+
def setup_layer(options, layer, setup_layers):
assert layer is not object
output = options.output
@@ -1351,7 +1373,20 @@
output.start_set_up(name_from_layer(layer))
t = time.time()
if hasattr(layer, 'setUp'):
- layer.setUp()
+ try:
+ layer.setUp()
+ except Exception:
+ if options.post_mortem:
+ if options.resume_layer:
+ options.output.error_with_banner(
+ cant_pm_in_subprocess_message
+ % options.resume_layer)
+ raise
+ else:
+ post_mortem(sys.exc_info())
+ else:
+ raise
+
output.stop_set_up(time.time() - t)
setup_layers[layer] = 1
@@ -2639,6 +2674,7 @@
doctest.DocFileSuite(
'testrunner-arguments.txt',
'testrunner-coverage.txt',
+ 'testrunner-debugging-layer-setup.test',
'testrunner-debugging.txt',
'testrunner-edge-cases.txt',
'testrunner-errors.txt',
More information about the Zope3-Checkins
mailing list