blob: 59898b3f02a49544ac70e8b9bdf6924aeade7be3 [file] [log] [blame]
Patrick Williams4fe85a32016-09-08 15:03:56 -05001#include <iostream>
2#include <cassert>
3#include <sdbusplus/message.hpp>
4#include <sdbusplus/bus.hpp>
5
6// Global to share the dbus type string between client and server.
7static std::string verifyTypeString;
8
9using verifyCallback_t = void(*)(sdbusplus::message::message&);
10verifyCallback_t verifyCallback = nullptr;
11
Patrick Williams24fb2962016-11-04 17:08:59 -050012static constexpr auto SERVICE = "sdbusplus.test.message.read";
Patrick Williams4fe85a32016-09-08 15:03:56 -050013static constexpr auto INTERFACE = SERVICE;
14static constexpr auto TEST_METHOD = "test";
15static constexpr auto QUIT_METHOD = "quit";
16
17// Open up the sdbus and claim SERVICE name.
18auto serverInit()
19{
20 auto b = sdbusplus::bus::new_default();
21 b.request_name(SERVICE);
22
23 return std::move(b);
24}
25
26// Thread to run the dbus server.
27void* server(void* b)
28{
29 auto bus = sdbusplus::bus::bus(reinterpret_cast<sdbusplus::bus::busp_t>(b));
30
31 while(1)
32 {
33 // Wait for messages.
34 auto m = bus.process();
35
36 if(!m)
37 {
38 bus.wait();
39 continue;
40 }
41
42 if (m.is_method_call(INTERFACE, TEST_METHOD))
43 {
44 // Verify the message type matches what the test expects.
45 assert(verifyTypeString == m.get_signature());
46
47 if (verifyCallback)
48 {
49
50 verifyCallback(m);
51 verifyCallback = nullptr;
52 }
53 else
54 {
55 std::cout << "Warning: No verification for "
56 << verifyTypeString << std::endl;
57 }
58 // Reply to client.
59 sd_bus_reply_method_return(m.release(), nullptr);
60 }
61 else if (m.is_method_call(INTERFACE, QUIT_METHOD))
62 {
63 // Reply and exit.
64 sd_bus_reply_method_return(m.release(), nullptr);
65 break;
66 }
67 }
Patrick Williams696e3152016-11-04 17:03:39 -050068
69 return nullptr;
Patrick Williams4fe85a32016-09-08 15:03:56 -050070}
71
72auto newMethodCall__test(sdbusplus::bus::bus& b)
73{
74 // Allocate a method-call message for INTERFACE,TEST_METHOD.
75 return b.new_method_call(SERVICE, "/", INTERFACE, TEST_METHOD);
76}
77
78void runTests()
79{
80 using namespace std::literals;
81
82 auto b = sdbusplus::bus::new_default();
83
84 // Test r-value int.
85 {
86 auto m = newMethodCall__test(b);
87 m.append(1);
88 verifyTypeString = "i";
89
90 struct verify
91 {
92 static void op(sdbusplus::message::message& m)
93 {
94 int32_t i = 0;
95 m.read(i);
96 assert(i == 1);
97 }
98 };
99 verifyCallback = &verify::op;
100
101 b.call_noreply(m);
102 }
103 // Test l-value int.
104 {
105 auto m = newMethodCall__test(b);
106 int a = 1;
107 m.append(a, a);
108 verifyTypeString = "ii";
109
110 struct verify
111 {
112 static void op(sdbusplus::message::message& m)
113 {
114 int32_t a = 0, b = 0;
115 m.read(a, b);
116 assert(a == 1);
117 assert(b == 1);
118 }
119 };
120 verifyCallback = &verify::op;
121
122 b.call_noreply(m);
123 }
124
125 // Test multiple ints.
126 {
127 auto m = newMethodCall__test(b);
128 m.append(1, 2, 3, 4, 5);
129 verifyTypeString = "iiiii";
130
131 struct verify
132 {
133 static void op(sdbusplus::message::message& m)
134 {
135 int32_t a = 0, b = 0, c = 0, d = 0, e = 0;
136 m.read(a,b,c,d,e);
137 assert(a == 1);
138 assert(b == 2);
139 assert(c == 3);
140 assert(d == 4);
141 assert(e == 5);
142 }
143 };
144 verifyCallback = &verify::op;
145
146 b.call_noreply(m);
147 }
148
Patrick Williams9e3b51e2016-10-18 07:47:29 -0500149 // Test double and bool.
150 {
151 auto m = newMethodCall__test(b);
152 bool t = true;
153 m.append(t, true, false, 1.1);
154 verifyTypeString = "bbbd";
155
156 struct verify
157 {
158 static void op(sdbusplus::message::message& m)
159 {
160 bool t1, t2, f1;
161 double d;
162 m.read(t1, t2, f1, d);
163 assert(t1);
164 assert(t2);
165 assert(!f1);
166 assert(d == 1.1);
167 }
168 };
169 verifyCallback = &verify::op;
170
171 b.call_noreply(m);
172 }
173
Patrick Williams4fe85a32016-09-08 15:03:56 -0500174 // Test r-value string.
175 {
176 auto m = newMethodCall__test(b);
177 m.append("asdf"s);
178 verifyTypeString = "s";
179
180 struct verify
181 {
182 static void op(sdbusplus::message::message& m)
183 {
184 const char* s = nullptr;
185 m.read(s);
186 assert(0 == strcmp("asdf", s));
187 }
188 };
189 verifyCallback = &verify::op;
190
191 b.call_noreply(m);
192 }
193
194 // Test multiple strings, various forms.
195 {
196 auto m = newMethodCall__test(b);
197 auto str = "jkl;"s;
198 auto str2 = "JKL:"s;
199 m.append(1, "asdf", "ASDF"s, str,
200 std::move(str2), 5);
201 verifyTypeString = "issssi";
202
203 struct verify
204 {
205 static void op(sdbusplus::message::message& m)
206 {
207 int32_t a = 0, b = 0;
208 std::string s0, s1, s2, s3;
209 m.read(a, s0, s1, s2, s3, b);
210 assert(a == 1);
211 assert(b == 5);
212 assert(s0 == "asdf"s);
213 assert(s1 == "ASDF"s);
214 assert(s2 == "jkl;"s);
215 assert(s3 == "JKL:");
216 }
217 };
218 verifyCallback = &verify::op;
219
220 b.call_noreply(m);
221 }
222
Patrick Williams930460c2016-07-20 17:52:55 -0500223 // Test vector.
224 {
225 auto m = newMethodCall__test(b);
226 std::vector<std::string> s{ "1", "2", "3"};
227 m.append(1, s, 2);
228 verifyTypeString = "iasi";
229
230 struct verify
231 {
232 static void op(sdbusplus::message::message& m)
233 {
234 int32_t a = 0;
235 std::vector<std::string> s;
236 m.read(a, s);
237 assert(a == 1);
238 assert(s[0] == "1");
239 assert(s[1] == "2");
240 assert(s[2] == "3");
241 decltype(s) s2 = { "1" , "2" , "3" };
242 assert(s == s2);
243 }
244 };
245 verifyCallback = &verify::op;
246
247 b.call_noreply(m);
248 }
249
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500250 // Test map.
251 {
252 auto m = newMethodCall__test(b);
253 std::map<std::string, int> s = { { "asdf", 3 }, { "jkl;", 4 } };
254 m.append(1, s, 2);
255 verifyTypeString = "ia{si}i";
256
257 struct verify
258 {
259 static void op(sdbusplus::message::message& m)
260 {
261 int32_t a = 0, b = 0;
262 std::map<std::string, int> s{};
263
264 m.read(a, s, b);
265 assert(a == 1);
266 assert(s.size() == 2);
267 assert(s["asdf"] == 3);
268 assert(s["jkl;"] == 4);
269 assert(b == 2);
270 }
271 };
272 verifyCallback = &verify::op;
273
274 b.call_noreply(m);
275 }
276
Patrick Williamsaa2f48a2016-09-10 14:23:34 -0500277 // Test tuple.
278 {
279 auto m = newMethodCall__test(b);
280 std::tuple<int, double, std::string> a{ 3, 4.1, "asdf" };
281 m.append(1, a, 2);
282 verifyTypeString = "i(ids)i";
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500283
Patrick Williamsaa2f48a2016-09-10 14:23:34 -0500284 struct verify
285 {
286 static void op(sdbusplus::message::message& m)
287 {
288 int32_t a = 0, b = 0;
289 std::tuple<int, double, std::string> c{};
290
291 m.read(a, c, b);
292 assert(a == 1);
293 assert(b == 2);
294 assert(c == std::make_tuple(3, 4.1, "asdf"s));
295 }
296 };
297 verifyCallback = &verify::op;
298
299 b.call_noreply(m);
300 }
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500301
Patrick Williams75596782016-09-11 21:14:10 -0500302 // Test variant.
303 {
304 auto m = newMethodCall__test(b);
305 sdbusplus::message::variant<int, double> a1{3.1}, a2{4};
306 m.append(1, a1, a2, 2);
307 verifyTypeString = "ivvi";
308
309 struct verify
310 {
311 static void op(sdbusplus::message::message& m)
312 {
313 int32_t a, b;
314 sdbusplus::message::variant<int, double> a1{}, a2{};
315
316 m.read(a, a1, a2, b);
317 assert(a == 1);
318 assert(a1 == 3.1);
319 assert(a2 == 4);
320 assert(b == 2);
321 }
322 };
323 verifyCallback = &verify::op;
324
325 b.call_noreply(m);
326 }
327
Patrick Williamsf101ee22016-11-04 17:44:04 -0500328 // Test variant with missing/wrong type.
329 {
330 auto m = newMethodCall__test(b);
331 sdbusplus::message::variant<uint64_t, double> a1{3.1}, a2{uint64_t(4)};
332 m.append(1, a1, a2, 2);
333 verifyTypeString = "ivvi";
334
335 struct verify
336 {
337 static void op(sdbusplus::message::message& m)
338 {
339 int32_t a, b;
340 sdbusplus::message::variant<uint8_t, double> a1{}, a2{};
341
342 m.read(a, a1, a2, b);
343 assert(a == 1);
344 assert(a1 == 3.1);
345 assert(a2 == uint8_t());
346 assert(b == 2);
347 }
348 };
349 verifyCallback = &verify::op;
350
351 b.call_noreply(m);
352 }
353
Patrick Williams75596782016-09-11 21:14:10 -0500354 // Test map-variant.
355 {
356 auto m = newMethodCall__test(b);
357 std::map<std::string, sdbusplus::message::variant<int, double>> a1 =
358 { { "asdf", 3 }, { "jkl;", 4.1 } };
359 m.append(1, a1, 2);
360 verifyTypeString = "ia{sv}i";
361
362 struct verify
363 {
364 static void op(sdbusplus::message::message& m)
365 {
366 int32_t a = 0, b = 0;
367 std::map<std::string,
368 sdbusplus::message::variant<int, double>> a1{};
369
370 m.read(a, a1, b);
371 assert(a == 1);
372 assert(a1["asdf"] == 3);
373 assert(a1["jkl;"] == 4.1);
374 assert(b == 2);
375 }
376 };
377 verifyCallback = &verify::op;
378
379 b.call_noreply(m);
380 }
381
382
Patrick Williams4fe85a32016-09-08 15:03:56 -0500383 // Shutdown server.
384 {
385 auto m = b.new_method_call(SERVICE, "/", INTERFACE, QUIT_METHOD);
386 b.call_noreply(m);
387 }
388}
389
390int main()
391{
392
393 // Initialize and start server thread.
394 pthread_t t;
395 {
396 auto b = serverInit();
397 pthread_create(&t, NULL, server, b.release());
398 }
399
400 runTests();
401
402 // Wait for server thread to exit.
403 pthread_join(t, NULL);
404
405 return 0;
406}