xref: /openbmc/sdbusplus/test/message/read.cpp (revision 9e3b51e34470c9d13649602e4a31bb61568f93ed)
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