Просмотр исходного кода

Merge branch 'feature/update_efuse_example_test_to_pytest' into 'master'

efuse_exmple_test: Update to pytest framework

See merge request espressif/esp-idf!18702
Aditya Patwardhan 3 лет назад
Родитель
Сommit
b2ce7b3c8c
2 измененных файлов с 444 добавлено и 240 удалено
  1. 99 0
      examples/system/efuse/conftest.py
  2. 345 240
      examples/system/efuse/pytest_efuse.py

+ 99 - 0
examples/system/efuse/conftest.py

@@ -0,0 +1,99 @@
+# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+# SPDX-License-Identifier: Apache-2.0
+
+import logging
+import os
+
+import pytest
+from _pytest.fixtures import FixtureRequest
+from _pytest.monkeypatch import MonkeyPatch
+from pytest_embedded_idf.app import FlashFile
+from pytest_embedded_idf.serial import IdfSerial
+
+
+# This is a custom IdfSerial class to support custom functionality
+# which is required only for this test
+class EfuseFlashEncSerial(IdfSerial):
+
+    @IdfSerial.use_esptool
+    def write_flash_no_enc(self) -> None:
+        self.app.flash_settings['encrypt'] = False
+        flash_files = []
+        for file in self.app.flash_files:
+            # Set encrypted flag to false for each file.
+            flash_files.append(file._replace(encrypted=False))
+        # Replace the original tuple with modified tuple with all the files marked as unencrypted.
+        self.app.flash_files = tuple(flash_files)
+        # Now flash the files
+        self.flash()
+
+    def bootloader_flash(self) -> None:
+        """
+        Flash bootloader.
+
+        :return: None
+        """
+        logging.info('Flashing bootloader')
+        bootloader_path = os.path.join(self.app.binary_path, 'bootloader', 'bootloader.bin')
+        offs = int(self.app.sdkconfig.get('BOOTLOADER_OFFSET_IN_FLASH', 0))
+        logging.info('bootloader offset is {0}'.format(hex(offs)))
+        prev_flash_files = self.app.flash_files
+        flash_files = []
+        flash_files.append(
+            FlashFile(
+                offs,
+                bootloader_path,
+                False,
+            )
+        )
+        self.app.flash_files = flash_files
+        self.app.flash_settings['encrypt'] = False
+        self.flash()
+        # Restore self.app.flash files to original value
+        self.app.flash_files = prev_flash_files
+
+    def erase_field_on_emul_efuse(self, pos_of_bits: list) -> None:
+        emul_efuse_bin_path = os.path.join(self.app.binary_path, 'emul_efuse.bin')
+        self.dump_flash(output=emul_efuse_bin_path, partition='emul_efuse')
+        logging.info('Erasing field on emulated efuse')
+
+        def erase_bit(pos_of_bit: int) -> None:
+            nbytes, nbits = divmod(pos_of_bit, 8)
+            with open(emul_efuse_bin_path, 'r+b') as f:
+                f.seek(nbytes)
+                data = ord(f.read(1))
+                data &= ~(1 << nbits)
+                f.seek(-1, os.SEEK_CUR)
+                f.write(bytes([data]))
+
+        for pos_of_bit in sorted(pos_of_bits):
+            erase_bit(pos_of_bit)
+
+        offs = self.app.partition_table['emul_efuse']['offset']
+        logging.info('emul efuse offset is {0}'.format(hex(offs)))
+        prev_flash_files = self.app.flash_files
+
+        flash_files = []
+        flash_files.append(
+            FlashFile(
+                offs,
+                emul_efuse_bin_path,
+                False,
+            )
+        )
+        self.app.flash_files = flash_files
+        self.app.flash_settings['encrypt'] = False
+        self.flash()
+        self.app.flash_files = prev_flash_files
+
+
+@pytest.fixture(scope='module')
+def monkeypatch_module(request: FixtureRequest) -> MonkeyPatch:
+    mp = MonkeyPatch()
+    request.addfinalizer(mp.undo)
+    return mp
+
+
+@pytest.fixture(scope='module', autouse=True)
+def replace_dut_class(monkeypatch_module: MonkeyPatch) -> None:
+    monkeypatch_module.setattr('pytest_embedded_idf.serial.IdfSerial', EfuseFlashEncSerial)

+ 345 - 240
examples/system/efuse/example_test.py → examples/system/efuse/pytest_efuse.py

@@ -1,76 +1,63 @@
+# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
+# SPDX-License-Identifier: Unlicense OR CC0-1.0
 from __future__ import unicode_literals
 
+import logging
 import os
-import re
-
-import ttfw_idf
-
-
-def erase_field_on_emul_efuse(dut, pos_of_bits):  # type: (ttfw_idf.TinyFW.Env, list) -> None
-    emul_efuse_bin_path = os.path.join(dut.app.binary_path, 'emul_efuse.bin')
-    dut.dump_flash(emul_efuse_bin_path, partition='emul_efuse')
-
-    def erase_bit(pos_of_bit):  # type: (int) -> None
-        nbytes, nbits = divmod(pos_of_bit, 8)
-        with open(emul_efuse_bin_path, 'r+b') as f:
-            f.seek(nbytes)
-            data = ord(f.read(1))
-            data &= ~(1 << nbits)
-            f.seek(-1, os.SEEK_CUR)
-            f.write(bytes([data]))
-
-    for pos_of_bit in sorted(pos_of_bits):
-        erase_bit(pos_of_bit)
-
-    offs = dut.app.partition_table['emul_efuse']['offset']
-    flash_files = [(offs, emul_efuse_bin_path)]
-    dut.write_flash(flash_files)
-
-
-@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32', 'esp32c3', 'esp32c2'])
-def test_examples_efuse(env, _):  # type: (ttfw_idf.TinyFW.Env, None) -> None
-    dut = env.get_dut('efuse', 'examples/system/efuse')
-    dut.start_app()
-    dut.expect_all(re.compile(r'example: Coding Scheme (3/4)|(NONE)|(REPEAT)|(RS \(Reed-Solomon coding\))'),
-                   'example: read efuse fields',
-                   re.compile(r'example: 1. read MAC address: {}'.format(r':'.join((r'[0-9a-f]{2}',) * 6))),
-                   'example: 2. read secure_version: 0',
-                   'example: 3. read custom fields',
-                   'example: module_version = 0',
-                   'example: device_role = None',
-                   'example: setting_1 = 0',
-                   'example: setting_2 = 0',
-                   'example: custom_secure_version = 0',
-                   'example: This example does not burn any efuse in reality only virtually',
-                   'example: Write operations in efuse fields are performed virtually',
-                   'example: write custom efuse fields',
-                   'efuse: Virtual efuses enabled: Not really burning eFuses',
-                   'example: module_version = 1',
-                   'example: device_role = Slave',
-                   'example: setting_1 = 3',
-                   'example: setting_2 = 4',
-                   'example: custom_secure_version = 5',
-                   'example: Done',
-                   timeout=30)
-
-
-@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32', 'esp32s2', 'esp32c3', 'esp32c2'])
-def test_examples_efuse_with_virt_flash_enc(env, _):  # type: (ttfw_idf.TinyFW.Env, None) -> None
-    dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_flash_enc')
+
+import pytest
+from pytest_embedded import Dut
+
+
+@pytest.mark.generic
+@pytest.mark.esp32
+@pytest.mark.esp32c2
+@pytest.mark.esp32c3
+def test_examples_efuse(dut: Dut) -> None:
+    dut.expect(r'example: Coding Scheme (3/4)|(NONE)|(REPEAT)|(RS \(Reed-Solomon coding\))', timeout=20)
+    dut.expect(['example: read efuse fields',
+                r'example: 1. read MAC address: {}'.format(r':'.join((r'[0-9a-f]{2}',) * 6)),
+                'example: 2. read secure_version: 0',
+                'example: 3. read custom fields',
+                'example: module_version = 0',
+                'example: device_role = None',
+                'example: setting_1 = 0',
+                'example: setting_2 = 0',
+                'example: custom_secure_version = 0',
+                'example: This example does not burn any efuse in reality only virtually',
+                'example: Write operations in efuse fields are performed virtually',
+                'example: write custom efuse fields',
+                'efuse: Virtual efuses enabled: Not really burning eFuses',
+                'example: module_version = 1',
+                'example: device_role = Slave',
+                'example: setting_1 = 3',
+                'example: setting_2 = 4',
+                'example: custom_secure_version = 5',
+                'example: Done'], expect_all=True)
+
+
+@pytest.mark.generic
+@pytest.mark.esp32
+@pytest.mark.esp32s2
+@pytest.mark.esp32c2
+@pytest.mark.esp32c3
+@pytest.mark.parametrize('config', ['virt_flash_enc',], indirect=True)
+@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True)
+def test_examples_efuse_with_virt_flash_enc(dut: Dut) -> None:
     # check and log bin size
     binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin')
     bin_size = os.path.getsize(binary_file)
-    ttfw_idf.log_performance('{}_bootloader_{}_bin_size'.format(dut.app.target, dut.app.config_name), '{}KB'.format(bin_size // 1024))
+    logging.info('{}_bootloader_virt_flash_enc_bin_size: {}KB'.format(dut.app.target, bin_size // 1024))
 
     print(' - Erase flash')
-    dut.erase_flash()
+    dut.serial.erase_flash()
 
     print(' - Start app (flash partition_table and app)')
-    dut.start_app_no_enc()
+    dut.serial.write_flash_no_enc()
     dut.expect('Loading virtual efuse blocks from real efuses')
     dut.expect('Checking flash encryption...')
     dut.expect('Generating new flash encryption key...')
-    if dut.TARGET == 'esp32':
+    if dut.app.target == 'esp32':
         dut.expect('Writing EFUSE_BLK_KEY0 with purpose 2')
         dut.expect('Setting CRYPT_CONFIG efuse to 0xF')
         dut.expect('Not disabling UART bootloader encryption')
@@ -79,7 +66,7 @@ def test_examples_efuse_with_virt_flash_enc(env, _):  # type: (ttfw_idf.TinyFW.E
         dut.expect('Disable JTAG...')
         dut.expect('Disable ROM BASIC interpreter fallback...')
     else:
-        if dut.TARGET == 'esp32c2':
+        if dut.app.target == 'esp32c2':
             dut.expect('Writing EFUSE_BLK_KEY0 with purpose 1')
         else:
             dut.expect('Writing EFUSE_BLK_KEY0 with purpose 4')
@@ -93,30 +80,32 @@ def test_examples_efuse_with_virt_flash_enc(env, _):  # type: (ttfw_idf.TinyFW.E
 
     dut.expect('Loading virtual efuse blocks from flash')
     dut.expect('Checking flash encryption...')
-    if dut.TARGET == 'esp32':
-        dut.expect('flash encryption is enabled (3 plaintext flashes left)')
+    if dut.app.target == 'esp32':
+        dut.expect_exact('flash encryption is enabled (3 plaintext flashes left)', timeout=3)
     else:
-        dut.expect('flash encryption is enabled (1 plaintext flashes left)')
+        dut.expect_exact('flash encryption is enabled (1 plaintext flashes left)')
 
-    dut.expect('Flash encryption mode is DEVELOPMENT (not secure)')
+    dut.expect_exact('Flash encryption mode is DEVELOPMENT (not secure)')
     dut.expect('Start eFuse example')
     dut.expect('example: Done')
 
 
-@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32s2'])
-def test_examples_efuse_with_virt_flash_enc_aes_256(env, _):  # type: (ttfw_idf.TinyFW.Env, None) -> None
+@pytest.mark.generic
+@pytest.mark.esp32s2
+@pytest.mark.parametrize('config', ['virt_flash_enc_aes_256',], indirect=True)
+@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True)
+def test_examples_efuse_with_virt_flash_enc_aes_256(dut: Dut) -> None:
     # Only ESP32-S2 has support AES-256 FLASH_ENCRYPTION key
-    dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_flash_enc_aes_256')
     # check and log bin size
     binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin')
     bin_size = os.path.getsize(binary_file)
-    ttfw_idf.log_performance('{}_bootloader_{}_bin_size'.format(dut.app.target, dut.app.config_name), '{}KB'.format(bin_size // 1024))
+    logging.info('{}_bootloader_virt_flash_enc_aes_256_bin_size: {}KB'.format(dut.app.target, bin_size // 1024))
 
     print(' - Erase flash')
-    dut.erase_flash()
+    dut.serial.erase_flash()
 
     print(' - Start app (flash partition_table and app)')
-    dut.start_app_no_enc()
+    dut.serial.write_flash_no_enc()
     dut.expect('Loading virtual efuse blocks from real efuses')
     dut.expect('Checking flash encryption...')
     dut.expect('Generating new flash encryption key...')
@@ -134,52 +123,57 @@ def test_examples_efuse_with_virt_flash_enc_aes_256(env, _):  # type: (ttfw_idf.
 
     dut.expect('Loading virtual efuse blocks from flash')
     dut.expect('Checking flash encryption...')
-    dut.expect('flash encryption is enabled (1 plaintext flashes left)')
+    dut.expect_exact('flash encryption is enabled (1 plaintext flashes left)')
 
-    dut.expect('Flash encryption mode is DEVELOPMENT (not secure)')
+    dut.expect_exact('Flash encryption mode is DEVELOPMENT (not secure)')
     dut.expect('Start eFuse example')
     dut.expect('example: Done')
 
 
-@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32', 'esp32s2', 'esp32c3', 'esp32c2'])
-def test_examples_efuse_with_virt_flash_enc_pre_loaded(env, _):  # type: (ttfw_idf.TinyFW.Env, None) -> None
-    dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_flash_enc')
+@pytest.mark.generic
+@pytest.mark.esp32
+@pytest.mark.esp32c2
+@pytest.mark.esp32c3
+@pytest.mark.esp32s2
+@pytest.mark.parametrize('config', ['virt_flash_enc',], indirect=True)
+@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True)
+def test_examples_efuse_with_virt_flash_enc_pre_loaded(dut: Dut) -> None:
 
     print(' - Erase flash')
-    dut.erase_flash()
+    dut.serial.erase_flash()
 
     print(' - Start app (flash partition_table and app)')
-    dut.start_app_no_enc()
+    dut.serial.write_flash_no_enc()
     dut.expect('Loading virtual efuse blocks from real efuses')
     dut.expect('Flash encryption completed', timeout=90)
     dut.expect('Resetting with flash encryption enabled...')
 
-    dut.expect('Flash encryption mode is DEVELOPMENT (not secure)')
+    dut.expect_exact('Flash encryption mode is DEVELOPMENT (not secure)')
     dut.expect('Start eFuse example')
     dut.expect('example: Done')
 
-    if dut.TARGET == 'esp32':
+    if dut.app.target == 'esp32':
         print(' - Flash emul_efuse with pre-loaded efuses (FLASH_CRYPT_CNT 1 -> 0)')
         # offset of this eFuse is taken from components/efuse/esp32/esp_efuse_table.csv
         FLASH_CRYPT_CNT = 20
         # Resets eFuse, which enables Flash encryption feature
-        erase_field_on_emul_efuse(dut, [FLASH_CRYPT_CNT])
-    elif dut.TARGET == 'esp32c2':
+        dut.serial.erase_field_on_emul_efuse([FLASH_CRYPT_CNT])
+    elif dut.app.target == 'esp32c2':
         FLASH_CRYPT_CNT = 39
-        erase_field_on_emul_efuse(dut, [FLASH_CRYPT_CNT])
+        dut.serial.erase_field_on_emul_efuse([FLASH_CRYPT_CNT])
     else:
         # offset of this eFuse is taken from components/efuse/{target}/esp_efuse_table.csv
         print(' - Flash emul_efuse with pre-loaded efuses (SPI_BOOT_CRYPT_CNT 1 -> 0)')
         SPI_BOOT_CRYPT_CNT = 82
         # Resets eFuse, which enables Flash encryption feature
-        erase_field_on_emul_efuse(dut, [SPI_BOOT_CRYPT_CNT])
+        dut.serial.erase_field_on_emul_efuse([SPI_BOOT_CRYPT_CNT])
 
     print(' - Start app (flash partition_table and app)')
-    dut.start_app_no_enc()
+    dut.serial.write_flash_no_enc()
     dut.expect('Loading virtual efuse blocks from flash')
     dut.expect('Checking flash encryption...')
     dut.expect('Using pre-loaded flash encryption key in efuse')
-    if dut.TARGET == 'esp32':
+    if dut.app.target == 'esp32':
         dut.expect('Setting CRYPT_CONFIG efuse to 0xF')
         dut.expect('Not disabling UART bootloader encryption')
         dut.expect('Disable UART bootloader decryption...')
@@ -197,33 +191,37 @@ def test_examples_efuse_with_virt_flash_enc_pre_loaded(env, _):  # type: (ttfw_i
 
     dut.expect('Loading virtual efuse blocks from flash')
     dut.expect('Checking flash encryption...')
-    if dut.TARGET == 'esp32':
-        dut.expect('flash encryption is enabled (3 plaintext flashes left)')
+    if dut.app.target == 'esp32':
+        dut.expect_exact('flash encryption is enabled (3 plaintext flashes left)')
     else:
-        dut.expect('flash encryption is enabled (1 plaintext flashes left)')
+        dut.expect_exact('flash encryption is enabled (1 plaintext flashes left)')
 
-    dut.expect('Flash encryption mode is DEVELOPMENT (not secure)')
+    dut.expect_exact('Flash encryption mode is DEVELOPMENT (not secure)')
     dut.expect('Start eFuse example')
     dut.expect('example: Done')
 
 
-@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32', 'esp32s2', 'esp32c3', 'esp32c2'])
-def test_examples_efuse_with_virt_flash_enc_release(env, _):  # type: (ttfw_idf.TinyFW.Env, None) -> None
-    dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_flash_enc_release')
+@pytest.mark.generic
+@pytest.mark.esp32
+@pytest.mark.esp32c2
+@pytest.mark.esp32c3
+@pytest.mark.esp32s2
+@pytest.mark.parametrize('config', ['virt_flash_enc_release',], indirect=True)
+@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True)
+def test_examples_efuse_with_virt_flash_enc_release(dut: Dut) -> None:
     # check and log bin size
     binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin')
     bin_size = os.path.getsize(binary_file)
-    ttfw_idf.log_performance('{}_bootloader_{}_bin_size'.format(dut.app.target, dut.app.config_name), '{}KB'.format(bin_size // 1024))
+    logging.info('{}_bootloader_virt_flash_enc_release_bin_size: {}KB'.format(dut.app.target, bin_size // 1024))
 
-    print(' - Erase flash')
-    dut.erase_flash()
+    dut.serial.erase_flash()
 
     print(' - Start app (flash partition_table and app)')
-    dut.start_app_no_enc()
+    dut.serial.write_flash_no_enc()
     dut.expect('Loading virtual efuse blocks from real efuses')
     dut.expect('Checking flash encryption...')
     dut.expect('Generating new flash encryption key...')
-    if dut.TARGET == 'esp32':
+    if dut.app.target == 'esp32':
         dut.expect('Writing EFUSE_BLK_KEY0 with purpose 2')
         dut.expect('Setting CRYPT_CONFIG efuse to 0xF')
         dut.expect('Disable UART bootloader encryption...')
@@ -232,7 +230,7 @@ def test_examples_efuse_with_virt_flash_enc_release(env, _):  # type: (ttfw_idf.
         dut.expect('Disable JTAG...')
         dut.expect('Disable ROM BASIC interpreter fallback...')
     else:
-        if dut.TARGET == 'esp32c2':
+        if dut.app.target == 'esp32c2':
             dut.expect('Writing EFUSE_BLK_KEY0 with purpose 1')
         else:
             dut.expect('Writing EFUSE_BLK_KEY0 with purpose 4')
@@ -247,30 +245,31 @@ def test_examples_efuse_with_virt_flash_enc_release(env, _):  # type: (ttfw_idf.
 
     dut.expect('Loading virtual efuse blocks from flash')
     dut.expect('Checking flash encryption...')
-    dut.expect('flash encryption is enabled (0 plaintext flashes left)')
-
+    dut.expect_exact('flash encryption is enabled (0 plaintext flashes left)', timeout=5)
     dut.expect('Flash encryption mode is RELEASE')
     dut.expect('Start eFuse example')
     dut.expect('example: Done')
 
 
-@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32'])
-def test_examples_efuse_with_virt_secure_boot_v1(env, _):  # type: (ttfw_idf.TinyFW.Env, None) -> None
+@pytest.mark.generic
+@pytest.mark.esp32
+@pytest.mark.parametrize('config', ['virt_secure_boot_v1',], indirect=True)
+@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True)
+def test_examples_efuse_with_virt_secure_boot_v1(dut: Dut) -> None:
     # only for ESP32
-    dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_secure_boot_v1')
     # check and log bin size
     binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin')
     bin_size = os.path.getsize(binary_file)
-    ttfw_idf.log_performance('{}_bootloader_{}_bin_size'.format(dut.app.target, dut.app.config_name), '{}KB'.format(bin_size // 1024))
+    logging.info('{}_bootloader_virt_secure_boot_v1_bin_size: {}KB'.format(dut.app.target, bin_size // 1024))
 
     print(' - Erase flash')
-    dut.erase_flash()
+    dut.serial.erase_flash()
 
     print(' - Flash bootloader')
-    dut.bootloader_flash()
+    dut.serial.bootloader_flash()
 
     print(' - Start app (flash partition_table and app)')
-    dut.start_app()
+    dut.serial.flash()
     dut.expect('Loading virtual efuse blocks from real efuses')
 
     dut.expect('Verifying image signature...')
@@ -290,7 +289,7 @@ def test_examples_efuse_with_virt_secure_boot_v1(env, _):  # type: (ttfw_idf.Tin
     dut.expect('Start eFuse example')
     dut.expect('example: Done')
 
-    dut.reset()
+    dut.serial.hard_reset()
     dut.expect('Loading virtual efuse blocks from flash')
     dut.expect('Verifying image signature...')
     dut.expect('secure_boot_v1: bootloader secure boot is already enabled. No need to generate digest. continuing..')
@@ -300,16 +299,18 @@ def test_examples_efuse_with_virt_secure_boot_v1(env, _):  # type: (ttfw_idf.Tin
     dut.expect('example: Done')
 
 
-@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32'])
-def test_examples_efuse_with_virt_secure_boot_v1_pre_loaded(env, _):  # type: (ttfw_idf.TinyFW.Env, None) -> None
-    # only for ESP32
-    dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_secure_boot_v1')
-
+@pytest.mark.generic
+@pytest.mark.esp32
+@pytest.mark.parametrize('config', ['virt_secure_boot_v1',], indirect=True)
+@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True)
+def test_examples_efuse_with_virt_secure_boot_v1_pre_loaded(dut: Dut) -> None:
     print(' - Erase flash')
-    dut.erase_flash()
+    dut.serial.erase_flash()
+    print(' - Flash bootloader')
+    dut.serial.bootloader_flash()
+    print(' - Start app (flash partition_table and app)')
+    dut.serial.flash()
 
-    dut.bootloader_flash()
-    dut.start_app()
     dut.expect('Loading virtual efuse blocks from real efuses')
     dut.expect('cpu_start: Pro cpu up')
     dut.expect('Loading virtual efuse blocks from flash')
@@ -320,10 +321,10 @@ def test_examples_efuse_with_virt_secure_boot_v1_pre_loaded(env, _):  # type: (t
     # offset of this eFuse is taken from components/efuse/esp32/esp_efuse_table.csv
     ABS_DONE_0 = 196
     # Resets eFuse, which enables Secure boot (V1) feature
-    erase_field_on_emul_efuse(dut, [ABS_DONE_0])
+    dut.serial.erase_field_on_emul_efuse([ABS_DONE_0])
 
     print(' - Start app (flash partition_table and app)')
-    dut.start_app()
+    dut.serial.flash()
     dut.expect('Loading virtual efuse blocks from flash')
 
     dut.expect('Verifying image signature...')
@@ -343,7 +344,7 @@ def test_examples_efuse_with_virt_secure_boot_v1_pre_loaded(env, _):  # type: (t
     dut.expect('Start eFuse example')
     dut.expect('example: Done')
 
-    dut.reset()
+    dut.serial.hard_reset()
     dut.expect('Loading virtual efuse blocks from flash')
     dut.expect('Verifying image signature...')
     dut.expect('secure_boot_v1: bootloader secure boot is already enabled. No need to generate digest. continuing..')
@@ -353,28 +354,26 @@ def test_examples_efuse_with_virt_secure_boot_v1_pre_loaded(env, _):  # type: (t
     dut.expect('example: Done')
 
 
-@ttfw_idf.idf_example_test(env_tag='Example_EthKitV12', target=['esp32'])
-def test_examples_efuse_with_virt_secure_boot_v2(env, _):  # type: (ttfw_idf.TinyFW.Env, None) -> None
+@pytest.mark.esp32
+@pytest.mark.parametrize('config', [('virt_secure_boot_v2.esp32'),], indirect=True)
+@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True)
+def test_examples_efuse_with_virt_secure_boot_v2(dut: Dut) -> None:
     # only for ESP32 ECO3
-    dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_secure_boot_v2.' + env.default_dut_cls.TARGET)
-    # check and log bin size
     binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin')
     bin_size = os.path.getsize(binary_file)
-    ttfw_idf.log_performance('{}_bootloader_{}_bin_size'.format(dut.app.target, dut.app.config_name), '{}KB'.format(bin_size // 1024))
+    logging.info('{}_bootloader_secure_boot_v2_bin_size: {}KB'.format(dut.app.target, bin_size // 1024))
 
     print(' - Erase flash')
-    dut.erase_flash()
-
+    dut.serial.erase_flash()
     print(' - Flash bootloader')
-    dut.bootloader_flash()
-
+    dut.serial.bootloader_flash()
     print(' - Start app (flash partition_table and app)')
-    dut.start_app()
+    dut.serial.flash()
     dut.expect('Loading virtual efuse blocks from real efuses')
 
     dut.expect('Verifying image signature...')
     dut.expect('secure_boot_v2: Secure boot V2 is not enabled yet and eFuse digest keys are not set')
-    dut.expect('secure_boot_v2: Verifying with RSA-PSS...')
+    dut.expect('secure_boot_v2: Verifying with RSA-PSS...', timeout=20)
     dut.expect('secure_boot_v2: Signature verified successfully!')
 
     dut.expect('secure_boot_v2: enabling secure boot v2...')
@@ -384,12 +383,12 @@ def test_examples_efuse_with_virt_secure_boot_v2(env, _):  # type: (ttfw_idf.Tin
     dut.expect('secure_boot_v2: Signature verified successfully!')
     dut.expect('secure_boot_v2: Secure boot digests absent, generating..')
     dut.expect('secure_boot_v2: Digests successfully calculated, 1 valid signatures')
-    dut.expect('secure_boot_v2: 1 signature block(s) found appended to the bootloader')
+    dut.expect_exact('secure_boot_v2: 1 signature block(s) found appended to the bootloader')
 
     dut.expect('Writing EFUSE_BLK_KEY1 with purpose 3')
     dut.expect('secure_boot_v2: Digests successfully calculated, 1 valid signatures')
-    dut.expect('secure_boot_v2: 1 signature block(s) found appended to the app')
-    dut.expect('secure_boot_v2: Application key(0) matches with bootloader key(0)')
+    dut.expect_exact('secure_boot_v2: 1 signature block(s) found appended to the app')
+    dut.expect_exact('secure_boot_v2: Application key(0) matches with bootloader key(0)')
 
     dut.expect('secure_boot_v2: blowing secure boot efuse...')
     dut.expect('Disable JTAG...')
@@ -403,7 +402,7 @@ def test_examples_efuse_with_virt_secure_boot_v2(env, _):  # type: (ttfw_idf.Tin
     dut.expect('Start eFuse example')
     dut.expect('example: Done')
 
-    dut.reset()
+    dut.serial.hard_reset()
     dut.expect('Loading virtual efuse blocks from flash')
     dut.expect('Verifying image signature...')
     dut.expect('secure_boot_v2: Verifying with RSA-PSS...')
@@ -412,19 +411,75 @@ def test_examples_efuse_with_virt_secure_boot_v2(env, _):  # type: (ttfw_idf.Tin
     dut.expect('secure_boot_v2: secure boot v2 is already enabled, continuing..')
     dut.expect('Start eFuse example')
     dut.expect('example: Done')
+    print(' - Erase flash')
+    dut.serial.erase_flash()
 
+    print(' - Flash bootloader and app')
+    dut.serial.bootloader_flash()
+    dut.serial.flash()
+    dut.expect('Loading virtual efuse blocks from real efuses')
+    dut.expect('Loading virtual efuse blocks from flash')
+    dut.expect('Start eFuse example')
+    dut.expect('example: Done')
 
-@ttfw_idf.idf_example_test(env_tag='Example_EthKitV12', target=['esp32'])
-def test_examples_efuse_with_virt_secure_boot_v2_pre_loaded(env, _):  # type: (ttfw_idf.TinyFW.Env, None) -> None
-    # only for ESP32 ECO3
-    dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_secure_boot_v2.' + env.default_dut_cls.TARGET)
+    print(' - Flash emul_efuse with pre-loaded efuses (ABS_DONE_1 1 -> 0)')
+    # offset of this eFuse is taken from components/efuse/esp32/esp_efuse_table.csv
+    ABS_DONE_1 = 197
+    # Resets eFuse, which enables Secure boot (V2) feature
+    dut.serial.erase_field_on_emul_efuse([ABS_DONE_1])
+
+    print(' - Start app (flash partition_table and app)')
+    dut.serial.flash()
+    dut.expect('Loading virtual efuse blocks from flash')
+
+    dut.expect('Verifying image signature...')
+    dut.expect('secure_boot_v2: Verifying with RSA-PSS...')
+    dut.expect('secure_boot_v2: Signature verified successfully!')
+
+    dut.expect('secure_boot_v2: enabling secure boot v2...')
+    dut.expect('Verifying image signature...')
+    dut.expect('secure_boot_v2: Verifying with RSA-PSS...')
+    dut.expect('secure_boot_v2: Signature verified successfully!')
+    dut.expect('secure_boot_v2: Secure boot digests already present')
+    dut.expect('secure_boot_v2: Using pre-loaded public key digest in eFuse')
+    dut.expect('secure_boot_v2: Digests successfully calculated, 1 valid signatures')
+    dut.expect_exact('secure_boot_v2: 1 signature block(s) found appended to the app')
+    dut.expect_exact('secure_boot_v2: Application key(0) matches with bootloader key(0)')
+
+    dut.expect('secure_boot_v2: blowing secure boot efuse...')
+    dut.expect('Disable JTAG...')
+    dut.expect('Disable ROM BASIC interpreter fallback...')
+    dut.expect('UART ROM Download mode kept enabled - SECURITY COMPROMISED')
+    dut.expect('Prevent read disabling of additional efuses...')
+    dut.expect('secure_boot_v2: Secure boot permanently enabled')
+
+    dut.expect('cpu_start: Pro cpu up')
+    dut.expect('Loading virtual efuse blocks from flash')
+    dut.expect('Start eFuse example')
+    dut.expect('example: Done')
+
+    dut.serial.hard_reset()
+    dut.expect('Loading virtual efuse blocks from flash')
+    dut.expect('Verifying image signature...')
+    dut.expect('secure_boot_v2: Verifying with RSA-PSS...')
+    dut.expect('secure_boot_v2: Signature verified successfully!')
+    dut.expect('secure_boot_v2: enabling secure boot v2...')
+    dut.expect('secure_boot_v2: secure boot v2 is already enabled, continuing..')
+    dut.expect('Start eFuse example')
+    dut.expect('example: Done')
+
+
+@pytest.mark.esp32
+@pytest.mark.parametrize('config', [('virt_secure_boot_v2.esp32'),], indirect=True)
+@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True)
+def test_examples_efuse_with_virt_secure_boot_v2_pre_loaded(dut: Dut) -> None:
 
     print(' - Erase flash')
     dut.erase_flash()
-
     print(' - Flash bootloader and app')
     dut.bootloader_flash()
-    dut.start_app()
+    print(' - Start app (flash partition_table and app)')
+    dut.serial.flash()
     dut.expect('Loading virtual efuse blocks from real efuses')
     dut.expect('cpu_start: Pro cpu up')
     dut.expect('Loading virtual efuse blocks from flash')
@@ -435,10 +490,10 @@ def test_examples_efuse_with_virt_secure_boot_v2_pre_loaded(env, _):  # type: (t
     # offset of this eFuse is taken from components/efuse/esp32/esp_efuse_table.csv
     ABS_DONE_1 = 197
     # Resets eFuse, which enables Secure boot (V2) feature
-    erase_field_on_emul_efuse(dut, [ABS_DONE_1])
+    dut.serial.erase_field_on_emul_efuse([ABS_DONE_1])
 
     print(' - Start app (flash partition_table and app)')
-    dut.start_app()
+    dut.serial.flash()
     dut.expect('Loading virtual efuse blocks from flash')
 
     dut.expect('Verifying image signature...')
@@ -452,8 +507,8 @@ def test_examples_efuse_with_virt_secure_boot_v2_pre_loaded(env, _):  # type: (t
     dut.expect('secure_boot_v2: Secure boot digests already present')
     dut.expect('secure_boot_v2: Using pre-loaded public key digest in eFuse')
     dut.expect('secure_boot_v2: Digests successfully calculated, 1 valid signatures')
-    dut.expect('secure_boot_v2: 1 signature block(s) found appended to the app')
-    dut.expect('secure_boot_v2: Application key(0) matches with bootloader key(0)')
+    dut.expect_exact('secure_boot_v2: 1 signature block(s) found appended to the app')
+    dut.expect_exact('secure_boot_v2: Application key(0) matches with bootloader key(0)')
 
     dut.expect('secure_boot_v2: blowing secure boot efuse...')
     dut.expect('Disable JTAG...')
@@ -467,7 +522,7 @@ def test_examples_efuse_with_virt_secure_boot_v2_pre_loaded(env, _):  # type: (t
     dut.expect('Start eFuse example')
     dut.expect('example: Done')
 
-    dut.reset()
+    dut.serial.hard_reset()
     dut.expect('Loading virtual efuse blocks from flash')
     dut.expect('Verifying image signature...')
     dut.expect('secure_boot_v2: Verifying with RSA-PSS...')
@@ -478,27 +533,26 @@ def test_examples_efuse_with_virt_secure_boot_v2_pre_loaded(env, _):  # type: (t
     dut.expect('example: Done')
 
 
-@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32s2', 'esp32c3', 'esp32c2'])
-def test_examples_efuse_with_virt_secure_boot_v2_esp32xx(env, _):  # type: (ttfw_idf.TinyFW.Env, None) -> None
-    dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_secure_boot_v2.' + env.default_dut_cls.TARGET)
+def test_examples_efuse_with_virt_secure_boot_v2_esp32xx(dut: Dut) -> None:
     # check and log bin size
     binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin')
     bin_size = os.path.getsize(binary_file)
-    ttfw_idf.log_performance('{}_bootloader_{}_bin_size'.format(dut.app.target, dut.app.config_name), '{}KB'.format(bin_size // 1024))
+    logging.info('{}_bootloader_virt_secure_boot_v2_bin_size: {}KB'.format(dut.app.target, bin_size // 1024))
 
     print(' - Erase flash')
-    dut.erase_flash()
-
+    dut.serial.erase_flash()
     print(' - Flash bootloader')
-    dut.bootloader_flash()
-
+    dut.serial.bootloader_flash()
     print(' - Start app (flash partition_table and app)')
-    dut.start_app()
+    dut.serial.flash()
     dut.expect('Loading virtual efuse blocks from real efuses')
 
     dut.expect('Verifying image signature...')
     dut.expect('secure_boot_v2: Secure boot V2 is not enabled yet and eFuse digest keys are not set')
-    signed_scheme = 'ECDSA' if dut.TARGET == 'esp32c2' else 'RSA-PSS'
+    if dut.app.target == 'esp32c2':
+        signed_scheme = 'ECDSA'
+    else:
+        signed_scheme = 'RSA-PSS'
     dut.expect('secure_boot_v2: Verifying with %s...' % signed_scheme)
     dut.expect('secure_boot_v2: Signature verified successfully!')
 
@@ -509,18 +563,18 @@ def test_examples_efuse_with_virt_secure_boot_v2_esp32xx(env, _):  # type: (ttfw
     dut.expect('secure_boot_v2: Signature verified successfully!')
     dut.expect('secure_boot_v2: Secure boot digests absent, generating..')
     dut.expect('secure_boot_v2: Digests successfully calculated, 1 valid signatures')
-    dut.expect('secure_boot_v2: 1 signature block(s) found appended to the bootloader')
+    dut.expect_exact('secure_boot_v2: 1 signature block(s) found appended to the bootloader')
 
-    if dut.TARGET == 'esp32c2':
+    if dut.app.target == 'esp32c2':
         dut.expect('Writing EFUSE_BLK_KEY0 with purpose 3')
     else:
         dut.expect('Writing EFUSE_BLK_KEY0 with purpose 9')
     dut.expect('secure_boot_v2: Digests successfully calculated, 1 valid signatures')
-    dut.expect('secure_boot_v2: 1 signature block(s) found appended to the app')
-    dut.expect('secure_boot_v2: Application key(0) matches with bootloader key(0)')
-    if dut.TARGET != 'esp32c2':
-        dut.expect('secure_boot_v2: Revoking empty key digest slot (1)...')
-        dut.expect('secure_boot_v2: Revoking empty key digest slot (2)...')
+    dut.expect_exact('secure_boot_v2: 1 signature block(s) found appended to the app')
+    dut.expect_exact('secure_boot_v2: Application key(0) matches with bootloader key(0)')
+    if dut.app.target != 'esp32c2':
+        dut.expect_exact('secure_boot_v2: Revoking empty key digest slot (1)...')
+        dut.expect_exact('secure_boot_v2: Revoking empty key digest slot (2)...')
     dut.expect('secure_boot_v2: blowing secure boot efuse...')
     dut.expect('UART ROM Download mode kept enabled - SECURITY COMPROMISED')
     dut.expect('Disable hardware & software JTAG...')
@@ -531,7 +585,7 @@ def test_examples_efuse_with_virt_secure_boot_v2_esp32xx(env, _):  # type: (ttfw
     dut.expect('Start eFuse example')
     dut.expect('example: Done')
 
-    dut.reset()
+    dut.serial.hard_reset()
     dut.expect('Loading virtual efuse blocks from flash')
     dut.expect('Verifying image signature...')
     dut.expect('secure_boot_v2: Verifying with %s...' % signed_scheme)
@@ -542,16 +596,37 @@ def test_examples_efuse_with_virt_secure_boot_v2_esp32xx(env, _):  # type: (ttfw
     dut.expect('example: Done')
 
 
-@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32s2', 'esp32c3', 'esp32c2'])
-def test_examples_efuse_with_virt_secure_boot_v2_esp32xx_pre_loaded(env, _):  # type: (ttfw_idf.TinyFW.Env, None) -> None
-    dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_secure_boot_v2.' + env.default_dut_cls.TARGET)
+@pytest.mark.generic
+@pytest.mark.esp32c3
+@pytest.mark.parametrize('config', ['virt_secure_boot_v2.esp32c3'], indirect=True)
+@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True)
+def test_examples_efuse_with_virt_secure_boot_v2_esp32c3(dut: Dut) -> None:
+    test_examples_efuse_with_virt_secure_boot_v2_esp32xx(dut)
+
+
+@pytest.mark.generic
+@pytest.mark.esp32c2
+@pytest.mark.parametrize('config', ['virt_secure_boot_v2.esp32c2'], indirect=True)
+@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True)
+def test_examples_efuse_with_virt_secure_boot_v2_esp32c2(dut: Dut) -> None:
+    test_examples_efuse_with_virt_secure_boot_v2_esp32xx(dut)
 
+
+@pytest.mark.generic
+@pytest.mark.esp32s2
+@pytest.mark.parametrize('config', ['virt_secure_boot_v2.esp32s2'], indirect=True)
+@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True)
+def test_examples_efuse_with_virt_secure_boot_v2_esp32s2(dut: Dut) -> None:
+    test_examples_efuse_with_virt_secure_boot_v2_esp32xx(dut)
+
+
+def test_example_efuse_with_virt_secure_boot_v2_esp32xx_pre_loaded(dut: Dut) -> None:
     print(' - Erase flash')
-    dut.erase_flash()
+    dut.serial.erase_flash()
 
     print(' - Flash bootloader and app')
-    dut.bootloader_flash()
-    dut.start_app()
+    dut.serial.bootloader_flash()
+    dut.serial.flash()
     dut.expect('Loading virtual efuse blocks from real efuses')
     dut.expect('cpu_start: Pro cpu up')
     dut.expect('Loading virtual efuse blocks from flash')
@@ -560,9 +635,9 @@ def test_examples_efuse_with_virt_secure_boot_v2_esp32xx_pre_loaded(env, _):  #
 
     print(' - Flash emul_efuse with pre-loaded efuses (SECURE_BOOT_EN 1 -> 0, SECURE_BOOT_KEY_REVOKE[0..2] -> 0)')
     # offsets of eFuses are taken from components/efuse/{target}/esp_efuse_table.csv
-    if dut.TARGET == 'esp32c2':
+    if dut.app.target == 'esp32c2':
         SECURE_BOOT_EN = 53
-        erase_field_on_emul_efuse(dut, [SECURE_BOOT_EN])
+        dut.serial.erase_field_on_emul_efuse([SECURE_BOOT_EN])
     else:
         SECURE_BOOT_EN = 116
         SECURE_BOOT_KEY_REVOKE0 = 85
@@ -570,36 +645,39 @@ def test_examples_efuse_with_virt_secure_boot_v2_esp32xx_pre_loaded(env, _):  #
         SECURE_BOOT_KEY_REVOKE2 = 87
         # Resets eFuse, which enables Secure boot feature
         # Resets eFuses, which control digest slots
-        erase_field_on_emul_efuse(dut, [SECURE_BOOT_EN, SECURE_BOOT_KEY_REVOKE0, SECURE_BOOT_KEY_REVOKE1, SECURE_BOOT_KEY_REVOKE2])
+        dut.serial.erase_field_on_emul_efuse([SECURE_BOOT_EN, SECURE_BOOT_KEY_REVOKE0, SECURE_BOOT_KEY_REVOKE1, SECURE_BOOT_KEY_REVOKE2])
 
     print(' - Start app (flash partition_table and app)')
-    dut.start_app()
+    dut.serial.flash()
     dut.expect('Loading virtual efuse blocks from flash')
 
     dut.expect('Verifying image signature...')
-    signed_scheme = 'ECDSA' if dut.TARGET == 'esp32c2' else 'RSA-PSS'
+    if dut.app.target == 'esp32c2':
+        signed_scheme = 'ECDSA'
+    else:
+        signed_scheme = 'RSA-PSS'
+
     dut.expect('secure_boot_v2: Verifying with %s...' % signed_scheme)
     dut.expect('secure_boot_v2: Signature verified successfully!')
     dut.expect('secure_boot_v2: Secure boot digests already present')
     dut.expect('secure_boot_v2: Using pre-loaded public key digest in eFuse')
     dut.expect('secure_boot_v2: Digests successfully calculated, 1 valid signatures')
-    dut.expect('secure_boot_v2: 1 signature block(s) found appended to the app')
-    dut.expect('secure_boot_v2: Application key(0) matches with bootloader key(0)')
-    if dut.TARGET != 'esp32c2':
-        dut.expect('secure_boot_v2: Revoking empty key digest slot (1)...')
-        dut.expect('secure_boot_v2: Revoking empty key digest slot (2)...')
+    dut.expect_exact('secure_boot_v2: 1 signature block(s) found appended to the app')
+    if dut.app.target != 'esp32c2':
+        dut.expect_exact('secure_boot_v2: Revoking empty key digest slot (1)...')
+        dut.expect_exact('secure_boot_v2: Revoking empty key digest slot (2)...')
 
     dut.expect('secure_boot_v2: blowing secure boot efuse...')
     dut.expect('UART ROM Download mode kept enabled - SECURITY COMPROMISED')
     dut.expect('Disable hardware & software JTAG...')
-    dut.expect('secure_boot_v2: Secure boot permanently enabled')
+    dut.expect('secure_boot_v2: Secure boot permanently enabled', timeout=20)
 
     dut.expect('cpu_start: Pro cpu up')
     dut.expect('Loading virtual efuse blocks from flash')
     dut.expect('Start eFuse example')
     dut.expect('example: Done')
 
-    dut.reset()
+    dut.serial.hard_reset()
     dut.expect('Loading virtual efuse blocks from flash')
     dut.expect('Verifying image signature...')
     dut.expect('secure_boot_v2: Verifying with %s...' % signed_scheme)
@@ -610,22 +688,48 @@ def test_examples_efuse_with_virt_secure_boot_v2_esp32xx_pre_loaded(env, _):  #
     dut.expect('example: Done')
 
 
-@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32'])
-def test_examples_efuse_with_virt_sb_v1_and_fe(env, _):  # type: (ttfw_idf.TinyFW.Env, None) -> None
-    dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_sb_v1_and_fe')
+@pytest.mark.generic
+@pytest.mark.esp32c3
+@pytest.mark.parametrize('config', ['virt_secure_boot_v2.esp32c3'], indirect=True)
+@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True)
+def test_examples_efuse_with_virt_secure_boot_v2_esp32c3_pre_loaded(dut: Dut) -> None:
+    test_example_efuse_with_virt_secure_boot_v2_esp32xx_pre_loaded(dut)
+
+
+@pytest.mark.generic
+@pytest.mark.esp32c2
+@pytest.mark.parametrize('config', ['virt_secure_boot_v2.esp32c2'], indirect=True)
+@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True)
+def test_examples_efuse_with_virt_secure_boot_v2_esp32c2_pre_loaded(dut: Dut) -> None:
+    test_example_efuse_with_virt_secure_boot_v2_esp32xx_pre_loaded(dut)
+
+
+@pytest.mark.generic
+@pytest.mark.esp32s2
+@pytest.mark.parametrize('config', ['virt_secure_boot_v2.esp32s2'], indirect=True)
+@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True)
+def test_examples_efuse_with_virt_secure_boot_v2_esp32s2_pre_loaded(dut: Dut) -> None:
+    test_example_efuse_with_virt_secure_boot_v2_esp32xx_pre_loaded(dut)
+
+
+@pytest.mark.generic
+@pytest.mark.esp32
+@pytest.mark.parametrize('config', ['virt_sb_v1_and_fe',], indirect=True)
+@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True)
+def test_examples_efuse_with_virt_sb_v1_and_fe(dut: Dut) -> None:
     # check and log bin size
     binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin')
     bin_size = os.path.getsize(binary_file)
-    ttfw_idf.log_performance('{}_bootloader_{}_bin_size'.format(dut.app.target, dut.app.config_name), '{}KB'.format(bin_size // 1024))
+    logging.info('{}_bootloader_virt_sb_v1_and_fe_bin_size: {}KB'.format(dut.app.target, bin_size // 1024))
 
     print(' - Erase flash')
-    dut.erase_flash()
+    dut.serial.erase_flash()
 
     print(' - Flash bootloader')
-    dut.bootloader_flash()
+    dut.serial.bootloader_flash()
 
     print(' - Start app (flash partition_table and app)')
-    dut.start_app_no_enc()
+    dut.serial.write_flash_no_enc()
     dut.expect('Loading virtual efuse blocks from real efuses')
 
     dut.expect('Verifying image signature...')
@@ -660,34 +764,34 @@ def test_examples_efuse_with_virt_sb_v1_and_fe(env, _):  # type: (ttfw_idf.TinyF
     dut.expect('Verifying image signature...')
     dut.expect('secure_boot_v1: bootloader secure boot is already enabled. No need to generate digest. continuing..')
     dut.expect('Checking flash encryption...')
-    dut.expect('flash_encrypt: flash encryption is enabled (3 plaintext flashes left)')
+    dut.expect_exact('flash_encrypt: flash encryption is enabled (3 plaintext flashes left)')
     dut.expect('Checking secure boot...')
     dut.expect('secure_boot_v1: bootloader secure boot is already enabled, continuing..')
 
     dut.expect('cpu_start: Pro cpu up')
     dut.expect('Loading virtual efuse blocks from flash')
-    dut.expect('flash_encrypt: Flash encryption mode is DEVELOPMENT (not secure)')
+    dut.expect_exact('flash_encrypt: Flash encryption mode is DEVELOPMENT (not secure)')
     dut.expect('Start eFuse example')
     dut.expect('example: Done')
 
 
-@ttfw_idf.idf_example_test(env_tag='Example_EthKitV12', target=['esp32'])
-def test_examples_efuse_with_virt_sb_v2_and_fe(env, _):  # type: (ttfw_idf.TinyFW.Env, None) -> None
-    # only for ESP32 ECO3
-    dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_sb_v2_and_fe.' + env.default_dut_cls.TARGET)
+@pytest.mark.esp32
+@pytest.mark.parametrize('config', ['virt_sb_v2_and_fe.esp32',], indirect=True)
+@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True)
+def test_examples_efuse_with_virt_sb_v2_and_fe(dut: Dut) -> None:
     # check and log bin size
     binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin')
     bin_size = os.path.getsize(binary_file)
-    ttfw_idf.log_performance('{}_bootloader_{}_bin_size'.format(dut.app.target, dut.app.config_name), '{}KB'.format(bin_size // 1024))
+    logging.info('{}_bootloader_virt_sb_v2_and_fe_bin_size: {}KB'.format(dut.app.target, bin_size // 1024))
 
     print(' - Erase flash')
-    dut.erase_flash()
+    dut.serial.erase_flash()
 
     print(' - Flash bootloader')
-    dut.bootloader_flash()
+    dut.serial.bootloader_flash()
 
     print(' - Start app (flash partition_table and app)')
-    dut.start_app_no_enc()
+    dut.serial.write_flash_no_enc()
     dut.expect('Loading virtual efuse blocks from real efuses')
 
     dut.expect('secure_boot_v2: Secure boot V2 is not enabled yet and eFuse digest keys are not set')
@@ -701,12 +805,12 @@ def test_examples_efuse_with_virt_sb_v2_and_fe(env, _):  # type: (ttfw_idf.TinyF
     dut.expect('secure_boot_v2: Signature verified successfully')
     dut.expect('secure_boot_v2: Secure boot digests absent, generating..')
     dut.expect('secure_boot_v2: Digests successfully calculated, 1 valid signatures')
-    dut.expect('secure_boot_v2: 1 signature block(s) found appended to the bootloader')
+    dut.expect_exact('secure_boot_v2: 1 signature block(s) found appended to the bootloader')
 
     dut.expect('Writing EFUSE_BLK_KEY1 with purpose 3')
     dut.expect('secure_boot_v2: Digests successfully calculated, 1 valid signatures')
-    dut.expect('secure_boot_v2: 1 signature block(s) found appended to the app')
-    dut.expect('secure_boot_v2: Application key(0) matches with bootloader key(0)')
+    dut.expect_exact('secure_boot_v2: 1 signature block(s) found appended to the app')
+    dut.expect_exact('secure_boot_v2: Application key(0) matches with bootloader key(0)')
 
     dut.expect('secure_boot_v2: blowing secure boot efuse...')
     dut.expect('Disable JTAG...')
@@ -742,35 +846,32 @@ def test_examples_efuse_with_virt_sb_v2_and_fe(env, _):  # type: (ttfw_idf.TinyF
     dut.expect('secure_boot_v2: Signature verified successfully!')
     dut.expect('secure_boot_v2: enabling secure boot v2...')
     dut.expect('secure_boot_v2: secure boot v2 is already enabled, continuing..')
-    dut.expect('flash_encrypt: flash encryption is enabled (3 plaintext flashes left)')
+    dut.expect_exact('flash_encrypt: flash encryption is enabled (3 plaintext flashes left)')
     dut.expect('cpu_start: Pro cpu up')
     dut.expect('Loading virtual efuse blocks from flash')
-    dut.expect('flash_encrypt: Flash encryption mode is DEVELOPMENT (not secure)')
+    dut.expect_exact('flash_encrypt: Flash encryption mode is DEVELOPMENT (not secure)')
     dut.expect('Start eFuse example')
     dut.expect('example: Done')
 
 
-@ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32s2', 'esp32c3', 'esp32c2'])
-def test_examples_efuse_with_virt_sb_v2_and_fe_esp32xx(env, _):  # type: (ttfw_idf.TinyFW.Env, None) -> None
-    dut = env.get_dut('efuse', 'examples/system/efuse', app_config_name='virt_sb_v2_and_fe.' + env.default_dut_cls.TARGET)
+def test_examples_efuse_with_virt_sb_v2_and_fe_esp32xx(dut: Dut) -> None:
     # check and log bin size
     binary_file = os.path.join(dut.app.binary_path, 'bootloader', 'bootloader.bin')
     bin_size = os.path.getsize(binary_file)
-    ttfw_idf.log_performance('{}_bootloader_{}_bin_size'.format(dut.app.target, dut.app.config_name), '{}KB'.format(bin_size // 1024))
+    logging.info('{}_bootloader_virt_sb_v2_and_fe_bin_size: {}KB'.format(dut.app.target, bin_size // 1024))
 
-    print(' - Erase flash')
-    dut.erase_flash()
+    dut.serial.erase_flash()
 
     print(' - Flash bootloader')
-    dut.bootloader_flash()
+    dut.serial.bootloader_flash()
 
     print(' - Start app (flash partition_table and app)')
-    dut.start_app_no_enc()
+    dut.serial.write_flash_no_enc()
     dut.expect('Loading virtual efuse blocks from real efuses')
 
     dut.expect('Verifying image signature...')
     dut.expect('secure_boot_v2: Secure boot V2 is not enabled yet and eFuse digest keys are not set')
-    signed_scheme = 'ECDSA' if dut.TARGET == 'esp32c2' else 'RSA-PSS'
+    signed_scheme = 'ECDSA' if dut.app.target == 'esp32c2' else 'RSA-PSS'
     dut.expect('secure_boot_v2: Verifying with %s...' % signed_scheme)
     dut.expect('secure_boot_v2: Signature verified successfully!')
 
@@ -781,28 +882,28 @@ def test_examples_efuse_with_virt_sb_v2_and_fe_esp32xx(env, _):  # type: (ttfw_i
     dut.expect('secure_boot_v2: Signature verified successfully!')
     dut.expect('secure_boot_v2: Secure boot digests absent, generating..')
     dut.expect('secure_boot_v2: Digests successfully calculated, 1 valid signatures')
-    dut.expect('secure_boot_v2: 1 signature block(s) found appended to the bootloader')
+    dut.expect_exact('secure_boot_v2: 1 signature block(s) found appended to the bootloader')
 
-    if dut.TARGET == 'esp32c2':
+    if dut.app.target == 'esp32c2':
         dut.expect('Writing EFUSE_BLK_KEY0 with purpose 3')
     else:
         dut.expect('Writing EFUSE_BLK_KEY0 with purpose 9')
     dut.expect('secure_boot_v2: Digests successfully calculated, 1 valid signatures')
-    dut.expect('secure_boot_v2: 1 signature block(s) found appended to the app')
-    dut.expect('secure_boot_v2: Application key(0) matches with bootloader key(0)')
-    if dut.TARGET != 'esp32c2':
-        dut.expect('secure_boot_v2: Revoking empty key digest slot (1)...')
-        dut.expect('secure_boot_v2: Revoking empty key digest slot (2)...')
+    dut.expect_exact('secure_boot_v2: 1 signature block(s) found appended to the app')
+    dut.expect_exact('secure_boot_v2: Application key(0) matches with bootloader key(0)')
+    if dut.app.target != 'esp32c2':
+        dut.expect_exact('secure_boot_v2: Revoking empty key digest slot (1)...')
+        dut.expect_exact('secure_boot_v2: Revoking empty key digest slot (2)...')
     dut.expect('secure_boot_v2: blowing secure boot efuse...')
     dut.expect('UART ROM Download mode kept enabled - SECURITY COMPROMISED')
     dut.expect('Disable hardware & software JTAG...')
 
-    if dut.TARGET != 'esp32c2':
+    if dut.app.target != 'esp32c2':
         dut.expect('secure_boot_v2: Secure boot permanently enabled')
 
     dut.expect('Checking flash encryption...')
     dut.expect('flash_encrypt: Generating new flash encryption key...')
-    if dut.TARGET == 'esp32c2':
+    if dut.app.target == 'esp32c2':
         dut.expect('Writing EFUSE_BLK_KEY0 with purpose 2')
     else:
         dut.expect('Writing EFUSE_BLK_KEY1 with purpose 4')
@@ -811,7 +912,7 @@ def test_examples_efuse_with_virt_sb_v2_and_fe_esp32xx(env, _):  # type: (ttfw_i
     dut.expect('Disable UART bootloader cache...')
     dut.expect('Disable JTAG...')
 
-    if dut.TARGET == 'esp32c2':
+    if dut.app.target == 'esp32c2':
         dut.expect('boot: Secure boot permanently enabled')
 
     dut.expect('Verifying image signature...')
@@ -832,26 +933,30 @@ def test_examples_efuse_with_virt_sb_v2_and_fe_esp32xx(env, _):  # type: (ttfw_i
     dut.expect('secure_boot_v2: Signature verified successfully!')
     dut.expect('secure_boot_v2: enabling secure boot v2...')
     dut.expect('secure_boot_v2: secure boot v2 is already enabled, continuing..')
-    dut.expect('flash_encrypt: flash encryption is enabled (1 plaintext flashes left)')
+    dut.expect_exact('flash_encrypt: flash encryption is enabled (1 plaintext flashes left)')
     dut.expect('cpu_start: Pro cpu up')
     dut.expect('Loading virtual efuse blocks from flash')
-    dut.expect('flash_encrypt: Flash encryption mode is DEVELOPMENT (not secure)')
+    dut.expect_exact('flash_encrypt: Flash encryption mode is DEVELOPMENT (not secure)')
     dut.expect('Start eFuse example')
     dut.expect('example: Done')
 
 
-if __name__ == '__main__':
-    test_examples_efuse()
-    test_examples_efuse_with_virt_flash_enc()
-    test_examples_efuse_with_virt_flash_enc_pre_loaded()
-    test_examples_efuse_with_virt_flash_enc_aes_256()
-    test_examples_efuse_with_virt_flash_enc_release()
-    test_examples_efuse_with_virt_secure_boot_v1()
-    test_examples_efuse_with_virt_secure_boot_v1_pre_loaded()
-    test_examples_efuse_with_virt_secure_boot_v2()
-    test_examples_efuse_with_virt_secure_boot_v2_pre_loaded()
-    test_examples_efuse_with_virt_secure_boot_v2_esp32xx()
-    test_examples_efuse_with_virt_secure_boot_v2_esp32xx_pre_loaded()
-    test_examples_efuse_with_virt_sb_v1_and_fe()
-    test_examples_efuse_with_virt_sb_v2_and_fe()
-    test_examples_efuse_with_virt_sb_v2_and_fe_esp32xx()
+@pytest.mark.esp32c3
+@pytest.mark.parametrize('config', ['virt_sb_v2_and_fe.esp32c3'], indirect=True)
+@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True)
+def test_examples_efuse_with_virt_sb_v2_and_fe_esp32c3(dut: Dut) -> None:
+    test_examples_efuse_with_virt_sb_v2_and_fe_esp32xx(dut)
+
+
+@pytest.mark.esp32c2
+@pytest.mark.parametrize('config', ['virt_sb_v2_and_fe.esp32c2'], indirect=True)
+@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True)
+def test_examples_efuse_with_virt_sb_v2_and_fe_esp32c2(dut: Dut) -> None:
+    test_examples_efuse_with_virt_sb_v2_and_fe_esp32xx(dut)
+
+
+@pytest.mark.esp32s2
+@pytest.mark.parametrize('config', ['virt_sb_v2_and_fe.esp32s2'], indirect=True)
+@pytest.mark.parametrize('skip_autoflash', ['y'], indirect=True)
+def test_examples_efuse_with_virt_sb_v2_and_fe_esp32s2(dut: Dut) -> None:
+    test_examples_efuse_with_virt_sb_v2_and_fe_esp32xx(dut)