11 from future
import standard_library
12 standard_library.install_aliases()
13 from builtins
import str
14 from builtins
import object
39 _mlab_do_not_reload =
True
41 gCurrentSpecialMessage =
""
42 gSpecialMessageMarker =
"<MLAB TC=1/>"
43 gEnablePrettyLogging =
False
44 gLogInfoMessages =
True
47 global gCurrentSpecialMessage
48 msg = gCurrentSpecialMessage
49 gCurrentSpecialMessage =
""
52 def emitSpecialMessage(loggingMethod, file, line, type, message, escapeHtml=True, formattedStack=''):
53 global gCurrentSpecialMessage
55 escapedMsg = mevis.MLAB.escapeString(message)
56 escapedMsg = escapedMsg.replace(
"\n",
"<br>")
60 if sys.version_info.major >= 3:
61 if isinstance(formattedStack, str):
62 formattedStack = formattedStack.encode()
64 encodedStackTrace = str(base64.b64encode(formattedStack))
66 specialMessage =
"##M[%s|%s|%s|%s]: %s" % (file, line, type, encodedStackTrace, escapedMsg)
67 if gEnablePrettyLogging:
68 gCurrentSpecialMessage = specialMessage
69 escapedMsg =
"<font style='font-weight:normal'><font color=black>" + mevis.MLAB.createHyperLinkWithLine(file, line) +
"(" + str(line) +
"):</font></font> " + escapedMsg
70 escapedMsg += gSpecialMessageMarker
71 loggingMethod(escapedMsg)
73 loggingMethod(specialMessage)
76 global gCurrentSpecialMessage
78 escapedMsg = mevis.MLAB.escapeString(message)
83 specialMessage =
"##C[%s|%s|%s:%s] %s" % (file, line, type,
",".join(fileList), str(escapedMsg))
84 if gEnablePrettyLogging:
85 gCurrentSpecialMessage = specialMessage
86 escapedMsg =
"<font style='font-weight:normal'><font color=black>" + mevis.MLAB.createHyperLinkWithLine(file, line) +
"(" + str(line) +
"):</font></font> " + escapedMsg
87 for fileInList
in fileList:
89 fileInList = fileInList[fileInList.index(
"|")+1:]
90 escapedMsg +=
" " + mevis.MLAB.createHyperLink(fileInList)
91 escapedMsg += gSpecialMessageMarker
92 mevis.MLAB.logHTML(escapedMsg)
94 mevis.MLAB.logHTML(specialMessage)
98 """ This decorator is used to specify the stack frame that is used to detect the location while logging.
99 It uses the stack frame that calls the given function. Functions with this decorator can call each other
100 recursively. The first stack frame of such a recursion is then used. """
101 def setLoggingCallerStackFrameWrapper(*args, **kwargs):
103 return func(*args, **kwargs)
104 return setLoggingCallerStackFrameWrapper
107 IncreaseLoggingStackDepthDecorator = UseStackFrameFromCallerForLogging
112 self.
__testHelper__testHelper = TestHelper.getInstance()
117 if not self.
__testHelper__testHelper.hasCallerStackFrame():
119 self.
__testHelper__testHelper.setCallerStackFrame(stackFrame)
127 return sys._getframe(stackDepth+1)
143 def __init__(self, errorRegExp, logErrorFunc, preventReplacingMessageSeverity=False):
146 handling = MessageHandling.EXPECT
if logErrorFunc
is not None else MessageHandling.IGNORE
152 def __enableErrorHandling( self, enable ):
153 logHandler = TestHelper.getInstance().getLogHandler()
154 logHandler.pushOrPopMessageFilter(enable, self.
__messageFilter__messageFilter)
164 mevis.MLAB.priv().flushPendingMessages()
169 return hasCaughtError
173 """Helper object to supress warnings.
174 Make sure that you call handleResult() in a finally: clause.
175 If no logErrorFunc it given, matching warnings will just be ignored, not expected,
176 so no error will be logged if no match was found.
178 def __init__(self, warningRegExp, logErrorFunc=None, expectWarning=True):
180 handling = MessageHandling.EXPECT
if logErrorFunc
is not None else MessageHandling.IGNORE
186 def __enableWarningHandling( self, enable ):
187 TestHelper.getInstance().getLogHandler().pushOrPopMessageFilter(enable, self.
__messageFilter__messageFilter)
190 mevis.MLAB.priv().flushPendingMessages()
205 def __init__(self, infoRegExp, allowUnexpectedMessages, logErrorFunc):
212 def __enableInfoHandling( self, enable ):
213 TestHelper.getInstance().getLogHandler().pushOrPopMessageFilter(enable, self.
__messageFilter__messageFilter)
216 mevis.MLAB.priv().flushPendingMessages()
220 if hadUnexpectedInfo:
222 self.
__logErrorFunc__logErrorFunc(
"Unexpected info message occurred")
223 if not hadExpectedInfo:
232 ChangeSet.__init__(self, context)
236 def _logDecorator (func):
237 def wrapper (*args, **kwds):
239 loggingMethod, message = func(*args, **kwds)
240 if gLogInfoMessages
or (loggingMethod != mevis.MLAB.logHTML):
241 stackFrame = TestHelper.getInstance().getCallerStackFrame()
242 stackLine = traceback.extract_stack(stackFrame, 1)[0]
243 emitSpecialMessage(loggingMethod, stackLine[0], stackLine[1],
"ChangeSet", message, escapeHtml=
True)
249 def _logInfo (self, message):
250 return mevis.MLAB.logHTML, message
255 def _logError (self, message):
256 return mevis.MLAB.logErrorHTML, message
276 _mTestCaseContext =
None
278 _mHelperModule =
None
280 _mResultDirectory =
None
285 _mTestCaseName =
None
290 _mTestCaseDataDirectory =
None
292 _mTestCaseResultDirectory =
None
295 _mChangeSetStack =
None
304 _mEnvironmentStack =
None
307 _mExtraTestCaseResults =
None
310 _mMacrosLogOnSuccess =
True
313 __lockObj = _thread.allocate_lock()
336 '''Static method to have a reference to **THE UNIQUE** instance'''
337 if len(kargs)
not in (0, 2):
338 raise Exception(
"Singleton's getInstance must be called with context and result directory arguments or without any!")
340 initialize = (len(kargs) == 2)
346 if not "context" in kargs
or not "resultDir" in kargs:
347 raise Exception(
"Singleton must be initialized with context and result directory!")
349 self.
__instance__instance = object.__new__(self)
352 '''Initialize object **here**, as you would do in __init__()...'''
354 self.
_mCtx_mCtx = kargs[
"context"]
359 self.
_mHelperModule_mHelperModule = self.
_mCtx_mCtx.addModule(mevis.MLAB.moduleLiteral(
"TestCenterHelperModule"))
392 return self.
_mCtx_mCtx
462 if functionName !=
None:
499 changeSet.enableAutoRevert(
False)
569 os.environ = dict(os.environ)
Class to handle field changes and make them revertable.
def __init__(self, infoRegExp, allowUnexpectedMessages, logErrorFunc)
def __enableInfoHandling(self, enable)
__allowUnexpectedMessages
def getCallingStackFrame(self, stackDepth)
def __init__(self, stackDepth)
__preventReplacingMessageSeverity
def __init__(self, errorRegExp, logErrorFunc, preventReplacingMessageSeverity=False)
__previousKeepMessageSeverity
def __enableErrorHandling(self, enable)
def __init__(self, warningRegExp, logErrorFunc=None, expectWarning=True)
def __enableWarningHandling(self, enable)
def __init__(self, context)
The default constructor.
def getTestCaseContext(self)
Get the context of the test.
def addExtraTestCaseResult(self, extraTestCaseResult)
def setLogHandler(self, logHandler)
Set the current log handler.
def unsetLogHandler(self)
Unset the current log handler.
def getMacrosLogOnSuccess(self)
def getPackageList(self)
Return the list of available packages.
def getChangeSetStackLength(self)
Get the length of the ChangeSet stack.
def getChangeSet(self)
Return the ChangeSet on top of the stack.
def setModuleName(self, moduleName)
def setPackageList(self, packageList)
Set the list of available packages.
def takeExtraTestCaseResults(self)
def setTestCaseName(self, testCaseName)
def getGlobalContext(self)
def getCallerStackFrame(self)
def getLogHandler(self)
Get the current log handler.
bool _mMacrosLogOnSuccess
def clearChangeSet(self)
Clear the change set stakc without restoring the field values.
def setCallerStackFrame(self, stackFrame)
def hasInstance(self)
Check if an instance has been initialized.
def hasCallerStackFrame(self)
def __new__(self, *args, **kargs)
The new method.
def setTestCaseContext(self, ctx)
Set the context of the test.
def getResultDirectory(self)
def getHelperContext(self)
def popEnvironment(self)
Pops an environment dictionary from the stack and makes it the current environment.
def pushChangeSet(self)
Push a new ChangeSet to the stack.
def resetCallerStackFrame(self)
def setMacrosLogOnSuccess(self, macrosLogOnSuccess)
def pushEnvironment(self)
Pushes the current environment to the stack.
def __init__(self, *args, **kargs)
The default constructor.
def getInstance(self, *args, **kargs)
The default constructor.
def setTestCaseDataDirectory(self, testCaseDataPath)
def getTestCaseDataDirectory(self)
def getTestCaseName(self)
def popChangeSet(self)
Pop a ChangeSet from the stack and delete it.
_mTestCaseResultDirectory
def getTestCaseResultDirectory(self)
def setTestCaseResultDirectory(self, testCaseName, functionName)
A singleton to provide important data for the testing process.
def emitSpecialCommand(file, line, type, fileList, message, escapeHtml=True)
def UseStackFrameFromCallerForLogging(func)
def takeCurrentSpecialMessage()
def emitSpecialMessage(loggingMethod, file, line, type, message, escapeHtml=True, formattedStack='')