2016-03-09 09:25:50 +00:00
|
|
|
"""Test the bootstrapping."""
|
2016-10-30 21:18:53 +00:00
|
|
|
# pylint: disable=protected-access
|
2017-02-18 19:31:37 +00:00
|
|
|
import asyncio
|
2016-11-30 21:02:45 +00:00
|
|
|
import os
|
2017-03-05 09:41:54 +00:00
|
|
|
from unittest.mock import Mock, patch
|
2016-10-08 18:27:35 +00:00
|
|
|
import logging
|
2015-08-11 15:20:13 +00:00
|
|
|
|
2016-11-30 21:02:45 +00:00
|
|
|
import homeassistant.config as config_util
|
2017-03-05 09:41:54 +00:00
|
|
|
from homeassistant import bootstrap
|
2015-08-11 15:20:13 +00:00
|
|
|
import homeassistant.util.dt as dt_util
|
|
|
|
|
2019-04-16 20:40:21 +00:00
|
|
|
from tests.common import (
|
2019-07-31 19:25:30 +00:00
|
|
|
patch_yaml_files,
|
|
|
|
get_test_config_dir,
|
|
|
|
mock_coro,
|
|
|
|
mock_integration,
|
|
|
|
MockModule,
|
|
|
|
)
|
2016-02-14 23:08:23 +00:00
|
|
|
|
2016-03-30 05:50:38 +00:00
|
|
|
ORIG_TIMEZONE = dt_util.DEFAULT_TIME_ZONE
|
2016-11-30 21:02:45 +00:00
|
|
|
VERSION_PATH = os.path.join(get_test_config_dir(), config_util.VERSION_FILE)
|
2015-08-11 15:20:13 +00:00
|
|
|
|
2016-10-08 18:27:35 +00:00
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
2016-03-30 05:50:38 +00:00
|
|
|
|
2018-01-27 19:58:27 +00:00
|
|
|
# prevent .HA_VERSION file from being written
|
2019-07-31 19:25:30 +00:00
|
|
|
@patch("homeassistant.bootstrap.conf_util.process_ha_config_upgrade", Mock())
|
2017-03-05 09:41:54 +00:00
|
|
|
@patch(
|
2019-07-31 19:25:30 +00:00
|
|
|
"homeassistant.util.location.async_detect_location_info",
|
|
|
|
Mock(return_value=mock_coro(None)),
|
|
|
|
)
|
|
|
|
@patch("os.path.isfile", Mock(return_value=True))
|
|
|
|
@patch("os.access", Mock(return_value=True))
|
|
|
|
@patch("homeassistant.bootstrap.async_enable_logging", Mock(return_value=True))
|
2017-03-05 09:41:54 +00:00
|
|
|
def test_from_config_file(hass):
|
|
|
|
"""Test with configuration file."""
|
2019-07-31 19:25:30 +00:00
|
|
|
components = set(["browser", "conversation", "script"])
|
|
|
|
files = {"config.yaml": "".join("{}:\n".format(comp) for comp in components)}
|
2016-03-30 05:50:38 +00:00
|
|
|
|
2017-03-05 09:41:54 +00:00
|
|
|
with patch_yaml_files(files, True):
|
2019-07-31 19:25:30 +00:00
|
|
|
yield from bootstrap.async_from_config_file("config.yaml", hass)
|
2016-03-30 05:50:38 +00:00
|
|
|
|
2017-03-05 09:41:54 +00:00
|
|
|
assert components == hass.config.components
|
2017-02-18 19:31:37 +00:00
|
|
|
|
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
@patch("homeassistant.bootstrap.async_enable_logging", Mock())
|
2018-04-28 23:26:20 +00:00
|
|
|
@asyncio.coroutine
|
2017-03-05 09:41:54 +00:00
|
|
|
def test_home_assistant_core_config_validation(hass):
|
|
|
|
"""Test if we pass in wrong information for HA conf."""
|
|
|
|
# Extensive HA conf validation testing is done
|
2019-07-31 19:25:30 +00:00
|
|
|
result = yield from bootstrap.async_from_config_dict(
|
|
|
|
{"homeassistant": {"latitude": "some string"}}, hass
|
|
|
|
)
|
2017-03-05 09:41:54 +00:00
|
|
|
assert result is None
|
2018-06-16 14:48:41 +00:00
|
|
|
|
|
|
|
|
|
|
|
async def test_async_from_config_file_not_mount_deps_folder(loop):
|
|
|
|
"""Test that we not mount the deps folder inside async_from_config_file."""
|
2019-07-31 19:25:30 +00:00
|
|
|
hass = Mock(async_add_executor_job=Mock(side_effect=lambda *args: mock_coro()))
|
|
|
|
|
|
|
|
with patch("homeassistant.bootstrap.is_virtual_env", return_value=False), patch(
|
|
|
|
"homeassistant.bootstrap.async_enable_logging", return_value=mock_coro()
|
|
|
|
), patch(
|
|
|
|
"homeassistant.bootstrap.async_mount_local_lib_path", return_value=mock_coro()
|
|
|
|
) as mock_mount, patch(
|
|
|
|
"homeassistant.bootstrap.async_from_config_dict", return_value=mock_coro()
|
|
|
|
):
|
|
|
|
|
|
|
|
await bootstrap.async_from_config_file("mock-path", hass)
|
2018-06-16 14:48:41 +00:00
|
|
|
assert len(mock_mount.mock_calls) == 1
|
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
with patch("homeassistant.bootstrap.is_virtual_env", return_value=True), patch(
|
|
|
|
"homeassistant.bootstrap.async_enable_logging", return_value=mock_coro()
|
|
|
|
), patch(
|
|
|
|
"homeassistant.bootstrap.async_mount_local_lib_path", return_value=mock_coro()
|
|
|
|
) as mock_mount, patch(
|
|
|
|
"homeassistant.bootstrap.async_from_config_dict", return_value=mock_coro()
|
|
|
|
):
|
2018-06-16 14:48:41 +00:00
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
await bootstrap.async_from_config_file("mock-path", hass)
|
2018-06-16 14:48:41 +00:00
|
|
|
assert len(mock_mount.mock_calls) == 0
|
2019-03-19 18:33:50 +00:00
|
|
|
|
|
|
|
|
|
|
|
async def test_load_hassio(hass):
|
|
|
|
"""Test that we load Hass.io component."""
|
|
|
|
with patch.dict(os.environ, {}, clear=True):
|
2019-04-09 16:30:32 +00:00
|
|
|
assert bootstrap._get_domains(hass, {}) == set()
|
2019-03-19 18:33:50 +00:00
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
with patch.dict(os.environ, {"HASSIO": "1"}):
|
|
|
|
assert bootstrap._get_domains(hass, {}) == {"hassio"}
|
2019-04-16 20:40:21 +00:00
|
|
|
|
|
|
|
|
|
|
|
async def test_empty_setup(hass):
|
|
|
|
"""Test an empty set up loads the core."""
|
|
|
|
await bootstrap._async_set_up_integrations(hass, {})
|
|
|
|
for domain in bootstrap.CORE_INTEGRATIONS:
|
|
|
|
assert domain in hass.config.components, domain
|
|
|
|
|
|
|
|
|
|
|
|
async def test_core_failure_aborts(hass, caplog):
|
|
|
|
"""Test failing core setup aborts further setup."""
|
2019-07-31 19:25:30 +00:00
|
|
|
with patch(
|
|
|
|
"homeassistant.components.homeassistant.async_setup",
|
|
|
|
return_value=mock_coro(False),
|
|
|
|
):
|
|
|
|
await bootstrap._async_set_up_integrations(hass, {"group": {}})
|
2019-04-16 20:40:21 +00:00
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
assert "core failed to initialize" in caplog.text
|
2019-04-16 20:40:21 +00:00
|
|
|
# We aborted early, group not set up
|
2019-07-31 19:25:30 +00:00
|
|
|
assert "group" not in hass.config.components
|
2019-04-16 20:40:21 +00:00
|
|
|
|
|
|
|
|
|
|
|
async def test_setting_up_config(hass, caplog):
|
|
|
|
"""Test we set up domains in config."""
|
2019-07-31 19:25:30 +00:00
|
|
|
await bootstrap._async_set_up_integrations(
|
|
|
|
hass, {"group hello": {}, "homeassistant": {}}
|
|
|
|
)
|
2019-04-16 20:40:21 +00:00
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
assert "group" in hass.config.components
|
2019-04-16 20:40:21 +00:00
|
|
|
|
|
|
|
|
|
|
|
async def test_setup_after_deps_all_present(hass, caplog):
|
|
|
|
"""Test after_dependencies when all present."""
|
|
|
|
caplog.set_level(logging.DEBUG)
|
|
|
|
order = []
|
|
|
|
|
|
|
|
def gen_domain_setup(domain):
|
|
|
|
async def async_setup(hass, config):
|
|
|
|
order.append(domain)
|
|
|
|
return True
|
|
|
|
|
|
|
|
return async_setup
|
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
mock_integration(
|
|
|
|
hass, MockModule(domain="root", async_setup=gen_domain_setup("root"))
|
|
|
|
)
|
|
|
|
mock_integration(
|
|
|
|
hass,
|
|
|
|
MockModule(
|
|
|
|
domain="first_dep",
|
|
|
|
async_setup=gen_domain_setup("first_dep"),
|
|
|
|
partial_manifest={"after_dependencies": ["root"]},
|
|
|
|
),
|
|
|
|
)
|
|
|
|
mock_integration(
|
|
|
|
hass,
|
|
|
|
MockModule(
|
|
|
|
domain="second_dep",
|
|
|
|
async_setup=gen_domain_setup("second_dep"),
|
|
|
|
partial_manifest={"after_dependencies": ["first_dep"]},
|
|
|
|
),
|
|
|
|
)
|
|
|
|
|
|
|
|
await bootstrap._async_set_up_integrations(
|
|
|
|
hass, {"root": {}, "first_dep": {}, "second_dep": {}}
|
|
|
|
)
|
|
|
|
|
|
|
|
assert "root" in hass.config.components
|
|
|
|
assert "first_dep" in hass.config.components
|
|
|
|
assert "second_dep" in hass.config.components
|
|
|
|
assert order == ["root", "first_dep", "second_dep"]
|
2019-04-16 20:40:21 +00:00
|
|
|
|
|
|
|
|
|
|
|
async def test_setup_after_deps_not_trigger_load(hass, caplog):
|
|
|
|
"""Test after_dependencies does not trigger loading it."""
|
|
|
|
caplog.set_level(logging.DEBUG)
|
|
|
|
order = []
|
|
|
|
|
|
|
|
def gen_domain_setup(domain):
|
|
|
|
async def async_setup(hass, config):
|
|
|
|
order.append(domain)
|
|
|
|
return True
|
|
|
|
|
|
|
|
return async_setup
|
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
mock_integration(
|
|
|
|
hass, MockModule(domain="root", async_setup=gen_domain_setup("root"))
|
|
|
|
)
|
|
|
|
mock_integration(
|
|
|
|
hass,
|
|
|
|
MockModule(
|
|
|
|
domain="first_dep",
|
|
|
|
async_setup=gen_domain_setup("first_dep"),
|
|
|
|
partial_manifest={"after_dependencies": ["root"]},
|
|
|
|
),
|
|
|
|
)
|
|
|
|
mock_integration(
|
|
|
|
hass,
|
|
|
|
MockModule(
|
|
|
|
domain="second_dep",
|
|
|
|
async_setup=gen_domain_setup("second_dep"),
|
|
|
|
partial_manifest={"after_dependencies": ["first_dep"]},
|
|
|
|
),
|
|
|
|
)
|
|
|
|
|
|
|
|
await bootstrap._async_set_up_integrations(hass, {"root": {}, "second_dep": {}})
|
|
|
|
|
|
|
|
assert "root" in hass.config.components
|
|
|
|
assert "first_dep" not in hass.config.components
|
|
|
|
assert "second_dep" in hass.config.components
|
|
|
|
assert order == ["root", "second_dep"]
|
2019-04-16 20:40:21 +00:00
|
|
|
|
|
|
|
|
|
|
|
async def test_setup_after_deps_not_present(hass, caplog):
|
|
|
|
"""Test after_dependencies when referenced integration doesn't exist."""
|
|
|
|
caplog.set_level(logging.DEBUG)
|
|
|
|
order = []
|
|
|
|
|
|
|
|
def gen_domain_setup(domain):
|
|
|
|
async def async_setup(hass, config):
|
|
|
|
order.append(domain)
|
|
|
|
return True
|
|
|
|
|
|
|
|
return async_setup
|
|
|
|
|
2019-07-31 19:25:30 +00:00
|
|
|
mock_integration(
|
|
|
|
hass, MockModule(domain="root", async_setup=gen_domain_setup("root"))
|
|
|
|
)
|
|
|
|
mock_integration(
|
|
|
|
hass,
|
|
|
|
MockModule(
|
|
|
|
domain="second_dep",
|
|
|
|
async_setup=gen_domain_setup("second_dep"),
|
|
|
|
partial_manifest={"after_dependencies": ["first_dep"]},
|
|
|
|
),
|
|
|
|
)
|
|
|
|
|
|
|
|
await bootstrap._async_set_up_integrations(
|
|
|
|
hass, {"root": {}, "first_dep": {}, "second_dep": {}}
|
|
|
|
)
|
|
|
|
|
|
|
|
assert "root" in hass.config.components
|
|
|
|
assert "first_dep" not in hass.config.components
|
|
|
|
assert "second_dep" in hass.config.components
|
|
|
|
assert order == ["root", "second_dep"]
|