From b8e47eb56f7aad00eda76b508816287fa04019b8 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Sun, 19 Jan 2020 21:24:28 +0100 Subject: [PATCH 1/3] mqtt: add basic set of unit tests --- components/mqtt/esp-mqtt | 2 +- components/mqtt/test/CMakeLists.txt | 2 + components/mqtt/test/component.mk | 4 ++ components/mqtt/test/test_mqtt.c | 70 +++++++++++++++++++++++++++++ 4 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 components/mqtt/test/CMakeLists.txt create mode 100644 components/mqtt/test/component.mk create mode 100644 components/mqtt/test/test_mqtt.c diff --git a/components/mqtt/esp-mqtt b/components/mqtt/esp-mqtt index 86fc8b758..9e20c7ae3 160000 --- a/components/mqtt/esp-mqtt +++ b/components/mqtt/esp-mqtt @@ -1 +1 @@ -Subproject commit 86fc8b7584f7f3aebf422843d84a26655e485fbe +Subproject commit 9e20c7ae3d6951cab3ed8dc66a0467da5bf37f16 diff --git a/components/mqtt/test/CMakeLists.txt b/components/mqtt/test/CMakeLists.txt new file mode 100644 index 000000000..867c58448 --- /dev/null +++ b/components/mqtt/test/CMakeLists.txt @@ -0,0 +1,2 @@ +idf_component_register(SRC_DIRS "." + PRIV_REQUIRES unity test_utils mqtt nvs_flash app_update) \ No newline at end of file diff --git a/components/mqtt/test/component.mk b/components/mqtt/test/component.mk new file mode 100644 index 000000000..5be873488 --- /dev/null +++ b/components/mqtt/test/component.mk @@ -0,0 +1,4 @@ +# +#Component Makefile +# +COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive \ No newline at end of file diff --git a/components/mqtt/test/test_mqtt.c b/components/mqtt/test/test_mqtt.c new file mode 100644 index 000000000..12cd1777b --- /dev/null +++ b/components/mqtt/test/test_mqtt.c @@ -0,0 +1,70 @@ +#include "test_utils.h" +#include "mqtt_client.h" +#include "unity.h" +#include +#include "nvs_flash.h" +#include "esp_ota_ops.h" + +static void test_leak_setup(const char * file, long line) +{ + uint8_t mac[6]; + struct timeval te; + gettimeofday(&te, NULL); // get current time + esp_read_mac(mac, ESP_MAC_WIFI_STA); + printf("%s:%ld: time=%ld.%lds, mac:" MACSTR "\n", file, line, te.tv_sec, te.tv_usec, MAC2STR(mac)); + unity_reset_leak_checks(); +} + +static const char* this_bin_addr(void) +{ + spi_flash_mmap_handle_t out_handle; + const void *binary_address; + const esp_partition_t* partition = esp_ota_get_running_partition(); + esp_partition_mmap(partition, 0, partition->size, SPI_FLASH_MMAP_DATA, &binary_address, &out_handle); + return binary_address; +} + +TEST_CASE("mqtt init with invalid url", "[mqtt][leaks=0]") +{ + test_leak_setup(__FILE__, __LINE__); + const esp_mqtt_client_config_t mqtt_cfg = { + .uri = "INVALID", + }; + esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg); + TEST_ASSERT_EQUAL(NULL, client ); +} + +TEST_CASE("mqtt init and deinit", "[mqtt][leaks=0]") +{ + test_leak_setup(__FILE__, __LINE__); + const esp_mqtt_client_config_t mqtt_cfg = { + // no connection takes place, but the uri has to be valid for init() to succeed + .uri = "mqtts://localhost:8883", + }; + esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg); + TEST_ASSERT_NOT_EQUAL(NULL, client ); + esp_mqtt_client_destroy(client); +} + +TEST_CASE("mqtt enqueue and destroy outbox", "[mqtt][leaks=0]") +{ + const char * bin_addr = this_bin_addr(); + test_leak_setup(__FILE__, __LINE__); + const int messages = 20; + const int size = 2000; + const esp_mqtt_client_config_t mqtt_cfg = { + // no connection takes place, but the uri has to be valid for init() to succeed + .uri = "mqtts://localhost:8883", + }; + esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg); + TEST_ASSERT_NOT_EQUAL(NULL, client ); + int bytes_before = esp_get_free_heap_size(); + for (int i=0; i Date: Tue, 21 Jan 2020 16:44:02 +0100 Subject: [PATCH 2/3] mqtt: example test to check connection with different ssl parameters --- .../mqtt/weekend_test/mqtt_publish_test.py | 8 +- .../mqtt/publish_connect_test/CMakeLists.txt | 19 ++ .../Makefile | 2 +- .../README.md | 2 +- .../mqtt/publish_connect_test/ca.crt | 22 ++ .../mqtt/publish_connect_test/ca.der | Bin 0 -> 919 bytes .../mqtt/publish_connect_test/ca.key | 27 ++ .../mqtt/publish_connect_test/client_inv.crt | 19 ++ .../publish_connect_test/client_no_pwd.key | 27 ++ .../mqtt/publish_connect_test/client_pwd.crt | 18 ++ .../mqtt/publish_connect_test/client_pwd.key | 30 +++ .../mqtt/publish_connect_test/example_test.py | 230 +++++++++++++++++ .../publish_connect_test/main/CMakeLists.txt | 2 + .../main/Kconfig.projbuild | 35 +++ .../publish_connect_test/main/component.mk | 1 + .../publish_connect_test/main/connect_test.c | 237 ++++++++++++++++++ .../main/mqtt_eclipse_org.pem | 0 .../main/publish_connect_test.c | 76 ++++++ .../publish_connect_test/main/publish_test.c | 175 +++++++++++++ .../sdkconfig.ci | 0 .../sdkconfig.qemu | 0 .../mqtt/publish_connect_test/server.key | 27 ++ .../mqtt/publish_test/CMakeLists.txt | 13 - .../mqtt/publish_test/main/CMakeLists.txt | 2 - .../mqtt/publish_test/main/component.mk | 1 - .../mqtt/publish_test/main/publish_test.c | 226 ----------------- 26 files changed, 948 insertions(+), 251 deletions(-) create mode 100644 examples/protocols/mqtt/publish_connect_test/CMakeLists.txt rename examples/protocols/mqtt/{publish_test => publish_connect_test}/Makefile (85%) rename examples/protocols/mqtt/{publish_test => publish_connect_test}/README.md (98%) create mode 100644 examples/protocols/mqtt/publish_connect_test/ca.crt create mode 100644 examples/protocols/mqtt/publish_connect_test/ca.der create mode 100644 examples/protocols/mqtt/publish_connect_test/ca.key create mode 100644 examples/protocols/mqtt/publish_connect_test/client_inv.crt create mode 100644 examples/protocols/mqtt/publish_connect_test/client_no_pwd.key create mode 100644 examples/protocols/mqtt/publish_connect_test/client_pwd.crt create mode 100644 examples/protocols/mqtt/publish_connect_test/client_pwd.key create mode 100644 examples/protocols/mqtt/publish_connect_test/example_test.py create mode 100644 examples/protocols/mqtt/publish_connect_test/main/CMakeLists.txt rename examples/protocols/mqtt/{publish_test => publish_connect_test}/main/Kconfig.projbuild (63%) create mode 100644 examples/protocols/mqtt/publish_connect_test/main/component.mk create mode 100644 examples/protocols/mqtt/publish_connect_test/main/connect_test.c rename examples/protocols/mqtt/{publish_test => publish_connect_test}/main/mqtt_eclipse_org.pem (100%) create mode 100644 examples/protocols/mqtt/publish_connect_test/main/publish_connect_test.c create mode 100644 examples/protocols/mqtt/publish_connect_test/main/publish_test.c rename examples/protocols/mqtt/{publish_test => publish_connect_test}/sdkconfig.ci (100%) rename examples/protocols/mqtt/{publish_test => publish_connect_test}/sdkconfig.qemu (100%) create mode 100644 examples/protocols/mqtt/publish_connect_test/server.key delete mode 100644 examples/protocols/mqtt/publish_test/CMakeLists.txt delete mode 100644 examples/protocols/mqtt/publish_test/main/CMakeLists.txt delete mode 100644 examples/protocols/mqtt/publish_test/main/component.mk delete mode 100644 examples/protocols/mqtt/publish_test/main/publish_test.c diff --git a/components/mqtt/weekend_test/mqtt_publish_test.py b/components/mqtt/weekend_test/mqtt_publish_test.py index 32ae3389f..e018ebf24 100644 --- a/components/mqtt/weekend_test/mqtt_publish_test.py +++ b/components/mqtt/weekend_test/mqtt_publish_test.py @@ -2,7 +2,6 @@ from __future__ import print_function from __future__ import unicode_literals from builtins import str import re -import os import sys import ssl import paho.mqtt.client as mqtt @@ -128,12 +127,7 @@ def test_weekend_mqtt_publish(env, extra_data): 3. Test evaluates python client received correct qos0 message 4. Test ESP32 client received correct qos0 message """ - dut1 = env.get_dut("mqtt_publish", "examples/protocols/mqtt/publish_test") - # check and log bin size - binary_file = os.path.join(dut1.app.binary_path, "mqtt_publish.bin") - bin_size = os.path.getsize(binary_file) - ttfw_idf.log_performance("mqtt_publish_bin_size", "{}KB".format(bin_size // 1024)) - ttfw_idf.check_performance("mqtt_publish_size", bin_size // 1024) + dut1 = env.get_dut("mqtt_publish_connect_test", "examples/protocols/mqtt/publish_connect_test") # Look for host:port in sdkconfig try: # python client subscribes to the topic to which esp client publishes and vice versa diff --git a/examples/protocols/mqtt/publish_connect_test/CMakeLists.txt b/examples/protocols/mqtt/publish_connect_test/CMakeLists.txt new file mode 100644 index 000000000..6d1ef5af8 --- /dev/null +++ b/examples/protocols/mqtt/publish_connect_test/CMakeLists.txt @@ -0,0 +1,19 @@ +# The following four lines of boilerplate have to be in your project's CMakeLists +# in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +# (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(mqtt_publish_connect_test) + +target_add_binary_data(mqtt_publish_connect_test.elf "main/mqtt_eclipse_org.pem" TEXT) +target_add_binary_data(mqtt_publish_connect_test.elf "ca.crt" TEXT) +target_add_binary_data(mqtt_publish_connect_test.elf "ca.der" TEXT) +target_add_binary_data(mqtt_publish_connect_test.elf "client_pwd.key" TEXT) +target_add_binary_data(mqtt_publish_connect_test.elf "client_pwd.crt" TEXT) +target_add_binary_data(mqtt_publish_connect_test.elf "client_no_pwd.key" TEXT) +target_add_binary_data(mqtt_publish_connect_test.elf "client_inv.crt" TEXT) diff --git a/examples/protocols/mqtt/publish_test/Makefile b/examples/protocols/mqtt/publish_connect_test/Makefile similarity index 85% rename from examples/protocols/mqtt/publish_test/Makefile rename to examples/protocols/mqtt/publish_connect_test/Makefile index 7d552c3be..49c193dd3 100644 --- a/examples/protocols/mqtt/publish_test/Makefile +++ b/examples/protocols/mqtt/publish_connect_test/Makefile @@ -2,7 +2,7 @@ # This is a project Makefile. It is assumed the directory this Makefile resides in is a # project subdirectory. # -PROJECT_NAME := mqtt_publish +PROJECT_NAME := mqtt_publish_connect_test EXTRA_COMPONENT_DIRS = $(IDF_PATH)/examples/common_components/protocol_examples_common diff --git a/examples/protocols/mqtt/publish_test/README.md b/examples/protocols/mqtt/publish_connect_test/README.md similarity index 98% rename from examples/protocols/mqtt/publish_test/README.md rename to examples/protocols/mqtt/publish_connect_test/README.md index ee377d5a6..2147420a5 100644 --- a/examples/protocols/mqtt/publish_test/README.md +++ b/examples/protocols/mqtt/publish_connect_test/README.md @@ -1,4 +1,4 @@ -# ESP-MQTT advanced published test +# ESP-MQTT advanced publish and connect test project (See the README.md file in the upper level 'examples' directory for more information about examples.) Main purpose of this example is to test the MQTT library to correctly publish and receive messages (of different size and sequences) over different transports. diff --git a/examples/protocols/mqtt/publish_connect_test/ca.crt b/examples/protocols/mqtt/publish_connect_test/ca.crt new file mode 100644 index 000000000..894f2959b --- /dev/null +++ b/examples/protocols/mqtt/publish_connect_test/ca.crt @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDkzCCAnugAwIBAgIUNI5wldYysh6rtCzYmda6H414aRswDQYJKoZIhvcNAQEL +BQAwWTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDESMBAGA1UEAwwJRXNwcmVzc2lmMB4X +DTIwMDEyMTA5MDk0NloXDTI1MDEyMDA5MDk0NlowWTELMAkGA1UEBhMCQVUxEzAR +BgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5 +IEx0ZDESMBAGA1UEAwwJRXNwcmVzc2lmMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAyadSpRnIQBVbEAsbpkrKrOMlBOMIUmA8AfNyOYPLfv0Oa5lBiMAV +3OQDu5tYyFYKwkCUqq65iAm50fPbSH71w1tkja6nZ1yAIM+TvpMlM/WiFGrhY+Tc +kAcLcKUJyPxrv/glzoVslbqUgIhuhCSKA8uk1+ILcn3nWzPcbcowLx31+AHeZj8h +bIAdj6vjqxMCFStp4IcA+ikmCk75LCN4vkkifdkebb/ZDNYCZZhpCBnCHyFAjPc4 +7C+FDVGT3/UUeeTy+Mtn+MqUAhB+W0sPDm1n2h59D4Z/MFm0hl6GQCAKeMJPzssU +BBsRm6zoyPQ4VTqG0uwfNNbORyIfKONMUwIDAQABo1MwUTAdBgNVHQ4EFgQUGYLV +EkgWzxjpltE6texha7zZVxowHwYDVR0jBBgwFoAUGYLVEkgWzxjpltE6texha7zZ +VxowDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAb2EF4Zg2XWNb +eZHnzupCDd9jAhwPqkt7F1OXvxJa/RFUSB9+2izGvikGGhuKY4f0iLuqF+bhExD9 +sapDcdFO2Suh4J3onbwEvmKvsv56K3xhapYg8WwPofpkVirnkwFjpQXGzrYxPujg +BPmSy3psQrhvOr/WH7SefJv2qr4ikaugfE+3enY4PL+C1dSQAuNo1QGgWsZIu0c8 +TZybNZ13vNVMA+tgj2CM8FR3Etaabwtu3TTcAnO7aoBTix/bLBTuZoczhN8/MhG3 +GylmDzFI8a6aKxQL3Fi4PsM82hRKWu3gfs39sR1Ci4V22v8uO5EWBPK0QZvDSc1a +KwwxI4zA0w== +-----END CERTIFICATE----- diff --git a/examples/protocols/mqtt/publish_connect_test/ca.der b/examples/protocols/mqtt/publish_connect_test/ca.der new file mode 100644 index 0000000000000000000000000000000000000000..c5c3304e23747ca8143d9d92365c99ac752799ff GIT binary patch literal 919 zcmXqLVxDZ!#8kb2nTe5!NyMbDVCpraO>(QZ=-iljZI^s+MW(a?FB_*;n@8JsUPeZ4 zRtAGeLv903Hs(+kHen{mP(xt@K@f+7hbuTgH&r*dB(WsbP|-jhB*?`h;h9>9lVs zq7a^$lAc*otPoIAso+zRVkl%F08+xt!|7UFP?TC+oS9}IC(dhRU|?uuXkckzX<`-y z6C)$T$>l*yB~LhrMhkFDFY`LJ=CLZv zV~(H%8^+H?md&T@{_WoYd$wTsr4n5y3-srdT22Q^JRiyICryr-&f1H}aBv2Ra&Ci#ceoL;FzpdUN za!XrWn}Y&Z#UcN5r$tz#1!u2$apH?bs8!pgH}WRe&bceeYdrP|W@2V!U|bw*5NIF^ zj5b+57BLnP$)>A99%APuUQWAcwe?M6_MV&JQs9V}Rc4Ve5Np7$fFGn^n33^63#$P$ zkU|c2VEO_EJ0nAWBJ0B$X0gf9l@p(zd*#G?Kbc8}f0cK&c<}W7LQ#JOLp=(&?%krycoL`>)AwnO8IW+p2v^6IU;&@!wumW?{3x z>FSjUOpi0JGA@WZ=CRw|#&^za)4An)uKF;)PUuhQ`4CbrbZu5Xcivr-J50s9vl@cC z +#include "esp_netif.h" + +#include "esp_log.h" +#include "mqtt_client.h" +#include "esp_tls.h" + +#if (!defined(CONFIG_EXAMPLE_CONNECT_CASE_NO_CERT)) || \ + (!defined(CONFIG_EXAMPLE_CONNECT_CASE_SERVER_CERT)) || \ + (!defined(CONFIG_EXAMPLE_CONNECT_CASE_MUTUAL_AUTH)) || \ + (!defined(CONFIG_EXAMPLE_CONNECT_CASE_INVALID_SERVER_CERT)) || \ + (!defined(CONFIG_EXAMPLE_CONNECT_CASE_SERVER_DER_CERT)) || \ + (!defined(CONFIG_EXAMPLE_CONNECT_CASE_MUTUAL_AUTH_KEY_PWD)) || \ + (!defined(CONFIG_EXAMPLE_CONNECT_CASE_MUTUAL_AUTH_BAD_CRT)) || \ + (!defined(CONFIG_EXAMPLE_CONNECT_CASE_NO_CERT_ALPN)) +#error "Some mandatory test case not defined!" +#endif + +extern const uint8_t ca_local_crt[] asm("_binary_ca_crt_start"); +extern const uint8_t ca_der_start[] asm("_binary_ca_der_start"); +extern const uint8_t ca_der_end[] asm("_binary_ca_der_end"); +extern const uint8_t client_pwd_crt[] asm("_binary_client_pwd_crt_start"); +extern const uint8_t client_pwd_key[] asm("_binary_client_pwd_key_start"); +extern const uint8_t client_inv_crt[] asm("_binary_client_inv_crt_start"); +extern const uint8_t client_no_pwd_key[] asm("_binary_client_no_pwd_key_start"); + +static const char *TAG = "CONNECT_TEST"; +static esp_mqtt_client_handle_t mqtt_client = NULL; +static int running_test_case = 0; + +static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data) +{ + esp_mqtt_event_handle_t event = event_data; + ESP_LOGD(TAG, "Event: %d, Test case: %d", event->event_id, running_test_case); + switch (event->event_id) { + case MQTT_EVENT_CONNECTED: + ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED: Test=%d", running_test_case); + break; + case MQTT_EVENT_ERROR: + ESP_LOGI(TAG, "MQTT_EVENT_ERROR: Test=%d", running_test_case); + if (event->error_handle->error_type == MQTT_ERROR_TYPE_ESP_TLS) { + ESP_LOGI(TAG, "ESP-TLS ERROR: 0x%x", event->error_handle->esp_tls_last_esp_err); + } else if (event->error_handle->error_type == MQTT_ERROR_TYPE_CONNECTION_REFUSED) { + ESP_LOGI(TAG, "MQTT ERROR: 0x%x", event->error_handle->connect_return_code); + } else { + ESP_LOGW(TAG, "Unknown error type: 0x%x", event->error_handle->error_type); + } + break; + default: + ESP_LOGI(TAG, "Other event id:%d", event->event_id); + break; + } +} + +static void create_client(void) +{ + const esp_mqtt_client_config_t mqtt_cfg = { + .uri = "mqtts://127.0.0.1:1234" + }; + esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg); + esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, client); + mqtt_client = client; + esp_mqtt_client_start(client); +} + +static void connect_no_certs(const char *host, const int port) +{ + char uri[64]; + sprintf(uri, "mqtts://%s:%d", host, port); + const esp_mqtt_client_config_t mqtt_cfg = { + .uri = uri + }; + esp_mqtt_set_config(mqtt_client, &mqtt_cfg); + esp_mqtt_client_disconnect(mqtt_client); + esp_mqtt_client_reconnect(mqtt_client); +} + +static void connect_with_client_key_password(const char *host, const int port) +{ + char uri[64]; + sprintf(uri, "mqtts://%s:%d", host, port); + const esp_mqtt_client_config_t mqtt_cfg = { + .uri = uri, + .cert_pem = (const char *)ca_local_crt, + .client_cert_pem = (const char *)client_pwd_crt, + .client_key_pem = (const char *)client_pwd_key, + .clientkey_password = "esp32", + .clientkey_password_len = 5 + }; + esp_mqtt_set_config(mqtt_client, &mqtt_cfg); + esp_mqtt_client_disconnect(mqtt_client); + esp_mqtt_client_reconnect(mqtt_client); +} + +static void connect_with_server_der_cert(const char *host, const int port) +{ + char uri[64]; + sprintf(uri, "mqtts://%s:%d", host, port); + const esp_mqtt_client_config_t mqtt_cfg = { + .uri = uri, + .cert_pem = (const char *)ca_der_start, + .cert_len = ca_der_end - ca_der_start, + .client_cert_pem = "NULL", + .client_key_pem = "NULL" + }; + esp_mqtt_set_config(mqtt_client, &mqtt_cfg); + esp_mqtt_client_disconnect(mqtt_client); + esp_mqtt_client_reconnect(mqtt_client); +} + +static void connect_with_wrong_server_cert(const char *host, const int port) +{ + char uri[64]; + sprintf(uri, "mqtts://%s:%d", host, port); + const esp_mqtt_client_config_t mqtt_cfg = { + .uri = uri, + .cert_pem = (const char *)client_pwd_crt, + .client_cert_pem = "NULL", + .client_key_pem = "NULL" + }; + esp_mqtt_set_config(mqtt_client, &mqtt_cfg); + esp_mqtt_client_disconnect(mqtt_client); + esp_mqtt_client_reconnect(mqtt_client); +} + +static void connect_with_server_cert(const char *host, const int port) +{ + char uri[64]; + sprintf(uri, "mqtts://%s:%d", host, port); + const esp_mqtt_client_config_t mqtt_cfg = { + .uri = uri, + .cert_pem = (const char *)ca_local_crt, + }; + esp_mqtt_set_config(mqtt_client, &mqtt_cfg); + esp_mqtt_client_disconnect(mqtt_client); + esp_mqtt_client_reconnect(mqtt_client); +} + +static void connect_with_server_client_certs(const char *host, const int port) +{ + char uri[64]; + sprintf(uri, "mqtts://%s:%d", host, port); + const esp_mqtt_client_config_t mqtt_cfg = { + .uri = uri, + .cert_pem = (const char *)ca_local_crt, + .client_cert_pem = (const char *)client_pwd_crt, + .client_key_pem = (const char *)client_no_pwd_key + }; + esp_mqtt_set_config(mqtt_client, &mqtt_cfg); + esp_mqtt_client_disconnect(mqtt_client); + esp_mqtt_client_reconnect(mqtt_client); +} + +static void connect_with_invalid_client_certs(const char *host, const int port) +{ + char uri[64]; + sprintf(uri, "mqtts://%s:%d", host, port); + const esp_mqtt_client_config_t mqtt_cfg = { + .uri = uri, + .cert_pem = (const char *)ca_local_crt, + .client_cert_pem = (const char *)client_inv_crt, + .client_key_pem = (const char *)client_no_pwd_key + }; + esp_mqtt_set_config(mqtt_client, &mqtt_cfg); + esp_mqtt_client_disconnect(mqtt_client); + esp_mqtt_client_reconnect(mqtt_client); +} + +static void connect_with_alpn(const char *host, const int port) +{ + char uri[64]; + const char *alpn_protos[] = { "mymqtt", NULL }; + sprintf(uri, "mqtts://%s:%d", host, port); + const esp_mqtt_client_config_t mqtt_cfg = { + .uri = uri, + .alpn_protos = alpn_protos + }; + esp_mqtt_set_config(mqtt_client, &mqtt_cfg); + esp_mqtt_client_disconnect(mqtt_client); + esp_mqtt_client_reconnect(mqtt_client); +} + +void connection_test(const char* line) +{ + char test_type[32]; + char host[32]; + int port; + int test_case; + + sscanf(line, "%s %s %d %d", test_type, host, &port, &test_case); + if (mqtt_client == NULL) { + create_client(); + } + ESP_LOGI(TAG, "CASE:%d, connecting to mqtts://%s:%d ", test_case, host, port); + running_test_case = test_case; + switch (test_case) { + case CONFIG_EXAMPLE_CONNECT_CASE_NO_CERT: + connect_no_certs(host, port); + break; + case CONFIG_EXAMPLE_CONNECT_CASE_SERVER_CERT: + connect_with_server_cert(host, port); + break; + case CONFIG_EXAMPLE_CONNECT_CASE_MUTUAL_AUTH: + connect_with_server_client_certs(host, port); + break; + case CONFIG_EXAMPLE_CONNECT_CASE_INVALID_SERVER_CERT: + connect_with_wrong_server_cert(host, port); + break; + case CONFIG_EXAMPLE_CONNECT_CASE_SERVER_DER_CERT: + connect_with_server_der_cert(host, port); + break; + case CONFIG_EXAMPLE_CONNECT_CASE_MUTUAL_AUTH_KEY_PWD: + connect_with_client_key_password(host, port); + break; + case CONFIG_EXAMPLE_CONNECT_CASE_MUTUAL_AUTH_BAD_CRT: + connect_with_invalid_client_certs(host, port); + break; + case CONFIG_EXAMPLE_CONNECT_CASE_NO_CERT_ALPN: + connect_with_alpn(host, port); + break; + default: + ESP_LOGE(TAG, "Unknown test case %d ", test_case); + break; + } + ESP_LOGI(TAG, "Test case:%d started", test_case); +} + + diff --git a/examples/protocols/mqtt/publish_test/main/mqtt_eclipse_org.pem b/examples/protocols/mqtt/publish_connect_test/main/mqtt_eclipse_org.pem similarity index 100% rename from examples/protocols/mqtt/publish_test/main/mqtt_eclipse_org.pem rename to examples/protocols/mqtt/publish_connect_test/main/mqtt_eclipse_org.pem diff --git a/examples/protocols/mqtt/publish_connect_test/main/publish_connect_test.c b/examples/protocols/mqtt/publish_connect_test/main/publish_connect_test.c new file mode 100644 index 000000000..fa7336c49 --- /dev/null +++ b/examples/protocols/mqtt/publish_connect_test/main/publish_connect_test.c @@ -0,0 +1,76 @@ +/* MQTT publish-connect test + + 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 +#include +#include "esp_system.h" +#include "nvs_flash.h" +#include "esp_event.h" +#include "esp_netif.h" +#include "protocol_examples_common.h" +#include "esp_log.h" + +static const char *TAG = "PUBLISH_CONNECT_TEST"; + +void connection_test(const char* line); +void publish_test(const char* line); + +static void get_string(char *line, size_t size) +{ + int count = 0; + while (count < size) { + int c = fgetc(stdin); + if (c == '\n') { + line[count] = '\0'; + break; + } else if (c > 0 && c < 127) { + line[count] = c; + ++count; + } + vTaskDelay(10 / portTICK_PERIOD_MS); + } +} + +void app_main(void) +{ + char line[256]; + + ESP_LOGI(TAG, "[APP] Free memory: %d bytes", esp_get_free_heap_size()); + ESP_LOGI(TAG, "[APP] IDF version: %s", esp_get_idf_version()); + + esp_log_level_set("*", ESP_LOG_INFO); + esp_log_level_set("MQTT_CLIENT", ESP_LOG_VERBOSE); + esp_log_level_set("TRANSPORT_TCP", ESP_LOG_VERBOSE); + esp_log_level_set("TRANSPORT_SSL", ESP_LOG_VERBOSE); + esp_log_level_set("TRANSPORT", ESP_LOG_VERBOSE); + esp_log_level_set("OUTBOX", ESP_LOG_VERBOSE); + + ESP_ERROR_CHECK(nvs_flash_init()); + ESP_ERROR_CHECK(esp_netif_init()); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + + /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. + * Read "Establishing Wi-Fi or Ethernet Connection" section in + * examples/protocols/README.md for more information about this function. + */ + ESP_ERROR_CHECK(example_connect()); + + while (1) { + get_string(line, sizeof(line)); + if (memcmp(line, "conn", 4) == 0) { + // line starting with "conn" indicate connection tests + connection_test(line); + get_string(line, sizeof(line)); + continue; + } else { + publish_test(line); + } + } + +} \ No newline at end of file diff --git a/examples/protocols/mqtt/publish_connect_test/main/publish_test.c b/examples/protocols/mqtt/publish_connect_test/main/publish_test.c new file mode 100644 index 000000000..c78a84e0d --- /dev/null +++ b/examples/protocols/mqtt/publish_connect_test/main/publish_test.c @@ -0,0 +1,175 @@ +/* MQTT publish test + + 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 +#include +#include +#include "esp_system.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/event_groups.h" + +#include "esp_log.h" +#include "mqtt_client.h" + +static const char *TAG = "PUBLISH_TEST"; + +static EventGroupHandle_t mqtt_event_group; +const static int CONNECTED_BIT = BIT0; + +static esp_mqtt_client_handle_t mqtt_client = NULL; + +static char *expected_data = NULL; +static char *actual_data = NULL; +static size_t expected_size = 0; +static size_t expected_published = 0; +static size_t actual_published = 0; +static int qos_test = 0; + + #if CONFIG_EXAMPLE_BROKER_CERTIFICATE_OVERRIDDEN == 1 + static const uint8_t mqtt_eclipse_org_pem_start[] = "-----BEGIN CERTIFICATE-----\n" CONFIG_EXAMPLE_BROKER_CERTIFICATE_OVERRIDE "\n-----END CERTIFICATE-----"; + #else + extern const uint8_t mqtt_eclipse_org_pem_start[] asm("_binary_mqtt_eclipse_org_pem_start"); + #endif + extern const uint8_t mqtt_eclipse_org_pem_end[] asm("_binary_mqtt_eclipse_org_pem_end"); + +static esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t event) +{ + esp_mqtt_client_handle_t client = event->client; + static int msg_id = 0; + static int actual_len = 0; + // your_context_t *context = event->context; + switch (event->event_id) { + case MQTT_EVENT_CONNECTED: + ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED"); + xEventGroupSetBits(mqtt_event_group, CONNECTED_BIT); + msg_id = esp_mqtt_client_subscribe(client, CONFIG_EXAMPLE_SUBSCIBE_TOPIC, qos_test); + ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id); + + break; + case MQTT_EVENT_DISCONNECTED: + ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED"); + break; + + case MQTT_EVENT_SUBSCRIBED: + ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id); + break; + case MQTT_EVENT_UNSUBSCRIBED: + ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id); + break; + case MQTT_EVENT_PUBLISHED: + ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id); + break; + case MQTT_EVENT_DATA: + ESP_LOGI(TAG, "MQTT_EVENT_DATA"); + printf("TOPIC=%.*s\r\n", event->topic_len, event->topic); + printf("DATA=%.*s\r\n", event->data_len, event->data); + printf("ID=%d, total_len=%d, data_len=%d, current_data_offset=%d\n", event->msg_id, event->total_data_len, event->data_len, event->current_data_offset); + if (event->topic) { + actual_len = event->data_len; + msg_id = event->msg_id; + } else { + actual_len += event->data_len; + // check consisency with msg_id across multiple data events for single msg + if (msg_id != event->msg_id) { + ESP_LOGI(TAG, "Wrong msg_id in chunked message %d != %d", msg_id, event->msg_id); + abort(); + } + } + memcpy(actual_data + event->current_data_offset, event->data, event->data_len); + if (actual_len == event->total_data_len) { + if (0 == memcmp(actual_data, expected_data, expected_size)) { + printf("OK!"); + memset(actual_data, 0, expected_size); + actual_published ++; + if (actual_published == expected_published) { + printf("Correct pattern received exactly x times\n"); + ESP_LOGI(TAG, "Test finished correctly!"); + } + } else { + printf("FAILED!"); + abort(); + } + } + break; + case MQTT_EVENT_ERROR: + ESP_LOGI(TAG, "MQTT_EVENT_ERROR"); + break; + default: + ESP_LOGI(TAG, "Other event id:%d", event->event_id); + break; + } + return ESP_OK; +} + + +static void mqtt_app_start(void) +{ + mqtt_event_group = xEventGroupCreate(); + const esp_mqtt_client_config_t mqtt_cfg = { + .event_handle = mqtt_event_handler, + .cert_pem = (const char *)mqtt_eclipse_org_pem_start, + }; + + ESP_LOGI(TAG, "[APP] Free memory: %d bytes", esp_get_free_heap_size()); + mqtt_client = esp_mqtt_client_init(&mqtt_cfg); +} + +void publish_test(const char* line) +{ + char pattern[32]; + char transport[32]; + int repeat = 0; + static bool is_mqtt_init = false; + + if (!is_mqtt_init) { + mqtt_app_start(); + is_mqtt_init = true; + } + sscanf(line, "%s %s %d %d %d", transport, pattern, &repeat, &expected_published, &qos_test); + ESP_LOGI(TAG, "PATTERN:%s REPEATED:%d PUBLISHED:%d\n", pattern, repeat, expected_published); + int pattern_size = strlen(pattern); + free(expected_data); + free(actual_data); + actual_published = 0; + expected_size = pattern_size * repeat; + expected_data = malloc(expected_size); + actual_data = malloc(expected_size); + for (int i = 0; i < repeat; i++) { + memcpy(expected_data + i * pattern_size, pattern, pattern_size); + } + printf("EXPECTED STRING %.*s, SIZE:%d\n", expected_size, expected_data, expected_size); + esp_mqtt_client_stop(mqtt_client); + + if (0 == strcmp(transport, "tcp")) { + ESP_LOGI(TAG, "[TCP transport] Startup.."); + esp_mqtt_client_set_uri(mqtt_client, CONFIG_EXAMPLE_BROKER_TCP_URI); + } else if (0 == strcmp(transport, "ssl")) { + ESP_LOGI(TAG, "[SSL transport] Startup.."); + esp_mqtt_client_set_uri(mqtt_client, CONFIG_EXAMPLE_BROKER_SSL_URI); + } else if (0 == strcmp(transport, "ws")) { + ESP_LOGI(TAG, "[WS transport] Startup.."); + esp_mqtt_client_set_uri(mqtt_client, CONFIG_EXAMPLE_BROKER_WS_URI); + } else if (0 == strcmp(transport, "wss")) { + ESP_LOGI(TAG, "[WSS transport] Startup.."); + esp_mqtt_client_set_uri(mqtt_client, CONFIG_EXAMPLE_BROKER_WSS_URI); + } else { + ESP_LOGE(TAG, "Unexpected transport"); + abort(); + } + xEventGroupClearBits(mqtt_event_group, CONNECTED_BIT); + esp_mqtt_client_start(mqtt_client); + ESP_LOGI(TAG, "Note free memory: %d bytes", esp_get_free_heap_size()); + xEventGroupWaitBits(mqtt_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); + + for (int i = 0; i < expected_published; i++) { + int msg_id = esp_mqtt_client_publish(mqtt_client, CONFIG_EXAMPLE_PUBLISH_TOPIC, expected_data, expected_size, qos_test, 0); + ESP_LOGI(TAG, "[%d] Publishing...", msg_id); + } +} diff --git a/examples/protocols/mqtt/publish_test/sdkconfig.ci b/examples/protocols/mqtt/publish_connect_test/sdkconfig.ci similarity index 100% rename from examples/protocols/mqtt/publish_test/sdkconfig.ci rename to examples/protocols/mqtt/publish_connect_test/sdkconfig.ci diff --git a/examples/protocols/mqtt/publish_test/sdkconfig.qemu b/examples/protocols/mqtt/publish_connect_test/sdkconfig.qemu similarity index 100% rename from examples/protocols/mqtt/publish_test/sdkconfig.qemu rename to examples/protocols/mqtt/publish_connect_test/sdkconfig.qemu diff --git a/examples/protocols/mqtt/publish_connect_test/server.key b/examples/protocols/mqtt/publish_connect_test/server.key new file mode 100644 index 000000000..2a4d650ea --- /dev/null +++ b/examples/protocols/mqtt/publish_connect_test/server.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEAlUCywNhVv4RO2y9h/XGKZ1azzk3jzHpSBzIGO9LoiA8trC/p +1ykGaUfYPJllYK4HMhC4fUyE3J7tVL2Eskzl26LNPLbEoaBWZM9NhV3iA1/1EtOu +p6umLx+y3sDfvK35YAOUbjdAlBfhnJ4r8h7oTsxl3J5jZ18zgjJnJi2NEFq/yTpO +MiwHLWPjy25fDFixfV9UzSvbgt1JaGPmC7c4QkhHzjyp0+ikuvRIw0p9BBNeqBV2 +da3qBMB5FtodUJTAz6o6OKWbTalLjQi6C1H6z9TnY7IrJBUOy/FWkQH/sEsLdscD +hHa1Dz2oT203QjhzyOSfnNF95D/1MdNcMt6l0wIDAQABAoIBAC1JJTOoMFRc48RT +myrYQYNbZlEphv3q+2qdfhC2zMFDwbrmCtCy7PQSzYSNkpoEE8DYG/JAvmtmeWJl +4pZrCK9ctWM/nWfhC3WpBL97nfEiM20T94F+bn0L5Cz8XqaULv839th+QUTt/hGU +WIctY5VNJXcMQ+MAmtNdUbjex1d3iuxiKHUo4nDoZ8digKFNdtdP5B5nlMq5chCL +mxNRcsGsx2dDAxbGUapdTVPWHPJKpLOBoSkluDsfd2KZADFU2R1SJpAX9+RYh3HM +5FTUdHTUaISxbKkgeDKlEM0lqk2TtGUwCyEj098ewi7Wzsu9w60IplPPUJx5FRG6 +jp3wzLkCgYEAxKp5T20rf/7ysX7x053I7VCjDXUxAaWOEj1uS3AhOkl0NaZg7Di+ +y53fWNkcHdkt2n2LqMt/43UgMYq3TVVcq2eunPNF11e1bJw8CjDafwDs4omwwyVn +lYhPuB4dK2OAib+vU5Zqpp0kZMoxk2MZVgon8z+s8DW/zmB6aFqAWeUCgYEAwkhC +OgmXKMdjOCVy5t2f5UbY8Y9rV3w8eUATuJ47MMwLr4pGYnKoEn9JB4ltWrHv/u5S +fOv3tIrrCEvnCoCbOILwCsY5LqTNXgqova8FB6RpMUQCzhDd8LHuvdHv0WMnMzX1 +3PKuqwh8JS55m4WqZRhzr5BFKG4fHPVs4IcaJVcCgYAzzCaJSdqUKqTnJOUydDNQ +ddWMHNqccWs62J0tF0pZHLGT089hSAzQejMyJnSmU+Ykzr4y5e44DUg+ZCelIZ93 +saYmxlgVwI8THQ8fLADQRIEfpV4996MRmkZM2vmZzOo03Zyi6lIKsga82Rg3lnk8 +1Q3ynknBNpbfF0AGLhfyFQKBgBYlxJ73HutAJ5hr9HhLBYJOnEaVUehMOlycKGNg +bmD2sdJWEgYBChXpurqIORYguLo4EuE4ySkkuPxeIr14wbkkfBbOWBBwKxUwY+IT +xKAFZxR9q1AwbgyVTCEJgKw/AGX/HcMNS0omEnjunmBTUYRq0C1QZgHg490aQUor +PJjLAoGAevzdTpFlVeuKeYh1oDubGO1LinyXpBv7fPFjl+zu4AVbjojcU6yC4OO6 +QvqopE6SyAECKy8kAOFcESPsGc9Lta2XUvI203z7pIVlNVEcJ0+90mQh3Mn1U46l +sZ49PdRvNwNb5wvkh1UqNsMlGFbRlzMbIk45ou4311kCobowZek= +-----END RSA PRIVATE KEY----- diff --git a/examples/protocols/mqtt/publish_test/CMakeLists.txt b/examples/protocols/mqtt/publish_test/CMakeLists.txt deleted file mode 100644 index 4a46af3e5..000000000 --- a/examples/protocols/mqtt/publish_test/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -# The following four lines of boilerplate have to be in your project's CMakeLists -# in this exact order for cmake to work correctly -cmake_minimum_required(VERSION 3.5) - -# (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(mqtt_publish) - -target_add_binary_data(mqtt_publish.elf "main/mqtt_eclipse_org.pem" TEXT) diff --git a/examples/protocols/mqtt/publish_test/main/CMakeLists.txt b/examples/protocols/mqtt/publish_test/main/CMakeLists.txt deleted file mode 100644 index 67c4c7b5a..000000000 --- a/examples/protocols/mqtt/publish_test/main/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -idf_component_register(SRCS "publish_test.c" - INCLUDE_DIRS ".") \ No newline at end of file diff --git a/examples/protocols/mqtt/publish_test/main/component.mk b/examples/protocols/mqtt/publish_test/main/component.mk deleted file mode 100644 index 597752fb9..000000000 --- a/examples/protocols/mqtt/publish_test/main/component.mk +++ /dev/null @@ -1 +0,0 @@ -COMPONENT_EMBED_TXTFILES := mqtt_eclipse_org.pem diff --git a/examples/protocols/mqtt/publish_test/main/publish_test.c b/examples/protocols/mqtt/publish_test/main/publish_test.c deleted file mode 100644 index b6b7e53a6..000000000 --- a/examples/protocols/mqtt/publish_test/main/publish_test.c +++ /dev/null @@ -1,226 +0,0 @@ -/* MQTT publish test - - 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 -#include -#include -#include "esp_wifi.h" -#include "esp_system.h" -#include "nvs_flash.h" -#include "esp_event.h" -#include "esp_netif.h" -#include "protocol_examples_common.h" - -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/semphr.h" -#include "freertos/queue.h" -#include "freertos/event_groups.h" - -#include "lwip/sockets.h" -#include "lwip/dns.h" -#include "lwip/netdb.h" - -#include "esp_log.h" -#include "mqtt_client.h" - -static const char *TAG = "PUBLISH_TEST"; - -static EventGroupHandle_t mqtt_event_group; -const static int CONNECTED_BIT = BIT0; - -static esp_mqtt_client_handle_t mqtt_client = NULL; - -static char *expected_data = NULL; -static char *actual_data = NULL; -static size_t expected_size = 0; -static size_t expected_published = 0; -static size_t actual_published = 0; -static int qos_test = 0; - - -#if CONFIG_EXAMPLE_BROKER_CERTIFICATE_OVERRIDDEN == 1 -static const uint8_t mqtt_eclipse_org_pem_start[] = "-----BEGIN CERTIFICATE-----\n" CONFIG_EXAMPLE_BROKER_CERTIFICATE_OVERRIDE "\n-----END CERTIFICATE-----"; -#else -extern const uint8_t mqtt_eclipse_org_pem_start[] asm("_binary_mqtt_eclipse_org_pem_start"); -#endif -extern const uint8_t mqtt_eclipse_org_pem_end[] asm("_binary_mqtt_eclipse_org_pem_end"); - -static esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t event) -{ - esp_mqtt_client_handle_t client = event->client; - static int msg_id = 0; - static int actual_len = 0; - // your_context_t *context = event->context; - switch (event->event_id) { - case MQTT_EVENT_CONNECTED: - ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED"); - xEventGroupSetBits(mqtt_event_group, CONNECTED_BIT); - msg_id = esp_mqtt_client_subscribe(client, CONFIG_EXAMPLE_SUBSCIBE_TOPIC, qos_test); - ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id); - - break; - case MQTT_EVENT_DISCONNECTED: - ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED"); - break; - - case MQTT_EVENT_SUBSCRIBED: - ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id); - break; - case MQTT_EVENT_UNSUBSCRIBED: - ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id); - break; - case MQTT_EVENT_PUBLISHED: - ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id); - break; - case MQTT_EVENT_DATA: - ESP_LOGI(TAG, "MQTT_EVENT_DATA"); - printf("TOPIC=%.*s\r\n", event->topic_len, event->topic); - printf("DATA=%.*s\r\n", event->data_len, event->data); - printf("ID=%d, total_len=%d, data_len=%d, current_data_offset=%d\n", event->msg_id, event->total_data_len, event->data_len, event->current_data_offset); - if (event->topic) { - actual_len = event->data_len; - msg_id = event->msg_id; - } else { - actual_len += event->data_len; - // check consisency with msg_id across multiple data events for single msg - if (msg_id != event->msg_id) { - ESP_LOGI(TAG, "Wrong msg_id in chunked message %d != %d", msg_id, event->msg_id); - abort(); - } - } - memcpy(actual_data + event->current_data_offset, event->data, event->data_len); - if (actual_len == event->total_data_len) { - if (0 == memcmp(actual_data, expected_data, expected_size)) { - printf("OK!"); - memset(actual_data, 0, expected_size); - actual_published ++; - if (actual_published == expected_published) { - printf("Correct pattern received exactly x times\n"); - ESP_LOGI(TAG, "Test finished correctly!"); - } - } else { - printf("FAILED!"); - abort(); - } - } - break; - case MQTT_EVENT_ERROR: - ESP_LOGI(TAG, "MQTT_EVENT_ERROR"); - break; - default: - ESP_LOGI(TAG, "Other event id:%d", event->event_id); - break; - } - return ESP_OK; -} - - -static void mqtt_app_start(void) -{ - mqtt_event_group = xEventGroupCreate(); - const esp_mqtt_client_config_t mqtt_cfg = { - .event_handle = mqtt_event_handler, - .cert_pem = (const char *)mqtt_eclipse_org_pem_start, - }; - - ESP_LOGI(TAG, "[APP] Free memory: %d bytes", esp_get_free_heap_size()); - mqtt_client = esp_mqtt_client_init(&mqtt_cfg); -} - -static void get_string(char *line, size_t size) -{ - - int count = 0; - while (count < size) { - int c = fgetc(stdin); - if (c == '\n') { - line[count] = '\0'; - break; - } else if (c > 0 && c < 127) { - line[count] = c; - ++count; - } - vTaskDelay(10 / portTICK_PERIOD_MS); - } -} - -void app_main(void) -{ - char line[256]; - char pattern[32]; - char transport[32]; - int repeat = 0; - - ESP_LOGI(TAG, "[APP] Free memory: %d bytes", esp_get_free_heap_size()); - ESP_LOGI(TAG, "[APP] IDF version: %s", esp_get_idf_version()); - - esp_log_level_set("*", ESP_LOG_INFO); - esp_log_level_set("MQTT_CLIENT", ESP_LOG_VERBOSE); - esp_log_level_set("TRANSPORT_TCP", ESP_LOG_VERBOSE); - esp_log_level_set("TRANSPORT_SSL", ESP_LOG_VERBOSE); - esp_log_level_set("TRANSPORT", ESP_LOG_VERBOSE); - esp_log_level_set("OUTBOX", ESP_LOG_VERBOSE); - - ESP_ERROR_CHECK(nvs_flash_init()); - ESP_ERROR_CHECK(esp_netif_init()); - ESP_ERROR_CHECK(esp_event_loop_create_default()); - - /* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig. - * Read "Establishing Wi-Fi or Ethernet Connection" section in - * examples/protocols/README.md for more information about this function. - */ - ESP_ERROR_CHECK(example_connect()); - - mqtt_app_start(); - - while (1) { - get_string(line, sizeof(line)); - sscanf(line, "%s %s %d %d %d", transport, pattern, &repeat, &expected_published, &qos_test); - ESP_LOGI(TAG, "PATTERN:%s REPEATED:%d PUBLISHED:%d\n", pattern, repeat, expected_published); - int pattern_size = strlen(pattern); - free(expected_data); - free(actual_data); - actual_published = 0; - expected_size = pattern_size * repeat; - expected_data = malloc(expected_size); - actual_data = malloc(expected_size); - for (int i = 0; i < repeat; i++) { - memcpy(expected_data + i * pattern_size, pattern, pattern_size); - } - printf("EXPECTED STRING %.*s, SIZE:%d\n", expected_size, expected_data, expected_size); - esp_mqtt_client_stop(mqtt_client); - - if (0 == strcmp(transport, "tcp")) { - ESP_LOGI(TAG, "[TCP transport] Startup.."); - esp_mqtt_client_set_uri(mqtt_client, CONFIG_EXAMPLE_BROKER_TCP_URI); - } else if (0 == strcmp(transport, "ssl")) { - ESP_LOGI(TAG, "[SSL transport] Startup.."); - esp_mqtt_client_set_uri(mqtt_client, CONFIG_EXAMPLE_BROKER_SSL_URI); - } else if (0 == strcmp(transport, "ws")) { - ESP_LOGI(TAG, "[WS transport] Startup.."); - esp_mqtt_client_set_uri(mqtt_client, CONFIG_EXAMPLE_BROKER_WS_URI); - } else if (0 == strcmp(transport, "wss")) { - ESP_LOGI(TAG, "[WSS transport] Startup.."); - esp_mqtt_client_set_uri(mqtt_client, CONFIG_EXAMPLE_BROKER_WSS_URI); - } else { - ESP_LOGE(TAG, "Unexpected transport"); - abort(); - } - xEventGroupClearBits(mqtt_event_group, CONNECTED_BIT); - esp_mqtt_client_start(mqtt_client); - ESP_LOGI(TAG, "Note free memory: %d bytes", esp_get_free_heap_size()); - xEventGroupWaitBits(mqtt_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); - - for (int i = 0; i < expected_published; i++) { - int msg_id = esp_mqtt_client_publish(mqtt_client, CONFIG_EXAMPLE_PUBLISH_TOPIC, expected_data, expected_size, qos_test, 0); - ESP_LOGI(TAG, "[%d] Publishing...", msg_id); - } - } -} From 911be990542e9ae9cb996a3c2899d11afc7b518a Mon Sep 17 00:00:00 2001 From: David Cermak Date: Fri, 7 Feb 2020 11:10:04 +0100 Subject: [PATCH 3/3] mqtt-tests: migrate the publish-connection test from example-test to test-apps --- .../mqtt/publish_connect_test/README.md | 85 ------------------ tools/ci/config/target-test.yml | 6 ++ .../mqtt/publish_connect_test/CMakeLists.txt | 0 .../mqtt/publish_connect_test/Makefile | 0 .../mqtt/publish_connect_test/README.md | 22 +++++ .../mqtt/publish_connect_test/app_test.py | 4 +- .../mqtt/publish_connect_test/ca.crt | 0 .../mqtt/publish_connect_test/ca.der | Bin .../mqtt/publish_connect_test/ca.key | 0 .../mqtt/publish_connect_test/client_inv.crt | 0 .../publish_connect_test/client_no_pwd.key | 0 .../mqtt/publish_connect_test/client_pwd.crt | 0 .../mqtt/publish_connect_test/client_pwd.key | 0 .../publish_connect_test/main/CMakeLists.txt | 0 .../main/Kconfig.projbuild | 0 .../publish_connect_test/main/component.mk | 0 .../publish_connect_test/main/connect_test.c | 0 .../main/mqtt_eclipse_org.pem | 0 .../main/publish_connect_test.c | 0 .../publish_connect_test/main/publish_test.c | 0 .../publish_connect_test/sdkconfig.ci.default | 0 .../mqtt/publish_connect_test/sdkconfig.qemu | 0 .../mqtt/publish_connect_test/server.key | 0 23 files changed, 30 insertions(+), 87 deletions(-) delete mode 100644 examples/protocols/mqtt/publish_connect_test/README.md rename {examples => tools/test_apps}/protocols/mqtt/publish_connect_test/CMakeLists.txt (100%) rename {examples => tools/test_apps}/protocols/mqtt/publish_connect_test/Makefile (100%) create mode 100644 tools/test_apps/protocols/mqtt/publish_connect_test/README.md rename examples/protocols/mqtt/publish_connect_test/example_test.py => tools/test_apps/protocols/mqtt/publish_connect_test/app_test.py (98%) rename {examples => tools/test_apps}/protocols/mqtt/publish_connect_test/ca.crt (100%) rename {examples => tools/test_apps}/protocols/mqtt/publish_connect_test/ca.der (100%) rename {examples => tools/test_apps}/protocols/mqtt/publish_connect_test/ca.key (100%) rename {examples => tools/test_apps}/protocols/mqtt/publish_connect_test/client_inv.crt (100%) rename {examples => tools/test_apps}/protocols/mqtt/publish_connect_test/client_no_pwd.key (100%) rename {examples => tools/test_apps}/protocols/mqtt/publish_connect_test/client_pwd.crt (100%) rename {examples => tools/test_apps}/protocols/mqtt/publish_connect_test/client_pwd.key (100%) rename {examples => tools/test_apps}/protocols/mqtt/publish_connect_test/main/CMakeLists.txt (100%) rename {examples => tools/test_apps}/protocols/mqtt/publish_connect_test/main/Kconfig.projbuild (100%) rename {examples => tools/test_apps}/protocols/mqtt/publish_connect_test/main/component.mk (100%) rename {examples => tools/test_apps}/protocols/mqtt/publish_connect_test/main/connect_test.c (100%) rename {examples => tools/test_apps}/protocols/mqtt/publish_connect_test/main/mqtt_eclipse_org.pem (100%) rename {examples => tools/test_apps}/protocols/mqtt/publish_connect_test/main/publish_connect_test.c (100%) rename {examples => tools/test_apps}/protocols/mqtt/publish_connect_test/main/publish_test.c (100%) rename examples/protocols/mqtt/publish_connect_test/sdkconfig.ci => tools/test_apps/protocols/mqtt/publish_connect_test/sdkconfig.ci.default (100%) rename {examples => tools/test_apps}/protocols/mqtt/publish_connect_test/sdkconfig.qemu (100%) rename {examples => tools/test_apps}/protocols/mqtt/publish_connect_test/server.key (100%) diff --git a/examples/protocols/mqtt/publish_connect_test/README.md b/examples/protocols/mqtt/publish_connect_test/README.md deleted file mode 100644 index 2147420a5..000000000 --- a/examples/protocols/mqtt/publish_connect_test/README.md +++ /dev/null @@ -1,85 +0,0 @@ -# ESP-MQTT advanced publish and connect test project -(See the README.md file in the upper level 'examples' directory for more information about examples.) - -Main purpose of this example is to test the MQTT library to correctly publish and receive messages (of different size and sequences) over different transports. -It is possible to run this example manually without any test to exercise how the MQTT library deals with - -- reception of fragmented messages -- runtime updates of URI - -## How to use example - -This example waits for user input to provide these parameters: -- transport: string parameter, one of: tcp, ssl, ws, wss -- pattern: sample string to be transmitted as message -- pattern repeats: number of repeats of pattern in one MQTT message -- repeated: number of repeats ESP32 publishes the message, also ESP32 expects to receive the same message the same number of repeats -- qos: number specifying qos, one of: 0, 1, 2 - -### Hardware Required - -This example can be executed on any ESP32 board, the only required interface is WiFi and connection to internet. - -### Configure the project - -* Open the project configuration menu (`idf.py menuconfig`) -* Configure Wi-Fi or Ethernet under "Example Connection Configuration" menu. See "Establishing Wi-Fi or Ethernet Connection" section in [examples/protocols/README.md](../../README.md) for more details. -* When using Make build system, set `Default serial port` under `Serial flasher config`. -* Set brokers for all 4 transports (TCP, SSL, WS, WSS), also set certificate if needed -* Set topics for publishing from and to ESP32 - -### Build and Flash - -Build the project and flash it to the board, then run monitor tool to view serial output: - -``` -idf.py -p PORT flash monitor -``` - -(To exit the serial monitor, type ``Ctrl-]``.) - -See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. - -## Example Output - -``` -I (4730) event: sta ip: 192.168.0.125, mask: 255.255.255.0, gw: 192.168.0.2 -I (4730) PUBLISH_TEST: [APP] Free memory: 236728 bytes -I (4730) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE -D (4740) MQTT_CLIENT: MQTT client_id=ESP32_09885C -I (31360) PUBLISH_TEST: PATTERN:1234 REPEATED:10 PUBLISHED:10 -``` -- User enters "tcp 1234 10 10 1" -``` -EXPECTED STRING 1234123412341234123412341234123412341234, SIZE:40 -W (31360) MQTT_CLIENT: Client asked to stop, but was not started -I (31360) PUBLISH_TEST: [TCP transport] Startup.. -D (31370) MQTT_CLIENT: Core selection disabled -I (31370) PUBLISH_TEST: Note free memory: 224652 bytes -I (31370) PUBLISH_TEST: Other event id:7 -D (31390) MQTT_CLIENT: Transport connected to mqtt://192.168.0.163:1883 -I (31400) MQTT_CLIENT: Sending MQTT CONNECT message, type: 1, id: 0000 -D (31410) MQTT_CLIENT: Connected -I (31410) PUBLISH_TEST: MQTT_EVENT_CONNECTED -D (31410) MQTT_CLIENT: mqtt_enqueue id: 31184, type=8 successful -D (31410) OUTBOX: ENQUEUE msgid=31184, msg_type=8, len=20, size=20 -D (31420) MQTT_CLIENT: Sent subscribe topic=/xxx.topic123, id: 31184, type=8 successful -I (31430) PUBLISH_TEST: sent subscribe successful, msg_id=31184 -D (31440) MQTT_CLIENT: mqtt_enqueue id: 16584, type=3 successful -D (31440) OUTBOX: ENQUEUE msgid=16584, msg_type=3, len=59, size=79 -I (31450) PUBLISH_TEST: [16584] Publishing... -D (31450) MQTT_CLIENT: msg_type=9, msg_id=31184 -D (31460) MQTT_CLIENT: pending_id=16584, pending_msg_count = 2 -D (31460) OUTBOX: DELETED msgid=31184, msg_type=8, remain size=59 -D (31470) MQTT_CLIENT: Subscribe successful -I (31470) PUBLISH_TEST: MQTT_EVENT_SUBSCRIBED, msg_id=31184 -D (31480) MQTT_CLIENT: msg_type=4, msg_id=16584 -D (31480) MQTT_CLIENT: pending_id=16584, pending_msg_count = 1 -D (31490) OUTBOX: DELETED msgid=16584, msg_type=3, remain size=0 -D (31500) MQTT_CLIENT: received MQTT_MSG_TYPE_PUBACK, finish QoS1 publish -I (31500) PUBLISH_TEST: MQTT_EVENT_PUBLISHED, msg_id=16584 -D (31510) MQTT_CLIENT: mqtt_enqueue id: 44615, type=3 successful -D (31520) OUTBOX: ENQUEUE msgid=44615, msg_type=3, len=59, size=59 -I (31530) PUBLISH_TEST: [44615] Publishing... -... -``` diff --git a/tools/ci/config/target-test.yml b/tools/ci/config/target-test.yml index 3384d3cd0..28f8cf9d0 100644 --- a/tools/ci/config/target-test.yml +++ b/tools/ci/config/target-test.yml @@ -308,6 +308,12 @@ test_app_test_001: - ESP32 - test_jtag_arm +test_app_test_002: + extends: .test_app_template + tags: + - ESP32 + - Example_WIFI + example_test_011: extends: .example_debug_template tags: diff --git a/examples/protocols/mqtt/publish_connect_test/CMakeLists.txt b/tools/test_apps/protocols/mqtt/publish_connect_test/CMakeLists.txt similarity index 100% rename from examples/protocols/mqtt/publish_connect_test/CMakeLists.txt rename to tools/test_apps/protocols/mqtt/publish_connect_test/CMakeLists.txt diff --git a/examples/protocols/mqtt/publish_connect_test/Makefile b/tools/test_apps/protocols/mqtt/publish_connect_test/Makefile similarity index 100% rename from examples/protocols/mqtt/publish_connect_test/Makefile rename to tools/test_apps/protocols/mqtt/publish_connect_test/Makefile diff --git a/tools/test_apps/protocols/mqtt/publish_connect_test/README.md b/tools/test_apps/protocols/mqtt/publish_connect_test/README.md new file mode 100644 index 000000000..fe866d171 --- /dev/null +++ b/tools/test_apps/protocols/mqtt/publish_connect_test/README.md @@ -0,0 +1,22 @@ +# ESP-MQTT advanced publish and connect test project + +Main purpose of this application is to test the MQTT library to correctly publish and receive messages (of different size and sequences) over different transports. +It is possible to run this example manually without any test to exercise how the MQTT library deals with + +- reception of fragmented messages +- runtime updates of URI + +## Runtime settings + +This app waits for user input to provide these parameters: +- test-type: "conn" if connection test (host, port, test-case number) +- publish test: + * transport: string parameter, one of: tcp, ssl, ws, wss + * pattern: sample string to be transmitted as message + * pattern repeats: number of repeats of pattern in one MQTT message + * repeated: number of repeats ESP32 publishes the message, also ESP32 expects to receive the same message the same number of repeats + * qos: number specifying qos, one of: 0, 1, 2 + +## Hardware Required + +This test-app can be executed on any ESP32 board, the only required interface is WiFi and connection to a local network, then depending on the test either a mqtt test broker or a tls server. diff --git a/examples/protocols/mqtt/publish_connect_test/example_test.py b/tools/test_apps/protocols/mqtt/publish_connect_test/app_test.py similarity index 98% rename from examples/protocols/mqtt/publish_connect_test/example_test.py rename to tools/test_apps/protocols/mqtt/publish_connect_test/app_test.py index ccc3e06ee..83f85c3bd 100644 --- a/examples/protocols/mqtt/publish_connect_test/example_test.py +++ b/tools/test_apps/protocols/mqtt/publish_connect_test/app_test.py @@ -130,7 +130,7 @@ class TlsServer: self.shutdown.set() -@ttfw_idf.idf_example_test(env_tag="Example_WIFI") +@ttfw_idf.idf_custom_test(env_tag="Example_WIFI", group="test-apps") def test_examples_protocol_mqtt_publish_connect(env, extra_data): """ steps: @@ -138,7 +138,7 @@ def test_examples_protocol_mqtt_publish_connect(env, extra_data): 2. connect to uri specified in the config 3. send and receive data """ - dut1 = env.get_dut("mqtt_publish_connect_test", "examples/protocols/mqtt/publish_connect_test", dut_class=ttfw_idf.ESP32DUT) + dut1 = env.get_dut("mqtt_publish_connect_test", "tools/test_apps/protocols/mqtt/publish_connect_test", dut_class=ttfw_idf.ESP32DUT) # check and log bin size binary_file = os.path.join(dut1.app.binary_path, "mqtt_publish_connect_test.bin") bin_size = os.path.getsize(binary_file) diff --git a/examples/protocols/mqtt/publish_connect_test/ca.crt b/tools/test_apps/protocols/mqtt/publish_connect_test/ca.crt similarity index 100% rename from examples/protocols/mqtt/publish_connect_test/ca.crt rename to tools/test_apps/protocols/mqtt/publish_connect_test/ca.crt diff --git a/examples/protocols/mqtt/publish_connect_test/ca.der b/tools/test_apps/protocols/mqtt/publish_connect_test/ca.der similarity index 100% rename from examples/protocols/mqtt/publish_connect_test/ca.der rename to tools/test_apps/protocols/mqtt/publish_connect_test/ca.der diff --git a/examples/protocols/mqtt/publish_connect_test/ca.key b/tools/test_apps/protocols/mqtt/publish_connect_test/ca.key similarity index 100% rename from examples/protocols/mqtt/publish_connect_test/ca.key rename to tools/test_apps/protocols/mqtt/publish_connect_test/ca.key diff --git a/examples/protocols/mqtt/publish_connect_test/client_inv.crt b/tools/test_apps/protocols/mqtt/publish_connect_test/client_inv.crt similarity index 100% rename from examples/protocols/mqtt/publish_connect_test/client_inv.crt rename to tools/test_apps/protocols/mqtt/publish_connect_test/client_inv.crt diff --git a/examples/protocols/mqtt/publish_connect_test/client_no_pwd.key b/tools/test_apps/protocols/mqtt/publish_connect_test/client_no_pwd.key similarity index 100% rename from examples/protocols/mqtt/publish_connect_test/client_no_pwd.key rename to tools/test_apps/protocols/mqtt/publish_connect_test/client_no_pwd.key diff --git a/examples/protocols/mqtt/publish_connect_test/client_pwd.crt b/tools/test_apps/protocols/mqtt/publish_connect_test/client_pwd.crt similarity index 100% rename from examples/protocols/mqtt/publish_connect_test/client_pwd.crt rename to tools/test_apps/protocols/mqtt/publish_connect_test/client_pwd.crt diff --git a/examples/protocols/mqtt/publish_connect_test/client_pwd.key b/tools/test_apps/protocols/mqtt/publish_connect_test/client_pwd.key similarity index 100% rename from examples/protocols/mqtt/publish_connect_test/client_pwd.key rename to tools/test_apps/protocols/mqtt/publish_connect_test/client_pwd.key diff --git a/examples/protocols/mqtt/publish_connect_test/main/CMakeLists.txt b/tools/test_apps/protocols/mqtt/publish_connect_test/main/CMakeLists.txt similarity index 100% rename from examples/protocols/mqtt/publish_connect_test/main/CMakeLists.txt rename to tools/test_apps/protocols/mqtt/publish_connect_test/main/CMakeLists.txt diff --git a/examples/protocols/mqtt/publish_connect_test/main/Kconfig.projbuild b/tools/test_apps/protocols/mqtt/publish_connect_test/main/Kconfig.projbuild similarity index 100% rename from examples/protocols/mqtt/publish_connect_test/main/Kconfig.projbuild rename to tools/test_apps/protocols/mqtt/publish_connect_test/main/Kconfig.projbuild diff --git a/examples/protocols/mqtt/publish_connect_test/main/component.mk b/tools/test_apps/protocols/mqtt/publish_connect_test/main/component.mk similarity index 100% rename from examples/protocols/mqtt/publish_connect_test/main/component.mk rename to tools/test_apps/protocols/mqtt/publish_connect_test/main/component.mk diff --git a/examples/protocols/mqtt/publish_connect_test/main/connect_test.c b/tools/test_apps/protocols/mqtt/publish_connect_test/main/connect_test.c similarity index 100% rename from examples/protocols/mqtt/publish_connect_test/main/connect_test.c rename to tools/test_apps/protocols/mqtt/publish_connect_test/main/connect_test.c diff --git a/examples/protocols/mqtt/publish_connect_test/main/mqtt_eclipse_org.pem b/tools/test_apps/protocols/mqtt/publish_connect_test/main/mqtt_eclipse_org.pem similarity index 100% rename from examples/protocols/mqtt/publish_connect_test/main/mqtt_eclipse_org.pem rename to tools/test_apps/protocols/mqtt/publish_connect_test/main/mqtt_eclipse_org.pem diff --git a/examples/protocols/mqtt/publish_connect_test/main/publish_connect_test.c b/tools/test_apps/protocols/mqtt/publish_connect_test/main/publish_connect_test.c similarity index 100% rename from examples/protocols/mqtt/publish_connect_test/main/publish_connect_test.c rename to tools/test_apps/protocols/mqtt/publish_connect_test/main/publish_connect_test.c diff --git a/examples/protocols/mqtt/publish_connect_test/main/publish_test.c b/tools/test_apps/protocols/mqtt/publish_connect_test/main/publish_test.c similarity index 100% rename from examples/protocols/mqtt/publish_connect_test/main/publish_test.c rename to tools/test_apps/protocols/mqtt/publish_connect_test/main/publish_test.c diff --git a/examples/protocols/mqtt/publish_connect_test/sdkconfig.ci b/tools/test_apps/protocols/mqtt/publish_connect_test/sdkconfig.ci.default similarity index 100% rename from examples/protocols/mqtt/publish_connect_test/sdkconfig.ci rename to tools/test_apps/protocols/mqtt/publish_connect_test/sdkconfig.ci.default diff --git a/examples/protocols/mqtt/publish_connect_test/sdkconfig.qemu b/tools/test_apps/protocols/mqtt/publish_connect_test/sdkconfig.qemu similarity index 100% rename from examples/protocols/mqtt/publish_connect_test/sdkconfig.qemu rename to tools/test_apps/protocols/mqtt/publish_connect_test/sdkconfig.qemu diff --git a/examples/protocols/mqtt/publish_connect_test/server.key b/tools/test_apps/protocols/mqtt/publish_connect_test/server.key similarity index 100% rename from examples/protocols/mqtt/publish_connect_test/server.key rename to tools/test_apps/protocols/mqtt/publish_connect_test/server.key