blob: 6485d997b37ca64d33486d5af1b677df5248781e [file] [log] [blame]
Patrick Venture95269db2018-08-31 09:19:17 -07001#include <systemd/sd-bus-protocol.h>
2
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -07003#include <array>
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -07004#include <map>
Patrick Williams7802c072016-09-02 15:20:22 -05005#include <sdbusplus/message.hpp>
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -07006#include <sdbusplus/test/sdbus_mock.hpp>
Ed Tanous28dc36d2018-02-21 12:22:54 -08007#include <set>
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -07008#include <string>
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -07009#include <tuple>
10#include <unordered_map>
11#include <vector>
Patrick Williams1807fa42016-08-01 22:23:30 -050012
Patrick Venture95269db2018-08-31 09:19:17 -070013#include <gmock/gmock.h>
14#include <gtest/gtest.h>
15
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070016namespace
Patrick Williams1807fa42016-08-01 22:23:30 -050017{
Patrick Williams5b485792016-08-02 07:35:14 -050018
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070019using testing::Eq;
20using testing::MatcherCast;
21using testing::Pointee;
22using testing::Return;
23using testing::SafeMatcherCast;
24using testing::StrEq;
25
26class AppendTest : public testing::Test
27{
28 protected:
29 testing::StrictMock<sdbusplus::SdBusMock> mock;
30
31 void SetUp() override
32 {
33 EXPECT_CALL(mock, sd_bus_message_new_method_call(testing::_, testing::_,
34 nullptr, nullptr,
35 nullptr, nullptr))
36 .WillRepeatedly(Return(0));
37 };
38
39 sdbusplus::message::message new_message()
40 {
41 return sdbusplus::get_mocked_new(&mock).new_method_call(
42 nullptr, nullptr, nullptr, nullptr);
43 }
44
45 template <typename T> void expect_basic(char type, T val)
46 {
47 EXPECT_CALL(mock,
48 sd_bus_message_append_basic(
49 nullptr, type,
50 MatcherCast<const void *>(
51 SafeMatcherCast<const T *>(Pointee(Eq(val))))))
52 .WillOnce(Return(0));
53 }
54
55 void expect_basic_string(char type, const char *str)
56 {
57 EXPECT_CALL(mock, sd_bus_message_append_basic(
58 nullptr, type,
59 MatcherCast<const void *>(
60 SafeMatcherCast<const char *>(StrEq(str)))))
61 .WillOnce(Return(0));
62 }
63
64 void expect_open_container(char type, const char *contents)
65 {
66 EXPECT_CALL(
67 mock, sd_bus_message_open_container(nullptr, type, StrEq(contents)))
68 .WillOnce(Return(0));
69 }
70
71 void expect_close_container()
72 {
73 EXPECT_CALL(mock, sd_bus_message_close_container(nullptr))
74 .WillOnce(Return(0));
75 }
76};
77
78TEST_F(AppendTest, RValueInt)
79{
80 expect_basic<int>(SD_BUS_TYPE_INT32, 1);
81 new_message().append(1);
Patrick Williams1807fa42016-08-01 22:23:30 -050082}
83
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070084TEST_F(AppendTest, LValueInt)
Patrick Williams1807fa42016-08-01 22:23:30 -050085{
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070086 const int a = 1;
87 expect_basic<int>(SD_BUS_TYPE_INT32, a);
88 new_message().append(a);
89}
Patrick Williams1807fa42016-08-01 22:23:30 -050090
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -070091TEST_F(AppendTest, XValueInt)
92{
93 int a = 1;
94 expect_basic<int>(SD_BUS_TYPE_INT32, a);
95 new_message().append(std::move(a));
96}
97
98TEST_F(AppendTest, RValueBool)
99{
100 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, true);
101 new_message().append(true);
102}
103
104TEST_F(AppendTest, LValueBool)
105{
106 const bool a = false;
107 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, false);
108 new_message().append(a);
109}
110
111TEST_F(AppendTest, XValueBool)
112{
113 bool a = false;
114 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, false);
115 new_message().append(std::move(a));
116}
117
118TEST_F(AppendTest, RValueDouble)
119{
120 expect_basic<double>(SD_BUS_TYPE_DOUBLE, 1.1);
121 new_message().append(1.1);
122}
123
124TEST_F(AppendTest, LValueDouble)
125{
126 const double a = 1.1;
127 expect_basic<double>(SD_BUS_TYPE_DOUBLE, a);
128 new_message().append(a);
129}
130
131TEST_F(AppendTest, XValueDouble)
132{
133 double a = 1.1;
134 expect_basic<double>(SD_BUS_TYPE_DOUBLE, a);
135 new_message().append(std::move(a));
136}
137
138TEST_F(AppendTest, RValueCString)
139{
140 expect_basic_string(SD_BUS_TYPE_STRING, "asdf");
141 new_message().append("asdf");
142}
143
144TEST_F(AppendTest, LValueCString)
145{
146 const char *const s = "asdf";
147 expect_basic_string(SD_BUS_TYPE_STRING, s);
148 new_message().append(s);
149}
150
151TEST_F(AppendTest, XValueCString)
152{
153 const char *s = "asdf";
154 expect_basic_string(SD_BUS_TYPE_STRING, s);
155 new_message().append(std::move(s));
156}
157
158TEST_F(AppendTest, RValueString)
159{
160 expect_basic_string(SD_BUS_TYPE_STRING, "asdf");
161 new_message().append(std::string{"asdf"});
162}
163
164TEST_F(AppendTest, LValueString)
165{
166 std::string s{"asdf"};
167 expect_basic_string(SD_BUS_TYPE_STRING, s.c_str());
168 new_message().append(s);
169}
170
171TEST_F(AppendTest, XValueString)
172{
173 std::string s{"asdf"};
174 expect_basic_string(SD_BUS_TYPE_STRING, s.c_str());
175 new_message().append(std::move(s));
176}
177
178TEST_F(AppendTest, ObjectPath)
179{
180 sdbusplus::message::object_path o{"/asdf"};
181 expect_basic_string(SD_BUS_TYPE_OBJECT_PATH, o.str.c_str());
182 new_message().append(o);
183}
184
185TEST_F(AppendTest, Signature)
186{
187 sdbusplus::message::signature g{"ii"};
188 expect_basic_string(SD_BUS_TYPE_SIGNATURE, g.str.c_str());
189 new_message().append(g);
190}
191
192TEST_F(AppendTest, CombinedBasic)
193{
194 const int c = 3;
195 const std::string s1{"fdsa"};
196 const char *const s2 = "asdf";
197
Patrick Williams1807fa42016-08-01 22:23:30 -0500198 {
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700199 testing::InSequence seq;
200 expect_basic<int>(SD_BUS_TYPE_INT32, 1);
201 expect_basic<double>(SD_BUS_TYPE_DOUBLE, 2.2);
202 expect_basic<int>(SD_BUS_TYPE_INT32, c);
203 expect_basic_string(SD_BUS_TYPE_STRING, s1.c_str());
204 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, false);
205 expect_basic_string(SD_BUS_TYPE_STRING, s2);
206 }
207 new_message().append(1, 2.2, c, s1, false, s2);
208}
Patrick Williams1807fa42016-08-01 22:23:30 -0500209
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700210TEST_F(AppendTest, Array)
211{
212 const std::array<double, 4> a{1.1, 2.2, 3.3, 4.4};
213
214 {
215 testing::InSequence seq;
216 expect_open_container(SD_BUS_TYPE_ARRAY, "d");
217 for (const auto &i : a)
Patrick Williams1807fa42016-08-01 22:23:30 -0500218 {
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700219 expect_basic<double>(SD_BUS_TYPE_DOUBLE, i);
Patrick Williams1807fa42016-08-01 22:23:30 -0500220 }
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700221 expect_close_container();
222 }
223 new_message().append(a);
224}
Patrick Williams1807fa42016-08-01 22:23:30 -0500225
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700226TEST_F(AppendTest, Vector)
227{
228 const std::vector<int> v{1, 2, 3, 4};
229
230 {
231 testing::InSequence seq;
232 expect_open_container(SD_BUS_TYPE_ARRAY, "i");
233 for (const auto &i : v)
Patrick Williams1807fa42016-08-01 22:23:30 -0500234 {
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700235 expect_basic<int>(SD_BUS_TYPE_INT32, i);
236 }
237 expect_close_container();
238 }
239 new_message().append(v);
240}
241
242TEST_F(AppendTest, Set)
243{
244 const std::set<std::string> s{"one", "two", "eight"};
245
246 {
247 testing::InSequence seq;
248 expect_open_container(SD_BUS_TYPE_ARRAY, "s");
249 for (const auto &i : s)
250 {
251 expect_basic_string(SD_BUS_TYPE_STRING, i.c_str());
252 }
253 expect_close_container();
254 }
255 new_message().append(s);
256}
257
258TEST_F(AppendTest, Map)
259{
260 const std::map<int, std::string> m{
261 {1, "a"},
262 {2, "bc"},
263 {3, "def"},
264 {4, "ghij"},
265 };
266
267 {
268 testing::InSequence seq;
269 expect_open_container(SD_BUS_TYPE_ARRAY, "{is}");
270 for (const auto &i : m)
271 {
272 expect_open_container(SD_BUS_TYPE_DICT_ENTRY, "is");
273 expect_basic<int>(SD_BUS_TYPE_INT32, i.first);
274 expect_basic_string(SD_BUS_TYPE_STRING, i.second.c_str());
275 expect_close_container();
276 }
277 expect_close_container();
278 }
279 new_message().append(m);
280}
281
282TEST_F(AppendTest, UnorderedMap)
283{
284 const std::unordered_map<int, bool> m{
285 {1, false},
286 {2, true},
287 {3, true},
288 {4, false},
289 };
290
291 {
292 testing::InSequence seq;
293 expect_open_container(SD_BUS_TYPE_ARRAY, "{ib}");
294 for (const auto &i : m)
295 {
296 expect_open_container(SD_BUS_TYPE_DICT_ENTRY, "ib");
297 expect_basic<int>(SD_BUS_TYPE_INT32, i.first);
298 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, i.second);
299 expect_close_container();
300 }
301 expect_close_container();
302 }
303 new_message().append(m);
304}
305
306TEST_F(AppendTest, Tuple)
307{
308 const std::tuple<int, std::string, bool> t{5, "asdf", false};
309
310 {
311 testing::InSequence seq;
312 expect_open_container(SD_BUS_TYPE_STRUCT, "isb");
313 expect_basic<int>(SD_BUS_TYPE_INT32, std::get<0>(t));
314 expect_basic_string(SD_BUS_TYPE_STRING, std::get<1>(t).c_str());
315 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, std::get<2>(t));
316 expect_close_container();
317 }
318 new_message().append(t);
319}
320
321TEST_F(AppendTest, Variant)
322{
323 const bool b1 = false;
324 const std::string s2{"asdf"};
325 const sdbusplus::message::variant<int, std::string, bool> v1{b1}, v2{s2};
326
327 {
328 testing::InSequence seq;
329 expect_open_container(SD_BUS_TYPE_VARIANT, "b");
330 expect_basic<int>(SD_BUS_TYPE_BOOLEAN, b1);
331 expect_close_container();
332 expect_open_container(SD_BUS_TYPE_VARIANT, "s");
333 expect_basic_string(SD_BUS_TYPE_STRING, s2.c_str());
334 expect_close_container();
335 }
336 new_message().append(v1, v2);
337}
338
339TEST_F(AppendTest, LargeCombo)
340{
341 std::vector<std::array<std::string, 3>> vas{{"a", "b", "c"},
342 {"d", "", "e"}};
343 std::map<std::string, sdbusplus::message::variant<int, double>> msv = {
344 {"a", 3.3}, {"b", 1}, {"c", 4.4}};
345
346 {
347 testing::InSequence seq;
348
349 expect_open_container(SD_BUS_TYPE_ARRAY, "as");
350 for (const auto &as : vas)
351 {
352 expect_open_container(SD_BUS_TYPE_ARRAY, "s");
353 for (const auto &s : as)
Patrick Williams07e1d6f2016-09-08 15:54:09 -0500354 {
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700355 expect_basic_string(SD_BUS_TYPE_STRING, s.c_str());
356 }
357 expect_close_container();
358 }
359 expect_close_container();
360
361 expect_open_container(SD_BUS_TYPE_ARRAY, "{sv}");
362 for (const auto &sv : msv)
363 {
364 expect_open_container(SD_BUS_TYPE_DICT_ENTRY, "sv");
365 expect_basic_string(SD_BUS_TYPE_STRING, sv.first.c_str());
366 if (sv.second.is<int>())
367 {
368 expect_open_container(SD_BUS_TYPE_VARIANT, "i");
369 expect_basic<int>(SD_BUS_TYPE_INT32, sv.second.get<int>());
370 expect_close_container();
Patrick Williams07e1d6f2016-09-08 15:54:09 -0500371 }
372 else
373 {
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700374 expect_open_container(SD_BUS_TYPE_VARIANT, "d");
375 expect_basic<double>(SD_BUS_TYPE_DOUBLE,
376 sv.second.get<double>());
377 expect_close_container();
Patrick Williams07e1d6f2016-09-08 15:54:09 -0500378 }
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700379 expect_close_container();
Patrick Williams1807fa42016-08-01 22:23:30 -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 new_message().append(vas, msv);
Patrick Williams1807fa42016-08-01 22:23:30 -0500384}
385
William A. Kennington IIIa1e9e2a2018-06-23 13:33:25 -0700386} // namespace