1 /* Copyright (C) 2013 BMW Group
2 * Author: Manfred Bathelt (manfred.bathelt@bmw.de)
3 * Author: Juergen Gehring (juergen.gehring@bmw.de)
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include <CommonAPI/SerializableStruct.h>
8 #include <CommonAPI/DBus/DBusInputStream.h>
9 #include <CommonAPI/DBus/DBusOutputStream.h>
11 #include <unordered_map>
12 #include <bits/functional_hash.h>
14 #include <gtest/gtest.h>
16 #include <dbus/dbus.h>
21 #include <unordered_map>
22 #include <bits/functional_hash.h>
25 class InputStreamTest: public ::testing::Test {
27 DBusMessage* libdbusMessage;
28 DBusMessageIter libdbusMessageWriteIter;
33 libdbusMessage = dbus_message_new_method_call("no.bus.here", "/no/object/here", NULL, "noMethodHere");
34 ASSERT_TRUE(libdbusMessage != NULL);
35 dbus_message_iter_init_append(libdbusMessage, &libdbusMessageWriteIter);
39 dbus_message_unref(libdbusMessage);
43 TEST_F(InputStreamTest, CanBeConstructed) {
44 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
45 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
48 TEST_F(InputStreamTest, ReadsEmptyMessages) {
49 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
50 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
52 EXPECT_EQ(0, scopedMessage.getBodyLength());
55 TEST_F(InputStreamTest, ReadsBytes) {
57 for (int i = 0; i < numOfElements; i += 1) {
58 dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_BYTE, &val);
61 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
62 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
64 EXPECT_EQ(numOfElements, scopedMessage.getBodyLength());
65 for (int i = 0; i < numOfElements; i += 1) {
68 EXPECT_EQ(val, readVal);
72 TEST_F(InputStreamTest, ReadsBools) {
73 dbus_bool_t f = FALSE;
75 for (int i = 0; i < numOfElements; i += 2) {
76 dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_BOOLEAN, &t);
77 dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_BOOLEAN, &f);
80 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
81 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
83 EXPECT_EQ(numOfElements*4, scopedMessage.getBodyLength());
84 for (int i = 0; i < numOfElements; i += 2) {
87 EXPECT_EQ(t, readVal);
89 EXPECT_EQ(f, readVal);
93 TEST_F(InputStreamTest, ReadsUint16) {
95 uint16_t val = 0xffff;
96 for (int i = 0; i < numOfElements; i += 1) {
97 dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_UINT16, &val);
100 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
101 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
103 EXPECT_EQ(numOfElements*2, scopedMessage.getBodyLength());
104 for (int i = 0; i < numOfElements; i += 1) {
107 EXPECT_EQ(val, readVal);
111 TEST_F(InputStreamTest, ReadsInt16) {
113 int16_t val = 0x7fff;
114 for (int i = 0; i < numOfElements; i += 1) {
115 dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_INT16, &val);
118 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
119 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
121 EXPECT_EQ(numOfElements*2, scopedMessage.getBodyLength());
122 for (int i = 0; i < numOfElements; i += 1) {
125 EXPECT_EQ(val, readVal);
129 TEST_F(InputStreamTest, ReadsUint32) {
131 uint32_t val = 0xffffffff;
132 for (int i = 0; i < numOfElements; i += 1) {
133 dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_UINT32, &val);
136 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
137 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
139 EXPECT_EQ(numOfElements*4, scopedMessage.getBodyLength());
140 for (int i = 0; i < numOfElements; i += 1) {
143 EXPECT_EQ(val, readVal);
147 TEST_F(InputStreamTest, ReadsInt32) {
149 int32_t val = 0x7fffffff;
150 for (int i = 0; i < numOfElements; i += 1) {
151 dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_INT32, &val);
154 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
155 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
157 EXPECT_EQ(numOfElements*4, scopedMessage.getBodyLength());
158 for (int i = 0; i < numOfElements; i += 1) {
161 EXPECT_EQ(val, readVal);
165 TEST_F(InputStreamTest, ReadsUint64) {
167 uint64_t val = 0xffffffffffffffff;
168 for (int i = 0; i < numOfElements; i += 1) {
169 dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_UINT64, &val);
172 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
173 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
175 EXPECT_EQ(numOfElements*8, scopedMessage.getBodyLength());
176 for (int i = 0; i < numOfElements; i += 1) {
179 EXPECT_EQ(val, readVal);
183 TEST_F(InputStreamTest, ReadsInt64) {
185 int64_t val = 0x7fffffffffffffff;
186 for (int i = 0; i < numOfElements; i += 1) {
187 dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_INT64, &val);
190 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
191 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
193 EXPECT_EQ(numOfElements*8, scopedMessage.getBodyLength());
194 for (int i = 0; i < numOfElements; i += 1) {
197 EXPECT_EQ(val, readVal);
201 TEST_F(InputStreamTest, ReadsDoubles) {
204 for (int i = 0; i < numOfElements; i += 1) {
205 dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_DOUBLE, &val);
208 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
209 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
211 EXPECT_EQ(numOfElements*8, scopedMessage.getBodyLength());
212 for (int i = 0; i < numOfElements; i += 1) {
215 EXPECT_EQ(val, readVal);
219 TEST_F(InputStreamTest, ReadsStrings) {
221 std::string val = "hai";
222 for (int i = 0; i < numOfElements; i += 1) {
223 dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_STRING, &val);
226 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
227 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
229 EXPECT_EQ(numOfElements*4 + numOfElements*4, scopedMessage.getBodyLength());
230 for (int i = 0; i < numOfElements; i += 1) {
233 EXPECT_EQ(val, readVal);
240 struct TestSerializableStruct: CommonAPI::SerializableStruct {
247 virtual void readFromInputStream(CommonAPI::InputStream& inputStream) {
248 inputStream >> a >> b >> c >> d >> e;
251 virtual void writeToOutputStream(CommonAPI::OutputStream& outputStream) const {
252 outputStream << a << b << c << d << e;
259 TEST_F(InputStreamTest, ReadsStructs) {
261 bmw::test::TestSerializableStruct testStruct;
264 testStruct.c = FALSE;
265 testStruct.d = "Hello all";
266 testStruct.e = 3.414;
268 DBusMessageIter subIter;
269 dbus_message_iter_open_container(&libdbusMessageWriteIter, DBUS_TYPE_STRUCT, NULL, &subIter);
270 dbus_message_iter_append_basic(&subIter, DBUS_TYPE_UINT32, &testStruct.a);
271 dbus_message_iter_append_basic(&subIter, DBUS_TYPE_INT16, &testStruct.b);
272 dbus_bool_t dbusBool = static_cast<dbus_bool_t>(testStruct.c);
273 dbus_message_iter_append_basic(&subIter, DBUS_TYPE_BOOLEAN, &dbusBool);
274 dbus_message_iter_append_basic(&subIter, DBUS_TYPE_STRING, &testStruct.d);
275 dbus_message_iter_append_basic(&subIter, DBUS_TYPE_DOUBLE, &testStruct.e);
276 dbus_message_iter_close_container(&libdbusMessageWriteIter, &subIter);
278 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
279 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
281 //40(byte length of struct) = 4(uint32_t) + 2(int16_t) + 2(padding) + 4(bool) + 4(strlength)
282 // + 9(string) + 1(terminating '\0' of string) + 6(padding) + 8 (double)
283 EXPECT_EQ(40, scopedMessage.getBodyLength());
285 bmw::test::TestSerializableStruct verifyStruct;
286 inStream >> verifyStruct;
287 EXPECT_EQ(testStruct.a, verifyStruct.a);
288 EXPECT_EQ(testStruct.b, verifyStruct.b);
289 EXPECT_EQ(testStruct.c, verifyStruct.c);
290 EXPECT_EQ(testStruct.d, verifyStruct.d);
291 EXPECT_EQ(testStruct.e, verifyStruct.e);
294 TEST_F(InputStreamTest, ReadsArrays) {
296 std::vector<int32_t> testVector;
297 int32_t val1 = 0xffffffff;
298 int32_t val2 = 0x7fffffff;
299 for (int i = 0; i < numOfElements; i += 2) {
300 testVector.push_back(val1);
301 testVector.push_back(val2);
304 DBusMessageIter subIter;
305 dbus_message_iter_open_container(&libdbusMessageWriteIter, DBUS_TYPE_ARRAY, "i", &subIter);
306 for (int i = 0; i < numOfElements; i++) {
307 dbus_message_iter_append_basic(&subIter, DBUS_TYPE_INT32, &testVector[i]);
309 dbus_message_iter_close_container(&libdbusMessageWriteIter, &subIter);
311 CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
312 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
314 EXPECT_EQ(scopedMessage.getBodyLength(), numOfElements*4 + 4);
315 std::vector<int32_t> verifyVector;
316 inStream >> verifyVector;
319 for (int i = 0; i < numOfElements; i += 2) {
320 res1 = verifyVector[i];
321 EXPECT_EQ(val1, res1);
322 res2 = verifyVector[i + 1];
323 EXPECT_EQ(val2, res2);
327 TEST_F(InputStreamTest, ReadsArraysInArrays) {
328 size_t numOfElements = 2;
329 DBusMessage* dbusMessage = dbus_message_new_method_call("no.bus.here", "/no/object/here", NULL, "noMethodHere");
330 ASSERT_TRUE(dbusMessage != NULL);
332 DBusMessageIter writeIter;
333 dbus_message_iter_init_append(dbusMessage, &writeIter);
335 std::vector<std::vector<int32_t>> testVector;
336 int32_t val1 = 0xffffffff;
337 int32_t val2 = 0x7fffffff;
338 for (int i = 0; i < numOfElements; i++) {
339 std::vector<int32_t> inner;
340 for (int j = 0; j < numOfElements; j += 2) {
341 inner.push_back(val1);
342 inner.push_back(val2);
344 testVector.push_back(inner);
347 DBusMessageIter subIter;
348 dbus_message_iter_open_container(&writeIter, DBUS_TYPE_ARRAY, "ai", &subIter);
349 for (int i = 0; i < numOfElements; i++) {
350 DBusMessageIter subsubIter;
351 dbus_message_iter_open_container(&subIter, DBUS_TYPE_ARRAY, "i", &subsubIter);
352 for (int j = 0; j < numOfElements; j++) {
353 dbus_message_iter_append_basic(&subsubIter, DBUS_TYPE_INT32, &(testVector[i][j]));
355 dbus_message_iter_close_container(&subIter, &subsubIter);
357 dbus_message_iter_close_container(&writeIter, &subIter);
359 CommonAPI::DBus::DBusMessage scopedMessage(dbusMessage);
360 CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
362 // 5*5*int32_t + 5*lengthField_inner(int32_t) + lengthField_outer(int32_t)
363 EXPECT_EQ(numOfElements*numOfElements*4 + numOfElements*4 + 4, scopedMessage.getBodyLength());
364 std::vector<std::vector<int32_t>> verifyVector;
365 inStream >> verifyVector;
369 for (int i = 0; i < numOfElements; i++) {
370 std::vector<int32_t> innerVerify = verifyVector[i];
371 for (int j = 0; j < numOfElements; j += 2) {
372 res1 = innerVerify[j];
373 EXPECT_EQ(val1, res1);
374 res2 = innerVerify[j + 1];
375 EXPECT_EQ(val2, res2);
380 int main(int argc, char** argv) {
381 ::testing::InitGoogleTest(&argc, argv);
382 return RUN_ALL_TESTS();