1# Unit tests (really integration tests) for esptool.py using the pytest framework
2# Uses a device in the Secure Download Mode connected to the serial port.
3#
4# RUNNING THIS WILL MESS UP THE DEVICE'S SPI FLASH CONTENTS
5#
6# How to use:
7#
8# Run with a physical connection to a chip:
9#  - `pytest test_esptool_sdm.py --chip esp32 --port /dev/ttyUSB0 --baud 115200`
10#
11# where  - --port       - a serial port for esptool.py operation
12#        - --chip       - ESP chip name
13#        - --baud       - baud rate
14#        - --with-trace - trace all interactions (True or False)
15
16from test_esptool import EsptoolTestCase, arg_chip, esptool, pytest
17
18
19@pytest.mark.skipif(
20    arg_chip == "esp8266", reason="ESP8266 does not support Secure Download Mode"
21)
22class TestSecureDownloadMode(EsptoolTestCase):
23    expected_chip_name = esptool.util.expand_chip_name(arg_chip)
24
25    def test_auto_detect(self):
26        output = self.run_esptool_error("flash_id", chip="auto")
27
28        if arg_chip in ["esp32", "esp32s2"]:  # no autodetection with get_security_info
29            assert "Secure Download Mode is enabled" in output
30            assert "Unsupported detection protocol" in output
31        else:
32            assert "Unsupported detection protocol" not in output
33            assert f"Detecting chip type... {self.expected_chip_name}" in output
34            assert "Stub loader is not supported in Secure Download Mode" in output
35            assert (
36                f"Chip is {self.expected_chip_name} in Secure Download Mode" in output
37            )
38
39    # Commands not supported in SDM
40    def test_sdm_incompatible_commands(self):
41        output = self.run_esptool_error("flash_id")  # flash_id
42        assert "This command (0xa) is not supported in Secure Download Mode" in output
43
44        output = self.run_esptool_error("read_flash 0 10 out.bin")  # read_flash
45        assert "This command (0xe) is not supported in Secure Download Mode" in output
46
47        output = self.run_esptool_error("erase_flash")  # erase_flash
48        assert (
49            f"{self.expected_chip_name} ROM does not support function erase_flash"
50            in output
51        )
52
53    # Commands supported in SDM
54    def test_sdm_compatible_commands(self):
55        output = self.run_esptool("write_flash 0x0 images/one_kb.bin")  # write_flash
56        assert "Security features enabled, so not changing any flash settings" in output
57        assert "Wrote 1024 bytes" in output
58        assert "Hash of data verified." not in output  # Verification not supported
59
60        output = self.run_esptool_error(
61            "write_flash --flash_size detect 0x0 images/one_kb.bin"
62        )
63        assert (
64            "Detecting flash size is not supported in secure download mode." in output
65        )
66
67        if arg_chip != "esp32":  # esp32 does not support get_security_info
68            output = self.run_esptool("get_security_info")  # get_security_info
69            assert "Security Information:" in output
70