Merge branch 'feat/mqtt_test_local_broker' into 'master'

feat(mqtt): Add publish stress test with local broker

See merge request espressif/esp-idf!33535
pull/14997/head
Rocha Euripedes 2024-12-04 21:47:11 +08:00
commit 11902d1a6f
6 zmienionych plików z 92 dodań i 13 usunięć

Wyświetl plik

@ -2,10 +2,6 @@
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
# (Not part of the boilerplate)
# This example uses an extra component for common functions such as Wi-Fi and Ethernet connection.
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/protocol_examples_common)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(mqtt_publish_connect_test)

Wyświetl plik

@ -34,7 +34,7 @@ menu "Example Configuration"
string "subscribe topic"
default "/topic/subscribe/py2esp"
help
topic to which esp32 client subsribes (and expects data)
topic to which esp32 client subscribes (and expects data)
config EXAMPLE_BROKER_CERTIFICATE_OVERRIDE
string "Broker certificate override"
@ -47,6 +47,27 @@ menu "Example Configuration"
bool
default y if EXAMPLE_BROKER_CERTIFICATE_OVERRIDE != ""
config EXAMPLE_RUN_LOCAL_BROKER
bool "Run local mosquitto"
default n
help
If enabled, this tests uses local mosquitto broker
running on the same endpoint as the client
config EXAMPLE_BROKER_HOST
string "Broker host address"
default "0.0.0.0"
depends on EXAMPLE_RUN_LOCAL_BROKER
help
Host name of the endpoint to bind the mosquitto listener.
config EXAMPLE_BROKER_PORT
int "Broker port"
default 1234
depends on EXAMPLE_RUN_LOCAL_BROKER
help
Port of the endpoint to bind the mosquitto listener
config EXAMPLE_CONNECT_CASE_NO_CERT
# Note: All the below config values (EXAMPLE_CONNECT_CASE...) are hidden and
# used to give symbolic names to test cases, which are then referenced from both

Wyświetl plik

@ -0,0 +1,8 @@
## IDF Component Manager Manifest File
dependencies:
espressif/mosquitto:
version: "*"
protocol_examples_common:
path: ${IDF_PATH}/examples/common_components/protocol_examples_common
idf:
version: ">=4.1.0"

Wyświetl plik

@ -20,6 +20,7 @@
#include "argtable3/argtable3.h"
#include "esp_log.h"
#include "publish_connect_test.h"
#include "mosq_broker.h"
static const char *TAG = "publish_connect_test";
@ -47,7 +48,7 @@ static int do_init(int argc, char **argv) {
(void)argc;
(void)argv;
const esp_mqtt_client_config_t mqtt_cfg = {
.broker.address.uri = "mqtts://127.0.0.1:1234",
.broker.address.uri = "mqtt://127.0.0.1:1234",
.network.disable_auto_reconnect = true
};
command_context.mqtt_client = esp_mqtt_client_init(&mqtt_cfg);
@ -78,7 +79,7 @@ static int do_stop(int argc, char **argv) {
ESP_LOGE(TAG, "Failed to stop mqtt client task");
return 1;
}
ESP_LOGI(TAG, "Mqtt client stoped");
ESP_LOGI(TAG, "Mqtt client stopped");
return 0;
}
@ -286,6 +287,15 @@ void register_connect_commands(void){
ESP_ERROR_CHECK(esp_console_cmd_register(&connection_teardown));
}
#ifdef CONFIG_EXAMPLE_RUN_LOCAL_BROKER
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 };
mosq_broker_run(&config);
}
#endif // CONFIG_EXAMPLE_RUN_LOCAL_BROKER
void app_main(void)
{
static const size_t max_line = 256;
@ -301,6 +311,9 @@ void app_main(void)
ESP_ERROR_CHECK(nvs_flash_init());
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
#ifdef CONFIG_EXAMPLE_RUN_LOCAL_BROKER
xTaskCreate(broker_task, "broker", 4096, NULL, 4, NULL);
#endif
ESP_ERROR_CHECK(example_connect());
esp_console_repl_t *repl = NULL;
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();

Wyświetl plik

@ -1,6 +1,5 @@
# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Unlicense OR CC0-1.0
import contextlib
import difflib
import logging
@ -9,9 +8,15 @@ import random
import re
import ssl
import string
from itertools import count, product
from threading import Event, Lock
from typing import Any, Dict, List, Tuple, no_type_check
from itertools import count
from itertools import product
from threading import Event
from threading import Lock
from typing import Any
from typing import Dict
from typing import List
from typing import no_type_check
from typing import Tuple
import paho.mqtt.client as mqtt
import pexpect
@ -152,7 +157,7 @@ def get_scenarios() -> List[Dict[str, int]]:
def get_timeout(test_case: Any) -> int:
transport, qos, enqueue, scenario = test_case
if transport in ['ws', 'wss'] or qos == 2:
return 90
return 120
return 60
@ -198,6 +203,11 @@ stress_scenarios = [{'len':20, 'repeat':50}] # many medium sized
transport_cases = ['tcp', 'ws', 'wss', 'ssl']
qos_cases = [0, 1, 2]
enqueue_cases = [0, 1]
local_broker_supported_transports = ['tcp']
local_broker_scenarios = [{'len':0, 'repeat':5}, # zero-sized messages
{'len':5, 'repeat':20}, # short messages
{'len':500, 'repeat':10}, # long messages
{'len':20, 'repeat':20}] # many medium sized
def make_cases(scenarios: List[Dict[str, int]]) -> List[Tuple[str, int, int, Dict[str, int]]]:
@ -212,6 +222,7 @@ stress_test_cases = make_cases(stress_scenarios)
@pytest.mark.ethernet
@pytest.mark.nightly_run
@pytest.mark.parametrize('test_case', test_cases)
@pytest.mark.parametrize('config', ['default'], indirect=True)
def test_mqtt_publish(dut: Dut, test_case: Any) -> None:
publish_cfg = get_configurations(dut)
dut.expect(re.compile(rb'mqtt>'), timeout=30)
@ -223,8 +234,25 @@ def test_mqtt_publish(dut: Dut, test_case: Any) -> None:
@pytest.mark.ethernet
@pytest.mark.nightly_run
@pytest.mark.parametrize('test_case', stress_test_cases)
@pytest.mark.parametrize('config', ['default'], indirect=True)
def test_mqtt_publish_stress(dut: Dut, test_case: Any) -> None:
publish_cfg = get_configurations(dut)
dut.expect(re.compile(rb'mqtt>'), timeout=30)
dut.write('init')
run_publish_test_case(dut, test_case, publish_cfg)
@pytest.mark.esp32
@pytest.mark.ethernet
@pytest.mark.parametrize('test_case', make_cases(local_broker_scenarios))
@pytest.mark.parametrize('config', ['local_broker'], indirect=True)
def test_mqtt_publish_lcoal(dut: Dut, test_case: Any) -> None:
if test_case[0] not in local_broker_supported_transports:
pytest.skip(f'Skipping transport: {test_case[0]}...')
dut_ip = dut.expect(r'esp_netif_handlers: .+ ip: (\d+\.\d+\.\d+\.\d+),').group(1)
publish_cfg = get_configurations(dut)
publish_cfg['broker_host_tcp'] = dut_ip
publish_cfg['broker_port_tcp'] = 1234
dut.expect(re.compile(rb'mqtt>'), timeout=30)
dut.confirm_write('init', expect_pattern='init', timeout=30)
run_publish_test_case(dut, test_case, publish_cfg)

Wyświetl plik

@ -0,0 +1,13 @@
CONFIG_EXAMPLE_BROKER_SSL_URI=""
CONFIG_EXAMPLE_BROKER_TCP_URI="mqtt://127.0.0.1:1234"
CONFIG_EXAMPLE_BROKER_WS_URI=""
CONFIG_EXAMPLE_BROKER_WSS_URI=""
CONFIG_EXAMPLE_BROKER_CERTIFICATE_OVERRIDE=""
CONFIG_ESP_TLS_INSECURE=y
CONFIG_ESP_TLS_SKIP_SERVER_CERT_VERIFY=y
CONFIG_EXAMPLE_CONNECT_ETHERNET=y
CONFIG_EXAMPLE_CONNECT_WIFI=n
CONFIG_MQTT_USE_CUSTOM_CONFIG=y
CONFIG_MQTT_POLL_READ_TIMEOUT_MS=50
CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE=y
CONFIG_EXAMPLE_RUN_LOCAL_BROKER=y