test: format all test scripts

This commit is contained in:
igor.udot
2025-02-24 10:18:03 +08:00
parent 717c18a58e
commit daf2d31008
381 changed files with 6180 additions and 4289 deletions

View File

@@ -1,14 +1,15 @@
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Unlicense OR CC0-1.0
import logging
import os
import pytest
from pytest_embedded import Dut
from pytest_embedded_idf.utils import idf_parametrize
@pytest.mark.esp32
@pytest.mark.httpbin
@idf_parametrize('target', ['esp32'], indirect=['target'])
def test_examples_protocol_esp_http_client(dut: Dut) -> None:
"""
steps: |
@@ -56,11 +57,15 @@ def test_examples_protocol_esp_http_client(dut: Dut) -> None:
dut.expect('Finish http example')
@pytest.mark.esp32
@pytest.mark.httpbin
@pytest.mark.parametrize('config', [
'ssldyn',
], indirect=True)
@pytest.mark.parametrize(
'config',
[
'ssldyn',
],
indirect=True,
)
@idf_parametrize('target', ['esp32'], indirect=['target'])
def test_examples_protocol_esp_http_client_dynamic_buffer(dut: Dut) -> None:
# test mbedtls dynamic resource
# check and log bin size
@@ -103,13 +108,18 @@ def test_examples_protocol_esp_http_client_dynamic_buffer(dut: Dut) -> None:
dut.expect('Finish http example')
@pytest.mark.linux
@pytest.mark.host_test
# Currently we are just testing the build for esp_http_client on Linux target. So skipping the test run.
# Later we will enable the test run for Linux target as well.
@pytest.mark.skipif('config.getvalue("target") == "linux"', reason='Do not run on Linux')
@pytest.mark.parametrize('config', [
'default', 'ssldyn',
], indirect=True)
@pytest.mark.parametrize(
'config',
[
'default',
'ssldyn',
],
indirect=True,
)
@idf_parametrize('target', ['linux'], indirect=['target'])
def test_examples_protocol_esp_http_client_linux(dut: Dut) -> None:
dut.expect('Finish http example', timeout=60)

View File

@@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Unlicense OR CC0-1.0
import logging
import os
@@ -9,6 +9,7 @@ import pexpect
import pytest
from common_test_methods import get_env_config_variable
from pytest_embedded import Dut
from pytest_embedded_idf.utils import idf_parametrize
def get_sdk_path() -> str:
@@ -19,27 +20,24 @@ def get_sdk_path() -> str:
class CustomProcess(object):
def __init__(self, cmd: str, logfile: str, verbose:bool =True) -> None:
def __init__(self, cmd: str, logfile: str, verbose: bool = True) -> None:
self.verbose = verbose
self.f = open(logfile, 'w', encoding='utf-8')
if self.verbose:
logging.info('Starting {} > {}'.format(cmd, self.f.name))
self.pexpect_proc = pexpect.spawn(cmd, timeout=60, logfile=self.f, encoding='utf-8', codec_errors='ignore')
def __enter__(self): # type: ignore
def __enter__(self): # type: ignore
return self
def close(self) -> None:
self.pexpect_proc.terminate(force=True)
def __exit__(self, type, value, traceback): # type: ignore
def __exit__(self, type, value, traceback): # type: ignore
self.close()
self.f.close()
@pytest.mark.esp32
@pytest.mark.esp32c3
@pytest.mark.esp32s3
@pytest.mark.wifi_router
@pytest.mark.parametrize(
'config',
@@ -49,8 +47,8 @@ class CustomProcess(object):
],
indirect=True,
)
@idf_parametrize('target', ['esp32', 'esp32c3', 'esp32s3'], indirect=['target'])
def test_examples_esp_local_ctrl(config: str, dut: Dut) -> None:
rel_project_path = os.path.join('examples', 'protocols', 'esp_local_ctrl')
idf_path = get_sdk_path()
@@ -75,20 +73,28 @@ def test_examples_esp_local_ctrl(config: str, dut: Dut) -> None:
# Running mDNS services in docker is not a trivial task. Therefore, the script won't connect to the host name but
# to IP address. However, the certificates were generated for the host name and will be rejected.
if config == 'default':
cmd = ' '.join([sys.executable, os.path.join(idf_path, rel_project_path, 'scripts/esp_local_ctrl.py'),
'--sec_ver 2',
'--sec2_username wifiprov',
'--sec2_pwd abcd1234',
'--name', dut_ip,
'--dont-check-hostname']) # don't reject the certificate because of the hostname
cmd = ' '.join([
sys.executable,
os.path.join(idf_path, rel_project_path, 'scripts/esp_local_ctrl.py'),
'--sec_ver 2',
'--sec2_username wifiprov',
'--sec2_pwd abcd1234',
'--name',
dut_ip,
'--dont-check-hostname',
]) # don't reject the certificate because of the hostname
elif config == 'http':
cmd = ' '.join([sys.executable, os.path.join(idf_path, rel_project_path, 'scripts/esp_local_ctrl.py'),
'--sec_ver 2',
'--transport http',
'--sec2_username wifiprov',
'--sec2_pwd abcd1234',
'--name', dut_ip,
'--dont-check-hostname'])
cmd = ' '.join([
sys.executable,
os.path.join(idf_path, rel_project_path, 'scripts/esp_local_ctrl.py'),
'--sec_ver 2',
'--transport http',
'--sec2_username wifiprov',
'--sec2_pwd abcd1234',
'--name',
dut_ip,
'--dont-check-hostname',
])
esp_local_ctrl_log = os.path.join(idf_path, rel_project_path, 'esp_local_ctrl.log')
with CustomProcess(cmd, esp_local_ctrl_log) as ctrl_py:
@@ -100,7 +106,7 @@ def test_examples_esp_local_ctrl(config: str, dut: Dut) -> None:
ctrl_py.pexpect_proc.expect(re.compile(r'\[ 2\] property1\s+INT32\s+{}'.format(prop1)))
ctrl_py.pexpect_proc.expect(re.compile(r'\[ 3\] property2\s+BOOLEAN\s+Read-Only\s+(True)|(False)'))
ctrl_py.pexpect_proc.expect(re.compile(r'\[ 4\] property3\s+STRING\s+{}'.format(prop3)))
ctrl_py.pexpect_proc.expect_exact('Select properties to set (0 to re-read, \'q\' to quit) :')
ctrl_py.pexpect_proc.expect_exact("Select properties to set (0 to re-read, 'q' to quit) :")
property1 = 123456789
property3 = ''

View File

@@ -1,23 +1,23 @@
#!/usr/bin/env python
#
# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
import logging
import os
import pytest
from pytest_embedded import Dut
from pytest_embedded_idf.utils import idf_parametrize
@pytest.mark.esp32
@pytest.mark.ethernet
@idf_parametrize('target', ['esp32'], indirect=['target'])
def test_examples_protocol_http_request(dut: Dut) -> None:
"""
steps: |
1. join AP/Ethernet
2. connect to example.com
3. check conneciton success
3. check connection success
"""
# check and log bin size
binary_file = os.path.join(dut.app.binary_path, 'http_request.bin')

View File

@@ -1,15 +1,13 @@
#!/usr/bin/env python
#
# SPDX-FileCopyrightText: 2018-2022 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2018-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
from __future__ import division, print_function, unicode_literals
import logging
import os
import sys
import pytest
from pytest_embedded_idf.utils import idf_parametrize
try:
from idf_http_server_test import test as client
@@ -32,12 +30,9 @@ from pytest_embedded import Dut
# features to this component.
@pytest.mark.esp32
@pytest.mark.esp32c3
@pytest.mark.esp32s3
@pytest.mark.wifi_router
@idf_parametrize('target', ['esp32', 'esp32c3', 'esp32s3'], indirect=['target'])
def test_examples_protocol_http_server_advanced(dut: Dut) -> None:
# Get binary file
binary_file = os.path.join(dut.app.binary_path, 'tests.bin')
bin_size = os.path.getsize(binary_file)
@@ -57,9 +52,12 @@ def test_examples_protocol_http_server_advanced(dut: Dut) -> None:
got_port = dut.expect(r"(?:[\s\S]*)Started HTTP server on port: '(\d+)'", timeout=30)[1].decode()
result = dut.expect(r"(?:[\s\S]*)Max URI handlers: '(\d+)'(?:[\s\S]*)Max Open Sessions: " # noqa: W605
r"'(\d+)'(?:[\s\S]*)Max Header Length: '(\d+)'(?:[\s\S]*)Max URI Length: "
r"'(\d+)'(?:[\s\S]*)Max Stack Size: '(\d+)'", timeout=15)
result = dut.expect(
r"(?:[\s\S]*)Max URI handlers: '(\d+)'(?:[\s\S]*)Max Open Sessions: " # noqa: W605
r"'(\d+)'(?:[\s\S]*)Max Header Length: '(\d+)'(?:[\s\S]*)Max URI Length: "
r"'(\d+)'(?:[\s\S]*)Max Stack Size: '(\d+)'",
timeout=15,
)
# max_uri_handlers = int(result[1])
max_sessions = int(result[2])
max_hdr_len = int(result[3])

View File

@@ -7,10 +7,11 @@ import time
import pytest
from pytest_embedded import Dut
from pytest_embedded_idf.utils import idf_parametrize
@pytest.mark.esp32
@pytest.mark.ethernet
@idf_parametrize('target', ['esp32'], indirect=['target'])
def test_http_server_async_handler(dut: Dut) -> None:
# Get binary file
binary_file = os.path.join(dut.app.binary_path, 'simple.bin')

View File

@@ -1,10 +1,7 @@
#!/usr/bin/env python
#
# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
from __future__ import print_function
import http.client
import logging
import os
@@ -14,6 +11,7 @@ import sys
import pexpect
import pytest
from pytest_embedded import Dut
from pytest_embedded_idf.utils import idf_parametrize
try:
import wifi_tools
@@ -68,12 +66,11 @@ def test_captive_page(ip: str, port: str, uri: str) -> bool:
return True
@pytest.mark.esp32
@pytest.mark.wifi_wlan
@pytest.mark.temp_skip_ci(targets=['esp32'], reason='unstable case')
@pytest.mark.xfail(reason='Runner unable to connect to target over WiFi', run=False)
@idf_parametrize('target', ['esp32'], indirect=['target'])
def test_example_captive_portal(dut: Dut) -> None:
# Get binary file
binary_file = os.path.join(dut.app.binary_path, 'captive_portal.bin')
bin_size = os.path.getsize(binary_file)
@@ -103,7 +100,9 @@ def test_example_captive_portal(dut: Dut) -> None:
except RuntimeError as err:
logging.info('error: {}'.format(err))
try:
got_ip = dut.expect(r'DHCP server assigned IP to a station, IP is: (\d+.\d+.\d+.\d+)', timeout=60)[1].decode()
got_ip = dut.expect(r'DHCP server assigned IP to a station, IP is: (\d+.\d+.\d+.\d+)', timeout=60)[
1
].decode()
logging.info('got_ip: {}'.format(got_ip))
if ip != got_ip:
raise RuntimeError('SoftAP connected to another host! {} != {}'.format(ip, got_ip))

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
# SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
import hashlib
import http.client
@@ -9,6 +9,7 @@ import os
import sys
import pytest
from pytest_embedded_idf.utils import idf_parametrize
try:
from idf_http_server_test import adder as client
@@ -20,13 +21,16 @@ from common_test_methods import get_env_config_variable
from pytest_embedded import Dut
@pytest.mark.esp32
@pytest.mark.esp32c3
@pytest.mark.esp32s3
@pytest.mark.wifi_router
@pytest.mark.parametrize('config', ['spiffs',], indirect=True)
@pytest.mark.parametrize(
'config',
[
'spiffs',
],
indirect=True,
)
@idf_parametrize('target', ['esp32', 'esp32c3', 'esp32s3'], indirect=['target'])
def test_examples_protocol_http_server_file_serving(dut: Dut) -> None:
# Get binary file
binary_file = os.path.join(dut.app.binary_path, 'file_server.bin')
bin_size = os.path.getsize(binary_file)
@@ -73,7 +77,7 @@ def test_examples_protocol_http_server_file_serving(dut: Dut) -> None:
logging.info('Passed the test to uploaded file on the file server')
# Download the uploaded file from the file server
logging.info("\nTesting for Download of \"existing\" file from the file server")
logging.info('\nTesting for Download of "existing" file from the file server')
download_data = client.getreq(conn, '/' + str(upload_file_name))
@@ -91,7 +95,7 @@ def test_examples_protocol_http_server_file_serving(dut: Dut) -> None:
raise RuntimeError('The md5 hash of the downloaded file does not match with that of the uploaded file')
# Upload existing file on the file server
logging.info("\nTesting the upload of \"already existing\" file on the file server")
logging.info('\nTesting the upload of "already existing" file on the file server')
client.postreq(conn, '/upload/' + str(upload_file_name), data=None)
try:
dut.expect('File already exists : /data/' + str(upload_file_name), timeout=10)
@@ -112,7 +116,7 @@ def test_examples_protocol_http_server_file_serving(dut: Dut) -> None:
conn = client.start_session(got_ip, got_port)
# Delete the existing file from the file server
logging.info("\nTesting the deletion of \"existing\" file on the file server")
logging.info('\nTesting the deletion of "existing" file on the file server')
client.postreq(conn, '/delete/' + str(upload_file_name), data=None)
try:
dut.expect('Deleting file : /' + str(upload_file_name), timeout=10)
@@ -123,7 +127,7 @@ def test_examples_protocol_http_server_file_serving(dut: Dut) -> None:
conn = client.start_session(got_ip, got_port)
# Try to delete non existing file from the file server
logging.info("\nTesting the deletion of \"non existing\" file on the file server")
logging.info('\nTesting the deletion of "non existing" file on the file server')
client.postreq(conn, '/delete/' + str(upload_file_name), data=None)
try:
dut.expect('File does not exist : /' + str(upload_file_name), timeout=10)
@@ -134,7 +138,7 @@ def test_examples_protocol_http_server_file_serving(dut: Dut) -> None:
conn = client.start_session(got_ip, got_port)
# Try to download non existing file from the file server
logging.info("\nTesting for Download of \"non existing\" file from the file server")
logging.info('\nTesting for Download of "non existing" file from the file server')
download_data = client.getreq(conn, '/' + str(upload_file_name))

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
# SPDX-FileCopyrightText: 2018-2022 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2018-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
import logging
import os
@@ -8,6 +8,7 @@ import random
import sys
import pytest
from pytest_embedded_idf.utils import idf_parametrize
try:
from idf_http_server_test import adder as client
@@ -23,19 +24,16 @@ from pytest_embedded import Dut
# > make print_flash_cmd | tail -n 1 > build/download.config
@pytest.mark.esp32
@pytest.mark.esp32c3
@pytest.mark.esp32s3
@pytest.mark.wifi_router
@idf_parametrize('target', ['esp32', 'esp32c3', 'esp32s3'], indirect=['target'])
def test_examples_protocol_http_server_persistence(dut: Dut) -> None:
# Get binary file
binary_file = os.path.join(dut.app.binary_path, 'persistent_sockets.bin')
bin_size = os.path.getsize(binary_file)
logging.info('http_server_bin_size : {}KB'.format(bin_size // 1024))
# Upload binary and start testing
logging.info('Starting http_server persistance test app')
logging.info('Starting http_server persistence test app')
# Parse IP address of STA
logging.info('Waiting to connect with AP')
@@ -70,7 +68,7 @@ def test_examples_protocol_http_server_persistence(dut: Dut) -> None:
dut.expect('Logging out', timeout=30)
# Test PUT request and initialize session context
num = random.randint(0,100)
num = random.randint(0, 100)
client.putreq(conn, '/adder', str(num))
visitor += 1
dut.expect('/adder visitor count = ' + str(visitor), timeout=30)
@@ -78,7 +76,7 @@ def test_examples_protocol_http_server_persistence(dut: Dut) -> None:
dut.expect('PUT allocating new session', timeout=30)
# Retest PUT request and change session context value
num = random.randint(0,100)
num = random.randint(0, 100)
logging.info('Adding: {}'.format(num))
client.putreq(conn, '/adder', str(num))
visitor += 1
@@ -95,7 +93,7 @@ def test_examples_protocol_http_server_persistence(dut: Dut) -> None:
pass
# Test POST request and session persistence
random_nums = [random.randint(0,100) for _ in range(100)]
random_nums = [random.randint(0, 100) for _ in range(100)]
for num in random_nums:
logging.info('Adding: {}'.format(num))
client.postreq(conn, '/adder', str(num))
@@ -120,7 +118,7 @@ def test_examples_protocol_http_server_persistence(dut: Dut) -> None:
logging.info('Validating user context data')
# Start another session to check user context data
client.start_session(got_ip, got_port)
num = random.randint(0,100)
num = random.randint(0, 100)
client.putreq(conn, '/adder', str(num))
visitor += 1
dut.expect('/adder visitor count = ' + str(visitor), timeout=30)

View File

@@ -12,6 +12,7 @@ import threading
import time
import pytest
from pytest_embedded_idf.utils import idf_parametrize
try:
import http.client
@@ -45,18 +46,15 @@ class http_client_thread(threading.Thread):
except socket.timeout:
self.exc = 1
def join(self, timeout=None): # type: ignore
def join(self, timeout=None): # type: ignore
threading.Thread.join(self)
if self.exc:
raise socket.timeout
@pytest.mark.esp32
@pytest.mark.esp32c3
@pytest.mark.esp32s3
@pytest.mark.wifi_router
@idf_parametrize('target', ['esp32', 'esp32c3', 'esp32s3'], indirect=['target'])
def test_examples_protocol_http_server_simple(dut: Dut) -> None:
# Get binary file
binary_file = os.path.join(dut.app.binary_path, 'simple.bin')
bin_size = os.path.getsize(binary_file)
@@ -106,7 +104,7 @@ def test_examples_protocol_http_server_simple(dut: Dut) -> None:
dut.expect('Registering /hello and /echo URIs', timeout=30)
# Generate random data of 10KB
random_data = ''.join(string.printable[random.randint(0,len(string.printable)) - 1] for _ in range(10 * 1024))
random_data = ''.join(string.printable[random.randint(0, len(string.printable)) - 1] for _ in range(10 * 1024))
logging.info('Test /echo POST handler with random data')
if not client.test_post_handler(got_ip, got_port, random_data):
raise RuntimeError
@@ -116,7 +114,9 @@ def test_examples_protocol_http_server_simple(dut: Dut) -> None:
if not client.test_custom_uri_query(got_ip, got_port, queries):
raise RuntimeError
dut.expect_exact('Found URL query => query1=http%3A%2F%2Ffoobar&query3=abcd%2B1234%20xyz&query2=Esp%21%40%20%23%2471', timeout=30)
dut.expect_exact(
'Found URL query => query1=http%3A%2F%2Ffoobar&query3=abcd%2B1234%20xyz&query2=Esp%21%40%20%23%2471', timeout=30
)
dut.expect_exact('Found URL query parameter => query1=http%3A%2F%2Ffoobar', timeout=30)
dut.expect_exact('Decoded query parameter => http://foobar', timeout=30)
dut.expect_exact('Found URL query parameter => query3=abcd%2B1234%20xyz', timeout=30)
@@ -125,12 +125,9 @@ def test_examples_protocol_http_server_simple(dut: Dut) -> None:
dut.expect_exact('Decoded query parameter => Esp!@ #$71', timeout=30)
@pytest.mark.esp32
@pytest.mark.esp32c3
@pytest.mark.esp32s3
@pytest.mark.wifi_router
@idf_parametrize('target', ['esp32', 'esp32c3', 'esp32s3'], indirect=['target'])
def test_examples_protocol_http_server_lru_purge_enable(dut: Dut) -> None:
# Get binary file
binary_file = os.path.join(dut.app.binary_path, 'simple.bin')
bin_size = os.path.getsize(binary_file)
@@ -169,9 +166,15 @@ def test_examples_protocol_http_server_lru_purge_enable(dut: Dut) -> None:
t.join()
@pytest.mark.esp32
@pytest.mark.wifi_router
@pytest.mark.parametrize('config', ['sse',], indirect=True)
@pytest.mark.parametrize(
'config',
[
'sse',
],
indirect=True,
)
@idf_parametrize('target', ['esp32'], indirect=['target'])
def test_examples_protocol_http_server_sse(dut: Dut) -> None:
# Get binary file
binary_file = os.path.join(dut.app.binary_path, 'simple.bin')

View File

@@ -1,16 +1,14 @@
#!/usr/bin/env python
#
# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
from __future__ import division, print_function, unicode_literals
import logging
import os
import pytest
from common_test_methods import get_env_config_variable
from pytest_embedded import Dut
from pytest_embedded_idf.utils import idf_parametrize
try:
import websocket
@@ -21,7 +19,7 @@ except ImportError:
OPCODE_TEXT = 0x1
OPCODE_BIN = 0x2
OPCODE_PING = 0x9
OPCODE_PONG = 0xa
OPCODE_PONG = 0xA
class WsClient:
@@ -30,17 +28,17 @@ class WsClient:
self.ip = ip
self.ws = websocket.WebSocket()
def __enter__(self): # type: ignore
def __enter__(self): # type: ignore
self.ws.connect('ws://{}:{}/ws'.format(self.ip, self.port))
return self
def __exit__(self, exc_type, exc_value, traceback): # type: ignore
def __exit__(self, exc_type, exc_value, traceback): # type: ignore
self.ws.close()
def read(self): # type: ignore
def read(self): # type: ignore
return self.ws.recv_data(control_frame=True)
def write(self, data='', opcode=OPCODE_TEXT): # type: ignore
def write(self, data='', opcode=OPCODE_TEXT): # type: ignore
if opcode == OPCODE_BIN:
return self.ws.send_binary(data.encode())
if opcode == OPCODE_PING:
@@ -48,8 +46,8 @@ class WsClient:
return self.ws.send(data)
@pytest.mark.esp32
@pytest.mark.wifi_router
@idf_parametrize('target', ['esp32'], indirect=['target'])
def test_examples_protocol_http_ws_echo_server(dut: Dut) -> None:
# Get binary file
binary_file = os.path.join(dut.app.binary_path, 'ws_echo_server.bin')

View File

@@ -1,17 +1,17 @@
#!/usr/bin/env python
#
# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
import logging
import os
import pytest
from pytest_embedded import Dut
from pytest_embedded_idf.utils import idf_parametrize
@pytest.mark.esp32
@pytest.mark.ethernet
@idf_parametrize('target', ['esp32'], indirect=['target'])
def test_examples_protocol_https_mbedtls(dut: Dut) -> None:
"""
steps: |

View File

@@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Unlicense OR CC0-1.0
import http.server
import logging
@@ -13,13 +13,15 @@ import pytest
from common_test_methods import get_env_config_variable
from common_test_methods import get_host_ip4_by_dest_ip
from pytest_embedded import Dut
from pytest_embedded_idf.utils import idf_parametrize
from RangeHTTPServer import RangeRequestHandler
def https_request_handler() -> Callable[...,http.server.BaseHTTPRequestHandler]:
def https_request_handler() -> Callable[..., http.server.BaseHTTPRequestHandler]:
"""
Returns a request handler class that handles broken pipe exception
"""
class RequestHandler(RangeRequestHandler):
protocol_version = 'HTTP/1.1'
@@ -47,7 +49,6 @@ def https_request_handler() -> Callable[...,http.server.BaseHTTPRequestHandler]:
def start_https_server(server_file: str, key_file: str, server_ip: str, server_port: int) -> None:
requestHandler = https_request_handler()
httpd = http.server.HTTPServer((server_ip, server_port), requestHandler)
@@ -58,12 +59,18 @@ def start_https_server(server_file: str, key_file: str, server_ip: str, server_p
httpd.serve_forever()
@pytest.mark.esp32
@pytest.mark.ethernet
@pytest.mark.parametrize('config', ['cli_ses_tkt',], indirect=True)
@pytest.mark.parametrize(
'config',
[
'cli_ses_tkt',
],
indirect=True,
)
@pytest.mark.parametrize('erase_nvs', ['y'], indirect=True)
@idf_parametrize('target', ['esp32'], indirect=['target'])
def test_examples_protocol_https_request_cli_session_tickets(dut: Dut) -> None:
logging.info("Testing for \"esp_tls client session tickets\"")
logging.info('Testing for "esp_tls client session tickets"')
# check and log bin size
binary_file = os.path.join(dut.app.binary_path, 'https_request.bin')
@@ -90,38 +97,44 @@ def test_examples_protocol_https_request_cli_session_tickets(dut: Dut) -> None:
dut.expect('Start https_request example', timeout=30)
print('writing to device: {}'.format('https://' + host_ip + ':' + str(server_port)))
dut.write('https://' + host_ip + ':' + str(server_port))
logging.info("Testing for \"https_request using saved session\"")
logging.info('Testing for "https_request using saved session"')
# Check for connection using already saved client session
try:
dut.expect('https_request to local server', timeout=30)
dut.expect(['Connection established...',
'Reading HTTP response...',
'HTTP/1.1 200 OK',
'connection closed'], expect_all=True)
dut.expect(
['Connection established...', 'Reading HTTP response...', 'HTTP/1.1 200 OK', 'connection closed'],
expect_all=True,
)
except Exception:
logging.info("Failed to connect to local https server\"")
logging.info('Failed to connect to local https server"')
raise
try:
dut.expect('https_request using saved client session', timeout=20)
dut.expect(['Connection established...',
'Reading HTTP response...',
'HTTP/1.1 200 OK',
'connection closed'], expect_all=True)
dut.expect(
['Connection established...', 'Reading HTTP response...', 'HTTP/1.1 200 OK', 'connection closed'],
expect_all=True,
)
except Exception:
logging.info("Failed the test for \"https_request using saved client session\"")
logging.info('Failed the test for "https_request using saved client session"')
raise
logging.info("Passed the test for \"https_request using saved client session\"")
logging.info('Passed the test for "https_request using saved client session"')
finally:
thread1.terminate()
@pytest.mark.esp32
@pytest.mark.ethernet
@pytest.mark.parametrize('config', ['ssldyn',], indirect=True)
@pytest.mark.parametrize(
'config',
[
'ssldyn',
],
indirect=True,
)
@pytest.mark.parametrize('erase_nvs', ['y'], indirect=True)
@idf_parametrize('target', ['esp32'], indirect=['target'])
def test_examples_protocol_https_request_dynamic_buffers(dut: Dut) -> None:
# Check for connection using crt bundle with mbedtls dynamic resource enabled
# check and log bin size
@@ -137,24 +150,23 @@ def test_examples_protocol_https_request_dynamic_buffers(dut: Dut) -> None:
raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet')
# only check if one connection is established
logging.info("Testing for \"https_request using crt bundle\" with mbedtls dynamic resource enabled")
logging.info('Testing for "https_request using crt bundle" with mbedtls dynamic resource enabled')
try:
dut.expect('https_request using crt bundle', timeout=30)
dut.expect(['Connection established...',
'Reading HTTP response...',
'HTTP/1.1 200 OK',
'connection closed'], expect_all=True)
dut.expect(
['Connection established...', 'Reading HTTP response...', 'HTTP/1.1 200 OK', 'connection closed'],
expect_all=True,
)
except Exception:
logging.info("Failed the test for \"https_request using crt bundle\" when mbedtls dynamic resource was enabled")
logging.info('Failed the test for "https_request using crt bundle" when mbedtls dynamic resource was enabled')
raise
logging.info("Passed the test for \"https_request using crt bundle\" when mbedtls dynamic resource was enabled")
logging.info('Passed the test for "https_request using crt bundle" when mbedtls dynamic resource was enabled')
@pytest.mark.esp32
@pytest.mark.ethernet
@pytest.mark.parametrize('erase_nvs', ['y'], indirect=True)
@idf_parametrize('target', ['esp32'], indirect=['target'])
def test_examples_protocol_https_request(dut: Dut) -> None:
"""
steps: |
1. join AP
@@ -176,77 +188,84 @@ def test_examples_protocol_https_request(dut: Dut) -> None:
raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet')
# Check for connection using crt bundle
logging.info("Testing for \"https_request using crt bundle\"")
logging.info('Testing for "https_request using crt bundle"')
try:
dut.expect('https_request using crt bundle', timeout=30)
dut.expect(['Certificate validated',
'Connection established...',
'Reading HTTP response...',
'HTTP/1.1 200 OK',
'connection closed'], expect_all=True)
dut.expect(
[
'Certificate validated',
'Connection established...',
'Reading HTTP response...',
'HTTP/1.1 200 OK',
'connection closed',
],
expect_all=True,
)
except Exception:
logging.info("Failed the test for \"https_request using crt bundle\"")
logging.info('Failed the test for "https_request using crt bundle"')
raise
logging.info("Passed the test for \"https_request using crt bundle\"")
logging.info('Passed the test for "https_request using crt bundle"')
# Check for connection using cacert_buf
logging.info("Testing for \"https_request using cacert_buf\"")
logging.info('Testing for "https_request using cacert_buf"')
try:
dut.expect('https_request using cacert_buf', timeout=20)
dut.expect(['Connection established...',
'Reading HTTP response...',
'HTTP/1.1 200 OK',
'connection closed'], expect_all=True)
dut.expect(
['Connection established...', 'Reading HTTP response...', 'HTTP/1.1 200 OK', 'connection closed'],
expect_all=True,
)
except Exception:
logging.info("Passed the test for \"https_request using cacert_buf\"")
logging.info('Passed the test for "https_request using cacert_buf"')
raise
logging.info("Passed the test for \"https_request using cacert_buf\"")
logging.info('Passed the test for "https_request using cacert_buf"')
# Check for connection using global ca_store
logging.info("Testing for \"https_request using global ca_store\"")
logging.info('Testing for "https_request using global ca_store"')
try:
dut.expect('https_request using global ca_store', timeout=20)
dut.expect(['Connection established...',
'Reading HTTP response...',
'HTTP/1.1 200 OK',
'connection closed'], expect_all=True)
dut.expect(
['Connection established...', 'Reading HTTP response...', 'HTTP/1.1 200 OK', 'connection closed'],
expect_all=True,
)
except Exception:
logging.info("Failed the test for \"https_request using global ca_store\"")
logging.info('Failed the test for "https_request using global ca_store"')
raise
logging.info("Passed the test for \"https_request using global ca_store\"")
logging.info('Passed the test for "https_request using global ca_store"')
# Check for connection using specified server supported ciphersuites
logging.info("Testing for \"https_request using server supported ciphersuites\"")
logging.info('Testing for "https_request using server supported ciphersuites"')
try:
dut.expect('https_request using server supported ciphersuites', timeout=20)
dut.expect(['Connection established...',
'Reading HTTP response...',
'HTTP/1.1 200 OK',
'connection closed'], expect_all=True)
dut.expect(
['Connection established...', 'Reading HTTP response...', 'HTTP/1.1 200 OK', 'connection closed'],
expect_all=True,
)
except Exception:
logging.info("Failed the test for \"https_request using server supported ciphersuites\"")
logging.info('Failed the test for "https_request using server supported ciphersuites"')
raise
logging.info("Passed the test for \"https_request using server supported ciphersuites\"")
logging.info('Passed the test for "https_request using server supported ciphersuites"')
# Check for connection using specified server unsupported ciphersuites
logging.info("Testing for \"https_request using server unsupported ciphersuites\"")
logging.info('Testing for "https_request using server unsupported ciphersuites"')
try:
dut.expect('https_request using server unsupported ciphersuites', timeout=20)
dut.expect('Connection failed...', timeout=30)
except Exception:
logging.info("Failed the test for \"https_request using server unsupported ciphersuites\"")
logging.info('Failed the test for "https_request using server unsupported ciphersuites"')
raise
logging.info("Passed the test for \"https_request using server unsupported ciphersuites\"")
logging.info('Passed the test for "https_request using server unsupported ciphersuites"')
@pytest.mark.esp32c2
@pytest.mark.wifi_ap
@pytest.mark.xtal_26mhz
@pytest.mark.parametrize(
'config, baud', [
'config, baud',
[
('esp32c2_rom_mbedtls', '74880'),
], indirect=True
],
indirect=True,
)
@idf_parametrize('target', ['esp32c2'], indirect=['target'])
def test_examples_protocol_https_request_rom_impl(dut: Dut) -> None:
# Connect to AP
if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True:
@@ -268,64 +287,69 @@ def test_examples_protocol_https_request_rom_impl(dut: Dut) -> None:
raise ValueError('ENV_TEST_FAILURE: Cannot connect to AP/Ethernet')
# Check for connection using crt bundle
logging.info("Testing for \"https_request using crt bundle\"")
logging.info('Testing for "https_request using crt bundle"')
try:
dut.expect('https_request using crt bundle', timeout=30)
dut.expect(['Certificate validated',
'Connection established...',
'Reading HTTP response...',
'HTTP/1.1 200 OK',
'connection closed'], expect_all=True)
dut.expect(
[
'Certificate validated',
'Connection established...',
'Reading HTTP response...',
'HTTP/1.1 200 OK',
'connection closed',
],
expect_all=True,
)
except Exception:
logging.info("Failed the test for \"https_request using crt bundle\"")
logging.info('Failed the test for "https_request using crt bundle"')
raise
logging.info("Passed the test for \"https_request using crt bundle\"")
logging.info('Passed the test for "https_request using crt bundle"')
# Check for connection using cacert_buf
logging.info("Testing for \"https_request using cacert_buf\"")
logging.info('Testing for "https_request using cacert_buf"')
try:
dut.expect('https_request using cacert_buf', timeout=20)
dut.expect(['Connection established...',
'Reading HTTP response...',
'HTTP/1.1 200 OK',
'connection closed'], expect_all=True)
dut.expect(
['Connection established...', 'Reading HTTP response...', 'HTTP/1.1 200 OK', 'connection closed'],
expect_all=True,
)
except Exception:
logging.info("Passed the test for \"https_request using cacert_buf\"")
logging.info('Passed the test for "https_request using cacert_buf"')
raise
logging.info("Passed the test for \"https_request using cacert_buf\"")
logging.info('Passed the test for "https_request using cacert_buf"')
# Check for connection using global ca_store
logging.info("Testing for \"https_request using global ca_store\"")
logging.info('Testing for "https_request using global ca_store"')
try:
dut.expect('https_request using global ca_store', timeout=20)
dut.expect(['Connection established...',
'Reading HTTP response...',
'HTTP/1.1 200 OK',
'connection closed'], expect_all=True)
dut.expect(
['Connection established...', 'Reading HTTP response...', 'HTTP/1.1 200 OK', 'connection closed'],
expect_all=True,
)
except Exception:
logging.info("Failed the test for \"https_request using global ca_store\"")
logging.info('Failed the test for "https_request using global ca_store"')
raise
logging.info("Passed the test for \"https_request using global ca_store\"")
logging.info('Passed the test for "https_request using global ca_store"')
# Check for connection using specified server supported ciphersuites
logging.info("Testing for \"https_request using server supported ciphersuites\"")
logging.info('Testing for "https_request using server supported ciphersuites"')
try:
dut.expect('https_request using server supported ciphersuites', timeout=20)
dut.expect(['Connection established...',
'Reading HTTP response...',
'HTTP/1.1 200 OK',
'connection closed'], expect_all=True)
dut.expect(
['Connection established...', 'Reading HTTP response...', 'HTTP/1.1 200 OK', 'connection closed'],
expect_all=True,
)
except Exception:
logging.info("Failed the test for \"https_request using server supported ciphersuites\"")
logging.info('Failed the test for "https_request using server supported ciphersuites"')
raise
logging.info("Passed the test for \"https_request using server supported ciphersuites\"")
logging.info('Passed the test for "https_request using server supported ciphersuites"')
# Check for connection using specified server unsupported ciphersuites
logging.info("Testing for \"https_request using server unsupported ciphersuites\"")
logging.info('Testing for "https_request using server unsupported ciphersuites"')
try:
dut.expect('https_request using server unsupported ciphersuites', timeout=20)
dut.expect('Connection failed...', timeout=30)
except Exception:
logging.info("Failed the test for \"https_request using server unsupported ciphersuites\"")
logging.info('Failed the test for "https_request using server unsupported ciphersuites"')
raise
logging.info("Passed the test for \"https_request using server unsupported ciphersuites\"")
logging.info('Passed the test for "https_request using server unsupported ciphersuites"')

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
# SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
import http.client
import logging
@@ -10,89 +10,94 @@ import ssl
import pytest
from common_test_methods import get_env_config_variable
from pytest_embedded import Dut
from pytest_embedded_idf.utils import idf_parametrize
server_cert_pem = '-----BEGIN CERTIFICATE-----\n'\
'MIIDKzCCAhOgAwIBAgIUBxM3WJf2bP12kAfqhmhhjZWv0ukwDQYJKoZIhvcNAQEL\n'\
'BQAwJTEjMCEGA1UEAwwaRVNQMzIgSFRUUFMgc2VydmVyIGV4YW1wbGUwHhcNMTgx\n'\
'MDE3MTEzMjU3WhcNMjgxMDE0MTEzMjU3WjAlMSMwIQYDVQQDDBpFU1AzMiBIVFRQ\n'\
'UyBzZXJ2ZXIgZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\n'\
'ALBint6nP77RCQcmKgwPtTsGK0uClxg+LwKJ3WXuye3oqnnjqJCwMEneXzGdG09T\n'\
'sA0SyNPwrEgebLCH80an3gWU4pHDdqGHfJQa2jBL290e/5L5MB+6PTs2NKcojK/k\n'\
'qcZkn58MWXhDW1NpAnJtjVniK2Ksvr/YIYSbyD+JiEs0MGxEx+kOl9d7hRHJaIzd\n'\
'GF/vO2pl295v1qXekAlkgNMtYIVAjUy9CMpqaQBCQRL+BmPSJRkXBsYk8GPnieS4\n'\
'sUsp53DsNvCCtWDT6fd9D1v+BB6nDk/FCPKhtjYOwOAZlX4wWNSZpRNr5dfrxKsb\n'\
'jAn4PCuR2akdF4G8WLUeDWECAwEAAaNTMFEwHQYDVR0OBBYEFMnmdJKOEepXrHI/\n'\
'ivM6mVqJgAX8MB8GA1UdIwQYMBaAFMnmdJKOEepXrHI/ivM6mVqJgAX8MA8GA1Ud\n'\
'EwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBADiXIGEkSsN0SLSfCF1VNWO3\n'\
'emBurfOcDq4EGEaxRKAU0814VEmU87btIDx80+z5Dbf+GGHCPrY7odIkxGNn0DJY\n'\
'W1WcF+DOcbiWoUN6DTkAML0SMnp8aGj9ffx3x+qoggT+vGdWVVA4pgwqZT7Ybntx\n'\
'bkzcNFW0sqmCv4IN1t4w6L0A87ZwsNwVpre/j6uyBw7s8YoJHDLRFT6g7qgn0tcN\n'\
'ZufhNISvgWCVJQy/SZjNBHSpnIdCUSJAeTY2mkM4sGxY0Widk8LnjydxZUSxC3Nl\n'\
'hb6pnMh3jRq4h0+5CZielA4/a+TdrNPv/qok67ot/XJdY3qHCCd8O2b14OVq9jo=\n'\
'-----END CERTIFICATE-----\n'
server_cert_pem = (
'-----BEGIN CERTIFICATE-----\n'
'MIIDKzCCAhOgAwIBAgIUBxM3WJf2bP12kAfqhmhhjZWv0ukwDQYJKoZIhvcNAQEL\n'
'BQAwJTEjMCEGA1UEAwwaRVNQMzIgSFRUUFMgc2VydmVyIGV4YW1wbGUwHhcNMTgx\n'
'MDE3MTEzMjU3WhcNMjgxMDE0MTEzMjU3WjAlMSMwIQYDVQQDDBpFU1AzMiBIVFRQ\n'
'UyBzZXJ2ZXIgZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\n'
'ALBint6nP77RCQcmKgwPtTsGK0uClxg+LwKJ3WXuye3oqnnjqJCwMEneXzGdG09T\n'
'sA0SyNPwrEgebLCH80an3gWU4pHDdqGHfJQa2jBL290e/5L5MB+6PTs2NKcojK/k\n'
'qcZkn58MWXhDW1NpAnJtjVniK2Ksvr/YIYSbyD+JiEs0MGxEx+kOl9d7hRHJaIzd\n'
'GF/vO2pl295v1qXekAlkgNMtYIVAjUy9CMpqaQBCQRL+BmPSJRkXBsYk8GPnieS4\n'
'sUsp53DsNvCCtWDT6fd9D1v+BB6nDk/FCPKhtjYOwOAZlX4wWNSZpRNr5dfrxKsb\n'
'jAn4PCuR2akdF4G8WLUeDWECAwEAAaNTMFEwHQYDVR0OBBYEFMnmdJKOEepXrHI/\n'
'ivM6mVqJgAX8MB8GA1UdIwQYMBaAFMnmdJKOEepXrHI/ivM6mVqJgAX8MA8GA1Ud\n'
'EwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBADiXIGEkSsN0SLSfCF1VNWO3\n'
'emBurfOcDq4EGEaxRKAU0814VEmU87btIDx80+z5Dbf+GGHCPrY7odIkxGNn0DJY\n'
'W1WcF+DOcbiWoUN6DTkAML0SMnp8aGj9ffx3x+qoggT+vGdWVVA4pgwqZT7Ybntx\n'
'bkzcNFW0sqmCv4IN1t4w6L0A87ZwsNwVpre/j6uyBw7s8YoJHDLRFT6g7qgn0tcN\n'
'ZufhNISvgWCVJQy/SZjNBHSpnIdCUSJAeTY2mkM4sGxY0Widk8LnjydxZUSxC3Nl\n'
'hb6pnMh3jRq4h0+5CZielA4/a+TdrNPv/qok67ot/XJdY3qHCCd8O2b14OVq9jo=\n'
'-----END CERTIFICATE-----\n'
)
client_cert_pem = '-----BEGIN CERTIFICATE-----\n' \
'MIID7TCCAtWgAwIBAgIUBdm7RStsshnl3CCpknSJhXQK4GcwDQYJKoZIhvcNAQEL\n' \
'BQAwgYUxCzAJBgNVBAYTAkNOMRAwDgYDVQQIDAdKaWFuZ3N1MQ8wDQYDVQQHDAZT\n' \
'dXpob3UxEjAQBgNVBAoMCUVzcHJlc3NpZjEMMAoGA1UECwwDY29tMRIwEAYDVQQD\n' \
'DAkxMjcuMC4wLjExHTAbBgkqhkiG9w0BCQEWDmVzcDMyeEBlc3AuY29tMB4XDTIx\n' \
'MTAwNTExMTMxMFoXDTMxMTAwMzExMTMxMFowgYUxCzAJBgNVBAYTAkNOMRAwDgYD\n' \
'VQQIDAdKaWFuZ3N1MQ8wDQYDVQQHDAZTdXpob3UxEjAQBgNVBAoMCUVzcHJlc3Np\n' \
'ZjEMMAoGA1UECwwDY29tMRIwEAYDVQQDDAkxMjcuMC4wLjExHTAbBgkqhkiG9w0B\n' \
'CQEWDmVzcDMyeEBlc3AuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC\n' \
'AQEAu2nP0HPtgKvRUwFuOs72caf4oyeK33OVfa6fGGttr/QYyw9PrwtdFDyEWEiI\n' \
'4P4hnxNC+bvNSYtJUzF9EmkqrUtKxhBsRVTKWOqumcgtiMWOxpdVKl0936ne2Pqh\n' \
'SweddrQwvPDFuB3hRikRX11+d5vkjFBV9FoZobKHWemDkXSc2R99xRie5PJoEfoz\n' \
'rmu5zjCaPHxzkyZsmH4MILfTuhUGc/Eye9Nl+lpY5KLjM14ZMQLK1CHRuI/oqCN6\n' \
'1WQrgUY5EyXGe0jXHTVhlL2RN8njxJ/4r3JnK/BQkcXTIMPOP8jIv9Sy1HhxfXKy\n' \
'HzLqOBn0Ft+mOADrpAWX8WnwUQIDAQABo1MwUTAdBgNVHQ4EFgQUpu4d8d+IywjB\n' \
'HMiKX84L+1ri8BIwHwYDVR0jBBgwFoAUpu4d8d+IywjBHMiKX84L+1ri8BIwDwYD\n' \
'VR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAXm5Hn/aKKO3RnHqqfxok\n' \
'Hbw5yA2L2T6VPj2puI0Sh5GW62INjM0Kszy3L5mQqLUSsjcEcFAZmpeo14ytPRLG\n' \
'o6+WG/4er3hBA7D8oDni7hp8Qs+/EtNuEuoU+qQiKsT2DvA5rafT7laNfvjgqaoJ\n' \
'YMTCvzKLnMBaglB+qC9grgvJwMN0RTzHyY6UySdNZmcf5QXWLWjsX8E8/u4iSq8l\n' \
'eZlddTjh7HGGEOim7AkvKR9VYAvKGOV+FvUzCxPpoTr6kS2NGwnR7QnvKADECtLj\n' \
'gf+hW1FalMn0yTVspg4+BNbIThh0thbsvPDUTekMNfaRKKHZpJP2Ty3LkCbANLBR\n' \
'tQ==\n' \
'-----END CERTIFICATE-----\n'
client_cert_pem = (
'-----BEGIN CERTIFICATE-----\n'
'MIID7TCCAtWgAwIBAgIUBdm7RStsshnl3CCpknSJhXQK4GcwDQYJKoZIhvcNAQEL\n'
'BQAwgYUxCzAJBgNVBAYTAkNOMRAwDgYDVQQIDAdKaWFuZ3N1MQ8wDQYDVQQHDAZT\n'
'dXpob3UxEjAQBgNVBAoMCUVzcHJlc3NpZjEMMAoGA1UECwwDY29tMRIwEAYDVQQD\n'
'DAkxMjcuMC4wLjExHTAbBgkqhkiG9w0BCQEWDmVzcDMyeEBlc3AuY29tMB4XDTIx\n'
'MTAwNTExMTMxMFoXDTMxMTAwMzExMTMxMFowgYUxCzAJBgNVBAYTAkNOMRAwDgYD\n'
'VQQIDAdKaWFuZ3N1MQ8wDQYDVQQHDAZTdXpob3UxEjAQBgNVBAoMCUVzcHJlc3Np\n'
'ZjEMMAoGA1UECwwDY29tMRIwEAYDVQQDDAkxMjcuMC4wLjExHTAbBgkqhkiG9w0B\n'
'CQEWDmVzcDMyeEBlc3AuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC\n'
'AQEAu2nP0HPtgKvRUwFuOs72caf4oyeK33OVfa6fGGttr/QYyw9PrwtdFDyEWEiI\n'
'4P4hnxNC+bvNSYtJUzF9EmkqrUtKxhBsRVTKWOqumcgtiMWOxpdVKl0936ne2Pqh\n'
'SweddrQwvPDFuB3hRikRX11+d5vkjFBV9FoZobKHWemDkXSc2R99xRie5PJoEfoz\n'
'rmu5zjCaPHxzkyZsmH4MILfTuhUGc/Eye9Nl+lpY5KLjM14ZMQLK1CHRuI/oqCN6\n'
'1WQrgUY5EyXGe0jXHTVhlL2RN8njxJ/4r3JnK/BQkcXTIMPOP8jIv9Sy1HhxfXKy\n'
'HzLqOBn0Ft+mOADrpAWX8WnwUQIDAQABo1MwUTAdBgNVHQ4EFgQUpu4d8d+IywjB\n'
'HMiKX84L+1ri8BIwHwYDVR0jBBgwFoAUpu4d8d+IywjBHMiKX84L+1ri8BIwDwYD\n'
'VR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAXm5Hn/aKKO3RnHqqfxok\n'
'Hbw5yA2L2T6VPj2puI0Sh5GW62INjM0Kszy3L5mQqLUSsjcEcFAZmpeo14ytPRLG\n'
'o6+WG/4er3hBA7D8oDni7hp8Qs+/EtNuEuoU+qQiKsT2DvA5rafT7laNfvjgqaoJ\n'
'YMTCvzKLnMBaglB+qC9grgvJwMN0RTzHyY6UySdNZmcf5QXWLWjsX8E8/u4iSq8l\n'
'eZlddTjh7HGGEOim7AkvKR9VYAvKGOV+FvUzCxPpoTr6kS2NGwnR7QnvKADECtLj\n'
'gf+hW1FalMn0yTVspg4+BNbIThh0thbsvPDUTekMNfaRKKHZpJP2Ty3LkCbANLBR\n'
'tQ==\n'
'-----END CERTIFICATE-----\n'
)
client_key_pem = '-----BEGIN PRIVATE KEY-----\n' \
'MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC7ac/Qc+2Aq9FT\n' \
'AW46zvZxp/ijJ4rfc5V9rp8Ya22v9BjLD0+vC10UPIRYSIjg/iGfE0L5u81Ji0lT\n' \
'MX0SaSqtS0rGEGxFVMpY6q6ZyC2IxY7Gl1UqXT3fqd7Y+qFLB512tDC88MW4HeFG\n' \
'KRFfXX53m+SMUFX0WhmhsodZ6YORdJzZH33FGJ7k8mgR+jOua7nOMJo8fHOTJmyY\n' \
'fgwgt9O6FQZz8TJ702X6WljkouMzXhkxAsrUIdG4j+ioI3rVZCuBRjkTJcZ7SNcd\n' \
'NWGUvZE3yePEn/ivcmcr8FCRxdMgw84/yMi/1LLUeHF9crIfMuo4GfQW36Y4AOuk\n' \
'BZfxafBRAgMBAAECggEBAJuJZ1UCwRtGfUS8LTVVSiZtVuZhDNoB3REfeR4VGkUq\n' \
'+eCcZm9JqQgAaX2zRRYlEtYocC8+c1MT69jFe51p9mc302ipfJHVmtFMg3dRMKkP\n' \
'/DxIn/+2voD/Q9kjt/TC7yXyyXglApKZCbrmnmpc93ZgxL7GdW+Dzz3pIne2WuC9\n' \
'T6ie71R8X60sau6ApMgkUq6On0f21v/VLkNU67tQJGBF6Q1HE8PK7Ptun3WSBVNm\n' \
'FNNJKRBwiqfWXe9hPlqqCWayYBrojSqJJXn5Xd6n5XzLDPzAXuPlkPF3VwWeXGam\n' \
'3RBZA26gwv50E1PeiUQOipkR57J+O9j/oA07AnhsxPkCgYEA8RMvE3ImZTkPVqdX\n' \
'72E2A5ScJswVvZelnRS/mG8U+8UlvevAu5MYr717DHKHy3yOw/u7wbkqk6KEIcyz\n' \
'ctNPBPqTweaZ28eEY/+lXSdQaWLD2UgZC8JIcMOSeFugghEHeBaxLzUYBNDToE3q\n' \
'1El2HJ7W14QuTA+CEtCEb+tc7ssCgYEAxwQkBTT8A7mOEE0phfUACqaBuAXld+zu\n' \
'I3PNJDIhg1ZABEJ9vo9+3duFDoEHVsJOetijrBBxf/XAvi3bTJ+gAjcA54cGpkxz\n' \
'6ssbFWZeC9exyo0ILKn33o716GrCvQn1kmuF2gasmAcrOVsMygawR7P02oasDP/X\n' \
'UckbZdqofdMCgYEAom0GfteePv0e9Idzm/mnZuot+4Xt7/vIvflIze+p96hxMXEy\n' \
'Pi9xppbH3S8dh2C44Bsv+epEYYxR8mP1VBxDVVtvSmmQqJ/Y93c7d3QRna/JvQ/y\n' \
'sBWKsU9T1HwHvRq0KZlAcEoZkMUSkSNuYPHN/qKWpkaM2vpn7T1Ivg+aYdkCgYA/\n' \
'CGO0NnzfXSTOqvHM2LVDqksJkuyD2Enwdpvxq+MLawTplHmpIl/HOuDgoCNH6lDa\n' \
'/cSRGcApDBgY5ANCOIiASxWBPzXu8+X+5odUdtCwpYdNJPAC3W6BUfw2uaGmKAJc\n' \
'dqu1S0nc+OBK0Tiyv/2TKD8T+3WAxINZBv4je2bEOwKBgEavm5zTN9NILJsJCf9k\n' \
'te7+uDFuyoNWkL1vmMPuJYVC1QMVq1yr3DSaxA19BG9P4ZyOMOwVlPVWA+LofD4D\n' \
'S+w4Jjl2KDI4tSLUr6bsAJWdDfmrmGmRN3Kpds4RXaymV3rjj7qRk1J+ivtwo89s\n' \
'Vj+VslYzxw7FKKmnBgh/qGbJ\n' \
'-----END PRIVATE KEY-----\n'
client_key_pem = (
'-----BEGIN PRIVATE KEY-----\n'
'MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC7ac/Qc+2Aq9FT\n'
'AW46zvZxp/ijJ4rfc5V9rp8Ya22v9BjLD0+vC10UPIRYSIjg/iGfE0L5u81Ji0lT\n'
'MX0SaSqtS0rGEGxFVMpY6q6ZyC2IxY7Gl1UqXT3fqd7Y+qFLB512tDC88MW4HeFG\n'
'KRFfXX53m+SMUFX0WhmhsodZ6YORdJzZH33FGJ7k8mgR+jOua7nOMJo8fHOTJmyY\n'
'fgwgt9O6FQZz8TJ702X6WljkouMzXhkxAsrUIdG4j+ioI3rVZCuBRjkTJcZ7SNcd\n'
'NWGUvZE3yePEn/ivcmcr8FCRxdMgw84/yMi/1LLUeHF9crIfMuo4GfQW36Y4AOuk\n'
'BZfxafBRAgMBAAECggEBAJuJZ1UCwRtGfUS8LTVVSiZtVuZhDNoB3REfeR4VGkUq\n'
'+eCcZm9JqQgAaX2zRRYlEtYocC8+c1MT69jFe51p9mc302ipfJHVmtFMg3dRMKkP\n'
'/DxIn/+2voD/Q9kjt/TC7yXyyXglApKZCbrmnmpc93ZgxL7GdW+Dzz3pIne2WuC9\n'
'T6ie71R8X60sau6ApMgkUq6On0f21v/VLkNU67tQJGBF6Q1HE8PK7Ptun3WSBVNm\n'
'FNNJKRBwiqfWXe9hPlqqCWayYBrojSqJJXn5Xd6n5XzLDPzAXuPlkPF3VwWeXGam\n'
'3RBZA26gwv50E1PeiUQOipkR57J+O9j/oA07AnhsxPkCgYEA8RMvE3ImZTkPVqdX\n'
'72E2A5ScJswVvZelnRS/mG8U+8UlvevAu5MYr717DHKHy3yOw/u7wbkqk6KEIcyz\n'
'ctNPBPqTweaZ28eEY/+lXSdQaWLD2UgZC8JIcMOSeFugghEHeBaxLzUYBNDToE3q\n'
'1El2HJ7W14QuTA+CEtCEb+tc7ssCgYEAxwQkBTT8A7mOEE0phfUACqaBuAXld+zu\n'
'I3PNJDIhg1ZABEJ9vo9+3duFDoEHVsJOetijrBBxf/XAvi3bTJ+gAjcA54cGpkxz\n'
'6ssbFWZeC9exyo0ILKn33o716GrCvQn1kmuF2gasmAcrOVsMygawR7P02oasDP/X\n'
'UckbZdqofdMCgYEAom0GfteePv0e9Idzm/mnZuot+4Xt7/vIvflIze+p96hxMXEy\n'
'Pi9xppbH3S8dh2C44Bsv+epEYYxR8mP1VBxDVVtvSmmQqJ/Y93c7d3QRna/JvQ/y\n'
'sBWKsU9T1HwHvRq0KZlAcEoZkMUSkSNuYPHN/qKWpkaM2vpn7T1Ivg+aYdkCgYA/\n'
'CGO0NnzfXSTOqvHM2LVDqksJkuyD2Enwdpvxq+MLawTplHmpIl/HOuDgoCNH6lDa\n'
'/cSRGcApDBgY5ANCOIiASxWBPzXu8+X+5odUdtCwpYdNJPAC3W6BUfw2uaGmKAJc\n'
'dqu1S0nc+OBK0Tiyv/2TKD8T+3WAxINZBv4je2bEOwKBgEavm5zTN9NILJsJCf9k\n'
'te7+uDFuyoNWkL1vmMPuJYVC1QMVq1yr3DSaxA19BG9P4ZyOMOwVlPVWA+LofD4D\n'
'S+w4Jjl2KDI4tSLUr6bsAJWdDfmrmGmRN3Kpds4RXaymV3rjj7qRk1J+ivtwo89s\n'
'Vj+VslYzxw7FKKmnBgh/qGbJ\n'
'-----END PRIVATE KEY-----\n'
)
success_response = '<h1>Hello Secure World!</h1>'
@pytest.mark.esp32
@pytest.mark.esp32c3
@pytest.mark.esp32s3
@pytest.mark.wifi_router
@idf_parametrize('target', ['esp32', 'esp32c3', 'esp32s3'], indirect=['target'])
def test_examples_protocol_https_server_simple(dut: Dut) -> None:
"""
steps: |
@@ -140,7 +145,7 @@ def test_examples_protocol_https_server_simple(dut: Dut) -> None:
conn = http.client.HTTPSConnection(got_ip, got_port, context=ssl_context)
logging.info('Performing SSL handshake with the server')
conn.request('GET','/')
conn.request('GET', '/')
resp = conn.getresponse()
dut.expect('performing session handshake')
got_resp = resp.read().decode('utf-8')
@@ -156,7 +161,9 @@ def test_examples_protocol_https_server_simple(dut: Dut) -> None:
serial_number = dut.expect(r'serial number\s*:([^\n]*)', timeout=5)[0]
issuer_name = dut.expect(r'issuer name\s*:([^\n]*)', timeout=5)[0]
expiry = dut.expect(r'expires on ((.*)\d{4}\-(0?[1-9]|1[012])\-(0?[1-9]|[12][0-9]|3[01])*)', timeout=5)[1].decode()
expiry = dut.expect(r'expires on ((.*)\d{4}\-(0?[1-9]|1[012])\-(0?[1-9]|[12][0-9]|3[01])*)', timeout=5)[
1
].decode()
logging.info('Serial No. {}'.format(serial_number))
logging.info('Issuer Name {}'.format(issuer_name))
@@ -168,11 +175,15 @@ def test_examples_protocol_https_server_simple(dut: Dut) -> None:
logging.info('SSL connection test successful\nClosing the connection')
@pytest.mark.esp32
@pytest.mark.esp32c3
@pytest.mark.esp32s3
@pytest.mark.wifi_router
@pytest.mark.parametrize('config', ['dynamic_buffer',], indirect=True)
@pytest.mark.parametrize(
'config',
[
'dynamic_buffer',
],
indirect=True,
)
@idf_parametrize('target', ['esp32', 'esp32c3', 'esp32s3'], indirect=['target'])
def test_examples_protocol_https_server_simple_dynamic_buffers(dut: Dut) -> None:
# Test with mbedTLS dynamic buffer feature
@@ -211,7 +222,7 @@ def test_examples_protocol_https_server_simple_dynamic_buffers(dut: Dut) -> None
conn = http.client.HTTPSConnection(got_ip, got_port, context=ssl_context)
logging.info('Performing SSL handshake with the server')
conn.request('GET','/')
conn.request('GET', '/')
resp = conn.getresponse()
dut.expect('performing session handshake')
got_resp = resp.read().decode('utf-8')
@@ -227,7 +238,9 @@ def test_examples_protocol_https_server_simple_dynamic_buffers(dut: Dut) -> None
serial_number = dut.expect(r'serial number\s*:([^\n]*)', timeout=5)[0]
issuer_name = dut.expect(r'issuer name\s*:([^\n]*)', timeout=5)[0]
expiry = dut.expect(r'expires on\s*:((.*)\d{4}\-(0?[1-9]|1[012])\-(0?[1-9]|[12][0-9]|3[01])*)', timeout=5)[1].decode()
expiry = dut.expect(r'expires on\s*:((.*)\d{4}\-(0?[1-9]|1[012])\-(0?[1-9]|[12][0-9]|3[01])*)', timeout=5)[
1
].decode()
logging.info('Serial No. : {}'.format(serial_number))
logging.info('Issuer Name : {}'.format(issuer_name))

View File

@@ -1,26 +1,25 @@
#!/usr/bin/env python
#
# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
from __future__ import division, print_function, unicode_literals
import logging
import os
import threading
import time
from types import TracebackType
from typing import Any, Optional
from typing import Any
from typing import Optional
import pytest
import websocket
from common_test_methods import get_env_config_variable
from pytest_embedded import Dut
from pytest_embedded_idf.utils import idf_parametrize
OPCODE_TEXT = 0x1
OPCODE_BIN = 0x2
OPCODE_PING = 0x9
OPCODE_PONG = 0xa
OPCODE_PONG = 0xA
CORRECT_ASYNC_DATA = 'Hello client'
@@ -28,9 +27,9 @@ class WsClient:
def __init__(self, ip, port, ca_file): # type: (str, int, str) -> None
self.port = port
self.ip = ip
sslopt = {'ca_certs':ca_file, 'check_hostname': False}
sslopt = {'ca_certs': ca_file, 'check_hostname': False}
self.ws = websocket.WebSocket(sslopt=sslopt)
# Set timeout to 10 seconds to avoid conection failure at the time of handshake
# Set timeout to 10 seconds to avoid connection failure at the time of handshake
self.ws.settimeout(10)
def __enter__(self): # type: ignore
@@ -106,10 +105,9 @@ def test_multiple_client_keep_alive_and_async_response(ip, port, ca_file): # ty
t.join()
@pytest.mark.esp32
@pytest.mark.wifi_router
@idf_parametrize('target', ['esp32'], indirect=['target'])
def test_examples_protocol_https_wss_server(dut: Dut) -> None:
# Get binary file
binary_file = os.path.join(dut.app.binary_path, 'wss_server.bin')
bin_size = os.path.getsize(binary_file)
@@ -172,8 +170,10 @@ def test_examples_protocol_https_wss_server(dut: Dut) -> None:
logging.info('Failed the test for keep alive,\nthe client got abruptly disconnected')
raise
# keepalive timeout is 10 seconds so do not respond for (10 + 1) senconds
logging.info('Testing if client is disconnected if it does not respond for 10s i.e. keep_alive timeout (approx time = 11s)')
# keepalive timeout is 10 seconds so do not respond for (10 + 1) seconds
logging.info(
'Testing if client is disconnected if it does not respond for 10s i.e. keep_alive timeout (approx time = 11s)'
)
try:
dut.expect('Client not alive, closing fd {}'.format(client_fd), timeout=20)
dut.expect('Client disconnected {}'.format(client_fd))

View File

@@ -1,14 +1,15 @@
# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Unlicense OR CC0-1.0
import logging
import os
import pytest
from pytest_embedded import Dut
from pytest_embedded_idf.utils import idf_parametrize
@pytest.mark.esp32
@pytest.mark.ethernet
@idf_parametrize('target', ['esp32'], indirect=['target'])
def test_examples_protocol_https_x509_bundle(dut: Dut) -> None:
"""
steps: |
@@ -28,9 +29,15 @@ def test_examples_protocol_https_x509_bundle(dut: Dut) -> None:
dut.expect('Completed {} connections'.format(num_URLS), timeout=60)
@pytest.mark.esp32
@pytest.mark.ethernet
@pytest.mark.parametrize('config', ['ssldyn',], indirect=True)
@pytest.mark.parametrize(
'config',
[
'ssldyn',
],
indirect=True,
)
@idf_parametrize('target', ['esp32'], indirect=['target'])
def test_examples_protocol_https_x509_bundle_dynamic_buffer(dut: Dut) -> None:
# test mbedtls dynamic resource
# check and log bin size
@@ -45,9 +52,15 @@ def test_examples_protocol_https_x509_bundle_dynamic_buffer(dut: Dut) -> None:
@pytest.mark.qemu
@pytest.mark.esp32
@pytest.mark.host_test
@pytest.mark.parametrize('config', ['default_crt_bundle',], indirect=True)
@pytest.mark.parametrize(
'config',
[
'default_crt_bundle',
],
indirect=True,
)
@idf_parametrize('target', ['esp32'], indirect=['target'])
def test_examples_protocol_https_x509_bundle_default_crt_bundle_stress_test(dut: Dut) -> None:
# check and log bin size
binary_file = os.path.join(dut.app.binary_path, 'https_x509_bundle.bin')

View File

@@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
import logging
import os
@@ -6,6 +6,7 @@ import os
import pytest
from common_test_methods import get_env_config_variable
from pytest_embedded import Dut
from pytest_embedded_idf.utils import idf_parametrize
def _run_test(dut: Dut) -> None:
@@ -27,41 +28,46 @@ def _run_test(dut: Dut) -> None:
# expect at least two packets (there could be lost packets)
ip = dut.expect(r'64 bytes from (\d+\.\d+\.\d+\.\d+) icmp_seq=\d ttl=\d+ time=\d+ ms')[1].decode()
dut.expect(fr'64 bytes from {ip} icmp_seq=[2-5] ttl=\d+ time=')
dut.expect(rf'64 bytes from {ip} icmp_seq=[2-5] ttl=\d+ time=')
dut.expect(r'5 packets transmitted, [2-5] received, \d{1,3}% packet loss')
dut.write('')
dut.expect('esp>')
@pytest.mark.esp32
@pytest.mark.esp32c2
@pytest.mark.esp32s2
@pytest.mark.esp32c3
@pytest.mark.esp32s3
@pytest.mark.esp32c5
@pytest.mark.esp32c6
@pytest.mark.esp32c61
@pytest.mark.wifi_ap
@idf_parametrize(
'target',
['esp32', 'esp32c2', 'esp32s2', 'esp32c3', 'esp32s3', 'esp32c5', 'esp32c6', 'esp32c61'],
indirect=['target'],
)
def test_protocols_icmp_echo(dut: Dut) -> None:
_run_test(dut)
@pytest.mark.esp32c2
@pytest.mark.wifi_ap
@pytest.mark.xtal_26mhz
@pytest.mark.parametrize(
'config, baud', [
'config, baud',
[
('c2_xtal26m', '74880'),
], indirect=True
],
indirect=True,
)
@idf_parametrize('target', ['esp32c2'], indirect=['target'])
def test_protocols_icmp_echo_esp32c2_26mhz(dut: Dut) -> None:
_run_test(dut)
@pytest.mark.esp32
@pytest.mark.wifi_router
@pytest.mark.parametrize('config', ['ipv6_only',], indirect=True)
@pytest.mark.parametrize(
'config',
[
'ipv6_only',
],
indirect=True,
)
@idf_parametrize('target', ['esp32'], indirect=['target'])
def test_protocols_icmp_echo_ipv6_only(dut: Dut) -> None:
# Parse IP address of STA
logging.info('Waiting to connect with AP')
@@ -82,7 +88,7 @@ def test_protocols_icmp_echo_ipv6_only(dut: Dut) -> None:
# expect at least two packets (there could be lost packets)
ip = dut.expect(r'64 bytes from ([0-9a-fA-F:]+) icmp_seq=\d ttl=\d+ time=\d+ ms')[1].decode()
dut.expect(fr'64 bytes from {ip} icmp_seq=[2-5] ttl=\d+ time=')
dut.expect(rf'64 bytes from {ip} icmp_seq=[2-5] ttl=\d+ time=')
dut.expect(r'5 packets transmitted, [2-5] received, \d{1,3}% packet loss')
dut.write('')

View File

@@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
import contextlib
import logging
@@ -9,6 +9,7 @@ from typing import Iterator
import pytest
from pytest_embedded import Dut
from pytest_embedded_idf.utils import idf_parametrize
from scapy.all import Ether
from scapy.all import raw
@@ -18,7 +19,7 @@ ETH_TYPE_3 = 0x2223
@contextlib.contextmanager
def configure_eth_if(eth_type: int, target_if: str='') -> Iterator[socket.socket]:
def configure_eth_if(eth_type: int, target_if: str = '') -> Iterator[socket.socket]:
if target_if == '':
# try to determine which interface to use
netifs = os.listdir('/sys/class/net/')
@@ -42,7 +43,7 @@ def configure_eth_if(eth_type: int, target_if: str='') -> Iterator[socket.socket
so.close()
def send_recv_eth_frame(payload_str: str, eth_type: int, dest_mac: str, eth_if: str='') -> str:
def send_recv_eth_frame(payload_str: str, eth_type: int, dest_mac: str, eth_if: str = '') -> str:
with configure_eth_if(eth_type, eth_if) as so:
so.settimeout(10)
eth_frame = Ether(dst=dest_mac, src=so.getsockname()[4], type=eth_type) / raw(payload_str.encode())
@@ -62,7 +63,7 @@ def send_recv_eth_frame(payload_str: str, eth_type: int, dest_mac: str, eth_if:
return str(eth_frame_repl.load.decode().rstrip('\x00'))
def recv_eth_frame(eth_type: int, eth_if: str='') -> str:
def recv_eth_frame(eth_type: int, eth_if: str = '') -> str:
with configure_eth_if(eth_type, eth_if) as so:
so.settimeout(10)
try:
@@ -101,9 +102,9 @@ def actual_test(dut: Dut) -> None:
raise Exception('Echoed message does not match!')
@pytest.mark.esp32 # internally tested using ESP32 with IP101 but may support all targets with SPI Ethernet
@pytest.mark.eth_ip101
@pytest.mark.flaky(reruns=3, reruns_delay=5)
@idf_parametrize('target', ['esp32'], indirect=['target'])
def test_esp_netif_l2tap_example(dut: Dut) -> None:
actual_test(dut)
@@ -113,12 +114,12 @@ if __name__ == '__main__':
message_1 = 'ESP32 test message with EthType ' + hex(ETH_TYPE_1)
message_2 = 'ESP32 test message with EthType ' + hex(ETH_TYPE_2)
# Usage: pytest_example_l2tap_echo.py [<dest_mac_address>] [<host_eth_interface>]
if sys.argv[2:]: # if two arguments provided:
if sys.argv[2:]: # if two arguments provided:
send_recv_eth_frame(message_1, ETH_TYPE_1, sys.argv[1], sys.argv[2])
send_recv_eth_frame(message_2, ETH_TYPE_2, sys.argv[1], sys.argv[2])
elif sys.argv[1:]: # if one argument provided:
elif sys.argv[1:]: # if one argument provided:
send_recv_eth_frame(message_1, ETH_TYPE_1, sys.argv[1])
send_recv_eth_frame(message_2, ETH_TYPE_2, sys.argv[1])
else: # if no argument provided:
else: # if no argument provided:
send_recv_eth_frame(message_1, ETH_TYPE_1, 'ff:ff:ff:ff:ff:ff')
send_recv_eth_frame(message_2, ETH_TYPE_2, 'ff:ff:ff:ff:ff:ff')

View File

@@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Unlicense OR CC0-1.0
import logging
import os
@@ -12,6 +12,7 @@ import paho.mqtt.client as mqtt
import pexpect
import pytest
from pytest_embedded import Dut
from pytest_embedded_idf.utils import idf_parametrize
event_client_connected = Event()
event_stop_client = Event()
@@ -50,7 +51,9 @@ def on_message(client, userdata, msg): # type: (mqtt.Client, tuple, mqtt.client
recv_binary = binary + '.received'
with open(recv_binary, 'w', encoding='utf-8') as fw:
fw.write(msg.payload)
raise ValueError('Received binary (saved as: {}) does not match the original file: {}'.format(recv_binary, binary))
raise ValueError(
'Received binary (saved as: {}) does not match the original file: {}'.format(recv_binary, binary)
)
payload = msg.payload.decode()
if not event_client_received_correct.is_set() and payload == 'data':
@@ -61,8 +64,8 @@ def on_message(client, userdata, msg): # type: (mqtt.Client, tuple, mqtt.client
message_log += 'Received data:' + msg.topic + ' ' + payload + '\n'
@pytest.mark.esp32
@pytest.mark.ethernet
@idf_parametrize('target', ['esp32'], indirect=['target'])
def test_examples_protocol_mqtt_ssl(dut): # type: (Dut) -> None
broker_url = ''
broker_port = 0
@@ -95,14 +98,16 @@ def test_examples_protocol_mqtt_ssl(dut): # type: (Dut) -> None
client.on_connect = on_connect
client.on_message = on_message
client.user_data_set((binary_file, bin_size))
client.tls_set(None,
None,
None, cert_reqs=ssl.CERT_NONE, tls_version=ssl.PROTOCOL_TLSv1_2, ciphers=None)
client.tls_set(None, None, None, cert_reqs=ssl.CERT_NONE, tls_version=ssl.PROTOCOL_TLSv1_2, ciphers=None)
client.tls_insecure_set(True)
print('Connecting...')
client.connect(broker_url, broker_port, 60)
except Exception:
print('ENV_TEST_FAILURE: Unexpected error while connecting to broker {}: {}:'.format(broker_url, sys.exc_info()[0]))
print(
'ENV_TEST_FAILURE: Unexpected error while connecting to broker {}: {}:'.format(
broker_url, sys.exc_info()[0]
)
)
raise
# Starting a py-client in a separate thread
thread1 = Thread(target=mqtt_client_task, args=(client,))

View File

@@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Unlicense OR CC0-1.0
import logging
import os
@@ -12,6 +12,7 @@ import pexpect
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
msgid = -1
@@ -25,13 +26,15 @@ def mqqt_server_sketch(my_ip, port): # type: (str, str) -> None
s.settimeout(60)
s.bind((my_ip, port))
s.listen(1)
q,addr = s.accept()
q, addr = s.accept()
q.settimeout(30)
print('connection accepted')
except Exception:
print('Local server on {}:{} listening/accepting failure: {}'
'Possibly check permissions or firewall settings'
'to accept connections on this address'.format(my_ip, port, sys.exc_info()[0]))
print(
'Local server on {}:{} listening/accepting failure: {}'
'Possibly check permissions or firewall settings'
'to accept connections on this address'.format(my_ip, port, sys.exc_info()[0])
)
raise
data = q.recv(1024)
# check if received initial empty message
@@ -49,8 +52,8 @@ def mqqt_server_sketch(my_ip, port): # type: (str, str) -> None
print('server closed')
@pytest.mark.esp32
@pytest.mark.ethernet
@idf_parametrize('target', ['esp32'], indirect=['target'])
def test_examples_protocol_mqtt_qos1(dut: Dut) -> None:
global msgid
"""
@@ -73,7 +76,7 @@ def test_examples_protocol_mqtt_qos1(dut: Dut) -> None:
# 2. start mqtt broker sketch
host_ip = get_host_ip4_by_dest_ip(ip_address)
thread1 = Thread(target=mqqt_server_sketch, args=(host_ip,1883))
thread1 = Thread(target=mqqt_server_sketch, args=(host_ip, 1883))
thread1.start()
data_write = 'mqtt://' + host_ip
@@ -85,8 +88,10 @@ def test_examples_protocol_mqtt_qos1(dut: Dut) -> None:
msgid_enqueued = dut.expect(b'outbox: ENQUEUE msgid=([0-9]+)', timeout=30).group(1).decode()
msgid_deleted = dut.expect(b'outbox: DELETED msgid=([0-9]+)', timeout=30).group(1).decode()
# 4. check the msgid of received data are the same as that of enqueued and deleted from outbox
if (msgid_enqueued == str(msgid) and msgid_deleted == str(msgid)):
if msgid_enqueued == str(msgid) and msgid_deleted == str(msgid):
print('PASS: Received correct msg id')
else:
print('Failure!')
raise ValueError('Mismatch of msgid: received: {}, enqueued {}, deleted {}'.format(msgid, msgid_enqueued, msgid_deleted))
raise ValueError(
'Mismatch of msgid: received: {}, enqueued {}, deleted {}'.format(msgid, msgid_enqueued, msgid_deleted)
)

View File

@@ -1,16 +1,18 @@
#!/usr/bin/env python
#
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Unlicense OR CC0-1.0
import logging
import os
import re
import sys
from threading import Event, Thread
from threading import Event
from threading import Thread
import paho.mqtt.client as mqtt
import pytest
from pytest_embedded import Dut
from pytest_embedded_idf.utils import idf_parametrize
event_client_connected = Event()
event_stop_client = Event()
@@ -43,8 +45,8 @@ def on_message(client, userdata, msg): # type: (mqtt.Client, tuple, mqtt.client
message_log += 'Received data:' + msg.topic + ' ' + payload + '\n'
@pytest.mark.esp32
@pytest.mark.ethernet
@idf_parametrize('target', ['esp32'], indirect=['target'])
def test_examples_protocol_mqtt_ws(dut): # type: (Dut) -> None
broker_url = ''
broker_port = 0
@@ -77,7 +79,11 @@ def test_examples_protocol_mqtt_ws(dut): # type: (Dut) -> None
print('Connecting...')
client.connect(broker_url, broker_port, 60)
except Exception:
print('ENV_TEST_FAILURE: Unexpected error while connecting to broker {}: {}:'.format(broker_url, sys.exc_info()[0]))
print(
'ENV_TEST_FAILURE: Unexpected error while connecting to broker {}: {}:'.format(
broker_url, sys.exc_info()[0]
)
)
raise
# Starting a py-client in a separate thread
thread1 = Thread(target=mqtt_client_task, args=(client,))

View File

@@ -1,18 +1,20 @@
#!/usr/bin/env python
#
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Unlicense OR CC0-1.0
import logging
import os
import re
import ssl
import sys
from threading import Event, Thread
from threading import Event
from threading import Thread
import paho.mqtt.client as mqtt
import pexpect
import pytest
from pytest_embedded import Dut
from pytest_embedded_idf.utils import idf_parametrize
event_client_connected = Event()
event_stop_client = Event()
@@ -45,8 +47,8 @@ def on_message(client, userdata, msg): # type: (mqtt.Client, tuple, mqtt.client
message_log += 'Received data:' + msg.topic + ' ' + payload + '\n'
@pytest.mark.esp32
@pytest.mark.ethernet
@idf_parametrize('target', ['esp32'], indirect=['target'])
def test_examples_protocol_mqtt_wss(dut): # type: (Dut) -> None
broker_url = ''
broker_port = 0
@@ -76,13 +78,15 @@ def test_examples_protocol_mqtt_wss(dut): # type: (Dut) -> None
client = mqtt.Client(transport='websockets')
client.on_connect = on_connect
client.on_message = on_message
client.tls_set(None,
None,
None, cert_reqs=ssl.CERT_NONE, tls_version=ssl.PROTOCOL_TLSv1_2, ciphers=None)
client.tls_set(None, None, None, cert_reqs=ssl.CERT_NONE, tls_version=ssl.PROTOCOL_TLSv1_2, ciphers=None)
print('Connecting...')
client.connect(broker_url, broker_port, 60)
except Exception:
print('ENV_TEST_FAILURE: Unexpected error while connecting to broker {}: {}:'.format(broker_url, sys.exc_info()[0]))
print(
'ENV_TEST_FAILURE: Unexpected error while connecting to broker {}: {}:'.format(
broker_url, sys.exc_info()[0]
)
)
raise
# Starting a py-client in a separate thread
thread1 = Thread(target=mqtt_client_task, args=(client,))

View File

@@ -1,23 +1,23 @@
#!/usr/bin/env python
#
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
import logging
import os
import pytest
from pytest_embedded import Dut
from pytest_embedded_idf.utils import idf_parametrize
@pytest.mark.esp32
@pytest.mark.ethernet
@idf_parametrize('target', ['esp32'], indirect=['target'])
def test_examples_protocol_mqtt5(dut: Dut) -> None:
"""
steps: |
1. join AP
2. connect to mqtt://mqtt.eclipseprojects.io
3. check conneciton success
3. check connection success
"""
# check and log bin size
binary_file = os.path.join(dut.app.binary_path, 'mqtt5.bin')

View File

@@ -1,17 +1,18 @@
# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
import datetime
import logging
from typing import Any, Tuple
from typing import Any
from typing import Tuple
import pytest
from common_test_methods import get_env_config_variable
from pytest_embedded import Dut
from pytest_embedded_idf.utils import idf_parametrize
@pytest.mark.esp32
@pytest.mark.wifi_ap
@idf_parametrize('target', ['esp32'], indirect=['target'])
def test_get_time_from_sntp_server(dut: Dut) -> None:
dut.expect('Time is not set yet. Connecting to WiFi and getting time over NTP.')
if dut.app.sdkconfig.get('EXAMPLE_WIFI_SSID_PWD_FROM_STDIN') is True:

View File

@@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
import logging
import socket
@@ -9,12 +9,14 @@ from common_test_methods import get_host_ip4_by_dest_ip
from common_test_methods import get_host_ip6_by_dest_ip
from common_test_methods import get_my_interface_by_dest_ip
from pytest_embedded import Dut
from pytest_embedded_idf.utils import idf_parametrize
try:
from run_tcp_server import TcpServer
except ImportError:
import os
import sys
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'scripts')))
from run_tcp_server import TcpServer
@@ -22,15 +24,12 @@ except ImportError:
PORT = 3333
@pytest.mark.esp32
@pytest.mark.esp32s2
@pytest.mark.esp32c2
@pytest.mark.esp32c3
@pytest.mark.esp32s3
@pytest.mark.esp32c5
@pytest.mark.esp32c6
@pytest.mark.esp32c61
@pytest.mark.wifi_router
@idf_parametrize(
'target',
['esp32', 'esp32s2', 'esp32c2', 'esp32c3', 'esp32s3', 'esp32c5', 'esp32c6', 'esp32c61'],
indirect=['target'],
)
def test_examples_tcp_client_ipv4(dut: Dut) -> None:
# Parse IP address of STA
logging.info('Waiting to connect with AP')
@@ -51,14 +50,10 @@ def test_examples_tcp_client_ipv4(dut: Dut) -> None:
dut.expect('OK: Message from ESP32')
@pytest.mark.esp32
@pytest.mark.esp32s2
@pytest.mark.esp32c2
@pytest.mark.esp32c3
@pytest.mark.esp32s3
@pytest.mark.esp32c6
@pytest.mark.esp32c61
@pytest.mark.wifi_router
@idf_parametrize(
'target', ['esp32', 'esp32s2', 'esp32c2', 'esp32c3', 'esp32s3', 'esp32c6', 'esp32c61'], indirect=['target']
)
def test_examples_tcp_client_ipv6(dut: Dut) -> None:
# Parse IP address of STA
logging.info('Waiting to connect with AP')

View File

@@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
import logging
import time
@@ -8,12 +8,14 @@ import pytest
from common_test_methods import get_env_config_variable
from common_test_methods import get_my_interface_by_dest_ip
from pytest_embedded import Dut
from pytest_embedded_idf.utils import idf_parametrize
try:
from run_tcp_client import tcp_client
except ImportError:
import os
import sys
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'scripts')))
from run_tcp_client import tcp_client
@@ -22,15 +24,12 @@ PORT = 3333
MESSAGE = 'Data to ESP'
@pytest.mark.esp32
@pytest.mark.esp32s2
@pytest.mark.esp32c2
@pytest.mark.esp32c3
@pytest.mark.esp32s3
@pytest.mark.esp32c5
@pytest.mark.esp32c6
@pytest.mark.esp32c61
@pytest.mark.wifi_router
@idf_parametrize(
'target',
['esp32', 'esp32s2', 'esp32c2', 'esp32c3', 'esp32s3', 'esp32c5', 'esp32c6', 'esp32c61'],
indirect=['target'],
)
def test_examples_tcp_server_ipv4(dut: Dut) -> None:
# Parse IP address of STA
logging.info('Waiting to connect with AP')
@@ -51,14 +50,16 @@ def test_examples_tcp_server_ipv4(dut: Dut) -> None:
dut.expect(MESSAGE)
@pytest.mark.esp32c2
@pytest.mark.wifi_router
@pytest.mark.xtal_26mhz
@pytest.mark.parametrize(
'config, baud', [
'config, baud',
[
('c2_xtal26m', '74880'),
], indirect=True
],
indirect=True,
)
@idf_parametrize('target', ['esp32c2'], indirect=['target'])
def test_examples_tcp_server_ipv4_esp32c2_26mhz(dut: Dut) -> None:
# Parse IP address of STA
logging.info('Waiting to connect with AP')
@@ -79,14 +80,10 @@ def test_examples_tcp_server_ipv4_esp32c2_26mhz(dut: Dut) -> None:
dut.expect(MESSAGE)
@pytest.mark.esp32
@pytest.mark.esp32s2
@pytest.mark.esp32c2
@pytest.mark.esp32c3
@pytest.mark.esp32s3
@pytest.mark.esp32c6
@pytest.mark.esp32c61
@pytest.mark.wifi_router
@idf_parametrize(
'target', ['esp32', 'esp32s2', 'esp32c2', 'esp32c3', 'esp32s3', 'esp32c6', 'esp32c61'], indirect=['target']
)
def test_examples_tcp_server_ipv6(dut: Dut) -> None:
# Parse IP address of STA
logging.info('Waiting to connect with AP')
@@ -111,14 +108,10 @@ def test_examples_tcp_server_ipv6(dut: Dut) -> None:
dut.expect(MESSAGE)
@pytest.mark.esp32
@pytest.mark.esp32s2
@pytest.mark.esp32c2
@pytest.mark.esp32c3
@pytest.mark.esp32s3
@pytest.mark.esp32c6
@pytest.mark.esp32c61
@pytest.mark.wifi_router
@idf_parametrize(
'target', ['esp32', 'esp32s2', 'esp32c2', 'esp32c3', 'esp32s3', 'esp32c6', 'esp32c61'], indirect=['target']
)
def test_examples_tcp_server_ipv6_only(dut: Dut) -> None:
# Parse IP address of STA
logging.info('Waiting to connect with AP')

View File

@@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
import logging
import socket
@@ -10,12 +10,14 @@ from common_test_methods import get_host_ip6_by_dest_ip
from common_test_methods import get_my_interface_by_dest_ip
from pexpect.exceptions import TIMEOUT
from pytest_embedded import Dut
from pytest_embedded_idf.utils import idf_parametrize
try:
from run_udp_server import UdpServer
except ImportError:
import os
import sys
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'scripts')))
from run_udp_server import UdpServer
@@ -24,15 +26,12 @@ PORT = 3333
MAX_RETRIES = 3
@pytest.mark.esp32
@pytest.mark.esp32s2
@pytest.mark.esp32c2
@pytest.mark.esp32c3
@pytest.mark.esp32s3
@pytest.mark.esp32c5
@pytest.mark.esp32c6
@pytest.mark.esp32c61
@pytest.mark.wifi_router
@idf_parametrize(
'target',
['esp32', 'esp32s2', 'esp32c2', 'esp32c3', 'esp32s3', 'esp32c5', 'esp32c6', 'esp32c61'],
indirect=['target'],
)
def test_examples_udp_client_ipv4(dut: Dut) -> None:
# Parse IP address of STA
logging.info('Waiting to connect with AP')
@@ -60,14 +59,10 @@ def test_examples_udp_client_ipv4(dut: Dut) -> None:
raise ValueError('Failed to send/recv udp packets.')
@pytest.mark.esp32
@pytest.mark.esp32s2
@pytest.mark.esp32c2
@pytest.mark.esp32c3
@pytest.mark.esp32s3
@pytest.mark.esp32c6
@pytest.mark.esp32c61
@pytest.mark.wifi_router
@idf_parametrize(
'target', ['esp32', 'esp32s2', 'esp32c2', 'esp32c3', 'esp32s3', 'esp32c6', 'esp32c61'], indirect=['target']
)
def test_examples_udp_client_ipv6(dut: Dut) -> None:
# Parse IP address of STA
logging.info('Waiting to connect with AP')

View File

@@ -1,4 +1,4 @@
# SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
import logging
@@ -6,12 +6,14 @@ import pytest
from common_test_methods import get_env_config_variable
from common_test_methods import get_my_interface_by_dest_ip
from pytest_embedded import Dut
from pytest_embedded_idf.utils import idf_parametrize
try:
from run_udp_client import udp_client
except ImportError:
import os
import sys
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', 'scripts')))
from run_udp_client import udp_client
@@ -21,15 +23,12 @@ MESSAGE = 'Data to ESP'
MAX_RETRIES = 3
@pytest.mark.esp32
@pytest.mark.esp32s2
@pytest.mark.esp32c2
@pytest.mark.esp32c3
@pytest.mark.esp32s3
@pytest.mark.esp32c5
@pytest.mark.esp32c6
@pytest.mark.esp32c61
@pytest.mark.wifi_router
@idf_parametrize(
'target',
['esp32', 'esp32s2', 'esp32c2', 'esp32c3', 'esp32s3', 'esp32c5', 'esp32c6', 'esp32c61'],
indirect=['target'],
)
def test_examples_udp_server_ipv4(dut: Dut) -> None:
# Parse IP address of STA
logging.info('Waiting to connect with AP')
@@ -54,14 +53,10 @@ def test_examples_udp_server_ipv4(dut: Dut) -> None:
dut.expect(MESSAGE)
@pytest.mark.esp32
@pytest.mark.esp32s2
@pytest.mark.esp32c2
@pytest.mark.esp32c3
@pytest.mark.esp32s3
@pytest.mark.esp32c6
@pytest.mark.esp32c61
@pytest.mark.wifi_router
@idf_parametrize(
'target', ['esp32', 'esp32s2', 'esp32c2', 'esp32c3', 'esp32s3', 'esp32c6', 'esp32c61'], indirect=['target']
)
def test_examples_udp_server_ipv6(dut: Dut) -> None:
# Parse IP address of STA
logging.info('Waiting to connect with AP')

View File

@@ -1,15 +1,18 @@
# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
# SPDX-FileCopyrightText: 2024-2025 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.esp32
@pytest.mark.eth_ip101
@pytest.mark.parametrize('config', [
'default_ip101',
], indirect=True)
def test_static_ip(
dut: Dut
) -> None:
@pytest.mark.parametrize(
'config',
[
'default_ip101',
],
indirect=True,
)
@idf_parametrize('target', ['esp32'], indirect=['target'])
def test_static_ip(dut: Dut) -> None:
dut.expect(r'Resolved IPv4 address: (\d+\.\d+\.\d+\.\d+)')