blob: 84dcc28e8ea09d536103b6fe4d47ef155b5eb9c5 [file] [log] [blame]
Patrick Williams1807fa42016-08-01 22:23:30 -05001#include <iostream>
Patrick Williams1807fa42016-08-01 22:23:30 -05002#include <cassert>
Patrick Williams7802c072016-09-02 15:20:22 -05003#include <sdbusplus/message.hpp>
Patrick Williams5b485792016-08-02 07:35:14 -05004#include <sdbusplus/bus.hpp>
Patrick Williams1807fa42016-08-01 22:23:30 -05005
6// Global to share the dbus type string between client and server.
7static std::string verifyTypeString;
8
Patrick Williams07e1d6f2016-09-08 15:54:09 -05009using verifyCallback_t = void(*)(sd_bus_message*);
10verifyCallback_t verifyCallback = nullptr;
11
Patrick Williams1807fa42016-08-01 22:23:30 -050012static constexpr auto SERVICE = "sdbusplus.test";
13static 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.
Patrick Williams5b485792016-08-02 07:35:14 -050018auto serverInit()
Patrick Williams1807fa42016-08-01 22:23:30 -050019{
Patrick Williams5b485792016-08-02 07:35:14 -050020 auto b = sdbusplus::bus::new_default();
21 b.request_name(SERVICE);
22
23 return std::move(b);
Patrick Williams1807fa42016-08-01 22:23:30 -050024}
25
26// Thread to run the dbus server.
27void* server(void* b)
28{
Patrick Williams5b485792016-08-02 07:35:14 -050029 auto bus = sdbusplus::bus::bus(reinterpret_cast<sdbusplus::bus::busp_t>(b));
Patrick Williams1807fa42016-08-01 22:23:30 -050030
31 while(1)
32 {
33 // Wait for messages.
Patrick Williams13b97c52016-09-09 09:36:55 -050034 auto m = bus.process().release();
Patrick Williams1807fa42016-08-01 22:23:30 -050035
Patrick Williams5b485792016-08-02 07:35:14 -050036 if(m == nullptr)
Patrick Williams1807fa42016-08-01 22:23:30 -050037 {
Patrick Williams5b485792016-08-02 07:35:14 -050038 bus.wait();
Patrick Williams1807fa42016-08-01 22:23:30 -050039 continue;
40 }
41
42 if (sd_bus_message_is_method_call(m, INTERFACE, TEST_METHOD))
43 {
44 // Verify the message type matches what the test expects.
Patrick Williams1807fa42016-08-01 22:23:30 -050045 assert(verifyTypeString == sd_bus_message_get_signature(m, true));
Patrick Williams07e1d6f2016-09-08 15:54:09 -050046 if (verifyCallback)
47 {
48 verifyCallback(m);
49 verifyCallback = nullptr;
50 }
51 else
52 {
53 std::cout << "Warning: No verification for "
54 << verifyTypeString << std::endl;
55 }
Patrick Williams1807fa42016-08-01 22:23:30 -050056 // Reply to client.
57 sd_bus_reply_method_return(m, nullptr);
58 }
59 else if (sd_bus_message_is_method_call(m, INTERFACE, QUIT_METHOD))
60 {
61 // Reply and exit.
62 sd_bus_reply_method_return(m, nullptr);
63 break;
64 }
65 }
66}
67
Patrick Williams7802c072016-09-02 15:20:22 -050068auto newMethodCall__test(sdbusplus::bus::bus& b)
Patrick Williams1807fa42016-08-01 22:23:30 -050069{
70 // Allocate a method-call message for INTERFACE,TEST_METHOD.
Patrick Williams7802c072016-09-02 15:20:22 -050071 return b.new_method_call(SERVICE, "/", INTERFACE, TEST_METHOD);
Patrick Williams1807fa42016-08-01 22:23:30 -050072}
73
74void runTests()
75{
76 using namespace std::literals;
77
Patrick Williams5b485792016-08-02 07:35:14 -050078 auto b = sdbusplus::bus::new_default();
Patrick Williams1807fa42016-08-01 22:23:30 -050079
80 // Test r-value int.
81 {
Patrick Williams7802c072016-09-02 15:20:22 -050082 auto m = newMethodCall__test(b);
83 m.append(1);
Patrick Williams1807fa42016-08-01 22:23:30 -050084 verifyTypeString = "i";
Patrick Williams07e1d6f2016-09-08 15:54:09 -050085
86 struct verify
87 {
88 static void op(sd_bus_message* m)
89 {
90 int32_t i = 0;
91 sd_bus_message_read_basic(m, 'i', &i);
92 assert(i == 1);
93 }
94 };
95 verifyCallback = &verify::op;
96
Patrick Williams5b485792016-08-02 07:35:14 -050097 b.call_noreply(m);
Patrick Williams1807fa42016-08-01 22:23:30 -050098 }
Patrick Williams1807fa42016-08-01 22:23:30 -050099 // Test l-value int.
100 {
Patrick Williams7802c072016-09-02 15:20:22 -0500101 auto m = newMethodCall__test(b);
Patrick Williams1807fa42016-08-01 22:23:30 -0500102 int a = 1;
Patrick Williams7802c072016-09-02 15:20:22 -0500103 m.append(a, a);
Patrick Williams1807fa42016-08-01 22:23:30 -0500104 verifyTypeString = "ii";
Patrick Williams07e1d6f2016-09-08 15:54:09 -0500105
106 struct verify
107 {
108 static void op(sd_bus_message* m)
109 {
110 int32_t a = 0, b = 0;
111 sd_bus_message_read(m, "ii", &a, &b);
112 assert(a == 1);
113 assert(b == 1);
114 }
115 };
116 verifyCallback = &verify::op;
117
Patrick Williams5b485792016-08-02 07:35:14 -0500118 b.call_noreply(m);
Patrick Williams1807fa42016-08-01 22:23:30 -0500119 }
120
121 // Test multiple ints.
122 {
Patrick Williams7802c072016-09-02 15:20:22 -0500123 auto m = newMethodCall__test(b);
124 m.append(1, 2, 3, 4, 5);
Patrick Williams1807fa42016-08-01 22:23:30 -0500125 verifyTypeString = "iiiii";
Patrick Williams07e1d6f2016-09-08 15:54:09 -0500126
127 struct verify
128 {
129 static void op(sd_bus_message* m)
130 {
131 int32_t a = 0, b = 0, c = 0, d = 0, e = 0;
132 sd_bus_message_read(m, "iiiii", &a, &b, &c, &d, &e);
133 assert(a == 1);
134 assert(b == 2);
135 assert(c == 3);
136 assert(d == 4);
137 assert(e == 5);
138 }
139 };
140 verifyCallback = &verify::op;
141
Patrick Williams5b485792016-08-02 07:35:14 -0500142 b.call_noreply(m);
Patrick Williams1807fa42016-08-01 22:23:30 -0500143 }
144
Patrick Williams9e3b51e2016-10-18 07:47:29 -0500145 // Test double and bool.
146 {
147 auto m = newMethodCall__test(b);
148 bool t = true;
149 m.append(t, true, false, 1.1);
150 verifyTypeString = "bbbd";
151
152 struct verify
153 {
154 static void op(sd_bus_message* m)
155 {
156 bool t1, t2, f1;
157 double d;
158 sd_bus_message_read(m, "bbbd", &t1, &t2, &f1, &d);
159 assert(t1);
160 assert(t2);
161 assert(!f1);
162 assert(d == 1.1);
163 }
164 };
165 verifyCallback = &verify::op;
166
167 b.call_noreply(m);
168 }
169
Patrick Williams1807fa42016-08-01 22:23:30 -0500170 // Test r-value string.
171 {
Patrick Williams7802c072016-09-02 15:20:22 -0500172 auto m = newMethodCall__test(b);
173 m.append("asdf"s);
Patrick Williams1807fa42016-08-01 22:23:30 -0500174 verifyTypeString = "s";
Patrick Williams07e1d6f2016-09-08 15:54:09 -0500175
176 struct verify
177 {
178 static void op(sd_bus_message* m)
179 {
180 const char* s = nullptr;
181 sd_bus_message_read_basic(m, 's', &s);
182 assert(0 == strcmp("asdf", s));
183 }
184 };
185 verifyCallback = &verify::op;
186
Patrick Williams5b485792016-08-02 07:35:14 -0500187 b.call_noreply(m);
Patrick Williams1807fa42016-08-01 22:23:30 -0500188 }
189
190 // Test multiple strings, various forms.
191 {
Patrick Williams7802c072016-09-02 15:20:22 -0500192 auto m = newMethodCall__test(b);
Patrick Williams1807fa42016-08-01 22:23:30 -0500193 auto str = "jkl;"s;
194 auto str2 = "JKL:"s;
Patrick Williams7802c072016-09-02 15:20:22 -0500195 m.append(1, "asdf", "ASDF"s, str,
196 std::move(str2), 5);
Patrick Williams1807fa42016-08-01 22:23:30 -0500197 verifyTypeString = "issssi";
Patrick Williams07e1d6f2016-09-08 15:54:09 -0500198
199 struct verify
200 {
201 static void op(sd_bus_message* m)
202 {
203 int32_t a = 0, b = 0;
204 const char *s0 = nullptr, *s1 = nullptr, *s2 = nullptr,
205 *s3 = nullptr;
206 sd_bus_message_read(m, "issssi", &a, &s0, &s1, &s2, &s3, &b);
207 assert(a == 1);
208 assert(b == 5);
209 assert(0 == strcmp("asdf", s0));
210 assert(0 == strcmp("ASDF", s1));
211 assert(0 == strcmp("jkl;", s2));
212 assert(0 == strcmp("JKL:", s3));
213 }
214 };
215 verifyCallback = &verify::op;
216
Patrick Williams5b485792016-08-02 07:35:14 -0500217 b.call_noreply(m);
Patrick Williams1807fa42016-08-01 22:23:30 -0500218 }
219
Patrick Williams930460c2016-07-20 17:52:55 -0500220 // Test vector.
221 {
222 auto m = newMethodCall__test(b);
223 std::vector<std::string> s{ "1", "2", "3"};
224 m.append(1, s, 2);
225 verifyTypeString = "iasi";
226
227 struct verify
228 {
229 static void op(sd_bus_message* m)
230 {
231 int32_t a = 0;
232 sd_bus_message_read(m, "i", &a);
233 assert(a == 1);
234
235 auto rc = sd_bus_message_enter_container(m,
236 SD_BUS_TYPE_ARRAY,
237 "s");
238 assert(0 <= rc);
239
240 const char* s = nullptr;
241 sd_bus_message_read_basic(m, 's', &s);
242 assert(0 == strcmp("1", s));
243 sd_bus_message_read_basic(m, 's', &s);
244 assert(0 == strcmp("2", s));
245 sd_bus_message_read_basic(m, 's', &s);
246 assert(0 == strcmp("3", s));
247 assert(1 == sd_bus_message_at_end(m, false));
248
249 sd_bus_message_exit_container(m);
250
251 sd_bus_message_read(m, "i", &a);
252 assert(a == 2);
253
254 }
255 };
256 verifyCallback = &verify::op;
257
258
259 b.call_noreply(m);
260 }
261
Patrick Williamsbbe0e432016-09-10 08:57:03 -0500262 // Test map.
263 {
264 auto m = newMethodCall__test(b);
265 std::map<std::string, int> s = { { "asdf", 3 }, { "jkl;", 4 } };
266 m.append(1, s, 2);
267 verifyTypeString = "ia{si}i";
268
269 struct verify
270 {
271 static void op(sd_bus_message* m)
272 {
273 int32_t a = 0;
274 sd_bus_message_read(m, "i", &a);
275 assert(a == 1);
276
277 auto rc = sd_bus_message_enter_container(m,
278 SD_BUS_TYPE_ARRAY,
279 "{si}");
280 assert(0 <= rc);
281
282 rc = sd_bus_message_enter_container(m,
283 SD_BUS_TYPE_DICT_ENTRY,
284 "si");
285 assert(0 <= rc);
286
287 const char* s = nullptr;
288 sd_bus_message_read_basic(m, 's', &s);
289 assert(0 == strcmp("asdf", s));
290 sd_bus_message_read_basic(m, 'i', &a);
291 assert(a == 3);
292
293 assert(1 == sd_bus_message_at_end(m, false));
294 sd_bus_message_exit_container(m);
295
296 rc = sd_bus_message_enter_container(m,
297 SD_BUS_TYPE_DICT_ENTRY,
298 "si");
299 assert(0 <= rc);
300
301 sd_bus_message_read_basic(m, 's', &s);
302 assert(0 == strcmp("jkl;", s));
303 sd_bus_message_read_basic(m, 'i', &a);
304 assert(a == 4);
305
306 assert(1 == sd_bus_message_at_end(m, false));
307 sd_bus_message_exit_container(m);
308
309 assert(1 == sd_bus_message_at_end(m, false));
310 sd_bus_message_exit_container(m);
311
312 sd_bus_message_read(m, "i", &a);
313 assert(a == 2);
314 }
315 };
316 verifyCallback = &verify::op;
317
318 b.call_noreply(m);
319 }
320
Patrick Williamsaa2f48a2016-09-10 14:23:34 -0500321 // Test tuple.
322 {
323 auto m = newMethodCall__test(b);
324 std::tuple<int, double, std::string> a{ 3, 4.1, "asdf" };
325 m.append(1, a, 2);
326 verifyTypeString = "i(ids)i";
327
328 struct verify
329 {
330 static void op(sd_bus_message* m)
331 {
332 int32_t a = 0;
333 double b = 0;
334 const char* c = nullptr;
335
336 sd_bus_message_read(m, "i", &a);
337 assert(a == 1);
338
339 auto rc = sd_bus_message_enter_container(m,
340 SD_BUS_TYPE_STRUCT,
341 "ids");
342 assert(0 <= rc);
343
344 sd_bus_message_read(m, "ids", &a, &b, &c);
345 assert(a == 3);
346 assert(b == 4.1);
347 assert(0 == strcmp(c, "asdf"));
348
349 sd_bus_message_exit_container(m);
350
351 sd_bus_message_read(m, "i", &a);
352 assert(a == 2);
353 }
354 };
355 verifyCallback = &verify::op;
356
357 b.call_noreply(m);
358 }
359
Patrick Williams75596782016-09-11 21:14:10 -0500360 // Test variant.
361 {
362 auto m = newMethodCall__test(b);
363 sdbusplus::message::variant<int, double> a1{3.1}, a2{4};
364 m.append(1, a1, a2, 2);
365 verifyTypeString = "ivvi";
366
367 struct verify
368 {
369 static void op(sd_bus_message* m)
370 {
371 int32_t a = 0;
372 double b = 0;
373
374 sd_bus_message_read(m, "i", &a);
375 assert(a == 1);
376
377 sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, "d");
378 sd_bus_message_read(m, "d", &b);
379 assert(b == 3.1);
380 sd_bus_message_exit_container(m);
381
382 sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, "i");
383 sd_bus_message_read(m, "i", &a);
384 assert(a == 4);
385 sd_bus_message_exit_container(m);
386
387 sd_bus_message_read(m, "i", &a);
388 assert(a == 2);
389 }
390 };
391 verifyCallback = &verify::op;
392
393 b.call_noreply(m);
394 }
395
396 // Test map-variant.
397 {
398 auto m = newMethodCall__test(b);
399 std::map<std::string, sdbusplus::message::variant<int, double>> a1 =
400 { { "asdf", 3 }, { "jkl;", 4.1 } };
401 m.append(1, a1, 2);
402 verifyTypeString = "ia{sv}i";
403
404 struct verify
405 {
406 static void op(sd_bus_message* m)
407 {
408 int32_t a = 0;
409 double b = 0;
410 const char* c = nullptr;
411
412 sd_bus_message_read(m, "i", &a);
413 assert(a == 1);
414
415 sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{sv}");
416 sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "sv");
417 sd_bus_message_read(m, "s", &c);
418 assert(0 == strcmp("asdf", c));
419 sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, "i");
420 sd_bus_message_read(m, "i", &a);
421 assert(a == 3);
422 sd_bus_message_exit_container(m);
423 sd_bus_message_exit_container(m);
424 sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "sv");
425 sd_bus_message_read(m, "s", &c);
426 assert(0 == strcmp("jkl;", c));
427 sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, "d");
428 sd_bus_message_read(m, "d", &b);
429 assert(b == 4.1);
430 sd_bus_message_exit_container(m);
431 sd_bus_message_exit_container(m);
432 sd_bus_message_exit_container(m);
433
434 sd_bus_message_read(m, "i", &a);
435 assert(a == 2);
436 }
437 };
438 verifyCallback = &verify::op;
439
440 b.call_noreply(m);
441 }
442
Patrick Williams1807fa42016-08-01 22:23:30 -0500443 // Shutdown server.
Patrick Williams7802c072016-09-02 15:20:22 -0500444 {
445 auto m = b.new_method_call(SERVICE, "/", INTERFACE, QUIT_METHOD);
446 b.call_noreply(m);
447 }
Patrick Williams1807fa42016-08-01 22:23:30 -0500448}
449
450int main()
451{
Patrick Williams07e1d6f2016-09-08 15:54:09 -0500452
Patrick Williams1807fa42016-08-01 22:23:30 -0500453 // Initialize and start server thread.
454 pthread_t t;
455 {
Patrick Williams5b485792016-08-02 07:35:14 -0500456 auto b = serverInit();
457 pthread_create(&t, NULL, server, b.release());
Patrick Williams1807fa42016-08-01 22:23:30 -0500458 }
459
460 runTests();
461
462 // Wait for server thread to exit.
463 pthread_join(t, NULL);
464
465 return 0;
466}