예제 #1
0
async def test_record_stream(hass, hass_client):
    """
    Test record stream.

    Purposefully not mocking anything here to test full
    integration with the stream component.
    """
    await async_setup_component(hass, "stream", {"stream": {}})

    with patch(
            "homeassistant.components.stream.recorder.recorder_save_worker"):
        # Setup demo track
        source = generate_h264_video()
        stream = preload_stream(hass, source)
        recorder = stream.add_provider("recorder")
        stream.start()

        segments = 0
        while True:
            segment = await recorder.recv()
            if not segment:
                break
            segments += 1

        stream.stop()

        assert segments > 1
예제 #2
0
파일: test_hls.py 프로젝트: jhofker/core-1
async def test_stream_ended(hass, stream_worker_sync):
    """Test hls stream packets ended."""
    await async_setup_component(hass, "stream", {"stream": {}})

    stream_worker_sync.pause()

    # Setup demo HLS track
    source = generate_h264_video()
    stream = preload_stream(hass, source)
    track = stream.add_provider("hls")

    # Request stream
    request_stream(hass, source)

    # Run it dead
    while True:
        segment = await track.recv()
        if segment is None:
            break
        segments = segment.sequence
        # Allow worker to finalize once enough of the stream is been consumed
        if segments > 1:
            stream_worker_sync.resume()

    assert segments > 1
    assert not track.get_segment()

    # Stop stream, if it hasn't quit already
    stream.stop()
예제 #3
0
async def test_record_stream(hass, hass_client, stream_worker_sync,
                             record_worker_sync):
    """
    Test record stream.

    Tests full integration with the stream component, and captures the
    stream worker and save worker to allow for clean shutdown of background
    threads.  The actual save logic is tested in test_recorder_save below.
    """
    await async_setup_component(hass, "stream", {"stream": {}})

    stream_worker_sync.pause()

    # Setup demo track
    source = generate_h264_video()
    stream = preload_stream(hass, source)
    recorder = stream.add_provider("recorder")
    stream.start()

    while True:
        segment = await recorder.recv()
        if not segment:
            break
        segments = segment.sequence
        if segments > 1:
            stream_worker_sync.resume()

    stream.stop()
    assert segments > 1

    # Verify that the save worker was invoked, then block until its
    # thread completes and is shutdown completely to avoid thread leaks.
    record_worker_sync.join()
예제 #4
0
async def test_record_stream(hass, hass_client):
    """
    Test record stream.

    Purposefully not mocking anything here to test full
    integration with the stream component.
    """
    await async_setup_component(hass, 'stream', {
        'stream': {}
    })

    with patch(
            'homeassistant.components.stream.recorder.recorder_save_worker'):
        # Setup demo track
        source = generate_h264_video()
        stream = preload_stream(hass, source)
        recorder = stream.add_provider('recorder')
        stream.start()

        segments = 0
        while True:
            segment = await recorder.recv()
            if not segment:
                break
            segments += 1

        stream.stop()

        assert segments == 3
예제 #5
0
async def test_stream_timeout(hass, hass_client):
    """Test hls stream timeout."""
    await async_setup_component(hass, 'stream', {'stream': {}})

    # Setup demo HLS track
    source = generate_h264_video()
    stream = preload_stream(hass, source)
    stream.add_provider('hls')

    # Request stream
    url = request_stream(hass, source)

    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

    # Wait a minute
    future = dt_util.utcnow() + timedelta(minutes=1)
    async_fire_time_changed(hass, future)

    # Fetch again to reset timer
    playlist_response = await http_client.get(parsed_url.path)
    assert playlist_response.status == 200

    # Wait 5 minutes
    future = dt_util.utcnow() + timedelta(minutes=5)
    async_fire_time_changed(hass, future)

    # Ensure playlist not accessable
    fail_response = await http_client.get(parsed_url.path)
    assert fail_response.status == 404
예제 #6
0
async def test_stream_ended(hass):
    """Test hls stream packets ended."""
    await async_setup_component(hass, 'stream', {
        'stream': {}
    })

    # Setup demo HLS track
    source = generate_h264_video()
    stream = preload_stream(hass, source)
    track = stream.add_provider('hls')
    track.num_segments = 2

    # Request stream
    request_stream(hass, source)

    # Run it dead
    segments = 0
    while await track.recv() is not None:
        segments += 1

    assert segments == 3
    assert not track.get_segment()

    # Stop stream, if it hasn't quit already
    stream.stop()
예제 #7
0
파일: test_hls.py 프로젝트: jhofker/core-1
async def test_stream_keepalive(hass):
    """Test hls stream retries the stream when keepalive=True."""
    await async_setup_component(hass, "stream", {"stream": {}})

    # Setup demo HLS track
    source = "test_stream_keepalive_source"
    stream = preload_stream(hass, source)
    track = stream.add_provider("hls")
    track.num_segments = 2

    cur_time = 0

    def time_side_effect():
        nonlocal cur_time
        if cur_time >= 80:
            stream.keepalive = False  # Thread should exit and be joinable.
        cur_time += 40
        return cur_time

    with patch("av.open") as av_open, patch(
            "homeassistant.components.stream.worker.time"
    ) as mock_time, patch(
            "homeassistant.components.stream.worker.STREAM_RESTART_INCREMENT",
            0):
        av_open.side_effect = av.error.InvalidDataError(-2, "error")
        mock_time.time.side_effect = time_side_effect
        # Request stream
        request_stream(hass, source, keepalive=True)
        stream._thread.join()
        stream._thread = None
        assert av_open.call_count == 2

    # Stop stream, if it hasn't quit already
    stream.stop()
예제 #8
0
async def test_recorder_timeout(hass, hass_client, stream_worker_sync):
    """
    Test recorder timeout.

    Mocks out the cleanup to assert that it is invoked after a timeout.
    This test does not start the recorder save thread.
    """
    await async_setup_component(hass, "stream", {"stream": {}})

    stream_worker_sync.pause()

    with patch(
            "homeassistant.components.stream.recorder.RecorderOutput.cleanup"
    ) as mock_cleanup:
        # Setup demo track
        source = generate_h264_video()
        stream = preload_stream(hass, source)
        recorder = stream.add_provider("recorder")
        stream.start()

        await recorder.recv()

        # Wait a minute
        future = dt_util.utcnow() + timedelta(minutes=1)
        async_fire_time_changed(hass, future)
        await hass.async_block_till_done()

        assert mock_cleanup.called

        stream_worker_sync.resume()
        stream.stop()
        await hass.async_block_till_done()
        await hass.async_block_till_done()
예제 #9
0
파일: test_hls.py 프로젝트: jhofker/core-1
async def test_hls_stream(hass, hass_client, stream_worker_sync):
    """
    Test hls stream.

    Purposefully not mocking anything here to test full
    integration with the stream component.
    """
    await async_setup_component(hass, "stream", {"stream": {}})

    stream_worker_sync.pause()

    # Setup demo HLS track
    source = generate_h264_video()
    stream = preload_stream(hass, source)
    stream.add_provider("hls")

    # Request stream
    url = request_stream(hass, source)

    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

    # Fetch init
    playlist = await playlist_response.text()
    playlist_url = "/".join(parsed_url.path.split("/")[:-1])
    init_url = playlist_url + "/init.mp4"
    init_response = await http_client.get(init_url)
    assert init_response.status == 200

    # Fetch segment
    playlist = await playlist_response.text()
    playlist_url = "/".join(parsed_url.path.split("/")[:-1])
    segment_url = playlist_url + "/" + playlist.splitlines()[-1]
    segment_response = await http_client.get(segment_url)
    assert segment_response.status == 200

    stream_worker_sync.resume()

    # Stop stream, if it hasn't quit already
    stream.stop()

    # Ensure playlist not accessible after stream ends
    fail_response = await http_client.get(parsed_url.path)
    assert fail_response.status == HTTP_NOT_FOUND
예제 #10
0
async def test_record_stream_audio(hass, hass_client, stream_worker_sync,
                                   record_worker_sync):
    """
    Test treatment of different audio inputs.

    Record stream output should have an audio channel when input has
    a valid codec and audio packets and no audio channel otherwise.
    """
    await async_setup_component(hass, "stream", {"stream": {}})

    for a_codec, expected_audio_streams in (
        ("aac", 1),  # aac is a valid mp4 codec
        ("pcm_mulaw", 0),  # G.711 is not a valid mp4 codec
        ("empty", 0),  # audio stream with no packets
        (None, 0),  # no audio stream
    ):
        record_worker_sync.reset()
        stream_worker_sync.pause()

        # Setup demo track
        source = generate_h264_video(container_format="mov",
                                     audio_codec=a_codec)  # mov can store PCM
        stream = preload_stream(hass, source)
        recorder = stream.add_provider("recorder")
        stream.start()

        while True:
            segment = await recorder.recv()
            if not segment:
                break
            last_segment = segment
            stream_worker_sync.resume()

        result = av.open(last_segment.segment, "r", format="mp4")

        assert len(result.streams.audio) == expected_audio_streams
        result.close()
        stream.stop()
        await hass.async_block_till_done()

        # Verify that the save worker was invoked, then block until its
        # thread completes and is shutdown completely to avoid thread leaks.
        record_worker_sync.join()
예제 #11
0
async def test_recorder_timeout(hass, hass_client):
    """Test recorder timeout."""
    await async_setup_component(hass, "stream", {"stream": {}})

    with patch(
            "homeassistant.components.stream.recorder.RecorderOutput.cleanup"
    ) as mock_cleanup:
        # Setup demo track
        source = generate_h264_video()
        stream = preload_stream(hass, source)
        recorder = stream.add_provider("recorder")
        stream.start()

        await recorder.recv()

        # Wait a minute
        future = dt_util.utcnow() + timedelta(minutes=1)
        async_fire_time_changed(hass, future)
        await hass.async_block_till_done()

        assert mock_cleanup.called
예제 #12
0
async def test_hls_stream(hass, hass_client):
    """
    Test hls stream.

    Purposefully not mocking anything here to test full
    integration with the stream component.
    """
    await async_setup_component(hass, 'stream', {
        'stream': {}
    })

    # Setup demo HLS track
    source = generate_h264_video()
    stream = preload_stream(hass, source)
    stream.add_provider('hls')

    # Request stream
    url = request_stream(hass, source)

    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

    # Fetch segment
    playlist = await playlist_response.text()
    playlist_url = '/'.join(parsed_url.path.split('/')[:-1])
    segment_url = playlist_url + playlist.splitlines()[-1][1:]
    segment_response = await http_client.get(segment_url)
    assert segment_response.status == 200

    # Stop stream, if it hasn't quit already
    stream.stop()

    # Ensure playlist not accessable after stream ends
    fail_response = await http_client.get(parsed_url.path)
    assert fail_response.status == 404
예제 #13
0
async def test_stream_ended(hass):
    """Test hls stream packets ended."""
    await async_setup_component(hass, 'stream', {'stream': {}})

    # Setup demo HLS track
    source = generate_h264_video()
    stream = preload_stream(hass, source)
    track = stream.add_provider('hls')
    track.num_segments = 2

    # Request stream
    request_stream(hass, source)

    # Run it dead
    segments = 0
    while await track.recv() is not None:
        segments += 1

    assert segments > 1
    assert not track.get_segment()

    # Stop stream, if it hasn't quit already
    stream.stop()
예제 #14
0
async def test_recorder_timeout(hass, hass_client):
    """Test recorder timeout."""
    await async_setup_component(hass, 'stream', {
        'stream': {}
    })

    with patch(
            'homeassistant.components.stream.recorder.RecorderOutput.cleanup'
            ) as mock_cleanup:
        # Setup demo track
        source = generate_h264_video()
        stream = preload_stream(hass, source)
        recorder = stream.add_provider('recorder')
        stream.start()

        await recorder.recv()

        # Wait a minute
        future = dt_util.utcnow() + timedelta(minutes=1)
        async_fire_time_changed(hass, future)
        await hass.async_block_till_done()

        assert mock_cleanup.called
예제 #15
0
async def test_record_stream_audio(hass, hass_client):
    """
    Test treatment of different audio inputs.

    Record stream output should have an audio channel when input has
    a valid codec and audio packets and no audio channel otherwise.
    """
    await async_setup_component(hass, "stream", {"stream": {}})

    for a_codec, expected_audio_streams in (
        ("aac", 1),  # aac is a valid mp4 codec
        ("pcm_mulaw", 0),  # G.711 is not a valid mp4 codec
        ("empty", 0),  # audio stream with no packets
        (None, 0),  # no audio stream
    ):
        with patch(
                "homeassistant.components.stream.recorder.recorder_save_worker"
        ):
            # Setup demo track
            source = generate_h264_video(
                container_format="mov",
                audio_codec=a_codec)  # mov can store PCM
            stream = preload_stream(hass, source)
            recorder = stream.add_provider("recorder")
            stream.start()

            while True:
                segment = await recorder.recv()
                if not segment:
                    break
                last_segment = segment

            result = av.open(last_segment.segment, "r", format="mp4")

            assert len(result.streams.audio) == expected_audio_streams
            result.close()
            stream.stop()
예제 #16
0
async def test_hls_stream(hass, hass_client):
    """
    Test hls stream.

    Purposefully not mocking anything here to test full
    integration with the stream component.
    """
    await async_setup_component(hass, 'stream', {'stream': {}})

    # Setup demo HLS track
    source = generate_h264_video()
    stream = preload_stream(hass, source)
    stream.add_provider('hls')

    # Request stream
    url = request_stream(hass, source)

    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

    # Fetch segment
    playlist = await playlist_response.text()
    playlist_url = '/'.join(parsed_url.path.split('/')[:-1])
    segment_url = playlist_url + playlist.splitlines()[-1][1:]
    segment_response = await http_client.get(segment_url)
    assert segment_response.status == 200

    # Stop stream, if it hasn't quit already
    stream.stop()

    # Ensure playlist not accessable after stream ends
    fail_response = await http_client.get(parsed_url.path)
    assert fail_response.status == 404
예제 #17
0
async def test_stream_ended(hass):
    """Test hls stream packets ended."""
    await async_setup_component(hass, "stream", {"stream": {}})

    # Setup demo HLS track
    source = generate_h264_video()
    stream = preload_stream(hass, source)
    track = stream.add_provider("hls")

    # Request stream
    request_stream(hass, source)

    # Run it dead
    while True:
        segment = await track.recv()
        if segment is None:
            break
        segments = segment.sequence

    assert segments > 1
    assert not track.get_segment()

    # Stop stream, if it hasn't quit already
    stream.stop()
예제 #18
0
async def test_stream_timeout(hass, hass_client):
    """Test hls stream timeout."""
    await async_setup_component(hass, 'stream', {
        'stream': {}
    })

    # Setup demo HLS track
    source = generate_h264_video()
    stream = preload_stream(hass, source)
    stream.add_provider('hls')

    # Request stream
    url = request_stream(hass, source)

    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

    # Wait a minute
    future = dt_util.utcnow() + timedelta(minutes=1)
    async_fire_time_changed(hass, future)

    # Fetch again to reset timer
    playlist_response = await http_client.get(parsed_url.path)
    assert playlist_response.status == 200

    # Wait 5 minutes
    future = dt_util.utcnow() + timedelta(minutes=5)
    async_fire_time_changed(hass, future)

    # Ensure playlist not accessable
    fail_response = await http_client.get(parsed_url.path)
    assert fail_response.status == 404