"""Test the bootstrapping.""" # pylint: disable=protected-access import asyncio import os from unittest.mock import Mock, patch import logging import homeassistant.config as config_util from homeassistant import bootstrap import homeassistant.util.dt as dt_util from tests.common import ( patch_yaml_files, get_test_config_dir, mock_coro, mock_integration, MockModule, ) ORIG_TIMEZONE = dt_util.DEFAULT_TIME_ZONE VERSION_PATH = os.path.join(get_test_config_dir(), config_util.VERSION_FILE) _LOGGER = logging.getLogger(__name__) # prevent .HA_VERSION file from being written @patch("homeassistant.bootstrap.conf_util.process_ha_config_upgrade", Mock()) @patch( "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)) def test_from_config_file(hass): """Test with configuration file.""" components = set(["browser", "conversation", "script"]) files = {"config.yaml": "".join("{}:\n".format(comp) for comp in components)} with patch_yaml_files(files, True): yield from bootstrap.async_from_config_file("config.yaml", hass) assert components == hass.config.components @patch("homeassistant.bootstrap.async_enable_logging", Mock()) @asyncio.coroutine 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 = yield from bootstrap.async_from_config_dict( {"homeassistant": {"latitude": "some string"}}, hass ) assert result is None 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.""" 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) assert len(mock_mount.mock_calls) == 1 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() ): await bootstrap.async_from_config_file("mock-path", hass) assert len(mock_mount.mock_calls) == 0 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() 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_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.""" with patch( "homeassistant.components.homeassistant.async_setup", return_value=mock_coro(False), ): await bootstrap._async_set_up_integrations(hass, {"group": {}}) assert "core failed to initialize" in caplog.text # We aborted early, group not set up assert "group" not in hass.config.components async def test_setting_up_config(hass, caplog): """Test we set up domains in config.""" await bootstrap._async_set_up_integrations( hass, {"group hello": {}, "homeassistant": {}} ) 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 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 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 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"]