xref: /openbmc/sdbusplus/test/message/read.cpp (revision 4fe85a30e7b2c7cdbc08c28971a8f2f7b8c4de85)
1*4fe85a30SPatrick Williams #include <iostream>
2*4fe85a30SPatrick Williams #include <cassert>
3*4fe85a30SPatrick Williams #include <sdbusplus/message.hpp>
4*4fe85a30SPatrick Williams #include <sdbusplus/bus.hpp>
5*4fe85a30SPatrick Williams 
6*4fe85a30SPatrick Williams // Global to share the dbus type string between client and server.
7*4fe85a30SPatrick Williams static std::string verifyTypeString;
8*4fe85a30SPatrick Williams 
9*4fe85a30SPatrick Williams using verifyCallback_t = void(*)(sdbusplus::message::message&);
10*4fe85a30SPatrick Williams verifyCallback_t verifyCallback = nullptr;
11*4fe85a30SPatrick Williams 
12*4fe85a30SPatrick Williams static constexpr auto SERVICE = "sdbusplus.test";
13*4fe85a30SPatrick Williams static constexpr auto INTERFACE = SERVICE;
14*4fe85a30SPatrick Williams static constexpr auto TEST_METHOD = "test";
15*4fe85a30SPatrick Williams static constexpr auto QUIT_METHOD = "quit";
16*4fe85a30SPatrick Williams 
17*4fe85a30SPatrick Williams // Open up the sdbus and claim SERVICE name.
18*4fe85a30SPatrick Williams auto serverInit()
19*4fe85a30SPatrick Williams {
20*4fe85a30SPatrick Williams     auto b = sdbusplus::bus::new_default();
21*4fe85a30SPatrick Williams     b.request_name(SERVICE);
22*4fe85a30SPatrick Williams 
23*4fe85a30SPatrick Williams     return std::move(b);
24*4fe85a30SPatrick Williams }
25*4fe85a30SPatrick Williams 
26*4fe85a30SPatrick Williams // Thread to run the dbus server.
27*4fe85a30SPatrick Williams void* server(void* b)
28*4fe85a30SPatrick Williams {
29*4fe85a30SPatrick Williams     auto bus = sdbusplus::bus::bus(reinterpret_cast<sdbusplus::bus::busp_t>(b));
30*4fe85a30SPatrick Williams 
31*4fe85a30SPatrick Williams     while(1)
32*4fe85a30SPatrick Williams     {
33*4fe85a30SPatrick Williams         // Wait for messages.
34*4fe85a30SPatrick Williams         auto m = bus.process();
35*4fe85a30SPatrick Williams 
36*4fe85a30SPatrick Williams         if(!m)
37*4fe85a30SPatrick Williams         {
38*4fe85a30SPatrick Williams             bus.wait();
39*4fe85a30SPatrick Williams             continue;
40*4fe85a30SPatrick Williams         }
41*4fe85a30SPatrick Williams 
42*4fe85a30SPatrick Williams         if (m.is_method_call(INTERFACE, TEST_METHOD))
43*4fe85a30SPatrick Williams         {
44*4fe85a30SPatrick Williams             // Verify the message type matches what the test expects.
45*4fe85a30SPatrick Williams             assert(verifyTypeString == m.get_signature());
46*4fe85a30SPatrick Williams 
47*4fe85a30SPatrick Williams             if (verifyCallback)
48*4fe85a30SPatrick Williams             {
49*4fe85a30SPatrick Williams 
50*4fe85a30SPatrick Williams                 verifyCallback(m);
51*4fe85a30SPatrick Williams                 verifyCallback = nullptr;
52*4fe85a30SPatrick Williams             }
53*4fe85a30SPatrick Williams             else
54*4fe85a30SPatrick Williams             {
55*4fe85a30SPatrick Williams                 std::cout << "Warning: No verification for "
56*4fe85a30SPatrick Williams                           << verifyTypeString << std::endl;
57*4fe85a30SPatrick Williams             }
58*4fe85a30SPatrick Williams             // Reply to client.
59*4fe85a30SPatrick Williams             sd_bus_reply_method_return(m.release(), nullptr);
60*4fe85a30SPatrick Williams         }
61*4fe85a30SPatrick Williams         else if (m.is_method_call(INTERFACE, QUIT_METHOD))
62*4fe85a30SPatrick Williams         {
63*4fe85a30SPatrick Williams             // Reply and exit.
64*4fe85a30SPatrick Williams             sd_bus_reply_method_return(m.release(), nullptr);
65*4fe85a30SPatrick Williams             break;
66*4fe85a30SPatrick Williams         }
67*4fe85a30SPatrick Williams     }
68*4fe85a30SPatrick Williams }
69*4fe85a30SPatrick Williams 
70*4fe85a30SPatrick Williams auto newMethodCall__test(sdbusplus::bus::bus& b)
71*4fe85a30SPatrick Williams {
72*4fe85a30SPatrick Williams     // Allocate a method-call message for INTERFACE,TEST_METHOD.
73*4fe85a30SPatrick Williams     return b.new_method_call(SERVICE, "/", INTERFACE, TEST_METHOD);
74*4fe85a30SPatrick Williams }
75*4fe85a30SPatrick Williams 
76*4fe85a30SPatrick Williams void runTests()
77*4fe85a30SPatrick Williams {
78*4fe85a30SPatrick Williams     using namespace std::literals;
79*4fe85a30SPatrick Williams 
80*4fe85a30SPatrick Williams     auto b = sdbusplus::bus::new_default();
81*4fe85a30SPatrick Williams 
82*4fe85a30SPatrick Williams     // Test r-value int.
83*4fe85a30SPatrick Williams     {
84*4fe85a30SPatrick Williams         auto m = newMethodCall__test(b);
85*4fe85a30SPatrick Williams         m.append(1);
86*4fe85a30SPatrick Williams         verifyTypeString = "i";
87*4fe85a30SPatrick Williams 
88*4fe85a30SPatrick Williams         struct verify
89*4fe85a30SPatrick Williams         {
90*4fe85a30SPatrick Williams             static void op(sdbusplus::message::message& m)
91*4fe85a30SPatrick Williams             {
92*4fe85a30SPatrick Williams                 int32_t i = 0;
93*4fe85a30SPatrick Williams                 m.read(i);
94*4fe85a30SPatrick Williams                 assert(i == 1);
95*4fe85a30SPatrick Williams             }
96*4fe85a30SPatrick Williams         };
97*4fe85a30SPatrick Williams         verifyCallback = &verify::op;
98*4fe85a30SPatrick Williams 
99*4fe85a30SPatrick Williams         b.call_noreply(m);
100*4fe85a30SPatrick Williams     }
101*4fe85a30SPatrick Williams     // Test l-value int.
102*4fe85a30SPatrick Williams     {
103*4fe85a30SPatrick Williams         auto m = newMethodCall__test(b);
104*4fe85a30SPatrick Williams         int a = 1;
105*4fe85a30SPatrick Williams         m.append(a, a);
106*4fe85a30SPatrick Williams         verifyTypeString = "ii";
107*4fe85a30SPatrick Williams 
108*4fe85a30SPatrick Williams         struct verify
109*4fe85a30SPatrick Williams         {
110*4fe85a30SPatrick Williams             static void op(sdbusplus::message::message& m)
111*4fe85a30SPatrick Williams             {
112*4fe85a30SPatrick Williams                 int32_t a = 0, b = 0;
113*4fe85a30SPatrick Williams                 m.read(a, b);
114*4fe85a30SPatrick Williams                 assert(a == 1);
115*4fe85a30SPatrick Williams                 assert(b == 1);
116*4fe85a30SPatrick Williams             }
117*4fe85a30SPatrick Williams         };
118*4fe85a30SPatrick Williams         verifyCallback = &verify::op;
119*4fe85a30SPatrick Williams 
120*4fe85a30SPatrick Williams         b.call_noreply(m);
121*4fe85a30SPatrick Williams     }
122*4fe85a30SPatrick Williams 
123*4fe85a30SPatrick Williams     // Test multiple ints.
124*4fe85a30SPatrick Williams     {
125*4fe85a30SPatrick Williams         auto m = newMethodCall__test(b);
126*4fe85a30SPatrick Williams         m.append(1, 2, 3, 4, 5);
127*4fe85a30SPatrick Williams         verifyTypeString = "iiiii";
128*4fe85a30SPatrick Williams 
129*4fe85a30SPatrick Williams         struct verify
130*4fe85a30SPatrick Williams         {
131*4fe85a30SPatrick Williams             static void op(sdbusplus::message::message& m)
132*4fe85a30SPatrick Williams             {
133*4fe85a30SPatrick Williams                 int32_t a = 0, b = 0, c = 0, d = 0, e = 0;
134*4fe85a30SPatrick Williams                 m.read(a,b,c,d,e);
135*4fe85a30SPatrick Williams                 assert(a == 1);
136*4fe85a30SPatrick Williams                 assert(b == 2);
137*4fe85a30SPatrick Williams                 assert(c == 3);
138*4fe85a30SPatrick Williams                 assert(d == 4);
139*4fe85a30SPatrick Williams                 assert(e == 5);
140*4fe85a30SPatrick Williams             }
141*4fe85a30SPatrick Williams         };
142*4fe85a30SPatrick Williams         verifyCallback = &verify::op;
143*4fe85a30SPatrick Williams 
144*4fe85a30SPatrick Williams         b.call_noreply(m);
145*4fe85a30SPatrick Williams     }
146*4fe85a30SPatrick Williams 
147*4fe85a30SPatrick Williams     // Test r-value string.
148*4fe85a30SPatrick Williams     {
149*4fe85a30SPatrick Williams         auto m = newMethodCall__test(b);
150*4fe85a30SPatrick Williams         m.append("asdf"s);
151*4fe85a30SPatrick Williams         verifyTypeString = "s";
152*4fe85a30SPatrick Williams 
153*4fe85a30SPatrick Williams         struct verify
154*4fe85a30SPatrick Williams         {
155*4fe85a30SPatrick Williams             static void op(sdbusplus::message::message& m)
156*4fe85a30SPatrick Williams             {
157*4fe85a30SPatrick Williams                 const char* s = nullptr;
158*4fe85a30SPatrick Williams                 m.read(s);
159*4fe85a30SPatrick Williams                 assert(0 == strcmp("asdf", s));
160*4fe85a30SPatrick Williams             }
161*4fe85a30SPatrick Williams         };
162*4fe85a30SPatrick Williams         verifyCallback = &verify::op;
163*4fe85a30SPatrick Williams 
164*4fe85a30SPatrick Williams         b.call_noreply(m);
165*4fe85a30SPatrick Williams     }
166*4fe85a30SPatrick Williams 
167*4fe85a30SPatrick Williams     // Test multiple strings, various forms.
168*4fe85a30SPatrick Williams     {
169*4fe85a30SPatrick Williams         auto m = newMethodCall__test(b);
170*4fe85a30SPatrick Williams         auto str = "jkl;"s;
171*4fe85a30SPatrick Williams         auto str2 = "JKL:"s;
172*4fe85a30SPatrick Williams         m.append(1, "asdf", "ASDF"s, str,
173*4fe85a30SPatrick Williams                  std::move(str2), 5);
174*4fe85a30SPatrick Williams         verifyTypeString = "issssi";
175*4fe85a30SPatrick Williams 
176*4fe85a30SPatrick Williams         struct verify
177*4fe85a30SPatrick Williams         {
178*4fe85a30SPatrick Williams             static void op(sdbusplus::message::message& m)
179*4fe85a30SPatrick Williams             {
180*4fe85a30SPatrick Williams                 int32_t a = 0, b = 0;
181*4fe85a30SPatrick Williams                 std::string s0, s1, s2, s3;
182*4fe85a30SPatrick Williams                 m.read(a, s0, s1, s2, s3, b);
183*4fe85a30SPatrick Williams                 assert(a == 1);
184*4fe85a30SPatrick Williams                 assert(b == 5);
185*4fe85a30SPatrick Williams                 assert(s0 == "asdf"s);
186*4fe85a30SPatrick Williams                 assert(s1 == "ASDF"s);
187*4fe85a30SPatrick Williams                 assert(s2 == "jkl;"s);
188*4fe85a30SPatrick Williams                 assert(s3 == "JKL:");
189*4fe85a30SPatrick Williams             }
190*4fe85a30SPatrick Williams         };
191*4fe85a30SPatrick Williams         verifyCallback = &verify::op;
192*4fe85a30SPatrick Williams 
193*4fe85a30SPatrick Williams         b.call_noreply(m);
194*4fe85a30SPatrick Williams     }
195*4fe85a30SPatrick Williams 
196*4fe85a30SPatrick Williams     // Shutdown server.
197*4fe85a30SPatrick Williams     {
198*4fe85a30SPatrick Williams         auto m = b.new_method_call(SERVICE, "/", INTERFACE, QUIT_METHOD);
199*4fe85a30SPatrick Williams         b.call_noreply(m);
200*4fe85a30SPatrick Williams     }
201*4fe85a30SPatrick Williams }
202*4fe85a30SPatrick Williams 
203*4fe85a30SPatrick Williams int main()
204*4fe85a30SPatrick Williams {
205*4fe85a30SPatrick Williams 
206*4fe85a30SPatrick Williams     // Initialize and start server thread.
207*4fe85a30SPatrick Williams     pthread_t t;
208*4fe85a30SPatrick Williams     {
209*4fe85a30SPatrick Williams         auto b = serverInit();
210*4fe85a30SPatrick Williams         pthread_create(&t, NULL, server, b.release());
211*4fe85a30SPatrick Williams     }
212*4fe85a30SPatrick Williams 
213*4fe85a30SPatrick Williams     runTests();
214*4fe85a30SPatrick Williams 
215*4fe85a30SPatrick Williams     // Wait for server thread to exit.
216*4fe85a30SPatrick Williams     pthread_join(t, NULL);
217*4fe85a30SPatrick Williams 
218*4fe85a30SPatrick Williams     return 0;
219*4fe85a30SPatrick Williams }
220