blob: 669879d4d2bb4687158f6dd46c3061dd6eb98e79 [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 Bishope30dd772016-11-12 21:39:28 -050016#include "../manager.hpp"
Brad Bishop49aefb32016-10-19 11:54:14 -040017#include "../config.h"
18#include <cassert>
Brad Bishopabb2a1a2016-11-30 22:02:28 -050019#include <iostream>
20#include <algorithm>
Brad Bishop49aefb32016-10-19 11:54:14 -040021
22constexpr auto SERVICE = "phosphor.inventory.test";
23constexpr auto INTERFACE = IFACE;
24constexpr auto ROOT = "/testing/inventory";
25
26auto server_thread(void *data)
27{
28 auto mgr = static_cast<phosphor::inventory::manager::Manager*>(data);
29
30 mgr->run();
31
32 return static_cast<void *>(nullptr);
33}
34
Brad Bishopabb2a1a2016-11-30 22:02:28 -050035/** @class SignalQueue
36 * @brief Store DBus signals in a queue.
37 */
38class SignalQueue
39{
40 public:
41 ~SignalQueue() = default;
42 SignalQueue() = delete;
43 SignalQueue(const SignalQueue &) = delete;
44 SignalQueue(SignalQueue &&) = default;
45 SignalQueue& operator=(const SignalQueue &) = delete;
46 SignalQueue& operator=(SignalQueue &&) = default;
47 explicit SignalQueue(const std::string &match) :
48 _bus(sdbusplus::bus::new_default()),
49 _match(_bus, match.c_str(), &callback, this),
50 _next(nullptr)
51 {
52 }
53
54 auto &&pop(unsigned timeout=1000000)
55 {
56 while(timeout > 0 && !_next)
57 {
58 _bus.process_discard();
59 _bus.wait(50000);
60 timeout -= 50000;
61 }
62 return std::move(_next);
63 }
64
65 private:
66 static int callback(sd_bus_message *m, void *context, sd_bus_error *)
67 {
68 auto *me = static_cast<SignalQueue *>(context);
69 sd_bus_message_ref(m);
70 sdbusplus::message::message msg{m};
71 me->_next = std::move(msg);
72 return 0;
73 }
74
75 sdbusplus::bus::bus _bus;
76 sdbusplus::server::match::match _match;
77 sdbusplus::message::message _next;
78};
79
80template <typename ...T>
81using Object = std::map<
82 std::string,
83 std::map<
84 std::string,
85 sdbusplus::message::variant<T...>>>;
86
87using ObjectPath = std::string;
88
89/**@brief Find a subset of interfaces and properties in an object. */
90template <typename ...T>
91auto hasProperties(const Object<T...> &l, const Object<T...> &r)
92{
93 Object<T...> result;
94 std::set_difference(
95 r.cbegin(),
96 r.cend(),
97 l.cbegin(),
98 l.cend(),
99 std::inserter(result, result.end()));
100 return result.empty();
101}
102
Brad Bishop49aefb32016-10-19 11:54:14 -0400103void runTests(phosphor::inventory::manager::Manager &mgr)
104{
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500105 const std::string root{ROOT};
Brad Bishop49aefb32016-10-19 11:54:14 -0400106 auto b = sdbusplus::bus::new_default();
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500107 auto notify = [&]()
Brad Bishop49aefb32016-10-19 11:54:14 -0400108 {
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500109 return b.new_method_call(
110 SERVICE,
111 ROOT,
112 INTERFACE,
113 "Notify");
114 };
Brad Bishop49aefb32016-10-19 11:54:14 -0400115
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500116 Object<std::string> obj{
117 {
118 "xyz.openbmc_project.Example.Iface1",
119 {{"ExampleProperty1", "test1"}}
120 },
121 {
122 "xyz.openbmc_project.Example.Iface2",
123 {{"ExampleProperty2", "test2"}}
124 },
125 };
Brad Bishop49aefb32016-10-19 11:54:14 -0400126
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500127 // Make sure the notify method works.
128 {
129 ObjectPath relPath{"/foo"};
130 ObjectPath path{root + relPath};
Brad Bishop49aefb32016-10-19 11:54:14 -0400131
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500132 SignalQueue queue(
133 "path='" + root + "',member='InterfacesAdded'");
134
135 auto m = notify();
136 m.append(relPath);
137 m.append(obj);
138 b.call(m);
139
140 auto sig{queue.pop()};
141 assert(sig);
142 ObjectPath signalPath;
143 Object<std::string> signalObject;
144 sig.read(signalPath);
145 assert(path == signalPath);
146 sig.read(signalObject);
147 assert(hasProperties(signalObject, obj));
148 auto moreSignals{queue.pop()};
149 assert(!moreSignals);
Brad Bishop49aefb32016-10-19 11:54:14 -0400150 }
151
152 mgr.shutdown();
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500153 std::cout << "Success!" << std::endl;
Brad Bishop49aefb32016-10-19 11:54:14 -0400154}
155
156int main()
157{
158 auto mgr = phosphor::inventory::manager::Manager(
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500159 sdbusplus::bus::new_default(),
Brad Bishop49aefb32016-10-19 11:54:14 -0400160 SERVICE, ROOT, INTERFACE);
161
162 pthread_t t;
163 {
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500164 pthread_create(&t, nullptr, server_thread, &mgr);
Brad Bishop49aefb32016-10-19 11:54:14 -0400165 }
166
167 runTests(mgr);
168
169 // Wait for server thread to exit.
Brad Bishopabb2a1a2016-11-30 22:02:28 -0500170 pthread_join(t, nullptr);
Brad Bishop49aefb32016-10-19 11:54:14 -0400171
172 return 0;
173}
174
175// vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4