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