remove the need to have query feature support (#18942)

* remove the need to have query feature support

Some InfluxDB servers don't have /query support feature but are still valid servers for storing data.
Usually those servers are proxies to others timeseries databases.
The change proposes to still validate the configuration but with less requirements on the server side.

* `.query` call is replaced by `.write_points`

* no more query call in the influxdb component. remove test

* reset mock after the setup and before the test

* remove unused import

* reset mock stats after component setup
pull/19033/head
Pierre Gronlier 2018-12-04 09:59:03 +01:00 committed by Paulus Schoutsen
parent 75b855ef93
commit a6511fc0b9
2 changed files with 19 additions and 26 deletions

View File

@ -136,7 +136,7 @@ def setup(hass, config):
try: try:
influx = InfluxDBClient(**kwargs) influx = InfluxDBClient(**kwargs)
influx.query("SHOW SERIES LIMIT 1;", database=conf[CONF_DB_NAME]) influx.write_points([])
except (exceptions.InfluxDBClientError, except (exceptions.InfluxDBClientError,
requests.exceptions.ConnectionError) as exc: requests.exceptions.ConnectionError) as exc:
_LOGGER.error("Database host is not accessible due to '%s', please " _LOGGER.error("Database host is not accessible due to '%s', please "

View File

@ -3,8 +3,6 @@ import datetime
import unittest import unittest
from unittest import mock from unittest import mock
import influxdb as influx_client
from homeassistant.setup import setup_component from homeassistant.setup import setup_component
import homeassistant.components.influxdb as influxdb import homeassistant.components.influxdb as influxdb
from homeassistant.const import EVENT_STATE_CHANGED, STATE_OFF, STATE_ON, \ from homeassistant.const import EVENT_STATE_CHANGED, STATE_OFF, STATE_ON, \
@ -48,7 +46,7 @@ class TestInfluxDB(unittest.TestCase):
assert self.hass.bus.listen.called assert self.hass.bus.listen.called
assert \ assert \
EVENT_STATE_CHANGED == self.hass.bus.listen.call_args_list[0][0][0] EVENT_STATE_CHANGED == self.hass.bus.listen.call_args_list[0][0][0]
assert mock_client.return_value.query.called assert mock_client.return_value.write_points.call_count == 1
def test_setup_config_defaults(self, mock_client): def test_setup_config_defaults(self, mock_client):
"""Test the setup with default configuration.""" """Test the setup with default configuration."""
@ -82,20 +80,7 @@ class TestInfluxDB(unittest.TestCase):
assert not setup_component(self.hass, influxdb.DOMAIN, config) assert not setup_component(self.hass, influxdb.DOMAIN, config)
def test_setup_query_fail(self, mock_client): def _setup(self, mock_client, **kwargs):
"""Test the setup for query failures."""
config = {
'influxdb': {
'host': 'host',
'username': 'user',
'password': 'pass',
}
}
mock_client.return_value.query.side_effect = \
influx_client.exceptions.InfluxDBClientError('fake')
assert not setup_component(self.hass, influxdb.DOMAIN, config)
def _setup(self, **kwargs):
"""Set up the client.""" """Set up the client."""
config = { config = {
'influxdb': { 'influxdb': {
@ -111,10 +96,11 @@ class TestInfluxDB(unittest.TestCase):
config['influxdb'].update(kwargs) config['influxdb'].update(kwargs)
assert setup_component(self.hass, influxdb.DOMAIN, config) assert setup_component(self.hass, influxdb.DOMAIN, config)
self.handler_method = self.hass.bus.listen.call_args_list[0][0][1] self.handler_method = self.hass.bus.listen.call_args_list[0][0][1]
mock_client.return_value.write_points.reset_mock()
def test_event_listener(self, mock_client): def test_event_listener(self, mock_client):
"""Test the event listener.""" """Test the event listener."""
self._setup() self._setup(mock_client)
# map of HA State to valid influxdb [state, value] fields # map of HA State to valid influxdb [state, value] fields
valid = { valid = {
@ -176,7 +162,7 @@ class TestInfluxDB(unittest.TestCase):
def test_event_listener_no_units(self, mock_client): def test_event_listener_no_units(self, mock_client):
"""Test the event listener for missing units.""" """Test the event listener for missing units."""
self._setup() self._setup(mock_client)
for unit in (None, ''): for unit in (None, ''):
if unit: if unit:
@ -207,7 +193,7 @@ class TestInfluxDB(unittest.TestCase):
def test_event_listener_inf(self, mock_client): def test_event_listener_inf(self, mock_client):
"""Test the event listener for missing units.""" """Test the event listener for missing units."""
self._setup() self._setup(mock_client)
attrs = {'bignumstring': '9' * 999, 'nonumstring': 'nan'} attrs = {'bignumstring': '9' * 999, 'nonumstring': 'nan'}
state = mock.MagicMock( state = mock.MagicMock(
@ -234,7 +220,7 @@ class TestInfluxDB(unittest.TestCase):
def test_event_listener_states(self, mock_client): def test_event_listener_states(self, mock_client):
"""Test the event listener against ignored states.""" """Test the event listener against ignored states."""
self._setup() self._setup(mock_client)
for state_state in (1, 'unknown', '', 'unavailable'): for state_state in (1, 'unknown', '', 'unavailable'):
state = mock.MagicMock( state = mock.MagicMock(
@ -264,7 +250,7 @@ class TestInfluxDB(unittest.TestCase):
def test_event_listener_blacklist(self, mock_client): def test_event_listener_blacklist(self, mock_client):
"""Test the event listener against a blacklist.""" """Test the event listener against a blacklist."""
self._setup() self._setup(mock_client)
for entity_id in ('ok', 'blacklisted'): for entity_id in ('ok', 'blacklisted'):
state = mock.MagicMock( state = mock.MagicMock(
@ -294,7 +280,7 @@ class TestInfluxDB(unittest.TestCase):
def test_event_listener_blacklist_domain(self, mock_client): def test_event_listener_blacklist_domain(self, mock_client):
"""Test the event listener against a blacklist.""" """Test the event listener against a blacklist."""
self._setup() self._setup(mock_client)
for domain in ('ok', 'another_fake'): for domain in ('ok', 'another_fake'):
state = mock.MagicMock( state = mock.MagicMock(
@ -337,6 +323,7 @@ class TestInfluxDB(unittest.TestCase):
} }
assert setup_component(self.hass, influxdb.DOMAIN, config) assert setup_component(self.hass, influxdb.DOMAIN, config)
self.handler_method = self.hass.bus.listen.call_args_list[0][0][1] self.handler_method = self.hass.bus.listen.call_args_list[0][0][1]
mock_client.return_value.write_points.reset_mock()
for entity_id in ('included', 'default'): for entity_id in ('included', 'default'):
state = mock.MagicMock( state = mock.MagicMock(
@ -378,6 +365,7 @@ class TestInfluxDB(unittest.TestCase):
} }
assert setup_component(self.hass, influxdb.DOMAIN, config) assert setup_component(self.hass, influxdb.DOMAIN, config)
self.handler_method = self.hass.bus.listen.call_args_list[0][0][1] self.handler_method = self.hass.bus.listen.call_args_list[0][0][1]
mock_client.return_value.write_points.reset_mock()
for domain in ('fake', 'another_fake'): for domain in ('fake', 'another_fake'):
state = mock.MagicMock( state = mock.MagicMock(
@ -408,7 +396,7 @@ class TestInfluxDB(unittest.TestCase):
def test_event_listener_invalid_type(self, mock_client): def test_event_listener_invalid_type(self, mock_client):
"""Test the event listener when an attribute has an invalid type.""" """Test the event listener when an attribute has an invalid type."""
self._setup() self._setup(mock_client)
# map of HA State to valid influxdb [state, value] fields # map of HA State to valid influxdb [state, value] fields
valid = { valid = {
@ -470,6 +458,7 @@ class TestInfluxDB(unittest.TestCase):
} }
assert setup_component(self.hass, influxdb.DOMAIN, config) assert setup_component(self.hass, influxdb.DOMAIN, config)
self.handler_method = self.hass.bus.listen.call_args_list[0][0][1] self.handler_method = self.hass.bus.listen.call_args_list[0][0][1]
mock_client.return_value.write_points.reset_mock()
for entity_id in ('ok', 'blacklisted'): for entity_id in ('ok', 'blacklisted'):
state = mock.MagicMock( state = mock.MagicMock(
@ -509,6 +498,7 @@ class TestInfluxDB(unittest.TestCase):
} }
assert setup_component(self.hass, influxdb.DOMAIN, config) assert setup_component(self.hass, influxdb.DOMAIN, config)
self.handler_method = self.hass.bus.listen.call_args_list[0][0][1] self.handler_method = self.hass.bus.listen.call_args_list[0][0][1]
mock_client.return_value.write_points.reset_mock()
attrs = { attrs = {
'unit_of_measurement': 'foobars', 'unit_of_measurement': 'foobars',
@ -548,6 +538,7 @@ class TestInfluxDB(unittest.TestCase):
} }
assert setup_component(self.hass, influxdb.DOMAIN, config) assert setup_component(self.hass, influxdb.DOMAIN, config)
self.handler_method = self.hass.bus.listen.call_args_list[0][0][1] self.handler_method = self.hass.bus.listen.call_args_list[0][0][1]
mock_client.return_value.write_points.reset_mock()
attrs = { attrs = {
'friendly_fake': 'tag_str', 'friendly_fake': 'tag_str',
@ -604,6 +595,7 @@ class TestInfluxDB(unittest.TestCase):
} }
assert setup_component(self.hass, influxdb.DOMAIN, config) assert setup_component(self.hass, influxdb.DOMAIN, config)
self.handler_method = self.hass.bus.listen.call_args_list[0][0][1] self.handler_method = self.hass.bus.listen.call_args_list[0][0][1]
mock_client.return_value.write_points.reset_mock()
test_components = [ test_components = [
{'domain': 'sensor', 'id': 'fake_humidity', 'res': 'humidity'}, {'domain': 'sensor', 'id': 'fake_humidity', 'res': 'humidity'},
@ -647,6 +639,7 @@ class TestInfluxDB(unittest.TestCase):
} }
assert setup_component(self.hass, influxdb.DOMAIN, config) assert setup_component(self.hass, influxdb.DOMAIN, config)
self.handler_method = self.hass.bus.listen.call_args_list[0][0][1] self.handler_method = self.hass.bus.listen.call_args_list[0][0][1]
mock_client.return_value.write_points.reset_mock()
state = mock.MagicMock( state = mock.MagicMock(
state=1, domain='fake', entity_id='entity.id', object_id='entity', state=1, domain='fake', entity_id='entity.id', object_id='entity',
@ -674,7 +667,7 @@ class TestInfluxDB(unittest.TestCase):
def test_queue_backlog_full(self, mock_client): def test_queue_backlog_full(self, mock_client):
"""Test the event listener to drop old events.""" """Test the event listener to drop old events."""
self._setup() self._setup(mock_client)
state = mock.MagicMock( state = mock.MagicMock(
state=1, domain='fake', entity_id='entity.id', object_id='entity', state=1, domain='fake', entity_id='entity.id', object_id='entity',