summaryrefslogtreecommitdiff
path: root/test/network_tests/second_address_tests
diff options
context:
space:
mode:
Diffstat (limited to 'test/network_tests/second_address_tests')
-rw-r--r--test/network_tests/second_address_tests/conf/second_address_test_master_client.json.in32
-rw-r--r--test/network_tests/second_address_tests/conf/second_address_test_master_service_udp.json.in40
-rw-r--r--test/network_tests/second_address_tests/conf/second_address_test_slave_client.json.in32
-rw-r--r--test/network_tests/second_address_tests/conf/second_address_test_slave_service_udp.json.in40
-rwxr-xr-xtest/network_tests/second_address_tests/conf/second_address_test_slave_starter.sh.in60
-rw-r--r--test/network_tests/second_address_tests/second_address_test_client.cpp353
-rw-r--r--test/network_tests/second_address_tests/second_address_test_globals.hpp29
-rwxr-xr-xtest/network_tests/second_address_tests/second_address_test_master_starter.sh77
-rw-r--r--test/network_tests/second_address_tests/second_address_test_service.cpp252
9 files changed, 915 insertions, 0 deletions
diff --git a/test/network_tests/second_address_tests/conf/second_address_test_master_client.json.in b/test/network_tests/second_address_tests/conf/second_address_test_master_client.json.in
new file mode 100644
index 0000000..542480f
--- /dev/null
+++ b/test/network_tests/second_address_tests/conf/second_address_test_master_client.json.in
@@ -0,0 +1,32 @@
+{
+ "unicast":"@TEST_IP_MASTER@",
+ "logging":
+ {
+ "level":"warning",
+ "console":"true",
+ "file":
+ {
+ "enable":"false",
+ "path":"/tmp/vsomeip.log"
+ },
+ "dlt":"false"
+ },
+ "applications" :
+ [
+ {
+ "name" : "second_address_test_client",
+ "id" : "0x1210",
+ "max_dispatch_time" : "1000"
+ }
+ ],
+ "routing":"routingmanagerd",
+ "service-discovery":
+ {
+ "enable":"true",
+ "multicast":"224.0.50.1",
+ "port":"30490",
+ "protocol":"udp",
+ "cyclic_offer_delay" : "1000",
+ "ttl" : "3"
+ }
+} \ No newline at end of file
diff --git a/test/network_tests/second_address_tests/conf/second_address_test_master_service_udp.json.in b/test/network_tests/second_address_tests/conf/second_address_test_master_service_udp.json.in
new file mode 100644
index 0000000..1b45898
--- /dev/null
+++ b/test/network_tests/second_address_tests/conf/second_address_test_master_service_udp.json.in
@@ -0,0 +1,40 @@
+{
+ "unicast":"@TEST_IP_MASTER@",
+ "logging":
+ {
+ "level":"warning",
+ "console":"true",
+ "file":
+ {
+ "enable":"false",
+ "path":"/tmp/vsomeip.log"
+ },
+ "dlt":"false"
+ },
+ "applications" :
+ [
+ {
+ "name" : "second_address_test_service",
+ "id" : "0x3489",
+ "max_dispatch_time" : "1000"
+ }
+ ],
+ "services":
+ [
+ {
+ "service":"0x3333",
+ "instance":"0x0001",
+ "unreliable":"30001"
+ }
+ ],
+ "routing":"routingmanagerd",
+ "service-discovery":
+ {
+ "enable":"true",
+ "multicast":"224.0.50.1",
+ "port":"30490",
+ "protocol":"udp",
+ "cyclic_offer_delay" : "1000",
+ "ttl" : "3"
+ }
+} \ No newline at end of file
diff --git a/test/network_tests/second_address_tests/conf/second_address_test_slave_client.json.in b/test/network_tests/second_address_tests/conf/second_address_test_slave_client.json.in
new file mode 100644
index 0000000..303bfae
--- /dev/null
+++ b/test/network_tests/second_address_tests/conf/second_address_test_slave_client.json.in
@@ -0,0 +1,32 @@
+{
+ "unicast":"@TEST_IP_SLAVE_SECOND@",
+ "logging":
+ {
+ "level":"warning",
+ "console":"true",
+ "file":
+ {
+ "enable":"false",
+ "path":"/tmp/vsomeip.log"
+ },
+ "dlt":"false"
+ },
+ "applications" :
+ [
+ {
+ "name" : "second_address_test_client",
+ "id" : "0x1210",
+ "max_dispatch_time" : "1000"
+ }
+ ],
+ "routing":"routingmanagerd",
+ "service-discovery":
+ {
+ "enable":"true",
+ "multicast":"224.0.50.1",
+ "port":"30490",
+ "protocol":"udp",
+ "cyclic_offer_delay" : "1000",
+ "ttl" : "3"
+ }
+} \ No newline at end of file
diff --git a/test/network_tests/second_address_tests/conf/second_address_test_slave_service_udp.json.in b/test/network_tests/second_address_tests/conf/second_address_test_slave_service_udp.json.in
new file mode 100644
index 0000000..9a7c062
--- /dev/null
+++ b/test/network_tests/second_address_tests/conf/second_address_test_slave_service_udp.json.in
@@ -0,0 +1,40 @@
+{
+ "unicast":"@TEST_IP_SLAVE_SECOND@",
+ "logging":
+ {
+ "level":"warning",
+ "console":"true",
+ "file":
+ {
+ "enable":"false",
+ "path":"/tmp/vsomeip.log"
+ },
+ "dlt":"false"
+ },
+ "applications" :
+ [
+ {
+ "name" : "second_address_test_service",
+ "id" : "0x3489",
+ "max_dispatch_time" : "1000"
+ }
+ ],
+ "services":
+ [
+ {
+ "service":"0x3333",
+ "instance":"0x0001",
+ "unreliable":"30001"
+ }
+ ],
+ "routing":"routingmanagerd",
+ "service-discovery":
+ {
+ "enable":"true",
+ "multicast":"224.0.50.1",
+ "port":"30490",
+ "protocol":"udp",
+ "cyclic_offer_delay" : "1000",
+ "ttl" : "3"
+ }
+} \ No newline at end of file
diff --git a/test/network_tests/second_address_tests/conf/second_address_test_slave_starter.sh.in b/test/network_tests/second_address_tests/conf/second_address_test_slave_starter.sh.in
new file mode 100755
index 0000000..5694aa6
--- /dev/null
+++ b/test/network_tests/second_address_tests/conf/second_address_test_slave_starter.sh.in
@@ -0,0 +1,60 @@
+#!/bin/bash
+# Copyright (C) 2015-2018 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/.
+
+FAIL=0
+
+if [ $# -lt 2 ]
+then
+ echo "Please pass a operation and communication mode to this script."
+ echo "For example: $0 CLIENT UDP"
+ echo "Valid operation modes include [SERVICE, CLIENT]"
+ echo "Valid communication modes include [UDP, TCP]"
+ exit 1
+fi
+
+OPERATIONMODE=$1
+COMMUNICATIONMODE=$2
+
+# Add second IP address to interface
+ip addr add @TEST_IP_SLAVE_SECOND@/32 dev eth0
+
+if [ "$OPERATIONMODE" = "CLIENT" ]; then
+ SLAVE_APPLICATION=second_address_test_client
+ export VSOMEIP_CONFIGURATION=second_address_test_slave_client.json
+
+elif [ "$OPERATIONMODE" = "SERVICE" ]; then
+ SLAVE_APPLICATION=second_address_test_service
+
+ if [ "$COMMUNICATIONMODE" = "TCP" ]; then
+ export VSOMEIP_CONFIGURATION=second_address_test_slave_service_tcp.json
+ elif [ "$COMMUNICATIONMODE" = "UDP" ]; then
+ export VSOMEIP_CONFIGURATION=second_address_test_slave_service_udp.json
+ fi
+fi
+
+../../examples/routingmanagerd/routingmanagerd &
+PID_VSOMEIPD=$!
+
+./$SLAVE_APPLICATION $COMMUNICATIONMODE &
+PID_SLAVE=$!
+
+# Wait until all slaves are finished
+for job in $PID_SLAVE
+do
+ # Fail gets incremented if a client exits with a non-zero exit code
+ echo "waiting for $job"
+ wait $job || FAIL=$(($FAIL+1))
+done
+
+# kill the services
+kill $PID_VSOMEIPD
+sleep 1
+
+# Delete second IP address
+ip addr del @TEST_IP_SLAVE_SECOND@/32 dev eth0
+
+# Check if everything went well
+exit $FAIL
diff --git a/test/network_tests/second_address_tests/second_address_test_client.cpp b/test/network_tests/second_address_tests/second_address_test_client.cpp
new file mode 100644
index 0000000..9f05706
--- /dev/null
+++ b/test/network_tests/second_address_tests/second_address_test_client.cpp
@@ -0,0 +1,353 @@
+// Copyright (C) 2014-2018 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 <chrono>
+#include <condition_variable>
+#include <iomanip>
+#include <iostream>
+#include <sstream>
+#include <thread>
+#include <map>
+#include <algorithm>
+#include <atomic>
+
+#include <gtest/gtest.h>
+
+#include <vsomeip/vsomeip.hpp>
+#include <vsomeip/internal/logger.hpp>
+
+#include "second_address_test_globals.hpp"
+
+class second_address_test_client {
+public:
+ second_address_test_client(struct second_address_test::service_info _service_info, bool _use_tcp) :
+ service_info_(_service_info),
+ use_tcp_(_use_tcp),
+ app_(vsomeip::runtime::get()->create_application("second_address_test_client")),
+ send_thread_(std::bind(&second_address_test_client::send, this)) {
+
+ if (!app_->init()) {
+ ADD_FAILURE() << "Couldn't initialize application";
+ return;
+ }
+
+ app_->register_state_handler(
+ std::bind(&second_address_test_client::on_state, this,
+ std::placeholders::_1));
+
+ app_->register_message_handler(service_info_.service_id,
+ service_info_.instance_id, service_info_.request_method_id,
+ std::bind(&second_address_test_client::on_message, this,
+ std::placeholders::_1));
+
+ app_->register_message_handler(service_info_.service_id,
+ service_info_.instance_id, service_info_.event_id,
+ std::bind(&second_address_test_client::on_notification, this,
+ std::placeholders::_1, false));
+
+ app_->register_message_handler(service_info_.service_id,
+ service_info_.instance_id, service_info_.selective_event_id,
+ std::bind(&second_address_test_client::on_notification, this,
+ std::placeholders::_1, true));
+
+ app_->register_message_handler(service_info_.service_id,
+ service_info_.instance_id, service_info_.shutdown_method_id,
+ std::bind(&second_address_test_client::on_shutdown_method_called, this,
+ std::placeholders::_1));
+
+ // register availability for all other services and request their event.
+ app_->register_availability_handler(service_info_.service_id,
+ service_info_.instance_id,
+ std::bind(&second_address_test_client::on_availability, this,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3));
+
+ app_->request_service(service_info_.service_id,
+ service_info_.instance_id);
+
+ app_->register_subscription_status_handler(service_info_.service_id,
+ service_info_.instance_id, service_info_.eventgroup_id,
+ service_info_.event_id,
+ std::bind(&second_address_test_client::on_subscription_status_changed, this,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3, std::placeholders::_4,
+ std::placeholders::_5, false));
+
+ app_->register_subscription_status_handler(service_info_.service_id,
+ service_info_.instance_id, service_info_.selective_eventgroup_id,
+ service_info_.selective_event_id,
+ std::bind(&second_address_test_client::on_subscription_status_changed, this,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3, std::placeholders::_4,
+ std::placeholders::_5, true));
+
+ app_->start();
+ }
+
+ ~second_address_test_client() {
+ send_thread_.join();
+ }
+
+ void subscribe() {
+ std::set<vsomeip::eventgroup_t> its_eventgroups;
+ its_eventgroups.insert(service_info_.eventgroup_id);
+
+ app_->request_event(service_info_.service_id,
+ service_info_.instance_id, service_info_.event_id,
+ its_eventgroups, vsomeip::event_type_e::ET_EVENT);
+
+ its_eventgroups.clear();
+ its_eventgroups.insert(service_info_.selective_eventgroup_id);
+
+ app_->request_event(service_info_.service_id,
+ service_info_.instance_id, service_info_.selective_event_id,
+ its_eventgroups, vsomeip::event_type_e::ET_SELECTIVE_EVENT);
+
+ app_->subscribe(service_info_.service_id, service_info_.instance_id,
+ service_info_.eventgroup_id);
+
+ app_->subscribe(service_info_.service_id, service_info_.instance_id,
+ service_info_.selective_eventgroup_id);
+ }
+
+ void on_state(vsomeip::state_type_e _state) {
+ VSOMEIP_DEBUG << "Application " << app_->get_name() << " is "
+ << (_state == vsomeip::state_type_e::ST_REGISTERED ?
+ "registered" : "deregistered") << " on client.";
+
+ if (_state == vsomeip::state_type_e::ST_REGISTERED) {
+ std::lock_guard<std::mutex> its_lock(mutex_);
+ wait_until_registered_ = false;
+ condition_.notify_one();
+ }
+ }
+
+ void on_availability(vsomeip::service_t _service, vsomeip::instance_t _instance,
+ bool _is_available) {
+
+ VSOMEIP_DEBUG << "Service [" << std::setw(4)
+ << std::setfill('0') << std::hex << _service << "." << _instance
+ << "] is " << (_is_available ? "available":"not available") << " on client.";
+
+ if (_is_available) {
+ std::lock_guard<std::mutex> its_lock(mutex_);
+ wait_until_service_available_ = false;
+ condition_.notify_one();
+ }
+ }
+
+ void on_message(const std::shared_ptr<vsomeip::message> &_message) {
+ EXPECT_EQ(service_info_.service_id, _message->get_service());
+ EXPECT_EQ(service_info_.instance_id, _message->get_instance());
+ EXPECT_EQ(service_info_.request_method_id, _message->get_method());
+
+ std::lock_guard<std::mutex> its_lock(mutex_);
+ auto its_payload = _message->get_payload();
+ std::uint32_t data = static_cast<std::uint32_t>(its_payload->get_data()[0]);
+
+ EXPECT_EQ(reply_received_, data);
+
+ wait_until_reply_received_ = false;
+ reply_received_++;
+ condition_.notify_one();
+ }
+
+ void on_notification(const std::shared_ptr<vsomeip::message> &_message,
+ bool _selective) {
+ EXPECT_EQ(service_info_.service_id, _message->get_service());
+ EXPECT_EQ(service_info_.instance_id, _message->get_instance());
+
+ static vsomeip::length_t length_last_received_msg(0);
+ EXPECT_GT(_message->get_payload()->get_length(), length_last_received_msg);
+ length_last_received_msg = _message->get_payload()->get_length();
+
+ if (_selective) {
+ EXPECT_EQ(service_info_.selective_event_id, _message->get_method());
+
+ if (++number_selective_events_received_ == second_address_test::number_of_events_to_send) {
+ std::lock_guard<std::mutex> its_lock(mutex_);
+ wait_until_selective_events_received_ = false;
+ condition_.notify_one();
+ }
+ } else {
+ EXPECT_EQ(service_info_.event_id, _message->get_method());
+
+ if (++number_events_received_ == second_address_test::number_of_events_to_send) {
+ std::lock_guard<std::mutex> its_lock(mutex_);
+ wait_until_events_received_ = false;
+ condition_.notify_one();
+ }
+ }
+ }
+
+ void on_subscription_status_changed(const vsomeip::service_t _service,
+ const vsomeip::instance_t _instance,
+ const vsomeip::eventgroup_t _eventgroup,
+ const vsomeip::event_t _event,
+ const uint16_t error_code,
+ bool _selective) {
+
+ VSOMEIP_DEBUG << "Subscription status changed on client";
+
+ EXPECT_EQ(service_info_.service_id, _service);
+ EXPECT_EQ(service_info_.instance_id, _instance);
+ EXPECT_TRUE((error_code == 0x0u || error_code == 0x7u));
+
+ if (_selective) {
+ EXPECT_EQ(service_info_.selective_eventgroup_id, _eventgroup);
+ EXPECT_EQ(service_info_.selective_event_id, _event);
+
+ if (error_code == 0x0u) { // accepted
+ std::lock_guard<std::mutex> its_lock(mutex_);
+ wait_until_selective_subscription_accepted_ = false;
+ condition_.notify_one();
+ }
+
+ } else {
+ EXPECT_EQ(service_info_.eventgroup_id, _eventgroup);
+ EXPECT_EQ(service_info_.event_id, _event);
+
+ if (error_code == 0x0u) { // accepted
+ std::lock_guard<std::mutex> its_lock(mutex_);
+ wait_until_subscription_accepted_ = false;
+ condition_.notify_one();
+ }
+ }
+ }
+
+ void on_shutdown_method_called(const std::shared_ptr<vsomeip::message> &_message) {
+ EXPECT_EQ(service_info_.service_id, _message->get_service());
+ EXPECT_EQ(service_info_.instance_id, _message->get_instance());
+ EXPECT_EQ(service_info_.shutdown_method_id, _message->get_method());
+
+ std::lock_guard<std::mutex> its_lock(mutex_);
+ wait_until_shutdown_reply_received_ = false;
+ condition_.notify_one();
+ }
+
+ void send() {
+ std::unique_lock<std::mutex> its_lock(mutex_);
+ while (wait_until_registered_) {
+ condition_.wait(its_lock);
+ }
+
+ while (wait_until_service_available_) {
+ condition_.wait(its_lock);
+ }
+
+ auto its_message = vsomeip::runtime::get()->create_request(use_tcp_);
+ its_message->set_service(service_info_.service_id);
+ its_message->set_instance(service_info_.instance_id);
+ its_message->set_method(service_info_.request_method_id);
+ its_message->set_message_type(vsomeip::message_type_e::MT_REQUEST);
+
+ auto its_payload = vsomeip::runtime::get()->create_payload();
+
+ VSOMEIP_DEBUG << "Client sending request messages";
+
+ for (std::uint32_t index = 0; index < second_address_test::number_of_messages_to_send; index++) {
+ vsomeip::byte_t *msg_payload = reinterpret_cast<vsomeip::byte_t *>(&index);
+ its_payload->set_data(msg_payload, sizeof(index));
+ its_message->set_payload(its_payload);
+ app_->send(its_message);
+
+ wait_until_reply_received_ = true;
+ message_sent_++;
+
+ while (wait_until_reply_received_) {
+ condition_.wait(its_lock);
+ }
+ }
+
+ VSOMEIP_DEBUG << "Client subscribing events";
+
+ subscribe();
+ while (wait_until_subscription_accepted_ || wait_until_selective_subscription_accepted_) {
+ condition_.wait(its_lock);
+ }
+
+ VSOMEIP_DEBUG << "Client requesting event notification";
+
+ its_message->set_method(service_info_.notify_method_id);
+ its_message->set_message_type(vsomeip::message_type_e::MT_REQUEST_NO_RETURN);
+ its_payload->set_data(&second_address_test::number_of_events_to_send, 1);
+ its_message->set_payload(its_payload);
+ app_->send(its_message);
+
+ VSOMEIP_DEBUG << "Client waiting event notification";
+
+ while (wait_until_events_received_ || wait_until_selective_events_received_) {
+ condition_.wait(its_lock);
+ }
+
+ VSOMEIP_DEBUG << "Client shutting down the service";
+
+ // shutdown service
+ its_message->set_method(service_info_.shutdown_method_id);
+ its_message->set_message_type(vsomeip::message_type_e::MT_REQUEST);
+ app_->send(its_message);
+
+ while (wait_until_shutdown_reply_received_) {
+ if (std::cv_status::timeout == condition_.wait_for(its_lock, std::chrono::seconds(30))) {
+ VSOMEIP_ERROR << "Shutdown request wasn't answered in time!";
+ break;
+ }
+ }
+
+ VSOMEIP_INFO << "Client going down";
+ app_->clear_all_handler();
+ app_->stop();
+ }
+
+
+private:
+ struct second_address_test::service_info service_info_;
+ bool use_tcp_;
+ std::shared_ptr<vsomeip::application> app_;
+
+ bool wait_until_registered_ = true;
+ bool wait_until_service_available_ = true;
+ bool wait_until_subscription_accepted_ = true;
+ bool wait_until_selective_subscription_accepted_ = true;
+ bool wait_until_shutdown_reply_received_ = true;
+ bool wait_until_reply_received_ = true;
+ bool wait_until_events_received_ = true;
+ bool wait_until_selective_events_received_ = true;
+ std::mutex mutex_;
+ std::condition_variable condition_;
+
+ std::thread send_thread_;
+ std::uint32_t message_sent_ = 0;
+ std::uint32_t reply_received_ = 0;
+ std::uint32_t number_events_received_ = 0;
+ std::uint32_t number_selective_events_received_ = 0;
+};
+
+static bool use_tcp = false;
+
+TEST(someip_event_test, communicate_using_second_address)
+{
+ second_address_test_client its_sample(second_address_test::service, use_tcp);
+}
+
+#if defined(__linux__) || defined(ANDROID)
+int main(int argc, char** argv)
+{
+ ::testing::InitGoogleTest(&argc, argv);
+ if (argc < 2) {
+ std::cerr << "Please specify a communication mode, like: " << argv[0] << " TCP" << std::endl;
+ std::cerr << "Valid communication modes are UDP or TCP" << std::endl;
+ return 1;
+ }
+
+ if (std::string("TCP")== std::string(argv[1])) {
+ use_tcp = true;
+ } else if (std::string("UDP")== std::string(argv[1])) {
+ use_tcp = false;
+ }
+
+ return RUN_ALL_TESTS();
+}
+#endif
diff --git a/test/network_tests/second_address_tests/second_address_test_globals.hpp b/test/network_tests/second_address_tests/second_address_test_globals.hpp
new file mode 100644
index 0000000..1909fcd
--- /dev/null
+++ b/test/network_tests/second_address_tests/second_address_test_globals.hpp
@@ -0,0 +1,29 @@
+// Copyright (C) 2014-2019 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 SECOND_ADDRESS_TEST_GLOBALS_HPP_
+#define SECOND_ADDRESS_TEST_GLOBALS_HPP_
+
+namespace second_address_test {
+
+struct service_info {
+ vsomeip::service_t service_id;
+ vsomeip::instance_t instance_id;
+ vsomeip::eventgroup_t eventgroup_id;
+ vsomeip::event_t event_id;
+ vsomeip::eventgroup_t selective_eventgroup_id;
+ vsomeip::event_t selective_event_id;
+ vsomeip::method_t request_method_id;
+ vsomeip::method_t notify_method_id;
+ vsomeip::method_t shutdown_method_id;
+};
+
+struct service_info service = { 0x3333, 0x1, 0x1, 0x3301, 0x2, 0x3302, 0x1111, 0x2222, 0x1404 };
+
+static constexpr std::uint32_t number_of_messages_to_send = 150;
+static constexpr std::uint8_t number_of_events_to_send = 150;
+}
+
+#endif /* SECOND_ADDRESS_TEST_GLOBALS_HPP_ */
diff --git a/test/network_tests/second_address_tests/second_address_test_master_starter.sh b/test/network_tests/second_address_tests/second_address_test_master_starter.sh
new file mode 100755
index 0000000..03d726b
--- /dev/null
+++ b/test/network_tests/second_address_tests/second_address_test_master_starter.sh
@@ -0,0 +1,77 @@
+#!/bin/bash
+# Copyright (C) 2015-2019 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/.
+
+FAIL=0
+
+if [ $# -lt 2 ]
+then
+ echo "Please pass a operation and communication mode to this script."
+ echo "For example: $0 SERVICE UDP"
+ echo "Valid operation modes include [SERVICE, CLIENT]"
+ echo "Valid communication modes include [UDP, TCP]"
+ exit 1
+fi
+
+OPERATIONMODE=$1
+COMMUNICATIONMODE=$2
+
+if [ "$OPERATIONMODE" = "SERVICE" ]; then
+ MASTER_APPLICATION=second_address_test_service
+ SLAVE_OPERATIONMODE="CLIENT"
+
+ if [ "$COMMUNICATIONMODE" = "TCP" ]; then
+ export VSOMEIP_CONFIGURATION=second_address_test_master_service_tcp.json
+ elif [ "$COMMUNICATIONMODE" = "UDP" ]; then
+ export VSOMEIP_CONFIGURATION=second_address_test_master_service_udp.json
+ fi
+
+elif [ "$OPERATIONMODE" = "CLIENT" ]; then
+ MASTER_APPLICATION=second_address_test_client
+ SLAVE_OPERATIONMODE="SERVICE"
+ export VSOMEIP_CONFIGURATION=second_address_test_master_client.json
+fi
+
+../../examples/routingmanagerd/routingmanagerd &
+PID_VSOMEIPD=$!
+
+./$MASTER_APPLICATION $COMMUNICATIONMODE &
+PID_MASTER=$!
+
+sleep 1
+
+if [ ! -z "$USE_LXC_TEST" ]; then
+ echo "starting offer test on slave LXC second_address_test_slave_starter.sh"
+ 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; ./second_address_test_slave_starter.sh $SLAVE_OPERATIONMODE $COMMUNICATIONMODE\"" &
+elif [ ! -z "$USE_DOCKER" ]; then
+ docker exec $DOCKER_IMAGE sh -c "cd $DOCKER_TESTS; sleep 10; ./second_address_test_slave_starter.sh $SLAVE_OPERATIONMODE $COMMUNICATIONMODE" &
+else
+cat <<End-of-message
+*******************************************************************************
+*******************************************************************************
+** Please now run:
+** second_address_test_slave_starter.sh $COMMUNICATIONMODE
+** from an external host to successfully complete this test.
+**
+** You probably will need to adapt the 'unicast' settings in
+** second_address_test_slave_{udp,tcp}.json to your personal setup.
+*******************************************************************************
+*******************************************************************************
+End-of-message
+fi
+
+# Wait until all slaves are finished
+for job in $PID_MASTER
+do
+ # Fail gets incremented if a client exits with a non-zero exit code
+ echo "waiting for $job"
+ wait $job || FAIL=$(($FAIL+1))
+done
+
+kill $PID_VSOMEIPD
+sleep 1
+
+# Check if everything went well
+exit $FAIL
diff --git a/test/network_tests/second_address_tests/second_address_test_service.cpp b/test/network_tests/second_address_tests/second_address_test_service.cpp
new file mode 100644
index 0000000..c675eee
--- /dev/null
+++ b/test/network_tests/second_address_tests/second_address_test_service.cpp
@@ -0,0 +1,252 @@
+// Copyright (C) 2014-2019 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 <chrono>
+#include <condition_variable>
+#include <iostream>
+#include <sstream>
+#include <thread>
+#include <map>
+
+#include <gtest/gtest.h>
+#include <vsomeip/vsomeip.hpp>
+#include <vsomeip/internal/logger.hpp>
+
+#include "second_address_test_globals.hpp"
+
+class second_address_test_service {
+public:
+ second_address_test_service(struct second_address_test::service_info _service_info) :
+ service_info_(_service_info),
+ app_(vsomeip::runtime::get()->create_application("second_address_test_service")),
+ offer_thread_(std::bind(&second_address_test_service::run, this)) {
+
+ if (!app_->init()) {
+ ADD_FAILURE() << "Couldn't initialize application";
+ return;
+ }
+
+ app_->register_state_handler(
+ std::bind(&second_address_test_service::on_state, this,
+ std::placeholders::_1));
+
+ app_->register_message_handler(service_info_.service_id,
+ service_info_.instance_id, service_info_.request_method_id,
+ std::bind(&second_address_test_service::on_message, this,
+ std::placeholders::_1));
+
+ app_->register_message_handler(service_info_.service_id,
+ service_info_.instance_id, service_info_.notify_method_id,
+ std::bind(&second_address_test_service::on_notify, this,
+ std::placeholders::_1));
+
+ app_->register_message_handler(service_info_.service_id,
+ service_info_.instance_id, service_info_.shutdown_method_id,
+ std::bind(&second_address_test_service::on_shutdown_method_called, this,
+ std::placeholders::_1));
+
+ app_->register_subscription_handler(service_info_.service_id,
+ service_info_.instance_id, service_info_.eventgroup_id,
+ std::bind(&second_address_test_service::subscription_handler,
+ this, std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3, std::placeholders::_4));
+
+ app_->register_subscription_handler(service_info_.service_id,
+ service_info_.instance_id, service_info_.selective_eventgroup_id,
+ std::bind(&second_address_test_service::selective_subscription_handler,
+ this, std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3, std::placeholders::_4));
+
+ app_->start();
+ }
+
+ ~second_address_test_service() {
+ offer_thread_.join();
+ }
+
+ void stop() {
+ app_->stop_offer_service(service_info_.service_id, service_info_.instance_id);
+ app_->clear_all_handler();
+ app_->stop();
+ }
+
+private:
+ void on_state(vsomeip::state_type_e _state) {
+ VSOMEIP_INFO << "Application " << app_->get_name() << " is "
+ << (_state == vsomeip::state_type_e::ST_REGISTERED ?
+ "registered" : "deregistered") << " on service.";
+
+ if (_state == vsomeip::state_type_e::ST_REGISTERED) {
+ std::lock_guard<std::mutex> its_lock(mutex_);
+ wait_until_registered_ = false;
+ condition_.notify_one();
+ }
+ }
+
+ void on_shutdown_method_called(const std::shared_ptr<vsomeip::message> &_message) {
+ app_->send(vsomeip::runtime::get()->create_response(_message));
+
+ VSOMEIP_WARNING << "************************************************************";
+ VSOMEIP_WARNING << "Shutdown method called on service -> going down!";
+ VSOMEIP_WARNING << "************************************************************";
+
+ std::lock_guard<std::mutex> its_lock(mutex_);
+ wait_until_shutdown_method_called_ = false;
+ condition_.notify_one();
+ }
+
+ void on_message(const std::shared_ptr<vsomeip::message> &_message) {
+ EXPECT_EQ(service_info_.service_id, _message->get_service());
+ EXPECT_EQ(service_info_.request_method_id, _message->get_method());
+ EXPECT_EQ(service_info_.instance_id, _message->get_instance());
+
+ std::shared_ptr<vsomeip::message> response = vsomeip::runtime::get()->create_response(_message);
+ response->set_payload(_message->get_payload());
+ app_->send(response);
+
+ std::lock_guard<std::mutex> its_lock(mutex_);
+ messages_received_++;
+
+ if (messages_received_ == second_address_test::number_of_messages_to_send) {
+ wait_until_receive_messages_ = false;
+ condition_.notify_one();
+ }
+ }
+
+ void on_notify(const std::shared_ptr<vsomeip::message> &_message) {
+ EXPECT_EQ(service_info_.service_id, _message->get_service());
+ EXPECT_EQ(service_info_.notify_method_id, _message->get_method());
+ EXPECT_EQ(service_info_.instance_id, _message->get_instance());
+
+ auto its_payload = _message->get_payload();
+ notifications_to_send_ = its_payload->get_data()[0];
+
+ std::lock_guard<std::mutex> its_lock(mutex_);
+ wait_until_notify_method_called_ = false;
+ condition_.notify_one();
+ }
+
+ void offer() {
+ app_->offer_service(service_info_.service_id, service_info_.instance_id);
+
+ std::set<vsomeip::eventgroup_t> its_eventgroups;
+ its_eventgroups.insert(service_info_.eventgroup_id);
+
+ app_->offer_event(service_info_.service_id, service_info_.instance_id,
+ service_info_.event_id, its_eventgroups,
+ vsomeip::event_type_e::ET_EVENT, std::chrono::milliseconds::zero(),
+ false, true, nullptr, vsomeip::reliability_type_e::RT_UNKNOWN);
+
+ its_eventgroups.clear();
+ its_eventgroups.insert(service_info_.selective_eventgroup_id);
+
+ app_->offer_event(service_info_.service_id, service_info_.instance_id,
+ service_info_.selective_event_id, its_eventgroups,
+ vsomeip::event_type_e::ET_SELECTIVE_EVENT, std::chrono::milliseconds::zero(),
+ false, true, nullptr, vsomeip::reliability_type_e::RT_UNKNOWN);
+ }
+
+ void notify() {
+ EXPECT_TRUE(client_subscribed_);
+ EXPECT_TRUE(client_subscribed_selective_);
+ auto its_payload = vsomeip::runtime::get()->create_payload();
+
+ std::uint32_t i = 0;
+
+ for (; i < notifications_to_send_; i++) {
+ its_payload->set_data(std::vector<vsomeip::byte_t>(i+1, 0x55));
+ app_->notify(service_info_.service_id, service_info_.instance_id,
+ service_info_.event_id, its_payload);
+ }
+
+ for (; i < 2 * notifications_to_send_; i++) {
+ its_payload->set_data(std::vector<vsomeip::byte_t>(i+1, 0x55));
+ app_->notify_one(service_info_.service_id, service_info_.instance_id,
+ service_info_.selective_event_id, its_payload, client_id_);
+ }
+ }
+
+ void run() {
+ VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex
+ << service_info_.service_id << "] Running";
+
+ std::unique_lock<std::mutex> its_lock(mutex_);
+ while (wait_until_registered_) {
+ condition_.wait(its_lock);
+ }
+
+ VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex
+ << service_info_.service_id << "] Offering";
+ offer();
+
+ while (wait_until_receive_messages_) {
+ condition_.wait(its_lock);
+ }
+
+ VSOMEIP_DEBUG << "Service waiting for notify method has been called";
+ while (wait_until_notify_method_called_) {
+ condition_.wait(its_lock);
+ }
+
+ VSOMEIP_DEBUG << "Service notifying events";
+ notify();
+
+ while (wait_until_shutdown_method_called_) {
+ condition_.wait(its_lock);
+ }
+
+ its_lock.unlock();
+ stop();
+ }
+
+ bool subscription_handler(vsomeip::client_t _client, std::uint32_t _uid, std::uint32_t _gid, bool _subscribed) {
+ (void)_uid;
+ (void)_gid;
+ VSOMEIP_DEBUG << __func__ << ": client 0x" << std::hex << std::setw(4) << std::setfill('0') << _client
+ << ((_subscribed) ? " subscribed" : "unsubscribed") << " on service.";
+ client_subscribed_ = _subscribed;
+ return true;
+ }
+
+ bool selective_subscription_handler(vsomeip::client_t _client, std::uint32_t _uid, std::uint32_t _gid, bool _subscribed) {
+ (void)_uid;
+ (void)_gid;
+ VSOMEIP_DEBUG << __func__ << ": client 0x" << std::hex << std::setw(4) << std::setfill('0') << _client
+ << ((_subscribed) ? " subscribed" : "unsubscribed") << " on service.";
+ client_subscribed_selective_ = _subscribed;
+ client_id_ = _client;
+ return true;
+ }
+
+private:
+ struct second_address_test::service_info service_info_;
+ std::shared_ptr<vsomeip::application> app_;
+
+ bool wait_until_registered_ = true;
+ bool wait_until_receive_messages_ = true;
+ bool wait_until_notify_method_called_ = true;
+ bool wait_until_shutdown_method_called_ = true;
+ bool client_subscribed_ = false;
+ bool client_subscribed_selective_ = false;
+ vsomeip::client_t client_id_ = 0;
+ std::uint32_t messages_received_ = 0;
+ std::uint8_t notifications_to_send_ = 0;
+ std::mutex mutex_;
+ std::condition_variable condition_;
+ std::thread offer_thread_;
+};
+
+TEST(someip_second_address_test, test_communication_with_client)
+{
+ second_address_test_service its_sample(second_address_test::service);
+}
+
+#if defined(__linux__) || defined(ANDROID)
+int main(int argc, char** argv)
+{
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
+#endif