blob: 581f7d0085fb86d851200fbc64688c3a8bde1808 [file] [log] [blame]
Patrick Venture95269db2018-08-31 09:19:17 -07001#include <systemd/sd-bus-protocol.h>
2
William A. Kennington III13367e42018-06-26 15:23:13 -07003#include <sdbusplus/exception.hpp>
Patrick Williams4fe85a32016-09-08 15:03:56 -05004#include <sdbusplus/message.hpp>
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -07005#include <sdbusplus/test/sdbus_mock.hpp>
Patrick Williams127b8ab2020-05-21 15:24:19 -05006
7#include <cerrno>
8#include <map>
Ed Tanous28dc36d2018-02-21 12:22:54 -08009#include <set>
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -070010#include <string>
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -070011#include <tuple>
12#include <unordered_map>
Patrick Williamsb98bdc62020-06-16 16:15:40 -050013#include <unordered_set>
William A. Kennington III4274c112018-11-26 09:50:13 -080014#include <variant>
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -070015#include <vector>
Patrick Williams4fe85a32016-09-08 15:03:56 -050016
Patrick Venture95269db2018-08-31 09:19:17 -070017#include <gmock/gmock.h>
18#include <gtest/gtest.h>
19
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -070020namespace
Patrick Williams4fe85a32016-09-08 15:03:56 -050021{
Patrick Williams4fe85a32016-09-08 15:03:56 -050022
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -070023using testing::DoAll;
Ed Tanous242677a2024-03-27 17:56:21 -070024using testing::ElementsAre;
25using testing::Invoke;
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -070026using testing::Return;
27using testing::StrEq;
28
29ACTION_TEMPLATE(AssignReadVal, HAS_1_TEMPLATE_PARAMS(typename, T),
30 AND_1_VALUE_PARAMS(val))
31{
William A. Kennington IIIe0d69652018-08-31 13:09:47 -070032 *static_cast<T*>(arg2) = val;
Patrick Williams4fe85a32016-09-08 15:03:56 -050033}
34
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -070035class ReadTest : public testing::Test
Patrick Williams4fe85a32016-09-08 15:03:56 -050036{
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -070037 protected:
38 testing::StrictMock<sdbusplus::SdBusMock> mock;
Patrick Williams4fe85a32016-09-08 15:03:56 -050039
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -070040 void SetUp() override
Patrick Williams4fe85a32016-09-08 15:03:56 -050041 {
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -070042 EXPECT_CALL(mock, sd_bus_message_new_method_call(testing::_, testing::_,
43 nullptr, nullptr,
44 nullptr, nullptr))
45 .WillRepeatedly(Return(0));
Ed Tanouscb2fbeb2023-01-06 13:16:19 -080046 }
Patrick Williams4fe85a32016-09-08 15:03:56 -050047
Patrick Williams10d7aa12021-11-19 11:36:18 -060048 sdbusplus::message_t new_message()
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -070049 {
50 return sdbusplus::get_mocked_new(&mock).new_method_call(
51 nullptr, nullptr, nullptr, nullptr);
52 }
53
William A. Kennington III13367e42018-06-26 15:23:13 -070054 void expect_basic_error(char type, int ret)
55 {
56 EXPECT_CALL(mock, sd_bus_message_read_basic(nullptr, type, testing::_))
57 .WillOnce(Return(ret));
58 }
59
Patrick Venture2b238af2018-08-31 12:45:01 -070060 template <typename T>
61 void expect_basic(char type, T val)
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -070062 {
63 EXPECT_CALL(mock, sd_bus_message_read_basic(nullptr, type, testing::_))
64 .WillOnce(DoAll(AssignReadVal<T>(val), Return(0)));
65 }
66
Ed Tanous242677a2024-03-27 17:56:21 -070067 template <typename T>
68 static void read_array_callback(sd_bus_message*, char, const void** p,
69 size_t* sz)
70 {
71 static const std::array<T, 3> arr{std::numeric_limits<T>::min(), 0,
72 std::numeric_limits<T>::max()};
73
74 *p = arr.data();
75 *sz = arr.size() * sizeof(T);
76 }
77
78 template <typename T>
79 void expect_read_array(char type)
80 {
81 EXPECT_CALL(mock, sd_bus_message_read_array(nullptr, type, testing::_,
82 testing::_))
83 .WillOnce(
84 DoAll(testing::Invoke(read_array_callback<T>), Return(0)));
85 }
86
William A. Kennington IIIe0d69652018-08-31 13:09:47 -070087 void expect_verify_type(char type, const char* contents, int ret)
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -070088 {
89 EXPECT_CALL(mock,
90 sd_bus_message_verify_type(nullptr, type, StrEq(contents)))
91 .WillOnce(Return(ret));
92 }
93
94 void expect_at_end(bool complete, int ret)
95 {
96 EXPECT_CALL(mock, sd_bus_message_at_end(nullptr, complete))
97 .WillOnce(Return(ret));
98 }
99
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700100 void expect_skip(const char* contents, int ret = 0)
William A. Kennington III60a72832018-06-26 14:31:15 -0700101 {
102 EXPECT_CALL(mock, sd_bus_message_skip(nullptr, StrEq(contents)))
William A. Kennington III13367e42018-06-26 15:23:13 -0700103 .WillOnce(Return(ret));
William A. Kennington III60a72832018-06-26 14:31:15 -0700104 }
105
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700106 void expect_enter_container(char type, const char* contents, int ret = 0)
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700107 {
108 EXPECT_CALL(mock, sd_bus_message_enter_container(nullptr, type,
109 StrEq(contents)))
William A. Kennington III13367e42018-06-26 15:23:13 -0700110 .WillOnce(Return(ret));
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700111 }
112
William A. Kennington III13367e42018-06-26 15:23:13 -0700113 void expect_exit_container(int ret = 0)
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700114 {
115 EXPECT_CALL(mock, sd_bus_message_exit_container(nullptr))
William A. Kennington III13367e42018-06-26 15:23:13 -0700116 .WillOnce(Return(ret));
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700117 }
118};
119
120TEST_F(ReadTest, Int)
121{
122 const int i = 1;
123 expect_basic<int>(SD_BUS_TYPE_INT32, i);
124 int ret;
125 new_message().read(ret);
126 EXPECT_EQ(i, ret);
127}
128
129TEST_F(ReadTest, Bool)
130{
131 const bool b = true;
132 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, b);
133 bool ret;
134 new_message().read(ret);
135 EXPECT_EQ(b, ret);
136}
137
138TEST_F(ReadTest, Double)
139{
140 const double d = 1.1;
141 expect_basic<double>(SD_BUS_TYPE_DOUBLE, d);
142 double ret;
143 new_message().read(ret);
144 EXPECT_EQ(d, ret);
145}
146
147TEST_F(ReadTest, CString)
148{
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700149 const char* const s = "asdf";
150 expect_basic<const char*>(SD_BUS_TYPE_STRING, s);
151 const char* ret;
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700152 new_message().read(ret);
153 EXPECT_EQ(s, ret);
154}
155
156TEST_F(ReadTest, String)
157{
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700158 const char* const s = "fsda";
159 expect_basic<const char*>(SD_BUS_TYPE_STRING, s);
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700160 std::string ret;
161 new_message().read(ret);
162 // Pointer comparison here is intentional as we don't expect a copy
163 EXPECT_EQ(s, ret);
164}
165
166TEST_F(ReadTest, ObjectPath)
167{
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700168 const char* const s = "/fsda";
169 expect_basic<const char*>(SD_BUS_TYPE_OBJECT_PATH, s);
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700170 sdbusplus::message::object_path ret;
171 new_message().read(ret);
172 EXPECT_EQ(s, ret.str);
173}
174
175TEST_F(ReadTest, Signature)
176{
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700177 const char* const s = "{ii}";
178 expect_basic<const char*>(SD_BUS_TYPE_SIGNATURE, s);
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700179 sdbusplus::message::signature ret;
180 new_message().read(ret);
181 EXPECT_EQ(s, ret.str);
182}
183
Patrick Williams7770d2b2023-07-25 18:38:32 -0500184TEST_F(ReadTest, UnixFd)
185{
186 const int fd = 42;
187 expect_basic<int>(SD_BUS_TYPE_UNIX_FD, fd);
188 sdbusplus::message::unix_fd ret;
189 new_message().read(ret);
190 EXPECT_EQ(fd, ret);
191}
192
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700193TEST_F(ReadTest, CombinedBasic)
194{
195 const double a = 2.2;
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700196 const char* const b = "ijkd";
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700197 const bool c = false;
198 const int d = 18;
199
200 {
201 testing::InSequence seq;
202 expect_basic<double>(SD_BUS_TYPE_DOUBLE, a);
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700203 expect_basic<const char*>(SD_BUS_TYPE_STRING, b);
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700204 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, c);
205 expect_basic<int>(SD_BUS_TYPE_INT32, d);
206 }
207
208 double ret_a;
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700209 const char* ret_b;
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700210 bool ret_c;
211 int ret_d;
212 new_message().read(ret_a, ret_b, ret_c, ret_d);
213 EXPECT_EQ(a, ret_a);
214 EXPECT_EQ(b, ret_b);
215 EXPECT_EQ(c, ret_c);
216 EXPECT_EQ(d, ret_d);
217}
218
William A. Kennington III13367e42018-06-26 15:23:13 -0700219TEST_F(ReadTest, BasicError)
220{
221 expect_basic_error(SD_BUS_TYPE_INT32, -EINVAL);
222 int ret;
223 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
224}
225
226TEST_F(ReadTest, BasicStringError)
227{
228 expect_basic_error(SD_BUS_TYPE_STRING, -EINVAL);
229 std::string ret;
230 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
231}
232
233TEST_F(ReadTest, BasicStringWrapperError)
234{
235 expect_basic_error(SD_BUS_TYPE_SIGNATURE, -EINVAL);
236 sdbusplus::message::signature ret;
237 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
238}
239
240TEST_F(ReadTest, BasicBoolError)
241{
242 expect_basic_error(SD_BUS_TYPE_BOOLEAN, -EINVAL);
243 bool ret;
244 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
245}
246
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700247TEST_F(ReadTest, Vector)
248{
Ed Tanousf4265a72024-03-04 21:07:05 -0800249 const std::vector<std::string> vs{"1", "2", "3", "4"};
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700250
251 {
252 testing::InSequence seq;
Ed Tanousf4265a72024-03-04 21:07:05 -0800253 expect_enter_container(SD_BUS_TYPE_ARRAY, "s");
254 for (const auto& i : vs)
Patrick Williams4fe85a32016-09-08 15:03:56 -0500255 {
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700256 expect_at_end(false, 0);
Ed Tanousf4265a72024-03-04 21:07:05 -0800257 expect_basic<const char*>(SD_BUS_TYPE_STRING, i.c_str());
Patrick Williams4fe85a32016-09-08 15:03:56 -0500258 }
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700259 expect_at_end(false, 1);
260 expect_exit_container();
261 }
Patrick Williams4fe85a32016-09-08 15:03:56 -0500262
Ed Tanousf4265a72024-03-04 21:07:05 -0800263 std::vector<std::string> ret_vs;
264 new_message().read(ret_vs);
265 EXPECT_EQ(vs, ret_vs);
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700266}
267
Ed Tanous242677a2024-03-27 17:56:21 -0700268TEST_F(ReadTest, VectorUnsignedIntegral8)
269{
270 expect_read_array<uint8_t>(SD_BUS_TYPE_BYTE);
271 std::vector<uint8_t> ret_vi;
272 new_message().read(ret_vi);
273 EXPECT_THAT(ret_vi, ElementsAre(0, 0, 255));
274}
275
276TEST_F(ReadTest, VectorIntegral32)
277{
278 expect_read_array<int32_t>(SD_BUS_TYPE_INT32);
279 std::vector<int32_t> ret_vi;
280 new_message().read(ret_vi);
281 EXPECT_THAT(ret_vi, ElementsAre(-2147483648, 0, 2147483647));
282}
283
284TEST_F(ReadTest, VectorIntegral64)
285{
286 expect_read_array<int64_t>(SD_BUS_TYPE_INT64);
287 std::vector<int64_t> ret_vi;
288 new_message().read(ret_vi);
289 EXPECT_THAT(ret_vi, ElementsAre(-9223372036854775807LL - 1, 0,
290 9223372036854775807LL));
291}
292
293TEST_F(ReadTest, VectorUnsignedIntegral32)
294{
295 expect_read_array<uint32_t>(SD_BUS_TYPE_UINT32);
296 std::vector<uint32_t> ret_vi;
297 new_message().read(ret_vi);
298 EXPECT_THAT(ret_vi, ElementsAre(0, 0, 4294967295));
299}
300
301TEST_F(ReadTest, VectorUnsignedIntegral64)
302{
303 expect_read_array<uint64_t>(SD_BUS_TYPE_UINT64);
304 std::vector<uint64_t> ret_vi;
305 new_message().read(ret_vi);
306 EXPECT_THAT(ret_vi, ElementsAre(0, 0, 18446744073709551615ULL));
307}
308
309TEST_F(ReadTest, VectorDouble)
310{
311 expect_read_array<double>(SD_BUS_TYPE_DOUBLE);
312 std::vector<double> ret_vi;
313 new_message().read(ret_vi);
314 EXPECT_THAT(ret_vi, ElementsAre(2.2250738585072014e-308, 0,
315 1.7976931348623157e+308));
316}
317
William A. Kennington III13367e42018-06-26 15:23:13 -0700318TEST_F(ReadTest, VectorEnterError)
319{
320 {
321 testing::InSequence seq;
Ed Tanousf4265a72024-03-04 21:07:05 -0800322 expect_enter_container(SD_BUS_TYPE_ARRAY, "s", -EINVAL);
William A. Kennington III13367e42018-06-26 15:23:13 -0700323 }
324
Ed Tanousf4265a72024-03-04 21:07:05 -0800325 std::vector<std::string> ret;
William A. Kennington III13367e42018-06-26 15:23:13 -0700326 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
327}
328
329TEST_F(ReadTest, VectorIterError)
330{
331 {
332 testing::InSequence seq;
Ed Tanousf4265a72024-03-04 21:07:05 -0800333 expect_enter_container(SD_BUS_TYPE_ARRAY, "s");
William A. Kennington III13367e42018-06-26 15:23:13 -0700334 expect_at_end(false, 0);
Ed Tanousf4265a72024-03-04 21:07:05 -0800335 expect_basic<const char*>(SD_BUS_TYPE_STRING, "1");
William A. Kennington III13367e42018-06-26 15:23:13 -0700336 expect_at_end(false, -EINVAL);
337 }
338
Ed Tanousf4265a72024-03-04 21:07:05 -0800339 std::vector<std::string> ret;
William A. Kennington III13367e42018-06-26 15:23:13 -0700340 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
341}
342
343TEST_F(ReadTest, VectorExitError)
344{
345 {
346 testing::InSequence seq;
Ed Tanousf4265a72024-03-04 21:07:05 -0800347 expect_enter_container(SD_BUS_TYPE_ARRAY, "s");
William A. Kennington III13367e42018-06-26 15:23:13 -0700348 expect_at_end(false, 0);
Ed Tanousf4265a72024-03-04 21:07:05 -0800349 expect_basic<const char*>(SD_BUS_TYPE_STRING, "1");
William A. Kennington III13367e42018-06-26 15:23:13 -0700350 expect_at_end(false, 0);
Ed Tanousf4265a72024-03-04 21:07:05 -0800351 expect_basic<const char*>(SD_BUS_TYPE_STRING, "2");
William A. Kennington III13367e42018-06-26 15:23:13 -0700352 expect_at_end(false, 1);
353 expect_exit_container(-EINVAL);
354 }
355
Ed Tanousf4265a72024-03-04 21:07:05 -0800356 std::vector<std::string> ret;
William A. Kennington III13367e42018-06-26 15:23:13 -0700357 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
358}
359
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700360TEST_F(ReadTest, Set)
361{
362 const std::set<std::string> ss{"one", "two", "eight"};
363
364 {
365 testing::InSequence seq;
366 expect_enter_container(SD_BUS_TYPE_ARRAY, "s");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700367 for (const auto& s : ss)
Patrick Williams4fe85a32016-09-08 15:03:56 -0500368 {
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700369 expect_at_end(false, 0);
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700370 expect_basic<const char*>(SD_BUS_TYPE_STRING, s.c_str());
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700371 }
372 expect_at_end(false, 1);
373 expect_exit_container();
374 }
Patrick Williams4fe85a32016-09-08 15:03:56 -0500375
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700376 std::set<std::string> ret_ss;
377 new_message().read(ret_ss);
378 EXPECT_EQ(ss, ret_ss);
379}
380
Patrick Williamsb98bdc62020-06-16 16:15:40 -0500381TEST_F(ReadTest, UnorderedSet)
382{
383 const std::unordered_set<std::string> ss{"one", "two", "eight"};
384
385 {
386 testing::InSequence seq;
387 expect_enter_container(SD_BUS_TYPE_ARRAY, "s");
388 for (const auto& s : ss)
389 {
390 expect_at_end(false, 0);
391 expect_basic<const char*>(SD_BUS_TYPE_STRING, s.c_str());
392 }
393 expect_at_end(false, 1);
394 expect_exit_container();
395 }
396
397 std::unordered_set<std::string> ret_ss;
398 new_message().read(ret_ss);
399 EXPECT_EQ(ss, ret_ss);
400}
401
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700402TEST_F(ReadTest, Map)
403{
404 const std::map<int, std::string> mis{
405 {1, "a"},
406 {2, "bc"},
407 {3, "def"},
408 {4, "ghij"},
409 };
410
411 {
412 testing::InSequence seq;
413 expect_enter_container(SD_BUS_TYPE_ARRAY, "{is}");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700414 for (const auto& is : mis)
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700415 {
416 expect_at_end(false, 0);
417 expect_enter_container(SD_BUS_TYPE_DICT_ENTRY, "is");
418 expect_basic<int>(SD_BUS_TYPE_INT32, is.first);
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700419 expect_basic<const char*>(SD_BUS_TYPE_STRING, is.second.c_str());
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700420 expect_exit_container();
421 }
422 expect_at_end(false, 1);
423 expect_exit_container();
424 }
425
426 std::map<int, std::string> ret_mis;
427 new_message().read(ret_mis);
428 EXPECT_EQ(mis, ret_mis);
429}
430
William A. Kennington III13367e42018-06-26 15:23:13 -0700431TEST_F(ReadTest, MapEnterError)
432{
433 {
434 testing::InSequence seq;
435 expect_enter_container(SD_BUS_TYPE_ARRAY, "{si}", -EINVAL);
436 }
437
438 std::map<std::string, int> ret;
439 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
440}
441
442TEST_F(ReadTest, MapEntryEnterError)
443{
444 {
445 testing::InSequence seq;
446 expect_enter_container(SD_BUS_TYPE_ARRAY, "{si}");
447 expect_at_end(false, 0);
448 expect_enter_container(SD_BUS_TYPE_DICT_ENTRY, "si", -EINVAL);
449 }
450
451 std::map<std::string, int> ret;
452 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
453}
454
455TEST_F(ReadTest, MapEntryExitError)
456{
457 {
458 testing::InSequence seq;
459 expect_enter_container(SD_BUS_TYPE_ARRAY, "{si}");
460 expect_at_end(false, 0);
461 expect_enter_container(SD_BUS_TYPE_DICT_ENTRY, "si");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700462 expect_basic<const char*>(SD_BUS_TYPE_STRING, "ab");
William A. Kennington III13367e42018-06-26 15:23:13 -0700463 expect_basic<int>(SD_BUS_TYPE_INT32, 1);
464 expect_exit_container(-EINVAL);
465 }
466
467 std::map<std::string, int> ret;
468 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
469}
470
471TEST_F(ReadTest, MapIterError)
472{
473 {
474 testing::InSequence seq;
475 expect_enter_container(SD_BUS_TYPE_ARRAY, "{si}");
476 expect_at_end(false, 0);
477 expect_enter_container(SD_BUS_TYPE_DICT_ENTRY, "si");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700478 expect_basic<const char*>(SD_BUS_TYPE_STRING, "ab");
William A. Kennington III13367e42018-06-26 15:23:13 -0700479 expect_basic<int>(SD_BUS_TYPE_INT32, 1);
480 expect_exit_container();
481 expect_at_end(false, -EINVAL);
482 }
483
484 std::map<std::string, int> ret;
485 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
486}
487
488TEST_F(ReadTest, MapExitError)
489{
490 {
491 testing::InSequence seq;
492 expect_enter_container(SD_BUS_TYPE_ARRAY, "{si}");
493 expect_at_end(false, 0);
494 expect_enter_container(SD_BUS_TYPE_DICT_ENTRY, "si");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700495 expect_basic<const char*>(SD_BUS_TYPE_STRING, "ab");
William A. Kennington III13367e42018-06-26 15:23:13 -0700496 expect_basic<int>(SD_BUS_TYPE_INT32, 1);
497 expect_exit_container();
498 expect_at_end(false, 1);
499 expect_exit_container(-EINVAL);
500 }
501
502 std::map<std::string, int> ret;
503 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
504}
505
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700506TEST_F(ReadTest, UnorderedMap)
507{
508 const std::unordered_map<int, std::string> mis{
509 {1, "a"},
510 {2, "bc"},
511 {3, "def"},
512 {4, "ghij"},
513 };
514
515 {
516 testing::InSequence seq;
517 expect_enter_container(SD_BUS_TYPE_ARRAY, "{is}");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700518 for (const auto& is : mis)
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700519 {
520 expect_at_end(false, 0);
521 expect_enter_container(SD_BUS_TYPE_DICT_ENTRY, "is");
522 expect_basic<int>(SD_BUS_TYPE_INT32, is.first);
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700523 expect_basic<const char*>(SD_BUS_TYPE_STRING, is.second.c_str());
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700524 expect_exit_container();
525 }
526 expect_at_end(false, 1);
527 expect_exit_container();
528 }
529
530 std::unordered_map<int, std::string> ret_mis;
531 new_message().read(ret_mis);
532 EXPECT_EQ(mis, ret_mis);
533}
534
535TEST_F(ReadTest, Tuple)
536{
537 const std::tuple<int, std::string, bool> tisb{3, "hi", false};
538
539 {
540 testing::InSequence seq;
541 expect_enter_container(SD_BUS_TYPE_STRUCT, "isb");
542 expect_basic<int>(SD_BUS_TYPE_INT32, std::get<0>(tisb));
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700543 expect_basic<const char*>(SD_BUS_TYPE_STRING,
544 std::get<1>(tisb).c_str());
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700545 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, std::get<2>(tisb));
546 expect_exit_container();
547 }
548
549 std::tuple<int, std::string, bool> ret_tisb;
550 new_message().read(ret_tisb);
551 EXPECT_EQ(tisb, ret_tisb);
552}
553
William A. Kennington III13367e42018-06-26 15:23:13 -0700554TEST_F(ReadTest, TupleEnterError)
555{
556 {
557 testing::InSequence seq;
558 expect_enter_container(SD_BUS_TYPE_STRUCT, "bis", -EINVAL);
559 }
560
561 std::tuple<bool, int, std::string> ret;
562 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
563}
564
565TEST_F(ReadTest, TupleExitError)
566{
567 {
568 testing::InSequence seq;
569 expect_enter_container(SD_BUS_TYPE_STRUCT, "bis");
570 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, false);
571 expect_basic<int>(SD_BUS_TYPE_INT32, 1);
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700572 expect_basic<const char*>(SD_BUS_TYPE_STRING, "ab");
William A. Kennington III13367e42018-06-26 15:23:13 -0700573 expect_exit_container(-EINVAL);
574 }
575
576 std::tuple<bool, int, std::string> ret;
577 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
578}
579
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700580TEST_F(ReadTest, Variant)
581{
582 const bool b1 = false;
583 const std::string s2{"asdf"};
William A. Kennington III4274c112018-11-26 09:50:13 -0800584 const std::variant<int, std::string, bool> v1{b1}, v2{s2};
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700585
586 {
587 testing::InSequence seq;
588 expect_verify_type(SD_BUS_TYPE_VARIANT, "i", false);
589 expect_verify_type(SD_BUS_TYPE_VARIANT, "s", false);
590 expect_verify_type(SD_BUS_TYPE_VARIANT, "b", true);
591 expect_enter_container(SD_BUS_TYPE_VARIANT, "b");
592 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, b1);
593 expect_exit_container();
594 expect_verify_type(SD_BUS_TYPE_VARIANT, "i", false);
595 expect_verify_type(SD_BUS_TYPE_VARIANT, "s", true);
596 expect_enter_container(SD_BUS_TYPE_VARIANT, "s");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700597 expect_basic<const char*>(SD_BUS_TYPE_STRING, s2.c_str());
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700598 expect_exit_container();
599 }
600
William A. Kennington III4274c112018-11-26 09:50:13 -0800601 std::variant<int, std::string, bool> ret_v1, ret_v2;
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700602 new_message().read(ret_v1, ret_v2);
603 EXPECT_EQ(v1, ret_v1);
604 EXPECT_EQ(v2, ret_v2);
605}
606
William A. Kennington III13367e42018-06-26 15:23:13 -0700607TEST_F(ReadTest, VariantVerifyError)
608{
609 {
610 testing::InSequence seq;
611 expect_verify_type(SD_BUS_TYPE_VARIANT, "i", -EINVAL);
612 }
613
William A. Kennington III4274c112018-11-26 09:50:13 -0800614 std::variant<int, bool> ret;
William A. Kennington III13367e42018-06-26 15:23:13 -0700615 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
616}
617
William A. Kennington III60a72832018-06-26 14:31:15 -0700618TEST_F(ReadTest, VariantSkipUnmatched)
619{
620 {
621 testing::InSequence seq;
622 expect_verify_type(SD_BUS_TYPE_VARIANT, "i", false);
623 expect_verify_type(SD_BUS_TYPE_VARIANT, "b", false);
624 expect_skip("v");
625 }
William A. Kennington III13367e42018-06-26 15:23:13 -0700626
William A. Kennington III4274c112018-11-26 09:50:13 -0800627 std::variant<int, bool> ret;
William A. Kennington III60a72832018-06-26 14:31:15 -0700628 new_message().read(ret);
629}
630
William A. Kennington III13367e42018-06-26 15:23:13 -0700631TEST_F(ReadTest, VariantSkipError)
632{
633 {
634 testing::InSequence seq;
635 expect_verify_type(SD_BUS_TYPE_VARIANT, "i", false);
636 expect_verify_type(SD_BUS_TYPE_VARIANT, "b", false);
637 expect_skip("v", -EINVAL);
638 }
639
William A. Kennington III4274c112018-11-26 09:50:13 -0800640 std::variant<int, bool> ret;
William A. Kennington III13367e42018-06-26 15:23:13 -0700641 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
642}
643
644TEST_F(ReadTest, VariantEnterError)
645{
646 {
647 testing::InSequence seq;
648 expect_verify_type(SD_BUS_TYPE_VARIANT, "i", true);
649 expect_enter_container(SD_BUS_TYPE_VARIANT, "i", -EINVAL);
650 }
651
William A. Kennington III4274c112018-11-26 09:50:13 -0800652 std::variant<int, bool> ret;
William A. Kennington III13367e42018-06-26 15:23:13 -0700653 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
654}
655
656TEST_F(ReadTest, VariantExitError)
657{
658 {
659 testing::InSequence seq;
660 expect_verify_type(SD_BUS_TYPE_VARIANT, "i", true);
661 expect_enter_container(SD_BUS_TYPE_VARIANT, "i");
662 expect_basic<int>(SD_BUS_TYPE_INT32, 10);
663 expect_exit_container(-EINVAL);
664 }
665
William A. Kennington III4274c112018-11-26 09:50:13 -0800666 std::variant<int, bool> ret;
William A. Kennington III13367e42018-06-26 15:23:13 -0700667 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
668}
669
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700670TEST_F(ReadTest, LargeCombo)
671{
672 const std::vector<std::set<std::string>> vas{
673 {"a", "b", "c"},
674 {"d", "", "e"},
675 };
William A. Kennington III4274c112018-11-26 09:50:13 -0800676 const std::map<std::string, std::variant<int, double>> msv = {
677 {"a", 3.3}, {"b", 1}, {"c", 4.4}};
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700678
679 {
680 testing::InSequence seq;
681
682 expect_enter_container(SD_BUS_TYPE_ARRAY, "as");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700683 for (const auto& as : vas)
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700684 {
685 expect_at_end(false, 0);
686 expect_enter_container(SD_BUS_TYPE_ARRAY, "s");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700687 for (const auto& s : as)
Patrick Williams4fe85a32016-09-08 15:03:56 -0500688 {
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700689 expect_at_end(false, 0);
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700690 expect_basic<const char*>(SD_BUS_TYPE_STRING, s.c_str());
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700691 }
692 expect_at_end(false, 1);
693 expect_exit_container();
694 }
695 expect_at_end(false, 1);
696 expect_exit_container();
Patrick Williams4fe85a32016-09-08 15:03:56 -0500697
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700698 expect_enter_container(SD_BUS_TYPE_ARRAY, "{sv}");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700699 for (const auto& sv : msv)
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700700 {
701 expect_at_end(false, 0);
702 expect_enter_container(SD_BUS_TYPE_DICT_ENTRY, "sv");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700703 expect_basic<const char*>(SD_BUS_TYPE_STRING, sv.first.c_str());
William A. Kennington III4274c112018-11-26 09:50:13 -0800704 if (std::holds_alternative<int>(sv.second))
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700705 {
706 expect_verify_type(SD_BUS_TYPE_VARIANT, "i", true);
707 expect_enter_container(SD_BUS_TYPE_VARIANT, "i");
William A. Kennington III4274c112018-11-26 09:50:13 -0800708 expect_basic<int>(SD_BUS_TYPE_INT32, std::get<int>(sv.second));
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700709 expect_exit_container();
Patrick Williams4fe85a32016-09-08 15:03:56 -0500710 }
711 else
712 {
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700713 expect_verify_type(SD_BUS_TYPE_VARIANT, "i", false);
714 expect_verify_type(SD_BUS_TYPE_VARIANT, "d", true);
715 expect_enter_container(SD_BUS_TYPE_VARIANT, "d");
716 expect_basic<double>(SD_BUS_TYPE_DOUBLE,
William A. Kennington III4274c112018-11-26 09:50:13 -0800717 std::get<double>(sv.second));
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700718 expect_exit_container();
Patrick Williams4fe85a32016-09-08 15:03:56 -0500719 }
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700720 expect_exit_container();
Patrick Williams4fe85a32016-09-08 15:03:56 -0500721 }
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700722 expect_at_end(false, 1);
723 expect_exit_container();
Patrick Williams4fe85a32016-09-08 15:03:56 -0500724 }
Patrick Williams696e3152016-11-04 17:03:39 -0500725
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700726 std::vector<std::set<std::string>> ret_vas;
William A. Kennington III4274c112018-11-26 09:50:13 -0800727 std::map<std::string, std::variant<int, double>> ret_msv;
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700728 new_message().read(ret_vas, ret_msv);
729 EXPECT_EQ(vas, ret_vas);
730 EXPECT_EQ(msv, ret_msv);
Patrick Williams4fe85a32016-09-08 15:03:56 -0500731}
732
Patrick Williams9cde21f2022-08-29 10:33:27 -0500733// Unpack tests.
734// Since unpack uses read, we're mostly just testing the compilation.
735// Duplicate a few tests from Read using 'unpack'.
736
737TEST_F(ReadTest, UnpackSingleVector)
738{
Ed Tanousf4265a72024-03-04 21:07:05 -0800739 const std::vector<std::string> vs{"a", "b", "c", "d"};
Patrick Williams9cde21f2022-08-29 10:33:27 -0500740
741 {
742 testing::InSequence seq;
Ed Tanousf4265a72024-03-04 21:07:05 -0800743 expect_enter_container(SD_BUS_TYPE_ARRAY, "s");
744 for (const auto& i : vs)
Patrick Williams9cde21f2022-08-29 10:33:27 -0500745 {
746 expect_at_end(false, 0);
Ed Tanousf4265a72024-03-04 21:07:05 -0800747 expect_basic<const char*>(SD_BUS_TYPE_STRING, i.c_str());
Patrick Williams9cde21f2022-08-29 10:33:27 -0500748 }
749 expect_at_end(false, 1);
750 expect_exit_container();
751 }
752
Ed Tanousf4265a72024-03-04 21:07:05 -0800753 auto ret_vs = new_message().unpack<std::vector<std::string>>();
754 EXPECT_EQ(vs, ret_vs);
Patrick Williams9cde21f2022-08-29 10:33:27 -0500755}
756
757TEST_F(ReadTest, UnpackMultiple)
758{
759 const std::tuple<int, std::string, bool> tisb{3, "hi", false};
760
761 {
762 testing::InSequence seq;
763 expect_basic<int>(SD_BUS_TYPE_INT32, std::get<0>(tisb));
764 expect_basic<const char*>(SD_BUS_TYPE_STRING,
765 std::get<1>(tisb).c_str());
766 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, std::get<2>(tisb));
767 }
768
769 auto ret_tisb = new_message().unpack<int, std::string, bool>();
770 EXPECT_EQ(tisb, ret_tisb);
771}
772
Patrick Williams5f1c0bd2023-11-28 10:33:44 -0600773TEST_F(ReadTest, UnpackStructuredBinding)
774{
775 const std::tuple<int, std::string, bool> tisb{3, "hi", false};
776
777 {
778 testing::InSequence seq;
779 expect_basic<int>(SD_BUS_TYPE_INT32, std::get<0>(tisb));
780 expect_basic<const char*>(SD_BUS_TYPE_STRING,
781 std::get<1>(tisb).c_str());
782 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, std::get<2>(tisb));
783 }
784
785 auto [ret_ti, ret_ts,
786 ret_tb] = new_message().unpack<int, std::string, bool>();
787 EXPECT_EQ(tisb, std::make_tuple(ret_ti, ret_ts, ret_tb));
788}
789
Lei YU88c6a822024-09-11 03:59:47 +0000790TEST_F(ReadTest, UnpackVoid)
791{
792 new_message().unpack<>();
793 new_message().unpack<void>();
794}
795
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700796} // namespace