Beispiel #1
0
    def test_start_queued_jobs(self, mock_allocate, mock_dequeue):
        job_resources = [Resources(100, 1), Resources(200, 2)]
        mock_runnable_jobs = {make_mock_job(r): r for r in job_resources}
        mock_dequeue.return_value = mock_runnable_jobs
        pool_executor = Mock()
        mock_future = Mock()
        pool_executor.submit.return_value = mock_future
        mock_runtime_context = Mock(builder=Mock())
        result = self.executor.start_queued_jobs(pool_executor, self.logger,
                                                 mock_runtime_context)
        self.assertEqual(mock_dequeue.call_args,
                         call(self.executor.available_resources))

        # allocates resources
        self.assertEqual(mock_allocate.call_args_list, [
            call(job_resources[0], self.logger),
            call(job_resources[1], self.logger)
        ])
        # connects builder and output_dirs
        self.assertTrue(
            all([
                j.builder == mock_runtime_context.builder
                for j in mock_runnable_jobs
            ]))
        self.assertEqual(self.executor.output_dirs,
                         {j.outdir
                          for j in mock_runnable_jobs})

        # submits a future
        self.assertEqual(
            pool_executor.submit.call_args_list,
            [call(j.run, mock_runtime_context) for j in mock_runnable_jobs])
        # returns set of submitted futures
        self.assertIn(mock_future, result)
Beispiel #2
0
 def setUp(self):
     self.jrq = JobResourceQueue()
     r100_4 = Resources(100, 4)
     r200_2 = Resources(200, 2)
     self.job100_4 = make_mock_job(r100_4)  # 100 RAM, 2 cores
     self.job200_2 = make_mock_job(r200_2)  # 200 RAM, 4 cores
     self.jobs = {self.job100_4: r100_4, self.job200_2: r200_2}
Beispiel #3
0
 def test_allocate_too_much_raises(self):
     resource = Resources(10000, 1)
     self.assertTrue(resource.exceeds(self.executor.available_resources))
     self.assertEqual(self.executor.available_resources,
                      self.executor.total_resources)
     with self.assertRaisesRegex(InconsistentResourcesException,
                                 'Available resources are negative'):
         self.executor.allocate(resource, self.logger)
Beispiel #4
0
 def setUp(self):
     self.resource11 = Resources(1, 1)
     self.resource22 = Resources(2, 2)
     self.resource33 = Resources(3, 3)
     self.resource21 = Resources(2, 1)
     self.resource12 = Resources(1, 2)
     self.resource_neg = Resources(-1, 0)
Beispiel #5
0
 def test_dequeue_one_fits(self):
     limit = Resources(250, 3)
     self.queue_jobs()
     runnable = self.jrq.dequeue(limit)
     self.assertIn(self.job200_2, runnable)
     runnable = self.jrq.dequeue(limit)
     self.assertEqual(len(runnable), 0)
Beispiel #6
0
 def test_smallest_cores_first(self):
     self.jrq.priority = Resources.CORES
     self.jrq.descending = False
     limit = Resources(250, 5)
     self.queue_jobs()
     runnable = self.jrq.dequeue(limit)
     self.assertEqual(len(runnable), 1)
     self.assertIn(self.job200_2, runnable)
Beispiel #7
0
 def test_init(self):
     expected_resources = Resources(1000, 2)
     self.assertEqual(self.executor.total_resources, expected_resources)
     self.assertEqual(self.executor.available_resources, expected_resources)
     self.assertIsNone(self.executor.max_workers)
     self.assertIsNotNone(self.executor.jrq)
     self.assertIsNotNone(self.executor.exceptions)
     self.assertIsNotNone(self.executor.resources_lock)
Beispiel #8
0
 def test_pop_runnable_job_largest_ram_first(self):
     self.jrq.priority = Resources.RAM
     self.jrq.descending = True
     limit = Resources(250, 5)
     self.queue_jobs()
     runnable = self.jrq.dequeue(limit)
     self.assertEqual(len(runnable), 1)
     self.assertIn(self.job200_2, runnable)
Beispiel #9
0
 def test_dequeue_one_at_a_time(self):
     limit = Resources(250, 5)
     self.queue_jobs()
     runnable = self.jrq.dequeue(limit)
     self.assertEqual(len(runnable), 1)
     runnable = self.jrq.dequeue(limit)
     self.assertEqual(len(runnable), 1)
     runnable = self.jrq.dequeue(limit)
     self.assertEqual(len(runnable), 0)
Beispiel #10
0
 def setUp(self):
     super(ThreadPoolJobExecutorQueueingTestCase, self).setUp()
     self.jobs_simple = [
         make_mock_job(Resources(100, 1)),
         make_mock_job(Resources(200, 2)),
         make_mock_job(Resources(150, 3))
     ]
     self.jobs_with_none = [
         make_mock_job(Resources(100, 1)),
         make_mock_job(Resources(200, 2)), None,
         make_mock_job(Resources(150, 3))
     ]
     self.mock_pool_executor = create_autospec(ThreadPoolExecutor)
     self.mock_runtime_context = Mock(
         workflow_eval_lock=threading.Condition(threading.RLock()))
Beispiel #11
0
 def test_eq(self):
     other = Resources(1, 1)
     self.assertEqual(self.resource11, other)
Beispiel #12
0
 def test_dequeue_none_fit_cores_too_small(self):
     limit = Resources(1000, 1)
     self.queue_jobs()
     runnable = self.jrq.dequeue(limit)
     self.assertEqual(len(runnable), 0)
Beispiel #13
0
 def test_job_done_callback_catches_restore_exception(self, mock_restore):
     exception = InconsistentResourcesException('inconsistent resources')
     mock_restore.side_effect = exception
     self.executor.job_done_callback(Resources(1, 1), self.logger, Mock())
     self.assertEqual(exception, self.executor.exceptions.get())
Beispiel #14
0
 def test_raise_if_oversized_does_nothing(self):
     rsc = Resources(100, 1)
     self.assertFalse(rsc.exceeds(self.executor.total_resources))
     job = make_mock_job(rsc)
     self.executor.raise_if_oversized(job)
Beispiel #15
0
 def test_raise_if_oversized_raises_with_oversized(self):
     rsc = Resources(100, 4)
     self.assertTrue(rsc.exceeds(self.executor.total_resources))
     job = make_mock_job(rsc)
     with self.assertRaisesRegex(OversizedJobException, 'exceed total'):
         self.executor.raise_if_oversized(job)
Beispiel #16
0
 def test_restore_only_cores_over_total_raises(self):
     with self.assertRaisesRegex(InconsistentResourcesException,
                                 'Available resources exceeds total'):
         self.executor.restore(Resources(0, 1), self.logger)
Beispiel #17
0
 def test_restore_over_total_raises(self):
     self.assertEqual(self.executor.available_resources,
                      self.executor.total_resources)
     with self.assertRaisesRegex(InconsistentResourcesException,
                                 'Available resources exceeds total'):
         self.executor.restore(Resources(200, 1), self.logger)
Beispiel #18
0
 def test_dequeue_all_fit(self):
     limit = Resources(1000, 10)
     self.queue_jobs()
     runnable = self.jrq.dequeue(limit)
     self.assertEqual(runnable, self.jobs)
Beispiel #19
0
 def test_from_dict(self):
     result = Resources.from_dict({'cores': 3, 'ram': 400})
     self.assertEqual(result.cores, 3)
     self.assertEqual(result.ram, 400)
Beispiel #20
0
 def test_from_job(self):
     mock_job = make_mock_job(Resources(4, 2))
     result = Resources.from_job(mock_job)
     self.assertEqual(result.ram, 4)
     self.assertEqual(result.cores, 2)
Beispiel #21
0
 def test_is_empty(self):
     self.assertTrue(self.jrq.is_empty())
     self.queue_jobs()
     self.assertFalse(self.jrq.is_empty())
     self.jrq.dequeue(Resources(300, 6))
     self.assertTrue(self.jrq.is_empty())
Beispiel #22
0
 def test_pop_runnable_exact_fit(self):
     limit = Resources(300, 6)
     self.queue_jobs()
     runnable = self.jrq.dequeue(limit)
     self.assertEqual(runnable, self.jobs)
Beispiel #23
0
class ResourcesTestCase(TestCase):
    def setUp(self):
        self.resource11 = Resources(1, 1)
        self.resource22 = Resources(2, 2)
        self.resource33 = Resources(3, 3)
        self.resource21 = Resources(2, 1)
        self.resource12 = Resources(1, 2)
        self.resource_neg = Resources(-1, 0)

    def test_init(self):
        self.assertEqual(self.resource11.cores, 1)
        self.assertEqual(self.resource11.ram, 1)
        self.assertEqual(self.resource22.cores, 2)
        self.assertEqual(self.resource22.ram, 2)
        self.assertEqual(self.resource33.cores, 3)
        self.assertEqual(self.resource33.ram, 3)
        self.assertEqual(self.resource21.cores, 1)
        self.assertEqual(self.resource21.ram, 2)

    def test_subtraction(self):
        result = self.resource33 - self.resource21
        self.assertEqual(result.ram, 1)
        self.assertEqual(result.cores, 2)

    def test_addition(self):
        result = self.resource11 + self.resource22
        self.assertEqual(result.ram, 3)
        self.assertEqual(result.cores, 3)

    def test_neg(self):
        result = -self.resource11
        self.assertEqual(result.ram, -1)
        self.assertEqual(result.cores, -1)

    def test_lt(self):
        self.assertTrue(self.resource11 < self.resource22)
        self.assertTrue(self.resource21 < self.resource33)
        self.assertFalse(self.resource11 < self.resource21)

    def test_gt(self):
        self.assertTrue(self.resource22 > self.resource11)
        self.assertTrue(self.resource33 > self.resource21)
        self.assertFalse(self.resource21 > self.resource11)

    def test_ge(self):
        self.assertTrue(self.resource21 >= self.resource11)
        self.assertFalse(self.resource22 >= self.resource33)

    def test_le(self):
        self.assertTrue(self.resource11 <= self.resource21)
        self.assertFalse(self.resource33 <= self.resource22)

    def test_eq(self):
        other = Resources(1, 1)
        self.assertEqual(self.resource11, other)

    def test_from_job(self):
        mock_job = make_mock_job(Resources(4, 2))
        result = Resources.from_job(mock_job)
        self.assertEqual(result.ram, 4)
        self.assertEqual(result.cores, 2)

    def test_from_job_defaults_empty_without_builder(self):
        mock_job = make_mock_job(Resources(4, 2))
        del mock_job.builder
        result = Resources.from_job(mock_job)
        self.assertEqual(result.ram, 0)
        self.assertEqual(result.cores, 0)

    def test_from_dict(self):
        result = Resources.from_dict({'cores': 3, 'ram': 400})
        self.assertEqual(result.cores, 3)
        self.assertEqual(result.ram, 400)

    def test_min(self):
        result = Resources.min(self.resource21, self.resource12)
        self.assertEqual(result, self.resource11)

    def test_is_negative(self):
        self.assertFalse(self.resource11.is_negative())
        self.assertTrue(self.resource_neg.is_negative())

    def test_exceeds(self):
        self.assertTrue(self.resource21.exceeds(self.resource11))
        self.assertFalse(self.resource11.exceeds(self.resource21))
        self.assertFalse(self.resource21.exceeds(self.resource21))

    def test_empty(self):
        self.assertEqual(Resources.EMPTY.ram, 0)
        self.assertEqual(Resources.EMPTY.cores, 0)
Beispiel #24
0
 def test_from_job_defaults_empty_without_builder(self):
     mock_job = make_mock_job(Resources(4, 2))
     del mock_job.builder
     result = Resources.from_job(mock_job)
     self.assertEqual(result.ram, 0)
     self.assertEqual(result.cores, 0)
Beispiel #25
0
 def test_allocate(self):
     resource = Resources(200, 1)
     self.executor.allocate(resource, self.logger)
     self.assertEqual(self.executor.available_resources, Resources(800, 1))
Beispiel #26
0
 def test_min(self):
     result = Resources.min(self.resource21, self.resource12)
     self.assertEqual(result, self.resource11)
Beispiel #27
0
 def test_restore(self):
     resource = Resources(200, 1)
     self.executor.available_resources = Resources(800, 1)
     self.executor.restore(resource, self.logger)
     self.assertEqual(self.executor.available_resources,
                      self.executor.total_resources)