diff options
author | Luke T. Shumaker <lukeshu@lukeshu.com> | 2025-05-27 14:42:35 -0400 |
---|---|---|
committer | Luke T. Shumaker <lukeshu@lukeshu.com> | 2025-05-27 19:23:14 -0400 |
commit | 968f7710458f44d5e62d2624461f4e8459c04168 (patch) | |
tree | 241b909f0d68f3c0f355ad924375c2fa5b9a19ae /libdhcp | |
parent | 65534dca5e71cd81070e2e464060f023b9868600 (diff) |
libdhcp: Add a basic smoke-test
Diffstat (limited to 'libdhcp')
-rw-r--r-- | libdhcp/CMakeLists.txt | 6 | ||||
-rw-r--r-- | libdhcp/tests/config.h | 25 | ||||
l--------- | libdhcp/tests/test.h | 1 | ||||
-rw-r--r-- | libdhcp/tests/test_client.c | 118 |
4 files changed, 150 insertions, 0 deletions
diff --git a/libdhcp/CMakeLists.txt b/libdhcp/CMakeLists.txt index 69ad470..f14e46d 100644 --- a/libdhcp/CMakeLists.txt +++ b/libdhcp/CMakeLists.txt @@ -11,4 +11,10 @@ target_sources(libdhcp INTERFACE ) target_link_libraries(libdhcp INTERFACE libmisc + libhw_generic ) + +if (ENABLE_TESTS) + add_lib_test(libdhcp test_client) + target_link_libraries(test_client libcr libhw_cr) +endif() diff --git a/libdhcp/tests/config.h b/libdhcp/tests/config.h new file mode 100644 index 0000000..53079fe --- /dev/null +++ b/libdhcp/tests/config.h @@ -0,0 +1,25 @@ +/* config.h - Compile-time configuration for the libdhcp tests + * + * Copyright (C) 2024-2025 Luke T. Shumaker <lukeshu@lukeshu.com> + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +#ifndef _CONFIG_H_ +#define _CONFIG_H_ + +#define CONFIG_COROUTINE_STACK_SIZE_DEFAULT (16*1024) +#define CONFIG_COROUTINE_NAME_LEN 16 +#define CONFIG_COROUTINE_NUM 16 + +#define CONFIG_COROUTINE_MEASURE_STACK 1 +#define CONFIG_COROUTINE_PROTECT_STACK 1 +#define CONFIG_COROUTINE_DEBUG 1 +#define CONFIG_COROUTINE_VALGRIND 1 +#define CONFIG_COROUTINE_GDB 1 + +#define CONFIG_DHCP_CAN_RECV_UNICAST_IP_WITHOUT_IP 0 /* bool */ +#define CONFIG_DHCP_DEBUG 1 /* bool */ +#define CONFIG_DHCP_OPT_SIZE 312 /* minimum of 312 */ +#define CONFIG_DHCP_SELECTING_NS (5*NS_PER_S) + +#endif /* _CONFIG_H_ */ diff --git a/libdhcp/tests/test.h b/libdhcp/tests/test.h new file mode 120000 index 0000000..2fb1bd5 --- /dev/null +++ b/libdhcp/tests/test.h @@ -0,0 +1 @@ +../../libmisc/tests/test.h
\ No newline at end of file diff --git a/libdhcp/tests/test_client.c b/libdhcp/tests/test_client.c new file mode 100644 index 0000000..90efd01 --- /dev/null +++ b/libdhcp/tests/test_client.c @@ -0,0 +1,118 @@ +/* libdhcp/tests/test_client.c - Tests for libdhcp client + * + * Copyright (C) 2025 Luke T. Shumaker <lukeshu@lukeshu.com> + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +#include <string.h> /* for memcpy() */ + +#include <libcr/coroutine.h> +#include <libhw/generic/net.h> +#include <libhw/host_alarmclock.h> + +#include <libdhcp/client.h> + +#include "test.h" + +/******************************************************************************/ + +struct test_udp { +}; +LO_IMPLEMENTATION_H(io_closer, struct test_udp, test_udp); +LO_IMPLEMENTATION_C(io_closer, struct test_udp, test_udp, static); +LO_IMPLEMENTATION_H(net_packet_conn, struct test_udp, test_udp); +LO_IMPLEMENTATION_C(net_packet_conn, struct test_udp, test_udp, static); + +static ssize_t test_udp_sendto(struct test_udp *LM_UNUSED(self), void *LM_UNUSED(buf), size_t len, struct net_ip4_addr LM_UNUSED(node), uint16_t LM_UNUSED(port)) { + return len; +} + +static ssize_t test_udp_recvfrom(struct test_udp *LM_UNUSED(self), void *buf, size_t len, struct net_ip4_addr *ret_node, uint16_t *ret_port) { + static const uint8_t resp_offer[] = {0x02,0x01,0x06,0x00,0xE8,0x40,0xC6,0x79,0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0xC0,0xA8,0x0A,0x78,0xC0,0xA8,0x0A,0x01,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x82,0x53,0x63,0x35,0x01,0x02,0x36,0x04,0xC0,0xA8,0x0A,0x01,0x33,0x04,0x00,0x00,0xA8,0xC0,0x3A,0x04,0x00,0x00,0x54,0x60,0x3B,0x04,0x00,0x00,0x93,0xA8,0x01,0x04,0xFF,0xFF,0xFF,0x00,0x1C,0x04,0xC0,0xA8,0x0A,0xFF,0x03,0x04,0xC0,0xA8,0x0A,0x01,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + static const uint8_t resp_ack[] = {0x02,0x01,0x06,0x00,0xE8,0x40,0xC6,0x79,0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0xC0,0xA8,0x0A,0x78,0xC0,0xA8,0x0A,0x01,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x82,0x53,0x63,0x35,0x01,0x05,0x36,0x04,0xC0,0xA8,0x0A,0x01,0x33,0x04,0x00,0x00,0xA8,0xC0,0x3A,0x04,0x00,0x00,0x54,0x60,0x3B,0x04,0x00,0x00,0x93,0xA8,0x01,0x04,0xFF,0xFF,0xFF,0x00,0x1C,0x04,0xC0,0xA8,0x0A,0xFF,0x03,0x04,0xC0,0xA8,0x0A,0x01,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + + static unsigned cnt = 0; + const void *resp; + size_t resp_len; + switch (cnt++) { + case 0: resp = resp_offer; resp_len = sizeof(resp_offer); break; + case 1: resp = resp_ack; resp_len = sizeof(resp_ack); break; + default: return -NET_ERECV_TIMEOUT; + } + test_assert(len >= resp_len); + memcpy(buf, resp, resp_len); + *ret_node = ((struct net_ip4_addr){{192,168,10,1}}); + *ret_port = 67; + return resp_len; +} + +static void test_udp_set_recv_deadline(struct test_udp *LM_UNUSED(self), uint64_t LM_UNUSED(ns_since_boot)) { + /* Do nothing? */ +} + +static int test_udp_close(struct test_udp *LM_UNUSED(self)) { + assert_notreached("not implemented"); +} + +/******************************************************************************/ + +struct test_iface { + struct net_iface_config cfg; + + struct test_udp conn; +}; +LO_IMPLEMENTATION_H(net_iface, struct test_iface, test); +LO_IMPLEMENTATION_C(net_iface, struct test_iface, test, static); + +static struct net_eth_addr test_hwaddr(struct test_iface *LM_UNUSED(self)) { + struct net_eth_addr ret = {{1, 2, 3, 4, 5, 6}}; + return ret; +} + +static void test_ifup(struct test_iface *LM_UNUSED(self), struct net_iface_config LM_UNUSED(cfg)) { + cr_exit(); +} + +static void test_ifdown(struct test_iface *LM_UNUSED(self)) { + assert_notreached("not implemented"); +} + +static bool test_arp_ping(struct test_iface *LM_UNUSED(self), struct net_ip4_addr LM_UNUSED(addr)) { + return false; +} + +static lo_interface net_stream_listener test_tcp_listen(struct test_iface *LM_UNUSED(self), uint16_t LM_UNUSED(local_port)) { + assert_notreached("not implemented"); +} + +static lo_interface net_stream_conn test_tcp_dial(struct test_iface *LM_UNUSED(self), struct net_ip4_addr LM_UNUSED(remote_node), uint16_t LM_UNUSED(remote_port)) { + assert_notreached("not implemented"); +} + +static lo_interface net_packet_conn test_udp_conn(struct test_iface *self, uint16_t local_port) { + bool once = false; + test_assert(local_port == 68); + test_assert(!once); + once = true; + return lo_box_test_udp_as_net_packet_conn(&self->conn); +} + +/******************************************************************************/ + +COROUTINE dhcp_cr(void *) { + cr_begin(); + struct test_iface iface = {}; + dhcp_client_main(lo_box_test_as_net_iface(&iface), "test-client"); + cr_end(); +} + +int main() { + struct hostclock clock_monotonic = { + .clock_id = CLOCK_MONOTONIC, + }; + bootclock = lo_box_hostclock_as_alarmclock(&clock_monotonic); + + coroutine_add("dhcp", dhcp_cr, NULL); + coroutine_main(); + return 0; +} |