mirror of
https://github.com/esphome/esphome.git
synced 2026-10-07 11:26:39 +00:00
[script] Disable queued script polling while the queue is empty (#18121)
This commit is contained in:
@@ -26,6 +26,7 @@ async def test_script_queued(
|
||||
"stop": {"processed": [], "stop_logged": False},
|
||||
"rejection": {"processed": [], "rejections": 0},
|
||||
"no_params": {"executions": 0},
|
||||
"boot": {"ended": []},
|
||||
}
|
||||
|
||||
# Patterns for Test 1: Queue depth
|
||||
@@ -49,12 +50,21 @@ async def test_script_queued(
|
||||
# Patterns for Test 5: No params
|
||||
no_params_end = re.compile(r"No params: END")
|
||||
|
||||
# Patterns for boot script (executed twice from on_boot before setup)
|
||||
boot_end = re.compile(r"Boot queued: END (\d+)")
|
||||
|
||||
# Patterns for Test 6: Re-execute after stop
|
||||
after_stop_end = re.compile(r"Stop test: END (\d+)")
|
||||
|
||||
# Test completion futures
|
||||
boot_complete = loop.create_future()
|
||||
test1_complete = loop.create_future()
|
||||
test2_complete = loop.create_future()
|
||||
test3_complete = loop.create_future()
|
||||
test4_complete = loop.create_future()
|
||||
test5_complete = loop.create_future()
|
||||
test5_again_complete = loop.create_future()
|
||||
test6_complete = loop.create_future()
|
||||
|
||||
def check_output(line: str) -> None:
|
||||
"""Check log output for all test messages."""
|
||||
@@ -122,11 +132,24 @@ async def test_script_queued(
|
||||
# Test 5: No params
|
||||
if no_params_end.search(line):
|
||||
test_results["no_params"]["executions"] += 1
|
||||
if (
|
||||
test_results["no_params"]["executions"] == 3
|
||||
and not test5_complete.done()
|
||||
):
|
||||
test5_complete.set_result(True)
|
||||
executions = test_results["no_params"]["executions"]
|
||||
for count, future in ((3, test5_complete), (6, test5_again_complete)):
|
||||
if executions == count and not future.done():
|
||||
future.set_result(True)
|
||||
|
||||
# Boot script (queued from on_boot before setup)
|
||||
if match := boot_end.search(line):
|
||||
test_results["boot"]["ended"].append(int(match.group(1)))
|
||||
if len(test_results["boot"]["ended"]) == 2 and not boot_complete.done():
|
||||
boot_complete.set_result(True)
|
||||
|
||||
# Test 6: Re-execute after stop
|
||||
if (
|
||||
(match := after_stop_end.search(line))
|
||||
and int(match.group(1)) == 9
|
||||
and not test6_complete.done()
|
||||
):
|
||||
test6_complete.set_result(True)
|
||||
|
||||
async with (
|
||||
run_compiled(yaml_config, line_callback=check_output),
|
||||
@@ -135,6 +158,13 @@ async def test_script_queued(
|
||||
# Get services
|
||||
_, services = await client.list_entities_services()
|
||||
|
||||
# Boot: both executions from on_boot must complete, including the one
|
||||
# that was queued before QueueingScript::setup() ran
|
||||
await asyncio.wait_for(boot_complete, timeout=2.0)
|
||||
assert sorted(test_results["boot"]["ended"]) == [1, 2], (
|
||||
f"Boot: Expected both on_boot executions to complete, got {sorted(test_results['boot']['ended'])}"
|
||||
)
|
||||
|
||||
# Test 1: Queue depth limit
|
||||
test_service = next((s for s in services if s.name == "test_queue_depth"), None)
|
||||
assert test_service is not None, "test_queue_depth service not found"
|
||||
@@ -203,3 +233,20 @@ async def test_script_queued(
|
||||
assert test_results["no_params"]["executions"] == 3, (
|
||||
f"Test 5: Expected 3 executions, got {test_results['no_params']['executions']}"
|
||||
)
|
||||
|
||||
# Test 5 again: after the queue fully drained (loop disabled while
|
||||
# idle), executing again must still work
|
||||
test_service = next((s for s in services if s.name == "test_no_params"), None)
|
||||
assert test_service is not None, "test_no_params service not found"
|
||||
await client.execute_service(test_service, {})
|
||||
await asyncio.wait_for(test5_again_complete, timeout=2.0)
|
||||
assert test_results["no_params"]["executions"] == 6, (
|
||||
f"Test 5 again: Expected 6 executions total, got {test_results['no_params']['executions']}"
|
||||
)
|
||||
|
||||
# Test 6: a stopped script (queue cleared, loop disabled) must run
|
||||
# again on the next execute; the future resolves only on "END 9"
|
||||
test_service = next((s for s in services if s.name == "test_after_stop"), None)
|
||||
assert test_service is not None, "test_after_stop service not found"
|
||||
await client.execute_service(test_service, {})
|
||||
await asyncio.wait_for(test6_complete, timeout=2.0)
|
||||
|
||||
Reference in New Issue
Block a user