blob: d1d78e7efb42fca6f8a7f020c3a51fd7df99be0d [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));
44 };
Patrick Williams4fe85a32016-09-08 15:03:56 -050045
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -070046 sdbusplus::message::message new_message()
47 {
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
162TEST_F(ReadTest, CombinedBasic)
163{
164 const double a = 2.2;
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700165 const char* const b = "ijkd";
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700166 const bool c = false;
167 const int d = 18;
168
169 {
170 testing::InSequence seq;
171 expect_basic<double>(SD_BUS_TYPE_DOUBLE, a);
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700172 expect_basic<const char*>(SD_BUS_TYPE_STRING, b);
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700173 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, c);
174 expect_basic<int>(SD_BUS_TYPE_INT32, d);
175 }
176
177 double ret_a;
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700178 const char* ret_b;
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700179 bool ret_c;
180 int ret_d;
181 new_message().read(ret_a, ret_b, ret_c, ret_d);
182 EXPECT_EQ(a, ret_a);
183 EXPECT_EQ(b, ret_b);
184 EXPECT_EQ(c, ret_c);
185 EXPECT_EQ(d, ret_d);
186}
187
William A. Kennington III13367e42018-06-26 15:23:13 -0700188TEST_F(ReadTest, BasicError)
189{
190 expect_basic_error(SD_BUS_TYPE_INT32, -EINVAL);
191 int ret;
192 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
193}
194
195TEST_F(ReadTest, BasicStringError)
196{
197 expect_basic_error(SD_BUS_TYPE_STRING, -EINVAL);
198 std::string ret;
199 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
200}
201
202TEST_F(ReadTest, BasicStringWrapperError)
203{
204 expect_basic_error(SD_BUS_TYPE_SIGNATURE, -EINVAL);
205 sdbusplus::message::signature ret;
206 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
207}
208
209TEST_F(ReadTest, BasicBoolError)
210{
211 expect_basic_error(SD_BUS_TYPE_BOOLEAN, -EINVAL);
212 bool ret;
213 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
214}
215
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700216TEST_F(ReadTest, Vector)
217{
218 const std::vector<int> vi{1, 2, 3, 4};
219
220 {
221 testing::InSequence seq;
222 expect_enter_container(SD_BUS_TYPE_ARRAY, "i");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700223 for (const auto& i : vi)
Patrick Williams4fe85a32016-09-08 15:03:56 -0500224 {
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700225 expect_at_end(false, 0);
226 expect_basic<int>(SD_BUS_TYPE_INT32, i);
Patrick Williams4fe85a32016-09-08 15:03:56 -0500227 }
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700228 expect_at_end(false, 1);
229 expect_exit_container();
230 }
Patrick Williams4fe85a32016-09-08 15:03:56 -0500231
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700232 std::vector<int> ret_vi;
233 new_message().read(ret_vi);
234 EXPECT_EQ(vi, ret_vi);
235}
236
William A. Kennington III13367e42018-06-26 15:23:13 -0700237TEST_F(ReadTest, VectorEnterError)
238{
239 {
240 testing::InSequence seq;
241 expect_enter_container(SD_BUS_TYPE_ARRAY, "i", -EINVAL);
242 }
243
244 std::vector<int> ret;
245 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
246}
247
248TEST_F(ReadTest, VectorIterError)
249{
250 {
251 testing::InSequence seq;
252 expect_enter_container(SD_BUS_TYPE_ARRAY, "i");
253 expect_at_end(false, 0);
254 expect_basic<int>(SD_BUS_TYPE_INT32, 1);
255 expect_at_end(false, -EINVAL);
256 }
257
258 std::vector<int> ret;
259 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
260}
261
262TEST_F(ReadTest, VectorExitError)
263{
264 {
265 testing::InSequence seq;
266 expect_enter_container(SD_BUS_TYPE_ARRAY, "i");
267 expect_at_end(false, 0);
268 expect_basic<int>(SD_BUS_TYPE_INT32, 1);
269 expect_at_end(false, 0);
270 expect_basic<int>(SD_BUS_TYPE_INT32, 2);
271 expect_at_end(false, 1);
272 expect_exit_container(-EINVAL);
273 }
274
275 std::vector<int> ret;
276 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
277}
278
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700279TEST_F(ReadTest, Set)
280{
281 const std::set<std::string> ss{"one", "two", "eight"};
282
283 {
284 testing::InSequence seq;
285 expect_enter_container(SD_BUS_TYPE_ARRAY, "s");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700286 for (const auto& s : ss)
Patrick Williams4fe85a32016-09-08 15:03:56 -0500287 {
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700288 expect_at_end(false, 0);
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700289 expect_basic<const char*>(SD_BUS_TYPE_STRING, s.c_str());
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700290 }
291 expect_at_end(false, 1);
292 expect_exit_container();
293 }
Patrick Williams4fe85a32016-09-08 15:03:56 -0500294
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700295 std::set<std::string> ret_ss;
296 new_message().read(ret_ss);
297 EXPECT_EQ(ss, ret_ss);
298}
299
Patrick Williamsb98bdc62020-06-16 16:15:40 -0500300TEST_F(ReadTest, UnorderedSet)
301{
302 const std::unordered_set<std::string> ss{"one", "two", "eight"};
303
304 {
305 testing::InSequence seq;
306 expect_enter_container(SD_BUS_TYPE_ARRAY, "s");
307 for (const auto& s : ss)
308 {
309 expect_at_end(false, 0);
310 expect_basic<const char*>(SD_BUS_TYPE_STRING, s.c_str());
311 }
312 expect_at_end(false, 1);
313 expect_exit_container();
314 }
315
316 std::unordered_set<std::string> ret_ss;
317 new_message().read(ret_ss);
318 EXPECT_EQ(ss, ret_ss);
319}
320
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700321TEST_F(ReadTest, Map)
322{
323 const std::map<int, std::string> mis{
324 {1, "a"},
325 {2, "bc"},
326 {3, "def"},
327 {4, "ghij"},
328 };
329
330 {
331 testing::InSequence seq;
332 expect_enter_container(SD_BUS_TYPE_ARRAY, "{is}");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700333 for (const auto& is : mis)
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700334 {
335 expect_at_end(false, 0);
336 expect_enter_container(SD_BUS_TYPE_DICT_ENTRY, "is");
337 expect_basic<int>(SD_BUS_TYPE_INT32, is.first);
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700338 expect_basic<const char*>(SD_BUS_TYPE_STRING, is.second.c_str());
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700339 expect_exit_container();
340 }
341 expect_at_end(false, 1);
342 expect_exit_container();
343 }
344
345 std::map<int, std::string> ret_mis;
346 new_message().read(ret_mis);
347 EXPECT_EQ(mis, ret_mis);
348}
349
William A. Kennington III13367e42018-06-26 15:23:13 -0700350TEST_F(ReadTest, MapEnterError)
351{
352 {
353 testing::InSequence seq;
354 expect_enter_container(SD_BUS_TYPE_ARRAY, "{si}", -EINVAL);
355 }
356
357 std::map<std::string, int> ret;
358 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
359}
360
361TEST_F(ReadTest, MapEntryEnterError)
362{
363 {
364 testing::InSequence seq;
365 expect_enter_container(SD_BUS_TYPE_ARRAY, "{si}");
366 expect_at_end(false, 0);
367 expect_enter_container(SD_BUS_TYPE_DICT_ENTRY, "si", -EINVAL);
368 }
369
370 std::map<std::string, int> ret;
371 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
372}
373
374TEST_F(ReadTest, MapEntryExitError)
375{
376 {
377 testing::InSequence seq;
378 expect_enter_container(SD_BUS_TYPE_ARRAY, "{si}");
379 expect_at_end(false, 0);
380 expect_enter_container(SD_BUS_TYPE_DICT_ENTRY, "si");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700381 expect_basic<const char*>(SD_BUS_TYPE_STRING, "ab");
William A. Kennington III13367e42018-06-26 15:23:13 -0700382 expect_basic<int>(SD_BUS_TYPE_INT32, 1);
383 expect_exit_container(-EINVAL);
384 }
385
386 std::map<std::string, int> ret;
387 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
388}
389
390TEST_F(ReadTest, MapIterError)
391{
392 {
393 testing::InSequence seq;
394 expect_enter_container(SD_BUS_TYPE_ARRAY, "{si}");
395 expect_at_end(false, 0);
396 expect_enter_container(SD_BUS_TYPE_DICT_ENTRY, "si");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700397 expect_basic<const char*>(SD_BUS_TYPE_STRING, "ab");
William A. Kennington III13367e42018-06-26 15:23:13 -0700398 expect_basic<int>(SD_BUS_TYPE_INT32, 1);
399 expect_exit_container();
400 expect_at_end(false, -EINVAL);
401 }
402
403 std::map<std::string, int> ret;
404 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
405}
406
407TEST_F(ReadTest, MapExitError)
408{
409 {
410 testing::InSequence seq;
411 expect_enter_container(SD_BUS_TYPE_ARRAY, "{si}");
412 expect_at_end(false, 0);
413 expect_enter_container(SD_BUS_TYPE_DICT_ENTRY, "si");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700414 expect_basic<const char*>(SD_BUS_TYPE_STRING, "ab");
William A. Kennington III13367e42018-06-26 15:23:13 -0700415 expect_basic<int>(SD_BUS_TYPE_INT32, 1);
416 expect_exit_container();
417 expect_at_end(false, 1);
418 expect_exit_container(-EINVAL);
419 }
420
421 std::map<std::string, int> ret;
422 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
423}
424
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700425TEST_F(ReadTest, UnorderedMap)
426{
427 const std::unordered_map<int, std::string> mis{
428 {1, "a"},
429 {2, "bc"},
430 {3, "def"},
431 {4, "ghij"},
432 };
433
434 {
435 testing::InSequence seq;
436 expect_enter_container(SD_BUS_TYPE_ARRAY, "{is}");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700437 for (const auto& is : mis)
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700438 {
439 expect_at_end(false, 0);
440 expect_enter_container(SD_BUS_TYPE_DICT_ENTRY, "is");
441 expect_basic<int>(SD_BUS_TYPE_INT32, is.first);
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700442 expect_basic<const char*>(SD_BUS_TYPE_STRING, is.second.c_str());
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700443 expect_exit_container();
444 }
445 expect_at_end(false, 1);
446 expect_exit_container();
447 }
448
449 std::unordered_map<int, std::string> ret_mis;
450 new_message().read(ret_mis);
451 EXPECT_EQ(mis, ret_mis);
452}
453
454TEST_F(ReadTest, Tuple)
455{
456 const std::tuple<int, std::string, bool> tisb{3, "hi", false};
457
458 {
459 testing::InSequence seq;
460 expect_enter_container(SD_BUS_TYPE_STRUCT, "isb");
461 expect_basic<int>(SD_BUS_TYPE_INT32, std::get<0>(tisb));
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700462 expect_basic<const char*>(SD_BUS_TYPE_STRING,
463 std::get<1>(tisb).c_str());
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700464 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, std::get<2>(tisb));
465 expect_exit_container();
466 }
467
468 std::tuple<int, std::string, bool> ret_tisb;
469 new_message().read(ret_tisb);
470 EXPECT_EQ(tisb, ret_tisb);
471}
472
William A. Kennington III13367e42018-06-26 15:23:13 -0700473TEST_F(ReadTest, TupleEnterError)
474{
475 {
476 testing::InSequence seq;
477 expect_enter_container(SD_BUS_TYPE_STRUCT, "bis", -EINVAL);
478 }
479
480 std::tuple<bool, int, std::string> ret;
481 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
482}
483
484TEST_F(ReadTest, TupleExitError)
485{
486 {
487 testing::InSequence seq;
488 expect_enter_container(SD_BUS_TYPE_STRUCT, "bis");
489 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, false);
490 expect_basic<int>(SD_BUS_TYPE_INT32, 1);
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700491 expect_basic<const char*>(SD_BUS_TYPE_STRING, "ab");
William A. Kennington III13367e42018-06-26 15:23:13 -0700492 expect_exit_container(-EINVAL);
493 }
494
495 std::tuple<bool, int, std::string> ret;
496 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
497}
498
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700499TEST_F(ReadTest, Variant)
500{
501 const bool b1 = false;
502 const std::string s2{"asdf"};
William A. Kennington III4274c112018-11-26 09:50:13 -0800503 const std::variant<int, std::string, bool> v1{b1}, v2{s2};
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700504
505 {
506 testing::InSequence seq;
507 expect_verify_type(SD_BUS_TYPE_VARIANT, "i", false);
508 expect_verify_type(SD_BUS_TYPE_VARIANT, "s", false);
509 expect_verify_type(SD_BUS_TYPE_VARIANT, "b", true);
510 expect_enter_container(SD_BUS_TYPE_VARIANT, "b");
511 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, b1);
512 expect_exit_container();
513 expect_verify_type(SD_BUS_TYPE_VARIANT, "i", false);
514 expect_verify_type(SD_BUS_TYPE_VARIANT, "s", true);
515 expect_enter_container(SD_BUS_TYPE_VARIANT, "s");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700516 expect_basic<const char*>(SD_BUS_TYPE_STRING, s2.c_str());
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700517 expect_exit_container();
518 }
519
William A. Kennington III4274c112018-11-26 09:50:13 -0800520 std::variant<int, std::string, bool> ret_v1, ret_v2;
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700521 new_message().read(ret_v1, ret_v2);
522 EXPECT_EQ(v1, ret_v1);
523 EXPECT_EQ(v2, ret_v2);
524}
525
William A. Kennington III13367e42018-06-26 15:23:13 -0700526TEST_F(ReadTest, VariantVerifyError)
527{
528 {
529 testing::InSequence seq;
530 expect_verify_type(SD_BUS_TYPE_VARIANT, "i", -EINVAL);
531 }
532
William A. Kennington III4274c112018-11-26 09:50:13 -0800533 std::variant<int, bool> ret;
William A. Kennington III13367e42018-06-26 15:23:13 -0700534 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
535}
536
William A. Kennington III60a72832018-06-26 14:31:15 -0700537TEST_F(ReadTest, VariantSkipUnmatched)
538{
539 {
540 testing::InSequence seq;
541 expect_verify_type(SD_BUS_TYPE_VARIANT, "i", false);
542 expect_verify_type(SD_BUS_TYPE_VARIANT, "b", false);
543 expect_skip("v");
544 }
William A. Kennington III13367e42018-06-26 15:23:13 -0700545
William A. Kennington III4274c112018-11-26 09:50:13 -0800546 std::variant<int, bool> ret;
William A. Kennington III60a72832018-06-26 14:31:15 -0700547 new_message().read(ret);
548}
549
William A. Kennington III13367e42018-06-26 15:23:13 -0700550TEST_F(ReadTest, VariantSkipError)
551{
552 {
553 testing::InSequence seq;
554 expect_verify_type(SD_BUS_TYPE_VARIANT, "i", false);
555 expect_verify_type(SD_BUS_TYPE_VARIANT, "b", false);
556 expect_skip("v", -EINVAL);
557 }
558
William A. Kennington III4274c112018-11-26 09:50:13 -0800559 std::variant<int, bool> ret;
William A. Kennington III13367e42018-06-26 15:23:13 -0700560 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
561}
562
563TEST_F(ReadTest, VariantEnterError)
564{
565 {
566 testing::InSequence seq;
567 expect_verify_type(SD_BUS_TYPE_VARIANT, "i", true);
568 expect_enter_container(SD_BUS_TYPE_VARIANT, "i", -EINVAL);
569 }
570
William A. Kennington III4274c112018-11-26 09:50:13 -0800571 std::variant<int, bool> ret;
William A. Kennington III13367e42018-06-26 15:23:13 -0700572 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
573}
574
575TEST_F(ReadTest, VariantExitError)
576{
577 {
578 testing::InSequence seq;
579 expect_verify_type(SD_BUS_TYPE_VARIANT, "i", true);
580 expect_enter_container(SD_BUS_TYPE_VARIANT, "i");
581 expect_basic<int>(SD_BUS_TYPE_INT32, 10);
582 expect_exit_container(-EINVAL);
583 }
584
William A. Kennington III4274c112018-11-26 09:50:13 -0800585 std::variant<int, bool> ret;
William A. Kennington III13367e42018-06-26 15:23:13 -0700586 EXPECT_THROW(new_message().read(ret), sdbusplus::exception::SdBusError);
587}
588
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700589TEST_F(ReadTest, LargeCombo)
590{
591 const std::vector<std::set<std::string>> vas{
592 {"a", "b", "c"},
593 {"d", "", "e"},
594 };
William A. Kennington III4274c112018-11-26 09:50:13 -0800595 const std::map<std::string, std::variant<int, double>> msv = {
596 {"a", 3.3}, {"b", 1}, {"c", 4.4}};
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700597
598 {
599 testing::InSequence seq;
600
601 expect_enter_container(SD_BUS_TYPE_ARRAY, "as");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700602 for (const auto& as : vas)
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700603 {
604 expect_at_end(false, 0);
605 expect_enter_container(SD_BUS_TYPE_ARRAY, "s");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700606 for (const auto& s : as)
Patrick Williams4fe85a32016-09-08 15:03:56 -0500607 {
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700608 expect_at_end(false, 0);
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700609 expect_basic<const char*>(SD_BUS_TYPE_STRING, s.c_str());
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700610 }
611 expect_at_end(false, 1);
612 expect_exit_container();
613 }
614 expect_at_end(false, 1);
615 expect_exit_container();
Patrick Williams4fe85a32016-09-08 15:03:56 -0500616
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700617 expect_enter_container(SD_BUS_TYPE_ARRAY, "{sv}");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700618 for (const auto& sv : msv)
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700619 {
620 expect_at_end(false, 0);
621 expect_enter_container(SD_BUS_TYPE_DICT_ENTRY, "sv");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700622 expect_basic<const char*>(SD_BUS_TYPE_STRING, sv.first.c_str());
William A. Kennington III4274c112018-11-26 09:50:13 -0800623 if (std::holds_alternative<int>(sv.second))
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700624 {
625 expect_verify_type(SD_BUS_TYPE_VARIANT, "i", true);
626 expect_enter_container(SD_BUS_TYPE_VARIANT, "i");
William A. Kennington III4274c112018-11-26 09:50:13 -0800627 expect_basic<int>(SD_BUS_TYPE_INT32, std::get<int>(sv.second));
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700628 expect_exit_container();
Patrick Williams4fe85a32016-09-08 15:03:56 -0500629 }
630 else
631 {
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700632 expect_verify_type(SD_BUS_TYPE_VARIANT, "i", false);
633 expect_verify_type(SD_BUS_TYPE_VARIANT, "d", true);
634 expect_enter_container(SD_BUS_TYPE_VARIANT, "d");
635 expect_basic<double>(SD_BUS_TYPE_DOUBLE,
William A. Kennington III4274c112018-11-26 09:50:13 -0800636 std::get<double>(sv.second));
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700637 expect_exit_container();
Patrick Williams4fe85a32016-09-08 15:03:56 -0500638 }
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700639 expect_exit_container();
Patrick Williams4fe85a32016-09-08 15:03:56 -0500640 }
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700641 expect_at_end(false, 1);
642 expect_exit_container();
Patrick Williams4fe85a32016-09-08 15:03:56 -0500643 }
Patrick Williams696e3152016-11-04 17:03:39 -0500644
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700645 std::vector<std::set<std::string>> ret_vas;
William A. Kennington III4274c112018-11-26 09:50:13 -0800646 std::map<std::string, std::variant<int, double>> ret_msv;
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700647 new_message().read(ret_vas, ret_msv);
648 EXPECT_EQ(vas, ret_vas);
649 EXPECT_EQ(msv, ret_msv);
Patrick Williams4fe85a32016-09-08 15:03:56 -0500650}
651
William A. Kennington IIIb4b4fa12018-06-25 17:20:06 -0700652} // namespace