def test_component_platform_not_found(self): """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', } 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('badplatform.yaml')) change_yaml_files(res) assert res['components'] == {'light': [], 'group': None} 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'])
def test_secrets(self, mock_get_loop): """Test secrets config checking method.""" files = { get_test_config_dir('secret.yaml'): ( BASE_CONFIG + 'http:\n' ' api_password: !secret http_pw'), 'secrets.yaml': ('logger: debug\n' 'http_pw: abc123'), } self.maxDiff = None 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) # convert secrets OrderedDict to dict for assertequal for key, val in res['secret_cache'].items(): res['secret_cache'][key] = dict(val) self.assertDictEqual({ 'components': {'http': {'api_password': '******', 'server_port': 8123}}, 'except': {}, 'secret_cache': {secrets_path: {'http_pw': 'abc123'}}, 'secrets': {'http_pw': 'abc123'}, 'yaml_files': ['.../secret.yaml', '.../secrets.yaml'] }, res)
def test_component_platform_not_found(self, mock_get_loop): """Test errors if component or platform not found.""" files = { 'badcomponent.yaml': BASE_CONFIG + 'beer:', 'badplatform.yaml': BASE_CONFIG + 'light:\n platform: 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']}, 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('badplatform.yaml')) change_yaml_files(res) self.assertDictEqual({'light': []}, res['components']) self.assertDictEqual({check_config.ERROR_STR: ['Platform not found: light.beer']}, res['except']) self.assertDictEqual({}, res['secret_cache']) self.assertDictEqual({}, res['secrets']) self.assertListEqual(['.../badplatform.yaml'], res['yaml_files'])
def test_setup_with_multiple_hosts(self, mock_phue): """Multiple hosts specified in the config file.""" mock_bridge = mock_phue.Bridge with assert_setup_component(1): with patch('homeassistant.helpers.discovery.load_platform') \ as mock_load: self.assertTrue(setup_component( self.hass, hue.DOMAIN, {hue.DOMAIN: {hue.CONF_BRIDGES: [ {CONF_HOST: 'localhost'}, {CONF_HOST: '192.168.0.1'}]}})) mock_bridge.assert_has_calls([ call( 'localhost', config_file_path=get_test_config_dir( hue.PHUE_CONFIG_FILE)), call( '192.168.0.1', config_file_path=get_test_config_dir( hue.PHUE_CONFIG_FILE))]) mock_load.mock_bridge.assert_not_called() mock_load.assert_has_calls([ call( self.hass, 'light', hue.DOMAIN, {'bridge_id': '127.0.0.1'}), call( self.hass, 'light', hue.DOMAIN, {'bridge_id': '192.168.0.1'}), ], any_order=True) self.assertTrue(hue.DOMAIN in self.hass.data) self.assertEqual(2, len(self.hass.data[hue.DOMAIN]))
def test_config_component_platform_fail_validation(self): """Test errors if component & platform not found.""" files = { 'component.yaml': 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({ 'components': {}, 'except': {'http': {'password': '******'}}, 'secret_cache': {}, 'secrets': {}, 'yaml_files': ['.../component.yaml'] }, res) files = { 'platform.yaml': (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({ 'components': {'mqtt': {'keepalive': 60, 'port': 1883, 'protocol': '3.1.1'}}, 'except': {'light.mqtt_json': {'platform': 'mqtt_json'}}, 'secret_cache': {}, 'secrets': {}, 'yaml_files': ['.../platform.yaml'] }, res)
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) files = { YAML_CONFIG_FILE: BASE_CONFIG + 'beer:', } with patch_yaml_files(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 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', ]} assert res['secret_cache'] == {} assert res['secrets'] == {} assert len(res['yaml_files']) == 1
def test_secrets(self, isfile_patch): """Test secrets config checking method.""" secrets_path = get_test_config_dir('secrets.yaml') files = { get_test_config_dir(YAML_CONFIG_FILE): BASE_CONFIG + ( 'http:\n' ' api_password: !secret http_pw'), secrets_path: ( 'logger: debug\n' 'http_pw: abc123'), } with patch_yaml_files(files): res = check_config.check(get_test_config_dir(), True) assert res['except'] == {} assert res['components'].keys() == {'homeassistant', 'http'} assert res['components']['http'] == { 'api_password': '******', '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']
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, loop, ): """Test it works.""" mock_ensure_config_exists.return_value = False assert ( await bootstrap.async_setup_hass( runner.RuntimeConfig( 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, patch( "homeassistant.components.http.start_http_server_and_save_config"): 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_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 ), patch( "homeassistant.components.http.start_http_server_and_save_config"): 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
def setUpModule(): # pylint: disable=invalid-name """Initalization of a Home Assistant server and Slave instance.""" global hass, slave, master_api hass = get_test_home_assistant() hass.bus.listen("test_event", lambda _: _) hass.states.set("test.test", "a_state") bootstrap.setup_component( hass, http.DOMAIN, {http.DOMAIN: {http.CONF_API_PASSWORD: API_PASSWORD, http.CONF_SERVER_PORT: MASTER_PORT}} ) bootstrap.setup_component(hass, "api") hass.start() time.sleep(0.05) master_api = remote.API("127.0.0.1", API_PASSWORD, MASTER_PORT) # Start slave slave = remote.HomeAssistant(master_api) slave.config.config_dir = get_test_config_dir() bootstrap.setup_component( slave, http.DOMAIN, {http.DOMAIN: {http.CONF_API_PASSWORD: API_PASSWORD, http.CONF_SERVER_PORT: SLAVE_PORT}} ) slave.start()
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, loop, ): """Test it works.""" with patch( "homeassistant.config.async_hass_config_yaml", return_value={"homeassistant": { "non-existing": 1 }}, ): hass = await bootstrap.async_setup_hass( runner.RuntimeConfig( 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
def test_setup_with_phue_conf(self, mock_phue): """No host in the config file, but one is cached in phue.conf.""" mock_bridge = mock_phue.Bridge with assert_setup_component(1): with patch( 'homeassistant.components.hue._find_host_from_config', return_value='localhost'): with patch('homeassistant.helpers.discovery.load_platform') \ as mock_load: self.assertTrue(setup_component( self.hass, hue.DOMAIN, {hue.DOMAIN: {hue.CONF_BRIDGES: [ {CONF_FILENAME: 'phue.conf'}]}})) mock_bridge.assert_called_once_with( 'localhost', config_file_path=get_test_config_dir( hue.PHUE_CONFIG_FILE)) mock_load.assert_called_once_with( self.hass, 'light', hue.DOMAIN, {'bridge_id': '127.0.0.1'}) self.assertTrue(hue.DOMAIN in self.hass.data) self.assertEqual(1, len(self.hass.data[hue.DOMAIN]))
def test_setup_bridge_registration_succeeds(self, mock_phue): """Test a registration success sequence.""" mock_bridge = mock_phue.Bridge mock_phue.PhueRegistrationException = Exception mock_bridge.side_effect = [ # First call, raise because not registered mock_phue.PhueRegistrationException(1, 2), # Second call, registration is done None, ] bridge = hue.HueBridge('localhost', self.hass, hue.PHUE_CONFIG_FILE) bridge.setup() self.assertFalse(bridge.configured) self.assertFalse(bridge.config_request_id is None) # Simulate the user confirming the registration self.hass.services.call( configurator.DOMAIN, configurator.SERVICE_CONFIGURE, {configurator.ATTR_CONFIGURE_ID: bridge.config_request_id}) self.hass.block_till_done() self.assertTrue(bridge.configured) self.assertTrue(bridge.config_request_id is None) # We should see a total of two identical calls args = call( 'localhost', config_file_path=get_test_config_dir(hue.PHUE_CONFIG_FILE)) mock_bridge.assert_has_calls([args, args]) # Make sure the request is done self.assertEqual(1, len(self.hass.states.all())) self.assertEqual('configured', self.hass.states.all()[0].state)
def test_bad_core_config(mock_is_file, loop): """Test a bad core config setup.""" files = {YAML_CONFIG_FILE: BAD_CORE_CONFIG} with patch_yaml_files(files): res = check_config.check(get_test_config_dir()) assert res["except"].keys() == {"homeassistant"} assert res["except"]["homeassistant"][1] == {"unit_system": "bad"}
def setUp(self): """Create & load secrets file.""" config_dir = get_test_config_dir() self._yaml_path = os.path.join(config_dir, YAML_CONFIG_FILE) self._secret_path = os.path.join(config_dir, yaml.SECRET_YAML) self._sub_folder_path = os.path.join(config_dir, "subFolder") self._unrelated_path = os.path.join(config_dir, "unrelated") load_yaml( self._secret_path, "http_pw: pwhttp\n" "comp1_un: un1\n" "comp1_pw: pw1\n" "stale_pw: not_used\n" "logger: debug\n", ) self._yaml = load_yaml( self._yaml_path, "http:\n" " api_password: !secret http_pw\n" "component:\n" " username: !secret comp1_un\n" " password: !secret comp1_pw\n" "", yaml_loader.Secrets(config_dir), )
def normalize_yaml_files(check_dict): """Remove configuration path from ['yaml_files'].""" root = get_test_config_dir() return [ key.replace(root, "...") for key in sorted(check_dict["yaml_files"].keys()) ]
async def test_setup_hass_safe_mode( mock_enable_logging, mock_is_virtual_env, mock_mount_local_lib_path, mock_ensure_config_exists, mock_process_ha_config_upgrade, loop, ): """Test it works.""" with patch( "homeassistant.components.browser.setup") as browser_setup, patch( "homeassistant.config_entries.ConfigEntries.async_domains", return_value=["browser"], ): hass = await bootstrap.async_setup_hass( runner.RuntimeConfig( 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_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 } }, ), patch( "homeassistant.components.http.start_http_server_and_save_config"): 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
def test_bad_core_config(isfile_patch, loop): """Test a bad core config setup.""" files = {YAML_CONFIG_FILE: BAD_CORE_CONFIG} with patch_yaml_files(files): res = check_config.check(get_test_config_dir()) assert res["except"].keys() == {"openpeerpower"} assert res["except"]["openpeerpower"][1] == {"unit_system": "bad"}
def setUp(self): # pylint: disable=invalid-name """Create & load secrets file.""" config_dir = get_test_config_dir() yaml.clear_secret_cache() self._yaml_path = os.path.join(config_dir, config_util.YAML_CONFIG_FILE) self._secret_path = os.path.join(config_dir, yaml._SECRET_YAML) self._sub_folder_path = os.path.join(config_dir, 'subFolder') if not os.path.exists(self._sub_folder_path): os.makedirs(self._sub_folder_path) self._unrelated_path = os.path.join(config_dir, 'unrelated') if not os.path.exists(self._unrelated_path): os.makedirs(self._unrelated_path) load_yaml(self._secret_path, 'http_pw: pwhttp\n' 'comp1_un: un1\n' 'comp1_pw: pw1\n' 'stale_pw: not_used\n' 'logger: debug\n') self._yaml = load_yaml(self._yaml_path, 'http:\n' ' api_password: !secret http_pw\n' 'component:\n' ' username: !secret comp1_un\n' ' password: !secret comp1_pw\n' '')
def setUpModule(): # pylint: disable=invalid-name """Initalization of a Home Assistant server and Slave instance.""" global hass, slave, master_api hass = get_test_home_assistant() hass.bus.listen("test_event", lambda _: _) hass.states.set("test.test", "a_state") bootstrap.setup_component( hass, http.DOMAIN, {http.DOMAIN: {http.CONF_API_PASSWORD: API_PASSWORD, http.CONF_SERVER_PORT: MASTER_PORT}} ) bootstrap.setup_component(hass, "api") hass.start() time.sleep(0.05) master_api = remote.API("127.0.0.1", API_PASSWORD, MASTER_PORT) # Start slave loop = asyncio.new_event_loop() # FIXME: should not be a daemon threading.Thread(name="SlaveThread", daemon=True, target=loop.run_forever).start() slave = remote.HomeAssistant(master_api, loop=loop) slave.config.config_dir = get_test_config_dir() slave.config.skip_pip = True bootstrap.setup_component( slave, http.DOMAIN, {http.DOMAIN: {http.CONF_API_PASSWORD: API_PASSWORD, http.CONF_SERVER_PORT: SLAVE_PORT}} ) with patch.object(ha, "_async_create_timer", return_value=None): slave.start()
def test_setup_with_host(self, mock_phue): """Host specified in the config file.""" mock_bridge = mock_phue.Bridge with assert_setup_component(1): with patch('homeassistant.helpers.discovery.load_platform') \ as mock_load: self.assertTrue( setup_component(self.hass, hue.DOMAIN, { hue.DOMAIN: { hue.CONF_BRIDGES: [{ CONF_HOST: 'localhost' }] } })) mock_bridge.assert_called_once_with( 'localhost', config_file_path=get_test_config_dir(hue.PHUE_CONFIG_FILE)) mock_load.assert_called_once_with(self.hass, 'light', hue.DOMAIN, {'bridge_id': '127.0.0.1'}) self.assertTrue(hue.DOMAIN in self.hass.data) self.assertEqual(1, len(self.hass.data[hue.DOMAIN]))
def test_setup_bridge_registration_succeeds(self, mock_phue): """Test a registration success sequence.""" mock_bridge = mock_phue.Bridge mock_phue.PhueRegistrationException = Exception mock_bridge.side_effect = [ # First call, raise because not registered mock_phue.PhueRegistrationException(1, 2), # Second call, registration is done None, ] bridge = hue.HueBridge( 'localhost', self.hass, hue.PHUE_CONFIG_FILE, None) bridge.setup() self.assertFalse(bridge.configured) self.assertFalse(bridge.config_request_id is None) # Simulate the user confirming the registration self.hass.services.call( configurator.DOMAIN, configurator.SERVICE_CONFIGURE, {configurator.ATTR_CONFIGURE_ID: bridge.config_request_id}) self.hass.block_till_done() self.assertTrue(bridge.configured) self.assertTrue(bridge.config_request_id is None) # We should see a total of two identical calls args = call( 'localhost', config_file_path=get_test_config_dir(hue.PHUE_CONFIG_FILE)) mock_bridge.assert_has_calls([args, args]) # Make sure the request is done self.assertEqual(1, len(self.hass.states.all())) self.assertEqual('configured', self.hass.states.all()[0].state)
def test_secrets(self): """Test secrets config checking method.""" files = { get_test_config_dir('secret.yaml'): (BASE_CONFIG + 'http:\n' ' api_password: !secret http_pw'), 'secrets.yaml': ('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) # convert secrets OrderedDict to dict for assertequal for key, val in res['secret_cache'].items(): res['secret_cache'][key] = dict(val) self.assertDictEqual( { 'components': { 'http': { 'api_password': '******', '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_config_component_platform_fail_validation(self): """Test errors if component & platform not found.""" files = { 'component.yaml': 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': '******'}}, res['except'] ) self.assertDictEqual({}, res['secret_cache']) self.assertDictEqual({}, res['secrets']) self.assertListEqual(['.../component.yaml'], res['yaml_files']) files = { 'platform.yaml': (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'])
def test_config_component_platform_fail_validation(self): """Test errors if component & platform not found.""" files = { 'component.yaml': 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( { 'components': {}, 'except': { 'http': { 'password': '******' } }, 'secret_cache': {}, 'secrets': {}, 'yaml_files': ['.../component.yaml'] }, res) files = { 'platform.yaml': (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( { 'components': { 'mqtt': { 'keepalive': 60, 'port': 1883, 'protocol': '3.1.1' } }, 'except': { 'light.mqtt_json': { 'platform': 'mqtt_json' } }, 'secret_cache': {}, 'secrets': {}, 'yaml_files': ['.../platform.yaml'] }, res)
def test_bad_core_config(self, isfile_patch): """Test a bad core config setup.""" files = { YAML_CONFIG_FILE: BAD_CORE_CONFIG, } with patch_yaml_files(files): res = check_config.check(get_test_config_dir()) assert res['except'].keys() == {'homeassistant'} assert res['except']['homeassistant'][1] == {'unit_system': 'bad'}
def setUp(self): """Initialize values for this testcase class.""" self.hass = get_test_home_assistant() self.cache = get_test_config_dir(base_ring.DEFAULT_CACHEDB) self.config = { 'username': '******', 'password': '******', 'monitored_conditions': ['ding', 'motion'], }
def test_bad_logger_value(self, mock_error): """Ensure logger: debug was removed.""" load_yaml(self._secret_path, "logger: info\npw: abc") load_yaml( self._yaml_path, "api_password: !secret pw", yaml_loader.Secrets(get_test_config_dir()), ) assert mock_error.call_count == 1, "Expected an error about logger: value"
def setUp(self): """Initialize values for this testcase class.""" self.hass = get_test_home_assistant() self.cache = get_test_config_dir(base_ring.DEFAULT_CACHEDB) self.config = { "username": "******", "password": "******", "monitored_conditions": ["ding", "motion"], }
def test_bridge_configure_and_discovered(self, mock_phue): """Bridge is in the config file, then we discover it.""" mock_bridge = mock_phue.Bridge mock_service = MagicMock() discovery_info = {'host': '192.168.1.10', 'serial': 'foobar'} with assert_setup_component(1): with patch('homeassistant.helpers.discovery.load_platform') \ as mock_load: # First we set up the component from config self.assertTrue( setup_component( self.hass, hue.DOMAIN, { hue.DOMAIN: { hue.CONF_BRIDGES: [{ CONF_HOST: '192.168.1.10' }] } })) mock_bridge.assert_called_once_with( '192.168.1.10', config_file_path=get_test_config_dir(hue.PHUE_CONFIG_FILE)) calls_to_mock_load = [ call(self.hass, 'light', hue.DOMAIN, {'bridge_id': '192.168.1.10'}), ] mock_load.assert_has_calls(calls_to_mock_load) self.assertTrue(hue.DOMAIN in self.hass.data) self.assertEqual(1, len(self.hass.data[hue.DOMAIN])) # Then we discover the same bridge hue.bridge_discovered(self.hass, mock_service, discovery_info) # No additional calls mock_bridge.assert_called_once_with( '192.168.1.10', config_file_path=get_test_config_dir(hue.PHUE_CONFIG_FILE)) mock_load.assert_has_calls(calls_to_mock_load) # Still only one self.assertTrue(hue.DOMAIN in self.hass.data) self.assertEqual(1, len(self.hass.data[hue.DOMAIN]))
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, loop, ): """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={ "homeassistant": { "internal_url": "http://192.168.1.100:8123", "external_url": "https://abcdef.ui.nabu.casa", }, "map": {}, "person": { "invalid": True }, }, ): hass = await bootstrap.async_setup_hass( runner.RuntimeConfig( 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 assert hass.config.config_dir == get_test_config_dir() assert hass.config.skip_pip assert hass.config.internal_url == "http://192.168.1.100:8123" assert hass.config.external_url == "https://abcdef.ui.nabu.casa"
def test_secrets(self): """Test secrets config checking method.""" files = { get_test_config_dir('secret.yaml'): (BASE_CONFIG + 'http:\n' ' api_password: !secret http_pw'), 'secrets.yaml': ('logger: debug\n' 'http_pw: abc123'), } self.maxDiff = None 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) # convert secrets OrderedDict to dict for assertequal for key, val in res['secret_cache'].items(): res['secret_cache'][key] = dict(val) self.assertDictEqual( { 'components': { 'http': { 'api_password': '******', 'server_port': 8123, '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_bridge_configure_and_discovered(self, mock_phue): """Bridge is in the config file, then we discover it.""" mock_bridge = mock_phue.Bridge mock_service = MagicMock() discovery_info = {'host': '192.168.1.10', 'serial': 'foobar'} with assert_setup_component(1): with patch('homeassistant.helpers.discovery.load_platform') \ as mock_load: # First we set up the component from config self.assertTrue(setup_component( self.hass, hue.DOMAIN, {hue.DOMAIN: {hue.CONF_BRIDGES: [ {CONF_HOST: '192.168.1.10'}]}})) mock_bridge.assert_called_once_with( '192.168.1.10', config_file_path=get_test_config_dir( hue.PHUE_CONFIG_FILE)) calls_to_mock_load = [ call( self.hass, 'light', hue.DOMAIN, {'bridge_id': '192.168.1.10'}), ] mock_load.assert_has_calls(calls_to_mock_load) self.assertTrue(hue.DOMAIN in self.hass.data) self.assertEqual(1, len(self.hass.data[hue.DOMAIN])) # Then we discover the same bridge hue.bridge_discovered(self.hass, mock_service, discovery_info) # No additional calls mock_bridge.assert_called_once_with( '192.168.1.10', config_file_path=get_test_config_dir( hue.PHUE_CONFIG_FILE)) mock_load.assert_has_calls(calls_to_mock_load) # Still only one self.assertTrue(hue.DOMAIN in self.hass.data) self.assertEqual(1, len(self.hass.data[hue.DOMAIN]))
def setUpModule(): # pylint: disable=invalid-name """ Initalizes a Home Assistant server. """ global KNOWN_DEV_PATH KNOWN_DEV_PATH = os.path.join(get_test_config_dir(), device_tracker.KNOWN_DEVICES_FILE) with open(KNOWN_DEV_PATH, 'w') as fil: fil.write('device,name,track,picture\n') fil.write('DEV1,device 1,1,http://example.com/dev1.jpg\n') fil.write('DEV2,device 2,1,http://example.com/dev2.jpg\n')
def setUpModule(): # pylint: disable=invalid-name """ Initalizes a Home Assistant server. """ global KNOWN_DEV_PATH KNOWN_DEV_PATH = os.path.join(get_test_config_dir(), device_tracker.CSV_DEVICES) with open(KNOWN_DEV_PATH, 'w') as fil: fil.write('device,name,track,picture\n') fil.write('DEV1,device 1,1,http://example.com/dev1.jpg\n') fil.write('DEV2,device 2,1,http://example.com/dev2.jpg\n')
def test_config_platform_valid(isfile_patch, loop): """Test a valid platform setup.""" files = {YAML_CONFIG_FILE: BASE_CONFIG + "light:\n platform: demo"} with patch_yaml_files(files): 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_bootstrap_error(loop): """Test a valid platform setup.""" files = {YAML_CONFIG_FILE: BASE_CONFIG + "automation: !include no.yaml"} with patch_yaml_files(files): 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"] == {} # No components, load failed assert res["secret_cache"] == {} assert res["secrets"] == {} assert res["yaml_files"] == {}
def test_secrets(self): """Test secrets config checking method.""" files = { get_test_config_dir('secret.yaml'): ( BASE_CONFIG + 'http:\n' ' api_password: !secret http_pw'), 'secrets.yaml': ('logger: debug\n' 'http_pw: abc123'), } self.maxDiff = None 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) # convert secrets OrderedDict to dict for assertequal for key, val in res['secret_cache'].items(): res['secret_cache'][key] = dict(val) self.assertDictEqual({ 'components': {'http': {'api_password': '******', 'cors_allowed_origins': [], 'development': '0', 'ip_ban_enabled': True, 'login_attempts_threshold': -1, 'server_host': '0.0.0.0', 'server_port': 8123, 'ssl_certificate': None, 'ssl_key': None, '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 change_yaml_files(check_dict): """Change the ['yaml_files'] property and remove the config path. Also removes other files like service.yaml that gets loaded """ 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):])
def test_config_platform_valid(self, isfile_patch): """Test a valid platform setup.""" files = { YAML_CONFIG_FILE: BASE_CONFIG + 'light:\n platform: demo', } with patch_yaml_files(files): 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_setup_bridge_connection_refused(self, mock_phue): """Test a registration failed with a connection refused exception.""" mock_bridge = mock_phue.Bridge mock_bridge.side_effect = ConnectionRefusedError() bridge = hue.HueBridge('localhost', self.hass, hue.PHUE_CONFIG_FILE) bridge.setup() self.assertFalse(bridge.configured) self.assertTrue(bridge.config_request_id is None) mock_bridge.assert_called_once_with( 'localhost', config_file_path=get_test_config_dir(hue.PHUE_CONFIG_FILE))
def test_config_component_platform_fail_validation(self, isfile_patch): """Test errors if component & platform not found.""" files = { YAML_CONFIG_FILE: BASE_CONFIG + 'http:\n password: err123', } with patch_yaml_files(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': '******'}} assert res['secret_cache'] == {} assert res['secrets'] == {} assert len(res['yaml_files']) == 1 files = { 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()) 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_bootstrap_error(self): """Test a valid platform setup.""" files = { YAML_CONFIG_FILE: BASE_CONFIG + 'automation: !include no.yaml', } with patch_yaml_files(files): 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'] == {} # No components, load failed assert res['secret_cache'] == {} assert res['secrets'] == {} assert res['yaml_files'] == {}
def test_config_component_platform_fail_validation(self, isfile_patch): """Test errors if component & platform not found.""" files = { YAML_CONFIG_FILE: BASE_CONFIG + 'http:\n password: err123', } with patch_yaml_files(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': '******'}} assert res['secret_cache'] == {} assert res['secrets'] == {} assert len(res['yaml_files']) == 1 files = { 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()) 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_config_platform_valid(self, mock_get_loop): """Test a valid platform setup.""" files = { 'light.yaml': 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'}]}, 'except': {}, 'secret_cache': {}, 'secrets': {}, 'yaml_files': ['.../light.yaml'] }, res)
def test_setup_bridge_registration_exception(self, mock_phue): """Test a registration failed with an exception.""" mock_bridge = mock_phue.Bridge mock_phue.PhueRegistrationException = Exception mock_bridge.side_effect = mock_phue.PhueRegistrationException(1, 2) bridge = hue.HueBridge('localhost', self.hass, hue.PHUE_CONFIG_FILE) bridge.setup() self.assertFalse(bridge.configured) self.assertFalse(bridge.config_request_id is None) self.assertTrue(isinstance(bridge.config_request_id, str)) mock_bridge.assert_called_once_with( 'localhost', config_file_path=get_test_config_dir(hue.PHUE_CONFIG_FILE))
def setUp(self): """Initialize values for this testcase class.""" self.hass = get_test_home_assistant() self.cache = get_test_config_dir(base_ring.DEFAULT_CACHEDB) self.config = { 'username': '******', 'password': '******', 'monitored_conditions': [ 'battery', 'last_activity', 'last_ding', 'last_motion', 'volume', 'wifi_signal_category', 'wifi_signal_strength'] }
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', } with patch_yaml_files(files): res = check_config.check(get_test_config_dir('badbootstrap.yaml')) change_yaml_files(res) err = res['except'].pop(check_config.ERROR_STR) assert len(err) == 1 assert res['except'] == {} assert res['components'] == {} assert res['secret_cache'] == {} assert res['secrets'] == {}
def test_setup_bridge_registration_retry(self, mock_phue): """ Test a registration retry sequence. This may happen when we start the registration process, the user responds to the request but we fail to confirm it with the bridge. """ mock_bridge = mock_phue.Bridge mock_phue.PhueRegistrationException = Exception mock_bridge.side_effect = [ # First call, raise because not registered mock_phue.PhueRegistrationException(1, 2), # Second call, for whatever reason authentication fails mock_phue.PhueRegistrationException(1, 2), ] bridge = hue.HueBridge( 'localhost', self.hass, hue.PHUE_CONFIG_FILE, None) bridge.setup() self.assertFalse(bridge.configured) self.assertFalse(bridge.config_request_id is None) # Simulate the user confirming the registration self.hass.services.call( configurator.DOMAIN, configurator.SERVICE_CONFIGURE, {configurator.ATTR_CONFIGURE_ID: bridge.config_request_id}) self.hass.block_till_done() self.assertFalse(bridge.configured) self.assertFalse(bridge.config_request_id is None) # We should see a total of two identical calls args = call( 'localhost', config_file_path=get_test_config_dir(hue.PHUE_CONFIG_FILE)) mock_bridge.assert_has_calls([args, args]) # Make sure the request is done self.assertEqual(1, len(self.hass.states.all())) self.assertEqual('configure', self.hass.states.all()[0].state) self.assertEqual( 'Failed to register, please try again.', self.hass.states.all()[0].attributes.get(configurator.ATTR_ERRORS))
def setUp(self): # pylint: disable=invalid-name """Create & load secrets file.""" config_dir = get_test_config_dir() self._yaml_path = os.path.join(config_dir, config_util.YAML_CONFIG_FILE) self._secret_path = os.path.join(config_dir, 'secrets.yaml') load_yaml(self._secret_path, 'http_pw: pwhttp\n' 'comp1_un: un1\n' 'comp1_pw: pw1\n' 'stale_pw: not_used\n' 'logger: debug\n') self._yaml = load_yaml(self._yaml_path, 'http:\n' ' api_password: !secret http_pw\n' 'component:\n' ' username: !secret comp1_un\n' ' password: !secret comp1_pw\n' '')
def test_package_invalid(self): \ # pylint: disable=no-self-use,invalid-name """Test a valid platform setup.""" files = { 'bad.yaml': 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) 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['secret_cache'] == {} assert res['secrets'] == {}