Robot Framework Integrated Development Environment (RIDE)
listeners.py
Go to the documentation of this file.
1 # Copyright 2008-2015 Nokia Networks
2 # Copyright 2016- Robot Framework Foundation
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 
16 import os.path
17 
18 from robotide.lib.robot.errors import DataError
19 from robotide.lib.robot.utils import (Importer, is_string, py2to3,
20  split_args_from_name_or_path, type_name)
21 
22 from .listenermethods import ListenerMethods, LibraryListenerMethods
23 from .loggerhelper import AbstractLoggerProxy, IsLogged
24 from .logger import LOGGER
25 
26 
27 @py2to3
28 class Listeners():
29 
32  _method_names = ('start_suite', 'end_suite', 'start_test', 'end_test',
33  'start_keyword', 'end_keyword', 'log_message', 'message',
34  'output_file', 'report_file', 'log_file', 'debug_file',
35  'xunit_file', 'library_import', 'resource_import',
36  'variables_import', 'close')
37 
38  def __init__(self, listeners, log_level='INFO'):
39  self._is_logged_is_logged = IsLogged(log_level)
40  listeners = ListenerProxy.import_listeners(listeners,
41  self._method_names_method_names)
42  for name in self._method_names_method_names:
43  method = ListenerMethods(name, listeners)
44  if name.endswith(('_file', '_import', 'log_message')):
45  name = '_' + name
46  setattr(self, name, method)
47 
48  def set_log_level(self, level):
49  self._is_logged_is_logged.set_level(level)
50 
51  def log_message(self, msg):
52  if self._is_logged_is_logged(msg.level):
53  self._log_message(msg)
54 
55  def imported(self, import_type, name, attrs):
56  method = getattr(self, '_%s_import' % import_type.lower())
57  method(name, attrs)
58 
59  def output_file(self, file_type, path):
60  method = getattr(self, '_%s_file' % file_type.lower())
61  method(path)
62 
63  def __nonzero__(self):
64  return any(isinstance(method, ListenerMethods) and method
65  for method in self.__dict__.values())
66 
67 
69 
72  _method_names = ('start_suite', 'end_suite', 'start_test', 'end_test',
73  'start_keyword', 'end_keyword', 'log_message', 'message',
74  'close')
75 
76  def __init__(self, log_level='INFO'):
77  self._is_logged_is_logged = IsLogged(log_level)
78  for name in self._method_names_method_names:
79  method = LibraryListenerMethods(name)
80  if name == 'log_message':
81  name = '_' + name
82  setattr(self, name, method)
83 
84  def register(self, listeners, library):
85  listeners = ListenerProxy.import_listeners(listeners,
86  self._method_names_method_names,
87  prefix='_',
88  raise_on_error=True)
89  for method in self._listener_methods_listener_methods():
90  method.register(listeners, library)
91 
92  def _listener_methods(self):
93  return [method for method in self.__dict__.values()
94  if isinstance(method, LibraryListenerMethods)]
95 
96  def unregister(self, library, close=False):
97  if close:
98  self.close(library=library)
99  for method in self._listener_methods_listener_methods():
100  method.unregister(library)
101 
102  def new_suite_scope(self):
103  for method in self._listener_methods_listener_methods():
104  method.new_suite_scope()
105 
107  for method in self._listener_methods_listener_methods():
108  method.discard_suite_scope()
109 
110  def set_log_level(self, level):
111  self._is_logged_is_logged.set_level(level)
112 
113  def log_message(self, msg):
114  if self._is_logged_is_logged(msg.level):
115  self._log_message(msg)
116 
117  def imported(self, import_type, name, attrs):
118  pass
119 
120  def output_file(self, file_type, path):
121  pass
122 
123 
124 class ListenerProxy(AbstractLoggerProxy):
125 
128  _no_method = None
129 
130  def __init__(self, listener, method_names, prefix=None):
131  listener, name = self._import_listener_import_listener(listener)
132  AbstractLoggerProxy.__init__(self, listener, method_names, prefix)
133  self.namename = name
134  self.versionversion = self._get_version_get_version(listener)
135  if self.versionversion == 3:
136  self.start_keywordstart_keyword = self.end_keywordend_keyword = None
137  self.library_importlibrary_import = self.resource_importresource_import = self.variables_importvariables_import = None
138 
139  def _import_listener(self, listener):
140  if not is_string(listener):
141  # Modules have `__name__`, with others better to use `type_name`.
142  name = getattr(listener, '__name__', None) or type_name(listener)
143  return listener, name
144  name, args = split_args_from_name_or_path(listener)
145  importer = Importer('listener')
146  listener = importer.import_class_or_module(os.path.normpath(name),
147  instantiate_with_args=args)
148  return listener, name
149 
150  def _get_version(self, listener):
151  try:
152  version = int(listener.ROBOT_LISTENER_API_VERSION)
153  if version not in (2, 3):
154  raise ValueError
155  except AttributeError:
156  raise DataError("Listener '%s' does not have mandatory "
157  "'ROBOT_LISTENER_API_VERSION' attribute."
158  % self.namename)
159  except (ValueError, TypeError):
160  raise DataError("Listener '%s' uses unsupported API version '%s'."
161  % (self.namename, listener.ROBOT_LISTENER_API_VERSION))
162  return version
163 
164  @classmethod
165  def import_listeners(cls, listeners, method_names, prefix=None,
166  raise_on_error=False):
167  imported = []
168  for listener in listeners:
169  try:
170  imported.append(cls(listener, method_names, prefix))
171  except DataError as err:
172  name = listener if is_string(listener) else type_name(listener)
173  msg = "Taking listener '%s' into use failed: %s" % (name, err)
174  if raise_on_error:
175  raise DataError(msg)
176  LOGGER.error(msg)
177  return imported
Used when variable does not exist.
Definition: errors.py:67
def imported(self, import_type, name, attrs)
Definition: listeners.py:117
def unregister(self, library, close=False)
Definition: listeners.py:96
def __init__(self, listener, method_names, prefix=None)
Definition: listeners.py:130
def import_listeners(cls, listeners, method_names, prefix=None, raise_on_error=False)
Definition: listeners.py:166
def __init__(self, listeners, log_level='INFO')
Definition: listeners.py:38
def imported(self, import_type, name, attrs)
Definition: listeners.py:55
def output_file(self, file_type, path)
Definition: listeners.py:59
def split_args_from_name_or_path(name)
Definition: text.py:132