Home | History | Annotate | Line # | Download | only in tests
leaseq_unittest.c revision 1.2
      1 /*	$NetBSD: leaseq_unittest.c,v 1.2 2018/04/07 22:37:30 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (C) 2015-2017 by Internet Systems Consortium, Inc. ("ISC")
      5  *
      6  * This Source Code Form is subject to the terms of the Mozilla Public
      7  * License, v. 2.0. If a copy of the MPL was not distributed with this
      8  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
      9  *
     10  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
     11  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
     12  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
     13  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
     14  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
     15  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
     16  * PERFORMANCE OF THIS SOFTWARE.
     17  */
     18 
     19 #include <config.h>
     20 
     21 #include "dhcpd.h"
     22 
     23 #include <atf-c.h>
     24 
     25 /*
     26  * Test the lease queue code.  These tests will verify that we can
     27  * add, find and remove leases from the lease queue code
     28  *
     29  * Thoughout the tests
     30  * lq will be the lease queue for which we add or removing leases
     31  * test_leaseX will be the leases we add or remove
     32  * We only care about the sort_time in the lease structure for these
     33  * tests but need to do a lease_reference in order to keep the ref
     34  * count positive to avoid the omapi code trying to free the object.
     35  * We can't use lease_allocate easily as we haven't set up the omapi
     36  * object information in the test.
     37  */
     38 
     39 #if defined (BINARY_LEASES)
     40 #define INIT_LQ(LQ) memset(&(LQ), 0, sizeof(struct leasechain))
     41 #else
     42 #define INIT_LQ(LQ) lq = NULL
     43 #endif
     44 
     45 /* Test basic leaseq functions with a single lease */
     46 /*- empty, add, get, and remove */
     47 ATF_TC(leaseq_basic);
     48 ATF_TC_HEAD(leaseq_basic, tc)
     49 {
     50 	atf_tc_set_md_var(tc, "descr", "Verify basic functions");
     51 }
     52 
     53 ATF_TC_BODY(leaseq_basic, tc)
     54 {
     55 	LEASE_STRUCT lq;
     56 	struct lease test_lease1, *check_lease;
     57 
     58 	INIT_LQ(lq);
     59 
     60 	memset(&test_lease1, 0, sizeof(struct lease));
     61 	test_lease1.sort_time = 10;
     62 	check_lease = NULL;
     63 	lease_reference(&check_lease, &test_lease1, MDL);
     64 
     65 	/* Check that the lq is empty */
     66 	if ((LEASE_NOT_EMPTY(lq)) || (LEASE_NOT_EMPTYP(&lq)))
     67 		atf_tc_fail("lq not empty at start.");
     68 
     69 	/* And that getting the first lease is okay when queue is empty  */
     70 	if ((LEASE_GET_FIRST(lq) != NULL) || (LEASE_GET_FIRSTP(&lq) != NULL))
     71 		atf_tc_fail("lease not null");
     72 
     73 	/* Add a lease */
     74 	LEASE_INSERTP(&lq, &test_lease1);
     75 
     76 	/* lq shouldn't be empty anymore */
     77 	if (!(LEASE_NOT_EMPTY(lq)) || !(LEASE_NOT_EMPTYP(&lq)))
     78 		atf_tc_fail("lq empty after insertion.");
     79 
     80 	/* We should have the same lease we inserted */
     81 	check_lease = LEASE_GET_FIRST(lq);
     82 	if (check_lease != &test_lease1)
     83 		atf_tc_fail("leases don't match");
     84 
     85 	/* We should have the same lease we inserted */
     86 	check_lease = LEASE_GET_FIRSTP(&lq);
     87 	if (check_lease != &test_lease1)
     88 		atf_tc_fail("leases don't match");
     89 
     90 	/* Check that doing a get on the last lease returns NULL */
     91 	if ((LEASE_GET_NEXT(lq, check_lease) != NULL) ||
     92 	    (LEASE_GET_NEXTP(&lq, check_lease) != NULL)) {
     93 		atf_tc_fail("Next not null");
     94 	}
     95 
     96 	/* Remove the lease */
     97 	LEASE_REMOVEP(&lq, &test_lease1);
     98 
     99 	/* and verify the lease queue is empty again */
    100 	if ((LEASE_NOT_EMPTY(lq)) || (LEASE_NOT_EMPTYP(&lq)))
    101 		atf_tc_fail("lq not empty afer removal");
    102 
    103 	/* And that getting the first lease is okay when queue is empty  */
    104 	if ((LEASE_GET_FIRST(lq) != NULL) || (LEASE_GET_FIRSTP(&lq) != NULL))
    105 		atf_tc_fail("lease not null");
    106 }
    107 
    108 /* Test if we can add leases to the end of the list and remove them
    109  * from the end */
    110 ATF_TC(leaseq_add_to_end);
    111 ATF_TC_HEAD(leaseq_add_to_end, tc)
    112 {
    113 	atf_tc_set_md_var(tc, "descr", "Verify adding to end of list");
    114 }
    115 
    116 ATF_TC_BODY(leaseq_add_to_end, tc)
    117 {
    118 	LEASE_STRUCT lq;
    119 	struct lease test_lease[3], *check_lease;
    120 	int i;
    121 
    122 	INIT_LQ(lq);
    123 
    124 	/* create and add 3 leases */
    125 	for (i = 0; i < 3; i++) {
    126 		memset(&test_lease[i], 0, sizeof(struct lease));
    127 		test_lease[i].sort_time = i;
    128 		check_lease = NULL;
    129 		lease_reference(&check_lease, &test_lease[i], MDL);
    130 		LEASE_INSERTP(&lq, &test_lease[i]);
    131 	}
    132 
    133 	/* check ordering of leases */
    134 	check_lease = LEASE_GET_FIRST(lq);
    135 	for (i = 0; i < 3; i++) {
    136 		if (check_lease != &test_lease[i])
    137 			atf_tc_fail("leases don't match, %d", i);
    138 		check_lease = LEASE_GET_NEXT(lq, check_lease);
    139 	}
    140 	if (check_lease != NULL)
    141 		atf_tc_fail("lease not null");
    142 
    143 	/* Remove the last lease and check the list */
    144 	LEASE_REMOVEP(&lq, &test_lease[2]);
    145 	check_lease = LEASE_GET_FIRST(lq);
    146 	if (check_lease != &test_lease[0])
    147 		atf_tc_fail("wrong lease after remove, 1");
    148 	check_lease = LEASE_GET_NEXT(lq, check_lease);
    149 	if (check_lease != &test_lease[1])
    150 		atf_tc_fail("wrong lease after remove, 2");
    151 
    152 	LEASE_REMOVEP(&lq, &test_lease[1]);
    153 	check_lease = LEASE_GET_FIRST(lq);
    154 	if (check_lease != &test_lease[0])
    155 		atf_tc_fail("wrong lease after remove, 3");
    156 
    157 	LEASE_REMOVEP(&lq, check_lease);
    158 
    159 	/* The lease queue should now be empty */
    160 	if (LEASE_NOT_EMPTY(lq))
    161 		atf_tc_fail("lq not empty afer removal");
    162 }
    163 
    164 /* Test if we can add leases to the start of the list and remove them
    165  * from the start */
    166 ATF_TC(leaseq_add_to_start);
    167 ATF_TC_HEAD(leaseq_add_to_start, tc)
    168 {
    169 	atf_tc_set_md_var(tc, "descr", "Verify adding to start of list");
    170 }
    171 
    172 ATF_TC_BODY(leaseq_add_to_start, tc)
    173 {
    174 	LEASE_STRUCT lq;
    175 	struct lease test_lease[3], *check_lease;
    176 	int i;
    177 
    178 	INIT_LQ(lq);
    179 
    180 	/* create 3 leases */
    181 	for (i = 0; i < 3; i++) {
    182 		memset(&test_lease[i], 0, sizeof(struct lease));
    183 		test_lease[i].sort_time = i;
    184 		check_lease = NULL;
    185 		lease_reference(&check_lease, &test_lease[i], MDL);
    186 	}
    187 
    188 	/* Add leases */
    189 	LEASE_INSERTP(&lq, &test_lease[2]);
    190 	LEASE_INSERTP(&lq, &test_lease[1]);
    191 	LEASE_INSERTP(&lq, &test_lease[0]);
    192 
    193 	/* check ordering of leases */
    194 	check_lease = LEASE_GET_FIRST(lq);
    195 	for (i = 0; i < 3; i++) {
    196 		if (check_lease != &test_lease[i])
    197 			atf_tc_fail("leases don't match, %d", i);
    198 		check_lease = LEASE_GET_NEXT(lq, check_lease);
    199 	}
    200 	if (check_lease != NULL)
    201 		atf_tc_fail("lease not null");
    202 
    203 	/* Remove the first lease and check the next one */
    204 	check_lease = LEASE_GET_FIRST(lq);
    205 	LEASE_REMOVEP(&lq, check_lease);
    206 	check_lease = LEASE_GET_FIRST(lq);
    207 	if (check_lease != &test_lease[1])
    208 		atf_tc_fail("wrong lease after remove, 1");
    209 	check_lease = LEASE_GET_NEXT(lq, check_lease);
    210 	if (check_lease != &test_lease[2])
    211 		atf_tc_fail("wrong lease after remove, 2");
    212 
    213 	check_lease = LEASE_GET_FIRST(lq);
    214 	LEASE_REMOVEP(&lq, check_lease);
    215 	check_lease = LEASE_GET_FIRST(lq);
    216 	if (check_lease != &test_lease[2])
    217 		atf_tc_fail("wrong lease after remove, 3");
    218 
    219 	LEASE_REMOVEP(&lq, check_lease);
    220 
    221 	/* The lease queue should now be empty */
    222 	if (LEASE_NOT_EMPTY(lq))
    223 		atf_tc_fail("lq not empty afer removal");
    224 }
    225 
    226 /* Test if we can add leases to the middle of the list and remove them
    227  * from the middle */
    228 ATF_TC(leaseq_add_to_middle);
    229 ATF_TC_HEAD(leaseq_add_to_middle, tc)
    230 {
    231 	atf_tc_set_md_var(tc, "descr", "Verify adding to end of list");
    232 }
    233 
    234 ATF_TC_BODY(leaseq_add_to_middle, tc)
    235 {
    236 	LEASE_STRUCT lq;
    237 	struct lease test_lease[3], *check_lease;
    238 	int i;
    239 
    240 	INIT_LQ(lq);
    241 
    242 	/* create 3 leases */
    243 	for (i = 0; i < 3; i++) {
    244 		memset(&test_lease[i], 0, sizeof(struct lease));
    245 		test_lease[i].sort_time = i;
    246 		check_lease = NULL;
    247 		lease_reference(&check_lease, &test_lease[i], MDL);
    248 	}
    249 
    250 	/* Add leases */
    251 	LEASE_INSERTP(&lq, &test_lease[0]);
    252 	LEASE_INSERTP(&lq, &test_lease[2]);
    253 	LEASE_INSERTP(&lq, &test_lease[1]);
    254 
    255 	/* check ordering of leases */
    256 	check_lease = LEASE_GET_FIRST(lq);
    257 	for (i = 0; i < 3; i++) {
    258 		if (check_lease != &test_lease[i])
    259 			atf_tc_fail("leases don't match, %d", i);
    260 		check_lease = LEASE_GET_NEXT(lq, check_lease);
    261 	}
    262 	if (check_lease != NULL)
    263 		atf_tc_fail("lease not null");
    264 
    265 	/* Remove the middle lease and check the list */
    266 	LEASE_REMOVEP(&lq, &test_lease[1]);
    267 	check_lease = LEASE_GET_FIRST(lq);
    268 	if (check_lease != &test_lease[0])
    269 		atf_tc_fail("wrong lease after remove, 1");
    270 	check_lease = LEASE_GET_NEXT(lq, check_lease);
    271 	if (check_lease != &test_lease[2])
    272 		atf_tc_fail("wrong lease after remove, 2");
    273 
    274 	LEASE_REMOVEP(&lq, &test_lease[0]);
    275 	check_lease = LEASE_GET_FIRST(lq);
    276 	if (check_lease != &test_lease[2])
    277 		atf_tc_fail("wrong lease after remove, 3");
    278 
    279 	LEASE_REMOVEP(&lq, check_lease);
    280 
    281 	/* The lease queue should now be empty */
    282 	if (LEASE_NOT_EMPTY(lq))
    283 		atf_tc_fail("lq not empty afer removal");
    284 }
    285 
    286 /* Test if we can cycle the leases we add three leases then remove
    287  * the first one, update it's sort time and re add it */
    288 ATF_TC(leaseq_cycle);
    289 ATF_TC_HEAD(leaseq_cycle, tc)
    290 {
    291 	atf_tc_set_md_var(tc, "descr", "Verify cycling the list");
    292 }
    293 
    294 ATF_TC_BODY(leaseq_cycle, tc)
    295 {
    296 	LEASE_STRUCT lq;
    297 	struct lease test_lease[3], *check_lease;
    298 	int i;
    299 
    300 	INIT_LQ(lq);
    301 
    302 	/* create and add 3 leases */
    303 	for (i = 0; i < 3; i++) {
    304 		memset(&test_lease[i], 0, sizeof(struct lease));
    305 		test_lease[i].sort_time = i;
    306 		check_lease = NULL;
    307 		lease_reference(&check_lease, &test_lease[i], MDL);
    308 		LEASE_INSERTP(&lq, &test_lease[i]);
    309 	}
    310 
    311 	/* Remove first lease, update it and re-insert it */
    312 	LEASE_REMOVEP(&lq, &test_lease[0]);
    313 	test_lease[0].sort_time = 4;
    314 	LEASE_INSERTP(&lq, &test_lease[0]);
    315 
    316 	/* check ordering of leases */
    317 	check_lease = LEASE_GET_FIRST(lq);
    318 	if (check_lease != &test_lease[1])
    319 		atf_tc_fail("leases don't match, 1");
    320 	check_lease = LEASE_GET_NEXT(lq, check_lease);
    321 	if (check_lease != &test_lease[2])
    322 		atf_tc_fail("leases don't match, 2");
    323 	check_lease = LEASE_GET_NEXT(lq, check_lease);
    324 	if (check_lease != &test_lease[0])
    325 		atf_tc_fail("leases don't match, 3");
    326 
    327 	/* Remove first lease, update it and re-insert it */
    328 	LEASE_REMOVEP(&lq, &test_lease[1]);
    329 	test_lease[1].sort_time = 5;
    330 	LEASE_INSERTP(&lq, &test_lease[1]);
    331 
    332 	/* check ordering of leases */
    333 	check_lease = LEASE_GET_FIRST(lq);
    334 	if (check_lease != &test_lease[2])
    335 		atf_tc_fail("leases don't match, 4");
    336 	check_lease = LEASE_GET_NEXT(lq, check_lease);
    337 	if (check_lease != &test_lease[0])
    338 		atf_tc_fail("leases don't match, 5");
    339 	check_lease = LEASE_GET_NEXT(lq, check_lease);
    340 	if (check_lease != &test_lease[1])
    341 		atf_tc_fail("leases don't match, 6");
    342 
    343 	/* Remove first lease, update it and re-insert it */
    344 	LEASE_REMOVEP(&lq, &test_lease[2]);
    345 	test_lease[2].sort_time = 6;
    346 	LEASE_INSERTP(&lq, &test_lease[2]);
    347 
    348 	/* check ordering of leases */
    349 	check_lease = LEASE_GET_FIRST(lq);
    350 	if (check_lease != &test_lease[0])
    351 		atf_tc_fail("leases don't match, 7");
    352 	check_lease = LEASE_GET_NEXT(lq, check_lease);
    353 	if (check_lease != &test_lease[1])
    354 		atf_tc_fail("leases don't match, 8");
    355 	check_lease = LEASE_GET_NEXT(lq, check_lease);
    356 	if (check_lease != &test_lease[2])
    357 		atf_tc_fail("leases don't match, 9");
    358 }
    359 
    360 /* Test what happens if we set the growth factor to a smallish number
    361  * and add enough leases to require it to grow multiple times
    362  * Mostly this is for the binary leases case but we can most of the
    363  * test for both.
    364  */
    365 
    366 ATF_TC(leaseq_long);
    367 ATF_TC_HEAD(leaseq_long, tc)
    368 {
    369 	atf_tc_set_md_var(tc, "descr", "Verify a long list");
    370 }
    371 
    372 ATF_TC_BODY(leaseq_long, tc)
    373 {
    374 	LEASE_STRUCT lq;
    375 	struct lease test_lease[20], *check_lease;
    376 	int i;
    377 
    378 	INIT_LQ(lq);
    379 #if defined (BINARY_LEASES)
    380 	lc_init_growth(&lq, 5);
    381 #endif
    382 
    383 	/* create and add 10 leases */
    384 	for (i = 0; i < 10; i++) {
    385 		memset(&test_lease[i], 0, sizeof(struct lease));
    386 		test_lease[i].sort_time = i;
    387 		check_lease = NULL;
    388 		lease_reference(&check_lease, &test_lease[i], MDL);
    389 
    390 		LEASE_INSERTP(&lq, &test_lease[i]);
    391 	}
    392 
    393 	/* check ordering of leases */
    394 	check_lease = LEASE_GET_FIRST(lq);
    395 	for (i = 0; i < 10; i++) {
    396 		if (check_lease != &test_lease[i])
    397 			atf_tc_fail("leases don't match, %d", i);
    398 		check_lease = LEASE_GET_NEXT(lq, check_lease);
    399 	}
    400 
    401 	/* Remove first 5 */
    402 	for (i = 0; i < 5; i++) {
    403 		LEASE_REMOVEP(&lq, &test_lease[i]);
    404 	}
    405 
    406 	/* Add 10 more */
    407 	for (i = 10; i < 20; i++) {
    408 		memset(&test_lease[i], 0, sizeof(struct lease));
    409 		test_lease[i].sort_time = i;
    410 		check_lease = NULL;
    411 		lease_reference(&check_lease, &test_lease[i], MDL);
    412 
    413 		LEASE_INSERTP(&lq, &test_lease[i]);
    414 	}
    415 
    416 	/* and the first 5 */
    417 	for (i = 0; i < 5; i++) {
    418 		LEASE_INSERTP(&lq, &test_lease[i]);
    419 	}
    420 
    421 	/* and check them all out */
    422 	check_lease = LEASE_GET_FIRST(lq);
    423 	for (i = 0; i < 20; i++) {
    424 		if (check_lease != &test_lease[i])
    425 			atf_tc_fail("leases don't match, %d", i);
    426 		check_lease = LEASE_GET_NEXT(lq, check_lease);
    427 	}
    428 }
    429 
    430 /* Test if we can add leases that all have the same sort time
    431  */
    432 ATF_TC(leaseq_same_time);
    433 ATF_TC_HEAD(leaseq_same_time, tc)
    434 {
    435 	atf_tc_set_md_var(tc, "descr", "Verify adding leases with same time");
    436 }
    437 
    438 ATF_TC_BODY(leaseq_same_time, tc)
    439 {
    440 	LEASE_STRUCT lq;
    441 	struct lease test_lease[20], *check_lease;
    442 	int i;
    443 
    444 	INIT_LQ(lq);
    445 
    446 	/* create and add 20 leases */
    447 	for (i = 0; i < 20; i++) {
    448 		memset(&test_lease[i], 0, sizeof(struct lease));
    449 		if (i < 10)
    450 			test_lease[i].sort_time = 10;
    451 		else
    452 			test_lease[i].sort_time = 20;
    453 		check_lease = NULL;
    454 		lease_reference(&check_lease, &test_lease[i], MDL);
    455 		LEASE_INSERTP(&lq, &test_lease[i]);
    456 	}
    457 
    458 #if defined (BINARY_LEASES)
    459 	/* the ordering isn't well defined for either but we check
    460 	 * to see what happens in the binary case.  At the start
    461 	 * the leases should stay in the order they were added.
    462 	 */
    463 
    464 	/* check ordering of leases */
    465 	check_lease = LEASE_GET_FIRST(lq);
    466 	for (i = 0; i < 20; i++) {
    467 		if (check_lease != &test_lease[i])
    468 			atf_tc_fail("leases don't match 1, %d", i);
    469 		check_lease = LEASE_GET_NEXT(lq, check_lease);
    470 	}
    471 	if (check_lease != NULL)
    472 		atf_tc_fail("lease not null");
    473 #endif
    474 
    475 	/* Remove first 10, update their time, but still before
    476 	 * the previous 10 and re add them */
    477 	for (i = 0; i < 10; i++) {
    478 		LEASE_REMOVEP(&lq, &test_lease[i]);
    479 		test_lease[i].sort_time = 15;
    480 		LEASE_INSERTP(&lq, &test_lease[i]);
    481 	}
    482 
    483 	/* The ordering becomes random at this point so we don't
    484 	 * check it.  We try to remove them all and see that
    485 	 * we got to an empty queue.
    486 	 */
    487 	for (i = 0; i < 20; i++) {
    488 		LEASE_REMOVEP(&lq, &test_lease[i]);
    489 	}
    490 	if (LEASE_NOT_EMPTY(lq))
    491 		atf_tc_fail("queue not empty");
    492 
    493 }
    494 
    495 ATF_TP_ADD_TCS(tp)
    496 {
    497 	ATF_TP_ADD_TC(tp, leaseq_basic);
    498 	ATF_TP_ADD_TC(tp, leaseq_add_to_end);
    499 	ATF_TP_ADD_TC(tp, leaseq_add_to_start);
    500 	ATF_TP_ADD_TC(tp, leaseq_add_to_middle);
    501 	ATF_TP_ADD_TC(tp, leaseq_cycle);
    502 	ATF_TP_ADD_TC(tp, leaseq_long);
    503 	ATF_TP_ADD_TC(tp, leaseq_same_time);
    504 	return (atf_no_error());
    505 }
    506