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