blob: 849b60baedafcfa884988fada71b9fc5689c5a77 [file] [log] [blame]
Brad Bishop49aefb32016-10-19 11:54:14 -04001/**
2 * Copyright © 2016 IBM Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Brad Bishopa6fcd562017-02-03 11:00:27 -050016#include "manager.hpp"
17#include "config.h"
Brad Bishop49aefb32016-10-19 11:54:14 -040018#include <cassert>
Brad Bishopabb2a1a2016-11-30 22:02:28 -050019#include <iostream>
20#include <algorithm>
Brad Bishop21621432017-01-13 16:35:53 -050021#include <thread>
Brad Bishop8f868502017-01-23 13:13:58 -050022#include <chrono>
Brad Bishopa6fcd562017-02-03 11:00:27 -050023#include "xyz/openbmc_project/Example/Iface1/server.hpp"
24#include "xyz/openbmc_project/Example/Iface2/server.hpp"
Brad Bishop49aefb32016-10-19 11:54:14 -040025
Brad Bishop8f868502017-01-23 13:13:58 -050026using namespace std::literals::chrono_literals;
27using namespace std::literals::string_literals;
28
Brad Bishop03f4cd92017-02-03 15:17:21 -050029using Object = phosphor::inventory::manager::Object;
30using ObjectMap = std::map<sdbusplus::message::object_path, Object>;
31
Brad Bishop8f868502017-01-23 13:13:58 -050032constexpr auto MGR_SERVICE = "phosphor.inventory.test.mgr";
33constexpr auto MGR_INTERFACE = IFACE;
34constexpr auto MGR_ROOT = "/testing/inventory";
35constexpr auto EXAMPLE_SERVICE = "phosphor.inventory.test.example";
36constexpr auto EXAMPLE_ROOT = "/testing";
37
38const auto trigger1 = sdbusplus::message::object_path(EXAMPLE_ROOT +
39 "/trigger1"s);
40const auto trigger2 = sdbusplus::message::object_path(EXAMPLE_ROOT +
41 "/trigger2"s);
Brad Bishopfb083c22017-01-19 09:22:04 -050042const auto trigger3 = sdbusplus::message::object_path(EXAMPLE_ROOT +
43 "/trigger3"s);
Brad Bishopfa51da72017-01-19 11:06:51 -050044const auto trigger4 = sdbusplus::message::object_path(EXAMPLE_ROOT +
45 "/trigger4"s);
Brad Bishopeb68a682017-01-22 00:58:54 -050046const auto trigger5 = sdbusplus::message::object_path(EXAMPLE_ROOT +
47 "/trigger5"s);
Brad Bishopfb083c22017-01-19 09:22:04 -050048
49const sdbusplus::message::object_path relDeleteMeOne{"/deleteme1"};
50const sdbusplus::message::object_path relDeleteMeTwo{"/deleteme2"};
51const sdbusplus::message::object_path relDeleteMeThree{"/deleteme3"};
52
53const std::string root{MGR_ROOT};
54const std::string deleteMeOne{root + relDeleteMeOne.str};
55const std::string deleteMeTwo{root + relDeleteMeTwo.str};
56const std::string deleteMeThree{root + relDeleteMeThree.str};
Brad Bishop8f868502017-01-23 13:13:58 -050057
58using ExampleIface1 = sdbusplus::xyz::openbmc_project::Example::server::Iface1;
59using ExampleIface2 = sdbusplus::xyz::openbmc_project::Example::server::Iface2;
60
61/** @class ExampleService
62 * @brief Host an object for triggering events.
63 */
64struct ExampleService
65{
66 ~ExampleService() = default;
67 ExampleService() :
68 shutdown(false),
69 bus(sdbusplus::bus::new_default()),
70 objmgr(sdbusplus::server::manager::manager(bus, MGR_ROOT))
71 {
72 bus.request_name(EXAMPLE_SERVICE);
73 }
74
75 void run()
76 {
77 sdbusplus::server::object::object <
78 ExampleIface1, ExampleIface2 > t1(bus, trigger1.str.c_str());
79 sdbusplus::server::object::object <
80 ExampleIface1, ExampleIface2 > t2(bus, trigger2.str.c_str());
Brad Bishopfb083c22017-01-19 09:22:04 -050081 sdbusplus::server::object::object <
82 ExampleIface1, ExampleIface2 > t3(bus, trigger3.str.c_str());
Brad Bishopfa51da72017-01-19 11:06:51 -050083 sdbusplus::server::object::object <
84 ExampleIface1, ExampleIface2 > t4(bus, trigger4.str.c_str());
Brad Bishopeb68a682017-01-22 00:58:54 -050085 sdbusplus::server::object::object <
86 ExampleIface1, ExampleIface2 > t5(bus, trigger5.str.c_str());
Brad Bishop8f868502017-01-23 13:13:58 -050087
88 while (!shutdown)
89 {
90 bus.process_discard();
91 bus.wait((5000000us).count());
92 }
93 }
94
95 volatile bool shutdown;
96 sdbusplus::bus::bus bus;
97 sdbusplus::server::manager::manager objmgr;
98};
Brad Bishop49aefb32016-10-19 11:54:14 -040099
Brad Bishop1157af12017-01-22 01:03:02 -0500100
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500101/** @class SignalQueue
102 * @brief Store DBus signals in a queue.
103 */
104class SignalQueue
105{
106 public:
Brad Bishop7b337772017-01-12 16:11:24 -0500107 ~SignalQueue() = default;
108 SignalQueue() = delete;
109 SignalQueue(const SignalQueue&) = delete;
110 SignalQueue(SignalQueue&&) = default;
111 SignalQueue& operator=(const SignalQueue&) = delete;
112 SignalQueue& operator=(SignalQueue&&) = default;
113 explicit SignalQueue(const std::string& match) :
114 _bus(sdbusplus::bus::new_default()),
115 _match(_bus, match.c_str(), &callback, this),
116 _next(nullptr)
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500117 {
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500118 }
Brad Bishop7b337772017-01-12 16:11:24 -0500119
120 auto&& pop(unsigned timeout = 1000000)
121 {
122 while (timeout > 0 && !_next)
123 {
124 _bus.process_discard();
125 _bus.wait(50000);
126 timeout -= 50000;
127 }
128 return std::move(_next);
129 }
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500130
131 private:
Brad Bishop7b337772017-01-12 16:11:24 -0500132 static int callback(sd_bus_message* m, void* context, sd_bus_error*)
133 {
134 auto* me = static_cast<SignalQueue*>(context);
135 sd_bus_message_ref(m);
136 sdbusplus::message::message msg{m};
137 me->_next = std::move(msg);
138 return 0;
139 }
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500140
Brad Bishop7b337772017-01-12 16:11:24 -0500141 sdbusplus::bus::bus _bus;
Patrick Williams133ca132017-05-01 22:12:34 -0500142 sdbusplus::bus::match_t _match;
Brad Bishop7b337772017-01-12 16:11:24 -0500143 sdbusplus::message::message _next;
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500144};
145
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500146/**@brief Find a subset of interfaces and properties in an object. */
Brad Bishop1157af12017-01-22 01:03:02 -0500147auto hasProperties(const Object& l, const Object& r)
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500148{
Brad Bishop1157af12017-01-22 01:03:02 -0500149 Object result;
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500150 std::set_difference(
Brad Bishop7b337772017-01-12 16:11:24 -0500151 r.cbegin(),
152 r.cend(),
153 l.cbegin(),
154 l.cend(),
155 std::inserter(result, result.end()));
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500156 return result.empty();
157}
158
Brad Bishop432e3522016-12-01 00:24:14 -0500159/**@brief Check an object for one or more interfaces. */
Brad Bishop1157af12017-01-22 01:03:02 -0500160auto hasInterfaces(const std::vector<std::string>& l, const Object& r)
Brad Bishop432e3522016-12-01 00:24:14 -0500161{
162 std::vector<std::string> stripped, interfaces;
163 std::transform(
Brad Bishop7b337772017-01-12 16:11:24 -0500164 r.cbegin(),
165 r.cend(),
166 std::back_inserter(stripped),
167 [](auto & p)
168 {
169 return p.first;
170 });
Brad Bishop432e3522016-12-01 00:24:14 -0500171 std::set_difference(
Brad Bishop7b337772017-01-12 16:11:24 -0500172 stripped.cbegin(),
173 stripped.cend(),
174 l.cbegin(),
175 l.cend(),
176 std::back_inserter(interfaces));
Brad Bishop432e3522016-12-01 00:24:14 -0500177 return interfaces.empty();
178}
179
Brad Bishop8f868502017-01-23 13:13:58 -0500180void runTests()
Brad Bishop49aefb32016-10-19 11:54:14 -0400181{
Brad Bishop8f868502017-01-23 13:13:58 -0500182 const std::string exampleRoot{EXAMPLE_ROOT};
Brad Bishop49aefb32016-10-19 11:54:14 -0400183 auto b = sdbusplus::bus::new_default();
Brad Bishop8f868502017-01-23 13:13:58 -0500184
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500185 auto notify = [&]()
Brad Bishop49aefb32016-10-19 11:54:14 -0400186 {
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500187 return b.new_method_call(
Brad Bishop8f868502017-01-23 13:13:58 -0500188 MGR_SERVICE,
189 MGR_ROOT,
190 MGR_INTERFACE,
Brad Bishop7b337772017-01-12 16:11:24 -0500191 "Notify");
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500192 };
Brad Bishop7b337772017-01-12 16:11:24 -0500193 auto set = [&](const std::string & path)
Brad Bishop432e3522016-12-01 00:24:14 -0500194 {
195 return b.new_method_call(
Brad Bishop8f868502017-01-23 13:13:58 -0500196 EXAMPLE_SERVICE,
Brad Bishop7b337772017-01-12 16:11:24 -0500197 path.c_str(),
198 "org.freedesktop.DBus.Properties",
199 "Set");
Brad Bishop432e3522016-12-01 00:24:14 -0500200 };
Brad Bishop49aefb32016-10-19 11:54:14 -0400201
Brad Bishop1157af12017-01-22 01:03:02 -0500202 Object obj
Brad Bishop7b337772017-01-12 16:11:24 -0500203 {
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500204 {
205 "xyz.openbmc_project.Example.Iface1",
Brad Bishop03f4cd92017-02-03 15:17:21 -0500206 {{"ExampleProperty1", "test1"s}}
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500207 },
208 {
209 "xyz.openbmc_project.Example.Iface2",
Brad Bishop134d2cb2017-02-23 12:37:56 -0500210 { {"ExampleProperty2", "test2"s},
211 {"ExampleProperty3", static_cast<int64_t>(0ll)}
212 }
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500213 },
214 };
Brad Bishop49aefb32016-10-19 11:54:14 -0400215
Brad Bishop3e4a19a2017-01-21 22:17:09 -0500216 // Validate startup events occurred.
217 {
218 sdbusplus::message::object_path relCreateMe3{"/createme3"};
219 std::string createMe3{root + relCreateMe3.str};
220
221 auto get = b.new_method_call(
222 MGR_SERVICE,
223 createMe3.c_str(),
224 "org.freedesktop.DBus.Properties",
225 "GetAll");
226 get.append("xyz.openbmc_project.Example.Iface1");
227 auto resp = b.call(get);
228
229 Object::mapped_type properties;
230 assert(!resp.is_method_error());
231 resp.read(properties);
232 }
233
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500234 // Make sure the notify method works.
235 {
Brad Bishop9aa5e2f2017-01-15 19:45:40 -0500236 sdbusplus::message::object_path relPath{"/foo"};
237 std::string path(root + relPath.str);
Brad Bishop49aefb32016-10-19 11:54:14 -0400238
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500239 SignalQueue queue(
Brad Bishop7b337772017-01-12 16:11:24 -0500240 "path='" + root + "',member='InterfacesAdded'");
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500241
242 auto m = notify();
Brad Bishop03f4cd92017-02-03 15:17:21 -0500243 m.append(ObjectMap({{relPath, obj}}));
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500244 b.call(m);
245
246 auto sig{queue.pop()};
247 assert(sig);
Brad Bishop9aa5e2f2017-01-15 19:45:40 -0500248 sdbusplus::message::object_path signalPath;
Brad Bishop1157af12017-01-22 01:03:02 -0500249 Object signalObjectType;
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500250 sig.read(signalPath);
Brad Bishope07a1642017-01-24 14:37:33 -0500251 assert(path == signalPath.str);
Brad Bishop1157af12017-01-22 01:03:02 -0500252 sig.read(signalObjectType);
253 assert(hasProperties(signalObjectType, obj));
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500254 auto moreSignals{queue.pop()};
255 assert(!moreSignals);
Brad Bishop49aefb32016-10-19 11:54:14 -0400256 }
257
Brad Bishopfa51da72017-01-19 11:06:51 -0500258 // Validate the propertyIs filter.
259 {
260 // Create an object to be deleted.
261 {
262 auto m = notify();
Brad Bishop03f4cd92017-02-03 15:17:21 -0500263 m.append(ObjectMap({{relDeleteMeThree, obj}}));
Brad Bishopfa51da72017-01-19 11:06:51 -0500264 b.call(m);
265 }
266
267 // Validate that the action does not run if the property doesn't match.
268 {
269 SignalQueue queue(
270 "path='" + root + "',member='InterfacesRemoved'");
271 auto m = set(trigger4.str);
272 m.append("xyz.openbmc_project.Example.Iface2");
273 m.append("ExampleProperty2");
274 m.append(sdbusplus::message::variant<std::string>("123"));
275 b.call(m);
276 auto sig{queue.pop()};
277 assert(!sig);
278 }
279
280 // Validate that the action does run if the property matches.
281 {
282 // Set ExampleProperty2 to something else to the 123 filter
283 // matches.
284 SignalQueue queue(
285 "path='" + root + "',member='InterfacesRemoved'");
286 auto m = set(trigger4.str);
287 m.append("xyz.openbmc_project.Example.Iface2");
288 m.append("ExampleProperty2");
289 m.append(sdbusplus::message::variant<std::string>("xyz"));
290 b.call(m);
291 auto sig{queue.pop()};
292 assert(!sig);
293 }
294 {
295 // Set ExampleProperty3 to 99.
296 SignalQueue queue(
297 "path='" + root + "',member='InterfacesRemoved'");
298 auto m = set(trigger4.str);
299 m.append("xyz.openbmc_project.Example.Iface2");
300 m.append("ExampleProperty3");
301 m.append(sdbusplus::message::variant<int64_t>(99));
302 b.call(m);
303 auto sig{queue.pop()};
304 assert(!sig);
305 }
306 {
307 SignalQueue queue(
308 "path='" + root + "',member='InterfacesRemoved'");
309 auto m = set(trigger4.str);
310 m.append("xyz.openbmc_project.Example.Iface2");
311 m.append("ExampleProperty2");
312 m.append(sdbusplus::message::variant<std::string>("123"));
313 b.call(m);
314
315 sdbusplus::message::object_path sigpath;
316 std::vector<std::string> interfaces;
317 {
318 std::vector<std::string> interfaces;
319 auto sig{queue.pop()};
320 assert(sig);
321 sig.read(sigpath);
322 assert(sigpath == deleteMeThree);
323 sig.read(interfaces);
324 std::sort(interfaces.begin(), interfaces.end());
325 assert(hasInterfaces(interfaces, obj));
326 }
327 }
328 }
329
Brad Bishop432e3522016-12-01 00:24:14 -0500330 // Make sure DBus signals are handled.
331 {
Brad Bishop432e3522016-12-01 00:24:14 -0500332 // Create some objects to be deleted by an action.
333 {
334 auto m = notify();
Brad Bishop03f4cd92017-02-03 15:17:21 -0500335 m.append(ObjectMap({{relDeleteMeOne, obj}}));
Brad Bishop432e3522016-12-01 00:24:14 -0500336 b.call(m);
337 }
338 {
339 auto m = notify();
Brad Bishop03f4cd92017-02-03 15:17:21 -0500340 m.append(ObjectMap({{relDeleteMeTwo, obj}}));
Brad Bishop432e3522016-12-01 00:24:14 -0500341 b.call(m);
342 }
Brad Bishopfb083c22017-01-19 09:22:04 -0500343 {
344 auto m = notify();
Brad Bishop03f4cd92017-02-03 15:17:21 -0500345 m.append(ObjectMap({{relDeleteMeThree, obj}}));
Brad Bishopfb083c22017-01-19 09:22:04 -0500346 b.call(m);
347 }
Brad Bishop432e3522016-12-01 00:24:14 -0500348
Brad Bishopfb083c22017-01-19 09:22:04 -0500349 // Set some properties that should not trigger due to a filter.
Brad Bishop432e3522016-12-01 00:24:14 -0500350 {
351 SignalQueue queue(
Brad Bishop7b337772017-01-12 16:11:24 -0500352 "path='" + root + "',member='InterfacesRemoved'");
Brad Bishop8f868502017-01-23 13:13:58 -0500353 auto m = set(trigger1.str);
Brad Bishop432e3522016-12-01 00:24:14 -0500354 m.append("xyz.openbmc_project.Example.Iface2");
355 m.append("ExampleProperty2");
356 m.append(sdbusplus::message::variant<std::string>("abc123"));
357 b.call(m);
358 auto sig{queue.pop()};
359 assert(!sig);
360 }
Brad Bishopfb083c22017-01-19 09:22:04 -0500361 {
362 SignalQueue queue(
363 "path='" + root + "',member='InterfacesRemoved'");
364 auto m = set(trigger3.str);
365 m.append("xyz.openbmc_project.Example.Iface2");
366 m.append("ExampleProperty3");
367 m.append(sdbusplus::message::variant<int64_t>(11));
368 b.call(m);
369 auto sig{queue.pop()};
370 assert(!sig);
371 }
Brad Bishop432e3522016-12-01 00:24:14 -0500372
Brad Bishopfb083c22017-01-19 09:22:04 -0500373 // Set some properties that should trigger.
Brad Bishop432e3522016-12-01 00:24:14 -0500374 {
375 SignalQueue queue(
Brad Bishop7b337772017-01-12 16:11:24 -0500376 "path='" + root + "',member='InterfacesRemoved'");
Brad Bishop432e3522016-12-01 00:24:14 -0500377
Brad Bishop8f868502017-01-23 13:13:58 -0500378 auto m = set(trigger1.str);
Brad Bishop432e3522016-12-01 00:24:14 -0500379 m.append("xyz.openbmc_project.Example.Iface2");
380 m.append("ExampleProperty2");
381 m.append(sdbusplus::message::variant<std::string>("xxxyyy"));
382 b.call(m);
383
Brad Bishop9aa5e2f2017-01-15 19:45:40 -0500384 sdbusplus::message::object_path sigpath;
Brad Bishop432e3522016-12-01 00:24:14 -0500385 std::vector<std::string> interfaces;
386 {
387 std::vector<std::string> interfaces;
388 auto sig{queue.pop()};
389 assert(sig);
390 sig.read(sigpath);
391 assert(sigpath == deleteMeOne);
392 sig.read(interfaces);
393 std::sort(interfaces.begin(), interfaces.end());
394 assert(hasInterfaces(interfaces, obj));
395 }
396 {
397 std::vector<std::string> interfaces;
398 auto sig{queue.pop()};
399 assert(sig);
400 sig.read(sigpath);
401 assert(sigpath == deleteMeTwo);
402 sig.read(interfaces);
403 std::sort(interfaces.begin(), interfaces.end());
404 assert(hasInterfaces(interfaces, obj));
405 }
406 {
407 // Make sure there were only two signals.
408 auto sig{queue.pop()};
409 assert(!sig);
410 }
411 }
Brad Bishopfb083c22017-01-19 09:22:04 -0500412 {
413 SignalQueue queue(
414 "path='" + root + "',member='InterfacesRemoved'");
415
416 auto m = set(trigger3.str);
417 m.append("xyz.openbmc_project.Example.Iface2");
418 m.append("ExampleProperty3");
419 m.append(sdbusplus::message::variant<int64_t>(10));
420 b.call(m);
421
422 sdbusplus::message::object_path sigpath;
423 std::vector<std::string> interfaces;
424 {
425 std::vector<std::string> interfaces;
426 auto sig{queue.pop()};
427 assert(sig);
428 sig.read(sigpath);
429 assert(sigpath == deleteMeThree);
430 sig.read(interfaces);
431 std::sort(interfaces.begin(), interfaces.end());
432 assert(hasInterfaces(interfaces, obj));
433 }
434 {
435 // Make sure there was only one signal.
436 auto sig{queue.pop()};
437 assert(!sig);
438 }
439 }
Brad Bishop432e3522016-12-01 00:24:14 -0500440 }
441
Brad Bishop22ecacc2016-12-01 08:38:06 -0500442 // Validate the set property action.
443 {
Brad Bishop9aa5e2f2017-01-15 19:45:40 -0500444 sdbusplus::message::object_path relChangeMe{"/changeme"};
Brad Bishop9aa5e2f2017-01-15 19:45:40 -0500445 std::string changeMe{root + relChangeMe.str};
Brad Bishop22ecacc2016-12-01 08:38:06 -0500446
447 // Create an object to be updated by the set property action.
448 {
449 auto m = notify();
Brad Bishop03f4cd92017-02-03 15:17:21 -0500450 m.append(ObjectMap({{relChangeMe, obj}}));
Brad Bishop22ecacc2016-12-01 08:38:06 -0500451 b.call(m);
452 }
453
Brad Bishop22ecacc2016-12-01 08:38:06 -0500454 // Trigger and validate the change.
455 {
456 SignalQueue queue(
Brad Bishop7b337772017-01-12 16:11:24 -0500457 "path='" + changeMe + "',member='PropertiesChanged'");
Brad Bishop8f868502017-01-23 13:13:58 -0500458 auto m = set(trigger2.str);
Brad Bishop22ecacc2016-12-01 08:38:06 -0500459 m.append("xyz.openbmc_project.Example.Iface2");
460 m.append("ExampleProperty2");
461 m.append(sdbusplus::message::variant<std::string>("yyyxxx"));
462 b.call(m);
463
464 std::string sigInterface;
Brad Bishop7b337772017-01-12 16:11:24 -0500465 std::map <
466 std::string,
467 sdbusplus::message::variant<std::string >> sigProperties;
Brad Bishop22ecacc2016-12-01 08:38:06 -0500468 {
469 std::vector<std::string> interfaces;
470 auto sig{queue.pop()};
471 sig.read(sigInterface);
472 assert(sigInterface == "xyz.openbmc_project.Example.Iface1");
473 sig.read(sigProperties);
474 assert(sigProperties["ExampleProperty1"] == "changed");
475 }
476 }
477 }
Brad Bishopeb68a682017-01-22 00:58:54 -0500478
479 // Validate the create object action.
480 {
481 sdbusplus::message::object_path relCreateMe1{"/createme1"};
482 sdbusplus::message::object_path relCreateMe2{"/createme2"};
483 std::string createMe1{root + relCreateMe1.str};
484 std::string createMe2{root + relCreateMe2.str};
485
486 // Trigger the action.
487 {
488 sdbusplus::message::object_path signalPath;
489 Object signalObject;
490
491 SignalQueue queue(
492 "path='" + root + "',member='InterfacesAdded'");
493
494 auto m = set(trigger5.str);
495 m.append("xyz.openbmc_project.Example.Iface2");
496 m.append("ExampleProperty2");
497 m.append(sdbusplus::message::variant<std::string>("abc123"));
498 b.call(m);
499 {
500 auto sig{queue.pop()};
501 assert(sig);
502 sig.read(signalPath);
503 assert(createMe1 == signalPath.str);
504 sig.read(signalObject);
505 }
506 {
507 auto sig{queue.pop()};
508 assert(sig);
509 sig.read(signalPath);
510 assert(createMe2 == signalPath.str);
511 sig.read(signalObject);
512 }
513
514 auto moreSignals{queue.pop()};
515 assert(!moreSignals);
516 }
517 }
Brad Bishop49aefb32016-10-19 11:54:14 -0400518}
519
520int main()
521{
Brad Bishop65247582017-01-15 19:48:41 -0500522 phosphor::inventory::manager::Manager mgr(
523 sdbusplus::bus::new_default(),
Brad Bishop8f868502017-01-23 13:13:58 -0500524 MGR_SERVICE, MGR_ROOT, MGR_INTERFACE);
525 ExampleService d;
Brad Bishop49aefb32016-10-19 11:54:14 -0400526
Brad Bishop8f868502017-01-23 13:13:58 -0500527 auto f1 = [](auto mgr)
Brad Bishop49aefb32016-10-19 11:54:14 -0400528 {
Brad Bishop21621432017-01-13 16:35:53 -0500529 mgr->run();
530 };
Brad Bishop8f868502017-01-23 13:13:58 -0500531 auto f2 = [](auto d)
532 {
533 d->run();
534 };
Brad Bishop49aefb32016-10-19 11:54:14 -0400535
Brad Bishop8f868502017-01-23 13:13:58 -0500536 auto t1 = std::thread(f1, &mgr);
537 auto t2 = std::thread(f2, &d);
538
539 runTests();
540
541 mgr.shutdown();
542 d.shutdown = true;
543
544 // Wait for server threads to exit.
545 t1.join();
546 t2.join();
547 std::cout << "Success! Waiting for threads to exit..." << std::endl;
Brad Bishop49aefb32016-10-19 11:54:14 -0400548
549 return 0;
550}
551
552// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4