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 
33 ATF_TC_HEAD(buffer_allocate, tc) {
34     atf_tc_set_md_var(tc, "descr", "buffer_allocate basic test");
35 }
36 
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 
76 ATF_TC_HEAD(buffer_reference, tc) {
77     atf_tc_set_md_var(tc, "descr", "buffer_reference basic test");
78 }
79 
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 
137 ATF_TC_HEAD(buffer_dereference, tc) {
138     atf_tc_set_md_var(tc, "descr", "buffer_dereference basic test");
139 }
140 
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 
206 ATF_TC_HEAD(data_string_forget, tc) {
207     atf_tc_set_md_var(tc, "descr", "data_string_forget basic test");
208 }
209 
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 
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 
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 
300 ATF_TC_HEAD(data_string_copy, tc) {
301     atf_tc_set_md_var(tc, "descr", "data_string_copy basic test");
302 }
303 
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 
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 
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 
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