From e77e0d76a73d429d67fa93ba42a5406fbcb2766c Mon Sep 17 00:00:00 2001 From: David Cermak Date: Fri, 11 Oct 2024 19:43:04 +0200 Subject: [PATCH] feat(sockutls): Add simple unit test --- components/sock_utils/include/ifaddrs.h | 42 +++++++++- components/sock_utils/src/getnameinfo.c | 7 +- components/sock_utils/src/ifaddrs.c | 1 + .../sock_utils/test/host/CMakeLists.txt | 9 ++ .../sock_utils/test/host/main/CMakeLists.txt | 6 ++ .../test/host/main/idf_component.yml | 5 ++ .../test/host/main/test_sock_utils.cpp | 84 +++++++++++++++++++ .../sock_utils/test/host/sdkconfig.defaults | 7 ++ 8 files changed, 155 insertions(+), 6 deletions(-) create mode 100644 components/sock_utils/test/host/CMakeLists.txt create mode 100644 components/sock_utils/test/host/main/CMakeLists.txt create mode 100644 components/sock_utils/test/host/main/idf_component.yml create mode 100644 components/sock_utils/test/host/main/test_sock_utils.cpp create mode 100644 components/sock_utils/test/host/sdkconfig.defaults diff --git a/components/sock_utils/include/ifaddrs.h b/components/sock_utils/include/ifaddrs.h index e8a0a01f743..a933760a34c 100644 --- a/components/sock_utils/include/ifaddrs.h +++ b/components/sock_utils/include/ifaddrs.h @@ -3,16 +3,40 @@ * * SPDX-License-Identifier: Apache-2.0 */ +#pragma once + +#include "lwip/sockets.h" + #ifndef NI_NUMERICHOST #define NI_NUMERICHOST 0x1 #endif #ifndef IFF_UP -#define IFF_UP 0x1 +#define IFF_UP 0x1 #endif #ifndef IFF_LOOPBACK -#define IFF_LOOPBACK 0x8 +#define IFF_LOOPBACK 0x8 +#endif + +#ifndef NI_NUMERICSERV +#define NI_NUMERICSERV 0x8 +#endif + +#ifndef NI_DGRAM +#define NI_DGRAM 0x00000010 +#endif + +#ifndef EAI_BADFLAGS +#define EAI_BADFLAGS 3 +#endif + +#ifndef AF_UNIX +#define AF_UNIX 1 +#endif + +#ifdef __cplusplus +extern "C" { #endif struct ifaddrs { @@ -25,3 +49,17 @@ struct ifaddrs { int getifaddrs(struct ifaddrs **ifap); void freeifaddrs(struct ifaddrs *ifa); + +#ifdef CONFIG_IDF_TARGET_LINUX +#define getnameinfo lwip_getnameinfo +#endif + +int getnameinfo(const struct sockaddr *addr, socklen_t addrlen, + char *host, socklen_t hostlen, + char *serv, socklen_t servlen, int flags); + +int socketpair(int domain, int type, int protocol, int sv[2]); + +#ifdef __cplusplus +} +#endif diff --git a/components/sock_utils/src/getnameinfo.c b/components/sock_utils/src/getnameinfo.c index 044f97acf0b..3d76f73d104 100644 --- a/components/sock_utils/src/getnameinfo.c +++ b/components/sock_utils/src/getnameinfo.c @@ -3,10 +3,9 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include -#include -#include -#include "net/if.h" +#include +#include "lwip/sockets.h" +#include "lwip/netdb.h" #include "ifaddrs.h" #include "esp_check.h" diff --git a/components/sock_utils/src/ifaddrs.c b/components/sock_utils/src/ifaddrs.c index a109ce6f5fa..5036e0696f8 100644 --- a/components/sock_utils/src/ifaddrs.c +++ b/components/sock_utils/src/ifaddrs.c @@ -40,6 +40,7 @@ int getifaddrs(struct ifaddrs **ifap) esp_netif_ip_info_t ip; esp_netif_t *netif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"); if (netif == NULL) { + free(addr_in); free(ifaddr->ifa_name); free(ifaddr); return -1; diff --git a/components/sock_utils/test/host/CMakeLists.txt b/components/sock_utils/test/host/CMakeLists.txt new file mode 100644 index 00000000000..2609149504a --- /dev/null +++ b/components/sock_utils/test/host/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.16) + +set(COMPONENTS main) + +#list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/mocks/freertos/") + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) + +project(sockutls_host_test) diff --git a/components/sock_utils/test/host/main/CMakeLists.txt b/components/sock_utils/test/host/main/CMakeLists.txt new file mode 100644 index 00000000000..d1c9998ce5b --- /dev/null +++ b/components/sock_utils/test/host/main/CMakeLists.txt @@ -0,0 +1,6 @@ +idf_component_register(SRCS "test_sock_utils.cpp" + INCLUDE_DIRS "$ENV{IDF_PATH}/tools" + WHOLE_ARCHIVE) + +target_compile_options(${COMPONENT_LIB} PUBLIC -fsanitize=address -fconcepts) +target_link_options(${COMPONENT_LIB} PUBLIC -fsanitize=address) diff --git a/components/sock_utils/test/host/main/idf_component.yml b/components/sock_utils/test/host/main/idf_component.yml new file mode 100644 index 00000000000..54750a85bb5 --- /dev/null +++ b/components/sock_utils/test/host/main/idf_component.yml @@ -0,0 +1,5 @@ +dependencies: + espressif/catch2: "^3.4.0" + sock_utils: + version: "*" + override_path: '../../../' diff --git a/components/sock_utils/test/host/main/test_sock_utils.cpp b/components/sock_utils/test/host/main/test_sock_utils.cpp new file mode 100644 index 00000000000..b64f3e1569f --- /dev/null +++ b/components/sock_utils/test/host/main/test_sock_utils.cpp @@ -0,0 +1,84 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "ifaddrs.h" +#include "esp_netif.h" +#include "esp_event.h" +#define CATCH_CONFIG_MAIN +#include "catch2/catch_test_macros.hpp" +#include "catch2/catch_session.hpp" +#include + +static char buffer[64]; + +TEST_CASE("getnameinfo() for IPv4", "[sock_utils]") +{ + struct sockaddr_in sock_addr = {}; + sock_addr.sin_family = AF_INET; + sock_addr.sin_port = 257; // (0x0101: same number for LE and BE) + REQUIRE(getnameinfo((struct sockaddr *)&sock_addr, sizeof(sock_addr), buffer, sizeof(buffer), NULL, 0, NI_NUMERICHOST) == 0); + CHECK(strcmp("0.0.0.0", buffer) == 0); + CHECK(getnameinfo((struct sockaddr *)&sock_addr, sizeof(sock_addr), NULL, 0, buffer, sizeof(buffer), NI_NUMERICSERV) == 0); + CHECK(strcmp("257", buffer) == 0); +} + +TEST_CASE("getnameinfo() for IPv6", "[sock_utils]") +{ + struct sockaddr_in sock_addr = {}; + sock_addr.sin_family = AF_INET6; + // IPv6 not supported for now + CHECK(getnameinfo((struct sockaddr *)&sock_addr, sizeof(sock_addr), buffer, sizeof(buffer), NULL, 0, NI_NUMERICHOST) != 0); +} + +TEST_CASE("getifaddr()", "[sock_utils]") +{ + + struct ifaddrs *addresses, *addr; + REQUIRE(getifaddrs(&addresses) != -1); + addr = addresses; + CHECK(addr != NULL); + int nr_of_addrs = 0; + + while (addr) { + ++nr_of_addrs; + if (addr->ifa_addr && addr->ifa_addr->sa_family == AF_INET) { // look for IP4 addresses + struct sockaddr_in *sock_addr = (struct sockaddr_in *) addr->ifa_addr; + if (getnameinfo((struct sockaddr *)sock_addr, sizeof(*sock_addr), + buffer, sizeof(buffer), NULL, 0, NI_NUMERICHOST) != 0) { + printf("getnameinfo() failed\n"); + } else { + printf("IPv4 address of interface \"%s\": %s\n", addr->ifa_name, buffer); + } + } + addr = addr->ifa_next; + } + // check that we got 1 address with exact content + CHECK(nr_of_addrs == 1); + CHECK(strcmp("1.2.3.4", buffer) == 0); + freeifaddrs(addresses); +} + +extern "C" void app_main(void) +{ + ESP_ERROR_CHECK(esp_netif_init()); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + esp_netif_inherent_config_t base_cfg = ESP_NETIF_INHERENT_DEFAULT_WIFI_STA(); + esp_netif_ip_info_t ip = { }; + ip.ip.addr = ESP_IP4TOADDR(1, 2, 3, 4); + base_cfg.ip_info = &ip; + esp_netif_config_t cfg = { .base = &base_cfg, .driver = NULL, .stack = ESP_NETIF_NETSTACK_DEFAULT_WIFI_STA }; + esp_netif_t *esp_netif = esp_netif_new(&cfg); + + Catch::Session session; + + int failures = session.run(); + if (failures > 0) { + printf("TEST FAILED! number of failures=%d\n", failures); + } else { + printf("Test passed!\n"); + } + esp_netif_destroy(esp_netif); +} diff --git a/components/sock_utils/test/host/sdkconfig.defaults b/components/sock_utils/test/host/sdkconfig.defaults new file mode 100644 index 00000000000..e71578ad1be --- /dev/null +++ b/components/sock_utils/test/host/sdkconfig.defaults @@ -0,0 +1,7 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) 5.4.0 Project Minimal Configuration +# +CONFIG_IDF_TARGET="linux" +CONFIG_COMPILER_CXX_EXCEPTIONS=y +CONFIG_FREERTOS_HZ=1000 +CONFIG_LWIP_ENABLE=y