blob: c6eb15278f9e6839ae507d37e575dcaf8251d67c [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>
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -07009#include <string>
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070010#include <tuple>
11#include <unordered_map>
William A. Kennington III4274c112018-11-26 09:50:13 -080012#include <variant>
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070013#include <vector>
Patrick Williams1807fa42016-08-01 22:23:30 -050014
Patrick Venture95269db2018-08-31 09:19:17 -070015#include <gmock/gmock.h>
16#include <gtest/gtest.h>
17
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070018namespace
Patrick Williams1807fa42016-08-01 22:23:30 -050019{
Patrick Williams5b485792016-08-02 07:35:14 -050020
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070021using testing::Eq;
22using testing::MatcherCast;
23using testing::Pointee;
24using testing::Return;
25using testing::SafeMatcherCast;
26using testing::StrEq;
27
28class AppendTest : public testing::Test
29{
30 protected:
31 testing::StrictMock<sdbusplus::SdBusMock> mock;
32
33 void SetUp() override
34 {
35 EXPECT_CALL(mock, sd_bus_message_new_method_call(testing::_, testing::_,
36 nullptr, nullptr,
37 nullptr, nullptr))
38 .WillRepeatedly(Return(0));
39 };
40
41 sdbusplus::message::message new_message()
42 {
43 return sdbusplus::get_mocked_new(&mock).new_method_call(
44 nullptr, nullptr, nullptr, nullptr);
45 }
46
Patrick Venture2b238af2018-08-31 12:45:01 -070047 template <typename T>
48 void expect_basic(char type, T val)
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070049 {
William A. Kennington IIIe0d69652018-08-31 13:09:47 -070050 EXPECT_CALL(mock, sd_bus_message_append_basic(
51 nullptr, type,
52 MatcherCast<const void*>(
53 SafeMatcherCast<const T*>(Pointee(Eq(val))))))
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070054 .WillOnce(Return(0));
55 }
56
William A. Kennington IIIe0d69652018-08-31 13:09:47 -070057 void expect_basic_string(char type, const char* str)
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070058 {
59 EXPECT_CALL(mock, sd_bus_message_append_basic(
60 nullptr, type,
William A. Kennington IIIe0d69652018-08-31 13:09:47 -070061 MatcherCast<const void*>(
62 SafeMatcherCast<const char*>(StrEq(str)))))
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070063 .WillOnce(Return(0));
64 }
65
William A. Kennington IIIe0d69652018-08-31 13:09:47 -070066 void expect_open_container(char type, const char* contents)
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070067 {
68 EXPECT_CALL(
69 mock, sd_bus_message_open_container(nullptr, type, StrEq(contents)))
70 .WillOnce(Return(0));
71 }
72
73 void expect_close_container()
74 {
75 EXPECT_CALL(mock, sd_bus_message_close_container(nullptr))
76 .WillOnce(Return(0));
77 }
78};
79
80TEST_F(AppendTest, RValueInt)
81{
82 expect_basic<int>(SD_BUS_TYPE_INT32, 1);
83 new_message().append(1);
Patrick Williams1807fa42016-08-01 22:23:30 -050084}
85
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070086TEST_F(AppendTest, LValueInt)
Patrick Williams1807fa42016-08-01 22:23:30 -050087{
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070088 const int a = 1;
89 expect_basic<int>(SD_BUS_TYPE_INT32, a);
90 new_message().append(a);
91}
Patrick Williams1807fa42016-08-01 22:23:30 -050092
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070093TEST_F(AppendTest, XValueInt)
94{
95 int a = 1;
96 expect_basic<int>(SD_BUS_TYPE_INT32, a);
97 new_message().append(std::move(a));
98}
99
100TEST_F(AppendTest, RValueBool)
101{
102 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, true);
103 new_message().append(true);
104}
105
106TEST_F(AppendTest, LValueBool)
107{
108 const bool a = false;
109 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, false);
110 new_message().append(a);
111}
112
113TEST_F(AppendTest, XValueBool)
114{
115 bool a = false;
116 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, false);
117 new_message().append(std::move(a));
118}
119
120TEST_F(AppendTest, RValueDouble)
121{
122 expect_basic<double>(SD_BUS_TYPE_DOUBLE, 1.1);
123 new_message().append(1.1);
124}
125
126TEST_F(AppendTest, LValueDouble)
127{
128 const double a = 1.1;
129 expect_basic<double>(SD_BUS_TYPE_DOUBLE, a);
130 new_message().append(a);
131}
132
133TEST_F(AppendTest, XValueDouble)
134{
135 double a = 1.1;
136 expect_basic<double>(SD_BUS_TYPE_DOUBLE, a);
137 new_message().append(std::move(a));
138}
139
140TEST_F(AppendTest, RValueCString)
141{
142 expect_basic_string(SD_BUS_TYPE_STRING, "asdf");
143 new_message().append("asdf");
144}
145
146TEST_F(AppendTest, LValueCString)
147{
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700148 const char* const s = "asdf";
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700149 expect_basic_string(SD_BUS_TYPE_STRING, s);
150 new_message().append(s);
151}
152
153TEST_F(AppendTest, XValueCString)
154{
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700155 const char* s = "asdf";
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700156 expect_basic_string(SD_BUS_TYPE_STRING, s);
157 new_message().append(std::move(s));
158}
159
160TEST_F(AppendTest, RValueString)
161{
162 expect_basic_string(SD_BUS_TYPE_STRING, "asdf");
163 new_message().append(std::string{"asdf"});
164}
165
166TEST_F(AppendTest, LValueString)
167{
168 std::string s{"asdf"};
169 expect_basic_string(SD_BUS_TYPE_STRING, s.c_str());
170 new_message().append(s);
171}
172
173TEST_F(AppendTest, XValueString)
174{
175 std::string s{"asdf"};
176 expect_basic_string(SD_BUS_TYPE_STRING, s.c_str());
177 new_message().append(std::move(s));
178}
179
180TEST_F(AppendTest, ObjectPath)
181{
182 sdbusplus::message::object_path o{"/asdf"};
183 expect_basic_string(SD_BUS_TYPE_OBJECT_PATH, o.str.c_str());
184 new_message().append(o);
185}
186
187TEST_F(AppendTest, Signature)
188{
189 sdbusplus::message::signature g{"ii"};
190 expect_basic_string(SD_BUS_TYPE_SIGNATURE, g.str.c_str());
191 new_message().append(g);
192}
193
194TEST_F(AppendTest, CombinedBasic)
195{
196 const int c = 3;
197 const std::string s1{"fdsa"};
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700198 const char* const s2 = "asdf";
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700199
Patrick Williams1807fa42016-08-01 22:23:30 -0500200 {
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700201 testing::InSequence seq;
202 expect_basic<int>(SD_BUS_TYPE_INT32, 1);
203 expect_basic<double>(SD_BUS_TYPE_DOUBLE, 2.2);
204 expect_basic<int>(SD_BUS_TYPE_INT32, c);
205 expect_basic_string(SD_BUS_TYPE_STRING, s1.c_str());
206 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, false);
207 expect_basic_string(SD_BUS_TYPE_STRING, s2);
208 }
209 new_message().append(1, 2.2, c, s1, false, s2);
210}
Patrick Williams1807fa42016-08-01 22:23:30 -0500211
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700212TEST_F(AppendTest, Array)
213{
214 const std::array<double, 4> a{1.1, 2.2, 3.3, 4.4};
215
216 {
217 testing::InSequence seq;
218 expect_open_container(SD_BUS_TYPE_ARRAY, "d");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700219 for (const auto& i : a)
Patrick Williams1807fa42016-08-01 22:23:30 -0500220 {
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700221 expect_basic<double>(SD_BUS_TYPE_DOUBLE, i);
Patrick Williams1807fa42016-08-01 22:23:30 -0500222 }
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700223 expect_close_container();
224 }
225 new_message().append(a);
226}
Patrick Williams1807fa42016-08-01 22:23:30 -0500227
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700228TEST_F(AppendTest, Vector)
229{
230 const std::vector<int> v{1, 2, 3, 4};
231
232 {
233 testing::InSequence seq;
234 expect_open_container(SD_BUS_TYPE_ARRAY, "i");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700235 for (const auto& i : v)
Patrick Williams1807fa42016-08-01 22:23:30 -0500236 {
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700237 expect_basic<int>(SD_BUS_TYPE_INT32, i);
238 }
239 expect_close_container();
240 }
241 new_message().append(v);
242}
243
244TEST_F(AppendTest, Set)
245{
246 const std::set<std::string> s{"one", "two", "eight"};
247
248 {
249 testing::InSequence seq;
250 expect_open_container(SD_BUS_TYPE_ARRAY, "s");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700251 for (const auto& i : s)
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700252 {
253 expect_basic_string(SD_BUS_TYPE_STRING, i.c_str());
254 }
255 expect_close_container();
256 }
257 new_message().append(s);
258}
259
260TEST_F(AppendTest, Map)
261{
262 const std::map<int, std::string> m{
263 {1, "a"},
264 {2, "bc"},
265 {3, "def"},
266 {4, "ghij"},
267 };
268
269 {
270 testing::InSequence seq;
271 expect_open_container(SD_BUS_TYPE_ARRAY, "{is}");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700272 for (const auto& i : m)
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700273 {
274 expect_open_container(SD_BUS_TYPE_DICT_ENTRY, "is");
275 expect_basic<int>(SD_BUS_TYPE_INT32, i.first);
276 expect_basic_string(SD_BUS_TYPE_STRING, i.second.c_str());
277 expect_close_container();
278 }
279 expect_close_container();
280 }
281 new_message().append(m);
282}
283
284TEST_F(AppendTest, UnorderedMap)
285{
286 const std::unordered_map<int, bool> m{
287 {1, false},
288 {2, true},
289 {3, true},
290 {4, false},
291 };
292
293 {
294 testing::InSequence seq;
295 expect_open_container(SD_BUS_TYPE_ARRAY, "{ib}");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700296 for (const auto& i : m)
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700297 {
298 expect_open_container(SD_BUS_TYPE_DICT_ENTRY, "ib");
299 expect_basic<int>(SD_BUS_TYPE_INT32, i.first);
300 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, i.second);
301 expect_close_container();
302 }
303 expect_close_container();
304 }
305 new_message().append(m);
306}
307
308TEST_F(AppendTest, Tuple)
309{
310 const std::tuple<int, std::string, bool> t{5, "asdf", false};
311
312 {
313 testing::InSequence seq;
314 expect_open_container(SD_BUS_TYPE_STRUCT, "isb");
315 expect_basic<int>(SD_BUS_TYPE_INT32, std::get<0>(t));
316 expect_basic_string(SD_BUS_TYPE_STRING, std::get<1>(t).c_str());
317 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, std::get<2>(t));
318 expect_close_container();
319 }
320 new_message().append(t);
321}
322
323TEST_F(AppendTest, Variant)
324{
325 const bool b1 = false;
326 const std::string s2{"asdf"};
William A. Kennington III4274c112018-11-26 09:50:13 -0800327 const std::variant<int, std::string, bool> v1{b1}, v2{s2};
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700328
329 {
330 testing::InSequence seq;
331 expect_open_container(SD_BUS_TYPE_VARIANT, "b");
332 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, b1);
333 expect_close_container();
334 expect_open_container(SD_BUS_TYPE_VARIANT, "s");
335 expect_basic_string(SD_BUS_TYPE_STRING, s2.c_str());
336 expect_close_container();
337 }
338 new_message().append(v1, v2);
339}
340
341TEST_F(AppendTest, LargeCombo)
342{
343 std::vector<std::array<std::string, 3>> vas{{"a", "b", "c"},
344 {"d", "", "e"}};
William A. Kennington III4274c112018-11-26 09:50:13 -0800345 std::map<std::string, std::variant<int, double>> msv = {
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700346 {"a", 3.3}, {"b", 1}, {"c", 4.4}};
347
348 {
349 testing::InSequence seq;
350
351 expect_open_container(SD_BUS_TYPE_ARRAY, "as");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700352 for (const auto& as : vas)
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700353 {
354 expect_open_container(SD_BUS_TYPE_ARRAY, "s");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700355 for (const auto& s : as)
Patrick Williams07e1d6f2016-09-08 15:54:09 -0500356 {
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700357 expect_basic_string(SD_BUS_TYPE_STRING, s.c_str());
358 }
359 expect_close_container();
360 }
361 expect_close_container();
362
363 expect_open_container(SD_BUS_TYPE_ARRAY, "{sv}");
William A. Kennington IIIe0d69652018-08-31 13:09:47 -0700364 for (const auto& sv : msv)
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700365 {
366 expect_open_container(SD_BUS_TYPE_DICT_ENTRY, "sv");
367 expect_basic_string(SD_BUS_TYPE_STRING, sv.first.c_str());
William A. Kennington III4274c112018-11-26 09:50:13 -0800368 if (std::holds_alternative<int>(sv.second))
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700369 {
370 expect_open_container(SD_BUS_TYPE_VARIANT, "i");
William A. Kennington III4274c112018-11-26 09:50:13 -0800371 expect_basic<int>(SD_BUS_TYPE_INT32, std::get<int>(sv.second));
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700372 expect_close_container();
Patrick Williams07e1d6f2016-09-08 15:54:09 -0500373 }
374 else
375 {
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700376 expect_open_container(SD_BUS_TYPE_VARIANT, "d");
377 expect_basic<double>(SD_BUS_TYPE_DOUBLE,
William A. Kennington III4274c112018-11-26 09:50:13 -0800378 std::get<double>(sv.second));
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700379 expect_close_container();
Patrick Williams07e1d6f2016-09-08 15:54:09 -0500380 }
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700381 expect_close_container();
Patrick Williams1807fa42016-08-01 22:23:30 -0500382 }
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700383 expect_close_container();
Patrick Williams1807fa42016-08-01 22:23:30 -0500384 }
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700385 new_message().append(vas, msv);
Patrick Williams1807fa42016-08-01 22:23:30 -0500386}
387
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700388} // namespace