From c5467b9f515538979be7fb6ab462b857527791f6 Mon Sep 17 00:00:00 2001 From: Christian Date: Tue, 8 Oct 2024 19:43:22 +0200 Subject: [PATCH] Initial automation of integration tests --- .gitignore | 4 +- example_apps/call_method_tcp.py | 15 ++- example_apps/call_method_udp.py | 21 +++- example_apps/offer_method_tcp.py | 15 ++- example_apps/offer_method_udp.py | 15 ++- example_apps/receive_events_tcp.py | 17 ++- .../CMakeLists.txt | 0 integration_tests/README.md | 24 +++++ .../automated_tests/call_method_tcp.py | 39 +++++++ .../automated_tests/call_method_udp.py | 39 +++++++ .../automated_tests/offer_method_tcp.py | 39 +++++++ .../automated_tests/offer_method_udp.py | 38 +++++++ .../offer_multiple_services.py | 42 ++++++++ .../automated_tests/receive_events_tcp.py | 49 +++++++++ .../automated_tests/receive_events_udp.py | 49 +++++++++ integration_tests/automated_tests/run_all.py | 44 ++++++++ .../automated_tests/send_events_tcp.py | 42 ++++++++ .../automated_tests/send_events_udp.py | 42 ++++++++ .../automated_tests/test_base.py | 100 ++++++++++++++++++ .../build_test_apps.sh | 0 .../call_method_tcp/call_method_tcp.cpp | 34 +++--- .../call_method_tcp/start_app.sh | 0 .../call_method_tcp/vsomeip-client.json | 0 .../call_method_udp/call_method_udp.cpp | 34 +++--- .../call_method_udp/start_app.sh | 0 .../call_method_udp/vsomeip-client.json | 0 .../offer_method_tcp/offer_method_tcp.cpp | 0 .../offer_method_tcp/start_app.sh | 0 .../offer_method_tcp/vsomeip-client.json | 0 .../offer_method_udp/offer_method_udp.cpp | 0 .../offer_method_udp/start_app.sh | 0 .../offer_method_udp/vsomeip-client.json | 0 .../offer_multiple_services.cpp | 0 .../offer_multiple_services/start_app.sh | 0 .../vsomeip-client.json | 0 .../receive_events_tcp/receive_events_tcp.cpp | 2 +- .../receive_events_tcp/start_app.sh | 0 .../receive_events_tcp/vsomeip-client.json | 0 .../receive_events_udp/receive_events_udp.cpp | 0 .../receive_events_udp/start_app.sh | 0 .../receive_events_udp/vsomeip-client.json | 0 .../send_events/send_events.cpp | 0 .../send_events/start_app.sh | 0 .../send_events/vsomeip-client.json | 0 setup.cfg | 2 +- src/someipy/_internal/someip_sd_option.py | 1 + src/someipy/client_service_instance.py | 2 +- src/someipy/service_discovery.py | 3 +- test_apps/README.md | 92 ---------------- 49 files changed, 645 insertions(+), 159 deletions(-) rename {test_apps => integration_tests}/CMakeLists.txt (100%) create mode 100644 integration_tests/README.md create mode 100644 integration_tests/automated_tests/call_method_tcp.py create mode 100644 integration_tests/automated_tests/call_method_udp.py create mode 100644 integration_tests/automated_tests/offer_method_tcp.py create mode 100644 integration_tests/automated_tests/offer_method_udp.py create mode 100644 integration_tests/automated_tests/offer_multiple_services.py create mode 100644 integration_tests/automated_tests/receive_events_tcp.py create mode 100644 integration_tests/automated_tests/receive_events_udp.py create mode 100644 integration_tests/automated_tests/run_all.py create mode 100644 integration_tests/automated_tests/send_events_tcp.py create mode 100644 integration_tests/automated_tests/send_events_udp.py create mode 100644 integration_tests/automated_tests/test_base.py rename {test_apps => integration_tests}/build_test_apps.sh (100%) mode change 100644 => 100755 rename {test_apps => integration_tests}/call_method_tcp/call_method_tcp.cpp (86%) rename {test_apps => integration_tests}/call_method_tcp/start_app.sh (100%) rename {test_apps => integration_tests}/call_method_tcp/vsomeip-client.json (100%) rename {test_apps => integration_tests}/call_method_udp/call_method_udp.cpp (86%) rename {test_apps => integration_tests}/call_method_udp/start_app.sh (100%) rename {test_apps => integration_tests}/call_method_udp/vsomeip-client.json (100%) rename {test_apps => integration_tests}/offer_method_tcp/offer_method_tcp.cpp (100%) rename {test_apps => integration_tests}/offer_method_tcp/start_app.sh (100%) rename {test_apps => integration_tests}/offer_method_tcp/vsomeip-client.json (100%) rename {test_apps => integration_tests}/offer_method_udp/offer_method_udp.cpp (100%) rename {test_apps => integration_tests}/offer_method_udp/start_app.sh (100%) rename {test_apps => integration_tests}/offer_method_udp/vsomeip-client.json (100%) rename {test_apps => integration_tests}/offer_multiple_services/offer_multiple_services.cpp (100%) rename {test_apps => integration_tests}/offer_multiple_services/start_app.sh (100%) rename {test_apps => integration_tests}/offer_multiple_services/vsomeip-client.json (100%) rename {test_apps => integration_tests}/receive_events_tcp/receive_events_tcp.cpp (99%) rename {test_apps => integration_tests}/receive_events_tcp/start_app.sh (100%) rename {test_apps => integration_tests}/receive_events_tcp/vsomeip-client.json (100%) rename {test_apps => integration_tests}/receive_events_udp/receive_events_udp.cpp (100%) rename {test_apps => integration_tests}/receive_events_udp/start_app.sh (100%) rename {test_apps => integration_tests}/receive_events_udp/vsomeip-client.json (100%) rename {test_apps => integration_tests}/send_events/send_events.cpp (100%) rename {test_apps => integration_tests}/send_events/start_app.sh (100%) rename {test_apps => integration_tests}/send_events/vsomeip-client.json (100%) delete mode 100644 test_apps/README.md diff --git a/.gitignore b/.gitignore index 8e9d16a..863f233 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,7 @@ venv/ *.whl -test_apps/build -test_apps/install +integration_tests/build +integration_tests/install build/ \ No newline at end of file diff --git a/example_apps/call_method_tcp.py b/example_apps/call_method_tcp.py index 7fea0ea..2042b96 100644 --- a/example_apps/call_method_tcp.py +++ b/example_apps/call_method_tcp.py @@ -1,6 +1,7 @@ import asyncio import ipaddress import logging +import sys from someipy import TransportLayerProtocol from someipy.client_service_instance import ( @@ -14,7 +15,7 @@ SD_MULTICAST_GROUP = "224.224.224.245" SD_PORT = 30490 -INTERFACE_IP = "127.0.0.1" +DEFAULT_INTERFACE_IP = "127.0.0.1" # Default IP if not provided SAMPLE_SERVICE_ID = 0x1234 SAMPLE_INSTANCE_ID = 0x5678 @@ -26,11 +27,19 @@ async def main(): # It's possible to configure the logging level of the someipy library, e.g. logging.INFO, logging.DEBUG, logging.WARN, .. set_someipy_log_level(logging.DEBUG) + # Get interface ip to use from command line argument (--interface_ip) or use default + interface_ip = DEFAULT_INTERFACE_IP + for i, arg in enumerate(sys.argv): + if arg == "--interface_ip": + if i + 1 < len(sys.argv): + interface_ip = sys.argv[i + 1] + break + # Since the construction of the class ServiceDiscoveryProtocol is not trivial and would require an async __init__ function # use the construct_service_discovery function # The local interface IP address needs to be passed so that the src-address of all SD UDP packets is correctly set service_discovery = await construct_service_discovery( - SD_MULTICAST_GROUP, SD_PORT, INTERFACE_IP + SD_MULTICAST_GROUP, SD_PORT, interface_ip ) addition_service = ( @@ -44,7 +53,7 @@ async def main(): client_instance_addition = await construct_client_service_instance( service=addition_service, instance_id=SAMPLE_INSTANCE_ID, - endpoint=(ipaddress.IPv4Address(INTERFACE_IP), 3002), + endpoint=(ipaddress.IPv4Address(interface_ip), 3002), ttl=5, sd_sender=service_discovery, protocol=TransportLayerProtocol.TCP, diff --git a/example_apps/call_method_udp.py b/example_apps/call_method_udp.py index 4971366..1cbdc38 100644 --- a/example_apps/call_method_udp.py +++ b/example_apps/call_method_udp.py @@ -1,6 +1,8 @@ import asyncio +import datetime import ipaddress import logging +import sys from someipy import TransportLayerProtocol from someipy.client_service_instance import ( @@ -14,7 +16,7 @@ SD_MULTICAST_GROUP = "224.224.224.245" SD_PORT = 30490 -INTERFACE_IP = "127.0.0.1" +DEFAULT_INTERFACE_IP = "127.0.0.1" # Default IP if not provided SAMPLE_SERVICE_ID = 0x1234 SAMPLE_INSTANCE_ID = 0x5678 @@ -26,11 +28,21 @@ async def main(): # It's possible to configure the logging level of the someipy library, e.g. logging.INFO, logging.DEBUG, logging.WARN, .. set_someipy_log_level(logging.DEBUG) + # Get interface ip to use from command line argument (--interface_ip) or use default + interface_ip = DEFAULT_INTERFACE_IP + for i, arg in enumerate(sys.argv): + if arg == "--interface_ip": + if i + 1 < len(sys.argv): + interface_ip = sys.argv[i + 1] + break + + print(interface_ip) + # Since the construction of the class ServiceDiscoveryProtocol is not trivial and would require an async __init__ function # use the construct_service_discovery function # The local interface IP address needs to be passed so that the src-address of all SD UDP packets is correctly set service_discovery = await construct_service_discovery( - SD_MULTICAST_GROUP, SD_PORT, INTERFACE_IP + SD_MULTICAST_GROUP, SD_PORT, interface_ip ) addition_service = ( @@ -44,7 +56,7 @@ async def main(): client_instance_addition = await construct_client_service_instance( service=addition_service, instance_id=SAMPLE_INSTANCE_ID, - endpoint=(ipaddress.IPv4Address(INTERFACE_IP), 3002), + endpoint=(ipaddress.IPv4Address(interface_ip), 3002), ttl=5, sd_sender=service_discovery, protocol=TransportLayerProtocol.UDP, @@ -56,7 +68,6 @@ async def main(): try: while True: - method_parameter = Addends(addend1=1, addend2=2) method_success, method_result = await client_instance_addition.call_method( SAMPLE_METHOD_ID, method_parameter.serialize() @@ -77,7 +88,7 @@ async def main(): elif method_success == MethodResult.SERVICE_NOT_FOUND: print("Service not yet available..") - await asyncio.sleep(2) + await asyncio.sleep(1) except asyncio.CancelledError: print("Shutdown..") finally: diff --git a/example_apps/offer_method_tcp.py b/example_apps/offer_method_tcp.py index dc692cd..f1d4856 100644 --- a/example_apps/offer_method_tcp.py +++ b/example_apps/offer_method_tcp.py @@ -1,6 +1,7 @@ import asyncio import ipaddress import logging +import sys from typing import Tuple from someipy import TransportLayerProtocol @@ -13,7 +14,7 @@ SD_MULTICAST_GROUP = "224.224.224.245" SD_PORT = 30490 -INTERFACE_IP = "127.0.0.1" +DEFAULT_INTERFACE_IP = "127.0.0.1" # Default IP if not provided SAMPLE_SERVICE_ID = 0x1234 SAMPLE_INSTANCE_ID = 0x5678 @@ -50,11 +51,19 @@ async def main(): # It's possible to configure the logging level of the someipy library, e.g. logging.INFO, logging.DEBUG, logging.WARN, .. set_someipy_log_level(logging.DEBUG) + # Get interface ip to use from command line argument (--interface_ip) or use default + interface_ip = DEFAULT_INTERFACE_IP + for i, arg in enumerate(sys.argv): + if arg == "--interface_ip": + if i + 1 < len(sys.argv): + interface_ip = sys.argv[i + 1] + break + # Since the construction of the class ServiceDiscoveryProtocol is not trivial and would require an async __init__ function # use the construct_service_discovery function # The local interface IP address needs to be passed so that the src-address of all SD UDP packets is correctly set service_discovery = await construct_service_discovery( - SD_MULTICAST_GROUP, SD_PORT, INTERFACE_IP + SD_MULTICAST_GROUP, SD_PORT, interface_ip ) addition_method = Method(id=SAMPLE_METHOD_ID, method_handler=add_method_handler) @@ -72,7 +81,7 @@ async def main(): addition_service, instance_id=SAMPLE_INSTANCE_ID, endpoint=( - ipaddress.IPv4Address(INTERFACE_IP), + ipaddress.IPv4Address(interface_ip), 3000, ), # src IP and port of the service ttl=5, diff --git a/example_apps/offer_method_udp.py b/example_apps/offer_method_udp.py index 2bf5bf7..728ff3d 100644 --- a/example_apps/offer_method_udp.py +++ b/example_apps/offer_method_udp.py @@ -1,6 +1,7 @@ import asyncio import ipaddress import logging +import sys from typing import Tuple from someipy import TransportLayerProtocol @@ -13,7 +14,7 @@ SD_MULTICAST_GROUP = "224.224.224.245" SD_PORT = 30490 -INTERFACE_IP = "127.0.0.1" +DEFAULT_INTERFACE_IP = "127.0.0.1" # Default IP if not provided SAMPLE_SERVICE_ID = 0x1234 SAMPLE_INSTANCE_ID = 0x5678 @@ -50,11 +51,19 @@ async def main(): # It's possible to configure the logging level of the someipy library, e.g. logging.INFO, logging.DEBUG, logging.WARN, .. set_someipy_log_level(logging.DEBUG) + # Get interface ip to use from command line argument (--interface_ip) or use default + interface_ip = DEFAULT_INTERFACE_IP + for i, arg in enumerate(sys.argv): + if arg == "--interface_ip": + if i + 1 < len(sys.argv): + interface_ip = sys.argv[i + 1] + break + # Since the construction of the class ServiceDiscoveryProtocol is not trivial and would require an async __init__ function # use the construct_service_discovery function # The local interface IP address needs to be passed so that the src-address of all SD UDP packets is correctly set service_discovery = await construct_service_discovery( - SD_MULTICAST_GROUP, SD_PORT, INTERFACE_IP + SD_MULTICAST_GROUP, SD_PORT, interface_ip ) addition_method = Method(id=SAMPLE_METHOD_ID, method_handler=add_method_handler) @@ -72,7 +81,7 @@ async def main(): addition_service, instance_id=SAMPLE_INSTANCE_ID, endpoint=( - ipaddress.IPv4Address(INTERFACE_IP), + ipaddress.IPv4Address(interface_ip), 3000, ), # src IP and port of the service ttl=5, diff --git a/example_apps/receive_events_tcp.py b/example_apps/receive_events_tcp.py index e617e36..46911df 100644 --- a/example_apps/receive_events_tcp.py +++ b/example_apps/receive_events_tcp.py @@ -1,6 +1,7 @@ import asyncio import ipaddress import logging +import sys from someipy import ServiceBuilder, EventGroup, TransportLayerProtocol, SomeIpMessage from someipy.service_discovery import construct_service_discovery @@ -10,7 +11,9 @@ SD_MULTICAST_GROUP = "224.224.224.245" SD_PORT = 30490 -INTERFACE_IP = "127.0.0.1" +DEFAULT_INTERFACE_IP = ( + "127.0.0.1" # default interface ip if not passed to the application +) SAMPLE_SERVICE_ID = 0x1234 SAMPLE_INSTANCE_ID = 0x5678 @@ -40,11 +43,19 @@ async def main(): # It's possible to configure the logging level of the someipy library, e.g. logging.INFO, logging.DEBUG, logging.WARN, .. set_someipy_log_level(logging.DEBUG) + # Get interface ip to use from command line argument (--interface_ip) or use default + interface_ip = DEFAULT_INTERFACE_IP + for i, arg in enumerate(sys.argv): + if arg == "--interface_ip": + if i + 1 < len(sys.argv): + interface_ip = sys.argv[i + 1] + break + # Since the construction of the class ServiceDiscoveryProtocol is not trivial and would require an async __init__ function # use the construct_service_discovery function # The local interface IP address needs to be passed so that the src-address of all SD UDP packets is correctly set service_discovery = await construct_service_discovery( - SD_MULTICAST_GROUP, SD_PORT, INTERFACE_IP + SD_MULTICAST_GROUP, SD_PORT, interface_ip ) # 1. For receiving events use a ClientServiceInstance. Since the construction of the class ClientServiceInstance is not @@ -67,7 +78,7 @@ async def main(): service_instance_temperature = await construct_client_service_instance( service=temperature_service, instance_id=SAMPLE_INSTANCE_ID, - endpoint=(ipaddress.IPv4Address(INTERFACE_IP), 3002), + endpoint=(ipaddress.IPv4Address(interface_ip), 3002), ttl=5, sd_sender=service_discovery, protocol=TransportLayerProtocol.TCP, diff --git a/test_apps/CMakeLists.txt b/integration_tests/CMakeLists.txt similarity index 100% rename from test_apps/CMakeLists.txt rename to integration_tests/CMakeLists.txt diff --git a/integration_tests/README.md b/integration_tests/README.md new file mode 100644 index 0000000..e04f7d9 --- /dev/null +++ b/integration_tests/README.md @@ -0,0 +1,24 @@ +# Integration Test Applications + +The integration test applications use the vsomeip library in order to stimulate the someipy applications. + +Each test application has a corresponding someipy example application, which are started together. The test applications can be either started manually or run automatically using the scripts `run_all.py` in `automated_tests`. The script will launch each pair of applications (a someipy app and a vsomeip app). After running both applications, the script will evaluate the logfiles. + +## Build Test Applications using CMake + +```bash +rm -rf build install && mkdir -p build && cd build && cmake .. && make && make install && cd .. +``` + +## Setup Python Pip Package from Source + +```bash +python3 -m pip install -e . +``` + +### Network Setup Linux + +```bash +sudo ip addr add 127.0.0.2/8 dev lo +sudo ip addr add 224.224.224.245 dev lo autojoin +``` diff --git a/integration_tests/automated_tests/call_method_tcp.py b/integration_tests/automated_tests/call_method_tcp.py new file mode 100644 index 0000000..c1b68c4 --- /dev/null +++ b/integration_tests/automated_tests/call_method_tcp.py @@ -0,0 +1,39 @@ +from test_base import TestBase + + +class TestCallMethodTcp(TestBase): + + def __init__(self, repository, ld_library_path=None, interface_ip="127.0.0.1"): + super().__init__() + + self.ld_library_path = ld_library_path + self.vsomeip_app = [ + f"{repository}/test_apps/install/call_method_tcp/call_method_tcp" + ] + self.someipy_app = [ + "python3", + f"{repository}/example_apps/call_method_tcp.py", + f"--interface_ip {interface_ip}", + ] + self.vsomeip_config = ( + f"{repository}/test_apps/install/call_method_tcp/vsomeip-client.json" + ) + + def evaluate(self) -> bool: + method_calls = 0 + responses = 0 + for l in self.output_someipy_app: + if "Received result for method" in l: + responses += 1 + if "Try to call method" in l: + method_calls += 1 + + print(f"Method calls: {method_calls}. Responses: {responses}") + difference = method_calls - responses + tolerance = max(0.1 * method_calls, 1) + if abs(difference) <= tolerance and method_calls > 0 and responses > 0: + return True + else: + print(f"Method calls: {method_calls}. Responses: {responses}") + self.print_outputs() + return False diff --git a/integration_tests/automated_tests/call_method_udp.py b/integration_tests/automated_tests/call_method_udp.py new file mode 100644 index 0000000..87c4276 --- /dev/null +++ b/integration_tests/automated_tests/call_method_udp.py @@ -0,0 +1,39 @@ +from test_base import TestBase + + +class TestCallMethodUdp(TestBase): + + def __init__(self, repository, ld_library_path=None, interface_ip="127.0.0.1"): + super().__init__() + + self.ld_library_path = ld_library_path + self.vsomeip_app = [ + f"{repository}/test_apps/install/call_method_udp/call_method_udp" + ] + self.someipy_app = [ + "python3", + f"{repository}/example_apps/call_method_udp.py", + f"--interface_ip {interface_ip}", + ] + self.vsomeip_config = ( + f"{repository}/test_apps/install/call_method_udp/vsomeip-client.json" + ) + + def evaluate(self) -> bool: + method_calls = 0 + responses = 0 + for l in self.output_someipy_app: + if "Received result for method" in l: + responses += 1 + if "Try to call method" in l: + method_calls += 1 + + print(f"Method calls: {method_calls}. Responses: {responses}") + difference = method_calls - responses + tolerance = max(0.1 * method_calls, 1) + if abs(difference) <= tolerance and method_calls > 0 and responses > 0: + return True + else: + print(f"Method calls: {method_calls}. Responses: {responses}") + self.print_outputs() + return False diff --git a/integration_tests/automated_tests/offer_method_tcp.py b/integration_tests/automated_tests/offer_method_tcp.py new file mode 100644 index 0000000..099cf96 --- /dev/null +++ b/integration_tests/automated_tests/offer_method_tcp.py @@ -0,0 +1,39 @@ +from test_base import TestBase + + +class TestOfferMethodTcp(TestBase): + + def __init__(self, repository, ld_library_path=None, interface_ip="127.0.0.1"): + super().__init__() + + self.ld_library_path = ld_library_path + self.vsomeip_app = [ + f"{repository}/test_apps/install/offer_method_tcp/offer_method_tcp" + ] + self.someipy_app = [ + "python3", + f"{repository}/example_apps/offer_method_tcp.py", + f"--interface_ip {interface_ip}", + ] + self.vsomeip_config = ( + f"{repository}/test_apps/install/offer_method_tcp/vsomeip-client.json" + ) + + def evaluate(self) -> bool: + method_calls = 0 + responses = 0 + for l in self.output_vsomeip_app: + if "Received a response from Service" in l: + responses += 1 + if "sent a request to Service" in l: + method_calls += 1 + + print(f"Method calls: {method_calls}. Responses: {responses}") + difference = method_calls - responses + tolerance = max(0.1 * method_calls, 1) + if abs(difference) <= tolerance and method_calls > 0 and responses > 0: + return True + else: + print(f"Method calls: {method_calls}. Responses: {responses}") + self.print_outputs() + return False diff --git a/integration_tests/automated_tests/offer_method_udp.py b/integration_tests/automated_tests/offer_method_udp.py new file mode 100644 index 0000000..e5995f2 --- /dev/null +++ b/integration_tests/automated_tests/offer_method_udp.py @@ -0,0 +1,38 @@ +from test_base import TestBase + + +class TestOfferMethodUdp(TestBase): + + def __init__(self, repository, ld_library_path=None, interface_ip="127.0.0.1"): + super().__init__() + + self.ld_library_path = ld_library_path + self.vsomeip_app = [ + f"{repository}/test_apps/install/offer_method_udp/offer_method_udp" + ] + self.someipy_app = [ + "python3", + f"{repository}/example_apps/offer_method_udp.py", + f"--interface_ip {interface_ip}", + ] + self.vsomeip_config = ( + f"{repository}/test_apps/install/offer_method_udp/vsomeip-client.json" + ) + + def evaluate(self) -> bool: + method_calls = 0 + responses = 0 + for l in self.output_vsomeip_app: + if "Received a response from Service" in l: + responses += 1 + if "sent a request to Service" in l: + method_calls += 1 + + print(f"Method calls: {method_calls}. Responses: {responses}") + difference = method_calls - responses + tolerance = max(0.1 * method_calls, 1) + if abs(difference) <= tolerance and method_calls > 0 and responses > 0: + return True + else: + self.print_outputs() + return False diff --git a/integration_tests/automated_tests/offer_multiple_services.py b/integration_tests/automated_tests/offer_multiple_services.py new file mode 100644 index 0000000..a0b9217 --- /dev/null +++ b/integration_tests/automated_tests/offer_multiple_services.py @@ -0,0 +1,42 @@ +from test_base import TestBase + + +class TestOfferMultipleServices(TestBase): + + def __init__(self, repository, ld_library_path=None, interface_ip="127.0.0.1"): + super().__init__() + + self.ld_library_path = ld_library_path + self.vsomeip_app = [ + f"{repository}/test_apps/install/offer_multiple_services/offer_multiple_services" + ] + self.someipy_app = [ + "python3", + f"{repository}/example_apps/offer_multiple_services.py", + f"--interface_ip {interface_ip}", + ] + self.vsomeip_config = f"{repository}/test_apps/install/offer_multiple_services/vsomeip-client.json" + + def evaluate(self) -> bool: + sent_events = 0 + received_events = 0 + for l in self.output_someipy_app: + if "Send event for instance" in l: + sent_events += 1 + + for l in self.output_vsomeip_app: + if "received a notification for event" in l: + received_events += 1 + + print(f"Received events: {received_events}. Sent events: {sent_events}") + difference_sent_received = sent_events - received_events + tolerance = max(0.1 * sent_events, 1) + if ( + abs(difference_sent_received) <= tolerance + and sent_events > 0 + and received_events > 0 + ): + return True + else: + self.print_outputs() + return False diff --git a/integration_tests/automated_tests/receive_events_tcp.py b/integration_tests/automated_tests/receive_events_tcp.py new file mode 100644 index 0000000..b67d27a --- /dev/null +++ b/integration_tests/automated_tests/receive_events_tcp.py @@ -0,0 +1,49 @@ +from test_base import TestBase +import re + + +class TestReceiveEventsTcp(TestBase): + + def __init__(self, repository, ld_library_path=None, interface_ip="127.0.0.1"): + super().__init__() + + self.ld_library_path = ld_library_path + self.vsomeip_app = [ + f"{repository}/test_apps/install/receive_events_tcp/receive_events_tcp" + ] + self.someipy_app = [ + "python3", + f"{repository}/example_apps/receive_events_tcp.py", + f"--interface_ip {interface_ip}", + ] + self.vsomeip_config = ( + f"{repository}/test_apps/install/receive_events_tcp/vsomeip-client.json" + ) + + def evaluate(self) -> bool: + sent_events = 0 + received_events = 0 + for l in self.output_someipy_app: + + received_bytes_pattern = r"Received (\d+) bytes" + match = re.search(received_bytes_pattern, l) + if match: + received_events += 1 + + for l in self.output_vsomeip_app: + if "Setting event" in l: + sent_events += 1 + + print(f"Received events: {received_events}. Sent events: {sent_events}") + difference_sent_received = sent_events - received_events + tolerance = max(0.1 * sent_events, 1) + if ( + abs(difference_sent_received) <= tolerance + and sent_events > 0 + and received_events > 0 + ): + return True + else: + print(f"Received events: {received_events}. Sent events: {sent_events}") + self.print_outputs() + return False diff --git a/integration_tests/automated_tests/receive_events_udp.py b/integration_tests/automated_tests/receive_events_udp.py new file mode 100644 index 0000000..43c7725 --- /dev/null +++ b/integration_tests/automated_tests/receive_events_udp.py @@ -0,0 +1,49 @@ +from test_base import TestBase +import re + + +class TestReceiveEventsUdp(TestBase): + + def __init__(self, repository, ld_library_path=None, interface_ip="127.0.0.1"): + super().__init__() + + self.ld_library_path = ld_library_path + self.vsomeip_app = [ + f"{repository}/test_apps/install/receive_events_udp/receive_events_udp" + ] + self.someipy_app = [ + "python3", + f"{repository}/example_apps/receive_events_udp.py", + f"--interface_ip {interface_ip}", + ] + self.vsomeip_config = ( + f"{repository}/test_apps/install/receive_events_udp/vsomeip-client.json" + ) + + def evaluate(self) -> bool: + sent_events = 0 + received_events = 0 + for l in self.output_someipy_app: + + received_bytes_pattern = r"Received (\d+) bytes" + match = re.search(received_bytes_pattern, l) + if match: + received_events += 1 + + for l in self.output_vsomeip_app: + if "Setting event" in l: + sent_events += 1 + + print(f"Received events: {received_events}. Sent events: {sent_events}") + difference_sent_received = sent_events - received_events + tolerance = max(0.1 * sent_events, 1) + if ( + abs(difference_sent_received) <= tolerance + and sent_events > 0 + and received_events > 0 + ): + return True + else: + print(f"Received events: {received_events}. Sent events: {sent_events}") + self.print_outputs() + return False diff --git a/integration_tests/automated_tests/run_all.py b/integration_tests/automated_tests/run_all.py new file mode 100644 index 0000000..f641667 --- /dev/null +++ b/integration_tests/automated_tests/run_all.py @@ -0,0 +1,44 @@ +import time +from send_events_udp import TestSendEventsUdp +from send_events_tcp import TestSendEventsTcp +from receive_events_udp import TestReceiveEventsUdp +from receive_events_tcp import TestReceiveEventsTcp +from call_method_udp import TestCallMethodUdp +from call_method_tcp import TestCallMethodTcp +from offer_method_udp import TestOfferMethodUdp +from offer_method_tcp import TestOfferMethodTcp +from offer_multiple_services import TestOfferMultipleServices +import os + +vsomeip_library_path = "" +current_file_path = os.path.abspath(__file__) +repository = os.path.dirname(os.path.dirname(current_file_path)) +repository = os.path.dirname(os.path.dirname(os.path.dirname(current_file_path))) +test_durations = 10 # duration of each test in seconds + +tests = { + "send_events_udp": TestSendEventsUdp, + "send_events_tcp": TestSendEventsTcp, + "receive_events_udp": TestReceiveEventsUdp, + "receive_events_tcp": TestReceiveEventsTcp, + "call_method_udp": TestCallMethodUdp, + "call_method_tcp": TestCallMethodTcp, + "offer_method_udp": TestOfferMethodUdp, + "offer_method_tcp": TestOfferMethodTcp, + "offer_multiple_services": TestOfferMultipleServices, +} + +test_summary = {} + +for test_name, test_class in tests.items(): + print(f"Starting test: {test_name}") + test = test_class(repository, ld_library_path=vsomeip_library_path) + test.run(test_durations) + success = test.evaluate() + print(f"{test_name}: {'Success' if success else 'Failure'}\n---\n") + test_summary[test_name] = success + time.sleep(1) + +print("\n\nTest summary:") +for test_name, success in test_summary.items(): + print(f"{test_name}:\t\t{'Success' if success else 'Failure'}") diff --git a/integration_tests/automated_tests/send_events_tcp.py b/integration_tests/automated_tests/send_events_tcp.py new file mode 100644 index 0000000..3ab433e --- /dev/null +++ b/integration_tests/automated_tests/send_events_tcp.py @@ -0,0 +1,42 @@ +from test_base import TestBase + + +class TestSendEventsTcp(TestBase): + + def __init__(self, repository, ld_library_path=None, interface_ip="127.0.0.1"): + super().__init__() + + self.ld_library_path = ld_library_path + self.vsomeip_app = [f"{repository}/test_apps/install/send_events/send_events"] + self.someipy_app = [ + "python3", + f"{repository}/example_apps/send_events_tcp.py", + f"--interface_ip {interface_ip}", + ] + self.vsomeip_config = ( + f"{repository}/test_apps/install/send_events/vsomeip-client.json" + ) + + def evaluate(self) -> bool: + sent_events = 0 + received_events = 0 + for l in self.output_someipy_app: + if "Send event for instance" in l: + sent_events += 1 + + for l in self.output_vsomeip_app: + if "received a notification for event" in l: + received_events += 1 + + print(f"Received events: {received_events}. Sent events: {sent_events}") + difference_sent_received = sent_events - received_events + tolerance = max(0.1 * sent_events, 1) + if ( + abs(difference_sent_received) <= tolerance + and sent_events > 0 + and received_events > 0 + ): + return True + else: + self.print_outputs() + return False diff --git a/integration_tests/automated_tests/send_events_udp.py b/integration_tests/automated_tests/send_events_udp.py new file mode 100644 index 0000000..9a648fc --- /dev/null +++ b/integration_tests/automated_tests/send_events_udp.py @@ -0,0 +1,42 @@ +from test_base import TestBase + + +class TestSendEventsUdp(TestBase): + + def __init__(self, repository, ld_library_path=None, interface_ip="127.0.0.1"): + super().__init__() + + self.ld_library_path = ld_library_path + self.vsomeip_app = [f"{repository}/test_apps/install/send_events/send_events"] + self.someipy_app = [ + "python3", + f"{repository}/example_apps/send_events_udp.py", + f"--interface_ip {interface_ip}", + ] + self.vsomeip_config = ( + f"{repository}/test_apps/install/send_events/vsomeip-client.json" + ) + + def evaluate(self) -> bool: + sent_events = 0 + received_events = 0 + for l in self.output_someipy_app: + if "Send event for instance" in l: + sent_events += 1 + + for l in self.output_vsomeip_app: + if "received a notification for event" in l: + received_events += 1 + + print(f"Received events: {received_events}. Sent events: {sent_events}") + difference_sent_received = sent_events - received_events + tolerance = max(0.1 * sent_events, 1) + if ( + abs(difference_sent_received) <= tolerance + and sent_events > 0 + and received_events > 0 + ): + return True + else: + self.print_outputs() + return False diff --git a/integration_tests/automated_tests/test_base.py b/integration_tests/automated_tests/test_base.py new file mode 100644 index 0000000..0745fb2 --- /dev/null +++ b/integration_tests/automated_tests/test_base.py @@ -0,0 +1,100 @@ +import subprocess +import time +import fcntl +import os +import signal +import threading +import queue +import select +from abc import abstractmethod + + +class TestBase: + def __init__(self): + self.ld_library_path = None + self.vsomeip_app = None + self.vsomeip_config = None + self.someipy_app = None + + self.output_someipy_app = None + self.output_vsomeip_app = None + + @abstractmethod + def evaluate(self) -> bool: + pass + + def run(self, duration=5): + env = dict(os.environ, VSOMEIP_CONFIGURATION=self.vsomeip_config) + if self.ld_library_path is not None: + env["LD_LIBRARY_PATH"] = self.ld_library_path + + thread_vsomeip, output_queue_vsomeip = self.run_in_thread( + self.vsomeip_app, duration, env + ) + + thread_python, output_queue_python = self.run_in_thread( + self.someipy_app, duration, env + ) + + thread_vsomeip.start() + thread_python.start() + thread_vsomeip.join() + thread_python.join() + + self.output_vsomeip_app = list(output_queue_vsomeip.queue) + self.output_someipy_app = list(output_queue_python.queue) + + def start_process(self, command, output_queue, env, timeout=5): + """Starts a subprocess and puts its stdout lines in a queue.""" + process = subprocess.Popen( + command, shell=False, stdout=subprocess.PIPE, env=env + ) + + # Set non-blocking mode for stdout + fcntl.fcntl(process.stdout.fileno(), fcntl.F_SETFL, os.O_NONBLOCK) + + # Collect output for timeout seconds + start_time = time.time() + while time.time() - start_time < timeout: + readable, _, _ = select.select( + [process.stdout], [], [], 0.1 + ) # Non-blocking read with timeout + if readable: + line = process.stdout.readline().decode().strip() + if line: + output_queue.put(line) + else: + break # No more output available + + process.send_signal(signal.SIGINT) + + # Collect output for 1 seconds after sending the sigint + start_time = time.time() + while time.time() - start_time < 1: + readable, _, _ = select.select( + [process.stdout], [], [], 0.1 + ) # Non-blocking read with timeout + if readable: + line = process.stdout.readline().decode().strip() + if line: + output_queue.put(line) + else: + break # No more output available + + process.wait() + + def run_in_thread(self, command, duration, env): + output_queue = queue.Queue() + thread = threading.Thread( + target=TestBase.start_process, + args=(self, command, output_queue, env, duration), + ) + return thread, output_queue + + def print_outputs(self): + print("-------- Output from someipy app --------") + for l in self.output_someipy_app: + print(l) + print("-------- Output from vsomeip app --------") + for l in self.output_vsomeip_app: + print(l) diff --git a/test_apps/build_test_apps.sh b/integration_tests/build_test_apps.sh old mode 100644 new mode 100755 similarity index 100% rename from test_apps/build_test_apps.sh rename to integration_tests/build_test_apps.sh diff --git a/test_apps/call_method_tcp/call_method_tcp.cpp b/integration_tests/call_method_tcp/call_method_tcp.cpp similarity index 86% rename from test_apps/call_method_tcp/call_method_tcp.cpp rename to integration_tests/call_method_tcp/call_method_tcp.cpp index 6e704af..c3e48e1 100644 --- a/test_apps/call_method_tcp/call_method_tcp.cpp +++ b/integration_tests/call_method_tcp/call_method_tcp.cpp @@ -38,9 +38,6 @@ class service_sample { SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_METHOD_ID, std::bind(&service_sample::on_message, this, std::placeholders::_1)); - - std::cout << "Static routing " << (use_static_routing_ ? "ON" : "OFF") - << std::endl; return true; } @@ -90,7 +87,17 @@ class service_sample { } void on_message(const std::shared_ptr &_request) { - std::cout << "Received a message with Client/Session [" + // Log the current time. + auto now = std::chrono::system_clock::now(); + auto now_time_t = std::chrono::system_clock::to_time_t(now); + auto now_ms = std::chrono::duration_cast( + now.time_since_epoch()).count(); + auto now_ms_remainder = now_ms % 1000; + auto now_tm = std::localtime(&now_time_t); + std::stringstream now_ss; + now_ss << std::put_time(now_tm, "%Y-%m-%d %H:%M:%S") << "." + << std::setfill('0') << std::setw(3) << now_ms_remainder; + std::cout << now_ss.str() << " Received a message with Client/Session [" << std::setfill('0') << std::hex << std::setw(4) << _request->get_client() << "/" << std::setw(4) << _request->get_session() << "]" @@ -114,24 +121,7 @@ class service_sample { std::unique_lock its_lock(mutex_); while (!blocked_) condition_.wait(its_lock); - - bool is_offer(true); - - if (use_static_routing_) { - offer(); - while (running_); - } else { - while (running_) { - if (is_offer) - offer(); - else - stop_offer(); - - for (int i = 0; i < 10 && running_; i++) - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - is_offer = !is_offer; - } - } + offer(); } private: diff --git a/test_apps/call_method_tcp/start_app.sh b/integration_tests/call_method_tcp/start_app.sh similarity index 100% rename from test_apps/call_method_tcp/start_app.sh rename to integration_tests/call_method_tcp/start_app.sh diff --git a/test_apps/call_method_tcp/vsomeip-client.json b/integration_tests/call_method_tcp/vsomeip-client.json similarity index 100% rename from test_apps/call_method_tcp/vsomeip-client.json rename to integration_tests/call_method_tcp/vsomeip-client.json diff --git a/test_apps/call_method_udp/call_method_udp.cpp b/integration_tests/call_method_udp/call_method_udp.cpp similarity index 86% rename from test_apps/call_method_udp/call_method_udp.cpp rename to integration_tests/call_method_udp/call_method_udp.cpp index 6e704af..c3e48e1 100644 --- a/test_apps/call_method_udp/call_method_udp.cpp +++ b/integration_tests/call_method_udp/call_method_udp.cpp @@ -38,9 +38,6 @@ class service_sample { SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_METHOD_ID, std::bind(&service_sample::on_message, this, std::placeholders::_1)); - - std::cout << "Static routing " << (use_static_routing_ ? "ON" : "OFF") - << std::endl; return true; } @@ -90,7 +87,17 @@ class service_sample { } void on_message(const std::shared_ptr &_request) { - std::cout << "Received a message with Client/Session [" + // Log the current time. + auto now = std::chrono::system_clock::now(); + auto now_time_t = std::chrono::system_clock::to_time_t(now); + auto now_ms = std::chrono::duration_cast( + now.time_since_epoch()).count(); + auto now_ms_remainder = now_ms % 1000; + auto now_tm = std::localtime(&now_time_t); + std::stringstream now_ss; + now_ss << std::put_time(now_tm, "%Y-%m-%d %H:%M:%S") << "." + << std::setfill('0') << std::setw(3) << now_ms_remainder; + std::cout << now_ss.str() << " Received a message with Client/Session [" << std::setfill('0') << std::hex << std::setw(4) << _request->get_client() << "/" << std::setw(4) << _request->get_session() << "]" @@ -114,24 +121,7 @@ class service_sample { std::unique_lock its_lock(mutex_); while (!blocked_) condition_.wait(its_lock); - - bool is_offer(true); - - if (use_static_routing_) { - offer(); - while (running_); - } else { - while (running_) { - if (is_offer) - offer(); - else - stop_offer(); - - for (int i = 0; i < 10 && running_; i++) - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - is_offer = !is_offer; - } - } + offer(); } private: diff --git a/test_apps/call_method_udp/start_app.sh b/integration_tests/call_method_udp/start_app.sh similarity index 100% rename from test_apps/call_method_udp/start_app.sh rename to integration_tests/call_method_udp/start_app.sh diff --git a/test_apps/call_method_udp/vsomeip-client.json b/integration_tests/call_method_udp/vsomeip-client.json similarity index 100% rename from test_apps/call_method_udp/vsomeip-client.json rename to integration_tests/call_method_udp/vsomeip-client.json diff --git a/test_apps/offer_method_tcp/offer_method_tcp.cpp b/integration_tests/offer_method_tcp/offer_method_tcp.cpp similarity index 100% rename from test_apps/offer_method_tcp/offer_method_tcp.cpp rename to integration_tests/offer_method_tcp/offer_method_tcp.cpp diff --git a/test_apps/offer_method_tcp/start_app.sh b/integration_tests/offer_method_tcp/start_app.sh similarity index 100% rename from test_apps/offer_method_tcp/start_app.sh rename to integration_tests/offer_method_tcp/start_app.sh diff --git a/test_apps/offer_method_tcp/vsomeip-client.json b/integration_tests/offer_method_tcp/vsomeip-client.json similarity index 100% rename from test_apps/offer_method_tcp/vsomeip-client.json rename to integration_tests/offer_method_tcp/vsomeip-client.json diff --git a/test_apps/offer_method_udp/offer_method_udp.cpp b/integration_tests/offer_method_udp/offer_method_udp.cpp similarity index 100% rename from test_apps/offer_method_udp/offer_method_udp.cpp rename to integration_tests/offer_method_udp/offer_method_udp.cpp diff --git a/test_apps/offer_method_udp/start_app.sh b/integration_tests/offer_method_udp/start_app.sh similarity index 100% rename from test_apps/offer_method_udp/start_app.sh rename to integration_tests/offer_method_udp/start_app.sh diff --git a/test_apps/offer_method_udp/vsomeip-client.json b/integration_tests/offer_method_udp/vsomeip-client.json similarity index 100% rename from test_apps/offer_method_udp/vsomeip-client.json rename to integration_tests/offer_method_udp/vsomeip-client.json diff --git a/test_apps/offer_multiple_services/offer_multiple_services.cpp b/integration_tests/offer_multiple_services/offer_multiple_services.cpp similarity index 100% rename from test_apps/offer_multiple_services/offer_multiple_services.cpp rename to integration_tests/offer_multiple_services/offer_multiple_services.cpp diff --git a/test_apps/offer_multiple_services/start_app.sh b/integration_tests/offer_multiple_services/start_app.sh similarity index 100% rename from test_apps/offer_multiple_services/start_app.sh rename to integration_tests/offer_multiple_services/start_app.sh diff --git a/test_apps/offer_multiple_services/vsomeip-client.json b/integration_tests/offer_multiple_services/vsomeip-client.json similarity index 100% rename from test_apps/offer_multiple_services/vsomeip-client.json rename to integration_tests/offer_multiple_services/vsomeip-client.json diff --git a/test_apps/receive_events_tcp/receive_events_tcp.cpp b/integration_tests/receive_events_tcp/receive_events_tcp.cpp similarity index 99% rename from test_apps/receive_events_tcp/receive_events_tcp.cpp rename to integration_tests/receive_events_tcp/receive_events_tcp.cpp index 4b5111c..1afb49d 100644 --- a/test_apps/receive_events_tcp/receive_events_tcp.cpp +++ b/integration_tests/receive_events_tcp/receive_events_tcp.cpp @@ -51,7 +51,7 @@ void run() { payload_->set_data(its_data, its_size); std::cout << "Setting event (Length=" << std::dec << its_size << ")." << std::endl; app_->notify(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENT_ID, payload_); - std::this_thread::sleep_for(std::chrono::milliseconds(5000)); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); } } diff --git a/test_apps/receive_events_tcp/start_app.sh b/integration_tests/receive_events_tcp/start_app.sh similarity index 100% rename from test_apps/receive_events_tcp/start_app.sh rename to integration_tests/receive_events_tcp/start_app.sh diff --git a/test_apps/receive_events_tcp/vsomeip-client.json b/integration_tests/receive_events_tcp/vsomeip-client.json similarity index 100% rename from test_apps/receive_events_tcp/vsomeip-client.json rename to integration_tests/receive_events_tcp/vsomeip-client.json diff --git a/test_apps/receive_events_udp/receive_events_udp.cpp b/integration_tests/receive_events_udp/receive_events_udp.cpp similarity index 100% rename from test_apps/receive_events_udp/receive_events_udp.cpp rename to integration_tests/receive_events_udp/receive_events_udp.cpp diff --git a/test_apps/receive_events_udp/start_app.sh b/integration_tests/receive_events_udp/start_app.sh similarity index 100% rename from test_apps/receive_events_udp/start_app.sh rename to integration_tests/receive_events_udp/start_app.sh diff --git a/test_apps/receive_events_udp/vsomeip-client.json b/integration_tests/receive_events_udp/vsomeip-client.json similarity index 100% rename from test_apps/receive_events_udp/vsomeip-client.json rename to integration_tests/receive_events_udp/vsomeip-client.json diff --git a/test_apps/send_events/send_events.cpp b/integration_tests/send_events/send_events.cpp similarity index 100% rename from test_apps/send_events/send_events.cpp rename to integration_tests/send_events/send_events.cpp diff --git a/test_apps/send_events/start_app.sh b/integration_tests/send_events/start_app.sh similarity index 100% rename from test_apps/send_events/start_app.sh rename to integration_tests/send_events/start_app.sh diff --git a/test_apps/send_events/vsomeip-client.json b/integration_tests/send_events/vsomeip-client.json similarity index 100% rename from test_apps/send_events/vsomeip-client.json rename to integration_tests/send_events/vsomeip-client.json diff --git a/setup.cfg b/setup.cfg index 6800d2f..74c88c9 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = someipy -version = 0.0.6 +version = 0.0.7 author = Christian H. author_email = someipy.package@gmail.com description = A Python package implementing the SOME/IP protocol diff --git a/src/someipy/_internal/someip_sd_option.py b/src/someipy/_internal/someip_sd_option.py index 3546b3f..f422886 100644 --- a/src/someipy/_internal/someip_sd_option.py +++ b/src/someipy/_internal/someip_sd_option.py @@ -34,6 +34,7 @@ class SdOptionType(Enum): IPV4_MULTICAST = 0x14 # TODO: not implemented IPV6_MULTICAST = 0x16 # TODO: not implemented IPV4_SD_ENDPOINT = 0x24 # TODO: not implemented + IPV6_SD_ENDPOINT = 0x26 # TODO: not implemented @dataclass diff --git a/src/someipy/client_service_instance.py b/src/someipy/client_service_instance.py index f1c9fbf..c0195cd 100644 --- a/src/someipy/client_service_instance.py +++ b/src/someipy/client_service_instance.py @@ -142,7 +142,7 @@ def register_callback(self, callback: Callable[[SomeIpMessage], None]) -> None: async def call_method( self, method_id: int, payload: bytes ) -> Tuple[MethodResult, bytes]: - + get_logger(_logger_name).debug(f"Try to call method 0x{method_id:04X}") has_service = False for s in self._found_services: if ( diff --git a/src/someipy/service_discovery.py b/src/someipy/service_discovery.py index b752261..1354d94 100644 --- a/src/someipy/service_discovery.py +++ b/src/someipy/service_discovery.py @@ -257,7 +257,8 @@ def _handle_subscribe_ack_eventgroup_entry( get_logger(_logger_name).debug( f"Received subscribe ACK for instance 0x{event_group_entry.sd_entry.instance_id:04X}, service 0x{event_group_entry.sd_entry.service_id:04X}, eventgroup 0x{event_group_entry.eventgroup_id:04X}" ) - # TODO: Implement subscription ACK handling + for o in self.attached_observers: + o.handle_subscribe_ack_eventgroup(event_group_entry) async def construct_service_discovery( diff --git a/test_apps/README.md b/test_apps/README.md deleted file mode 100644 index 898b98a..0000000 --- a/test_apps/README.md +++ /dev/null @@ -1,92 +0,0 @@ -# Test Applications - -The test applications can be used for contributions to someipy. The test applications use the vsomeip library in order to stimulate the someipy applications. - -## Build Test Applications using CMake - -```bash -rm -rf build install && mkdir -p build && cd build && cmake .. && make && make install && cd .. -``` - -## Setup Python Pip Package from Source - -```bash -python3 -m pip install -e . -``` - -## Test Procedure - -### Network Setup Linux - -```bash -sudo ip addr add 127.0.0.2/8 dev lo -sudo ip addr add 224.224.224.245 dev lo autojoin -``` - -### 1. send_events_udp - -Open two terminals (one for Python someipy example app, one for test app). - -Start apps: - -```bash -python3 send_events_udp.py -bash ./install/send_events/start_app.sh -``` - -Expected in test app: -- Expected log for UDP endpoint on port 3000: - - *endpoint_manager_impl::create_remote_client: 127.0.0.1:3000 reliable: 0 using local port: 0* - - *udp_client_endpoint_impl::connect: SO_RCVBUF is: 212992 (1703936) local port:0 remote:127.0.0.1:3000* -- Receive event with frequency 1Hz -- Service ID: 0x1234 -- Instance ID: 0x5678 -- Eventgroup ID: 0x0321 -- Event ID: 0x0123 -- SD Offer is sent with 0.5Hz - - -### 2. send_events_tcp - -Open two terminals (one for Python someipy example app, one for test app). - -Start apps: - -```bash -python3 send_events_tcp.py -bash ./install/send_events/start_app.sh -``` - -Expected in test app: -- Expected log for TCP endpoint on port 3000: - - *endpoint_manager_impl::create_remote_client: 127.0.0.1:3000 reliable: 1 using local port: 0* - - Check for "reliable == 1" in above log (i.e. TCP) - - No "udp_client_endpoint_impl::connect" shall appear -- Receive event with frequency 1Hz -- Service ID: 0x1234 -- Instance ID: 0x5678 -- Eventgroup ID: 0x0321 -- Event ID: 0x0123 -- SD Offer is sent with 0.5Hz - -### 3. receive_events_udp - -Open two terminals (one for Python someipy example app, one for test app). - -Start apps: - -```bash -python3 receive_events_udp.py -bash install/receive_events_udp/start_app.sh -``` - -Expected in test app: -- Expected log for UDP endpoint: REMOTE SUBSCRIBE(0000): [1234.5678.0321] from 127.0.0.1:3002 unreliable was accepted - -Expected in example app: -- Receive event with frequency 1Hz -- Service ID: 0x1234 -- Instance ID: 0x5678 -- Eventgroup ID: 0x0321 -- Event ID: 0x0123 -- SD Offer is sent with 0.5Hz \ No newline at end of file