• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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