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_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_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_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_JobResourcesInitCoresByStruct3(self):
        jr = JobResources(ResourceSize(min=1, max=3), ResourceSize(3))

        self.assertIsNone(jr.numCores.exact)
        self.assertEqual(jr.numCores.min, 1)
        self.assertEqual(jr.numCores.max, 3)
        self.assertIsNone(jr.numNodes.min)
        self.assertIsNone(jr.numNodes.max)
        self.assertEqual(jr.numNodes.exact, 3)
    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_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 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_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 __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_JobResourcesInitCoresByStructValid(self):
     try:
         jr = JobResources(ResourceSize(exact=1, min=2))
         self.fail("Non proper initialization passed")
     except Exception as e:
         pass
    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)