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/. */
6 #include <gtest/gtest.h>
8 #include <CommonAPI/DBus/DBusMessage.h>
9 #include <CommonAPI/DBus/DBusOutputStream.h>
10 #include <CommonAPI/DBus/DBusInputStream.h>
11 #include <CommonAPI/SerializableStruct.h>
14 class OutputStreamTest: public ::testing::Test {
17 CommonAPI::DBus::DBusMessage message;
19 const char* objectPath;
20 const char* interfaceName;
21 const char* methodName;
25 busName = "no.bus.here";
26 objectPath = "/no/object/here";
27 interfaceName = "no.interface.here";
28 methodName = "noMethodHere";
35 TEST_F(OutputStreamTest, CanBeConstructed) {
36 CommonAPI::DBus::DBusOutputStream outStream(message);
39 TEST_F(OutputStreamTest, WritesBytes) {
40 const char* signature = "yyyyyyyyyy";
41 message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
42 CommonAPI::DBus::DBusOutputStream outStream(message);
44 outStream.reserveMemory(numOfElements);
47 for (int i = 0; i < numOfElements; i += 2) {
53 EXPECT_EQ(numOfElements, message.getBodyLength());
55 CommonAPI::DBus::DBusInputStream inStream(message);
59 for (int i = 0; i < numOfElements; i += 2) {
60 inStream >> verifyVal1;
61 EXPECT_EQ(val1, verifyVal1);
63 inStream >> verifyVal2;
64 EXPECT_EQ(val2, verifyVal2);
68 TEST_F(OutputStreamTest, WritesBools) {
69 const char* signature = "bbbbbbbbbb";
70 message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
71 CommonAPI::DBus::DBusOutputStream outStream(message);
73 outStream.reserveMemory(numOfElements * 4);
76 for (int i = 0; i < numOfElements; i += 2) {
82 EXPECT_EQ(numOfElements*4, message.getBodyLength());
84 CommonAPI::DBus::DBusInputStream inStream(message);
88 for (int i = 0; i < numOfElements; i += 2) {
89 inStream >> verifyVal1;
90 EXPECT_EQ(val1, verifyVal1);
92 inStream >> verifyVal2;
93 EXPECT_EQ(val2, verifyVal2);
97 TEST_F(OutputStreamTest, WritesUInt16) {
98 const char* signature = "qqqqqqqqqq";
99 message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
100 CommonAPI::DBus::DBusOutputStream outStream(message);
102 outStream.reserveMemory(numOfElements * 2);
103 uint16_t val1 = 0x0000;
104 uint16_t val2 = 0xffff;
105 for (int i = 0; i < numOfElements; i += 2) {
111 EXPECT_EQ(numOfElements*2, message.getBodyLength());
113 CommonAPI::DBus::DBusInputStream inStream(message);
117 for (int i = 0; i < numOfElements; i += 2) {
118 inStream >> verifyVal1;
119 EXPECT_EQ(val1, verifyVal1);
121 inStream >> verifyVal2;
122 EXPECT_EQ(val2, verifyVal2);
126 TEST_F(OutputStreamTest, WritesInt16) {
127 const char* signature = "nnnnnnnnnn";
128 message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
129 CommonAPI::DBus::DBusOutputStream outStream(message);
131 outStream.reserveMemory(numOfElements * 2);
132 int16_t val1 = 0x7fff;
133 int16_t val2 = 0xffff;
134 for (int i = 0; i < numOfElements; i += 2) {
140 EXPECT_EQ(numOfElements*2, message.getBodyLength());
142 CommonAPI::DBus::DBusInputStream inStream(message);
146 for (int i = 0; i < numOfElements; i += 2) {
147 inStream >> verifyVal1;
148 EXPECT_EQ(val1, verifyVal1);
150 inStream >> verifyVal2;
151 EXPECT_EQ(val2, verifyVal2);
155 TEST_F(OutputStreamTest, WritesUInt32) {
156 const char* signature = "uuuuuuuuuu";
157 message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
158 CommonAPI::DBus::DBusOutputStream outStream(message);
160 outStream.reserveMemory(numOfElements * 4);
161 uint32_t val1 = 0x00000000;
162 uint32_t val2 = 0xffffffff;
163 for (int i = 0; i < numOfElements; i += 2) {
169 EXPECT_EQ(numOfElements*4, message.getBodyLength());
171 CommonAPI::DBus::DBusInputStream inStream(message);
175 for (int i = 0; i < numOfElements; i += 2) {
176 inStream >> verifyVal1;
177 EXPECT_EQ(val1, verifyVal1);
179 inStream >> verifyVal2;
180 EXPECT_EQ(val2, verifyVal2);
184 TEST_F(OutputStreamTest, WritesInt32) {
185 const char* signature = "iiiiiiiiii";
186 message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
187 CommonAPI::DBus::DBusOutputStream outStream(message);
189 outStream.reserveMemory(numOfElements * 4);
190 int32_t val1 = 0x7fffffff;
191 int32_t val2 = 0xffffffff;
192 for (int i = 0; i < numOfElements; i += 2) {
198 EXPECT_EQ(numOfElements*4, message.getBodyLength());
200 CommonAPI::DBus::DBusInputStream inStream(message);
204 for (int i = 0; i < numOfElements; i += 2) {
205 inStream >> verifyVal1;
206 EXPECT_EQ(val1, verifyVal1);
208 inStream >> verifyVal2;
209 EXPECT_EQ(val2, verifyVal2);
213 TEST_F(OutputStreamTest, WritesUInt64) {
214 const char* signature = "tttttttttt";
215 message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
216 CommonAPI::DBus::DBusOutputStream outStream(message);
218 outStream.reserveMemory(numOfElements * 8);
219 uint64_t val1 = 0x0000000000000000;
220 uint64_t val2 = 0xffffffffffffffff;
221 for (int i = 0; i < numOfElements; i += 2) {
227 EXPECT_EQ(numOfElements*8, message.getBodyLength());
229 CommonAPI::DBus::DBusInputStream inStream(message);
233 for (int i = 0; i < numOfElements; i += 2) {
234 inStream >> verifyVal1;
235 EXPECT_EQ(val1, verifyVal1);
237 inStream >> verifyVal2;
238 EXPECT_EQ(val2, verifyVal2);
242 TEST_F(OutputStreamTest, WritesInt64) {
243 const char* signature = "xxxxxxxxxx";
244 message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
245 CommonAPI::DBus::DBusOutputStream outStream(message);
247 outStream.reserveMemory(numOfElements * 8);
248 int64_t val1 = 0x7fffffffffffffff;
249 int64_t val2 = 0xffffffffffffffff;
250 for (int i = 0; i < numOfElements; i += 2) {
256 EXPECT_EQ(numOfElements*8, message.getBodyLength());
258 CommonAPI::DBus::DBusInputStream inStream(message);
262 for (int i = 0; i < numOfElements; i += 2) {
263 inStream >> verifyVal1;
264 EXPECT_EQ(val1, verifyVal1);
266 inStream >> verifyVal2;
267 EXPECT_EQ(val2, verifyVal2);
271 TEST_F(OutputStreamTest, WritesDouble) {
272 const char* signature = "dddddddddd";
273 message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
274 CommonAPI::DBus::DBusOutputStream outStream(message);
276 outStream.reserveMemory(numOfElements * 8);
279 for (int i = 0; i < numOfElements; i += 2) {
285 EXPECT_EQ(numOfElements*8, message.getBodyLength());
287 CommonAPI::DBus::DBusInputStream inStream(message);
291 std::string verifySignature;
292 for (int i = 0; i < numOfElements; i += 2) {
293 inStream >> verifyVal1;
294 EXPECT_EQ(val1, verifyVal1);
296 inStream >> verifyVal2;
297 EXPECT_EQ(val2, verifyVal2);
301 TEST_F(OutputStreamTest, WritesStrings) {
302 const char* signature = "sss";
303 message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
304 CommonAPI::DBus::DBusOutputStream outStream(message);
306 std::string val1 = "hai";
307 std::string val2 = "ciao";
308 std::string val3 = "salut";
310 //sizes of the strings + terminating null-bytes (each 1 byte) + length-fields (each 4 bytes)
311 outStream.reserveMemory(val1.size() + val2.size() + val3.size() + 3 + 3 * 4);
312 outStream << val1 << val2 << val3;
315 //Length fields + actual strings + terminating '\0's + 3(padding)
316 EXPECT_EQ(3*4 + 3 + 4 + 5 + 3 + 3, message.getBodyLength());
318 CommonAPI::DBus::DBusInputStream inStream(message);
320 std::string verifyVal1;
321 std::string verifyVal2;
322 std::string verifyVal3;
323 std::string verifySignature;
325 inStream >> verifyVal1;
326 inStream >> verifyVal2;
327 inStream >> verifyVal3;
329 EXPECT_EQ(val1, verifyVal1);
330 EXPECT_EQ(val2, verifyVal2);
331 EXPECT_EQ(val3, verifyVal3);
337 struct myStruct: CommonAPI::SerializableStruct {
346 virtual void readFromInputStream(CommonAPI::InputStream& inputMessageStream);
347 virtual void writeToOutputStream(CommonAPI::OutputStream& outputMessageStream) const;
350 myStruct::~myStruct() {
353 void myStruct::readFromInputStream(CommonAPI::InputStream& inputMessageStream) {
354 inputMessageStream >> a >> b >> c >> d >> e;
357 void myStruct::writeToOutputStream(CommonAPI::OutputStream& outputMessageStream) const {
358 outputMessageStream << a << b << c << d << e;
364 TEST_F(OutputStreamTest, WritesStructs) {
365 const char* signature = "(unbsd)";
366 message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
367 CommonAPI::DBus::DBusOutputStream outStream(message);
369 bmw::test::myStruct testStruct;
372 testStruct.c = FALSE;
373 testStruct.d = "Hello all";
374 testStruct.e = 3.414;
376 // 40(byte length of struct) = 4(uint32_t) + 2(int16_t) + 2(padding) + 4(bool) + 4(strlength)
377 // + 9(string) + 1(terminating '\0' of string) + 6(padding) + 8 (double)
378 outStream.reserveMemory(40);
379 outStream << testStruct;
382 EXPECT_EQ(40, message.getBodyLength());
384 CommonAPI::DBus::DBusInputStream inStream(message);
385 bmw::test::myStruct verifyStruct;
386 inStream >> verifyStruct;
388 EXPECT_EQ(testStruct.a, verifyStruct.a);
389 EXPECT_EQ(testStruct.b, verifyStruct.b);
390 EXPECT_EQ(testStruct.c, verifyStruct.c);
391 EXPECT_EQ(testStruct.d, verifyStruct.d);
392 EXPECT_EQ(testStruct.e, verifyStruct.e);
395 TEST_F(OutputStreamTest, WritesArrays) {
396 const char* signature = "ai";
397 message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
398 CommonAPI::DBus::DBusOutputStream outStream(message);
400 std::vector<int32_t> testVector;
401 int32_t val1 = 0xffffffff;
402 int32_t val2 = 0x7fffffff;
403 for (int i = 0; i < numOfElements; i += 2) {
404 testVector.push_back(val1);
405 testVector.push_back(val2);
408 outStream.reserveMemory(numOfElements * 4 + 4);
409 outStream << testVector;
412 EXPECT_EQ(numOfElements*4 + 4, message.getBodyLength());
414 CommonAPI::DBus::DBusInputStream inStream(message);
415 std::vector<int32_t> verifyVector;
416 inStream >> verifyVector;
420 for (int i = 0; i < numOfElements; i += 2) {
421 res1 = verifyVector[i];
422 EXPECT_EQ(val1, res1);
423 res2 = verifyVector[i + 1];
424 EXPECT_EQ(val2, res2);
428 TEST_F(OutputStreamTest, WritesArraysOfStrings) {
429 const char* signature = "as";
430 message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
431 CommonAPI::DBus::DBusOutputStream outStream(message);
433 std::vector<std::string> testVector;
434 std::string val1 = "Hai";
435 std::string val2 = "Ciao";
436 for (int i = 0; i < numOfElements; i += 2) {
437 testVector.push_back(val1);
438 testVector.push_back(val2);
441 // 101 = 4(lengthFieldOfArray) +
442 // 4*(4(lengthField1) + 4(string1 mit \0-byte) + 4(lengthField2) + 5(string2 mit \0-byte) + 3(paddingTo4)) +
443 // (4(lengthField1) + 4(string1 mit \0-byte) + 4(lengthField2) + 5(string2 mit \0-byte))
444 size_t vectorLength = 101;
445 outStream.reserveMemory(vectorLength);
446 outStream << testVector;
449 EXPECT_EQ(vectorLength, message.getBodyLength());
451 CommonAPI::DBus::DBusInputStream inStream(message);
452 std::vector<std::string> verifyVector;
453 inStream >> verifyVector;
457 for (int i = 0; i < numOfElements; i += 2) {
458 res1 = verifyVector[i];
459 EXPECT_EQ(val1, res1);
460 res2 = verifyVector[i + 1];
461 EXPECT_EQ(val2, res2);
465 TEST_F(OutputStreamTest, WritesArraysInArrays) {
466 const char* signature = "aai";
467 message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
468 CommonAPI::DBus::DBusOutputStream outStream(message);
470 std::vector<std::vector<int32_t>> testVector;
471 int32_t val1 = 0xffffffff;
472 int32_t val2 = 0x7fffffff;
473 for (int i = 0; i < numOfElements; i++) {
474 std::vector<int32_t> inner;
475 for (int j = 0; j < numOfElements; j += 2) {
476 inner.push_back(val1);
477 inner.push_back(val2);
479 testVector.push_back(inner);
482 outStream.reserveMemory(numOfElements * numOfElements * 4 + numOfElements * 4 + 4);
483 outStream << testVector;
486 EXPECT_EQ(numOfElements*numOfElements*4 + numOfElements*4 + 4, message.getBodyLength());
488 CommonAPI::DBus::DBusInputStream inStream(message);
489 std::vector<std::vector<int32_t>> verifyVector;
490 inStream >> verifyVector;
494 for (int i = 0; i < numOfElements; i++) {
495 std::vector<int32_t> innerVerify = verifyVector[i];
496 for (int j = 0; j < numOfElements; j += 2) {
497 res1 = innerVerify[j];
498 EXPECT_EQ(val1, res1);
499 res2 = innerVerify[j + 1];
500 EXPECT_EQ(val2, res2);
509 struct TestStruct: CommonAPI::SerializableStruct {
511 TestStruct(int32_t v1, double v2, double v3, std::string v4);
519 virtual void readFromInputStream(CommonAPI::InputStream& inputMessageStream);
520 virtual void writeToOutputStream(CommonAPI::OutputStream& outputMessageStream) const;
523 typedef std::vector<TestStruct> TestStructList;
525 TestStruct::TestStruct() :
526 val1(0), val2(0), val3(0), val4("") {
529 TestStruct::TestStruct(int32_t v1, double v2, double v3, std::string v4) :
530 val1(v1), val2(v2), val3(v3), val4(v4) {
533 TestStruct::~TestStruct() {
536 void TestStruct::readFromInputStream(CommonAPI::InputStream& inputMessageStream) {
537 inputMessageStream >> val1 >> val2 >> val3 >> val4;
540 void TestStruct::writeToOutputStream(CommonAPI::OutputStream& outputMessageStream) const {
541 outputMessageStream << val1 << val2 << val3 << val4;
549 TEST_F(OutputStreamTest, WritesTestStructs) {
550 const char* signature = "(idds)";
551 message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
552 CommonAPI::DBus::DBusOutputStream outStream(message);
554 com::bmw::test::TestStruct testStruct(1, 12.6, 1e40, "XXXXXXXXXXXXXXXXXXXX");
556 //4(int32_t) + 4(padding) + 8(double) + 8(double) + 4(str_length) + 20(string) + 1(null-termination)
557 uint32_t expectedSize = 49;
558 outStream.reserveMemory(expectedSize);
559 outStream << testStruct;
562 EXPECT_EQ(expectedSize, message.getBodyLength());
564 CommonAPI::DBus::DBusInputStream inStream(message);
565 com::bmw::test::TestStruct verifyStruct;
566 inStream >> verifyStruct;
568 EXPECT_EQ(testStruct.val1, verifyStruct.val1);
569 EXPECT_EQ(testStruct.val2, verifyStruct.val2);
570 EXPECT_EQ(testStruct.val3, verifyStruct.val3);
571 EXPECT_EQ(testStruct.val4, verifyStruct.val4);
574 TEST_F(OutputStreamTest, WritesTestStructLists) {
575 const char* signature = "a(idds)";
576 message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
577 CommonAPI::DBus::DBusOutputStream outStream(message);
579 com::bmw::test::TestStructList testList;
580 for (int i = 0; i < numOfElements; i++) {
581 testList.emplace_back(1, 12.6, 1e40, "XXXXXXXXXXXXXXXXXXXX");
584 //struct size: 49 = 4(int32_t) + 4(padding) + 8(double) + 8(double) + 4(str_length) + 20(string) + 1(null-termination)
585 //array size: 4(array_length) + 4(struct_padding) + (numElements-1)*(49(struct) + 7(struct_padding)) + 49(struct)
586 uint32_t expectedSize = 8 + (numOfElements - 1) * (49 + 7) + 49;
587 outStream.reserveMemory(expectedSize);
588 outStream << testList;
591 EXPECT_EQ(expectedSize, message.getBodyLength());
593 CommonAPI::DBus::DBusInputStream inStream(message);
594 com::bmw::test::TestStructList verifyList;
595 inStream >> verifyList;
597 EXPECT_EQ(numOfElements, verifyList.size());
606 struct ArrayStruct: CommonAPI::SerializableStruct {
608 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);
611 std::vector<int64_t> val1;
612 std::vector<std::string> val2;
613 std::vector<double> val3;
614 std::vector<std::string> val4;
615 std::vector<uint16_t> val5;
617 virtual void readFromInputStream(CommonAPI::InputStream& inputMessageStream);
618 virtual void writeToOutputStream(CommonAPI::OutputStream& outputMessageStream) const;
621 typedef std::vector<TestStruct> TestStructList;
623 ArrayStruct::ArrayStruct() {
626 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) :
627 val1(v1), val2(v2), val3(v3), val4(v4), val5(v5) {
630 ArrayStruct::~ArrayStruct() {
633 void ArrayStruct::readFromInputStream(CommonAPI::InputStream& inputMessageStream) {
634 inputMessageStream >> val1 >> val2 >> val3 >> val4 >> val5;
637 void ArrayStruct::writeToOutputStream(CommonAPI::OutputStream& outputMessageStream) const {
638 outputMessageStream << val1 << val2 << val3 << val4 << val5;
646 TEST_F(OutputStreamTest, WritesStructsOfArraysWithSthBefore) {
647 const char* signature = "(axasadasaq)";
648 message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
649 CommonAPI::DBus::DBusOutputStream outStream(message);
651 com::bmw::test::ArrayStruct arrayStruct;
652 for (int i = 0; i < numOfElements; i++) {
653 arrayStruct.val1.push_back(i*50);
654 arrayStruct.val2.push_back("Hai");
655 arrayStruct.val3.push_back(3.414);
656 arrayStruct.val4.push_back("Ciao");
657 arrayStruct.val5.push_back(i*5);
659 uint16_t frontValue = 0;
661 // 2(uint16) + 6(padding) --> 8
662 // 4(LengthField) + 4(padding) + 10 * 8(int64) --> 88 --> 96
663 // 4(LengthField) + 10 * (4(LengthField) + 4("Hai\0")) --> 84 --> 180
664 // 4(LengthField) + 10 * 8(double) --> 84 --> 264
665 // 4(LengthField) + 10 * (4(LengthField) + 5("Ciao\0") + 3(padding)) --> 124 --> 388
666 // 4(LengthField) + 10 * 2(uint16) --> 24 --> 412
667 size_t structLength = 412;
668 outStream.reserveMemory(structLength);
669 outStream << frontValue << arrayStruct;
672 EXPECT_EQ(structLength, message.getBodyLength());
674 CommonAPI::DBus::DBusInputStream inStream(message);
675 com::bmw::test::ArrayStruct verifyStruct;
677 uint16_t frontVerification;
678 inStream >> frontVerification >> verifyStruct;
680 EXPECT_EQ(frontValue, frontVerification);
688 for (int i = 0; i < numOfElements; i++) {
689 res1 = verifyStruct.val1[i];
690 res2 = verifyStruct.val2[i];
691 res3 = verifyStruct.val3[i];
692 res4 = verifyStruct.val4[i];
693 res5 = verifyStruct.val5[i];
695 EXPECT_EQ(i*50, res1);
696 EXPECT_EQ(std::string("Hai"), res2);
697 EXPECT_EQ(3.414, res3);
698 EXPECT_EQ(std::string("Ciao"), res4);
699 EXPECT_EQ(i*5, res5);
703 int main(int argc, char** argv) {
704 ::testing::InitGoogleTest(&argc, argv);
705 return RUN_ALL_TESTS();