blob: 8c2c4eabbd4736d4794d40f1e2a173c06d641953 [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
Andrew Geissler072da3e2018-01-18 07:21:42 -08009using verifyCallback_t = void (*)(sdbusplus::message::message&);
Patrick Williams4fe85a32016-09-08 15:03:56 -050010verifyCallback_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
Andrew Geissler072da3e2018-01-18 07:21:42 -080031 while (1)
Patrick Williams4fe85a32016-09-08 15:03:56 -050032 {
33 // Wait for messages.
34 auto m = bus.process();
35
Andrew Geissler072da3e2018-01-18 07:21:42 -080036 if (!m)
Patrick Williams4fe85a32016-09-08 15:03:56 -050037 {
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 {
Andrew Geissler072da3e2018-01-18 07:21:42 -080055 std::cout << "Warning: No verification for " << verifyTypeString
56 << std::endl;
Patrick Williams4fe85a32016-09-08 15:03:56 -050057 }
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;
Andrew Geissler072da3e2018-01-18 07:21:42 -0800136 m.read(a, b, c, d, e);
Patrick Williams4fe85a32016-09-08 15:03:56 -0500137 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;
Patrick Williamsb760a992016-11-28 11:26:55 -0600153 bool f = false;
154 bool f2 = false;
155 m.append(t, true, f, std::move(f2), false, 1.1);
156 verifyTypeString = "bbbbbd";
Patrick Williams9e3b51e2016-10-18 07:47:29 -0500157
158 struct verify
159 {
160 static void op(sdbusplus::message::message& m)
161 {
Patrick Williamsb760a992016-11-28 11:26:55 -0600162 bool t1, t2, f1, f2, f3;
Patrick Williams9e3b51e2016-10-18 07:47:29 -0500163 double d;
Patrick Williamsb760a992016-11-28 11:26:55 -0600164 m.read(t1, t2, f1, f2, f3, d);
Patrick Williams9e3b51e2016-10-18 07:47:29 -0500165 assert(t1);
166 assert(t2);
167 assert(!f1);
Patrick Williamsb760a992016-11-28 11:26:55 -0600168 assert(!f2);
169 assert(!f3);
Patrick Williams9e3b51e2016-10-18 07:47:29 -0500170 assert(d == 1.1);
171 }
172 };
173 verifyCallback = &verify::op;
174
175 b.call_noreply(m);
176 }
177
Patrick Williams4fe85a32016-09-08 15:03:56 -0500178 // Test r-value string.
179 {
180 auto m = newMethodCall__test(b);
181 m.append("asdf"s);
182 verifyTypeString = "s";
183
184 struct verify
185 {
186 static void op(sdbusplus::message::message& m)
187 {
188 const char* s = nullptr;
189 m.read(s);
190 assert(0 == strcmp("asdf", s));
191 }
192 };
193 verifyCallback = &verify::op;
194
195 b.call_noreply(m);
196 }
197
198 // Test multiple strings, various forms.
199 {
200 auto m = newMethodCall__test(b);
201 auto str = "jkl;"s;
202 auto str2 = "JKL:"s;
Andrew Geissler072da3e2018-01-18 07:21:42 -0800203 m.append(1, "asdf", "ASDF"s, str, std::move(str2), 5);
Patrick Williams4fe85a32016-09-08 15:03:56 -0500204 verifyTypeString = "issssi";
205
206 struct verify
207 {
208 static void op(sdbusplus::message::message& m)
209 {
210 int32_t a = 0, b = 0;
211 std::string s0, s1, s2, s3;
212 m.read(a, s0, s1, s2, s3, b);
213 assert(a == 1);
214 assert(b == 5);
215 assert(s0 == "asdf"s);
216 assert(s1 == "ASDF"s);
217 assert(s2 == "jkl;"s);
218 assert(s3 == "JKL:");
219 }
220 };
221 verifyCallback = &verify::op;
222
223 b.call_noreply(m);
224 }
225
Patrick Williams572a8ea2017-01-06 16:23:14 -0600226 // Test object_path and signature.
227 {
228 auto m = newMethodCall__test(b);
229 auto o = sdbusplus::message::object_path("/asdf");
230 auto s = sdbusplus::message::signature("iii");
231 m.append(1, o, s, 4);
232 verifyTypeString = "iogi";
233
234 struct verify
235 {
236 static void op(sdbusplus::message::message& m)
237 {
238 int32_t a = 0, b = 0;
239 sdbusplus::message::object_path o;
240 sdbusplus::message::signature s;
241 m.read(a, o, s, b);
242 assert(a == 1);
243 assert(b == 4);
244 assert(std::string(o) == "/asdf"s);
245 assert(std::string(s) == "iii"s);
246 }
247 };
248 verifyCallback = &verify::op;
249
250 b.call_noreply(m);
251 }
252
Patrick Williams930460c2016-07-20 17:52:55 -0500253 // Test vector.
254 {
255 auto m = newMethodCall__test(b);
Andrew Geissler072da3e2018-01-18 07:21:42 -0800256 std::vector<std::string> s{"1", "2", "3"};
Patrick Williams930460c2016-07-20 17:52:55 -0500257 m.append(1, s, 2);
258 verifyTypeString = "iasi";
259
260 struct verify
261 {
262 static void op(sdbusplus::message::message& m)
263 {
264 int32_t a = 0;
265 std::vector<std::string> s;
266 m.read(a, s);
267 assert(a == 1);
268 assert(s[0] == "1");
269 assert(s[1] == "2");
270 assert(s[2] == "3");
Andrew Geissler072da3e2018-01-18 07:21:42 -0800271 decltype(s) s2 = {"1", "2", "3"};
Patrick Williams930460c2016-07-20 17:52:55 -0500272 assert(s == s2);
273 }
274 };
275 verifyCallback = &verify::op;
276
277 b.call_noreply(m);
278 }
279
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500280 // Test map.
281 {
282 auto m = newMethodCall__test(b);
Andrew Geissler072da3e2018-01-18 07:21:42 -0800283 std::map<std::string, int> s = {{"asdf", 3}, {"jkl;", 4}};
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500284 m.append(1, s, 2);
285 verifyTypeString = "ia{si}i";
286
287 struct verify
288 {
289 static void op(sdbusplus::message::message& m)
290 {
291 int32_t a = 0, b = 0;
292 std::map<std::string, int> s{};
293
294 m.read(a, s, b);
295 assert(a == 1);
296 assert(s.size() == 2);
297 assert(s["asdf"] == 3);
298 assert(s["jkl;"] == 4);
299 assert(b == 2);
300 }
301 };
302 verifyCallback = &verify::op;
303
304 b.call_noreply(m);
305 }
306
Patrick Williamsaa2f48a2016-09-10 14:23:34 -0500307 // Test tuple.
308 {
309 auto m = newMethodCall__test(b);
Andrew Geissler072da3e2018-01-18 07:21:42 -0800310 std::tuple<int, double, std::string> a{3, 4.1, "asdf"};
Patrick Williamsaa2f48a2016-09-10 14:23:34 -0500311 m.append(1, a, 2);
312 verifyTypeString = "i(ids)i";
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500313
Patrick Williamsaa2f48a2016-09-10 14:23:34 -0500314 struct verify
315 {
316 static void op(sdbusplus::message::message& m)
317 {
318 int32_t a = 0, b = 0;
319 std::tuple<int, double, std::string> c{};
320
321 m.read(a, c, b);
322 assert(a == 1);
323 assert(b == 2);
324 assert(c == std::make_tuple(3, 4.1, "asdf"s));
325 }
326 };
327 verifyCallback = &verify::op;
328
329 b.call_noreply(m);
330 }
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500331
Patrick Williams75596782016-09-11 21:14:10 -0500332 // Test variant.
333 {
334 auto m = newMethodCall__test(b);
335 sdbusplus::message::variant<int, double> a1{3.1}, a2{4};
336 m.append(1, a1, a2, 2);
337 verifyTypeString = "ivvi";
338
339 struct verify
340 {
341 static void op(sdbusplus::message::message& m)
342 {
343 int32_t a, b;
344 sdbusplus::message::variant<int, double> a1{}, a2{};
345
346 m.read(a, a1, a2, b);
347 assert(a == 1);
348 assert(a1 == 3.1);
349 assert(a2 == 4);
350 assert(b == 2);
351 }
352 };
353 verifyCallback = &verify::op;
354
355 b.call_noreply(m);
356 }
357
Patrick Williamsf101ee22016-11-04 17:44:04 -0500358 // Test variant with missing/wrong type.
359 {
360 auto m = newMethodCall__test(b);
361 sdbusplus::message::variant<uint64_t, double> a1{3.1}, a2{uint64_t(4)};
362 m.append(1, a1, a2, 2);
363 verifyTypeString = "ivvi";
364
365 struct verify
366 {
367 static void op(sdbusplus::message::message& m)
368 {
369 int32_t a, b;
370 sdbusplus::message::variant<uint8_t, double> a1{}, a2{};
371
372 m.read(a, a1, a2, b);
373 assert(a == 1);
374 assert(a1 == 3.1);
375 assert(a2 == uint8_t());
376 assert(b == 2);
377 }
378 };
379 verifyCallback = &verify::op;
380
381 b.call_noreply(m);
382 }
383
Patrick Williams75596782016-09-11 21:14:10 -0500384 // Test map-variant.
385 {
386 auto m = newMethodCall__test(b);
Andrew Geissler072da3e2018-01-18 07:21:42 -0800387 std::map<std::string, sdbusplus::message::variant<int, double>> a1 = {
388 {"asdf", 3}, {"jkl;", 4.1}};
Patrick Williams75596782016-09-11 21:14:10 -0500389 m.append(1, a1, 2);
390 verifyTypeString = "ia{sv}i";
391
392 struct verify
393 {
394 static void op(sdbusplus::message::message& m)
395 {
396 int32_t a = 0, b = 0;
Andrew Geissler072da3e2018-01-18 07:21:42 -0800397 std::map<std::string, sdbusplus::message::variant<int, double>>
398 a1{};
Patrick Williams75596782016-09-11 21:14:10 -0500399
400 m.read(a, a1, b);
401 assert(a == 1);
402 assert(a1["asdf"] == 3);
403 assert(a1["jkl;"] == 4.1);
404 assert(b == 2);
405 }
406 };
407 verifyCallback = &verify::op;
408
409 b.call_noreply(m);
410 }
411
Patrick Williams4fe85a32016-09-08 15:03:56 -0500412 // Shutdown server.
413 {
414 auto m = b.new_method_call(SERVICE, "/", INTERFACE, QUIT_METHOD);
415 b.call_noreply(m);
416 }
417}
418
419int main()
420{
421
422 // Initialize and start server thread.
423 pthread_t t;
424 {
425 auto b = serverInit();
426 pthread_create(&t, NULL, server, b.release());
427 }
428
429 runTests();
430
431 // Wait for server thread to exit.
432 pthread_join(t, NULL);
433
434 return 0;
435}