def process_sync(self, root_task_result_promise, chain_args): try: wait_on_async_results(root_task_result_promise) chain_results, unsuccessful_services = get_results(root_task_result_promise, return_keys=('chain_results', 'unsuccessful_services')) self.check_for_failures(root_task_result_promise, unsuccessful_services) except ChainRevokedException as e: logger.error(e) if isinstance(e, ChainRevokedPreRunException): # Only in this case do we do the shutdown here; in the regular sync revoke case we do # the shutdown in root_task post_run signal, so that we have time to cleanup (cleanup code # may still run in a finally: clause even when result is marked ready and state == REVOKED) self.main_error_exit_handler(chain_details=(root_task_result_promise, chain_args), reason='Sync run: ChainRevokedException from root task') logger.debug('Root task revoked; cleanup will be done on root task completion') self.copy_submission_log() sys.exit(-1) except Exception as e: logger.debug(e, exc_info=True) self.main_error_exit_handler(chain_details=(root_task_result_promise, chain_args), reason=str(e)) rc = e.firex_returncode if isinstance(e, FireXReturnCodeException) else -1 sys.exit(rc) else: return chain_results
def test_wait_on_revoked_result(self): setup_revoke(["rev"]) test_app, mock_result = get_mocks(["rev"]) mock_result.state = PENDING with self.assertRaises(ChainRevokedException): wait_on_async_results(results=mock_result) unsuccessful = find_unsuccessful_in_chain(mock_result) self.assertDictEqual(unsuccessful, {'not_run': [mock_result]})
def test_wait_for_all_even_on_failure(self): setup_revoke() test_app, mock_results = get_mocks(["a0", "a1", "a2"]) with self.prime_mocks(mock_results, 2): # a0 and a2 should both be hit, but not a1 mock_results[1].state = FAILURE mock_results[1].results = OSError() with self.assertRaises(ChainInterruptedException): wait_on_async_results(results=mock_results)
def test_Chain_interrupted_from_exc(self): setup_revoke() test_app, mock_results = get_mocks(["a0", "a1"]) MockResult.set_heritage(mock_results[0], mock_results[1]) mock_results[0].state = SUCCESS mock_results[1].state = FAILURE mock_results[1].result = OSError() with self.assertRaises(ChainInterruptedException) as context: wait_on_async_results(results=mock_results[1]) self.assertTrue(isinstance(context.exception.__cause__, OSError))
def test_wait_on_revoked_chain(self): setup_revoke() test_app, mock_results = get_mocks(["a0", "a1", "a2"]) MockResult.set_heritage(mock_results[1], mock_results[2]) MockResult.set_heritage(mock_results[0], mock_results[1]) for i in range(3): # middle of the chain is revoked mock_results[0].state = SUCCESS mock_results[1].state = SUCCESS mock_results[2].state = STARTED mock_results[i].state = REVOKED with self.assertRaises(ChainRevokedException): wait_on_async_results(results=mock_results[2])
def test_multiple_failures(self): setup_revoke() test_app, mock_results = get_mocks(["a0", "a1", "a2", "a3"]) with self.prime_mocks(mock_results, 1): # a0 and a1 should both have failure mock_results[1].state = FAILURE mock_results[1].results = OSError() mock_results[2].state = PENDING mock_results[3].state = FAILURE mock_results[3].results = NotImplementedError() # make a1-a2 a chain, so a2 will not be hit MockResult.set_heritage(mock_results[1], mock_results[2]) mock_results.remove(mock_results[1]) with self.assertRaises(MultipleFailuresException) as multi_failure: self.assertIsNone(wait_on_async_results(results=mock_results)) multi_failure_exception = multi_failure.exception self.assertEqual(len(multi_failure_exception.failures), 2) self.assertTrue( isinstance(multi_failure_exception.failures[0], ChainInterruptedException)) self.assertTrue( isinstance(multi_failure_exception.failures[1], ChainInterruptedException))
def test_Chain_interrupted(self): setup_revoke() test_app, mock_results = get_mocks(["a0", "a1", "a2"]) MockResult.set_heritage(mock_results[1], mock_results[2]) MockResult.set_heritage(mock_results[0], mock_results[1]) mock_results[0].state = SUCCESS mock_results[1].state = FAILURE mock_results[2].state = PENDING with self.assertRaises(ChainInterruptedException) as context: wait_on_async_results(results=mock_results[2]) self.assertIsNone(context.exception.__cause__) unsuccessful = find_unsuccessful_in_chain(mock_results[-1]) self.assertDictEqual(unsuccessful, { 'not_run': [mock_results[2]], 'failed': [mock_results[1]] })
def test_wait_on_single_result(self): setup_revoke() test_app, mock_result = get_mocks() test_app.backend.set("anything", "yep".encode('utf-8')) mock_result.state = SUCCESS self.assertIsNone(wait_on_async_results(results=mock_result)) # wait then go def wait_and_go(): mock_result.state = SUCCESS return STARTED mock_result.state = wait_and_go try: self.assertIsNone(wait_on_async_results(results=mock_result)) finally: mock_result.backend = None
def test_wait_on_chain(self): setup_revoke() test_app, mock_results = get_mocks(["a0", "a1", "a2"]) MockResult.set_heritage(mock_results[1], mock_results[2]) MockResult.set_heritage(mock_results[0], mock_results[1]) with self.prime_mocks(mock_results, 3): self.assertIsNone(wait_on_async_results(results=mock_results[2])) unsuccessful = find_unsuccessful_in_chain(mock_results[-1]) self.assertDictEqual(unsuccessful, {})
def test_callbacks(self): setup_revoke() test_app, mock_result = get_mocks() mock_result.state = STARTED def call_this(): call_this.was_called += 1 if call_this.was_called == 5: mock_result.state = SUCCESS call_this.was_called = 0 callbacks = [ WaitLoopCallBack(func=call_this, frequency=0.2, kwargs={}) ] self.assertIsNone( wait_on_async_results(results=mock_result, callbacks=callbacks)) self.assertEqual(call_this.was_called, 5)
def test_timeout(self): setup_revoke() test_app, mock_result = get_mocks() mock_result.state = STARTED with self.assertRaises(WaitOnChainTimeoutError): wait_on_async_results(results=mock_result, max_wait=0.2)
def test_self_parent_recursion(self): setup_revoke() test_app, mock_result = get_mocks() MockResult.set_heritage(mock_result, mock_result) mock_result.state = SUCCESS self.assertIsNone(wait_on_async_results(results=mock_result))
def test_wait_on_many_results(self): setup_revoke() test_app, mock_results = get_mocks(["a1", "a2", "a3"]) with self.prime_mocks(mock_results, 3): self.assertIsNone(wait_on_async_results(results=mock_results))
def test_wait_on_nothing(self): # make sure the function returns, although in doesn't return anything self.assertIsNone(wait_on_async_results(results=None))