tests: fix blocking semantic in DBusProxyTest
[profile/ivi/common-api-dbus-runtime.git] / src / test / DBusOutputStreamTest.cpp
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 <dbus/dbus.h>
8 #include <gtest/gtest.h>
9
10 #include <CommonAPI/DBus/DBusMessage.h>
11 #include <CommonAPI/DBus/DBusOutputStream.h>
12 #include <CommonAPI/DBus/DBusInputStream.h>
13 #include <CommonAPI/SerializableStruct.h>
14 #include <CommonAPI/SerializableVariant.h>
15
16 #include "commonapi/tests/DerivedTypeCollection.h"
17
18
19 class OutputStreamTest: public ::testing::Test {
20 protected:
21   size_t numOfElements;
22   CommonAPI::DBus::DBusMessage message;
23   const char* busName;
24   const char* objectPath;
25   const char* interfaceName;
26   const char* methodName;
27
28   void SetUp() {
29     numOfElements = 10;
30     busName = "no.bus.here";
31     objectPath = "/no/object/here";
32     interfaceName = "no.interface.here";
33     methodName = "noMethodHere";
34   }
35
36   void TearDown() {
37   }
38 };
39
40 TEST_F(OutputStreamTest, CanBeConstructed) {
41   CommonAPI::DBus::DBusOutputStream outStream(message);
42 }
43
44 TEST_F(OutputStreamTest, WritesBytes) {
45   const char* signature = "yyyyyyyyyy";
46   message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
47   CommonAPI::DBus::DBusOutputStream outStream(message);
48
49   outStream.reserveMemory(numOfElements);
50   uint8_t val1 = 0xff;
51   uint8_t val2 = 0x00;
52   for (unsigned int i = 0; i < numOfElements; i += 2) {
53     outStream << val1;
54     outStream << val2;
55   }
56   outStream.flush();
57
58   EXPECT_EQ(numOfElements, message.getBodyLength());
59
60   CommonAPI::DBus::DBusInputStream inStream(message);
61
62   uint8_t verifyVal1;
63   uint8_t verifyVal2;
64   for (unsigned int i = 0; i < numOfElements; i += 2) {
65     inStream >> verifyVal1;
66     EXPECT_EQ(val1, verifyVal1);
67
68     inStream >> verifyVal2;
69     EXPECT_EQ(val2, verifyVal2);
70   }
71 }
72
73 TEST_F(OutputStreamTest, WritesBools) {
74   const char* signature = "bbbbbbbbbb";
75   message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
76   CommonAPI::DBus::DBusOutputStream outStream(message);
77
78   outStream.reserveMemory(numOfElements * 4);
79   bool val1 = TRUE;
80   bool val2 = FALSE;
81   for (unsigned int i = 0; i < numOfElements; i += 2) {
82     outStream << val1;
83     outStream << val2;
84   }
85   outStream.flush();
86
87   EXPECT_EQ(numOfElements*4, message.getBodyLength());
88
89   CommonAPI::DBus::DBusInputStream inStream(message);
90
91   bool verifyVal1;
92   bool verifyVal2;
93   for (unsigned int i = 0; i < numOfElements; i += 2) {
94     inStream >> verifyVal1;
95     EXPECT_EQ(val1, verifyVal1);
96
97     inStream >> verifyVal2;
98     EXPECT_EQ(val2, verifyVal2);
99   }
100 }
101
102 TEST_F(OutputStreamTest, WritesUInt16) {
103   const char* signature = "qqqqqqqqqq";
104   message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
105   CommonAPI::DBus::DBusOutputStream outStream(message);
106
107   outStream.reserveMemory(numOfElements * 2);
108   uint16_t val1 = 0x0000;
109   uint16_t val2 = 0xffff;
110   for (unsigned int i = 0; i < numOfElements; i += 2) {
111     outStream << val1;
112     outStream << val2;
113   }
114   outStream.flush();
115
116   EXPECT_EQ(numOfElements*2, message.getBodyLength());
117
118   CommonAPI::DBus::DBusInputStream inStream(message);
119
120   uint16_t verifyVal1;
121   uint16_t verifyVal2;
122   for (unsigned int i = 0; i < numOfElements; i += 2) {
123     inStream >> verifyVal1;
124     EXPECT_EQ(val1, verifyVal1);
125
126     inStream >> verifyVal2;
127     EXPECT_EQ(val2, verifyVal2);
128   }
129 }
130
131 TEST_F(OutputStreamTest, WritesInt16) {
132   const char* signature = "nnnnnnnnnn";
133   message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
134   CommonAPI::DBus::DBusOutputStream outStream(message);
135
136   outStream.reserveMemory(numOfElements * 2);
137   int16_t val1 = 0x7fff;
138   int16_t val2 = 0xffff;
139   for (unsigned int i = 0; i < numOfElements; i += 2) {
140     outStream << val1;
141     outStream << val2;
142   }
143   outStream.flush();
144
145   EXPECT_EQ(numOfElements*2, message.getBodyLength());
146
147   CommonAPI::DBus::DBusInputStream inStream(message);
148
149   int16_t verifyVal1;
150   int16_t verifyVal2;
151   for (unsigned int i = 0; i < numOfElements; i += 2) {
152     inStream >> verifyVal1;
153     EXPECT_EQ(val1, verifyVal1);
154
155     inStream >> verifyVal2;
156     EXPECT_EQ(val2, verifyVal2);
157   }
158 }
159
160 TEST_F(OutputStreamTest, WritesUInt32) {
161   const char* signature = "uuuuuuuuuu";
162   message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
163   CommonAPI::DBus::DBusOutputStream outStream(message);
164
165   outStream.reserveMemory(numOfElements * 4);
166   uint32_t val1 = 0x00000000;
167   uint32_t val2 = 0xffffffff;
168   for (unsigned int i = 0; i < numOfElements; i += 2) {
169     outStream << val1;
170     outStream << val2;
171   }
172   outStream.flush();
173
174   EXPECT_EQ(numOfElements*4, message.getBodyLength());
175
176   CommonAPI::DBus::DBusInputStream inStream(message);
177
178   uint32_t verifyVal1;
179   uint32_t verifyVal2;
180   for (unsigned int i = 0; i < numOfElements; i += 2) {
181     inStream >> verifyVal1;
182     EXPECT_EQ(val1, verifyVal1);
183
184     inStream >> verifyVal2;
185     EXPECT_EQ(val2, verifyVal2);
186   }
187 }
188
189 TEST_F(OutputStreamTest, WritesInt32) {
190   const char* signature = "iiiiiiiiii";
191   message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
192   CommonAPI::DBus::DBusOutputStream outStream(message);
193
194   outStream.reserveMemory(numOfElements * 4);
195   int32_t val1 = 0x7fffffff;
196   int32_t val2 = 0xffffffff;
197   for (unsigned int i = 0; i < numOfElements; i += 2) {
198     outStream << val1;
199     outStream << val2;
200   }
201   outStream.flush();
202
203   EXPECT_EQ(numOfElements*4, message.getBodyLength());
204
205   CommonAPI::DBus::DBusInputStream inStream(message);
206
207   int32_t verifyVal1;
208   int32_t verifyVal2;
209   for (unsigned int i = 0; i < numOfElements; i += 2) {
210     inStream >> verifyVal1;
211     EXPECT_EQ(val1, verifyVal1);
212
213     inStream >> verifyVal2;
214     EXPECT_EQ(val2, verifyVal2);
215   }
216 }
217
218 TEST_F(OutputStreamTest, WritesUInt64) {
219   const char* signature = "tttttttttt";
220   message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
221   CommonAPI::DBus::DBusOutputStream outStream(message);
222
223   outStream.reserveMemory(numOfElements * 8);
224   uint64_t val1 = 0x0000000000000000;
225   uint64_t val2 = 0xffffffffffffffff;
226   for (unsigned int i = 0; i < numOfElements; i += 2) {
227     outStream << val1;
228     outStream << val2;
229   }
230   outStream.flush();
231
232   EXPECT_EQ(numOfElements*8, message.getBodyLength());
233
234   CommonAPI::DBus::DBusInputStream inStream(message);
235
236   uint64_t verifyVal1;
237   uint64_t verifyVal2;
238   for (unsigned int i = 0; i < numOfElements; i += 2) {
239     inStream >> verifyVal1;
240     EXPECT_EQ(val1, verifyVal1);
241
242     inStream >> verifyVal2;
243     EXPECT_EQ(val2, verifyVal2);
244   }
245 }
246
247 TEST_F(OutputStreamTest, WritesInt64) {
248   const char* signature = "xxxxxxxxxx";
249   message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
250   CommonAPI::DBus::DBusOutputStream outStream(message);
251
252   outStream.reserveMemory(numOfElements * 8);
253   int64_t val1 = 0x7fffffffffffffff;
254   int64_t val2 = 0xffffffffffffffff;
255   for (unsigned int i = 0; i < numOfElements; i += 2) {
256     outStream << val1;
257     outStream << val2;
258   }
259   outStream.flush();
260
261   EXPECT_EQ(numOfElements*8, message.getBodyLength());
262
263   CommonAPI::DBus::DBusInputStream inStream(message);
264
265   int64_t verifyVal1;
266   int64_t verifyVal2;
267   for (unsigned int i = 0; i < numOfElements; i += 2) {
268     inStream >> verifyVal1;
269     EXPECT_EQ(val1, verifyVal1);
270
271     inStream >> verifyVal2;
272     EXPECT_EQ(val2, verifyVal2);
273   }
274 }
275
276 TEST_F(OutputStreamTest, WritesDouble) {
277   const char* signature = "dddddddddd";
278   message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
279   CommonAPI::DBus::DBusOutputStream outStream(message);
280
281   outStream.reserveMemory(numOfElements * 8);
282   double val1 = 13.37;
283   double val2 = 3.414;
284   for (unsigned int i = 0; i < numOfElements; i += 2) {
285     outStream << val1;
286     outStream << val2;
287   }
288   outStream.flush();
289
290   EXPECT_EQ(numOfElements*8, message.getBodyLength());
291
292   CommonAPI::DBus::DBusInputStream inStream(message);
293
294   double verifyVal1;
295   double verifyVal2;
296   std::string verifySignature;
297   for (unsigned int i = 0; i < numOfElements; i += 2) {
298     inStream >> verifyVal1;
299     EXPECT_EQ(val1, verifyVal1);
300
301     inStream >> verifyVal2;
302     EXPECT_EQ(val2, verifyVal2);
303   }
304 }
305
306 TEST_F(OutputStreamTest, WritesStrings) {
307   const char* signature = "sss";
308   message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
309   CommonAPI::DBus::DBusOutputStream outStream(message);
310
311   std::string val1 = "hai";
312   std::string val2 = "ciao";
313   std::string val3 = "salut";
314
315   //sizes of the strings + terminating null-bytes (each 1 byte) + length-fields (each 4 bytes)
316   outStream.reserveMemory(val1.size() + val2.size() + val3.size() + 3 + 3 * 4);
317   outStream << val1 << val2 << val3;
318   outStream.flush();
319
320   //Length fields + actual strings + terminating '\0's + 3(padding)
321   EXPECT_EQ(3*4 + 3 + 4 + 5 + 3 + 3, message.getBodyLength());
322
323   CommonAPI::DBus::DBusInputStream inStream(message);
324
325   std::string verifyVal1;
326   std::string verifyVal2;
327   std::string verifyVal3;
328   std::string verifySignature;
329
330   inStream >> verifyVal1;
331   inStream >> verifyVal2;
332   inStream >> verifyVal3;
333
334   EXPECT_EQ(val1, verifyVal1);
335   EXPECT_EQ(val2, verifyVal2);
336   EXPECT_EQ(val3, verifyVal3);
337 }
338
339 namespace bmw {
340 namespace test {
341
342 struct myStruct: CommonAPI::SerializableStruct {
343   ~myStruct();
344
345   uint32_t a;
346   int16_t b;
347   bool c;
348   std::string d;
349   double e;
350
351   virtual void readFromInputStream(CommonAPI::InputStream& inputMessageStream);
352   virtual void writeToOutputStream(CommonAPI::OutputStream& outputMessageStream) const;
353 };
354
355 myStruct::~myStruct() {
356 }
357
358 void myStruct::readFromInputStream(CommonAPI::InputStream& inputMessageStream) {
359   inputMessageStream >> a >> b >> c >> d >> e;
360 }
361
362 void myStruct::writeToOutputStream(CommonAPI::OutputStream& outputMessageStream) const {
363   outputMessageStream << a << b << c << d << e;
364 }
365
366 } //namespace test
367 } //namespace bmw
368
369 TEST_F(OutputStreamTest, WritesStructs) {
370   const char* signature = "(unbsd)";
371   message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
372   CommonAPI::DBus::DBusOutputStream outStream(message);
373
374   bmw::test::myStruct testStruct;
375   testStruct.a = 15;
376   testStruct.b = -32;
377   testStruct.c = FALSE;
378   testStruct.d = "Hello all";
379   testStruct.e = 3.414;
380
381   // 40(byte length of struct) = 4(uint32_t) + 2(int16_t) + 2(padding) + 4(bool) + 4(strlength)
382   //                           + 9(string) + 1(terminating '\0' of string) + 6(padding) + 8 (double)
383   outStream.reserveMemory(40);
384   outStream << testStruct;
385   outStream.flush();
386
387   EXPECT_EQ(40, message.getBodyLength());
388
389   CommonAPI::DBus::DBusInputStream inStream(message);
390   bmw::test::myStruct verifyStruct;
391   inStream >> verifyStruct;
392
393   EXPECT_EQ(testStruct.a, verifyStruct.a);
394   EXPECT_EQ(testStruct.b, verifyStruct.b);
395   EXPECT_EQ(testStruct.c, verifyStruct.c);
396   EXPECT_EQ(testStruct.d, verifyStruct.d);
397   EXPECT_EQ(testStruct.e, verifyStruct.e);
398 }
399
400 TEST_F(OutputStreamTest, WritesArrays) {
401   const char* signature = "ai";
402   message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
403   CommonAPI::DBus::DBusOutputStream outStream(message);
404
405   std::vector<int32_t> testVector;
406   int32_t val1 = 0xffffffff;
407   int32_t val2 = 0x7fffffff;
408   for (unsigned int i = 0; i < numOfElements; i += 2) {
409     testVector.push_back(val1);
410     testVector.push_back(val2);
411   }
412
413   outStream.reserveMemory(numOfElements * 4 + 4);
414   outStream << testVector;
415   outStream.flush();
416
417   EXPECT_EQ(numOfElements*4 + 4, message.getBodyLength());
418
419   CommonAPI::DBus::DBusInputStream inStream(message);
420   std::vector<int32_t> verifyVector;
421   inStream >> verifyVector;
422
423   int32_t res1;
424   int32_t res2;
425   for (unsigned int i = 0; i < numOfElements; i += 2) {
426     res1 = verifyVector[i];
427     EXPECT_EQ(val1, res1);
428     res2 = verifyVector[i + 1];
429     EXPECT_EQ(val2, res2);
430   }
431 }
432
433 TEST_F(OutputStreamTest, WritesArraysOfStrings) {
434   const char* signature = "as";
435   message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
436   CommonAPI::DBus::DBusOutputStream outStream(message);
437
438   std::vector<std::string> testVector;
439   std::string val1 = "Hai";
440   std::string val2 = "Ciao";
441   for (unsigned int i = 0; i < numOfElements; i += 2) {
442     testVector.push_back(val1);
443     testVector.push_back(val2);
444   }
445
446   // 101 = 4(lengthFieldOfArray) +
447   //       4*(4(lengthField1) + 4(string1 mit \0-byte) + 4(lengthField2) + 5(string2 mit \0-byte) + 3(paddingTo4)) +
448   //         (4(lengthField1) + 4(string1 mit \0-byte) + 4(lengthField2) + 5(string2 mit \0-byte))
449   size_t vectorLength = 101;
450   outStream.reserveMemory(vectorLength);
451   outStream << testVector;
452   outStream.flush();
453
454   EXPECT_EQ(vectorLength, message.getBodyLength());
455
456   CommonAPI::DBus::DBusInputStream inStream(message);
457   std::vector<std::string> verifyVector;
458   inStream >> verifyVector;
459
460   std::string res1;
461   std::string res2;
462   for (unsigned int i = 0; i < numOfElements; i += 2) {
463     res1 = verifyVector[i];
464     EXPECT_EQ(val1, res1);
465     res2 = verifyVector[i + 1];
466     EXPECT_EQ(val2, res2);
467   }
468 }
469
470 TEST_F(OutputStreamTest, WritesArraysInArrays) {
471   const char* signature = "aai";
472   message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
473   CommonAPI::DBus::DBusOutputStream outStream(message);
474
475   std::vector<std::vector<int32_t>> testVector;
476   int32_t val1 = 0xffffffff;
477   int32_t val2 = 0x7fffffff;
478   for (unsigned int i = 0; i < numOfElements; i++) {
479     std::vector<int32_t> inner;
480     for (unsigned int j = 0; j < numOfElements; j += 2) {
481       inner.push_back(val1);
482       inner.push_back(val2);
483     }
484     testVector.push_back(inner);
485   }
486
487   outStream.reserveMemory(numOfElements * numOfElements * 4 + numOfElements * 4 + 4);
488   outStream << testVector;
489   outStream.flush();
490
491   EXPECT_EQ(numOfElements*numOfElements*4 + numOfElements*4 + 4, message.getBodyLength());
492
493   CommonAPI::DBus::DBusInputStream inStream(message);
494   std::vector<std::vector<int32_t>> verifyVector;
495   inStream >> verifyVector;
496
497   int32_t res1;
498   int32_t res2;
499   for (unsigned int i = 0; i < numOfElements; i++) {
500     std::vector<int32_t> innerVerify = verifyVector[i];
501     for (unsigned int j = 0; j < numOfElements; j += 2) {
502       res1 = innerVerify[j];
503       EXPECT_EQ(val1, res1);
504       res2 = innerVerify[j + 1];
505       EXPECT_EQ(val2, res2);
506     }
507   }
508 }
509
510 typedef CommonAPI::Variant<int8_t, uint32_t, double, std::string> BasicTypeVariant;
511
512 TEST_F(OutputStreamTest, WritesBasicTypeVariants) {
513   numOfElements = 4;
514   const char* signature = "(yv)(yv)(yv)(yv)";
515   message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
516   CommonAPI::DBus::DBusOutputStream outStream(message);
517
518   int8_t fromInt8Value = 7;
519   uint32_t fromUInt32Value = 42;
520   double fromDoubleValue = 13.37;
521   std::string fromStringValue = "Hai :)";
522   BasicTypeVariant int8Variant(fromInt8Value);
523   BasicTypeVariant uint32Variant(fromUInt32Value);
524   BasicTypeVariant doubleVariant(fromDoubleValue);
525   BasicTypeVariant stringVariant(fromStringValue);
526
527   /* TODO:
528   testVector.push_back(inner);
529
530   //4 * (1(byte) + 2(signature length + content)) + 1(int8_t) + 4(uint32_t) + 8(double) +
531   outStream.reserveMemory(numOfElements * numOfElements * 4 + numOfElements * 4 + 4);
532   outStream << testVector;
533   outStream.flush();
534
535   EXPECT_EQ(numOfElements*numOfElements*4 + numOfElements*4 + 4, message.getBodyLength());
536
537   CommonAPI::DBus::DBusInputStream inStream(message);
538   std::vector<std::vector<int32_t>> verifyVector;
539   inStream >> verifyVector;
540
541   int32_t res1;
542   int32_t res2;
543   for (int i = 0; i < numOfElements; i++) {
544     std::vector<int32_t> innerVerify = verifyVector[i];
545     for (int j = 0; j < numOfElements; j += 2) {
546       res1 = innerVerify[j];
547       EXPECT_EQ(val1, res1);
548       res2 = innerVerify[j + 1];
549       EXPECT_EQ(val2, res2);
550     }
551   }
552   */
553 }
554
555 namespace com {
556 namespace bmw {
557 namespace test {
558
559 struct TestStruct: CommonAPI::SerializableStruct {
560   TestStruct();
561   TestStruct(int32_t v1, double v2, double v3, std::string v4);
562   ~TestStruct();
563
564   int32_t val1;
565   double val2;
566   double val3;
567   std::string val4;
568
569   virtual void readFromInputStream(CommonAPI::InputStream& inputMessageStream);
570   virtual void writeToOutputStream(CommonAPI::OutputStream& outputMessageStream) const;
571 };
572
573 typedef std::vector<TestStruct> TestStructList;
574
575 TestStruct::TestStruct() :
576     val1(0), val2(0), val3(0), val4("") {
577 }
578
579 TestStruct::TestStruct(int32_t v1, double v2, double v3, std::string v4) :
580     val1(v1), val2(v2), val3(v3), val4(v4) {
581 }
582
583 TestStruct::~TestStruct() {
584 }
585
586 void TestStruct::readFromInputStream(CommonAPI::InputStream& inputMessageStream) {
587   inputMessageStream >> val1 >> val2 >> val3 >> val4;
588 }
589
590 void TestStruct::writeToOutputStream(CommonAPI::OutputStream& outputMessageStream) const {
591   outputMessageStream << val1 << val2 << val3 << val4;
592 }
593
594 } // namespace test
595 } // namespace bmw
596 } // namespace com
597
598
599 TEST_F(OutputStreamTest, WritesTestStructs) {
600   const char* signature = "(idds)";
601   message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
602   CommonAPI::DBus::DBusOutputStream outStream(message);
603
604   com::bmw::test::TestStruct testStruct(1, 12.6, 1e40, "XXXXXXXXXXXXXXXXXXXX");
605
606   //4(int32_t) + 4(padding) + 8(double) + 8(double) + 4(str_length) + 20(string) + 1(null-termination)
607   uint32_t expectedSize = 49;
608   outStream.reserveMemory(expectedSize);
609   outStream << testStruct;
610   outStream.flush();
611
612   EXPECT_EQ(expectedSize, message.getBodyLength());
613
614   CommonAPI::DBus::DBusInputStream inStream(message);
615   com::bmw::test::TestStruct verifyStruct;
616   inStream >> verifyStruct;
617
618   EXPECT_EQ(testStruct.val1, verifyStruct.val1);
619   EXPECT_EQ(testStruct.val2, verifyStruct.val2);
620   EXPECT_EQ(testStruct.val3, verifyStruct.val3);
621   EXPECT_EQ(testStruct.val4, verifyStruct.val4);
622 }
623
624 TEST_F(OutputStreamTest, WritesTestStructLists) {
625   const char* signature = "a(idds)";
626   message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
627   CommonAPI::DBus::DBusOutputStream outStream(message);
628
629   com::bmw::test::TestStructList testList;
630   for (unsigned int i = 0; i < numOfElements; i++) {
631     testList.emplace_back(1, 12.6, 1e40, "XXXXXXXXXXXXXXXXXXXX");
632   }
633
634   //struct size: 49 = 4(int32_t) + 4(padding) + 8(double) + 8(double) + 4(str_length) + 20(string) + 1(null-termination)
635   //array size:  4(array_length) + 4(struct_padding) + (numElements-1)*(49(struct) + 7(struct_padding)) + 49(struct)
636   uint32_t expectedSize = 8 + (numOfElements - 1) * (49 + 7) + 49;
637   outStream.reserveMemory(expectedSize);
638   outStream << testList;
639   outStream.flush();
640
641   EXPECT_EQ(expectedSize, message.getBodyLength());
642
643   CommonAPI::DBus::DBusInputStream inStream(message);
644   com::bmw::test::TestStructList verifyList;
645   inStream >> verifyList;
646
647   EXPECT_EQ(numOfElements, verifyList.size());
648 }
649
650
651
652 namespace com {
653 namespace bmw {
654 namespace test {
655
656 struct ArrayStruct: CommonAPI::SerializableStruct {
657   ArrayStruct();
658   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);
659   ~ArrayStruct();
660
661   std::vector<int64_t> val1;
662   std::vector<std::string> val2;
663   std::vector<double> val3;
664   std::vector<std::string> val4;
665   std::vector<uint16_t> val5;
666
667   virtual void readFromInputStream(CommonAPI::InputStream& inputMessageStream);
668   virtual void writeToOutputStream(CommonAPI::OutputStream& outputMessageStream) const;
669 };
670
671 typedef std::vector<TestStruct> TestStructList;
672
673 ArrayStruct::ArrayStruct() {
674 }
675
676 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) :
677     val1(v1), val2(v2), val3(v3), val4(v4), val5(v5) {
678 }
679
680 ArrayStruct::~ArrayStruct() {
681 }
682
683 void ArrayStruct::readFromInputStream(CommonAPI::InputStream& inputMessageStream) {
684   inputMessageStream >> val1 >> val2 >> val3 >> val4 >> val5;
685 }
686
687 void ArrayStruct::writeToOutputStream(CommonAPI::OutputStream& outputMessageStream) const {
688   outputMessageStream << val1 << val2 << val3 << val4 << val5;
689 }
690
691 } // namespace test
692 } // namespace bmw
693 } // namespace com
694
695
696 TEST_F(OutputStreamTest, WritesStructsOfArraysWithSthBefore) {
697   const char* signature = "(axasadasaq)";
698   message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
699   CommonAPI::DBus::DBusOutputStream outStream(message);
700
701   com::bmw::test::ArrayStruct arrayStruct;
702   for (unsigned int i = 0; i < numOfElements; i++) {
703       arrayStruct.val1.push_back(i*50);
704       arrayStruct.val2.push_back("Hai");
705       arrayStruct.val3.push_back(3.414);
706       arrayStruct.val4.push_back("Ciao");
707       arrayStruct.val5.push_back(i*5);
708   }
709   uint16_t frontValue = 0;
710
711   // 2(uint16) + 6(padding)                                             --> 8
712   // 4(LengthField) + 4(padding) + 10 * 8(int64)                        --> 88  --> 96
713   // 4(LengthField) + 10 * (4(LengthField) + 4("Hai\0"))                --> 84  --> 180
714   // 4(LengthField) + 10 * 8(double)                                    --> 84  --> 264
715   // 4(LengthField) + 10 * (4(LengthField) + 5("Ciao\0") + 3(padding))  --> 124 --> 388
716   // 4(LengthField) + 10 * 2(uint16)                                    --> 24  --> 412
717   size_t structLength = 412;
718   outStream.reserveMemory(structLength);
719   outStream << frontValue << arrayStruct;
720   outStream.flush();
721
722   EXPECT_EQ(structLength, message.getBodyLength());
723
724   CommonAPI::DBus::DBusInputStream inStream(message);
725   com::bmw::test::ArrayStruct verifyStruct;
726
727   uint16_t frontVerification;
728   inStream >> frontVerification >> verifyStruct;
729
730   EXPECT_EQ(frontValue, frontVerification);
731
732   int64_t res1;
733   std::string res2;
734   double res3;
735   std::string res4;
736   uint16_t res5;
737
738   for (unsigned int i = 0; i < numOfElements; i++) {
739     res1 = verifyStruct.val1[i];
740     res2 = verifyStruct.val2[i];
741     res3 = verifyStruct.val3[i];
742     res4 = verifyStruct.val4[i];
743     res5 = verifyStruct.val5[i];
744
745     EXPECT_EQ(i*50, res1);
746     EXPECT_EQ(std::string("Hai"), res2);
747     EXPECT_EQ(3.414, res3);
748     EXPECT_EQ(std::string("Ciao"), res4);
749     EXPECT_EQ(i*5, res5);
750   }
751 }
752
753
754
755 TEST_F(OutputStreamTest, WritesEnumKeyedMaps) {
756   commonapi::tests::DerivedTypeCollection::TestEnumMap testEnumMap;
757
758   commonapi::tests::DerivedTypeCollection::TestEnum key1 = commonapi::tests::DerivedTypeCollection::TestEnum::E_NOT_USED;
759   commonapi::tests::DerivedTypeCollection::TestEnum key2 = commonapi::tests::DerivedTypeCollection::TestEnum::E_OK;
760   commonapi::tests::DerivedTypeCollection::TestEnum key3 = commonapi::tests::DerivedTypeCollection::TestEnum::E_OUT_OF_RANGE;
761   commonapi::tests::DerivedTypeCollection::TestEnum key4 = commonapi::tests::DerivedTypeCollection::TestEnum::E_UNKNOWN;
762   std::string val = "Hai";
763
764   testEnumMap.insert( {key1, val} );
765   testEnumMap.insert( {key2, val} );
766   testEnumMap.insert( {key3, val} );
767   testEnumMap.insert( {key4, val} );
768
769   const char* signature = "a{is}";
770   message = CommonAPI::DBus::DBusMessage::createMethodCall(busName, objectPath, interfaceName, methodName, signature);
771   CommonAPI::DBus::DBusOutputStream outStream(message);
772
773   //array length (4) + struct-padding (4) +
774   //      3 * (sizeof(int) + sizeof(string) + struct-padding) + (sizeof(int) + sizeof(string))
775   size_t sizeOfBody = 4 + 4 + 3 * (4 + 8 + 4) + (4 + 8);
776   outStream.reserveMemory(sizeOfBody);
777   outStream << testEnumMap;
778   outStream.flush();
779
780   EXPECT_EQ(sizeOfBody, message.getBodyLength());
781
782   CommonAPI::DBus::DBusInputStream inStream(message);
783
784   commonapi::tests::DerivedTypeCollection::TestEnumMap verificationMap;
785   inStream >> verificationMap;
786
787   for(auto it = verificationMap.begin(); it != verificationMap.end(); ++it) {
788     ASSERT_EQ(it->second, testEnumMap[it->first]);
789   }
790 }
791
792 int main(int argc, char** argv) {
793     ::testing::InitGoogleTest(&argc, argv);
794     return RUN_ALL_TESTS();
795 }