ha-core/tests/test_bootstrap.py

415 lines
12 KiB
Python
Raw Normal View History

2016-03-09 10:25:50 +01:00
"""Test the bootstrapping."""
# pylint: disable=protected-access
import logging
import os
from unittest.mock import Mock
from asynctest import patch
import pytest
2015-08-11 17:20:13 +02:00
from homeassistant import bootstrap
import homeassistant.config as config_util
from homeassistant.exceptions import HomeAssistantError
2015-08-11 17:20:13 +02:00
import homeassistant.util.dt as dt_util
from tests.common import (
MockConfigEntry,
MockModule,
flush_store,
2019-07-31 21:25:30 +02:00
get_test_config_dir,
mock_coro,
mock_integration,
)
2016-02-15 00:08:23 +01:00
2016-03-30 07:50:38 +02:00
ORIG_TIMEZONE = dt_util.DEFAULT_TIME_ZONE
VERSION_PATH = os.path.join(get_test_config_dir(), config_util.VERSION_FILE)
2015-08-11 17:20:13 +02:00
_LOGGER = logging.getLogger(__name__)
2016-03-30 07:50:38 +02:00
2019-07-31 21:25:30 +02:00
@patch("homeassistant.bootstrap.async_enable_logging", Mock())
async 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
result = await bootstrap.async_from_config_dict(
2019-07-31 21:25:30 +02:00
{"homeassistant": {"latitude": "some string"}}, hass
)
assert result is None
async def test_load_hassio(hass):
"""Test that we load Hass.io component."""
with patch.dict(os.environ, {}, clear=True):
assert bootstrap._get_domains(hass, {}) == set()
2019-07-31 21:25:30 +02:00
with patch.dict(os.environ, {"HASSIO": "1"}):
assert bootstrap._get_domains(hass, {}) == {"hassio"}
async def test_empty_setup(hass):
"""Test an empty set up loads the core."""
await bootstrap.async_from_config_dict({}, hass)
for domain in bootstrap.CORE_INTEGRATIONS:
assert domain in hass.config.components, domain
async def test_core_failure_loads_safe_mode(hass, caplog):
"""Test failing core setup aborts further setup."""
2019-07-31 21:25:30 +02:00
with patch(
"homeassistant.components.homeassistant.async_setup",
return_value=mock_coro(False),
):
await bootstrap.async_from_config_dict({"group": {}}, hass)
2019-07-31 21:25:30 +02:00
assert "core failed to initialize" in caplog.text
# We aborted early, group not set up
2019-07-31 21:25:30 +02:00
assert "group" not in hass.config.components
async def test_setting_up_config(hass, caplog):
"""Test we set up domains in config."""
2019-07-31 21:25:30 +02:00
await bootstrap._async_set_up_integrations(
hass, {"group hello": {}, "homeassistant": {}}
)
2019-07-31 21:25:30 +02:00
assert "group" in hass.config.components
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 21:25:30 +02: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"]
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 21:25:30 +02: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"]
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 21:25:30 +02: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"]
@pytest.fixture
def mock_is_virtual_env():
"""Mock enable logging."""
with patch(
"homeassistant.bootstrap.is_virtual_env", return_value=False
) as is_virtual_env:
yield is_virtual_env
@pytest.fixture
def mock_enable_logging():
"""Mock enable logging."""
with patch("homeassistant.bootstrap.async_enable_logging") as enable_logging:
yield enable_logging
@pytest.fixture
def mock_mount_local_lib_path():
"""Mock enable logging."""
with patch(
"homeassistant.bootstrap.async_mount_local_lib_path"
) as mount_local_lib_path:
yield mount_local_lib_path
@pytest.fixture
def mock_process_ha_config_upgrade():
"""Mock enable logging."""
with patch(
"homeassistant.config.process_ha_config_upgrade"
) as process_ha_config_upgrade:
yield process_ha_config_upgrade
@pytest.fixture
def mock_ensure_config_exists():
"""Mock enable logging."""
with patch(
"homeassistant.config.async_ensure_config_exists", return_value=True
) as ensure_config_exists:
yield ensure_config_exists
async def test_setup_hass(
mock_enable_logging,
mock_is_virtual_env,
mock_mount_local_lib_path,
mock_ensure_config_exists,
mock_process_ha_config_upgrade,
):
"""Test it works."""
verbose = Mock()
log_rotate_days = Mock()
log_file = Mock()
log_no_color = Mock()
with patch(
"homeassistant.config.async_hass_config_yaml",
return_value={"browser": {}, "frontend": {}},
):
hass = await bootstrap.async_setup_hass(
config_dir=get_test_config_dir(),
verbose=verbose,
log_rotate_days=log_rotate_days,
log_file=log_file,
log_no_color=log_no_color,
skip_pip=True,
safe_mode=False,
)
assert "browser" in hass.config.components
assert "safe_mode" not in hass.config.components
assert len(mock_enable_logging.mock_calls) == 1
assert mock_enable_logging.mock_calls[0][1] == (
hass,
verbose,
log_rotate_days,
log_file,
log_no_color,
)
assert len(mock_mount_local_lib_path.mock_calls) == 1
assert len(mock_ensure_config_exists.mock_calls) == 1
assert len(mock_process_ha_config_upgrade.mock_calls) == 1
async def test_setup_hass_invalid_yaml(
mock_enable_logging,
mock_is_virtual_env,
mock_mount_local_lib_path,
mock_ensure_config_exists,
mock_process_ha_config_upgrade,
):
"""Test it works."""
with patch(
"homeassistant.config.async_hass_config_yaml", side_effect=HomeAssistantError
):
hass = await bootstrap.async_setup_hass(
config_dir=get_test_config_dir(),
verbose=False,
log_rotate_days=10,
log_file="",
log_no_color=False,
skip_pip=True,
safe_mode=False,
)
assert "safe_mode" in hass.config.components
assert len(mock_mount_local_lib_path.mock_calls) == 0
async def test_setup_hass_config_dir_nonexistent(
mock_enable_logging,
mock_is_virtual_env,
mock_mount_local_lib_path,
mock_ensure_config_exists,
mock_process_ha_config_upgrade,
):
"""Test it works."""
mock_ensure_config_exists.return_value = False
assert (
await bootstrap.async_setup_hass(
config_dir=get_test_config_dir(),
verbose=False,
log_rotate_days=10,
log_file="",
log_no_color=False,
skip_pip=True,
safe_mode=False,
)
is None
)
async def test_setup_hass_safe_mode(
hass,
mock_enable_logging,
mock_is_virtual_env,
mock_mount_local_lib_path,
mock_ensure_config_exists,
mock_process_ha_config_upgrade,
):
"""Test it works."""
# Add a config entry to storage.
MockConfigEntry(domain="browser").add_to_hass(hass)
hass.config_entries._async_schedule_save()
await flush_store(hass.config_entries._store)
with patch("homeassistant.components.browser.setup") as browser_setup:
hass = await bootstrap.async_setup_hass(
config_dir=get_test_config_dir(),
verbose=False,
log_rotate_days=10,
log_file="",
log_no_color=False,
skip_pip=True,
safe_mode=True,
)
assert "safe_mode" in hass.config.components
assert len(mock_mount_local_lib_path.mock_calls) == 0
# Validate we didn't try to set up config entry.
assert "browser" not in hass.config.components
assert len(browser_setup.mock_calls) == 0
async def test_setup_hass_invalid_core_config(
mock_enable_logging,
mock_is_virtual_env,
mock_mount_local_lib_path,
mock_ensure_config_exists,
mock_process_ha_config_upgrade,
):
"""Test it works."""
with patch(
"homeassistant.config.async_hass_config_yaml",
return_value={"homeassistant": {"non-existing": 1}},
):
hass = await bootstrap.async_setup_hass(
config_dir=get_test_config_dir(),
verbose=False,
log_rotate_days=10,
log_file="",
log_no_color=False,
skip_pip=True,
safe_mode=False,
)
assert "safe_mode" in hass.config.components
async def test_setup_safe_mode_if_no_frontend(
mock_enable_logging,
mock_is_virtual_env,
mock_mount_local_lib_path,
mock_ensure_config_exists,
mock_process_ha_config_upgrade,
):
"""Test we setup safe mode if frontend didn't load."""
verbose = Mock()
log_rotate_days = Mock()
log_file = Mock()
log_no_color = Mock()
with patch(
"homeassistant.config.async_hass_config_yaml",
return_value={"map": {}, "person": {"invalid": True}},
):
hass = await bootstrap.async_setup_hass(
config_dir=get_test_config_dir(),
verbose=verbose,
log_rotate_days=log_rotate_days,
log_file=log_file,
log_no_color=log_no_color,
skip_pip=True,
safe_mode=False,
)
assert "safe_mode" in hass.config.components