def test_propagate_attribute(self): """ Test that attribute 'raises_on_failure' is well propagated through FuncGroup. """ first = ActivityTask(running_task, "test1") intermediary_activities = Chain( (running_task, "test2"), (running_task, "test3"), ) last = ActivityTask(running_task, "test4") def custom_func(_): return intermediary_activities Chain(first, FuncGroup(custom_func), last, send_result=True, raises_on_failure=False).submit(executor) self.assertFalse(first.activity.raises_on_failure) self.assertFalse(last.activity.raises_on_failure) self.assertFalse( intermediary_activities.activities[0].activity.raises_on_failure) self.assertFalse( intermediary_activities.activities[1].activity.raises_on_failure)
def run(self): x = 1 y = 2 z = 3 future = self.submit( Chain( Group( (increment_slowly, x), (increment_slowly, y), (increment_slowly, z), ), multiply, send_result=True ) ) futures.wait(future) res = future.result[-1] print('({}+1)*({}+1)*({}+1) = {}'.format(x, y, z, res)) # Canvas's and Group's can also be "optional" future = self.submit( Chain( (fail_incrementing, x), (increment_slowly, 1), # never executed raises_on_failure=False, ) ) futures.wait(future) print('SUCCESS!')
def test(self): complex_canvas = Chain((sum_values, [1, 2]), (sum_values, [1, 2]), Group( (to_int, 1), (to_int, 2), ), Chain( (sum_values, [1, 2]), running_task, ), (sum_values, [1, 2])) result = complex_canvas.submit(executor) self.assertFalse(result.finished) self.assertTrue(result.futures[0].finished) self.assertTrue(result.futures[1].finished) self.assertTrue(result.futures[2].finished) self.assertFalse(result.futures[3].finished) self.assertTrue(result.futures[3].futures[0].finished) self.assertFalse(result.futures[3].futures[1].finished) # As result.futures[3] is not finished, we shouldn't find other future self.assertEqual(len(result.futures), 4) # Change the state of the n-1 chain to make the whole # canvas done complex_canvas.activities[3].activities[1] = ActivityTask(to_int, 1) result = complex_canvas.submit(executor) self.assertTrue(result.finished) self.assertEqual(len(result.futures), 5)
def test(self): complex_canvas = Chain( ActivityTask(sum_values, [1, 2]), ActivityTask(sum_values, [1, 2]), Group( ActivityTask(to_int, 1), ActivityTask(to_int, 2), ), Chain( ActivityTask(sum_values, [1, 2]), ActivityTask(running_task, 1) ), ActivityTask(sum_values, [1, 2]) ) result = complex_canvas.submit(executor) self.assertFalse(result.finished) self.assertTrue(result.futures[0].finished) self.assertTrue(result.futures[1].finished) self.assertTrue(result.futures[2].finished) self.assertFalse(result.futures[3].finished) self.assertTrue(result.futures[3].futures[0].finished) self.assertFalse(result.futures[3].futures[1].finished) # As result.futures[3] is not finished, we shouldn't find other future self.assertEquals(len(result.futures), 4) # Change the state of the n-1 chain to make the whole # canvas done complex_canvas.activities[3].activities[1] = ActivityTask(to_int, 1) result = complex_canvas.submit(executor) self.assertTrue(result.finished) self.assertEquals(len(result.futures), 5)
def test(self): future = Chain((to_string, "test"), (to_string, "test")).submit(executor) self.assertTrue(future.finished) self.assertEqual(future.count_finished_activities, 2) future = Chain((to_string, "test"), (running_task, "test"), (to_string, "test")).submit(executor) self.assertTrue(future.running) self.assertEqual(future.count_finished_activities, 1)
def test_raises_on_failure(self): chain = Chain((to_string, "test1"), (zero_division), raises_on_failure=False) self.assertFalse(chain.activities[0].activity.raises_on_failure) self.assertFalse(chain.activities[1].activity.raises_on_failure) chain = Chain((to_string, "test1"), (zero_division), raises_on_failure=True) self.assertTrue(chain.activities[0].activity.raises_on_failure) self.assertTrue(chain.activities[1].activity.raises_on_failure)
def fn_steps_done(steps_done): marker = { "step": self.step_name, "status": "scheduled", "forced": False, "reasons": [], } chain = Chain() forced_steps = workflow.get_forced_steps() skipped_steps = workflow.get_skipped_steps() if step_will_run( self.step_name, forced_steps, skipped_steps, steps_done, self.force ): if step_is_forced(self.step_name, forced_steps, self.force): marker["forced"] = True marker["reasons"] = get_step_force_reasons( self.step_name, getattr(workflow, "steps_forced_reasons", {}) ) marker_done = copy.copy(marker) marker_done["status"] = "completed" workflow.add_forced_steps( self.force_steps_if_executed, "Dep of {}".format(self.step_name) ) chain += ( workflow.record_marker("log.step", marker), self.activities, ( activity.Activity( MarkStepDoneTask, **workflow._get_step_activity_params() ), workflow.get_step_bucket(), workflow.get_step_path_prefix(), self.step_name, ), workflow.record_marker("log.step", marker_done), ) else: marker["status"] = "skipped" if step_is_skipped_by_force(self.step_name, skipped_steps): marker["forced"] = True marker["reasons"] = get_step_skip_reasons( self.step_name, getattr(workflow, "steps_skipped_reasons", {}) ) else: marker["reasons"] = ["Step was already played"] if self.activities_if_step_already_done: chain.append(self.activities_if_step_already_done) chain.append(workflow.record_marker("log.step", marker)) if self.emit_signal: chain.append( workflow.signal("step.{}".format(self.step_name), propagate=False) ) chain.bubbles_exception_on_failure = self.bubbles_exception_on_failure return chain
def run(self): chain1 = Chain( Group(ActivityTask(func_a_1_1), ActivityTask(func_a_1_2)), self.signal("signal1"), Group(ActivityTask(func_a_2_1), ActivityTask(func_a_2_2)), ) chain2 = Chain( Group(ActivityTask(func_b_1_1), ActivityTask(func_b_1_2)), self.wait_signal("signal1"), Group(ActivityTask(func_b_2_1), ActivityTask(func_b_2_2)), ) my_group = Group(chain1, chain2) fut = self.submit(my_group) futures.wait(fut)
def test_propagate_attribute(self): """ Test that attribute 'raises_on_failure' is well propagated through Chain. """ inner_a = Chain( (running_task, "test1"), (running_task, "test2"), ) inner_b = ActivityTask(running_task, "test3") Chain(inner_a, inner_b, raises_on_failure=False).submit(executor) self.assertFalse(inner_b.activity.raises_on_failure) self.assertFalse(inner_a.activities[0].activity.raises_on_failure) self.assertFalse(inner_a.activities[1].activity.raises_on_failure)
def fn_steps_done(steps_done): marker = { "step": self.step_name, "status": "scheduled", "forced": False, "reasons": [] } chain = Chain() if step_will_run(self.step_name, workflow.get_forced_steps(), steps_done, self.force): if step_is_forced(self.step_name, workflow.get_forced_steps(), self.force): marker["forced"] = True marker["reasons"] = get_step_force_reasons(self.step_name, workflow.steps_forced_reasons) workflow.add_forced_steps(self.force_steps_if_executed, 'Dep of {}'.format(self.step_name)) chain += ( self.activities, (activity.Activity(MarkStepDoneTask, **workflow._get_step_activity_params()), workflow.get_step_bucket(), workflow.get_step_path_prefix(), self.step_name), workflow.record_marker('log.step', marker) ) else: marker["status"] = "skipped" if self.activities_if_step_already_done: chain.append(self.activities_if_step_already_done) chain.append( workflow.record_marker('log.step', marker)) if self.emit_signal: chain.append( workflow.signal('step.{}'.format(self.step_name), propagate=False)) return chain
def test_previous_value(self): future = Chain(ActivityTask(sum_values, [1, 2]), ActivityTask(sum_previous, [2, 3]), ActivityTask(sum_previous, [4, 5]), send_result=True).submit(executor) self.assertTrue(future.finished) self.assertEquals(future.result, [3, 8, 17])
def run(self): return self.submit( Chain( Group( self.wait_signal('signal'), self.wait_signal('signal 2'), ), )).result
def test_exceptions(self): future = Chain(ActivityTask(to_string, 1), ActivityTask(to_string, 2)).submit(executor) self.assertIsNone(future.exception) future = Chain( ActivityTask(zero_division), ActivityTask(zero_division), ).submit(executor) self.assertTrue(future.finished) self.assertIsInstance(future.exception, AggregateException) # Both tasks were tried and failed (being in a chain doesn't change this) self.assertEqual(2, len(future.exception.exceptions)) self.assertIsInstance(future.exception.exceptions[0], ZeroDivisionError) self.assertIsInstance(future.exception.exceptions[1], ZeroDivisionError)
def test_raises_on_failure_doesnt_set_exception(self): future = Chain( (zero_division), (to_string, "test1"), raises_on_failure=False ).submit(executor) self.assertEqual(1, future.count_finished_activities) self.assertIsNone(future.exception)
def run(self, *args, **kwargs): results = (Chain(ChildWorkflow2, (to_int, "2")).submit(self.executor).result) return { "workflow_id": self.get_run_context()["workflow_id"], "run_id": self.get_run_context()["run_id"], "child": results, }
def test_propagate_attribute(self): """ Test that attribute 'raises_on_failure' is well propagated through Step. """ self.create_bucket() executor = CustomExecutor(MyWorkflow) executor.initialize_history({}) activities = Chain( (MyTask, 1), (MyTask, 2), ) step_act = Step("test_propagate_attribute", activities) Chain(step_act, raises_on_failure=False).submit(executor) self.assertFalse(activities.activities[0].activity.raises_on_failure) self.assertFalse(activities.activities[1].activity.raises_on_failure)
def test_exceptions(self): future = Chain((to_string, 1), (to_string, 2)).submit(executor) self.assertIsNone(future.exception) # Do not execute the 3rd step is the 2nd is failing on chains future = Chain( (to_string, "test1"), (zero_division), (to_string, "test2"), ).submit(executor) self.assertTrue(future.finished) self.assertIsInstance(future.exception, AggregateException) # Both tasks were tried and failed (being in a chain doesn't change this) self.assertEqual(2, len(future.exception.exceptions)) self.assertIsNone(future.exception.exceptions[0]) self.assertIsInstance(future.exception.exceptions[1], ZeroDivisionError)
def run(self): all = [ self.submit(ChildWorkUntilSignalWorkflow), self.submit( Chain( ActivityTask(func_a_1_2), self.signal('signal1'), )), ] futures.wait(*all)
def run(self): return self.submit( Chain( Group( ChildWorkflowWaitingSignals, self.signal("signal", propagate=True), self.signal("signal 2", propagate=True), ), ) ).result
def run(self, x=5): future = self.submit( Chain(ActivityTask(increment, x), ActivityTask(double), send_result=True)) print("Future: {}".format(future)) futures.wait(future) print("Result: {}".format(future.result)) # future.result == [6, 12] return future.result
def fn_steps_done(steps_done): marker = { "step": self.step_name, "status": "scheduled", "forced": False, "reasons": [] } chain = Chain() forced_steps = workflow.get_forced_steps() skipped_steps = workflow.get_skipped_steps() if step_will_run(self.step_name, forced_steps, skipped_steps, steps_done, self.force): if step_is_forced(self.step_name, forced_steps, self.force): marker["forced"] = True marker["reasons"] = get_step_force_reasons( self.step_name, getattr(workflow, 'steps_forced_reasons', {}) ) marker_done = copy.copy(marker) marker_done["status"] = "completed" workflow.add_forced_steps(self.force_steps_if_executed, 'Dep of {}'.format(self.step_name)) chain += ( workflow.record_marker('log.step', marker), self.activities, (activity.Activity(MarkStepDoneTask, **workflow._get_step_activity_params()), workflow.get_step_bucket(), workflow.get_step_path_prefix(), self.step_name), workflow.record_marker('log.step', marker_done) ) else: marker["status"] = "skipped" if step_is_skipped_by_force(self.step_name, skipped_steps): marker["forced"] = True marker["reasons"] = get_step_skip_reasons( self.step_name, getattr(workflow, 'steps_skipped_reasons', {}) ) else: marker["reasons"] = ["Step was already played"] if self.activities_if_step_already_done: chain.append(self.activities_if_step_already_done) chain.append( workflow.record_marker('log.step', marker)) if self.emit_signal: chain.append( workflow.signal('step.{}'.format(self.step_name), propagate=False)) chain.bubbles_exception_on_failure = self.bubbles_exception_on_failure return chain
def test_previous_value_with_func(self): def custom_func(previous_value): group = Group() for i in range(0, previous_value): group.append(to_int, i * 2) return group chain = Chain((sum_values, [1, 2]), FuncGroup(custom_func), (sum_values, ), send_result=True).submit(executor) self.assertEqual(chain.result, [3, [0, 2, 4], 6])
def test_signals_dont_hurt(self): """ Check that propagate_attribute doesn't fail on signal-related objects :return: """ future = Chain((to_string, 1), executor.signal('test'), (to_string, 2), executor.wait_signal('test'), raises_on_failure=False).submit(executor) self.assertEqual(4, future.count_finished_activities) self.assertIsNone(future.exception)
def run(self, *args, **kwargs): future = self.submit( Chain( Group( (self.wait_signal("signal 2"), ), (self.wait_signal("signal"), ), (wait_and_signal, ), (wait_and_signal, "signal 2"), ), (increment, 1), )) futures.wait(future)
def run(self, use_chain): m1 = self.record_marker("marker 1") m2 = self.record_marker("marker 1", "some details") m3 = self.record_marker("marker 2", "2nd marker's details") if use_chain: # Markers will be submitted in 3 replays future = self.submit(Chain(m1, m2, m3)) else: # Markers will be submitted as one decision future = self.submit(m1) self.submit(m2) self.submit(m3) futures.wait(future)
def run(self): chain = Chain( self.record_marker('marker 1'), self.record_marker('marker 1', 'some details'), self.record_marker('marker 2', "2nd marker's details"), ) futures.wait(self.submit(chain)) markers = self.list_markers() assert 2 == len(markers) print('Markers: {}'.format(markers)) markers = self.list_markers(all=True) assert 3 == len(markers) print('Markers, all: {}'.format(markers))
def run(self, t1=30, t2=120): """ Cancel timer 2 after timer 1 is fired. """ future = self.submit( Group( self.start_timer("timer 2", t2), Chain(self.start_timer("timer 1", t1), self.cancel_timer("timer 2"),), ) ) if future.pending: print("Starting timers") futures.wait(future) print("Timer fired, exiting")
def run(self): x = 1 y = 2 z = 3 future = self.submit( Chain(Group( ActivityTask(increment_slowly, x), ActivityTask(increment_slowly, y), ActivityTask(increment_slowly, z), ), ActivityTask(multiply), send_result=True)) futures.wait(future) res = future.result[-1] print('({}+1)*({}+1)*({}+1) = {}'.format(x, y, z, res))
def run(self): x = 1 y = 2 z = 3 future = self.submit( Chain(Group( (increment_slowly, x), (increment_slowly, y), (increment_slowly, z), ), multiply, send_result=True)) futures.wait(future) res = future.result[-1] print('({}+1)*({}+1)*({}+1) = {}'.format(x, y, z, res)) # Canvas's and Group's can also be "optional" future = self.submit( Chain( (fail_incrementing, x), (increment_slowly, 1), # never executed (multiply, [3, 2]), raises_on_failure=False, )) assert [None] == future.result, 'Unexpected result {!r}'.format( future.result) print('Chain with failure: {}'.format(future.result)) # Breaking the chain on failure is the default but can be bypassed future = self.submit( Chain( (fail_incrementing, x), (increment_slowly, 1), # executed (multiply, [3, 2]), break_on_failure=False, )) assert [None, 2, 6] == future.result, 'Unexpected result {!r}'.format( future.result) print('Chain ignoring failure: {}'.format(future.result)) # Failing inside a chain by default don't stop an upper chain future = self.submit( Chain( Chain( (fail_incrementing, x), raises_on_failure=False, ), (increment_slowly, 1), # executed (multiply, [3, 2]), )) assert [[None], 2, 6] == future.result, 'Unexpected result {!r}'.format( future.result) print('Chain with failure in subchain: {}'.format(future.result)) # But it can, too future = self.submit( Chain( Chain( Chain( (fail_incrementing, x), raises_on_failure=False, bubbles_exception_on_failure=True, ), (increment_slowly, 1), # not executed bubbles_exception_on_failure=False, ), (multiply, [3, 2]), # executed )) assert [[[None]], 6] == future.result, 'Unexpected result {!r}'.format( future.result) print('Chain with failure in sub-subchain: {}'.format(future.result)) print('Finished!')