VirtualBox

Ignore:
Timestamp:
May 29, 2016 2:45:57 AM (9 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
107563
Message:

Bugfixes. Data structure unnecessary complicated now because I didn't want to play around with temp sql tables... anyways, it seems to work better.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/ValidationKit/testmanager/core/report.py

    r61270 r61271  
    221221
    222222
     223
    223224class ReportHitRowBase(object):
    224225    """ A row in a period. """
    225     def __init__(self, cHits, tsMin = None, tsMax = None):
     226    def __init__(self, idSubject, oSubject, cHits, tsMin = None, tsMax = None):
     227        self.idSubject          = idSubject;
     228        self.oSubject           = oSubject;
    226229        self.cHits              = cHits;
    227230        self.tsMin              = tsMin;
    228231        self.tsMax              = tsMax;
    229232
     233class ReportHitRowWithTotalBase(ReportHitRowBase):
     234    """ A row in a period. """
     235    def __init__(self, idSubject, oSubject, cHits, cTotal, tsMin = None, tsMax = None):
     236        ReportHitRowBase.__init__(self, idSubject, oSubject, cHits, tsMin, tsMax)
     237        self.cTotal             = cTotal;
     238        self.uPct               = cHits * 100 / cTotal;
     239
    230240class ReportFailureReasonRow(ReportHitRowBase):
    231241    """ The account of one failure reason for a period. """
    232242    def __init__(self, aoRow, oReason):
    233         ReportHitRowBase.__init__(self, aoRow[1], aoRow[2], aoRow[3]);
     243        ReportHitRowBase.__init__(self, aoRow[0], oReason, aoRow[1], aoRow[2], aoRow[3]);
    234244        self.idFailureReason    = aoRow[0];
    235245        self.oReason            = oReason;      # FailureReasonDataEx
    236246
    237 class ReportTestCaseFailureRow(ReportHitRowBase):
     247class ReportTestCaseFailureRow(ReportHitRowWithTotalBase):
    238248    """ The account of one test case for a period. """
    239     def __init__(self, aoRow, aoTestCase):
    240         ReportHitRowBase.__init__(self, aoRow[1], aoRow[2], aoRow[3]);
    241         self.idTestCase         = aoRow[0];
    242         self.aoTestCase         = aoTestCase;   # TestCaseDataEx
     249    def __init__(self, aoRow, oTestCase):
     250        ReportHitRowWithTotalBase.__init__(self, aoRow[0], oTestCase, aoRow[1], aoRow[4], aoRow[2], aoRow[3]);
    243251
    244252
     
    266274        self.aoRows.append(oRow);
    267275        self.dRowsById[idRow] = oRow;
    268 
     276        if idRow not in self.oSet.dSubjects:
     277            self.oSet.dSubjects[idRow] = oData;
     278        self._doStatsForRow(oRow, idRow, oData);
     279
     280    def _doStatsForRow(self, oRow, idRow, oData):
     281        """ Does the statistics for a row. Helper for appendRow as well as helpRecalcStats. """
    269282        if oRow.tsMin is not None and oRow.tsMin < self.tsMin:
    270283            self.tsMin = oRow.tsMin;
     
    278291            self.cMinHits = oRow.cHits;
    279292
    280         if idRow in self.oSet.dcTotalsPerId:
    281             self.oSet.dcTotalsPerId[idRow] += oRow.cHits;
     293        if idRow in self.oSet.dcHitsPerId:
     294            self.oSet.dcHitsPerId[idRow] += oRow.cHits;
    282295        else:
    283             self.dFirst[idRow]              = oData;
    284             self.oSet.dSubjects[idRow]      = oData;
    285             self.oSet.dcTotalsPerId[idRow]  = oRow.cHits;
    286             self.oSet.diPeriodFirst[idRow]  = self.iPeriod;
    287         self.oSet.diPeriodLast[idRow]       = self.iPeriod;
     296            self.oSet.dcHitsPerId[idRow]  = oRow.cHits;
     297
     298        if oRow.cHits > 0:
     299            if idRow not in self.oSet.diPeriodFirst:
     300                self.dFirst[idRow]              = oData;
     301                self.oSet.diPeriodFirst[idRow]  = self.iPeriod;
     302            self.oSet.diPeriodLast[idRow]       = self.iPeriod;
     303
     304    def helperSetRecalcStats(self):
     305        """ Recalc the statistics (do resetStats first on set). """
     306        for idRow, oRow in self.dRowsById.items():
     307            self._doStatsForRow(oRow, idRow, self.oSet.dSubjects[idRow]);
     308
     309    def helperSetResetStats(self):
     310        """ Resets the statistics. """
     311        self.tsMin      = self.tsEnd;
     312        self.tsMax      = self.tsStart;
     313        self.cHits      = 0;
     314        self.cMaxHits   = 0;
     315        self.cMinHits   = 99999999;
     316        self.dFirst     = {};
     317        self.dLast      = {};
     318
     319    def helperSetDeleteKeyFromSet(self, idKey):
     320        """ Helper for ReportPeriodSetBase::deleteKey """
     321        if idKey in self.dRowsById:
     322            oRow = self.dRowsById[idKey];
     323            self.aoRows.remove(oRow);
     324            del self.dRowsById[idKey]
     325            self.cHits -= oRow.cHits;
     326            if idKey in self.dFirst:
     327                del self.dFirst[idKey];
     328            if idKey in self.dLast:
     329                del self.dLast[idKey];
     330
     331class ReportPeriodWithTotalBase(ReportPeriodBase):
     332    """ In addition to the cHits, we also have a total to relate it too. """
     333    def __init__(self, oSet, iPeriod, sDesc, tsFrom, tsTo):
     334        ReportPeriodBase.__init__(self, oSet, iPeriod, sDesc, tsFrom, tsTo);
     335        self.cTotal             = 0;
     336        self.cMinTotal          = 0;
     337        self.cMaxTotal          = 99999999;
     338
     339    def _doStatsForRow(self, oRow, idRow, oData):
     340        assert isinstance(oRow, ReportHitRowWithTotalBase);
     341        super(ReportPeriodWithTotalBase, self)._doStatsForRow(oRow, idRow, oData);
     342        self.cTotal += oRow.cTotal;
     343        if oRow.cTotal > self.cMaxTotal:
     344            self.cMaxTotal = oRow.cTotal;
     345        if oRow.cTotal < self.cMinTotal:
     346            self.cMinTotal = oRow.cTotal;
     347        if idRow in self.oSet.dcTotalPerId:
     348            self.oSet.dcTotalPerId[idRow] += oRow.cTotal;
     349        else:
     350            self.oSet.dcTotalPerId[idRow]  = oRow.cTotal;
     351
     352    def helperSetResetStats(self):
     353        super(ReportPeriodWithTotalBase, self).helperSetResetStats();
     354        self.cTotal             = 0;
     355        self.cMinTotal          = 0;
     356        self.cMaxTotal          = 99999999;
    288357
    289358class ReportFailureReasonPeriod(ReportPeriodBase):
     
    293362        self.cWithoutReason     = 0;            # Number of failed test sets without any assigned reason.
    294363
    295 class ReportTestCaseFailurePeriod(ReportPeriodBase):
     364class ReportTestCaseFailurePeriod(ReportPeriodWithTotalBase):
    296365    """ A period in ReportTestCaseFailureSet. """
    297366    def __init__(self, oSet, iPeriod, sDesc, tsFrom, tsTo):
    298         ReportPeriodBase.__init__(self, oSet, iPeriod, sDesc, tsFrom, tsTo);
     367        ReportPeriodWithTotalBase.__init__(self, oSet, iPeriod, sDesc, tsFrom, tsTo);
     368
    299369
    300370
     
    304374        self.sIdAttr            = sIdAttr;      # The name of the key attribute.  Mainly for documentation purposes.
    305375        self.aoPeriods          = [];           # Periods (ReportPeriodBase descendant) in ascending order (time wise).
    306         self.dcTotalsPerId      = {};           # Totals per subject ID (key).
    307376        self.dSubjects          = {};           # The subject data objects, keyed by the subject ID.
    308         self.cHits              = 0;            # Total number of hits in all periods and all reasons.
     377        self.dcHitsPerId        = {};           # Sum hits per subject ID (key).
     378        self.cHits              = 0;            # Sum number of hits in all periods and all reasons.
    309379        self.cMaxHits           = 0;            # Max hits in a row.
    310380        self.cMinHits           = 0;            # Min hits in a row.
     
    322392        assert isinstance(oPeriod, ReportPeriodBase);
    323393        self.aoPeriods.append(oPeriod);
    324 
     394        self._doStatsForPeriod(oPeriod);
     395
     396    def _doStatsForPeriod(self, oPeriod):
     397        """ Worker for appendPeriod and recalcStats. """
    325398        self.cHits += oPeriod.cHits;
    326399        if oPeriod.cHits > self.cMaxHits:
     
    333406        if len(oPeriod.aoRows) < self.cMinHits:
    334407            self.cMinHits = len(oPeriod.aoRows);
     408
     409    def recalcStats(self):
     410        """ Recalculates the statistics. ASSUMES finalizePass1 hasn't been done yet. """
     411        self.cHits          = 0;
     412        self.cMaxHits       = 0;
     413        self.cMinHits       = 0;
     414        self.cMaxRows       = 0;
     415        self.cMinRows       = 0;
     416        self.diPeriodFirst  = {};
     417        self.diPeriodLast   = {};
     418        self.dcHitsPerId    = {};
     419        for oPeriod in self.aoPeriods:
     420            oPeriod.helperSetResetStats();
     421
     422        for oPeriod in self.aoPeriods:
     423            oPeriod.helperSetRecalcStats();
     424            self._doStatsForPeriod(oPeriod);
     425
     426    def deleteKey(self, idKey):
     427        """ Deletes a key from the set.  May leave cMaxHits and cMinHits with outdated values. """
     428        self.cHits -= self.dcHitsPerId[idKey];
     429        del self.dcHitsPerId[idKey];
     430        if idKey in self.diPeriodFirst:
     431            del self.diPeriodFirst[idKey];
     432        if idKey in self.diPeriodLast:
     433            del self.diPeriodLast[idKey];
     434        if idKey in self.aoEnterInfo:
     435            del self.aoEnterInfo[idKey];
     436        if idKey in self.aoLeaveInfo:
     437            del self.aoLeaveInfo[idKey];
     438        del self.dSubjects[idKey];
     439        for oPeriod in self.aoPeriods:
     440            oPeriod.helperSetDeleteKeyFromSet(idKey);
     441
     442    def pruneRowsWithZeroSumHits(self):
     443        """ Discards rows with zero sum hits across all periods.  Works around lazy selects counting both totals and hits. """
     444        fDeleted = False;
     445        aidKeys  = self.dcHitsPerId.keys();
     446        for idKey in aidKeys:
     447            if self.dcHitsPerId[idKey] == 0:
     448                self.deleteKey(idKey);
     449                fDeleted = True;
     450        if fDeleted:
     451            self.recalcStats();
    335452
    336453    def finalizePass1(self):
     
    347464        return self;
    348465
     466class ReportPeriodSetWithTotalBase(ReportPeriodSetBase):
     467    """ In addition to the cHits, we also have a total to relate it too. """
     468    def __init__(self, sIdAttr):
     469        ReportPeriodSetBase.__init__(self, sIdAttr);
     470        self.dcTotalPerId       = {};           # Sum total per subject ID (key).
     471        self.cTotal             = 0;            # Sum number of total in all periods and all reasons.
     472        self.cMaxTotal          = 0;            # Max total in a row.
     473        self.cMinTotal          = 0;            # Min total in a row.
     474
     475    def _doStatsForPeriod(self, oPeriod):
     476        assert isinstance(oPeriod, ReportPeriodWithTotalBase);
     477        super(ReportPeriodSetWithTotalBase, self)._doStatsForPeriod(oPeriod);
     478        self.cTotal += oPeriod.cTotal;
     479        if oPeriod.cTotal > self.cMaxTotal:
     480            self.cMaxTotal = oPeriod.cTotal;
     481        if oPeriod.cTotal < self.cMinTotal:
     482            self.cMinTotal = oPeriod.cTotal;
     483
     484    def recalcStats(self):
     485        self.dcTotalPerId       = {};
     486        self.cTotal             = 0;
     487        self.cMaxTotal          = 0;
     488        self.cMinTotal          = 0;
     489        super(ReportPeriodSetWithTotalBase, self).recalcStats();
     490
     491    def deleteKey(self, idKey):
     492        self.cTotal -= self.dcTotalPerId[idKey];
     493        del self.dcTotalPerId[idKey];
     494        super(ReportPeriodSetWithTotalBase, self).recalcStats();
     495
    349496class ReportFailureReasonSet(ReportPeriodSetBase):
    350497    """ What ReportLazyModel.getFailureReasons returns. """
     
    352499        ReportPeriodSetBase.__init__(self, 'idFailureReason');
    353500
    354 class ReportTestCaseFailureSet(ReportPeriodSetBase):
     501class ReportTestCaseFailureSet(ReportPeriodSetWithTotalBase):
    355502    """ What ReportLazyModel.getTestCaseFailures returns. """
    356503    def __init__(self):
    357         ReportPeriodSetBase.__init__(self, 'idTestCase');
    358 
     504        ReportPeriodSetWithTotalBase.__init__(self, 'idTestCase');
    359505
    360506
     
    570716        for iPeriod in xrange(self.cPeriods):
    571717            self._oDb.execute('SELECT   idTestCase,\n'
    572                               '         COUNT(idTestResult),\n'
     718                              '         COUNT(CASE WHEN enmStatus >= \'failure\' THEN 1 END),\n'
    573719                              '         MIN(tsDone),\n'
    574                               '         MAX(tsDone)\n'
     720                              '         MAX(tsDone),\n'
     721                              '         COUNT(idTestResult)\n'
    575722                              'FROM     TestSets\n'
    576723                              'WHERE    TRUE\n'
     
    588735
    589736            oSet.appendPeriod(oPeriod);
     737        oSet.pruneRowsWithZeroSumHits();
    590738
    591739
     
    635783                          'WHERE    TestSets.idTestCase       = %s\n'
    636784                          '     AND TestSets.idBuild          = Builds.idBuild\n'
    637                           '     AND Builds.tsExpire             > TestSets.tsCreated\n'
    638                           '     AND Builds.tsEffective         <= TestSets.tsCreated\n'
    639                           '     AND Builds.idBuildCategory      = BuildCategories.idBuildCategory\n'
     785                          '     AND TestSets.enmStatus       >= \'failure\'\n'
     786                          + self.getExtraWhereExprForPeriod(iPeriod) +
     787                          '     AND Builds.tsExpire           > TestSets.tsCreated\n'
     788                          '     AND Builds.tsEffective       <= TestSets.tsCreated\n'
     789                          '     AND Builds.idBuildCategory    = BuildCategories.idBuildCategory\n'
    640790                          'ORDER BY Builds.iRevision ' + sSorting + ',\n'
    641791                          '         TestSets.tsCreated ' + sSorting + '\n'
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette