2 new revisions:
Revision: 970e12328222
Branch: default
Author: Jussi Malinen <jussi.ao.mali...@gmail.com>
Date: Mon Jun 9 12:54:36 2014 UTC
Log: Update issue 811...
http://code.google.com/p/robotframework/source/detail?r=970e12328222
Revision: 13e23fb235f7
Branch: default
Author: Jussi Malinen <jussi.ao.mali...@gmail.com>
Date: Mon Jun 9 12:54:44 2014 UTC
Log: Automated merge with https://code.google.com/p/robotframework/
http://code.google.com/p/robotframework/source/detail?r=13e23fb235f7
==============================================================================
Revision: 970e12328222
Branch: default
Author: Jussi Malinen <jussi.ao.mali...@gmail.com>
Date: Mon Jun 9 12:54:36 2014 UTC
Log: Update issue 811
Now calling close method from library listener when ending the scope for
that library.
http://code.google.com/p/robotframework/source/detail?r=970e12328222
Modified:
/atest/robot/test_libraries/as_listener.txt
/atest/robot/test_libraries/as_listener_in_java.txt
/atest/testdata/test_libraries/as_listener/listenerlibrary.py
/atest/testresources/testlibs/JavaListenerLibrary.class
/atest/testresources/testlibs/JavaListenerLibrary.java
/src/robot/output/librarylisteners.py
/src/robot/output/listeners.py
/src/robot/running/namespace.py
=======================================
--- /atest/robot/test_libraries/as_listener.txt Wed May 28 12:28:07 2014 UTC
+++ /atest/robot/test_libraries/as_listener.txt Mon Jun 9 12:54:36 2014 UTC
@@ -1,5 +1,8 @@
*** Settings ***
-Suite Setup Run Tests ${EMPTY}
test_libraries/as_listener/suite_scope.txt
test_libraries/as_listener/test_scope.txt
+Suite Setup Run Tests ${EMPTY}
+... test_libraries/as_listener/suite_scope.txt
+... test_libraries/as_listener/test_scope.txt
+... test_libraries/as_listener/global_scope.txt
Force Tags regression jybot pybot
Resource atest_resource.txt
@@ -16,3 +19,14 @@
Check Test Case ${TESTNAME}
Listener methods starting with underscore are not keywords
Check Test Case ${TESTNAME}
+Global scope library gets events
+ Check Test Case ${TESTNAME}
+New test gets previous global scope events
+ Check Test Case ${TESTNAME}
+Check closing
+ Stderr Should Match
+ ... SEPARATOR=\n
+ ... *CLOSING TEST SUITE
+ ... CLOSING TEST CASE
+ ... CLOSING TEST CASE
+ ... CLOSING GLOBAL
=======================================
--- /atest/robot/test_libraries/as_listener_in_java.txt Wed May 28 12:28:07
2014 UTC
+++ /atest/robot/test_libraries/as_listener_in_java.txt Mon Jun 9 12:54:36
2014 UTC
@@ -12,3 +12,5 @@
Check Test Case ${TESTNAME}
Listener methods starting with underscore are not keywords
Check Test Case ${TESTNAME}
+Check closing
+ Stderr Should Match *CLOSING IN JAVA SUITE LIBRARY LISTENER\n
=======================================
--- /atest/testdata/test_libraries/as_listener/listenerlibrary.py Wed May
28 12:28:07 2014 UTC
+++ /atest/testdata/test_libraries/as_listener/listenerlibrary.py Mon Jun
9 12:54:36 2014 UTC
@@ -1,3 +1,5 @@
+import sys
+
class listenerlibrary(object):
ROBOT_LISTENER_API_VERSION = 2
@@ -25,6 +27,10 @@
def _end_keyword(self, name, attrs):
self.events.append('end kw %s' % name)
+ def _close(self):
+ self.events.append('close %s' % self.ROBOT_LIBRARY_SCOPE)
+ sys.__stderr__.write("CLOSING %s\n" % self.ROBOT_LIBRARY_SCOPE)
+
def events_should_be(self, *expected):
assert self._format(self.events) ==
self._format(expected), 'Expected events\n %s\n actual\n %s' %
(self._format(expected), self._format(self.events))
=======================================
--- /atest/testresources/testlibs/JavaListenerLibrary.class Wed May 28
11:31:17 2014 UTC
+++ /atest/testresources/testlibs/JavaListenerLibrary.class Mon Jun 9
12:54:36 2014 UTC
@@ -13,6 +13,8 @@
V W
V
X Y Z [ ROBOT_LISTENER_API_VERSION Ljava/lang/String;
+
+ a b c d ROBOT_LISTENER_API_VERSION Ljava/lang/String;
ConstantValue \ ROBOT_LIBRARY_SCOPE ] events Ljava/util/ArrayList;
Signature )Ljava/util/ArrayList<Ljava/lang/String;>; ROBOT_LIBRARY_LISTENER LJavaListenerLibrary; <init> ()V Code LineNumberTable
startSuite $(Ljava/lang/String;Ljava/util/Map;)V endSuite
startTest endTest
_startKeyword
@@ -31,6 +33,8 @@
f g java/lang/RuntimeException -Expected events not the same size.
Expected:
^ h
+
+ g w
Actual:
- i
@@ -40,6 +44,7 @@
TEST
SUITE append -(Ljava/lang/String;)Ljava/lang/StringBuilder; toString ()Ljava/lang/String; add (Ljava/lang/Object;)Z clone ()Ljava/lang/Object; size ()I -(Ljava/lang/Object;)Ljava/lang/StringBuilder; (Ljava/lang/String;)V get (I)Ljava/lang/Object; equals !
! " # $ % " # & ' ( ) * + ,
- . / 9 *· *» Y· µ **µ ± 0
1 2 / 8
+ 4 5 2 8
*´ » Y· ¶ +¶ ¶
¶
W± 0
@@ -68,16 +73,20 @@
¶
W± 0
% & 8 9 / #
+ ) * < = 2 #
*´ ¶ À ° 0 ) ) : ; < / É ™*´ ¶ +¹ Ÿ *» Y» Y· ¶
+¶ ¶ *´ ¶ ¶
· ¿ =
+¿ =
+¹ ¢ X+
¹ À *´
+ À
+*´
¶
+¹
+ À
¶
-š :» Y» Y·
¶ +
-¹ À ¶ ¶ *´
¶
-À ¶ ¶
· ¿„ §ÿ¤± 0
+¿„ §ÿ¤± 3
- . 7 / C 0 [ 1 ’ / ˜ 4 ) = > ?
=======================================
--- /atest/testresources/testlibs/JavaListenerLibrary.java Wed May 28
11:31:17 2014 UTC
+++ /atest/testresources/testlibs/JavaListenerLibrary.java Mon Jun 9
12:54:36 2014 UTC
@@ -37,6 +37,11 @@
events.add("end kw "+name);
}
+ public void close() {
+ System.err.println("CLOSING IN JAVA SUITE LIBRARY LISTENER");
+ }
+
+ @SuppressWarnings("unchecked")
public List<String> getEvents() {
return (List<String>)events.clone();
}
=======================================
--- /src/robot/output/librarylisteners.py Wed May 28 12:28:07 2014 UTC
+++ /src/robot/output/librarylisteners.py Mon Jun 9 12:54:36 2014 UTC
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from .listeners import Listeners, _ListenerProxy
+from .listeners import Listeners, ListenerProxy
from .loggerhelper import AbstractLoggerProxy
@@ -21,28 +21,52 @@
def __init__(self):
self._running_test = False
self._setup_or_teardown_type = None
+ self._global_listeners = {}
def __nonzero__(self):
return True
+ def _notify_end_test(self, listener, test):
+ Listeners._notify_end_test(self, listener, test)
+ if listener.library_scope == 'TESTCASE':
+ listener.call_method(listener.close)
+
+ def _notify_end_suite(self, listener, suite):
+ Listeners._notify_end_suite(self, listener, suite)
+ if listener.library_scope == 'TESTSUITE':
+ listener.call_method(listener.close)
+
+ def end_suite(self, suite):
+ for listener in self._listeners:
+ self._notify_end_suite(listener, suite)
+ if not suite.parent:
+ for listener in self._global_listeners.values():
+ listener.call_method(listener.close)
+
@property
def _listeners(self):
from robot.running import EXECUTION_CONTEXTS
if not EXECUTION_CONTEXTS.current:
return []
- return [_LibraryListenerProxy(listener) for listener in
- EXECUTION_CONTEXTS.current.namespace.library_listeners]
+ listeners = [_LibraryListenerProxy(library) for library in
+ EXECUTION_CONTEXTS.current.namespace.libraries
+ if library.has_listener]
+ for listener in listeners:
+ if listener.library_scope == 'GLOBAL':
+ self._global_listeners[listener.logger] = listener
+ return listeners
-class _LibraryListenerProxy(_ListenerProxy):
+class _LibraryListenerProxy(ListenerProxy):
- def __init__(self, listener):
- AbstractLoggerProxy.__init__(self, listener)
- self.name = type(listener).__name__
- self.version = self._get_version(listener)
- self.is_java = self._is_java(listener)
+ def __init__(self, library):
+ AbstractLoggerProxy.__init__(self, library.listener)
+ self.name = type(library).__name__
+ self.version = self._get_version(library.listener)
+ self.is_java = self._is_java(library.listener)
+ self.library_scope = library.scope
def _get_method_names(self, name):
- names = _ListenerProxy._get_method_names(self, name)
+ names = ListenerProxy._get_method_names(self, name)
return names + ['_' + name for name in names]
=======================================
--- /src/robot/output/listeners.py Wed Jun 4 13:08:57 2014 UTC
+++ /src/robot/output/listeners.py Mon Jun 9 12:54:36 2014 UTC
@@ -69,7 +69,7 @@
listeners = []
for name, args in listener_data:
try:
- listeners.append(_ListenerProxy(name, args))
+ listeners.append(ListenerProxy(name, args))
except DataError, err:
if args:
name += ':' + ':'.join(args)
@@ -78,13 +78,13 @@
return listeners
def start_suite(self, suite):
- for li in self._listeners:
- if li.version == 1:
- li.call_method(li.start_suite, suite.name, suite.doc)
+ for listener in self._listeners:
+ if listener.version == 1:
+ listener.call_method(listener.start_suite, suite.name,
suite.doc)
else:
attrs = self._get_start_attrs(suite, 'metadata')
attrs.update(self._get_suite_attrs(suite))
- li.call_method(li.start_suite, suite.name, attrs)
+ listener.call_method(listener.start_suite, suite.name,
attrs)
def _get_suite_attrs(self, suite):
return {
@@ -95,56 +95,62 @@
}
def end_suite(self, suite):
- for li in self._listeners:
- if li.version == 1:
- li.call_method(li.end_suite, suite.status,
- suite.full_message)
- else:
- attrs = self._get_end_attrs(suite, 'metadata')
- attrs['statistics'] = suite.stat_message
- attrs.update(self._get_suite_attrs(suite))
- li.call_method(li.end_suite, suite.name, attrs)
+ for listener in self._listeners:
+ self._notify_end_suite(listener, suite)
+
+ def _notify_end_suite(self, listener, suite):
+ if listener.version == 1:
+ listener.call_method(listener.end_suite, suite.status,
+ suite.full_message)
+ else:
+ attrs = self._get_end_attrs(suite, 'metadata')
+ attrs['statistics'] = suite.stat_message
+ attrs.update(self._get_suite_attrs(suite))
+ listener.call_method(listener.end_suite, suite.name, attrs)
def start_test(self, test):
self._running_test = True
- for li in self._listeners:
- if li.version == 1:
- li.call_method(li.start_test, test.name, test.doc,
- list(test.tags))
+ for listener in self._listeners:
+ if listener.version == 1:
+ listener.call_method(listener.start_test, test.name,
test.doc,
+ list(test.tags))
else:
attrs = self._get_start_attrs(test, 'tags')
attrs['critical'] = 'yes' if test.critical else 'no'
attrs['template'] = test.template or ''
- li.call_method(li.start_test, test.name, attrs)
+ listener.call_method(listener.start_test, test.name, attrs)
def end_test(self, test):
self._running_test = False
- for li in self._listeners:
- if li.version == 1:
- li.call_method(li.end_test, test.status, test.message)
- else:
- attrs = self._get_end_attrs(test, 'tags')
- attrs['critical'] = 'yes' if test.critical else 'no'
- attrs['template'] = test.template or ''
- li.call_method(li.end_test, test.name, attrs)
+ for listener in self._listeners:
+ self._notify_end_test(listener, test)
+
+ def _notify_end_test(self, listener, test):
+ if listener.version == 1:
+ listener.call_method(listener.end_test, test.status,
test.message)
+ else:
+ attrs = self._get_end_attrs(test, 'tags')
+ attrs['critical'] = 'yes' if test.critical else 'no'
+ attrs['template'] = test.template or ''
+ listener.call_method(listener.end_test, test.name, attrs)
def start_keyword(self, kw):
- for li in self._listeners:
- if li.version == 1:
- li.call_method(li.start_keyword, kw.name, kw.args)
+ for listener in self._listeners:
+ if listener.version == 1:
+ listener.call_method(listener.start_keyword, kw.name,
kw.args)
else:
attrs = self._get_start_attrs(kw, *self._kw_extra_attrs)
attrs['type'] = self._get_keyword_type(kw, start=True)
- li.call_method(li.start_keyword, kw.name, attrs)
+ listener.call_method(listener.start_keyword, kw.name,
attrs)
def end_keyword(self, kw):
- for li in self._listeners:
- if li.version == 1:
- li.call_method(li.end_keyword, kw.status)
+ for listener in self._listeners:
+ if listener.version == 1:
+ listener.call_method(listener.end_keyword, kw.status)
else:
attrs = self._get_end_attrs(kw, *self._kw_extra_attrs)
attrs['type'] = self._get_keyword_type(kw, start=False)
- li.call_method(li.end_keyword, kw.name, attrs)
+ listener.call_method(listener.end_keyword, kw.name, attrs)
def _get_keyword_type(self, kw, start=True):
# When running setup or teardown, only the top level keyword has
type
@@ -161,26 +167,26 @@
kw.type.title())
def log_message(self, msg):
- for li in self._listeners:
- if li.version == 2:
- li.call_method(li.log_message, self._create_msg_dict(msg))
+ for listener in self._listeners:
+ if listener.version == 2:
+ listener.call_method(listener.log_message,
self._create_msg_dict(msg))
def message(self, msg):
- for li in self._listeners:
- if li.version == 2:
- li.call_method(li.message, self._create_msg_dict(msg))
+ for listener in self._listeners:
+ if listener.version == 2:
+ listener.call_method(listener.message,
self._create_msg_dict(msg))
def _create_msg_dict(self, msg):
return {'timestamp': msg.timestamp, 'message': msg.message,
'level': msg.level, 'html': 'yes' if msg.html else 'no'}
def output_file(self, name, path):
- for li in self._listeners:
- li.call_method(getattr(li, '%s_file' % name.lower()), path)
+ for listener in self._listeners:
+ listener.call_method(getattr(listener, '%s_file' %
name.lower()), path)
def close(self):
- for li in self._listeners:
- li.call_method(li.close)
+ for listener in self._listeners:
+ listener.call_method(listener.close)
def _get_start_attrs(self, item, *extra):
return self._get_attrs(item, self._start_attrs, extra)
@@ -213,7 +219,7 @@
return value
-class _ListenerProxy(AbstractLoggerProxy):
+class ListenerProxy(AbstractLoggerProxy):
_methods = ['start_suite', 'end_suite', 'start_test', 'end_test',
'start_keyword', 'end_keyword', 'log_message', 'message',
'output_file', 'report_file', 'log_file', 'debug_file',
@@ -256,3 +262,8 @@
for key, value in dictionary.iteritems():
map.put(key, value)
return map
+
+
+# TODO: Remove in 2.9, left here in 2.8.5 for backwards compatibility.
+# Consider also decoupling importing from __init__ to ease extending.
+_ListenerProxy = ListenerProxy
=======================================
--- /src/robot/running/namespace.py Wed May 28 12:53:02 2014 UTC
+++ /src/robot/running/namespace.py Mon Jun 9 12:54:36 2014 UTC
@@ -56,10 +56,8 @@
self._imported_variable_files = ImportCache()
@property
- def library_listeners(self):
- for lib in self._testlibs.itervalues():
- if lib.has_listener:
- yield lib.listener
+ def libraries(self):
+ return list(self._testlibs.itervalues())
def handle_imports(self):
self._import_default_libraries()
==============================================================================
Revision: 13e23fb235f7
Branch: default
Author: Jussi Malinen <jussi.ao.mali...@gmail.com>
Date: Mon Jun 9 12:54:44 2014 UTC
Log: Automated merge with https://code.google.com/p/robotframework/
http://code.google.com/p/robotframework/source/detail?r=13e23fb235f7
--
---
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/d/optout.