StatsReportTest.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. using System;
  2. using UnityEngine;
  3. using NUnit.Framework;
  4. namespace Unity.WebRTC.RuntimeTest
  5. {
  6. class StatsReportTest
  7. {
  8. [SetUp]
  9. public void SetUp()
  10. {
  11. WebRTC.Initialize(true);
  12. }
  13. [TearDown]
  14. public void TearDown()
  15. {
  16. WebRTC.Dispose();
  17. }
  18. [Test]
  19. public void ConstructorThrowsException()
  20. {
  21. Assert.That(() => new RTCStatsReport(IntPtr.Zero), Throws.ArgumentException);
  22. }
  23. }
  24. class StatsCheck
  25. {
  26. class Ignore
  27. {
  28. static public void Pass<T>(T val)
  29. {
  30. }
  31. }
  32. public static void Test(RTCStats stats)
  33. {
  34. switch (stats.Type)
  35. {
  36. case RTCStatsType.CandidatePair:
  37. var iceCandidatePairStats = stats as RTCIceCandidatePairStats;
  38. Assert.NotNull(iceCandidatePairStats);
  39. Assert.AreEqual(24, iceCandidatePairStats.Dict.Count);
  40. Assert.IsNotEmpty(iceCandidatePairStats.transportId);
  41. Assert.IsNotEmpty(iceCandidatePairStats.localCandidateId);
  42. Assert.IsNotEmpty(iceCandidatePairStats.remoteCandidateId);
  43. Assert.IsNotEmpty(iceCandidatePairStats.state);
  44. Ignore.Pass(iceCandidatePairStats.priority);
  45. Ignore.Pass(iceCandidatePairStats.nominated);
  46. Ignore.Pass(iceCandidatePairStats.writable);
  47. Ignore.Pass(iceCandidatePairStats.readable);
  48. Ignore.Pass(iceCandidatePairStats.bytesSent);
  49. Ignore.Pass(iceCandidatePairStats.bytesReceived);
  50. Ignore.Pass(iceCandidatePairStats.totalRoundTripTime);
  51. Ignore.Pass(iceCandidatePairStats.currentRoundTripTime);
  52. Ignore.Pass(iceCandidatePairStats.availableOutgoingBitrate);
  53. Ignore.Pass(iceCandidatePairStats.availableIncomingBitrate);
  54. Ignore.Pass(iceCandidatePairStats.consentRequestsReceived);
  55. Ignore.Pass(iceCandidatePairStats.consentRequestsSent);
  56. Ignore.Pass(iceCandidatePairStats.requestsReceived);
  57. Ignore.Pass(iceCandidatePairStats.requestsSent);
  58. Ignore.Pass(iceCandidatePairStats.responsesReceived);
  59. Ignore.Pass(iceCandidatePairStats.responsesSent);
  60. Ignore.Pass(iceCandidatePairStats.retransmissionsReceived);
  61. Ignore.Pass(iceCandidatePairStats.retransmissionsSent);
  62. Ignore.Pass(iceCandidatePairStats.consentResponsesReceived);
  63. Ignore.Pass(iceCandidatePairStats.consentResponsesSent);
  64. break;
  65. case RTCStatsType.DataChannel:
  66. var dataChannelStats = stats as RTCDataChannelStats;
  67. Assert.NotNull(dataChannelStats);
  68. Assert.AreEqual(8, dataChannelStats.Dict.Count);
  69. Assert.IsNotEmpty(dataChannelStats.label);
  70. Assert.IsNotEmpty(dataChannelStats.state);
  71. Ignore.Pass(dataChannelStats.protocol);
  72. Ignore.Pass(dataChannelStats.messagesSent);
  73. Ignore.Pass(dataChannelStats.messagesReceived);
  74. Ignore.Pass(dataChannelStats.dataChannelIdentifier);
  75. Ignore.Pass(dataChannelStats.bytesSent);
  76. Ignore.Pass(dataChannelStats.bytesReceived);
  77. break;
  78. case RTCStatsType.LocalCandidate:
  79. case RTCStatsType.RemoteCandidate:
  80. var candidateStats = stats as RTCIceCandidateStats;
  81. Assert.NotNull(candidateStats);
  82. Assert.AreEqual(11, candidateStats.Dict.Count);
  83. Assert.IsNotEmpty(candidateStats.protocol);
  84. Assert.IsNotEmpty(candidateStats.candidateType);
  85. Ignore.Pass(candidateStats.ip);
  86. Ignore.Pass(candidateStats.address);
  87. Assert.IsNotEmpty(candidateStats.transportId);
  88. Ignore.Pass(candidateStats.url);
  89. Ignore.Pass(candidateStats.relayProtocol);
  90. Ignore.Pass(candidateStats.networkType);
  91. Ignore.Pass(candidateStats.priority);
  92. Ignore.Pass(candidateStats.isRemote);
  93. Ignore.Pass(candidateStats.port);
  94. break;
  95. case RTCStatsType.Certificate:
  96. var certificateStats = stats as RTCCertificateStats;
  97. Assert.NotNull(certificateStats);
  98. Assert.AreEqual(4, certificateStats.Dict.Count);
  99. Assert.IsNotEmpty(certificateStats.fingerprint);
  100. Assert.IsNotEmpty(certificateStats.fingerprintAlgorithm);
  101. Assert.IsNotEmpty(certificateStats.base64Certificate);
  102. Ignore.Pass(certificateStats.issuerCertificateId);
  103. break;
  104. case RTCStatsType.Codec:
  105. var codecStats = stats as RTCCodecStats;
  106. Assert.NotNull(codecStats);
  107. Assert.AreEqual(6, codecStats.Dict.Count);
  108. Assert.IsNotEmpty(codecStats.mimeType);
  109. Assert.IsNotEmpty(codecStats.transportId);
  110. Ignore.Pass(codecStats.sdpFmtpLine);
  111. Ignore.Pass(codecStats.payloadType);
  112. Ignore.Pass(codecStats.clockRate);
  113. Ignore.Pass(codecStats.channels);
  114. break;
  115. case RTCStatsType.InboundRtp:
  116. var inboundRtpStreamStats = stats as RTCInboundRTPStreamStats;
  117. Assert.NotNull(inboundRtpStreamStats);
  118. Assert.AreEqual(55, inboundRtpStreamStats.Dict.Count);
  119. Ignore.Pass(inboundRtpStreamStats.ssrc);
  120. // Obsolete: Assert.IsNotEmpty(inboundRtpStreamStats.mediaType);
  121. Assert.IsNotEmpty(inboundRtpStreamStats.kind);
  122. // Obsolete: Ignore.Pass(inboundRtpStreamStats.trackId);
  123. Assert.IsNotEmpty(inboundRtpStreamStats.transportId);
  124. Ignore.Pass(inboundRtpStreamStats.codecId);
  125. Ignore.Pass(inboundRtpStreamStats.packetsReceived);
  126. Ignore.Pass(inboundRtpStreamStats.fecPacketsReceived);
  127. Ignore.Pass(inboundRtpStreamStats.fecPacketsDiscarded);
  128. Ignore.Pass(inboundRtpStreamStats.bytesReceived);
  129. Ignore.Pass(inboundRtpStreamStats.headerBytesReceived);
  130. Ignore.Pass(inboundRtpStreamStats.packetsLost);
  131. Ignore.Pass(inboundRtpStreamStats.lastPacketReceivedTimestamp);
  132. Ignore.Pass(inboundRtpStreamStats.jitter);
  133. Ignore.Pass(inboundRtpStreamStats.jitterBufferDelay);
  134. Ignore.Pass(inboundRtpStreamStats.jitterBufferEmittedCount);
  135. Ignore.Pass(inboundRtpStreamStats.totalSamplesReceived);
  136. Ignore.Pass(inboundRtpStreamStats.totalSamplesDuration);
  137. Ignore.Pass(inboundRtpStreamStats.concealedSamples);
  138. Ignore.Pass(inboundRtpStreamStats.silentConcealedSamples);
  139. Ignore.Pass(inboundRtpStreamStats.concealmentEvents);
  140. Ignore.Pass(inboundRtpStreamStats.insertedSamplesForDeceleration);
  141. Ignore.Pass(inboundRtpStreamStats.removedSamplesForAcceleration);
  142. Ignore.Pass(inboundRtpStreamStats.audioLevel);
  143. Ignore.Pass(inboundRtpStreamStats.totalAudioEnergy);
  144. Ignore.Pass(inboundRtpStreamStats.roundTripTime);
  145. Ignore.Pass(inboundRtpStreamStats.packetsDiscarded);
  146. Ignore.Pass(inboundRtpStreamStats.packetsRepaired);
  147. Ignore.Pass(inboundRtpStreamStats.burstPacketsLost);
  148. Ignore.Pass(inboundRtpStreamStats.burstPacketsDiscarded);
  149. Ignore.Pass(inboundRtpStreamStats.burstLossCount);
  150. Ignore.Pass(inboundRtpStreamStats.burstDiscardCount);
  151. Ignore.Pass(inboundRtpStreamStats.burstLossRate);
  152. Ignore.Pass(inboundRtpStreamStats.burstDiscardRate);
  153. Ignore.Pass(inboundRtpStreamStats.gapLossRate);
  154. Ignore.Pass(inboundRtpStreamStats.gapDiscardRate);
  155. Ignore.Pass(inboundRtpStreamStats.framesReceived);
  156. Ignore.Pass(inboundRtpStreamStats.frameWidth);
  157. Ignore.Pass(inboundRtpStreamStats.frameHeight);
  158. Ignore.Pass(inboundRtpStreamStats.frameBitDepth);
  159. Ignore.Pass(inboundRtpStreamStats.framesPerSecond);
  160. Ignore.Pass(inboundRtpStreamStats.framesDecoded);
  161. Ignore.Pass(inboundRtpStreamStats.keyFramesDecoded);
  162. Ignore.Pass(inboundRtpStreamStats.totalDecodeTime);
  163. Ignore.Pass(inboundRtpStreamStats.totalInterFrameDelay);
  164. Ignore.Pass(inboundRtpStreamStats.totalSquaredInterFrameDelay);
  165. Ignore.Pass(inboundRtpStreamStats.contentType);
  166. Ignore.Pass(inboundRtpStreamStats.estimatedPlayoutTimestamp);
  167. Ignore.Pass(inboundRtpStreamStats.decoderImplementation);
  168. break;
  169. case RTCStatsType.RemoteInboundRtp:
  170. var remoteInboundRtpStreamStats = stats as RTCRemoteInboundRtpStreamStats;
  171. Assert.NotNull(remoteInboundRtpStreamStats);
  172. Assert.AreEqual(13, remoteInboundRtpStreamStats.Dict.Count);
  173. Ignore.Pass(remoteInboundRtpStreamStats.ssrc);
  174. Assert.IsNotEmpty(remoteInboundRtpStreamStats.kind);
  175. Assert.IsNotEmpty(remoteInboundRtpStreamStats.transportId);
  176. Assert.IsNotEmpty(remoteInboundRtpStreamStats.codecId);
  177. Ignore.Pass(remoteInboundRtpStreamStats.packetsLost);
  178. Ignore.Pass(remoteInboundRtpStreamStats.jitter);
  179. Assert.IsNotEmpty(remoteInboundRtpStreamStats.localId);
  180. Ignore.Pass(remoteInboundRtpStreamStats.roundTripTime);
  181. Ignore.Pass(remoteInboundRtpStreamStats.fractionLost);
  182. Ignore.Pass(remoteInboundRtpStreamStats.totalRoundTripTime);
  183. Ignore.Pass(remoteInboundRtpStreamStats.roundTripTimeMeasurements);
  184. // Obsolete: Assert.IsNotEmpty(remoteInboundRtpStreamStats.trackId);
  185. // Obsolete: Assert.IsNotEmpty(remoteInboundRtpStreamStats.mediaType);
  186. break;
  187. case RTCStatsType.RemoteOutboundRtp:
  188. var remoteOutboundRtpStreamStats = stats as RTCRemoteOutboundRtpStreamStats;
  189. Assert.NotNull(remoteOutboundRtpStreamStats);
  190. Assert.AreEqual(11, remoteOutboundRtpStreamStats.Dict.Count);
  191. Assert.IsNotEmpty(remoteOutboundRtpStreamStats.localId);
  192. Ignore.Pass(remoteOutboundRtpStreamStats.remoteTimestamp);
  193. Ignore.Pass(remoteOutboundRtpStreamStats.reportsSent);
  194. Ignore.Pass(remoteOutboundRtpStreamStats.packetsSent);
  195. Ignore.Pass(remoteOutboundRtpStreamStats.bytesSent);
  196. Ignore.Pass(remoteOutboundRtpStreamStats.ssrc);
  197. Assert.IsNotEmpty(remoteOutboundRtpStreamStats.kind);
  198. Assert.IsNotEmpty(remoteOutboundRtpStreamStats.transportId);
  199. Assert.IsNotEmpty(remoteOutboundRtpStreamStats.codecId);
  200. // Obsolete: Assert.IsNotEmpty(remoteOutboundRtpStreamStats.trackId);
  201. // Obsolete: Assert.IsNotEmpty(remoteOutboundRtpStreamStats.mediaType);
  202. break;
  203. case RTCStatsType.Transport:
  204. var transportStats = stats as RTCTransportStats;
  205. Assert.NotNull(transportStats);
  206. Assert.AreEqual(13, transportStats.Dict.Count);
  207. Ignore.Pass(transportStats.bytesSent);
  208. Ignore.Pass(transportStats.bytesReceived);
  209. Ignore.Pass(transportStats.packetsSent);
  210. Ignore.Pass(transportStats.packetsReceived);
  211. Ignore.Pass(transportStats.rtcpTransportStatsId);
  212. Ignore.Pass(transportStats.dtlsState);
  213. Ignore.Pass(transportStats.selectedCandidatePairId);
  214. Ignore.Pass(transportStats.localCertificateId);
  215. Ignore.Pass(transportStats.remoteCertificateId);
  216. Ignore.Pass(transportStats.tlsVersion);
  217. Ignore.Pass(transportStats.dtlsCipher);
  218. Ignore.Pass(transportStats.srtpCipher);
  219. Ignore.Pass(transportStats.selectedCandidatePairChanges);
  220. break;
  221. case RTCStatsType.OutboundRtp:
  222. var outboundRtpStreamStats = stats as RTCOutboundRTPStreamStats;
  223. Assert.NotNull(outboundRtpStreamStats);
  224. Assert.AreEqual(33, outboundRtpStreamStats.Dict.Count);
  225. Ignore.Pass(outboundRtpStreamStats.ssrc);
  226. // Obsolete: Assert.IsNotEmpty(outboundRtpStreamStats.mediaType);
  227. Assert.IsNotEmpty(outboundRtpStreamStats.kind);
  228. // Obsolete: Ignore.Pass(outboundRtpStreamStats.trackId);
  229. Assert.IsNotEmpty(outboundRtpStreamStats.transportId);
  230. Ignore.Pass(outboundRtpStreamStats.codecId);
  231. Ignore.Pass(outboundRtpStreamStats.mediaSourceId);
  232. Ignore.Pass(outboundRtpStreamStats.remoteId);
  233. Ignore.Pass(outboundRtpStreamStats.rid);
  234. Ignore.Pass(outboundRtpStreamStats.packetsSent);
  235. Ignore.Pass(outboundRtpStreamStats.retransmittedPacketsSent);
  236. Ignore.Pass(outboundRtpStreamStats.bytesSent);
  237. Ignore.Pass(outboundRtpStreamStats.headerBytesSent);
  238. Ignore.Pass(outboundRtpStreamStats.retransmittedBytesSent);
  239. Ignore.Pass(outboundRtpStreamStats.targetBitrate);
  240. Ignore.Pass(outboundRtpStreamStats.framesEncoded);
  241. Ignore.Pass(outboundRtpStreamStats.keyFramesEncoded);
  242. Ignore.Pass(outboundRtpStreamStats.totalEncodeTime);
  243. Ignore.Pass(outboundRtpStreamStats.totalEncodedBytesTarget);
  244. Ignore.Pass(outboundRtpStreamStats.frameWidth);
  245. Ignore.Pass(outboundRtpStreamStats.frameHeight);
  246. Ignore.Pass(outboundRtpStreamStats.framesPerSecond);
  247. Ignore.Pass(outboundRtpStreamStats.framesSent);
  248. Ignore.Pass(outboundRtpStreamStats.hugeFramesSent);
  249. Ignore.Pass(outboundRtpStreamStats.totalPacketSendDelay);
  250. Ignore.Pass(outboundRtpStreamStats.qualityLimitationReason);
  251. Ignore.Pass(outboundRtpStreamStats.qualityLimitationResolutionChanges);
  252. Ignore.Pass(outboundRtpStreamStats.contentType);
  253. Ignore.Pass(outboundRtpStreamStats.encoderImplementation);
  254. Ignore.Pass(outboundRtpStreamStats.firCount);
  255. Ignore.Pass(outboundRtpStreamStats.pliCount);
  256. Ignore.Pass(outboundRtpStreamStats.nackCount);
  257. Ignore.Pass(outboundRtpStreamStats.qpSum);
  258. break;
  259. case RTCStatsType.MediaSource:
  260. var mediaSourceStats = stats as RTCMediaSourceStats;
  261. Assert.NotNull(mediaSourceStats);
  262. Assert.IsNotEmpty(mediaSourceStats.trackIdentifier);
  263. Assert.IsNotEmpty(mediaSourceStats.kind);
  264. if (mediaSourceStats is RTCVideoSourceStats videoSourceStats)
  265. {
  266. Assert.AreEqual(6, videoSourceStats.Dict.Count);
  267. Ignore.Pass(videoSourceStats.width);
  268. Ignore.Pass(videoSourceStats.height);
  269. Ignore.Pass(videoSourceStats.frames);
  270. Ignore.Pass(videoSourceStats.framesPerSecond);
  271. }
  272. if (mediaSourceStats is RTCAudioSourceStats audioSourceStats)
  273. {
  274. Assert.AreEqual(5, audioSourceStats.Dict.Count);
  275. Ignore.Pass(audioSourceStats.audioLevel);
  276. Ignore.Pass(audioSourceStats.totalAudioEnergy);
  277. Ignore.Pass(audioSourceStats.totalSamplesDuration);
  278. }
  279. break;
  280. case RTCStatsType.Track:
  281. var mediaStreamTrackStats = stats as RTCMediaStreamTrackStats;
  282. Assert.NotNull(mediaStreamTrackStats);
  283. Assert.AreEqual(42, mediaStreamTrackStats.Dict.Count);
  284. Ignore.Pass(mediaStreamTrackStats.trackIdentifier);
  285. Ignore.Pass(mediaStreamTrackStats.mediaSourceId);
  286. Ignore.Pass(mediaStreamTrackStats.remoteSource);
  287. Ignore.Pass(mediaStreamTrackStats.ended);
  288. Ignore.Pass(mediaStreamTrackStats.detached);
  289. Ignore.Pass(mediaStreamTrackStats.kind);
  290. Ignore.Pass(mediaStreamTrackStats.jitterBufferDelay);
  291. Ignore.Pass(mediaStreamTrackStats.jitterBufferEmittedCount);
  292. Ignore.Pass(mediaStreamTrackStats.frameWidth);
  293. Ignore.Pass(mediaStreamTrackStats.frameHeight);
  294. Ignore.Pass(mediaStreamTrackStats.framesPerSecond);
  295. Ignore.Pass(mediaStreamTrackStats.framesSent);
  296. Ignore.Pass(mediaStreamTrackStats.hugeFramesSent);
  297. Ignore.Pass(mediaStreamTrackStats.framesReceived);
  298. Ignore.Pass(mediaStreamTrackStats.framesDecoded);
  299. Ignore.Pass(mediaStreamTrackStats.framesDropped);
  300. Ignore.Pass(mediaStreamTrackStats.framesCorrupted);
  301. Ignore.Pass(mediaStreamTrackStats.partialFramesLost);
  302. Ignore.Pass(mediaStreamTrackStats.fullFramesLost);
  303. Ignore.Pass(mediaStreamTrackStats.audioLevel);
  304. Ignore.Pass(mediaStreamTrackStats.totalAudioEnergy);
  305. Ignore.Pass(mediaStreamTrackStats.echoReturnLoss);
  306. Ignore.Pass(mediaStreamTrackStats.echoReturnLossEnhancement);
  307. Ignore.Pass(mediaStreamTrackStats.totalSamplesReceived);
  308. Ignore.Pass(mediaStreamTrackStats.totalSamplesDuration);
  309. Ignore.Pass(mediaStreamTrackStats.concealedSamples);
  310. Ignore.Pass(mediaStreamTrackStats.silentConcealedSamples);
  311. Ignore.Pass(mediaStreamTrackStats.concealmentEvents);
  312. Ignore.Pass(mediaStreamTrackStats.insertedSamplesForDeceleration);
  313. Ignore.Pass(mediaStreamTrackStats.removedSamplesForAcceleration);
  314. Ignore.Pass(mediaStreamTrackStats.jitterBufferFlushes);
  315. Ignore.Pass(mediaStreamTrackStats.delayedPacketOutageSamples);
  316. Ignore.Pass(mediaStreamTrackStats.relativePacketArrivalDelay);
  317. Ignore.Pass(mediaStreamTrackStats.jitterBufferTargetDelay);
  318. Ignore.Pass(mediaStreamTrackStats.interruptionCount);
  319. Ignore.Pass(mediaStreamTrackStats.totalInterruptionDuration);
  320. Ignore.Pass(mediaStreamTrackStats.freezeCount);
  321. Ignore.Pass(mediaStreamTrackStats.pauseCount);
  322. Ignore.Pass(mediaStreamTrackStats.totalFreezesDuration);
  323. Ignore.Pass(mediaStreamTrackStats.totalPausesDuration);
  324. Ignore.Pass(mediaStreamTrackStats.totalFramesDuration);
  325. Ignore.Pass(mediaStreamTrackStats.sumOfSquaredFramesDuration);
  326. break;
  327. case RTCStatsType.Stream:
  328. var mediaStreamStats = stats as RTCMediaStreamStats;
  329. Assert.NotNull(mediaStreamStats);
  330. Assert.AreEqual(2, mediaStreamStats.Dict.Count);
  331. Ignore.Pass(mediaStreamStats.streamIdentifier);
  332. Ignore.Pass(mediaStreamStats.trackIds);
  333. break;
  334. case RTCStatsType.PeerConnection:
  335. var peerConnectionStats = stats as RTCPeerConnectionStats;
  336. Assert.NotNull(peerConnectionStats);
  337. Assert.AreEqual(2, peerConnectionStats.Dict.Count);
  338. Ignore.Pass(peerConnectionStats.dataChannelsOpened);
  339. Ignore.Pass(peerConnectionStats.dataChannelsClosed);
  340. break;
  341. default:
  342. Debug.LogWarning(stats.Type);
  343. break;
  344. }
  345. }
  346. }
  347. }