xref: /openbmc/boost-dbus/test/avahi.cpp (revision 82a51ce2400eee6597afbe757d966ac7091da58b)
1a83e5951SBenjamin Kietzman // Copyright (c) Benjamin Kietzman (github.com/bkietz)
2a83e5951SBenjamin Kietzman //
3a83e5951SBenjamin Kietzman // Distributed under the Boost Software License, Version 1.0. (See accompanying
4a83e5951SBenjamin Kietzman // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5a83e5951SBenjamin Kietzman 
6a83e5951SBenjamin Kietzman #include <dbus/connection.hpp>
716d80fe9SBenjamin Kietzman #include <dbus/endpoint.hpp>
8a83e5951SBenjamin Kietzman #include <dbus/filter.hpp>
9a83e5951SBenjamin Kietzman #include <dbus/match.hpp>
10da3eeb6aSEd Tanous #include <dbus/message.hpp>
11b6e8327aSEd Tanous #include <dbus/utility.hpp>
12da3eeb6aSEd Tanous #include <functional>
13b2c2467dSBenjamin Kietzman 
14a83e5951SBenjamin Kietzman #include <unistd.h>
15b6e8327aSEd Tanous #include <gmock/gmock.h>
16da3eeb6aSEd Tanous #include <gtest/gtest.h>
17b2c2467dSBenjamin Kietzman 
18da3eeb6aSEd Tanous TEST(AvahiTest, GetHostName) {
19da3eeb6aSEd Tanous   dbus::endpoint test_daemon("org.freedesktop.Avahi", "/",
2016d80fe9SBenjamin Kietzman                              "org.freedesktop.Avahi.Server");
21da3eeb6aSEd Tanous   boost::asio::io_service io;
22da3eeb6aSEd Tanous   dbus::connection system_bus(io, dbus::bus::system);
23a83e5951SBenjamin Kietzman 
24da3eeb6aSEd Tanous   dbus::message m = dbus::message::new_call(test_daemon, "GetHostName");
25a83e5951SBenjamin Kietzman 
26da3eeb6aSEd Tanous   system_bus.async_send(
27da3eeb6aSEd Tanous       m, [&](const boost::system::error_code ec, dbus::message r) {
28a83e5951SBenjamin Kietzman 
29da3eeb6aSEd Tanous         std::string avahi_hostname;
30da3eeb6aSEd Tanous         std::string hostname;
31da3eeb6aSEd Tanous 
32a83e5951SBenjamin Kietzman         // get hostname from a system call
33a83e5951SBenjamin Kietzman         char c[1024];
34a83e5951SBenjamin Kietzman         gethostname(c, 1024);
35da3eeb6aSEd Tanous         hostname = c;
36a83e5951SBenjamin Kietzman 
37b2c2467dSBenjamin Kietzman         r.unpack(avahi_hostname);
38b2c2467dSBenjamin Kietzman 
39da3eeb6aSEd Tanous         // Get only the host name, not the fqdn
40da3eeb6aSEd Tanous         auto unix_hostname = hostname.substr(0, hostname.find("."));
41b2c2467dSBenjamin Kietzman         EXPECT_EQ(unix_hostname, avahi_hostname);
42b2c2467dSBenjamin Kietzman 
43b2c2467dSBenjamin Kietzman         io.stop();
44da3eeb6aSEd Tanous       });
45da3eeb6aSEd Tanous   boost::asio::deadline_timer t(io, boost::posix_time::seconds(10));
46da3eeb6aSEd Tanous   t.async_wait([&](const boost::system::error_code& /*e*/) {
47b2c2467dSBenjamin Kietzman     io.stop();
48da3eeb6aSEd Tanous     FAIL() << "Callback was never called\n";
49da3eeb6aSEd Tanous   });
50a83e5951SBenjamin Kietzman   io.run();
51a83e5951SBenjamin Kietzman }
52a83e5951SBenjamin Kietzman 
53da3eeb6aSEd Tanous TEST(AvahiTest, ServiceBrowser) {
54da3eeb6aSEd Tanous   boost::asio::io_service io;
55da3eeb6aSEd Tanous   dbus::connection system_bus(io, dbus::bus::system);
56a83e5951SBenjamin Kietzman 
57da3eeb6aSEd Tanous   dbus::endpoint test_daemon("org.freedesktop.Avahi", "/",
58da3eeb6aSEd Tanous                              "org.freedesktop.Avahi.Server");
59a83e5951SBenjamin Kietzman   // create new service browser
60da3eeb6aSEd Tanous   dbus::message m1 = dbus::message::new_call(test_daemon, "ServiceBrowserNew");
61da3eeb6aSEd Tanous   m1.pack<int32_t>(-1)
62da3eeb6aSEd Tanous       .pack<int32_t>(-1)
63da3eeb6aSEd Tanous       .pack<std::string>("_http._tcp")
64da3eeb6aSEd Tanous       .pack<std::string>("local")
65da3eeb6aSEd Tanous       .pack<uint32_t>(0);
66a83e5951SBenjamin Kietzman 
67da3eeb6aSEd Tanous   dbus::message r = system_bus.send(m1);
68da3eeb6aSEd Tanous   std::string browser_path;
69a83e5951SBenjamin Kietzman   r.unpack(browser_path);
70da3eeb6aSEd Tanous   testing::Test::RecordProperty("browserPath", browser_path);
71a83e5951SBenjamin Kietzman 
72da3eeb6aSEd Tanous   dbus::match ma(system_bus, "type='signal',path='" + browser_path + "'");
73da3eeb6aSEd Tanous   dbus::filter f(system_bus, [](dbus::message& m) {
74da3eeb6aSEd Tanous     auto member = m.get_member();
75da3eeb6aSEd Tanous     return member == "NameAcquired";
76da3eeb6aSEd Tanous   });
77a83e5951SBenjamin Kietzman 
78da3eeb6aSEd Tanous   std::function<void(boost::system::error_code, dbus::message)> event_handler =
79da3eeb6aSEd Tanous       [&](boost::system::error_code ec, dbus::message s) {
80da3eeb6aSEd Tanous         testing::Test::RecordProperty("firstSignal", s.get_member());
81da3eeb6aSEd Tanous         std::string a = s.get_member();
82da3eeb6aSEd Tanous         std::string dude;
83da3eeb6aSEd Tanous         s.unpack(dude);
84da3eeb6aSEd Tanous         f.async_dispatch(event_handler);
85da3eeb6aSEd Tanous         io.stop();
86da3eeb6aSEd Tanous       };
87da3eeb6aSEd Tanous   f.async_dispatch(event_handler);
88b2c2467dSBenjamin Kietzman 
89da3eeb6aSEd Tanous   boost::asio::deadline_timer t(io, boost::posix_time::seconds(10));
90da3eeb6aSEd Tanous   t.async_wait([&](const boost::system::error_code& /*e*/) {
91da3eeb6aSEd Tanous     io.stop();
92da3eeb6aSEd Tanous     FAIL() << "Callback was never called\n";
93da3eeb6aSEd Tanous   });
94a83e5951SBenjamin Kietzman   io.run();
95a83e5951SBenjamin Kietzman }
96b6e8327aSEd Tanous 
97b6e8327aSEd Tanous TEST(BOOST_DBUS, ListServices) {
98b6e8327aSEd Tanous   boost::asio::io_service io;
99b6e8327aSEd Tanous   boost::asio::deadline_timer t(io, boost::posix_time::seconds(10));
100b6e8327aSEd Tanous   t.async_wait([&](const boost::system::error_code& /*e*/) {
101b6e8327aSEd Tanous     io.stop();
102b6e8327aSEd Tanous     FAIL() << "Callback was never called\n";
103b6e8327aSEd Tanous   });
104b6e8327aSEd Tanous 
105b6e8327aSEd Tanous   dbus::connection system_bus(io, dbus::bus::system);
106b6e8327aSEd Tanous 
107b6e8327aSEd Tanous   dbus::endpoint test_daemon("org.freedesktop.DBus", "/",
108b6e8327aSEd Tanous                              "org.freedesktop.DBus");
109b6e8327aSEd Tanous   // create new service browser
110b6e8327aSEd Tanous   dbus::message m = dbus::message::new_call(test_daemon, "ListNames");
111b6e8327aSEd Tanous   system_bus.async_send(
112b6e8327aSEd Tanous       m, [&](const boost::system::error_code ec, dbus::message r) {
113b6e8327aSEd Tanous         io.stop();
114b6e8327aSEd Tanous         std::vector<std::string> services;
115b6e8327aSEd Tanous         r.unpack(services);
116b6e8327aSEd Tanous         // Test a couple things that should always be present.... adapt if
117b6e8327aSEd Tanous         // neccesary
118b6e8327aSEd Tanous         EXPECT_THAT(services, testing::Contains("org.freedesktop.DBus"));
119b6e8327aSEd Tanous         EXPECT_THAT(services, testing::Contains("org.freedesktop.Accounts"));
120b6e8327aSEd Tanous 
121b6e8327aSEd Tanous       });
122b6e8327aSEd Tanous 
123b6e8327aSEd Tanous   io.run();
124b6e8327aSEd Tanous }
125b6e8327aSEd Tanous 
126*82a51ce2SEd Tanous void query_interfaces(dbus::connection& system_bus, std::string& service_name,
127*82a51ce2SEd Tanous                       std::string& object_name) {
128*82a51ce2SEd Tanous   dbus::endpoint service_daemon(service_name, object_name,
129*82a51ce2SEd Tanous                                 "org.freedestop.DBus.Introspectable");
130*82a51ce2SEd Tanous   dbus::message m = dbus::message::new_call(service_daemon, "Introspect");
131*82a51ce2SEd Tanous   try {
132*82a51ce2SEd Tanous     auto r = system_bus.send(m);
133*82a51ce2SEd Tanous     std::vector<std::string> names;
134*82a51ce2SEd Tanous     // Todo(ed) figure out why we're occassionally getting access
135*82a51ce2SEd Tanous     // denied errors
136*82a51ce2SEd Tanous     // EXPECT_EQ(ec, boost::system::errc::success);
137*82a51ce2SEd Tanous 
138*82a51ce2SEd Tanous     std::string xml;
139*82a51ce2SEd Tanous     r.unpack(xml);
140*82a51ce2SEd Tanous     // TODO(ed) names needs lock for multithreaded access
141*82a51ce2SEd Tanous     dbus::read_dbus_xml_names(xml, names);
142*82a51ce2SEd Tanous     // loop over the newly added items
143*82a51ce2SEd Tanous     for (auto name : names) {
144*82a51ce2SEd Tanous       std::cout << name << "\n";
145*82a51ce2SEd Tanous       auto new_service_string = object_name + "/" + name;
146*82a51ce2SEd Tanous       query_interfaces(system_bus, service_name, new_service_string);
147*82a51ce2SEd Tanous     }
148*82a51ce2SEd Tanous   } catch (boost::system::error_code e) {
149*82a51ce2SEd Tanous     std::cout << e;
150*82a51ce2SEd Tanous   }
151*82a51ce2SEd Tanous }
152*82a51ce2SEd Tanous 
153*82a51ce2SEd Tanous TEST(BOOST_DBUS, ObjectManager) {
154b6e8327aSEd Tanous   boost::asio::io_service io;
155b6e8327aSEd Tanous   dbus::connection system_bus(io, dbus::bus::system);
156b6e8327aSEd Tanous 
157*82a51ce2SEd Tanous   dbus::match ma(system_bus,
158*82a51ce2SEd Tanous                  "type='signal',path_namespace='/xyz/openbmc_project/sensors'");
159*82a51ce2SEd Tanous   dbus::filter f(system_bus, [](dbus::message& m) {
160*82a51ce2SEd Tanous     auto member = m.get_member();
161*82a51ce2SEd Tanous     return member == "PropertiesChanged";
162*82a51ce2SEd Tanous   });
163b6e8327aSEd Tanous 
164*82a51ce2SEd Tanous   std::function<void(boost::system::error_code, dbus::message)> event_handler =
165*82a51ce2SEd Tanous       [&](boost::system::error_code ec, dbus::message s) {
166*82a51ce2SEd Tanous         std::string object_name;
167*82a51ce2SEd Tanous         std::vector<std::pair<std::string, dbus::dbus_variant>> values;
168*82a51ce2SEd Tanous         s.unpack(object_name).unpack(values);
169b6e8327aSEd Tanous 
170*82a51ce2SEd Tanous         EXPECT_EQ(object_name, "xyz.openbmc_project.Sensor.Value");
171*82a51ce2SEd Tanous 
172*82a51ce2SEd Tanous         //EXPECT_EQ(values.size(), 1);
173*82a51ce2SEd Tanous         auto expected = std::pair<std::string, dbus::dbus_variant>("Value", 42);
174*82a51ce2SEd Tanous         //EXPECT_EQ(values[0], expected);
175*82a51ce2SEd Tanous         //s.unpack(values);
176*82a51ce2SEd Tanous 
177*82a51ce2SEd Tanous         //f.async_dispatch(event_handler);
178b6e8327aSEd Tanous         io.stop();
179*82a51ce2SEd Tanous       };
180*82a51ce2SEd Tanous   f.async_dispatch(event_handler);
181b6e8327aSEd Tanous 
182*82a51ce2SEd Tanous   dbus::endpoint test_endpoint(
183*82a51ce2SEd Tanous       "org.freedesktop.Avahi",
184*82a51ce2SEd Tanous       "/xyz/openbmc_project/sensors/temperature/LR_Brd_Temp",
185*82a51ce2SEd Tanous       "org.freedesktop.DBus.Properties");
186b6e8327aSEd Tanous 
187*82a51ce2SEd Tanous   auto signal_name = std::string("PropertiesChanged");
188*82a51ce2SEd Tanous   auto m = dbus::message::new_signal(test_endpoint, signal_name);
189*82a51ce2SEd Tanous 
190*82a51ce2SEd Tanous   m.pack("xyz.openbmc_project.Sensor.Value");
191*82a51ce2SEd Tanous 
192*82a51ce2SEd Tanous   std::vector<std::pair<std::string, dbus::dbus_variant>> map2;
193*82a51ce2SEd Tanous 
194*82a51ce2SEd Tanous   map2.emplace_back("Value", 42);
195*82a51ce2SEd Tanous 
196*82a51ce2SEd Tanous   m.pack(map2);
197*82a51ce2SEd Tanous 
198*82a51ce2SEd Tanous   auto removed = std::vector<uint32_t>();
199*82a51ce2SEd Tanous   m.pack(removed);
200*82a51ce2SEd Tanous   system_bus.async_send(m,
201*82a51ce2SEd Tanous                         [&](boost::system::error_code ec, dbus::message s) {});
202b6e8327aSEd Tanous 
203b6e8327aSEd Tanous   io.run();
204b6e8327aSEd Tanous }
205