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