InputRemotingTest.cs 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. using System.Collections;
  2. using NUnit.Framework;
  3. using UnityEngine.InputSystem;
  4. using Unity.RenderStreaming.InputSystem;
  5. using Unity.RenderStreaming.RuntimeTest.Signaling;
  6. using Unity.WebRTC;
  7. using UnityEngine;
  8. using UnityEngine.TestTools;
  9. using Assert = NUnit.Framework.Assert;
  10. namespace Unity.RenderStreaming.RuntimeTest
  11. {
  12. using InputRemoting = Unity.RenderStreaming.InputSystem.InputRemoting;
  13. class MessageSerializerTest
  14. {
  15. [Test]
  16. public void Serialize()
  17. {
  18. InputRemoting.Message message1 = new InputRemoting.Message
  19. {
  20. participantId = 1,
  21. type = InputRemoting.MessageType.NewEvents,
  22. data = new byte[] { 1, 2, 3, 4, 5 },
  23. };
  24. var bytes = MessageSerializer.Serialize(ref message1);
  25. Assert.That(bytes, Is.Not.Null);
  26. Assert.That(bytes, Has.Length.GreaterThan(0));
  27. MessageSerializer.Deserialize(bytes, out var message2);
  28. Assert.That(message2.participantId, Is.EqualTo(message1.participantId));
  29. Assert.That(message2.type, Is.EqualTo(message1.type));
  30. Assert.That(message2.data, Is.EqualTo(message1.data));
  31. }
  32. }
  33. /// todo(kazuki):workaround
  34. class InputRemotingTest
  35. {
  36. class MyMonoBehaviourTest : MonoBehaviour, IMonoBehaviourTest
  37. {
  38. public bool IsTestFinished
  39. {
  40. get { return true; }
  41. }
  42. }
  43. private MonoBehaviourTest<MyMonoBehaviourTest> _test;
  44. private SignalingManagerInternal _target1, _target2;
  45. private RTCDataChannel _channel1, _channel2;
  46. private string connectionId = "12345";
  47. const float ResendOfferInterval = 3f;
  48. private RenderStreamingDependencies CreateDependencies()
  49. {
  50. return new RenderStreamingDependencies
  51. {
  52. signaling = new MockSignaling(),
  53. config = new RTCConfiguration
  54. {
  55. iceServers = new[] { new RTCIceServer { urls = new[] { "stun:stun.l.google.com:19302" } } },
  56. },
  57. startCoroutine = _test.component.StartCoroutine,
  58. stopCoroutine = _test.component.StopCoroutine,
  59. resentOfferInterval = ResendOfferInterval,
  60. };
  61. }
  62. [UnitySetUp]
  63. public IEnumerator UnitySetUp()
  64. {
  65. MockSignaling.Reset(true);
  66. _test = new MonoBehaviourTest<MyMonoBehaviourTest>();
  67. var dependencies1 = CreateDependencies();
  68. var dependencies2 = CreateDependencies();
  69. _target1 = new SignalingManagerInternal(ref dependencies1);
  70. _target2 = new SignalingManagerInternal(ref dependencies2);
  71. bool isStarted1 = false;
  72. bool isStarted2 = false;
  73. _target1.onStart += () => { isStarted1 = true; };
  74. _target2.onStart += () => { isStarted2 = true; };
  75. yield return new WaitUntil(() => isStarted1 && isStarted2);
  76. bool isCreatedConnection1 = false;
  77. bool isCreatedConnection2 = false;
  78. _target1.onCreatedConnection += _ => { isCreatedConnection1 = true; };
  79. _target2.onCreatedConnection += _ => { isCreatedConnection2 = true; };
  80. // _target1 is Receiver in private mode
  81. _target1.CreateConnection(connectionId);
  82. yield return new WaitUntil(() => isCreatedConnection1);
  83. // _target2 is sender in private mode
  84. _target2.CreateConnection(connectionId);
  85. yield return new WaitUntil(() => isCreatedConnection2);
  86. _target1.onAddChannel += (_, channel) => { _channel1 = channel; };
  87. // send offer automatically after creating channel
  88. _channel2 = _target2.CreateChannel(connectionId, "_test");
  89. bool isGotOffer1 = false;
  90. bool isGotAnswer2 = false;
  91. _target1.onGotOffer += (_, sdp) => { isGotOffer1 = true; };
  92. _target2.onGotAnswer += (_, sdp) => { isGotAnswer2 = true; };
  93. // each peer are not stable, signaling process not complete.
  94. yield return new WaitUntil(() => isGotOffer1);
  95. _target1.SendAnswer(connectionId);
  96. yield return new WaitUntil(() => isGotAnswer2);
  97. Assert.That(isGotAnswer2, Is.True);
  98. // If target1 processes resent Offer from target2, target1 is not stable.
  99. Assert.That(_target2.IsStable(connectionId), Is.True);
  100. yield return new WaitUntil(() => _channel1 != null);
  101. Assert.That(_channel1.ReadyState, Is.EqualTo(RTCDataChannelState.Open));
  102. }
  103. [UnityTearDown]
  104. public IEnumerator UnityTearDown()
  105. {
  106. _target1.DeleteConnection(connectionId);
  107. _target2.DeleteConnection(connectionId);
  108. bool isDeletedConnection1 = false;
  109. bool isDeletedConnection2 = false;
  110. _target1.onDeletedConnection += _ => { isDeletedConnection1 = true; };
  111. _target2.onDeletedConnection += _ => { isDeletedConnection2 = true; };
  112. yield return new WaitUntil(() => isDeletedConnection1 && isDeletedConnection2);
  113. _channel1.Dispose();
  114. _channel2.Dispose();
  115. _channel1 = null;
  116. _channel2 = null;
  117. _test.component.StopAllCoroutines();
  118. _target1.Dispose();
  119. _target2.Dispose();
  120. UnityEngine.Object.DestroyImmediate(_test.gameObject);
  121. }
  122. [Test]
  123. public void DoNothing()
  124. {
  125. }
  126. [Test]
  127. public void Sender()
  128. {
  129. var sender = new Sender();
  130. Assert.That(sender.layouts, Is.Not.Empty);
  131. Assert.That(sender.devices, Is.Not.Empty);
  132. var senderInput = new InputRemoting(sender);
  133. var senderDisposer = senderInput.Subscribe(new Observer(_channel1));
  134. senderInput.StartSending();
  135. senderInput.StopSending();
  136. senderDisposer.Dispose();
  137. sender.Dispose();
  138. }
  139. [Test]
  140. public void Receiver()
  141. {
  142. var receiver = new Receiver(_channel1);
  143. Assert.That(receiver.remoteDevices, Is.Empty);
  144. Assert.That(receiver.remoteLayouts, Is.Empty);
  145. var receiverInput = new InputRemoting(receiver);
  146. var receiverDisposer = receiverInput.Subscribe(receiverInput);
  147. receiverInput.StartSending();
  148. receiverInput.StopSending();
  149. receiverDisposer.Dispose();
  150. }
  151. /// todo(kazuki): This test is failed for timeout on macOS.
  152. /// todo(kazuki): This test is failed for timeout on iPhonePlayer.
  153. [UnityTest, Timeout(3000)]
  154. [UnityPlatform(exclude = new[] { RuntimePlatform.OSXPlayer, RuntimePlatform.IPhonePlayer })]
  155. public IEnumerator AddDevice()
  156. {
  157. var sender = new Sender();
  158. var senderInput = new InputRemoting(sender);
  159. var senderSubscriberDisposer = senderInput.Subscribe(new Observer(_channel1));
  160. var receiver = new Receiver(_channel2);
  161. var receiverInput = new InputRemoting(receiver);
  162. var receiverSubscriberDisposer = receiverInput.Subscribe(receiverInput);
  163. InputDevice device = null;
  164. InputDeviceChange change = default;
  165. receiver.onDeviceChange += (_device, _change) =>
  166. {
  167. device = _device;
  168. change = _change;
  169. };
  170. string layoutName = null;
  171. InputControlLayoutChange layoutChange = default;
  172. receiver.onLayoutChange += (_name, _change) =>
  173. {
  174. layoutName = _name;
  175. layoutChange = _change;
  176. };
  177. receiverInput.StartSending();
  178. senderInput.StartSending();
  179. yield return new WaitUntil(() => device != null);
  180. yield return new WaitUntil(() => layoutName != null);
  181. Assert.That(device, Is.Not.Null);
  182. Assert.That(change, Is.EqualTo(InputDeviceChange.Added));
  183. Assert.That(layoutName, Is.Not.Null);
  184. Assert.That(layoutChange, Is.EqualTo(InputControlLayoutChange.Added));
  185. Assert.That(receiver.remoteLayouts, Is.Not.Empty);
  186. Assert.That(receiver.remoteDevices, Is.Not.Empty);
  187. Assert.That(receiver.remoteDevices, Has.All.Matches<InputDevice>(d => d.remote));
  188. senderInput.StopSending();
  189. receiverInput.StopSending();
  190. senderSubscriberDisposer.Dispose();
  191. receiverSubscriberDisposer.Dispose();
  192. sender.Dispose();
  193. receiver.Dispose();
  194. }
  195. [Test]
  196. public void RemoveRemoteDevices()
  197. {
  198. var sender = new Sender();
  199. var senderInput = new InputRemoting(sender);
  200. senderInput.RemoveRemoteDevices(0);
  201. sender.Dispose();
  202. }
  203. [Test]
  204. public void SaveState()
  205. {
  206. var sender = new Sender();
  207. var inputRemoting = new InputRemoting(sender);
  208. var state = inputRemoting.SaveState();
  209. inputRemoting.RestoreState(state, sender);
  210. sender.Dispose();
  211. }
  212. }
  213. }