• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <atomic>
15 
16 #include <gtest/gtest.h>
17 
18 #ifndef _WIN32
19 #include <signal.h>
20 #endif
21 
22 #include <vsomeip/vsomeip.hpp>
23 #include <vsomeip/internal/logger.hpp>
24 
25 #include "initial_event_test_globals.hpp"
26 
27 class initial_event_test_client;
28 static initial_event_test_client* the_client;
29 extern "C" void signal_handler(int _signum);
30 
31 class initial_event_test_client {
32 public:
initial_event_test_client(int _client_number,bool _service_offered_tcp_and_udp,std::array<initial_event_test::service_info,7> _service_infos,bool _subscribe_on_available,std::uint32_t _events_to_subscribe,bool _initial_event_strict_checking,bool _dont_exit,bool _subscribe_only_one,vsomeip::reliability_type_e _reliability_type,bool _client_subscribes_twice)33     initial_event_test_client(int _client_number,
34                               bool _service_offered_tcp_and_udp,
35                               std::array<initial_event_test::service_info, 7> _service_infos,
36                               bool _subscribe_on_available, std::uint32_t _events_to_subscribe,
37                               bool _initial_event_strict_checking,
38                               bool _dont_exit, bool _subscribe_only_one,
39                               vsomeip::reliability_type_e _reliability_type,
40                               bool _client_subscribes_twice) :
41             client_number_(_client_number),
42             service_infos_(_service_infos),
43             service_offered_tcp_and_udp_(_service_offered_tcp_and_udp),
44             app_(vsomeip::runtime::get()->create_application()),
45             wait_until_registered_(true),
46             wait_for_stop_(true),
47             is_first(true),
48             subscribe_on_available_(_subscribe_on_available),
49             events_to_subscribe_(_events_to_subscribe),
50             initial_event_strict_checking_(_initial_event_strict_checking),
51             dont_exit_(_dont_exit),
52             subscribe_only_one_(_subscribe_only_one),
53             stop_thread_(&initial_event_test_client::wait_for_stop, this),
54             wait_for_signal_handler_registration_(true),
55             reliability_type_(_reliability_type),
56             client_subscribes_twice_(_client_subscribes_twice)
57         {
58         if (!app_->init()) {
59             stop_thread_.detach();
60             ADD_FAILURE() << "Couldn't initialize application";
61             return;
62         }
63 
64         app_->register_state_handler(
65                 std::bind(&initial_event_test_client::on_state, this,
66                         std::placeholders::_1));
67 
68         app_->register_message_handler(vsomeip::ANY_SERVICE,
69                 vsomeip::ANY_INSTANCE, vsomeip::ANY_METHOD,
70                 std::bind(&initial_event_test_client::on_message, this,
71                         std::placeholders::_1));
72 
73         // register availability for all other services and request their event.
74         for(const auto& i : service_infos_) {
75             if (i.service_id == 0xFFFF && i.instance_id == 0xFFFF) {
76                 continue;
77             }
78             app_->register_availability_handler(i.service_id, i.instance_id,
79                     std::bind(&initial_event_test_client::on_availability, this,
80                             std::placeholders::_1, std::placeholders::_2,
81                             std::placeholders::_3));
82             app_->request_service(i.service_id, i.instance_id);
83 
84             std::set<vsomeip::eventgroup_t> its_eventgroups;
85             its_eventgroups.insert(i.eventgroup_id);
86             for (std::uint32_t j = 0; j < events_to_subscribe_; j++ ) {
87                 app_->request_event(i.service_id, i.instance_id,
88                         static_cast<vsomeip::event_t>(i.event_id + j),
89                         its_eventgroups, vsomeip::event_type_e::ET_FIELD,
90                         reliability_type_);
91             }
92 
93             other_services_available_[std::make_pair(i.service_id, i.instance_id)] = false;
94 
95             if (!subscribe_on_available_) {
96                 if (events_to_subscribe_ == 1) {
97                     app_->subscribe(i.service_id, i.instance_id, i.eventgroup_id,
98                                     vsomeip::DEFAULT_MAJOR);
99 
100                     std::lock_guard<std::mutex> its_lock(received_notifications_mutex_);
101                     other_services_received_notification_[std::make_pair(i.service_id, i.event_id)] = 0;
102                 } else if (events_to_subscribe_ > 1) {
103                     if (!subscribe_only_one_) {
104                         for (std::uint32_t j = 0; j < events_to_subscribe_; j++ ) {
105                             app_->subscribe(i.service_id, i.instance_id, i.eventgroup_id,
106                                             vsomeip::DEFAULT_MAJOR,
107                                             static_cast<vsomeip::event_t>(i.event_id + j));
108                             std::lock_guard<std::mutex> its_lock(received_notifications_mutex_);
109                             other_services_received_notification_[std::make_pair(i.service_id, i.event_id + j)] = 0;
110                         }
111                     } else {
112                         app_->subscribe(i.service_id, i.instance_id, i.eventgroup_id,
113                                         vsomeip::DEFAULT_MAJOR,
114                                         static_cast<vsomeip::event_t>(i.event_id));
115                         other_services_received_notification_[std::make_pair(i.service_id, i.event_id)] = 0;
116                     }
117                 }
118             } else {
119                 for (std::uint32_t j = 0; j < events_to_subscribe_; j++ ) {
120                     other_services_received_notification_[std::make_pair(i.service_id, i.event_id + j)] = 0;
121                 }
122             }
123         }
124 
125         // Block all signals
126         sigset_t mask;
127         sigfillset(&mask);
128         pthread_sigmask(SIG_BLOCK, &mask, NULL);
129         // start thread which handles all of the signals
130         signal_thread_ = std::thread(&initial_event_test_client::wait_for_signal, this);
131         {
132             std::unique_lock<std::mutex> its_lock(signal_mutex_);
133             while(wait_for_signal_handler_registration_) {
134                 EXPECT_EQ(std::cv_status::no_timeout,
135                         signal_condition_.wait_for(its_lock, std::chrono::seconds(10)));
136             }
137             wait_for_signal_handler_registration_ = true;
138         }
139 
140         app_->start();
141     }
142 
~initial_event_test_client()143     ~initial_event_test_client() {
144         if (stop_thread_.joinable()) {
145             stop_thread_.join();
146         }
147         if (signal_thread_.joinable()) {
148             signal_thread_.join();
149         }
150     }
151 
on_state(vsomeip::state_type_e _state)152     void on_state(vsomeip::state_type_e _state) {
153         VSOMEIP_INFO << "Application " << app_->get_name() << " is "
154         << (_state == vsomeip::state_type_e::ST_REGISTERED ?
155                 "registered." : "deregistered.");
156 
157         if (_state == vsomeip::state_type_e::ST_REGISTERED) {
158             std::lock_guard<std::mutex> its_lock(mutex_);
159             wait_until_registered_ = false;
160             condition_.notify_one();
161         }
162     }
163 
on_availability(vsomeip::service_t _service,vsomeip::instance_t _instance,bool _is_available)164     void on_availability(vsomeip::service_t _service,
165                          vsomeip::instance_t _instance, bool _is_available) {
166         if(_is_available) {
167             auto its_service = other_services_available_.find(std::make_pair(_service, _instance));
168             if(its_service != other_services_available_.end()) {
169                 if(its_service->second != _is_available) {
170                 its_service->second = true;
171                 VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex
172                         << client_number_ << "] Service ["
173                 << std::setw(4) << std::setfill('0') << std::hex << _service << "." << _instance
174                 << "] is available.";
175 
176                 }
177             }
178 
179             if(std::all_of(other_services_available_.cbegin(),
180                            other_services_available_.cend(),
181                            [](const std::map<std::pair<vsomeip::service_t,
182                                    vsomeip::instance_t>, bool>::value_type& v) {
183                                 return v.second;})) {
184                 VSOMEIP_INFO << "[" << std::setw(4) << std::setfill('0') << std::hex
185                         << client_number_ << "] all services are available.";
186                 if (subscribe_on_available_) {
187                     for(const auto& i : service_infos_) {
188                         if (i.service_id == 0xFFFF && i.instance_id == 0xFFFF) {
189                             continue;
190                         }
191                         if (events_to_subscribe_ == 1 ) {
192                             app_->subscribe(i.service_id, i.instance_id, i.eventgroup_id,
193                                     vsomeip::DEFAULT_MAJOR);
194                         } else if (events_to_subscribe_ > 1) {
195                             for (std::uint32_t j = 0; j < events_to_subscribe_; j++ ) {
196                                 app_->subscribe(i.service_id, i.instance_id, i.eventgroup_id,
197                                         vsomeip::DEFAULT_MAJOR,
198                                         static_cast<vsomeip::event_t>(i.event_id + j));
199                             }
200                         }
201                     }
202                 }
203             }
204         }
205     }
206 
on_message(const std::shared_ptr<vsomeip::message> & _message)207     void on_message(const std::shared_ptr<vsomeip::message> &_message) {
208         if(_message->get_message_type() == vsomeip::message_type_e::MT_NOTIFICATION) {
209 
210             {
211                 std::lock_guard<std::mutex> its_lock(received_notifications_mutex_);
212                 other_services_received_notification_[std::make_pair(_message->get_service(),
213                                                                  _message->get_method())]++;
214                 VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex
215                 << client_number_ << "] "
216                 << "Received a notification with Client/Session [" << std::setw(4)
217                 << std::setfill('0') << std::hex << _message->get_client() << "/"
218                 << std::setw(4) << std::setfill('0') << std::hex
219                 << _message->get_session() << "] from Service/Method ["
220                 << std::setw(4) << std::setfill('0') << std::hex
221                 << _message->get_service() << "/" << std::setw(4) << std::setfill('0')
222                 << std::hex << _message->get_method() <<"] (now have: "
223                 << std::dec << other_services_received_notification_[std::make_pair(_message->get_service(),
224                                                                         _message->get_method())] << ")";
225             }
226 
227             std::shared_ptr<vsomeip::payload> its_payload(_message->get_payload());
228             EXPECT_EQ(2u, its_payload->get_length());
229             EXPECT_EQ((_message->get_service() & 0xFF00 ) >> 8, its_payload->get_data()[0]);
230             EXPECT_EQ((_message->get_service() & 0xFF), its_payload->get_data()[1]);
231             bool notify(false);
232             if (client_subscribes_twice_) {
233                 // only relevant for testcase:
234                 // initial_event_test_diff_client_ids_same_ports_udp_client_subscribes_twice
235                 // check that a second subscribe triggers another initial event
236                 // expect notifications_to_send_after_double_subscribe == 2;
237                 if (is_first) {
238                     std::this_thread::sleep_for(std::chrono::milliseconds(2000));
239                     for(const auto& i : service_infos_) {
240                         // subscribe again and expect initial events cached at rm::proxy to be received
241                         // as configured routing manager only fires the event once after first susbcribe.
242                         if (i.service_id == 0xFFFF && i.instance_id == 0xFFFF) {
243                             continue;
244                         }
245                         if (!subscribe_on_available_) {
246                             if (events_to_subscribe_ == 1) {
247                                 app_->subscribe(i.service_id, i.instance_id, i.eventgroup_id,
248                                                 vsomeip::DEFAULT_MAJOR);
249                             } else if (events_to_subscribe_ > 1) {
250                                 if (!subscribe_only_one_) {
251                                     for (std::uint32_t j = 0; j < events_to_subscribe_; j++ ) {
252                                         app_->subscribe(i.service_id, i.instance_id, i.eventgroup_id,
253                                                         vsomeip::DEFAULT_MAJOR,
254                                                         static_cast<vsomeip::event_t>(i.event_id + j));
255                                     }
256                                 } else {
257                                     app_->subscribe(i.service_id, i.instance_id, i.eventgroup_id,
258                                                     vsomeip::DEFAULT_MAJOR,
259                                                     static_cast<vsomeip::event_t>(i.event_id));
260                                 }
261                             }
262                         }
263                     }
264                     is_first = false;
265                 } else {
266                     bool received_initial_event_twice(false);
267                     std::lock_guard<std::mutex> its_lock(received_notifications_mutex_);
268                     received_initial_event_twice = all_notifications_received_twice();
269                     if (received_initial_event_twice) {
270                         notify = true;
271                     }
272                 }
273             } else {
274                 if (!service_offered_tcp_and_udp_) {
275                     std::lock_guard<std::mutex> its_lock(received_notifications_mutex_);
276                     if (all_notifications_received()) {
277                         notify = true;
278                     }
279                 } else {
280                     if (all_notifications_received_tcp_and_udp()) {
281                         notify = true;
282                     }
283                 }
284             }
285 
286             if (notify && !dont_exit_) {
287                 std::lock_guard<std::mutex> its_lock(stop_mutex_);
288                 wait_for_stop_ = false;
289                 stop_condition_.notify_one();
290             }
291         }
292     }
293 
all_notifications_received()294     bool all_notifications_received() {
295         return std::all_of(
296                 other_services_received_notification_.cbegin(),
297                 other_services_received_notification_.cend(),
298                 [&](const std::map<std::pair<vsomeip::service_t,
299                         vsomeip::method_t>, std::uint32_t>::value_type& v)
300                 {
301                     bool result;
302                     if (v.second == initial_event_test::notifications_to_send) {
303                         result = true;
304                     } else {
305                         if (v.second >= initial_event_test::notifications_to_send) {
306                             VSOMEIP_WARNING
307                                     << "[" << std::setw(4) << std::setfill('0') << std::hex
308                                         << client_number_ << "] "
309                                     << " Received multiple initial events from service/instance: "
310                                     << std::setw(4) << std::setfill('0') << std::hex << v.first.first
311                                     << "."
312                                     << std::setw(4) << std::setfill('0') << std::hex << v.first.second
313                                     << " number of received events: " << v.second
314                                     << ". This is caused by StopSubscribe/Subscribe messages and/or"
315                                     << " service offered via UDP and TCP";
316                             if (initial_event_strict_checking_) {
317                                 ADD_FAILURE() << "[" << std::setw(4) << std::setfill('0') << std::hex
318                                     << client_number_ << "] "
319                                     << " Received multiple initial events from service/instance: "
320                                     << std::setw(4) << std::setfill('0') << std::hex << v.first.first
321                                     << "."
322                                     << std::setw(4) << std::setfill('0') << std::hex << v.first.second
323                                     << " number of received events: " << v.second;
324                             }
325                             result = initial_event_strict_checking_ ? false : true;
326 
327                         } else {
328                             result = false;
329                         }
330                     }
331 
332                     return result;
333                 }
334         );
335     }
336 
all_notifications_received_twice()337     bool all_notifications_received_twice() {
338         return std::all_of(
339                 other_services_received_notification_.cbegin(),
340                 other_services_received_notification_.cend(),
341                 [&](const std::map<std::pair<vsomeip::service_t,
342                         vsomeip::method_t>, std::uint32_t>::value_type& v)
343                 {
344                     bool result;
345                     if (v.second == initial_event_test::notifications_to_send * 2) {
346                         result = true;
347                     } else {
348                         if (v.second >= initial_event_test::notifications_to_send * 2) {
349                             VSOMEIP_WARNING
350                                     << __func__ << "[" << std::setw(4) << std::setfill('0') << std::hex
351                                         << client_number_ << "] "
352                                     << " Received multiple initial events from service/instance: "
353                                     << std::setw(4) << std::setfill('0') << std::hex << v.first.first
354                                     << "."
355                                     << std::setw(4) << std::setfill('0') << std::hex << v.first.second
356                                     << " number of received events: " << v.second
357                                     << ". This is caused by StopSubscribe/Subscribe messages and/or"
358                                     << " service offered via UDP and TCP";
359                             if (initial_event_strict_checking_) {
360                                 ADD_FAILURE() << __func__ << "[" << std::setw(4) << std::setfill('0') << std::hex
361                                     << client_number_ << "] "
362                                     << " Received multiple initial events from service/instance: "
363                                     << std::setw(4) << std::setfill('0') << std::hex << v.first.first
364                                     << "."
365                                     << std::setw(4) << std::setfill('0') << std::hex << v.first.second
366                                     << " number of received events: " << v.second;
367                             }
368                             result = initial_event_strict_checking_ ? false : true;
369 
370                         } else {
371                             result = false;
372                         }
373                     }
374                     return result;
375                 }
376         );
377     }
378 
all_notifications_received_tcp_and_udp()379     bool all_notifications_received_tcp_and_udp() {
380         std::lock_guard<std::mutex> its_lock(received_notifications_mutex_);
381         std::uint32_t received_twice(0);
382         std::uint32_t received_normal(0);
383         for(const auto &v : other_services_received_notification_) {
384             if (!initial_event_strict_checking_ &&
385                     v.second > initial_event_test::notifications_to_send * 2) {
386                 VSOMEIP_WARNING
387                         << "[" << std::setw(4) << std::setfill('0') << std::hex
388                         << client_number_ << "] "
389                         << " Received multiple initial events from service/instance: "
390                         << std::setw(4) << std::setfill('0') << std::hex << v.first.first
391                         << "."
392                         << std::setw(4) << std::setfill('0') << std::hex << v.first.second
393                         << ". This is caused by StopSubscribe/Subscribe messages and/or"
394                         << " service offered via UDP and TCP";
395                 received_twice++;
396             } else if (initial_event_strict_checking_ &&
397                     v.second > initial_event_test::notifications_to_send * 2) {
398                 ADD_FAILURE() << "[" << std::setw(4) << std::setfill('0') << std::hex
399                     << client_number_ << "] "
400                     << " Received multiple initial events from service/instance: "
401                     << std::setw(4) << std::setfill('0') << std::hex << v.first.first
402                     << "."
403                     << std::setw(4) << std::setfill('0') << std::hex << v.first.second
404                     << " number of received events: " << v.second;
405             } else if (v.second == initial_event_test::notifications_to_send * 2) {
406                 received_twice++;
407             } else if(v.second == initial_event_test::notifications_to_send) {
408                 received_normal++;
409             }
410         }
411 
412         if(   received_twice == ((service_infos_.size() - 1) * events_to_subscribe_)/ 2
413            && received_normal == ((service_infos_.size() - 1) * events_to_subscribe_)/ 2) {
414             // routing manager stub receives the notification
415             // - twice from external nodes
416             // - and normal from all internal nodes
417             VSOMEIP_ERROR << "[" << std::setw(4) << std::setfill('0') << std::hex
418                         << client_number_ << "] "
419                         << "Received notifications:"
420                         << " Normal: " << received_normal
421                         << " Twice: " << received_twice;
422             return true;
423         } else if (initial_event_strict_checking_ && (
424                 received_twice > ((service_infos_.size() - 1) * events_to_subscribe_)/ 2)) {
425             ADD_FAILURE() << "[" << std::setw(4) << std::setfill('0') << std::hex
426                 << client_number_ << "] "
427                 << " Received too much initial events twice: " << received_twice;
428         } else if (received_normal == (events_to_subscribe_ * (service_infos_.size() - 1))) {
429             return true;
430         }
431         return false;
432     }
433 
wait_for_signal()434     void wait_for_signal() {
435         // register signal handler
436         the_client = this;
437 
438         sigset_t handler_mask;
439         sigemptyset(&handler_mask);
440         sigaddset(&handler_mask, SIGUSR1);
441         sigaddset(&handler_mask, SIGTERM);
442         sigaddset(&handler_mask, SIGINT);
443         sigaddset(&handler_mask, SIGABRT);
444         pthread_sigmask(SIG_UNBLOCK, &handler_mask, NULL);
445 
446 
447         struct sigaction sa_new, sa_old;
448         sa_new.sa_handler = signal_handler;
449         sa_new.sa_flags = 0;
450         sigemptyset(&sa_new.sa_mask);
451         ::sigaction(SIGUSR1, &sa_new, &sa_old);
452         ::sigaction(SIGINT, &sa_new, &sa_old);
453         ::sigaction(SIGTERM, &sa_new, &sa_old);
454         ::sigaction(SIGABRT, &sa_new, &sa_old);
455 
456 
457 
458 
459         {
460             std::lock_guard<std::mutex> its_lock(signal_mutex_);
461             wait_for_signal_handler_registration_ = false;
462             signal_condition_.notify_one();
463         }
464         while (wait_for_stop_) {
465             std::this_thread::sleep_for(std::chrono::milliseconds(10));
466        }
467     }
468 
handle_signal(int _signum)469     void handle_signal(int _signum) {
470         (void)_signum;
471         std::lock_guard<std::mutex> its_lock(stop_mutex_);
472         wait_for_stop_ = false;
473         stop_condition_.notify_one();
474     }
475 
wait_for_stop()476     void wait_for_stop() {
477         static int its_call_number(0);
478         its_call_number++;
479 
480         {
481             std::unique_lock<std::mutex> its_lock(stop_mutex_);
482             while (wait_for_stop_) {
483                 stop_condition_.wait_for(its_lock, std::chrono::milliseconds(100));
484             }
485             VSOMEIP_ERROR << "(" << std::dec << its_call_number << ") [" << std::setw(4) << std::setfill('0') << std::hex
486                     << client_number_
487                     << "] Received notifications from all services, going down";
488         }
489         for (const auto& i : service_infos_) {
490             if (i.service_id == 0xFFFF && i.instance_id == 0xFFFF) {
491                 continue;
492             }
493             app_->unsubscribe(i.service_id, i.instance_id, i.eventgroup_id);
494         }
495         app_->clear_all_handler();
496         app_->stop();
497     }
498 
499 private:
500     int client_number_;
501     std::array<initial_event_test::service_info, 7> service_infos_;
502     bool service_offered_tcp_and_udp_;
503     std::shared_ptr<vsomeip::application> app_;
504     std::map<std::pair<vsomeip::service_t, vsomeip::instance_t>, bool> other_services_available_;
505     std::mutex received_notifications_mutex_;
506     std::map<std::pair<vsomeip::service_t, vsomeip::method_t>, std::uint32_t> other_services_received_notification_;
507 
508     bool wait_until_registered_;
509     std::mutex mutex_;
510     std::condition_variable condition_;
511 
512     std::atomic<bool> wait_for_stop_;
513     std::atomic<bool> is_first;
514 
515     bool subscribe_on_available_;
516     std::uint32_t events_to_subscribe_;
517     bool initial_event_strict_checking_;
518     bool dont_exit_;
519     bool subscribe_only_one_;
520 
521     std::mutex stop_mutex_;
522     std::condition_variable stop_condition_;
523     std::thread stop_thread_;
524     bool wait_for_signal_handler_registration_;
525     std::mutex signal_mutex_;
526     std::condition_variable signal_condition_;
527     std::thread signal_thread_;
528     vsomeip::reliability_type_e reliability_type_;
529     bool client_subscribes_twice_;
530 };
531 
532 static int client_number;
533 static bool service_offered_tcp_and_udp;
534 static bool use_same_service_id;
535 static bool subscribe_on_available;
536 static std::uint32_t subscribe_multiple_events;
537 static bool initial_event_strict_checking;
538 static bool dont_exit;
539 static bool subscribe_only_one;
540 static bool client_subscribes_twice;
541 
542 vsomeip::reliability_type_e reliability_type = vsomeip::reliability_type_e::RT_UNKNOWN;
543 
544 
signal_handler(int signum)545 extern "C" void signal_handler(int signum) {
546     the_client->handle_signal(signum);
547 }
548 
TEST(someip_initial_event_test,wait_for_initial_events_of_all_services)549 TEST(someip_initial_event_test, wait_for_initial_events_of_all_services)
550 {
551     if(use_same_service_id) {
552         initial_event_test_client its_sample(client_number,
553                 service_offered_tcp_and_udp,
554                 initial_event_test::service_infos_same_service_id,
555                 subscribe_on_available, subscribe_multiple_events,
556                 initial_event_strict_checking, dont_exit,
557                 subscribe_only_one,
558                 reliability_type,
559                 client_subscribes_twice);
560     } else {
561         initial_event_test_client its_sample(client_number, service_offered_tcp_and_udp,
562                 initial_event_test::service_infos, subscribe_on_available,
563                 subscribe_multiple_events, initial_event_strict_checking, dont_exit,
564                 subscribe_only_one,
565                 reliability_type,
566                 client_subscribes_twice);
567     }
568 }
569 
570 #ifndef _WIN32
main(int argc,char ** argv)571 int main(int argc, char** argv)
572 {
573     // Block all signals
574     sigset_t mask;
575     sigfillset(&mask);
576     pthread_sigmask(SIG_BLOCK, &mask, NULL);
577     ::testing::InitGoogleTest(&argc, argv);
578 
579     if(argc < 2) {
580         std::cerr << "Please specify a client number, like: " << argv[0] << " 2 SUBSCRIBE_BEFORE_START SAME_SERVICE_ID" << std::endl;
581         std::cerr << "Valid client numbers are from 0 to 0xFFFF" << std::endl;
582         std::cerr << "After client number one/multiple of these flags can be specified:";
583         std::cerr << " - SERVICE_OFFERED_TCP_AND_UDP flag. Set this if the service is offered via TCP and UDP" << std::endl;
584         std::cerr << " - Time of subscription, valid values: [SUBSCRIBE_ON_AVAILABILITY, SUBSCRIBE_BEFORE_START], default SUBSCRIBE_BEFORE_START" << std::endl;
585         std::cerr << " - SAME_SERVICE_ID flag. If set the test is run w/ multiple instances of the same service, default false" << std::endl;
586         std::cerr << " - MULTIPLE_EVENTS flag. If set the test will subscribe to multiple events in the eventgroup, default false" << std::endl;
587         std::cerr << " - STRICT_CHECKING flag. If set the test will only successfully finish if exactly the number of initial events were received (and not more). Default false" << std::endl;
588         std::cerr << " - DONT_EXIT flag. If set the test will not exit if all notifications have been received. Default false" << std::endl;
589         std::cerr << " - SUBSCRIBE_ONLY_ONE flag. If set the test will only subscribe to one event even if MULTIPLE_EVENTS is set. Default false" << std::endl;
590         return 1;
591     }
592 
593     client_number = std::stoi(std::string(argv[1]), nullptr);
594 
595     subscribe_on_available = false;
596     initial_event_strict_checking = false;
597     service_offered_tcp_and_udp = false;
598     use_same_service_id = false;
599     subscribe_multiple_events = 1;
600     dont_exit = false;
601     subscribe_only_one = false;
602     client_subscribes_twice = false;
603     if (argc > 2) {
604         for (int i = 2; i < argc; i++) {
605             if (std::string("SUBSCRIBE_ON_AVAILABILITY") == std::string(argv[i])) {
606                 subscribe_on_available = true;
607             } else if (std::string("SUBSCRIBE_BEFORE_START") == std::string(argv[i])) {
608                 subscribe_on_available = false;
609             } else if (std::string("SAME_SERVICE_ID") == std::string(argv[i])) {
610                 use_same_service_id = true;
611                 std::cout << "Using same service ID" << std::endl;
612             } else if (std::string("MULTIPLE_EVENTS") == std::string(argv[i])) {
613                 subscribe_multiple_events = 5;
614             } else if (std::string("STRICT_CHECKING") == std::string(argv[i])) {
615                 initial_event_strict_checking = true;
616             } else if (std::string("DONT_EXIT") == std::string(argv[i])) {
617                 dont_exit = true;
618             } else if (std::string("SUBSCRIBE_ONLY_ONE") == std::string(argv[i])) {
619                 subscribe_only_one = true;
620             } else if (std::string("TCP")== std::string(argv[i])) {
621                 reliability_type = vsomeip::reliability_type_e::RT_RELIABLE;
622                 std::cout << "Using reliability type RT_RELIABLE" << std::endl;
623             } else if (std::string("UDP")== std::string(argv[i])) {
624                 reliability_type = vsomeip::reliability_type_e::RT_UNRELIABLE;
625                 std::cout << "Using reliability type RT_UNRELIABLE" << std::endl;
626             } else if (std::string("TCP_AND_UDP")== std::string(argv[i])) {
627                 reliability_type = vsomeip::reliability_type_e::RT_BOTH;
628                 std::cout << "Using reliability type RT_BOTH" << std::endl;
629             } else if (std::string("CLIENT_SUBSCRIBES_TWICE")== std::string(argv[i])) {
630                 client_subscribes_twice = true;
631                 std::cout << "Testing for initial event after a second subscribe from same client CLIENT_SUBSCRIBES_TWICE" << std::endl;
632             }
633         }
634     }
635 
636     return RUN_ALL_TESTS();
637 }
638 #endif
639