tests: fix blocking semantic in DBusProxyTest
[profile/ivi/common-api-dbus-runtime.git] / src / test / DBusBenchmarkingTest.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/DBus/DBusInputStream.h>
9 #include <CommonAPI/DBus/DBusOutputStream.h>
10
11 #include <unordered_map>
12 #include <bits/functional_hash.h>
13
14 #include <gtest/gtest.h>
15
16 #include <dbus/dbus.h>
17
18 #include <chrono>
19 #include <cstdint>
20 #include <vector>
21 #include <unordered_map>
22 #include <bits/functional_hash.h>
23
24
25 class BenchmarkingTest: public ::testing::Test {
26   protected:
27     DBusMessage* libdbusMessage;
28     DBusMessageIter libdbusMessageWriteIter;
29     size_t numOfElements;
30
31     void SetUp() {
32         numOfElements = 2;
33         libdbusMessage = dbus_message_new_method_call("no.bus.here", "/no/object/here", NULL, "noMethodHere");
34         ASSERT_TRUE(libdbusMessage != NULL);
35         dbus_message_iter_init_append(libdbusMessage, &libdbusMessageWriteIter);
36     }
37
38     void TearDown() {
39         dbus_message_unref(libdbusMessage);
40     }
41 };
42
43 template <typename _ArrayElementLibdbusType, typename _ArrayElementCommonApiType>
44 void prepareLibdbusArray(DBusMessage* libdbusMessage,
45                          const int arrayElementLibdbusType,
46                          const char* arrayElementLibdbusTypeAsString,
47                          const _ArrayElementLibdbusType& arrayInitElementValue,
48                          const uint32_t arrayInitTime,
49                          size_t& libdbusInitElementCount) {
50
51     DBusMessageIter libdbusMessageIter;
52     DBusMessageIter libdbusMessageContainerIter;
53
54     dbus_message_iter_init_append(libdbusMessage, &libdbusMessageIter);
55
56     dbus_bool_t libdbusSuccess = dbus_message_iter_open_container(&libdbusMessageIter,
57                                                                   DBUS_TYPE_ARRAY,
58                                                                   arrayElementLibdbusTypeAsString,
59                                                                   &libdbusMessageContainerIter);
60     ASSERT_TRUE(libdbusSuccess);
61
62
63     std::chrono::milliseconds libdbusInitTime;
64     std::chrono::time_point<std::chrono::high_resolution_clock> clockStart = std::chrono::high_resolution_clock::now();
65
66     do {
67         for (int i = 0; i < 1000; i++)
68             dbus_message_iter_append_basic(&libdbusMessageContainerIter,
69                                            arrayElementLibdbusType,
70                                            &arrayInitElementValue);
71
72         libdbusInitElementCount += 1000;
73
74         libdbusInitTime = std::chrono::duration_cast<std::chrono::milliseconds>(
75                 std::chrono::high_resolution_clock::now() - clockStart);
76     } while (libdbusInitTime.count() < arrayInitTime);
77
78     libdbusSuccess = dbus_message_iter_close_container(&libdbusMessageIter, &libdbusMessageContainerIter);
79     ASSERT_TRUE(libdbusSuccess);
80
81     std::cout << "LibdbusInitTime = " << libdbusInitTime.count() << std::endl;
82     std::cout << "LibdbusInitElementCount = " << libdbusInitElementCount << std::endl;
83 }
84
85
86 template <typename _ArrayElementLibdbusType, typename _ArrayElementCommonApiType>
87 void measureLibdbusArrayReadTime(DBusMessage* libdbusMessage,
88                                  size_t& libdbusInitElementCount,
89                                  std::chrono::milliseconds& libdbusArrayReadTime) {
90
91     DBusMessageIter libdbusMessageIter;
92     DBusMessageIter libdbusMessageContainerIter;
93
94     dbus_bool_t libdbusSuccess;
95
96     libdbusSuccess = dbus_message_iter_init(libdbusMessage, &libdbusMessageIter);
97     ASSERT_TRUE(libdbusSuccess);
98
99     dbus_message_iter_recurse(&libdbusMessageIter, &libdbusMessageContainerIter);
100
101     size_t libdbusReadElementCount = 0;
102     std::chrono::time_point<std::chrono::high_resolution_clock> clockStart = std::chrono::high_resolution_clock::now();
103
104     do {
105         _ArrayElementLibdbusType libdbusValue;
106
107         dbus_message_iter_get_basic(&libdbusMessageContainerIter, &libdbusValue);
108
109         ++libdbusReadElementCount;
110     } while (dbus_message_iter_next(&libdbusMessageContainerIter));
111
112     libdbusArrayReadTime = std::chrono::duration_cast<std::chrono::milliseconds>(
113             std::chrono::high_resolution_clock::now() - clockStart);
114
115     ASSERT_EQ(libdbusInitElementCount, libdbusReadElementCount);
116 }
117
118
119 template <typename _ArrayElementLibdbusType, typename _ArrayElementCommonApiType>
120 void measureCommonApiArrayReadTime(DBusMessage* libdbusMessage,
121                                    std::chrono::milliseconds& commonArrayApiReadTime,
122                                    size_t& libdbusInitElementCount) {
123
124     CommonAPI::DBus::DBusMessage dbusMessage(libdbusMessage);
125     CommonAPI::DBus::DBusInputStream DBusInputStream(dbusMessage);
126     std::vector<_ArrayElementCommonApiType> commonApiVector;
127
128     std::chrono::time_point<std::chrono::high_resolution_clock> clockStart = std::chrono::high_resolution_clock::now();
129
130     DBusInputStream >> commonApiVector;
131
132     commonArrayApiReadTime = std::chrono::duration_cast<std::chrono::milliseconds>(
133             std::chrono::high_resolution_clock::now() - clockStart);
134
135     ASSERT_EQ(libdbusInitElementCount, commonApiVector.size());
136 }
137
138
139 template <typename _ArrayElementLibdbusType, typename _ArrayElementCommonApiType>
140 void measureArrayReadTime(
141                 const int arrayElementLibdbusType,
142                 const char* arrayElementLibdbusTypeAsString,
143                 const _ArrayElementLibdbusType arrayInitElementValue,
144                 const uint32_t arrayInitTime,
145                 std::chrono::milliseconds& libdbusArrayReadTime,
146                 std::chrono::milliseconds& commonArrayApiReadTime) {
147
148         DBusMessage* libdbusMessage;
149     dbus_bool_t libdbusSuccess;
150     size_t libdbusInitElementCount = 0;
151
152     libdbusMessage = dbus_message_new_method_call("no.bus.here", "/no/object/here", NULL, "noMethodHere");
153     ASSERT_TRUE(libdbusMessage != NULL);
154
155     prepareLibdbusArray<_ArrayElementLibdbusType, _ArrayElementCommonApiType>(
156                                 libdbusMessage,
157                                 arrayElementLibdbusType,
158                                 arrayElementLibdbusTypeAsString,
159                                 arrayInitElementValue,
160                                 arrayInitTime,
161                                 libdbusInitElementCount);
162
163     measureLibdbusArrayReadTime<_ArrayElementLibdbusType, _ArrayElementCommonApiType>(
164                                 libdbusMessage,
165                                 libdbusInitElementCount,
166                                 libdbusArrayReadTime);
167
168     measureCommonApiArrayReadTime<_ArrayElementLibdbusType, _ArrayElementCommonApiType>(
169                                 libdbusMessage,
170                                 commonArrayApiReadTime,
171                                 libdbusInitElementCount);
172 }
173
174
175 TEST_F(BenchmarkingTest, InputStreamReadsIntegerArrayFasterThanLibdbus) {
176         std::chrono::milliseconds libdbusArrayReadTime;
177         std::chrono::milliseconds commonApiArrayReadTime;
178
179         measureArrayReadTime<int32_t, int32_t>(DBUS_TYPE_INT32,
180                                                                                    DBUS_TYPE_INT32_AS_STRING,
181                                                                                    1234567890,
182                                                                                    1000,
183                                                                                    libdbusArrayReadTime,
184                                                                                    commonApiArrayReadTime);
185
186         RecordProperty("LibdbusArrayReadTime", libdbusArrayReadTime.count());
187         RecordProperty("CommonApiArrayReadTime", commonApiArrayReadTime.count());
188
189         std::cout << "LibdbusArrayReadTime = " << libdbusArrayReadTime.count() << std::endl;
190         std::cout << "CommonApiArrayReadTime = " << commonApiArrayReadTime.count() << std::endl;
191
192     ASSERT_LT(commonApiArrayReadTime.count(), libdbusArrayReadTime.count() * 0.30)
193         << "CommonAPI::DBus::DBusInputStream must be at least 70% faster than libdbus!";
194 }
195
196 TEST_F(BenchmarkingTest, InputStreamReadsStringArrayFasterThanLibdbus) {
197         std::chrono::milliseconds libdbusArrayReadTime;
198         std::chrono::milliseconds commonApiArrayReadTime;
199
200         measureArrayReadTime<char*, std::string>(DBUS_TYPE_STRING,
201                                                                                          DBUS_TYPE_STRING_AS_STRING,
202                                                                                          const_cast<char*>("01234567890123456789"),
203                                                                                          1000,
204                                                                                          libdbusArrayReadTime,
205                                                                                          commonApiArrayReadTime);
206
207         RecordProperty("LibdbusArrayReadTime", libdbusArrayReadTime.count());
208         RecordProperty("CommonApiArrayReadTime", commonApiArrayReadTime.count());
209
210         std::cout << "LibdbusArrayReadTime = " << libdbusArrayReadTime.count() << std::endl;
211         std::cout << "CommonApiArrayReadTime = " << commonApiArrayReadTime.count() << std::endl;
212
213     ASSERT_LT(commonApiArrayReadTime.count(), libdbusArrayReadTime.count() * 0.30)
214         << "CommonAPI::DBus::DBusInputStream must be at least 70% faster than libdbus!";
215 }
216
217 int main(int argc, char** argv) {
218         ::testing::InitGoogleTest(&argc, argv);
219         return RUN_ALL_TESTS();
220 }