blob: 59e83b47dfd958d6ccf6aaf3f6794c4e885d86f9 [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
30class AppendTest : public testing::Test
31{
32 protected:
33 testing::StrictMock<sdbusplus::SdBusMock> mock;
34
35 void SetUp() override
36 {
37 EXPECT_CALL(mock, sd_bus_message_new_method_call(testing::_, testing::_,
38 nullptr, nullptr,
39 nullptr, nullptr))
40 .WillRepeatedly(Return(0));
41 };
42
Patrick Williams10d7aa12021-11-19 11:36:18 -060043 sdbusplus::message_t new_message()
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070044 {
45 return sdbusplus::get_mocked_new(&mock).new_method_call(
46 nullptr, nullptr, nullptr, nullptr);
47 }
48
Patrick Venture2b238af2018-08-31 12:45:01 -070049 template <typename T>
50 void expect_basic(char type, T val)
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070051 {
William A. Kennington IIIe0d69652018-08-31 13:09:47 -070052 EXPECT_CALL(mock, sd_bus_message_append_basic(
53 nullptr, type,
54 MatcherCast<const void*>(
55 SafeMatcherCast<const T*>(Pointee(Eq(val))))))
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070056 .WillOnce(Return(0));
57 }
58
William A. Kennington IIIe0d69652018-08-31 13:09:47 -070059 void expect_basic_string(char type, const char* str)
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070060 {
61 EXPECT_CALL(mock, sd_bus_message_append_basic(
62 nullptr, type,
William A. Kennington IIIe0d69652018-08-31 13:09:47 -070063 MatcherCast<const void*>(
64 SafeMatcherCast<const char*>(StrEq(str)))))
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070065 .WillOnce(Return(0));
66 }
67
William A. Kennington IIIe0d69652018-08-31 13:09:47 -070068 void expect_open_container(char type, const char* contents)
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070069 {
70 EXPECT_CALL(
71 mock, sd_bus_message_open_container(nullptr, type, StrEq(contents)))
72 .WillOnce(Return(0));
73 }
74
75 void expect_close_container()
76 {
77 EXPECT_CALL(mock, sd_bus_message_close_container(nullptr))
78 .WillOnce(Return(0));
79 }
80};
81
82TEST_F(AppendTest, RValueInt)
83{
Patrick Williamsb7329a92022-04-28 09:57:23 -050084 static_assert(
85 sdbusplus::message::details::can_append_multiple_v<decltype(1)>);
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070086 expect_basic<int>(SD_BUS_TYPE_INT32, 1);
87 new_message().append(1);
Patrick Williams1807fa42016-08-01 22:23:30 -050088}
89
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070090TEST_F(AppendTest, LValueInt)
Patrick Williams1807fa42016-08-01 22:23:30 -050091{
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070092 const int a = 1;
Patrick Williamsb7329a92022-04-28 09:57:23 -050093 static_assert(
94 sdbusplus::message::details::can_append_multiple_v<decltype(a)>);
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070095 expect_basic<int>(SD_BUS_TYPE_INT32, a);
96 new_message().append(a);
97}
Patrick Williams1807fa42016-08-01 22:23:30 -050098
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070099TEST_F(AppendTest, XValueInt)
100{
101 int a = 1;
102 expect_basic<int>(SD_BUS_TYPE_INT32, a);
103 new_message().append(std::move(a));
104}
105
106TEST_F(AppendTest, RValueBool)
107{
108 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, true);
109 new_message().append(true);
110}
111
112TEST_F(AppendTest, LValueBool)
113{
114 const bool a = false;
115 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, false);
116 new_message().append(a);
117}
118
119TEST_F(AppendTest, XValueBool)
120{
121 bool a = false;
122 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, false);
123 new_message().append(std::move(a));
124}
125
126TEST_F(AppendTest, RValueDouble)
127{
128 expect_basic<double>(SD_BUS_TYPE_DOUBLE, 1.1);
129 new_message().append(1.1);
130}
131
132TEST_F(AppendTest, LValueDouble)
133{
134 const double a = 1.1;
135 expect_basic<double>(SD_BUS_TYPE_DOUBLE, a);
136 new_message().append(a);
137}
138
139TEST_F(AppendTest, XValueDouble)
140{
141 double a = 1.1;
142 expect_basic<double>(SD_BUS_TYPE_DOUBLE, a);
143 new_message().append(std::move(a));
144}
145
146TEST_F(AppendTest, RValueCString)
147{
148 expect_basic_string(SD_BUS_TYPE_STRING, "asdf");
149 new_message().append("asdf");
150}
151
152TEST_F(AppendTest, LValueCString)
153{
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700154 const char* const s = "asdf";
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700155 expect_basic_string(SD_BUS_TYPE_STRING, s);
156 new_message().append(s);
157}
158
159TEST_F(AppendTest, XValueCString)
160{
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700161 const char* s = "asdf";
Patrick Williamsb7329a92022-04-28 09:57:23 -0500162 static_assert(
163 sdbusplus::message::details::can_append_multiple_v<decltype(s)>);
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700164 expect_basic_string(SD_BUS_TYPE_STRING, s);
165 new_message().append(std::move(s));
166}
167
168TEST_F(AppendTest, RValueString)
169{
170 expect_basic_string(SD_BUS_TYPE_STRING, "asdf");
171 new_message().append(std::string{"asdf"});
172}
173
174TEST_F(AppendTest, LValueString)
175{
176 std::string s{"asdf"};
Patrick Williamsb7329a92022-04-28 09:57:23 -0500177 static_assert(
178 !sdbusplus::message::details::can_append_multiple_v<decltype(s)>);
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700179 expect_basic_string(SD_BUS_TYPE_STRING, s.c_str());
180 new_message().append(s);
181}
182
183TEST_F(AppendTest, XValueString)
184{
185 std::string s{"asdf"};
186 expect_basic_string(SD_BUS_TYPE_STRING, s.c_str());
187 new_message().append(std::move(s));
188}
189
190TEST_F(AppendTest, ObjectPath)
191{
192 sdbusplus::message::object_path o{"/asdf"};
193 expect_basic_string(SD_BUS_TYPE_OBJECT_PATH, o.str.c_str());
194 new_message().append(o);
195}
196
197TEST_F(AppendTest, Signature)
198{
199 sdbusplus::message::signature g{"ii"};
200 expect_basic_string(SD_BUS_TYPE_SIGNATURE, g.str.c_str());
201 new_message().append(g);
202}
203
204TEST_F(AppendTest, CombinedBasic)
205{
206 const int c = 3;
207 const std::string s1{"fdsa"};
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700208 const char* const s2 = "asdf";
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700209
Patrick Williams1807fa42016-08-01 22:23:30 -0500210 {
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700211 testing::InSequence seq;
212 expect_basic<int>(SD_BUS_TYPE_INT32, 1);
213 expect_basic<double>(SD_BUS_TYPE_DOUBLE, 2.2);
214 expect_basic<int>(SD_BUS_TYPE_INT32, c);
215 expect_basic_string(SD_BUS_TYPE_STRING, s1.c_str());
216 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, false);
217 expect_basic_string(SD_BUS_TYPE_STRING, s2);
218 }
219 new_message().append(1, 2.2, c, s1, false, s2);
220}
Patrick Williams1807fa42016-08-01 22:23:30 -0500221
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700222TEST_F(AppendTest, Array)
223{
224 const std::array<double, 4> a{1.1, 2.2, 3.3, 4.4};
Patrick Williamsb7329a92022-04-28 09:57:23 -0500225 static_assert(
226 !sdbusplus::message::details::can_append_multiple_v<decltype(a)>);
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700227
228 {
229 testing::InSequence seq;
230 expect_open_container(SD_BUS_TYPE_ARRAY, "d");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700231 for (const auto& i : a)
Patrick Williams1807fa42016-08-01 22:23:30 -0500232 {
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700233 expect_basic<double>(SD_BUS_TYPE_DOUBLE, i);
Patrick Williams1807fa42016-08-01 22:23:30 -0500234 }
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700235 expect_close_container();
236 }
237 new_message().append(a);
238}
Patrick Williams1807fa42016-08-01 22:23:30 -0500239
Patrick Williamsb7329a92022-04-28 09:57:23 -0500240TEST_F(AppendTest, Span)
241{
242 const std::array<double, 4> a{1.1, 2.2, 3.3, 4.4};
243 auto s = std::span{a};
244 static_assert(
245 !sdbusplus::message::details::can_append_multiple_v<decltype(s)>);
246
247 {
248 testing::InSequence seq;
249 expect_open_container(SD_BUS_TYPE_ARRAY, "d");
250 for (const auto& i : s)
251 {
252 expect_basic<double>(SD_BUS_TYPE_DOUBLE, i);
253 }
254 expect_close_container();
255 }
256 new_message().append(s);
257}
258
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700259TEST_F(AppendTest, Vector)
260{
261 const std::vector<int> v{1, 2, 3, 4};
262
263 {
264 testing::InSequence seq;
265 expect_open_container(SD_BUS_TYPE_ARRAY, "i");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700266 for (const auto& i : v)
Patrick Williams1807fa42016-08-01 22:23:30 -0500267 {
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700268 expect_basic<int>(SD_BUS_TYPE_INT32, i);
269 }
270 expect_close_container();
271 }
272 new_message().append(v);
273}
274
275TEST_F(AppendTest, Set)
276{
277 const std::set<std::string> s{"one", "two", "eight"};
278
279 {
280 testing::InSequence seq;
281 expect_open_container(SD_BUS_TYPE_ARRAY, "s");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700282 for (const auto& i : s)
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700283 {
284 expect_basic_string(SD_BUS_TYPE_STRING, i.c_str());
285 }
286 expect_close_container();
287 }
288 new_message().append(s);
289}
290
Patrick Williamsb98bdc62020-06-16 16:15:40 -0500291TEST_F(AppendTest, UnorderedSet)
292{
293 const std::unordered_set<std::string> s{"one", "two", "eight"};
294
295 {
296 testing::InSequence seq;
297 expect_open_container(SD_BUS_TYPE_ARRAY, "s");
298 for (const auto& i : s)
299 {
300 expect_basic_string(SD_BUS_TYPE_STRING, i.c_str());
301 }
302 expect_close_container();
303 }
304 new_message().append(s);
305}
306
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700307TEST_F(AppendTest, Map)
308{
309 const std::map<int, std::string> m{
310 {1, "a"},
311 {2, "bc"},
312 {3, "def"},
313 {4, "ghij"},
314 };
315
316 {
317 testing::InSequence seq;
318 expect_open_container(SD_BUS_TYPE_ARRAY, "{is}");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700319 for (const auto& i : m)
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700320 {
321 expect_open_container(SD_BUS_TYPE_DICT_ENTRY, "is");
322 expect_basic<int>(SD_BUS_TYPE_INT32, i.first);
323 expect_basic_string(SD_BUS_TYPE_STRING, i.second.c_str());
324 expect_close_container();
325 }
326 expect_close_container();
327 }
328 new_message().append(m);
329}
330
331TEST_F(AppendTest, UnorderedMap)
332{
333 const std::unordered_map<int, bool> m{
334 {1, false},
335 {2, true},
336 {3, true},
337 {4, false},
338 };
339
340 {
341 testing::InSequence seq;
342 expect_open_container(SD_BUS_TYPE_ARRAY, "{ib}");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700343 for (const auto& i : m)
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700344 {
345 expect_open_container(SD_BUS_TYPE_DICT_ENTRY, "ib");
346 expect_basic<int>(SD_BUS_TYPE_INT32, i.first);
347 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, i.second);
348 expect_close_container();
349 }
350 expect_close_container();
351 }
352 new_message().append(m);
353}
354
355TEST_F(AppendTest, Tuple)
356{
357 const std::tuple<int, std::string, bool> t{5, "asdf", false};
358
359 {
360 testing::InSequence seq;
361 expect_open_container(SD_BUS_TYPE_STRUCT, "isb");
362 expect_basic<int>(SD_BUS_TYPE_INT32, std::get<0>(t));
363 expect_basic_string(SD_BUS_TYPE_STRING, std::get<1>(t).c_str());
364 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, std::get<2>(t));
365 expect_close_container();
366 }
367 new_message().append(t);
368}
369
370TEST_F(AppendTest, Variant)
371{
372 const bool b1 = false;
373 const std::string s2{"asdf"};
William A. Kennington III4274c112018-11-26 09:50:13 -0800374 const std::variant<int, std::string, bool> v1{b1}, v2{s2};
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700375
376 {
377 testing::InSequence seq;
378 expect_open_container(SD_BUS_TYPE_VARIANT, "b");
379 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, b1);
380 expect_close_container();
381 expect_open_container(SD_BUS_TYPE_VARIANT, "s");
382 expect_basic_string(SD_BUS_TYPE_STRING, s2.c_str());
383 expect_close_container();
384 }
385 new_message().append(v1, v2);
386}
387
388TEST_F(AppendTest, LargeCombo)
389{
390 std::vector<std::array<std::string, 3>> vas{{"a", "b", "c"},
391 {"d", "", "e"}};
William A. Kennington III4274c112018-11-26 09:50:13 -0800392 std::map<std::string, std::variant<int, double>> msv = {
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700393 {"a", 3.3}, {"b", 1}, {"c", 4.4}};
394
395 {
396 testing::InSequence seq;
397
398 expect_open_container(SD_BUS_TYPE_ARRAY, "as");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700399 for (const auto& as : vas)
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700400 {
401 expect_open_container(SD_BUS_TYPE_ARRAY, "s");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700402 for (const auto& s : as)
Patrick Williams07e1d6f2016-09-08 15:54:09 -0500403 {
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700404 expect_basic_string(SD_BUS_TYPE_STRING, s.c_str());
405 }
406 expect_close_container();
407 }
408 expect_close_container();
409
410 expect_open_container(SD_BUS_TYPE_ARRAY, "{sv}");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700411 for (const auto& sv : msv)
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700412 {
413 expect_open_container(SD_BUS_TYPE_DICT_ENTRY, "sv");
414 expect_basic_string(SD_BUS_TYPE_STRING, sv.first.c_str());
William A. Kennington III4274c112018-11-26 09:50:13 -0800415 if (std::holds_alternative<int>(sv.second))
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700416 {
417 expect_open_container(SD_BUS_TYPE_VARIANT, "i");
William A. Kennington III4274c112018-11-26 09:50:13 -0800418 expect_basic<int>(SD_BUS_TYPE_INT32, std::get<int>(sv.second));
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700419 expect_close_container();
Patrick Williams07e1d6f2016-09-08 15:54:09 -0500420 }
421 else
422 {
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700423 expect_open_container(SD_BUS_TYPE_VARIANT, "d");
424 expect_basic<double>(SD_BUS_TYPE_DOUBLE,
William A. Kennington III4274c112018-11-26 09:50:13 -0800425 std::get<double>(sv.second));
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700426 expect_close_container();
Patrick Williams07e1d6f2016-09-08 15:54:09 -0500427 }
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700428 expect_close_container();
Patrick Williams1807fa42016-08-01 22:23:30 -0500429 }
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700430 expect_close_container();
Patrick Williams1807fa42016-08-01 22:23:30 -0500431 }
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700432 new_message().append(vas, msv);
Patrick Williams1807fa42016-08-01 22:23:30 -0500433}
434
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700435} // namespace