|  |  |  | #!/usr/bin/env python
 | 
					
						
							|  |  |  | import pytest
 | 
					
						
							|  |  |  | import asyncio
 | 
					
						
							|  |  |  | import json
 | 
					
						
							|  |  |  | # 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
 | 
					
						
							|  |  |  | from parameterized import parameterized_class
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @parameterized_class(("in_services", "out_services"), [
 | 
					
						
							|  |  |  |   (["testJoystick"], ["carState"]),
 | 
					
						
							|  |  |  |   ([], ["carState"]),
 | 
					
						
							|  |  |  |   (["testJoystick"], []),
 | 
					
						
							|  |  |  |   ([], []),
 | 
					
						
							|  |  |  | ])
 | 
					
						
							|  |  |  | @pytest.mark.asyncio
 | 
					
						
							|  |  |  | class TestWebrtcdProc:
 | 
					
						
							|  |  |  |   async def assertCompletesWithTimeout(self, awaitable, timeout=1):
 | 
					
						
							|  |  |  |     try:
 | 
					
						
							|  |  |  |       async with asyncio.timeout(timeout):
 | 
					
						
							|  |  |  |         await awaitable
 | 
					
						
							|  |  |  |     except TimeoutError:
 | 
					
						
							|  |  |  |       pytest.fail("Timeout while waiting for awaitable to complete")
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   async def test_webrtcd(self, mocker):
 | 
					
						
							|  |  |  |     mock_request = mocker.MagicMock()
 | 
					
						
							|  |  |  |     async def connect(offer):
 | 
					
						
							|  |  |  |       body = {'sdp': offer.sdp, 'cameras': offer.video, 'bridge_services_in': self.in_services, 'bridge_services_out': self.out_services}
 | 
					
						
							|  |  |  |       mock_request.json.side_effect = mocker.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()
 | 
					
						
							|  |  |  |     if len(self.in_services) > 0 or len(self.out_services) > 0:
 | 
					
						
							|  |  |  |       builder.add_messaging()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     stream = builder.stream()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     await self.assertCompletesWithTimeout(stream.start())
 | 
					
						
							|  |  |  |     await self.assertCompletesWithTimeout(stream.wait_for_connection())
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     assert stream.has_incoming_video_track("road")
 | 
					
						
							|  |  |  |     assert stream.has_incoming_audio_track()
 | 
					
						
							|  |  |  |     assert stream.has_messaging_channel() == (len(self.in_services) > 0 or len(self.out_services) > 0)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     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
 | 
					
						
							|  |  |  |     assert 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())
 |