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