splunk: Handle datetime objects in event payload (#9628)

If an event contained a datetime.datetime object it would cause an
exception in the Splunk component. Most of the media_player
components do this in their `media_position_updated_at` attribute.

Use the JSONEncoder from homeassistant.remote instead of just using the
standard json.dumps encoder.

Fixes #9590
This commit is contained in:
Phil Kates 2017-09-30 00:35:25 -07:00 committed by Pascal Vizeli
parent e406c57ec9
commit 80a15977ff
2 changed files with 25 additions and 13 deletions

View file

@ -14,6 +14,7 @@ from homeassistant.const import (
CONF_NAME, CONF_HOST, CONF_PORT, CONF_SSL, CONF_TOKEN, EVENT_STATE_CHANGED)
from homeassistant.helpers import state as state_helper
import homeassistant.helpers.config_validation as cv
from homeassistant.remote import JSONEncoder
_LOGGER = logging.getLogger(__name__)
@ -81,7 +82,8 @@ def setup(hass, config):
"host": event_collector,
"event": json_body,
}
requests.post(event_collector, data=json.dumps(payload),
requests.post(event_collector,
data=json.dumps(payload, cls=JSONEncoder),
headers=headers, timeout=10)
except requests.exceptions.RequestException as error:
_LOGGER.exception("Error saving event to Splunk: %s", error)

View file

@ -1,10 +1,13 @@
"""The tests for the Splunk component."""
import json
import unittest
from unittest import mock
from homeassistant.setup import setup_component
import homeassistant.components.splunk as splunk
from homeassistant.const import STATE_ON, STATE_OFF, EVENT_STATE_CHANGED
from homeassistant.helpers import state as state_helper
import homeassistant.util.dt as dt_util
from tests.common import get_test_home_assistant
@ -71,13 +74,13 @@ class TestSplunk(unittest.TestCase):
self.handler_method = self.hass.bus.listen.call_args_list[0][0][1]
@mock.patch.object(splunk, 'requests')
@mock.patch('json.dumps')
def test_event_listener(self, mock_dump, mock_requests):
def test_event_listener(self, mock_requests):
"""Test event listener."""
mock_dump.side_effect = lambda x: x
self._setup(mock_requests)
valid = {'1': 1,
now = dt_util.now()
valid = {
'1': 1,
'1.0': 1.0,
STATE_ON: 1,
STATE_OFF: 0,
@ -88,13 +91,20 @@ class TestSplunk(unittest.TestCase):
state = mock.MagicMock(state=in_,
domain='fake',
object_id='entity',
attributes={})
attributes={'datetime_attr': now})
event = mock.MagicMock(data={'new_state': state}, time_fired=12345)
try:
out = state_helper.state_as_number(state)
except ValueError:
out = state.state
body = [{
'domain': 'fake',
'entity_id': 'entity',
'attributes': {},
'attributes': {
'datetime_attr': now.isoformat()
},
'time': '12345',
'value': out,
'host': 'HASS',
@ -107,7 +117,7 @@ class TestSplunk(unittest.TestCase):
self.assertEqual(
self.mock_post.call_args,
mock.call(
payload['host'], data=payload,
payload['host'], data=json.dumps(payload),
headers={'Authorization': 'Splunk secret'},
timeout=10
)