mirror of
https://github.com/esphome/esphome.git
synced 2026-11-02 03:16:40 +00:00
118 lines
4.6 KiB
Python
118 lines
4.6 KiB
Python
"""Integration test for the script on_stop trigger, script.stop without an id, and the choose action."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import asyncio
|
|
|
|
from aioesphomeapi import UserService
|
|
import pytest
|
|
|
|
from .types import APIClientConnectedFactory, RunCompiledFunction
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_script_on_stop_and_choose(
|
|
yaml_config: str,
|
|
run_compiled: RunCompiledFunction,
|
|
api_client_connected: APIClientConnectedFactory,
|
|
) -> None:
|
|
"""Test on_stop, self-stopping scripts and choose."""
|
|
lines: list[str] = []
|
|
waiters: list[tuple[str, asyncio.Future[None]]] = []
|
|
|
|
def check_output(line: str) -> None:
|
|
lines.append(line)
|
|
for text, future in waiters:
|
|
if text in line and not future.done():
|
|
future.set_result(None)
|
|
|
|
def expect(text: str) -> asyncio.Future[None]:
|
|
future: asyncio.Future[None] = asyncio.get_running_loop().create_future()
|
|
waiters.append((text, future))
|
|
return future
|
|
|
|
def count(text: str) -> int:
|
|
return sum(text in line for line in lines)
|
|
|
|
async with (
|
|
run_compiled(yaml_config, line_callback=check_output),
|
|
api_client_connected() as client,
|
|
):
|
|
_, services = await client.list_entities_services()
|
|
service: dict[str, UserService] = {s.name: s for s in services}
|
|
|
|
# choose runs only the first choice whose condition is true, or the else
|
|
# choice if none is, then continues
|
|
for value, label in (
|
|
(5, "small"),
|
|
(50, "medium"),
|
|
(500, "large"),
|
|
(5000, "default"),
|
|
):
|
|
done = expect(f"CHOOSE done {value}")
|
|
await client.execute_service(service["run_choose"], {"value": value})
|
|
await asyncio.wait_for(done, timeout=5.0)
|
|
assert count(f"CHOOSE {label} {value}") == 1
|
|
assert count("CHOOSE small") == 1
|
|
assert count("CHOOSE medium") == 1
|
|
assert count("CHOOSE large") == 1
|
|
assert count("CHOOSE default") == 1
|
|
|
|
# A bare script.stop inside a script stops that script and fires on_stop
|
|
stopped = expect("SELF on_stop")
|
|
await client.execute_service(service["run_self_stop"], {})
|
|
await asyncio.wait_for(stopped, timeout=5.0)
|
|
|
|
# Stopping a running script from outside fires on_stop
|
|
stopped = expect("LONG on_stop")
|
|
await client.execute_service(service["run_external_stop"], {})
|
|
await asyncio.wait_for(stopped, timeout=5.0)
|
|
|
|
# Stopping a script that is not running does not fire on_stop
|
|
idle_done = expect("IDLE stop done")
|
|
await client.execute_service(service["run_idle_stop"], {})
|
|
await asyncio.wait_for(idle_done, timeout=5.0)
|
|
|
|
# Restarting a running script stops the old run early
|
|
finished = expect("RESTART finished")
|
|
await client.execute_service(service["run_restart"], {})
|
|
await asyncio.wait_for(finished, timeout=5.0)
|
|
|
|
# A script that finishes normally does not fire on_stop
|
|
finished = expect("NORMAL finished")
|
|
await client.execute_service(service["run_normal"], {})
|
|
await asyncio.wait_for(finished, timeout=5.0)
|
|
|
|
# A restart script whose on_stop executes it again ends up with one run
|
|
finished = expect("REENTER finished")
|
|
await client.execute_service(service["run_reenter"], {})
|
|
await asyncio.wait_for(finished, timeout=5.0)
|
|
|
|
# Stopping several parallel runs fires on_stop once
|
|
done = expect("PARALLEL stop done")
|
|
await client.execute_service(service["run_parallel_stop"], {})
|
|
await asyncio.wait_for(done, timeout=5.0)
|
|
|
|
# Stopping a queued script fires on_stop once and drops the queued run
|
|
done = expect("QUEUED stop done")
|
|
await client.execute_service(service["run_queued_stop"], {})
|
|
await asyncio.wait_for(done, timeout=5.0)
|
|
await asyncio.sleep(0.2)
|
|
|
|
assert count("SELF not reached") == 0
|
|
assert count("SELF on_stop") == 1
|
|
assert count("LONG finished") == 0
|
|
assert count("LONG on_stop") == 1
|
|
assert count("RESTART start") == 2
|
|
assert count("RESTART on_stop") == 1
|
|
assert count("RESTART finished") == 1
|
|
assert count("NORMAL on_stop") == 0
|
|
assert count("REENTER on_stop") == 1
|
|
assert count("REENTER start") == 3
|
|
assert count("REENTER finished") == 1
|
|
assert count("PARALLEL on_stop") == 1
|
|
assert count("PARALLEL finished") == 0
|
|
assert count("QUEUED on_stop") == 1
|
|
assert count("QUEUED start") == 1
|
|
assert count("QUEUED finished") == 0
|