From bf0e4943befccf72232526094628bd5dc15b5b99 Mon Sep 17 00:00:00 2001 From: Chen Yudong Date: Sun, 3 Jul 2022 15:24:39 +0800 Subject: [PATCH 01/10] common_components: add wifi connect console commands --- .../protocol_examples_common/CMakeLists.txt | 29 +- .../Kconfig.projbuild | 18 +- .../addr_from_stdin.c | 2 +- .../protocol_examples_common/connect.c | 529 +++--------------- .../protocol_examples_common/console_cmd.c | 87 +++ .../protocol_examples_common/eth_connect.c | 219 ++++++++ .../include/addr_from_stdin.h | 8 +- .../include/example_common_private.h | 60 ++ .../include/protocol_examples_common.h | 49 +- .../protocol_examples_common/stdin_out.c | 5 + .../protocol_examples_common/wifi_connect.c | 236 ++++++++ examples/protocols/README.md | 2 +- .../main/simple_ota_example.c | 4 +- tools/ci/check_copyright_ignore.txt | 1 - 14 files changed, 756 insertions(+), 493 deletions(-) create mode 100644 examples/common_components/protocol_examples_common/console_cmd.c create mode 100644 examples/common_components/protocol_examples_common/eth_connect.c create mode 100644 examples/common_components/protocol_examples_common/include/example_common_private.h create mode 100644 examples/common_components/protocol_examples_common/wifi_connect.c diff --git a/examples/common_components/protocol_examples_common/CMakeLists.txt b/examples/common_components/protocol_examples_common/CMakeLists.txt index 5f903a75d0..3bf73579da 100644 --- a/examples/common_components/protocol_examples_common/CMakeLists.txt +++ b/examples/common_components/protocol_examples_common/CMakeLists.txt @@ -1,4 +1,25 @@ -idf_component_register(SRCS "connect.c" "stdin_out.c" "addr_from_stdin.c" - INCLUDE_DIRS "include" - PRIV_REQUIRES esp_netif driver esp_eth - ) +set(srcs "stdin_out.c" + "addr_from_stdin.c" + "connect.c" + "wifi_connect.c") + +if(CONFIG_EXAMPLE_PROVIDE_WIFI_CONSOLE_CMD) + list(APPEND srcs "console_cmd.c") +endif() + +if(CONFIG_EXAMPLE_CONNECT_ETHERNET) + list(APPEND srcs "eth_connect.c") +endif() + + +idf_component_register(SRCS "${srcs}" + INCLUDE_DIRS "include" + PRIV_REQUIRES esp_netif driver) + +if(CONFIG_EXAMPLE_PROVIDE_WIFI_CONSOLE_CMD) + idf_component_optional_requires(PRIVATE console) +endif() + +if(CONFIG_EXAMPLE_CONNECT_ETHERNET) + idf_component_optional_requires(PRIVATE esp_eth) +endif() diff --git a/examples/common_components/protocol_examples_common/Kconfig.projbuild b/examples/common_components/protocol_examples_common/Kconfig.projbuild index 7182563eae..27e81c0fd3 100644 --- a/examples/common_components/protocol_examples_common/Kconfig.projbuild +++ b/examples/common_components/protocol_examples_common/Kconfig.projbuild @@ -10,13 +10,29 @@ menu "Example Connection Configuration" Choose this option to connect with WiFi if EXAMPLE_CONNECT_WIFI + config EXAMPLE_WIFI_SSID_PWD_FROM_STDIN + bool "Get ssid and password from stdin" + default n + help + Give the WiFi SSID and password from stdin. + + config EXAMPLE_PROVIDE_WIFI_CONSOLE_CMD + depends on !EXAMPLE_WIFI_SSID_PWD_FROM_STDIN + bool "Provide wifi connect commands" + default y + help + Provide wifi connect commands for esp_console. + Please use `register_wifi_connect_commands` to register them. + config EXAMPLE_WIFI_SSID + depends on !EXAMPLE_WIFI_SSID_PWD_FROM_STDIN string "WiFi SSID" default "myssid" help SSID (network name) for the example to connect to. config EXAMPLE_WIFI_PASSWORD + depends on !EXAMPLE_WIFI_SSID_PWD_FROM_STDIN string "WiFi Password" default "mypassword" help @@ -282,9 +298,9 @@ menu "Example Connection Configuration" endif # EXAMPLE_CONNECT_ETHERNET config EXAMPLE_CONNECT_IPV6 + depends on (EXAMPLE_CONNECT_WIFI || EXAMPLE_CONNECT_ETHERNET) bool "Obtain IPv6 address" default y - depends on EXAMPLE_CONNECT_WIFI || EXAMPLE_CONNECT_ETHERNET select LWIP_IPV6 help By default, examples will wait until IPv4 and IPv6 local link addresses are obtained. diff --git a/examples/common_components/protocol_examples_common/addr_from_stdin.c b/examples/common_components/protocol_examples_common/addr_from_stdin.c index c907ffd96e..5c79be614f 100644 --- a/examples/common_components/protocol_examples_common/addr_from_stdin.c +++ b/examples/common_components/protocol_examples_common/addr_from_stdin.c @@ -50,7 +50,7 @@ esp_err_t get_addr_from_stdin(int port, int sock_type, int *ip_protocol, int *ad return ESP_OK; } -#if CONFIG_LWIP_IPV6 +#if CONFIG_EXAMPLE_CONNECT_IPV6 else if (cur->ai_family == AF_INET6) { *ip_protocol = IPPROTO_IPV6; *addr_family = AF_INET6; diff --git a/examples/common_components/protocol_examples_common/connect.c b/examples/common_components/protocol_examples_common/connect.c index 07e74de0da..e141e52af6 100644 --- a/examples/common_components/protocol_examples_common/connect.c +++ b/examples/common_components/protocol_examples_common/connect.c @@ -1,94 +1,29 @@ -/* Common functions for protocol examples, to establish Wi-Fi or Ethernet connection. - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ #include #include "protocol_examples_common.h" +#include "example_common_private.h" #include "sdkconfig.h" #include "esp_event.h" #include "esp_wifi.h" #include "esp_wifi_default.h" -#if CONFIG_EXAMPLE_CONNECT_ETHERNET -#include "esp_eth.h" -#if CONFIG_ETH_USE_SPI_ETHERNET -#include "driver/spi_master.h" -#endif // CONFIG_ETH_USE_SPI_ETHERNET -#endif // CONFIG_EXAMPLE_CONNECT_ETHERNET #include "esp_log.h" #include "esp_netif.h" -#include "driver/gpio.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/event_groups.h" #include "lwip/err.h" #include "lwip/sys.h" -#ifdef CONFIG_EXAMPLE_CONNECT_IPV6 -#define MAX_IP6_ADDRS_PER_NETIF (5) -#define NR_OF_IP_ADDRESSES_TO_WAIT_FOR (s_active_interfaces*2) - -#if defined(CONFIG_EXAMPLE_CONNECT_IPV6_PREF_LOCAL_LINK) -#define EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE ESP_IP6_ADDR_IS_LINK_LOCAL -#elif defined(CONFIG_EXAMPLE_CONNECT_IPV6_PREF_GLOBAL) -#define EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE ESP_IP6_ADDR_IS_GLOBAL -#elif defined(CONFIG_EXAMPLE_CONNECT_IPV6_PREF_SITE_LOCAL) -#define EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE ESP_IP6_ADDR_IS_SITE_LOCAL -#elif defined(CONFIG_EXAMPLE_CONNECT_IPV6_PREF_UNIQUE_LOCAL) -#define EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE ESP_IP6_ADDR_IS_UNIQUE_LOCAL -#endif // if-elif CONFIG_EXAMPLE_CONNECT_IPV6_PREF_... - -#else -#define NR_OF_IP_ADDRESSES_TO_WAIT_FOR (s_active_interfaces) -#endif - -#define EXAMPLE_DO_CONNECT CONFIG_EXAMPLE_CONNECT_WIFI || CONFIG_EXAMPLE_CONNECT_ETHERNET - -#if CONFIG_EXAMPLE_WIFI_SCAN_METHOD_FAST -#define EXAMPLE_WIFI_SCAN_METHOD WIFI_FAST_SCAN -#elif CONFIG_EXAMPLE_WIFI_SCAN_METHOD_ALL_CHANNEL -#define EXAMPLE_WIFI_SCAN_METHOD WIFI_ALL_CHANNEL_SCAN -#endif - -#if CONFIG_EXAMPLE_WIFI_CONNECT_AP_BY_SIGNAL -#define EXAMPLE_WIFI_CONNECT_AP_SORT_METHOD WIFI_CONNECT_AP_BY_SIGNAL -#elif CONFIG_EXAMPLE_WIFI_CONNECT_AP_BY_SECURITY -#define EXAMPLE_WIFI_CONNECT_AP_SORT_METHOD WIFI_CONNECT_AP_BY_SECURITY -#endif - -#if CONFIG_EXAMPLE_WIFI_AUTH_OPEN -#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_OPEN -#elif CONFIG_EXAMPLE_WIFI_AUTH_WEP -#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WEP -#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA_PSK -#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_PSK -#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA2_PSK -#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_PSK -#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA_WPA2_PSK -#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_WPA2_PSK -#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA2_ENTERPRISE -#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_ENTERPRISE -#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA3_PSK -#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA3_PSK -#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA2_WPA3_PSK -#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_WPA3_PSK -#elif CONFIG_EXAMPLE_WIFI_AUTH_WAPI_PSK -#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WAPI_PSK -#endif - -static int s_active_interfaces = 0; -static SemaphoreHandle_t s_semph_get_ip_addrs; -static esp_netif_t *s_example_esp_netif = NULL; - -#ifdef CONFIG_EXAMPLE_CONNECT_IPV6 -static esp_ip6_addr_t s_ipv6_addr; +static const char *TAG = "example_common"; +#if CONFIG_EXAMPLE_CONNECT_IPV6 /* types of ipv6 addresses to be displayed on ipv6 events */ -static const char *s_ipv6_addr_types[] = { +const char *example_ipv6_addr_types_to_str[6] = { "ESP_IP6_ADDR_IS_UNKNOWN", "ESP_IP6_ADDR_IS_GLOBAL", "ESP_IP6_ADDR_IS_LINK_LOCAL", @@ -98,406 +33,84 @@ static const char *s_ipv6_addr_types[] = { }; #endif -static const char *TAG = "example_connect"; - -#if CONFIG_EXAMPLE_CONNECT_WIFI -static esp_netif_t *wifi_start(void); -static void wifi_stop(void); -#endif -#if CONFIG_EXAMPLE_CONNECT_ETHERNET -static esp_netif_t *eth_start(void); -static void eth_stop(void); -#endif - /** * @brief Checks the netif description if it contains specified prefix. * All netifs created withing common connect component are prefixed with the module TAG, * so it returns true if the specified netif is owned by this module */ -static bool is_our_netif(const char *prefix, esp_netif_t *netif) +bool example_is_our_netif(const char *prefix, esp_netif_t *netif) { return strncmp(prefix, esp_netif_get_desc(netif), strlen(prefix) - 1) == 0; } -/* set up connection, Wi-Fi and/or Ethernet */ -static void start(void) -{ - -#if CONFIG_EXAMPLE_CONNECT_WIFI - s_example_esp_netif = wifi_start(); - s_active_interfaces++; -#endif - -#if CONFIG_EXAMPLE_CONNECT_ETHERNET - s_example_esp_netif = eth_start(); - s_active_interfaces++; -#endif - -#if CONFIG_EXAMPLE_CONNECT_WIFI && CONFIG_EXAMPLE_CONNECT_ETHERNET - /* if both intefaces at once, clear out to indicate that multiple netifs are active */ - s_example_esp_netif = NULL; -#endif - -#if EXAMPLE_DO_CONNECT - /* create semaphore if at least one interface is active */ - s_semph_get_ip_addrs = xSemaphoreCreateCounting(NR_OF_IP_ADDRESSES_TO_WAIT_FOR, 0); -#endif - -} - -/* tear down connection, release resources */ -static void stop(void) -{ -#if CONFIG_EXAMPLE_CONNECT_WIFI - wifi_stop(); - s_active_interfaces--; -#endif - -#if CONFIG_EXAMPLE_CONNECT_ETHERNET - eth_stop(); - s_active_interfaces--; -#endif -} - -#if EXAMPLE_DO_CONNECT -static esp_ip4_addr_t s_ip_addr; - -static void on_got_ip(void *arg, esp_event_base_t event_base, - int32_t event_id, void *event_data) -{ - ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data; - if (!is_our_netif(TAG, event->esp_netif)) { - ESP_LOGW(TAG, "Got IPv4 from another interface \"%s\": ignored", esp_netif_get_desc(event->esp_netif)); - return; - } - ESP_LOGI(TAG, "Got IPv4 event: Interface \"%s\" address: " IPSTR, esp_netif_get_desc(event->esp_netif), IP2STR(&event->ip_info.ip)); - memcpy(&s_ip_addr, &event->ip_info.ip, sizeof(s_ip_addr)); - xSemaphoreGive(s_semph_get_ip_addrs); -} -#endif - -#ifdef CONFIG_EXAMPLE_CONNECT_IPV6 - -static void on_got_ipv6(void *arg, esp_event_base_t event_base, - int32_t event_id, void *event_data) -{ - ip_event_got_ip6_t *event = (ip_event_got_ip6_t *)event_data; - if (!is_our_netif(TAG, event->esp_netif)) { - ESP_LOGW(TAG, "Got IPv6 from another netif: ignored"); - return; - } - esp_ip6_addr_type_t ipv6_type = esp_netif_ip6_get_addr_type(&event->ip6_info.ip); - ESP_LOGI(TAG, "Got IPv6 event: Interface \"%s\" address: " IPV6STR ", type: %s", esp_netif_get_desc(event->esp_netif), - IPV62STR(event->ip6_info.ip), s_ipv6_addr_types[ipv6_type]); - if (ipv6_type == EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE) { - memcpy(&s_ipv6_addr, &event->ip6_info.ip, sizeof(s_ipv6_addr)); - xSemaphoreGive(s_semph_get_ip_addrs); - } -} - -#endif // CONFIG_EXAMPLE_CONNECT_IPV6 - -esp_err_t example_connect(void) -{ -#if EXAMPLE_DO_CONNECT - if (s_semph_get_ip_addrs != NULL) { - return ESP_ERR_INVALID_STATE; - } -#endif - start(); - ESP_ERROR_CHECK(esp_register_shutdown_handler(&stop)); - ESP_LOGI(TAG, "Waiting for IP(s)"); - for (int i = 0; i < NR_OF_IP_ADDRESSES_TO_WAIT_FOR; ++i) { - xSemaphoreTake(s_semph_get_ip_addrs, portMAX_DELAY); - } - // iterate over active interfaces, and print out IPs of "our" netifs - esp_netif_t *netif = NULL; - esp_netif_ip_info_t ip; - for (int i = 0; i < esp_netif_get_nr_of_ifs(); ++i) { - netif = esp_netif_next(netif); - if (is_our_netif(TAG, netif)) { - ESP_LOGI(TAG, "Connected to %s", esp_netif_get_desc(netif)); - ESP_ERROR_CHECK(esp_netif_get_ip_info(netif, &ip)); - - ESP_LOGI(TAG, "- IPv4 address: " IPSTR, IP2STR(&ip.ip)); -#ifdef CONFIG_EXAMPLE_CONNECT_IPV6 - esp_ip6_addr_t ip6[MAX_IP6_ADDRS_PER_NETIF]; - int ip6_addrs = esp_netif_get_all_ip6(netif, ip6); - for (int j = 0; j < ip6_addrs; ++j) { - esp_ip6_addr_type_t ipv6_type = esp_netif_ip6_get_addr_type(&(ip6[j])); - ESP_LOGI(TAG, "- IPv6 address: " IPV6STR ", type: %s", IPV62STR(ip6[j]), s_ipv6_addr_types[ipv6_type]); - } -#endif - - } - } - return ESP_OK; -} - -esp_err_t example_disconnect(void) -{ - if (s_semph_get_ip_addrs == NULL) { - return ESP_ERR_INVALID_STATE; - } - vSemaphoreDelete(s_semph_get_ip_addrs); - s_semph_get_ip_addrs = NULL; - stop(); - ESP_ERROR_CHECK(esp_unregister_shutdown_handler(&stop)); - return ESP_OK; -} - -#ifdef CONFIG_EXAMPLE_CONNECT_WIFI - -static void on_wifi_disconnect(void *arg, esp_event_base_t event_base, - int32_t event_id, void *event_data) -{ - ESP_LOGI(TAG, "Wi-Fi disconnected, trying to reconnect..."); - esp_err_t err = esp_wifi_connect(); - if (err == ESP_ERR_WIFI_NOT_STARTED) { - return; - } - ESP_ERROR_CHECK(err); -} - -#ifdef CONFIG_EXAMPLE_CONNECT_IPV6 - -static void on_wifi_connect(void *esp_netif, esp_event_base_t event_base, - int32_t event_id, void *event_data) -{ - esp_netif_create_ip6_linklocal(esp_netif); -} - -#endif // CONFIG_EXAMPLE_CONNECT_IPV6 - -static esp_netif_t *wifi_start(void) -{ - char *desc; - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - - esp_netif_inherent_config_t esp_netif_config = ESP_NETIF_INHERENT_DEFAULT_WIFI_STA(); - // Prefix the interface description with the module TAG - // Warning: the interface desc is used in tests to capture actual connection details (IP, gw, mask) - asprintf(&desc, "%s: %s", TAG, esp_netif_config.if_desc); - esp_netif_config.if_desc = desc; - esp_netif_config.route_prio = 128; - esp_netif_t *netif = esp_netif_create_wifi(WIFI_IF_STA, &esp_netif_config); - free(desc); - esp_wifi_set_default_wifi_sta_handlers(); - - ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &on_wifi_disconnect, NULL)); - ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &on_got_ip, NULL)); -#ifdef CONFIG_EXAMPLE_CONNECT_IPV6 - ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, &on_wifi_connect, netif)); - ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_GOT_IP6, &on_got_ipv6, NULL)); -#endif - - ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); - wifi_config_t wifi_config = { - .sta = { - .ssid = CONFIG_EXAMPLE_WIFI_SSID, - .password = CONFIG_EXAMPLE_WIFI_PASSWORD, - .scan_method = EXAMPLE_WIFI_SCAN_METHOD, - .sort_method = EXAMPLE_WIFI_CONNECT_AP_SORT_METHOD, - .threshold.rssi = CONFIG_EXAMPLE_WIFI_SCAN_RSSI_THRESHOLD, - .threshold.authmode = EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD, - }, - }; - ESP_LOGI(TAG, "Connecting to %s...", wifi_config.sta.ssid); - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config)); - ESP_ERROR_CHECK(esp_wifi_start()); - esp_wifi_connect(); - return netif; -} - -static void wifi_stop(void) -{ - esp_netif_t *wifi_netif = get_example_netif_from_desc("sta"); - ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &on_wifi_disconnect)); - ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, &on_got_ip)); -#ifdef CONFIG_EXAMPLE_CONNECT_IPV6 - ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_GOT_IP6, &on_got_ipv6)); - ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, &on_wifi_connect)); -#endif - esp_err_t err = esp_wifi_stop(); - if (err == ESP_ERR_WIFI_NOT_INIT) { - return; - } - ESP_ERROR_CHECK(err); - ESP_ERROR_CHECK(esp_wifi_deinit()); - ESP_ERROR_CHECK(esp_wifi_clear_default_wifi_driver_and_handlers(wifi_netif)); - esp_netif_destroy(wifi_netif); - s_example_esp_netif = NULL; -} -#endif // CONFIG_EXAMPLE_CONNECT_WIFI - -#ifdef CONFIG_EXAMPLE_CONNECT_ETHERNET - -#ifdef CONFIG_EXAMPLE_CONNECT_IPV6 - -/** Event handler for Ethernet events */ -static void on_eth_event(void *esp_netif, esp_event_base_t event_base, - int32_t event_id, void *event_data) -{ - switch (event_id) { - case ETHERNET_EVENT_CONNECTED: - ESP_LOGI(TAG, "Ethernet Link Up"); - ESP_ERROR_CHECK(esp_netif_create_ip6_linklocal(esp_netif)); - break; - default: - break; - } -} - -#endif // CONFIG_EXAMPLE_CONNECT_IPV6 - -static esp_eth_handle_t s_eth_handle = NULL; -static esp_eth_mac_t *s_mac = NULL; -static esp_eth_phy_t *s_phy = NULL; -static esp_eth_netif_glue_handle_t s_eth_glue = NULL; - -static esp_netif_t *eth_start(void) -{ - char *desc; - esp_netif_inherent_config_t esp_netif_config = ESP_NETIF_INHERENT_DEFAULT_ETH(); - // Prefix the interface description with the module TAG - // Warning: the interface desc is used in tests to capture actual connection details (IP, gw, mask) - asprintf(&desc, "%s: %s", TAG, esp_netif_config.if_desc); - esp_netif_config.if_desc = desc; - esp_netif_config.route_prio = 64; - esp_netif_config_t netif_config = { - .base = &esp_netif_config, - .stack = ESP_NETIF_NETSTACK_DEFAULT_ETH - }; - esp_netif_t *netif = esp_netif_new(&netif_config); - assert(netif); - free(desc); - - eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG(); - mac_config.rx_task_stack_size = CONFIG_EXAMPLE_ETHERNET_EMAC_TASK_STACK_SIZE; - eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG(); - phy_config.phy_addr = CONFIG_EXAMPLE_ETH_PHY_ADDR; - phy_config.reset_gpio_num = CONFIG_EXAMPLE_ETH_PHY_RST_GPIO; -#if CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET - eth_esp32_emac_config_t esp32_emac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG(); - esp32_emac_config.smi_mdc_gpio_num = CONFIG_EXAMPLE_ETH_MDC_GPIO; - esp32_emac_config.smi_mdio_gpio_num = CONFIG_EXAMPLE_ETH_MDIO_GPIO; - s_mac = esp_eth_mac_new_esp32(&esp32_emac_config, &mac_config); -#if CONFIG_EXAMPLE_ETH_PHY_IP101 - s_phy = esp_eth_phy_new_ip101(&phy_config); -#elif CONFIG_EXAMPLE_ETH_PHY_RTL8201 - s_phy = esp_eth_phy_new_rtl8201(&phy_config); -#elif CONFIG_EXAMPLE_ETH_PHY_LAN87XX - s_phy = esp_eth_phy_new_lan87xx(&phy_config); -#elif CONFIG_EXAMPLE_ETH_PHY_DP83848 - s_phy = esp_eth_phy_new_dp83848(&phy_config); -#elif CONFIG_EXAMPLE_ETH_PHY_KSZ80XX - s_phy = esp_eth_phy_new_ksz80xx(&phy_config); -#endif -#elif CONFIG_EXAMPLE_USE_SPI_ETHERNET - gpio_install_isr_service(0); - spi_bus_config_t buscfg = { - .miso_io_num = CONFIG_EXAMPLE_ETH_SPI_MISO_GPIO, - .mosi_io_num = CONFIG_EXAMPLE_ETH_SPI_MOSI_GPIO, - .sclk_io_num = CONFIG_EXAMPLE_ETH_SPI_SCLK_GPIO, - .quadwp_io_num = -1, - .quadhd_io_num = -1, - }; - ESP_ERROR_CHECK(spi_bus_initialize(CONFIG_EXAMPLE_ETH_SPI_HOST, &buscfg, 1)); - spi_device_interface_config_t spi_devcfg = { - .mode = 0, - .clock_speed_hz = CONFIG_EXAMPLE_ETH_SPI_CLOCK_MHZ * 1000 * 1000, - .spics_io_num = CONFIG_EXAMPLE_ETH_SPI_CS_GPIO, - .queue_size = 20 - }; -#if CONFIG_EXAMPLE_USE_DM9051 - /* dm9051 ethernet driver is based on spi driver */ - eth_dm9051_config_t dm9051_config = ETH_DM9051_DEFAULT_CONFIG(CONFIG_EXAMPLE_ETH_SPI_HOST, &spi_devcfg); - dm9051_config.int_gpio_num = CONFIG_EXAMPLE_ETH_SPI_INT_GPIO; - s_mac = esp_eth_mac_new_dm9051(&dm9051_config, &mac_config); - s_phy = esp_eth_phy_new_dm9051(&phy_config); -#elif CONFIG_EXAMPLE_USE_W5500 - /* w5500 ethernet driver is based on spi driver */ - eth_w5500_config_t w5500_config = ETH_W5500_DEFAULT_CONFIG(CONFIG_EXAMPLE_ETH_SPI_HOST, &spi_devcfg); - w5500_config.int_gpio_num = CONFIG_EXAMPLE_ETH_SPI_INT_GPIO; - s_mac = esp_eth_mac_new_w5500(&w5500_config, &mac_config); - s_phy = esp_eth_phy_new_w5500(&phy_config); -#endif -#elif CONFIG_EXAMPLE_USE_OPENETH - phy_config.autonego_timeout_ms = 100; - s_mac = esp_eth_mac_new_openeth(&mac_config); - s_phy = esp_eth_phy_new_dp83848(&phy_config); -#endif - - // Install Ethernet driver - esp_eth_config_t config = ETH_DEFAULT_CONFIG(s_mac, s_phy); - ESP_ERROR_CHECK(esp_eth_driver_install(&config, &s_eth_handle)); -#if !CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET - /* The SPI Ethernet module might doesn't have a burned factory MAC address, we cat to set it manually. - 02:00:00 is a Locally Administered OUI range so should not be used except when testing on a LAN under your control. - */ - ESP_ERROR_CHECK(esp_eth_ioctl(s_eth_handle, ETH_CMD_S_MAC_ADDR, (uint8_t[]) { - 0x02, 0x00, 0x00, 0x12, 0x34, 0x56 - })); -#endif - // combine driver with netif - s_eth_glue = esp_eth_new_netif_glue(s_eth_handle); - esp_netif_attach(netif, s_eth_glue); - - // Register user defined event handers - ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, &on_got_ip, NULL)); -#ifdef CONFIG_EXAMPLE_CONNECT_IPV6 - ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_CONNECTED, &on_eth_event, netif)); - ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_GOT_IP6, &on_got_ipv6, NULL)); -#endif - - esp_eth_start(s_eth_handle); - return netif; -} - -static void eth_stop(void) -{ - esp_netif_t *eth_netif = get_example_netif_from_desc("eth"); - ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP, &on_got_ip)); -#ifdef CONFIG_EXAMPLE_CONNECT_IPV6 - ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_GOT_IP6, &on_got_ipv6)); - ESP_ERROR_CHECK(esp_event_handler_unregister(ETH_EVENT, ETHERNET_EVENT_CONNECTED, &on_eth_event)); -#endif - ESP_ERROR_CHECK(esp_eth_stop(s_eth_handle)); - ESP_ERROR_CHECK(esp_eth_del_netif_glue(s_eth_glue)); - ESP_ERROR_CHECK(esp_eth_driver_uninstall(s_eth_handle)); - s_eth_handle = NULL; - ESP_ERROR_CHECK(s_phy->del(s_phy)); - ESP_ERROR_CHECK(s_mac->del(s_mac)); - - esp_netif_destroy(eth_netif); - s_example_esp_netif = NULL; -} - -esp_eth_handle_t get_example_eth_handle(void) -{ - return s_eth_handle; -} - -#endif // CONFIG_EXAMPLE_CONNECT_ETHERNET - -esp_netif_t *get_example_netif(void) -{ - return s_example_esp_netif; -} - esp_netif_t *get_example_netif_from_desc(const char *desc) { esp_netif_t *netif = NULL; - char *expected_desc; - asprintf(&expected_desc, "%s: %s", TAG, desc); while ((netif = esp_netif_next(netif)) != NULL) { - if (strcmp(esp_netif_get_desc(netif), expected_desc) == 0) { - free(expected_desc); + if (strcmp(esp_netif_get_desc(netif), desc) == 0) { return netif; } } - free(expected_desc); return netif; } + +void example_print_all_netif_ips(const char *prefix) +{ + // iterate over active interfaces, and print out IPs of "our" netifs + esp_netif_t *netif = NULL; + esp_netif_ip_info_t ip; + for (int i = 0; i < esp_netif_get_nr_of_ifs(); ++i) { + netif = esp_netif_next(netif); + if (example_is_our_netif(prefix, netif)) { + ESP_LOGI(TAG, "Connected to %s", esp_netif_get_desc(netif)); + ESP_ERROR_CHECK(esp_netif_get_ip_info(netif, &ip)); + + ESP_LOGI(TAG, "- IPv4 address: " IPSTR ",", IP2STR(&ip.ip)); +#if CONFIG_EXAMPLE_CONNECT_IPV6 + esp_ip6_addr_t ip6[MAX_IP6_ADDRS_PER_NETIF]; + int ip6_addrs = esp_netif_get_all_ip6(netif, ip6); + for (int j = 0; j < ip6_addrs; ++j) { + esp_ip6_addr_type_t ipv6_type = esp_netif_ip6_get_addr_type(&(ip6[j])); + ESP_LOGI(TAG, "- IPv6 address: " IPV6STR ", type: %s", IPV62STR(ip6[j]), example_ipv6_addr_types_to_str[ipv6_type]); + } +#endif + } + } +} + + +esp_err_t example_connect(void) +{ +#if CONFIG_EXAMPLE_CONNECT_ETHERNET + example_ethernet_connect(); + ESP_ERROR_CHECK(esp_register_shutdown_handler(&example_ethernet_shutdown)); +#endif +#if CONFIG_EXAMPLE_CONNECT_WIFI + example_wifi_connect(); + ESP_ERROR_CHECK(esp_register_shutdown_handler(&example_wifi_shutdown)); +#endif + +#if CONFIG_EXAMPLE_CONNECT_ETHERNET + example_print_all_netif_ips(EXAMPLE_NETIF_DESC_ETH); +#endif +#if CONFIG_EXAMPLE_CONNECT_WIFI + example_print_all_netif_ips(EXAMPLE_NETIF_DESC_STA); +#endif + + return ESP_OK; +} + + + +esp_err_t example_disconnect(void) +{ +#if CONFIG_EXAMPLE_CONNECT_ETHERNET + example_ethernet_shutdown(); + ESP_ERROR_CHECK(esp_unregister_shutdown_handler(&example_ethernet_shutdown)); +#endif +#if CONFIG_EXAMPLE_CONNECT_WIFI + example_wifi_shutdown(); + ESP_ERROR_CHECK(esp_unregister_shutdown_handler(&example_wifi_shutdown)); +#endif + return ESP_OK; +} diff --git a/examples/common_components/protocol_examples_common/console_cmd.c b/examples/common_components/protocol_examples_common/console_cmd.c new file mode 100644 index 0000000000..4b3c20d7eb --- /dev/null +++ b/examples/common_components/protocol_examples_common/console_cmd.c @@ -0,0 +1,87 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + + +#include +#include "protocol_examples_common.h" +#include "example_common_private.h" +#include "esp_wifi.h" +#include "esp_log.h" +#include "esp_console.h" +#include "argtable3/argtable3.h" + + +static const char *TAG = "example_console"; + +typedef struct { + struct arg_str *ssid; + struct arg_str *password; + struct arg_int *channel; + struct arg_end *end; +} wifi_connect_args_t; +static wifi_connect_args_t connect_args; + +static int cmd_do_wifi_connect(int argc, char **argv) +{ + int nerrors = arg_parse(argc, argv, (void **) &connect_args); + + if (nerrors != 0) { + arg_print_errors(stderr, connect_args.end, argv[0]); + return 1; + } + + wifi_config_t wifi_config = { + .sta = { + .scan_method = WIFI_ALL_CHANNEL_SCAN, + .sort_method = WIFI_CONNECT_AP_BY_SIGNAL, + }, + }; + if (connect_args.channel->count > 0) { + wifi_config.sta.channel = (uint8_t)(connect_args.channel->ival[0]); + } + const char *ssid = connect_args.ssid->sval[0]; + const char *pass = connect_args.password->sval[0]; + strlcpy((char *) wifi_config.sta.ssid, ssid, sizeof(wifi_config.sta.ssid)); + if (pass) { + strlcpy((char *) wifi_config.sta.password, pass, sizeof(wifi_config.sta.password)); + } + example_wifi_sta_do_connect(wifi_config, false); + return 0; +} + +static int cmd_do_wifi_disconnect(int argc, char **argv) +{ + example_wifi_sta_do_disconnect(); + return 0; +} + +void register_wifi_connect_commands(void) +{ + ESP_LOGI(TAG, "Registering WiFi connect commands."); + example_wifi_start(); + + connect_args.ssid = arg_str1(NULL, NULL, "", "SSID of AP"); + connect_args.password = arg_str0(NULL, NULL, "", "password of AP"); + connect_args.channel = arg_int0("n", "channel", "", "channel of AP"); + connect_args.end = arg_end(2); + const esp_console_cmd_t wifi_connect_cmd = { + .command = "wifi_connect", + .help = "WiFi is station mode, join specified soft-AP", + .hint = NULL, + .func = &cmd_do_wifi_connect, + .argtable = &connect_args + }; + ESP_ERROR_CHECK( esp_console_cmd_register(&wifi_connect_cmd) ); + + + const esp_console_cmd_t wifi_disconnect_cmd = { + .command = "wifi_disconnect", + .help = "Do wifi disconnect", + .hint = NULL, + .func = &cmd_do_wifi_disconnect, + }; + ESP_ERROR_CHECK( esp_console_cmd_register(&wifi_disconnect_cmd) ); +} diff --git a/examples/common_components/protocol_examples_common/eth_connect.c b/examples/common_components/protocol_examples_common/eth_connect.c new file mode 100644 index 0000000000..71f06e2910 --- /dev/null +++ b/examples/common_components/protocol_examples_common/eth_connect.c @@ -0,0 +1,219 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include "protocol_examples_common.h" +#include "example_common_private.h" +#include "esp_event.h" +#include "esp_eth.h" +#if CONFIG_ETH_USE_SPI_ETHERNET +#include "driver/spi_master.h" +#endif // CONFIG_ETH_USE_SPI_ETHERNET +#include "esp_log.h" +#include "driver/gpio.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/event_groups.h" + + +static const char *TAG = "ethernet_connect"; +static SemaphoreHandle_t s_semph_get_ip_addrs = NULL; + +static esp_netif_t *eth_start(void); +static void eth_stop(void); + + +/** Event handler for Ethernet events */ + +static void eth_on_got_ip(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data; + if (!example_is_our_netif(EXAMPLE_NETIF_DESC_ETH, event->esp_netif)) { + return; + } + ESP_LOGI(TAG, "Got IPv4 event: Interface \"%s\" address: " IPSTR, esp_netif_get_desc(event->esp_netif), IP2STR(&event->ip_info.ip)); + if (s_semph_get_ip_addrs) { + xSemaphoreGive(s_semph_get_ip_addrs); + } +} + +#if CONFIG_EXAMPLE_CONNECT_IPV6 + +static void eth_on_got_ipv6(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + ip_event_got_ip6_t *event = (ip_event_got_ip6_t *)event_data; + if (!example_is_our_netif(EXAMPLE_NETIF_DESC_ETH, event->esp_netif)) { + return; + } + esp_ip6_addr_type_t ipv6_type = esp_netif_ip6_get_addr_type(&event->ip6_info.ip); + ESP_LOGI(TAG, "Got IPv6 event: Interface \"%s\" address: " IPV6STR ", type: %s", esp_netif_get_desc(event->esp_netif), + IPV62STR(event->ip6_info.ip), example_ipv6_addr_types_to_str[ipv6_type]); + if (ipv6_type == EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE) { + xSemaphoreGive(s_semph_get_ip_addrs); + } +} + +static void on_eth_event(void *esp_netif, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + switch (event_id) { + case ETHERNET_EVENT_CONNECTED: + ESP_LOGI(TAG, "Ethernet Link Up"); + ESP_ERROR_CHECK(esp_netif_create_ip6_linklocal(esp_netif)); + break; + default: + break; + } +} + +#endif // CONFIG_EXAMPLE_CONNECT_IPV6 + +static esp_eth_handle_t s_eth_handle = NULL; +static esp_eth_mac_t *s_mac = NULL; +static esp_eth_phy_t *s_phy = NULL; +static esp_eth_netif_glue_handle_t s_eth_glue = NULL; + +static esp_netif_t *eth_start(void) +{ + esp_netif_inherent_config_t esp_netif_config = ESP_NETIF_INHERENT_DEFAULT_ETH(); + // Warning: the interface desc is used in tests to capture actual connection details (IP, gw, mask) + esp_netif_config.if_desc = EXAMPLE_NETIF_DESC_ETH; + esp_netif_config.route_prio = 64; + esp_netif_config_t netif_config = { + .base = &esp_netif_config, + .stack = ESP_NETIF_NETSTACK_DEFAULT_ETH + }; + esp_netif_t *netif = esp_netif_new(&netif_config); + assert(netif); + + eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG(); + mac_config.rx_task_stack_size = CONFIG_EXAMPLE_ETHERNET_EMAC_TASK_STACK_SIZE; + eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG(); + phy_config.phy_addr = CONFIG_EXAMPLE_ETH_PHY_ADDR; + phy_config.reset_gpio_num = CONFIG_EXAMPLE_ETH_PHY_RST_GPIO; +#if CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET + eth_esp32_emac_config_t esp32_emac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG(); + esp32_emac_config.smi_mdc_gpio_num = CONFIG_EXAMPLE_ETH_MDC_GPIO; + esp32_emac_config.smi_mdio_gpio_num = CONFIG_EXAMPLE_ETH_MDIO_GPIO; + s_mac = esp_eth_mac_new_esp32(&esp32_emac_config, &mac_config); +#if CONFIG_EXAMPLE_ETH_PHY_IP101 + s_phy = esp_eth_phy_new_ip101(&phy_config); +#elif CONFIG_EXAMPLE_ETH_PHY_RTL8201 + s_phy = esp_eth_phy_new_rtl8201(&phy_config); +#elif CONFIG_EXAMPLE_ETH_PHY_LAN87XX + s_phy = esp_eth_phy_new_lan87xx(&phy_config); +#elif CONFIG_EXAMPLE_ETH_PHY_DP83848 + s_phy = esp_eth_phy_new_dp83848(&phy_config); +#elif CONFIG_EXAMPLE_ETH_PHY_KSZ80XX + s_phy = esp_eth_phy_new_ksz80xx(&phy_config); +#endif +#elif CONFIG_EXAMPLE_USE_SPI_ETHERNET + gpio_install_isr_service(0); + spi_bus_config_t buscfg = { + .miso_io_num = CONFIG_EXAMPLE_ETH_SPI_MISO_GPIO, + .mosi_io_num = CONFIG_EXAMPLE_ETH_SPI_MOSI_GPIO, + .sclk_io_num = CONFIG_EXAMPLE_ETH_SPI_SCLK_GPIO, + .quadwp_io_num = -1, + .quadhd_io_num = -1, + }; + ESP_ERROR_CHECK(spi_bus_initialize(CONFIG_EXAMPLE_ETH_SPI_HOST, &buscfg, 1)); + spi_device_interface_config_t spi_devcfg = { + .mode = 0, + .clock_speed_hz = CONFIG_EXAMPLE_ETH_SPI_CLOCK_MHZ * 1000 * 1000, + .spics_io_num = CONFIG_EXAMPLE_ETH_SPI_CS_GPIO, + .queue_size = 20 + }; +#if CONFIG_EXAMPLE_USE_DM9051 + /* dm9051 ethernet driver is based on spi driver */ + eth_dm9051_config_t dm9051_config = ETH_DM9051_DEFAULT_CONFIG(CONFIG_EXAMPLE_ETH_SPI_HOST, &spi_devcfg); + dm9051_config.int_gpio_num = CONFIG_EXAMPLE_ETH_SPI_INT_GPIO; + s_mac = esp_eth_mac_new_dm9051(&dm9051_config, &mac_config); + s_phy = esp_eth_phy_new_dm9051(&phy_config); +#elif CONFIG_EXAMPLE_USE_W5500 + /* w5500 ethernet driver is based on spi driver */ + eth_w5500_config_t w5500_config = ETH_W5500_DEFAULT_CONFIG(CONFIG_EXAMPLE_ETH_SPI_HOST, &spi_devcfg); + w5500_config.int_gpio_num = CONFIG_EXAMPLE_ETH_SPI_INT_GPIO; + s_mac = esp_eth_mac_new_w5500(&w5500_config, &mac_config); + s_phy = esp_eth_phy_new_w5500(&phy_config); +#endif +#elif CONFIG_EXAMPLE_USE_OPENETH + phy_config.autonego_timeout_ms = 100; + s_mac = esp_eth_mac_new_openeth(&mac_config); + s_phy = esp_eth_phy_new_dp83848(&phy_config); +#endif + + // Install Ethernet driver + esp_eth_config_t config = ETH_DEFAULT_CONFIG(s_mac, s_phy); + ESP_ERROR_CHECK(esp_eth_driver_install(&config, &s_eth_handle)); +#if !CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET + /* The SPI Ethernet module might doesn't have a burned factory MAC address, we cat to set it manually. + 02:00:00 is a Locally Administered OUI range so should not be used except when testing on a LAN under your control. + */ + ESP_ERROR_CHECK(esp_eth_ioctl(s_eth_handle, ETH_CMD_S_MAC_ADDR, (uint8_t[]) { + 0x02, 0x00, 0x00, 0x12, 0x34, 0x56 + })); +#endif + // combine driver with netif + s_eth_glue = esp_eth_new_netif_glue(s_eth_handle); + esp_netif_attach(netif, s_eth_glue); + + // Register user defined event handers + ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, ð_on_got_ip, NULL)); +#ifdef CONFIG_EXAMPLE_CONNECT_IPV6 + ESP_ERROR_CHECK(esp_event_handler_register(ETH_EVENT, ETHERNET_EVENT_CONNECTED, &on_eth_event, netif)); + ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_GOT_IP6, ð_on_got_ipv6, NULL)); +#endif + + esp_eth_start(s_eth_handle); + return netif; +} + +static void eth_stop(void) +{ + esp_netif_t *eth_netif = get_example_netif_from_desc(EXAMPLE_NETIF_DESC_ETH); + ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP, ð_on_got_ip)); +#if CONFIG_EXAMPLE_CONNECT_IPV6 + ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_GOT_IP6, ð_on_got_ipv6)); + ESP_ERROR_CHECK(esp_event_handler_unregister(ETH_EVENT, ETHERNET_EVENT_CONNECTED, &on_eth_event)); +#endif + ESP_ERROR_CHECK(esp_eth_stop(s_eth_handle)); + ESP_ERROR_CHECK(esp_eth_del_netif_glue(s_eth_glue)); + ESP_ERROR_CHECK(esp_eth_driver_uninstall(s_eth_handle)); + s_eth_handle = NULL; + ESP_ERROR_CHECK(s_phy->del(s_phy)); + ESP_ERROR_CHECK(s_mac->del(s_mac)); + + esp_netif_destroy(eth_netif); +} + +esp_eth_handle_t get_example_eth_handle(void) +{ + return s_eth_handle; +} + +/* tear down connection, release resources */ +void example_ethernet_shutdown(void) +{ + if (s_semph_get_ip_addrs == NULL) { + return; + } + vSemaphoreDelete(s_semph_get_ip_addrs); + s_semph_get_ip_addrs = NULL; + eth_stop(); +} + +esp_err_t example_ethernet_connect(void) +{ + s_semph_get_ip_addrs = xSemaphoreCreateCounting(NR_OF_IP_ADDRESSES_TO_WAIT_FOR, 0); + eth_start(); + ESP_LOGI(TAG, "Waiting for IP(s)."); + for (int i = 0; i < NR_OF_IP_ADDRESSES_TO_WAIT_FOR; ++i) { + xSemaphoreTake(s_semph_get_ip_addrs, portMAX_DELAY); + } + return ESP_OK; +} diff --git a/examples/common_components/protocol_examples_common/include/addr_from_stdin.h b/examples/common_components/protocol_examples_common/include/addr_from_stdin.h index 9a059c149c..827f8c25ac 100644 --- a/examples/common_components/protocol_examples_common/include/addr_from_stdin.h +++ b/examples/common_components/protocol_examples_common/include/addr_from_stdin.h @@ -12,14 +12,14 @@ #pragma once -#ifdef __cplusplus -extern "C" { -#endif - #include "lwip/sys.h" #include #include +#ifdef __cplusplus +extern "C" { +#endif + /** * @brief Read and evaluate IP address from stdin * diff --git a/examples/common_components/protocol_examples_common/include/example_common_private.h b/examples/common_components/protocol_examples_common/include/example_common_private.h new file mode 100644 index 0000000000..03518bfbac --- /dev/null +++ b/examples/common_components/protocol_examples_common/include/example_common_private.h @@ -0,0 +1,60 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +/* Private Funtions of protocol example common */ + +#pragma once + +#include "esp_err.h" +#include "esp_wifi.h" +#include "sdkconfig.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if CONFIG_EXAMPLE_CONNECT_IPV6 +#define NR_OF_IP_ADDRESSES_TO_WAIT_FOR (2) +#else +#define NR_OF_IP_ADDRESSES_TO_WAIT_FOR (1) +#endif + + +#if CONFIG_EXAMPLE_CONNECT_IPV6 +#define MAX_IP6_ADDRS_PER_NETIF (5) + +#if defined(CONFIG_EXAMPLE_CONNECT_IPV6_PREF_LOCAL_LINK) +#define EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE ESP_IP6_ADDR_IS_LINK_LOCAL +#elif defined(CONFIG_EXAMPLE_CONNECT_IPV6_PREF_GLOBAL) +#define EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE ESP_IP6_ADDR_IS_GLOBAL +#elif defined(CONFIG_EXAMPLE_CONNECT_IPV6_PREF_SITE_LOCAL) +#define EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE ESP_IP6_ADDR_IS_SITE_LOCAL +#elif defined(CONFIG_EXAMPLE_CONNECT_IPV6_PREF_UNIQUE_LOCAL) +#define EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE ESP_IP6_ADDR_IS_UNIQUE_LOCAL +#endif // if-elif CONFIG_EXAMPLE_CONNECT_IPV6_PREF_... + +#endif + + +#if CONFIG_EXAMPLE_CONNECT_IPV6 +extern const char *example_ipv6_addr_types_to_str[6]; +#endif + +void example_wifi_start(void); +void example_wifi_stop(void); +esp_err_t example_wifi_sta_do_connect(wifi_config_t wifi_config, bool wait); +esp_err_t example_wifi_sta_do_disconnect(void); +bool example_is_our_netif(const char *prefix, esp_netif_t *netif); +void example_print_all_netif_ips(const char *prefix); +void example_wifi_shutdown(void); +esp_err_t example_wifi_connect(void); +void example_ethernet_shutdown(void); +esp_err_t example_ethernet_connect(void); + + + +#ifdef __cplusplus +} +#endif diff --git a/examples/common_components/protocol_examples_common/include/protocol_examples_common.h b/examples/common_components/protocol_examples_common/include/protocol_examples_common.h index d43e94e0d0..3a318c6526 100644 --- a/examples/common_components/protocol_examples_common/include/protocol_examples_common.h +++ b/examples/common_components/protocol_examples_common/include/protocol_examples_common.h @@ -9,25 +9,32 @@ #pragma once +#include "sdkconfig.h" +#include "esp_err.h" +#include "esp_netif.h" +#if CONFIG_EXAMPLE_CONNECT_ETHERNET +#include "esp_eth.h" +#endif + #ifdef __cplusplus extern "C" { #endif -#include "esp_err.h" -#include "esp_netif.h" -#include "esp_eth.h" - -#ifdef CONFIG_EXAMPLE_CONNECT_ETHERNET -#define EXAMPLE_INTERFACE get_example_netif() +#if CONFIG_EXAMPLE_CONNECT_WIFI +#define EXAMPLE_NETIF_DESC_STA "example_netif_sta" #endif -#ifdef CONFIG_EXAMPLE_CONNECT_WIFI -#define EXAMPLE_INTERFACE get_example_netif() +#if CONFIG_EXAMPLE_CONNECT_ETHERNET +#define EXAMPLE_NETIF_DESC_ETH "example_netif_eth" #endif -#if !defined (CONFIG_EXAMPLE_CONNECT_ETHERNET) && !defined (CONFIG_EXAMPLE_CONNECT_WIFI) -// This is useful for some tests which do not need a network connection -#define EXAMPLE_INTERFACE NULL +/* Example default interface, prefer the ethernet one if running in example-test (CI) configuration */ +#if CONFIG_EXAMPLE_CONNECT_ETHERNET +#define EXAMPLE_INTERFACE get_example_netif_from_desc(EXAMPLE_NETIF_DESC_ETH) +#define get_example_netif() get_example_netif_from_desc(EXAMPLE_NETIF_DESC_ETH) +#elif CONFIG_EXAMPLE_CONNECT_WIFI +#define EXAMPLE_INTERFACE get_example_netif_from_desc(EXAMPLE_NETIF_DESC_STA) +#define get_example_netif() get_example_netif_from_desc(EXAMPLE_NETIF_DESC_STA) #endif /** @@ -60,15 +67,6 @@ esp_err_t example_disconnect(void); */ esp_err_t example_configure_stdin_stdout(void); -/** - * @brief Returns esp-netif pointer created by example_connect() - * - * @note If multiple interfaces active at once, this API return NULL - * In that case the get_example_netif_from_desc() should be used - * to get esp-netif pointer based on interface description - */ -esp_netif_t *get_example_netif(void); - /** * @brief Returns esp-netif pointer created by example_connect() described by * the supplied desc field @@ -79,7 +77,16 @@ esp_netif_t *get_example_netif(void); */ esp_netif_t *get_example_netif_from_desc(const char *desc); -#ifdef CONFIG_EXAMPLE_CONNECT_ETHERNET +#if CONFIG_EXAMPLE_PROVIDE_WIFI_CONSOLE_CMD +/** + * @brief Register wifi connect commands + * + * @note Provide wifi connect commands using esp_console. + */ +void register_wifi_connect_commands(void); +#endif + +#if CONFIG_EXAMPLE_CONNECT_ETHERNET /** * @brief Get the example Ethernet driver handle * diff --git a/examples/common_components/protocol_examples_common/stdin_out.c b/examples/common_components/protocol_examples_common/stdin_out.c index b57e0e7156..5fbc8a38af 100644 --- a/examples/common_components/protocol_examples_common/stdin_out.c +++ b/examples/common_components/protocol_examples_common/stdin_out.c @@ -15,6 +15,10 @@ esp_err_t example_configure_stdin_stdout(void) { + static bool configured = false; + if (configured) { + return ESP_OK; + } // Initialize VFS & UART so we can use std::cout/cin setvbuf(stdin, NULL, _IONBF, 0); /* Install UART driver for interrupt-driven reads and writes */ @@ -25,5 +29,6 @@ esp_err_t example_configure_stdin_stdout(void) esp_vfs_dev_uart_port_set_rx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CR); /* Move the caret to the beginning of the next line on '\n' */ esp_vfs_dev_uart_port_set_tx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CRLF); + configured = true; return ESP_OK; } diff --git a/examples/common_components/protocol_examples_common/wifi_connect.c b/examples/common_components/protocol_examples_common/wifi_connect.c new file mode 100644 index 0000000000..d899141cb0 --- /dev/null +++ b/examples/common_components/protocol_examples_common/wifi_connect.c @@ -0,0 +1,236 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ +/* Common functions for protocol examples, to establish Wi-Fi or Ethernet connection. + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. + */ + +#include +#include "protocol_examples_common.h" +#include "example_common_private.h" +#include "esp_log.h" + +#if CONFIG_EXAMPLE_CONNECT_WIFI + +static const char *TAG = "example_connect"; +static esp_netif_t *s_example_sta_netif = NULL; +static SemaphoreHandle_t s_semph_get_ip_addrs = NULL; + +#if CONFIG_EXAMPLE_WIFI_SCAN_METHOD_FAST +#define EXAMPLE_WIFI_SCAN_METHOD WIFI_FAST_SCAN +#elif CONFIG_EXAMPLE_WIFI_SCAN_METHOD_ALL_CHANNEL +#define EXAMPLE_WIFI_SCAN_METHOD WIFI_ALL_CHANNEL_SCAN +#endif + +#if CONFIG_EXAMPLE_WIFI_CONNECT_AP_BY_SIGNAL +#define EXAMPLE_WIFI_CONNECT_AP_SORT_METHOD WIFI_CONNECT_AP_BY_SIGNAL +#elif CONFIG_EXAMPLE_WIFI_CONNECT_AP_BY_SECURITY +#define EXAMPLE_WIFI_CONNECT_AP_SORT_METHOD WIFI_CONNECT_AP_BY_SECURITY +#endif + +#if CONFIG_EXAMPLE_WIFI_AUTH_OPEN +#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_OPEN +#elif CONFIG_EXAMPLE_WIFI_AUTH_WEP +#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WEP +#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA_PSK +#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_PSK +#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA2_PSK +#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_PSK +#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA_WPA2_PSK +#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_WPA2_PSK +#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA2_ENTERPRISE +#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_ENTERPRISE +#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA3_PSK +#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA3_PSK +#elif CONFIG_EXAMPLE_WIFI_AUTH_WPA2_WPA3_PSK +#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA2_WPA3_PSK +#elif CONFIG_EXAMPLE_WIFI_AUTH_WAPI_PSK +#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WAPI_PSK +#endif + + +static void example_handler_on_wifi_disconnect(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + ESP_LOGI(TAG, "Wi-Fi disconnected, trying to reconnect..."); + esp_err_t err = esp_wifi_connect(); + if (err == ESP_ERR_WIFI_NOT_STARTED) { + return; + } + ESP_ERROR_CHECK(err); +} + +static void example_handler_on_wifi_connect(void *esp_netif, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ +#if CONFIG_EXAMPLE_CONNECT_IPV6 + esp_netif_create_ip6_linklocal(esp_netif); +#endif // CONFIG_EXAMPLE_CONNECT_IPV6 +} + +static void example_handler_on_sta_got_ip(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data; + if (!example_is_our_netif(EXAMPLE_NETIF_DESC_STA, event->esp_netif)) { + return; + } + ESP_LOGI(TAG, "Got IPv4 event: Interface \"%s\" address: " IPSTR, esp_netif_get_desc(event->esp_netif), IP2STR(&event->ip_info.ip)); + if (s_semph_get_ip_addrs) { + xSemaphoreGive(s_semph_get_ip_addrs); + } else { + ESP_LOGI(TAG, "- IPv4 address: " IPSTR ",", IP2STR(&event->ip_info.ip)); + } +} + +#if CONFIG_EXAMPLE_CONNECT_IPV6 +static void example_handler_on_sta_got_ipv6(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) +{ + ip_event_got_ip6_t *event = (ip_event_got_ip6_t *)event_data; + if (!example_is_our_netif(EXAMPLE_NETIF_DESC_STA, event->esp_netif)) { + return; + } + esp_ip6_addr_type_t ipv6_type = esp_netif_ip6_get_addr_type(&event->ip6_info.ip); + ESP_LOGI(TAG, "Got IPv6 event: Interface \"%s\" address: " IPV6STR ", type: %s", esp_netif_get_desc(event->esp_netif), + IPV62STR(event->ip6_info.ip), example_ipv6_addr_types_to_str[ipv6_type]); + + if (ipv6_type == EXAMPLE_CONNECT_PREFERRED_IPV6_TYPE) { + if (s_semph_get_ip_addrs) { + xSemaphoreGive(s_semph_get_ip_addrs); + } else { + ESP_LOGI(TAG, "- IPv6 address: " IPV6STR ", type: %s", IPV62STR(event->ip6_info.ip), example_ipv6_addr_types_to_str[ipv6_type]); + } + } +} +#endif // CONFIG_EXAMPLE_CONNECT_IPV6 + + +void example_wifi_start(void) +{ + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + + esp_netif_inherent_config_t esp_netif_config = ESP_NETIF_INHERENT_DEFAULT_WIFI_STA(); + // Warning: the interface desc is used in tests to capture actual connection details (IP, gw, mask) + esp_netif_config.if_desc = EXAMPLE_NETIF_DESC_STA; + esp_netif_config.route_prio = 128; + s_example_sta_netif = esp_netif_create_wifi(WIFI_IF_STA, &esp_netif_config); + esp_wifi_set_default_wifi_sta_handlers(); + + ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_start()); +} + + +void example_wifi_stop(void) +{ + esp_err_t err = esp_wifi_stop(); + if (err == ESP_ERR_WIFI_NOT_INIT) { + return; + } + ESP_ERROR_CHECK(err); + ESP_ERROR_CHECK(esp_wifi_deinit()); + ESP_ERROR_CHECK(esp_wifi_clear_default_wifi_driver_and_handlers(s_example_sta_netif)); + esp_netif_destroy(s_example_sta_netif); + s_example_sta_netif = NULL; +} + + +esp_err_t example_wifi_sta_do_connect(wifi_config_t wifi_config, bool wait) +{ + if (wait) { + s_semph_get_ip_addrs = xSemaphoreCreateCounting(NR_OF_IP_ADDRESSES_TO_WAIT_FOR, 0); + } + + ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &example_handler_on_wifi_disconnect, NULL)); + ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &example_handler_on_sta_got_ip, NULL)); + ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, &example_handler_on_wifi_connect, s_example_sta_netif)); +#if CONFIG_EXAMPLE_CONNECT_IPV6 + ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_GOT_IP6, &example_handler_on_sta_got_ipv6, NULL)); +#endif + + ESP_LOGI(TAG, "Connecting to %s...", wifi_config.sta.ssid); + ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config)); + esp_err_t ret = esp_wifi_connect(); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "WiFi connect failed! ret:%x", ret); + return ret; + } + if (wait) { + ESP_LOGI(TAG, "Waiting for IP(s)"); + for (int i = 0; i < NR_OF_IP_ADDRESSES_TO_WAIT_FOR; ++i) { + xSemaphoreTake(s_semph_get_ip_addrs, portMAX_DELAY); + } + } + return ESP_OK; +} + +esp_err_t example_wifi_sta_do_disconnect(void) +{ + ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &example_handler_on_wifi_disconnect)); + ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, &example_handler_on_sta_got_ip)); + ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, &example_handler_on_wifi_connect)); +#if CONFIG_EXAMPLE_CONNECT_IPV6 + ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_GOT_IP6, &example_handler_on_sta_got_ipv6)); +#endif + if (s_semph_get_ip_addrs) { + vSemaphoreDelete(s_semph_get_ip_addrs); + } + return esp_wifi_disconnect(); +} + +void example_wifi_shutdown(void) +{ + example_wifi_sta_do_disconnect(); + example_wifi_stop(); +} + +esp_err_t example_wifi_connect(void) +{ + ESP_LOGI(TAG, "Start example_connect."); + example_wifi_start(); + wifi_config_t wifi_config = { + .sta = { +#if !CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN + .ssid = CONFIG_EXAMPLE_WIFI_SSID, + .password = CONFIG_EXAMPLE_WIFI_PASSWORD, +#endif + .scan_method = EXAMPLE_WIFI_SCAN_METHOD, + .sort_method = EXAMPLE_WIFI_CONNECT_AP_SORT_METHOD, + .threshold.rssi = CONFIG_EXAMPLE_WIFI_SCAN_RSSI_THRESHOLD, + .threshold.authmode = EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD, + }, + }; +#if CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN + example_configure_stdin_stdout(); + char buf[32+64+2] = {0}; + ESP_LOGI(TAG, "Please input ssid password:"); + fgets(buf, sizeof(buf), stdin); + int len = strlen(buf); + buf[len-1] = '\0'; + memset(wifi_config.sta.ssid, 0, 32); + char *temp = strtok(buf, " "); + strncpy((char*)wifi_config.sta.ssid, temp, 32); + memset(wifi_config.sta.password, 0, 64); + temp = strtok(NULL, " "); + if (temp) { + strncpy((char*)wifi_config.sta.password, temp, 64); + } else { + wifi_config.sta.threshold.authmode = WIFI_AUTH_OPEN; + } +#endif + example_wifi_sta_do_connect(wifi_config, true); + return ESP_OK; +} + + +#endif /* CONFIG_EXAMPLE_CONNECT_WIFI */ diff --git a/examples/protocols/README.md b/examples/protocols/README.md index 701daebf94..c8088b0259 100644 --- a/examples/protocols/README.md +++ b/examples/protocols/README.md @@ -8,7 +8,7 @@ See the [README.md](../README.md) file in the upper level [examples](../) direct ### About the `example_connect()` Function -Protocols examples use a simple helper function, `example_connect()`, to establish Wi-Fi and/or Ethernet connection. This function is implemented in [examples/common_components/protocol_examples/common/connect.c](../common_components/protocol_examples_common/connect.c), and has a very simple behavior: block until connection is established and IP address is obtained, then return. This function is used to reduce the amount of boilerplate and to keep the example code focused on the protocol or library being demonstrated. +Protocols examples use a simple helper function, `example_connect()`, to establish Wi-Fi and/or Ethernet connection. This function is implemented in [examples/common_components/protocol_examples_common/include/protocol_examples_common.h](../common_components/protocol_examples_common/include/protocol_examples_common.h), and has a very simple behavior: block until connection is established and IP address is obtained, then return. This function is used to reduce the amount of boilerplate and to keep the example code focused on the protocol or library being demonstrated. The simple `example_connect()` function does not handle timeouts, does not gracefully handle various error conditions, and is only suited for use in examples. When developing real applications, this helper function needs to be replaced with full Wi-Fi / Ethernet connection handling code. Such code can be found in [examples/wifi/getting_started/](../wifi/getting_started) and [examples/ethernet/basic/](../ethernet/basic) examples. diff --git a/examples/system/ota/simple_ota_example/main/simple_ota_example.c b/examples/system/ota/simple_ota_example/main/simple_ota_example.c index 6de619cd1e..6b030ef7ec 100644 --- a/examples/system/ota/simple_ota_example/main/simple_ota_example.c +++ b/examples/system/ota/simple_ota_example/main/simple_ota_example.c @@ -33,9 +33,9 @@ #ifdef CONFIG_EXAMPLE_FIRMWARE_UPGRADE_BIND_IF /* The interface name value can refer to if_desc in esp_netif_defaults.h */ #if CONFIG_EXAMPLE_FIRMWARE_UPGRADE_BIND_IF_ETH -static const char *bind_interface_name = "eth"; +static const char *bind_interface_name = EXAMPLE_NETIF_DESC_ETH; #elif CONFIG_EXAMPLE_FIRMWARE_UPGRADE_BIND_IF_STA -static const char *bind_interface_name = "sta"; +static const char *bind_interface_name = EXAMPLE_NETIF_DESC_STA; #endif #endif diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index b9236666e5..735a2ae77f 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -1744,7 +1744,6 @@ examples/build_system/cmake/multi_config/main/multi_config_example_main.c examples/common_components/iperf/include/iperf.h examples/common_components/iperf/iperf.c examples/common_components/protocol_examples_common/addr_from_stdin.c -examples/common_components/protocol_examples_common/connect.c examples/common_components/protocol_examples_common/include/addr_from_stdin.h examples/common_components/protocol_examples_common/include/protocol_examples_common.h examples/common_components/protocol_examples_common/stdin_out.c From 9575f03b8d48cfe529575559cbf7753c9e403cd3 Mon Sep 17 00:00:00 2001 From: Chen Yudong Date: Sun, 3 Jul 2022 19:44:00 +0800 Subject: [PATCH 02/10] CI: fix ip address checker and trace log --- .../esp_local_ctrl/pytest_esp_local_ctrl.py | 2 +- .../https_request/pytest_https_request.py | 18 ++--- .../mqtt/ssl/mqtt_ssl_example_test.py | 2 +- .../mqtt/tcp/mqtt_tcp_example_test.py | 6 +- .../protocols/mqtt/ws/mqtt_ws_example_test.py | 2 +- .../mqtt/wss/mqtt_wss_example_test.py | 2 +- .../advanced_https_ota/pytest_advanced_ota.py | 75 +++++++++---------- .../native_ota_example/pytest_native_ota.py | 30 ++++---- .../pytest_pre_encrypted_ota.py | 6 +- .../simple_ota_example/pytest_simple_ota.py | 38 +++++----- 10 files changed, 90 insertions(+), 91 deletions(-) diff --git a/examples/protocols/esp_local_ctrl/pytest_esp_local_ctrl.py b/examples/protocols/esp_local_ctrl/pytest_esp_local_ctrl.py index 33d050a536..b32a80326e 100644 --- a/examples/protocols/esp_local_ctrl/pytest_esp_local_ctrl.py +++ b/examples/protocols/esp_local_ctrl/pytest_esp_local_ctrl.py @@ -45,7 +45,7 @@ def test_examples_esp_local_ctrl(dut: Dut) -> None: rel_project_path = os.path.join('examples', 'protocols', 'esp_local_ctrl') idf_path = get_sdk_path() - dut_ip = dut.expect(r'esp_netif_handlers: sta ip: (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})')[1].decode() + dut_ip = dut.expect(r'IPv4 address: (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})')[1].decode() dut.expect('esp_https_server: Starting server') dut.expect('esp_https_server: Server listening on port 443') dut.expect('control: esp_local_ctrl service started with name : my_esp_ctrl_device') diff --git a/examples/protocols/https_request/pytest_https_request.py b/examples/protocols/https_request/pytest_https_request.py index 6f3bc42b17..635506365d 100644 --- a/examples/protocols/https_request/pytest_https_request.py +++ b/examples/protocols/https_request/pytest_https_request.py @@ -98,10 +98,10 @@ def test_examples_protocol_https_request_cli_session_tickets(dut: Dut) -> None: dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r' (sta|eth) ip: (\d+\.\d+\.\d+\.\d+)', timeout=60)[2].decode() - print('Connected to AP with IP: {}'.format(ip_address)) + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=60)[2].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') dut.expect('Start https_request example', timeout=30) @@ -150,10 +150,10 @@ def test_examples_protocol_https_request_dynamic_buffers(dut: Dut) -> None: dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r' (sta|eth) ip: (\d+\.\d+\.\d+\.\d+)', timeout=60)[2].decode() - print('Connected to AP with IP: {}'.format(ip_address)) + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=60)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') # only check if one connection is established logging.info("Testing for \"https_request using crt bundle\" with mbedtls dynamic resource enabled") @@ -188,10 +188,10 @@ def test_examples_protocol_https_request(dut: Dut) -> None: dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r' (sta|eth) ip: (\d+\.\d+\.\d+\.\d+)', timeout=60)[2].decode() - print('Connected to AP with IP: {}'.format(ip_address)) + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=60)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') # Check for connection using crt bundle logging.info("Testing for \"https_request using crt bundle\"") diff --git a/examples/protocols/mqtt/ssl/mqtt_ssl_example_test.py b/examples/protocols/mqtt/ssl/mqtt_ssl_example_test.py index 79705413d6..dc879d184a 100644 --- a/examples/protocols/mqtt/ssl/mqtt_ssl_example_test.py +++ b/examples/protocols/mqtt/ssl/mqtt_ssl_example_test.py @@ -110,7 +110,7 @@ def test_examples_protocol_mqtt_ssl(env, extra_data): raise ValueError('ENV_TEST_FAILURE: Test script cannot connect to broker: {}'.format(broker_url)) dut1.start_app() try: - ip_address = dut1.expect(re.compile(r' eth ip: ([^,]+),'), timeout=30) + ip_address = dut1.expect(re.compile(r'IPv4 address: ([^,]+),'), timeout=30) print('Connected to AP with IP: {}'.format(ip_address)) except DUT.ExpectTimeout: print('ENV_TEST_FAILURE: Cannot connect to AP') diff --git a/examples/protocols/mqtt/tcp/mqtt_tcp_example_test.py b/examples/protocols/mqtt/tcp/mqtt_tcp_example_test.py index acf78ed442..35a719a566 100644 --- a/examples/protocols/mqtt/tcp/mqtt_tcp_example_test.py +++ b/examples/protocols/mqtt/tcp/mqtt_tcp_example_test.py @@ -76,10 +76,10 @@ def test_examples_protocol_mqtt_qos1(env, extra_data): dut1.start_app() # waiting for getting the IP address try: - ip_address = dut1.expect(re.compile(r' (sta|eth) ip: ([^,]+),'), timeout=30) - print('Connected to AP with IP: {}'.format(ip_address)) + ip_address = dut1.expect(re.compile(r'IPv4 address: ([^,]+),'), timeout=30) + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except DUT.ExpectTimeout: - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') print('writing to device: {}'.format('mqtt://' + host_ip + '\n')) dut1.write('mqtt://' + host_ip + '\n') diff --git a/examples/protocols/mqtt/ws/mqtt_ws_example_test.py b/examples/protocols/mqtt/ws/mqtt_ws_example_test.py index 60da603585..b4fc2fa38d 100644 --- a/examples/protocols/mqtt/ws/mqtt_ws_example_test.py +++ b/examples/protocols/mqtt/ws/mqtt_ws_example_test.py @@ -83,7 +83,7 @@ def test_examples_protocol_mqtt_ws(env, extra_data): raise ValueError('ENV_TEST_FAILURE: Test script cannot connect to broker: {}'.format(broker_url)) dut1.start_app() try: - ip_address = dut1.expect(re.compile(r' eth ip: ([^,]+),'), timeout=30) + ip_address = dut1.expect(re.compile(r'IPv4 address: ([^,]+),'), timeout=30) print('Connected to AP with IP: {}'.format(ip_address)) except DUT.ExpectTimeout: print('ENV_TEST_FAILURE: Cannot connect to AP') diff --git a/examples/protocols/mqtt/wss/mqtt_wss_example_test.py b/examples/protocols/mqtt/wss/mqtt_wss_example_test.py index a7825e82b8..b00a154741 100644 --- a/examples/protocols/mqtt/wss/mqtt_wss_example_test.py +++ b/examples/protocols/mqtt/wss/mqtt_wss_example_test.py @@ -87,7 +87,7 @@ def test_examples_protocol_mqtt_wss(env, extra_data): raise ValueError('ENV_TEST_FAILURE: Test script cannot connect to broker: {}'.format(broker_url)) dut1.start_app() try: - ip_address = dut1.expect(re.compile(r' eth ip: ([^,]+),'), timeout=30) + ip_address = dut1.expect(re.compile(r'IPv4 address: ([^,]+),'), timeout=30) print('Connected to AP with IP: {}'.format(ip_address)) except DUT.ExpectTimeout: print('ENV_TEST_FAILURE: Cannot connect to AP') diff --git a/examples/system/ota/advanced_https_ota/pytest_advanced_ota.py b/examples/system/ota/advanced_https_ota/pytest_advanced_ota.py index 8fdd2c8d00..52d019229c 100644 --- a/examples/system/ota/advanced_https_ota/pytest_advanced_ota.py +++ b/examples/system/ota/advanced_https_ota/pytest_advanced_ota.py @@ -125,13 +125,13 @@ def test_examples_protocol_advanced_https_ota_example(dut: Dut) -> None: thread1.daemon = True thread1.start() for i in range(iterations): - dut.expect('Loaded app from partition at offset', timeout=60) + dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r' (sta|eth) ip: ([^,]+),', timeout=30) - print('Connected to AP with IP: {}'.format(ip_address)) + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') dut.expect('Starting Advanced OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + bin_name)) @@ -177,11 +177,11 @@ def test_examples_protocol_advanced_https_ota_example_truncated_bin(dut: Dut) -> thread1.start() dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r' (sta|eth) ip: ([^,]+),', timeout=30) - print('Connected to AP with IP: {}'.format(ip_address)) + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') dut.expect('Starting Advanced OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + truncated_bin_name)) @@ -232,11 +232,11 @@ def test_examples_protocol_advanced_https_ota_example_truncated_header(dut: Dut) thread1.start() dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r' (sta|eth) ip: ([^,]+),', timeout=30) - print('Connected to AP with IP: {}'.format(ip_address)) + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') dut.expect('Starting Advanced OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + truncated_bin_name)) @@ -287,11 +287,11 @@ def test_examples_protocol_advanced_https_ota_example_random(dut: Dut) -> None: thread1.start() dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r' (sta|eth) ip: ([^,]+),', timeout=30) - print('Connected to AP with IP: {}'.format(ip_address)) + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') dut.expect('Starting Advanced OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + random_bin_name)) @@ -344,11 +344,11 @@ def test_examples_protocol_advanced_https_ota_example_invalid_chip_id(dut: Dut) thread1.start() dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r' (sta|eth) ip: ([^,]+),', timeout=30) - print('Connected to AP with IP: {}'.format(ip_address)) + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') dut.expect('Starting Advanced OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + random_bin_name)) @@ -384,10 +384,10 @@ def test_examples_protocol_advanced_https_ota_example_chunked(dut: Dut) -> None: try: dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r' (sta|eth) ip: ([^,]+),', timeout=30) - print('Connected to AP with IP: {}'.format(ip_address)) + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') dut.expect('Starting Advanced OTA example', timeout=30) @@ -434,13 +434,13 @@ def test_examples_protocol_advanced_https_ota_example_redirect_url(dut: Dut) -> thread3.start() dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r' (sta|eth) ip: ([^,]+),', timeout=30) - print('Connected to AP with IP: {}'.format(ip_address)) + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: thread1.terminate() thread2.terminate() thread3.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') dut.expect('Starting Advanced OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':' + str(redirection_server_port) + '/' + bin_name)) @@ -496,11 +496,11 @@ def test_examples_protocol_advanced_https_ota_example_anti_rollback(dut: Dut) -> # Positive Case dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r' (sta|eth) ip: ([^,]+),', timeout=30) - print('Connected to AP with IP: {}'.format(ip_address)) + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') dut.expect('Starting Advanced OTA example', timeout=30) # Use originally generated image with secure_version=1 @@ -554,10 +554,10 @@ def test_examples_protocol_advanced_https_ota_example_partial_request(dut: Dut) thread1.start() dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r' (sta|eth) ip: ([^,]+),', timeout=30) - print('Connected to AP with IP: {}'.format(ip_address)) + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: - print('ENV_TEST_FAILURE: Cannot connect to AP') + print('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') thread1.terminate() raise dut.expect('Starting Advanced OTA example', timeout=30) @@ -599,11 +599,10 @@ def test_examples_protocol_advanced_https_ota_example_nimble_gatts(dut: Dut) -> thread1.start() dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r' sta ip: ([^,]+),', timeout=30) - print('Connected to AP with IP: {}'.format(ip_address)) + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: - thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') dut.expect('Starting Advanced OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + bin_name)) @@ -643,11 +642,11 @@ def test_examples_protocol_advanced_https_ota_example_bluedroid_gatts(dut: Dut) thread1.start() dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r' sta ip: ([^,]+),', timeout=30) - print('Connected to AP with IP: {}'.format(ip_address)) + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') dut.expect('Starting Advanced OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + bin_name)) @@ -695,10 +694,10 @@ def test_examples_protocol_advanced_https_ota_example_openssl_aligned_bin(dut: D try: dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r' (sta|eth) ip: ([^,]+),', timeout=30) - print('Connected to AP with IP: {}'.format(ip_address)) + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') dut.expect('Starting Advanced OTA example', timeout=30) diff --git a/examples/system/ota/native_ota_example/pytest_native_ota.py b/examples/system/ota/native_ota_example/pytest_native_ota.py index baee45799a..4f5f113a92 100644 --- a/examples/system/ota/native_ota_example/pytest_native_ota.py +++ b/examples/system/ota/native_ota_example/pytest_native_ota.py @@ -154,11 +154,11 @@ def test_examples_protocol_native_ota_example(dut: Dut) -> None: for i in range(iterations): dut.expect('Loaded app from partition at offset', timeout=60) try: - ip_address = dut.expect(r' (sta|eth) ip: ([^,]+),', timeout=30) - print('Connected to AP with IP: {}'.format(ip_address)) + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') dut.expect('Starting OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + bin_name)) @@ -203,11 +203,11 @@ def test_examples_protocol_native_ota_example_truncated_bin(dut: Dut) -> None: thread1.start() dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r' (sta|eth) ip: ([^,]+),', timeout=30) - print('Connected to AP with IP: {}'.format(ip_address)) + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') dut.expect('Starting OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + truncated_bin_name)) @@ -253,11 +253,11 @@ def test_examples_protocol_native_ota_example_truncated_header(dut: Dut) -> None thread1.start() dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r' (sta|eth) ip: ([^,]+),', timeout=30) - print('Connected to AP with IP: {}'.format(ip_address)) + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') dut.expect('Starting OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + truncated_bin_name)) @@ -302,11 +302,11 @@ def test_examples_protocol_native_ota_example_random(dut: Dut) -> None: thread1.start() dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r' (sta|eth) ip: ([^,]+),', timeout=30) - print('Connected to AP with IP: {}'.format(ip_address)) + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') dut.expect('Starting OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + random_bin_name)) @@ -336,10 +336,10 @@ def test_examples_protocol_native_ota_example_chunked(dut: Dut) -> None: try: dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r' (sta|eth) ip: ([^,]+),', timeout=30) - print('Connected to AP with IP: {}'.format(ip_address)) + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') dut.expect('Starting OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':8070/' + bin_name)) diff --git a/examples/system/ota/pre_encrypted_ota/pytest_pre_encrypted_ota.py b/examples/system/ota/pre_encrypted_ota/pytest_pre_encrypted_ota.py index dd63bfda1d..86ef19f21e 100644 --- a/examples/system/ota/pre_encrypted_ota/pytest_pre_encrypted_ota.py +++ b/examples/system/ota/pre_encrypted_ota/pytest_pre_encrypted_ota.py @@ -76,11 +76,11 @@ def test_examples_protocol_pre_encrypted_ota_example(dut: Dut) -> None: dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r' (sta|eth) ip: ([^,]+),', timeout=30) - print('Connected to AP with IP: {}'.format(ip_address)) + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') dut.expect('Starting Pre Encrypted OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + enc_bin_name)) diff --git a/examples/system/ota/simple_ota_example/pytest_simple_ota.py b/examples/system/ota/simple_ota_example/pytest_simple_ota.py index b8c04f1415..68a52749e3 100644 --- a/examples/system/ota/simple_ota_example/pytest_simple_ota.py +++ b/examples/system/ota/simple_ota_example/pytest_simple_ota.py @@ -138,11 +138,11 @@ def test_examples_protocol_simple_ota_example(dut: Dut) -> None: check_sha256(sha256_bootloader, str(dut.expect(r'SHA-256 for bootloader:\s+([a-f0-9]){64}')[0])) check_sha256(sha256_app, str(dut.expect(r'SHA-256 for current firmware:\s+([a-f0-9]){64}')[0])) try: - ip_address = dut.expect(r' sta ip: ([^,]+),', timeout=30) - print('Connected to AP with IP: {}'.format(ip_address)) + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') dut.expect('Starting OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':8000/simple_ota.bin')) @@ -172,13 +172,13 @@ def test_examples_protocol_simple_ota_example_ethernet_with_spiram_config(dut: D thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, 8000)) thread1.daemon = True thread1.start() - dut.expect('Loaded app from partition at offset 0x10000', timeout=30) + dut.expect('Loaded app from partition at offset 0x10000', timeout=30)) try: - ip_address = dut.expect(r' eth ip: ([^,]+),', timeout=30) - print('Connected to AP with IP: {}'.format(ip_address)) + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') dut.expect('Starting OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':8000/simple_ota.bin')) @@ -215,11 +215,11 @@ def test_examples_protocol_simple_ota_example_with_flash_encryption(dut: Dut) -> dut.expect('Loaded app from partition at offset 0x20000', timeout=30) dut.expect('Flash encryption mode is DEVELOPMENT', timeout=10) try: - ip_address = dut.expect(r' eth ip: ([^,]+),', timeout=30) - print('Connected to AP with IP: {}'.format(ip_address)) + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') dut.expect('Starting OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':8000/simple_ota.bin')) @@ -255,11 +255,11 @@ def test_examples_protocol_simple_ota_example_with_flash_encryption_wifi(dut: Du dut.expect('Loaded app from partition at offset 0x20000', timeout=30) dut.expect('Flash encryption mode is DEVELOPMENT', timeout=10) try: - ip_address = dut.expect(r' sta ip: ([^,]+),', timeout=30) - print('Connected to AP with IP: {}'.format(ip_address)) + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') dut.expect('Starting OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':8000/simple_ota.bin')) @@ -295,11 +295,11 @@ def test_examples_protocol_simple_ota_example_with_verify_app_signature_on_updat check_sha256(sha256_bootloader, str(dut.expect(r'SHA-256 for bootloader:\s+([a-f0-9]){64}')[0])) check_sha256(sha256_app, str(dut.expect(r'SHA-256 for current firmware:\s+([a-f0-9]){64}')[0])) try: - ip_address = dut.expect(r' eth ip: ([^,]+),', timeout=30) - print('Connected to AP with IP: {}'.format(ip_address)) + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') dut.expect('Starting OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':8000/simple_ota.bin')) @@ -338,11 +338,11 @@ def test_examples_protocol_simple_ota_example_with_verify_app_signature_on_updat check_sha256(sha256_bootloader, str(dut.expect(r'SHA-256 for bootloader:\s+([a-f0-9]){64}')[0])) check_sha256(sha256_app, str(dut.expect(r'SHA-256 for current firmware:\s+([a-f0-9]){64}')[0])) try: - ip_address = dut.expect(r' eth ip: ([^,]+),', timeout=30) - print('Connected to AP with IP: {}'.format(ip_address)) + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') dut.expect('Starting OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':8000/simple_ota.bin')) From 4d9393fc53bc46dd211902f4874fe61a741a04a5 Mon Sep 17 00:00:00 2001 From: Chen Yudong Date: Mon, 4 Jul 2022 22:13:16 +0800 Subject: [PATCH 03/10] example: use example common componments in esp_local_ctrl --- .../Kconfig.projbuild | 7 ++ .../protocol_examples_common/connect.c | 10 +- .../protocol_examples_common/wifi_connect.c | 22 +++- .../protocols/esp_local_ctrl/CMakeLists.txt | 4 + .../esp_local_ctrl/main/Kconfig.projbuild | 20 ---- .../protocols/esp_local_ctrl/main/app_main.c | 104 +----------------- 6 files changed, 41 insertions(+), 126 deletions(-) delete mode 100644 examples/protocols/esp_local_ctrl/main/Kconfig.projbuild diff --git a/examples/common_components/protocol_examples_common/Kconfig.projbuild b/examples/common_components/protocol_examples_common/Kconfig.projbuild index 27e81c0fd3..ec6f731cc3 100644 --- a/examples/common_components/protocol_examples_common/Kconfig.projbuild +++ b/examples/common_components/protocol_examples_common/Kconfig.projbuild @@ -39,6 +39,13 @@ menu "Example Connection Configuration" WiFi password (WPA or WPA2) for the example to use. Can be left blank if the network has no security set. + config EXAMPLE_WIFI_CONN_MAX_RETRY + int "Maximum retry" + default 6 + help + Set the Maximum retry to avoid station reconnecting to the AP unlimited, + in case the AP is really inexistent. + choice EXAMPLE_WIFI_SCAN_METHOD prompt "WiFi Scan Method" default EXAMPLE_WIFI_SCAN_METHOD_ALL_CHANNEL diff --git a/examples/common_components/protocol_examples_common/connect.c b/examples/common_components/protocol_examples_common/connect.c index e141e52af6..8a7e28266b 100644 --- a/examples/common_components/protocol_examples_common/connect.c +++ b/examples/common_components/protocol_examples_common/connect.c @@ -82,17 +82,22 @@ void example_print_all_netif_ips(const char *prefix) esp_err_t example_connect(void) { #if CONFIG_EXAMPLE_CONNECT_ETHERNET - example_ethernet_connect(); + if (example_ethernet_connect() != ESP_OK) { + return ESP_FAIL; + } ESP_ERROR_CHECK(esp_register_shutdown_handler(&example_ethernet_shutdown)); #endif #if CONFIG_EXAMPLE_CONNECT_WIFI - example_wifi_connect(); + if (example_wifi_connect() != ESP_OK) { + return ESP_FAIL; + } ESP_ERROR_CHECK(esp_register_shutdown_handler(&example_wifi_shutdown)); #endif #if CONFIG_EXAMPLE_CONNECT_ETHERNET example_print_all_netif_ips(EXAMPLE_NETIF_DESC_ETH); #endif + #if CONFIG_EXAMPLE_CONNECT_WIFI example_print_all_netif_ips(EXAMPLE_NETIF_DESC_STA); #endif @@ -101,7 +106,6 @@ esp_err_t example_connect(void) } - esp_err_t example_disconnect(void) { #if CONFIG_EXAMPLE_CONNECT_ETHERNET diff --git a/examples/common_components/protocol_examples_common/wifi_connect.c b/examples/common_components/protocol_examples_common/wifi_connect.c index d899141cb0..a93a927e48 100644 --- a/examples/common_components/protocol_examples_common/wifi_connect.c +++ b/examples/common_components/protocol_examples_common/wifi_connect.c @@ -55,10 +55,23 @@ static SemaphoreHandle_t s_semph_get_ip_addrs = NULL; #define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WAPI_PSK #endif +static int s_retry_num = 0; static void example_handler_on_wifi_disconnect(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { + s_retry_num++; + if (s_retry_num > CONFIG_EXAMPLE_WIFI_CONN_MAX_RETRY) { + ESP_LOGI(TAG, "WiFi Connect failed %d times, stop reconnect.", s_retry_num); + if (s_semph_get_ip_addrs) { + /* let example_wifi_sta_do_connect() return */ + xSemaphoreGive(s_semph_get_ip_addrs); +#if CONFIG_EXAMPLE_CONNECT_IPV6 + xSemaphoreGive(s_semph_get_ip_addrs); +#endif + } + return; + } ESP_LOGI(TAG, "Wi-Fi disconnected, trying to reconnect..."); esp_err_t err = esp_wifi_connect(); if (err == ESP_ERR_WIFI_NOT_STARTED) { @@ -78,6 +91,7 @@ static void example_handler_on_wifi_connect(void *esp_netif, esp_event_base_t ev static void example_handler_on_sta_got_ip(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { + s_retry_num = 0; ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data; if (!example_is_our_netif(EXAMPLE_NETIF_DESC_STA, event->esp_netif)) { return; @@ -150,7 +164,7 @@ esp_err_t example_wifi_sta_do_connect(wifi_config_t wifi_config, bool wait) if (wait) { s_semph_get_ip_addrs = xSemaphoreCreateCounting(NR_OF_IP_ADDRESSES_TO_WAIT_FOR, 0); } - + s_retry_num = 0; ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &example_handler_on_wifi_disconnect, NULL)); ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &example_handler_on_sta_got_ip, NULL)); ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, &example_handler_on_wifi_connect, s_example_sta_netif)); @@ -170,6 +184,9 @@ esp_err_t example_wifi_sta_do_connect(wifi_config_t wifi_config, bool wait) for (int i = 0; i < NR_OF_IP_ADDRESSES_TO_WAIT_FOR; ++i) { xSemaphoreTake(s_semph_get_ip_addrs, portMAX_DELAY); } + if (s_retry_num > CONFIG_EXAMPLE_WIFI_CONN_MAX_RETRY) { + return ESP_FAIL; + } } return ESP_OK; } @@ -228,8 +245,7 @@ esp_err_t example_wifi_connect(void) wifi_config.sta.threshold.authmode = WIFI_AUTH_OPEN; } #endif - example_wifi_sta_do_connect(wifi_config, true); - return ESP_OK; + return example_wifi_sta_do_connect(wifi_config, true); } diff --git a/examples/protocols/esp_local_ctrl/CMakeLists.txt b/examples/protocols/esp_local_ctrl/CMakeLists.txt index 25fb64bc05..507a362b52 100644 --- a/examples/protocols/esp_local_ctrl/CMakeLists.txt +++ b/examples/protocols/esp_local_ctrl/CMakeLists.txt @@ -2,5 +2,9 @@ # in this exact order for cmake to work correctly cmake_minimum_required(VERSION 3.16) +# (Not part of the boilerplate) +# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection. +set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common) + include($ENV{IDF_PATH}/tools/cmake/project.cmake) project(esp_local_ctrl) diff --git a/examples/protocols/esp_local_ctrl/main/Kconfig.projbuild b/examples/protocols/esp_local_ctrl/main/Kconfig.projbuild deleted file mode 100644 index 8122aab3b8..0000000000 --- a/examples/protocols/esp_local_ctrl/main/Kconfig.projbuild +++ /dev/null @@ -1,20 +0,0 @@ -menu "Example Configuration" - - config EXAMPLE_WIFI_SSID - string "WiFi SSID" - default "myssid" - help - SSID (network name) for the example to connect to. - - config EXAMPLE_WIFI_PASSWORD - string "WiFi Password" - default "mypassword" - help - WiFi password (WPA or WPA2) for the example to use. - - config EXAMPLE_MAXIMUM_RETRY - int "Maximum retry" - default 5 - help - Set the Maximum retry to avoid station reconnecting to the AP unlimited when the AP is really inexistent. -endmenu diff --git a/examples/protocols/esp_local_ctrl/main/app_main.c b/examples/protocols/esp_local_ctrl/main/app_main.c index 72c8f50920..1fd98fd219 100644 --- a/examples/protocols/esp_local_ctrl/main/app_main.c +++ b/examples/protocols/esp_local_ctrl/main/app_main.c @@ -17,110 +17,13 @@ #include "esp_log.h" #include "nvs_flash.h" #include "sdkconfig.h" +#include "protocol_examples_common.h" #include "lwip/err.h" #include "lwip/sys.h" -/* The examples use WiFi configuration that you can set via 'idf.py menuconfig'. - - If you'd rather not, just change the below entries to strings with - the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" -*/ -#define EXAMPLE_ESP_WIFI_SSID CONFIG_EXAMPLE_WIFI_SSID -#define EXAMPLE_ESP_WIFI_PASS CONFIG_EXAMPLE_WIFI_PASSWORD -#define EXAMPLE_ESP_MAXIMUM_RETRY CONFIG_EXAMPLE_MAXIMUM_RETRY - -/* FreeRTOS event group to signal when we are connected*/ -static EventGroupHandle_t s_wifi_event_group; - -/* The event group allows multiple bits for each event, but we only care about two events: - * - we are connected to the AP with an IP - * - we failed to connect after the maximum amount of retries */ -#define WIFI_CONNECTED_BIT BIT0 -#define WIFI_FAIL_BIT BIT1 - static const char *TAG = "local_ctrl_example"; -static int s_retry_num = 0; - -static void event_handler(void* arg, esp_event_base_t event_base, - int32_t event_id, void* event_data) -{ - if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) { - esp_wifi_connect(); - } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) { - if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) { - esp_wifi_connect(); - s_retry_num++; - ESP_LOGI(TAG, "retry to connect to the AP"); - } else { - xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT); - } - ESP_LOGI(TAG,"connect to the AP fail"); - } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { - ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data; - ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip)); - s_retry_num = 0; - xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); - } -} - -esp_err_t wifi_init_sta(void) -{ - esp_err_t ret_value = ESP_OK; - s_wifi_event_group = xEventGroupCreate(); - - ESP_ERROR_CHECK(esp_netif_init()); - - ESP_ERROR_CHECK(esp_event_loop_create_default()); - esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta(); - assert(sta_netif); - - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - - ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL)); - ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL)); - - wifi_config_t wifi_config = { - .sta = { - .ssid = EXAMPLE_ESP_WIFI_SSID, - .password = EXAMPLE_ESP_WIFI_PASS - }, - }; - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) ); - ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config) ); - ESP_ERROR_CHECK(esp_wifi_start() ); - - ESP_LOGI(TAG, "wifi_init_sta finished."); - - /* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum - * number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */ - EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group, - WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, - pdFALSE, - pdFALSE, - portMAX_DELAY); - - /* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually - * happened. */ - if (bits & WIFI_CONNECTED_BIT) { - ESP_LOGI(TAG, "connected to ap SSID:%s password:%s", - EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS); - } else if (bits & WIFI_FAIL_BIT) { - ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s", - EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS); - ret_value = ESP_FAIL; - } else { - ESP_LOGE(TAG, "UNEXPECTED EVENT"); - ret_value = ESP_ERR_INVALID_STATE; - } - - ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler)); - ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler)); - vEventGroupDelete(s_wifi_event_group); - return ret_value; -} /* Function responsible for configuring and starting the esp_local_ctrl service. * See local_ctrl_service.c for implementation */ @@ -135,9 +38,10 @@ void app_main(void) ret = nvs_flash_init(); } ESP_ERROR_CHECK(ret); + ESP_ERROR_CHECK(esp_netif_init()); + ESP_ERROR_CHECK(esp_event_loop_create_default()); - ESP_LOGI(TAG, "ESP_WIFI_MODE_STA"); - if (wifi_init_sta() == ESP_OK) { + if (example_connect() == ESP_OK) { start_esp_local_ctrl_service(); } else { ESP_LOGI(TAG, "Connection failed, not starting esp_local_ctrl service"); From 5d0302e49f704a264fa2c2cc0a9d0a26910a8697 Mon Sep 17 00:00:00 2001 From: Chen Yudong Date: Sun, 3 Jul 2022 15:29:21 +0800 Subject: [PATCH 04/10] CI: add some common test methods --- .gitlab/ci/rules.yml | 4 + .../ci/python_packages/common_test_methods.py | 83 +++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 tools/ci/python_packages/common_test_methods.py diff --git a/.gitlab/ci/rules.yml b/.gitlab/ci/rules.yml index 01f3ec5f0a..854b9811d7 100644 --- a/.gitlab/ci/rules.yml +++ b/.gitlab/ci/rules.yml @@ -29,6 +29,7 @@ - "tools/ci/python_packages/idf_iperf_test_util/**/*" - "tools/ci/python_packages/tiny_test_fw/**/*" - "tools/ci/python_packages/ttfw_idf/**/*" + - "tools/ci/python_packages/common_test_methods.py" - "tools/esp_prov/**/*" - "examples/**/*" @@ -56,6 +57,7 @@ - "tools/ci/python_packages/gitlab_api.py" - "tools/ci/python_packages/tiny_test_fw/**/*" - "tools/ci/python_packages/ttfw_idf/**/*" + - "tools/ci/python_packages/common_test_methods.py" - "tools/test_apps/**/*" - "tools/ldgen/**/*" @@ -64,6 +66,7 @@ - "tools/ci/python_packages/gitlab_api.py" - "tools/ci/python_packages/tiny_test_fw/**/*" - "tools/ci/python_packages/ttfw_idf/**/*" + - "tools/ci/python_packages/common_test_methods.py" - "tools/unit-test-app/**/*" @@ -73,6 +76,7 @@ - "tools/ci/python_packages/gitlab_api.py" - "tools/ci/python_packages/tiny_test_fw/**/*" - "tools/ci/python_packages/ttfw_idf/**/*" + - "tools/ci/python_packages/common_test_methods.py" - "components/**/*" diff --git a/tools/ci/python_packages/common_test_methods.py b/tools/ci/python_packages/common_test_methods.py new file mode 100644 index 0000000000..6540dc2990 --- /dev/null +++ b/tools/ci/python_packages/common_test_methods.py @@ -0,0 +1,83 @@ +# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 + +import logging +import os +import socket + +import netifaces +import yaml + +ENV_CONFIG_FILE_SEARCH = [ + os.path.join(os.environ['IDF_PATH'], 'EnvConfig.yml'), + os.path.join(os.environ['IDF_PATH'], 'ci-test-runner-configs', os.environ.get('CI_RUNNER_DESCRIPTION', ''), 'EnvConfig.yml'), +] + + +def get_my_ip_by_interface(interface_name: str, ip_type: int = netifaces.AF_INET) -> str: + for i in netifaces.ifaddresses(interface_name)[ip_type]: + interface_name = i['addr'].replace('%{}'.format(interface_name), '') + assert isinstance(interface_name, str) + return interface_name + return '' + + +def get_my_ip4_by_getway(getway: str = '') -> str: + getways = netifaces.gateways() + for gw, iface_name, _ in getways[netifaces.AF_INET]: + if gw and gw == getway: + interface = iface_name + break + else: + interface = getways['default'][netifaces.AF_INET][1] + logging.debug('Using interface: {}.'.format(interface)) + address = netifaces.ifaddresses(interface)[netifaces.AF_INET] + assert isinstance(address[0]['addr'], str) + return address[0]['addr'] + + +def get_my_ip4_by_dest_ip(dest_ip: str = '') -> str: + if not dest_ip: + dest_ip = '8.8.8.8' + s1 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + s1.connect((dest_ip, 80)) + my_ip = s1.getsockname()[0] + s1.close() + assert isinstance(my_ip, str) + return my_ip + + +def get_my_interface_by_dest_ip(dest_ip: str = '') -> str: + my_ip = get_my_ip4_by_dest_ip(dest_ip) + interfaces = netifaces.interfaces() + for interface in interfaces: + try: + addresses = netifaces.ifaddresses(interface)[netifaces.AF_INET] + except KeyError: + continue + if my_ip in [a['addr'] for a in addresses]: + assert isinstance(interface, str) + return interface + logging.error('Can not get interface, dest ip is {}'.format(dest_ip)) + return '' + + +def get_env_config(env_key: str = '', config_file: str = '') -> dict: + if not config_file: + for _file in ENV_CONFIG_FILE_SEARCH: + if os.path.exists(_file): + config_file = _file + if not config_file: + return dict() + + with open(config_file, 'r') as f: + config = yaml.load(f.read(), Loader=yaml.SafeLoader) + assert isinstance(config, dict) + if not env_key: + return config + if env_key in config: + _config = config[env_key] + assert isinstance(_config, dict) + return _config + logging.warning('Can not get env config, key: {}'.format(env_key)) + return dict() From 472ac2671204e9e6848283025bd95da546c348a0 Mon Sep 17 00:00:00 2001 From: Chen Yudong Date: Sun, 3 Jul 2022 16:22:20 +0800 Subject: [PATCH 05/10] CI: update test cases to use different environment variables change test environments optimize asio udp server test fix icmp echo test case use ethernet_router env to run iperf test cases --- .gitlab/ci/target-test.yml | 35 +- examples/ethernet/iperf/iperf_test.py | 7 +- .../network/simple_sniffer/example_test.py | 52 -- .../simple_sniffer/pytest_simple_sniffer.py | 47 ++ examples/protocols/.build-test-rules.yml | 2 +- examples/protocols/cbor/pytest_cbor.py | 2 +- .../esp_local_ctrl/pytest_esp_local_ctrl.py | 2 +- .../pytest_http_server_advanced.py | 2 +- .../captive_portal/pytest_captive_portal.py | 2 +- .../pytest_http_server_persistence.py | 2 +- .../simple/pytest_http_server_simple.py | 4 +- .../pytest_ws_server_example.py | 2 +- .../https_request/pytest_https_request.py | 28 +- .../simple/pytest_https_server_simple.py | 4 +- .../wss_server/pytest_https_wss_server.py | 2 +- .../pytest_https_x509_bundle.py | 4 +- examples/protocols/icmp_echo/example_test.py | 33 - .../icmp_echo/main/echo_example_main.c | 4 +- .../protocols/icmp_echo/pytest_icmp_echo.py | 36 ++ .../mqtt/tcp/mqtt_tcp_example_test.py | 22 +- examples/protocols/sntp/example_test.py | 51 -- examples/protocols/sntp/pytest_sntp.py | 55 ++ examples/protocols/sntp/sdkconfig.ci | 1 + .../sockets/tcp_client/example_test.py | 21 +- .../protocols/sockets/tcp_client/sdkconfig.ci | 1 + .../sockets/tcp_server/example_test.py | 14 +- .../protocols/sockets/tcp_server/sdkconfig.ci | 1 + .../sockets/tcp_server/sdkconfig.ci.1 | 1 + .../sockets/udp_client/example_test.py | 21 +- .../protocols/sockets/udp_client/sdkconfig.ci | 1 + .../sockets/udp_server/example_test.py | 14 +- .../protocols/sockets/udp_server/sdkconfig.ci | 1 + .../advanced_https_ota/pytest_advanced_ota.py | 565 +++++++++--------- .../native_ota_example/pytest_native_ota.py | 249 ++++---- .../pytest_pre_encrypted_ota.py | 39 +- .../simple_ota_example/pytest_simple_ota.py | 222 ++++--- pytest.ini | 9 +- .../mqtt/publish_connect_test/app_test.py | 26 +- 38 files changed, 788 insertions(+), 796 deletions(-) delete mode 100644 examples/network/simple_sniffer/example_test.py create mode 100644 examples/network/simple_sniffer/pytest_simple_sniffer.py delete mode 100644 examples/protocols/icmp_echo/example_test.py create mode 100644 examples/protocols/icmp_echo/pytest_icmp_echo.py delete mode 100644 examples/protocols/sntp/example_test.py create mode 100644 examples/protocols/sntp/pytest_sntp.py diff --git a/.gitlab/ci/target-test.yml b/.gitlab/ci/target-test.yml index 928ab88261..274a479dc6 100644 --- a/.gitlab/ci/target-test.yml +++ b/.gitlab/ci/target-test.yml @@ -11,8 +11,14 @@ reports: junit: XUNIT_RESULT.xml expire_in: 1 week + variables: + GIT_DEPTH: 1 script: - retry_failed git clone $KNOWN_FAILURE_CASES_REPO known_failure_cases + # get runner env config file + - retry_failed git clone $TEST_ENV_CONFIG_REPO + - python $CHECKOUT_REF_SCRIPT ci-test-runner-configs ci-test-runner-configs + - cp ./ci-test-runner-configs/${CI_RUNNER_DESCRIPTION}/EnvConfig.yml EnvConfig.yml || true # using runner tags as markers to filter the test cases # Runner tags are comma separated, replace the comma with " and " for markers - job_tags=$(python tools/ci/python_packages/gitlab_api.py get_job_tags $CI_PROJECT_ID --job_id $CI_JOB_ID) @@ -80,13 +86,13 @@ example_test_pytest_esp32c3_flash_suspend: - build_pytest_examples_esp32c3 tags: [ esp32c3, flash_suspend ] -example_test_pytest_esp32_ethernet_ota: +example_test_pytest_esp32_ethernet_router: extends: - .pytest_examples_dir_template - .rules:test:example_test-esp32-ota-related_changes needs: - build_pytest_examples_esp32 - tags: [ esp32, ethernet_ota ] + tags: [ esp32, ethernet_router ] example_test_pytest_esp32_wifi_ota: extends: @@ -128,21 +134,29 @@ example_test_pytest_esp32_8mb_flash: - build_pytest_examples_esp32 tags: [ esp32, ethernet_flash_8m ] -example_test_pytest_esp32_wifi: +example_test_pytest_esp32_wifi_nearby: extends: - .pytest_examples_dir_template - .rules:test:example_test-esp32-wifi-related_changes needs: - build_pytest_examples_esp32 - tags: [ esp32, wifi ] + tags: [ esp32, wifi_nearby ] -example_test_pytest_esp32_wifi_bt: +example_test_pytest_esp32_wifi_router: extends: - .pytest_examples_dir_template - .rules:test:example_test-esp32 needs: - build_pytest_examples_esp32 - tags: [ esp32, wifi_bt ] + tags: [ esp32, wifi_router ] + +example_test_pytest_esp32_wifi_wlan: + extends: + - .pytest_examples_dir_template + - .rules:test:example_test-esp32 + needs: + - build_pytest_examples_esp32 + tags: [ esp32, wifi_wlan ] example_test_pytest_esp32_ethernet_ip101: extends: @@ -340,6 +354,7 @@ test_app_test_pytest_esp32s2_usb_host: junit: $LOG_PATH/*/XUNIT_RESULT.xml expire_in: 1 week variables: + GIT_DEPTH: 1 TEST_FW_PATH: "$CI_PROJECT_DIR/tools/tiny-test-fw" LOG_PATH: "$CI_PROJECT_DIR/TEST_LOGS" ENV_FILE: "$CI_PROJECT_DIR/ci-test-runner-configs/$CI_RUNNER_DESCRIPTION/EnvConfig.yml" @@ -434,7 +449,7 @@ example_test_protocols: extends: .example_test_esp32_template tags: - ESP32 - - Example_WIFI_Protocols + - wifi_router example_test_002: extends: .example_test_esp32_template @@ -446,7 +461,7 @@ example_test_ethernet: extends: .example_test_esp32_template tags: - ESP32 - - Example_Ethernet + - ethernet_router .example_test_003: extends: .example_test_esp32_template @@ -559,6 +574,7 @@ example_test_ESP32C3_SDSPI: needs: - assign_custom_test variables: + GIT_DEPTH: 1 TEST_CASE_PATH: "$CI_PROJECT_DIR/tools/test_apps" CONFIG_FILE_PATH: "${CI_PROJECT_DIR}/tools/test_apps/test_configs" @@ -605,7 +621,7 @@ test_app_test_eth: extends: .test_app_esp32_template tags: - ESP32 - - Example_EthKitV1 + - ethernet_router test_app_test_003: extends: .test_app_esp32_template @@ -666,6 +682,7 @@ test_app_test_flash_psram_f8r8: needs: # the assign already needs all the build jobs - assign_unit_test variables: + GIT_DEPTH: 1 TEST_CASE_PATH: "$CI_PROJECT_DIR/tools/unit-test-app" CONFIG_FILE_PATH: "${CI_PROJECT_DIR}/components/idf_test/unit_test/test_configs" diff --git a/examples/ethernet/iperf/iperf_test.py b/examples/ethernet/iperf/iperf_test.py index 3bc69271c9..751be5942f 100644 --- a/examples/ethernet/iperf/iperf_test.py +++ b/examples/ethernet/iperf/iperf_test.py @@ -14,7 +14,9 @@ import re import subprocess import time +import netifaces import ttfw_idf +from common_test_methods import get_env_config, get_my_ip_by_interface from idf_iperf_test_util import IperfUtility from tiny_test_fw import TinyFW @@ -53,14 +55,15 @@ class IperfTestUtilityEth(IperfUtility.IperfTestUtility): return dut_ip, rssi -@ttfw_idf.idf_example_test(env_tag='Example_Ethernet') +@ttfw_idf.idf_example_test(env_tag='ethernet_router') def test_ethernet_throughput_basic(env, _): # type: (Any, Any) -> None """ steps: | 1. test TCP tx rx and UDP tx rx throughput 2. compare with the pre-defined pass standard """ - pc_nic_ip = env.get_pc_nic_info('pc_nic', 'ipv4')['addr'] + pc_nic = get_env_config('wifi_router').get('pc_nic', 'eth1') + pc_nic_ip = get_my_ip_by_interface(pc_nic, netifaces.AF_INET) pc_iperf_log_file = os.path.join(env.log_path, 'pc_iperf_log.md') # 1. get DUT diff --git a/examples/network/simple_sniffer/example_test.py b/examples/network/simple_sniffer/example_test.py deleted file mode 100644 index f6b0601170..0000000000 --- a/examples/network/simple_sniffer/example_test.py +++ /dev/null @@ -1,52 +0,0 @@ -# SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD -# SPDX-License-Identifier: Apache-2.0 -from __future__ import unicode_literals - -import re -from typing import Any - -import ttfw_idf - - -@ttfw_idf.idf_example_test(env_tag='Example_WIFI_Protocols') -def test_examples_simple_sniffer(env, _): # type: (Any, Any) -> None - - dut = env.get_dut('simple_sniffer', 'examples/network/simple_sniffer', app_config_name='mem') - dut.start_app() - - dut.expect('sniffer>') - dut.write('pcap --open -f simple-sniffer') - dut.expect('cmd_pcap: open file successfully') - dut.write('sniffer -i wlan -c 2 -n 10') - dut.expect('cmd_sniffer: 10 packages will be captured') - dut.expect('cmd_sniffer: start WiFi promiscuous ok') - dut.expect('cmd_sniffer: stop promiscuous ok') - dut.write('pcap --summary -f simple-sniffer') - dut.expect('cmd_pcap: Memory is to be parsed') - dut.expect('Pcap packet Head:') - dut.expect('Magic Number: a1b2c3d4') - dut.expect(re.compile(r'Major Version: [0-9]*')) - dut.expect(re.compile(r'Minor Version: [0-9]*')) - dut.expect(re.compile(r'SnapLen: [0-9]*')) - dut.expect(re.compile(r'LinkType: [0-9]*')) - for i in range(0, 10): - dut.expect('Packet ' + str(i) + ':') - dut.expect(re.compile(r'Timestamp \(Seconds\): [0-9]*')) - dut.expect(re.compile(r'Timestamp \(Microseconds\): [0-9]*')) - dut.expect(re.compile(r'Capture Length: [0-9]*')) - dut.expect(re.compile(r'Packet Length: [0-9]*')) - dut.expect(re.compile(r'Frame Type: .*')) - dut.expect(re.compile(r'Frame Subtype: .*')) - dut.expect(re.compile(r'Destination: .*')) - dut.expect(re.compile(r'Source: .*')) - dut.expect('Pcap packet Number: 10') - dut.write('pcap --close -f simple-sniffer') - dut.expect('cmd_pcap: free memory successfully') - dut.expect('cmd_pcap: .pcap file close done') - - dut.write('') - dut.expect('sniffer>') - - -if __name__ == '__main__': - test_examples_simple_sniffer() diff --git a/examples/network/simple_sniffer/pytest_simple_sniffer.py b/examples/network/simple_sniffer/pytest_simple_sniffer.py new file mode 100644 index 0000000000..ac3b0be290 --- /dev/null +++ b/examples/network/simple_sniffer/pytest_simple_sniffer.py @@ -0,0 +1,47 @@ +# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 + +import pytest +from pytest_embedded import Dut + + +@pytest.mark.esp32 +@pytest.mark.wifi_nearby +@pytest.mark.parametrize('config', [ + 'mem', +], indirect=True) +def test_examples_simple_sniffer(dut: Dut) -> None: + sniffer_num = 10 + dut.expect('sniffer>') + dut.write('pcap --open -f simple-sniffer') + dut.expect('cmd_pcap: open file successfully') + dut.write(f'sniffer -i wlan -c 2 -n {sniffer_num}') + dut.expect(f'cmd_sniffer: {sniffer_num} packages will be captured') + dut.expect('cmd_sniffer: start WiFi promiscuous ok') + dut.expect('cmd_sniffer: stop promiscuous ok') + dut.write('pcap --summary -f simple-sniffer') + dut.expect('cmd_pcap: Memory is to be parsed') + dut.expect('Pcap packet Head:') + dut.expect('Magic Number: a1b2c3d4') + dut.expect(r'Major Version: [0-9]+') + dut.expect(r'Minor Version: [0-9]+') + dut.expect(r'SnapLen: [0-9]+') + dut.expect(r'LinkType: [0-9]+') + # Allow "save captured packet failed" once + for i in range(0, sniffer_num - 1): + dut.expect(f'Packet {i}:') + dut.expect(r'Timestamp \(Seconds\): [0-9]+') + dut.expect(r'Timestamp \(Microseconds\): [0-9]+') + dut.expect(r'Capture Length: [0-9]+') + dut.expect(r'Packet Length: [0-9]+') + dut.expect(r'Frame Type:\s+\w+') + dut.expect(r'Frame Subtype:\s+\w+') + dut.expect(r'Destination:\s+\w+') + dut.expect(r'Source:\s+\w+') + dut.expect(r'Pcap packet Number: \d+') + dut.write('pcap --close -f simple-sniffer') + dut.expect('cmd_pcap: free memory successfully') + dut.expect('cmd_pcap: .pcap file close done') + + dut.write('') + dut.expect('sniffer>') diff --git a/examples/protocols/.build-test-rules.yml b/examples/protocols/.build-test-rules.yml index 74bffb33cc..312167563c 100644 --- a/examples/protocols/.build-test-rules.yml +++ b/examples/protocols/.build-test-rules.yml @@ -108,7 +108,7 @@ examples/protocols/https_x509_bundle: examples/protocols/icmp_echo: disable_test: - - if: IDF_TARGET != "esp32" + - if: IDF_TARGET == "esp32c2" temporary: true reason: lack of runners diff --git a/examples/protocols/cbor/pytest_cbor.py b/examples/protocols/cbor/pytest_cbor.py index e10530f5a8..2516396cfe 100644 --- a/examples/protocols/cbor/pytest_cbor.py +++ b/examples/protocols/cbor/pytest_cbor.py @@ -9,7 +9,7 @@ from pytest_embedded import Dut @pytest.mark.supported_targets -@pytest.mark.wifi +@pytest.mark.generic def test_examples_cbor(dut: Dut) -> None: dut.expect(r'example: encoded buffer size \d+') diff --git a/examples/protocols/esp_local_ctrl/pytest_esp_local_ctrl.py b/examples/protocols/esp_local_ctrl/pytest_esp_local_ctrl.py index b32a80326e..3adab74337 100644 --- a/examples/protocols/esp_local_ctrl/pytest_esp_local_ctrl.py +++ b/examples/protocols/esp_local_ctrl/pytest_esp_local_ctrl.py @@ -39,7 +39,7 @@ class CustomProcess(object): @pytest.mark.supported_targets -@pytest.mark.wifi +@pytest.mark.wifi_router def test_examples_esp_local_ctrl(dut: Dut) -> None: rel_project_path = os.path.join('examples', 'protocols', 'esp_local_ctrl') diff --git a/examples/protocols/http_server/advanced_tests/pytest_http_server_advanced.py b/examples/protocols/http_server/advanced_tests/pytest_http_server_advanced.py index 1dc342ac62..c339321dae 100644 --- a/examples/protocols/http_server/advanced_tests/pytest_http_server_advanced.py +++ b/examples/protocols/http_server/advanced_tests/pytest_http_server_advanced.py @@ -35,7 +35,7 @@ from pytest_embedded import Dut @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.wifi +@pytest.mark.wifi_router def test_examples_protocol_http_server_advanced(dut: Dut) -> None: # Get binary file diff --git a/examples/protocols/http_server/captive_portal/pytest_captive_portal.py b/examples/protocols/http_server/captive_portal/pytest_captive_portal.py index b77a18977c..4db106cbac 100644 --- a/examples/protocols/http_server/captive_portal/pytest_captive_portal.py +++ b/examples/protocols/http_server/captive_portal/pytest_captive_portal.py @@ -72,7 +72,7 @@ def test_captive_page(ip: str, port: str, uri: str) -> bool: @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.wifi_bt +@pytest.mark.wifi_wlan @pytest.mark.xfail(reason='Runner unable to connect to target over WiFi', run=False) def test_example_captive_portal(dut: Dut) -> None: diff --git a/examples/protocols/http_server/persistent_sockets/pytest_http_server_persistence.py b/examples/protocols/http_server/persistent_sockets/pytest_http_server_persistence.py index 9eaf5a4900..d0245f943f 100644 --- a/examples/protocols/http_server/persistent_sockets/pytest_http_server_persistence.py +++ b/examples/protocols/http_server/persistent_sockets/pytest_http_server_persistence.py @@ -30,7 +30,7 @@ from pytest_embedded import Dut @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.wifi +@pytest.mark.wifi_router def test_examples_protocol_http_server_persistence(dut: Dut) -> None: # Get binary file diff --git a/examples/protocols/http_server/simple/pytest_http_server_simple.py b/examples/protocols/http_server/simple/pytest_http_server_simple.py index 3d34df56dd..65a0c296ad 100644 --- a/examples/protocols/http_server/simple/pytest_http_server_simple.py +++ b/examples/protocols/http_server/simple/pytest_http_server_simple.py @@ -62,7 +62,7 @@ class http_client_thread(threading.Thread): @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.wifi +@pytest.mark.wifi_router def test_examples_protocol_http_server_simple(dut: Dut) -> None: # Get binary file @@ -130,7 +130,7 @@ def test_examples_protocol_http_server_simple(dut: Dut) -> None: @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.wifi +@pytest.mark.wifi_router def test_examples_protocol_http_server_lru_purge_enable(dut: Dut) -> None: # Get binary file diff --git a/examples/protocols/http_server/ws_echo_server/pytest_ws_server_example.py b/examples/protocols/http_server/ws_echo_server/pytest_ws_server_example.py index cc660568a4..04ed4b3af6 100644 --- a/examples/protocols/http_server/ws_echo_server/pytest_ws_server_example.py +++ b/examples/protocols/http_server/ws_echo_server/pytest_ws_server_example.py @@ -51,7 +51,7 @@ class WsClient: @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.wifi +@pytest.mark.wifi_router def test_examples_protocol_http_ws_echo_server(dut: Dut) -> None: # Get binary file binary_file = os.path.join(dut.app.binary_path, 'ws_echo_server.bin') diff --git a/examples/protocols/https_request/pytest_https_request.py b/examples/protocols/https_request/pytest_https_request.py index 635506365d..a8b0e5df50 100644 --- a/examples/protocols/https_request/pytest_https_request.py +++ b/examples/protocols/https_request/pytest_https_request.py @@ -10,19 +10,11 @@ from typing import Callable import pexpect import pytest +from common_test_methods import get_my_ip4_by_dest_ip from pytest_embedded import Dut from RangeHTTPServer import RangeRequestHandler -def get_my_ip() -> str: - s1 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - s1.connect(('8.8.8.8', 80)) - my_ip = '' - my_ip = s1.getsockname()[0] - s1.close() - return my_ip - - def get_server_status(host_ip: str, port: int) -> bool: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_status = sock.connect_ex((host_ip, port)) @@ -86,7 +78,15 @@ def test_examples_protocol_https_request_cli_session_tickets(dut: Dut) -> None: bin_size = os.path.getsize(binary_file) logging.info('https_request_bin_size : {}KB'.format(bin_size // 1024)) # start test - host_ip = get_my_ip() + dut.expect('Loaded app from partition at offset', timeout=30) + try: + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=60)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + + # start https server + host_ip = get_my_ip4_by_dest_ip(ip_address) server_port = 8070 server_file = os.path.join(os.path.dirname(__file__), 'main', 'local_server_cert.pem') key_file = os.path.join(os.path.dirname(__file__), 'main', 'local_server_key.pem') @@ -96,17 +96,9 @@ def test_examples_protocol_https_request_cli_session_tickets(dut: Dut) -> None: thread1.start() logging.info('The server started on {}:{}'.format(host_ip, server_port)) - dut.expect('Loaded app from partition at offset', timeout=30) - try: - ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=60)[2].decode() - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') - dut.expect('Start https_request example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port))) - dut.write('https://' + host_ip + ':' + str(server_port)) logging.info("Testing for \"https_request using saved session\"") diff --git a/examples/protocols/https_server/simple/pytest_https_server_simple.py b/examples/protocols/https_server/simple/pytest_https_server_simple.py index d970391e01..f86eb3c606 100644 --- a/examples/protocols/https_server/simple/pytest_https_server_simple.py +++ b/examples/protocols/https_server/simple/pytest_https_server_simple.py @@ -93,7 +93,7 @@ success_response = '

Hello Secure World!

' @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.wifi +@pytest.mark.wifi_router def test_examples_protocol_https_server_simple(dut: Dut) -> None: """ steps: | @@ -168,7 +168,7 @@ def test_examples_protocol_https_server_simple(dut: Dut) -> None: @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.wifi +@pytest.mark.wifi_router @pytest.mark.parametrize('config', ['dynamic_buffer',], indirect=True) def test_examples_protocol_https_server_simple_dynamic_buffers(dut: Dut) -> None: # Test with mbedTLS dynamic buffer feature diff --git a/examples/protocols/https_server/wss_server/pytest_https_wss_server.py b/examples/protocols/https_server/wss_server/pytest_https_wss_server.py index f9c5f82d3c..fe3e0b2bd3 100644 --- a/examples/protocols/https_server/wss_server/pytest_https_wss_server.py +++ b/examples/protocols/https_server/wss_server/pytest_https_wss_server.py @@ -109,7 +109,7 @@ def test_multiple_client_keep_alive_and_async_response(ip, port, ca_file): # ty @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.wifi +@pytest.mark.wifi_router def test_examples_protocol_https_wss_server(dut: Dut) -> None: # Get binary file diff --git a/examples/protocols/https_x509_bundle/pytest_https_x509_bundle.py b/examples/protocols/https_x509_bundle/pytest_https_x509_bundle.py index 385b10bf15..e48eb1050d 100644 --- a/examples/protocols/https_x509_bundle/pytest_https_x509_bundle.py +++ b/examples/protocols/https_x509_bundle/pytest_https_x509_bundle.py @@ -11,7 +11,7 @@ from pytest_embedded import Dut @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.wifi +@pytest.mark.wifi_router def test_examples_protocol_https_x509_bundle(dut: Dut) -> None: """ steps: | @@ -33,7 +33,7 @@ def test_examples_protocol_https_x509_bundle(dut: Dut) -> None: @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.wifi +@pytest.mark.wifi_router @pytest.mark.parametrize('config', ['ssldyn',], indirect=True) def test_examples_protocol_https_x509_bundle_dynamic_buffer(dut: Dut) -> None: # test mbedtls dynamic resource diff --git a/examples/protocols/icmp_echo/example_test.py b/examples/protocols/icmp_echo/example_test.py deleted file mode 100644 index 3a0da81a71..0000000000 --- a/examples/protocols/icmp_echo/example_test.py +++ /dev/null @@ -1,33 +0,0 @@ -from __future__ import unicode_literals - -import os -import re - -import ttfw_idf - - -@ttfw_idf.idf_example_test(env_tag='Example_WIFI_Protocols') -def test_examples_icmp_echo(env, extra_data): - - dut = env.get_dut('icmp_echo', 'examples/protocols/icmp_echo') - dut.start_app() - - dut.expect('example_connect: Connected to') - dut.expect('esp>') - - ping_dest = os.getenv('EXAMPLE_ICMP_SERVER', 'www.espressif.com') - dut.write('ping {}'.format(ping_dest)) - - ip_re = r'\.'.join((r'\d{1,3}',) * 4) - ip = dut.expect(re.compile(r'64 bytes from ({}) icmp_seq=1 ttl=\d+ time=\d+ ms'.format(ip_re)))[0] - - # expect at least one more (there could be lost packets) - dut.expect(re.compile(r'64 bytes from {} icmp_seq=[2-5] ttl=\d+ time='.format(ip))) - - dut.expect(re.compile(r'5 packets transmitted, [2-5] received, \d{1,3}% packet loss')) - dut.write('') - dut.expect('esp>') - - -if __name__ == '__main__': - test_examples_icmp_echo() diff --git a/examples/protocols/icmp_echo/main/echo_example_main.c b/examples/protocols/icmp_echo/main/echo_example_main.c index 1530265bae..fba333bdd4 100644 --- a/examples/protocols/icmp_echo/main/echo_example_main.c +++ b/examples/protocols/icmp_echo/main/echo_example_main.c @@ -199,8 +199,6 @@ void app_main(void) ESP_ERROR_CHECK(nvs_flash_init()); ESP_ERROR_CHECK(esp_netif_init()); ESP_ERROR_CHECK(esp_event_loop_create_default()); - /* wait for active network connection */ - ESP_ERROR_CHECK(example_connect()); esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT(); // install console REPL environment @@ -215,6 +213,8 @@ void app_main(void) ESP_ERROR_CHECK(esp_console_new_repl_usb_serial_jtag(&usbjtag_config, &repl_config, &repl)); #endif + /* register wifi connect commands */ + register_wifi_connect_commands(); /* register command `ping` */ register_ping(); /* register command `quit` */ diff --git a/examples/protocols/icmp_echo/pytest_icmp_echo.py b/examples/protocols/icmp_echo/pytest_icmp_echo.py new file mode 100644 index 0000000000..7165e5c9da --- /dev/null +++ b/examples/protocols/icmp_echo/pytest_icmp_echo.py @@ -0,0 +1,36 @@ +# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 + +import os + +import pytest +from common_test_methods import get_env_config +from pytest_embedded import Dut + + +@pytest.mark.esp32 +@pytest.mark.esp32c3 +@pytest.mark.esp32s2 +@pytest.mark.esp32s3 +@pytest.mark.wifi_nearby +def test_protocols_icmp_echo(dut: Dut) -> None: + # get env config + env_config = get_env_config('wifi_nearby') + ap_ssid = env_config['ap_ssid'] + ap_password = env_config['ap_password'] + ap_channel = env_config.get('ap_channel', 0) + + dut.expect('esp>') + dut.write(f'wifi_connect {ap_ssid} {ap_password} -n {ap_channel}') + dut.expect('Got IPv4 event:', timeout=30) + + ping_dest = os.getenv('EXAMPLE_ICMP_SERVER', 'ci.espressif.cn') + dut.write('ping {} -c 5'.format(ping_dest)) + + # expect at least two packets (there could be lost packets) + ip = dut.expect(r'64 bytes from (\d+\.\d+\.\d+\.\d+) icmp_seq=\d ttl=\d+ time=\d+ ms')[1].decode() + dut.expect(fr'64 bytes from {ip} icmp_seq=[2-5] ttl=\d+ time=') + + dut.expect(r'5 packets transmitted, [2-5] received, \d{1,3}% packet loss') + dut.write('') + dut.expect('esp>') diff --git a/examples/protocols/mqtt/tcp/mqtt_tcp_example_test.py b/examples/protocols/mqtt/tcp/mqtt_tcp_example_test.py index 35a719a566..06c5691fd4 100644 --- a/examples/protocols/mqtt/tcp/mqtt_tcp_example_test.py +++ b/examples/protocols/mqtt/tcp/mqtt_tcp_example_test.py @@ -7,19 +7,12 @@ import time from threading import Thread import ttfw_idf +from common_test_methods import get_my_ip4_by_dest_ip from tiny_test_fw import DUT msgid = -1 -def get_my_ip(): - s1 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - s1.connect(('8.8.8.8', 80)) - my_ip = s1.getsockname()[0] - s1.close() - return my_ip - - def mqqt_server_sketch(my_ip, port): global msgid print('Starting the server on {}'.format(my_ip)) @@ -68,19 +61,20 @@ def test_examples_protocol_mqtt_qos1(env, extra_data): binary_file = os.path.join(dut1.app.binary_path, 'mqtt_tcp.bin') bin_size = os.path.getsize(binary_file) ttfw_idf.log_performance('mqtt_tcp_bin_size', '{}KB'.format(bin_size // 1024)) - # 1. start mqtt broker sketch - host_ip = get_my_ip() - thread1 = Thread(target=mqqt_server_sketch, args=(host_ip,1883)) - thread1.start() - # 2. start the dut test and wait till client gets IP address + # 1. start the dut test and wait till client gets IP address dut1.start_app() # waiting for getting the IP address try: - ip_address = dut1.expect(re.compile(r'IPv4 address: ([^,]+),'), timeout=30) + ip_address = dut1.expect(re.compile(r'IPv4 address: ([^,]+),'), timeout=30)[0] print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except DUT.ExpectTimeout: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + # 2. start mqtt broker sketch + host_ip = get_my_ip4_by_dest_ip(ip_address) + thread1 = Thread(target=mqqt_server_sketch, args=(host_ip,1883)) + thread1.start() + print('writing to device: {}'.format('mqtt://' + host_ip + '\n')) dut1.write('mqtt://' + host_ip + '\n') thread1.join() diff --git a/examples/protocols/sntp/example_test.py b/examples/protocols/sntp/example_test.py deleted file mode 100644 index ff9b888670..0000000000 --- a/examples/protocols/sntp/example_test.py +++ /dev/null @@ -1,51 +0,0 @@ -from __future__ import unicode_literals - -import datetime -import re - -import ttfw_idf -from tiny_test_fw import Utility - - -@ttfw_idf.idf_example_test(env_tag='Example_WIFI_Protocols') -def test_examples_sntp(env, extra_data): - - dut = env.get_dut('sntp', 'examples/protocols/sntp') - dut.start_app() - - dut.expect_all('Time is not set yet. Connecting to WiFi and getting time over NTP.', - 'Initializing SNTP', - re.compile(r'Waiting for system time to be set... \(\d+/\d+\)'), - 'Notification of a time synchronization event', - timeout=60) - - TIME_FORMAT = '%a %b %d %H:%M:%S %Y' - TIME_FORMAT_REGEX = r'\w+\s+\w+\s+\d{1,2}\s+\d{2}:\d{2}:\d{2} \d{4}' - TIME_DIFF = datetime.timedelta(seconds=10 + 2) # cpu spends 10 seconds in deep sleep - NY_time = None - SH_time = None - - def check_time(prev_NY_time, prev_SH_time): - NY_str = dut.expect(re.compile(r'The current date/time in New York is: ({})'.format(TIME_FORMAT_REGEX)))[0] - SH_str = dut.expect(re.compile(r'The current date/time in Shanghai is: ({})'.format(TIME_FORMAT_REGEX)))[0] - Utility.console_log('New York: "{}"'.format(NY_str)) - Utility.console_log('Shanghai: "{}"'.format(SH_str)) - dut.expect('Entering deep sleep for 10 seconds') - Utility.console_log('Sleeping...') - new_NY_time = datetime.datetime.strptime(NY_str, TIME_FORMAT) - new_SH_time = datetime.datetime.strptime(SH_str, TIME_FORMAT) - - # The initial time is not checked because datetime has problems with timezones - assert prev_NY_time is None or new_NY_time - prev_NY_time < TIME_DIFF - assert prev_SH_time is None or new_SH_time - prev_SH_time < TIME_DIFF - - return (new_NY_time, new_SH_time) - - NY_time, SH_time = check_time(NY_time, SH_time) - for i in range(2, 4): - dut.expect('example: Boot count: {}'.format(i), timeout=30) - NY_time, SH_time = check_time(NY_time, SH_time) - - -if __name__ == '__main__': - test_examples_sntp() diff --git a/examples/protocols/sntp/pytest_sntp.py b/examples/protocols/sntp/pytest_sntp.py new file mode 100644 index 0000000000..5488160a6a --- /dev/null +++ b/examples/protocols/sntp/pytest_sntp.py @@ -0,0 +1,55 @@ +# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 + +import datetime +import logging +from typing import Any, Tuple + +import pytest +from common_test_methods import get_env_config +from pytest_embedded import Dut + + +@pytest.mark.esp32 +@pytest.mark.wifi_nearby +def test_get_time_from_sntp_server(dut: Dut) -> None: + dut.expect('Time is not set yet. Connecting to WiFi and getting time over NTP.') + if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True: + # get env config + env_config = get_env_config('wifi_nearby') + ap_ssid = env_config['ap_ssid'] + ap_password = env_config['ap_password'] + dut.expect('Please input ssid password:') + dut.write(' '.join([ap_ssid, ap_password])) + dut.expect('IPv4 address:') + + dut.expect('Initializing SNTP') + dut.expect(r'Waiting for system time to be set... \(\d+/\d+\)') + dut.expect('Notification of a time synchronization event') + + TIME_FORMAT = '%a %b %d %H:%M:%S %Y' + TIME_FORMAT_REGEX = r'\w+\s+\w+\s+\d{1,2}\s+\d{2}:\d{2}:\d{2} \d{4}' + TIME_DIFF = datetime.timedelta(seconds=10 + 2) # cpu spends 10 seconds in deep sleep + NY_time = None + SH_time = None + + def check_time(prev_NY_time: Any, prev_SH_time: Any) -> Tuple[Any, Any]: + NY_str = dut.expect(r'The current date/time in New York is: ({})'.format(TIME_FORMAT_REGEX))[1].decode() + SH_str = dut.expect(r'The current date/time in Shanghai is: ({})'.format(TIME_FORMAT_REGEX))[1].decode() + logging.info('New York: "{}"'.format(NY_str)) + logging.info('Shanghai: "{}"'.format(SH_str)) + dut.expect('Entering deep sleep for 10 seconds') + logging.info('Sleeping...') + new_NY_time = datetime.datetime.strptime(NY_str, TIME_FORMAT) + new_SH_time = datetime.datetime.strptime(SH_str, TIME_FORMAT) + + # The initial time is not checked because datetime has problems with timezones + assert not prev_NY_time or new_NY_time - prev_NY_time < TIME_DIFF + assert not prev_SH_time or new_SH_time - prev_SH_time < TIME_DIFF + + return (new_NY_time, new_SH_time) + + NY_time, SH_time = check_time(NY_time, SH_time) + for i in range(2, 4): + dut.expect('example: Boot count: {}'.format(i), timeout=30) + NY_time, SH_time = check_time(NY_time, SH_time) diff --git a/examples/protocols/sntp/sdkconfig.ci b/examples/protocols/sntp/sdkconfig.ci index a4c701a007..16f7dc8089 100644 --- a/examples/protocols/sntp/sdkconfig.ci +++ b/examples/protocols/sntp/sdkconfig.ci @@ -1,2 +1,3 @@ CONFIG_SNTP_TIME_SERVER="time.windows.com" CONFIG_LWIP_SNTP_MAX_SERVERS=2 +CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN=y diff --git a/examples/protocols/sockets/tcp_client/example_test.py b/examples/protocols/sockets/tcp_client/example_test.py index f7412c2dd3..954ddcca09 100644 --- a/examples/protocols/sockets/tcp_client/example_test.py +++ b/examples/protocols/sockets/tcp_client/example_test.py @@ -17,18 +17,13 @@ from threading import Event, Thread import netifaces import ttfw_idf +from common_test_methods import get_env_config, get_my_interface_by_dest_ip, get_my_ip_by_interface # ----------- Config ---------- PORT = 3333 -INTERFACE = 'eth0' # ------------------------------- -def get_my_ip(type): - for i in netifaces.ifaddresses(INTERFACE)[type]: - return i['addr'].replace('%{}'.format(INTERFACE), '') - - class TcpServer: def __init__(self, port, family_addr, persist=False): @@ -85,7 +80,7 @@ class TcpServer: break -@ttfw_idf.idf_example_test(env_tag='Example_WIFI_Protocols') +@ttfw_idf.idf_example_test(env_tag='wifi_router') def test_examples_protocol_socket_tcpclient(env, extra_data): """ steps: @@ -93,6 +88,11 @@ def test_examples_protocol_socket_tcpclient(env, extra_data): 2. have the board connect to the server 3. send and receive data """ + # get env config + env_config = get_env_config('wifi_router') + ap_ssid = env_config['ap_ssid'] + ap_password = env_config['ap_password'] + dut1 = env.get_dut('tcp_client', 'examples/protocols/sockets/tcp_client', dut_class=ttfw_idf.ESP32DUT) # check and log bin size binary_file = os.path.join(dut1.app.binary_path, 'tcp_client.bin') @@ -101,21 +101,24 @@ def test_examples_protocol_socket_tcpclient(env, extra_data): # start test dut1.start_app() + dut1.expect('Please input ssid password:') + dut1.write(' '.join([ap_ssid, ap_password])) ipv4 = dut1.expect(re.compile(r' IPv4 address: ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)'), timeout=30)[0] ipv6_r = r':'.join((r'[0-9a-fA-F]{4}',) * 8) # expect all 8 octets from IPv6 (assumes it's printed in the long form) ipv6 = dut1.expect(re.compile(r' IPv6 address: ({})'.format(ipv6_r)), timeout=30)[0] print('Connected with IPv4={} and IPv6={}'.format(ipv4, ipv6)) + my_interface = get_my_interface_by_dest_ip(ipv4) # test IPv4 with TcpServer(PORT, socket.AF_INET): - server_ip = get_my_ip(netifaces.AF_INET) + server_ip = get_my_ip_by_interface(my_interface, netifaces.AF_INET) print('Connect tcp client to server IP={}'.format(server_ip)) dut1.write(server_ip) dut1.expect(re.compile(r'OK: Message from ESP32')) # test IPv6 with TcpServer(PORT, socket.AF_INET6): - server_ip = get_my_ip(netifaces.AF_INET6) + server_ip = get_my_ip_by_interface(my_interface, netifaces.AF_INET6) print('Connect tcp client to server IP={}'.format(server_ip)) dut1.write(server_ip) dut1.expect(re.compile(r'OK: Message from ESP32')) diff --git a/examples/protocols/sockets/tcp_client/sdkconfig.ci b/examples/protocols/sockets/tcp_client/sdkconfig.ci index 2484db7abb..5ab5e15221 100644 --- a/examples/protocols/sockets/tcp_client/sdkconfig.ci +++ b/examples/protocols/sockets/tcp_client/sdkconfig.ci @@ -1 +1,2 @@ +CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN=y CONFIG_EXAMPLE_SOCKET_IP_INPUT_STDIN=y diff --git a/examples/protocols/sockets/tcp_server/example_test.py b/examples/protocols/sockets/tcp_server/example_test.py index 42f5d9a41b..bf5763836a 100644 --- a/examples/protocols/sockets/tcp_server/example_test.py +++ b/examples/protocols/sockets/tcp_server/example_test.py @@ -14,10 +14,10 @@ import socket import sys import ttfw_idf +from common_test_methods import get_env_config, get_my_interface_by_dest_ip # ----------- Config ---------- PORT = 3333 -INTERFACE = 'eth0' # ------------------------------- @@ -46,7 +46,7 @@ def tcp_client(address, payload): return data.decode() -@ttfw_idf.idf_example_test(env_tag='Example_WIFI_Protocols') +@ttfw_idf.idf_example_test(env_tag='wifi_router') def test_examples_protocol_socket_tcpserver(env, extra_data): MESSAGE = 'Data to ESP' """ @@ -55,6 +55,11 @@ def test_examples_protocol_socket_tcpserver(env, extra_data): 2. have the board connect to the server 3. send and receive data """ + # get env config + env_config = get_env_config('wifi_router') + ap_ssid = env_config['ap_ssid'] + ap_password = env_config['ap_password'] + dut1 = env.get_dut('tcp_client', 'examples/protocols/sockets/tcp_server', dut_class=ttfw_idf.ESP32DUT) # check and log bin size binary_file = os.path.join(dut1.app.binary_path, 'tcp_server.bin') @@ -63,19 +68,22 @@ def test_examples_protocol_socket_tcpserver(env, extra_data): # start test dut1.start_app() + dut1.expect('Please input ssid password:') + dut1.write(' '.join([ap_ssid, ap_password])) ipv4 = dut1.expect(re.compile(r' IPv4 address: ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)'), timeout=30)[0] ipv6_r = r':'.join((r'[0-9a-fA-F]{4}',) * 8) # expect all 8 octets from IPv6 (assumes it's printed in the long form) ipv6 = dut1.expect(re.compile(r' IPv6 address: ({})'.format(ipv6_r)), timeout=30)[0] print('Connected with IPv4={} and IPv6={}'.format(ipv4, ipv6)) + interface = get_my_interface_by_dest_ip(ipv4) # test IPv4 received = tcp_client(ipv4, MESSAGE) if not received == MESSAGE: raise dut1.expect(MESSAGE) # test IPv6 - received = tcp_client('{}%{}'.format(ipv6, INTERFACE), MESSAGE) + received = tcp_client('{}%{}'.format(ipv6, interface), MESSAGE) if not received == MESSAGE: raise dut1.expect(MESSAGE) diff --git a/examples/protocols/sockets/tcp_server/sdkconfig.ci b/examples/protocols/sockets/tcp_server/sdkconfig.ci index bea22a4eb0..850b017832 100644 --- a/examples/protocols/sockets/tcp_server/sdkconfig.ci +++ b/examples/protocols/sockets/tcp_server/sdkconfig.ci @@ -1,2 +1,3 @@ +CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN=y CONFIG_EXAMPLE_IPV4=y CONFIG_EXAMPLE_IPV6=y diff --git a/examples/protocols/sockets/tcp_server/sdkconfig.ci.1 b/examples/protocols/sockets/tcp_server/sdkconfig.ci.1 index 432514013f..14607f2963 100644 --- a/examples/protocols/sockets/tcp_server/sdkconfig.ci.1 +++ b/examples/protocols/sockets/tcp_server/sdkconfig.ci.1 @@ -1,3 +1,4 @@ +CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN=y CONFIG_EXAMPLE_IPV4=y CONFIG_EXAMPLE_IPV6=n CONFIG_EXAMPLE_CONNECT_IPV6=n diff --git a/examples/protocols/sockets/udp_client/example_test.py b/examples/protocols/sockets/udp_client/example_test.py index 9919a3746d..4c656021eb 100644 --- a/examples/protocols/sockets/udp_client/example_test.py +++ b/examples/protocols/sockets/udp_client/example_test.py @@ -17,18 +17,13 @@ from threading import Event, Thread import netifaces import ttfw_idf +from common_test_methods import get_env_config, get_my_interface_by_dest_ip, get_my_ip_by_interface # ----------- Config ---------- PORT = 3333 -INTERFACE = 'eth0' # ------------------------------- -def get_my_ip(type): - for i in netifaces.ifaddresses(INTERFACE)[type]: - return i['addr'].replace('%{}'.format(INTERFACE), '') - - class UdpServer: def __init__(self, port, family_addr, persist=False): @@ -78,7 +73,7 @@ class UdpServer: break -@ttfw_idf.idf_example_test(env_tag='Example_WIFI_Protocols') +@ttfw_idf.idf_example_test(env_tag='wifi_router') def test_examples_protocol_socket_udpclient(env, extra_data): """ steps: @@ -86,6 +81,11 @@ def test_examples_protocol_socket_udpclient(env, extra_data): 2. have the board connect to the server 3. send and receive data """ + # get env config + env_config = get_env_config('wifi_router') + ap_ssid = env_config['ap_ssid'] + ap_password = env_config['ap_password'] + dut1 = env.get_dut('udp_client', 'examples/protocols/sockets/udp_client', dut_class=ttfw_idf.ESP32DUT) # check and log bin size binary_file = os.path.join(dut1.app.binary_path, 'udp_client.bin') @@ -94,21 +94,24 @@ def test_examples_protocol_socket_udpclient(env, extra_data): # start test dut1.start_app() + dut1.expect('Please input ssid password:') + dut1.write(' '.join([ap_ssid, ap_password])) ipv4 = dut1.expect(re.compile(r' IPv4 address: ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)'), timeout=30)[0] ipv6_r = r':'.join((r'[0-9a-fA-F]{4}',) * 8) # expect all 8 octets from IPv6 (assumes it's printed in the long form) ipv6 = dut1.expect(re.compile(r' IPv6 address: ({})'.format(ipv6_r)), timeout=30)[0] print('Connected with IPv4={} and IPv6={}'.format(ipv4, ipv6)) + my_interface = get_my_interface_by_dest_ip(ipv4) # test IPv4 with UdpServer(PORT, socket.AF_INET): - server_ip = get_my_ip(netifaces.AF_INET) + server_ip = get_my_ip_by_interface(my_interface, netifaces.AF_INET) print('Connect udp client to server IP={}'.format(server_ip)) dut1.write(server_ip) dut1.expect(re.compile(r'OK: Message from ESP32')) # test IPv6 with UdpServer(PORT, socket.AF_INET6): - server_ip = get_my_ip(netifaces.AF_INET6) + server_ip = get_my_ip_by_interface(my_interface, netifaces.AF_INET6) print('Connect udp client to server IP={}'.format(server_ip)) dut1.write(server_ip) dut1.expect(re.compile(r'OK: Message from ESP32')) diff --git a/examples/protocols/sockets/udp_client/sdkconfig.ci b/examples/protocols/sockets/udp_client/sdkconfig.ci index 2484db7abb..5ab5e15221 100644 --- a/examples/protocols/sockets/udp_client/sdkconfig.ci +++ b/examples/protocols/sockets/udp_client/sdkconfig.ci @@ -1 +1,2 @@ +CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN=y CONFIG_EXAMPLE_SOCKET_IP_INPUT_STDIN=y diff --git a/examples/protocols/sockets/udp_server/example_test.py b/examples/protocols/sockets/udp_server/example_test.py index 484c181dab..7c890e0878 100644 --- a/examples/protocols/sockets/udp_server/example_test.py +++ b/examples/protocols/sockets/udp_server/example_test.py @@ -14,10 +14,10 @@ import socket import sys import ttfw_idf +from common_test_methods import get_env_config, get_my_interface_by_dest_ip # ----------- Config ---------- PORT = 3333 -INTERFACE = 'eth0' # ------------------------------- @@ -49,7 +49,7 @@ def udp_client(address, payload): return reply.decode() -@ttfw_idf.idf_example_test(env_tag='Example_WIFI_Protocols') +@ttfw_idf.idf_example_test(env_tag='wifi_router') def test_examples_protocol_socket_udpserver(env, extra_data): MESSAGE = 'Data to ESP' MAX_RETRIES = 3 @@ -59,6 +59,11 @@ def test_examples_protocol_socket_udpserver(env, extra_data): 2. have the board connect to the server 3. send and receive data """ + # get env config + env_config = get_env_config('wifi_router') + ap_ssid = env_config['ap_ssid'] + ap_password = env_config['ap_password'] + dut1 = env.get_dut('udp_server', 'examples/protocols/sockets/udp_server', dut_class=ttfw_idf.ESP32DUT) # check and log bin size binary_file = os.path.join(dut1.app.binary_path, 'udp_server.bin') @@ -67,6 +72,8 @@ def test_examples_protocol_socket_udpserver(env, extra_data): # start test dut1.start_app() + dut1.expect('Please input ssid password:') + dut1.write(' '.join([ap_ssid, ap_password])) ipv4 = dut1.expect(re.compile(r' IPv4 address: ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)'), timeout=30)[0] ipv6_r = r':'.join((r'[0-9a-fA-F]{4}',) * 8) # expect all 8 octets from IPv6 (assumes it's printed in the long form) @@ -74,6 +81,7 @@ def test_examples_protocol_socket_udpserver(env, extra_data): print('Connected with IPv4={} and IPv6={}'.format(ipv4, ipv6)) dut1.expect(re.compile(r'Waiting for data'), timeout=10) + interface = get_my_interface_by_dest_ip(ipv4) # test IPv4 for _ in range(MAX_RETRIES): print('Testing UDP on IPv4...') @@ -88,7 +96,7 @@ def test_examples_protocol_socket_udpserver(env, extra_data): # test IPv6 for _ in range(MAX_RETRIES): print('Testing UDP on IPv6...') - received = udp_client('{}%{}'.format(ipv6, INTERFACE), MESSAGE) + received = udp_client('{}%{}'.format(ipv6, interface), MESSAGE) if received == MESSAGE: print('OK') break diff --git a/examples/protocols/sockets/udp_server/sdkconfig.ci b/examples/protocols/sockets/udp_server/sdkconfig.ci index bea22a4eb0..850b017832 100644 --- a/examples/protocols/sockets/udp_server/sdkconfig.ci +++ b/examples/protocols/sockets/udp_server/sdkconfig.ci @@ -1,2 +1,3 @@ +CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN=y CONFIG_EXAMPLE_IPV4=y CONFIG_EXAMPLE_IPV6=y diff --git a/examples/system/ota/advanced_https_ota/pytest_advanced_ota.py b/examples/system/ota/advanced_https_ota/pytest_advanced_ota.py index 52d019229c..295bee727c 100644 --- a/examples/system/ota/advanced_https_ota/pytest_advanced_ota.py +++ b/examples/system/ota/advanced_https_ota/pytest_advanced_ota.py @@ -1,5 +1,6 @@ # SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Unlicense OR CC0-1.0 +from ast import Try import http.server import multiprocessing import os @@ -12,6 +13,7 @@ from typing import Callable import pexpect import pytest +from common_test_methods import get_my_ip4_by_dest_ip from pytest_embedded import Dut from RangeHTTPServer import RangeRequestHandler @@ -19,15 +21,6 @@ server_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'test_cer key_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'test_certs/server_key.pem') -def get_my_ip() -> str: - s1 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - s1.connect(('8.8.8.8', 80)) - my_ip = '' - my_ip = s1.getsockname()[0] - s1.close() - return my_ip - - def https_request_handler() -> Callable[...,http.server.BaseHTTPRequestHandler]: """ Returns a request handler class that handles broken pipe exception @@ -104,86 +97,86 @@ def start_redirect_server(ota_image_dir: str, server_ip: str, server_port: int, @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.ethernet_ota +@pytest.mark.ethernet_router def test_examples_protocol_advanced_https_ota_example(dut: Dut) -> None: """ This is a positive test case, which downloads complete binary file multiple number of times. Number of iterations can be specified in variable iterations. steps: | - 1. join AP + 1. join AP/Ethernet 2. Fetch OTA image over HTTPS 3. Reboot with the new OTA image """ - try: - # Number of iterations to validate OTA - iterations = 3 - server_port = 8001 - bin_name = 'advanced_https_ota.bin' - # start test - host_ip = get_my_ip() + # Number of iterations to validate OTA + iterations = 3 + server_port = 8001 + bin_name = 'advanced_https_ota.bin' + # start test + for _ in range(iterations): + dut.expect('Loaded app from partition at offset', timeout=30) + try: + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + dut.expect('Starting Advanced OTA example', timeout=30) + + host_ip = get_my_ip4_by_dest_ip(ip_address) thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) thread1.daemon = True thread1.start() - for i in range(iterations): - dut.expect('Loaded app from partition at offset', timeout=30) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') - dut.expect('Starting Advanced OTA example', timeout=30) - + try: print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + bin_name)) dut.write('https://' + host_ip + ':' + str(server_port) + '/' + bin_name) - finally: - thread1.terminate() + finally: + thread1.terminate() @pytest.mark.esp32 @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.ethernet_ota +@pytest.mark.ethernet_router def test_examples_protocol_advanced_https_ota_example_truncated_bin(dut: Dut) -> None: """ Working of OTA if binary file is truncated is validated in this test case. Application should return with error message in this case. steps: | - 1. join AP + 1. join AP/Ethernet 2. Generate truncated binary file 3. Fetch OTA image over HTTPS 4. Check working of code if bin is truncated """ + server_port = 8001 + # Original binary file generated after compilation + bin_name = 'advanced_https_ota.bin' + # Truncated binary file to be generated from original binary file + truncated_bin_name = 'truncated.bin' + # Size of truncated file to be grnerated. This value can range from 288 bytes (Image header size) to size of original binary file + # truncated_bin_size is set to 64000 to reduce consumed by the test case + truncated_bin_size = 64000 + binary_file = os.path.join(dut.app.binary_path, bin_name) + with open(binary_file, 'rb+') as f: + with open(os.path.join(dut.app.binary_path, truncated_bin_name), 'wb+') as fo: + fo.write(f.read(truncated_bin_size)) + + binary_file = os.path.join(dut.app.binary_path, truncated_bin_name) + # start test + dut.expect('Loaded app from partition at offset', timeout=30) try: - server_port = 8001 - # Original binary file generated after compilation - bin_name = 'advanced_https_ota.bin' - # Truncated binary file to be generated from original binary file - truncated_bin_name = 'truncated.bin' - # Size of truncated file to be grnerated. This value can range from 288 bytes (Image header size) to size of original binary file - # truncated_bin_size is set to 64000 to reduce consumed by the test case - truncated_bin_size = 64000 - binary_file = os.path.join(dut.app.binary_path, bin_name) - with open(binary_file, 'rb+') as f: - with open(os.path.join(dut.app.binary_path, truncated_bin_name), 'wb+') as fo: - fo.write(f.read(truncated_bin_size)) + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + dut.expect('Starting Advanced OTA example', timeout=30) - binary_file = os.path.join(dut.app.binary_path, truncated_bin_name) - # start test - host_ip = get_my_ip() - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) - thread1.daemon = True - thread1.start() - dut.expect('Loaded app from partition at offset', timeout=30) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') - dut.expect('Starting Advanced OTA example', timeout=30) + # Start server + host_ip = get_my_ip4_by_dest_ip(ip_address) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) + thread1.daemon = True + thread1.start() + try: print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + truncated_bin_name)) dut.write('https://' + host_ip + ':' + str(server_port) + '/' + truncated_bin_name) dut.expect('Image validation failed, image is corrupted', timeout=30) @@ -199,46 +192,46 @@ def test_examples_protocol_advanced_https_ota_example_truncated_bin(dut: Dut) -> @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.ethernet_ota +@pytest.mark.ethernet_router def test_examples_protocol_advanced_https_ota_example_truncated_header(dut: Dut) -> None: """ Working of OTA if headers of binary file are truncated is vaildated in this test case. Application should return with error message in this case. steps: | - 1. join AP + 1. join AP/Ethernet 2. Generate binary file with truncated headers 3. Fetch OTA image over HTTPS 4. Check working of code if headers are not sent completely """ + server_port = 8001 + # Original binary file generated after compilation + bin_name = 'advanced_https_ota.bin' + # Truncated binary file to be generated from original binary file + truncated_bin_name = 'truncated_header.bin' + # Size of truncated file to be generated. This value should be less than 288 bytes (Image header size) + truncated_bin_size = 180 + # check and log bin size + binary_file = os.path.join(dut.app.binary_path, bin_name) + with open(binary_file, 'rb+') as f: + with open(os.path.join(dut.app.binary_path, truncated_bin_name), 'wb+') as fo: + fo.write(f.read(truncated_bin_size)) + + binary_file = os.path.join(dut.app.binary_path, truncated_bin_name) + # start test + dut.expect('Loaded app from partition at offset', timeout=30) try: - server_port = 8001 - # Original binary file generated after compilation - bin_name = 'advanced_https_ota.bin' - # Truncated binary file to be generated from original binary file - truncated_bin_name = 'truncated_header.bin' - # Size of truncated file to be generated. This value should be less than 288 bytes (Image header size) - truncated_bin_size = 180 - # check and log bin size - binary_file = os.path.join(dut.app.binary_path, bin_name) - with open(binary_file, 'rb+') as f: - with open(os.path.join(dut.app.binary_path, truncated_bin_name), 'wb+') as fo: - fo.write(f.read(truncated_bin_size)) + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + # Start server + host_ip = get_my_ip4_by_dest_ip(ip_address) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) + thread1.daemon = True + thread1.start() - binary_file = os.path.join(dut.app.binary_path, truncated_bin_name) - # start test - host_ip = get_my_ip() - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) - thread1.daemon = True - thread1.start() - dut.expect('Loaded app from partition at offset', timeout=30) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + try: dut.expect('Starting Advanced OTA example', timeout=30) - print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + truncated_bin_name)) dut.write('https://' + host_ip + ':' + str(server_port) + '/' + truncated_bin_name) dut.expect('advanced_https_ota_example: esp_https_ota_read_img_desc failed', timeout=30) @@ -254,46 +247,46 @@ def test_examples_protocol_advanced_https_ota_example_truncated_header(dut: Dut) @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.ethernet_ota +@pytest.mark.ethernet_router def test_examples_protocol_advanced_https_ota_example_random(dut: Dut) -> None: """ Working of OTA if random data is added in binary file are validated in this test case. Magic byte verification should fail in this case. steps: | - 1. join AP + 1. join AP/Ethernet 2. Generate random binary image 3. Fetch OTA image over HTTPS 4. Check working of code for random binary file """ + server_port = 8001 + # Random binary file to be generated + random_bin_name = 'random.bin' + # Size of random binary file. 32000 is choosen, to reduce the time required to run the test-case + random_bin_size = 32000 + # check and log bin size + binary_file = os.path.join(dut.app.binary_path, random_bin_name) + with open(binary_file, 'wb+') as fo: + # First byte of binary file is always set to zero. If first byte is generated randomly, + # in some cases it may generate 0xE9 which will result in failure of testcase. + fo.write(struct.pack('B', 0)) + for i in range(random_bin_size - 1): + fo.write(struct.pack('B', random.randrange(0,255,1))) + + # start test + dut.expect('Loaded app from partition at offset', timeout=30) try: - server_port = 8001 - # Random binary file to be generated - random_bin_name = 'random.bin' - # Size of random binary file. 32000 is choosen, to reduce the time required to run the test-case - random_bin_size = 32000 - # check and log bin size - binary_file = os.path.join(dut.app.binary_path, random_bin_name) - with open(binary_file, 'wb+') as fo: - # First byte of binary file is always set to zero. If first byte is generated randomly, - # in some cases it may generate 0xE9 which will result in failure of testcase. - fo.write(struct.pack('B', 0)) - for i in range(random_bin_size - 1): - fo.write(struct.pack('B', random.randrange(0,255,1))) + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + # Start server + host_ip = get_my_ip4_by_dest_ip(ip_address) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) + thread1.daemon = True + thread1.start() - # start test - host_ip = get_my_ip() - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) - thread1.daemon = True - thread1.start() - dut.expect('Loaded app from partition at offset', timeout=30) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + try: dut.expect('Starting Advanced OTA example', timeout=30) - print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + random_bin_name)) dut.write('https://' + host_ip + ':' + str(server_port) + '/' + random_bin_name) dut.expect(r'esp_https_ota: Incorrect app descriptor magic', timeout=10) @@ -309,48 +302,48 @@ def test_examples_protocol_advanced_https_ota_example_random(dut: Dut) -> None: @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.ethernet_ota +@pytest.mark.ethernet_router def test_examples_protocol_advanced_https_ota_example_invalid_chip_id(dut: Dut) -> None: """ Working of OTA if binary file have invalid chip id is validated in this test case. Chip id verification should fail in this case. steps: | - 1. join AP + 1. join AP/Ethernet 2. Generate binary image with invalid chip id 3. Fetch OTA image over HTTPS 4. Check working of code for random binary file """ + server_port = 8001 + bin_name = 'advanced_https_ota.bin' + # Random binary file to be generated + random_bin_name = 'random.bin' + random_binary_file = os.path.join(dut.app.binary_path, random_bin_name) + # Size of random binary file. 2000 is choosen, to reduce the time required to run the test-case + random_bin_size = 2000 + + binary_file = os.path.join(dut.app.binary_path, bin_name) + with open(binary_file, 'rb+') as f: + data = list(f.read(random_bin_size)) + # Changing Chip id + data[13] = 0xfe + with open(random_binary_file, 'wb+') as fo: + fo.write(bytearray(data)) + + # start test + dut.expect('Loaded app from partition at offset', timeout=30) try: - server_port = 8001 - bin_name = 'advanced_https_ota.bin' - # Random binary file to be generated - random_bin_name = 'random.bin' - random_binary_file = os.path.join(dut.app.binary_path, random_bin_name) - # Size of random binary file. 2000 is choosen, to reduce the time required to run the test-case - random_bin_size = 2000 + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + # Start server + host_ip = get_my_ip4_by_dest_ip(ip_address) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) + thread1.daemon = True + thread1.start() - binary_file = os.path.join(dut.app.binary_path, bin_name) - with open(binary_file, 'rb+') as f: - data = list(f.read(random_bin_size)) - # Changing Chip id - data[13] = 0xfe - with open(random_binary_file, 'wb+') as fo: - fo.write(bytearray(data)) - - # start test - host_ip = get_my_ip() - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) - thread1.daemon = True - thread1.start() - dut.expect('Loaded app from partition at offset', timeout=30) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + try: dut.expect('Starting Advanced OTA example', timeout=30) - print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + random_bin_name)) dut.write('https://' + host_ip + ':' + str(server_port) + '/' + random_bin_name) dut.expect(r'esp_https_ota: Mismatch chip id, expected 0, found \d', timeout=10) @@ -366,31 +359,31 @@ def test_examples_protocol_advanced_https_ota_example_invalid_chip_id(dut: Dut) @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.ethernet_ota +@pytest.mark.ethernet_router def test_examples_protocol_advanced_https_ota_example_chunked(dut: Dut) -> None: """ This is a positive test case, which downloads complete binary file multiple number of times. Number of iterations can be specified in variable iterations. steps: | - 1. join AP + 1. join AP/Ethernet 2. Fetch OTA image over HTTPS 3. Reboot with the new OTA image """ # File to be downloaded. This file is generated after compilation bin_name = 'advanced_https_ota.bin' # start test - host_ip = get_my_ip() - chunked_server = start_chunked_server(dut.app.binary_path, 8070) + dut.expect('Loaded app from partition at offset', timeout=30) try: - dut.expect('Loaded app from partition at offset', timeout=30) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + # Start server + host_ip = get_my_ip4_by_dest_ip(ip_address) + chunked_server = start_chunked_server(dut.app.binary_path, 8070) + try: dut.expect('Starting Advanced OTA example', timeout=30) - print('writing to device: {}'.format('https://' + host_ip + ':8070/' + bin_name)) dut.write('https://' + host_ip + ':8070/' + bin_name) dut.expect('Loaded app from partition at offset', timeout=60) @@ -403,46 +396,45 @@ def test_examples_protocol_advanced_https_ota_example_chunked(dut: Dut) -> None: @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.ethernet_ota +@pytest.mark.ethernet_router def test_examples_protocol_advanced_https_ota_example_redirect_url(dut: Dut) -> None: """ This is a positive test case, which starts a server and a redirection server. Redirection server redirects http_request to different port Number of iterations can be specified in variable iterations. steps: | - 1. join AP + 1. join AP/Ethernet 2. Fetch OTA image over HTTPS 3. Reboot with the new OTA image """ + server_port = 8001 + # Port to which the request should be redirected + redirection_server_port = 8081 + redirection_server_port1 = 8082 + # File to be downloaded. This file is generated after compilation + bin_name = 'advanced_https_ota.bin' + # start test + dut.expect('Loaded app from partition at offset', timeout=30) try: - server_port = 8001 - # Port to which the request should be redirected - redirection_server_port = 8081 - redirection_server_port1 = 8082 - # File to be downloaded. This file is generated after compilation - bin_name = 'advanced_https_ota.bin' - # start test - host_ip = get_my_ip() - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) - thread1.daemon = True - thread1.start() - thread2 = multiprocessing.Process(target=start_redirect_server, args=(dut.app.binary_path, host_ip, redirection_server_port, redirection_server_port1)) - thread2.daemon = True - thread2.start() - thread3 = multiprocessing.Process(target=start_redirect_server, args=(dut.app.binary_path, host_ip, redirection_server_port1, server_port)) - thread3.daemon = True - thread3.start() - dut.expect('Loaded app from partition at offset', timeout=30) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - thread1.terminate() - thread2.terminate() - thread3.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') - dut.expect('Starting Advanced OTA example', timeout=30) + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + dut.expect('Starting Advanced OTA example', timeout=30) + # Start server + host_ip = get_my_ip4_by_dest_ip(ip_address) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) + thread1.daemon = True + thread2 = multiprocessing.Process(target=start_redirect_server, args=(dut.app.binary_path, host_ip, redirection_server_port, redirection_server_port1)) + thread2.daemon = True + thread3 = multiprocessing.Process(target=start_redirect_server, args=(dut.app.binary_path, host_ip, redirection_server_port1, server_port)) + thread3.daemon = True + + try: + thread1.start() + thread2.start() + thread3.start() print('writing to device: {}'.format('https://' + host_ip + ':' + str(redirection_server_port) + '/' + bin_name)) dut.write('https://' + host_ip + ':' + str(redirection_server_port) + '/' + bin_name) dut.expect('Loaded app from partition at offset', timeout=60) @@ -465,49 +457,49 @@ def test_examples_protocol_advanced_https_ota_example_anti_rollback(dut: Dut) -> Working of OTA when anti_rollback is enabled and security version of new image is less than current one. Application should return with error message in this case. steps: | - 1. join AP + 1. join AP/Ethernet 2. Generate binary file with lower security version 3. Fetch OTA image over HTTPS 4. Check working of anti_rollback feature """ + dut.serial.erase_flash() + dut.serial.flash() + server_port = 8001 + # Original binary file generated after compilation + bin_name = 'advanced_https_ota.bin' + # Modified firmware image to lower security version in its header. This is to enable negative test case + anti_rollback_bin_name = 'advanced_https_ota_lower_sec_version.bin' + # check and log bin size + binary_file = os.path.join(dut.app.binary_path, bin_name) + file_size = os.path.getsize(binary_file) + with open(binary_file, 'rb+') as f: + with open(os.path.join(dut.app.binary_path, anti_rollback_bin_name), 'wb+') as fo: + fo.write(f.read(file_size)) + # Change security_version to 0 for negative test case + fo.seek(36) + fo.write(b'\x00') + binary_file = os.path.join(dut.app.binary_path, anti_rollback_bin_name) + # start test + # Positive Case + dut.expect('Loaded app from partition at offset', timeout=30) try: - dut.serial.erase_flash() - dut.serial.flash() - server_port = 8001 - # Original binary file generated after compilation - bin_name = 'advanced_https_ota.bin' - # Modified firmware image to lower security version in its header. This is to enable negative test case - anti_rollback_bin_name = 'advanced_https_ota_lower_sec_version.bin' - # check and log bin size - binary_file = os.path.join(dut.app.binary_path, bin_name) - file_size = os.path.getsize(binary_file) - with open(binary_file, 'rb+') as f: - with open(os.path.join(dut.app.binary_path, anti_rollback_bin_name), 'wb+') as fo: - fo.write(f.read(file_size)) - # Change security_version to 0 for negative test case - fo.seek(36) - fo.write(b'\x00') - binary_file = os.path.join(dut.app.binary_path, anti_rollback_bin_name) - # start test - host_ip = get_my_ip() - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) - thread1.daemon = True - thread1.start() - # Positive Case - dut.expect('Loaded app from partition at offset', timeout=30) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') - dut.expect('Starting Advanced OTA example', timeout=30) + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + # Start server + host_ip = get_my_ip4_by_dest_ip(ip_address) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) + thread1.daemon = True + thread1.start() + try: + dut.expect('Starting Advanced OTA example', timeout=30) # Use originally generated image with secure_version=1 print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + bin_name)) dut.write('https://' + host_ip + ':' + str(server_port) + '/' + bin_name) dut.expect('Loaded app from partition at offset', timeout=60) - dut.expect(r' (sta|eth) ip: ([^,]+),', timeout=30) + dut.expect(r'IPv4 address: ([^,]+),', timeout=30) dut.expect(r'App is valid, rollback cancelled successfully', timeout=30) # Negative Case @@ -528,47 +520,47 @@ def test_examples_protocol_advanced_https_ota_example_anti_rollback(dut: Dut) -> @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.ethernet_ota +@pytest.mark.ethernet_router @pytest.mark.parametrize('config', ['partial_download',], indirect=True) def test_examples_protocol_advanced_https_ota_example_partial_request(dut: Dut) -> None: """ This is a positive test case, to test OTA workflow with Range HTTP header. steps: | - 1. join AP + 1. join AP/Ethernet 2. Fetch OTA image over HTTPS 3. Reboot with the new OTA image """ + server_port = 8001 + # Size of partial HTTP request + request_size = 16384 + # File to be downloaded. This file is generated after compilation + bin_name = 'advanced_https_ota.bin' + binary_file = os.path.join(dut.app.binary_path, bin_name) + bin_size = os.path.getsize(binary_file) + http_requests = int((bin_size / request_size) - 1) + # start test + dut.expect('Loaded app from partition at offset', timeout=30) try: - server_port = 8001 - # Size of partial HTTP request - request_size = 16384 - # File to be downloaded. This file is generated after compilation - bin_name = 'advanced_https_ota.bin' - binary_file = os.path.join(dut.app.binary_path, bin_name) - bin_size = os.path.getsize(binary_file) - http_requests = int((bin_size / request_size) - 1) - # start test - host_ip = get_my_ip() - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) - thread1.daemon = True - thread1.start() - dut.expect('Loaded app from partition at offset', timeout=30) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - print('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') - thread1.terminate() - raise - dut.expect('Starting Advanced OTA example', timeout=30) + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + print('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + raise + # Start server + host_ip = get_my_ip4_by_dest_ip(ip_address) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) + thread1.daemon = True + thread1.start() + try: + dut.expect('Starting Advanced OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + bin_name)) dut.write('https://' + host_ip + ':' + str(server_port) + '/' + bin_name) for _ in range(http_requests): dut.expect('Connection closed', timeout=60) dut.expect('Loaded app from partition at offset', timeout=60) dut.expect('Starting Advanced OTA example', timeout=30) - finally: + except: thread1.terminate() @@ -583,27 +575,29 @@ def test_examples_protocol_advanced_https_ota_example_nimble_gatts(dut: Dut) -> """ Run an OTA image update while a BLE GATT Server is running in background. This GATT server will be using NimBLE Host stack. steps: | - 1. join AP + 1. join AP/Ethernet 2. Run BLE advertise and then GATT server. 3. Fetch OTA image over HTTPS 4. Reboot with the new OTA image """ + server_port = 8001 + # File to be downloaded. This file is generated after compilation + bin_name = 'advanced_https_ota.bin' + # start test + dut.expect('Loaded app from partition at offset', timeout=30) try: - server_port = 8001 - # File to be downloaded. This file is generated after compilation - bin_name = 'advanced_https_ota.bin' - # start test - host_ip = get_my_ip() - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) - thread1.daemon = True - thread1.start() - dut.expect('Loaded app from partition at offset', timeout=30) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30)[1].decode() + print('Connected to AP with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + # Start server + host_ip = get_my_ip4_by_dest_ip(ip_address) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) + thread1.daemon = True + thread1.start() + + try: dut.expect('Starting Advanced OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + bin_name)) print('Started GAP advertising.') @@ -611,7 +605,7 @@ def test_examples_protocol_advanced_https_ota_example_nimble_gatts(dut: Dut) -> dut.write('https://' + host_ip + ':' + str(server_port) + '/' + bin_name) dut.expect('Loaded app from partition at offset', timeout=60) dut.expect('Starting Advanced OTA example', timeout=30) - finally: + except: thread1.terminate() @@ -626,28 +620,29 @@ def test_examples_protocol_advanced_https_ota_example_bluedroid_gatts(dut: Dut) """ Run an OTA image update while a BLE GATT Server is running in background. This GATT server will be using Bluedroid Host stack. steps: | - 1. join AP + 1. join AP/Ethernet 2. Run BLE advertise and then GATT server. 3. Fetch OTA image over HTTPS 4. Reboot with the new OTA image """ + server_port = 8001 + # File to be downloaded. This file is generated after compilation + bin_name = 'advanced_https_ota.bin' + # start test + dut.expect('Loaded app from partition at offset', timeout=30) try: - server_port = 8001 - # File to be downloaded. This file is generated after compilation - bin_name = 'advanced_https_ota.bin' - # start test - host_ip = get_my_ip() - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) - thread1.daemon = True - thread1.start() - dut.expect('Loaded app from partition at offset', timeout=30) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30)[1].decode() + print('Connected to AP with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + # Start server + host_ip = get_my_ip4_by_dest_ip(ip_address) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) + thread1.daemon = True + thread1.start() + + try: dut.expect('Starting Advanced OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + bin_name)) dut.expect('Started advertising.', timeout=30) @@ -664,12 +659,12 @@ def test_examples_protocol_advanced_https_ota_example_bluedroid_gatts(dut: Dut) @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.ethernet_ota +@pytest.mark.ethernet_router def test_examples_protocol_advanced_https_ota_example_openssl_aligned_bin(dut: Dut) -> None: """ This is a test case for esp_http_client_read with binary size multiple of 289 bytes steps: | - 1. join AP + 1. join AP/Ethernet 2. Fetch OTA image over HTTPS 3. Reboot with the new OTA image """ @@ -689,18 +684,18 @@ def test_examples_protocol_advanced_https_ota_example_openssl_aligned_bin(dut: D for _ in range(dummy_data_size): fo.write(struct.pack('B', random.randrange(0,255,1))) # start test - host_ip = get_my_ip() + dut.expect('Loaded app from partition at offset', timeout=30) + try: + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + + # Start server + host_ip = get_my_ip4_by_dest_ip(ip_address) chunked_server = start_chunked_server(dut.app.binary_path, 8070) try: - dut.expect('Loaded app from partition at offset', timeout=30) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') - dut.expect('Starting Advanced OTA example', timeout=30) - print('writing to device: {}'.format('https://' + host_ip + ':8070/' + aligned_bin_name)) dut.write('https://' + host_ip + ':8070/' + aligned_bin_name) dut.expect('Loaded app from partition at offset', timeout=60) diff --git a/examples/system/ota/native_ota_example/pytest_native_ota.py b/examples/system/ota/native_ota_example/pytest_native_ota.py index 4f5f113a92..964f1b8194 100644 --- a/examples/system/ota/native_ota_example/pytest_native_ota.py +++ b/examples/system/ota/native_ota_example/pytest_native_ota.py @@ -12,6 +12,7 @@ from typing import Callable, Tuple import pexpect import pytest +from common_test_methods import get_my_ip4_by_dest_ip from pytest_embedded import Dut server_cert = '-----BEGIN CERTIFICATE-----\n' \ @@ -65,15 +66,6 @@ server_key = '-----BEGIN PRIVATE KEY-----\n'\ '-----END PRIVATE KEY-----\n' -def get_my_ip() -> str: - s1 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - s1.connect(('8.8.8.8', 80)) - my_ip = '' - my_ip = s1.getsockname()[0] - s1.close() - return my_ip - - def create_file(server_file: str, file_data: str) -> None: with open(server_file, 'w+') as file: file.write(file_data) @@ -130,86 +122,84 @@ def start_chunked_server(ota_image_dir: str, server_port: int) -> subprocess.Pop @pytest.mark.supported_targets -@pytest.mark.ethernet_ota +@pytest.mark.ethernet_router def test_examples_protocol_native_ota_example(dut: Dut) -> None: """ This is a positive test case, which downloads complete binary file multiple number of times. Number of iterations can be specified in variable iterations. steps: | - 1. join AP + 1. join AP/Ethernet 2. Fetch OTA image over HTTPS 3. Reboot with the new OTA image """ - try: - server_port = 8002 - # No. of times working of application to be validated - iterations = 3 - # File to be downloaded. This file is generated after compilation - bin_name = 'native_ota.bin' - # start test - host_ip = get_my_ip() + server_port = 8002 + # No. of times working of application to be validated + iterations = 3 + # File to be downloaded. This file is generated after compilation + bin_name = 'native_ota.bin' + # start test + for _ in range(iterations): + dut.expect('Loaded app from partition at offset', timeout=60) + try: + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + # Start server + host_ip = get_my_ip4_by_dest_ip(ip_address) thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) thread1.daemon = True thread1.start() - for i in range(iterations): - dut.expect('Loaded app from partition at offset', timeout=60) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + try: dut.expect('Starting OTA example', timeout=30) - print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + bin_name)) dut.write('https://' + host_ip + ':' + str(server_port) + '/' + bin_name) - finally: - thread1.terminate() + finally: + thread1.terminate() @pytest.mark.supported_targets -@pytest.mark.ethernet_ota +@pytest.mark.ethernet_router def test_examples_protocol_native_ota_example_truncated_bin(dut: Dut) -> None: """ Working of OTA if binary file is truncated is validated in this test case. Application should return with error message in this case. steps: | - 1. join AP + 1. join AP/Ethernet 2. Generate truncated binary file 3. Fetch OTA image over HTTPS 4. Check working of code if bin is truncated """ + server_port = 8002 + # Original binary file generated after compilation + bin_name = 'native_ota.bin' + # Truncated binary file to be generated from original binary file + truncated_bin_name = 'truncated.bin' + # Size of truncated file to be grnerated. This value can range from 288 bytes (Image header size) to size of original binary file + # truncated_bin_size is set to 64000 to reduce consumed by the test case + truncated_bin_size = 64000 + # check and log bin size + binary_file = os.path.join(dut.app.binary_path, bin_name) + f = open(binary_file, 'rb+') + fo = open(os.path.join(dut.app.binary_path, truncated_bin_name), 'wb+') + fo.write(f.read(truncated_bin_size)) + fo.close() + f.close() + binary_file = os.path.join(dut.app.binary_path, truncated_bin_name) + # start test + dut.expect('Loaded app from partition at offset', timeout=30) + try: + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + # Start server + host_ip = get_my_ip4_by_dest_ip(ip_address) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) + thread1.daemon = True + thread1.start() try: - server_port = 8002 - # Original binary file generated after compilation - bin_name = 'native_ota.bin' - # Truncated binary file to be generated from original binary file - truncated_bin_name = 'truncated.bin' - # Size of truncated file to be grnerated. This value can range from 288 bytes (Image header size) to size of original binary file - # truncated_bin_size is set to 64000 to reduce consumed by the test case - truncated_bin_size = 64000 - # check and log bin size - binary_file = os.path.join(dut.app.binary_path, bin_name) - f = open(binary_file, 'rb+') - fo = open(os.path.join(dut.app.binary_path, truncated_bin_name), 'wb+') - fo.write(f.read(truncated_bin_size)) - fo.close() - f.close() - binary_file = os.path.join(dut.app.binary_path, truncated_bin_name) - # start test - host_ip = get_my_ip() - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) - thread1.daemon = True - thread1.start() - dut.expect('Loaded app from partition at offset', timeout=30) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') dut.expect('Starting OTA example', timeout=30) - print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + truncated_bin_name)) dut.write('https://' + host_ip + ':' + str(server_port) + '/' + truncated_bin_name) dut.expect('native_ota_example: Image validation failed, image is corrupted', timeout=20) @@ -219,47 +209,46 @@ def test_examples_protocol_native_ota_example_truncated_bin(dut: Dut) -> None: @pytest.mark.supported_targets -@pytest.mark.ethernet_ota +@pytest.mark.ethernet_router def test_examples_protocol_native_ota_example_truncated_header(dut: Dut) -> None: """ Working of OTA if headers of binary file are truncated is vaildated in this test case. Application should return with error message in this case. steps: | - 1. join AP + 1. join AP/Ethernet 2. Generate binary file with truncated headers 3. Fetch OTA image over HTTPS 4. Check working of code if headers are not sent completely """ + server_port = 8002 + # Original binary file generated after compilation + bin_name = 'native_ota.bin' + # Truncated binary file to be generated from original binary file + truncated_bin_name = 'truncated_header.bin' + # Size of truncated file to be grnerated. This value should be less than 288 bytes (Image header size) + truncated_bin_size = 180 + # check and log bin size + binary_file = os.path.join(dut.app.binary_path, bin_name) + f = open(binary_file, 'rb+') + fo = open(os.path.join(dut.app.binary_path, truncated_bin_name), 'wb+') + fo.write(f.read(truncated_bin_size)) + fo.close() + f.close() + binary_file = os.path.join(dut.app.binary_path, truncated_bin_name) + # start test + dut.expect('Loaded app from partition at offset', timeout=30) + try: + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + # Start server + host_ip = get_my_ip4_by_dest_ip(ip_address) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) + thread1.daemon = True + thread1.start() try: - server_port = 8002 - # Original binary file generated after compilation - bin_name = 'native_ota.bin' - # Truncated binary file to be generated from original binary file - truncated_bin_name = 'truncated_header.bin' - # Size of truncated file to be grnerated. This value should be less than 288 bytes (Image header size) - truncated_bin_size = 180 - # check and log bin size - binary_file = os.path.join(dut.app.binary_path, bin_name) - f = open(binary_file, 'rb+') - fo = open(os.path.join(dut.app.binary_path, truncated_bin_name), 'wb+') - fo.write(f.read(truncated_bin_size)) - fo.close() - f.close() - binary_file = os.path.join(dut.app.binary_path, truncated_bin_name) - # start test - host_ip = get_my_ip() - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) - thread1.daemon = True - thread1.start() - dut.expect('Loaded app from partition at offset', timeout=30) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') dut.expect('Starting OTA example', timeout=30) - print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + truncated_bin_name)) dut.write('https://' + host_ip + ':' + str(server_port) + '/' + truncated_bin_name) dut.expect('native_ota_example: received package is not fit len', timeout=20) @@ -269,46 +258,46 @@ def test_examples_protocol_native_ota_example_truncated_header(dut: Dut) -> None @pytest.mark.supported_targets -@pytest.mark.ethernet_ota +@pytest.mark.ethernet_router def test_examples_protocol_native_ota_example_random(dut: Dut) -> None: """ Working of OTA if random data is added in binary file are validated in this test case. Magic byte verification should fail in this case. steps: | - 1. join AP + 1. join AP/Ethernet 2. Generate random binary image 3. Fetch OTA image over HTTPS 4. Check working of code for random binary file """ + server_port = 8002 + # Random binary file to be generated + random_bin_name = 'random.bin' + # Size of random binary file. 32000 is choosen, to reduce the time required to run the test-case + random_bin_size = 32000 + # check and log bin size + binary_file = os.path.join(dut.app.binary_path, random_bin_name) + fo = open(binary_file, 'wb+') + # First byte of binary file is always set to zero. If first byte is generated randomly, + # in some cases it may generate 0xE9 which will result in failure of testcase. + fo.write(struct.pack('B', 0)) + for i in range(random_bin_size - 1): + fo.write(struct.pack('B', random.randrange(0,255,1))) + fo.close() + # start test + dut.expect('Loaded app from partition at offset', timeout=30) try: - server_port = 8002 - # Random binary file to be generated - random_bin_name = 'random.bin' - # Size of random binary file. 32000 is choosen, to reduce the time required to run the test-case - random_bin_size = 32000 - # check and log bin size - binary_file = os.path.join(dut.app.binary_path, random_bin_name) - fo = open(binary_file, 'wb+') - # First byte of binary file is always set to zero. If first byte is generated randomly, - # in some cases it may generate 0xE9 which will result in failure of testcase. - fo.write(struct.pack('B', 0)) - for i in range(random_bin_size - 1): - fo.write(struct.pack('B', random.randrange(0,255,1))) - fo.close() - # start test - host_ip = get_my_ip() - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) - thread1.daemon = True - thread1.start() - dut.expect('Loaded app from partition at offset', timeout=30) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') - dut.expect('Starting OTA example', timeout=30) + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + # Start server + host_ip = get_my_ip4_by_dest_ip(ip_address) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) + thread1.daemon = True + thread1.start() + try: + dut.expect('Starting OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + random_bin_name)) dut.write('https://' + host_ip + ':' + str(server_port) + '/' + random_bin_name) dut.expect('esp_ota_ops: OTA image has invalid magic byte', timeout=20) @@ -318,29 +307,29 @@ def test_examples_protocol_native_ota_example_random(dut: Dut) -> None: @pytest.mark.supported_targets -@pytest.mark.ethernet_ota +@pytest.mark.ethernet_router def test_examples_protocol_native_ota_example_chunked(dut: Dut) -> None: """ This is a positive test case, which downloads complete binary file multiple number of times. Number of iterations can be specified in variable iterations. steps: | - 1. join AP + 1. join AP/Ethernet 2. Fetch OTA image over HTTPS 3. Reboot with the new OTA image """ # File to be downloaded. This file is generated after compilation bin_name = 'native_ota.bin' # start test - host_ip = get_my_ip() + dut.expect('Loaded app from partition at offset', timeout=30) + try: + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + # Start server + host_ip = get_my_ip4_by_dest_ip(ip_address) chunked_server = start_chunked_server(dut.app.binary_path, 8070) try: - dut.expect('Loaded app from partition at offset', timeout=30) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') - dut.expect('Starting OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':8070/' + bin_name)) dut.write('https://' + host_ip + ':8070/' + bin_name) diff --git a/examples/system/ota/pre_encrypted_ota/pytest_pre_encrypted_ota.py b/examples/system/ota/pre_encrypted_ota/pytest_pre_encrypted_ota.py index 86ef19f21e..559c0dc733 100644 --- a/examples/system/ota/pre_encrypted_ota/pytest_pre_encrypted_ota.py +++ b/examples/system/ota/pre_encrypted_ota/pytest_pre_encrypted_ota.py @@ -9,6 +9,7 @@ from typing import Callable import pexpect import pytest +from common_test_methods import get_my_ip4_by_dest_ip from pytest_embedded import Dut from RangeHTTPServer import RangeRequestHandler @@ -17,15 +18,6 @@ key_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'server_cert enc_bin_name = 'pre_encrypted_ota_secure.bin' -def get_my_ip() -> str: - s1 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - s1.connect(('8.8.8.8', 80)) - my_ip = '' - my_ip = s1.getsockname()[0] - s1.close() - return my_ip - - def https_request_handler() -> Callable[...,http.server.BaseHTTPRequestHandler]: """ Returns a request handler class that handles broken pipe exception @@ -64,25 +56,24 @@ def start_https_server(ota_image_dir: str, server_ip: str, server_port: int) -> @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.ethernet_ota +@pytest.mark.ethernet_router def test_examples_protocol_pre_encrypted_ota_example(dut: Dut) -> None: + server_port = 8001 + dut.expect('Loaded app from partition at offset', timeout=30) try: - server_port = 8001 - # start test - host_ip = get_my_ip() - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) - thread1.daemon = True - thread1.start() + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + thread1.terminate() + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + # Start server + host_ip = get_my_ip4_by_dest_ip(ip_address) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) + thread1.daemon = True + thread1.start() - dut.expect('Loaded app from partition at offset', timeout=30) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + try: dut.expect('Starting Pre Encrypted OTA example', timeout=30) - print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + enc_bin_name)) dut.write('https://' + host_ip + ':' + str(server_port) + '/' + enc_bin_name) dut.expect('Magic Verified', timeout=30) diff --git a/examples/system/ota/simple_ota_example/pytest_simple_ota.py b/examples/system/ota/simple_ota_example/pytest_simple_ota.py index 68a52749e3..d2a1c04611 100644 --- a/examples/system/ota/simple_ota_example/pytest_simple_ota.py +++ b/examples/system/ota/simple_ota_example/pytest_simple_ota.py @@ -10,6 +10,7 @@ from typing import Tuple import pexpect import pytest +from common_test_methods import get_my_ip4_by_dest_ip from pytest_embedded import Dut server_cert = '-----BEGIN CERTIFICATE-----\n' \ @@ -63,15 +64,6 @@ server_key = '-----BEGIN PRIVATE KEY-----\n'\ '-----END PRIVATE KEY-----\n' -def get_my_ip() -> str: - s1 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - s1.connect(('8.8.8.8', 80)) - my_ip = '' - my_ip = s1.getsockname()[0] - s1.close() - return my_ip - - def start_https_server(ota_image_dir: str, server_ip: str, server_port: int, server_file: str = None, key_file: str = None) -> None: os.chdir(ota_image_dir) @@ -123,28 +115,28 @@ def calc_all_sha256(dut: Dut) -> Tuple[str, str]: def test_examples_protocol_simple_ota_example(dut: Dut) -> None: """ steps: | - 1. join AP + 1. join AP/Ethernet 2. Fetch OTA image over HTTPS 3. Reboot with the new OTA image """ + sha256_bootloader, sha256_app = calc_all_sha256(dut) + # start test + dut.expect('Loaded app from partition at offset 0x10000', timeout=30) + check_sha256(sha256_bootloader, str(dut.expect(r'SHA-256 for bootloader:\s+([a-f0-9]){64}')[0])) + check_sha256(sha256_app, str(dut.expect(r'SHA-256 for current firmware:\s+([a-f0-9]){64}')[0])) + try: + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + thread1.terminate() + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + # Start server + host_ip = get_my_ip4_by_dest_ip(ip_address) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, 8000)) + thread1.daemon = True + thread1.start() try: - sha256_bootloader, sha256_app = calc_all_sha256(dut) - # start test - host_ip = get_my_ip() - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, 8000)) - thread1.daemon = True - thread1.start() - dut.expect('Loaded app from partition at offset 0x10000', timeout=30) - check_sha256(sha256_bootloader, str(dut.expect(r'SHA-256 for bootloader:\s+([a-f0-9]){64}')[0])) - check_sha256(sha256_app, str(dut.expect(r'SHA-256 for current firmware:\s+([a-f0-9]){64}')[0])) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') dut.expect('Starting OTA example', timeout=30) - print('writing to device: {}'.format('https://' + host_ip + ':8000/simple_ota.bin')) dut.write('https://' + host_ip + ':8000/simple_ota.bin') dut.expect('Loaded app from partition at offset 0x110000', timeout=60) @@ -157,30 +149,30 @@ def test_examples_protocol_simple_ota_example(dut: Dut) -> None: @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.ethernet_ota +@pytest.mark.ethernet_router @pytest.mark.parametrize('config', ['spiram',], indirect=True) def test_examples_protocol_simple_ota_example_ethernet_with_spiram_config(dut: Dut) -> None: """ steps: | - 1. join AP + 1. join AP/Ethernet 2. Fetch OTA image over HTTPS 3. Reboot with the new OTA image """ + # start test + dut.expect('Loaded app from partition at offset 0x10000', timeout=30)) + try: + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + thread1.terminate() + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + # Start server + host_ip = get_my_ip4_by_dest_ip(ip_address) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, 8000)) + thread1.daemon = True + thread1.start() try: - # start test - host_ip = get_my_ip() - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, 8000)) - thread1.daemon = True - thread1.start() - dut.expect('Loaded app from partition at offset 0x10000', timeout=30)) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') dut.expect('Starting OTA example', timeout=30) - print('writing to device: {}'.format('https://' + host_ip + ':8000/simple_ota.bin')) dut.write('https://' + host_ip + ':8000/simple_ota.bin') dut.expect('Loaded app from partition at offset 0x110000', timeout=60) @@ -199,29 +191,29 @@ def test_examples_protocol_simple_ota_example_ethernet_with_spiram_config(dut: D def test_examples_protocol_simple_ota_example_with_flash_encryption(dut: Dut) -> None: """ steps: | - 1. join AP + 1. join AP/Ethernet 2. Fetch OTA image over HTTPS 3. Reboot with the new OTA image """ + # Erase flash + dut.serial.erase_flash() + dut.serial.flash() + # start test + dut.expect('Loaded app from partition at offset 0x20000', timeout=30) + dut.expect('Flash encryption mode is DEVELOPMENT', timeout=10) + try: + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + thread1.terminate() + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + # Start server + host_ip = get_my_ip4_by_dest_ip(ip_address) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, 8000)) + thread1.daemon = True + thread1.start() try: - # Erase flash - dut.serial.erase_flash() - dut.serial.flash() - # start test - host_ip = get_my_ip() - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, 8000)) - thread1.daemon = True - thread1.start() - dut.expect('Loaded app from partition at offset 0x20000', timeout=30) - dut.expect('Flash encryption mode is DEVELOPMENT', timeout=10) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') dut.expect('Starting OTA example', timeout=30) - print('writing to device: {}'.format('https://' + host_ip + ':8000/simple_ota.bin')) dut.write('https://' + host_ip + ':8000/simple_ota.bin') dut.expect('Loaded app from partition at offset 0x120000', timeout=60) @@ -239,29 +231,29 @@ def test_examples_protocol_simple_ota_example_with_flash_encryption(dut: Dut) -> def test_examples_protocol_simple_ota_example_with_flash_encryption_wifi(dut: Dut) -> None: """ steps: | - 1. join AP + 1. join AP/Ethernet 2. Fetch OTA image over HTTPS 3. Reboot with the new OTA image """ + # start test + # Erase flash + dut.serial.erase_flash() + dut.serial.flash() + dut.expect('Loaded app from partition at offset 0x20000', timeout=30) + dut.expect('Flash encryption mode is DEVELOPMENT', timeout=10) + try: + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + thread1.terminate() + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + # Start server + host_ip = get_my_ip4_by_dest_ip(ip_address) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, 8000)) + thread1.daemon = True + thread1.start() try: - # start test - # Erase flash - dut.serial.erase_flash() - dut.serial.flash() - host_ip = get_my_ip() - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, 8000)) - thread1.daemon = True - thread1.start() - dut.expect('Loaded app from partition at offset 0x20000', timeout=30) - dut.expect('Flash encryption mode is DEVELOPMENT', timeout=10) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') dut.expect('Starting OTA example', timeout=30) - print('writing to device: {}'.format('https://' + host_ip + ':8000/simple_ota.bin')) dut.write('https://' + host_ip + ':8000/simple_ota.bin') dut.expect('Loaded app from partition at offset 0x120000', timeout=60) @@ -275,39 +267,38 @@ def test_examples_protocol_simple_ota_example_with_flash_encryption_wifi(dut: Du @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.ethernet_ota +@pytest.mark.ethernet_router @pytest.mark.parametrize('config', ['on_update_no_sb_ecdsa',], indirect=True) def test_examples_protocol_simple_ota_example_with_verify_app_signature_on_update_no_secure_boot_ecdsa(dut: Dut) -> None: """ steps: | - 1. join AP + 1. join AP/Ethernet 2. Fetch OTA image over HTTPS 3. Reboot with the new OTA image """ + sha256_bootloader, sha256_app = calc_all_sha256(dut) + # start test + dut.expect('Loaded app from partition at offset 0x20000', timeout=30) + check_sha256(sha256_bootloader, str(dut.expect(r'SHA-256 for bootloader:\s+([a-f0-9]){64}')[0])) + check_sha256(sha256_app, str(dut.expect(r'SHA-256 for current firmware:\s+([a-f0-9]){64}')[0])) try: - sha256_bootloader, sha256_app = calc_all_sha256(dut) - # start test - host_ip = get_my_ip() - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, 8000)) - thread1.daemon = True - thread1.start() - dut.expect('Loaded app from partition at offset 0x20000', timeout=30) - check_sha256(sha256_bootloader, str(dut.expect(r'SHA-256 for bootloader:\s+([a-f0-9]){64}')[0])) - check_sha256(sha256_app, str(dut.expect(r'SHA-256 for current firmware:\s+([a-f0-9]){64}')[0])) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') - dut.expect('Starting OTA example', timeout=30) + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + thread1.terminate() + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + # Start server + host_ip = get_my_ip4_by_dest_ip(ip_address) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, 8000)) + thread1.daemon = True + thread1.start() + try: + dut.expect('Starting OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':8000/simple_ota.bin')) dut.write('https://' + host_ip + ':8000/simple_ota.bin') dut.expect('Writing to partition subtype 16 at offset 0x120000', timeout=20) - dut.expect('Verifying image signature...', timeout=60) - dut.expect('Loaded app from partition at offset 0x120000', timeout=20) dut.expect('Starting OTA example', timeout=30) finally: @@ -318,33 +309,34 @@ def test_examples_protocol_simple_ota_example_with_verify_app_signature_on_updat @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.ethernet +@pytest.mark.ethernet_router @pytest.mark.parametrize('config', ['on_update_no_sb_rsa',], indirect=True) def test_examples_protocol_simple_ota_example_with_verify_app_signature_on_update_no_secure_boot_rsa(dut: Dut) -> None: """ steps: | - 1. join AP + 1. join AP/Ethernet 2. Fetch OTA image over HTTPS 3. Reboot with the new OTA image """ + sha256_bootloader, sha256_app = calc_all_sha256(dut) + # start test + dut.expect('Loaded app from partition at offset 0x20000', timeout=30) + check_sha256(sha256_bootloader, str(dut.expect(r'SHA-256 for bootloader:\s+([a-f0-9]){64}')[0])) + check_sha256(sha256_app, str(dut.expect(r'SHA-256 for current firmware:\s+([a-f0-9]){64}')[0])) try: - sha256_bootloader, sha256_app = calc_all_sha256(dut) - # start test - host_ip = get_my_ip() - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, 8000)) - thread1.daemon = True - thread1.start() - dut.expect('Loaded app from partition at offset 0x20000', timeout=30) - check_sha256(sha256_bootloader, str(dut.expect(r'SHA-256 for bootloader:\s+([a-f0-9]){64}')[0])) - check_sha256(sha256_app, str(dut.expect(r'SHA-256 for current firmware:\s+([a-f0-9]){64}')[0])) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') - dut.expect('Starting OTA example', timeout=30) + ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + thread1.terminate() + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + # Start server + host_ip = get_my_ip4_by_dest_ip(ip_address) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, 8000)) + thread1.daemon = True + thread1.start() + try: + dut.expect('Starting OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':8000/simple_ota.bin')) dut.write('https://' + host_ip + ':8000/simple_ota.bin') dut.expect('Writing to partition subtype 16 at offset 0x120000', timeout=20) diff --git a/pytest.ini b/pytest.ini index 999d0082ea..2ca3960681 100644 --- a/pytest.ini +++ b/pytest.ini @@ -36,7 +36,6 @@ markers = quad_psram: runners with quad psram octal_psram: runners with octal psram usb_host: usb host runners - ethernet_ota: ethernet OTA runners flash_encryption: Flash Encryption runners ir_transceiver: runners with a pair of IR transmitter and receiver wifi_ota: wifi OTA runners @@ -44,15 +43,17 @@ markers = flash_encryption_wifi_ota: flash encryprion ota wifi runner ethernet: ethernet runner ethernet_flash_8m: ethernet runner with 8mb flash - wifi: wifi runner - wifi_bt: wifi runner with bluetooth + ethernet_router: both the runner and dut connect to the same router + wifi_nearby: runner with a wifi AP nearby + wifi_router: runner can connect to the dut by a wifi router + wifi_wlan: wifi runner with a wireless NIC deepsleep_temp_tag: temporary env for running potentially harmfull deepsleep related tests # multi-dut markers multi_dut_generic: tests should be run on generic runners, at least have two duts connected. # host_test markers - host_test: tests which shouldn't be built at the build stage, and instead built in host_test stage. + host_test: tests which shouldn not be built at the build stage, and instead built in host_test stage. qemu: build and test using qemu-system-xtensa, not real target. # log related diff --git a/tools/test_apps/protocols/mqtt/publish_connect_test/app_test.py b/tools/test_apps/protocols/mqtt/publish_connect_test/app_test.py index da22edb83f..2e99d02294 100644 --- a/tools/test_apps/protocols/mqtt/publish_connect_test/app_test.py +++ b/tools/test_apps/protocols/mqtt/publish_connect_test/app_test.py @@ -15,6 +15,7 @@ from threading import Event, Lock, Thread import paho.mqtt.client as mqtt import ttfw_idf +from common_test_methods import get_my_ip4_by_dest_ip DEFAULT_MSG_SIZE = 16 @@ -33,19 +34,6 @@ def set_server_cert_cn(ip): raise('openssl command {} failed'.format(args)) -def get_my_ip(): - s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - try: - # doesn't even have to be reachable - s.connect(('10.255.255.255', 1)) - IP = s.getsockname()[0] - except Exception: - IP = '127.0.0.1' - finally: - s.close() - return IP - - # Publisher class creating a python client to send/receive published data from esp-mqtt client class MqttPublisher: @@ -247,8 +235,8 @@ class TlsServer: self.shutdown.set() -def connection_tests(dut, cases): - ip = get_my_ip() +def connection_tests(dut, cases, dut_ip): + ip = get_my_ip4_by_dest_ip(dut_ip) set_server_cert_cn(ip) server_port = 2222 @@ -314,7 +302,7 @@ def connection_tests(dut, cases): teardown_connection_suite() -@ttfw_idf.idf_custom_test(env_tag='Example_EthKitV1', group='test-apps') +@ttfw_idf.idf_custom_test(env_tag='ethernet_router', group='test-apps') def test_app_protocol_mqtt_publish_connect(env, extra_data): """ steps: @@ -348,11 +336,11 @@ def test_app_protocol_mqtt_publish_connect(env, extra_data): raise dut1.start_app() - esp_ip = dut1.expect(re.compile(r' IPv4 address: ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)'), timeout=30) - print('Got IP={}'.format(esp_ip[0])) + esp_ip = dut1.expect(re.compile(r' IPv4 address: ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)'), timeout=30)[0] + print('Got IP={}'.format(esp_ip)) if not os.getenv('MQTT_SKIP_CONNECT_TEST'): - connection_tests(dut1,cases) + connection_tests(dut1,cases,esp_ip) # # start publish tests only if enabled in the environment (for weekend tests only) From 4313ff46557f5c237a391d55720760e1fab26bd3 Mon Sep 17 00:00:00 2001 From: Chen Yudong Date: Mon, 4 Jul 2022 16:15:40 +0800 Subject: [PATCH 06/10] CI: input ssid password depends on sdkconfig --- examples/protocols/sntp/pytest_sntp.py | 1 - .../protocols/sockets/tcp_client/example_test.py | 13 ++++++------- .../protocols/sockets/tcp_server/example_test.py | 13 ++++++------- .../protocols/sockets/udp_client/example_test.py | 13 ++++++------- .../protocols/sockets/udp_server/example_test.py | 13 ++++++------- 5 files changed, 24 insertions(+), 29 deletions(-) diff --git a/examples/protocols/sntp/pytest_sntp.py b/examples/protocols/sntp/pytest_sntp.py index 5488160a6a..26f19b7712 100644 --- a/examples/protocols/sntp/pytest_sntp.py +++ b/examples/protocols/sntp/pytest_sntp.py @@ -15,7 +15,6 @@ from pytest_embedded import Dut def test_get_time_from_sntp_server(dut: Dut) -> None: dut.expect('Time is not set yet. Connecting to WiFi and getting time over NTP.') if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True: - # get env config env_config = get_env_config('wifi_nearby') ap_ssid = env_config['ap_ssid'] ap_password = env_config['ap_password'] diff --git a/examples/protocols/sockets/tcp_client/example_test.py b/examples/protocols/sockets/tcp_client/example_test.py index 954ddcca09..76c70b760f 100644 --- a/examples/protocols/sockets/tcp_client/example_test.py +++ b/examples/protocols/sockets/tcp_client/example_test.py @@ -88,11 +88,6 @@ def test_examples_protocol_socket_tcpclient(env, extra_data): 2. have the board connect to the server 3. send and receive data """ - # get env config - env_config = get_env_config('wifi_router') - ap_ssid = env_config['ap_ssid'] - ap_password = env_config['ap_password'] - dut1 = env.get_dut('tcp_client', 'examples/protocols/sockets/tcp_client', dut_class=ttfw_idf.ESP32DUT) # check and log bin size binary_file = os.path.join(dut1.app.binary_path, 'tcp_client.bin') @@ -101,8 +96,12 @@ def test_examples_protocol_socket_tcpclient(env, extra_data): # start test dut1.start_app() - dut1.expect('Please input ssid password:') - dut1.write(' '.join([ap_ssid, ap_password])) + if dut1.app.get_sdkconfig_config_value('CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN'): + env_config = get_env_config('wifi_router') + ap_ssid = env_config['ap_ssid'] + ap_password = env_config['ap_password'] + dut1.expect('Please input ssid password:') + dut1.write(' '.join([ap_ssid, ap_password])) ipv4 = dut1.expect(re.compile(r' IPv4 address: ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)'), timeout=30)[0] ipv6_r = r':'.join((r'[0-9a-fA-F]{4}',) * 8) # expect all 8 octets from IPv6 (assumes it's printed in the long form) diff --git a/examples/protocols/sockets/tcp_server/example_test.py b/examples/protocols/sockets/tcp_server/example_test.py index bf5763836a..d3728c0805 100644 --- a/examples/protocols/sockets/tcp_server/example_test.py +++ b/examples/protocols/sockets/tcp_server/example_test.py @@ -55,11 +55,6 @@ def test_examples_protocol_socket_tcpserver(env, extra_data): 2. have the board connect to the server 3. send and receive data """ - # get env config - env_config = get_env_config('wifi_router') - ap_ssid = env_config['ap_ssid'] - ap_password = env_config['ap_password'] - dut1 = env.get_dut('tcp_client', 'examples/protocols/sockets/tcp_server', dut_class=ttfw_idf.ESP32DUT) # check and log bin size binary_file = os.path.join(dut1.app.binary_path, 'tcp_server.bin') @@ -68,8 +63,12 @@ def test_examples_protocol_socket_tcpserver(env, extra_data): # start test dut1.start_app() - dut1.expect('Please input ssid password:') - dut1.write(' '.join([ap_ssid, ap_password])) + if dut1.app.get_sdkconfig_config_value('CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN'): + env_config = get_env_config('wifi_router') + ap_ssid = env_config['ap_ssid'] + ap_password = env_config['ap_password'] + dut1.expect('Please input ssid password:') + dut1.write(' '.join([ap_ssid, ap_password])) ipv4 = dut1.expect(re.compile(r' IPv4 address: ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)'), timeout=30)[0] ipv6_r = r':'.join((r'[0-9a-fA-F]{4}',) * 8) # expect all 8 octets from IPv6 (assumes it's printed in the long form) diff --git a/examples/protocols/sockets/udp_client/example_test.py b/examples/protocols/sockets/udp_client/example_test.py index 4c656021eb..2878ade7f2 100644 --- a/examples/protocols/sockets/udp_client/example_test.py +++ b/examples/protocols/sockets/udp_client/example_test.py @@ -81,11 +81,6 @@ def test_examples_protocol_socket_udpclient(env, extra_data): 2. have the board connect to the server 3. send and receive data """ - # get env config - env_config = get_env_config('wifi_router') - ap_ssid = env_config['ap_ssid'] - ap_password = env_config['ap_password'] - dut1 = env.get_dut('udp_client', 'examples/protocols/sockets/udp_client', dut_class=ttfw_idf.ESP32DUT) # check and log bin size binary_file = os.path.join(dut1.app.binary_path, 'udp_client.bin') @@ -94,8 +89,12 @@ def test_examples_protocol_socket_udpclient(env, extra_data): # start test dut1.start_app() - dut1.expect('Please input ssid password:') - dut1.write(' '.join([ap_ssid, ap_password])) + if dut1.app.get_sdkconfig_config_value('CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN'): + env_config = get_env_config('wifi_router') + ap_ssid = env_config['ap_ssid'] + ap_password = env_config['ap_password'] + dut1.expect('Please input ssid password:') + dut1.write(' '.join([ap_ssid, ap_password])) ipv4 = dut1.expect(re.compile(r' IPv4 address: ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)'), timeout=30)[0] ipv6_r = r':'.join((r'[0-9a-fA-F]{4}',) * 8) # expect all 8 octets from IPv6 (assumes it's printed in the long form) diff --git a/examples/protocols/sockets/udp_server/example_test.py b/examples/protocols/sockets/udp_server/example_test.py index 7c890e0878..72057339b4 100644 --- a/examples/protocols/sockets/udp_server/example_test.py +++ b/examples/protocols/sockets/udp_server/example_test.py @@ -59,11 +59,6 @@ def test_examples_protocol_socket_udpserver(env, extra_data): 2. have the board connect to the server 3. send and receive data """ - # get env config - env_config = get_env_config('wifi_router') - ap_ssid = env_config['ap_ssid'] - ap_password = env_config['ap_password'] - dut1 = env.get_dut('udp_server', 'examples/protocols/sockets/udp_server', dut_class=ttfw_idf.ESP32DUT) # check and log bin size binary_file = os.path.join(dut1.app.binary_path, 'udp_server.bin') @@ -72,8 +67,12 @@ def test_examples_protocol_socket_udpserver(env, extra_data): # start test dut1.start_app() - dut1.expect('Please input ssid password:') - dut1.write(' '.join([ap_ssid, ap_password])) + if dut1.app.get_sdkconfig_config_value('CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN'): + env_config = get_env_config('wifi_router') + ap_ssid = env_config['ap_ssid'] + ap_password = env_config['ap_password'] + dut1.expect('Please input ssid password:') + dut1.write(' '.join([ap_ssid, ap_password])) ipv4 = dut1.expect(re.compile(r' IPv4 address: ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)'), timeout=30)[0] ipv6_r = r':'.join((r'[0-9a-fA-F]{4}',) * 8) # expect all 8 octets from IPv6 (assumes it's printed in the long form) From 692fbc169cfe711c376b62bc178303d26ee3c777 Mon Sep 17 00:00:00 2001 From: Chen Yudong Date: Mon, 4 Jul 2022 16:54:33 +0800 Subject: [PATCH 07/10] CI: use ssid password from stdin for pytest cases --- .../esp_local_ctrl/pytest_esp_local_ctrl.py | 7 +++++++ .../protocols/esp_local_ctrl/sdkconfig.ci | 1 + .../pytest_http_server_advanced.py | 7 +++++++ .../http_server/advanced_tests/sdkconfig.ci | 1 + .../pytest_http_server_persistence.py | 7 +++++++ .../persistent_sockets/sdkconfig.ci | 1 + .../simple/pytest_http_server_simple.py | 13 ++++++++++++ .../protocols/http_server/simple/sdkconfig.ci | 1 + .../pytest_ws_server_example.py | 7 +++++++ .../http_server/ws_echo_server/sdkconfig.ci | 1 + .../simple/pytest_https_server_simple.py | 19 +++++++++++++---- .../https_server/simple/sdkconfig.ci | 1 + .../simple/sdkconfig.ci.dynamic_buffer | 1 + .../wss_server/pytest_https_wss_server.py | 10 +++++++-- .../https_server/wss_server/sdkconfig.ci | 1 + .../pytest_https_x509_bundle.py | 21 +++++++++++++++++-- .../protocols/https_x509_bundle/sdkconfig.ci | 1 + .../https_x509_bundle/sdkconfig.ci.ssldyn | 1 + 18 files changed, 93 insertions(+), 8 deletions(-) create mode 100644 examples/protocols/esp_local_ctrl/sdkconfig.ci create mode 100644 examples/protocols/http_server/advanced_tests/sdkconfig.ci create mode 100644 examples/protocols/http_server/persistent_sockets/sdkconfig.ci create mode 100644 examples/protocols/https_server/wss_server/sdkconfig.ci diff --git a/examples/protocols/esp_local_ctrl/pytest_esp_local_ctrl.py b/examples/protocols/esp_local_ctrl/pytest_esp_local_ctrl.py index 3adab74337..ebb8aacaa2 100644 --- a/examples/protocols/esp_local_ctrl/pytest_esp_local_ctrl.py +++ b/examples/protocols/esp_local_ctrl/pytest_esp_local_ctrl.py @@ -9,6 +9,7 @@ import sys import pexpect import pytest +from common_test_methods import get_env_config from pytest_embedded import Dut @@ -45,6 +46,12 @@ def test_examples_esp_local_ctrl(dut: Dut) -> None: rel_project_path = os.path.join('examples', 'protocols', 'esp_local_ctrl') idf_path = get_sdk_path() + if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True: + env_config = get_env_config('wifi_router') + ap_ssid = env_config['ap_ssid'] + ap_password = env_config['ap_password'] + dut.expect('Please input ssid password:') + dut.write(' '.join([ap_ssid, ap_password])) dut_ip = dut.expect(r'IPv4 address: (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})')[1].decode() dut.expect('esp_https_server: Starting server') dut.expect('esp_https_server: Server listening on port 443') diff --git a/examples/protocols/esp_local_ctrl/sdkconfig.ci b/examples/protocols/esp_local_ctrl/sdkconfig.ci new file mode 100644 index 0000000000..543e69e76e --- /dev/null +++ b/examples/protocols/esp_local_ctrl/sdkconfig.ci @@ -0,0 +1 @@ +CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN=y diff --git a/examples/protocols/http_server/advanced_tests/pytest_http_server_advanced.py b/examples/protocols/http_server/advanced_tests/pytest_http_server_advanced.py index c339321dae..1bb2e1e85d 100644 --- a/examples/protocols/http_server/advanced_tests/pytest_http_server_advanced.py +++ b/examples/protocols/http_server/advanced_tests/pytest_http_server_advanced.py @@ -17,6 +17,7 @@ except ModuleNotFoundError: sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', '..', '..', 'tools', 'ci', 'python_packages')) from idf_http_server_test import test as client +from common_test_methods import get_env_config from pytest_embedded import Dut # When running on local machine execute the following before running this script @@ -47,6 +48,12 @@ def test_examples_protocol_http_server_advanced(dut: Dut) -> None: # Parse IP address of STA logging.info('Waiting to connect with AP') + if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True: + env_config = get_env_config('wifi_router') + ap_ssid = env_config['ap_ssid'] + ap_password = env_config['ap_password'] + dut.expect('Please input ssid password:') + dut.write(' '.join([ap_ssid, ap_password])) got_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() got_port = dut.expect(r"(?:[\s\S]*)Started HTTP server on port: '(\d+)'", timeout=30)[1].decode() diff --git a/examples/protocols/http_server/advanced_tests/sdkconfig.ci b/examples/protocols/http_server/advanced_tests/sdkconfig.ci new file mode 100644 index 0000000000..543e69e76e --- /dev/null +++ b/examples/protocols/http_server/advanced_tests/sdkconfig.ci @@ -0,0 +1 @@ +CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN=y diff --git a/examples/protocols/http_server/persistent_sockets/pytest_http_server_persistence.py b/examples/protocols/http_server/persistent_sockets/pytest_http_server_persistence.py index d0245f943f..d20db381af 100644 --- a/examples/protocols/http_server/persistent_sockets/pytest_http_server_persistence.py +++ b/examples/protocols/http_server/persistent_sockets/pytest_http_server_persistence.py @@ -19,6 +19,7 @@ except ModuleNotFoundError: sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', '..', '..', 'tools', 'ci', 'python_packages')) from idf_http_server_test import adder as client +from common_test_methods import get_env_config from pytest_embedded import Dut # When running on local machine execute the following before running this script @@ -43,6 +44,12 @@ def test_examples_protocol_http_server_persistence(dut: Dut) -> None: # Parse IP address of STA logging.info('Waiting to connect with AP') + if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True: + env_config = get_env_config('wifi_router') + ap_ssid = env_config['ap_ssid'] + ap_password = env_config['ap_password'] + dut.expect('Please input ssid password:') + dut.write(' '.join([ap_ssid, ap_password])) got_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() got_port = dut.expect(r"(?:[\s\S]*)Starting server on port: '(\d+)'", timeout=30)[1].decode() diff --git a/examples/protocols/http_server/persistent_sockets/sdkconfig.ci b/examples/protocols/http_server/persistent_sockets/sdkconfig.ci new file mode 100644 index 0000000000..543e69e76e --- /dev/null +++ b/examples/protocols/http_server/persistent_sockets/sdkconfig.ci @@ -0,0 +1 @@ +CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN=y diff --git a/examples/protocols/http_server/simple/pytest_http_server_simple.py b/examples/protocols/http_server/simple/pytest_http_server_simple.py index 65a0c296ad..d4ab0ae7fb 100644 --- a/examples/protocols/http_server/simple/pytest_http_server_simple.py +++ b/examples/protocols/http_server/simple/pytest_http_server_simple.py @@ -23,6 +23,7 @@ except ModuleNotFoundError: sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', '..', '..', 'tools', 'ci', 'python_packages')) from idf_http_server_test import client +from common_test_methods import get_env_config from pytest_embedded import Dut @@ -75,6 +76,12 @@ def test_examples_protocol_http_server_simple(dut: Dut) -> None: # Parse IP address of STA logging.info('Waiting to connect with AP') + if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True: + env_config = get_env_config('wifi_router') + ap_ssid = env_config['ap_ssid'] + ap_password = env_config['ap_password'] + dut.expect('Please input ssid password:') + dut.write(' '.join([ap_ssid, ap_password])) got_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() got_port = dut.expect(r"(?:[\s\S]*)Starting server on port: '(\d+)'", timeout=30)[1].decode() @@ -143,6 +150,12 @@ def test_examples_protocol_http_server_lru_purge_enable(dut: Dut) -> None: # Parse IP address of STA logging.info('Waiting to connect with AP') + if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True: + env_config = get_env_config('wifi_router') + ap_ssid = env_config['ap_ssid'] + ap_password = env_config['ap_password'] + dut.expect('Please input ssid password:') + dut.write(' '.join([ap_ssid, ap_password])) got_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() got_port = dut.expect(r"(?:[\s\S]*)Starting server on port: '(\d+)'", timeout=30)[1].decode() diff --git a/examples/protocols/http_server/simple/sdkconfig.ci b/examples/protocols/http_server/simple/sdkconfig.ci index d022d0a55d..e1f72a625c 100644 --- a/examples/protocols/http_server/simple/sdkconfig.ci +++ b/examples/protocols/http_server/simple/sdkconfig.ci @@ -1 +1,2 @@ CONFIG_EXAMPLE_BASIC_AUTH=y +CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN=y diff --git a/examples/protocols/http_server/ws_echo_server/pytest_ws_server_example.py b/examples/protocols/http_server/ws_echo_server/pytest_ws_server_example.py index 04ed4b3af6..c76f4030ff 100644 --- a/examples/protocols/http_server/ws_echo_server/pytest_ws_server_example.py +++ b/examples/protocols/http_server/ws_echo_server/pytest_ws_server_example.py @@ -9,6 +9,7 @@ import logging import os import pytest +from common_test_methods import get_env_config from pytest_embedded import Dut try: @@ -62,6 +63,12 @@ def test_examples_protocol_http_ws_echo_server(dut: Dut) -> None: # Parse IP address of STA logging.info('Waiting to connect with AP') + if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True: + env_config = get_env_config('wifi_router') + ap_ssid = env_config['ap_ssid'] + ap_password = env_config['ap_password'] + dut.expect('Please input ssid password:') + dut.write(' '.join([ap_ssid, ap_password])) got_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() got_port = dut.expect(r"Starting server on port: '(\d+)'", timeout=30)[1].decode() diff --git a/examples/protocols/http_server/ws_echo_server/sdkconfig.ci b/examples/protocols/http_server/ws_echo_server/sdkconfig.ci index 757c0adcca..6110153c28 100644 --- a/examples/protocols/http_server/ws_echo_server/sdkconfig.ci +++ b/examples/protocols/http_server/ws_echo_server/sdkconfig.ci @@ -1 +1,2 @@ CONFIG_LOG_DEFAULT_LEVEL_DEBUG=y +CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN=y diff --git a/examples/protocols/https_server/simple/pytest_https_server_simple.py b/examples/protocols/https_server/simple/pytest_https_server_simple.py index f86eb3c606..bc86c4a45a 100644 --- a/examples/protocols/https_server/simple/pytest_https_server_simple.py +++ b/examples/protocols/https_server/simple/pytest_https_server_simple.py @@ -9,6 +9,7 @@ import os import ssl import pytest +from common_test_methods import get_env_config from pytest_embedded import Dut server_cert_pem = '-----BEGIN CERTIFICATE-----\n'\ @@ -106,11 +107,16 @@ def test_examples_protocol_https_server_simple(dut: Dut) -> None: bin_size = os.path.getsize(binary_file) logging.info('https_server_simple_bin_size : {}KB'.format(bin_size // 1024)) # start test + logging.info('Waiting to connect with AP') + if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True: + env_config = get_env_config('wifi_router') + ap_ssid = env_config['ap_ssid'] + ap_password = env_config['ap_password'] + dut.expect('Please input ssid password:') + dut.write(' '.join([ap_ssid, ap_password])) # Parse IP address and port of the server dut.expect(r'Starting server') got_port = int(dut.expect(r'Server listening on port (\d+)', timeout=30)[1].decode()) - logging.info('Waiting to connect with AP') - got_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() # Expected logs @@ -174,11 +180,16 @@ def test_examples_protocol_https_server_simple_dynamic_buffers(dut: Dut) -> None # Test with mbedTLS dynamic buffer feature # start test + logging.info('Waiting to connect with AP') + if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True: + env_config = get_env_config('wifi_router') + ap_ssid = env_config['ap_ssid'] + ap_password = env_config['ap_password'] + dut.expect('Please input ssid password:') + dut.write(' '.join([ap_ssid, ap_password])) # Parse IP address and port of the server dut.expect(r'Starting server') got_port = int(dut.expect(r'Server listening on port (\d+)', timeout=30)[1].decode()) - logging.info('Waiting to connect with AP') - got_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() # Expected logs diff --git a/examples/protocols/https_server/simple/sdkconfig.ci b/examples/protocols/https_server/simple/sdkconfig.ci index 084692470b..84ffce91b8 100644 --- a/examples/protocols/https_server/simple/sdkconfig.ci +++ b/examples/protocols/https_server/simple/sdkconfig.ci @@ -1,2 +1,3 @@ CONFIG_ESP_HTTPS_SERVER_ENABLE=y CONFIG_EXAMPLE_ENABLE_HTTPS_USER_CALLBACK=y +CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN=y diff --git a/examples/protocols/https_server/simple/sdkconfig.ci.dynamic_buffer b/examples/protocols/https_server/simple/sdkconfig.ci.dynamic_buffer index 506d118f8e..3abca03116 100644 --- a/examples/protocols/https_server/simple/sdkconfig.ci.dynamic_buffer +++ b/examples/protocols/https_server/simple/sdkconfig.ci.dynamic_buffer @@ -1,5 +1,6 @@ CONFIG_ESP_HTTPS_SERVER_ENABLE=y CONFIG_EXAMPLE_ENABLE_HTTPS_USER_CALLBACK=y +CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN=y CONFIG_MBEDTLS_DYNAMIC_BUFFER=y CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA=y CONFIG_MBEDTLS_DYNAMIC_FREE_CA_CERT=y diff --git a/examples/protocols/https_server/wss_server/pytest_https_wss_server.py b/examples/protocols/https_server/wss_server/pytest_https_wss_server.py index fe3e0b2bd3..552f64e28f 100644 --- a/examples/protocols/https_server/wss_server/pytest_https_wss_server.py +++ b/examples/protocols/https_server/wss_server/pytest_https_wss_server.py @@ -14,6 +14,7 @@ from typing import Any, Optional import pytest import websocket +from common_test_methods import get_env_config from pytest_embedded import Dut OPCODE_TEXT = 0x1 @@ -119,10 +120,15 @@ def test_examples_protocol_https_wss_server(dut: Dut) -> None: logging.info('Starting wss_server test app') + logging.info('Waiting to connect with AP') + if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True: + env_config = get_env_config('wifi_router') + ap_ssid = env_config['ap_ssid'] + ap_password = env_config['ap_password'] + dut.expect('Please input ssid password:') + dut.write(' '.join([ap_ssid, ap_password])) # Parse IP address of STA got_port = int(dut.expect(r'Server listening on port (\d+)', timeout=30)[1].decode()) - logging.info('Waiting to connect with AP') - got_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() logging.info('Got IP : {}'.format(got_ip)) diff --git a/examples/protocols/https_server/wss_server/sdkconfig.ci b/examples/protocols/https_server/wss_server/sdkconfig.ci new file mode 100644 index 0000000000..543e69e76e --- /dev/null +++ b/examples/protocols/https_server/wss_server/sdkconfig.ci @@ -0,0 +1 @@ +CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN=y diff --git a/examples/protocols/https_x509_bundle/pytest_https_x509_bundle.py b/examples/protocols/https_x509_bundle/pytest_https_x509_bundle.py index e48eb1050d..b722953a01 100644 --- a/examples/protocols/https_x509_bundle/pytest_https_x509_bundle.py +++ b/examples/protocols/https_x509_bundle/pytest_https_x509_bundle.py @@ -4,6 +4,7 @@ import logging import os import pytest +from common_test_methods import get_env_config from pytest_embedded import Dut @@ -11,7 +12,7 @@ from pytest_embedded import Dut @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.wifi_router +@pytest.mark.wifi_nearby def test_examples_protocol_https_x509_bundle(dut: Dut) -> None: """ steps: | @@ -23,6 +24,14 @@ def test_examples_protocol_https_x509_bundle(dut: Dut) -> None: binary_file = os.path.join(dut.app.binary_path, 'https_x509_bundle.bin') bin_size = os.path.getsize(binary_file) logging.info('https_x509_bundle_bin_size : {}KB'.format(bin_size // 1024)) + # Connect to AP + if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True: + env_config = get_env_config('wifi_nearby') + ap_ssid = env_config['ap_ssid'] + ap_password = env_config['ap_password'] + dut.expect('Please input ssid password:') + dut.write(' '.join([ap_ssid, ap_password])) + dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30) # start test num_URLS = int(dut.expect(r'Connecting to (\d+) URLs', timeout=30)[1].decode()) dut.expect(r'Connection established to ([\s\S]*)', timeout=30) @@ -33,7 +42,7 @@ def test_examples_protocol_https_x509_bundle(dut: Dut) -> None: @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.wifi_router +@pytest.mark.wifi_nearby @pytest.mark.parametrize('config', ['ssldyn',], indirect=True) def test_examples_protocol_https_x509_bundle_dynamic_buffer(dut: Dut) -> None: # test mbedtls dynamic resource @@ -41,6 +50,14 @@ def test_examples_protocol_https_x509_bundle_dynamic_buffer(dut: Dut) -> None: binary_file = os.path.join(dut.app.binary_path, 'https_x509_bundle.bin') bin_size = os.path.getsize(binary_file) logging.info('https_x509_bundle_bin_size : {}KB'.format(bin_size // 1024)) + # Connect to AP + if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True: + env_config = get_env_config('wifi_nearby') + ap_ssid = env_config['ap_ssid'] + ap_password = env_config['ap_password'] + dut.expect('Please input ssid password:') + dut.write(' '.join([ap_ssid, ap_password])) + dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30) # start test num_URLS = int(dut.expect(r'Connecting to (\d+) URLs', timeout=30)[1].decode()) dut.expect(r'Connection established to ([\s\S]*)', timeout=30) diff --git a/examples/protocols/https_x509_bundle/sdkconfig.ci b/examples/protocols/https_x509_bundle/sdkconfig.ci index 7011410ad3..cd5b3811fa 100644 --- a/examples/protocols/https_x509_bundle/sdkconfig.ci +++ b/examples/protocols/https_x509_bundle/sdkconfig.ci @@ -1,3 +1,4 @@ CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE=y CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE=y CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE_PATH="certs" +CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN=y diff --git a/examples/protocols/https_x509_bundle/sdkconfig.ci.ssldyn b/examples/protocols/https_x509_bundle/sdkconfig.ci.ssldyn index 4854bdde4c..bb5ca1c44d 100644 --- a/examples/protocols/https_x509_bundle/sdkconfig.ci.ssldyn +++ b/examples/protocols/https_x509_bundle/sdkconfig.ci.ssldyn @@ -4,3 +4,4 @@ CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE_PATH="certs" CONFIG_MBEDTLS_DYNAMIC_BUFFER=y CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT=y CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA=y +CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN=y From 2f75733ad71b19bc93a6096efcc74ae65e0496cb Mon Sep 17 00:00:00 2001 From: Chen Yudong Date: Thu, 7 Jul 2022 00:34:06 +0800 Subject: [PATCH 08/10] CI: Improve common test methods also fix ota test cases --- .gitlab/ci/rules.yml | 2 +- .gitlab/ci/target-test.yml | 64 ++-- .../Kconfig.projbuild | 4 +- .../protocol_examples_common/console_cmd.c | 2 +- .../include/protocol_examples_common.h | 5 +- .../protocol_examples_common/wifi_connect.c | 18 +- examples/ethernet/iperf/iperf_test.py | 6 +- .../simple_sniffer/pytest_simple_sniffer.py | 10 +- .../esp_local_ctrl/pytest_esp_local_ctrl.py | 12 +- .../pytest_http_server_advanced.py | 10 +- .../pytest_http_server_persistence.py | 10 +- .../simple/pytest_http_server_simple.py | 16 +- .../pytest_ws_server_example.py | 10 +- .../https_request/pytest_https_request.py | 92 +++-- .../simple/pytest_https_server_simple.py | 24 +- .../wss_server/pytest_https_wss_server.py | 12 +- .../pytest_https_x509_bundle.py | 22 +- .../icmp_echo/main/echo_example_main.c | 2 +- .../protocols/icmp_echo/pytest_icmp_echo.py | 14 +- examples/protocols/modbus/tcp/example_test.py | 8 +- .../mqtt/ssl/mqtt_ssl_example_test.py | 4 +- .../mqtt/tcp/mqtt_tcp_example_test.py | 8 +- .../protocols/mqtt/ws/mqtt_ws_example_test.py | 4 +- .../mqtt/wss/mqtt_wss_example_test.py | 4 +- examples/protocols/sntp/pytest_sntp.py | 12 +- .../sockets/tcp_client/example_test.py | 16 +- .../sockets/tcp_server/example_test.py | 12 +- .../sockets/udp_client/example_test.py | 40 ++- .../sockets/udp_client/main/udp_client.c | 7 + .../sockets/udp_server/example_test.py | 12 +- .../sockets/udp_server/main/udp_server.c | 5 + examples/system/ota/README.md | 12 +- .../main/advanced_https_ota_example.c | 1 + .../advanced_https_ota/pytest_advanced_ota.py | 338 ++++++++++-------- .../advanced_https_ota/sdkconfig.ci.nimble | 1 + .../main/native_ota_example.c | 4 +- .../native_ota_example/pytest_native_ota.py | 163 +++++---- .../pytest_pre_encrypted_ota.py | 25 +- .../main/simple_ota_example.c | 4 +- .../simple_ota_example/pytest_simple_ota.py | 221 +++++------- .../ota/simple_ota_example/sdkconfig.ci | 1 + .../simple_ota_example/sdkconfig.ci.flash_enc | 25 -- .../sdkconfig.ci.flash_enc_wifi | 5 + pytest.ini | 12 +- .../ci/python_packages/common_test_methods.py | 99 ++--- .../mqtt/publish_connect_test/app_test.py | 6 +- 46 files changed, 700 insertions(+), 684 deletions(-) delete mode 100644 examples/system/ota/simple_ota_example/sdkconfig.ci.flash_enc diff --git a/.gitlab/ci/rules.yml b/.gitlab/ci/rules.yml index 854b9811d7..e23544c399 100644 --- a/.gitlab/ci/rules.yml +++ b/.gitlab/ci/rules.yml @@ -66,7 +66,6 @@ - "tools/ci/python_packages/gitlab_api.py" - "tools/ci/python_packages/tiny_test_fw/**/*" - "tools/ci/python_packages/ttfw_idf/**/*" - - "tools/ci/python_packages/common_test_methods.py" - "tools/unit-test-app/**/*" @@ -187,6 +186,7 @@ .patterns-example_test-related_changes-wifi: &patterns-example_test-related_changes-wifi - "components/esp_wifi/lib" + - "components/lwip/**/*" - "examples/protocols/**/*" - "examples/wifi/**/*" diff --git a/.gitlab/ci/target-test.yml b/.gitlab/ci/target-test.yml index 274a479dc6..566938b7d1 100644 --- a/.gitlab/ci/target-test.yml +++ b/.gitlab/ci/target-test.yml @@ -13,12 +13,12 @@ expire_in: 1 week variables: GIT_DEPTH: 1 + SUBMODULES_TO_FETCH: "none" script: - retry_failed git clone $KNOWN_FAILURE_CASES_REPO known_failure_cases # get runner env config file - retry_failed git clone $TEST_ENV_CONFIG_REPO - python $CHECKOUT_REF_SCRIPT ci-test-runner-configs ci-test-runner-configs - - cp ./ci-test-runner-configs/${CI_RUNNER_DESCRIPTION}/EnvConfig.yml EnvConfig.yml || true # using runner tags as markers to filter the test cases # Runner tags are comma separated, replace the comma with " and " for markers - job_tags=$(python tools/ci/python_packages/gitlab_api.py get_job_tags $CI_PROJECT_ID --job_id $CI_JOB_ID) @@ -86,37 +86,37 @@ example_test_pytest_esp32c3_flash_suspend: - build_pytest_examples_esp32c3 tags: [ esp32c3, flash_suspend ] -example_test_pytest_esp32_ethernet_router: +example_test_pytest_esp32_ethernet_ota: extends: - .pytest_examples_dir_template - .rules:test:example_test-esp32-ota-related_changes needs: - build_pytest_examples_esp32 - tags: [ esp32, ethernet_router ] + tags: [ esp32, ethernet_ota ] -example_test_pytest_esp32_wifi_ota: +example_test_pytest_esp32_wifi_high_traffic: + extends: + - .pytest_examples_dir_template + - .rules:test:example_test-esp32 + needs: + - build_pytest_examples_esp32 + tags: [ esp32, wifi_high_traffic ] + +example_test_pytest_esp32_flash_encryption_wifi_high_traffic: extends: - .pytest_examples_dir_template - .rules:test:example_test-esp32-ota-related_changes-include_nightly_run needs: - build_pytest_examples_esp32 - tags: [ esp32, wifi_ota ] + tags: [ esp32, flash_encryption_wifi_high_traffic ] -example_test_pytest_esp32_flash_encryption_ota: - extends: - - .pytest_examples_dir_template - - .rules:test:example_test-esp32-ota-related_changes - needs: - - build_pytest_examples_esp32 - tags: [ esp32, flash_encryption_ota ] - -example_test_pytest_esp32c3_flash_encryption_wifi_ota: +example_test_pytest_esp32c3_flash_encryption_wifi_high_traffic: extends: - .pytest_examples_dir_template - .rules:test:example_test-esp32c3-ota-related_changes-include_nightly_run needs: - build_pytest_examples_esp32c3 - tags: [ esp32c3, flash_encryption_wifi_ota ] + tags: [ esp32c3, flash_encryption_wifi_high_traffic ] example_test_pytest_esp32_ethernet: extends: @@ -134,13 +134,13 @@ example_test_pytest_esp32_8mb_flash: - build_pytest_examples_esp32 tags: [ esp32, ethernet_flash_8m ] -example_test_pytest_esp32_wifi_nearby: +example_test_pytest_esp32_wifi_ap: extends: - .pytest_examples_dir_template - - .rules:test:example_test-esp32-wifi-related_changes + - .rules:test:example_test-esp32 needs: - build_pytest_examples_esp32 - tags: [ esp32, wifi_nearby ] + tags: [ esp32, wifi_ap ] example_test_pytest_esp32_wifi_router: extends: @@ -153,7 +153,7 @@ example_test_pytest_esp32_wifi_router: example_test_pytest_esp32_wifi_wlan: extends: - .pytest_examples_dir_template - - .rules:test:example_test-esp32 + - .rules:test:example_test-esp32-wifi-related_changes needs: - build_pytest_examples_esp32 tags: [ esp32, wifi_wlan ] @@ -394,7 +394,7 @@ test_weekend_mqtt: - .rules:labels:weekend_test tags: - ESP32 - - Example_EthKitV1 + - ethernet_router script: - export MQTT_PUBLISH_TEST=1 - export TEST_PATH=$CI_PROJECT_DIR/tools/test_apps/protocols/mqtt/publish_connect_test @@ -426,12 +426,6 @@ test_weekend_mqtt: - .example_test_template - .rules:test:example_test-esp32s3 -example_test_001B: - extends: .example_test_esp32_template - tags: - - ESP32 - - Example_EthKitV1 - example_test_001B_V3: extends: .example_test_esp32_template tags: @@ -452,12 +446,14 @@ example_test_protocols: - wifi_router example_test_002: - extends: .example_test_esp32_template + extends: + - .example_test_esp32_template + - .rules:test:example_test-esp32-wifi-related_changes tags: - ESP32 - Example_ShieldBox_Basic -example_test_ethernet: +example_test_ethernet_router: extends: .example_test_esp32_template tags: - ESP32 @@ -611,24 +607,12 @@ test_app_test_001: variables: SETUP_TOOLS: "1" -test_app_test_002: - extends: .test_app_esp32_template - tags: - - ESP32 - - Example_WIFI - test_app_test_eth: extends: .test_app_esp32_template tags: - ESP32 - ethernet_router -test_app_test_003: - extends: .test_app_esp32_template - tags: - - ESP32 - - Example_PPP - test_app_test_004: extends: .test_app_esp32s2_template tags: diff --git a/examples/common_components/protocol_examples_common/Kconfig.projbuild b/examples/common_components/protocol_examples_common/Kconfig.projbuild index ec6f731cc3..ed382457d7 100644 --- a/examples/common_components/protocol_examples_common/Kconfig.projbuild +++ b/examples/common_components/protocol_examples_common/Kconfig.projbuild @@ -22,7 +22,7 @@ menu "Example Connection Configuration" default y help Provide wifi connect commands for esp_console. - Please use `register_wifi_connect_commands` to register them. + Please use `example_register_wifi_connect_commands` to register them. config EXAMPLE_WIFI_SSID depends on !EXAMPLE_WIFI_SSID_PWD_FROM_STDIN @@ -305,7 +305,7 @@ menu "Example Connection Configuration" endif # EXAMPLE_CONNECT_ETHERNET config EXAMPLE_CONNECT_IPV6 - depends on (EXAMPLE_CONNECT_WIFI || EXAMPLE_CONNECT_ETHERNET) + depends on EXAMPLE_CONNECT_WIFI || EXAMPLE_CONNECT_ETHERNET bool "Obtain IPv6 address" default y select LWIP_IPV6 diff --git a/examples/common_components/protocol_examples_common/console_cmd.c b/examples/common_components/protocol_examples_common/console_cmd.c index 4b3c20d7eb..342a92c769 100644 --- a/examples/common_components/protocol_examples_common/console_cmd.c +++ b/examples/common_components/protocol_examples_common/console_cmd.c @@ -58,7 +58,7 @@ static int cmd_do_wifi_disconnect(int argc, char **argv) return 0; } -void register_wifi_connect_commands(void) +void example_register_wifi_connect_commands(void) { ESP_LOGI(TAG, "Registering WiFi connect commands."); example_wifi_start(); diff --git a/examples/common_components/protocol_examples_common/include/protocol_examples_common.h b/examples/common_components/protocol_examples_common/include/protocol_examples_common.h index 3a318c6526..7417c1e635 100644 --- a/examples/common_components/protocol_examples_common/include/protocol_examples_common.h +++ b/examples/common_components/protocol_examples_common/include/protocol_examples_common.h @@ -81,9 +81,10 @@ esp_netif_t *get_example_netif_from_desc(const char *desc); /** * @brief Register wifi connect commands * - * @note Provide wifi connect commands using esp_console. + * Provide a simple wifi_connect command in esp_console. + * This function can be used after esp_console is initialized. */ -void register_wifi_connect_commands(void); +void example_register_wifi_connect_commands(void); #endif #if CONFIG_EXAMPLE_CONNECT_ETHERNET diff --git a/examples/common_components/protocol_examples_common/wifi_connect.c b/examples/common_components/protocol_examples_common/wifi_connect.c index a93a927e48..682367fffc 100644 --- a/examples/common_components/protocol_examples_common/wifi_connect.c +++ b/examples/common_components/protocol_examples_common/wifi_connect.c @@ -229,18 +229,20 @@ esp_err_t example_wifi_connect(void) }; #if CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN example_configure_stdin_stdout(); - char buf[32+64+2] = {0}; + char buf[sizeof(wifi_config.sta.ssid)+sizeof(wifi_config.sta.password)+2] = {0}; ESP_LOGI(TAG, "Please input ssid password:"); fgets(buf, sizeof(buf), stdin); int len = strlen(buf); - buf[len-1] = '\0'; - memset(wifi_config.sta.ssid, 0, 32); - char *temp = strtok(buf, " "); - strncpy((char*)wifi_config.sta.ssid, temp, 32); - memset(wifi_config.sta.password, 0, 64); - temp = strtok(NULL, " "); + buf[len-1] = '\0'; /* removes '\n' */ + memset(wifi_config.sta.ssid, 0, sizeof(wifi_config.sta.ssid)); + + char *rest = NULL; + char *temp = strtok_r(buf, " ", &rest); + strncpy((char*)wifi_config.sta.ssid, temp, sizeof(wifi_config.sta.ssid)); + memset(wifi_config.sta.password, 0, sizeof(wifi_config.sta.password)); + temp = strtok_r(NULL, " ", &rest); if (temp) { - strncpy((char*)wifi_config.sta.password, temp, 64); + strncpy((char*)wifi_config.sta.password, temp, sizeof(wifi_config.sta.password)); } else { wifi_config.sta.threshold.authmode = WIFI_AUTH_OPEN; } diff --git a/examples/ethernet/iperf/iperf_test.py b/examples/ethernet/iperf/iperf_test.py index 751be5942f..9fe3f9f2be 100644 --- a/examples/ethernet/iperf/iperf_test.py +++ b/examples/ethernet/iperf/iperf_test.py @@ -16,7 +16,7 @@ import time import netifaces import ttfw_idf -from common_test_methods import get_env_config, get_my_ip_by_interface +from common_test_methods import get_env_config_variable, get_host_ip_by_interface from idf_iperf_test_util import IperfUtility from tiny_test_fw import TinyFW @@ -62,8 +62,8 @@ def test_ethernet_throughput_basic(env, _): # type: (Any, Any) -> None 1. test TCP tx rx and UDP tx rx throughput 2. compare with the pre-defined pass standard """ - pc_nic = get_env_config('wifi_router').get('pc_nic', 'eth1') - pc_nic_ip = get_my_ip_by_interface(pc_nic, netifaces.AF_INET) + pc_nic = get_env_config_variable('wifi_router', 'pc_nic', default='eth1') + pc_nic_ip = get_host_ip_by_interface(pc_nic, netifaces.AF_INET) pc_iperf_log_file = os.path.join(env.log_path, 'pc_iperf_log.md') # 1. get DUT diff --git a/examples/network/simple_sniffer/pytest_simple_sniffer.py b/examples/network/simple_sniffer/pytest_simple_sniffer.py index ac3b0be290..a52e4f38c2 100644 --- a/examples/network/simple_sniffer/pytest_simple_sniffer.py +++ b/examples/network/simple_sniffer/pytest_simple_sniffer.py @@ -6,12 +6,12 @@ from pytest_embedded import Dut @pytest.mark.esp32 -@pytest.mark.wifi_nearby +@pytest.mark.wifi_ap @pytest.mark.parametrize('config', [ 'mem', ], indirect=True) def test_examples_simple_sniffer(dut: Dut) -> None: - sniffer_num = 10 + sniffer_num = 9 dut.expect('sniffer>') dut.write('pcap --open -f simple-sniffer') dut.expect('cmd_pcap: open file successfully') @@ -27,8 +27,8 @@ def test_examples_simple_sniffer(dut: Dut) -> None: dut.expect(r'Minor Version: [0-9]+') dut.expect(r'SnapLen: [0-9]+') dut.expect(r'LinkType: [0-9]+') - # Allow "save captured packet failed" once - for i in range(0, sniffer_num - 1): + # Allow "save captured packet failed" twice + for i in range(0, sniffer_num - 2): dut.expect(f'Packet {i}:') dut.expect(r'Timestamp \(Seconds\): [0-9]+') dut.expect(r'Timestamp \(Microseconds\): [0-9]+') @@ -38,7 +38,7 @@ def test_examples_simple_sniffer(dut: Dut) -> None: dut.expect(r'Frame Subtype:\s+\w+') dut.expect(r'Destination:\s+\w+') dut.expect(r'Source:\s+\w+') - dut.expect(r'Pcap packet Number: \d+') + dut.expect(r'Pcap packet Number: [7-9]') dut.write('pcap --close -f simple-sniffer') dut.expect('cmd_pcap: free memory successfully') dut.expect('cmd_pcap: .pcap file close done') diff --git a/examples/protocols/esp_local_ctrl/pytest_esp_local_ctrl.py b/examples/protocols/esp_local_ctrl/pytest_esp_local_ctrl.py index ebb8aacaa2..805f5e23cc 100644 --- a/examples/protocols/esp_local_ctrl/pytest_esp_local_ctrl.py +++ b/examples/protocols/esp_local_ctrl/pytest_esp_local_ctrl.py @@ -9,7 +9,7 @@ import sys import pexpect import pytest -from common_test_methods import get_env_config +from common_test_methods import get_env_config_variable from pytest_embedded import Dut @@ -47,12 +47,12 @@ def test_examples_esp_local_ctrl(dut: Dut) -> None: idf_path = get_sdk_path() if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True: - env_config = get_env_config('wifi_router') - ap_ssid = env_config['ap_ssid'] - ap_password = env_config['ap_password'] dut.expect('Please input ssid password:') - dut.write(' '.join([ap_ssid, ap_password])) - dut_ip = dut.expect(r'IPv4 address: (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})')[1].decode() + env_name = 'wifi_router' + ap_ssid = get_env_config_variable(env_name, 'ap_ssid') + ap_password = get_env_config_variable(env_name, 'ap_password') + dut.write(f'{ap_ssid} {ap_password}') + dut_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)')[1].decode() dut.expect('esp_https_server: Starting server') dut.expect('esp_https_server: Server listening on port 443') dut.expect('control: esp_local_ctrl service started with name : my_esp_ctrl_device') diff --git a/examples/protocols/http_server/advanced_tests/pytest_http_server_advanced.py b/examples/protocols/http_server/advanced_tests/pytest_http_server_advanced.py index 1bb2e1e85d..a74947c641 100644 --- a/examples/protocols/http_server/advanced_tests/pytest_http_server_advanced.py +++ b/examples/protocols/http_server/advanced_tests/pytest_http_server_advanced.py @@ -17,7 +17,7 @@ except ModuleNotFoundError: sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', '..', '..', 'tools', 'ci', 'python_packages')) from idf_http_server_test import test as client -from common_test_methods import get_env_config +from common_test_methods import get_env_config_variable from pytest_embedded import Dut # When running on local machine execute the following before running this script @@ -49,11 +49,11 @@ def test_examples_protocol_http_server_advanced(dut: Dut) -> None: # Parse IP address of STA logging.info('Waiting to connect with AP') if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True: - env_config = get_env_config('wifi_router') - ap_ssid = env_config['ap_ssid'] - ap_password = env_config['ap_password'] dut.expect('Please input ssid password:') - dut.write(' '.join([ap_ssid, ap_password])) + env_name = 'wifi_router' + ap_ssid = get_env_config_variable(env_name, 'ap_ssid') + ap_password = get_env_config_variable(env_name, 'ap_password') + dut.write(f'{ap_ssid} {ap_password}') got_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() got_port = dut.expect(r"(?:[\s\S]*)Started HTTP server on port: '(\d+)'", timeout=30)[1].decode() diff --git a/examples/protocols/http_server/persistent_sockets/pytest_http_server_persistence.py b/examples/protocols/http_server/persistent_sockets/pytest_http_server_persistence.py index d20db381af..131492ed09 100644 --- a/examples/protocols/http_server/persistent_sockets/pytest_http_server_persistence.py +++ b/examples/protocols/http_server/persistent_sockets/pytest_http_server_persistence.py @@ -19,7 +19,7 @@ except ModuleNotFoundError: sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', '..', '..', 'tools', 'ci', 'python_packages')) from idf_http_server_test import adder as client -from common_test_methods import get_env_config +from common_test_methods import get_env_config_variable from pytest_embedded import Dut # When running on local machine execute the following before running this script @@ -45,11 +45,11 @@ def test_examples_protocol_http_server_persistence(dut: Dut) -> None: # Parse IP address of STA logging.info('Waiting to connect with AP') if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True: - env_config = get_env_config('wifi_router') - ap_ssid = env_config['ap_ssid'] - ap_password = env_config['ap_password'] dut.expect('Please input ssid password:') - dut.write(' '.join([ap_ssid, ap_password])) + env_name = 'wifi_router' + ap_ssid = get_env_config_variable(env_name, 'ap_ssid') + ap_password = get_env_config_variable(env_name, 'ap_password') + dut.write(f'{ap_ssid} {ap_password}') got_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() got_port = dut.expect(r"(?:[\s\S]*)Starting server on port: '(\d+)'", timeout=30)[1].decode() diff --git a/examples/protocols/http_server/simple/pytest_http_server_simple.py b/examples/protocols/http_server/simple/pytest_http_server_simple.py index d4ab0ae7fb..02df921206 100644 --- a/examples/protocols/http_server/simple/pytest_http_server_simple.py +++ b/examples/protocols/http_server/simple/pytest_http_server_simple.py @@ -23,7 +23,7 @@ except ModuleNotFoundError: sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', '..', '..', 'tools', 'ci', 'python_packages')) from idf_http_server_test import client -from common_test_methods import get_env_config +from common_test_methods import get_env_config_variable from pytest_embedded import Dut @@ -77,10 +77,10 @@ def test_examples_protocol_http_server_simple(dut: Dut) -> None: # Parse IP address of STA logging.info('Waiting to connect with AP') if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True: - env_config = get_env_config('wifi_router') - ap_ssid = env_config['ap_ssid'] - ap_password = env_config['ap_password'] dut.expect('Please input ssid password:') + env_name = 'wifi_router' + ap_ssid = get_env_config_variable(env_name, 'ap_ssid') + ap_password = get_env_config_variable(env_name, 'ap_password') dut.write(' '.join([ap_ssid, ap_password])) got_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() got_port = dut.expect(r"(?:[\s\S]*)Starting server on port: '(\d+)'", timeout=30)[1].decode() @@ -151,11 +151,11 @@ def test_examples_protocol_http_server_lru_purge_enable(dut: Dut) -> None: # Parse IP address of STA logging.info('Waiting to connect with AP') if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True: - env_config = get_env_config('wifi_router') - ap_ssid = env_config['ap_ssid'] - ap_password = env_config['ap_password'] dut.expect('Please input ssid password:') - dut.write(' '.join([ap_ssid, ap_password])) + env_name = 'wifi_router' + ap_ssid = get_env_config_variable(env_name, 'ap_ssid') + ap_password = get_env_config_variable(env_name, 'ap_password') + dut.write(f'{ap_ssid} {ap_password}') got_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() got_port = dut.expect(r"(?:[\s\S]*)Starting server on port: '(\d+)'", timeout=30)[1].decode() diff --git a/examples/protocols/http_server/ws_echo_server/pytest_ws_server_example.py b/examples/protocols/http_server/ws_echo_server/pytest_ws_server_example.py index c76f4030ff..3cfbf3843f 100644 --- a/examples/protocols/http_server/ws_echo_server/pytest_ws_server_example.py +++ b/examples/protocols/http_server/ws_echo_server/pytest_ws_server_example.py @@ -9,7 +9,7 @@ import logging import os import pytest -from common_test_methods import get_env_config +from common_test_methods import get_env_config_variable from pytest_embedded import Dut try: @@ -64,11 +64,11 @@ def test_examples_protocol_http_ws_echo_server(dut: Dut) -> None: # Parse IP address of STA logging.info('Waiting to connect with AP') if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True: - env_config = get_env_config('wifi_router') - ap_ssid = env_config['ap_ssid'] - ap_password = env_config['ap_password'] dut.expect('Please input ssid password:') - dut.write(' '.join([ap_ssid, ap_password])) + env_name = 'wifi_router' + ap_ssid = get_env_config_variable(env_name, 'ap_ssid') + ap_password = get_env_config_variable(env_name, 'ap_password') + dut.write(f'{ap_ssid} {ap_password}') got_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() got_port = dut.expect(r"Starting server on port: '(\d+)'", timeout=30)[1].decode() diff --git a/examples/protocols/https_request/pytest_https_request.py b/examples/protocols/https_request/pytest_https_request.py index a8b0e5df50..03789b7d2a 100644 --- a/examples/protocols/https_request/pytest_https_request.py +++ b/examples/protocols/https_request/pytest_https_request.py @@ -10,20 +10,11 @@ from typing import Callable import pexpect import pytest -from common_test_methods import get_my_ip4_by_dest_ip +from common_test_methods import get_host_ip4_by_dest_ip from pytest_embedded import Dut from RangeHTTPServer import RangeRequestHandler -def get_server_status(host_ip: str, port: int) -> bool: - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - server_status = sock.connect_ex((host_ip, port)) - sock.close() - if server_status == 0: - return True - return False - - def https_request_handler() -> Callable[...,http.server.BaseHTTPRequestHandler]: """ Returns a request handler class that handles broken pipe exception @@ -77,54 +68,53 @@ def test_examples_protocol_https_request_cli_session_tickets(dut: Dut) -> None: binary_file = os.path.join(dut.app.binary_path, 'https_request.bin') bin_size = os.path.getsize(binary_file) logging.info('https_request_bin_size : {}KB'.format(bin_size // 1024)) - # start test - dut.expect('Loaded app from partition at offset', timeout=30) - try: - ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=60)[1].decode() - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') - # start https server - host_ip = get_my_ip4_by_dest_ip(ip_address) server_port = 8070 server_file = os.path.join(os.path.dirname(__file__), 'main', 'local_server_cert.pem') key_file = os.path.join(os.path.dirname(__file__), 'main', 'local_server_key.pem') - if (get_server_status(host_ip, server_port) is False): - thread1 = multiprocessing.Process(target=start_https_server, args=(server_file, key_file, host_ip, server_port)) - thread1.daemon = True - thread1.start() - logging.info('The server started on {}:{}'.format(host_ip, server_port)) - - dut.expect('Start https_request example', timeout=30) - - print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port))) - dut.write('https://' + host_ip + ':' + str(server_port)) - logging.info("Testing for \"https_request using saved session\"") - - # Check for connection using already saved client session + thread1 = multiprocessing.Process(target=start_https_server, args=(server_file, key_file, '0.0.0.0', server_port)) + thread1.daemon = True + thread1.start() + logging.info('The server started on localhost:{}'.format(server_port)) try: - dut.expect('https_request to local server', timeout=30) - dut.expect(['Connection established...', - 'Reading HTTP response...', - 'HTTP/1.1 200 OK', - 'connection closed'], expect_all=True) - except Exception: - logging.info("Failed to connect to local https server\"") - raise + # start test + dut.expect('Loaded app from partition at offset', timeout=30) + try: + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=60)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + host_ip = get_host_ip4_by_dest_ip(ip_address) - try: - dut.expect('https_request using saved client session', timeout=20) - dut.expect(['Connection established...', - 'Reading HTTP response...', - 'HTTP/1.1 200 OK', - 'connection closed'], expect_all=True) - except Exception: - logging.info("Failed the test for \"https_request using saved client session\"") - raise + dut.expect('Start https_request example', timeout=30) + print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port))) + dut.write('https://' + host_ip + ':' + str(server_port)) + logging.info("Testing for \"https_request using saved session\"") - logging.info("Passed the test for \"https_request using saved client session\"") - thread1.terminate() + # Check for connection using already saved client session + try: + dut.expect('https_request to local server', timeout=30) + dut.expect(['Connection established...', + 'Reading HTTP response...', + 'HTTP/1.1 200 OK', + 'connection closed'], expect_all=True) + except Exception: + logging.info("Failed to connect to local https server\"") + raise + + try: + dut.expect('https_request using saved client session', timeout=20) + dut.expect(['Connection established...', + 'Reading HTTP response...', + 'HTTP/1.1 200 OK', + 'connection closed'], expect_all=True) + except Exception: + logging.info("Failed the test for \"https_request using saved client session\"") + raise + + logging.info("Passed the test for \"https_request using saved client session\"") + finally: + thread1.terminate() @pytest.mark.esp32 diff --git a/examples/protocols/https_server/simple/pytest_https_server_simple.py b/examples/protocols/https_server/simple/pytest_https_server_simple.py index bc86c4a45a..ab027c44cf 100644 --- a/examples/protocols/https_server/simple/pytest_https_server_simple.py +++ b/examples/protocols/https_server/simple/pytest_https_server_simple.py @@ -9,7 +9,7 @@ import os import ssl import pytest -from common_test_methods import get_env_config +from common_test_methods import get_env_config_variable from pytest_embedded import Dut server_cert_pem = '-----BEGIN CERTIFICATE-----\n'\ @@ -109,11 +109,11 @@ def test_examples_protocol_https_server_simple(dut: Dut) -> None: # start test logging.info('Waiting to connect with AP') if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True: - env_config = get_env_config('wifi_router') - ap_ssid = env_config['ap_ssid'] - ap_password = env_config['ap_password'] dut.expect('Please input ssid password:') - dut.write(' '.join([ap_ssid, ap_password])) + env_name = 'wifi_router' + ap_ssid = get_env_config_variable(env_name, 'ap_ssid') + ap_password = get_env_config_variable(env_name, 'ap_password') + dut.write(f'{ap_ssid} {ap_password}') # Parse IP address and port of the server dut.expect(r'Starting server') got_port = int(dut.expect(r'Server listening on port (\d+)', timeout=30)[1].decode()) @@ -182,11 +182,11 @@ def test_examples_protocol_https_server_simple_dynamic_buffers(dut: Dut) -> None # start test logging.info('Waiting to connect with AP') if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True: - env_config = get_env_config('wifi_router') - ap_ssid = env_config['ap_ssid'] - ap_password = env_config['ap_password'] dut.expect('Please input ssid password:') - dut.write(' '.join([ap_ssid, ap_password])) + env_name = 'wifi_router' + ap_ssid = get_env_config_variable(env_name, 'ap_ssid') + ap_password = get_env_config_variable(env_name, 'ap_password') + dut.write(f'{ap_ssid} {ap_password}') # Parse IP address and port of the server dut.expect(r'Starting server') got_port = int(dut.expect(r'Server listening on port (\d+)', timeout=30)[1].decode()) @@ -230,9 +230,9 @@ def test_examples_protocol_https_server_simple_dynamic_buffers(dut: Dut) -> None logging.info('Checking user callback: Obtaining client certificate...') - serial_number = dut.expect(r'serial number(.*)', timeout=5)[0] - issuer_name = dut.expect(r'issuer name(.*)', timeout=5)[0] - expiry = dut.expect(r'expires on ((.*)\d{4}\-(0?[1-9]|1[012])\-(0?[1-9]|[12][0-9]|3[01])*)', timeout=5)[1].decode() + serial_number = dut.expect(r'serial number\s*:([^\n]*)', timeout=5)[0] + issuer_name = dut.expect(r'issuer name\s*:([^\n]*)', timeout=5)[0] + expiry = dut.expect(r'expires on\s*:((.*)\d{4}\-(0?[1-9]|1[012])\-(0?[1-9]|[12][0-9]|3[01])*)', timeout=5)[1].decode() logging.info('Serial No. : {}'.format(serial_number)) logging.info('Issuer Name : {}'.format(issuer_name)) diff --git a/examples/protocols/https_server/wss_server/pytest_https_wss_server.py b/examples/protocols/https_server/wss_server/pytest_https_wss_server.py index 552f64e28f..396d2ea780 100644 --- a/examples/protocols/https_server/wss_server/pytest_https_wss_server.py +++ b/examples/protocols/https_server/wss_server/pytest_https_wss_server.py @@ -14,7 +14,7 @@ from typing import Any, Optional import pytest import websocket -from common_test_methods import get_env_config +from common_test_methods import get_env_config_variable from pytest_embedded import Dut OPCODE_TEXT = 0x1 @@ -122,11 +122,11 @@ def test_examples_protocol_https_wss_server(dut: Dut) -> None: logging.info('Waiting to connect with AP') if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True: - env_config = get_env_config('wifi_router') - ap_ssid = env_config['ap_ssid'] - ap_password = env_config['ap_password'] dut.expect('Please input ssid password:') - dut.write(' '.join([ap_ssid, ap_password])) + env_name = 'wifi_router' + ap_ssid = get_env_config_variable(env_name, 'ap_ssid') + ap_password = get_env_config_variable(env_name, 'ap_password') + dut.write(f'{ap_ssid} {ap_password}') # Parse IP address of STA got_port = int(dut.expect(r'Server listening on port (\d+)', timeout=30)[1].decode()) got_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() @@ -146,7 +146,7 @@ def test_examples_protocol_https_wss_server(dut: Dut) -> None: opcode, data = ws.read() data = data.decode('UTF-8') if data != DATA: - raise RuntimeError('Failed to receive the correct echo response') + raise RuntimeError(f'Failed to receive the correct echo response.') logging.info('Correct echo response obtained from the wss server') # Test for PING diff --git a/examples/protocols/https_x509_bundle/pytest_https_x509_bundle.py b/examples/protocols/https_x509_bundle/pytest_https_x509_bundle.py index b722953a01..e19bd92fbf 100644 --- a/examples/protocols/https_x509_bundle/pytest_https_x509_bundle.py +++ b/examples/protocols/https_x509_bundle/pytest_https_x509_bundle.py @@ -4,7 +4,7 @@ import logging import os import pytest -from common_test_methods import get_env_config +from common_test_methods import get_env_config_variable from pytest_embedded import Dut @@ -12,7 +12,7 @@ from pytest_embedded import Dut @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.wifi_nearby +@pytest.mark.wifi_ap def test_examples_protocol_https_x509_bundle(dut: Dut) -> None: """ steps: | @@ -26,11 +26,11 @@ def test_examples_protocol_https_x509_bundle(dut: Dut) -> None: logging.info('https_x509_bundle_bin_size : {}KB'.format(bin_size // 1024)) # Connect to AP if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True: - env_config = get_env_config('wifi_nearby') - ap_ssid = env_config['ap_ssid'] - ap_password = env_config['ap_password'] dut.expect('Please input ssid password:') - dut.write(' '.join([ap_ssid, ap_password])) + env_name = 'wifi_ap' + ap_ssid = get_env_config_variable(env_name, 'ap_ssid') + ap_password = get_env_config_variable(env_name, 'ap_password') + dut.write(f'{ap_ssid} {ap_password}') dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30) # start test num_URLS = int(dut.expect(r'Connecting to (\d+) URLs', timeout=30)[1].decode()) @@ -42,7 +42,7 @@ def test_examples_protocol_https_x509_bundle(dut: Dut) -> None: @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.wifi_nearby +@pytest.mark.wifi_ap @pytest.mark.parametrize('config', ['ssldyn',], indirect=True) def test_examples_protocol_https_x509_bundle_dynamic_buffer(dut: Dut) -> None: # test mbedtls dynamic resource @@ -52,11 +52,11 @@ def test_examples_protocol_https_x509_bundle_dynamic_buffer(dut: Dut) -> None: logging.info('https_x509_bundle_bin_size : {}KB'.format(bin_size // 1024)) # Connect to AP if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True: - env_config = get_env_config('wifi_nearby') - ap_ssid = env_config['ap_ssid'] - ap_password = env_config['ap_password'] dut.expect('Please input ssid password:') - dut.write(' '.join([ap_ssid, ap_password])) + env_name = 'wifi_ap' + ap_ssid = get_env_config_variable(env_name, 'ap_ssid') + ap_password = get_env_config_variable(env_name, 'ap_password') + dut.write(f'{ap_ssid} {ap_password}') dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30) # start test num_URLS = int(dut.expect(r'Connecting to (\d+) URLs', timeout=30)[1].decode()) diff --git a/examples/protocols/icmp_echo/main/echo_example_main.c b/examples/protocols/icmp_echo/main/echo_example_main.c index fba333bdd4..ce7955b7fd 100644 --- a/examples/protocols/icmp_echo/main/echo_example_main.c +++ b/examples/protocols/icmp_echo/main/echo_example_main.c @@ -214,7 +214,7 @@ void app_main(void) #endif /* register wifi connect commands */ - register_wifi_connect_commands(); + example_register_wifi_connect_commands(); /* register command `ping` */ register_ping(); /* register command `quit` */ diff --git a/examples/protocols/icmp_echo/pytest_icmp_echo.py b/examples/protocols/icmp_echo/pytest_icmp_echo.py index 7165e5c9da..c8172594f0 100644 --- a/examples/protocols/icmp_echo/pytest_icmp_echo.py +++ b/examples/protocols/icmp_echo/pytest_icmp_echo.py @@ -4,7 +4,7 @@ import os import pytest -from common_test_methods import get_env_config +from common_test_methods import get_env_config_variable from pytest_embedded import Dut @@ -12,13 +12,15 @@ from pytest_embedded import Dut @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.wifi_nearby +@pytest.mark.wifi_ap def test_protocols_icmp_echo(dut: Dut) -> None: # get env config - env_config = get_env_config('wifi_nearby') - ap_ssid = env_config['ap_ssid'] - ap_password = env_config['ap_password'] - ap_channel = env_config.get('ap_channel', 0) + sdkconfig_ssid = dut.app.sdkconfig.get('CONFIG_EXAMPLE_WIFI_SSID') + sdkconfig_pwd = dut.app.sdkconfig.get('CONFIG_EXAMPLE_WIFI_SSID') + env_name = 'wifi_ap' + ap_ssid = get_env_config_variable(env_name, 'ap_ssid', default=sdkconfig_ssid) + ap_password = get_env_config_variable(env_name, 'ap_password', default=sdkconfig_pwd) + ap_channel = get_env_config_variable(env_name, 'ap_channel', default=0) dut.expect('esp>') dut.write(f'wifi_connect {ap_ssid} {ap_password} -n {ap_channel}') diff --git a/examples/protocols/modbus/tcp/example_test.py b/examples/protocols/modbus/tcp/example_test.py index 925b465ff4..f3fa9ceddc 100644 --- a/examples/protocols/modbus/tcp/example_test.py +++ b/examples/protocols/modbus/tcp/example_test.py @@ -29,8 +29,8 @@ STACK_PAR_OK = 6 STACK_PAR_FAIL = 7 STACK_DESTROY = 8 -pattern_dict_slave = {STACK_IPV4: (r'.*I \([0-9]+\) example_connect: - IPv4 address: ([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}).*'), - STACK_IPV6: (r'.*I \([0-9]+\) example_connect: - IPv6 address: (([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}).*'), +pattern_dict_slave = {STACK_IPV4: (r'.*I \([0-9]+\) example_common: - IPv4 address: ([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}).*'), + STACK_IPV6: (r'.*I \([0-9]+\) example_common: - IPv6 address: (([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}).*'), STACK_INIT: (r'.*I \(([0-9]+)\) MB_TCP_SLAVE_PORT: (Protocol stack initialized).'), STACK_CONNECT: (r'.*I\s\(([0-9]+)\) MB_TCP_SLAVE_PORT: Socket \(#[0-9]+\), accept client connection from address: ' r'([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}).*'), @@ -40,8 +40,8 @@ pattern_dict_slave = {STACK_IPV4: (r'.*I \([0-9]+\) example_connect: - IPv4 addr STACK_PAR_FAIL: (r'.*E \(([0-9]+)\) SLAVE_TEST: Response time exceeds configured [0-9]+ [ms], ignore packet.*'), STACK_DESTROY: (r'.*I\s\(([0-9]+)\) SLAVE_TEST: (Modbus controller destroyed).')} -pattern_dict_master = {STACK_IPV4: (r'.*I \([0-9]+\) example_connect: - IPv4 address: ([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}).*'), - STACK_IPV6: (r'.*I \([0-9]+\) example_connect: - IPv6 address: (([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}).*'), +pattern_dict_master = {STACK_IPV4: (r'.*I \([0-9]+\) example_common: - IPv4 address: ([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}).*'), + STACK_IPV6: (r'.*I \([0-9]+\) example_common: - IPv6 address: (([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}).*'), STACK_INIT: (r'.*I \(([0-9]+)\) MASTER_TEST: (Modbus master stack initialized).*'), STACK_CONNECT: (r'.*.*I\s\(([0-9]+)\) MB_TCP_MASTER_PORT: (Connected [0-9]+ slaves), start polling.*'), STACK_START: (r'.*I \(([0-9]+)\) MASTER_TEST: (Start modbus test).*'), diff --git a/examples/protocols/mqtt/ssl/mqtt_ssl_example_test.py b/examples/protocols/mqtt/ssl/mqtt_ssl_example_test.py index dc879d184a..0bdd6d355b 100644 --- a/examples/protocols/mqtt/ssl/mqtt_ssl_example_test.py +++ b/examples/protocols/mqtt/ssl/mqtt_ssl_example_test.py @@ -58,7 +58,7 @@ def on_message(client, userdata, msg): message_log += 'Received data:' + msg.topic + ' ' + payload + '\n' -@ttfw_idf.idf_example_test(env_tag='Example_EthKitV1') +@ttfw_idf.idf_example_test(env_tag='ethernet_router') def test_examples_protocol_mqtt_ssl(env, extra_data): broker_url = '' broker_port = 0 @@ -110,7 +110,7 @@ def test_examples_protocol_mqtt_ssl(env, extra_data): raise ValueError('ENV_TEST_FAILURE: Test script cannot connect to broker: {}'.format(broker_url)) dut1.start_app() try: - ip_address = dut1.expect(re.compile(r'IPv4 address: ([^,]+),'), timeout=30) + ip_address = dut1.expect(re.compile(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)'), timeout=30)[0] print('Connected to AP with IP: {}'.format(ip_address)) except DUT.ExpectTimeout: print('ENV_TEST_FAILURE: Cannot connect to AP') diff --git a/examples/protocols/mqtt/tcp/mqtt_tcp_example_test.py b/examples/protocols/mqtt/tcp/mqtt_tcp_example_test.py index 06c5691fd4..735c6ade53 100644 --- a/examples/protocols/mqtt/tcp/mqtt_tcp_example_test.py +++ b/examples/protocols/mqtt/tcp/mqtt_tcp_example_test.py @@ -7,7 +7,7 @@ import time from threading import Thread import ttfw_idf -from common_test_methods import get_my_ip4_by_dest_ip +from common_test_methods import get_host_ip4_by_dest_ip from tiny_test_fw import DUT msgid = -1 @@ -46,7 +46,7 @@ def mqqt_server_sketch(my_ip, port): print('server closed') -@ttfw_idf.idf_example_test(env_tag='Example_EthKitV1') +@ttfw_idf.idf_example_test(env_tag='ethernet_router') def test_examples_protocol_mqtt_qos1(env, extra_data): global msgid """ @@ -65,13 +65,13 @@ def test_examples_protocol_mqtt_qos1(env, extra_data): dut1.start_app() # waiting for getting the IP address try: - ip_address = dut1.expect(re.compile(r'IPv4 address: ([^,]+),'), timeout=30)[0] + ip_address = dut1.expect(re.compile(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)'), timeout=30)[0] print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except DUT.ExpectTimeout: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') # 2. start mqtt broker sketch - host_ip = get_my_ip4_by_dest_ip(ip_address) + host_ip = get_host_ip4_by_dest_ip(ip_address) thread1 = Thread(target=mqqt_server_sketch, args=(host_ip,1883)) thread1.start() diff --git a/examples/protocols/mqtt/ws/mqtt_ws_example_test.py b/examples/protocols/mqtt/ws/mqtt_ws_example_test.py index b4fc2fa38d..f8d87d9768 100644 --- a/examples/protocols/mqtt/ws/mqtt_ws_example_test.py +++ b/examples/protocols/mqtt/ws/mqtt_ws_example_test.py @@ -39,7 +39,7 @@ def on_message(client, userdata, msg): message_log += 'Received data:' + msg.topic + ' ' + payload + '\n' -@ttfw_idf.idf_example_test(env_tag='Example_EthKitV1') +@ttfw_idf.idf_example_test(env_tag='ethernet_router') def test_examples_protocol_mqtt_ws(env, extra_data): broker_url = '' broker_port = 0 @@ -83,7 +83,7 @@ def test_examples_protocol_mqtt_ws(env, extra_data): raise ValueError('ENV_TEST_FAILURE: Test script cannot connect to broker: {}'.format(broker_url)) dut1.start_app() try: - ip_address = dut1.expect(re.compile(r'IPv4 address: ([^,]+),'), timeout=30) + ip_address = dut1.expect(re.compile(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)'), timeout=30)[0] print('Connected to AP with IP: {}'.format(ip_address)) except DUT.ExpectTimeout: print('ENV_TEST_FAILURE: Cannot connect to AP') diff --git a/examples/protocols/mqtt/wss/mqtt_wss_example_test.py b/examples/protocols/mqtt/wss/mqtt_wss_example_test.py index b00a154741..4d204d6b10 100644 --- a/examples/protocols/mqtt/wss/mqtt_wss_example_test.py +++ b/examples/protocols/mqtt/wss/mqtt_wss_example_test.py @@ -40,7 +40,7 @@ def on_message(client, userdata, msg): message_log += 'Received data:' + msg.topic + ' ' + payload + '\n' -@ttfw_idf.idf_example_test(env_tag='Example_EthKitV1') +@ttfw_idf.idf_example_test(env_tag='ethernet_router') def test_examples_protocol_mqtt_wss(env, extra_data): broker_url = '' broker_port = 0 @@ -87,7 +87,7 @@ def test_examples_protocol_mqtt_wss(env, extra_data): raise ValueError('ENV_TEST_FAILURE: Test script cannot connect to broker: {}'.format(broker_url)) dut1.start_app() try: - ip_address = dut1.expect(re.compile(r'IPv4 address: ([^,]+),'), timeout=30) + ip_address = dut1.expect(re.compile(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)'), timeout=30)[0] print('Connected to AP with IP: {}'.format(ip_address)) except DUT.ExpectTimeout: print('ENV_TEST_FAILURE: Cannot connect to AP') diff --git a/examples/protocols/sntp/pytest_sntp.py b/examples/protocols/sntp/pytest_sntp.py index 26f19b7712..fb5f83dc68 100644 --- a/examples/protocols/sntp/pytest_sntp.py +++ b/examples/protocols/sntp/pytest_sntp.py @@ -6,20 +6,20 @@ import logging from typing import Any, Tuple import pytest -from common_test_methods import get_env_config +from common_test_methods import get_env_config_variable from pytest_embedded import Dut @pytest.mark.esp32 -@pytest.mark.wifi_nearby +@pytest.mark.wifi_ap def test_get_time_from_sntp_server(dut: Dut) -> None: dut.expect('Time is not set yet. Connecting to WiFi and getting time over NTP.') if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True: - env_config = get_env_config('wifi_nearby') - ap_ssid = env_config['ap_ssid'] - ap_password = env_config['ap_password'] dut.expect('Please input ssid password:') - dut.write(' '.join([ap_ssid, ap_password])) + env_name = 'wifi_ap' + ap_ssid = get_env_config_variable(env_name, 'ap_ssid') + ap_password = get_env_config_variable(env_name, 'ap_password') + dut.write(f'{ap_ssid} {ap_password}') dut.expect('IPv4 address:') dut.expect('Initializing SNTP') diff --git a/examples/protocols/sockets/tcp_client/example_test.py b/examples/protocols/sockets/tcp_client/example_test.py index 76c70b760f..d8dc41a542 100644 --- a/examples/protocols/sockets/tcp_client/example_test.py +++ b/examples/protocols/sockets/tcp_client/example_test.py @@ -17,7 +17,7 @@ from threading import Event, Thread import netifaces import ttfw_idf -from common_test_methods import get_env_config, get_my_interface_by_dest_ip, get_my_ip_by_interface +from common_test_methods import get_env_config_variable, get_host_ip_by_interface, get_my_interface_by_dest_ip # ----------- Config ---------- PORT = 3333 @@ -97,13 +97,13 @@ def test_examples_protocol_socket_tcpclient(env, extra_data): # start test dut1.start_app() if dut1.app.get_sdkconfig_config_value('CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN'): - env_config = get_env_config('wifi_router') - ap_ssid = env_config['ap_ssid'] - ap_password = env_config['ap_password'] dut1.expect('Please input ssid password:') - dut1.write(' '.join([ap_ssid, ap_password])) + env_name = 'wifi_router' + ap_ssid = get_env_config_variable(env_name, 'ap_ssid') + ap_password = get_env_config_variable(env_name, 'ap_password') + dut1.write(f'{ap_ssid} {ap_password}') - ipv4 = dut1.expect(re.compile(r' IPv4 address: ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)'), timeout=30)[0] + ipv4 = dut1.expect(re.compile(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)'), timeout=30)[0] ipv6_r = r':'.join((r'[0-9a-fA-F]{4}',) * 8) # expect all 8 octets from IPv6 (assumes it's printed in the long form) ipv6 = dut1.expect(re.compile(r' IPv6 address: ({})'.format(ipv6_r)), timeout=30)[0] print('Connected with IPv4={} and IPv6={}'.format(ipv4, ipv6)) @@ -111,13 +111,13 @@ def test_examples_protocol_socket_tcpclient(env, extra_data): my_interface = get_my_interface_by_dest_ip(ipv4) # test IPv4 with TcpServer(PORT, socket.AF_INET): - server_ip = get_my_ip_by_interface(my_interface, netifaces.AF_INET) + server_ip = get_host_ip_by_interface(my_interface, netifaces.AF_INET) print('Connect tcp client to server IP={}'.format(server_ip)) dut1.write(server_ip) dut1.expect(re.compile(r'OK: Message from ESP32')) # test IPv6 with TcpServer(PORT, socket.AF_INET6): - server_ip = get_my_ip_by_interface(my_interface, netifaces.AF_INET6) + server_ip = get_host_ip_by_interface(my_interface, netifaces.AF_INET6) print('Connect tcp client to server IP={}'.format(server_ip)) dut1.write(server_ip) dut1.expect(re.compile(r'OK: Message from ESP32')) diff --git a/examples/protocols/sockets/tcp_server/example_test.py b/examples/protocols/sockets/tcp_server/example_test.py index d3728c0805..bc8bd5d293 100644 --- a/examples/protocols/sockets/tcp_server/example_test.py +++ b/examples/protocols/sockets/tcp_server/example_test.py @@ -14,7 +14,7 @@ import socket import sys import ttfw_idf -from common_test_methods import get_env_config, get_my_interface_by_dest_ip +from common_test_methods import get_env_config_variable, get_my_interface_by_dest_ip # ----------- Config ---------- PORT = 3333 @@ -64,13 +64,13 @@ def test_examples_protocol_socket_tcpserver(env, extra_data): # start test dut1.start_app() if dut1.app.get_sdkconfig_config_value('CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN'): - env_config = get_env_config('wifi_router') - ap_ssid = env_config['ap_ssid'] - ap_password = env_config['ap_password'] dut1.expect('Please input ssid password:') - dut1.write(' '.join([ap_ssid, ap_password])) + env_name = 'wifi_router' + ap_ssid = get_env_config_variable(env_name, 'ap_ssid') + ap_password = get_env_config_variable(env_name, 'ap_password') + dut1.write(f'{ap_ssid} {ap_password}') - ipv4 = dut1.expect(re.compile(r' IPv4 address: ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)'), timeout=30)[0] + ipv4 = dut1.expect(re.compile(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)'), timeout=30)[0] ipv6_r = r':'.join((r'[0-9a-fA-F]{4}',) * 8) # expect all 8 octets from IPv6 (assumes it's printed in the long form) ipv6 = dut1.expect(re.compile(r' IPv6 address: ({})'.format(ipv6_r)), timeout=30)[0] print('Connected with IPv4={} and IPv6={}'.format(ipv4, ipv6)) diff --git a/examples/protocols/sockets/udp_client/example_test.py b/examples/protocols/sockets/udp_client/example_test.py index 2878ade7f2..c90ff7488f 100644 --- a/examples/protocols/sockets/udp_client/example_test.py +++ b/examples/protocols/sockets/udp_client/example_test.py @@ -17,7 +17,8 @@ from threading import Event, Thread import netifaces import ttfw_idf -from common_test_methods import get_env_config, get_my_interface_by_dest_ip, get_my_ip_by_interface +from common_test_methods import get_env_config_variable, get_host_ip_by_interface, get_my_interface_by_dest_ip +from tiny_test_fw.DUT import ExpectTimeout # ----------- Config ---------- PORT = 3333 @@ -60,6 +61,7 @@ class UdpServer: while not self.shutdown.is_set(): try: data, addr = self.socket.recvfrom(1024) + print(addr) if not data: return data = data.decode() @@ -90,13 +92,13 @@ def test_examples_protocol_socket_udpclient(env, extra_data): # start test dut1.start_app() if dut1.app.get_sdkconfig_config_value('CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN'): - env_config = get_env_config('wifi_router') - ap_ssid = env_config['ap_ssid'] - ap_password = env_config['ap_password'] dut1.expect('Please input ssid password:') - dut1.write(' '.join([ap_ssid, ap_password])) + env_name = 'wifi_router' + ap_ssid = get_env_config_variable(env_name, 'ap_ssid') + ap_password = get_env_config_variable(env_name, 'ap_password') + dut1.write(f'{ap_ssid} {ap_password}') - ipv4 = dut1.expect(re.compile(r' IPv4 address: ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)'), timeout=30)[0] + ipv4 = dut1.expect(re.compile(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)'), timeout=30)[0] ipv6_r = r':'.join((r'[0-9a-fA-F]{4}',) * 8) # expect all 8 octets from IPv6 (assumes it's printed in the long form) ipv6 = dut1.expect(re.compile(r' IPv6 address: ({})'.format(ipv6_r)), timeout=30)[0] print('Connected with IPv4={} and IPv6={}'.format(ipv4, ipv6)) @@ -104,16 +106,30 @@ def test_examples_protocol_socket_udpclient(env, extra_data): my_interface = get_my_interface_by_dest_ip(ipv4) # test IPv4 with UdpServer(PORT, socket.AF_INET): - server_ip = get_my_ip_by_interface(my_interface, netifaces.AF_INET) + server_ip = get_host_ip_by_interface(my_interface, netifaces.AF_INET) print('Connect udp client to server IP={}'.format(server_ip)) - dut1.write(server_ip) - dut1.expect(re.compile(r'OK: Message from ESP32')) + for _ in range(3): + try: + dut1.write(server_ip) + dut1.expect(re.compile(r'OK: Message from ESP32')) + break + except ExpectTimeout: + pass + else: + raise ValueError('Failed to send/recv udp packets.') # test IPv6 with UdpServer(PORT, socket.AF_INET6): - server_ip = get_my_ip_by_interface(my_interface, netifaces.AF_INET6) + server_ip = get_host_ip_by_interface(my_interface, netifaces.AF_INET6) print('Connect udp client to server IP={}'.format(server_ip)) - dut1.write(server_ip) - dut1.expect(re.compile(r'OK: Message from ESP32')) + for _ in range(3): + try: + dut1.write(server_ip) + dut1.expect(re.compile(r'OK: Message from ESP32')) + break + except ExpectTimeout: + pass + else: + raise ValueError('Failed to send/recv udp packets.') if __name__ == '__main__': diff --git a/examples/protocols/sockets/udp_client/main/udp_client.c b/examples/protocols/sockets/udp_client/main/udp_client.c index 7d39803311..268f6e65da 100644 --- a/examples/protocols/sockets/udp_client/main/udp_client.c +++ b/examples/protocols/sockets/udp_client/main/udp_client.c @@ -73,6 +73,13 @@ static void udp_client_task(void *pvParameters) ESP_LOGE(TAG, "Unable to create socket: errno %d", errno); break; } + + // Set timeout + struct timeval timeout; + timeout.tv_sec = 10; + timeout.tv_usec = 0; + setsockopt (sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof timeout); + ESP_LOGI(TAG, "Socket created, sending to %s:%d", HOST_IP_ADDR, PORT); while (1) { diff --git a/examples/protocols/sockets/udp_server/example_test.py b/examples/protocols/sockets/udp_server/example_test.py index 72057339b4..7aebb8ff8a 100644 --- a/examples/protocols/sockets/udp_server/example_test.py +++ b/examples/protocols/sockets/udp_server/example_test.py @@ -14,7 +14,7 @@ import socket import sys import ttfw_idf -from common_test_methods import get_env_config, get_my_interface_by_dest_ip +from common_test_methods import get_env_config_variable, get_my_interface_by_dest_ip # ----------- Config ---------- PORT = 3333 @@ -68,13 +68,13 @@ def test_examples_protocol_socket_udpserver(env, extra_data): # start test dut1.start_app() if dut1.app.get_sdkconfig_config_value('CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN'): - env_config = get_env_config('wifi_router') - ap_ssid = env_config['ap_ssid'] - ap_password = env_config['ap_password'] dut1.expect('Please input ssid password:') - dut1.write(' '.join([ap_ssid, ap_password])) + env_name = 'wifi_router' + ap_ssid = get_env_config_variable(env_name, 'ap_ssid') + ap_password = get_env_config_variable(env_name, 'ap_password') + dut1.write(f'{ap_ssid} {ap_password}') - ipv4 = dut1.expect(re.compile(r' IPv4 address: ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)'), timeout=30)[0] + ipv4 = dut1.expect(re.compile(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)'), timeout=30)[0] ipv6_r = r':'.join((r'[0-9a-fA-F]{4}',) * 8) # expect all 8 octets from IPv6 (assumes it's printed in the long form) ipv6 = dut1.expect(re.compile(r' IPv6 address: ({})'.format(ipv6_r)), timeout=30)[0] print('Connected with IPv4={} and IPv6={}'.format(ipv4, ipv6)) diff --git a/examples/protocols/sockets/udp_server/main/udp_server.c b/examples/protocols/sockets/udp_server/main/udp_server.c index 3db2a89a97..5381b00f7c 100644 --- a/examples/protocols/sockets/udp_server/main/udp_server.c +++ b/examples/protocols/sockets/udp_server/main/udp_server.c @@ -71,6 +71,11 @@ static void udp_server_task(void *pvParameters) setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt)); } #endif + // Set timeout + struct timeval timeout; + timeout.tv_sec = 10; + timeout.tv_usec = 0; + setsockopt (sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof timeout); int err = bind(sock, (struct sockaddr *)&dest_addr, sizeof(dest_addr)); if (err < 0) { diff --git a/examples/system/ota/README.md b/examples/system/ota/README.md index 376a823e31..ff5e5ee8e0 100644 --- a/examples/system/ota/README.md +++ b/examples/system/ota/README.md @@ -86,12 +86,14 @@ cp ca_cert.pem /path/to/ota/example/server_certs/ ### Internal workflow of the OTA Example -After booting, the firmware prints "Starting OTA example" to the console and: +After booting, the firmware: -1. Connects via Ethernet or to the AP using the provided SSID and password (Wi-Fi case) -2. Connects to the HTTPS server and downloads the new image -3. Writes the image to flash, and instructs the bootloader to boot from this image after the next reset -4. Reboots +1. prints "OTA example app_main start" to the console +2. Connects via Ethernet or to the AP using the provided SSID and password (Wi-Fi case) +3. prints "Starting OTA example task" to the console +4. Connects to the HTTPS server and downloads the new image +5. Writes the image to flash, and instructs the bootloader to boot from this image after the next reset +6. Reboots If you want to rollback to the `factory` app after the upgrade (or to the first OTA partition in case the `factory` partition does not exist), run the command `idf.py erase_otadata`. This restores the `ota_data` partition to its initial state. diff --git a/examples/system/ota/advanced_https_ota/main/advanced_https_ota_example.c b/examples/system/ota/advanced_https_ota/main/advanced_https_ota_example.c index b2f8aaa3fd..434f612ca2 100644 --- a/examples/system/ota/advanced_https_ota/main/advanced_https_ota_example.c +++ b/examples/system/ota/advanced_https_ota/main/advanced_https_ota_example.c @@ -176,6 +176,7 @@ ota_end: void app_main(void) { + ESP_LOGI(TAG, "OTA example app_main start"); // Initialize NVS. esp_err_t err = nvs_flash_init(); if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) { diff --git a/examples/system/ota/advanced_https_ota/pytest_advanced_ota.py b/examples/system/ota/advanced_https_ota/pytest_advanced_ota.py index 295bee727c..c07dfcf9d9 100644 --- a/examples/system/ota/advanced_https_ota/pytest_advanced_ota.py +++ b/examples/system/ota/advanced_https_ota/pytest_advanced_ota.py @@ -1,6 +1,5 @@ # SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Unlicense OR CC0-1.0 -from ast import Try import http.server import multiprocessing import os @@ -9,11 +8,12 @@ import socket import ssl import struct import subprocess +import time from typing import Callable import pexpect import pytest -from common_test_methods import get_my_ip4_by_dest_ip +from common_test_methods import get_env_config_variable, get_host_ip4_by_dest_ip from pytest_embedded import Dut from RangeHTTPServer import RangeRequestHandler @@ -97,7 +97,7 @@ def start_redirect_server(ota_image_dir: str, server_ip: str, server_port: int, @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.ethernet_router +@pytest.mark.ethernet_ota def test_examples_protocol_advanced_https_ota_example(dut: Dut) -> None: """ This is a positive test case, which downloads complete binary file multiple number of times. @@ -111,32 +111,34 @@ def test_examples_protocol_advanced_https_ota_example(dut: Dut) -> None: iterations = 3 server_port = 8001 bin_name = 'advanced_https_ota.bin' - # start test - for _ in range(iterations): - dut.expect('Loaded app from partition at offset', timeout=30) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30)[1].decode() - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') - dut.expect('Starting Advanced OTA example', timeout=30) + # Start server + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, '0.0.0.0', server_port)) + thread1.daemon = True + thread1.start() + try: + # start test + for _ in range(iterations): + dut.expect('Loaded app from partition at offset', timeout=30) + try: + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + dut.expect('Starting Advanced OTA example', timeout=30) + host_ip = get_host_ip4_by_dest_ip(ip_address) - host_ip = get_my_ip4_by_dest_ip(ip_address) - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) - thread1.daemon = True - thread1.start() - try: print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + bin_name)) dut.write('https://' + host_ip + ':' + str(server_port) + '/' + bin_name) - finally: - thread1.terminate() + dut.expect('upgrade successful. Rebooting ...', timeout=60) + finally: + thread1.terminate() @pytest.mark.esp32 @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.ethernet_router +@pytest.mark.ethernet_ota def test_examples_protocol_advanced_https_ota_example_truncated_bin(dut: Dut) -> None: """ Working of OTA if binary file is truncated is validated in this test case. @@ -159,24 +161,22 @@ def test_examples_protocol_advanced_https_ota_example_truncated_bin(dut: Dut) -> with open(binary_file, 'rb+') as f: with open(os.path.join(dut.app.binary_path, truncated_bin_name), 'wb+') as fo: fo.write(f.read(truncated_bin_size)) - binary_file = os.path.join(dut.app.binary_path, truncated_bin_name) - # start test - dut.expect('Loaded app from partition at offset', timeout=30) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30)[1].decode() - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') - dut.expect('Starting Advanced OTA example', timeout=30) - # Start server - host_ip = get_my_ip4_by_dest_ip(ip_address) - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, '0.0.0.0', server_port)) thread1.daemon = True thread1.start() - try: + # start test + dut.expect('Loaded app from partition at offset', timeout=30) + try: + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + dut.expect('Starting Advanced OTA example', timeout=30) + host_ip = get_host_ip4_by_dest_ip(ip_address) + print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + truncated_bin_name)) dut.write('https://' + host_ip + ':' + str(server_port) + '/' + truncated_bin_name) dut.expect('Image validation failed, image is corrupted', timeout=30) @@ -192,7 +192,7 @@ def test_examples_protocol_advanced_https_ota_example_truncated_bin(dut: Dut) -> @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.ethernet_router +@pytest.mark.ethernet_ota def test_examples_protocol_advanced_https_ota_example_truncated_header(dut: Dut) -> None: """ Working of OTA if headers of binary file are truncated is vaildated in this test case. @@ -215,22 +215,21 @@ def test_examples_protocol_advanced_https_ota_example_truncated_header(dut: Dut) with open(binary_file, 'rb+') as f: with open(os.path.join(dut.app.binary_path, truncated_bin_name), 'wb+') as fo: fo.write(f.read(truncated_bin_size)) - binary_file = os.path.join(dut.app.binary_path, truncated_bin_name) - # start test - dut.expect('Loaded app from partition at offset', timeout=30) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30)[1].decode() - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') # Start server - host_ip = get_my_ip4_by_dest_ip(ip_address) - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, '0.0.0.0', server_port)) thread1.daemon = True thread1.start() - try: + # start test + dut.expect('Loaded app from partition at offset', timeout=30) + try: + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + host_ip = get_host_ip4_by_dest_ip(ip_address) + dut.expect('Starting Advanced OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + truncated_bin_name)) dut.write('https://' + host_ip + ':' + str(server_port) + '/' + truncated_bin_name) @@ -247,7 +246,7 @@ def test_examples_protocol_advanced_https_ota_example_truncated_header(dut: Dut) @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.ethernet_router +@pytest.mark.ethernet_ota def test_examples_protocol_advanced_https_ota_example_random(dut: Dut) -> None: """ Working of OTA if random data is added in binary file are validated in this test case. @@ -271,21 +270,20 @@ def test_examples_protocol_advanced_https_ota_example_random(dut: Dut) -> None: fo.write(struct.pack('B', 0)) for i in range(random_bin_size - 1): fo.write(struct.pack('B', random.randrange(0,255,1))) - - # start test - dut.expect('Loaded app from partition at offset', timeout=30) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30)[1].decode() - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') # Start server - host_ip = get_my_ip4_by_dest_ip(ip_address) - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, '0.0.0.0', server_port)) thread1.daemon = True thread1.start() - try: + # start test + dut.expect('Loaded app from partition at offset', timeout=30) + try: + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + host_ip = get_host_ip4_by_dest_ip(ip_address) + dut.expect('Starting Advanced OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + random_bin_name)) dut.write('https://' + host_ip + ':' + str(server_port) + '/' + random_bin_name) @@ -302,7 +300,7 @@ def test_examples_protocol_advanced_https_ota_example_random(dut: Dut) -> None: @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.ethernet_router +@pytest.mark.ethernet_ota def test_examples_protocol_advanced_https_ota_example_invalid_chip_id(dut: Dut) -> None: """ Working of OTA if binary file have invalid chip id is validated in this test case. @@ -328,21 +326,20 @@ def test_examples_protocol_advanced_https_ota_example_invalid_chip_id(dut: Dut) data[13] = 0xfe with open(random_binary_file, 'wb+') as fo: fo.write(bytearray(data)) - - # start test - dut.expect('Loaded app from partition at offset', timeout=30) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30)[1].decode() - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') # Start server - host_ip = get_my_ip4_by_dest_ip(ip_address) - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, '0.0.0.0', server_port)) thread1.daemon = True thread1.start() - try: + # start test + dut.expect('Loaded app from partition at offset', timeout=30) + try: + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + host_ip = get_host_ip4_by_dest_ip(ip_address) + dut.expect('Starting Advanced OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + random_bin_name)) dut.write('https://' + host_ip + ':' + str(server_port) + '/' + random_bin_name) @@ -359,7 +356,7 @@ def test_examples_protocol_advanced_https_ota_example_invalid_chip_id(dut: Dut) @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.ethernet_router +@pytest.mark.ethernet_ota def test_examples_protocol_advanced_https_ota_example_chunked(dut: Dut) -> None: """ This is a positive test case, which downloads complete binary file multiple number of times. @@ -371,23 +368,25 @@ def test_examples_protocol_advanced_https_ota_example_chunked(dut: Dut) -> None: """ # File to be downloaded. This file is generated after compilation bin_name = 'advanced_https_ota.bin' - # start test - dut.expect('Loaded app from partition at offset', timeout=30) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30)[1].decode() - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') # Start server - host_ip = get_my_ip4_by_dest_ip(ip_address) chunked_server = start_chunked_server(dut.app.binary_path, 8070) - try: + # start test + dut.expect('Loaded app from partition at offset', timeout=30) + try: + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + host_ip = get_host_ip4_by_dest_ip(ip_address) + dut.expect('Starting Advanced OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':8070/' + bin_name)) dut.write('https://' + host_ip + ':8070/' + bin_name) - dut.expect('Loaded app from partition at offset', timeout=60) - dut.expect('Starting Advanced OTA example', timeout=30) + dut.expect('upgrade successful. Rebooting ...', timeout=60) + # after reboot + dut.expect('Loaded app from partition at offset', timeout=30) + dut.expect('OTA example app_main start', timeout=10) finally: chunked_server.kill() @@ -396,7 +395,7 @@ def test_examples_protocol_advanced_https_ota_example_chunked(dut: Dut) -> None: @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.ethernet_router +@pytest.mark.ethernet_ota def test_examples_protocol_advanced_https_ota_example_redirect_url(dut: Dut) -> None: """ This is a positive test case, which starts a server and a redirection server. @@ -416,29 +415,32 @@ def test_examples_protocol_advanced_https_ota_example_redirect_url(dut: Dut) -> # start test dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30)[1].decode() + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') dut.expect('Starting Advanced OTA example', timeout=30) # Start server - host_ip = get_my_ip4_by_dest_ip(ip_address) + host_ip = get_host_ip4_by_dest_ip(ip_address) thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) thread1.daemon = True thread2 = multiprocessing.Process(target=start_redirect_server, args=(dut.app.binary_path, host_ip, redirection_server_port, redirection_server_port1)) thread2.daemon = True thread3 = multiprocessing.Process(target=start_redirect_server, args=(dut.app.binary_path, host_ip, redirection_server_port1, server_port)) thread3.daemon = True + thread1.start() + thread2.start() + thread3.start() + time.sleep(1) try: - thread1.start() - thread2.start() - thread3.start() print('writing to device: {}'.format('https://' + host_ip + ':' + str(redirection_server_port) + '/' + bin_name)) dut.write('https://' + host_ip + ':' + str(redirection_server_port) + '/' + bin_name) - dut.expect('Loaded app from partition at offset', timeout=60) - dut.expect('Starting Advanced OTA example', timeout=30) + dut.expect('upgrade successful. Rebooting ...', timeout=60) + # after reboot + dut.expect('Loaded app from partition at offset', timeout=30) + dut.expect('OTA example app_main start', timeout=10) finally: thread1.terminate() thread2.terminate() @@ -479,27 +481,27 @@ def test_examples_protocol_advanced_https_ota_example_anti_rollback(dut: Dut) -> fo.seek(36) fo.write(b'\x00') binary_file = os.path.join(dut.app.binary_path, anti_rollback_bin_name) - # start test - # Positive Case - dut.expect('Loaded app from partition at offset', timeout=30) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30)[1].decode() - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') # Start server - host_ip = get_my_ip4_by_dest_ip(ip_address) - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, '0.0.0.0', server_port)) thread1.daemon = True thread1.start() - try: + # start test + # Positive Case + dut.expect('Loaded app from partition at offset', timeout=30) + try: + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + host_ip = get_host_ip4_by_dest_ip(ip_address) + dut.expect('Starting Advanced OTA example', timeout=30) # Use originally generated image with secure_version=1 print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + bin_name)) dut.write('https://' + host_ip + ':' + str(server_port) + '/' + bin_name) dut.expect('Loaded app from partition at offset', timeout=60) - dut.expect(r'IPv4 address: ([^,]+),', timeout=30) + dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() dut.expect(r'App is valid, rollback cancelled successfully', timeout=30) # Negative Case @@ -520,7 +522,7 @@ def test_examples_protocol_advanced_https_ota_example_anti_rollback(dut: Dut) -> @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.ethernet_router +@pytest.mark.ethernet_ota @pytest.mark.parametrize('config', ['partial_download',], indirect=True) def test_examples_protocol_advanced_https_ota_example_partial_request(dut: Dut) -> None: """ @@ -532,35 +534,37 @@ def test_examples_protocol_advanced_https_ota_example_partial_request(dut: Dut) """ server_port = 8001 # Size of partial HTTP request - request_size = 16384 + request_size = int(dut.app.sdkconfig.get('EXAMPLE_HTTP_REQUEST_SIZE')) # File to be downloaded. This file is generated after compilation bin_name = 'advanced_https_ota.bin' binary_file = os.path.join(dut.app.binary_path, bin_name) bin_size = os.path.getsize(binary_file) http_requests = int((bin_size / request_size) - 1) - # start test - dut.expect('Loaded app from partition at offset', timeout=30) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30)[1].decode() - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - print('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') - raise + assert http_requests > 1 # Start server - host_ip = get_my_ip4_by_dest_ip(ip_address) - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, '0.0.0.0', server_port)) thread1.daemon = True thread1.start() - try: + # start test + dut.expect('Loaded app from partition at offset', timeout=30) + try: + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + host_ip = get_host_ip4_by_dest_ip(ip_address) + dut.expect('Starting Advanced OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + bin_name)) dut.write('https://' + host_ip + ':' + str(server_port) + '/' + bin_name) for _ in range(http_requests): dut.expect('Connection closed', timeout=60) - dut.expect('Loaded app from partition at offset', timeout=60) - dut.expect('Starting Advanced OTA example', timeout=30) - except: + dut.expect('upgrade successful. Rebooting ...', timeout=60) + # after reboot + dut.expect('Loaded app from partition at offset', timeout=30) + dut.expect('OTA example app_main start', timeout=20) + finally: thread1.terminate() @@ -568,7 +572,7 @@ def test_examples_protocol_advanced_https_ota_example_partial_request(dut: Dut) @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.wifi_ota +@pytest.mark.wifi_high_traffic @pytest.mark.nightly_run @pytest.mark.parametrize('config', ['nimble',], indirect=True) def test_examples_protocol_advanced_https_ota_example_nimble_gatts(dut: Dut) -> None: @@ -583,29 +587,37 @@ def test_examples_protocol_advanced_https_ota_example_nimble_gatts(dut: Dut) -> server_port = 8001 # File to be downloaded. This file is generated after compilation bin_name = 'advanced_https_ota.bin' - # start test - dut.expect('Loaded app from partition at offset', timeout=30) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30)[1].decode() - print('Connected to AP with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') - # Start server - host_ip = get_my_ip4_by_dest_ip(ip_address) - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, '0.0.0.0', server_port)) thread1.daemon = True thread1.start() - try: + # start test + dut.expect('Loaded app from partition at offset', timeout=30) + # Parse IP address of STA + if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True: + env_name = 'wifi_high_traffic' + dut.expect('Please input ssid password:') + ap_ssid = get_env_config_variable(env_name, 'ap_ssid') + ap_password = get_env_config_variable(env_name, 'ap_password') + dut.write(f'{ap_ssid} {ap_password}') + try: + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + print('Connected to AP with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + host_ip = get_host_ip4_by_dest_ip(ip_address) + dut.expect('Starting Advanced OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + bin_name)) print('Started GAP advertising.') dut.write('https://' + host_ip + ':' + str(server_port) + '/' + bin_name) - dut.expect('Loaded app from partition at offset', timeout=60) - dut.expect('Starting Advanced OTA example', timeout=30) - except: + dut.expect('upgrade successful. Rebooting ...', timeout=60) + # after reboot + dut.expect('Loaded app from partition at offset', timeout=30) + dut.expect('OTA example app_main start', timeout=10) + finally: thread1.terminate() @@ -613,7 +625,7 @@ def test_examples_protocol_advanced_https_ota_example_nimble_gatts(dut: Dut) -> @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.wifi_ota +@pytest.mark.wifi_high_traffic @pytest.mark.nightly_run @pytest.mark.parametrize('config', ['bluedroid',], indirect=True) def test_examples_protocol_advanced_https_ota_example_bluedroid_gatts(dut: Dut) -> None: @@ -628,29 +640,37 @@ def test_examples_protocol_advanced_https_ota_example_bluedroid_gatts(dut: Dut) server_port = 8001 # File to be downloaded. This file is generated after compilation bin_name = 'advanced_https_ota.bin' - # start test - dut.expect('Loaded app from partition at offset', timeout=30) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30)[1].decode() - print('Connected to AP with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') - # Start server - host_ip = get_my_ip4_by_dest_ip(ip_address) - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, '0.0.0.0', server_port)) thread1.daemon = True thread1.start() - try: + # start test + dut.expect('Loaded app from partition at offset', timeout=30) + # Parse IP address of STA + if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True: + env_name = 'wifi_high_traffic' + dut.expect('Please input ssid password:') + ap_ssid = get_env_config_variable(env_name, 'ap_ssid') + ap_password = get_env_config_variable(env_name, 'ap_password') + dut.write(f'{ap_ssid} {ap_password}') + try: + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + print('Connected to AP with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') + host_ip = get_host_ip4_by_dest_ip(ip_address) + dut.expect('Starting Advanced OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + bin_name)) dut.expect('Started advertising.', timeout=30) print('Started GAP advertising.') dut.write('https://' + host_ip + ':' + str(server_port) + '/' + bin_name) - dut.expect('Loaded app from partition at offset', timeout=60) - dut.expect('Starting Advanced OTA example', timeout=30) + dut.expect('upgrade successful. Rebooting ...', timeout=60) + # after reboot + dut.expect('Loaded app from partition at offset', timeout=30) + dut.expect('OTA example app_main start', timeout=10) finally: thread1.terminate() @@ -659,7 +679,7 @@ def test_examples_protocol_advanced_https_ota_example_bluedroid_gatts(dut: Dut) @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.ethernet_router +@pytest.mark.ethernet_ota def test_examples_protocol_advanced_https_ota_example_openssl_aligned_bin(dut: Dut) -> None: """ This is a test case for esp_http_client_read with binary size multiple of 289 bytes @@ -683,23 +703,25 @@ def test_examples_protocol_advanced_https_ota_example_openssl_aligned_bin(dut: D fo.write(f.read(bin_size)) for _ in range(dummy_data_size): fo.write(struct.pack('B', random.randrange(0,255,1))) - # start test - dut.expect('Loaded app from partition at offset', timeout=30) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30)[1].decode() - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') - # Start server - host_ip = get_my_ip4_by_dest_ip(ip_address) chunked_server = start_chunked_server(dut.app.binary_path, 8070) try: + # start test + dut.expect('Loaded app from partition at offset', timeout=30) + try: + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + host_ip = get_host_ip4_by_dest_ip(ip_address) + dut.expect('Starting Advanced OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':8070/' + aligned_bin_name)) dut.write('https://' + host_ip + ':8070/' + aligned_bin_name) - dut.expect('Loaded app from partition at offset', timeout=60) - dut.expect('Starting Advanced OTA example', timeout=30) + dut.expect('upgrade successful. Rebooting ...', timeout=60) + # after reboot + dut.expect('Loaded app from partition at offset', timeout=30) + dut.expect('OTA example app_main start', timeout=10) try: os.remove(aligned_bin_name) except OSError: diff --git a/examples/system/ota/advanced_https_ota/sdkconfig.ci.nimble b/examples/system/ota/advanced_https_ota/sdkconfig.ci.nimble index ce813f6cf2..1771a20999 100644 --- a/examples/system/ota/advanced_https_ota/sdkconfig.ci.nimble +++ b/examples/system/ota/advanced_https_ota/sdkconfig.ci.nimble @@ -11,6 +11,7 @@ CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_example_with_ble.csv" CONFIG_PARTITION_TABLE_FILENAME="partitions_example_with_ble.csv" +CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN=y CONFIG_EXAMPLE_FIRMWARE_UPGRADE_URL="FROM_STDIN" CONFIG_EXAMPLE_SKIP_COMMON_NAME_CHECK=y CONFIG_EXAMPLE_SKIP_VERSION_CHECK=y diff --git a/examples/system/ota/native_ota_example/main/native_ota_example.c b/examples/system/ota/native_ota_example/main/native_ota_example.c index 5e1d0f51d2..ebebbabd99 100644 --- a/examples/system/ota/native_ota_example/main/native_ota_example.c +++ b/examples/system/ota/native_ota_example/main/native_ota_example.c @@ -80,7 +80,7 @@ static void ota_example_task(void *pvParameter) esp_ota_handle_t update_handle = 0 ; const esp_partition_t *update_partition = NULL; - ESP_LOGI(TAG, "Starting OTA example"); + ESP_LOGI(TAG, "Starting OTA example task"); const esp_partition_t *configured = esp_ota_get_boot_partition(); const esp_partition_t *running = esp_ota_get_running_partition(); @@ -273,6 +273,8 @@ static bool diagnostic(void) void app_main(void) { + ESP_LOGI(TAG, "OTA example app_main start"); + uint8_t sha_256[HASH_LEN] = { 0 }; esp_partition_t partition; diff --git a/examples/system/ota/native_ota_example/pytest_native_ota.py b/examples/system/ota/native_ota_example/pytest_native_ota.py index 964f1b8194..ef684a2bde 100644 --- a/examples/system/ota/native_ota_example/pytest_native_ota.py +++ b/examples/system/ota/native_ota_example/pytest_native_ota.py @@ -12,7 +12,7 @@ from typing import Callable, Tuple import pexpect import pytest -from common_test_methods import get_my_ip4_by_dest_ip +from common_test_methods import get_host_ip4_by_dest_ip from pytest_embedded import Dut server_cert = '-----BEGIN CERTIFICATE-----\n' \ @@ -122,7 +122,7 @@ def start_chunked_server(ota_image_dir: str, server_port: int) -> subprocess.Pop @pytest.mark.supported_targets -@pytest.mark.ethernet_router +@pytest.mark.ethernet_ota def test_examples_protocol_native_ota_example(dut: Dut) -> None: """ This is a positive test case, which downloads complete binary file multiple number of times. @@ -137,29 +137,31 @@ def test_examples_protocol_native_ota_example(dut: Dut) -> None: iterations = 3 # File to be downloaded. This file is generated after compilation bin_name = 'native_ota.bin' - # start test - for _ in range(iterations): - dut.expect('Loaded app from partition at offset', timeout=60) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30)[1].decode() - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') - # Start server - host_ip = get_my_ip4_by_dest_ip(ip_address) - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) - thread1.daemon = True - thread1.start() - try: - dut.expect('Starting OTA example', timeout=30) + # Start server + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, '0.0.0.0', server_port)) + thread1.daemon = True + thread1.start() + try: + # start test + for _ in range(iterations): + dut.expect('Loaded app from partition at offset', timeout=30) + try: + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + host_ip = get_host_ip4_by_dest_ip(ip_address) + + dut.expect('Starting OTA example task', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + bin_name)) dut.write('https://' + host_ip + ':' + str(server_port) + '/' + bin_name) - finally: - thread1.terminate() + dut.expect('Prepare to restart system!', timeout=60) + finally: + thread1.terminate() @pytest.mark.supported_targets -@pytest.mark.ethernet_router +@pytest.mark.ethernet_ota def test_examples_protocol_native_ota_example_truncated_bin(dut: Dut) -> None: """ Working of OTA if binary file is truncated is validated in this test case. @@ -180,26 +182,26 @@ def test_examples_protocol_native_ota_example_truncated_bin(dut: Dut) -> None: truncated_bin_size = 64000 # check and log bin size binary_file = os.path.join(dut.app.binary_path, bin_name) - f = open(binary_file, 'rb+') - fo = open(os.path.join(dut.app.binary_path, truncated_bin_name), 'wb+') - fo.write(f.read(truncated_bin_size)) - fo.close() - f.close() + with open(binary_file, 'rb+') as fr: + bin_data = fr.read(truncated_bin_size) binary_file = os.path.join(dut.app.binary_path, truncated_bin_name) - # start test - dut.expect('Loaded app from partition at offset', timeout=30) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30)[1].decode() - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + with open(binary_file, 'wb+') as fo: + fo.write(bin_data) # Start server - host_ip = get_my_ip4_by_dest_ip(ip_address) - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, '0.0.0.0', server_port)) thread1.daemon = True thread1.start() try: - dut.expect('Starting OTA example', timeout=30) + # start test + dut.expect('Loaded app from partition at offset', timeout=30) + try: + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + host_ip = get_host_ip4_by_dest_ip(ip_address) + + dut.expect('Starting OTA example task', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + truncated_bin_name)) dut.write('https://' + host_ip + ':' + str(server_port) + '/' + truncated_bin_name) dut.expect('native_ota_example: Image validation failed, image is corrupted', timeout=20) @@ -209,7 +211,7 @@ def test_examples_protocol_native_ota_example_truncated_bin(dut: Dut) -> None: @pytest.mark.supported_targets -@pytest.mark.ethernet_router +@pytest.mark.ethernet_ota def test_examples_protocol_native_ota_example_truncated_header(dut: Dut) -> None: """ Working of OTA if headers of binary file are truncated is vaildated in this test case. @@ -229,26 +231,26 @@ def test_examples_protocol_native_ota_example_truncated_header(dut: Dut) -> None truncated_bin_size = 180 # check and log bin size binary_file = os.path.join(dut.app.binary_path, bin_name) - f = open(binary_file, 'rb+') - fo = open(os.path.join(dut.app.binary_path, truncated_bin_name), 'wb+') - fo.write(f.read(truncated_bin_size)) - fo.close() - f.close() + with open(binary_file, 'rb+') as fr: + bin_data = fr.read(truncated_bin_size) binary_file = os.path.join(dut.app.binary_path, truncated_bin_name) - # start test - dut.expect('Loaded app from partition at offset', timeout=30) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30)[1].decode() - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + with open(binary_file, 'wb+') as fo: + fo.write(bin_data) # Start server - host_ip = get_my_ip4_by_dest_ip(ip_address) - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, '0.0.0.0', server_port)) thread1.daemon = True thread1.start() try: - dut.expect('Starting OTA example', timeout=30) + # start test + dut.expect('Loaded app from partition at offset', timeout=30) + try: + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + host_ip = get_host_ip4_by_dest_ip(ip_address) + + dut.expect('Starting OTA example task', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + truncated_bin_name)) dut.write('https://' + host_ip + ':' + str(server_port) + '/' + truncated_bin_name) dut.expect('native_ota_example: received package is not fit len', timeout=20) @@ -258,7 +260,7 @@ def test_examples_protocol_native_ota_example_truncated_header(dut: Dut) -> None @pytest.mark.supported_targets -@pytest.mark.ethernet_router +@pytest.mark.ethernet_ota def test_examples_protocol_native_ota_example_random(dut: Dut) -> None: """ Working of OTA if random data is added in binary file are validated in this test case. @@ -279,25 +281,25 @@ def test_examples_protocol_native_ota_example_random(dut: Dut) -> None: fo = open(binary_file, 'wb+') # First byte of binary file is always set to zero. If first byte is generated randomly, # in some cases it may generate 0xE9 which will result in failure of testcase. - fo.write(struct.pack('B', 0)) - for i in range(random_bin_size - 1): - fo.write(struct.pack('B', random.randrange(0,255,1))) - fo.close() - # start test - dut.expect('Loaded app from partition at offset', timeout=30) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30)[1].decode() - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + with open(binary_file, 'wb+') as fo: + fo.write(struct.pack('B', 0)) + for _ in range(random_bin_size - 1): + fo.write(struct.pack('B', random.randrange(0,255,1))) # Start server - host_ip = get_my_ip4_by_dest_ip(ip_address) - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, '0.0.0.0', server_port)) thread1.daemon = True thread1.start() - try: - dut.expect('Starting OTA example', timeout=30) + # start test + dut.expect('Loaded app from partition at offset', timeout=30) + try: + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + host_ip = get_host_ip4_by_dest_ip(ip_address) + + dut.expect('Starting OTA example task', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + random_bin_name)) dut.write('https://' + host_ip + ':' + str(server_port) + '/' + random_bin_name) dut.expect('esp_ota_ops: OTA image has invalid magic byte', timeout=20) @@ -307,7 +309,7 @@ def test_examples_protocol_native_ota_example_random(dut: Dut) -> None: @pytest.mark.supported_targets -@pytest.mark.ethernet_router +@pytest.mark.ethernet_ota def test_examples_protocol_native_ota_example_chunked(dut: Dut) -> None: """ This is a positive test case, which downloads complete binary file multiple number of times. @@ -319,22 +321,25 @@ def test_examples_protocol_native_ota_example_chunked(dut: Dut) -> None: """ # File to be downloaded. This file is generated after compilation bin_name = 'native_ota.bin' - # start test - dut.expect('Loaded app from partition at offset', timeout=30) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30)[1].decode() - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') # Start server - host_ip = get_my_ip4_by_dest_ip(ip_address) chunked_server = start_chunked_server(dut.app.binary_path, 8070) try: - dut.expect('Starting OTA example', timeout=30) + # start test + dut.expect('Loaded app from partition at offset', timeout=30) + try: + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + host_ip = get_host_ip4_by_dest_ip(ip_address) + + dut.expect('Starting OTA example task', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':8070/' + bin_name)) dut.write('https://' + host_ip + ':8070/' + bin_name) - dut.expect('Loaded app from partition at offset', timeout=60) - dut.expect('Starting OTA example', timeout=30) + dut.expect('Prepare to restart system!', timeout=60) + # after reboot + dut.expect('Loaded app from partition at offset', timeout=30) + dut.expect('OTA example app_main start', timeout=10) os.remove(os.path.join(dut.app.binary_path, 'server_cert.pem')) os.remove(os.path.join(dut.app.binary_path, 'server_key.pem')) finally: diff --git a/examples/system/ota/pre_encrypted_ota/pytest_pre_encrypted_ota.py b/examples/system/ota/pre_encrypted_ota/pytest_pre_encrypted_ota.py index 559c0dc733..9f2ef24780 100644 --- a/examples/system/ota/pre_encrypted_ota/pytest_pre_encrypted_ota.py +++ b/examples/system/ota/pre_encrypted_ota/pytest_pre_encrypted_ota.py @@ -9,7 +9,7 @@ from typing import Callable import pexpect import pytest -from common_test_methods import get_my_ip4_by_dest_ip +from common_test_methods import get_host_ip4_by_dest_ip from pytest_embedded import Dut from RangeHTTPServer import RangeRequestHandler @@ -56,28 +56,29 @@ def start_https_server(ota_image_dir: str, server_ip: str, server_port: int) -> @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.ethernet_router +@pytest.mark.ethernet_ota def test_examples_protocol_pre_encrypted_ota_example(dut: Dut) -> None: server_port = 8001 - dut.expect('Loaded app from partition at offset', timeout=30) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') # Start server - host_ip = get_my_ip4_by_dest_ip(ip_address) - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, server_port)) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, '0.0.0.0', server_port)) thread1.daemon = True thread1.start() - try: + dut.expect('Loaded app from partition at offset', timeout=30) + try: + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + host_ip = get_host_ip4_by_dest_ip(ip_address) + dut.expect('Starting Pre Encrypted OTA example', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + enc_bin_name)) dut.write('https://' + host_ip + ':' + str(server_port) + '/' + enc_bin_name) dut.expect('Magic Verified', timeout=30) dut.expect('Reading RSA private key', timeout=30) dut.expect('upgrade successful. Rebooting', timeout=30) + # after reboot + dut.expect('Loaded app from partition at offset', timeout=30) finally: thread1.terminate() diff --git a/examples/system/ota/simple_ota_example/main/simple_ota_example.c b/examples/system/ota/simple_ota_example/main/simple_ota_example.c index 6b030ef7ec..e3e8c732cb 100644 --- a/examples/system/ota/simple_ota_example/main/simple_ota_example.c +++ b/examples/system/ota/simple_ota_example/main/simple_ota_example.c @@ -78,7 +78,7 @@ esp_err_t _http_event_handler(esp_http_client_event_t *evt) void simple_ota_example_task(void *pvParameter) { - ESP_LOGI(TAG, "Starting OTA example"); + ESP_LOGI(TAG, "Starting OTA example task"); #ifdef CONFIG_EXAMPLE_FIRMWARE_UPGRADE_BIND_IF esp_netif_t *netif = get_example_netif_from_desc(bind_interface_name); if (netif == NULL) { @@ -127,6 +127,7 @@ void simple_ota_example_task(void *pvParameter) ESP_LOGI(TAG, "Attempting to download update from %s", config.url); esp_err_t ret = esp_https_ota(&ota_config); if (ret == ESP_OK) { + ESP_LOGI(TAG, "OTA Succeed, Rebooting..."); esp_restart(); } else { ESP_LOGE(TAG, "Firmware upgrade failed"); @@ -165,6 +166,7 @@ static void get_sha256_of_partitions(void) void app_main(void) { + ESP_LOGI(TAG, "OTA example app_main start"); // Initialize NVS. esp_err_t err = nvs_flash_init(); if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) { diff --git a/examples/system/ota/simple_ota_example/pytest_simple_ota.py b/examples/system/ota/simple_ota_example/pytest_simple_ota.py index d2a1c04611..5d3386c485 100644 --- a/examples/system/ota/simple_ota_example/pytest_simple_ota.py +++ b/examples/system/ota/simple_ota_example/pytest_simple_ota.py @@ -3,14 +3,13 @@ import http.server import multiprocessing import os -import socket import ssl import sys from typing import Tuple import pexpect import pytest -from common_test_methods import get_my_ip4_by_dest_ip +from common_test_methods import get_env_config_variable, get_host_ip4_by_dest_ip from pytest_embedded import Dut server_cert = '-----BEGIN CERTIFICATE-----\n' \ @@ -110,8 +109,7 @@ def calc_all_sha256(dut: Dut) -> Tuple[str, str]: @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.wifi_ota -@pytest.mark.nightly_run +@pytest.mark.wifi_high_traffic def test_examples_protocol_simple_ota_example(dut: Dut) -> None: """ steps: | @@ -120,27 +118,36 @@ def test_examples_protocol_simple_ota_example(dut: Dut) -> None: 3. Reboot with the new OTA image """ sha256_bootloader, sha256_app = calc_all_sha256(dut) - # start test - dut.expect('Loaded app from partition at offset 0x10000', timeout=30) - check_sha256(sha256_bootloader, str(dut.expect(r'SHA-256 for bootloader:\s+([a-f0-9]){64}')[0])) - check_sha256(sha256_app, str(dut.expect(r'SHA-256 for current firmware:\s+([a-f0-9]){64}')[0])) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') # Start server - host_ip = get_my_ip4_by_dest_ip(ip_address) - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, 8000)) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, '0.0.0.0', 8000)) thread1.daemon = True thread1.start() try: - dut.expect('Starting OTA example', timeout=30) + # start test + dut.expect('Loaded app from partition at offset 0x10000', timeout=30) + check_sha256(sha256_bootloader, str(dut.expect(r'SHA-256 for bootloader:\s+([a-f0-9]){64}')[0])) + check_sha256(sha256_app, str(dut.expect(r'SHA-256 for current firmware:\s+([a-f0-9]){64}')[0])) + # Parse IP address of STA + if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True: + env_name = 'wifi_high_traffic' + dut.expect('Please input ssid password:') + ap_ssid = get_env_config_variable(env_name, 'ap_ssid') + ap_password = get_env_config_variable(env_name, 'ap_password') + dut.write(f'{ap_ssid} {ap_password}') + try: + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + host_ip = get_host_ip4_by_dest_ip(ip_address) + + dut.expect('Starting OTA example task', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':8000/simple_ota.bin')) dut.write('https://' + host_ip + ':8000/simple_ota.bin') - dut.expect('Loaded app from partition at offset 0x110000', timeout=60) - dut.expect('Starting OTA example', timeout=30) + dut.expect('OTA Succeed, Rebooting...', timeout=60) + # after reboot + dut.expect('Loaded app from partition at offset 0x110000', timeout=30) + dut.expect('OTA example app_main start', timeout=10) finally: thread1.terminate() @@ -149,7 +156,7 @@ def test_examples_protocol_simple_ota_example(dut: Dut) -> None: @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.ethernet_router +@pytest.mark.ethernet_ota @pytest.mark.parametrize('config', ['spiram',], indirect=True) def test_examples_protocol_simple_ota_example_ethernet_with_spiram_config(dut: Dut) -> None: """ @@ -158,73 +165,34 @@ def test_examples_protocol_simple_ota_example_ethernet_with_spiram_config(dut: D 2. Fetch OTA image over HTTPS 3. Reboot with the new OTA image """ - # start test - dut.expect('Loaded app from partition at offset 0x10000', timeout=30)) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') # Start server - host_ip = get_my_ip4_by_dest_ip(ip_address) - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, 8000)) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, '0.0.0.0', 8000)) thread1.daemon = True thread1.start() try: - dut.expect('Starting OTA example', timeout=30) + # start test + dut.expect('Loaded app from partition at offset 0x10000', timeout=30) + try: + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + host_ip = get_host_ip4_by_dest_ip(ip_address) + + dut.expect('Starting OTA example task', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':8000/simple_ota.bin')) dut.write('https://' + host_ip + ':8000/simple_ota.bin') - dut.expect('Loaded app from partition at offset 0x110000', timeout=60) - dut.expect('Starting OTA example', timeout=30) + dut.expect('OTA Succeed, Rebooting...', timeout=60) + # after reboot + dut.expect('Loaded app from partition at offset 0x110000', timeout=30) + dut.expect('OTA example app_main start', timeout=10) finally: thread1.terminate() @pytest.mark.esp32 @pytest.mark.esp32c3 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.flash_encryption_ota -@pytest.mark.parametrize('config', ['flash_enc',], indirect=True) -@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True) -def test_examples_protocol_simple_ota_example_with_flash_encryption(dut: Dut) -> None: - """ - steps: | - 1. join AP/Ethernet - 2. Fetch OTA image over HTTPS - 3. Reboot with the new OTA image - """ - # Erase flash - dut.serial.erase_flash() - dut.serial.flash() - # start test - dut.expect('Loaded app from partition at offset 0x20000', timeout=30) - dut.expect('Flash encryption mode is DEVELOPMENT', timeout=10) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') - # Start server - host_ip = get_my_ip4_by_dest_ip(ip_address) - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, 8000)) - thread1.daemon = True - thread1.start() - try: - dut.expect('Starting OTA example', timeout=30) - print('writing to device: {}'.format('https://' + host_ip + ':8000/simple_ota.bin')) - dut.write('https://' + host_ip + ':8000/simple_ota.bin') - dut.expect('Loaded app from partition at offset 0x120000', timeout=60) - dut.expect('Flash encryption mode is DEVELOPMENT', timeout=10) - dut.expect('Starting OTA example', timeout=30) - finally: - thread1.terminate() - - -@pytest.mark.esp32c3 -@pytest.mark.flash_encryption_wifi_ota +@pytest.mark.flash_encryption_wifi_high_traffic @pytest.mark.nightly_run @pytest.mark.parametrize('config', ['flash_enc_wifi',], indirect=True) @pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True) @@ -239,26 +207,35 @@ def test_examples_protocol_simple_ota_example_with_flash_encryption_wifi(dut: Du # Erase flash dut.serial.erase_flash() dut.serial.flash() - dut.expect('Loaded app from partition at offset 0x20000', timeout=30) - dut.expect('Flash encryption mode is DEVELOPMENT', timeout=10) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') # Start server - host_ip = get_my_ip4_by_dest_ip(ip_address) - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, 8000)) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, '0.0.0.0', 8000)) thread1.daemon = True thread1.start() try: - dut.expect('Starting OTA example', timeout=30) + dut.expect('Loaded app from partition at offset 0x20000', timeout=30) + dut.expect('Flash encryption mode is DEVELOPMENT', timeout=10) + # Parse IP address of STA + if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True: + env_name = 'flash_encryption_wifi_high_traffic' + dut.expect('Please input ssid password:') + ap_ssid = get_env_config_variable(env_name, 'ap_ssid') + ap_password = get_env_config_variable(env_name, 'ap_password') + dut.write(f'{ap_ssid} {ap_password}') + try: + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + host_ip = get_host_ip4_by_dest_ip(ip_address) + + dut.expect('Starting OTA example task', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':8000/simple_ota.bin')) dut.write('https://' + host_ip + ':8000/simple_ota.bin') - dut.expect('Loaded app from partition at offset 0x120000', timeout=60) + dut.expect('OTA Succeed, Rebooting...', timeout=60) + # after reboot + dut.expect('Loaded app from partition at offset 0x120000', timeout=30) dut.expect('Flash encryption mode is DEVELOPMENT', timeout=10) - dut.expect('Starting OTA example', timeout=30) + dut.expect('OTA example app_main start', timeout=10) finally: thread1.terminate() @@ -267,7 +244,7 @@ def test_examples_protocol_simple_ota_example_with_flash_encryption_wifi(dut: Du @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.ethernet_router +@pytest.mark.ethernet_ota @pytest.mark.parametrize('config', ['on_update_no_sb_ecdsa',], indirect=True) def test_examples_protocol_simple_ota_example_with_verify_app_signature_on_update_no_secure_boot_ecdsa(dut: Dut) -> None: """ @@ -277,30 +254,31 @@ def test_examples_protocol_simple_ota_example_with_verify_app_signature_on_updat 3. Reboot with the new OTA image """ sha256_bootloader, sha256_app = calc_all_sha256(dut) - # start test - dut.expect('Loaded app from partition at offset 0x20000', timeout=30) - check_sha256(sha256_bootloader, str(dut.expect(r'SHA-256 for bootloader:\s+([a-f0-9]){64}')[0])) - check_sha256(sha256_app, str(dut.expect(r'SHA-256 for current firmware:\s+([a-f0-9]){64}')[0])) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') # Start server - host_ip = get_my_ip4_by_dest_ip(ip_address) - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, 8000)) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, '0.0.0.0', 8000)) thread1.daemon = True thread1.start() - try: - dut.expect('Starting OTA example', timeout=30) + # start test + dut.expect('Loaded app from partition at offset 0x20000', timeout=30) + check_sha256(sha256_bootloader, str(dut.expect(r'SHA-256 for bootloader:\s+([a-f0-9]){64}')[0])) + check_sha256(sha256_app, str(dut.expect(r'SHA-256 for current firmware:\s+([a-f0-9]){64}')[0])) + try: + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + host_ip = get_host_ip4_by_dest_ip(ip_address) + + dut.expect('Starting OTA example task', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':8000/simple_ota.bin')) dut.write('https://' + host_ip + ':8000/simple_ota.bin') dut.expect('Writing to partition subtype 16 at offset 0x120000', timeout=20) dut.expect('Verifying image signature...', timeout=60) + dut.expect('OTA Succeed, Rebooting...', timeout=60) + # after reboot dut.expect('Loaded app from partition at offset 0x120000', timeout=20) - dut.expect('Starting OTA example', timeout=30) + dut.expect('OTA example app_main start', timeout=10) finally: thread1.terminate() @@ -309,7 +287,7 @@ def test_examples_protocol_simple_ota_example_with_verify_app_signature_on_updat @pytest.mark.esp32c3 @pytest.mark.esp32s2 @pytest.mark.esp32s3 -@pytest.mark.ethernet_router +@pytest.mark.ethernet_ota @pytest.mark.parametrize('config', ['on_update_no_sb_rsa',], indirect=True) def test_examples_protocol_simple_ota_example_with_verify_app_signature_on_update_no_secure_boot_rsa(dut: Dut) -> None: """ @@ -319,35 +297,34 @@ def test_examples_protocol_simple_ota_example_with_verify_app_signature_on_updat 3. Reboot with the new OTA image """ sha256_bootloader, sha256_app = calc_all_sha256(dut) - # start test - dut.expect('Loaded app from partition at offset 0x20000', timeout=30) - check_sha256(sha256_bootloader, str(dut.expect(r'SHA-256 for bootloader:\s+([a-f0-9]){64}')[0])) - check_sha256(sha256_app, str(dut.expect(r'SHA-256 for current firmware:\s+([a-f0-9]){64}')[0])) - try: - ip_address = dut.expect(r'IPv4 address: ([^,]+),', timeout=30) - print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) - except pexpect.exceptions.TIMEOUT: - thread1.terminate() - raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') # Start server - host_ip = get_my_ip4_by_dest_ip(ip_address) - thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, host_ip, 8000)) + thread1 = multiprocessing.Process(target=start_https_server, args=(dut.app.binary_path, '0.0.0.0', 8000)) thread1.daemon = True thread1.start() - try: - dut.expect('Starting OTA example', timeout=30) + # start test + dut.expect('Loaded app from partition at offset 0x20000', timeout=30) + check_sha256(sha256_bootloader, str(dut.expect(r'SHA-256 for bootloader:\s+([a-f0-9]){64}')[0])) + check_sha256(sha256_app, str(dut.expect(r'SHA-256 for current firmware:\s+([a-f0-9]){64}')[0])) + try: + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) + except pexpect.exceptions.TIMEOUT: + raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') + host_ip = get_host_ip4_by_dest_ip(ip_address) + + dut.expect('Starting OTA example task', timeout=30) print('writing to device: {}'.format('https://' + host_ip + ':8000/simple_ota.bin')) dut.write('https://' + host_ip + ':8000/simple_ota.bin') dut.expect('Writing to partition subtype 16 at offset 0x120000', timeout=20) - dut.expect('Verifying image signature...', timeout=60) dut.expect('#0 app key digest == #0 trusted key digest', timeout=10) dut.expect('Verifying with RSA-PSS...', timeout=10) dut.expect('Signature verified successfully!', timeout=10) - + dut.expect('OTA Succeed, Rebooting...', timeout=60) + # after reboot dut.expect('Loaded app from partition at offset 0x120000', timeout=20) - dut.expect('Starting OTA example', timeout=30) + dut.expect('OTA example app_main start', timeout=10) finally: thread1.terminate() diff --git a/examples/system/ota/simple_ota_example/sdkconfig.ci b/examples/system/ota/simple_ota_example/sdkconfig.ci index 0570a134c8..ff83e7ffe8 100644 --- a/examples/system/ota/simple_ota_example/sdkconfig.ci +++ b/examples/system/ota/simple_ota_example/sdkconfig.ci @@ -1,3 +1,4 @@ +CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN=y CONFIG_EXAMPLE_FIRMWARE_UPGRADE_URL="FROM_STDIN" CONFIG_EXAMPLE_SKIP_COMMON_NAME_CHECK=y CONFIG_EXAMPLE_FIRMWARE_UPGRADE_BIND_IF=y diff --git a/examples/system/ota/simple_ota_example/sdkconfig.ci.flash_enc b/examples/system/ota/simple_ota_example/sdkconfig.ci.flash_enc deleted file mode 100644 index 9080772536..0000000000 --- a/examples/system/ota/simple_ota_example/sdkconfig.ci.flash_enc +++ /dev/null @@ -1,25 +0,0 @@ -CONFIG_EXAMPLE_FIRMWARE_UPGRADE_URL="FROM_STDIN" -CONFIG_EXAMPLE_SKIP_COMMON_NAME_CHECK=y -CONFIG_SECURE_FLASH_ENC_ENABLED=y -CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT=y -CONFIG_SECURE_BOOT_ALLOW_ROM_BASIC=y -CONFIG_SECURE_BOOT_ALLOW_JTAG=y -CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC=y -CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_DEC=y -CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE=y -CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED=y -CONFIG_PARTITION_TABLE_OFFSET=0x9000 -CONFIG_EXAMPLE_CONNECT_ETHERNET=y -CONFIG_EXAMPLE_CONNECT_WIFI=n -CONFIG_EXAMPLE_USE_INTERNAL_ETHERNET=y -CONFIG_EXAMPLE_ETH_PHY_IP101=y -CONFIG_EXAMPLE_ETH_MDC_GPIO=23 -CONFIG_EXAMPLE_ETH_MDIO_GPIO=18 -CONFIG_EXAMPLE_ETH_PHY_RST_GPIO=5 -CONFIG_EXAMPLE_ETH_PHY_ADDR=1 -# This is required for nvs encryption (which is enabled by default with flash encryption) -CONFIG_PARTITION_TABLE_TWO_OTA_ENCRYPTED_NVS=y - -CONFIG_MBEDTLS_TLS_CLIENT_ONLY=y -CONFIG_COMPILER_OPTIMIZATION_SIZE=y -CONFIG_EXAMPLE_CONNECT_IPV6=n diff --git a/examples/system/ota/simple_ota_example/sdkconfig.ci.flash_enc_wifi b/examples/system/ota/simple_ota_example/sdkconfig.ci.flash_enc_wifi index cfd62a636f..d4fba8c002 100644 --- a/examples/system/ota/simple_ota_example/sdkconfig.ci.flash_enc_wifi +++ b/examples/system/ota/simple_ota_example/sdkconfig.ci.flash_enc_wifi @@ -11,5 +11,10 @@ CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED=y CONFIG_PARTITION_TABLE_OFFSET=0x9000 CONFIG_EXAMPLE_CONNECT_ETHERNET=n CONFIG_EXAMPLE_CONNECT_WIFI=y +CONFIG_EXAMPLE_WIFI_SSID_PWD_FROM_STDIN=y # This is required for nvs encryption (which is enabled by default with flash encryption) CONFIG_PARTITION_TABLE_TWO_OTA_ENCRYPTED_NVS=y + +CONFIG_MBEDTLS_TLS_CLIENT_ONLY=y +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_EXAMPLE_CONNECT_IPV6=n diff --git a/pytest.ini b/pytest.ini index 2ca3960681..0e31e46f8f 100644 --- a/pytest.ini +++ b/pytest.ini @@ -36,16 +36,16 @@ markers = quad_psram: runners with quad psram octal_psram: runners with octal psram usb_host: usb host runners + ethernet_ota: ethernet OTA runners flash_encryption: Flash Encryption runners ir_transceiver: runners with a pair of IR transmitter and receiver - wifi_ota: wifi OTA runners - flash_encryption_ota: flash encryprion ota ethernet runner - flash_encryption_wifi_ota: flash encryprion ota wifi runner + flash_encryption_wifi_high_traffic: Flash Encryption runners with wifi high traffic support ethernet: ethernet runner ethernet_flash_8m: ethernet runner with 8mb flash - ethernet_router: both the runner and dut connect to the same router - wifi_nearby: runner with a wifi AP nearby - wifi_router: runner can connect to the dut by a wifi router + ethernet_router: both the runner and dut connect to the same router through ethernet NIC + wifi_ap: a wifi AP in the environment + wifi_router: both the runner and dut connect to the same wifi router + wifi_high_traffic: wifi high traffic runners wifi_wlan: wifi runner with a wireless NIC deepsleep_temp_tag: temporary env for running potentially harmfull deepsleep related tests diff --git a/tools/ci/python_packages/common_test_methods.py b/tools/ci/python_packages/common_test_methods.py index 6540dc2990..85ace23373 100644 --- a/tools/ci/python_packages/common_test_methods.py +++ b/tools/ci/python_packages/common_test_methods.py @@ -4,6 +4,7 @@ import logging import os import socket +from typing import Any import netifaces import yaml @@ -12,43 +13,40 @@ ENV_CONFIG_FILE_SEARCH = [ os.path.join(os.environ['IDF_PATH'], 'EnvConfig.yml'), os.path.join(os.environ['IDF_PATH'], 'ci-test-runner-configs', os.environ.get('CI_RUNNER_DESCRIPTION', ''), 'EnvConfig.yml'), ] +ENV_CONFIG_TEMPLATE = ''' +$IDF_PATH/EnvConfig.yml: + ```yaml + : + key: var + key2: var2 + : + key: var + ``` +''' -def get_my_ip_by_interface(interface_name: str, ip_type: int = netifaces.AF_INET) -> str: - for i in netifaces.ifaddresses(interface_name)[ip_type]: - interface_name = i['addr'].replace('%{}'.format(interface_name), '') - assert isinstance(interface_name, str) - return interface_name +def get_host_ip_by_interface(interface_name: str, ip_type: int = netifaces.AF_INET) -> str: + for _addr in netifaces.ifaddresses(interface_name)[ip_type]: + host_ip = _addr['addr'].replace('%{}'.format(interface_name), '') + assert isinstance(host_ip, str) + return host_ip return '' -def get_my_ip4_by_getway(getway: str = '') -> str: - getways = netifaces.gateways() - for gw, iface_name, _ in getways[netifaces.AF_INET]: - if gw and gw == getway: - interface = iface_name - break - else: - interface = getways['default'][netifaces.AF_INET][1] - logging.debug('Using interface: {}.'.format(interface)) - address = netifaces.ifaddresses(interface)[netifaces.AF_INET] - assert isinstance(address[0]['addr'], str) - return address[0]['addr'] - - -def get_my_ip4_by_dest_ip(dest_ip: str = '') -> str: +def get_host_ip4_by_dest_ip(dest_ip: str = '') -> str: if not dest_ip: dest_ip = '8.8.8.8' s1 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s1.connect((dest_ip, 80)) - my_ip = s1.getsockname()[0] + host_ip = s1.getsockname()[0] s1.close() - assert isinstance(my_ip, str) - return my_ip + assert isinstance(host_ip, str) + print(f'Using host ip: {host_ip}') + return host_ip def get_my_interface_by_dest_ip(dest_ip: str = '') -> str: - my_ip = get_my_ip4_by_dest_ip(dest_ip) + my_ip = get_host_ip4_by_dest_ip(dest_ip) interfaces = netifaces.interfaces() for interface in interfaces: try: @@ -62,22 +60,39 @@ def get_my_interface_by_dest_ip(dest_ip: str = '') -> str: return '' -def get_env_config(env_key: str = '', config_file: str = '') -> dict: - if not config_file: - for _file in ENV_CONFIG_FILE_SEARCH: - if os.path.exists(_file): - config_file = _file - if not config_file: - return dict() +def get_env_config_variable(env_name: str, key: str, default: Any = None) -> Any: + """ + Get test environment related variable - with open(config_file, 'r') as f: - config = yaml.load(f.read(), Loader=yaml.SafeLoader) - assert isinstance(config, dict) - if not env_key: - return config - if env_key in config: - _config = config[env_key] - assert isinstance(_config, dict) - return _config - logging.warning('Can not get env config, key: {}'.format(env_key)) - return dict() + config file format: $IDF_PATH/EnvConfig.yml + ``` + : + key: var + key2: var2 + : + key: var + ``` + """ + config = dict() + for _file in ENV_CONFIG_FILE_SEARCH: + try: + with open(_file, 'r') as f: + data = yaml.load(f.read(), Loader=yaml.SafeLoader) + config = data[env_name] + break + except (FileNotFoundError, KeyError): + pass + else: + pass + + var = config.get(key, default) + if var is None: + logging.warning(f'Failed to get env variable {env_name}/{key}.') + logging.info(f'Env config file template: {ENV_CONFIG_TEMPLATE}') + if not os.environ.get('CI_JOB_ID'): + # Try to get variable from stdin + var = input(f'You can input the variable now:') + else: + raise ValueError(f'Env variable not found: {env_name}/{key}') + logging.debug(f'Got env variable {env_name}/{key}: {var}') + return var diff --git a/tools/test_apps/protocols/mqtt/publish_connect_test/app_test.py b/tools/test_apps/protocols/mqtt/publish_connect_test/app_test.py index 2e99d02294..0b30d06a46 100644 --- a/tools/test_apps/protocols/mqtt/publish_connect_test/app_test.py +++ b/tools/test_apps/protocols/mqtt/publish_connect_test/app_test.py @@ -15,7 +15,7 @@ from threading import Event, Lock, Thread import paho.mqtt.client as mqtt import ttfw_idf -from common_test_methods import get_my_ip4_by_dest_ip +from common_test_methods import get_host_ip4_by_dest_ip DEFAULT_MSG_SIZE = 16 @@ -236,7 +236,7 @@ class TlsServer: def connection_tests(dut, cases, dut_ip): - ip = get_my_ip4_by_dest_ip(dut_ip) + ip = get_host_ip4_by_dest_ip(dut_ip) set_server_cert_cn(ip) server_port = 2222 @@ -336,7 +336,7 @@ def test_app_protocol_mqtt_publish_connect(env, extra_data): raise dut1.start_app() - esp_ip = dut1.expect(re.compile(r' IPv4 address: ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)'), timeout=30)[0] + esp_ip = dut1.expect(re.compile(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)'), timeout=30)[0] print('Got IP={}'.format(esp_ip)) if not os.getenv('MQTT_SKIP_CONNECT_TEST'): From f7981d87600740023708f540374f7ee56e95facc Mon Sep 17 00:00:00 2001 From: Chen Yudong Date: Thu, 14 Jul 2022 13:17:39 +0800 Subject: [PATCH 09/10] ci: add python_package for running pytest locally --- conftest.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/conftest.py b/conftest.py index 37f2908ddb..ff9881b41e 100644 --- a/conftest.py +++ b/conftest.py @@ -33,6 +33,13 @@ from pytest_embedded.plugin import multi_dut_argument, multi_dut_fixture from pytest_embedded.utils import find_by_suffix from pytest_embedded_idf.dut import IdfDut +try: + import common_test_methods # noqa: F401 +except ImportError: + sys.path.append(os.path.join(os.path.dirname(__file__), 'tools', 'ci', 'python_packages')) + import common_test_methods # noqa: F401 + + SUPPORTED_TARGETS = ['esp32', 'esp32s2', 'esp32c3', 'esp32s3', 'esp32c2'] PREVIEW_TARGETS = ['linux', 'esp32h2'] DEFAULT_SDKCONFIG = 'default' From d54e1e8379b1907586061057ce78491bfe5d4703 Mon Sep 17 00:00:00 2001 From: Chen Yudong Date: Thu, 14 Jul 2022 22:55:50 +0800 Subject: [PATCH 10/10] CI: make sure that reading of the ipv4 address has finished --- .../esp_local_ctrl/pytest_esp_local_ctrl.py | 2 +- .../pytest_http_server_advanced.py | 2 +- .../pytest_http_server_file_serving.py | 2 +- .../pytest_http_server_persistence.py | 2 +- .../simple/pytest_http_server_simple.py | 4 +-- .../pytest_ws_server_example.py | 2 +- .../https_request/pytest_https_request.py | 6 ++--- .../simple/pytest_https_server_simple.py | 8 +++--- .../wss_server/pytest_https_wss_server.py | 2 +- .../pytest_https_x509_bundle.py | 4 +-- .../mqtt/ssl/mqtt_ssl_example_test.py | 2 +- .../mqtt/tcp/mqtt_tcp_example_test.py | 2 +- .../protocols/mqtt/ws/mqtt_ws_example_test.py | 2 +- .../mqtt/wss/mqtt_wss_example_test.py | 2 +- .../sockets/tcp_client/example_test.py | 2 +- .../sockets/tcp_server/example_test.py | 2 +- .../sockets/udp_client/example_test.py | 2 +- .../sockets/udp_server/example_test.py | 2 +- .../advanced_https_ota/pytest_advanced_ota.py | 26 +++++++++---------- .../native_ota_example/pytest_native_ota.py | 10 +++---- .../pytest_pre_encrypted_ota.py | 2 +- .../simple_ota_example/pytest_simple_ota.py | 10 +++---- .../mqtt/publish_connect_test/app_test.py | 2 +- 23 files changed, 50 insertions(+), 50 deletions(-) diff --git a/examples/protocols/esp_local_ctrl/pytest_esp_local_ctrl.py b/examples/protocols/esp_local_ctrl/pytest_esp_local_ctrl.py index 805f5e23cc..d499111c86 100644 --- a/examples/protocols/esp_local_ctrl/pytest_esp_local_ctrl.py +++ b/examples/protocols/esp_local_ctrl/pytest_esp_local_ctrl.py @@ -52,7 +52,7 @@ def test_examples_esp_local_ctrl(dut: Dut) -> None: ap_ssid = get_env_config_variable(env_name, 'ap_ssid') ap_password = get_env_config_variable(env_name, 'ap_password') dut.write(f'{ap_ssid} {ap_password}') - dut_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)')[1].decode() + dut_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]')[1].decode() dut.expect('esp_https_server: Starting server') dut.expect('esp_https_server: Server listening on port 443') dut.expect('control: esp_local_ctrl service started with name : my_esp_ctrl_device') diff --git a/examples/protocols/http_server/advanced_tests/pytest_http_server_advanced.py b/examples/protocols/http_server/advanced_tests/pytest_http_server_advanced.py index a74947c641..65e8fabb23 100644 --- a/examples/protocols/http_server/advanced_tests/pytest_http_server_advanced.py +++ b/examples/protocols/http_server/advanced_tests/pytest_http_server_advanced.py @@ -54,7 +54,7 @@ def test_examples_protocol_http_server_advanced(dut: Dut) -> None: ap_ssid = get_env_config_variable(env_name, 'ap_ssid') ap_password = get_env_config_variable(env_name, 'ap_password') dut.write(f'{ap_ssid} {ap_password}') - got_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + got_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode() got_port = dut.expect(r"(?:[\s\S]*)Started HTTP server on port: '(\d+)'", timeout=30)[1].decode() diff --git a/examples/protocols/http_server/file_serving/pytest_http_server_file_serving.py b/examples/protocols/http_server/file_serving/pytest_http_server_file_serving.py index cc96cf93c6..ce89f3877f 100644 --- a/examples/protocols/http_server/file_serving/pytest_http_server_file_serving.py +++ b/examples/protocols/http_server/file_serving/pytest_http_server_file_serving.py @@ -38,7 +38,7 @@ def test_examples_protocol_http_server_file_serving(dut: Dut) -> None: dut.expect('Initializing SPIFFS', timeout=30) # Parse IP address of STA logging.info('Waiting to connect with AP') - got_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + got_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode() # Expected logs got_port = dut.expect(r"Starting HTTP Server on port: '(\d+)'", timeout=30)[1].decode() logging.info('Got IP : {}'.format(got_ip)) diff --git a/examples/protocols/http_server/persistent_sockets/pytest_http_server_persistence.py b/examples/protocols/http_server/persistent_sockets/pytest_http_server_persistence.py index 131492ed09..ac8b3febc3 100644 --- a/examples/protocols/http_server/persistent_sockets/pytest_http_server_persistence.py +++ b/examples/protocols/http_server/persistent_sockets/pytest_http_server_persistence.py @@ -50,7 +50,7 @@ def test_examples_protocol_http_server_persistence(dut: Dut) -> None: ap_ssid = get_env_config_variable(env_name, 'ap_ssid') ap_password = get_env_config_variable(env_name, 'ap_password') dut.write(f'{ap_ssid} {ap_password}') - got_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + got_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode() got_port = dut.expect(r"(?:[\s\S]*)Starting server on port: '(\d+)'", timeout=30)[1].decode() logging.info('Got IP : {}'.format(got_ip)) diff --git a/examples/protocols/http_server/simple/pytest_http_server_simple.py b/examples/protocols/http_server/simple/pytest_http_server_simple.py index 02df921206..fc1b3d9b58 100644 --- a/examples/protocols/http_server/simple/pytest_http_server_simple.py +++ b/examples/protocols/http_server/simple/pytest_http_server_simple.py @@ -82,7 +82,7 @@ def test_examples_protocol_http_server_simple(dut: Dut) -> None: ap_ssid = get_env_config_variable(env_name, 'ap_ssid') ap_password = get_env_config_variable(env_name, 'ap_password') dut.write(' '.join([ap_ssid, ap_password])) - got_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + got_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode() got_port = dut.expect(r"(?:[\s\S]*)Starting server on port: '(\d+)'", timeout=30)[1].decode() logging.info('Got IP : {}'.format(got_ip)) @@ -156,7 +156,7 @@ def test_examples_protocol_http_server_lru_purge_enable(dut: Dut) -> None: ap_ssid = get_env_config_variable(env_name, 'ap_ssid') ap_password = get_env_config_variable(env_name, 'ap_password') dut.write(f'{ap_ssid} {ap_password}') - got_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + got_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode() got_port = dut.expect(r"(?:[\s\S]*)Starting server on port: '(\d+)'", timeout=30)[1].decode() logging.info('Got IP : {}'.format(got_ip)) diff --git a/examples/protocols/http_server/ws_echo_server/pytest_ws_server_example.py b/examples/protocols/http_server/ws_echo_server/pytest_ws_server_example.py index 3cfbf3843f..b387c92a52 100644 --- a/examples/protocols/http_server/ws_echo_server/pytest_ws_server_example.py +++ b/examples/protocols/http_server/ws_echo_server/pytest_ws_server_example.py @@ -69,7 +69,7 @@ def test_examples_protocol_http_ws_echo_server(dut: Dut) -> None: ap_ssid = get_env_config_variable(env_name, 'ap_ssid') ap_password = get_env_config_variable(env_name, 'ap_password') dut.write(f'{ap_ssid} {ap_password}') - got_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + got_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode() got_port = dut.expect(r"Starting server on port: '(\d+)'", timeout=30)[1].decode() logging.info('Got IP : {}'.format(got_ip)) diff --git a/examples/protocols/https_request/pytest_https_request.py b/examples/protocols/https_request/pytest_https_request.py index 03789b7d2a..a672edc2fc 100644 --- a/examples/protocols/https_request/pytest_https_request.py +++ b/examples/protocols/https_request/pytest_https_request.py @@ -80,7 +80,7 @@ def test_examples_protocol_https_request_cli_session_tickets(dut: Dut) -> None: # start test dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=60)[1].decode() + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=60)[1].decode() print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') @@ -132,7 +132,7 @@ def test_examples_protocol_https_request_dynamic_buffers(dut: Dut) -> None: dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=60)[1].decode() + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=60)[1].decode() print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') @@ -170,7 +170,7 @@ def test_examples_protocol_https_request(dut: Dut) -> None: dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=60)[1].decode() + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=60)[1].decode() print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') diff --git a/examples/protocols/https_server/simple/pytest_https_server_simple.py b/examples/protocols/https_server/simple/pytest_https_server_simple.py index ab027c44cf..0d7967dab4 100644 --- a/examples/protocols/https_server/simple/pytest_https_server_simple.py +++ b/examples/protocols/https_server/simple/pytest_https_server_simple.py @@ -117,7 +117,7 @@ def test_examples_protocol_https_server_simple(dut: Dut) -> None: # Parse IP address and port of the server dut.expect(r'Starting server') got_port = int(dut.expect(r'Server listening on port (\d+)', timeout=30)[1].decode()) - got_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + got_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode() # Expected logs @@ -158,8 +158,8 @@ def test_examples_protocol_https_server_simple(dut: Dut) -> None: logging.info('Checking user callback: Obtaining client certificate...') - serial_number = dut.expect(r'serial number(.*)', timeout=5)[0] - issuer_name = dut.expect(r'issuer name(.*)', timeout=5)[0] + serial_number = dut.expect(r'serial number\s*:([^\n]*)', timeout=5)[0] + issuer_name = dut.expect(r'issuer name\s*:([^\n]*)', timeout=5)[0] expiry = dut.expect(r'expires on ((.*)\d{4}\-(0?[1-9]|1[012])\-(0?[1-9]|[12][0-9]|3[01])*)', timeout=5)[1].decode() logging.info('Serial No. {}'.format(serial_number)) @@ -190,7 +190,7 @@ def test_examples_protocol_https_server_simple_dynamic_buffers(dut: Dut) -> None # Parse IP address and port of the server dut.expect(r'Starting server') got_port = int(dut.expect(r'Server listening on port (\d+)', timeout=30)[1].decode()) - got_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + got_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode() # Expected logs diff --git a/examples/protocols/https_server/wss_server/pytest_https_wss_server.py b/examples/protocols/https_server/wss_server/pytest_https_wss_server.py index 396d2ea780..824c22c598 100644 --- a/examples/protocols/https_server/wss_server/pytest_https_wss_server.py +++ b/examples/protocols/https_server/wss_server/pytest_https_wss_server.py @@ -129,7 +129,7 @@ def test_examples_protocol_https_wss_server(dut: Dut) -> None: dut.write(f'{ap_ssid} {ap_password}') # Parse IP address of STA got_port = int(dut.expect(r'Server listening on port (\d+)', timeout=30)[1].decode()) - got_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + got_ip = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode() logging.info('Got IP : {}'.format(got_ip)) logging.info('Got Port : {}'.format(got_port)) diff --git a/examples/protocols/https_x509_bundle/pytest_https_x509_bundle.py b/examples/protocols/https_x509_bundle/pytest_https_x509_bundle.py index e19bd92fbf..41b9a94f77 100644 --- a/examples/protocols/https_x509_bundle/pytest_https_x509_bundle.py +++ b/examples/protocols/https_x509_bundle/pytest_https_x509_bundle.py @@ -31,7 +31,7 @@ def test_examples_protocol_https_x509_bundle(dut: Dut) -> None: ap_ssid = get_env_config_variable(env_name, 'ap_ssid') ap_password = get_env_config_variable(env_name, 'ap_password') dut.write(f'{ap_ssid} {ap_password}') - dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30) + dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30) # start test num_URLS = int(dut.expect(r'Connecting to (\d+) URLs', timeout=30)[1].decode()) dut.expect(r'Connection established to ([\s\S]*)', timeout=30) @@ -57,7 +57,7 @@ def test_examples_protocol_https_x509_bundle_dynamic_buffer(dut: Dut) -> None: ap_ssid = get_env_config_variable(env_name, 'ap_ssid') ap_password = get_env_config_variable(env_name, 'ap_password') dut.write(f'{ap_ssid} {ap_password}') - dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30) + dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30) # start test num_URLS = int(dut.expect(r'Connecting to (\d+) URLs', timeout=30)[1].decode()) dut.expect(r'Connection established to ([\s\S]*)', timeout=30) diff --git a/examples/protocols/mqtt/ssl/mqtt_ssl_example_test.py b/examples/protocols/mqtt/ssl/mqtt_ssl_example_test.py index 0bdd6d355b..3309ca4d2a 100644 --- a/examples/protocols/mqtt/ssl/mqtt_ssl_example_test.py +++ b/examples/protocols/mqtt/ssl/mqtt_ssl_example_test.py @@ -110,7 +110,7 @@ def test_examples_protocol_mqtt_ssl(env, extra_data): raise ValueError('ENV_TEST_FAILURE: Test script cannot connect to broker: {}'.format(broker_url)) dut1.start_app() try: - ip_address = dut1.expect(re.compile(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)'), timeout=30)[0] + ip_address = dut1.expect(re.compile(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]'), timeout=30)[0] print('Connected to AP with IP: {}'.format(ip_address)) except DUT.ExpectTimeout: print('ENV_TEST_FAILURE: Cannot connect to AP') diff --git a/examples/protocols/mqtt/tcp/mqtt_tcp_example_test.py b/examples/protocols/mqtt/tcp/mqtt_tcp_example_test.py index 735c6ade53..76dc4a4ca9 100644 --- a/examples/protocols/mqtt/tcp/mqtt_tcp_example_test.py +++ b/examples/protocols/mqtt/tcp/mqtt_tcp_example_test.py @@ -65,7 +65,7 @@ def test_examples_protocol_mqtt_qos1(env, extra_data): dut1.start_app() # waiting for getting the IP address try: - ip_address = dut1.expect(re.compile(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)'), timeout=30)[0] + ip_address = dut1.expect(re.compile(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]'), timeout=30)[0] print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except DUT.ExpectTimeout: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') diff --git a/examples/protocols/mqtt/ws/mqtt_ws_example_test.py b/examples/protocols/mqtt/ws/mqtt_ws_example_test.py index f8d87d9768..72d4fa71e7 100644 --- a/examples/protocols/mqtt/ws/mqtt_ws_example_test.py +++ b/examples/protocols/mqtt/ws/mqtt_ws_example_test.py @@ -83,7 +83,7 @@ def test_examples_protocol_mqtt_ws(env, extra_data): raise ValueError('ENV_TEST_FAILURE: Test script cannot connect to broker: {}'.format(broker_url)) dut1.start_app() try: - ip_address = dut1.expect(re.compile(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)'), timeout=30)[0] + ip_address = dut1.expect(re.compile(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]'), timeout=30)[0] print('Connected to AP with IP: {}'.format(ip_address)) except DUT.ExpectTimeout: print('ENV_TEST_FAILURE: Cannot connect to AP') diff --git a/examples/protocols/mqtt/wss/mqtt_wss_example_test.py b/examples/protocols/mqtt/wss/mqtt_wss_example_test.py index 4d204d6b10..9f8ab12692 100644 --- a/examples/protocols/mqtt/wss/mqtt_wss_example_test.py +++ b/examples/protocols/mqtt/wss/mqtt_wss_example_test.py @@ -87,7 +87,7 @@ def test_examples_protocol_mqtt_wss(env, extra_data): raise ValueError('ENV_TEST_FAILURE: Test script cannot connect to broker: {}'.format(broker_url)) dut1.start_app() try: - ip_address = dut1.expect(re.compile(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)'), timeout=30)[0] + ip_address = dut1.expect(re.compile(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]'), timeout=30)[0] print('Connected to AP with IP: {}'.format(ip_address)) except DUT.ExpectTimeout: print('ENV_TEST_FAILURE: Cannot connect to AP') diff --git a/examples/protocols/sockets/tcp_client/example_test.py b/examples/protocols/sockets/tcp_client/example_test.py index d8dc41a542..3427296b5b 100644 --- a/examples/protocols/sockets/tcp_client/example_test.py +++ b/examples/protocols/sockets/tcp_client/example_test.py @@ -103,7 +103,7 @@ def test_examples_protocol_socket_tcpclient(env, extra_data): ap_password = get_env_config_variable(env_name, 'ap_password') dut1.write(f'{ap_ssid} {ap_password}') - ipv4 = dut1.expect(re.compile(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)'), timeout=30)[0] + ipv4 = dut1.expect(re.compile(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]'), timeout=30)[0] ipv6_r = r':'.join((r'[0-9a-fA-F]{4}',) * 8) # expect all 8 octets from IPv6 (assumes it's printed in the long form) ipv6 = dut1.expect(re.compile(r' IPv6 address: ({})'.format(ipv6_r)), timeout=30)[0] print('Connected with IPv4={} and IPv6={}'.format(ipv4, ipv6)) diff --git a/examples/protocols/sockets/tcp_server/example_test.py b/examples/protocols/sockets/tcp_server/example_test.py index bc8bd5d293..fe83f705df 100644 --- a/examples/protocols/sockets/tcp_server/example_test.py +++ b/examples/protocols/sockets/tcp_server/example_test.py @@ -70,7 +70,7 @@ def test_examples_protocol_socket_tcpserver(env, extra_data): ap_password = get_env_config_variable(env_name, 'ap_password') dut1.write(f'{ap_ssid} {ap_password}') - ipv4 = dut1.expect(re.compile(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)'), timeout=30)[0] + ipv4 = dut1.expect(re.compile(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]'), timeout=30)[0] ipv6_r = r':'.join((r'[0-9a-fA-F]{4}',) * 8) # expect all 8 octets from IPv6 (assumes it's printed in the long form) ipv6 = dut1.expect(re.compile(r' IPv6 address: ({})'.format(ipv6_r)), timeout=30)[0] print('Connected with IPv4={} and IPv6={}'.format(ipv4, ipv6)) diff --git a/examples/protocols/sockets/udp_client/example_test.py b/examples/protocols/sockets/udp_client/example_test.py index c90ff7488f..a5425b8614 100644 --- a/examples/protocols/sockets/udp_client/example_test.py +++ b/examples/protocols/sockets/udp_client/example_test.py @@ -98,7 +98,7 @@ def test_examples_protocol_socket_udpclient(env, extra_data): ap_password = get_env_config_variable(env_name, 'ap_password') dut1.write(f'{ap_ssid} {ap_password}') - ipv4 = dut1.expect(re.compile(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)'), timeout=30)[0] + ipv4 = dut1.expect(re.compile(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]'), timeout=30)[0] ipv6_r = r':'.join((r'[0-9a-fA-F]{4}',) * 8) # expect all 8 octets from IPv6 (assumes it's printed in the long form) ipv6 = dut1.expect(re.compile(r' IPv6 address: ({})'.format(ipv6_r)), timeout=30)[0] print('Connected with IPv4={} and IPv6={}'.format(ipv4, ipv6)) diff --git a/examples/protocols/sockets/udp_server/example_test.py b/examples/protocols/sockets/udp_server/example_test.py index 7aebb8ff8a..9207138a89 100644 --- a/examples/protocols/sockets/udp_server/example_test.py +++ b/examples/protocols/sockets/udp_server/example_test.py @@ -74,7 +74,7 @@ def test_examples_protocol_socket_udpserver(env, extra_data): ap_password = get_env_config_variable(env_name, 'ap_password') dut1.write(f'{ap_ssid} {ap_password}') - ipv4 = dut1.expect(re.compile(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)'), timeout=30)[0] + ipv4 = dut1.expect(re.compile(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]'), timeout=30)[0] ipv6_r = r':'.join((r'[0-9a-fA-F]{4}',) * 8) # expect all 8 octets from IPv6 (assumes it's printed in the long form) ipv6 = dut1.expect(re.compile(r' IPv6 address: ({})'.format(ipv6_r)), timeout=30)[0] print('Connected with IPv4={} and IPv6={}'.format(ipv4, ipv6)) diff --git a/examples/system/ota/advanced_https_ota/pytest_advanced_ota.py b/examples/system/ota/advanced_https_ota/pytest_advanced_ota.py index c07dfcf9d9..ed9ef7793d 100644 --- a/examples/system/ota/advanced_https_ota/pytest_advanced_ota.py +++ b/examples/system/ota/advanced_https_ota/pytest_advanced_ota.py @@ -120,7 +120,7 @@ def test_examples_protocol_advanced_https_ota_example(dut: Dut) -> None: for _ in range(iterations): dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode() print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') @@ -170,7 +170,7 @@ def test_examples_protocol_advanced_https_ota_example_truncated_bin(dut: Dut) -> # start test dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode() print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') @@ -224,7 +224,7 @@ def test_examples_protocol_advanced_https_ota_example_truncated_header(dut: Dut) # start test dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode() print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') @@ -278,7 +278,7 @@ def test_examples_protocol_advanced_https_ota_example_random(dut: Dut) -> None: # start test dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode() print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') @@ -334,7 +334,7 @@ def test_examples_protocol_advanced_https_ota_example_invalid_chip_id(dut: Dut) # start test dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode() print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') @@ -374,7 +374,7 @@ def test_examples_protocol_advanced_https_ota_example_chunked(dut: Dut) -> None: # start test dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode() print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') @@ -415,7 +415,7 @@ def test_examples_protocol_advanced_https_ota_example_redirect_url(dut: Dut) -> # start test dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode() print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') @@ -490,7 +490,7 @@ def test_examples_protocol_advanced_https_ota_example_anti_rollback(dut: Dut) -> # Positive Case dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode() print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') @@ -501,7 +501,7 @@ def test_examples_protocol_advanced_https_ota_example_anti_rollback(dut: Dut) -> print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port) + '/' + bin_name)) dut.write('https://' + host_ip + ':' + str(server_port) + '/' + bin_name) dut.expect('Loaded app from partition at offset', timeout=60) - dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode() dut.expect(r'App is valid, rollback cancelled successfully', timeout=30) # Negative Case @@ -549,7 +549,7 @@ def test_examples_protocol_advanced_https_ota_example_partial_request(dut: Dut) # start test dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode() print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') @@ -602,7 +602,7 @@ def test_examples_protocol_advanced_https_ota_example_nimble_gatts(dut: Dut) -> ap_password = get_env_config_variable(env_name, 'ap_password') dut.write(f'{ap_ssid} {ap_password}') try: - ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode() print('Connected to AP with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') @@ -655,7 +655,7 @@ def test_examples_protocol_advanced_https_ota_example_bluedroid_gatts(dut: Dut) ap_password = get_env_config_variable(env_name, 'ap_password') dut.write(f'{ap_ssid} {ap_password}') try: - ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode() print('Connected to AP with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP') @@ -709,7 +709,7 @@ def test_examples_protocol_advanced_https_ota_example_openssl_aligned_bin(dut: D # start test dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode() print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') diff --git a/examples/system/ota/native_ota_example/pytest_native_ota.py b/examples/system/ota/native_ota_example/pytest_native_ota.py index ef684a2bde..d590174f4d 100644 --- a/examples/system/ota/native_ota_example/pytest_native_ota.py +++ b/examples/system/ota/native_ota_example/pytest_native_ota.py @@ -146,7 +146,7 @@ def test_examples_protocol_native_ota_example(dut: Dut) -> None: for _ in range(iterations): dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode() print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') @@ -195,7 +195,7 @@ def test_examples_protocol_native_ota_example_truncated_bin(dut: Dut) -> None: # start test dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode() print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') @@ -244,7 +244,7 @@ def test_examples_protocol_native_ota_example_truncated_header(dut: Dut) -> None # start test dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode() print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') @@ -293,7 +293,7 @@ def test_examples_protocol_native_ota_example_random(dut: Dut) -> None: # start test dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode() print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') @@ -327,7 +327,7 @@ def test_examples_protocol_native_ota_example_chunked(dut: Dut) -> None: # start test dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode() print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') diff --git a/examples/system/ota/pre_encrypted_ota/pytest_pre_encrypted_ota.py b/examples/system/ota/pre_encrypted_ota/pytest_pre_encrypted_ota.py index 9f2ef24780..b9f2f056c4 100644 --- a/examples/system/ota/pre_encrypted_ota/pytest_pre_encrypted_ota.py +++ b/examples/system/ota/pre_encrypted_ota/pytest_pre_encrypted_ota.py @@ -66,7 +66,7 @@ def test_examples_protocol_pre_encrypted_ota_example(dut: Dut) -> None: try: dut.expect('Loaded app from partition at offset', timeout=30) try: - ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode() print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') diff --git a/examples/system/ota/simple_ota_example/pytest_simple_ota.py b/examples/system/ota/simple_ota_example/pytest_simple_ota.py index 5d3386c485..93edd4bde2 100644 --- a/examples/system/ota/simple_ota_example/pytest_simple_ota.py +++ b/examples/system/ota/simple_ota_example/pytest_simple_ota.py @@ -135,7 +135,7 @@ def test_examples_protocol_simple_ota_example(dut: Dut) -> None: ap_password = get_env_config_variable(env_name, 'ap_password') dut.write(f'{ap_ssid} {ap_password}') try: - ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode() print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') @@ -173,7 +173,7 @@ def test_examples_protocol_simple_ota_example_ethernet_with_spiram_config(dut: D # start test dut.expect('Loaded app from partition at offset 0x10000', timeout=30) try: - ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode() print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') @@ -222,7 +222,7 @@ def test_examples_protocol_simple_ota_example_with_flash_encryption_wifi(dut: Du ap_password = get_env_config_variable(env_name, 'ap_password') dut.write(f'{ap_ssid} {ap_password}') try: - ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode() print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') @@ -264,7 +264,7 @@ def test_examples_protocol_simple_ota_example_with_verify_app_signature_on_updat check_sha256(sha256_bootloader, str(dut.expect(r'SHA-256 for bootloader:\s+([a-f0-9]){64}')[0])) check_sha256(sha256_app, str(dut.expect(r'SHA-256 for current firmware:\s+([a-f0-9]){64}')[0])) try: - ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode() print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') @@ -307,7 +307,7 @@ def test_examples_protocol_simple_ota_example_with_verify_app_signature_on_updat check_sha256(sha256_bootloader, str(dut.expect(r'SHA-256 for bootloader:\s+([a-f0-9]){64}')[0])) check_sha256(sha256_app, str(dut.expect(r'SHA-256 for current firmware:\s+([a-f0-9]){64}')[0])) try: - ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)', timeout=30)[1].decode() + ip_address = dut.expect(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]', timeout=30)[1].decode() print('Connected to AP/Ethernet with IP: {}'.format(ip_address)) except pexpect.exceptions.TIMEOUT: raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet') diff --git a/tools/test_apps/protocols/mqtt/publish_connect_test/app_test.py b/tools/test_apps/protocols/mqtt/publish_connect_test/app_test.py index 0b30d06a46..a2366d3bca 100644 --- a/tools/test_apps/protocols/mqtt/publish_connect_test/app_test.py +++ b/tools/test_apps/protocols/mqtt/publish_connect_test/app_test.py @@ -336,7 +336,7 @@ def test_app_protocol_mqtt_publish_connect(env, extra_data): raise dut1.start_app() - esp_ip = dut1.expect(re.compile(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)'), timeout=30)[0] + esp_ip = dut1.expect(re.compile(r'IPv4 address: (\d+\.\d+\.\d+\.\d+)[^\d]'), timeout=30)[0] print('Got IP={}'.format(esp_ip)) if not os.getenv('MQTT_SKIP_CONNECT_TEST'):