blob: 4eb6437225681fd2cd588863b9a623ae165dfbe8 [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>
Ed Tanous28dc36d2018-02-21 12:22:54 -08005#include <unordered_map>
6#include <set>
Patrick Williams4fe85a32016-09-08 15:03:56 -05007
8// Global to share the dbus type string between client and server.
9static std::string verifyTypeString;
10
Andrew Geissler072da3e2018-01-18 07:21:42 -080011using verifyCallback_t = void (*)(sdbusplus::message::message&);
Patrick Williams4fe85a32016-09-08 15:03:56 -050012verifyCallback_t verifyCallback = nullptr;
13
Patrick Williams24fb2962016-11-04 17:08:59 -050014static constexpr auto SERVICE = "sdbusplus.test.message.read";
Patrick Williams4fe85a32016-09-08 15:03:56 -050015static constexpr auto INTERFACE = SERVICE;
16static constexpr auto TEST_METHOD = "test";
17static constexpr auto QUIT_METHOD = "quit";
18
19// Open up the sdbus and claim SERVICE name.
20auto serverInit()
21{
22 auto b = sdbusplus::bus::new_default();
23 b.request_name(SERVICE);
24
25 return std::move(b);
26}
27
28// Thread to run the dbus server.
29void* server(void* b)
30{
William A. Kennington IIIb5645502018-06-19 18:36:41 -070031 auto bus = sdbusplus::bus::bus(reinterpret_cast<sdbusplus::bus::busp_t>(b),
32 std::false_type());
Patrick Williams4fe85a32016-09-08 15:03:56 -050033
Andrew Geissler072da3e2018-01-18 07:21:42 -080034 while (1)
Patrick Williams4fe85a32016-09-08 15:03:56 -050035 {
36 // Wait for messages.
37 auto m = bus.process();
38
Andrew Geissler072da3e2018-01-18 07:21:42 -080039 if (!m)
Patrick Williams4fe85a32016-09-08 15:03:56 -050040 {
41 bus.wait();
42 continue;
43 }
44
45 if (m.is_method_call(INTERFACE, TEST_METHOD))
46 {
47 // Verify the message type matches what the test expects.
48 assert(verifyTypeString == m.get_signature());
49
50 if (verifyCallback)
51 {
52
53 verifyCallback(m);
54 verifyCallback = nullptr;
55 }
56 else
57 {
Andrew Geissler072da3e2018-01-18 07:21:42 -080058 std::cout << "Warning: No verification for " << verifyTypeString
59 << std::endl;
Patrick Williams4fe85a32016-09-08 15:03:56 -050060 }
61 // Reply to client.
William A. Kennington IIIb5645502018-06-19 18:36:41 -070062 auto sd_m = m.release();
63 sd_bus_reply_method_return(sd_m, nullptr);
64 sd_bus_message_unref(sd_m);
Patrick Williams4fe85a32016-09-08 15:03:56 -050065 }
66 else if (m.is_method_call(INTERFACE, QUIT_METHOD))
67 {
68 // Reply and exit.
William A. Kennington IIIb5645502018-06-19 18:36:41 -070069 auto sd_m = m.release();
70 sd_bus_reply_method_return(sd_m, nullptr);
71 sd_bus_message_unref(sd_m);
Patrick Williams4fe85a32016-09-08 15:03:56 -050072 break;
73 }
74 }
Patrick Williams696e3152016-11-04 17:03:39 -050075
76 return nullptr;
Patrick Williams4fe85a32016-09-08 15:03:56 -050077}
78
79auto newMethodCall__test(sdbusplus::bus::bus& b)
80{
81 // Allocate a method-call message for INTERFACE,TEST_METHOD.
82 return b.new_method_call(SERVICE, "/", INTERFACE, TEST_METHOD);
83}
84
85void runTests()
86{
87 using namespace std::literals;
88
89 auto b = sdbusplus::bus::new_default();
90
91 // Test r-value int.
92 {
93 auto m = newMethodCall__test(b);
94 m.append(1);
95 verifyTypeString = "i";
96
97 struct verify
98 {
99 static void op(sdbusplus::message::message& m)
100 {
101 int32_t i = 0;
102 m.read(i);
103 assert(i == 1);
104 }
105 };
106 verifyCallback = &verify::op;
107
108 b.call_noreply(m);
109 }
110 // Test l-value int.
111 {
112 auto m = newMethodCall__test(b);
113 int a = 1;
114 m.append(a, a);
115 verifyTypeString = "ii";
116
117 struct verify
118 {
119 static void op(sdbusplus::message::message& m)
120 {
121 int32_t a = 0, b = 0;
122 m.read(a, b);
123 assert(a == 1);
124 assert(b == 1);
125 }
126 };
127 verifyCallback = &verify::op;
128
129 b.call_noreply(m);
130 }
131
132 // Test multiple ints.
133 {
134 auto m = newMethodCall__test(b);
135 m.append(1, 2, 3, 4, 5);
136 verifyTypeString = "iiiii";
137
138 struct verify
139 {
140 static void op(sdbusplus::message::message& m)
141 {
142 int32_t a = 0, b = 0, c = 0, d = 0, e = 0;
Andrew Geissler072da3e2018-01-18 07:21:42 -0800143 m.read(a, b, c, d, e);
Patrick Williams4fe85a32016-09-08 15:03:56 -0500144 assert(a == 1);
145 assert(b == 2);
146 assert(c == 3);
147 assert(d == 4);
148 assert(e == 5);
149 }
150 };
151 verifyCallback = &verify::op;
152
153 b.call_noreply(m);
154 }
155
Patrick Williams9e3b51e2016-10-18 07:47:29 -0500156 // Test double and bool.
157 {
158 auto m = newMethodCall__test(b);
159 bool t = true;
Patrick Williamsb760a992016-11-28 11:26:55 -0600160 bool f = false;
161 bool f2 = false;
162 m.append(t, true, f, std::move(f2), false, 1.1);
163 verifyTypeString = "bbbbbd";
Patrick Williams9e3b51e2016-10-18 07:47:29 -0500164
165 struct verify
166 {
167 static void op(sdbusplus::message::message& m)
168 {
Patrick Williamsb760a992016-11-28 11:26:55 -0600169 bool t1, t2, f1, f2, f3;
Patrick Williams9e3b51e2016-10-18 07:47:29 -0500170 double d;
Patrick Williamsb760a992016-11-28 11:26:55 -0600171 m.read(t1, t2, f1, f2, f3, d);
Patrick Williams9e3b51e2016-10-18 07:47:29 -0500172 assert(t1);
173 assert(t2);
174 assert(!f1);
Patrick Williamsb760a992016-11-28 11:26:55 -0600175 assert(!f2);
176 assert(!f3);
Patrick Williams9e3b51e2016-10-18 07:47:29 -0500177 assert(d == 1.1);
178 }
179 };
180 verifyCallback = &verify::op;
181
182 b.call_noreply(m);
183 }
184
Patrick Williams4fe85a32016-09-08 15:03:56 -0500185 // Test r-value string.
186 {
187 auto m = newMethodCall__test(b);
188 m.append("asdf"s);
189 verifyTypeString = "s";
190
191 struct verify
192 {
193 static void op(sdbusplus::message::message& m)
194 {
195 const char* s = nullptr;
196 m.read(s);
197 assert(0 == strcmp("asdf", s));
198 }
199 };
200 verifyCallback = &verify::op;
201
202 b.call_noreply(m);
203 }
204
205 // Test multiple strings, various forms.
206 {
207 auto m = newMethodCall__test(b);
208 auto str = "jkl;"s;
209 auto str2 = "JKL:"s;
Andrew Geissler072da3e2018-01-18 07:21:42 -0800210 m.append(1, "asdf", "ASDF"s, str, std::move(str2), 5);
Patrick Williams4fe85a32016-09-08 15:03:56 -0500211 verifyTypeString = "issssi";
212
213 struct verify
214 {
215 static void op(sdbusplus::message::message& m)
216 {
217 int32_t a = 0, b = 0;
218 std::string s0, s1, s2, s3;
219 m.read(a, s0, s1, s2, s3, b);
220 assert(a == 1);
221 assert(b == 5);
222 assert(s0 == "asdf"s);
223 assert(s1 == "ASDF"s);
224 assert(s2 == "jkl;"s);
225 assert(s3 == "JKL:");
226 }
227 };
228 verifyCallback = &verify::op;
229
230 b.call_noreply(m);
231 }
232
Patrick Williams572a8ea2017-01-06 16:23:14 -0600233 // Test object_path and signature.
234 {
235 auto m = newMethodCall__test(b);
236 auto o = sdbusplus::message::object_path("/asdf");
237 auto s = sdbusplus::message::signature("iii");
238 m.append(1, o, s, 4);
239 verifyTypeString = "iogi";
240
241 struct verify
242 {
243 static void op(sdbusplus::message::message& m)
244 {
245 int32_t a = 0, b = 0;
246 sdbusplus::message::object_path o;
247 sdbusplus::message::signature s;
248 m.read(a, o, s, b);
249 assert(a == 1);
250 assert(b == 4);
251 assert(std::string(o) == "/asdf"s);
252 assert(std::string(s) == "iii"s);
253 }
254 };
255 verifyCallback = &verify::op;
256
257 b.call_noreply(m);
258 }
259
Patrick Williams930460c2016-07-20 17:52:55 -0500260 // Test vector.
261 {
262 auto m = newMethodCall__test(b);
Andrew Geissler072da3e2018-01-18 07:21:42 -0800263 std::vector<std::string> s{"1", "2", "3"};
Patrick Williams930460c2016-07-20 17:52:55 -0500264 m.append(1, s, 2);
265 verifyTypeString = "iasi";
266
267 struct verify
268 {
269 static void op(sdbusplus::message::message& m)
270 {
271 int32_t a = 0;
272 std::vector<std::string> s;
273 m.read(a, s);
274 assert(a == 1);
275 assert(s[0] == "1");
276 assert(s[1] == "2");
277 assert(s[2] == "3");
Andrew Geissler072da3e2018-01-18 07:21:42 -0800278 decltype(s) s2 = {"1", "2", "3"};
Patrick Williams930460c2016-07-20 17:52:55 -0500279 assert(s == s2);
280 }
281 };
282 verifyCallback = &verify::op;
283
284 b.call_noreply(m);
285 }
286
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500287 // Test map.
288 {
289 auto m = newMethodCall__test(b);
Andrew Geissler072da3e2018-01-18 07:21:42 -0800290 std::map<std::string, int> s = {{"asdf", 3}, {"jkl;", 4}};
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500291 m.append(1, s, 2);
292 verifyTypeString = "ia{si}i";
293
294 struct verify
295 {
296 static void op(sdbusplus::message::message& m)
297 {
298 int32_t a = 0, b = 0;
299 std::map<std::string, int> s{};
300
301 m.read(a, s, b);
302 assert(a == 1);
303 assert(s.size() == 2);
304 assert(s["asdf"] == 3);
305 assert(s["jkl;"] == 4);
306 assert(b == 2);
307 }
308 };
309 verifyCallback = &verify::op;
310
311 b.call_noreply(m);
312 }
313
Ed Tanous28dc36d2018-02-21 12:22:54 -0800314 // Test unordered_map.
315 {
316 auto m = newMethodCall__test(b);
317 std::unordered_map<std::string, int> s = {{"asdf", 3}, {"jkl;", 4}};
318 m.append(1, s, 2);
319 verifyTypeString = "ia{si}i";
320
321 struct verify
322 {
323 static void op(sdbusplus::message::message& m)
324 {
325 int32_t a = 0, b = 0;
326 std::unordered_map<std::string, int> s{};
327
328 m.read(a, s, b);
329 assert(a == 1);
330 assert(s.size() == 2);
331 assert(s["asdf"] == 3);
332 assert(s["jkl;"] == 4);
333 assert(b == 2);
334 }
335 };
336 verifyCallback = &verify::op;
337
338 b.call_noreply(m);
339 }
340
341 // Test set.
342 {
343 auto m = newMethodCall__test(b);
344 std::set<std::string> s = {{"asdf"}, {"jkl;"}};
345 m.append(1, s, 2);
346 verifyTypeString = "iasi";
347
348 struct verify
349 {
350 static void op(sdbusplus::message::message& m)
351 {
352 int32_t a = 0, b = 0;
353 std::set<std::string> s{};
354
355 m.read(a, s, b);
356 assert(a == 1);
357 assert(s.size() == 2);
358 assert(s.find("asdf") != s.end());
359 assert(s.find("jkl;") != s.end());
360 assert(b == 2);
361 }
362 };
363 verifyCallback = &verify::op;
364
365 b.call_noreply(m);
366 }
367
Patrick Williamsaa2f48a2016-09-10 14:23:34 -0500368 // Test tuple.
369 {
370 auto m = newMethodCall__test(b);
Andrew Geissler072da3e2018-01-18 07:21:42 -0800371 std::tuple<int, double, std::string> a{3, 4.1, "asdf"};
Patrick Williamsaa2f48a2016-09-10 14:23:34 -0500372 m.append(1, a, 2);
373 verifyTypeString = "i(ids)i";
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500374
Patrick Williamsaa2f48a2016-09-10 14:23:34 -0500375 struct verify
376 {
377 static void op(sdbusplus::message::message& m)
378 {
379 int32_t a = 0, b = 0;
380 std::tuple<int, double, std::string> c{};
381
382 m.read(a, c, b);
383 assert(a == 1);
384 assert(b == 2);
385 assert(c == std::make_tuple(3, 4.1, "asdf"s));
386 }
387 };
388 verifyCallback = &verify::op;
389
390 b.call_noreply(m);
391 }
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500392
Patrick Williams75596782016-09-11 21:14:10 -0500393 // Test variant.
394 {
395 auto m = newMethodCall__test(b);
396 sdbusplus::message::variant<int, double> a1{3.1}, a2{4};
397 m.append(1, a1, a2, 2);
398 verifyTypeString = "ivvi";
399
400 struct verify
401 {
402 static void op(sdbusplus::message::message& m)
403 {
404 int32_t a, b;
405 sdbusplus::message::variant<int, double> a1{}, a2{};
406
407 m.read(a, a1, a2, b);
408 assert(a == 1);
409 assert(a1 == 3.1);
410 assert(a2 == 4);
411 assert(b == 2);
412 }
413 };
414 verifyCallback = &verify::op;
415
416 b.call_noreply(m);
417 }
418
Patrick Williamsf101ee22016-11-04 17:44:04 -0500419 // Test variant with missing/wrong type.
420 {
421 auto m = newMethodCall__test(b);
422 sdbusplus::message::variant<uint64_t, double> a1{3.1}, a2{uint64_t(4)};
423 m.append(1, a1, a2, 2);
424 verifyTypeString = "ivvi";
425
426 struct verify
427 {
428 static void op(sdbusplus::message::message& m)
429 {
430 int32_t a, b;
431 sdbusplus::message::variant<uint8_t, double> a1{}, a2{};
432
433 m.read(a, a1, a2, b);
434 assert(a == 1);
435 assert(a1 == 3.1);
436 assert(a2 == uint8_t());
437 assert(b == 2);
438 }
439 };
440 verifyCallback = &verify::op;
441
442 b.call_noreply(m);
443 }
444
Patrick Williams75596782016-09-11 21:14:10 -0500445 // Test map-variant.
446 {
447 auto m = newMethodCall__test(b);
Andrew Geissler072da3e2018-01-18 07:21:42 -0800448 std::map<std::string, sdbusplus::message::variant<int, double>> a1 = {
449 {"asdf", 3}, {"jkl;", 4.1}};
Patrick Williams75596782016-09-11 21:14:10 -0500450 m.append(1, a1, 2);
451 verifyTypeString = "ia{sv}i";
452
453 struct verify
454 {
455 static void op(sdbusplus::message::message& m)
456 {
457 int32_t a = 0, b = 0;
Andrew Geissler072da3e2018-01-18 07:21:42 -0800458 std::map<std::string, sdbusplus::message::variant<int, double>>
459 a1{};
Patrick Williams75596782016-09-11 21:14:10 -0500460
461 m.read(a, a1, b);
462 assert(a == 1);
463 assert(a1["asdf"] == 3);
464 assert(a1["jkl;"] == 4.1);
465 assert(b == 2);
466 }
467 };
468 verifyCallback = &verify::op;
469
470 b.call_noreply(m);
471 }
472
Patrick Williams4fe85a32016-09-08 15:03:56 -0500473 // Shutdown server.
474 {
475 auto m = b.new_method_call(SERVICE, "/", INTERFACE, QUIT_METHOD);
476 b.call_noreply(m);
477 }
478}
479
480int main()
481{
482
483 // Initialize and start server thread.
484 pthread_t t;
485 {
486 auto b = serverInit();
487 pthread_create(&t, NULL, server, b.release());
488 }
489
490 runTests();
491
492 // Wait for server thread to exit.
493 pthread_join(t, NULL);
494
495 return 0;
496}