async def test_execute_multiple_spawn_steps(): steps = [ (0, 'step_spawn', (step_spawn, None, Spawn[MockData], True)), (1, 'step1', (step1, MockData, MockData, False)), (2, 'step2', (step2, MockData, MockData, False)), (3, 'step3', (step3, MockData, MockData, False)), (4, 'step_respawn', (step_respawn, MockData, Spawn[MockData], True)), (5, 'step4', (step4, MockData, Union[MockData, str], False)), (6, 'step5a', (step5a, MockData, MockResult, False)), (7, 'step5b', (step5b, str, MockResult, False)), (8, 'step6', (step6, MockResult, MockResult, False)) ] i, j, count = 0, 0, 0 async for result in execute_steps(steps=steps, payload=None, context=test_context(), query_arg1='a'): assert result == MockResult(f"a {i} step1 step2 step3 respawn:{j} step4 step5a step6") i, j = i + 1 if j == 2 else i, j + 1 if j < 2 else 0 count += 1 assert count <= 9 assert count == 9 i, j, count = 0, 0, 0 async for result in execute_steps(steps=steps, payload=None, context=test_context(), query_arg1='b'): assert result == MockResult(f"b {i} step1 step2 step3 respawn:{j} step4 step5b step6") i, j = i + 1 if j == 2 else i, j + 1 if j < 2 else 0 count += 1 assert count <= 9 assert count == 9
async def test_execute_decision_steps(): steps = {'step1': (step1, MockData, MockData), 'step2': (step2, MockData, MockData), 'step3': (step3, MockData, MockData), 'step4': (step4, MockData, Union[MockData, str]), 'step5a': (step5a, MockData, MockResult), 'step5b': (step5b, str, MockResult), 'step6': (step6, MockResult, MockResult)} async for result in execute_steps(steps=steps, payload=MockData('a'), context=test_context()): assert result == MockResult("a step1 step2 step3 step4 step5a step6") async for result in execute_steps(steps=steps, payload=MockData('b'), context=test_context()): assert result == MockResult("b step1 step2 step3 step4 step5b step6")
async def test_execute_decision_steps(): steps = [ (0, 'step1', (step1, MockData, MockData, False)), (1, 'step2', (step2, MockData, MockData, False)), (2, 'step3', (step3, MockData, MockData, False)), (3, 'step4', (step4, MockData, Union[MockData, str], False)), (4, 'step5a', (step5a, MockData, MockResult, False)), (5, 'step5b', (step5b, str, MockResult, False)), (6, 'step6', (step6, MockResult, MockResult, False)) ] async for result in execute_steps(steps=steps, payload=MockData('a'), context=test_context()): assert result == MockResult("a step1 step2 step3 step4 step5a step6") async for result in execute_steps(steps=steps, payload=MockData('b'), context=test_context()): assert result == MockResult("b step1 step2 step3 step4 step5b step6")
async def handle_async_event( self, *, context: EventContext, query_args: Optional[Dict[str, Any]], payload: Optional[EventPayload] ) -> AsyncGenerator[Optional[EventPayload], None]: """ Handles execution of engine defined event. Executes event handler code deployed with app. Execution goes as following: * EventDescriptor from AppConfig is used * an object from a class with CamelCase name same as event name is instantiated * find the next step to execute that accepts input with payload type * method with same name as step is invoked in instantiated object * if a step specifies write_stream, and event is not None, payload is published to a stream * repeats previous 3 steps executing next step that accepts current payload type :param context: EventContext :param query_args: arguments from a query context in the form of a dictionary :param payload: EventPayload, to be sent to event implementor """ await self._ensure_initialized(context) steps = self.steps[context.event_name] async for result in execute_steps(steps, context=context, payload=payload, **(query_args or {})): yield result
async def test_execute_linear_steps(): steps = [ (0, 'step1', (step1, MockData, MockData, False)), (1, 'step2', (step2, MockData, MockData, False)), (2, 'step3', (step3, MockData, MockData, False)) ] async for result in execute_steps(steps=steps, payload=MockData('input'), context=test_context()): assert result == MockData("input step1 step2 step3")
async def test_execute_spawn_middle_steps_not_supported(): steps = {'step1': (step1, MockData, MockData), 'step2': (step2, MockData, MockData), 'step3': (step3, MockData, MockData), 'step_spawn_middle': (step_spawn_middle, MockData, Spawn[MockData])} with pytest.raises(NotImplementedError): async for _ in execute_steps(steps=steps, payload=MockData('a'), context=test_context()): pass
async def test_execute_spawn_initial_steps(): steps = {'step_spawn': (step_spawn, None, Spawn[MockData]), 'step1': (step1, MockData, MockData), 'step2': (step2, MockData, MockData), 'step3': (step3, MockData, MockData), 'step4': (step4, MockData, Union[MockData, str]), 'step5a': (step5a, MockData, MockResult), 'step5b': (step5b, str, MockResult), 'step6': (step6, MockResult, MockResult)} i = 0 async for result in execute_steps(steps=steps, payload=None, context=test_context(), query_arg1='a'): assert result == MockResult(f"a {i} step1 step2 step3 step4 step5a step6") i += 1 assert i == 3 i = 0 async for result in execute_steps(steps=steps, payload=None, context=test_context(), query_arg1='b'): assert result == MockResult(f"b {i} step1 step2 step3 step4 step5b step6") i += 1 assert i == 3
async def test_execute_spawn_initial_steps(): steps = [ (0, 'step_spawn', (step_spawn, None, Spawn[MockData], True)), (1, 'step1', (step1, MockData, MockData, False)), (2, 'step2', (step2, MockData, MockData, False)), (3, 'step3', (step3, MockData, MockData, False)), (4, 'step4', (step4, MockData, Union[MockData, str], False)), (5, 'step5a', (step5a, MockData, MockResult, False)), (6, 'step5b', (step5b, str, MockResult, False)), (7, 'step6', (step6, MockResult, MockResult, False)) ] i = 0 async for result in execute_steps(steps=steps, payload=None, context=test_context(), query_arg1='a'): assert result == MockResult(f"a {i} step1 step2 step3 step4 step5a step6") i += 1 assert i == 3 i = 0 async for result in execute_steps(steps=steps, payload=None, context=test_context(), query_arg1='b'): assert result == MockResult(f"b {i} step1 step2 step3 step4 step5b step6") i += 1 assert i == 3
async def test_execute_linear_steps(): steps = {'step1': (step1, MockData, MockData), 'step2': (step2, MockData, MockData), 'step3': (step3, MockData, MockData)} async for result in execute_steps(steps=steps, payload=MockData('input'), context=test_context()): assert result == MockData("input step1 step2 step3")