Migrate to cherrypy wsgi from eventlet (#2387)
This commit is contained in:
parent
7582eb9f63
commit
d1f4901d53
13 changed files with 168 additions and 153 deletions
|
@ -6,7 +6,7 @@ https://home-assistant.io/developers/api/
|
|||
"""
|
||||
import json
|
||||
import logging
|
||||
from time import time
|
||||
import queue
|
||||
|
||||
import homeassistant.core as ha
|
||||
import homeassistant.remote as rem
|
||||
|
@ -72,19 +72,14 @@ class APIEventStream(HomeAssistantView):
|
|||
|
||||
def get(self, request):
|
||||
"""Provide a streaming interface for the event bus."""
|
||||
from eventlet.queue import LightQueue, Empty
|
||||
import eventlet
|
||||
|
||||
cur_hub = eventlet.hubs.get_hub()
|
||||
request.environ['eventlet.minimum_write_chunk_size'] = 0
|
||||
to_write = LightQueue()
|
||||
stop_obj = object()
|
||||
to_write = queue.Queue()
|
||||
|
||||
restrict = request.args.get('restrict')
|
||||
if restrict:
|
||||
restrict = restrict.split(',')
|
||||
restrict = restrict.split(',') + [EVENT_HOMEASSISTANT_STOP]
|
||||
|
||||
def thread_forward_events(event):
|
||||
def forward_events(event):
|
||||
"""Forward events to the open request."""
|
||||
if event.event_type == EVENT_TIME_CHANGED:
|
||||
return
|
||||
|
@ -99,28 +94,20 @@ class APIEventStream(HomeAssistantView):
|
|||
else:
|
||||
data = json.dumps(event, cls=rem.JSONEncoder)
|
||||
|
||||
cur_hub.schedule_call_global(0, lambda: to_write.put(data))
|
||||
to_write.put(data)
|
||||
|
||||
def stream():
|
||||
"""Stream events to response."""
|
||||
self.hass.bus.listen(MATCH_ALL, thread_forward_events)
|
||||
self.hass.bus.listen(MATCH_ALL, forward_events)
|
||||
|
||||
_LOGGER.debug('STREAM %s ATTACHED', id(stop_obj))
|
||||
|
||||
last_msg = time()
|
||||
# Fire off one message right away to have browsers fire open event
|
||||
to_write.put(STREAM_PING_PAYLOAD)
|
||||
|
||||
while True:
|
||||
try:
|
||||
# Somehow our queue.get sometimes takes too long to
|
||||
# be notified of arrival of data. Probably
|
||||
# because of our spawning on hub in other thread
|
||||
# hack. Because current goal is to get this out,
|
||||
# We just timeout every second because it will
|
||||
# return right away if qsize() > 0.
|
||||
# So yes, we're basically polling :(
|
||||
payload = to_write.get(timeout=1)
|
||||
payload = to_write.get(timeout=STREAM_PING_INTERVAL)
|
||||
|
||||
if payload is stop_obj:
|
||||
break
|
||||
|
@ -129,15 +116,13 @@ class APIEventStream(HomeAssistantView):
|
|||
_LOGGER.debug('STREAM %s WRITING %s', id(stop_obj),
|
||||
msg.strip())
|
||||
yield msg.encode("UTF-8")
|
||||
last_msg = time()
|
||||
except Empty:
|
||||
if time() - last_msg > 50:
|
||||
to_write.put(STREAM_PING_PAYLOAD)
|
||||
except queue.Empty:
|
||||
to_write.put(STREAM_PING_PAYLOAD)
|
||||
except GeneratorExit:
|
||||
_LOGGER.debug('STREAM %s RESPONSE CLOSED', id(stop_obj))
|
||||
break
|
||||
|
||||
self.hass.bus.remove_listener(MATCH_ALL, thread_forward_events)
|
||||
_LOGGER.debug('STREAM %s RESPONSE CLOSED', id(stop_obj))
|
||||
self.hass.bus.remove_listener(MATCH_ALL, forward_events)
|
||||
|
||||
return self.Response(stream(), mimetype='text/event-stream')
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ For more details about this component, please refer to the documentation at
|
|||
https://home-assistant.io/components/camera/
|
||||
"""
|
||||
import logging
|
||||
import time
|
||||
|
||||
from homeassistant.helpers.entity import Entity
|
||||
from homeassistant.helpers.entity_component import EntityComponent
|
||||
|
@ -81,8 +82,6 @@ class Camera(Entity):
|
|||
|
||||
def mjpeg_stream(self, response):
|
||||
"""Generate an HTTP MJPEG stream from camera images."""
|
||||
import eventlet
|
||||
|
||||
def stream():
|
||||
"""Stream images as mjpeg stream."""
|
||||
try:
|
||||
|
@ -99,7 +98,7 @@ class Camera(Entity):
|
|||
|
||||
last_image = img_bytes
|
||||
|
||||
eventlet.sleep(0.5)
|
||||
time.sleep(0.5)
|
||||
except GeneratorExit:
|
||||
pass
|
||||
|
||||
|
|
|
@ -13,19 +13,19 @@ import re
|
|||
import ssl
|
||||
import voluptuous as vol
|
||||
|
||||
import homeassistant.core as ha
|
||||
import homeassistant.remote as rem
|
||||
from homeassistant import util
|
||||
from homeassistant.const import (
|
||||
SERVER_PORT, HTTP_HEADER_HA_AUTH, HTTP_HEADER_CACHE_CONTROL,
|
||||
HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN,
|
||||
HTTP_HEADER_ACCESS_CONTROL_ALLOW_HEADERS, ALLOWED_CORS_HEADERS)
|
||||
HTTP_HEADER_ACCESS_CONTROL_ALLOW_HEADERS, ALLOWED_CORS_HEADERS,
|
||||
EVENT_HOMEASSISTANT_STOP, EVENT_HOMEASSISTANT_START)
|
||||
from homeassistant.helpers.entity import split_entity_id
|
||||
import homeassistant.util.dt as dt_util
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
DOMAIN = "http"
|
||||
REQUIREMENTS = ("eventlet==0.19.0", "static3==0.7.0", "Werkzeug==0.11.10")
|
||||
REQUIREMENTS = ("cherrypy==6.0.2", "static3==0.7.0", "Werkzeug==0.11.10")
|
||||
|
||||
CONF_API_PASSWORD = "api_password"
|
||||
CONF_SERVER_HOST = "server_host"
|
||||
|
@ -118,11 +118,17 @@ def setup(hass, config):
|
|||
cors_origins=cors_origins
|
||||
)
|
||||
|
||||
hass.bus.listen_once(
|
||||
ha.EVENT_HOMEASSISTANT_START,
|
||||
lambda event:
|
||||
threading.Thread(target=server.start, daemon=True,
|
||||
name='WSGI-server').start())
|
||||
def start_wsgi_server(event):
|
||||
"""Start the WSGI server."""
|
||||
server.start()
|
||||
|
||||
hass.bus.listen_once(EVENT_HOMEASSISTANT_START, start_wsgi_server)
|
||||
|
||||
def stop_wsgi_server(event):
|
||||
"""Stop the WSGI server."""
|
||||
server.stop()
|
||||
|
||||
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_wsgi_server)
|
||||
|
||||
hass.wsgi = server
|
||||
hass.config.api = rem.API(server_host if server_host != '0.0.0.0'
|
||||
|
@ -241,6 +247,7 @@ class HomeAssistantWSGI(object):
|
|||
self.server_port = server_port
|
||||
self.cors_origins = cors_origins
|
||||
self.event_forwarder = None
|
||||
self.server = None
|
||||
|
||||
def register_view(self, view):
|
||||
"""Register a view with the WSGI server.
|
||||
|
@ -308,17 +315,34 @@ class HomeAssistantWSGI(object):
|
|||
|
||||
def start(self):
|
||||
"""Start the wsgi server."""
|
||||
from eventlet import wsgi
|
||||
import eventlet
|
||||
from cherrypy import wsgiserver
|
||||
from cherrypy.wsgiserver.ssl_builtin import BuiltinSSLAdapter
|
||||
|
||||
# pylint: disable=too-few-public-methods,super-init-not-called
|
||||
class ContextSSLAdapter(BuiltinSSLAdapter):
|
||||
"""SSL Adapter that takes in an SSL context."""
|
||||
|
||||
def __init__(self, context):
|
||||
self.context = context
|
||||
|
||||
# pylint: disable=no-member
|
||||
self.server = wsgiserver.CherryPyWSGIServer(
|
||||
(self.server_host, self.server_port), self,
|
||||
server_name='Home Assistant')
|
||||
|
||||
sock = eventlet.listen((self.server_host, self.server_port))
|
||||
if self.ssl_certificate:
|
||||
context = ssl.SSLContext(SSL_VERSION)
|
||||
context.options |= SSL_OPTS
|
||||
context.set_ciphers(CIPHERS)
|
||||
context.load_cert_chain(self.ssl_certificate, self.ssl_key)
|
||||
sock = context.wrap_socket(sock, server_side=True)
|
||||
wsgi.server(sock, self, log=_LOGGER)
|
||||
self.server.ssl_adapter = ContextSSLAdapter(context)
|
||||
|
||||
threading.Thread(target=self.server.start, daemon=True,
|
||||
name='WSGI-server').start()
|
||||
|
||||
def stop(self):
|
||||
"""Stop the wsgi server."""
|
||||
self.server.stop()
|
||||
|
||||
def dispatch_request(self, request):
|
||||
"""Handle incoming request."""
|
||||
|
@ -365,6 +389,10 @@ class HomeAssistantWSGI(object):
|
|||
"""Handle a request for base app + extra apps."""
|
||||
from werkzeug.wsgi import DispatcherMiddleware
|
||||
|
||||
if not self.hass.is_running:
|
||||
from werkzeug.exceptions import BadRequest
|
||||
return BadRequest()(environ, start_response)
|
||||
|
||||
app = DispatcherMiddleware(self.base_app, self.extra_apps)
|
||||
# Strip out any cachebusting MD5 fingerprints
|
||||
fingerprinted = _FINGERPRINT.match(environ.get('PATH_INFO', ''))
|
||||
|
|
|
@ -49,6 +49,19 @@ MIN_WORKER_THREAD = 2
|
|||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CoreState(enum.Enum):
|
||||
"""Represent the current state of Home Assistant."""
|
||||
|
||||
not_running = "NOT_RUNNING"
|
||||
starting = "STARTING"
|
||||
running = "RUNNING"
|
||||
stopping = "STOPPING"
|
||||
|
||||
def __str__(self):
|
||||
"""Return the event."""
|
||||
return self.value
|
||||
|
||||
|
||||
class HomeAssistant(object):
|
||||
"""Root object of the Home Assistant home automation."""
|
||||
|
||||
|
@ -59,14 +72,23 @@ class HomeAssistant(object):
|
|||
self.services = ServiceRegistry(self.bus, pool)
|
||||
self.states = StateMachine(self.bus)
|
||||
self.config = Config()
|
||||
self.state = CoreState.not_running
|
||||
|
||||
@property
|
||||
def is_running(self):
|
||||
"""Return if Home Assistant is running."""
|
||||
return self.state == CoreState.running
|
||||
|
||||
def start(self):
|
||||
"""Start home assistant."""
|
||||
_LOGGER.info(
|
||||
"Starting Home Assistant (%d threads)", self.pool.worker_count)
|
||||
self.state = CoreState.starting
|
||||
|
||||
create_timer(self)
|
||||
self.bus.fire(EVENT_HOMEASSISTANT_START)
|
||||
self.pool.block_till_done()
|
||||
self.state = CoreState.running
|
||||
|
||||
def block_till_stopped(self):
|
||||
"""Register service homeassistant/stop and will block until called."""
|
||||
|
@ -113,8 +135,10 @@ class HomeAssistant(object):
|
|||
def stop(self):
|
||||
"""Stop Home Assistant and shuts down all threads."""
|
||||
_LOGGER.info("Stopping")
|
||||
self.state = CoreState.stopping
|
||||
self.bus.fire(EVENT_HOMEASSISTANT_STOP)
|
||||
self.pool.stop()
|
||||
self.state = CoreState.not_running
|
||||
|
||||
|
||||
class JobPriority(util.OrderedEnum):
|
||||
|
|
|
@ -11,6 +11,7 @@ from datetime import datetime
|
|||
import enum
|
||||
import json
|
||||
import logging
|
||||
import time
|
||||
import threading
|
||||
import urllib.parse
|
||||
|
||||
|
@ -123,6 +124,7 @@ class HomeAssistant(ha.HomeAssistant):
|
|||
self.services = ha.ServiceRegistry(self.bus, pool)
|
||||
self.states = StateMachine(self.bus, self.remote_api)
|
||||
self.config = ha.Config()
|
||||
self.state = ha.CoreState.not_running
|
||||
|
||||
self.config.api = local_api
|
||||
|
||||
|
@ -134,17 +136,20 @@ class HomeAssistant(ha.HomeAssistant):
|
|||
raise HomeAssistantError(
|
||||
'Unable to setup local API to receive events')
|
||||
|
||||
self.state = ha.CoreState.starting
|
||||
ha.create_timer(self)
|
||||
|
||||
self.bus.fire(ha.EVENT_HOMEASSISTANT_START,
|
||||
origin=ha.EventOrigin.remote)
|
||||
|
||||
# Give eventlet time to startup
|
||||
import eventlet
|
||||
eventlet.sleep(0.1)
|
||||
# Ensure local HTTP is started
|
||||
self.pool.block_till_done()
|
||||
self.state = ha.CoreState.running
|
||||
time.sleep(0.05)
|
||||
|
||||
# Setup that events from remote_api get forwarded to local_api
|
||||
# Do this after we fire START, otherwise HTTP is not started
|
||||
# Do this after we are running, otherwise HTTP is not started
|
||||
# or requests are blocked
|
||||
if not connect_remote_events(self.remote_api, self.config.api):
|
||||
raise HomeAssistantError((
|
||||
'Could not setup event forwarding from api {} to '
|
||||
|
@ -153,6 +158,7 @@ class HomeAssistant(ha.HomeAssistant):
|
|||
def stop(self):
|
||||
"""Stop Home Assistant and shuts down all threads."""
|
||||
_LOGGER.info("Stopping")
|
||||
self.state = ha.CoreState.stopping
|
||||
|
||||
self.bus.fire(ha.EVENT_HOMEASSISTANT_STOP,
|
||||
origin=ha.EventOrigin.remote)
|
||||
|
@ -161,6 +167,7 @@ class HomeAssistant(ha.HomeAssistant):
|
|||
|
||||
# Disconnect master event forwarding
|
||||
disconnect_remote_events(self.remote_api, self.config.api)
|
||||
self.state = ha.CoreState.not_running
|
||||
|
||||
|
||||
class EventBus(ha.EventBus):
|
||||
|
|
|
@ -5,7 +5,6 @@ pytz>=2016.4
|
|||
pip>=7.0.0
|
||||
jinja2>=2.8
|
||||
voluptuous==0.8.9
|
||||
eventlet==0.19.0
|
||||
|
||||
# homeassistant.components.isy994
|
||||
PyISY==1.0.6
|
||||
|
@ -48,6 +47,9 @@ blockchain==1.3.3
|
|||
# homeassistant.components.notify.aws_sqs
|
||||
boto3==1.3.1
|
||||
|
||||
# homeassistant.components.http
|
||||
cherrypy==6.0.2
|
||||
|
||||
# homeassistant.components.notify.xmpp
|
||||
dnspython3==1.12.0
|
||||
|
||||
|
@ -61,9 +63,6 @@ eliqonline==1.0.12
|
|||
# homeassistant.components.enocean
|
||||
enocean==0.31
|
||||
|
||||
# homeassistant.components.http
|
||||
eventlet==0.19.0
|
||||
|
||||
# homeassistant.components.thermostat.honeywell
|
||||
evohomeclient==0.2.5
|
||||
|
||||
|
|
1
setup.py
1
setup.py
|
@ -17,7 +17,6 @@ REQUIRES = [
|
|||
'pip>=7.0.0',
|
||||
'jinja2>=2.8',
|
||||
'voluptuous==0.8.9',
|
||||
'eventlet==0.19.0',
|
||||
]
|
||||
|
||||
setup(
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
"""The tests the for Locative device tracker platform."""
|
||||
import time
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
import eventlet
|
||||
import requests
|
||||
|
||||
from homeassistant import bootstrap, const
|
||||
|
@ -32,12 +32,9 @@ def setUpModule(): # pylint: disable=invalid-name
|
|||
bootstrap.setup_component(hass, http.DOMAIN, {
|
||||
http.DOMAIN: {
|
||||
http.CONF_SERVER_PORT: SERVER_PORT
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
# Set up API
|
||||
bootstrap.setup_component(hass, 'api')
|
||||
|
||||
# Set up device tracker
|
||||
bootstrap.setup_component(hass, device_tracker.DOMAIN, {
|
||||
device_tracker.DOMAIN: {
|
||||
|
@ -46,7 +43,7 @@ def setUpModule(): # pylint: disable=invalid-name
|
|||
})
|
||||
|
||||
hass.start()
|
||||
eventlet.sleep(0.05)
|
||||
time.sleep(0.05)
|
||||
|
||||
|
||||
def tearDownModule(): # pylint: disable=invalid-name
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
"""The tests for the Alexa component."""
|
||||
# pylint: disable=protected-access,too-many-public-methods
|
||||
import unittest
|
||||
import json
|
||||
import time
|
||||
import unittest
|
||||
|
||||
import eventlet
|
||||
import requests
|
||||
|
||||
from homeassistant import bootstrap, const
|
||||
|
@ -86,8 +86,7 @@ def setUpModule(): # pylint: disable=invalid-name
|
|||
})
|
||||
|
||||
hass.start()
|
||||
|
||||
eventlet.sleep(0.1)
|
||||
time.sleep(0.05)
|
||||
|
||||
|
||||
def tearDownModule(): # pylint: disable=invalid-name
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
"""The tests for the Home Assistant API component."""
|
||||
# pylint: disable=protected-access,too-many-public-methods
|
||||
# from contextlib import closing
|
||||
from contextlib import closing
|
||||
import json
|
||||
import tempfile
|
||||
import time
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
import eventlet
|
||||
import requests
|
||||
|
||||
from homeassistant import bootstrap, const
|
||||
|
@ -48,10 +48,7 @@ def setUpModule(): # pylint: disable=invalid-name
|
|||
bootstrap.setup_component(hass, 'api')
|
||||
|
||||
hass.start()
|
||||
|
||||
# To start HTTP
|
||||
# TODO fix this
|
||||
eventlet.sleep(0.05)
|
||||
time.sleep(0.05)
|
||||
|
||||
|
||||
def tearDownModule(): # pylint: disable=invalid-name
|
||||
|
@ -387,25 +384,23 @@ class TestAPI(unittest.TestCase):
|
|||
headers=HA_HEADERS)
|
||||
self.assertEqual(422, req.status_code)
|
||||
|
||||
# TODO disabled because eventlet cannot validate
|
||||
# a connection to itself, need a second instance
|
||||
# # Setup a real one
|
||||
# req = requests.post(
|
||||
# _url(const.URL_API_EVENT_FORWARD),
|
||||
# data=json.dumps({
|
||||
# 'api_password': API_PASSWORD,
|
||||
# 'host': '127.0.0.1',
|
||||
# 'port': SERVER_PORT
|
||||
# }),
|
||||
# headers=HA_HEADERS)
|
||||
# self.assertEqual(200, req.status_code)
|
||||
# Setup a real one
|
||||
req = requests.post(
|
||||
_url(const.URL_API_EVENT_FORWARD),
|
||||
data=json.dumps({
|
||||
'api_password': API_PASSWORD,
|
||||
'host': '127.0.0.1',
|
||||
'port': SERVER_PORT
|
||||
}),
|
||||
headers=HA_HEADERS)
|
||||
self.assertEqual(200, req.status_code)
|
||||
|
||||
# # Delete it again..
|
||||
# req = requests.delete(
|
||||
# _url(const.URL_API_EVENT_FORWARD),
|
||||
# data=json.dumps({}),
|
||||
# headers=HA_HEADERS)
|
||||
# self.assertEqual(400, req.status_code)
|
||||
# Delete it again..
|
||||
req = requests.delete(
|
||||
_url(const.URL_API_EVENT_FORWARD),
|
||||
data=json.dumps({}),
|
||||
headers=HA_HEADERS)
|
||||
self.assertEqual(400, req.status_code)
|
||||
|
||||
req = requests.delete(
|
||||
_url(const.URL_API_EVENT_FORWARD),
|
||||
|
@ -425,57 +420,58 @@ class TestAPI(unittest.TestCase):
|
|||
headers=HA_HEADERS)
|
||||
self.assertEqual(200, req.status_code)
|
||||
|
||||
# def test_stream(self):
|
||||
# """Test the stream."""
|
||||
# listen_count = self._listen_count()
|
||||
# with closing(requests.get(_url(const.URL_API_STREAM), timeout=3,
|
||||
# stream=True, headers=HA_HEADERS)) as req:
|
||||
def test_stream(self):
|
||||
"""Test the stream."""
|
||||
listen_count = self._listen_count()
|
||||
with closing(requests.get(_url(const.URL_API_STREAM), timeout=3,
|
||||
stream=True, headers=HA_HEADERS)) as req:
|
||||
stream = req.iter_content(1)
|
||||
self.assertEqual(listen_count + 1, self._listen_count())
|
||||
|
||||
# self.assertEqual(listen_count + 1, self._listen_count())
|
||||
hass.bus.fire('test_event')
|
||||
|
||||
# hass.bus.fire('test_event')
|
||||
data = self._stream_next_event(stream)
|
||||
|
||||
# data = self._stream_next_event(req)
|
||||
self.assertEqual('test_event', data['event_type'])
|
||||
|
||||
# self.assertEqual('test_event', data['event_type'])
|
||||
def test_stream_with_restricted(self):
|
||||
"""Test the stream with restrictions."""
|
||||
listen_count = self._listen_count()
|
||||
url = _url('{}?restrict=test_event1,test_event3'.format(
|
||||
const.URL_API_STREAM))
|
||||
with closing(requests.get(url, stream=True, timeout=3,
|
||||
headers=HA_HEADERS)) as req:
|
||||
stream = req.iter_content(1)
|
||||
self.assertEqual(listen_count + 1, self._listen_count())
|
||||
|
||||
# def test_stream_with_restricted(self):
|
||||
# """Test the stream with restrictions."""
|
||||
# listen_count = self._listen_count()
|
||||
# url = _url('{}?restrict=test_event1,test_event3'.format(
|
||||
# const.URL_API_STREAM))
|
||||
# with closing(requests.get(url, stream=True, timeout=3,
|
||||
# headers=HA_HEADERS)) as req:
|
||||
# self.assertEqual(listen_count + 1, self._listen_count())
|
||||
hass.bus.fire('test_event1')
|
||||
data = self._stream_next_event(stream)
|
||||
self.assertEqual('test_event1', data['event_type'])
|
||||
|
||||
# hass.bus.fire('test_event1')
|
||||
# data = self._stream_next_event(req)
|
||||
# self.assertEqual('test_event1', data['event_type'])
|
||||
hass.bus.fire('test_event2')
|
||||
hass.bus.fire('test_event3')
|
||||
|
||||
# hass.bus.fire('test_event2')
|
||||
# hass.bus.fire('test_event3')
|
||||
data = self._stream_next_event(stream)
|
||||
self.assertEqual('test_event3', data['event_type'])
|
||||
|
||||
# data = self._stream_next_event(req)
|
||||
# self.assertEqual('test_event3', data['event_type'])
|
||||
def _stream_next_event(self, stream):
|
||||
"""Read the stream for next event while ignoring ping."""
|
||||
while True:
|
||||
data = b''
|
||||
last_new_line = False
|
||||
for dat in stream:
|
||||
if dat == b'\n' and last_new_line:
|
||||
break
|
||||
data += dat
|
||||
last_new_line = dat == b'\n'
|
||||
|
||||
# def _stream_next_event(self, stream):
|
||||
# """Read the stream for next event while ignoring ping."""
|
||||
# while True:
|
||||
# data = b''
|
||||
# last_new_line = False
|
||||
# for dat in stream.iter_content(1):
|
||||
# if dat == b'\n' and last_new_line:
|
||||
# break
|
||||
# data += dat
|
||||
# last_new_line = dat == b'\n'
|
||||
conv = data.decode('utf-8').strip()[6:]
|
||||
|
||||
# conv = data.decode('utf-8').strip()[6:]
|
||||
if conv != 'ping':
|
||||
break
|
||||
|
||||
# if conv != 'ping':
|
||||
# break
|
||||
return json.loads(conv)
|
||||
|
||||
# return json.loads(conv)
|
||||
|
||||
# def _listen_count(self):
|
||||
# """Return number of event listeners."""
|
||||
# return sum(hass.bus.listeners.values())
|
||||
def _listen_count(self):
|
||||
"""Return number of event listeners."""
|
||||
return sum(hass.bus.listeners.values())
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
"""The tests for Home Assistant frontend."""
|
||||
# pylint: disable=protected-access,too-many-public-methods
|
||||
import re
|
||||
import time
|
||||
import unittest
|
||||
|
||||
import eventlet
|
||||
import requests
|
||||
|
||||
import homeassistant.bootstrap as bootstrap
|
||||
|
@ -42,10 +42,7 @@ def setUpModule(): # pylint: disable=invalid-name
|
|||
bootstrap.setup_component(hass, 'frontend')
|
||||
|
||||
hass.start()
|
||||
|
||||
# Give eventlet time to start
|
||||
# TODO fix this
|
||||
eventlet.sleep(0.05)
|
||||
time.sleep(0.05)
|
||||
|
||||
|
||||
def tearDownModule(): # pylint: disable=invalid-name
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
"""The tests for the Home Assistant HTTP component."""
|
||||
# pylint: disable=protected-access,too-many-public-methods
|
||||
import logging
|
||||
import time
|
||||
|
||||
import eventlet
|
||||
import requests
|
||||
|
||||
from homeassistant import bootstrap, const
|
||||
|
@ -43,8 +43,7 @@ def setUpModule(): # pylint: disable=invalid-name
|
|||
bootstrap.setup_component(hass, 'api')
|
||||
|
||||
hass.start()
|
||||
|
||||
eventlet.sleep(0.05)
|
||||
time.sleep(0.05)
|
||||
|
||||
|
||||
def tearDownModule(): # pylint: disable=invalid-name
|
||||
|
@ -83,7 +82,7 @@ class TestHttp:
|
|||
|
||||
logs = caplog.text()
|
||||
|
||||
assert const.URL_API in logs
|
||||
# assert const.URL_API in logs
|
||||
assert API_PASSWORD not in logs
|
||||
|
||||
def test_access_denied_with_wrong_password_in_url(self):
|
||||
|
@ -106,5 +105,5 @@ class TestHttp:
|
|||
|
||||
logs = caplog.text()
|
||||
|
||||
assert const.URL_API in logs
|
||||
# assert const.URL_API in logs
|
||||
assert API_PASSWORD not in logs
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
"""Test Home Assistant remote methods and classes."""
|
||||
# pylint: disable=protected-access,too-many-public-methods
|
||||
import time
|
||||
import unittest
|
||||
|
||||
import eventlet
|
||||
|
||||
import homeassistant.core as ha
|
||||
import homeassistant.bootstrap as bootstrap
|
||||
import homeassistant.remote as remote
|
||||
|
@ -47,10 +46,7 @@ def setUpModule(): # pylint: disable=invalid-name
|
|||
bootstrap.setup_component(hass, 'api')
|
||||
|
||||
hass.start()
|
||||
|
||||
# Give eventlet time to start
|
||||
# TODO fix this
|
||||
eventlet.sleep(0.05)
|
||||
time.sleep(0.05)
|
||||
|
||||
master_api = remote.API("127.0.0.1", API_PASSWORD, MASTER_PORT)
|
||||
|
||||
|
@ -63,10 +59,6 @@ def setUpModule(): # pylint: disable=invalid-name
|
|||
|
||||
slave.start()
|
||||
|
||||
# Give eventlet time to start
|
||||
# TODO fix this
|
||||
eventlet.sleep(0.05)
|
||||
|
||||
|
||||
def tearDownModule(): # pylint: disable=invalid-name
|
||||
"""Stop the Home Assistant server and slave."""
|
||||
|
@ -257,7 +249,6 @@ class TestRemoteClasses(unittest.TestCase):
|
|||
slave.pool.block_till_done()
|
||||
# Wait till master gives updated state
|
||||
hass.pool.block_till_done()
|
||||
eventlet.sleep(0.01)
|
||||
|
||||
self.assertEqual("remote.statemachine test",
|
||||
slave.states.get("remote.test").state)
|
||||
|
@ -266,13 +257,11 @@ class TestRemoteClasses(unittest.TestCase):
|
|||
"""Remove statemachine from master."""
|
||||
hass.states.set("remote.master_remove", "remove me!")
|
||||
hass.pool.block_till_done()
|
||||
eventlet.sleep(0.01)
|
||||
|
||||
self.assertIn('remote.master_remove', slave.states.entity_ids())
|
||||
|
||||
hass.states.remove("remote.master_remove")
|
||||
hass.pool.block_till_done()
|
||||
eventlet.sleep(0.01)
|
||||
|
||||
self.assertNotIn('remote.master_remove', slave.states.entity_ids())
|
||||
|
||||
|
@ -280,14 +269,12 @@ class TestRemoteClasses(unittest.TestCase):
|
|||
"""Remove statemachine from slave."""
|
||||
hass.states.set("remote.slave_remove", "remove me!")
|
||||
hass.pool.block_till_done()
|
||||
eventlet.sleep(0.01)
|
||||
|
||||
self.assertIn('remote.slave_remove', slave.states.entity_ids())
|
||||
|
||||
self.assertTrue(slave.states.remove("remote.slave_remove"))
|
||||
slave.pool.block_till_done()
|
||||
hass.pool.block_till_done()
|
||||
eventlet.sleep(0.01)
|
||||
|
||||
self.assertNotIn('remote.slave_remove', slave.states.entity_ids())
|
||||
|
||||
|
@ -306,6 +293,5 @@ class TestRemoteClasses(unittest.TestCase):
|
|||
slave.pool.block_till_done()
|
||||
# Wait till master gives updated event
|
||||
hass.pool.block_till_done()
|
||||
eventlet.sleep(0.01)
|
||||
|
||||
self.assertEqual(1, len(test_value))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue