diff options
Diffstat (limited to 'test/suspend_resume_tests/suspend_resume_test_service.cpp')
-rw-r--r-- | test/suspend_resume_tests/suspend_resume_test_service.cpp | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/test/suspend_resume_tests/suspend_resume_test_service.cpp b/test/suspend_resume_tests/suspend_resume_test_service.cpp new file mode 100644 index 0000000..205a2ce --- /dev/null +++ b/test/suspend_resume_tests/suspend_resume_test_service.cpp @@ -0,0 +1,213 @@ +// 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 <atomic> + +#include <gtest/gtest.h> + +#include <vsomeip/vsomeip.hpp> +#include <vsomeip/internal/logger.hpp> + +#include "suspend_resume_test.hpp" + +pid_t daemon_pid__; + +class suspend_resume_test_service { +public: + suspend_resume_test_service() + : name_("suspend_resume_test_service"), + app_(vsomeip::runtime::get()->create_application(name_)), + is_running_(true), + is_unblocked_(false), + runner_(std::bind(&suspend_resume_test_service::run, this)), + sr_runner_(std::bind(&suspend_resume_test_service::sr_run, this)) { + } + + void run_test() { + + register_state_handler(); + register_message_handler(); + register_subscription_handler(); + + start(); + + VSOMEIP_DEBUG << "Using daemon with pid=" << std::dec << daemon_pid__; + + { + std::unique_lock<std::mutex> its_lock(mutex_); + auto r = cv_.wait_for(its_lock, std::chrono::seconds(30)); + EXPECT_EQ(r, std::cv_status::no_timeout); + } + + stop(); + } + +private: + void start() { + + app_->init(); + cv_.notify_one(); + } + + void stop() { + + is_running_ = false; + sr_cv_.notify_one(); + + app_->stop(); + + runner_.join(); + sr_runner_.join(); + } + + void run() { + + { + std::unique_lock<std::mutex> its_lock(mutex_); + cv_.wait(its_lock); + } + + app_->start(); + } + + void sr_run() { + + while (is_running_) { + std::unique_lock<std::mutex> its_lock(sr_mutex_); + sr_cv_.wait(its_lock); + + if (is_running_) { + VSOMEIP_DEBUG << "send kill SIGUSR1 to PID: " << std::dec << daemon_pid__; + kill(daemon_pid__, SIGUSR1); + std::this_thread::sleep_for(std::chrono::seconds(5)); + VSOMEIP_DEBUG << "send kill SIGUSR2 to PID: " << std::dec << daemon_pid__; + kill(daemon_pid__, SIGUSR2); + } + } + } + + void register_state_handler() { + + app_->register_state_handler( + std::bind(&suspend_resume_test_service::on_state, this, std::placeholders::_1)); + } + + void register_message_handler() { + + app_->register_message_handler(TEST_SERVICE, TEST_INSTANCE, TEST_METHOD, + std::bind(&suspend_resume_test_service::on_message, this, + std::placeholders::_1)); + } + + void register_subscription_handler() { + + app_->register_subscription_handler(TEST_SERVICE, TEST_INSTANCE, TEST_EVENTGROUP, + std::bind(&suspend_resume_test_service::on_subscribe, this, + std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)); + } + + void offer_service() { + app_->offer_event(TEST_SERVICE, TEST_INSTANCE, TEST_EVENT, { TEST_EVENTGROUP }, + vsomeip::event_type_e::ET_FIELD, + std::chrono::milliseconds::zero(), false, true, nullptr, + vsomeip::reliability_type_e::RT_UNRELIABLE); + + vsomeip::byte_t its_data[] = { 0x1, 0x2, 0x3 }; + auto its_payload = vsomeip::runtime::get()->create_payload(); + its_payload->set_data(its_data, sizeof(its_data)); + app_->notify(TEST_SERVICE, TEST_INSTANCE, TEST_EVENT, its_payload); + + app_->offer_service(TEST_SERVICE, TEST_INSTANCE, TEST_MAJOR, TEST_MINOR); + } + + // handler + 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) { + offer_service(); + } + } + + void on_message(const std::shared_ptr<vsomeip::message> &_message) { + + VSOMEIP_DEBUG << __func__ << ": Received " + << std::hex << std::setw(4) << std::setfill('0') + << _message->get_service() + << std::hex << std::setw(4) << std::setfill('0') + << _message->get_instance() + << std::hex << std::setw(4) << std::setfill('0') + << _message->get_method(); + + if (_message->get_service() == TEST_SERVICE + && _message->get_instance() == TEST_INSTANCE + && _message->get_method() == TEST_METHOD) { + + if (_message->get_payload()->get_length() == 1) { + + vsomeip::byte_t its_control_byte(*_message->get_payload()->get_data()); + + switch (its_control_byte) { + case TEST_SUSPEND: + sr_cv_.notify_one(); + break; + case TEST_STOP: + cv_.notify_one(); + break; + default: + ; + } + } + } + } + + bool on_subscribe(vsomeip::client_t _client, + vsomeip::uid_t _uid, vsomeip::gid_t _gid, + bool _is_subscribe) { + + (void)_client; + (void)_uid; + (void)_gid; + + VSOMEIP_DEBUG << __func__ << ": is_subscribe=" << std::boolalpha << _is_subscribe; + if (!_is_subscribe) + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + return (true); + } + +private: // members + std::string name_; + std::shared_ptr<vsomeip::application> app_; + std::atomic<bool> is_running_; + bool is_unblocked_; + std::mutex mutex_; + std::condition_variable cv_; + std::mutex sr_mutex_; + std::condition_variable sr_cv_; + std::thread runner_; + std::thread sr_runner_; +}; + +TEST(suspend_resume_test, fast) +{ + suspend_resume_test_service its_service; + its_service.run_test(); +} + +#ifndef _WIN32 +int main(int argc, char** argv) { + + ::testing::InitGoogleTest(&argc, argv); + + daemon_pid__ = atoi(argv[1]); + + return RUN_ALL_TESTS(); +} +#endif // _WIN32 |