1*ce893c7eSchristos /* $NetBSD: load_bal_unittest.c,v 1.2 2018/04/07 22:37:30 christos Exp $ */
26fb29d29Schristos
36fb29d29Schristos /*
46fb29d29Schristos * Copyright (C) 2012-2017 by Internet Systems Consortium, Inc. ("ISC")
56fb29d29Schristos *
66fb29d29Schristos * This Source Code Form is subject to the terms of the Mozilla Public
76fb29d29Schristos * License, v. 2.0. If a copy of the MPL was not distributed with this
86fb29d29Schristos * file, You can obtain one at http://mozilla.org/MPL/2.0/.
96fb29d29Schristos *
106fb29d29Schristos * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
116fb29d29Schristos * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
126fb29d29Schristos * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
136fb29d29Schristos * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
146fb29d29Schristos * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
156fb29d29Schristos * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
166fb29d29Schristos * PERFORMANCE OF THIS SOFTWARE.
176fb29d29Schristos */
186fb29d29Schristos
196fb29d29Schristos #include <config.h>
206fb29d29Schristos
216fb29d29Schristos #include "dhcpd.h"
226fb29d29Schristos
236fb29d29Schristos #include <atf-c.h>
246fb29d29Schristos
256fb29d29Schristos /*
266fb29d29Schristos * Test the load balancing code.
276fb29d29Schristos *
286fb29d29Schristos * The two main variables are:
296fb29d29Schristos * packet => the "packet" being processed
306fb29d29Schristos * state => the "state" of the failover peer
316fb29d29Schristos * We only fill in the fields necessary for our testing
326fb29d29Schristos * packet->raw->secs => amount of time the client has been trying
336fb29d29Schristos * packet->raw->hlen => the length of the mac address of the client
346fb29d29Schristos * packet->raw->chaddr => the mac address of the client
356fb29d29Schristos * To simplify the tests the mac address will be only 1 byte long and
366fb29d29Schristos * not really matter. Instead the hba will be all 1s and the tests
376fb29d29Schristos * will use the primary/secondary flag to change the expected result.
386fb29d29Schristos *
396fb29d29Schristos * state->i_am => primary or secondary
406fb29d29Schristos * state->load_balance_max_secs => maxixum time for a client to be trying
416fb29d29Schristos * before the other peer responds
426fb29d29Schristos * set to 5 for these tests
436fb29d29Schristos * state->hba = array of hash buckets assigning the hash to primary or secondary
446fb29d29Schristos * set to all ones (all primary) for theses tests
456fb29d29Schristos */
466fb29d29Schristos
476fb29d29Schristos ATF_TC(load_balance);
486fb29d29Schristos
ATF_TC_HEAD(load_balance,tc)496fb29d29Schristos ATF_TC_HEAD(load_balance, tc)
506fb29d29Schristos {
516fb29d29Schristos atf_tc_set_md_var(tc, "descr", "This test case checks that "
526fb29d29Schristos "load balancing works.");
536fb29d29Schristos }
546fb29d29Schristos
ATF_TC_BODY(load_balance,tc)556fb29d29Schristos ATF_TC_BODY(load_balance, tc)
566fb29d29Schristos {
576fb29d29Schristos #if defined(FAILOVER_PROTOCOL)
586fb29d29Schristos struct packet packet;
596fb29d29Schristos struct dhcp_packet raw;
606fb29d29Schristos dhcp_failover_state_t pstate, sstate;
616fb29d29Schristos u_int8_t hba[256];
626fb29d29Schristos
636fb29d29Schristos memset(&packet, 0, sizeof(struct packet));
646fb29d29Schristos memset(&raw, 0, sizeof(struct dhcp_packet));
656fb29d29Schristos packet.raw = &raw;
666fb29d29Schristos raw.hlen = 1;
676fb29d29Schristos raw.chaddr[0] = 14;
686fb29d29Schristos
696fb29d29Schristos memset(hba, 0xFF, 256);
706fb29d29Schristos
716fb29d29Schristos /* primary state */
726fb29d29Schristos memset(&pstate, 0, sizeof(dhcp_failover_state_t));
736fb29d29Schristos pstate.i_am = primary;
746fb29d29Schristos pstate.load_balance_max_secs = 5;
756fb29d29Schristos pstate.hba = hba;
766fb29d29Schristos
776fb29d29Schristos /* secondary state, we can reuse the hba as it doesn't change */
786fb29d29Schristos memset(&sstate, 0, sizeof(dhcp_failover_state_t));
796fb29d29Schristos sstate.i_am = secondary;
806fb29d29Schristos sstate.load_balance_max_secs = 5;
816fb29d29Schristos sstate.hba = hba;
826fb29d29Schristos
836fb29d29Schristos /* Basic check, primary accepted, secondary not */
846fb29d29Schristos raw.secs = htons(0);
856fb29d29Schristos if (load_balance_mine(&packet, &pstate) != 1) {
866fb29d29Schristos atf_tc_fail("ERROR: primary not accepted %s:%d", MDL);
876fb29d29Schristos }
886fb29d29Schristos
896fb29d29Schristos if (load_balance_mine(&packet, &sstate) != 0) {
906fb29d29Schristos atf_tc_fail("ERROR: secondary accepted %s:%d", MDL);
916fb29d29Schristos }
926fb29d29Schristos
936fb29d29Schristos
946fb29d29Schristos /* Timeout not exceeded, primary accepted, secondary not */
956fb29d29Schristos raw.secs = htons(2);
966fb29d29Schristos if (load_balance_mine(&packet, &pstate) != 1) {
976fb29d29Schristos atf_tc_fail("ERROR: primary not accepted %s:%d", MDL);
986fb29d29Schristos }
996fb29d29Schristos
1006fb29d29Schristos if (load_balance_mine(&packet, &sstate) != 0) {
1016fb29d29Schristos atf_tc_fail("ERROR: secondary accepted %s:%d", MDL);
1026fb29d29Schristos }
1036fb29d29Schristos
1046fb29d29Schristos /* Timeout exceeded, both accepted */
1056fb29d29Schristos raw.secs = htons(6);
1066fb29d29Schristos if (load_balance_mine(&packet, &pstate) != 1) {
1076fb29d29Schristos atf_tc_fail("ERROR: primary not accepted %s:%d", MDL);
1086fb29d29Schristos }
1096fb29d29Schristos
1106fb29d29Schristos if (load_balance_mine(&packet, &sstate) != 1) {
1116fb29d29Schristos atf_tc_fail("ERROR: secondary not accepted %s:%d", MDL);
1126fb29d29Schristos }
1136fb29d29Schristos
1146fb29d29Schristos /* Timeout exeeded with a large value, both accepted */
1156fb29d29Schristos raw.secs = htons(257);
1166fb29d29Schristos if (load_balance_mine(&packet, &pstate) != 1) {
1176fb29d29Schristos atf_tc_fail("ERROR: primary not accepted %s:%d", MDL);
1186fb29d29Schristos }
1196fb29d29Schristos
1206fb29d29Schristos if (load_balance_mine(&packet, &sstate) != 1) {
1216fb29d29Schristos atf_tc_fail("ERROR: secondary not accepted %s:%d", MDL);
1226fb29d29Schristos }
1236fb29d29Schristos #else
1246fb29d29Schristos atf_tc_skip("failover is disabled");
1256fb29d29Schristos #endif
1266fb29d29Schristos }
1276fb29d29Schristos
1286fb29d29Schristos ATF_TC(load_balance_swap);
1296fb29d29Schristos
ATF_TC_HEAD(load_balance_swap,tc)1306fb29d29Schristos ATF_TC_HEAD(load_balance_swap, tc)
1316fb29d29Schristos {
1326fb29d29Schristos atf_tc_set_md_var(tc, "descr", "This test case checks that "
1336fb29d29Schristos "load balancing works with byteswapping.");
1346fb29d29Schristos }
1356fb29d29Schristos
ATF_TC_BODY(load_balance_swap,tc)1366fb29d29Schristos ATF_TC_BODY(load_balance_swap, tc)
1376fb29d29Schristos {
1386fb29d29Schristos #if defined(FAILOVER_PROTOCOL)
1396fb29d29Schristos struct packet packet;
1406fb29d29Schristos struct dhcp_packet raw;
1416fb29d29Schristos dhcp_failover_state_t pstate, sstate;
1426fb29d29Schristos u_int8_t hba[256];
1436fb29d29Schristos
1446fb29d29Schristos check_secs_byte_order = 1;
1456fb29d29Schristos
1466fb29d29Schristos memset(&packet, 0, sizeof(struct packet));
1476fb29d29Schristos memset(&raw, 0, sizeof(struct dhcp_packet));
1486fb29d29Schristos packet.raw = &raw;
1496fb29d29Schristos raw.hlen = 1;
1506fb29d29Schristos raw.chaddr[0] = 14;
1516fb29d29Schristos
1526fb29d29Schristos memset(hba, 0xFF, 256);
1536fb29d29Schristos
1546fb29d29Schristos /* primary state */
1556fb29d29Schristos memset(&pstate, 0, sizeof(dhcp_failover_state_t));
1566fb29d29Schristos pstate.i_am = primary;
1576fb29d29Schristos pstate.load_balance_max_secs = 5;
1586fb29d29Schristos pstate.hba = hba;
1596fb29d29Schristos
1606fb29d29Schristos /* secondary state, we can reuse the hba as it doesn't change */
1616fb29d29Schristos memset(&sstate, 0, sizeof(dhcp_failover_state_t));
1626fb29d29Schristos sstate.i_am = secondary;
1636fb29d29Schristos sstate.load_balance_max_secs = 5;
1646fb29d29Schristos sstate.hba = hba;
1656fb29d29Schristos
1666fb29d29Schristos /* Small byteswapped timeout, primary accepted, secondary not*/
1676fb29d29Schristos raw.secs = htons(256);
1686fb29d29Schristos if (load_balance_mine(&packet, &pstate) != 1) {
1696fb29d29Schristos atf_tc_fail("ERROR: primary not accepted %s:%d", MDL);
1706fb29d29Schristos }
1716fb29d29Schristos
1726fb29d29Schristos if (load_balance_mine(&packet, &sstate) != 0) {
1736fb29d29Schristos atf_tc_fail("ERROR: secondary accepted %s:%d", MDL);
1746fb29d29Schristos }
1756fb29d29Schristos
1766fb29d29Schristos /* Large byteswapped timeout, both accepted*/
1776fb29d29Schristos raw.secs = htons(256 * 6);
1786fb29d29Schristos if (load_balance_mine(&packet, &pstate) != 1) {
1796fb29d29Schristos atf_tc_fail("ERROR: primary not accepted %s:%d", MDL);
1806fb29d29Schristos }
1816fb29d29Schristos
1826fb29d29Schristos if (load_balance_mine(&packet, &sstate) != 1) {
1836fb29d29Schristos atf_tc_fail("ERROR: secondary not accepted %s:%d", MDL);
1846fb29d29Schristos }
1856fb29d29Schristos #else
1866fb29d29Schristos atf_tc_skip("failover is disabled");
1876fb29d29Schristos #endif
1886fb29d29Schristos }
1896fb29d29Schristos
1906fb29d29Schristos
ATF_TP_ADD_TCS(tp)1916fb29d29Schristos ATF_TP_ADD_TCS(tp)
1926fb29d29Schristos {
1936fb29d29Schristos ATF_TP_ADD_TC(tp, load_balance);
1946fb29d29Schristos ATF_TP_ADD_TC(tp, load_balance_swap);
1956fb29d29Schristos
1966fb29d29Schristos return (atf_no_error());
1976fb29d29Schristos }
198