зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1654430 - Update waitForRtpFlow() mochitest helper to use sender/receiver.getStats. r=ng
Differential Revision: https://phabricator.services.mozilla.com/D89082
This commit is contained in:
Родитель
fb585eddf0
Коммит
4c69b0ebaa
|
@ -1787,91 +1787,88 @@ PeerConnectionWrapper.prototype = {
|
|||
* @returns {Promise}
|
||||
* Returns a promise which yields a StatsReport object with RTP stats.
|
||||
*/
|
||||
async waitForRtpFlow(track) {
|
||||
info("waitForRtpFlow(" + track.id + ")");
|
||||
let hasFlow = (stats, retries) => {
|
||||
const dict = JSON.stringify([...stats.entries()]);
|
||||
info(
|
||||
`Checking for stats in ${dict} for ${track.kind} track ${track.id}` +
|
||||
`retry number ${retries}`
|
||||
);
|
||||
const rtp = [...stats.values()].find(({ type }) =>
|
||||
["inbound-rtp", "outbound-rtp"].includes(type)
|
||||
);
|
||||
if (!rtp) {
|
||||
return false;
|
||||
}
|
||||
info("Should have RTP stats for track " + track.id);
|
||||
info("RTP stats: " + JSON.stringify(rtp));
|
||||
let nrPackets =
|
||||
rtp[rtp.type == "outbound-rtp" ? "packetsSent" : "packetsReceived"];
|
||||
info(
|
||||
"Track " +
|
||||
track.id +
|
||||
" has " +
|
||||
nrPackets +
|
||||
" " +
|
||||
rtp.type +
|
||||
" RTP packets."
|
||||
);
|
||||
return nrPackets > 0;
|
||||
};
|
||||
async _waitForRtpFlow(target, rtpType) {
|
||||
const { track } = target;
|
||||
info(`_waitForRtpFlow(${track.id}, ${rtpType})`);
|
||||
const packets = `packets${rtpType == "outbound-rtp" ? "Sent" : "Received"}`;
|
||||
|
||||
// Time between stats checks
|
||||
const retryInterval = 500;
|
||||
// Timeout in ms
|
||||
const timeout = 30000;
|
||||
let retry = 0;
|
||||
// Check hasFlow at a reasonable interval
|
||||
for (let remaining = timeout; remaining >= 0; remaining -= retryInterval) {
|
||||
let stats = await this._pc.getStats(track);
|
||||
if (hasFlow(stats, retry++)) {
|
||||
ok(true, "RTP flowing for " + track.kind + " track " + track.id);
|
||||
return stats;
|
||||
const retryInterval = 500; // Time between stats checks
|
||||
const timeout = 30000; // Timeout in ms
|
||||
const retries = timeout / retryInterval;
|
||||
|
||||
for (let i = 0; i < retries; i++) {
|
||||
info(`Checking ${rtpType} for ${track.kind} track ${track.id} try ${i}`);
|
||||
for (const rtp of (await target.getStats()).values()) {
|
||||
if (rtp.type != rtpType) {
|
||||
continue;
|
||||
}
|
||||
if (rtp.kind != track.kind) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const numPackets = rtp[packets];
|
||||
info(`Track ${track.id} has ${numPackets} ${packets}.`);
|
||||
if (!numPackets) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ok(true, `RTP flowing for ${track.kind} track ${track.id}`);
|
||||
return;
|
||||
}
|
||||
await wait(retryInterval);
|
||||
}
|
||||
throw new Error(
|
||||
"Timeout checking for stats for track " +
|
||||
track.id +
|
||||
" after at least" +
|
||||
timeout +
|
||||
"ms"
|
||||
`Checking stats for track ${track.id} timed out after ${timeout} ms`
|
||||
);
|
||||
},
|
||||
|
||||
getExpectedActiveReceiveTracks() {
|
||||
/**
|
||||
* Wait for inbound RTP packet flow for the given MediaStreamTrack.
|
||||
*
|
||||
* @param {object} receiver
|
||||
* An RTCRtpReceiver to wait for data flow on.
|
||||
* @returns {Promise}
|
||||
* Returns a promise that resolves once data is flowing.
|
||||
*/
|
||||
async waitForInboundRtpFlow(receiver) {
|
||||
return this._waitForRtpFlow(receiver, "inbound-rtp");
|
||||
},
|
||||
|
||||
/**
|
||||
* Wait for outbound RTP packet flow for the given MediaStreamTrack.
|
||||
*
|
||||
* @param {object} sender
|
||||
* An RTCRtpSender to wait for data flow on.
|
||||
* @returns {Promise}
|
||||
* Returns a promise that resolves once data is flowing.
|
||||
*/
|
||||
async waitForOutboundRtpFlow(sender) {
|
||||
return this._waitForRtpFlow(sender, "outbound-rtp");
|
||||
},
|
||||
|
||||
getExpectedActiveReceivers() {
|
||||
return this._pc
|
||||
.getTransceivers()
|
||||
.filter(t => {
|
||||
return (
|
||||
.filter(
|
||||
t =>
|
||||
!t.stopped &&
|
||||
t.currentDirection &&
|
||||
t.currentDirection != "inactive" &&
|
||||
t.currentDirection != "sendonly"
|
||||
);
|
||||
})
|
||||
.map(t => {
|
||||
)
|
||||
.filter(({ receiver }) => receiver.track)
|
||||
.map(({ mid, currentDirection, receiver }) => {
|
||||
info(
|
||||
"Found transceiver that should be receiving RTP: mid=" +
|
||||
t.mid +
|
||||
" currentDirection=" +
|
||||
t.currentDirection +
|
||||
" kind=" +
|
||||
t.receiver.track.kind +
|
||||
" track-id=" +
|
||||
t.receiver.track.id
|
||||
`Found transceiver that should be receiving RTP: mid=${mid}` +
|
||||
` currentDirection=${currentDirection}` +
|
||||
` kind=${receiver.track.kind} track-id=${receiver.track.id}`
|
||||
);
|
||||
return t.receiver.track;
|
||||
})
|
||||
.filter(t => t);
|
||||
return receiver;
|
||||
});
|
||||
},
|
||||
|
||||
getExpectedSendTracks() {
|
||||
return this._pc
|
||||
.getSenders()
|
||||
.map(s => s.track)
|
||||
.filter(t => t);
|
||||
getExpectedSenders() {
|
||||
return this._pc.getSenders().filter(({ track }) => track);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1882,24 +1879,21 @@ PeerConnectionWrapper.prototype = {
|
|||
* A promise that resolves when media flows for all elements and tracks
|
||||
*/
|
||||
waitForMediaFlow() {
|
||||
return Promise.all(
|
||||
[].concat(
|
||||
this.localMediaElements.map(element =>
|
||||
this.waitForMediaElementFlow(element)
|
||||
),
|
||||
this.remoteMediaElements
|
||||
.filter(elem =>
|
||||
this.getExpectedActiveReceiveTracks().some(track =>
|
||||
elem.srcObject.getTracks().some(t => t == track)
|
||||
)
|
||||
const receivers = this.getExpectedActiveReceivers();
|
||||
return Promise.all([
|
||||
...this.localMediaElements.map(el => this.waitForMediaElementFlow(el)),
|
||||
...this.remoteMediaElements
|
||||
.filter(({ srcObject }) =>
|
||||
receivers.some(({ track }) =>
|
||||
srcObject.getTracks().some(t => t == track)
|
||||
)
|
||||
.map(elem => this.waitForMediaElementFlow(elem)),
|
||||
this.getExpectedActiveReceiveTracks().map(track =>
|
||||
this.waitForRtpFlow(track)
|
||||
),
|
||||
this.getExpectedSendTracks().map(track => this.waitForRtpFlow(track))
|
||||
)
|
||||
);
|
||||
)
|
||||
.map(el => this.waitForMediaElementFlow(el)),
|
||||
...receivers.map(receiver => this.waitForInboundRtpFlow(receiver)),
|
||||
...this.getExpectedSenders().map(sender =>
|
||||
this.waitForOutboundRtpFlow(sender)
|
||||
),
|
||||
]);
|
||||
},
|
||||
|
||||
async waitForSyncedRtcp() {
|
||||
|
|
|
@ -153,48 +153,43 @@ function waitForAnIceCandidate(pc) {
|
|||
});
|
||||
}
|
||||
|
||||
function checkTrackStats(pc, track, outbound) {
|
||||
var audio = track.kind == "audio";
|
||||
var msg =
|
||||
pc +
|
||||
" stats " +
|
||||
(outbound ? "outbound " : "inbound ") +
|
||||
(audio ? "audio" : "video") +
|
||||
" rtp track id " +
|
||||
track.id;
|
||||
return pc.getStats(track).then(stats => {
|
||||
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"
|
||||
);
|
||||
});
|
||||
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`
|
||||
);
|
||||
}
|
||||
|
||||
var checkAllTrackStats = pc => {
|
||||
return Promise.all(
|
||||
[].concat(
|
||||
pc
|
||||
.getExpectedActiveReceiveTracks()
|
||||
.map(track => checkTrackStats(pc, track, false)),
|
||||
pc.getExpectedSendTracks().map(track => checkTrackStats(pc, track, true))
|
||||
)
|
||||
);
|
||||
};
|
||||
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.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<!DOCTYPE HTML>
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<script type="application/javascript" src="pc.js"></script>
|
||||
|
@ -12,6 +12,7 @@
|
|||
});
|
||||
|
||||
runNetworkTest(function (options) {
|
||||
SimpleTest.requestCompleteLog();
|
||||
var test = new PeerConnectionTest(options);
|
||||
test.chain.replace("PC_LOCAL_GUM",
|
||||
[
|
||||
|
|
Загрузка…
Ссылка в новой задаче