def test_suspend_and_revert_even_if_task_is_gone(self): flow = lf.Flow('linear').add(utils.ProgressingTask('a'), utils.ProgressingTask('b'), utils.FailingTask('c')) engine = self._make_engine(flow) with SuspendingListener(engine, task_name='b', task_state=states.REVERTED) as capturer: engine.run() expected = [ 'a.t RUNNING', 'a.t SUCCESS(5)', 'b.t RUNNING', 'b.t SUCCESS(5)', 'c.t RUNNING', 'c.t FAILURE(Failure: RuntimeError: Woot!)', 'c.t REVERTING', 'c.t REVERTED(None)', 'b.t REVERTING', 'b.t REVERTED(None)' ] self.assertEqual(expected, capturer.values) # pretend we are resuming, but task 'c' gone when flow got updated flow2 = lf.Flow('linear').add( utils.ProgressingTask('a'), utils.ProgressingTask('b'), ) engine2 = self._make_engine(flow2, engine.storage._flowdetail) with utils.CaptureListener(engine2, capture_flow=False) as capturer2: self.assertRaisesRegex(RuntimeError, '^Woot', engine2.run) self.assertEqual(states.REVERTED, engine2.storage.get_flow_state()) expected = ['a.t REVERTING', 'a.t REVERTED(None)'] self.assertEqual(expected, capturer2.values)
def test_invalid_decider_depth(self): g_1 = utils.ProgressingTask(name='g-1') g_2 = utils.ProgressingTask(name='g-2') for not_a_depth in ['not-a-depth', object(), 2, 3.4, False]: flow = gf.Flow('g') flow.add(g_1, g_2) self.assertRaises((ValueError, TypeError), flow.link, g_1, g_2, decider=lambda history: False, decider_depth=not_a_depth)
def test_storage_is_rechecked(self): flow = lf.Flow('linear').add( utils.ProgressingTask('b', requires=['foo']), utils.ProgressingTask('c')) engine = self._make_engine(flow) engine.storage.inject({'foo': 'bar'}) with SuspendingListener(engine, task_name='b', task_state=states.SUCCESS): engine.run() self.assertEqual(states.SUSPENDED, engine.storage.get_flow_state()) # uninject everything: engine.storage.save(engine.storage.injector_name, {}, states.SUCCESS) self.assertRaises(exc.MissingDependencies, engine.run)
def test_on_update_progress(self): request = self.make_request(task=utils.ProgressingTask(), arguments={}) # create server and process request s = self.server(reset_master_mock=True) s._process_request(request, self.message_mock) # check calls master_mock_calls = [ mock.call.Response(pr.RUNNING), mock.call.proxy.publish(self.response_inst_mock, self.reply_to, correlation_id=self.task_uuid), mock.call.Response(pr.EVENT, details={'progress': 0.0}, event_type=task_atom.EVENT_UPDATE_PROGRESS), mock.call.proxy.publish(self.response_inst_mock, self.reply_to, correlation_id=self.task_uuid), mock.call.Response(pr.EVENT, details={'progress': 1.0}, event_type=task_atom.EVENT_UPDATE_PROGRESS), mock.call.proxy.publish(self.response_inst_mock, self.reply_to, correlation_id=self.task_uuid), mock.call.Response(pr.SUCCESS, result=5), mock.call.proxy.publish(self.response_inst_mock, self.reply_to, correlation_id=self.task_uuid) ] self.master_mock.assert_has_calls(master_mock_calls)
def test_basic_do_not_capture(self): flow = lf.Flow("test") flow.add(test_utils.ProgressingTask("task1")) e = self._make_engine(flow) with test_utils.CaptureListener(e, capture_task=False) as capturer: e.run() expected = ['test.f RUNNING', 'test.f SUCCESS'] self.assertEqual(expected, capturer.values)
def test_on_run_reply_failure(self): request = self.make_request(task=utils.ProgressingTask(), arguments={}) self.proxy_inst_mock.publish.side_effect = RuntimeError('Woot!') # create server and process request s = self.server(reset_master_mock=True) s._process_request(request, self.message_mock) self.assertEqual(1, self.proxy_inst_mock.publish.call_count)
def test_suspend_linear_flow(self): flow = lf.Flow('linear').add(utils.ProgressingTask('a'), utils.ProgressingTask('b'), utils.ProgressingTask('c')) engine = self._make_engine(flow) with SuspendingListener(engine, task_name='b', task_state=states.SUCCESS) as capturer: engine.run() self.assertEqual(states.SUSPENDED, engine.storage.get_flow_state()) expected = [ 'a.t RUNNING', 'a.t SUCCESS(5)', 'b.t RUNNING', 'b.t SUCCESS(5)' ] self.assertEqual(expected, capturer.values) with utils.CaptureListener(engine, capture_flow=False) as capturer: engine.run() self.assertEqual(states.SUCCESS, engine.storage.get_flow_state()) expected = ['c.t RUNNING', 'c.t SUCCESS(5)'] self.assertEqual(expected, capturer.values)
def test_inject_persistent_missing(self): t = test_utils.ProgressingTask('my retry', requires=['x']) s = self._get_storage() s.ensure_atom(t) missing = s.fetch_unsatisfied_args(t.name, t.rebind) self.assertEqual(set(['x']), missing) s.inject_atom_args(t.name, {'x': 2}, transient=False) missing = s.fetch_unsatisfied_args(t.name, t.rebind) self.assertEqual(set(), missing) args = s.fetch_mapped_args(t.rebind, atom_name=t.name) self.assertEqual(2, args['x'])
def test_suspend_linear_flow_on_revert(self): flow = lf.Flow('linear').add(utils.ProgressingTask('a'), utils.ProgressingTask('b'), utils.FailingTask('c')) engine = self._make_engine(flow) with SuspendingListener(engine, task_name='b', task_state=states.REVERTED) as capturer: engine.run() self.assertEqual(states.SUSPENDED, engine.storage.get_flow_state()) expected = [ 'a.t RUNNING', 'a.t SUCCESS(5)', 'b.t RUNNING', 'b.t SUCCESS(5)', 'c.t RUNNING', 'c.t FAILURE(Failure: RuntimeError: Woot!)', 'c.t REVERTING', 'c.t REVERTED(None)', 'b.t REVERTING', 'b.t REVERTED(None)' ] self.assertEqual(expected, capturer.values) with utils.CaptureListener(engine, capture_flow=False) as capturer: self.assertRaisesRegex(RuntimeError, '^Woot', engine.run) self.assertEqual(states.REVERTED, engine.storage.get_flow_state()) expected = ['a.t REVERTING', 'a.t REVERTED(None)'] self.assertEqual(expected, capturer.values)
def test_suspend_one_task(self): flow = utils.ProgressingTask('a') engine = self._make_engine(flow) with SuspendingListener(engine, task_name='b', task_state=states.SUCCESS) as capturer: engine.run() self.assertEqual(states.SUCCESS, engine.storage.get_flow_state()) expected = ['a.t RUNNING', 'a.t SUCCESS(5)'] self.assertEqual(expected, capturer.values) with SuspendingListener(engine, task_name='b', task_state=states.SUCCESS) as capturer: engine.run() self.assertEqual(states.SUCCESS, engine.storage.get_flow_state()) expected = [] self.assertEqual(expected, capturer.values)
def sleep_factory(): f = lf.Flow("test") f.add(test_utils.SleepTask('test1')) f.add(test_utils.ProgressingTask('test2')) return f