1 // Copyright (C) 2015-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 <memory>
10 #include <thread>
11
12 #include <gtest/gtest.h>
13
14 #include <vsomeip/vsomeip.hpp>
15
16 #include "../someip_test_globals.hpp"
17 #include "../implementation/runtime/include/application_impl.hpp"
18 #include "../implementation/routing/include/routing_manager.hpp"
19
20 class magic_cookies_test_client {
21 public:
magic_cookies_test_client()22 magic_cookies_test_client()
23 : app_(new vsomeip::application_impl("")),
24 is_blocked_(false),
25 sent_messages_good_(8),
26 sent_messages_bad_(7),
27 received_responses_(0),
28 received_errors_(0),
29 wait_for_replies_(true),
30 runner_(std::bind(&magic_cookies_test_client::run, this)) {
31 }
32
init()33 void init() {
34 VSOMEIP_INFO << "Initializing...";
35 if (!app_->init()) {
36 ADD_FAILURE() << "Couldn't initialize application";
37 exit(EXIT_FAILURE);
38 }
39
40 app_->register_state_handler(
41 std::bind(
42 &magic_cookies_test_client::on_state,
43 this,
44 std::placeholders::_1));
45
46 app_->register_message_handler(
47 vsomeip::ANY_SERVICE, vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip::ANY_METHOD,
48 std::bind(&magic_cookies_test_client::on_message,
49 this,
50 std::placeholders::_1));
51
52 app_->register_availability_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID,
53 std::bind(&magic_cookies_test_client::on_availability,
54 this,
55 std::placeholders::_1, std::placeholders::_2, std::placeholders::_3),
56 vsomeip::DEFAULT_MAJOR, vsomeip::DEFAULT_MINOR);
57 }
58
start()59 void start() {
60 VSOMEIP_INFO << "Starting...";
61 app_->start();
62 }
63
stop()64 void stop() {
65 VSOMEIP_INFO << "Stopping...";
66 app_->clear_all_handler();
67 app_->stop();
68 }
69
on_state(vsomeip::state_type_e _state)70 void on_state(vsomeip::state_type_e _state) {
71 if (_state == vsomeip::state_type_e::ST_REGISTERED) {
72 VSOMEIP_INFO << "Client registration done.";
73 app_->request_service(vsomeip_test::TEST_SERVICE_SERVICE_ID,
74 vsomeip_test::TEST_SERVICE_INSTANCE_ID,
75 vsomeip::ANY_MAJOR, vsomeip::ANY_MINOR);
76 }
77 }
78
on_availability(vsomeip::service_t _service,vsomeip::instance_t _instance,bool _is_available)79 void on_availability(vsomeip::service_t _service, vsomeip::instance_t _instance, bool _is_available) {
80 VSOMEIP_INFO << "Service ["
81 << std::setw(4) << std::setfill('0') << std::hex << _service << "." << _instance
82 << "] is "
83 << (_is_available ? "available." : "NOT available.");
84
85 if (vsomeip_test::TEST_SERVICE_SERVICE_ID == _service && vsomeip_test::TEST_SERVICE_INSTANCE_ID == _instance) {
86 static bool is_available = false;
87 if (is_available && !_is_available) is_available = false;
88 else if (_is_available && !is_available) {
89 is_available = true;
90 std::lock_guard< std::mutex > its_lock(mutex_);
91 is_blocked_ = true;
92 condition_.notify_one();
93 }
94 }
95 }
96
on_message(const std::shared_ptr<vsomeip::message> & _response)97 void on_message(const std::shared_ptr< vsomeip::message > &_response) {
98 if (_response->get_return_code() == vsomeip::return_code_e::E_OK) {
99 VSOMEIP_INFO << "Received a response from Service ["
100 << std::setw(4) << std::setfill('0') << std::hex << _response->get_service()
101 << "."
102 << std::setw(4) << std::setfill('0') << std::hex << _response->get_instance()
103 << "] to Client/Session ["
104 << std::setw(4) << std::setfill('0') << std::hex << _response->get_client()
105 << "/"
106 << std::setw(4) << std::setfill('0') << std::hex << _response->get_session()
107 << "]";
108 received_responses_++;
109 } else if (_response->get_return_code() == vsomeip::return_code_e::E_MALFORMED_MESSAGE) {
110 VSOMEIP_INFO << "Received an error message from Service ["
111 << std::setw(4) << std::setfill('0') << std::hex << _response->get_service()
112 << "."
113 << std::setw(4) << std::setfill('0') << std::hex << _response->get_instance()
114 << "] to Client/Session ["
115 << std::setw(4) << std::setfill('0') << std::hex << _response->get_client()
116 << "/"
117 << std::setw(4) << std::setfill('0') << std::hex << _response->get_session()
118 << "]";
119 received_errors_++;
120 }
121 if (received_errors_ == sent_messages_bad_
122 && received_responses_ == sent_messages_good_) {
123 std::lock_guard<std::mutex> its_lock(mutex_);
124 wait_for_replies_ = false;
125 condition_.notify_one();
126 }
127 }
128
join()129 void join() {
130 runner_.join();
131 }
132
run()133 void run() {
134 std::unique_lock< std::mutex > its_lock(mutex_);
135 while (!is_blocked_) {
136 if (std::cv_status::timeout ==
137 condition_.wait_for(its_lock, std::chrono::milliseconds(5000))) {
138 GTEST_NONFATAL_FAILURE_("Service didn't become available within 5s.");
139 break;
140 }
141 }
142 VSOMEIP_INFO << "Running...";
143
144 vsomeip::routing_manager *its_routing = app_->get_routing_manager();
145
146 vsomeip::byte_t its_good_payload_data[] = {
147 0x12, 0x34, 0x84, 0x21,
148 0x00, 0x00, 0x00, 0x11,
149 0x13, 0x43, 0x00, 0x00,
150 0x01, 0x00, 0x00, 0x00,
151 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01
152 };
153
154 vsomeip::byte_t its_bad_payload_data[] = {
155 0x12, 0x34, 0x84, 0x21,
156 0x00, 0x00, 0x01, 0x23,
157 0x13, 0x43, 0x00, 0x00,
158 0x01, 0x00, 0x00, 0x00,
159 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01
160 };
161
162 // Test sequence
163 its_good_payload_data[11] = 0x01;
164 its_routing->send(0x1343, its_good_payload_data, sizeof(its_good_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true);
165 std::this_thread::sleep_for(std::chrono::seconds(11));
166 its_bad_payload_data[11] = 0x02;
167 its_routing->send(0x1343, its_bad_payload_data, sizeof(its_bad_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true);
168 std::this_thread::sleep_for(std::chrono::seconds(11));
169 its_good_payload_data[11] = 0x03;
170 its_routing->send(0x1343, its_good_payload_data, sizeof(its_good_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true);
171 std::this_thread::sleep_for(std::chrono::seconds(11));
172 its_bad_payload_data[11] = 0x04;
173 its_routing->send(0x1343, its_bad_payload_data, sizeof(its_bad_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true);
174 std::this_thread::sleep_for(std::chrono::seconds(11));
175 its_bad_payload_data[11] = 0x05;
176 its_routing->send(0x1343, its_bad_payload_data, sizeof(its_bad_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true);
177 std::this_thread::sleep_for(std::chrono::seconds(11));
178 its_good_payload_data[11] = 0x06;
179 its_routing->send(0x1343, its_good_payload_data, sizeof(its_good_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true);
180 std::this_thread::sleep_for(std::chrono::seconds(11));
181 its_good_payload_data[11] = 0x07;
182 its_routing->send(0x1343, its_good_payload_data, sizeof(its_good_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true);
183 std::this_thread::sleep_for(std::chrono::seconds(11));
184 its_bad_payload_data[11] = 0x08;
185 its_routing->send(0x1343, its_bad_payload_data, sizeof(its_bad_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true);
186 std::this_thread::sleep_for(std::chrono::seconds(11));
187 its_bad_payload_data[11] = 0x09;
188 its_routing->send(0x1343, its_bad_payload_data, sizeof(its_bad_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true);
189 std::this_thread::sleep_for(std::chrono::seconds(11));
190 its_bad_payload_data[11] = 0x0A;
191 its_routing->send(0x1343, its_bad_payload_data, sizeof(its_bad_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true);
192 std::this_thread::sleep_for(std::chrono::seconds(11));
193 its_good_payload_data[11] = 0x0B;
194 its_routing->send(0x1343, its_good_payload_data, sizeof(its_good_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true);
195 std::this_thread::sleep_for(std::chrono::seconds(11));
196 its_good_payload_data[11] = 0x0C;
197 its_routing->send(0x1343, its_good_payload_data, sizeof(its_good_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true);
198 std::this_thread::sleep_for(std::chrono::seconds(11));
199 its_good_payload_data[11] = 0x0D;
200 its_routing->send(0x1343, its_good_payload_data, sizeof(its_good_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true);
201 std::this_thread::sleep_for(std::chrono::seconds(11));
202 its_bad_payload_data[11] = 0x0E;
203 its_routing->send(0x1343, its_bad_payload_data, sizeof(its_bad_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true);
204 std::this_thread::sleep_for(std::chrono::seconds(11));
205 its_good_payload_data[11] = 0x0F;
206 its_routing->send(0x1343, its_good_payload_data, sizeof(its_good_payload_data), vsomeip_test::TEST_SERVICE_INSTANCE_ID, true);
207
208 while (wait_for_replies_) {
209 if(std::cv_status::timeout ==
210 condition_.wait_for(its_lock, std::chrono::milliseconds(5000))) {
211 GTEST_NONFATAL_FAILURE_("Didn't receive all replies/errors in time");
212 break;
213 }
214 }
215 EXPECT_EQ(sent_messages_good_, received_responses_);
216 EXPECT_EQ(sent_messages_bad_, received_errors_);
217 stop();
218 }
219
220 private:
221 std::shared_ptr< vsomeip::application_impl > app_;
222 std::mutex mutex_;
223 std::condition_variable condition_;
224 bool is_blocked_;
225 const std::uint32_t sent_messages_good_;
226 const std::uint32_t sent_messages_bad_;
227 std::atomic<std::uint32_t> received_responses_;
228 std::atomic<std::uint32_t> received_errors_;
229 bool wait_for_replies_;
230 std::thread runner_;
231 };
232
TEST(someip_magic_cookies_test,send_good_and_bad_messages)233 TEST(someip_magic_cookies_test, send_good_and_bad_messages)
234 {
235 magic_cookies_test_client its_client;
236 its_client.init();
237 its_client.start();
238 its_client.join();
239 }
240
main(int argc,char ** argv)241 int main(int argc, char** argv) {
242 ::testing::InitGoogleTest(&argc, argv);
243 return RUN_ALL_TESTS();
244 }
245
246
247