def test_NodesRangeMax(self): res = self.createLocalResources() sched = Scheduler(res) try: min_nodes = self.__nnodes + 1 max_nodes = min_nodes + 2 jobRes = JobResources( numNodes=ResourceSize(min=min_nodes, max=max_nodes)) allocation = sched.allocateJob(jobRes) self.fail("Allocation created with wrong resource requirements") except NotSufficientResources: pass except Exception: self.fail("Wrong exception") min_nodes = 1 max_nodes = 6 jobRes = JobResources( numNodes=ResourceSize(min=min_nodes, max=max_nodes)) allocation = sched.allocateJob(jobRes) self.assertIsNotNone(allocation) self.assertTrue(len(allocation.nodeAllocations) == self.__nnodes) self.assertEqual(res.usedCores, self.__ncores) self.assertEqual(res.freeCores, 0) min_nodes = 1 max_nodes = 6 jobRes = JobResources( numNodes=ResourceSize(min=min_nodes, max=max_nodes)) allocation = sched.allocateJob(jobRes) self.assertIsNone(allocation)
def test_CoresExact(self): res = self.createLocalResources() cores = 2 sched = Scheduler(res) jobRes = JobResources(numCores=ResourceSize(exact=cores)) allocation = sched.allocateJob(jobRes) self.assertIsNotNone(allocation) self.assertEqual(allocation.cores, cores) self.assertEqual(res.usedCores, cores) self.assertEqual(res.freeCores, self.__ncores - cores) sched.releaseAllocation(allocation) cores = 6 jobRes = JobResources(numCores=ResourceSize(exact=cores)) allocation = sched.allocateJob(jobRes) self.assertIsNotNone(allocation) self.assertEqual(allocation.cores, cores) self.assertEqual(res.usedCores, cores) self.assertEqual(res.freeCores, self.__ncores - cores) self.assertTrue(len(allocation.nodeAllocations) == 3) sched.releaseAllocation(allocation)
def test_NodesRangeInvalid(self): res = self.createLocalResources() sched = Scheduler(res) try: min_nodes = 1 jobRes = JobResources(numNodes=ResourceSize(min=min_nodes)) allocation1 = sched.allocateJob(jobRes) self.fail("Allocation created with wrong resource requirements") except InvalidResourceSpec: self.assertEqual(res.usedCores, 0) self.assertEqual(res.freeCores, self.__ncores) except Exception: self.fail("Wrong exception") try: max_nodes = 1 jobRes = JobResources(numNodes=ResourceSize(max=max_nodes)) allocation1 = sched.allocateJob(jobRes) self.fail("Allocation created with wrong resource requirements") except InvalidResourceSpec: self.assertEqual(res.usedCores, 0) self.assertEqual(res.freeCores, self.__ncores) except Exception: self.fail("Wrong exception")
def test_JobListInit(self): jl = JobList() try: jl.add('job1') self.fail("Invalid object added to job list") except AssertionError: pass jName1 = 'job1' j1 = Job(jName1, JobExecution('/bin/date'), JobResources(numCores=2)) jl.add(j1) self.assertTrue(jl.get(jName1) is not None) self.assertTrue(jl.exist(jName1)) try: jl.add(j1) self.fail('Non-uniqe job added to job list') except JobAlreadyExist: pass self.assertTrue(jl.get(jName1) is not None) self.assertTrue(jl.exist(jName1)) jName2 = 'job2' jl.add(Job('job2', JobExecution('/bin/date'), JobResources(numCores=1))) self.assertTrue(jl.get(jName2) is not None) self.assertTrue(jl.exist(jName2))
def test_CoresRange(self): res = self.createLocalResources() minCores = 2 maxCores = 4 used = 0 sched = Scheduler(res) jobRes = JobResources( numCores=ResourceSize(min=minCores, max=maxCores)) allocation = sched.allocateJob(jobRes) self.assertIsNotNone(allocation) self.assertEqual(allocation.cores, maxCores) used += maxCores self.assertEqual(res.usedCores, used) self.assertEqual(res.freeCores, self.__ncores - used) self.assertTrue(len(allocation.nodeAllocations) == 2) minCores = 2 maxCores = 3 jobRes = JobResources( numCores=ResourceSize(min=minCores, max=maxCores)) allocation = sched.allocateJob(jobRes) self.assertEqual(allocation.cores, maxCores) used += maxCores self.assertEqual(res.usedCores, used) self.assertEqual(res.freeCores, self.__ncores - used) self.assertTrue(len(allocation.nodeAllocations) == 1) minCores = 1 maxCores = 3 jobRes = JobResources( numCores=ResourceSize(min=minCores, max=maxCores)) allocation = sched.allocateJob(jobRes) self.assertIsNotNone(allocation) self.assertEqual(allocation.cores, minCores) used += minCores self.assertEqual(res.usedCores, used) self.assertEqual(res.freeCores, self.__ncores - used) self.assertTrue(len(allocation.nodeAllocations) == 1) minCores = 1 maxCores = 3 jobRes = JobResources( numCores=ResourceSize(min=minCores, max=maxCores)) allocation = sched.allocateJob(jobRes) self.assertIsNone(allocation)
def test_JobResourcesWT(self): jr = JobResources(numCores=1, wt="5s") self.assertEqual(jr.wt.total_seconds(), 5) jr = JobResources(numCores=1, wt="2h5s") self.assertEqual(jr.wt.total_seconds(), timedelta(hours=2, seconds=5).total_seconds()) jr = JobResources(numCores=1, wt="122h90m5s") self.assertEqual( jr.wt.total_seconds(), timedelta(hours=122, minutes=90, seconds=5).total_seconds())
def test_JobResourcesInitCoresByStruct2(self): jr = JobResources(ResourceSize(min=1, max=3)) self.assertIsNone(jr.numCores.exact) self.assertEqual(jr.numCores.min, 1) self.assertEqual(jr.numCores.max, 3) self.assertIsNone(jr.numNodes)
def test_JobResourcesInitCoresByStruct(self): jr = JobResources(ResourceSize(1)) self.assertEqual(jr.numCores.exact, 1) self.assertIsNone(jr.numCores.min) self.assertIsNone(jr.numCores.max) self.assertIsNone(jr.numNodes)
def test_JobVars(self): res = self.createLocalResources() manager = Manager(res, self.config) scriptFile = join(self.testSandbox, 'script.sh') if exists(scriptFile): os.remove(scriptFile) with open(scriptFile, 'w') as f: f.write(''' #!/bin/env bash echo "*** environment ***" env ''') os.chmod(scriptFile, stat.S_IXUSR | stat.S_IRUSR | stat.S_IWUSR) jobs = [ Job( 'job1', JobExecution( 'bash', args=[scriptFile], wd='${root_wd}/job1', stdout='${nnodes}.${ncores}-${jname}.stdout', stderr='${nnodes}.${ncores}-${jname}.stderr', ), JobResources(numNodes=ResourceSize(1), numCores=ResourceSize(2))) ] startTime = datetime.datetime.now() asyncio.get_event_loop().run_until_complete( asyncio.gather(self.__schedule(jobs, manager))) asyncio.get_event_loop().close() duration = datetime.datetime.now() - startTime self.assertTrue(duration.total_seconds() > 0 and duration.total_seconds() < 4) job1_wd = join(self.testSandbox, 'job1') self.assertTrue(os.path.exists(job1_wd)) self.assertTrue( os.path.exists(os.path.join(job1_wd, '1.2-job1.stdout'))) self.assertTrue( os.path.exists(os.path.join(job1_wd, '1.2-job1.stderr'))) stderrStat = os.stat(os.path.join(job1_wd, '1.2-job1.stderr')) self.assertTrue(stderrStat.st_size == 0) with open(os.path.join(job1_wd, '1.2-job1.stdout'), 'r', 1) as file, \ mmap.mmap(file.fileno(), 0, prot=mmap.PROT_READ) as s: self.assertTrue(s.find('QCG_PM_NTASKS=2'.encode('UTF-8')) != -1) self.assertTrue( s.find('QCG_PM_TASKS_PER_NODE=2'.encode('UTF-8')) != -1) self.assertTrue(s.find('QCG_PM_NNODES=1'.encode('UTF-8')) != -1) self.assertTrue(s.find('QCG_PM_NPROCS=2'.encode('UTF-8')) != -1)
def test_NodesRangeEqual(self): res = self.createLocalResources() sched = Scheduler(res) min_nodes = 1 max_nodes = 1 jobRes = JobResources( numNodes=ResourceSize(min=min_nodes, max=max_nodes)) allocation1 = sched.allocateJob(jobRes) self.assertIsNotNone(allocation1) self.assertTrue(len(allocation1.nodeAllocations) == 1) self.assertEqual(res.usedCores, 2) min_nodes = 1 max_nodes = 1 jobRes = JobResources( numNodes=ResourceSize(min=min_nodes, max=max_nodes)) allocation2 = sched.allocateJob(jobRes) self.assertIsNotNone(allocation2) self.assertTrue(len(allocation2.nodeAllocations) == 1) self.assertEqual(res.usedCores, 4) sched.releaseAllocation(allocation1) sched.releaseAllocation(allocation2) min_nodes = 3 max_nodes = 3 jobRes = JobResources( numNodes=ResourceSize(min=min_nodes, max=max_nodes)) allocation3 = sched.allocateJob(jobRes) self.assertIsNotNone(allocation3) self.assertTrue(len(allocation3.nodeAllocations) == 3) sched.releaseAllocation(allocation3) try: min_nodes = 4 max_nodes = 4 jobRes = JobResources( numNodes=ResourceSize(min=min_nodes, max=max_nodes)) allocation4 = sched.allocateJob(jobRes) except NotSufficientResources: self.assertEqual(res.usedCores, 0) self.assertEqual(res.freeCores, self.__ncores) except Exception: self.fail("Wrong exception")
def test_NodesRange(self): res = self.createLocalResources() sched = Scheduler(res) min_nodes = 1 max_nodes = 2 jobRes = JobResources( numNodes=ResourceSize(min=min_nodes, max=max_nodes)) allocation = sched.allocateJob(jobRes) self.assertIsNotNone(allocation) self.assertTrue(len(allocation.nodeAllocations) == 2) min_nodes = 1 max_nodes = 2 jobRes = JobResources( numNodes=ResourceSize(min=min_nodes, max=max_nodes)) allocation = sched.allocateJob(jobRes) self.assertIsNotNone(allocation) self.assertTrue(len(allocation.nodeAllocations) == 1)
def test_NodesSimple(self): res = self.createLocalResources() nnodes = 2 sched = Scheduler(res) jobRes = JobResources(numNodes=ResourceSize(nnodes)) allocation = sched.allocateJob(jobRes) self.assertIsNotNone(allocation) self.assertTrue(len(allocation.nodeAllocations) == 2)
def test_JobResourcesImportExportEquality(self): jr = JobResources(numNodes=ResourceSize(max=2, min=1)) jr_json = jr.toJSON() jr_copy = JobResources(**json.loads(jr_json)) jr_json2 = jr_copy.toJSON() self.assertEqual(jr_json, jr_json2)
def __setupJobs(self): self.jobs = [ Job( 'msleep1', JobExecution( '/usr/bin/sleep', args=['5s'], wd=abspath(join(self.testSandbox, 'sleep1.sandbox')), stdout='sleep1.stdout', stderr='sleep1.stderr', ), JobResources(numCores=ResourceSize(2))), Job( 'msleep2', JobExecution( '/usr/bin/sleep', args=['5s'], wd=abspath(join(self.testSandbox, 'sleep2.sandbox')), stdout='sleep2.stdout', stderr='sleep2.stderr', ), JobResources(numCores=ResourceSize(2))), Job( 'mscript', JobExecution( '/usr/bin/bash', args=[self.scriptFile], wd=abspath(join(self.testSandbox, 'script.sandbox')), stdout='script.stdout', stderr='script.stderr', ), JobResources(numCores=ResourceSize(2))), Job( 'msleep3', JobExecution( '/usr/bin/sleep', args=['5s'], wd=abspath(join(self.testSandbox, 'sleep3.sandbox')), stdout='sleep3.stdout', stderr='sleep3.stderr', ), JobResources(numCores=ResourceSize(1))) ]
def test_JobResourcesImportFromJSONDefault(self): jr_json = """{ "numCores": { "exact": 1 }, "numNodes": { "exact": 2 } }""" jr = JobResources(**json.loads(jr_json)) self.assertEqual(jr.numCores.exact, 1) self.assertIsNone(jr.numCores.min) self.assertIsNone(jr.numCores.max) self.assertEqual(jr.numNodes.exact, 2) self.assertIsNone(jr.numNodes.max) self.assertIsNone(jr.numNodes.min)
def test_JobInitAndJson(self): jName = 'job1' j = Job(jName, JobExecution('/bin/date'), JobResources(numCores=2)) self.assertIsNotNone(j) self.assertIsNotNone(j.execution) self.assertEqual(j.name, jName) self.assertEqual(j.state, JobState.QUEUED) self.assertEqual(len(j.history), 1) self.assertEqual(j.hasDependencies(), False) j.state = JobState.EXECUTING self.assertEqual(j.state, JobState.EXECUTING) self.assertEqual(len(j.history), 2) j_json = j.toJSON() j_copy = Job(**json.loads(j_json)) self.assertIsNotNone(j_copy) j_json2 = j_copy.toJSON() self.assertEqual(j_json, j_json2) self.compareJobs(j, j_copy)
def test_ExecutorSimple(self): res = self.createLocalResources() manager = Manager(res) testSandbox = 'test-sandbox' if exists(testSandbox): shutil.rmtree(testSandbox) os.makedirs(testSandbox) for dir in [ 'hostname.sandbox', 'env.sandbox', 'sleep.sandbox', 'script.sandbox' ]: dPath = join(testSandbox, dir) if exists(dPath): shutil.rmtree(dPath) scriptFile = abspath(join(testSandbox, 'script.sh')) if exists(scriptFile): os.remove(scriptFile) with open(scriptFile, 'w') as f: f.write(''' #!/bin/bash echo "*** environment ***" env echo "*** info ***" echo "host: `hostname --fqdn`" echo "cwd: `pwd`" echo "date: `date`" echo "account: `id`" echo "taskset: `taskset -p $$`" ''') hostnameStdinFile = abspath(join(testSandbox, 'hostname.stdin')) if exists(hostnameStdinFile): os.remove(hostnameStdinFile) with open(hostnameStdinFile, 'w') as f: f.write('some host name') jobs = [ Job( 'job1', JobExecution( '/usr/bin/wc', args=['-m'], wd=abspath(join(testSandbox, 'hostname.sandbox')), stdin=hostnameStdinFile, stdout='hostname.stdout', stderr='hostname.stderr', ), JobResources(numCores=ResourceSize(2))), Job( 'job2', JobExecution( '/usr/bin/env', wd=abspath(join(testSandbox, 'env.sandbox')), stdout='env.stdout', stderr='env.stderr', ), JobResources(numCores=ResourceSize(1))), Job( 'sleep', JobExecution( '/usr/bin/sleep', args=['2s'], wd=abspath(join(testSandbox, 'sleep.sandbox')), stdout='sleep.stdout', stderr='sleep.stderr', ), JobResources(numCores=ResourceSize(1))), Job( 'script', JobExecution( '/usr/bin/bash', args=[scriptFile], wd=abspath(join(testSandbox, 'script.sandbox')), stdout='script.stdout', stderr='script.stderr', ), JobResources(numCores=ResourceSize(1))) ] startTime = datetime.datetime.now() asyncio.get_event_loop().run_until_complete( asyncio.gather(self.__schedule(jobs, manager))) asyncio.get_event_loop().close() duration = datetime.datetime.now() - startTime self.assertTrue(duration.total_seconds() > 2 and duration.total_seconds() < 6) for job in jobs: self.assertTrue(os.path.exists(job.execution.wd)) self.assertTrue( os.path.exists( os.path.join(job.execution.wd, job.execution.stdout))) self.assertTrue( os.path.exists( os.path.join(job.execution.wd, job.execution.stderr))) stderrStat = os.stat( os.path.join(job.execution.wd, job.execution.stderr)) self.assertTrue(stderrStat.st_size == 0)
def test_JobResourcesInitCoresByStructValid(self): try: jr = JobResources(ResourceSize(exact=1, min=2)) self.fail("Non proper initialization passed") except Exception as e: pass
def test_JobResourcesInitNodes(self): jr = JobResources(numNodes=2) self.assertEqual(jr.numNodes.exact, 2) self.assertIsNone(jr.numCores)