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
ATF_TC_HEAD(load_balance,tc)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
ATF_TC_BODY(load_balance,tc)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
ATF_TC_HEAD(load_balance_swap,tc)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
ATF_TC_BODY(load_balance_swap,tc)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
ATF_TP_ADD_TCS(tp)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