Files
dragonpilot/system/webrtc/tests/test_webrtcd.py
Kacper Rączy f058b5d64e webrtcd: webrtc streaming server (audio/video/cereal) (#30186)
* WebRTCClient and WebRTCServer abstractions

* webrtc client implementation

* Interactive test scripts

* Send localDescriptions as offer/asnwer, as they are different

* Tracks need to be added after setting remote description for multi-cam streaming to work

* Remove WebRTCStreamingMetadata

* Wait for tracks

* Move stuff to separate files, rename some things

* Refactor everything, create WebRTCStreamBuilder for both offer and answers

* ta flight done time to grind

* wait for incoming tracks and channels

* Dummy track and frame reader track. Fix timing.

* dt based on camera type

* first trial of the new api

* Fix audio track

* methods for checking for incoming tracks

* Web migration part 2

* Fixes for stream api

* use rtc description for web.py

* experimental cereal proxy

* remove old code from bodyav

* fix is_started

* serialize session description

* fix audio

* messaging channel wrapper

* fix audiotrack

* h264 codec preference

* Add codec preference to tracks

* override sdp codecs

* add logging

* Move cli stuff to separate file

* slight cleanup

* Fix audio track

* create codec_mime inside force_codec function

* fix incoming media estimation

* move builders to __init__

* stream updates following builders

* Update example script

* web.py support for new builder

* web speaker fixes

* StreamingMediaInfo API

* Move things around

* should_add_data_channel rename

* is_connected_and_ready

* fix linter errors

* make cli executable

* remove dumb comments

* logging support

* fix parse_info_from_offer

* improve type annotations

* satisfy linters

* Support for waiting for disconnection

* Split device tracks into video/audio files. Move audio speaker to audio.py

* default dt for dummy video track

* Fix cli

* new speaker fixes

* Remove almost all functionality from web.py

* webrtcd

* continue refactoring web.py

* after handling joystick reset in controlsd with #30409, controls are not necessary anymore

* ping endpoint

* Update js files to at least support what worked previously

* Fixes after some tests on the body

* Streaming fixes

* Remove the use of WebRTCStreamBuilder. Subclass use is now required

* Add todo

* delete all streams on shutdown

* Replace lastPing with lastChannelMessageTime

* Update ping text only if rtc is still on

* That should affect the chart too

* Fix paths in web

* use protocol in SSLContext

* remove warnings since aiortc is not used directly anymore

* check if task is done in stop

* remove channel handler wrapper, since theres only one channel

* Move things around

* Moved webrtc abstractions to separate repository

* Moved webrtcd to tools/webrtc

* Update imports

* Add bodyrtc as dependency

* Add webrtcd to process_config

* Remove usage of DummyVideoStreamTrack

* Add main to webrtcd

* Move webrtcd to system

* Fix imports

* Move cereal proxy logic outside of runner

* Incoming proxy abstractions

* Add some tests

* Make it executable

* Fix process config

* Fix imports

* Additional tests. Add tests to pyproject.toml

* Update poetry lock

* New line

* Bump aiortc to 1.6.0

* Added teleoprtc_repo as submodule, and linked its source dir

* Add init file to webrtc module

* Handle aiortc warnings

* Ignore deprecation warnings

* Ignore resource warning too

* Ignore the warnings

* find free port for test_webrtcd

* Start process inside the test case

* random sleep test

* test 2

* Test endpoint function instead

* Update comment

* Add system/webrtc to release

* default arguments for body fields

* Add teleoprtc to release

* Bump teleoprtc

* Exclude teleoprtc from static analysis

* Use separate event loop for stream session tests
2023-12-01 21:13:37 -08:00

61 lines
2.2 KiB
Python
Executable File

#!/usr/bin/env python
import asyncio
import json
import unittest
from unittest.mock import MagicMock, AsyncMock
# for aiortc and its dependencies
import warnings
warnings.filterwarnings("ignore", category=DeprecationWarning)
from openpilot.system.webrtc.webrtcd import get_stream
import aiortc
from teleoprtc import WebRTCOfferBuilder
class TestWebrtcdProc(unittest.IsolatedAsyncioTestCase):
async def assertCompletesWithTimeout(self, awaitable, timeout=1):
try:
async with asyncio.timeout(timeout):
await awaitable
except asyncio.TimeoutError:
self.fail("Timeout while waiting for awaitable to complete")
async def test_webrtcd(self):
mock_request = MagicMock()
async def connect(offer):
body = {'sdp': offer.sdp, 'cameras': offer.video, 'bridge_services_in': [], 'bridge_services_out': []}
mock_request.json.side_effect = AsyncMock(return_value=body)
response = await get_stream(mock_request)
response_json = json.loads(response.text)
return aiortc.RTCSessionDescription(**response_json)
builder = WebRTCOfferBuilder(connect)
builder.offer_to_receive_video_stream("road")
builder.offer_to_receive_audio_stream()
builder.add_messaging()
stream = builder.stream()
await self.assertCompletesWithTimeout(stream.start())
await self.assertCompletesWithTimeout(stream.wait_for_connection())
self.assertTrue(stream.has_incoming_video_track("road"))
self.assertTrue(stream.has_incoming_audio_track())
self.assertTrue(stream.has_messaging_channel())
video_track, audio_track = stream.get_incoming_video_track("road"), stream.get_incoming_audio_track()
await self.assertCompletesWithTimeout(video_track.recv())
await self.assertCompletesWithTimeout(audio_track.recv())
await self.assertCompletesWithTimeout(stream.stop())
# cleanup, very implementation specific, test may break if it changes
self.assertTrue(mock_request.app["streams"].__setitem__.called, "Implementation changed, please update this test")
_, session = mock_request.app["streams"].__setitem__.call_args.args
await self.assertCompletesWithTimeout(session.post_run_cleanup())
if __name__ == "__main__":
unittest.main()