diff --git a/components/esp_netif/Kconfig b/components/esp_netif/Kconfig index 7704a2959a..1c3f111e17 100644 --- a/components/esp_netif/Kconfig +++ b/components/esp_netif/Kconfig @@ -13,9 +13,18 @@ menu "ESP NETIF Adapter" the timer expires. The IP lost timer is stopped if the station get the IP again before the timer expires. + config ESP_NETIF_PROVIDE_CUSTOM_IMPLEMENTATION + bool "Use only ESP-NETIF headers" + default n + help + No implementation of ESP-NETIF functions is provided. + This option is used for adding a custom TCP/IP stack and defining related + esp_netif functionality + choice ESP_NETIF_USE_TCPIP_STACK_LIB prompt "TCP/IP Stack Library" default ESP_NETIF_TCPIP_LWIP + depends on !ESP_NETIF_PROVIDE_CUSTOM_IMPLEMENTATION help Choose the TCP/IP Stack to work, for example, LwIP, uIP, etc. config ESP_NETIF_TCPIP_LWIP diff --git a/components/esp_netif/loopback/esp_netif_loopback.c b/components/esp_netif/loopback/esp_netif_loopback.c index e3687f6195..28fd7cabab 100644 --- a/components/esp_netif/loopback/esp_netif_loopback.c +++ b/components/esp_netif/loopback/esp_netif_loopback.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -465,4 +465,23 @@ esp_err_t esp_netif_remove_ip6_address(esp_netif_t *esp_netif, const esp_ip6_add return ESP_ERR_NOT_SUPPORTED; } +int esp_netif_get_all_ip6(esp_netif_t *esp_netif, esp_ip6_addr_t if_ip6[]) +{ + return 0; +} + +esp_ip6_addr_type_t esp_netif_ip6_get_addr_type(esp_ip6_addr_t* ip6_addr) +{ + return ESP_IP6_ADDR_IS_UNKNOWN; +} + +esp_err_t esp_netif_tcpip_exec(esp_netif_callback_fn fn, void*ctx) +{ + return fn(ctx); +} + +esp_netif_t *esp_netif_get_handle_from_ifkey(const char *if_key) +{ + return esp_netif_get_handle_from_ifkey_unsafe(if_key); +} #endif /* CONFIG_ESP_NETIF_LOOPBACK */ diff --git a/components/esp_netif/test_apps/test_app_esp_netif/main/CMakeLists.txt b/components/esp_netif/test_apps/test_app_esp_netif/main/CMakeLists.txt index cd1df185c2..e2354e125e 100644 --- a/components/esp_netif/test_apps/test_app_esp_netif/main/CMakeLists.txt +++ b/components/esp_netif/test_apps/test_app_esp_netif/main/CMakeLists.txt @@ -1,5 +1,11 @@ -idf_component_register(SRCS "esp_netif_test.c" - REQUIRES test_utils - INCLUDE_DIRS "." - PRIV_INCLUDE_DIRS "$ENV{IDF_PATH}/components/esp_netif/private_include" "." - PRIV_REQUIRES unity esp_netif nvs_flash esp_wifi) +if(CONFIG_ESP_NETIF_TCPIP_LWIP) + set(srcs_test_stack esp_netif_test_lwip.c) +elseif(CONFIG_ESP_NETIF_LOOPBACK) + set(srcs_test_stack esp_netif_test_loopback.c) +endif() + +idf_component_register(SRCS esp_netif_test.c ${srcs_test_stack} + REQUIRES test_utils + INCLUDE_DIRS "." + PRIV_INCLUDE_DIRS "$ENV{IDF_PATH}/components/esp_netif/private_include" "." + PRIV_REQUIRES unity esp_netif nvs_flash esp_wifi) diff --git a/components/esp_netif/test_apps/test_app_esp_netif/main/esp_netif_test.c b/components/esp_netif/test_apps/test_app_esp_netif/main/esp_netif_test.c index 080f565ec5..c8ba023ab4 100644 --- a/components/esp_netif/test_apps/test_app_esp_netif/main/esp_netif_test.c +++ b/components/esp_netif/test_apps/test_app_esp_netif/main/esp_netif_test.c @@ -18,99 +18,10 @@ #include "memory_checks.h" #include "lwip/netif.h" -TEST_GROUP(esp_netif); - -TEST_SETUP(esp_netif) -{ - test_utils_record_free_mem(); - TEST_ESP_OK(test_utils_set_leak_level(0, ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_GENERAL)); -} - -TEST_TEAR_DOWN(esp_netif) -{ - test_utils_finish_and_evaluate_leaks(test_utils_get_leak_level(ESP_LEAK_TYPE_WARNING, ESP_COMP_LEAK_ALL), - test_utils_get_leak_level(ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_ALL)); -} - -TEST(esp_netif, init_and_destroy) -{ - esp_netif_config_t cfg = ESP_NETIF_DEFAULT_WIFI_STA(); - esp_netif_t *esp_netif = esp_netif_new(NULL); - - TEST_ASSERT_EQUAL(NULL, esp_netif); - esp_netif = esp_netif_new(&cfg); - TEST_ASSERT_NOT_EQUAL(NULL, esp_netif); - - esp_netif_destroy(esp_netif); -} - -TEST(esp_netif, init_and_destroy_sntp) -{ - esp_sntp_config_t config = ESP_NETIF_SNTP_DEFAULT_CONFIG("127.0.0.1"); - config.start = false; - TEST_ESP_OK(esp_netif_sntp_init(&config)); - // Cannot initialize multiple times - TEST_ASSERT_NOT_EQUAL(ESP_OK, esp_netif_sntp_init(&config)); - // Try again to see that the state didn't change - TEST_ASSERT_NOT_EQUAL(ESP_OK, esp_netif_sntp_init(&config)); - esp_netif_sntp_deinit(); - - // Can initialize again once it's destroyed - TEST_ESP_OK(esp_netif_sntp_init(&config)); - - // Test the reachability API - size_t reachability = 0; - // Invalid state is expected since SNTP service didn't start - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, esp_netif_sntp_reachability(0, &reachability)); - esp_netif_sntp_deinit(); -} - -TEST(esp_netif, convert_ip_addresses) -{ - const char *ipv4_src[] = {"127.168.1.1", "255.255.255.0", "305.500.721.801", "127.168.1..", "abc.def.***.ddd"}; - esp_ip4_addr_t ipv4; - TEST_ASSERT_EQUAL(ESP_OK, esp_netif_str_to_ip4(ipv4_src[0], &ipv4)); - TEST_ASSERT_EQUAL(ipv4.addr, ESP_IP4TOADDR(127, 168, 1, 1)); - TEST_ASSERT_EQUAL(ESP_OK, esp_netif_str_to_ip4(ipv4_src[1], &ipv4)); - TEST_ASSERT_EQUAL(ipv4.addr, ESP_IP4TOADDR(255, 255, 255, 0)); - TEST_ASSERT_NOT_EQUAL(ESP_OK, esp_netif_str_to_ip4(ipv4_src[2], &ipv4)); - TEST_ASSERT_NOT_EQUAL(ESP_OK, esp_netif_str_to_ip4(ipv4_src[3], &ipv4)); - TEST_ASSERT_NOT_EQUAL(ESP_OK, esp_netif_str_to_ip4(ipv4_src[4], &ipv4)); - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_netif_str_to_ip4(NULL, &ipv4)); - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_netif_str_to_ip4(ipv4_src[0], NULL)); - - const char *ipv6_src[] = {"127:168:6:8:188:65:1:0", "255:255:255:0:0:0:65:56", "305:500:721:888:777:458:555:666", "EFGH.127:168::55"}; - esp_ip6_addr_t ipv6; - TEST_ASSERT_EQUAL(ESP_OK, esp_netif_str_to_ip6(ipv6_src[0], &ipv6)); - TEST_ASSERT_EQUAL(ESP_OK, esp_netif_str_to_ip6(ipv6_src[1], &ipv6)); - TEST_ASSERT_EQUAL(ESP_OK, esp_netif_str_to_ip6(ipv6_src[2], &ipv6)); - TEST_ASSERT_NOT_EQUAL(ESP_OK, esp_netif_str_to_ip6(ipv6_src[3], &ipv6)); - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_netif_str_to_ip6(NULL, &ipv6)); - TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_netif_str_to_ip6(ipv6_src[0], NULL)); -} - -TEST(esp_netif, get_from_if_key) -{ - // init default netif - esp_netif_config_t cfg = ESP_NETIF_DEFAULT_WIFI_STA(); - esp_netif_t *esp_netif = esp_netif_new(&cfg); - TEST_ASSERT_NOT_NULL(esp_netif); - - // check it's accessible by key - TEST_ASSERT_EQUAL(esp_netif, esp_netif_get_handle_from_ifkey("WIFI_STA_DEF")); - - // destroy it - esp_netif_destroy(esp_netif); - - // check it's also destroyed in list - TEST_ASSERT_EQUAL(NULL, esp_netif_get_handle_from_ifkey("WIFI_STA_DEF")); - -} - -// This is a private esp-netif API, but include here to test it +//// This is a private esp-netif API, but include here to test it bool esp_netif_is_netif_listed(esp_netif_t *esp_netif); -TEST(esp_netif, create_delete_multiple_netifs) +void create_delete_multiple_netifs(void) { // interface key has to be a unique identifier const char* if_keys[] = { "if1", "if2", "if3", "if4", "if5", "if6", "if7", "if8", "if9" }; @@ -139,477 +50,23 @@ TEST(esp_netif, create_delete_multiple_netifs) esp_netif_destroy(netifs[i]); TEST_ASSERT_FALSE(esp_netif_is_netif_listed(netifs[i])); } - } -static bool desc_matches_with(esp_netif_t *netif, void *ctx) + +void get_from_if_key(void) { - return strcmp(ctx, esp_netif_get_desc(netif)) == 0; -} - -TEST(esp_netif, find_netifs) -{ - // Create some interfaces - const char* if_keys[] = { "if1", "if2", "if3", "if4", "if5"}; - const int nr_of_netifs = sizeof(if_keys)/sizeof(char*); - esp_netif_t *netifs[nr_of_netifs]; - - for (int i=0; i max_prio_i ? 0 : i }; - esp_netif_config_t cfg = { .base = &base_netif_config, - .stack = ESP_NETIF_NETSTACK_DEFAULT_WIFI_STA, - .driver = &driver_config }; - netifs[i] = esp_netif_new(&cfg); - TEST_ASSERT_NOT_NULL(netifs[i]); - // set the interface up and connected -- to enable the default netif based on route_prio - esp_netif_action_start(netifs[i], 0, 0, 0); - esp_netif_action_connected(netifs[i], 0, 0, 0); - } - // route_prio increases with index until max_prio_i -> check this is the default netif - TEST_ASSERT_EQUAL_PTR(esp_netif_get_netif_impl(netifs[max_prio_i]), netif_default); - // now we stop the max_prio netif and check the default is on the previous index (max_prio-1) - esp_netif_action_stop(netifs[max_prio_i], 0, 0, 0); - TEST_ASSERT_EQUAL_PTR(esp_netif_get_netif_impl(netifs[max_prio_i - 1]), netif_default); - - // now we override the default netif with API (which has route_prio == 0) - int override_prio_i = nr_of_netifs - 1; // last netif to be set-default manually - esp_netif_set_default_netif(netifs[override_prio_i]); - // check the configured netif is default - TEST_ASSERT_EQUAL_PTR(esp_netif_get_netif_impl(netifs[override_prio_i]), netif_default); - // try to start/connect the previously stopped netif with max_prio - esp_netif_action_start(netifs[max_prio_i], 0, 0, 0); - esp_netif_action_connected(netifs[max_prio_i], 0, 0, 0); - // and check the configured netif is still the default - TEST_ASSERT_EQUAL_PTR(esp_netif_get_netif_impl(netifs[override_prio_i]), netif_default); - // we destroy the configured default netif - esp_netif_destroy(netifs[override_prio_i]); - // ...and check the max-prio netif is default now - TEST_ASSERT_EQUAL_PTR(esp_netif_get_netif_impl(netifs[max_prio_i]), netif_default); - // stop the max_prio netif, to see the auto-default still works - esp_netif_action_stop(netifs[max_prio_i], 0, 0, 0); - // ...so the current default is on (max_prio-1) - TEST_ASSERT_EQUAL_PTR(esp_netif_get_netif_impl(netifs[max_prio_i - 1]), netif_default); - // destroy one by one and check it's been removed - for (int i=0; i < override_prio_i; ++i) { - esp_netif_destroy(netifs[i]); - TEST_ASSERT_FALSE(esp_netif_is_netif_listed(netifs[i])); - } -} - -// to probe DNS server info directly in LWIP -const ip_addr_t * dns_getserver(u8_t numdns); - -TEST(esp_netif, set_get_dnsserver) -{ - // create a couple of netifs - test_case_uses_tcpip(); - const char *if_keys[] = {"if0", "if1", "if2", "if3", "if4", "if5", "if6", "if7", "if8", "if9"}; - const int nr_of_netifs = sizeof(if_keys) / sizeof(char *); - esp_netif_t *netifs[nr_of_netifs]; - esp_netif_driver_ifconfig_t driver_config = { .handle = (void*)1, .transmit = dummy_transmit }; - // create 10 netifs with different route prio - for (int i = 0; i < nr_of_netifs; ++i) { - esp_netif_inherent_config_t base_netif_config = { .if_key = if_keys[i], .route_prio = i }; - esp_netif_config_t cfg = { .base = &base_netif_config, - .stack = ESP_NETIF_NETSTACK_DEFAULT_WIFI_STA, - .driver = &driver_config }; - netifs[i] = esp_netif_new(&cfg); - TEST_ASSERT_NOT_NULL(netifs[i]); - // set the interface up and connected -- to enable the default netif based on route_prio - esp_netif_action_start(netifs[i], 0, 0, 0); - esp_netif_action_connected(netifs[i], 0, 0, 0); - } - - esp_netif_dns_info_t dns[2]; - esp_netif_dns_info_t get_dns; - TEST_ASSERT_EQUAL(ESP_OK, esp_netif_str_to_ip4("1.2.3.4", &dns[0].ip.u_addr.ip4)); - TEST_ASSERT_EQUAL(ESP_OK, esp_netif_str_to_ip4("5.6.7.8", &dns[1].ip.u_addr.ip4)); - - // set DNS info to one netif - TEST_ASSERT_EQUAL(ESP_OK, esp_netif_set_dns_info(netifs[3], ESP_NETIF_DNS_MAIN, &dns[0])); - TEST_ASSERT_EQUAL(ESP_OK, esp_netif_set_dns_info(netifs[3], ESP_NETIF_DNS_BACKUP, &dns[1])); -#ifndef CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF - // check that calling setters/getters with 'esp_netif==NULL' is invalid - TEST_ASSERT_NOT_EQUAL(ESP_OK, esp_netif_set_dns_info(NULL, ESP_NETIF_DNS_BACKUP, &dns[1])); - TEST_ASSERT_NOT_EQUAL(ESP_OK, esp_netif_get_dns_info(NULL, ESP_NETIF_DNS_BACKUP, &get_dns)); - - // check that the global DNS is configured the same way - const ip_addr_t *ip = dns_getserver(0); - TEST_ASSERT_EQUAL(ip->u_addr.ip4.addr, dns[0].ip.u_addr.ip4.addr); - ip = dns_getserver(1); - TEST_ASSERT_EQUAL(ip->u_addr.ip4.addr, dns[1].ip.u_addr.ip4.addr); - - // check that we get the same DNS information for all netifs - for (int i=0; i < nr_of_netifs; ++i) { - TEST_ASSERT_EQUAL(ESP_OK, esp_netif_get_dns_info(netifs[i], ESP_NETIF_DNS_MAIN, &get_dns)); - TEST_ASSERT_EQUAL(get_dns.ip.u_addr.ip4.addr, dns[0].ip.u_addr.ip4.addr); - TEST_ASSERT_EQUAL(ESP_OK, esp_netif_get_dns_info(netifs[i], ESP_NETIF_DNS_BACKUP, &get_dns)); - TEST_ASSERT_EQUAL(get_dns.ip.u_addr.ip4.addr, dns[1].ip.u_addr.ip4.addr); - } -#else - // check that calling setters/getters with 'esp_netif==NULL' is valid, they set/get global DNS servers - TEST_ASSERT_EQUAL(ESP_OK, esp_netif_set_dns_info(NULL, ESP_NETIF_DNS_MAIN, &dns[0])); - TEST_ASSERT_EQUAL(ESP_OK, esp_netif_get_dns_info(NULL, ESP_NETIF_DNS_BACKUP, &get_dns)); - const ip_addr_t *ip = dns_getserver(0); - TEST_ASSERT_EQUAL(ip->u_addr.ip4.addr, dns[0].ip.u_addr.ip4.addr); - ip = dns_getserver(1); - TEST_ASSERT_EQUAL(ip->u_addr.ip4.addr, get_dns.ip.u_addr.ip4.addr); // same as what we got at the esp-netif layer - TEST_ASSERT_NOT_EQUAL(ip->u_addr.ip4.addr, dns[1].ip.u_addr.ip4.addr); // but different from what we set earlier per netif - - // now we set the netif[3] as default one and check again - esp_netif_set_default_netif(netifs[3]); - ip = dns_getserver(1); - TEST_ASSERT_EQUAL(ip->u_addr.ip4.addr, dns[1].ip.u_addr.ip4.addr); // now the ESP_NETIF_DNS_BACKUP[3[ should be set globally - - // check that we get a different DNS server with another netif - TEST_ASSERT_EQUAL(ESP_OK, esp_netif_get_dns_info(netifs[5], ESP_NETIF_DNS_MAIN, &get_dns)); - TEST_ASSERT_NOT_EQUAL(dns[0].ip.u_addr.ip4.addr, get_dns.ip.u_addr.ip4.addr); -#endif - - for (int i=0; i < nr_of_netifs; ++i) { - esp_netif_destroy(netifs[i]); - TEST_ASSERT_FALSE(esp_netif_is_netif_listed(netifs[i])); - } -} - -TEST_GROUP_RUNNER(esp_netif) -{ - /** - * Keep the tests that don't need to start TCP/IP stack first, when the leak checker - * is more strict with leak level set to 0 - */ - RUN_TEST_CASE(esp_netif, init_and_destroy) - RUN_TEST_CASE(esp_netif, init_and_destroy_sntp) - RUN_TEST_CASE(esp_netif, convert_ip_addresses) - RUN_TEST_CASE(esp_netif, get_from_if_key) - RUN_TEST_CASE(esp_netif, create_delete_multiple_netifs) - RUN_TEST_CASE(esp_netif, find_netifs) -#ifdef CONFIG_ESP_WIFI_ENABLED - RUN_TEST_CASE(esp_netif, create_custom_wifi_interfaces) - RUN_TEST_CASE(esp_netif, create_destroy_default_wifi) -#endif - /** - * After follow tests which start lwIP and thus expect some mem-leaks by TCP/IP stack - */ -#ifdef CONFIG_ESP_WIFI_ENABLED - RUN_TEST_CASE(esp_netif, get_set_hostname) - RUN_TEST_CASE(esp_netif, dhcp_client_state_transitions_wifi_sta) -#endif -#if defined(CONFIG_ESP_WIFI_ENABLED) && defined(CONFIG_ESP_WIFI_SOFTAP_SUPPORT) - RUN_TEST_CASE(esp_netif, dhcp_server_state_transitions_wifi_ap) - RUN_TEST_CASE(esp_netif, dhcp_server_state_transitions_mesh) -#endif - RUN_TEST_CASE(esp_netif, route_priority) - RUN_TEST_CASE(esp_netif, set_get_dnsserver) -} - -void app_main(void) -{ - UNITY_MAIN(esp_netif); + + // check it's also destroyed in list + TEST_ASSERT_EQUAL(NULL, esp_netif_get_handle_from_ifkey("WIFI_STA_DEF")); + } diff --git a/components/esp_netif/test_apps/test_app_esp_netif/main/esp_netif_test.h b/components/esp_netif/test_apps/test_app_esp_netif/main/esp_netif_test.h new file mode 100644 index 0000000000..716e88188b --- /dev/null +++ b/components/esp_netif/test_apps/test_app_esp_netif/main/esp_netif_test.h @@ -0,0 +1,14 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#pragma once + +#include "unity.h" +#include "unity_fixture.h" +#include "esp_netif.h" + +// List of tests that are common for both configurations +void create_delete_multiple_netifs(void); +void get_from_if_key(void); diff --git a/components/esp_netif/test_apps/test_app_esp_netif/main/esp_netif_test_loopback.c b/components/esp_netif/test_apps/test_app_esp_netif/main/esp_netif_test_loopback.c new file mode 100644 index 0000000000..1465b4423a --- /dev/null +++ b/components/esp_netif/test_apps/test_app_esp_netif/main/esp_netif_test_loopback.c @@ -0,0 +1,49 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#include +#include +#include "unity.h" +#include "unity_fixture.h" +#include "esp_netif.h" +#include "memory_checks.h" +#include "esp_netif_test.h" + +TEST_GROUP(esp_netif); + +TEST_SETUP(esp_netif) +{ + test_utils_record_free_mem(); + TEST_ESP_OK(test_utils_set_leak_level(0, ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_GENERAL)); +} + +TEST_TEAR_DOWN(esp_netif) +{ + test_utils_finish_and_evaluate_leaks(test_utils_get_leak_level(ESP_LEAK_TYPE_WARNING, ESP_COMP_LEAK_ALL), + test_utils_get_leak_level(ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_ALL)); +} + +TEST(esp_netif, create_delete_multiple_netifs) +{ + create_delete_multiple_netifs(); +} + +TEST(esp_netif, get_from_if_key) +{ + get_from_if_key(); +} + +TEST_GROUP_RUNNER(esp_netif) +{ + RUN_TEST_CASE(esp_netif, create_delete_multiple_netifs) + RUN_TEST_CASE(esp_netif, get_from_if_key) +} + +void app_main(void) +{ + UNITY_MAIN(esp_netif); +} + +const esp_netif_netstack_config_t *_g_esp_netif_netstack_default_wifi_sta = (esp_netif_netstack_config_t*)1; diff --git a/components/esp_netif/test_apps/test_app_esp_netif/main/esp_netif_test_lwip.c b/components/esp_netif/test_apps/test_app_esp_netif/main/esp_netif_test_lwip.c new file mode 100644 index 0000000000..6fe84750b4 --- /dev/null +++ b/components/esp_netif/test_apps/test_app_esp_netif/main/esp_netif_test_lwip.c @@ -0,0 +1,606 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +#include +#include +#include "unity.h" +#include "unity_fixture.h" +#include "esp_netif.h" +#include "esp_netif_sntp.h" +#include "esp_netif_net_stack.h" +#include "esp_wifi.h" +#include "nvs_flash.h" +#include "esp_wifi_netif.h" +#include "sdkconfig.h" +#include "test_utils.h" +#include "memory_checks.h" +#include "lwip/netif.h" +#include "esp_netif_test.h" + +TEST_GROUP(esp_netif); + +TEST_SETUP(esp_netif) +{ + test_utils_record_free_mem(); + TEST_ESP_OK(test_utils_set_leak_level(0, ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_GENERAL)); +} + +TEST_TEAR_DOWN(esp_netif) +{ + test_utils_finish_and_evaluate_leaks(test_utils_get_leak_level(ESP_LEAK_TYPE_WARNING, ESP_COMP_LEAK_ALL), + test_utils_get_leak_level(ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_ALL)); +} + +TEST(esp_netif, init_and_destroy) +{ + esp_netif_config_t cfg = ESP_NETIF_DEFAULT_WIFI_STA(); + esp_netif_t *esp_netif = esp_netif_new(NULL); + + TEST_ASSERT_EQUAL(NULL, esp_netif); + esp_netif = esp_netif_new(&cfg); + TEST_ASSERT_NOT_EQUAL(NULL, esp_netif); + + esp_netif_destroy(esp_netif); +} + +TEST(esp_netif, init_and_destroy_sntp) +{ + esp_sntp_config_t config = ESP_NETIF_SNTP_DEFAULT_CONFIG("127.0.0.1"); + config.start = false; + TEST_ESP_OK(esp_netif_sntp_init(&config)); + // Cannot initialize multiple times + TEST_ASSERT_NOT_EQUAL(ESP_OK, esp_netif_sntp_init(&config)); + // Try again to see that the state didn't change + TEST_ASSERT_NOT_EQUAL(ESP_OK, esp_netif_sntp_init(&config)); + esp_netif_sntp_deinit(); + + // Can initialize again once it's destroyed + TEST_ESP_OK(esp_netif_sntp_init(&config)); + + // Test the reachability API + size_t reachability = 0; + // Invalid state is expected since SNTP service didn't start + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_STATE, esp_netif_sntp_reachability(0, &reachability)); + esp_netif_sntp_deinit(); +} + +TEST(esp_netif, convert_ip_addresses) +{ + const char *ipv4_src[] = {"127.168.1.1", "255.255.255.0", "305.500.721.801", "127.168.1..", "abc.def.***.ddd"}; + esp_ip4_addr_t ipv4; + TEST_ASSERT_EQUAL(ESP_OK, esp_netif_str_to_ip4(ipv4_src[0], &ipv4)); + TEST_ASSERT_EQUAL(ipv4.addr, ESP_IP4TOADDR(127, 168, 1, 1)); + TEST_ASSERT_EQUAL(ESP_OK, esp_netif_str_to_ip4(ipv4_src[1], &ipv4)); + TEST_ASSERT_EQUAL(ipv4.addr, ESP_IP4TOADDR(255, 255, 255, 0)); + TEST_ASSERT_NOT_EQUAL(ESP_OK, esp_netif_str_to_ip4(ipv4_src[2], &ipv4)); + TEST_ASSERT_NOT_EQUAL(ESP_OK, esp_netif_str_to_ip4(ipv4_src[3], &ipv4)); + TEST_ASSERT_NOT_EQUAL(ESP_OK, esp_netif_str_to_ip4(ipv4_src[4], &ipv4)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_netif_str_to_ip4(NULL, &ipv4)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_netif_str_to_ip4(ipv4_src[0], NULL)); + + const char *ipv6_src[] = {"127:168:6:8:188:65:1:0", "255:255:255:0:0:0:65:56", "305:500:721:888:777:458:555:666", "EFGH.127:168::55"}; + esp_ip6_addr_t ipv6; + TEST_ASSERT_EQUAL(ESP_OK, esp_netif_str_to_ip6(ipv6_src[0], &ipv6)); + TEST_ASSERT_EQUAL(ESP_OK, esp_netif_str_to_ip6(ipv6_src[1], &ipv6)); + TEST_ASSERT_EQUAL(ESP_OK, esp_netif_str_to_ip6(ipv6_src[2], &ipv6)); + TEST_ASSERT_NOT_EQUAL(ESP_OK, esp_netif_str_to_ip6(ipv6_src[3], &ipv6)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_netif_str_to_ip6(NULL, &ipv6)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_netif_str_to_ip6(ipv6_src[0], NULL)); +} + +TEST(esp_netif, get_from_if_key) +{ + get_from_if_key(); +} + +// This is a private esp-netif API, but include here to test it +bool esp_netif_is_netif_listed(esp_netif_t *esp_netif); + +TEST(esp_netif, create_delete_multiple_netifs) +{ + create_delete_multiple_netifs(); +} + +static bool desc_matches_with(esp_netif_t *netif, void *ctx) +{ + return strcmp(ctx, esp_netif_get_desc(netif)) == 0; +} + +/* + * This test validates esp_netif_find_if() API by searching in the list of netifs + * by their description using the predicate function desc_matches_with() above. + * These netifs have the same key and description, so we can use esp_netif_get_handle_from_ifkey() + * to validate the test. + */ +TEST(esp_netif, find_netifs) +{ + // Create some interfaces + const char* if_keys[] = { "if1", "if2", "if3", "if4", "if5"}; + const int nr_of_netifs = sizeof(if_keys)/sizeof(char*); + esp_netif_t *netifs[nr_of_netifs]; + + for (int i=0; i max_prio_i ? 0 : i }; + esp_netif_config_t cfg = { .base = &base_netif_config, + .stack = ESP_NETIF_NETSTACK_DEFAULT_WIFI_STA, + .driver = &driver_config }; + netifs[i] = esp_netif_new(&cfg); + TEST_ASSERT_NOT_NULL(netifs[i]); + // set the interface up and connected -- to enable the default netif based on route_prio + esp_netif_action_start(netifs[i], 0, 0, 0); + esp_netif_action_connected(netifs[i], 0, 0, 0); + } + // route_prio increases with index until max_prio_i -> check this is the default netif + TEST_ASSERT_EQUAL_PTR(esp_netif_get_netif_impl(netifs[max_prio_i]), netif_default); + // now we stop the max_prio netif and check the default is on the previous index (max_prio-1) + esp_netif_action_stop(netifs[max_prio_i], 0, 0, 0); + TEST_ASSERT_EQUAL_PTR(esp_netif_get_netif_impl(netifs[max_prio_i - 1]), netif_default); + + // now we override the default netif with API (which has route_prio == 0) + int override_prio_i = nr_of_netifs - 1; // last netif to be set-default manually + esp_netif_set_default_netif(netifs[override_prio_i]); + // check the configured netif is default + TEST_ASSERT_EQUAL_PTR(esp_netif_get_netif_impl(netifs[override_prio_i]), netif_default); + // try to start/connect the previously stopped netif with max_prio + esp_netif_action_start(netifs[max_prio_i], 0, 0, 0); + esp_netif_action_connected(netifs[max_prio_i], 0, 0, 0); + // and check the configured netif is still the default + TEST_ASSERT_EQUAL_PTR(esp_netif_get_netif_impl(netifs[override_prio_i]), netif_default); + // we destroy the configured default netif + esp_netif_destroy(netifs[override_prio_i]); + // ...and check the max-prio netif is default now + TEST_ASSERT_EQUAL_PTR(esp_netif_get_netif_impl(netifs[max_prio_i]), netif_default); + // stop the max_prio netif, to see the auto-default still works + esp_netif_action_stop(netifs[max_prio_i], 0, 0, 0); + // ...so the current default is on (max_prio-1) + TEST_ASSERT_EQUAL_PTR(esp_netif_get_netif_impl(netifs[max_prio_i - 1]), netif_default); + // destroy one by one and check it's been removed + for (int i=0; i < override_prio_i; ++i) { + esp_netif_destroy(netifs[i]); + TEST_ASSERT_FALSE(esp_netif_is_netif_listed(netifs[i])); + } +} + +// to probe DNS server info directly in LWIP +const ip_addr_t * dns_getserver(u8_t numdns); + +TEST(esp_netif, set_get_dnsserver) +{ + // create a couple of netifs + test_case_uses_tcpip(); + const char *if_keys[] = {"if0", "if1", "if2", "if3", "if4", "if5", "if6", "if7", "if8", "if9"}; + const int nr_of_netifs = sizeof(if_keys) / sizeof(char *); + esp_netif_t *netifs[nr_of_netifs]; + esp_netif_driver_ifconfig_t driver_config = { .handle = (void*)1, .transmit = dummy_transmit }; + // create 10 netifs with different route prio + for (int i = 0; i < nr_of_netifs; ++i) { + esp_netif_inherent_config_t base_netif_config = { .if_key = if_keys[i], .route_prio = i }; + esp_netif_config_t cfg = { .base = &base_netif_config, + .stack = ESP_NETIF_NETSTACK_DEFAULT_WIFI_STA, + .driver = &driver_config }; + netifs[i] = esp_netif_new(&cfg); + TEST_ASSERT_NOT_NULL(netifs[i]); + // set the interface up and connected -- to enable the default netif based on route_prio + esp_netif_action_start(netifs[i], 0, 0, 0); + esp_netif_action_connected(netifs[i], 0, 0, 0); + } + + esp_netif_dns_info_t dns[2]; + esp_netif_dns_info_t get_dns; + TEST_ASSERT_EQUAL(ESP_OK, esp_netif_str_to_ip4("1.2.3.4", &dns[0].ip.u_addr.ip4)); + TEST_ASSERT_EQUAL(ESP_OK, esp_netif_str_to_ip4("5.6.7.8", &dns[1].ip.u_addr.ip4)); + + // set DNS info to one netif + TEST_ASSERT_EQUAL(ESP_OK, esp_netif_set_dns_info(netifs[3], ESP_NETIF_DNS_MAIN, &dns[0])); + TEST_ASSERT_EQUAL(ESP_OK, esp_netif_set_dns_info(netifs[3], ESP_NETIF_DNS_BACKUP, &dns[1])); +#ifndef CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF + // check that calling setters/getters with 'esp_netif==NULL' is invalid + TEST_ASSERT_NOT_EQUAL(ESP_OK, esp_netif_set_dns_info(NULL, ESP_NETIF_DNS_BACKUP, &dns[1])); + TEST_ASSERT_NOT_EQUAL(ESP_OK, esp_netif_get_dns_info(NULL, ESP_NETIF_DNS_BACKUP, &get_dns)); + + // check that the global DNS is configured the same way + const ip_addr_t *ip = dns_getserver(0); + TEST_ASSERT_EQUAL(ip->u_addr.ip4.addr, dns[0].ip.u_addr.ip4.addr); + ip = dns_getserver(1); + TEST_ASSERT_EQUAL(ip->u_addr.ip4.addr, dns[1].ip.u_addr.ip4.addr); + + // check that we get the same DNS information for all netifs + for (int i=0; i < nr_of_netifs; ++i) { + TEST_ASSERT_EQUAL(ESP_OK, esp_netif_get_dns_info(netifs[i], ESP_NETIF_DNS_MAIN, &get_dns)); + TEST_ASSERT_EQUAL(get_dns.ip.u_addr.ip4.addr, dns[0].ip.u_addr.ip4.addr); + TEST_ASSERT_EQUAL(ESP_OK, esp_netif_get_dns_info(netifs[i], ESP_NETIF_DNS_BACKUP, &get_dns)); + TEST_ASSERT_EQUAL(get_dns.ip.u_addr.ip4.addr, dns[1].ip.u_addr.ip4.addr); + } +#else + // check that calling setters/getters with 'esp_netif==NULL' is valid, they set/get global DNS servers + TEST_ASSERT_EQUAL(ESP_OK, esp_netif_set_dns_info(NULL, ESP_NETIF_DNS_MAIN, &dns[0])); + TEST_ASSERT_EQUAL(ESP_OK, esp_netif_get_dns_info(NULL, ESP_NETIF_DNS_BACKUP, &get_dns)); + const ip_addr_t *ip = dns_getserver(0); + TEST_ASSERT_EQUAL(ip->u_addr.ip4.addr, dns[0].ip.u_addr.ip4.addr); + ip = dns_getserver(1); + TEST_ASSERT_EQUAL(ip->u_addr.ip4.addr, get_dns.ip.u_addr.ip4.addr); // same as what we got at the esp-netif layer + TEST_ASSERT_NOT_EQUAL(ip->u_addr.ip4.addr, dns[1].ip.u_addr.ip4.addr); // but different from what we set earlier per netif + + // now we set the netif[3] as default one and check again + esp_netif_set_default_netif(netifs[3]); + ip = dns_getserver(1); + TEST_ASSERT_EQUAL(ip->u_addr.ip4.addr, dns[1].ip.u_addr.ip4.addr); // now the ESP_NETIF_DNS_BACKUP[3[ should be set globally + + // check that we get a different DNS server with another netif + TEST_ASSERT_EQUAL(ESP_OK, esp_netif_get_dns_info(netifs[5], ESP_NETIF_DNS_MAIN, &get_dns)); + TEST_ASSERT_NOT_EQUAL(dns[0].ip.u_addr.ip4.addr, get_dns.ip.u_addr.ip4.addr); +#endif + + for (int i=0; i < nr_of_netifs; ++i) { + esp_netif_destroy(netifs[i]); + TEST_ASSERT_FALSE(esp_netif_is_netif_listed(netifs[i])); + } +} + +TEST_GROUP_RUNNER(esp_netif) +{ + /** + * Keep the tests that don't need to start TCP/IP stack first, when the leak checker + * is more strict with leak level set to 0 + */ + RUN_TEST_CASE(esp_netif, init_and_destroy) + RUN_TEST_CASE(esp_netif, init_and_destroy_sntp) + RUN_TEST_CASE(esp_netif, convert_ip_addresses) + RUN_TEST_CASE(esp_netif, get_from_if_key) + RUN_TEST_CASE(esp_netif, create_delete_multiple_netifs) + RUN_TEST_CASE(esp_netif, find_netifs) +#ifdef CONFIG_ESP_WIFI_ENABLED + RUN_TEST_CASE(esp_netif, create_custom_wifi_interfaces) + RUN_TEST_CASE(esp_netif, create_destroy_default_wifi) +#endif + /** + * After follow tests which start lwIP and thus expect some mem-leaks by TCP/IP stack + */ +#ifdef CONFIG_ESP_WIFI_ENABLED + RUN_TEST_CASE(esp_netif, get_set_hostname) + RUN_TEST_CASE(esp_netif, dhcp_client_state_transitions_wifi_sta) +#endif +#if defined(CONFIG_ESP_WIFI_ENABLED) && defined(CONFIG_ESP_WIFI_SOFTAP_SUPPORT) + RUN_TEST_CASE(esp_netif, dhcp_server_state_transitions_wifi_ap) + RUN_TEST_CASE(esp_netif, dhcp_server_state_transitions_mesh) +#endif + RUN_TEST_CASE(esp_netif, route_priority) + RUN_TEST_CASE(esp_netif, set_get_dnsserver) +} + +void app_main(void) +{ + UNITY_MAIN(esp_netif); +} diff --git a/components/esp_netif/test_apps/test_app_esp_netif/pytest_esp_netif.py b/components/esp_netif/test_apps/test_app_esp_netif/pytest_esp_netif.py index 43c0125637..746316674f 100644 --- a/components/esp_netif/test_apps/test_app_esp_netif/pytest_esp_netif.py +++ b/components/esp_netif/test_apps/test_app_esp_netif/pytest_esp_netif.py @@ -10,6 +10,7 @@ from pytest_embedded import Dut @pytest.mark.parametrize('config', [ 'global_dns', 'dns_per_netif', + 'loopback', # test config without LWIP ], indirect=True) def test_esp_netif(dut: Dut) -> None: dut.expect_unity_test_output() diff --git a/components/esp_netif/test_apps/test_app_esp_netif/sdkconfig.ci.dns_per_netif b/components/esp_netif/test_apps/test_app_esp_netif/sdkconfig.ci.dns_per_netif index 3abbf3a3bc..b7cd513a8e 100644 --- a/components/esp_netif/test_apps/test_app_esp_netif/sdkconfig.ci.dns_per_netif +++ b/components/esp_netif/test_apps/test_app_esp_netif/sdkconfig.ci.dns_per_netif @@ -1 +1,3 @@ +CONFIG_ESP_NETIF_TCPIP_LWIP=y +CONFIG_ESP_NETIF_LOOPBACK=n CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF=y diff --git a/components/esp_netif/test_apps/test_app_esp_netif/sdkconfig.ci.global_dns b/components/esp_netif/test_apps/test_app_esp_netif/sdkconfig.ci.global_dns index ba627cbf81..61733abdeb 100644 --- a/components/esp_netif/test_apps/test_app_esp_netif/sdkconfig.ci.global_dns +++ b/components/esp_netif/test_apps/test_app_esp_netif/sdkconfig.ci.global_dns @@ -1 +1,3 @@ +CONFIG_ESP_NETIF_TCPIP_LWIP=y +CONFIG_ESP_NETIF_LOOPBACK=n CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF=n diff --git a/components/esp_netif/test_apps/test_app_esp_netif/sdkconfig.ci.loopback b/components/esp_netif/test_apps/test_app_esp_netif/sdkconfig.ci.loopback new file mode 100644 index 0000000000..ddeaa1295f --- /dev/null +++ b/components/esp_netif/test_apps/test_app_esp_netif/sdkconfig.ci.loopback @@ -0,0 +1,2 @@ +CONFIG_ESP_NETIF_LOOPBACK=y +CONFIG_ESP_NETIF_TCPIP_LWIP=n