blob: c930372e02b3b199cad5840cc1d1fe306d501431 [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;
24using testing::Return;
25using testing::StrEq;
26
27ACTION_TEMPLATE(AssignReadVal, HAS_1_TEMPLATE_PARAMS(typename, T),
28 AND_1_VALUE_PARAMS(val))
29{
William A. Kennington IIIe0d69652018-08-31 13:09:47 -070030 *static_cast<T*>(arg2) = val;
Patrick Williams4fe85a32016-09-08 15:03:56 -050031}
32
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -070033class ReadTest : public testing::Test
Patrick Williams4fe85a32016-09-08 15:03:56 -050034{
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -070035 protected:
36 testing::StrictMock<sdbusplus::SdBusMock> mock;
Patrick Williams4fe85a32016-09-08 15:03:56 -050037
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -070038 void SetUp() override
Patrick Williams4fe85a32016-09-08 15:03:56 -050039 {
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -070040 EXPECT_CALL(mock, sd_bus_message_new_method_call(testing::_, testing::_,
41 nullptr, nullptr,
42 nullptr, nullptr))
43 .WillRepeatedly(Return(0));
Ed Tanouscb2fbeb2023-01-06 13:16:19 -080044 }
Patrick Williams4fe85a32016-09-08 15:03:56 -050045
Patrick Williams10d7aa12021-11-19 11:36:18 -060046 sdbusplus::message_t new_message()
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -070047 {
48 return sdbusplus::get_mocked_new(&mock).new_method_call(
49 nullptr, nullptr, nullptr, nullptr);
50 }
51
William A. Kennington III13367e42018-06-26 15:23:13 -070052 void expect_basic_error(char type, int ret)
53 {
54 EXPECT_CALL(mock, sd_bus_message_read_basic(nullptr, type, testing::_))
55 .WillOnce(Return(ret));
56 }
57
Patrick Venture2b238af2018-08-31 12:45:01 -070058 template <typename T>
59 void expect_basic(char type, T val)
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -070060 {
61 EXPECT_CALL(mock, sd_bus_message_read_basic(nullptr, type, testing::_))
62 .WillOnce(DoAll(AssignReadVal<T>(val), Return(0)));
63 }
64
William A. Kennington IIIe0d69652018-08-31 13:09:47 -070065 void expect_verify_type(char type, const char* contents, int ret)
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -070066 {
67 EXPECT_CALL(mock,
68 sd_bus_message_verify_type(nullptr, type, StrEq(contents)))
69 .WillOnce(Return(ret));
70 }
71
72 void expect_at_end(bool complete, int ret)
73 {
74 EXPECT_CALL(mock, sd_bus_message_at_end(nullptr, complete))
75 .WillOnce(Return(ret));
76 }
77
William A. Kennington IIIe0d69652018-08-31 13:09:47 -070078 void expect_skip(const char* contents, int ret = 0)
William A. Kennington III60a72832018-06-26 14:31:15 -070079 {
80 EXPECT_CALL(mock, sd_bus_message_skip(nullptr, StrEq(contents)))
William A. Kennington III13367e42018-06-26 15:23:13 -070081 .WillOnce(Return(ret));
William A. Kennington III60a72832018-06-26 14:31:15 -070082 }
83
William A. Kennington IIIe0d69652018-08-31 13:09:47 -070084 void expect_enter_container(char type, const char* contents, int ret = 0)
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -070085 {
86 EXPECT_CALL(mock, sd_bus_message_enter_container(nullptr, type,
87 StrEq(contents)))
William A. Kennington III13367e42018-06-26 15:23:13 -070088 .WillOnce(Return(ret));
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -070089 }
90
William A. Kennington III13367e42018-06-26 15:23:13 -070091 void expect_exit_container(int ret = 0)
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -070092 {
93 EXPECT_CALL(mock, sd_bus_message_exit_container(nullptr))
William A. Kennington III13367e42018-06-26 15:23:13 -070094 .WillOnce(Return(ret));
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -070095 }
96};
97
98TEST_F(ReadTest, Int)
99{
100 const int i = 1;
101 expect_basic<int>(SD_BUS_TYPE_INT32, i);
102 int ret;
103 new_message().read(ret);
104 EXPECT_EQ(i, ret);
105}
106
107TEST_F(ReadTest, Bool)
108{
109 const bool b = true;
110 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, b);
111 bool ret;
112 new_message().read(ret);
113 EXPECT_EQ(b, ret);
114}
115
116TEST_F(ReadTest, Double)
117{
118 const double d = 1.1;
119 expect_basic<double>(SD_BUS_TYPE_DOUBLE, d);
120 double ret;
121 new_message().read(ret);
122 EXPECT_EQ(d, ret);
123}
124
125TEST_F(ReadTest, CString)
126{
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700127 const char* const s = "asdf";
128 expect_basic<const char*>(SD_BUS_TYPE_STRING, s);
129 const char* ret;
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700130 new_message().read(ret);
131 EXPECT_EQ(s, ret);
132}
133
134TEST_F(ReadTest, String)
135{
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700136 const char* const s = "fsda";
137 expect_basic<const char*>(SD_BUS_TYPE_STRING, s);
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700138 std::string ret;
139 new_message().read(ret);
140 // Pointer comparison here is intentional as we don't expect a copy
141 EXPECT_EQ(s, ret);
142}
143
144TEST_F(ReadTest, ObjectPath)
145{
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700146 const char* const s = "/fsda";
147 expect_basic<const char*>(SD_BUS_TYPE_OBJECT_PATH, s);
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700148 sdbusplus::message::object_path ret;
149 new_message().read(ret);
150 EXPECT_EQ(s, ret.str);
151}
152
153TEST_F(ReadTest, Signature)
154{
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700155 const char* const s = "{ii}";
156 expect_basic<const char*>(SD_BUS_TYPE_SIGNATURE, s);
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700157 sdbusplus::message::signature ret;
158 new_message().read(ret);
159 EXPECT_EQ(s, ret.str);
160}
161
Patrick Williams7770d2b2023-07-25 18:38:32 -0500162TEST_F(ReadTest, UnixFd)
163{
164 const int fd = 42;
165 expect_basic<int>(SD_BUS_TYPE_UNIX_FD, fd);
166 sdbusplus::message::unix_fd ret;
167 new_message().read(ret);
168 EXPECT_EQ(fd, ret);
169}
170
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700171TEST_F(ReadTest, CombinedBasic)
172{
173 const double a = 2.2;
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700174 const char* const b = "ijkd";
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700175 const bool c = false;
176 const int d = 18;
177
178 {
179 testing::InSequence seq;
180 expect_basic<double>(SD_BUS_TYPE_DOUBLE, a);
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700181 expect_basic<const char*>(SD_BUS_TYPE_STRING, b);
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700182 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, c);
183 expect_basic<int>(SD_BUS_TYPE_INT32, d);
184 }
185
186 double ret_a;
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700187 const char* ret_b;
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700188 bool ret_c;
189 int ret_d;
190 new_message().read(ret_a, ret_b, ret_c, ret_d);
191 EXPECT_EQ(a, ret_a);
192 EXPECT_EQ(b, ret_b);
193 EXPECT_EQ(c, ret_c);
194 EXPECT_EQ(d, ret_d);
195}
196
William A. Kennington III13367e42018-06-26 15:23:13 -0700197TEST_F(ReadTest, BasicError)
198{
199 expect_basic_error(SD_BUS_TYPE_INT32, -EINVAL);
200 int ret;
201 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
202}
203
204TEST_F(ReadTest, BasicStringError)
205{
206 expect_basic_error(SD_BUS_TYPE_STRING, -EINVAL);
207 std::string ret;
208 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
209}
210
211TEST_F(ReadTest, BasicStringWrapperError)
212{
213 expect_basic_error(SD_BUS_TYPE_SIGNATURE, -EINVAL);
214 sdbusplus::message::signature ret;
215 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
216}
217
218TEST_F(ReadTest, BasicBoolError)
219{
220 expect_basic_error(SD_BUS_TYPE_BOOLEAN, -EINVAL);
221 bool ret;
222 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
223}
224
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700225TEST_F(ReadTest, Vector)
226{
227 const std::vector<int> vi{1, 2, 3, 4};
228
229 {
230 testing::InSequence seq;
231 expect_enter_container(SD_BUS_TYPE_ARRAY, "i");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700232 for (const auto& i : vi)
Patrick Williams4fe85a32016-09-08 15:03:56 -0500233 {
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700234 expect_at_end(false, 0);
235 expect_basic<int>(SD_BUS_TYPE_INT32, i);
Patrick Williams4fe85a32016-09-08 15:03:56 -0500236 }
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700237 expect_at_end(false, 1);
238 expect_exit_container();
239 }
Patrick Williams4fe85a32016-09-08 15:03:56 -0500240
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700241 std::vector<int> ret_vi;
242 new_message().read(ret_vi);
243 EXPECT_EQ(vi, ret_vi);
244}
245
William A. Kennington III13367e42018-06-26 15:23:13 -0700246TEST_F(ReadTest, VectorEnterError)
247{
248 {
249 testing::InSequence seq;
250 expect_enter_container(SD_BUS_TYPE_ARRAY, "i", -EINVAL);
251 }
252
253 std::vector<int> ret;
254 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
255}
256
257TEST_F(ReadTest, VectorIterError)
258{
259 {
260 testing::InSequence seq;
261 expect_enter_container(SD_BUS_TYPE_ARRAY, "i");
262 expect_at_end(false, 0);
263 expect_basic<int>(SD_BUS_TYPE_INT32, 1);
264 expect_at_end(false, -EINVAL);
265 }
266
267 std::vector<int> ret;
268 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
269}
270
271TEST_F(ReadTest, VectorExitError)
272{
273 {
274 testing::InSequence seq;
275 expect_enter_container(SD_BUS_TYPE_ARRAY, "i");
276 expect_at_end(false, 0);
277 expect_basic<int>(SD_BUS_TYPE_INT32, 1);
278 expect_at_end(false, 0);
279 expect_basic<int>(SD_BUS_TYPE_INT32, 2);
280 expect_at_end(false, 1);
281 expect_exit_container(-EINVAL);
282 }
283
284 std::vector<int> ret;
285 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
286}
287
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700288TEST_F(ReadTest, Set)
289{
290 const std::set<std::string> ss{"one", "two", "eight"};
291
292 {
293 testing::InSequence seq;
294 expect_enter_container(SD_BUS_TYPE_ARRAY, "s");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700295 for (const auto& s : ss)
Patrick Williams4fe85a32016-09-08 15:03:56 -0500296 {
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700297 expect_at_end(false, 0);
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700298 expect_basic<const char*>(SD_BUS_TYPE_STRING, s.c_str());
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700299 }
300 expect_at_end(false, 1);
301 expect_exit_container();
302 }
Patrick Williams4fe85a32016-09-08 15:03:56 -0500303
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700304 std::set<std::string> ret_ss;
305 new_message().read(ret_ss);
306 EXPECT_EQ(ss, ret_ss);
307}
308
Patrick Williamsb98bdc62020-06-16 16:15:40 -0500309TEST_F(ReadTest, UnorderedSet)
310{
311 const std::unordered_set<std::string> ss{"one", "two", "eight"};
312
313 {
314 testing::InSequence seq;
315 expect_enter_container(SD_BUS_TYPE_ARRAY, "s");
316 for (const auto& s : ss)
317 {
318 expect_at_end(false, 0);
319 expect_basic<const char*>(SD_BUS_TYPE_STRING, s.c_str());
320 }
321 expect_at_end(false, 1);
322 expect_exit_container();
323 }
324
325 std::unordered_set<std::string> ret_ss;
326 new_message().read(ret_ss);
327 EXPECT_EQ(ss, ret_ss);
328}
329
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700330TEST_F(ReadTest, Map)
331{
332 const std::map<int, std::string> mis{
333 {1, "a"},
334 {2, "bc"},
335 {3, "def"},
336 {4, "ghij"},
337 };
338
339 {
340 testing::InSequence seq;
341 expect_enter_container(SD_BUS_TYPE_ARRAY, "{is}");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700342 for (const auto& is : mis)
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700343 {
344 expect_at_end(false, 0);
345 expect_enter_container(SD_BUS_TYPE_DICT_ENTRY, "is");
346 expect_basic<int>(SD_BUS_TYPE_INT32, is.first);
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700347 expect_basic<const char*>(SD_BUS_TYPE_STRING, is.second.c_str());
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700348 expect_exit_container();
349 }
350 expect_at_end(false, 1);
351 expect_exit_container();
352 }
353
354 std::map<int, std::string> ret_mis;
355 new_message().read(ret_mis);
356 EXPECT_EQ(mis, ret_mis);
357}
358
William A. Kennington III13367e42018-06-26 15:23:13 -0700359TEST_F(ReadTest, MapEnterError)
360{
361 {
362 testing::InSequence seq;
363 expect_enter_container(SD_BUS_TYPE_ARRAY, "{si}", -EINVAL);
364 }
365
366 std::map<std::string, int> ret;
367 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
368}
369
370TEST_F(ReadTest, MapEntryEnterError)
371{
372 {
373 testing::InSequence seq;
374 expect_enter_container(SD_BUS_TYPE_ARRAY, "{si}");
375 expect_at_end(false, 0);
376 expect_enter_container(SD_BUS_TYPE_DICT_ENTRY, "si", -EINVAL);
377 }
378
379 std::map<std::string, int> ret;
380 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
381}
382
383TEST_F(ReadTest, MapEntryExitError)
384{
385 {
386 testing::InSequence seq;
387 expect_enter_container(SD_BUS_TYPE_ARRAY, "{si}");
388 expect_at_end(false, 0);
389 expect_enter_container(SD_BUS_TYPE_DICT_ENTRY, "si");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700390 expect_basic<const char*>(SD_BUS_TYPE_STRING, "ab");
William A. Kennington III13367e42018-06-26 15:23:13 -0700391 expect_basic<int>(SD_BUS_TYPE_INT32, 1);
392 expect_exit_container(-EINVAL);
393 }
394
395 std::map<std::string, int> ret;
396 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
397}
398
399TEST_F(ReadTest, MapIterError)
400{
401 {
402 testing::InSequence seq;
403 expect_enter_container(SD_BUS_TYPE_ARRAY, "{si}");
404 expect_at_end(false, 0);
405 expect_enter_container(SD_BUS_TYPE_DICT_ENTRY, "si");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700406 expect_basic<const char*>(SD_BUS_TYPE_STRING, "ab");
William A. Kennington III13367e42018-06-26 15:23:13 -0700407 expect_basic<int>(SD_BUS_TYPE_INT32, 1);
408 expect_exit_container();
409 expect_at_end(false, -EINVAL);
410 }
411
412 std::map<std::string, int> ret;
413 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
414}
415
416TEST_F(ReadTest, MapExitError)
417{
418 {
419 testing::InSequence seq;
420 expect_enter_container(SD_BUS_TYPE_ARRAY, "{si}");
421 expect_at_end(false, 0);
422 expect_enter_container(SD_BUS_TYPE_DICT_ENTRY, "si");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700423 expect_basic<const char*>(SD_BUS_TYPE_STRING, "ab");
William A. Kennington III13367e42018-06-26 15:23:13 -0700424 expect_basic<int>(SD_BUS_TYPE_INT32, 1);
425 expect_exit_container();
426 expect_at_end(false, 1);
427 expect_exit_container(-EINVAL);
428 }
429
430 std::map<std::string, int> ret;
431 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
432}
433
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700434TEST_F(ReadTest, UnorderedMap)
435{
436 const std::unordered_map<int, std::string> mis{
437 {1, "a"},
438 {2, "bc"},
439 {3, "def"},
440 {4, "ghij"},
441 };
442
443 {
444 testing::InSequence seq;
445 expect_enter_container(SD_BUS_TYPE_ARRAY, "{is}");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700446 for (const auto& is : mis)
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700447 {
448 expect_at_end(false, 0);
449 expect_enter_container(SD_BUS_TYPE_DICT_ENTRY, "is");
450 expect_basic<int>(SD_BUS_TYPE_INT32, is.first);
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700451 expect_basic<const char*>(SD_BUS_TYPE_STRING, is.second.c_str());
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700452 expect_exit_container();
453 }
454 expect_at_end(false, 1);
455 expect_exit_container();
456 }
457
458 std::unordered_map<int, std::string> ret_mis;
459 new_message().read(ret_mis);
460 EXPECT_EQ(mis, ret_mis);
461}
462
463TEST_F(ReadTest, Tuple)
464{
465 const std::tuple<int, std::string, bool> tisb{3, "hi", false};
466
467 {
468 testing::InSequence seq;
469 expect_enter_container(SD_BUS_TYPE_STRUCT, "isb");
470 expect_basic<int>(SD_BUS_TYPE_INT32, std::get<0>(tisb));
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700471 expect_basic<const char*>(SD_BUS_TYPE_STRING,
472 std::get<1>(tisb).c_str());
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700473 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, std::get<2>(tisb));
474 expect_exit_container();
475 }
476
477 std::tuple<int, std::string, bool> ret_tisb;
478 new_message().read(ret_tisb);
479 EXPECT_EQ(tisb, ret_tisb);
480}
481
William A. Kennington III13367e42018-06-26 15:23:13 -0700482TEST_F(ReadTest, TupleEnterError)
483{
484 {
485 testing::InSequence seq;
486 expect_enter_container(SD_BUS_TYPE_STRUCT, "bis", -EINVAL);
487 }
488
489 std::tuple<bool, int, std::string> ret;
490 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
491}
492
493TEST_F(ReadTest, TupleExitError)
494{
495 {
496 testing::InSequence seq;
497 expect_enter_container(SD_BUS_TYPE_STRUCT, "bis");
498 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, false);
499 expect_basic<int>(SD_BUS_TYPE_INT32, 1);
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700500 expect_basic<const char*>(SD_BUS_TYPE_STRING, "ab");
William A. Kennington III13367e42018-06-26 15:23:13 -0700501 expect_exit_container(-EINVAL);
502 }
503
504 std::tuple<bool, int, std::string> ret;
505 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
506}
507
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700508TEST_F(ReadTest, Variant)
509{
510 const bool b1 = false;
511 const std::string s2{"asdf"};
William A. Kennington III4274c112018-11-26 09:50:13 -0800512 const std::variant<int, std::string, bool> v1{b1}, v2{s2};
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700513
514 {
515 testing::InSequence seq;
516 expect_verify_type(SD_BUS_TYPE_VARIANT, "i", false);
517 expect_verify_type(SD_BUS_TYPE_VARIANT, "s", false);
518 expect_verify_type(SD_BUS_TYPE_VARIANT, "b", true);
519 expect_enter_container(SD_BUS_TYPE_VARIANT, "b");
520 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, b1);
521 expect_exit_container();
522 expect_verify_type(SD_BUS_TYPE_VARIANT, "i", false);
523 expect_verify_type(SD_BUS_TYPE_VARIANT, "s", true);
524 expect_enter_container(SD_BUS_TYPE_VARIANT, "s");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700525 expect_basic<const char*>(SD_BUS_TYPE_STRING, s2.c_str());
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700526 expect_exit_container();
527 }
528
William A. Kennington III4274c112018-11-26 09:50:13 -0800529 std::variant<int, std::string, bool> ret_v1, ret_v2;
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700530 new_message().read(ret_v1, ret_v2);
531 EXPECT_EQ(v1, ret_v1);
532 EXPECT_EQ(v2, ret_v2);
533}
534
William A. Kennington III13367e42018-06-26 15:23:13 -0700535TEST_F(ReadTest, VariantVerifyError)
536{
537 {
538 testing::InSequence seq;
539 expect_verify_type(SD_BUS_TYPE_VARIANT, "i", -EINVAL);
540 }
541
William A. Kennington III4274c112018-11-26 09:50:13 -0800542 std::variant<int, bool> ret;
William A. Kennington III13367e42018-06-26 15:23:13 -0700543 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
544}
545
William A. Kennington III60a72832018-06-26 14:31:15 -0700546TEST_F(ReadTest, VariantSkipUnmatched)
547{
548 {
549 testing::InSequence seq;
550 expect_verify_type(SD_BUS_TYPE_VARIANT, "i", false);
551 expect_verify_type(SD_BUS_TYPE_VARIANT, "b", false);
552 expect_skip("v");
553 }
William A. Kennington III13367e42018-06-26 15:23:13 -0700554
William A. Kennington III4274c112018-11-26 09:50:13 -0800555 std::variant<int, bool> ret;
William A. Kennington III60a72832018-06-26 14:31:15 -0700556 new_message().read(ret);
557}
558
William A. Kennington III13367e42018-06-26 15:23:13 -0700559TEST_F(ReadTest, VariantSkipError)
560{
561 {
562 testing::InSequence seq;
563 expect_verify_type(SD_BUS_TYPE_VARIANT, "i", false);
564 expect_verify_type(SD_BUS_TYPE_VARIANT, "b", false);
565 expect_skip("v", -EINVAL);
566 }
567
William A. Kennington III4274c112018-11-26 09:50:13 -0800568 std::variant<int, bool> ret;
William A. Kennington III13367e42018-06-26 15:23:13 -0700569 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
570}
571
572TEST_F(ReadTest, VariantEnterError)
573{
574 {
575 testing::InSequence seq;
576 expect_verify_type(SD_BUS_TYPE_VARIANT, "i", true);
577 expect_enter_container(SD_BUS_TYPE_VARIANT, "i", -EINVAL);
578 }
579
William A. Kennington III4274c112018-11-26 09:50:13 -0800580 std::variant<int, bool> ret;
William A. Kennington III13367e42018-06-26 15:23:13 -0700581 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
582}
583
584TEST_F(ReadTest, VariantExitError)
585{
586 {
587 testing::InSequence seq;
588 expect_verify_type(SD_BUS_TYPE_VARIANT, "i", true);
589 expect_enter_container(SD_BUS_TYPE_VARIANT, "i");
590 expect_basic<int>(SD_BUS_TYPE_INT32, 10);
591 expect_exit_container(-EINVAL);
592 }
593
William A. Kennington III4274c112018-11-26 09:50:13 -0800594 std::variant<int, bool> ret;
William A. Kennington III13367e42018-06-26 15:23:13 -0700595 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
596}
597
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700598TEST_F(ReadTest, LargeCombo)
599{
600 const std::vector<std::set<std::string>> vas{
601 {"a", "b", "c"},
602 {"d", "", "e"},
603 };
William A. Kennington III4274c112018-11-26 09:50:13 -0800604 const std::map<std::string, std::variant<int, double>> msv = {
605 {"a", 3.3}, {"b", 1}, {"c", 4.4}};
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700606
607 {
608 testing::InSequence seq;
609
610 expect_enter_container(SD_BUS_TYPE_ARRAY, "as");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700611 for (const auto& as : vas)
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700612 {
613 expect_at_end(false, 0);
614 expect_enter_container(SD_BUS_TYPE_ARRAY, "s");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700615 for (const auto& s : as)
Patrick Williams4fe85a32016-09-08 15:03:56 -0500616 {
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700617 expect_at_end(false, 0);
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700618 expect_basic<const char*>(SD_BUS_TYPE_STRING, s.c_str());
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700619 }
620 expect_at_end(false, 1);
621 expect_exit_container();
622 }
623 expect_at_end(false, 1);
624 expect_exit_container();
Patrick Williams4fe85a32016-09-08 15:03:56 -0500625
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700626 expect_enter_container(SD_BUS_TYPE_ARRAY, "{sv}");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700627 for (const auto& sv : msv)
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700628 {
629 expect_at_end(false, 0);
630 expect_enter_container(SD_BUS_TYPE_DICT_ENTRY, "sv");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700631 expect_basic<const char*>(SD_BUS_TYPE_STRING, sv.first.c_str());
William A. Kennington III4274c112018-11-26 09:50:13 -0800632 if (std::holds_alternative<int>(sv.second))
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700633 {
634 expect_verify_type(SD_BUS_TYPE_VARIANT, "i", true);
635 expect_enter_container(SD_BUS_TYPE_VARIANT, "i");
William A. Kennington III4274c112018-11-26 09:50:13 -0800636 expect_basic<int>(SD_BUS_TYPE_INT32, std::get<int>(sv.second));
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700637 expect_exit_container();
Patrick Williams4fe85a32016-09-08 15:03:56 -0500638 }
639 else
640 {
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700641 expect_verify_type(SD_BUS_TYPE_VARIANT, "i", false);
642 expect_verify_type(SD_BUS_TYPE_VARIANT, "d", true);
643 expect_enter_container(SD_BUS_TYPE_VARIANT, "d");
644 expect_basic<double>(SD_BUS_TYPE_DOUBLE,
William A. Kennington III4274c112018-11-26 09:50:13 -0800645 std::get<double>(sv.second));
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700646 expect_exit_container();
Patrick Williams4fe85a32016-09-08 15:03:56 -0500647 }
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700648 expect_exit_container();
Patrick Williams4fe85a32016-09-08 15:03:56 -0500649 }
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700650 expect_at_end(false, 1);
651 expect_exit_container();
Patrick Williams4fe85a32016-09-08 15:03:56 -0500652 }
Patrick Williams696e3152016-11-04 17:03:39 -0500653
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700654 std::vector<std::set<std::string>> ret_vas;
William A. Kennington III4274c112018-11-26 09:50:13 -0800655 std::map<std::string, std::variant<int, double>> ret_msv;
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700656 new_message().read(ret_vas, ret_msv);
657 EXPECT_EQ(vas, ret_vas);
658 EXPECT_EQ(msv, ret_msv);
Patrick Williams4fe85a32016-09-08 15:03:56 -0500659}
660
Patrick Williams9cde21f2022-08-29 10:33:27 -0500661// Unpack tests.
662// Since unpack uses read, we're mostly just testing the compilation.
663// Duplicate a few tests from Read using 'unpack'.
664
665TEST_F(ReadTest, UnpackSingleVector)
666{
667 const std::vector<int> vi{1, 2, 3, 4};
668
669 {
670 testing::InSequence seq;
671 expect_enter_container(SD_BUS_TYPE_ARRAY, "i");
672 for (const auto& i : vi)
673 {
674 expect_at_end(false, 0);
675 expect_basic<int>(SD_BUS_TYPE_INT32, i);
676 }
677 expect_at_end(false, 1);
678 expect_exit_container();
679 }
680
681 auto ret_vi = new_message().unpack<std::vector<int>>();
682 EXPECT_EQ(vi, ret_vi);
683}
684
685TEST_F(ReadTest, UnpackMultiple)
686{
687 const std::tuple<int, std::string, bool> tisb{3, "hi", false};
688
689 {
690 testing::InSequence seq;
691 expect_basic<int>(SD_BUS_TYPE_INT32, std::get<0>(tisb));
692 expect_basic<const char*>(SD_BUS_TYPE_STRING,
693 std::get<1>(tisb).c_str());
694 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, std::get<2>(tisb));
695 }
696
697 auto ret_tisb = new_message().unpack<int, std::string, bool>();
698 EXPECT_EQ(tisb, ret_tisb);
699}
700
Patrick Williams5f1c0bd2023-11-28 10:33:44 -0600701TEST_F(ReadTest, UnpackStructuredBinding)
702{
703 const std::tuple<int, std::string, bool> tisb{3, "hi", false};
704
705 {
706 testing::InSequence seq;
707 expect_basic<int>(SD_BUS_TYPE_INT32, std::get<0>(tisb));
708 expect_basic<const char*>(SD_BUS_TYPE_STRING,
709 std::get<1>(tisb).c_str());
710 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, std::get<2>(tisb));
711 }
712
713 auto [ret_ti, ret_ts,
714 ret_tb] = new_message().unpack<int, std::string, bool>();
715 EXPECT_EQ(tisb, std::make_tuple(ret_ti, ret_ts, ret_tb));
716}
717
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700718} // namespace