blob: 1b46c0218b156da691ff94376ac4449753ffa795 [file] [log] [blame]
Ed Tanousc9b55212017-06-12 13:25:51 -07001// Copyright (c) Benjamin Kietzman (github.com/bkietz)
2//
3// Distributed under the Boost Software License, Version 1.0. (See accompanying
4// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6#include <dbus/connection.hpp>
7#include <dbus/endpoint.hpp>
8#include <dbus/filter.hpp>
9#include <dbus/match.hpp>
10#include <dbus/message.hpp>
Ed Tanousc9b55212017-06-12 13:25:51 -070011#include <functional>
12
13#include <unistd.h>
14#include <gmock/gmock.h>
15#include <gtest/gtest.h>
16
17TEST(AvahiTest, GetHostName) {
18 dbus::endpoint test_daemon("org.freedesktop.Avahi", "/",
19 "org.freedesktop.Avahi.Server");
20 boost::asio::io_service io;
Ed Tanous5fceeb42017-06-28 09:43:09 -070021 auto system_bus = std::make_shared<dbus::connection>(io, dbus::bus::system);
Ed Tanousc9b55212017-06-12 13:25:51 -070022
23 dbus::message m = dbus::message::new_call(test_daemon, "GetHostName");
24
Ed Tanous5fceeb42017-06-28 09:43:09 -070025 system_bus->async_send(
Ed Tanousc9b55212017-06-12 13:25:51 -070026 m, [&](const boost::system::error_code ec, dbus::message r) {
27
28 std::string avahi_hostname;
29 std::string hostname;
30
31 // get hostname from a system call
32 char c[1024];
33 gethostname(c, 1024);
34 hostname = c;
35
36 r.unpack(avahi_hostname);
37
38 // Get only the host name, not the fqdn
39 auto unix_hostname = hostname.substr(0, hostname.find("."));
40 EXPECT_EQ(unix_hostname, avahi_hostname);
41
42 io.stop();
43 });
44 boost::asio::deadline_timer t(io, boost::posix_time::seconds(10));
45 t.async_wait([&](const boost::system::error_code& /*e*/) {
46 io.stop();
47 FAIL() << "Callback was never called\n";
48 });
49 io.run();
50}
51
52TEST(AvahiTest, ServiceBrowser) {
53 boost::asio::io_service io;
Ed Tanous5fceeb42017-06-28 09:43:09 -070054 auto system_bus = std::make_shared<dbus::connection>(io, dbus::bus::system);
Ed Tanousc9b55212017-06-12 13:25:51 -070055
56 dbus::endpoint test_daemon("org.freedesktop.Avahi", "/",
57 "org.freedesktop.Avahi.Server");
58 // create new service browser
59 dbus::message m1 = dbus::message::new_call(test_daemon, "ServiceBrowserNew");
60 m1.pack<int32_t>(-1)
61 .pack<int32_t>(-1)
62 .pack<std::string>("_http._tcp")
63 .pack<std::string>("local")
64 .pack<uint32_t>(0);
65
Ed Tanous5fceeb42017-06-28 09:43:09 -070066 dbus::message r = system_bus->send(m1);
Ed Tanousc9b55212017-06-12 13:25:51 -070067 std::string browser_path;
68 r.unpack(browser_path);
69 testing::Test::RecordProperty("browserPath", browser_path);
70
71 dbus::match ma(system_bus, "type='signal',path='" + browser_path + "'");
72 dbus::filter f(system_bus, [](dbus::message& m) {
73 auto member = m.get_member();
74 return member == "NameAcquired";
75 });
76
77 std::function<void(boost::system::error_code, dbus::message)> event_handler =
78 [&](boost::system::error_code ec, dbus::message s) {
79 testing::Test::RecordProperty("firstSignal", s.get_member());
80 std::string a = s.get_member();
81 std::string dude;
82 s.unpack(dude);
83 f.async_dispatch(event_handler);
84 io.stop();
85 };
86 f.async_dispatch(event_handler);
87
88 boost::asio::deadline_timer t(io, boost::posix_time::seconds(10));
89 t.async_wait([&](const boost::system::error_code& /*e*/) {
90 io.stop();
91 FAIL() << "Callback was never called\n";
92 });
93 io.run();
94}
95
96TEST(BOOST_DBUS, ListServices) {
97 boost::asio::io_service io;
98 boost::asio::deadline_timer t(io, boost::posix_time::seconds(10));
99 t.async_wait([&](const boost::system::error_code& /*e*/) {
100 io.stop();
101 FAIL() << "Callback was never called\n";
102 });
103
Ed Tanous5fceeb42017-06-28 09:43:09 -0700104 auto system_bus = std::make_shared<dbus::connection>(io, dbus::bus::system);
Ed Tanousc9b55212017-06-12 13:25:51 -0700105
106 dbus::endpoint test_daemon("org.freedesktop.DBus", "/",
107 "org.freedesktop.DBus");
108 // create new service browser
109 dbus::message m = dbus::message::new_call(test_daemon, "ListNames");
Ed Tanous5fceeb42017-06-28 09:43:09 -0700110 system_bus->async_send(
Ed Tanousc9b55212017-06-12 13:25:51 -0700111 m, [&](const boost::system::error_code ec, dbus::message r) {
112 io.stop();
113 std::vector<std::string> services;
114 r.unpack(services);
115 // Test a couple things that should always be present.... adapt if
116 // neccesary
117 EXPECT_THAT(services, testing::Contains("org.freedesktop.DBus"));
118 EXPECT_THAT(services, testing::Contains("org.freedesktop.Accounts"));
119
120 });
121
122 io.run();
123}
124
Ed Tanous4d92cbf2017-06-22 15:41:02 -0700125TEST(BOOST_DBUS, SingleSensorChanged) {
Ed Tanousc9b55212017-06-12 13:25:51 -0700126 boost::asio::io_service io;
Ed Tanous5fceeb42017-06-28 09:43:09 -0700127
128 auto system_bus = std::make_shared<dbus::connection>(io, dbus::bus::system);
Ed Tanousc9b55212017-06-12 13:25:51 -0700129
Ed Tanous3dac7492017-08-02 13:46:20 -0700130 dbus::match ma(system_bus, "type='signal',path_namespace='/xyz/openbmc_project/sensors'");
Ed Tanous5fceeb42017-06-28 09:43:09 -0700131
Ed Tanous4d92cbf2017-06-22 15:41:02 -0700132 dbus::filter f(system_bus, [](dbus::message& m) {
133 auto member = m.get_member();
134 return member == "PropertiesChanged";
135 });
Ed Tanousc9b55212017-06-12 13:25:51 -0700136
Ed Tanous4d92cbf2017-06-22 15:41:02 -0700137 f.async_dispatch([&](boost::system::error_code ec, dbus::message s) {
138 std::string object_name;
139 EXPECT_EQ(s.get_path(),
140 "/xyz/openbmc_project/sensors/temperature/LR_Brd_Temp");
141
142 std::vector<std::pair<std::string, dbus::dbus_variant>> values;
Ed Tanous3dac7492017-08-02 13:46:20 -0700143 s.unpack(object_name, values);
Ed Tanous4d92cbf2017-06-22 15:41:02 -0700144 EXPECT_EQ(object_name, "xyz.openbmc_project.Sensor.Value");
145
146 EXPECT_EQ(values.size(), 1);
147 auto expected = std::pair<std::string, dbus::dbus_variant>("Value", 42);
148 EXPECT_EQ(values[0], expected);
149
150 io.stop();
151 });
152
153 dbus::endpoint test_endpoint(
154 "org.freedesktop.Avahi",
155 "/xyz/openbmc_project/sensors/temperature/LR_Brd_Temp",
156 "org.freedesktop.DBus.Properties");
157
158 auto signal_name = std::string("PropertiesChanged");
159 auto m = dbus::message::new_signal(test_endpoint, signal_name);
160
161 m.pack("xyz.openbmc_project.Sensor.Value");
162
163 std::vector<std::pair<std::string, dbus::dbus_variant>> map2;
164
165 map2.emplace_back("Value", 42);
166
167 m.pack(map2);
168
169 auto removed = std::vector<uint32_t>();
170 m.pack(removed);
Ed Tanous5fceeb42017-06-28 09:43:09 -0700171 system_bus->async_send(m,
172 [&](boost::system::error_code ec, dbus::message s) {});
Ed Tanousc9b55212017-06-12 13:25:51 -0700173
174 io.run();
175}
Ed Tanous4d92cbf2017-06-22 15:41:02 -0700176
177TEST(BOOST_DBUS, MultipleSensorChanged) {
178 boost::asio::io_service io;
Ed Tanous5fceeb42017-06-28 09:43:09 -0700179 auto system_bus = std::make_shared<dbus::connection>(io, dbus::bus::system);
Ed Tanous4d92cbf2017-06-22 15:41:02 -0700180
181 dbus::match ma(system_bus,
182 "type='signal',path_namespace='/xyz/openbmc_project/sensors'");
183 dbus::filter f(system_bus, [](dbus::message& m) {
184 auto member = m.get_member();
185 return member == "PropertiesChanged";
186 });
187
188 int count = 0;
Ed Tanous5fceeb42017-06-28 09:43:09 -0700189 std::function<void(boost::system::error_code, dbus::message)> callback = [&](
190 boost::system::error_code ec, dbus::message s) {
Ed Tanous4d92cbf2017-06-22 15:41:02 -0700191 std::string object_name;
192 EXPECT_EQ(s.get_path(),
193 "/xyz/openbmc_project/sensors/temperature/LR_Brd_Temp");
194
195 std::vector<std::pair<std::string, dbus::dbus_variant>> values;
Ed Tanous3dac7492017-08-02 13:46:20 -0700196 s.unpack(object_name, values);
Ed Tanous4d92cbf2017-06-22 15:41:02 -0700197 EXPECT_EQ(object_name, "xyz.openbmc_project.Sensor.Value");
198
199 EXPECT_EQ(values.size(), 1);
200 auto expected = std::pair<std::string, dbus::dbus_variant>("Value", 42);
201 EXPECT_EQ(values[0], expected);
202 count++;
203 if (count == 2) {
204 io.stop();
Ed Tanous5fceeb42017-06-28 09:43:09 -0700205 } else {
206 f.async_dispatch(callback);
Ed Tanous4d92cbf2017-06-22 15:41:02 -0700207 }
Ed Tanous3dac7492017-08-02 13:46:20 -0700208 s.unpack(object_name, values);
Ed Tanous4d92cbf2017-06-22 15:41:02 -0700209
Ed Tanous5fceeb42017-06-28 09:43:09 -0700210 };
211 f.async_dispatch(callback);
Ed Tanous4d92cbf2017-06-22 15:41:02 -0700212
213 dbus::endpoint test_endpoint(
214 "org.freedesktop.Avahi",
215 "/xyz/openbmc_project/sensors/temperature/LR_Brd_Temp",
216 "org.freedesktop.DBus.Properties");
217
218 auto signal_name = std::string("PropertiesChanged");
219 auto m = dbus::message::new_signal(test_endpoint, signal_name);
220
221 m.pack("xyz.openbmc_project.Sensor.Value");
222
223 std::vector<std::pair<std::string, dbus::dbus_variant>> map2;
224
225 map2.emplace_back("Value", 42);
226
227 m.pack(map2);
228
229 auto removed = std::vector<uint32_t>();
230 m.pack(removed);
Ed Tanous5fceeb42017-06-28 09:43:09 -0700231 system_bus->async_send(m,
232 [&](boost::system::error_code ec, dbus::message s) {});
233 system_bus->async_send(m,
234 [&](boost::system::error_code ec, dbus::message s) {});
Ed Tanous4d92cbf2017-06-22 15:41:02 -0700235 io.run();
Ed Tanous5fceeb42017-06-28 09:43:09 -0700236}
237
238TEST(BOOST_DBUS, MethodCall) {
239 boost::asio::io_service io;
240 boost::asio::deadline_timer t(io, boost::posix_time::seconds(30));
241 t.async_wait([&](const boost::system::error_code& /*e*/) {
242 io.stop();
243 FAIL() << "Callback was never called\n";
244 });
Ed Tanous5fceeb42017-06-28 09:43:09 -0700245
Ed Tanous3dac7492017-08-02 13:46:20 -0700246 auto system_bus = std::make_shared<dbus::connection>(io, dbus::bus::system);
247 std::string requested_name = system_bus->get_unique_name();
Ed Tanous5fceeb42017-06-28 09:43:09 -0700248
249 dbus::filter f(system_bus, [](dbus::message& m) {
Ed Tanous5fceeb42017-06-28 09:43:09 -0700250 return (m.get_member() == "Get" &&
251 m.get_interface() == "org.freedesktop.DBus.Properties" &&
252 m.get_signature() == "ss");
253 });
254
255 std::function<void(boost::system::error_code, dbus::message)> method_handler =
256 [&](boost::system::error_code ec, dbus::message s) {
257 if (ec) {
258 FAIL() << ec;
259 } else {
260 std::string intf_name, prop_name;
Ed Tanous3dac7492017-08-02 13:46:20 -0700261 s.unpack(intf_name, prop_name);
Ed Tanous5fceeb42017-06-28 09:43:09 -0700262
263 EXPECT_EQ(intf_name, "xyz.openbmc_project.fwupdate1");
264 EXPECT_EQ(prop_name, "State");
265
266 // send a reply so dbus doesn't get angry?
267 auto r = system_bus->reply(s);
268 r.pack("IDLE");
Ed Tanous3dac7492017-08-02 13:46:20 -0700269 system_bus->async_send(r, [&](boost::system::error_code ec,
270 dbus::message s) { });
271 io.stop();
Ed Tanous5fceeb42017-06-28 09:43:09 -0700272 }
Ed Tanous3dac7492017-08-02 13:46:20 -0700273 };
Ed Tanous5fceeb42017-06-28 09:43:09 -0700274 f.async_dispatch(method_handler);
275
Ed Tanous3dac7492017-08-02 13:46:20 -0700276 dbus::endpoint test_endpoint(
277 requested_name,
278 "/xyz/openbmc_project/fwupdate1",
279 "org.freedesktop.DBus.Properties");
Ed Tanous5fceeb42017-06-28 09:43:09 -0700280
281 auto method_name = std::string("Get");
282 auto m = dbus::message::new_call(test_endpoint, method_name);
283
Ed Tanous3dac7492017-08-02 13:46:20 -0700284 m.pack("xyz.openbmc_project.fwupdate1", "State");
285 system_bus->async_send(m,
286 [&](boost::system::error_code ec, dbus::message s) {
287 std::cerr <<"received s: " << s << std::endl;
288 });
Ed Tanous5fceeb42017-06-28 09:43:09 -0700289
290 io.run();
291}