blob: 0a941f7127ca23d6be56d58ad2677ae8c6ba696f [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;
142 sdbusplus::server::match::match _match;
143 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 Bishop03f4cd92017-02-03 15:17:21 -0500210 {{"ExampleProperty2", "test2"s}}
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500211 },
212 };
Brad Bishop49aefb32016-10-19 11:54:14 -0400213
Brad Bishop3e4a19a2017-01-21 22:17:09 -0500214 // Validate startup events occurred.
215 {
216 sdbusplus::message::object_path relCreateMe3{"/createme3"};
217 std::string createMe3{root + relCreateMe3.str};
218
219 auto get = b.new_method_call(
220 MGR_SERVICE,
221 createMe3.c_str(),
222 "org.freedesktop.DBus.Properties",
223 "GetAll");
224 get.append("xyz.openbmc_project.Example.Iface1");
225 auto resp = b.call(get);
226
227 Object::mapped_type properties;
228 assert(!resp.is_method_error());
229 resp.read(properties);
230 }
231
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500232 // Make sure the notify method works.
233 {
Brad Bishop9aa5e2f2017-01-15 19:45:40 -0500234 sdbusplus::message::object_path relPath{"/foo"};
235 std::string path(root + relPath.str);
Brad Bishop49aefb32016-10-19 11:54:14 -0400236
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500237 SignalQueue queue(
Brad Bishop7b337772017-01-12 16:11:24 -0500238 "path='" + root + "',member='InterfacesAdded'");
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500239
240 auto m = notify();
Brad Bishop03f4cd92017-02-03 15:17:21 -0500241 m.append(ObjectMap({{relPath, obj}}));
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500242 b.call(m);
243
244 auto sig{queue.pop()};
245 assert(sig);
Brad Bishop9aa5e2f2017-01-15 19:45:40 -0500246 sdbusplus::message::object_path signalPath;
Brad Bishop1157af12017-01-22 01:03:02 -0500247 Object signalObjectType;
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500248 sig.read(signalPath);
Brad Bishope07a1642017-01-24 14:37:33 -0500249 assert(path == signalPath.str);
Brad Bishop1157af12017-01-22 01:03:02 -0500250 sig.read(signalObjectType);
251 assert(hasProperties(signalObjectType, obj));
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500252 auto moreSignals{queue.pop()};
253 assert(!moreSignals);
Brad Bishop49aefb32016-10-19 11:54:14 -0400254 }
255
Brad Bishopfa51da72017-01-19 11:06:51 -0500256 // Validate the propertyIs filter.
257 {
258 // Create an object to be deleted.
259 {
260 auto m = notify();
Brad Bishop03f4cd92017-02-03 15:17:21 -0500261 m.append(ObjectMap({{relDeleteMeThree, obj}}));
Brad Bishopfa51da72017-01-19 11:06:51 -0500262 b.call(m);
263 }
264
265 // Validate that the action does not run if the property doesn't match.
266 {
267 SignalQueue queue(
268 "path='" + root + "',member='InterfacesRemoved'");
269 auto m = set(trigger4.str);
270 m.append("xyz.openbmc_project.Example.Iface2");
271 m.append("ExampleProperty2");
272 m.append(sdbusplus::message::variant<std::string>("123"));
273 b.call(m);
274 auto sig{queue.pop()};
275 assert(!sig);
276 }
277
278 // Validate that the action does run if the property matches.
279 {
280 // Set ExampleProperty2 to something else to the 123 filter
281 // matches.
282 SignalQueue queue(
283 "path='" + root + "',member='InterfacesRemoved'");
284 auto m = set(trigger4.str);
285 m.append("xyz.openbmc_project.Example.Iface2");
286 m.append("ExampleProperty2");
287 m.append(sdbusplus::message::variant<std::string>("xyz"));
288 b.call(m);
289 auto sig{queue.pop()};
290 assert(!sig);
291 }
292 {
293 // Set ExampleProperty3 to 99.
294 SignalQueue queue(
295 "path='" + root + "',member='InterfacesRemoved'");
296 auto m = set(trigger4.str);
297 m.append("xyz.openbmc_project.Example.Iface2");
298 m.append("ExampleProperty3");
299 m.append(sdbusplus::message::variant<int64_t>(99));
300 b.call(m);
301 auto sig{queue.pop()};
302 assert(!sig);
303 }
304 {
305 SignalQueue queue(
306 "path='" + root + "',member='InterfacesRemoved'");
307 auto m = set(trigger4.str);
308 m.append("xyz.openbmc_project.Example.Iface2");
309 m.append("ExampleProperty2");
310 m.append(sdbusplus::message::variant<std::string>("123"));
311 b.call(m);
312
313 sdbusplus::message::object_path sigpath;
314 std::vector<std::string> interfaces;
315 {
316 std::vector<std::string> interfaces;
317 auto sig{queue.pop()};
318 assert(sig);
319 sig.read(sigpath);
320 assert(sigpath == deleteMeThree);
321 sig.read(interfaces);
322 std::sort(interfaces.begin(), interfaces.end());
323 assert(hasInterfaces(interfaces, obj));
324 }
325 }
326 }
327
Brad Bishop432e3522016-12-01 00:24:14 -0500328 // Make sure DBus signals are handled.
329 {
Brad Bishop432e3522016-12-01 00:24:14 -0500330 // Create some objects to be deleted by an action.
331 {
332 auto m = notify();
Brad Bishop03f4cd92017-02-03 15:17:21 -0500333 m.append(ObjectMap({{relDeleteMeOne, obj}}));
Brad Bishop432e3522016-12-01 00:24:14 -0500334 b.call(m);
335 }
336 {
337 auto m = notify();
Brad Bishop03f4cd92017-02-03 15:17:21 -0500338 m.append(ObjectMap({{relDeleteMeTwo, obj}}));
Brad Bishop432e3522016-12-01 00:24:14 -0500339 b.call(m);
340 }
Brad Bishopfb083c22017-01-19 09:22:04 -0500341 {
342 auto m = notify();
Brad Bishop03f4cd92017-02-03 15:17:21 -0500343 m.append(ObjectMap({{relDeleteMeThree, obj}}));
Brad Bishopfb083c22017-01-19 09:22:04 -0500344 b.call(m);
345 }
Brad Bishop432e3522016-12-01 00:24:14 -0500346
Brad Bishopfb083c22017-01-19 09:22:04 -0500347 // Set some properties that should not trigger due to a filter.
Brad Bishop432e3522016-12-01 00:24:14 -0500348 {
349 SignalQueue queue(
Brad Bishop7b337772017-01-12 16:11:24 -0500350 "path='" + root + "',member='InterfacesRemoved'");
Brad Bishop8f868502017-01-23 13:13:58 -0500351 auto m = set(trigger1.str);
Brad Bishop432e3522016-12-01 00:24:14 -0500352 m.append("xyz.openbmc_project.Example.Iface2");
353 m.append("ExampleProperty2");
354 m.append(sdbusplus::message::variant<std::string>("abc123"));
355 b.call(m);
356 auto sig{queue.pop()};
357 assert(!sig);
358 }
Brad Bishopfb083c22017-01-19 09:22:04 -0500359 {
360 SignalQueue queue(
361 "path='" + root + "',member='InterfacesRemoved'");
362 auto m = set(trigger3.str);
363 m.append("xyz.openbmc_project.Example.Iface2");
364 m.append("ExampleProperty3");
365 m.append(sdbusplus::message::variant<int64_t>(11));
366 b.call(m);
367 auto sig{queue.pop()};
368 assert(!sig);
369 }
Brad Bishop432e3522016-12-01 00:24:14 -0500370
Brad Bishopfb083c22017-01-19 09:22:04 -0500371 // Set some properties that should trigger.
Brad Bishop432e3522016-12-01 00:24:14 -0500372 {
373 SignalQueue queue(
Brad Bishop7b337772017-01-12 16:11:24 -0500374 "path='" + root + "',member='InterfacesRemoved'");
Brad Bishop432e3522016-12-01 00:24:14 -0500375
Brad Bishop8f868502017-01-23 13:13:58 -0500376 auto m = set(trigger1.str);
Brad Bishop432e3522016-12-01 00:24:14 -0500377 m.append("xyz.openbmc_project.Example.Iface2");
378 m.append("ExampleProperty2");
379 m.append(sdbusplus::message::variant<std::string>("xxxyyy"));
380 b.call(m);
381
Brad Bishop9aa5e2f2017-01-15 19:45:40 -0500382 sdbusplus::message::object_path sigpath;
Brad Bishop432e3522016-12-01 00:24:14 -0500383 std::vector<std::string> interfaces;
384 {
385 std::vector<std::string> interfaces;
386 auto sig{queue.pop()};
387 assert(sig);
388 sig.read(sigpath);
389 assert(sigpath == deleteMeOne);
390 sig.read(interfaces);
391 std::sort(interfaces.begin(), interfaces.end());
392 assert(hasInterfaces(interfaces, obj));
393 }
394 {
395 std::vector<std::string> interfaces;
396 auto sig{queue.pop()};
397 assert(sig);
398 sig.read(sigpath);
399 assert(sigpath == deleteMeTwo);
400 sig.read(interfaces);
401 std::sort(interfaces.begin(), interfaces.end());
402 assert(hasInterfaces(interfaces, obj));
403 }
404 {
405 // Make sure there were only two signals.
406 auto sig{queue.pop()};
407 assert(!sig);
408 }
409 }
Brad Bishopfb083c22017-01-19 09:22:04 -0500410 {
411 SignalQueue queue(
412 "path='" + root + "',member='InterfacesRemoved'");
413
414 auto m = set(trigger3.str);
415 m.append("xyz.openbmc_project.Example.Iface2");
416 m.append("ExampleProperty3");
417 m.append(sdbusplus::message::variant<int64_t>(10));
418 b.call(m);
419
420 sdbusplus::message::object_path sigpath;
421 std::vector<std::string> interfaces;
422 {
423 std::vector<std::string> interfaces;
424 auto sig{queue.pop()};
425 assert(sig);
426 sig.read(sigpath);
427 assert(sigpath == deleteMeThree);
428 sig.read(interfaces);
429 std::sort(interfaces.begin(), interfaces.end());
430 assert(hasInterfaces(interfaces, obj));
431 }
432 {
433 // Make sure there was only one signal.
434 auto sig{queue.pop()};
435 assert(!sig);
436 }
437 }
Brad Bishop432e3522016-12-01 00:24:14 -0500438 }
439
Brad Bishop22ecacc2016-12-01 08:38:06 -0500440 // Validate the set property action.
441 {
Brad Bishop9aa5e2f2017-01-15 19:45:40 -0500442 sdbusplus::message::object_path relChangeMe{"/changeme"};
Brad Bishop9aa5e2f2017-01-15 19:45:40 -0500443 std::string changeMe{root + relChangeMe.str};
Brad Bishop22ecacc2016-12-01 08:38:06 -0500444
445 // Create an object to be updated by the set property action.
446 {
447 auto m = notify();
Brad Bishop03f4cd92017-02-03 15:17:21 -0500448 m.append(ObjectMap({{relChangeMe, obj}}));
Brad Bishop22ecacc2016-12-01 08:38:06 -0500449 b.call(m);
450 }
451
Brad Bishop22ecacc2016-12-01 08:38:06 -0500452 // Trigger and validate the change.
453 {
454 SignalQueue queue(
Brad Bishop7b337772017-01-12 16:11:24 -0500455 "path='" + changeMe + "',member='PropertiesChanged'");
Brad Bishop8f868502017-01-23 13:13:58 -0500456 auto m = set(trigger2.str);
Brad Bishop22ecacc2016-12-01 08:38:06 -0500457 m.append("xyz.openbmc_project.Example.Iface2");
458 m.append("ExampleProperty2");
459 m.append(sdbusplus::message::variant<std::string>("yyyxxx"));
460 b.call(m);
461
462 std::string sigInterface;
Brad Bishop7b337772017-01-12 16:11:24 -0500463 std::map <
464 std::string,
465 sdbusplus::message::variant<std::string >> sigProperties;
Brad Bishop22ecacc2016-12-01 08:38:06 -0500466 {
467 std::vector<std::string> interfaces;
468 auto sig{queue.pop()};
469 sig.read(sigInterface);
470 assert(sigInterface == "xyz.openbmc_project.Example.Iface1");
471 sig.read(sigProperties);
472 assert(sigProperties["ExampleProperty1"] == "changed");
473 }
474 }
475 }
Brad Bishopeb68a682017-01-22 00:58:54 -0500476
477 // Validate the create object action.
478 {
479 sdbusplus::message::object_path relCreateMe1{"/createme1"};
480 sdbusplus::message::object_path relCreateMe2{"/createme2"};
481 std::string createMe1{root + relCreateMe1.str};
482 std::string createMe2{root + relCreateMe2.str};
483
484 // Trigger the action.
485 {
486 sdbusplus::message::object_path signalPath;
487 Object signalObject;
488
489 SignalQueue queue(
490 "path='" + root + "',member='InterfacesAdded'");
491
492 auto m = set(trigger5.str);
493 m.append("xyz.openbmc_project.Example.Iface2");
494 m.append("ExampleProperty2");
495 m.append(sdbusplus::message::variant<std::string>("abc123"));
496 b.call(m);
497 {
498 auto sig{queue.pop()};
499 assert(sig);
500 sig.read(signalPath);
501 assert(createMe1 == signalPath.str);
502 sig.read(signalObject);
503 }
504 {
505 auto sig{queue.pop()};
506 assert(sig);
507 sig.read(signalPath);
508 assert(createMe2 == signalPath.str);
509 sig.read(signalObject);
510 }
511
512 auto moreSignals{queue.pop()};
513 assert(!moreSignals);
514 }
515 }
Brad Bishop49aefb32016-10-19 11:54:14 -0400516}
517
518int main()
519{
Brad Bishop65247582017-01-15 19:48:41 -0500520 phosphor::inventory::manager::Manager mgr(
521 sdbusplus::bus::new_default(),
Brad Bishop8f868502017-01-23 13:13:58 -0500522 MGR_SERVICE, MGR_ROOT, MGR_INTERFACE);
523 ExampleService d;
Brad Bishop49aefb32016-10-19 11:54:14 -0400524
Brad Bishop8f868502017-01-23 13:13:58 -0500525 auto f1 = [](auto mgr)
Brad Bishop49aefb32016-10-19 11:54:14 -0400526 {
Brad Bishop21621432017-01-13 16:35:53 -0500527 mgr->run();
528 };
Brad Bishop8f868502017-01-23 13:13:58 -0500529 auto f2 = [](auto d)
530 {
531 d->run();
532 };
Brad Bishop49aefb32016-10-19 11:54:14 -0400533
Brad Bishop8f868502017-01-23 13:13:58 -0500534 auto t1 = std::thread(f1, &mgr);
535 auto t2 = std::thread(f2, &d);
536
537 runTests();
538
539 mgr.shutdown();
540 d.shutdown = true;
541
542 // Wait for server threads to exit.
543 t1.join();
544 t2.join();
545 std::cout << "Success! Waiting for threads to exit..." << std::endl;
Brad Bishop49aefb32016-10-19 11:54:14 -0400546
547 return 0;
548}
549
550// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4