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