diff options
author | Martin Pool <mbp@canonical.com> | 2011-11-29 13:21:58 +1100 |
---|---|---|
committer | Martin Pool <mbp@canonical.com> | 2011-11-29 13:21:58 +1100 |
commit | 2b1fba6a3e920d0e2e87551defaed08025dc112c (patch) | |
tree | 025c663825dfc5cda89315b1b147748cdf811594 | |
parent | 05e00d8d1b3d0a6e0ddc2153d9552f7823223ae9 (diff) | |
download | fixtures-2b1fba6a3e920d0e2e87551defaed08025dc112c.tar.gz |
Rename to just TimeoutException, and remove more connections to Timeout only being used in tests
-rw-r--r-- | README | 6 | ||||
-rw-r--r-- | lib/fixtures/__init__.py | 2 | ||||
-rw-r--r-- | lib/fixtures/_fixtures/__init__.py | 6 | ||||
-rw-r--r-- | lib/fixtures/_fixtures/timeout.py | 33 | ||||
-rw-r--r-- | lib/fixtures/tests/_fixtures/test_timeout.py | 42 |
5 files changed, 53 insertions, 36 deletions
@@ -343,9 +343,9 @@ Aborts if the covered code takes more than a specified number of whole wall-cloc seconds. There are two possibilities, controlled by the 'gentle' argument: when gentle, -an exception will be raised and the test will fail. When not gentle, the -entire test process will be terminated, which is less clean, but more likely to -break hangs where no Python code is running. +an exception will be raised and the test (or other covered code) will fail. +When not gentle, the entire process will be terminated, which is less clean, +but more likely to break hangs where no Python code is running. *Caution:* Only one timeout can be active at any time across all threads in a single process. Using more than one has undefined results. (This could be diff --git a/lib/fixtures/__init__.py b/lib/fixtures/__init__.py index 42ecf6f..7e4a319 100644 --- a/lib/fixtures/__init__.py +++ b/lib/fixtures/__init__.py @@ -52,6 +52,7 @@ __all__ = [ 'TempDir', 'TestWithFixtures', 'Timeout', + 'TimeoutException', ] @@ -66,6 +67,7 @@ from fixtures._fixtures import ( PythonPathEntry, TempDir, Timeout, + TimeoutException, ) from fixtures.testcase import TestWithFixtures diff --git a/lib/fixtures/_fixtures/__init__.py b/lib/fixtures/_fixtures/__init__.py index d219c7a..30c1594 100644 --- a/lib/fixtures/_fixtures/__init__.py +++ b/lib/fixtures/_fixtures/__init__.py @@ -26,6 +26,7 @@ __all__ = [ 'PythonPathEntry', 'TempDir', 'Timeout', + 'TimeoutException', ] @@ -37,4 +38,7 @@ from fixtures._fixtures.packagepath import PackagePathEntry from fixtures._fixtures.pythonpackage import PythonPackage from fixtures._fixtures.pythonpath import PythonPathEntry from fixtures._fixtures.tempdir import TempDir -from fixtures._fixtures.timeout import Timeout +from fixtures._fixtures.timeout import ( + Timeout, + TimeoutException, + ) diff --git a/lib/fixtures/_fixtures/timeout.py b/lib/fixtures/_fixtures/timeout.py index b5fcbe9..73c61c6 100644 --- a/lib/fixtures/_fixtures/timeout.py +++ b/lib/fixtures/_fixtures/timeout.py @@ -1,7 +1,7 @@ # fixtures: Fixtures with cleanups for testing and convenience. # # Copyright (C) 2011, Martin Pool <mbp@sourcefrog.net> -# +# # Licensed under either the Apache License, Version 2.0 or the BSD 3-clause # license at the users choice. A copy of both licenses are available in the # project source as Apache-2.0 and BSD. You may not use this file except in @@ -14,32 +14,51 @@ # limitations under that license. +"""Timeout fixture.""" + + import signal import fixtures +__all__ = [ + 'Timeout', + 'TimeoutException', + ] -class TestTimeoutException(Exception): - """Test timed out""" + +class TimeoutException(Exception): + """Timeout expired""" class Timeout(fixtures.Fixture): + """Fixture that aborts the contained code after a number of seconds. + + The interrupt can be either gentle, in which case TimeoutException is + raised, or not gentle, in which case the process will typically be aborted + by SIGALRM. + + Cautions: + * This has no effect on Windows. + * Only one Timeout can be used at any time per process. + """ def __init__(self, timeout_secs, gentle): self.timeout_secs = timeout_secs self.alarm_fn = getattr(signal, 'alarm', None) self.gentle = gentle - def signal_handler(self): - raise TestTimeoutException() + def signal_handler(self, signum, frame): + raise TimeoutException() def setUp(self): - super(TestTimeout, self).setUp() + super(Timeout, self).setUp() if self.alarm_fn is None: return # Can't run on Windows self.alarm_fn(self.timeout_secs) self.addCleanup(lambda: self.alarm_fn(0)) if self.gentle: saved_handler = signal.signal(signal.SIGALRM, self.signal_handler) - self.addCleanup(lambda: signal.signal(signal.SIGALRM, saved_handler)) + self.addCleanup(lambda: signal.signal( + signal.SIGALRM, saved_handler)) # Otherwise, the SIGALRM will probably kill the process. diff --git a/lib/fixtures/tests/_fixtures/test_timeout.py b/lib/fixtures/tests/_fixtures/test_timeout.py index 3521aaa..cbd868e 100644 --- a/lib/fixtures/tests/_fixtures/test_timeout.py +++ b/lib/fixtures/tests/_fixtures/test_timeout.py @@ -15,6 +15,7 @@ import os import signal +import time import testtools from testtools.testcase import ( @@ -22,27 +23,22 @@ from testtools.testcase import ( ) import fixtures -from fixtures import EnvironmentVariableFixture, TestWithFixtures -class ExampleTests(testtools.TestCase, TestWithFixtures): - """These are not intended to pass: they are sample data for the real tests""" - - def sample_timeout_passes(self): - self.useFixture(fixtures.Timeout(100, gentle=True)) +def sample_timeout_passes(): + with fixtures.Timeout(100, gentle=True): pass # Timeout shouldn't fire - def sample_long_delay_with_timeout(self): - self.useFixture(fixtures.Timeout(2, gentle=True)) +def sample_long_delay_with_gentle_timeout(): + with fixtures.Timeout(1, gentle=True): time.sleep(100) # Expected to be killed here. - def sample_long_delay_with_harsh_timeout(self): - self.useFixture(fixtures.Timeout(2, gentle=False)) +def sample_long_delay_with_harsh_timeout(): + with fixtures.Timeout(1, gentle=False): time.sleep(100) # Expected to be killed here. - -class TestTimeout(testtools.TestCase, TestWithFixtures): +class TestTimeout(testtools.TestCase, fixtures.TestWithFixtures): def requireUnix(self): if getattr(signal, 'alarm', None) is None: @@ -50,26 +46,22 @@ class TestTimeout(testtools.TestCase, TestWithFixtures): def test_timeout_passes(self): # This can pass even on Windows - the test is skipped. - test = ExampleTests('sample_timeout_passes') - result = test.run() - self.assertTrue(result.wasSuccessful()) + sample_timeout_passes() def test_timeout_gentle(self): self.requireUnix() - test = ExampleTests('sample_long_delay_with_timeout') - result = test.run() - self.assertFalse(result.wasSuccessful()) + self.assertRaises( + fixtures.TimeoutException, + sample_long_delay_with_gentle_timeout) def test_timeout_harsh(self): self.requireUnix() - test = ExampleTests('sample_long_delay_with_harsh_timeout') # This will normally kill the whole process, which would be # inconvenient. Let's hook the alarm here so we can observe it. - got_alarm = False - def sigalrm_handler(): - got_alarm = True + self.got_alarm = False + def sigalrm_handler(signum, frame): + self.got_alarm = True old_handler = signal.signal(signal.SIGALRM, sigalrm_handler) self.addCleanup(signal.signal, signal.SIGALRM, old_handler) - result = test.run() - self.assertFalse(result.wasSuccessful()) - self.assertTrue(got_alarm) + sample_long_delay_with_harsh_timeout() + self.assertTrue(self.got_alarm) |