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 "initial_event_test_globals.hpp"
21
22
23 class initial_event_test_service {
24 public:
initial_event_test_service(struct initial_event_test::service_info _service_info,std::uint32_t _events_to_offer,vsomeip::reliability_type_e _reliability_type)25 initial_event_test_service(struct initial_event_test::service_info _service_info,
26 std::uint32_t _events_to_offer, vsomeip::reliability_type_e _reliability_type) :
27 service_info_(_service_info),
28 app_(vsomeip::runtime::get()->create_application()),
29 wait_until_registered_(true),
30 events_to_offer_(_events_to_offer),
31 offer_thread_(std::bind(&initial_event_test_service::run, this)),
32 reliability_type_(_reliability_type) {
33 if (!app_->init()) {
34 offer_thread_.detach();
35 ADD_FAILURE() << "Couldn't initialize application";
36 return;
37 }
38 app_->register_state_handler(
39 std::bind(&initial_event_test_service::on_state, this,
40 std::placeholders::_1));
41
42 // offer field
43 std::set<vsomeip::eventgroup_t> its_eventgroups;
44 its_eventgroups.insert(service_info_.eventgroup_id);
45 for (std::uint16_t i = 0; i < events_to_offer_; i++) {
46 app_->offer_event(service_info_.service_id, service_info_.instance_id,
47 static_cast<vsomeip::event_t>(service_info_.event_id + i),
48 its_eventgroups, vsomeip::event_type_e::ET_FIELD,
49 std::chrono::milliseconds::zero(), false, true, nullptr,
50 reliability_type_);
51 }
52
53 // set value to field
54 std::shared_ptr<vsomeip::payload> its_payload =
55 vsomeip::runtime::get()->create_payload();
56 vsomeip::byte_t its_data[2] = {static_cast<vsomeip::byte_t>((service_info_.service_id & 0xFF00) >> 8),
57 static_cast<vsomeip::byte_t>((service_info_.service_id & 0xFF))};
58 its_payload->set_data(its_data, 2);
59 for (std::uint16_t i = 0; i < events_to_offer_; i++) {
60 app_->notify(service_info_.service_id, service_info_.instance_id,
61 static_cast<vsomeip::event_t>(service_info_.event_id + i), its_payload);
62 }
63
64 app_->start();
65 }
66
~initial_event_test_service()67 ~initial_event_test_service() {
68 if (offer_thread_.joinable()) {
69 offer_thread_.join();
70 }
71 }
72
offer()73 void offer() {
74 app_->offer_service(service_info_.service_id, service_info_.instance_id);
75 }
76
on_state(vsomeip::state_type_e _state)77 void on_state(vsomeip::state_type_e _state) {
78 VSOMEIP_INFO << "Application " << app_->get_name() << " is "
79 << (_state == vsomeip::state_type_e::ST_REGISTERED ?
80 "registered." : "deregistered.");
81
82 if (_state == vsomeip::state_type_e::ST_REGISTERED) {
83 std::lock_guard<std::mutex> its_lock(mutex_);
84 wait_until_registered_ = false;
85 condition_.notify_one();
86 }
87 }
88
run()89 void run() {
90 VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex
91 << service_info_.service_id << "] Running";
92 std::unique_lock<std::mutex> its_lock(mutex_);
93 while (wait_until_registered_) {
94 condition_.wait(its_lock);
95 }
96
97 VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex
98 << service_info_.service_id << "] Offering";
99 offer();
100 }
101
102 private:
103 initial_event_test::service_info service_info_;
104 std::shared_ptr<vsomeip::application> app_;
105
106 bool wait_until_registered_;
107 std::uint32_t events_to_offer_;
108 std::mutex mutex_;
109 std::condition_variable condition_;
110 std::thread offer_thread_;
111 vsomeip::reliability_type_e reliability_type_;
112 };
113
114 static unsigned long service_number;
115 static bool use_same_service_id;
116 static std::uint32_t offer_multiple_events;
117 vsomeip::reliability_type_e reliability_type = vsomeip::reliability_type_e::RT_UNKNOWN;
118
TEST(someip_initial_event_test,set_field_once)119 TEST(someip_initial_event_test, set_field_once)
120 {
121 if(use_same_service_id) {
122 initial_event_test_service its_sample(
123 initial_event_test::service_infos_same_service_id[service_number], offer_multiple_events,
124 reliability_type);
125 } else {
126 initial_event_test_service its_sample(
127 initial_event_test::service_infos[service_number], offer_multiple_events,
128 reliability_type);
129 }
130 }
131
132 #ifndef _WIN32
main(int argc,char ** argv)133 int main(int argc, char** argv)
134 {
135 ::testing::InitGoogleTest(&argc, argv);
136 if(argc < 2) {
137 std::cerr << "Please specify a service number and subscription type, like: " << argv[0] << " 2 SAME_SERVICE_ID" << std::endl;
138 std::cerr << "Valid service numbers are in the range of [1,6]" << std::endl;
139 std::cerr << "After the service number one/multiple of these flags can be specified:";
140 std::cerr << " - SAME_SERVICE_ID flag. If set the test is run w/ multiple instances of the same service, default false" << std::endl;
141 std::cerr << " - MULTIPLE_EVENTS flag. If set the test will offer to multiple events in the eventgroup, default false" << std::endl;
142 return 1;
143 }
144
145 service_number = std::stoul(std::string(argv[1]), nullptr);
146
147 offer_multiple_events = 1;
148 use_same_service_id = false;
149
150 if (argc > 2) {
151 for (int i = 2; i < argc; i++) {
152 if (std::string("SAME_SERVICE_ID") == std::string(argv[i])) {
153 use_same_service_id = true;
154 std::cout << "Using same service ID" << std::endl;
155 } else if (std::string("MULTIPLE_EVENTS") == std::string(argv[i])) {
156 offer_multiple_events = 5;
157 } else if (std::string("TCP")== std::string(argv[i])) {
158 reliability_type = vsomeip::reliability_type_e::RT_RELIABLE;
159 std::cout << "Using reliability type RT_RELIABLE" << std::endl;
160 } else if (std::string("UDP")== std::string(argv[i])) {
161 reliability_type = vsomeip::reliability_type_e::RT_UNRELIABLE;
162 std::cout << "Using reliability type RT_UNRELIABLE" << std::endl;
163 } else if (std::string("TCP_AND_UDP")== std::string(argv[i])) {
164 reliability_type = vsomeip::reliability_type_e::RT_BOTH;
165 std::cout << "Using reliability type RT_BOTH" << std::endl;
166 }
167 }
168 }
169 return RUN_ALL_TESTS();
170 }
171 #endif
172