def test_json_base_large_message(monkeypatch: Any, capsys: Any, loop: Any) -> None: services, future = start_service("tests/services/dummy_service.py", monkeypatch) instance = services.get("test_dummy") async def _async() -> None: data = ["item {}".format(i) for i in range(1, 10000)] assert len(json.dumps(data)) > 60000 t1 = time.time() json_message = await instance.message_envelope.build_message( instance, "topic", data) assert len(json.dumps(json_message)) < 60000 t2 = time.time() result, message_uuid, timestamp = await instance.message_envelope.parse_message( json_message) assert result.get("metadata", {}).get("data_encoding") == "base64_gzip_json" assert len(json.dumps(result.get("data"))) == len(json.dumps(data)) assert json.dumps(result.get("data")) == json.dumps(data) assert len(message_uuid) == 73 assert message_uuid[0:36] == instance.uuid assert timestamp >= t1 assert timestamp <= t2 loop.run_until_complete(_async()) async def _async_kill(): os.kill(os.getpid(), signal.SIGINT) loop.create_task(_async_kill()) loop.run_until_complete(future)
def test_conflicting_port_http_service(monkeypatch: Any, capsys: Any, loop: Any) -> None: services, future = start_service( "tests/services/http_service_same_port.py", monkeypatch) assert services is not None assert len(services) == 2 instance = services.get("test_http1") assert instance is not None port1 = instance.context.get("_http_port") assert instance.uuid is not None instance = services.get("test_http2") assert instance is not None port2 = instance.context.get("_http_port") assert instance.uuid is not None assert bool(port1 and port2) is False loop.run_until_complete(future) out, err = capsys.readouterr() assert "address already in use" in err or "address in use" in err
def test_start_aws_sns_sqs_service_with_credentials_with_custom_protocol( monkeypatch: Any, capsys: Any, loop: Any) -> None: services, future = start_service( 'tests/services/aws_sns_sqs_service_with_credentials_with_custom_protocol.py', monkeypatch) assert services is not None assert len(services) == 1 instance = services.get('test_aws_sns_sqs') assert instance is not None assert instance.uuid is not None async def _async(loop: Any) -> None: loop_until = time.time() + 10 while loop_until > time.time(): if instance.test_topic_data_received and instance.test_topic_data: break await asyncio.sleep(0.5) assert instance.test_topic_data_received assert instance.test_topic_data == instance.data_uuid loop.run_until_complete(_async(loop)) instance.stop_service() loop.run_until_complete(future)
def test_protobuf_base(monkeypatch: Any, capsys: Any, loop: Any) -> None: services, future = start_service( 'tests/services/dummy_protobuf_service.py', monkeypatch) instance = services.get('test_dummy_protobuf') async def _async() -> None: data = Person() data.name = 'John Doe' data.id = '12' t1 = time.time() protobuf_message = await instance.message_protocol.build_message( instance, 'topic', data) t2 = time.time() result, message_uuid, timestamp = await instance.message_protocol.parse_message( protobuf_message, Person) assert type(result.get('data')) is Person assert result.get('data') == data assert result.get('metadata', {}).get('data_encoding') == 'proto' assert result.get('data') == data assert result.get('data').name == data.name assert result.get('data').id == data.id assert len(MessageToJson(result.get('data'))) == len( MessageToJson(data)) assert MessageToJson(result.get('data')) == MessageToJson(data) assert len(message_uuid) == 73 assert message_uuid[0:36] == instance.uuid assert timestamp >= t1 assert timestamp <= t2 loop.run_until_complete(_async()) os.kill(os.getpid(), signal.SIGINT) loop.run_until_complete(future)
def test_protobuf_object_static_validation_function_fail( monkeypatch: Any, capsys: Any, loop: Any) -> None: services, future = start_service( 'tests/services/dummy_protobuf_service.py', monkeypatch) instance = services.get('test_dummy_protobuf') def test_static_validator(person: Person) -> None: validate_field_regex(person.name, r'^(#?[a-fA-F0-9]{6}|)$') async def _async() -> None: data = Person() data.name = 'John Doe' data.id = '12' protobuf_message = await instance.message_protocol.build_message( instance, 'topic', data) await instance.message_protocol.parse_message(protobuf_message, Person, test_static_validator) with pytest.raises(RegexMissmatchException): loop.run_until_complete(_async()) os.kill(os.getpid(), signal.SIGINT) loop.run_until_complete(future)
def test_schedule_service(monkeypatch: Any, capsys: Any, loop: Any) -> None: services, future = start_service("tests/services/schedule_service.py", monkeypatch) assert services is not None assert len(services) == 1 instance = services.get("test_schedule") assert instance is not None assert instance.uuid is not None async def _async(loop: Any) -> None: seconds = instance.seconds_triggered third_seconds_triggered = instance.third_seconds_triggered await asyncio.sleep(1.5) assert instance.seconds_triggered > seconds assert instance.third_seconds_triggered == third_seconds_triggered seconds = instance.seconds_triggered await asyncio.sleep(4) assert instance.seconds_triggered > seconds assert instance.third_seconds_triggered > third_seconds_triggered loop.run_until_complete(_async(loop)) instance.stop_service() loop.run_until_complete(future)
def test_protobuf_base_no_proto_class(monkeypatch: Any, capsys: Any, loop: Any) -> None: services, future = start_service( "tests/services/dummy_protobuf_service.py", monkeypatch) instance = services.get("test_dummy_protobuf") async def _async() -> None: data = Person() data.name = "John Doe" data.id = "12" protobuf_message = await instance.message_envelope.build_message( instance, "topic", data) result, message_uuid, timestamp = await instance.message_envelope.parse_message( protobuf_message) assert type(result.get("data")) is not Person assert type(result.get("data")) is bytes assert result.get("data") != data assert result.get("data") == b"\n\x0212\x12\x08John Doe" loop.run_until_complete(_async()) async def _async_kill(): os.kill(os.getpid(), signal.SIGINT) loop.create_task(_async_kill()) loop.run_until_complete(future)
def test_start_process_http_later_request(monkeypatch: Any, capsys: Any, loop: Any) -> None: func, future = start_service('tests/services/start_process_service_http_2.py', monkeypatch, wait=False) port = 53252 async def _async(loop: Any) -> None: await asyncio.sleep(5) async with aiohttp.ClientSession(loop=loop) as client: try: response = await client.get('http://127.0.0.1:{}/'.format(port)) except Exception: response = False assert response is not False loop.run_until_complete(_async(loop)) loop.run_until_complete(future) services = func() assert services is not None assert len(services) == 1 instance = services.get('test_http') assert instance is not None assert instance.uuid is not None assert instance.function_order == [ '_start_service', '_started_service', 'index', '_stop_service' ] instance.stop_service()
def test_start_process_schedule(monkeypatch: Any, capsys: Any, loop: Any) -> None: services, future = start_service( "tests/services/start_process_service_schedule.py", monkeypatch) assert services is not None assert len(services) == 1 instance = services.get("test_schedule") assert instance is not None assert instance.uuid is not None async def _async(loop: Any) -> None: await asyncio.sleep(8) loop.run_until_complete(_async(loop)) instance.stop_service() loop.run_until_complete(future) assert instance.function_order == [ "_start_service", "_started_service", "every_fifth_second", "every_fifth_second", "stop_service", "_stopping_service", "_stop_service", ]
def test_import_error(monkeypatch: Any, capsys: Any, loop: Any) -> None: with pytest.raises(ImportError): services, future = start_service( "tests/services/import_error_service.py", monkeypatch) out, err = capsys.readouterr() assert "Invalid service, unable to load service file" in err
def test_start_amqp_service_with_credentials(monkeypatch: Any, capsys: Any, loop: Any) -> None: services, future = start_service("tests/services/amqp_service_with_credentials.py", monkeypatch) assert services is not None assert len(services) == 1 instance = services.get("test_amqp") assert instance is not None assert instance.uuid is not None async def _async(loop: Any) -> None: loop_until = time.time() + 10 while loop_until > time.time(): if ( instance.test_topic_data_received and instance.test_topic_metadata_topic and instance.test_topic_service_uuid and instance.wildcard_topic_data_received and instance.test_topic_specified_queue_name_data_received ): break await asyncio.sleep(0.5) assert instance.test_topic_data_received assert instance.test_topic_metadata_topic == "test.topic" assert instance.test_topic_service_uuid == instance.uuid assert instance.wildcard_topic_data_received assert instance.test_topic_specified_queue_name_data_received loop.run_until_complete(_async(loop)) instance.stop_service() loop.run_until_complete(future)
def test_json_base_large_message(monkeypatch: Any, capsys: Any, loop: Any) -> None: services, future = start_service('tests/services/dummy_service.py', monkeypatch) instance = services.get('test_dummy') async def _async() -> None: data = ['item {}'.format(i) for i in range(1, 10000)] assert len(ujson.dumps(data)) > 60000 t1 = time.time() json_message = await instance.message_protocol.build_message( instance, 'topic', data) assert len(ujson.dumps(json_message)) < 60000 t2 = time.time() result, message_uuid, timestamp = await instance.message_protocol.parse_message( json_message) assert result.get('metadata', {}).get('data_encoding') == 'base64_gzip_json' assert len(ujson.dumps(result.get('data'))) == len(ujson.dumps(data)) assert ujson.dumps(result.get('data')) == ujson.dumps(data) assert len(message_uuid) == 73 assert message_uuid[0:36] == instance.uuid assert timestamp >= t1 assert timestamp <= t2 loop.run_until_complete(_async()) os.kill(os.getpid(), signal.SIGINT) loop.run_until_complete(future)
def test_syntax_error_service(monkeypatch: Any, capsys: Any) -> None: with pytest.raises(SyntaxError): services, future = start_service( 'tests/services/syntax_error_service.py', monkeypatch) out, err = capsys.readouterr() assert 'Unable to load service file' in err
def test_protobuf_object_static_validation_function_fail( monkeypatch: Any, capsys: Any, loop: Any) -> None: services, future = start_service( "tests/services/dummy_protobuf_service.py", monkeypatch) instance = services.get("test_dummy_protobuf") def test_static_validator(person: Person) -> None: validate_field_regex(person.name, r"^(#?[a-fA-F0-9]{6}|)$") async def _async() -> None: data = Person() data.name = "John Doe" data.id = "12" protobuf_message = await instance.message_envelope.build_message( instance, "topic", data) await instance.message_envelope.parse_message(protobuf_message, Person, test_static_validator) with pytest.raises(RegexMissmatchException): loop.run_until_complete(_async()) async def _async_kill(): os.kill(os.getpid(), signal.SIGINT) loop.create_task(_async_kill()) loop.run_until_complete(future)
def test_invalid_filename(monkeypatch: Any, capsys: Any, loop: Any) -> None: with pytest.raises(SystemExit): services, future = start_service( "tests/services/no_service_existing.py", monkeypatch) out, err = capsys.readouterr() assert "Invalid service, no such service" in err
def test_start_aws_sns_sqs_service_dead_letter_queue(monkeypatch: Any, capsys: Any, loop: Any) -> None: services, future = start_service( "tests/services/aws_sns_sqs_service_dead_letter_queue.py", monkeypatch) assert services is not None assert len(services) == 1 instance = services.get("test_aws_sns_sqs_dead_letter_queue") assert instance is not None assert instance.uuid is not None async def _async(loop: Any) -> None: loop_until = time.time() + 18 while loop_until > time.time(): if instance.test_topic_data_received_count == 3 and instance.test_dlq_data_received_after_count == 3: break await asyncio.sleep(0.5) assert instance.test_topic_data_received_count == 3 assert instance.test_dlq_data_received_after_count == 3 loop.run_until_complete(_async(loop)) instance.stop_service() loop.run_until_complete(future)
def test_start_process_http_early_request(monkeypatch: Any, capsys: Any, loop: Any) -> None: func, future = start_service( "tests/services/start_process_service_http_1.py", monkeypatch, wait=False) port = 53251 async def _async(loop: Any) -> None: await asyncio.sleep(1.5) async with aiohttp.ClientSession(loop=loop) as client: try: response = await client.get("http://127.0.0.1:{}/".format(port) ) except Exception: response = False assert response is False loop.run_until_complete(_async(loop)) loop.run_until_complete(future) services = func() assert services is not None assert len(services) == 1 instance = services.get("test_http") assert instance is not None assert instance.uuid is not None assert instance.function_order == [ "_start_service", "_started_service", "_stop_service" ] instance.stop_service()
def test_exception_service_in_init(monkeypatch: Any, capsys: Any, loop: Any) -> None: services, future = start_service( "tests/services/exception_service_init.py", monkeypatch) with pytest.raises(Exception): loop.run_until_complete(future)
def test_invalid_service(monkeypatch: Any, capsys: Any, loop: Any) -> None: with pytest.raises(NameError): services, future = start_service("tests/services/invalid_service.py", monkeypatch) out, err = capsys.readouterr() assert "Unable to load service file" in err
def test_publish_invalid_credentials(monkeypatch: Any, capsys: Any, loop: Any) -> None: services, future = start_service("tests/services/dummy_service.py", monkeypatch) instance = services.get("test_dummy") with pytest.raises(AWSSNSSQSException): loop.run_until_complete( AWSSNSSQSTransport.publish(instance, "data", "test-topic", wait=True)) async def _async_kill(): os.kill(os.getpid(), signal.SIGINT) loop.create_task(_async_kill()) loop.run_until_complete(future) if not future.done(): future.set_result(None) out, err = capsys.readouterr() assert "The security token included in the request is invalid" in err assert out == ""
def test_empty_service(monkeypatch: Any, capsys: Any, loop: Any) -> None: services, future = start_service("tests/services/empty_service.py", monkeypatch) loop.run_until_complete(future) out, err = capsys.readouterr() assert "No transports defined in service file" in err
def test_exception_service(monkeypatch: Any, capsys: Any, loop: Any) -> None: services, future = start_service("tests/services/exception_service.py", monkeypatch) loop.run_until_complete(future) out, err = capsys.readouterr() assert "fail in _start_service()" in err
def test_non_named_same_named_sub_service_without_py_ending(monkeypatch: Any, capsys: Any, loop: Any) -> None: services, future = start_service('tests/services/test-copy/test-copy', monkeypatch) instance = services.get('test_dummy') assert instance is not None os.kill(os.getpid(), signal.SIGINT) loop.run_until_complete(future)
def test_non_decorated_service(monkeypatch: Any, capsys: Any, loop: Any) -> None: services, future = start_service('tests/services/non_decorated_service.py', monkeypatch) loop.run_until_complete(future) out, err = capsys.readouterr() assert 'No transports defined in service file' in err
def test_relative_import_service_without_py_ending(monkeypatch: Any, capsys: Any, loop: Any) -> None: services, future = start_service('tests/services/relative_service', monkeypatch) instance = services.get('test_relative') assert instance is not None os.kill(os.getpid(), signal.SIGINT) loop.run_until_complete(future)
def test_relative_import_service_without_py_ending(monkeypatch: Any, capsys: Any, loop: Any) -> None: services, future = start_service("tests/services/relative_service", monkeypatch) instance = services.get("test_relative") assert instance is not None async def _async_kill(): os.kill(os.getpid(), signal.SIGINT) loop.create_task(_async_kill()) loop.run_until_complete(future)
def test_non_named_same_named_sub_service_without_py_ending( monkeypatch: Any, capsys: Any, loop: Any) -> None: services, future = start_service("tests/services/test-copy/test-copy", monkeypatch) instance = services.get("test_dummy") assert instance is not None async def _async_kill(): os.kill(os.getpid(), signal.SIGINT) loop.create_task(_async_kill()) loop.run_until_complete(future)
def test_access_log(monkeypatch: Any, loop: Any) -> None: log_path = '/tmp/03c2ad00-d47d-4569-84a3-0958f88f6c14.log' logging.basicConfig(format='%(asctime)s (%(name)s): %(message)s', level=logging.INFO) logging.Formatter(fmt='%(asctime)s.%(msecs).03d', datefmt='%Y-%m-%d %H:%M:%S') services, future = start_service('tests/services/http_access_log_service.py', monkeypatch) instance = services.get('test_http') port = instance.context.get('_http_port') assert os.path.exists(log_path) is True with open(log_path) as file: content = file.read() assert content == 'Listening [http] on http://127.0.0.1:{}/\n'.format(port) async def _async(loop: Any) -> None: async with aiohttp.ClientSession(loop=loop) as client: await client.get('http://127.0.0.1:{}/test'.format(port)) with open(log_path) as file: content = file.read() assert '[http] [200] 127.0.0.1 - "GET /test HTTP/1.1" 4 -' in content assert '[http] [404] 127.0.0.1 - "GET /404 HTTP/1.1" 8 -' not in content async with aiohttp.ClientSession(loop=loop) as client: await client.get('http://127.0.0.1:{}/404'.format(port)) with open(log_path) as file: content = file.read() assert '[http] [200] 127.0.0.1 - "GET /test HTTP/1.1" 4 -' in content assert '[http] [404] 127.0.0.1 - "GET /404 HTTP/1.1" 8 -' in content async with aiohttp.ClientSession(loop=loop) as client: await client.post('http://127.0.0.1:{}/zero-post'.format(port), data=b'') with open(log_path) as file: content = file.read() assert '[http] [404] 127.0.0.1 - "POST /zero-post HTTP/1.1" 8 0' in content async with aiohttp.ClientSession(loop=loop) as client: await client.post('http://127.0.0.1:{}/post'.format(port), data=b'RANDOMDATA') with open(log_path) as file: content = file.read() assert '[http] [404] 127.0.0.1 - "POST /post HTTP/1.1" 8 10' in content with open(log_path) as file: content = file.read() assert content == 'Listening [http] on http://127.0.0.1:{}/\n'.format(port) loop.run_until_complete(_async(loop)) instance.stop_service() loop.run_until_complete(future) assert os.path.exists(log_path) is False
def test_start_http_service(monkeypatch: Any, capsys: Any, loop: Any) -> None: services, future = start_service("tests/services/http_service.py", monkeypatch) assert services is not None assert len(services) == 1 instance = services.get("test_http") assert instance is not None port = instance.context.get("_http_port") assert port is not None assert port != 0 assert instance.uuid is not None instance.stop_service() loop.run_until_complete(future)
def test_publish_invalid_credentials(monkeypatch: Any, capsys: Any, loop: Any) -> None: services, future = start_service('tests/services/dummy_service.py', monkeypatch) instance = services.get('test_dummy') with pytest.raises(AWSSNSSQSException): loop.run_until_complete(AWSSNSSQSTransport.publish(instance, 'data', 'test-topic', wait=True)) os.kill(os.getpid(), signal.SIGINT) loop.run_until_complete(future) out, err = capsys.readouterr() assert 'The security token included in the request is invalid' in err assert out == ''