Skip to content

Commit 4574ee8

Browse files
committed
fix(mqtt_cxx): Implement simple unit tests
1 parent d979e1b commit 4574ee8

File tree

9 files changed

+144
-27
lines changed

9 files changed

+144
-27
lines changed

.github/workflows/mqtt_cxx__build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
matrix:
1616
idf_ver: ["release-v5.1", "release-v5.2", "release-v5.3", "release-v5.4", "release-v5.5"]
1717
idf_target: ["esp32"]
18-
test: [ { app: mqtt-basic, path: "components/esp_mqtt_cxx/examples" }]
18+
test: [ { app: mqtt-basic, path: "components/esp_mqtt_cxx/examples" }, { app: test, path: "components/esp_mqtt_cxx/test/host" }]
1919
runs-on: ubuntu-22.04
2020
container: espressif/idf:${{ matrix.idf_ver }}
2121
steps:

components/esp_mqtt_cxx/esp_mqtt_cxx.cpp

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -260,18 +260,6 @@ void Client::on_data(esp_mqtt_event_handle_t const event)
260260
{
261261
}
262262

263-
void Client::dispatch_event_for_test(int32_t event_id, esp_mqtt_event_t *event)
264-
{
265-
if (event == nullptr) {
266-
throw MQTTException(ESP_ERR_INVALID_ARG);
267-
}
268-
event->event_id = static_cast<esp_mqtt_event_id_t>(event_id);
269-
auto err = esp_mqtt_dispatch_custom_event(handler.get(), event);
270-
if (err != ESP_OK) {
271-
throw MQTTException(err);
272-
}
273-
}
274-
275263
std::optional<MessageID> Client::subscribe(std::string const &topic, QoS qos)
276264
{
277265
auto res = esp_mqtt_client_subscribe(handler.get(), topic.c_str(),

components/esp_mqtt_cxx/include/esp_mqtt.hpp

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -229,14 +229,6 @@ class Client {
229229

230230
virtual ~Client() = default;
231231

232-
/**
233-
* @brief Test helper to dispatch events without a broker connection
234-
*
235-
* Intended for unit tests; forwards directly to the internal event handler.
236-
*/
237-
void dispatch_event_for_test(int32_t event_id, esp_mqtt_event_t *event);
238-
239-
240232
protected:
241233
/**
242234
* @brief Helper type to be used as custom deleter for std::unique_ptr.
@@ -266,13 +258,13 @@ class Client {
266258
*/
267259
virtual void on_error(const esp_mqtt_event_handle_t event);
268260
/**
269-
* @brief Called if there is an disconnection event
261+
* @brief Called if there is a disconnection event
270262
*
271263
* @param event mqtt event data
272264
*/
273265
virtual void on_disconnected(const esp_mqtt_event_handle_t event);
274266
/**
275-
* @brief Called if there is an subscribed event
267+
* @brief Called if there is a subscribed event
276268
*
277269
* @param event mqtt event data
278270
*/
@@ -284,26 +276,26 @@ class Client {
284276
*/
285277
virtual void on_unsubscribed(const esp_mqtt_event_handle_t event);
286278
/**
287-
* @brief Called if there is an published event
279+
* @brief Called if there is a published event
288280
*
289281
* @param event mqtt event data
290282
*/
291283
virtual void on_published(const esp_mqtt_event_handle_t event);
292284
/**
293-
* @brief Called if there is an before connect event
285+
* @brief Called if there is a before connect event
294286
*
295287
* @param event mqtt event data
296288
*/
297289
virtual void on_before_connect(const esp_mqtt_event_handle_t event);
298290
/**
299-
* @brief Called if there is an connected event
291+
* @brief Called if there is a connected event
300292
*
301293
* @param event mqtt event data
302294
*
303295
*/
304296
virtual void on_connected(const esp_mqtt_event_handle_t event) = 0;
305297
/**
306-
* @brief Called if there is an data event
298+
* @brief Called if there is a data event
307299
*
308300
* @param event mqtt event data
309301
*
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
cmake_minimum_required(VERSION 3.5)
2+
3+
4+
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
5+
if(${IDF_TARGET} STREQUAL "linux")
6+
set(EXTRA_COMPONENT_DIRS "../../../../common_components/linux_compat")
7+
set(COMPONENTS main)
8+
endif()
9+
10+
project(esp_mqtt_cxx_host_test)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Test basic mqtt_cxx wrapper operations
2+
3+
## Warning: Linux target not supported, this test works only on target
4+
5+
## Example output
6+
```
7+
I (588) main_task: Started on CPU0
8+
I (598) main_task: Calling app_main()
9+
Randomness seeded to: 374196253
10+
I (608) mqtt_client_cpp: MQTT_EVENT_BEFORE_CONNECT
11+
E (618) esp-tls: [sock=54] delayed connect error: Connection reset by peer
12+
E (618) transport_base: Failed to open a new connection: 32772
13+
E (618) mqtt_client: Error transport connect
14+
I (618) mqtt_client_cpp: MQTT_EVENT_ERROR
15+
E (628) mqtt_client_cpp: Last error reported from esp-tls: 0x8004
16+
E (628) mqtt_client_cpp: Last error captured as transport's socket errno: 0x68
17+
I (638) mqtt_client_cpp: Last errno string (Connection reset by peer)
18+
I (648) mqtt_client_cpp: MQTT_EVENT_DISCONNECTED
19+
===============================================================================
20+
All tests passed (6 assertions in 1 test case)
21+
22+
Test passed!
23+
I (5658) main_task: Returned from app_main()
24+
```
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
idf_component_register(SRCS "test_esp_mqtt_cxx.cpp"
2+
WHOLE_ARCHIVE)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
dependencies:
2+
espressif/catch2: "^3.4.0"
3+
esp_mqtt_cxx:
4+
version: "*"
5+
override_path: '../../../'
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
#include "catch2/catch_session.hpp"
7+
#include "catch2/catch_test_macros.hpp"
8+
#include "esp_mqtt.hpp"
9+
#include "esp_mqtt_client_config.hpp"
10+
#include "esp_netif.h"
11+
12+
namespace mqtt = idf::mqtt;
13+
14+
namespace {
15+
class TestClient final : public mqtt::Client {
16+
public:
17+
using mqtt::Client::Client;
18+
19+
bool constructed{false};
20+
bool before_connect{false};
21+
bool disconnected{false};
22+
23+
TestClient(const mqtt::BrokerConfiguration &broker, const mqtt::ClientCredentials &credentials, const mqtt::Configuration &config) :
24+
mqtt::Client(broker, credentials, config)
25+
{
26+
constructed = true;
27+
}
28+
29+
private:
30+
void on_connected(esp_mqtt_event_handle_t const event) override
31+
{
32+
CHECK(constructed);
33+
}
34+
35+
void on_data(esp_mqtt_event_handle_t const event) override
36+
{
37+
CHECK(constructed);
38+
}
39+
40+
void on_before_connect(esp_mqtt_event_handle_t const event) override
41+
{
42+
CHECK(constructed);
43+
before_connect = true;
44+
}
45+
46+
void on_disconnected(const esp_mqtt_event_handle_t event) override
47+
{
48+
CHECK(constructed);
49+
disconnected = true;
50+
51+
}
52+
53+
};
54+
} // namespace
55+
56+
TEST_CASE("Client does not auto-start and can dispatch events after construction", "[esp_mqtt_cxx]")
57+
{
58+
mqtt::BrokerConfiguration broker{
59+
.address = mqtt::URI{std::string{"mqtt://127.0.0.1:1883"}},
60+
.security = mqtt::Insecure{}
61+
};
62+
mqtt::ClientCredentials credentials{};
63+
mqtt::Configuration config{};
64+
65+
TestClient client{broker, credentials, config};
66+
67+
REQUIRE(client.is_started() == false);
68+
69+
// start the client and expect disconnection (reset by peer)
70+
// since no server's running on this ESP32
71+
client.start();
72+
CHECK(client.is_started() == true);
73+
74+
CHECK(client.before_connect);
75+
usleep(10000);
76+
CHECK(client.disconnected);
77+
}
78+
79+
extern "C" void app_main(void)
80+
{
81+
ESP_ERROR_CHECK(esp_netif_init());
82+
ESP_ERROR_CHECK(esp_event_loop_create_default());
83+
84+
Catch::Session session;
85+
86+
int failures = session.run();
87+
if (failures > 0) {
88+
printf("TEST FAILED! number of failures=%d\n", failures);
89+
return;
90+
}
91+
printf("Test passed!\n");
92+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
CONFIG_COMPILER_CXX_EXCEPTIONS=y
2+
CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192
3+
CONFIG_LWIP_PPP_SUPPORT=y
4+
CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE=y

0 commit comments

Comments
 (0)