247 lines
7.8 KiB
Python
247 lines
7.8 KiB
Python
"""Test check_config helper."""
|
|
import logging
|
|
from unittest.mock import Mock, patch
|
|
|
|
from homeassistant.config import YAML_CONFIG_FILE
|
|
from homeassistant.helpers.check_config import (
|
|
CheckConfigError,
|
|
async_check_ha_config_file,
|
|
)
|
|
from homeassistant.requirements import RequirementsNotFound
|
|
|
|
from tests.common import mock_platform, patch_yaml_files
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
BASE_CONFIG = (
|
|
"homeassistant:\n"
|
|
" name: Home\n"
|
|
" latitude: -26.107361\n"
|
|
" longitude: 28.054500\n"
|
|
" elevation: 1600\n"
|
|
" unit_system: metric\n"
|
|
" time_zone: GMT\n"
|
|
"\n\n"
|
|
)
|
|
|
|
BAD_CORE_CONFIG = "homeassistant:\n unit_system: bad\n\n\n"
|
|
|
|
|
|
def log_ha_config(conf):
|
|
"""Log the returned config."""
|
|
cnt = 0
|
|
_LOGGER.debug("CONFIG - %s lines - %s errors", len(conf), len(conf.errors))
|
|
for key, val in conf.items():
|
|
_LOGGER.debug("#%s - %s: %s", cnt, key, val)
|
|
cnt += 1
|
|
for cnt, err in enumerate(conf.errors):
|
|
_LOGGER.debug("error[%s] = %s", cnt, err)
|
|
|
|
|
|
async def test_bad_core_config(hass):
|
|
"""Test a bad core config setup."""
|
|
files = {YAML_CONFIG_FILE: BAD_CORE_CONFIG}
|
|
with patch("os.path.isfile", return_value=True), patch_yaml_files(files):
|
|
res = await async_check_ha_config_file(hass)
|
|
log_ha_config(res)
|
|
|
|
assert isinstance(res.errors[0].message, str)
|
|
assert res.errors[0].domain == "homeassistant"
|
|
assert res.errors[0].config == {"unit_system": "bad"}
|
|
|
|
# Only 1 error expected
|
|
res.errors.pop(0)
|
|
assert not res.errors
|
|
|
|
|
|
async def test_config_platform_valid(hass):
|
|
"""Test a valid platform setup."""
|
|
files = {YAML_CONFIG_FILE: BASE_CONFIG + "light:\n platform: demo"}
|
|
with patch("os.path.isfile", return_value=True), patch_yaml_files(files):
|
|
res = await async_check_ha_config_file(hass)
|
|
log_ha_config(res)
|
|
|
|
assert res.keys() == {"homeassistant", "light"}
|
|
assert res["light"] == [{"platform": "demo"}]
|
|
assert not res.errors
|
|
|
|
|
|
async def test_component_platform_not_found(hass):
|
|
"""Test errors if component or platform not found."""
|
|
# Make sure they don't exist
|
|
files = {YAML_CONFIG_FILE: BASE_CONFIG + "beer:"}
|
|
with patch("os.path.isfile", return_value=True), patch_yaml_files(files):
|
|
res = await async_check_ha_config_file(hass)
|
|
log_ha_config(res)
|
|
|
|
assert res.keys() == {"homeassistant"}
|
|
assert res.errors[0] == CheckConfigError(
|
|
"Integration error: beer - Integration 'beer' not found.", None, None
|
|
)
|
|
|
|
# Only 1 error expected
|
|
res.errors.pop(0)
|
|
assert not res.errors
|
|
|
|
|
|
async def test_component_requirement_not_found(hass):
|
|
"""Test errors if component with a requirement not found not found."""
|
|
# Make sure they don't exist
|
|
files = {YAML_CONFIG_FILE: BASE_CONFIG + "test_custom_component:"}
|
|
with patch(
|
|
"homeassistant.helpers.check_config.async_get_integration_with_requirements",
|
|
side_effect=RequirementsNotFound("test_custom_component", ["any"]),
|
|
), patch("os.path.isfile", return_value=True), patch_yaml_files(files):
|
|
res = await async_check_ha_config_file(hass)
|
|
log_ha_config(res)
|
|
|
|
assert res.keys() == {"homeassistant"}
|
|
assert res.errors[0] == CheckConfigError(
|
|
"Integration error: test_custom_component - Requirements for test_custom_component not found: ['any'].",
|
|
None,
|
|
None,
|
|
)
|
|
|
|
# Only 1 error expected
|
|
res.errors.pop(0)
|
|
assert not res.errors
|
|
|
|
|
|
async def test_component_not_found_safe_mode(hass):
|
|
"""Test no errors if component not found in safe mode."""
|
|
# Make sure they don't exist
|
|
files = {YAML_CONFIG_FILE: BASE_CONFIG + "beer:"}
|
|
hass.config.safe_mode = True
|
|
with patch("os.path.isfile", return_value=True), patch_yaml_files(files):
|
|
res = await async_check_ha_config_file(hass)
|
|
log_ha_config(res)
|
|
|
|
assert res.keys() == {"homeassistant"}
|
|
assert not res.errors
|
|
|
|
|
|
async def test_component_platform_not_found_2(hass):
|
|
"""Test errors if component or platform not found."""
|
|
# Make sure they don't exist
|
|
files = {YAML_CONFIG_FILE: BASE_CONFIG + "light:\n platform: beer"}
|
|
with patch("os.path.isfile", return_value=True), patch_yaml_files(files):
|
|
res = await async_check_ha_config_file(hass)
|
|
log_ha_config(res)
|
|
|
|
assert res.keys() == {"homeassistant", "light"}
|
|
assert res["light"] == []
|
|
|
|
assert res.errors[0] == CheckConfigError(
|
|
"Platform error light.beer - Integration 'beer' not found.", None, None
|
|
)
|
|
|
|
# Only 1 error expected
|
|
res.errors.pop(0)
|
|
assert not res.errors
|
|
|
|
|
|
async def test_platform_not_found_safe_mode(hass):
|
|
"""Test no errors if platform not found in safe_mode."""
|
|
# Make sure they don't exist
|
|
files = {YAML_CONFIG_FILE: BASE_CONFIG + "light:\n platform: beer"}
|
|
hass.config.safe_mode = True
|
|
with patch("os.path.isfile", return_value=True), patch_yaml_files(files):
|
|
res = await async_check_ha_config_file(hass)
|
|
log_ha_config(res)
|
|
|
|
assert res.keys() == {"homeassistant", "light"}
|
|
assert res["light"] == []
|
|
|
|
assert not res.errors
|
|
|
|
|
|
async def test_package_invalid(hass):
|
|
"""Test a valid platform setup."""
|
|
files = {
|
|
YAML_CONFIG_FILE: BASE_CONFIG + (" packages:\n p1:\n" ' group: ["a"]')
|
|
}
|
|
with patch("os.path.isfile", return_value=True), patch_yaml_files(files):
|
|
res = await async_check_ha_config_file(hass)
|
|
log_ha_config(res)
|
|
|
|
assert res.errors[0].domain == "homeassistant.packages.p1.group"
|
|
assert res.errors[0].config == {"group": ["a"]}
|
|
# Only 1 error expected
|
|
res.errors.pop(0)
|
|
assert not res.errors
|
|
|
|
assert res.keys() == {"homeassistant"}
|
|
|
|
|
|
async def test_bootstrap_error(hass):
|
|
"""Test a valid platform setup."""
|
|
files = {YAML_CONFIG_FILE: BASE_CONFIG + "automation: !include no.yaml"}
|
|
with patch("os.path.isfile", return_value=True), patch_yaml_files(files):
|
|
res = await async_check_ha_config_file(hass)
|
|
log_ha_config(res)
|
|
|
|
assert res.errors[0].domain is None
|
|
|
|
# Only 1 error expected
|
|
res.errors.pop(0)
|
|
assert not res.errors
|
|
|
|
|
|
async def test_automation_config_platform(hass):
|
|
"""Test automation async config."""
|
|
files = {
|
|
YAML_CONFIG_FILE: BASE_CONFIG
|
|
+ """
|
|
automation:
|
|
use_blueprint:
|
|
path: test_event_service.yaml
|
|
input:
|
|
trigger_event: blueprint_event
|
|
service_to_call: test.automation
|
|
input_datetime:
|
|
""",
|
|
hass.config.path(
|
|
"blueprints/automation/test_event_service.yaml"
|
|
): """
|
|
blueprint:
|
|
name: "Call service based on event"
|
|
domain: automation
|
|
input:
|
|
trigger_event:
|
|
service_to_call:
|
|
trigger:
|
|
platform: event
|
|
event_type: !input trigger_event
|
|
action:
|
|
service: !input service_to_call
|
|
""",
|
|
}
|
|
with patch("os.path.isfile", return_value=True), patch_yaml_files(files):
|
|
res = await async_check_ha_config_file(hass)
|
|
assert len(res.get("automation", [])) == 1
|
|
assert len(res.errors) == 0
|
|
assert "input_datetime" in res
|
|
|
|
|
|
async def test_config_platform_raise(hass):
|
|
"""Test bad config validation platform."""
|
|
mock_platform(
|
|
hass,
|
|
"bla.config",
|
|
Mock(async_validate_config=Mock(side_effect=Exception("Broken"))),
|
|
)
|
|
files = {
|
|
YAML_CONFIG_FILE: BASE_CONFIG
|
|
+ """
|
|
bla:
|
|
value: 1
|
|
""",
|
|
}
|
|
with patch("os.path.isfile", return_value=True), patch_yaml_files(files):
|
|
res = await async_check_ha_config_file(hass)
|
|
assert len(res.errors) == 1
|
|
err = res.errors[0]
|
|
assert err.domain == "bla"
|
|
assert err.message == "Unexpected error calling config validator: Broken"
|
|
assert err.config == {"value": 1}
|