Add async friendly helper for validating config schemas (#123800)
* Add async friendly helper for validating config schemas * Improve docstrings * Add tests
This commit is contained in:
parent
a7bca9bcea
commit
533442f33e
4 changed files with 161 additions and 7 deletions
|
@ -3,13 +3,16 @@
|
|||
from collections import OrderedDict
|
||||
from datetime import date, datetime, timedelta
|
||||
import enum
|
||||
from functools import partial
|
||||
import logging
|
||||
import os
|
||||
from socket import _GLOBAL_DEFAULT_TIMEOUT
|
||||
import threading
|
||||
from typing import Any
|
||||
from unittest.mock import Mock, patch
|
||||
from unittest.mock import ANY, Mock, patch
|
||||
import uuid
|
||||
|
||||
import py
|
||||
import pytest
|
||||
import voluptuous as vol
|
||||
|
||||
|
@ -1738,3 +1741,67 @@ def test_determine_script_action_ambiguous() -> None:
|
|||
def test_determine_script_action_non_ambiguous() -> None:
|
||||
"""Test determine script action with a non ambiguous action."""
|
||||
assert cv.determine_script_action({"delay": "00:00:05"}) == "delay"
|
||||
|
||||
|
||||
async def test_async_validate(hass: HomeAssistant, tmpdir: py.path.local) -> None:
|
||||
"""Test the async_validate helper."""
|
||||
validator_calls: dict[str, list[int]] = {}
|
||||
|
||||
def _mock_validator_schema(real_func, *args):
|
||||
calls = validator_calls.setdefault(real_func.__name__, [])
|
||||
calls.append(threading.get_ident())
|
||||
return real_func(*args)
|
||||
|
||||
CV_PREFIX = "homeassistant.helpers.config_validation"
|
||||
with (
|
||||
patch(f"{CV_PREFIX}.isdir", wraps=partial(_mock_validator_schema, cv.isdir)),
|
||||
patch(f"{CV_PREFIX}.string", wraps=partial(_mock_validator_schema, cv.string)),
|
||||
):
|
||||
# Assert validation in event loop when not decorated with not_async_friendly
|
||||
await cv.async_validate(hass, cv.string, "abcd")
|
||||
assert validator_calls == {"string": [hass.loop_thread_id]}
|
||||
validator_calls = {}
|
||||
|
||||
# Assert validation in executor when decorated with not_async_friendly
|
||||
await cv.async_validate(hass, cv.isdir, tmpdir)
|
||||
assert validator_calls == {"isdir": [hass.loop_thread_id, ANY]}
|
||||
assert validator_calls["isdir"][1] != hass.loop_thread_id
|
||||
validator_calls = {}
|
||||
|
||||
# Assert validation in executor when decorated with not_async_friendly
|
||||
await cv.async_validate(hass, vol.All(cv.isdir, cv.string), tmpdir)
|
||||
assert validator_calls == {"isdir": [hass.loop_thread_id, ANY], "string": [ANY]}
|
||||
assert validator_calls["isdir"][1] != hass.loop_thread_id
|
||||
assert validator_calls["string"][0] != hass.loop_thread_id
|
||||
validator_calls = {}
|
||||
|
||||
# Assert validation in executor when decorated with not_async_friendly
|
||||
await cv.async_validate(hass, vol.All(cv.string, cv.isdir), tmpdir)
|
||||
assert validator_calls == {
|
||||
"isdir": [hass.loop_thread_id, ANY],
|
||||
"string": [hass.loop_thread_id, ANY],
|
||||
}
|
||||
assert validator_calls["isdir"][1] != hass.loop_thread_id
|
||||
assert validator_calls["string"][1] != hass.loop_thread_id
|
||||
validator_calls = {}
|
||||
|
||||
# Assert validation in event loop when not using cv.async_validate
|
||||
cv.isdir(tmpdir)
|
||||
assert validator_calls == {"isdir": [hass.loop_thread_id]}
|
||||
validator_calls = {}
|
||||
|
||||
# Assert validation in event loop when not using cv.async_validate
|
||||
vol.All(cv.isdir, cv.string)(tmpdir)
|
||||
assert validator_calls == {
|
||||
"isdir": [hass.loop_thread_id],
|
||||
"string": [hass.loop_thread_id],
|
||||
}
|
||||
validator_calls = {}
|
||||
|
||||
# Assert validation in event loop when not using cv.async_validate
|
||||
vol.All(cv.string, cv.isdir)(tmpdir)
|
||||
assert validator_calls == {
|
||||
"isdir": [hass.loop_thread_id],
|
||||
"string": [hass.loop_thread_id],
|
||||
}
|
||||
validator_calls = {}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue