def debug(msg, html=True, timestamp=None, level=0): currentThread = threading.currentThread() if currentThread.getName() in LOGGING_THREADS: if level <= debugLogLevel: logMsg = Message(msg, 'DEBUG', html, timestamp=timestamp) LOGGER.log_message(logMsg) else: if level <= debugLogLevel: logMsg = Message(msg, 'DEBUG', html, timestamp=timestamp) if currentThread in threadDict: threadDict[currentThread]['msgList'].append(logMsg) else: threadDict[currentThread]['msgList'] = [] threadDict[currentThread]['msgList'].append(logMsg)
def _handle_lib_import(self, func, args, kwargs): libs = [] errors = [] lib_cached = self._get_lib_from_cache(args[0], args[1]) if lib_cached: libs.append(lib_cached.lib) errors = lib_cached.errors else: try: def to_call(): try: libs.append(func(*args, **kwargs)) except: errors.append(sys.exc_info()) t = threading.Thread(target=to_call) t.setDaemon(True) t.start() t.join(timeout=self.lib_import_timeout) except: errors.append(sys.exc_info()) if len(libs) > 0: library = libs[0] else: try: library = TestLibrary(args[0], args[1], args[2], create_handlers=False) except: try: library = _BaseTestLibrary(libcode=None, name=args[0], args=args[1], source=None, variables=args[2]) except: try: library = _BaseTestLibrary(libcode=None, name=args[0], args=[], source=None, variables=args[3]) except: errors.append(sys.exc_info()) if lib_cached is None: self.cached_lib_items.append( LibItem(args[0], args[1], library, errors)) for e in errors: msg = '{LIB_ERROR: ' + args[0] + ', value: VALUE_START(' + str( e) + ')VALUE_END, lib_file_import:' + str(library.source) + '}' LOGGER.message(Message(message=msg, level='FAIL')) self._handle_keywords(library) return library
def info(msg, html=False, also_console=True, timestamp=None): currentThread = threading.currentThread() if currentThread.getName() in LOGGING_THREADS: logMsg = Message(msg, 'INFO', html, timestamp=timestamp) LOGGER.log_message(logMsg) if also_console: sys.__stdout__.write('\n %s' % (msg)) else: if also_console: sys.__stdout__.write("\n%s" % (msg)) logMsg = Message(msg, 'INFO', html, timestamp=timestamp) if currentThread in threadDict: threadDict[currentThread]['msgList'].append(logMsg) else: threadDict[currentThread]['msgList'] = [] threadDict[currentThread]['msgList'].append(logMsg)
def details(msg, html=True, also_console=True, timestamp=None): current_thread = threading.currentThread() if current_thread.getName() in LOGGING_THREADS: log_msg = Message(msg, 'INFO', html, timestamp=timestamp) LOGGER.log_message(log_msg) if also_console: sys.__stdout__.write('\n\x1b[5;36mINFO : %s\x1b[0m' % msg) else: if also_console: sys.__stdout__.write("\n%s" % msg) log_msg = Message(msg, 'INFO', html, timestamp=timestamp) if current_thread in threadDict: threadDict[current_thread]['msg_list'].append(log_msg) else: threadDict[current_thread]['msg_list'] = [] threadDict[current_thread]['msg_list'].append(log_msg)
def write(msg, level, html=False): """Writes the message to the log file using the given level. Valid log levels are `TRACE`, `DEBUG`, `INFO` and `WARN`. Instead of using this method, it is generally better to use the level specific methods such as `info` and `debug`. """ if threading.currentThread().getName() in LOGGING_THREADS: LOGGER.log_message(Message(msg, level, html))
def _handle_lib_import(self, func, args, kwargs): libs = [] errors = [] lib_cached = self._get_lib_from_cache(args[0], args[1]) if lib_cached: libs.append(lib_cached.lib) errors = lib_cached.errors else: try: # this is required to not get blocked thread in code using gevent; if it's not supported # the sleep function is just void if self.support_gevent: from gevent import monkey, sleep monkey.patch_all() else: sleep = lambda : None def to_call(): try: libs.append(func(*args, **kwargs)) sleep() except: errors.append(sys.exc_info()) t = threading.Thread(target=to_call) t.setDaemon(True) t.start() t.join(timeout=self.lib_import_timeout) except: errors.append(sys.exc_info()) if len(libs) > 0: library = libs[0] else: try: library = self._create_test_library(args[0], args[1], args[2]) except: try: library = self._create_base_test_library(args[0], args[1], args[2]) except: try: library = self._create_base_test_library(args[0], [], args[3]) except: errors.append(sys.exc_info()) for e in errors: msg = json.dumps({'import_error': {'name': args[0], 'error': str(e)}}) LOGGER.message(Message(message=msg, level='NONE')) try: if lib_cached is None: self.cached_lib_items.append(LibItem(args[0], args[1], library, errors)) if self.handle_keywords: self._handle_keywords(library) return library except: return None
def fail(msg, html=True, also_console=True, timestamp=None): font_tag = '<font color=\"red\"><b> FAIL: ' font_end_tag = '</b></font>' failmsg = "%s %s %s" % (font_tag, msg, font_end_tag) current_thread = threading.currentThread() sys.__stdout__.write('\n\x1b[38;5;1mFAIL: %s\x1b[0m' % msg) if current_thread.getName() in LOGGING_THREADS: log_msg = Message(failmsg, 'FAIL', html, timestamp=timestamp) LOGGER.log_message(log_msg) if also_console: sys.__stdout__.write('\n %s' % msg) else: if also_console: sys.__stdout__.write("\n%s" % msg) log_msg = Message(msg, 'FAIL', html, timestamp=timestamp) if current_thread in threadDict: threadDict[current_thread]['msg_list'].append(log_msg) else: threadDict[current_thread]['msg_list'] = [] threadDict[current_thread]['msg_list'].append(log_msg)
def _handle_keywords(self, library): if library is not None and hasattr(library, 'handlers'): for keyword in library.handlers: if keyword not in self.cached_kw_items and not isinstance(keyword, _JavaHandler): try: keyword_source = PythonKeywordSource(keyword) msg = json.dumps({'keyword_source': dict(keyword_source.__dict__)}) LOGGER.message(Message(message=msg, level='NONE')) except: pass # TODO: add logging finally: self.cached_kw_items.add(keyword)
def _custom_and_standard_keyword_conflict_warning(self, custom, standard): custom_with_name = standard_with_name = '' if custom.library.name != custom.library.orig_name: custom_with_name = f" imported as '{custom.library.name}'" if standard.library.name != standard.library.orig_name: standard_with_name = f" imported as '{standard.library.name}'" message = ( f"Keyword '{standard.name}' found both from a custom library " f"'{custom.library.orig_name}'{custom_with_name} and a standard library " f"'{standard.library.orig_name}'{standard_with_name}. The custom keyword " f"is used. To select explicitly, and to get rid of this warning, use " f"either '{custom.longname}' or '{standard.longname}'.") custom.pre_run_messages += Message(message, level='WARN'),
def _wrap(self, func, argser, kwargs): if type(func) == MethodType: if func.__name__ == 'import_library': # print str(argser) q = [] errors = [] lib_cached = self.get_from_cache(argser[0], argser[1]) if lib_cached: q.append(lib_cached.result) errors = lib_cached.errors else: try: t = threading.Thread(target=self._imp, args=(func, q, errors, argser), kwargs=kwargs) t.setDaemon(True) t.start() t.join(timeout=int(self.lib_import_timeout)) except: errors.append(sys.exc_info()) if len(q) > 0: result = q[0] else: try: result = TestLibrary(argser[0], argser[1], argser[2], create_handlers=False) except: try: result = _BaseTestLibrary(libcode=None, name=argser[0], args=argser[1], source=None, variables=argser[2]) except: try: result = _BaseTestLibrary(libcode=None, name=argser[0], args=[], source=None, variables=argser[3]) except: errors.append(sys.exc_info()) if lib_cached is None: lib = LibItem(argser[0], argser[1]) lib.result = result lib.errors = errors self.cached_lib_items.append(lib) for p in errors: msg = Message(message='{LIB_ERROR: ' + argser[0] + ', value: VALUE_START(' + str( p) + ')VALUE_END, lib_file_import:' + str(result.source) + '}', level='FAIL') LOGGER.message(msg) else: result = func(*argser, **kwargs) else: result = func(self.obj, *argser, **kwargs) return result
def _handle_lib_import(self, func, args, kwargs): libs = [] errors = [] lib_cached = self._get_lib_from_cache(args[0], args[1]) if lib_cached: libs.append(lib_cached.lib) errors = lib_cached.errors else: try: def to_call(): try: libs.append(func(*args, **kwargs)) except: errors.append(sys.exc_info()) t = threading.Thread(target=to_call) t.setDaemon(True) t.start() t.join(timeout=self.lib_import_timeout) except: errors.append(sys.exc_info()) if len(libs) > 0: library = libs[0] else: try: library = TestLibrary(args[0], args[1], args[2], create_handlers=False) except: try: library = _BaseTestLibrary(libcode=None, name=args[0], args=args[1], source=None, variables=args[2]) except: try: library = _BaseTestLibrary(libcode=None, name=args[0], args=[], source=None, variables=args[3]) except: errors.append(sys.exc_info()) if lib_cached is None: self.cached_lib_items.append(LibItem(args[0], args[1], library, errors)) for e in errors: msg = json.dumps({'import_error': {'name': args[0], 'error': str(e)}}) LOGGER.message(Message(message=msg, level='NONE')) if self.handle_keywords: self._handle_keywords(library) return library
def _custom_and_standard_keyword_conflict_warning(self, custom, standard): custom_with_name = standard_with_name = '' if custom.library.name != custom.library.orig_name: custom_with_name = " imported as '%s'" % custom.library.name if standard.library.name != standard.library.orig_name: standard_with_name = " imported as '%s'" % standard.library.name warning = Message("Keyword '%s' found both from a custom test library " "'%s'%s and a standard library '%s'%s. The custom " "keyword is used. To select explicitly, and to get " "rid of this warning, use either '%s' or '%s'." % (standard.name, custom.library.orig_name, custom_with_name, standard.library.orig_name, standard_with_name, custom.longname, standard.longname), level='WARN') if custom.pre_run_messages: custom.pre_run_messages.append(warning) else: custom.pre_run_messages = [warning]
def _get_runner_from_test_case_file(self, name): if name not in self.user_keywords.handlers: return None runner = self.user_keywords.handlers.create_runner(name) ctx = EXECUTION_CONTEXTS.current caller = ctx.user_keywords[-1] if ctx.user_keywords else ctx.test if caller and runner.source != caller.source: local_runner = self._get_runner_from_resource_file( name, caller.source) if local_runner: message = ( f"Keyword '{caller.longname}' called keyword '{name}' that " f"exist both in the same resource file and in the test case " f"file using that resource. The keyword in the test case file " f"is used now, but this will change in Robot Framework 6.0." ) runner.pre_run_messages += Message(message, level='WARN'), return runner
def visit_suite(self, suite): if suite.parent: suite.parent.tests.clear() suite.parent.keywords.clear() else: # when first suite is visited all suites are counted and message is send to server msg = json.dumps({'suite_count': self.__count_suites(suite)}) LOGGER.message(Message(message=msg, level='NONE')) if len(suite.tests) == 0 or suite.test_count == 0: current_suite = RedTestSuiteBuilder().build(suite.source) if len(self.f_suites) == 0: suite.suites = current_suite.suites else: suite.suites = self.__filter_by_name(current_suite.suites) suite.tests.clear() suite.keywords.clear() suite.suites.visit(self)