chore: Adds pre-commit checks and introduce conventional commits

This commit is contained in:
Euripedes Rocha Filho
2025-09-25 15:49:41 +02:00
parent 5b1f57f690
commit 04f8e3765d
62 changed files with 1901 additions and 872 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
dependencies:
espressif/mqtt:
version: "*"
override_path: "../../../.."
override_path: "../../../.."
+5
View File
@@ -1,3 +1,8 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
/* Build only example to check mqtt client API from C++
This example code is in the Public Domain (or CC0 licensed, at your option.)
+26 -24
View File
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -11,7 +11,6 @@
#include "esp_eth.h"
#include "esp_log.h"
#if SOC_EMAC_SUPPORTED
#define ETH_START_BIT BIT(0)
#define ETH_STOP_BIT BIT(1)
@@ -20,7 +19,6 @@
#define ETH_STOP_TIMEOUT_MS (10000)
#define ETH_GET_IP_TIMEOUT_MS (60000)
static const char *TAG = "esp32_eth_test_fixture";
static EventGroupHandle_t s_eth_event_group = NULL;
static esp_netif_t *s_eth_netif = NULL;
@@ -29,30 +27,34 @@ static esp_eth_phy_t *s_phy = NULL;
static esp_eth_handle_t s_eth_handle = NULL;
static esp_eth_netif_glue_handle_t s_eth_glue = NULL;
/** Event handler for Ethernet events */
static void eth_event_handler(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
EventGroupHandle_t eth_event_group = (EventGroupHandle_t)arg;
switch (event_id) {
case ETHERNET_EVENT_CONNECTED:
xEventGroupSetBits(eth_event_group, ETH_CONNECT_BIT);
ESP_LOGI(TAG, "Ethernet Link Up");
break;
case ETHERNET_EVENT_DISCONNECTED:
ESP_LOGI(TAG, "Ethernet Link Down");
break;
case ETHERNET_EVENT_START:
xEventGroupSetBits(eth_event_group, ETH_START_BIT);
ESP_LOGI(TAG, "Ethernet Started");
break;
case ETHERNET_EVENT_STOP:
xEventGroupSetBits(eth_event_group, ETH_STOP_BIT);
ESP_LOGI(TAG, "Ethernet Stopped");
break;
default:
break;
case ETHERNET_EVENT_CONNECTED:
xEventGroupSetBits(eth_event_group, ETH_CONNECT_BIT);
ESP_LOGI(TAG, "Ethernet Link Up");
break;
case ETHERNET_EVENT_DISCONNECTED:
ESP_LOGI(TAG, "Ethernet Link Down");
break;
case ETHERNET_EVENT_START:
xEventGroupSetBits(eth_event_group, ETH_START_BIT);
ESP_LOGI(TAG, "Ethernet Started");
break;
case ETHERNET_EVENT_STOP:
xEventGroupSetBits(eth_event_group, ETH_STOP_BIT);
ESP_LOGI(TAG, "Ethernet Stopped");
break;
default:
break;
}
}
@@ -76,12 +78,15 @@ static esp_err_t test_uninstall_driver(esp_eth_handle_t eth_hdl, uint32_t ms_to_
{
int i = 0;
ms_to_wait += 100;
for (i = 0; i < ms_to_wait / 100; i++) {
vTaskDelay(pdMS_TO_TICKS(100));
if (esp_eth_driver_uninstall(eth_hdl) == ESP_OK) {
break;
}
}
if (i < ms_to_wait / 10) {
return ESP_OK;
} else {
@@ -89,7 +94,6 @@ static esp_err_t test_uninstall_driver(esp_eth_handle_t eth_hdl, uint32_t ms_to_
}
}
void connect_test_fixture_setup(void)
{
EventBits_t bits;
@@ -99,14 +103,12 @@ void connect_test_fixture_setup(void)
// create TCP/IP netif
esp_netif_config_t netif_cfg = ESP_NETIF_DEFAULT_ETH();
s_eth_netif = esp_netif_new(&netif_cfg);
eth_mac_config_t mac_config = ETH_MAC_DEFAULT_CONFIG();
eth_esp32_emac_config_t esp32_emac_config = ETH_ESP32_EMAC_DEFAULT_CONFIG();
s_mac = esp_eth_mac_new_esp32(&esp32_emac_config, &mac_config);
eth_phy_config_t phy_config = ETH_PHY_DEFAULT_CONFIG();
s_phy = esp_eth_phy_new_ip101(&phy_config);
esp_eth_config_t eth_config = ETH_DEFAULT_CONFIG(s_mac, s_phy);
// install Ethernet driver
TEST_ESP_OK(esp_eth_driver_install(&eth_config, &s_eth_handle));
// combine driver with netif
-1
View File
@@ -2,4 +2,3 @@ dependencies:
espressif/mqtt:
version: "*"
override_path: "../../../.."
+31 -31
View File
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*
@@ -23,12 +23,14 @@
TEST_GROUP(mqtt);
TEST_SETUP(mqtt){
TEST_SETUP(mqtt)
{
test_utils_record_free_mem();
TEST_ESP_OK(test_utils_set_leak_level(0, ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_GENERAL));
}
TEST_TEAR_DOWN(mqtt){
TEST_TEAR_DOWN(mqtt)
{
test_utils_finish_and_evaluate_leaks(test_utils_get_leak_level(ESP_LEAK_TYPE_WARNING, ESP_COMP_LEAK_ALL),
test_utils_get_leak_level(ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_ALL));
}
@@ -36,87 +38,85 @@ TEST_TEAR_DOWN(mqtt){
TEST(mqtt, init_with_invalid_url)
{
const esp_mqtt_client_config_t mqtt_cfg = {
.broker.address.uri = "INVALID",
.broker.address.uri = "INVALID",
};
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
TEST_ASSERT_EQUAL(NULL, client );
TEST_ASSERT_EQUAL(NULL, client);
}
TEST(mqtt, init_and_deinit)
{
const esp_mqtt_client_config_t mqtt_cfg = {
// no connection takes place, but the uri has to be valid for init() to succeed
.broker.address.uri = "mqtts://localhost:8883",
// no connection takes place, but the uri has to be valid for init() to succeed
.broker.address.uri = "mqtts://localhost:8883",
};
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
TEST_ASSERT_NOT_EQUAL(NULL, client );
TEST_ASSERT_NOT_EQUAL(NULL, client);
esp_mqtt_client_destroy(client);
}
static const char* this_bin_addr(void)
static const char *this_bin_addr(void)
{
esp_partition_mmap_handle_t out_handle;
const void *binary_address;
const esp_partition_t* partition = esp_ota_get_running_partition();
const esp_partition_t *partition = esp_ota_get_running_partition();
esp_partition_mmap(partition, 0, partition->size, ESP_PARTITION_MMAP_DATA, &binary_address, &out_handle);
return binary_address;
}
TEST(mqtt, enqueue_and_destroy_outbox)
{
const char * bin_addr = this_bin_addr();
// Reseting leak detection since this_bin_addr adds to allocated memory.
const char *bin_addr = this_bin_addr();
// Resetting leak detection since this_bin_addr adds to allocated memory.
test_utils_record_free_mem();
TEST_ESP_OK(test_utils_set_leak_level(0, ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_GENERAL));
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
.broker.address.uri = "mqtts://localhost:8883",
// no connection takes place, but the uri has to be valid for init() to succeed
.broker.address.uri = "mqtts://localhost:8883",
};
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
TEST_ASSERT_NOT_EQUAL(NULL, client );
TEST_ASSERT_NOT_EQUAL(NULL, client);
int bytes_before = esp_get_free_heap_size();
for (int i=0; i<messages; ++i) {
for (int i = 0; i < messages; ++i) {
esp_mqtt_client_publish(client, "test", bin_addr, size, 1, 0);
}
int bytes_after = esp_get_free_heap_size();
// check that outbox allocated all messages on heap
TEST_ASSERT_GREATER_OR_EQUAL(messages*size, bytes_before - bytes_after);
TEST_ASSERT_GREATER_OR_EQUAL(messages * size, bytes_before - bytes_after);
esp_mqtt_client_destroy(client);
}
#if SOC_EMAC_SUPPORTED
/**
* This test cases uses ethernet kit, so build and use it only if EMAC supported
* This test cases uses ethernet kit, so build and use it only if EMACS supported
*/
TEST(mqtt, broker_tests)
{
test_case_uses_tcpip();
connect_test_fixture_setup();
RUN_MQTT_BROKER_TEST(mqtt_connect_disconnect);
RUN_MQTT_BROKER_TEST(mqtt_subscribe_publish);
RUN_MQTT_BROKER_TEST(mqtt_lwt_clean_disconnect);
RUN_MQTT_BROKER_TEST(mqtt_subscribe_payload);
connect_test_fixture_teardown();
}
#endif // SOC_EMAC_SUPPORTED
TEST_GROUP_RUNNER(mqtt) {
RUN_TEST_CASE(mqtt, init_with_invalid_url);
RUN_TEST_CASE(mqtt, init_and_deinit);
RUN_TEST_CASE(mqtt, enqueue_and_destroy_outbox);
TEST_GROUP_RUNNER(mqtt)
{
RUN_TEST_CASE(mqtt, init_with_invalid_url);
RUN_TEST_CASE(mqtt, init_and_deinit);
RUN_TEST_CASE(mqtt, enqueue_and_destroy_outbox);
#if SOC_EMAC_SUPPORTED
RUN_TEST_CASE(mqtt, broker_tests);
RUN_TEST_CASE(mqtt, broker_tests);
#endif // SOC_EMAC_SUPPORTED
}
void app_main(void){
UNITY_MAIN(mqtt);
void app_main(void)
{
UNITY_MAIN(mqtt);
}
+39 -38
View File
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -22,7 +22,6 @@
} \
} while(0)
static const int COMMON_OPERATION_TIMEOUT = 10000;
static const int CONNECT_BIT = BIT0;
static const int DISCONNECT_BIT = BIT1;
@@ -30,7 +29,7 @@ static const int DATA_BIT = BIT2;
static EventGroupHandle_t s_event_group;
static char* append_mac(const char* string)
static char *append_mac(const char *string)
{
uint8_t mac[6];
char *id_string = NULL;
@@ -43,7 +42,7 @@ static void mqtt_data_handler_qos(void *handler_args, esp_event_base_t base, int
{
if (event_id == MQTT_EVENT_DATA) {
esp_mqtt_event_handle_t event = event_data;
int * qos = handler_args;
int *qos = handler_args;
*qos = event->qos;
xEventGroupSetBits(s_event_group, DATA_BIT);
}
@@ -56,12 +55,13 @@ static void mqtt_data_handler_lwt(void *handler_args, esp_event_base_t base, int
ESP_LOGI("mqtt-lwt", "MQTT_EVENT_DATA");
ESP_LOGI("mqtt-lwt", "TOPIC=%.*s", event->topic_len, event->topic);
ESP_LOGI("mqtt-lwt", "DATA=%.*s", event->data_len, event->data);
if (strncmp(event->data, "no-lwt", event->data_len) == 0) {
// no lwt, just to indicate the test has finished
xEventGroupSetBits(s_event_group, DATA_BIT);
} else {
// count up any potential lwt message
int * count = handler_args;
int *count = handler_args;
*count = *count + 1;
ESP_LOGE("mqtt-lwt", "count=%d", *count);
}
@@ -73,40 +73,42 @@ static void mqtt_data_handler_subscribe(void *handler_args, esp_event_base_t bas
if (event_id == MQTT_EVENT_SUBSCRIBED) {
esp_mqtt_event_handle_t event = event_data;
ESP_LOGI("mqtt-subscribe", "MQTT_EVENT_SUBSCRIBED, data size=%d", event->data_len);
int * sub_payload = handler_args;
int *sub_payload = handler_args;
if (event->data_len == 1) {
ESP_LOGI("mqtt-subscribe", "DATA=%d", *(uint8_t*)event->data);
*sub_payload = *(uint8_t*)event->data;
ESP_LOGI("mqtt-subscribe", "DATA=%d", *(uint8_t *)event->data);
*sub_payload = *(uint8_t *)event->data;
}
xEventGroupSetBits(s_event_group, DATA_BIT);
}
}
static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
{
switch ((esp_mqtt_event_id_t)event_id) {
case MQTT_EVENT_CONNECTED:
xEventGroupSetBits(s_event_group, CONNECT_BIT);
break;
case MQTT_EVENT_CONNECTED:
xEventGroupSetBits(s_event_group, CONNECT_BIT);
break;
case MQTT_EVENT_DISCONNECTED:
xEventGroupSetBits(s_event_group, DISCONNECT_BIT);
break;
default:
break;
case MQTT_EVENT_DISCONNECTED:
xEventGroupSetBits(s_event_group, DISCONNECT_BIT);
break;
default:
break;
}
}
bool mqtt_connect_disconnect(void)
{
const esp_mqtt_client_config_t mqtt_cfg = {
.broker.address.uri = CONFIG_MQTT_TEST_BROKER_URI,
.network.disable_auto_reconnect = true,
.broker.address.uri = CONFIG_MQTT_TEST_BROKER_URI,
.network.disable_auto_reconnect = true,
};
s_event_group = xEventGroupCreate();
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
TEST_ASSERT_TRUE(NULL != client );
TEST_ASSERT_TRUE(NULL != client);
esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL);
TEST_ASSERT_TRUE(ESP_OK == esp_mqtt_client_start(client));
WAIT_FOR_EVENT(CONNECT_BIT);
@@ -122,13 +124,13 @@ bool mqtt_connect_disconnect(void)
bool mqtt_subscribe_publish(void)
{
const esp_mqtt_client_config_t mqtt_cfg = {
.broker.address.uri = CONFIG_MQTT_TEST_BROKER_URI,
.broker.address.uri = CONFIG_MQTT_TEST_BROKER_URI,
};
char* topic = append_mac("topic");
char *topic = append_mac("topic");
TEST_ASSERT_TRUE(NULL != topic);
s_event_group = xEventGroupCreate();
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
TEST_ASSERT_TRUE(NULL != client );
TEST_ASSERT_TRUE(NULL != client);
esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL);
TEST_ASSERT_TRUE(ESP_OK == esp_mqtt_client_start(client));
WAIT_FOR_EVENT(CONNECT_BIT);
@@ -149,25 +151,24 @@ bool mqtt_subscribe_publish(void)
bool mqtt_lwt_clean_disconnect(void)
{
char* lwt = append_mac("lwt");
char *lwt = append_mac("lwt");
TEST_ASSERT_TRUE(lwt);
const esp_mqtt_client_config_t mqtt_cfg1 = {
.broker.address.uri = CONFIG_MQTT_TEST_BROKER_URI,
.credentials.set_null_client_id = true,
.session.last_will.topic = lwt,
.session.last_will.msg = "lwt_msg"
.broker.address.uri = CONFIG_MQTT_TEST_BROKER_URI,
.credentials.set_null_client_id = true,
.session.last_will.topic = lwt,
.session.last_will.msg = "lwt_msg"
};
const esp_mqtt_client_config_t mqtt_cfg2 = {
.broker.address.uri = CONFIG_MQTT_TEST_BROKER_URI,
.credentials.set_null_client_id = true,
.session.last_will.topic = lwt,
.session.last_will.msg = "lwt_msg"
.broker.address.uri = CONFIG_MQTT_TEST_BROKER_URI,
.credentials.set_null_client_id = true,
.session.last_will.topic = lwt,
.session.last_will.msg = "lwt_msg"
};
s_event_group = xEventGroupCreate();
esp_mqtt_client_handle_t client1 = esp_mqtt_client_init(&mqtt_cfg1);
esp_mqtt_client_handle_t client2 = esp_mqtt_client_init(&mqtt_cfg2);
TEST_ASSERT_TRUE(NULL != client1 && NULL != client2 );
TEST_ASSERT_TRUE(NULL != client1 && NULL != client2);
esp_mqtt_client_register_event(client1, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL);
esp_mqtt_client_register_event(client2, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL);
TEST_ASSERT_TRUE(esp_mqtt_client_start(client1) == ESP_OK);
@@ -201,14 +202,14 @@ bool mqtt_lwt_clean_disconnect(void)
bool mqtt_subscribe_payload(void)
{
const esp_mqtt_client_config_t mqtt_cfg = {
.broker.address.uri = CONFIG_MQTT_TEST_BROKER_URI,
.network.disable_auto_reconnect = true,
.broker.address.uri = CONFIG_MQTT_TEST_BROKER_URI,
.network.disable_auto_reconnect = true,
};
char* topic = append_mac("topic");
char *topic = append_mac("topic");
TEST_ASSERT_TRUE(NULL != topic);
s_event_group = xEventGroupCreate();
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
TEST_ASSERT_TRUE(NULL != client );
TEST_ASSERT_TRUE(NULL != client);
esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL);
TEST_ASSERT_TRUE(ESP_OK == esp_mqtt_client_start(client));
WAIT_FOR_EVENT(CONNECT_BIT);
@@ -19,7 +19,6 @@
ESP_LOGI("mqtt_test", "Test:" #test_name "() passed "); \
} while(0)
/**
* @brief This module contains mqtt test cases interacting the client with a (real) broker
*/
+1 -1
View File
@@ -1,4 +1,4 @@
dependencies:
espressif/mqtt:
version: "*"
override_path: "../../../.."
override_path: "../../../.."
+8 -13
View File
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -15,7 +15,6 @@
#include "test_mqtt_connection.h"
#include "esp_partition.h"
TEST_GROUP(mqtt5);
TEST_SETUP(mqtt5)
@@ -43,7 +42,7 @@ TEST(mqtt5, init_with_invalid_url)
.session.protocol_ver = MQTT_PROTOCOL_V_5,
};
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt5_cfg);
TEST_ASSERT_EQUAL(NULL, client );
TEST_ASSERT_EQUAL(NULL, client);
}
TEST(mqtt5, init_and_deinit)
@@ -75,14 +74,13 @@ TEST(mqtt5, init_and_deinit)
.correlation_data = "123456",
.correlation_data_len = 6,
};
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt5_cfg);
esp_mqtt5_client_set_user_property(&connect_property.user_property, user_property_arr, 3);
esp_mqtt5_client_set_user_property(&connect_property.will_user_property, user_property_arr, 3);
esp_mqtt5_client_set_connect_property(client, &connect_property);
esp_mqtt5_client_delete_user_property(connect_property.user_property);
esp_mqtt5_client_delete_user_property(connect_property.will_user_property);
TEST_ASSERT_NOT_EQUAL(NULL, client );
TEST_ASSERT_NOT_EQUAL(NULL, client);
esp_mqtt_client_destroy(client);
}
@@ -98,7 +96,7 @@ static const char *this_bin_addr(void)
TEST(mqtt5, enqueue_and_destroy_outbox)
{
const char *bin_addr = this_bin_addr();
// Reseting leak detection since this_bin_addr adds to allocated memory.
// Resetting leak detection since this_bin_addr adds to allocated memory.
test_utils_record_free_mem();
TEST_ESP_OK(test_utils_set_leak_level(0, ESP_LEAK_TYPE_CRITICAL, ESP_COMP_LEAK_GENERAL));
const int messages = 20;
@@ -118,8 +116,9 @@ TEST(mqtt5, enqueue_and_destroy_outbox)
.content_type = "json",
};
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt5_cfg);
TEST_ASSERT_NOT_EQUAL(NULL, client );
TEST_ASSERT_NOT_EQUAL(NULL, client);
int bytes_before = esp_get_free_heap_size();
for (int i = 0; i < messages; i ++) {
esp_mqtt5_client_set_user_property(&publish_property.user_property, user_property_arr, 3);
esp_mqtt5_client_set_publish_property(client, &publish_property);
@@ -127,27 +126,25 @@ TEST(mqtt5, enqueue_and_destroy_outbox)
esp_mqtt5_client_delete_user_property(publish_property.user_property);
publish_property.user_property = NULL;
}
int bytes_after = esp_get_free_heap_size();
// check that outbox allocated all messages on heap
TEST_ASSERT_GREATER_OR_EQUAL(messages * size, bytes_before - bytes_after);
esp_mqtt_client_destroy(client);
}
#if SOC_EMAC_SUPPORTED
/**
* This test cases uses ethernet kit, so build and use it only if EMAC supported
* This test cases uses ethernet kit, so build and use it only if EMACS supported
*/
TEST(mqtt5, broker_tests)
{
test_case_uses_tcpip();
connect_test_fixture_setup();
RUN_MQTT5_BROKER_TEST(mqtt5_connect_disconnect);
RUN_MQTT5_BROKER_TEST(mqtt5_subscribe_publish);
RUN_MQTT5_BROKER_TEST(mqtt5_lwt_clean_disconnect);
RUN_MQTT5_BROKER_TEST(mqtt5_subscribe_payload);
connect_test_fixture_teardown();
}
#endif // SOC_EMAC_SUPPORTED
@@ -158,14 +155,12 @@ TEST_GROUP_RUNNER(mqtt5)
RUN_TEST_CASE(mqtt5, init_with_invalid_url);
RUN_TEST_CASE(mqtt5, init_and_deinit);
RUN_TEST_CASE(mqtt5, enqueue_and_destroy_outbox);
#if SOC_EMAC_SUPPORTED
RUN_TEST_CASE(mqtt5, broker_tests);
#endif // SOC_EMAC_SUPPORTED
#endif //!DISABLED_FOR_TARGETS(ESP32H2)
}
void app_main(void)
{
UNITY_MAIN(mqtt5);
+46 -44
View File
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -23,7 +23,6 @@
} \
} while(0)
static const int COMMON_OPERATION_TIMEOUT = 10000;
static const int CONNECT_BIT = BIT0;
static const int DISCONNECT_BIT = BIT1;
@@ -37,7 +36,7 @@ static esp_mqtt5_user_property_item_t user_property_arr[3] = {
{"p", "password"}
};
static char* append_mac(const char* string)
static char *append_mac(const char *string)
{
uint8_t mac[6];
char *id_string = NULL;
@@ -50,7 +49,7 @@ static void mqtt5_data_handler_qos(void *handler_args, esp_event_base_t base, in
{
if (event_id == MQTT_EVENT_DATA) {
esp_mqtt_event_handle_t event = event_data;
int * qos = handler_args;
int *qos = handler_args;
*qos = event->qos;
xEventGroupSetBits(s_event_group, DATA_BIT);
}
@@ -63,12 +62,13 @@ static void mqtt5_data_handler_lwt(void *handler_args, esp_event_base_t base, in
ESP_LOGI("mqtt-lwt", "MQTT_EVENT_DATA");
ESP_LOGI("mqtt-lwt", "TOPIC=%.*s", event->topic_len, event->topic);
ESP_LOGI("mqtt-lwt", "DATA=%.*s", event->data_len, event->data);
if (strncmp(event->data, "no-lwt", event->data_len) == 0) {
// no lwt, just to indicate the test has finished
xEventGroupSetBits(s_event_group, DATA_BIT);
} else {
// count up any potential lwt message
int * count = handler_args;
int *count = handler_args;
*count = *count + 1;
ESP_LOGE("mqtt5-lwt", "count=%d", *count);
}
@@ -80,37 +80,39 @@ static void mqtt5_data_handler_subscribe(void *handler_args, esp_event_base_t ba
if (event_id == MQTT_EVENT_SUBSCRIBED) {
esp_mqtt_event_handle_t event = event_data;
ESP_LOGI("mqtt5-subscribe", "MQTT_EVENT_SUBSCRIBED, data size=%d", event->data_len);
int * sub_payload = handler_args;
int *sub_payload = handler_args;
if (event->data_len == 1) {
ESP_LOGI("mqtt5-subscribe", "DATA=%d", *(uint8_t*)event->data);
*sub_payload = *(uint8_t*)event->data;
ESP_LOGI("mqtt5-subscribe", "DATA=%d", *(uint8_t *)event->data);
*sub_payload = *(uint8_t *)event->data;
}
xEventGroupSetBits(s_event_group, DATA_BIT);
}
}
static void mqtt5_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
{
switch ((esp_mqtt_event_id_t)event_id) {
case MQTT_EVENT_CONNECTED:
xEventGroupSetBits(s_event_group, CONNECT_BIT);
break;
case MQTT_EVENT_CONNECTED:
xEventGroupSetBits(s_event_group, CONNECT_BIT);
break;
case MQTT_EVENT_DISCONNECTED:
xEventGroupSetBits(s_event_group, DISCONNECT_BIT);
break;
default:
break;
case MQTT_EVENT_DISCONNECTED:
xEventGroupSetBits(s_event_group, DISCONNECT_BIT);
break;
default:
break;
}
}
bool mqtt5_connect_disconnect(void)
{
const esp_mqtt_client_config_t mqtt5_cfg = {
.broker.address.uri = CONFIG_MQTT5_TEST_BROKER_URI,
.network.disable_auto_reconnect = true,
.session.protocol_ver = MQTT_PROTOCOL_V_5,
.broker.address.uri = CONFIG_MQTT5_TEST_BROKER_URI,
.network.disable_auto_reconnect = true,
.session.protocol_ver = MQTT_PROTOCOL_V_5,
};
esp_mqtt5_connection_property_config_t connect_property = {
.session_expiry_interval = 10,
@@ -126,14 +128,15 @@ bool mqtt5_connect_disconnect(void)
};
s_event_group = xEventGroupCreate();
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt5_cfg);
TEST_ASSERT_TRUE(NULL != client );
TEST_ASSERT_TRUE(NULL != client);
esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt5_event_handler, NULL);
TEST_ASSERT_TRUE(ESP_OK == esp_mqtt5_client_set_user_property(&connect_property.user_property, user_property_arr, 3));
TEST_ASSERT_TRUE(ESP_OK == esp_mqtt5_client_set_connect_property(client, &connect_property));
esp_mqtt5_client_delete_user_property(connect_property.user_property);
TEST_ASSERT_TRUE(ESP_OK == esp_mqtt_client_start(client));
WAIT_FOR_EVENT(CONNECT_BIT);
TEST_ASSERT_TRUE(ESP_OK == esp_mqtt5_client_set_user_property(&disconnect_property.user_property, user_property_arr, 3));
TEST_ASSERT_TRUE(ESP_OK == esp_mqtt5_client_set_user_property(&disconnect_property.user_property, user_property_arr,
3));
TEST_ASSERT_TRUE(ESP_OK == esp_mqtt5_client_set_disconnect_property(client, &disconnect_property));
esp_mqtt5_client_delete_user_property(disconnect_property.user_property);
esp_mqtt_client_disconnect(client);
@@ -148,8 +151,8 @@ bool mqtt5_connect_disconnect(void)
bool mqtt5_subscribe_publish(void)
{
const esp_mqtt_client_config_t mqtt5_cfg = {
.broker.address.uri = CONFIG_MQTT5_TEST_BROKER_URI,
.session.protocol_ver = MQTT_PROTOCOL_V_5,
.broker.address.uri = CONFIG_MQTT5_TEST_BROKER_URI,
.session.protocol_ver = MQTT_PROTOCOL_V_5,
};
esp_mqtt5_publish_property_config_t publish_property = {
.payload_format_indicator = 1,
@@ -166,11 +169,11 @@ bool mqtt5_subscribe_publish(void)
.retain_as_published_flag = true,
.retain_handle = 0,
};
char* topic = append_mac("topic");
char *topic = append_mac("topic");
TEST_ASSERT_TRUE(NULL != topic);
s_event_group = xEventGroupCreate();
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt5_cfg);
TEST_ASSERT_TRUE(NULL != client );
TEST_ASSERT_TRUE(NULL != client);
esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt5_event_handler, NULL);
TEST_ASSERT_TRUE(ESP_OK == esp_mqtt_client_start(client));
WAIT_FOR_EVENT(CONNECT_BIT);
@@ -193,21 +196,21 @@ bool mqtt5_subscribe_publish(void)
bool mqtt5_lwt_clean_disconnect(void)
{
char* lwt = append_mac("lwt");
char *lwt = append_mac("lwt");
TEST_ASSERT_TRUE(lwt);
const esp_mqtt_client_config_t mqtt5_cfg1 = {
.broker.address.uri = CONFIG_MQTT5_TEST_BROKER_URI,
.credentials.set_null_client_id = true,
.session.last_will.topic = lwt,
.session.last_will.msg = "lwt_msg",
.session.protocol_ver = MQTT_PROTOCOL_V_5,
.broker.address.uri = CONFIG_MQTT5_TEST_BROKER_URI,
.credentials.set_null_client_id = true,
.session.last_will.topic = lwt,
.session.last_will.msg = "lwt_msg",
.session.protocol_ver = MQTT_PROTOCOL_V_5,
};
const esp_mqtt_client_config_t mqtt5_cfg2 = {
.broker.address.uri = CONFIG_MQTT5_TEST_BROKER_URI,
.credentials.set_null_client_id = true,
.session.last_will.topic = lwt,
.session.last_will.msg = "lwt_msg",
.session.protocol_ver = MQTT_PROTOCOL_V_5,
.broker.address.uri = CONFIG_MQTT5_TEST_BROKER_URI,
.credentials.set_null_client_id = true,
.session.last_will.topic = lwt,
.session.last_will.msg = "lwt_msg",
.session.protocol_ver = MQTT_PROTOCOL_V_5,
};
esp_mqtt5_connection_property_config_t connect_property = {
.will_delay_interval = 10,
@@ -219,10 +222,9 @@ bool mqtt5_lwt_clean_disconnect(void)
.correlation_data_len = 6,
};
s_event_group = xEventGroupCreate();
esp_mqtt_client_handle_t client1 = esp_mqtt_client_init(&mqtt5_cfg1);
esp_mqtt_client_handle_t client2 = esp_mqtt_client_init(&mqtt5_cfg2);
TEST_ASSERT_TRUE(NULL != client1 && NULL != client2 );
TEST_ASSERT_TRUE(NULL != client1 && NULL != client2);
esp_mqtt_client_register_event(client1, ESP_EVENT_ANY_ID, mqtt5_event_handler, NULL);
esp_mqtt_client_register_event(client2, ESP_EVENT_ANY_ID, mqtt5_event_handler, NULL);
TEST_ASSERT_TRUE(ESP_OK == esp_mqtt5_client_set_connect_property(client1, &connect_property));
@@ -258,15 +260,15 @@ bool mqtt5_lwt_clean_disconnect(void)
bool mqtt5_subscribe_payload(void)
{
const esp_mqtt_client_config_t mqtt5_cfg = {
.broker.address.uri = CONFIG_MQTT5_TEST_BROKER_URI,
.network.disable_auto_reconnect = true,
.session.protocol_ver = MQTT_PROTOCOL_V_5,
.broker.address.uri = CONFIG_MQTT5_TEST_BROKER_URI,
.network.disable_auto_reconnect = true,
.session.protocol_ver = MQTT_PROTOCOL_V_5,
};
char* topic = append_mac("topic");
char *topic = append_mac("topic");
TEST_ASSERT_TRUE(NULL != topic);
s_event_group = xEventGroupCreate();
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt5_cfg);
TEST_ASSERT_TRUE(NULL != client );
TEST_ASSERT_TRUE(NULL != client);
esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt5_event_handler, NULL);
TEST_ASSERT_TRUE(ESP_OK == esp_mqtt_client_start(client));
WAIT_FOR_EVENT(CONNECT_BIT);
@@ -20,7 +20,6 @@
ESP_LOGI("mqtt5_test", "Test:" #test_name "() passed "); \
} while(0)
/**
* @brief This module contains mqtt5 test cases interacting the client with a (real) broker
*/
@@ -1,3 +1,8 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/* MQTT connect test
This example code is in the Public Domain (or CC0 licensed, at your option.)
@@ -43,16 +48,21 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
(void)event_id;
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_BEFORE_CONNECT:
break;
case MQTT_EVENT_CONNECTED:
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED: Test=%d", running_test_case);
break;
case MQTT_EVENT_DISCONNECTED:
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: %s", esp_err_to_name(event->error_handle->esp_tls_last_esp_err));
} else if (event->error_handle->error_type == MQTT_ERROR_TYPE_CONNECTION_REFUSED) {
@@ -60,7 +70,9 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
} 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;
@@ -69,7 +81,7 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
static void connect_no_certs(esp_mqtt_client_handle_t client, const char *uri)
{
ESP_LOGI(TAG, "Runnning :CONFIG_EXAMPLE_CONNECT_CASE_NO_CERT");
ESP_LOGI(TAG, "Running :CONFIG_EXAMPLE_CONNECT_CASE_NO_CERT");
const esp_mqtt_client_config_t mqtt_cfg = {
.broker.address.uri = uri
};
@@ -81,10 +93,10 @@ static void connect_with_client_key_password(esp_mqtt_client_handle_t client, co
const esp_mqtt_client_config_t mqtt_cfg = {
.broker.address.uri = uri,
.broker.verification.certificate = (const char *)ca_local_crt,
.credentials.authentication.certificate = (const char *)client_pwd_crt,
.credentials.authentication.key = (const char *)client_pwd_key,
.credentials.authentication.key_password = "esp32",
.credentials.authentication.key_password_len = 5
.credentials.authentication.certificate = (const char *)client_pwd_crt,
.credentials.authentication.key = (const char *)client_pwd_key,
.credentials.authentication.key_password = "esp32",
.credentials.authentication.key_password_len = 5
};
esp_mqtt_set_config(client, &mqtt_cfg);
}
@@ -94,9 +106,9 @@ static void connect_with_server_der_cert(esp_mqtt_client_handle_t client, const
const esp_mqtt_client_config_t mqtt_cfg = {
.broker.address.uri = uri,
.broker.verification.certificate = (const char *)ca_der_start,
.broker.verification.certificate_len = ca_der_end - ca_der_start,
.credentials.authentication.certificate = "NULL",
.credentials.authentication.key = "NULL"
.broker.verification.certificate_len = ca_der_end - ca_der_start,
.credentials.authentication.certificate = "NULL",
.credentials.authentication.key = "NULL"
};
esp_mqtt_set_config(client, &mqtt_cfg);
}
@@ -106,8 +118,8 @@ static void connect_with_wrong_server_cert(esp_mqtt_client_handle_t client, cons
const esp_mqtt_client_config_t mqtt_cfg = {
.broker.address.uri = uri,
.broker.verification.certificate = (const char *)client_pwd_crt,
.credentials.authentication.certificate = "NULL",
.credentials.authentication.key = "NULL"
.credentials.authentication.certificate = "NULL",
.credentials.authentication.key = "NULL"
};
esp_mqtt_set_config(client, &mqtt_cfg);
}
@@ -126,8 +138,8 @@ static void connect_with_server_client_certs(esp_mqtt_client_handle_t client, co
const esp_mqtt_client_config_t mqtt_cfg = {
.broker.address.uri = uri,
.broker.verification.certificate = (const char *)ca_local_crt,
.credentials.authentication.certificate = (const char *)client_pwd_crt,
.credentials.authentication.key = (const char *)client_no_pwd_key
.credentials.authentication.certificate = (const char *)client_pwd_crt,
.credentials.authentication.key = (const char *)client_no_pwd_key
};
esp_mqtt_set_config(client, &mqtt_cfg);
}
@@ -137,8 +149,8 @@ static void connect_with_invalid_client_certs(esp_mqtt_client_handle_t client, c
const esp_mqtt_client_config_t mqtt_cfg = {
.broker.address.uri = uri,
.broker.verification.certificate = (const char *)ca_local_crt,
.credentials.authentication.certificate = (const char *)client_inv_crt,
.credentials.authentication.key = (const char *)client_no_pwd_key
.credentials.authentication.certificate = (const char *)client_inv_crt,
.credentials.authentication.key = (const char *)client_no_pwd_key
};
esp_mqtt_set_config(client, &mqtt_cfg);
}
@@ -153,45 +165,57 @@ static void connect_with_alpn(esp_mqtt_client_handle_t client, const char *uri)
esp_mqtt_set_config(client, &mqtt_cfg);
}
void connect_setup(command_context_t * ctx) {
void connect_setup(command_context_t *ctx)
{
esp_mqtt_client_register_event(ctx->mqtt_client, ESP_EVENT_ANY_ID, mqtt_event_handler, ctx->data);
}
void connect_teardown(command_context_t * ctx) {
void connect_teardown(command_context_t *ctx)
{
esp_mqtt_client_unregister_event(ctx->mqtt_client, ESP_EVENT_ANY_ID, mqtt_event_handler);
}
void connection_test(command_context_t * ctx, const char *uri, int test_case)
void connection_test(command_context_t *ctx, const char *uri, int test_case)
{
ESP_LOGI(TAG, "CASE:%d, connecting to %s", test_case, uri);
running_test_case = test_case;
switch (test_case) {
case CONFIG_EXAMPLE_CONNECT_CASE_NO_CERT:
connect_no_certs(ctx->mqtt_client, uri);
break;
case CONFIG_EXAMPLE_CONNECT_CASE_SERVER_CERT:
connect_with_server_cert(ctx->mqtt_client, uri);
break;
case CONFIG_EXAMPLE_CONNECT_CASE_MUTUAL_AUTH:
connect_with_server_client_certs(ctx->mqtt_client, uri);
break;
case CONFIG_EXAMPLE_CONNECT_CASE_INVALID_SERVER_CERT:
connect_with_wrong_server_cert(ctx->mqtt_client, uri);
break;
case CONFIG_EXAMPLE_CONNECT_CASE_SERVER_DER_CERT:
connect_with_server_der_cert(ctx->mqtt_client, uri);
break;
case CONFIG_EXAMPLE_CONNECT_CASE_MUTUAL_AUTH_KEY_PWD:
connect_with_client_key_password(ctx->mqtt_client, uri);
break;
case CONFIG_EXAMPLE_CONNECT_CASE_MUTUAL_AUTH_BAD_CRT:
connect_with_invalid_client_certs(ctx->mqtt_client, uri);
break;
case CONFIG_EXAMPLE_CONNECT_CASE_NO_CERT_ALPN:
connect_with_alpn(ctx->mqtt_client, uri);
break;
default:
ESP_LOGE(TAG, "Unknown test case %d ", test_case);
break;
}
ESP_LOGI(TAG, "Test case:%d started", test_case);
}
@@ -1,3 +1,8 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/* MQTT publish-connect test
This example code is in the Public Domain (or CC0 licensed, at your option.)
@@ -36,15 +41,16 @@ publish_args_t publish_args;
return 1; \
}} while(0)
static int do_free_heap(int argc, char **argv) {
static int do_free_heap(int argc, char **argv)
{
(void)argc;
(void)argv;
ESP_LOGI(TAG, "Note free memory: %d bytes", esp_get_free_heap_size());
return 0;
}
static int do_init(int argc, char **argv) {
static int do_init(int argc, char **argv)
{
(void)argc;
(void)argv;
const esp_mqtt_client_config_t mqtt_cfg = {
@@ -52,75 +58,92 @@ static int do_init(int argc, char **argv) {
.network.disable_auto_reconnect = true
};
command_context.mqtt_client = esp_mqtt_client_init(&mqtt_cfg);
if(!command_context.mqtt_client) {
if (!command_context.mqtt_client) {
ESP_LOGE(TAG, "Failed to initialize client");
return 1;
}
publish_init_flags();
ESP_LOGI(TAG, "Mqtt client initialized");
return 0;
}
static int do_start(int argc, char **argv) {
static int do_start(int argc, char **argv)
{
(void)argc;
(void)argv;
if(esp_mqtt_client_start(command_context.mqtt_client) != ESP_OK) {
if (esp_mqtt_client_start(command_context.mqtt_client) != ESP_OK) {
ESP_LOGE(TAG, "Failed to start mqtt client task");
return 1;
}
ESP_LOGI(TAG, "Mqtt client started");
return 0;
}
static int do_stop(int argc, char **argv) {
static int do_stop(int argc, char **argv)
{
(void)argc;
(void)argv;
if(esp_mqtt_client_stop(command_context.mqtt_client) != ESP_OK) {
if (esp_mqtt_client_stop(command_context.mqtt_client) != ESP_OK) {
ESP_LOGE(TAG, "Failed to stop mqtt client task");
return 1;
}
ESP_LOGI(TAG, "Mqtt client stopped");
return 0;
}
static int do_disconnect(int argc, char **argv) {
static int do_disconnect(int argc, char **argv)
{
(void)argc;
(void)argv;
if(esp_mqtt_client_disconnect(command_context.mqtt_client) != ESP_OK) {
if (esp_mqtt_client_disconnect(command_context.mqtt_client) != ESP_OK) {
ESP_LOGE(TAG, "Failed to request disconnection");
return 1;
}
ESP_LOGI(TAG, "Mqtt client disconnected");
return 0;
}
static int do_connect_setup(int argc, char **argv) {
static int do_connect_setup(int argc, char **argv)
{
(void)argc;
(void)argv;
connect_setup(&command_context);
return 0;
}
static int do_connect_teardown(int argc, char **argv) {
static int do_connect_teardown(int argc, char **argv)
{
(void)argc;
(void)argv;
connect_teardown(&command_context);
return 0;
}
static int do_reconnect(int argc, char **argv) {
static int do_reconnect(int argc, char **argv)
{
(void)argc;
(void)argv;
if(esp_mqtt_client_reconnect(command_context.mqtt_client) != ESP_OK) {
if (esp_mqtt_client_reconnect(command_context.mqtt_client) != ESP_OK) {
ESP_LOGE(TAG, "Failed to request reconnection");
return 1;
}
ESP_LOGI(TAG, "Mqtt client will reconnect");
return 0;
;
}
static int do_destroy(int argc, char **argv) {
static int do_destroy(int argc, char **argv)
{
(void)argc;
(void)argv;
esp_mqtt_client_destroy(command_context.mqtt_client);
@@ -132,54 +155,62 @@ static int do_destroy(int argc, char **argv) {
static int do_connect(int argc, char **argv)
{
int nerrors = arg_parse(argc, argv, (void **) &connection_args);
if (nerrors != 0) {
arg_print_errors(stderr, connection_args.end, argv[0]);
return 1;
}
if(!command_context.mqtt_client) {
if (!command_context.mqtt_client) {
ESP_LOGE(TAG, "MQTT client not initialized, call init first");
return 1;
}
connection_test(&command_context, *connection_args.uri->sval, *connection_args.test_case->ival);
return 0;
}
static int do_publish_setup(int argc, char **argv) {
static int do_publish_setup(int argc, char **argv)
{
RETURN_ON_PARSE_ERROR(publish_setup_args);
if(command_context.data) {
if (command_context.data) {
free(command_context.data);
}
command_context.data = calloc(1, sizeof(publish_context_t));
((publish_context_t*)command_context.data)->pattern = strdup(*publish_setup_args.pattern->sval);
((publish_context_t*)command_context.data)->pattern_repetitions = *publish_setup_args.pattern_repetitions->ival;
((publish_context_t*)command_context.data)->subscribe_to = strdup(*publish_setup_args.subscribe_to->sval);
((publish_context_t*)command_context.data)->publish_to = strdup(*publish_setup_args.publish_to->sval);
((publish_context_t *)command_context.data)->pattern = strdup(*publish_setup_args.pattern->sval);
((publish_context_t *)command_context.data)->pattern_repetitions = *publish_setup_args.pattern_repetitions->ival;
((publish_context_t *)command_context.data)->subscribe_to = strdup(*publish_setup_args.subscribe_to->sval);
((publish_context_t *)command_context.data)->publish_to = strdup(*publish_setup_args.publish_to->sval);
publish_setup(&command_context, *publish_setup_args.transport->sval);
return 0;
}
static int do_publish(int argc, char **argv) {
static int do_publish(int argc, char **argv)
{
RETURN_ON_PARSE_ERROR(publish_args);
publish_test(&command_context, publish_args.expected_to_publish->ival[0], publish_args.qos->ival[0], publish_args.enqueue->ival[0]);
publish_test(&command_context, publish_args.expected_to_publish->ival[0], publish_args.qos->ival[0],
publish_args.enqueue->ival[0]);
return 0;
}
static int do_publish_report(int argc, char **argv) {
static int do_publish_report(int argc, char **argv)
{
(void)argc;
(void)argv;
publish_context_t * ctx = command_context.data;
ESP_LOGI(TAG,"Test Report : Messages received %d, %d expected", ctx->nr_of_msg_received, ctx->nr_of_msg_expected);
publish_context_t *ctx = command_context.data;
ESP_LOGI(TAG, "Test Report : Messages received %d, %d expected", ctx->nr_of_msg_received, ctx->nr_of_msg_expected);
return 0;
}
void register_common_commands(void) {
void register_common_commands(void)
{
const esp_console_cmd_t init = {
.command = "init",
.help = "Run inition test\n",
.hint = NULL,
.func = &do_init,
};
const esp_console_cmd_t start = {
.command = "start",
.help = "Run startion test\n",
@@ -210,17 +241,19 @@ void register_common_commands(void) {
ESP_ERROR_CHECK(esp_console_cmd_register(&destroy));
ESP_ERROR_CHECK(esp_console_cmd_register(&free_heap));
}
void register_publish_commands(void) {
publish_setup_args.transport = arg_str1(NULL,NULL,"<transport>", "Selected transport to test");
publish_setup_args.publish_to = arg_str1(NULL,NULL,"<transport>", "Selected publish_to to publish");
publish_setup_args.subscribe_to = arg_str1(NULL,NULL,"<transport>", "Selected subscribe_to to publish");
publish_setup_args.pattern = arg_str1(NULL,NULL,"<pattern>", "Message pattern repeated to build big messages");
publish_setup_args.pattern_repetitions = arg_int1(NULL,NULL,"<pattern repetitions>", "How many times the pattern is repeated");
void register_publish_commands(void)
{
publish_setup_args.transport = arg_str1(NULL, NULL, "<transport>", "Selected transport to test");
publish_setup_args.publish_to = arg_str1(NULL, NULL, "<transport>", "Selected publish_to to publish");
publish_setup_args.subscribe_to = arg_str1(NULL, NULL, "<transport>", "Selected subscribe_to to publish");
publish_setup_args.pattern = arg_str1(NULL, NULL, "<pattern>", "Message pattern repeated to build big messages");
publish_setup_args.pattern_repetitions = arg_int1(NULL, NULL, "<pattern repetitions>",
"How many times the pattern is repeated");
publish_setup_args.end = arg_end(1);
publish_args.expected_to_publish = arg_int1(NULL,NULL,"<number of messages>", "How many times the pattern is repeated");
publish_args.qos = arg_int1(NULL,NULL,"<qos>", "How many times the pattern is repeated");
publish_args.enqueue = arg_int1(NULL,NULL,"<enqueue>", "How many times the pattern is repeated");
publish_args.expected_to_publish = arg_int1(NULL, NULL, "<number of messages>",
"How many times the pattern is repeated");
publish_args.qos = arg_int1(NULL, NULL, "<qos>", "How many times the pattern is repeated");
publish_args.enqueue = arg_int1(NULL, NULL, "<enqueue>", "How many times the pattern is repeated");
publish_args.end = arg_end(1);
const esp_console_cmd_t publish_setup = {
.command = "publish_setup",
@@ -229,7 +262,6 @@ void register_publish_commands(void) {
.func = &do_publish_setup,
.argtable = &publish_setup_args
};
const esp_console_cmd_t publish = {
.command = "publish",
.help = "Run publish test\n",
@@ -247,11 +279,11 @@ void register_publish_commands(void) {
ESP_ERROR_CHECK(esp_console_cmd_register(&publish));
ESP_ERROR_CHECK(esp_console_cmd_register(&publish_report));
}
void register_connect_commands(void){
connection_args.uri = arg_str1(NULL,NULL,"<broker uri>", "Broker address");
connection_args.test_case = arg_int1(NULL, NULL, "<test case>","Selected test case");
void register_connect_commands(void)
{
connection_args.uri = arg_str1(NULL, NULL, "<broker uri>", "Broker address");
connection_args.test_case = arg_int1(NULL, NULL, "<test case>", "Selected test case");
connection_args.end = arg_end(1);
const esp_console_cmd_t connect = {
.command = "connect",
.help = "Run connection test\n",
@@ -259,7 +291,6 @@ void register_connect_commands(void){
.func = &do_connect,
.argtable = &connection_args
};
const esp_console_cmd_t reconnect = {
.command = "reconnect",
.help = "Run reconnection test\n",
@@ -292,7 +323,7 @@ void register_connect_commands(void){
}
#ifdef CONFIG_EXAMPLE_RUN_LOCAL_BROKER
static void broker_task(void* ctx)
static void broker_task(void *ctx)
{
// broker continues to run in this task
struct mosq_broker_config config = { .host = CONFIG_EXAMPLE_BROKER_HOST, .port = CONFIG_EXAMPLE_BROKER_PORT };
@@ -303,15 +334,12 @@ static void broker_task(void* ctx)
void app_main(void)
{
static const size_t max_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("wifi", ESP_LOG_ERROR);
esp_log_level_set("mqtt_client", 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());
@@ -327,7 +355,6 @@ void app_main(void)
register_common_commands();
register_connect_commands();
register_publish_commands();
esp_console_dev_uart_config_t hw_config = ESP_CONSOLE_DEV_UART_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_console_new_repl_uart(&hw_config, &repl_config, &repl));
ESP_ERROR_CHECK(esp_console_start_repl(repl));
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@@ -11,7 +11,7 @@ typedef enum {NONE, TCP, SSL, WS, WSS} transport_t;
typedef struct {
esp_mqtt_client_handle_t mqtt_client;
void * data;
void *data;
} command_context_t;
typedef struct {
@@ -25,7 +25,7 @@ typedef struct {
size_t expected_size;
size_t nr_of_msg_received;
size_t nr_of_msg_expected;
char * received_data;
char *received_data;
} publish_context_t ;
typedef struct {
@@ -51,9 +51,9 @@ typedef struct {
} publish_setup_args_t;
void publish_init_flags(void);
void publish_setup(command_context_t * ctx, char const * transport);
void publish_teardown(command_context_t * ctx);
void publish_test(command_context_t * ctx, int expect_to_publish, int qos, bool enqueue);
void connection_test(command_context_t * ctx, const char *uri, int test_case);
void connect_setup(command_context_t * ctx);
void connect_teardown(command_context_t * ctx);
void publish_setup(command_context_t *ctx, char const *transport);
void publish_teardown(command_context_t *ctx);
void publish_test(command_context_t *ctx, int expect_to_publish, int qos, bool enqueue);
void connection_test(command_context_t *ctx, const char *uri, int test_case);
void connect_setup(command_context_t *ctx);
void connect_teardown(command_context_t *ctx);
@@ -1,3 +1,8 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/* MQTT publish test
This example code is in the Public Domain (or CC0 licensed, at your option.)
@@ -27,7 +32,8 @@ static EventGroupHandle_t mqtt_event_group;
const static int CONNECTED_BIT = BIT0;
#define CLIENT_ID_SUFFIX_SIZE 12
#if CONFIG_EXAMPLE_BROKER_CERTIFICATE_OVERRIDDEN == 1
static const uint8_t mqtt_eclipseprojects_io_pem_start[] = "-----BEGIN CERTIFICATE-----\n" CONFIG_EXAMPLE_BROKER_CERTIFICATE_OVERRIDE "\n-----END CERTIFICATE-----";
static const uint8_t mqtt_eclipseprojects_io_pem_start[] = "-----BEGIN CERTIFICATE-----\n"
CONFIG_EXAMPLE_BROKER_CERTIFICATE_OVERRIDE "\n-----END CERTIFICATE-----";
#else
extern const uint8_t mqtt_eclipseprojects_io_pem_start[] asm("_binary_mqtt_eclipseprojects_io_pem_start");
#endif
@@ -35,21 +41,23 @@ extern const uint8_t mqtt_eclipseprojects_io_pem_end[] asm("_binary_mqtt_eclip
static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
{
publish_context_t * test_data = handler_args;
publish_context_t *test_data = handler_args;
esp_mqtt_event_handle_t event = event_data;
esp_mqtt_client_handle_t client = event->client;
static int msg_id = 0;
static int actual_len = 0;
switch (event->event_id) {
case MQTT_EVENT_BEFORE_CONNECT:
break;
case MQTT_EVENT_CONNECTED:
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
xEventGroupSetBits(mqtt_event_group, CONNECTED_BIT);
msg_id = esp_mqtt_client_subscribe(client, test_data->subscribe_to, test_data->qos);
ESP_LOGI(TAG, "sent subscribe successful %s , msg_id=%d", test_data->subscribe_to, msg_id);
break;
case MQTT_EVENT_DISCONNECTED:
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
break;
@@ -57,58 +65,74 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
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_LOGD(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
break;
case MQTT_EVENT_DATA:
ESP_LOGI(TAG, "MQTT_EVENT_DATA");
ESP_LOGI(TAG, "TOPIC=%.*s", event->topic_len, event->topic);
ESP_LOGI(TAG, "ID=%d, total_len=%d, data_len=%d, current_data_offset=%d", event->msg_id, event->total_data_len, event->data_len, event->current_data_offset);
if (event->current_data_offset == 0) {
actual_len = event->data_len;
msg_id = event->msg_id;
if (event->total_data_len != test_data->expected_size) {
ESP_LOGE(TAG, "Incorrect message size: %d != %d", event->total_data_len, test_data->expected_size);
abort();
}
} else {
actual_len += event->data_len;
// check consistency with msg_id across multiple data events for single msg
if (msg_id != event->msg_id) {
ESP_LOGE(TAG, "Wrong msg_id in chunked message %d != %d", msg_id, event->msg_id);
abort();
}
}
if (event->current_data_offset + event->data_len > test_data->expected_size) {
ESP_LOGE(TAG, "Buffer overflow detected: offset %d + data_len %d > buffer size %d", event->current_data_offset, event->data_len, test_data->expected_size);
abort();
}
if (memcmp(test_data->expected + event->current_data_offset, event->data, event->data_len) != 0) {
ESP_LOGE(TAG, "Data mismatch at offset %d: \n expected %.*s, \n got %.*s", event->current_data_offset, event->data_len, test_data->expected + event->current_data_offset, event->data_len, event->data);
ESP_LOGI(TAG, "ID=%d, total_len=%d, data_len=%d, current_data_offset=%d", event->msg_id, event->total_data_len,
event->data_len, event->current_data_offset);
if (event->current_data_offset == 0) {
actual_len = event->data_len;
msg_id = event->msg_id;
if (event->total_data_len != test_data->expected_size) {
ESP_LOGE(TAG, "Incorrect message size: %d != %d", event->total_data_len, test_data->expected_size);
abort();
}
} else {
actual_len += event->data_len;
// check consistency with msg_id across multiple data events for single msg
if (msg_id != event->msg_id) {
ESP_LOGE(TAG, "Wrong msg_id in chunked message %d != %d", msg_id, event->msg_id);
abort();
}
}
if (event->current_data_offset + event->data_len > test_data->expected_size) {
ESP_LOGE(TAG, "Buffer overflow detected: offset %d + data_len %d > buffer size %d", event->current_data_offset,
event->data_len, test_data->expected_size);
abort();
}
}
if (memcmp(test_data->expected + event->current_data_offset, event->data, event->data_len) != 0) {
ESP_LOGE(TAG, "Data mismatch at offset %d: \n expected %.*s, \n got %.*s", event->current_data_offset, event->data_len,
test_data->expected + event->current_data_offset, event->data_len, event->data);
abort();
}
memcpy(test_data->received_data + event->current_data_offset, event->data, event->data_len);
if (actual_len == event->total_data_len) {
if (0 == memcmp(test_data->received_data, test_data->expected, test_data->expected_size)) {
memset(test_data->received_data, 0, test_data->expected_size);
test_data->nr_of_msg_received++;
if (test_data->nr_of_msg_received == test_data->nr_of_msg_expected) {
ESP_LOGI(TAG, "Correct pattern received exactly x times");
ESP_LOGI(TAG, "Test finished correctly!");
}
} else {
ESP_LOGE(TAG, "FAILED!");
abort();
}
}
memcpy(test_data->received_data + event->current_data_offset, event->data, event->data_len);
if (actual_len == event->total_data_len) {
if (0 == memcmp(test_data->received_data, test_data->expected, test_data->expected_size)) {
memset(test_data->received_data, 0, test_data->expected_size);
test_data->nr_of_msg_received++;
if (test_data->nr_of_msg_received == test_data->nr_of_msg_expected) {
ESP_LOGI(TAG, "Correct pattern received exactly x times");
ESP_LOGI(TAG, "Test finished correctly!");
}
} else {
ESP_LOGE(TAG, "FAILED!");
abort();
}
}
break;
case MQTT_EVENT_ERROR:
ESP_LOGE(TAG, "MQTT_EVENT_ERROR");
break;
default:
ESP_LOGI(TAG, "Other event id:%d", event->event_id);
break;
@@ -120,7 +144,7 @@ void test_init(void)
ESP_LOGI(TAG, "[APP] Free memory: %d bytes", esp_get_free_heap_size());
}
void pattern_setup(publish_context_t * test_data)
void pattern_setup(publish_context_t *test_data)
{
int pattern_size = strlen(test_data->pattern);
free(test_data->expected);
@@ -129,17 +153,20 @@ void pattern_setup(publish_context_t * test_data)
test_data->expected_size = (size_t)(pattern_size) * test_data->pattern_repetitions;
test_data->expected = malloc(test_data->expected_size);
test_data->received_data = malloc(test_data->expected_size);
for (int i = 0; i < test_data->pattern_repetitions; i++) {
memcpy(test_data->expected + (ptrdiff_t)(i * pattern_size), test_data->pattern, pattern_size);
}
ESP_LOGI(TAG, "EXPECTED STRING %.*s, SIZE:%d", test_data->expected_size, test_data->expected, test_data->expected_size);
}
static void configure_client(command_context_t * ctx, const char *transport)
static void configure_client(command_context_t *ctx, const char *transport)
{
publish_context_t * test_data = ctx->data;
publish_context_t *test_data = ctx->data;
ESP_LOGI(TAG, "Configuration");
transport_t selected_transport;
if (0 == strcmp(transport, "tcp")) {
selected_transport = TCP;
} else if (0 == strcmp(transport, "ssl")) {
@@ -153,34 +180,40 @@ static void configure_client(command_context_t * ctx, const char *transport)
abort();
}
if (selected_transport != test_data->selected_transport) {
test_data->selected_transport = selected_transport;
esp_mqtt_client_config_t config = {0};
switch (selected_transport) {
case NONE:
break;
case TCP:
ESP_LOGI(TAG, "[TCP transport] Startup..");
config.broker.address.uri = CONFIG_EXAMPLE_BROKER_TCP_URI;
break;
case SSL:
ESP_LOGI(TAG, "[SSL transport] Startup..");
config.broker.address.uri = CONFIG_EXAMPLE_BROKER_SSL_URI;
break;
case WS:
ESP_LOGI(TAG, "[WS transport] Startup..");
config.broker.address.uri = CONFIG_EXAMPLE_BROKER_WS_URI;
break;
case WSS:
ESP_LOGI(TAG, "[WSS transport] Startup..");
config.broker.address.uri = CONFIG_EXAMPLE_BROKER_WSS_URI;
break;
}
if (selected_transport == SSL || selected_transport == WSS) {
ESP_LOGI(TAG, "Set certificate");
config.broker.verification.certificate = (const char *)mqtt_eclipseprojects_io_pem_start;
}
// Generate a random client id for each iteration
char client_id[CLIENT_ID_SUFFIX_SIZE] = {0};
snprintf(client_id, sizeof(client_id), "esp32-%08X", esp_random());
@@ -189,41 +222,47 @@ static void configure_client(command_context_t * ctx, const char *transport)
}
}
void publish_init_flags(void) {
void publish_init_flags(void)
{
mqtt_event_group = xEventGroupCreate();
}
void publish_setup(command_context_t * ctx, char const * const transport) {
void publish_setup(command_context_t *ctx, char const *const transport)
{
xEventGroupClearBits(mqtt_event_group, CONNECTED_BIT);
publish_context_t * data = (publish_context_t*)ctx->data;
publish_context_t *data = (publish_context_t *)ctx->data;
pattern_setup(data);
configure_client(ctx, transport);
esp_mqtt_client_register_event(ctx->mqtt_client, ESP_EVENT_ANY_ID, mqtt_event_handler, data);
}
void publish_teardown(command_context_t * ctx)
void publish_teardown(command_context_t *ctx)
{
esp_mqtt_client_unregister_event(ctx->mqtt_client, ESP_EVENT_ANY_ID, mqtt_event_handler);
}
void publish_test(command_context_t * ctx, int expect_to_publish, int qos, bool enqueue)
void publish_test(command_context_t *ctx, int expect_to_publish, int qos, bool enqueue)
{
publish_context_t * data = (publish_context_t*)ctx->data;
publish_context_t *data = (publish_context_t *)ctx->data;
data->nr_of_msg_expected = expect_to_publish;
ESP_LOGI(TAG, "PATTERN:%s REPEATED:%d PUBLISHED:%d", data->pattern, data->pattern_repetitions, data->nr_of_msg_expected);
ESP_LOGI(TAG, "PATTERN:%s REPEATED:%d PUBLISHED:%d", data->pattern, data->pattern_repetitions,
data->nr_of_msg_expected);
xEventGroupWaitBits(mqtt_event_group, CONNECTED_BIT, false, true, portMAX_DELAY);
for (int i = 0; i < data->nr_of_msg_expected; i++) {
int msg_id;
if (enqueue) {
msg_id = esp_mqtt_client_enqueue(ctx->mqtt_client, data->publish_to, data->expected, data->expected_size, qos, 0, true);
} else {
msg_id = esp_mqtt_client_publish(ctx->mqtt_client, data->publish_to, data->expected, data->expected_size, qos, 0);
if(msg_id < 0) {
if (msg_id < 0) {
ESP_LOGE(TAG, "Failed to publish");
break;
}
}
ESP_LOGD(TAG, "Publishing msg_id=%d", msg_id);
}
}
@@ -181,8 +181,8 @@ def connect_dut(dut: Dut, uri: str, case_id: int) -> Any:
def run_cases(dut: Dut, uri: str, cases: Dict[str, int]) -> None:
try:
dut.write('init')
dut.write(f'start')
dut.write(f'disconnect')
dut.write('start')
dut.write('disconnect')
for case in [
'EXAMPLE_CONNECT_CASE_NO_CERT',
'EXAMPLE_CONNECT_CASE_SERVER_CERT',
+10 -12
View File
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -25,7 +25,7 @@ extern "C" {
#include "Mockqueue.h"
#include "Mocktask.h"
#if __has_include ("Mockidf_additions.h")
/* Some functions were moved from "task.h" to "idf_additions.h" */
/* Some functions were moved from "task.h" to "idf_additions.h" */
#include "Mockidf_additions.h"
#endif
#include "Mockesp_timer.h"
@@ -49,7 +49,8 @@ auto random_string(std::size_t n)
return str;
}
using unique_mqtt_client = std::unique_ptr < std::remove_pointer_t<esp_mqtt_client_handle_t>, decltype([](esp_mqtt_client_handle_t client)
using unique_mqtt_client = std::unique_ptr < std::remove_pointer_t<esp_mqtt_client_handle_t>,
decltype([](esp_mqtt_client_handle_t client)
{
esp_mqtt_client_destroy(client);
}) >;
@@ -118,15 +119,15 @@ SCENARIO("MQTT Client Operation")
REQUIRE(res == ESP_FAIL);
}
}
SECTION("User set interface to use"){
SECTION("User set interface to use") {
http_parser_parse_url_ExpectAnyArgsAndReturn(0);
http_parser_parse_url_ReturnThruPtr_u(&ret_uri);
struct ifreq if_name = {};
strncpy(if_name.ifr_name, "custom", IFNAMSIZ - 1);
if_name.ifr_name[IFNAMSIZ - 1] = '\0';;
config.network.if_name = &if_name;
SECTION("Client is not started"){
REQUIRE(esp_mqtt_set_config(client.get(), &config)== ESP_OK);
SECTION("Client is not started") {
REQUIRE(esp_mqtt_set_config(client.get(), &config) == ESP_OK);
}
}
SECTION("After Start Client Is Cleanly destroyed") {
@@ -143,15 +144,14 @@ SCENARIO("MQTT Client Operation")
auto password = random_string(10);
auto lw_topic = random_string(10);
auto lw_msg = random_string(10);
config.broker = {.address = {
.hostname = host.data(),
.path = path.data()
.path = path.data()
}
};
config.credentials = {
.username = username.data(),
.client_id = client_id.data(),
.client_id = client_id.data(),
.authentication = {
.password = password.data()
}
@@ -159,13 +159,11 @@ SCENARIO("MQTT Client Operation")
config.session = {
.last_will {
.topic = lw_topic.data(),
.msg = lw_msg.data()
.msg = lw_msg.data()
}
};
auto client = unique_mqtt_client{esp_mqtt_client_init(&config)};
REQUIRE(client != nullptr);
}
}
}