3 new revisions:
Revision: 60b4d6e45b74
Branch: default
Author: Pekka Klärck
Date: Sun Jan 26 15:50:25 2014 UTC
Log: Small cleanup for handling --suite with dots at parsing time....
http://code.google.com/p/robotframework/source/detail?r=60b4d6e45b74
Revision: e5cabbbef368
Branch: default
Author: Pekka Klärck
Date: Sun Jan 26 16:21:28 2014 UTC
Log: Enhanced tests for restoring original signal handler....
http://code.google.com/p/robotframework/source/detail?r=e5cabbbef368
Revision: ae16a4f2bbbe
Branch: default
Author: Pekka Klärck
Date: Sun Jan 26 16:46:11 2014 UTC
Log: Turned signal handler to context manager....
http://code.google.com/p/robotframework/source/detail?r=ae16a4f2bbbe
==============================================================================
Revision: 60b4d6e45b74
Branch: default
Author: Pekka Klärck
Date: Sun Jan 26 15:50:25 2014 UTC
Log: Small cleanup for handling --suite with dots at parsing time.
Update issue 1632
Status: Done
Looked very good. The algorithm to generate suite names was a bit hard to
understand, so I changed it to use more explicit `while '.' not in suite`
loop. Also added some more cases to the unit test to verify the
implementation.
http://code.google.com/p/robotframework/source/detail?r=60b4d6e45b74
Modified:
/src/robot/parsing/populators.py
/utest/parsing/test_populator.py
=======================================
--- /src/robot/parsing/populators.py Fri Jan 24 07:02:45 2014 UTC
+++ /src/robot/parsing/populators.py Sun Jan 26 15:50:25 2014 UTC
@@ -106,7 +106,7 @@
def populate(self, path, datadir, include_suites=None,
warn_on_skipped=False, recurse=True):
LOGGER.info("Parsing test data directory '%s'" % path)
- include_suites = self._get_include_suites(path, include_suites)
+ include_suites = self._get_include_suites(path, include_suites or
[])
init_file, children = self._get_children(path, include_suites)
if init_file:
self._populate_init_file(datadir, init_file)
@@ -146,11 +146,11 @@
return incl_suites
def _create_included_suites(self, incl_suites):
- result = []
- for splitted in (i.split('.') for i in incl_suites or []):
- for j in range(1, len(splitted)+1):
- result.append('.'.join(splitted[-j:]))
- return result
+ for suite in incl_suites:
+ yield suite
+ while '.' in suite:
+ suite = suite.split('.', 1)[1]
+ yield suite
def _directory_is_included(self, path, incl_suites):
name = os.path.basename(os.path.normpath(path))
=======================================
--- /utest/parsing/test_populator.py Thu Jan 23 09:13:21 2014 UTC
+++ /utest/parsing/test_populator.py Sun Jan 26 15:50:25 2014 UTC
@@ -24,10 +24,13 @@
class FromDirectoryPopulatorTest(unittest.TestCase):
def test_included_suites_with_dot(self):
- populator = FromDirectoryPopulator()
- self.assertEqual(populator._create_included_suites([]), [])
- self.assertEqual(populator._create_included_suites(['foo']),
['foo'])
- self.assertEqual(populator._create_included_suites(['bar.zoo']),
['zoo', 'bar.zoo'])
+ create_included_suites =
FromDirectoryPopulator()._create_included_suites
+ for inp, exp in [([], []),
+ (['foo'], ['foo']),
+ (['bar.zoo'], ['bar.zoo', 'zoo']),
+ (['1.2.3', 'x.y', 'z'],
+ ['1.2.3', '2.3', '3', 'x.y', 'y', 'z'])]:
+ assert_equals(list(create_included_suites(inp)), exp)
class _PopulatorTest(unittest.TestCase):
==============================================================================
Revision: e5cabbbef368
Branch: default
Author: Pekka Klärck
Date: Sun Jan 26 16:21:28 2014 UTC
Log: Enhanced tests for restoring original signal handler.
Update issue 1617
Added unit tests for actually restoring signal handlers both when using
robot.run and TestSuite.run().
http://code.google.com/p/robotframework/source/detail?r=e5cabbbef368
Modified:
/src/robot/running/signalhandler.py
/utest/api/test_run_and_rebot.py
/utest/running/test_running.py
=======================================
--- /src/robot/running/signalhandler.py Thu Jan 23 14:00:53 2014 UTC
+++ /src/robot/running/signalhandler.py Sun Jan 26 16:21:28 2014 UTC
@@ -32,8 +32,8 @@
def __init__(self):
self._signal_count = 0
self._running_keyword = False
- self.orig_sigint = None
- self.orig_sigterm = None
+ self._orig_sigint = None
+ self._orig_sigterm = None
def __call__(self, signum, frame):
self._signal_count += 1
@@ -50,15 +50,15 @@
def start(self):
if signal:
- self.orig_sigint = signal.getsignal(signal.SIGINT)
- self.orig_sigterm = signal.getsignal(signal.SIGTERM)
+ self._orig_sigint = signal.getsignal(signal.SIGINT)
+ self._orig_sigterm = signal.getsignal(signal.SIGTERM)
for signum in signal.SIGINT, signal.SIGTERM:
self._register_signal_handler(signum)
def stop(self):
if signal:
- signal.signal(signal.SIGINT, self.orig_sigint)
- signal.signal(signal.SIGTERM, self.orig_sigterm)
+ signal.signal(signal.SIGINT, self._orig_sigint)
+ signal.signal(signal.SIGTERM, self._orig_sigterm)
def _register_signal_handler(self, signum):
try:
=======================================
--- /utest/api/test_run_and_rebot.py Thu Dec 19 14:28:22 2013 UTC
+++ /utest/api/test_run_and_rebot.py Sun Jan 26 16:21:28 2014 UTC
@@ -1,6 +1,7 @@
import unittest
import sys
import tempfile
+import signal
from os.path import abspath, dirname, join, exists, curdir
from os import chdir
from StringIO import StringIO
@@ -154,6 +155,25 @@
assert_equals(rc, 1)
+class TestPreservingSignalHandlers(unittest.TestCase):
+
+ def setUp(self):
+ self.orig_sigint = signal.getsignal(signal.SIGINT)
+ self.orig_sigterm = signal.getsignal(signal.SIGTERM)
+
+ def tearDown(self):
+ signal.signal(signal.SIGINT, self.orig_sigint)
+ signal.signal(signal.SIGTERM, self.orig_sigterm)
+
+ def test_original_signal_handlers_are_restored(self):
+ my_sigterm = lambda signum, frame: None
+ signal.signal(signal.SIGTERM, my_sigterm)
+ run(join(ROOT, 'atest', 'testdata', 'misc', 'pass_and_fail.txt'),
+ stdout=StringIO(), output=None, log=None, report=None)
+ assert_equals(signal.getsignal(signal.SIGINT), self.orig_sigint)
+ assert_equals(signal.getsignal(signal.SIGTERM), my_sigterm)
+
+
class TestRelativeImportsFromPythonpath(RunningTestCase):
_data = join(abspath(dirname(__file__)), 'import_test.txt')
=======================================
--- /utest/running/test_running.py Mon Dec 23 13:43:57 2013 UTC
+++ /utest/running/test_running.py Sun Jan 26 16:21:28 2014 UTC
@@ -1,6 +1,6 @@
import sys
import unittest
-
+import signal
from StringIO import StringIO
from os.path import abspath, dirname, normpath, join
@@ -12,9 +12,12 @@
CURDIR = dirname(abspath(__file__))
DATADIR = normpath(join(CURDIR, '..', '..', 'atest', 'testdata', 'misc'))
+
def run(suite, **kwargs):
- result = suite.run(output='NONE', stdout=StringIO(), stderr=StringIO(),
- **kwargs)
+ config = dict(output=None, log=None, report=None,
+ stdout=StringIO(), stderr=StringIO())
+ config.update(kwargs)
+ result = suite.run(**config)
return result.suite
@@ -209,11 +212,31 @@
suite = TestSuite(name='My Suite')
suite.variables.create('${MESSAGE}', 'Hello, world!')
suite.tests.create(name='My Test').keywords.create('Log',
args=['${MESSAGE}', 'WARN'])
- suite.run(stdout=stdout, stderr=stderr, **options)
+ run(suite, stdout=stdout, stderr=stderr, **options)
def _assert_normal_stdout_stderr_are_empty(self):
self._assert_outputs()
+class TestPreservingSignalHandlers(unittest.TestCase):
+
+ def setUp(self):
+ self.orig_sigint = signal.getsignal(signal.SIGINT)
+ self.orig_sigterm = signal.getsignal(signal.SIGTERM)
+
+ def tearDown(self):
+ signal.signal(signal.SIGINT, self.orig_sigint)
+ signal.signal(signal.SIGTERM, self.orig_sigterm)
+
+ def test_original_signal_handlers_are_restored(self):
+ my_sigterm = lambda signum, frame: None
+ signal.signal(signal.SIGTERM, my_sigterm)
+ suite = TestSuite(name='My Suite')
+ suite.tests.create(name='My Test').keywords.create('Log',
args=['Hi!'])
+ run(suite)
+ assert_equals(signal.getsignal(signal.SIGINT), self.orig_sigint)
+ assert_equals(signal.getsignal(signal.SIGTERM), my_sigterm)
+
+
if __name__ == '__main__':
unittest.main()
==============================================================================
Revision: ae16a4f2bbbe
Branch: default
Author: Pekka Klärck
Date: Sun Jan 26 16:46:11 2014 UTC
Log: Turned signal handler to context manager.
Old start() was kept for backwards compatibility reasons but a note about
removing it in RF 2.9 was added.
Update issue 1617
Summary: Signal handler should be reset to original after execution
Status: Done
Cc: pekka.klarck
Turned the signal handler into a context manager. This cleaned up its usage
and also made sure original signal handlers are restored also if there are
unexpected failures.
http://code.google.com/p/robotframework/source/detail?r=ae16a4f2bbbe
Modified:
/src/robot/running/model.py
/src/robot/running/signalhandler.py
/utest/running/test_signalhandler.py
=======================================
--- /src/robot/running/model.py Thu Jan 23 14:00:53 2014 UTC
+++ /src/robot/running/model.py Sun Jan 26 16:46:11 2014 UTC
@@ -12,6 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from __future__ import with_statement
+
from robot import model
from robot.conf import RobotSettings
from robot.output import LOGGER, Output, pyloggingconf
@@ -187,14 +189,13 @@
if not settings:
settings = RobotSettings(options)
LOGGER.register_console_logger(**settings.console_logger_config)
- STOP_SIGNAL_MONITOR.start()
- IMPORTER.reset()
- pyloggingconf.initialize(settings['LogLevel'])
- init_global_variables(settings)
- output = Output(settings)
- runner = Runner(output, settings)
- self.visit(runner)
- STOP_SIGNAL_MONITOR.stop()
+ with STOP_SIGNAL_MONITOR:
+ IMPORTER.reset()
+ pyloggingconf.initialize(settings['LogLevel'])
+ init_global_variables(settings)
+ output = Output(settings)
+ runner = Runner(output, settings)
+ self.visit(runner)
output.close(runner.result)
return runner.result
=======================================
--- /src/robot/running/signalhandler.py Sun Jan 26 16:21:28 2014 UTC
+++ /src/robot/running/signalhandler.py Sun Jan 26 16:46:11 2014 UTC
@@ -49,13 +49,19 @@
raise ExecutionFailed('Execution terminated by signal', exit=True)
def start(self):
+ # TODO: Remove start() in favor of __enter__ in RF 2.9. Refactoring
+ # the whole signal handler at that point would be a good idea.
+ self.__enter__()
+
+ def __enter__(self):
if signal:
self._orig_sigint = signal.getsignal(signal.SIGINT)
self._orig_sigterm = signal.getsignal(signal.SIGTERM)
for signum in signal.SIGINT, signal.SIGTERM:
self._register_signal_handler(signum)
+ return self
- def stop(self):
+ def __exit__(self, *exc_info):
if signal:
signal.signal(signal.SIGINT, self._orig_sigint)
signal.signal(signal.SIGTERM, self._orig_sigterm)
=======================================
--- /utest/running/test_signalhandler.py Wed Jan 15 13:31:26 2014 UTC
+++ /utest/running/test_signalhandler.py Sun Jan 26 16:46:11 2014 UTC
@@ -1,3 +1,4 @@
+from __future__ import with_statement
import sys
import signal
import unittest
@@ -21,7 +22,7 @@
self.messages.append(msg)
-class TestSignalHandlerRegisteringFaiures(unittest.TestCase):
+class TestSignalHandlerRegisteringFailures(unittest.TestCase):
def setUp(self):
self.logger = LoggerStub()
@@ -58,15 +59,6 @@
t.join()
assert_equal(len(self.logger.messages), 0)
- def test_signal_handler_restore(self):
- orig_sigint = signal.getsignal(signal.SIGINT)
- orig_sigterm = signal.getsignal(signal.SIGTERM)
- signal_monitor = _StopSignalMonitor()
- signal_monitor.start()
- signal_monitor.stop()
- assert_equal(orig_sigint, signal.getsignal(signal.SIGINT))
- assert_equal(orig_sigterm, signal.getsignal(signal.SIGTERM))
-
if sys.platform.startswith('java'):
# signal.signal may raise IllegalArgumentException with Jython
2.5.2:
@@ -83,5 +75,42 @@
'java.lang.IllegalArgumentException: xxx')
+class TestRestoringOriginalHandlers(unittest.TestCase):
+
+ def get_int(self):
+ return signal.getsignal(signal.SIGINT)
+
+ def get_term(self):
+ return signal.getsignal(signal.SIGTERM)
+
+ def setUp(self):
+ self.orig_int = self.get_int()
+ self.orig_term = self.get_term()
+
+ def tearDown(self):
+ signal.signal(signal.SIGINT, self.orig_int)
+ signal.signal(signal.SIGTERM, self.orig_term)
+
+ def test_restore_when_no_failures(self):
+ with _StopSignalMonitor() as monitor:
+ assert_equal(self.get_int(), monitor)
+ assert_equal(self.get_term(), monitor)
+ assert_equal(self.get_int(), self.orig_int)
+ assert_equal(self.get_term(), self.orig_term)
+
+ def test_restore_when_failure(self):
+ try:
+ with _StopSignalMonitor() as monitor:
+ assert_equal(self.get_int(), monitor)
+ assert_equal(self.get_term(), monitor)
+ raise ZeroDivisionError
+ except ZeroDivisionError:
+ pass
+ else:
+ raise AssertionError
+ assert_equal(self.get_int(), self.orig_int)
+ assert_equal(self.get_term(), self.orig_term)
+
+
if __name__ == '__main__':
unittest.main()
--
---
You received this message because you are subscribed to the Google Groups "robotframework-commit" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to robotframework-commit+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.