def removeEntry(self, uidAuthor, idSchedGroup, fCascade = False, fCommit = False): """ Deletes a scheduling group. """ # # Input validation and retrival of current data. # if idSchedGroup == 1: raise TMExceptionBase('Cannot remove the default scheduling group (id 1).'); oData = SchedGroupDataEx().initFromDbWithId(self._oDb, idSchedGroup); # # We use cascade a little different here... We don't actually delete # associated testboxes or testgroups. # if len(oData.aoTestBoxes) > 0: if fCascade is not True: # Complain about there being associated testboxes. asTestBoxes = ['%s (#%d)' % (oTestBox.sName, oTestBox.idTestBox) for oTestBox in oData.aoTestBoxes]; raise TMExceptionBase('Scheduling group #%d is associated with one or more test boxes: %s' % (idSchedGroup, ', '.join(asTestBoxes),)); else: # Reassign testboxes to scheduling group #1 (the default group). oTbLogic = TestBoxLogic(self._oDb); for oTestBox in oData.aoTestBoxes: oTbCopy = TestBoxData().initFromOther(oTestBox); oTbCopy.idSchedGroup = 1; oTbLogic.editEntry(oTbCopy, uidAuthor, fCommit = False); oData = SchedGroupDataEx().initFromDbWithId(self._oDb, idSchedGroup); if len(oData.aoTestBoxes) != 0: raise TMExceptionBase('More testboxes was added to the scheduling group as we were trying to delete it.'); # # Remove the group and all member records. # for oMember in oData.aoMembers: self._removeSchedGroupMember(uidAuthor, oMember); self._oDb.execute('UPDATE SchedGroupMembers\n' 'SET tsExpire = CURRENT_TIMESTAMP\n' 'WHERE idSchedGroup = %s\n' ' AND tsExpire = \'infinity\'::TIMESTAMP\n' , (idSchedGroup,)); (tsCur, tsCurMinusOne) = self._oDb.getCurrentTimestamps(); if oData.tsEffective != tsCur and oData.tsEffective != tsCurMinusOne: self._historizeEntry(idSchedGroup, tsCurMinusOne); self._readdEntry(uidAuthor, oData, tsCurMinusOne); self._historizeEntry(idSchedGroup); self._oDb.execute('UPDATE SchedGroups\n' 'SET tsExpire = CURRENT_TIMESTAMP\n' 'WHERE idSchedGroup = %s\n' ' AND tsExpire = \'infinity\'::TIMESTAMP\n' , (idSchedGroup,)) self._oDb.maybeCommit(fCommit) return True;
def removeEntry(self, uidAuthor, idSchedGroup, fCascade = False, fCommit = False): """ Deletes a scheduling group. """ # # Input validation and retrival of current data. # if idSchedGroup == 1: raise TMRowInUse('Cannot remove the default scheduling group (id 1).'); oData = SchedGroupDataEx().initFromDbWithId(self._oDb, idSchedGroup); # # We use cascade a little different here... We don't actually delete # associated testboxes or testgroups. # if oData.aoTestBoxes: if fCascade is not True: # Complain about there being associated testboxes. asTestBoxes = ['%s (#%d)' % (oTestBox.sName, oTestBox.idTestBox) for oTestBox in oData.aoTestBoxes]; raise TMRowInUse('Scheduling group #%d is associated with one or more test boxes: %s' % (idSchedGroup, ', '.join(asTestBoxes),)); else: # Reassign testboxes to scheduling group #1 (the default group). oTbLogic = TestBoxLogic(self._oDb); for oTestBox in oData.aoTestBoxes: oTbCopy = TestBoxData().initFromOther(oTestBox); oTbCopy.idSchedGroup = 1; oTbLogic.editEntry(oTbCopy, uidAuthor, fCommit = False); oData = SchedGroupDataEx().initFromDbWithId(self._oDb, idSchedGroup); if oData.aoTestBoxes: raise TMRowInUse('More testboxes was added to the scheduling group as we were trying to delete it.'); # # Remove the group and all member records. # for oMember in oData.aoMembers: self._removeSchedGroupMember(uidAuthor, oMember); self._oDb.execute('UPDATE SchedGroupMembers\n' 'SET tsExpire = CURRENT_TIMESTAMP\n' 'WHERE idSchedGroup = %s\n' ' AND tsExpire = \'infinity\'::TIMESTAMP\n' , (idSchedGroup,)); (tsCur, tsCurMinusOne) = self._oDb.getCurrentTimestamps(); if oData.tsEffective != tsCur and oData.tsEffective != tsCurMinusOne: self._historizeEntry(idSchedGroup, tsCurMinusOne); self._readdEntry(uidAuthor, oData, tsCurMinusOne); self._historizeEntry(idSchedGroup); self._oDb.execute('UPDATE SchedGroups\n' 'SET tsExpire = CURRENT_TIMESTAMP\n' 'WHERE idSchedGroup = %s\n' ' AND tsExpire = \'infinity\'::TIMESTAMP\n' , (idSchedGroup,)) self._oDb.maybeCommit(fCommit) return True;
def getTestBox(self, idTestBox): """ Gets the corresponding TestBoxData object. """ oRet = self._adCache[self.ksObjType_TestBox_idTestBox].get(idTestBox); if oRet is None: # Load cache entry. from testmanager.core.testbox import TestBoxData; oRet = TestBoxData(); try: oRet.initFromDbWithId(self._oDb, idTestBox, self.tsNow, self.sPeriodBack); except: self._handleDbException(); raise; else: self._adCache[self.ksObjType_TestBox_idGenTestBox][oRet.idGenTestBox] = oRet; self._adCache[self.ksObjType_TestBox_idTestBox][idTestBox] = oRet; return oRet;
def getTestBox(self, idTestBox): """ Gets the corresponding TestBoxData object. """ oRet = self._adCache[self.ksObjType_TestBox_idTestBox].get(idTestBox); if oRet is None: # Load cache entry. from testmanager.core.testbox import TestBoxData; oRet = TestBoxData(); try: oRet.initFromDbWithId(self._oDb, idTestBox, self.tsNow, self.sPeriodBack); except: self._handleDbException(); else: self._adCache[self.ksObjType_TestBox_idGenTestBox][oRet.idGenTestBox] = oRet; self._adCache[self.ksObjType_TestBox_idTestBox][idTestBox] = oRet; return oRet;
def tryFetchStatusAndConfig(self, idTestBox, sTestBoxUuid, sTestBoxAddr): """ Tries to fetch the testbox status and current testbox config. Returns (TestBoxStatusData, TestBoxData) on success, (None, None) if not found. May throw an exception on database error. """ self._oDb.execute( 'SELECT *\n' 'FROM TestBoxStatuses, TestBoxes\n' 'WHERE TestBoxStatuses.idTestBox = %s\n' ' AND TestBoxes.idTestBox = %s\n' ' AND TestBoxes.tsExpire = \'infinity\'::timestamp\n' ' AND TestBoxes.uuidSystem = %s\n' ' AND TestBoxes.ip = %s\n', ( idTestBox, idTestBox, sTestBoxUuid, sTestBoxAddr, )) cRows = self._oDb.getRowCount() if cRows != 1: if cRows != 0: raise TMExceptionBase( 'tryFetchStatusForCommandReq got %s rows for idTestBox=%s' % (cRows, idTestBox)) return (None, None) aoRow = self._oDb.fetchOne() return (TestBoxStatusData().initFromDbRow(aoRow[0:5]), TestBoxData().initFromDbRow(aoRow[5:]))
def getEligibleTestBoxes(self): """ Returns a list of TestBoxData objects with eligible testboxes for the total period of time defined for this graph. """ # Taking the simple way out now, getting all active testboxes at the # time without filtering out on sample sources. # 1. Collect the relevant testbox generation IDs. self._oDb.execute('SELECT DISTINCT idTestBox, idGenTestBox\n' 'FROM TestSets\n' 'WHERE ' + self._getEligibleTestSetPeriod(fLeadingAnd=False) + 'ORDER BY idTestBox, idGenTestBox DESC') idPrevTestBox = -1 asIdGenTestBoxes = [] for _ in range(self._oDb.getRowCount()): aoRow = self._oDb.fetchOne() if aoRow[0] != idPrevTestBox: idPrevTestBox = aoRow[0] asIdGenTestBoxes.append(str(aoRow[1])) # 2. Query all the testbox data in one go. aoRet = [] if len(asIdGenTestBoxes) > 0: self._oDb.execute('SELECT *\n' 'FROM TestBoxes\n' 'WHERE idGenTestBox in (' + ','.join(asIdGenTestBoxes) + ')\n' 'ORDER BY sName') for _ in range(self._oDb.getRowCount()): aoRet.append(TestBoxData().initFromDbRow(self._oDb.fetchOne())) return aoRet
def tryFetchStatusAndConfig(self, idTestBox, sTestBoxUuid, sTestBoxAddr): """ Tries to fetch the testbox status and current testbox config. Returns (TestBoxStatusData, TestBoxData) on success, (None, None) if not found. May throw an exception on database error. """ self._oDb.execute('SELECT TestBoxStatuses.*,\n' ' TestBoxesWithStrings.*\n' 'FROM TestBoxStatuses,\n' ' TestBoxesWithStrings\n' 'WHERE TestBoxStatuses.idTestBox = %s\n' ' AND TestBoxesWithStrings.idTestBox = %s\n' ' AND TestBoxesWithStrings.tsExpire = \'infinity\'::TIMESTAMP\n' ' AND TestBoxesWithStrings.uuidSystem = %s\n' ' AND TestBoxesWithStrings.ip = %s\n' , ( idTestBox, idTestBox, sTestBoxUuid, sTestBoxAddr,) ); cRows = self._oDb.getRowCount(); if cRows != 1: if cRows != 0: raise TMTooManyRows('tryFetchStatusForCommandReq got %s rows for idTestBox=%s' % (cRows, idTestBox)); return (None, None); aoRow = self._oDb.fetchOne(); return (TestBoxStatusData().initFromDbRow(aoRow[:TestBoxStatusData.kcDbColumns]), TestBoxData().initFromDbRow(aoRow[TestBoxStatusData.kcDbColumns:]));
def _actionTestBoxListPost(self): """Actions on a list of testboxes.""" # Parameters. aidTestBoxes = self.getListOfIntParams(TestBoxData.ksParam_idTestBox, iMin = 1, aiDefaults = []); sListAction = self.getStringParam(self.ksParamListAction); if sListAction in [asDesc[0] for asDesc in WuiTestBoxList.kasTestBoxActionDescs]: idAction = None; else: asActionPrefixes = [ 'setgroup-', ]; i = 0; while i < len(asActionPrefixes) and not sListAction.startswith(asActionPrefixes[i]): i += 1; if i >= len(asActionPrefixes): raise WuiException('Parameter "%s" has an invalid value: "%s"' % (self.ksParamListAction, sListAction,)); idAction = sListAction[len(asActionPrefixes[i]):]; if not idAction.isdigit(): raise WuiException('Parameter "%s" has an invalid value: "%s"' % (self.ksParamListAction, sListAction,)); idAction = int(idAction); sListAction = sListAction[:len(asActionPrefixes[i]) - 1]; self._checkForUnknownParameters(); # Take action. if sListAction is 'none': pass; else: oLogic = TestBoxLogic(self._oDb); aoTestBoxes = [] for idTestBox in aidTestBoxes: aoTestBoxes.append(TestBoxData().initFromDbWithId(self._oDb, idTestBox)); if sListAction in [ 'enable', 'disable' ]: fEnable = sListAction == 'enable'; for oTestBox in aoTestBoxes: if oTestBox.fEnabled != fEnable: oTestBox.fEnabled = fEnable; oLogic.editEntry(oTestBox, self._oCurUser.uid, fCommit = False); elif sListAction == 'setgroup': for oTestBox in aoTestBoxes: if oTestBox.idSchedGroup != idAction: oTestBox.idSchedGroup = idAction; oLogic.editEntry(oTestBox, self._oCurUser.uid, fCommit = False); else: for oTestBox in aoTestBoxes: if oTestBox.enmPendingCmd != sListAction: oTestBox.enmPendingCmd = sListAction; oLogic.editEntry(oTestBox, self._oCurUser.uid, fCommit = False); self._oDb.commit(); # Re-display the list. self._sPageTitle = None; self._sPageBody = None; self._sRedirectTo = self._sActionUrlBase + self.ksActionTestBoxList; return True;
def _initExtraMembersFromDb(self, oDb, tsNow = None, sPeriodBack = None): """ Worker shared by the initFromDb* methods. Returns self. Raises exception if no row or database error. """ # # It all upfront so the object has some kind of consistency if anything # below raises exceptions. # self.oBuildSrc = None; self.oBuildSrcValidationKit = None; self.aoTestBoxes = []; self.aoMembers = []; # # Build source. # if self.idBuildSrc: self.oBuildSrc = BuildSourceData().initFromDbWithId(oDb, self.idBuildSrc, tsNow, sPeriodBack); if self.idBuildSrcTestSuite: self.oBuildSrcValidationKit = BuildSourceData().initFromDbWithId(oDb, self.idBuildSrcTestSuite, tsNow, sPeriodBack); # # Test Boxes. # oDb.execute('SELECT TestBoxesWithStrings.*\n' 'FROM TestBoxesWithStrings,\n' ' TestBoxesInSchedGroups\n' 'WHERE TestBoxesInSchedGroups.idSchedGroup = %s\n' + self.formatSimpleNowAndPeriod(oDb, tsNow, sPeriodBack, sTablePrefix = 'TestBoxesInSchedGroups.') + ' AND TestBoxesWithStrings.idTestBox = TestBoxesInSchedGroups.idTestBox\n' + self.formatSimpleNowAndPeriod(oDb, tsNow, sPeriodBack, sTablePrefix = 'TestBoxesWithStrings.') + 'ORDER BY TestBoxesWithStrings.sName, TestBoxesWithStrings.idTestBox\n' , (self.idSchedGroup,)); for aoRow in oDb.fetchAll(): self.aoTestBoxes.append(TestBoxData().initFromDbRow(aoRow)); # # Test groups. # oDb.execute('SELECT SchedGroupMembers.*, TestGroups.*\n' 'FROM SchedGroupMembers\n' 'LEFT OUTER JOIN TestGroups ON (SchedGroupMembers.idTestGroup = TestGroups.idTestGroup)\n' 'WHERE SchedGroupMembers.idSchedGroup = %s\n' + self.formatSimpleNowAndPeriod(oDb, tsNow, sPeriodBack, sTablePrefix = 'SchedGroupMembers.') + self.formatSimpleNowAndPeriod(oDb, tsNow, sPeriodBack, sTablePrefix = 'TestGroups.') + 'ORDER BY SchedGroupMembers.idTestGroupPreReq, SchedGroupMembers.idTestGroup\n' , (self.idSchedGroup,)); for aoRow in oDb.fetchAll(): self.aoMembers.append(SchedGroupMemberDataEx().initFromDbRow(aoRow)); return self;
def getGang(self, idTestSetGangLeader): """ Returns an array of TestBoxData object representing the gang for the given testset. """ self._oDb.execute( 'SELECT TestBoxes.*\n' 'FROM TestBoxes, TestSets\n' 'WHERE TestSets.idTestSetGangLeader = %s\n' ' AND TestSets.idGenTestBox = TestBoxes.idGenTestBox\n' 'ORDER BY iGangMemberNo ASC\n', (idTestSetGangLeader, )) aaoRows = self._oDb.fetchAll() aoTestBoxes = [] for aoRow in aaoRows: aoTestBoxes.append(TestBoxData().initFromDbRow(aoRow)) return aoTestBoxes
def _initExtraMembersFromDb(self, oDb, tsNow=None, sPeriodBack=None): """ Worker shared by the initFromDb* methods. Returns self. Raises exception if no row or database error. """ # # It all upfront so the object has some kind of consistency if anything # below raises exceptions. # self.oBuildSrc = None self.oBuildSrcValidationKit = None self.aoTestBoxes = [] self.aoMembers = [] # # Build source. # if self.idBuildSrc: self.oBuildSrc = BuildSourceData().initFromDbWithId( oDb, self.idBuildSrc, tsNow, sPeriodBack) if self.idBuildSrcTestSuite: self.oBuildSrcValidationKit = BuildSourceData().initFromDbWithId( oDb, self.idBuildSrcTestSuite, tsNow, sPeriodBack) # # Test Boxes. # ## @todo sPeriodBack! if tsNow is None: oDb.execute( 'SELECT *\n' 'FROM TestBoxes\n' 'WHERE TestBoxes.idSchedGroup = %s\n' ' AND TestBoxes.tsExpire = \'infinity\'::TIMESTAMP\n' 'ORDER BY TestBoxes.sName, TestBoxes.idTestBox\n', (self.idSchedGroup, )) else: oDb.execute( 'SELECT *\n' 'FROM TestBoxes\n' 'WHERE TestBoxes.idSchedGroup = %s\n' ' AND TestBoxes.tsExpire > %s\n' ' AND TestBoxes.tsEffective <= %s\n' 'ORDER BY TestBoxes.sName, TestBoxes.idTestBox\n', (self.idSchedGroup, tsNow, tsNow, tsNow, tsNow)) for aoRow in oDb.fetchAll(): self.aoTestBoxes.append(TestBoxData().initFromDbRow(aoRow)) # # Test groups. # ## @todo sPeriodBack! if tsNow is None: oDb.execute( 'SELECT SchedGroupMembers.*, TestGroups.*\n' 'FROM SchedGroupMembers\n' 'LEFT OUTER JOIN TestGroups ON (SchedGroupMembers.idTestGroup = TestGroups.idTestGroup)\n' 'WHERE SchedGroupMembers.idSchedGroup = %s\n' ' AND SchedGroupMembers.tsExpire = \'infinity\'::TIMESTAMP\n' ' AND TestGroups.tsExpire = \'infinity\'::TIMESTAMP\n' 'ORDER BY SchedGroupMembers.idTestGroupPreReq, SchedGroupMembers.idTestGroup\n', (self.idSchedGroup, )) else: oDb.execute( 'SELECT SchedGroupMembers.*, TestGroups.*\n' 'FROM SchedGroupMembers\n' 'LEFT OUTER JOIN TestGroups ON (SchedGroupMembers.idTestGroup = TestGroups.idTestGroup)\n' 'WHERE SchedGroupMembers.idSchedGroup = %s\n' ' AND SchedGroupMembers.tsExpire > %s\n' ' AND SchedGroupMembers.tsEffective <= %s\n' ' AND TestGroups.tsExpire > %s\n' ' AND TestGroups.tsEffective <= %s\n' 'ORDER BY SchedGroupMembers.idTestGroupPreReq, SchedGroupMembers.idTestGroup\n', (self.idSchedGroup, tsNow, tsNow, tsNow, tsNow)) for aoRow in oDb.fetchAll(): self.aoMembers.append( SchedGroupMemberDataEx().initFromDbRow(aoRow)) return self