diff --git a/tests/helpers/test_aiohttp_client.py b/tests/helpers/test_aiohttp_client.py index 83e1275819b..4bca671059f 100644 --- a/tests/helpers/test_aiohttp_client.py +++ b/tests/helpers/test_aiohttp_client.py @@ -1,10 +1,13 @@ """Test the aiohttp client helper.""" +import asyncio import unittest import aiohttp +from homeassistant.bootstrap import setup_component import homeassistant.helpers.aiohttp_client as client -from homeassistant.util.async import run_callback_threadsafe +from homeassistant.util.async import ( + run_callback_threadsafe, run_coroutine_threadsafe) from tests.common import get_test_home_assistant @@ -79,3 +82,81 @@ class TestHelpersAiohttpClient(unittest.TestCase): assert isinstance( self.hass.data[client.DATA_CONNECTOR_NOTVERIFY], aiohttp.TCPConnector) + + def test_get_clientsession_cleanup(self): + """Test init clientsession with ssl.""" + run_callback_threadsafe(self.hass.loop, client.async_get_clientsession, + self.hass).result() + + assert isinstance( + self.hass.data[client.DATA_CLIENTSESSION], aiohttp.ClientSession) + assert isinstance( + self.hass.data[client.DATA_CONNECTOR], aiohttp.TCPConnector) + + run_coroutine_threadsafe( + client.async_cleanup_websession(self.hass), self.hass.loop + ).result() + + assert self.hass.data[client.DATA_CLIENTSESSION].closed + assert self.hass.data[client.DATA_CONNECTOR].closed + + +@asyncio.coroutine +def test_fetching_url(aioclient_mock, hass, test_client): + """Test that it fetches the given url.""" + aioclient_mock.get('http://example.com/mjpeg_stream', content=[ + b'Frame1', b'Frame2', b'Frame3' + ]) + + def setup_platform(): + """Setup the platform.""" + assert setup_component(hass, 'camera', { + 'camera': { + 'name': 'config_test', + 'platform': 'mjpeg', + 'mjpeg_url': 'http://example.com/mjpeg_stream', + }}) + + yield from hass.loop.run_in_executor(None, setup_platform) + + client = yield from test_client(hass.http.app) + + resp = yield from client.get('/api/camera_proxy_stream/camera.config_test') + + assert resp.status == 200 + assert aioclient_mock.call_count == 1 + body = yield from resp.text() + assert body == 'Frame3Frame2Frame1' + + aioclient_mock.clear_requests() + aioclient_mock.get( + 'http://example.com/mjpeg_stream', exc=asyncio.TimeoutError(), + content=[b'Frame1', b'Frame2', b'Frame3']) + + resp = yield from client.get('/api/camera_proxy_stream/camera.config_test') + + assert resp.status == 200 + body = yield from resp.text() + assert body == '' + + aioclient_mock.clear_requests() + aioclient_mock.get( + 'http://example.com/mjpeg_stream', exc=asyncio.CancelledError(), + content=[b'Frame1', b'Frame2', b'Frame3']) + + resp = yield from client.get('/api/camera_proxy_stream/camera.config_test') + + assert resp.status == 200 + body = yield from resp.text() + assert body == '' + + aioclient_mock.clear_requests() + aioclient_mock.get( + 'http://example.com/mjpeg_stream', exc=aiohttp.errors.ClientError(), + content=[b'Frame1', b'Frame2', b'Frame3']) + + resp = yield from client.get('/api/camera_proxy_stream/camera.config_test') + + assert resp.status == 200 + body = yield from resp.text() + assert body == '' diff --git a/tests/test_util/aiohttp.py b/tests/test_util/aiohttp.py index afe2f626de7..220eccca699 100644 --- a/tests/test_util/aiohttp.py +++ b/tests/test_util/aiohttp.py @@ -25,7 +25,7 @@ class AiohttpClientMocker: content=None, json=None, params=None, - headers=None, + headers={}, exc=None, cookies=None): """Mock a request.""" @@ -39,7 +39,7 @@ class AiohttpClientMocker: url = str(yarl.URL(url).with_query(params)) self._mocks.append(AiohttpClientMockResponse( - method, url, status, content, cookies, exc)) + method, url, status, content, cookies, exc, headers)) def get(self, *args, **kwargs): """Register a mock get request.""" @@ -91,7 +91,8 @@ class AiohttpClientMocker: class AiohttpClientMockResponse: """Mock Aiohttp client response.""" - def __init__(self, method, url, status, response, cookies=None, exc=None): + def __init__(self, method, url, status, response, cookies=None, exc=None, + headers={}): """Initialize a fake response.""" self.method = method self._url = url @@ -101,6 +102,7 @@ class AiohttpClientMockResponse: self.response = response self.exc = exc + self._headers = headers self._cookies = {} if cookies: @@ -109,6 +111,18 @@ class AiohttpClientMockResponse: cookie.value = data self._cookies[name] = cookie + if isinstance(response, list): + self.content = mock.MagicMock() + + @asyncio.coroutine + def read(*argc, **kwargs): + """Read content stream mock.""" + if self.response: + return self.response.pop() + return None + + self.content.read = read + def match_request(self, method, url, params=None): """Test if response answers request.""" if method.lower() != self.method.lower(): @@ -142,6 +156,11 @@ class AiohttpClientMockResponse: return True + @property + def headers(self): + """Return content_type.""" + return self._headers + @property def cookies(self): """Return dict of cookies."""