def test_revert_exception_is_reraised(self): flow = lf.Flow('revert-1').add( utils.NastyTask(), utils.FailingTask(name='fail') ) engine = self._make_engine(flow) self.assertFailuresRegexp(RuntimeError, '^Gotcha', engine.run)
def test_graph_flow_four_tasks_revert_failure(self): flow = gf.Flow('g-3-nasty').add( utils.NastyTask(name='task2', provides='b', requires=['a']), utils.FailingTask(name='task3', requires=['b']), utils.SaveOrderTask(name='task1', provides='a')) engine = self._make_engine(flow) self.assertFailuresRegexp(RuntimeError, '^Gotcha', engine.run) self.assertEqual(engine.storage.get_flow_state(), states.FAILURE)
def test_parallel_revert_exception_is_reraised(self): # NOTE(imelnikov): if we put NastyTask and FailingTask # into the same unordered flow, it is not guaranteed # that NastyTask execution would be attempted before # FailingTask fails. flow = lf.Flow('p-r-r-l').add( uf.Flow('p-r-r').add(utils.TaskNoRequiresNoReturns(name='task1'), utils.NastyTask()), utils.FailingTask()) engine = self._make_engine(flow) self.assertFailuresRegexp(RuntimeError, '^Gotcha', engine.run)
def test_requests_cache_match(self): cache = worker_types.RequestsCache() cache[self.task_uuid] = self.request() cache['task-uuid-2'] = self.request(task=utils.NastyTask(), uuid='task-uuid-2') worker = worker_types.TopicWorker("dummy-topic", [utils.DummyTask], identity="dummy") matches = cache.get_waiting_requests(worker) self.assertEqual(1, len(matches)) self.assertEqual(2, len(cache))
def test_parallel_revert_exception_is_reraised_(self): flow = lf.Flow('p-r-reraise').add( utils.SaveOrderTask(self.values, name='task1', sleep=0.01), utils.NastyTask(), utils.FailingTask(sleep=0.01), utils.SaveOrderTask(self.values, name='task2') # this should not get reverted ) engine = self._make_engine(flow) with self.assertRaisesRegexp(RuntimeError, '^Gotcha'): engine.run() result = set(self.values) self.assertEquals(result, set(['task1']))
def test_linear_nested_to_parallel_revert_exception(self): flow = uf.Flow('p-root').add( utils.SaveOrderTask(self.values, name='task1', sleep=0.01), utils.SaveOrderTask(self.values, name='task2', sleep=0.01), lf.Flow('l-inner').add( utils.SaveOrderTask(self.values, name='task3'), utils.NastyTask(), utils.FailingTask(sleep=0.01))) engine = self._make_engine(flow) with self.assertRaisesRegexp(RuntimeError, '^Gotcha'): engine.run() result = set(self.values) possible_result = set([ 'task1', 'task1 reverted(5)', 'task2', 'task2 reverted(5)', 'task3' ]) self.assertIsSubset(possible_result, result)
def test_states_retry_failure_linear_flow(self): flow = lf.Flow('flow-1', retry.Times(2, 'r1', provides='x')).add( utils.NastyTask("task1"), utils.ConditionalTask("task2")) engine = self._make_engine(flow) utils.register_notifiers(engine, self.values) engine.storage.inject({'y': 4}) self.assertRaisesRegexp(RuntimeError, '^Gotcha', engine.run) self.assertEqual(engine.storage.fetch_all(), {'y': 4, 'x': 1}) expected = [ 'flow RUNNING', 'r1 RUNNING', 'r1 SUCCESS', 'task1 RUNNING', 'task1 SUCCESS', 'task2 RUNNING', 'task2', 'task2 FAILURE', 'task2 REVERTING', u'task2 reverted(Failure: RuntimeError: Woot!)', 'task2 REVERTED', 'task1 REVERTING', 'task1 FAILURE', 'flow FAILURE' ] self.assertEqual(self.values, expected)
def test_states_retry_failure_linear_flow(self): flow = lf.Flow('flow-1', retry.Times(2, 'r1', provides='x')).add( utils.NastyTask("task1"), utils.ConditionalTask("task2")) engine = self._make_engine(flow) engine.storage.inject({'y': 4}) with utils.CaptureListener(engine) as capturer: self.assertRaisesRegexp(RuntimeError, '^Gotcha', engine.run) self.assertEqual(engine.storage.fetch_all(), {'y': 4, 'x': 1}) expected = [ 'flow-1.f RUNNING', 'r1.r RUNNING', 'r1.r SUCCESS(1)', 'task1.t RUNNING', 'task1.t SUCCESS(None)', 'task2.t RUNNING', 'task2.t FAILURE(Failure: RuntimeError: Woot!)', 'task2.t REVERTING', 'task2.t REVERTED', 'task1.t REVERTING', 'task1.t FAILURE', 'flow-1.f FAILURE' ] self.assertEqual(expected, capturer.values)
def test_nested_parallel_revert_exception_is_reraised(self): flow = uf.Flow('p-root').add( utils.SaveOrderTask(self.values, name='task1'), utils.SaveOrderTask(self.values, name='task2'), lf.Flow('p-inner').add( utils.SaveOrderTask(self.values, name='task3', sleep=0.1), utils.NastyTask(), utils.FailingTask(sleep=0.01))) engine = self._make_engine(flow) with self.assertRaisesRegexp(RuntimeError, '^Gotcha'): engine.run() result = set(self.values) # Task1, task2 may *not* have executed and also may have *not* reverted # since the above is an unordered flow so take that into account by # ensuring that the superset is matched. possible_result = set([ 'task1', 'task1 reverted(5)', 'task2', 'task2 reverted(5)', 'task3', 'task3 reverted(5)' ]) self.assertIsSubset(possible_result, result)
def test_parallel_revert_exception_do_not_revert_linear_tasks(self): flow = lf.Flow('l-root').add( utils.SaveOrderTask(self.values, name='task1'), utils.SaveOrderTask(self.values, name='task2'), uf.Flow('p-inner').add( utils.SaveOrderTask(self.values, name='task3', sleep=0.1), utils.NastyTask(), utils.FailingTask(sleep=0.01))) engine = self._make_engine(flow) # Depending on when (and if failing task) is executed the exception # raised could be either woot or gotcha since the above unordered # sub-flow does not guarantee that the ordering will be maintained, # even with sleeping. was_nasty = False try: engine.run() self.assertTrue(False) except RuntimeError as e: self.assertRegexpMatches(str(e), '^Gotcha|^Woot') if 'Gotcha!' in str(e): was_nasty = True result = set(self.values) possible_result = set(['task1', 'task2', 'task3', 'task3 reverted(5)']) if not was_nasty: possible_result.update(['task1 reverted(5)', 'task2 reverted(5)']) self.assertIsSubset(possible_result, result) # If the nasty task killed reverting, then task1 and task2 should not # have reverted, but if the failing task stopped execution then task1 # and task2 should have reverted. if was_nasty: must_not_have = ['task1 reverted(5)', 'task2 reverted(5)'] for r in must_not_have: self.assertNotIn(r, result) else: must_have = ['task1 reverted(5)', 'task2 reverted(5)'] for r in must_have: self.assertIn(r, result)