mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
test: format all test scripts
This commit is contained in:
+4
-4
@@ -1,15 +1,15 @@
|
||||
# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
|
||||
from pytest_embedded_idf.utils import idf_parametrize
|
||||
|
||||
TEST_APP_IN_FLASH = [pytest.param('app_in_flash', marks=pytest.mark.esp32p4)]
|
||||
|
||||
|
||||
@pytest.mark.esp32p4
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.parametrize('config', TEST_APP_IN_FLASH, indirect=True)
|
||||
@idf_parametrize('config', ['app_in_flash'], indirect=['config'])
|
||||
@idf_parametrize('target', ['esp32p4'], indirect=['target'])
|
||||
def test_ld_non_contiguous_memory(dut: Dut) -> None:
|
||||
dut.expect_exact('buf2 placed in low sram')
|
||||
dut.expect_exact('buf1 placed in high sram')
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
from pytest_embedded_idf.utils import idf_parametrize
|
||||
|
||||
|
||||
@pytest.mark.linux
|
||||
@pytest.mark.host_test
|
||||
@idf_parametrize('target', ['linux'], indirect=['target'])
|
||||
def test_linux_freertos_SMP(dut: Dut) -> None:
|
||||
dut.expect_exact('Press ENTER to see the list of tests.')
|
||||
dut.write('![ignore]')
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
import pytest
|
||||
from pytest_embedded_idf.dut import IdfDut
|
||||
from pytest_embedded_idf.utils import idf_parametrize
|
||||
|
||||
|
||||
@pytest.mark.supported_targets
|
||||
@pytest.mark.temp_skip_ci(targets=['esp32h2', 'esp32p4'], reason='h2/p4 does not support wifi')
|
||||
@pytest.mark.generic
|
||||
@idf_parametrize('target', ['supported_targets'], indirect=['target'])
|
||||
def test_i2c_wifi_startup(dut: IdfDut) -> None:
|
||||
dut.expect_exact('I2C-WIFI test success')
|
||||
|
||||
@@ -1,17 +1,21 @@
|
||||
# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
import pytest
|
||||
from pytest_embedded_idf.dut import IdfDut
|
||||
from pytest_embedded_idf.utils import idf_parametrize
|
||||
|
||||
|
||||
@pytest.mark.supported_targets
|
||||
@pytest.mark.temp_skip_ci(targets=['esp32h2', 'esp32p4'], reason='h2/p4 not supported') # TODO: IDF-8990
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.parametrize('config', [
|
||||
'phy_multiple_init_data',
|
||||
'phy_multiple_init_data_embed',
|
||||
], indirect=True)
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
[
|
||||
'phy_multiple_init_data',
|
||||
'phy_multiple_init_data_embed',
|
||||
],
|
||||
indirect=True,
|
||||
)
|
||||
@idf_parametrize('target', ['supported_targets'], indirect=['target'])
|
||||
def test_phy_multi_init_data_bin(dut: IdfDut, config: str) -> None:
|
||||
if config == 'phy_multiple_init_data':
|
||||
dut.expect_exact('Support multiple PHY init data bins')
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
import random
|
||||
import string
|
||||
@@ -7,6 +7,7 @@ from typing import Tuple
|
||||
import pexpect
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
from pytest_embedded_idf.utils import idf_parametrize
|
||||
|
||||
|
||||
def run_phy_tsens_test(dut: Tuple[Dut, Dut]) -> None:
|
||||
@@ -143,12 +144,9 @@ def run_phy_tsens_test_with_light_sleep(dut: Tuple[Dut, Dut]) -> None:
|
||||
assert 0 < float(temp_val) < 70
|
||||
|
||||
|
||||
@pytest.mark.esp32c3
|
||||
@pytest.mark.esp32c6
|
||||
@pytest.mark.esp32s2
|
||||
@pytest.mark.esp32s3
|
||||
@pytest.mark.two_duts
|
||||
@pytest.mark.parametrize('count', [2], indirect=True)
|
||||
@idf_parametrize('target', ['esp32c3', 'esp32c6', 'esp32s2', 'esp32s3'], indirect=['target'])
|
||||
def test_phy_tsens_coexist(dut: Tuple[Dut, Dut]) -> None:
|
||||
for _dut in dut:
|
||||
_dut.expect('esp>')
|
||||
@@ -165,7 +163,6 @@ def test_phy_tsens_coexist(dut: Tuple[Dut, Dut]) -> None:
|
||||
run_phy_tsens_test_with_light_sleep(dut)
|
||||
|
||||
|
||||
@pytest.mark.esp32c2
|
||||
@pytest.mark.two_duts
|
||||
@pytest.mark.xtal_26mhz
|
||||
@pytest.mark.parametrize(
|
||||
@@ -175,6 +172,7 @@ def test_phy_tsens_coexist(dut: Tuple[Dut, Dut]) -> None:
|
||||
],
|
||||
indirect=True,
|
||||
)
|
||||
@idf_parametrize('target', ['esp32c2'], indirect=['target'])
|
||||
def test_phy_tsens_coexist_c2_xtal26m(dut: Tuple[Dut, Dut]) -> None:
|
||||
for _dut in dut:
|
||||
_dut.expect('esp>')
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
|
||||
import contextlib
|
||||
import logging
|
||||
import os
|
||||
@@ -9,31 +8,49 @@ import socketserver
|
||||
import ssl
|
||||
import subprocess
|
||||
from threading import Thread
|
||||
from typing import Any, Callable, Dict, Optional
|
||||
from typing import Any
|
||||
from typing import Callable
|
||||
from typing import Dict
|
||||
from typing import Optional
|
||||
|
||||
import pytest
|
||||
from common_test_methods import get_host_ip4_by_dest_ip
|
||||
from pytest_embedded import Dut
|
||||
from pytest_embedded_idf.utils import idf_parametrize
|
||||
|
||||
SERVER_PORT = 2222
|
||||
|
||||
|
||||
def _path(f): # type: (str) -> str
|
||||
return os.path.join(os.path.dirname(os.path.realpath(__file__)),f)
|
||||
return os.path.join(os.path.dirname(os.path.realpath(__file__)), f)
|
||||
|
||||
|
||||
def set_server_cert_cn(ip): # type: (str) -> None
|
||||
arg_list = [
|
||||
['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']]
|
||||
['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 RuntimeError('openssl command {} failed'.format(args))
|
||||
|
||||
|
||||
class MQTTHandler(socketserver.StreamRequestHandler):
|
||||
|
||||
def handle(self) -> None:
|
||||
logging.info(' - connection from: {}'.format(self.client_address))
|
||||
data = bytearray(self.request.recv(1024))
|
||||
@@ -56,12 +73,14 @@ class TlsServer(socketserver.TCPServer):
|
||||
allow_reuse_address = True
|
||||
allow_reuse_port = True
|
||||
|
||||
def __init__(self,
|
||||
port:int = SERVER_PORT,
|
||||
ServerHandler: Callable[[Any, Any, Any], socketserver.BaseRequestHandler] = MQTTHandler,
|
||||
client_cert:bool=False,
|
||||
refuse_connection:bool=False,
|
||||
use_alpn:bool=False):
|
||||
def __init__(
|
||||
self,
|
||||
port: int = SERVER_PORT,
|
||||
ServerHandler: Callable[[Any, Any, Any], socketserver.BaseRequestHandler] = MQTTHandler,
|
||||
client_cert: bool = False,
|
||||
refuse_connection: bool = False,
|
||||
use_alpn: bool = False,
|
||||
):
|
||||
self.refuse_connection = refuse_connection
|
||||
self.context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
|
||||
self.ssl_error = ''
|
||||
@@ -73,7 +92,7 @@ class TlsServer(socketserver.TCPServer):
|
||||
if use_alpn:
|
||||
self.context.set_alpn_protocols(['mymqtt', 'http/1.1'])
|
||||
self.server_thread = Thread(target=self.serve_forever)
|
||||
super().__init__(('',port), ServerHandler)
|
||||
super().__init__(('', port), ServerHandler)
|
||||
|
||||
def server_activate(self) -> None:
|
||||
self.socket = self.context.wrap_socket(self.socket, server_side=True)
|
||||
@@ -125,14 +144,16 @@ def get_test_cases(dut: Dut) -> Any:
|
||||
cases = {}
|
||||
try:
|
||||
# Get connection test cases configuration: symbolic names for test cases
|
||||
for case in ['EXAMPLE_CONNECT_CASE_NO_CERT',
|
||||
'EXAMPLE_CONNECT_CASE_SERVER_CERT',
|
||||
'EXAMPLE_CONNECT_CASE_MUTUAL_AUTH',
|
||||
'EXAMPLE_CONNECT_CASE_INVALID_SERVER_CERT',
|
||||
'EXAMPLE_CONNECT_CASE_SERVER_DER_CERT',
|
||||
'EXAMPLE_CONNECT_CASE_MUTUAL_AUTH_KEY_PWD',
|
||||
'EXAMPLE_CONNECT_CASE_MUTUAL_AUTH_BAD_CRT',
|
||||
'EXAMPLE_CONNECT_CASE_NO_CERT_ALPN']:
|
||||
for case in [
|
||||
'EXAMPLE_CONNECT_CASE_NO_CERT',
|
||||
'EXAMPLE_CONNECT_CASE_SERVER_CERT',
|
||||
'EXAMPLE_CONNECT_CASE_MUTUAL_AUTH',
|
||||
'EXAMPLE_CONNECT_CASE_INVALID_SERVER_CERT',
|
||||
'EXAMPLE_CONNECT_CASE_SERVER_DER_CERT',
|
||||
'EXAMPLE_CONNECT_CASE_MUTUAL_AUTH_KEY_PWD',
|
||||
'EXAMPLE_CONNECT_CASE_MUTUAL_AUTH_BAD_CRT',
|
||||
'EXAMPLE_CONNECT_CASE_NO_CERT_ALPN',
|
||||
]:
|
||||
cases[case] = dut.app.sdkconfig.get(case)
|
||||
except Exception:
|
||||
logging.error('ENV_TEST_FAILURE: Some mandatory CONNECTION test case not found in sdkconfig')
|
||||
@@ -147,7 +168,7 @@ def get_dut_ip(dut: Dut) -> Any:
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def connect_dut(dut: Dut, uri:str, case_id:int) -> Any:
|
||||
def connect_dut(dut: Dut, uri: str, case_id: int) -> Any:
|
||||
dut.write('connection_setup')
|
||||
dut.write(f'connect {uri} {case_id}')
|
||||
dut.expect(f'Test case:{case_id} started')
|
||||
@@ -157,12 +178,16 @@ def connect_dut(dut: Dut, uri:str, case_id:int) -> Any:
|
||||
dut.write('disconnect')
|
||||
|
||||
|
||||
def run_cases(dut:Dut, uri:str, cases:Dict[str, int]) -> None:
|
||||
def run_cases(dut: Dut, uri: str, cases: Dict[str, int]) -> None:
|
||||
try:
|
||||
dut.write('init')
|
||||
dut.write(f'start')
|
||||
dut.write(f'disconnect')
|
||||
for case in ['EXAMPLE_CONNECT_CASE_NO_CERT', 'EXAMPLE_CONNECT_CASE_SERVER_CERT', 'EXAMPLE_CONNECT_CASE_SERVER_DER_CERT']:
|
||||
for case in [
|
||||
'EXAMPLE_CONNECT_CASE_NO_CERT',
|
||||
'EXAMPLE_CONNECT_CASE_SERVER_CERT',
|
||||
'EXAMPLE_CONNECT_CASE_SERVER_DER_CERT',
|
||||
]:
|
||||
# All these cases connect to the server with no server verification or with server only verification
|
||||
with TlsServer(), connect_dut(dut, uri, cases[case]):
|
||||
logging.info(f'Running {case}: default server - expect to connect normally')
|
||||
@@ -172,9 +197,13 @@ def run_cases(dut:Dut, uri:str, cases:Dict[str, int]) -> None:
|
||||
dut.expect(f'MQTT_EVENT_ERROR: Test={cases[case]}', timeout=30)
|
||||
dut.expect('MQTT ERROR: 0x5') # expecting 0x5 ... connection not authorized error
|
||||
with TlsServer(client_cert=True) as server, connect_dut(dut, uri, cases[case]):
|
||||
logging.info(f'Running {case}: server with client verification - handshake error since client presents no client certificate')
|
||||
logging.info(
|
||||
f'Running {case}: server with client verification - handshake error since client presents no client certificate'
|
||||
)
|
||||
dut.expect(f'MQTT_EVENT_ERROR: Test={cases[case]}', timeout=30)
|
||||
dut.expect('ESP-TLS ERROR: ESP_ERR_MBEDTLS_SSL_HANDSHAKE_FAILED') # expect ... handshake error (PEER_DID_NOT_RETURN_A_CERTIFICATE)
|
||||
dut.expect(
|
||||
'ESP-TLS ERROR: ESP_ERR_MBEDTLS_SSL_HANDSHAKE_FAILED'
|
||||
) # expect ... handshake error (PEER_DID_NOT_RETURN_A_CERTIFICATE)
|
||||
assert 'PEER_DID_NOT_RETURN_A_CERTIFICATE' in server.last_ssl_error()
|
||||
|
||||
for case in ['EXAMPLE_CONNECT_CASE_MUTUAL_AUTH', 'EXAMPLE_CONNECT_CASE_MUTUAL_AUTH_KEY_PWD']:
|
||||
@@ -187,15 +216,21 @@ def run_cases(dut:Dut, uri:str, cases:Dict[str, int]) -> None:
|
||||
with TlsServer() as s, connect_dut(dut, uri, cases[case]):
|
||||
logging.info(f'Running {case}: invalid server certificate on default server - expect ssl handshake error')
|
||||
dut.expect(f'MQTT_EVENT_ERROR: Test={cases[case]}', timeout=30)
|
||||
dut.expect('ESP-TLS ERROR: ESP_ERR_MBEDTLS_SSL_HANDSHAKE_FAILED') # expect ... handshake error (TLSV1_ALERT_UNKNOWN_CA)
|
||||
if re.match('.*alert.*unknown.*ca',s.last_ssl_error(), flags=re.I) is None:
|
||||
dut.expect(
|
||||
'ESP-TLS ERROR: ESP_ERR_MBEDTLS_SSL_HANDSHAKE_FAILED'
|
||||
) # expect ... handshake error (TLSV1_ALERT_UNKNOWN_CA)
|
||||
if re.match('.*alert.*unknown.*ca', s.last_ssl_error(), flags=re.I) is None:
|
||||
raise Exception(f'Unexpected ssl error from the server: {s.last_ssl_error()}')
|
||||
|
||||
case = 'EXAMPLE_CONNECT_CASE_MUTUAL_AUTH_BAD_CRT'
|
||||
with TlsServer(client_cert=True) as s, connect_dut(dut, uri, cases[case]):
|
||||
logging.info(f'Running {case}: Invalid client certificate on server with client verification - expect ssl handshake error')
|
||||
logging.info(
|
||||
f'Running {case}: Invalid client certificate on server with client verification - expect ssl handshake error'
|
||||
)
|
||||
dut.expect(f'MQTT_EVENT_ERROR: Test={cases[case]}', timeout=30)
|
||||
dut.expect('ESP-TLS ERROR: ESP_ERR_MBEDTLS_SSL_HANDSHAKE_FAILED') # expect ... handshake error (CERTIFICATE_VERIFY_FAILED)
|
||||
dut.expect(
|
||||
'ESP-TLS ERROR: ESP_ERR_MBEDTLS_SSL_HANDSHAKE_FAILED'
|
||||
) # expect ... handshake error (CERTIFICATE_VERIFY_FAILED)
|
||||
if 'CERTIFICATE_VERIFY_FAILED' not in s.last_ssl_error():
|
||||
raise Exception('Unexpected ssl error from the server {}'.format(s.last_ssl_error()))
|
||||
|
||||
@@ -214,8 +249,8 @@ def run_cases(dut:Dut, uri:str, cases:Dict[str, int]) -> None:
|
||||
dut.write('destroy')
|
||||
|
||||
|
||||
@pytest.mark.esp32
|
||||
@pytest.mark.ethernet
|
||||
@idf_parametrize('target', ['esp32'], indirect=['target'])
|
||||
def test_mqtt_connect(
|
||||
dut: Dut,
|
||||
log_performance: Callable[[str, object], None],
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
|
||||
import contextlib
|
||||
import difflib
|
||||
import logging
|
||||
@@ -9,23 +8,32 @@ import random
|
||||
import re
|
||||
import ssl
|
||||
import string
|
||||
from itertools import count, product
|
||||
from threading import Event, Lock
|
||||
from typing import Any, Dict, List, Tuple, no_type_check
|
||||
from itertools import count
|
||||
from itertools import product
|
||||
from threading import Event
|
||||
from threading import Lock
|
||||
from typing import Any
|
||||
from typing import Dict
|
||||
from typing import List
|
||||
from typing import no_type_check
|
||||
from typing import Tuple
|
||||
|
||||
import paho.mqtt.client as mqtt
|
||||
import pexpect
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
from pytest_embedded_idf.utils import idf_parametrize
|
||||
|
||||
DEFAULT_MSG_SIZE = 16
|
||||
|
||||
|
||||
# Publisher class creating a python client to send/receive published data from esp-mqtt client
|
||||
class MqttPublisher(mqtt.Client):
|
||||
|
||||
def __init__(self, repeat, published, publish_cfg, log_details=False): # type: (MqttPublisher, int, int, dict, bool) -> None
|
||||
self.sample_string = ''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for _ in range(DEFAULT_MSG_SIZE))
|
||||
self.sample_string = ''.join(
|
||||
random.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits)
|
||||
for _ in range(DEFAULT_MSG_SIZE)
|
||||
)
|
||||
self.log_details = log_details
|
||||
self.repeat = repeat
|
||||
self.publish_cfg = publish_cfg
|
||||
@@ -42,7 +50,7 @@ class MqttPublisher(mqtt.Client):
|
||||
if self.log_details:
|
||||
logging.info(text)
|
||||
|
||||
def on_connect(self, mqttc: Any, obj: Any, flags: Any, rc:int) -> None:
|
||||
def on_connect(self, mqttc: Any, obj: Any, flags: Any, rc: int) -> None:
|
||||
self.event_client_connected.set()
|
||||
|
||||
def on_connect_fail(self, mqttc: Any, obj: Any) -> None:
|
||||
@@ -58,12 +66,14 @@ class MqttPublisher(mqtt.Client):
|
||||
self.event_client_got_all.set()
|
||||
else:
|
||||
differences = len(list(filter(lambda data: data[0] != data[1], zip(payload, self.expected_data))))
|
||||
logging.error(f'Payload differ in {differences} positions from expected data. received size: {len(payload)} expected size:'
|
||||
f'{len(self.expected_data)}')
|
||||
logging.error(
|
||||
f'Payload differ in {differences} positions from expected data. received size: {len(payload)} expected size:'
|
||||
f'{len(self.expected_data)}'
|
||||
)
|
||||
logging.info(f'Repetitions: {payload.count(self.sample_string)}')
|
||||
logging.info(f'Pattern: {self.sample_string}')
|
||||
logging.info(f'First : {payload[:DEFAULT_MSG_SIZE]}')
|
||||
logging.info(f'Last : {payload[-DEFAULT_MSG_SIZE:]}')
|
||||
logging.info(f'First : {payload[:DEFAULT_MSG_SIZE]}') # noqa: E203
|
||||
logging.info(f'Last : {payload[-DEFAULT_MSG_SIZE:]}') # noqa: E203
|
||||
matcher = difflib.SequenceMatcher(a=payload, b=self.expected_data)
|
||||
for match in matcher.get_matching_blocks():
|
||||
logging.info(f'Match: {match}')
|
||||
@@ -97,9 +107,10 @@ class MqttPublisher(mqtt.Client):
|
||||
self.loop_stop()
|
||||
|
||||
|
||||
def get_configurations(dut: Dut) -> Dict[str,Any]:
|
||||
def get_configurations(dut: Dut) -> Dict[str, Any]:
|
||||
publish_cfg = {}
|
||||
try:
|
||||
|
||||
@no_type_check
|
||||
def get_broker_from_dut(dut, config_option):
|
||||
# logging.info('Option:', config_option, dut.app.sdkconfig.get(config_option))
|
||||
@@ -107,13 +118,20 @@ def get_configurations(dut: Dut) -> Dict[str,Any]:
|
||||
if value is None:
|
||||
return None, None
|
||||
return value.group(1), int(value.group(2))
|
||||
|
||||
# Get publish test configuration
|
||||
publish_cfg['publish_topic'] = dut.app.sdkconfig.get('EXAMPLE_SUBSCRIBE_TOPIC').replace('"','')
|
||||
publish_cfg['subscribe_topic'] = dut.app.sdkconfig.get('EXAMPLE_PUBLISH_TOPIC').replace('"','')
|
||||
publish_cfg['broker_host_ssl'], publish_cfg['broker_port_ssl'] = get_broker_from_dut(dut, 'EXAMPLE_BROKER_SSL_URI')
|
||||
publish_cfg['broker_host_tcp'], publish_cfg['broker_port_tcp'] = get_broker_from_dut(dut, 'EXAMPLE_BROKER_TCP_URI')
|
||||
publish_cfg['publish_topic'] = dut.app.sdkconfig.get('EXAMPLE_SUBSCRIBE_TOPIC').replace('"', '')
|
||||
publish_cfg['subscribe_topic'] = dut.app.sdkconfig.get('EXAMPLE_PUBLISH_TOPIC').replace('"', '')
|
||||
publish_cfg['broker_host_ssl'], publish_cfg['broker_port_ssl'] = get_broker_from_dut(
|
||||
dut, 'EXAMPLE_BROKER_SSL_URI'
|
||||
)
|
||||
publish_cfg['broker_host_tcp'], publish_cfg['broker_port_tcp'] = get_broker_from_dut(
|
||||
dut, 'EXAMPLE_BROKER_TCP_URI'
|
||||
)
|
||||
publish_cfg['broker_host_ws'], publish_cfg['broker_port_ws'] = get_broker_from_dut(dut, 'EXAMPLE_BROKER_WS_URI')
|
||||
publish_cfg['broker_host_wss'], publish_cfg['broker_port_wss'] = get_broker_from_dut(dut, 'EXAMPLE_BROKER_WSS_URI')
|
||||
publish_cfg['broker_host_wss'], publish_cfg['broker_port_wss'] = get_broker_from_dut(
|
||||
dut, 'EXAMPLE_BROKER_WSS_URI'
|
||||
)
|
||||
|
||||
except Exception:
|
||||
logging.info('ENV_TEST_FAILURE: Some mandatory PUBLISH test case not found in sdkconfig')
|
||||
@@ -123,7 +141,7 @@ def get_configurations(dut: Dut) -> Dict[str,Any]:
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def connected_and_subscribed(dut:Dut, transport:str, pattern:str, pattern_repetitions:int) -> Any:
|
||||
def connected_and_subscribed(dut: Dut, transport: str, pattern: str, pattern_repetitions: int) -> Any:
|
||||
dut.write(f'publish_setup {transport} {pattern} {pattern_repetitions}')
|
||||
dut.write(f'start')
|
||||
dut.expect(re.compile(rb'MQTT_EVENT_SUBSCRIBED'), timeout=60)
|
||||
@@ -136,16 +154,17 @@ def get_scenarios() -> List[Dict[str, int]]:
|
||||
# Initialize message sizes and repeat counts (if defined in the environment)
|
||||
for i in count(0):
|
||||
# Check env variable: MQTT_PUBLISH_MSG_{len|repeat}_{x}
|
||||
env_dict = {var:'MQTT_PUBLISH_MSG_' + var + '_' + str(i) for var in ['len', 'repeat']}
|
||||
env_dict = {var: 'MQTT_PUBLISH_MSG_' + var + '_' + str(i) for var in ['len', 'repeat']}
|
||||
if os.getenv(env_dict['len']) and os.getenv(env_dict['repeat']):
|
||||
scenarios.append({var: int(os.getenv(env_dict[var])) for var in ['len', 'repeat']}) # type: ignore
|
||||
continue
|
||||
break
|
||||
if not scenarios: # No message sizes present in the env - set defaults
|
||||
scenarios = [{'len':0, 'repeat':5}, # zero-sized messages
|
||||
{'len':2, 'repeat':5}, # short messages
|
||||
{'len':200, 'repeat':3}, # long messages
|
||||
]
|
||||
if not scenarios: # No message sizes present in the env - set defaults
|
||||
scenarios = [
|
||||
{'len': 0, 'repeat': 5}, # zero-sized messages
|
||||
{'len': 2, 'repeat': 5}, # short messages
|
||||
{'len': 200, 'repeat': 3}, # long messages
|
||||
]
|
||||
return scenarios
|
||||
|
||||
|
||||
@@ -166,14 +185,20 @@ def run_publish_test_case(dut: Dut, test_case: Any, publish_cfg: Any) -> None:
|
||||
publish_cfg['queue'] = enqueue
|
||||
publish_cfg['transport'] = transport
|
||||
test_timeout = get_timeout(test_case)
|
||||
logging.info(f'Starting Publish test: transport:{transport}, qos:{qos}, nr_of_msgs:{published},'
|
||||
f' msg_size:{repeat*DEFAULT_MSG_SIZE}, enqueue:{enqueue}')
|
||||
with MqttPublisher(repeat, published, publish_cfg) as publisher, connected_and_subscribed(dut, transport, publisher.sample_string, scenario['len']):
|
||||
logging.info(
|
||||
f'Starting Publish test: transport:{transport}, qos:{qos}, nr_of_msgs:{published},'
|
||||
f' msg_size:{repeat * DEFAULT_MSG_SIZE}, enqueue:{enqueue}'
|
||||
)
|
||||
with MqttPublisher(repeat, published, publish_cfg) as publisher, connected_and_subscribed(
|
||||
dut, transport, publisher.sample_string, scenario['len']
|
||||
):
|
||||
msgs_published: List[mqtt.MQTTMessageInfo] = []
|
||||
dut.write(f'publish {publisher.published} {qos} {enqueue}')
|
||||
assert publisher.event_client_got_all.wait(timeout=test_timeout), (f'Not all data received from ESP32: {transport} '
|
||||
f'qos={qos} received: {publisher.received} '
|
||||
f'expected: {publisher.published}')
|
||||
assert publisher.event_client_got_all.wait(timeout=test_timeout), (
|
||||
f'Not all data received from ESP32: {transport} '
|
||||
f'qos={qos} received: {publisher.received} '
|
||||
f'expected: {publisher.published}'
|
||||
)
|
||||
logging.info(' - all data received from ESP32')
|
||||
payload = publisher.sample_string * publisher.repeat
|
||||
for _ in range(publisher.published):
|
||||
@@ -194,7 +219,7 @@ def run_publish_test_case(dut: Dut, test_case: Any, publish_cfg: Any) -> None:
|
||||
logging.info('ESP32 received all data from runner')
|
||||
|
||||
|
||||
stress_scenarios = [{'len':20, 'repeat':50}] # many medium sized
|
||||
stress_scenarios = [{'len': 20, 'repeat': 50}] # many medium sized
|
||||
transport_cases = ['tcp', 'ws', 'wss', 'ssl']
|
||||
qos_cases = [0, 1, 2]
|
||||
enqueue_cases = [0, 1]
|
||||
@@ -208,10 +233,10 @@ test_cases = make_cases(get_scenarios())
|
||||
stress_test_cases = make_cases(stress_scenarios)
|
||||
|
||||
|
||||
@pytest.mark.esp32
|
||||
@pytest.mark.ethernet
|
||||
@pytest.mark.nightly_run
|
||||
@pytest.mark.parametrize('test_case', test_cases)
|
||||
@idf_parametrize('target', ['esp32'], indirect=['target'])
|
||||
def test_mqtt_publish(dut: Dut, test_case: Any) -> None:
|
||||
publish_cfg = get_configurations(dut)
|
||||
dut.expect(re.compile(rb'mqtt>'), timeout=30)
|
||||
@@ -219,10 +244,10 @@ def test_mqtt_publish(dut: Dut, test_case: Any) -> None:
|
||||
run_publish_test_case(dut, test_case, publish_cfg)
|
||||
|
||||
|
||||
@pytest.mark.esp32
|
||||
@pytest.mark.ethernet
|
||||
@pytest.mark.nightly_run
|
||||
@pytest.mark.parametrize('test_case', stress_test_cases)
|
||||
@idf_parametrize('target', ['esp32'], indirect=['target'])
|
||||
def test_mqtt_publish_stress(dut: Dut, test_case: Any) -> None:
|
||||
publish_cfg = get_configurations(dut)
|
||||
dut.expect(re.compile(rb'mqtt>'), timeout=30)
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
import struct
|
||||
import typing as t
|
||||
import zlib
|
||||
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
from pytest_embedded_idf.utils import idf_parametrize
|
||||
|
||||
|
||||
# To prepare a runner for these tests,
|
||||
# 1. Connect an FPGA with C3 image
|
||||
@@ -17,10 +18,8 @@ from pytest_embedded import Dut
|
||||
# Export it as EFUSEPORT
|
||||
# e.g export EFUSEPORT=/dev/ttyUSB1
|
||||
# 4. Run these tests
|
||||
|
||||
|
||||
def corrupt_signature(signed_bootloader, seed=0, corrupt_sig=True, corrupt_crc=False, corrupt_single_block=None):
|
||||
# type: (bytes, int, bool, bool, int) -> bytes
|
||||
# type: (bytes, int, bool, bool, t.Optional[int]) -> bytes
|
||||
image = signed_bootloader[:-4096]
|
||||
signature = signed_bootloader[-4096:]
|
||||
sig_blocks = (signature[0:1216], signature[1216:2432], signature[2432:3648])
|
||||
@@ -37,8 +36,8 @@ def corrupt_sig_block(sig_block, seed=0, corrupt_sig=True, corrupt_crc=False):
|
||||
# type: (bytes, int, bool, bool) -> bytes
|
||||
assert len(sig_block) == 1216
|
||||
magic = sig_block[0]
|
||||
assert magic in [0xe7, 0xff]
|
||||
if magic != 0xe7:
|
||||
assert magic in [0xE7, 0xFF]
|
||||
if magic != 0xE7:
|
||||
return sig_block # not valid
|
||||
data = sig_block[:812]
|
||||
new_sig = sig = sig_block[812:1196]
|
||||
@@ -58,7 +57,7 @@ def corrupt_sig_block(sig_block, seed=0, corrupt_sig=True, corrupt_crc=False):
|
||||
assert new_sig != sig
|
||||
|
||||
if not corrupt_crc:
|
||||
crc = struct.pack('<I', zlib.crc32(data + new_sig) & 0xffffffff)
|
||||
crc = struct.pack('<I', zlib.crc32(data + new_sig) & 0xFFFFFFFF)
|
||||
else:
|
||||
crc = struct.pack('<I', zlib.crc32(crc))
|
||||
|
||||
@@ -79,9 +78,7 @@ def dut_start_secure_app(dut: Dut) -> None:
|
||||
|
||||
# Test secure boot flow.
|
||||
# Correctly signed bootloader + correctly signed app should work
|
||||
@pytest.mark.esp32c3
|
||||
@pytest.mark.esp32s3
|
||||
@pytest.mark.esp32p4
|
||||
@idf_parametrize('target', ['esp32c3', 'esp32s3', 'esp32p4'], indirect=['target'])
|
||||
def test_examples_security_secure_boot(dut: Dut) -> None:
|
||||
dut_start_secure_app(dut)
|
||||
dut.expect('Secure Boot is enabled', timeout=10)
|
||||
@@ -91,12 +88,10 @@ def test_examples_security_secure_boot(dut: Dut) -> None:
|
||||
|
||||
# Test efuse key index and key block combination.
|
||||
# Any key index can be written to any key block and should work
|
||||
@pytest.mark.esp32c3
|
||||
@pytest.mark.esp32s3
|
||||
@pytest.mark.esp32p4
|
||||
# Increasing the test timeout to 1200s as the test runs for 18 iterations
|
||||
# and thus the default 600s timeout is not sufficient
|
||||
@pytest.mark.timeout(1200)
|
||||
@idf_parametrize('target', ['esp32c3', 'esp32s3', 'esp32p4'], indirect=['target'])
|
||||
def test_examples_security_secure_boot_key_combo(dut: Dut) -> None:
|
||||
dut_start_secure_app(dut)
|
||||
dut.expect('Secure Boot is enabled', timeout=10)
|
||||
@@ -113,9 +108,7 @@ def test_examples_security_secure_boot_key_combo(dut: Dut) -> None:
|
||||
|
||||
# Test secure boot key revoke.
|
||||
# If a key is revoked, bootloader signed with that key should fail verification
|
||||
@pytest.mark.esp32c3
|
||||
@pytest.mark.esp32s3
|
||||
@pytest.mark.esp32p4
|
||||
@idf_parametrize('target', ['esp32c3', 'esp32s3', 'esp32p4'], indirect=['target'])
|
||||
def test_examples_security_secure_boot_key_revoke(dut: Dut) -> None:
|
||||
dut_start_secure_app(dut)
|
||||
dut.expect('Secure Boot is enabled', timeout=10)
|
||||
@@ -132,12 +125,10 @@ def test_examples_security_secure_boot_key_revoke(dut: Dut) -> None:
|
||||
|
||||
# Test bootloader signature corruption.
|
||||
# Corrupt one byte at a time of bootloader signature and test that the verification fails
|
||||
@pytest.mark.esp32c3
|
||||
@pytest.mark.esp32s3
|
||||
@pytest.mark.esp32p4
|
||||
@pytest.mark.timeout(18000)
|
||||
# Increasing the test timeout to 18000s as the test runs for 384 iterations
|
||||
# and thus the default 600s timeout is not sufficient
|
||||
@idf_parametrize('target', ['esp32c3', 'esp32s3', 'esp32p4'], indirect=['target'])
|
||||
def test_examples_security_secure_boot_corrupt_bl_sig(dut: Dut) -> None:
|
||||
dut_start_secure_app(dut)
|
||||
dut.expect('Secure Boot is enabled', timeout=10)
|
||||
@@ -169,12 +160,10 @@ def test_examples_security_secure_boot_corrupt_bl_sig(dut: Dut) -> None:
|
||||
|
||||
# Test app signature corruption.
|
||||
# Corrupt app signature, one byte at a time, and test that the verification fails
|
||||
@pytest.mark.esp32c3
|
||||
@pytest.mark.esp32s3
|
||||
@pytest.mark.esp32p4
|
||||
@pytest.mark.timeout(18000)
|
||||
# Increasing the test timeout to 18000s as the test runs for 385 iterations
|
||||
# and thus the default 600s timeout is not sufficient
|
||||
@idf_parametrize('target', ['esp32c3', 'esp32s3', 'esp32p4'], indirect=['target'])
|
||||
def test_examples_security_secure_boot_corrupt_app_sig(dut: Dut) -> None:
|
||||
dut_start_secure_app(dut)
|
||||
dut.expect('Secure Boot is enabled', timeout=10)
|
||||
@@ -213,6 +202,8 @@ def test_examples_security_secure_boot_corrupt_app_sig(dut: Dut) -> None:
|
||||
dut.secure_boot_burn_en_bit()
|
||||
dut.secure_boot_burn_digest('test_rsa_3072_key.pem', 0, 0)
|
||||
|
||||
dut.expect('Sig block 0 invalid: {}'.format('CRC mismatch' if dut.target == 'esp32p4' else 'Stored CRC ends'), timeout=2)
|
||||
dut.expect(
|
||||
'Sig block 0 invalid: {}'.format('CRC mismatch' if dut.target == 'esp32p4' else 'Stored CRC ends'), timeout=2
|
||||
)
|
||||
dut.expect('Secure boot signature verification failed', timeout=2)
|
||||
dut.expect('No bootable app partitions in the partition table', timeout=2)
|
||||
|
||||
+7
-5
@@ -1,12 +1,14 @@
|
||||
# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
from pytest_embedded_idf.utils import idf_parametrize
|
||||
|
||||
|
||||
@pytest.mark.esp32c2
|
||||
@pytest.mark.esp32c3
|
||||
@pytest.mark.generic
|
||||
@idf_parametrize('target', ['esp32c2', 'esp32c3'], indirect=['target'])
|
||||
def test_examples_security_on_update_no_secure_boot(dut: Dut) -> None:
|
||||
dut.expect("This app is not signed, but check signature on update is enabled in config. It won't be possible to verify any update.", timeout=10)
|
||||
dut.expect(
|
||||
"This app is not signed, but check signature on update is enabled in config. It won't be possible to verify any update.",
|
||||
timeout=10,
|
||||
)
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
from pytest_embedded_idf.utils import idf_parametrize
|
||||
|
||||
|
||||
@pytest.mark.esp32
|
||||
@pytest.mark.esp32c3
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
[
|
||||
'default',
|
||||
],
|
||||
indirect=True)
|
||||
indirect=True,
|
||||
)
|
||||
@idf_parametrize('target', ['esp32', 'esp32c3'], indirect=['target'])
|
||||
def test_partition_table_readonly(dut: Dut) -> None:
|
||||
dut.run_all_single_board_cases(timeout=120)
|
||||
|
||||
|
||||
@pytest.mark.esp32
|
||||
@pytest.mark.esp32c3
|
||||
@pytest.mark.flash_encryption
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
[
|
||||
'encrypted',
|
||||
],
|
||||
indirect=True)
|
||||
indirect=True,
|
||||
)
|
||||
@idf_parametrize('target', ['esp32', 'esp32c3'], indirect=['target'])
|
||||
def test_partition_table_readonly_flash_encryption(dut: Dut) -> None:
|
||||
dut.run_all_single_board_cases(timeout=120)
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
# SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
import os
|
||||
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
from pytest_embedded_idf.utils import idf_parametrize
|
||||
|
||||
PROMPT = 'test_intr_dump>'
|
||||
|
||||
|
||||
@pytest.mark.esp32
|
||||
@pytest.mark.qemu
|
||||
@pytest.mark.host_test
|
||||
@idf_parametrize('target', ['esp32'], indirect=['target'])
|
||||
def test_esp_intr_dump_nonshared(dut: Dut) -> None:
|
||||
dut.expect_exact(PROMPT, timeout=30)
|
||||
|
||||
@@ -22,9 +23,9 @@ def test_esp_intr_dump_nonshared(dut: Dut) -> None:
|
||||
dut.expect(r'(\d+)\s+3\s+Level\s+Used: GPIO')
|
||||
|
||||
|
||||
@pytest.mark.esp32
|
||||
@pytest.mark.qemu
|
||||
@pytest.mark.host_test
|
||||
@idf_parametrize('target', ['esp32'], indirect=['target'])
|
||||
def test_esp_intr_dump_shared(dut: Dut) -> None:
|
||||
dut.expect_exact(PROMPT, timeout=30)
|
||||
|
||||
@@ -47,8 +48,8 @@ def test_esp_intr_dump_shared(dut: Dut) -> None:
|
||||
|
||||
|
||||
# TODO: IDF-9512, Update the expected output of dual core RISC-V chips when the issue is resolved
|
||||
@pytest.mark.supported_targets
|
||||
@pytest.mark.generic
|
||||
@idf_parametrize('target', ['supported_targets'], indirect=['target'])
|
||||
def test_esp_intr_dump_expected_output(dut: Dut) -> None:
|
||||
dut.expect_exact(PROMPT, timeout=30)
|
||||
dut.write('intr_dump\n')
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
import os
|
||||
import re
|
||||
@@ -7,6 +7,7 @@ import typing
|
||||
import pexpect
|
||||
import pytest
|
||||
from pytest_embedded_idf import IdfDut
|
||||
from pytest_embedded_idf.utils import idf_parametrize
|
||||
|
||||
if typing.TYPE_CHECKING:
|
||||
from conftest import OpenOCD
|
||||
@@ -34,18 +35,13 @@ def _test_idf_gdb(openocd_dut: 'OpenOCD', dut: IdfDut) -> None:
|
||||
p.expect_exact('hit Temporary breakpoint 1, app_main ()')
|
||||
|
||||
|
||||
@pytest.mark.esp32
|
||||
@pytest.mark.esp32s2
|
||||
@pytest.mark.esp32c2
|
||||
@pytest.mark.jtag
|
||||
@idf_parametrize('target', ['esp32', 'esp32s2', 'esp32c2'], indirect=['target'])
|
||||
def test_idf_gdb(openocd_dut: 'OpenOCD', dut: IdfDut) -> None:
|
||||
_test_idf_gdb(openocd_dut, dut)
|
||||
|
||||
|
||||
@pytest.mark.esp32s3
|
||||
@pytest.mark.esp32c3
|
||||
@pytest.mark.esp32c6
|
||||
@pytest.mark.esp32h2
|
||||
@pytest.mark.usb_serial_jtag
|
||||
@idf_parametrize('target', ['esp32s3', 'esp32c3', 'esp32c6', 'esp32h2'], indirect=['target'])
|
||||
def test_idf_gdb_usj(openocd_dut: 'OpenOCD', dut: IdfDut) -> None:
|
||||
_test_idf_gdb(openocd_dut, dut)
|
||||
|
||||
@@ -1,19 +1,16 @@
|
||||
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
|
||||
import pytest
|
||||
from pytest_embedded_idf import IdfDut
|
||||
from pytest_embedded_idf.utils import idf_parametrize
|
||||
|
||||
|
||||
@pytest.mark.parametrize('offset', [
|
||||
pytest.param('0x40007d54', marks=[pytest.mark.esp32]),
|
||||
# pytest.param('0x4000f6e2', marks=[pytest.mark.esp32s2]),
|
||||
# pytest.param('0x40047654', marks=[pytest.mark.esp32c3]),
|
||||
])
|
||||
@pytest.mark.parametrize('embedded_services, skip_autoflash, erase_all', [
|
||||
('esp,idf,jtag', 'y', 'y'),
|
||||
], indirect=True)
|
||||
@pytest.mark.jtag
|
||||
@idf_parametrize('embedded_services', ['esp,idf,jtag'], indirect=['embedded_services'])
|
||||
@idf_parametrize('erase_all', ['y'], indirect=['erase_all'])
|
||||
@idf_parametrize('offset', ['0x40007d54'])
|
||||
@idf_parametrize('skip_autoflash', ['y'], indirect=['skip_autoflash'])
|
||||
@idf_parametrize('target', ['esp32'], indirect=['target'])
|
||||
def test_loadable_elf(dut: IdfDut, offset: str) -> None:
|
||||
dut.gdb.write('mon reset halt')
|
||||
dut.gdb.write(f'thb *{offset}')
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
# SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
import os.path as path
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
from pytest_embedded_idf.utils import idf_parametrize
|
||||
|
||||
sys.path.append(path.expandvars(path.join('$IDF_PATH', 'tools', 'test_apps', 'system', 'panic')))
|
||||
from test_panic_util import PanicTestDut # noqa: E402
|
||||
@@ -19,8 +20,8 @@ def get_line_number(lookup: str, offset: int = 0) -> int:
|
||||
|
||||
|
||||
@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='esp32p4 support TBD') # TODO: IDF-8992
|
||||
@pytest.mark.supported_targets
|
||||
@pytest.mark.generic
|
||||
@idf_parametrize('target', ['supported_targets'], indirect=['target'])
|
||||
def test_gdbstub_runtime(dut: PanicTestDut) -> None:
|
||||
dut.expect_exact('tested app is running.')
|
||||
dut.write(b'\x03') # send Ctrl-C
|
||||
@@ -73,7 +74,9 @@ def test_gdbstub_runtime(dut: PanicTestDut) -> None:
|
||||
# 4200ae5c: f99ff0ef jal ra,4200adf4 <foo>
|
||||
# 4200ae60: a011 j 4200ae64 <app_main+0x4e> <----------- here after return from foo()
|
||||
# }
|
||||
assert payload['frame']['line'] == str(get_line_number('label_3:', 1) if dut.is_xtensa else get_line_number('foo();', 0))
|
||||
assert payload['frame']['line'] == str(
|
||||
get_line_number('label_3:', 1) if dut.is_xtensa else get_line_number('foo();', 0)
|
||||
)
|
||||
assert payload['frame']['func'] == 'app_main'
|
||||
assert payload['stopped-threads'] == 'all'
|
||||
|
||||
@@ -155,11 +158,9 @@ def test_gdbstub_runtime(dut: PanicTestDut) -> None:
|
||||
assert payload['stopped-threads'] == 'all'
|
||||
|
||||
|
||||
@pytest.mark.esp32
|
||||
@pytest.mark.esp32s2
|
||||
@pytest.mark.esp32s3
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.temp_skip_ci(targets=['esp32', 'esp32s2', 'esp32s3'], reason='fix IDF-7927')
|
||||
@idf_parametrize('target', ['esp32', 'esp32s2', 'esp32s3'], indirect=['target'])
|
||||
def test_gdbstub_runtime_xtensa_stepping_bug(dut: PanicTestDut) -> None:
|
||||
dut.expect_exact('tested app is running.')
|
||||
dut.write(b'\x03') # send Ctrl-C
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
from pytest_embedded_idf.utils import idf_parametrize
|
||||
|
||||
|
||||
@pytest.mark.esp32
|
||||
@pytest.mark.esp32s2
|
||||
@pytest.mark.generic
|
||||
@idf_parametrize('target', ['esp32', 'esp32s2'], indirect=['target'])
|
||||
def test_sys_longjmp(dut: Dut) -> None:
|
||||
dut.expect_exact('Test successful')
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
import logging
|
||||
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
from pytest_embedded_idf.utils import idf_parametrize
|
||||
|
||||
MEM_TEST_UNICORE = {
|
||||
'esp32s2': [
|
||||
@@ -14,16 +14,12 @@ MEM_TEST_UNICORE = {
|
||||
['DRAM0_RTCFAST', 'WR'],
|
||||
['PERI1_RTCSLOW', 'WR'],
|
||||
['PERI2_RTCSLOW_0', 'WRX'],
|
||||
['PERI2_RTCSLOW_1', 'WRX']
|
||||
],
|
||||
'esp32c3': [
|
||||
['IRAM0_SRAM', 'WRX'],
|
||||
['DRAM0_SRAM', 'WR'],
|
||||
['IRAM0_RTCFAST', 'WRX']
|
||||
['PERI2_RTCSLOW_1', 'WRX'],
|
||||
],
|
||||
'esp32c3': [['IRAM0_SRAM', 'WRX'], ['DRAM0_SRAM', 'WR'], ['IRAM0_RTCFAST', 'WRX']],
|
||||
'esp32s3': [
|
||||
['IRAM0_SRAM (core 0)', 'WRX'],
|
||||
['DRAM0_SRAM (core 0)', 'WR']
|
||||
['DRAM0_SRAM (core 0)', 'WR'],
|
||||
# temporarily disabled unless IDF-5208 gets merged
|
||||
# ['IRAM0_RTCFAST', 'WR'],
|
||||
],
|
||||
@@ -38,19 +34,16 @@ MEM_TEST_MULTICORE = {
|
||||
# instruction execute test temporarily disabled
|
||||
# ['IRAM0_SRAM (core 1)', 'WRX'],
|
||||
['IRAM0_SRAM (core 1)', 'WR'],
|
||||
['DRAM0_SRAM (core 1)', 'WR']
|
||||
['DRAM0_SRAM (core 1)', 'WR'],
|
||||
# temporarily disabled unless IDF-5208 gets merged
|
||||
# ['IRAM0_RTCFAST', 'WR'],
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.esp32s2
|
||||
@pytest.mark.esp32s3
|
||||
@pytest.mark.esp32c3
|
||||
@pytest.mark.generic
|
||||
@idf_parametrize('target', ['esp32s2', 'esp32s3', 'esp32c3'], indirect=['target'])
|
||||
def test_sys_memprot(dut: Dut) -> None:
|
||||
|
||||
current_target = dut.target
|
||||
|
||||
unicore = dut.app.sdkconfig.get('FREERTOS_UNICORE')
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,23 +1,35 @@
|
||||
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
import pytest
|
||||
from pytest_embedded_idf.dut import IdfDut
|
||||
from pytest_embedded_idf.utils import idf_parametrize
|
||||
|
||||
|
||||
@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='esp32p4 support TBD') # TODO: IDF-8994
|
||||
@pytest.mark.supported_targets
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.parametrize('config', ['pure_ram',], indirect=True,)
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
[
|
||||
'pure_ram',
|
||||
],
|
||||
indirect=True,
|
||||
)
|
||||
@idf_parametrize('target', ['supported_targets'], indirect=['target'])
|
||||
def test_pure_ram_loadable_app(dut: IdfDut) -> None:
|
||||
dut.expect('main_task: Calling app_main()', timeout=10)
|
||||
dut.expect('Time since boot: 3 seconds...', timeout=10)
|
||||
|
||||
|
||||
@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='esp32p4 support TBD') # TODO: IDF-8994
|
||||
@pytest.mark.supported_targets
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.parametrize('config', ['defaults',], indirect=True,)
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
[
|
||||
'defaults',
|
||||
],
|
||||
indirect=True,
|
||||
)
|
||||
@idf_parametrize('target', ['supported_targets'], indirect=['target'])
|
||||
def test_ram_loadable_app(dut: IdfDut) -> None:
|
||||
dut.expect('spi_flash: detected chip', timeout=10)
|
||||
dut.expect('Time since boot: 3 seconds...', timeout=30)
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
from pytest_embedded_idf.utils import idf_parametrize
|
||||
|
||||
|
||||
@pytest.mark.esp32p4
|
||||
@pytest.mark.generic
|
||||
@idf_parametrize('target', ['esp32p4'], indirect=['target'])
|
||||
def test_rtc_mem_reserve(dut: Dut) -> None:
|
||||
dut.run_all_single_board_cases()
|
||||
|
||||
@@ -1,31 +1,39 @@
|
||||
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2022-2026 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
from pytest_embedded_idf.utils import idf_parametrize
|
||||
|
||||
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.parametrize('config', [
|
||||
pytest.param('flash_80m_qio', marks=[pytest.mark.supported_targets]),
|
||||
pytest.param('no_vfs', marks=[pytest.mark.supported_targets]),
|
||||
pytest.param('no_vfs_partial', marks=[pytest.mark.supported_targets]),
|
||||
pytest.param('opt_o0', marks=[pytest.mark.supported_targets]),
|
||||
pytest.param('opt_o2', marks=[pytest.mark.supported_targets]),
|
||||
pytest.param('stack_check_verbose_log', marks=[pytest.mark.supported_targets]),
|
||||
pytest.param('sram1_iram', marks=[pytest.mark.esp32]),
|
||||
pytest.param('main_task_cpu1', marks=[pytest.mark.esp32, pytest.mark.esp32s3]),
|
||||
], indirect=True)
|
||||
@idf_parametrize(
|
||||
'config,target',
|
||||
[
|
||||
('flash_80m_qio', 'supported_targets'),
|
||||
('no_vfs', 'supported_targets'),
|
||||
('no_vfs_partial', 'supported_targets'),
|
||||
('opt_o0', 'supported_targets'),
|
||||
('opt_o2', 'supported_targets'),
|
||||
('stack_check_verbose_log', 'supported_targets'),
|
||||
('sram1_iram', 'esp32'),
|
||||
('main_task_cpu1', 'esp32'),
|
||||
('main_task_cpu1', 'esp32s3'),
|
||||
],
|
||||
indirect=['config', 'target'],
|
||||
)
|
||||
def test_sys_startup(dut: Dut) -> None:
|
||||
dut.expect_exact('app_main running')
|
||||
|
||||
|
||||
@pytest.mark.esp32
|
||||
@pytest.mark.esp32s3
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.parametrize('config', [
|
||||
'single_core_variant',
|
||||
], indirect=True)
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
[
|
||||
'single_core_variant',
|
||||
],
|
||||
indirect=True,
|
||||
)
|
||||
@idf_parametrize('target', ['esp32', 'esp32s3'], indirect=['target'])
|
||||
def test_sys_startup_single_core_variant(dut: Dut) -> None:
|
||||
dut.expect('Running on single core variant of a chip, but app is built with multi-core support.')
|
||||
dut.expect(r'abort\(\) was called at PC [0-9xa-f]+ on core 0')
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
from pytest_embedded_idf.utils import idf_parametrize
|
||||
|
||||
|
||||
@pytest.mark.esp32
|
||||
@pytest.mark.esp32c3
|
||||
@pytest.mark.generic
|
||||
@idf_parametrize('target', ['esp32', 'esp32c3'], indirect=['target'])
|
||||
def test_watchpoint(dut: Dut) -> None:
|
||||
dut.expect_exact('stacks clean', timeout=3)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
import os
|
||||
import re
|
||||
@@ -7,13 +7,12 @@ import pytest
|
||||
from artifacts_handler import ArtifactType
|
||||
from idf_ci_utils import IDF_PATH
|
||||
from pytest_embedded import Dut
|
||||
from pytest_embedded_idf.utils import idf_parametrize
|
||||
|
||||
|
||||
@pytest.mark.esp32
|
||||
@pytest.mark.esp32s3
|
||||
@pytest.mark.esp32p4
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.parametrize('config', ['multicore', 'multicore_psram'], indirect=True)
|
||||
@idf_parametrize('target', ['esp32', 'esp32s3', 'esp32p4'], indirect=['target'])
|
||||
def test_multicore_app_and_unicore_bootloader(dut: Dut, app_downloader, config) -> None: # type: ignore
|
||||
dut.expect('Multicore bootloader')
|
||||
dut.expect('Multicore app')
|
||||
@@ -37,11 +36,9 @@ def test_multicore_app_and_unicore_bootloader(dut: Dut, app_downloader, config)
|
||||
dut.expect('NVS test done\n')
|
||||
|
||||
|
||||
@pytest.mark.esp32
|
||||
@pytest.mark.esp32s3
|
||||
@pytest.mark.esp32p4
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.parametrize('config', ['unicore', 'unicore_psram'], indirect=True)
|
||||
@idf_parametrize('target', ['esp32', 'esp32s3', 'esp32p4'], indirect=['target'])
|
||||
def test_unicore_app_and_multicore_bootloader(dut: Dut, app_downloader, config) -> None: # type: ignore
|
||||
dut.expect('Unicore bootloader')
|
||||
dut.expect('Unicore app')
|
||||
|
||||
Reference in New Issue
Block a user