[svn r63797] introduce a clean "guardedcall" interface for performing calls with exception catching and stdout/stderr capturing
--HG-- branch : trunk
This commit is contained in:
parent
4893c58d22
commit
bba69f207b
|
@ -286,6 +286,28 @@ class Config(object):
|
||||||
roots.append(pydir)
|
roots.append(pydir)
|
||||||
return roots
|
return roots
|
||||||
|
|
||||||
|
def guardedcall(self, func):
|
||||||
|
excinfo = result = None
|
||||||
|
capture = self._getcapture()
|
||||||
|
try:
|
||||||
|
try:
|
||||||
|
result = func()
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
raise
|
||||||
|
except:
|
||||||
|
excinfo = py.code.ExceptionInfo()
|
||||||
|
finally:
|
||||||
|
stdout, stderr = capture.reset()
|
||||||
|
return CallResult(result, excinfo, stdout, stderr)
|
||||||
|
|
||||||
|
class CallResult:
|
||||||
|
def __init__(self, result, excinfo, stdout, stderr):
|
||||||
|
self.stdout = stdout
|
||||||
|
self.stderr = stderr
|
||||||
|
self.outerr = (self.stdout, self.stderr)
|
||||||
|
self.excinfo = excinfo
|
||||||
|
if excinfo is None:
|
||||||
|
self.result = result
|
||||||
|
|
||||||
#
|
#
|
||||||
# helpers
|
# helpers
|
||||||
|
|
|
@ -198,41 +198,22 @@ class SetupState(object):
|
||||||
self.stack.append(col)
|
self.stack.append(col)
|
||||||
|
|
||||||
def do_setup(self, item):
|
def do_setup(self, item):
|
||||||
excinfo, outerr = guarded_call(item.config._getcapture(),
|
call = item.config.guardedcall(lambda: self.prepare(item))
|
||||||
lambda: self.prepare(item)
|
rep = ItemSetupReport(item, call.excinfo, call.outerr)
|
||||||
)
|
|
||||||
rep = ItemSetupReport(item, excinfo, outerr)
|
|
||||||
item.config.pytestplugins.notify("itemsetupreport", rep)
|
item.config.pytestplugins.notify("itemsetupreport", rep)
|
||||||
return not excinfo
|
return not call.excinfo
|
||||||
|
|
||||||
def do_teardown(self, item):
|
def do_teardown(self, item):
|
||||||
excinfo, outerr = guarded_call(item.config._getcapture(),
|
call = item.config.guardedcall(lambda: self.teardown_exact(item))
|
||||||
lambda: self.teardown_exact(item)
|
if call.excinfo:
|
||||||
)
|
rep = ItemSetupReport(item, call.excinfo, call.outerr)
|
||||||
if excinfo:
|
|
||||||
rep = ItemSetupReport(item, excinfo, outerr)
|
|
||||||
item.config.pytestplugins.notify("itemsetupreport", rep)
|
item.config.pytestplugins.notify("itemsetupreport", rep)
|
||||||
|
|
||||||
def do_fixture_and_runtest(self, item):
|
def do_fixture_and_runtest(self, item):
|
||||||
""" setup fixture and perform actual item.runtest(). """
|
""" setup fixture and perform actual item.runtest(). """
|
||||||
if self.do_setup(item):
|
if self.do_setup(item):
|
||||||
excinfo, outerr = guarded_call(item.config._getcapture(),
|
call = item.config.guardedcall(lambda: item.runtest())
|
||||||
lambda: item.runtest())
|
|
||||||
item.config.pytestplugins.notify(
|
item.config.pytestplugins.notify(
|
||||||
"item_runtest_finished",
|
"item_runtest_finished",
|
||||||
item=item, excinfo=excinfo, outerr=outerr)
|
item=item, excinfo=call.excinfo, outerr=call.outerr)
|
||||||
self.do_teardown(item)
|
self.do_teardown(item)
|
||||||
|
|
||||||
def guarded_call(capture, call):
|
|
||||||
excinfo = None
|
|
||||||
try:
|
|
||||||
try:
|
|
||||||
call()
|
|
||||||
except (KeyboardInterrupt, Exit):
|
|
||||||
raise
|
|
||||||
except:
|
|
||||||
excinfo = py.code.ExceptionInfo()
|
|
||||||
finally:
|
|
||||||
outerr = capture.reset()
|
|
||||||
return excinfo, outerr
|
|
||||||
|
|
||||||
|
|
|
@ -137,8 +137,7 @@ class TestConfigAPI:
|
||||||
assert pl[1] == somepath
|
assert pl[1] == somepath
|
||||||
|
|
||||||
def test_setsessionclass_and_initsession(self, testdir):
|
def test_setsessionclass_and_initsession(self, testdir):
|
||||||
from py.__.test.config import Config
|
config = testdir.Config()
|
||||||
config = Config()
|
|
||||||
class Session1:
|
class Session1:
|
||||||
def __init__(self, config):
|
def __init__(self, config):
|
||||||
self.config = config
|
self.config = config
|
||||||
|
@ -149,7 +148,6 @@ class TestConfigAPI:
|
||||||
py.test.raises(ValueError, "config.setsessionclass(Session1)")
|
py.test.raises(ValueError, "config.setsessionclass(Session1)")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class TestConfigApi_getcolitems:
|
class TestConfigApi_getcolitems:
|
||||||
def test_getcolitems_onedir(self, tmpdir):
|
def test_getcolitems_onedir(self, tmpdir):
|
||||||
config = py.test.config._reparse([tmpdir])
|
config = py.test.config._reparse([tmpdir])
|
||||||
|
@ -214,6 +212,37 @@ class TestConfigApi_getcolitems:
|
||||||
assert col.config is config
|
assert col.config is config
|
||||||
|
|
||||||
|
|
||||||
|
class TestGuardedCall:
|
||||||
|
def test_guardedcall_ok(self, testdir):
|
||||||
|
config = testdir.parseconfig()
|
||||||
|
def myfunc(x):
|
||||||
|
print x
|
||||||
|
print >>py.std.sys.stderr, "hello"
|
||||||
|
return 7
|
||||||
|
call = config.guardedcall(lambda: myfunc(3))
|
||||||
|
assert call.excinfo is None
|
||||||
|
assert call.result == 7
|
||||||
|
assert call.stdout.startswith("3")
|
||||||
|
assert call.stderr.startswith("hello")
|
||||||
|
|
||||||
|
def test_guardedcall_fail(self, testdir):
|
||||||
|
config = testdir.parseconfig()
|
||||||
|
def myfunc(x):
|
||||||
|
print x
|
||||||
|
raise ValueError(17)
|
||||||
|
call = config.guardedcall(lambda: myfunc(3))
|
||||||
|
assert call.excinfo
|
||||||
|
assert call.excinfo.type == ValueError
|
||||||
|
assert not hasattr(call, 'result')
|
||||||
|
assert call.stdout.startswith("3")
|
||||||
|
assert not call.stderr
|
||||||
|
|
||||||
|
def test_guardedcall_keyboardinterrupt(self, testdir):
|
||||||
|
config = testdir.parseconfig()
|
||||||
|
def myfunc():
|
||||||
|
raise KeyboardInterrupt
|
||||||
|
py.test.raises(KeyboardInterrupt, config.guardedcall, myfunc)
|
||||||
|
|
||||||
class TestOptionEffects:
|
class TestOptionEffects:
|
||||||
def test_boxed_option_default(self, testdir):
|
def test_boxed_option_default(self, testdir):
|
||||||
tmpdir = testdir.tmpdir.ensure("subdir", dir=1)
|
tmpdir = testdir.tmpdir.ensure("subdir", dir=1)
|
||||||
|
|
Loading…
Reference in New Issue