From aaaffd20a602bd3fa70c9941a5ad74b0670ba651 Mon Sep 17 00:00:00 2001 From: Raffael Rostagno Date: Thu, 5 Sep 2024 14:39:19 -0300 Subject: [PATCH] tests: ethernet: esp32: Functional test for CI Functional test for Ethernet for CI device testing Signed-off-by: Raffael Rostagno --- .../boards/espressif/ethernet/CMakeLists.txt | 9 ++ tests/boards/espressif/ethernet/Kconfig | 20 +++ .../boards/esp32_ethernet_kit_procpu.overlay | 17 ++ tests/boards/espressif/ethernet/prj.conf | 19 +++ tests/boards/espressif/ethernet/src/main.c | 146 ++++++++++++++++++ tests/boards/espressif/ethernet/testcase.yaml | 6 + 6 files changed, 217 insertions(+) create mode 100644 tests/boards/espressif/ethernet/CMakeLists.txt create mode 100644 tests/boards/espressif/ethernet/Kconfig create mode 100644 tests/boards/espressif/ethernet/boards/esp32_ethernet_kit_procpu.overlay create mode 100644 tests/boards/espressif/ethernet/prj.conf create mode 100644 tests/boards/espressif/ethernet/src/main.c create mode 100644 tests/boards/espressif/ethernet/testcase.yaml diff --git a/tests/boards/espressif/ethernet/CMakeLists.txt b/tests/boards/espressif/ethernet/CMakeLists.txt new file mode 100644 index 00000000000..038af7bf3b5 --- /dev/null +++ b/tests/boards/espressif/ethernet/CMakeLists.txt @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(ethernet_test) + +target_include_directories(app PRIVATE ${ZEPHYR_BASE}/subsys/net/ip) +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/boards/espressif/ethernet/Kconfig b/tests/boards/espressif/ethernet/Kconfig new file mode 100644 index 00000000000..e7d074da43d --- /dev/null +++ b/tests/boards/espressif/ethernet/Kconfig @@ -0,0 +1,20 @@ +# Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +mainmenu "Ethernet Test" + +source "Kconfig.zephyr" + +config DHCP_ASSIGN_TIMEOUT + int "DHCP Assign Timeout (in seconds)" + default 30 + help + Timeout duration for receiving IPv4 address from DHCP. + If no address is assigned within this time, test will fail. + +config GATEWAY_PING_TIMEOUT + int "Gateway Ping Timeout (in seconds)" + default 10 + help + Timeout duration for pinging the network gateway. + If no reply is received within this time, test will fail. diff --git a/tests/boards/espressif/ethernet/boards/esp32_ethernet_kit_procpu.overlay b/tests/boards/espressif/ethernet/boards/esp32_ethernet_kit_procpu.overlay new file mode 100644 index 00000000000..33c31c6ab98 --- /dev/null +++ b/tests/boards/espressif/ethernet/boards/esp32_ethernet_kit_procpu.overlay @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +ð { + status = "okay"; +}; + +&phy { + status = "okay"; +}; + +&mdio { + status = "okay"; +}; diff --git a/tests/boards/espressif/ethernet/prj.conf b/tests/boards/espressif/ethernet/prj.conf new file mode 100644 index 00000000000..f568dd121d4 --- /dev/null +++ b/tests/boards/espressif/ethernet/prj.conf @@ -0,0 +1,19 @@ +CONFIG_ZTEST=y + +CONFIG_NETWORKING=y +CONFIG_NET_L2_ETHERNET=y + +CONFIG_NET_IPV6=n +CONFIG_NET_IPV4=y +CONFIG_NET_ARP=y +CONFIG_NET_UDP=y +CONFIG_NET_DHCPV4=y +CONFIG_NET_DHCPV4_OPTION_CALLBACKS=y +CONFIG_DNS_RESOLVER=y + +CONFIG_SYS_HEAP_AUTO=y +CONFIG_INIT_STACKS=y +CONFIG_NET_MGMT=y +CONFIG_NET_MGMT_EVENT=y +CONFIG_NET_LOG=y +CONFIG_LOG=y diff --git a/tests/boards/espressif/ethernet/src/main.c b/tests/boards/espressif/ethernet/src/main.c new file mode 100644 index 00000000000..b64bc946366 --- /dev/null +++ b/tests/boards/espressif/ethernet/src/main.c @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(ethernet_test, LOG_LEVEL_INF); + +#include "net_private.h" + +#define DHCP_OPTION_NTP (42) +#define TEST_DATA "ICMP dummy data" + +K_SEM_DEFINE(net_event, 0, 1); + +static struct net_if *iface; + +static uint8_t ntp_server[4]; +static struct net_mgmt_event_callback mgmt_cb; +static struct net_dhcpv4_option_callback dhcp_cb; + +static void ipv4_event(struct net_mgmt_event_callback *cb, uint32_t mgmt_event, + struct net_if *iface) +{ + if ((mgmt_event != NET_EVENT_IPV4_ADDR_ADD) || + (iface->config.ip.ipv4->unicast[0].ipv4.addr_type != NET_ADDR_DHCP)) { + return; + } + + char buf[NET_IPV4_ADDR_LEN]; + + LOG_INF("Address[%d]: %s", net_if_get_by_iface(iface), + net_addr_ntop(AF_INET, &iface->config.ip.ipv4->unicast[0].ipv4.address.in_addr, buf, + sizeof(buf))); + LOG_INF("Subnet[%d]: %s", net_if_get_by_iface(iface), + net_addr_ntop(AF_INET, &iface->config.ip.ipv4->unicast[0].netmask, buf, + sizeof(buf))); + LOG_INF("Router[%d]: %s", net_if_get_by_iface(iface), + net_addr_ntop(AF_INET, &iface->config.ip.ipv4->gw, buf, sizeof(buf))); + LOG_INF("Lease time[%d]: %u seconds", net_if_get_by_iface(iface), + iface->config.dhcpv4.lease_time); + + /* release processing of IPV4 event by test case */ + k_sem_give(&net_event); +} + +static int icmp_event(struct net_icmp_ctx *ctx, struct net_pkt *pkt, struct net_icmp_ip_hdr *hdr, + struct net_icmp_hdr *icmp_hdr, void *user_data) +{ + struct net_ipv4_hdr *ip_hdr = hdr->ipv4; + + LOG_INF("Received echo reply from %s", net_sprint_ipv4_addr(&ip_hdr->src)); + + k_sem_give(&net_event); + + return 0; +} + +static void option_handler(struct net_dhcpv4_option_callback *cb, size_t length, + enum net_dhcpv4_msg_type msg_type, struct net_if *iface) +{ + char buf[NET_IPV4_ADDR_LEN]; + + LOG_INF("DHCP Option %d: %s", cb->option, + net_addr_ntop(AF_INET, cb->data, buf, sizeof(buf))); +} + +ZTEST(ethernet, test_dhcp_check) +{ + LOG_INF("Waiting for IPV4 assign event..."); + + zassert_equal(k_sem_take(&net_event, K_SECONDS(CONFIG_DHCP_ASSIGN_TIMEOUT)), 0, + "IPV4 address assign event timeout"); + + LOG_INF("DHCP check successful"); +} + +ZTEST(ethernet, test_icmp_check) +{ + struct net_icmp_ping_params params; + struct net_icmp_ctx ctx; + struct in_addr gw_addr_4; + struct sockaddr_in dst4 = {0}; + int ret; + + gw_addr_4 = net_if_ipv4_get_gw(iface); + zassert_not_equal(gw_addr_4.s_addr, 0, "Gateway address is not set"); + + ret = net_icmp_init_ctx(&ctx, NET_ICMPV4_ECHO_REPLY, 0, icmp_event); + zassert_equal(ret, 0, "Cannot init ICMP (%d)", ret); + + dst4.sin_family = AF_INET; + memcpy(&dst4.sin_addr, &gw_addr_4, sizeof(gw_addr_4)); + + params.identifier = 1234; + params.sequence = 5678; + params.tc_tos = 1; + params.priority = 2; + params.data = TEST_DATA; + params.data_size = sizeof(TEST_DATA); + + LOG_INF("Pinging the gateway..."); + + ret = net_icmp_send_echo_request(&ctx, iface, (struct sockaddr *)&dst4, ¶ms, NULL); + zassert_equal(ret, 0, "Cannot send ICMP echo request (%d)", ret); + + zassert_equal(k_sem_take(&net_event, K_SECONDS(CONFIG_GATEWAY_PING_TIMEOUT)), 0, + "Gateway ping (ICMP) timed out"); + + net_icmp_cleanup_ctx(&ctx); +} + +static void *ethernet_setup(void) +{ + iface = net_if_get_first_by_type(&NET_L2_GET_NAME(ETHERNET)); + + net_mgmt_init_event_callback(&mgmt_cb, ipv4_event, NET_EVENT_IPV4_ADDR_ADD); + net_mgmt_add_event_callback(&mgmt_cb); + + net_dhcpv4_init_option_callback(&dhcp_cb, option_handler, DHCP_OPTION_NTP, ntp_server, + sizeof(ntp_server)); + net_dhcpv4_add_option_callback(&dhcp_cb); + + /* reset semaphore that tracks IPV4 assign event */ + k_sem_reset(&net_event); + + LOG_INF("Starting DHCPv4 client on %s: index=%d", net_if_get_device(iface)->name, + net_if_get_by_iface(iface)); + + net_dhcpv4_start(iface); + + return NULL; +} + +ZTEST_SUITE(ethernet, NULL, ethernet_setup, NULL, NULL, NULL); diff --git a/tests/boards/espressif/ethernet/testcase.yaml b/tests/boards/espressif/ethernet/testcase.yaml new file mode 100644 index 00000000000..a963a4088af --- /dev/null +++ b/tests/boards/espressif/ethernet/testcase.yaml @@ -0,0 +1,6 @@ +tests: + boards.esp32.ethernet: + platform_allow: + - esp32_ethernet_kit/esp32/procpu + tags: + - ethernet