xref: /openbmc/sdbusplus/test/message/append.cpp (revision 7802c074)
1 #include <iostream>
2 #include <cassert>
3 #include <sdbusplus/message.hpp>
4 #include <sdbusplus/bus.hpp>
5 
6 // Global to share the dbus type string between client and server.
7 static std::string verifyTypeString;
8 
9 static constexpr auto SERVICE = "sdbusplus.test";
10 static constexpr auto INTERFACE = SERVICE;
11 static constexpr auto TEST_METHOD = "test";
12 static constexpr auto QUIT_METHOD = "quit";
13 
14 // Open up the sdbus and claim SERVICE name.
15 auto serverInit()
16 {
17     auto b = sdbusplus::bus::new_default();
18     b.request_name(SERVICE);
19 
20     return std::move(b);
21 }
22 
23 // Thread to run the dbus server.
24 void* server(void* b)
25 {
26     auto bus = sdbusplus::bus::bus(reinterpret_cast<sdbusplus::bus::busp_t>(b));
27 
28     while(1)
29     {
30         // Wait for messages.
31         sd_bus_message *m = bus.process();
32 
33         if(m == nullptr)
34         {
35             bus.wait();
36             continue;
37         }
38 
39         if (sd_bus_message_is_method_call(m, INTERFACE, TEST_METHOD))
40         {
41             // Verify the message type matches what the test expects.
42             // TODO: It would be nice to verify content here as well.
43             assert(verifyTypeString == sd_bus_message_get_signature(m, true));
44             // Reply to client.
45             sd_bus_reply_method_return(m, nullptr);
46         }
47         else if (sd_bus_message_is_method_call(m, INTERFACE, QUIT_METHOD))
48         {
49             // Reply and exit.
50             sd_bus_reply_method_return(m, nullptr);
51             break;
52         }
53     }
54 }
55 
56 auto newMethodCall__test(sdbusplus::bus::bus& b)
57 {
58     // Allocate a method-call message for INTERFACE,TEST_METHOD.
59     return b.new_method_call(SERVICE, "/", INTERFACE, TEST_METHOD);
60 }
61 
62 void runTests()
63 {
64     using namespace std::literals;
65 
66     auto b = sdbusplus::bus::new_default();
67 
68     // Test r-value int.
69     {
70         auto m = newMethodCall__test(b);
71         m.append(1);
72         verifyTypeString = "i";
73         b.call_noreply(m);
74     }
75     // Test l-value int.
76     {
77         auto m = newMethodCall__test(b);
78         int a = 1;
79         m.append(a, a);
80         verifyTypeString = "ii";
81         b.call_noreply(m);
82     }
83 
84     // Test multiple ints.
85     {
86         auto m = newMethodCall__test(b);
87         m.append(1, 2, 3, 4, 5);
88         verifyTypeString = "iiiii";
89         b.call_noreply(m);
90     }
91 
92     // Test r-value string.
93     {
94         auto m = newMethodCall__test(b);
95         m.append("asdf"s);
96         verifyTypeString = "s";
97         b.call_noreply(m);
98     }
99 
100     // Test multiple strings, various forms.
101     {
102         auto m = newMethodCall__test(b);
103         auto str = "jkl;"s;
104         auto str2 = "JKL:"s;
105         m.append(1, "asdf", "ASDF"s, str,
106                  std::move(str2), 5);
107         verifyTypeString = "issssi";
108         b.call_noreply(m);
109     }
110 
111     // Shutdown server.
112     {
113         auto m = b.new_method_call(SERVICE, "/", INTERFACE, QUIT_METHOD);
114         b.call_noreply(m);
115     }
116 }
117 
118 int main()
119 {
120     // Initialize and start server thread.
121     pthread_t t;
122     {
123         auto b = serverInit();
124         pthread_create(&t, NULL, server, b.release());
125     }
126 
127     runTests();
128 
129     // Wait for server thread to exit.
130     pthread_join(t, NULL);
131 
132     return 0;
133 }
134