Better handling of KeyboardInterrupt

When we get a suspected KeyboardInterrupt (no result from Deferred),
explicitly stop the result and report the error as if it were a user
error.
This commit is contained in:
Jonathan Lange
2016-02-14 13:01:31 +00:00
parent 725bfa9595
commit cd286b23f2
3 changed files with 13 additions and 5 deletions

6
NEWS
View File

@@ -16,6 +16,12 @@ Improvements
* Fixed example in ``failed`` docstring. (Jonathan Lange, Github #208)
* Rather than explicitly raising a ``KeyboardInterrupt`` if we get no result
from a ``Deferred``, we tell the test result to stop running tests and
report the lack of result as a test error. This ought to make weird
concurrency interaction bugs easier to understand. (Jonathan Lange)
2.0.0
~~~~~

View File

@@ -469,8 +469,8 @@ class TestAsynchronousDeferredRunTest(NeedsTwistedTestCase):
runner = self.make_runner(test, timeout * 5)
result = self.make_result()
reactor.callLater(timeout, os.kill, os.getpid(), SIGINT)
self.assertThat(lambda:runner.run(result),
Raises(MatchesException(KeyboardInterrupt)))
runner.run(result)
self.assertThat(result.shouldStop, Equals(True))
@skipIf(os.name != "posix", "Sending SIGINT with os.kill is posix only")
def test_fast_keyboard_interrupt_stops_test_run(self):
@@ -488,8 +488,8 @@ class TestAsynchronousDeferredRunTest(NeedsTwistedTestCase):
runner = self.make_runner(test, timeout * 5)
result = self.make_result()
reactor.callWhenRunning(os.kill, os.getpid(), SIGINT)
self.assertThat(lambda:runner.run(result),
Raises(MatchesException(KeyboardInterrupt)))
runner.run(result)
self.assertThat(result.shouldStop, Equals(True))
def test_timeout_causes_test_error(self):
# If a test times out, it reports itself as having failed with a

View File

@@ -395,7 +395,9 @@ class AsynchronousDeferredRunTest(_DeferredRunTest):
except NoResultError:
# We didn't get a result at all! This could be for any number of
# reasons, but most likely someone hit Ctrl-C during the test.
raise KeyboardInterrupt
self._got_user_exception(sys.exc_info())
self.result.stop()
return False, []
except TimeoutError:
# The function took too long to run.
self._log_user_exception(TimeoutError(self.case, self._timeout))