diff --git a/components/app_update/test_apps/test_app_update/pytest_app_update_ut.py b/components/app_update/test_apps/test_app_update/pytest_app_update_ut.py index 087216c2ad..a8fe757fe1 100644 --- a/components/app_update/test_apps/test_app_update/pytest_app_update_ut.py +++ b/components/app_update/test_apps/test_app_update/pytest_app_update_ut.py @@ -1,16 +1,18 @@ -# 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 re import pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize DEFAULT_TIMEOUT = 20 TEST_SUBMENU_PATTERN_PYTEST = re.compile(rb'\s+\((\d+)\)\s+"([^"]+)"\r?\n') -@pytest.mark.supported_targets -@pytest.mark.temp_skip_ci(targets=['esp32c5'], reason='C5 has not supported deep sleep') # TODO: [ESP32C5] IDF-8640, IDF-10317 +@pytest.mark.temp_skip_ci( + targets=['esp32c5'], reason='C5 has not supported deep sleep' +) # TODO: [ESP32C5] IDF-8640, IDF-10317 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -19,11 +21,11 @@ TEST_SUBMENU_PATTERN_PYTEST = re.compile(rb'\s+\((\d+)\)\s+"([^"]+)"\r?\n') ], indirect=True, ) +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_app_update(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=90) -@pytest.mark.supported_targets # TODO: [ESP32C61] IDF-9245, IDF-10983 @pytest.mark.temp_skip_ci(targets=['esp32c61'], reason='C61 has not supported deep sleep') @pytest.mark.generic @@ -34,12 +36,14 @@ def test_app_update(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_app_update_xip_psram(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=90) -@pytest.mark.supported_targets -@pytest.mark.temp_skip_ci(targets=['esp32c5'], reason='C5 has not supported deep sleep') # TODO: [ESP32C5] IDF-8640, IDF-10317 +@pytest.mark.temp_skip_ci( + targets=['esp32c5'], reason='C5 has not supported deep sleep' +) # TODO: [ESP32C5] IDF-8640, IDF-10317 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -48,14 +52,11 @@ def test_app_update_xip_psram(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_app_update_xip_psram_rom_impl(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=90) -@pytest.mark.esp32 -@pytest.mark.esp32c3 -@pytest.mark.esp32s3 -@pytest.mark.esp32p4 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -64,5 +65,6 @@ def test_app_update_xip_psram_rom_impl(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32', 'esp32c3', 'esp32s3', 'esp32p4'], indirect=['target']) def test_app_update_with_rollback(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=90) diff --git a/components/bootloader_support/test_apps/bootloader_support/pytest_bootloader_support.py b/components/bootloader_support/test_apps/bootloader_support/pytest_bootloader_support.py index 8082cac3f2..59e3d4cf6a 100644 --- a/components/bootloader_support/test_apps/bootloader_support/pytest_bootloader_support.py +++ b/components/bootloader_support/test_apps/bootloader_support/pytest_bootloader_support.py @@ -1,26 +1,26 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 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.supported_targets +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_bootloader_support(dut: Dut) -> None: dut.run_all_single_board_cases() @pytest.mark.host_test @pytest.mark.qemu -@pytest.mark.esp32 +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_bootloader_support_qemu_esp32(dut: Dut) -> None: dut.run_all_single_board_cases() @pytest.mark.host_test @pytest.mark.qemu -@pytest.mark.esp32c3 +@idf_parametrize('target', ['esp32c3'], indirect=['target']) def test_bootloader_support_qemu_esp32c3(dut: Dut) -> None: for case in dut.test_menu: if 'qemu-ignore-c3' not in case.groups: diff --git a/components/bootloader_support/test_apps/rtc_custom_section/pytest_rtc_mem.py b/components/bootloader_support/test_apps/rtc_custom_section/pytest_rtc_mem.py index 6dbf4030a3..1ccf193dfb 100644 --- a/components/bootloader_support/test_apps/rtc_custom_section/pytest_rtc_mem.py +++ b/components/bootloader_support/test_apps/rtc_custom_section/pytest_rtc_mem.py @@ -1,17 +1,15 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 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.esp32 -@pytest.mark.esp32c3 -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32p4 +@idf_parametrize( + 'target', + ['esp32', 'esp32c3', 'esp32c5', 'esp32c6', 'esp32h2', 'esp32s2', 'esp32s3', 'esp32p4'], + indirect=['target'], +) def test_rtc_reserved_memory(dut: Dut) -> None: dut.expect_exact('SUCCESS: data were saved across reboot', timeout=10) diff --git a/components/bt/test_apps/basic_unit_test/pytest_basic_unit_test.py b/components/bt/test_apps/basic_unit_test/pytest_basic_unit_test.py index de3d235bb5..98e7cd8a6e 100644 --- a/components/bt/test_apps/basic_unit_test/pytest_basic_unit_test.py +++ b/components/bt/test_apps/basic_unit_test/pytest_basic_unit_test.py @@ -1,11 +1,11 @@ -# 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 pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize @pytest.mark.generic -@pytest.mark.esp32 -@pytest.mark.esp32c3 +@idf_parametrize('target', ['esp32', 'esp32c3'], indirect=['target']) def test_bt(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/bt/test_apps/memory_release/pytest_memory_release.py b/components/bt/test_apps/memory_release/pytest_memory_release.py index fbb3916991..d5d70fcd2b 100644 --- a/components/bt/test_apps/memory_release/pytest_memory_release.py +++ b/components/bt/test_apps/memory_release/pytest_memory_release.py @@ -1,14 +1,20 @@ -# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 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.parametrize('config', [ - pytest.param('default', marks=[pytest.mark.esp32, pytest.mark.esp32c2, pytest.mark.generic]), - pytest.param('iram', marks=[pytest.mark.esp32c2, pytest.mark.generic]), - pytest.param('psram', marks=[pytest.mark.esp32, pytest.mark.psram]), -], indirect=True) +@idf_parametrize( + 'config,target,markers', + [ + ('default', 'esp32', (pytest.mark.generic,)), + ('default', 'esp32c2', (pytest.mark.generic,)), + ('iram', 'esp32c2', (pytest.mark.generic,)), + ('psram', 'esp32', (pytest.mark.psram,)), + ], + indirect=['config', 'target'], +) def test_bt_memory_release(dut: Dut) -> None: dut.expect_exact('BLE Host Task Started', timeout=6) dut.expect_exact('BLE Host Task Stopped', timeout=8) diff --git a/components/console/test_apps/console/pytest_console.py b/components/console/test_apps/console/pytest_console.py index 20901b4652..cac89e155d 100644 --- a/components/console/test_apps/console/pytest_console.py +++ b/components/console/test_apps/console/pytest_console.py @@ -1,7 +1,8 @@ -# 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 pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize def do_test_quit(dut: Dut) -> None: @@ -44,69 +45,61 @@ def do_test_help_quit(dut: Dut) -> None: dut.expect(r'quit\s+Quit REPL environment\s+esp>') -@pytest.mark.parametrize( - 'config', [ - pytest.param('defaults'), - ] -) -@pytest.mark.parametrize( - 'test_on', [ - pytest.param('host', marks=[pytest.mark.linux, pytest.mark.host_test]), - pytest.param('target', marks=[pytest.mark.esp32, pytest.mark.generic]), - pytest.param('target', marks=[pytest.mark.esp32c3, pytest.mark.generic]), - pytest.param('qemu', marks=[pytest.mark.esp32, pytest.mark.host_test, pytest.mark.qemu]), - ] +@idf_parametrize('config', ['defaults'], indirect=['config']) +@idf_parametrize( + 'target,test_on,markers', + [ + ('linux', 'host', (pytest.mark.host_test,)), + ('esp32', 'target', (pytest.mark.generic,)), + ('esp32c3', 'target', (pytest.mark.generic,)), + ('esp32', 'qemu', (pytest.mark.host_test, pytest.mark.qemu)), + ], + indirect=['target'], ) def test_console(dut: Dut, test_on: str) -> None: dut.run_all_single_board_cases(group='!ignore', timeout=120) -@pytest.mark.parametrize( - 'config', [ - pytest.param('defaults'), - ] -) -@pytest.mark.parametrize( - 'test_on', [ - pytest.param('host', marks=[pytest.mark.linux, pytest.mark.host_test]), - pytest.param('target', marks=[pytest.mark.esp32, pytest.mark.generic]), - pytest.param('target', marks=[pytest.mark.esp32c3, pytest.mark.generic]), - pytest.param('qemu', marks=[pytest.mark.esp32, pytest.mark.host_test, pytest.mark.qemu]), - ] +@idf_parametrize('config', ['defaults'], indirect=['config']) +@idf_parametrize( + 'target,test_on,markers', + [ + ('linux', 'host', (pytest.mark.host_test,)), + ('esp32', 'target', (pytest.mark.generic,)), + ('esp32c3', 'target', (pytest.mark.generic,)), + ('esp32', 'qemu', (pytest.mark.host_test, pytest.mark.qemu)), + ], + indirect=['target'], ) def test_console_repl(dut: Dut, test_on: str) -> None: do_test_quit(dut) -@pytest.mark.parametrize( - 'config', [ - pytest.param('defaults'), - ] -) -@pytest.mark.parametrize( - 'test_on', [ - pytest.param('host', marks=[pytest.mark.linux, pytest.mark.host_test]), - pytest.param('target', marks=[pytest.mark.esp32, pytest.mark.generic]), - pytest.param('target', marks=[pytest.mark.esp32c3, pytest.mark.generic]), - pytest.param('qemu', marks=[pytest.mark.esp32, pytest.mark.host_test, pytest.mark.qemu]), - ] +@idf_parametrize('config', ['defaults'], indirect=['config']) +@idf_parametrize( + 'target,test_on,markers', + [ + ('linux', 'host', (pytest.mark.host_test,)), + ('esp32', 'target', (pytest.mark.generic,)), + ('esp32c3', 'target', (pytest.mark.generic,)), + ('esp32', 'qemu', (pytest.mark.host_test, pytest.mark.qemu)), + ], + indirect=['target'], ) def test_console_help_sorted_registration(dut: Dut, test_on: str) -> None: do_test_help_generic(dut, 'sorted') -@pytest.mark.parametrize( - 'config', [ - pytest.param('defaults'), - ] -) -@pytest.mark.parametrize( - 'test_on', [ - pytest.param('host', marks=[pytest.mark.linux, pytest.mark.host_test]), - pytest.param('target', marks=[pytest.mark.esp32, pytest.mark.generic]), - pytest.param('target', marks=[pytest.mark.esp32c3, pytest.mark.generic]), - pytest.param('qemu', marks=[pytest.mark.esp32, pytest.mark.host_test, pytest.mark.qemu]), - ] +@idf_parametrize('config', ['defaults'], indirect=['config']) +@idf_parametrize( + 'target,test_on,markers', + [ + ('linux', 'host', (pytest.mark.host_test,)), + ('esp32', 'target', (pytest.mark.generic,)), + ('esp32c3', 'target', (pytest.mark.generic,)), + ('esp32', 'qemu', (pytest.mark.host_test, pytest.mark.qemu)), + ], + indirect=['target'], ) def test_console_help_reverse_registration(dut: Dut, test_on: str) -> None: dut.expect_exact('Press ENTER to see the list of tests') @@ -131,63 +124,45 @@ def test_console_help_reverse_registration(dut: Dut, test_on: str) -> None: dut.expect_exact('esp>') -@pytest.mark.parametrize( - 'config', [ - pytest.param('sorted'), - ] -) -@pytest.mark.parametrize( - 'test_on', [ - pytest.param('host', marks=[pytest.mark.linux, pytest.mark.host_test]), - ] -) +@idf_parametrize('config', ['sorted'], indirect=['config']) +@idf_parametrize('target', ['linux'], indirect=['target']) +@idf_parametrize('test_on,markers', [('host', (pytest.mark.host_test,))]) def test_console_sorted_help_sorted_registration(dut: Dut, test_on: str) -> None: do_test_help_generic(dut, 'sorted') -@pytest.mark.parametrize( - 'config', [ - pytest.param('sorted', marks=[pytest.mark.linux, pytest.mark.host_test]), - ] -) -@pytest.mark.parametrize( - 'test_on', [ - pytest.param('host', marks=[pytest.mark.linux, pytest.mark.host_test]), - ] -) +@idf_parametrize('config', ['sorted'], indirect=['config']) +@idf_parametrize('target', ['linux'], indirect=['target']) +@idf_parametrize('test_on,markers', [('host', (pytest.mark.host_test,))]) def test_console_sorted_help_reverse_registration(dut: Dut, test_on: str) -> None: do_test_help_generic(dut, 'reverse') -@pytest.mark.parametrize( - 'config', [ - pytest.param('defaults'), - ] -) -@pytest.mark.parametrize( - 'test_on', [ - pytest.param('host', marks=[pytest.mark.linux, pytest.mark.host_test]), - pytest.param('target', marks=[pytest.mark.esp32, pytest.mark.generic]), - pytest.param('target', marks=[pytest.mark.esp32c3, pytest.mark.generic]), - pytest.param('qemu', marks=[pytest.mark.esp32, pytest.mark.host_test, pytest.mark.qemu]), - ] +@idf_parametrize('config', ['defaults'], indirect=['config']) +@idf_parametrize( + 'target,test_on,markers', + [ + ('linux', 'host', (pytest.mark.host_test,)), + ('esp32', 'target', (pytest.mark.generic,)), + ('esp32c3', 'target', (pytest.mark.generic,)), + ('esp32', 'qemu', (pytest.mark.host_test, pytest.mark.qemu)), + ], + indirect=['target'], ) def test_console_help_quit(dut: Dut, test_on: str) -> None: do_test_help_quit(dut) -@pytest.mark.parametrize( - 'config', [ - pytest.param('defaults'), - ] -) -@pytest.mark.parametrize( - 'test_on', [ - pytest.param('host', marks=[pytest.mark.linux, pytest.mark.host_test]), - pytest.param('target', marks=[pytest.mark.esp32, pytest.mark.generic]), - pytest.param('target', marks=[pytest.mark.esp32c3, pytest.mark.generic]), - pytest.param('qemu', marks=[pytest.mark.esp32, pytest.mark.host_test, pytest.mark.qemu]), - ] +@idf_parametrize('config', ['defaults'], indirect=['config']) +@idf_parametrize( + 'target,test_on,markers', + [ + ('linux', 'host', (pytest.mark.host_test,)), + ('esp32', 'target', (pytest.mark.generic,)), + ('esp32c3', 'target', (pytest.mark.generic,)), + ('esp32', 'qemu', (pytest.mark.host_test, pytest.mark.qemu)), + ], + indirect=['target'], ) def test_console_help_verbose_level_0(dut: Dut, test_on: str) -> None: help_verbose_info = 'Print the summary of all registered commands if no arguments are given,' @@ -200,18 +175,16 @@ def test_console_help_verbose_level_0(dut: Dut, test_on: str) -> None: dut.expect_exact('help', not_matching=help_verbose_info) -@pytest.mark.parametrize( - 'config', [ - pytest.param('defaults'), - ] -) -@pytest.mark.parametrize( - 'test_on', [ - pytest.param('host', marks=[pytest.mark.linux, pytest.mark.host_test]), - pytest.param('target', marks=[pytest.mark.esp32, pytest.mark.generic]), - pytest.param('target', marks=[pytest.mark.esp32c3, pytest.mark.generic]), - pytest.param('qemu', marks=[pytest.mark.esp32, pytest.mark.host_test, pytest.mark.qemu]), - ] +@idf_parametrize('config', ['defaults'], indirect=['config']) +@idf_parametrize( + 'target,test_on,markers', + [ + ('linux', 'host', (pytest.mark.host_test,)), + ('esp32', 'target', (pytest.mark.generic,)), + ('esp32c3', 'target', (pytest.mark.generic,)), + ('esp32', 'qemu', (pytest.mark.host_test, pytest.mark.qemu)), + ], + indirect=['target'], ) def test_console_help_verbose_level_1(dut: Dut, test_on: str) -> None: help_verbose_info = 'Print the summary of all registered commands if no arguments are given,' @@ -223,18 +196,16 @@ def test_console_help_verbose_level_1(dut: Dut, test_on: str) -> None: dut.expect_exact(help_verbose_info) -@pytest.mark.parametrize( - 'config', [ - pytest.param('defaults'), - ] -) -@pytest.mark.parametrize( - 'test_on', [ - pytest.param('host', marks=[pytest.mark.linux, pytest.mark.host_test]), - pytest.param('target', marks=[pytest.mark.esp32, pytest.mark.generic]), - pytest.param('target', marks=[pytest.mark.esp32c3, pytest.mark.generic]), - pytest.param('qemu', marks=[pytest.mark.esp32, pytest.mark.host_test, pytest.mark.qemu]), - ] +@idf_parametrize('config', ['defaults'], indirect=['config']) +@idf_parametrize( + 'target,test_on,markers', + [ + ('linux', 'host', (pytest.mark.host_test,)), + ('esp32', 'target', (pytest.mark.generic,)), + ('esp32c3', 'target', (pytest.mark.generic,)), + ('esp32', 'qemu', (pytest.mark.host_test, pytest.mark.qemu)), + ], + indirect=['target'], ) def test_console_help_verbose_subcommand(dut: Dut, test_on: str) -> None: help_verbose_info = 'Print the summary of all registered commands if no arguments are given,' @@ -244,24 +215,23 @@ def test_console_help_verbose_subcommand(dut: Dut, test_on: str) -> None: # verify help --verbose=0 subcommand dut.write('help --verbose=0') dut.write('help --verbose=0') - dut.expect_exact('help --verbose=0',not_matching=help_verbose_info) + dut.expect_exact('help --verbose=0', not_matching=help_verbose_info) # verify help --verbose=1 subcommand dut.write('help --verbose=1') dut.expect_exact(help_verbose_info) -@pytest.mark.parametrize( - 'config', [ - pytest.param('defaults'), - ] -) -@pytest.mark.parametrize( - 'test_on', [ - pytest.param('host', marks=[pytest.mark.linux, pytest.mark.host_test]), - pytest.param('target', marks=[pytest.mark.esp32, pytest.mark.esp32c3, pytest.mark.generic]), - pytest.param('qemu', marks=[pytest.mark.esp32, pytest.mark.host_test, pytest.mark.qemu]), - ] +@idf_parametrize('config', ['defaults'], indirect=['config']) +@idf_parametrize( + 'target,test_on,markers', + [ + ('linux', 'host', (pytest.mark.host_test,)), + ('esp32', 'target', (pytest.mark.generic,)), + ('esp32c3', 'target', (pytest.mark.generic,)), + ('esp32', 'qemu', (pytest.mark.host_test, pytest.mark.qemu)), + ], + indirect=['target'], ) def test_console_help_deregister(dut: Dut, test_on: str) -> None: dut.expect_exact('Press ENTER to see the list of tests') @@ -275,17 +245,16 @@ def test_console_help_deregister(dut: Dut, test_on: str) -> None: dut.expect_exact(cmd_z_description, not_matching=cmd_a_description) -@pytest.mark.parametrize( - 'config', [ - pytest.param('defaults'), - ] -) -@pytest.mark.parametrize( - 'test_on', [ - pytest.param('host', marks=[pytest.mark.linux, pytest.mark.host_test]), - pytest.param('target', marks=[pytest.mark.esp32, pytest.mark.esp32c3, pytest.mark.generic]), - pytest.param('qemu', marks=[pytest.mark.esp32, pytest.mark.host_test, pytest.mark.qemu]), - ] +@idf_parametrize('config', ['defaults'], indirect=['config']) +@idf_parametrize( + 'target,test_on,markers', + [ + ('linux', 'host', (pytest.mark.host_test,)), + ('esp32', 'target', (pytest.mark.generic,)), + ('esp32c3', 'target', (pytest.mark.generic,)), + ('esp32', 'qemu', (pytest.mark.host_test, pytest.mark.qemu)), + ], + indirect=['target'], ) def test_console_help_re_register(dut: Dut, test_on: str) -> None: dut.expect_exact('Press ENTER to see the list of tests') diff --git a/components/cxx/test_apps/exception/pytest_cxx_exception.py b/components/cxx/test_apps/exception/pytest_cxx_exception.py index f270c017f5..e89f3c561a 100644 --- a/components/cxx/test_apps/exception/pytest_cxx_exception.py +++ b/components/cxx/test_apps/exception/pytest_cxx_exception.py @@ -1,12 +1,11 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 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_cxx_exception(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/cxx/test_apps/exception_no_except/pytest_cxx_exception_no_except.py b/components/cxx/test_apps/exception_no_except/pytest_cxx_exception_no_except.py index ee825df7a1..ba8849827b 100644 --- a/components/cxx/test_apps/exception_no_except/pytest_cxx_exception_no_except.py +++ b/components/cxx/test_apps/exception_no_except/pytest_cxx_exception_no_except.py @@ -1,13 +1,12 @@ -# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 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_cxx_noexcept_out_of_range(dut: Dut) -> None: dut.expect_exact('Press ENTER to see the list of tests') dut.write('1') @@ -15,9 +14,8 @@ def test_cxx_noexcept_out_of_range(dut: Dut) -> None: dut.expect_exact('Rebooting...') -@pytest.mark.esp32 -@pytest.mark.esp32c3 @pytest.mark.generic +@idf_parametrize('target', ['esp32', 'esp32c3'], indirect=['target']) def test_cxx_noexcept_bad_alloc(dut: Dut) -> None: dut.expect_exact('Press ENTER to see the list of tests') dut.write('2') diff --git a/components/cxx/test_apps/general/pytest_cxx_general.py b/components/cxx/test_apps/general/pytest_cxx_general.py index 0ba975526b..f480ed673c 100644 --- a/components/cxx/test_apps/general/pytest_cxx_general.py +++ b/components/cxx/test_apps/general/pytest_cxx_general.py @@ -1,36 +1,31 @@ -# 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 pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -configurations = [ - 'noexcept', - 'exceptions_rtti' -] +configurations = ['noexcept', 'exceptions_rtti'] -@pytest.mark.esp32 -@pytest.mark.esp32c3 @pytest.mark.generic @pytest.mark.parametrize('config', configurations, indirect=True) +@idf_parametrize('target', ['esp32', 'esp32c3'], indirect=['target']) def test_cxx_static_init_non_pod(dut: Dut) -> None: dut.run_all_single_board_cases(name=['can use static initializers for non-POD types']) -@pytest.mark.esp32 -@pytest.mark.esp32c3 @pytest.mark.generic @pytest.mark.parametrize('config', configurations, indirect=True) +@idf_parametrize('target', ['esp32', 'esp32c3'], indirect=['target']) def test_cxx_misc(dut: Dut) -> None: dut.run_all_single_board_cases(group='misc') -@pytest.mark.esp32 -@pytest.mark.esp32c3 @pytest.mark.generic @pytest.mark.parametrize('config', configurations, indirect=True) +@idf_parametrize('target', ['esp32', 'esp32c3'], indirect=['target']) def test_cxx_stack_smash(dut: Dut) -> None: dut.expect_exact('Press ENTER to see the list of tests') - dut.write('\"stack smashing protection CXX\"') + dut.write('"stack smashing protection CXX"') dut.expect_exact('Stack smashing protect failure!') dut.expect_exact('Rebooting...') diff --git a/components/cxx/test_apps/rtti/pytest_cxx_rtti.py b/components/cxx/test_apps/rtti/pytest_cxx_rtti.py index a5217c66d7..40ec38cbd0 100644 --- a/components/cxx/test_apps/rtti/pytest_cxx_rtti.py +++ b/components/cxx/test_apps/rtti/pytest_cxx_rtti.py @@ -1,12 +1,11 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 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_cxx_rtti(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/driver/test_apps/dac_test_apps/legacy_dac_driver/pytest_legacy_dac.py b/components/driver/test_apps/dac_test_apps/legacy_dac_driver/pytest_legacy_dac.py index 89e8486cd4..5e4f4baf3c 100644 --- a/components/driver/test_apps/dac_test_apps/legacy_dac_driver/pytest_legacy_dac.py +++ b/components/driver/test_apps/dac_test_apps/legacy_dac_driver/pytest_legacy_dac.py @@ -1,12 +1,10 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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 @pytest.mark.parametrize( 'config', @@ -15,5 +13,6 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize('target', ['esp32', 'esp32s2'], indirect=['target']) def test_legacy_dac(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/pytest_legacy_i2s_adc_dac.py b/components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/pytest_legacy_i2s_adc_dac.py index 59b4de2b1e..a7332243db 100644 --- a/components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/pytest_legacy_i2s_adc_dac.py +++ b/components/driver/test_apps/i2s_test_apps/legacy_i2s_adc_dac/pytest_legacy_i2s_adc_dac.py @@ -1,11 +1,10 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 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.esp32 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -14,6 +13,7 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_i2s_adc_dac(dut: Dut) -> None: # ADC_DMA_read test takes more than 30 sec dut.run_all_single_board_cases(timeout=60) diff --git a/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/pytest_legacy_i2s.py b/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/pytest_legacy_i2s.py index bb70f8ee6a..76d2a0d1ad 100644 --- a/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/pytest_legacy_i2s.py +++ b/components/driver/test_apps/i2s_test_apps/legacy_i2s_driver/pytest_legacy_i2s.py @@ -1,18 +1,10 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 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.esp32 -@pytest.mark.esp32s2 -@pytest.mark.esp32c3 -@pytest.mark.esp32c5 -@pytest.mark.esp32s3 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 -@pytest.mark.esp32c61 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -21,5 +13,10 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize( + 'target', + ['esp32', 'esp32s2', 'esp32c3', 'esp32c5', 'esp32s3', 'esp32c6', 'esp32h2', 'esp32p4', 'esp32c61'], + indirect=['target'], +) def test_legacy_i2s(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/driver/test_apps/legacy_adc_driver/pytest_legacy_adc.py b/components/driver/test_apps/legacy_adc_driver/pytest_legacy_adc.py index 064d9449ab..a7acc58b25 100644 --- a/components/driver/test_apps/legacy_adc_driver/pytest_legacy_adc.py +++ b/components/driver/test_apps/legacy_adc_driver/pytest_legacy_adc.py @@ -1,17 +1,10 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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.esp32s3 -@pytest.mark.esp32c3 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32c5 -@pytest.mark.esp32p4 @pytest.mark.adc @pytest.mark.parametrize( 'config', @@ -20,11 +13,15 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize( + 'target', + ['esp32', 'esp32s2', 'esp32s3', 'esp32c3', 'esp32c6', 'esp32h2', 'esp32c5', 'esp32p4'], + indirect=['target'], +) def test_legacy_adc(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32c2 @pytest.mark.adc @pytest.mark.xtal_26mhz @pytest.mark.parametrize( @@ -34,5 +31,6 @@ def test_legacy_adc(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32c2'], indirect=['target']) def test_legacy_adc_esp32c2_xtal_26mhz(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/driver/test_apps/legacy_mcpwm_driver/pytest_legacy_mcpwm.py b/components/driver/test_apps/legacy_mcpwm_driver/pytest_legacy_mcpwm.py index a8a9e25bd1..b415ffed0a 100644 --- a/components/driver/test_apps/legacy_mcpwm_driver/pytest_legacy_mcpwm.py +++ b/components/driver/test_apps/legacy_mcpwm_driver/pytest_legacy_mcpwm.py @@ -1,15 +1,10 @@ -# 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 pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32 -@pytest.mark.esp32s3 -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -18,5 +13,6 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize('target', ['esp32', 'esp32s3', 'esp32c5', 'esp32c6', 'esp32h2', 'esp32p4'], indirect=['target']) def test_legacy_mcpwm(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/driver/test_apps/legacy_pcnt_driver/pytest_legacy_pcnt.py b/components/driver/test_apps/legacy_pcnt_driver/pytest_legacy_pcnt.py index 46eddeb18e..8d2045f4eb 100644 --- a/components/driver/test_apps/legacy_pcnt_driver/pytest_legacy_pcnt.py +++ b/components/driver/test_apps/legacy_pcnt_driver/pytest_legacy_pcnt.py @@ -1,16 +1,10 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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.esp32s3 -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -19,5 +13,8 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize( + 'target', ['esp32', 'esp32s2', 'esp32s3', 'esp32c5', 'esp32c6', 'esp32h2', 'esp32p4'], indirect=['target'] +) def test_legacy_pcnt(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=240) diff --git a/components/driver/test_apps/legacy_rmt_driver/pytest_legacy_rmt_driver.py b/components/driver/test_apps/legacy_rmt_driver/pytest_legacy_rmt_driver.py index 654b4a06b1..6512651cfa 100644 --- a/components/driver/test_apps/legacy_rmt_driver/pytest_legacy_rmt_driver.py +++ b/components/driver/test_apps/legacy_rmt_driver/pytest_legacy_rmt_driver.py @@ -1,20 +1,22 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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.esp32s3 -@pytest.mark.esp32c3 -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 @pytest.mark.generic -@pytest.mark.parametrize('config', [ - 'release', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'release', + ], + indirect=True, +) +@idf_parametrize( + 'target', + ['esp32', 'esp32s2', 'esp32s3', 'esp32c3', 'esp32c5', 'esp32c6', 'esp32h2', 'esp32p4'], + indirect=['target'], +) def test_legacy_rmt(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=120) diff --git a/components/driver/test_apps/legacy_rtc_temp_driver/pytest_legacy_temp_sensor_driver.py b/components/driver/test_apps/legacy_rtc_temp_driver/pytest_legacy_temp_sensor_driver.py index 85359b8ca7..47646ffe48 100644 --- a/components/driver/test_apps/legacy_rtc_temp_driver/pytest_legacy_temp_sensor_driver.py +++ b/components/driver/test_apps/legacy_rtc_temp_driver/pytest_legacy_temp_sensor_driver.py @@ -1,21 +1,22 @@ -# SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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.esp32s2 -@pytest.mark.esp32c3 -@pytest.mark.esp32s3 -@pytest.mark.esp32c2 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 -@pytest.mark.esp32c5 -@pytest.mark.esp32c61 @pytest.mark.generic -@pytest.mark.parametrize('config', [ - 'release', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'release', + ], + indirect=True, +) +@idf_parametrize( + 'target', + ['esp32s2', 'esp32c3', 'esp32s3', 'esp32c2', 'esp32c6', 'esp32h2', 'esp32p4', 'esp32c5', 'esp32c61'], + indirect=['target'], +) def test_legacy_temp_sensor_driver(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=120) diff --git a/components/driver/test_apps/legacy_sigma_delta_driver/pytest_legacy_sigma_delta.py b/components/driver/test_apps/legacy_sigma_delta_driver/pytest_legacy_sigma_delta.py index 30b41ab229..9a6b264285 100644 --- a/components/driver/test_apps/legacy_sigma_delta_driver/pytest_legacy_sigma_delta.py +++ b/components/driver/test_apps/legacy_sigma_delta_driver/pytest_legacy_sigma_delta.py @@ -1,23 +1,22 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded_idf import IdfDut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32 -@pytest.mark.esp32c3 -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32p4 @pytest.mark.generic @pytest.mark.parametrize( 'config', [ 'release', ], - indirect=True) + indirect=True, +) +@idf_parametrize( + 'target', + ['esp32', 'esp32c3', 'esp32c5', 'esp32c6', 'esp32h2', 'esp32s2', 'esp32s3', 'esp32p4'], + indirect=['target'], +) def test_legacy_sigma_delta(dut: IdfDut) -> None: dut.run_all_single_board_cases(group='sigma_delta') diff --git a/components/driver/test_apps/legacy_timer_driver/pytest_legacy_timer_driver.py b/components/driver/test_apps/legacy_timer_driver/pytest_legacy_timer_driver.py index 726f05adc7..503d591c83 100644 --- a/components/driver/test_apps/legacy_timer_driver/pytest_legacy_timer_driver.py +++ b/components/driver/test_apps/legacy_timer_driver/pytest_legacy_timer_driver.py @@ -1,13 +1,18 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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.supported_targets @pytest.mark.generic -@pytest.mark.parametrize('config', [ - 'release', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'release', + ], + indirect=True, +) +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_legacy_timer_driver(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=120) diff --git a/components/driver/test_apps/touch_sensor_v1/pytest_touch_sensor_v1.py b/components/driver/test_apps/touch_sensor_v1/pytest_touch_sensor_v1.py index 368fa6cca2..edb264bb7d 100644 --- a/components/driver/test_apps/touch_sensor_v1/pytest_touch_sensor_v1.py +++ b/components/driver/test_apps/touch_sensor_v1/pytest_touch_sensor_v1.py @@ -1,10 +1,10 @@ -# 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 pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -13,5 +13,6 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_touch_sensor_v1(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=60) diff --git a/components/driver/test_apps/touch_sensor_v2/pytest_touch_sensor_v2.py b/components/driver/test_apps/touch_sensor_v2/pytest_touch_sensor_v2.py index 3f03441018..1c0ff4364d 100644 --- a/components/driver/test_apps/touch_sensor_v2/pytest_touch_sensor_v2.py +++ b/components/driver/test_apps/touch_sensor_v2/pytest_touch_sensor_v2.py @@ -1,11 +1,10 @@ -# 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 pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -14,5 +13,6 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize('target', ['esp32s2', 'esp32s3'], indirect=['target']) def test_touch_sensor_v2(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=120) diff --git a/components/driver/test_apps/twai/pytest_twai.py b/components/driver/test_apps/twai/pytest_twai.py index 9113bb1a6e..8e73a13167 100644 --- a/components/driver/test_apps/twai/pytest_twai.py +++ b/components/driver/test_apps/twai/pytest_twai.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import logging import subprocess @@ -8,15 +8,9 @@ import pytest from can import Bus from can import Message from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32 -@pytest.mark.esp32c3 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32p4 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -25,6 +19,9 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize( + 'target', ['esp32', 'esp32c3', 'esp32c6', 'esp32h2', 'esp32s2', 'esp32s3', 'esp32p4'], indirect=['target'] +) def test_twai_self(dut: Dut) -> None: dut.run_all_single_board_cases(group='twai-loop-back') @@ -36,18 +33,11 @@ def fixture_create_socket_can() -> Bus: stop_command = 'sudo ip link set can0 down' subprocess.run(start_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) bus = Bus(interface='socketcan', channel='can0', bitrate=250000) - yield bus # test invoked here + yield bus # test invoked here bus.shutdown() subprocess.run(stop_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) -@pytest.mark.esp32 -@pytest.mark.esp32c3 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32p4 @pytest.mark.twai_std @pytest.mark.parametrize( 'config', @@ -56,6 +46,9 @@ def fixture_create_socket_can() -> Bus: ], indirect=True, ) +@idf_parametrize( + 'target', ['esp32', 'esp32c3', 'esp32c6', 'esp32h2', 'esp32s2', 'esp32s3', 'esp32p4'], indirect=['target'] +) def test_twai_listen_only(dut: Dut, socket_can: Bus) -> None: dut.serial.hard_reset() dut.expect_exact('Press ENTER to see the list of tests') @@ -75,13 +68,6 @@ def test_twai_listen_only(dut: Dut, socket_can: Bus) -> None: dut.expect_unity_test_output() -@pytest.mark.esp32 -@pytest.mark.esp32c3 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32p4 @pytest.mark.twai_std @pytest.mark.parametrize( 'config', @@ -90,6 +76,9 @@ def test_twai_listen_only(dut: Dut, socket_can: Bus) -> None: ], indirect=True, ) +@idf_parametrize( + 'target', ['esp32', 'esp32c3', 'esp32c6', 'esp32h2', 'esp32s2', 'esp32s3', 'esp32p4'], indirect=['target'] +) def test_twai_remote_request(dut: Dut, socket_can: Bus) -> None: dut.serial.hard_reset() dut.expect_exact('Press ENTER to see the list of tests') diff --git a/components/efuse/test_apps/pytest_efuse.py b/components/efuse/test_apps/pytest_efuse.py index f746d5cd98..6d823e62cb 100644 --- a/components/efuse/test_apps/pytest_efuse.py +++ b/components/efuse/test_apps/pytest_efuse.py @@ -1,24 +1,27 @@ -# 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 pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.supported_targets -@pytest.mark.temp_skip_ci(targets=['esp32s2', 'esp32s3'], reason='eFuse for S2 and S3 is similar to the C3 chip, so testing on C3 is enough') +@pytest.mark.temp_skip_ci( + targets=['esp32s2', 'esp32s3'], reason='eFuse for S2 and S3 is similar to the C3 chip, so testing on C3 is enough' +) @pytest.mark.generic +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_efuse(dut: Dut) -> None: dut.run_all_single_board_cases() @pytest.mark.qemu -@pytest.mark.esp32 @pytest.mark.host_test +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_efuse_qemu(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.linux @pytest.mark.host_test +@idf_parametrize('target', ['linux'], indirect=['target']) def test_efuse_linux(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=60) diff --git a/components/esp-tls/test_apps/pytest_esp-tls.py b/components/esp-tls/test_apps/pytest_esp-tls.py index 37acd0be3e..553912ef8b 100644 --- a/components/esp-tls/test_apps/pytest_esp-tls.py +++ b/components/esp-tls/test_apps/pytest_esp-tls.py @@ -1,10 +1,11 @@ -# 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 pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.supported_targets @pytest.mark.generic +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_esp_tls(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_adc/test_apps/adc/pytest_adc.py b/components/esp_adc/test_apps/adc/pytest_adc.py index 94133182ae..365b9ad1c5 100644 --- a/components/esp_adc/test_apps/adc/pytest_adc.py +++ b/components/esp_adc/test_apps/adc/pytest_adc.py @@ -1,29 +1,22 @@ -# SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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.esp32s3 -@pytest.mark.esp32c3 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32c5 -@pytest.mark.esp32p4 @pytest.mark.adc -@pytest.mark.parametrize('config', [ - 'iram_safe', - 'release', - 'pm_enable' -], indirect=True) +@pytest.mark.parametrize('config', ['iram_safe', 'release', 'pm_enable'], indirect=True) +@idf_parametrize( + 'target', + ['esp32', 'esp32s2', 'esp32s3', 'esp32c3', 'esp32c6', 'esp32h2', 'esp32c5', 'esp32p4'], + indirect=['target'], +) def test_adc(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=120, reset=True) # No PM test, as C2 doesn't support ADC continuous mode -@pytest.mark.esp32c2 @pytest.mark.adc @pytest.mark.xtal_26mhz @pytest.mark.parametrize( @@ -34,19 +27,19 @@ def test_adc(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32c2'], indirect=['target']) def test_adc_esp32c2_xtal_26mhz(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=120, reset=True) -@pytest.mark.esp32s3 -@pytest.mark.esp32c3 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32c5 -@pytest.mark.esp32p4 @pytest.mark.adc -@pytest.mark.parametrize('config', [ - 'gdma_iram_safe', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'gdma_iram_safe', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32s3', 'esp32c3', 'esp32c6', 'esp32h2', 'esp32c5', 'esp32p4'], indirect=['target']) def test_adc_gdma_iram(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=120, reset=True) diff --git a/components/esp_app_format/test_apps/pytest_esp_app_format.py b/components/esp_app_format/test_apps/pytest_esp_app_format.py index 1c0a3e90d3..843ceb825a 100644 --- a/components/esp_app_format/test_apps/pytest_esp_app_format.py +++ b/components/esp_app_format/test_apps/pytest_esp_app_format.py @@ -1,18 +1,17 @@ -# 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 pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32 -@pytest.mark.esp32s2 -@pytest.mark.esp32c3 @pytest.mark.generic +@idf_parametrize('target', ['esp32', 'esp32s2', 'esp32c3'], indirect=['target']) def test_esp_app_format(dut: Dut) -> None: dut.expect_unity_test_output() -@pytest.mark.linux @pytest.mark.host_test +@idf_parametrize('target', ['linux'], indirect=['target']) def test_esp_app_format_linux(dut: Dut) -> None: dut.expect_unity_test_output() diff --git a/components/esp_bootloader_format/test_apps/pytest_esp_bootloader_format.py b/components/esp_bootloader_format/test_apps/pytest_esp_bootloader_format.py index fa4d7a7f3a..43891cea30 100644 --- a/components/esp_bootloader_format/test_apps/pytest_esp_bootloader_format.py +++ b/components/esp_bootloader_format/test_apps/pytest_esp_bootloader_format.py @@ -1,10 +1,11 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-2025 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.generic +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_esp_bootloader_format(dut: Dut) -> None: dut.expect_unity_test_output() diff --git a/components/esp_common/test_apps/esp_common/pytest_esp_common.py b/components/esp_common/test_apps/esp_common/pytest_esp_common.py index aa47cf812f..726657be42 100644 --- a/components/esp_common/test_apps/esp_common/pytest_esp_common.py +++ b/components/esp_common/test_apps/esp_common/pytest_esp_common.py @@ -1,30 +1,24 @@ -# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 from typing import Any import pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize @pytest.mark.generic -@pytest.mark.supported_targets @pytest.mark.parametrize( 'config', - [ - 'default' - ], + ['default'], indirect=True, ) +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_esp_common(dut: Dut) -> None: dut.run_all_single_board_cases() # psram noinit attr tests with psram enabled -@pytest.mark.esp32 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32p4 -@pytest.mark.esp32c5 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -33,35 +27,24 @@ def test_esp_common(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32', 'esp32s2', 'esp32s3', 'esp32p4', 'esp32c5'], indirect=['target']) def test_esp_attr_psram_noinit(dut: Dut) -> None: dut.run_all_single_board_cases() # psram noinit memory tests with psram enabled -@pytest.mark.esp32 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32p4 -@pytest.mark.esp32c5 @pytest.mark.generic -@pytest.mark.supported_targets @pytest.mark.parametrize( 'config', - [ - 'psram_noinit' - ], + ['psram_noinit'], indirect=True, ) +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_esp_attr_psram_noinit_multiple_stages(case_tester: Any) -> None: case_tester.run_all_multi_stage_cases() # psram attr tests with psram enabled -@pytest.mark.esp32 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32p4 -@pytest.mark.esp32c5 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -70,47 +53,42 @@ def test_esp_attr_psram_noinit_multiple_stages(case_tester: Any) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32', 'esp32s2', 'esp32s3', 'esp32p4', 'esp32c5'], indirect=['target']) def test_esp_attr_psram(dut: Dut) -> None: dut.run_all_single_board_cases() # psram attr tests with xip_psram -@pytest.mark.esp32s2 @pytest.mark.generic @pytest.mark.parametrize( 'config', - [ - 'xip_psram_esp32s2' - ], + ['xip_psram_esp32s2'], indirect=True, ) +@idf_parametrize('target', ['esp32s2'], indirect=['target']) def test_esp_attr_xip_psram_esp32s2(dut: Dut) -> None: dut.run_all_single_board_cases() # psram attr tests with xip_psram -@pytest.mark.esp32s3 @pytest.mark.generic @pytest.mark.parametrize( 'config', - [ - 'xip_psram_esp32s3' - ], + ['xip_psram_esp32s3'], indirect=True, ) +@idf_parametrize('target', ['esp32s3'], indirect=['target']) def test_esp_attr_xip_psram_esp32s3(dut: Dut) -> None: dut.run_all_single_board_cases() # psram attr tests with xip_psram -@pytest.mark.esp32p4 @pytest.mark.generic @pytest.mark.parametrize( 'config', - [ - 'xip_psram_esp32p4' - ], + ['xip_psram_esp32p4'], indirect=True, ) +@idf_parametrize('target', ['esp32p4'], indirect=['target']) def test_esp_attr_xip_psram_esp32p4(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_driver_ana_cmpr/test_apps/analog_comparator/pytest_ana_cmpr.py b/components/esp_driver_ana_cmpr/test_apps/analog_comparator/pytest_ana_cmpr.py index d9eeb38699..3efcc580a0 100644 --- a/components/esp_driver_ana_cmpr/test_apps/analog_comparator/pytest_ana_cmpr.py +++ b/components/esp_driver_ana_cmpr/test_apps/analog_comparator/pytest_ana_cmpr.py @@ -1,13 +1,10 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-2025 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.esp32h2 -@pytest.mark.esp32p4 -@pytest.mark.esp32c5 -@pytest.mark.esp32c61 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -17,5 +14,6 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize('target', ['esp32h2', 'esp32p4', 'esp32c5', 'esp32c61'], indirect=['target']) def test_ana_cmpr(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_driver_bitscrambler/test_apps/bitscrambler/pytest_bitscrambler.py b/components/esp_driver_bitscrambler/test_apps/bitscrambler/pytest_bitscrambler.py index d73d1fed4b..ba6490743f 100644 --- a/components/esp_driver_bitscrambler/test_apps/bitscrambler/pytest_bitscrambler.py +++ b/components/esp_driver_bitscrambler/test_apps/bitscrambler/pytest_bitscrambler.py @@ -2,10 +2,10 @@ # 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.esp32c5 @pytest.mark.generic +@idf_parametrize('target', ['esp32p4', 'esp32c5'], indirect=['target']) def test_bitscrambler(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_driver_cam/test_apps/csi/pytest_csi.py b/components/esp_driver_cam/test_apps/csi/pytest_csi.py index 07510eac36..3be2c9557f 100644 --- a/components/esp_driver_cam/test_apps/csi/pytest_csi.py +++ b/components/esp_driver_cam/test_apps/csi/pytest_csi.py @@ -1,10 +1,11 @@ -# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2024-2025 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_csi(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_driver_cam/test_apps/dvp/pytest_dvp.py b/components/esp_driver_cam/test_apps/dvp/pytest_dvp.py index 139f1c0694..2c6f832922 100644 --- a/components/esp_driver_cam/test_apps/dvp/pytest_dvp.py +++ b/components/esp_driver_cam/test_apps/dvp/pytest_dvp.py @@ -1,10 +1,11 @@ -# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2024-2025 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_dvp(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_driver_cam/test_apps/isp_dvp/pytest_isp_dvp.py b/components/esp_driver_cam/test_apps/isp_dvp/pytest_isp_dvp.py index a9922987c5..211e25d4de 100644 --- a/components/esp_driver_cam/test_apps/isp_dvp/pytest_isp_dvp.py +++ b/components/esp_driver_cam/test_apps/isp_dvp/pytest_isp_dvp.py @@ -1,10 +1,11 @@ -# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2024-2025 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_isp_dvp(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_driver_dac/test_apps/dac/pytest_dac.py b/components/esp_driver_dac/test_apps/dac/pytest_dac.py index 3caf0085f0..5a282e1cd8 100644 --- a/components/esp_driver_dac/test_apps/dac/pytest_dac.py +++ b/components/esp_driver_dac/test_apps/dac/pytest_dac.py @@ -1,12 +1,10 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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 @pytest.mark.parametrize( 'config', @@ -16,5 +14,6 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize('target', ['esp32', 'esp32s2'], indirect=['target']) def test_dac(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_driver_gpio/test_apps/gpio/pytest_gpio.py b/components/esp_driver_gpio/test_apps/gpio/pytest_gpio.py index bb0a48d5c4..008e15003d 100644 --- a/components/esp_driver_gpio/test_apps/gpio/pytest_gpio.py +++ b/components/esp_driver_gpio/test_apps/gpio/pytest_gpio.py @@ -1,7 +1,8 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded_idf import IdfDut +from pytest_embedded_idf.utils import idf_parametrize CONFIGS = [ 'iram_safe', @@ -9,21 +10,17 @@ CONFIGS = [ ] -@pytest.mark.supported_targets @pytest.mark.generic @pytest.mark.parametrize('config', CONFIGS, indirect=True) +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_gpio(dut: IdfDut) -> None: dut.run_all_single_board_cases(group='gpio') -@pytest.mark.esp32 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 -@pytest.mark.esp32c5 @pytest.mark.generic @pytest.mark.parametrize('config', CONFIGS, indirect=True) +@idf_parametrize( + 'target', ['esp32', 'esp32s2', 'esp32s3', 'esp32c6', 'esp32h2', 'esp32p4', 'esp32c5'], indirect=['target'] +) def test_rtc_io(dut: IdfDut) -> None: dut.run_all_single_board_cases(group='rtcio') diff --git a/components/esp_driver_gpio/test_apps/gpio_extensions/pytest_gpio_extensions.py b/components/esp_driver_gpio/test_apps/gpio_extensions/pytest_gpio_extensions.py index a92700388d..a6cb431bf5 100644 --- a/components/esp_driver_gpio/test_apps/gpio_extensions/pytest_gpio_extensions.py +++ b/components/esp_driver_gpio/test_apps/gpio_extensions/pytest_gpio_extensions.py @@ -1,7 +1,8 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded_idf import IdfDut +from pytest_embedded_idf.utils import idf_parametrize CONFIGS = [ 'iram_safe', @@ -9,31 +10,23 @@ CONFIGS = [ ] -@pytest.mark.esp32c2 -@pytest.mark.esp32c3 -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32c61 -@pytest.mark.esp32h2 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32p4 @pytest.mark.generic @pytest.mark.parametrize('config', CONFIGS, indirect=True) +@idf_parametrize( + 'target', + ['esp32c2', 'esp32c3', 'esp32c5', 'esp32c6', 'esp32c61', 'esp32h2', 'esp32s2', 'esp32s3', 'esp32p4'], + indirect=['target'], +) def test_gpio_filter(dut: IdfDut) -> None: dut.run_all_single_board_cases(group='gpio_filter') -@pytest.mark.esp32c2 -@pytest.mark.esp32c3 -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32c61 -@pytest.mark.esp32h2 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32p4 @pytest.mark.generic @pytest.mark.parametrize('config', CONFIGS, indirect=True) +@idf_parametrize( + 'target', + ['esp32c2', 'esp32c3', 'esp32c5', 'esp32c6', 'esp32c61', 'esp32h2', 'esp32s2', 'esp32s3', 'esp32p4'], + indirect=['target'], +) def test_dedic_gpio(dut: IdfDut) -> None: dut.run_all_single_board_cases(group='dedic_gpio') diff --git a/components/esp_driver_gptimer/test_apps/gptimer/pytest_gptimer.py b/components/esp_driver_gptimer/test_apps/gptimer/pytest_gptimer.py index 178619615c..f87e448e5e 100644 --- a/components/esp_driver_gptimer/test_apps/gptimer/pytest_gptimer.py +++ b/components/esp_driver_gptimer/test_apps/gptimer/pytest_gptimer.py @@ -1,11 +1,10 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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.supported_targets @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -15,11 +14,11 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_gptimer(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32c2 @pytest.mark.generic @pytest.mark.xtal_26mhz @pytest.mark.parametrize( @@ -29,5 +28,6 @@ def test_gptimer(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32c2'], indirect=['target']) def test_gptimer_esp32c2_xtal_26mhz(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_driver_i2c/test_apps/i2c_test_apps/pytest_i2c.py b/components/esp_driver_i2c/test_apps/i2c_test_apps/pytest_i2c.py index fbcfd363e9..de7106b1fe 100644 --- a/components/esp_driver_i2c/test_apps/i2c_test_apps/pytest_i2c.py +++ b/components/esp_driver_i2c/test_apps/i2c_test_apps/pytest_i2c.py @@ -2,9 +2,9 @@ # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.supported_targets @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -14,30 +14,40 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_i2c(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32 -@pytest.mark.esp32c3 -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 @pytest.mark.generic_multi_device @pytest.mark.parametrize( 'count, config', [ - (2, 'defaults',), - (2, 'release',), - (2, 'iram_safe',), - (2, 'slave_v2',), + ( + 2, + 'defaults', + ), + ( + 2, + 'release', + ), + ( + 2, + 'iram_safe', + ), + ( + 2, + 'slave_v2', + ), ], - indirect=True + indirect=True, ) -def test_i2c_multi_device(case_tester) -> None: # type: ignore +@idf_parametrize( + 'target', + ['esp32', 'esp32c3', 'esp32c5', 'esp32c6', 'esp32h2', 'esp32p4', 'esp32s2', 'esp32s3'], + indirect=['target'], +) +def test_i2c_multi_device(case_tester) -> None: # type: ignore for case in case_tester.test_menu: if case.attributes.get('test_env', 'generic_multi_device') == 'generic_multi_device': case_tester.run_multi_dev_case(case=case, reset=True) diff --git a/components/esp_driver_i2s/test_apps/i2s/pytest_i2s.py b/components/esp_driver_i2s/test_apps/i2s/pytest_i2s.py index 138769c594..2f7ac561f3 100644 --- a/components/esp_driver_i2s/test_apps/i2s/pytest_i2s.py +++ b/components/esp_driver_i2s/test_apps/i2s/pytest_i2s.py @@ -1,18 +1,10 @@ -# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 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.esp32 -@pytest.mark.esp32s2 -@pytest.mark.esp32c3 -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32s3 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 -@pytest.mark.esp32c61 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -22,5 +14,10 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize( + 'target', + ['esp32', 'esp32s2', 'esp32c3', 'esp32c5', 'esp32c6', 'esp32s3', 'esp32h2', 'esp32p4', 'esp32c61'], + indirect=['target'], +) def test_i2s(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_driver_i2s/test_apps/i2s_multi_dev/pytest_i2s_multi_dev.py b/components/esp_driver_i2s/test_apps/i2s_multi_dev/pytest_i2s_multi_dev.py index 000bb65e39..06ba3a2bfe 100644 --- a/components/esp_driver_i2s/test_apps/i2s_multi_dev/pytest_i2s_multi_dev.py +++ b/components/esp_driver_i2s/test_apps/i2s_multi_dev/pytest_i2s_multi_dev.py @@ -1,17 +1,17 @@ -# 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 pytest +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32s3 -@pytest.mark.esp32c3 -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 @pytest.mark.generic_multi_device -@pytest.mark.parametrize('count', [ - 2, -], indirect=True) +@pytest.mark.parametrize( + 'count', + [ + 2, + ], + indirect=True, +) +@idf_parametrize('target', ['esp32s3', 'esp32c3', 'esp32c5', 'esp32c6', 'esp32h2', 'esp32p4'], indirect=['target']) def test_i2s_multi_dev(case_tester) -> None: # type: ignore case_tester.run_all_multi_dev_cases(reset=True, timeout=30) diff --git a/components/esp_driver_i2s/test_apps/lp_i2s/pytest_lp_i2s.py b/components/esp_driver_i2s/test_apps/lp_i2s/pytest_lp_i2s.py index 2c7e4ffa8a..db2527a9ec 100644 --- a/components/esp_driver_i2s/test_apps/lp_i2s/pytest_lp_i2s.py +++ b/components/esp_driver_i2s/test_apps/lp_i2s/pytest_lp_i2s.py @@ -1,10 +1,11 @@ -# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2024-2025 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.esp32p4 @pytest.mark.lp_i2s +@idf_parametrize('target', ['esp32p4'], indirect=['target']) def test_lp_i2s(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=200) diff --git a/components/esp_driver_jpeg/test_apps/jpeg_test_apps/pytest_jpeg.py b/components/esp_driver_jpeg/test_apps/jpeg_test_apps/pytest_jpeg.py index cdd75ead6a..2ee2e26ae3 100644 --- a/components/esp_driver_jpeg/test_apps/jpeg_test_apps/pytest_jpeg.py +++ b/components/esp_driver_jpeg/test_apps/jpeg_test_apps/pytest_jpeg.py @@ -1,10 +1,10 @@ -# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2024-2025 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 @pytest.mark.parametrize( 'config', @@ -13,5 +13,6 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize('target', ['esp32p4'], indirect=['target']) def test_jpeg(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_driver_ledc/test_apps/ledc/pytest_ledc.py b/components/esp_driver_ledc/test_apps/ledc/pytest_ledc.py index 22687a67fc..b3e6f5052e 100644 --- a/components/esp_driver_ledc/test_apps/ledc/pytest_ledc.py +++ b/components/esp_driver_ledc/test_apps/ledc/pytest_ledc.py @@ -1,12 +1,11 @@ -# SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded_idf import IdfDut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.supported_targets -@pytest.mark.temp_skip_ci(targets=['esp32s3'], - reason='skip due to duplication with test_ledc_psram') +@pytest.mark.temp_skip_ci(targets=['esp32s3'], reason='skip due to duplication with test_ledc_psram') @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -16,11 +15,11 @@ from pytest_embedded_idf import IdfDut ], indirect=True, ) +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_ledc(dut: IdfDut) -> None: dut.run_all_single_board_cases(reset=True) -@pytest.mark.esp32s3 @pytest.mark.octal_psram @pytest.mark.parametrize( 'config', @@ -30,21 +29,29 @@ def test_ledc(dut: IdfDut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32s3'], indirect=['target']) def test_ledc_psram(dut: IdfDut) -> None: dut.run_all_single_board_cases(reset=True) -@pytest.mark.supported_targets -@pytest.mark.temp_skip_ci(targets=['esp32s3', 'esp32c61'], - reason='s3 multi device runner has no psram, c61 lack of runner IDF-10949') +@pytest.mark.temp_skip_ci( + targets=['esp32s3', 'esp32c61'], reason='s3 multi device runner has no psram, c61 lack of runner IDF-10949' +) @pytest.mark.generic_multi_device @pytest.mark.parametrize( 'count, config', [ - (2, 'iram_safe',), - (2, 'release',), + ( + 2, + 'iram_safe', + ), + ( + 2, + 'release', + ), ], - indirect=True + indirect=True, ) -def test_ledc_multi_device(case_tester) -> None: # type: ignore +@idf_parametrize('target', ['supported_targets'], indirect=['target']) +def test_ledc_multi_device(case_tester) -> None: # type: ignore case_tester.run_all_multi_dev_cases(reset=True) diff --git a/components/esp_driver_mcpwm/test_apps/mcpwm/pytest_mcpwm.py b/components/esp_driver_mcpwm/test_apps/mcpwm/pytest_mcpwm.py index 8fde6c768c..e200d22e5c 100644 --- a/components/esp_driver_mcpwm/test_apps/mcpwm/pytest_mcpwm.py +++ b/components/esp_driver_mcpwm/test_apps/mcpwm/pytest_mcpwm.py @@ -1,15 +1,10 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 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.esp32s3 -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -19,5 +14,6 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize('target', ['esp32', 'esp32s3', 'esp32c5', 'esp32c6', 'esp32h2', 'esp32p4'], indirect=['target']) def test_mcpwm(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_driver_parlio/test_apps/parlio/pytest_parlio_unity.py b/components/esp_driver_parlio/test_apps/parlio/pytest_parlio_unity.py index 3db44388b6..9150b19700 100644 --- a/components/esp_driver_parlio/test_apps/parlio/pytest_parlio_unity.py +++ b/components/esp_driver_parlio/test_apps/parlio/pytest_parlio_unity.py @@ -1,13 +1,10 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 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.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -17,5 +14,6 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize('target', ['esp32c5', 'esp32c6', 'esp32h2', 'esp32p4'], indirect=['target']) def test_parlio(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_driver_pcnt/test_apps/pulse_cnt/pytest_pulse_cnt.py b/components/esp_driver_pcnt/test_apps/pulse_cnt/pytest_pulse_cnt.py index 04566c1d5d..54290a9201 100644 --- a/components/esp_driver_pcnt/test_apps/pulse_cnt/pytest_pulse_cnt.py +++ b/components/esp_driver_pcnt/test_apps/pulse_cnt/pytest_pulse_cnt.py @@ -1,16 +1,10 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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.esp32s3 -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -20,5 +14,8 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize( + 'target', ['esp32', 'esp32s2', 'esp32s3', 'esp32c5', 'esp32c6', 'esp32h2', 'esp32p4'], indirect=['target'] +) def test_pulse_cnt(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_driver_ppa/test_apps/pytest_ppa.py b/components/esp_driver_ppa/test_apps/pytest_ppa.py index 534d32cee1..5622c6be44 100644 --- a/components/esp_driver_ppa/test_apps/pytest_ppa.py +++ b/components/esp_driver_ppa/test_apps/pytest_ppa.py @@ -1,10 +1,10 @@ -# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2024-2025 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 @pytest.mark.parametrize( 'config', @@ -13,5 +13,6 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize('target', ['esp32p4'], indirect=['target']) def test_ppa(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_driver_rmt/test_apps/rmt/pytest_rmt.py b/components/esp_driver_rmt/test_apps/rmt/pytest_rmt.py index 15f27cf1ac..4a9612aa79 100644 --- a/components/esp_driver_rmt/test_apps/rmt/pytest_rmt.py +++ b/components/esp_driver_rmt/test_apps/rmt/pytest_rmt.py @@ -1,16 +1,10 @@ -# SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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.esp32c3 -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -20,11 +14,13 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize( + 'target', ['esp32', 'esp32s2', 'esp32c3', 'esp32c5', 'esp32c6', 'esp32h2', 'esp32p4'], indirect=['target'] +) def test_rmt(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32s3 @pytest.mark.octal_psram @pytest.mark.parametrize( 'config', @@ -34,5 +30,6 @@ def test_rmt(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32s3'], indirect=['target']) def test_rmt_psram(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_driver_sdio/test_apps/sdio/sdio_common_tests/pytest_sdio.py b/components/esp_driver_sdio/test_apps/sdio/sdio_common_tests/pytest_sdio.py index 1e123bd929..5def5f9c29 100644 --- a/components/esp_driver_sdio/test_apps/sdio/sdio_common_tests/pytest_sdio.py +++ b/components/esp_driver_sdio/test_apps/sdio/sdio_common_tests/pytest_sdio.py @@ -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 os.path from typing import List @@ -16,8 +16,18 @@ def parameter_expand(existing_parameters: List[List[str]], value_list: List[str] return ret -esp32_32_param = [[f'{os.path.join(os.path.dirname(__file__), "host_sdmmc")}|{os.path.join(os.path.dirname(__file__), "sdio")}', 'esp32|esp32']] -esp32_c6_param = [[f'{os.path.join(os.path.dirname(__file__), "host_sdmmc")}|{os.path.join(os.path.dirname(__file__), "sdio")}', 'esp32|esp32c6']] +esp32_32_param = [ + [ + f'{os.path.join(os.path.dirname(__file__), "host_sdmmc")}|{os.path.join(os.path.dirname(__file__), "sdio")}', + 'esp32|esp32', + ] +] +esp32_c6_param = [ + [ + f'{os.path.join(os.path.dirname(__file__), "host_sdmmc")}|{os.path.join(os.path.dirname(__file__), "sdio")}', + 'esp32|esp32c6', + ] +] esp32_param_default = [pytest.param(*param) for param in parameter_expand(esp32_32_param, ['default|default'])] c6_param_default = [pytest.param(*param) for param in parameter_expand(esp32_c6_param, ['default|default'])] @@ -26,7 +36,7 @@ c6_param_retention = [pytest.param(*param) for param in parameter_expand(esp32_c # Normal tests -def test_sdio_flow(dut:Tuple[IdfDut, IdfDut]) -> None: +def test_sdio_flow(dut: Tuple[IdfDut, IdfDut]) -> None: dut[1].expect('Press ENTER to see the list of tests') dut[1].write('[sdio]') dut[1].expect('test_sdio: slave ready') @@ -38,24 +48,34 @@ def test_sdio_flow(dut:Tuple[IdfDut, IdfDut]) -> None: dut[0].expect_unity_test_output() -@pytest.mark.esp32c6 @pytest.mark.sdio_multidev_32_c6 -@pytest.mark.parametrize('count', [2,], indirect=True) +@pytest.mark.parametrize( + 'count', + [ + 2, + ], + indirect=True, +) @pytest.mark.parametrize('app_path, target, config', c6_param_default, indirect=True) -def test_sdio_esp32_esp32c6(dut:Tuple[IdfDut, IdfDut]) -> None: +def test_sdio_esp32_esp32c6(dut: Tuple[IdfDut, IdfDut]) -> None: test_sdio_flow(dut) -@pytest.mark.esp32 @pytest.mark.sdio_master_slave -@pytest.mark.parametrize('count', [2,], indirect=True) +@pytest.mark.parametrize( + 'count', + [ + 2, + ], + indirect=True, +) @pytest.mark.parametrize('app_path, target, config', esp32_param_default, indirect=True) -def test_sdio_esp32_esp32(dut:Tuple[IdfDut, IdfDut]) -> None: +def test_sdio_esp32_esp32(dut: Tuple[IdfDut, IdfDut]) -> None: test_sdio_flow(dut) # From host speed tests -def test_sdio_speed_frhost_flow(dut:Tuple[IdfDut, IdfDut], expected_4b_speed:int, expected_1b_speed:int) -> None: +def test_sdio_speed_frhost_flow(dut: Tuple[IdfDut, IdfDut], expected_4b_speed: int, expected_1b_speed: int) -> None: dut[1].expect('Press ENTER to see the list of tests') dut[1].write('"SDIO_Slave: test from host (Performance)"') dut[1].expect('test_sdio: slave ready') @@ -66,32 +86,42 @@ def test_sdio_speed_frhost_flow(dut:Tuple[IdfDut, IdfDut], expected_4b_speed:int dut[0].expect('Probe using SD 4-bit') res = dut[0].expect(r'Throughput: compensated (\d+)') frhost_speed_4bit = res.group(1).decode('utf8') - assert (int(frhost_speed_4bit) > expected_4b_speed) + assert int(frhost_speed_4bit) > expected_4b_speed dut[0].expect('Probe using SD 1-bit') res = dut[0].expect(r'Throughput: compensated (\d+)') frhost_speed_1bit = res.group(1).decode('utf8') - assert (int(frhost_speed_1bit) > expected_1b_speed) + assert int(frhost_speed_1bit) > expected_1b_speed -@pytest.mark.esp32c6 @pytest.mark.sdio_multidev_32_c6 -@pytest.mark.parametrize('count', [2,], indirect=True) +@pytest.mark.parametrize( + 'count', + [ + 2, + ], + indirect=True, +) @pytest.mark.parametrize('app_path, target, config', c6_param_default, indirect=True) -def test_sdio_speed_frhost_esp32_esp32c6(dut:Tuple[IdfDut, IdfDut]) -> None: +def test_sdio_speed_frhost_esp32_esp32c6(dut: Tuple[IdfDut, IdfDut]) -> None: test_sdio_speed_frhost_flow(dut, 10000, 4000) -@pytest.mark.esp32 @pytest.mark.sdio_master_slave -@pytest.mark.parametrize('count', [2,], indirect=True) +@pytest.mark.parametrize( + 'count', + [ + 2, + ], + indirect=True, +) @pytest.mark.parametrize('app_path, target, config', esp32_param_default, indirect=True) -def test_sdio_speed_frhost_esp32_esp32(dut:Tuple[IdfDut, IdfDut]) -> None: +def test_sdio_speed_frhost_esp32_esp32(dut: Tuple[IdfDut, IdfDut]) -> None: test_sdio_speed_frhost_flow(dut, 12200, 4000) # To host speed tests -def test_sdio_speed_tohost_flow(dut:Tuple[IdfDut, IdfDut], expected_4b_speed:int, expected_1b_speed:int) -> None: +def test_sdio_speed_tohost_flow(dut: Tuple[IdfDut, IdfDut], expected_4b_speed: int, expected_1b_speed: int) -> None: dut[1].expect('Press ENTER to see the list of tests') dut[1].write('"SDIO_Slave: test to host (Performance)"') dut[1].expect('test_sdio: slave ready') @@ -102,32 +132,42 @@ def test_sdio_speed_tohost_flow(dut:Tuple[IdfDut, IdfDut], expected_4b_speed:int dut[0].expect('Probe using SD 4-bit') res = dut[0].expect(r'Throughput: compensated (\d+)') tohost_speed_4bit = res.group(1).decode('utf8') - assert (int(tohost_speed_4bit) > expected_4b_speed) + assert int(tohost_speed_4bit) > expected_4b_speed dut[0].expect('Probe using SD 1-bit') res = dut[0].expect(r'Throughput: compensated (\d+)') tohost_speed_1bit = res.group(1).decode('utf8') - assert (int(tohost_speed_1bit) > expected_1b_speed) + assert int(tohost_speed_1bit) > expected_1b_speed -@pytest.mark.esp32c6 @pytest.mark.sdio_multidev_32_c6 -@pytest.mark.parametrize('count', [2,], indirect=True) +@pytest.mark.parametrize( + 'count', + [ + 2, + ], + indirect=True, +) @pytest.mark.parametrize('app_path, target, config', c6_param_default, indirect=True) -def test_sdio_speed_tohost_esp32_esp32c6(dut:Tuple[IdfDut, IdfDut]) -> None: +def test_sdio_speed_tohost_esp32_esp32c6(dut: Tuple[IdfDut, IdfDut]) -> None: test_sdio_speed_tohost_flow(dut, 9000, 4000) -@pytest.mark.esp32 @pytest.mark.sdio_master_slave -@pytest.mark.parametrize('count', [2,], indirect=True) +@pytest.mark.parametrize( + 'count', + [ + 2, + ], + indirect=True, +) @pytest.mark.parametrize('app_path, target, config', esp32_param_default, indirect=True) -def test_sdio_speed_tohost_esp32_esp32(dut:Tuple[IdfDut, IdfDut]) -> None: +def test_sdio_speed_tohost_esp32_esp32(dut: Tuple[IdfDut, IdfDut]) -> None: test_sdio_speed_tohost_flow(dut, 12200, 4000) # Retention tests -def test_sdio_retention(dut:Tuple[IdfDut, IdfDut]) -> None: +def test_sdio_retention(dut: Tuple[IdfDut, IdfDut]) -> None: dut[1].expect('Press ENTER to see the list of tests') dut[1].write('[sdio_retention]') dut[1].expect('test_sdio: slave ready') @@ -139,9 +179,14 @@ def test_sdio_retention(dut:Tuple[IdfDut, IdfDut]) -> None: dut[0].expect_unity_test_output() -@pytest.mark.esp32c6 @pytest.mark.sdio_multidev_32_c6 -@pytest.mark.parametrize('count', [2,], indirect=True) +@pytest.mark.parametrize( + 'count', + [ + 2, + ], + indirect=True, +) @pytest.mark.parametrize('app_path, target, config', c6_param_retention, indirect=True) -def test_sdio_retention_esp32_esp32c6(dut:Tuple[IdfDut, IdfDut]) -> None: +def test_sdio_retention_esp32_esp32c6(dut: Tuple[IdfDut, IdfDut]) -> None: test_sdio_retention(dut) diff --git a/components/esp_driver_sdm/test_apps/sigma_delta/pytest_sigma_delta.py b/components/esp_driver_sdm/test_apps/sigma_delta/pytest_sigma_delta.py index 0a464e7ab5..7f614064ab 100644 --- a/components/esp_driver_sdm/test_apps/sigma_delta/pytest_sigma_delta.py +++ b/components/esp_driver_sdm/test_apps/sigma_delta/pytest_sigma_delta.py @@ -1,7 +1,8 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded_idf import IdfDut +from pytest_embedded_idf.utils import idf_parametrize CONFIGS = [ 'iram_safe', @@ -9,16 +10,12 @@ CONFIGS = [ ] -@pytest.mark.esp32 -@pytest.mark.esp32c3 -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 @pytest.mark.generic @pytest.mark.parametrize('config', CONFIGS, indirect=True) +@idf_parametrize( + 'target', + ['esp32', 'esp32c3', 'esp32c5', 'esp32c6', 'esp32h2', 'esp32s2', 'esp32s3', 'esp32h2', 'esp32p4'], + indirect=['target'], +) def test_sdm(dut: IdfDut) -> None: dut.run_all_single_board_cases(group='sdm') diff --git a/components/esp_driver_sdmmc/test_apps/sdmmc/pytest_sdmmc.py b/components/esp_driver_sdmmc/test_apps/sdmmc/pytest_sdmmc.py index 6feedee57e..dfc410e7b2 100644 --- a/components/esp_driver_sdmmc/test_apps/sdmmc/pytest_sdmmc.py +++ b/components/esp_driver_sdmmc/test_apps/sdmmc/pytest_sdmmc.py @@ -1,13 +1,12 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded_idf import IdfDut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32 -@pytest.mark.esp32s3 -@pytest.mark.esp32p4 @pytest.mark.sdcard +@idf_parametrize('target', ['esp32', 'esp32s3', 'esp32p4'], indirect=['target']) def test_sdmmc(dut: IdfDut) -> None: # SDMMC driver can't be reinitialized if the test fails, # so we need to reset the board between tests to avoid failing diff --git a/components/esp_driver_sdspi/test_apps/sdspi/pytest_sdspi.py b/components/esp_driver_sdspi/test_apps/sdspi/pytest_sdspi.py index 723b9b08ab..4c187b2d12 100644 --- a/components/esp_driver_sdspi/test_apps/sdspi/pytest_sdspi.py +++ b/components/esp_driver_sdspi/test_apps/sdspi/pytest_sdspi.py @@ -1,15 +1,12 @@ -# 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 pytest from pytest_embedded_idf import IdfDut +from pytest_embedded_idf.utils import idf_parametrize @pytest.mark.temp_skip_ci(targets=['esp32c61'], reason='C5 C61 GPSPI same, so testing on C5 is enough') -@pytest.mark.esp32 -@pytest.mark.esp32s3 -@pytest.mark.esp32c3 -@pytest.mark.esp32p4 -@pytest.mark.esp32c5 @pytest.mark.sdcard_spimode +@idf_parametrize('target', ['esp32', 'esp32s3', 'esp32c3', 'esp32p4', 'esp32c5'], indirect=['target']) def test_sdspi(dut: IdfDut) -> None: dut.run_all_single_board_cases(reset=True) diff --git a/components/esp_driver_spi/test_apps/master/pytest_spi_master.py b/components/esp_driver_spi/test_apps/master/pytest_spi_master.py index 8cfd75be17..80d958b3c3 100644 --- a/components/esp_driver_spi/test_apps/master/pytest_spi_master.py +++ b/components/esp_driver_spi/test_apps/master/pytest_spi_master.py @@ -1,13 +1,22 @@ -# 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 pytest - - +from pytest_embedded_idf.utils import idf_parametrize # If `test_env` is define, should not run on generic runner -@pytest.mark.supported_targets + + @pytest.mark.generic -@pytest.mark.parametrize('config', ['release', 'freertos_compliance', 'freertos_flash',], indirect=True) -def test_master_single_dev(case_tester) -> None: # type: ignore +@pytest.mark.parametrize( + 'config', + [ + 'release', + 'freertos_compliance', + 'freertos_flash', + ], + indirect=True, +) +@idf_parametrize('target', ['supported_targets'], indirect=['target']) +def test_master_single_dev(case_tester) -> None: # type: ignore for case in case_tester.test_menu: if 'test_env' in case.attributes: continue @@ -15,10 +24,16 @@ def test_master_single_dev(case_tester) -> None: # type: ignore # Job for test_env `external_flash` just for esp32 only -@pytest.mark.esp32 @pytest.mark.flash_multi -@pytest.mark.parametrize('config', ['release',], indirect=True) -def test_master_esp_flash(case_tester) -> None: # type: ignore +@pytest.mark.parametrize( + 'config', + [ + 'release', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32'], indirect=['target']) +def test_master_esp_flash(case_tester) -> None: # type: ignore for case in case_tester.test_menu: # test case `spi_bus_lock_with_flash` use difference test env if case.attributes.get('test_env') == 'external_flash': @@ -28,19 +43,28 @@ def test_master_esp_flash(case_tester) -> None: # type: ignore # if `test_env` not defined, will run on `generic_multi_device` by default # TODO: [ESP32C61] IDF-10949 @pytest.mark.temp_skip_ci(targets=['esp32c61'], reason='no multi-dev runner') -@pytest.mark.supported_targets @pytest.mark.generic_multi_device @pytest.mark.parametrize( 'count, config', [ - (2, 'release',), - (2, 'freertos_compliance',), - (2, 'freertos_flash',), + ( + 2, + 'release', + ), + ( + 2, + 'freertos_compliance', + ), + ( + 2, + 'freertos_flash', + ), (2, 'iram_safe'), ], - indirect=True + indirect=True, ) -def test_master_multi_dev(case_tester) -> None: # type: ignore +@idf_parametrize('target', ['supported_targets'], indirect=['target']) +def test_master_multi_dev(case_tester) -> None: # type: ignore for case in case_tester.test_menu: if case.attributes.get('test_env', 'generic_multi_device') == 'generic_multi_device': case_tester.run_multi_dev_case(case=case, reset=True) diff --git a/components/esp_driver_spi/test_apps/param/pytest_spi_param.py b/components/esp_driver_spi/test_apps/param/pytest_spi_param.py index d7df696410..049c6ec316 100644 --- a/components/esp_driver_spi/test_apps/param/pytest_spi_param.py +++ b/components/esp_driver_spi/test_apps/param/pytest_spi_param.py @@ -1,12 +1,13 @@ -# 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 pytest - - +from pytest_embedded_idf.utils import idf_parametrize # If `test_env` is define, should not run on generic runner -@pytest.mark.supported_targets + + @pytest.mark.generic -def test_param_single_dev(case_tester) -> None: # type: ignore +@idf_parametrize('target', ['supported_targets'], indirect=['target']) +def test_param_single_dev(case_tester) -> None: # type: ignore for case in case_tester.test_menu: if 'test_env' in case.attributes: continue @@ -16,10 +17,16 @@ def test_param_single_dev(case_tester) -> None: # type: ignore # if `test_env` not defined, will run on `generic_multi_device` by default # TODO: [ESP32C61] IDF-10949 @pytest.mark.temp_skip_ci(targets=['esp32c61'], reason='no multi-dev runner') -@pytest.mark.supported_targets @pytest.mark.generic_multi_device -@pytest.mark.parametrize('count', [2,], indirect=True) -def test_param_multi_dev(case_tester) -> None: # type: ignore +@pytest.mark.parametrize( + 'count', + [ + 2, + ], + indirect=True, +) +@idf_parametrize('target', ['supported_targets'], indirect=['target']) +def test_param_multi_dev(case_tester) -> None: # type: ignore for case in case_tester.test_menu: if case.attributes.get('test_env', 'generic_multi_device') == 'generic_multi_device': case_tester.run_multi_dev_case(case=case, reset=True) diff --git a/components/esp_driver_spi/test_apps/slave/pytest_spi_slave.py b/components/esp_driver_spi/test_apps/slave/pytest_spi_slave.py index d1ace584c8..b037f7499e 100644 --- a/components/esp_driver_spi/test_apps/slave/pytest_spi_slave.py +++ b/components/esp_driver_spi/test_apps/slave/pytest_spi_slave.py @@ -1,13 +1,14 @@ -# 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 pytest - - +from pytest_embedded_idf.utils import idf_parametrize # If `test_env` is define, should not run on generic runner -@pytest.mark.supported_targets + + @pytest.mark.generic @pytest.mark.parametrize('config', ['release', 'iram_safe'], indirect=True) -def test_slave_single_dev(case_tester) -> None: # type: ignore +@idf_parametrize('target', ['supported_targets'], indirect=['target']) +def test_slave_single_dev(case_tester) -> None: # type: ignore for case in case_tester.test_menu: if 'test_env' in case.attributes: continue @@ -17,10 +18,10 @@ def test_slave_single_dev(case_tester) -> None: # type: ignore # if `test_env` not defined, will run on `generic_multi_device` by default # TODO: [ESP32C61] IDF-10949 @pytest.mark.temp_skip_ci(targets=['esp32c61'], reason='no multi-dev runner') -@pytest.mark.supported_targets @pytest.mark.generic_multi_device @pytest.mark.parametrize('count, config', [(2, 'release'), (2, 'iram_safe')], indirect=True) -def test_slave_multi_dev(case_tester) -> None: # type: ignore +@idf_parametrize('target', ['supported_targets'], indirect=['target']) +def test_slave_multi_dev(case_tester) -> None: # type: ignore for case in case_tester.test_menu: if case.attributes.get('test_env', 'generic_multi_device') == 'generic_multi_device': case_tester.run_multi_dev_case(case=case, reset=True) diff --git a/components/esp_driver_spi/test_apps/slave_hd/pytest_spi_slave_hd.py b/components/esp_driver_spi/test_apps/slave_hd/pytest_spi_slave_hd.py index 20a055f566..22c5163812 100644 --- a/components/esp_driver_spi/test_apps/slave_hd/pytest_spi_slave_hd.py +++ b/components/esp_driver_spi/test_apps/slave_hd/pytest_spi_slave_hd.py @@ -1,21 +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 pytest - - +from pytest_embedded_idf.utils import idf_parametrize # If `test_env` is define, should not run on generic runner -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32c2 -@pytest.mark.esp32c3 -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32c61 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 + + @pytest.mark.generic @pytest.mark.parametrize('config', ['release'], indirect=True) -def test_slave_hd_single_dev(case_tester) -> None: # type: ignore +@idf_parametrize( + 'target', + ['esp32s2', 'esp32s3', 'esp32c2', 'esp32c3', 'esp32c5', 'esp32c6', 'esp32c61', 'esp32h2', 'esp32p4'], + indirect=['target'], +) +def test_slave_hd_single_dev(case_tester) -> None: # type: ignore for case in case_tester.test_menu: if 'test_env' in case.attributes: continue @@ -23,17 +20,14 @@ def test_slave_hd_single_dev(case_tester) -> None: # type: ignore # if `test_env` not defined, will run on `generic_multi_device` by default -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32c2 -@pytest.mark.esp32c3 -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 @pytest.mark.generic_multi_device @pytest.mark.parametrize('count, config', [(2, 'release')], indirect=True) -def test_slave_hd_multi_dev(case_tester) -> None: # type: ignore +@idf_parametrize( + 'target', + ['esp32s2', 'esp32s3', 'esp32c2', 'esp32c3', 'esp32c5', 'esp32c6', 'esp32h2', 'esp32p4'], + indirect=['target'], +) +def test_slave_hd_multi_dev(case_tester) -> None: # type: ignore for case in case_tester.test_menu: if case.attributes.get('test_env', 'generic_multi_device') == 'generic_multi_device': case_tester.run_multi_dev_case(case=case, reset=True) diff --git a/components/esp_driver_touch_sens/test_apps/touch_sens/pytest_touch_sens.py b/components/esp_driver_touch_sens/test_apps/touch_sens/pytest_touch_sens.py index c1205a9117..f2cb32df50 100644 --- a/components/esp_driver_touch_sens/test_apps/touch_sens/pytest_touch_sens.py +++ b/components/esp_driver_touch_sens/test_apps/touch_sens/pytest_touch_sens.py @@ -1,12 +1,10 @@ -# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2024-2025 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.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32p4 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -16,5 +14,6 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize('target', ['esp32s2', 'esp32s3', 'esp32p4'], indirect=['target']) def test_touch_sens(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_driver_tsens/test_apps/temperature_sensor/pytest_temperature_sensor.py b/components/esp_driver_tsens/test_apps/temperature_sensor/pytest_temperature_sensor.py index bb4111bfca..c5880f8058 100644 --- a/components/esp_driver_tsens/test_apps/temperature_sensor/pytest_temperature_sensor.py +++ b/components/esp_driver_tsens/test_apps/temperature_sensor/pytest_temperature_sensor.py @@ -1,48 +1,44 @@ -# SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded import Dut from pytest_embedded_idf.unity_tester import CaseTester +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32s2 -@pytest.mark.esp32c3 -@pytest.mark.esp32s3 -@pytest.mark.esp32c2 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 -@pytest.mark.esp32c5 -@pytest.mark.esp32c61 @pytest.mark.generic -@pytest.mark.parametrize('config', [ - 'release', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'release', + ], + indirect=True, +) +@idf_parametrize( + 'target', + ['esp32s2', 'esp32c3', 'esp32s3', 'esp32c2', 'esp32c6', 'esp32h2', 'esp32p4', 'esp32c5', 'esp32c61'], + indirect=['target'], +) def test_temperature_sensor_driver(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 -@pytest.mark.esp32c5 -@pytest.mark.esp32c61 @pytest.mark.generic -@pytest.mark.parametrize('config', [ - 'iram_safe', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'iram_safe', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32c6', 'esp32h2', 'esp32p4', 'esp32c5', 'esp32c61'], indirect=['target']) def test_temperature_sensor_cbs(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32s2 -@pytest.mark.esp32c3 -@pytest.mark.esp32s3 -@pytest.mark.esp32c2 -@pytest.mark.esp32c6 -@pytest.mark.esp32c61 @pytest.mark.wifi_two_dut @pytest.mark.parametrize('count', [2], indirect=True) +@idf_parametrize('target', ['esp32s2', 'esp32c3', 'esp32s3', 'esp32c2', 'esp32c6', 'esp32c61'], indirect=['target']) def test_temperature_phy_cases(case_tester: CaseTester) -> None: # type: ignore for case in case_tester.test_menu: if case.attributes.get('test_env', 'wifi_two_dut') == 'wifi_two_dut': diff --git a/components/esp_driver_uart/test_apps/rs485/pytest_rs485.py b/components/esp_driver_uart/test_apps/rs485/pytest_rs485.py index d539b0c151..72dcff04e2 100644 --- a/components/esp_driver_uart/test_apps/rs485/pytest_rs485.py +++ b/components/esp_driver_uart/test_apps/rs485/pytest_rs485.py @@ -1,11 +1,20 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32 @pytest.mark.multi_dut_modbus_rs485 -@pytest.mark.parametrize('count, config', [(2, 'release',)], indirect=True) -def test_rs485_multi_dev(case_tester) -> None: # type: ignore +@pytest.mark.parametrize( + 'count, config', + [ + ( + 2, + 'release', + ) + ], + indirect=True, +) +@idf_parametrize('target', ['esp32'], indirect=['target']) +def test_rs485_multi_dev(case_tester) -> None: # type: ignore case_tester.run_all_multi_dev_cases(reset=True) diff --git a/components/esp_driver_uart/test_apps/uart/pytest_uart.py b/components/esp_driver_uart/test_apps/uart/pytest_uart.py index 68b2661cda..da106d3d95 100644 --- a/components/esp_driver_uart/test_apps/uart/pytest_uart.py +++ b/components/esp_driver_uart/test_apps/uart/pytest_uart.py @@ -1,6 +1,7 @@ -# SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import pytest +from pytest_embedded_idf.utils import idf_parametrize input_argv = { 'esp32': ['uart'], @@ -16,7 +17,6 @@ input_argv = { } -@pytest.mark.supported_targets @pytest.mark.temp_skip_ci(targets=['esp32s3'], reason='skip due to duplication with test_uart_single_dev_psram') @pytest.mark.generic @pytest.mark.parametrize( @@ -27,7 +27,8 @@ input_argv = { ], indirect=True, ) -def test_uart_single_dev(case_tester) -> None: # type: ignore +@idf_parametrize('target', ['supported_targets'], indirect=['target']) +def test_uart_single_dev(case_tester) -> None: # type: ignore dut = case_tester.first_dut chip_type = dut.app.target @@ -48,7 +49,6 @@ def test_uart_single_dev(case_tester) -> None: # type: ignore dut._run_normal_case(case, reset=True) -@pytest.mark.esp32s3 @pytest.mark.octal_psram @pytest.mark.parametrize( 'config', @@ -58,7 +58,8 @@ def test_uart_single_dev(case_tester) -> None: # type: ignore ], indirect=True, ) -def test_uart_single_dev_psram(case_tester) -> None: # type: ignore +@idf_parametrize('target', ['esp32s3'], indirect=['target']) +def test_uart_single_dev_psram(case_tester) -> None: # type: ignore dut = case_tester.first_dut for case in case_tester.test_menu: dut.serial.hard_reset() diff --git a/components/esp_driver_uart/test_apps/uart_vfs/pytest_uart_vfs.py b/components/esp_driver_uart/test_apps/uart_vfs/pytest_uart_vfs.py index 131d8c9423..4852f3ea6d 100644 --- a/components/esp_driver_uart/test_apps/uart_vfs/pytest_uart_vfs.py +++ b/components/esp_driver_uart/test_apps/uart_vfs/pytest_uart_vfs.py @@ -1,24 +1,34 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-2025 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.supported_targets @pytest.mark.temp_skip_ci(targets=['esp32s3'], reason='skip due to duplication with test_uart_vfs_psram') @pytest.mark.generic -@pytest.mark.parametrize('config', [ - 'default', 'iram', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'default', + 'iram', + ], + indirect=True, +) +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_uart_vfs_default(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32s3 @pytest.mark.quad_psram -@pytest.mark.parametrize('config', [ - 'default', 'iram', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'default', + 'iram', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32s3'], indirect=['target']) def test_uart_vfs_psram(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_driver_usb_serial_jtag/test_apps/usb_serial_jtag/pytest_usb_serial_jtag.py b/components/esp_driver_usb_serial_jtag/test_apps/usb_serial_jtag/pytest_usb_serial_jtag.py index 859de671c1..d96301173f 100644 --- a/components/esp_driver_usb_serial_jtag/test_apps/usb_serial_jtag/pytest_usb_serial_jtag.py +++ b/components/esp_driver_usb_serial_jtag/test_apps/usb_serial_jtag/pytest_usb_serial_jtag.py @@ -1,13 +1,10 @@ -# SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-2025 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.esp32s3 -@pytest.mark.esp32c3 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 @pytest.mark.usb_serial_jtag @pytest.mark.parametrize( 'port, flash_port, config', @@ -16,21 +13,20 @@ from pytest_embedded import Dut ], indirect=True, ) -def test_usb_serial_jtag_dev(dut: Dut) -> None: # type: ignore +@idf_parametrize('target', ['esp32s3', 'esp32c3', 'esp32c6', 'esp32h2'], indirect=['target']) +def test_usb_serial_jtag_dev(dut: Dut) -> None: # type: ignore dut.expect_exact('Press ENTER to see the list of tests') - dut.write('\"test print via usb_serial_jtag driver multiple times in different tasks\"') + dut.write('"test print via usb_serial_jtag driver multiple times in different tasks"') for i in range(300 * 2): - dut.expect(r'Oh, hello world (\d), this test is for testing message and parse in python, time (\d+)', timeout=10) + dut.expect( + r'Oh, hello world (\d), this test is for testing message and parse in python, time (\d+)', timeout=10 + ) dut.expect('PASS') - dut.expect_exact('Enter next test, or \'enter\' to see menu') - dut.write('\"see if fsync appears to work\"') + dut.expect_exact("Enter next test, or 'enter' to see menu") + dut.write('"see if fsync appears to work"') dut.expect('PASS') -@pytest.mark.esp32s3 -@pytest.mark.esp32c3 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 @pytest.mark.usb_serial_jtag @pytest.mark.parametrize( 'port, flash_port, config', @@ -39,8 +35,9 @@ def test_usb_serial_jtag_dev(dut: Dut) -> None: # type: ignore ], indirect=True, ) -def test_usb_serial_jtag_rom_dev(dut: Dut) -> None: # type: ignore +@idf_parametrize('target', ['esp32s3', 'esp32c3', 'esp32c6', 'esp32h2'], indirect=['target']) +def test_usb_serial_jtag_rom_dev(dut: Dut) -> None: # type: ignore dut.expect_exact('Press ENTER to see the list of tests') - dut.write('\"test rom printf work after driver installed\"') + dut.write('"test rom printf work after driver installed"') dut.expect(r'hi, espressif1', timeout=10) dut.expect(r'hi, espressif2', timeout=10) diff --git a/components/esp_driver_usb_serial_jtag/test_apps/usb_serial_jtag_vfs/pytest_usb_serial_jtag_vfs.py b/components/esp_driver_usb_serial_jtag/test_apps/usb_serial_jtag_vfs/pytest_usb_serial_jtag_vfs.py index 897f3179ee..165a54fb97 100644 --- a/components/esp_driver_usb_serial_jtag/test_apps/usb_serial_jtag_vfs/pytest_usb_serial_jtag_vfs.py +++ b/components/esp_driver_usb_serial_jtag/test_apps/usb_serial_jtag_vfs/pytest_usb_serial_jtag_vfs.py @@ -1,24 +1,23 @@ -# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2024-2025 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.esp32s3 -@pytest.mark.esp32c3 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 @pytest.mark.usb_serial_jtag @pytest.mark.parametrize( 'port, flash_port, config', [ pytest.param('/dev/serial_ports/ttyACM-esp32', '/dev/serial_ports/ttyUSB-esp32', 'release'), ], - indirect=True,) + indirect=True, +) @pytest.mark.parametrize('test_message', ['test123456789!@#%^&*']) +@idf_parametrize('target', ['esp32s3', 'esp32c3', 'esp32c6', 'esp32h2'], indirect=['target']) def test_usj_vfs_release(dut: Dut, test_message: list) -> None: dut.expect_exact('Press ENTER to see the list of tests') - dut.write('\"test select read, write and timeout\"') + dut.write('"test select read, write and timeout"') dut.expect_exact('select timed out', timeout=2) dut.write(test_message) dut.expect_exact(test_message, timeout=2) diff --git a/components/esp_eth/test_apps/pytest_esp_eth.py b/components/esp_eth/test_apps/pytest_esp_eth.py index 07b45872ef..2f61a900da 100644 --- a/components/esp_eth/test_apps/pytest_esp_eth.py +++ b/components/esp_eth/test_apps/pytest_esp_eth.py @@ -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 @@ -11,6 +11,7 @@ from typing import Iterator import pytest from pytest_embedded_idf import IdfDut +from pytest_embedded_idf.utils import idf_parametrize from scapy.all import Ether from scapy.all import raw @@ -45,7 +46,7 @@ class EthTestIntf(object): logging.info('Use %s for testing', self.target_if) @contextlib.contextmanager - def configure_eth_if(self, eth_type:int=0) -> Iterator[socket.socket]: + def configure_eth_if(self, eth_type: int = 0) -> Iterator[socket.socket]: if eth_type == 0: eth_type = self.eth_type so = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(eth_type)) @@ -60,14 +61,14 @@ class EthTestIntf(object): so.settimeout(10) payload = bytearray(1010) for i, _ in enumerate(payload): - payload[i] = i & 0xff + payload[i] = i & 0xFF eth_frame = Ether(dst=mac, src=so.getsockname()[4], type=self.eth_type) / raw(payload) try: so.send(raw(eth_frame)) except Exception as e: raise e - def recv_resp_poke(self, mac:str, i:int=0) -> None: + def recv_resp_poke(self, mac: str, i: int = 0) -> None: eth_type_ctrl = self.eth_type + 1 with self.configure_eth_if(eth_type_ctrl) as so: so.settimeout(30) @@ -76,13 +77,13 @@ class EthTestIntf(object): eth_frame = Ether(so.recv(60)) except Exception as e: raise e - if mac == eth_frame.src and eth_frame.load[0] == 0xfa: + if mac == eth_frame.src and eth_frame.load[0] == 0xFA: if eth_frame.load[1] != i: raise RuntimeError('Missed Poke Packet') logging.info('Poke Packet received...') eth_frame.dst = eth_frame.src eth_frame.src = so.getsockname()[4] - eth_frame.load = bytes.fromhex('fb') # POKE_RESP code + eth_frame.load = bytes.fromhex('fb') # POKE_RESP code so.send(raw(eth_frame)) break else: @@ -92,9 +93,9 @@ class EthTestIntf(object): else: raise RuntimeError('No Poke Packet!') - def traffic_gen(self, mac: str, pipe_rcv:connection.Connection) -> None: + def traffic_gen(self, mac: str, pipe_rcv: connection.Connection) -> None: with self.configure_eth_if() as so: - payload = bytes.fromhex('ff') # DUMMY_TRAFFIC code + payload = bytes.fromhex('ff') # DUMMY_TRAFFIC code payload += bytes(1485) eth_frame = Ether(dst=mac, src=so.getsockname()[4], type=self.eth_type) / raw(payload) try: @@ -103,7 +104,7 @@ class EthTestIntf(object): except Exception as e: raise e - def eth_loopback(self, mac: str, pipe_rcv:connection.Connection) -> None: + def eth_loopback(self, mac: str, pipe_rcv: connection.Connection) -> None: with self.configure_eth_if(self.eth_type) as so: so.settimeout(30) try: @@ -158,7 +159,7 @@ def ethernet_l2_test(dut: IdfDut) -> None: raise RuntimeError('No broadcast received from expected DUT MAC addr') for i in range(0, 1010): - if eth_frame.load[i] != i & 0xff: + if eth_frame.load[i] != i & 0xFF: raise RuntimeError('Packet content mismatch') dut.expect_unity_test_output() @@ -172,7 +173,9 @@ def ethernet_l2_test(dut: IdfDut) -> None: # (there might be slight delay due to the RSTP execution) target_if.recv_resp_poke(mac=dut_mac) target_if.send_eth_packet('ff:ff:ff:ff:ff:ff') # broadcast frame - target_if.send_eth_packet('01:00:5e:00:00:00') # IPv4 multicast frame (some SPI Eth modules filter multicast other than IP) + target_if.send_eth_packet( + '01:00:5e:00:00:00' + ) # IPv4 multicast frame (some SPI Eth modules filter multicast other than IP) target_if.send_eth_packet(mac=dut_mac) # unicast frame dut.expect_unity_test_output(extra_before=res.group(1)) @@ -191,7 +194,13 @@ def ethernet_l2_test(dut: IdfDut) -> None: target_if.recv_resp_poke(dut_mac, rx_i) # Start/stop under heavy Rx traffic pipe_rcv, pipe_send = Pipe(False) - tx_proc = Process(target=target_if.traffic_gen, args=(dut_mac, pipe_rcv, )) + tx_proc = Process( + target=target_if.traffic_gen, + args=( + dut_mac, + pipe_rcv, + ), + ) tx_proc.start() dut.expect_exact('Ethernet Stopped') pipe_send.send(0) # just send some dummy data @@ -219,7 +228,13 @@ def ethernet_heap_alloc_test(dut: IdfDut) -> None: ) dut_mac = res.group(1).decode('utf-8') pipe_rcv, pipe_send = Pipe(False) - loopback_proc = Process(target=target_if.eth_loopback, args=(dut_mac, pipe_rcv, )) + loopback_proc = Process( + target=target_if.eth_loopback, + args=( + dut_mac, + pipe_rcv, + ), + ) loopback_proc.start() target_if.recv_resp_poke(mac=dut_mac) @@ -233,55 +248,67 @@ def ethernet_heap_alloc_test(dut: IdfDut) -> None: # ----------- IP101 ----------- -@pytest.mark.esp32 @pytest.mark.ethernet -@pytest.mark.parametrize('config', [ - 'default_ip101', - 'release_ip101', - 'single_core_ip101' -], indirect=True) +@pytest.mark.parametrize('config', ['default_ip101', 'release_ip101', 'single_core_ip101'], indirect=True) @pytest.mark.flaky(reruns=3, reruns_delay=5) +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_esp_ethernet(dut: IdfDut) -> None: ethernet_test(dut) -@pytest.mark.esp32 @pytest.mark.ethernet -@pytest.mark.parametrize('config', [ - 'default_ip101', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'default_ip101', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_esp_emac(dut: IdfDut) -> None: ethernet_int_emac_test(dut) dut.serial.hard_reset() ethernet_heap_alloc_test(dut) -@pytest.mark.esp32 @pytest.mark.eth_ip101 -@pytest.mark.parametrize('config', [ - 'default_ip101', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'default_ip101', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_esp_eth_ip101(dut: IdfDut) -> None: ethernet_l2_test(dut) # ----------- IP101 ESP32P4 ----------- -@pytest.mark.esp32p4 @pytest.mark.eth_ip101 -@pytest.mark.parametrize('config', [ - 'default_ip101_esp32p4', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'default_ip101_esp32p4', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32p4'], indirect=['target']) def test_esp32p4_ethernet(dut: IdfDut) -> None: ethernet_test(dut) dut.serial.hard_reset() ethernet_l2_test(dut) -@pytest.mark.esp32p4 @pytest.mark.eth_ip101 -@pytest.mark.parametrize('config', [ - 'default_ip101_esp32p4', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'default_ip101_esp32p4', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32p4'], indirect=['target']) def test_esp32p4_emac(dut: IdfDut) -> None: ethernet_int_emac_test(dut) dut.serial.hard_reset() @@ -289,11 +316,15 @@ def test_esp32p4_emac(dut: IdfDut) -> None: # ----------- LAN8720 ----------- -@pytest.mark.esp32 @pytest.mark.eth_lan8720 -@pytest.mark.parametrize('config', [ - 'default_lan8720', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'default_lan8720', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_esp_eth_lan8720(dut: IdfDut) -> None: ethernet_test(dut) dut.serial.hard_reset() @@ -301,11 +332,15 @@ def test_esp_eth_lan8720(dut: IdfDut) -> None: # ----------- RTL8201 ----------- -@pytest.mark.esp32 @pytest.mark.eth_rtl8201 -@pytest.mark.parametrize('config', [ - 'default_rtl8201', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'default_rtl8201', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_esp_eth_rtl8201(dut: IdfDut) -> None: ethernet_test(dut) dut.serial.hard_reset() @@ -313,11 +348,15 @@ def test_esp_eth_rtl8201(dut: IdfDut) -> None: # ----------- KSZ8041 ----------- -@pytest.mark.esp32 @pytest.mark.eth_ksz8041 -@pytest.mark.parametrize('config', [ - 'default_ksz8041', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'default_ksz8041', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_esp_eth_ksz8041(dut: IdfDut) -> None: ethernet_test(dut) dut.serial.hard_reset() @@ -325,11 +364,15 @@ def test_esp_eth_ksz8041(dut: IdfDut) -> None: # ----------- DP83848 ----------- -@pytest.mark.esp32 @pytest.mark.eth_dp83848 -@pytest.mark.parametrize('config', [ - 'default_dp83848', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'default_dp83848', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_esp_eth_dp83848(dut: IdfDut) -> None: ethernet_test(dut) dut.serial.hard_reset() @@ -337,12 +380,16 @@ def test_esp_eth_dp83848(dut: IdfDut) -> None: # ----------- W5500 ----------- -@pytest.mark.esp32 @pytest.mark.eth_w5500 -@pytest.mark.parametrize('config', [ - 'default_w5500', - 'poll_w5500', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'default_w5500', + 'poll_w5500', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_esp_eth_w5500(dut: IdfDut) -> None: ethernet_test(dut) dut.serial.hard_reset() @@ -352,12 +399,16 @@ def test_esp_eth_w5500(dut: IdfDut) -> None: # ----------- KSZ8851SNL ----------- -@pytest.mark.esp32 @pytest.mark.eth_ksz8851snl -@pytest.mark.parametrize('config', [ - 'default_ksz8851snl', - 'poll_ksz8851snl', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'default_ksz8851snl', + 'poll_ksz8851snl', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_esp_eth_ksz8851snl(dut: IdfDut) -> None: ethernet_test(dut) dut.serial.hard_reset() @@ -367,12 +418,16 @@ def test_esp_eth_ksz8851snl(dut: IdfDut) -> None: # ----------- DM9051 ----------- -@pytest.mark.esp32 @pytest.mark.eth_dm9051 -@pytest.mark.parametrize('config', [ - 'default_dm9051', - 'poll_dm9051', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'default_dm9051', + 'poll_dm9051', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_esp_eth_dm9051(dut: IdfDut) -> None: ethernet_test(dut) dut.serial.hard_reset() diff --git a/components/esp_event/host_test/esp_event_unit_test/pytest_esp_event_linux.py b/components/esp_event/host_test/esp_event_unit_test/pytest_esp_event_linux.py index 7b289385f8..79b2c2ebbb 100644 --- a/components/esp_event/host_test/esp_event_unit_test/pytest_esp_event_linux.py +++ b/components/esp_event/host_test/esp_event_unit_test/pytest_esp_event_linux.py @@ -1,10 +1,11 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-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.linux @pytest.mark.host_test +@idf_parametrize('target', ['linux'], indirect=['target']) def test_esp_event_linux(dut: Dut) -> None: dut.expect_exact('All tests passed', timeout=5) diff --git a/components/esp_event/test_apps/pytest_esp_event.py b/components/esp_event/test_apps/pytest_esp_event.py index ff04ca3a55..a8b47ca347 100644 --- a/components/esp_event/test_apps/pytest_esp_event.py +++ b/components/esp_event/test_apps/pytest_esp_event.py @@ -2,37 +2,35 @@ # 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.esp32c3 @pytest.mark.generic +@idf_parametrize('target', ['esp32', 'esp32s2', 'esp32c3'], indirect=['target']) def test_esp_event(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32 -@pytest.mark.esp32c3 @pytest.mark.host_test @pytest.mark.qemu @pytest.mark.xfail('config.getvalue("target") == "esp32c3"', reason='Unstable on QEMU, needs investigation') +@idf_parametrize('target', ['esp32', 'esp32c3'], indirect=['target']) def test_esp_event_qemu(dut: Dut) -> None: for case in dut.test_menu: if 'qemu-ignore' not in case.groups and not case.is_ignored and case.type == 'normal': dut._run_normal_case(case) -@pytest.mark.linux @pytest.mark.host_test +@idf_parametrize('target', ['linux'], indirect=['target']) def test_esp_event_posix_simulator(dut: Dut) -> None: dut.expect_exact('Press ENTER to see the list of tests.') dut.write('*') dut.expect(r'\d{2} Tests 0 Failures 0 Ignored', timeout=120) -@pytest.mark.esp32 @pytest.mark.generic +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_esp_event_profiling(dut: Dut) -> None: dut.expect_exact('Press ENTER to see the list of tests.') dut.write('"profiling reports valid values"') @@ -40,7 +38,7 @@ def test_esp_event_profiling(dut: Dut) -> None: # with an execution time superior to 0 us matches = dut.expect(r'HANDLER .+ inv:[1-9][0-9]{0,} time:[1-9][0-9]{0,} us', timeout=2) matches_arr = matches.group().split(b'\r\n') - assert (len(matches_arr) == 3) + assert len(matches_arr) == 3 dut.expect('1 Tests 0 Failures 0 Ignored', timeout=120) dut.expect_exact("Enter next test, or 'enter' to see menu") @@ -48,7 +46,7 @@ def test_esp_event_profiling(dut: Dut) -> None: # look for 1 handlers never invoked matches = dut.expect(r'HANDLER .+ inv:0 time:0 us', timeout=2) matches_arr = matches.group().split(b'\r\n') - assert (len(matches_arr) == 1) + assert len(matches_arr) == 1 dut.expect('1 Tests 0 Failures 0 Ignored', timeout=120) dut.expect_exact("Enter next test, or 'enter' to see menu") diff --git a/components/esp_hid/test_apps/pytest_esp_hid.py b/components/esp_hid/test_apps/pytest_esp_hid.py index 664e29bf6f..c59350344e 100644 --- a/components/esp_hid/test_apps/pytest_esp_hid.py +++ b/components/esp_hid/test_apps/pytest_esp_hid.py @@ -1,12 +1,11 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 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.esp32 -@pytest.mark.esp32c3 +@idf_parametrize('target', ['esp32', 'esp32c3'], indirect=['target']) def test_esp_hid(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_http_client/test_apps/pytest_esp_http_client_ut.py b/components/esp_http_client/test_apps/pytest_esp_http_client_ut.py index b648571e56..ec91799b88 100644 --- a/components/esp_http_client/test_apps/pytest_esp_http_client_ut.py +++ b/components/esp_http_client/test_apps/pytest_esp_http_client_ut.py @@ -1,11 +1,11 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 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.supported_targets @pytest.mark.generic +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_esp_http_client(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_http_server/test_apps/pytest_esp_http_server_ut.py b/components/esp_http_server/test_apps/pytest_esp_http_server_ut.py index 613408c543..073c7eafae 100644 --- a/components/esp_http_server/test_apps/pytest_esp_http_server_ut.py +++ b/components/esp_http_server/test_apps/pytest_esp_http_server_ut.py @@ -1,11 +1,11 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 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.supported_targets @pytest.mark.generic +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_esp_http_server(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_hw_support/test_apps/dma/pytest_dma.py b/components/esp_hw_support/test_apps/dma/pytest_dma.py index 1d741f14fb..e70adf3476 100644 --- a/components/esp_hw_support/test_apps/dma/pytest_dma.py +++ b/components/esp_hw_support/test_apps/dma/pytest_dma.py @@ -1,17 +1,10 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 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.esp32s2 -@pytest.mark.esp32c2 -@pytest.mark.esp32c3 -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32c61 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -20,11 +13,15 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize( + 'target', + ['esp32s2', 'esp32c2', 'esp32c3', 'esp32c5', 'esp32c6', 'esp32c61', 'esp32h2', 'esp32p4'], + indirect=['target'], +) def test_dma(dut: Dut) -> None: dut.run_all_single_board_cases(reset=True) -@pytest.mark.esp32s3 @pytest.mark.octal_psram @pytest.mark.parametrize( 'config', @@ -33,5 +30,6 @@ def test_dma(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32s3'], indirect=['target']) def test_dma_psram(dut: Dut) -> None: dut.run_all_single_board_cases(reset=True) diff --git a/components/esp_hw_support/test_apps/dma2d/pytest_dma2d.py b/components/esp_hw_support/test_apps/dma2d/pytest_dma2d.py index 1fbdd0e0dd..314949f222 100644 --- a/components/esp_hw_support/test_apps/dma2d/pytest_dma2d.py +++ b/components/esp_hw_support/test_apps/dma2d/pytest_dma2d.py @@ -1,11 +1,10 @@ -# SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-2025 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 @pytest.mark.parametrize( 'config', @@ -14,5 +13,6 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize('target', ['esp32p4'], indirect=['target']) def test_dma2d(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/pytest_esp_hw_support.py b/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/pytest_esp_hw_support.py index 303f5bc685..c874e8f204 100644 --- a/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/pytest_esp_hw_support.py +++ b/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/pytest_esp_hw_support.py @@ -1,18 +1,15 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 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('single_core_esp32', marks=[pytest.mark.esp32]), - pytest.param('default', marks=[pytest.mark.supported_targets]), - pytest.param('release', marks=[pytest.mark.supported_targets]), - ], - indirect=True, +@idf_parametrize( + 'config,target', + [('single_core_esp32', 'esp32'), ('default', 'supported_targets'), ('release', 'supported_targets')], + indirect=['config', 'target'], ) def test_esp_hw_support(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=180) diff --git a/components/esp_hw_support/test_apps/host_test_linux/pytest_esp_hw_support_linux.py b/components/esp_hw_support/test_apps/host_test_linux/pytest_esp_hw_support_linux.py index a2dce9a03e..9c3bd55273 100644 --- a/components/esp_hw_support/test_apps/host_test_linux/pytest_esp_hw_support_linux.py +++ b/components/esp_hw_support/test_apps/host_test_linux/pytest_esp_hw_support_linux.py @@ -1,10 +1,11 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-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.linux @pytest.mark.host_test +@idf_parametrize('target', ['linux'], indirect=['target']) def test_esp_hw_support_linux(dut: Dut) -> None: dut.run_all_single_board_cases(group='!ignore', timeout=120) diff --git a/components/esp_hw_support/test_apps/mspi/pytest_flash_psram.py b/components/esp_hw_support/test_apps/mspi/pytest_flash_psram.py index 6704041ebb..41be9d93c5 100644 --- a/components/esp_hw_support/test_apps/mspi/pytest_flash_psram.py +++ b/components/esp_hw_support/test_apps/mspi/pytest_flash_psram.py @@ -1,44 +1,53 @@ -# 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 os import pathlib import pytest from pytest_embedded_idf import IdfDut +from pytest_embedded_idf.utils import idf_parametrize -MSPI_F8R8_configs = [p.name.replace('sdkconfig.ci.', '') for p in pathlib.Path(os.path.dirname(__file__)).glob('sdkconfig.ci.esp32s3_f8r8*')] +MSPI_F8R8_configs = [ + p.name.replace('sdkconfig.ci.', '') + for p in pathlib.Path(os.path.dirname(__file__)).glob('sdkconfig.ci.esp32s3_f8r8*') +] -@pytest.mark.esp32s3 @pytest.mark.MSPI_F8R8 @pytest.mark.parametrize('config', MSPI_F8R8_configs, indirect=True) +@idf_parametrize('target', ['esp32s3'], indirect=['target']) def test_flash8_psram8(dut: IdfDut) -> None: dut.run_all_single_board_cases() # For F4R8 board (Quad Flash and Octal PSRAM) -MSPI_F4R8_configs = [p.name.replace('sdkconfig.ci.', '') for p in pathlib.Path(os.path.dirname(__file__)).glob('sdkconfig.ci.esp32s3_f4r8*')] +MSPI_F4R8_configs = [ + p.name.replace('sdkconfig.ci.', '') + for p in pathlib.Path(os.path.dirname(__file__)).glob('sdkconfig.ci.esp32s3_f4r8*') +] -@pytest.mark.esp32s3 @pytest.mark.MSPI_F4R8 @pytest.mark.parametrize('config', MSPI_F4R8_configs, indirect=True) +@idf_parametrize('target', ['esp32s3'], indirect=['target']) def test_flash4_psram8(dut: IdfDut) -> None: dut.run_all_single_board_cases() # For F4R4 board (Quad Flash and Quad PSRAM) -MSPI_F4R4_configs = [p.name.replace('sdkconfig.ci.', '') for p in pathlib.Path(os.path.dirname(__file__)).glob('sdkconfig.ci.esp32s3_f4r4*')] +MSPI_F4R4_configs = [ + p.name.replace('sdkconfig.ci.', '') + for p in pathlib.Path(os.path.dirname(__file__)).glob('sdkconfig.ci.esp32s3_f4r4*') +] -@pytest.mark.esp32s3 @pytest.mark.MSPI_F4R4 @pytest.mark.parametrize('config', MSPI_F4R4_configs, indirect=True) +@idf_parametrize('target', ['esp32s3'], indirect=['target']) def test_flash4_psram4(dut: IdfDut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32p4 @pytest.mark.flash_120m @pytest.mark.parametrize( 'config', @@ -47,5 +56,6 @@ def test_flash4_psram4(dut: IdfDut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32p4'], indirect=['target']) def test_flash_psram_esp32p4(dut: IdfDut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_hw_support/test_apps/mspi_psram_with_dfs/pytest_psram_with_dfs.py b/components/esp_hw_support/test_apps/mspi_psram_with_dfs/pytest_psram_with_dfs.py index 5680c21c53..985699e131 100644 --- a/components/esp_hw_support/test_apps/mspi_psram_with_dfs/pytest_psram_with_dfs.py +++ b/components/esp_hw_support/test_apps/mspi_psram_with_dfs/pytest_psram_with_dfs.py @@ -1,39 +1,45 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import os import pathlib import pytest from pytest_embedded_idf import IdfDut +from pytest_embedded_idf.utils import idf_parametrize -MSPI_F8R8_configs = [p.name.replace('sdkconfig.ci.', '') for p in pathlib.Path(os.path.dirname(__file__)).glob('sdkconfig.ci.f8r8*')] +MSPI_F8R8_configs = [ + p.name.replace('sdkconfig.ci.', '') for p in pathlib.Path(os.path.dirname(__file__)).glob('sdkconfig.ci.f8r8*') +] -@pytest.mark.esp32s3 @pytest.mark.MSPI_F8R8 @pytest.mark.parametrize('config', MSPI_F8R8_configs, indirect=True) +@idf_parametrize('target', ['esp32s3'], indirect=['target']) def test_flash8_psram8_with_dfs(dut: IdfDut) -> None: dut.run_all_single_board_cases() # For F4R8 board (Quad Flash and Octal PSRAM) -MSPI_F4R8_configs = [p.name.replace('sdkconfig.ci.', '') for p in pathlib.Path(os.path.dirname(__file__)).glob('sdkconfig.ci.f4r8*')] +MSPI_F4R8_configs = [ + p.name.replace('sdkconfig.ci.', '') for p in pathlib.Path(os.path.dirname(__file__)).glob('sdkconfig.ci.f4r8*') +] -@pytest.mark.esp32s3 @pytest.mark.MSPI_F4R8 @pytest.mark.parametrize('config', MSPI_F4R8_configs, indirect=True) +@idf_parametrize('target', ['esp32s3'], indirect=['target']) def test_flash4_psram8_with_dfs(dut: IdfDut) -> None: dut.run_all_single_board_cases() # For F4R4 board (Quad Flash and Quad PSRAM) -MSPI_F4R4_configs = [p.name.replace('sdkconfig.ci.', '') for p in pathlib.Path(os.path.dirname(__file__)).glob('sdkconfig.ci.f4r4*')] +MSPI_F4R4_configs = [ + p.name.replace('sdkconfig.ci.', '') for p in pathlib.Path(os.path.dirname(__file__)).glob('sdkconfig.ci.f4r4*') +] -@pytest.mark.esp32s3 @pytest.mark.MSPI_F4R4 @pytest.mark.parametrize('config', MSPI_F4R4_configs, indirect=True) +@idf_parametrize('target', ['esp32s3'], indirect=['target']) def test_flash4_psram4_with_dfs(dut: IdfDut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_hw_support/test_apps/rtc_8md256/pytest_rtc_8md256.py b/components/esp_hw_support/test_apps/rtc_8md256/pytest_rtc_8md256.py index 0ef937c0f5..1942b0623d 100644 --- a/components/esp_hw_support/test_apps/rtc_8md256/pytest_rtc_8md256.py +++ b/components/esp_hw_support/test_apps/rtc_8md256/pytest_rtc_8md256.py @@ -1,8 +1,8 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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 def deepsleep_test(dut: Dut, case_name: str) -> None: @@ -19,21 +19,15 @@ def deepsleep_test(dut: Dut, case_name: str) -> None: dut.expect(r'rst:.*\(%s\)' % reset_reason, timeout=10) -@pytest.mark.esp32 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32c3 -@pytest.mark.esp32c2 @pytest.mark.generic +@idf_parametrize('target', ['esp32', 'esp32s2', 'esp32s3', 'esp32c3', 'esp32c2'], indirect=['target']) def test_rtc_8md256_deepsleep(dut: Dut) -> None: deepsleep_test(dut, '"Can use 8MD256 as RTC clock source in deepsleep"') # Only targets with SOC_PM_SUPPORT_RTC_PERIPH_PD defined -@pytest.mark.esp32 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 @pytest.mark.generic +@idf_parametrize('target', ['esp32', 'esp32s2', 'esp32s3'], indirect=['target']) def test_rtc_8md256_deepsleep_force_rtcperiph(dut: Dut) -> None: deepsleep_test(dut, '"Can use 8MD256 as RTC clock source in deepsleep (force rtc_periph)"') @@ -48,18 +42,13 @@ def lightsleep_test(dut: Dut, case_name: str) -> None: dut.expect(r'Returned from light sleep, reason: timer', timeout=10) -@pytest.mark.esp32 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32c3 @pytest.mark.generic +@idf_parametrize('target', ['esp32', 'esp32s2', 'esp32s3', 'esp32c3'], indirect=['target']) def test_rtc_8md256_lightsleep(dut: Dut) -> None: lightsleep_test(dut, '"Can use 8MD256 as RTC clock source in lightsleep"') -@pytest.mark.esp32 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 @pytest.mark.generic +@idf_parametrize('target', ['esp32', 'esp32s2', 'esp32s3'], indirect=['target']) def test_rtc_8md256_lightsleep_force_rtcperiph(dut: Dut) -> None: lightsleep_test(dut, '"Can use 8MD256 as RTC clock source in lightsleep (force rtc_periph)"') diff --git a/components/esp_hw_support/test_apps/rtc_clk/pytest_rtc_clk.py b/components/esp_hw_support/test_apps/rtc_clk/pytest_rtc_clk.py index 396e5139b5..baae55ba3d 100644 --- a/components/esp_hw_support/test_apps/rtc_clk/pytest_rtc_clk.py +++ b/components/esp_hw_support/test_apps/rtc_clk/pytest_rtc_clk.py @@ -1,32 +1,33 @@ -# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 from typing import Any import pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize @pytest.mark.generic -@pytest.mark.esp32 +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_rtc_clk(dut: Dut) -> None: dut.run_all_single_board_cases(group='rtc_clk') -@pytest.mark.esp32 @pytest.mark.xtal32k +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_rtc_xtal32k(dut: Dut) -> None: dut.run_all_single_board_cases(attributes={'test_env': 'xtal32k'}) -@pytest.mark.esp32 @pytest.mark.no32kXtal +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_rtc_no_xtal32k(dut: Dut) -> None: dut.run_all_single_board_cases(attributes={'test_env': 'noXtal32k'}) @pytest.mark.generic -@pytest.mark.supported_targets # TODO: [ESP32P4] IDF-8973 [ESP32C5] IDF-10309 [ESP32C61] IDF-9274 IDF-10984 @pytest.mark.temp_skip_ci(targets=['esp32c6', 'esp32h2', 'esp32p4', 'esp32c5', 'esp32c61'], reason='support TBD') +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_rtc_calib(case_tester: Any) -> None: case_tester.run_all_multi_stage_cases() diff --git a/components/esp_hw_support/test_apps/sleep_retention/pytest_retention.py b/components/esp_hw_support/test_apps/sleep_retention/pytest_retention.py index 3a4ca50f1e..b515a68d39 100644 --- a/components/esp_hw_support/test_apps/sleep_retention/pytest_retention.py +++ b/components/esp_hw_support/test_apps/sleep_retention/pytest_retention.py @@ -1,35 +1,15 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 -import functools -from typing import Callable -from typing import Dict -from typing import List - import pytest from pytest_embedded import Dut - - -def target_list(targets: List[str]) -> Callable: - - def decorator(func: Callable) -> Callable: - - @functools.wraps(func) - def wrapper(*args: List, **kwargs: Dict) -> Callable: - return func(*args, **kwargs) # type: ignore - - for target in targets: - wrapper = pytest.mark.__getattr__(target)(wrapper) - - return wrapper - - return decorator +from pytest_embedded_idf.utils import idf_parametrize # SOC_PAU_SUPPORTED == 1 retention_targets = ['esp32c6', 'esp32h2', 'esp32p4', 'esp32c5', 'esp32c61'] -@target_list(retention_targets) @pytest.mark.generic +@idf_parametrize('target', ['esp32c61', 'esp32c5', 'esp32p4', 'esp32h2', 'esp32c6'], indirect=['target']) def test_sleep_retention(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_hw_support/test_apps/vad_wakeup/pytest_wakeup_vad.py b/components/esp_hw_support/test_apps/vad_wakeup/pytest_wakeup_vad.py index 2fe20c476a..3413396876 100644 --- a/components/esp_hw_support/test_apps/vad_wakeup/pytest_wakeup_vad.py +++ b/components/esp_hw_support/test_apps/vad_wakeup/pytest_wakeup_vad.py @@ -1,11 +1,12 @@ -# 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.esp32p4 @pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='lack of runners for now') @pytest.mark.lp_i2s +@idf_parametrize('target', ['esp32p4'], indirect=['target']) def test_efuse_component_ut(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_hw_support/test_apps/wakeup_tests/pytest_wakeup_tests.py b/components/esp_hw_support/test_apps/wakeup_tests/pytest_wakeup_tests.py index b99d1345a4..f621c295e0 100644 --- a/components/esp_hw_support/test_apps/wakeup_tests/pytest_wakeup_tests.py +++ b/components/esp_hw_support/test_apps/wakeup_tests/pytest_wakeup_tests.py @@ -1,11 +1,11 @@ -# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - from time import sleep from typing import Tuple import pytest from pytest_embedded_idf.dut import IdfDut +from pytest_embedded_idf.utils import idf_parametrize TEST_CONFIGS = [ pytest.param('default'), @@ -36,14 +36,10 @@ available_rtcio_nums = { } -@pytest.mark.esp32 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 @pytest.mark.generic_multi_device @pytest.mark.parametrize('count', [2], indirect=True) @pytest.mark.parametrize('config', TEST_CONFIGS, indirect=True) +@idf_parametrize('target', ['esp32', 'esp32s2', 'esp32s3', 'esp32c6', 'esp32h2'], indirect=['target']) def test_ext1_deepsleep(dut: Tuple[IdfDut, IdfDut]) -> None: wakee = dut[0] waker = dut[1] @@ -86,12 +82,10 @@ def test_ext1_deepsleep(dut: Tuple[IdfDut, IdfDut]) -> None: wakee.expect(f'io_wakeup_num = {gpio_num}', timeout=10) -@pytest.mark.esp32c2 -@pytest.mark.esp32c3 -@pytest.mark.esp32c6 @pytest.mark.generic_multi_device @pytest.mark.parametrize('count', [2], indirect=True) @pytest.mark.parametrize('config', TEST_CONFIGS, indirect=True) +@idf_parametrize('target', ['esp32c2', 'esp32c3', 'esp32c6'], indirect=['target']) def test_rtcio_deepsleep(dut: Tuple[IdfDut, IdfDut]) -> None: wakee = dut[0] waker = dut[1] @@ -134,16 +128,12 @@ def test_rtcio_deepsleep(dut: Tuple[IdfDut, IdfDut]) -> None: wakee.expect(f'io_wakeup_num = {gpio_num}', timeout=10) -@pytest.mark.esp32 -@pytest.mark.esp32c2 -@pytest.mark.esp32c3 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 @pytest.mark.generic_multi_device @pytest.mark.parametrize('count', [2], indirect=True) @pytest.mark.parametrize('config', TEST_CONFIGS, indirect=True) +@idf_parametrize( + 'target', ['esp32', 'esp32c2', 'esp32c3', 'esp32s2', 'esp32s3', 'esp32c6', 'esp32h2'], indirect=['target'] +) def test_gpio_wakeup_enable_lightsleep(dut: Tuple[IdfDut, IdfDut]) -> None: wakee = dut[0] waker = dut[1] @@ -153,7 +143,6 @@ def test_gpio_wakeup_enable_lightsleep(dut: Tuple[IdfDut, IdfDut]) -> None: for wakeup_level in [1, 0]: for gpio_num in gpio_nums: - wakee.write('\r\n') wakee.expect('io_wakeup_test>', timeout=10) wakee.write(f'gpio -p {gpio_num} -l {wakeup_level}') diff --git a/components/esp_lcd/test_apps/i2c_lcd/pytest_i2c_lcd.py b/components/esp_lcd/test_apps/i2c_lcd/pytest_i2c_lcd.py index 610d15c48b..1848e7344e 100644 --- a/components/esp_lcd/test_apps/i2c_lcd/pytest_i2c_lcd.py +++ b/components/esp_lcd/test_apps/i2c_lcd/pytest_i2c_lcd.py @@ -1,11 +1,10 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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.esp32c3 @pytest.mark.i2c_oled @pytest.mark.parametrize( 'config', @@ -14,5 +13,6 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize('target', ['esp32c3'], indirect=['target']) def test_i2c_lcd(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_lcd/test_apps/i2c_lcd_legacy/pytest_i2c_lcd_legacy.py b/components/esp_lcd/test_apps/i2c_lcd_legacy/pytest_i2c_lcd_legacy.py index a2e09316a6..d0aa353142 100644 --- a/components/esp_lcd/test_apps/i2c_lcd_legacy/pytest_i2c_lcd_legacy.py +++ b/components/esp_lcd/test_apps/i2c_lcd_legacy/pytest_i2c_lcd_legacy.py @@ -1,11 +1,10 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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.esp32c3 @pytest.mark.i2c_oled @pytest.mark.parametrize( 'config', @@ -14,5 +13,6 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize('target', ['esp32c3'], indirect=['target']) def test_i2c_lcd_legacy(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_lcd/test_apps/i80_lcd/pytest_i80_lcd.py b/components/esp_lcd/test_apps/i80_lcd/pytest_i80_lcd.py index 78d8b7df5f..f8bf0548d2 100644 --- a/components/esp_lcd/test_apps/i80_lcd/pytest_i80_lcd.py +++ b/components/esp_lcd/test_apps/i80_lcd/pytest_i80_lcd.py @@ -1,13 +1,10 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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.esp32s3 -@pytest.mark.esp32p4 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -16,5 +13,6 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize('target', ['esp32', 'esp32s2', 'esp32s3', 'esp32p4'], indirect=['target']) def test_i80_lcd(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_lcd/test_apps/mipi_dsi_lcd/pytest_mipi_dsi_lcd.py b/components/esp_lcd/test_apps/mipi_dsi_lcd/pytest_mipi_dsi_lcd.py index 7e4dc07e7d..04f1620759 100644 --- a/components/esp_lcd/test_apps/mipi_dsi_lcd/pytest_mipi_dsi_lcd.py +++ b/components/esp_lcd/test_apps/mipi_dsi_lcd/pytest_mipi_dsi_lcd.py @@ -1,10 +1,10 @@ -# SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-2025 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 @pytest.mark.parametrize( 'config', @@ -14,5 +14,6 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize('target', ['esp32p4'], indirect=['target']) def test_dsi_lcd(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_lcd/test_apps/parlio_lcd/pytest_parlio_lcd.py b/components/esp_lcd/test_apps/parlio_lcd/pytest_parlio_lcd.py index f3fb114c9f..56097d32b1 100644 --- a/components/esp_lcd/test_apps/parlio_lcd/pytest_parlio_lcd.py +++ b/components/esp_lcd/test_apps/parlio_lcd/pytest_parlio_lcd.py @@ -1,12 +1,10 @@ -# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2024-2025 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.esp32h2 -@pytest.mark.esp32c5 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -15,5 +13,6 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize('target', ['esp32p4', 'esp32h2', 'esp32c5'], indirect=['target']) def test_parlio_lcd(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_lcd/test_apps/rgb_lcd/pytest_rgb_lcd.py b/components/esp_lcd/test_apps/rgb_lcd/pytest_rgb_lcd.py index a9d77166a4..fb1b6e1fc8 100644 --- a/components/esp_lcd/test_apps/rgb_lcd/pytest_rgb_lcd.py +++ b/components/esp_lcd/test_apps/rgb_lcd/pytest_rgb_lcd.py @@ -1,10 +1,10 @@ -# SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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.esp32s3 @pytest.mark.octal_psram @pytest.mark.parametrize( 'config', @@ -14,11 +14,11 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize('target', ['esp32s3'], indirect=['target']) def test_rgb_lcd_esp32s3(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32p4 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -28,5 +28,6 @@ def test_rgb_lcd_esp32s3(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32p4'], indirect=['target']) def test_rgb_lcd_esp32p4(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_lcd/test_apps/spi_lcd/pytest_spi_lcd.py b/components/esp_lcd/test_apps/spi_lcd/pytest_spi_lcd.py index 2cdeaf11e8..26ad646b73 100644 --- a/components/esp_lcd/test_apps/spi_lcd/pytest_spi_lcd.py +++ b/components/esp_lcd/test_apps/spi_lcd/pytest_spi_lcd.py @@ -1,10 +1,10 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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.supported_targets @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -13,5 +13,6 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_spi_lcd(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_mm/test_apps/mm/pytest_mmap.py b/components/esp_mm/test_apps/mm/pytest_mmap.py index 04accedf06..d696bee32d 100644 --- a/components/esp_mm/test_apps/mm/pytest_mmap.py +++ b/components/esp_mm/test_apps/mm/pytest_mmap.py @@ -1,11 +1,11 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 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 # normal mmu tests -@pytest.mark.supported_targets + + @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -14,6 +14,7 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_mmap(dut: Dut) -> None: dut.run_all_single_board_cases(group='mmu') @@ -28,7 +29,16 @@ PSRAM_RELEASE_CONFIGS = [ @pytest.mark.generic -@pytest.mark.parametrize('config', PSRAM_RELEASE_CONFIGS, indirect=True) +@idf_parametrize( + 'config,target', + [ + ('psram_release_esp32', 'esp32'), + ('psram_release_esp32s2', 'esp32s2'), + ('psram_release_esp32s3', 'esp32s3'), + ('psram_release_esp32p4', 'esp32p4'), + ], + indirect=['config', 'target'], +) def test_mmap_psram(dut: Dut) -> None: dut.run_all_single_board_cases(group='mmu') @@ -41,13 +51,14 @@ XIP_CONFIGS = [ @pytest.mark.generic -@pytest.mark.parametrize('config', XIP_CONFIGS, indirect=True) +@idf_parametrize( + 'config,target', [('xip_psram_esp32s2', 'esp32s2'), ('xip_psram_esp32s3', 'esp32s3')], indirect=['config', 'target'] +) def test_mmap_xip_psram(dut: Dut) -> None: dut.run_all_single_board_cases(group='mmu') # normal cache tests -@pytest.mark.supported_targets @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -56,19 +67,31 @@ def test_mmap_xip_psram(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_cache(dut: Dut) -> None: dut.run_all_single_board_cases(group='cache') # cache tests with psram enabled @pytest.mark.generic -@pytest.mark.parametrize('config', PSRAM_RELEASE_CONFIGS, indirect=True) +@idf_parametrize( + 'config,target', + [ + ('psram_release_esp32', 'esp32'), + ('psram_release_esp32s2', 'esp32s2'), + ('psram_release_esp32s3', 'esp32s3'), + ('psram_release_esp32p4', 'esp32p4'), + ], + indirect=['config', 'target'], +) def test_cache_psram(dut: Dut) -> None: dut.run_all_single_board_cases(group='cache') # cache tests with xip_psram @pytest.mark.generic -@pytest.mark.parametrize('config', XIP_CONFIGS, indirect=True) +@idf_parametrize( + 'config,target', [('xip_psram_esp32s2', 'esp32s2'), ('xip_psram_esp32s3', 'esp32s3')], indirect=['config', 'target'] +) def test_cache_xip_psram(dut: Dut) -> None: dut.run_all_single_board_cases(group='cache') diff --git a/components/esp_mm/test_apps/mmap_hw/pytest_mmap_hw.py b/components/esp_mm/test_apps/mmap_hw/pytest_mmap_hw.py index 1590f48d51..bddb0d4f39 100644 --- a/components/esp_mm/test_apps/mmap_hw/pytest_mmap_hw.py +++ b/components/esp_mm/test_apps/mmap_hw/pytest_mmap_hw.py @@ -1,11 +1,10 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 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.supported_targets @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -14,5 +13,6 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_mmap_hw(dut: Dut) -> None: dut.run_all_single_board_cases(group='mmu', timeout=600) diff --git a/components/esp_netif/test_apps/test_app_esp_netif/pytest_esp_netif.py b/components/esp_netif/test_apps/test_app_esp_netif/pytest_esp_netif.py index 746316674f..64d3b025d9 100644 --- a/components/esp_netif/test_apps/test_app_esp_netif/pytest_esp_netif.py +++ b/components/esp_netif/test_apps/test_app_esp_netif/pytest_esp_netif.py @@ -1,16 +1,20 @@ -# 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 pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32s2 -@pytest.mark.esp32c3 @pytest.mark.generic -@pytest.mark.parametrize('config', [ - 'global_dns', - 'dns_per_netif', - 'loopback', # test config without LWIP -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'global_dns', + 'dns_per_netif', + 'loopback', # test config without LWIP + ], + indirect=True, +) +@idf_parametrize('target', ['esp32s2', 'esp32c3'], indirect=['target']) def test_esp_netif(dut: Dut) -> None: dut.expect_unity_test_output() diff --git a/components/esp_netif/test_apps/test_app_vfs_l2tap/pytest_esp_vfs_l2tap.py b/components/esp_netif/test_apps/test_app_vfs_l2tap/pytest_esp_vfs_l2tap.py index a93a9a9e34..1a9f547da8 100644 --- a/components/esp_netif/test_apps/test_app_vfs_l2tap/pytest_esp_vfs_l2tap.py +++ b/components/esp_netif/test_apps/test_app_vfs_l2tap/pytest_esp_vfs_l2tap.py @@ -1,22 +1,31 @@ -# 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 pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32 @pytest.mark.ethernet -@pytest.mark.parametrize('config', [ - 'defaults', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'defaults', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_esp_netif_vfs_l2tp(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32p4 @pytest.mark.eth_ip101 -@pytest.mark.parametrize('config', [ - 'defaults', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'defaults', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32p4'], indirect=['target']) def test_esp_netif_vfs_l2tp_p4(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_partition/host_test/partition_api_test/pytest_esp_partition_linux.py b/components/esp_partition/host_test/partition_api_test/pytest_esp_partition_linux.py index 6d3b8a6d5d..7f2b68dc35 100644 --- a/components/esp_partition/host_test/partition_api_test/pytest_esp_partition_linux.py +++ b/components/esp_partition/host_test/partition_api_test/pytest_esp_partition_linux.py @@ -1,10 +1,11 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-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.linux @pytest.mark.host_test +@idf_parametrize('target', ['linux'], indirect=['target']) def test_esp_partition_linux(dut: Dut) -> None: dut.expect_unity_test_output(timeout=5) diff --git a/components/esp_pm/test_apps/esp_pm/pytest_esp_pm.py b/components/esp_pm/test_apps/esp_pm/pytest_esp_pm.py index 2c246b9938..2cd49b5884 100644 --- a/components/esp_pm/test_apps/esp_pm/pytest_esp_pm.py +++ b/components/esp_pm/test_apps/esp_pm/pytest_esp_pm.py @@ -1,61 +1,57 @@ -# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2024-2025 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.generic -@pytest.mark.supported_targets @pytest.mark.temp_skip_ci(targets=['esp32c61'], reason='not supported yet') # TODO: [ESP32C61] IDF-9250 IDF-10985 -@pytest.mark.parametrize('config', [ - 'default', - 'slp_iram_opt', - 'limits', - 'options', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'default', + 'slp_iram_opt', + 'limits', + 'options', + ], + indirect=True, +) +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_esp_pm(dut: Dut) -> None: dut.run_all_single_board_cases() # psram attr tests with xip_psram -@pytest.mark.esp32s2 @pytest.mark.generic @pytest.mark.parametrize( 'config', - [ - 'pm_xip_psram_esp32s2' - ], + ['pm_xip_psram_esp32s2'], indirect=True, ) +@idf_parametrize('target', ['esp32s2'], indirect=['target']) def test_esp_attr_xip_psram_esp32s2(dut: Dut) -> None: dut.run_all_single_board_cases() # psram attr tests with xip_psram -@pytest.mark.esp32s3 @pytest.mark.generic @pytest.mark.parametrize( 'config', - [ - 'pm_xip_psram_esp32s3' - ], + ['pm_xip_psram_esp32s3'], indirect=True, ) +@idf_parametrize('target', ['esp32s3'], indirect=['target']) def test_esp_attr_xip_psram_esp32s3(dut: Dut) -> None: dut.run_all_single_board_cases() # power down CPU and TOP domain in auto-lightsleep -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 @pytest.mark.generic @pytest.mark.parametrize( 'config', - [ - 'pm_pd_top_sleep' - ], + ['pm_pd_top_sleep'], ) +@idf_parametrize('target', ['esp32c5', 'esp32c6', 'esp32h2', 'esp32p4'], indirect=['target']) def test_esp_pd_top_and_cpu_sleep(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_psram/test_apps/psram/pytest_psram.py b/components/esp_psram/test_apps/psram/pytest_psram.py index e13d48e803..cf5d41b7d4 100644 --- a/components/esp_psram/test_apps/psram/pytest_psram.py +++ b/components/esp_psram/test_apps/psram/pytest_psram.py @@ -1,10 +1,10 @@ -# SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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.generic @pytest.mark.parametrize( 'config', @@ -14,11 +14,11 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_psram_esp32(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32 @pytest.mark.psramv0 @pytest.mark.parametrize( 'config', @@ -28,11 +28,11 @@ def test_psram_esp32(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_psram_esp32_psramv0(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32s2 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -42,11 +42,11 @@ def test_psram_esp32_psramv0(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32s2'], indirect=['target']) def test_psram_esp32s2(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32s3 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -56,11 +56,11 @@ def test_psram_esp32s2(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32s3'], indirect=['target']) def test_psram_esp32s3(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32s3 @pytest.mark.octal_psram @pytest.mark.parametrize( 'config', @@ -70,25 +70,22 @@ def test_psram_esp32s3(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32s3'], indirect=['target']) def test_psram_esp32s3_octal(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32p4 @pytest.mark.generic @pytest.mark.parametrize( 'config', - [ - 'esp32p4_200m_release', - 'esp32p4_xip' - ], + ['esp32p4_200m_release', 'esp32p4_xip'], indirect=True, ) +@idf_parametrize('target', ['esp32p4'], indirect=['target']) def test_psram_esp32p4(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32c5 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -98,11 +95,11 @@ def test_psram_esp32p4(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32c5'], indirect=['target']) def test_psram_esp32c5(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32c61 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -112,5 +109,6 @@ def test_psram_esp32c5(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32c61'], indirect=['target']) def test_psram_esp32c61(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_ringbuf/test_apps/pytest_esp_ringbuf.py b/components/esp_ringbuf/test_apps/pytest_esp_ringbuf.py index 47b0dde7d5..ca44dcfa16 100644 --- a/components/esp_ringbuf/test_apps/pytest_esp_ringbuf.py +++ b/components/esp_ringbuf/test_apps/pytest_esp_ringbuf.py @@ -1,39 +1,52 @@ -# 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 pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize @pytest.mark.generic -@pytest.mark.parametrize('target', [ - 'esp32', - 'esp32s2', -]) -@pytest.mark.parametrize('config', [ - 'default', - 'ringbuf_flash', -]) +@pytest.mark.parametrize( + 'target', + [ + 'esp32', + 'esp32s2', + ], +) +@pytest.mark.parametrize( + 'config', + [ + 'default', + 'ringbuf_flash', + ], +) def test_esp_ringbuf(dut: Dut) -> None: dut.run_all_single_board_cases() @pytest.mark.host_test @pytest.mark.qemu -@pytest.mark.parametrize('target', [ - 'esp32', - 'esp32c3', -]) -@pytest.mark.parametrize('config', [ - 'default', - 'ringbuf_flash', -]) +@pytest.mark.parametrize( + 'target', + [ + 'esp32', + 'esp32c3', + ], +) +@pytest.mark.parametrize( + 'config', + [ + 'default', + 'ringbuf_flash', + ], +) def test_esp_ringbuf_qemu(dut: Dut) -> None: for case in dut.test_menu: if 'qemu-ignore' not in case.groups and not case.is_ignored and case.type == 'normal': dut._run_normal_case(case) -@pytest.mark.linux @pytest.mark.host_test +@idf_parametrize('target', ['linux'], indirect=['target']) def test_esp_ringbuf_posix_simulator(dut: Dut) -> None: dut.run_all_single_board_cases(group='linux') diff --git a/components/esp_rom/test_apps/linux_rom_apis/pytest_esp_rom_linux.py b/components/esp_rom/test_apps/linux_rom_apis/pytest_esp_rom_linux.py index c9985e1123..0d2a4b48fd 100644 --- a/components/esp_rom/test_apps/linux_rom_apis/pytest_esp_rom_linux.py +++ b/components/esp_rom/test_apps/linux_rom_apis/pytest_esp_rom_linux.py @@ -1,10 +1,11 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-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.linux @pytest.mark.host_test +@idf_parametrize('target', ['linux'], indirect=['target']) def test_esp_rom_linux(dut: Dut) -> None: dut.expect_exact('All tests passed', timeout=5) diff --git a/components/esp_rom/test_apps/rom_impl_components/pytest_esp_rom_impl_components.py b/components/esp_rom/test_apps/rom_impl_components/pytest_esp_rom_impl_components.py index a400d9e69b..4efbe677c0 100644 --- a/components/esp_rom/test_apps/rom_impl_components/pytest_esp_rom_impl_components.py +++ b/components/esp_rom/test_apps/rom_impl_components/pytest_esp_rom_impl_components.py @@ -1,10 +1,10 @@ -# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2024-2025 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.supported_targets @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -14,5 +14,6 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_esp_rom_impl_components(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_rom/test_apps/rom_tests/pytest_esp_rom.py b/components/esp_rom/test_apps/rom_tests/pytest_esp_rom.py index 28b068c5ce..0bc7bfef1a 100644 --- a/components/esp_rom/test_apps/rom_tests/pytest_esp_rom.py +++ b/components/esp_rom/test_apps/rom_tests/pytest_esp_rom.py @@ -1,24 +1,22 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 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.esp32c3 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32c61 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 @pytest.mark.generic +@idf_parametrize( + 'target', + ['esp32c3', 'esp32s2', 'esp32s3', 'esp32c5', 'esp32c6', 'esp32c61', 'esp32h2', 'esp32p4'], + indirect=['target'], +) def test_esp_rom(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32c3 @pytest.mark.host_test @pytest.mark.qemu +@idf_parametrize('target', ['esp32c3'], indirect=['target']) def test_esp_rom_qemu(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_security/test_apps/crypto_drivers/pytest_crypto_drivers.py b/components/esp_security/test_apps/crypto_drivers/pytest_crypto_drivers.py index 44435595f0..8e697da9af 100644 --- a/components/esp_security/test_apps/crypto_drivers/pytest_crypto_drivers.py +++ b/components/esp_security/test_apps/crypto_drivers/pytest_crypto_drivers.py @@ -1,16 +1,13 @@ -# 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 pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32c3 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 -@pytest.mark.esp32c5 @pytest.mark.generic +@idf_parametrize( + 'target', ['esp32s2', 'esp32s3', 'esp32c3', 'esp32c6', 'esp32h2', 'esp32p4', 'esp32c5'], indirect=['target'] +) def test_crypto_drivers(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=180) diff --git a/components/esp_system/test_apps/cache_panic/pytest_cache_panic_test.py b/components/esp_system/test_apps/cache_panic/pytest_cache_panic_test.py index f107e348a0..4c169b54e9 100644 --- a/components/esp_system/test_apps/cache_panic/pytest_cache_panic_test.py +++ b/components/esp_system/test_apps/cache_panic/pytest_cache_panic_test.py @@ -1,10 +1,11 @@ -# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 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.supported_targets @pytest.mark.generic +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_cache_panic(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/esp_system/test_apps/console/pytest_esp_system_console_tests.py b/components/esp_system/test_apps/console/pytest_esp_system_console_tests.py index 2625d583ac..e7506c0da8 100644 --- a/components/esp_system/test_apps/console/pytest_esp_system_console_tests.py +++ b/components/esp_system/test_apps/console/pytest_esp_system_console_tests.py @@ -1,8 +1,9 @@ -# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import pexpect import pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize def not_expect(dut: Dut, output_regex: str) -> None: @@ -24,26 +25,18 @@ JTAG_SERIAL_MARKS = [ @pytest.mark.generic -@pytest.mark.parametrize( - 'config', - [ - pytest.param('console_none', marks=pytest.mark.supported_targets), - ], - indirect=True -) +@idf_parametrize('config', ['console_none'], indirect=['config']) +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_esp_system_console_no_output_uart(dut: Dut) -> None: not_expect(dut, r'2nd stage bootloader|Hello World') dut.expect('This message will be printed even with CONFIG_ESP_CONSOLE_NONE') @pytest.mark.usb_serial_jtag -@pytest.mark.parametrize( - 'port, flash_port, config', - [ - pytest.param('/dev/serial_ports/ttyACM-esp32', '/dev/serial_ports/ttyUSB-esp32', 'serial_jtag_only', marks=JTAG_SERIAL_MARKS), - ], - indirect=True, -) +@idf_parametrize('config', ['serial_jtag_only'], indirect=['config']) +@idf_parametrize('flash_port', ['/dev/serial_ports/ttyUSB-esp32'], indirect=['flash_port']) +@idf_parametrize('port', ['/dev/serial_ports/ttyACM-esp32'], indirect=['port']) +@idf_parametrize('target', ['esp32c2', 'esp32c3', 'esp32c6', 'esp32h2', 'esp32s3'], indirect=['target']) def test_esp_system_console_only_serial_jtag(dut: Dut) -> None: dut.expect('2nd stage bootloader') dut.expect('Hello World') @@ -54,26 +47,18 @@ def test_esp_system_console_only_serial_jtag(dut: Dut) -> None: @pytest.mark.usb_serial_jtag -@pytest.mark.parametrize( - 'port, flash_port, config', - [ - pytest.param('/dev/serial_ports/ttyACM-esp32', '/dev/serial_ports/ttyUSB-esp32', 'serial_jtag_only_no_vfs', marks=JTAG_SERIAL_MARKS), - ], - indirect=True, -) +@idf_parametrize('config', ['serial_jtag_only_no_vfs'], indirect=['config']) +@idf_parametrize('flash_port', ['/dev/serial_ports/ttyUSB-esp32'], indirect=['flash_port']) +@idf_parametrize('port', ['/dev/serial_ports/ttyACM-esp32'], indirect=['port']) +@idf_parametrize('target', ['esp32c2', 'esp32c3', 'esp32c6', 'esp32h2', 'esp32s3'], indirect=['target']) def test_esp_system_console_only_serial_jtag_no_vfs(dut: Dut) -> None: dut.expect('2nd stage bootloader') dut.expect('Hello World') @pytest.mark.generic -@pytest.mark.parametrize( - 'config', - [ - pytest.param('simple', marks=pytest.mark.supported_targets), - ], - indirect=True -) +@idf_parametrize('config', ['simple'], indirect=['config']) +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_esp_system_console_correct_open_and_close(dut: Dut) -> None: dut.expect('2nd stage bootloader') dut.expect('Hello World') diff --git a/components/esp_system/test_apps/esp_system_unity_tests/pytest_esp_system_unity_tests.py b/components/esp_system/test_apps/esp_system_unity_tests/pytest_esp_system_unity_tests.py index f0fc1bb0a4..3d0d92f227 100644 --- a/components/esp_system/test_apps/esp_system_unity_tests/pytest_esp_system_unity_tests.py +++ b/components/esp_system/test_apps/esp_system_unity_tests/pytest_esp_system_unity_tests.py @@ -2,18 +2,23 @@ # 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', +@idf_parametrize( + 'config,target', [ - pytest.param('default', marks=[pytest.mark.supported_targets]), - pytest.param('pd_vddsdio', marks=[pytest.mark.supported_targets]), - pytest.param('psram', marks=[pytest.mark.esp32, pytest.mark.esp32s2, pytest.mark.esp32s3, pytest.mark.esp32p4]), - pytest.param('psram_with_pd_top', marks=[pytest.mark.esp32p4]), - pytest.param('single_core_esp32', marks=[pytest.mark.esp32]), - ] + ('default', 'supported_targets'), + ('pd_vddsdio', 'supported_targets'), + ('psram', 'esp32'), + ('psram', 'esp32p4'), + ('psram', 'esp32s2'), + ('psram', 'esp32s3'), + ('psram_with_pd_top', 'esp32p4'), + ('single_core_esp32', 'esp32'), + ], + indirect=['config', 'target'], ) def test_esp_system(dut: Dut) -> None: # esp32p4 32MB PSRAM initialize in startup takes more than 30 sec @@ -21,12 +26,8 @@ def test_esp_system(dut: Dut) -> None: @pytest.mark.generic -@pytest.mark.parametrize( - 'config', - [ - pytest.param('default', marks=[pytest.mark.supported_targets]), - ] -) +@idf_parametrize('config', ['default'], indirect=['config']) +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_stack_smash_protection(dut: Dut) -> None: dut.expect_exact('Press ENTER to see the list of tests') dut.write('"stack smashing protection"') @@ -35,13 +36,8 @@ def test_stack_smash_protection(dut: Dut) -> None: @pytest.mark.generic -@pytest.mark.parametrize( - 'config', - [ - # Testing this feature on a single RISC-V target is enough - pytest.param('framepointer', marks=[pytest.mark.esp32c3]), - ] -) +@idf_parametrize('config', ['framepointer'], indirect=['config']) +@idf_parametrize('target', ['esp32c3'], indirect=['target']) def test_frame_pointer_backtracing(dut: Dut) -> None: dut.expect_exact('Press ENTER to see the list of tests') dut.write('"Backtrace detects corrupted frames"') diff --git a/components/esp_system/test_apps/linux_apis/pytest_esp_system_linux.py b/components/esp_system/test_apps/linux_apis/pytest_esp_system_linux.py index 811afecc86..279dc5b237 100644 --- a/components/esp_system/test_apps/linux_apis/pytest_esp_system_linux.py +++ b/components/esp_system/test_apps/linux_apis/pytest_esp_system_linux.py @@ -1,10 +1,11 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-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.linux @pytest.mark.host_test +@idf_parametrize('target', ['linux'], indirect=['target']) def test_esp_system_linux(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=60) diff --git a/components/esp_tee/test_apps/tee_cli_app/pytest_tee_cli.py b/components/esp_tee/test_apps/tee_cli_app/pytest_tee_cli.py index ef948dbc7b..35ebd12a42 100644 --- a/components/esp_tee/test_apps/tee_cli_app/pytest_tee_cli.py +++ b/components/esp_tee/test_apps/tee_cli_app/pytest_tee_cli.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Apache-2.0 import hashlib import http.server @@ -21,6 +21,7 @@ from ecdsa.curves import NIST256p from ecdsa.keys import VerifyingKey from ecdsa.util import sigdecode_der from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize from RangeHTTPServer import RangeRequestHandler TEST_MSG = 'hello world' @@ -34,8 +35,8 @@ key_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'test_certs/ ########################### -@pytest.mark.esp32c6 @pytest.mark.generic +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_tee_cli_secure_storage(dut: Dut) -> None: # Dumping the REE binary size binary_file = os.path.join(dut.app.binary_path, 'tee_cli.bin') @@ -80,9 +81,10 @@ def test_tee_cli_secure_storage(dut: Dut) -> None: dut.write(f'tee_sec_stg_decrypt {sec_stg_slots.get(i)} {test_msg_cipher} {test_msg_tag}') test_msg_decipher = dut.expect(r'Decrypted plaintext -\s*([0-9a-fA-F]{64})', timeout=30)[1].decode() - assert (test_msg_decipher == test_msg_hash) + assert test_msg_decipher == test_msg_hash time.sleep(1) + ######################## # ESP-TEE: Attestation # ######################## @@ -119,8 +121,8 @@ def verify_att_token_signature(att_tk: str) -> Any: return vk.verify_digest(signature, digest, sigdecode=sigdecode_der) -@pytest.mark.esp32c6 @pytest.mark.generic +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_tee_cli_attestation(dut: Dut) -> None: # Dumping the REE binary size binary_file = os.path.join(dut.app.binary_path, 'tee_cli.bin') @@ -141,15 +143,17 @@ def test_tee_cli_attestation(dut: Dut) -> None: att_tk = dut.expect(r"'(.*?)'", timeout=30)[1].decode() assert verify_att_token_signature(att_tk) + ####################################### # ESP-TEE: Over-the-Air (OTA) updates # ####################################### -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): def finish(self) -> None: try: @@ -174,14 +178,12 @@ def start_https_server(ota_image_dir: str, server_ip: str, server_port: int) -> requestHandler = https_request_handler() httpd = http.server.HTTPServer((server_ip, server_port), requestHandler) - httpd.socket = ssl.wrap_socket(httpd.socket, - keyfile=key_file, - certfile=server_file, server_side=True) + httpd.socket = ssl.wrap_socket(httpd.socket, keyfile=key_file, certfile=server_file, server_side=True) httpd.serve_forever() -@pytest.mark.esp32c6 @pytest.mark.wifi_high_traffic +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_tee_cli_secure_ota_wifi(dut: Dut) -> None: """ This is a positive test case, which downloads complete binary file multiple number of times. diff --git a/components/esp_tee/test_apps/tee_test_fw/pytest_esp_tee_ut.py b/components/esp_tee/test_apps/tee_test_fw/pytest_esp_tee_ut.py index 6bbed77791..ec47009f7f 100644 --- a/components/esp_tee/test_apps/tee_test_fw/pytest_esp_tee_ut.py +++ b/components/esp_tee/test_apps/tee_test_fw/pytest_esp_tee_ut.py @@ -6,19 +6,13 @@ from typing import Dict import pytest from pytest_embedded_idf import IdfDut +from pytest_embedded_idf.utils import idf_parametrize -CONFIGS_DEFAULT = [ - pytest.param('default', marks=[pytest.mark.esp32c6]) -] +CONFIGS_DEFAULT = [pytest.param('default', marks=[pytest.mark.esp32c6])] -CONFIGS_OTA = [ - pytest.param('ota', marks=[pytest.mark.esp32c6]) -] +CONFIGS_OTA = [pytest.param('ota', marks=[pytest.mark.esp32c6])] -CONFIGS_ALL = [ - pytest.param('default', marks=[pytest.mark.esp32c6]), - pytest.param('ota', marks=[pytest.mark.esp32c6]) -] +CONFIGS_ALL = [pytest.param('default', marks=[pytest.mark.esp32c6]), pytest.param('ota', marks=[pytest.mark.esp32c6])] TEE_VIOLATION_TEST_EXC_RSN: Dict[str, Any] = { 'esp32c6': { @@ -27,7 +21,7 @@ TEE_VIOLATION_TEST_EXC_RSN: Dict[str, Any] = { ('IRAM', 'W1'): 'Store access fault', ('IRAM', 'W2'): 'Store access fault', ('DRAM', 'X1'): 'Instruction access fault', - ('DRAM', 'X2'): 'Instruction access fault' + ('DRAM', 'X2'): 'Instruction access fault', } } @@ -53,20 +47,23 @@ TEST_PARTITION_LABEL = 'test' @pytest.mark.generic -@pytest.mark.parametrize('config', CONFIGS_DEFAULT, indirect=True) +@idf_parametrize('config', ['default'], indirect=['config']) +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_esp_tee(dut: IdfDut) -> None: dut.run_all_single_board_cases(group='basic') @pytest.mark.generic -@pytest.mark.parametrize('config', CONFIGS_ALL, indirect=True) +@idf_parametrize('config', ['default', 'ota'], indirect=['config']) +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_esp_tee_crypto_aes(dut: IdfDut) -> None: dut.run_all_single_board_cases(group='aes') dut.run_all_single_board_cases(group='aes-gcm') @pytest.mark.generic -@pytest.mark.parametrize('config', CONFIGS_ALL, indirect=True) +@idf_parametrize('config', ['default', 'ota'], indirect=['config']) +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_esp_tee_crypto_sha(dut: IdfDut) -> None: dut.run_all_single_board_cases(group='mbedtls') dut.run_all_single_board_cases(group='hw_crypto') @@ -74,7 +71,8 @@ def test_esp_tee_crypto_sha(dut: IdfDut) -> None: # NOTE: Stress testing the AES performance case for interrupt-related edge-cases @pytest.mark.generic -@pytest.mark.parametrize('config', CONFIGS_ALL, indirect=True) +@idf_parametrize('config', ['default', 'ota'], indirect=['config']) +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_esp_tee_aes_perf(dut: IdfDut) -> None: # start test for i in range(24): @@ -85,32 +83,36 @@ def test_esp_tee_aes_perf(dut: IdfDut) -> None: dut.write('"mbedtls AES performance"') dut.expect_unity_test_output(timeout=60) + # ---------------- TEE Exceptions generation Tests ---------------- @pytest.mark.generic -@pytest.mark.parametrize('config', CONFIGS_DEFAULT, indirect=True) +@idf_parametrize('config', ['default'], indirect=['config']) +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_esp_tee_apm_violation(dut: IdfDut) -> None: for check in TEE_APM_VIOLATION_EXC_CHK: dut.expect_exact('Press ENTER to see the list of tests') dut.write(f'"Test APM violation interrupt: {check}"') - exc = dut.expect(r"Core ([01]) panic\'ed \(([^)]+)\)", timeout=30).group(2).decode() + exc = dut.expect(r'Core ([01]) panic\'ed \(([^)]+)\)', timeout=30).group(2).decode() if exc != 'Authority exception': raise RuntimeError('Incorrect exception received!') @pytest.mark.generic -@pytest.mark.parametrize('config', CONFIGS_DEFAULT, indirect=True) +@idf_parametrize('config', ['default'], indirect=['config']) +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_esp_tee_illegal_instruction(dut: IdfDut) -> None: dut.expect_exact('Press ENTER to see the list of tests') dut.write(f'"Test TEE-TEE violation: Illegal Instruction"') - exc = dut.expect(r"Core ([01]) panic\'ed \(([^)]+)\)", timeout=30).group(2).decode() + exc = dut.expect(r'Core ([01]) panic\'ed \(([^)]+)\)', timeout=30).group(2).decode() if exc != 'Illegal instruction': raise RuntimeError('Incorrect exception received!') @pytest.mark.generic -@pytest.mark.parametrize('config', CONFIGS_DEFAULT, indirect=True) +@idf_parametrize('config', ['default'], indirect=['config']) +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_esp_tee_violation_checks(dut: IdfDut) -> None: checks_list = TEE_VIOLATION_TEST_EXC_RSN[dut.target] for test in checks_list: @@ -120,13 +122,14 @@ def test_esp_tee_violation_checks(dut: IdfDut) -> None: continue dut.expect_exact('Press ENTER to see the list of tests') dut.write(f'"Test TEE-TEE violation: {memory} ({access_type})"') - actual_exc = dut.expect(r"Core ([01]) panic\'ed \(([^)]+)\)", timeout=30).group(2).decode() + actual_exc = dut.expect(r'Core ([01]) panic\'ed \(([^)]+)\)', timeout=30).group(2).decode() if actual_exc != expected_exc: raise RuntimeError('Incorrect exception received!') @pytest.mark.generic -@pytest.mark.parametrize('config', CONFIGS_DEFAULT, indirect=True) +@idf_parametrize('config', ['default'], indirect=['config']) +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_esp_tee_isolation_checks(dut: IdfDut) -> None: checks_list = REE_ISOLATION_TEST_EXC_RSN[dut.target] for test in checks_list: @@ -136,11 +139,12 @@ def test_esp_tee_isolation_checks(dut: IdfDut) -> None: continue dut.expect_exact('Press ENTER to see the list of tests') dut.write(f'"Test REE-TEE isolation: {memory} ({access_type})"') - actual_exc = dut.expect(r"Core ([01]) panic\'ed \(([^)]+)\)", timeout=30).group(2).decode() + actual_exc = dut.expect(r'Core ([01]) panic\'ed \(([^)]+)\)', timeout=30).group(2).decode() if actual_exc != expected_exc: raise RuntimeError('Incorrect exception received!') dut.expect('Exception origin: U-mode') + # ---------------- TEE Flash Protection Tests ---------------- @@ -154,7 +158,7 @@ class TeeFlashAccessApi(Enum): def check_panic_or_reset(dut: IdfDut) -> None: try: - exc = dut.expect(r"Core ([01]) panic\'ed \(([^)]+)\)", timeout=5).group(2).decode() + exc = dut.expect(r'Core ([01]) panic\'ed \(([^)]+)\)', timeout=5).group(2).decode() if exc not in {'Cache error', 'Authority exception'}: raise RuntimeError('Flash operation incorrect exception') except Exception: @@ -167,7 +171,7 @@ def check_panic_or_reset(dut: IdfDut) -> None: def run_multiple_stages(dut: IdfDut, test_case_num: int, stages: int, api: TeeFlashAccessApi) -> None: exp_seq = { TeeFlashAccessApi.ESP_PARTITION: ['read', 'program_page', 'program_page', 'erase_sector'], - TeeFlashAccessApi.ESP_FLASH: ['program_page', 'read', 'erase_sector', 'program_page'] + TeeFlashAccessApi.ESP_FLASH: ['program_page', 'read', 'erase_sector', 'program_page'], } for stage in range(1, stages + 1): @@ -178,7 +182,9 @@ def run_multiple_stages(dut: IdfDut, test_case_num: int, stages: int, api: TeeFl if 1 < stage <= stages: if api in exp_seq: try: - match = dut.expect(r'\[_ss_spi_flash_hal_(\w+)\] Illegal flash access at \s*(0x[0-9a-fA-F]+)', timeout=5) + match = dut.expect( + r'\[_ss_spi_flash_hal_(\w+)\] Illegal flash access at \s*(0x[0-9a-fA-F]+)', timeout=5 + ) fault_api = match.group(1).decode() if fault_api != exp_seq[api][stage - 2]: raise RuntimeError('Flash operation address check failed') @@ -186,7 +192,7 @@ def run_multiple_stages(dut: IdfDut, test_case_num: int, stages: int, api: TeeFl # NOTE: The esp_partition_read API handles both decrypted # and plaintext reads. When flash encryption is enabled, # it uses the MMU HAL instead of the SPI flash HAL. - exc = dut.expect(r"Core ([01]) panic\'ed \(([^)]+)\)", timeout=5).group(2).decode() + exc = dut.expect(r'Core ([01]) panic\'ed \(([^)]+)\)', timeout=5).group(2).decode() if exc != 'Cache error': raise RuntimeError('Flash operation incorrect exception') else: @@ -197,8 +203,9 @@ def run_multiple_stages(dut: IdfDut, test_case_num: int, stages: int, api: TeeFl @pytest.mark.generic -@pytest.mark.parametrize('config', CONFIGS_OTA, indirect=True) -@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True) +@idf_parametrize('config', ['ota'], indirect=['config']) +@idf_parametrize('skip_autoflash', ['y'], indirect=['skip_autoflash']) +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_esp_tee_flash_prot_esp_partition_mmap(dut: IdfDut) -> None: # Flash the bootloader, TEE and REE firmware dut.serial.custom_flash() @@ -213,8 +220,9 @@ def test_esp_tee_flash_prot_esp_partition_mmap(dut: IdfDut) -> None: @pytest.mark.generic -@pytest.mark.parametrize('config', CONFIGS_OTA, indirect=True) -@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True) +@idf_parametrize('config', ['ota'], indirect=['config']) +@idf_parametrize('skip_autoflash', ['y'], indirect=['skip_autoflash']) +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_esp_tee_flash_prot_spi_flash_mmap(dut: IdfDut) -> None: # Flash the bootloader, TEE and REE firmware dut.serial.custom_flash() @@ -229,8 +237,9 @@ def test_esp_tee_flash_prot_spi_flash_mmap(dut: IdfDut) -> None: @pytest.mark.generic -@pytest.mark.parametrize('config', CONFIGS_OTA, indirect=True) -@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True) +@idf_parametrize('config', ['ota'], indirect=['config']) +@idf_parametrize('skip_autoflash', ['y'], indirect=['skip_autoflash']) +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_esp_tee_flash_prot_esp_rom_spiflash(dut: IdfDut) -> None: # Flash the bootloader, TEE and REE firmware dut.serial.custom_flash() @@ -245,8 +254,9 @@ def test_esp_tee_flash_prot_esp_rom_spiflash(dut: IdfDut) -> None: @pytest.mark.generic -@pytest.mark.parametrize('config', CONFIGS_OTA, indirect=True) -@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True) +@idf_parametrize('config', ['ota'], indirect=['config']) +@idf_parametrize('skip_autoflash', ['y'], indirect=['skip_autoflash']) +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_esp_tee_flash_prot_esp_partition(dut: IdfDut) -> None: # Flash the bootloader, TEE and REE firmware dut.serial.custom_flash() @@ -261,8 +271,9 @@ def test_esp_tee_flash_prot_esp_partition(dut: IdfDut) -> None: @pytest.mark.generic -@pytest.mark.parametrize('config', CONFIGS_OTA, indirect=True) -@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True) +@idf_parametrize('config', ['ota'], indirect=['config']) +@idf_parametrize('skip_autoflash', ['y'], indirect=['skip_autoflash']) +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_esp_tee_flash_prot_esp_flash(dut: IdfDut) -> None: # Flash the bootloader, TEE and REE firmware dut.serial.custom_flash() @@ -275,11 +286,13 @@ def test_esp_tee_flash_prot_esp_flash(dut: IdfDut) -> None: else: continue + # ---------------- TEE Local OTA tests ---------------- @pytest.mark.generic -@pytest.mark.parametrize('config', CONFIGS_OTA, indirect=True) +@idf_parametrize('config', ['ota'], indirect=['config']) +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_esp_tee_ota_negative(dut: IdfDut) -> None: # start test dut.expect_exact('Press ENTER to see the list of tests') @@ -291,8 +304,9 @@ def test_esp_tee_ota_negative(dut: IdfDut) -> None: @pytest.mark.generic -@pytest.mark.parametrize('config', CONFIGS_OTA, indirect=True) -@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True) +@idf_parametrize('config', ['ota'], indirect=['config']) +@idf_parametrize('skip_autoflash', ['y'], indirect=['skip_autoflash']) +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_esp_tee_ota_corrupted_img(dut: IdfDut) -> None: # Flashing the TEE app to the non-secure app's passive partition dut.serial.custom_flash_w_test_tee_img_gen() @@ -328,8 +342,9 @@ def tee_ota_stage_checks(dut: IdfDut, stage: TeeOtaStage, offset: str) -> None: @pytest.mark.generic -@pytest.mark.parametrize('config', CONFIGS_OTA, indirect=True) -@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True) +@idf_parametrize('config', ['ota'], indirect=['config']) +@idf_parametrize('skip_autoflash', ['y'], indirect=['skip_autoflash']) +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_esp_tee_ota_reboot_without_ota_end(dut: IdfDut) -> None: # Flashing the TEE app to the non-secure app's passive partition dut.serial.custom_flash_w_test_tee_img_gen() @@ -352,8 +367,9 @@ def test_esp_tee_ota_reboot_without_ota_end(dut: IdfDut) -> None: @pytest.mark.generic -@pytest.mark.parametrize('config', CONFIGS_OTA, indirect=True) -@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True) +@idf_parametrize('config', ['ota'], indirect=['config']) +@idf_parametrize('skip_autoflash', ['y'], indirect=['skip_autoflash']) +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_esp_tee_ota_valid_img(dut: IdfDut) -> None: # Flashing the TEE app to the non-secure app's passive partition dut.serial.custom_flash_w_test_tee_img_gen() @@ -384,8 +400,9 @@ def test_esp_tee_ota_valid_img(dut: IdfDut) -> None: @pytest.mark.generic -@pytest.mark.parametrize('config', CONFIGS_OTA, indirect=True) -@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True) +@idf_parametrize('config', ['ota'], indirect=['config']) +@idf_parametrize('skip_autoflash', ['y'], indirect=['skip_autoflash']) +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_esp_tee_ota_rollback(dut: IdfDut) -> None: # Flashing the TEE app to the non-secure app's passive partition dut.serial.custom_flash_w_test_tee_img_rb() @@ -416,24 +433,28 @@ def test_esp_tee_ota_rollback(dut: IdfDut) -> None: # erasing TEE otadata dut.serial.erase_partition('tee_otadata') + # ---------------- TEE Secure Storage tests ---------------- @pytest.mark.generic -@pytest.mark.parametrize('config', CONFIGS_OTA, indirect=True) -@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True) +@idf_parametrize('config', ['ota'], indirect=['config']) +@idf_parametrize('skip_autoflash', ['y'], indirect=['skip_autoflash']) +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_esp_tee_secure_storage(dut: IdfDut) -> None: # Flash image and erase the secure_storage partition dut.serial.custom_flash_with_empty_sec_stg() dut.run_all_single_board_cases(group='secure_storage') + # ---------------- TEE Attestation tests ---------------- @pytest.mark.generic -@pytest.mark.parametrize('config', CONFIGS_OTA, indirect=True) -@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True) +@idf_parametrize('config', ['ota'], indirect=['config']) +@idf_parametrize('skip_autoflash', ['y'], indirect=['skip_autoflash']) +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_esp_tee_attestation(dut: IdfDut) -> None: # Flash image and erase the secure_storage partition dut.serial.custom_flash_with_empty_sec_stg() diff --git a/components/esp_timer/test_apps/pytest_esp_timer_ut.py b/components/esp_timer/test_apps/pytest_esp_timer_ut.py index e7c23e9234..26e520e27b 100644 --- a/components/esp_timer/test_apps/pytest_esp_timer_ut.py +++ b/components/esp_timer/test_apps/pytest_esp_timer_ut.py @@ -1,7 +1,8 @@ -# 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 pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize CONFIGS = [ pytest.param('general', marks=[pytest.mark.supported_targets]), @@ -18,22 +19,40 @@ CONFIGS = [ @pytest.mark.generic -@pytest.mark.parametrize('config', CONFIGS, indirect=True) +@idf_parametrize( + 'config,target', + [ + ('general', 'supported_targets'), + ('release', 'supported_targets'), + ('single_core', 'esp32'), + ('freertos_compliance', 'esp32'), + ('isr_dispatch_esp32', 'esp32'), + ('isr_dispatch_esp32c3', 'esp32c3'), + ('cpu1_esp32', 'esp32'), + ('any_cpu_esp32', 'esp32'), + ('cpu1_esp32s3', 'esp32s3'), + ('any_cpu_esp32s3', 'esp32s3'), + ], + indirect=['config', 'target'], +) def test_esp_timer(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=120) -@pytest.mark.esp32 @pytest.mark.generic @pytest.mark.psram -@pytest.mark.parametrize('config', [ - 'psram', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'psram', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_esp_timer_psram(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=120) -@pytest.mark.esp32c2 @pytest.mark.generic @pytest.mark.xtal_26mhz @pytest.mark.parametrize( @@ -43,5 +62,6 @@ def test_esp_timer_psram(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32c2'], indirect=['target']) def test_esp_timer_esp32c2_xtal_26mhz(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=120) diff --git a/components/esp_vfs_console/test_apps/usb_cdc_vfs/pytest_usb_cdc_vfs.py b/components/esp_vfs_console/test_apps/usb_cdc_vfs/pytest_usb_cdc_vfs.py index b6c8503d45..5d3d30021f 100644 --- a/components/esp_vfs_console/test_apps/usb_cdc_vfs/pytest_usb_cdc_vfs.py +++ b/components/esp_vfs_console/test_apps/usb_cdc_vfs/pytest_usb_cdc_vfs.py @@ -2,17 +2,19 @@ # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32s3 @pytest.mark.usb_device @pytest.mark.parametrize( 'port, flash_port, config', [ pytest.param('/dev/serial_ports/ttyACM-esp32', '/dev/serial_ports/ttyUSB-esp32', 'release'), ], - indirect=True,) + indirect=True, +) @pytest.mark.parametrize('test_message', ['test123456789!@#%^&*']) +@idf_parametrize('target', ['esp32s3'], indirect=['target']) def test_usb_cdc_vfs_default(dut: Dut, test_message: str) -> None: # test run: test_usb_cdc_select dut.expect_exact('test_usb_cdc_select', timeout=2) diff --git a/components/esp_wifi/test_apps/wifi_connect/pytest_wifi_connect.py b/components/esp_wifi/test_apps/wifi_connect/pytest_wifi_connect.py index 8f52ec69e3..db91ffbcbf 100644 --- a/components/esp_wifi/test_apps/wifi_connect/pytest_wifi_connect.py +++ b/components/esp_wifi/test_apps/wifi_connect/pytest_wifi_connect.py @@ -1,23 +1,19 @@ -# 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 pytest from pytest_embedded_idf.unity_tester import CaseTester +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32 -@pytest.mark.esp32c3 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32c61 @pytest.mark.wifi_two_dut @pytest.mark.parametrize('count', [2], indirect=True) +@idf_parametrize( + 'target', ['esp32', 'esp32c3', 'esp32s2', 'esp32s3', 'esp32c5', 'esp32c6', 'esp32c61'], indirect=['target'] +) def test_wifi_connect_cases(case_tester: CaseTester) -> None: # type: ignore case_tester.run_all_cases() -@pytest.mark.esp32c2 @pytest.mark.wifi_two_dut @pytest.mark.xtal_26mhz @pytest.mark.parametrize( @@ -27,5 +23,6 @@ def test_wifi_connect_cases(case_tester: CaseTester) -> None: # type: ignore ], indirect=True, ) +@idf_parametrize('target', ['esp32c2'], indirect=['target']) def test_wifi_connect_cases_esp32c2_xtal26m(case_tester: CaseTester) -> None: case_tester.run_all_cases() diff --git a/components/esp_wifi/test_apps/wifi_function/pytest_wifi_function.py b/components/esp_wifi/test_apps/wifi_function/pytest_wifi_function.py index bdaa31ad27..6d39624d92 100644 --- a/components/esp_wifi/test_apps/wifi_function/pytest_wifi_function.py +++ b/components/esp_wifi/test_apps/wifi_function/pytest_wifi_function.py @@ -1,23 +1,19 @@ -# 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 pytest from pytest_embedded import Dut - - -@pytest.mark.esp32 -@pytest.mark.esp32c3 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32c6 -@pytest.mark.esp32c61 -@pytest.mark.esp32c5 +from pytest_embedded_idf.utils import idf_parametrize # @pytest.mark.esp32c2 # esp32c2 are using xtal_26mhz + + @pytest.mark.generic +@idf_parametrize( + 'target', ['esp32', 'esp32c3', 'esp32s2', 'esp32s3', 'esp32c6', 'esp32c61', 'esp32c5'], indirect=['target'] +) def test_wifi_unit_test(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32c2 @pytest.mark.xtal_26mhz @pytest.mark.generic @pytest.mark.parametrize( @@ -27,5 +23,6 @@ def test_wifi_unit_test(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32c2'], indirect=['target']) def test_wifi_unit_test_esp32c2_xtal26m(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/espcoredump/test_apps/pytest_coredump.py b/components/espcoredump/test_apps/pytest_coredump.py index c3e241a991..8685495c35 100644 --- a/components/espcoredump/test_apps/pytest_coredump.py +++ b/components/espcoredump/test_apps/pytest_coredump.py @@ -1,13 +1,11 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 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.esp32 -@pytest.mark.esp32c3 -@pytest.mark.esp32c2 +@idf_parametrize('target', ['esp32', 'esp32c3', 'esp32c2'], indirect=['target']) def test_coredump(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/fatfs/host_test/pytest_fatfs_linux.py b/components/fatfs/host_test/pytest_fatfs_linux.py index 7b12c361a1..e14e927a34 100644 --- a/components/fatfs/host_test/pytest_fatfs_linux.py +++ b/components/fatfs/host_test/pytest_fatfs_linux.py @@ -1,10 +1,11 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-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.linux @pytest.mark.host_test +@idf_parametrize('target', ['linux'], indirect=['target']) def test_fatfs_linux(dut: Dut) -> None: dut.expect_exact('All tests passed', timeout=120) diff --git a/components/fatfs/test_apps/flash_ro/pytest_fatfs_flash_ro.py b/components/fatfs/test_apps/flash_ro/pytest_fatfs_flash_ro.py index 3840e60f50..0339f8b6b3 100644 --- a/components/fatfs/test_apps/flash_ro/pytest_fatfs_flash_ro.py +++ b/components/fatfs/test_apps/flash_ro/pytest_fatfs_flash_ro.py @@ -1,11 +1,11 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 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_fatfs_flash_ro(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/fatfs/test_apps/flash_wl/pytest_fatfs_flash_wl.py b/components/fatfs/test_apps/flash_wl/pytest_fatfs_flash_wl.py index 9abd181502..add0149f51 100644 --- a/components/fatfs/test_apps/flash_wl/pytest_fatfs_flash_wl.py +++ b/components/fatfs/test_apps/flash_wl/pytest_fatfs_flash_wl.py @@ -1,11 +1,10 @@ -# 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 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', @@ -15,20 +14,21 @@ from pytest_embedded import Dut 'fastseek', 'auto_fsync', 'no_dyn_buffers', - ] + ], ) +@idf_parametrize('target', ['esp32', 'esp32c3'], indirect=['target']) def test_fatfs_flash_wl_generic(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=240) -@pytest.mark.esp32 @pytest.mark.generic @pytest.mark.psram @pytest.mark.parametrize( 'config', [ 'psram', - ] + ], ) +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_fatfs_flash_wl_psram(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=180) diff --git a/components/fatfs/test_apps/sdcard/pytest_fatfs_sdcard.py b/components/fatfs/test_apps/sdcard/pytest_fatfs_sdcard.py index b49aece201..b0657186d2 100644 --- a/components/fatfs/test_apps/sdcard/pytest_fatfs_sdcard.py +++ b/components/fatfs/test_apps/sdcard/pytest_fatfs_sdcard.py @@ -1,52 +1,50 @@ -# 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 pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32 -@pytest.mark.esp32c3 @pytest.mark.sdcard_sdmode @pytest.mark.parametrize( 'config', [ 'default', 'release', - ] + ], ) +@idf_parametrize('target', ['esp32', 'esp32c3'], indirect=['target']) def test_fatfs_sdcard_generic_sdmmc(dut: Dut) -> None: dut.run_all_single_board_cases(group='sdmmc', timeout=180) -@pytest.mark.esp32 @pytest.mark.temp_skip_ci(targets=['esp32'], reason='IDFCI-2058, temporary lack runner') -@pytest.mark.esp32c3 @pytest.mark.sdcard_spimode @pytest.mark.parametrize( 'config', [ 'default', 'release', - ] + ], ) +@idf_parametrize('target', ['esp32', 'esp32c3'], indirect=['target']) def test_fatfs_sdcard_generic_sdspi(dut: Dut) -> None: dut.run_all_single_board_cases(group='sdspi', timeout=180) -@pytest.mark.esp32 @pytest.mark.sdcard_sdmode @pytest.mark.psram @pytest.mark.parametrize( 'config', [ 'psram', - ] + ], ) +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_fatfs_sdcard_psram_sdmmc(dut: Dut) -> None: dut.run_all_single_board_cases(group='sdmmc', timeout=180) -@pytest.mark.esp32 @pytest.mark.temp_skip_ci(targets=['esp32'], reason='IDFCI-2058, temporary lack runner') @pytest.mark.sdcard_spimode @pytest.mark.psram @@ -54,7 +52,8 @@ def test_fatfs_sdcard_psram_sdmmc(dut: Dut) -> None: 'config', [ 'psram', - ] + ], ) +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_fatfs_sdcard_psram_sdspi(dut: Dut) -> None: dut.run_all_single_board_cases(group='sdspi', timeout=180) diff --git a/components/freertos/test_apps/freertos/pytest_freertos.py b/components/freertos/test_apps/freertos/pytest_freertos.py index 15d798b931..6ea7c3cf78 100644 --- a/components/freertos/test_apps/freertos/pytest_freertos.py +++ b/components/freertos/test_apps/freertos/pytest_freertos.py @@ -1,57 +1,88 @@ -# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 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 CONFIGS = [ - pytest.param('default', marks=[pytest.mark.supported_targets,]), + pytest.param( + 'default', + marks=[ + pytest.mark.supported_targets, + ], + ), pytest.param('freertos_options', marks=[pytest.mark.supported_targets]), pytest.param('psram', marks=[pytest.mark.esp32, pytest.mark.esp32s3, pytest.mark.esp32p4, pytest.mark.esp32c5]), pytest.param('single_core', marks=[pytest.mark.esp32, pytest.mark.esp32p4]), # TODO: [ESP32C5] IDF-10335 # TODO: [ESP32C61] IDF-11146 - pytest.param('smp', marks=[ - pytest.mark.supported_targets, - pytest.mark.temp_skip_ci(targets=['esp32p4', 'esp32c5', 'esp32c61', 'esp32h21'], - reason='test failed/TBD IDF-8113') - ]), + pytest.param( + 'smp', + marks=[ + pytest.mark.supported_targets, + pytest.mark.temp_skip_ci( + targets=['esp32p4', 'esp32c5', 'esp32c61', 'esp32h21'], reason='test failed/TBD IDF-8113' + ), + ], + ), ] @pytest.mark.generic -@pytest.mark.parametrize('config', CONFIGS, indirect=True) +@idf_parametrize( + 'config,target,markers', + [ + ('default', 'supported_targets'), + ('freertos_options', 'supported_targets'), + ('psram', 'esp32'), + ('psram', 'esp32c5'), + ('psram', 'esp32p4'), + ('psram', 'esp32s3'), + ('single_core', 'esp32'), + ('single_core', 'esp32p4'), + ( + 'smp', + 'supported_targets', + ( + pytest.mark.temp_skip_ci( + targets=['esp32p4', 'esp32c5', 'esp32c61', 'esp32h21'], reason='test failed/TBD IDF-8113' + ), + ), + ), + ], + indirect=['config', 'target'], +) def test_freertos(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.supported_targets @pytest.mark.generic @pytest.mark.parametrize('config', ['freertos_options'], indirect=True) +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_task_notify_too_high_index_fails(dut: Dut) -> None: dut.expect_exact('Press ENTER to see the list of tests.') - dut.write('\"Notify too high index fails\"') + dut.write('"Notify too high index fails"') dut.expect('assert failed: xTaskGenericNotify', timeout=5) dut.expect('uxIndexToNotify < [0-9]+') dut.expect_exact('Rebooting...') -@pytest.mark.supported_targets @pytest.mark.generic @pytest.mark.parametrize('config', ['freertos_options'], indirect=True) +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_task_notify_wait_too_high_index_fails(dut: Dut) -> None: dut.expect_exact('Press ENTER to see the list of tests.') - dut.write('\"Notify Wait too high index fails\"') + dut.write('"Notify Wait too high index fails"') dut.expect('assert failed: xTaskGenericNotifyWait', timeout=5) dut.expect('uxIndexToWait < [0-9]+', timeout=5) dut.expect_exact('Rebooting...') -@pytest.mark.supported_targets @pytest.mark.generic @pytest.mark.parametrize('config', ['default'], indirect=True) +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_port_must_assert_in_isr(dut: Dut) -> None: dut.expect_exact('Press ENTER to see the list of tests.') - dut.write('\"port must assert if in ISR context\"') + dut.write('"port must assert if in ISR context"') dut.expect('assert failed: vPortAssertIfInISR', timeout=5) dut.expect_exact('Rebooting...') diff --git a/components/hal/test_apps/crypto/pytest_crypto.py b/components/hal/test_apps/crypto/pytest_crypto.py index 64fe21473b..0b8f3dab83 100644 --- a/components/hal/test_apps/crypto/pytest_crypto.py +++ b/components/hal/test_apps/crypto/pytest_crypto.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import binascii import os @@ -16,6 +16,7 @@ from cryptography.hazmat.primitives.serialization import load_pem_private_key from ecdsa import NIST256p from ecdsa.ellipticcurve import Point from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize def load_ecdsa_key(filename: str) -> SECP256R1: @@ -34,10 +35,13 @@ def test_xts_aes_encryption(negotiated_key: bytes, plaintext_data: bytes, encryp 'espsecure.py', 'encrypt_flash_data', '--aes_xts', - '--keyfile', 'test/negotiated_key.bin', - '--address', '0x120000', - '--output', 'test/enc-data.bin', - 'test/plaintext.bin' + '--keyfile', + 'test/negotiated_key.bin', + '--address', + '0x120000', + '--output', + 'test/enc-data.bin', + 'test/plaintext.bin', ] result = subprocess.run(command, capture_output=True, text=True) assert result.returncode == 0, f'Command failed with error: {result.stderr}' @@ -79,7 +83,9 @@ def calculate_key_manager_ecdh0_negotiated_key(k2_G_hex: str, k1_ecdsa_key: str) return negotiated_key -def test_ecdsa_key(negotiated_key: bytes, digest: bytes, signature_r_le: bytes, signature_s_le: bytes, pubx: bytes, puby: bytes) -> None: +def test_ecdsa_key( + negotiated_key: bytes, digest: bytes, signature_r_le: bytes, signature_s_le: bytes, pubx: bytes, puby: bytes +) -> None: r = int.from_bytes(signature_r_le, 'little') s = int.from_bytes(signature_s_le, 'little') signature = utils.encode_dss_signature(r, s) @@ -103,8 +109,8 @@ def test_ecdsa_key(negotiated_key: bytes, digest: bytes, signature_r_le: bytes, raise -@pytest.mark.supported_targets @pytest.mark.generic +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_crypto(dut: Dut) -> None: # if the env variable IDF_FPGA_ENV is set, we would need a longer timeout # as tests for efuses burning security peripherals would be run @@ -157,9 +163,9 @@ def test_crypto(dut: Dut) -> None: dut.expect('Tests finished', timeout=timeout) -@pytest.mark.supported_targets @pytest.mark.generic @pytest.mark.parametrize('config', ['long_aes_operations'], indirect=True) +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_crypto_long_aes_operations(dut: Dut) -> None: # if the env variable IDF_FPGA_ENV is set, we would need a longer timeout # as tests for efuses burning security peripherals would be run diff --git a/components/hal/test_apps/hal_utils/pytest_hal_utils.py b/components/hal/test_apps/hal_utils/pytest_hal_utils.py index c8e422e42c..16d1a2b39f 100644 --- a/components/hal/test_apps/hal_utils/pytest_hal_utils.py +++ b/components/hal/test_apps/hal_utils/pytest_hal_utils.py @@ -1,10 +1,11 @@ -# SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-2025 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_hal_utils(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/heap/test_apps/heap_tests/pytest_heap.py b/components/heap/test_apps/heap_tests/pytest_heap.py index e36de539b1..eaa23700be 100644 --- a/components/heap/test_apps/heap_tests/pytest_heap.py +++ b/components/heap/test_apps/heap_tests/pytest_heap.py @@ -1,11 +1,11 @@ -# 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 pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize @pytest.mark.generic -@pytest.mark.supported_targets @pytest.mark.nightly_run @pytest.mark.parametrize( 'config', @@ -13,24 +13,20 @@ from pytest_embedded import Dut 'no_poisoning', 'light_poisoning', 'comprehensive_poisoning', - ] + ], ) +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_heap_poisoning(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32 -@pytest.mark.esp32c3 @pytest.mark.host_test @pytest.mark.qemu @pytest.mark.parametrize( 'config, embedded_services', - [ - ('no_poisoning', 'idf,qemu'), - ('light_poisoning', 'idf,qemu'), - ('comprehensive_poisoning', 'idf,qemu') - ] + [('no_poisoning', 'idf,qemu'), ('light_poisoning', 'idf,qemu'), ('comprehensive_poisoning', 'idf,qemu')], ) +@idf_parametrize('target', ['esp32', 'esp32c3'], indirect=['target']) def test_heap_poisoning_qemu(dut: Dut) -> None: for case in dut.test_menu: if 'qemu-ignore' not in case.groups and not case.is_ignored and case.type == 'normal': @@ -38,13 +34,8 @@ def test_heap_poisoning_qemu(dut: Dut) -> None: @pytest.mark.generic -@pytest.mark.supported_targets -@pytest.mark.parametrize( - 'config', - [ - 'in_flash' - ] -) +@pytest.mark.parametrize('config', ['in_flash']) +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_heap_in_flash(dut: Dut) -> None: dut.run_all_single_board_cases() @@ -56,15 +47,9 @@ def test_heap_in_flash(dut: Dut) -> None: 'esp32', 'esp32s2', 'esp32s3', - ] -) -@pytest.mark.parametrize( - 'config', - [ - 'psram', - 'psram_all_ext' - ] + ], ) +@pytest.mark.parametrize('config', ['psram', 'psram_all_ext']) def test_heap(dut: Dut) -> None: dut.run_all_single_board_cases(group='psram') @@ -74,19 +59,11 @@ def test_heap(dut: Dut) -> None: 'target', [ 'esp32', - ] -) -@pytest.mark.parametrize( - 'config', - [ - 'misc_options' - ] + ], ) +@pytest.mark.parametrize('config', ['misc_options']) def test_heap_misc_options(dut: Dut) -> None: - dut.run_all_single_board_cases(name=[ - 'IRAM_8BIT capability test', - 'test allocation and free function hooks' - ]) + dut.run_all_single_board_cases(name=['IRAM_8BIT capability test', 'test allocation and free function hooks']) dut.expect_exact("Enter next test, or 'enter' to see menu") dut.write('"When enabled, allocation operation failure generates an abort"') @@ -94,14 +71,15 @@ def test_heap_misc_options(dut: Dut) -> None: @pytest.mark.generic -@pytest.mark.parametrize( - 'config', +@idf_parametrize( + 'config,target', [ - pytest.param('heap_trace_esp32', marks=[pytest.mark.esp32]), - pytest.param('heap_trace_hashmap_esp32', marks=[pytest.mark.esp32]), - pytest.param('heap_trace_esp32c3', marks=[pytest.mark.esp32c3]), - pytest.param('heap_trace_hashmap_esp32c3', marks=[pytest.mark.esp32c3]) - ] + ('heap_trace_esp32', 'esp32'), + ('heap_trace_hashmap_esp32', 'esp32'), + ('heap_trace_esp32c3', 'esp32c3'), + ('heap_trace_hashmap_esp32c3', 'esp32c3'), + ], + indirect=['config', 'target'], ) def test_heap_trace_dump(dut: Dut) -> None: dut.run_all_single_board_cases(group='trace-dump&internal') @@ -111,13 +89,8 @@ def test_heap_trace_dump(dut: Dut) -> None: @pytest.mark.generic -@pytest.mark.supported_targets @pytest.mark.temp_skip_ci(targets=['esp32c61'], reason='support TBD') # TODO [ESP32C61] IDF-9858 IDF-10989 -@pytest.mark.parametrize( - 'config', - [ - 'mem_prot' - ] -) +@pytest.mark.parametrize('config', ['mem_prot']) +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_memory_protection(dut: Dut) -> None: dut.run_all_single_board_cases(group='heap&mem_prot', timeout=300) diff --git a/components/heap/test_apps/host_test_linux/pytest_heap_linux.py b/components/heap/test_apps/host_test_linux/pytest_heap_linux.py index 41e79ac944..582cbf2f56 100644 --- a/components/heap/test_apps/host_test_linux/pytest_heap_linux.py +++ b/components/heap/test_apps/host_test_linux/pytest_heap_linux.py @@ -1,10 +1,11 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-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.linux @pytest.mark.host_test +@idf_parametrize('target', ['linux'], indirect=['target']) def test_heap_linux(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=60) diff --git a/components/linux/test_apps/linux_test/pytest_linux_test.py b/components/linux/test_apps/linux_test/pytest_linux_test.py index f0e77455b1..15cf390d9d 100644 --- a/components/linux/test_apps/linux_test/pytest_linux_test.py +++ b/components/linux/test_apps/linux_test/pytest_linux_test.py @@ -1,11 +1,12 @@ -# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2024-2025 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.linux @pytest.mark.host_test +@idf_parametrize('target', ['linux'], indirect=['target']) def test_linux_component(dut: IdfDut) -> None: dut.expect_exact('Press ENTER to see the list of tests.') dut.write('![ignore]') diff --git a/components/log/host_test/log_test/pytest_log_linux.py b/components/log/host_test/log_test/pytest_log_linux.py index c60206131c..ffd06d72fb 100644 --- a/components/log/host_test/log_test/pytest_log_linux.py +++ b/components/log/host_test/log_test/pytest_log_linux.py @@ -1,24 +1,29 @@ -# SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-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.linux @pytest.mark.host_test -@pytest.mark.parametrize('config', [ - 'default', - 'v1_color', - 'v2_color', - 'v2_no_color_no_support', - 'v2_no_timestamp', - 'v2_no_timestamp_no_support', - 'v2_rtos_timestamp', - 'v2_system_full_timestamp', - 'v2_system_timestamp', - 'tag_level_linked_list', - 'tag_level_linked_list_and_array_cache', - 'tag_level_none', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'default', + 'v1_color', + 'v2_color', + 'v2_no_color_no_support', + 'v2_no_timestamp', + 'v2_no_timestamp_no_support', + 'v2_rtos_timestamp', + 'v2_system_full_timestamp', + 'v2_system_timestamp', + 'tag_level_linked_list', + 'tag_level_linked_list_and_array_cache', + 'tag_level_none', + ], + indirect=True, +) +@idf_parametrize('target', ['linux'], indirect=['target']) def test_log_linux(dut: Dut) -> None: dut.expect_exact('All tests passed', timeout=5) diff --git a/components/log/test_apps/pytest_esp_log.py b/components/log/test_apps/pytest_esp_log.py index 33414b08ae..faa55a0030 100644 --- a/components/log/test_apps/pytest_esp_log.py +++ b/components/log/test_apps/pytest_esp_log.py @@ -1,11 +1,11 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-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.generic +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_esp_log(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/lwip/test_apps/pytest_lwip.py b/components/lwip/test_apps/pytest_lwip.py index 02b4bc2ee8..962dbd794b 100644 --- a/components/lwip/test_apps/pytest_lwip.py +++ b/components/lwip/test_apps/pytest_lwip.py @@ -1,10 +1,11 @@ -# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 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.esp32 @pytest.mark.generic +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_lwip(dut: Dut) -> None: dut.expect_unity_test_output() diff --git a/components/mbedtls/test_apps/pytest_mbedtls_ut.py b/components/mbedtls/test_apps/pytest_mbedtls_ut.py index 3614c8dcaa..3f640a94e8 100644 --- a/components/mbedtls/test_apps/pytest_mbedtls_ut.py +++ b/components/mbedtls/test_apps/pytest_mbedtls_ut.py @@ -1,16 +1,16 @@ -# 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 pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.supported_targets @pytest.mark.generic +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_mbedtls(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -19,15 +19,11 @@ def test_mbedtls(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_mbedtls_esp32_compiler_perf_opt(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32c3 -@pytest.mark.esp32c5 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -36,15 +32,11 @@ def test_mbedtls_esp32_compiler_perf_opt(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32', 'esp32s2', 'esp32s3', 'esp32c3', 'esp32c5'], indirect=['target']) def test_mbedtls_aes_no_hw(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32c5 -@pytest.mark.esp32c61 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -54,32 +46,35 @@ def test_mbedtls_aes_no_hw(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32', 'esp32s2', 'esp32s3', 'esp32c5', 'esp32c61'], indirect=['target']) def test_mbedtls_psram(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32p4 @pytest.mark.generic @pytest.mark.parametrize( 'config', - [ - 'psram_esp32p4_200m', - 'psram_all_ext_esp32p4_200m' - ], + ['psram_esp32p4_200m', 'psram_all_ext_esp32p4_200m'], indirect=True, ) +@idf_parametrize('target', ['esp32p4'], indirect=['target']) def test_mbedtls_psram_esp32p4(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32h2 @pytest.mark.ecdsa_efuse -@pytest.mark.parametrize('config', ['ecdsa_sign',], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'ecdsa_sign', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32h2'], indirect=['target']) def test_mbedtls_ecdsa_sign(dut: Dut) -> None: dut.run_all_single_board_cases(group='efuse_key') -@pytest.mark.esp32c2 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -88,5 +83,6 @@ def test_mbedtls_ecdsa_sign(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32c2'], indirect=['target']) def test_mbedtls_rom_impl_esp32c2(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/mqtt/test_apps/test_mqtt/pytest_mqtt_ut.py b/components/mqtt/test_apps/test_mqtt/pytest_mqtt_ut.py index 300d53ec45..429b857470 100644 --- a/components/mqtt/test_apps/test_mqtt/pytest_mqtt_ut.py +++ b/components/mqtt/test_apps/test_mqtt/pytest_mqtt_ut.py @@ -1,10 +1,11 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-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.ethernet +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_mqtt_client(dut: Dut) -> None: dut.expect_unity_test_output() diff --git a/components/mqtt/test_apps/test_mqtt5/pytest_mqtt5_ut.py b/components/mqtt/test_apps/test_mqtt5/pytest_mqtt5_ut.py index df15c392b8..7e38dfac8d 100644 --- a/components/mqtt/test_apps/test_mqtt5/pytest_mqtt5_ut.py +++ b/components/mqtt/test_apps/test_mqtt5/pytest_mqtt5_ut.py @@ -1,10 +1,11 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-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.ethernet +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_mqtt5_client(dut: Dut) -> None: dut.expect_unity_test_output() diff --git a/components/newlib/test_apps/newlib/pytest_newlib.py b/components/newlib/test_apps/newlib/pytest_newlib.py index 6b66d16736..36c142a74d 100644 --- a/components/newlib/test_apps/newlib/pytest_newlib.py +++ b/components/newlib/test_apps/newlib/pytest_newlib.py @@ -1,22 +1,23 @@ -# 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 pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize @pytest.mark.generic -@pytest.mark.parametrize( - 'config', +@idf_parametrize( + 'config,target', [ - pytest.param('default', marks=[pytest.mark.supported_targets]), - pytest.param('picolibc', marks=[pytest.mark.supported_targets]), - pytest.param('options', marks=[pytest.mark.supported_targets]), - pytest.param('single_core_esp32', marks=[pytest.mark.esp32]), - pytest.param('psram_esp32', marks=[pytest.mark.esp32]), - pytest.param('release_esp32', marks=[pytest.mark.esp32]), - pytest.param('release_esp32c2', marks=[pytest.mark.esp32c2]), + ('default', 'supported_targets'), + ('picolibc', 'supported_targets'), + ('options', 'supported_targets'), + ('single_core_esp32', 'esp32'), + ('psram_esp32', 'esp32'), + ('release_esp32', 'esp32'), + ('release_esp32c2', 'esp32c2'), ], - indirect=True + indirect=['config', 'target'], ) def test_newlib(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/nvs_flash/host_test/nvs_host_test/pytest_nvs_host_linux.py b/components/nvs_flash/host_test/nvs_host_test/pytest_nvs_host_linux.py index bc3828ada2..37b8275a7e 100644 --- a/components/nvs_flash/host_test/nvs_host_test/pytest_nvs_host_linux.py +++ b/components/nvs_flash/host_test/nvs_host_test/pytest_nvs_host_linux.py @@ -1,10 +1,11 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-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.linux @pytest.mark.host_test +@idf_parametrize('target', ['linux'], indirect=['target']) def test_nvs_host_linux(dut: Dut) -> None: dut.expect_exact('All tests passed', timeout=60) diff --git a/components/nvs_flash/host_test/nvs_page_test/pytest_nvs_page_linux.py b/components/nvs_flash/host_test/nvs_page_test/pytest_nvs_page_linux.py index dc8b09d2a5..0e30e463bf 100644 --- a/components/nvs_flash/host_test/nvs_page_test/pytest_nvs_page_linux.py +++ b/components/nvs_flash/host_test/nvs_page_test/pytest_nvs_page_linux.py @@ -1,10 +1,11 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-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.linux @pytest.mark.host_test +@idf_parametrize('target', ['linux'], indirect=['target']) def test_nvs_page_linux(dut: Dut) -> None: dut.expect_unity_test_output(timeout=120) diff --git a/components/nvs_flash/test_apps/pytest_nvs_flash.py b/components/nvs_flash/test_apps/pytest_nvs_flash.py index 3d6171de17..35af7f4d22 100644 --- a/components/nvs_flash/test_apps/pytest_nvs_flash.py +++ b/components/nvs_flash/test_apps/pytest_nvs_flash.py @@ -1,45 +1,49 @@ -# SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Apache-2.0 import pytest from pytest_embedded_idf.dut import IdfDut +from pytest_embedded_idf.utils import idf_parametrize CONFIGS_NVS_ENCR_FLASH_ENC = [ - pytest.param('nvs_encr_flash_enc_esp32', marks=[pytest.mark.esp32]), + pytest.param('nvs_encr_flash_enc_esp32', marks=[pytest.mark.esp32]), pytest.param('nvs_encr_flash_enc_esp32c3', marks=[pytest.mark.esp32c3]), ] -@pytest.mark.esp32 -@pytest.mark.esp32c3 @pytest.mark.generic @pytest.mark.parametrize('config', ['default'], indirect=True) +@idf_parametrize('target', ['esp32', 'esp32c3'], indirect=['target']) def test_nvs_flash(dut: IdfDut) -> None: dut.run_all_single_board_cases(group='!nvs_encr_hmac', timeout=120) -@pytest.mark.esp32c3 @pytest.mark.nvs_encr_hmac @pytest.mark.parametrize('config', ['nvs_encr_hmac_esp32c3'], indirect=True) +@idf_parametrize('target', ['esp32c3'], indirect=['target']) def test_nvs_flash_encr_hmac(dut: IdfDut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32c3 @pytest.mark.nvs_encr_hmac @pytest.mark.parametrize('config', ['nvs_encr_hmac_no_cfg_esp32c3'], indirect=True) +@idf_parametrize('target', ['esp32c3'], indirect=['target']) def test_nvs_flash_encr_hmac_no_cfg(dut: IdfDut) -> None: dut.run_all_single_board_cases(group='nvs_encr_hmac', timeout=120) @pytest.mark.flash_encryption -@pytest.mark.parametrize('config', CONFIGS_NVS_ENCR_FLASH_ENC, indirect=True) +@idf_parametrize( + 'config,target', + [('nvs_encr_flash_enc_esp32', 'esp32'), ('nvs_encr_flash_enc_esp32c3', 'esp32c3')], + indirect=['config', 'target'], +) def test_nvs_flash_encr_flash_enc(dut: IdfDut) -> None: # Erase the nvs_key partition dut.serial.erase_partition('nvs_key') dut.run_all_single_board_cases() -@pytest.mark.esp32 @pytest.mark.psram +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_nvs_flash_ram(dut: IdfDut) -> None: dut.run_all_single_board_cases(group='nvs_ram') diff --git a/components/nvs_flash/test_apps_bootloader/pytest_nvs_bootloader_support.py b/components/nvs_flash/test_apps_bootloader/pytest_nvs_bootloader_support.py index b44656e19d..6ff278636f 100644 --- a/components/nvs_flash/test_apps_bootloader/pytest_nvs_bootloader_support.py +++ b/components/nvs_flash/test_apps_bootloader/pytest_nvs_bootloader_support.py @@ -2,35 +2,34 @@ # SPDX-License-Identifier: Apache-2.0 import pytest from pytest_embedded_idf.dut import IdfDut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32 -@pytest.mark.esp32c3 @pytest.mark.generic @pytest.mark.parametrize('config', ['default'], indirect=True) +@idf_parametrize('target', ['esp32', 'esp32c3'], indirect=['target']) def test_nvs_bootloader_support(dut: IdfDut) -> None: dut.run_all_single_board_cases(group='!nvs_encrypted_bootloader', timeout=120) -@pytest.mark.esp32c3 @pytest.mark.nvs_encr_hmac @pytest.mark.parametrize('config', ['nvs_enc_hmac'], indirect=True) +@idf_parametrize('target', ['esp32c3'], indirect=['target']) def test_nvs_bootloader_support_encr_hmac(dut: IdfDut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32 -@pytest.mark.esp32c3 @pytest.mark.flash_encryption @pytest.mark.parametrize('config', ['nvs_enc_flash_enc'], indirect=True) +@idf_parametrize('target', ['esp32', 'esp32c3'], indirect=['target']) def test_nvs_bootloader_support_encr_flash_enc(dut: IdfDut) -> None: # Erase the nvs_key partition dut.serial.erase_partition('nvs_key') dut.run_all_single_board_cases() -@pytest.mark.esp32c3 @pytest.mark.nvs_encr_hmac @pytest.mark.parametrize('config', ['nvs_enc_hmac_no_cfg'], indirect=True) +@idf_parametrize('target', ['esp32c3'], indirect=['target']) def test_nvs_bootloader_support_encr_hmac_no_cfg(dut: IdfDut) -> None: dut.run_all_single_board_cases() diff --git a/components/perfmon/test_apps/pytest_perfmon_ut.py b/components/perfmon/test_apps/pytest_perfmon_ut.py index 32adeee597..2a810f2a87 100644 --- a/components/perfmon/test_apps/pytest_perfmon_ut.py +++ b/components/perfmon/test_apps/pytest_perfmon_ut.py @@ -1,13 +1,11 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 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.esp32 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 +@idf_parametrize('target', ['esp32', 'esp32s2', 'esp32s3'], indirect=['target']) def test_perfmon_ut(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/protocomm/test_apps/pytest_protocomm_ut.py b/components/protocomm/test_apps/pytest_protocomm_ut.py index 1235f234c6..7d741121b3 100644 --- a/components/protocomm/test_apps/pytest_protocomm_ut.py +++ b/components/protocomm/test_apps/pytest_protocomm_ut.py @@ -1,11 +1,11 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 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.supported_targets @pytest.mark.generic +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_protocomm(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/pthread/test_apps/pthread_psram_tests/pytest_pthread_psram_tests.py b/components/pthread/test_apps/pthread_psram_tests/pytest_pthread_psram_tests.py index 9da7f7cba3..43ab9c38e7 100644 --- a/components/pthread/test_apps/pthread_psram_tests/pytest_pthread_psram_tests.py +++ b/components/pthread/test_apps/pthread_psram_tests/pytest_pthread_psram_tests.py @@ -1,11 +1,12 @@ -# SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-2025 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.generic @pytest.mark.psram +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_pthread_psram(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=10) diff --git a/components/pthread/test_apps/pthread_unity_tests/pytest_pthread_unity_tests.py b/components/pthread/test_apps/pthread_unity_tests/pytest_pthread_unity_tests.py index a9472aa73d..5e6aba09c9 100644 --- a/components/pthread/test_apps/pthread_unity_tests/pytest_pthread_unity_tests.py +++ b/components/pthread/test_apps/pthread_unity_tests/pytest_pthread_unity_tests.py @@ -1,11 +1,11 @@ -# 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 pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize @pytest.mark.generic -@pytest.mark.supported_targets @pytest.mark.parametrize( 'config', [ @@ -13,25 +13,20 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_pthread(dut: Dut) -> None: dut.run_all_single_board_cases(group='!thread-specific', timeout=300) @pytest.mark.generic -@pytest.mark.parametrize( - 'config', - [ - pytest.param('single_core_esp32', marks=[pytest.mark.esp32]), - pytest.param('single_core_esp32s3', marks=[pytest.mark.esp32s3]), - ], - indirect=True, +@idf_parametrize( + 'config,target', [('single_core_esp32', 'esp32'), ('single_core_esp32s3', 'esp32s3')], indirect=['config', 'target'] ) def test_pthread_single_core(dut: Dut) -> None: dut.run_all_single_board_cases(group='!thread-specific', timeout=300) @pytest.mark.generic -@pytest.mark.supported_targets @pytest.mark.parametrize( 'config', [ @@ -39,32 +34,28 @@ def test_pthread_single_core(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_pthread_tls(dut: Dut) -> None: dut.run_all_single_board_cases(group='thread-specific', timeout=300) @pytest.mark.generic -@pytest.mark.parametrize( - 'config', - [ - pytest.param('single_core_esp32_tls', marks=[pytest.mark.esp32]), - ], - indirect=True, -) +@idf_parametrize('config', ['single_core_esp32_tls'], indirect=['config']) +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_pthread_single_core_tls(dut: Dut) -> None: dut.run_all_single_board_cases(group='thread-specific', timeout=300) @pytest.mark.host_test @pytest.mark.qemu -@pytest.mark.esp32 +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_pthread_qemu(dut: Dut) -> None: for case in dut.test_menu: if 'qemu-ignore' not in case.groups and case.type == 'normal': dut._run_normal_case(case, timeout=75) -@pytest.mark.linux @pytest.mark.host_test +@idf_parametrize('target', ['linux'], indirect=['target']) def test_pthread_linux(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=120) diff --git a/components/rt/test_apps/posix_rt_test/pytest_rt_mqueue_tests.py b/components/rt/test_apps/posix_rt_test/pytest_rt_mqueue_tests.py index f43f8abc22..a4729a7292 100644 --- a/components/rt/test_apps/posix_rt_test/pytest_rt_mqueue_tests.py +++ b/components/rt/test_apps/posix_rt_test/pytest_rt_mqueue_tests.py @@ -1,13 +1,11 @@ -# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2024-2025 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.esp32 -@pytest.mark.esp32c3 -@pytest.mark.esp32p4 -@pytest.mark.esp32s2 +@idf_parametrize('target', ['esp32', 'esp32c3', 'esp32p4', 'esp32s2'], indirect=['target']) def test_rt_mqueue(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/spi_flash/test_apps/esp_flash/pytest_esp_flash.py b/components/spi_flash/test_apps/esp_flash/pytest_esp_flash.py index cc2c4edac3..423e01c440 100644 --- a/components/spi_flash/test_apps/esp_flash/pytest_esp_flash.py +++ b/components/spi_flash/test_apps/esp_flash/pytest_esp_flash.py @@ -2,9 +2,9 @@ # SPDX-License-Identifier: Apache-2.0 import pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.supported_targets @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -16,17 +16,11 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_esp_flash(dut: Dut) -> None: dut.run_all_single_board_cases(group='esp_flash') -@pytest.mark.esp32s3 -@pytest.mark.esp32c3 -@pytest.mark.esp32c2 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32c5 -@pytest.mark.esp32c61 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -35,15 +29,13 @@ def test_esp_flash(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize( + 'target', ['esp32s3', 'esp32c3', 'esp32c2', 'esp32c6', 'esp32h2', 'esp32c5', 'esp32c61'], indirect=['target'] +) def test_esp_flash_rom(dut: Dut) -> None: dut.run_all_single_board_cases(group='esp_flash') -@pytest.mark.esp32 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32c3 -@pytest.mark.esp32c2 @pytest.mark.flash_multi @pytest.mark.parametrize( 'config', @@ -52,11 +44,11 @@ def test_esp_flash_rom(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32', 'esp32s2', 'esp32s3', 'esp32c3', 'esp32c2'], indirect=['target']) def test_esp_flash_multi(dut: Dut) -> None: dut.run_all_single_board_cases(group='esp_flash_multi', timeout=120) -@pytest.mark.esp32c2 @pytest.mark.generic @pytest.mark.xtal_26mhz @pytest.mark.parametrize( @@ -67,5 +59,6 @@ def test_esp_flash_multi(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32c2'], indirect=['target']) def test_esp_flash_26mhz_c2(dut: Dut) -> None: dut.run_all_single_board_cases(group='esp_flash') diff --git a/components/spi_flash/test_apps/esp_flash_stress/pytest_esp_flash_stress.py b/components/spi_flash/test_apps/esp_flash_stress/pytest_esp_flash_stress.py index 686f4de695..d34314230c 100644 --- a/components/spi_flash/test_apps/esp_flash_stress/pytest_esp_flash_stress.py +++ b/components/spi_flash/test_apps/esp_flash_stress/pytest_esp_flash_stress.py @@ -1,10 +1,10 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 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.supported_targets @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -13,11 +13,11 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_esp_flash_stress(dut: Dut) -> None: dut.run_all_single_board_cases(group='esp_flash') -@pytest.mark.esp32s3 @pytest.mark.MSPI_F8R8 @pytest.mark.parametrize( 'config', @@ -26,11 +26,11 @@ def test_esp_flash_stress(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32s3'], indirect=['target']) def test_esp_flash_stress_f8r8(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32s3 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -39,11 +39,11 @@ def test_esp_flash_stress_f8r8(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32s3'], indirect=['target']) def test_esp_flash_stress_rom_xip_psram(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32c3 @pytest.mark.flash_suspend @pytest.mark.parametrize( 'config', @@ -52,5 +52,6 @@ def test_esp_flash_stress_rom_xip_psram(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32c3'], indirect=['target']) def test_flash_auto_suspend_stress(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/spi_flash/test_apps/flash_encryption/pytest_flash_encrypted.py b/components/spi_flash/test_apps/flash_encryption/pytest_flash_encrypted.py index 58112e1432..c85f9ffd6c 100644 --- a/components/spi_flash/test_apps/flash_encryption/pytest_flash_encrypted.py +++ b/components/spi_flash/test_apps/flash_encryption/pytest_flash_encrypted.py @@ -1,11 +1,10 @@ -# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 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.esp32 -@pytest.mark.esp32c3 @pytest.mark.flash_encryption @pytest.mark.parametrize( 'config', @@ -15,11 +14,11 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize('target', ['esp32', 'esp32c3'], indirect=['target']) def test_flash_encryption(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32c3 @pytest.mark.flash_encryption @pytest.mark.parametrize( 'config', @@ -28,11 +27,11 @@ def test_flash_encryption(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32c3'], indirect=['target']) def test_flash_encryption_rom_impl(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32s3 @pytest.mark.flash_encryption_f4r8 @pytest.mark.parametrize( 'config', @@ -43,11 +42,11 @@ def test_flash_encryption_rom_impl(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32s3'], indirect=['target']) def test_flash_encryption_f4r8(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32s3 @pytest.mark.flash_encryption_f8r8 @pytest.mark.parametrize( 'config', @@ -56,5 +55,6 @@ def test_flash_encryption_f4r8(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32s3'], indirect=['target']) def test_flash_encryption_f8r8(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/spi_flash/test_apps/flash_mmap/pytest_flash_mmap.py b/components/spi_flash/test_apps/flash_mmap/pytest_flash_mmap.py index 0e5a8078b0..68c4f23038 100644 --- a/components/spi_flash/test_apps/flash_mmap/pytest_flash_mmap.py +++ b/components/spi_flash/test_apps/flash_mmap/pytest_flash_mmap.py @@ -2,9 +2,9 @@ # SPDX-License-Identifier: Apache-2.0 import pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.supported_targets @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -13,15 +13,11 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_flash_mmap(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=30) -@pytest.mark.esp32s3 -@pytest.mark.esp32c3 -@pytest.mark.esp32c2 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -30,11 +26,11 @@ def test_flash_mmap(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32s3', 'esp32c3', 'esp32c2', 'esp32c6', 'esp32h2'], indirect=['target']) def test_flash_mmap_rom_impl(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=30) -@pytest.mark.supported_targets @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -43,11 +39,11 @@ def test_flash_mmap_rom_impl(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_flash_mmap_xip_psram(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=30) -@pytest.mark.supported_targets @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -56,11 +52,11 @@ def test_flash_mmap_xip_psram(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_flash_mmap_psram(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=30) -@pytest.mark.supported_targets @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -69,5 +65,6 @@ def test_flash_mmap_psram(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_flash_mmap_xip_psram_rom_impl(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=30) diff --git a/components/spi_flash/test_apps/flash_suspend/pytest_flash_auto_suspend.py b/components/spi_flash/test_apps/flash_suspend/pytest_flash_auto_suspend.py index 281403f885..09d1bda04d 100644 --- a/components/spi_flash/test_apps/flash_suspend/pytest_flash_auto_suspend.py +++ b/components/spi_flash/test_apps/flash_suspend/pytest_flash_auto_suspend.py @@ -1,10 +1,10 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-2025 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.esp32c3 @pytest.mark.flash_suspend @pytest.mark.parametrize( 'config', @@ -15,5 +15,6 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize('target', ['esp32c3'], indirect=['target']) def test_flash_auto_suspend(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=30) diff --git a/components/spi_flash/test_apps/mspi_test/pytest_mspi_test.py b/components/spi_flash/test_apps/mspi_test/pytest_mspi_test.py index ecf7413eb0..020dfbf34d 100644 --- a/components/spi_flash/test_apps/mspi_test/pytest_mspi_test.py +++ b/components/spi_flash/test_apps/mspi_test/pytest_mspi_test.py @@ -1,10 +1,10 @@ -# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 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.supported_targets @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -14,12 +14,11 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_mspi_bus(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -28,13 +27,11 @@ def test_mspi_bus(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32s2', 'esp32s3'], indirect=['target']) def test_mspi_bus_xip_psram(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -43,5 +40,6 @@ def test_mspi_bus_xip_psram(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32', 'esp32s2', 'esp32s3'], indirect=['target']) def test_mspi_bus_psram(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/spiffs/host_test/pytest_spiffs_linux.py b/components/spiffs/host_test/pytest_spiffs_linux.py index 18dbd3f2cd..2d1ddfe6f7 100644 --- a/components/spiffs/host_test/pytest_spiffs_linux.py +++ b/components/spiffs/host_test/pytest_spiffs_linux.py @@ -1,11 +1,12 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-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.linux @pytest.mark.host_test @pytest.mark.parametrize('config', ['erase_check', 'no_erase_check']) +@idf_parametrize('target', ['linux'], indirect=['target']) def test_spiffs_linux(dut: Dut) -> None: dut.expect_unity_test_output(timeout=5) diff --git a/components/spiffs/test_apps/pytest_spiffs.py b/components/spiffs/test_apps/pytest_spiffs.py index ef4a26fe16..318e0d9f83 100644 --- a/components/spiffs/test_apps/pytest_spiffs.py +++ b/components/spiffs/test_apps/pytest_spiffs.py @@ -1,24 +1,32 @@ -# 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 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', - 'release', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'default', + 'release', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32', 'esp32c3'], indirect=['target']) def test_spiffs_generic(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=120) -@pytest.mark.esp32s3 @pytest.mark.quad_psram -@pytest.mark.parametrize('config', [ - 'psram', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'psram', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32s3'], indirect=['target']) def test_spiffs_psram(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=120) diff --git a/components/tcp_transport/test_apps/pytest_tcp_transport_ut.py b/components/tcp_transport/test_apps/pytest_tcp_transport_ut.py index e61f61788b..04f50051eb 100644 --- a/components/tcp_transport/test_apps/pytest_tcp_transport_ut.py +++ b/components/tcp_transport/test_apps/pytest_tcp_transport_ut.py @@ -1,7 +1,8 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 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 CONFIGS = [ pytest.param('default', marks=[pytest.mark.esp32, pytest.mark.esp32c3]), @@ -10,6 +11,10 @@ CONFIGS = [ @pytest.mark.generic -@pytest.mark.parametrize('config', CONFIGS, indirect=True) +@idf_parametrize( + 'config,target', + [('default', 'esp32'), ('default', 'esp32c3'), ('psram_esp32', 'esp32')], + indirect=['config', 'target'], +) def test_tcp_transport_client(dut: Dut) -> None: dut.expect_unity_test_output() diff --git a/components/touch_element/test_apps/pytest_touch_element.py b/components/touch_element/test_apps/pytest_touch_element.py index 75b07625be..b2db9c40df 100644 --- a/components/touch_element/test_apps/pytest_touch_element.py +++ b/components/touch_element/test_apps/pytest_touch_element.py @@ -1,19 +1,16 @@ -# 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 pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 @pytest.mark.generic @pytest.mark.parametrize( 'config', - [ - 'opt_o0', - 'opt_o2' - ], + ['opt_o0', 'opt_o2'], indirect=True, ) +@idf_parametrize('target', ['esp32s2', 'esp32s3'], indirect=['target']) def test_touch_element(dut: Dut) -> None: dut.run_all_single_board_cases(timeout=120) diff --git a/components/ulp/test_apps/lp_core/lp_core_basic_tests/pytest_lp_core_basic.py b/components/ulp/test_apps/lp_core/lp_core_basic_tests/pytest_lp_core_basic.py index 4d0c7f570e..653341e7e1 100644 --- a/components/ulp/test_apps/lp_core/lp_core_basic_tests/pytest_lp_core_basic.py +++ b/components/ulp/test_apps/lp_core/lp_core_basic_tests/pytest_lp_core_basic.py @@ -3,11 +3,9 @@ import pytest from pytest_embedded import Dut from pytest_embedded_idf import CaseTester +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32p4 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -16,12 +14,11 @@ from pytest_embedded_idf import CaseTester ], indirect=True, ) +@idf_parametrize('target', ['esp32c5', 'esp32c6', 'esp32p4'], indirect=['target']) def test_lp_core(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32c5 -@pytest.mark.esp32p4 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -30,11 +27,11 @@ def test_lp_core(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32c5', 'esp32p4'], indirect=['target']) def test_lp_core_xtal(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32p4 @pytest.mark.lp_i2s @pytest.mark.parametrize( 'config', @@ -43,16 +40,14 @@ def test_lp_core_xtal(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32p4'], indirect=['target']) def test_lp_vad(dut: Dut) -> None: dut.run_all_single_board_cases(group='lp_vad') -@pytest.mark.esp32c6 # TODO: Enable LP I2C test for esp32p4 (IDF-9407) @pytest.mark.generic_multi_device -@pytest.mark.parametrize( - 'count', [2], indirect=True -) +@pytest.mark.parametrize('count', [2], indirect=True) @pytest.mark.parametrize( 'config', [ @@ -60,18 +55,23 @@ def test_lp_vad(dut: Dut) -> None: ], indirect=True, ) -def test_lp_core_multi_device(case_tester) -> None: # type: ignore +@idf_parametrize('target', ['esp32c6'], indirect=['target']) +def test_lp_core_multi_device(case_tester) -> None: # type: ignore for case in case_tester.test_menu: if case.attributes.get('test_env', 'generic_multi_device') == 'generic_multi_device': case_tester.run_multi_dev_case(case=case, reset=True) @pytest.mark.generic_multi_device -@pytest.mark.parametrize('target', [ - 'esp32c5', - 'esp32c6', - 'esp32p4', -], indirect=True) +@pytest.mark.parametrize( + 'target', + [ + 'esp32c5', + 'esp32c6', + 'esp32p4', + ], + indirect=True, +) @pytest.mark.parametrize( 'config', [ @@ -81,10 +81,7 @@ def test_lp_core_multi_device(case_tester) -> None: # type: ignore ) @pytest.mark.parametrize('count', [2], indirect=True) def test_lp_uart_wakeup_modes(case_tester: CaseTester) -> None: - relevant_cases = [ - case for case in case_tester.test_menu - if {'wakeup', 'uart'}.issubset(case.groups) - ] + relevant_cases = [case for case in case_tester.test_menu if {'wakeup', 'uart'}.issubset(case.groups)] assert len(relevant_cases) == 12, ( f"Expected 12 test cases with groups 'wakeup' and 'uart', but found {len(relevant_cases)}." ) diff --git a/components/ulp/test_apps/lp_core/lp_core_hp_uart/pytest_lp_core_hp_uart.py b/components/ulp/test_apps/lp_core/lp_core_hp_uart/pytest_lp_core_hp_uart.py index 1da7285165..72e91019cc 100644 --- a/components/ulp/test_apps/lp_core/lp_core_hp_uart/pytest_lp_core_hp_uart.py +++ b/components/ulp/test_apps/lp_core/lp_core_hp_uart/pytest_lp_core_hp_uart.py @@ -1,13 +1,12 @@ -# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2024-2025 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.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32p4 @pytest.mark.generic +@idf_parametrize('target', ['esp32c5', 'esp32c6', 'esp32p4'], indirect=['target']) def test_lp_core_hp_uart_print(dut: Dut) -> None: dut.expect_exact('Press ENTER to see the list of tests') dut.write('"lp-print can output to hp-uart"') @@ -16,10 +15,8 @@ def test_lp_core_hp_uart_print(dut: Dut) -> None: dut.expect_exact('56') -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32p4 @pytest.mark.generic +@idf_parametrize('target', ['esp32c5', 'esp32c6', 'esp32p4'], indirect=['target']) def test_lp_core_panic(dut: Dut) -> None: dut.expect_exact('Press ENTER to see the list of tests') dut.write('"LP-Core panic"') @@ -29,10 +26,8 @@ def test_lp_core_panic(dut: Dut) -> None: dut.expect_exact('ELF file SHA256:') -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32p4 @pytest.mark.generic +@idf_parametrize('target', ['esp32c5', 'esp32c6', 'esp32p4'], indirect=['target']) def test_lp_core_shared_mem(dut: Dut) -> None: dut.expect_exact('Press ENTER to see the list of tests') dut.write('"LP-Core Shared-mem"') @@ -49,8 +44,8 @@ def test_lp_core_shared_mem(dut: Dut) -> None: dut.expect_exact('HP shared memory test passed') -@pytest.mark.esp32p4 @pytest.mark.generic +@idf_parametrize('target', ['esp32p4'], indirect=['target']) def test_lp_core_lp_rom(dut: Dut) -> None: dut.expect_exact('Press ENTER to see the list of tests') dut.write('"LP-Core LP-ROM"') diff --git a/components/ulp/test_apps/ulp_fsm/pytest_ulp_fsm_app.py b/components/ulp/test_apps/ulp_fsm/pytest_ulp_fsm_app.py index 9db9abb6a9..c41d7d4f0d 100644 --- a/components/ulp/test_apps/ulp_fsm/pytest_ulp_fsm_app.py +++ b/components/ulp/test_apps/ulp_fsm/pytest_ulp_fsm_app.py @@ -1,13 +1,11 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 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.esp32s3 @pytest.mark.generic +@idf_parametrize('target', ['esp32', 'esp32s2', 'esp32s3'], indirect=['target']) def test_ulp_fsm(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/ulp/test_apps/ulp_riscv/pytest_ulp_riscv.py b/components/ulp/test_apps/ulp_riscv/pytest_ulp_riscv.py index 6553fb42d9..dacb99920d 100644 --- a/components/ulp/test_apps/ulp_riscv/pytest_ulp_riscv.py +++ b/components/ulp/test_apps/ulp_riscv/pytest_ulp_riscv.py @@ -1,23 +1,20 @@ -# 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 pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 @pytest.mark.generic +@idf_parametrize('target', ['esp32s2', 'esp32s3'], indirect=['target']) def test_ulp_riscv(dut: Dut) -> None: # type: ignore dut.run_all_single_board_cases() -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 @pytest.mark.generic_multi_device -@pytest.mark.parametrize( - 'count', [2], indirect=True -) -def test_ulp_riscv_multi_device(case_tester) -> None: # type: ignore +@pytest.mark.parametrize('count', [2], indirect=True) +@idf_parametrize('target', ['esp32s2', 'esp32s3'], indirect=['target']) +def test_ulp_riscv_multi_device(case_tester) -> None: # type: ignore for case in case_tester.test_menu: if case.attributes.get('test_env', 'generic_multi_device') == 'generic_multi_device': case_tester.run_multi_dev_case(case=case, reset=True) diff --git a/components/usb/test_apps/enum/pytest_enum.py b/components/usb/test_apps/enum/pytest_enum.py index ac834f948a..024f9f8016 100644 --- a/components/usb/test_apps/enum/pytest_enum.py +++ b/components/usb/test_apps/enum/pytest_enum.py @@ -2,9 +2,10 @@ # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32s3 @pytest.mark.temp_skip_ci(targets=['esp32s3'], reason='only to run locally') +@idf_parametrize('target', ['esp32s3'], indirect=['target']) def test_usb_enum(dut: Dut) -> None: dut.run_all_single_board_cases(group='mock_enum_device', timeout=250) # some tests take more than default timeout diff --git a/components/usb/test_apps/hcd/pytest_usb_hcd.py b/components/usb/test_apps/hcd/pytest_usb_hcd.py index 4bb9ea888c..9b0f3048f1 100644 --- a/components/usb/test_apps/hcd/pytest_usb_hcd.py +++ b/components/usb/test_apps/hcd/pytest_usb_hcd.py @@ -2,15 +2,14 @@ # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32p4 @pytest.mark.temp_skip_ci(targets=['esp32s2'], reason='lack of runners with usb_host_flash_disk tag') @pytest.mark.usb_host_flash_disk +@idf_parametrize('target', ['esp32s2', 'esp32s3', 'esp32p4'], indirect=['target']) def test_usb_hcd(dut: Dut) -> None: - if (dut.target == 'esp32s3'): + if dut.target == 'esp32s3': dut.run_all_single_board_cases(group='full_speed', reset=True) else: dut.run_all_single_board_cases(group='high_speed', reset=True) diff --git a/components/usb/test_apps/phy/pytest_usb_phy.py b/components/usb/test_apps/phy/pytest_usb_phy.py index fef606d3f0..586730c428 100644 --- a/components/usb/test_apps/phy/pytest_usb_phy.py +++ b/components/usb/test_apps/phy/pytest_usb_phy.py @@ -2,11 +2,10 @@ # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32p4 @pytest.mark.generic +@idf_parametrize('target', ['esp32s2', 'esp32s3', 'esp32p4'], indirect=['target']) def test_usb_phy(dut: Dut) -> None: dut.run_all_single_board_cases(group='phy') diff --git a/components/usb/test_apps/usb_host/pytest_usb_host.py b/components/usb/test_apps/usb_host/pytest_usb_host.py index 95dd043de6..8d712c673f 100644 --- a/components/usb/test_apps/usb_host/pytest_usb_host.py +++ b/components/usb/test_apps/usb_host/pytest_usb_host.py @@ -2,15 +2,14 @@ # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32p4 @pytest.mark.temp_skip_ci(targets=['esp32s2'], reason='lack of runners with usb_host_flash_disk tag') @pytest.mark.usb_host_flash_disk +@idf_parametrize('target', ['esp32s2', 'esp32s3', 'esp32p4'], indirect=['target']) def test_usb_host(dut: Dut) -> None: - if (dut.target == 'esp32s3'): + if dut.target == 'esp32s3': dut.run_all_single_board_cases(group='full_speed', reset=True) else: dut.run_all_single_board_cases(group='high_speed', reset=True) diff --git a/components/vfs/test_apps/pytest_vfs.py b/components/vfs/test_apps/pytest_vfs.py index 60661554cd..038e405e29 100644 --- a/components/vfs/test_apps/pytest_vfs.py +++ b/components/vfs/test_apps/pytest_vfs.py @@ -1,34 +1,45 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-2025 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.esp32c2 -@pytest.mark.esp32c3 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 @pytest.mark.generic -@pytest.mark.parametrize('config', [ - 'default', 'iram', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'default', + 'iram', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32c2', 'esp32c3', 'esp32c6', 'esp32h2'], indirect=['target']) def test_vfs_default(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32 @pytest.mark.generic -@pytest.mark.parametrize('config', [ - 'ccomp', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'ccomp', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_vfs_ccomp(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32s3 @pytest.mark.quad_psram -@pytest.mark.parametrize('config', [ - 'psram', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'psram', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32s3'], indirect=['target']) def test_vfs_psram(dut: Dut) -> None: dut.run_all_single_board_cases() diff --git a/components/wear_levelling/host_test/pytest_wear_levelling_linux.py b/components/wear_levelling/host_test/pytest_wear_levelling_linux.py index 64e79de405..6c952b16f1 100644 --- a/components/wear_levelling/host_test/pytest_wear_levelling_linux.py +++ b/components/wear_levelling/host_test/pytest_wear_levelling_linux.py @@ -1,10 +1,11 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-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.linux @pytest.mark.host_test +@idf_parametrize('target', ['linux'], indirect=['target']) def test_wear_levelling_linux(dut: Dut) -> None: dut.expect_exact('All tests passed', timeout=120) diff --git a/components/wear_levelling/test_apps/pytest_wear_levelling.py b/components/wear_levelling/test_apps/pytest_wear_levelling.py index a88d0be4fa..98287957a8 100644 --- a/components/wear_levelling/test_apps/pytest_wear_levelling.py +++ b/components/wear_levelling/test_apps/pytest_wear_levelling.py @@ -1,17 +1,21 @@ -# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 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', [ - '4k', - '512perf', - '512safe', - 'release', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + '4k', + '512perf', + '512safe', + 'release', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32', 'esp32c3'], indirect=['target']) def test_wear_levelling(dut: Dut) -> None: dut.expect_unity_test_output() diff --git a/components/wpa_supplicant/test_apps/pytest_wpa_supplicant_ut.py b/components/wpa_supplicant/test_apps/pytest_wpa_supplicant_ut.py index 5968529522..0b535dd157 100644 --- a/components/wpa_supplicant/test_apps/pytest_wpa_supplicant_ut.py +++ b/components/wpa_supplicant/test_apps/pytest_wpa_supplicant_ut.py @@ -1,32 +1,30 @@ -# SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded import Dut from pytest_embedded_idf.unity_tester import CaseTester +from pytest_embedded_idf.utils import idf_parametrize @pytest.mark.generic -@pytest.mark.esp32 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32c3 -@pytest.mark.esp32c2 -@pytest.mark.esp32c6 -@pytest.mark.esp32c61 -@pytest.mark.esp32c5 +@idf_parametrize( + 'target', + ['esp32', 'esp32s2', 'esp32s3', 'esp32c3', 'esp32c2', 'esp32c6', 'esp32c61', 'esp32c5'], + indirect=['target'], +) def test_wpa_supplicant_ut(dut: Dut) -> None: dut.run_all_single_board_cases() -@pytest.mark.esp32 @pytest.mark.wifi_two_dut @pytest.mark.parametrize( 'count', [ 2, ], - indirect=True + indirect=True, ) +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_wpa_supplicant_ut_offchan(case_tester: CaseTester) -> None: for case in case_tester.test_menu: if case.attributes.get('test_env') == 'wifi_two_dut': @@ -34,15 +32,18 @@ def test_wpa_supplicant_ut_offchan(case_tester: CaseTester) -> None: # test when external bss segment is enabled -@pytest.mark.esp32s3 @pytest.mark.wifi_two_dut @pytest.mark.parametrize( 'count, config', [ - (2, 'ext_esp32s3',), + ( + 2, + 'ext_esp32s3', + ), ], - indirect=True + indirect=True, ) +@idf_parametrize('target', ['esp32s3'], indirect=['target']) def test_wpa_supplicant_ut_psram(case_tester: CaseTester) -> None: for case in case_tester.test_menu: if case.attributes.get('test_env') == 'wifi_two_dut': diff --git a/examples/bluetooth/bluedroid/ble/ble_throughput/pytest_ble_throughput_test.py b/examples/bluetooth/bluedroid/ble/ble_throughput/pytest_ble_throughput_test.py index e99fc108a9..a19cb8ed78 100644 --- a/examples/bluetooth/bluedroid/ble/ble_throughput/pytest_ble_throughput_test.py +++ b/examples/bluetooth/bluedroid/ble/ble_throughput/pytest_ble_throughput_test.py @@ -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 os.path import time @@ -6,30 +6,35 @@ from typing import Tuple import pytest from pytest_embedded_idf.dut import IdfDut - - +from pytest_embedded_idf.utils import idf_parametrize # Case 1: gatt write throughput test(EXAMPLE_CI_ID = 2) -@pytest.mark.esp32 -@pytest.mark.esp32c3 -@pytest.mark.esp32c6 -@pytest.mark.esp32c61 -@pytest.mark.esp32c5 -@pytest.mark.esp32h2 -@pytest.mark.esp32s3 + + @pytest.mark.wifi_two_dut @pytest.mark.parametrize( - 'count, app_path, config, erase_nvs', [ - (2, - f'{os.path.join(os.path.dirname(__file__), "throughput_server")}|{os.path.join(os.path.dirname(__file__), "throughput_client")}', - 'write', 'y'), + 'count, app_path, config, erase_nvs', + [ + ( + 2, + f'{os.path.join(os.path.dirname(__file__), "throughput_server")}|{os.path.join(os.path.dirname(__file__), "throughput_client")}', + 'write', + 'y', + ), ], indirect=True, ) +@idf_parametrize( + 'target', ['esp32', 'esp32c3', 'esp32c6', 'esp32c61', 'esp32c5', 'esp32h2', 'esp32s3'], indirect=['target'] +) def test_gatt_write_throughput(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: server = dut[0] client = dut[1] - client_addr = client.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') - server_addr = server.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') + client_addr = ( + client.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') + ) + server_addr = ( + server.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') + ) client.expect_exact('GATT client register, status 0', timeout=30) server.expect_exact('GATT server register, status 0', timeout=30) @@ -49,22 +54,31 @@ def test_gatt_write_throughput(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> Non # Case 2: gatt write throughput test for ESP32C2 26mhz xtal(EXAMPLE_CI_ID = 2) -@pytest.mark.esp32c2 @pytest.mark.wifi_two_dut @pytest.mark.xtal_26mhz @pytest.mark.parametrize( - 'count, target, baud, app_path, config, erase_nvs', [ - (2, 'esp32c2|esp32c2', '74880', - f'{os.path.join(os.path.dirname(__file__), "throughput_server")}|{os.path.join(os.path.dirname(__file__), "throughput_client")}', - 'esp32c2_xtal26m_write', 'y'), + 'count, target, baud, app_path, config, erase_nvs', + [ + ( + 2, + 'esp32c2|esp32c2', + '74880', + f'{os.path.join(os.path.dirname(__file__), "throughput_server")}|{os.path.join(os.path.dirname(__file__), "throughput_client")}', + 'esp32c2_xtal26m_write', + 'y', + ), ], indirect=True, ) def test_c2_26mhz_xtal_write_throughput(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: server = dut[0] client = dut[1] - client_addr = client.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') - server_addr = server.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') + client_addr = ( + client.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') + ) + server_addr = ( + server.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') + ) client.expect_exact('GATT client register, status 0', timeout=30) server.expect_exact('GATT server register, status 0', timeout=30) @@ -84,27 +98,31 @@ def test_c2_26mhz_xtal_write_throughput(app_path: str, dut: Tuple[IdfDut, IdfDut # Case 3: gatt notify throughput test(EXAMPLE_CI_ID = 1) -@pytest.mark.esp32 -@pytest.mark.esp32c3 -@pytest.mark.esp32c6 -@pytest.mark.esp32c61 -@pytest.mark.esp32c5 -@pytest.mark.esp32h2 -@pytest.mark.esp32s3 @pytest.mark.wifi_two_dut @pytest.mark.parametrize( - 'count, app_path, config, erase_nvs', [ - (2, - f'{os.path.join(os.path.dirname(__file__), "throughput_server")}|{os.path.join(os.path.dirname(__file__), "throughput_client")}', - 'notify', 'y'), + 'count, app_path, config, erase_nvs', + [ + ( + 2, + f'{os.path.join(os.path.dirname(__file__), "throughput_server")}|{os.path.join(os.path.dirname(__file__), "throughput_client")}', + 'notify', + 'y', + ), ], indirect=True, ) +@idf_parametrize( + 'target', ['esp32', 'esp32c3', 'esp32c6', 'esp32c61', 'esp32c5', 'esp32h2', 'esp32s3'], indirect=['target'] +) def test_gatt_notify_throughput(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: server = dut[0] client = dut[1] - client_addr = client.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') - server_addr = server.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') + client_addr = ( + client.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') + ) + server_addr = ( + server.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') + ) client.expect_exact('GATT client register, status 0', timeout=30) server.expect_exact('GATT server register, status 0', timeout=30) @@ -126,22 +144,31 @@ def test_gatt_notify_throughput(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> No # Case 4: gatt notify throughput test for ESP32C2 26mhz xtal(EXAMPLE_CI_ID = 1) -@pytest.mark.esp32c2 @pytest.mark.wifi_two_dut @pytest.mark.xtal_26mhz @pytest.mark.parametrize( - 'count, target, baud, app_path, config, erase_nvs', [ - (2, 'esp32c2|esp32c2', '74880', - f'{os.path.join(os.path.dirname(__file__), "throughput_server")}|{os.path.join(os.path.dirname(__file__), "throughput_client")}', - 'esp32c2_xtal26m_notify', 'y'), + 'count, target, baud, app_path, config, erase_nvs', + [ + ( + 2, + 'esp32c2|esp32c2', + '74880', + f'{os.path.join(os.path.dirname(__file__), "throughput_server")}|{os.path.join(os.path.dirname(__file__), "throughput_client")}', + 'esp32c2_xtal26m_notify', + 'y', + ), ], indirect=True, ) def test_c2_26mhz_xtal_notify_throughput(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: server = dut[0] client = dut[1] - client_addr = client.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') - server_addr = server.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') + client_addr = ( + client.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') + ) + server_addr = ( + server.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') + ) client.expect_exact('GATT client register, status 0', timeout=30) server.expect_exact('GATT server register, status 0', timeout=30) diff --git a/examples/bluetooth/bluedroid/ble/pytest_ble_test.py b/examples/bluetooth/bluedroid/ble/pytest_ble_test.py index f2d020c6d1..7ac6ec61fc 100644 --- a/examples/bluetooth/bluedroid/ble/pytest_ble_test.py +++ b/examples/bluetooth/bluedroid/ble/pytest_ble_test.py @@ -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 os.path from typing import Tuple @@ -7,31 +7,36 @@ import pexpect import pytest from pytest_embedded import Dut from pytest_embedded_idf.dut import IdfDut - - +from pytest_embedded_idf.utils import idf_parametrize # Case 1: gatt client and gatt server test # EXAMPLE_CI_ID=3 -@pytest.mark.esp32 -@pytest.mark.esp32c3 -@pytest.mark.esp32c6 -@pytest.mark.esp32c5 -@pytest.mark.esp32h2 -@pytest.mark.esp32s3 -@pytest.mark.esp32c61 + + @pytest.mark.wifi_two_dut @pytest.mark.parametrize( - 'count, app_path, config, erase_nvs', [ - (2, - f'{os.path.join(os.path.dirname(__file__), "gatt_server")}|{os.path.join(os.path.dirname(__file__), "gatt_client")}', - 'name', 'y'), + 'count, app_path, config, erase_nvs', + [ + ( + 2, + f'{os.path.join(os.path.dirname(__file__), "gatt_server")}|{os.path.join(os.path.dirname(__file__), "gatt_client")}', + 'name', + 'y', + ), ], indirect=True, ) +@idf_parametrize( + 'target', ['esp32', 'esp32c3', 'esp32c6', 'esp32c5', 'esp32h2', 'esp32s3', 'esp32c61'], indirect=['target'] +) def test_gatt_func(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: gatt_client = dut[1] gatt_server = dut[0] - gatt_client_addr = gatt_client.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') - gatt_server_addr = gatt_server.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') + gatt_client_addr = ( + gatt_client.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') + ) + gatt_server_addr = ( + gatt_server.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') + ) gatt_client.expect_exact('GATT client register, status 0', timeout=30) gatt_server.expect_exact('GATT server register, status 0', timeout=30) gatt_server.expect_exact('Advertising start successfully', timeout=30) @@ -56,22 +61,31 @@ def test_gatt_func(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: # Case 2: gatt client and gatt server test for ESP32C2 26mhz xtal # EXAMPLE_CI_ID=3 -@pytest.mark.esp32c2 @pytest.mark.wifi_two_dut @pytest.mark.xtal_26mhz @pytest.mark.parametrize( - 'count, target, baud, app_path, config, erase_nvs', [ - (2, 'esp32c2|esp32c2', '74880', - f'{os.path.join(os.path.dirname(__file__), "gatt_server")}|{os.path.join(os.path.dirname(__file__), "gatt_client")}', - 'esp32c2_xtal26m', 'y'), + 'count, target, baud, app_path, config, erase_nvs', + [ + ( + 2, + 'esp32c2|esp32c2', + '74880', + f'{os.path.join(os.path.dirname(__file__), "gatt_server")}|{os.path.join(os.path.dirname(__file__), "gatt_client")}', + 'esp32c2_xtal26m', + 'y', + ), ], indirect=True, ) def test_c2_26mhz_xtal_gatt_func(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: gatt_client = dut[1] gatt_server = dut[0] - gatt_client_addr = gatt_client.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})').group(1).decode('utf8') - gatt_server_addr = gatt_server.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})').group(1).decode('utf8') + gatt_client_addr = ( + gatt_client.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})').group(1).decode('utf8') + ) + gatt_server_addr = ( + gatt_server.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})').group(1).decode('utf8') + ) gatt_client.expect_exact('GATT client register, status 0', timeout=30) gatt_server.expect_exact('GATT server register, status 0', timeout=30) gatt_server.expect_exact('Advertising start successfully', timeout=30) @@ -96,26 +110,30 @@ def test_c2_26mhz_xtal_gatt_func(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> N # Case 3: gatt security server and gatt security client test # EXAMPLE_CI_ID=5 -@pytest.mark.esp32 -@pytest.mark.esp32c3 -@pytest.mark.esp32c6 -@pytest.mark.esp32c5 -@pytest.mark.esp32h2 -@pytest.mark.esp32s3 -@pytest.mark.esp32c61 @pytest.mark.wifi_two_dut @pytest.mark.parametrize( - 'count, app_path, config, erase_nvs', [ - (2, - f'{os.path.join(os.path.dirname(__file__), "gatt_security_server")}|{os.path.join(os.path.dirname(__file__), "gatt_security_client")}', - 'name', 'y'), + 'count, app_path, config, erase_nvs', + [ + ( + 2, + f'{os.path.join(os.path.dirname(__file__), "gatt_security_server")}|{os.path.join(os.path.dirname(__file__), "gatt_security_client")}', + 'name', + 'y', + ), ], indirect=True, ) +@idf_parametrize( + 'target', ['esp32', 'esp32c3', 'esp32c6', 'esp32c5', 'esp32h2', 'esp32s3', 'esp32c61'], indirect=['target'] +) def test_gatt_security_func(app_path: str, dut: Tuple[IdfDut, IdfDut], target: Tuple) -> None: gatt_security_client = dut[1] gatt_security_server = dut[0] - gatt_security_client_addr = gatt_security_client.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') + gatt_security_client_addr = ( + gatt_security_client.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30) + .group(1) + .decode('utf8') + ) gatt_security_client.expect_exact('GATT client register, status 0', timeout=30) gatt_security_server.expect_exact('GATT server register, status 0', timeout=30) @@ -142,7 +160,9 @@ def test_gatt_security_func(app_path: str, dut: Tuple[IdfDut, IdfDut], target: T if target == ('esp32', 'esp32'): gatt_security_server.expect_exact(f'Authentication complete, addr_type 1, addr ', timeout=30) else: - gatt_security_server.expect_exact(f'Authentication complete, addr_type 0, addr {gatt_security_client_addr}', timeout=30) + gatt_security_server.expect_exact( + f'Authentication complete, addr_type 0, addr {gatt_security_client_addr}', timeout=30 + ) gatt_security_client.expect_exact(f'Authentication complete, addr_type 1, addr ', timeout=30) gatt_security_server.expect_exact('Pairing successfully', timeout=30) gatt_security_server.expect_exact('Bonded devices number 1', timeout=30) @@ -158,21 +178,30 @@ def test_gatt_security_func(app_path: str, dut: Tuple[IdfDut, IdfDut], target: T # Case 4: gatt security server and gatt security client test for ESP32C2 26mhz xtal # EXAMPLE_CI_ID=5 -@pytest.mark.esp32c2 @pytest.mark.wifi_two_dut @pytest.mark.xtal_26mhz @pytest.mark.parametrize( - 'count, target, baud, app_path, config, erase_nvs', [ - (2, 'esp32c2|esp32c2', '74880', - f'{os.path.join(os.path.dirname(__file__), "gatt_security_server")}|{os.path.join(os.path.dirname(__file__), "gatt_security_client")}', - 'esp32c2_xtal26m', 'y'), + 'count, target, baud, app_path, config, erase_nvs', + [ + ( + 2, + 'esp32c2|esp32c2', + '74880', + f'{os.path.join(os.path.dirname(__file__), "gatt_security_server")}|{os.path.join(os.path.dirname(__file__), "gatt_security_client")}', + 'esp32c2_xtal26m', + 'y', + ), ], indirect=True, ) def test_c2_26mhz_xtal_gatt_security_func(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: gatt_security_client = dut[1] gatt_security_server = dut[0] - gatt_security_client_addr = gatt_security_client.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') + gatt_security_client_addr = ( + gatt_security_client.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30) + .group(1) + .decode('utf8') + ) gatt_security_client.expect_exact('GATT client register, status 0', timeout=30) gatt_security_server.expect_exact('GATT server register, status 0', timeout=30) @@ -193,7 +222,9 @@ def test_c2_26mhz_xtal_gatt_security_func(app_path: str, dut: Tuple[IdfDut, IdfD gatt_security_server.expect_exact('Key exchanged, key_type ESP_LE_KEY_PENC', timeout=30) gatt_security_server.expect_exact('Key exchanged, key_type ESP_LE_KEY_LID', timeout=30) gatt_security_server.expect_exact('Key exchanged, key_type ESP_LE_KEY_PID', timeout=30) - gatt_security_server.expect_exact(f'Authentication complete, addr_type 0, addr {gatt_security_client_addr}', timeout=30) + gatt_security_server.expect_exact( + f'Authentication complete, addr_type 0, addr {gatt_security_client_addr}', timeout=30 + ) gatt_security_client.expect_exact(f'Authentication complete, addr_type 1, addr ', timeout=30) gatt_security_server.expect_exact('Pairing successfully', timeout=30) gatt_security_server.expect_exact('Bonded devices number 1', timeout=30) @@ -208,27 +239,31 @@ def test_c2_26mhz_xtal_gatt_security_func(app_path: str, dut: Tuple[IdfDut, IdfD # Case 5: ble ibeacon test -@pytest.mark.esp32 -@pytest.mark.esp32c3 -@pytest.mark.esp32c6 -@pytest.mark.esp32c5 -@pytest.mark.esp32h2 -@pytest.mark.esp32s3 -@pytest.mark.esp32c61 @pytest.mark.wifi_two_dut @pytest.mark.parametrize( - 'count, app_path, config, erase_nvs', [ - (2, - f'{os.path.join(os.path.dirname(__file__), "ble_ibeacon")}|{os.path.join(os.path.dirname(__file__), "ble_ibeacon")}', - 'sender|receiver', 'y'), + 'count, app_path, config, erase_nvs', + [ + ( + 2, + f'{os.path.join(os.path.dirname(__file__), "ble_ibeacon")}|{os.path.join(os.path.dirname(__file__), "ble_ibeacon")}', + 'sender|receiver', + 'y', + ), ], indirect=True, ) +@idf_parametrize( + 'target', ['esp32', 'esp32c3', 'esp32c6', 'esp32c5', 'esp32h2', 'esp32s3', 'esp32c61'], indirect=['target'] +) def test_ble_ibeacon_func(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: ibeacon_sender = dut[0] ibeacon_receiver = dut[1] - ibeacon_sender_addr = ibeacon_sender.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') + ibeacon_sender_addr = ( + ibeacon_sender.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30) + .group(1) + .decode('utf8') + ) ibeacon_sender.expect_exact('Advertising start successfully', timeout=30) ibeacon_receiver.expect_exact('Scanning start successfully', timeout=30) @@ -242,14 +277,19 @@ def test_ble_ibeacon_func(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: # Case 5: ble ibeacon test for ESP32C2 26mhz xtal -@pytest.mark.esp32c2 @pytest.mark.wifi_two_dut @pytest.mark.xtal_26mhz @pytest.mark.parametrize( - 'count, target, baud, app_path, config, erase_nvs', [ - (2, 'esp32c2|esp32c2', '74880', - f'{os.path.join(os.path.dirname(__file__), "ble_ibeacon")}|{os.path.join(os.path.dirname(__file__), "ble_ibeacon")}', - 'esp32c2_xtal26m_sender|esp32c2_xtal26m_receiver', 'y'), + 'count, target, baud, app_path, config, erase_nvs', + [ + ( + 2, + 'esp32c2|esp32c2', + '74880', + f'{os.path.join(os.path.dirname(__file__), "ble_ibeacon")}|{os.path.join(os.path.dirname(__file__), "ble_ibeacon")}', + 'esp32c2_xtal26m_sender|esp32c2_xtal26m_receiver', + 'y', + ), ], indirect=True, ) @@ -257,7 +297,11 @@ def test_c2_26mhz_ble_ibeacon_func(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> ibeacon_sender = dut[0] ibeacon_receiver = dut[1] - ibeacon_sender_addr = ibeacon_sender.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') + ibeacon_sender_addr = ( + ibeacon_sender.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30) + .group(1) + .decode('utf8') + ) ibeacon_sender.expect_exact('Advertising start successfully', timeout=30) ibeacon_receiver.expect_exact('Scanning start successfully', timeout=30) @@ -272,27 +316,31 @@ def test_c2_26mhz_ble_ibeacon_func(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> # Case 6: gatt client and gatt server config test # EXAMPLE_CI_ID=4 -@pytest.mark.esp32 -@pytest.mark.esp32c3 -@pytest.mark.esp32c6 -@pytest.mark.esp32c5 -@pytest.mark.esp32h2 -@pytest.mark.esp32s3 -@pytest.mark.esp32c61 @pytest.mark.wifi_two_dut @pytest.mark.parametrize( - 'count, app_path, config, erase_nvs', [ - (2, - f'{os.path.join(os.path.dirname(__file__), "gatt_server")}|{os.path.join(os.path.dirname(__file__), "gatt_client")}', - 'cfg_test', 'y'), + 'count, app_path, config, erase_nvs', + [ + ( + 2, + f'{os.path.join(os.path.dirname(__file__), "gatt_server")}|{os.path.join(os.path.dirname(__file__), "gatt_client")}', + 'cfg_test', + 'y', + ), ], indirect=True, ) +@idf_parametrize( + 'target', ['esp32', 'esp32c3', 'esp32c6', 'esp32c5', 'esp32h2', 'esp32s3', 'esp32c61'], indirect=['target'] +) def test_gatt_config_func(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: gatt_client = dut[1] gatt_server = dut[0] - gatt_client_addr = gatt_client.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') - gatt_server_addr = gatt_server.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') + gatt_client_addr = ( + gatt_client.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') + ) + gatt_server_addr = ( + gatt_server.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') + ) gatt_client.expect_exact('GATT client register, status 0', timeout=30) gatt_server.expect_exact('GATT server register, status 0', timeout=30) gatt_server.expect_exact('Advertising start successfully', timeout=30) @@ -317,22 +365,31 @@ def test_gatt_config_func(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: # Case 7: gatt client and gatt server config test for ESP32C2 26mhz xtal # EXAMPLE_CI_ID=3 -@pytest.mark.esp32c2 @pytest.mark.wifi_two_dut @pytest.mark.xtal_26mhz @pytest.mark.parametrize( - 'count, target, baud, app_path, config, erase_nvs', [ - (2, 'esp32c2|esp32c2', '74880', - f'{os.path.join(os.path.dirname(__file__), "gatt_server")}|{os.path.join(os.path.dirname(__file__), "gatt_client")}', - 'esp32c2_cfg_test', 'y'), + 'count, target, baud, app_path, config, erase_nvs', + [ + ( + 2, + 'esp32c2|esp32c2', + '74880', + f'{os.path.join(os.path.dirname(__file__), "gatt_server")}|{os.path.join(os.path.dirname(__file__), "gatt_client")}', + 'esp32c2_cfg_test', + 'y', + ), ], indirect=True, ) def test_c2_26mhz_xtal_gatt_config_func(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: gatt_client = dut[1] gatt_server = dut[0] - gatt_client_addr = gatt_client.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})').group(1).decode('utf8') - gatt_server_addr = gatt_server.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})').group(1).decode('utf8') + gatt_client_addr = ( + gatt_client.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})').group(1).decode('utf8') + ) + gatt_server_addr = ( + gatt_server.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})').group(1).decode('utf8') + ) gatt_client.expect_exact('GATT client register, status 0', timeout=30) gatt_server.expect_exact('GATT server register, status 0', timeout=30) gatt_server.expect_exact('Advertising start successfully', timeout=30) @@ -356,16 +413,13 @@ def test_c2_26mhz_xtal_gatt_config_func(app_path: str, dut: Tuple[IdfDut, IdfDut # Case 8: BLE init deinit loop test -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32c3 -@pytest.mark.esp32s3 -@pytest.mark.esp32c5 -@pytest.mark.esp32c61 -@pytest.mark.esp32 @pytest.mark.generic -@pytest.mark.parametrize('config, app_path', [('init_deinit', - f'{os.path.join(os.path.dirname(__file__), "gatt_client")}')], indirect=True) +@pytest.mark.parametrize( + 'config, app_path', [('init_deinit', f'{os.path.join(os.path.dirname(__file__), "gatt_client")}')], indirect=True +) +@idf_parametrize( + 'target', ['esp32c6', 'esp32h2', 'esp32c3', 'esp32s3', 'esp32c5', 'esp32c61', 'esp32'], indirect=['target'] +) def test_bluedroid_host_init_deinit(dut: Dut) -> None: all_hp = [] dut.expect_exact('Bluetooth MAC:') @@ -377,17 +431,16 @@ def test_bluedroid_host_init_deinit(dut: Dut) -> None: # # Case 9: BLE init deinit loop test for ESP32C2 26mhz xtal -@pytest.mark.esp32c2 @pytest.mark.wifi_two_dut @pytest.mark.xtal_26mhz @pytest.mark.parametrize( - 'baud, app_path, config', [ - ('74880', - f'{os.path.join(os.path.dirname(__file__), "gatt_client")}', - 'esp32c2_init_deinit'), + 'baud, app_path, config', + [ + ('74880', f'{os.path.join(os.path.dirname(__file__), "gatt_client")}', 'esp32c2_init_deinit'), ], indirect=True, ) +@idf_parametrize('target', ['esp32c2'], indirect=['target']) def test_c2_26mhz_bluedroid_host_init_deinit(dut: Dut) -> None: all_hp = [] dut.expect_exact('Bluetooth MAC:') diff --git a/examples/bluetooth/bluedroid/ble_50/pytest_ble50_test.py b/examples/bluetooth/bluedroid/ble_50/pytest_ble50_test.py index b3b42a6a3c..d48aef51ac 100644 --- a/examples/bluetooth/bluedroid/ble_50/pytest_ble50_test.py +++ b/examples/bluetooth/bluedroid/ble_50/pytest_ble50_test.py @@ -1,34 +1,38 @@ -# 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 os.path from typing import Tuple import pytest from pytest_embedded_idf.dut import IdfDut - - +from pytest_embedded_idf.utils import idf_parametrize # Case 1: ble50 security client and ble50 security server test # EXAMPLE_CI_ID=6 -@pytest.mark.esp32c3 -@pytest.mark.esp32c6 -@pytest.mark.esp32c5 -@pytest.mark.esp32h2 -@pytest.mark.esp32s3 -@pytest.mark.esp32c61 + + @pytest.mark.wifi_two_dut @pytest.mark.parametrize( - 'count, app_path, config, erase_nvs', [ - (2, - f'{os.path.join(os.path.dirname(__file__), "ble50_security_server")}|{os.path.join(os.path.dirname(__file__), "ble50_security_client")}', - 'name', 'y'), + 'count, app_path, config, erase_nvs', + [ + ( + 2, + f'{os.path.join(os.path.dirname(__file__), "ble50_security_server")}|{os.path.join(os.path.dirname(__file__), "ble50_security_client")}', + 'name', + 'y', + ), ], indirect=True, ) +@idf_parametrize('target', ['esp32c3', 'esp32c6', 'esp32c5', 'esp32h2', 'esp32s3', 'esp32c61'], indirect=['target']) def test_ble50_security_func(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: server = dut[0] client = dut[1] - client_addr = client.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') - server_addr = server.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') + client_addr = ( + client.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') + ) + server_addr = ( + server.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') + ) server.expect_exact('Extended advertising params set, status 0', timeout=30) server.expect_exact('Extended advertising data set, status 0', timeout=30) @@ -48,22 +52,31 @@ def test_ble50_security_func(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: # Case 2: ble50 security client and ble50 security server test for ESP32C2 26mhz xtal # EXAMPLE_CI_ID=6 -@pytest.mark.esp32c2 @pytest.mark.wifi_two_dut @pytest.mark.xtal_26mhz @pytest.mark.parametrize( - 'count, target, baud, app_path, config, erase_nvs', [ - (2, 'esp32c2|esp32c2', '74880', - f'{os.path.join(os.path.dirname(__file__), "ble50_security_server")}|{os.path.join(os.path.dirname(__file__), "ble50_security_client")}', - 'esp32c2_xtal26m', 'y'), + 'count, target, baud, app_path, config, erase_nvs', + [ + ( + 2, + 'esp32c2|esp32c2', + '74880', + f'{os.path.join(os.path.dirname(__file__), "ble50_security_server")}|{os.path.join(os.path.dirname(__file__), "ble50_security_client")}', + 'esp32c2_xtal26m', + 'y', + ), ], indirect=True, ) def test_c2_26mhz_xtal_ble50_security_func(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: server = dut[0] client = dut[1] - client_addr = client.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') - server_addr = server.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') + client_addr = ( + client.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') + ) + server_addr = ( + server.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') + ) server.expect_exact('Extended advertising params set, status 0', timeout=30) server.expect_exact('Extended advertising data set, status 0', timeout=30) @@ -83,21 +96,20 @@ def test_c2_26mhz_xtal_ble50_security_func(app_path: str, dut: Tuple[IdfDut, Idf # Case 3: period_adv and period_sync test # EXAMPLE_CI_ID=8 -@pytest.mark.esp32c3 -@pytest.mark.esp32c6 -@pytest.mark.esp32c5 -@pytest.mark.esp32h2 -@pytest.mark.esp32s3 -@pytest.mark.esp32c61 @pytest.mark.wifi_two_dut @pytest.mark.parametrize( - 'count, app_path, config, erase_nvs', [ - (2, - f'{os.path.join(os.path.dirname(__file__), "periodic_adv")}|{os.path.join(os.path.dirname(__file__), "periodic_sync")}', - 'name', 'y'), + 'count, app_path, config, erase_nvs', + [ + ( + 2, + f'{os.path.join(os.path.dirname(__file__), "periodic_adv")}|{os.path.join(os.path.dirname(__file__), "periodic_sync")}', + 'name', + 'y', + ), ], indirect=True, ) +@idf_parametrize('target', ['esp32c3', 'esp32c6', 'esp32c5', 'esp32h2', 'esp32s3', 'esp32c61'], indirect=['target']) def test_period_adv_sync_func(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: adv_dut = dut[0] sync_dut = dut[1] @@ -118,14 +130,19 @@ def test_period_adv_sync_func(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None # Case 4: period_adv and period_sync test for ESP32C2 26mhz xtal # EXAMPLE_CI_ID=8 -@pytest.mark.esp32c2 @pytest.mark.wifi_two_dut @pytest.mark.xtal_26mhz @pytest.mark.parametrize( - 'count, target, baud, app_path, config, erase_nvs', [ - (2, 'esp32c2|esp32c2', '74880', - f'{os.path.join(os.path.dirname(__file__), "periodic_adv")}|{os.path.join(os.path.dirname(__file__), "periodic_sync")}', - 'esp32c2_xtal26m', 'y'), + 'count, target, baud, app_path, config, erase_nvs', + [ + ( + 2, + 'esp32c2|esp32c2', + '74880', + f'{os.path.join(os.path.dirname(__file__), "periodic_adv")}|{os.path.join(os.path.dirname(__file__), "periodic_sync")}', + 'esp32c2_xtal26m', + 'y', + ), ], indirect=True, ) @@ -149,26 +166,29 @@ def test_c2_26mhz_xtal_period_adv_sync_func(app_path: str, dut: Tuple[IdfDut, Id # Case 5: ble50 security client and ble50 security server config test # EXAMPLE_CI_ID=7 -@pytest.mark.esp32c3 -@pytest.mark.esp32c6 -@pytest.mark.esp32c5 -@pytest.mark.esp32h2 -@pytest.mark.esp32s3 -@pytest.mark.esp32c61 @pytest.mark.wifi_two_dut @pytest.mark.parametrize( - 'count, app_path, config, erase_nvs', [ - (2, - f'{os.path.join(os.path.dirname(__file__), "ble50_security_server")}|{os.path.join(os.path.dirname(__file__), "ble50_security_client")}', - 'cfg_test', 'y'), + 'count, app_path, config, erase_nvs', + [ + ( + 2, + f'{os.path.join(os.path.dirname(__file__), "ble50_security_server")}|{os.path.join(os.path.dirname(__file__), "ble50_security_client")}', + 'cfg_test', + 'y', + ), ], indirect=True, ) +@idf_parametrize('target', ['esp32c3', 'esp32c6', 'esp32c5', 'esp32h2', 'esp32s3', 'esp32c61'], indirect=['target']) def test_ble50_security_config_func(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: server = dut[0] client = dut[1] - client_addr = client.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') - server_addr = server.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') + client_addr = ( + client.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') + ) + server_addr = ( + server.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') + ) server.expect_exact('Extended advertising params set, status 0', timeout=30) server.expect_exact('Extended advertising data set, status 0', timeout=30) @@ -190,22 +210,31 @@ def test_ble50_security_config_func(app_path: str, dut: Tuple[IdfDut, IdfDut]) - # Case 6: ble50 security client and ble50 security server config test for ESP32C2 26mhz xtal # EXAMPLE_CI_ID=7 -@pytest.mark.esp32c2 @pytest.mark.wifi_two_dut @pytest.mark.xtal_26mhz @pytest.mark.parametrize( - 'count, target, baud, app_path, config, erase_nvs', [ - (2, 'esp32c2|esp32c2', '74880', - f'{os.path.join(os.path.dirname(__file__), "ble50_security_server")}|{os.path.join(os.path.dirname(__file__), "ble50_security_client")}', - 'esp32c2_cfg_test', 'y'), + 'count, target, baud, app_path, config, erase_nvs', + [ + ( + 2, + 'esp32c2|esp32c2', + '74880', + f'{os.path.join(os.path.dirname(__file__), "ble50_security_server")}|{os.path.join(os.path.dirname(__file__), "ble50_security_client")}', + 'esp32c2_cfg_test', + 'y', + ), ], indirect=True, ) def test_c2_26mhz_xtal_ble50_security_config_func(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: server = dut[0] client = dut[1] - client_addr = client.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') - server_addr = server.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') + client_addr = ( + client.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') + ) + server_addr = ( + server.expect(r'Bluetooth MAC: (([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2})', timeout=30).group(1).decode('utf8') + ) server.expect_exact('Extended advertising params set, status 0', timeout=30) server.expect_exact('Extended advertising data set, status 0', timeout=30) diff --git a/examples/bluetooth/bluedroid/classic_bt/bt_discovery/pytest_classic_bt_discovery_test.py b/examples/bluetooth/bluedroid/classic_bt/bt_discovery/pytest_classic_bt_discovery_test.py index d68b55be8c..08bee890f0 100644 --- a/examples/bluetooth/bluedroid/classic_bt/bt_discovery/pytest_classic_bt_discovery_test.py +++ b/examples/bluetooth/bluedroid/classic_bt/bt_discovery/pytest_classic_bt_discovery_test.py @@ -1,10 +1,11 @@ -# 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.generic +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_bt_discovery(dut: Dut) -> None: dut.expect_exact('Discovery started.') diff --git a/examples/bluetooth/bluedroid/classic_bt/pytest_classic_bt_test.py b/examples/bluetooth/bluedroid/classic_bt/pytest_classic_bt_test.py index 07e1e27f31..4154dce414 100644 --- a/examples/bluetooth/bluedroid/classic_bt/pytest_classic_bt_test.py +++ b/examples/bluetooth/bluedroid/classic_bt/pytest_classic_bt_test.py @@ -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 os.path from typing import Tuple @@ -6,16 +6,20 @@ from typing import Tuple import pexpect import pytest from pytest_embedded_idf.dut import IdfDut - - # Case 1: SPP -@pytest.mark.esp32 + + @pytest.mark.wifi_two_dut @pytest.mark.parametrize( - 'count, app_path, target, erase_all, config', [ - (2, - f'{os.path.join(os.path.dirname(__file__), "bt_spp_acceptor")}|{os.path.join(os.path.dirname(__file__), "bt_spp_initiator")}', - 'esp32|esp32', 'y', 'test'), + 'count, app_path, target, erase_all, config', + [ + ( + 2, + f'{os.path.join(os.path.dirname(__file__), "bt_spp_acceptor")}|{os.path.join(os.path.dirname(__file__), "bt_spp_initiator")}', + 'esp32|esp32', + 'y', + 'test', + ), ], indirect=True, ) @@ -39,13 +43,16 @@ def test_bt_spp_only(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: # Case 2: SPP_VFS -@pytest.mark.esp32 @pytest.mark.wifi_two_dut @pytest.mark.parametrize( - 'count, app_path, target, config', [ - (2, - f'{os.path.join(os.path.dirname(__file__), "bt_spp_vfs_acceptor")}|{os.path.join(os.path.dirname(__file__), "bt_spp_vfs_initiator")}', - 'esp32|esp32', 'test'), + 'count, app_path, target, config', + [ + ( + 2, + f'{os.path.join(os.path.dirname(__file__), "bt_spp_vfs_acceptor")}|{os.path.join(os.path.dirname(__file__), "bt_spp_vfs_initiator")}', + 'esp32|esp32', + 'test', + ), ], indirect=True, ) @@ -64,13 +71,16 @@ def test_bt_spp_vfs(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: # Case 3: A2DP -@pytest.mark.esp32 @pytest.mark.wifi_two_dut @pytest.mark.parametrize( - 'count, app_path, target, config', [ - (2, - f'{os.path.join(os.path.dirname(__file__), "a2dp_sink")}|{os.path.join(os.path.dirname(__file__), "a2dp_source")}', - 'esp32|esp32', 'test'), + 'count, app_path, target, config', + [ + ( + 2, + f'{os.path.join(os.path.dirname(__file__), "a2dp_sink")}|{os.path.join(os.path.dirname(__file__), "a2dp_source")}', + 'esp32|esp32', + 'test', + ), ], indirect=True, ) @@ -87,13 +97,16 @@ def test_bt_a2dp(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: # Case 4: HFP -@pytest.mark.esp32 @pytest.mark.wifi_two_dut @pytest.mark.parametrize( - 'count, app_path, target, config', [ - (2, - f'{os.path.join(os.path.dirname(__file__), "hfp_ag")}|{os.path.join(os.path.dirname(__file__), "hfp_hf")}', - 'esp32|esp32', 'all'), + 'count, app_path, target, config', + [ + ( + 2, + f'{os.path.join(os.path.dirname(__file__), "hfp_ag")}|{os.path.join(os.path.dirname(__file__), "hfp_hf")}', + 'esp32|esp32', + 'all', + ), ], indirect=True, ) @@ -109,14 +122,17 @@ def test_bt_hfp(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: # # Case 5: HID -@pytest.mark.esp32 @pytest.mark.wifi_two_dut @pytest.mark.parametrize( - 'count, app_path, target, config', [ - (2, - f'{os.path.join(os.path.dirname(__file__), "bt_hid_mouse_device")}|' - f'{os.path.join(os.path.abspath(os.path.join(os.path.dirname(__file__), "../..")), "esp_hid_host")}', - 'esp32|esp32', 'test'), + 'count, app_path, target, config', + [ + ( + 2, + f'{os.path.join(os.path.dirname(__file__), "bt_hid_mouse_device")}|' + f'{os.path.join(os.path.abspath(os.path.join(os.path.dirname(__file__), "../..")), "esp_hid_host")}', + 'esp32|esp32', + 'test', + ), ], indirect=True, ) @@ -135,13 +151,16 @@ def test_bt_hid(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: # Case 6: L2CAP -@pytest.mark.esp32 @pytest.mark.wifi_two_dut @pytest.mark.parametrize( - 'count, app_path, target, config', [ - (2, - f'{os.path.join(os.path.dirname(__file__), "bt_l2cap_server")}|{os.path.join(os.path.dirname(__file__), "bt_l2cap_client")}', - 'esp32|esp32', 'test'), + 'count, app_path, target, config', + [ + ( + 2, + f'{os.path.join(os.path.dirname(__file__), "bt_l2cap_server")}|{os.path.join(os.path.dirname(__file__), "bt_l2cap_client")}', + 'esp32|esp32', + 'test', + ), ], indirect=True, ) diff --git a/examples/bluetooth/nimble/pytest_nimble_test.py b/examples/bluetooth/nimble/pytest_nimble_test.py index 76ab824842..47eb5488ef 100644 --- a/examples/bluetooth/nimble/pytest_nimble_test.py +++ b/examples/bluetooth/nimble/pytest_nimble_test.py @@ -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 os.path from typing import Tuple @@ -6,24 +6,24 @@ from typing import Tuple import pexpect import pytest from pytest_embedded_idf.dut import IdfDut - - +from pytest_embedded_idf.utils import idf_parametrize # Case 1: BLE power save test -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32c3 -@pytest.mark.esp32s3 -@pytest.mark.esp32c5 -@pytest.mark.esp32c61 -@pytest.mark.esp32 + + @pytest.mark.wifi_two_dut @pytest.mark.parametrize( - 'count, app_path', [ - (2, - f'{os.path.join(os.path.dirname(__file__), "power_save")}|{os.path.join(os.path.dirname(__file__), "blecent")}'), + 'count, app_path', + [ + ( + 2, + f'{os.path.join(os.path.dirname(__file__), "power_save")}|{os.path.join(os.path.dirname(__file__), "blecent")}', + ), ], indirect=True, ) +@idf_parametrize( + 'target', ['esp32c6', 'esp32h2', 'esp32c3', 'esp32s3', 'esp32c5', 'esp32c61', 'esp32'], indirect=['target'] +) def test_power_save_conn(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: peripheral = dut[0] central = dut[1] @@ -39,17 +39,21 @@ def test_power_save_conn(app_path: str, dut: Tuple[IdfDut, IdfDut]) -> None: # Case 2: BLE power save test for ESP32C2 -@pytest.mark.esp32c2 @pytest.mark.wifi_two_dut @pytest.mark.xtal_26mhz @pytest.mark.parametrize( - 'config, count, app_path, baud', [ - ('esp32c2_xtal26m', 2, - f'{os.path.join(os.path.dirname(__file__), "power_save")}|{os.path.join(os.path.dirname(__file__), "blecent")}', - '74880'), + 'config, count, app_path, baud', + [ + ( + 'esp32c2_xtal26m', + 2, + f'{os.path.join(os.path.dirname(__file__), "power_save")}|{os.path.join(os.path.dirname(__file__), "blecent")}', + '74880', + ), ], indirect=True, ) +@idf_parametrize('target', ['esp32c2'], indirect=['target']) def test_power_save_conn_esp32c2_26mhz(dut: Tuple[IdfDut, IdfDut]) -> None: peripheral = dut[0] central = dut[1] diff --git a/examples/build_system/cmake/import_lib/pytest_import_lib.py b/examples/build_system/cmake/import_lib/pytest_import_lib.py index 2bb4845224..95f86b0807 100644 --- a/examples/build_system/cmake/import_lib/pytest_import_lib.py +++ b/examples/build_system/cmake/import_lib/pytest_import_lib.py @@ -1,14 +1,13 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest +from pytest_embedded_idf.utils import idf_parametrize from pytest_embedded_qemu.dut import QemuDut -@pytest.mark.esp32 -@pytest.mark.esp32c3 @pytest.mark.host_test @pytest.mark.qemu +@idf_parametrize('target', ['esp32', 'esp32c3'], indirect=['target']) def test_pytest_host(dut: QemuDut) -> None: dut.expect_exact('Initializing the filesystem') dut.expect_exact('Read XML data:') @@ -16,5 +15,5 @@ def test_pytest_host(dut: QemuDut) -> None: dut.expect_exact('To: Tove') dut.expect_exact('From: Jani') dut.expect_exact('Heading: Reminder') - dut.expect_exact('Body: Don\'t forget me this weekend!') + dut.expect_exact("Body: Don't forget me this weekend!") dut.expect_exact('Example end', timeout=20) diff --git a/examples/build_system/cmake/plugins/pytest_plugins.py b/examples/build_system/cmake/plugins/pytest_plugins.py index ece4ea019d..61fec11187 100644 --- a/examples/build_system/cmake/plugins/pytest_plugins.py +++ b/examples/build_system/cmake/plugins/pytest_plugins.py @@ -1,15 +1,14 @@ -# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import textwrap 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_plugins(dut: Dut) -> None: log_text = textwrap.dedent(r""" Nihao plugin performing self-registration... diff --git a/examples/custom_bootloader/bootloader_extra_dir/pytest_bootloader_extra_dir.py b/examples/custom_bootloader/bootloader_extra_dir/pytest_bootloader_extra_dir.py index 217ce76f8e..274e392cd8 100644 --- a/examples/custom_bootloader/bootloader_extra_dir/pytest_bootloader_extra_dir.py +++ b/examples/custom_bootloader/bootloader_extra_dir/pytest_bootloader_extra_dir.py @@ -1,10 +1,11 @@ -# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2024-2025 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.supported_targets @pytest.mark.generic +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_custom_bootloader_extra_component(dut: Dut) -> None: dut.expect_exact('This function is called from an extra component') diff --git a/examples/custom_bootloader/bootloader_hooks/pytest_custom_bootloader_hooks.py b/examples/custom_bootloader/bootloader_hooks/pytest_custom_bootloader_hooks.py index f96a8502eb..5c32d93293 100644 --- a/examples/custom_bootloader/bootloader_hooks/pytest_custom_bootloader_hooks.py +++ b/examples/custom_bootloader/bootloader_hooks/pytest_custom_bootloader_hooks.py @@ -1,12 +1,12 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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.supported_targets @pytest.mark.generic +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_custom_bootloader_hooks_example(dut: Dut) -> None: # Expect to read both hooks messages dut.expect_exact('This hook is called BEFORE bootloader initialization') diff --git a/examples/custom_bootloader/bootloader_multiboot/pytest_custom_bootloader_multiboot.py b/examples/custom_bootloader/bootloader_multiboot/pytest_custom_bootloader_multiboot.py index f9a9a5cf98..35f013612f 100644 --- a/examples/custom_bootloader/bootloader_multiboot/pytest_custom_bootloader_multiboot.py +++ b/examples/custom_bootloader/bootloader_multiboot/pytest_custom_bootloader_multiboot.py @@ -1,13 +1,13 @@ -# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded import Dut from pytest_embedded_idf.app import IdfApp +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32c3 -@pytest.mark.esp32s3 @pytest.mark.generic +@idf_parametrize('target', ['esp32c3', 'esp32s3'], indirect=['target']) def test_custom_bootloader_multiboot_example(app: IdfApp, dut: Dut) -> None: # Expect to see all three partitions in the list dut.expect_exact('default') diff --git a/examples/custom_bootloader/bootloader_override/pytest_custom_bootloader_override.py b/examples/custom_bootloader/bootloader_override/pytest_custom_bootloader_override.py index 21a07ad0f3..3ed72b3f3a 100644 --- a/examples/custom_bootloader/bootloader_override/pytest_custom_bootloader_override.py +++ b/examples/custom_bootloader/bootloader_override/pytest_custom_bootloader_override.py @@ -1,13 +1,13 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import pytest from pytest_embedded import Dut from pytest_embedded_idf.app import IdfApp +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.supported_targets @pytest.mark.generic +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_custom_bootloader_impl_example(app: IdfApp, dut: Dut) -> None: # Expect to read a message from the custom bootloader # This message is defined in the Kconfig file, retrieve it while deleting diff --git a/examples/cxx/exceptions/pytest_examples_cxx_exceptions.py b/examples/cxx/exceptions/pytest_examples_cxx_exceptions.py index 0aa17b4c57..f62a8ae866 100644 --- a/examples/cxx/exceptions/pytest_examples_cxx_exceptions.py +++ b/examples/cxx/exceptions/pytest_examples_cxx_exceptions.py @@ -1,11 +1,12 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Unlicense OR 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.generic +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_examples_cpp_exceptions(dut: IdfDut) -> None: lines = [ 'app_main starting', diff --git a/examples/cxx/pthread/pytest_examples_cxx_pthread.py b/examples/cxx/pthread/pytest_examples_cxx_pthread.py index 904e273f05..c52438184a 100644 --- a/examples/cxx/pthread/pytest_examples_cxx_pthread.py +++ b/examples/cxx/pthread/pytest_examples_cxx_pthread.py @@ -1,11 +1,12 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Unlicense OR 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.generic +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_examples_cpp_pthread(dut: IdfDut) -> None: dut.expect( [ diff --git a/examples/cxx/rtti/pytest_examples_cxx_rtti.py b/examples/cxx/rtti/pytest_examples_cxx_rtti.py index d92432ae01..e6d81bd99b 100644 --- a/examples/cxx/rtti/pytest_examples_cxx_rtti.py +++ b/examples/cxx/rtti/pytest_examples_cxx_rtti.py @@ -1,11 +1,12 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Unlicense OR 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.generic +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_cpp_rtti_example(dut: IdfDut) -> None: dut.expect_exact('Type name of std::cout is: std::ostream') dut.expect_exact('Type name of std::cin is: std::istream') diff --git a/examples/ethernet/basic/pytest_eth_basic.py b/examples/ethernet/basic/pytest_eth_basic.py index 74c5a2ac63..d9109007ac 100644 --- a/examples/ethernet/basic/pytest_eth_basic.py +++ b/examples/ethernet/basic/pytest_eth_basic.py @@ -1,21 +1,24 @@ -# 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 platform import subprocess import pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32 -@pytest.mark.parametrize('config', [ - pytest.param('default_ip101', marks=[pytest.mark.ethernet_router]), - pytest.param('default_generic', marks=[pytest.mark.ethernet_router]), - pytest.param('default_dm9051', marks=[pytest.mark.eth_dm9051]), -], indirect=True) -def test_esp_eth_basic( - dut: Dut -) -> None: +@pytest.mark.parametrize( + 'config', + [ + pytest.param('default_ip101', marks=[pytest.mark.ethernet_router]), + pytest.param('default_generic', marks=[pytest.mark.ethernet_router]), + pytest.param('default_dm9051', marks=[pytest.mark.eth_dm9051]), + ], + indirect=True, +) +@idf_parametrize('target', ['esp32'], indirect=['target']) +def test_esp_eth_basic(dut: Dut) -> None: # wait for ip received dut_ip = dut.expect(r'esp_netif_handlers: .+ ip: (\d+\.\d+\.\d+\.\d+),').group(1) # ping it once diff --git a/examples/ethernet/iperf/pytest_eth_iperf.py b/examples/ethernet/iperf/pytest_eth_iperf.py index ad80a84ef0..25a4718275 100644 --- a/examples/ethernet/iperf/pytest_eth_iperf.py +++ b/examples/ethernet/iperf/pytest_eth_iperf.py @@ -1,5 +1,7 @@ -# 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 +from pytest_embedded_idf.utils import idf_parametrize + """ Test case for iperf example. @@ -26,11 +28,16 @@ NO_BANDWIDTH_LIMIT = -1 # iperf send bandwidth is not limited class IperfTestUtilityEth(IperfUtility.IperfTestUtility): - """ iperf test implementation """ - def __init__(self, dut: str, config_name: str, pc_nic_ip: str, pc_iperf_log_file: str, test_result:Any=None) -> None: - IperfUtility.IperfTestUtility.__init__(self, dut, config_name, 'None', 'None', pc_nic_ip, pc_iperf_log_file, test_result) + """iperf test implementation""" - def setup(self) -> Tuple[str,int]: + def __init__( + self, dut: str, config_name: str, pc_nic_ip: str, pc_iperf_log_file: str, test_result: Any = None + ) -> None: + IperfUtility.IperfTestUtility.__init__( + self, dut, config_name, 'None', 'None', pc_nic_ip, pc_iperf_log_file, test_result + ) + + def setup(self) -> Tuple[str, int]: """ setup iperf test: @@ -55,7 +62,7 @@ def test_esp_eth_iperf( check_performance: Callable[[str, float, str], None], udp_tx_bw_lim: Optional[int] = NO_BANDWIDTH_LIMIT, udp_rx_bw_lim: Optional[int] = NO_BANDWIDTH_LIMIT, - spi_eth: Optional[bool] = False + spi_eth: Optional[bool] = False, ) -> None: """ steps: | @@ -86,26 +93,36 @@ def test_esp_eth_iperf( # 4. log performance and compare with pass standard for throughput_type in test_result: - log_performance('{}_throughput'.format(throughput_type), - '{:.02f} Mbps'.format(test_result[throughput_type].get_best_throughput())) + log_performance( + '{}_throughput'.format(throughput_type), + '{:.02f} Mbps'.format(test_result[throughput_type].get_best_throughput()), + ) # do check after logging, otherwise test will exit immediately if check fail, some performance can't be logged. for throughput_type in test_result: if spi_eth: - check_performance('{}_eth_throughput_spi_eth'.format(throughput_type), - test_result[throughput_type].get_best_throughput(), - dut.target) + check_performance( + '{}_eth_throughput_spi_eth'.format(throughput_type), + test_result[throughput_type].get_best_throughput(), + dut.target, + ) else: - check_performance('{}_eth_throughput'.format(throughput_type), - test_result[throughput_type].get_best_throughput(), - dut.target) + check_performance( + '{}_eth_throughput'.format(throughput_type), + test_result[throughput_type].get_best_throughput(), + dut.target, + ) -@pytest.mark.esp32 @pytest.mark.ethernet_router -@pytest.mark.parametrize('config', [ - 'default_ip101', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'default_ip101', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_esp_eth_iperf_ip101( dut: Dut, log_performance: Callable[[str, object], None], @@ -114,11 +131,15 @@ def test_esp_eth_iperf_ip101( test_esp_eth_iperf(dut, log_performance, check_performance, udp_tx_bw_lim=90) -@pytest.mark.esp32p4 @pytest.mark.eth_ip101 -@pytest.mark.parametrize('config', [ - 'default_ip101_esp32p4', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'default_ip101_esp32p4', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32p4'], indirect=['target']) def test_esp_eth_iperf_ip101_esp32p4( dut: Dut, log_performance: Callable[[str, object], None], @@ -127,11 +148,15 @@ def test_esp_eth_iperf_ip101_esp32p4( test_esp_eth_iperf(dut, log_performance, check_performance, udp_tx_bw_lim=96) -@pytest.mark.esp32 @pytest.mark.eth_lan8720 -@pytest.mark.parametrize('config', [ - 'default_lan8720', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'default_lan8720', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_esp_eth_iperf_lan8720( dut: Dut, log_performance: Callable[[str, object], None], @@ -140,11 +165,15 @@ def test_esp_eth_iperf_lan8720( test_esp_eth_iperf(dut, log_performance, check_performance, udp_tx_bw_lim=90) -@pytest.mark.esp32 @pytest.mark.eth_rtl8201 -@pytest.mark.parametrize('config', [ - 'default_rtl8201', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'default_rtl8201', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_esp_eth_iperf_rtl8201( dut: Dut, log_performance: Callable[[str, object], None], @@ -153,11 +182,15 @@ def test_esp_eth_iperf_rtl8201( test_esp_eth_iperf(dut, log_performance, check_performance, udp_tx_bw_lim=90) -@pytest.mark.esp32 @pytest.mark.eth_dp83848 -@pytest.mark.parametrize('config', [ - 'default_dp83848', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'default_dp83848', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_esp_eth_iperf_dp83848( dut: Dut, log_performance: Callable[[str, object], None], @@ -166,11 +199,15 @@ def test_esp_eth_iperf_dp83848( test_esp_eth_iperf(dut, log_performance, check_performance, udp_tx_bw_lim=90) -@pytest.mark.esp32 @pytest.mark.eth_ksz8041 -@pytest.mark.parametrize('config', [ - 'default_ksz8041', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'default_ksz8041', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_esp_eth_iperf_ksz8041( dut: Dut, log_performance: Callable[[str, object], None], @@ -179,11 +216,15 @@ def test_esp_eth_iperf_ksz8041( test_esp_eth_iperf(dut, log_performance, check_performance, udp_tx_bw_lim=90) -@pytest.mark.esp32 @pytest.mark.eth_dm9051 -@pytest.mark.parametrize('config', [ - 'default_dm9051', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'default_dm9051', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_esp_eth_iperf_dm9051( dut: Dut, log_performance: Callable[[str, object], None], @@ -192,11 +233,15 @@ def test_esp_eth_iperf_dm9051( test_esp_eth_iperf(dut, log_performance, check_performance, spi_eth=True, udp_rx_bw_lim=10) -@pytest.mark.esp32 @pytest.mark.eth_w5500 -@pytest.mark.parametrize('config', [ - 'default_w5500', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'default_w5500', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_esp_eth_iperf_w5500( dut: Dut, log_performance: Callable[[str, object], None], @@ -205,11 +250,15 @@ def test_esp_eth_iperf_w5500( test_esp_eth_iperf(dut, log_performance, check_performance, spi_eth=True, udp_rx_bw_lim=10) -@pytest.mark.esp32 @pytest.mark.eth_ksz8851snl -@pytest.mark.parametrize('config', [ - 'default_ksz8851snl', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'default_ksz8851snl', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_esp_eth_iperf_ksz8851snl( dut: Dut, log_performance: Callable[[str, object], None], diff --git a/examples/get-started/blink/pytest_blink.py b/examples/get-started/blink/pytest_blink.py index 8df33cfb83..55be95a566 100644 --- a/examples/get-started/blink/pytest_blink.py +++ b/examples/get-started/blink/pytest_blink.py @@ -1,14 +1,15 @@ -# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import logging import os import pytest from pytest_embedded_idf.dut import IdfDut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.supported_targets @pytest.mark.generic +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_blink(dut: IdfDut) -> None: # check and log bin size binary_file = os.path.join(dut.app.binary_path, 'blink.bin') diff --git a/examples/get-started/hello_world/pytest_hello_world.py b/examples/get-started/hello_world/pytest_hello_world.py index 30b63b638c..eb02bd7782 100644 --- a/examples/get-started/hello_world/pytest_hello_world.py +++ b/examples/get-started/hello_world/pytest_hello_world.py @@ -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 hashlib import logging @@ -6,29 +6,27 @@ from typing import Callable import pytest from pytest_embedded_idf.dut import IdfDut +from pytest_embedded_idf.utils import idf_parametrize from pytest_embedded_qemu.app import QemuApp from pytest_embedded_qemu.dut import QemuDut -@pytest.mark.supported_targets -@pytest.mark.preview_targets @pytest.mark.generic -def test_hello_world( - dut: IdfDut, log_minimum_free_heap_size: Callable[..., None] -) -> None: +@idf_parametrize('target', ['supported_targets', 'preview_targets'], indirect=['target']) +def test_hello_world(dut: IdfDut, log_minimum_free_heap_size: Callable[..., None]) -> None: dut.expect('Hello world!') log_minimum_free_heap_size() -@pytest.mark.linux @pytest.mark.host_test +@idf_parametrize('target', ['linux'], indirect=['target']) def test_hello_world_linux(dut: IdfDut) -> None: dut.expect('Hello world!') -@pytest.mark.linux @pytest.mark.host_test @pytest.mark.macos_shell +@idf_parametrize('target', ['linux'], indirect=['target']) def test_hello_world_macos(dut: IdfDut) -> None: dut.expect('Hello world!') @@ -47,14 +45,11 @@ def verify_elf_sha256_embedding(app: QemuApp, sha256_reported: str) -> None: raise ValueError('ELF file SHA256 mismatch') -@pytest.mark.esp32 -@pytest.mark.esp32c3 @pytest.mark.host_test @pytest.mark.qemu +@idf_parametrize('target', ['esp32', 'esp32c3'], indirect=['target']) def test_hello_world_host(app: QemuApp, dut: QemuDut) -> None: - sha256_reported = ( - dut.expect(r'ELF file SHA256:\s+([a-f0-9]+)').group(1).decode('utf-8') - ) + sha256_reported = dut.expect(r'ELF file SHA256:\s+([a-f0-9]+)').group(1).decode('utf-8') verify_elf_sha256_embedding(app, sha256_reported) dut.expect('Hello world!') diff --git a/examples/ieee802154/ieee802154_cli/pytest_test_ieee802154.py b/examples/ieee802154/ieee802154_cli/pytest_test_ieee802154.py index 965780de69..9e9dd4f18f 100644 --- a/examples/ieee802154/ieee802154_cli/pytest_test_ieee802154.py +++ b/examples/ieee802154/ieee802154_cli/pytest_test_ieee802154.py @@ -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: CC0-1.0 - import random import re from time import sleep -from typing import List, Tuple +from typing import List +from typing import Tuple import pexpect import pytest from pytest_embedded_idf.dut import IdfDut +from pytest_embedded_idf.utils import idf_parametrize def generate_shortaddr() -> str: @@ -33,7 +34,7 @@ def generate_extaddr() -> str: return extaddr -def dlt_pendingtable(ser:IdfDut, addr:str) -> None: +def dlt_pendingtable(ser: IdfDut, addr: str) -> None: if addr != '': addr_list = re.findall(r'0x([A-Za-z0-9]{2})', addr) addr_field = '0x' + ''.join(reversed(addr_list)) @@ -52,7 +53,7 @@ def dlt_pendingtable(ser:IdfDut, addr:str) -> None: sleep(0.1) -def add_pendingtable(ser:IdfDut, addr:str='') -> None: +def add_pendingtable(ser: IdfDut, addr: str = '') -> None: if len(addr.split(' ')) == 2 or len(addr.split(' ')) == 8: cmd = 'pending %s\n' % (addr) addr_list = re.findall(r'0x([A-Za-z0-9]{2})', addr) @@ -66,7 +67,7 @@ def add_pendingtable(ser:IdfDut, addr:str='') -> None: sleep(0.1) -def generate_wrong_PANID_addr(right:str) -> str: +def generate_wrong_PANID_addr(right: str) -> str: wrong = '' for i in right.split(' '): num = (int(i, 16) + random.randint(1, 255)) % 256 @@ -75,7 +76,9 @@ def generate_wrong_PANID_addr(right:str) -> str: return wrong -def set_mismatch_short_extern_addr_pendingtable(ser:IdfDut, addr:str, short:int=12, extern:int=12) -> List[List]: +def set_mismatch_short_extern_addr_pendingtable( + ser: IdfDut, addr: str, short: int = 12, extern: int = 12 +) -> List[List]: short_addr = [] extern_addr = [] cnt = 0 @@ -100,7 +103,7 @@ def set_mismatch_short_extern_addr_pendingtable(ser:IdfDut, addr:str, short:int= return [short_addr, extern_addr] -def dlt_short_extern_addr_in_pendingtable(ser:IdfDut, table:List, short:int=5, extern:int=5) -> None: +def dlt_short_extern_addr_in_pendingtable(ser: IdfDut, table: List, short: int = 5, extern: int = 5) -> None: cnt = 0 while cnt < short: dlt_pendingtable(ser, table[0][cnt]) @@ -110,13 +113,15 @@ def dlt_short_extern_addr_in_pendingtable(ser:IdfDut, table:List, short:int=5, e cnt = cnt + 1 -@pytest.mark.esp32c6 @pytest.mark.ieee802154 @pytest.mark.parametrize( - 'count, config', [ + 'count, config', + [ (2, 'release'), - ], indirect=True + ], + indirect=True, ) +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_based_txrx(dut: Tuple[IdfDut, IdfDut]) -> None: transmit = dut[0] receive = dut[1] @@ -147,12 +152,15 @@ def test_based_txrx(dut: Tuple[IdfDut, IdfDut]) -> None: assert 'Rx Done' not in str(tmp) -@pytest.mark.esp32c6 @pytest.mark.ieee802154 @pytest.mark.parametrize( - 'config', ['release',], - indirect=True + 'config', + [ + 'release', + ], + indirect=True, ) +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_based_energy(dut: IdfDut) -> None: transmit = dut transmit.expect('ieee802154>', timeout=10) @@ -161,12 +169,15 @@ def test_based_energy(dut: IdfDut) -> None: transmit.expect('ed_scan_rss_value:', timeout=10) -@pytest.mark.esp32c6 @pytest.mark.ieee802154 @pytest.mark.parametrize( - 'config', ['release',], - indirect=True + 'config', + [ + 'release', + ], + indirect=True, ) +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_based_channel(dut: IdfDut) -> None: transmit = dut transmit.expect('ieee802154>', timeout=10) @@ -176,12 +187,15 @@ def test_based_channel(dut: IdfDut) -> None: transmit.expect('current channel: 23', timeout=10) -@pytest.mark.esp32c6 @pytest.mark.ieee802154 @pytest.mark.parametrize( - 'config', ['release',], - indirect=True + 'config', + [ + 'release', + ], + indirect=True, ) +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_based_txpower(dut: IdfDut) -> None: transmit = dut transmit.expect('ieee802154>', timeout=10) @@ -191,12 +205,15 @@ def test_based_txpower(dut: IdfDut) -> None: transmit.expect('current txpower: 13', timeout=10) -@pytest.mark.esp32c6 @pytest.mark.ieee802154 @pytest.mark.parametrize( - 'config', ['release',], - indirect=True + 'config', + [ + 'release', + ], + indirect=True, ) +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_based_promiscuous(dut: IdfDut) -> None: transmit = dut transmit.expect('ieee802154>', timeout=10) @@ -210,12 +227,15 @@ def test_based_promiscuous(dut: IdfDut) -> None: transmit.expect('hardware promiscuous mode was disabled', timeout=10) -@pytest.mark.esp32c6 @pytest.mark.ieee802154 @pytest.mark.parametrize( - 'config', ['release',], - indirect=True + 'config', + [ + 'release', + ], + indirect=True, ) +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_based_panid(dut: IdfDut) -> None: transmit = dut transmit.expect('ieee802154>', timeout=10) @@ -225,12 +245,15 @@ def test_based_panid(dut: IdfDut) -> None: transmit.expect('current panid: 0x60', timeout=10) -@pytest.mark.esp32c6 @pytest.mark.ieee802154 @pytest.mark.parametrize( - 'config', ['release',], - indirect=True + 'config', + [ + 'release', + ], + indirect=True, ) +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_based_shortaddr(dut: IdfDut) -> None: transmit = dut transmit.expect('ieee802154>', timeout=10) @@ -240,12 +263,15 @@ def test_based_shortaddr(dut: IdfDut) -> None: transmit.expect('current shortaddr: 0x1234', timeout=10) -@pytest.mark.esp32c6 @pytest.mark.ieee802154 @pytest.mark.parametrize( - 'config', ['release',], - indirect=True + 'config', + [ + 'release', + ], + indirect=True, ) +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_based_extaddr(dut: IdfDut) -> None: transmit = dut transmit.expect('ieee802154>', timeout=10) @@ -255,12 +281,15 @@ def test_based_extaddr(dut: IdfDut) -> None: transmit.expect('get extaddr: 0807060504030201', timeout=10) -@pytest.mark.esp32c6 @pytest.mark.ieee802154 @pytest.mark.parametrize( - 'config', ['release',], - indirect=True + 'config', + [ + 'release', + ], + indirect=True, ) +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_based_coordinator(dut: IdfDut) -> None: transmit = dut transmit.expect('ieee802154>', timeout=10) @@ -274,12 +303,15 @@ def test_based_coordinator(dut: IdfDut) -> None: transmit.expect('hardware coordinator was disabled', timeout=10) -@pytest.mark.esp32c6 @pytest.mark.ieee802154 @pytest.mark.parametrize( - 'config', ['release',], - indirect=True + 'config', + [ + 'release', + ], + indirect=True, ) +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_based_pending(dut: IdfDut) -> None: transmit = dut transmit.expect('ieee802154>', timeout=10) @@ -295,12 +327,15 @@ def test_based_pending(dut: IdfDut) -> None: transmit.expect('clear the pending address table', timeout=10) -@pytest.mark.esp32c6 @pytest.mark.ieee802154 @pytest.mark.parametrize( - 'config', ['release',], - indirect=True + 'config', + [ + 'release', + ], + indirect=True, ) +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_based_cca(dut: IdfDut) -> None: transmit = dut transmit.expect('ieee802154>', timeout=10) @@ -312,13 +347,15 @@ def test_based_cca(dut: IdfDut) -> None: transmit.expect('threshold:-60 dB, mode: 0', timeout=10) -@pytest.mark.esp32c6 @pytest.mark.ieee802154 @pytest.mark.parametrize( - 'count, config', [ + 'count, config', + [ (2, 'release'), - ], indirect=True + ], + indirect=True, ) +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_based_autoack(dut: Tuple[IdfDut, IdfDut]) -> None: transmit = dut[0] receive = dut[1] @@ -359,18 +396,20 @@ def test_based_autoack(dut: Tuple[IdfDut, IdfDut]) -> None: transmit.expect('02 00 00', timeout=10) -@pytest.mark.esp32c6 @pytest.mark.ieee802154 @pytest.mark.parametrize( - 'count, config', [ + 'count, config', + [ (2, 'release'), - ], indirect=True + ], + indirect=True, ) +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_based_autopending(dut: Tuple[IdfDut, IdfDut]) -> None: transmit = dut[0] receive = dut[1] -# mode 0: CMD ID = 0x04 --> FP = 1 + # mode 0: CMD ID = 0x04 --> FP = 1 transmit.expect('ieee802154>', timeout=10) transmit.write('rx -r 0') transmit.expect('radio exit receive mode') @@ -397,11 +436,13 @@ def test_based_autopending(dut: Tuple[IdfDut, IdfDut]) -> None: receive.write('rx -r 1') receive.expect('RX Start', timeout=10) - transmit.write('tx 0x23 0x08 0x00 0x74 0x2E 0x49 0x26 0x04 0x53 0x04 0xe3 0x71 0xc2 0x36 0xf7 0xa5 0x2b 0x68 0x79 0x8c 0x72 0x50 0x8b 0x61 0x55 0x56') + transmit.write( + 'tx 0x23 0x08 0x00 0x74 0x2E 0x49 0x26 0x04 0x53 0x04 0xe3 0x71 0xc2 0x36 0xf7 0xa5 0x2b 0x68 0x79 0x8c 0x72 0x50 0x8b 0x61 0x55 0x56' + ) transmit.expect('Rx ack 5 bytes', timeout=10) transmit.expect('12 00 00', timeout=10) -# mode 0: CMD ID != 0x04 --> FP = 0 + # mode 0: CMD ID != 0x04 --> FP = 0 receive.write('pending -r') receive.expect('clear the pending address table', timeout=10) receive.write('promisc -d') @@ -426,7 +467,7 @@ def test_based_autopending(dut: Tuple[IdfDut, IdfDut]) -> None: transmit.expect('Rx ack 5 bytes', timeout=10) transmit.expect('02 00 0c', timeout=10) -# mode 1: CMD ID = 0x04, src addr in pending table --> FP = 1 + # mode 1: CMD ID = 0x04, src addr in pending table --> FP = 1 receive.write('pending -r') receive.expect('clear the pending address table', timeout=10) receive.write('promisc -d') @@ -459,7 +500,7 @@ def test_based_autopending(dut: Tuple[IdfDut, IdfDut]) -> None: transmit.expect('Rx ack 5 bytes', timeout=10) transmit.expect('12 00 00', timeout=10) -# mode 1: CMD ID = 0x04, src addr not in pending table --> FP = 0 + # mode 1: CMD ID = 0x04, src addr not in pending table --> FP = 0 receive.write('pending -r') receive.expect('clear the pending address table', timeout=10) receive.write('promisc -d') @@ -487,11 +528,13 @@ def test_based_autopending(dut: Tuple[IdfDut, IdfDut]) -> None: receive.write('rx -r 1') receive.expect('RX Start', timeout=10) - transmit.write('tx 0x2b 0x88 0x08 0xE3 0x9F 0x20 0x9E 0x18 0xE7 0x66 0xC4 0x17 0x92 0x8a 0xcd 0x4c 0xd0 0x20 0x40 0x0d 0x46 0x04 0xa0 0xe3 0x9c 0x57') + transmit.write( + 'tx 0x2b 0x88 0x08 0xE3 0x9F 0x20 0x9E 0x18 0xE7 0x66 0xC4 0x17 0x92 0x8a 0xcd 0x4c 0xd0 0x20 0x40 0x0d 0x46 0x04 0xa0 0xe3 0x9c 0x57' + ) transmit.expect('Rx ack 5 bytes', timeout=10) transmit.expect('02 00 08', timeout=10) -# mode 2: frame type is data, src addr in pending table --> FP = 1 + # mode 2: frame type is data, src addr in pending table --> FP = 1 receive.write('pending -r') receive.expect('clear the pending address table', timeout=10) receive.write('promisc -d') @@ -524,7 +567,7 @@ def test_based_autopending(dut: Tuple[IdfDut, IdfDut]) -> None: transmit.expect('Rx ack 5 bytes', timeout=10) transmit.expect('12 00 10', timeout=10) -# mode 2: frame type is data, src addr not in pending table --> FP = 0 + # mode 2: frame type is data, src addr not in pending table --> FP = 0 receive.write('pending -r') receive.expect('clear the pending address table', timeout=10) receive.write('promisc -d') @@ -557,12 +600,15 @@ def test_based_autopending(dut: Tuple[IdfDut, IdfDut]) -> None: transmit.expect('02 00 10', timeout=10) -@pytest.mark.esp32c6 @pytest.mark.ieee802154 @pytest.mark.parametrize( - 'config', ['release',], - indirect=True + 'config', + [ + 'release', + ], + indirect=True, ) +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_based_transmit_failed(dut: IdfDut) -> None: transmit = dut transmit.expect('ieee802154>', timeout=10) @@ -579,12 +625,15 @@ def test_based_transmit_failed(dut: IdfDut) -> None: transmit.expect('08 09 00 00 00 00 00 00', timeout=10) -@pytest.mark.esp32c6 @pytest.mark.ieee802154 @pytest.mark.parametrize( - 'config', ['release',], - indirect=True + 'config', + [ + 'release', + ], + indirect=True, ) +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_based_initialize(dut: IdfDut) -> None: transmit = dut transmit.expect('ieee802154>', timeout=10) diff --git a/examples/network/bridge/pytest_example_bridge.py b/examples/network/bridge/pytest_example_bridge.py index 419cce09ab..007f4c2d2b 100644 --- a/examples/network/bridge/pytest_example_bridge.py +++ b/examples/network/bridge/pytest_example_bridge.py @@ -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 ipaddress import logging @@ -17,8 +17,9 @@ import pytest from common_test_methods import get_host_ip_by_interface from netmiko import ConnectHandler from pytest_embedded import Dut - +from pytest_embedded_idf.utils import idf_parametrize # Testbed configuration + BR_PORTS_NUM = 2 IPERF_BW_LIM = 6 MIN_UDP_THROUGHPUT = 5 @@ -30,9 +31,7 @@ class EndnodeSsh: self.host_ip = host_ip self.ssh_client = paramiko.SSHClient() self.ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) - self.ssh_client.connect(hostname=self.host_ip, - username=usr, - password=passwd) + self.ssh_client.connect(hostname=self.host_ip, username=usr, password=passwd) self.executor: ThreadPoolExecutor self.async_result: Future @@ -69,9 +68,7 @@ class SwitchSsh: if self.type == self.EDGE_SWITCH_5XP: self.ssh_client = paramiko.SSHClient() self.ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) - self.ssh_client.connect(hostname=self.host_ip, - username=usr, - password=passwd) + self.ssh_client.connect(hostname=self.host_ip, username=usr, password=passwd) else: edgeSwitch = { 'device_type': 'ubiquiti_edgeswitch', @@ -119,7 +116,10 @@ class SwitchSsh: def get_endnode_mac_by_interface(endnode: EndnodeSsh, if_name: str) -> str: ip_info = endnode.exec_cmd(f'ip addr show {if_name}') - regex = if_name + r':.*?link/ether ([0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2})' + regex = ( + if_name + + r':.*?link/ether ([0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2})' + ) mac_addr = re.search(regex, ip_info, re.DOTALL) if mac_addr is None: return '' @@ -160,7 +160,15 @@ def get_host_brcast_ip_by_interface(interface_name: str, ip_type: int = netiface return '' -def run_iperf(proto: str, endnode: EndnodeSsh, server_ip: str, bandwidth_lim:int=10, interval:int=5, server_if:str='', client_if:str='') -> float: +def run_iperf( + proto: str, + endnode: EndnodeSsh, + server_ip: str, + bandwidth_lim: int = 10, + interval: int = 5, + server_if: str = '', + client_if: str = '', +) -> float: if proto == 'tcp': proto = '' else: @@ -168,19 +176,29 @@ def run_iperf(proto: str, endnode: EndnodeSsh, server_ip: str, bandwidth_lim:int if ipaddress.ip_address(server_ip).is_multicast: # Configure Multicast Server - server_proc = subprocess.Popen(['iperf', '-u', '-s', '-i', '1', '-t', '%i' % interval, '-B', '%s%%%s' - % (server_ip, server_if)], text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + server_proc = subprocess.Popen( + ['iperf', '-u', '-s', '-i', '1', '-t', '%i' % interval, '-B', '%s%%%s' % (server_ip, server_if)], + text=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) # Configure Multicast Client endnode_ip = get_endnode_ip_by_interface(endnode, client_if) if endnode_ip == '': raise RuntimeError('End node IP address not found') - client_res = endnode.exec_cmd('iperf -u -c %s -t %i -i 1 -b %iM --ttl 5 -B %s' % (server_ip, interval, bandwidth_lim, endnode_ip)) + client_res = endnode.exec_cmd( + 'iperf -u -c %s -t %i -i 1 -b %iM --ttl 5 -B %s' % (server_ip, interval, bandwidth_lim, endnode_ip) + ) if server_proc.wait(10) is None: # Process did not finish. server_proc.terminate() else: # Configure Server - server_proc = subprocess.Popen(['iperf', '%s' % proto, '-s', '-i', '1', '-t', '%i' % interval], text=True, - stdout=subprocess.PIPE, stderr=subprocess.PIPE) + server_proc = subprocess.Popen( + ['iperf', '%s' % proto, '-s', '-i', '1', '-t', '%i' % interval], + text=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) # Configure Client client_res = endnode.exec_cmd('iperf %s -c %s -t %i -i 1 -b %iM' % (proto, server_ip, interval, bandwidth_lim)) if server_proc.wait(10) is None: # Process did not finish. @@ -239,16 +257,16 @@ def send_brcast_msg_endnode_to_host(endnode: EndnodeSsh, host_brcast_ip: str, te return nc_host_out -@pytest.mark.esp32 @pytest.mark.eth_w5500 -@pytest.mark.parametrize('config', [ - 'w5500', -], indirect=True) -def test_esp_eth_bridge( - dut: Dut, - dev_user: str, - dev_password: str -) -> None: +@pytest.mark.parametrize( + 'config', + [ + 'w5500', + ], + indirect=True, +) +@idf_parametrize('target', ['esp32'], indirect=['target']) +def test_esp_eth_bridge(dut: Dut, dev_user: str, dev_password: str) -> None: # ------------------------------ # # Pre-test testbed configuration # # ------------------------------ # @@ -263,18 +281,15 @@ def test_esp_eth_bridge( port_num = int(sw_info.group(2)) port_num_endnode = int(port_num) + 1 # endnode address is always + 1 to the host - endnode = EndnodeSsh(f'10.10.{sw_num}.{port_num_endnode}', - dev_user, - dev_password) - switch1 = SwitchSsh(f'10.10.{sw_num}.100', - dev_user, - dev_password, - SwitchSsh.EDGE_SWITCH_10XP) + endnode = EndnodeSsh(f'10.10.{sw_num}.{port_num_endnode}', dev_user, dev_password) + switch1 = SwitchSsh(f'10.10.{sw_num}.100', dev_user, dev_password, SwitchSsh.EDGE_SWITCH_10XP) # Collect all addresses in our network # ------------------------------------ # Bridge (DUT) MAC - br_mac = dut.expect(r'esp_netif_br_glue: ([0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2})') + br_mac = dut.expect( + r'esp_netif_br_glue: ([0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2})' + ) br_mac = br_mac.group(1).decode('utf-8') logging.info('ESP Bridge MAC %s', br_mac) # Get unique identification of each Ethernet port @@ -350,7 +365,9 @@ def test_esp_eth_bridge( logging.info('link up the port #2') switch1.switch_port_up(port_num_endnode) - dut.expect_exact(f'Ethernet ({p2_id}) Link Up') # Note: No "Ethernet Got IP Address" since DHCP Server is connected to port #1 + dut.expect_exact( + f'Ethernet ({p2_id}) Link Up' + ) # Note: No "Ethernet Got IP Address" since DHCP Server is connected to port #1 logging.info('link down both ports') switch1.switch_port_down(port_num_endnode) @@ -369,30 +386,43 @@ def test_esp_eth_bridge( # unicast UDP bandwidth_udp = run_iperf('udp', endnode, host_ip, IPERF_BW_LIM, 5) if bandwidth_udp < MIN_UDP_THROUGHPUT: - logging.warning('Unicast UDP bandwidth was less than expected. Trying again over longer period to compensate transient drops.') + logging.warning( + 'Unicast UDP bandwidth was less than expected. Trying again over longer period to compensate transient drops.' + ) bandwidth_udp = run_iperf('udp', endnode, host_ip, IPERF_BW_LIM, 60) logging.info('Unicast UDP average bandwidth: %s Mbits/s', bandwidth_udp) # unicast TCP bandwidth_tcp = run_iperf('tcp', endnode, host_ip, IPERF_BW_LIM, 5) if bandwidth_tcp < MIN_TCP_THROUGHPUT: - logging.warning('Unicast TCP bandwidth was less than expected. Trying again over longer period to compensate transient drops.') + logging.warning( + 'Unicast TCP bandwidth was less than expected. Trying again over longer period to compensate transient drops.' + ) bandwidth_tcp = run_iperf('tcp', endnode, host_ip, IPERF_BW_LIM, 60) logging.info('Unicast TCP average bandwidth: %s Mbits/s', bandwidth_tcp) # multicast UDP bandwidth_mcast_udp = run_iperf('udp', endnode, '224.0.1.4', IPERF_BW_LIM, 5, host_if, endnode_if) if bandwidth_mcast_udp < MIN_UDP_THROUGHPUT: - logging.warning('Multicast UDP bandwidth was less than expected. Trying again over longer period to compensate transient drops.') + logging.warning( + 'Multicast UDP bandwidth was less than expected. Trying again over longer period to compensate transient drops.' + ) bandwidth_mcast_udp = run_iperf('udp', endnode, '224.0.1.4', IPERF_BW_LIM, 60, host_if, endnode_if) logging.info('Multicast UDP average bandwidth: %s Mbits/s', bandwidth_mcast_udp) if bandwidth_udp < MIN_UDP_THROUGHPUT: - raise RuntimeError('Unicast UDP throughput expected %.2f, actual %.2f' % (MIN_UDP_THROUGHPUT, bandwidth_udp) + ' Mbits/s') + raise RuntimeError( + 'Unicast UDP throughput expected %.2f, actual %.2f' % (MIN_UDP_THROUGHPUT, bandwidth_udp) + ' Mbits/s' + ) if bandwidth_tcp < MIN_TCP_THROUGHPUT: - raise RuntimeError('Unicast TCP throughput expected %.2f, actual %.2f' % (MIN_TCP_THROUGHPUT, bandwidth_tcp) + ' Mbits/s') + raise RuntimeError( + 'Unicast TCP throughput expected %.2f, actual %.2f' % (MIN_TCP_THROUGHPUT, bandwidth_tcp) + ' Mbits/s' + ) if bandwidth_mcast_udp < MIN_UDP_THROUGHPUT: - raise RuntimeError('Multicast UDP throughput expected %.2f, actual %.2f' % (MIN_UDP_THROUGHPUT, bandwidth_mcast_udp) + ' Mbits/s') + raise RuntimeError( + 'Multicast UDP throughput expected %.2f, actual %.2f' % (MIN_UDP_THROUGHPUT, bandwidth_mcast_udp) + + ' Mbits/s' + ) # ------------------------------------------------ # TEST Objective 4: adding/deleting entries in FDB diff --git a/examples/network/simple_sniffer/pytest_simple_sniffer.py b/examples/network/simple_sniffer/pytest_simple_sniffer.py index ec4808c5e4..12ad33fe06 100644 --- a/examples/network/simple_sniffer/pytest_simple_sniffer.py +++ b/examples/network/simple_sniffer/pytest_simple_sniffer.py @@ -3,6 +3,7 @@ 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 _sniffer_packets_check(dut: Dut, channel: int, packet_num: int) -> None: @@ -36,18 +37,19 @@ def _sniffer_packets_check(dut: Dut, channel: int, packet_num: int) -> None: dut.expect('cmd_pcap: .pcap file close done') -@pytest.mark.esp32 -@pytest.mark.esp32c2 -@pytest.mark.esp32c3 -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32c61 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 @pytest.mark.wifi_ap -@pytest.mark.parametrize('config', [ - 'mem', -], indirect=True) +@pytest.mark.parametrize( + 'config', + [ + 'mem', + ], + indirect=True, +) +@idf_parametrize( + 'target', + ['esp32', 'esp32c2', 'esp32c3', 'esp32c5', 'esp32c6', 'esp32c61', 'esp32s2', 'esp32s3'], + indirect=['target'], +) def test_examples_simple_sniffer(dut: Dut) -> None: dut.expect('sniffer>') channel = get_env_config_variable('wifi_ap', 'sniffer_channel', default=1) diff --git a/examples/network/vlan_support/pytest_vlan_napt.py b/examples/network/vlan_support/pytest_vlan_napt.py index 21a29b9b8b..c646e5b370 100644 --- a/examples/network/vlan_support/pytest_vlan_napt.py +++ b/examples/network/vlan_support/pytest_vlan_napt.py @@ -1,22 +1,27 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import ipaddress import subprocess import threading import time -from typing import Dict, Union +from typing import Dict +from typing import Union import pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize from scapy import layers -from scapy.all import ICMP, IP, TCP, UDP, AsyncSniffer +from scapy.all import AsyncSniffer +from scapy.all import ICMP +from scapy.all import IP +from scapy.all import TCP +from scapy.all import UDP udp_port = 1234 tcp_port = 4321 -def run_cmd(command: str, secure: bool=False) -> str: +def run_cmd(command: str, secure: bool = False) -> str: if secure is False: print(f'Running: {command}') @@ -73,12 +78,16 @@ def setup_network(config: dict) -> None: def create_config(dut: Dut) -> dict: pc_iface = dut.app.sdkconfig.get('EXAMPLE_VLAN_PYTEST_PC_IFACE') - vlanClient_conf = {'id': str(dut.app.sdkconfig.get('EXAMPLE_ETHERNET_VLAN_ID')), - 'name': 'vlanClient', - 'ip': dut.app.sdkconfig.get('EXAMPLE_VLAN_STATIC_ADDR_DEF_GW')} - vlanServer_conf = {'id': str(dut.app.sdkconfig.get('EXAMPLE_EXTRA_ETHERNET_VLAN_ID')), - 'name': 'vlanServer', - 'ip': dut.app.sdkconfig.get('EXAMPLE_EXTRA_VLAN_STATIC_ADDR_DEF_GW')} + vlanClient_conf = { + 'id': str(dut.app.sdkconfig.get('EXAMPLE_ETHERNET_VLAN_ID')), + 'name': 'vlanClient', + 'ip': dut.app.sdkconfig.get('EXAMPLE_VLAN_STATIC_ADDR_DEF_GW'), + } + vlanServer_conf = { + 'id': str(dut.app.sdkconfig.get('EXAMPLE_EXTRA_ETHERNET_VLAN_ID')), + 'name': 'vlanServer', + 'ip': dut.app.sdkconfig.get('EXAMPLE_EXTRA_VLAN_STATIC_ADDR_DEF_GW'), + } esp_vlanClient_ip = dut.app.sdkconfig.get('EXAMPLE_VLAN_STATIC_IPV4_ADDR') esp_vlanServer_ip = dut.app.sdkconfig.get('EXAMPLE_EXTRA_VLAN_STATIC_IPV4_ADDR') @@ -89,31 +98,33 @@ def create_config(dut: Dut) -> dict: config: Dict[str, Union[str, dict, dict, str, str, list, list, list, list]] = { # Basic Configurations 'pc_iface': pc_iface, - 'vlanClient': vlanClient_conf, 'vlanServer': vlanServer_conf, - 'esp_vlanClient_ip': esp_vlanClient_ip, 'esp_vlanServer_ip': esp_vlanServer_ip, - - 'vlan_create_cmd_l': [f'ip netns add ns_vlanClient', - f"ip link add link {pc_iface} name {vlanClient_conf['name']} type vlan id {vlanClient_conf['id']}", - f"ip link set {vlanClient_conf['name']} netns ns_vlanClient", - f"ip netns exec ns_vlanClient ip addr add {vlanClient_conf['ip']}/255.255.255.0 dev {vlanClient_conf['name']}", - f"ip netns exec ns_vlanClient ip link set dev {vlanClient_conf['name']} up", - f"ip link add link {pc_iface} name {vlanServer_conf['name']} type vlan id {vlanServer_conf['id']}", - f"ip addr add {vlanServer_conf['ip']}/255.255.255.0 dev {vlanServer_conf['name']}", - f"ip link set dev {vlanServer_conf['name']} up"], - - 'vlan_destroy_cmd_l': [f"ip netns exec ns_vlanClient ip link set dev {vlanClient_conf['name']} down", - f"ip netns exec ns_vlanClient ip link delete {vlanClient_conf['name']}", - f"ip link set dev {vlanServer_conf['name']} down", - f"ip link delete {vlanServer_conf['name']}", - f'ip netns delete ns_vlanClient'], - - 'set_route_cmd_l': [f'ip netns exec ns_vlanClient ip route add {vlanServer_net_addr}/24 via {esp_vlanClient_ip}'], - - 'delete_route_cmd_l': [f'ip netns exec ns_vlanClient ip route delete {vlanServer_net_addr}/24 via {esp_vlanClient_ip}'], + 'vlan_create_cmd_l': [ + f'ip netns add ns_vlanClient', + f'ip link add link {pc_iface} name {vlanClient_conf["name"]} type vlan id {vlanClient_conf["id"]}', + f'ip link set {vlanClient_conf["name"]} netns ns_vlanClient', + f'ip netns exec ns_vlanClient ip addr add {vlanClient_conf["ip"]}/255.255.255.0 dev {vlanClient_conf["name"]}', + f'ip netns exec ns_vlanClient ip link set dev {vlanClient_conf["name"]} up', + f'ip link add link {pc_iface} name {vlanServer_conf["name"]} type vlan id {vlanServer_conf["id"]}', + f'ip addr add {vlanServer_conf["ip"]}/255.255.255.0 dev {vlanServer_conf["name"]}', + f'ip link set dev {vlanServer_conf["name"]} up', + ], + 'vlan_destroy_cmd_l': [ + f'ip netns exec ns_vlanClient ip link set dev {vlanClient_conf["name"]} down', + f'ip netns exec ns_vlanClient ip link delete {vlanClient_conf["name"]}', + f'ip link set dev {vlanServer_conf["name"]} down', + f'ip link delete {vlanServer_conf["name"]}', + f'ip netns delete ns_vlanClient', + ], + 'set_route_cmd_l': [ + f'ip netns exec ns_vlanClient ip route add {vlanServer_net_addr}/24 via {esp_vlanClient_ip}' + ], + 'delete_route_cmd_l': [ + f'ip netns exec ns_vlanClient ip route delete {vlanServer_net_addr}/24 via {esp_vlanClient_ip}' + ], } return config @@ -121,7 +132,6 @@ def create_config(dut: Dut) -> dict: # Ping Test def ping_test(config: dict) -> None: - setup_network(config) capture = AsyncSniffer(iface=config['vlanServer']['name'], filter='icmp', count=10) @@ -131,7 +141,11 @@ def ping_test(config: dict) -> None: time.sleep(1) # Run network test commands here - print(run_cmd_sec(f"ip netns exec ns_vlanClient ping -I {config['vlanClient']['ip']} {config['vlanServer']['ip']} -c 10")) + print( + run_cmd_sec( + f'ip netns exec ns_vlanClient ping -I {config["vlanClient"]["ip"]} {config["vlanServer"]["ip"]} -c 10' + ) + ) # Stop sniffing capture.join(timeout=20) @@ -147,12 +161,20 @@ def ping_test(config: dict) -> None: print('Failure: No packets captured') assert False - print(f"Captured: {len(vlanServer_pkt_list)} packets on interface {config['vlanServer']['name']}") + print(f'Captured: {len(vlanServer_pkt_list)} packets on interface {config["vlanServer"]["name"]}') for pkt in vlanServer_pkt_list: print('Summary: ', pkt.summary()) - if pkt[ICMP].type == 8 and pkt[IP].src == config['esp_vlanServer_ip'] and pkt[IP].dst == config['vlanServer']['ip']: + if ( + pkt[ICMP].type == 8 + and pkt[IP].src == config['esp_vlanServer_ip'] + and pkt[IP].dst == config['vlanServer']['ip'] + ): vlanServer_forward_flag = True - if pkt[ICMP].type == 0 and pkt[IP].src == config['vlanServer']['ip'] and pkt[IP].dst == config['esp_vlanServer_ip']: + if ( + pkt[ICMP].type == 0 + and pkt[IP].src == config['vlanServer']['ip'] + and pkt[IP].dst == config['esp_vlanServer_ip'] + ): vlanServer_return_flag = True assert vlanServer_forward_flag and vlanServer_return_flag @@ -170,7 +192,13 @@ def udp_client(serverip: str, port: int) -> None: def udp_server_client_comm(config: dict, port: int) -> None: - server_thread = threading.Thread(target=udp_server, args=(config['vlanServer']['ip'], port,)) + server_thread = threading.Thread( + target=udp_server, + args=( + config['vlanServer']['ip'], + port, + ), + ) client_thread = threading.Thread(target=udp_client, args=(config['vlanServer']['ip'], port)) server_thread.start() @@ -186,13 +214,9 @@ def udp_lfilter(packet: layers.l2.Ether) -> layers.l2.Ether: def udp_test(config: dict) -> None: - setup_network(config) - capture = AsyncSniffer(iface=config['vlanServer']['name'], - filter='udp', - lfilter=udp_lfilter, - count=10) + capture = AsyncSniffer(iface=config['vlanServer']['name'], filter='udp', lfilter=udp_lfilter, count=10) # Start sniffing capture.start() @@ -216,13 +240,21 @@ def udp_test(config: dict) -> None: print('Failure: No packets captured') assert False - print(f"Captured: {len(vlanServer_pkt_list)} packets on interface {config['vlanServer']['name']}") + print(f'Captured: {len(vlanServer_pkt_list)} packets on interface {config["vlanServer"]["name"]}') for pkt in vlanServer_pkt_list: print('Summary: ', pkt.summary()) if UDP in pkt: - if pkt[UDP].dport == udp_port and pkt[IP].src == config['esp_vlanServer_ip'] and pkt[IP].dst == config['vlanServer']['ip']: + if ( + pkt[UDP].dport == udp_port + and pkt[IP].src == config['esp_vlanServer_ip'] + and pkt[IP].dst == config['vlanServer']['ip'] + ): vlanServer_forward_flag = True - if pkt[UDP].sport == udp_port and pkt[IP].src == config['vlanServer']['ip'] and pkt[IP].dst == config['esp_vlanServer_ip']: + if ( + pkt[UDP].sport == udp_port + and pkt[IP].src == config['vlanServer']['ip'] + and pkt[IP].dst == config['esp_vlanServer_ip'] + ): vlanServer_return_flag = True assert vlanServer_forward_flag and vlanServer_return_flag @@ -240,7 +272,13 @@ def tcp_client(serverip: str, port: int) -> None: def tcp_server_client_comm(config: dict, port: int) -> None: - server_thread = threading.Thread(target=tcp_server, args=(config['vlanServer']['ip'], port,)) + server_thread = threading.Thread( + target=tcp_server, + args=( + config['vlanServer']['ip'], + port, + ), + ) client_thread = threading.Thread(target=tcp_client, args=(config['vlanServer']['ip'], port)) server_thread.start() @@ -256,13 +294,9 @@ def tcp_lfilter(packet: layers.l2.Ether) -> layers.l2.Ether: def tcp_test(config: dict) -> None: - setup_network(config) - capture = AsyncSniffer(iface=config['vlanServer']['name'], - filter='tcp', - lfilter=tcp_lfilter, - count=10) + capture = AsyncSniffer(iface=config['vlanServer']['name'], filter='tcp', lfilter=tcp_lfilter, count=10) # Start sniffing capture.start() @@ -286,36 +320,44 @@ def tcp_test(config: dict) -> None: print('Failure: No packets captured') assert False - print(f"Captured: {len(vlanServer_pkt_list)} packets on interface {config['vlanServer']['name']}") + print(f'Captured: {len(vlanServer_pkt_list)} packets on interface {config["vlanServer"]["name"]}') for pkt in vlanServer_pkt_list: print('Summary: ', pkt.summary()) if TCP in pkt: - if pkt[TCP].dport == tcp_port and pkt[IP].src == config['esp_vlanServer_ip'] and pkt[IP].dst == config['vlanServer']['ip']: + if ( + pkt[TCP].dport == tcp_port + and pkt[IP].src == config['esp_vlanServer_ip'] + and pkt[IP].dst == config['vlanServer']['ip'] + ): vlanServer_forward_flag = True - if pkt[TCP].sport == tcp_port and pkt[IP].src == config['vlanServer']['ip'] and pkt[IP].dst == config['esp_vlanServer_ip']: + if ( + pkt[TCP].sport == tcp_port + and pkt[IP].src == config['vlanServer']['ip'] + and pkt[IP].dst == config['esp_vlanServer_ip'] + ): vlanServer_return_flag = True assert vlanServer_forward_flag and vlanServer_return_flag -@pytest.mark.esp32 @pytest.mark.ethernet_vlan +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_vlan_napt_pingtest(dut: Dut) -> None: dut.expect('main_task: Returned from app_main()') test_conf = create_config(dut) ping_test(test_conf) -@pytest.mark.esp32 @pytest.mark.ethernet_vlan +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_vlan_napt_udptest(dut: Dut) -> None: dut.expect('main_task: Returned from app_main()') test_conf = create_config(dut) udp_test(test_conf) -@pytest.mark.esp32 @pytest.mark.ethernet_vlan +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_vlan_napt_tcptest(dut: Dut) -> None: dut.expect('main_task: Returned from app_main()') test_conf = create_config(dut) diff --git a/examples/openthread/pytest_otbr.py b/examples/openthread/pytest_otbr.py index 9c0e8cf017..45c1b31fd7 100644 --- a/examples/openthread/pytest_otbr.py +++ b/examples/openthread/pytest_otbr.py @@ -91,15 +91,10 @@ ESPPORT1 = os.getenv('ESPPORT1') ESPPORT2 = os.getenv('ESPPORT2') ESPPORT3 = os.getenv('ESPPORT3') -PORT_MAPPING = { - 'ESPPORT1': 'esp32h2', - 'ESPPORT2': 'esp32s3', - 'ESPPORT3': 'esp32c6' -} +PORT_MAPPING = {'ESPPORT1': 'esp32h2', 'ESPPORT2': 'esp32s3', 'ESPPORT3': 'esp32c6'} # Case 1: Thread network formation and attaching -@pytest.mark.supported_targets @pytest.mark.openthread_br @pytest.mark.flaky(reruns=1, reruns_delay=1) @pytest.mark.parametrize( @@ -113,7 +108,7 @@ PORT_MAPPING = { f'|{os.path.join(os.path.dirname(__file__), "ot_br")}', 'esp32c6|esp32h2|esp32s3', f'{ESPPORT3}|{ESPPORT1}|{ESPPORT2}', - id='c6-h2-s3' + id='c6-h2-s3', ), pytest.param( 'rcp_spi|cli|br_spi', @@ -123,12 +118,12 @@ PORT_MAPPING = { f'|{os.path.join(os.path.dirname(__file__), "ot_br")}', 'esp32h2|esp32c6|esp32s3', f'{ESPPORT1}|{ESPPORT3}|{ESPPORT2}', - id='h2-c6-s3' + id='h2-c6-s3', ), ], indirect=True, ) -def test_thread_connect(dut:Tuple[IdfDut, IdfDut, IdfDut]) -> None: +def test_thread_connect(dut: Tuple[IdfDut, IdfDut, IdfDut]) -> None: br = dut[2] cli_h2 = dut[1] dut[0].serial.stop_redirect_thread() @@ -168,7 +163,7 @@ def test_thread_connect(dut:Tuple[IdfDut, IdfDut, IdfDut]) -> None: # / \ # / \ # Wi-FI_Host Thread_End_Device -def formBasicWiFiThreadNetwork(br:IdfDut, cli:IdfDut) -> None: +def formBasicWiFiThreadNetwork(br: IdfDut, cli: IdfDut) -> None: ocf.init_thread(br) ocf.init_thread(cli) otbr_wifi_para = copy.copy(default_br_wifi_para) @@ -179,11 +174,10 @@ def formBasicWiFiThreadNetwork(br:IdfDut, cli:IdfDut) -> None: otcli_thread_para.dataset = ocf.getDataset(br) otcli_thread_para.exaddr = '7766554433221101' ocf.joinThreadNetwork(cli, otcli_thread_para) - ocf.wait(cli,10) + ocf.wait(cli, 10) # Case 2: Bidirectional IPv6 connectivity -@pytest.mark.supported_targets @pytest.mark.openthread_br @pytest.mark.flaky(reruns=1, reruns_delay=1) @pytest.mark.parametrize( @@ -197,14 +191,14 @@ def formBasicWiFiThreadNetwork(br:IdfDut, cli:IdfDut) -> None: f'|{os.path.join(os.path.dirname(__file__), "ot_br")}', 'esp32c6|esp32h2|esp32s3', f'{ESPPORT3}|{ESPPORT1}|{ESPPORT2}', - id='c6-h2-s3' + id='c6-h2-s3', ), ], indirect=True, ) -def test_Bidirectional_IPv6_connectivity(Init_interface:bool, dut: Tuple[IdfDut, IdfDut, IdfDut]) -> None: +def test_Bidirectional_IPv6_connectivity(Init_interface: bool, dut: Tuple[IdfDut, IdfDut, IdfDut]) -> None: br = dut[2] - cli = dut[1] + cli = dut[1] assert Init_interface dut[0].serial.stop_redirect_thread() @@ -236,7 +230,6 @@ def test_Bidirectional_IPv6_connectivity(Init_interface:bool, dut: Tuple[IdfDut, # Case 3: Multicast forwarding from Wi-Fi to Thread network -@pytest.mark.supported_targets @pytest.mark.openthread_br @pytest.mark.flaky(reruns=1, reruns_delay=1) @pytest.mark.parametrize( @@ -250,14 +243,14 @@ def test_Bidirectional_IPv6_connectivity(Init_interface:bool, dut: Tuple[IdfDut, f'|{os.path.join(os.path.dirname(__file__), "ot_br")}', 'esp32c6|esp32h2|esp32s3', f'{ESPPORT3}|{ESPPORT1}|{ESPPORT2}', - id='c6-h2-s3' + id='c6-h2-s3', ), ], indirect=True, ) -def test_multicast_forwarding_A(Init_interface:bool, dut: Tuple[IdfDut, IdfDut, IdfDut]) -> None: +def test_multicast_forwarding_A(Init_interface: bool, dut: Tuple[IdfDut, IdfDut, IdfDut]) -> None: br = dut[2] - cli = dut[1] + cli = dut[1] assert Init_interface dut[0].serial.stop_redirect_thread() @@ -290,7 +283,6 @@ def test_multicast_forwarding_A(Init_interface:bool, dut: Tuple[IdfDut, IdfDut, # Case 4: Multicast forwarding from Thread to Wi-Fi network -@pytest.mark.supported_targets @pytest.mark.openthread_br @pytest.mark.flaky(reruns=1, reruns_delay=1) @pytest.mark.parametrize( @@ -304,14 +296,14 @@ def test_multicast_forwarding_A(Init_interface:bool, dut: Tuple[IdfDut, IdfDut, f'|{os.path.join(os.path.dirname(__file__), "ot_br")}', 'esp32c6|esp32h2|esp32s3', f'{ESPPORT3}|{ESPPORT1}|{ESPPORT2}', - id='c6-h2-s3' + id='c6-h2-s3', ), ], indirect=True, ) -def test_multicast_forwarding_B(Init_interface:bool, dut: Tuple[IdfDut, IdfDut, IdfDut]) -> None: +def test_multicast_forwarding_B(Init_interface: bool, dut: Tuple[IdfDut, IdfDut, IdfDut]) -> None: br = dut[2] - cli = dut[1] + cli = dut[1] assert Init_interface dut[0].serial.stop_redirect_thread() @@ -324,7 +316,7 @@ def test_multicast_forwarding_B(Init_interface:bool, dut: Tuple[IdfDut, IdfDut, cli.expect('Done', timeout=5) ocf.wait(cli, 3) myudp = ocf.udp_parameter('INET6', '::', 5090, 'ff04::125', False, 15.0, b'') - udp_mission = threading.Thread(target=ocf.create_host_udp_server, args=(myudp, )) + udp_mission = threading.Thread(target=ocf.create_host_udp_server, args=(myudp,)) udp_mission.start() start_time = time.time() while not myudp.init_flag: @@ -345,7 +337,6 @@ def test_multicast_forwarding_B(Init_interface:bool, dut: Tuple[IdfDut, IdfDut, # Case 5: discover dervice published by Thread device -@pytest.mark.supported_targets @pytest.mark.openthread_br @pytest.mark.flaky(reruns=1, reruns_delay=1) @pytest.mark.parametrize( @@ -359,14 +350,16 @@ def test_multicast_forwarding_B(Init_interface:bool, dut: Tuple[IdfDut, IdfDut, f'|{os.path.join(os.path.dirname(__file__), "ot_br")}', 'esp32c6|esp32h2|esp32s3', f'{ESPPORT3}|{ESPPORT1}|{ESPPORT2}', - id='c6-h2-s3' + id='c6-h2-s3', ), ], indirect=True, ) -def test_service_discovery_of_Thread_device(Init_interface:bool, Init_avahi:bool, dut: Tuple[IdfDut, IdfDut, IdfDut]) -> None: +def test_service_discovery_of_Thread_device( + Init_interface: bool, Init_avahi: bool, dut: Tuple[IdfDut, IdfDut, IdfDut] +) -> None: br = dut[2] - cli = dut[1] + cli = dut[1] assert Init_interface assert Init_avahi dut[0].serial.stop_redirect_thread() @@ -405,7 +398,6 @@ def test_service_discovery_of_Thread_device(Init_interface:bool, Init_avahi:bool # Case 6: discover dervice published by Wi-Fi device -@pytest.mark.supported_targets @pytest.mark.openthread_br @pytest.mark.flaky(reruns=1, reruns_delay=1) @pytest.mark.parametrize( @@ -419,14 +411,16 @@ def test_service_discovery_of_Thread_device(Init_interface:bool, Init_avahi:bool f'|{os.path.join(os.path.dirname(__file__), "ot_br")}', 'esp32c6|esp32h2|esp32s3', f'{ESPPORT3}|{ESPPORT1}|{ESPPORT2}', - id='c6-h2-s3' + id='c6-h2-s3', ), ], indirect=True, ) -def test_service_discovery_of_WiFi_device(Init_interface:bool, Init_avahi:bool, dut: Tuple[IdfDut, IdfDut, IdfDut]) -> None: +def test_service_discovery_of_WiFi_device( + Init_interface: bool, Init_avahi: bool, dut: Tuple[IdfDut, IdfDut, IdfDut] +) -> None: br = dut[2] - cli = dut[1] + cli = dut[1] assert Init_interface assert Init_avahi dut[0].serial.stop_redirect_thread() @@ -474,7 +468,6 @@ def test_service_discovery_of_WiFi_device(Init_interface:bool, Init_avahi:bool, # Case 7: ICMP communication via NAT64 -@pytest.mark.supported_targets @pytest.mark.openthread_br @pytest.mark.flaky(reruns=1, reruns_delay=1) @pytest.mark.parametrize( @@ -488,14 +481,14 @@ def test_service_discovery_of_WiFi_device(Init_interface:bool, Init_avahi:bool, f'|{os.path.join(os.path.dirname(__file__), "ot_br")}', 'esp32c6|esp32h2|esp32s3', f'{ESPPORT3}|{ESPPORT1}|{ESPPORT2}', - id='c6-h2-s3' + id='c6-h2-s3', ), ], indirect=True, ) -def test_ICMP_NAT64(Init_interface:bool, dut: Tuple[IdfDut, IdfDut, IdfDut]) -> None: +def test_ICMP_NAT64(Init_interface: bool, dut: Tuple[IdfDut, IdfDut, IdfDut]) -> None: br = dut[2] - cli = dut[1] + cli = dut[1] assert Init_interface dut[0].serial.stop_redirect_thread() @@ -513,7 +506,6 @@ def test_ICMP_NAT64(Init_interface:bool, dut: Tuple[IdfDut, IdfDut, IdfDut]) -> # Case 8: UDP communication via NAT64 -@pytest.mark.supported_targets @pytest.mark.openthread_br @pytest.mark.flaky(reruns=1, reruns_delay=1) @pytest.mark.parametrize( @@ -527,14 +519,14 @@ def test_ICMP_NAT64(Init_interface:bool, dut: Tuple[IdfDut, IdfDut, IdfDut]) -> f'|{os.path.join(os.path.dirname(__file__), "ot_br")}', 'esp32c6|esp32h2|esp32s3', f'{ESPPORT3}|{ESPPORT1}|{ESPPORT2}', - id='c6-h2-s3' + id='c6-h2-s3', ), ], indirect=True, ) -def test_UDP_NAT64(Init_interface:bool, dut: Tuple[IdfDut, IdfDut, IdfDut]) -> None: +def test_UDP_NAT64(Init_interface: bool, dut: Tuple[IdfDut, IdfDut, IdfDut]) -> None: br = dut[2] - cli = dut[1] + cli = dut[1] assert Init_interface dut[0].serial.stop_redirect_thread() @@ -549,7 +541,7 @@ def test_UDP_NAT64(Init_interface:bool, dut: Tuple[IdfDut, IdfDut, IdfDut]) -> N host_ipv4_address = ocf.get_host_ipv4_address() print('host_ipv4_address: ', host_ipv4_address) myudp = ocf.udp_parameter('INET4', host_ipv4_address, 5090, '', False, 15.0, b'') - udp_mission = threading.Thread(target=ocf.create_host_udp_server, args=(myudp, )) + udp_mission = threading.Thread(target=ocf.create_host_udp_server, args=(myudp,)) udp_mission.start() start_time = time.time() while not myudp.init_flag: @@ -570,7 +562,6 @@ def test_UDP_NAT64(Init_interface:bool, dut: Tuple[IdfDut, IdfDut, IdfDut]) -> N # Case 9: TCP communication via NAT64 -@pytest.mark.supported_targets @pytest.mark.openthread_br @pytest.mark.flaky(reruns=1, reruns_delay=1) @pytest.mark.parametrize( @@ -584,14 +575,14 @@ def test_UDP_NAT64(Init_interface:bool, dut: Tuple[IdfDut, IdfDut, IdfDut]) -> N f'|{os.path.join(os.path.dirname(__file__), "ot_br")}', 'esp32c6|esp32h2|esp32s3', f'{ESPPORT3}|{ESPPORT1}|{ESPPORT2}', - id='c6-h2-s3' + id='c6-h2-s3', ), ], indirect=True, ) -def test_TCP_NAT64(Init_interface:bool, dut: Tuple[IdfDut, IdfDut, IdfDut]) -> None: +def test_TCP_NAT64(Init_interface: bool, dut: Tuple[IdfDut, IdfDut, IdfDut]) -> None: br = dut[2] - cli = dut[1] + cli = dut[1] assert Init_interface dut[0].serial.stop_redirect_thread() @@ -607,7 +598,7 @@ def test_TCP_NAT64(Init_interface:bool, dut: Tuple[IdfDut, IdfDut, IdfDut]) -> N connect_address = ocf.get_ipv6_from_ipv4(host_ipv4_address, br) print('connect_address is: ', connect_address) mytcp = ocf.tcp_parameter('INET4', host_ipv4_address, 12345, False, False, 15.0, b'') - tcp_mission = threading.Thread(target=ocf.create_host_tcp_server, args=(mytcp, )) + tcp_mission = threading.Thread(target=ocf.create_host_tcp_server, args=(mytcp,)) tcp_mission.start() start_time = time.time() while not mytcp.listen_flag: @@ -633,8 +624,6 @@ def test_TCP_NAT64(Init_interface:bool, dut: Tuple[IdfDut, IdfDut, IdfDut]) -> N # Case 10: Sleepy device test -@pytest.mark.esp32h2 -@pytest.mark.esp32c6 @pytest.mark.openthread_sleep @pytest.mark.parametrize( 'config, count, app_path, target, port', @@ -646,7 +635,7 @@ def test_TCP_NAT64(Init_interface:bool, dut: Tuple[IdfDut, IdfDut, IdfDut]) -> N f'|{os.path.join(os.path.dirname(__file__), "ot_sleepy_device/light_sleep")}', 'esp32h2|esp32c6', f'{ESPPORT1}|{ESPPORT3}', - id='h2-c6' + id='h2-c6', ), pytest.param( 'cli|sleepy', @@ -655,7 +644,7 @@ def test_TCP_NAT64(Init_interface:bool, dut: Tuple[IdfDut, IdfDut, IdfDut]) -> N f'|{os.path.join(os.path.dirname(__file__), "ot_sleepy_device/light_sleep")}', 'esp32c6|esp32h2', f'{ESPPORT3}|{ESPPORT1}', - id='c6-h2' + id='c6-h2', ), ], indirect=True, @@ -693,7 +682,6 @@ def test_ot_sleepy_device(dut: Tuple[IdfDut, IdfDut]) -> None: # Case 11: Basic startup Test of BR -@pytest.mark.supported_targets @pytest.mark.openthread_br @pytest.mark.flaky(reruns=1, reruns_delay=1) @pytest.mark.parametrize( @@ -702,11 +690,10 @@ def test_ot_sleepy_device(dut: Tuple[IdfDut, IdfDut]) -> None: pytest.param( 'rcp_uart|br', 2, - f'{os.path.join(os.path.dirname(__file__), "ot_rcp")}' - f'|{os.path.join(os.path.dirname(__file__), "ot_br")}', + f'{os.path.join(os.path.dirname(__file__), "ot_rcp")}|{os.path.join(os.path.dirname(__file__), "ot_br")}', 'esp32c6|esp32s3', f'{ESPPORT3}|{ESPPORT2}', - id='c6-s3' + id='c6-s3', ), ], indirect=True, @@ -735,7 +722,6 @@ def test_basic_startup(dut: Tuple[IdfDut, IdfDut]) -> None: # Case 12: Curl a website via DNS and NAT64 -@pytest.mark.supported_targets @pytest.mark.openthread_bbr @pytest.mark.flaky(reruns=1, reruns_delay=1) @pytest.mark.parametrize( @@ -749,14 +735,14 @@ def test_basic_startup(dut: Tuple[IdfDut, IdfDut]) -> None: f'|{os.path.join(os.path.dirname(__file__), "ot_br")}', 'esp32c6|esp32h2|esp32s3', f'{ESPPORT3}|{ESPPORT1}|{ESPPORT2}', - id='c6-h2-s3' + id='c6-h2-s3', ), ], indirect=True, ) -def test_NAT64_DNS(Init_interface:bool, dut: Tuple[IdfDut, IdfDut, IdfDut]) -> None: +def test_NAT64_DNS(Init_interface: bool, dut: Tuple[IdfDut, IdfDut, IdfDut]) -> None: br = dut[2] - cli = dut[1] + cli = dut[1] assert Init_interface dut[0].serial.stop_redirect_thread() @@ -777,7 +763,6 @@ def test_NAT64_DNS(Init_interface:bool, dut: Tuple[IdfDut, IdfDut, IdfDut]) -> N # Case 13: Meshcop discovery of Border Router -@pytest.mark.supported_targets @pytest.mark.openthread_br @pytest.mark.flaky(reruns=1, reruns_delay=1) @pytest.mark.parametrize( @@ -786,16 +771,15 @@ def test_NAT64_DNS(Init_interface:bool, dut: Tuple[IdfDut, IdfDut, IdfDut]) -> N pytest.param( 'rcp_uart|br', 2, - f'{os.path.join(os.path.dirname(__file__), "ot_rcp")}' - f'|{os.path.join(os.path.dirname(__file__), "ot_br")}', + f'{os.path.join(os.path.dirname(__file__), "ot_rcp")}|{os.path.join(os.path.dirname(__file__), "ot_br")}', 'esp32c6|esp32s3', f'{ESPPORT3}|{ESPPORT2}', - id='c6-s3' + id='c6-s3', ), ], indirect=True, ) -def test_br_meshcop(Init_interface:bool, Init_avahi:bool, dut: Tuple[IdfDut, IdfDut]) -> None: +def test_br_meshcop(Init_interface: bool, Init_avahi: bool, dut: Tuple[IdfDut, IdfDut]) -> None: br = dut[1] assert Init_interface assert Init_avahi @@ -839,7 +823,6 @@ def test_br_meshcop(Init_interface:bool, Init_avahi:bool, dut: Tuple[IdfDut, Idf # Case 14: Curl a website over HTTPS via DNS and NAT64 -@pytest.mark.supported_targets @pytest.mark.openthread_bbr @pytest.mark.flaky(reruns=1, reruns_delay=1) @pytest.mark.parametrize( @@ -853,14 +836,14 @@ def test_br_meshcop(Init_interface:bool, Init_avahi:bool, dut: Tuple[IdfDut, Idf f'|{os.path.join(os.path.dirname(__file__), "ot_br")}', 'esp32c6|esp32h2|esp32s3', f'{ESPPORT3}|{ESPPORT1}|{ESPPORT2}', - id='c6-h2-s3' + id='c6-h2-s3', ), ], indirect=True, ) -def test_https_NAT64_DNS(Init_interface:bool, dut: Tuple[IdfDut, IdfDut, IdfDut]) -> None: +def test_https_NAT64_DNS(Init_interface: bool, dut: Tuple[IdfDut, IdfDut, IdfDut]) -> None: br = dut[2] - cli = dut[1] + cli = dut[1] assert Init_interface dut[0].serial.stop_redirect_thread() @@ -879,7 +862,6 @@ def test_https_NAT64_DNS(Init_interface:bool, dut: Tuple[IdfDut, IdfDut, IdfDut] # Case 15: Thread network formation and attaching with TREL -@pytest.mark.supported_targets @pytest.mark.openthread_br @pytest.mark.flaky(reruns=1, reruns_delay=1) @pytest.mark.parametrize( @@ -892,7 +874,7 @@ def test_https_NAT64_DNS(Init_interface:bool, dut: Tuple[IdfDut, IdfDut, IdfDut] f'|{os.path.join(os.path.dirname(__file__), "ot_trel")}', 'esp32c6|esp32s3', f'{ESPPORT3}|{ESPPORT2}', - id='c6-s3' + id='c6-s3', ), ], indirect=True, @@ -934,7 +916,6 @@ def test_trel_connect(dut: Tuple[IdfDut, IdfDut]) -> None: # Case 16: Thread network BR lib check -@pytest.mark.supported_targets @pytest.mark.openthread_br @pytest.mark.flaky(reruns=1, reruns_delay=1) @pytest.mark.parametrize( @@ -943,11 +924,10 @@ def test_trel_connect(dut: Tuple[IdfDut, IdfDut]) -> None: pytest.param( 'rcp_uart|br_libcheck', 2, - f'{os.path.join(os.path.dirname(__file__), "ot_rcp")}' - f'|{os.path.join(os.path.dirname(__file__), "ot_br")}', + f'{os.path.join(os.path.dirname(__file__), "ot_rcp")}|{os.path.join(os.path.dirname(__file__), "ot_br")}', 'esp32c6|esp32s3', f'{ESPPORT3}|{ESPPORT2}', - id='c6-s3' + id='c6-s3', ), ], indirect=True, diff --git a/examples/peripherals/adc/continuous_read/pytest_adc_continuous.py b/examples/peripherals/adc/continuous_read/pytest_adc_continuous.py index c891db39e8..53dbbdb8ea 100644 --- a/examples/peripherals/adc/continuous_read/pytest_adc_continuous.py +++ b/examples/peripherals/adc/continuous_read/pytest_adc_continuous.py @@ -1,17 +1,14 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded.dut import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32c3 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32c5 @pytest.mark.adc +@idf_parametrize( + 'target', ['esp32', 'esp32s2', 'esp32s3', 'esp32c3', 'esp32c6', 'esp32h2', 'esp32c5'], indirect=['target'] +) def test_adc_continuous(dut: Dut) -> None: res = dut.expect(r'TASK: ret is 0, ret_num is (\d+) bytes') num = res.group(1).decode('utf8') diff --git a/examples/peripherals/adc/oneshot_read/pytest_adc_oneshot.py b/examples/peripherals/adc/oneshot_read/pytest_adc_oneshot.py index 4fb24a6d3c..9702550ffa 100644 --- a/examples/peripherals/adc/oneshot_read/pytest_adc_oneshot.py +++ b/examples/peripherals/adc/oneshot_read/pytest_adc_oneshot.py @@ -1,22 +1,18 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded.dut import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32c3 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32c5 @pytest.mark.adc +@idf_parametrize( + 'target', ['esp32', 'esp32s2', 'esp32s3', 'esp32c3', 'esp32c6', 'esp32h2', 'esp32c5'], indirect=['target'] +) def test_adc_oneshot(dut: Dut) -> None: dut.expect(r'EXAMPLE: ADC1 Channel\[(\d+)\] Raw Data: (\d+)', timeout=5) -@pytest.mark.esp32c2 @pytest.mark.adc @pytest.mark.xtal_26mhz @pytest.mark.parametrize( @@ -26,5 +22,6 @@ def test_adc_oneshot(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32c2'], indirect=['target']) def test_adc_oneshot_esp32c2_xtal_26mhz(dut: Dut) -> None: dut.expect(r'EXAMPLE: ADC1 Channel\[(\d+)\] Raw Data: (\d+)', timeout=5) diff --git a/examples/peripherals/analog_comparator/pytest_ana_cmpr_example.py b/examples/peripherals/analog_comparator/pytest_ana_cmpr_example.py index e9196eb6f8..6d512fc864 100644 --- a/examples/peripherals/analog_comparator/pytest_ana_cmpr_example.py +++ b/examples/peripherals/analog_comparator/pytest_ana_cmpr_example.py @@ -1,13 +1,10 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-2025 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.esp32h2 -@pytest.mark.esp32p4 -@pytest.mark.esp32c5 -@pytest.mark.esp32c61 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -17,9 +14,12 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize('target', ['esp32h2', 'esp32p4', 'esp32c5', 'esp32c61'], indirect=['target']) def test_ana_cmpr_example(dut: Dut) -> None: sdkconfig = dut.app.sdkconfig - dut.expect(r'ana_cmpr_example: Analog Comparator source gpio ([0-9]+), external reference gpio ([0-9]+)', timeout=10) + dut.expect( + r'ana_cmpr_example: Analog Comparator source gpio ([0-9]+), external reference gpio ([0-9]+)', timeout=10 + ) if sdkconfig['EXAMPLE_INTERNAL_REF']: dut.expect('ana_cmpr_example: Allocate Analog Comparator with internal reference', timeout=10) dut.expect(r'ana_cmpr_example: Analog comparator enabled, reference voltage: [0-9]+% \* VDD', timeout=10) diff --git a/examples/peripherals/bitscrambler/pytest_bitscrambler_loopback_example.py b/examples/peripherals/bitscrambler/pytest_bitscrambler_loopback_example.py index df9bbf7617..7ade762b0f 100644 --- a/examples/peripherals/bitscrambler/pytest_bitscrambler_loopback_example.py +++ b/examples/peripherals/bitscrambler/pytest_bitscrambler_loopback_example.py @@ -2,11 +2,11 @@ # 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.esp32c5 @pytest.mark.generic +@idf_parametrize('target', ['esp32p4', 'esp32c5'], indirect=['target']) def test_bitscrambler_loopback_example(dut: Dut) -> None: dut.expect_exact('BitScrambler example main', timeout=5) dut.expect_exact('BitScrambler program complete. Input 40, output 40 bytes') diff --git a/examples/peripherals/camera/dvp_isp_dsi/pytest_dvp_isp_dsi.py b/examples/peripherals/camera/dvp_isp_dsi/pytest_dvp_isp_dsi.py index 7eb81af001..63bad81e79 100644 --- a/examples/peripherals/camera/dvp_isp_dsi/pytest_dvp_isp_dsi.py +++ b/examples/peripherals/camera/dvp_isp_dsi/pytest_dvp_isp_dsi.py @@ -1,10 +1,11 @@ -# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2024-2025 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_dvp_isp_dsi(dut: Dut) -> None: dut.expect_exact('Calling app_main()') diff --git a/examples/peripherals/camera/mipi_isp_dsi/pytest_mipi_isp_dsi.py b/examples/peripherals/camera/mipi_isp_dsi/pytest_mipi_isp_dsi.py index 44da4af5ef..569ced9a11 100644 --- a/examples/peripherals/camera/mipi_isp_dsi/pytest_mipi_isp_dsi.py +++ b/examples/peripherals/camera/mipi_isp_dsi/pytest_mipi_isp_dsi.py @@ -1,10 +1,11 @@ -# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2024-2025 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_mipi_isp_dsi(dut: Dut) -> None: dut.expect_exact('Calling app_main()') diff --git a/examples/peripherals/dac/dac_continuous/dac_audio/pytest_dac_audio.py b/examples/peripherals/dac/dac_continuous/dac_audio/pytest_dac_audio.py index e8940823a2..4c4561c7fe 100644 --- a/examples/peripherals/dac/dac_continuous/dac_audio/pytest_dac_audio.py +++ b/examples/peripherals/dac/dac_continuous/dac_audio/pytest_dac_audio.py @@ -1,8 +1,8 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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 def dac_example_expect(dut: Dut, mode: str) -> None: @@ -13,8 +13,6 @@ def dac_example_expect(dut: Dut, mode: str) -> None: dut.expect('Play count: 2', timeout=10) -@pytest.mark.esp32 -@pytest.mark.esp32s2 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -24,6 +22,7 @@ def dac_example_expect(dut: Dut, mode: str) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32', 'esp32s2'], indirect=['target']) def test_dac_audio_example(dut: Dut) -> None: sdkconfig = dut.app.sdkconfig if sdkconfig['EXAMPLE_DAC_WRITE_SYNC']: diff --git a/examples/peripherals/dac/dac_continuous/signal_generator/pytest_dac_continuous.py b/examples/peripherals/dac/dac_continuous/signal_generator/pytest_dac_continuous.py index 1abbe71b40..d64cc10568 100644 --- a/examples/peripherals/dac/dac_continuous/signal_generator/pytest_dac_continuous.py +++ b/examples/peripherals/dac/dac_continuous/signal_generator/pytest_dac_continuous.py @@ -1,8 +1,8 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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 def test_dac_continuous_output(dut: Dut, mode: str, chan0_io: str, chan1_io: str) -> None: @@ -21,8 +21,6 @@ def test_dac_continuous_output(dut: Dut, mode: str, chan0_io: str, chan1_io: str dut.expect(r'dac continuous\({}\): sine wave start'.format(mode), timeout=20) -@pytest.mark.esp32 -@pytest.mark.esp32s2 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -32,6 +30,7 @@ def test_dac_continuous_output(dut: Dut, mode: str, chan0_io: str, chan1_io: str ], indirect=True, ) +@idf_parametrize('target', ['esp32', 'esp32s2'], indirect=['target']) def test_dac_continuous_example_with_dma(dut: Dut) -> None: sdkconfig = dut.app.sdkconfig if dut.target == 'esp32': diff --git a/examples/peripherals/dac/dac_cosine_wave/pytest_dac_cosine_wave.py b/examples/peripherals/dac/dac_cosine_wave/pytest_dac_cosine_wave.py index 22d432d12b..2e4ab8ce3f 100644 --- a/examples/peripherals/dac/dac_cosine_wave/pytest_dac_cosine_wave.py +++ b/examples/peripherals/dac/dac_cosine_wave/pytest_dac_cosine_wave.py @@ -1,12 +1,12 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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.adc +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_dac_cosine_wave_example_with_12bit_adc(dut: Dut) -> None: res = [] for _ in range(30): @@ -19,8 +19,8 @@ def test_dac_cosine_wave_example_with_12bit_adc(dut: Dut) -> None: assert max(chan0_val) - min(chan0_val) > 1000 -@pytest.mark.esp32s2 @pytest.mark.adc +@idf_parametrize('target', ['esp32s2'], indirect=['target']) def test_dac_cosine_wave_example_with_13bit_adc(dut: Dut) -> None: res = [] for _ in range(30): diff --git a/examples/peripherals/dac/dac_oneshot/pytest_dac_oneshot.py b/examples/peripherals/dac/dac_oneshot/pytest_dac_oneshot.py index ed6fe07fd3..3a44d53282 100644 --- a/examples/peripherals/dac/dac_oneshot/pytest_dac_oneshot.py +++ b/examples/peripherals/dac/dac_oneshot/pytest_dac_oneshot.py @@ -1,13 +1,12 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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_dac_oneshot_example(dut: Dut) -> None: res = [] for _ in range(10): diff --git a/examples/peripherals/gpio/generic_gpio/pytest_generic_gpio_example.py b/examples/peripherals/gpio/generic_gpio/pytest_generic_gpio_example.py index 076a227db2..a43eeb5bae 100644 --- a/examples/peripherals/gpio/generic_gpio/pytest_generic_gpio_example.py +++ b/examples/peripherals/gpio/generic_gpio/pytest_generic_gpio_example.py @@ -1,16 +1,14 @@ -# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - from typing import Callable import pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.supported_targets @pytest.mark.generic -def test_generic_gpio_example( - dut: Dut, log_minimum_free_heap_size: Callable[..., None] -) -> None: +@idf_parametrize('target', ['supported_targets'], indirect=['target']) +def test_generic_gpio_example(dut: Dut, log_minimum_free_heap_size: Callable[..., None]) -> None: log_minimum_free_heap_size() dut.expect(r'cnt: \d+') diff --git a/examples/peripherals/i2c/i2c_tools/pytest_examples_i2c_tools.py b/examples/peripherals/i2c/i2c_tools/pytest_examples_i2c_tools.py index cc152e0070..52989ef804 100644 --- a/examples/peripherals/i2c/i2c_tools/pytest_examples_i2c_tools.py +++ b/examples/peripherals/i2c/i2c_tools/pytest_examples_i2c_tools.py @@ -1,13 +1,14 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-2025 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 EXPECT_TIMEOUT = 20 -@pytest.mark.esp32 @pytest.mark.ccs811 +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_i2ctools_example(dut: IdfDut) -> None: dut.expect_exact('i2c-tools>', timeout=EXPECT_TIMEOUT) # Get i2c address diff --git a/examples/peripherals/i2s/i2s_advance/i2s_usb/pytest_i2s_usb.py b/examples/peripherals/i2s/i2s_advance/i2s_usb/pytest_i2s_usb.py index 4a673b6833..034f1d56f2 100644 --- a/examples/peripherals/i2s/i2s_advance/i2s_usb/pytest_i2s_usb.py +++ b/examples/peripherals/i2s/i2s_advance/i2s_usb/pytest_i2s_usb.py @@ -2,11 +2,10 @@ # 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.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32p4 @pytest.mark.generic +@idf_parametrize('target', ['esp32s2', 'esp32s3', 'esp32p4'], indirect=['target']) def test_i2s_usb_example(dut: Dut) -> None: dut.expect(r'initial MCLK: [0-9]+ Hz') diff --git a/examples/peripherals/i2s/i2s_basic/i2s_pdm/pytest_i2s_pdm.py b/examples/peripherals/i2s/i2s_basic/i2s_pdm/pytest_i2s_pdm.py index 836c411a6d..2a7529f44e 100644 --- a/examples/peripherals/i2s/i2s_basic/i2s_pdm/pytest_i2s_pdm.py +++ b/examples/peripherals/i2s/i2s_basic/i2s_pdm/pytest_i2s_pdm.py @@ -2,50 +2,47 @@ # 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.esp32s3 -@pytest.mark.esp32c3 -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 -@pytest.mark.esp32c61 @pytest.mark.generic -@pytest.mark.parametrize( - 'config', - ['pdm_tx'], - indirect=True +@pytest.mark.parametrize('config', ['pdm_tx'], indirect=True) +@idf_parametrize( + 'target', + ['esp32', 'esp32s3', 'esp32c3', 'esp32c5', 'esp32c6', 'esp32h2', 'esp32p4', 'esp32c61'], + indirect=['target'], ) def test_i2s_pdm_tx_example(dut: Dut) -> None: dut.expect(r'I2S PDM TX example start', timeout=5) dut.expect(r'---------------------------', timeout=5) dut.expect(r'i2s_common: tx channel is registered on I2S0 successfully', timeout=5) - dut.expect(r'i2s_common: DMA malloc info: dma_desc_num = ([0-9]+), ' - r'dma_desc_buf_size = dma_frame_num \* slot_num \* data_bit_width = ([0-9]+)', timeout=5) - dut.expect(r'i2s_pdm: Clock division info: \[sclk\] ([0-9]+) Hz ' - r'\[mdiv\] ([0-9]+) ([0-9]+)/([0-9]+) \[mclk\] ([0-9]+) Hz \[bdiv\] ([0-9]+) \[bclk\] ([0-9]+) Hz', timeout=5) + dut.expect( + r'i2s_common: DMA malloc info: dma_desc_num = ([0-9]+), ' + r'dma_desc_buf_size = dma_frame_num \* slot_num \* data_bit_width = ([0-9]+)', + timeout=5, + ) + dut.expect( + r'i2s_pdm: Clock division info: \[sclk\] ([0-9]+) Hz ' + r'\[mdiv\] ([0-9]+) ([0-9]+)/([0-9]+) \[mclk\] ([0-9]+) Hz \[bdiv\] ([0-9]+) \[bclk\] ([0-9]+) Hz', + timeout=5, + ) dut.expect(r'i2s_pdm: The tx channel on I2S0 has been initialized to PDM TX mode successfully', timeout=5) dut.expect(r'i2s_common: i2s tx channel enabled', timeout=5) dut.expect(r'Playing bass `twinkle twinkle little star`', timeout=5) -@pytest.mark.esp32 -@pytest.mark.esp32s3 -@pytest.mark.esp32p4 @pytest.mark.generic -@pytest.mark.parametrize( - 'config', - ['pdm_rx'], - indirect=True -) +@pytest.mark.parametrize('config', ['pdm_rx'], indirect=True) +@idf_parametrize('target', ['esp32', 'esp32s3', 'esp32p4'], indirect=['target']) def test_i2s_pdm_rx_example(dut: Dut) -> None: dut.expect(r'I2S PDM RX example start', timeout=5) dut.expect(r'---------------------------', timeout=5) dut.expect(r'i2s_common: rx channel is registered on I2S0 successfully', timeout=5) - dut.expect(r'i2s_common: DMA malloc info: dma_desc_num = ([0-9]+), ' - r'dma_desc_buf_size = dma_frame_num \* slot_num \* data_bit_width = ([0-9]+)', timeout=5) + dut.expect( + r'i2s_common: DMA malloc info: dma_desc_num = ([0-9]+), ' + r'dma_desc_buf_size = dma_frame_num \* slot_num \* data_bit_width = ([0-9]+)', + timeout=5, + ) dut.expect(r'i2s_common: i2s rx channel enabled', timeout=5) dut.expect(r'Read Task: i2s read ([0-9]+) bytes', timeout=5) dut.expect(r'-----------------------------------', timeout=5) diff --git a/examples/peripherals/i2s/i2s_basic/i2s_std/pytest_i2s_std.py b/examples/peripherals/i2s/i2s_basic/i2s_std/pytest_i2s_std.py index c4bbda6e53..9d7fbbbd5b 100644 --- a/examples/peripherals/i2s/i2s_basic/i2s_std/pytest_i2s_std.py +++ b/examples/peripherals/i2s/i2s_basic/i2s_std/pytest_i2s_std.py @@ -2,36 +2,41 @@ # 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.esp32s3 -@pytest.mark.esp32c3 -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 -@pytest.mark.esp32c61 @pytest.mark.generic +@idf_parametrize( + 'target', + ['esp32', 'esp32s2', 'esp32s3', 'esp32c3', 'esp32c5', 'esp32c6', 'esp32h2', 'esp32p4', 'esp32c61'], + indirect=['target'], +) def test_i2s_basic_example(dut: Dut) -> None: - dut.expect(r'i2s_common: tx channel is registered on I2S0 successfully', timeout=5) dut.expect(r'i2s_common: rx channel is registered on I2S0 successfully', timeout=5) - dut.expect(r'i2s_common: DMA malloc info: dma_desc_num = ([0-9]+), ' - r'dma_desc_buf_size = dma_frame_num \* slot_num \* data_bit_width = ([0-9]+)', timeout=5) - dut.expect(r'i2s_std: Clock division info: \[sclk\] ([0-9]+) Hz ' - r'\[mdiv\] ([0-9]+) ([0-9]+)/([0-9]+) \[mclk\] ([0-9]+) Hz \[bdiv\] ([0-9]+) \[bclk\] ([0-9]+) Hz', timeout=5) + dut.expect( + r'i2s_common: DMA malloc info: dma_desc_num = ([0-9]+), ' + r'dma_desc_buf_size = dma_frame_num \* slot_num \* data_bit_width = ([0-9]+)', + timeout=5, + ) + dut.expect( + r'i2s_std: Clock division info: \[sclk\] ([0-9]+) Hz ' + r'\[mdiv\] ([0-9]+) ([0-9]+)/([0-9]+) \[mclk\] ([0-9]+) Hz \[bdiv\] ([0-9]+) \[bclk\] ([0-9]+) Hz', + timeout=5, + ) dut.expect(r'i2s_std: The tx channel on I2S0 has been initialized to STD mode successfully', timeout=5) - dut.expect(r'i2s_common: DMA malloc info: dma_desc_num = ([0-9]+), ' - r'dma_desc_buf_size = dma_frame_num \* slot_num \* data_bit_width = ([0-9]+)', timeout=5) - dut.expect(r'i2s_std: Clock division info: \[sclk\] ([0-9]+) Hz ' - r'\[mdiv\] ([0-9]+) ([0-9]+)/([0-9]+) \[mclk\] ([0-9]+) Hz \[bdiv\] ([0-9]+) \[bclk\] ([0-9]+) Hz', timeout=5) + dut.expect( + r'i2s_common: DMA malloc info: dma_desc_num = ([0-9]+), ' + r'dma_desc_buf_size = dma_frame_num \* slot_num \* data_bit_width = ([0-9]+)', + timeout=5, + ) + dut.expect( + r'i2s_std: Clock division info: \[sclk\] ([0-9]+) Hz ' + r'\[mdiv\] ([0-9]+) ([0-9]+)/([0-9]+) \[mclk\] ([0-9]+) Hz \[bdiv\] ([0-9]+) \[bclk\] ([0-9]+) Hz', + timeout=5, + ) dut.expect(r'i2s_std: The rx channel on I2S0 has been initialized to STD mode successfully', timeout=5) - chan_enable_pattern = [ - r'i2s_common: i2s tx channel enabled', - r'i2s_common: i2s rx channel enabled' - ] + chan_enable_pattern = [r'i2s_common: i2s tx channel enabled', r'i2s_common: i2s rx channel enabled'] dut.expect(chan_enable_pattern, timeout=5) dut.expect(chan_enable_pattern, timeout=5) dut.expect(r'Write Task: i2s write ([0-9]+) bytes', timeout=5) diff --git a/examples/peripherals/i2s/i2s_basic/i2s_tdm/pytest_i2s_tdm.py b/examples/peripherals/i2s/i2s_basic/i2s_tdm/pytest_i2s_tdm.py index ecc130510c..65bf9da7be 100644 --- a/examples/peripherals/i2s/i2s_basic/i2s_tdm/pytest_i2s_tdm.py +++ b/examples/peripherals/i2s/i2s_basic/i2s_tdm/pytest_i2s_tdm.py @@ -2,34 +2,39 @@ # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32s3 -@pytest.mark.esp32c3 -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 -@pytest.mark.esp32c61 @pytest.mark.generic +@idf_parametrize( + 'target', ['esp32s3', 'esp32c3', 'esp32c5', 'esp32c6', 'esp32h2', 'esp32p4', 'esp32c61'], indirect=['target'] +) def test_i2s_tdm_example(dut: Dut) -> None: - dut.expect(r'i2s_common: tx channel is registered on I2S0 successfully', timeout=5) dut.expect(r'i2s_common: rx channel is registered on I2S0 successfully', timeout=5) - dut.expect(r'i2s_common: DMA malloc info: dma_desc_num = ([0-9]+), ' - r'dma_desc_buf_size = dma_frame_num \* slot_num \* data_bit_width = ([0-9]+)', timeout=5) - dut.expect(r'i2s_tdm: Clock division info: \[sclk\] ([0-9]+) Hz ' - r'\[mdiv\] ([0-9]+) ([0-9]+)/([0-9]+) \[mclk\] ([0-9]+) Hz \[bdiv\] ([0-9]+) \[bclk\] ([0-9]+) Hz', timeout=5) + dut.expect( + r'i2s_common: DMA malloc info: dma_desc_num = ([0-9]+), ' + r'dma_desc_buf_size = dma_frame_num \* slot_num \* data_bit_width = ([0-9]+)', + timeout=5, + ) + dut.expect( + r'i2s_tdm: Clock division info: \[sclk\] ([0-9]+) Hz ' + r'\[mdiv\] ([0-9]+) ([0-9]+)/([0-9]+) \[mclk\] ([0-9]+) Hz \[bdiv\] ([0-9]+) \[bclk\] ([0-9]+) Hz', + timeout=5, + ) dut.expect(r'i2s_tdm: The tx channel on I2S0 has been initialized to TDM mode successfully', timeout=5) - dut.expect(r'i2s_common: DMA malloc info: dma_desc_num = ([0-9]+), ' - r'dma_desc_buf_size = dma_frame_num \* slot_num \* data_bit_width = ([0-9]+)', timeout=5) - dut.expect(r'i2s_tdm: Clock division info: \[sclk\] ([0-9]+) Hz ' - r'\[mdiv\] ([0-9]+) ([0-9]+)/([0-9]+) \[mclk\] ([0-9]+) Hz \[bdiv\] ([0-9]+) \[bclk\] ([0-9]+) Hz', timeout=5) + dut.expect( + r'i2s_common: DMA malloc info: dma_desc_num = ([0-9]+), ' + r'dma_desc_buf_size = dma_frame_num \* slot_num \* data_bit_width = ([0-9]+)', + timeout=5, + ) + dut.expect( + r'i2s_tdm: Clock division info: \[sclk\] ([0-9]+) Hz ' + r'\[mdiv\] ([0-9]+) ([0-9]+)/([0-9]+) \[mclk\] ([0-9]+) Hz \[bdiv\] ([0-9]+) \[bclk\] ([0-9]+) Hz', + timeout=5, + ) dut.expect(r'i2s_tdm: The rx channel on I2S0 has been initialized to TDM mode successfully', timeout=5) - chan_enable_pattern = [ - r'i2s_common: i2s tx channel enabled', - r'i2s_common: i2s rx channel enabled' - ] + chan_enable_pattern = [r'i2s_common: i2s tx channel enabled', r'i2s_common: i2s rx channel enabled'] dut.expect(chan_enable_pattern, timeout=5) dut.expect(chan_enable_pattern, timeout=5) dut.expect(r'Write Task: i2s write ([0-9]+) bytes', timeout=5) diff --git a/examples/peripherals/i2s/i2s_codec/i2s_es7210_tdm/pytest_i2s_es7210_tdm.py b/examples/peripherals/i2s/i2s_codec/i2s_es7210_tdm/pytest_i2s_es7210_tdm.py index 4f44422087..0fda2176f5 100644 --- a/examples/peripherals/i2s/i2s_codec/i2s_es7210_tdm/pytest_i2s_es7210_tdm.py +++ b/examples/peripherals/i2s/i2s_codec/i2s_es7210_tdm/pytest_i2s_es7210_tdm.py @@ -1,15 +1,12 @@ -# 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 pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32s3 -@pytest.mark.esp32c3 -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 @pytest.mark.generic +@idf_parametrize('target', ['esp32s3', 'esp32c3', 'esp32c5', 'esp32c6', 'esp32h2'], indirect=['target']) def test_i2s_es7210_tdm_example(dut: Dut) -> None: dut.expect_exact('example: Create I2S receive channel') dut.expect_exact('example: Configure I2S receive channel to TDM mode') diff --git a/examples/peripherals/i2s/i2s_codec/i2s_es8311/pytest_i2s_es8311.py b/examples/peripherals/i2s/i2s_codec/i2s_es8311/pytest_i2s_es8311.py index 54404601b0..b9eb9d85f1 100644 --- a/examples/peripherals/i2s/i2s_codec/i2s_es8311/pytest_i2s_es8311.py +++ b/examples/peripherals/i2s/i2s_codec/i2s_es8311/pytest_i2s_es8311.py @@ -1,26 +1,22 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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.esp32s3 -@pytest.mark.esp32c3 -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 -@pytest.mark.esp32c61 @pytest.mark.generic +@idf_parametrize( + 'target', + ['esp32', 'esp32s2', 'esp32s3', 'esp32c3', 'esp32c5', 'esp32c6', 'esp32h2', 'esp32p4', 'esp32c61'], + indirect=['target'], +) def test_i2s_es8311_example_generic(dut: Dut) -> None: dut.expect('i2s es8311 codec example start') dut.expect('-----------------------------') dut.expect('I \\(([0-9]+)\\) i2s_es8311: i2s driver init success') -@pytest.mark.esp32s3 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -29,6 +25,7 @@ def test_i2s_es8311_example_generic(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32s3'], indirect=['target']) def test_i2s_es8311_example_bsp(dut: Dut) -> None: dut.expect('i2s es8311 codec example start') dut.expect('-----------------------------') diff --git a/examples/peripherals/i2s/i2s_recorder/pytest_i2s_record.py b/examples/peripherals/i2s/i2s_recorder/pytest_i2s_record.py index 5c1a92c2fc..be6b9f241b 100644 --- a/examples/peripherals/i2s/i2s_recorder/pytest_i2s_record.py +++ b/examples/peripherals/i2s/i2s_recorder/pytest_i2s_record.py @@ -1,13 +1,12 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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.esp32s3 -@pytest.mark.esp32p4 @pytest.mark.generic +@idf_parametrize('target', ['esp32', 'esp32s3', 'esp32p4'], indirect=['target']) def test_i2s_recorder_generic(dut: Dut) -> None: dut.expect('PDM microphone recording example start') dut.expect('--------------------------------------') diff --git a/examples/peripherals/lcd/mipi_dsi/pytest_mipi_dsi_panel_lvgl.py b/examples/peripherals/lcd/mipi_dsi/pytest_mipi_dsi_panel_lvgl.py index 53a65f9950..c2ef947776 100644 --- a/examples/peripherals/lcd/mipi_dsi/pytest_mipi_dsi_panel_lvgl.py +++ b/examples/peripherals/lcd/mipi_dsi/pytest_mipi_dsi_panel_lvgl.py @@ -1,10 +1,11 @@ -# SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-2025 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_rgb_lcd_lvgl(dut: Dut) -> None: dut.expect_exact('example: Install MIPI DSI LCD control panel') diff --git a/examples/peripherals/lcd/rgb_panel/pytest_rgb_panel_lvgl.py b/examples/peripherals/lcd/rgb_panel/pytest_rgb_panel_lvgl.py index d9af5c60c3..972e00feac 100644 --- a/examples/peripherals/lcd/rgb_panel/pytest_rgb_panel_lvgl.py +++ b/examples/peripherals/lcd/rgb_panel/pytest_rgb_panel_lvgl.py @@ -1,10 +1,10 @@ -# SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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.esp32s3 @pytest.mark.octal_psram @pytest.mark.parametrize( 'config', @@ -15,6 +15,7 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize('target', ['esp32s3'], indirect=['target']) def test_rgb_lcd_lvgl_esp32s3(dut: Dut) -> None: dut.expect_exact('example: Turn off LCD backlight') dut.expect_exact('example: Install RGB LCD panel driver') @@ -26,7 +27,6 @@ def test_rgb_lcd_lvgl_esp32s3(dut: Dut) -> None: dut.expect_exact('example: Display LVGL UI') -@pytest.mark.esp32p4 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -37,6 +37,7 @@ def test_rgb_lcd_lvgl_esp32s3(dut: Dut) -> None: ], indirect=True, ) +@idf_parametrize('target', ['esp32p4'], indirect=['target']) def test_rgb_lcd_lvgl_esp32p4(dut: Dut) -> None: dut.expect_exact('example: Turn off LCD backlight') dut.expect_exact('example: Install RGB LCD panel driver') diff --git a/examples/peripherals/mcpwm/mcpwm_bdc_speed_control/pytest_bdc_speed_control.py b/examples/peripherals/mcpwm/mcpwm_bdc_speed_control/pytest_bdc_speed_control.py index 95579418bd..e298450400 100644 --- a/examples/peripherals/mcpwm/mcpwm_bdc_speed_control/pytest_bdc_speed_control.py +++ b/examples/peripherals/mcpwm/mcpwm_bdc_speed_control/pytest_bdc_speed_control.py @@ -1,12 +1,12 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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.esp32s3 @pytest.mark.generic +@idf_parametrize('target', ['esp32s3'], indirect=['target']) def test_bdc_speed_control_example(dut: Dut) -> None: dut.expect_exact('example: Create DC motor') dut.expect_exact('example: Init pcnt driver to decode rotary signal') diff --git a/examples/peripherals/mcpwm/mcpwm_bldc_hall_control/pytest_bldc_hall_control.py b/examples/peripherals/mcpwm/mcpwm_bldc_hall_control/pytest_bldc_hall_control.py index ccc6a4e34e..0fbdabd061 100644 --- a/examples/peripherals/mcpwm/mcpwm_bldc_hall_control/pytest_bldc_hall_control.py +++ b/examples/peripherals/mcpwm/mcpwm_bldc_hall_control/pytest_bldc_hall_control.py @@ -1,12 +1,12 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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.esp32s3 @pytest.mark.generic +@idf_parametrize('target', ['esp32s3'], indirect=['target']) def test_bldc_hall_control_example(dut: Dut) -> None: dut.expect_exact('example: Disable MOSFET gate') dut.expect_exact('example: Create MCPWM timer') diff --git a/examples/peripherals/mcpwm/mcpwm_capture_hc_sr04/pytest_hc_sr04.py b/examples/peripherals/mcpwm/mcpwm_capture_hc_sr04/pytest_hc_sr04.py index f677a255a9..141b0c83ff 100644 --- a/examples/peripherals/mcpwm/mcpwm_capture_hc_sr04/pytest_hc_sr04.py +++ b/examples/peripherals/mcpwm/mcpwm_capture_hc_sr04/pytest_hc_sr04.py @@ -1,16 +1,12 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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.esp32s3 -@pytest.mark.esp32c6 -@pytest.mark.esp32c5 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 @pytest.mark.generic +@idf_parametrize('target', ['esp32', 'esp32s3', 'esp32c6', 'esp32c5', 'esp32h2', 'esp32p4'], indirect=['target']) def test_hc_sr04_example(dut: Dut) -> None: dut.expect_exact('example: Install capture timer') dut.expect_exact('example: Install capture channel') diff --git a/examples/peripherals/mcpwm/mcpwm_foc_svpwm_open_loop/pytest_foc_open_loop.py b/examples/peripherals/mcpwm/mcpwm_foc_svpwm_open_loop/pytest_foc_open_loop.py index 2e7735c8eb..b3d1068824 100644 --- a/examples/peripherals/mcpwm/mcpwm_foc_svpwm_open_loop/pytest_foc_open_loop.py +++ b/examples/peripherals/mcpwm/mcpwm_foc_svpwm_open_loop/pytest_foc_open_loop.py @@ -1,12 +1,12 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-2025 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.esp32s3 @pytest.mark.generic +@idf_parametrize('target', ['esp32s3'], indirect=['target']) def test_open_foc(dut: Dut) -> None: dut.expect_exact('example_foc: Hello FOC') dut.expect_exact('example_foc: Inverter init OK') diff --git a/examples/peripherals/mcpwm/mcpwm_servo_control/pytest_servo_mg996r.py b/examples/peripherals/mcpwm/mcpwm_servo_control/pytest_servo_mg996r.py index 11a7d01cd8..0f92ed3336 100644 --- a/examples/peripherals/mcpwm/mcpwm_servo_control/pytest_servo_mg996r.py +++ b/examples/peripherals/mcpwm/mcpwm_servo_control/pytest_servo_mg996r.py @@ -1,16 +1,12 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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.esp32s3 -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 @pytest.mark.generic +@idf_parametrize('target', ['esp32', 'esp32s3', 'esp32c5', 'esp32c6', 'esp32h2', 'esp32p4'], indirect=['target']) def test_servo_mg996r_example(dut: Dut) -> None: dut.expect_exact('example: Create timer and operator') dut.expect_exact('example: Connect timer and operator') diff --git a/examples/peripherals/mcpwm/mcpwm_sync/pytest_mcpwm_sync.py b/examples/peripherals/mcpwm/mcpwm_sync/pytest_mcpwm_sync.py index 23ba1a4e34..aa632e16b5 100644 --- a/examples/peripherals/mcpwm/mcpwm_sync/pytest_mcpwm_sync.py +++ b/examples/peripherals/mcpwm/mcpwm_sync/pytest_mcpwm_sync.py @@ -1,21 +1,16 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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.esp32s3 -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 @pytest.mark.generic -@pytest.mark.parametrize('config', [ - pytest.param('gpio', marks=[pytest.mark.esp32, pytest.mark.esp32s3]), - pytest.param('tez', marks=[pytest.mark.esp32, pytest.mark.esp32s3]), - pytest.param('soft', marks=[pytest.mark.esp32s3]), -], indirect=True) +@idf_parametrize( + 'config,target', + [('gpio', 'esp32'), ('gpio', 'esp32s3'), ('tez', 'esp32'), ('tez', 'esp32s3'), ('soft', 'esp32s3')], + indirect=['config', 'target'], +) def test_mcpwm_sync_example(dut: Dut) -> None: dut.expect_exact('example: Create timers') dut.expect_exact('example: Create operators') diff --git a/examples/peripherals/parlio/parlio_rx/logic_analyzer/pytest_logic_analyzer.py b/examples/peripherals/parlio/parlio_rx/logic_analyzer/pytest_logic_analyzer.py index 2d6bc17398..1899df802b 100644 --- a/examples/peripherals/parlio/parlio_rx/logic_analyzer/pytest_logic_analyzer.py +++ b/examples/peripherals/parlio/parlio_rx/logic_analyzer/pytest_logic_analyzer.py @@ -1,13 +1,10 @@ -# SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-2025 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.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 @pytest.mark.generic @pytest.mark.parametrize( 'config', @@ -16,6 +13,7 @@ from pytest_embedded import Dut ], indirect=True, ) +@idf_parametrize('target', ['esp32c5', 'esp32c6', 'esp32h2', 'esp32p4'], indirect=['target']) def test_logic_analyzer_flash_stream(dut: Dut) -> None: dut.expect(r'flash_fat: Probe data partition base addr: \w+ size: \w+') dut.expect(r'flash_fat: flash FATFS mounted') diff --git a/examples/peripherals/parlio/parlio_tx/simple_rgb_led_matrix/pytest_simple_rgb_led_matrix.py b/examples/peripherals/parlio/parlio_tx/simple_rgb_led_matrix/pytest_simple_rgb_led_matrix.py index 9376556578..1c1127f565 100644 --- a/examples/peripherals/parlio/parlio_tx/simple_rgb_led_matrix/pytest_simple_rgb_led_matrix.py +++ b/examples/peripherals/parlio/parlio_tx/simple_rgb_led_matrix/pytest_simple_rgb_led_matrix.py @@ -1,11 +1,12 @@ -# SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-2025 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.esp32c6 @pytest.mark.generic +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_simple_rgb_led_matrix_example(dut: Dut) -> None: dut.expect_exact('example: Install fast GPIO bundle for line address control') dut.expect_exact('example: Install parallel IO TX unit') diff --git a/examples/peripherals/pcnt/rotary_encoder/pytest_rotary_encoder.py b/examples/peripherals/pcnt/rotary_encoder/pytest_rotary_encoder.py index 29d17f4c81..4d6c2271f7 100644 --- a/examples/peripherals/pcnt/rotary_encoder/pytest_rotary_encoder.py +++ b/examples/peripherals/pcnt/rotary_encoder/pytest_rotary_encoder.py @@ -1,17 +1,14 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded.dut import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 @pytest.mark.generic +@idf_parametrize( + 'target', ['esp32', 'esp32s2', 'esp32s3', 'esp32c5', 'esp32c6', 'esp32h2', 'esp32p4'], indirect=['target'] +) def test_rotary_encoder(dut: Dut) -> None: dut.expect_exact('install pcnt unit') dut.expect_exact('set glitch filter') diff --git a/examples/peripherals/ppa/ppa_dsi/pytest_ppa_dsi.py b/examples/peripherals/ppa/ppa_dsi/pytest_ppa_dsi.py index 65eece5657..f8a55926c1 100644 --- a/examples/peripherals/ppa/ppa_dsi/pytest_ppa_dsi.py +++ b/examples/peripherals/ppa/ppa_dsi/pytest_ppa_dsi.py @@ -1,10 +1,11 @@ -# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2024-2025 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_ppa_dsi(dut: Dut) -> None: dut.expect_exact('Calling app_main()') diff --git a/examples/peripherals/rmt/dshot_esc/pytest_dshot_esc.py b/examples/peripherals/rmt/dshot_esc/pytest_dshot_esc.py index 3f2470cea4..4356000120 100644 --- a/examples/peripherals/rmt/dshot_esc/pytest_dshot_esc.py +++ b/examples/peripherals/rmt/dshot_esc/pytest_dshot_esc.py @@ -1,18 +1,16 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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.esp32s3 -@pytest.mark.esp32c3 -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 @pytest.mark.generic +@idf_parametrize( + 'target', + ['esp32', 'esp32s2', 'esp32s3', 'esp32c3', 'esp32c5', 'esp32c6', 'esp32h2', 'esp32p4'], + indirect=['target'], +) def test_dshot_esc_example(dut: Dut) -> None: dut.expect_exact('example: Create RMT TX channel') dut.expect_exact('example: Install Dshot ESC encoder') diff --git a/examples/peripherals/rmt/ir_nec_transceiver/pytest_ir_nec.py b/examples/peripherals/rmt/ir_nec_transceiver/pytest_ir_nec.py index 7c6979a62a..209d836867 100644 --- a/examples/peripherals/rmt/ir_nec_transceiver/pytest_ir_nec.py +++ b/examples/peripherals/rmt/ir_nec_transceiver/pytest_ir_nec.py @@ -1,12 +1,12 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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.ir_transceiver +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_ir_nec_example(dut: Dut) -> None: dut.expect_exact('example: create RMT RX channel') dut.expect_exact('example: register RX done callback') diff --git a/examples/peripherals/rmt/led_strip/pytest_led_strip.py b/examples/peripherals/rmt/led_strip/pytest_led_strip.py index e7f73b87a8..d38b0f60cc 100644 --- a/examples/peripherals/rmt/led_strip/pytest_led_strip.py +++ b/examples/peripherals/rmt/led_strip/pytest_led_strip.py @@ -1,18 +1,16 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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.esp32s3 -@pytest.mark.esp32c3 -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 @pytest.mark.generic +@idf_parametrize( + 'target', + ['esp32', 'esp32s2', 'esp32s3', 'esp32c3', 'esp32c5', 'esp32c6', 'esp32h2', 'esp32p4'], + indirect=['target'], +) def test_led_strip_example(dut: Dut) -> None: dut.expect_exact('example: Create RMT TX channel') dut.expect_exact('example: Install led strip encoder') diff --git a/examples/peripherals/rmt/musical_buzzer/pytest_musical_buzzer.py b/examples/peripherals/rmt/musical_buzzer/pytest_musical_buzzer.py index 3ba73406f0..bfbfb04a6d 100644 --- a/examples/peripherals/rmt/musical_buzzer/pytest_musical_buzzer.py +++ b/examples/peripherals/rmt/musical_buzzer/pytest_musical_buzzer.py @@ -1,17 +1,14 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32c3 -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 @pytest.mark.generic +@idf_parametrize( + 'target', ['esp32s2', 'esp32s3', 'esp32c3', 'esp32c5', 'esp32c6', 'esp32h2', 'esp32p4'], indirect=['target'] +) def test_musical_buzzer_example(dut: Dut) -> None: dut.expect_exact('example: Create RMT TX channel') dut.expect_exact('example: Install musical score encoder') diff --git a/examples/peripherals/rmt/onewire/pytest_onewire.py b/examples/peripherals/rmt/onewire/pytest_onewire.py index 3204c21ed9..3571b45cbc 100644 --- a/examples/peripherals/rmt/onewire/pytest_onewire.py +++ b/examples/peripherals/rmt/onewire/pytest_onewire.py @@ -1,18 +1,16 @@ -# 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 pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32c3 -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 @pytest.mark.generic +@idf_parametrize( + 'target', + ['esp32', 'esp32s2', 'esp32s3', 'esp32c3', 'esp32c5', 'esp32c6', 'esp32h2', 'esp32p4'], + indirect=['target'], +) def test_onewire_example(dut: Dut) -> None: dut.expect_exact('example: 1-Wire bus installed on GPIO') dut.expect_exact('example: Device iterator created, start searching') diff --git a/examples/peripherals/rmt/stepper_motor/pytest_stepper_motor.py b/examples/peripherals/rmt/stepper_motor/pytest_stepper_motor.py index 4a730b2019..aa538f42aa 100644 --- a/examples/peripherals/rmt/stepper_motor/pytest_stepper_motor.py +++ b/examples/peripherals/rmt/stepper_motor/pytest_stepper_motor.py @@ -1,15 +1,12 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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.esp32s3 -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 @pytest.mark.generic +@idf_parametrize('target', ['esp32s3', 'esp32c5', 'esp32c6', 'esp32h2', 'esp32p4'], indirect=['target']) def test_stepper_motor_example(dut: Dut) -> None: dut.expect_exact('example: Initialize EN + DIR GPIO') dut.expect_exact('example: Create RMT TX channel') diff --git a/examples/peripherals/sdio/pytest_sdio_test.py b/examples/peripherals/sdio/pytest_sdio_test.py index 487d8d35f6..dea3c707fa 100644 --- a/examples/peripherals/sdio/pytest_sdio_test.py +++ b/examples/peripherals/sdio/pytest_sdio_test.py @@ -1,13 +1,13 @@ -# SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Apache-2.0 import os from typing import Tuple import pytest from pytest_embedded_idf import IdfDut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32 @pytest.mark.sdio_master_slave @pytest.mark.parametrize( 'count, app_path', @@ -16,6 +16,7 @@ from pytest_embedded_idf import IdfDut ], indirect=True, ) +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_example_sdio_communication(dut: Tuple[IdfDut, IdfDut]) -> None: """ Configurations diff --git a/examples/peripherals/sigma_delta/sdm_dac/pytest_sdm_dac_example.py b/examples/peripherals/sigma_delta/sdm_dac/pytest_sdm_dac_example.py index 6155a182a0..99d1837f46 100644 --- a/examples/peripherals/sigma_delta/sdm_dac/pytest_sdm_dac_example.py +++ b/examples/peripherals/sigma_delta/sdm_dac/pytest_sdm_dac_example.py @@ -1,18 +1,16 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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.esp32s3 -@pytest.mark.esp32c3 -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 @pytest.mark.generic +@idf_parametrize( + 'target', + ['esp32', 'esp32s2', 'esp32s3', 'esp32c3', 'esp32c5', 'esp32c6', 'esp32h2', 'esp32p4'], + indirect=['target'], +) def test_sdm_dac_example(dut: Dut) -> None: dut.expect(r'sdm_dac: Sigma-delta output is attached to GPIO \w+') dut.expect(r'sdm_dac: Timer allocated with resolution \w+ Hz') diff --git a/examples/peripherals/sigma_delta/sdm_led/pytest_sdm_led_example.py b/examples/peripherals/sigma_delta/sdm_led/pytest_sdm_led_example.py index c30c7d274e..7e5aa2f87a 100644 --- a/examples/peripherals/sigma_delta/sdm_led/pytest_sdm_led_example.py +++ b/examples/peripherals/sigma_delta/sdm_led/pytest_sdm_led_example.py @@ -1,18 +1,16 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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.esp32s3 -@pytest.mark.esp32c3 -@pytest.mark.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 @pytest.mark.generic +@idf_parametrize( + 'target', + ['esp32', 'esp32s2', 'esp32s3', 'esp32c3', 'esp32c5', 'esp32c6', 'esp32h2', 'esp32p4'], + indirect=['target'], +) def test_sdm_led_example(dut: Dut) -> None: dut.expect_exact('sdm_led: Install sigma delta channel') dut.expect_exact('sdm_led: Enable sigma delta channel') diff --git a/examples/peripherals/temperature_sensor/temp_sensor/pytest_temp_sensor_example.py b/examples/peripherals/temperature_sensor/temp_sensor/pytest_temp_sensor_example.py index 7cccdee2fe..df1727e3f4 100644 --- a/examples/peripherals/temperature_sensor/temp_sensor/pytest_temp_sensor_example.py +++ b/examples/peripherals/temperature_sensor/temp_sensor/pytest_temp_sensor_example.py @@ -1,19 +1,16 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded.dut import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32s2 -@pytest.mark.esp32c3 -@pytest.mark.esp32s3 -@pytest.mark.esp32c2 -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 -@pytest.mark.esp32c5 -@pytest.mark.esp32c61 @pytest.mark.generic +@idf_parametrize( + 'target', + ['esp32s2', 'esp32c3', 'esp32s3', 'esp32c2', 'esp32c6', 'esp32h2', 'esp32p4', 'esp32c5', 'esp32c61'], + indirect=['target'], +) def test_temp_sensor_example(dut: Dut) -> None: dut.expect_exact('Install temperature sensor') dut.expect_exact('Enable temperature sensor') diff --git a/examples/peripherals/temperature_sensor/temp_sensor_monitor/pytest_temp_sensor_monitor_example.py b/examples/peripherals/temperature_sensor/temp_sensor_monitor/pytest_temp_sensor_monitor_example.py index 458741547c..f5cccf04ac 100644 --- a/examples/peripherals/temperature_sensor/temp_sensor_monitor/pytest_temp_sensor_monitor_example.py +++ b/examples/peripherals/temperature_sensor/temp_sensor_monitor/pytest_temp_sensor_monitor_example.py @@ -1,15 +1,12 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded.dut import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32c6 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 -@pytest.mark.esp32c5 -@pytest.mark.esp32c61 @pytest.mark.generic +@idf_parametrize('target', ['esp32c6', 'esp32h2', 'esp32p4', 'esp32c5', 'esp32c61'], indirect=['target']) def test_temp_sensor_monitor_example(dut: Dut) -> None: dut.expect_exact('Install temperature sensor') dut.expect_exact('Enable temperature sensor') diff --git a/examples/peripherals/timer_group/gptimer/pytest_gptimer_example.py b/examples/peripherals/timer_group/gptimer/pytest_gptimer_example.py index 29a534d611..835b540e21 100644 --- a/examples/peripherals/timer_group/gptimer/pytest_gptimer_example.py +++ b/examples/peripherals/timer_group/gptimer/pytest_gptimer_example.py @@ -1,12 +1,12 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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.supported_targets @pytest.mark.generic +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_gptimer_example(dut: Dut) -> None: dut.expect_exact('Create timer handle', timeout=5) dut.expect_exact('Start timer, stop it at alarm event', timeout=5) @@ -27,7 +27,7 @@ def test_gptimer_example(dut: Dut) -> None: dut.expect_exact('Stop timer') dut.expect_exact('Start timer, update alarm value dynamically') - for i in range(1,5): + for i in range(1, 5): res = dut.expect(r'Timer alarmed, count=(\d+)', timeout=5) alarm_count = res.group(1).decode('utf8') assert (i * 1000000 - 20) < int(alarm_count) < (i * 1000000 + 20) diff --git a/examples/peripherals/timer_group/gptimer_capture_hc_sr04/pytest_gptimer_capture_example.py b/examples/peripherals/timer_group/gptimer_capture_hc_sr04/pytest_gptimer_capture_example.py index 2756fe0fa2..559955d047 100644 --- a/examples/peripherals/timer_group/gptimer_capture_hc_sr04/pytest_gptimer_capture_example.py +++ b/examples/peripherals/timer_group/gptimer_capture_hc_sr04/pytest_gptimer_capture_example.py @@ -1,15 +1,12 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 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.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32c61 -@pytest.mark.esp32h2 -@pytest.mark.esp32p4 @pytest.mark.generic +@idf_parametrize('target', ['esp32c5', 'esp32c6', 'esp32c61', 'esp32h2', 'esp32p4'], indirect=['target']) def test_gptimer_capture(dut: Dut) -> None: dut.expect_exact('Configure trig gpio') dut.expect_exact('Configure echo gpio') diff --git a/examples/peripherals/timer_group/wiegand_interface/pytest_wiegand.py b/examples/peripherals/timer_group/wiegand_interface/pytest_wiegand.py index 8e7f391aeb..50e23ceded 100644 --- a/examples/peripherals/timer_group/wiegand_interface/pytest_wiegand.py +++ b/examples/peripherals/timer_group/wiegand_interface/pytest_wiegand.py @@ -1,19 +1,16 @@ -# SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-2025 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.esp32c5 -@pytest.mark.esp32c6 -@pytest.mark.esp32c61 -@pytest.mark.esp32h2 -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32p4 @pytest.mark.generic +@idf_parametrize( + 'target', + ['esp32', 'esp32c3', 'esp32c5', 'esp32c6', 'esp32c61', 'esp32h2', 'esp32s2', 'esp32s3', 'esp32p4'], + indirect=['target'], +) def test_gptimer_wiegand(dut: Dut) -> None: dut.expect_exact('example: Configure wiegand interface') dut.expect_exact('example: send wiegand data') diff --git a/examples/peripherals/touch_sensor/touch_element/touch_button/pytest_touch_button.py b/examples/peripherals/touch_sensor/touch_element/touch_button/pytest_touch_button.py index 013bf9dbb0..0b6e6959b9 100644 --- a/examples/peripherals/touch_sensor/touch_element/touch_button/pytest_touch_button.py +++ b/examples/peripherals/touch_sensor/touch_element/touch_button/pytest_touch_button.py @@ -1,12 +1,12 @@ -# 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 pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 @pytest.mark.generic +@idf_parametrize('target', ['esp32s2', 'esp32s3'], indirect=['target']) def test_touch_button(dut: Dut) -> None: dut.expect_exact('Touch Button Example: Touch element library installed') dut.expect_exact('Touch Button Example: Touch button installed') diff --git a/examples/peripherals/touch_sensor/touch_element/touch_element_waterproof/pytest_touch_element_waterproof.py b/examples/peripherals/touch_sensor/touch_element/touch_element_waterproof/pytest_touch_element_waterproof.py index 7e1e25e008..d87760af97 100644 --- a/examples/peripherals/touch_sensor/touch_element/touch_element_waterproof/pytest_touch_element_waterproof.py +++ b/examples/peripherals/touch_sensor/touch_element/touch_element_waterproof/pytest_touch_element_waterproof.py @@ -1,12 +1,12 @@ -# 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 pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 @pytest.mark.generic +@idf_parametrize('target', ['esp32s2', 'esp32s3'], indirect=['target']) def test_touch_element_waterproof(dut: Dut) -> None: dut.expect_exact('Touch Element Waterproof Example: Touch Element library install') dut.expect_exact('Touch Element Waterproof Example: Touch Element waterproof install') diff --git a/examples/peripherals/touch_sensor/touch_element/touch_elements_combination/pytest_touch_elements_combination.py b/examples/peripherals/touch_sensor/touch_element/touch_elements_combination/pytest_touch_elements_combination.py index d91e4fba80..96d2f7c702 100644 --- a/examples/peripherals/touch_sensor/touch_element/touch_elements_combination/pytest_touch_elements_combination.py +++ b/examples/peripherals/touch_sensor/touch_element/touch_elements_combination/pytest_touch_elements_combination.py @@ -1,12 +1,12 @@ -# 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 pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 @pytest.mark.generic +@idf_parametrize('target', ['esp32s2', 'esp32s3'], indirect=['target']) def test_touch_elements_combination(dut: Dut) -> None: dut.expect_exact('Touch Elements Combination Example: Touch element library installed') dut.expect_exact('Touch Elements Combination Example: Touch button installed') diff --git a/examples/peripherals/touch_sensor/touch_element/touch_matrix/pytest_touch_matrix.py b/examples/peripherals/touch_sensor/touch_element/touch_matrix/pytest_touch_matrix.py index cc6efd44e5..e3d836e58f 100644 --- a/examples/peripherals/touch_sensor/touch_element/touch_matrix/pytest_touch_matrix.py +++ b/examples/peripherals/touch_sensor/touch_element/touch_matrix/pytest_touch_matrix.py @@ -1,12 +1,12 @@ -# 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 pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 @pytest.mark.generic +@idf_parametrize('target', ['esp32s2', 'esp32s3'], indirect=['target']) def test_touch_matrix(dut: Dut) -> None: dut.expect_exact('Touch Matrix Example: Touch element library installed') dut.expect_exact('Touch Matrix Example: Touch matrix installed') diff --git a/examples/peripherals/touch_sensor/touch_element/touch_slider/pytest_touch_slider.py b/examples/peripherals/touch_sensor/touch_element/touch_slider/pytest_touch_slider.py index 18edc4f240..26a073d08d 100644 --- a/examples/peripherals/touch_sensor/touch_element/touch_slider/pytest_touch_slider.py +++ b/examples/peripherals/touch_sensor/touch_element/touch_slider/pytest_touch_slider.py @@ -1,12 +1,12 @@ -# 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 pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 @pytest.mark.generic +@idf_parametrize('target', ['esp32s2', 'esp32s3'], indirect=['target']) def test_touch_slider(dut: Dut) -> None: dut.expect_exact('Touch Slider Example: Touch element library installed') dut.expect_exact('Touch Slider Example: Touch slider installed') diff --git a/examples/peripherals/touch_sensor/touch_sens_basic/pytest_touch_sens_basic.py b/examples/peripherals/touch_sensor/touch_sens_basic/pytest_touch_sens_basic.py index b5b91f410a..3f02c3fbeb 100644 --- a/examples/peripherals/touch_sensor/touch_sens_basic/pytest_touch_sens_basic.py +++ b/examples/peripherals/touch_sensor/touch_sens_basic/pytest_touch_sens_basic.py @@ -2,13 +2,11 @@ # 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.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32p4 @pytest.mark.generic +@idf_parametrize('target', ['esp32', 'esp32s2', 'esp32s3', 'esp32p4'], indirect=['target']) def test_touch_sens(dut: Dut) -> None: dut.expect(r'Touch \[CH [0-9]+\] enabled on GPIO[0-9]+') dut.expect_exact('Initial benchmark and new threshold are:') diff --git a/examples/peripherals/twai/twai_alert_and_recovery/pytest_twai_alert_recovery_example.py b/examples/peripherals/twai/twai_alert_and_recovery/pytest_twai_alert_recovery_example.py index 200fb60709..e86b71c064 100644 --- a/examples/peripherals/twai/twai_alert_and_recovery/pytest_twai_alert_recovery_example.py +++ b/examples/peripherals/twai/twai_alert_and_recovery/pytest_twai_alert_recovery_example.py @@ -1,12 +1,12 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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.twai_transceiver +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_twai_alert_recovery_example(dut: Dut) -> None: dut.expect_exact('TWAI Alert and Recovery: Driver installed') dut.expect_exact('TWAI Alert and Recovery: Driver uninstalled') diff --git a/examples/peripherals/twai/twai_self_test/pytest_twai_self_test_example.py b/examples/peripherals/twai/twai_self_test/pytest_twai_self_test_example.py index ea139a4e35..39a0243050 100644 --- a/examples/peripherals/twai/twai_self_test/pytest_twai_self_test_example.py +++ b/examples/peripherals/twai/twai_self_test/pytest_twai_self_test_example.py @@ -1,12 +1,12 @@ -# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2021-2025 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.twai_transceiver +@idf_parametrize('target', ['esp32'], indirect=['target']) def test_twai_self_test_example(dut: Dut) -> None: dut.expect_exact('TWAI Self Test: Driver installed') dut.expect_exact('TWAI Self Test: Driver uninstalled') diff --git a/examples/peripherals/uart/uart_async_rxtxtasks/pytest_async_rxtxtasks.py b/examples/peripherals/uart/uart_async_rxtxtasks/pytest_async_rxtxtasks.py index b039660e56..ac08448929 100644 --- a/examples/peripherals/uart/uart_async_rxtxtasks/pytest_async_rxtxtasks.py +++ b/examples/peripherals/uart/uart_async_rxtxtasks/pytest_async_rxtxtasks.py @@ -2,9 +2,10 @@ # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.supported_targets @pytest.mark.generic +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_uart_async_rxtxtasks_example(dut: Dut) -> None: dut.expect_exact('TX_TASK: Wrote 11 bytes') diff --git a/examples/peripherals/uart/uart_events/pytest_events.py b/examples/peripherals/uart/uart_events/pytest_events.py index fb4a8a4611..eb83282253 100644 --- a/examples/peripherals/uart/uart_events/pytest_events.py +++ b/examples/peripherals/uart/uart_events/pytest_events.py @@ -2,10 +2,11 @@ # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.supported_targets @pytest.mark.generic +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_uart_events_example(dut: Dut) -> None: dut.expect_exact('Returned from app_main()') dut.write('a') diff --git a/examples/peripherals/uart/uart_select/pytest_uart_select.py b/examples/peripherals/uart/uart_select/pytest_uart_select.py index eb37f26cee..e9f6717bf5 100644 --- a/examples/peripherals/uart/uart_select/pytest_uart_select.py +++ b/examples/peripherals/uart/uart_select/pytest_uart_select.py @@ -2,10 +2,11 @@ # SPDX-License-Identifier: CC0-1.0 import pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.supported_targets @pytest.mark.generic +@idf_parametrize('target', ['supported_targets'], indirect=['target']) def test_uart_select_example(dut: Dut) -> None: dut.expect_exact('uart_select_example: Timeout has been reached and nothing has been received') dut.write('a') diff --git a/examples/peripherals/usb/device/tusb_composite_msc_serialdevice/pytest_usb_device_composite.py b/examples/peripherals/usb/device/tusb_composite_msc_serialdevice/pytest_usb_device_composite.py index 5ff64a8de7..2c42a9235a 100644 --- a/examples/peripherals/usb/device/tusb_composite_msc_serialdevice/pytest_usb_device_composite.py +++ b/examples/peripherals/usb/device/tusb_composite_msc_serialdevice/pytest_usb_device_composite.py @@ -1,18 +1,17 @@ -# SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 from time import sleep import pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize from serial import Serial from serial.tools.list_ports import comports -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32p4 @pytest.mark.temp_skip_ci(targets=['esp32s3'], reason='lack of runners with usb_device tag') @pytest.mark.usb_device +@idf_parametrize('target', ['esp32s2', 'esp32s3', 'esp32p4'], indirect=['target']) def test_usb_composite_device_serial_example(dut: Dut) -> None: dut.expect_exact('Hello World!') dut.expect_exact('USB Composite initialization') diff --git a/examples/peripherals/usb/device/tusb_console/pytest_usb_device_console.py b/examples/peripherals/usb/device/tusb_console/pytest_usb_device_console.py index 879b6a9e2e..8860dbff92 100644 --- a/examples/peripherals/usb/device/tusb_console/pytest_usb_device_console.py +++ b/examples/peripherals/usb/device/tusb_console/pytest_usb_device_console.py @@ -1,18 +1,17 @@ -# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 from time import sleep import pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize from serial import Serial from serial.tools.list_ports import comports -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32p4 @pytest.mark.temp_skip_ci(targets=['esp32s3'], reason='lack of runners with usb_device tag') @pytest.mark.usb_device +@idf_parametrize('target', ['esp32s2', 'esp32s3', 'esp32p4'], indirect=['target']) def test_usb_device_console_example(dut: Dut) -> None: dut.expect_exact('USB initialization DONE') dut.expect_exact('example: log -> UART') diff --git a/examples/peripherals/usb/device/tusb_hid/pytest_usb_device_hid.py b/examples/peripherals/usb/device/tusb_hid/pytest_usb_device_hid.py index eacb17ccf5..986b293fe8 100644 --- a/examples/peripherals/usb/device/tusb_hid/pytest_usb_device_hid.py +++ b/examples/peripherals/usb/device/tusb_hid/pytest_usb_device_hid.py @@ -1,14 +1,13 @@ -# 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 pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32p4 @pytest.mark.temp_skip_ci(targets=['esp32s3'], reason='lack of runners with usb_device tag') @pytest.mark.usb_device +@idf_parametrize('target', ['esp32s2', 'esp32s3', 'esp32p4'], indirect=['target']) def test_usb_device_hid_example(dut: Dut) -> None: dut.expect_exact('USB initialization DONE') dut.expect_exact('Sending Keyboard report') diff --git a/examples/peripherals/usb/device/tusb_midi/pytest_usb_device_midi.py b/examples/peripherals/usb/device/tusb_midi/pytest_usb_device_midi.py index b3eb2a2ca3..9c6a576246 100644 --- a/examples/peripherals/usb/device/tusb_midi/pytest_usb_device_midi.py +++ b/examples/peripherals/usb/device/tusb_midi/pytest_usb_device_midi.py @@ -1,14 +1,13 @@ -# 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 pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32p4 @pytest.mark.temp_skip_ci(targets=['esp32s3'], reason='lack of runners with usb_device tag') @pytest.mark.usb_device +@idf_parametrize('target', ['esp32s2', 'esp32s3', 'esp32p4'], indirect=['target']) def test_usb_device_midi_example(dut: Dut) -> None: dut.expect_exact('USB initialization DONE') dut.expect_exact('MIDI write task init') diff --git a/examples/peripherals/usb/device/tusb_msc/pytest_usb_device_msc.py b/examples/peripherals/usb/device/tusb_msc/pytest_usb_device_msc.py index ca792f328f..3503b0e62d 100644 --- a/examples/peripherals/usb/device/tusb_msc/pytest_usb_device_msc.py +++ b/examples/peripherals/usb/device/tusb_msc/pytest_usb_device_msc.py @@ -1,14 +1,13 @@ -# 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 pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32p4 @pytest.mark.temp_skip_ci(targets=['esp32s3'], reason='lack of runners with usb_device tag') @pytest.mark.usb_device +@idf_parametrize('target', ['esp32s2', 'esp32s3', 'esp32p4'], indirect=['target']) def test_usb_device_msc_example(dut: Dut) -> None: dut.expect('Mount storage') dut.expect('TinyUSB Driver installed') diff --git a/examples/peripherals/usb/device/tusb_ncm/pytest_usb_device_ncm.py b/examples/peripherals/usb/device/tusb_ncm/pytest_usb_device_ncm.py index b01a9c47a8..ce60d13eb3 100644 --- a/examples/peripherals/usb/device/tusb_ncm/pytest_usb_device_ncm.py +++ b/examples/peripherals/usb/device/tusb_ncm/pytest_usb_device_ncm.py @@ -1,22 +1,24 @@ -# 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 subprocess import time import pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 @pytest.mark.temp_skip_ci(targets=['esp32s3'], reason='lack of runners with usb_device tag') @pytest.mark.usb_device +@idf_parametrize('target', ['esp32s2', 'esp32s3'], indirect=['target']) def test_usb_device_ncm_example(dut: Dut) -> None: - netif_mac = dut.expect(r'Network interface HW address: ([0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2})') + netif_mac = dut.expect( + r'Network interface HW address: ([0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2}:[0-9A-Fa-f]{2})' + ) netif_mac = netif_mac.group(1).decode('utf-8') dut.expect_exact('USB NCM and WiFi initialized and started') dut.expect_exact('Returned from app_main()') - time.sleep(1) # Wait 1s for the network interface to appear + time.sleep(1) # Wait 1s for the network interface to appear out_bytes = subprocess.check_output('ifconfig', shell=True, timeout=5) out_str = out_bytes.decode('utf-8') print('expected network interface HW address: ', netif_mac) diff --git a/examples/peripherals/usb/device/tusb_serial_device/pytest_usb_device_serial.py b/examples/peripherals/usb/device/tusb_serial_device/pytest_usb_device_serial.py index 9a5e25550c..f1dd71ef11 100644 --- a/examples/peripherals/usb/device/tusb_serial_device/pytest_usb_device_serial.py +++ b/examples/peripherals/usb/device/tusb_serial_device/pytest_usb_device_serial.py @@ -1,18 +1,17 @@ -# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 from time import sleep import pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize from serial import Serial from serial.tools.list_ports import comports -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32p4 @pytest.mark.temp_skip_ci(targets=['esp32s3'], reason='lack of runners with usb_device tag') @pytest.mark.usb_device +@idf_parametrize('target', ['esp32s2', 'esp32s3', 'esp32p4'], indirect=['target']) def test_usb_device_serial_example(dut: Dut) -> None: dut.expect_exact('USB initialization DONE') sleep(2) # Some time for the OS to enumerate our USB device diff --git a/examples/peripherals/usb/host/msc/pytest_usb_host_msc.py b/examples/peripherals/usb/host/msc/pytest_usb_host_msc.py index cae9851d4c..6ee2bbdd00 100644 --- a/examples/peripherals/usb/host/msc/pytest_usb_host_msc.py +++ b/examples/peripherals/usb/host/msc/pytest_usb_host_msc.py @@ -1,14 +1,13 @@ -# 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 pytest from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32p4 @pytest.mark.temp_skip_ci(targets=['esp32s2'], reason='lack of runners with usb_host_flash_disk tag') @pytest.mark.usb_host_flash_disk +@idf_parametrize('target', ['esp32s2', 'esp32s3', 'esp32p4'], indirect=['target']) def test_usb_host_msc_example(dut: Dut) -> None: # Get wMaxPacketSize to get USB device speed max_packet_size = int(dut.expect(r'wMaxPacketSize (\d{2,3})')[1].decode()) @@ -21,10 +20,10 @@ def test_usb_host_msc_example(dut: Dut) -> None: read_throughput = float(dut.expect(r'example: Read speed ([0-9]*[.]?[0-9]+) MiB')[1].decode()) # Set write and read throughput limits - if (max_packet_size == 512): # wMaxPacketSize = 512 for HS + if max_packet_size == 512: # wMaxPacketSize = 512 for HS write_throughput_limit = 4.9 read_throughput_limit = 11.5 - else: # wMaxPacketSize = 64 for FS + else: # wMaxPacketSize = 64 for FS write_throughput_limit = 0.9 read_throughput_limit = 1.0 diff --git a/examples/peripherals/usb/host/usb_host_lib/pytest_usb_host_lib.py b/examples/peripherals/usb/host/usb_host_lib/pytest_usb_host_lib.py index 4f1e0a3168..b3907df7af 100644 --- a/examples/peripherals/usb/host/usb_host_lib/pytest_usb_host_lib.py +++ b/examples/peripherals/usb/host/usb_host_lib/pytest_usb_host_lib.py @@ -1,14 +1,13 @@ -# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2024-2025 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.esp32s2 -@pytest.mark.esp32s3 -@pytest.mark.esp32p4 @pytest.mark.temp_skip_ci(targets=['esp32s2'], reason='lack of runners with usb_host_flash_disk tag') @pytest.mark.usb_host_flash_disk +@idf_parametrize('target', ['esp32s2', 'esp32s3', 'esp32p4'], indirect=['target']) def test_usb_host_lib_example(dut: Dut) -> None: # register client dut.expect_exact('CLASS: Registering Client') diff --git a/examples/peripherals/usb_serial_jtag/usb_serial_jtag_echo/pytest_usj_echo_example.py b/examples/peripherals/usb_serial_jtag/usb_serial_jtag_echo/pytest_usj_echo_example.py index 0bda957d04..6a4b68a5cb 100644 --- a/examples/peripherals/usb_serial_jtag/usb_serial_jtag_echo/pytest_usj_echo_example.py +++ b/examples/peripherals/usb_serial_jtag/usb_serial_jtag_echo/pytest_usj_echo_example.py @@ -1,21 +1,22 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 from time import sleep import pytest import serial.tools.list_ports from pytest_embedded import Dut +from pytest_embedded_idf.utils import idf_parametrize -@pytest.mark.esp32c6 # usb_serial_jtag is very similar, test C6 is enough. @pytest.mark.usj_device +@idf_parametrize('target', ['esp32c6'], indirect=['target']) def test_usb_device_serial_echo_example(dut: Dut) -> None: dut.expect_exact('USB_SERIAL_JTAG init done') sleep(2) ports = list(serial.tools.list_ports.comports()) for p in ports: - if (p.device == '/dev/ttyACM0'): # Get the usb_serial_jtag port + if p.device == '/dev/ttyACM0': # Get the usb_serial_jtag port with serial.Serial(p.device) as s: s.write(b'hi, espressif\n') sleep(1) diff --git a/examples/protocols/esp_http_client/pytest_esp_http_client.py b/examples/protocols/esp_http_client/pytest_esp_http_client.py index dc22927201..c329a16503 100644 --- a/examples/protocols/esp_http_client/pytest_esp_http_client.py +++ b/examples/protocols/esp_http_client/pytest_esp_http_client.py @@ -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) diff --git a/examples/protocols/esp_local_ctrl/pytest_esp_local_ctrl.py b/examples/protocols/esp_local_ctrl/pytest_esp_local_ctrl.py index bfd59b66cb..92820a6f2c 100644 --- a/examples/protocols/esp_local_ctrl/pytest_esp_local_ctrl.py +++ b/examples/protocols/esp_local_ctrl/pytest_esp_local_ctrl.py @@ -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 = '' diff --git a/examples/protocols/http_request/pytest_http_request.py b/examples/protocols/http_request/pytest_http_request.py index b9bf0d5cf8..b2a871e983 100644 --- a/examples/protocols/http_request/pytest_http_request.py +++ b/examples/protocols/http_request/pytest_http_request.py @@ -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') diff --git a/examples/protocols/http_server/advanced_tests/pytest_http_server_advanced.py b/examples/protocols/http_server/advanced_tests/pytest_http_server_advanced.py index 79f031fe4f..7dba01c69a 100644 --- a/examples/protocols/http_server/advanced_tests/pytest_http_server_advanced.py +++ b/examples/protocols/http_server/advanced_tests/pytest_http_server_advanced.py @@ -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]) diff --git a/examples/protocols/http_server/async_handlers/pytest_http_server_async.py b/examples/protocols/http_server/async_handlers/pytest_http_server_async.py index 1021fbbdc2..bebd7937b1 100644 --- a/examples/protocols/http_server/async_handlers/pytest_http_server_async.py +++ b/examples/protocols/http_server/async_handlers/pytest_http_server_async.py @@ -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') diff --git a/examples/protocols/http_server/captive_portal/pytest_captive_portal.py b/examples/protocols/http_server/captive_portal/pytest_captive_portal.py index d08b20df06..60c051aa77 100644 --- a/examples/protocols/http_server/captive_portal/pytest_captive_portal.py +++ b/examples/protocols/http_server/captive_portal/pytest_captive_portal.py @@ -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)) diff --git a/examples/protocols/http_server/file_serving/pytest_http_server_file_serving.py b/examples/protocols/http_server/file_serving/pytest_http_server_file_serving.py index ff0c0e8ef5..64326435be 100644 --- a/examples/protocols/http_server/file_serving/pytest_http_server_file_serving.py +++ b/examples/protocols/http_server/file_serving/pytest_http_server_file_serving.py @@ -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)) diff --git a/examples/protocols/http_server/persistent_sockets/pytest_http_server_persistence.py b/examples/protocols/http_server/persistent_sockets/pytest_http_server_persistence.py index 9d19d77f20..e44704ec7a 100644 --- a/examples/protocols/http_server/persistent_sockets/pytest_http_server_persistence.py +++ b/examples/protocols/http_server/persistent_sockets/pytest_http_server_persistence.py @@ -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) diff --git a/examples/protocols/http_server/simple/pytest_http_server_simple.py b/examples/protocols/http_server/simple/pytest_http_server_simple.py index 8de35734ed..828e833ccf 100644 --- a/examples/protocols/http_server/simple/pytest_http_server_simple.py +++ b/examples/protocols/http_server/simple/pytest_http_server_simple.py @@ -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') diff --git a/examples/protocols/http_server/ws_echo_server/pytest_ws_server_example.py b/examples/protocols/http_server/ws_echo_server/pytest_ws_server_example.py index 9dd1bf4c49..4a3b4c1443 100644 --- a/examples/protocols/http_server/ws_echo_server/pytest_ws_server_example.py +++ b/examples/protocols/http_server/ws_echo_server/pytest_ws_server_example.py @@ -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') diff --git a/examples/protocols/https_mbedtls/pytest_https_mbedtls.py b/examples/protocols/https_mbedtls/pytest_https_mbedtls.py index 8fd2e2a313..0027bb8cc2 100644 --- a/examples/protocols/https_mbedtls/pytest_https_mbedtls.py +++ b/examples/protocols/https_mbedtls/pytest_https_mbedtls.py @@ -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: | diff --git a/examples/protocols/https_request/pytest_https_request.py b/examples/protocols/https_request/pytest_https_request.py index e24bff59fd..456c5ede88 100644 --- a/examples/protocols/https_request/pytest_https_request.py +++ b/examples/protocols/https_request/pytest_https_request.py @@ -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"') diff --git a/examples/protocols/https_server/simple/pytest_https_server_simple.py b/examples/protocols/https_server/simple/pytest_https_server_simple.py index 98179cfca7..1ae348ec2b 100644 --- a/examples/protocols/https_server/simple/pytest_https_server_simple.py +++ b/examples/protocols/https_server/simple/pytest_https_server_simple.py @@ -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 = '