cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# -*- coding: utf-8 -*-
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncTest Manager Core - Web Server Abstraction Base Class.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncCopyright (C) 2012-2014 Oracle Corporation
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncThis file is part of VirtualBox Open Source Edition (OSE), as
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncavailable from http://www.virtualbox.org. This file is free software;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncyou can redistribute it and/or modify it under the terms of the GNU
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncGeneral Public License (GPL) as published by the Free Software
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncFoundation, in version 2 as it comes in the "COPYING" file of the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncVirtualBox OSE distribution. VirtualBox OSE is distributed in the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsynchope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncThe contents of this file may alternatively be used under the terms
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncof the Common Development and Distribution License Version 1.0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync(CDDL) only, as it comes in the "COPYING.CDDL" file of the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncVirtualBox OSE distribution, in which case the provisions of the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncCDDL are applicable instead of those of the GPL.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncYou may elect to license modified versions of this file under the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncterms and conditions of either the GPL or the CDDL or both.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# Standard python imports.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# Validation Kit imports.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom testmanager.core.db import TMDatabaseConnection;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom testmanager.core.globalresource import GlobalResourceLogic;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom testmanager.core.testboxstatus import TestBoxStatusData, TestBoxStatusLogic;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom testmanager.core.testbox import TestBoxData, TestBoxLogic;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom testmanager.core.testresults import TestResultLogic;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom testmanager.core.testset import TestSetData, TestSetLogic;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom testmanager.core.systemlog import SystemLogData, SystemLogLogic;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom testmanager.core.schedulerbase import SchedulerBase;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# Python 3 hacks:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Exception class for TestBoxController.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncclass TestBoxController(object): # pylint: disable=R0903
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync TestBox Controller class.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## Applicable testbox commands to an idle TestBox.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## Applicable testbox commands to a busy TestBox.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync kasBusyCmds = [TestBoxData.ksTestBoxCmd_Abort, TestBoxData.ksTestBoxCmd_Reboot];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## Commands that can be ACK'ed.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync kasAckableCmds = [constants.tbresp.CMD_EXEC, constants.tbresp.CMD_ABORT, constants.tbresp.CMD_REBOOT,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync constants.tbresp.CMD_UPGRADE, constants.tbresp.CMD_UPGRADE_AND_REBOOT, constants.tbresp.CMD_SPECIAL];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## Commands that can be NACK'ed or NOTSUP'ed.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync kasNackableCmds = kasAckableCmds + [kasAckableCmds, constants.tbresp.CMD_IDLE, constants.tbresp.CMD_WAIT];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## Mapping from TestBoxCmd_T to TestBoxState_T
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync TestBoxData.ksTestBoxCmd_Reboot: TestBoxStatusData.ksTestBoxState_Rebooting,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync TestBoxData.ksTestBoxCmd_Upgrade: TestBoxStatusData.ksTestBoxState_Upgrading,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync TestBoxData.ksTestBoxCmd_UpgradeAndReboot: TestBoxStatusData.ksTestBoxState_UpgradingAndRebooting,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync TestBoxData.ksTestBoxCmd_Special: TestBoxStatusData.ksTestBoxState_DoingSpecialCmd,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## Mapping from TestBoxCmd_T to TestBox responses commands.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync TestBoxData.ksTestBoxCmd_Abort: constants.tbresp.CMD_ABORT,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync TestBoxData.ksTestBoxCmd_Reboot: constants.tbresp.CMD_REBOOT,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync TestBoxData.ksTestBoxCmd_Upgrade: constants.tbresp.CMD_UPGRADE,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync TestBoxData.ksTestBoxCmd_UpgradeAndReboot: constants.tbresp.CMD_UPGRADE_AND_REBOOT,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync TestBoxData.ksTestBoxCmd_Special: constants.tbresp.CMD_SPECIAL,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## Mapping from TestBox responses to TestBoxCmd_T commands.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync constants.tbresp.CMD_ABORT: TestBoxData.ksTestBoxCmd_Abort,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync constants.tbresp.CMD_REBOOT: TestBoxData.ksTestBoxCmd_Reboot,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync constants.tbresp.CMD_UPGRADE: TestBoxData.ksTestBoxCmd_Upgrade,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync constants.tbresp.CMD_UPGRADE_AND_REBOOT: TestBoxData.ksTestBoxCmd_UpgradeAndReboot,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync constants.tbresp.CMD_SPECIAL: TestBoxData.ksTestBoxCmd_Special,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## The path to the upgrade zip, relative WebServerGlueBase.getBaseUrl().
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksUpgradeZip = 'htdocs/upgrade/VBoxTestBoxScript.zip';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## Valid TestBox result values.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync kasValidResults = list(constants.result.g_kasValidResults);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## Mapping TestBox result values to TestStatus_T values.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync constants.result.PASSED: TestSetData.ksTestStatus_Success,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync constants.result.SKIPPED: TestSetData.ksTestStatus_Skipped,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync constants.result.ABORTED: TestSetData.ksTestStatus_Aborted,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync constants.result.BAD_TESTBOX: TestSetData.ksTestStatus_BadTestBox,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync constants.result.FAILED: TestSetData.ksTestStatus_Failure,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync constants.result.TIMED_OUT: TestSetData.ksTestStatus_TimedOut,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync constants.result.REBOOTED: TestSetData.ksTestStatus_Rebooted,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Won't raise exceptions.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._sAction = None; # _getStandardParams / dispatchRequest sets this later on.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._idTestBox = None; # _getStandardParams / dispatchRequest sets this later on.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._sTestBoxUuid = None; # _getStandardParams / dispatchRequest sets this later on.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._sTestBoxAddr = None; # _getStandardParams / dispatchRequest sets this later on.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._idTestSet = None; # _getStandardParams / dispatchRequest sets this later on.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._dParams = None; # _getStandardParams / dispatchRequest sets this later on.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync constants.tbreq.REQUEST_COMMAND_BUSY: self._actionRequestCommandBusy,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync constants.tbreq.REQUEST_COMMAND_IDLE: self._actionRequestCommandIdle,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync constants.tbreq.COMMAND_ACK : self._actionCommandAck,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync constants.tbreq.COMMAND_NACK : self._actionCommandNack,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync constants.tbreq.COMMAND_NOTSUP : self._actionCommandNotSup,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync constants.tbreq.XML_RESULTS : self._actionXmlResults,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync constants.tbreq.EXEC_COMPLETED : self._actionExecCompleted,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _getStringParam(self, sName, asValidValues = None, fStrip = False, sDefValue = None):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Gets a string parameter (stripped).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Raises exception if not found and no default is provided, or if the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync value isn't found in asValidValues.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestBoxControllerException('%s parameter %s is missing' % (self._sAction, sName));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if asValidValues is not None and sValue not in asValidValues:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestBoxControllerException('%s parameter %s value "%s" not in %s ' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Gets a boolean parameter.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Raises exception if not found and no default is provided, or if not a
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync valid boolean.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sValue = self._getStringParam(sName, [ 'True', 'true', '1', 'False', 'false', '0'], sDefValue = str(fDefValue));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return sValue == 'True' or sValue == 'true' or sValue == '1';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _getIntParam(self, sName, iMin = None, iMax = None):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Gets a string parameter.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Raises exception if not found, not a valid integer, or if the value
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync isn't in the range defined by iMin and iMax.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestBoxControllerException('%s parameter %s value "%s" cannot be convert to an integer' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestBoxControllerException('%s parameter %s value %d is out of range [%s..%s]' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _getLongParam(self, sName, lMin = None, lMax = None, lDefValue = None):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Gets a string parameter.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Raises exception if not found, not a valid long integer, or if the value
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync isn't in the range defined by lMin and lMax.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sValue = self._getStringParam(sName, sDefValue = (str(lDefValue) if lDefValue is not None else None));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestBoxControllerException('%s parameter %s value "%s" cannot be convert to an integer (%s)' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestBoxControllerException('%s parameter %s value %d is out of range [%s..%s]' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Check if we've handled all parameters, raises exception if anything
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync unknown was found.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if len(self._asCheckedParams) != len(self._dParams):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sUnknownParams += ' ' + sKey + '=' + self._dParams[sKey];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestBoxControllerException('Unknown parameters: ' + sUnknownParams);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Makes a reply to the testbox script.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Will raise exception on failure.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Makes a simple reply to the testbox script.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Will raise exception on failure.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self._writeResponse({constants.tbresp.ALL_PARAM_RESULT: sResultValue});
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Makes an IDLE reply to the testbox script.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Will raise exception on failure.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self._writeResponse({ constants.tbresp.ALL_PARAM_RESULT: constants.tbresp.CMD_IDLE });
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Cleans up any old test set that may be left behind and changes the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync state to 'idle'. See scenario #9:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync file://../../docs/AutomaticTestingRevamp.html#cleaning-up-abandond-testcase
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Note. oStatusData.enmState is set to idle, but tsUpdated is not changed.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Cleanup any abandond test.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync SystemLogLogic(oDb).addEntry(SystemLogData.ksEvent_TestSetAbandond,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync "idTestSet=%u idTestBox=%u enmState=%s %s"
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync TestSetLogic(oDb).completeAsAbandond(oStatusData.idTestSet, fCommit = False);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync GlobalResourceLogic(oDb).freeGlobalResourcesByTestBox(self._idTestBox, fCommit = False);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Change to idle status
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oStatusData.enmState != TestBoxStatusData.ksTestBoxState_Idle:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync TestBoxStatusLogic(oDb).updateState(self._idTestBox, TestBoxStatusData.ksTestBoxState_Idle, fCommit = False);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oStatusData.enmState = TestBoxStatusData.ksTestBoxState_Idle;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _connectToDbAndValidateTb(self, asValidStates = None):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Connects to the database and validates the testbox.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns (TMDatabaseConnection, TestBoxStatusData, TestBoxData) on success.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns (None, None, None) on failure after sending the box an appropriate response.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync May raise exception on DB error.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync (oStatusData, oTestBoxData) = oLogic.tryFetchStatusAndConfig(self._idTestBox, self._sTestBoxUuid, self._sTestBoxAddr);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._resultResponse(constants.tbresp.STATUS_DEAD);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync elif asValidStates is not None and oStatusData.enmState not in asValidStates:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._resultResponse(constants.tbresp.STATUS_NACK);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync elif self._idTestSet is not None and self._idTestSet != oStatusData.idTestSet:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._resultResponse(constants.tbresp.STATUS_NACK);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return (None, None, None);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def writeToMainLog(self, oTestSet, sText, fIgnoreSizeCheck = False):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ Writes the text to the main log file. """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Calc the file name and open the file.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sFile = os.path.join(config.g_ksFileAreaRootDir, oTestSet.sBaseFilename + '-main.log');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Check the size.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fSizeOk = oStat.st_size / (1024 * 1024) < config.g_kcMbMaxMainLog;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Write the text.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ Implement sign-on """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Validate parameters (raises exception on failure).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sOs = self._getStringParam(constants.tbreq.SIGNON_PARAM_OS, coreconsts.g_kasOses);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sOsVersion = self._getStringParam(constants.tbreq.SIGNON_PARAM_OS_VERSION);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sCpuVendor = self._getStringParam(constants.tbreq.SIGNON_PARAM_CPU_VENDOR);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sCpuArch = self._getStringParam(constants.tbreq.SIGNON_PARAM_CPU_ARCH, coreconsts.g_kasCpuArches);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sCpuName = self._getStringParam(constants.tbreq.SIGNON_PARAM_CPU_NAME, fStrip = True, sDefValue = ''); # new
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync lCpuRevision = self._getLongParam( constants.tbreq.SIGNON_PARAM_CPU_REVISION, lMin = 0, lDefValue = 0); # new
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cCpus = self._getIntParam( constants.tbreq.SIGNON_PARAM_CPU_COUNT, 1, 16384);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fCpuHwVirt = self._getBoolParam( constants.tbreq.SIGNON_PARAM_HAS_HW_VIRT);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fCpuNestedPaging = self._getBoolParam( constants.tbreq.SIGNON_PARAM_HAS_NESTED_PAGING);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fCpu64BitGuest = self._getBoolParam( constants.tbreq.SIGNON_PARAM_HAS_64_BIT_GUEST, fDefValue = True);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fChipsetIoMmu = self._getBoolParam( constants.tbreq.SIGNON_PARAM_HAS_IOMMU);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cMbMemory = self._getLongParam( constants.tbreq.SIGNON_PARAM_MEM_SIZE, 8, 1073741823); # 8MB..1PB
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cMbScratch = self._getLongParam( constants.tbreq.SIGNON_PARAM_SCRATCH_SIZE, 0, 1073741823); # 0..1PB
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sReport = self._getStringParam(constants.tbreq.SIGNON_PARAM_REPORT, fStrip = True, sDefValue = ''); # new
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync iTestBoxScriptRev = self._getIntParam( constants.tbreq.SIGNON_PARAM_SCRIPT_REV, 1, 100000000);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync iPythonHexVersion = self._getIntParam( constants.tbreq.SIGNON_PARAM_PYTHON_VERSION, 0x020300f0, 0x030f00f0);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Null conversions for new parameters.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Connect to the database and validate the testbox.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestBox = oTestBoxLogic.tryFetchTestBoxByUuid(self._sTestBoxUuid);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oSystemLogLogic.addEntry(SystemLogData.ksEvent_TestBoxUnknown,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'addr=%s uuid=%s os=%s %d cpus' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % (self._sTestBoxAddr, self._sTestBoxUuid, sOs, cCpus),
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self._resultResponse(constants.tbresp.STATUS_NACK);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Update the row in TestBoxes if something changed.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync or iTestBoxScriptRev != oTestBox.iTestBoxScriptRev \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync or iPythonHexVersion != oTestBox.iPythonHexVersion:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Update the testbox status, making sure there is a status.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oStatusData = oStatusLogic.tryFetchStatus(oTestBox.idTestBox);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oStatusData is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oStatusLogic.insertIdleStatus(oTestBox.idTestBox, oTestBox.idGenTestBox, fCommit = True);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # ACK the request.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync constants.tbresp.ALL_PARAM_RESULT: constants.tbresp.STATUS_ACK,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync constants.tbresp.SIGNON_PARAM_ID: oTestBox.idTestBox,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync constants.tbresp.SIGNON_PARAM_NAME: oTestBox.sName,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync _doRequestCommand worker for handling a box in gang-cleanup.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync This will check if all testboxes has completed their run, pretending to
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync be busy until that happens. Once all are completed, resources will be
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync freed and the testbox returns to idle state (we update oStatusData).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestSet = TestSetData().initFromDbWithId(oDb, oStatusData.idTestSet);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oStatusLogic.isWholeGangDoneTesting(oTestSet.idTestSetGangLeader):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync GlobalResourceLogic(oDb).freeGlobalResourcesByTestBox(self._idTestBox, fCommit = False);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync TestBoxStatusLogic(oDb).updateState(self._idTestBox, TestBoxStatusData.ksTestBoxState_Idle, fCommit = False);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oStatusData.enmState = TestBoxStatusData.ksTestBoxState_Idle;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _doGangGatheringTimedOut(self, oDb, oStatusData):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync _doRequestCommand worker for handling a box in gang-gathering-timed-out state.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync This will do clean-ups similar to _cleanupOldTest and update the state likewise.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync TestSetLogic(oDb).completeAsGangGatheringTimeout(oStatusData.idTestSet, fCommit = False);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync GlobalResourceLogic(oDb).freeGlobalResourcesByTestBox(self._idTestBox, fCommit = False);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync TestBoxStatusLogic(oDb).updateState(self._idTestBox, TestBoxStatusData.ksTestBoxState_Idle, fCommit = False);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oStatusData.enmState = TestBoxStatusData.ksTestBoxState_Idle;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync _doRequestCommand worker for handling a box in gang-gathering state.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync This only checks for timeout. It will update the oStatusData if a
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync timeout is detected, so that the box will be idle upon return.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oStatusLogic.timeSinceLastChangeInSecs(oStatusData) > config.g_kcSecGangGathering \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and SchedulerBase.tryCancelGangGathering(oDb, oStatusData): # <-- Updates oStatusData.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Common code for handling command request.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync (oDb, oStatusData, oTestBoxData) = self._connectToDbAndValidateTb();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oDb is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Status clean up.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Only when BUSY will the TestBox Script request and execute commands
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # concurrently. So, it must be idle when sending REQUEST_COMMAND_IDLE.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oStatusData.enmState == TestBoxStatusData.ksTestBoxState_GangGathering:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync elif oStatusData.enmState == TestBoxStatusData.ksTestBoxState_GangGatheringTimedOut:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync elif oStatusData.enmState == TestBoxStatusData.ksTestBoxState_GangTesting:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dResponse = SchedulerBase.composeExecResponse(oDb, oTestBoxData.idTestBox, self._oSrvGlue.getBaseUrl());
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if dResponse is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync elif oStatusData.enmState == TestBoxStatusData.ksTestBoxState_GangCleanup:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync elif oStatusData.enmState != TestBoxStatusData.ksTestBoxState_Idle: # (includes ksTestBoxState_GangGatheringTimedOut)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Check for pending command.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oTestBoxData.enmPendingCmd != TestBoxData.ksTestBoxCmd_None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync asValidCmds = TestBoxController.kasIdleCmds if fIdle else TestBoxController.kasBusyCmds;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dResponse = { constants.tbresp.ALL_PARAM_RESULT: TestBoxController.kdCmdToTbRespCmd[oTestBoxData.enmPendingCmd] };
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oTestBoxData.enmPendingCmd in [TestBoxData.ksTestBoxCmd_Upgrade, TestBoxData.ksTestBoxCmd_UpgradeAndReboot]:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dResponse[constants.tbresp.UPGRADE_PARAM_URL] = self._oSrvGlue.getBaseUrl() + TestBoxController.ksUpgradeZip;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oTestBoxData.enmPendingCmd == TestBoxData.ksTestBoxCmd_Abort and fIdle:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync TestBoxLogic(oDb).setCommand(self._idTestBox, sOldCommand = oTestBoxData.enmPendingCmd,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sNewCommand = TestBoxData.ksTestBoxCmd_None, fCommit = True);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # If doing gang stuff, return 'CMD_WAIT'.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## @todo r=bird: Why is GangTesting included here? Figure out when testing gang testing.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oStatusData.enmState in [TestBoxStatusData.ksTestBoxState_GangGathering,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self._resultResponse(constants.tbresp.CMD_WAIT);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # If idling and enabled try schedule a new task.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and oStatusData.enmState == TestBoxStatusData.ksTestBoxState_Idle: # (paranoia)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dResponse = SchedulerBase.scheduleNewTask(oDb, oTestBoxData, self._oSrvGlue.getBaseUrl());
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if dResponse is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Touch the status row every couple of mins so we can tell that the box is alive.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oStatusData.enmState != TestBoxStatusData.ksTestBoxState_GangGathering \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and oStatusLogic.timeSinceLastChangeInSecs(oStatusData) >= TestBoxStatusLogic.kcSecIdleTouchStatus:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oStatusLogic.touchStatus(oTestBoxData.idTestBox, fCommit = True);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ Implement request for command. """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ Implement request for command. """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ Implements ACK, NACK and NACK(ENOTSUP). """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oDb is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # If the command maps to a TestBoxCmd_T value, it means we have to
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # check and update TestBoxes. If it's an ACK, the testbox status will
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # need updating as well.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sPendingCmd = TestBoxController.kdTbRespCmdToCmd[sCmd];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sPendingCmd is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestBoxLogic.setCommand(self._idTestBox, sOldCommand = sPendingCmd,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sNewCommand = TestBoxData.ksTestBoxCmd_None, fCommit = False);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and TestBoxController.kdCmdToState[sPendingCmd] is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oStatusLogic.updateState(self._idTestBox, TestBoxController.kdCmdToState[sPendingCmd], fCommit = False);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Commit the two updates.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Log NACKs.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oSysLogLogic.addEntry(SystemLogData.ksEvent_CmdNacked,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'idTestBox=%s sCmd=%s' % (self._idTestBox, sPendingCmd),
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self._resultResponse(constants.tbresp.STATUS_ACK);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ Implement command ACK'ing """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sCmd = self._getStringParam(constants.tbreq.COMMAND_ACK_PARAM_CMD_NAME, TestBoxController.kasAckableCmds);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ Implement command NACK'ing """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sCmd = self._getStringParam(constants.tbreq.COMMAND_ACK_PARAM_CMD_NAME, TestBoxController.kasNackableCmds);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ Implement command NACK(ENOTSUP)'ing """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sCmd = self._getStringParam(constants.tbreq.COMMAND_ACK_PARAM_CMD_NAME, TestBoxController.kasNackableCmds);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ Implement submitting log entries to the main log file. """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Parameter validation.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sBody = self._getStringParam(constants.tbreq.LOG_PARAM_BODY, fStrip = False);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self._resultResponse(constants.tbresp.STATUS_NACK);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync (oDb, oStatusData, _) = self._connectToDbAndValidateTb([TestBoxStatusData.ksTestBoxState_Testing,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Write the text to the log file.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestSet = TestSetData().initFromDbWithId(oDb, oStatusData.idTestSet);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## @todo Overflow is a hanging offence, need to note it and fail whatever is going on...
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self._resultResponse(constants.tbresp.STATUS_ACK);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ Implement uploading of files. """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Parameter validation.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sName = self._getStringParam(constants.tbreq.UPLOAD_PARAM_NAME);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sMime = self._getStringParam(constants.tbreq.UPLOAD_PARAM_MIME);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sKind = self._getStringParam(constants.tbreq.UPLOAD_PARAM_KIND);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sDesc = self._getStringParam(constants.tbreq.UPLOAD_PARAM_DESC);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync (oDb, oStatusData, _) = self._connectToDbAndValidateTb([TestBoxStatusData.ksTestBoxState_Testing,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestBoxControllerException('Invalid file name "%s"' % (sName,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if re.match(r'^[a-zA-Z0-9_\-(){}#@+,.=]*$', sName) is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestBoxControllerException('Invalid file name "%s"' % (sName,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sMime not in [ 'text/plain', #'text/html', 'text/xml',
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #'video/webm', 'video/mpeg', 'video/mpeg4-generic',
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestBoxControllerException('Invalid MIME type "%s"' % (sMime,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestBoxControllerException('Invalid kind "%s"' % (sKind,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestBoxControllerException('Invalid description "%s"' % (sDesc,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestBoxControllerException('Invalid description "%s"' % (sDesc,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if ('application/octet-stream', {}) != self._oSrvGlue.getContentType():
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestBoxControllerException('Unexpected content type: %s; %s' % self._oSrvGlue.getContentType());
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestBoxControllerException('File "%s" is empty or negative in size (%s)' % (sName, cbFile));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if (cbFile + 1048575) / 1048576 > config.g_kcMbMaxUploadSingle:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestBoxControllerException('File "%s" is too big %u bytes (max %u MiB)'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Write the text to the log file.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestSet = TestSetData().initFromDbWithId(oDb, oStatusData.idTestSet);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oDstFile = TestSetLogic(oDb).createFile(oTestSet, sName = sName, sMime = sMime, sKind = sKind, sDesc = sDesc,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self._resultResponse(constants.tbresp.STATUS_ACK);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ Implement submitting "XML" like test result stream. """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Parameter validation.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sXml = self._getStringParam(constants.tbreq.XML_RESULT_PARAM_BODY, fStrip = False);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if len(sXml) == 0: # Used for link check by vboxinstaller.py on Windows.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self._resultResponse(constants.tbresp.STATUS_ACK);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync (oDb, oStatusData, _) = self._connectToDbAndValidateTb([TestBoxStatusData.ksTestBoxState_Testing,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Process the XML.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync (sError, fUnforgivable) = TestResultLogic(oDb).processXmlStream(sXml, self._idTestSet);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sError is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestSet = TestSetData().initFromDbWithId(oDb, oStatusData.idTestSet);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.writeToMainLog(oTestSet, '\n!!XML error: %s\n\n' % (sXml,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self._resultResponse(constants.tbresp.STATUS_NACK);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self._resultResponse(constants.tbresp.STATUS_ACK);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Implement EXEC completion.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Because the action is request by the worker thread of the testbox
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync script we cannot pass pending commands back to it like originally
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync planned. So, we just complete the test set and update the status.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Parameter validation.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sStatus = self._getStringParam(constants.tbreq.EXEC_COMPLETED_PARAM_RESULT, TestBoxController.kasValidResults);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync (oDb, oStatusData, _) = self._connectToDbAndValidateTb([TestBoxStatusData.ksTestBoxState_Testing,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Complete the status.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync idTestSetGangLeader = oTestSetLogic.complete(oStatusData.idTestSet, self.kadTbResultToStatus[sStatus], fCommit = False);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oStatusData.enmState == TestBoxStatusData.ksTestBoxState_Testing:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync assert idTestSetGangLeader is None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync GlobalResourceLogic(oDb).freeGlobalResourcesByTestBox(self._idTestBox);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oStatusLogic.updateState(self._idTestBox, TestBoxStatusData.ksTestBoxState_Idle, fCommit = False);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync assert idTestSetGangLeader is not None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oStatusLogic.updateState(self._idTestBox, TestBoxStatusData.ksTestBoxState_GangCleanup, oStatusData.idTestSet,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oStatusLogic.isWholeGangDoneTesting(idTestSetGangLeader):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync GlobalResourceLogic(oDb).freeGlobalResourcesByTestBox(self._idTestBox);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oStatusLogic.updateState(self._idTestBox, TestBoxStatusData.ksTestBoxState_Idle, fCommit = False);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self._resultResponse(constants.tbresp.STATUS_ACK);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Gets the standard parameters and validates them.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync The parameters are returned as a tuple: sAction, idTestBox, sTestBoxUuid.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Note! the sTextBoxId can be None if it's a SIGNON request.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Raises TestBoxControllerException on invalid input.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Get the action parameter and validate it.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if constants.tbreq.ALL_PARAM_ACTION not in dParams:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestBoxControllerException('No "%s" parameter in request (params: %s)' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sAction = dParams[constants.tbreq.ALL_PARAM_ACTION];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestBoxControllerException('Unknown action "%s" in request (params: %s; action: %s)' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # TestBox UUID.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if constants.tbreq.ALL_PARAM_TESTBOX_UUID not in dParams:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestBoxControllerException('No "%s" parameter in request (params: %s)' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % (constants.tbreq.ALL_PARAM_TESTBOX_UUID, dParams,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sTestBoxUuid = dParams[constants.tbreq.ALL_PARAM_TESTBOX_UUID];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestBoxControllerException('Invalid %s parameter value "%s": %s ' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % (constants.tbreq.ALL_PARAM_TESTBOX_UUID, sTestBoxUuid, oXcpt));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sTestBoxUuid == '00000000-0000-0000-0000-000000000000':
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestBoxControllerException('Invalid %s parameter value "%s": NULL UUID not allowed.' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % (constants.tbreq.ALL_PARAM_TESTBOX_UUID, sTestBoxUuid));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # TestBox ID.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if constants.tbreq.ALL_PARAM_TESTBOX_ID in dParams:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sTestBoxId = dParams[constants.tbreq.ALL_PARAM_TESTBOX_ID];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestBoxControllerException('Bad value for "%s": "%s"' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % (constants.tbreq.ALL_PARAM_TESTBOX_ID, sTestBoxId));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestBoxControllerException('No "%s" parameter in request (params: %s)' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % (constants.tbreq.ALL_PARAM_TESTBOX_ID, dParams,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Test Set ID.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if constants.tbreq.RESULT_PARAM_TEST_SET_ID in dParams:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sTestSetId = dParams[constants.tbreq.RESULT_PARAM_TEST_SET_ID];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestBoxControllerException('Bad value for "%s": "%s"' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % (constants.tbreq.RESULT_PARAM_TEST_SET_ID, sTestSetId));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync elif sAction not in [ constants.tbreq.XML_RESULTS, ]: ## More later.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestBoxControllerException('No "%s" parameter in request (params: %s)' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % (constants.tbreq.RESULT_PARAM_TEST_SET_ID, dParams,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # The testbox address.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sTestBoxAddr is None or sTestBoxAddr.strip() == '':
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestBoxControllerException('Invalid client address "%s"' % (sTestBoxAddr,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Update the list of checked parameters.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._asCheckedParams.extend([constants.tbreq.ALL_PARAM_TESTBOX_UUID, constants.tbreq.ALL_PARAM_ACTION]);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if idTestBox is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._asCheckedParams.append(constants.tbreq.ALL_PARAM_TESTBOX_ID);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if idTestSet is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._asCheckedParams.append(constants.tbreq.RESULT_PARAM_TEST_SET_ID);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return (sAction, idTestBox, sTestBoxUuid, sTestBoxAddr, idTestSet);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Dispatches the incoming request.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Will raise TestBoxControllerException on failure.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Must be a POST request.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestBoxControllerException('Error retriving request method: %s' % (oXcpt,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestBoxControllerException('Error expected POST request not "%s"' % (sMethod,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Get the parameters and checks for duplicates.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestBoxControllerException('Error retriving parameters: %s' % (oXcpt,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TestBoxControllerException('Parameter "%s" is given multiple times: %s' % (sKey, dParams[sKey]));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Get+validate the standard action parameters and dispatch the request.