Merge branch 'esp8266-native-build-infra' into esp8266-native-framework-installer

This commit is contained in:
J. Nick Koston
2026-08-22 21:24:07 -05:00
80 changed files with 352 additions and 578 deletions
+24 -4
View File
@@ -6,6 +6,8 @@ from collections.abc import Generator
import gzip
import hashlib
import io
import itertools
import logging
from pathlib import Path
import socket
import struct
@@ -53,8 +55,9 @@ def mock_sleep() -> Generator[Mock]:
@pytest.fixture
def mock_time(mock_sleep: Mock) -> Generator[None]:
"""Mock time-related functions for consistent testing."""
# Provide enough values for multiple calls (tests may call perform_ota multiple times)
with patch("time.perf_counter", side_effect=[0, 1, 0, 1, 0, 1]):
# Monotonically increasing, never exhausted regardless of how many timing
# windows perform_ota measures or how many times a test calls it
with patch("time.perf_counter", side_effect=itertools.count()):
yield
@@ -372,7 +375,9 @@ def test_perform_ota_successful_md5_auth(
@pytest.mark.usefixtures("mock_time")
def test_perform_ota_no_auth(mock_socket: Mock, mock_file: io.BytesIO) -> None:
def test_perform_ota_no_auth(
mock_socket: Mock, mock_file: io.BytesIO, caplog: pytest.LogCaptureFixture
) -> None:
"""Test OTA without authentication."""
recv_responses = [
bytes([espota2.RESPONSE_OK]), # First byte of version response
@@ -387,7 +392,14 @@ def test_perform_ota_no_auth(mock_socket: Mock, mock_file: io.BytesIO) -> None:
mock_socket.recv.side_effect = recv_responses
espota2.perform_ota(mock_socket, None, mock_file, "test.bin")
# Distinct window lengths pin each duration to its label; exactly the 6
# expected perf_counter calls, so an unaccounted timing window raises
timings = [0.0, 2.0, 10.0, 15.0, 20.0, 27.0]
with (
patch("time.perf_counter", side_effect=timings),
caplog.at_level(logging.INFO),
):
espota2.perform_ota(mock_socket, None, mock_file, "test.bin")
# Should not send any auth-related data
auth_calls = [
@@ -397,6 +409,14 @@ def test_perform_ota_no_auth(mock_socket: Mock, mock_file: io.BytesIO) -> None:
]
assert len(auth_calls) == 0
# The timing summary is the observable output of the upload; exact strings
# pin each duration to its label
assert "Preparing for upload took 2.00 seconds" in caplog.text
assert (
"Update took 14.00 seconds (prepare 2.00, upload 5.00, commit 7.00)"
in caplog.text
)
@pytest.mark.usefixtures("mock_time")
def test_perform_ota_with_compression(mock_socket: Mock) -> None: