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/. */
8 #include <gtest/gtest.h>
10 #include <CommonAPI/DBus/DBusMessage.h>
11 #include <CommonAPI/DBus/DBusOutputStream.h>
12 #include <CommonAPI/DBus/DBusInputStream.h>
13 #include <CommonAPI/SerializableStruct.h>
16 class OutputStreamTest: public ::testing::Test {
19 CommonAPI::DBus::DBusMessage message;
21 const char* objectPath;
22 const char* interfaceName;
23 const char* methodName;
27 busName = "no.bus.here";
28 objectPath = "/no/object/here";
29 interfaceName = "no.interface.here";
30 methodName = "noMethodHere";
37 TEST_F(OutputStreamTest, CanBeConstructed) {
38 CommonAPI::DBus::DBusOutputStream outStream(message);
41 TEST_F(OutputStreamTest, WritesBytes) {
42 const char* signature = "yyyyyyyyyy";
43 message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
44 CommonAPI::DBus::DBusOutputStream outStream(message);
46 outStream.reserveMemory(numOfElements);
49 for (int i = 0; i < numOfElements; i += 2) {
55 EXPECT_EQ(numOfElements, message.getBodyLength());
57 CommonAPI::DBus::DBusInputStream inStream(message);
61 for (int i = 0; i < numOfElements; i += 2) {
62 inStream >> verifyVal1;
63 EXPECT_EQ(val1, verifyVal1);
65 inStream >> verifyVal2;
66 EXPECT_EQ(val2, verifyVal2);
70 TEST_F(OutputStreamTest, WritesBools) {
71 const char* signature = "bbbbbbbbbb";
72 message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
73 CommonAPI::DBus::DBusOutputStream outStream(message);
75 outStream.reserveMemory(numOfElements * 4);
78 for (int i = 0; i < numOfElements; i += 2) {
84 EXPECT_EQ(numOfElements*4, message.getBodyLength());
86 CommonAPI::DBus::DBusInputStream inStream(message);
90 for (int i = 0; i < numOfElements; i += 2) {
91 inStream >> verifyVal1;
92 EXPECT_EQ(val1, verifyVal1);
94 inStream >> verifyVal2;
95 EXPECT_EQ(val2, verifyVal2);
99 TEST_F(OutputStreamTest, WritesUInt16) {
100 const char* signature = "qqqqqqqqqq";
101 message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
102 CommonAPI::DBus::DBusOutputStream outStream(message);
104 outStream.reserveMemory(numOfElements * 2);
105 uint16_t val1 = 0x0000;
106 uint16_t val2 = 0xffff;
107 for (int i = 0; i < numOfElements; i += 2) {
113 EXPECT_EQ(numOfElements*2, message.getBodyLength());
115 CommonAPI::DBus::DBusInputStream inStream(message);
119 for (int i = 0; i < numOfElements; i += 2) {
120 inStream >> verifyVal1;
121 EXPECT_EQ(val1, verifyVal1);
123 inStream >> verifyVal2;
124 EXPECT_EQ(val2, verifyVal2);
128 TEST_F(OutputStreamTest, WritesInt16) {
129 const char* signature = "nnnnnnnnnn";
130 message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
131 CommonAPI::DBus::DBusOutputStream outStream(message);
133 outStream.reserveMemory(numOfElements * 2);
134 int16_t val1 = 0x7fff;
135 int16_t val2 = 0xffff;
136 for (int i = 0; i < numOfElements; i += 2) {
142 EXPECT_EQ(numOfElements*2, message.getBodyLength());
144 CommonAPI::DBus::DBusInputStream inStream(message);
148 for (int i = 0; i < numOfElements; i += 2) {
149 inStream >> verifyVal1;
150 EXPECT_EQ(val1, verifyVal1);
152 inStream >> verifyVal2;
153 EXPECT_EQ(val2, verifyVal2);
157 TEST_F(OutputStreamTest, WritesUInt32) {
158 const char* signature = "uuuuuuuuuu";
159 message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
160 CommonAPI::DBus::DBusOutputStream outStream(message);
162 outStream.reserveMemory(numOfElements * 4);
163 uint32_t val1 = 0x00000000;
164 uint32_t val2 = 0xffffffff;
165 for (int i = 0; i < numOfElements; i += 2) {
171 EXPECT_EQ(numOfElements*4, message.getBodyLength());
173 CommonAPI::DBus::DBusInputStream inStream(message);
177 for (int i = 0; i < numOfElements; i += 2) {
178 inStream >> verifyVal1;
179 EXPECT_EQ(val1, verifyVal1);
181 inStream >> verifyVal2;
182 EXPECT_EQ(val2, verifyVal2);
186 TEST_F(OutputStreamTest, WritesInt32) {
187 const char* signature = "iiiiiiiiii";
188 message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
189 CommonAPI::DBus::DBusOutputStream outStream(message);
191 outStream.reserveMemory(numOfElements * 4);
192 int32_t val1 = 0x7fffffff;
193 int32_t val2 = 0xffffffff;
194 for (int i = 0; i < numOfElements; i += 2) {
200 EXPECT_EQ(numOfElements*4, message.getBodyLength());
202 CommonAPI::DBus::DBusInputStream inStream(message);
206 for (int i = 0; i < numOfElements; i += 2) {
207 inStream >> verifyVal1;
208 EXPECT_EQ(val1, verifyVal1);
210 inStream >> verifyVal2;
211 EXPECT_EQ(val2, verifyVal2);
215 TEST_F(OutputStreamTest, WritesUInt64) {
216 const char* signature = "tttttttttt";
217 message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
218 CommonAPI::DBus::DBusOutputStream outStream(message);
220 outStream.reserveMemory(numOfElements * 8);
221 uint64_t val1 = 0x0000000000000000;
222 uint64_t val2 = 0xffffffffffffffff;
223 for (int i = 0; i < numOfElements; i += 2) {
229 EXPECT_EQ(numOfElements*8, message.getBodyLength());
231 CommonAPI::DBus::DBusInputStream inStream(message);
235 for (int i = 0; i < numOfElements; i += 2) {
236 inStream >> verifyVal1;
237 EXPECT_EQ(val1, verifyVal1);
239 inStream >> verifyVal2;
240 EXPECT_EQ(val2, verifyVal2);
244 TEST_F(OutputStreamTest, WritesInt64) {
245 const char* signature = "xxxxxxxxxx";
246 message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
247 CommonAPI::DBus::DBusOutputStream outStream(message);
249 outStream.reserveMemory(numOfElements * 8);
250 int64_t val1 = 0x7fffffffffffffff;
251 int64_t val2 = 0xffffffffffffffff;
252 for (int i = 0; i < numOfElements; i += 2) {
258 EXPECT_EQ(numOfElements*8, message.getBodyLength());
260 CommonAPI::DBus::DBusInputStream inStream(message);
264 for (int i = 0; i < numOfElements; i += 2) {
265 inStream >> verifyVal1;
266 EXPECT_EQ(val1, verifyVal1);
268 inStream >> verifyVal2;
269 EXPECT_EQ(val2, verifyVal2);
273 TEST_F(OutputStreamTest, WritesDouble) {
274 const char* signature = "dddddddddd";
275 message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
276 CommonAPI::DBus::DBusOutputStream outStream(message);
278 outStream.reserveMemory(numOfElements * 8);
281 for (int i = 0; i < numOfElements; i += 2) {
287 EXPECT_EQ(numOfElements*8, message.getBodyLength());
289 CommonAPI::DBus::DBusInputStream inStream(message);
293 std::string verifySignature;
294 for (int i = 0; i < numOfElements; i += 2) {
295 inStream >> verifyVal1;
296 EXPECT_EQ(val1, verifyVal1);
298 inStream >> verifyVal2;
299 EXPECT_EQ(val2, verifyVal2);
303 TEST_F(OutputStreamTest, WritesStrings) {
304 const char* signature = "sss";
305 message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
306 CommonAPI::DBus::DBusOutputStream outStream(message);
308 std::string val1 = "hai";
309 std::string val2 = "ciao";
310 std::string val3 = "salut";
312 //sizes of the strings + terminating null-bytes (each 1 byte) + length-fields (each 4 bytes)
313 outStream.reserveMemory(val1.size() + val2.size() + val3.size() + 3 + 3 * 4);
314 outStream << val1 << val2 << val3;
317 //Length fields + actual strings + terminating '\0's + 3(padding)
318 EXPECT_EQ(3*4 + 3 + 4 + 5 + 3 + 3, message.getBodyLength());
320 CommonAPI::DBus::DBusInputStream inStream(message);
322 std::string verifyVal1;
323 std::string verifyVal2;
324 std::string verifyVal3;
325 std::string verifySignature;
327 inStream >> verifyVal1;
328 inStream >> verifyVal2;
329 inStream >> verifyVal3;
331 EXPECT_EQ(val1, verifyVal1);
332 EXPECT_EQ(val2, verifyVal2);
333 EXPECT_EQ(val3, verifyVal3);
339 struct myStruct: CommonAPI::SerializableStruct {
348 virtual void readFromInputStream(CommonAPI::InputStream& inputMessageStream);
349 virtual void writeToOutputStream(CommonAPI::OutputStream& outputMessageStream) const;
352 myStruct::~myStruct() {
355 void myStruct::readFromInputStream(CommonAPI::InputStream& inputMessageStream) {
356 inputMessageStream >> a >> b >> c >> d >> e;
359 void myStruct::writeToOutputStream(CommonAPI::OutputStream& outputMessageStream) const {
360 outputMessageStream << a << b << c << d << e;
366 TEST_F(OutputStreamTest, WritesStructs) {
367 const char* signature = "(unbsd)";
368 message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
369 CommonAPI::DBus::DBusOutputStream outStream(message);
371 bmw::test::myStruct testStruct;
374 testStruct.c = FALSE;
375 testStruct.d = "Hello all";
376 testStruct.e = 3.414;
378 // 40(byte length of struct) = 4(uint32_t) + 2(int16_t) + 2(padding) + 4(bool) + 4(strlength)
379 // + 9(string) + 1(terminating '\0' of string) + 6(padding) + 8 (double)
380 outStream.reserveMemory(40);
381 outStream << testStruct;
384 EXPECT_EQ(40, message.getBodyLength());
386 CommonAPI::DBus::DBusInputStream inStream(message);
387 bmw::test::myStruct verifyStruct;
388 inStream >> verifyStruct;
390 EXPECT_EQ(testStruct.a, verifyStruct.a);
391 EXPECT_EQ(testStruct.b, verifyStruct.b);
392 EXPECT_EQ(testStruct.c, verifyStruct.c);
393 EXPECT_EQ(testStruct.d, verifyStruct.d);
394 EXPECT_EQ(testStruct.e, verifyStruct.e);
397 TEST_F(OutputStreamTest, WritesArrays) {
398 const char* signature = "ai";
399 message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
400 CommonAPI::DBus::DBusOutputStream outStream(message);
402 std::vector<int32_t> testVector;
403 int32_t val1 = 0xffffffff;
404 int32_t val2 = 0x7fffffff;
405 for (int i = 0; i < numOfElements; i += 2) {
406 testVector.push_back(val1);
407 testVector.push_back(val2);
410 outStream.reserveMemory(numOfElements * 4 + 4);
411 outStream << testVector;
414 EXPECT_EQ(numOfElements*4 + 4, message.getBodyLength());
416 CommonAPI::DBus::DBusInputStream inStream(message);
417 std::vector<int32_t> verifyVector;
418 inStream >> verifyVector;
422 for (int i = 0; i < numOfElements; i += 2) {
423 res1 = verifyVector[i];
424 EXPECT_EQ(val1, res1);
425 res2 = verifyVector[i + 1];
426 EXPECT_EQ(val2, res2);
430 TEST_F(OutputStreamTest, WritesArraysOfStrings) {
431 const char* signature = "as";
432 message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
433 CommonAPI::DBus::DBusOutputStream outStream(message);
435 std::vector<std::string> testVector;
436 std::string val1 = "Hai";
437 std::string val2 = "Ciao";
438 for (int i = 0; i < numOfElements; i += 2) {
439 testVector.push_back(val1);
440 testVector.push_back(val2);
443 // 101 = 4(lengthFieldOfArray) +
444 // 4*(4(lengthField1) + 4(string1 mit \0-byte) + 4(lengthField2) + 5(string2 mit \0-byte) + 3(paddingTo4)) +
445 // (4(lengthField1) + 4(string1 mit \0-byte) + 4(lengthField2) + 5(string2 mit \0-byte))
446 size_t vectorLength = 101;
447 outStream.reserveMemory(vectorLength);
448 outStream << testVector;
451 EXPECT_EQ(vectorLength, message.getBodyLength());
453 CommonAPI::DBus::DBusInputStream inStream(message);
454 std::vector<std::string> verifyVector;
455 inStream >> verifyVector;
459 for (int i = 0; i < numOfElements; i += 2) {
460 res1 = verifyVector[i];
461 EXPECT_EQ(val1, res1);
462 res2 = verifyVector[i + 1];
463 EXPECT_EQ(val2, res2);
467 TEST_F(OutputStreamTest, WritesArraysInArrays) {
468 const char* signature = "aai";
469 message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
470 CommonAPI::DBus::DBusOutputStream outStream(message);
472 std::vector<std::vector<int32_t>> testVector;
473 int32_t val1 = 0xffffffff;
474 int32_t val2 = 0x7fffffff;
475 for (int i = 0; i < numOfElements; i++) {
476 std::vector<int32_t> inner;
477 for (int j = 0; j < numOfElements; j += 2) {
478 inner.push_back(val1);
479 inner.push_back(val2);
481 testVector.push_back(inner);
484 outStream.reserveMemory(numOfElements * numOfElements * 4 + numOfElements * 4 + 4);
485 outStream << testVector;
488 EXPECT_EQ(numOfElements*numOfElements*4 + numOfElements*4 + 4, message.getBodyLength());
490 CommonAPI::DBus::DBusInputStream inStream(message);
491 std::vector<std::vector<int32_t>> verifyVector;
492 inStream >> verifyVector;
496 for (int i = 0; i < numOfElements; i++) {
497 std::vector<int32_t> innerVerify = verifyVector[i];
498 for (int j = 0; j < numOfElements; j += 2) {
499 res1 = innerVerify[j];
500 EXPECT_EQ(val1, res1);
501 res2 = innerVerify[j + 1];
502 EXPECT_EQ(val2, res2);
511 struct TestStruct: CommonAPI::SerializableStruct {
513 TestStruct(int32_t v1, double v2, double v3, std::string v4);
521 virtual void readFromInputStream(CommonAPI::InputStream& inputMessageStream);
522 virtual void writeToOutputStream(CommonAPI::OutputStream& outputMessageStream) const;
525 typedef std::vector<TestStruct> TestStructList;
527 TestStruct::TestStruct() :
528 val1(0), val2(0), val3(0), val4("") {
531 TestStruct::TestStruct(int32_t v1, double v2, double v3, std::string v4) :
532 val1(v1), val2(v2), val3(v3), val4(v4) {
535 TestStruct::~TestStruct() {
538 void TestStruct::readFromInputStream(CommonAPI::InputStream& inputMessageStream) {
539 inputMessageStream >> val1 >> val2 >> val3 >> val4;
542 void TestStruct::writeToOutputStream(CommonAPI::OutputStream& outputMessageStream) const {
543 outputMessageStream << val1 << val2 << val3 << val4;
551 TEST_F(OutputStreamTest, WritesTestStructs) {
552 const char* signature = "(idds)";
553 message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
554 CommonAPI::DBus::DBusOutputStream outStream(message);
556 com::bmw::test::TestStruct testStruct(1, 12.6, 1e40, "XXXXXXXXXXXXXXXXXXXX");
558 //4(int32_t) + 4(padding) + 8(double) + 8(double) + 4(str_length) + 20(string) + 1(null-termination)
559 uint32_t expectedSize = 49;
560 outStream.reserveMemory(expectedSize);
561 outStream << testStruct;
564 EXPECT_EQ(expectedSize, message.getBodyLength());
566 CommonAPI::DBus::DBusInputStream inStream(message);
567 com::bmw::test::TestStruct verifyStruct;
568 inStream >> verifyStruct;
570 EXPECT_EQ(testStruct.val1, verifyStruct.val1);
571 EXPECT_EQ(testStruct.val2, verifyStruct.val2);
572 EXPECT_EQ(testStruct.val3, verifyStruct.val3);
573 EXPECT_EQ(testStruct.val4, verifyStruct.val4);
576 TEST_F(OutputStreamTest, WritesTestStructLists) {
577 const char* signature = "a(idds)";
578 message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
579 CommonAPI::DBus::DBusOutputStream outStream(message);
581 com::bmw::test::TestStructList testList;
582 for (int i = 0; i < numOfElements; i++) {
583 testList.emplace_back(1, 12.6, 1e40, "XXXXXXXXXXXXXXXXXXXX");
586 //struct size: 49 = 4(int32_t) + 4(padding) + 8(double) + 8(double) + 4(str_length) + 20(string) + 1(null-termination)
587 //array size: 4(array_length) + 4(struct_padding) + (numElements-1)*(49(struct) + 7(struct_padding)) + 49(struct)
588 uint32_t expectedSize = 8 + (numOfElements - 1) * (49 + 7) + 49;
589 outStream.reserveMemory(expectedSize);
590 outStream << testList;
593 EXPECT_EQ(expectedSize, message.getBodyLength());
595 CommonAPI::DBus::DBusInputStream inStream(message);
596 com::bmw::test::TestStructList verifyList;
597 inStream >> verifyList;
599 EXPECT_EQ(numOfElements, verifyList.size());
608 struct ArrayStruct: CommonAPI::SerializableStruct {
610 ArrayStruct(std::vector<int64_t> v1, std::vector<std::string> v2, std::vector<double> v3, std::vector<std::string> v4, std::vector<uint16_t> v5);
613 std::vector<int64_t> val1;
614 std::vector<std::string> val2;
615 std::vector<double> val3;
616 std::vector<std::string> val4;
617 std::vector<uint16_t> val5;
619 virtual void readFromInputStream(CommonAPI::InputStream& inputMessageStream);
620 virtual void writeToOutputStream(CommonAPI::OutputStream& outputMessageStream) const;
623 typedef std::vector<TestStruct> TestStructList;
625 ArrayStruct::ArrayStruct() {
628 ArrayStruct::ArrayStruct(std::vector<int64_t> v1, std::vector<std::string> v2, std::vector<double> v3, std::vector<std::string> v4, std::vector<uint16_t> v5) :
629 val1(v1), val2(v2), val3(v3), val4(v4), val5(v5) {
632 ArrayStruct::~ArrayStruct() {
635 void ArrayStruct::readFromInputStream(CommonAPI::InputStream& inputMessageStream) {
636 inputMessageStream >> val1 >> val2 >> val3 >> val4 >> val5;
639 void ArrayStruct::writeToOutputStream(CommonAPI::OutputStream& outputMessageStream) const {
640 outputMessageStream << val1 << val2 << val3 << val4 << val5;
648 TEST_F(OutputStreamTest, WritesStructsOfArraysWithSthBefore) {
649 const char* signature = "(axasadasaq)";
650 message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
651 CommonAPI::DBus::DBusOutputStream outStream(message);
653 com::bmw::test::ArrayStruct arrayStruct;
654 for (int i = 0; i < numOfElements; i++) {
655 arrayStruct.val1.push_back(i*50);
656 arrayStruct.val2.push_back("Hai");
657 arrayStruct.val3.push_back(3.414);
658 arrayStruct.val4.push_back("Ciao");
659 arrayStruct.val5.push_back(i*5);
661 uint16_t frontValue = 0;
663 // 2(uint16) + 6(padding) --> 8
664 // 4(LengthField) + 4(padding) + 10 * 8(int64) --> 88 --> 96
665 // 4(LengthField) + 10 * (4(LengthField) + 4("Hai\0")) --> 84 --> 180
666 // 4(LengthField) + 10 * 8(double) --> 84 --> 264
667 // 4(LengthField) + 10 * (4(LengthField) + 5("Ciao\0") + 3(padding)) --> 124 --> 388
668 // 4(LengthField) + 10 * 2(uint16) --> 24 --> 412
669 size_t structLength = 412;
670 outStream.reserveMemory(structLength);
671 outStream << frontValue << arrayStruct;
674 EXPECT_EQ(structLength, message.getBodyLength());
676 CommonAPI::DBus::DBusInputStream inStream(message);
677 com::bmw::test::ArrayStruct verifyStruct;
679 uint16_t frontVerification;
680 inStream >> frontVerification >> verifyStruct;
682 EXPECT_EQ(frontValue, frontVerification);
690 for (int i = 0; i < numOfElements; i++) {
691 res1 = verifyStruct.val1[i];
692 res2 = verifyStruct.val2[i];
693 res3 = verifyStruct.val3[i];
694 res4 = verifyStruct.val4[i];
695 res5 = verifyStruct.val5[i];
697 EXPECT_EQ(i*50, res1);
698 EXPECT_EQ(std::string("Hai"), res2);
699 EXPECT_EQ(3.414, res3);
700 EXPECT_EQ(std::string("Ciao"), res4);
701 EXPECT_EQ(i*5, res5);
705 int main(int argc, char** argv) {
706 ::testing::InitGoogleTest(&argc, argv);
707 return RUN_ALL_TESTS();