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