1 // Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
2 // This Source Code Form is subject to the terms of the Mozilla Public
3 // License, v. 2.0. If a copy of the MPL was not distributed with this
4 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
6 #include <chrono>
7 #include <condition_variable>
8 #include <iomanip>
9 #include <iostream>
10 #include <sstream>
11 #include <thread>
12 #include <map>
13 #include <algorithm>
14
15 #include <gtest/gtest.h>
16
17 #include <vsomeip/vsomeip.hpp>
18 #include <vsomeip/internal/logger.hpp>
19
20 #include "offer_test_globals.hpp"
21
22 static std::string service_number;
23
24 class offer_test_service {
25 public:
offer_test_service(struct offer_test::service_info _service_info)26 offer_test_service(struct offer_test::service_info _service_info) :
27 service_info_(_service_info),
28 // service with number 1 uses "routingmanagerd" as application name
29 // this way the same json file can be reused for all local tests
30 // including the ones with routingmanagerd
31 app_(vsomeip::runtime::get()->create_application(
32 (service_number == "1") ? "routingmanagerd" :
33 "offer_test_service" + service_number)),
34 wait_until_registered_(true),
35 wait_until_service_available_(true),
36 offer_thread_(std::bind(&offer_test_service::run, this)) {
37 if (!app_->init()) {
38 ADD_FAILURE() << "Couldn't initialize application";
39 return;
40 }
41 app_->register_state_handler(
42 std::bind(&offer_test_service::on_state, this,
43 std::placeholders::_1));
44
45 app_->register_availability_handler(service_info_.service_id,
46 service_info_.instance_id,
47 std::bind(&offer_test_service::on_availability, this,
48 std::placeholders::_1, std::placeholders::_2,
49 std::placeholders::_3));
50 app_->request_service(service_info_.service_id,
51 service_info_.instance_id);
52 app_->start();
53 }
54
~offer_test_service()55 ~offer_test_service() {
56 offer_thread_.join();
57 }
58
offer()59 void offer() {
60 app_->offer_service(service_info_.service_id, service_info_.instance_id);
61 // this is allowed
62 app_->offer_service(service_info_.service_id, service_info_.instance_id);
63 // this is not allowed and will be rejected
64 app_->offer_service(service_info_.service_id, service_info_.instance_id, 33, 4711);
65 }
66
on_state(vsomeip::state_type_e _state)67 void on_state(vsomeip::state_type_e _state) {
68 VSOMEIP_INFO << "Application " << app_->get_name() << " is "
69 << (_state == vsomeip::state_type_e::ST_REGISTERED ?
70 "registered." : "deregistered.");
71
72 if (_state == vsomeip::state_type_e::ST_REGISTERED) {
73 std::lock_guard<std::mutex> its_lock(mutex_);
74 wait_until_registered_ = false;
75 condition_.notify_one();
76 }
77 }
78
on_availability(vsomeip::service_t _service,vsomeip::instance_t _instance,bool _is_available)79 void on_availability(vsomeip::service_t _service,
80 vsomeip::instance_t _instance, bool _is_available) {
81 VSOMEIP_INFO << "Service [" << std::setw(4)
82 << std::setfill('0') << std::hex << _service << "." << _instance
83 << "] is " << (_is_available ? "available":"not available") << ".";
84 std::lock_guard<std::mutex> its_lock(mutex_);
85 if(_is_available) {
86 wait_until_service_available_ = false;
87 condition_.notify_one();
88 } else {
89 wait_until_service_available_ = true;
90 condition_.notify_one();
91 }
92 }
93
run()94 void run() {
95 VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex
96 << service_info_.service_id << "] Running";
97 {
98 std::unique_lock<std::mutex> its_lock(mutex_);
99 while (wait_until_registered_) {
100 condition_.wait(its_lock);
101 }
102
103 VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex
104 << service_info_.service_id << "] Offering";
105 offer();
106
107 while(wait_until_service_available_) {
108 condition_.wait(its_lock);
109 }
110 }
111
112 std::this_thread::sleep_for(std::chrono::seconds(1));
113 VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex
114 << service_info_.service_id << "] Calling stop method";
115 std::shared_ptr<vsomeip::message> msg(vsomeip::runtime::get()->create_request());
116 msg->set_service(service_info_.service_id);
117 msg->set_instance(service_info_.instance_id);
118 msg->set_method(service_info_.shutdown_method_id);
119 msg->set_message_type(vsomeip::message_type_e::MT_REQUEST_NO_RETURN);
120 app_->send(msg);
121 std::this_thread::sleep_for(std::chrono::seconds(2));
122 app_->clear_all_handler();
123 app_->stop();
124 }
125
126 private:
127 struct offer_test::service_info service_info_;
128 std::shared_ptr<vsomeip::application> app_;
129
130 bool wait_until_registered_;
131 bool wait_until_service_available_;
132 std::mutex mutex_;
133 std::condition_variable condition_;
134 std::thread offer_thread_;
135 };
136
TEST(someip_offer_test,notify_increasing_counter)137 TEST(someip_offer_test, notify_increasing_counter)
138 {
139 offer_test_service its_sample(offer_test::service);
140 }
141
142
143 #ifndef _WIN32
main(int argc,char ** argv)144 int main(int argc, char** argv)
145 {
146 ::testing::InitGoogleTest(&argc, argv);
147 if(argc < 2) {
148 std::cerr << "Please specify a service number, like: " << argv[0] << " 2" << std::endl;
149 return 1;
150 }
151
152 service_number = std::string(argv[1]);
153 return RUN_ALL_TESTS();
154 }
155 #endif
156