# -*- coding: utf-8 -*-
# $Id$
"""
Test Manager Web-UI - Form Helpers.
"""
__copyright__ = \
"""
Copyright (C) 2012-2014 Oracle Corporation
This file is part of VirtualBox Open Source Edition (OSE), as
available from http://www.virtualbox.org. This file is free software;
General Public License (GPL) as published by the Free Software
Foundation, in version 2 as it comes in the "COPYING" file of the
VirtualBox OSE distribution. VirtualBox OSE is distributed in the
hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
The contents of this file may alternatively be used under the terms
of the Common Development and Distribution License Version 1.0
(CDDL) only, as it comes in the "COPYING.CDDL" file of the
VirtualBox OSE distribution, in which case the provisions of the
CDDL are applicable instead of those of the GPL.
You may elect to license modified versions of this file under the
terms and conditions of either the GPL or the CDDL or both.
"""
# Standard python imports.
import copy;
# Validation Kit imports.
"""
Helper for constructing a form.
"""
u'<div id="%s" class="tmform">\n' \
u' <form action="%s" method="post">\n' \
u' <ul>\n' \
"""Internal worker for appending text to the body."""
assert not self._fFinalized;
if not self._fFinalized:
return True;
return False;
"""Escapes error text, preserving some predefined HTML tags."""
else:
return sText;
"""Internal worker for adding a label."""
' <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'
' <div class="tmform-field"><div class="tmform-field-%s">\n'
' <label for="%s">%s</label>\n'
"""
Finalizes the form and returns the body.
"""
if not self._fFinalized:
' </form>\n'
'</div>\n'
'<div class="clear"></div>\n'
);
"""Adds a hidden text input."""
' <input name="%s" id="%s" type="text" hidden%s value="%s" class="tmform-hidden">\n'
' </div>\n'
' </li>\n'
#
# Text input fields.
#
"""Adds a text input."""
if self._fReadOnly:
if sSubClass not in ('int', 'long', 'string', 'uuid', 'timestamp', 'wide'): raise Exception(sSubClass);
' </div></div>\n'
' </li>\n'
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);
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'
"""Adds a wide text input."""
"""Adds a wide read-only text input."""
"""Adds a multiline text input."""
if self._fReadOnly:
' </div></div>\n'
' </li>\n'
"""Adds a multiline read-only text input."""
' </div></div>\n'
' </li>\n'
"""Adds an integer input."""
"""Adds an integer input."""
"""Adds a long input."""
"""Adds a long input."""
"""Adds an UUID input."""
"""Adds a read-only UUID input."""
"""Adds a read-only database string timstamp input."""
#
# Text areas.
#
#
# Combo boxes.
#
"""Adds a combo box."""
if self._fReadOnly:
escapeElem(sText)));
' </div></div>\n'
' </li>\n'
);
"""Adds a read-only combo box."""
escapeElem(sText)));
' </div></div>\n'
' </li>\n'
);
#
# Check boxes.
#
"""Reinterprets a value as a boolean type."""
if fValue is None:
else:
return fValue;
"""Adds an check box."""
if self._fReadOnly:
return self._add(' <input name="%s" id="%s" type="checkbox"%s%s value="1" class="tmform-checkbox">\n'
' </div></div>\n'
' </li>\n'
"""Adds an readonly check box."""
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'
#
# List of items to check
#
"""
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
"""
if fReadOnly:
sExtraAttribs += ' readonly onclick="return false" onkeydown="return false"';
if fUseTable:
' <td><input type="checkbox" name="%s" value="%s"%s%s></td>\n'
' <td>%s</td>\n'
' </tr>\n'
else:
'<input type="checkbox" name="%s" value="%s"%s%s> %s</input></div>\n'
' </li>\n');
"""
asOsArches is a list of [sValue, fChecked, sName] sub-arrays.
"""
return self._addList(sName, aoOsArches, sLabel, fUseTable = False, sId = 'tmform-checkbox-list-os-arches',
"""
List of checkboxes for build type selection.
aoTypes is a list of [sValue, fChecked, sName] sub-arrays.
"""
return self._addList(sName, aoTypes, sLabel, fUseTable = False, sId = 'tmform-checkbox-list-build-types',
"""
List of checkboxes for test box (dependency) selection.
aoTestCases is a list of [sValue, fChecked, sName] sub-arrays.
"""
return self._addList(sName, aoTestCases, sLabel, fUseTable = False, sId = 'tmform-checkbox-list-testcases',
"""
List of checkboxes for resource selection.
aoTestCases is a list of [sValue, fChecked, sName] sub-arrays.
"""
return self._addList(sName, aoTestCases, sLabel, fUseTable = False, sId = 'tmform-checkbox-list-resources',
"""
List of checkboxes for test group selection.
aoTestGroups is a list of [sValue, fChecked, sName] sub-arrays.
"""
return self._addList(sName, aoTestGroups, sLabel, fUseTable = False, sId = 'tmform-checkbox-list-testgroups',
"""
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
"""
sTableId = 'TestArgsExtendingListRoot';
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 += '\n';
sHtml += '{\n';
sHtml += ' {\n';
sHtml += '\n';
sHtml += ' }\n';
sHtml += '}\n';
sHtml += '\n';
sHtml += 'function %s_extendListEx(cGangMembers, cSecTimeout, sArgs, sTestBoxReqExpr, sBuildReqExpr)\n' % (sName,);
sHtml += '{\n';
sHtml += ' var oTBody = document.createElement(\'tbody\');\n';
sHtml += ' var sHtml = \'\';\n';
sHtml += ' var sId;\n';
sHtml += '\n';
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' \
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' \
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' \
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' \
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' \
sHtml += ' sHtml += \' <td></td>\';\n';
sHtml += ' sHtml += \'</tr>\';\n'
sHtml += '\n';
sHtml += ' oTBody.innerHTML = sHtml;\n';
sHtml += '\n';
sHtml += ' oElement.appendChild(oTBody);\n';
sHtml += '\n';
sHtml += '}\n';
sHtml += '{\n';
sHtml += '}\n';
sHtml += '{\n';
sHtml += ' %s_extendListEx("1", "%s", "--cpu-counts 1 --virt-modes raw", ' \
sHtml += ' %s_extendListEx("1", "%s", "--cpu-counts 1 --virt-modes hwvirt", ' \
sHtml += ' %s_extendListEx("1", "%s", "--cpu-counts 1 --virt-modes hwvirt-np", ' \
sHtml += '}\n';
sHtml += '{\n';
sHtml += ' %s_extendListEx("1", "%s", "--cpu-counts 1 --virt-modes hwvirt", ' \
sHtml += ' %s_extendListEx("1", "%s", "--cpu-counts 1 --virt-modes hwvirt-np", ' \
sHtml += '}\n';
sHtml += '{\n';
sHtml += ' %s_extendListEx("1", "%s", "--cpu-counts 2 --virt-modes hwvirt",' \
sHtml += ' %s_extendListEx("1", "%s", "--cpu-counts 2 --virt-modes hwvirt-np",' \
sHtml += ' %s_extendListEx("1", "%s", "--cpu-counts 3 --virt-modes hwvirt",' \
sHtml += ' %s_extendListEx("1", "%s", "--cpu-counts 4 --virt-modes hwvirt-np ",' \
#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' \
if not fReadOnly:
sHtml += ' <caption>\n' \
' <a href="#" onClick="%s_extendList()">Add</a>\n' % (sName,);
sHtml += ' </caption>\n';
dSubErrors = {};
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,
if not fReadOnly:
sHtml += ' <td><a href="#" onclick="%s_removeEntry(\'%s\');">Remove</a></td>\n' \
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' \
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' \
if iVar in dSubErrors:
sHtml += ' <tr><td colspan="4"><p align="left" class="tmform-error-desc">%s</p></td></tr>\n' \
sHtml += '</tbody>\n';
sHtml += ' </table>\n'
sHtml += '</li>\n'
def addListOfTestGroupMembers(self, sName, aoTestGroupMembers, aoAllTestCases, sLabel, # pylint: disable=R0914
"""
For WuiTestGroup.
"""
' <thead>\n'
' <tr>\n'
' <th rowspan="2"></th>\n'
' <th rowspan="2">Test Case</th>\n'
' <th rowspan="2">All Vars</th>\n'
' <th rowspan="2">Priority [0..31]</th>\n'
' <th colspan="4" align="center">Variations</th>\n'
' </tr>\n'
' <tr>\n'
' <th>Included</th>\n'
' <th>Gang size</th>\n'
' <th>Timeout</th>\n'
' <th>Arguments</th>\n'
' </tr>\n'
' </thead>\n'
' <tbody>\n'
);
if self._fReadOnly:
# Is it a member?
oMember = None;
break;
# Start on the rows...
' <td rowspan="%d">\n'
' <input name="%s[%s]" type="hidden" value="%s">\n' # idTestCase
' <input name="%s[%s]" type="hidden" value="%s">\n' # idTestGroup
' <input name="%s[%s]" type="hidden" value="%s">\n' # tsExpire
' <input name="%s[%s]" type="hidden" value="%s">\n' # tsEffective
' <input name="%s[%s]" type="hidden" value="%s">\n' # uidAuthor
' <input name="%s" type="checkbox"%s%s value="%d" class="tmform-checkbox" title="#%d - %s">\n' # (list)
' </td>\n'
));
' <input name="%s[%s]" type="checkbox"%s%s value="-1">\n'
' </td>\n'
' <input name="%s[%s]" type="text" value="%s" style="max-width:3em;" %s>\n'
' </td>\n'
# Argument variations.
aidTestCaseArgs = [] if oMember is None or oMember.aidTestCaseArgs is None else oMember.aidTestCaseArgs;
if iVar > 0:
' <input name="%s[%s]" type="checkbox"%s%s value="%d">'
' </td>\n'
));
' <td align="center">%s</td>\n'
' <td align="left">%s</td>\n'
% ( oVar.cGangMembers,
' </tr>\n');
'</table>\n');
def addListOfSchedGroupMembers(self, sName, aoSchedGroupMembers, aoAllTestGroups, # pylint: disable=R0914
"""
For WuiAdminSchedGroup.
"""
if self._fReadOnly:
' <thead>\n'
' <tr>\n'
' <th></th>\n'
' <th>Test Group</th>\n'
' <th>Priority [0..31]</th>\n'
' <th>Prerequisite Test Group</th>\n'
' <th>Weekly schedule</th>\n'
' </tr>\n'
' </thead>\n'
' <tbody>\n'
);
# Is it a member?
oMember = None;
break;
# Start on the rows...
' <td>\n'
' <input name="%s[%s]" type="hidden" value="%s">\n' # idTestGroup
' <input name="%s[%s]" type="hidden" value="%s">\n' # idSchedGroup
' <input name="%s[%s]" type="hidden" value="%s">\n' # tsExpire
' <input name="%s[%s]" type="hidden" value="%s">\n' # tsEffective
' <input name="%s[%s]" type="hidden" value="%s">\n' # uidAuthor
' <input name="%s" type="checkbox"%s%s value="%d" class="tmform-checkbox" title="#%d - %s">\n' # (list)
' </td>\n'
sPrefix, SchedGroupMemberData.ksParam_idSchedGroup, -1 if oMember is None else oMember.idSchedGroup,
));
' <input name="%s[%s]" type="text" value="%s" style="max-width:3em;" %s>\n'
' </td>\n'
' <select name="%s[%s]" id="%s[%s]" class="tmform-combobox"%s>\n'
' <option value="-1"%s>None</option>\n'
));
for oTestGroup2 in aoAllTestGroups:
if oTestGroup2 != oTestGroup:
' </td>\n');
' Todo<input name="%s[%s]" type="hidden" value="%s">\n'
' </td>\n'
'</table>\n');
#
# Buttons.
#
"""Adds the submit button to the form."""
if self._fReadOnly:
return True;
' <br>\n'
' <div class="tmform-field"><div class="tmform-field-submit">\n'
' <label> </label>\n'
' <input type="submit" value="%s">\n'
' </div></div>\n'
' </li>\n'
% (escapeElem(sLabel),));
"""Adds a reset button to the form."""
if self._fReadOnly:
return True;
' <div class="tmform-button"><div class="tmform-button-reset">\n'
' <input type="reset" value="%s">\n'
' </div></div>\n'
' </li>\n'
);