diff options
author | Diogo Pedrosa <diogo12pedrosa@gmail.com> | 2023-03-09 17:57:35 +0000 |
---|---|---|
committer | Diogo Pedrosa <diogo12pedrosa@gmail.com> | 2023-03-10 14:41:51 +0000 |
commit | 826ebb8d352245a36ecaec32b6af61e7abf4696e (patch) | |
tree | d4e984dd100f3257ce784c9e30aefb6e60a93ab5 /test/network_tests/payload_tests | |
parent | fc73f40fa1501dc53210c63cb7c0d7623d106370 (diff) | |
download | vSomeIP-826ebb8d352245a36ecaec32b6af61e7abf4696e.tar.gz |
vsomeip 3.3.0
Diffstat (limited to 'test/network_tests/payload_tests')
22 files changed, 1570 insertions, 0 deletions
diff --git a/test/network_tests/payload_tests/conf/external_local_payload_test_client_external.json.in b/test/network_tests/payload_tests/conf/external_local_payload_test_client_external.json.in new file mode 100644 index 0000000..0abaea2 --- /dev/null +++ b/test/network_tests/payload_tests/conf/external_local_payload_test_client_external.json.in @@ -0,0 +1,53 @@ +{ + "unicast" : "@TEST_IP_SLAVE@", + "netmask" : "255.255.255.0", + "logging" : + { + "level" : "debug", + "console" : "true", + "file" : + { + "enable" : "true", + "path" : "/var/log/vsomeip.log" + }, + + "dlt" : "true" + }, + + "applications" : + [ + { + "name" : "external_local_payload_test_client_external", + "id" : "0x1343" + } + ], + + "services" : + [ + { + "service" : "0x1234", + "instance" : "0x5678", + "unicast" : "@TEST_IP_MASTER@", + "unreliable" : "30509", + "reliable" : + { + "port" : "30510", + "enable-magic-cookies" : "false" + } + } + ], + "npdu-default-timings" : { + "debounce-time-request" : "0", + "debounce-time-response" : "0", + "max-retention-time-request" : "0", + "max-retention-time-response" : "0" + }, + "routing" : "external_local_payload_test_client_external", + "service-discovery" : + { + "enable" : "false", + "multicast" : "224.0.0.1", + "port" : "30491", + "protocol" : "udp" + } +} diff --git a/test/network_tests/payload_tests/conf/external_local_payload_test_client_local.json.in b/test/network_tests/payload_tests/conf/external_local_payload_test_client_local.json.in new file mode 100644 index 0000000..1f4fd6d --- /dev/null +++ b/test/network_tests/payload_tests/conf/external_local_payload_test_client_local.json.in @@ -0,0 +1,54 @@ +{ + "unicast" : "@TEST_IP_MASTER@", + "netmask" : "255.255.255.0", + "logging" : + { + "level" : "debug", + "console" : "true", + "file" : + { + "enable" : "true", + "path" : "/var/log/vsomeip.log" + }, + + "dlt" : "true" + }, + + "applications" : + [ + { + "name" : "external_local_payload_test_client_local", + "id" : "0x1343" + } + ], + + + "services" : + [ + { + "service" : "0x1234", + "instance" : "0x5678", + "unicast" : "@TEST_IP_MASTER@", + "unreliable" : "30509", + "reliable" : + { + "port" : "30510", + "enable-magic-cookies" : "false" + } + } + ], + "npdu-default-timings" : { + "debounce-time-request" : "0", + "debounce-time-response" : "0", + "max-retention-time-request" : "0", + "max-retention-time-response" : "0" + }, + "routing" : "external_local_payload_test_service", + "service-discovery" : + { + "enable" : "false", + "multicast" : "224.0.0.1", + "port" : "30491", + "protocol" : "udp" + } +} diff --git a/test/network_tests/payload_tests/conf/external_local_payload_test_service.json.in b/test/network_tests/payload_tests/conf/external_local_payload_test_service.json.in new file mode 100644 index 0000000..aaeae82 --- /dev/null +++ b/test/network_tests/payload_tests/conf/external_local_payload_test_service.json.in @@ -0,0 +1,51 @@ +{ + "unicast" : "@TEST_IP_MASTER@", + "logging" : + { + "level" : "debug", + "console" : "true", + "file" : + { + "enable" : "false", + "path" : "/tmp/vsomeip.log" + }, + + "dlt" : "false" + }, + + "applications" : + [ + { + "name" : "external_local_payload_test_service", + "id" : "0x1277" + } + ], + + "services" : + [ + { + "service" : "0x1234", + "instance" : "0x5678", + "unreliable" : "30509", + "reliable" : + { + "port" : "30510", + "enable-magic-cookies" : "false" + } + } + ], + "npdu-default-timings" : { + "debounce-time-request" : "0", + "debounce-time-response" : "0", + "max-retention-time-request" : "0", + "max-retention-time-response" : "0" + }, + "routing" : "external_local_payload_test_service", + "service-discovery" : + { + "enable" : "false", + "multicast" : "224.0.0.1", + "port" : "30490", + "protocol" : "udp" + } +} diff --git a/test/network_tests/payload_tests/external_local_payload_test_client_external_start.sh b/test/network_tests/payload_tests/external_local_payload_test_client_external_start.sh new file mode 100755 index 0000000..5f6b7ea --- /dev/null +++ b/test/network_tests/payload_tests/external_local_payload_test_client_external_start.sh @@ -0,0 +1,13 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +export VSOMEIP_APPLICATION_NAME=external_local_payload_test_client_external +export VSOMEIP_CONFIGURATION=external_local_payload_test_client_external.json +./payload_test_client --udp --max-payload-size UDP +# We sleep to let the service restart with --tcp option so we can test +# communication via TCP. +sleep 5 +./payload_test_client --tcp --max-payload-size TCP diff --git a/test/network_tests/payload_tests/external_local_payload_test_client_external_starter.sh b/test/network_tests/payload_tests/external_local_payload_test_client_external_starter.sh new file mode 100755 index 0000000..af044cf --- /dev/null +++ b/test/network_tests/payload_tests/external_local_payload_test_client_external_starter.sh @@ -0,0 +1,121 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the client and service with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start two binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs client +# and service and checks that both exit sucessfully. + +FAIL=0 + +# Parameter 1: the pid to check +# Parameter 2: number of TCP/UDP sockets the process should have open +check_tcp_udp_sockets_are_open () +{ + # Check that the passed pid/process does listen on at least one TCP/UDP socket + # awk is used to avoid the case when a inode number is the same as a PID. The awk + # program filters the netstat output down to the protocol (1st field) and + # the PID/Program name (last field) fields. + SERVICE_SOCKETS_LISTENING=$(netstat -tulpen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) + if [ $SERVICE_SOCKETS_LISTENING -lt $2 ] + then + ((FAIL+=1)) + fi +} + +# Parameter 1: the pid to check +check_tcp_udp_sockets_are_closed () +{ + # Check that the passed pid/process does not listen on any TCP/UDP socket + # or has any active connection via a TCP/UDP socket + # awk is used to avoid the case when a inode number is the same as a PID. The awk + # program filters the netstat output down to the protocol (1st field) and + # the PID/Program name (last field) fields. + SERVICE_SOCKETS_LISTENING=$(netstat -tulpen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) + if [ $SERVICE_SOCKETS_LISTENING -ne 0 ] + then + ((FAIL+=1)) + fi + + SERVICE_SOCKETS_CONNECTED=$(netstat -tupen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) + if [ $SERVICE_SOCKETS_CONNECTED -ne 0 ] + then + ((FAIL+=1)) + fi +} + +# Start the service for payload test with UDP +export VSOMEIP_APPLICATION_NAME=external_local_payload_test_service +export VSOMEIP_CONFIGURATION=external_local_payload_test_service.json +./payload_test_service --udp & +SERIVCE_PID=$! + +# Display a message to show the user that he must now call the external client +# to finish the test successfully +if [ ! -z "$USE_LXC_TEST" ]; then + echo "starting external local payload on slave LXC" + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./external_local_payload_test_client_external_start.sh\"" & + echo "remote ssh job id: $!" +elif [ ! -z "$USE_DOCKER" ]; then + docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./external_local_payload_test_client_external_start.sh" & +else +cat <<End-of-message +******************************************************************************* +******************************************************************************* +** Please now run: +** external_local_payload_test_client_external_start.sh +** from an external host to successfully complete this test. +** +** You probably will need to adapt the 'unicast' settings in +** external_local_payload_test_client_external.json and +** external_local_payload_test_service.json to your personal setup. +******************************************************************************* +******************************************************************************* +End-of-message +fi + +# The service should listen on a TCP and UDP socket now +sleep 1 +check_tcp_udp_sockets_are_open $SERIVCE_PID 2 + +# Wait until service is finished +# The client remotely shuts down the service if he has successfully transmitted +# all the packets with different payloads. Therefore we can assume that everything +# went well, even if we can only check the exit code of the service here. + +# Fail gets incremented if either client or service exit +# with a non-zero exit code +wait $SERIVCE_PID || ((FAIL+=1)) + + +# Start the service for payload test with tcp +export VSOMEIP_APPLICATION_NAME=external_local_payload_test_service +export VSOMEIP_CONFIGURATION=external_local_payload_test_service.json +./payload_test_service --tcp & +SERIVCE_PID=$! + +# The service should listen on a TCP and UDP socket now +sleep 1 +check_tcp_udp_sockets_are_open $SERIVCE_PID 2 + + +# Wait until service is finished +# The client remotely shuts down the service if he has successfully transmitted +# all the packets with different payloads. Therefore we can assume that everything +# went well, even if we can only check the exit code of the service here. + +# Fail gets incremented if either client or service exit +# with a non-zero exit code +wait $SERIVCE_PID || ((FAIL+=1)) + +# Check if server exited sucessfully +if [ $FAIL -eq 0 ] +then + exit 0 +else + exit 1 +fi diff --git a/test/network_tests/payload_tests/external_local_payload_test_client_local_and_external_starter.sh b/test/network_tests/payload_tests/external_local_payload_test_client_local_and_external_starter.sh new file mode 100755 index 0000000..4d45b85 --- /dev/null +++ b/test/network_tests/payload_tests/external_local_payload_test_client_local_and_external_starter.sh @@ -0,0 +1,139 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the client and service with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start two binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs client +# and service and checks that both exit sucessfully. + +FAIL=0 + +# Parameter 1: the pid to check +# Parameter 2: number of TCP/UDP sockets the process should have open +check_tcp_udp_sockets_are_open () +{ + # Check that the passed pid/process does listen on at least one TCP/UDP socket + # awk is used to avoid the case when a inode number is the same as a PID. The awk + # program filters the netstat output down to the protocol (1st field) and + # the PID/Program name (last field) fields. + SERVICE_SOCKETS_LISTENING=$(netstat -tulpen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) + if [ $SERVICE_SOCKETS_LISTENING -lt $2 ] + then + ((FAIL+=1)) + fi +} + +# Parameter 1: the pid to check +check_tcp_udp_sockets_are_closed () +{ + # Check that the passed pid/process does not listen on any TCP/UDP socket + # or has any active connection via a TCP/UDP socket + # awk is used to avoid the case when a inode number is the same as a PID. The awk + # program filters the netstat output down to the protocol (1st field) and + # the PID/Program name (last field) fields. + SERVICE_SOCKETS_LISTENING=$(netstat -tulpen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) + if [ $SERVICE_SOCKETS_LISTENING -ne 0 ] + then + ((FAIL+=1)) + fi + + SERVICE_SOCKETS_CONNECTED=$(netstat -tupen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) + if [ $SERVICE_SOCKETS_CONNECTED -ne 0 ] + then + ((FAIL+=1)) + fi +} + +# Start the service +export VSOMEIP_APPLICATION_NAME=external_local_payload_test_service +export VSOMEIP_CONFIGURATION=external_local_payload_test_service.json +./payload_test_service & +SERIVCE_PID=$! +sleep 1; + +# The service should listen on a TCP and UDP socket now +check_tcp_udp_sockets_are_open $SERIVCE_PID 2 + +# Start the client which sends messages over local UDS +export VSOMEIP_APPLICATION_NAME=external_local_payload_test_client_local +export VSOMEIP_CONFIGURATION=external_local_payload_test_client_local.json +./payload_test_client --dont-shutdown-service & +CLIENT_PID=$! +sleep 1 + +check_tcp_udp_sockets_are_open $SERIVCE_PID 2 +check_tcp_udp_sockets_are_closed $CLIENT_PID + +# Wait until client is finished +wait $CLIENT_PID || ((FAIL+=1)) + +# Display a message to show the user that he must now call the external client +# to finish the test successfully +if [ ! -z "$USE_LXC_TEST" ]; then + echo "starting external local payload on slave LXC" + ssh -tt -i $SANDBOX_ROOT_DIR/commonapi_main/lxc-config/.ssh/mgc_lxc/rsa_key_file.pub -o StrictHostKeyChecking=no root@$LXC_TEST_SLAVE_IP "bash -ci \"set -m; cd \\\$SANDBOX_TARGET_DIR/vsomeip_lib/test/network_tests; ./external_local_payload_test_client_external_start.sh\"" & + echo "remote ssh job id: $!" +elif [ ! -z "$USE_DOCKER" ]; then + docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS && ./external_local_payload_test_client_external_start.sh" & +else +cat <<End-of-message +******************************************************************************* +******************************************************************************* +** Please now run: +** external_local_payload_test_client_external_start.sh +** from an external host to successfully complete this test. +** +** You probably will need to adapt the 'unicast' settings in +** external_local_payload_test_client_external.json and +** external_local_payload_test_service.json to your personal setup. +******************************************************************************* +******************************************************************************* +End-of-message +fi + +# The service should still listen on a TCP and UDP socket +sleep 1 +check_tcp_udp_sockets_are_open $SERIVCE_PID 2 + +# Wait until service is finished +# The client remotely shuts down the service if he has successfully transmitted +# all the packets with different payloads. Therefore we can assume that everything +# went well, even if we can only check the exit code of the service here. + +# Fail gets incremented if either client or service exit +# with a non-zero exit code +wait $SERIVCE_PID || ((FAIL+=1)) + + +# Start the service for payload test with tcp +export VSOMEIP_APPLICATION_NAME=external_local_payload_test_service +export VSOMEIP_CONFIGURATION=external_local_payload_test_service.json +./payload_test_service --tcp & +SERIVCE_PID=$! + +# The service should listen on a TCP and UDP socket now +sleep 1 +check_tcp_udp_sockets_are_open $SERIVCE_PID 2 + + +# Wait until service is finished +# The client remotely shuts down the service if he has successfully transmitted +# all the packets with different payloads. Therefore we can assume that everything +# went well, even if we can only check the exit code of the service here. + +# Fail gets incremented if either client or service exit +# with a non-zero exit code +wait $SERIVCE_PID || ((FAIL+=1)) + +# Check if client and server both exited sucessfully and the service didnt't +# have any open TCP/UDP sockets +if [ $FAIL -eq 0 ] +then + exit 0 +else + exit 1 +fi diff --git a/test/network_tests/payload_tests/external_local_payload_test_client_local_start.sh b/test/network_tests/payload_tests/external_local_payload_test_client_local_start.sh new file mode 100755 index 0000000..b79e534 --- /dev/null +++ b/test/network_tests/payload_tests/external_local_payload_test_client_local_start.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +export VSOMEIP_APPLICATION_NAME=external_local_payload_test_client_local +export VSOMEIP_CONFIGURATION=external_local_payload_test_client_local.json +./payload_test_client diff --git a/test/network_tests/payload_tests/external_local_payload_test_client_local_starter.sh b/test/network_tests/payload_tests/external_local_payload_test_client_local_starter.sh new file mode 100755 index 0000000..c73dd81 --- /dev/null +++ b/test/network_tests/payload_tests/external_local_payload_test_client_local_starter.sh @@ -0,0 +1,91 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the client and service with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start two binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs client +# and service and checks that both exit sucessfully. + +FAIL=0 + +# Parameter 1: the pid to check +# Parameter 2: number of TCP/UDP sockets the process should have open +check_tcp_udp_sockets_are_open () +{ + # Check that the passed pid/process does listen on at least one TCP/UDP socket + # awk is used to avoid the case when a inode number is the same as a PID. The awk + # program filters the netstat output down to the protocol (1st field) and + # the PID/Program name (last field) fields. + SERVICE_SOCKETS_LISTENING=$(netstat -tulpen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) + if [ $SERVICE_SOCKETS_LISTENING -lt $2 ] + then + ((FAIL+=1)) + fi +} + +# Parameter 1: the pid to check +check_tcp_udp_sockets_are_closed () +{ + # Check that the passed pid/process does not listen on any TCP/UDP socket + # or has any active connection via a TCP/UDP socket + # awk is used to avoid the case when a inode number is the same as a PID. The awk + # program filters the netstat output down to the protocol (1st field) and + # the PID/Program name (last field) fields. + SERVICE_SOCKETS_LISTENING=$(netstat -tulpen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) + if [ $SERVICE_SOCKETS_LISTENING -ne 0 ] + then + ((FAIL+=1)) + fi + + SERVICE_SOCKETS_CONNECTED=$(netstat -tupen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) + if [ $SERVICE_SOCKETS_CONNECTED -ne 0 ] + then + ((FAIL+=1)) + fi +} + +# Start the service +export VSOMEIP_APPLICATION_NAME=external_local_payload_test_service +export VSOMEIP_CONFIGURATION=external_local_payload_test_service.json +./payload_test_service & +SERIVCE_PID=$! +sleep 1; + +# The service should listen on a TCP and UDP socket now +check_tcp_udp_sockets_are_open $SERIVCE_PID 2 + +# Start the client +export VSOMEIP_APPLICATION_NAME=external_local_payload_test_client_local +export VSOMEIP_CONFIGURATION=external_local_payload_test_client_local.json +./payload_test_client & +CLIENT_PID=$! + +# The service should still listen on a TCP and UDP socket now +check_tcp_udp_sockets_are_open $SERIVCE_PID 2 +# The client should use the shortcut over a local UDS instead of TCP/UDP, +# therefore he shouldn't have any open TCP/UDP sockets +check_tcp_udp_sockets_are_closed $CLIENT_PID + +if [ ! -z "$USE_DOCKER" ]; then + FAIL=0 +fi + +# Wait until client and service are finished +for job in $(jobs -p) +do + # Fail gets incremented if either client or service exit + # with a non-zero exit code + wait $job || ((FAIL+=1)) +done + +# Check if client and server both exited sucessfully +if [ $FAIL -eq 0 ] +then + exit 0 +else + exit 1 +fi diff --git a/test/network_tests/payload_tests/external_local_payload_test_service_client_external_start.sh b/test/network_tests/payload_tests/external_local_payload_test_service_client_external_start.sh new file mode 100755 index 0000000..046d50b --- /dev/null +++ b/test/network_tests/payload_tests/external_local_payload_test_service_client_external_start.sh @@ -0,0 +1,12 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +export VSOMEIP_APPLICATION_NAME=external_local_payload_test_service +export VSOMEIP_CONFIGURATION=external_local_payload_test_service.json +./payload_test_service --udp +# After payload was measured with UDP the client will restart and measure +# throughput with TCP +./payload_test_service --tcp
\ No newline at end of file diff --git a/test/network_tests/payload_tests/external_local_payload_test_service_start.sh b/test/network_tests/payload_tests/external_local_payload_test_service_start.sh new file mode 100755 index 0000000..90b1b38 --- /dev/null +++ b/test/network_tests/payload_tests/external_local_payload_test_service_start.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +export VSOMEIP_APPLICATION_NAME=external_local_payload_test_service +export VSOMEIP_CONFIGURATION=external_local_payload_test_service.json +./payload_test_service diff --git a/test/network_tests/payload_tests/local_payload_test_client.json b/test/network_tests/payload_tests/local_payload_test_client.json new file mode 100644 index 0000000..24fa1fa --- /dev/null +++ b/test/network_tests/payload_tests/local_payload_test_client.json @@ -0,0 +1,36 @@ +{ + "unicast" : "127.0.0.1", + "netmask" : "255.255.255.0", + "logging" : + { + "level" : "debug", + "console" : "true", + "file" : + { + "enable" : "true", + "path" : "/var/log/vsomeip.log" + }, + + "dlt" : "true" + }, + + "applications" : + [ + { + "name" : "local_payload_test_client", + "id" : "0x1343" + } + ], + "services" : + [ + ], + + "routing" : "local_payload_test_service", + "service-discovery" : + { + "enable" : "false", + "multicast" : "224.0.0.1", + "port" : "30491", + "protocol" : "udp" + } +} diff --git a/test/network_tests/payload_tests/local_payload_test_client_start.sh b/test/network_tests/payload_tests/local_payload_test_client_start.sh new file mode 100755 index 0000000..975be2a --- /dev/null +++ b/test/network_tests/payload_tests/local_payload_test_client_start.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +export VSOMEIP_APPLICATION_NAME=local_payload_test_client +export VSOMEIP_CONFIGURATION=local_payload_test_client.json +./payload_test_client diff --git a/test/network_tests/payload_tests/local_payload_test_huge_payload_starter.sh b/test/network_tests/payload_tests/local_payload_test_huge_payload_starter.sh new file mode 100755 index 0000000..c230891 --- /dev/null +++ b/test/network_tests/payload_tests/local_payload_test_huge_payload_starter.sh @@ -0,0 +1,43 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the client and service with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start two binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs client +# and service and checks that both exit sucessfully. + +FAIL=0 + +# Start the service +export VSOMEIP_APPLICATION_NAME=local_payload_test_service +export VSOMEIP_CONFIGURATION=local_payload_test_service.json +./payload_test_service & +SERIVCE_PID=$! +sleep 1; + +# Start the client +export VSOMEIP_APPLICATION_NAME=local_payload_test_client +export VSOMEIP_CONFIGURATION=local_payload_test_client.json +./payload_test_client --number-of-messages 100 --max-payload-size 10485760 & +CLIENT_PID=$! + +# Wait until client and service are finished +for job in $(jobs -p) +do + # Fail gets incremented if either client or service exit + # with a non-zero exit code + wait $job || ((FAIL+=1)) +done + +# Check if client and server both exited sucessfully and the service didnt't +# have any open tcp/udp sockets +if [ $FAIL -eq 0 ] +then + exit 0 +else + exit 1 +fi diff --git a/test/network_tests/payload_tests/local_payload_test_service.json b/test/network_tests/payload_tests/local_payload_test_service.json new file mode 100644 index 0000000..b5c83a6 --- /dev/null +++ b/test/network_tests/payload_tests/local_payload_test_service.json @@ -0,0 +1,40 @@ +{ + "unicast" : "127.0.0.1", + "logging" : + { + "level" : "debug", + "console" : "true", + "file" : + { + "enable" : "false", + "path" : "/tmp/vsomeip.log" + }, + + "dlt" : "false" + }, + + "applications" : + [ + { + "name" : "local_payload_test_service", + "id" : "0x1277" + } + ], + + "services" : + [ + { + "service" : "0x1234", + "instance" : "0x5678" + } + ], + + "routing" : "local_payload_test_service", + "service-discovery" : + { + "enable" : "false", + "multicast" : "224.0.0.1", + "port" : "30490", + "protocol" : "udp" + } +} diff --git a/test/network_tests/payload_tests/local_payload_test_service_start.sh b/test/network_tests/payload_tests/local_payload_test_service_start.sh new file mode 100755 index 0000000..cc67f54 --- /dev/null +++ b/test/network_tests/payload_tests/local_payload_test_service_start.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +export VSOMEIP_APPLICATION_NAME=local_payload_test_service +export VSOMEIP_CONFIGURATION=local_payload_test_service.json +./payload_test_service diff --git a/test/network_tests/payload_tests/local_payload_test_starter.sh b/test/network_tests/payload_tests/local_payload_test_starter.sh new file mode 100755 index 0000000..abc4577 --- /dev/null +++ b/test/network_tests/payload_tests/local_payload_test_starter.sh @@ -0,0 +1,69 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the client and service with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start two binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs client +# and service and checks that both exit sucessfully. + +FAIL=0 + +# Parameter 1: the pid to check +check_tcp_udp_sockets_are_closed () +{ + # Check that the service does not listen on any TCP/UDP socket + # or has any active connection via a TCP/UDP socket + # awk is used to avoid the case when a inode number is the same as a PID. The awk + # program filters the netstat output down to the protocol (1st field) and + # the PID/Program name (last field) fields. + SERVICE_SOCKETS_LISTENING=$(netstat -tulpen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) + if [ $SERVICE_SOCKETS_LISTENING -ne 0 ] + then + ((FAIL+=1)) + fi + + SERVICE_SOCKETS_CONNECTED=$(netstat -tupen 2> /dev/null | awk '{print $1 "\t" $NF}' | grep $1 | wc -l) + if [ $SERVICE_SOCKETS_CONNECTED -ne 0 ] + then + ((FAIL+=1)) + fi +} + +# Start the service +export VSOMEIP_APPLICATION_NAME=local_payload_test_service +export VSOMEIP_CONFIGURATION=local_payload_test_service.json +./payload_test_service & +SERIVCE_PID=$! +sleep 1; + +check_tcp_udp_sockets_are_closed $SERIVCE_PID + +# Start the client +export VSOMEIP_APPLICATION_NAME=local_payload_test_client +export VSOMEIP_CONFIGURATION=local_payload_test_client.json +./payload_test_client & +CLIENT_PID=$! + +check_tcp_udp_sockets_are_closed $SERIVCE_PID +check_tcp_udp_sockets_are_closed $CLIENT_PID + +# Wait until client and service are finished +for job in $(jobs -p) +do + # Fail gets incremented if either client or service exit + # with a non-zero exit code + wait $job || ((FAIL+=1)) +done + +# Check if client and server both exited sucessfully and the service didnt't +# have any open tcp/udp sockets +if [ $FAIL -eq 0 ] +then + exit 0 +else + exit 1 +fi diff --git a/test/network_tests/payload_tests/payload_test_client.cpp b/test/network_tests/payload_tests/payload_test_client.cpp new file mode 100644 index 0000000..fd235d8 --- /dev/null +++ b/test/network_tests/payload_tests/payload_test_client.cpp @@ -0,0 +1,415 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "payload_test_client.hpp" + +enum class payloadsize + : std::uint8_t + { + UDS, TCP, UDP, USER_SPECIFIED +}; + +// this variables are changed via cmdline parameters +static bool use_tcp = false; +static bool call_service_sync = true; +static std::uint32_t sliding_window_size = vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND_PAYLOAD_TESTS; +static payloadsize max_payload_size = payloadsize::UDS; +static bool shutdown_service_at_end = true; +static std::uint32_t user_defined_max_payload; +static std::uint32_t number_of_messages_to_send = 0; + +payload_test_client::payload_test_client( + bool _use_tcp, + bool _call_service_sync, + std::uint32_t _sliding_window_size) : + app_(vsomeip::runtime::get()->create_application()), + request_(vsomeip::runtime::get()->create_request(_use_tcp)), + call_service_sync_(_call_service_sync), + sliding_window_size_(_sliding_window_size), + blocked_(false), + is_available_(false), + number_of_messages_to_send_(number_of_messages_to_send ? number_of_messages_to_send : vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND_PAYLOAD_TESTS), + number_of_sent_messages_(0), + number_of_sent_messages_total_(0), + number_of_acknowledged_messages_(0), + current_payload_size_(1), + all_msg_acknowledged_(false), + sender_(std::bind(&payload_test_client::run, this)) +{ +} + +bool payload_test_client::init() +{ + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return false; + } + + app_->register_state_handler( + std::bind(&payload_test_client::on_state, this, + std::placeholders::_1)); + + app_->register_message_handler(vsomeip::ANY_SERVICE, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip::ANY_METHOD, + std::bind(&payload_test_client::on_message, this, + std::placeholders::_1)); + + app_->register_availability_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, + std::bind(&payload_test_client::on_availability, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + return true; +} + +void payload_test_client::start() +{ + VSOMEIP_INFO << "Starting..."; + app_->start(); +} + +void payload_test_client::stop() +{ + VSOMEIP_INFO << "Stopping..."; + // shutdown the service + if(shutdown_service_at_end) + { + shutdown_service(); + } + app_->clear_all_handler(); +} + +void payload_test_client::shutdown_service() +{ + request_->set_service(vsomeip_test::TEST_SERVICE_SERVICE_ID); + request_->set_instance(vsomeip_test::TEST_SERVICE_INSTANCE_ID); + request_->set_method(vsomeip_test::TEST_SERVICE_METHOD_ID_SHUTDOWN); + app_->send(request_); +} + +void payload_test_client::join_sender_thread() +{ + sender_.join(); +} + +void payload_test_client::on_state(vsomeip::state_type_e _state) +{ + if(_state == vsomeip::state_type_e::ST_REGISTERED) + { + app_->request_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, false); + } +} + +void payload_test_client::on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available) +{ + VSOMEIP_INFO << "Service [" << std::setw(4) << std::setfill('0') << std::hex + << _service << "." << _instance << "] is " + << (_is_available ? "available." : "NOT available."); + + if(vsomeip_test::TEST_SERVICE_SERVICE_ID == _service + && vsomeip_test::TEST_SERVICE_INSTANCE_ID == _instance) + { + if(is_available_ && !_is_available) + { + is_available_ = false; + } + else if(_is_available && !is_available_) + { + is_available_ = true; + send(); + } + } +} + +void payload_test_client::on_message(const std::shared_ptr<vsomeip::message>& _response) +{ + number_of_acknowledged_messages_++; + + ASSERT_EQ(_response->get_service(), vsomeip_test::TEST_SERVICE_SERVICE_ID); + ASSERT_EQ(_response->get_instance(), vsomeip_test::TEST_SERVICE_INSTANCE_ID); + + if(call_service_sync_) + { + // We notify the sender thread every time a message was acknowledged + { + std::lock_guard<std::mutex> lk(all_msg_acknowledged_mutex_); + all_msg_acknowledged_ = true; + } + all_msg_acknowledged_cv_.notify_one(); + } + else + { + // We notify the sender thread only if all sent messages have been acknowledged + if(number_of_acknowledged_messages_ == number_of_messages_to_send_) + { + std::lock_guard<std::mutex> lk(all_msg_acknowledged_mutex_); + number_of_acknowledged_messages_ = 0; + all_msg_acknowledged_ = true; + all_msg_acknowledged_cv_.notify_one(); + } + else if(number_of_acknowledged_messages_ % sliding_window_size_ == 0) + { + std::lock_guard<std::mutex> lk(all_msg_acknowledged_mutex_); + all_msg_acknowledged_ = true; + all_msg_acknowledged_cv_.notify_one(); + } + } +} + +void payload_test_client::send() +{ + std::lock_guard<std::mutex> its_lock(mutex_); + blocked_ = true; + condition_.notify_one(); +} + +void payload_test_client::run() +{ + std::unique_lock<std::mutex> its_lock(mutex_); + while (!blocked_) + { + condition_.wait(its_lock); + } + + request_->set_service(vsomeip_test::TEST_SERVICE_SERVICE_ID); + request_->set_instance(vsomeip_test::TEST_SERVICE_INSTANCE_ID); + request_->set_method(vsomeip_test::TEST_SERVICE_METHOD_ID); + + // lock the mutex + std::unique_lock<std::mutex> lk(all_msg_acknowledged_mutex_); + + std::uint32_t max_allowed_payload = get_max_allowed_payload(); + + std::shared_ptr<vsomeip::payload> payload = vsomeip::runtime::get()->create_payload(); + std::vector<vsomeip::byte_t> payload_data; + bool reached_peak = false; + for(;;) + { + payload_data.assign(current_payload_size_ , vsomeip_test::PAYLOAD_TEST_DATA); + payload->set_data(payload_data); + request_->set_payload(payload); + + watch_.reset(); + watch_.start(); + + call_service_sync_ ? send_messages_sync(lk) : send_messages_async(lk); + + watch_.stop(); + print_throughput(); + + // Increase array size for next iteration + if(!reached_peak) { + current_payload_size_ *= 2; + } else { + current_payload_size_ /= 2; + } + + if(!reached_peak && current_payload_size_ > max_allowed_payload) + { + current_payload_size_ = max_allowed_payload; + reached_peak = true; + } else if(reached_peak && current_payload_size_ <= 1) { + break; + } + } + blocked_ = false; + + stop(); + std::thread t1([](){ std::this_thread::sleep_for(std::chrono::microseconds(1000000 * 5));}); + t1.join(); + app_->stop(); + std::thread t([](){ std::this_thread::sleep_for(std::chrono::microseconds(1000000 * 5));}); + t.join(); +} + + +std::uint32_t payload_test_client::get_max_allowed_payload() +{ + std::uint32_t payload; + switch (max_payload_size) + { + case payloadsize::UDS: + // TODO + payload = 1024 * 32 - 16; + break; + case payloadsize::TCP: + // TODO + payload = 4095 - 16; + break; + case payloadsize::UDP: + payload = VSOMEIP_MAX_UDP_MESSAGE_SIZE - 16; + break; + case payloadsize::USER_SPECIFIED: + payload = user_defined_max_payload; + break; + default: + payload = VSOMEIP_MAX_LOCAL_MESSAGE_SIZE; + break; + } + return payload; +} + +void payload_test_client::send_messages_sync(std::unique_lock<std::mutex>& lk) +{ + for (number_of_sent_messages_ = 0; + number_of_sent_messages_ < number_of_messages_to_send_; + number_of_sent_messages_++, number_of_sent_messages_total_++) + { + app_->send(request_); + // wait until the send messages has been acknowledged + // as long we wait lk is released; after wait returns lk is reacquired + all_msg_acknowledged_cv_.wait(lk, [&] + { return all_msg_acknowledged_;}); + // Reset condition variable (lk is locked again here) + all_msg_acknowledged_ = false; + } +} + +void payload_test_client::send_messages_async(std::unique_lock<std::mutex>& lk) +{ + for (number_of_sent_messages_ = 0; + number_of_sent_messages_ < number_of_messages_to_send_; + number_of_sent_messages_++, number_of_sent_messages_total_++) + { + app_->send(request_); + + if((number_of_sent_messages_+1) % sliding_window_size_ == 0) + { + // wait until all send messages have been acknowledged + // as long we wait lk is released; after wait returns lk is reacquired + all_msg_acknowledged_cv_.wait(lk, [&] + { return all_msg_acknowledged_;}); + + // Reset condition variable + all_msg_acknowledged_ = false; + } + } +} + +void payload_test_client::print_throughput() +{ + constexpr std::uint32_t usec_per_sec = 1000000; + stop_watch::usec_t time_needed = watch_.get_total_elapsed_microseconds(); + stop_watch::usec_t time_per_message = time_needed / number_of_sent_messages_; + std::double_t calls_per_sec = number_of_sent_messages_ + * (usec_per_sec / static_cast<double>(time_needed)); + std::double_t mbyte_per_sec = ((number_of_sent_messages_ + * current_payload_size_) + / (static_cast<double>(time_needed) / usec_per_sec)) / (1024*1024); + + VSOMEIP_INFO<< "[ Payload Test ] : :" + << "Payload size [byte]: " << std::dec << std::setw(8) << std::setfill('0') << current_payload_size_ + << " Messages sent: " << std::dec << std::setw(8) << std::setfill('0') << number_of_sent_messages_ + << " Meantime/message [usec]: " << std::dec << std::setw(8) << std::setfill('0') << time_per_message + << " Calls/sec: " << std::dec << std::setw(8) << std::setfill('0') << calls_per_sec + << " MiB/sec: " << std::dec << std::setw(8) << std::setfill('0') << mbyte_per_sec; +} + +TEST(someip_payload_test, send_different_payloads) +{ + payload_test_client test_client_(use_tcp, call_service_sync, sliding_window_size); + if (test_client_.init()) { + test_client_.start(); + test_client_.join_sender_thread(); + } +} + + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + std::string tcp_enable("--tcp"); + std::string udp_enable("--udp"); + std::string sync_enable("--sync"); + std::string async_enable("--async"); + std::string sliding_window_size_param("--sliding-window-size"); + std::string max_payload_size_param("--max-payload-size"); + std::string shutdown_service_disable_param("--dont-shutdown-service"); + std::string numbers_of_messages("--number-of-messages"); + std::string help("--help"); + + int i = 1; + while (i < argc) + { + if(tcp_enable == argv[i]) + { + use_tcp = true; + } + else if(udp_enable == argv[i]) + { + use_tcp = false; + } + else if(sync_enable == argv[i]) + { + call_service_sync = true; + } + else if(async_enable == argv[i]) + { + call_service_sync = false; + } + else if(sliding_window_size_param == argv[i] && i + 1 < argc) + { + i++; + std::stringstream converter(argv[i]); + converter >> sliding_window_size; + } + else if(max_payload_size_param == argv[i] && i + 1 < argc) + { + i++; + if(std::string("UDS") == argv[i]) + { + max_payload_size = payloadsize::UDS; + } + else if(std::string("TCP") == argv[i]) + { + max_payload_size = payloadsize::TCP; + } + else if(std::string("UDP") == argv[i]) + { + max_payload_size = payloadsize::UDP; + } + else { + max_payload_size = payloadsize::USER_SPECIFIED; + std::stringstream converter(argv[i]); + converter >> user_defined_max_payload; + } + } + else if (numbers_of_messages == argv[i]) { + i++; + std::stringstream converter(argv[i]); + converter >> number_of_messages_to_send; + } + else if(shutdown_service_disable_param == argv[i]) + { + shutdown_service_at_end = false; + } + else if(help == argv[i]) + { + VSOMEIP_INFO << "Parameters:\n" + << "--tcp: Send messages via TCP\n" + << "--udp: Send messages via UDP (default)\n" + << "--sync: Wait for acknowledge before sending next message (default)\n" + << "--async: Send multiple messages w/o waiting for" + " acknowledge of service\n" + << "--sliding-window-size: Number of messages to send before waiting " + "for acknowledge of service. Default: " << sliding_window_size << "\n" + << "--max-payload-size: limit the maximum payloadsize of send requests. One of {" + "UDS (=" << VSOMEIP_MAX_LOCAL_MESSAGE_SIZE << "byte), " + "UDP (=" << VSOMEIP_MAX_UDP_MESSAGE_SIZE << "byte), " + "TCP (=" << VSOMEIP_MAX_TCP_MESSAGE_SIZE << "byte)}, default: UDS\n" + << "--dont-shutdown-service: Don't shutdown the service upon " + "finishing of the payload test\n" + << "--number-of-messages: Number of messages to send per payload size iteration\n" + << "--help: print this help"; + } + i++; + } + + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/payload_tests/payload_test_client.hpp b/test/network_tests/payload_tests/payload_test_client.hpp new file mode 100644 index 0000000..2757d00 --- /dev/null +++ b/test/network_tests/payload_tests/payload_test_client.hpp @@ -0,0 +1,71 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef PAYLOADTESTCLIENT_HPP_ +#define PAYLOADTESTCLIENT_HPP_ + +#include <gtest/gtest.h> + +#include <vsomeip/vsomeip.hpp> + +#include <cmath> +#include <thread> +#include <mutex> +#include <condition_variable> +#include <functional> + +#include "../someip_test_globals.hpp" + +#include "stopwatch.hpp" + +class payload_test_client +{ +public: + payload_test_client(bool _use_tcp, bool _call_service_sync, std::uint32_t _sliding_window_size); + bool init(); + void start(); + void stop(); + void join_sender_thread(); + void on_state(vsomeip::state_type_e _state); + void on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available); + void on_message(const std::shared_ptr<vsomeip::message> &_response); + void send(); + void run(); + +private: + void print_throughput(); + void send_messages_sync(std::unique_lock<std::mutex>& lk); + void send_messages_async(std::unique_lock<std::mutex>& lk); + void shutdown_service(); + std::uint32_t get_max_allowed_payload(); + +private: + std::shared_ptr<vsomeip::application> app_; + std::shared_ptr<vsomeip::message> request_; + bool call_service_sync_; + std::uint32_t sliding_window_size_; + std::mutex mutex_; + std::condition_variable condition_; + bool blocked_; + bool is_available_; + const std::uint32_t number_of_messages_to_send_; + std::uint32_t number_of_sent_messages_; + std::uint32_t number_of_sent_messages_total_; + std::uint32_t number_of_acknowledged_messages_; + + std::uint32_t current_payload_size_; + + stop_watch watch_; + + bool all_msg_acknowledged_; + std::mutex all_msg_acknowledged_mutex_; + std::condition_variable all_msg_acknowledged_cv_; + + std::thread sender_; + +}; + +#endif /* PAYLOADTESTCLIENT_HPP_ */ diff --git a/test/network_tests/payload_tests/payload_test_service.cpp b/test/network_tests/payload_tests/payload_test_service.cpp new file mode 100644 index 0000000..5cace17 --- /dev/null +++ b/test/network_tests/payload_tests/payload_test_service.cpp @@ -0,0 +1,185 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "payload_test_service.hpp" + +// this variables are changed via cmdline parameters + +static bool check_payload = true; + +payload_test_service::payload_test_service() : + app_(vsomeip::runtime::get()->create_application()), + is_registered_(false), + blocked_(false), + number_of_received_messages_(0), + offer_thread_(std::bind(&payload_test_service::run, this)) +{ +} + +bool payload_test_service::init() +{ + std::lock_guard<std::mutex> its_lock(mutex_); + + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return false; + } + app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip_test::TEST_SERVICE_METHOD_ID, + std::bind(&payload_test_service::on_message, this, + std::placeholders::_1)); + + app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, + vsomeip_test::TEST_SERVICE_INSTANCE_ID, + vsomeip_test::TEST_SERVICE_METHOD_ID_SHUTDOWN, + std::bind(&payload_test_service::on_message_shutdown, this, + std::placeholders::_1)); + + app_->register_state_handler( + std::bind(&payload_test_service::on_state, this, + std::placeholders::_1)); + return true; +} + +void payload_test_service::start() +{ + VSOMEIP_INFO << "Starting..."; + app_->start(); +} + +void payload_test_service::stop() +{ + VSOMEIP_INFO << "Stopping..."; + app_->clear_all_handler(); + app_->stop(); +} + +void payload_test_service::join_offer_thread() +{ + offer_thread_.join(); +} + +void payload_test_service::offer() +{ + app_->offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID); +} + +void payload_test_service::stop_offer() +{ + app_->stop_offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID); +} + +void payload_test_service::on_state(vsomeip::state_type_e _state) +{ + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? "registered." : + "deregistered."); + + if(_state == vsomeip::state_type_e::ST_REGISTERED) + { + if(!is_registered_) + { + is_registered_ = true; + std::lock_guard<std::mutex> its_lock(mutex_); + blocked_ = true; + // "start" the run method thread + condition_.notify_one(); + } + } + else + { + is_registered_ = false; + } +} + +void payload_test_service::on_message(const std::shared_ptr<vsomeip::message>& _request) +{ + number_of_received_messages_++; + if(number_of_received_messages_ % vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND_PAYLOAD_TESTS == 0) + { + VSOMEIP_INFO << "Received a message with Client/Session [" << std::setw(4) + << std::setfill('0') << std::hex << _request->get_client() << "/" + << std::setw(4) << std::setfill('0') << std::hex + << _request->get_session() << "] payload size [byte]:" + << std::dec << _request->get_payload()->get_length(); + } + + ASSERT_EQ(vsomeip_test::TEST_SERVICE_SERVICE_ID, _request->get_service()); + ASSERT_EQ(vsomeip_test::TEST_SERVICE_METHOD_ID, _request->get_method()); + + // Check the protocol version this shall be set to 0x01 according to the spec. + // TR_SOMEIP_00052 + ASSERT_EQ(0x01, _request->get_protocol_version()); + // Check the message type this shall be 0xx (REQUEST) according to the spec. + // TR_SOMEIP_00055 + ASSERT_EQ(vsomeip::message_type_e::MT_REQUEST, _request->get_message_type()); + + if (check_payload) { + std::shared_ptr<vsomeip::payload> pl = _request->get_payload(); + vsomeip::byte_t* pl_ptr = pl->get_data(); + for (vsomeip::length_t i = 0; i < pl->get_length(); i++) + { + ASSERT_EQ(vsomeip_test::PAYLOAD_TEST_DATA, *(pl_ptr+i)); + } + } + + // send response + std::shared_ptr<vsomeip::message> its_response = + vsomeip::runtime::get()->create_response(_request); + + app_->send(its_response); +} + +void payload_test_service::on_message_shutdown( + const std::shared_ptr<vsomeip::message>& _request) +{ + (void)_request; + VSOMEIP_INFO << "Shutdown method was called, going down now."; + stop(); +} + +void payload_test_service::run() +{ + std::unique_lock<std::mutex> its_lock(mutex_); + while (!blocked_) + condition_.wait(its_lock); + + offer(); +} + +TEST(someip_payload_test, send_response_for_every_request) +{ + payload_test_service test_service; + if (test_service.init()) { + test_service.start(); + test_service.join_offer_thread(); + } +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) +{ + std::string help("--help"); + std::string check("--do-not-check-payload"); + + int i = 1; + while (i < argc) + { + if(help == argv[i]) + { + VSOMEIP_INFO << "Parameters:\n" + << "--help: print this help\n" + << "--do-not-check-payload: Don't verify payload data " + << "-> Use this flag for performance measurements!"; + } else if (check == argv[i]) { + check_payload = false; + } + i++; + } + + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/network_tests/payload_tests/payload_test_service.hpp b/test/network_tests/payload_tests/payload_test_service.hpp new file mode 100644 index 0000000..9054fd9 --- /dev/null +++ b/test/network_tests/payload_tests/payload_test_service.hpp @@ -0,0 +1,45 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef PAYLOADTESTSERVICE_HPP_ +#define PAYLOADTESTSERVICE_HPP_ +#include <gtest/gtest.h> + +#include <vsomeip/vsomeip.hpp> + +#include <thread> +#include <mutex> +#include <condition_variable> +#include <functional> + +#include "../someip_test_globals.hpp" + +class payload_test_service +{ +public: + payload_test_service(); + bool init(); + void start(); + void stop(); + void offer(); + void stop_offer(); + void join_offer_thread(); + void on_state(vsomeip::state_type_e _state); + void on_message(const std::shared_ptr<vsomeip::message> &_request); + void on_message_shutdown(const std::shared_ptr<vsomeip::message> &_request); + void run(); + +private: + std::shared_ptr<vsomeip::application> app_; + bool is_registered_; + + std::mutex mutex_; + std::condition_variable condition_; + bool blocked_; + std::uint32_t number_of_received_messages_; + std::thread offer_thread_; +}; + +#endif /* PAYLOADTESTSERVICE_HPP_ */ diff --git a/test/network_tests/payload_tests/stopwatch.cpp b/test/network_tests/payload_tests/stopwatch.cpp new file mode 100644 index 0000000..83506f4 --- /dev/null +++ b/test/network_tests/payload_tests/stopwatch.cpp @@ -0,0 +1,38 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "stopwatch.hpp" + +#include <cassert> +#include <ctime> + + +#define USEC_PER_SEC 1000000ULL +#define NSEC_PER_USEC 1000ULL + + +stop_watch::usec_t stop_watch::get_total_elapsed_microseconds() const { + usec_t elapsed = total_elapsed_; + + if (started_) + elapsed += get_elapsed(); + + return elapsed; +} + +stop_watch::usec_t stop_watch::get_total_elapsed_seconds() const { + return get_total_elapsed_microseconds() / USEC_PER_SEC; +} + +stop_watch::usec_t stop_watch::now() { + struct timespec ts; + + const int ret = clock_gettime(CLOCK_MONOTONIC_RAW, &ts); + assert(!ret); + static_cast<void>(ret); // prevent warning in release build + + return (usec_t) ts.tv_sec * USEC_PER_SEC + (usec_t) ts.tv_nsec / NSEC_PER_USEC; +} + diff --git a/test/network_tests/payload_tests/stopwatch.hpp b/test/network_tests/payload_tests/stopwatch.hpp new file mode 100644 index 0000000..5917e12 --- /dev/null +++ b/test/network_tests/payload_tests/stopwatch.hpp @@ -0,0 +1,58 @@ +// Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef STOP_WATCH_H_ +#define STOP_WATCH_H_ + +#include <cstdint> + + +class stop_watch +{ +public: + typedef uint64_t usec_t; + + stop_watch() : + started_(false), + start_time_point_(0), + total_elapsed_(0) + { + } + + inline void reset() + { + started_ = false; + total_elapsed_ = 0; + } + + inline void start() + { + start_time_point_ = now(); + started_ = true; + } + + inline void stop() + { + total_elapsed_ += get_elapsed(); + started_ = false; + } + + usec_t get_total_elapsed_microseconds() const; + usec_t get_total_elapsed_seconds() const; + +private: + inline usec_t get_elapsed() const + { + return now() - start_time_point_; + } + + static usec_t now(); + + bool started_; + usec_t start_time_point_; + usec_t total_elapsed_; +}; + +#endif // STOP_WATCH_H_ |