blob: 20ca441d065c74a68a427627a300b06cfa62f6ac [file] [log] [blame]
Patrick Venture95269db2018-08-31 09:19:17 -07001#include <systemd/sd-bus-protocol.h>
2
Patrick Williams7802c072016-09-02 15:20:22 -05003#include <sdbusplus/message.hpp>
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -07004#include <sdbusplus/test/sdbus_mock.hpp>
Patrick Williams127b8ab2020-05-21 15:24:19 -05005
6#include <array>
7#include <map>
Ed Tanous28dc36d2018-02-21 12:22:54 -08008#include <set>
Patrick Williamsb7329a92022-04-28 09:57:23 -05009#include <span>
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070010#include <string>
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -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 IIIa1e9e2a2018-06-23 13:33:25 -070015#include <vector>
Patrick Williams1807fa42016-08-01 22:23:30 -050016
Patrick Venture95269db2018-08-31 09:19:17 -070017#include <gmock/gmock.h>
18#include <gtest/gtest.h>
19
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070020namespace
Patrick Williams1807fa42016-08-01 22:23:30 -050021{
Patrick Williams5b485792016-08-02 07:35:14 -050022
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070023using testing::Eq;
24using testing::MatcherCast;
25using testing::Pointee;
26using testing::Return;
27using testing::SafeMatcherCast;
28using testing::StrEq;
29
Ed Tanous640a7d52023-01-04 13:17:55 -080030MATCHER_P(iovec_equal, match_string, "")
31{
32 const char* start = std::bit_cast<char*>(arg->iov_base);
33 return std::string(start, arg->iov_len) == match_string;
34}
35
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070036class AppendTest : public testing::Test
37{
38 protected:
39 testing::StrictMock<sdbusplus::SdBusMock> mock;
40
41 void SetUp() override
42 {
43 EXPECT_CALL(mock, sd_bus_message_new_method_call(testing::_, testing::_,
44 nullptr, nullptr,
45 nullptr, nullptr))
46 .WillRepeatedly(Return(0));
Ed Tanouscb2fbeb2023-01-06 13:16:19 -080047 }
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070048
Patrick Williams10d7aa12021-11-19 11:36:18 -060049 sdbusplus::message_t new_message()
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070050 {
51 return sdbusplus::get_mocked_new(&mock).new_method_call(
52 nullptr, nullptr, nullptr, nullptr);
53 }
54
Patrick Venture2b238af2018-08-31 12:45:01 -070055 template <typename T>
56 void expect_basic(char type, T val)
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070057 {
William A. Kennington IIIe0d69652018-08-31 13:09:47 -070058 EXPECT_CALL(mock, sd_bus_message_append_basic(
59 nullptr, type,
60 MatcherCast<const void*>(
61 SafeMatcherCast<const T*>(Pointee(Eq(val))))))
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070062 .WillOnce(Return(0));
63 }
64
William A. Kennington IIIe0d69652018-08-31 13:09:47 -070065 void expect_basic_string(char type, const char* str)
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070066 {
67 EXPECT_CALL(mock, sd_bus_message_append_basic(
68 nullptr, type,
William A. Kennington IIIe0d69652018-08-31 13:09:47 -070069 MatcherCast<const void*>(
70 SafeMatcherCast<const char*>(StrEq(str)))))
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070071 .WillOnce(Return(0));
72 }
Ed Tanous640a7d52023-01-04 13:17:55 -080073 void expect_basic_string_iovec(const char* str, size_t size)
74 {
75 std::string tmp = {str, size};
76 EXPECT_CALL(mock, sd_bus_message_append_string_iovec(
77 nullptr, iovec_equal(tmp), 1))
78 .WillOnce(Return(0));
79 }
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070080
William A. Kennington IIIe0d69652018-08-31 13:09:47 -070081 void expect_open_container(char type, const char* contents)
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070082 {
83 EXPECT_CALL(
84 mock, sd_bus_message_open_container(nullptr, type, StrEq(contents)))
85 .WillOnce(Return(0));
86 }
87
88 void expect_close_container()
89 {
90 EXPECT_CALL(mock, sd_bus_message_close_container(nullptr))
91 .WillOnce(Return(0));
92 }
93};
94
95TEST_F(AppendTest, RValueInt)
96{
Patrick Williamsb7329a92022-04-28 09:57:23 -050097 static_assert(
98 sdbusplus::message::details::can_append_multiple_v<decltype(1)>);
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070099 expect_basic<int>(SD_BUS_TYPE_INT32, 1);
100 new_message().append(1);
Patrick Williams1807fa42016-08-01 22:23:30 -0500101}
102
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700103TEST_F(AppendTest, LValueInt)
Patrick Williams1807fa42016-08-01 22:23:30 -0500104{
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700105 const int a = 1;
Patrick Williamsb7329a92022-04-28 09:57:23 -0500106 static_assert(
107 sdbusplus::message::details::can_append_multiple_v<decltype(a)>);
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700108 expect_basic<int>(SD_BUS_TYPE_INT32, a);
109 new_message().append(a);
110}
Patrick Williams1807fa42016-08-01 22:23:30 -0500111
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700112TEST_F(AppendTest, XValueInt)
113{
114 int a = 1;
115 expect_basic<int>(SD_BUS_TYPE_INT32, a);
116 new_message().append(std::move(a));
117}
118
119TEST_F(AppendTest, RValueBool)
120{
121 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, true);
122 new_message().append(true);
123}
124
125TEST_F(AppendTest, LValueBool)
126{
127 const bool a = false;
128 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, false);
129 new_message().append(a);
130}
131
132TEST_F(AppendTest, XValueBool)
133{
134 bool a = false;
135 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, false);
136 new_message().append(std::move(a));
137}
138
139TEST_F(AppendTest, RValueDouble)
140{
141 expect_basic<double>(SD_BUS_TYPE_DOUBLE, 1.1);
142 new_message().append(1.1);
143}
144
145TEST_F(AppendTest, LValueDouble)
146{
147 const double a = 1.1;
148 expect_basic<double>(SD_BUS_TYPE_DOUBLE, a);
149 new_message().append(a);
150}
151
152TEST_F(AppendTest, XValueDouble)
153{
154 double a = 1.1;
155 expect_basic<double>(SD_BUS_TYPE_DOUBLE, a);
156 new_message().append(std::move(a));
157}
158
159TEST_F(AppendTest, RValueCString)
160{
161 expect_basic_string(SD_BUS_TYPE_STRING, "asdf");
162 new_message().append("asdf");
163}
164
165TEST_F(AppendTest, LValueCString)
166{
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700167 const char* const s = "asdf";
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700168 expect_basic_string(SD_BUS_TYPE_STRING, s);
169 new_message().append(s);
170}
171
172TEST_F(AppendTest, XValueCString)
173{
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700174 const char* s = "asdf";
Patrick Williamsb7329a92022-04-28 09:57:23 -0500175 static_assert(
176 sdbusplus::message::details::can_append_multiple_v<decltype(s)>);
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700177 expect_basic_string(SD_BUS_TYPE_STRING, s);
178 new_message().append(std::move(s));
179}
180
181TEST_F(AppendTest, RValueString)
182{
183 expect_basic_string(SD_BUS_TYPE_STRING, "asdf");
184 new_message().append(std::string{"asdf"});
185}
186
187TEST_F(AppendTest, LValueString)
188{
189 std::string s{"asdf"};
Patrick Williamsb7329a92022-04-28 09:57:23 -0500190 static_assert(
191 !sdbusplus::message::details::can_append_multiple_v<decltype(s)>);
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700192 expect_basic_string(SD_BUS_TYPE_STRING, s.c_str());
193 new_message().append(s);
194}
195
196TEST_F(AppendTest, XValueString)
197{
198 std::string s{"asdf"};
199 expect_basic_string(SD_BUS_TYPE_STRING, s.c_str());
200 new_message().append(std::move(s));
201}
202
Ed Tanous640a7d52023-01-04 13:17:55 -0800203TEST_F(AppendTest, LValueStringView)
204{
205 std::string_view s{"asdf"};
206 expect_basic_string_iovec(s.data(), s.size());
207 new_message().append(s);
208}
209
210TEST_F(AppendTest, RValueStringView)
211{
212 std::string_view s{"asdf"};
213 expect_basic_string_iovec(s.data(), s.size());
214 new_message().append(std::string_view{"asdf"});
215}
216
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700217TEST_F(AppendTest, ObjectPath)
218{
219 sdbusplus::message::object_path o{"/asdf"};
220 expect_basic_string(SD_BUS_TYPE_OBJECT_PATH, o.str.c_str());
221 new_message().append(o);
222}
223
224TEST_F(AppendTest, Signature)
225{
226 sdbusplus::message::signature g{"ii"};
227 expect_basic_string(SD_BUS_TYPE_SIGNATURE, g.str.c_str());
228 new_message().append(g);
229}
230
231TEST_F(AppendTest, CombinedBasic)
232{
233 const int c = 3;
234 const std::string s1{"fdsa"};
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700235 const char* const s2 = "asdf";
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700236
Patrick Williams1807fa42016-08-01 22:23:30 -0500237 {
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700238 testing::InSequence seq;
239 expect_basic<int>(SD_BUS_TYPE_INT32, 1);
240 expect_basic<double>(SD_BUS_TYPE_DOUBLE, 2.2);
241 expect_basic<int>(SD_BUS_TYPE_INT32, c);
242 expect_basic_string(SD_BUS_TYPE_STRING, s1.c_str());
243 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, false);
244 expect_basic_string(SD_BUS_TYPE_STRING, s2);
245 }
246 new_message().append(1, 2.2, c, s1, false, s2);
247}
Patrick Williams1807fa42016-08-01 22:23:30 -0500248
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700249TEST_F(AppendTest, Array)
250{
251 const std::array<double, 4> a{1.1, 2.2, 3.3, 4.4};
Patrick Williamsb7329a92022-04-28 09:57:23 -0500252 static_assert(
253 !sdbusplus::message::details::can_append_multiple_v<decltype(a)>);
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700254
255 {
256 testing::InSequence seq;
257 expect_open_container(SD_BUS_TYPE_ARRAY, "d");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700258 for (const auto& i : a)
Patrick Williams1807fa42016-08-01 22:23:30 -0500259 {
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700260 expect_basic<double>(SD_BUS_TYPE_DOUBLE, i);
Patrick Williams1807fa42016-08-01 22:23:30 -0500261 }
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700262 expect_close_container();
263 }
264 new_message().append(a);
265}
Patrick Williams1807fa42016-08-01 22:23:30 -0500266
Patrick Williamsb7329a92022-04-28 09:57:23 -0500267TEST_F(AppendTest, Span)
268{
269 const std::array<double, 4> a{1.1, 2.2, 3.3, 4.4};
270 auto s = std::span{a};
271 static_assert(
272 !sdbusplus::message::details::can_append_multiple_v<decltype(s)>);
273
274 {
275 testing::InSequence seq;
276 expect_open_container(SD_BUS_TYPE_ARRAY, "d");
277 for (const auto& i : s)
278 {
279 expect_basic<double>(SD_BUS_TYPE_DOUBLE, i);
280 }
281 expect_close_container();
282 }
283 new_message().append(s);
284}
285
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700286TEST_F(AppendTest, Vector)
287{
288 const std::vector<int> v{1, 2, 3, 4};
289
290 {
291 testing::InSequence seq;
292 expect_open_container(SD_BUS_TYPE_ARRAY, "i");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700293 for (const auto& i : v)
Patrick Williams1807fa42016-08-01 22:23:30 -0500294 {
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700295 expect_basic<int>(SD_BUS_TYPE_INT32, i);
296 }
297 expect_close_container();
298 }
299 new_message().append(v);
300}
301
302TEST_F(AppendTest, Set)
303{
304 const std::set<std::string> s{"one", "two", "eight"};
305
306 {
307 testing::InSequence seq;
308 expect_open_container(SD_BUS_TYPE_ARRAY, "s");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700309 for (const auto& i : s)
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700310 {
311 expect_basic_string(SD_BUS_TYPE_STRING, i.c_str());
312 }
313 expect_close_container();
314 }
315 new_message().append(s);
316}
317
Patrick Williamsb98bdc62020-06-16 16:15:40 -0500318TEST_F(AppendTest, UnorderedSet)
319{
320 const std::unordered_set<std::string> s{"one", "two", "eight"};
321
322 {
323 testing::InSequence seq;
324 expect_open_container(SD_BUS_TYPE_ARRAY, "s");
325 for (const auto& i : s)
326 {
327 expect_basic_string(SD_BUS_TYPE_STRING, i.c_str());
328 }
329 expect_close_container();
330 }
331 new_message().append(s);
332}
333
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700334TEST_F(AppendTest, Map)
335{
336 const std::map<int, std::string> m{
337 {1, "a"},
338 {2, "bc"},
339 {3, "def"},
340 {4, "ghij"},
341 };
342
343 {
344 testing::InSequence seq;
345 expect_open_container(SD_BUS_TYPE_ARRAY, "{is}");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700346 for (const auto& i : m)
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700347 {
348 expect_open_container(SD_BUS_TYPE_DICT_ENTRY, "is");
349 expect_basic<int>(SD_BUS_TYPE_INT32, i.first);
350 expect_basic_string(SD_BUS_TYPE_STRING, i.second.c_str());
351 expect_close_container();
352 }
353 expect_close_container();
354 }
355 new_message().append(m);
356}
357
358TEST_F(AppendTest, UnorderedMap)
359{
360 const std::unordered_map<int, bool> m{
361 {1, false},
362 {2, true},
363 {3, true},
364 {4, false},
365 };
366
367 {
368 testing::InSequence seq;
369 expect_open_container(SD_BUS_TYPE_ARRAY, "{ib}");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700370 for (const auto& i : m)
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700371 {
372 expect_open_container(SD_BUS_TYPE_DICT_ENTRY, "ib");
373 expect_basic<int>(SD_BUS_TYPE_INT32, i.first);
374 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, i.second);
375 expect_close_container();
376 }
377 expect_close_container();
378 }
379 new_message().append(m);
380}
381
382TEST_F(AppendTest, Tuple)
383{
384 const std::tuple<int, std::string, bool> t{5, "asdf", false};
385
386 {
387 testing::InSequence seq;
388 expect_open_container(SD_BUS_TYPE_STRUCT, "isb");
389 expect_basic<int>(SD_BUS_TYPE_INT32, std::get<0>(t));
390 expect_basic_string(SD_BUS_TYPE_STRING, std::get<1>(t).c_str());
391 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, std::get<2>(t));
392 expect_close_container();
393 }
394 new_message().append(t);
395}
396
397TEST_F(AppendTest, Variant)
398{
399 const bool b1 = false;
400 const std::string s2{"asdf"};
William A. Kennington III4274c112018-11-26 09:50:13 -0800401 const std::variant<int, std::string, bool> v1{b1}, v2{s2};
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700402
403 {
404 testing::InSequence seq;
405 expect_open_container(SD_BUS_TYPE_VARIANT, "b");
406 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, b1);
407 expect_close_container();
408 expect_open_container(SD_BUS_TYPE_VARIANT, "s");
409 expect_basic_string(SD_BUS_TYPE_STRING, s2.c_str());
410 expect_close_container();
411 }
412 new_message().append(v1, v2);
413}
414
415TEST_F(AppendTest, LargeCombo)
416{
417 std::vector<std::array<std::string, 3>> vas{{"a", "b", "c"},
418 {"d", "", "e"}};
William A. Kennington III4274c112018-11-26 09:50:13 -0800419 std::map<std::string, std::variant<int, double>> msv = {
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700420 {"a", 3.3}, {"b", 1}, {"c", 4.4}};
421
422 {
423 testing::InSequence seq;
424
425 expect_open_container(SD_BUS_TYPE_ARRAY, "as");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700426 for (const auto& as : vas)
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700427 {
428 expect_open_container(SD_BUS_TYPE_ARRAY, "s");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700429 for (const auto& s : as)
Patrick Williams07e1d6f2016-09-08 15:54:09 -0500430 {
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700431 expect_basic_string(SD_BUS_TYPE_STRING, s.c_str());
432 }
433 expect_close_container();
434 }
435 expect_close_container();
436
437 expect_open_container(SD_BUS_TYPE_ARRAY, "{sv}");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700438 for (const auto& sv : msv)
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700439 {
440 expect_open_container(SD_BUS_TYPE_DICT_ENTRY, "sv");
441 expect_basic_string(SD_BUS_TYPE_STRING, sv.first.c_str());
William A. Kennington III4274c112018-11-26 09:50:13 -0800442 if (std::holds_alternative<int>(sv.second))
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700443 {
444 expect_open_container(SD_BUS_TYPE_VARIANT, "i");
William A. Kennington III4274c112018-11-26 09:50:13 -0800445 expect_basic<int>(SD_BUS_TYPE_INT32, std::get<int>(sv.second));
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700446 expect_close_container();
Patrick Williams07e1d6f2016-09-08 15:54:09 -0500447 }
448 else
449 {
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700450 expect_open_container(SD_BUS_TYPE_VARIANT, "d");
451 expect_basic<double>(SD_BUS_TYPE_DOUBLE,
William A. Kennington III4274c112018-11-26 09:50:13 -0800452 std::get<double>(sv.second));
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700453 expect_close_container();
Patrick Williams07e1d6f2016-09-08 15:54:09 -0500454 }
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700455 expect_close_container();
Patrick Williams1807fa42016-08-01 22:23:30 -0500456 }
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700457 expect_close_container();
Patrick Williams1807fa42016-08-01 22:23:30 -0500458 }
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700459 new_message().append(vas, msv);
Patrick Williams1807fa42016-08-01 22:23:30 -0500460}
461
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700462} // namespace