• 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 
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