kopia lustrzana https://github.com/espressif/esp-idf
Merge branch 'feat/mqtt_test_local_broker' into 'master'
feat(mqtt): Add publish stress test with local broker See merge request espressif/esp-idf!33535pull/14997/head
commit
11902d1a6f
|
@ -2,10 +2,6 @@
|
||||||
# in this exact order for cmake to work correctly
|
# in this exact order for cmake to work correctly
|
||||||
cmake_minimum_required(VERSION 3.16)
|
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)
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
|
|
||||||
project(mqtt_publish_connect_test)
|
project(mqtt_publish_connect_test)
|
||||||
|
|
|
@ -34,7 +34,7 @@ menu "Example Configuration"
|
||||||
string "subscribe topic"
|
string "subscribe topic"
|
||||||
default "/topic/subscribe/py2esp"
|
default "/topic/subscribe/py2esp"
|
||||||
help
|
help
|
||||||
topic to which esp32 client subsribes (and expects data)
|
topic to which esp32 client subscribes (and expects data)
|
||||||
|
|
||||||
config EXAMPLE_BROKER_CERTIFICATE_OVERRIDE
|
config EXAMPLE_BROKER_CERTIFICATE_OVERRIDE
|
||||||
string "Broker certificate override"
|
string "Broker certificate override"
|
||||||
|
@ -47,6 +47,27 @@ menu "Example Configuration"
|
||||||
bool
|
bool
|
||||||
default y if EXAMPLE_BROKER_CERTIFICATE_OVERRIDE != ""
|
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
|
config EXAMPLE_CONNECT_CASE_NO_CERT
|
||||||
# Note: All the below config values (EXAMPLE_CONNECT_CASE...) are hidden and
|
# 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
|
# used to give symbolic names to test cases, which are then referenced from both
|
||||||
|
|
|
@ -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"
|
|
@ -20,6 +20,7 @@
|
||||||
#include "argtable3/argtable3.h"
|
#include "argtable3/argtable3.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "publish_connect_test.h"
|
#include "publish_connect_test.h"
|
||||||
|
#include "mosq_broker.h"
|
||||||
|
|
||||||
static const char *TAG = "publish_connect_test";
|
static const char *TAG = "publish_connect_test";
|
||||||
|
|
||||||
|
@ -47,7 +48,7 @@ static int do_init(int argc, char **argv) {
|
||||||
(void)argc;
|
(void)argc;
|
||||||
(void)argv;
|
(void)argv;
|
||||||
const esp_mqtt_client_config_t mqtt_cfg = {
|
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
|
.network.disable_auto_reconnect = true
|
||||||
};
|
};
|
||||||
command_context.mqtt_client = esp_mqtt_client_init(&mqtt_cfg);
|
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");
|
ESP_LOGE(TAG, "Failed to stop mqtt client task");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
ESP_LOGI(TAG, "Mqtt client stoped");
|
ESP_LOGI(TAG, "Mqtt client stopped");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,6 +287,15 @@ void register_connect_commands(void){
|
||||||
ESP_ERROR_CHECK(esp_console_cmd_register(&connection_teardown));
|
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)
|
void app_main(void)
|
||||||
{
|
{
|
||||||
static const size_t max_line = 256;
|
static const size_t max_line = 256;
|
||||||
|
@ -301,6 +311,9 @@ void app_main(void)
|
||||||
ESP_ERROR_CHECK(nvs_flash_init());
|
ESP_ERROR_CHECK(nvs_flash_init());
|
||||||
ESP_ERROR_CHECK(esp_netif_init());
|
ESP_ERROR_CHECK(esp_netif_init());
|
||||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
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_ERROR_CHECK(example_connect());
|
||||||
esp_console_repl_t *repl = NULL;
|
esp_console_repl_t *repl = NULL;
|
||||||
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
|
esp_console_repl_config_t repl_config = ESP_CONSOLE_REPL_CONFIG_DEFAULT();
|
||||||
|
|
|
@ -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
|
# SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||||
|
|
||||||
import contextlib
|
import contextlib
|
||||||
import difflib
|
import difflib
|
||||||
import logging
|
import logging
|
||||||
|
@ -9,9 +8,15 @@ import random
|
||||||
import re
|
import re
|
||||||
import ssl
|
import ssl
|
||||||
import string
|
import string
|
||||||
from itertools import count, product
|
from itertools import count
|
||||||
from threading import Event, Lock
|
from itertools import product
|
||||||
from typing import Any, Dict, List, Tuple, no_type_check
|
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 paho.mqtt.client as mqtt
|
||||||
import pexpect
|
import pexpect
|
||||||
|
@ -152,7 +157,7 @@ def get_scenarios() -> List[Dict[str, int]]:
|
||||||
def get_timeout(test_case: Any) -> int:
|
def get_timeout(test_case: Any) -> int:
|
||||||
transport, qos, enqueue, scenario = test_case
|
transport, qos, enqueue, scenario = test_case
|
||||||
if transport in ['ws', 'wss'] or qos == 2:
|
if transport in ['ws', 'wss'] or qos == 2:
|
||||||
return 90
|
return 120
|
||||||
return 60
|
return 60
|
||||||
|
|
||||||
|
|
||||||
|
@ -198,6 +203,11 @@ stress_scenarios = [{'len':20, 'repeat':50}] # many medium sized
|
||||||
transport_cases = ['tcp', 'ws', 'wss', 'ssl']
|
transport_cases = ['tcp', 'ws', 'wss', 'ssl']
|
||||||
qos_cases = [0, 1, 2]
|
qos_cases = [0, 1, 2]
|
||||||
enqueue_cases = [0, 1]
|
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]]]:
|
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.ethernet
|
||||||
@pytest.mark.nightly_run
|
@pytest.mark.nightly_run
|
||||||
@pytest.mark.parametrize('test_case', test_cases)
|
@pytest.mark.parametrize('test_case', test_cases)
|
||||||
|
@pytest.mark.parametrize('config', ['default'], indirect=True)
|
||||||
def test_mqtt_publish(dut: Dut, test_case: Any) -> None:
|
def test_mqtt_publish(dut: Dut, test_case: Any) -> None:
|
||||||
publish_cfg = get_configurations(dut)
|
publish_cfg = get_configurations(dut)
|
||||||
dut.expect(re.compile(rb'mqtt>'), timeout=30)
|
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.ethernet
|
||||||
@pytest.mark.nightly_run
|
@pytest.mark.nightly_run
|
||||||
@pytest.mark.parametrize('test_case', stress_test_cases)
|
@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:
|
def test_mqtt_publish_stress(dut: Dut, test_case: Any) -> None:
|
||||||
publish_cfg = get_configurations(dut)
|
publish_cfg = get_configurations(dut)
|
||||||
dut.expect(re.compile(rb'mqtt>'), timeout=30)
|
dut.expect(re.compile(rb'mqtt>'), timeout=30)
|
||||||
dut.write('init')
|
dut.write('init')
|
||||||
run_publish_test_case(dut, test_case, publish_cfg)
|
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)
|
||||||
|
|
|
@ -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
|
Ładowanie…
Reference in New Issue