1 /* $NetBSD: test_alloc.c,v 1.1.1.3 2014/07/12 11:57:48 spz Exp $ */
2 /*
3 * Copyright (c) 2007,2009,2012 by Internet Systems Consortium, Inc. ("ISC")
4 *
5 * We test the functions provided in alloc.c here. These are very
6 * basic functions, and it is very important that they work correctly.
7 *
8 * You can see two different styles of testing:
9 *
10 * - In the first, we have a single test for each function that tests
11 * all of the possible ways it can operate. (This is the case for
12 * the buffer tests.)
13 *
14 * - In the second, we have a separate test for each of the ways a
15 * function can operate. (This is the case for the data_string
16 * tests.)
17 *
18 * The advantage of a single test per function is that you have fewer
19 * tests, and less duplicated and extra code. The advantage of having
20 * a separate test is that each test is simpler. Plus if you need to
21 * allow certain tests to fail for some reason (known bugs that are
22 * hard to fix for example), then
23 */
24
25 /** @TODO: dmalloc() test */
26
27 #include "config.h"
28 #include <atf-c.h>
29 #include "dhcpd.h"
30
31 ATF_TC(buffer_allocate);
32
ATF_TC_HEAD(buffer_allocate,tc)33 ATF_TC_HEAD(buffer_allocate, tc) {
34 atf_tc_set_md_var(tc, "descr", "buffer_allocate basic test");
35 }
36
ATF_TC_BODY(buffer_allocate,tc)37 ATF_TC_BODY(buffer_allocate, tc) {
38 struct buffer *buf = 0;
39
40 /*
41 * Check a 0-length buffer.
42 */
43 buf = NULL;
44 if (!buffer_allocate(&buf, 0, MDL)) {
45 atf_tc_fail("failed on 0-len buffer");
46 }
47 if (!buffer_dereference(&buf, MDL)) {
48 atf_tc_fail("buffer_dereference() failed");
49 }
50 if (buf != NULL) {
51 atf_tc_fail("buffer_dereference() did not NULL-out buffer");
52 }
53
54 /*
55 * Check an actual buffer.
56 */
57 buf = NULL;
58 if (!buffer_allocate(&buf, 100, MDL)) {
59 atf_tc_fail("failed on allocate 100 bytes\n");
60 }
61 if (!buffer_dereference(&buf, MDL)) {
62 atf_tc_fail("buffer_dereference() failed");
63 }
64 if (buf != NULL) {
65 atf_tc_fail("buffer_dereference() did not NULL-out buffer");
66 }
67
68 /*
69 * Okay, we're happy.
70 */
71 atf_tc_pass();
72 }
73
74 ATF_TC(buffer_reference);
75
ATF_TC_HEAD(buffer_reference,tc)76 ATF_TC_HEAD(buffer_reference, tc) {
77 atf_tc_set_md_var(tc, "descr", "buffer_reference basic test");
78 }
79
ATF_TC_BODY(buffer_reference,tc)80 ATF_TC_BODY(buffer_reference, tc) {
81
82 struct buffer *a, *b;
83
84 /*
85 * Create a buffer.
86 */
87 a = NULL;
88 if (!buffer_allocate(&a, 100, MDL)) {
89 atf_tc_fail("failed on allocate 100 bytes");
90 }
91
92 /**
93 * Confirm buffer_reference() doesn't work if we pass in NULL.
94 *
95 * @TODO: we should confirm we get an error message here.
96 */
97 if (buffer_reference(NULL, a, MDL)) {
98 atf_tc_fail("succeeded on an error input");
99 }
100
101 /**
102 * @TODO: we should confirm we get an error message if we pass
103 * a non-NULL target.
104 */
105
106 /*
107 * Confirm we work under normal circumstances.
108 */
109 b = NULL;
110 if (!buffer_reference(&b, a, MDL)) {
111 atf_tc_fail("buffer_reference() failed");
112 }
113
114 if (b != a) {
115 atf_tc_fail("incorrect pointer returned");
116 }
117
118 if (b->refcnt != 2) {
119 atf_tc_fail("incorrect refcnt");
120 }
121
122 /*
123 * Clean up.
124 */
125 if (!buffer_dereference(&b, MDL)) {
126 atf_tc_fail("buffer_dereference() failed");
127 }
128 if (!buffer_dereference(&a, MDL)) {
129 atf_tc_fail("buffer_dereference() failed");
130 }
131
132 }
133
134
135 ATF_TC(buffer_dereference);
136
ATF_TC_HEAD(buffer_dereference,tc)137 ATF_TC_HEAD(buffer_dereference, tc) {
138 atf_tc_set_md_var(tc, "descr", "buffer_dereference basic test");
139 }
140
ATF_TC_BODY(buffer_dereference,tc)141 ATF_TC_BODY(buffer_dereference, tc) {
142 struct buffer *a, *b;
143
144 /**
145 * Confirm buffer_dereference() doesn't work if we pass in NULL.
146 *
147 * TODO: we should confirm we get an error message here.
148 */
149 if (buffer_dereference(NULL, MDL)) {
150 atf_tc_fail("succeeded on an error input");
151 }
152
153 /**
154 * Confirm buffer_dereference() doesn't work if we pass in
155 * a pointer to NULL.
156 *
157 * @TODO: we should confirm we get an error message here.
158 */
159 a = NULL;
160 if (buffer_dereference(&a, MDL)) {
161 atf_tc_fail("succeeded on an error input");
162 }
163
164 /*
165 * Confirm we work under normal circumstances.
166 */
167 a = NULL;
168 if (!buffer_allocate(&a, 100, MDL)) {
169 atf_tc_fail("failed on allocate");
170 }
171 if (!buffer_dereference(&a, MDL)) {
172 atf_tc_fail("buffer_dereference() failed");
173 }
174 if (a != NULL) {
175 atf_tc_fail("non-null buffer after buffer_dereference()");
176 }
177
178 /**
179 * Confirm we get an error from negative refcnt.
180 *
181 * @TODO: we should confirm we get an error message here.
182 */
183 a = NULL;
184 if (!buffer_allocate(&a, 100, MDL)) {
185 atf_tc_fail("failed on allocate");
186 }
187 b = NULL;
188 if (!buffer_reference(&b, a, MDL)) {
189 atf_tc_fail("buffer_reference() failed");
190 }
191 a->refcnt = 0; /* purposely set to invalid value */
192 if (buffer_dereference(&a, MDL)) {
193 atf_tc_fail("buffer_dereference() succeeded on error input");
194 }
195 a->refcnt = 2;
196 if (!buffer_dereference(&b, MDL)) {
197 atf_tc_fail("buffer_dereference() failed");
198 }
199 if (!buffer_dereference(&a, MDL)) {
200 atf_tc_fail("buffer_dereference() failed");
201 }
202 }
203
204 ATF_TC(data_string_forget);
205
ATF_TC_HEAD(data_string_forget,tc)206 ATF_TC_HEAD(data_string_forget, tc) {
207 atf_tc_set_md_var(tc, "descr", "data_string_forget basic test");
208 }
209
ATF_TC_BODY(data_string_forget,tc)210 ATF_TC_BODY(data_string_forget, tc) {
211 struct buffer *buf;
212 struct data_string a;
213 const char *str = "Lorem ipsum dolor sit amet turpis duis.";
214
215 /*
216 * Create the string we want to forget.
217 */
218 memset(&a, 0, sizeof(a));
219 a.len = strlen(str);
220 buf = NULL;
221 if (!buffer_allocate(&buf, a.len, MDL)) {
222 atf_tc_fail("out of memory");
223 }
224 if (!buffer_reference(&a.buffer, buf, MDL)) {
225 atf_tc_fail("buffer_reference() failed");
226 }
227 a.data = a.buffer->data;
228 memcpy(a.buffer->data, str, a.len);
229
230 /*
231 * Forget and confirm we've forgotten.
232 */
233 data_string_forget(&a, MDL);
234
235 if (a.len != 0) {
236 atf_tc_fail("incorrect length");
237 }
238
239 if (a.data != NULL) {
240 atf_tc_fail("incorrect data");
241 }
242 if (a.terminated) {
243 atf_tc_fail("incorrect terminated");
244 }
245 if (a.buffer != NULL) {
246 atf_tc_fail("incorrect buffer");
247 }
248 if (buf->refcnt != 1) {
249 atf_tc_fail("too many references to buf");
250 }
251
252 /*
253 * Clean up buffer.
254 */
255 if (!buffer_dereference(&buf, MDL)) {
256 atf_tc_fail("buffer_reference() failed");
257 }
258 }
259
260 ATF_TC(data_string_forget_nobuf);
261
ATF_TC_HEAD(data_string_forget_nobuf,tc)262 ATF_TC_HEAD(data_string_forget_nobuf, tc) {
263 atf_tc_set_md_var(tc, "descr", "data_string_forget test, "
264 "data_string without buffer");
265 }
266
ATF_TC_BODY(data_string_forget_nobuf,tc)267 ATF_TC_BODY(data_string_forget_nobuf, tc) {
268 struct data_string a;
269 const char *str = "Lorem ipsum dolor sit amet massa nunc.";
270
271 /*
272 * Create the string we want to forget.
273 */
274 memset(&a, 0, sizeof(a));
275 a.len = strlen(str);
276 a.data = (const unsigned char *)str;
277 a.terminated = 1;
278
279 /*
280 * Forget and confirm we've forgotten.
281 */
282 data_string_forget(&a, MDL);
283
284 if (a.len != 0) {
285 atf_tc_fail("incorrect length");
286 }
287 if (a.data != NULL) {
288 atf_tc_fail("incorrect data");
289 }
290 if (a.terminated) {
291 atf_tc_fail("incorrect terminated");
292 }
293 if (a.buffer != NULL) {
294 atf_tc_fail("incorrect buffer");
295 }
296 }
297
298 ATF_TC(data_string_copy);
299
ATF_TC_HEAD(data_string_copy,tc)300 ATF_TC_HEAD(data_string_copy, tc) {
301 atf_tc_set_md_var(tc, "descr", "data_string_copy basic test");
302 }
303
ATF_TC_BODY(data_string_copy,tc)304 ATF_TC_BODY(data_string_copy, tc) {
305 struct data_string a, b;
306 const char *str = "Lorem ipsum dolor sit amet orci aliquam.";
307
308 /*
309 * Create the string we want to copy.
310 */
311 memset(&a, 0, sizeof(a));
312 a.len = strlen(str);
313 if (!buffer_allocate(&a.buffer, a.len, MDL)) {
314 atf_tc_fail("out of memory");
315 }
316 a.data = a.buffer->data;
317 memcpy(a.buffer->data, str, a.len);
318
319 /*
320 * Copy the string, and confirm it works.
321 */
322 memset(&b, 0, sizeof(b));
323 data_string_copy(&b, &a, MDL);
324
325 if (b.len != a.len) {
326 atf_tc_fail("incorrect length");
327 }
328 if (b.data != a.data) {
329 atf_tc_fail("incorrect data");
330 }
331 if (b.terminated != a.terminated) {
332 atf_tc_fail("incorrect terminated");
333 }
334 if (b.buffer != a.buffer) {
335 atf_tc_fail("incorrect buffer");
336 }
337
338 /*
339 * Clean up.
340 */
341 data_string_forget(&b, MDL);
342 data_string_forget(&a, MDL);
343 }
344
345 ATF_TC(data_string_copy_nobuf);
346
ATF_TC_HEAD(data_string_copy_nobuf,tc)347 ATF_TC_HEAD(data_string_copy_nobuf, tc) {
348 atf_tc_set_md_var(tc, "descr", "data_string_copy test, "
349 "data_string without buffer");
350 }
351
ATF_TC_BODY(data_string_copy_nobuf,tc)352 ATF_TC_BODY(data_string_copy_nobuf, tc) {
353 struct data_string a, b;
354 const char *str = "Lorem ipsum dolor sit amet cras amet.";
355
356 /*
357 * Create the string we want to copy.
358 */
359 memset(&a, 0, sizeof(a));
360 a.len = strlen(str);
361 a.data = (const unsigned char *)str;
362 a.terminated = 1;
363
364 /*
365 * Copy the string, and confirm it works.
366 */
367 memset(&b, 0, sizeof(b));
368 data_string_copy(&b, &a, MDL);
369
370 if (b.len != a.len) {
371 atf_tc_fail("incorrect length");
372 }
373 if (b.data != a.data) {
374 atf_tc_fail("incorrect data");
375 }
376 if (b.terminated != a.terminated) {
377 atf_tc_fail("incorrect terminated");
378 }
379 if (b.buffer != a.buffer) {
380 atf_tc_fail("incorrect buffer");
381 }
382
383 /*
384 * Clean up.
385 */
386 data_string_forget(&b, MDL);
387 data_string_forget(&a, MDL);
388
389 }
390
ATF_TP_ADD_TCS(tp)391 ATF_TP_ADD_TCS(tp)
392 {
393 ATF_TP_ADD_TC(tp, buffer_allocate);
394 ATF_TP_ADD_TC(tp, buffer_reference);
395 ATF_TP_ADD_TC(tp, buffer_dereference);
396 ATF_TP_ADD_TC(tp, data_string_forget);
397 ATF_TP_ADD_TC(tp, data_string_forget_nobuf);
398 ATF_TP_ADD_TC(tp, data_string_copy);
399 ATF_TP_ADD_TC(tp, data_string_copy_nobuf);
400
401 return (atf_no_error());
402 }
403