ci: Introduce property ownership test

This commit is contained in:
Euripedes Rocha Filho
2026-09-22 12:35:17 +02:00
committed by Euripedes Rocha
parent e21ebb3e8d
commit 7b5090ec4b
2 changed files with 112 additions and 0 deletions
@@ -4,9 +4,37 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include <string.h>
#include "mqtt_client_priv.h"
static struct esp_mqtt_client s_client;
static mqtt5_config_storage_t s_mqtt5_config;
esp_mqtt_client_handle_t test_mqtt5_property_client_reset(void)
{
memset(&s_client, 0, sizeof(s_client));
memset(&s_mqtt5_config, 0, sizeof(s_mqtt5_config));
s_client.mqtt5_config = &s_mqtt5_config;
s_client.mqtt_state.connection.information.protocol_ver = MQTT_PROTOCOL_V_5;
return &s_client;
}
mqtt5_staged_property_t *test_mqtt5_publish_property_slot(void)
{
return &s_mqtt5_config.publish_property;
}
mqtt5_staged_property_t *test_mqtt5_subscribe_property_slot(void)
{
return &s_mqtt5_config.subscribe_property;
}
mqtt5_staged_property_t *test_mqtt5_unsubscribe_property_slot(void)
{
return &s_mqtt5_config.unsubscribe_property;
}
esp_err_t test_mqtt5_check_inflight_maximum(uint16_t send_count, uint16_t receive_maximum)
{
struct esp_mqtt_client client = {0};
+84
View File
@@ -11,6 +11,10 @@
#include "mqtt5_client.h"
extern "C" {
#include "Mockqueue.h"
#include "Mocktask.h"
#include "mqtt5_client_priv.h"
esp_err_t test_mqtt5_check_inflight_maximum(uint16_t send_count, uint16_t receive_maximum);
int test_mqtt5_increment_packet_counter_with_dup(void);
esp_err_t test_mqtt5_set_connect_null_property(void);
@@ -18,6 +22,22 @@ extern "C" {
esp_err_t test_mqtt5_set_subscribe_null_property(void);
esp_err_t test_mqtt5_set_unsubscribe_null_property(void);
esp_err_t test_mqtt5_set_disconnect_null_property(void);
esp_mqtt_client_handle_t test_mqtt5_property_client_reset(void);
mqtt5_staged_property_t *test_mqtt5_publish_property_slot(void);
mqtt5_staged_property_t *test_mqtt5_subscribe_property_slot(void);
mqtt5_staged_property_t *test_mqtt5_unsubscribe_property_slot(void);
}
static void use_task(TaskHandle_t task)
{
xTaskGetCurrentTaskHandle_IgnoreAndReturn(task);
}
static esp_mqtt_client_handle_t prepare_property_client()
{
xQueueTakeMutexRecursive_IgnoreAndReturn(pdTRUE);
xQueueGiveMutexRecursive_IgnoreAndReturn(pdTRUE);
return test_mqtt5_property_client_reset();
}
TEST_CASE("MQTT5 inflight quota uses an exact upper bound")
@@ -53,3 +73,67 @@ TEST_CASE("MQTT5 property setters reject a null client")
REQUIRE(esp_mqtt5_client_set_unsubscribe_property(nullptr, &unsubscribe) == ESP_ERR_INVALID_ARG);
REQUIRE(esp_mqtt5_client_set_disconnect_property(nullptr, &disconnect) == ESP_ERR_INVALID_ARG);
}
TEST_CASE("MQTT5 staged property enforces task ownership")
{
int task_a_storage;
int task_b_storage;
int property_a = 1;
int property_b = 2;
int replacement = 3;
TaskHandle_t task_a = reinterpret_cast<TaskHandle_t>(&task_a_storage);
TaskHandle_t task_b = reinterpret_cast<TaskHandle_t>(&task_b_storage);
mqtt5_staged_property_t slot = {};
use_task(task_a);
REQUIRE(esp_mqtt5_staged_property_set(&slot, &property_a) == ESP_OK);
REQUIRE(esp_mqtt5_staged_property_get(&slot) == &property_a);
use_task(task_b);
REQUIRE(esp_mqtt5_staged_property_get(&slot) == nullptr);
esp_mqtt5_staged_property_clear(&slot);
REQUIRE(slot.property == &property_a);
REQUIRE(slot.owner == task_a);
REQUIRE(esp_mqtt5_staged_property_set(&slot, &property_b) == ESP_ERR_INVALID_STATE);
REQUIRE(slot.property == &property_a);
REQUIRE(slot.owner == task_a);
use_task(task_a);
REQUIRE(esp_mqtt5_staged_property_set(&slot, &replacement) == ESP_OK);
REQUIRE(esp_mqtt5_staged_property_get(&slot) == &replacement);
esp_mqtt5_staged_property_clear(&slot);
REQUIRE(slot.property == nullptr);
REQUIRE(slot.owner == nullptr);
use_task(task_b);
REQUIRE(esp_mqtt5_staged_property_set(&slot, &property_b) == ESP_OK);
REQUIRE(esp_mqtt5_staged_property_get(&slot) == &property_b);
}
TEST_CASE("MQTT5 property setters use task-owned slots")
{
int task_a_storage;
int task_b_storage;
TaskHandle_t task_a = reinterpret_cast<TaskHandle_t>(&task_a_storage);
TaskHandle_t task_b = reinterpret_cast<TaskHandle_t>(&task_b_storage);
esp_mqtt5_publish_property_config_t publish_a = {};
esp_mqtt5_publish_property_config_t publish_b = {};
esp_mqtt5_subscribe_property_config_t subscribe_a = {};
esp_mqtt5_subscribe_property_config_t subscribe_b = {};
esp_mqtt5_unsubscribe_property_config_t unsubscribe_a = {};
esp_mqtt5_unsubscribe_property_config_t unsubscribe_b = {};
esp_mqtt_client_handle_t client = prepare_property_client();
use_task(task_a);
REQUIRE(esp_mqtt5_client_set_publish_property(client, &publish_a) == ESP_OK);
REQUIRE(esp_mqtt5_client_set_subscribe_property(client, &subscribe_a) == ESP_OK);
REQUIRE(esp_mqtt5_client_set_unsubscribe_property(client, &unsubscribe_a) == ESP_OK);
REQUIRE(test_mqtt5_publish_property_slot()->property == &publish_a);
REQUIRE(test_mqtt5_subscribe_property_slot()->property == &subscribe_a);
REQUIRE(test_mqtt5_unsubscribe_property_slot()->property == &unsubscribe_a);
REQUIRE(test_mqtt5_publish_property_slot()->owner == task_a);
REQUIRE(test_mqtt5_subscribe_property_slot()->owner == task_a);
REQUIRE(test_mqtt5_unsubscribe_property_slot()->owner == task_a);
use_task(task_b);
REQUIRE(esp_mqtt5_client_set_publish_property(client, &publish_b) == ESP_ERR_INVALID_STATE);
REQUIRE(esp_mqtt5_client_set_subscribe_property(client, &subscribe_b) == ESP_ERR_INVALID_STATE);
REQUIRE(esp_mqtt5_client_set_unsubscribe_property(client, &unsubscribe_b) == ESP_ERR_INVALID_STATE);
REQUIRE(test_mqtt5_publish_property_slot()->property == &publish_a);
REQUIRE(test_mqtt5_subscribe_property_slot()->property == &subscribe_a);
REQUIRE(test_mqtt5_unsubscribe_property_slot()->property == &unsubscribe_a);
}