Changeset 65054 in vbox for trunk/src/VBox/ValidationKit
- Timestamp:
- Jan 2, 2017 9:20:49 PM (8 years ago)
- Location:
- trunk/src/VBox/ValidationKit/testmanager
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/ValidationKit/testmanager/core/report.py
r62484 r65054 38 38 from testmanager.core.testcase import TestCaseLogic; 39 39 from testmanager.core.testcaseargs import TestCaseArgsLogic; 40 from testmanager.core.testresults import TestResultLogic, TestResultFilter; 40 41 from common import constants; 42 43 44 45 class ReportFilter(TestResultFilter): 46 """ 47 Same as TestResultFilter for now. 48 """ 49 50 def __init__(self): 51 TestResultFilter.__init__(self); 41 52 42 53 … … 73 84 74 85 75 def __init__(self, oDb, tsNow, cPeriods, cHoursPerPeriod, sSubject, aidSubjects ):86 def __init__(self, oDb, tsNow, cPeriods, cHoursPerPeriod, sSubject, aidSubjects, oFilter): 76 87 ModelLogicBase.__init__(self, oDb); 77 88 # Public so the report generator can easily access them. … … 82 93 self.sSubject = sSubject; 83 94 self.aidSubjects = aidSubjects; 95 self.oFilter = oFilter; 84 96 85 97 def getExtraSubjectTables(self): 86 98 """ 87 Returns a string with any extra tables needed by the subject. Each 88 table name is prefixed by a comma, so can be appended to a FROM 89 statement. 90 """ 91 return ''; 99 Returns a list of additional tables needed by the subject. 100 """ 101 return []; 92 102 93 103 def getExtraSubjectWhereExpr(self): … … 527 537 """ 528 538 539 sBaseQuery = 'SELECT TestSets.enmStatus, COUNT(TestSets.idTestSet)\n' \ 540 'FROM TestSets\n' \ 541 + self.oFilter.getTableJoins(); 542 for sTable in self.getExtraSubjectTables(): 543 sBaseQuery = sBaseQuery[:-1] + ',\n ' + sTable + '\n'; 544 sBaseQuery += 'WHERE enmStatus <> \'running\'\n' \ 545 + self.oFilter.getWhereConditions() \ 546 + self.getExtraSubjectWhereExpr(); 547 529 548 adPeriods = []; 530 549 for iPeriod in xrange(self.cPeriods): 531 self._oDb.execute('SELECT enmStatus, COUNT(TestSets.idTestSet)\n' 532 'FROM TestSets' + self.getExtraSubjectTables() +'\n' 533 'WHERE enmStatus <> \'running\'\n' 534 + self.getExtraSubjectWhereExpr() 535 + self.getExtraWhereExprForPeriod(iPeriod) 536 + 537 'GROUP BY enmStatus\n'); 550 self._oDb.execute(sBaseQuery + self.getExtraWhereExprForPeriod(iPeriod) + 'GROUP BY enmStatus\n'); 538 551 539 552 dRet = \ … … 567 580 oFailureReasonLogic = FailureReasonLogic(self._oDb); 568 581 582 # 569 583 # Create a temporary table 584 # 570 585 sTsNow = 'CURRENT_TIMESTAMP' if self.tsNow is None else self._oDb.formatBindArgs('%s::TIMESTAMP', (self.tsNow,)); 571 586 sTsFirst = '(%s - interval \'%s hours\')' \ 572 587 % (sTsNow, self.cHoursPerPeriod * self.cPeriods,); 573 self._oDb.execute('CREATE TEMPORARY TABLE TmpReasons ON COMMIT DROP AS\n' 574 'SELECT TestResultFailures.idFailureReason AS idFailureReason,\n' 575 ' TestResultFailures.idTestResult AS idTestResult,\n' 576 ' TestSets.idTestSet AS idTestSet,\n' 577 ' TestSets.tsDone AS tsDone,\n' 578 ' TestSets.tsCreated AS tsCreated,\n' 579 ' TestSets.idBuild AS idBuild\n' 580 'FROM TestResultFailures,\n' 581 ' TestResults,\n' 582 ' TestSets' + self.getExtraSubjectTables() + '\n' 583 'WHERE TestResultFailures.idTestResult = TestResults.idTestResult\n' 584 ' AND TestResultFailures.tsExpire = \'infinity\'::TIMESTAMP\n' 585 ' AND TestResultFailures.tsEffective >= ' + sTsFirst + '\n' 586 ' AND TestResults.enmStatus <> \'running\'\n' 587 ' AND TestResults.enmStatus <> \'success\'\n' 588 ' AND TestResults.tsCreated >= ' + sTsFirst + '\n' 589 ' AND TestResults.tsCreated < ' + sTsNow + '\n' 590 ' AND TestResults.idTestSet = TestSets.idTestSet\n' 591 ' AND TestSets.tsDone >= ' + sTsFirst + '\n' 592 ' AND TestSets.tsDone < ' + sTsNow + '\n' 593 + self.getExtraSubjectWhereExpr()); 588 sQuery = 'CREATE TEMPORARY TABLE TmpReasons ON COMMIT DROP AS\n' \ 589 'SELECT TestResultFailures.idFailureReason AS idFailureReason,\n' \ 590 ' TestResultFailures.idTestResult AS idTestResult,\n' \ 591 ' TestSets.idTestSet AS idTestSet,\n' \ 592 ' TestSets.tsDone AS tsDone,\n' \ 593 ' TestSets.tsCreated AS tsCreated,\n' \ 594 ' TestSets.idBuild AS idBuild\n' \ 595 'FROM TestResultFailures,\n' \ 596 ' TestResults,\n' \ 597 ' TestSets\n' \ 598 + self.oFilter.getTableJoins(dOmitTables = {'TestResults': True, 'TestResultFailures': True}); 599 for sTable in self.getExtraSubjectTables(): 600 if sTable not in [ 'TestResults', 'TestResultFailures' ] and not self.oFilter.isJoiningWithTable(sTable): 601 sQuery = sQuery[:-1] + ',\n ' + sTable + '\n'; 602 sQuery += 'WHERE TestResultFailures.idTestResult = TestResults.idTestResult\n' \ 603 ' AND TestResultFailures.tsExpire = \'infinity\'::TIMESTAMP\n' \ 604 ' AND TestResultFailures.tsEffective >= ' + sTsFirst + '\n' \ 605 ' AND TestResults.enmStatus <> \'running\'\n' \ 606 ' AND TestResults.enmStatus <> \'success\'\n' \ 607 ' AND TestResults.tsCreated >= ' + sTsFirst + '\n' \ 608 ' AND TestResults.tsCreated < ' + sTsNow + '\n' \ 609 ' AND TestResults.idTestSet = TestSets.idTestSet\n' \ 610 ' AND TestSets.tsDone >= ' + sTsFirst + '\n' \ 611 ' AND TestSets.tsDone < ' + sTsNow + '\n' \ 612 + self.oFilter.getWhereConditions() \ 613 + self.getExtraSubjectWhereExpr(); 614 self._oDb.execute(sQuery); 594 615 self._oDb.execute('SELECT idFailureReason FROM TmpReasons;'); 595 616 617 # 596 618 # Retrieve the period results. 619 # 597 620 oSet = ReportFailureReasonSet(); 598 621 for iPeriod in xrange(self.cPeriods): … … 735 758 oSet = ReportPeriodSetWithTotalBase(sIdColumn if sIdAttr is None else sIdAttr); 736 759 760 # Construct base query. 761 sBaseQuery = 'SELECT TestSets.' + sIdColumn + ',\n' \ 762 ' COUNT(CASE WHEN TestSets.enmStatus >= \'failure\' THEN 1 END),\n' \ 763 ' MIN(TestSets.tsDone),\n' \ 764 ' MAX(TestSets.tsDone),\n' \ 765 ' COUNT(TestSets.idTestResult)\n' \ 766 'FROM TestSets\n' \ 767 + self.oFilter.getTableJoins(); 768 for sTable in self.getExtraSubjectTables(): 769 sBaseQuery = sBaseQuery[:-1] + ',\n ' + sTable + '\n'; 770 sBaseQuery += 'WHERE TRUE\n' \ 771 + self.oFilter.getWhereConditions() \ 772 + self.getExtraSubjectWhereExpr() + '\n'; 773 737 774 # Retrieve the period results. 738 775 for iPeriod in xrange(self.cPeriods): 739 self._oDb.execute('SELECT ' + sIdColumn + ',\n' 740 ' COUNT(CASE WHEN enmStatus >= \'failure\' THEN 1 END),\n' 741 ' MIN(tsDone),\n' 742 ' MAX(tsDone),\n' 743 ' COUNT(idTestResult)\n' 744 'FROM TestSets' + self.getExtraSubjectTables() + '\n' 745 'WHERE TRUE\n' 746 + self.getExtraWhereExprForPeriod(iPeriod) 747 + self.getExtraSubjectWhereExpr() + '\n' 748 'GROUP BY ' + sIdColumn + '\n'); 776 self._oDb.execute(sBaseQuery + self.getExtraWhereExprForPeriod(iPeriod) + 'GROUP BY TestSets.' + sIdColumn + '\n'); 749 777 aaoRows = self._oDb.fetchAll() 750 778 … … 797 825 """ 798 826 sSorting = 'ASC' if fEnter else 'DESC'; 799 self._oDb.execute('SELECT TestSets.idTestResult,\n' 800 ' TestSets.idTestSet,\n' 801 ' TestSets.tsDone,\n' 802 ' TestSets.idBuild,\n' 803 ' Builds.iRevision,\n' 804 ' BuildCategories.sRepository\n' 805 'FROM TestSets,\n' 806 ' Builds,\n' 807 ' BuildCategories' + self.getExtraSubjectTables() + '\n' 808 'WHERE TestSets.' + sIdColumn + ' = %s\n' 809 ' AND TestSets.idBuild = Builds.idBuild\n' 810 ' AND TestSets.enmStatus >= \'failure\'\n' 811 + self.getExtraWhereExprForPeriod(iPeriod) + 812 ' AND Builds.tsExpire > TestSets.tsCreated\n' 813 ' AND Builds.tsEffective <= TestSets.tsCreated\n' 814 ' AND Builds.idBuildCategory = BuildCategories.idBuildCategory' 815 + self.getExtraSubjectWhereExpr() + '\n' 816 'ORDER BY Builds.iRevision ' + sSorting + ',\n' 817 ' TestSets.tsCreated ' + sSorting + '\n' 818 'LIMIT 1\n' 819 , ( idSubject, )); 827 sQuery = 'SELECT TestSets.idTestResult,\n' \ 828 ' TestSets.idTestSet,\n' \ 829 ' TestSets.tsDone,\n' \ 830 ' TestSets.idBuild,\n' \ 831 ' Builds.iRevision,\n' \ 832 ' BuildCategories.sRepository\n' \ 833 'FROM TestSets\n' \ 834 + self.oFilter.getTableJoins(dOmitTables = {'Builds': True, 'BuildCategories': True}); 835 sQuery = sQuery[:-1] + ',\n' \ 836 ' Builds,\n' \ 837 ' BuildCategories\n'; 838 for sTable in self.getExtraSubjectTables(): 839 if sTable not in [ 'Builds', 'BuildCategories' ] and not self.oFilter.isJoiningWithTable(sTable): 840 sQuery = sQuery[:-1] + ',\n ' + sTable + '\n'; 841 sQuery += 'WHERE TestSets.' + sIdColumn + ' = ' + str(idSubject) + '\n' \ 842 ' AND TestSets.idBuild = Builds.idBuild\n' \ 843 ' AND TestSets.enmStatus >= \'failure\'\n' \ 844 + self.getExtraWhereExprForPeriod(iPeriod) + \ 845 ' AND Builds.tsExpire > TestSets.tsCreated\n' \ 846 ' AND Builds.tsEffective <= TestSets.tsCreated\n' \ 847 ' AND Builds.idBuildCategory = BuildCategories.idBuildCategory\n' \ 848 + self.oFilter.getWhereConditions() \ 849 + self.getExtraSubjectWhereExpr() + '\n' \ 850 'ORDER BY Builds.iRevision ' + sSorting + ',\n' \ 851 ' TestSets.tsCreated ' + sSorting + '\n' \ 852 'LIMIT 1\n'; 853 self._oDb.execute(sQuery); 820 854 aoRow = self._oDb.fetchOne(); 821 855 if aoRow is None: … … 826 860 iPeriod = iPeriod, fEnter = fEnter, idSubject = idSubject, oSubject = oSubject); 827 861 828 862 def fetchPossibleFilterOptions(self, oFilter, tsNow, sPeriod): 863 """ 864 Fetches possible filtering options. 865 """ 866 return TestResultLogic(self._oDb).fetchPossibleFilterOptions(oFilter, tsNow, sPeriod); 829 867 830 868 -
trunk/src/VBox/ValidationKit/testmanager/core/testresults.py
r65053 r65054 660 660 def __init__(self): 661 661 ModelFilterBase.__init__(self); 662 oCrit = FilterCriterion('Test status ', sVarNm = 'ts', sType = FilterCriterion.ksType_String,662 oCrit = FilterCriterion('Test statuses', sVarNm = 'ts', sType = FilterCriterion.ksType_String, 663 663 sTable = 'TestSets', sColumn = 'enmStatus'); 664 oCrit.aoPossible = (665 FilterCriterionValueAndDescription(TestResultData.ksTestStatus_Success, 'Success'),666 FilterCriterionValueAndDescription(TestResultData.ksTestStatus_Running, 'Running'),667 FilterCriterionValueAndDescription(TestResultData.ksTestStatus_Skipped, 'Skipped'),668 FilterCriterionValueAndDescription(TestResultData.ksTestStatus_Aborted, 'Aborted'),669 FilterCriterionValueAndDescription(TestResultData.ksTestStatus_Failure, 'Failure'),670 FilterCriterionValueAndDescription(TestResultData.ksTestStatus_TimedOut, 'Timed out'),671 FilterCriterionValueAndDescription(TestResultData.ksTestStatus_Rebooted, 'Rebooted'),672 );673 664 self.aCriteria.append(oCrit); 674 665 assert self.aCriteria[self.kiTestStatus] is oCrit; … … 695 686 assert self.aCriteria[self.kiRevisions] is oCrit; 696 687 697 oCrit = FilterCriterion('CPU Arches', sVarNm = 'ca', sTable = 'TestBoxesWithStrings', sColumn = 'idStrCpuArch');688 oCrit = FilterCriterion('CPU arches', sVarNm = 'ca', sTable = 'TestBoxesWithStrings', sColumn = 'idStrCpuArch'); 698 689 self.aCriteria.append(oCrit); 699 690 assert self.aCriteria[self.kiCpuArches] is oCrit; 700 691 701 oCrit = FilterCriterion('CPU Vendor', sVarNm = 'cv', sTable = 'TestBoxesWithStrings', sColumn = 'idStrCpuVendor');692 oCrit = FilterCriterion('CPU vendors', sVarNm = 'cv', sTable = 'TestBoxesWithStrings', sColumn = 'idStrCpuVendor'); 702 693 self.aCriteria.append(oCrit); 703 694 assert self.aCriteria[self.kiCpuVendors] is oCrit; … … 711 702 assert self.aCriteria[self.kiOsVersions] is oCrit; 712 703 713 oCrit = FilterCriterion('Failure Reasons', sVarNm = 'fr', sTable = 'TestResultFailures', sColumn = 'idFailureReason');704 oCrit = FilterCriterion('Failure reasons', sVarNm = 'fr', sTable = 'TestResultFailures', sColumn = 'idFailureReason'); 714 705 self.aCriteria.append(oCrit); 715 706 assert self.aCriteria[self.kiFailReasons] is oCrit; … … 731 722 return sQuery; 732 723 733 def getTableJoins(self, sExtraIndent = '', iOmit = -1 ):724 def getTableJoins(self, sExtraIndent = '', iOmit = -1, dOmitTables = None): 734 725 """ 735 726 Construct the WHERE conditions for the filter, optionally omitting one 736 727 criterion. 737 728 """ 729 afDone = { 'TestSets': True, }; 730 if dOmitTables is not None: 731 afDone.update(dOmitTables); 732 738 733 sQuery = ''; 739 afDone = { 'TestSets': True, };740 734 for iCrit, oCrit in enumerate(self.aCriteria): 741 735 if oCrit.sState == FilterCriterion.ksState_Selected \ … … 1455 1449 """ Does the tedious result fetching and handling of missing bits. """ 1456 1450 dLeft = { oValue: 1 for oValue in oCrit.aoSelected }; 1451 oCrit.aoPossible = []; 1457 1452 for aoRow in self._oDb.fetchAll(): 1458 1453 oCrit.aoPossible.append(FilterCriterionValueAndDescription(aoRow[0], aoRow[1])); … … 1471 1466 getattr(oMissing, sNameAttr), 1472 1467 fIrrelevant = True)); 1468 1469 # Statuses. 1470 oCrit = oFilter.aCriteria[TestResultFilter.kiTestStatus]; 1471 self._oDb.execute('SELECT TestSets.enmStatus, TestSets.enmStatus, COUNT(TestSets.idTestSet)\n' 1472 'FROM TestSets\n' + oFilter.getTableJoins(iOmit = TestResultFilter.kiTestStatus) + 1473 'WHERE ' + self._getTimePeriodQueryPart(tsNow, sPeriod) + 1474 oFilter.getWhereConditions(iOmit = TestResultFilter.kiTestStatus) + 1475 'GROUP BY TestSets.enmStatus\n' 1476 'ORDER BY TestSets.enmStatus\n'); 1477 workerDoFetch(None, fIdIsName = True); 1473 1478 1474 1479 # Scheduling groups (see getSchedGroups). … … 1599 1604 ' ON BuildCategories.idBuildCategory = BuildCategoryIDs.idBuildCategory\n' 1600 1605 'ORDER BY BuildCategories.sBranch DESC\n' ); 1601 workerDoFetch( BuildCategoryLogic, fIdIsName = True);1606 workerDoFetch(None, fIdIsName = True); 1602 1607 1603 1608 # Failure reasons. -
trunk/src/VBox/ValidationKit/testmanager/webui/wuimain.py
r65053 r65054 901 901 return True; 902 902 903 def _generateResultFilter(self, oFilter, oResultLogic, tsNow, sPeriod, enmResultsGroupingType , aoGroupMembers,904 fOnlyFailures , fOnlyNeedingReason):903 def _generateResultFilter(self, oFilter, oResultLogic, tsNow, sPeriod, enmResultsGroupingType = None, aoGroupMembers = None, 904 fOnlyFailures = False, fOnlyNeedingReason = False): 905 905 """ 906 906 Generates the result filter for the left hand side. … … 927 927 u' <dl>\n'; 928 928 929 for iCrit, oCrit in enumerate(oFilter.aCriteria):929 for oCrit in oFilter.aCriteria: 930 930 if len(oCrit.aoPossible) > 0: 931 931 sClass = 'sf-collapsable' if oCrit.sState == oCrit.ksState_Selected else 'sf-expandable'; … … 1188 1188 return self.ksDispatchRcAllDone; 1189 1189 1190 def _actionGenericReport(self, oModelType, o ReportType):1190 def _actionGenericReport(self, oModelType, oFilterType, oReportType): 1191 1191 """ 1192 1192 Generic report action. 1193 1193 oReportType is a child of WuiReportContentBase. 1194 oFilterType is a child of ModelFilterBase. 1194 1195 oModelType is a child of ReportModelBase. 1195 1196 """ … … 1207 1208 if aidSubjects is None: 1208 1209 raise WuiException('Missing parameter %s' % (self.ksParamReportSubjectIds,)); 1210 oFilter = oFilterType().initFromParams(self); 1209 1211 self._checkForUnknownParameters(); 1210 1212 … … 1217 1219 self.ksParamReportSubjectIds: aidSubjects, 1218 1220 }; 1219 1220 oModel = oModelType(self._oDb, tsEffective, cPeriods, cHoursPerPeriod, sSubject, aidSubjects); 1221 ## @todo oFilter. 1222 1223 oModel = oModelType(self._oDb, tsEffective, cPeriods, cHoursPerPeriod, sSubject, aidSubjects, oFilter); 1221 1224 oContent = oReportType(oModel, dParams, fSubReport = False, fnDPrint = self._oSrvGlue.dprint, oDisp = self); 1222 1225 (self._sPageTitle, self._sPageBody) = oContent.show(); 1223 1226 sNavi = self._generateReportNavigation(tsEffective, cHoursPerPeriod, cPeriods); 1224 1227 self._sPageBody = sNavi + self._sPageBody; 1228 1229 self._sPageFilter = self._generateResultFilter(oFilter, oModel, tsEffective, '%s hours' % (cHoursPerPeriod * cPeriods,)); 1225 1230 return True; 1226 1231 1227 1232 def _actionReportSummary(self): 1228 1233 """ Action wrapper. """ 1229 from testmanager.core.report import ReportLazyModel ;1234 from testmanager.core.report import ReportLazyModel, ReportFilter; 1230 1235 from testmanager.webui.wuireport import WuiReportSummary; 1231 return self._actionGenericReport(ReportLazyModel, WuiReportSummary);1236 return self._actionGenericReport(ReportLazyModel, ReportFilter, WuiReportSummary); 1232 1237 1233 1238 def _actionReportRate(self): 1234 1239 """ Action wrapper. """ 1235 from testmanager.core.report import ReportLazyModel ;1240 from testmanager.core.report import ReportLazyModel, ReportFilter; 1236 1241 from testmanager.webui.wuireport import WuiReportSuccessRate; 1237 return self._actionGenericReport(ReportLazyModel, WuiReportSuccessRate);1242 return self._actionGenericReport(ReportLazyModel, ReportFilter, WuiReportSuccessRate); 1238 1243 1239 1244 def _actionReportTestCaseFailures(self): 1240 1245 """ Action wrapper. """ 1241 from testmanager.core.report import ReportLazyModel ;1246 from testmanager.core.report import ReportLazyModel, ReportFilter; 1242 1247 from testmanager.webui.wuireport import WuiReportTestCaseFailures; 1243 return self._actionGenericReport(ReportLazyModel, WuiReportTestCaseFailures);1248 return self._actionGenericReport(ReportLazyModel, ReportFilter, WuiReportTestCaseFailures); 1244 1249 1245 1250 def _actionReportFailureReasons(self): 1246 1251 """ Action wrapper. """ 1247 from testmanager.core.report import ReportLazyModel ;1252 from testmanager.core.report import ReportLazyModel, ReportFilter; 1248 1253 from testmanager.webui.wuireport import WuiReportFailureReasons; 1249 return self._actionGenericReport(ReportLazyModel, WuiReportFailureReasons);1254 return self._actionGenericReport(ReportLazyModel, ReportFilter, WuiReportFailureReasons); 1250 1255 1251 1256 def _actionGraphWiz(self):
Note:
See TracChangeset
for help on using the changeset viewer.