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.

Reply via email to