style: format python files with isort and double-quote-string-fixer
This commit is contained in:
@@ -1,16 +1,17 @@
|
||||
from __future__ import print_function
|
||||
from __future__ import unicode_literals
|
||||
import re
|
||||
from __future__ import print_function, unicode_literals
|
||||
|
||||
import os
|
||||
import socket
|
||||
import select
|
||||
import subprocess
|
||||
from threading import Thread, Event
|
||||
import ttfw_idf
|
||||
import ssl
|
||||
import paho.mqtt.client as mqtt
|
||||
import string
|
||||
import random
|
||||
import re
|
||||
import select
|
||||
import socket
|
||||
import ssl
|
||||
import string
|
||||
import subprocess
|
||||
from threading import Event, Thread
|
||||
|
||||
import paho.mqtt.client as mqtt
|
||||
import ttfw_idf
|
||||
|
||||
DEFAULT_MSG_SIZE = 16
|
||||
|
||||
@@ -21,12 +22,12 @@ def _path(f):
|
||||
|
||||
def set_server_cert_cn(ip):
|
||||
arg_list = [
|
||||
['openssl', 'req', '-out', _path('srv.csr'), '-key', _path('server.key'),'-subj', "/CN={}".format(ip), '-new'],
|
||||
['openssl', 'req', '-out', _path('srv.csr'), '-key', _path('server.key'),'-subj', '/CN={}'.format(ip), '-new'],
|
||||
['openssl', 'x509', '-req', '-in', _path('srv.csr'), '-CA', _path('ca.crt'),
|
||||
'-CAkey', _path('ca.key'), '-CAcreateserial', '-out', _path('srv.crt'), '-days', '360']]
|
||||
for args in arg_list:
|
||||
if subprocess.check_call(args) != 0:
|
||||
raise("openssl command {} failed".format(args))
|
||||
raise('openssl command {} failed'.format(args))
|
||||
|
||||
|
||||
def get_my_ip():
|
||||
@@ -54,9 +55,9 @@ class MqttPublisher:
|
||||
self.log_details = log_details
|
||||
self.repeat = repeat
|
||||
self.publish_cfg = publish_cfg
|
||||
self.publish_cfg["qos"] = qos
|
||||
self.publish_cfg["queue"] = queue
|
||||
self.publish_cfg["transport"] = transport
|
||||
self.publish_cfg['qos'] = qos
|
||||
self.publish_cfg['queue'] = queue
|
||||
self.publish_cfg['transport'] = transport
|
||||
# static variables used to pass options to and from static callbacks of paho-mqtt client
|
||||
MqttPublisher.event_client_connected = Event()
|
||||
MqttPublisher.event_client_got_all = Event()
|
||||
@@ -90,52 +91,52 @@ class MqttPublisher:
|
||||
|
||||
def __enter__(self):
|
||||
|
||||
qos = self.publish_cfg["qos"]
|
||||
queue = self.publish_cfg["queue"]
|
||||
transport = self.publish_cfg["transport"]
|
||||
broker_host = self.publish_cfg["broker_host_" + transport]
|
||||
broker_port = self.publish_cfg["broker_port_" + transport]
|
||||
qos = self.publish_cfg['qos']
|
||||
queue = self.publish_cfg['queue']
|
||||
transport = self.publish_cfg['transport']
|
||||
broker_host = self.publish_cfg['broker_host_' + transport]
|
||||
broker_port = self.publish_cfg['broker_port_' + transport]
|
||||
|
||||
# Start the test
|
||||
self.print_details("PUBLISH TEST: transport:{}, qos:{}, sequence:{}, enqueue:{}, sample msg:'{}'"
|
||||
.format(transport, qos, MqttPublisher.published, queue, MqttPublisher.expected_data))
|
||||
|
||||
try:
|
||||
if transport in ["ws", "wss"]:
|
||||
self.client = mqtt.Client(transport="websockets")
|
||||
if transport in ['ws', 'wss']:
|
||||
self.client = mqtt.Client(transport='websockets')
|
||||
else:
|
||||
self.client = mqtt.Client()
|
||||
self.client.on_connect = MqttPublisher.on_connect
|
||||
self.client.on_message = MqttPublisher.on_message
|
||||
self.client.user_data_set(0)
|
||||
|
||||
if transport in ["ssl", "wss"]:
|
||||
if transport in ['ssl', 'wss']:
|
||||
self.client.tls_set(None, None, None, cert_reqs=ssl.CERT_NONE, tls_version=ssl.PROTOCOL_TLSv1_2, ciphers=None)
|
||||
self.client.tls_insecure_set(True)
|
||||
self.print_details("Connecting...")
|
||||
self.print_details('Connecting...')
|
||||
self.client.connect(broker_host, broker_port, 60)
|
||||
except Exception:
|
||||
self.print_details("ENV_TEST_FAILURE: Unexpected error while connecting to broker {}".format(broker_host))
|
||||
self.print_details('ENV_TEST_FAILURE: Unexpected error while connecting to broker {}'.format(broker_host))
|
||||
raise
|
||||
# Starting a py-client in a separate thread
|
||||
thread1 = Thread(target=self.mqtt_client_task, args=(self.client,))
|
||||
thread1.start()
|
||||
self.print_details("Connecting py-client to broker {}:{}...".format(broker_host, broker_port))
|
||||
self.print_details('Connecting py-client to broker {}:{}...'.format(broker_host, broker_port))
|
||||
if not MqttPublisher.event_client_connected.wait(timeout=30):
|
||||
raise ValueError("ENV_TEST_FAILURE: Test script cannot connect to broker: {}".format(broker_host))
|
||||
self.client.subscribe(self.publish_cfg["subscribe_topic"], qos)
|
||||
self.dut.write(' '.join(str(x) for x in (transport, self.sample_string, self.repeat, MqttPublisher.published, qos, queue)), eol="\n")
|
||||
raise ValueError('ENV_TEST_FAILURE: Test script cannot connect to broker: {}'.format(broker_host))
|
||||
self.client.subscribe(self.publish_cfg['subscribe_topic'], qos)
|
||||
self.dut.write(' '.join(str(x) for x in (transport, self.sample_string, self.repeat, MqttPublisher.published, qos, queue)), eol='\n')
|
||||
try:
|
||||
# waiting till subscribed to defined topic
|
||||
self.dut.expect(re.compile(r"MQTT_EVENT_SUBSCRIBED"), timeout=30)
|
||||
self.dut.expect(re.compile(r'MQTT_EVENT_SUBSCRIBED'), timeout=30)
|
||||
for _ in range(MqttPublisher.published):
|
||||
self.client.publish(self.publish_cfg["publish_topic"], self.sample_string * self.repeat, qos)
|
||||
self.print_details("Publishing...")
|
||||
self.print_details("Checking esp-client received msg published from py-client...")
|
||||
self.dut.expect(re.compile(r"Correct pattern received exactly x times"), timeout=60)
|
||||
self.client.publish(self.publish_cfg['publish_topic'], self.sample_string * self.repeat, qos)
|
||||
self.print_details('Publishing...')
|
||||
self.print_details('Checking esp-client received msg published from py-client...')
|
||||
self.dut.expect(re.compile(r'Correct pattern received exactly x times'), timeout=60)
|
||||
if not MqttPublisher.event_client_got_all.wait(timeout=60):
|
||||
raise ValueError("Not all data received from ESP32")
|
||||
print(" - all data received from ESP32")
|
||||
raise ValueError('Not all data received from ESP32')
|
||||
print(' - all data received from ESP32')
|
||||
finally:
|
||||
self.event_stop_client.set()
|
||||
thread1.join()
|
||||
@@ -164,7 +165,7 @@ class TlsServer:
|
||||
try:
|
||||
self.socket.bind(('', self.port))
|
||||
except socket.error as e:
|
||||
print("Bind failed:{}".format(e))
|
||||
print('Bind failed:{}'.format(e))
|
||||
raise
|
||||
|
||||
self.socket.listen(1)
|
||||
@@ -190,23 +191,23 @@ class TlsServer:
|
||||
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
|
||||
if self.client_cert:
|
||||
context.verify_mode = ssl.CERT_REQUIRED
|
||||
context.load_verify_locations(cafile=_path("ca.crt"))
|
||||
context.load_cert_chain(certfile=_path("srv.crt"), keyfile=_path("server.key"))
|
||||
context.load_verify_locations(cafile=_path('ca.crt'))
|
||||
context.load_cert_chain(certfile=_path('srv.crt'), keyfile=_path('server.key'))
|
||||
if self.use_alpn:
|
||||
context.set_alpn_protocols(["mymqtt", "http/1.1"])
|
||||
context.set_alpn_protocols(['mymqtt', 'http/1.1'])
|
||||
self.socket = context.wrap_socket(self.socket, server_side=True)
|
||||
try:
|
||||
self.conn, address = self.socket.accept() # accept new connection
|
||||
self.socket.settimeout(10.0)
|
||||
print(" - connection from: {}".format(address))
|
||||
print(' - connection from: {}'.format(address))
|
||||
if self.use_alpn:
|
||||
self.negotiated_protocol = self.conn.selected_alpn_protocol()
|
||||
print(" - negotiated_protocol: {}".format(self.negotiated_protocol))
|
||||
print(' - negotiated_protocol: {}'.format(self.negotiated_protocol))
|
||||
self.handle_conn()
|
||||
except ssl.SSLError as e:
|
||||
self.conn = None
|
||||
self.ssl_error = str(e)
|
||||
print(" - SSLError: {}".format(str(e)))
|
||||
print(' - SSLError: {}'.format(str(e)))
|
||||
|
||||
def handle_conn(self):
|
||||
while not self.shutdown.is_set():
|
||||
@@ -216,7 +217,7 @@ class TlsServer:
|
||||
self.process_mqtt_connect()
|
||||
|
||||
except socket.error as err:
|
||||
print(" - error: {}".format(err))
|
||||
print(' - error: {}'.format(err))
|
||||
raise
|
||||
|
||||
def process_mqtt_connect(self):
|
||||
@@ -225,20 +226,20 @@ class TlsServer:
|
||||
message = ''.join(format(x, '02x') for x in data)
|
||||
if message[0:16] == '101800044d515454':
|
||||
if self.refuse_connection is False:
|
||||
print(" - received mqtt connect, sending ACK")
|
||||
self.conn.send(bytearray.fromhex("20020000"))
|
||||
print(' - received mqtt connect, sending ACK')
|
||||
self.conn.send(bytearray.fromhex('20020000'))
|
||||
else:
|
||||
# injecting connection not authorized error
|
||||
print(" - received mqtt connect, sending NAK")
|
||||
self.conn.send(bytearray.fromhex("20020005"))
|
||||
print(' - received mqtt connect, sending NAK')
|
||||
self.conn.send(bytearray.fromhex('20020005'))
|
||||
else:
|
||||
raise Exception(" - error process_mqtt_connect unexpected connect received: {}".format(message))
|
||||
raise Exception(' - error process_mqtt_connect unexpected connect received: {}'.format(message))
|
||||
finally:
|
||||
# stop the server after the connect message in happy flow, or if any exception occur
|
||||
self.shutdown.set()
|
||||
|
||||
|
||||
@ttfw_idf.idf_custom_test(env_tag="Example_WIFI", group="test-apps")
|
||||
@ttfw_idf.idf_custom_test(env_tag='Example_WIFI', group='test-apps')
|
||||
def test_app_protocol_mqtt_publish_connect(env, extra_data):
|
||||
"""
|
||||
steps:
|
||||
@@ -246,11 +247,11 @@ def test_app_protocol_mqtt_publish_connect(env, extra_data):
|
||||
2. connect to uri specified in the config
|
||||
3. send and receive data
|
||||
"""
|
||||
dut1 = env.get_dut("mqtt_publish_connect_test", "tools/test_apps/protocols/mqtt/publish_connect_test", dut_class=ttfw_idf.ESP32DUT)
|
||||
dut1 = env.get_dut('mqtt_publish_connect_test', 'tools/test_apps/protocols/mqtt/publish_connect_test', dut_class=ttfw_idf.ESP32DUT)
|
||||
# check and log bin size
|
||||
binary_file = os.path.join(dut1.app.binary_path, "mqtt_publish_connect_test.bin")
|
||||
binary_file = os.path.join(dut1.app.binary_path, 'mqtt_publish_connect_test.bin')
|
||||
bin_size = os.path.getsize(binary_file)
|
||||
ttfw_idf.log_performance("mqtt_publish_connect_test_bin_size", "{}KB".format(bin_size // 1024))
|
||||
ttfw_idf.log_performance('mqtt_publish_connect_test_bin_size', '{}KB'.format(bin_size // 1024))
|
||||
|
||||
# Look for test case symbolic names and publish configs
|
||||
cases = {}
|
||||
@@ -263,30 +264,30 @@ def test_app_protocol_mqtt_publish_connect(env, extra_data):
|
||||
return value.group(1), int(value.group(2))
|
||||
|
||||
# Get connection test cases configuration: symbolic names for test cases
|
||||
for i in ["CONFIG_EXAMPLE_CONNECT_CASE_NO_CERT",
|
||||
"CONFIG_EXAMPLE_CONNECT_CASE_SERVER_CERT",
|
||||
"CONFIG_EXAMPLE_CONNECT_CASE_MUTUAL_AUTH",
|
||||
"CONFIG_EXAMPLE_CONNECT_CASE_INVALID_SERVER_CERT",
|
||||
"CONFIG_EXAMPLE_CONNECT_CASE_SERVER_DER_CERT",
|
||||
"CONFIG_EXAMPLE_CONNECT_CASE_MUTUAL_AUTH_KEY_PWD",
|
||||
"CONFIG_EXAMPLE_CONNECT_CASE_MUTUAL_AUTH_BAD_CRT",
|
||||
"CONFIG_EXAMPLE_CONNECT_CASE_NO_CERT_ALPN"]:
|
||||
for i in ['CONFIG_EXAMPLE_CONNECT_CASE_NO_CERT',
|
||||
'CONFIG_EXAMPLE_CONNECT_CASE_SERVER_CERT',
|
||||
'CONFIG_EXAMPLE_CONNECT_CASE_MUTUAL_AUTH',
|
||||
'CONFIG_EXAMPLE_CONNECT_CASE_INVALID_SERVER_CERT',
|
||||
'CONFIG_EXAMPLE_CONNECT_CASE_SERVER_DER_CERT',
|
||||
'CONFIG_EXAMPLE_CONNECT_CASE_MUTUAL_AUTH_KEY_PWD',
|
||||
'CONFIG_EXAMPLE_CONNECT_CASE_MUTUAL_AUTH_BAD_CRT',
|
||||
'CONFIG_EXAMPLE_CONNECT_CASE_NO_CERT_ALPN']:
|
||||
cases[i] = dut1.app.get_sdkconfig()[i]
|
||||
# Get publish test configuration
|
||||
publish_cfg["publish_topic"] = dut1.app.get_sdkconfig()["CONFIG_EXAMPLE_SUBSCIBE_TOPIC"].replace('"','')
|
||||
publish_cfg["subscribe_topic"] = dut1.app.get_sdkconfig()["CONFIG_EXAMPLE_PUBLISH_TOPIC"].replace('"','')
|
||||
publish_cfg["broker_host_ssl"], publish_cfg["broker_port_ssl"] = get_host_port_from_dut(dut1, "CONFIG_EXAMPLE_BROKER_SSL_URI")
|
||||
publish_cfg["broker_host_tcp"], publish_cfg["broker_port_tcp"] = get_host_port_from_dut(dut1, "CONFIG_EXAMPLE_BROKER_TCP_URI")
|
||||
publish_cfg["broker_host_ws"], publish_cfg["broker_port_ws"] = get_host_port_from_dut(dut1, "CONFIG_EXAMPLE_BROKER_WS_URI")
|
||||
publish_cfg["broker_host_wss"], publish_cfg["broker_port_wss"] = get_host_port_from_dut(dut1, "CONFIG_EXAMPLE_BROKER_WSS_URI")
|
||||
publish_cfg['publish_topic'] = dut1.app.get_sdkconfig()['CONFIG_EXAMPLE_SUBSCIBE_TOPIC'].replace('"','')
|
||||
publish_cfg['subscribe_topic'] = dut1.app.get_sdkconfig()['CONFIG_EXAMPLE_PUBLISH_TOPIC'].replace('"','')
|
||||
publish_cfg['broker_host_ssl'], publish_cfg['broker_port_ssl'] = get_host_port_from_dut(dut1, 'CONFIG_EXAMPLE_BROKER_SSL_URI')
|
||||
publish_cfg['broker_host_tcp'], publish_cfg['broker_port_tcp'] = get_host_port_from_dut(dut1, 'CONFIG_EXAMPLE_BROKER_TCP_URI')
|
||||
publish_cfg['broker_host_ws'], publish_cfg['broker_port_ws'] = get_host_port_from_dut(dut1, 'CONFIG_EXAMPLE_BROKER_WS_URI')
|
||||
publish_cfg['broker_host_wss'], publish_cfg['broker_port_wss'] = get_host_port_from_dut(dut1, 'CONFIG_EXAMPLE_BROKER_WSS_URI')
|
||||
|
||||
except Exception:
|
||||
print('ENV_TEST_FAILURE: Some mandatory test case not found in sdkconfig')
|
||||
raise
|
||||
|
||||
dut1.start_app()
|
||||
esp_ip = dut1.expect(re.compile(r" IPv4 address: ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)"), timeout=30)
|
||||
print("Got IP={}".format(esp_ip[0]))
|
||||
esp_ip = dut1.expect(re.compile(r' IPv4 address: ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)'), timeout=30)
|
||||
print('Got IP={}'.format(esp_ip[0]))
|
||||
|
||||
#
|
||||
# start connection test
|
||||
@@ -295,73 +296,73 @@ def test_app_protocol_mqtt_publish_connect(env, extra_data):
|
||||
server_port = 2222
|
||||
|
||||
def start_connection_case(case, desc):
|
||||
print("Starting {}: {}".format(case, desc))
|
||||
print('Starting {}: {}'.format(case, desc))
|
||||
case_id = cases[case]
|
||||
dut1.write("conn {} {} {}".format(ip, server_port, case_id))
|
||||
dut1.expect("Test case:{} started".format(case_id))
|
||||
dut1.write('conn {} {} {}'.format(ip, server_port, case_id))
|
||||
dut1.expect('Test case:{} started'.format(case_id))
|
||||
return case_id
|
||||
|
||||
for case in ["CONFIG_EXAMPLE_CONNECT_CASE_NO_CERT", "CONFIG_EXAMPLE_CONNECT_CASE_SERVER_CERT", "CONFIG_EXAMPLE_CONNECT_CASE_SERVER_DER_CERT"]:
|
||||
for case in ['CONFIG_EXAMPLE_CONNECT_CASE_NO_CERT', 'CONFIG_EXAMPLE_CONNECT_CASE_SERVER_CERT', 'CONFIG_EXAMPLE_CONNECT_CASE_SERVER_DER_CERT']:
|
||||
# All these cases connect to the server with no server verification or with server only verification
|
||||
with TlsServer(server_port):
|
||||
test_nr = start_connection_case(case, "default server - expect to connect normally")
|
||||
dut1.expect("MQTT_EVENT_CONNECTED: Test={}".format(test_nr), timeout=30)
|
||||
test_nr = start_connection_case(case, 'default server - expect to connect normally')
|
||||
dut1.expect('MQTT_EVENT_CONNECTED: Test={}'.format(test_nr), timeout=30)
|
||||
with TlsServer(server_port, refuse_connection=True):
|
||||
test_nr = start_connection_case(case, "ssl shall connect, but mqtt sends connect refusal")
|
||||
dut1.expect("MQTT_EVENT_ERROR: Test={}".format(test_nr), timeout=30)
|
||||
dut1.expect("MQTT ERROR: 0x5") # expecting 0x5 ... connection not authorized error
|
||||
test_nr = start_connection_case(case, 'ssl shall connect, but mqtt sends connect refusal')
|
||||
dut1.expect('MQTT_EVENT_ERROR: Test={}'.format(test_nr), timeout=30)
|
||||
dut1.expect('MQTT ERROR: 0x5') # expecting 0x5 ... connection not authorized error
|
||||
with TlsServer(server_port, client_cert=True) as s:
|
||||
test_nr = start_connection_case(case, "server with client verification - handshake error since client presents no client certificate")
|
||||
dut1.expect("MQTT_EVENT_ERROR: Test={}".format(test_nr), timeout=30)
|
||||
dut1.expect("ESP-TLS ERROR: 0x8010") # expect ... handshake error (PEER_DID_NOT_RETURN_A_CERTIFICATE)
|
||||
if "PEER_DID_NOT_RETURN_A_CERTIFICATE" not in s.get_last_ssl_error():
|
||||
raise("Unexpected ssl error from the server {}".format(s.get_last_ssl_error()))
|
||||
test_nr = start_connection_case(case, 'server with client verification - handshake error since client presents no client certificate')
|
||||
dut1.expect('MQTT_EVENT_ERROR: Test={}'.format(test_nr), timeout=30)
|
||||
dut1.expect('ESP-TLS ERROR: 0x8010') # expect ... handshake error (PEER_DID_NOT_RETURN_A_CERTIFICATE)
|
||||
if 'PEER_DID_NOT_RETURN_A_CERTIFICATE' not in s.get_last_ssl_error():
|
||||
raise('Unexpected ssl error from the server {}'.format(s.get_last_ssl_error()))
|
||||
|
||||
for case in ["CONFIG_EXAMPLE_CONNECT_CASE_MUTUAL_AUTH", "CONFIG_EXAMPLE_CONNECT_CASE_MUTUAL_AUTH_KEY_PWD"]:
|
||||
for case in ['CONFIG_EXAMPLE_CONNECT_CASE_MUTUAL_AUTH', 'CONFIG_EXAMPLE_CONNECT_CASE_MUTUAL_AUTH_KEY_PWD']:
|
||||
# These cases connect to server with both server and client verification (client key might be password protected)
|
||||
with TlsServer(server_port, client_cert=True):
|
||||
test_nr = start_connection_case(case, "server with client verification - expect to connect normally")
|
||||
dut1.expect("MQTT_EVENT_CONNECTED: Test={}".format(test_nr), timeout=30)
|
||||
test_nr = start_connection_case(case, 'server with client verification - expect to connect normally')
|
||||
dut1.expect('MQTT_EVENT_CONNECTED: Test={}'.format(test_nr), timeout=30)
|
||||
|
||||
case = "CONFIG_EXAMPLE_CONNECT_CASE_INVALID_SERVER_CERT"
|
||||
case = 'CONFIG_EXAMPLE_CONNECT_CASE_INVALID_SERVER_CERT'
|
||||
with TlsServer(server_port) as s:
|
||||
test_nr = start_connection_case(case, "invalid server certificate on default server - expect ssl handshake error")
|
||||
dut1.expect("MQTT_EVENT_ERROR: Test={}".format(test_nr), timeout=30)
|
||||
dut1.expect("ESP-TLS ERROR: 0x8010") # expect ... handshake error (TLSV1_ALERT_UNKNOWN_CA)
|
||||
if "alert unknown ca" not in s.get_last_ssl_error():
|
||||
raise Exception("Unexpected ssl error from the server {}".format(s.get_last_ssl_error()))
|
||||
test_nr = start_connection_case(case, 'invalid server certificate on default server - expect ssl handshake error')
|
||||
dut1.expect('MQTT_EVENT_ERROR: Test={}'.format(test_nr), timeout=30)
|
||||
dut1.expect('ESP-TLS ERROR: 0x8010') # expect ... handshake error (TLSV1_ALERT_UNKNOWN_CA)
|
||||
if 'alert unknown ca' not in s.get_last_ssl_error():
|
||||
raise Exception('Unexpected ssl error from the server {}'.format(s.get_last_ssl_error()))
|
||||
|
||||
case = "CONFIG_EXAMPLE_CONNECT_CASE_MUTUAL_AUTH_BAD_CRT"
|
||||
case = 'CONFIG_EXAMPLE_CONNECT_CASE_MUTUAL_AUTH_BAD_CRT'
|
||||
with TlsServer(server_port, client_cert=True) as s:
|
||||
test_nr = start_connection_case(case, "Invalid client certificate on server with client verification - expect ssl handshake error")
|
||||
dut1.expect("MQTT_EVENT_ERROR: Test={}".format(test_nr), timeout=30)
|
||||
dut1.expect("ESP-TLS ERROR: 0x8010") # expect ... handshake error (CERTIFICATE_VERIFY_FAILED)
|
||||
if "CERTIFICATE_VERIFY_FAILED" not in s.get_last_ssl_error():
|
||||
raise Exception("Unexpected ssl error from the server {}".format(s.get_last_ssl_error()))
|
||||
test_nr = start_connection_case(case, 'Invalid client certificate on server with client verification - expect ssl handshake error')
|
||||
dut1.expect('MQTT_EVENT_ERROR: Test={}'.format(test_nr), timeout=30)
|
||||
dut1.expect('ESP-TLS ERROR: 0x8010') # expect ... handshake error (CERTIFICATE_VERIFY_FAILED)
|
||||
if 'CERTIFICATE_VERIFY_FAILED' not in s.get_last_ssl_error():
|
||||
raise Exception('Unexpected ssl error from the server {}'.format(s.get_last_ssl_error()))
|
||||
|
||||
for case in ["CONFIG_EXAMPLE_CONNECT_CASE_NO_CERT", "CONFIG_EXAMPLE_CONNECT_CASE_NO_CERT_ALPN"]:
|
||||
for case in ['CONFIG_EXAMPLE_CONNECT_CASE_NO_CERT', 'CONFIG_EXAMPLE_CONNECT_CASE_NO_CERT_ALPN']:
|
||||
with TlsServer(server_port, use_alpn=True) as s:
|
||||
test_nr = start_connection_case(case, "server with alpn - expect connect, check resolved protocol")
|
||||
dut1.expect("MQTT_EVENT_CONNECTED: Test={}".format(test_nr), timeout=30)
|
||||
if case == "CONFIG_EXAMPLE_CONNECT_CASE_NO_CERT" and s.get_negotiated_protocol() is None:
|
||||
print(" - client with alpn off, no negotiated protocol: OK")
|
||||
elif case == "CONFIG_EXAMPLE_CONNECT_CASE_NO_CERT_ALPN" and s.get_negotiated_protocol() == "mymqtt":
|
||||
print(" - client with alpn on, negotiated protocol resolved: OK")
|
||||
test_nr = start_connection_case(case, 'server with alpn - expect connect, check resolved protocol')
|
||||
dut1.expect('MQTT_EVENT_CONNECTED: Test={}'.format(test_nr), timeout=30)
|
||||
if case == 'CONFIG_EXAMPLE_CONNECT_CASE_NO_CERT' and s.get_negotiated_protocol() is None:
|
||||
print(' - client with alpn off, no negotiated protocol: OK')
|
||||
elif case == 'CONFIG_EXAMPLE_CONNECT_CASE_NO_CERT_ALPN' and s.get_negotiated_protocol() == 'mymqtt':
|
||||
print(' - client with alpn on, negotiated protocol resolved: OK')
|
||||
else:
|
||||
raise Exception("Unexpected negotiated protocol {}".format(s.get_negotiated_protocol()))
|
||||
raise Exception('Unexpected negotiated protocol {}'.format(s.get_negotiated_protocol()))
|
||||
|
||||
#
|
||||
# start publish tests
|
||||
def start_publish_case(transport, qos, repeat, published, queue):
|
||||
print("Starting Publish test: transport:{}, qos:{}, nr_of_msgs:{}, msg_size:{}, enqueue:{}"
|
||||
print('Starting Publish test: transport:{}, qos:{}, nr_of_msgs:{}, msg_size:{}, enqueue:{}'
|
||||
.format(transport, qos, published, repeat * DEFAULT_MSG_SIZE, queue))
|
||||
with MqttPublisher(dut1, transport, qos, repeat, published, queue, publish_cfg):
|
||||
pass
|
||||
|
||||
for qos in [0, 1, 2]:
|
||||
for transport in ["tcp", "ssl", "ws", "wss"]:
|
||||
for transport in ['tcp', 'ssl', 'ws', 'wss']:
|
||||
for q in [0, 1]:
|
||||
if publish_cfg["broker_host_" + transport] is None:
|
||||
if publish_cfg['broker_host_' + transport] is None:
|
||||
print('Skipping transport: {}...'.format(transport))
|
||||
continue
|
||||
start_publish_case(transport, qos, 0, 5, q)
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
from __future__ import print_function
|
||||
from __future__ import unicode_literals
|
||||
import re
|
||||
import os
|
||||
import socket
|
||||
from threading import Thread, Event
|
||||
import ttfw_idf
|
||||
import ssl
|
||||
from __future__ import print_function, unicode_literals
|
||||
|
||||
SERVER_CERTS_DIR = "server_certs/"
|
||||
import os
|
||||
import re
|
||||
import socket
|
||||
import ssl
|
||||
from threading import Event, Thread
|
||||
|
||||
import ttfw_idf
|
||||
|
||||
SERVER_CERTS_DIR = 'server_certs/'
|
||||
|
||||
|
||||
def _path(f):
|
||||
@@ -45,7 +46,7 @@ class TlsServer:
|
||||
try:
|
||||
self.socket.bind(('', self.port))
|
||||
except socket.error as e:
|
||||
print("Bind failed:{}".format(e))
|
||||
print('Bind failed:{}'.format(e))
|
||||
raise
|
||||
|
||||
self.socket.listen(1)
|
||||
@@ -63,62 +64,62 @@ class TlsServer:
|
||||
|
||||
def run_server(self):
|
||||
context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
|
||||
context.load_verify_locations(cafile=_path(SERVER_CERTS_DIR + "ca.crt"))
|
||||
context.load_cert_chain(certfile=_path(SERVER_CERTS_DIR + "server.crt"), keyfile=_path(SERVER_CERTS_DIR + "server.key"))
|
||||
context.load_verify_locations(cafile=_path(SERVER_CERTS_DIR + 'ca.crt'))
|
||||
context.load_cert_chain(certfile=_path(SERVER_CERTS_DIR + 'server.crt'), keyfile=_path(SERVER_CERTS_DIR + 'server.key'))
|
||||
context.verify_flags = self.negotiated_protocol
|
||||
self.socket = context.wrap_socket(self.socket, server_side=True)
|
||||
try:
|
||||
print("Listening socket")
|
||||
print('Listening socket')
|
||||
self.conn, address = self.socket.accept() # accept new connection
|
||||
self.socket.settimeout(20.0)
|
||||
print(" - connection from: {}".format(address))
|
||||
print(' - connection from: {}'.format(address))
|
||||
except ssl.SSLError as e:
|
||||
self.conn = None
|
||||
self.ssl_error = str(e)
|
||||
print(" - SSLError: {}".format(str(e)))
|
||||
print(' - SSLError: {}'.format(str(e)))
|
||||
|
||||
|
||||
@ttfw_idf.idf_custom_test(env_tag="Example_WIFI", group="test-apps")
|
||||
@ttfw_idf.idf_custom_test(env_tag='Example_WIFI', group='test-apps')
|
||||
def test_app_esp_openssl(env, extra_data):
|
||||
dut1 = env.get_dut("openssl_connect_test", "tools/test_apps/protocols/openssl", dut_class=ttfw_idf.ESP32DUT)
|
||||
dut1 = env.get_dut('openssl_connect_test', 'tools/test_apps/protocols/openssl', dut_class=ttfw_idf.ESP32DUT)
|
||||
# check and log bin size
|
||||
binary_file = os.path.join(dut1.app.binary_path, "openssl_connect_test.bin")
|
||||
binary_file = os.path.join(dut1.app.binary_path, 'openssl_connect_test.bin')
|
||||
bin_size = os.path.getsize(binary_file)
|
||||
ttfw_idf.log_performance("openssl_connect_test_bin_size", "{}KB".format(bin_size // 1024))
|
||||
ttfw_idf.log_performance('openssl_connect_test_bin_size', '{}KB'.format(bin_size // 1024))
|
||||
dut1.start_app()
|
||||
esp_ip = dut1.expect(re.compile(r" IPv4 address: ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)"), timeout=30)
|
||||
print("Got IP={}".format(esp_ip[0]))
|
||||
esp_ip = dut1.expect(re.compile(r' IPv4 address: ([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)'), timeout=30)
|
||||
print('Got IP={}'.format(esp_ip[0]))
|
||||
ip = get_my_ip()
|
||||
server_port = 2222
|
||||
|
||||
def start_case(case, desc, negotiated_protocol, result):
|
||||
with TlsServer(server_port, negotiated_protocol=negotiated_protocol):
|
||||
print("Starting {}: {}".format(case, desc))
|
||||
dut1.write("conn {} {} {}".format(ip, server_port, case))
|
||||
print('Starting {}: {}'.format(case, desc))
|
||||
dut1.write('conn {} {} {}'.format(ip, server_port, case))
|
||||
dut1.expect(re.compile(result), timeout=10)
|
||||
return case
|
||||
|
||||
# start test cases
|
||||
start_case(
|
||||
case="CONFIG_TLSV1_1_CONNECT_WRONG_CERT_VERIFY_NONE",
|
||||
desc="Connect with verify_none mode using wrong certs",
|
||||
case='CONFIG_TLSV1_1_CONNECT_WRONG_CERT_VERIFY_NONE',
|
||||
desc='Connect with verify_none mode using wrong certs',
|
||||
negotiated_protocol=ssl.PROTOCOL_TLSv1_1,
|
||||
result="SSL Connection Succeed")
|
||||
result='SSL Connection Succeed')
|
||||
start_case(
|
||||
case="CONFIG_TLSV1_1_CONNECT_WRONG_CERT_VERIFY_PEER",
|
||||
desc="Connect with verify_peer mode using wrong certs",
|
||||
case='CONFIG_TLSV1_1_CONNECT_WRONG_CERT_VERIFY_PEER',
|
||||
desc='Connect with verify_peer mode using wrong certs',
|
||||
negotiated_protocol=ssl.PROTOCOL_TLSv1_1,
|
||||
result="SSL Connection Failed")
|
||||
result='SSL Connection Failed')
|
||||
start_case(
|
||||
case="CONFIG_TLSV1_2_CONNECT_WRONG_CERT_VERIFY_NONE",
|
||||
desc="Connect with verify_none mode using wrong certs",
|
||||
case='CONFIG_TLSV1_2_CONNECT_WRONG_CERT_VERIFY_NONE',
|
||||
desc='Connect with verify_none mode using wrong certs',
|
||||
negotiated_protocol=ssl.PROTOCOL_TLSv1_2,
|
||||
result="SSL Connection Succeed")
|
||||
result='SSL Connection Succeed')
|
||||
start_case(
|
||||
case="CONFIG_TLSV1_1_CONNECT_WRONG_CERT_VERIFY_PEER",
|
||||
desc="Connect with verify_peer mode using wrong certs",
|
||||
case='CONFIG_TLSV1_1_CONNECT_WRONG_CERT_VERIFY_PEER',
|
||||
desc='Connect with verify_peer mode using wrong certs',
|
||||
negotiated_protocol=ssl.PROTOCOL_TLSv1_2,
|
||||
result="SSL Connection Failed")
|
||||
result='SSL Connection Failed')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
from __future__ import print_function
|
||||
from __future__ import unicode_literals
|
||||
from __future__ import print_function, unicode_literals
|
||||
|
||||
import re
|
||||
import socket
|
||||
import subprocess
|
||||
import ttfw_idf
|
||||
import time
|
||||
from threading import Event, Thread
|
||||
|
||||
import netifaces
|
||||
from threading import Thread, Event
|
||||
import ttfw_idf
|
||||
|
||||
|
||||
def run_server(server_stop, port, server_ip, client_ip):
|
||||
print("Starting PPP server on port: {}".format(port))
|
||||
print('Starting PPP server on port: {}'.format(port))
|
||||
try:
|
||||
arg_list = ['pppd', port, '115200', '{}:{}'.format(server_ip, client_ip), 'modem', 'local', 'noauth', 'debug', 'nocrtscts', 'nodetach', '+ipv6']
|
||||
p = subprocess.Popen(arg_list, stdout=subprocess.PIPE, bufsize=1)
|
||||
@@ -19,17 +20,17 @@ def run_server(server_stop, port, server_ip, client_ip):
|
||||
raise ValueError('ENV_TEST_FAILURE: PPP terminated unexpectedly with {}'.format(p.poll()))
|
||||
line = p.stdout.readline()
|
||||
if line:
|
||||
print("[PPPD:]{}".format(line.rstrip()))
|
||||
print('[PPPD:]{}'.format(line.rstrip()))
|
||||
time.sleep(0.1)
|
||||
except Exception as e:
|
||||
print(e)
|
||||
raise ValueError('ENV_TEST_FAILURE: Error running PPP server')
|
||||
finally:
|
||||
p.terminate()
|
||||
print("PPP server stopped")
|
||||
print('PPP server stopped')
|
||||
|
||||
|
||||
@ttfw_idf.idf_custom_test(env_tag="Example_PPP", group="test-apps")
|
||||
@ttfw_idf.idf_custom_test(env_tag='Example_PPP', group='test-apps')
|
||||
def test_examples_protocol_pppos_connect(env, extra_data):
|
||||
"""
|
||||
steps:
|
||||
@@ -38,17 +39,17 @@ def test_examples_protocol_pppos_connect(env, extra_data):
|
||||
3. check TCP client-server connection between client-server
|
||||
"""
|
||||
|
||||
dut1 = env.get_dut("pppos_connect_test", "tools/test_apps/protocols/pppos", dut_class=ttfw_idf.ESP32DUT)
|
||||
dut1 = env.get_dut('pppos_connect_test', 'tools/test_apps/protocols/pppos', dut_class=ttfw_idf.ESP32DUT)
|
||||
# Look for test case symbolic names
|
||||
try:
|
||||
server_ip = dut1.app.get_sdkconfig()["CONFIG_TEST_APP_PPP_SERVER_IP"].replace('"','')
|
||||
client_ip = dut1.app.get_sdkconfig()["CONFIG_TEST_APP_PPP_CLIENT_IP"].replace('"','')
|
||||
port_nr = dut1.app.get_sdkconfig()["CONFIG_TEST_APP_TCP_PORT"]
|
||||
server_ip = dut1.app.get_sdkconfig()['CONFIG_TEST_APP_PPP_SERVER_IP'].replace('"','')
|
||||
client_ip = dut1.app.get_sdkconfig()['CONFIG_TEST_APP_PPP_CLIENT_IP'].replace('"','')
|
||||
port_nr = dut1.app.get_sdkconfig()['CONFIG_TEST_APP_TCP_PORT']
|
||||
except Exception:
|
||||
print('ENV_TEST_FAILURE: Some mandatory configuration not found in sdkconfig')
|
||||
raise
|
||||
|
||||
print("Starting the test on {}".format(dut1))
|
||||
print('Starting the test on {}'.format(dut1))
|
||||
dut1.start_app()
|
||||
|
||||
# the PPP test env uses two ttyUSB's: one for ESP32 board, another one for ppp server
|
||||
@@ -60,29 +61,29 @@ def test_examples_protocol_pppos_connect(env, extra_data):
|
||||
t.start()
|
||||
try:
|
||||
ppp_server_timeout = time.time() + 30
|
||||
while "ppp0" not in netifaces.interfaces():
|
||||
while 'ppp0' not in netifaces.interfaces():
|
||||
print("PPP server haven't yet setup its netif, list of active netifs:{}".format(netifaces.interfaces()))
|
||||
time.sleep(0.5)
|
||||
if time.time() > ppp_server_timeout:
|
||||
raise ValueError("ENV_TEST_FAILURE: PPP server failed to setup ppp0 interface within timeout")
|
||||
ip6_addr = dut1.expect(re.compile(r"Got IPv6 address (\w{4}\:\w{4}\:\w{4}\:\w{4}\:\w{4}\:\w{4}\:\w{4}\:\w{4})"), timeout=30)[0]
|
||||
print("IPv6 address of ESP: {}".format(ip6_addr))
|
||||
raise ValueError('ENV_TEST_FAILURE: PPP server failed to setup ppp0 interface within timeout')
|
||||
ip6_addr = dut1.expect(re.compile(r'Got IPv6 address (\w{4}\:\w{4}\:\w{4}\:\w{4}\:\w{4}\:\w{4}\:\w{4}\:\w{4})'), timeout=30)[0]
|
||||
print('IPv6 address of ESP: {}'.format(ip6_addr))
|
||||
|
||||
dut1.expect(re.compile(r"Socket listening"))
|
||||
print("Starting the IPv6 test...")
|
||||
dut1.expect(re.compile(r'Socket listening'))
|
||||
print('Starting the IPv6 test...')
|
||||
# Connect to TCP server on ESP using IPv6 address
|
||||
for res in socket.getaddrinfo(ip6_addr + "%ppp0", int(port_nr), socket.AF_INET6,
|
||||
for res in socket.getaddrinfo(ip6_addr + '%ppp0', int(port_nr), socket.AF_INET6,
|
||||
socket.SOCK_STREAM, socket.SOL_TCP):
|
||||
af, socktype, proto, canonname, addr = res
|
||||
sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
|
||||
sock.connect(addr)
|
||||
sock.sendall(b"Espressif")
|
||||
sock.sendall(b'Espressif')
|
||||
sock.close()
|
||||
|
||||
dut1.expect(re.compile(r"IPv6 test passed"))
|
||||
print("IPv6 test passed!")
|
||||
dut1.expect(re.compile(r'IPv6 test passed'))
|
||||
print('IPv6 test passed!')
|
||||
|
||||
print("Starting the IPv4 test...")
|
||||
print('Starting the IPv4 test...')
|
||||
# Start the TCP server and wait for the ESP to connect with IPv4 address
|
||||
try:
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
@@ -103,8 +104,8 @@ def test_examples_protocol_pppos_connect(env, extra_data):
|
||||
conn.send(data.encode())
|
||||
break
|
||||
conn.close()
|
||||
dut1.expect(re.compile(r"IPv4 test passed"))
|
||||
print("IPv4 test passed!")
|
||||
dut1.expect(re.compile(r'IPv4 test passed'))
|
||||
print('IPv4 test passed!')
|
||||
finally:
|
||||
server_stop.set()
|
||||
t.join()
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
from __future__ import unicode_literals
|
||||
from tiny_test_fw import Utility
|
||||
import debug_backend
|
||||
|
||||
import os
|
||||
import pexpect
|
||||
import serial
|
||||
import threading
|
||||
import time
|
||||
|
||||
import debug_backend
|
||||
import pexpect
|
||||
import serial
|
||||
import ttfw_idf
|
||||
from tiny_test_fw import Utility
|
||||
|
||||
|
||||
class SerialThread(object):
|
||||
@@ -33,12 +35,12 @@ class SerialThread(object):
|
||||
Utility.console_log('The pyserial thread is still alive', 'O')
|
||||
|
||||
|
||||
@ttfw_idf.idf_custom_test(env_tag="test_jtag_arm", group="test-apps")
|
||||
@ttfw_idf.idf_custom_test(env_tag='test_jtag_arm', group='test-apps')
|
||||
def test_app_loadable_elf(env, extra_data):
|
||||
|
||||
rel_project_path = os.path.join('tools', 'test_apps', 'system', 'gdb_loadable_elf')
|
||||
app_files = ['gdb_loadable_elf.elf']
|
||||
app = ttfw_idf.LoadableElfTestApp(rel_project_path, app_files, target="esp32")
|
||||
app = ttfw_idf.LoadableElfTestApp(rel_project_path, app_files, target='esp32')
|
||||
idf_path = app.get_sdk_path()
|
||||
proj_path = os.path.join(idf_path, rel_project_path)
|
||||
elf_path = os.path.join(app.binary_path, 'gdb_loadable_elf.elf')
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
import ttfw_idf
|
||||
from tiny_test_fw import Utility
|
||||
|
||||
|
||||
mem_test = [
|
||||
['IRAM0_SRAM', 'WRX'],
|
||||
['IRAM0_RTCFAST', 'WRX'],
|
||||
@@ -15,24 +14,24 @@ mem_test = [
|
||||
]
|
||||
|
||||
|
||||
@ttfw_idf.idf_custom_test(env_tag="Example_GENERIC", target="esp32s2", group="test-apps")
|
||||
@ttfw_idf.idf_custom_test(env_tag='Example_GENERIC', target='esp32s2', group='test-apps')
|
||||
def test_memprot(env, extra_data):
|
||||
|
||||
dut = env.get_dut("memprot", "tools/test_apps/system/memprot")
|
||||
dut = env.get_dut('memprot', 'tools/test_apps/system/memprot')
|
||||
dut.start_app()
|
||||
|
||||
for i in mem_test:
|
||||
if 'R' in i[1]:
|
||||
dut.expect(i[0] + " read low: OK")
|
||||
dut.expect(i[0] + " read high: OK")
|
||||
dut.expect(i[0] + ' read low: OK')
|
||||
dut.expect(i[0] + ' read high: OK')
|
||||
if 'W' in i[1]:
|
||||
dut.expect(i[0] + " write low: OK")
|
||||
dut.expect(i[0] + " write high: OK")
|
||||
dut.expect(i[0] + ' write low: OK')
|
||||
dut.expect(i[0] + ' write high: OK')
|
||||
if 'X' in i[1]:
|
||||
dut.expect(i[0] + " exec low: OK")
|
||||
dut.expect(i[0] + " exec high: OK")
|
||||
dut.expect(i[0] + ' exec low: OK')
|
||||
dut.expect(i[0] + ' exec high: OK')
|
||||
|
||||
Utility.console_log("Memprot test done")
|
||||
Utility.console_log('Memprot test done')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
from __future__ import unicode_literals
|
||||
from SimpleWebSocketServer import SimpleWebSocketServer, WebSocket
|
||||
from tiny_test_fw import Utility
|
||||
|
||||
import glob
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import threading
|
||||
|
||||
import ttfw_idf
|
||||
from SimpleWebSocketServer import SimpleWebSocketServer, WebSocket
|
||||
from tiny_test_fw import Utility
|
||||
|
||||
|
||||
class IDEWSProtocol(WebSocket):
|
||||
|
||||
@@ -1,295 +1,295 @@
|
||||
#!/usr/bin/env python
|
||||
import sys
|
||||
|
||||
import panic_tests as test
|
||||
from test_panic_util.test_panic_util import panic_test, run_all
|
||||
|
||||
|
||||
# test_task_wdt
|
||||
|
||||
@panic_test(target=['ESP32', 'ESP32S2'])
|
||||
def test_panic_task_wdt(env, _extra_data):
|
||||
test.task_wdt_inner(env, "panic")
|
||||
test.task_wdt_inner(env, 'panic')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_coredump_task_wdt_uart_elf_crc(env, _extra_data):
|
||||
test.task_wdt_inner(env, "coredump_uart_elf_crc")
|
||||
test.task_wdt_inner(env, 'coredump_uart_elf_crc')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_coredump_task_wdt_uart_bin_crc(env, _extra_data):
|
||||
test.task_wdt_inner(env, "coredump_uart_bin_crc")
|
||||
test.task_wdt_inner(env, 'coredump_uart_bin_crc')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_coredump_task_wdt_flash_elf_sha(env, _extra_data):
|
||||
test.task_wdt_inner(env, "coredump_flash_elf_sha")
|
||||
test.task_wdt_inner(env, 'coredump_flash_elf_sha')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_coredump_task_wdt_flash_bin_crc(env, _extra_data):
|
||||
test.task_wdt_inner(env, "coredump_flash_bin_crc")
|
||||
test.task_wdt_inner(env, 'coredump_flash_bin_crc')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_gdbstub_task_wdt(env, _extra_data):
|
||||
test.task_wdt_inner(env, "gdbstub")
|
||||
test.task_wdt_inner(env, 'gdbstub')
|
||||
|
||||
|
||||
# test_int_wdt
|
||||
|
||||
@panic_test()
|
||||
def test_panic_int_wdt(env, _extra_data):
|
||||
test.int_wdt_inner(env, "panic")
|
||||
test.int_wdt_inner(env, 'panic')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_coredump_int_wdt_uart_elf_crc(env, _extra_data):
|
||||
test.int_wdt_inner(env, "coredump_uart_elf_crc")
|
||||
test.int_wdt_inner(env, 'coredump_uart_elf_crc')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_coredump_int_wdt_uart_bin_crc(env, _extra_data):
|
||||
test.int_wdt_inner(env, "coredump_uart_bin_crc")
|
||||
test.int_wdt_inner(env, 'coredump_uart_bin_crc')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_coredump_int_wdt_flash_elf_sha(env, _extra_data):
|
||||
test.int_wdt_inner(env, "coredump_flash_elf_sha")
|
||||
test.int_wdt_inner(env, 'coredump_flash_elf_sha')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_coredump_int_wdt_flash_bin_crc(env, _extra_data):
|
||||
test.int_wdt_inner(env, "coredump_flash_bin_crc")
|
||||
test.int_wdt_inner(env, 'coredump_flash_bin_crc')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_gdbstub_int_wdt(env, _extra_data):
|
||||
test.int_wdt_inner(env, "gdbstub")
|
||||
test.int_wdt_inner(env, 'gdbstub')
|
||||
|
||||
|
||||
# test_int_wdt_cache_disabled
|
||||
|
||||
@panic_test()
|
||||
def test_panic_int_wdt_cache_disabled(env, _extra_data):
|
||||
test.int_wdt_cache_disabled_inner(env, "panic")
|
||||
test.int_wdt_cache_disabled_inner(env, 'panic')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_coredump_int_wdt_cache_disabled_uart_elf_crc(env, _extra_data):
|
||||
test.int_wdt_cache_disabled_inner(env, "coredump_uart_elf_crc")
|
||||
test.int_wdt_cache_disabled_inner(env, 'coredump_uart_elf_crc')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_coredump_int_wdt_cache_disabled_uart_bin_crc(env, _extra_data):
|
||||
test.int_wdt_cache_disabled_inner(env, "coredump_uart_bin_crc")
|
||||
test.int_wdt_cache_disabled_inner(env, 'coredump_uart_bin_crc')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_coredump_int_wdt_cache_disabled_flash_elf_sha(env, _extra_data):
|
||||
test.int_wdt_cache_disabled_inner(env, "coredump_flash_elf_sha")
|
||||
test.int_wdt_cache_disabled_inner(env, 'coredump_flash_elf_sha')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_coredump_int_wdt_cache_disabled_flash_bin_crc(env, _extra_data):
|
||||
test.int_wdt_cache_disabled_inner(env, "coredump_flash_bin_crc")
|
||||
test.int_wdt_cache_disabled_inner(env, 'coredump_flash_bin_crc')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_gdbstub_int_wdt_cache_disabled(env, _extra_data):
|
||||
test.int_wdt_cache_disabled_inner(env, "gdbstub")
|
||||
test.int_wdt_cache_disabled_inner(env, 'gdbstub')
|
||||
|
||||
|
||||
# test_cache_error
|
||||
|
||||
@panic_test()
|
||||
def test_panic_cache_error(env, _extra_data):
|
||||
test.cache_error_inner(env, "panic")
|
||||
test.cache_error_inner(env, 'panic')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_coredump_cache_error_uart_elf_crc(env, _extra_data):
|
||||
test.cache_error_inner(env, "coredump_uart_elf_crc")
|
||||
test.cache_error_inner(env, 'coredump_uart_elf_crc')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_coredump_cache_error_uart_bin_crc(env, _extra_data):
|
||||
test.cache_error_inner(env, "coredump_uart_bin_crc")
|
||||
test.cache_error_inner(env, 'coredump_uart_bin_crc')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_coredump_cache_error_flash_elf_sha(env, _extra_data):
|
||||
test.cache_error_inner(env, "coredump_flash_elf_sha")
|
||||
test.cache_error_inner(env, 'coredump_flash_elf_sha')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_coredump_cache_error_flash_bin_crc(env, _extra_data):
|
||||
test.cache_error_inner(env, "coredump_flash_bin_crc")
|
||||
test.cache_error_inner(env, 'coredump_flash_bin_crc')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_gdbstub_cache_error(env, _extra_data):
|
||||
test.cache_error_inner(env, "gdbstub")
|
||||
test.cache_error_inner(env, 'gdbstub')
|
||||
|
||||
|
||||
# test_stack_overflow
|
||||
|
||||
@panic_test(target=['ESP32', 'ESP32S2'])
|
||||
def test_panic_stack_overflow(env, _extra_data):
|
||||
test.stack_overflow_inner(env, "panic")
|
||||
test.stack_overflow_inner(env, 'panic')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_coredump_stack_overflow_uart_elf_crc(env, _extra_data):
|
||||
test.stack_overflow_inner(env, "coredump_uart_elf_crc")
|
||||
test.stack_overflow_inner(env, 'coredump_uart_elf_crc')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_coredump_stack_overflow_uart_bin_crc(env, _extra_data):
|
||||
test.stack_overflow_inner(env, "coredump_uart_bin_crc")
|
||||
test.stack_overflow_inner(env, 'coredump_uart_bin_crc')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_coredump_stack_overflow_flash_elf_sha(env, _extra_data):
|
||||
test.stack_overflow_inner(env, "coredump_flash_elf_sha")
|
||||
test.stack_overflow_inner(env, 'coredump_flash_elf_sha')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_coredump_stack_overflow_flash_bin_crc(env, _extra_data):
|
||||
test.stack_overflow_inner(env, "coredump_flash_bin_crc")
|
||||
test.stack_overflow_inner(env, 'coredump_flash_bin_crc')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_gdbstub_stack_overflow(env, _extra_data):
|
||||
test.stack_overflow_inner(env, "gdbstub")
|
||||
test.stack_overflow_inner(env, 'gdbstub')
|
||||
|
||||
|
||||
# test_instr_fetch_prohibited
|
||||
|
||||
@panic_test(target=['ESP32', 'ESP32S2'])
|
||||
def test_panic_instr_fetch_prohibited(env, _extra_data):
|
||||
test.instr_fetch_prohibited_inner(env, "panic")
|
||||
test.instr_fetch_prohibited_inner(env, 'panic')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_coredump_instr_fetch_prohibited_uart_elf_crc(env, _extra_data):
|
||||
test.instr_fetch_prohibited_inner(env, "coredump_uart_elf_crc")
|
||||
test.instr_fetch_prohibited_inner(env, 'coredump_uart_elf_crc')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_coredump_instr_fetch_prohibited_uart_bin_crc(env, _extra_data):
|
||||
test.instr_fetch_prohibited_inner(env, "coredump_uart_bin_crc")
|
||||
test.instr_fetch_prohibited_inner(env, 'coredump_uart_bin_crc')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_coredump_instr_fetch_prohibited_flash_elf_sha(env, _extra_data):
|
||||
test.instr_fetch_prohibited_inner(env, "coredump_flash_elf_sha")
|
||||
test.instr_fetch_prohibited_inner(env, 'coredump_flash_elf_sha')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_coredump_instr_fetch_prohibited_flash_bin_crc(env, _extra_data):
|
||||
test.instr_fetch_prohibited_inner(env, "coredump_flash_bin_crc")
|
||||
test.instr_fetch_prohibited_inner(env, 'coredump_flash_bin_crc')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_gdbstub_instr_fetch_prohibited(env, _extra_data):
|
||||
test.instr_fetch_prohibited_inner(env, "gdbstub")
|
||||
test.instr_fetch_prohibited_inner(env, 'gdbstub')
|
||||
|
||||
|
||||
# test_illegal_instruction
|
||||
|
||||
@panic_test(target=['ESP32', 'ESP32S2'])
|
||||
def test_panic_illegal_instruction(env, _extra_data):
|
||||
test.illegal_instruction_inner(env, "panic")
|
||||
test.illegal_instruction_inner(env, 'panic')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_coredump_illegal_instruction_uart_elf_crc(env, _extra_data):
|
||||
test.illegal_instruction_inner(env, "coredump_uart_elf_crc")
|
||||
test.illegal_instruction_inner(env, 'coredump_uart_elf_crc')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_coredump_illegal_instruction_uart_bin_crc(env, _extra_data):
|
||||
test.illegal_instruction_inner(env, "coredump_uart_bin_crc")
|
||||
test.illegal_instruction_inner(env, 'coredump_uart_bin_crc')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_coredump_illegal_instruction_flash_elf_sha(env, _extra_data):
|
||||
test.illegal_instruction_inner(env, "coredump_flash_elf_sha")
|
||||
test.illegal_instruction_inner(env, 'coredump_flash_elf_sha')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_coredump_illegal_instruction_flash_bin_crc(env, _extra_data):
|
||||
test.illegal_instruction_inner(env, "coredump_flash_bin_crc")
|
||||
test.illegal_instruction_inner(env, 'coredump_flash_bin_crc')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_gdbstub_illegal_instruction(env, _extra_data):
|
||||
test.illegal_instruction_inner(env, "gdbstub")
|
||||
test.illegal_instruction_inner(env, 'gdbstub')
|
||||
|
||||
|
||||
# test_storeprohibited
|
||||
|
||||
@panic_test(target=['ESP32', 'ESP32S2'])
|
||||
def test_panic_storeprohibited(env, _extra_data):
|
||||
test.storeprohibited_inner(env, "panic")
|
||||
test.storeprohibited_inner(env, 'panic')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_coredump_storeprohibited_uart_elf_crc(env, _extra_data):
|
||||
test.storeprohibited_inner(env, "coredump_uart_elf_crc")
|
||||
test.storeprohibited_inner(env, 'coredump_uart_elf_crc')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_coredump_storeprohibited_uart_bin_crc(env, _extra_data):
|
||||
test.storeprohibited_inner(env, "coredump_uart_bin_crc")
|
||||
test.storeprohibited_inner(env, 'coredump_uart_bin_crc')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_coredump_storeprohibited_flash_elf_sha(env, _extra_data):
|
||||
test.storeprohibited_inner(env, "coredump_flash_elf_sha")
|
||||
test.storeprohibited_inner(env, 'coredump_flash_elf_sha')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_coredump_storeprohibited_flash_bin_crc(env, _extra_data):
|
||||
test.storeprohibited_inner(env, "coredump_flash_bin_crc")
|
||||
test.storeprohibited_inner(env, 'coredump_flash_bin_crc')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_gdbstub_storeprohibited(env, _extra_data):
|
||||
test.storeprohibited_inner(env, "gdbstub")
|
||||
test.storeprohibited_inner(env, 'gdbstub')
|
||||
|
||||
|
||||
# test_abort
|
||||
|
||||
@panic_test(target=['ESP32', 'ESP32S2'])
|
||||
def test_panic_abort(env, _extra_data):
|
||||
test.abort_inner(env, "panic")
|
||||
test.abort_inner(env, 'panic')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_coredump_abort_uart_elf_crc(env, _extra_data):
|
||||
test.abort_inner(env, "coredump_uart_elf_crc")
|
||||
test.abort_inner(env, 'coredump_uart_elf_crc')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_coredump_abort_uart_bin_crc(env, _extra_data):
|
||||
test.abort_inner(env, "coredump_uart_bin_crc")
|
||||
test.abort_inner(env, 'coredump_uart_bin_crc')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_coredump_abort_flash_elf_sha(env, _extra_data):
|
||||
test.abort_inner(env, "coredump_flash_elf_sha")
|
||||
test.abort_inner(env, 'coredump_flash_elf_sha')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_coredump_abort_flash_bin_crc(env, _extra_data):
|
||||
test.abort_inner(env, "coredump_flash_bin_crc")
|
||||
test.abort_inner(env, 'coredump_flash_bin_crc')
|
||||
|
||||
|
||||
@panic_test()
|
||||
def test_gdbstub_abort(env, _extra_data):
|
||||
test.abort_inner(env, "gdbstub")
|
||||
test.abort_inner(env, 'gdbstub')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
#!/usr/bin/env python
|
||||
from pprint import pformat
|
||||
import re
|
||||
from pprint import pformat
|
||||
|
||||
from test_panic_util.test_panic_util import get_dut
|
||||
|
||||
|
||||
def get_default_backtrace(test_name):
|
||||
return [
|
||||
test_name,
|
||||
"app_main",
|
||||
"main_task",
|
||||
"vPortTaskWrapper"
|
||||
'app_main',
|
||||
'main_task',
|
||||
'vPortTaskWrapper'
|
||||
]
|
||||
|
||||
|
||||
@@ -17,133 +18,133 @@ def test_common(dut, test_name, expected_backtrace=None):
|
||||
if expected_backtrace is None:
|
||||
expected_backtrace = get_default_backtrace(dut.test_name)
|
||||
|
||||
if "gdbstub" in test_name:
|
||||
if 'gdbstub' in test_name:
|
||||
dut.start_gdb()
|
||||
frames = dut.gdb_backtrace()
|
||||
if not dut.match_backtrace(frames, expected_backtrace):
|
||||
raise AssertionError("Unexpected backtrace in test {}:\n{}".format(test_name, pformat(frames)))
|
||||
raise AssertionError('Unexpected backtrace in test {}:\n{}'.format(test_name, pformat(frames)))
|
||||
return
|
||||
|
||||
if "uart" in test_name:
|
||||
if 'uart' in test_name:
|
||||
dut.expect(dut.COREDUMP_UART_END)
|
||||
|
||||
dut.expect("Rebooting...")
|
||||
dut.expect('Rebooting...')
|
||||
|
||||
if "uart" in test_name:
|
||||
if 'uart' in test_name:
|
||||
dut.process_coredump_uart()
|
||||
# TODO: check backtrace
|
||||
elif "flash" in test_name:
|
||||
elif 'flash' in test_name:
|
||||
dut.process_coredump_flash()
|
||||
# TODO: check backtrace
|
||||
elif "panic" in test_name:
|
||||
elif 'panic' in test_name:
|
||||
# TODO: check backtrace
|
||||
pass
|
||||
|
||||
|
||||
def task_wdt_inner(env, test_name):
|
||||
with get_dut(env, test_name, "test_task_wdt", qemu_wdt_enable=True) as dut:
|
||||
dut.expect("Task watchdog got triggered. The following tasks did not reset the watchdog in time:")
|
||||
dut.expect("CPU 0: main")
|
||||
dut.expect(re.compile(r"abort\(\) was called at PC [0-9xa-f]+ on core 0"))
|
||||
dut.expect_none("register dump:")
|
||||
with get_dut(env, test_name, 'test_task_wdt', qemu_wdt_enable=True) as dut:
|
||||
dut.expect('Task watchdog got triggered. The following tasks did not reset the watchdog in time:')
|
||||
dut.expect('CPU 0: main')
|
||||
dut.expect(re.compile(r'abort\(\) was called at PC [0-9xa-f]+ on core 0'))
|
||||
dut.expect_none('register dump:')
|
||||
dut.expect_backtrace()
|
||||
dut.expect_elf_sha256()
|
||||
dut.expect_none("Guru Meditation")
|
||||
dut.expect_none('Guru Meditation')
|
||||
test_common(dut, test_name, expected_backtrace=[
|
||||
# Backtrace interrupted when abort is called, IDF-842.
|
||||
# Task WDT calls abort internally.
|
||||
"panic_abort", "esp_system_abort"
|
||||
'panic_abort', 'esp_system_abort'
|
||||
])
|
||||
|
||||
|
||||
def int_wdt_inner(env, test_name):
|
||||
with get_dut(env, test_name, "test_int_wdt", qemu_wdt_enable=True) as dut:
|
||||
dut.expect_gme("Interrupt wdt timeout on CPU0")
|
||||
with get_dut(env, test_name, 'test_int_wdt', qemu_wdt_enable=True) as dut:
|
||||
dut.expect_gme('Interrupt wdt timeout on CPU0')
|
||||
dut.expect_reg_dump(0)
|
||||
dut.expect_backtrace()
|
||||
dut.expect_none("Guru Meditation")
|
||||
dut.expect_none('Guru Meditation')
|
||||
dut.expect_reg_dump(1)
|
||||
dut.expect_backtrace()
|
||||
dut.expect_elf_sha256()
|
||||
dut.expect_none("Guru Meditation")
|
||||
dut.expect_none('Guru Meditation')
|
||||
test_common(dut, test_name)
|
||||
|
||||
|
||||
def int_wdt_cache_disabled_inner(env, test_name):
|
||||
with get_dut(env, test_name, "test_int_wdt_cache_disabled", qemu_wdt_enable=True) as dut:
|
||||
dut.expect("Re-enable cpu cache.")
|
||||
dut.expect_gme("Interrupt wdt timeout on CPU0")
|
||||
with get_dut(env, test_name, 'test_int_wdt_cache_disabled', qemu_wdt_enable=True) as dut:
|
||||
dut.expect('Re-enable cpu cache.')
|
||||
dut.expect_gme('Interrupt wdt timeout on CPU0')
|
||||
dut.expect_reg_dump(0)
|
||||
dut.expect("Backtrace:")
|
||||
dut.expect_none("Guru Meditation")
|
||||
dut.expect('Backtrace:')
|
||||
dut.expect_none('Guru Meditation')
|
||||
dut.expect_reg_dump(1)
|
||||
dut.expect_backtrace()
|
||||
dut.expect_elf_sha256()
|
||||
dut.expect_none("Guru Meditation")
|
||||
dut.expect_none('Guru Meditation')
|
||||
test_common(dut, test_name)
|
||||
|
||||
|
||||
def cache_error_inner(env, test_name):
|
||||
with get_dut(env, test_name, "test_cache_error") as dut:
|
||||
dut.expect("Re-enable cpu cache.")
|
||||
dut.expect_gme("Cache disabled but cached memory region accessed")
|
||||
with get_dut(env, test_name, 'test_cache_error') as dut:
|
||||
dut.expect('Re-enable cpu cache.')
|
||||
dut.expect_gme('Cache disabled but cached memory region accessed')
|
||||
dut.expect_reg_dump(0)
|
||||
dut.expect_backtrace()
|
||||
dut.expect_elf_sha256()
|
||||
dut.expect_none("Guru Meditation")
|
||||
dut.expect_none('Guru Meditation')
|
||||
test_common(dut, test_name,
|
||||
expected_backtrace=["die"] + get_default_backtrace(dut.test_name))
|
||||
expected_backtrace=['die'] + get_default_backtrace(dut.test_name))
|
||||
|
||||
|
||||
def abort_inner(env, test_name):
|
||||
with get_dut(env, test_name, "test_abort") as dut:
|
||||
dut.expect(re.compile(r"abort\(\) was called at PC [0-9xa-f]+ on core 0"))
|
||||
with get_dut(env, test_name, 'test_abort') as dut:
|
||||
dut.expect(re.compile(r'abort\(\) was called at PC [0-9xa-f]+ on core 0'))
|
||||
dut.expect_backtrace()
|
||||
dut.expect_elf_sha256()
|
||||
dut.expect_none("Guru Meditation", "Re-entered core dump")
|
||||
dut.expect_none('Guru Meditation', 'Re-entered core dump')
|
||||
test_common(dut, test_name, expected_backtrace=[
|
||||
# Backtrace interrupted when abort is called, IDF-842
|
||||
"panic_abort", "esp_system_abort"
|
||||
'panic_abort', 'esp_system_abort'
|
||||
])
|
||||
|
||||
|
||||
def storeprohibited_inner(env, test_name):
|
||||
with get_dut(env, test_name, "test_storeprohibited") as dut:
|
||||
dut.expect_gme("StoreProhibited")
|
||||
with get_dut(env, test_name, 'test_storeprohibited') as dut:
|
||||
dut.expect_gme('StoreProhibited')
|
||||
dut.expect_reg_dump(0)
|
||||
dut.expect_backtrace()
|
||||
dut.expect_elf_sha256()
|
||||
dut.expect_none("Guru Meditation")
|
||||
dut.expect_none('Guru Meditation')
|
||||
test_common(dut, test_name)
|
||||
|
||||
|
||||
def stack_overflow_inner(env, test_name):
|
||||
with get_dut(env, test_name, "test_stack_overflow") as dut:
|
||||
dut.expect_gme("Unhandled debug exception")
|
||||
dut.expect("Stack canary watchpoint triggered (main)")
|
||||
with get_dut(env, test_name, 'test_stack_overflow') as dut:
|
||||
dut.expect_gme('Unhandled debug exception')
|
||||
dut.expect('Stack canary watchpoint triggered (main)')
|
||||
dut.expect_reg_dump(0)
|
||||
dut.expect_backtrace()
|
||||
dut.expect_elf_sha256()
|
||||
dut.expect_none("Guru Meditation")
|
||||
dut.expect_none('Guru Meditation')
|
||||
test_common(dut, test_name)
|
||||
|
||||
|
||||
def illegal_instruction_inner(env, test_name):
|
||||
with get_dut(env, test_name, "test_illegal_instruction") as dut:
|
||||
dut.expect_gme("IllegalInstruction")
|
||||
with get_dut(env, test_name, 'test_illegal_instruction') as dut:
|
||||
dut.expect_gme('IllegalInstruction')
|
||||
dut.expect_reg_dump(0)
|
||||
dut.expect_backtrace()
|
||||
dut.expect_elf_sha256()
|
||||
dut.expect_none("Guru Meditation")
|
||||
dut.expect_none('Guru Meditation')
|
||||
test_common(dut, test_name)
|
||||
|
||||
|
||||
def instr_fetch_prohibited_inner(env, test_name):
|
||||
with get_dut(env, test_name, "test_instr_fetch_prohibited") as dut:
|
||||
dut.expect_gme("InstrFetchProhibited")
|
||||
with get_dut(env, test_name, 'test_instr_fetch_prohibited') as dut:
|
||||
dut.expect_gme('InstrFetchProhibited')
|
||||
dut.expect_reg_dump(0)
|
||||
dut.expect_backtrace()
|
||||
dut.expect_elf_sha256()
|
||||
dut.expect_none("Guru Meditation")
|
||||
dut.expect_none('Guru Meditation')
|
||||
test_common(dut, test_name,
|
||||
expected_backtrace=["_init"] + get_default_backtrace(dut.test_name))
|
||||
expected_backtrace=['_init'] + get_default_backtrace(dut.test_name))
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
import logging
|
||||
import os
|
||||
from pygdbmi.gdbcontroller import GdbController
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import ttfw_idf
|
||||
from tiny_test_fw import Utility, TinyFW, DUT
|
||||
from tiny_test_fw.Utility import SearchCases, CaseConfig
|
||||
|
||||
import ttfw_idf
|
||||
from pygdbmi.gdbcontroller import GdbController
|
||||
from tiny_test_fw import DUT, TinyFW, Utility
|
||||
from tiny_test_fw.Utility import CaseConfig, SearchCases
|
||||
|
||||
# hard-coded to the path one level above - only intended to be used from the panic test app
|
||||
TEST_PATH = os.path.relpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), ".."), os.getenv("IDF_PATH"))
|
||||
TEST_SUITE = "Panic"
|
||||
TEST_PATH = os.path.relpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..'), os.getenv('IDF_PATH'))
|
||||
TEST_SUITE = 'Panic'
|
||||
|
||||
|
||||
def ok(data):
|
||||
@@ -21,7 +21,7 @@ def ok(data):
|
||||
|
||||
def unexpected(data):
|
||||
""" Helper function used with dut.expect_any """
|
||||
raise AssertionError("Unexpected: {}".format(data))
|
||||
raise AssertionError('Unexpected: {}'.format(data))
|
||||
|
||||
|
||||
class PanicTestApp(ttfw_idf.TestApp):
|
||||
@@ -33,8 +33,8 @@ class PanicTestMixin(object):
|
||||
BOOT_CMD_ADDR = 0x9000
|
||||
BOOT_CMD_SIZE = 0x1000
|
||||
DEFAULT_EXPECT_TIMEOUT = 10
|
||||
COREDUMP_UART_START = "================= CORE DUMP START ================="
|
||||
COREDUMP_UART_END = "================= CORE DUMP END ================="
|
||||
COREDUMP_UART_START = '================= CORE DUMP START ================='
|
||||
COREDUMP_UART_END = '================= CORE DUMP END ================='
|
||||
|
||||
def start_test(self, test_name):
|
||||
""" Starts the app and sends it the test name """
|
||||
@@ -42,24 +42,24 @@ class PanicTestMixin(object):
|
||||
# Start the app and verify that it has started up correctly
|
||||
self.start_capture_raw_data()
|
||||
self.start_app()
|
||||
self.expect("Enter test name: ")
|
||||
Utility.console_log("Setting boot command: " + test_name)
|
||||
self.expect('Enter test name: ')
|
||||
Utility.console_log('Setting boot command: ' + test_name)
|
||||
self.write(test_name)
|
||||
self.expect("Got test name: " + test_name)
|
||||
self.expect('Got test name: ' + test_name)
|
||||
|
||||
def expect_none(self, *patterns, **timeout_args):
|
||||
""" like dut.expect_all, but with an inverse logic """
|
||||
found_data = []
|
||||
if "timeout" not in timeout_args:
|
||||
timeout_args["timeout"] = 1
|
||||
if 'timeout' not in timeout_args:
|
||||
timeout_args['timeout'] = 1
|
||||
|
||||
def found(data):
|
||||
raise AssertionError("Unexpected: {}".format(data))
|
||||
raise AssertionError('Unexpected: {}'.format(data))
|
||||
found_data.append(data)
|
||||
try:
|
||||
expect_items = [(pattern, found) for pattern in patterns]
|
||||
self.expect_any(*expect_items, **timeout_args)
|
||||
raise AssertionError("Unexpected: {}".format(found_data))
|
||||
raise AssertionError('Unexpected: {}'.format(found_data))
|
||||
except DUT.ExpectTimeout:
|
||||
return True
|
||||
|
||||
@@ -69,18 +69,18 @@ class PanicTestMixin(object):
|
||||
|
||||
def expect_reg_dump(self, core=0):
|
||||
""" Expect method for the register dump """
|
||||
self.expect(re.compile(r"Core\s+%d register dump:" % core))
|
||||
self.expect(re.compile(r'Core\s+%d register dump:' % core))
|
||||
|
||||
def expect_elf_sha256(self):
|
||||
""" Expect method for ELF SHA256 line """
|
||||
elf_sha256 = self.app.get_elf_sha256()
|
||||
sdkconfig = self.app.get_sdkconfig()
|
||||
elf_sha256_len = int(sdkconfig.get("CONFIG_APP_RETRIEVE_LEN_ELF_SHA", "16"))
|
||||
self.expect("ELF file SHA256: " + elf_sha256[0:elf_sha256_len])
|
||||
elf_sha256_len = int(sdkconfig.get('CONFIG_APP_RETRIEVE_LEN_ELF_SHA', '16'))
|
||||
self.expect('ELF file SHA256: ' + elf_sha256[0:elf_sha256_len])
|
||||
|
||||
def expect_backtrace(self):
|
||||
self.expect("Backtrace:")
|
||||
self.expect_none("CORRUPTED")
|
||||
self.expect('Backtrace:')
|
||||
self.expect_none('CORRUPTED')
|
||||
|
||||
def __enter__(self):
|
||||
self._raw_data = None
|
||||
@@ -89,8 +89,8 @@ class PanicTestMixin(object):
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
log_folder = self.app.get_log_folder(TEST_SUITE)
|
||||
with open(os.path.join(log_folder, "log_" + self.test_name + ".txt"), "w") as log_file:
|
||||
Utility.console_log("Writing output of {} to {}".format(self.test_name, log_file.name))
|
||||
with open(os.path.join(log_folder, 'log_' + self.test_name + '.txt'), 'w') as log_file:
|
||||
Utility.console_log('Writing output of {} to {}'.format(self.test_name, log_file.name))
|
||||
log_file.write(self.get_raw_data())
|
||||
if self.gdb:
|
||||
self.gdb.exit()
|
||||
@@ -103,18 +103,18 @@ class PanicTestMixin(object):
|
||||
|
||||
def _call_espcoredump(self, extra_args, coredump_file_name, output_file_name):
|
||||
# no "with" here, since we need the file to be open for later inspection by the test case
|
||||
self.coredump_output = open(output_file_name, "w")
|
||||
espcoredump_script = os.path.join(os.environ["IDF_PATH"], "components", "espcoredump", "espcoredump.py")
|
||||
self.coredump_output = open(output_file_name, 'w')
|
||||
espcoredump_script = os.path.join(os.environ['IDF_PATH'], 'components', 'espcoredump', 'espcoredump.py')
|
||||
espcoredump_args = [
|
||||
sys.executable,
|
||||
espcoredump_script,
|
||||
"info_corefile",
|
||||
"--core", coredump_file_name,
|
||||
'info_corefile',
|
||||
'--core', coredump_file_name,
|
||||
]
|
||||
espcoredump_args += extra_args
|
||||
espcoredump_args.append(self.app.elf_file)
|
||||
Utility.console_log("Running " + " ".join(espcoredump_args))
|
||||
Utility.console_log("espcoredump output is written to " + self.coredump_output.name)
|
||||
Utility.console_log('Running ' + ' '.join(espcoredump_args))
|
||||
Utility.console_log('espcoredump output is written to ' + self.coredump_output.name)
|
||||
|
||||
subprocess.check_call(espcoredump_args, stdout=self.coredump_output)
|
||||
self.coredump_output.flush()
|
||||
@@ -127,22 +127,22 @@ class PanicTestMixin(object):
|
||||
coredump_start = data.find(self.COREDUMP_UART_START)
|
||||
coredump_end = data.find(self.COREDUMP_UART_END)
|
||||
coredump_base64 = data[coredump_start + len(self.COREDUMP_UART_START):coredump_end]
|
||||
with open(os.path.join(log_folder, "coredump_data_" + self.test_name + ".b64"), "w") as coredump_file:
|
||||
Utility.console_log("Writing UART base64 core dump to " + coredump_file.name)
|
||||
with open(os.path.join(log_folder, 'coredump_data_' + self.test_name + '.b64'), 'w') as coredump_file:
|
||||
Utility.console_log('Writing UART base64 core dump to ' + coredump_file.name)
|
||||
coredump_file.write(coredump_base64)
|
||||
|
||||
output_file_name = os.path.join(log_folder, "coredump_uart_result_" + self.test_name + ".txt")
|
||||
self._call_espcoredump(["--core-format", "b64"], coredump_file.name, output_file_name)
|
||||
output_file_name = os.path.join(log_folder, 'coredump_uart_result_' + self.test_name + '.txt')
|
||||
self._call_espcoredump(['--core-format', 'b64'], coredump_file.name, output_file_name)
|
||||
|
||||
def process_coredump_flash(self):
|
||||
""" Extract the core dump from flash, run espcoredump on it """
|
||||
log_folder = self.app.get_log_folder(TEST_SUITE)
|
||||
coredump_file_name = os.path.join(log_folder, "coredump_data_" + self.test_name + ".bin")
|
||||
Utility.console_log("Writing flash binary core dump to " + coredump_file_name)
|
||||
self.dump_flash(coredump_file_name, partition="coredump")
|
||||
coredump_file_name = os.path.join(log_folder, 'coredump_data_' + self.test_name + '.bin')
|
||||
Utility.console_log('Writing flash binary core dump to ' + coredump_file_name)
|
||||
self.dump_flash(coredump_file_name, partition='coredump')
|
||||
|
||||
output_file_name = os.path.join(log_folder, "coredump_flash_result_" + self.test_name + ".txt")
|
||||
self._call_espcoredump(["--core-format", "raw"], coredump_file_name, output_file_name)
|
||||
output_file_name = os.path.join(log_folder, 'coredump_flash_result_' + self.test_name + '.txt')
|
||||
self._call_espcoredump(['--core-format', 'raw'], coredump_file_name, output_file_name)
|
||||
|
||||
def start_gdb(self):
|
||||
"""
|
||||
@@ -152,44 +152,44 @@ class PanicTestMixin(object):
|
||||
self.stop_receive()
|
||||
self._port_close()
|
||||
|
||||
Utility.console_log("Starting GDB...", "orange")
|
||||
self.gdb = GdbController(gdb_path=self.TOOLCHAIN_PREFIX + "gdb")
|
||||
Utility.console_log('Starting GDB...', 'orange')
|
||||
self.gdb = GdbController(gdb_path=self.TOOLCHAIN_PREFIX + 'gdb')
|
||||
|
||||
# pygdbmi logs to console by default, make it log to a file instead
|
||||
log_folder = self.app.get_log_folder(TEST_SUITE)
|
||||
pygdbmi_log_file_name = os.path.join(log_folder, "pygdbmi_log_" + self.test_name + ".txt")
|
||||
pygdbmi_log_file_name = os.path.join(log_folder, 'pygdbmi_log_' + self.test_name + '.txt')
|
||||
pygdbmi_logger = self.gdb.logger
|
||||
pygdbmi_logger.setLevel(logging.DEBUG)
|
||||
while pygdbmi_logger.hasHandlers():
|
||||
pygdbmi_logger.removeHandler(pygdbmi_logger.handlers[0])
|
||||
log_handler = logging.FileHandler(pygdbmi_log_file_name)
|
||||
log_handler.setFormatter(logging.Formatter("%(asctime)s %(levelname)s: %(message)s"))
|
||||
log_handler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s: %(message)s'))
|
||||
pygdbmi_logger.addHandler(log_handler)
|
||||
|
||||
# Set up logging for GDB remote protocol
|
||||
gdb_remotelog_file_name = os.path.join(log_folder, "gdb_remote_log_" + self.test_name + ".txt")
|
||||
self.gdb.write("-gdb-set remotelogfile " + gdb_remotelog_file_name)
|
||||
gdb_remotelog_file_name = os.path.join(log_folder, 'gdb_remote_log_' + self.test_name + '.txt')
|
||||
self.gdb.write('-gdb-set remotelogfile ' + gdb_remotelog_file_name)
|
||||
|
||||
# Load the ELF file
|
||||
self.gdb.write("-file-exec-and-symbols {}".format(self.app.elf_file))
|
||||
self.gdb.write('-file-exec-and-symbols {}'.format(self.app.elf_file))
|
||||
|
||||
# Connect GDB to UART
|
||||
Utility.console_log("Connecting to GDB Stub...", "orange")
|
||||
self.gdb.write("-gdb-set serial baud 115200")
|
||||
responses = self.gdb.write("-target-select remote " + self.get_gdb_remote(), timeout_sec=3)
|
||||
Utility.console_log('Connecting to GDB Stub...', 'orange')
|
||||
self.gdb.write('-gdb-set serial baud 115200')
|
||||
responses = self.gdb.write('-target-select remote ' + self.get_gdb_remote(), timeout_sec=3)
|
||||
|
||||
# Make sure we get the 'stopped' notification
|
||||
stop_response = self.find_gdb_response('stopped', 'notify', responses)
|
||||
if not stop_response:
|
||||
responses = self.gdb.write("-exec-interrupt", timeout_sec=3)
|
||||
responses = self.gdb.write('-exec-interrupt', timeout_sec=3)
|
||||
stop_response = self.find_gdb_response('stopped', 'notify', responses)
|
||||
assert stop_response
|
||||
frame = stop_response["payload"]["frame"]
|
||||
if "file" not in frame:
|
||||
frame["file"] = "?"
|
||||
if "line" not in frame:
|
||||
frame["line"] = "?"
|
||||
Utility.console_log("Stopped in {func} at {addr} ({file}:{line})".format(**frame), "orange")
|
||||
frame = stop_response['payload']['frame']
|
||||
if 'file' not in frame:
|
||||
frame['file'] = '?'
|
||||
if 'line' not in frame:
|
||||
frame['line'] = '?'
|
||||
Utility.console_log('Stopped in {func} at {addr} ({file}:{line})'.format(**frame), 'orange')
|
||||
|
||||
# Drain remaining responses
|
||||
self.gdb.get_gdb_response(raise_error_on_timeout=False)
|
||||
@@ -201,8 +201,8 @@ class PanicTestMixin(object):
|
||||
"""
|
||||
assert self.gdb
|
||||
|
||||
responses = self.gdb.write("-stack-list-frames", timeout_sec=3)
|
||||
return self.find_gdb_response("done", "result", responses)["payload"]["stack"]
|
||||
responses = self.gdb.write('-stack-list-frames', timeout_sec=3)
|
||||
return self.find_gdb_response('done', 'result', responses)['payload']['stack']
|
||||
|
||||
@staticmethod
|
||||
def match_backtrace(gdb_backtrace, expected_functions_list):
|
||||
@@ -211,7 +211,7 @@ class PanicTestMixin(object):
|
||||
given by gdb_backtrace argument. The latter is in the same format as returned by gdb_backtrace()
|
||||
function.
|
||||
"""
|
||||
return all([frame["func"] == expected_functions_list[i] for i, frame in enumerate(gdb_backtrace)])
|
||||
return all([frame['func'] == expected_functions_list[i] for i, frame in enumerate(gdb_backtrace)])
|
||||
|
||||
@staticmethod
|
||||
def find_gdb_response(message, response_type, responses):
|
||||
@@ -220,8 +220,8 @@ class PanicTestMixin(object):
|
||||
by message and type. Returned message is a dictionary, refer to pygdbmi docs for the format.
|
||||
"""
|
||||
def match_response(response):
|
||||
return (response["message"] == message and
|
||||
response["type"] == response_type)
|
||||
return (response['message'] == message and
|
||||
response['type'] == response_type)
|
||||
|
||||
filtered_responses = [r for r in responses if match_response(r)]
|
||||
if not filtered_responses:
|
||||
@@ -252,11 +252,11 @@ def panic_test(**kwargs):
|
||||
|
||||
if 'additional_duts' not in kwargs:
|
||||
kwargs['additional_duts'] = PANIC_TEST_DUT_DICT
|
||||
return ttfw_idf.idf_custom_test(app=PanicTestApp, env_tag="Example_GENERIC", **kwargs)
|
||||
return ttfw_idf.idf_custom_test(app=PanicTestApp, env_tag='Example_GENERIC', **kwargs)
|
||||
|
||||
|
||||
def get_dut(env, app_config_name, test_name, qemu_wdt_enable=False):
|
||||
dut = env.get_dut("panic", TEST_PATH, app_config_name=app_config_name, allow_dut_exception=True)
|
||||
dut = env.get_dut('panic', TEST_PATH, app_config_name=app_config_name, allow_dut_exception=True)
|
||||
dut.qemu_wdt_enable = qemu_wdt_enable
|
||||
""" Wrapper for getting the DUT and starting the test """
|
||||
dut.start_test(test_name)
|
||||
@@ -270,13 +270,13 @@ def run_all(filename, case_filter=[]):
|
||||
"""
|
||||
TinyFW.set_default_config(env_config_file=None, test_suite_name=TEST_SUITE)
|
||||
test_methods = SearchCases.Search.search_test_cases(filename)
|
||||
test_methods = filter(lambda m: not m.case_info["ignore"], test_methods)
|
||||
test_methods = filter(lambda m: not m.case_info['ignore'], test_methods)
|
||||
test_cases = CaseConfig.Parser.apply_config(test_methods, None)
|
||||
tests_failed = []
|
||||
for case in test_cases:
|
||||
test_name = case.test_method.__name__
|
||||
if case_filter:
|
||||
if case_filter[0].endswith("*"):
|
||||
if case_filter[0].endswith('*'):
|
||||
if not test_name.startswith(case_filter[0][:-1]):
|
||||
continue
|
||||
else:
|
||||
@@ -287,9 +287,9 @@ def run_all(filename, case_filter=[]):
|
||||
tests_failed.append(case)
|
||||
|
||||
if tests_failed:
|
||||
print("The following tests have failed:")
|
||||
print('The following tests have failed:')
|
||||
for case in tests_failed:
|
||||
print(" - " + case.test_method.__name__)
|
||||
print(' - ' + case.test_method.__name__)
|
||||
raise SystemExit(1)
|
||||
|
||||
print("Tests pass")
|
||||
print('Tests pass')
|
||||
|
||||
@@ -1,22 +1,23 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
import glob
|
||||
import os
|
||||
|
||||
import ttfw_idf
|
||||
from tiny_test_fw import Utility
|
||||
|
||||
|
||||
@ttfw_idf.idf_custom_test(env_tag="Example_GENERIC", group="test-apps")
|
||||
@ttfw_idf.idf_custom_test(env_tag='Example_GENERIC', group='test-apps')
|
||||
def test_startup(env, extra_data):
|
||||
config_files = glob.glob(os.path.join(os.path.dirname(__file__), "sdkconfig.ci.*"))
|
||||
config_names = [os.path.basename(s).replace("sdkconfig.ci.", "") for s in config_files]
|
||||
config_files = glob.glob(os.path.join(os.path.dirname(__file__), 'sdkconfig.ci.*'))
|
||||
config_names = [os.path.basename(s).replace('sdkconfig.ci.', '') for s in config_files]
|
||||
for name in config_names:
|
||||
Utility.console_log("Checking config \"{}\"... ".format(name), end="")
|
||||
dut = env.get_dut("startup", "tools/test_apps/system/startup", app_config_name=name)
|
||||
Utility.console_log("Checking config \"{}\"... ".format(name), end='')
|
||||
dut = env.get_dut('startup', 'tools/test_apps/system/startup', app_config_name=name)
|
||||
dut.start_app()
|
||||
dut.expect("app_main running")
|
||||
dut.expect('app_main running')
|
||||
env.close_dut(dut.name)
|
||||
Utility.console_log("done")
|
||||
Utility.console_log('done')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
Reference in New Issue
Block a user