xref: /openbmc/sdbusplus/test/message/read.cpp (revision f101ee28)
14fe85a30SPatrick Williams #include <iostream>
24fe85a30SPatrick Williams #include <cassert>
34fe85a30SPatrick Williams #include <sdbusplus/message.hpp>
44fe85a30SPatrick Williams #include <sdbusplus/bus.hpp>
54fe85a30SPatrick Williams 
64fe85a30SPatrick Williams // Global to share the dbus type string between client and server.
74fe85a30SPatrick Williams static std::string verifyTypeString;
84fe85a30SPatrick Williams 
94fe85a30SPatrick Williams using verifyCallback_t = void(*)(sdbusplus::message::message&);
104fe85a30SPatrick Williams verifyCallback_t verifyCallback = nullptr;
114fe85a30SPatrick Williams 
1224fb2968SPatrick Williams static constexpr auto SERVICE = "sdbusplus.test.message.read";
134fe85a30SPatrick Williams static constexpr auto INTERFACE = SERVICE;
144fe85a30SPatrick Williams static constexpr auto TEST_METHOD = "test";
154fe85a30SPatrick Williams static constexpr auto QUIT_METHOD = "quit";
164fe85a30SPatrick Williams 
174fe85a30SPatrick Williams // Open up the sdbus and claim SERVICE name.
184fe85a30SPatrick Williams auto serverInit()
194fe85a30SPatrick Williams {
204fe85a30SPatrick Williams     auto b = sdbusplus::bus::new_default();
214fe85a30SPatrick Williams     b.request_name(SERVICE);
224fe85a30SPatrick Williams 
234fe85a30SPatrick Williams     return std::move(b);
244fe85a30SPatrick Williams }
254fe85a30SPatrick Williams 
264fe85a30SPatrick Williams // Thread to run the dbus server.
274fe85a30SPatrick Williams void* server(void* b)
284fe85a30SPatrick Williams {
294fe85a30SPatrick Williams     auto bus = sdbusplus::bus::bus(reinterpret_cast<sdbusplus::bus::busp_t>(b));
304fe85a30SPatrick Williams 
314fe85a30SPatrick Williams     while(1)
324fe85a30SPatrick Williams     {
334fe85a30SPatrick Williams         // Wait for messages.
344fe85a30SPatrick Williams         auto m = bus.process();
354fe85a30SPatrick Williams 
364fe85a30SPatrick Williams         if(!m)
374fe85a30SPatrick Williams         {
384fe85a30SPatrick Williams             bus.wait();
394fe85a30SPatrick Williams             continue;
404fe85a30SPatrick Williams         }
414fe85a30SPatrick Williams 
424fe85a30SPatrick Williams         if (m.is_method_call(INTERFACE, TEST_METHOD))
434fe85a30SPatrick Williams         {
444fe85a30SPatrick Williams             // Verify the message type matches what the test expects.
454fe85a30SPatrick Williams             assert(verifyTypeString == m.get_signature());
464fe85a30SPatrick Williams 
474fe85a30SPatrick Williams             if (verifyCallback)
484fe85a30SPatrick Williams             {
494fe85a30SPatrick Williams 
504fe85a30SPatrick Williams                 verifyCallback(m);
514fe85a30SPatrick Williams                 verifyCallback = nullptr;
524fe85a30SPatrick Williams             }
534fe85a30SPatrick Williams             else
544fe85a30SPatrick Williams             {
554fe85a30SPatrick Williams                 std::cout << "Warning: No verification for "
564fe85a30SPatrick Williams                           << verifyTypeString << std::endl;
574fe85a30SPatrick Williams             }
584fe85a30SPatrick Williams             // Reply to client.
594fe85a30SPatrick Williams             sd_bus_reply_method_return(m.release(), nullptr);
604fe85a30SPatrick Williams         }
614fe85a30SPatrick Williams         else if (m.is_method_call(INTERFACE, QUIT_METHOD))
624fe85a30SPatrick Williams         {
634fe85a30SPatrick Williams             // Reply and exit.
644fe85a30SPatrick Williams             sd_bus_reply_method_return(m.release(), nullptr);
654fe85a30SPatrick Williams             break;
664fe85a30SPatrick Williams         }
674fe85a30SPatrick Williams     }
68696e3159SPatrick Williams 
69696e3159SPatrick Williams     return nullptr;
704fe85a30SPatrick Williams }
714fe85a30SPatrick Williams 
724fe85a30SPatrick Williams auto newMethodCall__test(sdbusplus::bus::bus& b)
734fe85a30SPatrick Williams {
744fe85a30SPatrick Williams     // Allocate a method-call message for INTERFACE,TEST_METHOD.
754fe85a30SPatrick Williams     return b.new_method_call(SERVICE, "/", INTERFACE, TEST_METHOD);
764fe85a30SPatrick Williams }
774fe85a30SPatrick Williams 
784fe85a30SPatrick Williams void runTests()
794fe85a30SPatrick Williams {
804fe85a30SPatrick Williams     using namespace std::literals;
814fe85a30SPatrick Williams 
824fe85a30SPatrick Williams     auto b = sdbusplus::bus::new_default();
834fe85a30SPatrick Williams 
844fe85a30SPatrick Williams     // Test r-value int.
854fe85a30SPatrick Williams     {
864fe85a30SPatrick Williams         auto m = newMethodCall__test(b);
874fe85a30SPatrick Williams         m.append(1);
884fe85a30SPatrick Williams         verifyTypeString = "i";
894fe85a30SPatrick Williams 
904fe85a30SPatrick Williams         struct verify
914fe85a30SPatrick Williams         {
924fe85a30SPatrick Williams             static void op(sdbusplus::message::message& m)
934fe85a30SPatrick Williams             {
944fe85a30SPatrick Williams                 int32_t i = 0;
954fe85a30SPatrick Williams                 m.read(i);
964fe85a30SPatrick Williams                 assert(i == 1);
974fe85a30SPatrick Williams             }
984fe85a30SPatrick Williams         };
994fe85a30SPatrick Williams         verifyCallback = &verify::op;
1004fe85a30SPatrick Williams 
1014fe85a30SPatrick Williams         b.call_noreply(m);
1024fe85a30SPatrick Williams     }
1034fe85a30SPatrick Williams     // Test l-value int.
1044fe85a30SPatrick Williams     {
1054fe85a30SPatrick Williams         auto m = newMethodCall__test(b);
1064fe85a30SPatrick Williams         int a = 1;
1074fe85a30SPatrick Williams         m.append(a, a);
1084fe85a30SPatrick Williams         verifyTypeString = "ii";
1094fe85a30SPatrick Williams 
1104fe85a30SPatrick Williams         struct verify
1114fe85a30SPatrick Williams         {
1124fe85a30SPatrick Williams             static void op(sdbusplus::message::message& m)
1134fe85a30SPatrick Williams             {
1144fe85a30SPatrick Williams                 int32_t a = 0, b = 0;
1154fe85a30SPatrick Williams                 m.read(a, b);
1164fe85a30SPatrick Williams                 assert(a == 1);
1174fe85a30SPatrick Williams                 assert(b == 1);
1184fe85a30SPatrick Williams             }
1194fe85a30SPatrick Williams         };
1204fe85a30SPatrick Williams         verifyCallback = &verify::op;
1214fe85a30SPatrick Williams 
1224fe85a30SPatrick Williams         b.call_noreply(m);
1234fe85a30SPatrick Williams     }
1244fe85a30SPatrick Williams 
1254fe85a30SPatrick Williams     // Test multiple ints.
1264fe85a30SPatrick Williams     {
1274fe85a30SPatrick Williams         auto m = newMethodCall__test(b);
1284fe85a30SPatrick Williams         m.append(1, 2, 3, 4, 5);
1294fe85a30SPatrick Williams         verifyTypeString = "iiiii";
1304fe85a30SPatrick Williams 
1314fe85a30SPatrick Williams         struct verify
1324fe85a30SPatrick Williams         {
1334fe85a30SPatrick Williams             static void op(sdbusplus::message::message& m)
1344fe85a30SPatrick Williams             {
1354fe85a30SPatrick Williams                 int32_t a = 0, b = 0, c = 0, d = 0, e = 0;
1364fe85a30SPatrick Williams                 m.read(a,b,c,d,e);
1374fe85a30SPatrick Williams                 assert(a == 1);
1384fe85a30SPatrick Williams                 assert(b == 2);
1394fe85a30SPatrick Williams                 assert(c == 3);
1404fe85a30SPatrick Williams                 assert(d == 4);
1414fe85a30SPatrick Williams                 assert(e == 5);
1424fe85a30SPatrick Williams             }
1434fe85a30SPatrick Williams         };
1444fe85a30SPatrick Williams         verifyCallback = &verify::op;
1454fe85a30SPatrick Williams 
1464fe85a30SPatrick Williams         b.call_noreply(m);
1474fe85a30SPatrick Williams     }
1484fe85a30SPatrick Williams 
1499e3b51e3SPatrick Williams     // Test double and bool.
1509e3b51e3SPatrick Williams     {
1519e3b51e3SPatrick Williams         auto m = newMethodCall__test(b);
1529e3b51e3SPatrick Williams         bool t = true;
1539e3b51e3SPatrick Williams         m.append(t, true, false, 1.1);
1549e3b51e3SPatrick Williams         verifyTypeString = "bbbd";
1559e3b51e3SPatrick Williams 
1569e3b51e3SPatrick Williams         struct verify
1579e3b51e3SPatrick Williams         {
1589e3b51e3SPatrick Williams             static void op(sdbusplus::message::message& m)
1599e3b51e3SPatrick Williams             {
1609e3b51e3SPatrick Williams                 bool t1, t2, f1;
1619e3b51e3SPatrick Williams                 double d;
1629e3b51e3SPatrick Williams                 m.read(t1, t2, f1, d);
1639e3b51e3SPatrick Williams                 assert(t1);
1649e3b51e3SPatrick Williams                 assert(t2);
1659e3b51e3SPatrick Williams                 assert(!f1);
1669e3b51e3SPatrick Williams                 assert(d == 1.1);
1679e3b51e3SPatrick Williams             }
1689e3b51e3SPatrick Williams         };
1699e3b51e3SPatrick Williams         verifyCallback = &verify::op;
1709e3b51e3SPatrick Williams 
1719e3b51e3SPatrick Williams         b.call_noreply(m);
1729e3b51e3SPatrick Williams     }
1739e3b51e3SPatrick Williams 
1744fe85a30SPatrick Williams     // Test r-value string.
1754fe85a30SPatrick Williams     {
1764fe85a30SPatrick Williams         auto m = newMethodCall__test(b);
1774fe85a30SPatrick Williams         m.append("asdf"s);
1784fe85a30SPatrick Williams         verifyTypeString = "s";
1794fe85a30SPatrick Williams 
1804fe85a30SPatrick Williams         struct verify
1814fe85a30SPatrick Williams         {
1824fe85a30SPatrick Williams             static void op(sdbusplus::message::message& m)
1834fe85a30SPatrick Williams             {
1844fe85a30SPatrick Williams                 const char* s = nullptr;
1854fe85a30SPatrick Williams                 m.read(s);
1864fe85a30SPatrick Williams                 assert(0 == strcmp("asdf", s));
1874fe85a30SPatrick Williams             }
1884fe85a30SPatrick Williams         };
1894fe85a30SPatrick Williams         verifyCallback = &verify::op;
1904fe85a30SPatrick Williams 
1914fe85a30SPatrick Williams         b.call_noreply(m);
1924fe85a30SPatrick Williams     }
1934fe85a30SPatrick Williams 
1944fe85a30SPatrick Williams     // Test multiple strings, various forms.
1954fe85a30SPatrick Williams     {
1964fe85a30SPatrick Williams         auto m = newMethodCall__test(b);
1974fe85a30SPatrick Williams         auto str = "jkl;"s;
1984fe85a30SPatrick Williams         auto str2 = "JKL:"s;
1994fe85a30SPatrick Williams         m.append(1, "asdf", "ASDF"s, str,
2004fe85a30SPatrick Williams                  std::move(str2), 5);
2014fe85a30SPatrick Williams         verifyTypeString = "issssi";
2024fe85a30SPatrick Williams 
2034fe85a30SPatrick Williams         struct verify
2044fe85a30SPatrick Williams         {
2054fe85a30SPatrick Williams             static void op(sdbusplus::message::message& m)
2064fe85a30SPatrick Williams             {
2074fe85a30SPatrick Williams                 int32_t a = 0, b = 0;
2084fe85a30SPatrick Williams                 std::string s0, s1, s2, s3;
2094fe85a30SPatrick Williams                 m.read(a, s0, s1, s2, s3, b);
2104fe85a30SPatrick Williams                 assert(a == 1);
2114fe85a30SPatrick Williams                 assert(b == 5);
2124fe85a30SPatrick Williams                 assert(s0 == "asdf"s);
2134fe85a30SPatrick Williams                 assert(s1 == "ASDF"s);
2144fe85a30SPatrick Williams                 assert(s2 == "jkl;"s);
2154fe85a30SPatrick Williams                 assert(s3 == "JKL:");
2164fe85a30SPatrick Williams             }
2174fe85a30SPatrick Williams         };
2184fe85a30SPatrick Williams         verifyCallback = &verify::op;
2194fe85a30SPatrick Williams 
2204fe85a30SPatrick Williams         b.call_noreply(m);
2214fe85a30SPatrick Williams     }
2224fe85a30SPatrick Williams 
223930460c0SPatrick Williams     // Test vector.
224930460c0SPatrick Williams     {
225930460c0SPatrick Williams         auto m = newMethodCall__test(b);
226930460c0SPatrick Williams         std::vector<std::string> s{ "1", "2", "3"};
227930460c0SPatrick Williams         m.append(1, s, 2);
228930460c0SPatrick Williams         verifyTypeString = "iasi";
229930460c0SPatrick Williams 
230930460c0SPatrick Williams         struct verify
231930460c0SPatrick Williams         {
232930460c0SPatrick Williams             static void op(sdbusplus::message::message& m)
233930460c0SPatrick Williams             {
234930460c0SPatrick Williams                 int32_t a = 0;
235930460c0SPatrick Williams                 std::vector<std::string> s;
236930460c0SPatrick Williams                 m.read(a, s);
237930460c0SPatrick Williams                 assert(a == 1);
238930460c0SPatrick Williams                 assert(s[0] == "1");
239930460c0SPatrick Williams                 assert(s[1] == "2");
240930460c0SPatrick Williams                 assert(s[2] == "3");
241930460c0SPatrick Williams                 decltype(s) s2 = { "1" , "2" , "3" };
242930460c0SPatrick Williams                 assert(s == s2);
243930460c0SPatrick Williams             }
244930460c0SPatrick Williams         };
245930460c0SPatrick Williams         verifyCallback = &verify::op;
246930460c0SPatrick Williams 
247930460c0SPatrick Williams         b.call_noreply(m);
248930460c0SPatrick Williams     }
249930460c0SPatrick Williams 
250bbe0e436SPatrick Williams     // Test map.
251bbe0e436SPatrick Williams     {
252bbe0e436SPatrick Williams         auto m = newMethodCall__test(b);
253bbe0e436SPatrick Williams         std::map<std::string, int> s = { { "asdf", 3 }, { "jkl;", 4 } };
254bbe0e436SPatrick Williams         m.append(1, s, 2);
255bbe0e436SPatrick Williams         verifyTypeString = "ia{si}i";
256bbe0e436SPatrick Williams 
257bbe0e436SPatrick Williams         struct verify
258bbe0e436SPatrick Williams         {
259bbe0e436SPatrick Williams             static void op(sdbusplus::message::message& m)
260bbe0e436SPatrick Williams             {
261bbe0e436SPatrick Williams                 int32_t a = 0, b = 0;
262bbe0e436SPatrick Williams                 std::map<std::string, int> s{};
263bbe0e436SPatrick Williams 
264bbe0e436SPatrick Williams                 m.read(a, s, b);
265bbe0e436SPatrick Williams                 assert(a == 1);
266bbe0e436SPatrick Williams                 assert(s.size() == 2);
267bbe0e436SPatrick Williams                 assert(s["asdf"] == 3);
268bbe0e436SPatrick Williams                 assert(s["jkl;"] == 4);
269bbe0e436SPatrick Williams                 assert(b == 2);
270bbe0e436SPatrick Williams             }
271bbe0e436SPatrick Williams         };
272bbe0e436SPatrick Williams         verifyCallback = &verify::op;
273bbe0e436SPatrick Williams 
274bbe0e436SPatrick Williams         b.call_noreply(m);
275bbe0e436SPatrick Williams     }
276bbe0e436SPatrick Williams 
277aa2f48afSPatrick Williams     // Test tuple.
278aa2f48afSPatrick Williams     {
279aa2f48afSPatrick Williams         auto m = newMethodCall__test(b);
280aa2f48afSPatrick Williams         std::tuple<int, double, std::string> a{ 3, 4.1, "asdf" };
281aa2f48afSPatrick Williams         m.append(1, a, 2);
282aa2f48afSPatrick Williams         verifyTypeString = "i(ids)i";
283bbe0e436SPatrick Williams 
284aa2f48afSPatrick Williams         struct verify
285aa2f48afSPatrick Williams         {
286aa2f48afSPatrick Williams             static void op(sdbusplus::message::message& m)
287aa2f48afSPatrick Williams             {
288aa2f48afSPatrick Williams                 int32_t a = 0, b = 0;
289aa2f48afSPatrick Williams                 std::tuple<int, double, std::string> c{};
290aa2f48afSPatrick Williams 
291aa2f48afSPatrick Williams                 m.read(a, c, b);
292aa2f48afSPatrick Williams                 assert(a == 1);
293aa2f48afSPatrick Williams                 assert(b == 2);
294aa2f48afSPatrick Williams                 assert(c == std::make_tuple(3, 4.1, "asdf"s));
295aa2f48afSPatrick Williams             }
296aa2f48afSPatrick Williams         };
297aa2f48afSPatrick Williams         verifyCallback = &verify::op;
298aa2f48afSPatrick Williams 
299aa2f48afSPatrick Williams         b.call_noreply(m);
300aa2f48afSPatrick Williams     }
301bbe0e436SPatrick Williams 
30275596786SPatrick Williams     // Test variant.
30375596786SPatrick Williams     {
30475596786SPatrick Williams         auto m = newMethodCall__test(b);
30575596786SPatrick Williams         sdbusplus::message::variant<int, double> a1{3.1}, a2{4};
30675596786SPatrick Williams         m.append(1, a1, a2, 2);
30775596786SPatrick Williams         verifyTypeString = "ivvi";
30875596786SPatrick Williams 
30975596786SPatrick Williams         struct verify
31075596786SPatrick Williams         {
31175596786SPatrick Williams             static void op(sdbusplus::message::message& m)
31275596786SPatrick Williams             {
31375596786SPatrick Williams                 int32_t a, b;
31475596786SPatrick Williams                 sdbusplus::message::variant<int, double> a1{}, a2{};
31575596786SPatrick Williams 
31675596786SPatrick Williams                 m.read(a, a1, a2, b);
31775596786SPatrick Williams                 assert(a == 1);
31875596786SPatrick Williams                 assert(a1 == 3.1);
31975596786SPatrick Williams                 assert(a2 == 4);
32075596786SPatrick Williams                 assert(b == 2);
32175596786SPatrick Williams             }
32275596786SPatrick Williams         };
32375596786SPatrick Williams         verifyCallback = &verify::op;
32475596786SPatrick Williams 
32575596786SPatrick Williams         b.call_noreply(m);
32675596786SPatrick Williams     }
32775596786SPatrick Williams 
328*f101ee28SPatrick Williams     // Test variant with missing/wrong type.
329*f101ee28SPatrick Williams     {
330*f101ee28SPatrick Williams         auto m = newMethodCall__test(b);
331*f101ee28SPatrick Williams         sdbusplus::message::variant<uint64_t, double> a1{3.1}, a2{uint64_t(4)};
332*f101ee28SPatrick Williams         m.append(1, a1, a2, 2);
333*f101ee28SPatrick Williams         verifyTypeString = "ivvi";
334*f101ee28SPatrick Williams 
335*f101ee28SPatrick Williams         struct verify
336*f101ee28SPatrick Williams         {
337*f101ee28SPatrick Williams             static void op(sdbusplus::message::message& m)
338*f101ee28SPatrick Williams             {
339*f101ee28SPatrick Williams                 int32_t a, b;
340*f101ee28SPatrick Williams                 sdbusplus::message::variant<uint8_t, double> a1{}, a2{};
341*f101ee28SPatrick Williams 
342*f101ee28SPatrick Williams                 m.read(a, a1, a2, b);
343*f101ee28SPatrick Williams                 assert(a == 1);
344*f101ee28SPatrick Williams                 assert(a1 == 3.1);
345*f101ee28SPatrick Williams                 assert(a2 == uint8_t());
346*f101ee28SPatrick Williams                 assert(b == 2);
347*f101ee28SPatrick Williams             }
348*f101ee28SPatrick Williams         };
349*f101ee28SPatrick Williams         verifyCallback = &verify::op;
350*f101ee28SPatrick Williams 
351*f101ee28SPatrick Williams         b.call_noreply(m);
352*f101ee28SPatrick Williams     }
353*f101ee28SPatrick Williams 
35475596786SPatrick Williams     // Test map-variant.
35575596786SPatrick Williams     {
35675596786SPatrick Williams         auto m = newMethodCall__test(b);
35775596786SPatrick Williams         std::map<std::string, sdbusplus::message::variant<int, double>> a1 =
35875596786SPatrick Williams                 { { "asdf", 3 }, { "jkl;", 4.1 } };
35975596786SPatrick Williams         m.append(1, a1, 2);
36075596786SPatrick Williams         verifyTypeString = "ia{sv}i";
36175596786SPatrick Williams 
36275596786SPatrick Williams         struct verify
36375596786SPatrick Williams         {
36475596786SPatrick Williams             static void op(sdbusplus::message::message& m)
36575596786SPatrick Williams             {
36675596786SPatrick Williams                 int32_t a = 0, b = 0;
36775596786SPatrick Williams                 std::map<std::string,
36875596786SPatrick Williams                          sdbusplus::message::variant<int, double>> a1{};
36975596786SPatrick Williams 
37075596786SPatrick Williams                 m.read(a, a1, b);
37175596786SPatrick Williams                 assert(a == 1);
37275596786SPatrick Williams                 assert(a1["asdf"] == 3);
37375596786SPatrick Williams                 assert(a1["jkl;"] == 4.1);
37475596786SPatrick Williams                 assert(b == 2);
37575596786SPatrick Williams             }
37675596786SPatrick Williams         };
37775596786SPatrick Williams         verifyCallback = &verify::op;
37875596786SPatrick Williams 
37975596786SPatrick Williams         b.call_noreply(m);
38075596786SPatrick Williams     }
38175596786SPatrick Williams 
38275596786SPatrick Williams 
3834fe85a30SPatrick Williams     // Shutdown server.
3844fe85a30SPatrick Williams     {
3854fe85a30SPatrick Williams         auto m = b.new_method_call(SERVICE, "/", INTERFACE, QUIT_METHOD);
3864fe85a30SPatrick Williams         b.call_noreply(m);
3874fe85a30SPatrick Williams     }
3884fe85a30SPatrick Williams }
3894fe85a30SPatrick Williams 
3904fe85a30SPatrick Williams int main()
3914fe85a30SPatrick Williams {
3924fe85a30SPatrick Williams 
3934fe85a30SPatrick Williams     // Initialize and start server thread.
3944fe85a30SPatrick Williams     pthread_t t;
3954fe85a30SPatrick Williams     {
3964fe85a30SPatrick Williams         auto b = serverInit();
3974fe85a30SPatrick Williams         pthread_create(&t, NULL, server, b.release());
3984fe85a30SPatrick Williams     }
3994fe85a30SPatrick Williams 
4004fe85a30SPatrick Williams     runTests();
4014fe85a30SPatrick Williams 
4024fe85a30SPatrick Williams     // Wait for server thread to exit.
4034fe85a30SPatrick Williams     pthread_join(t, NULL);
4044fe85a30SPatrick Williams 
4054fe85a30SPatrick Williams     return 0;
4064fe85a30SPatrick Williams }
407