767f17996bf84ad9f73f9554215f587ccb7df7ec
[strongswan.git] / src / libstrongswan / tests / test_bio_writer.c
1 /*
2 * Copyright (C) 2013 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "test_suite.h"
17
18 #include <bio/bio_writer.h>
19
20 /*******************************************************************************
21 * different integer writes
22 */
23
24 static inline void verify_int_buffer(chunk_t data, int bits, int val)
25 {
26 size_t i;
27 int len = bits / 8;
28
29 ck_assert_int_eq(data.len, (val + 1) * len);
30 for (i = 0; i < data.len; i++)
31 {
32 (i + 1) % len ? ck_assert_int_eq(data.ptr[i], 0)
33 : ck_assert_int_eq(data.ptr[i], i / len);
34 }
35 }
36
37 #define assert_integer_write(init, bits) ({ \
38 int i; \
39 bio_writer_t *writer = bio_writer_create(init); \
40 for (i = 0; i < 16; i++) \
41 { \
42 writer->write_uint##bits(writer, i); \
43 verify_int_buffer(writer->get_buf(writer), bits, i); \
44 } \
45 writer->destroy(writer); \
46 })
47
48 START_TEST(test_write_uint8)
49 {
50 /* use default buffer (and increase) size */
51 assert_integer_write(0, 8);
52 /* force a resize by the given size */
53 assert_integer_write(1, 8);
54 }
55 END_TEST
56
57 START_TEST(test_write_uint16)
58 {
59 assert_integer_write(0, 16);
60 assert_integer_write(1, 16);
61 }
62 END_TEST
63
64 START_TEST(test_write_uint24)
65 {
66 assert_integer_write(0, 24);
67 assert_integer_write(1, 24);
68 }
69 END_TEST
70
71 START_TEST(test_write_uint32)
72 {
73 assert_integer_write(0, 32);
74 assert_integer_write(1, 32);
75 }
76 END_TEST
77
78 START_TEST(test_write_uint64)
79 {
80 assert_integer_write(0, 64);
81 assert_integer_write(1, 64);
82 }
83 END_TEST
84
85 /*******************************************************************************
86 * write data / skip
87 */
88
89 static inline void assert_writer_after_write(bio_writer_t *writer, int count)
90 {
91 chunk_t buf;
92 size_t i;
93
94 buf = writer->get_buf(writer);
95 ck_assert_int_eq(buf.len, count * 3);
96 for (i = 0; i < buf.len; i++)
97 {
98 ck_assert(buf.ptr[i] == i % 3);
99 }
100 }
101
102 START_TEST(test_write_data)
103 {
104 chunk_t buf, data = chunk_from_chars(0x00, 0x01, 0x02);
105 bio_writer_t *writer;
106
107 /* no allocation, but default buffer size */
108 writer = bio_writer_create(0);
109 buf = writer->get_buf(writer);
110 ck_assert_int_eq(buf.len, 0);
111 ck_assert(buf.ptr == NULL);
112
113 writer->write_data(writer, chunk_empty);
114 buf = writer->get_buf(writer);
115 ck_assert_int_eq(buf.len, 0);
116 ck_assert(buf.ptr == NULL);
117 writer->destroy(writer);
118
119 /* custom buffer size, initial buffer allocated */
120 writer = bio_writer_create(1);
121 buf = writer->get_buf(writer);
122 ck_assert_int_eq(buf.len, 0);
123 ck_assert(buf.ptr != NULL);
124
125 writer->write_data(writer, chunk_empty);
126 buf = writer->get_buf(writer);
127 ck_assert_int_eq(buf.len, 0);
128 ck_assert(buf.ptr != NULL);
129 writer->destroy(writer);
130
131 writer = bio_writer_create(0);
132
133 writer->write_data(writer, data);
134 assert_writer_after_write(writer, 1);
135
136 writer->write_data(writer, data);
137 assert_writer_after_write(writer, 2);
138
139 writer->write_data(writer, data);
140 assert_writer_after_write(writer, 3);
141
142 writer->destroy(writer);
143 }
144 END_TEST
145
146 START_TEST(test_skip)
147 {
148 chunk_t skipped, buf, data = chunk_from_chars(0x00, 0x01, 0x02);
149 bio_writer_t *writer;
150
151 writer = bio_writer_create(4);
152 skipped = writer->skip(writer, 3);
153 ck_assert_int_eq(skipped.len, 3);
154 buf = writer->get_buf(writer);
155 ck_assert(skipped.ptr == buf.ptr);
156 memset(skipped.ptr, 0, skipped.len);
157
158 writer->write_data(writer, data);
159 buf = writer->get_buf(writer);
160 ck_assert(chunk_equals(buf, chunk_from_chars(0x00, 0x00, 0x00, 0x00, 0x01, 0x02)));
161 writer->destroy(writer);
162
163 writer = bio_writer_create(1);
164 skipped = writer->skip(writer, 3);
165 memcpy(skipped.ptr, data.ptr, data.len);
166
167 writer->write_data(writer, data);
168 assert_writer_after_write(writer, 2);
169 writer->destroy(writer);
170 }
171 END_TEST
172
173 /*******************************************************************************
174 * write length followed by data
175 */
176
177 #define assert_write_data_len(init, bits) ({ \
178 bio_writer_t *writer; \
179 chunk_t buf, data; \
180 int i, len = bits / 8; \
181 writer = bio_writer_create(init); \
182 writer->write_data##bits(writer, chunk_empty); \
183 buf = writer->get_buf(writer); \
184 ck_assert_int_eq(buf.len, len); \
185 ck_assert_int_eq(buf.ptr[len - 1], 0); \
186 writer->destroy(writer); \
187 data = chunk_alloca(32); \
188 memset(data.ptr, 0, data.len); \
189 for (i = 0; i < 32; i++) \
190 { \
191 data.ptr[i] = i; \
192 data.len = i; \
193 writer = bio_writer_create(init); \
194 writer->write_data##bits(writer, data); \
195 buf = writer->get_buf(writer); \
196 ck_assert_int_eq(buf.len, len + i); \
197 ck_assert_int_eq(buf.ptr[len - 1], i); \
198 ck_assert(chunk_equals(chunk_create(buf.ptr + len, buf.len - len), data)); \
199 writer->destroy(writer); \
200 } \
201 })
202
203 START_TEST(test_write_data8)
204 {
205 assert_write_data_len(0, 8);
206 assert_write_data_len(1, 8);
207 }
208 END_TEST
209
210 START_TEST(test_write_data16)
211 {
212 assert_write_data_len(0, 16);
213 assert_write_data_len(1, 16);
214 }
215 END_TEST
216
217 START_TEST(test_write_data24)
218 {
219 assert_write_data_len(0, 24);
220 assert_write_data_len(1, 24);
221 }
222 END_TEST
223
224 START_TEST(test_write_data32)
225 {
226 assert_write_data_len(0, 32);
227 assert_write_data_len(1, 32);
228 }
229 END_TEST
230
231
232 /*******************************************************************************
233 * add length header before current data
234 */
235
236 #define assert_wrap_data(init, bits) ({ \
237 bio_writer_t *writer; \
238 chunk_t buf, data; \
239 int i, len = bits / 8; \
240 writer = bio_writer_create(init); \
241 writer->wrap##bits(writer); \
242 buf = writer->get_buf(writer); \
243 ck_assert_int_eq(buf.len, len); \
244 ck_assert_int_eq(buf.ptr[len - 1], 0); \
245 writer->destroy(writer); \
246 data = chunk_alloca(32); \
247 memset(data.ptr, 0, data.len); \
248 for (i = 0; i < 32; i++) \
249 { \
250 data.ptr[i] = i; \
251 data.len = i; \
252 writer = bio_writer_create(init); \
253 writer->write_data(writer, data); \
254 writer->wrap##bits(writer); \
255 buf = writer->get_buf(writer); \
256 ck_assert_int_eq(buf.len, len + i); \
257 ck_assert_int_eq(buf.ptr[len - 1], i); \
258 ck_assert(chunk_equals(chunk_create(buf.ptr + len, buf.len - len), data)); \
259 writer->wrap##bits(writer); \
260 buf = writer->get_buf(writer); \
261 ck_assert_int_eq(buf.len, 2 * len + i); \
262 ck_assert_int_eq(buf.ptr[len - 1], len + i); \
263 ck_assert(chunk_equals(chunk_create(buf.ptr + 2 * len, buf.len - 2 * len), data)); \
264 writer->destroy(writer); \
265 } \
266 })
267
268 START_TEST(test_wrap8)
269 {
270 assert_wrap_data(0, 8);
271 assert_wrap_data(1, 8);
272 }
273 END_TEST
274
275 START_TEST(test_wrap16)
276 {
277 assert_wrap_data(0, 16);
278 assert_wrap_data(1, 16);
279 }
280 END_TEST
281
282 START_TEST(test_wrap24)
283 {
284 assert_wrap_data(0, 24);
285 assert_wrap_data(1, 24);
286 }
287 END_TEST
288
289 START_TEST(test_wrap32)
290 {
291 assert_wrap_data(0, 32);
292 assert_wrap_data(1, 32);
293 }
294 END_TEST
295
296 /*******************************************************************************
297 * test data extraction
298 */
299
300 START_TEST(test_get_buf)
301 {
302 bio_writer_t *writer;
303 chunk_t data1, data2;
304
305 writer = bio_writer_create(0);
306 writer->write_uint8(writer, 1);
307 data1 = writer->get_buf(writer);
308 ck_assert_int_eq(data1.len, 1);
309 ck_assert(data1.ptr[0] == 1);
310
311 data2 = writer->get_buf(writer);
312 ck_assert(chunk_equals(data1, data2));
313 ck_assert(data1.ptr == data2.ptr);
314 writer->destroy(writer);
315 }
316 END_TEST
317
318 START_TEST(test_extract_buf)
319 {
320 bio_writer_t *writer;
321 chunk_t data1, data2;
322
323 writer = bio_writer_create(0);
324 writer->write_uint8(writer, 1);
325 data1 = writer->extract_buf(writer);
326 ck_assert_int_eq(data1.len, 1);
327 ck_assert(data1.ptr[0] == 1);
328
329 data2 = writer->get_buf(writer);
330 ck_assert_int_eq(data2.len, 0);
331 ck_assert(data2.ptr == NULL);
332 data2 = writer->extract_buf(writer);
333 ck_assert_int_eq(data2.len, 0);
334 ck_assert(data2.ptr == NULL);
335
336 writer->write_uint8(writer, 1);
337 data2 = writer->get_buf(writer);
338 ck_assert(chunk_equals(data1, data2));
339 ck_assert(data1.ptr != data2.ptr);
340
341 writer->destroy(writer);
342 chunk_free(&data1);
343 }
344 END_TEST
345
346 Suite *bio_writer_suite_create()
347 {
348 Suite *s;
349 TCase *tc;
350
351 s = suite_create("bio_writer");
352
353 tc = tcase_create("integer writes");
354 tcase_add_test(tc, test_write_uint8);
355 tcase_add_test(tc, test_write_uint16);
356 tcase_add_test(tc, test_write_uint24);
357 tcase_add_test(tc, test_write_uint32);
358 tcase_add_test(tc, test_write_uint64);
359 suite_add_tcase(s, tc);
360
361 tc = tcase_create("data writes/skip");
362 tcase_add_test(tc, test_write_data);
363 tcase_add_test(tc, test_skip);
364 suite_add_tcase(s, tc);
365
366 tc = tcase_create("data length writes");
367 tcase_add_test(tc, test_write_data8);
368 tcase_add_test(tc, test_write_data16);
369 tcase_add_test(tc, test_write_data24);
370 tcase_add_test(tc, test_write_data32);
371 suite_add_tcase(s, tc);
372
373 tc = tcase_create("wrap writes");
374 tcase_add_test(tc, test_wrap8);
375 tcase_add_test(tc, test_wrap16);
376 tcase_add_test(tc, test_wrap24);
377 tcase_add_test(tc, test_wrap32);
378 suite_add_tcase(s, tc);
379
380 tc = tcase_create("get/extract");
381 tcase_add_test(tc, test_get_buf);
382 tcase_add_test(tc, test_extract_buf);
383 suite_add_tcase(s, tc);
384
385 return s;
386 }