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