4 new revisions:

Revision: 82db62aa0032
Author:   Pekka Klärck
Date:     Tue Dec 20 14:14:00 2011
Log: atest/genrunner.py: 1) four space separation is better than two space ...
http://code.google.com/p/robotframework/source/detail?r=82db62aa0032

Revision: 24c720921b9f
Author:   Pekka Klärck
Date:     Tue Dec 20 14:31:19 2011
Log: Prevent infinite recursion by having a hard limit of how many keywords...
http://code.google.com/p/robotframework/source/detail?r=24c720921b9f

Revision: a21cebe1158e
Author:   Pekka Klärck
Date:     Tue Dec 20 14:41:34 2011
Log:      test cleanup
http://code.google.com/p/robotframework/source/detail?r=a21cebe1158e

Revision: 80961a182cb5
Author:   Pekka Klärck
Date:     Tue Dec 20 14:50:03 2011
Log: Fixed execution context dependent BuiltIn keywords/methods by importin...
http://code.google.com/p/robotframework/source/detail?r=80961a182cb5

==============================================================================
Revision: 82db62aa0032
Author:   Pekka Klärck
Date:     Tue Dec 20 14:14:00 2011
Log: atest/genrunner.py: 1) four space separation is better than two space separation, 2) cleanup is better than messup
http://code.google.com/p/robotframework/source/detail?r=82db62aa0032

Modified:
 /atest/genrunner.py

=======================================
--- /atest/genrunner.py Wed Apr 21 00:52:13 2010
+++ /atest/genrunner.py Tue Dec 20 14:14:00 2011
@@ -6,22 +6,22 @@
 """

 from __future__ import with_statement
-import sys, os
+from os.path import abspath, basename, dirname, exists, join
+import os
+import sys

 if len(sys.argv) != 2:
-    print __doc__ % os.path.basename(sys.argv[0])
+    print __doc__ % basename(sys.argv[0])
     sys.exit(1)

-inpath = os.path.abspath(sys.argv[1])
-outpath = inpath.replace(os.path.join('atest', 'testdata'),
-                         os.path.join('atest', 'robot'))
-
-dirname = os.path.dirname(outpath)
-if not os.path.exists(dirname):
-    os.mkdir(dirname)
-
-with open(inpath) as input:
-    tests = []
+INPATH = abspath(sys.argv[1])
+OUTPATH = INPATH.replace(join('atest', 'testdata'), join('atest', 'robot'))
+
+if not exists(dirname(OUTPATH)):
+    os.mkdir(dirname(OUTPATH))
+
+with open(INPATH) as input:
+    TESTS = []
     process = False
     for line in input.readlines():
         line = line.rstrip()
@@ -29,19 +29,20 @@
             name = line.replace('*', '').replace(' ', '').upper()
             process = name in ('TESTCASE', 'TESTCASES')
         elif process and line and line[0] != ' ':
-            tests.append(line.split('  ')[0])
-
-with open(outpath, 'w') as output:
-    path = inpath.split(os.path.join('atest', 'testdata'))[1][1:]
-    output.write("""*** Settings ***
-Suite Setup     Run Tests  ${EMPTY}  %s
-Force Tags      regression  pybot  jybot
-Resource        atest_resource.txt
+            TESTS.append(line.split('  ')[0])
+
+with open(OUTPATH, 'wb') as output:
+ path = INPATH.split(join('atest', 'testdata'))[1][1:].replace(os.sep, '/')
+    output.write("""\
+*** Settings ***
+Suite Setup      Run Tests    ${EMPTY}    %(path)s
+Force Tags       regression    pybot    jybot
+Resource         atest_resource.txt

 *** Test Cases ***

-""" % path.replace(os.sep, '/'))
-    for test in tests:
-        output.write(test + '\n    Check Test Case  ${TESTNAME}\n\n')
-
-print outpath
+""" % locals())
+    for test in TESTS:
+        output.write(test + '\n    Check Test Case    ${TESTNAME}\n\n')
+
+print OUTPATH

==============================================================================
Revision: 24c720921b9f
Author:   Pekka Klärck
Date:     Tue Dec 20 14:31:19 2011
Log: Prevent infinite recursion by having a hard limit of how many keywords can be open.

Update issue 551
Status: Done
Labels: Priority-Medium

The infinite recursion problem is now fixed and also acceptance
tested. There is a hard limit of 100 keywords that can be open
simultaneously. That ought to be enough for all valid usages so I
don't consider the fix backwards-incompatible. I also decided to raise
the priority of this issue as crashes are always somewhat nasty and
this has happened several times in real life.

Notice that before the simple fix prevented recursion involving Run
Keyword variants, a separate refactoring was needed to make them use
the same execution context as other keywords.
http://code.google.com/p/robotframework/source/detail?r=24c720921b9f

Added:
 /atest/robot/running/prevent_recursion.txt
 /atest/testdata/running/prevent_recursion.txt
Modified:
 /src/robot/running/context.py

=======================================
--- /dev/null
+++ /atest/robot/running/prevent_recursion.txt  Tue Dec 20 14:31:19 2011
@@ -0,0 +1,20 @@
+*** Settings ***
+Suite Setup      Run Tests    ${EMPTY}    running/prevent_recursion.txt
+Force Tags       regression    pybot    jybot
+Resource         atest_resource.txt
+
+*** Test Cases ***
+
+Infinite recursion
+    Check Test Case    ${TESTNAME}
+
+Infinite cyclic recursion
+    Check Test Case    ${TESTNAME}
+
+Infinite recursion with Run Keyword
+    Check Test Case    ${TESTNAME}
+
+Recursion below the recursion limit is ok
+ [Documentation] Also verifies that blown recursion limit doesn't affect subsequent tests
+    Check Test Case    ${TESTNAME}
+
=======================================
--- /dev/null
+++ /atest/testdata/running/prevent_recursion.txt       Tue Dec 20 14:31:19 2011
@@ -0,0 +1,53 @@
+*** Settings ***
+Suite Teardown    Recursion With Run Keyword
+
+*** Variables ***
+${PTD FAILED}        \n\nAlso teardown of the parent suite failed.
+${LIMIT EXCEEDED} Maximum limit of started keywords exceeded.${PTD FAILED}
+
+
+*** Test Cases ***
+
+Infinite recursion
+    [Documentation]    FAIL ${LIMIT EXCEEDED}
+    Recursion
+
+Infinite cyclic recursion
+    [Documentation]    FAIL ${LIMIT EXCEEDED}
+    Cyclic recursion
+
+Infinite recursion with Run Keyword
+    [Documentation]    FAIL ${LIMIT EXCEEDED}
+    Recursion with Run Keyword
+
+Recursion below the recursion limit is ok
+    [Documentation]    FAIL Still below limit!${PTD FAILED}
+    Limited recursion 1
+    Limited recursion 2
+
+
+*** Keywords ***
+
+Recursion
+    Recursion
+
+Limited recursion 1
+    [Arguments]    ${limit}=${45}
+    Run Keyword If    ${limit} > 0    Limited recursion 1   ${limit - 1}
+
+Limited recursion 2
+    [Arguments]    ${limit}=${90}
+    Run Keyword If    ${limit} < 0    Fail    Still below limit!
+    Limited recursion 2     ${limit - 1}
+
+Cyclic recursion
+    Cyclic recursion 2
+
+Cyclic recursion 2
+    Cyclic recursion 3
+
+Cyclic recursion 3
+    Cyclic recursion
+
+Recursion With Run Keyword
+    Run Keyword    Recursion With Run Keyword
=======================================
--- /src/robot/running/context.py       Tue Dec 20 13:45:05 2011
+++ /src/robot/running/context.py       Tue Dec 20 14:31:19 2011
@@ -12,6 +12,7 @@
 #  See the License for the specific language governing permissions and
 #  limitations under the License.

+from robot.errors import DataError
 from robot.variables import GLOBAL_VARIABLES


@@ -44,12 +45,14 @@


 class _ExecutionContext(object):
+    _started_keywords_threshold = 100

     def __init__(self, namespace, output, dry_run=False):
         self.namespace = namespace
         self.output = output
         self.dry_run = dry_run
         self._in_teardown = 0
+        self._started_keywords = 0

     @property
     def teardown(self):
@@ -119,10 +122,14 @@
         return self.namespace.get_handler(name)

     def start_keyword(self, keyword):
+        self._started_keywords += 1
+        if self._started_keywords > self._started_keywords_threshold:
+            raise DataError('Maximum limit of started keywords exceeded.')
         self.output.start_keyword(keyword)

     def end_keyword(self, keyword):
         self.output.end_keyword(keyword)
+        self._started_keywords -= 1

     def start_user_keyword(self, kw):
         self.namespace.start_user_keyword(kw)

==============================================================================
Revision: a21cebe1158e
Author:   Pekka Klärck
Date:     Tue Dec 20 14:41:34 2011
Log:      test cleanup
http://code.google.com/p/robotframework/source/detail?r=a21cebe1158e

Modified:
 /atest/robot/test_libraries/library_imports.txt

=======================================
--- /atest/robot/test_libraries/library_imports.txt     Wed Oct  5 22:12:27 2011
+++ /atest/robot/test_libraries/library_imports.txt     Tue Dec 20 14:41:34 2011
@@ -7,16 +7,16 @@
 *** Test Cases ***
 Normal Library Import
     Run Tests  ${EMPTY}  test_libraries/library_import_normal.txt
-    Check Test Case  Normal Library Import
+    Check Test Case  ${TESTNAME}

 Library Import With Spaces In Name
-    ${test} =  Check Test Case  Library Import With Spaces In Name
+    ${test} =  Check Test Case  ${TESTNAME}
     Check Log Message  ${test.kws[0].messages[0]}  It works!
     Check Log Message  ${test.kws[1].messages[0]}  It really workz!!

 Number Of Keywords In Imported Library Is Reported In Syslog
- ${testlibs path} = Join Path ${CURDIR}/../../ testresources/testlibs/
-    ${ex lib module} =  Join Path  ${testlibs path}  ExampleLibrary
+ ${testlibs path} = Normalize Path ${CURDIR}/../../testresources/testlibs/
+    ${ex lib module} =  Normalize Path  ${testlibs path}/ExampleLibrary
Check Syslog Contains | INFO \ | Imported library 'ExampleLibrary' with arguments [ ] (version <unknown>, class type, testcase scope, 28 keywords, source ${ex lib module}
     ${lib class module} =  Join Path  ${testlibs path}  libmodule
Check Syslog Contains | INFO \ | Imported library 'libmodule.LibClass1' with arguments [ ] (version <unknown>, class type, testcase scope, 1 keywords, source ${lib class module}
@@ -27,7 +27,7 @@
Check Syslog Contains | WARN \ | Imported library 'libmodule' contains no keywords

 Importing Python Class From Module
-    Check Test Case  Importing Python Class From Module
+    Check Test Case  ${TESTNAME}

 Namespace is initialized during library init
     Check Test Case   ${TEST NAME}

==============================================================================
Revision: 80961a182cb5
Author:   Pekka Klärck
Date:     Tue Dec 20 14:50:03 2011
Log: Fixed execution context dependent BuiltIn keywords/methods by importing libraries/resources/variables only after correct execution context is set.
http://code.google.com/p/robotframework/source/detail?r=80961a182cb5

Modified:
 /src/robot/running/model.py
 /src/robot/running/namespace.py

=======================================
--- /src/robot/running/model.py Tue Dec 20 13:45:05 2011
+++ /src/robot/running/model.py Tue Dec 20 14:50:03 2011
@@ -123,8 +123,10 @@
         self.status = 'RUNNING'
         self.starttime = utils.get_timestamp()
         parent_vars = parent.context.get_current_vars() if parent else None
-        ns = Namespace(self, parent_vars, skip_imports=errors.exit)
+        ns = Namespace(self, parent_vars)
self.context = EXECUTION_CONTEXTS.start_suite(ns, output, self._run_mode_dry_run)
+        if not errors.exit:
+            ns.handle_imports()
         self._set_variable_dependent_metadata(self.context)
         output.start_suite(self)
         return self.context
=======================================
--- /src/robot/running/namespace.py     Tue Dec 20 13:45:05 2011
+++ /src/robot/running/namespace.py     Tue Dec 20 14:50:03 2011
@@ -41,7 +41,7 @@
     A new instance of this class is created for each test suite.
     """

-    def __init__(self, suite, parent_vars, skip_imports=False):
+    def __init__(self, suite, parent_vars):
         if suite is not None:
LOGGER.info("Initializing namespace for test suite '%s'" % suite.longname)
         self.variables = self._create_variables(suite, parent_vars)
@@ -52,9 +52,11 @@
         self._testlibs = {}
         self._imported_resource_files = ImportCache()
         self._imported_variable_files = ImportCache()
+
+    def handle_imports(self):
         self._import_default_libraries()
-        if suite.source and not skip_imports:
-            self._handle_imports(suite.imports)
+        if self.suite.source:
+            self._handle_imports(self.suite.imports)

     def _create_variables(self, suite, parent_vars):
         variables = _VariableScopes(suite, parent_vars)

Reply via email to