diff options
Diffstat (limited to 'test/network_tests/suspend_resume_tests/suspend_resume_test_client.cpp')
-rw-r--r-- | test/network_tests/suspend_resume_tests/suspend_resume_test_client.cpp | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/test/network_tests/suspend_resume_tests/suspend_resume_test_client.cpp b/test/network_tests/suspend_resume_tests/suspend_resume_test_client.cpp new file mode 100644 index 0000000..11ae578 --- /dev/null +++ b/test/network_tests/suspend_resume_tests/suspend_resume_test_client.cpp @@ -0,0 +1,239 @@ +// Copyright (C) 2021 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 <condition_variable> +#include <mutex> +#include <thread> + +#include <gtest/gtest.h> + +#include <vsomeip/vsomeip.hpp> +#include <vsomeip/internal/logger.hpp> + +#include "suspend_resume_test.hpp" + +class suspend_resume_test_client { +public: + suspend_resume_test_client() + : name_("suspend_resume_test_client"), + app_(vsomeip::runtime::get()->create_application(name_)), + has_received_(false), + runner_(std::bind(&suspend_resume_test_client::run, this)) { + + } + + void run_test() { + + register_state_handler(); + register_message_handler(); + register_availability_handler(); + + start(); + + { + VSOMEIP_DEBUG << "Started."; + std::unique_lock<std::mutex> its_lock(mutex_); + auto r = cv_.wait_for(its_lock, std::chrono::seconds(10)); + EXPECT_EQ(r, std::cv_status::no_timeout); + } + + toggle(); + + { + VSOMEIP_DEBUG << "Toggled."; + std::unique_lock<std::mutex> its_lock(mutex_); + if (!has_received_) { + auto r = cv_.wait_for(its_lock, std::chrono::seconds(10)); + EXPECT_EQ(r, std::cv_status::no_timeout); + } + } + + send_suspend(); + + bool was_successful; + { + VSOMEIP_DEBUG << "Triggered suspend/resume."; + + // Wait for service to become availaber after suspend/resume. + std::unique_lock<std::mutex> its_lock(mutex_); + auto r = cv_.wait_for(its_lock, std::chrono::seconds(10)); + EXPECT_EQ(r, std::cv_status::no_timeout); + + // Wait for initial event after suspend/resume. + r = cv_.wait_for(its_lock, std::chrono::seconds(10)); + EXPECT_EQ(r, std::cv_status::no_timeout); + + was_successful = (r == std::cv_status::no_timeout); + } + + if (was_successful) + send_stop(); + + stop(); + } + +private: + void register_state_handler() { + + app_->register_state_handler( + std::bind(&suspend_resume_test_client::on_state, this, std::placeholders::_1)); + } + + void register_availability_handler() { + + app_->register_availability_handler(TEST_SERVICE, TEST_INSTANCE, + std::bind(&suspend_resume_test_client::on_availability, this, + std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + } + + void register_message_handler() { + + app_->register_message_handler(TEST_SERVICE, TEST_INSTANCE, TEST_EVENT, + std::bind(&suspend_resume_test_client::on_message, this, + std::placeholders::_1)); + } + + void start() { + + app_->init(); + cv_.notify_one(); + } + + void run() { + + { + std::unique_lock<std::mutex> its_lock(mutex_); + cv_.wait(its_lock); + } + + app_->start(); + } + + void stop() { + + app_->stop(); + runner_.join(); + } + + void on_state(vsomeip::state_type_e _state) { + + VSOMEIP_DEBUG << __func__ << ": state=" + << (_state == vsomeip::state_type_e::ST_REGISTERED ? + "registered." : "NOT registered."); + + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + app_->request_event(TEST_SERVICE, TEST_INSTANCE, TEST_EVENT, { TEST_EVENTGROUP }); + app_->request_service(TEST_SERVICE, TEST_INSTANCE); + } + } + + void on_availability(vsomeip::service_t _service, vsomeip::instance_t _instance, bool _is_available) { + + static bool is_available(false); + + if (_service == TEST_SERVICE && _instance == TEST_INSTANCE) { + + VSOMEIP_DEBUG << __func__ << ": Test service is " + << (_is_available ? "available." : "NOT available."); + + if (_is_available) + cv_.notify_one(); + else if (is_available) + has_received_ = false; + + is_available = _is_available; + } + } + + void on_message(const std::shared_ptr<vsomeip::message> &_message) { + + if (_message->get_service() == TEST_SERVICE + && _message->get_instance() == TEST_INSTANCE + && _message->get_method() == TEST_EVENT) { + + VSOMEIP_DEBUG << __func__ << ": Received event."; + if (!has_received_) { + has_received_ = true; + cv_.notify_one(); + } + } + } + + void toggle() { + + app_->subscribe(TEST_SERVICE, TEST_INSTANCE, TEST_EVENTGROUP, TEST_MAJOR); + std::this_thread::sleep_for(std::chrono::seconds(3)); + app_->unsubscribe(TEST_SERVICE, TEST_INSTANCE, TEST_EVENTGROUP); + app_->subscribe(TEST_SERVICE, TEST_INSTANCE, TEST_EVENTGROUP, TEST_MAJOR); + std::this_thread::sleep_for(std::chrono::seconds(2)); + app_->unsubscribe(TEST_SERVICE, TEST_INSTANCE, TEST_EVENTGROUP); + app_->subscribe(TEST_SERVICE, TEST_INSTANCE, TEST_EVENTGROUP, TEST_MAJOR); + + } + + + void send_suspend() { + + auto its_message = vsomeip::runtime::get()->create_request(false); + its_message->set_service(TEST_SERVICE); + its_message->set_instance(TEST_INSTANCE); + its_message->set_method(TEST_METHOD); + its_message->set_interface_version(TEST_MAJOR); + its_message->set_message_type(vsomeip::message_type_e::MT_REQUEST_NO_RETURN); + its_message->set_return_code(vsomeip::return_code_e::E_OK); + + vsomeip::byte_t its_data[] = { TEST_SUSPEND }; + auto its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data(its_data, sizeof(its_data)); + its_message->set_payload(its_payload); + + app_->send(its_message); + + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + } + + void send_stop() { + + auto its_message = vsomeip::runtime::get()->create_request(false); + its_message->set_service(TEST_SERVICE); + its_message->set_instance(TEST_INSTANCE); + its_message->set_method(TEST_METHOD); + its_message->set_interface_version(TEST_MAJOR); + its_message->set_message_type(vsomeip::message_type_e::MT_REQUEST_NO_RETURN); + its_message->set_return_code(vsomeip::return_code_e::E_OK); + + vsomeip::byte_t its_data[] = { TEST_STOP }; + auto its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data(its_data, sizeof(its_data)); + its_message->set_payload(its_payload); + + app_->send(its_message); + + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + } + +private: // members + std::string name_; + std::shared_ptr<vsomeip::application> app_; + std::mutex mutex_; + std::condition_variable cv_; + bool has_received_; + std::thread runner_; +}; + +TEST(suspend_resume_test, fast) +{ + suspend_resume_test_client its_client; + its_client.run_test(); +} + +#if defined(__linux__) || defined(ANDROID) +int main(int argc, char** argv) { + + ::testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} +#endif |