mqtt tests: connect to local broker when running in CI to make the tests more reliable

This commit is contained in:
David Cermak
2018-12-07 15:15:34 +01:00
parent fe19ea977b
commit 00bf376bc3
16 changed files with 346 additions and 186 deletions

View File

@ -240,6 +240,7 @@ build_esp_idf_tests_cmake:
when: always when: always
paths: paths:
- build_examples/*/*/*/build/*.bin - build_examples/*/*/*/build/*.bin
- build_examples/*/*/*/sdkconfig
- build_examples/*/*/*/build/*.elf - build_examples/*/*/*/build/*.elf
- build_examples/*/*/*/build/*.map - build_examples/*/*/*/build/*.map
- build_examples/*/*/*/build/download.config - build_examples/*/*/*/build/download.config
@ -272,6 +273,7 @@ build_esp_idf_tests_cmake:
when: always when: always
paths: paths:
- build_examples_cmake/*/*/*/build/*.bin - build_examples_cmake/*/*/*/build/*.bin
- build_examples_cmake/*/*/*/sdkconfig
- build_examples_cmake/*/*/*/build/*.elf - build_examples_cmake/*/*/*/build/*.elf
- build_examples_cmake/*/*/*/build/*.map - build_examples_cmake/*/*/*/build/*.map
- build_examples_cmake/*/*/*/build/download.config - build_examples_cmake/*/*/*/build/download.config

View File

@ -12,4 +12,20 @@ config WIFI_PASSWORD
help help
WiFi password (WPA or WPA2) for the example to use. WiFi password (WPA or WPA2) for the example to use.
config BROKER_URI
string "Broker URL"
default "mqtts://iot.eclipse.org:8883"
help
URL of an mqtt broker which this example connects to.
config BROKER_CERTIFICATE_OVERRIDE
string "Broker certificate override"
default ""
help
Please leave empty if broker certificate included from a textfile; otherwise fill in a base64 part of PEM format certificate
config BROKER_CERTIFICATE_OVERRIDDEN
bool
default y if BROKER_CERTIFICATE_OVERRIDE != ""
endmenu endmenu

View File

@ -69,7 +69,11 @@ static void wifi_init(void)
xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY);
} }
extern const uint8_t iot_eclipse_org_pem_start[] asm("_binary_iot_eclipse_org_pem_start"); #if CONFIG_BROKER_CERTIFICATE_OVERRIDDEN == 1
static const uint8_t iot_eclipse_org_pem_start[] = "-----BEGIN CERTIFICATE-----\n" CONFIG_BROKER_CERTIFICATE_OVERRIDE "\n-----END CERTIFICATE-----";
#else
extern const uint8_t iot_eclipse_org_pem_start[] asm("_binary_iot_eclipse_org_pem_start");
#endif
extern const uint8_t iot_eclipse_org_pem_end[] asm("_binary_iot_eclipse_org_pem_end"); extern const uint8_t iot_eclipse_org_pem_end[] asm("_binary_iot_eclipse_org_pem_end");
static esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t event) static esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t event)
@ -116,10 +120,11 @@ static esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t event)
return ESP_OK; return ESP_OK;
} }
static void mqtt_app_start(void) static void mqtt_app_start(void)
{ {
const esp_mqtt_client_config_t mqtt_cfg = { const esp_mqtt_client_config_t mqtt_cfg = {
.uri = "mqtts://iot.eclipse.org:8883", .uri = CONFIG_BROKER_URI,
.event_handle = mqtt_event_handler, .event_handle = mqtt_event_handler,
.cert_pem = (const char *)iot_eclipse_org_pem_start, .cert_pem = (const char *)iot_eclipse_org_pem_start,
}; };

View File

@ -1,54 +1,62 @@
from __future__ import print_function
from __future__ import unicode_literals
from builtins import str
import re import re
import os import os
import sys import sys
import time
import socket
import imp
import ssl import ssl
import paho.mqtt.client as mqtt import paho.mqtt.client as mqtt
from threading import Thread, Event
try:
import IDF
except ImportError:
# this is a test case write with tiny-test-fw.
# to run test cases outside tiny-test-fw,
# we need to set environment variable `TEST_FW_PATH`,
# then get and insert `TEST_FW_PATH` to sys path before import FW module
test_fw_path = os.getenv("TEST_FW_PATH")
if test_fw_path and test_fw_path not in sys.path:
sys.path.insert(0, test_fw_path)
import IDF
import DUT
event_client_connected = Event()
event_stop_client = Event()
event_client_received_correct = Event()
message_log = ""
g_recv_data=""
g_recv_topic=""
g_broker_connected=0
# The callback for when the client receives a CONNACK response from the server. # The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc): def on_connect(client, userdata, flags, rc):
global g_broker_connected print("Connected with result code " + str(rc))
print("Connected with result code "+str(rc)) event_client_connected.set()
g_broker_connected = 1
client.subscribe("/topic/qos0") client.subscribe("/topic/qos0")
def mqtt_client_task(client):
while not event_stop_client.is_set():
client.loop()
# The callback for when a PUBLISH message is received from the server. # The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg): def on_message(client, userdata, msg):
global g_recv_topic global message_log
global g_recv_data
payload = msg.payload.decode() payload = msg.payload.decode()
if g_recv_data == "" and payload == "data": if not event_client_received_correct.is_set() and payload == "data":
client.publish("/topic/qos0", "data_to_esp32") client.publish("/topic/qos0", "data_to_esp32")
g_recv_topic = msg.topic if msg.topic == "/topic/qos0" and payload == "data":
g_recv_data = payload event_client_received_correct.set()
print(msg.topic+" "+str(payload)) message_log += "Received data:" + msg.topic + " " + payload + "\n"
# this is a test case write with tiny-test-fw.
# to run test cases outside tiny-test-fw,
# we need to set environment variable `TEST_FW_PATH`,
# then get and insert `TEST_FW_PATH` to sys path before import FW module
test_fw_path = os.getenv("TEST_FW_PATH")
if test_fw_path and test_fw_path not in sys.path:
sys.path.insert(0, test_fw_path)
import TinyFW
import IDF
import DUT
@IDF.idf_example_test(env_tag="Example_WIFI") @IDF.idf_example_test(env_tag="Example_WIFI")
def test_examples_protocol_mqtt_ssl(env, extra_data): def test_examples_protocol_mqtt_ssl(env, extra_data):
global g_recv_topic broker_url = ""
global g_recv_data broker_port = 0
global g_broker_connected
broker_url="iot.eclipse.org"
""" """
steps: | steps: |
1. join AP and connects to ssl broker 1. join AP and connects to ssl broker
@ -60,15 +68,20 @@ def test_examples_protocol_mqtt_ssl(env, extra_data):
# check and log bin size # check and log bin size
binary_file = os.path.join(dut1.app.binary_path, "mqtt_ssl.bin") binary_file = os.path.join(dut1.app.binary_path, "mqtt_ssl.bin")
bin_size = os.path.getsize(binary_file) bin_size = os.path.getsize(binary_file)
IDF.log_performance("mqtt_ssl_bin_size", "{}KB".format(bin_size//1024)) IDF.log_performance("mqtt_ssl_bin_size", "{}KB"
IDF.check_performance("mqtt_ssl_size", bin_size//1024) .format(bin_size // 1024))
# 1. start test (and check the environment is healthy) IDF.check_performance("mqtt_ssl_size", bin_size // 1024)
dut1.start_app() # Look for host:port in sdkconfig
client = None try:
# 2. Test connects to a broker value = re.search(r'\:\/\/([^:]+)\:([0-9]+)', dut1.app.get_sdkconfig()["CONFIG_BROKER_URI"])
broker_url = value.group(1)
broker_port = int(value.group(2))
except Exception:
print('ENV_TEST_FAILURE: Cannot find broker url in sdkconfig')
raise
client = None
# 1. Test connects to a broker
try: try:
ip_address = dut1.expect(re.compile(r" sta ip: ([^,]+),"), timeout=30)
print("Connected to AP with IP: {}".format(ip_address))
client = mqtt.Client() client = mqtt.Client()
client.on_connect = on_connect client.on_connect = on_connect
client.on_message = on_message client.on_message = on_message
@ -77,28 +90,32 @@ def test_examples_protocol_mqtt_ssl(env, extra_data):
None, cert_reqs=ssl.CERT_NONE, tls_version=ssl.PROTOCOL_TLSv1, ciphers=None) None, cert_reqs=ssl.CERT_NONE, tls_version=ssl.PROTOCOL_TLSv1, ciphers=None)
client.tls_insecure_set(True) client.tls_insecure_set(True)
print("Connecting...") print("Connecting...")
client.connect(broker_url, 8883, 60) client.connect(broker_url, broker_port, 60)
print("...done") except Exception:
except DUT.ExpectTimeout:
raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP')
except:
print("ENV_TEST_FAILURE: Unexpected error while connecting to broker {}: {}:".format(broker_url, sys.exc_info()[0])) print("ENV_TEST_FAILURE: Unexpected error while connecting to broker {}: {}:".format(broker_url, sys.exc_info()[0]))
raise raise
print("Start Looping...") # Starting a py-client in a separate thread
start = time.time() thread1 = Thread(target=mqtt_client_task, args=(client,))
while (time.time() - start) <= 20: thread1.start()
client.loop() try:
print("...done") print("Connecting py-client to broker {}:{}...".format(broker_url, broker_port))
if g_broker_connected == 0: if not event_client_connected.wait(timeout=30):
raise ValueError('ENV_TEST_FAILURE: Test script cannot connect to broker: {}'.format(broker_url)) raise ValueError("ENV_TEST_FAILURE: Test script cannot connect to broker: {}".format(broker_url))
# 3. check the message received back from the server dut1.start_app()
if g_recv_topic == "/topic/qos0" and g_recv_data == "data" : try:
print("PASS: Received correct message") ip_address = dut1.expect(re.compile(r" sta ip: ([^,]+),"), timeout=30)
else: print("Connected to AP with IP: {}".format(ip_address))
print("Failure!") except DUT.ExpectTimeout:
raise ValueError('Wrong data received topic: {}, data:{}'.format(g_recv_topic, g_recv_data)) print('ENV_TEST_FAILURE: Cannot connect to AP')
# 4. check that the esp32 client received data sent by this python client raise
dut1.expect(re.compile(r"DATA=data_to_esp32"), timeout=30) print("Checking py-client received msg published from esp...")
if not event_client_received_correct.wait(timeout=30):
raise ValueError('Wrong data received, msg log: {}'.format(message_log))
print("Checking esp-client received msg published from py-client...")
dut1.expect(re.compile(r"DATA=data_to_esp32"), timeout=30)
finally:
event_stop_client.set()
thread1.join()
if __name__ == '__main__': if __name__ == '__main__':
test_examples_protocol_mqtt_ssl() test_examples_protocol_mqtt_ssl()

View File

@ -0,0 +1,2 @@
CONFIG_BROKER_URI="mqtts://${EXAMPLE_MQTT_BROKER_SSL}"
CONFIG_BROKER_CERTIFICATE_OVERRIDE="${EXAMPLE_MQTT_BROKER_CERTIFICATE}"

View File

@ -19,7 +19,7 @@ config BROKER_URL
URL of the broker to connect to URL of the broker to connect to
config BROKER_URL_FROM_STDIN config BROKER_URL_FROM_STDIN
bool bool
default y if BROKER_URL = "FROM_STDIN" default y if BROKER_URL = "FROM_STDIN"
endmenu endmenu

View File

@ -12,4 +12,10 @@ config WIFI_PASSWORD
help help
WiFi password (WPA or WPA2) for the example to use. WiFi password (WPA or WPA2) for the example to use.
config BROKER_URI
string "Broker URL"
default "ws://iot.eclipse.org:80/ws"
help
URL of an mqtt broker which this example connects to.
endmenu endmenu

View File

@ -115,7 +115,7 @@ static void wifi_init(void)
static void mqtt_app_start(void) static void mqtt_app_start(void)
{ {
const esp_mqtt_client_config_t mqtt_cfg = { const esp_mqtt_client_config_t mqtt_cfg = {
.uri = "ws://iot.eclipse.org:80/ws", .uri = CONFIG_BROKER_URI,
.event_handle = mqtt_event_handler, .event_handle = mqtt_event_handler,
// .user_context = (void *)your_context // .user_context = (void *)your_context
}; };

View File

@ -4,52 +4,57 @@ from builtins import str
import re import re
import os import os
import sys import sys
import time
import socket
import imp
import paho.mqtt.client as mqtt import paho.mqtt.client as mqtt
from threading import Thread, Event
try:
import IDF
except Exception:
# this is a test case write with tiny-test-fw.
# to run test cases outside tiny-test-fw,
# we need to set environment variable `TEST_FW_PATH`,
# then get and insert `TEST_FW_PATH` to sys path before import FW module
test_fw_path = os.getenv("TEST_FW_PATH")
if test_fw_path and test_fw_path not in sys.path:
sys.path.insert(0, test_fw_path)
import IDF
import DUT
event_client_connected = Event()
event_stop_client = Event()
event_client_received_correct = Event()
message_log = ""
g_recv_data=""
g_recv_topic=""
g_broker_connected=0
# The callback for when the client receives a CONNACK response from the server. # The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc): def on_connect(client, userdata, flags, rc):
global g_broker_connected print("Connected with result code " + str(rc))
print("Connected with result code "+str(rc)) event_client_connected.set()
g_broker_connected = 1
client.subscribe("/topic/qos0") client.subscribe("/topic/qos0")
def mqtt_client_task(client):
while not event_stop_client.is_set():
client.loop()
# The callback for when a PUBLISH message is received from the server. # The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg): def on_message(client, userdata, msg):
global g_recv_topic global message_log
global g_recv_data
payload = msg.payload.decode() payload = msg.payload.decode()
if g_recv_data == "" and payload == "data": if not event_client_received_correct.is_set() and payload == "data":
client.publish("/topic/qos0", "data_to_esp32") client.publish("/topic/qos0", "data_to_esp32")
g_recv_topic = msg.topic if msg.topic == "/topic/qos0" and payload == "data":
g_recv_data = payload event_client_received_correct.set()
print(msg.topic+" "+payload) message_log += "Received data:" + msg.topic + " " + payload + "\n"
# this is a test case write with tiny-test-fw.
# to run test cases outside tiny-test-fw,
# we need to set environment variable `TEST_FW_PATH`,
# then get and insert `TEST_FW_PATH` to sys path before import FW module
test_fw_path = os.getenv("TEST_FW_PATH")
if test_fw_path and test_fw_path not in sys.path:
sys.path.insert(0, test_fw_path)
import TinyFW
import IDF
import DUT
@IDF.idf_example_test(env_tag="Example_WIFI") @IDF.idf_example_test(env_tag="Example_WIFI")
def test_examples_protocol_mqtt_ws(env, extra_data): def test_examples_protocol_mqtt_ws(env, extra_data):
global g_recv_topic broker_url = ""
global g_recv_data broker_port = 0
global g_broker_connected
broker_url="iot.eclipse.org"
""" """
steps: | steps: |
1. join AP and connects to ws broker 1. join AP and connects to ws broker
@ -61,42 +66,50 @@ def test_examples_protocol_mqtt_ws(env, extra_data):
# check and log bin size # check and log bin size
binary_file = os.path.join(dut1.app.binary_path, "mqtt_websocket.bin") binary_file = os.path.join(dut1.app.binary_path, "mqtt_websocket.bin")
bin_size = os.path.getsize(binary_file) bin_size = os.path.getsize(binary_file)
IDF.log_performance("mqtt_websocket_bin_size", "{}KB".format(bin_size//1024)) IDF.log_performance("mqtt_websocket_bin_size", "{}KB".format(bin_size // 1024))
IDF.check_performance("mqtt_websocket_size", bin_size//1024) IDF.check_performance("mqtt_websocket_size", bin_size // 1024)
# 1. start test (and check the environment is healthy) # Look for host:port in sdkconfig
dut1.start_app() try:
client = None value = re.search(r'\:\/\/([^:]+)\:([0-9]+)', dut1.app.get_sdkconfig()["CONFIG_BROKER_URI"])
# 2. Test connects to a broker broker_url = value.group(1)
broker_port = int(value.group(2))
except Exception:
print('ENV_TEST_FAILURE: Cannot find broker url in sdkconfig')
raise
client = None
# 1. Test connects to a broker
try: try:
ip_address = dut1.expect(re.compile(r" sta ip: ([^,]+),"), timeout=30)
print("Connected to AP with IP: {}".format(ip_address))
client = mqtt.Client(transport="websockets") client = mqtt.Client(transport="websockets")
client.on_connect = on_connect client.on_connect = on_connect
client.on_message = on_message client.on_message = on_message
client.ws_set_options(path="/ws", headers=None) client.ws_set_options(path="/ws", headers=None)
print("Connecting...") print("Connecting...")
client.connect(broker_url, 80, 60) client.connect(broker_url, broker_port, 60)
print("...done") except Exception:
except DUT.ExpectTimeout:
raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP')
except:
print("ENV_TEST_FAILURE: Unexpected error while connecting to broker {}: {}:".format(broker_url, sys.exc_info()[0])) print("ENV_TEST_FAILURE: Unexpected error while connecting to broker {}: {}:".format(broker_url, sys.exc_info()[0]))
raise raise
print("Start Looping...") # Starting a py-client in a separate thread
start = time.time() thread1 = Thread(target=mqtt_client_task, args=(client,))
while (time.time() - start) <= 20: thread1.start()
client.loop() try:
print("...done") print("Connecting py-client to broker {}:{}...".format(broker_url, broker_port))
if g_broker_connected == 0: if not event_client_connected.wait(timeout=30):
raise ValueError('ENV_TEST_FAILURE: Test script cannot connect to broker: {}'.format(broker_url)) raise ValueError("ENV_TEST_FAILURE: Test script cannot connect to broker: {}".format(broker_url))
# 3. check the message received back from the server dut1.start_app()
if g_recv_topic == "/topic/qos0" and g_recv_data == "data" : try:
print("PASS: Received correct message") ip_address = dut1.expect(re.compile(r" sta ip: ([^,]+),"), timeout=30)
else: print("Connected to AP with IP: {}".format(ip_address))
print("Failure!") except DUT.ExpectTimeout:
raise ValueError('Wrong data received topic: {}, data:{}'.format(g_recv_topic, g_recv_data)) print('ENV_TEST_FAILURE: Cannot connect to AP')
# 4. check that the esp32 client received data sent by this python client raise
dut1.expect(re.compile(r"DATA=data_to_esp32"), timeout=30) print("Checking py-client received msg published from esp...")
if not event_client_received_correct.wait(timeout=30):
raise ValueError('Wrong data received, msg log: {}'.format(message_log))
print("Checking esp-client received msg published from py-client...")
dut1.expect(re.compile(r"DATA=data_to_esp32"), timeout=30)
finally:
event_stop_client.set()
thread1.join()
if __name__ == '__main__': if __name__ == '__main__':
test_examples_protocol_mqtt_ws() test_examples_protocol_mqtt_ws()

View File

@ -0,0 +1 @@
CONFIG_BROKER_URI="ws://${EXAMPLE_MQTT_BROKER_WS}/ws"

View File

@ -12,4 +12,20 @@ config WIFI_PASSWORD
help help
WiFi password (WPA or WPA2) for the example to use. WiFi password (WPA or WPA2) for the example to use.
config BROKER_URI
string "Broker URL"
default "wss://iot.eclipse.org:443/ws"
help
URL of an mqtt broker which this example connects to.
config BROKER_CERTIFICATE_OVERRIDE
string "Server certificate override"
default ""
help
Please leave empty if server certificate included from a textfile; otherwise fill in a base64 part of PEM format certificate
config BROKER_CERTIFICATE_OVERRIDDEN
bool
default y if BROKER_CERTIFICATE_OVERRIDE != ""
endmenu endmenu

View File

@ -69,7 +69,11 @@ static void wifi_init(void)
xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY); xEventGroupWaitBits(wifi_event_group, CONNECTED_BIT, false, true, portMAX_DELAY);
} }
extern const uint8_t iot_eclipse_org_pem_start[] asm("_binary_iot_eclipse_org_pem_start"); #if CONFIG_BROKER_CERTIFICATE_OVERRIDDEN == 1
static const uint8_t iot_eclipse_org_pem_start[] = "-----BEGIN CERTIFICATE-----\n" CONFIG_BROKER_CERTIFICATE_OVERRIDE "\n-----END CERTIFICATE-----";
#else
extern const uint8_t iot_eclipse_org_pem_start[] asm("_binary_iot_eclipse_org_pem_start");
#endif
extern const uint8_t iot_eclipse_org_pem_end[] asm("_binary_iot_eclipse_org_pem_end"); extern const uint8_t iot_eclipse_org_pem_end[] asm("_binary_iot_eclipse_org_pem_end");
static esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t event) static esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t event)
@ -119,7 +123,7 @@ static esp_err_t mqtt_event_handler(esp_mqtt_event_handle_t event)
static void mqtt_app_start(void) static void mqtt_app_start(void)
{ {
const esp_mqtt_client_config_t mqtt_cfg = { const esp_mqtt_client_config_t mqtt_cfg = {
.uri = "wss://iot.eclipse.org:443/ws", .uri = CONFIG_BROKER_URI,
.event_handle = mqtt_event_handler, .event_handle = mqtt_event_handler,
.cert_pem = (const char *)iot_eclipse_org_pem_start, .cert_pem = (const char *)iot_eclipse_org_pem_start,
}; };

View File

@ -1,55 +1,61 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from __future__ import unicode_literals
from builtins import str
import re import re
import os import os
import sys import sys
import time
import socket
import imp
import ssl import ssl
import paho.mqtt.client as mqtt import paho.mqtt.client as mqtt
from threading import Thread, Event
try:
import IDF
except ImportError:
# this is a test case write with tiny-test-fw.
# to run test cases outside tiny-test-fw,
# we need to set environment variable `TEST_FW_PATH`,
# then get and insert `TEST_FW_PATH` to sys path before import FW module
test_fw_path = os.getenv("TEST_FW_PATH")
if test_fw_path and test_fw_path not in sys.path:
sys.path.insert(0, test_fw_path)
import IDF
import DUT
event_client_connected = Event()
event_stop_client = Event()
event_client_received_correct = Event()
message_log = ""
g_recv_data=""
g_recv_topic=""
g_broker_connected=0
# The callback for when the client receives a CONNACK response from the server. # The callback for when the client receives a CONNACK response from the server.
def on_connect(client, userdata, flags, rc): def on_connect(client, userdata, flags, rc):
global g_broker_connected print("Connected with result code " + str(rc))
print("Connected with result code "+str(rc)) event_client_connected.set()
g_broker_connected = 1
client.subscribe("/topic/qos0") client.subscribe("/topic/qos0")
def mqtt_client_task(client):
while not event_stop_client.is_set():
client.loop()
# The callback for when a PUBLISH message is received from the server. # The callback for when a PUBLISH message is received from the server.
def on_message(client, userdata, msg): def on_message(client, userdata, msg):
global g_recv_topic global message_log
global g_recv_data
payload = msg.payload.decode() payload = msg.payload.decode()
if g_recv_data == "" and payload == "data": if not event_client_received_correct.is_set() and payload == "data":
client.publish("/topic/qos0", "data_to_esp32") client.publish("/topic/qos0", "data_to_esp32")
g_recv_topic = msg.topic if msg.topic == "/topic/qos0" and payload == "data":
g_recv_data = payload event_client_received_correct.set()
print(msg.topic+" "+str(payload)) message_log += "Received data:" + msg.topic + " " + payload + "\n"
# this is a test case write with tiny-test-fw.
# to run test cases outside tiny-test-fw,
# we need to set environment variable `TEST_FW_PATH`,
# then get and insert `TEST_FW_PATH` to sys path before import FW module
test_fw_path = os.getenv("TEST_FW_PATH")
if test_fw_path and test_fw_path not in sys.path:
sys.path.insert(0, test_fw_path)
import TinyFW
import IDF
import DUT
@IDF.idf_example_test(env_tag="Example_WIFI") @IDF.idf_example_test(env_tag="Example_WIFI")
def test_examples_protocol_mqtt_wss(env, extra_data): def test_examples_protocol_mqtt_wss(env, extra_data):
global g_recv_topic broker_url = ""
global g_recv_data broker_port = 0
global g_broker_connected
broker_url="iot.eclipse.org"
""" """
steps: | steps: |
1. join AP and connects to wss broker 1. join AP and connects to wss broker
@ -61,15 +67,19 @@ def test_examples_protocol_mqtt_wss(env, extra_data):
# check and log bin size # check and log bin size
binary_file = os.path.join(dut1.app.binary_path, "mqtt_websocket_secure.bin") binary_file = os.path.join(dut1.app.binary_path, "mqtt_websocket_secure.bin")
bin_size = os.path.getsize(binary_file) bin_size = os.path.getsize(binary_file)
IDF.log_performance("mqtt_websocket_secure_bin_size", "{}KB".format(bin_size//1024)) IDF.log_performance("mqtt_websocket_secure_bin_size", "{}KB".format(bin_size // 1024))
IDF.check_performance("mqtt_websocket_secure_size", bin_size//1024) IDF.check_performance("mqtt_websocket_secure_size", bin_size // 1024)
# 1. start test (and check the environment is healthy) # Look for host:port in sdkconfig
dut1.start_app() try:
client = None value = re.search(r'\:\/\/([^:]+)\:([0-9]+)', dut1.app.get_sdkconfig()["CONFIG_BROKER_URI"])
# 2. Test connects to a broker broker_url = value.group(1)
broker_port = int(value.group(2))
except Exception:
print('ENV_TEST_FAILURE: Cannot find broker url in sdkconfig')
raise
client = None
# 1. Test connects to a broker
try: try:
ip_address = dut1.expect(re.compile(r" sta ip: ([^,]+),"), timeout=30)
print("Connected to AP with IP: {}".format(ip_address))
client = mqtt.Client(transport="websockets") client = mqtt.Client(transport="websockets")
client.on_connect = on_connect client.on_connect = on_connect
client.on_message = on_message client.on_message = on_message
@ -77,28 +87,32 @@ def test_examples_protocol_mqtt_wss(env, extra_data):
None, None,
None, cert_reqs=ssl.CERT_NONE, tls_version=ssl.PROTOCOL_TLSv1, ciphers=None) None, cert_reqs=ssl.CERT_NONE, tls_version=ssl.PROTOCOL_TLSv1, ciphers=None)
print("Connecting...") print("Connecting...")
client.connect(broker_url, 443, 60) client.connect(broker_url, broker_port, 60)
print("...done") except Exception:
except DUT.ExpectTimeout:
raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP')
except:
print("ENV_TEST_FAILURE: Unexpected error while connecting to broker {}: {}:".format(broker_url, sys.exc_info()[0])) print("ENV_TEST_FAILURE: Unexpected error while connecting to broker {}: {}:".format(broker_url, sys.exc_info()[0]))
raise raise
print("Start Looping...") # Starting a py-client in a separate thread
start = time.time() thread1 = Thread(target=mqtt_client_task, args=(client,))
while (time.time() - start) <= 20: thread1.start()
client.loop() try:
print("...done") print("Connecting py-client to broker {}:{}...".format(broker_url, broker_port))
if g_broker_connected == 0: if not event_client_connected.wait(timeout=30):
raise ValueError('ENV_TEST_FAILURE: Test script cannot connect to broker: {}'.format(broker_url)) raise ValueError("ENV_TEST_FAILURE: Test script cannot connect to broker: {}".format(broker_url))
# 3. check the message received back from the server dut1.start_app()
if g_recv_topic == "/topic/qos0" and g_recv_data == "data" : try:
print("PASS: Received correct message") ip_address = dut1.expect(re.compile(r" sta ip: ([^,]+),"), timeout=30)
else: print("Connected to AP with IP: {}".format(ip_address))
print("Failure!") except DUT.ExpectTimeout:
raise ValueError('Wrong data received topic: {}, data:{}'.format(g_recv_topic, g_recv_data)) print('ENV_TEST_FAILURE: Cannot connect to AP')
# 4. check that the esp32 client received data sent by this python client raise
dut1.expect(re.compile(r"DATA=data_to_esp32"), timeout=30) print("Checking py-client received msg published from esp...")
if not event_client_received_correct.wait(timeout=30):
raise ValueError('Wrong data received, msg log: {}'.format(message_log))
print("Checking esp-client received msg published from py-client...")
dut1.expect(re.compile(r"DATA=data_to_esp32"), timeout=30)
finally:
event_stop_client.set()
thread1.join()
if __name__ == '__main__': if __name__ == '__main__':
test_examples_protocol_mqtt_wss() test_examples_protocol_mqtt_wss()

View File

@ -0,0 +1,3 @@
CONFIG_BROKER_URI="wss://${EXAMPLE_MQTT_BROKER_WSS}/ws"
CONFIG_BROKER_CERTIFICATE_OVERRIDE="${EXAMPLE_MQTT_BROKER_CERTIFICATE}"

27
tools/ci/envsubst.py Executable file
View File

@ -0,0 +1,27 @@
#!/usr/bin/env python
#
# A script similar to GNU envsubst, but filters out
# some CI related variables.
import os
import sys
def main():
# Sanitize environment variables
vars_to_remove = []
for var_name in os.environ.keys():
if var_name.startswith('CI_'):
vars_to_remove.append(var_name)
for var_name in vars_to_remove:
del os.environ[var_name]
for line in sys.stdin:
if not line:
break
sys.stdout.write(os.path.expandvars(line))
sys.stdout.flush()
if __name__ == '__main__':
main()

View File

@ -62,6 +62,34 @@ class IDFApp(App.BaseApp):
"partition_table", "gen_esp32part.py") "partition_table", "gen_esp32part.py")
assert os.path.exists(esptool) and os.path.exists(partition_tool) assert os.path.exists(esptool) and os.path.exists(partition_tool)
return esptool, partition_tool return esptool, partition_tool
def _get_sdkconfig_paths(self):
"""
returns list of possible paths where sdkconfig could be found
Note: could be overwritten by a derived class to provide other locations or order
"""
return [os.path.join(self.binary_path, "sdkconfig"), os.path.join(self.binary_path, "..", "sdkconfig")]
def get_sdkconfig(self):
"""
reads sdkconfig and returns a dictionary with all configuredvariables
:param sdkconfig_file: location of sdkconfig
:raise: AssertionError: if sdkconfig file does not exist in defined paths
"""
d = {}
sdkconfig_file = None
for i in self._get_sdkconfig_paths():
if os.path.exists(i):
sdkconfig_file = i
break
assert sdkconfig_file is not None
with open(sdkconfig_file) as f:
for line in f:
configs = line.split('=')
if len(configs) == 2:
d[configs[0]] = configs[1]
return d
def get_binary_path(self, app_path): def get_binary_path(self, app_path):
""" """
@ -144,6 +172,12 @@ class IDFApp(App.BaseApp):
class Example(IDFApp): class Example(IDFApp):
def _get_sdkconfig_paths(self):
"""
overrides the parent method to provide exact path of sdkconfig for example tests
"""
return [os.path.join(self.binary_path, "..", "sdkconfig")]
def get_binary_path(self, app_path): def get_binary_path(self, app_path):
# build folder of example path # build folder of example path
path = os.path.join(self.idf_path, app_path, "build") path = os.path.join(self.idf_path, app_path, "build")