]> granicus.if.org Git - icinga2/blob - test/base-object-packer.cpp
Test PackObject
[icinga2] / test / base-object-packer.cpp
1 /******************************************************************************
2  * Icinga 2                                                                   *
3  * Copyright (C) 2012-2018 Icinga Development Team (https://www.icinga.com/)  *
4  *                                                                            *
5  * This program is free software; you can redistribute it and/or              *
6  * modify it under the terms of the GNU General Public License                *
7  * as published by the Free Software Foundation; either version 2             *
8  * of the License, or (at your option) any later version.                     *
9  *                                                                            *
10  * This program is distributed in the hope that it will be useful,            *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
13  * GNU General Public License for more details.                               *
14  *                                                                            *
15  * You should have received a copy of the GNU General Public License          *
16  * along with this program; if not, write to the Free Software Foundation     *
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.             *
18  ******************************************************************************/
19
20 #include "base/object-packer.hpp"
21 #include "base/value.hpp"
22 #include "base/string.hpp"
23 #include "base/array.hpp"
24 #include "base/dictionary.hpp"
25 #include <BoostTestTargetConfig.h>
26 #include <climits>
27 #include <initializer_list>
28 #include <iomanip>
29 #include <strstream>
30
31 using namespace icinga;
32
33 #if CHAR_MIN != 0
34 union CharU2SConverter
35 {
36         CharU2SConverter()
37         {
38                 s = 0;
39         }
40
41         unsigned char u;
42         signed char s;
43 };
44 #endif
45
46 /**
47  * Avoid implementation-defined overflows during unsigned to signed casts
48  */
49 static inline char UIntToByte(unsigned i)
50 {
51 #if CHAR_MIN == 0
52         return i;
53 #else
54         CharU2SConverter converter;
55
56         converter.u = i;
57         return converter.s;
58 #endif
59 }
60
61 #if CHAR_MIN != 0
62 union CharS2UConverter
63 {
64         CharS2UConverter()
65         {
66                 u = 0;
67         }
68
69         unsigned char u;
70         signed char s;
71 };
72 #endif
73
74 /**
75  * Avoid implementation-defined underflows during signed to unsigned casts
76  */
77 static inline unsigned ByteToUInt(char c)
78 {
79 #if CHAR_MIN == 0
80         return c;
81 #else
82         CharS2UConverter converter;
83
84         converter.s = c;
85         return converter.u;
86 #endif
87 }
88
89 /**
90  * Compare the expected output with the actual output
91  */
92 static inline bool ComparePackObjectResult(const String& actualOutput, const std::initializer_list<int>& out)
93 {
94         if (actualOutput.GetLength() != out.size())
95                 return false;
96
97         auto actualOutputPos = actualOutput.Begin();
98         for (auto byte : out) {
99                 if (*actualOutputPos != UIntToByte(byte))
100                         return false;
101
102                 ++actualOutputPos;
103         }
104
105         return true;
106 }
107
108 /**
109  * Pack the given input and compare with the expected output
110  */
111 static inline bool AssertPackObjectResult(Value in, std::initializer_list<int> out)
112 {
113         auto actualOutput = PackObject(in);
114         bool equal = ComparePackObjectResult(actualOutput, out);
115
116         if (!equal) {
117                 std::ostringstream buf;
118                 buf << std::setw(2) << std::setfill('0') << std::setbase(16);
119
120                 buf << "--- ";
121                 for (int c : out) {
122                         buf << c;
123                 }
124                 buf << std::endl;
125
126                 buf << "+++ ";
127                 for (char c : actualOutput) {
128                         buf << ByteToUInt(c);
129                 }
130                 buf << std::endl;
131
132                 BOOST_TEST_MESSAGE(buf.str());
133         }
134
135         return equal;
136 }
137
138 BOOST_AUTO_TEST_SUITE(object_packer)
139
140 BOOST_AUTO_TEST_CASE(pack_null)
141 {
142         BOOST_CHECK(AssertPackObjectResult(Empty, {0}));
143 }
144
145 BOOST_AUTO_TEST_CASE(pack_false)
146 {
147         BOOST_CHECK(AssertPackObjectResult(false, {1}));
148 }
149
150 BOOST_AUTO_TEST_CASE(pack_true)
151 {
152         BOOST_CHECK(AssertPackObjectResult(true, {2}));
153 }
154
155 BOOST_AUTO_TEST_CASE(pack_number)
156 {
157         BOOST_CHECK(AssertPackObjectResult(42.125, {
158                 // type
159                 3,
160                 // IEEE 754
161                 64, 69, 16, 0, 0, 0, 0, 0
162         }));
163 }
164
165 BOOST_AUTO_TEST_CASE(pack_string)
166 {
167         BOOST_CHECK(AssertPackObjectResult(
168                 String(
169                         // ASCII (1 to 127)
170                         "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
171                         "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
172                         "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
173                         "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
174                         "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
175                         "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
176                         "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
177                         "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
178                         // some keyboard-independent non-ASCII unicode characters
179                         "áéíóú"
180                 ),
181                 {
182                         // type
183                         4,
184                         // length
185                         0, 0, 0, 0, 0, 0, 0, 137,
186                         // ASCII
187                         1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
188                         16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
189                         32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
190                         48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
191                         64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
192                         80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
193                         96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
194                         112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
195                         // UTF-8
196                         195, 161, 195, 169, 195, 173, 195, 179, 195, 186
197                 }
198         ));
199 }
200
201 BOOST_AUTO_TEST_CASE(pack_array)
202 {
203         BOOST_CHECK(AssertPackObjectResult(
204                 (Array::Ptr)new Array({Empty, false, true, 42.125, "foobar"}),
205                 {
206                         // type
207                         5,
208                         // length
209                         0, 0, 0, 0, 0, 0, 0, 5,
210                         // Empty
211                         0,
212                         // false
213                         1,
214                         // true
215                         2,
216                         // 42.125
217                         3,
218                         64, 69, 16, 0, 0, 0, 0, 0,
219                         // "foobar"
220                         4,
221                         0, 0, 0, 0, 0, 0, 0, 6,
222                         102, 111, 111, 98, 97, 114
223                 }
224         ));
225 }
226
227 BOOST_AUTO_TEST_CASE(pack_object)
228 {
229         BOOST_CHECK(AssertPackObjectResult(
230                 (Dictionary::Ptr)new Dictionary({
231                         {"null", Empty},
232                         {"false", false},
233                         {"true", true},
234                         {"42.125", 42.125},
235                         {"foobar", "foobar"},
236                         {"[]", (Array::Ptr)new Array()}
237                 }),
238                 {
239                         // type
240                         6,
241                         // length
242                         0, 0, 0, 0, 0, 0, 0, 6,
243                         // "42.125"
244                         0, 0, 0, 0, 0, 0, 0, 6,
245                         52, 50, 46, 49, 50, 53,
246                         // 42.125
247                         3,
248                         64, 69, 16, 0, 0, 0, 0, 0,
249                         // "[]"
250                         0, 0, 0, 0, 0, 0, 0, 2,
251                         91, 93,
252                         // (Array::Ptr)new Array()
253                         5,
254                         0, 0, 0, 0, 0, 0, 0, 0,
255                         // "false"
256                         0, 0, 0, 0, 0, 0, 0, 5,
257                         102, 97, 108, 115, 101,
258                         // false
259                         1,
260                         // "foobar"
261                         0, 0, 0, 0, 0, 0, 0, 6,
262                         102, 111, 111, 98, 97, 114,
263                         // "foobar"
264                         4,
265                         0, 0, 0, 0, 0, 0, 0, 6,
266                         102, 111, 111, 98, 97, 114,
267                         // "null"
268                         0, 0, 0, 0, 0, 0, 0, 4,
269                         110, 117, 108, 108,
270                         // Empty
271                         0,
272                         // "true"
273                         0, 0, 0, 0, 0, 0, 0, 4,
274                         116, 114, 117, 101,
275                         // true
276                         2
277                 }
278         ));
279 }
280
281 BOOST_AUTO_TEST_SUITE_END()