1
0
mirror of https://github.com/esphome/esphome.git synced 2025-09-06 13:22:19 +01:00
Files
esphome/tests/unit_tests/test_coroutine.py

205 lines
6.4 KiB
Python

"""Tests for the coroutine module."""
import pytest
from esphome.coroutine import CoroPriority, FakeEventLoop, coroutine_with_priority
def test_coro_priority_enum_values() -> None:
"""Test that CoroPriority enum values match expected priorities."""
assert CoroPriority.PLATFORM == 1000
assert CoroPriority.NETWORK == 201
assert CoroPriority.NETWORK_TRANSPORT == 200
assert CoroPriority.CORE == 100
assert CoroPriority.DIAGNOSTICS == 90
assert CoroPriority.STATUS == 80
assert CoroPriority.COMMUNICATION == 60
assert CoroPriority.APPLICATION == 50
assert CoroPriority.WEB == 40
assert CoroPriority.AUTOMATION == 30
assert CoroPriority.BUS == 1
assert CoroPriority.COMPONENT == 0
assert CoroPriority.LATE == -100
assert CoroPriority.WORKAROUNDS == -999
assert CoroPriority.FINAL == -1000
def test_coroutine_with_priority_accepts_float() -> None:
"""Test that coroutine_with_priority accepts float values."""
@coroutine_with_priority(100.0)
def test_func() -> None:
pass
assert hasattr(test_func, "priority")
assert test_func.priority == 100.0
def test_coroutine_with_priority_accepts_enum() -> None:
"""Test that coroutine_with_priority accepts CoroPriority enum values."""
@coroutine_with_priority(CoroPriority.CORE)
def test_func() -> None:
pass
assert hasattr(test_func, "priority")
assert test_func.priority == 100.0
def test_float_and_enum_are_interchangeable() -> None:
"""Test that float and CoroPriority enum values produce the same priority."""
@coroutine_with_priority(100.0)
def func_with_float() -> None:
pass
@coroutine_with_priority(CoroPriority.CORE)
def func_with_enum() -> None:
pass
assert func_with_float.priority == func_with_enum.priority
assert func_with_float.priority == 100.0
@pytest.mark.parametrize(
("enum_value", "float_value"),
[
(CoroPriority.PLATFORM, 1000.0),
(CoroPriority.NETWORK, 201.0),
(CoroPriority.NETWORK_TRANSPORT, 200.0),
(CoroPriority.CORE, 100.0),
(CoroPriority.DIAGNOSTICS, 90.0),
(CoroPriority.STATUS, 80.0),
(CoroPriority.COMMUNICATION, 60.0),
(CoroPriority.APPLICATION, 50.0),
(CoroPriority.WEB, 40.0),
(CoroPriority.AUTOMATION, 30.0),
(CoroPriority.BUS, 1.0),
(CoroPriority.COMPONENT, 0.0),
(CoroPriority.LATE, -100.0),
(CoroPriority.WORKAROUNDS, -999.0),
(CoroPriority.FINAL, -1000.0),
],
)
def test_all_priority_values_are_interchangeable(
enum_value: CoroPriority, float_value: float
) -> None:
"""Test that all CoroPriority values work correctly with coroutine_with_priority."""
@coroutine_with_priority(enum_value)
def func_with_enum() -> None:
pass
@coroutine_with_priority(float_value)
def func_with_float() -> None:
pass
assert func_with_enum.priority == float_value
assert func_with_float.priority == float_value
assert func_with_enum.priority == func_with_float.priority
def test_execution_order_with_enum_priorities() -> None:
"""Test that execution order is correct when using enum priorities."""
execution_order: list[str] = []
@coroutine_with_priority(CoroPriority.PLATFORM)
async def platform_func() -> None:
execution_order.append("platform")
@coroutine_with_priority(CoroPriority.CORE)
async def core_func() -> None:
execution_order.append("core")
@coroutine_with_priority(CoroPriority.FINAL)
async def final_func() -> None:
execution_order.append("final")
# Create event loop and add jobs
loop = FakeEventLoop()
loop.add_job(platform_func)
loop.add_job(core_func)
loop.add_job(final_func)
# Run all tasks
loop.flush_tasks()
# Check execution order (higher priority runs first)
assert execution_order == ["platform", "core", "final"]
def test_mixed_float_and_enum_priorities() -> None:
"""Test that mixing float and enum priorities works correctly."""
execution_order: list[str] = []
@coroutine_with_priority(1000.0) # Same as PLATFORM
async def func1() -> None:
execution_order.append("func1")
@coroutine_with_priority(CoroPriority.CORE)
async def func2() -> None:
execution_order.append("func2")
@coroutine_with_priority(-1000.0) # Same as FINAL
async def func3() -> None:
execution_order.append("func3")
# Create event loop and add jobs
loop = FakeEventLoop()
loop.add_job(func2)
loop.add_job(func3)
loop.add_job(func1)
# Run all tasks
loop.flush_tasks()
# Check execution order
assert execution_order == ["func1", "func2", "func3"]
def test_enum_priority_comparison() -> None:
"""Test that enum priorities can be compared directly."""
assert CoroPriority.PLATFORM > CoroPriority.NETWORK
assert CoroPriority.NETWORK > CoroPriority.NETWORK_TRANSPORT
assert CoroPriority.NETWORK_TRANSPORT > CoroPriority.CORE
assert CoroPriority.CORE > CoroPriority.DIAGNOSTICS
assert CoroPriority.DIAGNOSTICS > CoroPriority.STATUS
assert CoroPriority.STATUS > CoroPriority.COMMUNICATION
assert CoroPriority.COMMUNICATION > CoroPriority.APPLICATION
assert CoroPriority.APPLICATION > CoroPriority.WEB
assert CoroPriority.WEB > CoroPriority.AUTOMATION
assert CoroPriority.AUTOMATION > CoroPriority.BUS
assert CoroPriority.BUS > CoroPriority.COMPONENT
assert CoroPriority.COMPONENT > CoroPriority.LATE
assert CoroPriority.LATE > CoroPriority.WORKAROUNDS
assert CoroPriority.WORKAROUNDS > CoroPriority.FINAL
def test_custom_priority_between_enum_values() -> None:
"""Test that custom float priorities between enum values work correctly."""
execution_order: list[str] = []
@coroutine_with_priority(CoroPriority.CORE) # 100
async def core_func() -> None:
execution_order.append("core")
@coroutine_with_priority(95.0) # Between CORE and DIAGNOSTICS
async def custom_func() -> None:
execution_order.append("custom")
@coroutine_with_priority(CoroPriority.DIAGNOSTICS) # 90
async def diag_func() -> None:
execution_order.append("diagnostics")
# Create event loop and add jobs
loop = FakeEventLoop()
loop.add_job(diag_func)
loop.add_job(core_func)
loop.add_job(custom_func)
# Run all tasks
loop.flush_tasks()
# Check execution order
assert execution_order == ["core", "custom", "diagnostics"]