Пример #1
0
def test_merge_id_schema(hass):
    """Test if we identify the config schemas correctly."""
    types = {
        'panel_custom': 'list',
        'group': 'dict',
        'script': 'dict',
        'input_boolean': 'dict',
        'shell_command': 'dict',
        'qwikswitch': 'dict',
    }
    for name, expected_type in types.items():
        module = config_util.get_component(hass, name)
        typ, _ = config_util._identify_config_schema(module)
        assert typ == expected_type, "{} expected {}, got {}".format(
            name, expected_type, typ)
Пример #2
0
def test_merge_id_schema(hass):
    """Test if we identify the config schemas correctly."""
    types = {
        'panel_custom': 'list',
        'group': 'dict',
        'script': 'dict',
        'input_boolean': 'dict',
        'shell_command': 'dict',
        'qwikswitch': 'dict',
    }
    for name, expected_type in types.items():
        module = config_util.get_component(name)
        typ, _ = config_util._identify_config_schema(module)
        assert typ == expected_type, "{} expected {}, got {}".format(
            name, expected_type, typ)
Пример #3
0
def check_ha_config_file(config_dir):
    """Check if Home Assistant configuration file is valid."""
    result = HomeAssistantConfig()

    def _pack_error(package, component, config, message):
        """Handle errors from packages: _log_pkg_error."""
        message = "Package {} setup failed. Component {} {}".format(
            package, component, message)
        domain = 'homeassistant.packages.{}.{}'.format(package, component)
        pack_config = core_config[CONF_PACKAGES].get(package, config)
        result.add_error(message, domain, pack_config)

    def _comp_error(ex, domain, config):
        """Handle errors from components: async_log_exception."""
        result.add_error(_format_config_error(ex, domain, config), domain,
                         config)

    # Load configuration.yaml
    try:
        config_path = find_config_file(config_dir)
        if not config_path:
            return result.add_error("File configuration.yaml not found.")
        config = load_yaml_config_file(config_path)
    except HomeAssistantError as err:
        return result.add_error("Error loading {}: {}".format(
            config_path, err))
    finally:
        yaml.clear_secret_cache()

    # Extract and validate core [homeassistant] config
    try:
        core_config = config.pop(CONF_CORE, {})
        core_config = CORE_CONFIG_SCHEMA(core_config)
        result[CONF_CORE] = core_config
    except vol.Invalid as err:
        result.add_error(err, CONF_CORE, core_config)
        core_config = {}

    # Merge packages
    merge_packages_config(config, core_config.get(CONF_PACKAGES, {}),
                          _pack_error)
    del core_config[CONF_PACKAGES]

    # Ensure we have no None values after merge
    for key, value in config.items():
        if not value:
            config[key] = {}

    # Filter out repeating config sections
    components = set(key.split(' ')[0] for key in config.keys())

    # Process and validate config
    for domain in components:
        component = get_component(domain)
        if not component:
            result.add_error("Component not found: {}".format(domain))
            continue

        if hasattr(component, 'CONFIG_SCHEMA'):
            try:
                config = component.CONFIG_SCHEMA(config)
                result[domain] = config[domain]
            except vol.Invalid as ex:
                _comp_error(ex, domain, config)
                continue

        if not hasattr(component, 'PLATFORM_SCHEMA'):
            continue

        platforms = []
        for p_name, p_config in config_per_platform(config, domain):
            # Validate component specific platform schema
            try:
                p_validated = component.PLATFORM_SCHEMA(p_config)
            except vol.Invalid as ex:
                _comp_error(ex, domain, config)
                continue

            # Not all platform components follow same pattern for platforms
            # So if p_name is None we are not going to validate platform
            # (the automation component is one of them)
            if p_name is None:
                platforms.append(p_validated)
                continue

            platform = get_platform(domain, p_name)

            if platform is None:
                result.add_error("Platform not found: {}.{}".format(
                    domain, p_name))
                continue

            # Validate platform specific schema
            if hasattr(platform, 'PLATFORM_SCHEMA'):
                # pylint: disable=no-member
                try:
                    p_validated = platform.PLATFORM_SCHEMA(p_validated)
                except vol.Invalid as ex:
                    _comp_error(ex, '{}.{}'.format(domain, p_name),
                                p_validated)
                    continue

            platforms.append(p_validated)

        # Remove config for current component and add validated config back in.
        for filter_comp in extract_domain_configs(config, domain):
            del config[filter_comp]
        result[domain] = platforms

    return result
Пример #4
0
def check_ha_config_file(config_dir):
    """Check if Home Assistant configuration file is valid."""
    result = HomeAssistantConfig()

    def _pack_error(package, component, config, message):
        """Handle errors from packages: _log_pkg_error."""
        message = "Package {} setup failed. Component {} {}".format(
            package, component, message)
        domain = 'homeassistant.packages.{}.{}'.format(package, component)
        pack_config = core_config[CONF_PACKAGES].get(package, config)
        result.add_error(message, domain, pack_config)

    def _comp_error(ex, domain, config):
        """Handle errors from components: async_log_exception."""
        result.add_error(
            _format_config_error(ex, domain, config), domain, config)

    # Load configuration.yaml
    try:
        config_path = find_config_file(config_dir)
        if not config_path:
            return result.add_error("File configuration.yaml not found.")
        config = load_yaml_config_file(config_path)
    except HomeAssistantError as err:
        return result.add_error(err)
    finally:
        yaml.clear_secret_cache()

    # Extract and validate core [homeassistant] config
    try:
        core_config = config.pop(CONF_CORE, {})
        core_config = CORE_CONFIG_SCHEMA(core_config)
        result[CONF_CORE] = core_config
    except vol.Invalid as err:
        result.add_error(err, CONF_CORE, core_config)
        core_config = {}

    # Merge packages
    merge_packages_config(
        config, core_config.get(CONF_PACKAGES, {}), _pack_error)
    del core_config[CONF_PACKAGES]

    # Ensure we have no None values after merge
    for key, value in config.items():
        if not value:
            config[key] = {}

    # Filter out repeating config sections
    components = set(key.split(' ')[0] for key in config.keys())

    # Process and validate config
    for domain in components:
        component = get_component(domain)
        if not component:
            result.add_error("Component not found: {}".format(domain))
            continue

        if hasattr(component, 'CONFIG_SCHEMA'):
            try:
                config = component.CONFIG_SCHEMA(config)
                result[domain] = config[domain]
            except vol.Invalid as ex:
                _comp_error(ex, domain, config)
                continue

        if not hasattr(component, 'PLATFORM_SCHEMA'):
            continue

        platforms = []
        for p_name, p_config in config_per_platform(config, domain):
            # Validate component specific platform schema
            try:
                p_validated = component.PLATFORM_SCHEMA(p_config)
            except vol.Invalid as ex:
                _comp_error(ex, domain, config)
                continue

            # Not all platform components follow same pattern for platforms
            # So if p_name is None we are not going to validate platform
            # (the automation component is one of them)
            if p_name is None:
                platforms.append(p_validated)
                continue

            platform = get_platform(domain, p_name)

            if platform is None:
                result.add_error(
                    "Platform not found: {}.{}".format(domain, p_name))
                continue

            # Validate platform specific schema
            if hasattr(platform, 'PLATFORM_SCHEMA'):
                # pylint: disable=no-member
                try:
                    p_validated = platform.PLATFORM_SCHEMA(p_validated)
                except vol.Invalid as ex:
                    _comp_error(
                        ex, '{}.{}'.format(domain, p_name), p_validated)
                    continue

            platforms.append(p_validated)

        # Remove config for current component and add validated config back in.
        for filter_comp in extract_domain_configs(config, domain):
            del config[filter_comp]
        result[domain] = platforms

    return result