36_mlab_do_not_reload =
True
38gEnablePrettyLogging =
False
39gLogInfoMessages =
True
43 """Stores an additional message (usually the unformatted version) with a log message."""
45 specialMessageMarker = re.compile(
r".*<MLAB TC=(\d+)\/>")
46 currentSpecialMessageId = 0
50 def add(cls, message, specialMessage):
52 message += f
"<MLAB TC={cls.currentSpecialMessageId}/>"
57 def get(cls, message):
60 messageId = int(match.group(1))
62 if specialMessage
is not None:
68def emitSpecialMessage(loggingMethod, file, line, type, message, escapeHtml=True, formattedStack=""):
70 escapedMsg = mevis.MLAB.escapeString(message)
71 escapedMsg = escapedMsg.replace(
"\n",
"<br>")
75 if sys.version_info.major >= 3:
76 if isinstance(formattedStack, str):
77 formattedStack = formattedStack.encode()
79 encodedStackTrace = str(base64.b64encode(formattedStack))
81 specialMessage =
"##M[%s|%s|%s|%s]: %s" % (file, line, type, encodedStackTrace, escapedMsg)
82 if gEnablePrettyLogging:
84 "<font style='font-weight:normal'><font color=black>"
85 + mevis.MLAB.createHyperLinkWithLine(file, line)
91 loggingMethod(SpecialMessage.add(escapedMsg, specialMessage))
93 loggingMethod(specialMessage)
96def emitSpecialCommand(file, line, type, fileList, message, escapeHtml=True):
98 escapedMsg = mevis.MLAB.escapeString(message)
103 specialMessage =
"##C[%s|%s|%s:%s] %s" % (file, line, type,
",".join(fileList), str(escapedMsg))
104 if gEnablePrettyLogging:
106 "<font style='font-weight:normal'><font color=black>"
107 + mevis.MLAB.createHyperLinkWithLine(file, line)
110 +
"):</font></font> "
113 for fileInList
in fileList:
114 if "|" in fileInList:
115 fileInList = fileInList[fileInList.index(
"|") + 1 :]
116 escapedMsg +=
" " + mevis.MLAB.createHyperLink(fileInList)
117 escapedMsg = SpecialMessage.add(escapedMsg, specialMessage)
118 mevis.MLAB.logHTML(escapedMsg)
120 mevis.MLAB.logHTML(specialMessage)
123def UseStackFrameFromCallerForLogging(func):
124 """This decorator is used to specify the stack frame that is used to detect the location while logging.
125 It uses the stack frame that calls the given function. Functions with this decorator can call each other
126 recursively. The first stack frame of such a recursion is then used."""
128 def setLoggingCallerStackFrameWrapper(*args, **kwargs):
130 return func(*args, **kwargs)
132 return setLoggingCallerStackFrameWrapper
136IncreaseLoggingStackDepthDecorator = UseStackFrameFromCallerForLogging
157 return sys._getframe(stackDepth + 1)
173 def __init__(self, errorRegExp, logErrorFunc, preventReplacingMessageSeverity=False):
176 handling = MessageHandling.EXPECT
if logErrorFunc
is not None else MessageHandling.IGNORE
182 def __enableErrorHandling(self, enable):
183 logHandler = TestHelper.getInstance().getLogHandler()
194 mevis.MLAB.priv().flushPendingMessages()
199 return hasCaughtError
203 """Helper object to supress warnings.
204 Make sure that you call handleResult() in a finally: clause.
205 If no logErrorFunc it given, matching warnings will just be ignored, not expected,
206 so no error will be logged if no match was found.
209 def __init__(self, warningRegExp, logErrorFunc=None, expectWarning=True):
211 handling = MessageHandling.EXPECT
if logErrorFunc
is not None else MessageHandling.IGNORE
217 def __enableWarningHandling(self, enable):
218 TestHelper.getInstance().getLogHandler().pushOrPopMessageFilter(enable, self.
__messageFilter)
221 mevis.MLAB.priv().flushPendingMessages()
236 def __init__(self, infoRegExp, allowUnexpectedMessages, logErrorFunc):
243 def __enableInfoHandling(self, enable):
244 TestHelper.getInstance().getLogHandler().pushOrPopMessageFilter(enable, self.
__messageFilter)
247 mevis.MLAB.priv().flushPendingMessages()
251 if hadUnexpectedInfo:
254 if not hadExpectedInfo:
264 ChangeSet.__init__(self, context)
270 def wrapper(*args, **kwds):
272 loggingMethod, message = func(*args, **kwds)
273 if gLogInfoMessages
or (loggingMethod != mevis.MLAB.logHTML):
274 stackFrame = TestHelper.getInstance().getCallerStackFrame()
275 stackLine = traceback.extract_stack(stackFrame, 1)[0]
276 emitSpecialMessage(loggingMethod, stackLine[0], stackLine[1],
"ChangeSet", message, escapeHtml=
True)
285 return mevis.MLAB.logHTML, message
292 return mevis.MLAB.logErrorHTML, message
317 _mTestCaseContext =
None
319 _mHelperModule =
None
321 _mResultDirectory =
None
326 _mTestCaseName =
None
331 _mTestCaseDataDirectory =
None
333 _mTestCaseResultDirectory =
None
336 _mChangeSetStack =
None
339 _mSecureTesting =
False
346 _mStackFrameStack =
None
349 _mEnvironmentStack =
None
352 _mExtraTestCaseResults =
None
355 _mMacrosLogOnSuccess =
True
358 __lockObj = _thread.allocate_lock()
383 """Static method to have a reference to **THE UNIQUE** instance"""
384 if len(kargs)
not in (0, 2):
386 "Singleton's getInstance must be called with context and result directory arguments or without any!"
389 initialize = len(kargs) == 2
395 if not "context" in kargs
or not "resultDir" in kargs:
396 raise Exception(
"Singleton must be initialized with context and result directory!")
401 """Initialize object **here**, as you would do in __init__()..."""
403 self.
_mCtx = kargs[
"context"]
408 self.
_mHelperModule = self.
_mCtx.addModule(mevis.MLAB.moduleLiteral(
"TestCenterHelperModule"))
473 def getTestCaseContext(self):
485 def getResultDirectory(self):
529 if functionName !=
None:
570 changeSet.enableAutoRevert(
False)
669 os.environ = dict(os.environ)
Class to handle field changes and make them revertable.
Filter for error messages.
Filter for info messages.
Filter for warning messages.
__enableInfoHandling(self, enable)
__init__(self, infoRegExp, allowUnexpectedMessages, logErrorFunc)
__allowUnexpectedMessages
__init__(self, stackDepth, optional=False)
getCallingStackFrame(self, stackDepth)
Stores an additional message (usually the unformatted version) with a log message.
int currentSpecialMessageId
add(cls, message, specialMessage)
__preventReplacingMessageSeverity
__previousKeepMessageSeverity
__enableErrorHandling(self, enable)
__init__(self, errorRegExp, logErrorFunc, preventReplacingMessageSeverity=False)
Helper object to supress warnings.
__enableWarningHandling(self, enable)
__init__(self, warningRegExp, logErrorFunc=None, expectWarning=True)
__init__(self, context)
The default constructor.
pushChangeSet(self)
Push a new ChangeSet to the stack.
pushCallerStackFrame(self, stackFrame)
popEnvironment(self)
Pops an environment dictionary from the stack and makes it the current environment.
getLogHandler(self)
Get the current log handler.
getCallerStackFrame(self)
bool _mSecureTesting
Allow checking, whether tests are run in secure mode.
takeExtraTestCaseResults(self)
_mHelperModule
The context of the helper module.
_mTestCaseName
The name of the current test case.
setLogHandler(self, logHandler)
Set the current log handler.
setTestCaseName(self, testCaseName)
_mChangeSetStack
A stack of ChangeSets used to revert changes to field values.
_mExtraTestCaseResults
A list of extra test case results.
setMacrosLogOnSuccess(self, macrosLogOnSuccess)
bool _mMacrosLogOnSuccess
This is the default value for the 'logOnSuccess' parameter (if it is None) of the ASSERT_*/EXPECT_* m...
__new__(self, *args, **kargs)
The new method.
clearChangeSet(self)
Clear the change set stack without restoring the field values.
popChangeSet(self)
Pop a ChangeSet from the stack and delete it.
__init__(self, *args, **kargs)
The default constructor.
_mEnvironmentStack
A stack of environment dictionaries used to revert changes to the environment.
setModuleName(self, moduleName)
hasCallerStackFrame(self)
_mModuleName
The name of the currently tested module.
setTestCaseContext(self, ctx)
Set the context of the test.
getChangeSet(self)
Return the ChangeSet on top of the stack.
popCallerStackFrame(self)
_mTestCaseContext
The current test's context.
runTestInCurrentMlabInstance(self)
Set if tests are not run in secure mode.
_mStackFrameStack
The stack frame of the calling function that is used when logging events.
getChangeSetStackLength(self)
Get the length of the ChangeSet stack.
getTestCaseResultDirectory(self)
_mTestCaseDataDirectory
The path to the test case data.
setPackageList(self, packageList)
Set the list of available packages.
getMacrosLogOnSuccess(self)
addExtraTestCaseResult(self, extraTestCaseResult)
getTestCaseDataDirectory(self)
pushEnvironment(self)
Pushes the current environment to the stack.
testIsRunInSecureMode(self)
Check if tests are run in secure mode.
setTestCaseResultDirectory(self, testCaseName, functionName)
hasInstance(self)
Check if an instance has been initialized.
getPackageList(self)
Return the list of available packages.
unsetLogHandler(self)
Unset the current log handler.
setTestCaseDataDirectory(self, testCaseDataPath)
_mPackageList
The list of packages that should be assumed to be available.
getInstance(self, *args, **kargs)
The default constructor.
_mTestCaseResultDirectory
The path to the results.
_mLogHandler
The log handler that can be used to handle the reports.
runTestInSecureMode(self)
Set if tests are run in secure mode.
_mResultDirectory
The directory used to save results.
A singleton to provide important data for the testing process.