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 124fe85a30SPatrick Williams static constexpr auto SERVICE = "sdbusplus.test"; 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 } 684fe85a30SPatrick Williams } 694fe85a30SPatrick Williams 704fe85a30SPatrick Williams auto newMethodCall__test(sdbusplus::bus::bus& b) 714fe85a30SPatrick Williams { 724fe85a30SPatrick Williams // Allocate a method-call message for INTERFACE,TEST_METHOD. 734fe85a30SPatrick Williams return b.new_method_call(SERVICE, "/", INTERFACE, TEST_METHOD); 744fe85a30SPatrick Williams } 754fe85a30SPatrick Williams 764fe85a30SPatrick Williams void runTests() 774fe85a30SPatrick Williams { 784fe85a30SPatrick Williams using namespace std::literals; 794fe85a30SPatrick Williams 804fe85a30SPatrick Williams auto b = sdbusplus::bus::new_default(); 814fe85a30SPatrick Williams 824fe85a30SPatrick Williams // Test r-value int. 834fe85a30SPatrick Williams { 844fe85a30SPatrick Williams auto m = newMethodCall__test(b); 854fe85a30SPatrick Williams m.append(1); 864fe85a30SPatrick Williams verifyTypeString = "i"; 874fe85a30SPatrick Williams 884fe85a30SPatrick Williams struct verify 894fe85a30SPatrick Williams { 904fe85a30SPatrick Williams static void op(sdbusplus::message::message& m) 914fe85a30SPatrick Williams { 924fe85a30SPatrick Williams int32_t i = 0; 934fe85a30SPatrick Williams m.read(i); 944fe85a30SPatrick Williams assert(i == 1); 954fe85a30SPatrick Williams } 964fe85a30SPatrick Williams }; 974fe85a30SPatrick Williams verifyCallback = &verify::op; 984fe85a30SPatrick Williams 994fe85a30SPatrick Williams b.call_noreply(m); 1004fe85a30SPatrick Williams } 1014fe85a30SPatrick Williams // Test l-value int. 1024fe85a30SPatrick Williams { 1034fe85a30SPatrick Williams auto m = newMethodCall__test(b); 1044fe85a30SPatrick Williams int a = 1; 1054fe85a30SPatrick Williams m.append(a, a); 1064fe85a30SPatrick Williams verifyTypeString = "ii"; 1074fe85a30SPatrick Williams 1084fe85a30SPatrick Williams struct verify 1094fe85a30SPatrick Williams { 1104fe85a30SPatrick Williams static void op(sdbusplus::message::message& m) 1114fe85a30SPatrick Williams { 1124fe85a30SPatrick Williams int32_t a = 0, b = 0; 1134fe85a30SPatrick Williams m.read(a, b); 1144fe85a30SPatrick Williams assert(a == 1); 1154fe85a30SPatrick Williams assert(b == 1); 1164fe85a30SPatrick Williams } 1174fe85a30SPatrick Williams }; 1184fe85a30SPatrick Williams verifyCallback = &verify::op; 1194fe85a30SPatrick Williams 1204fe85a30SPatrick Williams b.call_noreply(m); 1214fe85a30SPatrick Williams } 1224fe85a30SPatrick Williams 1234fe85a30SPatrick Williams // Test multiple ints. 1244fe85a30SPatrick Williams { 1254fe85a30SPatrick Williams auto m = newMethodCall__test(b); 1264fe85a30SPatrick Williams m.append(1, 2, 3, 4, 5); 1274fe85a30SPatrick Williams verifyTypeString = "iiiii"; 1284fe85a30SPatrick Williams 1294fe85a30SPatrick Williams struct verify 1304fe85a30SPatrick Williams { 1314fe85a30SPatrick Williams static void op(sdbusplus::message::message& m) 1324fe85a30SPatrick Williams { 1334fe85a30SPatrick Williams int32_t a = 0, b = 0, c = 0, d = 0, e = 0; 1344fe85a30SPatrick Williams m.read(a,b,c,d,e); 1354fe85a30SPatrick Williams assert(a == 1); 1364fe85a30SPatrick Williams assert(b == 2); 1374fe85a30SPatrick Williams assert(c == 3); 1384fe85a30SPatrick Williams assert(d == 4); 1394fe85a30SPatrick Williams assert(e == 5); 1404fe85a30SPatrick Williams } 1414fe85a30SPatrick Williams }; 1424fe85a30SPatrick Williams verifyCallback = &verify::op; 1434fe85a30SPatrick Williams 1444fe85a30SPatrick Williams b.call_noreply(m); 1454fe85a30SPatrick Williams } 1464fe85a30SPatrick Williams 147*9e3b51e3SPatrick Williams // Test double and bool. 148*9e3b51e3SPatrick Williams { 149*9e3b51e3SPatrick Williams auto m = newMethodCall__test(b); 150*9e3b51e3SPatrick Williams bool t = true; 151*9e3b51e3SPatrick Williams m.append(t, true, false, 1.1); 152*9e3b51e3SPatrick Williams verifyTypeString = "bbbd"; 153*9e3b51e3SPatrick Williams 154*9e3b51e3SPatrick Williams struct verify 155*9e3b51e3SPatrick Williams { 156*9e3b51e3SPatrick Williams static void op(sdbusplus::message::message& m) 157*9e3b51e3SPatrick Williams { 158*9e3b51e3SPatrick Williams bool t1, t2, f1; 159*9e3b51e3SPatrick Williams double d; 160*9e3b51e3SPatrick Williams m.read(t1, t2, f1, d); 161*9e3b51e3SPatrick Williams assert(t1); 162*9e3b51e3SPatrick Williams assert(t2); 163*9e3b51e3SPatrick Williams assert(!f1); 164*9e3b51e3SPatrick Williams assert(d == 1.1); 165*9e3b51e3SPatrick Williams } 166*9e3b51e3SPatrick Williams }; 167*9e3b51e3SPatrick Williams verifyCallback = &verify::op; 168*9e3b51e3SPatrick Williams 169*9e3b51e3SPatrick Williams b.call_noreply(m); 170*9e3b51e3SPatrick Williams } 171*9e3b51e3SPatrick Williams 1724fe85a30SPatrick Williams // Test r-value string. 1734fe85a30SPatrick Williams { 1744fe85a30SPatrick Williams auto m = newMethodCall__test(b); 1754fe85a30SPatrick Williams m.append("asdf"s); 1764fe85a30SPatrick Williams verifyTypeString = "s"; 1774fe85a30SPatrick Williams 1784fe85a30SPatrick Williams struct verify 1794fe85a30SPatrick Williams { 1804fe85a30SPatrick Williams static void op(sdbusplus::message::message& m) 1814fe85a30SPatrick Williams { 1824fe85a30SPatrick Williams const char* s = nullptr; 1834fe85a30SPatrick Williams m.read(s); 1844fe85a30SPatrick Williams assert(0 == strcmp("asdf", s)); 1854fe85a30SPatrick Williams } 1864fe85a30SPatrick Williams }; 1874fe85a30SPatrick Williams verifyCallback = &verify::op; 1884fe85a30SPatrick Williams 1894fe85a30SPatrick Williams b.call_noreply(m); 1904fe85a30SPatrick Williams } 1914fe85a30SPatrick Williams 1924fe85a30SPatrick Williams // Test multiple strings, various forms. 1934fe85a30SPatrick Williams { 1944fe85a30SPatrick Williams auto m = newMethodCall__test(b); 1954fe85a30SPatrick Williams auto str = "jkl;"s; 1964fe85a30SPatrick Williams auto str2 = "JKL:"s; 1974fe85a30SPatrick Williams m.append(1, "asdf", "ASDF"s, str, 1984fe85a30SPatrick Williams std::move(str2), 5); 1994fe85a30SPatrick Williams verifyTypeString = "issssi"; 2004fe85a30SPatrick Williams 2014fe85a30SPatrick Williams struct verify 2024fe85a30SPatrick Williams { 2034fe85a30SPatrick Williams static void op(sdbusplus::message::message& m) 2044fe85a30SPatrick Williams { 2054fe85a30SPatrick Williams int32_t a = 0, b = 0; 2064fe85a30SPatrick Williams std::string s0, s1, s2, s3; 2074fe85a30SPatrick Williams m.read(a, s0, s1, s2, s3, b); 2084fe85a30SPatrick Williams assert(a == 1); 2094fe85a30SPatrick Williams assert(b == 5); 2104fe85a30SPatrick Williams assert(s0 == "asdf"s); 2114fe85a30SPatrick Williams assert(s1 == "ASDF"s); 2124fe85a30SPatrick Williams assert(s2 == "jkl;"s); 2134fe85a30SPatrick Williams assert(s3 == "JKL:"); 2144fe85a30SPatrick Williams } 2154fe85a30SPatrick Williams }; 2164fe85a30SPatrick Williams verifyCallback = &verify::op; 2174fe85a30SPatrick Williams 2184fe85a30SPatrick Williams b.call_noreply(m); 2194fe85a30SPatrick Williams } 2204fe85a30SPatrick Williams 221930460c0SPatrick Williams // Test vector. 222930460c0SPatrick Williams { 223930460c0SPatrick Williams auto m = newMethodCall__test(b); 224930460c0SPatrick Williams std::vector<std::string> s{ "1", "2", "3"}; 225930460c0SPatrick Williams m.append(1, s, 2); 226930460c0SPatrick Williams verifyTypeString = "iasi"; 227930460c0SPatrick Williams 228930460c0SPatrick Williams struct verify 229930460c0SPatrick Williams { 230930460c0SPatrick Williams static void op(sdbusplus::message::message& m) 231930460c0SPatrick Williams { 232930460c0SPatrick Williams int32_t a = 0; 233930460c0SPatrick Williams std::vector<std::string> s; 234930460c0SPatrick Williams m.read(a, s); 235930460c0SPatrick Williams assert(a == 1); 236930460c0SPatrick Williams assert(s[0] == "1"); 237930460c0SPatrick Williams assert(s[1] == "2"); 238930460c0SPatrick Williams assert(s[2] == "3"); 239930460c0SPatrick Williams decltype(s) s2 = { "1" , "2" , "3" }; 240930460c0SPatrick Williams assert(s == s2); 241930460c0SPatrick Williams } 242930460c0SPatrick Williams }; 243930460c0SPatrick Williams verifyCallback = &verify::op; 244930460c0SPatrick Williams 245930460c0SPatrick Williams b.call_noreply(m); 246930460c0SPatrick Williams } 247930460c0SPatrick Williams 248bbe0e436SPatrick Williams // Test map. 249bbe0e436SPatrick Williams { 250bbe0e436SPatrick Williams auto m = newMethodCall__test(b); 251bbe0e436SPatrick Williams std::map<std::string, int> s = { { "asdf", 3 }, { "jkl;", 4 } }; 252bbe0e436SPatrick Williams m.append(1, s, 2); 253bbe0e436SPatrick Williams verifyTypeString = "ia{si}i"; 254bbe0e436SPatrick Williams 255bbe0e436SPatrick Williams struct verify 256bbe0e436SPatrick Williams { 257bbe0e436SPatrick Williams static void op(sdbusplus::message::message& m) 258bbe0e436SPatrick Williams { 259bbe0e436SPatrick Williams int32_t a = 0, b = 0; 260bbe0e436SPatrick Williams std::map<std::string, int> s{}; 261bbe0e436SPatrick Williams 262bbe0e436SPatrick Williams m.read(a, s, b); 263bbe0e436SPatrick Williams assert(a == 1); 264bbe0e436SPatrick Williams assert(s.size() == 2); 265bbe0e436SPatrick Williams assert(s["asdf"] == 3); 266bbe0e436SPatrick Williams assert(s["jkl;"] == 4); 267bbe0e436SPatrick Williams assert(b == 2); 268bbe0e436SPatrick Williams } 269bbe0e436SPatrick Williams }; 270bbe0e436SPatrick Williams verifyCallback = &verify::op; 271bbe0e436SPatrick Williams 272bbe0e436SPatrick Williams b.call_noreply(m); 273bbe0e436SPatrick Williams } 274bbe0e436SPatrick Williams 275aa2f48afSPatrick Williams // Test tuple. 276aa2f48afSPatrick Williams { 277aa2f48afSPatrick Williams auto m = newMethodCall__test(b); 278aa2f48afSPatrick Williams std::tuple<int, double, std::string> a{ 3, 4.1, "asdf" }; 279aa2f48afSPatrick Williams m.append(1, a, 2); 280aa2f48afSPatrick Williams verifyTypeString = "i(ids)i"; 281bbe0e436SPatrick Williams 282aa2f48afSPatrick Williams struct verify 283aa2f48afSPatrick Williams { 284aa2f48afSPatrick Williams static void op(sdbusplus::message::message& m) 285aa2f48afSPatrick Williams { 286aa2f48afSPatrick Williams int32_t a = 0, b = 0; 287aa2f48afSPatrick Williams std::tuple<int, double, std::string> c{}; 288aa2f48afSPatrick Williams 289aa2f48afSPatrick Williams m.read(a, c, b); 290aa2f48afSPatrick Williams assert(a == 1); 291aa2f48afSPatrick Williams assert(b == 2); 292aa2f48afSPatrick Williams assert(c == std::make_tuple(3, 4.1, "asdf"s)); 293aa2f48afSPatrick Williams } 294aa2f48afSPatrick Williams }; 295aa2f48afSPatrick Williams verifyCallback = &verify::op; 296aa2f48afSPatrick Williams 297aa2f48afSPatrick Williams b.call_noreply(m); 298aa2f48afSPatrick Williams } 299bbe0e436SPatrick Williams 30075596786SPatrick Williams // Test variant. 30175596786SPatrick Williams { 30275596786SPatrick Williams auto m = newMethodCall__test(b); 30375596786SPatrick Williams sdbusplus::message::variant<int, double> a1{3.1}, a2{4}; 30475596786SPatrick Williams m.append(1, a1, a2, 2); 30575596786SPatrick Williams verifyTypeString = "ivvi"; 30675596786SPatrick Williams 30775596786SPatrick Williams struct verify 30875596786SPatrick Williams { 30975596786SPatrick Williams static void op(sdbusplus::message::message& m) 31075596786SPatrick Williams { 31175596786SPatrick Williams int32_t a, b; 31275596786SPatrick Williams sdbusplus::message::variant<int, double> a1{}, a2{}; 31375596786SPatrick Williams 31475596786SPatrick Williams m.read(a, a1, a2, b); 31575596786SPatrick Williams assert(a == 1); 31675596786SPatrick Williams assert(a1 == 3.1); 31775596786SPatrick Williams assert(a2 == 4); 31875596786SPatrick Williams assert(b == 2); 31975596786SPatrick Williams } 32075596786SPatrick Williams }; 32175596786SPatrick Williams verifyCallback = &verify::op; 32275596786SPatrick Williams 32375596786SPatrick Williams b.call_noreply(m); 32475596786SPatrick Williams } 32575596786SPatrick Williams 32675596786SPatrick Williams // Test map-variant. 32775596786SPatrick Williams { 32875596786SPatrick Williams auto m = newMethodCall__test(b); 32975596786SPatrick Williams std::map<std::string, sdbusplus::message::variant<int, double>> a1 = 33075596786SPatrick Williams { { "asdf", 3 }, { "jkl;", 4.1 } }; 33175596786SPatrick Williams m.append(1, a1, 2); 33275596786SPatrick Williams verifyTypeString = "ia{sv}i"; 33375596786SPatrick Williams 33475596786SPatrick Williams struct verify 33575596786SPatrick Williams { 33675596786SPatrick Williams static void op(sdbusplus::message::message& m) 33775596786SPatrick Williams { 33875596786SPatrick Williams int32_t a = 0, b = 0; 33975596786SPatrick Williams std::map<std::string, 34075596786SPatrick Williams sdbusplus::message::variant<int, double>> a1{}; 34175596786SPatrick Williams 34275596786SPatrick Williams m.read(a, a1, b); 34375596786SPatrick Williams assert(a == 1); 34475596786SPatrick Williams assert(a1["asdf"] == 3); 34575596786SPatrick Williams assert(a1["jkl;"] == 4.1); 34675596786SPatrick Williams assert(b == 2); 34775596786SPatrick Williams } 34875596786SPatrick Williams }; 34975596786SPatrick Williams verifyCallback = &verify::op; 35075596786SPatrick Williams 35175596786SPatrick Williams b.call_noreply(m); 35275596786SPatrick Williams } 35375596786SPatrick Williams 35475596786SPatrick Williams 3554fe85a30SPatrick Williams // Shutdown server. 3564fe85a30SPatrick Williams { 3574fe85a30SPatrick Williams auto m = b.new_method_call(SERVICE, "/", INTERFACE, QUIT_METHOD); 3584fe85a30SPatrick Williams b.call_noreply(m); 3594fe85a30SPatrick Williams } 3604fe85a30SPatrick Williams } 3614fe85a30SPatrick Williams 3624fe85a30SPatrick Williams int main() 3634fe85a30SPatrick Williams { 3644fe85a30SPatrick Williams 3654fe85a30SPatrick Williams // Initialize and start server thread. 3664fe85a30SPatrick Williams pthread_t t; 3674fe85a30SPatrick Williams { 3684fe85a30SPatrick Williams auto b = serverInit(); 3694fe85a30SPatrick Williams pthread_create(&t, NULL, server, b.release()); 3704fe85a30SPatrick Williams } 3714fe85a30SPatrick Williams 3724fe85a30SPatrick Williams runTests(); 3734fe85a30SPatrick Williams 3744fe85a30SPatrick Williams // Wait for server thread to exit. 3754fe85a30SPatrick Williams pthread_join(t, NULL); 3764fe85a30SPatrick Williams 3774fe85a30SPatrick Williams return 0; 3784fe85a30SPatrick Williams } 379