def _formatListEntry(self, iEntry): from testmanager.webui.wuiadmin import WuiAdmin oEntry = self._aoEntries[iEntry] return [ oEntry.idFailureCategory, oEntry.sShort, oEntry.sFull, [ WuiTmLink( 'Details', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionFailureCategoryDetails, FailureCategoryData.ksParam_idFailureCategory: oEntry.idFailureCategory }), WuiTmLink( 'Modify', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionFailureCategoryEdit, FailureCategoryData.ksParam_idFailureCategory: oEntry.idFailureCategory }), WuiTmLink( 'Remove', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionFailureCategoryDoRemove, FailureCategoryData.ksParam_idFailureCategory: oEntry.idFailureCategory }, sConfirm= 'Do you really want to remove failure cateogry #%d?' % (oEntry.idFailureCategory, )), ] ]
def _formatListEntry(self, iEntry): from testmanager.webui.wuiadmin import WuiAdmin oEntry = self._aoEntries[iEntry] return [ oEntry.idGlobalRsrc, oEntry.sName, oEntry.sDescription, oEntry.fEnabled, [ WuiTmLink( 'Modify', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionGlobalRsrcShowEdit, GlobalResourceData.ksParam_idGlobalRsrc: oEntry.idGlobalRsrc }), WuiTmLink( 'Remove', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionGlobalRsrcDel, GlobalResourceData.ksParam_idGlobalRsrc: oEntry.idGlobalRsrc }, sConfirm= 'Are you sure you want to remove global resource #%d?' % (oEntry.idGlobalRsrc, )), ] ]
def _formatListEntry(self, iEntry): from testmanager.webui.wuiadmin import WuiAdmin oEntry = self._aoEntries[iEntry] oAction = None if self._oDisp is None or not self._oDisp.isReadOnlyUser(): if oEntry.sEvent == SystemLogData.ksEvent_TestBoxUnknown \ and oEntry.sLogText.find('addr=') >= 0 \ and oEntry.sLogText.find('uuid=') >= 0: sUuid = (oEntry.sLogText[(oEntry.sLogText.find('uuid=') + 5):])[:36] sAddr = (oEntry.sLogText[(oEntry.sLogText.find('addr=') + 5):]).split(' ')[0] oAction = WuiTmLink( 'Add TestBox', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionTestBoxAdd, TestBoxData.ksParam_uuidSystem: sUuid, TestBoxData.ksParam_ip: sAddr }) elif oEntry.sEvent == SystemLogData.ksEvent_UserAccountUnknown: sUserName = oEntry.sLogText[oEntry.sLogText.find('(') + 1:oEntry.sLogText.find(')')] oAction = WuiTmLink( 'Add User', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionUserAdd, UserAccountData.ksParam_sLoginName: sUserName }) return [oEntry.tsCreated, oEntry.sEvent, oEntry.sLogText, oAction]
def _formatListEntry(self, iEntry): from testmanager.webui.wuiadmin import WuiAdmin; oEntry = self._aoEntries[iEntry]; aoActions = [ WuiTmLink('Details', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionBuildCategoryDetails, BuildCategoryData.ksParam_idBuildCategory: oEntry.idBuildCategory, }), WuiTmLink('Clone', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionBuildCategoryClone, BuildCategoryData.ksParam_idBuildCategory: oEntry.idBuildCategory, }), WuiTmLink('Try Remove', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionBuildCategoryDoRemove, BuildCategoryData.ksParam_idBuildCategory: oEntry.idBuildCategory, }), ]; sHtml = '<ul class="tmshowall">\n'; for sOsArch in oEntry.asOsArches: sHtml += ' <li class="tmshowall">%s</li>\n' % (webutils.escapeElem(sOsArch),); sHtml += '</ul>\n' return [ oEntry.idBuildCategory, oEntry.sRepository, oEntry.sProduct, oEntry.sBranch, oEntry.sType, WuiRawHtml(sHtml), aoActions, ];
def _formatListEntry(self, iEntry): from testmanager.webui.wuiadmin import WuiAdmin from testmanager.webui.wuiadminfailurecategory import WuiFailureReasonCategoryLink; oEntry = self._aoEntries[iEntry] aoActions = [ WuiTmLink('Details', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionFailureReasonDetails, FailureReasonData.ksParam_idFailureReason: oEntry.idFailureReason } ), ]; if self._oDisp is None or not self._oDisp.isReadOnlyUser(): aoActions += [ WuiTmLink('Modify', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionFailureReasonEdit, FailureReasonData.ksParam_idFailureReason: oEntry.idFailureReason } ), WuiTmLink('Remove', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionFailureReasonDoRemove, FailureReasonData.ksParam_idFailureReason: oEntry.idFailureReason }, sConfirm = 'Are you sure you want to remove failure reason #%d?' % (oEntry.idFailureReason,)), ]; return [ oEntry.idFailureReason, WuiFailureReasonCategoryLink(oEntry.idFailureCategory, sName = oEntry.oCategory.sShort, fBracketed = False), oEntry.sShort, oEntry.sFull, oEntry.iTicket, oEntry.asUrls, aoActions, ]
def _formatListEntry(self, iEntry): from testmanager.webui.wuiadmin import WuiAdmin oEntry = self._aoEntries[iEntry] return [ oEntry.idFailureReason, oEntry.idFailureCategory, oEntry.sShort, oEntry.sFull, oEntry.iTicket, oEntry.asUrls, [ WuiTmLink( 'Modify', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionFailureReasonShowEdit, FailureReasonData.ksParam_idFailureReason: oEntry.idFailureReason }), WuiTmLink( 'Remove', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionFailureReasonDel, FailureReasonData.ksParam_idFailureReason: oEntry.idFailureReason }, sConfirm= 'Are you sure you want to remove failure reason #%d?' % (oEntry.idFailureReason, )), ] ]
def __init__(self, sSubject, aIdSubjects, sName=WuiContentBase.ksShortReportLink, tsNow=None, cPeriods=None, cHoursPerPeriod=None, fBracketed=False, dExtraParams=None): from testmanager.webui.wuimain import WuiMain dParams = { WuiMain.ksParamAction: WuiMain.ksActionReportSummary, WuiMain.ksParamReportSubject: sSubject, WuiMain.ksParamReportSubjectIds: aIdSubjects, } if dExtraParams is not None: dParams.update(dExtraParams) if tsNow is not None: dParams[WuiMain.ksParamEffectiveDate] = tsNow if cPeriods is not None: dParams[WuiMain.ksParamReportPeriods] = cPeriods if cPeriods is not None: dParams[WuiMain.ksParamReportPeriodInHours] = cHoursPerPeriod WuiTmLink.__init__(self, sName, WuiMain.ksScriptName, dParams, fBracketed=fBracketed)
def _formatListEntry(self, iEntry): from testmanager.webui.wuiadmin import WuiAdmin oEntry = self._aoEntries[iEntry] sShortFailReason = \ FailureReasonLogic(TMDatabaseConnection()).getById(oEntry.idFailureReason).sShort return [ oEntry.idBlacklisting, sShortFailReason, oEntry.sProduct, oEntry.sBranch, oEntry.asTypes, oEntry.asOsArches, oEntry.iFirstRevision, oEntry.iLastRevision, [ WuiTmLink('Details', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionBuildBlacklistDetails, BuildBlacklistData.ksParam_idBlacklisting: oEntry.idBlacklisting }), WuiTmLink('Edit', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionBuildBlacklistEdit, BuildBlacklistData.ksParam_idBlacklisting: oEntry.idBlacklisting }), WuiTmLink('Clone', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionBuildBlacklistClone, BuildBlacklistData.ksParam_idBlacklisting: oEntry.idBlacklisting, WuiAdmin.ksParamEffectiveDate: oEntry.tsEffective, }), WuiTmLink('Remove', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionBuildBlacklistDoRemove, BuildBlacklistData.ksParam_idBlacklisting: oEntry.idBlacklisting }, sConfirm = 'Are you sure you want to remove black list entry #%d?' % (oEntry.idBlacklisting,)), ] ];
def __init__(self, sName = WuiContentBase.ksShortAddLink, sTitle = None, fBracketed = None): if fBracketed is None: fBracketed = len(sName) > 2; from testmanager.webui.wuiadmin import WuiAdmin; WuiTmLink.__init__(self, sName = sName, sUrlBase = WuiAdmin.ksScriptName, dParams = { WuiAdmin.ksParamAction: WuiAdmin.ksActionFailureReasonAdd, }, fBracketed = fBracketed);
def __init__(self, idTestResult, sName = WuiContentBase.ksShortDetailsLink, sTitle = None, fBracketed = None): if fBracketed is None: fBracketed = len(sName) > 2; WuiTmLink.__init__(self, sName = sName, sUrlBase = WuiMain.ksScriptName, dParams = { WuiMain.ksParamAction: WuiMain.ksActionTestResultFailureDetails, TestResultFailureData.ksParam_idTestResult: idTestResult, }, fBracketed = fBracketed); self.idTestResult = idTestResult;
def __init__(self, idTestBox, sName = WuiContentBase.ksShortDetailsLink, fBracketed = False, tsNow = None): from testmanager.webui.wuiadmin import WuiAdmin; dParams = { WuiAdmin.ksParamAction: WuiAdmin.ksActionTestBoxDetails, TestBoxData.ksParam_idTestBox: idTestBox, }; if tsNow is not None: dParams[WuiAdmin.ksParamEffectiveDate] = tsNow; ## ?? WuiTmLink.__init__(self, sName, WuiAdmin.ksScriptName, dParams, fBracketed = fBracketed); self.idTestBox = idTestBox;
def __init__(self, idFailureCategory, sName = WuiContentBase.ksShortDetailsLink, sTitle = None, fBracketed = None): if fBracketed is None: fBracketed = len(sName) > 2; from testmanager.webui.wuiadmin import WuiAdmin; WuiTmLink.__init__(self, sName = sName, sUrlBase = WuiAdmin.ksScriptName, dParams = { WuiAdmin.ksParamAction: WuiAdmin.ksActionFailureCategoryDetails, FailureCategoryData.ksParam_idFailureCategory: idFailureCategory, }, fBracketed = fBracketed); self.idFailureCategory = idFailureCategory;
def _formatListEntry(self, iEntry): """ Format *show all* table entry """ from testmanager.webui.wuiadmin import WuiAdmin oEntry = self._aoEntries[iEntry] aoActions = [ WuiTmLink( 'Details', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionBuildSrcDetails, BuildSourceData.ksParam_idBuildSrc: oEntry.idBuildSrc, WuiAdmin.ksParamEffectiveDate: self._tsEffectiveDate, }), WuiTmLink( 'Clone', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionBuildSrcClone, BuildSourceData.ksParam_idBuildSrc: oEntry.idBuildSrc, WuiAdmin.ksParamEffectiveDate: self._tsEffectiveDate, }), ] if isDbTimestampInfinity(oEntry.tsExpire): aoActions += [ WuiTmLink( 'Modify', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionBuildSrcEdit, BuildSourceData.ksParam_idBuildSrc: oEntry.idBuildSrc }), WuiTmLink( 'Remove', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionBuildSrcDoRemove, BuildSourceData.ksParam_idBuildSrc: oEntry.idBuildSrc }, sConfirm='Are you sure you want to remove build source #%d?' % (oEntry.idBuildSrc, )) ] return [ oEntry.idBuildSrc, oEntry.sName, oEntry.sDescription, oEntry.sProduct, oEntry.sBranch, self._getSubList(oEntry.asTypes), self._getSubList(oEntry.asOsArches), oEntry.iFirstRevision, oEntry.iLastRevision, utils.formatIntervalSeconds2(oEntry.cSecMaxAge) if oEntry.cSecMaxAge is not None else None, aoActions, ]
def _formatListEntry(self, iEntry): from testmanager.webui.wuiadmin import WuiAdmin; oEntry = self._aoEntries[iEntry]; return [ oEntry.uid, oEntry.sUsername, oEntry.sEmail, oEntry.sFullName, oEntry.sLoginName, [ WuiTmLink('Modify', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionUserEdit, UserAccountData.ksParam_uid: oEntry.uid } ), WuiTmLink('Remove', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionUserDelPost, UserAccountData.ksParam_uid: oEntry.uid }, sConfirm = 'Are you sure you want to remove user #%d?' % (oEntry.uid,)), ] ];
def _formatListEntry(self, iEntry): from testmanager.webui.wuiadmin import WuiAdmin oEntry = self._aoEntries[iEntry]; aoActions = []; if oEntry.sLogUrl is not None: aoActions.append(WuiBuildLogLink(oEntry.sLogUrl, 'Build Log')); dParams = { WuiAdmin.ksParamAction: WuiAdmin.ksActionBuildBlacklistAdd, BuildBlacklistData.ksParam_sProduct: oEntry.oCat.sProduct, BuildBlacklistData.ksParam_sBranch: oEntry.oCat.sBranch, BuildBlacklistData.ksParam_asTypes: oEntry.oCat.sType, BuildBlacklistData.ksParam_asOsArches: oEntry.oCat.asOsArches, BuildBlacklistData.ksParam_iFirstRevision: oEntry.iRevision, BuildBlacklistData.ksParam_iLastRevision: oEntry.iRevision } if self._oDisp is None or not self._oDisp.isReadOnlyUser(): aoActions += [ WuiTmLink('Blacklist', WuiAdmin.ksScriptName, dParams), WuiTmLink('Details', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionBuildDetails, BuildData.ksParam_idBuild: oEntry.idBuild, WuiAdmin.ksParamEffectiveDate: self._tsEffectiveDate, }), WuiTmLink('Clone', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionBuildClone, BuildData.ksParam_idBuild: oEntry.idBuild, WuiAdmin.ksParamEffectiveDate: self._tsEffectiveDate, }), ]; if isDbTimestampInfinity(oEntry.tsExpire): aoActions += [ WuiTmLink('Modify', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionBuildEdit, BuildData.ksParam_idBuild: oEntry.idBuild }), WuiTmLink('Remove', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionBuildDoRemove, BuildData.ksParam_idBuild: oEntry.idBuild }, sConfirm = 'Are you sure you want to remove build #%d?' % (oEntry.idBuild,) ), ]; return [ oEntry.idBuild, oEntry.oCat.sProduct, oEntry.oCat.sBranch, WuiSvnLinkWithTooltip(oEntry.iRevision, oEntry.oCat.sRepository, sName = '%s r%s' % (oEntry.sVersion, oEntry.iRevision,)), oEntry.oCat.sType, ' '.join(oEntry.oCat.asOsArches), 'batch' if oEntry.uidAuthor is None else oEntry.uidAuthor, self.formatTsShort(oEntry.tsCreated), oEntry.sBinaries if not oEntry.fBinariesDeleted else '<Deleted>', aoActions, ];
def __init__(self, sSubject, aIdSubjects, sName = WuiContentBase.ksShortReportLink, tsNow = None, cPeriods = None, cHoursPerPeriod = None, fBracketed = False, dExtraParams = None): from testmanager.webui.wuimain import WuiMain; dParams = { WuiMain.ksParamAction: WuiMain.ksActionReportSummary, WuiMain.ksParamReportSubject: sSubject, WuiMain.ksParamReportSubjectIds: aIdSubjects, }; if dExtraParams is not None: dParams.update(dExtraParams); if tsNow is not None: dParams[WuiMain.ksParamEffectiveDate] = tsNow; if cPeriods is not None: dParams[WuiMain.ksParamReportPeriods] = cPeriods; if cPeriods is not None: dParams[WuiMain.ksParamReportPeriodInHours] = cHoursPerPeriod; WuiTmLink.__init__(self, sName, WuiMain.ksScriptName, dParams, fBracketed = fBracketed);
def _generateTopRowFormActions(self, oData): """ We add a way to get back to the test set to the actions. """ aoActions = super(WuiTestResultFailure, self)._generateTopRowFormActions(oData); if oData and oData.idTestResult is not None and oData.idTestResult > 0: aoActions.append(WuiTmLink('Associated Test Set', WuiMain.ksScriptName, { WuiMain.ksParamAction: WuiMain.ksActionTestSetDetailsFromResult, TestSetData.ksParam_idTestResult: oData.idTestResult } )); return aoActions;
def _formatListEntry(self, iEntry): from testmanager.webui.wuiadmin import WuiAdmin; oEntry = self._aoEntries[iEntry]; aoActions = [ WuiTmLink('Details', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionUserDetails, UserAccountData.ksParam_uid: oEntry.uid } ), ]; if self._oDisp is None or not self._oDisp.isReadOnlyUser(): aoActions += [ WuiTmLink('Modify', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionUserEdit, UserAccountData.ksParam_uid: oEntry.uid } ), WuiTmLink('Remove', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionUserDelPost, UserAccountData.ksParam_uid: oEntry.uid }, sConfirm = 'Are you sure you want to remove user #%d?' % (oEntry.uid,)), ]; return [ oEntry.uid, oEntry.sUsername, oEntry.sEmail, oEntry.sFullName, oEntry.sLoginName, 'read only' if oEntry.fReadOnly else 'full', aoActions, ];
def _formatListEntry(self, iEntry): from testmanager.webui.wuiadmin import WuiAdmin; oEntry = self._aoEntries[iEntry]; if oEntry.sEvent == SystemLogData.ksEvent_TestBoxUnknown \ and oEntry.sLogText.find('addr=') >= 0 \ and oEntry.sLogText.find('uuid=') >= 0: sUuid = (oEntry.sLogText[(oEntry.sLogText.find('uuid=') + 5):])[:36]; sAddr = (oEntry.sLogText[(oEntry.sLogText.find('addr=') + 5):]).split(' ')[0]; oAction = WuiTmLink('Add TestBox', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionTestBoxAdd, TestBoxData.ksParam_uuidSystem: sUuid, TestBoxData.ksParam_ip: sAddr }); elif oEntry.sEvent == SystemLogData.ksEvent_UserAccountUnknown: sUserName = oEntry.sLogText[oEntry.sLogText.find('(') + 1: oEntry.sLogText.find(')')] oAction = WuiTmLink('Add User', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionUserAdd, UserAccountData.ksParam_sLoginName: sUserName }); else: oAction = ''; # pylint: disable=R0204 return [oEntry.tsCreated, oEntry.sEvent, oEntry.sLogText, oAction];
def _formatEventTimestampHtml(self, tsEvent, tsLog, idEvent, oTestSet): """ Formats an event timestamp with a main log link. """ tsEvent = db.dbTimestampToZuluDatetime(tsEvent); #sFormattedTimestamp = u'%04u\u2011%02u\u2011%02u\u00a0%02u:%02u:%02uZ' \ # % ( tsEvent.year, tsEvent.month, tsEvent.day, # tsEvent.hour, tsEvent.minute, tsEvent.second,); sFormattedTimestamp = u'%02u:%02u:%02uZ' \ % ( tsEvent.hour, tsEvent.minute, tsEvent.second,); sTitle = u'#%u - %04u\u2011%02u\u2011%02u\u00a0%02u:%02u:%02u.%06uZ' \ % ( idEvent, tsEvent.year, tsEvent.month, tsEvent.day, tsEvent.hour, tsEvent.minute, tsEvent.second, tsEvent.microsecond, ); tsLog = db.dbTimestampToZuluDatetime(tsLog); sFragment = u'%02u_%02u_%02u_%06u' % ( tsLog.hour, tsLog.minute, tsLog.second, tsLog.microsecond); return WuiTmLink(sFormattedTimestamp, '', { WuiMain.ksParamAction: WuiMain.ksActionViewLog, WuiMain.ksParamLogSetId: oTestSet.idTestSet, }, sFragmentId = sFragment, sTitle = sTitle, fBracketed = False, ).toHtml();
def _recursivelyGenerateEvents(self, oTestResult, sParentName, sLineage, iRow, iFailure, oTestSet, iDepth): # pylint: disable=R0914 """ Recursively generate event table rows for the result set. oTestResult is an object of the type TestResultDataEx. """ # Hack: Replace empty outer test result name with (pretty) command line. if iRow == 1: sName = '' sDisplayName = sParentName else: sName = oTestResult.sName if sParentName == '' else '%s, %s' % ( sParentName, oTestResult.sName, ) sDisplayName = webutils.escapeElem(sName) # Format error count. sErrCnt = '' if oTestResult.cErrors > 0: sErrCnt = ' (1 error)' if oTestResult.cErrors == 1 else ' (%d errors)' % oTestResult.cErrors # Format the include in graph checkboxes. sLineage += ':%u' % (oTestResult.idStrName, ) sResultGraph = '<input type="checkbox" name="%s" value="%s%s" title="Include result in graph."/>' \ % (WuiMain.ksParamReportSubjectIds, ReportGraphModel.ksTypeResult, sLineage,) sElapsedGraph = '' if oTestResult.tsElapsed is not None: sElapsedGraph = '<input type="checkbox" name="%s" value="%s%s" title="Include elapsed time in graph."/>' \ % ( WuiMain.ksParamReportSubjectIds, ReportGraphModel.ksTypeElapsed, sLineage) if len(oTestResult.aoChildren) == 0 \ and len(oTestResult.aoValues) == 0 \ and len(oTestResult.aoMsgs) == 0 \ and len(oTestResult.aoFiles) == 0: # Leaf - single row. tsEvent = oTestResult.tsCreated if oTestResult.tsElapsed is not None: tsEvent += oTestResult.tsElapsed sHtml = ' <tr class="%s tmtbl-events-leaf tmtbl-events-lvl%s tmstatusrow-%s">\n' \ ' <td>%s</td>\n' \ ' <td>%s</td>\n' \ ' <td>%s</td>\n' \ ' <td>%s</td>\n' \ ' <td colspan="2"%s>%s%s</td>\n' \ ' <td>%s</td>\n' \ ' </tr>\n' \ % ( 'tmodd' if iRow & 1 else 'tmeven', iDepth, oTestResult.enmStatus, webutils.escapeElem(self.formatTsShort(tsEvent)), sElapsedGraph, webutils.escapeElem(self.formatIntervalShort(oTestResult.tsElapsed)) if oTestResult.tsElapsed is not None else '', sDisplayName, ' id="failure-%u"' % (iFailure,) if oTestResult.isFailure() else '', webutils.escapeElem(oTestResult.enmStatus), webutils.escapeElem(sErrCnt), sResultGraph ) iRow += 1 else: # Multiple rows. sHtml = ' <tr class="%s tmtbl-events-first tmtbl-events-lvl%s ">\n' \ ' <td>%s</td>\n' \ ' <td></td>\n' \ ' <td></td>\n' \ ' <td>%s</td>\n' \ ' <td colspan="2">%s</td>\n' \ ' <td></td>\n' \ ' </tr>\n' \ % ( 'tmodd' if iRow & 1 else 'tmeven', iDepth, webutils.escapeElem(self.formatTsShort(oTestResult.tsCreated)), ## @todo more timeline stuff later. sDisplayName, 'running' if oTestResult.tsElapsed is None else '', ) iRow += 1 # Depth. for oChild in oTestResult.aoChildren: (sChildHtml, iRow, iFailure) = self._recursivelyGenerateEvents( oChild, sName, sLineage, iRow, iFailure, oTestSet, iDepth + 1) sHtml += sChildHtml # Messages. for oMsg in oTestResult.aoMsgs: sHtml += ' <tr class="%s tmtbl-events-message tmtbl-events-lvl%s">\n' \ ' <td>%s</td>\n' \ ' <td></td>\n' \ ' <td></td>\n' \ ' <td colspan="3">%s: %s</td>\n' \ ' <td></td>\n' \ ' </tr>\n' \ % ( 'tmodd' if iRow & 1 else 'tmeven', iDepth, webutils.escapeElem(self.formatTsShort(oMsg.tsCreated)), webutils.escapeElem(oMsg.enmLevel), webutils.escapeElem(oMsg.sMsg), ) iRow += 1 # Values. for oValue in oTestResult.aoValues: sHtml += ' <tr class="%s tmtbl-events-value tmtbl-events-lvl%s">\n' \ ' <td>%s</td>\n' \ ' <td></td>\n' \ ' <td></td>\n' \ ' <td>%s</td>\n' \ ' <td class="tmtbl-events-number">%s</td>\n' \ ' <td class="tmtbl-events-unit">%s</td>\n' \ ' <td><input type="checkbox" name="%s" value="%s%s:%u" title="Include value in graph."></td>\n' \ ' </tr>\n' \ % ( 'tmodd' if iRow & 1 else 'tmeven', iDepth, webutils.escapeElem(self.formatTsShort(oValue.tsCreated)), webutils.escapeElem(oValue.sName), utils.formatNumber(oValue.lValue).replace(' ', ' '), webutils.escapeElem(oValue.sUnit), WuiMain.ksParamReportSubjectIds, ReportGraphModel.ksTypeValue, sLineage, oValue.idStrName, ) iRow += 1 # Files. for oFile in oTestResult.aoFiles: if oFile.sMime in [ 'text/plain', ]: aoLinks = [ WuiTmLink('%s (%s)' % (oFile.sFile, oFile.sKind), '', { self._oDisp.ksParamAction: self._oDisp.ksActionViewLog, self._oDisp.ksParamLogSetId: oTestSet.idTestSet, self._oDisp.ksParamLogFileId: oFile.idTestResultFile, }, sTitle=oFile.sDescription), WuiTmLink( 'View Raw', '', { self._oDisp.ksParamAction: self._oDisp.ksActionGetFile, self._oDisp.ksParamGetFileSetId: oTestSet.idTestSet, self._oDisp.ksParamGetFileId: oFile.idTestResultFile, self._oDisp.ksParamGetFileDownloadIt: False, }, sTitle=oFile.sDescription), ] else: aoLinks = [ WuiTmLink( '%s (%s)' % (oFile.sFile, oFile.sKind), '', { self._oDisp.ksParamAction: self._oDisp.ksActionGetFile, self._oDisp.ksParamGetFileSetId: oTestSet.idTestSet, self._oDisp.ksParamGetFileId: oFile.idTestResultFile, self._oDisp.ksParamGetFileDownloadIt: False, }, sTitle=oFile.sDescription), ] aoLinks.append( WuiTmLink('Download', '', { self._oDisp.ksParamAction: self._oDisp.ksActionGetFile, self._oDisp.ksParamGetFileSetId: oTestSet.idTestSet, self._oDisp.ksParamGetFileId: oFile.idTestResultFile, self._oDisp.ksParamGetFileDownloadIt: True, }, sTitle=oFile.sDescription)) sHtml += ' <tr class="%s tmtbl-events-file tmtbl-events-lvl%s">\n' \ ' <td></td>\n' \ ' <td>%s</td>\n' \ ' <td></td>\n' \ ' <td>%s</td>\n' \ ' <td></td>\n' \ ' <td></td>\n' \ ' <td></td>\n' \ ' </tr>\n' \ % ( 'tmodd' if iRow & 1 else 'tmeven', iDepth, webutils.escapeElem(self.formatTsShort(oFile.tsCreated)), '\n'.join(oLink.toHtml() for oLink in aoLinks),) iRow += 1 # Done? if oTestResult.tsElapsed is not None: sHtml += ' <tr class="%s tmtbl-events-final tmtbl-events-lvl%s tmstatusrow-%s">\n' \ ' <td>%s</td>\n' \ ' <td>%s</td>\n' \ ' <td>%s</td>\n' \ ' <td>%s</td>\n' \ ' <td colspan="2"%s>%s%s</td>\n' \ ' <td>%s</td>\n' \ ' </tr>\n' \ % ( 'tmodd' if iRow & 1 else 'tmeven', iDepth, oTestResult.enmStatus, webutils.escapeElem(self.formatTsShort(oTestResult.tsCreated + oTestResult.tsElapsed)), sElapsedGraph, webutils.escapeElem(self.formatIntervalShort(oTestResult.tsElapsed)), sDisplayName, ' id="failure-%u"' % (iFailure,) if oTestResult.isFailure() else '', webutils.escapeElem(oTestResult.enmStatus), webutils.escapeElem(sErrCnt), sResultGraph) iRow += 1 if oTestResult.isFailure(): iFailure += 1 return (sHtml, iRow, iFailure)
def showTestCaseResultDetails( self, # pylint: disable=R0914,R0915 oTestResultTree, oTestSet, oBuildEx, oValidationKitEx, oTestBox, oTestGroup, oTestCaseEx, oTestVarEx): """Show detailed result""" def getTcDepsHtmlList(aoTestCaseData): """Get HTML <ul> list of Test Case name items""" if len(aoTestCaseData) > 0: sTmp = '<ul>' for oTestCaseData in aoTestCaseData: sTmp += '<li>%s</li>' % (webutils.escapeElem( oTestCaseData.sName), ) sTmp += '</ul>' else: sTmp = 'No items' return sTmp def getGrDepsHtmlList(aoGlobalResourceData): """Get HTML <ul> list of Global Resource name items""" if len(aoGlobalResourceData) > 0: sTmp = '<ul>' for oGlobalResourceData in aoGlobalResourceData: sTmp += '<li>%s</li>' % (webutils.escapeElem( oGlobalResourceData.sName), ) sTmp += '</ul>' else: sTmp = 'No items' return sTmp asHtml = [] # Test result + test set details. aoResultRows = [ WuiTmLink( oTestCaseEx.sName, self.oWuiAdmin.ksScriptName, { self.oWuiAdmin.ksParamAction: self.oWuiAdmin.ksActionTestCaseDetails, TestCaseData.ksParam_idTestCase: oTestCaseEx.idTestCase, self.oWuiAdmin.ksParamEffectiveDate: oTestSet.tsConfig, }, fBracketed=False), ] if oTestCaseEx.sDescription is not None and len( oTestCaseEx.sDescription) > 0: aoResultRows.append([ oTestCaseEx.sDescription, ]) aoResultRows.append([ 'Status:', WuiRawHtml('<span class="tmspan-status-%s">%s</span>' % ( oTestResultTree.enmStatus, oTestResultTree.enmStatus, )) ]) if oTestResultTree.cErrors > 0: aoResultRows.append(('Errors:', oTestResultTree.cErrors)) aoResultRows.append(['Elapsed:', oTestResultTree.tsElapsed]) cSecCfgTimeout = oTestCaseEx.cSecTimeout if oTestVarEx.cSecTimeout is None else oTestVarEx.cSecTimeout cSecEffTimeout = cSecCfgTimeout * oTestBox.pctScaleTimeout / 100 aoResultRows.append([ 'Timeout:', '%s (%s sec)' % ( utils.formatIntervalSeconds(cSecEffTimeout), cSecEffTimeout, ) ]) if cSecEffTimeout != cSecCfgTimeout: aoResultRows.append([ 'Cfg Timeout:', '%s (%s sec)' % ( utils.formatIntervalSeconds(cSecCfgTimeout), cSecCfgTimeout, ) ]) aoResultRows += [ ('Started:', WuiTmLink( self.formatTsShort(oTestSet.tsCreated), WuiMain.ksScriptName, { WuiMain.ksParamAction: WuiMain.ksActionResultsUnGrouped, WuiMain.ksParamEffectiveDate: oTestSet.tsCreated, }, fBracketed=False)), ] if oTestSet.tsDone is not None: aoResultRows += [ ('Done:', WuiTmLink(self.formatTsShort(oTestSet.tsDone), WuiMain.ksScriptName, { WuiMain.ksParamAction: WuiMain.ksActionResultsUnGrouped, WuiMain.ksParamEffectiveDate: oTestSet.tsDone, }, fBracketed=False)) ] else: aoResultRows += [('Done:', 'Still running...')] aoResultRows += [('Config:', oTestSet.tsConfig)] if oTestVarEx.cGangMembers > 1: aoResultRows.append([ 'Member No:', '#%s (of %s)' % (oTestSet.iGangMemberNo, oTestVarEx.cGangMembers) ]) aoResultRows += [ ('Test Group:', WuiTmLink( oTestGroup.sName, self.oWuiAdmin.ksScriptName, { self.oWuiAdmin.ksParamAction: self.oWuiAdmin.ksActionTestGroupDetails, TestGroupData.ksParam_idTestGroup: oTestGroup.idTestGroup, self.oWuiAdmin.ksParamEffectiveDate: oTestSet.tsConfig, }, fBracketed=False)), ] if oTestVarEx.sTestBoxReqExpr is not None: aoResultRows.append(['TestBox reqs:', oTestVarEx.sTestBoxReqExpr]) elif oTestCaseEx.sTestBoxReqExpr is not None or oTestVarEx.sTestBoxReqExpr is not None: aoResultRows.append(['TestBox reqs:', oTestCaseEx.sTestBoxReqExpr]) if oTestVarEx.sBuildReqExpr is not None: aoResultRows.append(['Build reqs:', oTestVarEx.sBuildReqExpr]) elif oTestCaseEx.sBuildReqExpr is not None or oTestVarEx.sBuildReqExpr is not None: aoResultRows.append(['Build reqs:', oTestCaseEx.sBuildReqExpr]) if oTestCaseEx.sValidationKitZips is not None and oTestCaseEx.sValidationKitZips != '@VALIDATIONKIT_ZIP@': aoResultRows.append( ['Validation Kit:', oTestCaseEx.sValidationKitZips]) if oTestCaseEx.aoDepTestCases is not None and len( oTestCaseEx.aoDepTestCases) > 0: aoResultRows.append([ 'Prereq. Test Cases:', oTestCaseEx.aoDepTestCases, getTcDepsHtmlList ]) if oTestCaseEx.aoDepGlobalResources is not None and len( oTestCaseEx.aoDepGlobalResources) > 0: aoResultRows.append([ 'Global Resources:', oTestCaseEx.aoDepGlobalResources, getGrDepsHtmlList ]) # Builds. aoBuildRows = [] if oBuildEx is not None: aoBuildRows += [ WuiTmLink( 'Build', self.oWuiAdmin.ksScriptName, { self.oWuiAdmin.ksParamAction: self.oWuiAdmin.ksActionBuildDetails, BuildData.ksParam_idBuild: oBuildEx.idBuild, self.oWuiAdmin.ksParamEffectiveDate: oTestSet.tsCreated, }, fBracketed=False), ] self._anchorAndAppendBinaries(oBuildEx.sBinaries, aoBuildRows) aoBuildRows += [ ('Revision:', WuiSvnLinkWithTooltip(oBuildEx.iRevision, oBuildEx.oCat.sRepository, fBracketed=False)), ('Product:', oBuildEx.oCat.sProduct), ('Branch:', oBuildEx.oCat.sBranch), ('Type:', oBuildEx.oCat.sType), ('Version:', oBuildEx.sVersion), ('Created:', oBuildEx.tsCreated), ] if oBuildEx.uidAuthor is not None: aoBuildRows += [ ('Author ID:', oBuildEx.uidAuthor), ] if oBuildEx.sLogUrl is not None: aoBuildRows += [ ('Log:', WuiBuildLogLink(oBuildEx.sLogUrl, fBracketed=False)), ] aoValidationKitRows = [] if oValidationKitEx is not None: aoValidationKitRows += [ WuiTmLink( 'Validation Kit', self.oWuiAdmin.ksScriptName, { self.oWuiAdmin.ksParamAction: self.oWuiAdmin.ksActionBuildDetails, BuildData.ksParam_idBuild: oValidationKitEx.idBuild, self.oWuiAdmin.ksParamEffectiveDate: oTestSet.tsCreated, }, fBracketed=False), ] self._anchorAndAppendBinaries(oValidationKitEx.sBinaries, aoValidationKitRows) aoValidationKitRows += [('Revision:', WuiSvnLink(oValidationKitEx.iRevision, fBracketed=False))] if oValidationKitEx.oCat.sProduct != 'VBox TestSuite': aoValidationKitRows += [ ('Product:', oValidationKitEx.oCat.sProduct), ] if oValidationKitEx.oCat.sBranch != 'trunk': aoValidationKitRows += [ ('Product:', oValidationKitEx.oCat.sBranch), ] if oValidationKitEx.oCat.sType != 'release': aoValidationKitRows += [ ('Type:', oValidationKitEx.oCat.sType), ] if oValidationKitEx.sVersion != '0.0.0': aoValidationKitRows += [ ('Version:', oValidationKitEx.sVersion), ] aoValidationKitRows += [ ('Created:', oValidationKitEx.tsCreated), ] if oValidationKitEx.uidAuthor is not None: aoValidationKitRows += [ ('Author ID:', oValidationKitEx.uidAuthor), ] if oValidationKitEx.sLogUrl is not None: aoValidationKitRows += [ ('Log:', WuiBuildLogLink(oValidationKitEx.sLogUrl, fBracketed=False)), ] # TestBox. aoTestBoxRows = [ WuiTmLink( oTestBox.sName, self.oWuiAdmin.ksScriptName, { self.oWuiAdmin.ksParamAction: self.oWuiAdmin.ksActionTestBoxDetails, TestBoxData.ksParam_idGenTestBox: oTestSet.idGenTestBox, }, fBracketed=False), ] if oTestBox.sDescription is not None and len( oTestBox.sDescription) > 0: aoTestBoxRows.append([ oTestBox.sDescription, ]) aoTestBoxRows += [ ('IP:', oTestBox.ip), #( 'UUID:', oTestBox.uuidSystem ), #( 'Enabled:', oTestBox.fEnabled ), #( 'Lom Kind:', oTestBox.enmLomKind ), #( 'Lom IP:', oTestBox.ipLom ), ('OS/Arch:', '%s.%s' % (oTestBox.sOs, oTestBox.sCpuArch)), ('OS Version:', oTestBox.sOsVersion), ('CPUs:', oTestBox.cCpus), ] if oTestBox.sCpuName is not None: aoTestBoxRows.append( ['CPU Name', oTestBox.sCpuName.replace(' ', ' ')]) if oTestBox.lCpuRevision is not None: # ASSUMING x86+AMD64 versioning scheme here. uFamily = (oTestBox.lCpuRevision >> 24) & 0xff uModel = (oTestBox.lCpuRevision >> 8) & 0xffff uStepping = oTestBox.lCpuRevision & 0xff aoTestBoxRows += [ ('CPU Family', '%u (%#x)' % ( uFamily, uFamily, )), ('CPU Model', '%u (%#x)' % ( uModel, uModel, )), ('CPU Stepping', '%u (%#x)' % ( uStepping, uStepping, )), ] asFeatures = [ oTestBox.sCpuVendor, ] if oTestBox.fCpuHwVirt is True: asFeatures.append(u'HW\u2011Virt') if oTestBox.fCpuNestedPaging is True: asFeatures.append(u'Nested\u2011Paging') if oTestBox.fCpu64BitGuest is True: asFeatures.append(u'64\u2011bit\u2011Guest') if oTestBox.fChipsetIoMmu is True: asFeatures.append(u'I/O\u2011MMU') aoTestBoxRows += [ ('Features:', u' '.join(asFeatures)), ('RAM size:', '%s MB' % (oTestBox.cMbMemory, )), ('Scratch Size:', '%s MB' % (oTestBox.cMbScratch, )), ('Scale Timeout:', '%s%%' % (oTestBox.pctScaleTimeout, )), ('Script Rev:', WuiSvnLink(oTestBox.iTestBoxScriptRev, fBracketed=False)), ('Python:', oTestBox.formatPythonVersion()), ('Pending Command:', oTestBox.enmPendingCmd), ] aoRows = [ aoResultRows, aoBuildRows, aoValidationKitRows, aoTestBoxRows, ] asHtml.append(self._htmlTable(aoRows)) # # Convert the tree to a list of events, values, message and files. # sHtmlEvents = '' sHtmlEvents += '<table class="tmtbl-events" id="tmtbl-events" width="100%">\n' sHtmlEvents += ' <tr class="tmheader">\n' \ ' <th>When</th>\n' \ ' <th></th>\n' \ ' <th>Elapsed</th>\n' \ ' <th>Event name</th>\n' \ ' <th colspan="2">Value (status)</th>' \ ' <th></th>\n' \ ' </tr>\n' sPrettyCmdLine = ' \\<br> \n'.join( webutils.escapeElem(oTestCaseEx.sBaseCmd + ' ' + oTestVarEx.sArgs).split()) (sTmp, _, cFailures) = self._recursivelyGenerateEvents(oTestResultTree, sPrettyCmdLine, '', 1, 0, oTestSet, 0) sHtmlEvents += sTmp sHtmlEvents += '</table>\n' # # Put it all together. # sHtml = '<table class="tmtbl-testresult-details-base" width="100%">\n' sHtml += ' <tr>\n' sHtml += ' <td valign="top" width="20%%">\n%s\n</td>\n' % ' <br>\n'.join( asHtml) sHtml += ' <td valign="top" width="80%" style="padding-left:6px">\n' sHtml += ' <h2>Events:</h2>\n' sHtml += ' <form action="#" method="get" id="graph-form">\n' \ ' <input type="hidden" name="%s" value="%s"/>\n' \ ' <input type="hidden" name="%s" value="%u"/>\n' \ ' <input type="hidden" name="%s" value="%u"/>\n' \ ' <input type="hidden" name="%s" value="%u"/>\n' \ ' <input type="hidden" name="%s" value="%u"/>\n' \ % ( WuiMain.ksParamAction, WuiMain.ksActionGraphWiz, WuiMain.ksParamGraphWizTestBoxIds, oTestBox.idTestBox, WuiMain.ksParamGraphWizBuildCatIds, oBuildEx.idBuildCategory, WuiMain.ksParamGraphWizTestCaseIds, oTestSet.idTestCase, WuiMain.ksParamGraphWizSrcTestSetId, oTestSet.idTestSet, ) if oTestSet.tsDone is not None: sHtml += ' <input type="hidden" name="%s" value="%s"/>\n' \ % ( WuiMain.ksParamEffectiveDate, oTestSet.tsDone, ) sHtml += ' <p>\n' sFormButton = '<button type="submit" onclick="%s">Show graphs</button>' \ % ( webutils.escapeAttr('addDynamicGraphInputs("graph-form", "main", "%s", "%s");' % (WuiMain.ksParamGraphWizWidth, WuiMain.ksParamGraphWizDpi, )) ) sHtml += ' ' + sFormButton + '\n' sHtml += ' %s %s %s\n' \ % ( WuiTmLink('Log File', '', { WuiMain.ksParamAction: WuiMain.ksActionViewLog, WuiMain.ksParamLogSetId: oTestSet.idTestSet, }), WuiTmLink('Raw Log', '', { WuiMain.ksParamAction: WuiMain.ksActionGetFile, WuiMain.ksParamGetFileSetId: oTestSet.idTestSet, WuiMain.ksParamGetFileDownloadIt: False, }), WuiTmLink('Download Log', '', { WuiMain.ksParamAction: WuiMain.ksActionGetFile, WuiMain.ksParamGetFileSetId: oTestSet.idTestSet, WuiMain.ksParamGetFileDownloadIt: True, }), ) sHtml += ' </p>\n' if cFailures == 1: sHtml += ' <p>%s</p>\n' % (WuiTmLink('Jump to failure', '#failure-0'), ) elif cFailures > 1: sHtml += ' <p>Jump to failure: ' if cFailures <= 13: for iFailure in range(0, cFailures): sHtml += ' ' + WuiTmLink('#%u' % (iFailure, ), '#failure-%u' % (iFailure, )).toHtml() else: for iFailure in range(0, 6): sHtml += ' ' + WuiTmLink('#%u' % (iFailure, ), '#failure-%u' % (iFailure, )).toHtml() sHtml += ' ... ' for iFailure in range(cFailures - 6, cFailures): sHtml += ' ' + WuiTmLink('#%u' % (iFailure, ), '#failure-%u' % (iFailure, )).toHtml() sHtml += ' </p>\n' sHtml += sHtmlEvents sHtml += ' <p>' + sFormButton + '</p>\n' sHtml += ' </form>\n' sHtml += ' </td>\n' sHtml += ' </tr>\n' sHtml += '</table>\n' return ('Test Case result details', sHtml)
def _formatListEntry(self, iEntry): # pylint: disable=R0914 from testmanager.webui.wuiadmin import WuiAdmin oEntry = self._aoEntries[iEntry] # Lights outs managment. if oEntry.enmLomKind == TestBoxData.ksLomKind_ILOM: aoLom = [ WuiLinkBase('ILOM', 'https://%s/' % (oEntry.ipLom, ), fBracketed=False), ] elif oEntry.enmLomKind == TestBoxData.ksLomKind_ELOM: aoLom = [ WuiLinkBase('ELOM', 'http://%s/' % (oEntry.ipLom, ), fBracketed=False), ] elif oEntry.enmLomKind == TestBoxData.ksLomKind_AppleXserveLom: aoLom = ['Apple LOM'] elif oEntry.enmLomKind == TestBoxData.ksLomKind_None: aoLom = ['none'] else: aoLom = [ 'Unexpected enmLomKind value "%s"' % (oEntry.enmLomKind, ) ] if oEntry.ipLom is not None: if oEntry.enmLomKind in [ TestBoxData.ksLomKind_ILOM, TestBoxData.ksLomKind_ELOM ]: aoLom += [ WuiLinkBase('(ssh)', 'ssh://%s' % (oEntry.ipLom, ), fBracketed=False) ] aoLom += [WuiRawHtml('<br>'), '%s' % (oEntry.ipLom, )] # State and Last seen. if oEntry.oStatus is None: oSeen = WuiSpanText('tmspan-offline', 'Never') oState = '' else: oDelta = oEntry.tsCurrent - oEntry.oStatus.tsUpdated if oDelta.days <= 0 and oDelta.seconds <= self.kcSecMaxStatusDeltaAlive: oSeen = WuiSpanText( 'tmspan-online', u'%s\u00a0s\u00a0ago' % (oDelta.days * 24 * 3600 + oDelta.seconds, )) else: oSeen = WuiSpanText( 'tmspan-offline', u'%s' % (self.formatTsShort(oEntry.oStatus.tsUpdated), )) if oEntry.oStatus.idTestSet is None: oState = str(oEntry.oStatus.enmState) else: from testmanager.webui.wuimain import WuiMain oState = WuiTmLink( oEntry.oStatus.enmState, WuiMain.ksScriptName, # pylint: disable=R0204 { WuiMain.ksParamAction: WuiMain.ksActionTestResultDetails, TestSetData.ksParam_idTestSet: oEntry.oStatus.idTestSet, }, sTitle='#%u' % (oEntry.oStatus.idTestSet, ), fBracketed=False) # Comment oComment = self._formatCommentCell(oEntry.sComment) # Group links. aoGroups = [] for oInGroup in oEntry.aoInSchedGroups: oSchedGroup = oInGroup.oSchedGroup aoGroups.append( WuiTmLink(oSchedGroup.sName, WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionSchedGroupEdit, SchedGroupData.ksParam_idSchedGroup: oSchedGroup.idSchedGroup, }, sTitle='#%u' % (oSchedGroup.idSchedGroup, ), fBracketed=len(oEntry.aoInSchedGroups) > 1)) # Reformat the OS version to take less space. aoOs = ['N/A'] if oEntry.sOs is not None and oEntry.sOsVersion is not None and oEntry.sCpuArch: sOsVersion = oEntry.sOsVersion if sOsVersion[0] not in [ 'v', 'V', 'r', 'R'] \ and sOsVersion[0].isdigit() \ and sOsVersion.find('.') in range(4) \ and oEntry.sOs in [ 'linux', 'solaris', 'darwin', ]: sOsVersion = 'v' + sOsVersion sVer1 = sOsVersion sVer2 = None if oEntry.sOs == 'linux' or oEntry.sOs == 'darwin': iSep = sOsVersion.find(' / ') if iSep > 0: sVer1 = sOsVersion[:iSep].strip() sVer2 = sOsVersion[iSep + 3:].strip() sVer2 = sVer2.replace('Red Hat Enterprise Linux Server', 'RHEL') sVer2 = sVer2.replace('Oracle Linux Server', 'OL') elif oEntry.sOs == 'solaris': iSep = sOsVersion.find(' (') if iSep > 0 and sOsVersion[-1] == ')': sVer1 = sOsVersion[:iSep].strip() sVer2 = sOsVersion[iSep + 2:-1].strip() elif oEntry.sOs == 'win': iSep = sOsVersion.find('build') if iSep > 0: sVer1 = sOsVersion[:iSep].strip() sVer2 = 'B' + sOsVersion[iSep + 1:].strip() aoOs = [ WuiSpanText('tmspan-osarch', u'%s.%s' % ( oEntry.sOs, oEntry.sCpuArch, )), WuiSpanText( 'tmspan-osver1', sVer1.replace('-', u'\u2011'), ), ] if sVer2 is not None: aoOs += [ WuiRawHtml('<br>'), WuiSpanText('tmspan-osver2', sVer2.replace('-', u'\u2011')), ] # Format the CPU revision. oCpu = None if oEntry.lCpuRevision is not None and oEntry.sCpuVendor is not None and oEntry.sCpuName is not None: oCpu = [ u'%s (fam:%xh\u00a0m:%xh\u00a0s:%xh)' % ( oEntry.sCpuVendor, oEntry.getCpuFamily(), oEntry.getCpuModel(), oEntry.getCpuStepping(), ), WuiRawHtml('<br>'), oEntry.sCpuName, ] else: oCpu = [] if oEntry.sCpuVendor is not None: oCpu.append(oEntry.sCpuVendor) if oEntry.lCpuRevision is not None: oCpu.append('%#x' % (oEntry.lCpuRevision, )) if oEntry.sCpuName is not None: oCpu.append(oEntry.sCpuName) # Stuff cpu vendor and cpu/box features into one field. asFeatures = [] if oEntry.fCpuHwVirt is True: asFeatures.append(u'HW\u2011Virt') if oEntry.fCpuNestedPaging is True: asFeatures.append(u'Nested\u2011Paging') if oEntry.fCpu64BitGuest is True: asFeatures.append(u'64\u2011bit\u2011Guest') if oEntry.fChipsetIoMmu is True: asFeatures.append(u'I/O\u2011MMU') sFeatures = u' '.join(asFeatures) if asFeatures else u'' # Collection applicable actions. aoActions = [ WuiTmLink( 'Details', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionTestBoxDetails, TestBoxData.ksParam_idTestBox: oEntry.idTestBox, WuiAdmin.ksParamEffectiveDate: self._tsEffectiveDate, }), ] if self._oDisp is None or not self._oDisp.isReadOnlyUser(): if isDbTimestampInfinity(oEntry.tsExpire): aoActions += [ WuiTmLink( 'Edit', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionTestBoxEdit, TestBoxData.ksParam_idTestBox: oEntry.idTestBox, }), WuiTmLink( 'Remove', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionTestBoxRemovePost, TestBoxData.ksParam_idTestBox: oEntry.idTestBox }, sConfirm='Are you sure that you want to remove %s (%s)?' % (oEntry.sName, oEntry.ip)), ] if oEntry.sOs not in [ 'win', 'os2', ] and oEntry.ip is not None: aoActions.append( WuiLinkBase( 'ssh', 'ssh://vbox@%s' % (oEntry.ip, ), )) return [ self._getCheckBoxColumn(iEntry, oEntry.idTestBox), [ WuiSpanText('tmspan-name', oEntry.sName), WuiRawHtml('<br>'), '%s' % (oEntry.ip, ), ], aoLom, [ '' if oEntry.fEnabled else 'disabled / ', oState, WuiRawHtml('<br>'), oSeen, ], oEntry.enmPendingCmd, oComment, WuiSvnLink(oEntry.iTestBoxScriptRev), oEntry.formatPythonVersion(), aoGroups, aoOs, oCpu, sFeatures, oEntry.cCpus if oEntry.cCpus is not None else 'N/A', utils.formatNumberNbsp(oEntry.cMbMemory) + u'\u00a0MB' if oEntry.cMbMemory is not None else 'N/A', utils.formatNumberNbsp(oEntry.cMbScratch) + u'\u00a0MB' if oEntry.cMbScratch is not None else 'N/A', aoActions, ]
def _generateNavigation(self, cbFile): """Generate the HTML for the log navigation.""" dParams = { WuiMain.ksParamAction: WuiMain.ksActionViewLog, WuiMain.ksParamLogSetId: self._oTestSet.idTestSet, WuiMain.ksParamLogFileId: self._oLogFile.idTestResultFile, WuiMain.ksParamLogChunkSize: self._cbChunk, WuiMain.ksParamLogChunkNo: self._iChunk, }; # # The page walker. # dParams2 = dict(dParams); del dParams2[WuiMain.ksParamLogChunkNo]; sHrefFmt = '<a href="?%s&%s=%%s" title="%%s">%%s</a>' \ % (webutils.encodeUrlParams(dParams2).replace('%', '%%'), WuiMain.ksParamLogChunkNo,); sHtmlWalker = self.genericPageWalker(self._iChunk, (cbFile + self._cbChunk - 1) / self._cbChunk, sHrefFmt, 11, 0, 'chunk'); # # The chunk size selector. # dParams2 = dict(dParams); del dParams2[WuiMain.ksParamLogChunkSize]; sHtmlSize = '<form name="ChunkSizeForm" method="GET">\n' \ ' Max <select name="%s" onchange="window.location=\'?%s&%s=\' + ' \ 'this.options[this.selectedIndex].value;" title="Max items per page">\n' \ % ( WuiMain.ksParamLogChunkSize, webutils.encodeUrlParams(dParams2), WuiMain.ksParamLogChunkSize,); for cbChunk in [ 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216 ]: sHtmlSize += ' <option value="%d" %s>%d bytes</option>\n' \ % (cbChunk, 'selected="selected"' if cbChunk == self._cbChunk else '', cbChunk); sHtmlSize += ' </select> per page\n' \ '</form>\n' # # Download links. # oRawLink = WuiTmLink('View Raw', '', { WuiMain.ksParamAction: WuiMain.ksActionGetFile, WuiMain.ksParamGetFileSetId: self._oTestSet.idTestSet, WuiMain.ksParamGetFileId: self._oLogFile.idTestResultFile, WuiMain.ksParamGetFileDownloadIt: False, }, sTitle = '%u MiB' % ((cbFile + 1048576 - 1) / 1048576,) ); oDownloadLink = WuiTmLink('Download Log', '', { WuiMain.ksParamAction: WuiMain.ksActionGetFile, WuiMain.ksParamGetFileSetId: self._oTestSet.idTestSet, WuiMain.ksParamGetFileId: self._oLogFile.idTestResultFile, WuiMain.ksParamGetFileDownloadIt: True, }, sTitle = '%u MiB' % ((cbFile + 1048576 - 1) / 1048576,) ); oTestSetLink = WuiTmLink('Test Set', '', { WuiMain.ksParamAction: WuiMain.ksActionTestResultDetails, TestSetData.ksParam_idTestSet: self._oTestSet.idTestSet, }); # # Combine the elements and return. # return '<div class="tmlogviewernavi">\n' \ ' <table width=100%>\n' \ ' <tr>\n' \ ' <td width=20%>\n' \ ' ' + oTestSetLink.toHtml() + '\n' \ ' ' + oRawLink.toHtml() + '\n' \ ' ' + oDownloadLink.toHtml() + '\n' \ ' </td>\n' \ ' <td width=60% align=center>' + sHtmlWalker + '</td>' \ ' <td width=20% align=right>' + sHtmlSize + '</td>\n' \ ' </tr>\n' \ ' </table>\n' \ '</div>\n';
def _formatListEntry(self, iEntry): """ Format *show all* table entry """ from testmanager.webui.wuiadmin import WuiAdmin oEntry = self._aoEntries[iEntry] oBuildSrc = None if oEntry.idBuildSrc is not None: oBuildSrc = WuiTmLink( oEntry.oBuildSrc.sName if oEntry.oBuildSrc else str(oEntry.idBuildSrc), WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionBuildSrcDetails, BuildSourceData.ksParam_idBuildSrc: oEntry.idBuildSrc, }) oValidationKitSrc = None if oEntry.idBuildSrcTestSuite is not None: oValidationKitSrc = WuiTmLink( oEntry.oBuildSrcValidationKit.sName if oEntry.oBuildSrcValidationKit else str(oEntry.idBuildSrcTestSuite), WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionBuildSrcDetails, BuildSourceData.ksParam_idBuildSrc: oEntry.idBuildSrcTestSuite, }) # Test groups aoMembers = [] for oMember in oEntry.aoMembers: aoMembers.append( WuiTmLink( oMember.oTestGroup.sName, WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionTestGroupDetails, TestGroupData.ksParam_idTestGroup: oMember.idTestGroup, WuiAdmin.ksParamEffectiveDate: self._tsEffectiveDate, }, sTitle='#%s' % (oMember.idTestGroup, ) if oMember.oTestGroup.sDescription is None else '#%s - %s' % ( oMember.idTestGroup, oMember.oTestGroup.sDescription, ))) # Test boxes. aoTestBoxes = [] for oTestBox in oEntry.aoTestBoxes: aoTestBoxes.append( WuiTmLink( oTestBox.sName, WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionTestBoxDetails, TestBoxData.ksParam_idTestBox: oTestBox.idTestBox, WuiAdmin.ksParamEffectiveDate: self._tsEffectiveDate, }, sTitle='#%s - %s / %s - %s.%s (%s)' % ( oTestBox.idTestBox, oTestBox.ip, oTestBox.uuidSystem, oTestBox.sOs, oTestBox.sCpuArch, oTestBox.sOsVersion, ))) # Actions aoActions = [ WuiTmLink( 'Details', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionSchedGroupDetails, SchedGroupData.ksParam_idSchedGroup: oEntry.idSchedGroup, WuiAdmin.ksParamEffectiveDate: self._tsEffectiveDate, }), ] if isDbTimestampInfinity(oEntry.tsExpire): aoActions.append( WuiTmLink( 'Modify', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionSchedGroupEdit, SchedGroupData.ksParam_idSchedGroup: oEntry.idSchedGroup })) aoActions.append( WuiTmLink( 'Clone', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionSchedGroupClone, SchedGroupData.ksParam_idSchedGroup: oEntry.idSchedGroup, WuiAdmin.ksParamEffectiveDate: self._tsEffectiveDate, })) if isDbTimestampInfinity(oEntry.tsExpire): aoActions.append( WuiTmLink( 'Remove', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionSchedGroupDoRemove, SchedGroupData.ksParam_idSchedGroup: oEntry.idSchedGroup }, sConfirm= 'Are you sure you want to remove scheduling group #%d?' % (oEntry.idSchedGroup, ))) return [ oEntry.idSchedGroup, oEntry.sName, oEntry.fEnabled, oEntry.enmScheduler, oBuildSrc, oValidationKitSrc, aoMembers, aoTestBoxes, aoActions, ]
def _formatListEntry(self, iEntry): """ Format *show all* table entry """ oEntry = self._aoEntries[iEntry] from testmanager.webui.wuiadmin import WuiAdmin oValidationKit = None if oEntry.idBuildTestSuite is not None: oValidationKit = WuiTmLink( '#%d - r%s' % (oEntry.idBuildTestSuite, oEntry.iRevisionTestSuite), WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionBuildDetails, BuildData.ksParam_idBuild: oEntry.idBuildTestSuite }, fBracketed=False) aoTestSetLinks = [ WuiTmLink( oEntry.enmStatus, WuiMain.ksScriptName, { WuiMain.ksParamAction: WuiMain.ksActionTestResultDetails, TestSetData.ksParam_idTestSet: oEntry.idTestSet }, fBracketed=False), ] if oEntry.cErrors > 0: aoTestSetLinks.append( WuiTmLink('- %d error(s)' % (oEntry.cErrors, ), WuiMain.ksScriptName, { WuiMain.ksParamAction: WuiMain.ksActionTestResultDetails, TestSetData.ksParam_idTestSet: oEntry.idTestSet }, sFragmentId='failure-0', fBracketed=False)) self._dTestBoxLinkParams[ WuiMain.ksParamGroupMemberId] = oEntry.idTestBox self._dTestCaseLinkParams[ WuiMain.ksParamGroupMemberId] = oEntry.idTestCase self._dRevLinkParams[WuiMain.ksParamGroupMemberId] = oEntry.iRevision sTestBoxTitle = u'' if oEntry.sCpuVendor is not None: sTestBoxTitle += 'CPU vendor:\t%s\n' % (oEntry.sCpuVendor, ) if oEntry.sCpuName is not None: sTestBoxTitle += 'CPU name:\t%s\n' % (' '.join( oEntry.sCpuName.split()), ) if oEntry.sOsVersion is not None: sTestBoxTitle += 'OS version:\t%s\n' % (oEntry.sOsVersion, ) asFeatures = [] if oEntry.fCpuHwVirt is True: asFeatures.append(u'HW\u2011Virt') if oEntry.fCpuNestedPaging is True: asFeatures.append(u'Nested\u2011Paging') if oEntry.fCpu64BitGuest is True: asFeatures.append(u'64\u2011bit\u2011Guest') #if oEntry.fChipsetIoMmu is True: asFeatures.append(u'I/O\u2011MMU'); sTestBoxTitle += u'CPU features:\t' + u', '.join(asFeatures) return [ oEntry.tsCreated, [ WuiTmLink('#%d - %s %s (%s)' % ( oEntry.idBuild, oEntry.sProduct, oEntry.sVersion, oEntry.sType, ), WuiMain.ksScriptName, self._dRevLinkParams, sTitle='%s' % (oEntry.sBranch, ), fBracketed=False), WuiSvnLinkWithTooltip( oEntry.iRevision, 'vbox'), ## @todo add sRepository TestResultListingData WuiTmLink( self.ksShortDetailsLink, WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionBuildDetails, BuildData.ksParam_idBuild: oEntry.idBuild }, fBracketed=False), ], oValidationKit, '%s.%s' % (oEntry.sOs, oEntry.sArch), [ WuiTmLink(oEntry.sTestBoxName, WuiMain.ksScriptName, self._dTestBoxLinkParams, fBracketed=False, sTitle=sTestBoxTitle), WuiTmLink(self.ksShortDetailsLink, WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionTestBoxDetails, TestBoxData.ksParam_idTestBox: oEntry.idTestBox }, fBracketed=False) ], [ WuiTmLink(oEntry.sTestCaseName, WuiMain.ksScriptName, self._dTestCaseLinkParams, fBracketed=False, sTitle=(oEntry.sBaseCmd + ' ' + oEntry.sArgs) if oEntry.sArgs else oEntry.sBaseCmd), WuiTmLink( self.ksShortDetailsLink, WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionTestCaseDetails, TestCaseData.ksParam_idTestCase: oEntry.idTestCase }, fBracketed=False), ], oEntry.tsElapsed, aoTestSetLinks ]
def _recursivelyGenerateEvents(self, oTestResult, sParentName, sLineage, iRow, iFailure, oTestSet, iDepth): # pylint: disable=R0914 """ Recursively generate event table rows for the result set. oTestResult is an object of the type TestResultDataEx. """ # Hack: Replace empty outer test result name with (pretty) command line. if iRow == 1: sName = ''; sDisplayName = sParentName; else: sName = oTestResult.sName if sParentName == '' else '%s, %s' % (sParentName, oTestResult.sName,); sDisplayName = webutils.escapeElem(sName); # Format error count. sErrCnt = ''; if oTestResult.cErrors > 0: sErrCnt = ' (1 error)' if oTestResult.cErrors == 1 else ' (%d errors)' % oTestResult.cErrors; # Format bits for adding or editing the failure reason. Level 0 is handled at the top of the page. sChangeReason = ''; if oTestResult.cErrors > 0 and iDepth > 0: dTmp = { self._oDisp.ksParamAction: self._oDisp.ksActionTestResultFailureAdd if oTestResult.oReason is None else self._oDisp.ksActionTestResultFailureEdit, TestResultFailureData.ksParam_idTestResult: oTestResult.idTestResult, }; sChangeReason = ' <a href="?%s" class="tmtbl-edit-reason" onclick="addRedirectToAnchorHref(this)">%s</a> ' \ % ( webutils.encodeUrlParams(dTmp), WuiContentBase.ksShortEditLinkHtml ); # Format the include in graph checkboxes. sLineage += ':%u' % (oTestResult.idStrName,); sResultGraph = '<input type="checkbox" name="%s" value="%s%s" title="Include result in graph."/>' \ % (WuiMain.ksParamReportSubjectIds, ReportGraphModel.ksTypeResult, sLineage,); sElapsedGraph = ''; if oTestResult.tsElapsed is not None: sElapsedGraph = '<input type="checkbox" name="%s" value="%s%s" title="Include elapsed time in graph."/>' \ % ( WuiMain.ksParamReportSubjectIds, ReportGraphModel.ksTypeElapsed, sLineage); if len(oTestResult.aoChildren) == 0 \ and len(oTestResult.aoValues) + len(oTestResult.aoMsgs) + len(oTestResult.aoFiles) == 0: # Leaf - single row. tsEvent = oTestResult.tsCreated; if oTestResult.tsElapsed is not None: tsEvent += oTestResult.tsElapsed; sHtml = ' <tr class="%s tmtbl-events-leaf tmtbl-events-lvl%s tmstatusrow-%s" id="S%u">\n' \ ' <td id="E%u">%s</td>\n' \ ' <td>%s</td>\n' \ ' <td>%s</td>\n' \ ' <td>%s</td>\n' \ ' <td colspan="2"%s>%s%s%s</td>\n' \ ' <td>%s</td>\n' \ ' </tr>\n' \ % ( 'tmodd' if iRow & 1 else 'tmeven', iDepth, oTestResult.enmStatus, oTestResult.idTestResult, oTestResult.idTestResult, self._formatEventTimestampHtml(tsEvent, oTestResult.tsCreated, oTestResult.idTestResult, oTestSet), sElapsedGraph, webutils.escapeElem(self.formatIntervalShort(oTestResult.tsElapsed)) if oTestResult.tsElapsed is not None else '', sDisplayName, ' id="failure-%u"' % (iFailure,) if oTestResult.isFailure() else '', webutils.escapeElem(oTestResult.enmStatus), webutils.escapeElem(sErrCnt), sChangeReason if oTestResult.oReason is None else '', sResultGraph ); iRow += 1; else: # Multiple rows. sHtml = ' <tr class="%s tmtbl-events-first tmtbl-events-lvl%s ">\n' \ ' <td>%s</td>\n' \ ' <td></td>\n' \ ' <td></td>\n' \ ' <td>%s</td>\n' \ ' <td colspan="2">%s</td>\n' \ ' <td></td>\n' \ ' </tr>\n' \ % ( 'tmodd' if iRow & 1 else 'tmeven', iDepth, self._formatEventTimestampHtml(oTestResult.tsCreated, oTestResult.tsCreated, oTestResult.idTestResult, oTestSet), sDisplayName, 'running' if oTestResult.tsElapsed is None else '', ); iRow += 1; # Depth. Check if our error count is just reflecting the one of our children. cErrorsBelow = 0; for oChild in oTestResult.aoChildren: (sChildHtml, iRow, iFailure) = self._recursivelyGenerateEvents(oChild, sName, sLineage, iRow, iFailure, oTestSet, iDepth + 1); sHtml += sChildHtml; cErrorsBelow += oChild.cErrors; # Messages. for oMsg in oTestResult.aoMsgs: sHtml += ' <tr class="%s tmtbl-events-message tmtbl-events-lvl%s">\n' \ ' <td>%s</td>\n' \ ' <td></td>\n' \ ' <td></td>\n' \ ' <td colspan="3">%s: %s</td>\n' \ ' <td></td>\n' \ ' </tr>\n' \ % ( 'tmodd' if iRow & 1 else 'tmeven', iDepth, self._formatEventTimestampHtml(oMsg.tsCreated, oMsg.tsCreated, oMsg.idTestResultMsg, oTestSet), webutils.escapeElem(oMsg.enmLevel), webutils.escapeElem(oMsg.sMsg), ); iRow += 1; # Values. for oValue in oTestResult.aoValues: sHtml += ' <tr class="%s tmtbl-events-value tmtbl-events-lvl%s">\n' \ ' <td>%s</td>\n' \ ' <td></td>\n' \ ' <td></td>\n' \ ' <td>%s</td>\n' \ ' <td class="tmtbl-events-number">%s</td>\n' \ ' <td class="tmtbl-events-unit">%s</td>\n' \ ' <td><input type="checkbox" name="%s" value="%s%s:%u" title="Include value in graph."></td>\n' \ ' </tr>\n' \ % ( 'tmodd' if iRow & 1 else 'tmeven', iDepth, self._formatEventTimestampHtml(oValue.tsCreated, oValue.tsCreated, oValue.idTestResultValue, oTestSet), webutils.escapeElem(oValue.sName), utils.formatNumber(oValue.lValue).replace(' ', ' '), webutils.escapeElem(oValue.sUnit), WuiMain.ksParamReportSubjectIds, ReportGraphModel.ksTypeValue, sLineage, oValue.idStrName, ); iRow += 1; # Files. for oFile in oTestResult.aoFiles: if oFile.sMime in [ 'text/plain', ]: aoLinks = [ WuiTmLink('%s (%s)' % (oFile.sFile, oFile.sKind), '', { self._oDisp.ksParamAction: self._oDisp.ksActionViewLog, self._oDisp.ksParamLogSetId: oTestSet.idTestSet, self._oDisp.ksParamLogFileId: oFile.idTestResultFile, }, sTitle = oFile.sDescription), WuiTmLink('View Raw', '', { self._oDisp.ksParamAction: self._oDisp.ksActionGetFile, self._oDisp.ksParamGetFileSetId: oTestSet.idTestSet, self._oDisp.ksParamGetFileId: oFile.idTestResultFile, self._oDisp.ksParamGetFileDownloadIt: False, }, sTitle = oFile.sDescription), ] else: aoLinks = [ WuiTmLink('%s (%s)' % (oFile.sFile, oFile.sKind), '', { self._oDisp.ksParamAction: self._oDisp.ksActionGetFile, self._oDisp.ksParamGetFileSetId: oTestSet.idTestSet, self._oDisp.ksParamGetFileId: oFile.idTestResultFile, self._oDisp.ksParamGetFileDownloadIt: False, }, sTitle = oFile.sDescription), ] aoLinks.append(WuiTmLink('Download', '', { self._oDisp.ksParamAction: self._oDisp.ksActionGetFile, self._oDisp.ksParamGetFileSetId: oTestSet.idTestSet, self._oDisp.ksParamGetFileId: oFile.idTestResultFile, self._oDisp.ksParamGetFileDownloadIt: True, }, sTitle = oFile.sDescription)); sHtml += ' <tr class="%s tmtbl-events-file tmtbl-events-lvl%s">\n' \ ' <td>%s</td>\n' \ ' <td></td>\n' \ ' <td></td>\n' \ ' <td>%s</td>\n' \ ' <td></td>\n' \ ' <td></td>\n' \ ' <td></td>\n' \ ' </tr>\n' \ % ( 'tmodd' if iRow & 1 else 'tmeven', iDepth, self._formatEventTimestampHtml(oFile.tsCreated, oFile.tsCreated, oFile.idTestResultFile, oTestSet), '\n'.join(oLink.toHtml() for oLink in aoLinks),); iRow += 1; # Done? if oTestResult.tsElapsed is not None: tsEvent = oTestResult.tsCreated + oTestResult.tsElapsed; sHtml += ' <tr class="%s tmtbl-events-final tmtbl-events-lvl%s tmstatusrow-%s" id="E%d">\n' \ ' <td>%s</td>\n' \ ' <td>%s</td>\n' \ ' <td>%s</td>\n' \ ' <td>%s</td>\n' \ ' <td colspan="2"%s>%s%s%s</td>\n' \ ' <td>%s</td>\n' \ ' </tr>\n' \ % ( 'tmodd' if iRow & 1 else 'tmeven', iDepth, oTestResult.enmStatus, oTestResult.idTestResult, self._formatEventTimestampHtml(tsEvent, tsEvent, oTestResult.idTestResult, oTestSet), sElapsedGraph, webutils.escapeElem(self.formatIntervalShort(oTestResult.tsElapsed)), sDisplayName, ' id="failure-%u"' % (iFailure,) if oTestResult.isFailure() else '', webutils.escapeElem(oTestResult.enmStatus), webutils.escapeElem(sErrCnt), sChangeReason if cErrorsBelow < oTestResult.cErrors and oTestResult.oReason is None else '', sResultGraph); iRow += 1; # Failure reason. if oTestResult.oReason is not None: sReasonText = '%s / %s' % ( oTestResult.oReason.oFailureReason.oCategory.sShort, oTestResult.oReason.oFailureReason.sShort, ); sCommentHtml = ''; if oTestResult.oReason.sComment is not None and len(oTestResult.oReason.sComment.strip()) > 0: sCommentHtml = '<br>' + webutils.escapeElem(oTestResult.oReason.sComment.strip()); sCommentHtml = sCommentHtml.replace('\n', '<br>'); sDetailedReason = ' <a href="?%s" class="tmtbl-show-reason">%s</a>' \ % ( webutils.encodeUrlParams({ self._oDisp.ksParamAction: self._oDisp.ksActionTestResultFailureDetails, TestResultFailureData.ksParam_idTestResult: oTestResult.idTestResult,}), WuiContentBase.ksShortDetailsLinkHtml,); sHtml += ' <tr class="%s tmtbl-events-reason tmtbl-events-lvl%s">\n' \ ' <td>%s</td>\n' \ ' <td colspan="2">%s</td>\n' \ ' <td colspan="3">%s%s%s%s</td>\n' \ ' <td>%s</td>\n' \ ' </tr>\n' \ % ( 'tmodd' if iRow & 1 else 'tmeven', iDepth, webutils.escapeElem(self.formatTsShort(oTestResult.oReason.tsEffective)), oTestResult.oReason.oAuthor.sUsername, webutils.escapeElem(sReasonText), sDetailedReason, sChangeReason, sCommentHtml, 'todo'); iRow += 1; if oTestResult.isFailure(): iFailure += 1; return (sHtml, iRow, iFailure);
def _formatListEntry(self, iEntry): oEntry = self._aoEntries[iEntry] from testmanager.webui.wuiadmin import WuiAdmin # # Test case list. # sHtml = '' if len(oEntry.aoMembers) > 0: for oMember in oEntry.aoMembers: sHtml += '<dl>\n' \ ' <dd><strong>%s</strong> (priority: %d) %s %s</dd>\n' \ % ( webutils.escapeElem(oMember.oTestCase.sName), oMember.iSchedPriority, WuiTmLink('Details', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionTestCaseDetails, TestCaseData.ksParam_idGenTestCase: oMember.oTestCase.idGenTestCase, } ).toHtml(), WuiTmLink('Edit', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionTestCaseEdit, TestCaseData.ksParam_idTestCase: oMember.oTestCase.idTestCase, } ).toHtml() if isDbTimestampInfinity(oMember.oTestCase.tsExpire) else '', ) sHtml += ' <dt>\n' fNoGang = True for oVar in oMember.oTestCase.aoTestCaseArgs: if oVar.cGangMembers > 1: fNoGang = False break sHtml += ' <table class="tminnertbl" width="100%">\n' if fNoGang: sHtml += ' <tr><th>Timeout</th><th>Arguments</th></tr>\n' else: sHtml += ' <tr><th>Gang Size</th><th>Timeout</th><th style="text-align:left;">Arguments</th></tr>\n' cArgsIncluded = 0 for oVar in oMember.oTestCase.aoTestCaseArgs: if oMember.aidTestCaseArgs is None or oVar.idTestCaseArgs in oMember.aidTestCaseArgs: cArgsIncluded += 1 if fNoGang: sHtml += ' <tr>' else: sHtml += ' <tr><td>%s</td>' % ( oVar.cGangMembers, ) sHtml += '<td>%s</td><td>%s</td></tr>\n' \ % ( utils.formatIntervalSeconds(oMember.oTestCase.cSecTimeout if oVar.cSecTimeout is None else oVar.cSecTimeout), webutils.escapeElem(oVar.sArgs), ) if cArgsIncluded == 0: sHtml += ' <tr><td colspan="%u">No arguments selected.</td></tr>\n' % ( 2 if fNoGang else 3, ) sHtml += ' </table>\n' \ ' </dl>\n' oTestCases = WuiRawHtml(sHtml) # # Actions. # aoActions = [ WuiTmLink( 'Details', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionTestGroupDetails, TestGroupData.ksParam_idTestGroup: oEntry.idTestGroup, WuiAdmin.ksParamEffectiveDate: self._tsEffectiveDate, }) ] if isDbTimestampInfinity(oEntry.tsExpire): aoActions.append( WuiTmLink( 'Modify', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionTestGroupEdit, TestGroupData.ksParam_idTestGroup: oEntry.idTestGroup })) aoActions.append( WuiTmLink( 'Clone', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionTestGroupClone, TestGroupData.ksParam_idTestGroup: oEntry.idTestGroup, WuiAdmin.ksParamEffectiveDate: self._tsEffectiveDate, })) aoActions.append( WuiTmLink( 'Remove', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionTestGroupDoRemove, TestGroupData.ksParam_idTestGroup: oEntry.idTestGroup }, sConfirm='Do you really want to remove test group #%d?' % (oEntry.idTestGroup, ))) else: aoActions.append( WuiTmLink( 'Clone', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionTestGroupClone, TestGroupData.ksParam_idTestGroup: oEntry.idTestGroup, WuiAdmin.ksParamEffectiveDate: self._tsEffectiveDate, })) return [ oEntry.idTestGroup, oEntry.sName, oEntry.sDescription if oEntry.sDescription is not None else '', oTestCases, self._formatCommentCell(oEntry.sComment, cMaxLines=max(3, len(oEntry.aoMembers) * 2)), aoActions ]
def __init__(self, idTestSet, sName = WuiContentBase.ksShortDetailsLink, fBracketed = False): WuiTmLink.__init__(self, sName, WuiMain.ksScriptName, { WuiMain.ksParamAction: WuiMain.ksActionTestResultDetails, TestSetData.ksParam_idTestSet: idTestSet, }, fBracketed = fBracketed); self.idTestSet = idTestSet;
def _generateNavigation(self, cbFile): """Generate the HTML for the log navigation.""" dParams = { WuiMain.ksParamAction: WuiMain.ksActionViewLog, WuiMain.ksParamLogSetId: self._oTestSet.idTestSet, WuiMain.ksParamLogFileId: self._oLogFile.idTestResultFile, WuiMain.ksParamLogChunkSize: self._cbChunk, WuiMain.ksParamLogChunkNo: self._iChunk, } # # The page walker. # dParams2 = dict(dParams) del dParams2[WuiMain.ksParamLogChunkNo] sHrefFmt = '<a href="?%s&%s=%%s" title="%%s">%%s</a>' \ % (webutils.encodeUrlParams(dParams2).replace('%', '%%'), WuiMain.ksParamLogChunkNo,) sHtmlWalker = self.genericPageWalker( self._iChunk, (cbFile + self._cbChunk - 1) // self._cbChunk, sHrefFmt, 11, 0, 'chunk') # # The chunk size selector. # dParams2 = dict(dParams) del dParams2[WuiMain.ksParamLogChunkSize] sHtmlSize = '<form name="ChunkSizeForm" method="GET">\n' \ ' Max <select name="%s" onchange="window.location=\'?%s&%s=\' + ' \ 'this.options[this.selectedIndex].value;" title="Max items per page">\n' \ % ( WuiMain.ksParamLogChunkSize, webutils.encodeUrlParams(dParams2), WuiMain.ksParamLogChunkSize,) for cbChunk in [ 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, 16777216 ]: sHtmlSize += ' <option value="%d" %s>%d bytes</option>\n' \ % (cbChunk, 'selected="selected"' if cbChunk == self._cbChunk else '', cbChunk) sHtmlSize += ' </select> per page\n' \ '</form>\n' # # Download links. # oRawLink = WuiTmLink( 'View Raw', '', { WuiMain.ksParamAction: WuiMain.ksActionGetFile, WuiMain.ksParamGetFileSetId: self._oTestSet.idTestSet, WuiMain.ksParamGetFileId: self._oLogFile.idTestResultFile, WuiMain.ksParamGetFileDownloadIt: False, }, sTitle='%u MiB' % ((cbFile + 1048576 - 1) // 1048576, )) oDownloadLink = WuiTmLink( 'Download Log', '', { WuiMain.ksParamAction: WuiMain.ksActionGetFile, WuiMain.ksParamGetFileSetId: self._oTestSet.idTestSet, WuiMain.ksParamGetFileId: self._oLogFile.idTestResultFile, WuiMain.ksParamGetFileDownloadIt: True, }, sTitle='%u MiB' % ((cbFile + 1048576 - 1) // 1048576, )) oTestSetLink = WuiTmLink( 'Test Set', '', { WuiMain.ksParamAction: WuiMain.ksActionTestResultDetails, TestSetData.ksParam_idTestSet: self._oTestSet.idTestSet, }) # # Combine the elements and return. # return '<div class="tmlogviewernavi">\n' \ ' <table width=100%>\n' \ ' <tr>\n' \ ' <td width=20%>\n' \ ' ' + oTestSetLink.toHtml() + '\n' \ ' ' + oRawLink.toHtml() + '\n' \ ' ' + oDownloadLink.toHtml() + '\n' \ ' </td>\n' \ ' <td width=60% align=center>' + sHtmlWalker + '</td>' \ ' <td width=20% align=right>' + sHtmlSize + '</td>\n' \ ' </tr>\n' \ ' </table>\n' \ '</div>\n'
def _formatListEntry(self, iEntry): """ Format *show all* table entry """ oEntry = self._aoEntries[iEntry]; from testmanager.webui.wuiadmin import WuiAdmin; from testmanager.webui.wuireport import WuiReportSummaryLink; oValidationKit = None; if oEntry.idBuildTestSuite is not None: oValidationKit = WuiTmLink('r%s' % (oEntry.iRevisionTestSuite,), WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionBuildDetails, BuildData.ksParam_idBuild: oEntry.idBuildTestSuite }, fBracketed = False); aoTestSetLinks = []; aoTestSetLinks.append(WuiTmLink(oEntry.enmStatus, WuiMain.ksScriptName, { WuiMain.ksParamAction: WuiMain.ksActionTestResultDetails, TestSetData.ksParam_idTestSet: oEntry.idTestSet }, fBracketed = False)); if oEntry.cErrors > 0: aoTestSetLinks.append(WuiRawHtml('-')); aoTestSetLinks.append(WuiTmLink('%d error%s' % (oEntry.cErrors, '' if oEntry.cErrors == 1 else 's', ), WuiMain.ksScriptName, { WuiMain.ksParamAction: WuiMain.ksActionTestResultDetails, TestSetData.ksParam_idTestSet: oEntry.idTestSet }, sFragmentId = 'failure-0', fBracketed = False)); self._dTestBoxLinkParams[WuiMain.ksParamGroupMemberId] = oEntry.idTestBox; self._dTestCaseLinkParams[WuiMain.ksParamGroupMemberId] = oEntry.idTestCase; self._dRevLinkParams[WuiMain.ksParamGroupMemberId] = oEntry.iRevision; sTestBoxTitle = u''; if oEntry.sCpuVendor is not None: sTestBoxTitle += 'CPU vendor:\t%s\n' % ( oEntry.sCpuVendor, ); if oEntry.sCpuName is not None: sTestBoxTitle += 'CPU name:\t%s\n' % ( ' '.join(oEntry.sCpuName.split()), ); if oEntry.sOsVersion is not None: sTestBoxTitle += 'OS version:\t%s\n' % ( oEntry.sOsVersion, ); asFeatures = []; if oEntry.fCpuHwVirt is True: asFeatures.append(u'HW\u2011Virt'); if oEntry.fCpuNestedPaging is True: asFeatures.append(u'Nested\u2011Paging'); if oEntry.fCpu64BitGuest is True: asFeatures.append(u'64\u2011bit\u2011Guest'); #if oEntry.fChipsetIoMmu is True: asFeatures.append(u'I/O\u2011MMU'); sTestBoxTitle += u'CPU features:\t' + u', '.join(asFeatures); # Testcase if oEntry.sSubName is not None and len(oEntry.sSubName) > 0: sTestCaseName = '%s / %s' % (oEntry.sTestCaseName, oEntry.sSubName,); else: sTestCaseName = oEntry.sTestCaseName; # Reason: aoReasons = []; for oIt in oEntry.aoFailureReasons: sReasonTitle = 'Reason: \t%s\n' % ( oIt.oFailureReason.sShort, ); sReasonTitle += 'Category:\t%s\n' % ( oIt.oFailureReason.oCategory.sShort, ); sReasonTitle += 'Assigned:\t%s\n' % ( self.formatTsShort(oIt.tsFailureReasonAssigned), ); sReasonTitle += 'By User: \t%s\n' % ( oIt.oFailureReasonAssigner.sUsername, ); if oIt.sFailureReasonComment is not None and len(oIt.sFailureReasonComment) > 0: sReasonTitle += 'Comment: \t%s\n' % ( oIt.sFailureReasonComment, ); if oIt.oFailureReason.iTicket is not None and oIt.oFailureReason.iTicket > 0: sReasonTitle += 'xTracker:\t#%s\n' % ( oIt.oFailureReason.iTicket, ); for i, sUrl in enumerate(oIt.oFailureReason.asUrls): sUrl = sUrl.strip(); if len(sUrl) > 0: sReasonTitle += 'URL#%u: \t%s\n' % ( i, sUrl, ); aoReasons.append(WuiTmLink(oIt.oFailureReason.sShort, WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionFailureReasonDetails, FailureReasonData.ksParam_idFailureReason: oIt.oFailureReason.idFailureReason }, sTitle = sReasonTitle)); return [ oEntry.tsCreated, [ WuiTmLink('%s %s (%s)' % (oEntry.sProduct, oEntry.sVersion, oEntry.sType,), WuiMain.ksScriptName, self._dRevLinkParams, sTitle = '%s' % (oEntry.sBranch,), fBracketed = False), WuiSvnLinkWithTooltip(oEntry.iRevision, 'vbox'), ## @todo add sRepository TestResultListingData WuiTmLink(self.ksShortDetailsLink, WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionBuildDetails, BuildData.ksParam_idBuild: oEntry.idBuild }, fBracketed = False), ], oValidationKit, [ WuiTmLink(oEntry.sTestBoxName, WuiMain.ksScriptName, self._dTestBoxLinkParams, fBracketed = False, sTitle = sTestBoxTitle), WuiTmLink(self.ksShortDetailsLink, WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionTestBoxDetails, TestBoxData.ksParam_idTestBox: oEntry.idTestBox }, fBracketed = False), WuiReportSummaryLink(ReportModelBase.ksSubTestBox, oEntry.idTestBox, fBracketed = False), ], '%s.%s' % (oEntry.sOs, oEntry.sArch), [ WuiTmLink(sTestCaseName, WuiMain.ksScriptName, self._dTestCaseLinkParams, fBracketed = False, sTitle = (oEntry.sBaseCmd + ' ' + oEntry.sArgs) if oEntry.sArgs else oEntry.sBaseCmd), WuiTmLink(self.ksShortDetailsLink, WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionTestCaseDetails, TestCaseData.ksParam_idTestCase: oEntry.idTestCase }, fBracketed = False), WuiReportSummaryLink(ReportModelBase.ksSubTestCase, oEntry.idTestCase, fBracketed = False), ], oEntry.tsElapsed, aoTestSetLinks, aoReasons ];
def _formatListEntry(self, iEntry): oEntry = self._aoEntries[iEntry] from testmanager.webui.wuiadmin import WuiAdmin aoRet = \ [ oEntry.sName.replace('-', u'\u2011'), 'Enabled' if oEntry.fEnabled else 'Disabled', utils.formatIntervalSeconds(oEntry.cSecTimeout), ] # Base command and variations. fNoGang = True fNoSubName = True fAllDefaultTimeouts = True for oVar in oEntry.aoTestCaseArgs: if fNoSubName and oVar.sSubName is not None and len( oVar.sSubName.strip()) > 0: fNoSubName = False if oVar.cGangMembers > 1: fNoGang = False if oVar.cSecTimeout is not None: fAllDefaultTimeouts = False sHtml = ' <table class="tminnertbl" width=100%>\n' \ ' <tr>\n' \ ' ' if not fNoSubName: sHtml += '<th class="tmtcasubname">Sub-name</th>' if not fNoGang: sHtml += '<th class="tmtcagangsize">Gang Size</th>' if not fAllDefaultTimeouts: sHtml += '<th class="tmtcatimeout">Timeout</th>' sHtml += '<th>Additional Arguments</b></th>\n' \ ' </tr>\n' for oTmp in oEntry.aoTestCaseArgs: sHtml += '<tr>' if not fNoSubName: sHtml += '<td>%s</td>' % (webutils.escapeElem(oTmp.sSubName) if oTmp.sSubName is not None else '') if not fNoGang: sHtml += '<td>%d</td>' % (oTmp.cGangMembers, ) if not fAllDefaultTimeouts: sHtml += '<td>%s</td>' \ % (utils.formatIntervalSeconds(oTmp.cSecTimeout) if oTmp.cSecTimeout is not None else 'Default',) sHtml += u'<td>%s</td></tr>' \ % ( webutils.escapeElem(oTmp.sArgs.replace('-', u'\u2011')) if len(oTmp.sArgs) > 0 else u'\u2011',) sHtml += '</tr>\n' sHtml += ' </table>' aoRet.append( [oEntry.sBaseCmd.replace('-', u'\u2011'), WuiRawHtml(sHtml)]) # Next. aoRet += [ oEntry.sValidationKitZips if oEntry.sValidationKitZips is not None else '', ] # Show dependency on other testcases if oEntry.aoDepTestCases not in (None, []): sHtml = ' <ul class="tmshowall">\n' for sTmp in oEntry.aoDepTestCases: sHtml += ' <li class="tmshowall"><a href="%s?%s=%s&%s=%s">%s</a></li>\n' \ % (WuiAdmin.ksScriptName, WuiAdmin.ksParamAction, WuiAdmin.ksActionTestCaseEdit, TestCaseData.ksParam_idTestCase, sTmp.idTestCase, sTmp.sName) sHtml += ' </ul>\n' else: sHtml = '<ul class="tmshowall"><li class="tmshowall">None</li></ul>\n' aoRet.append(WuiRawHtml(sHtml)) # Show dependency on global resources if oEntry.aoDepGlobalResources not in (None, []): sHtml = ' <ul class="tmshowall">\n' for sTmp in oEntry.aoDepGlobalResources: sHtml += ' <li class="tmshowall"><a href="%s?%s=%s&%s=%s">%s</a></li>\n' \ % (WuiAdmin.ksScriptName, WuiAdmin.ksParamAction, WuiAdmin.ksActionGlobalRsrcShowEdit, GlobalResourceData.ksParam_idGlobalRsrc, sTmp.idGlobalRsrc, sTmp.sName) sHtml += ' </ul>\n' else: sHtml = '<ul class="tmshowall"><li class="tmshowall">None</li></ul>\n' aoRet.append(WuiRawHtml(sHtml)) # Comment (note). aoRet.append(self._formatCommentCell(oEntry.sComment)) # Show actions that can be taken. aoActions = [ WuiTmLink( 'Details', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionTestCaseDetails, TestCaseData.ksParam_idGenTestCase: oEntry.idGenTestCase }), ] if isDbTimestampInfinity(oEntry.tsExpire): aoActions.append( WuiTmLink( 'Modify', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionTestCaseEdit, TestCaseData.ksParam_idTestCase: oEntry.idTestCase })) aoActions.append( WuiTmLink( 'Clone', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionTestCaseClone, TestCaseData.ksParam_idGenTestCase: oEntry.idGenTestCase })) if isDbTimestampInfinity(oEntry.tsExpire): aoActions.append( WuiTmLink( 'Remove', WuiAdmin.ksScriptName, { WuiAdmin.ksParamAction: WuiAdmin.ksActionTestCaseDoRemove, TestCaseData.ksParam_idTestCase: oEntry.idTestCase }, sConfirm='Are you sure you want to remove test case #%d?' % (oEntry.idTestCase, ))) aoRet.append(aoActions) return aoRet