123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- using System;
- using System.Collections;
- using System.Threading;
- using System.Diagnostics;
- using NUnit.Framework;
- using Unity.RenderStreaming.RuntimeTest.Signaling;
- using Unity.RenderStreaming.Signaling;
- using Unity.WebRTC;
- using UnityEngine;
- using UnityEngine.TestTools;
- using Debug = UnityEngine.Debug;
- namespace Unity.RenderStreaming.RuntimeTest
- {
- [TestFixture(typeof(WebSocketSignaling))]
- [TestFixture(typeof(HttpSignaling))]
- [TestFixture(typeof(MockSignaling))]
- [UnityPlatform(exclude = new[] {RuntimePlatform.IPhonePlayer})]
- [ConditionalIgnore(ConditionalIgnore.IL2CPP, "Process.Start does not implement in IL2CPP.")]
- class SignalingTest : IPrebuildSetup
- {
- private readonly Type m_SignalingType;
- private Process m_ServerProcess;
- private RTCSessionDescription m_DescOffer;
- private RTCSessionDescription m_DescAnswer;
- private RTCIceCandidate m_candidate;
- private SynchronizationContext m_Context;
- private ISignaling signaling1;
- private ISignaling signaling2;
- public SignalingTest()
- {
- }
- public SignalingTest(Type type)
- {
- m_SignalingType = type;
- }
- public void Setup()
- {
- if (m_SignalingType == typeof(MockSignaling))
- {
- return;
- }
- #if UNITY_EDITOR
- string dir = System.IO.Directory.GetCurrentDirectory();
- string fileName = System.IO.Path.Combine(dir, Editor.WebAppDownloader.GetFileName());
- if (System.IO.File.Exists(fileName) || System.IO.File.Exists(TestUtility.GetWebAppLocationFromEnv()))
- {
- // already exists.
- return;
- }
- bool downloadRaised = false;
- Editor.WebAppDownloader.DownloadCurrentVersionWebApp(dir, success => { downloadRaised = true; });
- TestUtility.Wait(() => downloadRaised, 10000);
- #endif
- }
- [OneTimeSetUp]
- public void OneTimeSetUp()
- {
- if (m_SignalingType == typeof(MockSignaling))
- {
- MockSignaling.Reset(false);
- return;
- }
- m_ServerProcess = new Process();
- string fileName = TestUtility.GetWebAppLocationFromEnv();
- if (string.IsNullOrEmpty(fileName))
- {
- Debug.Log($"webapp file not found in {fileName}");
- string dir = System.IO.Directory.GetCurrentDirectory();
- fileName = System.IO.Path.Combine(dir, TestUtility.GetFileName());
- }
- Assert.IsTrue(System.IO.File.Exists(fileName), $"webapp file not found in {fileName}");
- ProcessStartInfo startInfo = new ProcessStartInfo
- {
- WindowStyle = ProcessWindowStyle.Hidden,
- FileName = fileName,
- UseShellExecute = false
- };
- string arguments = $"-p {TestUtility.PortNumber}";
- if (m_SignalingType == typeof(HttpSignaling))
- {
- arguments += " -t http";
- }
- startInfo.Arguments = arguments;
- m_ServerProcess.StartInfo = startInfo;
- m_ServerProcess.OutputDataReceived += (sender, e) => { Debug.Log(e.Data); };
- bool success = m_ServerProcess.Start();
- Assert.True(success);
- }
- [OneTimeTearDown]
- public void OneTimeTearDown()
- {
- if (m_SignalingType == typeof(MockSignaling))
- {
- return;
- }
- m_ServerProcess?.Kill();
- m_ServerProcess?.WaitForExit();
- m_ServerProcess?.Dispose();
- m_ServerProcess = null;
- }
- ISignaling CreateSignaling(Type type, SynchronizationContext mainThread)
- {
- if (type == typeof(WebSocketSignaling))
- {
- var settings = new WebSocketSignalingSettings
- (
- url: $"ws://localhost:{TestUtility.PortNumber}"
- );
- return new WebSocketSignaling(settings, mainThread);
- }
- if (type == typeof(HttpSignaling))
- {
- var settings = new HttpSignalingSettings
- (
- url: $"http://localhost:{TestUtility.PortNumber}",
- interval: 100
- );
- return new HttpSignaling(settings, mainThread);
- }
- if (type == typeof(MockSignaling))
- {
- return new MockSignaling();
- }
- throw new ArgumentException();
- }
- [UnitySetUp, Timeout(1000)]
- public IEnumerator UnitySetUp()
- {
- RTCConfiguration config = default;
- RTCIceCandidate candidate_ = null;
- config.iceServers = new[] {new RTCIceServer {urls = new[] {"stun:stun.l.google.com:19302"}}};
- var peer1 = new RTCPeerConnection(ref config);
- var peer2 = new RTCPeerConnection(ref config);
- peer1.OnIceCandidate = candidate => { candidate_ = candidate; };
- AudioStreamTrack track = new AudioStreamTrack();
- peer1.AddTrack(track);
- var op1 = peer1.CreateOffer();
- yield return op1;
- m_DescOffer = op1.Desc;
- var op2 = peer1.SetLocalDescription(ref m_DescOffer);
- yield return op2;
- var op3 = peer2.SetRemoteDescription(ref m_DescOffer);
- yield return op3;
- var op4 = peer2.CreateAnswer();
- yield return op4;
- m_DescAnswer = op4.Desc;
- var op5 = peer2.SetLocalDescription(ref m_DescAnswer);
- yield return op5;
- var op6 = peer1.SetRemoteDescription(ref m_DescAnswer);
- yield return op6;
- yield return new WaitUntil(() => candidate_ != null);
- m_candidate = candidate_;
- track.Dispose();
- peer1.Close();
- peer2.Close();
- m_Context = SynchronizationContext.Current;
- signaling1 = CreateSignaling(m_SignalingType, m_Context);
- signaling2 = CreateSignaling(m_SignalingType, m_Context);
- }
- [TearDown]
- public void TearDown()
- {
- signaling1.Stop();
- signaling2.Stop();
- m_Context = null;
- }
- [UnityTest, Timeout(10000)]
- public IEnumerator OnConnect()
- {
- bool startRaised1 = false;
- string connectionId1 = null;
- signaling1.OnStart += s => { startRaised1 = true; };
- signaling1.Start();
- yield return new WaitUntil(() => startRaised1);
- signaling1.OnCreateConnection += (s, connectionId, polite) => { connectionId1 = connectionId; };
- signaling1.OpenConnection(Guid.NewGuid().ToString());
- yield return new WaitUntil(() => !string.IsNullOrEmpty(connectionId1));
- Assert.IsNotEmpty(connectionId1);
- }
- [UnityTest, Timeout(10000)]
- public IEnumerator OnOffer()
- {
- bool startRaised1 = false;
- bool startRaised2 = false;
- bool offerRaised = false;
- bool raiseOnDestroy1 = false;
- bool raiseOnDestroy2 = false;
- string connectionId1 = null;
- string connectionId2 = null;
- const string _connectionId = "12345";
- signaling1.OnStart += s => { startRaised1 = true; };
- signaling2.OnStart += s => { startRaised2 = true; };
- signaling1.Start();
- signaling2.Start();
- yield return new WaitUntil(() => startRaised1 && startRaised2);
- signaling1.OnCreateConnection += (s, connectionId, polite) => {
- connectionId1 = connectionId;
- };
- signaling1.OnDestroyConnection += (signaling, id) =>
- {
- raiseOnDestroy1 = id == connectionId1;
- };
- signaling1.OpenConnection(_connectionId);
- signaling2.OnCreateConnection += (s, connectionId, polite) => {
- connectionId2 = connectionId;
- };
- signaling1.OnDestroyConnection += (signaling, id) =>
- {
- raiseOnDestroy2 = id == connectionId2;
- };
- signaling2.OpenConnection(_connectionId);
- yield return new WaitUntil(() =>
- !string.IsNullOrEmpty(connectionId1) && !string.IsNullOrEmpty(connectionId2));
- Assert.That(connectionId1, Is.EqualTo(_connectionId));
- Assert.That(connectionId2, Is.EqualTo(_connectionId));
- signaling2.OnOffer += (s, e) => { offerRaised = true; };
- signaling1.SendOffer(connectionId1, m_DescOffer);
- yield return new WaitUntil(() => offerRaised);
- signaling1.CloseConnection(connectionId1);
- yield return new WaitUntil(() => raiseOnDestroy1 && raiseOnDestroy2);
- Assert.That(raiseOnDestroy1, Is.True);
- Assert.That(raiseOnDestroy2, Is.True);
- }
- [UnityTest, Timeout(10000)]
- public IEnumerator OnAnswer()
- {
- bool startRaised1 = false;
- bool startRaised2 = false;
- bool offerRaised = false;
- bool answerRaised = false;
- string connectionId1 = null;
- string connectionId2 = null;
- signaling1.OnStart += s => { startRaised1 = true; };
- signaling2.OnStart += s => { startRaised2 = true; };
- signaling1.Start();
- signaling2.Start();
- yield return new WaitUntil(() => startRaised1 && startRaised2);
- signaling1.OnCreateConnection += (s, connectionId, polite) => {
- connectionId1 = connectionId;
- };
- signaling1.OpenConnection(Guid.NewGuid().ToString());
- signaling2.OnCreateConnection += (s, connectionId, polite) => {
- connectionId2 = connectionId;
- };
- signaling2.OpenConnection(Guid.NewGuid().ToString());
- yield return new WaitUntil(() =>
- !string.IsNullOrEmpty(connectionId1) && !string.IsNullOrEmpty(connectionId2));
- signaling2.OnOffer += (s, e) => { offerRaised = true; };
- signaling1.SendOffer(connectionId1, m_DescOffer);
- yield return new WaitUntil(() => offerRaised);
- signaling1.OnAnswer += (s, e) => { answerRaised = true; };
- signaling2.SendAnswer(connectionId1, m_DescAnswer);
- yield return new WaitUntil(() => answerRaised);
- }
- [UnityTest, Timeout(10000)]
- public IEnumerator OnCandidate()
- {
- bool startRaised1 = false;
- bool startRaised2 = false;
- bool offerRaised = false;
- bool answerRaised = false;
- bool candidateRaised1 = false;
- bool candidateRaised2 = false;
- string connectionId1 = null;
- string connectionId2 = null;
- signaling1.OnStart += s => { startRaised1 = true; };
- signaling2.OnStart += s => { startRaised2 = true; };
- signaling1.Start();
- signaling2.Start();
- yield return new WaitUntil(() => startRaised1 && startRaised2);
- signaling1.OnCreateConnection += (s, connectionId, polite) => {
- connectionId1 = connectionId;
- };
- signaling1.OpenConnection(Guid.NewGuid().ToString());
- signaling2.OnCreateConnection += (s, connectionId, polite) => {
- connectionId2 = connectionId;
- };
- signaling2.OpenConnection(Guid.NewGuid().ToString());
- yield return new WaitUntil(() =>
- !string.IsNullOrEmpty(connectionId1) && !string.IsNullOrEmpty(connectionId2));
- signaling2.OnOffer += (s, e) => { offerRaised = true; };
- signaling1.SendOffer(connectionId1, m_DescOffer);
- yield return new WaitUntil(() => offerRaised);
- signaling1.OnAnswer += (s, e) => { answerRaised = true; };
- signaling2.SendAnswer(connectionId1, m_DescAnswer);
- yield return new WaitUntil(() => answerRaised);
- signaling2.OnIceCandidate += (s, e) => { candidateRaised1 = true; };
- signaling1.SendCandidate(connectionId1, m_candidate);
- yield return new WaitUntil(() => candidateRaised1);
- signaling1.OnIceCandidate += (s, e) => { candidateRaised2 = true; };
- signaling2.SendCandidate(connectionId1, m_candidate);
- yield return new WaitUntil(() => candidateRaised2);
- }
- }
- }
|