1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 #include <CommonAPI/SerializableStruct.h>
5 #include <CommonAPI/DBus/DBusInputStream.h>
6 #include <CommonAPI/DBus/DBusOutputStream.h>
8 #include <unordered_map>
9 #include <bits/functional_hash.h>
11 #include <gtest/gtest.h>
13 #include <dbus/dbus.h>
18 #include <unordered_map>
19 #include <bits/functional_hash.h>
22 class InputStreamTest: public ::testing::Test {
24 DBusMessage* libdbusMessage;
25 DBusMessageIter libdbusMessageWriteIter;
30 libdbusMessage = dbus_message_new_method_call("no.bus.here", "/no/object/here", NULL, "noMethodHere");
31 ASSERT_TRUE(libdbusMessage != NULL);
32 dbus_message_iter_init_append(libdbusMessage, &libdbusMessageWriteIter);
36 dbus_message_unref(libdbusMessage);
40 TEST_F(InputStreamTest, CanBeConstructed) {
41 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
42 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
45 TEST_F(InputStreamTest, ReadsEmptyMessages) {
46 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
47 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
49 EXPECT_EQ(0, scopedMessage.getBodyLength());
52 TEST_F(InputStreamTest, ReadsBytes) {
54 for (int i = 0; i < numOfElements; i += 1) {
55 dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_BYTE, &val);
58 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
59 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
61 EXPECT_EQ(numOfElements, scopedMessage.getBodyLength());
62 for (int i = 0; i < numOfElements; i += 1) {
65 EXPECT_EQ(val, readVal);
69 TEST_F(InputStreamTest, ReadsBools) {
70 dbus_bool_t f = FALSE;
72 for (int i = 0; i < numOfElements; i += 2) {
73 dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_BOOLEAN, &t);
74 dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_BOOLEAN, &f);
77 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
78 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
80 EXPECT_EQ(numOfElements*4, scopedMessage.getBodyLength());
81 for (int i = 0; i < numOfElements; i += 2) {
84 EXPECT_EQ(t, readVal);
86 EXPECT_EQ(f, readVal);
90 TEST_F(InputStreamTest, ReadsUint16) {
92 uint16_t val = 0xffff;
93 for (int i = 0; i < numOfElements; i += 1) {
94 dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_UINT16, &val);
97 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
98 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
100 EXPECT_EQ(numOfElements*2, scopedMessage.getBodyLength());
101 for (int i = 0; i < numOfElements; i += 1) {
104 EXPECT_EQ(val, readVal);
108 TEST_F(InputStreamTest, ReadsInt16) {
110 int16_t val = 0x7fff;
111 for (int i = 0; i < numOfElements; i += 1) {
112 dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_INT16, &val);
115 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
116 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
118 EXPECT_EQ(numOfElements*2, scopedMessage.getBodyLength());
119 for (int i = 0; i < numOfElements; i += 1) {
122 EXPECT_EQ(val, readVal);
126 TEST_F(InputStreamTest, ReadsUint32) {
128 uint32_t val = 0xffffffff;
129 for (int i = 0; i < numOfElements; i += 1) {
130 dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_UINT32, &val);
133 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
134 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
136 EXPECT_EQ(numOfElements*4, scopedMessage.getBodyLength());
137 for (int i = 0; i < numOfElements; i += 1) {
140 EXPECT_EQ(val, readVal);
144 TEST_F(InputStreamTest, ReadsInt32) {
146 int32_t val = 0x7fffffff;
147 for (int i = 0; i < numOfElements; i += 1) {
148 dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_INT32, &val);
151 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
152 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
154 EXPECT_EQ(numOfElements*4, scopedMessage.getBodyLength());
155 for (int i = 0; i < numOfElements; i += 1) {
158 EXPECT_EQ(val, readVal);
162 TEST_F(InputStreamTest, ReadsUint64) {
164 uint64_t val = 0xffffffffffffffff;
165 for (int i = 0; i < numOfElements; i += 1) {
166 dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_UINT64, &val);
169 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
170 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
172 EXPECT_EQ(numOfElements*8, scopedMessage.getBodyLength());
173 for (int i = 0; i < numOfElements; i += 1) {
176 EXPECT_EQ(val, readVal);
180 TEST_F(InputStreamTest, ReadsInt64) {
182 int64_t val = 0x7fffffffffffffff;
183 for (int i = 0; i < numOfElements; i += 1) {
184 dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_INT64, &val);
187 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
188 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
190 EXPECT_EQ(numOfElements*8, scopedMessage.getBodyLength());
191 for (int i = 0; i < numOfElements; i += 1) {
194 EXPECT_EQ(val, readVal);
198 TEST_F(InputStreamTest, ReadsDoubles) {
201 for (int i = 0; i < numOfElements; i += 1) {
202 dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_DOUBLE, &val);
205 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
206 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
208 EXPECT_EQ(numOfElements*8, scopedMessage.getBodyLength());
209 for (int i = 0; i < numOfElements; i += 1) {
212 EXPECT_EQ(val, readVal);
216 TEST_F(InputStreamTest, ReadsStrings) {
218 std::string val = "hai";
219 for (int i = 0; i < numOfElements; i += 1) {
220 dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_STRING, &val);
223 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
224 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
226 EXPECT_EQ(numOfElements*4 + numOfElements*4, scopedMessage.getBodyLength());
227 for (int i = 0; i < numOfElements; i += 1) {
230 EXPECT_EQ(val, readVal);
237 struct TestSerializableStruct: CommonAPI::SerializableStruct {
244 virtual void readFromInputStream(CommonAPI::InputStream& inputStream) {
245 inputStream >> a >> b >> c >> d >> e;
248 virtual void writeToOutputStream(CommonAPI::OutputStream& outputStream) const {
249 outputStream << a << b << c << d << e;
256 TEST_F(InputStreamTest, ReadsStructs) {
258 bmw::test::TestSerializableStruct testStruct;
261 testStruct.c = FALSE;
262 testStruct.d = "Hello all";
263 testStruct.e = 3.414;
265 DBusMessageIter subIter;
266 dbus_message_iter_open_container(&libdbusMessageWriteIter, DBUS_TYPE_STRUCT, NULL, &subIter);
267 dbus_message_iter_append_basic(&subIter, DBUS_TYPE_UINT32, &testStruct.a);
268 dbus_message_iter_append_basic(&subIter, DBUS_TYPE_INT16, &testStruct.b);
269 dbus_bool_t dbusBool = static_cast<dbus_bool_t>(testStruct.c);
270 dbus_message_iter_append_basic(&subIter, DBUS_TYPE_BOOLEAN, &dbusBool);
271 dbus_message_iter_append_basic(&subIter, DBUS_TYPE_STRING, &testStruct.d);
272 dbus_message_iter_append_basic(&subIter, DBUS_TYPE_DOUBLE, &testStruct.e);
273 dbus_message_iter_close_container(&libdbusMessageWriteIter, &subIter);
275 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
276 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
278 //40(byte length of struct) = 4(uint32_t) + 2(int16_t) + 2(padding) + 4(bool) + 4(strlength)
279 // + 9(string) + 1(terminating '\0' of string) + 6(padding) + 8 (double)
280 EXPECT_EQ(40, scopedMessage.getBodyLength());
282 bmw::test::TestSerializableStruct verifyStruct;
283 inStream >> verifyStruct;
284 EXPECT_EQ(testStruct.a, verifyStruct.a);
285 EXPECT_EQ(testStruct.b, verifyStruct.b);
286 EXPECT_EQ(testStruct.c, verifyStruct.c);
287 EXPECT_EQ(testStruct.d, verifyStruct.d);
288 EXPECT_EQ(testStruct.e, verifyStruct.e);
291 TEST_F(InputStreamTest, ReadsArrays) {
293 std::vector<int32_t> testVector;
294 int32_t val1 = 0xffffffff;
295 int32_t val2 = 0x7fffffff;
296 for (int i = 0; i < numOfElements; i += 2) {
297 testVector.push_back(val1);
298 testVector.push_back(val2);
301 DBusMessageIter subIter;
302 dbus_message_iter_open_container(&libdbusMessageWriteIter, DBUS_TYPE_ARRAY, "i", &subIter);
303 for (int i = 0; i < numOfElements; i++) {
304 dbus_message_iter_append_basic(&subIter, DBUS_TYPE_INT32, &testVector[i]);
306 dbus_message_iter_close_container(&libdbusMessageWriteIter, &subIter);
308 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
309 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
311 EXPECT_EQ(scopedMessage.getBodyLength(), numOfElements*4 + 4);
312 std::vector<int32_t> verifyVector;
313 inStream >> verifyVector;
316 for (int i = 0; i < numOfElements; i += 2) {
317 res1 = verifyVector[i];
318 EXPECT_EQ(val1, res1);
319 res2 = verifyVector[i + 1];
320 EXPECT_EQ(val2, res2);
324 TEST_F(InputStreamTest, ReadsArraysInArrays) {
325 size_t numOfElements = 2;
326 DBusMessage* dbusMessage = dbus_message_new_method_call("no.bus.here", "/no/object/here", NULL, "noMethodHere");
327 ASSERT_TRUE(dbusMessage != NULL);
329 DBusMessageIter writeIter;
330 dbus_message_iter_init_append(dbusMessage, &writeIter);
332 std::vector<std::vector<int32_t>> testVector;
333 int32_t val1 = 0xffffffff;
334 int32_t val2 = 0x7fffffff;
335 for (int i = 0; i < numOfElements; i++) {
336 std::vector<int32_t> inner;
337 for (int j = 0; j < numOfElements; j += 2) {
338 inner.push_back(val1);
339 inner.push_back(val2);
341 testVector.push_back(inner);
344 DBusMessageIter subIter;
345 dbus_message_iter_open_container(&writeIter, DBUS_TYPE_ARRAY, "ai", &subIter);
346 for (int i = 0; i < numOfElements; i++) {
347 DBusMessageIter subsubIter;
348 dbus_message_iter_open_container(&subIter, DBUS_TYPE_ARRAY, "i", &subsubIter);
349 for (int j = 0; j < numOfElements; j++) {
350 dbus_message_iter_append_basic(&subsubIter, DBUS_TYPE_INT32, &(testVector[i][j]));
352 dbus_message_iter_close_container(&subIter, &subsubIter);
354 dbus_message_iter_close_container(&writeIter, &subIter);
356 CommonAPI::DBus::DBusMessage scopedMessage(dbusMessage);
357 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
359 // 5*5*int32_t + 5*lengthField_inner(int32_t) + lengthField_outer(int32_t)
360 EXPECT_EQ(numOfElements*numOfElements*4 + numOfElements*4 + 4, scopedMessage.getBodyLength());
361 std::vector<std::vector<int32_t>> verifyVector;
362 inStream >> verifyVector;
366 for (int i = 0; i < numOfElements; i++) {
367 std::vector<int32_t> innerVerify = verifyVector[i];
368 for (int j = 0; j < numOfElements; j += 2) {
369 res1 = innerVerify[j];
370 EXPECT_EQ(val1, res1);
371 res2 = innerVerify[j + 1];
372 EXPECT_EQ(val2, res2);
377 int main(int argc, char** argv) {
378 ::testing::InitGoogleTest(&argc, argv);
379 return RUN_ALL_TESTS();