Home | History | Annotate | Line # | Download | only in tests
      1 /*	$NetBSD: load_bal_unittest.c,v 1.2 2018/04/07 22:37:30 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (C) 2012-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 load balancing code.
     27  *
     28  * The two main variables are:
     29  * packet => the "packet" being processed
     30  * state  => the "state" of the failover peer
     31  * We only fill in the fields necessary for our testing
     32  * packet->raw->secs   => amount of time the client has been trying
     33  * packet->raw->hlen   => the length of the mac address of the client
     34  * packet->raw->chaddr => the mac address of the client
     35  * To simplify the tests the mac address will be only 1 byte long and
     36  * not really matter.  Instead the hba will be all 1s and the tests
     37  * will use the primary/secondary flag to change the expected result.
     38  *
     39  * state->i_am => primary or secondary
     40  * state->load_balance_max_secs => maxixum time for a client to be trying
     41  *                                 before the other peer responds
     42  *                                 set to 5 for these tests
     43  * state->hba = array of hash buckets assigning the hash to primary or secondary
     44  *              set to all ones (all primary) for theses tests
     45  */
     46 
     47 ATF_TC(load_balance);
     48 
     49 ATF_TC_HEAD(load_balance, tc)
     50 {
     51 	atf_tc_set_md_var(tc, "descr", "This test case checks that "
     52 			  "load balancing works.");
     53 }
     54 
     55 ATF_TC_BODY(load_balance, tc)
     56 {
     57 #if defined(FAILOVER_PROTOCOL)
     58 	struct packet packet;
     59 	struct dhcp_packet raw;
     60 	dhcp_failover_state_t pstate, sstate;
     61 	u_int8_t hba[256];
     62 
     63 	memset(&packet, 0, sizeof(struct packet));
     64 	memset(&raw, 0, sizeof(struct dhcp_packet));
     65 	packet.raw = &raw;
     66 	raw.hlen = 1;
     67 	raw.chaddr[0] = 14;
     68 
     69 	memset(hba, 0xFF, 256);
     70 
     71 	/* primary state */
     72 	memset(&pstate, 0, sizeof(dhcp_failover_state_t));
     73 	pstate.i_am = primary;
     74 	pstate.load_balance_max_secs = 5;
     75 	pstate.hba = hba;
     76 
     77 	/* secondary state, we can reuse the hba as it doesn't change */
     78 	memset(&sstate, 0, sizeof(dhcp_failover_state_t));
     79 	sstate.i_am = secondary;
     80 	sstate.load_balance_max_secs = 5;
     81 	sstate.hba = hba;
     82 
     83 	/* Basic check, primary accepted, secondary not */
     84 	raw.secs = htons(0);
     85 	if (load_balance_mine(&packet, &pstate) != 1) {
     86 		atf_tc_fail("ERROR: primary not accepted %s:%d", MDL);
     87 	}
     88 
     89 	if (load_balance_mine(&packet, &sstate) != 0) {
     90 		atf_tc_fail("ERROR: secondary accepted %s:%d", MDL);
     91 	}
     92 
     93 
     94 	/* Timeout not exceeded, primary accepted, secondary not */
     95 	raw.secs = htons(2);
     96 	if (load_balance_mine(&packet, &pstate) != 1) {
     97 		atf_tc_fail("ERROR: primary not accepted %s:%d", MDL);
     98 	}
     99 
    100 	if (load_balance_mine(&packet, &sstate) != 0) {
    101 		atf_tc_fail("ERROR: secondary accepted %s:%d", MDL);
    102 	}
    103 
    104 	/* Timeout exceeded, both accepted */
    105 	raw.secs = htons(6);
    106 	if (load_balance_mine(&packet, &pstate) != 1) {
    107 		atf_tc_fail("ERROR: primary not accepted %s:%d", MDL);
    108 	}
    109 
    110 	if (load_balance_mine(&packet, &sstate) != 1) {
    111 		atf_tc_fail("ERROR: secondary not accepted %s:%d", MDL);
    112 	}
    113 
    114 	/* Timeout exeeded with a large value, both accepted */
    115 	raw.secs = htons(257);
    116 	if (load_balance_mine(&packet, &pstate) != 1) {
    117 		atf_tc_fail("ERROR: primary not accepted %s:%d", MDL);
    118 	}
    119 
    120 	if (load_balance_mine(&packet, &sstate) != 1) {
    121 		atf_tc_fail("ERROR: secondary not accepted %s:%d", MDL);
    122 	}
    123 #else
    124     atf_tc_skip("failover is disabled");
    125 #endif
    126 }
    127 
    128 ATF_TC(load_balance_swap);
    129 
    130 ATF_TC_HEAD(load_balance_swap, tc)
    131 {
    132 	atf_tc_set_md_var(tc, "descr", "This test case checks that "
    133 			  "load balancing works with byteswapping.");
    134 }
    135 
    136 ATF_TC_BODY(load_balance_swap, tc)
    137 {
    138 #if defined(FAILOVER_PROTOCOL)
    139 	struct packet packet;
    140 	struct dhcp_packet raw;
    141 	dhcp_failover_state_t pstate, sstate;
    142 	u_int8_t hba[256];
    143 
    144 	check_secs_byte_order = 1;
    145 
    146 	memset(&packet, 0, sizeof(struct packet));
    147 	memset(&raw, 0, sizeof(struct dhcp_packet));
    148 	packet.raw = &raw;
    149 	raw.hlen = 1;
    150 	raw.chaddr[0] = 14;
    151 
    152 	memset(hba, 0xFF, 256);
    153 
    154 	/* primary state */
    155 	memset(&pstate, 0, sizeof(dhcp_failover_state_t));
    156 	pstate.i_am = primary;
    157 	pstate.load_balance_max_secs = 5;
    158 	pstate.hba = hba;
    159 
    160 	/* secondary state, we can reuse the hba as it doesn't change */
    161 	memset(&sstate, 0, sizeof(dhcp_failover_state_t));
    162 	sstate.i_am = secondary;
    163 	sstate.load_balance_max_secs = 5;
    164 	sstate.hba = hba;
    165 
    166 	/* Small byteswapped timeout, primary accepted, secondary not*/
    167 	raw.secs = htons(256);
    168 	if (load_balance_mine(&packet, &pstate) != 1) {
    169 		atf_tc_fail("ERROR: primary not accepted %s:%d", MDL);
    170 	}
    171 
    172 	if (load_balance_mine(&packet, &sstate) != 0) {
    173 		atf_tc_fail("ERROR: secondary accepted %s:%d", MDL);
    174 	}
    175 
    176 	/* Large byteswapped timeout, both accepted*/
    177 	raw.secs = htons(256 * 6);
    178 	if (load_balance_mine(&packet, &pstate) != 1) {
    179 		atf_tc_fail("ERROR: primary not accepted %s:%d", MDL);
    180 	}
    181 
    182 	if (load_balance_mine(&packet, &sstate) != 1) {
    183 		atf_tc_fail("ERROR: secondary not accepted %s:%d", MDL);
    184 	}
    185 #else
    186 	atf_tc_skip("failover is disabled");
    187 #endif
    188 }
    189 
    190 
    191 ATF_TP_ADD_TCS(tp)
    192 {
    193 	ATF_TP_ADD_TC(tp, load_balance);
    194 	ATF_TP_ADD_TC(tp, load_balance_swap);
    195 
    196 	return (atf_no_error());
    197 }
    198