Esempio n. 1
0
 def _getCheckBoxColumn(self, iEntry, sValue):
     """
     Used by _formatListEntry implementations, returns a WuiRawHtmlBase object.
     """
     _ = iEntry;
     return WuiRawHtml('<input type="checkbox" name="%s" value="%s">'
                       % (webutils.escapeAttr(self._sCheckboxName), webutils.escapeAttr(unicode(sValue))));
    def _debugRenderPanel(self):
        """
        Renders a simple form for controlling WUI debugging.

        Returns the HTML for it.
        """

        sHtml  = '<div id="debug-panel">\n' \
                 ' <form id="debug-panel-form" type="get" action="#">\n';

        for sKey, oValue in self._dParams.iteritems():
            if sKey not in self.kasDbgParams:
                if hasattr(oValue, 'startswith'):
                    sHtml += '  <input type="hidden" name="%s" value="%s"/>\n' \
                           % (webutils.escapeAttr(sKey), webutils.escapeAttrToStr(oValue),);
                else:
                    for oSubValue in oValue:
                        sHtml += '  <input type="hidden" name="%s" value="%s"/>\n' \
                               % (webutils.escapeAttr(sKey), webutils.escapeAttrToStr(oSubValue),);

        for aoCheckBox in (
                [self.ksParamDbgSqlTrace, self._fDbgSqlTrace, 'SQL trace'],
                [self.ksParamDbgSqlExplain, self._fDbgSqlExplain, 'SQL explain'], ):
            sHtml += ' <input type="checkbox" name="%s" value="1"%s />%s\n' \
                % (aoCheckBox[0], ' checked' if aoCheckBox[1] else '', aoCheckBox[2]);

        sHtml += '  <button type="submit">Apply</button>\n';
        sHtml += ' </form>\n' \
                 '</div>\n';
        return sHtml;
Esempio n. 3
0
 def addTextHidden(self, sName, sValue, sExtraAttribs = ''):
     """Adds a hidden text input."""
     return self._add('      <div class="tmform-field-hidden">\n'
                      '        <input name="%s" id="%s" type="text" hidden%s value="%s" class="tmform-hidden">\n'
                      '      </div>\n'
                      '    </li>\n'
                      % ( escapeAttr(sName), escapeAttr(sName), sExtraAttribs, escapeElem(str(sValue)) ));
Esempio n. 4
0
    def _debugRenderPanel(self):
        """
        Renders a simple form for controlling WUI debugging.

        Returns the HTML for it.
        """

        sHtml  = '<div id="debug-panel">\n' \
                 ' <form id="debug-panel-form" type="get" action="#">\n';

        for sKey, oValue in self._dParams.items():
            if sKey not in self.kasDbgParams:
                if hasattr(oValue, 'startswith'):
                    sHtml += '  <input type="hidden" name="%s" value="%s"/>\n' \
                           % (webutils.escapeAttr(sKey), webutils.escapeAttrToStr(oValue),);
                else:
                    for oSubValue in oValue:
                        sHtml += '  <input type="hidden" name="%s" value="%s"/>\n' \
                               % (webutils.escapeAttr(sKey), webutils.escapeAttrToStr(oSubValue),);

        for aoCheckBox in (
                [self.ksParamDbgSqlTrace, self._fDbgSqlTrace, 'SQL trace'],
                [self.ksParamDbgSqlExplain, self._fDbgSqlExplain, 'SQL explain'], ):
            sHtml += ' <input type="checkbox" name="%s" value="1"%s />%s\n' \
                % (aoCheckBox[0], ' checked' if aoCheckBox[1] else '', aoCheckBox[2]);

        sHtml += '  <button type="submit">Apply</button>\n';
        sHtml += ' </form>\n' \
                 '</div>\n';
        return sHtml;
Esempio n. 5
0
 def _getCheckBoxColumn(self, iEntry, sValue):
     """
     Used by _formatListEntry implementations, returns a WuiRawHtmlBase object.
     """
     _ = iEntry;
     return WuiRawHtml('<input type="checkbox" name="%s" value="%s">'
                       % (webutils.escapeAttr(self._sCheckboxName), webutils.escapeAttr(unicode(sValue))));
Esempio n. 6
0
 def addTextHidden(self, sName, sValue, sExtraAttribs = ''):
     """Adds a hidden text input."""
     return self._add('      <div class="tmform-field-hidden">\n'
                      '        <input name="%s" id="%s" type="text" hidden%s value="%s" class="tmform-hidden">\n'
                      '      </div>\n'
                      '    </li>\n'
                      % ( escapeAttr(sName), escapeAttr(sName), sExtraAttribs, escapeElem(str(sValue)) ));
Esempio n. 7
0
 def addTextRO(self, sName, sValue, sLabel, sSubClass = 'string', sExtraAttribs = '', sPostHtml = ''):
     """Adds a read-only text input."""
     if sSubClass not in ('int', 'long', 'string', 'uuid', 'timestamp', 'wide'): raise Exception(sSubClass);
     self._addLabel(sName, sLabel, sSubClass);
     return self._add('          <input name="%s" id="%s" type="text" readonly%s value="%s" class="tmform-input-readonly">%s\n'
                      '        </div></div>\n'
                      '      </li>\n'
                      % ( escapeAttr(sName), escapeAttr(sName), sExtraAttribs, escapeElem(str(sValue)), sPostHtml ));
Esempio n. 8
0
 def addTextRO(self, sName, sValue, sLabel, sSubClass = 'string', sExtraAttribs = '', sPostHtml = ''):
     """Adds a read-only text input."""
     if sSubClass not in ('int', 'long', 'string', 'uuid', 'timestamp', 'wide'): raise Exception(sSubClass);
     self._addLabel(sName, sLabel, sSubClass);
     return self._add('          <input name="%s" id="%s" type="text" readonly%s value="%s" class="tmform-input-readonly">%s\n'
                      '        </div></div>\n'
                      '      </li>\n'
                      % ( escapeAttr(sName), escapeAttr(sName), sExtraAttribs, escapeElem(str(sValue)), sPostHtml ));
Esempio n. 9
0
 def addMultilineTextRO(self, sName, sValue, sLabel, sSubClass = 'string', sExtraAttribs = ''):
     """Adds a multiline read-only text input."""
     if sSubClass not in ('int', 'long', 'string', 'uuid', 'timestamp'): raise Exception(sSubClass)
     self._addLabel(sName, sLabel, sSubClass)
     sNewValue = str(sValue) if not isinstance(sValue, list) else '\n'.join(sValue)
     return self._add('          <textarea name="%s" id="%s" readonly %s>%s</textarea>\n'
                      '        </div></div>\n'
                      '      </li>\n'
                      % ( escapeAttr(sName), escapeAttr(sName), sExtraAttribs, escapeElem(sNewValue)))
Esempio n. 10
0
 def __init__(self, sSpanClass, sText, sTitle = None):
     if sTitle is None:
         WuiRawHtml.__init__(self,
                             u'<span class="%s">%s</span>'
                             % ( webutils.escapeAttr(sSpanClass),  webutils.escapeElem(sText),));
     else:
         WuiRawHtml.__init__(self,
                             u'<span class="%s" title="%s">%s</span>'
                             % ( webutils.escapeAttr(sSpanClass), webutils.escapeAttr(sTitle), webutils.escapeElem(sText),));
Esempio n. 11
0
 def __init__(self, sSpanClass, sText, sTitle = None):
     if sTitle is None:
         WuiRawHtml.__init__(self,
                             u'<span class="%s">%s</span>'
                             % ( webutils.escapeAttr(sSpanClass),  webutils.escapeElem(sText),));
     else:
         WuiRawHtml.__init__(self,
                             u'<span class="%s" title="%s">%s</span>'
                             % ( webutils.escapeAttr(sSpanClass), webutils.escapeAttr(sTitle), webutils.escapeElem(sText),));
Esempio n. 12
0
 def addMultilineTextRO(self, sName, sValue, sLabel, sSubClass = 'string', sExtraAttribs = ''):
     """Adds a multiline read-only text input."""
     if sSubClass not in ('int', 'long', 'string', 'uuid', 'timestamp'): raise Exception(sSubClass)
     self._addLabel(sName, sLabel, sSubClass)
     sNewValue = str(sValue) if not isinstance(sValue, list) else '\n'.join(sValue)
     return self._add('          <textarea name="%s" id="%s" readonly %s>%s</textarea>\n'
                      '        </div></div>\n'
                      '      </li>\n'
                      % ( escapeAttr(sName), escapeAttr(sName), sExtraAttribs, escapeElem(sNewValue)))
    def _addList(self, sName, aoRows, sLabel, fUseTable=False, sId="dummy", sExtraAttribs=""):
        """
        Adds a list of items to check.

        @param sName  Name of HTML form element
        @param aoRows  List of [sValue, fChecked, sName] sub-arrays.
        @param sLabel Label of HTML form element
        """
        fReadOnly = self._fReadOnly
        ## @todo add this as a parameter.
        if fReadOnly:
            sExtraAttribs += ' readonly onclick="return false" onkeydown="return false"'

        self._addLabel(sName, sLabel, "list")
        if len(aoRows) == 0:
            return self._add("No items</div></div></li>")
        sNameEscaped = escapeAttr(sName)

        self._add('          <div class="tmform-checkboxes-container" id="%s">\n' % (escapeAttr(sId),))
        if fUseTable:
            self._add("          <table>\n")
            for asRow in aoRows:
                assert len(asRow) == 3
                # Don't allow sloppy input data!
                fChecked = self._reinterpretBool(asRow[1])
                self._add(
                    "            <tr>\n"
                    '              <td><input type="checkbox" name="%s" value="%s"%s%s></td>\n'
                    "              <td>%s</td>\n"
                    "            </tr>\n"
                    % (
                        sNameEscaped,
                        escapeAttr(str(asRow[0])),
                        " checked" if fChecked else "",
                        sExtraAttribs,
                        escapeElem(str(asRow[2])),
                    )
                )
            self._add("          </table>\n")
        else:
            for asRow in aoRows:
                assert len(asRow) == 3
                # Don't allow sloppy input data!
                fChecked = self._reinterpretBool(asRow[1])
                self._add(
                    '            <div class="tmform-checkbox-holder">'
                    '<input type="checkbox" name="%s" value="%s"%s%s> %s</input></div>\n'
                    % (
                        sNameEscaped,
                        escapeAttr(str(asRow[0])),
                        " checked" if fChecked else "",
                        sExtraAttribs,
                        escapeElem(str(asRow[2])),
                    )
                )
        return self._add("        </div></div></div>\n" "      </li>\n")
Esempio n. 14
0
 def addCheckBox(self, sName, fChecked, sLabel, sExtraAttribs = ''):
     """Adds an check box."""
     if self._fReadOnly:
         return self.addCheckBoxRO(sName, fChecked, sLabel, sExtraAttribs);
     self._addLabel(sName, sLabel, 'checkbox');
     fChecked = self._reinterpretBool(fChecked);
     return self._add('          <input name="%s" id="%s" type="checkbox"%s%s value="1" class="tmform-checkbox">\n'
                      '        </div></div>\n'
                      '      </li>\n'
                      % (escapeAttr(sName), escapeAttr(sName), ' checked' if fChecked else '', sExtraAttribs));
 def addTextRO(self, sName, sValue, sLabel, sSubClass="string", sExtraAttribs="", sPostHtml=""):
     """Adds a read-only text input."""
     if sSubClass not in ("int", "long", "string", "uuid", "timestamp", "wide"):
         raise Exception(sSubClass)
     self._addLabel(sName, sLabel, sSubClass)
     return self._add(
         '          <input name="%s" id="%s" type="text" readonly%s value="%s" class="tmform-input-readonly">%s\n'
         "        </div></div>\n"
         "      </li>\n" % (escapeAttr(sName), escapeAttr(sName), sExtraAttribs, escapeElem(str(sValue)), sPostHtml)
     )
Esempio n. 16
0
 def addCheckBoxRO(self, sName, fChecked, sLabel, sExtraAttribs = ''):
     """Adds an readonly check box."""
     self._addLabel(sName, sLabel, 'checkbox');
     fChecked = self._reinterpretBool(fChecked);
     # Hack Alert! The onclick and onkeydown are for preventing editing and fake readonly/disabled.
     return self._add('          <input name="%s" id="%s" type="checkbox"%s readonly%s value="1" class="readonly"\n'
                      '              onclick="return false" onkeydown="return false">\n'
                      '        </div></div>\n'
                      '      </li>\n'
                      % (escapeAttr(sName), escapeAttr(sName), ' checked' if fChecked else '', sExtraAttribs));
Esempio n. 17
0
 def addCheckBox(self, sName, fChecked, sLabel, sExtraAttribs = ''):
     """Adds an check box."""
     if self._fReadOnly:
         return self.addCheckBoxRO(sName, fChecked, sLabel, sExtraAttribs);
     self._addLabel(sName, sLabel, 'checkbox');
     fChecked = self._reinterpretBool(fChecked);
     return self._add('          <input name="%s" id="%s" type="checkbox"%s%s value="1" class="tmform-checkbox">\n'
                      '        </div></div>\n'
                      '      </li>\n'
                      % (escapeAttr(sName), escapeAttr(sName), ' checked' if fChecked else '', sExtraAttribs));
Esempio n. 18
0
 def addCheckBoxRO(self, sName, fChecked, sLabel, sExtraAttribs = ''):
     """Adds an readonly check box."""
     self._addLabel(sName, sLabel, 'checkbox');
     fChecked = self._reinterpretBool(fChecked);
     # Hack Alert! The onclick and onkeydown are for preventing editing and fake readonly/disabled.
     return self._add('          <input name="%s" id="%s" type="checkbox"%s readonly%s value="1" class="readonly"\n'
                      '              onclick="return false" onkeydown="return false">\n'
                      '        </div></div>\n'
                      '      </li>\n'
                      % (escapeAttr(sName), escapeAttr(sName), ' checked' if fChecked else '', sExtraAttribs));
 def addCheckBox(self, sName, fChecked, sLabel, sExtraAttribs=""):
     """Adds an check box."""
     if self._fReadOnly:
         return self.addCheckBoxRO(sName, fChecked, sLabel, sExtraAttribs)
     self._addLabel(sName, sLabel, "checkbox")
     fChecked = self._reinterpretBool(fChecked)
     return self._add(
         '          <input name="%s" id="%s" type="checkbox"%s%s value="1" class="tmform-checkbox">\n'
         "        </div></div>\n"
         "      </li>\n" % (escapeAttr(sName), escapeAttr(sName), " checked" if fChecked else "", sExtraAttribs)
     )
 def addMultilineTextRO(self, sName, sValue, sLabel, sSubClass="string", sExtraAttribs=""):
     """Adds a multiline read-only text input."""
     if sSubClass not in ("int", "long", "string", "uuid", "timestamp"):
         raise Exception(sSubClass)
     self._addLabel(sName, sLabel, sSubClass)
     sNewValue = str(sValue) if not isinstance(sValue, list) else "\n".join(sValue)
     return self._add(
         '          <textarea name="%s" id="%s" readonly %s>%s</textarea>\n'
         "        </div></div>\n"
         "      </li>\n" % (escapeAttr(sName), escapeAttr(sName), sExtraAttribs, escapeElem(sNewValue))
     )
Esempio n. 21
0
    def _generateMenus(self):
        """
        Generates the two menus, returning them as (sTopMenuItems, sSideMenuItems).
        """
        #
        # We use the action to locate the side menu.
        #
        aasSideMenu = None
        for cchAction in range(len(self._sAction), 1, -1):
            sActionParam = "%s=%s" % (self.ksParamAction, self._sAction[:cchAction])
            for aoItem in self._aaoMenus:
                if aoItem[1].find(sActionParam) > 0:
                    aasSideMenu = aoItem[2]
                    break
                for asSubItem in aoItem[2]:
                    if asSubItem[1].find(sActionParam) > 0:
                        aasSideMenu = aoItem[2]
                        break
                if aasSideMenu is not None:
                    break

        #
        # Top menu first.
        #
        sTopMenuItems = ""
        for aoItem in self._aaoMenus:
            if aasSideMenu is aoItem[2]:
                sTopMenuItems += '<li class="current_page_item">'
            else:
                sTopMenuItems += "<li>"
            sTopMenuItems += (
                '<a href="' + webutils.escapeAttr(aoItem[1]) + '">' + webutils.escapeElem(aoItem[0]) + "</a></li>\n"
            )

        #
        # Side menu (if found).
        #
        sActionParam = "%s=%s" % (self.ksParamAction, self._sAction)
        sSideMenuItems = ""
        if aasSideMenu is not None:
            for asSubItem in aasSideMenu:
                if asSubItem[1].find(sActionParam) > 0:
                    sSideMenuItems += '<li class="current_page_item">'
                else:
                    sSideMenuItems += "<li>"
                sSideMenuItems += (
                    '<a href="'
                    + webutils.escapeAttr(asSubItem[1])
                    + '">'
                    + webutils.escapeElem(asSubItem[0])
                    + "</a></li>\n"
                )

        return (sTopMenuItems, sSideMenuItems)
Esempio n. 22
0
    def _generateMenus(self):
        """
        Generates the two menus, returning them as (sTopMenuItems, sSideMenuItems).
        """
        fReadOnly = self.isReadOnlyUser();

        #
        # We use the action to locate the side menu.
        #
        aasSideMenu = None;
        for cchAction in range(len(self._sAction), 1, -1):
            sActionParam = '%s=%s' % (self.ksParamAction, self._sAction[:cchAction]);
            for aoItem in self._aaoMenus:
                if self._isMenuMatch(aoItem[1], sActionParam):
                    aasSideMenu = aoItem[2];
                    break;
                for asSubItem in aoItem[2]:
                    if self._isMenuMatch(asSubItem[1], sActionParam):
                        aasSideMenu = aoItem[2];
                        break;
                if aasSideMenu is not None:
                    break;

        #
        # Top menu first.
        #
        sTopMenuItems = '';
        for aoItem in self._aaoMenus:
            if aasSideMenu is aoItem[2]:
                sTopMenuItems += '<li class="current_page_item">';
            else:
                sTopMenuItems += '<li>';
            sTopMenuItems += '<a href="' + webutils.escapeAttr(aoItem[1]) + '">' \
                           + webutils.escapeElem(aoItem[0]) + '</a></li>\n';

        #
        # Side menu (if found).
        #
        sActionParam = '%s=%s' % (self.ksParamAction, self._sAction);
        sSideMenuItems = '';
        if aasSideMenu is not None:
            for asSubItem in aasSideMenu:
                if asSubItem[1] is not None:
                    if not asSubItem[2] or not fReadOnly:
                        if self._isSideMenuMatch(asSubItem[1], sActionParam):
                            sSideMenuItems += '<li class="current_page_item">';
                        else:
                            sSideMenuItems += '<li>';
                        sSideMenuItems += '<a href="' + webutils.escapeAttr(asSubItem[1]) + '">' \
                                        + webutils.escapeElem(asSubItem[0]) + '</a></li>\n';
                else:
                    sSideMenuItems += '<li class="subheader_item">' + webutils.escapeElem(asSubItem[0]) + '</li>';
        return (sTopMenuItems, sSideMenuItems);
    def _generateMenus(self):
        """
        Generates the two menus, returning them as (sTopMenuItems, sSideMenuItems).
        """
        fReadOnly = self.isReadOnlyUser();

        #
        # We use the action to locate the side menu.
        #
        aasSideMenu = None;
        for cchAction in range(len(self._sAction), 1, -1):
            sActionParam = '%s=%s' % (self.ksParamAction, self._sAction[:cchAction]);
            for aoItem in self._aaoMenus:
                if self._isMenuMatch(aoItem[1], sActionParam):
                    aasSideMenu = aoItem[2];
                    break;
                for asSubItem in aoItem[2]:
                    if self._isMenuMatch(asSubItem[1], sActionParam):
                        aasSideMenu = aoItem[2];
                        break;
                if aasSideMenu is not None:
                    break;

        #
        # Top menu first.
        #
        sTopMenuItems = '';
        for aoItem in self._aaoMenus:
            if aasSideMenu is aoItem[2]:
                sTopMenuItems += '<li class="current_page_item">';
            else:
                sTopMenuItems += '<li>';
            sTopMenuItems += '<a href="' + webutils.escapeAttr(aoItem[1]) + '">' \
                           + webutils.escapeElem(aoItem[0]) + '</a></li>\n';

        #
        # Side menu (if found).
        #
        sActionParam = '%s=%s' % (self.ksParamAction, self._sAction);
        sSideMenuItems = '';
        if aasSideMenu is not None:
            for asSubItem in aasSideMenu:
                if asSubItem[1] is not None:
                    if not asSubItem[2] or not fReadOnly:
                        if self._isSideMenuMatch(asSubItem[1], sActionParam):
                            sSideMenuItems += '<li class="current_page_item">';
                        else:
                            sSideMenuItems += '<li>';
                        sSideMenuItems += '<a href="' + webutils.escapeAttr(asSubItem[1]) + '">' \
                                        + webutils.escapeElem(asSubItem[0]) + '</a></li>\n';
                else:
                    sSideMenuItems += '<li class="subheader_item">' + webutils.escapeElem(asSubItem[0]) + '</li>';
        return (sTopMenuItems, sSideMenuItems);
Esempio n. 24
0
    def _generateMenus(self):
        """
        Generates the two menus, returning them as (sTopMenuItems, sSideMenuItems).
        """
        #
        # We use the action to locate the side menu.
        #
        aasSideMenu = None
        for cchAction in range(len(self._sAction), 1, -1):
            sActionParam = '%s=%s' % (self.ksParamAction,
                                      self._sAction[:cchAction])
            for aoItem in self._aaoMenus:
                if self._isMenuMatch(aoItem[1], sActionParam):
                    aasSideMenu = aoItem[2]
                    break
                for asSubItem in aoItem[2]:
                    if self._isMenuMatch(asSubItem[1], sActionParam):
                        aasSideMenu = aoItem[2]
                        break
                if aasSideMenu is not None:
                    break

        #
        # Top menu first.
        #
        sTopMenuItems = ''
        for aoItem in self._aaoMenus:
            if aasSideMenu is aoItem[2]:
                sTopMenuItems += '<li class="current_page_item">'
            else:
                sTopMenuItems += '<li>'
            sTopMenuItems += '<a href="' + webutils.escapeAttr(aoItem[1]) + '">' \
                           + webutils.escapeElem(aoItem[0]) + '</a></li>\n'

        #
        # Side menu (if found).
        #
        sActionParam = '%s=%s' % (self.ksParamAction, self._sAction)
        sSideMenuItems = ''
        if aasSideMenu is not None:
            for asSubItem in aasSideMenu:
                if self._isSideMenuMatch(asSubItem[1], sActionParam):
                    sSideMenuItems += '<li class="current_page_item">'
                else:
                    sSideMenuItems += '<li>'
                sSideMenuItems += '<a href="' + webutils.escapeAttr(asSubItem[1]) + '">' \
                                + webutils.escapeElem(asSubItem[0]) + '</a></li>\n'

        return (sTopMenuItems, sSideMenuItems)
Esempio n. 25
0
 def addComboBoxRO(self, sName, sSelected, sLabel, aoOptions, sExtraAttribs = ''):
     """Adds a read-only combo box."""
     self.addTextHidden(sName, sSelected);
     self._addLabel(sName, sLabel, 'combobox-readonly');
     self._add('          <select name="%s" id="%s" disabled class="tmform-combobox"%s>\n'
               % (escapeAttr(sName), escapeAttr(sName), sExtraAttribs));
     for iValue, sText, _ in aoOptions:
         sValue = str(iValue);
         self._add('            <option value="%s"%s>%s</option>\n'
                   % (escapeAttr(sValue), ' selected' if sValue == str(sSelected) else '',
                      escapeElem(sText)));
     return self._add('          </select>\n'
                      '        </div></div>\n'
                      '      </li>\n'
                     );
Esempio n. 26
0
 def addComboBoxRO(self, sName, sSelected, sLabel, aoOptions, sExtraAttribs = ''):
     """Adds a read-only combo box."""
     self.addTextHidden(sName, sSelected);
     self._addLabel(sName, sLabel, 'combobox-readonly');
     self._add('          <select name="%s" id="%s" disabled class="tmform-combobox"%s>\n'
               % (escapeAttr(sName), escapeAttr(sName), sExtraAttribs));
     for iValue, sText, _ in aoOptions:
         sValue = str(iValue);
         self._add('            <option value="%s"%s>%s</option>\n'
                   % (escapeAttr(sValue), ' selected' if sValue == str(sSelected) else '',
                      escapeElem(sText)));
     return self._add('          </select>\n'
                      '        </div></div>\n'
                      '      </li>\n'
                     );
Esempio n. 27
0
    def _formatCommentCell(self, sComment, cMaxLines = 3, cchMaxLine = 63):
        """
        Helper functions for formatting comment cell.
        Returns None or WuiRawHtml instance.
        """
        # Nothing to do for empty comments.
        if sComment is None:
            return None;
        sComment = sComment.strip();
        if len(sComment) == 0:
            return None;

        # Restrict the text if necessary, making the whole text available thru mouse-over.
        ## @todo this would be better done by java script or smth, so it could automatically adjust to the table size.
        if len(sComment) > cchMaxLine or sComment.count('\n') >= cMaxLines:
            sShortHtml = '';
            for iLine, sLine in enumerate(sComment.split('\n')):
                if iLine >= cMaxLines:
                    break;
                if iLine > 0:
                    sShortHtml += '<br>\n';
                if len(sLine) > cchMaxLine:
                    sShortHtml += webutils.escapeElem(sLine[:(cchMaxLine - 3)]);
                    sShortHtml += '...';
                else:
                    sShortHtml += webutils.escapeElem(sLine);
            return WuiRawHtml('<span class="tmcomment" title="%s">%s</span>' % (webutils.escapeAttr(sComment), sShortHtml,));

        return WuiRawHtml('<span class="tmcomment">%s</span>' % (webutils.escapeElem(sComment).replace('\n', '<br>'),));
Esempio n. 28
0
    def _debugRenderPanel(self):
        """
        Renders a simple form for controlling WUI debugging.

        Returns the HTML for it.
        """

        sHtml = '<div id="debug-panel">\n' ' <form id="debug-panel-form" type="get" action="#">\n'

        for sKey, oValue in self._dParams.iteritems():
            if sKey not in self.kasDbgParams:
                sHtml += '  <input type="hidden" name="%s" value="%s"/>\n' % (
                    webutils.escapeAttr(sKey),
                    webutils.escapeAttrToStr(oValue),
                )

        for aoCheckBox in (
            [self.ksParamDbgSqlTrace, self._fDbgSqlTrace, "SQL trace"],
            [self.ksParamDbgSqlExplain, self._fDbgSqlExplain, "SQL explain"],
        ):
            sHtml += ' <input type="checkbox" name="%s" value="1"%s>%s</input>\n' % (
                aoCheckBox[0],
                " checked" if aoCheckBox[1] else "",
                aoCheckBox[2],
            )

        sHtml += '  <button type="submit">Apply</button>\n'
        sHtml += " </form>\n" "</div>\n"
        return sHtml
    def toHtml(self):
        """
        Returns a simple HTML anchor element.
        """
        sExtraAttrs = self.sExtraAttrs;
        if self.sConfirm is not None:
            sExtraAttrs += 'onclick=\'return confirm("%s");\' ' % (webutils.escapeAttr(self.sConfirm),);
        if self.sTitle is not None:
            sExtraAttrs += 'title="%s" ' % (webutils.escapeAttr(self.sTitle),);
        if sExtraAttrs and sExtraAttrs[-1] != ' ':
            sExtraAttrs += ' ';

        sFmt = '[<a %shref="%s">%s</a>]';
        if not self.fBracketed:
            sFmt = '<a %shref="%s">%s</a>';
        return sFmt % (sExtraAttrs, webutils.escapeAttr(self.sUrl), webutils.escapeElem(self.sName));
 def addComboBox(self, sName, sSelected, sLabel, aoOptions, sExtraAttribs=""):
     """Adds a combo box."""
     if self._fReadOnly:
         return self.addComboBoxRO(sName, sSelected, sLabel, aoOptions, sExtraAttribs)
     self._addLabel(sName, sLabel, "combobox")
     self._add(
         '          <select name="%s" id="%s" class="tmform-combobox"%s>\n'
         % (escapeAttr(sName), escapeAttr(sName), sExtraAttribs)
     )
     for iValue, sText, _ in aoOptions:
         sValue = str(iValue)
         self._add(
             '            <option value="%s"%s>%s</option>\n'
             % (escapeAttr(sValue), " selected" if sValue == str(sSelected) else "", escapeElem(sText))
         )
     return self._add("          </select>\n" "        </div></div>\n" "      </li>\n")
    def toHtml(self):
        """
        Returns a simple HTML anchor element.
        """
        sExtraAttrs = self.sExtraAttrs
        if self.sConfirm is not None:
            sExtraAttrs += "onclick='return confirm(\"%s\");' " % (webutils.escapeAttr(self.sConfirm),)
        if self.sTitle is not None:
            sExtraAttrs += 'title="%s" ' % (webutils.escapeAttr(self.sTitle),)
        if len(sExtraAttrs) > 0 and sExtraAttrs[-1] != " ":
            sExtraAttrs += " "

        sFmt = '[<a %shref="%s">%s</a>]'
        if not self.fBracketed:
            sFmt = '<a %shref="%s">%s</a>'
        return sFmt % (sExtraAttrs, webutils.escapeAttr(self.sUrl), webutils.escapeElem(self.sName))
Esempio n. 32
0
 def _addLabel(self, sName, sLabel, sDivSubClass = 'normal'):
     """Internal worker for adding a label."""
     if sName in self._dErrors:
         sError = self._dErrors[sName];
         if utils.isString(sError):          # List error trick (it's an associative array).
             return self._add('      <li>\n'
                              '        <div class="tmform-field"><div class="tmform-field-%s">\n'
                              '          <label for="%s" class="tmform-error-label">%s\n'
                              '              <span class="tmform-error-desc">%s</span>\n'
                              '          </label>\n'
                              % (escapeAttr(sDivSubClass), escapeAttr(sName), escapeElem(sLabel),
                                 self._escapeErrorText(sError), ) );
     return self._add('      <li>\n'
                      '        <div class="tmform-field"><div class="tmform-field-%s">\n'
                      '          <label  for="%s">%s</label>\n'
                      % (escapeAttr(sDivSubClass), escapeAttr(sName), escapeElem(sLabel)) );
Esempio n. 33
0
    def toHtml(self):
        """
        Returns a simple HTML anchor element.
        """
        sExtraAttrs = self.sExtraAttrs;
        if self.sConfirm is not None:
            sExtraAttrs += 'onclick=\'return confirm("%s");\' ' % (webutils.escapeAttr(self.sConfirm),);
        if self.sTitle is not None:
            sExtraAttrs += 'title="%s" ' % (webutils.escapeAttr(self.sTitle),);
        if sExtraAttrs and sExtraAttrs[-1] != ' ':
            sExtraAttrs += ' ';

        sFmt = '[<a %shref="%s">%s</a>]';
        if not self.fBracketed:
            sFmt = '<a %shref="%s">%s</a>';
        return sFmt % (sExtraAttrs, webutils.escapeAttr(self.sUrl), webutils.escapeElem(self.sName));
Esempio n. 34
0
 def _formatSeriesNameForTable(self, oSet, idKey):
     oTestBox = oSet.dSubjects[idKey]
     sHtml = u'<td>'
     sHtml += WuiTestResultsForTestBoxLink(
         idKey, oTestBox.sName, self._dExtraTestResultsParams).toHtml()
     sHtml += u' '
     sHtml += WuiTestBoxDetailsLinkShort(oTestBox).toHtml()
     sHtml += u' '
     sHtml += WuiReportSummaryLink(
         ReportModelBase.ksSubTestBox,
         oTestBox.idTestBox,
         dExtraParams=self._dExtraParams).toHtml()
     sHtml += u'</td>'
     sOsAndVer = '%s %s' % (
         oTestBox.sOs,
         oTestBox.sOsVersion.strip(),
     )
     if len(sOsAndVer) < 22:
         sHtml += u'<td>%s</td>' % (webutils.escapeElem(sOsAndVer), )
     else:  # wonder if td.title works..
         sHtml += u'<td title="%s" width="1%%" style="white-space:nowrap;">%s...</td>' \
               % (webutils.escapeAttr(sOsAndVer), webutils.escapeElem(sOsAndVer[:20]))
     sHtml += u'<td>%s</td>' % (webutils.escapeElem(
         oTestBox.getArchBitString()), )
     sHtml += u'<td>%s</td>' % (webutils.escapeElem(
         oTestBox.getPrettyCpuVendor()), )
     sHtml += u'<td>%s' % (oTestBox.getPrettyCpuVersion(), )
     if oTestBox.fCpuNestedPaging: sHtml += u', np'
     elif oTestBox.fCpuHwVirt: sHtml += u', hw'
     else: sHtml += u', raw'
     if oTestBox.fCpu64BitGuest: sHtml += u', 64'
     sHtml += u'</td>'
     return sHtml
Esempio n. 35
0
 def _addLabel(self, sName, sLabel, sDivSubClass = 'normal'):
     """Internal worker for adding a label."""
     if sName in self._dErrors:
         sError = self._dErrors[sName];
         if utils.isString(sError):          # List error trick (it's an associative array).
             return self._add('      <li>\n'
                              '        <div class="tmform-field"><div class="tmform-field-%s">\n'
                              '          <label for="%s" class="tmform-error-label">%s\n'
                              '              <span class="tmform-error-desc">%s</span>\n'
                              '          </label>\n'
                              % (escapeAttr(sDivSubClass), escapeAttr(sName), escapeElem(sLabel),
                                 self._escapeErrorText(sError), ) );
     return self._add('      <li>\n'
                      '        <div class="tmform-field"><div class="tmform-field-%s">\n'
                      '          <label  for="%s">%s</label>\n'
                      % (escapeAttr(sDivSubClass), escapeAttr(sName), escapeElem(sLabel)) );
Esempio n. 36
0
    def _formatCommentCell(self, sComment, cMaxLines = 3, cchMaxLine = 63):
        """
        Helper functions for formatting comment cell.
        Returns None or WuiRawHtml instance.
        """
        # Nothing to do for empty comments.
        if sComment is None:
            return None;
        sComment = sComment.strip();
        if not sComment:
            return None;

        # Restrict the text if necessary, making the whole text available thru mouse-over.
        ## @todo this would be better done by java script or smth, so it could automatically adjust to the table size.
        if len(sComment) > cchMaxLine or sComment.count('\n') >= cMaxLines:
            sShortHtml = '';
            for iLine, sLine in enumerate(sComment.split('\n')):
                if iLine >= cMaxLines:
                    break;
                if iLine > 0:
                    sShortHtml += '<br>\n';
                if len(sLine) > cchMaxLine:
                    sShortHtml += webutils.escapeElem(sLine[:(cchMaxLine - 3)]);
                    sShortHtml += '...';
                else:
                    sShortHtml += webutils.escapeElem(sLine);
            return WuiRawHtml('<span class="tmcomment" title="%s">%s</span>' % (webutils.escapeAttr(sComment), sShortHtml,));

        return WuiRawHtml('<span class="tmcomment">%s</span>' % (webutils.escapeElem(sComment).replace('\n', '<br>'),));
    def show(self, fShowNavigation=True):
        """
        Displays the list.
        Returns (Title, HTML) on success, raises exception on error.
        """
        assert self._aoActions is not None
        assert self._sAction is not None

        sPageBody = (
            '<script language="JavaScript">\n'
            "function toggle%s(oSource) {\n"
            "    aoCheckboxes = document.getElementsByName('%s');\n"
            "    for(var i in aoCheckboxes)\n"
            "        aoCheckboxes[i].checked = oSource.checked;\n"
            "}\n"
            "</script>\n" % ("" if self._sId is None else self._sId, self._sCheckboxName)
        )
        if fShowNavigation:
            sPageBody += self._generateNavigation("top")
        if len(self._aoEntries) > 0:

            sPageBody += '<form action="?%s" method="post" class="tmlistactionform">\n' % (
                webutils.encodeUrlParams({WuiDispatcherBase.ksParamAction: self._sAction}),
            )
            sPageBody += self._generateTable()

            sPageBody += (
                "  <label>Actions</label>\n"
                '  <select name="%s" id="%s-action-combo" class="tmlistactionform-combo">\n'
                % (webutils.escapeAttr(WuiDispatcherBase.ksParamListAction), webutils.escapeAttr(self._sId))
            )
            for oValue, sText, _ in self._aoActions:
                sPageBody += '    <option value="%s">%s</option>\n' % (
                    webutils.escapeAttr(unicode(oValue)),
                    webutils.escapeElem(sText),
                )
            sPageBody += "  </select>\n"
            sPageBody += '  <input type="submit"></input>\n'
            sPageBody += "</form>\n"
            if fShowNavigation:
                sPageBody += self._generateNavigation("bottom")
        else:
            sPageBody += "<p>No entries.</p>"

        return (self._composeTitle(), sPageBody)
Esempio n. 38
0
 def addText(self,
             sName,
             sValue,
             sLabel,
             sSubClass='string',
             sExtraAttribs='',
             sPostHtml=''):
     """Adds a text input."""
     if self._fReadOnly:
         return self.addTextRO(sName, sValue, sLabel, sSubClass,
                               sExtraAttribs)
     if sSubClass not in ('int', 'long', 'string', 'uuid', 'timestamp',
                          'wide'):
         raise Exception(sSubClass)
     self._addLabel(sName, sLabel, sSubClass)
     return self._add(
         '          <input name="%s" id="%s" type="text"%s value="%s">%s\n'
         '        </div></div>\n'
         '      </li>\n' % (escapeAttr(sName), escapeAttr(sName),
                            sExtraAttribs, escapeElem(sValue), sPostHtml))
Esempio n. 39
0
    def _addList(self, sName, aoRows, sLabel, fUseTable = False, sId = 'dummy', sExtraAttribs = ''):
        """
        Adds a list of items to check.

        @param sName  Name of HTML form element
        @param aoRows  List of [sValue, fChecked, sName] sub-arrays.
        @param sLabel Label of HTML form element
        """
        fReadOnly = self._fReadOnly; ## @todo add this as a parameter.
        if fReadOnly:
            sExtraAttribs += ' readonly onclick="return false" onkeydown="return false"';

        self._addLabel(sName, sLabel, 'list');
        if len(aoRows) == 0:
            return self._add('No items</div></div></li>')
        sNameEscaped = escapeAttr(sName);

        self._add('          <div class="tmform-checkboxes-container" id="%s">\n' % (escapeAttr(sId),));
        if fUseTable:
            self._add('          <table>\n');
            for asRow in aoRows:
                assert len(asRow) == 3; # Don't allow sloppy input data!
                fChecked = self._reinterpretBool(asRow[1])
                self._add('            <tr>\n'
                          '              <td><input type="checkbox" name="%s" value="%s"%s%s></td>\n'
                          '              <td>%s</td>\n'
                          '            </tr>\n'
                          % ( sNameEscaped, escapeAttr(str(asRow[0])), ' checked' if fChecked else '', sExtraAttribs,
                              escapeElem(str(asRow[2])), ));
            self._add('          </table>\n');
        else:
            for asRow in aoRows:
                assert len(asRow) == 3; # Don't allow sloppy input data!
                fChecked = self._reinterpretBool(asRow[1])
                self._add('            <div class="tmform-checkbox-holder">'
                          '<input type="checkbox" name="%s" value="%s"%s%s> %s</input></div>\n'
                          % ( sNameEscaped, escapeAttr(str(asRow[0])), ' checked' if fChecked else '', sExtraAttribs,
                              escapeElem(str(asRow[2])),));
        return self._add('        </div></div></div>\n'
                         '      </li>\n');
Esempio n. 40
0
 def addComboBox(self,
                 sName,
                 sSelected,
                 sLabel,
                 aoOptions,
                 sExtraAttribs=''):
     """Adds a combo box."""
     if self._fReadOnly:
         return self.addComboBoxRO(sName, sSelected, sLabel, aoOptions,
                                   sExtraAttribs)
     self._addLabel(sName, sLabel, 'combobox')
     self._add(
         '          <select name="%s" id="%s" class="tmform-combobox"%s>\n'
         % (escapeAttr(sName), escapeAttr(sName), sExtraAttribs))
     for iValue, sText, _ in aoOptions:
         sValue = str(iValue)
         self._add('            <option value="%s"%s>%s</option>\n' %
                   (escapeAttr(sValue), ' selected'
                    if sValue == str(sSelected) else '', escapeElem(sText)))
     return self._add('          </select>\n'
                      '        </div></div>\n'
                      '      </li>\n')
Esempio n. 41
0
    def show(self, fShowNavigation=True):
        """
        Displays the list.
        Returns (Title, HTML) on success, raises exception on error.
        """
        assert self._aoActions is not None
        assert self._sAction is not None

        sPageBody = '<script language="JavaScript">\n' \
                    'function toggle%s(oSource) {\n' \
                    '    aoCheckboxes = document.getElementsByName(\'%s\');\n' \
                    '    for(var i in aoCheckboxes)\n' \
                    '        aoCheckboxes[i].checked = oSource.checked;\n' \
                    '}\n' \
                    '</script>\n' \
                    % ('' if self._sId is None else self._sId, self._sCheckboxName,)
        if fShowNavigation:
            sPageBody += self._generateNavigation('top')
        if len(self._aoEntries) > 0:

            sPageBody += '<form action="?%s" method="post" class="tmlistactionform">\n' \
                       % (webutils.encodeUrlParams({WuiDispatcherBase.ksParamAction: self._sAction,}),)
            sPageBody += self._generateTable()

            sPageBody += '  <label>Actions</label>\n' \
                         '  <select name="%s" id="%s-action-combo" class="tmlistactionform-combo">\n' \
                       % (webutils.escapeAttr(WuiDispatcherBase.ksParamListAction), webutils.escapeAttr(self._sId),)
            for oValue, sText, _ in self._aoActions:
                sPageBody += '    <option value="%s">%s</option>\n' \
                           % (webutils.escapeAttr(unicode(oValue)), webutils.escapeElem(sText), )
            sPageBody += '  </select>\n'
            sPageBody += '  <input type="submit"></input>\n'
            sPageBody += '</form>\n'
            if fShowNavigation:
                sPageBody += self._generateNavigation('bottom')
        else:
            sPageBody += '<p>No entries.</p>'

        return (self._composeTitle(), sPageBody)
Esempio n. 42
0
    def show(self):
        """
        Generates the tooltip.
        Returns (sTitle, HTML).
        """
        sHtml = '<div class="tmvcstimeline tmvcstimelinetooltip">\n'

        oCurDate = None
        for oEntry in self.aoEntries:
            oTsZulu = db.dbTimestampToZuluDatetime(oEntry.tsCreated)
            if oCurDate is None or oCurDate != oTsZulu.date():
                if oCurDate is not None:
                    sHtml += ' </dl>\n'
                oCurDate = oTsZulu.date()
                sHtml += ' <h2>%s:</h2>\n' \
                         ' <dl>\n' \
                       % (oTsZulu.strftime('%Y-%m-%d'),)

            sEntry = '  <dt id="r%s">' % (oEntry.iRevision, )
            sEntry += '<a href="%s">' \
                    % ( webutils.escapeAttr(config.g_ksTracChangsetUrlFmt
                                            % { 'iRevision': oEntry.iRevision, 'sRepository': oEntry.sRepository,}), )

            sEntry += '<span class="tmvcstimeline-time">%s</span>' % (
                oTsZulu.strftime('%H:%MZ'), )
            sEntry += ' Changeset <span class="tmvcstimeline-rev">[%s]</span>' % (
                oEntry.iRevision, )
            sEntry += ' by <span class="tmvcstimeline-author">%s</span>' % (
                webutils.escapeElem(oEntry.sAuthor), )
            sEntry += '</a>\n'
            sEntry += '</dt>\n'
            sEntry += '  <dd>%s</dd>\n' % (webutils.escapeElem(
                oEntry.sMessage), )

            sHtml += sEntry

        if oCurDate is not None:
            sHtml += ' </dl>\n'
        sHtml += '</div>\n'

        return ('VCS History Tooltip', sHtml)
 def _formatSeriesNameForTable(self, oSet, idKey):
     oTestBox = oSet.dSubjects[idKey];
     sHtml  = u'<td>';
     sHtml += WuiReportSummaryLink(ReportModelBase.ksSubTestBox, oTestBox.idTestBox, sName = oTestBox.sName,
                                   dExtraParams = self._dExtraParams).toHtml();
     sHtml += u' ';
     sHtml += WuiTestBoxDetailsLink(oTestBox.idTestBox).toHtml();
     sHtml += u'</td>';
     sOsAndVer = '%s %s' % (oTestBox.sOs, oTestBox.sOsVersion.strip(),);
     if len(sOsAndVer) < 22:
         sHtml += u'<td>%s</td>' % (webutils.escapeElem(sOsAndVer),);
     else: # wonder if td.title works..
         sHtml += u'<td title="%s" width="1%%" style="white-space:nowrap;">%s...</td>' \
               % (webutils.escapeAttr(sOsAndVer), webutils.escapeElem(sOsAndVer[:20]));
     sHtml += u'<td>%s</td>'    % (webutils.escapeElem(oTestBox.getArchBitString()),);
     sHtml += u'<td>%s</td>'    % (webutils.escapeElem(oTestBox.getPrettyCpuVendor()),);
     sHtml += u'<td>%s'         % (oTestBox.getPrettyCpuVersion(),);
     if oTestBox.fCpuNestedPaging:   sHtml += u', np';
     elif oTestBox.fCpuHwVirt:       sHtml += u', hw';
     else:                           sHtml += u', raw';
     if oTestBox.fCpu64BitGuest:     sHtml += u', 64';
     sHtml += u'</td>';
     return sHtml;
    def show(self):
        """
        Generates the tooltip.
        Returns (sTitle, HTML).
        """
        sHtml  = '<div class="tmvcstimeline tmvcstimelinetooltip">\n';

        oCurDate = None;
        for oEntry in self.aoEntries:
            oTsZulu = db.dbTimestampToZuluDatetime(oEntry.tsCreated);
            if oCurDate is None or oCurDate != oTsZulu.date():
                if oCurDate is not None:
                    sHtml += ' </dl>\n'
                oCurDate = oTsZulu.date();
                sHtml += ' <h2>%s:</h2>\n' \
                         ' <dl>\n' \
                       % (oTsZulu.strftime('%Y-%m-%d'),);

            sEntry  = '  <dt id="r%s">' % (oEntry.iRevision, );
            sEntry += '<a href="%s">' \
                    % ( webutils.escapeAttr(config.g_ksTracChangsetUrlFmt
                                            % { 'iRevision': oEntry.iRevision, 'sRepository': oEntry.sRepository,}), );

            sEntry += '<span class="tmvcstimeline-time">%s</span>' % ( oTsZulu.strftime('%H:%MZ'), );
            sEntry += ' Changeset <span class="tmvcstimeline-rev">[%s]</span>' % ( oEntry.iRevision, );
            sEntry += ' by <span class="tmvcstimeline-author">%s</span>' % ( webutils.escapeElem(oEntry.sAuthor), );
            sEntry += '</a>\n';
            sEntry += '</dt>\n';
            sEntry += '  <dd>%s</dd>\n' % ( webutils.escapeElem(oEntry.sMessage), );

            sHtml += sEntry;

        if oCurDate is not None:
            sHtml += ' </dl>\n';
        sHtml += '</div>\n';

        return ('VCS History Tooltip', sHtml);
Esempio n. 45
0
    def renderGraph(self):
        aoTable = self._oData.aoTable
        sReport = '<div class="tmbargraph">\n'

        # Figure the range.
        fpMin = self.fpMin
        fpMax = self.fpMax
        if self.fpMax is None:
            fpMax = float(aoTable[1].aoValues[0])
        for i in range(1, len(aoTable)):
            for oValue in aoTable[i].aoValues:
                fpValue = float(oValue)
                if fpValue < fpMin:
                    fpMin = fpValue
                if fpValue > fpMax:
                    fpMax = fpValue
        assert fpMin >= 0

        # Format the data.
        sReport += '<table class="tmbargraphl1" border="1" id="%s">\n' % (
            escapeAttr(self._sId), )
        for i in range(1, len(aoTable)):
            oRow = aoTable[i]
            sReport += '  <tr>\n' \
                       '    <td>%s</td>\n' \
                       '    <td height="100%%" width="%spx">\n' \
                       '      <table class="tmbargraphl2" height="100%%" width="100%%" ' \
                                    'border="0" cellspacing="0" cellpadding="0">\n' \
                     % (escapeElem(oRow.sName), escapeAttr(str(self.cxMaxBar + 2)))
            for j in range(len(oRow.aoValues)):
                oValue = oRow.aoValues[j]
                cPct = int(float(oValue) * 100 / fpMax)
                cxBar = int(float(oValue) * self.cxMaxBar / fpMax)
                sValue = escapeElem(oRow.asValues[j])
                sColor = self.kasColors[j % len(self.kasColors)]
                sInvColor = 'white'
                if sColor[0] == '#' and len(sColor) == 7:
                    sInvColor = '#%06x' % (~int(sColor[1:], 16) & 0xffffff, )

                sReport += '        <tr><td>\n' \
                           '          <table class="tmbargraphl3" height="100%%" border="0" cellspacing="0" cellpadding="0">\n' \
                           '            <tr>\n'
                if cPct >= 99:
                    sReport += '              <td width="%spx" nowrap bgcolor="%s" align="right" style="color:%s;">' \
                               '%s&nbsp;</td>\n' \
                             % (cxBar, sColor, sInvColor, sValue)
                elif cPct < 1:
                    sReport += '              <td width="%spx" nowrap style="color:%s;">%s</td>\n' \
                             % (self.cxMaxBar - cxBar, sColor, sValue)
                elif cPct >= 50:
                    sReport += '              <td width="%spx" nowrap bgcolor="%s" align="right" style="color:%s;">' \
                               '%s&nbsp;</td>\n' \
                               '              <td width="%spx" nowrap><div>&nbsp;</div></td>\n' \
                             % (cxBar, sColor, sInvColor, sValue, self.cxMaxBar - cxBar)
                else:
                    sReport += '              <td width="%spx" nowrap bgcolor="%s"></td>\n' \
                               '              <td width="%spx" nowrap>&nbsp;%s</td>\n' \
                             % (cxBar, sColor, self.cxMaxBar - cxBar, sValue)
                sReport += '            </tr>\n' \
                           '          </table>\n' \
                           '        </td></tr>\n'
            sReport += '      </table>\n' \
                       '    </td>\n' \
                       '  </tr>\n'
            if i + 1 < len(aoTable) and len(oRow.aoValues) > 1:
                sReport += '  <tr></tr>\n'

        sReport += '</table>\n'

        sReport += '<div class="tmgraphlegend">\n' \
                   '  <p>Legend:\n'
        for j in range(len(aoTable[0].asValues)):
            sColor = self.kasColors[j % len(self.kasColors)]
            sReport += '    <font color="%s">&#x25A0; %s</font>\n' \
                     % (sColor, escapeElem(aoTable[0].asValues[j]))
        sReport += '  </p>\n' \
                   '</div>\n'

        sReport += '</div>\n'
        return sReport
Esempio n. 46
0
    def _generateInteractiveForm(self):
        """
        Generates the HTML for the interactive form.
        Returns (sTopOfForm, sEndOfForm)
        """

        #
        # The top of the form.
        #
        sTop  = '<form action="#" method="get" id="graphwiz-form">\n' \
                ' <input type="hidden" name="%s" value="%s"/>\n' \
                ' <input type="hidden" name="%s" value="%u"/>\n' \
                % ( WuiMain.ksParamAction,                 WuiMain.ksActionGraphWiz,
                    WuiMain.ksParamGraphWizSrcTestSetId,   self._dParams[WuiMain.ksParamGraphWizSrcTestSetId],
                    )

        sTop += ' <div id="graphwiz-nav">\n'
        sTop  += '  <script type="text/javascript">\n' \
                 '   window.onresize = function(){ return graphwizOnResizeRecalcWidth("graphwiz-nav", "%s"); }\n' \
                 '   window.onload   = function(){ return graphwizOnLoadRememberWidth("graphwiz-nav"); }\n' \
                 '  </script>\n' \
               % ( WuiMain.ksParamGraphWizWidth, )

        #
        # Top: First row.
        #
        sTop += '  <div id="graphwiz-top-1">\n'

        # time.
        sNow = self._dParams[WuiMain.ksParamEffectiveDate]
        if sNow is None: sNow = ''
        sTop += '   <div id="graphwiz-time">\n'
        sTop  += '    <label for="%s">Starting:</label>\n' \
                 '    <input type="text" name="%s" id="%s" value="%s" class="graphwiz-time-input"/>\n' \
               % ( WuiMain.ksParamEffectiveDate,
                   WuiMain.ksParamEffectiveDate, WuiMain.ksParamEffectiveDate, sNow, )

        sTop += '    <input type="hidden" name="%s" value="%u"/>\n' % (
            WuiMain.ksParamReportPeriods,
            1,
        )
        sTop  += '    <label for="%s"> Going back:\n' \
                 '    <input type="text" name="%s" id="%s" value="%s" class="graphwiz-period-input"/>\n' \
               % ( WuiMain.ksParamReportPeriodInHours,
                   WuiMain.ksParamReportPeriodInHours, WuiMain.ksParamReportPeriodInHours,
                   utils.formatIntervalHours(self._dParams[WuiMain.ksParamReportPeriodInHours]) )
        sTop += '   </div>\n'

        # Graph options top row.
        sTop += '   <div id="graphwiz-top-options-1">\n'

        # graph type.
        sTop  += '    <label for="%s">Graph:</label>\n' \
                 '    <select name="%s" id="%s">\n' \
               % ( WuiMain.ksParamGraphWizImpl, WuiMain.ksParamGraphWizImpl, WuiMain.ksParamGraphWizImpl, )
        for (sImpl, sDesc) in WuiMain.kaasGraphWizImplCombo:
            sTop  += '     <option value="%s"%s>%s</option>\n' \
                   % (sImpl, ' selected' if sImpl == self._dParams[WuiMain.ksParamGraphWizImpl] else '', sDesc)
        sTop += '    </select>\n'

        # graph size.
        sTop  += '    <label for="%s">Graph size:</label>\n' \
                 '    <input type="text" name="%s" id="%s" value="%s" class="graphwiz-pixel-input"> x\n' \
                 '    <input type="text" name="%s" id="%s" value="%s" class="graphwiz-pixel-input">\n' \
                 '    <label for="%s">Dpi:</label>'\
                 '    <input type="text" name="%s" id="%s" value="%s" class="graphwiz-dpi-input">\n' \
                 '    <button type="button" onclick="%s">Defaults</button>\n' \
               % ( WuiMain.ksParamGraphWizWidth,
                   WuiMain.ksParamGraphWizWidth,  WuiMain.ksParamGraphWizWidth,  self._dParams[WuiMain.ksParamGraphWizWidth],
                   WuiMain.ksParamGraphWizHeight, WuiMain.ksParamGraphWizHeight, self._dParams[WuiMain.ksParamGraphWizHeight],
                   WuiMain.ksParamGraphWizDpi,
                   WuiMain.ksParamGraphWizDpi,    WuiMain.ksParamGraphWizDpi,    self._dParams[WuiMain.ksParamGraphWizDpi],
                   webutils.escapeAttr('return graphwizSetDefaultSizeValues("graphwiz-nav", "%s", "%s", "%s");'
                                       % ( WuiMain.ksParamGraphWizWidth, WuiMain.ksParamGraphWizHeight,
                                           WuiMain.ksParamGraphWizDpi )),
                 )

        sTop += '   </div>\n'
        # (options row 1)

        sTop += '  </div>\n'
        # (end of row 1)

        #
        # Top: Second row.
        #
        sTop += '  <div id="graphwiz-top-2">\n'

        # Submit
        sFormButton = '<button type="submit">Refresh</button>\n'
        sTop += '   <div id="graphwiz-top-submit">' + sFormButton + '</div>\n'

        # Options.
        sTop += '   <div id="graphwiz-top-options-2">\n'

        sTop  += '    <input type="checkbox" name="%s" id="%s" value="1"%s/>\n' \
                 '    <label for="%s">Tabular data</label>\n' \
               % ( WuiMain.ksParamGraphWizTabular, WuiMain.ksParamGraphWizTabular,
                   ' checked' if self._dParams[WuiMain.ksParamGraphWizTabular] else '',
                   WuiMain.ksParamGraphWizTabular)

        if hasattr(self.oGraphClass, 'setXkcdStyle'):
            sTop  += '    <input type="checkbox" name="%s" id="%s" value="1"%s/>\n' \
                     '    <label for="%s">xkcd-style</label>\n' \
                   % ( WuiMain.ksParamGraphWizXkcdStyle, WuiMain.ksParamGraphWizXkcdStyle,
                       ' checked' if self._dParams[WuiMain.ksParamGraphWizXkcdStyle] else '',
                       WuiMain.ksParamGraphWizXkcdStyle)
        elif self._dParams[WuiMain.ksParamGraphWizXkcdStyle]:
            sTop  += '    <input type="hidden" name="%s" id="%s" value="1"/>\n' \
                   % ( WuiMain.ksParamGraphWizXkcdStyle, WuiMain.ksParamGraphWizXkcdStyle, )

        if not hasattr(self.oGraphClass, 'kfNoErrorBarsSupport'):
            sTop  += '    <input type="checkbox" name="%s" id="%s" value="1"%s title="%s"/>\n' \
                     '    <label for="%s">Error bars,</label>\n' \
                     '    <label for="%s">max: </label>\n' \
                     '    <input type="text" name="%s" id="%s" value="%s" class="graphwiz-maxerrorbar-input" title="%s"/>\n' \
                   % ( WuiMain.ksParamGraphWizErrorBarY, WuiMain.ksParamGraphWizErrorBarY,
                       ' checked' if self._dParams[WuiMain.ksParamGraphWizErrorBarY] else '',
                       'Error bars shows some of the max and min results on the Y-axis.',
                       WuiMain.ksParamGraphWizErrorBarY,
                       WuiMain.ksParamGraphWizMaxErrorBarY,
                       WuiMain.ksParamGraphWizMaxErrorBarY, WuiMain.ksParamGraphWizMaxErrorBarY,
                       self._dParams[WuiMain.ksParamGraphWizMaxErrorBarY],
                       'Maximum number of Y-axis error bar per graph. (Too many makes it unreadable.)'
                       )
        else:
            if self._dParams[WuiMain.ksParamGraphWizErrorBarY]:
                sTop += '<input type="hidden" name="%s" id="%s" value="1">\n' \
                      % ( WuiMain.ksParamGraphWizErrorBarY, WuiMain.ksParamGraphWizErrorBarY, )
            sTop += '<input type="hidden" name="%s" id="%s" value="%u">\n' \
                  % ( WuiMain.ksParamGraphWizMaxErrorBarY, WuiMain.ksParamGraphWizMaxErrorBarY,
                      self._dParams[WuiMain.ksParamGraphWizMaxErrorBarY], )

        sTop  += '    <label for="%s">Font size: </label>\n' \
                 '    <input type="text" name="%s" id="%s" value="%s" class="graphwiz-fontsize-input"/>\n' \
               % ( WuiMain.ksParamGraphWizFontSize,
                   WuiMain.ksParamGraphWizFontSize, WuiMain.ksParamGraphWizFontSize,
                   self._dParams[WuiMain.ksParamGraphWizFontSize], )

        sTop  += '    <label for="%s">Data series: </label>\n' \
                 '    <input type="text" name="%s" id="%s" value="%s" class="graphwiz-maxpergraph-input" title="%s"/>\n' \
               % ( WuiMain.ksParamGraphWizMaxPerGraph,
                   WuiMain.ksParamGraphWizMaxPerGraph, WuiMain.ksParamGraphWizMaxPerGraph,
                   self._dParams[WuiMain.ksParamGraphWizMaxPerGraph],
                   'Max data series per graph.' )

        sTop += '   </div>\n'
        # (options row 2)

        sTop += '  </div>\n'
        # (end of row 2)

        sTop += ' </div>\n'
        # end of top.

        #
        # The end of the page selection.
        #
        sEnd = ' <div id="graphwiz-end-selection">\n'

        #
        # Testbox selection
        #
        aidTestBoxes = list(self._dParams[WuiMain.ksParamGraphWizTestBoxIds])
        sEnd += '  <div id="graphwiz-testboxes" class="graphwiz-end-selection-group">\n' \
                '   <h3>TestBox Selection:</h3>\n' \
                '   <ol class="tmgraph-testboxes">\n'

        # Get a list of eligible testboxes from the DB.
        for oTestBox in self._oModel.getEligibleTestBoxes():
            try:
                aidTestBoxes.remove(oTestBox.idTestBox)
            except:
                sChecked = ''
            else:
                sChecked = ' checked'
            sEnd += '   <li><input type="checkbox" name="%s" value="%s" id="gw-tb-%u"%s/>' \
                    '<label for="gw-tb-%u">%s</label></li>\n' \
                  % ( WuiMain.ksParamGraphWizTestBoxIds, oTestBox.idTestBox, oTestBox.idTestBox, sChecked,
                      oTestBox.idTestBox, oTestBox.sName)

        # List testboxes that have been checked in a different period or something.
        for idTestBox in aidTestBoxes:
            oTestBox = self._oModel.oCache.getTestBox(idTestBox)
            sEnd += '   <li><input type="checkbox" name="%s" value="%s" id="gw-tb-%u" checked/>' \
                    '<label for="gw-tb-%u">%s</label></li>\n' \
                  % ( WuiMain.ksParamGraphWizTestBoxIds, oTestBox.idTestBox, oTestBox.idTestBox,
                      oTestBox.idTestBox, oTestBox.sName)

        sEnd += '   </ol>\n' \
                ' </div>\n'

        #
        # Build category selection.
        #
        aidBuildCategories = list(
            self._dParams[WuiMain.ksParamGraphWizBuildCatIds])
        sEnd += '  <div id="graphwiz-buildcategories" class="graphwiz-end-selection-group">\n' \
                '   <h3>Build Category Selection:</h3>\n' \
                '   <ol class="tmgraph-buildcategories">\n'
        for oBuildCat in self._oModel.getEligibleBuildCategories():
            try:
                aidBuildCategories.remove(oBuildCat.idBuildCategory)
            except:
                sChecked = ''
            else:
                sChecked = ' checked'
            sEnd += '    <li><input type="checkbox" name="%s" value="%s" id="gw-bc-%u" %s/>' \
                    '<label for="gw-bc-%u">%s / %s / %s / %s</label></li>\n' \
                  % ( WuiMain.ksParamGraphWizBuildCatIds, oBuildCat.idBuildCategory, oBuildCat.idBuildCategory, sChecked,
                      oBuildCat.idBuildCategory,
                      oBuildCat.sProduct, oBuildCat.sBranch, oBuildCat.sType, ' & '.join(oBuildCat.asOsArches) )
        assert len(aidBuildCategories) == 0
        # SQL should return all currently selected.

        sEnd += '   </ol>\n' \
                ' </div>\n'

        #
        # Testcase variations.
        #
        sEnd += '  <div id="graphwiz-testcase-variations" class="graphwiz-end-selection-group">\n' \
                '   <h3>Miscellaneous:</h3>\n' \
                '   <ol>'

        sEnd += '    <li>\n' \
                '     <input type="checkbox" id="%s" name="%s" value="1"%s/>\n' \
                '     <label for="%s">Separate by testcase variation.</label>\n' \
                '    </li>\n' \
              % ( WuiMain.ksParamGraphWizSepTestVars, WuiMain.ksParamGraphWizSepTestVars,
                  ' checked' if self._dParams[WuiMain.ksParamGraphWizSepTestVars] else '',
                  WuiMain.ksParamGraphWizSepTestVars )


        sEnd += '    <li>\n' \
                '     <lable for="%s">Test case ID:</label>\n' \
                '     <input type="text" id="%s" name="%s" value="%s" readonly/>\n' \
                '    </li>\n' \
              % ( WuiMain.ksParamGraphWizTestCaseIds,
                  WuiMain.ksParamGraphWizTestCaseIds, WuiMain.ksParamGraphWizTestCaseIds,
                  ','.join([str(i) for i in self._dParams[WuiMain.ksParamGraphWizTestCaseIds]]), )

        sEnd += '   </ol>\n' \
                '  </div>\n'

        #sEnd += '   <h3>&nbsp;</h3>\n';

        #
        # Finish up the form.
        #
        sEnd += '  <div id="graphwiz-end-submit"><p>' + sFormButton + '</p></div>\n'
        sEnd += ' </div>\n' \
                '</form>\n'

        return (sTop, sEnd)
Esempio n. 47
0
    def renderGraph(self):
        aoTable  = self._oData.aoTable;
        sReport  = '<div class="tmbargraph">\n';

        # Figure the range.
        fpMin = self.fpMin;
        fpMax = self.fpMax;
        if self.fpMax is None:
            fpMax = float(aoTable[1].aoValues[0]);
        for i in range(1, len(aoTable)):
            for oValue in aoTable[i].aoValues:
                fpValue = float(oValue);
                if fpValue < fpMin:
                    fpMin = fpValue;
                if fpValue > fpMax:
                    fpMax = fpValue;
        assert fpMin >= 0;

        # Format the data.
        sReport += '<table class="tmbargraphl1" border="1" id="%s">\n' % (escapeAttr(self._sId),);
        for i in range(1, len(aoTable)):
            oRow = aoTable[i];
            sReport += '  <tr>\n' \
                       '    <td>%s</td>\n' \
                       '    <td height="100%%" width="%spx">\n' \
                       '      <table class="tmbargraphl2" height="100%%" width="100%%" ' \
                                    'border="0" cellspacing="0" cellpadding="0">\n' \
                     % (escapeElem(oRow.sName), escapeAttr(str(self.cxMaxBar + 2)));
            for j in range(len(oRow.aoValues)):
                oValue = oRow.aoValues[j];
                cPct   = int(float(oValue) * 100 / fpMax);
                cxBar  = int(float(oValue) * self.cxMaxBar / fpMax);
                sValue = escapeElem(oRow.asValues[j]);
                sColor = self.kasColors[j % len(self.kasColors)];

                sReport += '        <tr><td>\n' \
                           '          <table class="tmbargraphl3" height="100%%" border="0" cellspacing="0" cellpadding="0">\n' \
                           '            <tr>\n';
                if cPct >= 99:
                    sReport += '              <td width="%spx" nowrap bgcolor="%s" align="right">%s&nbsp;</td>\n' \
                             % (cxBar, sColor, sValue);
                elif cPct < 1:
                    sReport += '              <td width="%spx" nowrap style="color:%s;">%s</td>\n' \
                             % (self.cxMaxBar - cxBar, sColor, sValue);
                elif cPct >= 50:
                    sReport += '              <td width="%spx" nowrap bgcolor="%s" align="right">%s&nbsp;</td>\n' \
                               '              <td width="%spx" nowrap><div>&nbsp;</div></td>\n' \
                             % (cxBar, sColor, sValue, self.cxMaxBar - cxBar);
                else:
                    sReport += '              <td width="%spx" nowrap bgcolor="%s"></td>\n' \
                               '              <td width="%spx" nowrap>&nbsp;%s</td>\n' \
                             % (cxBar, sColor, self.cxMaxBar - cxBar, sValue);
                sReport += '            </tr>\n' \
                           '          </table>\n' \
                           '        </td></tr>\n'
            sReport += '      </table>\n' \
                       '    </td>\n' \
                       '  </tr>\n';
            if i + 1 < len(aoTable) and len(oRow.aoValues) > 1:
                sReport += '  <tr></tr>\n'

        sReport += '</table>\n';

        sReport += '<div class="tmgraphlegend">\n' \
                   '  <p>Legend:\n';
        for j in range(len(aoTable[0].asValues)):
            sColor = self.kasColors[j % len(self.kasColors)];
            sReport += '    <font color="%s">&#x25A0; %s</font>\n' \
                     % (sColor, escapeElem(aoTable[0].asValues[j]));
        sReport += '  </p>\n' \
                   '</div>\n';

        sReport += '</div>\n';
        return sReport;
Esempio n. 48
0
    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 = '&nbsp;\\<br>&nbsp;&nbsp;&nbsp;&nbsp;\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)
Esempio n. 49
0
 def __init__(self, sSpanClass, sText):
     WuiRawHtml.__init__(
         self, u'<span class="%s">%s</span>' % (
             webutils.escapeAttr(sSpanClass),
             webutils.escapeElem(sText),
         ))
Esempio n. 50
0
    def _generateInteractiveForm(self):
        """
        Generates the HTML for the interactive form.
        Returns (sTopOfForm, sEndOfForm)
        """

        #
        # The top of the form.
        #
        sTop  = '<form action="#" method="get" id="graphwiz-form">\n' \
                ' <input type="hidden" name="%s" value="%s"/>\n' \
                ' <input type="hidden" name="%s" value="%u"/>\n' \
                % ( WuiMain.ksParamAction,                 WuiMain.ksActionGraphWiz,
                    WuiMain.ksParamGraphWizSrcTestSetId,   self._dParams[WuiMain.ksParamGraphWizSrcTestSetId],
                    );

        sTop  += ' <div id="graphwiz-nav">\n';
        sTop  += '  <script type="text/javascript">\n' \
                 '   window.onresize = function(){ return graphwizOnResizeRecalcWidth("graphwiz-nav", "%s"); }\n' \
                 '   window.onload   = function(){ return graphwizOnLoadRememberWidth("graphwiz-nav"); }\n' \
                 '  </script>\n' \
               % ( WuiMain.ksParamGraphWizWidth, );

        #
        # Top: First row.
        #
        sTop  += '  <div id="graphwiz-top-1">\n';

        # time.
        sNow = self._dParams[WuiMain.ksParamEffectiveDate];
        if sNow is None: sNow = '';
        sTop  += '   <div id="graphwiz-time">\n';
        sTop  += '    <label for="%s">Starting:</label>\n' \
                 '    <input type="text" name="%s" id="%s" value="%s" class="graphwiz-time-input"/>\n' \
               % ( WuiMain.ksParamEffectiveDate,
                   WuiMain.ksParamEffectiveDate, WuiMain.ksParamEffectiveDate, sNow, );

        sTop  += '    <input type="hidden" name="%s" value="%u"/>\n' % ( WuiMain.ksParamReportPeriods, 1, );
        sTop  += '    <label for="%s"> Going back:\n' \
                 '    <input type="text" name="%s" id="%s" value="%s" class="graphwiz-period-input"/>\n' \
               % ( WuiMain.ksParamReportPeriodInHours,
                   WuiMain.ksParamReportPeriodInHours, WuiMain.ksParamReportPeriodInHours,
                   utils.formatIntervalHours(self._dParams[WuiMain.ksParamReportPeriodInHours]) );
        sTop  += '   </div>\n';

        # Graph options top row.
        sTop  += '   <div id="graphwiz-top-options-1">\n';

        # graph type.
        sTop  += '    <label for="%s">Graph:</label>\n' \
                 '    <select name="%s" id="%s">\n' \
               % ( WuiMain.ksParamGraphWizImpl, WuiMain.ksParamGraphWizImpl, WuiMain.ksParamGraphWizImpl, );
        for (sImpl, sDesc) in WuiMain.kaasGraphWizImplCombo:
            sTop  += '     <option value="%s"%s>%s</option>\n' \
                   % (sImpl, ' selected' if sImpl == self._dParams[WuiMain.ksParamGraphWizImpl] else '', sDesc);
        sTop  += '    </select>\n';

        # graph size.
        sTop  += '    <label for="%s">Graph size:</label>\n' \
                 '    <input type="text" name="%s" id="%s" value="%s" class="graphwiz-pixel-input"> x\n' \
                 '    <input type="text" name="%s" id="%s" value="%s" class="graphwiz-pixel-input">\n' \
                 '    <label for="%s">Dpi:</label>'\
                 '    <input type="text" name="%s" id="%s" value="%s" class="graphwiz-dpi-input">\n' \
                 '    <button type="button" onclick="%s">Defaults</button>\n' \
               % ( WuiMain.ksParamGraphWizWidth,
                   WuiMain.ksParamGraphWizWidth,  WuiMain.ksParamGraphWizWidth,  self._dParams[WuiMain.ksParamGraphWizWidth],
                   WuiMain.ksParamGraphWizHeight, WuiMain.ksParamGraphWizHeight, self._dParams[WuiMain.ksParamGraphWizHeight],
                   WuiMain.ksParamGraphWizDpi,
                   WuiMain.ksParamGraphWizDpi,    WuiMain.ksParamGraphWizDpi,    self._dParams[WuiMain.ksParamGraphWizDpi],
                   webutils.escapeAttr('return graphwizSetDefaultSizeValues("graphwiz-nav", "%s", "%s", "%s");'
                                       % ( WuiMain.ksParamGraphWizWidth, WuiMain.ksParamGraphWizHeight,
                                           WuiMain.ksParamGraphWizDpi )),
                 );

        sTop  += '   </div>\n'; # (options row 1)

        sTop  += '  </div>\n'; # (end of row 1)

        #
        # Top: Second row.
        #
        sTop  += '  <div id="graphwiz-top-2">\n';

        # Submit
        sFormButton = '<button type="submit">Refresh</button>\n';
        sTop  += '   <div id="graphwiz-top-submit">' + sFormButton + '</div>\n';


        # Options.
        sTop  += '   <div id="graphwiz-top-options-2">\n';

        sTop  += '    <input type="checkbox" name="%s" id="%s" value="1"%s/>\n' \
                 '    <label for="%s">Tabular data</label>\n' \
               % ( WuiMain.ksParamGraphWizTabular, WuiMain.ksParamGraphWizTabular,
                   ' checked' if self._dParams[WuiMain.ksParamGraphWizTabular] else '',
                   WuiMain.ksParamGraphWizTabular);

        if hasattr(self.oGraphClass, 'setXkcdStyle'):
            sTop  += '    <input type="checkbox" name="%s" id="%s" value="1"%s/>\n' \
                     '    <label for="%s">xkcd-style</label>\n' \
                   % ( WuiMain.ksParamGraphWizXkcdStyle, WuiMain.ksParamGraphWizXkcdStyle,
                       ' checked' if self._dParams[WuiMain.ksParamGraphWizXkcdStyle] else '',
                       WuiMain.ksParamGraphWizXkcdStyle);
        elif self._dParams[WuiMain.ksParamGraphWizXkcdStyle]:
            sTop  += '    <input type="hidden" name="%s" id="%s" value="1"/>\n' \
                   % ( WuiMain.ksParamGraphWizXkcdStyle, WuiMain.ksParamGraphWizXkcdStyle, );

        if not hasattr(self.oGraphClass, 'kfNoErrorBarsSupport'):
            sTop  += '    <input type="checkbox" name="%s" id="%s" value="1"%s title="%s"/>\n' \
                     '    <label for="%s">Error bars,</label>\n' \
                     '    <label for="%s">max: </label>\n' \
                     '    <input type="text" name="%s" id="%s" value="%s" class="graphwiz-maxerrorbar-input" title="%s"/>\n' \
                   % ( WuiMain.ksParamGraphWizErrorBarY, WuiMain.ksParamGraphWizErrorBarY,
                       ' checked' if self._dParams[WuiMain.ksParamGraphWizErrorBarY] else '',
                       'Error bars shows some of the max and min results on the Y-axis.',
                       WuiMain.ksParamGraphWizErrorBarY,
                       WuiMain.ksParamGraphWizMaxErrorBarY,
                       WuiMain.ksParamGraphWizMaxErrorBarY, WuiMain.ksParamGraphWizMaxErrorBarY,
                       self._dParams[WuiMain.ksParamGraphWizMaxErrorBarY],
                       'Maximum number of Y-axis error bar per graph. (Too many makes it unreadable.)'
                       );
        else:
            if self._dParams[WuiMain.ksParamGraphWizErrorBarY]:
                sTop += '<input type="hidden" name="%s" id="%s" value="1">\n' \
                      % ( WuiMain.ksParamGraphWizErrorBarY, WuiMain.ksParamGraphWizErrorBarY, );
            sTop += '<input type="hidden" name="%s" id="%s" value="%u">\n' \
                  % ( WuiMain.ksParamGraphWizMaxErrorBarY, WuiMain.ksParamGraphWizMaxErrorBarY,
                      self._dParams[WuiMain.ksParamGraphWizMaxErrorBarY], );

        sTop  += '    <label for="%s">Font size: </label>\n' \
                 '    <input type="text" name="%s" id="%s" value="%s" class="graphwiz-fontsize-input"/>\n' \
               % ( WuiMain.ksParamGraphWizFontSize,
                   WuiMain.ksParamGraphWizFontSize, WuiMain.ksParamGraphWizFontSize,
                   self._dParams[WuiMain.ksParamGraphWizFontSize], );

        sTop  += '    <label for="%s">Data series: </label>\n' \
                 '    <input type="text" name="%s" id="%s" value="%s" class="graphwiz-maxpergraph-input" title="%s"/>\n' \
               % ( WuiMain.ksParamGraphWizMaxPerGraph,
                   WuiMain.ksParamGraphWizMaxPerGraph, WuiMain.ksParamGraphWizMaxPerGraph,
                   self._dParams[WuiMain.ksParamGraphWizMaxPerGraph],
                   'Max data series per graph.' );

        sTop  += '   </div>\n'; # (options row 2)

        sTop  += '  </div>\n'; # (end of row 2)

        sTop  += ' </div>\n'; # end of top.

        #
        # The end of the page selection.
        #
        sEnd = ' <div id="graphwiz-end-selection">\n';

        #
        # Testbox selection
        #
        aidTestBoxes = list(self._dParams[WuiMain.ksParamGraphWizTestBoxIds]);
        sEnd += '  <div id="graphwiz-testboxes" class="graphwiz-end-selection-group">\n' \
                '   <h3>TestBox Selection:</h3>\n' \
                '   <ol class="tmgraph-testboxes">\n';

        # Get a list of eligible testboxes from the DB.
        for oTestBox in self._oModel.getEligibleTestBoxes():
            try:    aidTestBoxes.remove(oTestBox.idTestBox);
            except: sChecked = '';
            else:   sChecked = ' checked';
            sEnd += '   <li><input type="checkbox" name="%s" value="%s" id="gw-tb-%u"%s/>' \
                    '<label for="gw-tb-%u">%s</label></li>\n' \
                  % ( WuiMain.ksParamGraphWizTestBoxIds, oTestBox.idTestBox, oTestBox.idTestBox, sChecked,
                      oTestBox.idTestBox, oTestBox.sName);

        # List testboxes that have been checked in a different period or something.
        for idTestBox in aidTestBoxes:
            oTestBox = self._oModel.oCache.getTestBox(idTestBox);
            sEnd += '   <li><input type="checkbox" name="%s" value="%s" id="gw-tb-%u" checked/>' \
                    '<label for="gw-tb-%u">%s</label></li>\n' \
                  % ( WuiMain.ksParamGraphWizTestBoxIds, oTestBox.idTestBox, oTestBox.idTestBox,
                      oTestBox.idTestBox, oTestBox.sName);

        sEnd += '   </ol>\n' \
                ' </div>\n';

        #
        # Build category selection.
        #
        aidBuildCategories = list(self._dParams[WuiMain.ksParamGraphWizBuildCatIds]);
        sEnd += '  <div id="graphwiz-buildcategories" class="graphwiz-end-selection-group">\n' \
                '   <h3>Build Category Selection:</h3>\n' \
                '   <ol class="tmgraph-buildcategories">\n';
        for oBuildCat in self._oModel.getEligibleBuildCategories():
            try:    aidBuildCategories.remove(oBuildCat.idBuildCategory);
            except: sChecked = '';
            else:   sChecked = ' checked';
            sEnd += '    <li><input type="checkbox" name="%s" value="%s" id="gw-bc-%u" %s/>' \
                    '<label for="gw-bc-%u">%s / %s / %s / %s</label></li>\n' \
                  % ( WuiMain.ksParamGraphWizBuildCatIds, oBuildCat.idBuildCategory, oBuildCat.idBuildCategory, sChecked,
                      oBuildCat.idBuildCategory,
                      oBuildCat.sProduct, oBuildCat.sBranch, oBuildCat.sType, ' & '.join(oBuildCat.asOsArches) );
        assert len(aidBuildCategories) == 0; # SQL should return all currently selected.

        sEnd += '   </ol>\n' \
                ' </div>\n';

        #
        # Testcase variations.
        #
        sEnd += '  <div id="graphwiz-testcase-variations" class="graphwiz-end-selection-group">\n' \
                '   <h3>Miscellaneous:</h3>\n' \
                '   <ol>';

        sEnd += '    <li>\n' \
                '     <input type="checkbox" id="%s" name="%s" value="1"%s/>\n' \
                '     <label for="%s">Separate by testcase variation.</label>\n' \
                '    </li>\n' \
              % ( WuiMain.ksParamGraphWizSepTestVars, WuiMain.ksParamGraphWizSepTestVars,
                  ' checked' if self._dParams[WuiMain.ksParamGraphWizSepTestVars] else '',
                  WuiMain.ksParamGraphWizSepTestVars );


        sEnd += '    <li>\n' \
                '     <lable for="%s">Test case ID:</label>\n' \
                '     <input type="text" id="%s" name="%s" value="%s" readonly/>\n' \
                '    </li>\n' \
              % ( WuiMain.ksParamGraphWizTestCaseIds,
                  WuiMain.ksParamGraphWizTestCaseIds, WuiMain.ksParamGraphWizTestCaseIds,
                  ','.join([str(i) for i in self._dParams[WuiMain.ksParamGraphWizTestCaseIds]]), );

        sEnd += '   </ol>\n' \
                '  </div>\n';

        #sEnd += '   <h3>&nbsp;</h3>\n';

        #
        # Finish up the form.
        #
        sEnd += '  <div id="graphwiz-end-submit"><p>' + sFormButton + '</p></div>\n';
        sEnd += ' </div>\n' \
                '</form>\n';

        return (sTop, sEnd);
Esempio n. 51
0
    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 = '&nbsp;\\<br>&nbsp;&nbsp;&nbsp;&nbsp;\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 _generatePage(self):
        """
        Generates the page using _sTemplate, _sPageTitle, _aaoMenus, and _sPageBody.
        """
        assert self._sRedirectTo is None;

        #
        # Build the replacement string dictionary.
        #

        # Provide basic auth log out for browsers that supports it.
        sUserAgent = self._oSrvGlue.getUserAgent();
        if   (sUserAgent.startswith('Mozilla/') and sUserAgent.find('Firefox') > 0) \
          or False:
            # Log in as the logout user in the same realm, the browser forgets
            # the old login and the job is done. (see apache sample conf)
            sLogOut = ' (<a href="%s://logout:logout@%s%slogout.py">logout</a>)' \
                % (self._oSrvGlue.getUrlScheme(), self._oSrvGlue.getUrlNetLoc(), self._oSrvGlue.getUrlBasePath());
        elif (sUserAgent.startswith('Mozilla/') and sUserAgent.find('Safari') > 0) \
          or False:
            # For a 401, causing the browser to forget the old login. Works
            # with safari as well as the two above. Since safari consider the
            # above method a phishing attempt and displays a warning to that
            # effect, which when taken seriously aborts the logout, this method
            # is preferable, even if it throws logon boxes in the user's face
            # till he/she/it hits escape, because it always works.
            sLogOut = ' (<a href="logout2.py">logout</a>)'
        elif (sUserAgent.startswith('Mozilla/') and sUserAgent.find('MSIE') > 0) \
          or (sUserAgent.startswith('Mozilla/') and sUserAgent.find('Chrome') > 0) \
          or False:
            ## There doesn't seem to be any way to make IE really log out
            # without using a cookie and systematically 401 accesses based on
            # some logout state associated with it.  Not sure how secure that
            # can be made and we really want to avoid cookies.  So, perhaps,
            # just avoid IE for now. :-)
            ## Chrome/21.0 doesn't want to log out either.
            sLogOut = ''
        else:
            sLogOut = ''

        # Prep Menus.
        (sTopMenuItems, sSideMenuItems) = self._generateMenus();

        # The dictionary (max variable length is 28 chars (see further down)).
        dReplacements = {
            '@@PAGE_TITLE@@':           self._sPageTitle,
            '@@LOG_OUT@@':              sLogOut,
            '@@TESTMANAGER_VERSION@@':  config.g_ksVersion,
            '@@TESTMANAGER_REVISION@@': config.g_ksRevision,
            '@@BASE_URL@@':             self._oSrvGlue.getBaseUrl(),
            '@@TOP_MENU_ITEMS@@':       sTopMenuItems,
            '@@SIDE_MENU_ITEMS@@':      sSideMenuItems,
            '@@SIDE_FILTER_CONTROL@@':  self._sPageFilter,
            '@@SIDE_MENU_FORM_ATTRS@@': '',
            '@@PAGE_BODY@@':            self._sPageBody,
            '@@DEBUG@@':                '',
        };

        # Side menu form attributes.
        if self._dSideMenuFormAttrs:
            dReplacements['@@SIDE_MENU_FORM_ATTRS@@'] = ' '.join(['%s="%s"' % (sKey, webutils.escapeAttr(sValue))
                                                                  for sKey, sValue in self._dSideMenuFormAttrs.items()]);

        # Special current user handling.
        if self._oCurUser is not None:
            dReplacements['@@USER_NAME@@'] = self._oCurUser.sUsername;
        else:
            dReplacements['@@USER_NAME@@'] = 'unauthorized user "' + self._oSrvGlue.getLoginName() + '"';

        # Prep debug section.
        if self._sDebug == '':
            if config.g_kfWebUiSqlTrace or self._fDbgSqlTrace or self._fDbgSqlExplain:
                self._sDebug  = '<h3>Processed in %s ns.</h3>\n%s\n' \
                              % ( utils.formatNumber(utils.timestampNano() - self._oSrvGlue.tsStart,),
                                  self._oDb.debugHtmlReport(self._oSrvGlue.tsStart));
            elif config.g_kfWebUiProcessedIn:
                self._sDebug  = '<h3>Processed in %s ns.</h3>\n' \
                              % ( utils.formatNumber(utils.timestampNano() - self._oSrvGlue.tsStart,), );
            if config.g_kfWebUiDebugPanel:
                self._sDebug += self._debugRenderPanel();
        if self._sDebug != '':
            dReplacements['@@DEBUG@@'] = u'<div id="debug"><br><br><hr/>' \
                                       + (unicode(self._sDebug, errors='ignore') if isinstance(self._sDebug, str)
                                          else self._sDebug) \
                                       + u'</div>\n';

        #
        # Load the template.
        #
        oFile = open(os.path.join(self._oSrvGlue.pathTmWebUI(), self._sTemplate));
        sTmpl = oFile.read();
        oFile.close();

        #
        # Process the template, outputting each part we process.
        #
        offStart = 0;
        offCur   = 0;
        while offCur < len(sTmpl):
            # Look for a replacement variable.
            offAtAt = sTmpl.find('@@', offCur);
            if offAtAt < 0:
                break;
            offCur = offAtAt + 2;
            if sTmpl[offCur] not in string.ascii_uppercase:
                continue;
            offEnd = sTmpl.find('@@', offCur, offCur+28);
            if offEnd <= 0:
                continue;
            offCur = offEnd;
            sReplacement = sTmpl[offAtAt:offEnd+2];
            if sReplacement in dReplacements:
                # Got a match! Write out the previous chunk followed by the replacement text.
                if offStart < offAtAt:
                    self._oSrvGlue.write(sTmpl[offStart:offAtAt]);
                self._oSrvGlue.write(dReplacements[sReplacement]);
                # Advance past the replacement point in the template.
                offCur += 2;
                offStart = offCur;
            else:
                assert False, 'Unknown replacement "%s" at offset %s in %s' % (sReplacement, offAtAt, self._sTemplate );

        # The final chunk.
        if offStart < len(sTmpl):
            self._oSrvGlue.write(sTmpl[offStart:]);

        return True;
Esempio n. 53
0
    def _generatePage(self):
        """
        Generates the page using _sTemplate, _sPageTitle, _aaoMenus, and _sPageBody.
        """
        assert self._sRedirectTo is None;

        #
        # Build the replacement string dictionary.
        #

        # Provide basic auth log out for browsers that supports it.
        sUserAgent = self._oSrvGlue.getUserAgent();
        if   (sUserAgent.startswith('Mozilla/') and sUserAgent.find('Firefox') > 0) \
          or False:
            # Log in as the logout user in the same realm, the browser forgets
            # the old login and the job is done. (see apache sample conf)
            sLogOut = ' (<a href="%s://logout:logout@%s%slogout.py">logout</a>)' \
                % (self._oSrvGlue.getUrlScheme(), self._oSrvGlue.getUrlNetLoc(), self._oSrvGlue.getUrlBasePath());
        elif (sUserAgent.startswith('Mozilla/') and sUserAgent.find('Safari') > 0) \
          or False:
            # For a 401, causing the browser to forget the old login. Works
            # with safari as well as the two above. Since safari consider the
            # above method a phishing attempt and displays a warning to that
            # effect, which when taken seriously aborts the logout, this method
            # is preferable, even if it throws logon boxes in the user's face
            # till he/she/it hits escape, because it always works.
            sLogOut = ' (<a href="logout2.py">logout</a>)'
        elif (sUserAgent.startswith('Mozilla/') and sUserAgent.find('MSIE') > 0) \
          or (sUserAgent.startswith('Mozilla/') and sUserAgent.find('Chrome') > 0) \
          or False:
            ## There doesn't seem to be any way to make IE really log out
            # without using a cookie and systematically 401 accesses based on
            # some logout state associated with it.  Not sure how secure that
            # can be made and we really want to avoid cookies.  So, perhaps,
            # just avoid IE for now. :-)
            ## Chrome/21.0 doesn't want to log out either.
            sLogOut = ''
        else:
            sLogOut = ''

        # Prep Menus.
        (sTopMenuItems, sSideMenuItems) = self._generateMenus();

        # The dictionary (max variable length is 28 chars (see further down)).
        dReplacements = {
            '@@PAGE_TITLE@@':           self._sPageTitle,
            '@@LOG_OUT@@':              sLogOut,
            '@@TESTMANAGER_VERSION@@':  config.g_ksVersion,
            '@@TESTMANAGER_REVISION@@': config.g_ksRevision,
            '@@BASE_URL@@':             self._oSrvGlue.getBaseUrl(),
            '@@TOP_MENU_ITEMS@@':       sTopMenuItems,
            '@@SIDE_MENU_ITEMS@@':      sSideMenuItems,
            '@@SIDE_FILTER_CONTROL@@':  self._sPageFilter,
            '@@SIDE_MENU_FORM_ATTRS@@': '',
            '@@PAGE_BODY@@':            self._sPageBody,
            '@@DEBUG@@':                '',
        };

        # Side menu form attributes.
        if self._dSideMenuFormAttrs:
            dReplacements['@@SIDE_MENU_FORM_ATTRS@@'] = ' '.join(['%s="%s"' % (sKey, webutils.escapeAttr(sValue))
                                                                  for sKey, sValue in self._dSideMenuFormAttrs.items()]);

        # Special current user handling.
        if self._oCurUser is not None:
            dReplacements['@@USER_NAME@@'] = self._oCurUser.sUsername;
        else:
            dReplacements['@@USER_NAME@@'] = 'unauthorized user "' + self._oSrvGlue.getLoginName() + '"';

        # Prep debug section.
        if self._sDebug == '':
            if config.g_kfWebUiSqlTrace or self._fDbgSqlTrace or self._fDbgSqlExplain:
                self._sDebug  = '<h3>Processed in %s ns.</h3>\n%s\n' \
                              % ( utils.formatNumber(utils.timestampNano() - self._oSrvGlue.tsStart,),
                                  self._oDb.debugHtmlReport(self._oSrvGlue.tsStart));
            elif config.g_kfWebUiProcessedIn:
                self._sDebug  = '<h3>Processed in %s ns.</h3>\n' \
                              % ( utils.formatNumber(utils.timestampNano() - self._oSrvGlue.tsStart,), );
            if config.g_kfWebUiDebugPanel:
                self._sDebug += self._debugRenderPanel();
        if self._sDebug != '':
            dReplacements['@@DEBUG@@'] = u'<div id="debug"><br><br><hr/>' \
                                       + (utils.toUnicode(self._sDebug, errors='ignore') if isinstance(self._sDebug, str)
                                          else self._sDebug) \
                                       + u'</div>\n';

        #
        # Load the template.
        #
        oFile = open(os.path.join(self._oSrvGlue.pathTmWebUI(), self._sTemplate));
        sTmpl = oFile.read();
        oFile.close();

        #
        # Process the template, outputting each part we process.
        #
        offStart = 0;
        offCur   = 0;
        while offCur < len(sTmpl):
            # Look for a replacement variable.
            offAtAt = sTmpl.find('@@', offCur);
            if offAtAt < 0:
                break;
            offCur = offAtAt + 2;
            if sTmpl[offCur] not in string.ascii_uppercase:
                continue;
            offEnd = sTmpl.find('@@', offCur, offCur+28);
            if offEnd <= 0:
                continue;
            offCur = offEnd;
            sReplacement = sTmpl[offAtAt:offEnd+2];
            if sReplacement in dReplacements:
                # Got a match! Write out the previous chunk followed by the replacement text.
                if offStart < offAtAt:
                    self._oSrvGlue.write(sTmpl[offStart:offAtAt]);
                self._oSrvGlue.write(dReplacements[sReplacement]);
                # Advance past the replacement point in the template.
                offCur += 2;
                offStart = offCur;
            else:
                assert False, 'Unknown replacement "%s" at offset %s in %s' % (sReplacement, offAtAt, self._sTemplate );

        # The final chunk.
        if offStart < len(sTmpl):
            self._oSrvGlue.write(sTmpl[offStart:]);

        return True;
Esempio n. 54
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)
 def __init__(self, sSpanClass, sText):
     WuiRawHtml.__init__(
         self, u'<span class="%s">%s</span>' % (webutils.escapeAttr(sSpanClass), webutils.escapeElem(sText))
     )
Esempio n. 56
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)