VirtualBox

Changeset 65091 in vbox


Ignore:
Timestamp:
Jan 4, 2017 2:04:12 AM (8 years ago)
Author:
vboxsync
Message:

TestManager: Merged OS versions into the OS filter.

Location:
trunk/src/VBox/ValidationKit/testmanager
Files:
5 edited

Legend:

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

    r65080 r65091  
    11641164        self.sHover      = sHover;      ##< Optional hover/title string.
    11651165        self.fIrrelevant = fIrrelevant; ##< Irrelevant filter option, only present because it's selected
     1166        self.aoSubs      = [];          ##< References to FilterCriterion.oSub.aoPossible.
    11661167
    11671168
     
    11901191
    11911192    def __init__(self, sName, sVarNm = None, sType = ksType_UInt, sState = ksState_NotSelected, sKind = ksKind_AnyOf,
    1192                  sTable = None, sColumn = None):
     1193                 sTable = None, sColumn = None, oSub = None):
    11931194        assert len(sVarNm) in (2,3); # required by wuimain.py
    11941195        self.sName      = sName;
     
    11971198        self.sType      = sType;
    11981199        self.sKind      = sKind;
    1199         self.aoSelected = []; # Single value, any type.
    1200         self.aoPossible = []; # type: list[FilterCriterionValueAndDescription]
     1200        self.aoSelected = [];       ##< Single value, any type.
     1201        self.aoPossible = [];       ##< type: list[FilterCriterionValueAndDescription]
    12011202        self.sTable     = sTable;
    12021203        self.sColumn    = sColumn;
    1203         self.fExpanded  = None; ##< Tristate (None, False, True) indicating whether the criterion should be shown/hid regardless.
     1204        self.fExpanded  = None;     ##< Tristate (None, False, True)
     1205        self.oSub       = oSub;     ##< type: FilterCriterion
    12041206
    12051207
     
    12321234        self.aCriteria = []; # type: list[FilterCriterion]
    12331235
     1236    def _initFromParamsWorker(self, oDisp, oCriterion):
     1237        """ Worker for initFromParams. """
     1238        if oCriterion.sType == FilterCriterion.ksType_UInt:
     1239            oCriterion.aoSelected = oDisp.getListOfIntParams(oCriterion.sVarNm, iMin = 0, aiDefaults = []);
     1240        elif oCriterion.sType == FilterCriterion.ksType_String:
     1241            oCriterion.aoSelected = oDisp.getListOfStrParams(oCriterion.sVarNm, asDefaults = []);
     1242            if len(oCriterion.aoSelected) > 100:
     1243                raise TMExceptionBase('Variable %s has %u value, max allowed is 100!'
     1244                                      % (oCriterion.sVarNm, len(oCriterion.aoSelected)));
     1245            for sValue in oCriterion.aoSelected:
     1246                if   len(sValue) > 64 \
     1247                  or '\'' in sValue \
     1248                  or sValue[-1] == '\\':
     1249                    raise TMExceptionBase('Variable %s has an illegal value "%s"!' % (oCriterion.sVarNm, sValue));
     1250        else:
     1251            assert False;
     1252        if len(oCriterion.aoSelected) > 0:
     1253            oCriterion.sState     = FilterCriterion.ksState_Selected;
     1254        else:
     1255            oCriterion.sState     = FilterCriterion.ksState_NotSelected;
     1256
     1257        if oCriterion.oSub is not None:
     1258            self._initFromParamsWorker(oDisp, oCriterion.oSub);
     1259        return;
     1260
    12341261    def initFromParams(self, oDisp): # type: (WuiDispatcherBase) -> self
    12351262        """
     
    12401267
    12411268        for oCriterion in self.aCriteria:
    1242             if oCriterion.sType == FilterCriterion.ksType_UInt:
    1243                 oCriterion.aoSelected = oDisp.getListOfIntParams(oCriterion.sVarNm, iMin = 0, aiDefaults = []);
    1244             elif oCriterion.sType == FilterCriterion.ksType_String:
    1245                 oCriterion.aoSelected = oDisp.getListOfStrParams(oCriterion.sVarNm, asDefaults = []);
    1246                 if len(oCriterion.aoSelected) > 100:
    1247                     raise TMExceptionBase('Variable %s has %u value, max allowed is 100!'
    1248                                           % (oCriterion.sVarNm, len(oCriterion.aoSelected)));
    1249                 for sValue in oCriterion.aoSelected:
    1250                     if   len(sValue) > 64 \
    1251                       or '\'' in sValue \
    1252                       or sValue[-1] == '\\':
    1253                         raise TMExceptionBase('Variable %s has an illegal value "%s"!' % (oCriterion.sVarNm, sValue));
    1254             else:
    1255                 assert False;
    1256             if len(oCriterion.aoSelected) > 0:
    1257                 oCriterion.sState     = FilterCriterion.ksState_Selected;
    1258             else:
    1259                 oCriterion.sState     = FilterCriterion.ksState_NotSelected;
     1269            self._initFromParamsWorker(oDisp, oCriterion);
    12601270        return self;
    12611271
  • trunk/src/VBox/ValidationKit/testmanager/core/testresults.py

    r65084 r65091  
    660660    kiMisc                  = 12;
    661661    kiOses                  = 13;
    662     kiOsVersions            = 14;
    663     kiPythonVersions        = 15;
    664     kiFailReasons           = 16;
     662    kiPythonVersions        = 14;
     663    kiFailReasons           = 15;
    665664
    666665    kiMisc_NestedPaging     =  0;
     
    743742        assert self.aCriteria[self.kiMisc] is oCrit;
    744743
    745         oCrit = FilterCriterion('OSes', sVarNm = 'os', sTable = 'TestBoxesWithStrings', sColumn = 'idStrOs');
     744        oCrit = FilterCriterion('OS / Version', sVarNm = 'os', sTable = 'TestBoxesWithStrings', sColumn = 'idStrOs',
     745                                oSub = FilterCriterion('OS Versions', sVarNm = 'ov',
     746                                                       sTable = 'TestBoxesWithStrings', sColumn = 'idStrOsVersion'));
    746747        self.aCriteria.append(oCrit);
    747748        assert self.aCriteria[self.kiOses] is oCrit;
    748 
    749         oCrit = FilterCriterion('OS Versions', sVarNm = 'ov', sTable = 'TestBoxesWithStrings', sColumn = 'idStrOsVersion');
    750         self.aCriteria.append(oCrit);
    751         assert self.aCriteria[self.kiOsVersions] is oCrit;
    752749
    753750        oCrit = FilterCriterion('Python', sVarNm = 'py', sTable = 'TestBoxesWithStrings', sColumn = 'iPythonHexVersion');
     
    772769    };
    773770
     771    def _getWhereWorker(self, iCrit, oCrit, sExtraIndent, iOmit):
     772        """ Formats one - main or sub. """
     773        sQuery = '';
     774        if oCrit.sState == FilterCriterion.ksState_Selected and iCrit != iOmit:
     775            if iCrit == self.kiMisc:
     776                for iValue in oCrit.aoSelected:
     777                    if iValue in self.kdMiscConditions:
     778                        sQuery += '%s   AND %s\n' % (sExtraIndent, self.kdMiscConditions[iValue],);
     779            else:
     780                if iCrit == self.kiMemory:
     781                    sQuery += '%s   AND (%s.%s / 1024) IN (' % (sExtraIndent, oCrit.sTable, oCrit.sColumn,);
     782                else:
     783                    sQuery += '%s   AND %s.%s IN (' % (sExtraIndent, oCrit.sTable, oCrit.sColumn,);
     784                if oCrit.sType == FilterCriterion.ksType_String:
     785                    sQuery += ', '.join('\'%s\'' % (sValue,) for sValue in oCrit.aoSelected) + ')\n';
     786                else:
     787                    sQuery += ', '.join(str(iValue) for iValue in oCrit.aoSelected) + ')\n';
     788            if oCrit.oSub is not None:
     789                sQuery += self._getWhereWorker(iCrit | (((iCrit >> 8) + 1) << 8), oCrit.oSub, sExtraIndent, iOmit);
     790        return sQuery;
     791
    774792    def getWhereConditions(self, sExtraIndent = '', iOmit = -1):
    775793        """
     
    779797        sQuery = '';
    780798        for iCrit, oCrit in enumerate(self.aCriteria):
    781             if oCrit.sState == FilterCriterion.ksState_Selected and iCrit != iOmit:
    782                 if iCrit == self.kiMisc:
    783                     for iValue in oCrit.aoSelected:
    784                         if iValue in self.kdMiscConditions:
    785                             sQuery += '%s   AND %s\n' % (sExtraIndent, self.kdMiscConditions[iValue],);
    786                 else:
    787                     if iCrit == self.kiMemory:
    788                         sQuery += '%s   AND (%s.%s / 1024) IN (' % (sExtraIndent, oCrit.sTable, oCrit.sColumn,);
    789                     else:
    790                         sQuery += '%s   AND %s.%s IN (' % (sExtraIndent, oCrit.sTable, oCrit.sColumn,);
    791                     if oCrit.sType == FilterCriterion.ksType_String:
    792                         sQuery += ', '.join('\'%s\'' % (sValue,) for sValue in oCrit.aoSelected) + ')\n';
    793                     else:
    794                         sQuery += ', '.join(str(iValue) for iValue in oCrit.aoSelected) + ')\n';
     799            sQuery += self._getWhereWorker(iCrit, oCrit, sExtraIndent, iOmit);
    795800        return sQuery;
    796801
     
    15541559                                                                                       fIrrelevant = True));
    15551560
     1561        def workerDoFetchNested():
     1562            """ Does the tedious result fetching and handling of missing bits. """
     1563            oCrit.aoPossible = [];
     1564            oCrit.oSub.aoPossible = [];
     1565            dLeft    = { oValue: 1 for oValue in oCrit.aoSelected };
     1566            dSubLeft = { oValue: 1 for oValue in oCrit.oSub.aoSelected };
     1567            oMain    = None;
     1568            for aoRow in self._oDb.fetchAll():
     1569                if oMain is None or oMain.oValue != aoRow[0]:
     1570                    oMain = FilterCriterionValueAndDescription(aoRow[0], aoRow[1], 0);
     1571                    oCrit.aoPossible.append(oMain);
     1572                    if aoRow[0] in dLeft:
     1573                        del dLeft[aoRow[0]];
     1574                oCurSub = FilterCriterionValueAndDescription(aoRow[2], aoRow[3], aoRow[4]);
     1575                oCrit.oSub.aoPossible.append(oCurSub);
     1576                if aoRow[2] in dLeft:
     1577                    del dSubLeft[aoRow[2]];
     1578
     1579                oMain.aoSubs.append(oCurSub);
     1580                oMain.cTimes += aoRow[4];
     1581
     1582            if len(dLeft) > 0:
     1583                pass; ## @todo
     1584
    15561585        # Statuses.
    15571586        oCrit = oFilter.aCriteria[TestResultFilter.kiTestStatus];
     
    16061635        workerDoFetch(TestBoxLogic);
    16071636
    1608         # Testbox OSes.
     1637        # Testbox OSes and versions.
    16091638        oCrit = oFilter.aCriteria[TestResultFilter.kiOses];
    16101639        self._oDb.execute('SELECT TestBoxesWithStrings.idStrOs,\n'
    16111640                          '       TestBoxesWithStrings.sOs,\n'
     1641                          '       TestBoxesWithStrings.idStrOsVersion,\n'
     1642                          '       TestBoxesWithStrings.sOsVersion,\n'
    16121643                          '       SUM(TestBoxGenIDs.cTimes)\n'
    16131644                          'FROM   ( SELECT TestSets.idGenTestBox,\n'
     
    16221653                          '       LEFT OUTER JOIN TestBoxesWithStrings\n'
    16231654                          '                    ON TestBoxesWithStrings.idGenTestBox = TestBoxGenIDs.idGenTestBox\n'
    1624                           'GROUP BY TestBoxesWithStrings.idStrOs, TestBoxesWithStrings.sOs\n'
    1625                           'ORDER BY TestBoxesWithStrings.sOs\n' );
    1626         workerDoFetch(None, fIdIsName = True);
    1627 
    1628         # Testbox OS versions .
    1629         oCrit = oFilter.aCriteria[TestResultFilter.kiOsVersions];
    1630         self._oDb.execute('SELECT TestBoxesWithStrings.idStrOsVersion,\n'
    1631                           '       TestBoxesWithStrings.sOsVersion,\n'
    1632                           '       SUM(TestBoxGenIDs.cTimes)\n'
    1633                           'FROM   ( SELECT TestSets.idGenTestBox     AS idGenTestBox,\n'
    1634                           '                COUNT(TestSets.idTestSet) AS cTimes\n'
    1635                           '         FROM   TestSets\n' + oFilter.getTableJoins(iOmit = TestResultFilter.kiOsVersions) +
    1636                           ''.join('                , %s\n' % (sTable,) for sTable in oReportModel.getExtraSubjectTables()) +
    1637                           '         WHERE  ' + self._getTimePeriodQueryPart(tsNow, sPeriod, '        ') +
    1638                           oFilter.getWhereConditions(iOmit = TestResultFilter.kiOsVersions) +
    1639                           oReportModel.getExtraSubjectWhereExpr() +
    1640                           '         GROUP BY TestSets.idGenTestBox\n'
    1641                           '       ) AS TestBoxGenIDs\n'
    1642                           '       LEFT OUTER JOIN TestBoxesWithStrings\n'
    1643                           '                    ON TestBoxesWithStrings.idGenTestBox = TestBoxGenIDs.idGenTestBox\n'
    1644                           'GROUP BY TestBoxesWithStrings.idStrOsVersion, TestBoxesWithStrings.sOsVersion\n'
    1645                           'ORDER BY TestBoxesWithStrings.sOsVersion\n' );
    1646         workerDoFetch(None, fIdIsName = True);
     1655                          'GROUP BY TestBoxesWithStrings.idStrOs,\n'
     1656                          '         TestBoxesWithStrings.sOs,\n'
     1657                          '         TestBoxesWithStrings.idStrOsVersion,\n'
     1658                          '         TestBoxesWithStrings.sOsVersion\n'
     1659                          'ORDER BY TestBoxesWithStrings.sOs,\n'
     1660                          '         TestBoxesWithStrings.sOsVersion\n'
     1661                           );
     1662        workerDoFetchNested();
    16471663
    16481664        # Testbox CPU/OS architectures.
     
    17701786        workerDoFetch(None, fIdIsName = True);
    17711787        for oCur in oCrit.aoPossible:
    1772             oCur.sDesc = TestBoxData.formatPythonVersionEx(oCur.oValue);
     1788            oCur.sDesc = TestBoxData.formatPythonVersionEx(oCur.oValue); # pylint: disable=redefined-variable-type
    17731789
    17741790        # Testcases (see getTestCases).
  • trunk/src/VBox/ValidationKit/testmanager/htdocs/css/common.css

    r65090 r65091  
    324324}
    325325
    326 
    327326/* Filters: */
    328327#side-filters p:first-child {
     
    333332}
    334333
    335 #side-filters dd.sf-collapsable {
     334#side-filters dd.sf-collapsible {
    336335    display:        block;
    337336}
     
    378377}
    379378
    380 #side-filters ul {
     379#side-filters dd > ul {
    381380    max-height:     22em;
    382381    overflow:       auto;
     382}
     383
     384#side-filters ul ul {
     385    margin-left:    1.4em;
     386}
     387
     388#side-filters li {
     389    padding-top:    1px;
     390    padding-bottom: 1px;
     391    overflow-wrap:  break-word;
     392}
     393
     394ul.sf-checkbox-collapsible {
     395    display:        block;
     396}
     397
     398ul.sf-checkbox-expandable {
     399    display:        none;
    383400}
    384401
     
    407424    margin-right:   3px;
    408425    margin-bottom:  0.5em;
     426    font-family:    Times New, Times, serif;
    409427    font-size:      0.86em;
     428    font-style:     normal;
     429    font-weight:    normal;
    410430    line-height:    1.2em;
    411     font-style:     normal;
    412431    text-align:     center;
    413432}
  • trunk/src/VBox/ValidationKit/testmanager/htdocs/js/common.js

    r65085 r65091  
    353353
    354354
    355 /** @name Collapsable / Expandable items
     355/** @name Collapsible / Expandable items
    356356 * @{
    357357 */
     
    359359
    360360/**
    361  * Toggles the collapsable / expandable state of a parent DD and DT unclke.
     361 * Toggles the collapsible / expandable state of a parent DD and DT uncle.
    362362 *
    363363 * @returns true
    364364 * @param   oAnchor             The anchor object.
    365365 */
    366 function toggleCollapsableDtDd(oAnchor)
     366function toggleCollapsibleDtDd(oAnchor)
    367367{
    368368    var oParent = oAnchor.parentElement;
     
    377377    var sNewClass;
    378378    var sNewChar;
    379     if (     sClass.substr(-11) == 'collapsable')
     379    if (     sClass.substr(-11) == 'collapsible')
    380380    {
    381381        sNewClass = sClass.substr(0, sClass.length - 11) + 'expandable';
     
    384384    else if (sClass.substr(-10) == 'expandable')
    385385    {
    386         sNewClass = sClass.substr(0, sClass.length - 10) + 'collapsable';
     386        sNewClass = sClass.substr(0, sClass.length - 10) + 'collapsible';
    387387        sNewChar  = '\u25BC'; /* black down-pointing triangle */
    388388    }
    389389    else
    390390    {
    391         console.log('toggleCollapsableParent: Invalid class: ' + sClass);
     391        console.log('toggleCollapsibleParent: Invalid class: ' + sClass);
    392392        return true;
    393393    }
     
    400400    if (oDdElement)
    401401        oDdElement.className = sNewClass;
     402    return true;
     403}
     404
     405/**
     406 * Shows/hides a sub-category UL according to checkbox status.
     407 *
     408 * The checkbox is expected to be within a label element or something.
     409 *
     410 * @returns true
     411 * @param   oInput          The input checkbox.
     412 */
     413function toggleCollapsibleCheckbox(oInput)
     414{
     415    var oParent = oInput.parentElement;
     416
     417    /* Find the UL sibling element. */
     418    var oUlElement = oParent.nextSibling;
     419    while (oUlElement != null && oUlElement.tagName != 'UL')
     420        oUlElement = oUlElement.nextSibling;
     421
     422    /* Change the visibility. */
     423    if (oInput.checked)
     424        oUlElement.className = oUlElement.className.replace('expandable', 'collapsible');
     425    else
     426        oUlElement.className = oUlElement.className.replace('collapsible', 'expandable');
    402427    return true;
    403428}
  • trunk/src/VBox/ValidationKit/testmanager/webui/wuimain.py

    r65090 r65091  
    933933        for oCrit in oFilter.aCriteria:
    934934            if len(oCrit.aoPossible) > 0:
    935                 if   oCrit.sState == oCrit.ksState_Selected \
    936                   or len(oCrit.aoPossible) <= 2 \
     935                if   (    oCrit.oSub is None \
     936                      and (   oCrit.sState == oCrit.ksState_Selected \
     937                           or len(oCrit.aoPossible) <= 2)) \
     938                  or (    oCrit.oSub is not None \
     939                      and (   oCrit.sState == oCrit.ksState_Selected \
     940                           or oCrit.oSub.sState == oCrit.ksState_Selected \
     941                           or (len(oCrit.aoPossible) <= 2 and len(oCrit.oSub.aoPossible) <= 2))) \
    937942                  or oCrit.fExpanded is True:
    938                     sClass = 'sf-collapsable';
     943                    sClass = 'sf-collapsible';
    939944                    sChar  = '&#9660;';
    940945                else:
     
    942947                    sChar  = '&#9654;';
    943948
    944                 sHtml += u'  <dt class="%s"><a href="javascript:void(0)" onclick="toggleCollapsableDtDd(this);">%s'\
     949                sHtml += u'  <dt class="%s"><a href="javascript:void(0)" onclick="toggleCollapsibleDtDd(this);">%s'\
    945950                         u' %s</a></dt>\n' \
    946951                         u'  <dd class="%s">\n' \
     
    950955                for oDesc in oCrit.aoPossible:
    951956                    fChecked = oDesc.oValue in oCrit.aoSelected;
    952                     sHtml += u'    <li%s%s><input type="checkbox" name="%s" value="%s"%s/>%s%s</li>\n' \
     957                    sHtml += u'    <li%s%s><label><input type="checkbox" name="%s" value="%s"%s%s/>%s%s</label>\n' \
    953958                           % ( ' class="side-filter-irrelevant"' if oDesc.fIrrelevant else '',
    954                                ' title="%s"' % (webutils.escapeAttr(oDesc.sHover,) if oDesc.sHover is not None else ''),
    955                                oCrit.sVarNm, oDesc.oValue, ' checked' if fChecked else '',
     959                               (' title="%s"' % (webutils.escapeAttr(oDesc.sHover,)) if oDesc.sHover is not None else ''),
     960                               oCrit.sVarNm,
     961                               oDesc.oValue,
     962                               ' checked' if fChecked else '',
     963                               ' onclick="toggleCollapsibleCheckbox(this);"' if oDesc.aoSubs is not None else '',
    956964                               webutils.escapeElem(oDesc.sDesc),
    957965                               '<span class="side-filter-count"> [%u]</span>' % (oDesc.cTimes) if oDesc.cTimes is not None
    958966                               else '', );
    959 
     967                    if oDesc.aoSubs is not None:
     968                        sHtml += u'     <ul class="sf-checkbox-%s">\n' % ('collapsible' if fChecked else 'expandable', );
     969                        for oSubDesc in oDesc.aoSubs:
     970                            fSubChecked = oSubDesc.oValue in oCrit.oSub.aoSelected;
     971                            sHtml += u'     <li%s%s><label><input type="checkbox" name="%s" value="%s"%s/>%s%s</label>\n' \
     972                                   % ( ' class="side-filter-irrelevant"' if oSubDesc.fIrrelevant else '',
     973                                       ' title="%s"' % ( webutils.escapeAttr(oSubDesc.sHover,) if oSubDesc.sHover is not None
     974                                                         else ''),
     975                                       oCrit.oSub.sVarNm, oSubDesc.oValue, ' checked' if fSubChecked else '',
     976                                       webutils.escapeElem(oSubDesc.sDesc),
     977                                       '<span class="side-filter-count"> [%u]</span>' % (oSubDesc.cTimes)
     978                                       if oSubDesc.cTimes is not None else '', );
     979
     980                        sHtml += u'     </ul>\n';
     981                    sHtml += u'    </li>';
    960982                sHtml += u'   </ul>\n' \
    961983                         u'  </dd>\n';
Note: See TracChangeset for help on using the changeset viewer.

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