1 /* $NetBSD: load_bal_unittest.c,v 1.1.1.2 2014/07/12 11:58:16 spz Exp $ */ 2 /* 3 * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15 * PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <config.h> 19 20 #include "dhcpd.h" 21 22 #include <atf-c.h> 23 24 /* 25 * Test the load balancing code. 26 * 27 * The two main variables are: 28 * packet => the "packet" being processed 29 * state => the "state" of the failover peer 30 * We only fill in the fields necessary for our testing 31 * packet->raw->secs => amount of time the client has been trying 32 * packet->raw->hlen => the length of the mac address of the client 33 * packet->raw->chaddr => the mac address of the client 34 * To simplify the tests the mac address will be only 1 byte long and 35 * not really matter. Instead the hba will be all 1s and the tests 36 * will use the primary/secondary flag to change the expected result. 37 * 38 * state->i_am => primary or secondary 39 * state->load_balance_max_secs => maxixum time for a client to be trying 40 * before the other peer responds 41 * set to 5 for these tests 42 * state->hba = array of hash buckets assigning the hash to primary or secondary 43 * set to all ones (all primary) for theses tests 44 */ 45 46 ATF_TC(load_balance); 47 48 ATF_TC_HEAD(load_balance, tc) 49 { 50 atf_tc_set_md_var(tc, "descr", "This test case checks that " 51 "load balancing works."); 52 } 53 54 ATF_TC_BODY(load_balance, tc) 55 { 56 struct packet packet; 57 struct dhcp_packet raw; 58 dhcp_failover_state_t pstate, sstate; 59 u_int8_t hba[256]; 60 61 memset(&packet, 0, sizeof(struct packet)); 62 memset(&raw, 0, sizeof(struct dhcp_packet)); 63 packet.raw = &raw; 64 raw.hlen = 1; 65 raw.chaddr[0] = 14; 66 67 memset(hba, 0xFF, 256); 68 69 /* primary state */ 70 memset(&pstate, 0, sizeof(dhcp_failover_state_t)); 71 pstate.i_am = primary; 72 pstate.load_balance_max_secs = 5; 73 pstate.hba = hba; 74 75 /* secondary state, we can reuse the hba as it doesn't change */ 76 memset(&sstate, 0, sizeof(dhcp_failover_state_t)); 77 sstate.i_am = secondary; 78 sstate.load_balance_max_secs = 5; 79 sstate.hba = hba; 80 81 /* Basic check, primary accepted, secondary not */ 82 raw.secs = htons(0); 83 if (load_balance_mine(&packet, &pstate) != 1) { 84 atf_tc_fail("ERROR: primary not accepted %s:%d", MDL); 85 } 86 87 if (load_balance_mine(&packet, &sstate) != 0) { 88 atf_tc_fail("ERROR: secondary accepted %s:%d", MDL); 89 } 90 91 92 /* Timeout not exceeded, primary accepted, secondary not */ 93 raw.secs = htons(2); 94 if (load_balance_mine(&packet, &pstate) != 1) { 95 atf_tc_fail("ERROR: primary not accepted %s:%d", MDL); 96 } 97 98 if (load_balance_mine(&packet, &sstate) != 0) { 99 atf_tc_fail("ERROR: secondary accepted %s:%d", MDL); 100 } 101 102 /* Timeout exceeded, both accepted */ 103 raw.secs = htons(6); 104 if (load_balance_mine(&packet, &pstate) != 1) { 105 atf_tc_fail("ERROR: primary not accepted %s:%d", MDL); 106 } 107 108 if (load_balance_mine(&packet, &sstate) != 1) { 109 atf_tc_fail("ERROR: secondary not accepted %s:%d", MDL); 110 } 111 112 /* Timeout exeeded with a large value, both accepted */ 113 raw.secs = htons(257); 114 if (load_balance_mine(&packet, &pstate) != 1) { 115 atf_tc_fail("ERROR: primary not accepted %s:%d", MDL); 116 } 117 118 if (load_balance_mine(&packet, &sstate) != 1) { 119 atf_tc_fail("ERROR: secondary not accepted %s:%d", MDL); 120 } 121 122 } 123 124 ATF_TC(load_balance_swap); 125 126 ATF_TC_HEAD(load_balance_swap, tc) 127 { 128 atf_tc_set_md_var(tc, "descr", "This test case checks that " 129 "load balancing works with byteswapping."); 130 } 131 132 ATF_TC_BODY(load_balance_swap, tc) 133 { 134 #if defined(SECS_BYTEORDER) 135 struct packet packet; 136 struct dhcp_packet raw; 137 dhcp_failover_state_t pstate, sstate; 138 u_int8_t hba[256]; 139 140 memset(&packet, 0, sizeof(struct packet)); 141 memset(&raw, 0, sizeof(struct dhcp_packet)); 142 packet.raw = &raw; 143 raw.hlen = 1; 144 raw.chaddr[0] = 14; 145 146 memset(hba, 0xFF, 256); 147 148 /* primary state */ 149 memset(&pstate, 0, sizeof(dhcp_failover_state_t)); 150 pstate.i_am = primary; 151 pstate.load_balance_max_secs = 5; 152 pstate.hba = hba; 153 154 /* secondary state, we can reuse the hba as it doesn't change */ 155 memset(&sstate, 0, sizeof(dhcp_failover_state_t)); 156 sstate.i_am = secondary; 157 sstate.load_balance_max_secs = 5; 158 sstate.hba = hba; 159 160 /* Small byteswapped timeout, primary accepted, secondary not*/ 161 raw.secs = htons(256); 162 if (load_balance_mine(&packet, &pstate) != 1) { 163 atf_tc_fail("ERROR: primary not accepted %s:%d", MDL); 164 } 165 166 if (load_balance_mine(&packet, &sstate) != 0) { 167 atf_tc_fail("ERROR: secondary accepted %s:%d", MDL); 168 } 169 170 /* Large byteswapped timeout, both accepted*/ 171 raw.secs = htons(256 * 6); 172 if (load_balance_mine(&packet, &pstate) != 1) { 173 atf_tc_fail("ERROR: primary not accepted %s:%d", MDL); 174 } 175 176 if (load_balance_mine(&packet, &sstate) != 1) { 177 atf_tc_fail("ERROR: secondary not accepted %s:%d", MDL); 178 } 179 180 #else 181 atf_tc_skip("SECS_BYTEORDER not defined"); 182 #endif 183 } 184 185 186 ATF_TP_ADD_TCS(tp) 187 { 188 ATF_TP_ADD_TC(tp, load_balance); 189 ATF_TP_ADD_TC(tp, load_balance_swap); 190 191 return (atf_no_error()); 192 } 193