def _doGangGathering(self, oDb, oStatusData):
     """
     _doRequestCommand worker for handling a box in gang-gathering state.
     This only checks for timeout.  It will update the oStatusData if a
     timeout is detected, so that the box will be idle upon return.
     """
     oStatusLogic = TestBoxStatusLogic(oDb)
     if     oStatusLogic.timeSinceLastChangeInSecs(oStatusData) > config.g_kcSecGangGathering \
        and SchedulerBase.tryCancelGangGathering(oDb, oStatusData): # <-- Updates oStatusData.
         self._doGangGatheringTimedOut(oDb, oStatusData)
     return None
 def _doGangGathering(self, oDb, oStatusData):
     """
     _doRequestCommand worker for handling a box in gang-gathering state.
     This only checks for timeout.  It will update the oStatusData if a
     timeout is detected, so that the box will be idle upon return.
     """
     oStatusLogic = TestBoxStatusLogic(oDb);
     if     oStatusLogic.timeSinceLastChangeInSecs(oStatusData) > config.g_kcSecGangGathering \
        and SchedulerBase.tryCancelGangGathering(oDb, oStatusData): # <-- Updates oStatusData.
         self._doGangGatheringTimedOut(oDb, oStatusData);
     return None;
    def _doRequestCommand(self, fIdle):
        """
        Common code for handling command request.
        """

        (oDb, oStatusData, oTestBoxData) = self._connectToDbAndValidateTb()
        if oDb is None:
            return False

        #
        # Status clean up.
        #
        # Only when BUSY will the TestBox Script request and execute commands
        # concurrently.  So, it must be idle when sending REQUEST_COMMAND_IDLE.
        #
        if fIdle:
            if oStatusData.enmState == TestBoxStatusData.ksTestBoxState_GangGathering:
                self._doGangGathering(oDb, oStatusData)
            elif oStatusData.enmState == TestBoxStatusData.ksTestBoxState_GangGatheringTimedOut:
                self._doGangGatheringTimedOut(oDb, oStatusData)
            elif oStatusData.enmState == TestBoxStatusData.ksTestBoxState_GangTesting:
                dResponse = SchedulerBase.composeExecResponse(
                    oDb, oTestBoxData.idTestBox, self._oSrvGlue.getBaseUrl())
                if dResponse is not None:
                    return dResponse
            elif oStatusData.enmState == TestBoxStatusData.ksTestBoxState_GangCleanup:
                self._doGangCleanup(oDb, oStatusData)
            elif oStatusData.enmState != TestBoxStatusData.ksTestBoxState_Idle:  # (includes ksTestBoxState_GangGatheringTimedOut)
                self._cleanupOldTest(oDb, oStatusData)

        #
        # Check for pending command.
        #
        if oTestBoxData.enmPendingCmd != TestBoxData.ksTestBoxCmd_None:
            asValidCmds = TestBoxController.kasIdleCmds if fIdle else TestBoxController.kasBusyCmds
            if oTestBoxData.enmPendingCmd in asValidCmds:
                dResponse = {
                    constants.tbresp.ALL_PARAM_RESULT:
                    TestBoxController.kdCmdToTbRespCmd[
                        oTestBoxData.enmPendingCmd]
                }
                if oTestBoxData.enmPendingCmd in [
                        TestBoxData.ksTestBoxCmd_Upgrade,
                        TestBoxData.ksTestBoxCmd_UpgradeAndReboot
                ]:
                    dResponse[constants.tbresp.
                              UPGRADE_PARAM_URL] = self._oSrvGlue.getBaseUrl(
                              ) + TestBoxController.ksUpgradeZip
                return self._writeResponse(dResponse)

            if oTestBoxData.enmPendingCmd == TestBoxData.ksTestBoxCmd_Abort and fIdle:
                TestBoxLogic(oDb).setCommand(
                    self._idTestBox,
                    sOldCommand=oTestBoxData.enmPendingCmd,
                    sNewCommand=TestBoxData.ksTestBoxCmd_None,
                    fCommit=True)

        #
        # If doing gang stuff, return 'CMD_WAIT'.
        #
        ## @todo r=bird: Why is GangTesting included here? Figure out when testing gang testing.
        if oStatusData.enmState in [
                TestBoxStatusData.ksTestBoxState_GangGathering,
                TestBoxStatusData.ksTestBoxState_GangTesting,
                TestBoxStatusData.ksTestBoxState_GangCleanup
        ]:
            return self._resultResponse(constants.tbresp.CMD_WAIT)

        #
        # If idling and enabled try schedule a new task.
        #
        if    fIdle \
          and oTestBoxData.fEnabled \
          and not TestSetLogic(oDb).isTestBoxExecutingToRapidly(oTestBoxData.idTestBox) \
          and oStatusData.enmState == TestBoxStatusData.ksTestBoxState_Idle: # (paranoia)
            dResponse = SchedulerBase.scheduleNewTask(
                oDb, oTestBoxData, oStatusData.iWorkItem,
                self._oSrvGlue.getBaseUrl())
            if dResponse is not None:
                return self._writeResponse(dResponse)

        #
        # Touch the status row every couple of mins so we can tell that the box is alive.
        #
        oStatusLogic = TestBoxStatusLogic(oDb)
        if    oStatusData.enmState != TestBoxStatusData.ksTestBoxState_GangGathering \
          and oStatusLogic.timeSinceLastChangeInSecs(oStatusData) >= TestBoxStatusLogic.kcSecIdleTouchStatus:
            oStatusLogic.touchStatus(oTestBoxData.idTestBox, fCommit=True)

        return self._idleResponse()
    def _doRequestCommand(self, fIdle):
        """
        Common code for handling command request.
        """

        (oDb, oStatusData, oTestBoxData) = self._connectToDbAndValidateTb();
        if oDb is None:
            return False;

        #
        # Status clean up.
        #
        # Only when BUSY will the TestBox Script request and execute commands
        # concurrently.  So, it must be idle when sending REQUEST_COMMAND_IDLE.
        #
        if fIdle:
            if oStatusData.enmState == TestBoxStatusData.ksTestBoxState_GangGathering:
                self._doGangGathering(oDb, oStatusData);
            elif oStatusData.enmState == TestBoxStatusData.ksTestBoxState_GangGatheringTimedOut:
                self._doGangGatheringTimedOut(oDb, oStatusData);
            elif oStatusData.enmState == TestBoxStatusData.ksTestBoxState_GangTesting:
                dResponse = SchedulerBase.composeExecResponse(oDb, oTestBoxData.idTestBox, self._oSrvGlue.getBaseUrl());
                if dResponse is not None:
                    return dResponse;
            elif oStatusData.enmState == TestBoxStatusData.ksTestBoxState_GangCleanup:
                self._doGangCleanup(oDb, oStatusData);
            elif oStatusData.enmState != TestBoxStatusData.ksTestBoxState_Idle: # (includes ksTestBoxState_GangGatheringTimedOut)
                self._cleanupOldTest(oDb, oStatusData);

        #
        # Check for pending command.
        #
        if oTestBoxData.enmPendingCmd != TestBoxData.ksTestBoxCmd_None:
            asValidCmds = TestBoxController.kasIdleCmds if fIdle else TestBoxController.kasBusyCmds;
            if oTestBoxData.enmPendingCmd in asValidCmds:
                dResponse = { constants.tbresp.ALL_PARAM_RESULT: TestBoxController.kdCmdToTbRespCmd[oTestBoxData.enmPendingCmd] };
                if oTestBoxData.enmPendingCmd in [TestBoxData.ksTestBoxCmd_Upgrade, TestBoxData.ksTestBoxCmd_UpgradeAndReboot]:
                    dResponse[constants.tbresp.UPGRADE_PARAM_URL] = self._oSrvGlue.getBaseUrl() + TestBoxController.ksUpgradeZip;
                return self._writeResponse(dResponse);

            if oTestBoxData.enmPendingCmd == TestBoxData.ksTestBoxCmd_Abort and fIdle:
                TestBoxLogic(oDb).setCommand(self._idTestBox, sOldCommand = oTestBoxData.enmPendingCmd,
                                             sNewCommand = TestBoxData.ksTestBoxCmd_None, fCommit = True);

        #
        # If doing gang stuff, return 'CMD_WAIT'.
        #
        ## @todo r=bird: Why is GangTesting included here? Figure out when testing gang testing.
        if oStatusData.enmState in [TestBoxStatusData.ksTestBoxState_GangGathering,
                                    TestBoxStatusData.ksTestBoxState_GangTesting,
                                    TestBoxStatusData.ksTestBoxState_GangCleanup]:
            return self._resultResponse(constants.tbresp.CMD_WAIT);

        #
        # If idling and enabled try schedule a new task.
        #
        if fIdle \
          and oTestBoxData.fEnabled \
          and oStatusData.enmState == TestBoxStatusData.ksTestBoxState_Idle: # (paranoia)
            dResponse = SchedulerBase.scheduleNewTask(oDb, oTestBoxData, self._oSrvGlue.getBaseUrl());
            if dResponse is not None:
                return self._writeResponse(dResponse);

        #
        # Touch the status row every couple of mins so we can tell that the box is alive.
        #
        oStatusLogic = TestBoxStatusLogic(oDb);
        if    oStatusData.enmState != TestBoxStatusData.ksTestBoxState_GangGathering \
          and oStatusLogic.timeSinceLastChangeInSecs(oStatusData) >= TestBoxStatusLogic.kcSecIdleTouchStatus:
            oStatusLogic.touchStatus(oTestBoxData.idTestBox, fCommit = True);

        return self._idleResponse();