check_config script evolution (#12792)
* Initial async_check_ha_config_file * check_ha_config_file * Various fixes * feedback - return the config * move_to_check_config
This commit is contained in:
parent
5e2296f2a4
commit
6734c966b3
5 changed files with 316 additions and 254 deletions
|
@ -1,9 +1,12 @@
|
|||
"""Test check_config script."""
|
||||
import asyncio
|
||||
import logging
|
||||
import os # noqa: F401 pylint: disable=unused-import
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
import homeassistant.scripts.check_config as check_config
|
||||
from homeassistant.config import YAML_CONFIG_FILE
|
||||
from homeassistant.loader import set_component
|
||||
from tests.common import patch_yaml_files, get_test_config_dir
|
||||
|
||||
|
@ -21,21 +24,14 @@ BASE_CONFIG = (
|
|||
)
|
||||
|
||||
|
||||
def change_yaml_files(check_dict):
|
||||
"""Change the ['yaml_files'] property and remove the configuration path.
|
||||
|
||||
Also removes other files like service.yaml that gets loaded.
|
||||
"""
|
||||
def normalize_yaml_files(check_dict):
|
||||
"""Remove configuration path from ['yaml_files']."""
|
||||
root = get_test_config_dir()
|
||||
keys = check_dict['yaml_files'].keys()
|
||||
check_dict['yaml_files'] = []
|
||||
for key in sorted(keys):
|
||||
if not key.startswith('/'):
|
||||
check_dict['yaml_files'].append(key)
|
||||
if key.startswith(root):
|
||||
check_dict['yaml_files'].append('...' + key[len(root):])
|
||||
return [key.replace(root, '...')
|
||||
for key in sorted(check_dict['yaml_files'].keys())]
|
||||
|
||||
|
||||
# pylint: disable=unsubscriptable-object
|
||||
class TestCheckConfig(unittest.TestCase):
|
||||
"""Tests for the homeassistant.scripts.check_config module."""
|
||||
|
||||
|
@ -51,176 +47,165 @@ class TestCheckConfig(unittest.TestCase):
|
|||
asyncio.set_event_loop(asyncio.new_event_loop())
|
||||
|
||||
# Will allow seeing full diff
|
||||
self.maxDiff = None
|
||||
self.maxDiff = None # pylint: disable=invalid-name
|
||||
|
||||
# pylint: disable=no-self-use,invalid-name
|
||||
def test_config_platform_valid(self):
|
||||
@patch('os.path.isfile', return_value=True)
|
||||
def test_config_platform_valid(self, isfile_patch):
|
||||
"""Test a valid platform setup."""
|
||||
files = {
|
||||
'light.yaml': BASE_CONFIG + 'light:\n platform: demo',
|
||||
YAML_CONFIG_FILE: BASE_CONFIG + 'light:\n platform: demo',
|
||||
}
|
||||
with patch_yaml_files(files):
|
||||
res = check_config.check(get_test_config_dir('light.yaml'))
|
||||
change_yaml_files(res)
|
||||
self.assertDictEqual({
|
||||
'components': {'light': [{'platform': 'demo'}], 'group': None},
|
||||
'except': {},
|
||||
'secret_cache': {},
|
||||
'secrets': {},
|
||||
'yaml_files': ['.../light.yaml']
|
||||
}, res)
|
||||
res = check_config.check(get_test_config_dir())
|
||||
assert res['components'].keys() == {'homeassistant', 'light'}
|
||||
assert res['components']['light'] == [{'platform': 'demo'}]
|
||||
assert res['except'] == {}
|
||||
assert res['secret_cache'] == {}
|
||||
assert res['secrets'] == {}
|
||||
assert len(res['yaml_files']) == 1
|
||||
|
||||
def test_config_component_platform_fail_validation(self):
|
||||
@patch('os.path.isfile', return_value=True)
|
||||
def test_config_component_platform_fail_validation(self, isfile_patch):
|
||||
"""Test errors if component & platform not found."""
|
||||
files = {
|
||||
'component.yaml': BASE_CONFIG + 'http:\n password: err123',
|
||||
YAML_CONFIG_FILE: BASE_CONFIG + 'http:\n password: err123',
|
||||
}
|
||||
with patch_yaml_files(files):
|
||||
res = check_config.check(get_test_config_dir('component.yaml'))
|
||||
change_yaml_files(res)
|
||||
|
||||
self.assertDictEqual({}, res['components'])
|
||||
res['except'].pop(check_config.ERROR_STR)
|
||||
self.assertDictEqual(
|
||||
{'http': {'password': 'err123'}},
|
||||
res['except']
|
||||
)
|
||||
self.assertDictEqual({}, res['secret_cache'])
|
||||
self.assertDictEqual({}, res['secrets'])
|
||||
self.assertListEqual(['.../component.yaml'], res['yaml_files'])
|
||||
res = check_config.check(get_test_config_dir())
|
||||
assert res['components'].keys() == {'homeassistant'}
|
||||
assert res['except'].keys() == {'http'}
|
||||
assert res['except']['http'][1] == {'http': {'password': 'err123'}}
|
||||
assert res['secret_cache'] == {}
|
||||
assert res['secrets'] == {}
|
||||
assert len(res['yaml_files']) == 1
|
||||
|
||||
files = {
|
||||
'platform.yaml': (BASE_CONFIG + 'mqtt:\n\n'
|
||||
'light:\n platform: mqtt_json'),
|
||||
YAML_CONFIG_FILE: (BASE_CONFIG + 'mqtt:\n\n'
|
||||
'light:\n platform: mqtt_json'),
|
||||
}
|
||||
with patch_yaml_files(files):
|
||||
res = check_config.check(get_test_config_dir('platform.yaml'))
|
||||
change_yaml_files(res)
|
||||
self.assertDictEqual(
|
||||
{'mqtt': {
|
||||
'keepalive': 60,
|
||||
'port': 1883,
|
||||
'protocol': '3.1.1',
|
||||
'discovery': False,
|
||||
'discovery_prefix': 'homeassistant',
|
||||
'tls_version': 'auto',
|
||||
},
|
||||
'light': [],
|
||||
'group': None},
|
||||
res['components']
|
||||
)
|
||||
self.assertDictEqual(
|
||||
{'light.mqtt_json': {'platform': 'mqtt_json'}},
|
||||
res['except']
|
||||
)
|
||||
self.assertDictEqual({}, res['secret_cache'])
|
||||
self.assertDictEqual({}, res['secrets'])
|
||||
self.assertListEqual(['.../platform.yaml'], res['yaml_files'])
|
||||
res = check_config.check(get_test_config_dir())
|
||||
assert res['components'].keys() == {
|
||||
'homeassistant', 'light', 'mqtt'}
|
||||
assert res['components']['light'] == []
|
||||
assert res['components']['mqtt'] == {
|
||||
'keepalive': 60,
|
||||
'port': 1883,
|
||||
'protocol': '3.1.1',
|
||||
'discovery': False,
|
||||
'discovery_prefix': 'homeassistant',
|
||||
'tls_version': 'auto',
|
||||
}
|
||||
assert res['except'].keys() == {'light.mqtt_json'}
|
||||
assert res['except']['light.mqtt_json'][1] == {
|
||||
'platform': 'mqtt_json'}
|
||||
assert res['secret_cache'] == {}
|
||||
assert res['secrets'] == {}
|
||||
assert len(res['yaml_files']) == 1
|
||||
|
||||
def test_component_platform_not_found(self):
|
||||
@patch('os.path.isfile', return_value=True)
|
||||
def test_component_platform_not_found(self, isfile_patch):
|
||||
"""Test errors if component or platform not found."""
|
||||
# Make sure they don't exist
|
||||
set_component('beer', None)
|
||||
set_component('light.beer', None)
|
||||
files = {
|
||||
'badcomponent.yaml': BASE_CONFIG + 'beer:',
|
||||
'badplatform.yaml': BASE_CONFIG + 'light:\n platform: beer',
|
||||
YAML_CONFIG_FILE: BASE_CONFIG + 'beer:',
|
||||
}
|
||||
with patch_yaml_files(files):
|
||||
res = check_config.check(get_test_config_dir('badcomponent.yaml'))
|
||||
change_yaml_files(res)
|
||||
self.assertDictEqual({}, res['components'])
|
||||
self.assertDictEqual({
|
||||
check_config.ERROR_STR: [
|
||||
'Component not found: beer',
|
||||
'Setup failed for beer: Component not found.']
|
||||
}, res['except'])
|
||||
self.assertDictEqual({}, res['secret_cache'])
|
||||
self.assertDictEqual({}, res['secrets'])
|
||||
self.assertListEqual(['.../badcomponent.yaml'], res['yaml_files'])
|
||||
res = check_config.check(get_test_config_dir())
|
||||
assert res['components'].keys() == {'homeassistant'}
|
||||
assert res['except'] == {
|
||||
check_config.ERROR_STR: ['Component not found: beer']}
|
||||
assert res['secret_cache'] == {}
|
||||
assert res['secrets'] == {}
|
||||
assert len(res['yaml_files']) == 1
|
||||
|
||||
res = check_config.check(get_test_config_dir('badplatform.yaml'))
|
||||
change_yaml_files(res)
|
||||
assert res['components'] == {'light': [], 'group': None}
|
||||
set_component('light.beer', None)
|
||||
files = {
|
||||
YAML_CONFIG_FILE: BASE_CONFIG + 'light:\n platform: beer',
|
||||
}
|
||||
with patch_yaml_files(files):
|
||||
res = check_config.check(get_test_config_dir())
|
||||
assert res['components'].keys() == {'homeassistant', 'light'}
|
||||
assert res['components']['light'] == []
|
||||
assert res['except'] == {
|
||||
check_config.ERROR_STR: [
|
||||
'Platform not found: light.beer',
|
||||
]}
|
||||
self.assertDictEqual({}, res['secret_cache'])
|
||||
self.assertDictEqual({}, res['secrets'])
|
||||
self.assertListEqual(['.../badplatform.yaml'], res['yaml_files'])
|
||||
assert res['secret_cache'] == {}
|
||||
assert res['secrets'] == {}
|
||||
assert len(res['yaml_files']) == 1
|
||||
|
||||
def test_secrets(self):
|
||||
@patch('os.path.isfile', return_value=True)
|
||||
def test_secrets(self, isfile_patch):
|
||||
"""Test secrets config checking method."""
|
||||
secrets_path = get_test_config_dir('secrets.yaml')
|
||||
|
||||
files = {
|
||||
get_test_config_dir('secret.yaml'): (
|
||||
BASE_CONFIG +
|
||||
get_test_config_dir(YAML_CONFIG_FILE): BASE_CONFIG + (
|
||||
'http:\n'
|
||||
' api_password: !secret http_pw'),
|
||||
'secrets.yaml': ('logger: debug\n'
|
||||
'http_pw: abc123'),
|
||||
secrets_path: (
|
||||
'logger: debug\n'
|
||||
'http_pw: abc123'),
|
||||
}
|
||||
|
||||
with patch_yaml_files(files):
|
||||
config_path = get_test_config_dir('secret.yaml')
|
||||
secrets_path = get_test_config_dir('secrets.yaml')
|
||||
|
||||
res = check_config.check(config_path)
|
||||
change_yaml_files(res)
|
||||
res = check_config.check(get_test_config_dir(), True)
|
||||
|
||||
# convert secrets OrderedDict to dict for assertequal
|
||||
for key, val in res['secret_cache'].items():
|
||||
res['secret_cache'][key] = dict(val)
|
||||
assert res['except'] == {}
|
||||
assert res['components'].keys() == {'homeassistant', 'http'}
|
||||
assert res['components']['http'] == {
|
||||
'api_password': 'abc123',
|
||||
'cors_allowed_origins': [],
|
||||
'ip_ban_enabled': True,
|
||||
'login_attempts_threshold': -1,
|
||||
'server_host': '0.0.0.0',
|
||||
'server_port': 8123,
|
||||
'trusted_networks': [],
|
||||
'use_x_forwarded_for': False}
|
||||
assert res['secret_cache'] == {secrets_path: {'http_pw': 'abc123'}}
|
||||
assert res['secrets'] == {'http_pw': 'abc123'}
|
||||
assert normalize_yaml_files(res) == [
|
||||
'.../configuration.yaml', '.../secrets.yaml']
|
||||
|
||||
self.assertDictEqual({
|
||||
'components': {'http': {'api_password': 'abc123',
|
||||
'cors_allowed_origins': [],
|
||||
'ip_ban_enabled': True,
|
||||
'login_attempts_threshold': -1,
|
||||
'server_host': '0.0.0.0',
|
||||
'server_port': 8123,
|
||||
'trusted_networks': [],
|
||||
'use_x_forwarded_for': False}},
|
||||
'except': {},
|
||||
'secret_cache': {secrets_path: {'http_pw': 'abc123'}},
|
||||
'secrets': {'http_pw': 'abc123'},
|
||||
'yaml_files': ['.../secret.yaml', '.../secrets.yaml']
|
||||
}, res)
|
||||
|
||||
def test_package_invalid(self): \
|
||||
@patch('os.path.isfile', return_value=True)
|
||||
def test_package_invalid(self, isfile_patch): \
|
||||
# pylint: disable=no-self-use,invalid-name
|
||||
"""Test a valid platform setup."""
|
||||
files = {
|
||||
'bad.yaml': BASE_CONFIG + (' packages:\n'
|
||||
' p1:\n'
|
||||
' group: ["a"]'),
|
||||
YAML_CONFIG_FILE: BASE_CONFIG + (
|
||||
' packages:\n'
|
||||
' p1:\n'
|
||||
' group: ["a"]'),
|
||||
}
|
||||
with patch_yaml_files(files):
|
||||
res = check_config.check(get_test_config_dir('bad.yaml'))
|
||||
change_yaml_files(res)
|
||||
res = check_config.check(get_test_config_dir())
|
||||
|
||||
err = res['except'].pop('homeassistant.packages.p1')
|
||||
assert res['except'] == {}
|
||||
assert err == {'group': ['a']}
|
||||
assert res['yaml_files'] == ['.../bad.yaml']
|
||||
|
||||
assert res['components'] == {}
|
||||
assert res['except'].keys() == {'homeassistant.packages.p1.group'}
|
||||
assert res['except']['homeassistant.packages.p1.group'][1] == \
|
||||
{'group': ['a']}
|
||||
assert len(res['except']) == 1
|
||||
assert res['components'].keys() == {'homeassistant'}
|
||||
assert len(res['components']) == 1
|
||||
assert res['secret_cache'] == {}
|
||||
assert res['secrets'] == {}
|
||||
assert len(res['yaml_files']) == 1
|
||||
|
||||
def test_bootstrap_error(self): \
|
||||
# pylint: disable=no-self-use,invalid-name
|
||||
"""Test a valid platform setup."""
|
||||
files = {
|
||||
'badbootstrap.yaml': BASE_CONFIG + 'automation: !include no.yaml',
|
||||
YAML_CONFIG_FILE: BASE_CONFIG + 'automation: !include no.yaml',
|
||||
}
|
||||
with patch_yaml_files(files):
|
||||
res = check_config.check(get_test_config_dir('badbootstrap.yaml'))
|
||||
change_yaml_files(res)
|
||||
|
||||
res = check_config.check(get_test_config_dir(YAML_CONFIG_FILE))
|
||||
err = res['except'].pop(check_config.ERROR_STR)
|
||||
assert len(err) == 1
|
||||
assert res['except'] == {}
|
||||
assert res['components'] == {}
|
||||
assert res['components'] == {} # No components, load failed
|
||||
assert res['secret_cache'] == {}
|
||||
assert res['secrets'] == {}
|
||||
assert res['yaml_files'] == {}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue