def getTestCaseArgs(self, idTestCaseArgs):
     """ Gets the corresponding TestCaseArgsData object. """
     oRet = self._adCache[self.ksObjType_TestCaseArgs_idTestCaseArgs].get(idTestCaseArgs);
     if oRet is None:
         # Load cache entry.
         from testmanager.core.testcaseargs import TestCaseArgsData;
         oRet = TestCaseArgsData();
         try:    oRet.initFromDbWithId(self._oDb, idTestCaseArgs, self.tsNow, self.sPeriodBack);
         except: self._handleDbException(); raise;
         else:   self._adCache[self.ksObjType_TestCaseArgs_idGenTestCaseArgs][oRet.idGenTestCaseArgs] = oRet;
         self._adCache[self.ksObjType_TestCaseArgs_idTestCaseArgs][idTestCaseArgs] = oRet;
     return oRet;
Example #2
0
 def getTestCaseArgs(self, idTestCaseArgs):
     """ Gets the corresponding TestCaseArgsData object. """
     oRet = self._adCache[self.ksObjType_TestCaseArgs_idTestCaseArgs].get(idTestCaseArgs);
     if oRet is None:
         # Load cache entry.
         from testmanager.core.testcaseargs import TestCaseArgsData;
         oRet = TestCaseArgsData();
         try:    oRet.initFromDbWithId(self._oDb, idTestCaseArgs, self.tsNow, self.sPeriodBack);
         except: self._handleDbException();
         else:   self._adCache[self.ksObjType_TestCaseArgs_idGenTestCaseArgs][oRet.idGenTestCaseArgs] = oRet;
         self._adCache[self.ksObjType_TestCaseArgs_idTestCaseArgs][idTestCaseArgs] = oRet;
     return oRet;
    def getTestCaseArgsForGroup(self, idSchedGroup, cMax=None):
        """
        Gets the testcase argument variation w/ testgroup+priority for the given scheduling group.

        Returns an array TestCaseArgsData instance (sorted by group and
        variation id) with an extra iSchedPriority member.
        May raise exception on DB error or if the result exceeds cMax.
        """

        self._oDb.execute(
            'SELECT   TestGroupMembers.idTestGroup, TestGroupMembers.iSchedPriority, TestCaseArgs.*\n'
            'FROM     SchedGroupMembers, TestGroups, TestGroupMembers, TestCaseArgs, TestCases\n'
            'WHERE    SchedGroupMembers.idSchedGroup = %s\n'
            '     AND SchedGroupMembers.tsExpire     = \'infinity\'::TIMESTAMP\n'
            '     AND TestGroups.idTestGroup         = SchedGroupMembers.idTestGroup\n'
            '     AND TestGroups.tsExpire            = \'infinity\'::TIMESTAMP\n'
            '     AND TestGroupMembers.idTestGroup   = TestGroups.idTestGroup\n'
            '     AND TestGroupMembers.tsExpire      = \'infinity\'::TIMESTAMP\n'
            '     AND TestCaseArgs.idTestCase        = TestGroupMembers.idTestCase\n'
            '     AND TestCaseArgs.tsExpire          = \'infinity\'::TIMESTAMP\n'
            '     AND (   TestGroupMembers.aidTestCaseArgs is NULL\n'
            '          OR TestCaseArgs.idTestCaseArgs = ANY(TestGroupMembers.aidTestCaseArgs) )\n'
            '     AND TestCases.idTestCase           = TestCaseArgs.idTestCase\n'
            '     AND TestCases.tsExpire             = \'infinity\'::TIMESTAMP\n'
            '     AND TestCases.fEnabled             = TRUE\n'
            'ORDER BY TestGroupMembers.idTestGroup, TestGroupMembers.idTestCase, TestCaseArgs.idTestCaseArgs\n',
            (idSchedGroup, ))

        if cMax is not None and self._oDb.getRowCount() > cMax:
            raise TMExceptionBase(
                'Too many argument variations for scheduling group %s: %s, max %s'
                % (
                    idSchedGroup,
                    cMax,
                    self._oDb.getRowCount(),
                ))

        aoRet = []
        for aoRow in self._oDb.fetchAll():
            oVariation = TestCaseArgsData().initFromDbRow(aoRow[2:])
            oVariation.idTestGroup = aoRow[0]
            oVariation.iSchedPriority = aoRow[1]
            aoRet.append(oVariation)
        return aoRet
Example #4
0
    def getTestCaseArgsForGroup(self, idSchedGroup, cMax = None):
        """
        Gets the testcase argument variation w/ testgroup+priority for the given scheduling group.

        Returns an array TestCaseArgsData instance (sorted by group and
        variation id) with an extra iSchedPriority member.
        May raise exception on DB error or if the result exceeds cMax.
        """

        self._oDb.execute('SELECT   TestGroupMembers.idTestGroup, TestGroupMembers.iSchedPriority, TestCaseArgs.*\n'
                          'FROM     SchedGroupMembers, TestGroups, TestGroupMembers, TestCaseArgs, TestCases\n'
                          'WHERE    SchedGroupMembers.idSchedGroup = %s\n'
                          '     AND SchedGroupMembers.tsExpire     = \'infinity\'::TIMESTAMP\n'
                          '     AND TestGroups.idTestGroup         = SchedGroupMembers.idTestGroup\n'
                          '     AND TestGroups.tsExpire            = \'infinity\'::TIMESTAMP\n'
                          '     AND TestGroupMembers.idTestGroup   = TestGroups.idTestGroup\n'
                          '     AND TestGroupMembers.tsExpire      = \'infinity\'::TIMESTAMP\n'
                          '     AND TestCaseArgs.idTestCase        = TestGroupMembers.idTestCase\n'
                          '     AND TestCaseArgs.tsExpire          = \'infinity\'::TIMESTAMP\n'
                          '     AND (   TestGroupMembers.aidTestCaseArgs is NULL\n'
                          '          OR TestCaseArgs.idTestCaseArgs = ANY(TestGroupMembers.aidTestCaseArgs) )\n'
                          '     AND TestCases.idTestCase           = TestCaseArgs.idTestCase\n'
                          '     AND TestCases.tsExpire             = \'infinity\'::TIMESTAMP\n'
                          '     AND TestCases.fEnabled             = TRUE\n'
                          'ORDER BY TestGroupMembers.idTestGroup, TestGroupMembers.idTestCase, TestCaseArgs.idTestCaseArgs\n'
                          , (idSchedGroup,));

        if cMax is not None  and  self._oDb.getRowCount() > cMax:
            raise TMExceptionBase('Too many argument variations for scheduling group %s: %s, max %s'
                                  % (idSchedGroup, cMax, self._oDb.getRowCount(),));

        aoRet = [];
        for aoRow in self._oDb.fetchAll():
            oVariation = TestCaseArgsData().initFromDbRow(aoRow[2:]);
            oVariation.idTestGroup    = aoRow[0];
            oVariation.iSchedPriority = aoRow[1];
            aoRet.append(oVariation);
        return aoRet;
Example #5
0
    def addListOfTestCaseArgs(self, sName, aoVariations, sLabel): # pylint: disable=R0915
        """
        Adds a list of test case argument variations to the form.

        @param sName        Name of HTML form element
        @param aoVariations List of TestCaseArgsData instances.
        @param sLabel       Label of HTML form element
        """
        self._addLabel(sName, sLabel);

        sTableId = 'TestArgsExtendingListRoot';
        fReadOnly = self._fReadOnly;  ## @todo argument?
        sReadOnlyAttr = ' readonly class="tmform-input-readonly"' if fReadOnly else '';

        sHtml  = '<li>\n'

        #
        # Define javascript function for extending the list of test case
        # variations.  Doing it here so we can use the python constants. This
        # also permits multiple argument lists on one page should that ever be
        # required...
        #
        if not fReadOnly:
            sHtml += '<script type="text/javascript">\n'
            sHtml += '\n';
            sHtml += 'g_%s_aItems = { %s };\n' % (sName, ', '.join(('%s: 1' % (i,)) for i in range(len(aoVariations))),);
            sHtml += 'g_%s_cItems = %s;\n' % (sName, len(aoVariations),);
            sHtml += 'g_%s_iIdMod = %s;\n' % (sName, len(aoVariations) + 32);
            sHtml += '\n';
            sHtml += 'function %s_removeEntry(sId)\n' % (sName,);
            sHtml += '{\n';
            sHtml += '    if (g_%s_cItems > 1)\n' % (sName,);
            sHtml += '    {\n';
            sHtml += '        g_%s_cItems--;\n' % (sName,);
            sHtml += '        delete g_%s_aItems[sId];\n' % (sName,);
            sHtml += '        setElementValueToKeyList(\'%s\', g_%s_aItems);\n' % (sName, sName);
            sHtml += '\n';
            for iInput in range(8):
                sHtml += '        removeHtmlNode(\'%s[\' + sId + \'][%s]\');\n' % (sName, iInput,);
            sHtml += '    }\n';
            sHtml += '}\n';
            sHtml += '\n';
            sHtml += 'function %s_extendListEx(cGangMembers, cSecTimeout, sArgs, sTestBoxReqExpr, sBuildReqExpr)\n' % (sName,);
            sHtml += '{\n';
            sHtml += '    var oElement = document.getElementById(\'%s\');\n' % (sTableId,);
            sHtml += '    var oTBody   = document.createElement(\'tbody\');\n';
            sHtml += '    var sHtml    = \'\';\n';
            sHtml += '    var sId;\n';
            sHtml += '\n';
            sHtml += '    g_%s_iIdMod += 1;\n' % (sName,);
            sHtml += '    sId = g_%s_iIdMod.toString();\n' % (sName,);

            oVarDefaults = TestCaseArgsData();
            oVarDefaults.convertToParamNull();
            sHtml += '\n';
            sHtml += '    sHtml += \'<tr class="tmform-testcasevars-first-row">\';\n';
            sHtml += '    sHtml += \'  <td>Gang Members:</td>\';\n';
            sHtml += '    sHtml += \'  <td class="tmform-field-tiny-int">' \
                     '<input name="%s[\' + sId + \'][%s]" id="%s[\' + sId + \'][0]" value="\' + cGangMembers + \'"></td>\';\n' \
                   % (sName, TestCaseArgsData.ksParam_cGangMembers, sName,);
            sHtml += '    sHtml += \'  <td>Timeout:</td>\';\n';
            sHtml += '    sHtml += \'  <td class="tmform-field-int">' \
                     '<input name="%s[\' + sId + \'][%s]" id="%s[\' + sId + \'][1]" value="\'+ cSecTimeout + \'"></td>\';\n' \
                   % (sName, TestCaseArgsData.ksParam_cSecTimeout, sName,);
            sHtml += '    sHtml += \'  <td><a href="#" onclick="%s_removeEntry(\\\'\' + sId + \'\\\');"> Remove</a></td>\';\n' \
                   % (sName, );
            sHtml += '    sHtml += \'  <td></td>\';\n';
            sHtml += '    sHtml += \'</tr>\';\n'
            sHtml += '\n';
            sHtml += '    sHtml += \'<tr class="tmform-testcasevars-inner-row">\';\n';
            sHtml += '    sHtml += \'  <td>Arguments:</td>\';\n';
            sHtml += '    sHtml += \'  <td class="tmform-field-wide100" colspan="4">' \
                     '<input name="%s[\' + sId + \'][%s]" id="%s[\' + sId + \'][2]" value="\' + sArgs + \'"></td>\';\n' \
                   % (sName, TestCaseArgsData.ksParam_sArgs, sName,);
            sHtml += '    sHtml += \'  <td></td>\';\n';
            sHtml += '    sHtml += \'</tr>\';\n'
            sHtml += '\n';
            sHtml += '    sHtml += \'<tr class="tmform-testcasevars-inner-row">\';\n';
            sHtml += '    sHtml += \'  <td>TestBox Reqs:</td>\';\n';
            sHtml += '    sHtml += \'  <td class="tmform-field-wide100" colspan="4">' \
                     '<input name="%s[\' + sId + \'][%s]" id="%s[\' + sId + \'][2]" value="\' + sTestBoxReqExpr' \
                     ' + \'"></td>\';\n' \
                   % (sName, TestCaseArgsData.ksParam_sTestBoxReqExpr, sName,);
            sHtml += '    sHtml += \'  <td></td>\';\n';
            sHtml += '    sHtml += \'</tr>\';\n'
            sHtml += '\n';
            sHtml += '    sHtml += \'<tr class="tmform-testcasevars-final-row">\';\n';
            sHtml += '    sHtml += \'  <td>Build Reqs:</td>\';\n';
            sHtml += '    sHtml += \'  <td class="tmform-field-wide100" colspan="4">' \
                     '<input name="%s[\' + sId + \'][%s]" id="%s[\' + sId + \'][2]" value="\' + sBuildReqExpr + \'"></td>\';\n' \
                   % (sName, TestCaseArgsData.ksParam_sBuildReqExpr, sName,);
            sHtml += '    sHtml += \'  <td></td>\';\n';
            sHtml += '    sHtml += \'</tr>\';\n'
            sHtml += '\n';
            sHtml += '    oTBody.id = \'%s[\' + sId + \'][6]\';\n' % (sName,);
            sHtml += '    oTBody.innerHTML = sHtml;\n';
            sHtml += '\n';
            sHtml += '    oElement.appendChild(oTBody);\n';
            sHtml += '\n';
            sHtml += '    g_%s_aItems[sId] = 1;\n' % (sName,);
            sHtml += '    g_%s_cItems++;\n' % (sName,);
            sHtml += '    setElementValueToKeyList(\'%s\', g_%s_aItems);\n' % (sName, sName);
            sHtml += '}\n';
            sHtml += 'function %s_extendList()\n' % (sName,);
            sHtml += '{\n';
            sHtml += '    %s_extendListEx("%s", "%s", "%s", "%s", "%s");\n' % (sName,
                escapeAttr(str(oVarDefaults.cGangMembers)), escapeAttr(str(oVarDefaults.cSecTimeout)),
                escapeAttr(oVarDefaults.sArgs), escapeAttr(oVarDefaults.sTestBoxReqExpr),
                escapeAttr(oVarDefaults.sBuildReqExpr), );
            sHtml += '}\n';
            if config.g_kfVBoxSpecific:
                sSecTimeoutDef = escapeAttr(str(oVarDefaults.cSecTimeout));
                sHtml += 'function vbox_%s_add_uni()\n' % (sName,);
                sHtml += '{\n';
                sHtml += '    %s_extendListEx("1", "%s", "--cpu-counts 1 --virt-modes raw", ' \
                         ' "", "");\n' % (sName, sSecTimeoutDef);
                sHtml += '    %s_extendListEx("1", "%s", "--cpu-counts 1 --virt-modes hwvirt", ' \
                         ' "fCpuHwVirt is True", "");\n' % (sName, sSecTimeoutDef);
                sHtml += '    %s_extendListEx("1", "%s", "--cpu-counts 1 --virt-modes hwvirt-np", ' \
                         ' "fCpuNestedPaging is True", "");\n' % (sName, sSecTimeoutDef);
                sHtml += '}\n';
                sHtml += 'function vbox_%s_add_uni_amd64()\n' % (sName,);
                sHtml += '{\n';
                sHtml += '    %s_extendListEx("1", "%s", "--cpu-counts 1 --virt-modes hwvirt", ' \
                         ' "fCpuHwVirt is True", "");\n' % (sName, sSecTimeoutDef);
                sHtml += '    %s_extendListEx("1", "%s", "--cpu-counts 1 --virt-modes hwvirt-np", ' \
                         ' "fCpuNestedPaging is True", "");\n' % (sName, sSecTimeoutDef);
                sHtml += '}\n';
                sHtml += 'function vbox_%s_add_smp()\n' % (sName,);
                sHtml += '{\n';
                sHtml += '    %s_extendListEx("1", "%s", "--cpu-counts 2 --virt-modes hwvirt",' \
                         ' "fCpuHwVirt is True and cCpus >= 2", "");\n' % (sName, sSecTimeoutDef);
                sHtml += '    %s_extendListEx("1", "%s", "--cpu-counts 2 --virt-modes hwvirt-np",' \
                         ' "fCpuNestedPaging is True and cCpus >= 2", "");\n' % (sName, sSecTimeoutDef);
                sHtml += '    %s_extendListEx("1", "%s", "--cpu-counts 3 --virt-modes hwvirt",' \
                         ' "fCpuHwVirt is True and cCpus >= 3", "");\n' % (sName, sSecTimeoutDef);
                sHtml += '    %s_extendListEx("1", "%s", "--cpu-counts 4 --virt-modes hwvirt-np ",' \
                         ' "fCpuNestedPaging is True and cCpus >= 4", "");\n' % (sName, sSecTimeoutDef);
                #sHtml += '    %s_extendListEx("1", "%s", "--cpu-counts 6 --virt-modes hwvirt",' \
                #         ' "fCpuHwVirt is True and cCpus >= 6", "");\n' % (sName, sSecTimeoutDef);
                #sHtml += '    %s_extendListEx("1", "%s", "--cpu-counts 8 --virt-modes hwvirt-np",' \
                #         ' "fCpuNestedPaging is True and cCpus >= 8", "");\n' % (sName, sSecTimeoutDef);
                sHtml += '}\n';
            sHtml += '</script>\n';


        #
        # List current entries.
        #
        sHtml += '<input type="hidden" name="%s" id="%s" value="%s">\n' \
               % (sName, sName, ','.join(str(i) for i in range(len(aoVariations))), );
        sHtml += '  <table id="%s" class="tmform-testcasevars">\n' % (sTableId,)
        if not fReadOnly:
            sHtml += '  <caption>\n' \
                     '    <a href="#" onClick="%s_extendList()">Add</a>\n' % (sName,);
            if config.g_kfVBoxSpecific:
                sHtml += '    [<a href="#" onClick="vbox_%s_add_uni()">Single CPU Variations</a>\n' % (sName,);
                sHtml += '    <a href="#" onClick="vbox_%s_add_uni_amd64()">amd64</a>]\n' % (sName,);
                sHtml += '    [<a href="#" onClick="vbox_%s_add_smp()">SMP Variations</a>]\n' % (sName,);
            sHtml += '  </caption>\n';

        dSubErrors = {};
        if sName in self._dErrors  and  isinstance(self._dErrors[sName], dict):
            dSubErrors = self._dErrors[sName];

        for iVar in range(len(aoVariations)):
            oVar = copy.copy(aoVariations[iVar]);
            oVar.convertToParamNull();

            sHtml += '<tbody id="%s[%s][6]">\n' % (sName, iVar,)
            sHtml += '  <tr class="tmform-testcasevars-first-row">\n' \
                     '    <td>Gang Members:</td>' \
                     '    <td class="tmform-field-tiny-int"><input name="%s[%s][%s]" id="%s[%s][1]" value="%s"%s></td>\n' \
                     '    <td>Timeout:</td>' \
                     '    <td class="tmform-field-int"><input name="%s[%s][%s]" id="%s[%s][2]" value="%s"%s></td>\n' \
                   % ( sName, iVar, TestCaseArgsData.ksParam_cGangMembers, sName, iVar, oVar.cGangMembers, sReadOnlyAttr,
                       sName, iVar, TestCaseArgsData.ksParam_cSecTimeout,  sName, iVar,
                       utils.formatIntervalSeconds2(oVar.cSecTimeout), sReadOnlyAttr, );
            if not fReadOnly:
                sHtml += '    <td><a href="#" onclick="%s_removeEntry(\'%s\');">Remove</a></td>\n' \
                       % (sName, iVar);
            else:
                sHtml +=  '    <td></td>\n';
            sHtml += '    <td class="tmform-testcasevars-stupid-border-column"></td>\n' \
                     '  </tr>\n';

            sHtml += '  <tr class="tmform-testcasevars-inner-row">\n' \
                     '    <td>Arguments:</td>' \
                     '    <td class="tmform-field-wide100" colspan="4">' \
                     '<input name="%s[%s][%s]" id="%s[%s][3]" value="%s"%s></td>\n' \
                     '    <td></td>\n' \
                     '  </tr>\n' \
                   % ( sName, iVar, TestCaseArgsData.ksParam_sArgs, sName, iVar, escapeAttr(oVar.sArgs), sReadOnlyAttr)

            sHtml += '  <tr class="tmform-testcasevars-inner-row">\n' \
                     '    <td>TestBox Reqs:</td>' \
                     '    <td class="tmform-field-wide100" colspan="4">' \
                     '<input name="%s[%s][%s]" id="%s[%s][4]" value="%s"%s></td>\n' \
                     '    <td></td>\n' \
                     '  </tr>\n' \
                   % ( sName, iVar, TestCaseArgsData.ksParam_sTestBoxReqExpr, sName, iVar,
                       escapeAttr(oVar.sTestBoxReqExpr), sReadOnlyAttr)

            sHtml += '  <tr class="tmform-testcasevars-final-row">\n' \
                     '    <td>Build Reqs:</td>' \
                     '    <td class="tmform-field-wide100" colspan="4">' \
                     '<input name="%s[%s][%s]" id="%s[%s][5]" value="%s"%s></td>\n' \
                     '    <td></td>\n' \
                     '  </tr>\n' \
                   % ( sName, iVar, TestCaseArgsData.ksParam_sBuildReqExpr, sName, iVar,
                       escapeAttr(oVar.sBuildReqExpr), sReadOnlyAttr)


            if iVar in dSubErrors:
                sHtml += '  <tr><td colspan="4"><p align="left" class="tmform-error-desc">%s</p></td></tr>\n' \
                       % (self._escapeErrorText(dSubErrors[iVar]),);

            sHtml += '</tbody>\n';
        sHtml += '  </table>\n'
        sHtml += '</li>\n'

        return self._add(sHtml)
Example #6
0
    def addListOfTestCaseArgs(self, sName, aoVariations, sLabel): # pylint: disable=R0915
        """
        Adds a list of test case argument variations to the form.

        @param sName        Name of HTML form element
        @param aoVariations List of TestCaseArgsData instances.
        @param sLabel       Label of HTML form element
        """
        self._addLabel(sName, sLabel);

        sTableId = 'TestArgsExtendingListRoot';
        fReadOnly = self._fReadOnly;  ## @todo argument?
        sReadOnlyAttr = ' readonly class="tmform-input-readonly"' if fReadOnly else '';

        sHtml  = '<li>\n'

        #
        # Define javascript function for extending the list of test case
        # variations.  Doing it here so we can use the python constants. This
        # also permits multiple argument lists on one page should that ever be
        # required...
        #
        if not fReadOnly:
            sHtml += '<script type="text/javascript">\n'
            sHtml += '\n';
            sHtml += 'g_%s_aItems = { %s };\n' % (sName, ', '.join(('%s: 1' % (i,)) for i in range(len(aoVariations))),);
            sHtml += 'g_%s_cItems = %s;\n' % (sName, len(aoVariations),);
            sHtml += 'g_%s_iIdMod = %s;\n' % (sName, len(aoVariations) + 32);
            sHtml += '\n';
            sHtml += 'function %s_removeEntry(sId)\n' % (sName,);
            sHtml += '{\n';
            sHtml += '    if (g_%s_cItems > 1)\n' % (sName,);
            sHtml += '    {\n';
            sHtml += '        g_%s_cItems--;\n' % (sName,);
            sHtml += '        delete g_%s_aItems[sId];\n' % (sName,);
            sHtml += '        setElementValueToKeyList(\'%s\', g_%s_aItems);\n' % (sName, sName);
            sHtml += '\n';
            for iInput in range(8):
                sHtml += '        removeHtmlNode(\'%s[\' + sId + \'][%s]\');\n' % (sName, iInput,);
            sHtml += '    }\n';
            sHtml += '}\n';
            sHtml += '\n';
            sHtml += 'function %s_extendListEx(cGangMembers, cSecTimeout, sArgs, sTestBoxReqExpr, sBuildReqExpr)\n' % (sName,);
            sHtml += '{\n';
            sHtml += '    var oElement = document.getElementById(\'%s\');\n' % (sTableId,);
            sHtml += '    var oTBody   = document.createElement(\'tbody\');\n';
            sHtml += '    var sHtml    = \'\';\n';
            sHtml += '    var sId;\n';
            sHtml += '\n';
            sHtml += '    g_%s_iIdMod += 1;\n' % (sName,);
            sHtml += '    sId = g_%s_iIdMod.toString();\n' % (sName,);

            oVarDefaults = TestCaseArgsData();
            oVarDefaults.convertToParamNull();
            sHtml += '\n';
            sHtml += '    sHtml += \'<tr class="tmform-testcasevars-first-row">\';\n';
            sHtml += '    sHtml += \'  <td>Gang Members:</td>\';\n';
            sHtml += '    sHtml += \'  <td class="tmform-field-tiny-int">' \
                     '<input name="%s[\' + sId + \'][%s]" id="%s[\' + sId + \'][0]" value="\' + cGangMembers + \'"></td>\';\n' \
                   % (sName, TestCaseArgsData.ksParam_cGangMembers, sName,);
            sHtml += '    sHtml += \'  <td>Timeout:</td>\';\n';
            sHtml += '    sHtml += \'  <td class="tmform-field-int">' \
                     '<input name="%s[\' + sId + \'][%s]" id="%s[\' + sId + \'][1]" value="\'+ cSecTimeout + \'"></td>\';\n' \
                   % (sName, TestCaseArgsData.ksParam_cSecTimeout, sName,);
            sHtml += '    sHtml += \'  <td><a href="#" onclick="%s_removeEntry(\\\'\' + sId + \'\\\');"> Remove</a></td>\';\n' \
                   % (sName, );
            sHtml += '    sHtml += \'  <td></td>\';\n';
            sHtml += '    sHtml += \'</tr>\';\n'
            sHtml += '\n';
            sHtml += '    sHtml += \'<tr class="tmform-testcasevars-inner-row">\';\n';
            sHtml += '    sHtml += \'  <td>Arguments:</td>\';\n';
            sHtml += '    sHtml += \'  <td class="tmform-field-wide100" colspan="4">' \
                     '<input name="%s[\' + sId + \'][%s]" id="%s[\' + sId + \'][2]" value="\' + sArgs + \'"></td>\';\n' \
                   % (sName, TestCaseArgsData.ksParam_sArgs, sName,);
            sHtml += '    sHtml += \'  <td></td>\';\n';
            sHtml += '    sHtml += \'</tr>\';\n'
            sHtml += '\n';
            sHtml += '    sHtml += \'<tr class="tmform-testcasevars-inner-row">\';\n';
            sHtml += '    sHtml += \'  <td>TestBox Reqs:</td>\';\n';
            sHtml += '    sHtml += \'  <td class="tmform-field-wide100" colspan="4">' \
                     '<input name="%s[\' + sId + \'][%s]" id="%s[\' + sId + \'][2]" value="\' + sTestBoxReqExpr' \
                     ' + \'"></td>\';\n' \
                   % (sName, TestCaseArgsData.ksParam_sTestBoxReqExpr, sName,);
            sHtml += '    sHtml += \'  <td></td>\';\n';
            sHtml += '    sHtml += \'</tr>\';\n'
            sHtml += '\n';
            sHtml += '    sHtml += \'<tr class="tmform-testcasevars-final-row">\';\n';
            sHtml += '    sHtml += \'  <td>Build Reqs:</td>\';\n';
            sHtml += '    sHtml += \'  <td class="tmform-field-wide100" colspan="4">' \
                     '<input name="%s[\' + sId + \'][%s]" id="%s[\' + sId + \'][2]" value="\' + sBuildReqExpr + \'"></td>\';\n' \
                   % (sName, TestCaseArgsData.ksParam_sBuildReqExpr, sName,);
            sHtml += '    sHtml += \'  <td></td>\';\n';
            sHtml += '    sHtml += \'</tr>\';\n'
            sHtml += '\n';
            sHtml += '    oTBody.id = \'%s[\' + sId + \'][6]\';\n' % (sName,);
            sHtml += '    oTBody.innerHTML = sHtml;\n';
            sHtml += '\n';
            sHtml += '    oElement.appendChild(oTBody);\n';
            sHtml += '\n';
            sHtml += '    g_%s_aItems[sId] = 1;\n' % (sName,);
            sHtml += '    g_%s_cItems++;\n' % (sName,);
            sHtml += '    setElementValueToKeyList(\'%s\', g_%s_aItems);\n' % (sName, sName);
            sHtml += '}\n';
            sHtml += 'function %s_extendList()\n' % (sName,);
            sHtml += '{\n';
            sHtml += '    %s_extendListEx("%s", "%s", "%s", "%s", "%s");\n' % (sName,
                escapeAttr(str(oVarDefaults.cGangMembers)), escapeAttr(str(oVarDefaults.cSecTimeout)),
                escapeAttr(oVarDefaults.sArgs), escapeAttr(oVarDefaults.sTestBoxReqExpr),
                escapeAttr(oVarDefaults.sBuildReqExpr), );
            sHtml += '}\n';
            if config.g_kfVBoxSpecific:
                sSecTimeoutDef = escapeAttr(str(oVarDefaults.cSecTimeout));
                sHtml += 'function vbox_%s_add_uni()\n' % (sName,);
                sHtml += '{\n';
                sHtml += '    %s_extendListEx("1", "%s", "--cpu-counts 1 --virt-modes raw", ' \
                         ' "", "");\n' % (sName, sSecTimeoutDef);
                sHtml += '    %s_extendListEx("1", "%s", "--cpu-counts 1 --virt-modes hwvirt", ' \
                         ' "fCpuHwVirt is True", "");\n' % (sName, sSecTimeoutDef);
                sHtml += '    %s_extendListEx("1", "%s", "--cpu-counts 1 --virt-modes hwvirt-np", ' \
                         ' "fCpuNestedPaging is True", "");\n' % (sName, sSecTimeoutDef);
                sHtml += '}\n';
                sHtml += 'function vbox_%s_add_uni_amd64()\n' % (sName,);
                sHtml += '{\n';
                sHtml += '    %s_extendListEx("1", "%s", "--cpu-counts 1 --virt-modes hwvirt", ' \
                         ' "fCpuHwVirt is True", "");\n' % (sName, sSecTimeoutDef);
                sHtml += '    %s_extendListEx("1", "%s", "--cpu-counts 1 --virt-modes hwvirt-np", ' \
                         ' "fCpuNestedPaging is True", "");\n' % (sName, sSecTimeoutDef);
                sHtml += '}\n';
                sHtml += 'function vbox_%s_add_smp()\n' % (sName,);
                sHtml += '{\n';
                sHtml += '    %s_extendListEx("1", "%s", "--cpu-counts 2 --virt-modes hwvirt",' \
                         ' "fCpuHwVirt is True and cCpus >= 2", "");\n' % (sName, sSecTimeoutDef);
                sHtml += '    %s_extendListEx("1", "%s", "--cpu-counts 2 --virt-modes hwvirt-np",' \
                         ' "fCpuNestedPaging is True and cCpus >= 2", "");\n' % (sName, sSecTimeoutDef);
                sHtml += '    %s_extendListEx("1", "%s", "--cpu-counts 3 --virt-modes hwvirt",' \
                         ' "fCpuHwVirt is True and cCpus >= 3", "");\n' % (sName, sSecTimeoutDef);
                sHtml += '    %s_extendListEx("1", "%s", "--cpu-counts 4 --virt-modes hwvirt-np ",' \
                         ' "fCpuNestedPaging is True and cCpus >= 4", "");\n' % (sName, sSecTimeoutDef);
                #sHtml += '    %s_extendListEx("1", "%s", "--cpu-counts 6 --virt-modes hwvirt",' \
                #         ' "fCpuHwVirt is True and cCpus >= 6", "");\n' % (sName, sSecTimeoutDef);
                #sHtml += '    %s_extendListEx("1", "%s", "--cpu-counts 8 --virt-modes hwvirt-np",' \
                #         ' "fCpuNestedPaging is True and cCpus >= 8", "");\n' % (sName, sSecTimeoutDef);
                sHtml += '}\n';
            sHtml += '</script>\n';


        #
        # List current entries.
        #
        sHtml += '<input type="hidden" name="%s" id="%s" value="%s">\n' \
               % (sName, sName, ','.join(str(i) for i in range(len(aoVariations))), );
        sHtml += '  <table id="%s" class="tmform-testcasevars">\n' % (sTableId,)
        if not fReadOnly:
            sHtml += '  <caption>\n' \
                     '    <a href="#" onClick="%s_extendList()">Add</a>\n' % (sName,);
            if config.g_kfVBoxSpecific:
                sHtml += '    [<a href="#" onClick="vbox_%s_add_uni()">Single CPU Variations</a>\n' % (sName,);
                sHtml += '    <a href="#" onClick="vbox_%s_add_uni_amd64()">amd64</a>]\n' % (sName,);
                sHtml += '    [<a href="#" onClick="vbox_%s_add_smp()">SMP Variations</a>]\n' % (sName,);
            sHtml += '  </caption>\n';

        dSubErrors = {};
        if sName in self._dErrors  and  isinstance(self._dErrors[sName], dict):
            dSubErrors = self._dErrors[sName];

        for iVar in range(len(aoVariations)):
            oVar = copy.copy(aoVariations[iVar]);
            oVar.convertToParamNull();

            sHtml += '<tbody id="%s[%s][6]">\n' % (sName, iVar,)
            sHtml += '  <tr class="tmform-testcasevars-first-row">\n' \
                     '    <td>Gang Members:</td>' \
                     '    <td class="tmform-field-tiny-int"><input name="%s[%s][%s]" id="%s[%s][1]" value="%s"%s></td>\n' \
                     '    <td>Timeout:</td>' \
                     '    <td class="tmform-field-int"><input name="%s[%s][%s]" id="%s[%s][2]" value="%s"%s></td>\n' \
                   % ( sName, iVar, TestCaseArgsData.ksParam_cGangMembers, sName, iVar, oVar.cGangMembers, sReadOnlyAttr,
                       sName, iVar, TestCaseArgsData.ksParam_cSecTimeout,  sName, iVar,
                       utils.formatIntervalSeconds2(oVar.cSecTimeout), sReadOnlyAttr, );
            if not fReadOnly:
                sHtml += '    <td><a href="#" onclick="%s_removeEntry(\'%s\');">Remove</a></td>\n' \
                       % (sName, iVar);
            else:
                sHtml +=  '    <td></td>\n';
            sHtml += '    <td class="tmform-testcasevars-stupid-border-column"></td>\n' \
                     '  </tr>\n';

            sHtml += '  <tr class="tmform-testcasevars-inner-row">\n' \
                     '    <td>Arguments:</td>' \
                     '    <td class="tmform-field-wide100" colspan="4">' \
                     '<input name="%s[%s][%s]" id="%s[%s][3]" value="%s"%s></td>\n' \
                     '    <td></td>\n' \
                     '  </tr>\n' \
                   % ( sName, iVar, TestCaseArgsData.ksParam_sArgs, sName, iVar, escapeAttr(oVar.sArgs), sReadOnlyAttr)

            sHtml += '  <tr class="tmform-testcasevars-inner-row">\n' \
                     '    <td>TestBox Reqs:</td>' \
                     '    <td class="tmform-field-wide100" colspan="4">' \
                     '<input name="%s[%s][%s]" id="%s[%s][4]" value="%s"%s></td>\n' \
                     '    <td></td>\n' \
                     '  </tr>\n' \
                   % ( sName, iVar, TestCaseArgsData.ksParam_sTestBoxReqExpr, sName, iVar,
                       escapeAttr(oVar.sTestBoxReqExpr), sReadOnlyAttr)

            sHtml += '  <tr class="tmform-testcasevars-final-row">\n' \
                     '    <td>Build Reqs:</td>' \
                     '    <td class="tmform-field-wide100" colspan="4">' \
                     '<input name="%s[%s][%s]" id="%s[%s][5]" value="%s"%s></td>\n' \
                     '    <td></td>\n' \
                     '  </tr>\n' \
                   % ( sName, iVar, TestCaseArgsData.ksParam_sBuildReqExpr, sName, iVar,
                       escapeAttr(oVar.sBuildReqExpr), sReadOnlyAttr)


            if iVar in dSubErrors:
                sHtml += '  <tr><td colspan="4"><p align="left" class="tmform-error-desc">%s</p></td></tr>\n' \
                       % (self._escapeErrorText(dSubErrors[iVar]),);

            sHtml += '</tbody>\n';
        sHtml += '  </table>\n'
        sHtml += '</li>\n'

        return self._add(sHtml)