Fix exception in stream idle callback (#46642)

* Fix exception in stream idle callback

Fix bug where idle timeout callback fails if the stream previously exited.

* Add a test for stream idle timeout after stream is stopped.

* Add clarifying comment to idle timer clear method

* Clear hls timer only on stop
This commit is contained in:
Allen Porter 2021-02-16 12:10:26 -08:00 committed by GitHub
parent c45ce86e53
commit aaecd91407
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 36 additions and 1 deletions

View File

@ -212,6 +212,9 @@ class Stream:
def stop(self):
"""Remove outputs and access token."""
self.access_token = None
if self._hls_timer:
self._hls_timer.clear()
self._hls_timer = None
if self._hls:
self._hls.cleanup()
self._hls = None

View File

@ -63,7 +63,7 @@ class IdleTimer:
self._unsub = async_call_later(self._hass, self._timeout, self.fire)
def clear(self):
"""Clear and disable the timer."""
"""Clear and disable the timer if it has not already fired."""
if self._unsub is not None:
self._unsub()

View File

@ -159,6 +159,38 @@ async def test_stream_timeout(hass, hass_client, stream_worker_sync):
assert fail_response.status == HTTP_NOT_FOUND
async def test_stream_timeout_after_stop(hass, hass_client, stream_worker_sync):
"""Test hls stream timeout after the stream has been stopped already."""
await async_setup_component(hass, "stream", {"stream": {}})
stream_worker_sync.pause()
# Setup demo HLS track
source = generate_h264_video()
stream = create_stream(hass, source)
# Request stream
stream.hls_output()
stream.start()
url = stream.endpoint_url()
http_client = await hass_client()
# Fetch playlist
parsed_url = urlparse(url)
playlist_response = await http_client.get(parsed_url.path)
assert playlist_response.status == 200
stream_worker_sync.resume()
stream.stop()
# Wait 5 minutes and fire callback. Stream should already have been
# stopped so this is a no-op.
future = dt_util.utcnow() + timedelta(minutes=5)
async_fire_time_changed(hass, future)
await hass.async_block_till_done()
async def test_stream_ended(hass, stream_worker_sync):
"""Test hls stream packets ended."""
await async_setup_component(hass, "stream", {"stream": {}})