cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# -*- coding: utf-8 -*-
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# $Id$
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# pylint: disable=C0302
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync"""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncTest Manager - Base class and utilities for the schedulers.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync"""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync__copyright__ = \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync"""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncCopyright (C) 2012-2014 Oracle Corporation
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
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.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
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.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
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"""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync__version__ = "$Revision$"
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# Standard python imports.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncimport unittest;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# Validation Kit imports.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom common import utils, constants;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom testmanager import config;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom testmanager.core.build import BuildDataEx, BuildLogic;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom testmanager.core.base import ModelDataBase, ModelDataBaseTestCase, TMExceptionBase;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom testmanager.core.buildsource import BuildSourceData, BuildSourceLogic;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom testmanager.core.globalresource import GlobalResourceLogic;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom testmanager.core.schedgroup import SchedGroupData, SchedGroupLogic;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom testmanager.core.systemlog import SystemLogData, SystemLogLogic;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom testmanager.core.testbox import TestBoxData;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom testmanager.core.testboxstatus import TestBoxStatusData, TestBoxStatusLogic;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom testmanager.core.testcase import TestCaseLogic;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom testmanager.core.testcaseargs import TestCaseArgsDataEx, TestCaseArgsLogic;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncfrom testmanager.core.testset import TestSetData, TestSetLogic;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncclass ReCreateQueueData(object):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Data object for recreating a scheduling queue.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync It's mostly a storage object, but has a few data checking operation
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync associated with it.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def __init__(self, oDb, idSchedGroup):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Load data from the database.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Will extend the entries with aoTestCases and dTestCases members
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # further down. checkForGroupDepCycles will add aidTestGroupPreReqs.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.aoTestGroups = SchedGroupLogic(oDb).getMembers(idSchedGroup);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # aoTestCases entries are TestCaseData instance with iSchedPriority
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # and idTestGroup added for our purposes.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # We will add oTestGroup and aoArgsVariations members to each further down.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.aoTestCases = SchedGroupLogic(oDb).getTestCasesForGroup(idSchedGroup, cMax = 4096);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Load dependencies.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestCaseLogic = TestCaseLogic(oDb)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for oTestCase in self.aoTestCases:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestCase.aidPreReqs = oTestCaseLogic.getTestCasePreReqIds(oTestCase.idTestCase, cMax = 4096);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # aoTestCases entries are TestCaseArgsData instance with iSchedPriority
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # and idTestGroup added for our purposes.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # We will add oTestGroup and oTestCase members to each further down.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.aoArgsVariations = SchedGroupLogic(oDb).getTestCaseArgsForGroup(idSchedGroup, cMax = 65536);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Generate global lookups.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Generate a testcase lookup dictionary for use when working on
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # argument variations.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.dTestCases = dict();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for oTestCase in self.aoTestCases:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.dTestCases[oTestCase.idTestCase] = oTestCase;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync assert len(self.dTestCases) <= len(self.aoTestCases); # Note! Can be shorter!
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Generate a testgroup lookup dictionary.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.dTestGroups = dict();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for oTestGroup in self.aoTestGroups:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.dTestGroups[oTestGroup.idTestGroup] = oTestGroup;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync assert len(self.dTestGroups) == len(self.aoTestGroups);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Associate extra members with the base data.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if len(self.aoTestGroups) > 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Prep the test groups.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for oTestGroup in self.aoTestGroups:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestGroup.aoTestCases = list();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestGroup.dTestCases = dict();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Link testcases to their group, both directions. Prep testcases for
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # argument varation association.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestGroup = self.aoTestGroups[0];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for oTestCase in self.aoTestCases:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oTestGroup.idTestGroup != oTestCase.idTestGroup:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestGroup = self.dTestGroups[oTestCase.idTestGroup];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync assert oTestCase.idTestCase not in oTestGroup.dTestCases;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestGroup.dTestCases[oTestCase.idTestCase] = oTestCase;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestGroup.aoTestCases.append(oTestCase);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestCase.oTestGroup = oTestGroup;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestCase.aoArgsVariations = list();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Associate testcase argument variations with their testcases (group)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # in both directions.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestGroup = self.aoTestGroups[0];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestCase = self.aoTestCases[0] if len(self.aoTestCases) > 0 else None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for oArgVariation in self.aoArgsVariations:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oTestGroup.idTestGroup != oArgVariation.idTestGroup:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestGroup = self.dTestGroups[oArgVariation.idTestGroup];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oTestCase.idTestCase != oArgVariation.idTestCase or oTestCase.idTestGroup != oArgVariation.idTestGroup:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestCase = oTestGroup.dTestCases[oArgVariation.idTestCase];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestCase.aoArgsVariations.append(oArgVariation);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oArgVariation.oTestCase = oTestCase;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oArgVariation.oTestGroup = oTestGroup;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync assert len(self.aoTestCases) == 0;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync assert len(self.aoArgsVariations) == 0;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # done.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync @staticmethod
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _addPreReqError(aoErrors, aidChain, oObj, sMsg):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ Returns a chain of IDs error entry. """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sMsg += ' Dependency chain: %s' % (aidChain[0],);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for i in range(1, len(aidChain)):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sMsg += ' -> %s' % (aidChain[i],);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoErrors.append([sMsg, oObj]);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return aoErrors;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def checkForGroupDepCycles(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Checks for testgroup depencency cycles and any missing testgroup
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dependencies.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns array of errors (see SchedulderBase.recreateQueue()).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoErrors = list();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for oTestGroup in self.aoTestGroups:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync idPreReq = oTestGroup.idTestGroupPreReq;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if idPreReq is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestGroup.aidTestGroupPreReqs = list();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync continue;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aidChain = [oTestGroup.idTestGroup,];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync while idPreReq is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aidChain.append(idPreReq);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if len(aidChain) >= 10:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._addPreReqError(aoErrors, aidChain, oTestGroup,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'TestGroup #%s prerequisite chain is too long!'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % (oTestGroup.idTestGroup,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync break;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oDep = self.dTestGroups.get(idPreReq, None);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oDep is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._addPreReqError(aoErrors, aidChain, oTestGroup,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'TestGroup #%s prerequisite #%s is not in the scheduling group!'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % (oTestGroup.idTestGroup, idPreReq,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync break;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync idPreReq = oDep.idTestGroupPreReq;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestGroup.aidTestGroupPreReqs = aidChain[1:];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return aoErrors;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def checkForMissingTestCaseDeps(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Checks that testcase dependencies stays within bounds. We do not allow
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dependencies outside a testgroup, no dependency cycles or even remotely
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync long dependency chains.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns array of errors (see SchedulderBase.recreateQueue()).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoErrors = list();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for oTestGroup in self.aoTestGroups:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for oTestCase in oTestGroup.aoTestCases:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if len(oTestCase.aidPreReqs) == 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync continue;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Stupid recursion code using special stack(s).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aiIndexes = [(oTestCase, 0), ];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aidChain = [oTestCase.idTestGroup,];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync while len(aiIndexes) > 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync (oCur, i) = aiIndexes[-1];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if i >= len(oCur.aidPreReqs):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aiIndexes.pop();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aidChain.pop();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aiIndexes[-1][1] = i + 1; # whatever happens, we'll advance on the current level.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync idPreReq = oTestCase.aidPreReqs[i];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oDep = oTestGroup.dTestCases.get(idPreReq, None);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oDep is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._addPreReqError(aoErrors, aidChain, oTestCase,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'TestCase #%s prerequisite #%s is not in the scheduling group!'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % (oTestCase.idTestCase, idPreReq));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync elif idPreReq in aidChain:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._addPreReqError(aoErrors, aidChain, oTestCase,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'TestCase #%s prerequisite #%s creates a cycle!'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % (oTestCase.idTestCase, idPreReq));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync elif len(oDep.aiPreReqs) == 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync pass;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync elif len(aidChain) >= 10:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._addPreReqError(aoErrors, aidChain, oTestCase,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'TestCase #%s prerequisite chain is too long!' % (oTestCase.idTestCase,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aiIndexes.append((oDep, 0));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aidChain.append(idPreReq);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return aoErrors;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def deepTestGroupSort(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Sorts the testgroups and their testcases by priority and dependencies.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Note! Don't call this before checking for dependency cycles!
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if len(self.aoTestGroups) == 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # ASSUMES groups as well as testcases are sorted by priority by the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # database. So we only have to concern ourselves with the dependency
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # sorting.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync iGrpPrio = self.aoTestGroups[0].iSchedPriority;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for oTestGroup in self.aoTestGroups:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oTestGroup.iSchedPriority > iGrpPrio:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TMExceptionBase('Incorrectly sorted testgroups returned by database.');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync iGrpPrio = oTestGroup.iSchedPriority;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if len(oTestGroup.aoTestCases) > 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync iTstPrio = oTestGroup.aoTestCases[0];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for oTestCase in oTestGroup.aoTestCases:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oTestCase.iSchedPriority > iTstPrio:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TMExceptionBase('Incorrectly sorted testcases returned by database.');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Sort the testgroups by dependencies.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync i = 0;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync while i < len(self.aoTestGroups):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestGroup = self.aoTestGroups[i];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oTestGroup.idTestGroupPreReq is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync iPreReq = self.aoTestGroups.index(self.dTestGroups[oTestGroup.idTestGroupPreReq]);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if iPreReq > i:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # The prerequisite is after the current entry. Move the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # current entry so that it's following it's prereq entry.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.aoTestGroups.insert(iPreReq + 1, oTestGroup);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.aoTestGroups.pop(i);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync continue;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync assert iPreReq < i;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync i += 1; # Advance.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Sort the testcases by dependencies.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Same algorithm as above, just more prerequisites.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for oTestGroup in self.aoTestGroups:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync i = 0;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync while i < len(oTestGroup.aoTestCases):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestCase = oTestGroup.aoTestCases[i];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if len(oTestCase.aidPreReqs) > 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for idPreReq in oTestCase.aidPreReqs:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync iPreReq = oTestGroup.aoTestCases.index(oTestGroup.dTestCases[idPreReq]);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if iPreReq > i:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # The prerequisite is after the current entry. Move the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # current entry so that it's following it's prereq entry.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestGroup.aoTestGroups.insert(iPreReq + 1, oTestCase);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestGroup.aoTestGroups.pop(i);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync i -= 1; # Don't advance.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync break;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync assert iPreReq < i;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync i += 1; # Advance.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncclass SchedQueueData(ModelDataBase):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Scheduling queue data item.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksIdAttr = 'idSchedGroup';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_idSchedGroup = 'SchedQueueData_idSchedGroup';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_idItem = 'SchedQueueData_idItem';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_offQueue = 'SchedQueueData_offQueue';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_idGenTestCaseArgs = 'SchedQueueData_idGenTestCaseArgs';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_idTestGroup = 'SchedQueueData_idTestGroup';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_aidTestGroupPreReqs = 'SchedQueueData_aidTestGroupPreReqs';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_bmHourlySchedule = 'SchedQueueData_bmHourlySchedule';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_tsConfig = 'SchedQueueData_tsConfig';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_tsLastScheduled = 'SchedQueueData_tsLastScheduled';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_idTestSetGangLeader = 'SchedQueueData_idTestSetGangLeader';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ksParam_cMissingGangMembers = 'SchedQueueData_cMissingGangMembers';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync kasAllowNullAttributes = [ 'idItem', 'offQueue', 'aidTestGroupPreReqs', 'bmHourlySchedule', 'idTestSetGangLeader',
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'tsConfig', 'tsLastScheduled' ];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def __init__(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ModelDataBase.__init__(self);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Initialize with defaults.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # See the database for explanations of each of these fields.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idSchedGroup = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idItem = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.offQueue = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idGenTestCaseArgs = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestGroup = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.aidTestGroupPreReqs = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.bmHourlySchedule = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.tsConfig = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.tsLastScheduled = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestSetGangLeader = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.cMissingGangMembers = 1;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def initFromValues(self, idSchedGroup, idGenTestCaseArgs, idTestGroup, aidTestGroupPreReqs, # pylint: disable=R0913
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync bmHourlySchedule, cMissingGangMembers,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync idItem = None, offQueue = None, tsConfig = None, tsLastScheduled = None, idTestSetGangLeader = None):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Reinitialize with all attributes potentially given as inputs.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Return self.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idSchedGroup = idSchedGroup;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idItem = idItem;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.offQueue = offQueue;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idGenTestCaseArgs = idGenTestCaseArgs;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestGroup = idTestGroup;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.aidTestGroupPreReqs = aidTestGroupPreReqs;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.bmHourlySchedule = bmHourlySchedule;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.tsConfig = tsConfig;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.tsLastScheduled = tsLastScheduled;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestSetGangLeader = idTestSetGangLeader;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.cMissingGangMembers = cMissingGangMembers;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def initFromDbRow(self, aoRow):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Initialize from database row (SELECT * FROM SchedQueues).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns self.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Raises exception if no row is specfied.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if aoRow is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise TMExceptionBase('SchedQueueData not found.');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idSchedGroup = aoRow[0];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idItem = aoRow[1];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.offQueue = aoRow[2];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idGenTestCaseArgs = aoRow[3];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestGroup = aoRow[4];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.aidTestGroupPreReqs = aoRow[5];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.bmHourlySchedule = aoRow[6];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.tsConfig = aoRow[7];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.tsLastScheduled = aoRow[8];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.idTestSetGangLeader = aoRow[9];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.cMissingGangMembers = aoRow[10];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncclass SchedulerBase(object):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync The scheduler base class.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync The scheduler classes have two functions:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 1. Recreate the scheduling queue.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 2. Pick the next task from the queue.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync The first is scheduler specific, the latter isn't.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync class BuildCache(object):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ Build cache. """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync class BuildCacheIterator(object):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ Build class iterator. """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def __init__(self, oCache):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.oCache = oCache;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.iCur = 0;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def __iter__(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """Returns self, required by the language."""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def next(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """Returns the next build, raises StopIteration when the end has been reached."""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync while True:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if self.iCur >= len(self.oCache.aoEntries):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oEntry = self.oCache.fetchFromCursor();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oEntry is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise StopIteration;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oEntry = self.oCache.aoEntries[self.iCur];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.iCur += 1;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if not oEntry.fRemoved:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return oEntry;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # end
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync class BuildCacheEntry(object):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ Build cache entry. """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def __init__(self, oBuild, fMaybeBlacklisted):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.oBuild = oBuild;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._fBlacklisted = None if fMaybeBlacklisted is True else False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.fRemoved = False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._dPreReqDecisions = dict();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def remove(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Marks the cache entry as removed.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync This doesn't actually remove it from the cache array, only marks
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync it as removed. It has no effect on open iterators.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.fRemoved = True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def getPreReqDecision(self, sPreReqSet):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Retrieves a cached prerequisite decision.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns boolean if found, None if not.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self._dPreReqDecisions.get(sPreReqSet);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def setPreReqDecision(self, sPreReqSet, fDecision):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Caches a prerequistie decision.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._dPreReqDecisions[sPreReqSet] = fDecision;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return fDecision;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def isBlacklisted(self, oDb):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ Checks if the build is blacklisted. """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if self._fBlacklisted is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._fBlacklisted = BuildLogic(oDb).isBuildBlacklisted(self.oBuild);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self._fBlacklisted;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def __init__(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.aoEntries = [];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.oCursor = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def setupSource(self, oDb, idBuildSrc, sOs, sCpuArch, tsNow):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ Configures the build cursor for the cache. """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if len(self.aoEntries) == 0 and self.oCursor is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oBuildSource = BuildSourceData().initFromDbWithId(oDb, idBuildSrc, tsNow);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.oCursor = BuildSourceLogic(oDb).openBuildCursor(oBuildSource, sOs, sCpuArch, tsNow);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def __iter__(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """Return an iterator."""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return self.BuildCacheIterator(self);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def fetchFromCursor(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ Fetches a build from the cursor and adds it to the cache."""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if self.oCursor is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoRow = self.oCursor.fetchOne();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if aoRow is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oBuild = BuildDataEx().initFromDbRow(aoRow);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oEntry = self.BuildCacheEntry(oBuild, aoRow[-1]);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.aoEntries.append(oEntry);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return oEntry;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def __init__(self, oDb, oSchedGrpData, iVerbosity = 0, tsSecStart = None):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb = oDb;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oSchedGrpData = oSchedGrpData;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._iVerbosity = iVerbosity;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._asMessages = [];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._tsSecStart = tsSecStart if tsSecStart is not None else utils.timestampSecond();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.oBuildCache = self.BuildCache();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.dTestGroupMembers = dict();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync @staticmethod
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _instantiate(oDb, oSchedGrpData, iVerbosity = 0, tsSecStart = None):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Instantiate the scheduler specified by the scheduling group.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns scheduler child class instance. May raise exception if
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync the input is invalid.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oSchedGrpData.enmScheduler == SchedGroupData.ksScheduler_BestEffortContinousItegration:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync from testmanager.core.schedulerbeci import SchdulerBeci;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oScheduler = SchdulerBeci(oDb, oSchedGrpData, iVerbosity, tsSecStart);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise oDb.integrityException('Invalid scheduler "%s", idSchedGroup=%d' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % (oSchedGrpData.enmScheduler, oSchedGrpData.idSchedGroup));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return oScheduler;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Misc.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def msgDebug(self, sText):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """Debug printing."""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if self._iVerbosity > 1:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._asMessages.append('debug:' + sText);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def msgInfo(self, sText):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """Info printing."""
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if self._iVerbosity > 1:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._asMessages.append('info: ' + sText);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def dprint(self, sMsg):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """Prints a debug message to the srv glue log (see config.py). """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if config.g_kfSrvGlueDebugScheduler:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.dprint(sMsg);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def getElapsedSecs(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """ Returns the number of seconds this scheduling task has been running. """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync tsSecNow = utils.timestampSecond();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if tsSecNow < self._tsSecStart: # paranoia
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._tsSecStart = tsSecNow;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return tsSecNow - self._tsSecStart;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Create schedule.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _recreateQueueCancelGatherings(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Cancels all pending gang gatherings on the current queue.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('SELECT idTestSetGangLeader\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'FROM SchedQueues\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE idSchedGroup = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND idTestSetGangLeader is not NULL\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , (self._oSchedGrpData.idSchedGroup,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if self._oDb.getRowCount() > 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTBStatusLogic = TestBoxStatusLogic(self._oDb);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for aoRow in self._oDb.fetchAll():
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync idTestSetGangLeader = aoRow[0];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTBStatusLogic.updateGangStatus(idTestSetGangLeader,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync TestBoxStatusData.ksTestBoxState_GangGatheringTimedOut,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fCommit = False);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _recreateQueueItems(self, oData):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns an array of queue items (SchedQueueData).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Child classes must override this.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync _ = oData;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return [];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def recreateQueueWorker(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Worker for recreateQueue.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Collect the necessary data and validate it.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oData = ReCreateQueueData(self._oDb, self._oSchedGrpData.idSchedGroup);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoErrors = oData.checkForGroupDepCycles();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoErrors.extend(oData.checkForMissingTestCaseDeps());
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if len(aoErrors) == 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oData.deepTestGroupSort();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # The creation of the scheduling queue is done by the child class.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # We will try guess where in queue we're currently at and rotate
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # the items such that we will resume execution in the approximately
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # same position. The goal of the scheduler is to provide a 100%
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # deterministic result so that if we regenerate the queue when there
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # are no changes to the testcases, testgroups or scheduling groups
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # involved, test execution will be unchanged (save for maybe just a
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # little for gang gathering).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoItems = list();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if len(oData.aoArgsVariations) > 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoItems = self._recreateQueueItems(oData);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.msgDebug('len(aoItems)=%s' % (len(aoItems),));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for i in range(len(aoItems)):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.msgDebug('aoItems[%2d]=%s' % (i, aoItems[i]));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if len(aoItems) > 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('SELECT offQueue FROM SchedQueues WHERE idSchedGroup = %s ORDER BY idItem LIMIT 1'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , (self._oSchedGrpData.idSchedGroup,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if self._oDb.getRowCount() > 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync offQueue = self._oDb.fetchOne()[0];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('SELECT COUNT(*) FROM SchedQueues WHERE idSchedGroup = %s'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , (self._oSchedGrpData.idSchedGroup,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cItems = self._oDb.fetchOne()[0];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync offQueueNew = (offQueue * cItems) / len(aoItems);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if offQueueNew != 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoItems = aoItems[offQueueNew:] + aoItems[:offQueueNew];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Replace the scheduling queue.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Care need to be take to first timeout/abort any gangs in the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # gathering state since these use the queue to set up the date.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._recreateQueueCancelGatherings();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('DELETE FROM SchedQueues WHERE idSchedGroup = %s\n', (self._oSchedGrpData.idSchedGroup,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for oItem in aoItems:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('INSERT INTO SchedQueues (\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' idSchedGroup,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' offQueue,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' idGenTestCaseArgs,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' idTestGroup,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' aidTestGroupPreReqs,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' bmHourlySchedule,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' cMissingGangMembers )\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'VALUES ( %s, %s, %s, %s, %s, %s, %s )\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , ( oItem.idSchedGroup,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oItem.offQueue,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oItem.idGenTestCaseArgs,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oItem.idTestGroup,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oItem.aidTestGroupPreReqs if len(oItem.aidTestGroupPreReqs) > 0 else None,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oItem.bmHourlySchedule,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oItem.cMissingGangMembers
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return (aoErrors, self._asMessages);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync @staticmethod
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def recreateQueue(oDb, uidAuthor, idSchedGroup, iVerbosity = 1):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync (Re-)creates the scheduling queue for the given group.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns (asMessages, asMessages). On success the array with the error
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync will be empty, on failure it will contain (sError, oRelatedObject)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync entries. The messages is for debugging and are simple strings.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Raises exception database error.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoErrors = [];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync asMessages = [];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # To avoid concurrency issues (SchedQueues) and inconsistent data (*),
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # we lock quite a few tables while doing this work. We access more
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # data than scheduleNewTask so we lock some additional tables.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oDb.rollback();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oDb.begin();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oDb.execute('LOCK TABLE SchedGroups, SchedGroupMembers, TestGroups, TestGroupMembers IN SHARE MODE');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oDb.execute('LOCK TABLE TestBoxes, TestCaseArgs, TestCases IN SHARE MODE');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oDb.execute('LOCK TABLE TestBoxStatuses, SchedQueues IN EXCLUSIVE MODE');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Instantiate the scheduler and call the worker function.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oSchedGrpData = SchedGroupData().initFromDbWithId(oDb, idSchedGroup);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oScheduler = SchedulerBase._instantiate(oDb, oSchedGrpData, iVerbosity);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync (aoErrors, asMessages) = oScheduler.recreateQueueWorker();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if len(aoErrors) == 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync SystemLogLogic(oDb).addEntry(SystemLogData.ksEvent_SchedQueueRecreate,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'User #%d recreated sched queue #%d.' % (uidAuthor, idSchedGroup,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oDb.commit();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oDb.rollback();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oDb.rollback();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return (aoErrors, asMessages);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Schedule Task.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _composeGangArguments(self, idTestSet):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Composes the gang specific testdriver arguments.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns command line string, including a leading space.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestSet = TestSetData().initFromDbWithId(self._oDb, idTestSet);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aoGangMembers = TestSetLogic(self._oDb).getGang(oTestSet.idTestSetGangLeader);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sArgs = ' --gang-member-no %s --gang-members %s' % (oTestSet.iGangMemberNo, len(aoGangMembers));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for i in range(len(aoGangMembers)):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sArgs = ' --gang-ipv4-%s %s' % (i, aoGangMembers[i].ip); ## @todo IPv6
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return sArgs;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def composeExecResponseWorker(self, idTestSet, oTestEx, oTestBox, oBuild, oValidationKitBuild, sBaseUrl):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Given all the bits of data, compose an EXEC command response to the testbox.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sScriptZips = oTestEx.oTestCase.sValidationKitZips;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sScriptZips is None or sScriptZips.find('@VALIDATIONKIT_ZIP@') >= 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync assert oValidationKitBuild;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sScriptZips is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sScriptZips = oValidationKitBuild.sBinaries;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sScriptZips = sScriptZips.replace('@VALIDATIONKIT_ZIP@', oValidationKitBuild.sBinaries);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sScriptZips = sScriptZips.replace('@DOWNLOAD_BASE_URL@', sBaseUrl + config.g_ksTmDownloadBaseUrlRel);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sCmdLine = oTestEx.oTestCase.sBaseCmd + ' ' + oTestEx.sArgs;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sCmdLine = sCmdLine.replace('@BUILD_BINARIES@', oBuild.sBinaries);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sCmdLine = sCmdLine.strip();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oTestEx.cGangMembers > 1:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sCmdLine += ' ' + self._composeGangArguments(idTestSet);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cSecTimeout = oTestEx.cSecTimeout if oTestEx.cSecTimeout is not None else oTestEx.oTestCase.cSecTimeout;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cSecTimeout = cSecTimeout * oTestBox.pctScaleTimeout / 100;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dResponse = \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync {
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync constants.tbresp.ALL_PARAM_RESULT: constants.tbresp.CMD_EXEC,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync constants.tbresp.EXEC_PARAM_RESULT_ID: idTestSet,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync constants.tbresp.EXEC_PARAM_SCRIPT_ZIPS: sScriptZips,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync constants.tbresp.EXEC_PARAM_SCRIPT_CMD_LINE: sCmdLine,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync constants.tbresp.EXEC_PARAM_TIMEOUT: cSecTimeout,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync };
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return dResponse;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync @staticmethod
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def composeExecResponse(oDb, idTestSet, sBaseUrl, iVerbosity = 0):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Composes an EXEC response for a gang member (other than the last).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns a EXEC response or raises an exception (DB/input error).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Gather the necessary data.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestSet = TestSetData().initFromDbWithId(oDb, idTestSet);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestBox = TestBoxData().initFromDbWithGenId(oDb, oTestSet.idGenTestBox);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestEx = TestCaseArgsDataEx().initFromDbWithGenId(oDb, oTestSet.idGenTestCaseArgs);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oBuild = BuildDataEx().initFromDbWithId(oDb, oTestSet.idBuild);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oValidationKitBuild = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oTestSet.idBuildTestSuite is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oValidationKitBuild = BuildDataEx().initFromDbWithId(oDb, oTestSet.idBuildTestSuite);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Instantiate the specified scheduler and let it do the rest.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oSchedGrpData = SchedGroupData().initFromDbWithId(oDb, oTestBox.idSchedGroup, oTestSet.tsCreated);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync assert oSchedGrpData.fEnabled is True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync assert oSchedGrpData.idBuildSrc is not None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oScheduler = SchedulerBase._instantiate(oDb, oSchedGrpData, iVerbosity);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return oScheduler.composeExecResponseWorker(idTestSet, oTestEx, oTestBox, oBuild, oValidationKitBuild, sBaseUrl);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _updateTask(self, oTask, tsNow):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Updates a gang schedule task.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync assert oTask.cMissingGangMembers >= 1;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync assert oTask.idTestSetGangLeader is not None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync assert oTask.idTestSetGangLeader >= 1;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if tsNow is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('UPDATE SchedQueues\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' SET idTestSetGangLeader = %s,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' cMissingGangMembers = %s,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' tsLastScheduled = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE idItem = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , (oTask.idTestSetGangLeader, oTask.cMissingGangMembers, tsNow, oTask.idItem,) );
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('UPDATE SchedQueues\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' SET cMissingGangMembers = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE idItem = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , (oTask.cMissingGangMembers, oTask.idItem,) );
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _moveTaskToEndOfQueue(self, oTask, cGangMembers, tsNow):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync The task has been scheduled successfully, reset it's data move it to
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync the end of the queue.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if cGangMembers > 1:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('UPDATE SchedQueues\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' SET idItem = NEXTVAL(\'SchedQueueItemIdSeq\'),\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' idTestSetGangLeader = NULL,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' cMissingGangMembers = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE idItem = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , (cGangMembers, oTask.idItem,) );
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('UPDATE SchedQueues\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' SET idItem = NEXTVAL(\'SchedQueueItemIdSeq\'),\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' idTestSetGangLeader = NULL,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' cMissingGangMembers = 1,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' tsLastScheduled = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE idItem = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , (tsNow, oTask.idItem,) );
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _createTestSet(self, oTask, oTestEx, oTestBoxData, oBuild, oValidationKitBuild, tsNow):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Creates a test set for using the given data.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Will not commit, someone up the callstack will that later on.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns the test set ID, may raise an exception on database error.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Lazy bird doesn't want to write testset.py and does it all here.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # We're getting the TestSet ID first in order to include it in the base
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # file name (that way we can directly relate files on the disk to the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # test set when doing batch work), and also for idTesetSetGangLeader.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('SELECT NEXTVAL(\'TestSetIdSeq\')');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync idTestSet = self._oDb.fetchOne()[0];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sBaseFilename = '%04d/%02d/%02d/%02d/TestSet-%s' \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % (tsNow.year, tsNow.month, tsNow.day, (tsNow.hour / 6) * 6, idTestSet);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Gang scheduling parameters. Changes the oTask data for updating by caller.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync iGangMemberNo = 0;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oTestEx.cGangMembers <= 1:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync assert oTask.idTestSetGangLeader is None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync assert oTask.cMissingGangMembers <= 1;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync elif oTask.idTestSetGangLeader is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync assert oTask.cMissingGangMembers == oTestEx.cGangMembers;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTask.cMissingGangMembers = oTestEx.cGangMembers - 1;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTask.idTestSetGangLeader = idTestSet;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync assert oTask.cMissingGangMembers > 0 and oTask.cMissingGangMembers < oTestEx.cGangMembers;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTask.cMissingGangMembers -= 1;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Do the database stuff.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('INSERT INTO TestSets (\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' idTestSet,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' tsConfig,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' tsCreated,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' idBuild,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' idBuildCategory,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' idBuildTestSuite,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' idGenTestBox,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' idTestBox,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' idTestGroup,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' idGenTestCase,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' idTestCase,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' idGenTestCaseArgs,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' idTestCaseArgs,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' sBaseFilename,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' iGangMemberNo,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' idTestSetGangLeader )\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'VALUES ( %s,\n' # idTestSet
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' %s,\n' # tsConfig
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' %s,\n' # tsCreated
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' %s,\n' # idBuild
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' %s,\n' # idBuildCategory
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' %s,\n' # idBuildTestSuite
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' %s,\n' # idGenTestBox
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' %s,\n' # idTestBox
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' %s,\n' # idTestGroup
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' %s,\n' # idGenTestCase
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' %s,\n' # idTestCase
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' %s,\n' # idGenTestCaseArgs
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' %s,\n' # idTestCaseArgs
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' %s,\n' # sBaseFilename
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' %s,\n' # iGangMemberNo
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' %s)\n' # idTestSetGangLeader
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , ( idTestSet,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTask.tsConfig,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync tsNow,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oBuild.idBuild,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oBuild.idBuildCategory,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oValidationKitBuild.idBuild if oValidationKitBuild is not None else None,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestBoxData.idGenTestBox,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestBoxData.idTestBox,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTask.idTestGroup,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestEx.oTestCase.idGenTestCase,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestEx.oTestCase.idTestCase,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestEx.idGenTestCaseArgs,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestEx.idTestCaseArgs,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sBaseFilename,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync iGangMemberNo,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTask.idTestSetGangLeader,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('INSERT INTO TestResults (\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' idTestResultParent,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' idTestSet,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' tsCreated,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' idStrName,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' cErrors,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' enmStatus,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' iNestingDepth)\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'VALUES ( NULL,\n' # idTestResultParent
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' %s,\n' # idTestSet
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' %s,\n' # tsCreated
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' 0,\n' # idStrName
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' 0,\n' # cErrors
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' \'running\'::TestStatus_T,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' 0)\n' # iNestingDepth
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'RETURNING idTestResult'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , ( idTestSet, tsNow, ));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync idTestResult = self._oDb.fetchOne()[0];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('UPDATE TestSets\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' SET idTestResult = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE idTestSet = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , (idTestResult, idTestSet, ));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return idTestSet;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _tryFindValidationKitBit(self, oTestBoxData, tsNow):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Tries to find the most recent validation kit build suitable for the given testbox.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns BuildDataEx or None. Raise exception on database error.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Can be overridden by child classes to change the default build requirements.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oBuildLogic = BuildLogic(self._oDb);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oBuildSource = BuildSourceData().initFromDbWithId(self._oDb, self._oSchedGrpData.idBuildSrcTestSuite, tsNow);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oCursor = BuildSourceLogic(self._oDb).openBuildCursor(oBuildSource, oTestBoxData.sOs, oTestBoxData.sCpuArch, tsNow);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for _ in range(oCursor.getRowCount()):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oBuild = BuildDataEx().initFromDbRow(oCursor.fetchOne());
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if not oBuildLogic.isBuildBlacklisted(oBuild):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return oBuild;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _tryFindBuild(self, oTask, oTestEx, oTestBoxData, tsNow):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Tries to find a fitting build.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns BuildDataEx or None. Raise exception on database error.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Can be overridden by child classes to change the default build requirements.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Gather the set of prerequisites we have and turn them into a value
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # set for use in the loop below.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Note! We're scheduling on testcase level and ignoring argument variation
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # selections in TestGroupMembers is intentional.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dPreReqs = {};
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Direct prerequisites. We assume they're all enabled as this can be
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # checked at queue creation time.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for oPreReq in oTestEx.aoTestCasePreReqs:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dPreReqs[oPreReq.idTestCase] = 1;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Testgroup dependencies from the scheduling group config.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oTask.aidTestGroupPreReqs is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for iTestGroup in oTask.aidTestGroupPreReqs:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Make sure the _active_ test group members are in the cache.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if iTestGroup not in self.dTestGroupMembers:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('SELECT DISTINCT TestGroupMembers.idTestCase\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'FROM TestGroupMembers, TestCases\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE TestGroupMembers.idTestGroup = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND TestGroupMembers.tsExpire > %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND TestGroupMembers.tsEffective <= %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND TestCases.idTestCase = TestGroupMembers.idTestCase\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND TestCases.tsExpire > %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND TestCases.tsEffective <= %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND TestCases.fEnabled is TRUE\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , (iTestGroup, oTask.tsConfig, oTask.tsConfig, oTask.tsConfig, oTask.tsConfig,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aidTestCases = [];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for aoRow in self._oDb.fetchAll():
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aidTestCases.append(aoRow[0]);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.dTestGroupMembers[iTestGroup] = aidTestCases;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Add the testgroup members to the prerequisites.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for idTestCase in self.dTestGroupMembers[iTestGroup]:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dPreReqs[idTestCase] = 1;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Create a SQL values table out of them.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sPreReqSet = ''
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if len(dPreReqs) > 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for idPreReq in sorted(dPreReqs.keys()):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sPreReqSet += ', (' + str(idPreReq) + ')';
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sPreReqSet = sPreReqSet[2:]; # drop the leading ', '.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Try the builds.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.oBuildCache.setupSource(self._oDb, self._oSchedGrpData.idBuildSrc, oTestBoxData.sOs, oTestBoxData.sCpuArch, tsNow);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for oEntry in self.oBuildCache:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Check build requirements set by the test.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if not oTestEx.matchesBuildProps(oEntry.oBuild):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync continue;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oEntry.isBlacklisted(self._oDb):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oEntry.remove();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync continue;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Check prerequisites. The default scheduler is satisfied if one
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # argument variation has been executed successfully. It is not
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # satisfied if there are any failure runs.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if len(sPreReqSet) > 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fDecision = oEntry.getPreReqDecision(sPreReqSet);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if fDecision is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ## @todo DB Tuning
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Check for missing prereqs.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('SELECT COUNT(*)\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'FROM (VALUES ' + sPreReqSet + ') AS PreReqs(idTestCase)\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'LEFT OUTER JOIN (SELECT *\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' FROM TestSets\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' WHERE enmStatus IN (%s, %s)\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND idBuild = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' ) AS TestSets\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' ON (PreReqs.idTestCase = TestSets.idTestCase)\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE TestSets.idTestSet is NULL\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , ( TestSetData.ksTestStatus_Success, TestSetData.ksTestStatus_Skipped,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oEntry.oBuild.idBuild, ));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cMissingPreReqs = self._oDb.fetchOne()[0];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if cMissingPreReqs > 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.dprint('build %s is missing %u prerequisites (out of %s)'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % (oEntry.oBuild.idBuild, cMissingPreReqs, sPreReqSet,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oEntry.setPreReqDecision(sPreReqSet, False);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync continue;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Check for failed prereq runs.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('SELECT COUNT(*)\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'FROM (VALUES ' + sPreReqSet + ') AS PreReqs(idTestCase),\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' TestSets\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE PreReqs.idTestCase = TestSets.idTestCase\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND TestSets.idBuild = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND TestSets.enmStatus IN (%s, %s, %s)\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , ( oEntry.oBuild.idBuild,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync TestSetData.ksTestStatus_Failure,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync TestSetData.ksTestStatus_TimedOut,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync TestSetData.ksTestStatus_Rebooted,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync )
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync );
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync cFailedPreReqs = self._oDb.fetchOne()[0];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if cFailedPreReqs > 0:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.dprint('build %s is has %u prerequisite failures (out of %s)'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % (oEntry.oBuild.idBuild, cFailedPreReqs, sPreReqSet,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oEntry.setPreReqDecision(sPreReqSet, False);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync continue;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oEntry.setPreReqDecision(sPreReqSet, True);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync elif not fDecision:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync continue;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # If we can, check if the build files still exist.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oEntry.oBuild.areFilesStillThere() is False:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.dprint('build %s no longer exists' % (oEntry.oBuild.idBuild,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oEntry.remove();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync continue;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.dprint('found oBuild=%s' % (oEntry.oBuild,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return oEntry.oBuild;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _tryFindMatchingBuild(self, oLeaderBuild, oTestBoxData, idBuildSrc):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Tries to find a matching build for gang scheduling.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns BuildDataEx or None. Raise exception on database error.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Can be overridden by child classes to change the default build requirements.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Note! Should probably check build prerequisites if we get a different
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # build back, so that we don't use a build which hasn't passed
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # the smoke test.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync _ = idBuildSrc;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return BuildLogic(self._oDb).tryFindSameBuildForOsArch(oLeaderBuild, oTestBoxData.sOs, oTestBoxData.sCpuArch);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _tryAsLeader(self, oTask, oTestEx, oTestBoxData, tsNow, sBaseUrl):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Try schedule the task as a gang leader (can be a gang of one).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns response or None. May raise exception on DB error.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # We don't wait for busy resources, we just try the next test.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestArgsLogic = TestCaseArgsLogic(self._oDb);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if not oTestArgsLogic.areResourcesFree(oTestEx):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.dprint('Cannot get global test resources!');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Find a matching build (this is the difficult bit).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oBuild = self._tryFindBuild(oTask, oTestEx, oTestBoxData, tsNow);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oBuild is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.dprint('No build!');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oTestEx.oTestCase.needValidationKitBit():
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oValidationKitBuild = self._tryFindValidationKitBit(oTestBoxData, tsNow);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oValidationKitBuild is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.dprint('No validation kit build!');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oValidationKitBuild = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Create a testset, allocate the resources and update the state.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Note! Since resource allocation may still fail, we create a nested
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # transaction so we can roll back. (Heed lock warning in docs!)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('SAVEPOINT tryAsLeader');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync idTestSet = self._createTestSet(oTask, oTestEx, oTestBoxData, oBuild, oValidationKitBuild, tsNow);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if GlobalResourceLogic(self._oDb).allocateResources(oTestBoxData.idTestBox, oTestEx.aoGlobalRsrc, fCommit = False) \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync is not True:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('ROLLBACK TO SAVEPOINT tryAsLeader');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.dprint('Failed to allocate global resources!');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oTestEx.cGangMembers <= 1:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # We're alone, put the task back at the end of the queue and issue EXEC cmd.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._moveTaskToEndOfQueue(oTask, oTestEx.cGangMembers, tsNow);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dResponse = self.composeExecResponseWorker(idTestSet, oTestEx, oTestBoxData, oBuild, oValidationKitBuild, sBaseUrl);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sTBState = TestBoxStatusData.ksTestBoxState_Testing;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # We're missing gang members, issue WAIT cmd.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._updateTask(oTask, tsNow if idTestSet == oTask.idTestSetGangLeader else None);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dResponse = { constants.tbresp.ALL_PARAM_RESULT: constants.tbresp.CMD_WAIT, };
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sTBState = TestBoxStatusData.ksTestBoxState_GangGathering;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync TestBoxStatusLogic(self._oDb).updateState(oTestBoxData.idTestBox, sTBState, idTestSet, fCommit = False);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('RELEASE SAVEPOINT tryAsLeader');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return dResponse;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def _tryAsGangMember(self, oTask, oTestEx, oTestBoxData, tsNow, sBaseUrl):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Try schedule the task as a gang member.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns response or None. May raise exception on DB error.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # The leader has choosen a build, we need to find a matching one for our platform.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # (It's up to the scheduler decide upon how strict dependencies are to be enforced
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # upon subordinate group members.)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oLeaderTestSet = TestSetData().initFromDbWithId(self._oDb, oTestBoxData.idTestSetGangLeader);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oLeaderBuild = BuildDataEx().initFromDbWithId(self._oDb, oLeaderTestSet.idBuild);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oBuild = self._tryFindMatchingBuild(oLeaderBuild, oTestBoxData, self._oSchedGrpData.idBuildSrc);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oBuild is None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oValidationKitBuild = None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oLeaderTestSet.idBuildTestSuite is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oLeaderValidationKitBit = BuildDataEx().initFromDbWithId(self._oDb, oLeaderTestSet.idBuildTestSuite);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oValidationKitBuild = self._tryFindMatchingBuild(oLeaderValidationKitBit, oTestBoxData,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oSchedGrpData.idBuildSrcTestSuite);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Create a testset and update the state(s).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync idTestSet = self._createTestSet(oTask, oTestEx, oTestBoxData, oBuild, oValidationKitBuild, tsNow);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTBStatusLogic = TestBoxStatusLogic(self._oDb);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oTask.cMissingGangMembers < 1:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # The whole gang is there, move the task to the end of the queue
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # and update the status on the other gang members.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._moveTaskToEndOfQueue(oTask, oTestEx.cGangMembers, tsNow);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dResponse = self.composeExecResponseWorker(idTestSet, oTestEx, oTestBoxData, oBuild, oValidationKitBuild, sBaseUrl);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sTBState = TestBoxStatusData.ksTestBoxState_GangTesting;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTBStatusLogic.updateGangStatus(oTask.idTestSetGangLeader, sTBState, fCommit = False);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # We're still missing some gang members, issue WAIT cmd.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._updateTask(oTask, tsNow if idTestSet == oTask.idTestSetGangLeader else None);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dResponse = { constants.tbresp.ALL_PARAM_RESULT: constants.tbresp.CMD_WAIT, };
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sTBState = TestBoxStatusData.ksTestBoxState_GangGathering;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTBStatusLogic.updateState(oTestBoxData.idTestBox, sTBState, idTestSet, fCommit = False);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return dResponse;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def scheduleNewTaskWorker(self, oTestBoxData, tsNow, sBaseUrl):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Worker for schduling a new task.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Iterate the scheduler queue (fetch all to avoid having to concurrent
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # queries), trying out each task to see if the testbox can execute it.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dRejected = {}; # variations we've already checked out and rejected.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self._oDb.execute('SELECT *\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'FROM SchedQueues\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE idSchedGroup = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' AND ( bmHourlySchedule IS NULL\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' OR get_bit(bmHourlySchedule, %s) = 1 )\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'ORDER BY idItem ASC\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , (self._oSchedGrpData.idSchedGroup, utils.getLocalHourOfWeek()) );
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync aaoRows = self._oDb.fetchAll();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync for aoRow in aaoRows:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Don't loop forever.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if self.getElapsedSecs() >= config.g_kcSecMaxNewTask:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync break;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Unpack the data and check if we've rejected the testcasevar/group variation already (they repeat).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTask = SchedQueueData().initFromDbRow(aoRow);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if config.g_kfSrvGlueDebugScheduler:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.dprint('** Considering: idItem=%s idGenTestCaseArgs=%s idTestGroup=%s Deps=%s last=%s cfg=%s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % ( oTask.idItem, oTask.idGenTestCaseArgs, oTask.idTestGroup, oTask.aidTestGroupPreReqs,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTask.tsLastScheduled, oTask.tsConfig,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sRejectNm = '%s:%s' % (oTask.idGenTestCaseArgs, oTask.idTestGroup,);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if sRejectNm in dRejected:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.dprint('Duplicate, already rejected! (%s)' % (sRejectNm,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync continue;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dRejected[sRejectNm] = 1;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Fetch all the test case info (too much, but who cares right now).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestEx = TestCaseArgsDataEx().initFromDbWithGenIdEx(self._oDb, oTask.idGenTestCaseArgs,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync tsConfigEff = oTask.tsConfig,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync tsRsrcEff = oTask.tsConfig);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if config.g_kfSrvGlueDebugScheduler:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.dprint('TestCase "%s": %s %s' % (oTestEx.oTestCase.sName, oTestEx.oTestCase.sBaseCmd, oTestEx.sArgs,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # This shouldn't happen, but just in case it does...
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oTestEx.oTestCase.fEnabled is not True:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.dprint('Testcase is not enabled!!');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync continue;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Check if the testbox properties matches the test.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if not oTestEx.matchesTestBoxProps(oTestBoxData):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.dprint('Testbox mismatch!');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync continue;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Try schedule it.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oTask.idTestSetGangLeader is None or oTestEx.cGangMembers <= 1:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dResponse = self._tryAsLeader(oTask, oTestEx, oTestBoxData, tsNow, sBaseUrl);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync elif oTask.cMissingGangMembers > 1:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dResponse = self._tryAsGangMember(oTask, oTestEx, oTestBoxData, tsNow, sBaseUrl);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync else:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dResponse = None; # Shouldn't happen!
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if dResponse is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.dprint('Found a task! dResponse=%s' % (dResponse,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return dResponse;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Found no suitable task.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync @staticmethod
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def scheduleNewTask(oDb, oTestBoxData, sBaseUrl, iVerbosity = 0):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Schedules a new task.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # To avoid concurrency issues in SchedQueues we lock all the rows
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # related to our scheduling queue. Also, since this is a very
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # expensive operation we lock the testbox status row to fend of
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # repeated retires by fault testbox script.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync tsSecStart = utils.timestampSecond();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oDb.rollback();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oDb.begin();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oDb.execute('SELECT idTestBox FROM TestBoxStatuses WHERE idTestBox = %s FOR UPDATE NOWAIT'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % (oTestBoxData.idTestBox,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oDb.execute('SELECT idSchedGroup FROM SchedQueues WHERE idSchedGroup = %s FOR UPDATE'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync % (oTestBoxData.idSchedGroup,));
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # We need the current timestamp.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync tsNow = oDb.getCurrentTimestamp();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Re-read the testbox data ...
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestBoxDataCur = TestBoxData().initFromDbWithId(oDb, oTestBoxData.idTestBox, tsNow);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oTestBoxDataCur.fEnabled \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and oTestBoxDataCur.idGenTestBox == oTestBoxData.idGenTestBox \
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and oTestBoxDataCur.idSchedGroup == oTestBoxData.idSchedGroup: # (paranoia wrt idSchedGroup)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # ... and schedule group data.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oSchedGrpData = SchedGroupData().initFromDbWithId(oDb, oTestBoxDataCur.idSchedGroup, tsNow);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oSchedGrpData.fEnabled and oSchedGrpData.idBuildSrc is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Instantiate the specified scheduler and let it do the rest.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oScheduler = SchedulerBase._instantiate(oDb, oSchedGrpData, iVerbosity, tsSecStart);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync dResponse = oScheduler.scheduleNewTaskWorker(oTestBoxDataCur, tsNow, sBaseUrl);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if dResponse is not None:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oDb.commit();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return dResponse;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oDb.rollback();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Not enabled, rollback and return no task.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oDb.rollback();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return None;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync @staticmethod
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def tryCancelGangGathering(oDb, oStatusData):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Try canceling a gang gathering.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns True if successfully cancelled.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Returns False if not (someone raced us to the SchedQueue table).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync Note! oStatusData is re-initialized.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync """
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync assert oStatusData.enmState == TestBoxStatusData.ksTestBoxState_GangGathering;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync try:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Lock the tables we're updating so we don't run into concurrency
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # issues (we're racing both scheduleNewTask and other callers of
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # this method).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oDb.rollback();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oDb.begin();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oDb.execute('LOCK TABLE TestBoxStatuses, SchedQueues IN EXCLUSIVE MODE');
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Re-read the testbox data and check that we're still in the same state.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oStatusData.initFromDbWithId(oDb, oStatusData.idTestBox);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync if oStatusData.enmState == TestBoxStatusData.ksTestBoxState_GangGathering:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Get the leader thru the test set and change the state of the whole gang.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestSetData = TestSetData().initFromDbWithId(oDb, oStatusData.idTestSet);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTBStatusLogic = TestBoxStatusLogic(oDb);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTBStatusLogic.updateGangStatus(oTestSetData.idTestSetGangLeader,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync TestBoxStatusData.ksTestBoxState_GangGatheringTimedOut,
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync fCommit = False);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Move the scheduling queue item to the end.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oDb.execute('SELECT *\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'FROM SchedQueues\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE idTestSetGangLeader = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , (oTestSetData.idTestSetGangLeader,) );
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTask = SchedQueueData().initFromDbRow(oDb.fetchOne());
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oTestEx = TestCaseArgsDataEx().initFromDbWithGenId(oDb, oTask.idGenTestCaseArgs);
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oDb.execute('UPDATE SchedQueues\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' SET idItem = NEXTVAL(\'SchedQueueItemIdSeq\'),\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' idTestSetGangLeader = NULL,\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ' cMissingGangMembers = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync 'WHERE idItem = %s\n'
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync , (oTestEx.cGangMembers, oTask.idItem,) );
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oDb.commit();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync elif oStatusData.enmState == TestBoxStatusData.ksTestBoxState_GangGatheringTimedOut:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oDb.rollback();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return True;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync except:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oDb.rollback();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync raise;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # Not enabled, rollback and return no task.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync oDb.rollback();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync return False;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync#
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# Unit testing.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync#
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync# pylint: disable=C0111
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncclass SchedQueueDataTestCase(ModelDataBaseTestCase):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync def setUp(self):
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync self.aoSamples = [SchedQueueData(),];
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncif __name__ == '__main__':
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync unittest.main();
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync # not reached.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync