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