diff --git a/tests/integration/fixtures/scheduler_numeric_id_test.yaml b/tests/integration/fixtures/scheduler_numeric_id_test.yaml index f8265a7832..29b547d66d 100644 --- a/tests/integration/fixtures/scheduler_numeric_id_test.yaml +++ b/tests/integration/fixtures/scheduler_numeric_id_test.yaml @@ -17,6 +17,9 @@ globals: - id: interval_counter type: int initial_value: '0' + - id: retry_counter + type: int + initial_value: '0' - id: tests_done type: bool initial_value: 'false' @@ -109,11 +112,33 @@ script: id(timeout_counter) += 1; }); + // Test 10: set_retry with numeric ID + App.scheduler.set_retry(component1, 6001U, 50, 3, + [](uint8_t retry_countdown) { + id(retry_counter)++; + ESP_LOGI("test", "Numeric retry 6001 attempt %d (countdown=%d)", + id(retry_counter), retry_countdown); + if (id(retry_counter) >= 2) { + ESP_LOGI("test", "Numeric retry 6001 done"); + return RetryResult::DONE; + } + return RetryResult::RETRY; + }); + + // Test 11: cancel_retry with numeric ID + App.scheduler.set_retry(component1, 6002U, 100, 5, + [](uint8_t retry_countdown) { + ESP_LOGE("test", "ERROR: Numeric retry 6002 should have been cancelled"); + return RetryResult::RETRY; + }); + App.scheduler.cancel_retry(component1, 6002U); + ESP_LOGI("test", "Cancelled numeric retry 6002"); + - id: report_results then: - lambda: |- - ESP_LOGI("test", "Final results - Timeouts: %d, Intervals: %d", - id(timeout_counter), id(interval_counter)); + ESP_LOGI("test", "Final results - Timeouts: %d, Intervals: %d, Retries: %d", + id(timeout_counter), id(interval_counter), id(retry_counter)); sensor: - platform: template diff --git a/tests/integration/fixtures/scheduler_retry_test.yaml b/tests/integration/fixtures/scheduler_retry_test.yaml index 11fff6c395..ffe9082a69 100644 --- a/tests/integration/fixtures/scheduler_retry_test.yaml +++ b/tests/integration/fixtures/scheduler_retry_test.yaml @@ -43,9 +43,6 @@ globals: - id: static_char_retry_counter type: int initial_value: '0' - - id: mixed_cancel_result - type: bool - initial_value: 'false' # Using different component types for each test to ensure isolation sensor: @@ -271,23 +268,6 @@ script: ESP_LOGI("test", "Static cancel result: %s", result ? "true" : "false"); }); - # Test 10: Mix string and const char* cancel - - logger.log: "=== Test 10: Mixed string/const char* ===" - - lambda: |- - auto *component = id(immediate_done_sensor); - - // Set with std::string - std::string str_name = "mixed_retry"; - App.scheduler.set_retry(component, str_name, 40, 3, - [](uint8_t retry_countdown) { - ESP_LOGI("test", "Mixed retry - should be cancelled"); - return RetryResult::RETRY; - }); - - // Cancel with const char* - id(mixed_cancel_result) = App.scheduler.cancel_retry(component, "mixed_retry"); - ESP_LOGI("test", "Mixed cancel result: %s", id(mixed_cancel_result) ? "true" : "false"); - # Wait for all tests to complete before reporting - delay: 500ms @@ -303,5 +283,4 @@ script: ESP_LOGI("test", "Multiple same name counter: %d (expected 20+)", id(multiple_same_name_counter)); ESP_LOGI("test", "Const char retry counter: %d (expected 1)", id(const_char_retry_counter)); ESP_LOGI("test", "Static char retry counter: %d (expected 1)", id(static_char_retry_counter)); - ESP_LOGI("test", "Mixed cancel result: %s (expected true)", id(mixed_cancel_result) ? "true" : "false"); ESP_LOGI("test", "All retry tests completed"); diff --git a/tests/integration/test_scheduler_numeric_id_test.py b/tests/integration/test_scheduler_numeric_id_test.py index e56d889cd1..510256b9a4 100644 --- a/tests/integration/test_scheduler_numeric_id_test.py +++ b/tests/integration/test_scheduler_numeric_id_test.py @@ -18,6 +18,7 @@ async def test_scheduler_numeric_id_test( # Track counts timeout_count = 0 interval_count = 0 + retry_count = 0 # Events for each test completion numeric_timeout_1001_fired = asyncio.Event() @@ -30,13 +31,17 @@ async def test_scheduler_numeric_id_test( component_interval_fired = asyncio.Event() zero_id_timeout_fired = asyncio.Event() max_id_timeout_fired = asyncio.Event() + numeric_retry_done = asyncio.Event() + numeric_retry_cancelled = asyncio.Event() final_results_logged = asyncio.Event() # Track interval counts numeric_interval_count = 0 + numeric_retry_count = 0 def on_log_line(line: str) -> None: - nonlocal timeout_count, interval_count, numeric_interval_count + nonlocal timeout_count, interval_count, retry_count + nonlocal numeric_interval_count, numeric_retry_count # Strip ANSI color codes clean_line = re.sub(r"\x1b\[[0-9;]*m", "", line) @@ -88,12 +93,27 @@ async def test_scheduler_numeric_id_test( max_id_timeout_fired.set() timeout_count += 1 + # Check for numeric retry tests + elif "Numeric retry 6001 attempt" in clean_line: + match = re.search(r"attempt (\d+)", clean_line) + if match: + numeric_retry_count = int(match.group(1)) + + elif "Numeric retry 6001 done" in clean_line: + numeric_retry_done.set() + + elif "Cancelled numeric retry 6002" in clean_line: + numeric_retry_cancelled.set() + # Check for final results elif "Final results" in clean_line: - match = re.search(r"Timeouts: (\d+), Intervals: (\d+)", clean_line) + match = re.search( + r"Timeouts: (\d+), Intervals: (\d+), Retries: (\d+)", clean_line + ) if match: timeout_count = int(match.group(1)) interval_count = int(match.group(2)) + retry_count = int(match.group(3)) final_results_logged.set() async with ( @@ -164,6 +184,23 @@ async def test_scheduler_numeric_id_test( except TimeoutError: pytest.fail("Max ID timeout did not fire within 0.5 seconds") + # Wait for numeric retry tests + try: + await asyncio.wait_for(numeric_retry_done.wait(), timeout=1.0) + except TimeoutError: + pytest.fail( + f"Numeric retry 6001 did not complete. Count: {numeric_retry_count}" + ) + + assert numeric_retry_count >= 2, ( + f"Expected at least 2 numeric retry attempts, got {numeric_retry_count}" + ) + + # Verify numeric retry was cancelled + assert numeric_retry_cancelled.is_set(), ( + "Numeric retry 6002 should have been cancelled" + ) + # Wait for final results try: await asyncio.wait_for(final_results_logged.wait(), timeout=3.0) @@ -175,3 +212,6 @@ async def test_scheduler_numeric_id_test( assert interval_count >= 3, ( f"Expected at least 3 interval fires, got {interval_count}" ) + assert retry_count >= 2, ( + f"Expected at least 2 retry attempts, got {retry_count}" + ) diff --git a/tests/integration/test_scheduler_retry_test.py b/tests/integration/test_scheduler_retry_test.py index c04b7197c9..910034e5bb 100644 --- a/tests/integration/test_scheduler_retry_test.py +++ b/tests/integration/test_scheduler_retry_test.py @@ -25,7 +25,6 @@ async def test_scheduler_retry_test( multiple_name_done = asyncio.Event() const_char_done = asyncio.Event() static_char_done = asyncio.Event() - mixed_cancel_done = asyncio.Event() test_complete = asyncio.Event() # Track retry counts @@ -42,14 +41,13 @@ async def test_scheduler_retry_test( # Track specific test results cancel_result = None empty_cancel_result = None - mixed_cancel_result = None backoff_intervals = [] def on_log_line(line: str) -> None: nonlocal simple_retry_count, backoff_retry_count, immediate_done_count nonlocal cancel_retry_count, empty_name_retry_count, component_retry_count nonlocal multiple_name_count, const_char_retry_count, static_char_retry_count - nonlocal cancel_result, empty_cancel_result, mixed_cancel_result + nonlocal cancel_result, empty_cancel_result # Strip ANSI color codes clean_line = re.sub(r"\x1b\[[0-9;]*m", "", line) @@ -129,11 +127,6 @@ async def test_scheduler_retry_test( # This is part of test 9, but we don't track it separately pass - # Mixed cancel test - elif "Mixed cancel result:" in clean_line: - mixed_cancel_result = "true" in clean_line - mixed_cancel_done.set() - # Test completion elif "All retry tests completed" in clean_line: test_complete.set() @@ -279,16 +272,6 @@ async def test_scheduler_retry_test( f"Expected 1 static char retry call, got {static_char_retry_count}" ) - # Wait for mixed cancel test - try: - await asyncio.wait_for(mixed_cancel_done.wait(), timeout=1.0) - except TimeoutError: - pytest.fail("Mixed cancel test did not complete") - - assert mixed_cancel_result is True, ( - "Mixed string/const char cancel should have succeeded" - ) - # Wait for test completion try: await asyncio.wait_for(test_complete.wait(), timeout=1.0)