mirror of
https://github.com/home-assistant/core.git
synced 2025-08-20 10:50:06 +00:00
.devcontainer
.github
.vscode
homeassistant
machine
pylint
rootfs
script
tests
auth
components
fixtures
hassfest
helpers
pylint
resources
scripts
snapshots
test_util
testing_config
util
snapshots
yaml
__init__.py
test_aiohttp.py
test_async.py
test_color.py
test_dt.py
test_enum.py
test_executor.py
test_file.py
test_init.py
test_json.py
test_language.py
test_location.py
test_logging.py
test_network.py
test_package.py
test_percentage.py
test_process.py
test_read_only_dict.py
test_scaling.py
test_ssl.py
test_thread.py
test_timeout.py
test_ulid.py
test_unit_conversion.py
test_unit_system.py
test_uuid.py
test_variance.py
__init__.py
common.py
conftest.py
ignore_uncaught_exceptions.py
patch_time.py
ruff.toml
syrupy.py
test_bootstrap.py
test_config.py
test_config_entries.py
test_const.py
test_core.py
test_data_entry_flow.py
test_exceptions.py
test_loader.py
test_main.py
test_requirements.py
test_runner.py
test_setup.py
test_test_fixtures.py
typing.py
.core_files.yaml
.coveragerc
.dockerignore
.gitattributes
.gitignore
.hadolint.yaml
.pre-commit-config.yaml
.prettierignore
.strict-typing
.yamllint
CLA.md
CODEOWNERS
CODE_OF_CONDUCT.md
CONTRIBUTING.md
Dockerfile
Dockerfile.dev
LICENSE.md
MANIFEST.in
README.rst
build.yaml
codecov.yml
mypy.ini
pyproject.toml
requirements.txt
requirements_all.txt
requirements_test.txt
requirements_test_all.txt
requirements_test_pre_commit.txt
333 lines
11 KiB
Python
333 lines
11 KiB
Python
"""Test Home Assistant timeout handler."""
|
|
import asyncio
|
|
from contextlib import suppress
|
|
import time
|
|
|
|
import pytest
|
|
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.util.timeout import TimeoutManager
|
|
|
|
|
|
async def test_simple_global_timeout() -> None:
|
|
"""Test a simple global timeout."""
|
|
timeout = TimeoutManager()
|
|
|
|
with pytest.raises(asyncio.TimeoutError):
|
|
async with timeout.async_timeout(0.1):
|
|
await asyncio.sleep(0.3)
|
|
|
|
|
|
async def test_simple_global_timeout_with_executor_job(hass: HomeAssistant) -> None:
|
|
"""Test a simple global timeout with executor job."""
|
|
timeout = TimeoutManager()
|
|
|
|
with pytest.raises(asyncio.TimeoutError):
|
|
async with timeout.async_timeout(0.1):
|
|
await hass.async_add_executor_job(lambda: time.sleep(0.2))
|
|
|
|
|
|
async def test_simple_global_timeout_freeze() -> None:
|
|
"""Test a simple global timeout freeze."""
|
|
timeout = TimeoutManager()
|
|
|
|
async with timeout.async_timeout(0.2), timeout.async_freeze():
|
|
await asyncio.sleep(0.3)
|
|
|
|
|
|
async def test_simple_zone_timeout_freeze_inside_executor_job(
|
|
hass: HomeAssistant,
|
|
) -> None:
|
|
"""Test a simple zone timeout freeze inside an executor job."""
|
|
timeout = TimeoutManager()
|
|
|
|
def _some_sync_work():
|
|
with timeout.freeze("recorder"):
|
|
time.sleep(0.3)
|
|
|
|
async with timeout.async_timeout(1.0), timeout.async_timeout(
|
|
0.2, zone_name="recorder"
|
|
):
|
|
await hass.async_add_executor_job(_some_sync_work)
|
|
|
|
|
|
async def test_simple_global_timeout_freeze_inside_executor_job(
|
|
hass: HomeAssistant,
|
|
) -> None:
|
|
"""Test a simple global timeout freeze inside an executor job."""
|
|
timeout = TimeoutManager()
|
|
|
|
def _some_sync_work():
|
|
with timeout.freeze():
|
|
time.sleep(0.3)
|
|
|
|
async with timeout.async_timeout(0.2):
|
|
await hass.async_add_executor_job(_some_sync_work)
|
|
|
|
|
|
async def test_mix_global_timeout_freeze_and_zone_freeze_inside_executor_job(
|
|
hass: HomeAssistant,
|
|
) -> None:
|
|
"""Test a simple global timeout freeze inside an executor job."""
|
|
timeout = TimeoutManager()
|
|
|
|
def _some_sync_work():
|
|
with timeout.freeze("recorder"):
|
|
time.sleep(0.3)
|
|
|
|
async with timeout.async_timeout(0.1), timeout.async_timeout(
|
|
0.2, zone_name="recorder"
|
|
):
|
|
await hass.async_add_executor_job(_some_sync_work)
|
|
|
|
|
|
async def test_mix_global_timeout_freeze_and_zone_freeze_different_order(
|
|
hass: HomeAssistant,
|
|
) -> None:
|
|
"""Test a simple global timeout freeze inside an executor job before timeout was set."""
|
|
timeout = TimeoutManager()
|
|
|
|
def _some_sync_work():
|
|
with timeout.freeze("recorder"):
|
|
time.sleep(0.4)
|
|
|
|
async with timeout.async_timeout(0.1):
|
|
hass.async_add_executor_job(_some_sync_work)
|
|
async with timeout.async_timeout(0.2, zone_name="recorder"):
|
|
await asyncio.sleep(0.3)
|
|
|
|
|
|
async def test_mix_global_timeout_freeze_and_zone_freeze_other_zone_inside_executor_job(
|
|
hass: HomeAssistant,
|
|
) -> None:
|
|
"""Test a simple global timeout freeze other zone inside an executor job."""
|
|
timeout = TimeoutManager()
|
|
|
|
def _some_sync_work():
|
|
with timeout.freeze("not_recorder"):
|
|
time.sleep(0.3)
|
|
|
|
with pytest.raises(asyncio.TimeoutError):
|
|
async with timeout.async_timeout(0.1):
|
|
async with timeout.async_timeout(
|
|
0.2, zone_name="recorder"
|
|
), timeout.async_timeout(0.2, zone_name="not_recorder"):
|
|
await hass.async_add_executor_job(_some_sync_work)
|
|
|
|
|
|
async def test_mix_global_timeout_freeze_and_zone_freeze_inside_executor_job_second_job_outside_zone_context(
|
|
hass: HomeAssistant,
|
|
) -> None:
|
|
"""Test a simple global timeout freeze inside an executor job with second job outside of zone context."""
|
|
timeout = TimeoutManager()
|
|
|
|
def _some_sync_work():
|
|
with timeout.freeze("recorder"):
|
|
time.sleep(0.3)
|
|
|
|
with pytest.raises(asyncio.TimeoutError):
|
|
async with timeout.async_timeout(0.1):
|
|
async with timeout.async_timeout(0.2, zone_name="recorder"):
|
|
await hass.async_add_executor_job(_some_sync_work)
|
|
await hass.async_add_executor_job(lambda: time.sleep(0.2))
|
|
|
|
|
|
async def test_simple_global_timeout_freeze_with_executor_job(
|
|
hass: HomeAssistant,
|
|
) -> None:
|
|
"""Test a simple global timeout freeze with executor job."""
|
|
timeout = TimeoutManager()
|
|
|
|
async with timeout.async_timeout(0.2), timeout.async_freeze():
|
|
await hass.async_add_executor_job(lambda: time.sleep(0.3))
|
|
|
|
|
|
async def test_simple_global_timeout_freeze_reset() -> None:
|
|
"""Test a simple global timeout freeze reset."""
|
|
timeout = TimeoutManager()
|
|
|
|
with pytest.raises(asyncio.TimeoutError):
|
|
async with timeout.async_timeout(0.2):
|
|
async with timeout.async_freeze():
|
|
await asyncio.sleep(0.1)
|
|
await asyncio.sleep(0.2)
|
|
|
|
|
|
async def test_simple_zone_timeout() -> None:
|
|
"""Test a simple zone timeout."""
|
|
timeout = TimeoutManager()
|
|
|
|
with pytest.raises(asyncio.TimeoutError):
|
|
async with timeout.async_timeout(0.1, "test"):
|
|
await asyncio.sleep(0.3)
|
|
|
|
|
|
async def test_multiple_zone_timeout() -> None:
|
|
"""Test a simple zone timeout."""
|
|
timeout = TimeoutManager()
|
|
|
|
with pytest.raises(asyncio.TimeoutError):
|
|
async with timeout.async_timeout(0.1, "test"):
|
|
async with timeout.async_timeout(0.5, "test"):
|
|
await asyncio.sleep(0.3)
|
|
|
|
|
|
async def test_different_zone_timeout() -> None:
|
|
"""Test a simple zone timeout."""
|
|
timeout = TimeoutManager()
|
|
|
|
with pytest.raises(asyncio.TimeoutError):
|
|
async with timeout.async_timeout(0.1, "test"):
|
|
async with timeout.async_timeout(0.5, "other"):
|
|
await asyncio.sleep(0.3)
|
|
|
|
|
|
async def test_simple_zone_timeout_freeze() -> None:
|
|
"""Test a simple zone timeout freeze."""
|
|
timeout = TimeoutManager()
|
|
|
|
async with timeout.async_timeout(0.2, "test"), timeout.async_freeze("test"):
|
|
await asyncio.sleep(0.3)
|
|
|
|
|
|
async def test_simple_zone_timeout_freeze_without_timeout() -> None:
|
|
"""Test a simple zone timeout freeze on a zone that does not have a timeout set."""
|
|
timeout = TimeoutManager()
|
|
|
|
async with timeout.async_timeout(0.1, "test"), timeout.async_freeze("test"):
|
|
await asyncio.sleep(0.3)
|
|
|
|
|
|
async def test_simple_zone_timeout_freeze_reset() -> None:
|
|
"""Test a simple zone timeout freeze reset."""
|
|
timeout = TimeoutManager()
|
|
|
|
with pytest.raises(asyncio.TimeoutError):
|
|
async with timeout.async_timeout(0.2, "test"):
|
|
async with timeout.async_freeze("test"):
|
|
await asyncio.sleep(0.1)
|
|
await asyncio.sleep(0.2, "test")
|
|
|
|
|
|
async def test_mix_zone_timeout_freeze_and_global_freeze() -> None:
|
|
"""Test a mix zone timeout freeze and global freeze."""
|
|
timeout = TimeoutManager()
|
|
|
|
async with timeout.async_timeout(0.2, "test"), timeout.async_freeze(
|
|
"test"
|
|
), timeout.async_freeze():
|
|
await asyncio.sleep(0.3)
|
|
|
|
|
|
async def test_mix_global_and_zone_timeout_freeze_() -> None:
|
|
"""Test a mix zone timeout freeze and global freeze."""
|
|
timeout = TimeoutManager()
|
|
|
|
async with timeout.async_timeout(
|
|
0.2, "test"
|
|
), timeout.async_freeze(), timeout.async_freeze("test"):
|
|
await asyncio.sleep(0.3)
|
|
|
|
|
|
async def test_mix_zone_timeout_freeze() -> None:
|
|
"""Test a mix zone timeout global freeze."""
|
|
timeout = TimeoutManager()
|
|
|
|
async with timeout.async_timeout(0.2, "test"), timeout.async_freeze():
|
|
await asyncio.sleep(0.3)
|
|
|
|
|
|
async def test_mix_zone_timeout() -> None:
|
|
"""Test a mix zone timeout global."""
|
|
timeout = TimeoutManager()
|
|
|
|
async with timeout.async_timeout(0.1):
|
|
with suppress(asyncio.TimeoutError):
|
|
async with timeout.async_timeout(0.2, "test"):
|
|
await asyncio.sleep(0.4)
|
|
|
|
|
|
async def test_mix_zone_timeout_trigger_global() -> None:
|
|
"""Test a mix zone timeout global with trigger it."""
|
|
timeout = TimeoutManager()
|
|
|
|
with pytest.raises(asyncio.TimeoutError):
|
|
async with timeout.async_timeout(0.1):
|
|
with suppress(asyncio.TimeoutError):
|
|
async with timeout.async_timeout(0.1, "test"):
|
|
await asyncio.sleep(0.3)
|
|
|
|
await asyncio.sleep(0.3)
|
|
|
|
|
|
async def test_mix_zone_timeout_trigger_global_cool_down() -> None:
|
|
"""Test a mix zone timeout global with trigger it with cool_down."""
|
|
timeout = TimeoutManager()
|
|
|
|
async with timeout.async_timeout(0.1, cool_down=0.3):
|
|
with suppress(asyncio.TimeoutError):
|
|
async with timeout.async_timeout(0.1, "test"):
|
|
await asyncio.sleep(0.3)
|
|
|
|
await asyncio.sleep(0.2)
|
|
|
|
# Cleanup lingering (cool_down) task after test is done
|
|
await asyncio.sleep(0.3)
|
|
|
|
|
|
async def test_simple_zone_timeout_freeze_without_timeout_cleanup(
|
|
hass: HomeAssistant,
|
|
) -> None:
|
|
"""Test a simple zone timeout freeze on a zone that does not have a timeout set."""
|
|
timeout = TimeoutManager()
|
|
|
|
async def background():
|
|
async with timeout.async_freeze("test"):
|
|
await asyncio.sleep(0.4)
|
|
|
|
async with timeout.async_timeout(0.1):
|
|
hass.async_create_task(background())
|
|
await asyncio.sleep(0.2)
|
|
|
|
|
|
async def test_simple_zone_timeout_freeze_without_timeout_cleanup2(
|
|
hass: HomeAssistant,
|
|
) -> None:
|
|
"""Test a simple zone timeout freeze on a zone that does not have a timeout set."""
|
|
timeout = TimeoutManager()
|
|
|
|
async def background():
|
|
async with timeout.async_freeze("test"):
|
|
await asyncio.sleep(0.2)
|
|
|
|
with pytest.raises(asyncio.TimeoutError):
|
|
async with timeout.async_timeout(0.1):
|
|
hass.async_create_task(background())
|
|
await asyncio.sleep(0.3)
|
|
|
|
|
|
async def test_simple_zone_timeout_freeze_without_timeout_exeption() -> None:
|
|
"""Test a simple zone timeout freeze on a zone that does not have a timeout set."""
|
|
timeout = TimeoutManager()
|
|
|
|
with pytest.raises(asyncio.TimeoutError):
|
|
async with timeout.async_timeout(0.1):
|
|
with suppress(RuntimeError):
|
|
async with timeout.async_freeze("test"):
|
|
raise RuntimeError()
|
|
|
|
await asyncio.sleep(0.4)
|
|
|
|
|
|
async def test_simple_zone_timeout_zone_with_timeout_exeption() -> None:
|
|
"""Test a simple zone timeout freeze on a zone that does not have a timeout set."""
|
|
timeout = TimeoutManager()
|
|
|
|
with pytest.raises(asyncio.TimeoutError):
|
|
async with timeout.async_timeout(0.1):
|
|
with suppress(RuntimeError):
|
|
async with timeout.async_timeout(0.3, "test"):
|
|
raise RuntimeError()
|
|
|
|
await asyncio.sleep(0.3)
|