From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- dom/media/webrtc/tests/mochitests/templates.js | 615 +++++++++++++++++++++++++ 1 file changed, 615 insertions(+) create mode 100644 dom/media/webrtc/tests/mochitests/templates.js (limited to 'dom/media/webrtc/tests/mochitests/templates.js') diff --git a/dom/media/webrtc/tests/mochitests/templates.js b/dom/media/webrtc/tests/mochitests/templates.js new file mode 100644 index 0000000000..6b7750fd2c --- /dev/null +++ b/dom/media/webrtc/tests/mochitests/templates.js @@ -0,0 +1,615 @@ +/** + * Default list of commands to execute for a PeerConnection test. + */ + +const STABLE = "stable"; +const HAVE_LOCAL_OFFER = "have-local-offer"; +const HAVE_REMOTE_OFFER = "have-remote-offer"; +const CLOSED = "closed"; + +const ICE_NEW = "new"; +const GATH_NEW = "new"; +const GATH_GATH = "gathering"; +const GATH_COMPLETE = "complete"; + +function deltaSeconds(date1, date2) { + return (date2.getTime() - date1.getTime()) / 1000; +} + +function dumpSdp(test) { + if (typeof test._local_offer !== "undefined") { + dump("ERROR: SDP offer: " + test._local_offer.sdp.replace(/[\r]/g, "")); + } + if (typeof test._remote_answer !== "undefined") { + dump("ERROR: SDP answer: " + test._remote_answer.sdp.replace(/[\r]/g, "")); + } + + if ( + test.pcLocal && + typeof test.pcLocal._local_ice_candidates !== "undefined" + ) { + dump( + "pcLocal._local_ice_candidates: " + + JSON.stringify(test.pcLocal._local_ice_candidates) + + "\n" + ); + dump( + "pcLocal._remote_ice_candidates: " + + JSON.stringify(test.pcLocal._remote_ice_candidates) + + "\n" + ); + dump( + "pcLocal._ice_candidates_to_add: " + + JSON.stringify(test.pcLocal._ice_candidates_to_add) + + "\n" + ); + } + if ( + test.pcRemote && + typeof test.pcRemote._local_ice_candidates !== "undefined" + ) { + dump( + "pcRemote._local_ice_candidates: " + + JSON.stringify(test.pcRemote._local_ice_candidates) + + "\n" + ); + dump( + "pcRemote._remote_ice_candidates: " + + JSON.stringify(test.pcRemote._remote_ice_candidates) + + "\n" + ); + dump( + "pcRemote._ice_candidates_to_add: " + + JSON.stringify(test.pcRemote._ice_candidates_to_add) + + "\n" + ); + } + + if (test.pcLocal && typeof test.pcLocal.iceConnectionLog !== "undefined") { + dump( + "pcLocal ICE connection state log: " + + test.pcLocal.iceConnectionLog + + "\n" + ); + } + if (test.pcRemote && typeof test.pcRemote.iceConnectionLog !== "undefined") { + dump( + "pcRemote ICE connection state log: " + + test.pcRemote.iceConnectionLog + + "\n" + ); + } + + if ( + test.pcLocal && + test.pcRemote && + typeof test.pcLocal.setRemoteDescDate !== "undefined" && + typeof test.pcRemote.setLocalDescDate !== "undefined" + ) { + var delta = deltaSeconds( + test.pcLocal.setRemoteDescDate, + test.pcRemote.setLocalDescDate + ); + dump( + "Delay between pcLocal.setRemote <-> pcRemote.setLocal: " + delta + "\n" + ); + } + if ( + test.pcLocal && + test.pcRemote && + typeof test.pcLocal.setRemoteDescDate !== "undefined" && + typeof test.pcLocal.setRemoteDescStableEventDate !== "undefined" + ) { + var delta = deltaSeconds( + test.pcLocal.setRemoteDescDate, + test.pcLocal.setRemoteDescStableEventDate + ); + dump( + "Delay between pcLocal.setRemote <-> pcLocal.signalingStateStable: " + + delta + + "\n" + ); + } + if ( + test.pcLocal && + test.pcRemote && + typeof test.pcRemote.setLocalDescDate !== "undefined" && + typeof test.pcRemote.setLocalDescStableEventDate !== "undefined" + ) { + var delta = deltaSeconds( + test.pcRemote.setLocalDescDate, + test.pcRemote.setLocalDescStableEventDate + ); + dump( + "Delay between pcRemote.setLocal <-> pcRemote.signalingStateStable: " + + delta + + "\n" + ); + } +} + +// We need to verify that at least one candidate has been (or will be) gathered. +function waitForAnIceCandidate(pc) { + return new Promise(resolve => { + if (!pc.localRequiresTrickleIce || pc._local_ice_candidates.length) { + resolve(); + } else { + // In some circumstances, especially when both PCs are on the same + // browser, even though we are connected, the connection can be + // established without receiving a single candidate from one or other + // peer. So we wait for at least one... + pc._pc.addEventListener("icecandidate", resolve); + } + }).then(() => { + ok( + pc._local_ice_candidates.length, + pc + " received local trickle ICE candidates" + ); + isnot( + pc._pc.iceGatheringState, + GATH_NEW, + pc + " ICE gathering state is not 'new'" + ); + }); +} + +async function checkTrackStats(pc, track, outbound) { + const audio = track.kind == "audio"; + const msg = + `${pc} stats ${outbound ? "outbound " : "inbound "}` + + `${audio ? "audio" : "video"} rtp track id ${track.id}`; + const stats = await pc.getStats(track); + ok( + pc.hasStat(stats, { + type: outbound ? "outbound-rtp" : "inbound-rtp", + kind: audio ? "audio" : "video", + }), + `${msg} - found expected stats` + ); + ok( + !pc.hasStat(stats, { + type: outbound ? "inbound-rtp" : "outbound-rtp", + }), + `${msg} - did not find extra stats with wrong direction` + ); + ok( + !pc.hasStat(stats, { + kind: audio ? "video" : "audio", + }), + `${msg} - did not find extra stats with wrong media type` + ); +} + +function checkAllTrackStats(pc) { + return Promise.all([ + ...pc + .getExpectedActiveReceivers() + .map(({ track }) => checkTrackStats(pc, track, false)), + ...pc + .getExpectedSenders() + .map(({ track }) => checkTrackStats(pc, track, true)), + ]); +} + +// Commands run once at the beginning of each test, even when performing a +// renegotiation test. +var commandsPeerConnectionInitial = [ + function PC_LOCAL_SETUP_ICE_LOGGER(test) { + test.pcLocal.logIceConnectionState(); + }, + + function PC_REMOTE_SETUP_ICE_LOGGER(test) { + test.pcRemote.logIceConnectionState(); + }, + + function PC_LOCAL_SETUP_SIGNALING_LOGGER(test) { + test.pcLocal.logSignalingState(); + }, + + function PC_REMOTE_SETUP_SIGNALING_LOGGER(test) { + test.pcRemote.logSignalingState(); + }, + + function PC_LOCAL_SETUP_TRACK_HANDLER(test) { + test.pcLocal.setupTrackEventHandler(); + }, + + function PC_REMOTE_SETUP_TRACK_HANDLER(test) { + test.pcRemote.setupTrackEventHandler(); + }, + + function PC_LOCAL_CHECK_INITIAL_SIGNALINGSTATE(test) { + is( + test.pcLocal.signalingState, + STABLE, + "Initial local signalingState is 'stable'" + ); + }, + + function PC_REMOTE_CHECK_INITIAL_SIGNALINGSTATE(test) { + is( + test.pcRemote.signalingState, + STABLE, + "Initial remote signalingState is 'stable'" + ); + }, + + function PC_LOCAL_CHECK_INITIAL_ICE_STATE(test) { + is( + test.pcLocal.iceConnectionState, + ICE_NEW, + "Initial local ICE connection state is 'new'" + ); + }, + + function PC_REMOTE_CHECK_INITIAL_ICE_STATE(test) { + is( + test.pcRemote.iceConnectionState, + ICE_NEW, + "Initial remote ICE connection state is 'new'" + ); + }, + + function PC_LOCAL_CHECK_INITIAL_CAN_TRICKLE_SYNC(test) { + is( + test.pcLocal._pc.canTrickleIceCandidates, + null, + "Local trickle status should start out unknown" + ); + }, + + function PC_REMOTE_CHECK_INITIAL_CAN_TRICKLE_SYNC(test) { + is( + test.pcRemote._pc.canTrickleIceCandidates, + null, + "Remote trickle status should start out unknown" + ); + }, +]; + +var commandsGetUserMedia = [ + function PC_LOCAL_GUM(test) { + return test.pcLocal.getAllUserMediaAndAddStreams(test.pcLocal.constraints); + }, + + function PC_REMOTE_GUM(test) { + return test.pcRemote.getAllUserMediaAndAddStreams( + test.pcRemote.constraints + ); + }, +]; + +var commandsPeerConnectionOfferAnswer = [ + function PC_LOCAL_SETUP_ICE_HANDLER(test) { + test.pcLocal.setupIceCandidateHandler(test); + }, + + function PC_REMOTE_SETUP_ICE_HANDLER(test) { + test.pcRemote.setupIceCandidateHandler(test); + }, + + function PC_LOCAL_CREATE_OFFER(test) { + return test.createOffer(test.pcLocal).then(offer => { + is( + test.pcLocal.signalingState, + STABLE, + "Local create offer does not change signaling state" + ); + }); + }, + + function PC_LOCAL_SET_LOCAL_DESCRIPTION(test) { + return test + .setLocalDescription(test.pcLocal, test.originalOffer, HAVE_LOCAL_OFFER) + .then(() => { + is( + test.pcLocal.signalingState, + HAVE_LOCAL_OFFER, + "signalingState after local setLocalDescription is 'have-local-offer'" + ); + }); + }, + + function PC_REMOTE_GET_OFFER(test) { + test._local_offer = test.originalOffer; + test._offer_constraints = test.pcLocal.constraints; + test._offer_options = test.pcLocal.offerOptions; + return Promise.resolve(); + }, + + function PC_REMOTE_SET_REMOTE_DESCRIPTION(test) { + return test + .setRemoteDescription(test.pcRemote, test._local_offer, HAVE_REMOTE_OFFER) + .then(() => { + is( + test.pcRemote.signalingState, + HAVE_REMOTE_OFFER, + "signalingState after remote setRemoteDescription is 'have-remote-offer'" + ); + }); + }, + + function PC_REMOTE_CHECK_CAN_TRICKLE_SYNC(test) { + is( + test.pcRemote._pc.canTrickleIceCandidates, + true, + "Remote thinks that local can trickle" + ); + }, + + function PC_LOCAL_SANE_LOCAL_SDP(test) { + test.pcLocal.localRequiresTrickleIce = sdputils.verifySdp( + test._local_offer, + "offer", + test._offer_constraints, + test._offer_options, + test.testOptions + ); + }, + + function PC_REMOTE_SANE_REMOTE_SDP(test) { + test.pcRemote.remoteRequiresTrickleIce = sdputils.verifySdp( + test._local_offer, + "offer", + test._offer_constraints, + test._offer_options, + test.testOptions + ); + }, + + function PC_REMOTE_CREATE_ANSWER(test) { + return test.createAnswer(test.pcRemote).then(answer => { + is( + test.pcRemote.signalingState, + HAVE_REMOTE_OFFER, + "Remote createAnswer does not change signaling state" + ); + }); + }, + + function PC_REMOTE_SET_LOCAL_DESCRIPTION(test) { + return test + .setLocalDescription(test.pcRemote, test.originalAnswer, STABLE) + .then(() => { + is( + test.pcRemote.signalingState, + STABLE, + "signalingState after remote setLocalDescription is 'stable'" + ); + }); + }, + + function PC_LOCAL_GET_ANSWER(test) { + test._remote_answer = test.originalAnswer; + test._answer_constraints = test.pcRemote.constraints; + return Promise.resolve(); + }, + + function PC_LOCAL_SET_REMOTE_DESCRIPTION(test) { + return test + .setRemoteDescription(test.pcLocal, test._remote_answer, STABLE) + .then(() => { + is( + test.pcLocal.signalingState, + STABLE, + "signalingState after local setRemoteDescription is 'stable'" + ); + }); + }, + + function PC_REMOTE_SANE_LOCAL_SDP(test) { + test.pcRemote.localRequiresTrickleIce = sdputils.verifySdp( + test._remote_answer, + "answer", + test._offer_constraints, + test._offer_options, + test.testOptions + ); + }, + function PC_LOCAL_SANE_REMOTE_SDP(test) { + test.pcLocal.remoteRequiresTrickleIce = sdputils.verifySdp( + test._remote_answer, + "answer", + test._offer_constraints, + test._offer_options, + test.testOptions + ); + }, + + function PC_LOCAL_CHECK_CAN_TRICKLE_SYNC(test) { + is( + test.pcLocal._pc.canTrickleIceCandidates, + true, + "Local thinks that remote can trickle" + ); + }, + + function PC_LOCAL_WAIT_FOR_ICE_CONNECTED(test) { + return test.pcLocal.waitForIceConnected().then(() => { + info( + test.pcLocal + + ": ICE connection state log: " + + test.pcLocal.iceConnectionLog + ); + }); + }, + + function PC_REMOTE_WAIT_FOR_ICE_CONNECTED(test) { + return test.pcRemote.waitForIceConnected().then(() => { + info( + test.pcRemote + + ": ICE connection state log: " + + test.pcRemote.iceConnectionLog + ); + }); + }, + + function PC_LOCAL_VERIFY_ICE_GATHERING(test) { + return waitForAnIceCandidate(test.pcLocal); + }, + + function PC_REMOTE_VERIFY_ICE_GATHERING(test) { + return waitForAnIceCandidate(test.pcRemote); + }, + + function PC_LOCAL_WAIT_FOR_MEDIA_FLOW(test) { + return test.pcLocal.waitForMediaFlow(); + }, + + function PC_REMOTE_WAIT_FOR_MEDIA_FLOW(test) { + return test.pcRemote.waitForMediaFlow(); + }, + + function PC_LOCAL_CHECK_STATS(test) { + return test.pcLocal.getStats().then(stats => { + test.pcLocal.checkStats(stats); + }); + }, + + function PC_REMOTE_CHECK_STATS(test) { + return test.pcRemote.getStats().then(stats => { + test.pcRemote.checkStats(stats); + }); + }, + + function PC_LOCAL_CHECK_ICE_CONNECTION_TYPE(test) { + return test.pcLocal.getStats().then(stats => { + test.pcLocal.checkStatsIceConnectionType( + stats, + test.testOptions.expectedLocalCandidateType + ); + }); + }, + + function PC_REMOTE_CHECK_ICE_CONNECTION_TYPE(test) { + return test.pcRemote.getStats().then(stats => { + test.pcRemote.checkStatsIceConnectionType( + stats, + test.testOptions.expectedRemoteCandidateType + ); + }); + }, + + function PC_LOCAL_CHECK_ICE_CONNECTIONS(test) { + return test.pcLocal.getStats().then(stats => { + test.pcLocal.checkStatsIceConnections(stats, test.testOptions); + }); + }, + + function PC_REMOTE_CHECK_ICE_CONNECTIONS(test) { + return test.pcRemote.getStats().then(stats => { + test.pcRemote.checkStatsIceConnections(stats, test.testOptions); + }); + }, + + function PC_LOCAL_CHECK_MSID(test) { + return test.pcLocal.checkLocalMsids(); + }, + function PC_REMOTE_CHECK_MSID(test) { + return test.pcRemote.checkLocalMsids(); + }, + + function PC_LOCAL_CHECK_TRACK_STATS(test) { + return checkAllTrackStats(test.pcLocal); + }, + function PC_REMOTE_CHECK_TRACK_STATS(test) { + return checkAllTrackStats(test.pcRemote); + }, + function PC_LOCAL_VERIFY_SDP_AFTER_END_OF_TRICKLE(test) { + if (test.pcLocal.endOfTrickleSdp) { + /* In case the endOfTrickleSdp promise is resolved already it will win the + * race because it gets evaluated first. But if endOfTrickleSdp is still + * pending the rejection will win the race. */ + return Promise.race([ + test.pcLocal.endOfTrickleSdp, + Promise.reject("No SDP"), + ]).then( + sdp => + sdputils.checkSdpAfterEndOfTrickle( + sdp, + test.testOptions, + test.pcLocal.label + ), + () => + info( + "pcLocal: Gathering is not complete yet, skipping post-gathering SDP check" + ) + ); + } + }, + function PC_REMOTE_VERIFY_SDP_AFTER_END_OF_TRICKLE(test) { + if (test.pcRemote.endOfTrickleSdp) { + /* In case the endOfTrickleSdp promise is resolved already it will win the + * race because it gets evaluated first. But if endOfTrickleSdp is still + * pending the rejection will win the race. */ + return Promise.race([ + test.pcRemote.endOfTrickleSdp, + Promise.reject("No SDP"), + ]).then( + sdp => + sdputils.checkSdpAfterEndOfTrickle( + sdp, + test.testOptions, + test.pcRemote.label + ), + () => + info( + "pcRemote: Gathering is not complete yet, skipping post-gathering SDP check" + ) + ); + } + }, +]; + +function PC_LOCAL_REMOVE_ALL_BUT_H264_FROM_OFFER(test) { + isnot( + test.originalOffer.sdp.search("H264/90000"), + -1, + "H.264 should be present in the SDP offer" + ); + test.originalOffer.sdp = sdputils.removeCodec( + sdputils.removeCodec( + sdputils.removeCodec(test.originalOffer.sdp, 120), + 121, + 97 + ) + ); + info("Updated H264 only offer: " + JSON.stringify(test.originalOffer)); +} + +function PC_LOCAL_REMOVE_BUNDLE_FROM_OFFER(test) { + test.originalOffer.sdp = sdputils.removeBundle(test.originalOffer.sdp); + info("Updated no bundle offer: " + JSON.stringify(test.originalOffer)); +} + +function PC_LOCAL_REMOVE_RTCPMUX_FROM_OFFER(test) { + test.originalOffer.sdp = sdputils.removeRtcpMux(test.originalOffer.sdp); + info("Updated no RTCP-Mux offer: " + JSON.stringify(test.originalOffer)); +} + +function PC_LOCAL_REMOVE_SSRC_FROM_OFFER(test) { + test.originalOffer.sdp = sdputils.removeSSRCs(test.originalOffer.sdp); + info("Updated no SSRCs offer: " + JSON.stringify(test.originalOffer)); +} + +function PC_REMOTE_REMOVE_SSRC_FROM_ANSWER(test) { + test.originalAnswer.sdp = sdputils.removeSSRCs(test.originalAnswer.sdp); + info("Updated no SSRCs answer: " + JSON.stringify(test.originalAnswer)); +} + +var addRenegotiation = (chain, commands, checks) => { + chain.append(commands); + chain.append(commandsPeerConnectionOfferAnswer); + if (checks) { + chain.append(checks); + } +}; + +var addRenegotiationAnswerer = (chain, commands, checks) => { + chain.append(function SWAP_PC_LOCAL_PC_REMOTE(test) { + var temp = test.pcLocal; + test.pcLocal = test.pcRemote; + test.pcRemote = temp; + }); + addRenegotiation(chain, commands, checks); +}; -- cgit v1.2.3