async def test_handle_spawn_event(monkeypatch, mock_app_config): # noqa: F811 expected_prefix = MockData("stream: ok.") monkeypatch.setattr(MockStreamManager, 'test_payload', expected_prefix) await mock_handle_spawn_event(mock_app_config, payload=MockData("ok"), expected=expected_prefix, stream_name='mock_write_stream_event')
async def test_execute_spawn_event(mock_app_config): # noqa: F811 result = await execute_event(mock_app_config, 'mock_spawn_event', 'ok') assert result == [ MockData(value='stream: ok.0'), MockData(value='stream: ok.1'), MockData(value='stream: ok.2') ]
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_service(mock_app_config): # noqa: F811 result = await execute_service(mock_app_config, 'mock_service_event', max_events=3) assert result == [ MockData(value='stream: service.0'), MockData(value='stream: service.1'), MockData(value='stream: service.2') ]
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 test_write_stream_batch(monkeypatch, mock_app_config, mock_plugin_config): # noqa: F811 payload = "ok" expected = MockData("stream: ok.3") setup_mocks(monkeypatch) monkeypatch.setattr(MockEventHandler, 'input_payload', payload) monkeypatch.setattr(MockEventHandler, 'expected_result', expected) monkeypatch.setattr(MockStreamManager, 'test_payload', payload) monkeypatch.setattr(MockEventHandler, 'test_track_ids', None) engine = await create_engine(app_config=mock_app_config, plugin=mock_plugin_config) stream_manager = MockStreamManager(address='test') monkeypatch.setattr(engine, 'stream_manager', stream_manager) event_info = mock_app_config.events['mock_write_stream_event'] await invoke_execute(engine=engine, from_app=engine.app_config, event_name='mock_spawn_event', query_args={}, payload=payload, expected=expected, track_ids={ "track.request_id": "test_request_id", "track.request_ts": "2020-02-05T17:07:37.771396+00:00", "track.session_id": "test_session_id" }) assert stream_manager.write_stream_name == event_info.write_stream.name assert stream_manager.write_stream_payload == expected assert stream_manager.write_target_max_len == 10 await engine.stop()
async def test_read_write_stream_new_queue( monkeypatch, mock_app_config, mock_plugin_config # noqa: F811 ): payload = MockData("ok") expected = MockResult("ok: ok") setup_mocks(monkeypatch) monkeypatch.setattr(MockEventHandler, 'input_payload', payload) monkeypatch.setattr(MockEventHandler, 'expected_result', expected) monkeypatch.setattr( MockEventHandler, 'test_track_ids', { 'track.operation_id': 'test_operation_id', 'track.request_id': 'test_request_id', 'track.request_ts': '2020-02-05T17:07:37.771396+00:00', 'track.session_id': 'test_session_id', 'stream.name': 'test_stream', 'stream.msg_id': '0000000000-0', 'stream.consumer_group': 'test_group', 'event.app': 'mock_app.test' }) monkeypatch.setattr(MockStreamManager, 'test_payload', payload) mock_app_config.events['mock_read_write_stream'].write_stream.queues = \ ['custom'] engine = await create_engine(app_config=mock_app_config, plugin=mock_plugin_config) monkeypatch.setattr(engine, 'stream_manager', MockStreamManager(address='test')) res = await engine.read_stream(event_name='mock_read_write_stream', test_mode=True) assert res == expected assert engine.stream_manager.write_stream_name == 'mock_read_write_stream.write.custom' assert engine.stream_manager.write_stream_queue == 'custom' assert engine.stream_manager.write_stream_payload == expected await engine.stop()
async def test_execute_collector(monkeypatch, mock_app_config, mock_plugin_config): # noqa: F811 payload = MockData(value="ok") expected = MockResult(value="step3: ok") setup_mocks(monkeypatch) monkeypatch.setattr(MockEventHandler, 'input_payload', payload) monkeypatch.setattr(MockEventHandler, 'expected_result', expected) monkeypatch.setattr(MockStreamManager, 'test_payload', expected) monkeypatch.setattr(MockEventHandler, 'test_track_ids', None) engine = await create_engine(app_config=mock_app_config, plugin=mock_plugin_config) await invoke_execute(engine=engine, from_app=engine.app_config, event_name='mock_collector', query_args={}, payload=payload, expected=expected, track_ids={ "track.request_id": "test_request_id", "track.request_ts": "2020-02-05T17:07:37.771396+00:00", "track.session_id": "test_session_id" }) await engine.stop()
async def __preprocess__(payload: None, context: EventContext, request: PreprocessHook) -> MockData: args = await request.parsed_args() data = Payload.parse_form_field(args['field2'], MockData) return MockData( value=f"field1:{args['field1']} field2:{data.value} file:{args['file']}" )
async def __preprocess__(payload: None, context: EventContext, request: PreprocessHook, *, query_arg1: str) -> Union[str, MockData]: fields = await request.parsed_args() if any(x not in fields for x in ('field1', 'field2', 'attachment')): request.set_status(400) return "Missing required fields" data = Json.parse_form_field(fields['field2'], MockData) return MockData(value=f"field1={fields['field1']} field2={data.value} attachment={fields['attachment']}")
async def test_service_loop_timeout(monkeypatch, mock_app_config, mock_plugin_config): # noqa: F811 payload = MockData("timeout") expected = MockData("stream: service.1") setup_mocks(monkeypatch) monkeypatch.setattr(MockEventHandler, 'input_payload', payload) monkeypatch.setattr(MockEventHandler, 'expected_result', expected) monkeypatch.setattr(MockStreamManager, 'test_payload', payload) monkeypatch.setattr(MockEventHandler, 'test_track_ids', None) engine = await create_engine(app_config=mock_app_config, plugin=mock_plugin_config) monkeypatch.setattr(engine, 'stream_manager', MockStreamManager(address='test')) res = await engine.service_loop(event_name='mock_service_timeout', test_mode=True) assert isinstance(res, TimeoutError) await engine.stop()
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_event_preprocess(mock_app_config): # noqa: F811 def mock_hooks(module, context: EventContext, preprocess_hook: PreprocessHook, postprocess_hook: PostprocessHook): preprocess_hook.headers = PreprocessHeaders.from_dict( {'X-Track-Request-Id': 'Testing!'}) assert postprocess_hook.headers.get('recognized') is None result, pp_result, response = await execute_event(mock_app_config, 'mock_post_preprocess', MockData(value='ok'), query_arg1='ok', preprocess=True, postprocess=True, mocks=[mock_hooks]) assert result == MockData(value='ok: Testing!') assert pp_result == result assert response.headers['recognized'] == 'ok: Testing!'
async def test_read_stream_event_fail_and_process_next( monkeypatch, mock_app_config, mock_plugin_config): # noqa: F811 setup_mocks(monkeypatch) payload = MockData("cancel") expected = MockResult("none") monkeypatch.setattr(MockEventHandler, 'input_payload', payload) monkeypatch.setattr(MockEventHandler, 'expected_result', expected) monkeypatch.setattr(MockStreamManager, 'test_payload', payload) engine = await create_engine(app_config=mock_app_config, plugin=mock_plugin_config) monkeypatch.setattr(engine, 'stream_manager', MockStreamManager(address='test')) res = await engine.read_stream(event_name='mock_stream_timeout', test_mode=True) assert isinstance(res, asyncio.CancelledError) payload = MockData("fail") expected = MockResult("none") monkeypatch.setattr(MockEventHandler, 'input_payload', payload) monkeypatch.setattr(MockEventHandler, 'expected_result', expected) monkeypatch.setattr(MockStreamManager, 'test_payload', payload) engine = await create_engine(app_config=mock_app_config, plugin=mock_plugin_config) monkeypatch.setattr(engine, 'stream_manager', MockStreamManager(address='test')) res = await engine.read_stream(event_name='mock_stream_timeout', test_mode=True) assert isinstance(res, ValueError) payload = MockData("ok") expected = MockResult("ok: ok") monkeypatch.setattr(MockEventHandler, 'input_payload', payload) monkeypatch.setattr(MockEventHandler, 'expected_result', expected) monkeypatch.setattr(MockStreamManager, 'test_payload', payload) res = await engine.read_stream(event_name='mock_stream_timeout', test_mode=True) assert res == expected await engine.stop()
async def test_read_write_stream_multiple_queues_propagate( monkeypatch, mock_app_config, mock_plugin_config # noqa: F811 ): payload = MockData("ok") expected = MockResult("ok: ok") setup_mocks(monkeypatch) monkeypatch.setattr(MockEventHandler, 'input_payload', payload) monkeypatch.setattr(MockEventHandler, 'expected_result', expected) monkeypatch.setattr( MockEventHandler, 'test_track_ids', { 'track.operation_id': 'test_operation_id', 'track.request_id': 'test_request_id', 'track.request_ts': '2020-02-05T17:07:37.771396+00:00', 'track.session_id': 'test_session_id', 'stream.name': 'test_stream', 'stream.msg_id': '0000000000-0', 'stream.consumer_group': 'test_group', 'event.app': 'mock_app.test' }) monkeypatch.setattr(MockStreamManager, 'test_payload', payload) monkeypatch.setattr(MockStreamManager, 'test_queue', None) # Will use last part of stream name mock_app_config.events['mock_read_write_stream'].read_stream.queues = \ ['q1', 'q2'] mock_app_config.events['mock_read_write_stream'].write_stream.queues = \ ['q3', 'q4'] mock_app_config.events['mock_read_write_stream'].write_stream.queue_strategy = \ StreamQueueStrategy.PROPAGATE engine = await create_engine(app_config=mock_app_config, plugin=mock_plugin_config) monkeypatch.setattr(engine, 'stream_manager', MockStreamManager(address='test')) res = await engine.read_stream(event_name='mock_read_write_stream', test_mode=True) assert res == expected assert engine.stream_manager.write_stream_name == 'mock_read_write_stream.write.q4' assert engine.stream_manager.write_stream_queue == 'q2' assert engine.stream_manager.write_stream_payload == expected assert MockStreamManager.last_read_stream_names[-2:] == \ ['mock_read_write_stream.read.q1', 'mock_read_write_stream.read.q2'] assert MockStreamManager.last_read_queue_names[-2:] == \ ['q1', 'q2'] assert MockStreamManager.last_write_stream_names[-4:] == [ 'mock_read_write_stream.write.q3', 'mock_read_write_stream.write.q4', 'mock_read_write_stream.write.q3', 'mock_read_write_stream.write.q4' ] assert MockStreamManager.last_write_queue_names[-4:] == \ ['q1', 'q1', 'q2', 'q2'] await engine.stop()
async def test_postprocess(mock_plugin_config): # noqa: F811 await mock_handle_postprocess(mock_plugin_config, payload=MockData("ok"), expected="PluginEvent.postprocess", expected_response={ 'cookies': { 'PluginCookie': ('PluginCookieValue', tuple(), {}) }, 'headers': { 'PluginHeader': 'PluginHeaderValue' }, 'status': 999 })
async def test_read_stream_failed(monkeypatch, mock_app_config, mock_plugin_config): # noqa: F811 payload = MockData("fail") setup_mocks(monkeypatch) monkeypatch.setattr(MockEventHandler, 'input_payload', payload) monkeypatch.setattr(MockEventHandler, 'expected_result', None) monkeypatch.setattr(MockStreamManager, 'test_payload', payload) engine = await create_engine(app_config=mock_app_config, plugin=mock_plugin_config) monkeypatch.setattr(engine, 'stream_manager', MockStreamManager(address='test')) res = await engine.read_stream(event_name='mock_stream_event', test_mode=True) assert isinstance(res, ValueError) await engine.stop()
def entry_point(payload: None, context: EventContext, *, arg_str: Optional[str] = None, arg_int: Optional[int] = None, arg_float: Optional[float] = None, arg_date: Optional[date] = None, arg_datetime: Optional[datetime] = None) -> List[MockData]: logger.info(context, "mock_app_api_query_args.entry_point") return [ MockData( f"get-{arg_str} get-{arg_int}, get-{arg_float}, get-{arg_date}, get{arg_datetime}" ) ]
class MockEventHandler(EventHandler): input_query_args = {"query_arg1": "ok"} input_payload = MockData("ok") expected_result = MockResult("ok: ok", processed=True) test_track_ids = { 'track.operation_id': 'test_operation_id', 'track.request_id': 'test_request_id', 'track.request_ts': '2020-02-05T17:07:37.771396+00:00', 'track.session_id': 'test_session_id' } expected_track_ids = test_track_ids call_function = None def __init__(self, *, app_config: AppConfig, plugins: List[AppConfig], effective_events: Dict[str, EventDescriptor], settings: Dict[str, Any]): self.app_config = app_config self.plugins = plugins self.effective_events = effective_events self.settings = settings async def handle_async_event( self, *, context: EventContext, query_args: Optional[dict], payload: Optional[EventPayload] ) -> AsyncGenerator[Optional[EventPayload], None]: assert payload == MockEventHandler.input_payload if MockEventHandler.call_function is not None: yield MockEventHandler.call_function(payload, context) elif isinstance(payload, MockData) and payload.value == 'fail': # type: ignore raise ValueError("Test for error") elif isinstance( payload, MockData) and payload.value == 'cancel': # type: ignore raise asyncio.CancelledError("Test for cancellation") elif isinstance( payload, MockData) and payload.value == 'timeout': # type: ignore await asyncio.sleep(5.0) yield MockEventHandler.expected_result async def postprocess(self, *, context: EventContext, payload: Optional[EventPayload], response: PostprocessHook) -> Optional[EventPayload]: response.set_header("PluginHeader", "PluginHeaderValue") response.set_cookie("PluginCookie", "PluginCookieValue") response.set_status(999) return payload
async def test_read_stream_timeout_ok(monkeypatch, mock_app_config, mock_plugin_config): # noqa: F811 payload = MockData("ok") expected = MockResult("ok: ok") setup_mocks(monkeypatch) monkeypatch.setattr(MockEventHandler, 'input_payload', payload) monkeypatch.setattr(MockEventHandler, 'expected_result', expected) monkeypatch.setattr(MockStreamManager, 'test_payload', payload) engine = await create_engine(app_config=mock_app_config, plugin=mock_plugin_config) monkeypatch.setattr(engine, 'stream_manager', MockStreamManager(address='test')) res = await engine.read_stream(event_name='mock_stream_timeout', test_mode=True) assert res == expected await engine.stop()
async def test_read_stream(monkeypatch, mock_app_config, mock_plugin_config): # noqa: F811 payload = MockData("ok") expected = MockResult("ok: ok") setup_mocks(monkeypatch) from mock_app import mock_event_dataobject_payload monkeypatch.setattr(MockEventHandler, 'input_payload', payload) monkeypatch.setattr(MockEventHandler, 'call_function', mock_event_dataobject_payload.entry_point) monkeypatch.setattr(MockStreamManager, 'test_payload', payload) engine = await create_engine(app_config=mock_app_config, plugin=mock_plugin_config) monkeypatch.setattr(engine, 'stream_manager', MockStreamManager(address='test')) res = await engine.read_stream(event_name='mock_stream_event', test_mode=True) assert res == expected await engine.stop()
async def test_execute(monkeypatch, mock_app_config, mock_plugin_config): # noqa: F811 payload = MockData("ok") expected = MockResult("ok: ok") setup_mocks(monkeypatch) monkeypatch.setattr(MockEventHandler, 'input_payload', payload) monkeypatch.setattr(MockEventHandler, 'expected_result', expected) monkeypatch.setattr(MockStreamManager, 'test_payload', expected) monkeypatch.setattr(MockEventHandler, 'test_track_ids', None) engine = await create_engine(app_config=mock_app_config, plugin=mock_plugin_config) await invoke_execute(engine=engine, from_app=engine.app_config, event_name='mock_post_event', query_args={"query_arg1": "ok"}, payload=payload, expected=expected, track_ids={"track.session_id": "test_session_id"}) await engine.stop()
async def test_execute_multipart_event(mock_app_config): # noqa: F811 fields = { 'field1': 'value1', 'field2': { 'value': 'value2' }, 'attachment': 'test_file_name.bytes' } upload = {'attachment': b'testdata'} result = await execute_event(mock_app_config, 'mock_multipart_event', None, fields=fields, upload=upload, query_arg1='ok', preprocess=True) assert result == MockData( value='field1=value1 field2=value2 attachment=test_file_name.bytes ok')
async def step_spawn(payload: None, context: EventContext, *, query_arg1: str) -> Spawn[MockData]: for i in range(3): yield MockData(query_arg1 + ' ' + str(i))
def step4(payload: MockData, context: EventContext) -> Union[MockData, str]: if payload.value.startswith('a'): return MockData(payload.value + ' step4') else: return payload.value + ' step4'
async def test_invoke_single_step(): result = await invoke_single_step(step1, payload=MockData('input'), context=test_context()) assert result == MockData("input step1")
async def step_respawn(payload: MockData, context: EventContext) -> Spawn[MockData]: for j in range(3): yield MockData(payload.value + ' respawn:' + str(j))
def entry_point(payload: None, context: EventContext, *, arg1: Optional[int] = None) -> List[MockData]: logger.info(context, "mock_app_api_get_list.entry_point") return [MockData(f"get-{arg1}")]
def step3(payload: MockData, context: EventContext) -> MockData: return MockData(payload.value + ' step3')