def testJobTRSetLocalInput(databases): """Test that Task Runner restrictions do not override local inputs. Two Task Runners, one is allowed at the task level, local input is bound to the other task runner. """ gen = DataGenerator(databases) prodName = gen.createProduct('input1', True) fwName = gen.createFramework('testfw1', [prodName]) taskName = gen.createTask('task1', fwName) tr1Name = gen.createTaskRunner(capabilities=[fwName]) tr2Name = gen.createTaskRunner(capabilities=[fwName]) config = gen.createConfiguration() config._addInput({ 'name': prodName, 'locator': 'dummy', 'localAt': tr2Name }) config.getTask(taskName)._setRunners([tr1Name]) config._notify() # TODO: This is a hack to prevent 'sanityCheck' from reporting an error gen.inputsCreated = [prodName] def simulate(config): sanityCheck(gen, config) job, = config.createJobs(gen.owner) task = job.assignTask(databases.resourceDB[tr1Name]) assert task is None assert not job.isExecutionFinished() assert not job.hasFinalResult() runWithReload(databases, config, simulate)
def testJobResourceRemovedWhileRunning(databases): """Test what happens when a non-TR resource removed while in use. Unlike with a TR, this is not a reason to fail the task, since it may be possible for the task to complete successfully. For example, removal of the resource may simply be the resource management being moved outside of SoftFab. """ gen = DataGenerator(databases) resType = gen.createResourceType(pertask=True) fwName = gen.createFramework(name='testfw1', resources=[('ref1', resType, ())]) taskName = gen.createTask('task1', fwName) trName = gen.createTaskRunner(capabilities=[fwName]) config = gen.createConfiguration() resName = gen.createResource(resType) sanityCheck(gen, config) job, = config.createJobs(gen.owner) runner = databases.resourceDB[trName] resource = databases.resourceDB[resName] task = job.assignTask(runner) assert task is not None assert task.isRunning() assert resource.isReserved() databases.resourceDB.remove(resource) assert task.isRunning() assert task.result is None taskDone(job, taskName, ResultCode.OK) assert job.isExecutionFinished() assert job.hasFinalResult() assert job.result == ResultCode.OK assert job.getFinalResult() == ResultCode.OK
def testJobTRSetOverride(databases): """Test overriding Task Runner restrictions. Two Task Runners, one allowed at the job level and overridden at the task level. """ gen = DataGenerator(databases) fwName = gen.createFramework('testfw1') taskName = gen.createTask('task1', fwName) tr1Name = gen.createTaskRunner(capabilities=[fwName]) tr2Name = gen.createTaskRunner(capabilities=[fwName]) config = gen.createConfiguration() config._setRunners([tr1Name]) config.getTask(taskName)._setRunners([tr2Name]) config._notify() def simulate(config): sanityCheck(gen, config) job, = config.createJobs(gen.owner) task = job.assignTask(databases.resourceDB[tr1Name]) assert task is None assert not job.isExecutionFinished() assert not job.hasFinalResult() task = job.assignTask(databases.resourceDB[tr2Name]) assert task is not None taskDone(job, task.getName()) assert job.isExecutionFinished() assert job.hasFinalResult() runWithReload(databases, config, simulate)
def testResReqAssignNonExclusive(databases): """Test assigning task using a non-exclusive resource.""" def check(config): job, = config.createJobs(OWNER) taskRunner = databases.resourceDB[tr] # Try to assign with resource unavailable. reserveResource(databases.resourceDB, res) task = job.assignTask(taskRunner) assert task is None # Try to assign with resource available. freeResource(databases.resourceDB, res) task = job.assignTask(taskRunner) assert task is not None assert databases.resourceDB[res].isFree() job.taskDone('task', ResultCode.OK, 'summary text', (), {}) assert databases.resourceDB[res].isFree() gen = DataGenerator(databases) resType = gen.createResourceType() res = gen.createResource(resType, ()) tr = gen.createTaskRunner() fwSpecs = ( ('ref', resType, ()), (taskRunnerResourceRefName, taskRunnerResourceTypeName, ()), ) framework = gen.createFramework('fw', resources=fwSpecs) gen.createTask('task', framework, resources=()) config = gen.createConfiguration() runWithReload(databases, config, check)
def testResReqAssignCombinedDefs(databases): """Test whether simple resource requirements from both the framework and task definition are used in task assignment.""" def check(config): resourceDB = databases.resourceDB job, = config.createJobs(OWNER) taskRunner = resourceDB[tr] # Try to assign with both cap_a and cap_b unavailable. reserveResource(resourceDB, resA) reserveResource(resourceDB, resB) task = job.assignTask(taskRunner) assert task is None # Try to assign with only cap_a unavailable. freeResource(resourceDB, resB) task = job.assignTask(taskRunner) assert task is None # Try to assign with only cap_b unavailable. freeResource(resourceDB, resA) reserveResource(resourceDB, resB) task = job.assignTask(taskRunner) assert task is None # Try to assign with cap_a and cap_b available. freeResource(resourceDB, resB) task = job.assignTask(taskRunner) assert task is not None assert not resourceDB[resA].isFree() assert not resourceDB[resB].isFree() assert resourceDB[resC].isFree() job.taskDone('task', ResultCode.OK, 'summary text', (), {}) assert resourceDB[resA].isFree() assert resourceDB[resB].isFree() assert resourceDB[resC].isFree() gen = DataGenerator(databases) resType = gen.createResourceType(pertask=True) resA = gen.createResource(resType, ('cap_a', )) resB = gen.createResource(resType, ('cap_b', 'cap_d')) resC = gen.createResource(resType, ('cap_c', )) tr = gen.createTaskRunner() fwSpecs = ( ('ref1', resType, ('cap_a', )), (taskRunnerResourceRefName, taskRunnerResourceTypeName, ()), ) framework = gen.createFramework('fw', resources=fwSpecs) tdSpecs = (('ref2', resType, ('cap_b', )), ) gen.createTask('task', framework, resources=tdSpecs) config = gen.createConfiguration() runWithReload(databases, config, check)
def testJobTRRemovedWhileRunning(databases): """Test what happens when a busy Task Runner is removed.""" gen = DataGenerator(databases) fwName = gen.createFramework('testfw1') taskName = gen.createTask('task1', fwName) trName = gen.createTaskRunner(capabilities=[fwName]) config = gen.createConfiguration() sanityCheck(gen, config) job, = config.createJobs(gen.owner) runner = databases.resourceDB[trName] task = job.assignTask(runner) assert task is not None assert task.isRunning() databases.resourceDB.remove(runner) assert not task.isRunning() assert task.result == ResultCode.ERROR
def testJobTRSetNoCaps(databases): """Test that Task Runner restrictions do not override capabilities. One Task Runner, explicitly allowed both at the task and at the job level, but does not have required capability. """ gen = DataGenerator(databases) fwName = gen.createFramework('testfw1') taskName = gen.createTask('task1', fwName) tr1Name = gen.createTaskRunner(capabilities=['dummy']) config = gen.createConfiguration() config._setRunners([tr1Name]) config.getTask(taskName)._setRunners([tr1Name]) config._notify() def simulate(config): sanityCheck(gen, config) job, = config.createJobs(gen.owner) task = job.assignTask(databases.resourceDB[tr1Name]) assert task is None assert not job.isExecutionFinished() assert not job.hasFinalResult() runWithReload(databases, config, simulate)