tests: fix blocking semantic in DBusProxyTest
[profile/ivi/common-api-dbus-runtime.git] / src / test / DBusInputStreamTest.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 <CommonAPI/SerializableStruct.h>
8 #include <CommonAPI/SerializableVariant.h>
9 #include <CommonAPI/DBus/DBusInputStream.h>
10 #include <CommonAPI/DBus/DBusOutputStream.h>
11
12 #include "DBusTestUtils.h"
13
14 #include <unordered_map>
15 #include <bits/functional_hash.h>
16
17 #include <gtest/gtest.h>
18
19 #include <dbus/dbus.h>
20
21 #include <chrono>
22 #include <cstdint>
23 #include <vector>
24 #include <unordered_map>
25 #include <bits/functional_hash.h>
26
27
28 class InputStreamTest: public ::testing::Test {
29   protected:
30     DBusMessage* libdbusMessage;
31     DBusMessageIter libdbusMessageWriteIter;
32     size_t numOfElements;
33
34     void SetUp() {
35         numOfElements = 2;
36         libdbusMessage = dbus_message_new_method_call("no.bus.here", "/no/object/here", NULL, "noMethodHere");
37         ASSERT_TRUE(libdbusMessage != NULL);
38         dbus_message_iter_init_append(libdbusMessage, &libdbusMessageWriteIter);
39     }
40
41     void TearDown() {
42         dbus_message_unref(libdbusMessage);
43     }
44 };
45
46 TEST_F(InputStreamTest, CanBeConstructed) {
47     CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
48     CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
49 }
50
51 TEST_F(InputStreamTest, ReadsEmptyMessages) {
52     CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
53     CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
54
55     EXPECT_EQ(0, scopedMessage.getBodyLength());
56 }
57
58 TEST_F(InputStreamTest, ReadsBytes) {
59     uint8_t val = 0xff;
60     for (unsigned int i = 0; i < numOfElements; i += 1) {
61         dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_BYTE, &val);
62     }
63
64     CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
65     CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
66
67     EXPECT_EQ(numOfElements, scopedMessage.getBodyLength());
68     for (unsigned int i = 0; i < numOfElements; i += 1) {
69         uint8_t readVal;
70         inStream >> readVal;
71         EXPECT_EQ(val, readVal);
72     }
73 }
74
75 TEST_F(InputStreamTest, ReadsBools) {
76     dbus_bool_t f = FALSE;
77     dbus_bool_t t = TRUE;
78     for (unsigned int i = 0; i < numOfElements; i += 2) {
79         dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_BOOLEAN, &t);
80         dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_BOOLEAN, &f);
81     }
82
83     CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
84     CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
85
86     EXPECT_EQ(numOfElements*4, scopedMessage.getBodyLength());
87     for (unsigned int i = 0; i < numOfElements; i += 2) {
88         bool readVal;
89         inStream >> readVal;
90         EXPECT_EQ(t, readVal);
91         inStream >> readVal;
92         EXPECT_EQ(f, readVal);
93     }
94 }
95
96 TEST_F(InputStreamTest, ReadsUint16) {
97
98     uint16_t val = 0xffff;
99     for (unsigned int i = 0; i < numOfElements; i += 1) {
100         dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_UINT16, &val);
101     }
102
103     CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
104     CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
105
106     EXPECT_EQ(numOfElements*2, scopedMessage.getBodyLength());
107     for (unsigned int i = 0; i < numOfElements; i += 1) {
108         uint16_t readVal;
109         inStream >> readVal;
110         EXPECT_EQ(val, readVal);
111     }
112 }
113
114 TEST_F(InputStreamTest, ReadsInt16) {
115
116     int16_t val = 0x7fff;
117     for (unsigned int i = 0; i < numOfElements; i += 1) {
118         dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_INT16, &val);
119     }
120
121     CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
122     CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
123
124     EXPECT_EQ(numOfElements*2, scopedMessage.getBodyLength());
125     for (unsigned int i = 0; i < numOfElements; i += 1) {
126         int16_t readVal;
127         inStream >> readVal;
128         EXPECT_EQ(val, readVal);
129     }
130 }
131
132 TEST_F(InputStreamTest, ReadsUint32) {
133
134     uint32_t val = 0xffffffff;
135     for (unsigned int i = 0; i < numOfElements; i += 1) {
136         dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_UINT32, &val);
137     }
138
139     CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
140     CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
141
142     EXPECT_EQ(numOfElements*4, scopedMessage.getBodyLength());
143     for (unsigned int i = 0; i < numOfElements; i += 1) {
144         uint32_t readVal;
145         inStream >> readVal;
146         EXPECT_EQ(val, readVal);
147     }
148 }
149
150 TEST_F(InputStreamTest, ReadsInt32) {
151
152     int32_t val = 0x7fffffff;
153     for (unsigned int i = 0; i < numOfElements; i += 1) {
154         dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_INT32, &val);
155     }
156
157     CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
158     CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
159
160     EXPECT_EQ(numOfElements*4, scopedMessage.getBodyLength());
161     for (unsigned int i = 0; i < numOfElements; i += 1) {
162         int32_t readVal;
163         inStream >> readVal;
164         EXPECT_EQ(val, readVal);
165     }
166 }
167
168 TEST_F(InputStreamTest, ReadsUint64) {
169
170     uint64_t val = 0xffffffffffffffff;
171     for (unsigned int i = 0; i < numOfElements; i += 1) {
172         dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_UINT64, &val);
173     }
174
175     CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
176     CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
177
178     EXPECT_EQ(numOfElements*8, scopedMessage.getBodyLength());
179     for (unsigned int i = 0; i < numOfElements; i += 1) {
180         uint64_t readVal;
181         inStream >> readVal;
182         EXPECT_EQ(val, readVal);
183     }
184 }
185
186 TEST_F(InputStreamTest, ReadsInt64) {
187
188     int64_t val = 0x7fffffffffffffff;
189     for (unsigned int i = 0; i < numOfElements; i += 1) {
190         dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_INT64, &val);
191     }
192
193     CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
194     CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
195
196     EXPECT_EQ(numOfElements*8, scopedMessage.getBodyLength());
197     for (unsigned int i = 0; i < numOfElements; i += 1) {
198         int64_t readVal;
199         inStream >> readVal;
200         EXPECT_EQ(val, readVal);
201     }
202 }
203
204 TEST_F(InputStreamTest, ReadsDoubles) {
205
206     double val = 13.37;
207     for (unsigned int i = 0; i < numOfElements; i += 1) {
208         dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_DOUBLE, &val);
209     }
210
211     CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
212     CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
213
214     EXPECT_EQ(numOfElements*8, scopedMessage.getBodyLength());
215     for (unsigned int i = 0; i < numOfElements; i += 1) {
216         double readVal;
217         inStream >> readVal;
218         EXPECT_EQ(val, readVal);
219     }
220 }
221
222 TEST_F(InputStreamTest, ReadsStrings) {
223
224     std::string val = "hai";
225     for (unsigned int i = 0; i < numOfElements; i += 1) {
226         dbus_message_iter_append_basic(&libdbusMessageWriteIter, DBUS_TYPE_STRING, &val);
227     }
228
229     CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
230     CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
231
232     EXPECT_EQ(numOfElements*4 + numOfElements*4, scopedMessage.getBodyLength());
233     for (unsigned int i = 0; i < numOfElements; i += 1) {
234         std::string readVal;
235         inStream >> readVal;
236         EXPECT_EQ(val, readVal);
237     }
238 }
239
240
241
242 namespace bmw {
243 namespace test {
244
245 struct TestSerializableStruct: CommonAPI::SerializableStruct {
246     uint32_t a;
247     int16_t b;
248     bool c;
249     std::string d;
250     double e;
251
252         virtual void readFromInputStream(CommonAPI::InputStream& inputStream) {
253                 inputStream >> a >> b >> c >> d >> e;
254         }
255
256         virtual void writeToOutputStream(CommonAPI::OutputStream& outputStream) const {
257                 outputStream << a << b << c << d << e;
258         }
259
260     static void writeToTypeOutputStream(CommonAPI::TypeOutputStream& typeOutputStream) {
261         typeOutputStream.writeUInt32Type();
262         typeOutputStream.writeInt16Type();
263         typeOutputStream.writeBoolType();
264         typeOutputStream.writeStringType();
265         typeOutputStream.writeDoubleType();
266     }
267 };
268
269 bool operator==(const TestSerializableStruct& lhs, const TestSerializableStruct& rhs) {
270     if (&lhs == &rhs)
271         return true;
272
273     return (lhs.a == rhs.a) && (lhs.b == rhs.b) && (lhs.c == rhs.c) && (lhs.d == rhs.d) && (lhs.e == rhs.e);
274 }
275
276 } //namespace test
277 } //namespace bmw
278
279 TEST_F(InputStreamTest, ReadsStructs) {
280
281     bmw::test::TestSerializableStruct testStruct;
282     testStruct.a = 15;
283     testStruct.b = -32;
284     testStruct.c = FALSE;
285     testStruct.d = "Hello all";
286     testStruct.e = 3.414;
287
288     DBusMessageIter subIter;
289     dbus_message_iter_open_container(&libdbusMessageWriteIter, DBUS_TYPE_STRUCT, NULL, &subIter);
290     dbus_message_iter_append_basic(&subIter, DBUS_TYPE_UINT32, &testStruct.a);
291     dbus_message_iter_append_basic(&subIter, DBUS_TYPE_INT16, &testStruct.b);
292     dbus_bool_t dbusBool = static_cast<dbus_bool_t>(testStruct.c);
293     dbus_message_iter_append_basic(&subIter, DBUS_TYPE_BOOLEAN, &dbusBool);
294     dbus_message_iter_append_basic(&subIter, DBUS_TYPE_STRING, &testStruct.d);
295     dbus_message_iter_append_basic(&subIter, DBUS_TYPE_DOUBLE, &testStruct.e);
296     dbus_message_iter_close_container(&libdbusMessageWriteIter, &subIter);
297
298     CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
299     CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
300
301     //40(byte length of struct) = 4(uint32_t) + 2(int16_t) + 2(padding) + 4(bool) + 4(strlength)
302     //                          + 9(string) + 1(terminating '\0' of string) + 6(padding) + 8 (double)
303     EXPECT_EQ(40, scopedMessage.getBodyLength());
304
305     bmw::test::TestSerializableStruct verifyStruct;
306     inStream >> verifyStruct;
307     EXPECT_EQ(testStruct.a, verifyStruct.a);
308     EXPECT_EQ(testStruct.b, verifyStruct.b);
309     EXPECT_EQ(testStruct.c, verifyStruct.c);
310     EXPECT_EQ(testStruct.d, verifyStruct.d);
311     EXPECT_EQ(testStruct.e, verifyStruct.e);
312 }
313
314 TEST_F(InputStreamTest, ReadsArrays) {
315
316     std::vector<int32_t> testVector;
317     int32_t val1 = 0xffffffff;
318     int32_t val2 = 0x7fffffff;
319     for (unsigned int i = 0; i < numOfElements; i += 2) {
320         testVector.push_back(val1);
321         testVector.push_back(val2);
322     }
323
324     DBusMessageIter subIter;
325     dbus_message_iter_open_container(&libdbusMessageWriteIter, DBUS_TYPE_ARRAY, "i", &subIter);
326     for (unsigned int i = 0; i < numOfElements; i++) {
327         dbus_message_iter_append_basic(&subIter, DBUS_TYPE_INT32, &testVector[i]);
328     }
329     dbus_message_iter_close_container(&libdbusMessageWriteIter, &subIter);
330
331     CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
332     CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
333
334     EXPECT_EQ(scopedMessage.getBodyLength(), numOfElements*4 + 4);
335     std::vector<int32_t> verifyVector;
336     inStream >> verifyVector;
337     int32_t res1;
338     int32_t res2;
339     for (unsigned int i = 0; i < numOfElements; i += 2) {
340         res1 = verifyVector[i];
341         EXPECT_EQ(val1, res1);
342         res2 = verifyVector[i + 1];
343         EXPECT_EQ(val2, res2);
344     }
345 }
346
347 TEST_F(InputStreamTest, ReadsArraysInArrays) {
348     size_t numOfElements = 2;
349     DBusMessage* dbusMessage = dbus_message_new_method_call("no.bus.here", "/no/object/here", NULL, "noMethodHere");
350     ASSERT_TRUE(dbusMessage != NULL);
351
352     DBusMessageIter writeIter;
353     dbus_message_iter_init_append(dbusMessage, &writeIter);
354
355     std::vector<std::vector<int32_t>> testVector;
356     int32_t val1 = 0xffffffff;
357     int32_t val2 = 0x7fffffff;
358     for (unsigned int i = 0; i < numOfElements; i++) {
359         std::vector<int32_t> inner;
360         for (unsigned int j = 0; j < numOfElements; j += 2) {
361             inner.push_back(val1);
362             inner.push_back(val2);
363         }
364         testVector.push_back(inner);
365     }
366
367     DBusMessageIter subIter;
368     dbus_message_iter_open_container(&writeIter, DBUS_TYPE_ARRAY, "ai", &subIter);
369     for (unsigned int i = 0; i < numOfElements; i++) {
370         DBusMessageIter subsubIter;
371         dbus_message_iter_open_container(&subIter, DBUS_TYPE_ARRAY, "i", &subsubIter);
372         for (unsigned int j = 0; j < numOfElements; j++) {
373             dbus_message_iter_append_basic(&subsubIter, DBUS_TYPE_INT32, &(testVector[i][j]));
374         }
375         dbus_message_iter_close_container(&subIter, &subsubIter);
376     }
377     dbus_message_iter_close_container(&writeIter, &subIter);
378
379     CommonAPI::DBus::DBusMessage scopedMessage(dbusMessage);
380     CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
381
382     // 5*5*int32_t + 5*lengthField_inner(int32_t) + lengthField_outer(int32_t)
383     EXPECT_EQ(numOfElements*numOfElements*4 + numOfElements*4 + 4, scopedMessage.getBodyLength());
384     std::vector<std::vector<int32_t>> verifyVector;
385     inStream >> verifyVector;
386
387     int32_t res1;
388     int32_t res2;
389     for (unsigned int i = 0; i < numOfElements; i++) {
390         std::vector<int32_t> innerVerify = verifyVector[i];
391         for (unsigned int j = 0; j < numOfElements; j += 2) {
392             res1 = innerVerify[j];
393             EXPECT_EQ(val1, res1);
394             res2 = innerVerify[j + 1];
395             EXPECT_EQ(val2, res2);
396         }
397     }
398 }
399
400 TEST_F(InputStreamTest, ReadsInt32Variants) {
401     typedef CommonAPI::Variant<int32_t, double, std::string> TestedVariantType;
402
403     int32_t fromInt = 5;
404     int8_t variantTypeIndex = 3;
405
406     for (unsigned int i = 0; i < numOfElements; i += 1) {
407         DBusMessageIter subIter;
408         dbus_message_iter_open_container(&libdbusMessageWriteIter, DBUS_TYPE_STRUCT, NULL, &subIter);
409         dbus_message_iter_append_basic(&subIter, DBUS_TYPE_BYTE, &variantTypeIndex);
410         DBusMessageIter subSubIter;
411         dbus_message_iter_open_container(&subIter, DBUS_TYPE_VARIANT, "i", &subSubIter);
412         dbus_message_iter_append_basic(&subSubIter, DBUS_TYPE_INT32, &fromInt);
413         dbus_message_iter_close_container(&subIter, &subSubIter);
414         dbus_message_iter_close_container(&libdbusMessageWriteIter, &subIter);
415     }
416
417     CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
418     CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
419
420     TestedVariantType referenceVariant(fromInt);
421
422     EXPECT_EQ(numOfElements*4 + numOfElements*4, scopedMessage.getBodyLength());
423     for (unsigned int i = 0; i < numOfElements; i += 1) {
424         TestedVariantType readVariant;
425         inStream >> readVariant;
426
427         //TODO: EXPECT_NO_THROW   (oder so)
428         int32_t actualResult = readVariant.get<int32_t>();
429
430         bool varEq = (referenceVariant == readVariant);
431         EXPECT_TRUE(varEq);
432         EXPECT_EQ(fromInt, actualResult);
433     }
434 }
435
436 TEST_F(InputStreamTest, ReadsStringVariants) {
437     typedef CommonAPI::Variant<int32_t, double, std::string> TestedVariantType;
438
439     std::string fromString = "Hello World with CommonAPI Variants!";
440     int8_t variantTypeIndex = 1;
441
442     for (unsigned int i = 0; i < numOfElements; i += 1) {
443         DBusMessageIter subIter;
444         dbus_message_iter_open_container(&libdbusMessageWriteIter, DBUS_TYPE_STRUCT, NULL, &subIter);
445         dbus_message_iter_append_basic(&subIter, DBUS_TYPE_BYTE, &variantTypeIndex);
446         DBusMessageIter subSubIter;
447         dbus_message_iter_open_container(&subIter, DBUS_TYPE_VARIANT, "s", &subSubIter);
448         dbus_message_iter_append_basic(&subSubIter, DBUS_TYPE_STRING, &fromString);
449         dbus_message_iter_close_container(&subIter, &subSubIter);
450         dbus_message_iter_close_container(&libdbusMessageWriteIter, &subIter);
451     }
452
453     CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
454     CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
455
456     TestedVariantType referenceVariant(fromString);
457
458     //Variant: type-index(1) + signature(2) + padding(1) + stringLength(4) + string(37) = 45
459     //         +struct-padding inbetween (alignment 8)
460     EXPECT_EQ(numOfElements * (1+3+4+fromString.length()+1) + (numOfElements - 1) * (8-((fromString.length()+1)%8)) , scopedMessage.getBodyLength());
461     for (unsigned int i = 0; i < numOfElements; i += 1) {
462         TestedVariantType readVariant;
463         inStream >> readVariant;
464
465         std::string actualResult = readVariant.get<std::string>();
466
467         bool variantsAreEqual = (referenceVariant == readVariant);
468         EXPECT_TRUE(variantsAreEqual);
469         EXPECT_EQ(fromString, actualResult);
470     }
471 }
472
473
474 TEST_F(InputStreamTest, ReadsVariantsWithAnArrayOfStrings) {
475     typedef CommonAPI::Variant<int32_t, double, std::vector<std::string>> TestedVariantType;
476
477     std::string testString1 = "Hello World with CommonAPI Variants!";
478     std::string testString2 = "What a beautiful world if there are working Arrays within Variants!!";
479     int8_t variantTypeIndex = 1;
480
481     std::vector<std::string> testInnerVector;
482
483     for (unsigned int i = 0; i < numOfElements; i += 2) {
484         testInnerVector.push_back(testString1);
485         testInnerVector.push_back(testString2);
486     }
487
488     for (unsigned int i = 0; i < numOfElements; i += 1) {
489         DBusMessageIter subIter;
490         dbus_message_iter_open_container(&libdbusMessageWriteIter, DBUS_TYPE_STRUCT, NULL, &subIter);
491         dbus_message_iter_append_basic(&subIter, DBUS_TYPE_BYTE, &variantTypeIndex);
492         DBusMessageIter subSubIter;
493         dbus_message_iter_open_container(&subIter, DBUS_TYPE_VARIANT, "as", &subSubIter);
494
495         DBusMessageIter innerArrayIter;
496         dbus_message_iter_open_container(&subSubIter, DBUS_TYPE_ARRAY, "s", &innerArrayIter);
497         for (unsigned int i = 0; i < numOfElements; i++) {
498             dbus_message_iter_append_basic(&innerArrayIter, DBUS_TYPE_STRING, &testInnerVector[i]);
499         }
500         dbus_message_iter_close_container(&subSubIter, &innerArrayIter);
501
502         dbus_message_iter_close_container(&subIter, &subSubIter);
503         dbus_message_iter_close_container(&libdbusMessageWriteIter, &subIter);
504     }
505
506     CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
507     CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
508
509     TestedVariantType referenceVariant(testInnerVector);
510
511     //Variant: structAlign + type-index(1) + variantSignature(4) + padding(3) + arrayLength(4) + stringLength(4) +
512     //         string(37) + padding(3) + stringLength(4) + string(69) = 129
513     EXPECT_EQ(129 + 7 + 129, scopedMessage.getBodyLength());
514     for (unsigned int i = 0; i < numOfElements; i += 1) {
515         TestedVariantType readVariant;
516         inStream >> readVariant;
517
518         std::vector<std::string> actualResult = readVariant.get<std::vector<std::string>>();
519
520         bool variantsAreEqual = (referenceVariant == readVariant);
521         EXPECT_TRUE(variantsAreEqual);
522         EXPECT_EQ(testInnerVector, actualResult);
523     }
524
525 }
526
527
528 TEST_F(InputStreamTest, ReadsVariantsWithVariants) {
529     typedef CommonAPI::Variant<int8_t, uint64_t, CommonAPI::ByteBuffer> InnerVariantType;
530
531     typedef CommonAPI::Variant<int32_t,
532                                double,
533                                std::string,
534                                InnerVariantType>
535             TestedVariantType;
536
537     int8_t outerVariantTypeIndex = 1;
538     int8_t innerVariant1TypeIndex = 1;
539     int8_t innerVariant2TypeIndex = 3;
540
541     const uint32_t byteBufferElementCount = numOfElements*10;
542
543     CommonAPI::ByteBuffer innerVariant1Value;
544     for (unsigned int i = 0; i < byteBufferElementCount; ++i) {
545         innerVariant1Value.push_back((char) (i+40));
546     }
547
548     int8_t innerVariant2Value = -55;
549
550
551     DBusMessageIter outerVariantStructIter;
552     DBusMessageIter outerVariantActualIter;
553     DBusMessageIter innerVariantStructIter;
554     DBusMessageIter innerVariantActualIterator;
555     DBusMessageIter innerArrayIter;
556
557
558     //begin 1. outer variant
559     dbus_message_iter_open_container(&libdbusMessageWriteIter, DBUS_TYPE_STRUCT, NULL, &outerVariantStructIter);
560     dbus_message_iter_append_basic(&outerVariantStructIter, DBUS_TYPE_BYTE, &outerVariantTypeIndex);
561     dbus_message_iter_open_container(&outerVariantStructIter, DBUS_TYPE_VARIANT, "(yv)", &outerVariantActualIter);
562
563     //begin inner variant
564     dbus_message_iter_open_container(&outerVariantActualIter, DBUS_TYPE_STRUCT, NULL, &innerVariantStructIter);
565     dbus_message_iter_append_basic(&innerVariantStructIter, DBUS_TYPE_BYTE, &innerVariant1TypeIndex);
566     dbus_message_iter_open_container(&innerVariantStructIter, DBUS_TYPE_VARIANT, "ay", &innerVariantActualIterator);
567
568     //begin inner variant content
569     dbus_message_iter_open_container(&innerVariantActualIterator, DBUS_TYPE_ARRAY, "y", &innerArrayIter);
570     for (unsigned int i = 0; i < byteBufferElementCount; i++) {
571         dbus_message_iter_append_basic(&innerArrayIter, DBUS_TYPE_BYTE, &innerVariant1Value[i]);
572     }
573     dbus_message_iter_close_container(&innerVariantActualIterator, &innerArrayIter);
574     //end inner variant content
575
576     dbus_message_iter_close_container(&innerVariantStructIter, &innerVariantActualIterator);
577     dbus_message_iter_close_container(&outerVariantActualIter, &innerVariantStructIter);
578     //end inner variant
579
580     dbus_message_iter_close_container(&outerVariantStructIter, &outerVariantActualIter);
581     dbus_message_iter_close_container(&libdbusMessageWriteIter, &outerVariantStructIter);
582     //end 1. outer variant
583
584
585     //begin 2. outer variant
586     dbus_message_iter_open_container(&libdbusMessageWriteIter, DBUS_TYPE_STRUCT, NULL, &outerVariantStructIter);
587     dbus_message_iter_append_basic(&outerVariantStructIter, DBUS_TYPE_BYTE, &outerVariantTypeIndex);
588     dbus_message_iter_open_container(&outerVariantStructIter, DBUS_TYPE_VARIANT, "(yv)", &outerVariantActualIter);
589
590     //begin inner variant
591     dbus_message_iter_open_container(&outerVariantActualIter, DBUS_TYPE_STRUCT, NULL, &innerVariantStructIter);
592     dbus_message_iter_append_basic(&innerVariantStructIter, DBUS_TYPE_BYTE, &innerVariant2TypeIndex);
593     dbus_message_iter_open_container(&innerVariantStructIter, DBUS_TYPE_VARIANT, "y", &innerVariantActualIterator);
594
595     //begin inner variant content
596     dbus_message_iter_append_basic(&innerVariantActualIterator, DBUS_TYPE_BYTE, &innerVariant2Value);
597     //end inner variant content
598
599     dbus_message_iter_close_container(&innerVariantStructIter, &innerVariantActualIterator);
600     dbus_message_iter_close_container(&outerVariantActualIter, &innerVariantStructIter);
601     //end inner variant
602
603     dbus_message_iter_close_container(&outerVariantStructIter, &outerVariantActualIter);
604     dbus_message_iter_close_container(&libdbusMessageWriteIter, &outerVariantStructIter);
605     //end 2. outer variant
606
607
608     CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
609     CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
610
611     InnerVariantType referenceInnerVariant1(innerVariant1Value);
612     InnerVariantType referenceInnerVariant2(innerVariant2Value);
613
614     TestedVariantType referenceVariant1(referenceInnerVariant1);
615     TestedVariantType referenceVariant2(referenceInnerVariant2);
616
617     //Variant1: type-index(1) + varSigLen(1) + varSig(2) + struct-padding(4) + inner-type-index(1) + varLen(1) + varSig(3) +
618     //          padding(3) + byteBufferLength(4) + byteBuffer(20) = 40
619     //Variant2: type-index(1) + varSigLen(1) + varSig(2) + struct-padding(4) + inner-type-index(1) + varLen(1) + varSig(2) +
620     //          byte(1) = 13
621     // = 53
622     EXPECT_EQ(53, scopedMessage.getBodyLength());
623
624     TestedVariantType readVariant1;
625     TestedVariantType readVariant2;
626     inStream >> readVariant1;
627     inStream >> readVariant2;
628     EXPECT_EQ(referenceVariant1, readVariant1);
629     EXPECT_EQ(referenceVariant2, readVariant2);
630
631     InnerVariantType readInnerVariant1 = readVariant1.get<InnerVariantType>();
632     InnerVariantType readInnerVariant2 = readVariant2.get<InnerVariantType>();
633     EXPECT_EQ(referenceInnerVariant1, readInnerVariant1);
634     EXPECT_EQ(referenceInnerVariant2, readInnerVariant2);
635
636     CommonAPI::ByteBuffer readInnerValue1 = readInnerVariant1.get<CommonAPI::ByteBuffer>();
637     int8_t readInnerValue2 = readInnerVariant2.get<int8_t>();
638     EXPECT_EQ(innerVariant1Value, readInnerValue1);
639     EXPECT_EQ(innerVariant2Value, readInnerValue2);
640 }
641
642
643 TEST_F(InputStreamTest, ReadsVariantsWithStructs) {
644     typedef CommonAPI::Variant<int32_t,
645                                double,
646                                std::string,
647                                bmw::test::TestSerializableStruct>
648             TestedVariantType;
649
650     int8_t variantTypeIndex = 1;
651
652     bmw::test::TestSerializableStruct testStruct;
653     testStruct.a = 15;
654     testStruct.b = -32;
655     testStruct.c = false;
656     testStruct.d = "Hello all!";
657     testStruct.e = 3.414;
658
659
660     DBusMessageIter variantStructIter;
661     DBusMessageIter variantActualIter;
662     DBusMessageIter innerStructIter;
663
664
665     //begin variant
666     dbus_message_iter_open_container(&libdbusMessageWriteIter, DBUS_TYPE_STRUCT, NULL, &variantStructIter);
667     dbus_message_iter_append_basic(&variantStructIter, DBUS_TYPE_BYTE, &variantTypeIndex);
668     dbus_message_iter_open_container(&variantStructIter, DBUS_TYPE_VARIANT, "(unbsd)", &variantActualIter);
669
670     //begin variant content
671     dbus_message_iter_open_container(&variantActualIter, DBUS_TYPE_STRUCT, NULL, &innerStructIter);
672
673     dbus_bool_t dbusBool = 0;
674     dbus_message_iter_append_basic(&innerStructIter, DBUS_TYPE_UINT32, &testStruct.a);
675     dbus_message_iter_append_basic(&innerStructIter, DBUS_TYPE_INT16, &testStruct.b);
676     dbus_message_iter_append_basic(&innerStructIter, DBUS_TYPE_BOOLEAN, &dbusBool);
677     dbus_message_iter_append_basic(&innerStructIter, DBUS_TYPE_STRING, &testStruct.d);
678     dbus_message_iter_append_basic(&innerStructIter, DBUS_TYPE_DOUBLE, &testStruct.e);
679
680     dbus_message_iter_close_container(&variantActualIter, &innerStructIter);
681     //end variant content
682
683     dbus_message_iter_close_container(&variantStructIter, &variantActualIter);
684     dbus_message_iter_close_container(&libdbusMessageWriteIter, &variantStructIter);
685     //end variant
686
687     CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
688     CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
689     TestedVariantType referenceVariant(testStruct);
690
691     //type-index(1) + varSigLen(1) + varSig(8) + struct-padding(6) + uint32(4) + int16(2) + padding(2) + bool(4) +
692     //stringLen(4) + stringVal(11) + padding(5) + double(8) = 56
693     EXPECT_EQ(56, scopedMessage.getBodyLength());
694
695     TestedVariantType readVariant;
696     inStream >> readVariant;
697
698     bmw::test::TestSerializableStruct readStruct = readVariant.get<bmw::test::TestSerializableStruct>();
699     EXPECT_EQ(testStruct.a, readStruct.a);
700     EXPECT_EQ(testStruct.b, readStruct.b);
701     EXPECT_EQ(testStruct.c, readStruct.c);
702     EXPECT_EQ(testStruct.d, readStruct.d);
703     EXPECT_EQ(testStruct.e, readStruct.e);
704     EXPECT_EQ(testStruct, readStruct);
705     EXPECT_EQ(referenceVariant, readVariant);
706 }
707
708
709 TEST_F(InputStreamTest, ReadsVariantsWithAnArrayOfStructs) {
710     typedef CommonAPI::Variant<int32_t, double, std::vector<bmw::test::TestSerializableStruct>> TestedVariantType;
711
712     bmw::test::TestSerializableStruct testStruct;
713     testStruct.a = 15;
714     testStruct.b = -32;
715     testStruct.c = false;
716     testStruct.d = "Hello all!";
717     testStruct.e = 3.414;
718
719     int8_t variantTypeIndex = 1;
720
721     DBusMessageIter subIter;
722     DBusMessageIter subSubIter;
723     DBusMessageIter innerArrayIter;
724     DBusMessageIter innerStructIter;
725
726     //begin variant
727     dbus_message_iter_open_container(&libdbusMessageWriteIter, DBUS_TYPE_STRUCT, NULL, &subIter);
728     dbus_message_iter_append_basic(&subIter, DBUS_TYPE_BYTE, &variantTypeIndex);
729     dbus_message_iter_open_container(&subIter, DBUS_TYPE_VARIANT, "a(unbsd)", &subSubIter);
730
731     //begin array
732     dbus_message_iter_open_container(&subSubIter, DBUS_TYPE_ARRAY, "(unbsd)", &innerArrayIter);
733
734     //begin struct
735     dbus_message_iter_open_container(&innerArrayIter, DBUS_TYPE_STRUCT, NULL, &innerStructIter);
736
737     dbus_bool_t dbusBool = 0;
738     dbus_message_iter_append_basic(&innerStructIter, DBUS_TYPE_UINT32, &testStruct.a);
739     dbus_message_iter_append_basic(&innerStructIter, DBUS_TYPE_INT16, &testStruct.b);
740     dbus_message_iter_append_basic(&innerStructIter, DBUS_TYPE_BOOLEAN, &dbusBool);
741     dbus_message_iter_append_basic(&innerStructIter, DBUS_TYPE_STRING, &testStruct.d);
742     dbus_message_iter_append_basic(&innerStructIter, DBUS_TYPE_DOUBLE, &testStruct.e);
743
744     dbus_message_iter_close_container(&innerArrayIter, &innerStructIter);
745     //end struct
746
747     dbus_message_iter_close_container(&subSubIter, &innerArrayIter);
748     //end array
749
750     dbus_message_iter_close_container(&subIter, &subSubIter);
751     dbus_message_iter_close_container(&libdbusMessageWriteIter, &subIter);
752     //end variant
753
754     CommonAPI::DBus::DBusMessage scopedMessage(libdbusMessage);
755     CommonAPI::DBus::DBusInputStream inStream(scopedMessage);
756
757     std::vector<bmw::test::TestSerializableStruct> referenceInnerVector;
758     referenceInnerVector.push_back(testStruct);
759     TestedVariantType referenceVariant(referenceInnerVector);
760
761     //type-index(1) + varSigLen(1) + variantSig(9) + padding(1) + arrayLength(4) + uint32(4) + int16(2) + padding(2)
762     //bool(4) + stringLength(4) + string(11) + padding(5) + double(8) = 56
763     EXPECT_EQ(56, scopedMessage.getBodyLength());
764
765     TestedVariantType readVariant;
766     inStream >> readVariant;
767
768     std::vector<bmw::test::TestSerializableStruct> actualResult = readVariant.get<std::vector<bmw::test::TestSerializableStruct>>();
769     bmw::test::TestSerializableStruct readStruct = actualResult[0];
770
771     EXPECT_EQ(testStruct.a, readStruct.a);
772     EXPECT_EQ(testStruct.b, readStruct.b);
773     EXPECT_EQ(testStruct.c, readStruct.c);
774     EXPECT_EQ(testStruct.d, readStruct.d);
775     EXPECT_EQ(testStruct.e, readStruct.e);
776     EXPECT_EQ(testStruct, readStruct);
777     EXPECT_EQ(referenceInnerVector, actualResult);
778     EXPECT_EQ(referenceVariant, readVariant);
779 }
780
781
782 int main(int argc, char** argv) {
783         ::testing::InitGoogleTest(&argc, argv);
784         return RUN_ALL_TESTS();
785 }