diff --git a/.coveragerc b/.coveragerc index 037128c2991..0cadbe492ab 100644 --- a/.coveragerc +++ b/.coveragerc @@ -505,7 +505,6 @@ omit = homeassistant/components/sensor/gpsd.py homeassistant/components/sensor/gtfs.py homeassistant/components/sensor/haveibeenpwned.py - homeassistant/components/sensor/hddtemp.py homeassistant/components/sensor/hp_ilo.py homeassistant/components/sensor/htu21d.py homeassistant/components/sensor/hydroquebec.py diff --git a/homeassistant/components/sensor/hddtemp.py b/homeassistant/components/sensor/hddtemp.py index fef84091b18..af4b1e61138 100644 --- a/homeassistant/components/sensor/hddtemp.py +++ b/homeassistant/components/sensor/hddtemp.py @@ -47,11 +47,10 @@ def setup_platform(hass, config, add_devices, discovery_info=None): port = config.get(CONF_PORT) disks = config.get(CONF_DISKS) - try: - hddtemp = HddTempData(host, port) - hddtemp.update() - except RuntimeError: - _LOGGER.error("Unable to fetch the data from %s:%s", host, port) + hddtemp = HddTempData(host, port) + hddtemp.update() + + if hddtemp.data is None: return False if not disks: @@ -61,8 +60,6 @@ def setup_platform(hass, config, add_devices, discovery_info=None): for disk in disks: if disk in hddtemp.data: dev.append(HddTempSensor(name, disk, hddtemp)) - else: - continue add_devices(dev, True) @@ -107,7 +104,7 @@ class HddTempSensor(Entity): """Get the latest data from HDDTemp daemon and updates the state.""" self.hddtemp.update() - if self.disk in self.hddtemp.data: + if self.hddtemp.data and self.disk in self.hddtemp.data: self._details = self.hddtemp.data[self.disk].split('|') self._state = self._details[2] else: diff --git a/tests/components/sensor/test_hddtemp.py b/tests/components/sensor/test_hddtemp.py new file mode 100644 index 00000000000..35d1c08c08a --- /dev/null +++ b/tests/components/sensor/test_hddtemp.py @@ -0,0 +1,195 @@ +"""The tests for the hddtemp platform.""" +import unittest +from unittest.mock import patch + +from homeassistant.setup import setup_component + +from tests.common import get_test_home_assistant + +VALID_CONFIG_MINIMAL = { + 'sensor': { + 'platform': 'hddtemp', + } +} + +VALID_CONFIG_NAME = { + 'sensor': { + 'platform': 'hddtemp', + 'name': 'FooBar', + } +} + +VALID_CONFIG_ONE_DISK = { + 'sensor': { + 'platform': 'hddtemp', + 'disks': [ + '/dev/sdd1', + ], + } +} + +VALID_CONFIG_WRONG_DISK = { + 'sensor': { + 'platform': 'hddtemp', + 'disks': [ + '/dev/sdx1', + ], + } +} + +VALID_CONFIG_MULTIPLE_DISKS = { + 'sensor': { + 'platform': 'hddtemp', + 'host': 'foobar.local', + 'disks': [ + '/dev/sda1', + '/dev/sdb1', + '/dev/sdc1', + ], + } +} + +VALID_CONFIG_HOST = { + 'sensor': { + 'platform': 'hddtemp', + 'host': 'alice.local', + } +} + + +class TelnetMock(): + """Mock class for the telnetlib.Telnet object.""" + + def __init__(self, host, port, timeout=0): + """Initialize Telnet object.""" + self.host = host + self.port = port + self.timeout = timeout + self.sample_data = bytes('|/dev/sda1|WDC WD30EZRX-12DC0B0|29|C|' + + '|/dev/sdb1|WDC WD15EADS-11P7B2|32|C|' + + '|/dev/sdc1|WDC WD20EARX-22MMMB0|29|C|' + + '|/dev/sdd1|WDC WD15EARS-00Z5B1|89|F|', + 'ascii') + + def read_all(self): + """Return sample values.""" + if self.host == 'alice.local': + raise ConnectionRefusedError + else: + return self.sample_data + return None + + +class TestHDDTempSensor(unittest.TestCase): + """Test the hddtemp sensor.""" + + def setUp(self): + """Set up things to run when tests begin.""" + self.hass = get_test_home_assistant() + self.config = VALID_CONFIG_ONE_DISK + self.reference = {'/dev/sda1': {'device': '/dev/sda1', + 'temperature': '29', + 'unit_of_measurement': '°C', + 'model': 'WDC WD30EZRX-12DC0B0', }, + '/dev/sdb1': {'device': '/dev/sdb1', + 'temperature': '32', + 'unit_of_measurement': '°C', + 'model': 'WDC WD15EADS-11P7B2', }, + '/dev/sdc1': {'device': '/dev/sdc1', + 'temperature': '29', + 'unit_of_measurement': '°C', + 'model': 'WDC WD20EARX-22MMMB0', }, + '/dev/sdd1': {'device': '/dev/sdd1', + 'temperature': '32', + 'unit_of_measurement': '°C', + 'model': 'WDC WD15EARS-00Z5B1', }, } + + def tearDown(self): + """Stop everything that was started.""" + self.hass.stop() + + @patch('telnetlib.Telnet', new=TelnetMock) + def test_hddtemp_min_config(self): + """Test minimal hddtemp configuration.""" + assert setup_component(self.hass, 'sensor', VALID_CONFIG_MINIMAL) + + entity = self.hass.states.all()[0].entity_id + state = self.hass.states.get(entity) + + reference = self.reference[state.attributes.get('device')] + + self.assertEqual(state.state, reference['temperature']) + self.assertEqual(state.attributes.get('device'), reference['device']) + self.assertEqual(state.attributes.get('model'), reference['model']) + self.assertEqual(state.attributes.get('unit_of_measurement'), + reference['unit_of_measurement']) + self.assertEqual(state.attributes.get('friendly_name'), + 'HD Temperature ' + reference['device']) + + @patch('telnetlib.Telnet', new=TelnetMock) + def test_hddtemp_rename_config(self): + """Test hddtemp configuration with different name.""" + assert setup_component(self.hass, 'sensor', VALID_CONFIG_NAME) + + entity = self.hass.states.all()[0].entity_id + state = self.hass.states.get(entity) + + reference = self.reference[state.attributes.get('device')] + + self.assertEqual(state.attributes.get('friendly_name'), + 'FooBar ' + reference['device']) + + @patch('telnetlib.Telnet', new=TelnetMock) + def test_hddtemp_one_disk(self): + """Test hddtemp one disk configuration.""" + assert setup_component(self.hass, 'sensor', VALID_CONFIG_ONE_DISK) + + state = self.hass.states.get('sensor.hd_temperature_devsdd1') + + reference = self.reference[state.attributes.get('device')] + + self.assertEqual(state.state, reference['temperature']) + self.assertEqual(state.attributes.get('device'), reference['device']) + self.assertEqual(state.attributes.get('model'), reference['model']) + self.assertEqual(state.attributes.get('unit_of_measurement'), + reference['unit_of_measurement']) + self.assertEqual(state.attributes.get('friendly_name'), + 'HD Temperature ' + reference['device']) + + @patch('telnetlib.Telnet', new=TelnetMock) + def test_hddtemp_wrong_disk(self): + """Test hddtemp wrong disk configuration.""" + assert setup_component(self.hass, 'sensor', VALID_CONFIG_WRONG_DISK) + + self.assertEqual(len(self.hass.states.all()), 0) + + @patch('telnetlib.Telnet', new=TelnetMock) + def test_hddtemp_multiple_disks(self): + """Test hddtemp multiple disk configuration.""" + assert setup_component(self.hass, + 'sensor', VALID_CONFIG_MULTIPLE_DISKS) + + for sensor in ['sensor.hd_temperature_devsda1', + 'sensor.hd_temperature_devsdb1', + 'sensor.hd_temperature_devsdc1']: + + state = self.hass.states.get(sensor) + + reference = self.reference[state.attributes.get('device')] + + self.assertEqual(state.state, + reference['temperature']) + self.assertEqual(state.attributes.get('device'), + reference['device']) + self.assertEqual(state.attributes.get('model'), + reference['model']) + self.assertEqual(state.attributes.get('unit_of_measurement'), + reference['unit_of_measurement']) + self.assertEqual(state.attributes.get('friendly_name'), + 'HD Temperature ' + reference['device']) + + @patch('telnetlib.Telnet', new=TelnetMock) + def test_hddtemp_host_unreachable(self): + """Test hddtemp if host unreachable.""" + assert setup_component(self.hass, 'sensor', VALID_CONFIG_HOST) + self.assertEqual(len(self.hass.states.all()), 0)