mirror of
https://github.com/servo/servo.git
synced 2025-08-24 14:48:21 +01:00
Update web-platform-tests to revision b'7af9d6ec48ab04043a2bea85a3599904a1a19efa'
This commit is contained in:
parent
8050c95e31
commit
87be1008de
2742 changed files with 142451 additions and 40667 deletions
|
@ -16,15 +16,36 @@ function getLines(sdp, startsWith) {
|
|||
const getUfrags = ({sdp}) => getLines(sdp, "a=ice-ufrag:");
|
||||
const getPwds = ({sdp}) => getLines(sdp, "a=ice-pwd:");
|
||||
|
||||
async function exchangeOfferAnswerEndOnFirst(pc1, pc2) {
|
||||
await pc1.setLocalDescription(await pc1.createOffer());
|
||||
const negotiators = [
|
||||
{
|
||||
tag: "",
|
||||
async setOffer(pc) {
|
||||
await pc.setLocalDescription(await pc.createOffer());
|
||||
},
|
||||
async setAnswer(pc) {
|
||||
await pc.setLocalDescription(await pc.createAnswer());
|
||||
},
|
||||
},
|
||||
{
|
||||
tag: " (perfect negotiation)",
|
||||
async setOffer(pc) {
|
||||
await pc.setLocalDescription();
|
||||
},
|
||||
async setAnswer(pc) {
|
||||
await pc.setLocalDescription();
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
async function exchangeOfferAnswerEndOnFirst(pc1, pc2, negotiator) {
|
||||
await negotiator.setOffer(pc1);
|
||||
await pc2.setRemoteDescription(pc1.localDescription);
|
||||
await pc2.setLocalDescription(await pc2.createAnswer());
|
||||
await negotiator.setAnswer(pc2);
|
||||
await pc1.setRemoteDescription(pc2.localDescription); // End on pc1. No race
|
||||
}
|
||||
|
||||
async function exchangeOfferAnswerEndOnSecond(pc1, pc2) {
|
||||
await pc1.setLocalDescription(await pc1.createOffer());
|
||||
async function exchangeOfferAnswerEndOnSecond(pc1, pc2, negotiator) {
|
||||
await negotiator.setOffer(pc1);
|
||||
await pc2.setRemoteDescription(pc1.localDescription);
|
||||
await pc1.setRemoteDescription(await pc2.createAnswer());
|
||||
await pc2.setLocalDescription(pc1.remoteDescription); // End on pc2. No race
|
||||
|
@ -65,330 +86,404 @@ promise_test(async t => {
|
|||
await assertNoNegotiationNeeded(t, pc1);
|
||||
}, "restartIce() does not trigger negotiation ahead of initial negotiation");
|
||||
|
||||
promise_test(async t => {
|
||||
const pc1 = new RTCPeerConnection();
|
||||
const pc2 = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc1.close());
|
||||
t.add_cleanup(() => pc2.close());
|
||||
// Run remaining tests twice: once for each negotiator
|
||||
|
||||
pc1.addTransceiver("audio");
|
||||
await new Promise(r => pc1.onnegotiationneeded = r);
|
||||
pc1.restartIce();
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2);
|
||||
await assertNoNegotiationNeeded(t, pc1);
|
||||
}, "restartIce() has no effect on initial negotiation");
|
||||
for (const negotiator of negotiators) {
|
||||
const {tag} = negotiator;
|
||||
|
||||
promise_test(async t => {
|
||||
const pc1 = new RTCPeerConnection();
|
||||
const pc2 = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc1.close());
|
||||
t.add_cleanup(() => pc2.close());
|
||||
promise_test(async t => {
|
||||
const pc1 = new RTCPeerConnection();
|
||||
const pc2 = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc1.close());
|
||||
t.add_cleanup(() => pc2.close());
|
||||
|
||||
pc1.addTransceiver("audio");
|
||||
await new Promise(r => pc1.onnegotiationneeded = r);
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2);
|
||||
pc1.restartIce();
|
||||
await new Promise(r => pc1.onnegotiationneeded = r);
|
||||
}, "restartIce() fires negotiationneeded after initial negotiation");
|
||||
pc1.addTransceiver("audio");
|
||||
await new Promise(r => pc1.onnegotiationneeded = r);
|
||||
pc1.restartIce();
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2, negotiator);
|
||||
await assertNoNegotiationNeeded(t, pc1);
|
||||
}, `restartIce() has no effect on initial negotiation${tag}`);
|
||||
|
||||
promise_test(async t => {
|
||||
const pc1 = new RTCPeerConnection();
|
||||
const pc2 = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc1.close());
|
||||
t.add_cleanup(() => pc2.close());
|
||||
promise_test(async t => {
|
||||
const pc1 = new RTCPeerConnection();
|
||||
const pc2 = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc1.close());
|
||||
t.add_cleanup(() => pc2.close());
|
||||
|
||||
pc1.addTransceiver("audio");
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2);
|
||||
pc1.addTransceiver("audio");
|
||||
await new Promise(r => pc1.onnegotiationneeded = r);
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2, negotiator);
|
||||
pc1.restartIce();
|
||||
await new Promise(r => pc1.onnegotiationneeded = r);
|
||||
}, `restartIce() fires negotiationneeded after initial negotiation${tag}`);
|
||||
|
||||
const [oldUfrag1] = getUfrags(pc1.localDescription);
|
||||
const [oldUfrag2] = getUfrags(pc2.localDescription);
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2);
|
||||
assert_ufrags_equals(getUfrags(pc1.localDescription)[0], oldUfrag1, "control 1");
|
||||
assert_ufrags_equals(getUfrags(pc2.localDescription)[0], oldUfrag2, "control 2");
|
||||
promise_test(async t => {
|
||||
const pc1 = new RTCPeerConnection();
|
||||
const pc2 = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc1.close());
|
||||
t.add_cleanup(() => pc2.close());
|
||||
|
||||
pc1.restartIce();
|
||||
await new Promise(r => pc1.onnegotiationneeded = r);
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2);
|
||||
const [newUfrag1] = getUfrags(pc1.localDescription);
|
||||
const [newUfrag2] = getUfrags(pc2.localDescription);
|
||||
assert_ufrags_not_equals(newUfrag1, oldUfrag1, "ufrag 1 changed");
|
||||
assert_ufrags_not_equals(newUfrag1, oldUfrag2, "ufrag 2 changed");
|
||||
await assertNoNegotiationNeeded(t, pc1);
|
||||
pc1.addTransceiver("audio");
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2, negotiator);
|
||||
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2);
|
||||
assert_ufrags_equals(getUfrags(pc1.localDescription)[0], newUfrag1, "Unchanged 1");
|
||||
assert_ufrags_equals(getUfrags(pc2.localDescription)[0], newUfrag2, "Unchanged 2");
|
||||
}, "restartIce() causes fresh ufrags");
|
||||
const [oldUfrag1] = getUfrags(pc1.localDescription);
|
||||
const [oldUfrag2] = getUfrags(pc2.localDescription);
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2, negotiator);
|
||||
assert_ufrags_equals(getUfrags(pc1.localDescription)[0], oldUfrag1, "control 1");
|
||||
assert_ufrags_equals(getUfrags(pc2.localDescription)[0], oldUfrag2, "control 2");
|
||||
|
||||
promise_test(async t => {
|
||||
const pc1 = new RTCPeerConnection();
|
||||
const pc2 = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc1.close());
|
||||
t.add_cleanup(() => pc2.close());
|
||||
pc1.restartIce();
|
||||
await new Promise(r => pc1.onnegotiationneeded = r);
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2, negotiator);
|
||||
const [newUfrag1] = getUfrags(pc1.localDescription);
|
||||
const [newUfrag2] = getUfrags(pc2.localDescription);
|
||||
assert_ufrags_not_equals(newUfrag1, oldUfrag1, "ufrag 1 changed");
|
||||
assert_ufrags_not_equals(newUfrag1, oldUfrag2, "ufrag 2 changed");
|
||||
await assertNoNegotiationNeeded(t, pc1);
|
||||
|
||||
pc1.addTransceiver("audio");
|
||||
await new Promise(r => pc1.onnegotiationneeded = r);
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2);
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2, negotiator);
|
||||
assert_ufrags_equals(getUfrags(pc1.localDescription)[0], newUfrag1, "Unchanged 1");
|
||||
assert_ufrags_equals(getUfrags(pc2.localDescription)[0], newUfrag2, "Unchanged 2");
|
||||
}, `restartIce() causes fresh ufrags${tag}`);
|
||||
|
||||
const [oldUfrag1] = getUfrags(pc1.localDescription);
|
||||
const [oldUfrag2] = getUfrags(pc2.localDescription);
|
||||
promise_test(async t => {
|
||||
const config = {bundlePolicy: "max-bundle"};
|
||||
const pc1 = new RTCPeerConnection(config);
|
||||
const pc2 = new RTCPeerConnection(config);
|
||||
t.add_cleanup(() => pc1.close());
|
||||
t.add_cleanup(() => pc2.close());
|
||||
|
||||
await pc1.setLocalDescription(await pc1.createOffer());
|
||||
pc1.restartIce();
|
||||
await pc2.setRemoteDescription(pc1.localDescription);
|
||||
await pc2.setLocalDescription(await pc2.createAnswer());
|
||||
// Several tests in this file initializes the onnegotiationneeded listener
|
||||
// before the setLocalDescription() or setRemoteDescription() that we expect
|
||||
// to trigger negotiation needed. This allows Chrome to exercise these tests
|
||||
// without timing out due to a bug that causes onnegotiationneeded to fire too
|
||||
// early.
|
||||
// TODO(https://crbug.com/985797): Once Chrome does not fire ONN too early,
|
||||
// simply do "await new Promise(...)" instead of
|
||||
// "await negotiationNeededPromise" here and in other tests in this file.
|
||||
const negotiationNeededPromise =
|
||||
new Promise(r => pc1.onnegotiationneeded = r);
|
||||
await pc1.setRemoteDescription(pc2.localDescription);
|
||||
assert_ufrags_equals(getUfrags(pc1.localDescription)[0], oldUfrag1, "Unchanged 1");
|
||||
assert_ufrags_equals(getUfrags(pc2.localDescription)[0], oldUfrag2, "Unchanged 2");
|
||||
await negotiationNeededPromise;
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2);
|
||||
const [newUfrag1] = getUfrags(pc1.localDescription);
|
||||
const [newUfrag2] = getUfrags(pc2.localDescription);
|
||||
assert_ufrags_not_equals(newUfrag1, oldUfrag1, "ufrag 1 changed");
|
||||
assert_ufrags_not_equals(newUfrag1, oldUfrag2, "ufrag 2 changed");
|
||||
await assertNoNegotiationNeeded(t, pc1);
|
||||
}, "restartIce() works in have-local-offer");
|
||||
pc1.onicecandidate = e => {
|
||||
if (e.candidate) {
|
||||
pc2.addIceCandidate({
|
||||
candidate: e.candidate.candidate,
|
||||
sdpMid: e.candidate.sdpMid
|
||||
});
|
||||
}
|
||||
}
|
||||
pc2.onicecandidate = e => {
|
||||
if (e.candidate) {
|
||||
pc1.addIceCandidate({
|
||||
candidate: e.candidate.candidate,
|
||||
sdpMid: e.candidate.sdpMid
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
promise_test(async t => {
|
||||
const pc1 = new RTCPeerConnection();
|
||||
const pc2 = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc1.close());
|
||||
t.add_cleanup(() => pc2.close());
|
||||
// See the explanation below about Chrome's onnegotiationneeded firing
|
||||
// too early.
|
||||
const negotiationNeededPromise1 =
|
||||
new Promise(r => pc1.onnegotiationneeded = r);
|
||||
pc1.addTransceiver("video");
|
||||
pc1.addTransceiver("audio");
|
||||
await negotiationNeededPromise1;
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2, negotiator);
|
||||
|
||||
pc1.addTransceiver("audio");
|
||||
await new Promise(r => pc1.onnegotiationneeded = r);
|
||||
await pc1.setLocalDescription(await pc1.createOffer());
|
||||
pc1.restartIce();
|
||||
await pc2.setRemoteDescription(pc1.localDescription);
|
||||
await pc2.setLocalDescription(await pc2.createAnswer());
|
||||
const negotiationNeededPromise =
|
||||
new Promise(r => pc1.onnegotiationneeded = r);
|
||||
await pc1.setRemoteDescription(pc2.localDescription);
|
||||
const [oldUfrag1] = getUfrags(pc1.localDescription);
|
||||
const [oldUfrag2] = getUfrags(pc2.localDescription);
|
||||
await negotiationNeededPromise;
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2);
|
||||
const [newUfrag1] = getUfrags(pc1.localDescription);
|
||||
const [newUfrag2] = getUfrags(pc2.localDescription);
|
||||
assert_ufrags_not_equals(newUfrag1, oldUfrag1, "ufrag 1 changed");
|
||||
assert_ufrags_not_equals(newUfrag1, oldUfrag2, "ufrag 2 changed");
|
||||
await assertNoNegotiationNeeded(t, pc1);
|
||||
}, "restartIce() works in initial have-local-offer");
|
||||
const [videoTc, audioTc] = pc1.getTransceivers();
|
||||
const [videoTp, audioTp] =
|
||||
pc1.getTransceivers().map(tc => tc.sender.transport);
|
||||
assert_equals(pc1.getTransceivers().length, 2, 'transceiver count');
|
||||
|
||||
promise_test(async t => {
|
||||
const pc1 = new RTCPeerConnection();
|
||||
const pc2 = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc1.close());
|
||||
t.add_cleanup(() => pc2.close());
|
||||
// On Chrome, it is possible (likely, even) that videoTc.sender.transport.state
|
||||
// will be 'connected' by the time we get here. We'll race 2 promises here:
|
||||
// 1. Resolve after onstatechange is called with connected state.
|
||||
// 2. If already connected, resolve immediately.
|
||||
await Promise.race([
|
||||
new Promise(r => videoTc.sender.transport.onstatechange =
|
||||
() => videoTc.sender.transport.state == "connected" && r()),
|
||||
new Promise(r => videoTc.sender.transport.state == "connected" && r())
|
||||
]);
|
||||
assert_equals(videoTc.sender.transport.state, "connected");
|
||||
|
||||
pc1.addTransceiver("audio");
|
||||
await new Promise(r => pc1.onnegotiationneeded = r);
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2);
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2, negotiator);
|
||||
assert_equals(videoTp, pc1.getTransceivers()[0].sender.transport,
|
||||
'offer/answer retains dtls transport');
|
||||
assert_equals(audioTp, pc1.getTransceivers()[1].sender.transport,
|
||||
'offer/answer retains dtls transport');
|
||||
|
||||
const [oldUfrag1] = getUfrags(pc1.localDescription);
|
||||
const [oldUfrag2] = getUfrags(pc2.localDescription);
|
||||
const negotiationNeededPromise2 =
|
||||
new Promise(r => pc1.onnegotiationneeded = r);
|
||||
pc1.restartIce();
|
||||
await negotiationNeededPromise2;
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2, negotiator);
|
||||
|
||||
await pc2.setLocalDescription(await pc2.createOffer());
|
||||
await pc1.setRemoteDescription(pc2.localDescription);
|
||||
pc1.restartIce();
|
||||
await pc2.setRemoteDescription(await pc1.createAnswer());
|
||||
const negotiationNeededPromise =
|
||||
new Promise(r => pc1.onnegotiationneeded = r);
|
||||
await pc1.setLocalDescription(pc2.remoteDescription); // End on pc1. No race
|
||||
assert_ufrags_equals(getUfrags(pc1.localDescription)[0], oldUfrag1, "Unchanged 1");
|
||||
assert_ufrags_equals(getUfrags(pc2.localDescription)[0], oldUfrag2, "Unchanged 2");
|
||||
await negotiationNeededPromise;
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2);
|
||||
const [newUfrag1] = getUfrags(pc1.localDescription);
|
||||
const [newUfrag2] = getUfrags(pc2.localDescription);
|
||||
assert_ufrags_not_equals(newUfrag1, oldUfrag1, "ufrag 1 changed");
|
||||
assert_ufrags_not_equals(newUfrag1, oldUfrag2, "ufrag 2 changed");
|
||||
await assertNoNegotiationNeeded(t, pc1);
|
||||
}, "restartIce() works in have-remote-offer");
|
||||
const [newVideoTp, newAudioTp] =
|
||||
pc1.getTransceivers().map(tc => tc.sender.transport);
|
||||
assert_equals(videoTp, newVideoTp, 'ice restart retains dtls transport');
|
||||
assert_equals(audioTp, newAudioTp, 'ice restart retains dtls transport');
|
||||
}, `restartIce() retains dtls transports${tag}`);
|
||||
|
||||
promise_test(async t => {
|
||||
const pc1 = new RTCPeerConnection();
|
||||
const pc2 = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc1.close());
|
||||
t.add_cleanup(() => pc2.close());
|
||||
promise_test(async t => {
|
||||
const pc1 = new RTCPeerConnection();
|
||||
const pc2 = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc1.close());
|
||||
t.add_cleanup(() => pc2.close());
|
||||
|
||||
pc2.addTransceiver("audio");
|
||||
await pc2.setLocalDescription(await pc2.createOffer());
|
||||
await pc1.setRemoteDescription(pc2.localDescription);
|
||||
pc1.restartIce();
|
||||
await pc2.setRemoteDescription(await pc1.createAnswer());
|
||||
await pc1.setLocalDescription(pc2.remoteDescription); // End on pc1. No race
|
||||
await assertNoNegotiationNeeded(t, pc1);
|
||||
}, "restartIce() does nothing in initial have-remote-offer");
|
||||
pc1.addTransceiver("audio");
|
||||
await new Promise(r => pc1.onnegotiationneeded = r);
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2, negotiator);
|
||||
|
||||
promise_test(async t => {
|
||||
const pc1 = new RTCPeerConnection();
|
||||
const pc2 = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc1.close());
|
||||
t.add_cleanup(() => pc2.close());
|
||||
const [oldUfrag1] = getUfrags(pc1.localDescription);
|
||||
const [oldUfrag2] = getUfrags(pc2.localDescription);
|
||||
|
||||
pc1.addTransceiver("audio");
|
||||
await new Promise(r => pc1.onnegotiationneeded = r);
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2);
|
||||
await negotiator.setOffer(pc1);
|
||||
pc1.restartIce();
|
||||
await pc2.setRemoteDescription(pc1.localDescription);
|
||||
await negotiator.setAnswer(pc2);
|
||||
// Several tests in this file initializes the onnegotiationneeded listener
|
||||
// before the setLocalDescription() or setRemoteDescription() that we expect
|
||||
// to trigger negotiation needed. This allows Chrome to exercise these tests
|
||||
// without timing out due to a bug that causes onnegotiationneeded to fire too
|
||||
// early.
|
||||
// TODO(https://crbug.com/985797): Once Chrome does not fire ONN too early,
|
||||
// simply do "await new Promise(...)" instead of
|
||||
// "await negotiationNeededPromise" here and in other tests in this file.
|
||||
const negotiationNeededPromise =
|
||||
new Promise(r => pc1.onnegotiationneeded = r);
|
||||
await pc1.setRemoteDescription(pc2.localDescription);
|
||||
assert_ufrags_equals(getUfrags(pc1.localDescription)[0], oldUfrag1, "Unchanged 1");
|
||||
assert_ufrags_equals(getUfrags(pc2.localDescription)[0], oldUfrag2, "Unchanged 2");
|
||||
await negotiationNeededPromise;
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2, negotiator);
|
||||
const [newUfrag1] = getUfrags(pc1.localDescription);
|
||||
const [newUfrag2] = getUfrags(pc2.localDescription);
|
||||
assert_ufrags_not_equals(newUfrag1, oldUfrag1, "ufrag 1 changed");
|
||||
assert_ufrags_not_equals(newUfrag1, oldUfrag2, "ufrag 2 changed");
|
||||
await assertNoNegotiationNeeded(t, pc1);
|
||||
}, `restartIce() works in have-local-offer${tag}`);
|
||||
|
||||
const [oldUfrag1] = getUfrags(pc1.localDescription);
|
||||
const [oldUfrag2] = getUfrags(pc2.localDescription);
|
||||
promise_test(async t => {
|
||||
const pc1 = new RTCPeerConnection();
|
||||
const pc2 = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc1.close());
|
||||
t.add_cleanup(() => pc2.close());
|
||||
|
||||
pc1.restartIce();
|
||||
await new Promise(r => pc1.onnegotiationneeded = r);
|
||||
const negotiationNeededPromise =
|
||||
new Promise(r => pc1.onnegotiationneeded = r);
|
||||
await exchangeOfferAnswerEndOnSecond(pc2, pc1);
|
||||
assert_ufrags_equals(getUfrags(pc1.localDescription)[0], oldUfrag1, "nothing yet 1");
|
||||
assert_ufrags_equals(getUfrags(pc2.localDescription)[0], oldUfrag2, "nothing yet 2");
|
||||
await negotiationNeededPromise;
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2);
|
||||
const [newUfrag1] = getUfrags(pc1.localDescription);
|
||||
const [newUfrag2] = getUfrags(pc2.localDescription);
|
||||
assert_ufrags_not_equals(newUfrag1, oldUfrag1, "ufrag 1 changed");
|
||||
assert_ufrags_not_equals(newUfrag2, oldUfrag2, "ufrag 2 changed");
|
||||
await assertNoNegotiationNeeded(t, pc1);
|
||||
}, "restartIce() survives remote offer");
|
||||
pc1.addTransceiver("audio");
|
||||
await new Promise(r => pc1.onnegotiationneeded = r);
|
||||
await negotiator.setOffer(pc1);
|
||||
pc1.restartIce();
|
||||
await pc2.setRemoteDescription(pc1.localDescription);
|
||||
await negotiator.setAnswer(pc2);
|
||||
const negotiationNeededPromise =
|
||||
new Promise(r => pc1.onnegotiationneeded = r);
|
||||
await pc1.setRemoteDescription(pc2.localDescription);
|
||||
const [oldUfrag1] = getUfrags(pc1.localDescription);
|
||||
const [oldUfrag2] = getUfrags(pc2.localDescription);
|
||||
await negotiationNeededPromise;
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2, negotiator);
|
||||
const [newUfrag1] = getUfrags(pc1.localDescription);
|
||||
const [newUfrag2] = getUfrags(pc2.localDescription);
|
||||
assert_ufrags_not_equals(newUfrag1, oldUfrag1, "ufrag 1 changed");
|
||||
assert_ufrags_not_equals(newUfrag1, oldUfrag2, "ufrag 2 changed");
|
||||
await assertNoNegotiationNeeded(t, pc1);
|
||||
}, `restartIce() works in initial have-local-offer${tag}`);
|
||||
|
||||
promise_test(async t => {
|
||||
const pc1 = new RTCPeerConnection();
|
||||
const pc2 = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc1.close());
|
||||
t.add_cleanup(() => pc2.close());
|
||||
promise_test(async t => {
|
||||
const pc1 = new RTCPeerConnection();
|
||||
const pc2 = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc1.close());
|
||||
t.add_cleanup(() => pc2.close());
|
||||
|
||||
pc1.addTransceiver("audio");
|
||||
await new Promise(r => pc1.onnegotiationneeded = r);
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2);
|
||||
pc1.addTransceiver("audio");
|
||||
await new Promise(r => pc1.onnegotiationneeded = r);
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2, negotiator);
|
||||
|
||||
const [oldUfrag1] = getUfrags(pc1.localDescription);
|
||||
const [oldUfrag2] = getUfrags(pc2.localDescription);
|
||||
const [oldUfrag1] = getUfrags(pc1.localDescription);
|
||||
const [oldUfrag2] = getUfrags(pc2.localDescription);
|
||||
|
||||
pc1.restartIce();
|
||||
pc2.restartIce();
|
||||
await new Promise(r => pc1.onnegotiationneeded = r);
|
||||
await exchangeOfferAnswerEndOnSecond(pc2, pc1);
|
||||
const [newUfrag1] = getUfrags(pc1.localDescription);
|
||||
const [newUfrag2] = getUfrags(pc2.localDescription);
|
||||
assert_ufrags_not_equals(newUfrag1, oldUfrag1, "ufrag 1 changed");
|
||||
assert_ufrags_not_equals(newUfrag1, oldUfrag2, "ufrag 2 changed");
|
||||
await assertNoNegotiationNeeded(t, pc1);
|
||||
await negotiator.setOffer(pc2);
|
||||
await pc1.setRemoteDescription(pc2.localDescription);
|
||||
pc1.restartIce();
|
||||
await pc2.setRemoteDescription(await pc1.createAnswer());
|
||||
const negotiationNeededPromise =
|
||||
new Promise(r => pc1.onnegotiationneeded = r);
|
||||
await pc1.setLocalDescription(pc2.remoteDescription); // End on pc1. No race
|
||||
assert_ufrags_equals(getUfrags(pc1.localDescription)[0], oldUfrag1, "Unchanged 1");
|
||||
assert_ufrags_equals(getUfrags(pc2.localDescription)[0], oldUfrag2, "Unchanged 2");
|
||||
await negotiationNeededPromise;
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2, negotiator);
|
||||
const [newUfrag1] = getUfrags(pc1.localDescription);
|
||||
const [newUfrag2] = getUfrags(pc2.localDescription);
|
||||
assert_ufrags_not_equals(newUfrag1, oldUfrag1, "ufrag 1 changed");
|
||||
assert_ufrags_not_equals(newUfrag1, oldUfrag2, "ufrag 2 changed");
|
||||
await assertNoNegotiationNeeded(t, pc1);
|
||||
}, `restartIce() works in have-remote-offer${tag}`);
|
||||
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2);
|
||||
assert_ufrags_equals(getUfrags(pc1.localDescription)[0], newUfrag1, "Unchanged 1");
|
||||
assert_ufrags_equals(getUfrags(pc2.localDescription)[0], newUfrag2, "Unchanged 2");
|
||||
await assertNoNegotiationNeeded(t, pc1);
|
||||
}, "restartIce() is satisfied by remote ICE restart");
|
||||
promise_test(async t => {
|
||||
const pc1 = new RTCPeerConnection();
|
||||
const pc2 = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc1.close());
|
||||
t.add_cleanup(() => pc2.close());
|
||||
|
||||
promise_test(async t => {
|
||||
const pc1 = new RTCPeerConnection();
|
||||
const pc2 = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc1.close());
|
||||
t.add_cleanup(() => pc2.close());
|
||||
pc2.addTransceiver("audio");
|
||||
await negotiator.setOffer(pc2);
|
||||
await pc1.setRemoteDescription(pc2.localDescription);
|
||||
pc1.restartIce();
|
||||
await pc2.setRemoteDescription(await pc1.createAnswer());
|
||||
await pc1.setLocalDescription(pc2.remoteDescription); // End on pc1. No race
|
||||
await assertNoNegotiationNeeded(t, pc1);
|
||||
}, `restartIce() does nothing in initial have-remote-offer${tag}`);
|
||||
|
||||
pc1.addTransceiver("audio");
|
||||
await new Promise(r => pc1.onnegotiationneeded = r);
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2);
|
||||
promise_test(async t => {
|
||||
const pc1 = new RTCPeerConnection();
|
||||
const pc2 = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc1.close());
|
||||
t.add_cleanup(() => pc2.close());
|
||||
|
||||
const [oldUfrag1] = getUfrags(pc1.localDescription);
|
||||
const [oldUfrag2] = getUfrags(pc2.localDescription);
|
||||
pc1.addTransceiver("audio");
|
||||
await new Promise(r => pc1.onnegotiationneeded = r);
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2, negotiator);
|
||||
|
||||
pc1.restartIce();
|
||||
await new Promise(r => pc1.onnegotiationneeded = r);
|
||||
await pc1.setLocalDescription(await pc1.createOffer({iceRestart: false}));
|
||||
await pc2.setRemoteDescription(pc1.localDescription);
|
||||
await pc2.setLocalDescription(await pc2.createAnswer());
|
||||
await pc1.setRemoteDescription(pc2.localDescription);
|
||||
const [newUfrag1] = getUfrags(pc1.localDescription);
|
||||
const [newUfrag2] = getUfrags(pc2.localDescription);
|
||||
assert_ufrags_not_equals(newUfrag1, oldUfrag1, "ufrag 1 changed");
|
||||
assert_ufrags_not_equals(newUfrag1, oldUfrag2, "ufrag 2 changed");
|
||||
await assertNoNegotiationNeeded(t, pc1);
|
||||
}, "restartIce() trumps {iceRestart: false}");
|
||||
const [oldUfrag1] = getUfrags(pc1.localDescription);
|
||||
const [oldUfrag2] = getUfrags(pc2.localDescription);
|
||||
|
||||
promise_test(async t => {
|
||||
const pc1 = new RTCPeerConnection();
|
||||
const pc2 = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc1.close());
|
||||
t.add_cleanup(() => pc2.close());
|
||||
pc1.restartIce();
|
||||
await new Promise(r => pc1.onnegotiationneeded = r);
|
||||
const negotiationNeededPromise =
|
||||
new Promise(r => pc1.onnegotiationneeded = r);
|
||||
await exchangeOfferAnswerEndOnSecond(pc2, pc1, negotiator);
|
||||
assert_ufrags_equals(getUfrags(pc1.localDescription)[0], oldUfrag1, "nothing yet 1");
|
||||
assert_ufrags_equals(getUfrags(pc2.localDescription)[0], oldUfrag2, "nothing yet 2");
|
||||
await negotiationNeededPromise;
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2, negotiator);
|
||||
const [newUfrag1] = getUfrags(pc1.localDescription);
|
||||
const [newUfrag2] = getUfrags(pc2.localDescription);
|
||||
assert_ufrags_not_equals(newUfrag1, oldUfrag1, "ufrag 1 changed");
|
||||
assert_ufrags_not_equals(newUfrag2, oldUfrag2, "ufrag 2 changed");
|
||||
await assertNoNegotiationNeeded(t, pc1);
|
||||
}, `restartIce() survives remote offer${tag}`);
|
||||
|
||||
pc1.addTransceiver("audio");
|
||||
await new Promise(r => pc1.onnegotiationneeded = r);
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2);
|
||||
promise_test(async t => {
|
||||
const pc1 = new RTCPeerConnection();
|
||||
const pc2 = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc1.close());
|
||||
t.add_cleanup(() => pc2.close());
|
||||
|
||||
const [oldUfrag1] = getUfrags(pc1.localDescription);
|
||||
const [oldUfrag2] = getUfrags(pc2.localDescription);
|
||||
pc1.addTransceiver("audio");
|
||||
await new Promise(r => pc1.onnegotiationneeded = r);
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2, negotiator);
|
||||
|
||||
pc1.restartIce();
|
||||
await new Promise(r => pc1.onnegotiationneeded = r);
|
||||
await pc1.setLocalDescription(await pc1.createOffer());
|
||||
const negotiationNeededPromise =
|
||||
new Promise(r => pc1.onnegotiationneeded = r);
|
||||
await pc1.setLocalDescription({type: "rollback"});
|
||||
await negotiationNeededPromise;
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2);
|
||||
const [newUfrag1] = getUfrags(pc1.localDescription);
|
||||
const [newUfrag2] = getUfrags(pc2.localDescription);
|
||||
assert_ufrags_not_equals(newUfrag1, oldUfrag1, "ufrag 1 changed");
|
||||
assert_ufrags_not_equals(newUfrag1, oldUfrag2, "ufrag 2 changed");
|
||||
await assertNoNegotiationNeeded(t, pc1);
|
||||
}, "restartIce() survives rollback");
|
||||
const [oldUfrag1] = getUfrags(pc1.localDescription);
|
||||
const [oldUfrag2] = getUfrags(pc2.localDescription);
|
||||
|
||||
promise_test(async t => {
|
||||
const pc1 = new RTCPeerConnection({bundlePolicy: "max-compat"});
|
||||
const pc2 = new RTCPeerConnection({bundlePolicy: "max-compat"});
|
||||
t.add_cleanup(() => pc1.close());
|
||||
t.add_cleanup(() => pc2.close());
|
||||
pc1.restartIce();
|
||||
pc2.restartIce();
|
||||
await new Promise(r => pc1.onnegotiationneeded = r);
|
||||
await exchangeOfferAnswerEndOnSecond(pc2, pc1, negotiator);
|
||||
const [newUfrag1] = getUfrags(pc1.localDescription);
|
||||
const [newUfrag2] = getUfrags(pc2.localDescription);
|
||||
assert_ufrags_not_equals(newUfrag1, oldUfrag1, "ufrag 1 changed");
|
||||
assert_ufrags_not_equals(newUfrag1, oldUfrag2, "ufrag 2 changed");
|
||||
await assertNoNegotiationNeeded(t, pc1);
|
||||
|
||||
pc1.addTransceiver("audio");
|
||||
pc1.addTransceiver("video");
|
||||
await new Promise(r => pc1.onnegotiationneeded = r);
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2);
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2, negotiator);
|
||||
assert_ufrags_equals(getUfrags(pc1.localDescription)[0], newUfrag1, "Unchanged 1");
|
||||
assert_ufrags_equals(getUfrags(pc2.localDescription)[0], newUfrag2, "Unchanged 2");
|
||||
await assertNoNegotiationNeeded(t, pc1);
|
||||
}, `restartIce() is satisfied by remote ICE restart${tag}`);
|
||||
|
||||
const oldUfrags1 = getUfrags(pc1.localDescription);
|
||||
const oldUfrags2 = getUfrags(pc2.localDescription);
|
||||
const oldPwds2 = getPwds(pc2.localDescription);
|
||||
promise_test(async t => {
|
||||
const pc1 = new RTCPeerConnection();
|
||||
const pc2 = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc1.close());
|
||||
t.add_cleanup(() => pc2.close());
|
||||
|
||||
pc1.restartIce();
|
||||
await new Promise(r => pc1.onnegotiationneeded = r);
|
||||
pc1.addTransceiver("audio");
|
||||
await new Promise(r => pc1.onnegotiationneeded = r);
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2, negotiator);
|
||||
|
||||
// Engineer a partial ICE restart from pc2
|
||||
pc2.restartIce();
|
||||
await pc2.setLocalDescription(await pc2.createOffer());
|
||||
{
|
||||
let {type, sdp} = pc2.localDescription;
|
||||
// Restore both old ice-ufrag and old ice-pwd to trigger a partial restart
|
||||
sdp = sdp.replace(getUfrags({sdp})[0], oldUfrags2[0]);
|
||||
sdp = sdp.replace(getPwds({sdp})[0], oldPwds2[0]);
|
||||
const newUfrags2 = getUfrags({sdp});
|
||||
const newPwds2 = getPwds({sdp});
|
||||
assert_ufrags_equals(newUfrags2[0], oldUfrags2[0], "control ufrag match");
|
||||
assert_ufrags_equals(newPwds2[0], oldPwds2[0], "control pwd match");
|
||||
assert_ufrags_not_equals(newUfrags2[1], oldUfrags2[1], "control ufrag non-match");
|
||||
assert_ufrags_not_equals(newPwds2[1], oldPwds2[1], "control pwd non-match");
|
||||
await pc1.setRemoteDescription({type, sdp});
|
||||
}
|
||||
const negotiationNeededPromise =
|
||||
new Promise(r => pc1.onnegotiationneeded = r);
|
||||
await pc1.setLocalDescription(await pc1.createAnswer());
|
||||
const newUfrags1 = getUfrags(pc1.localDescription);
|
||||
assert_ufrags_equals(newUfrags1[0], oldUfrags1[0], "Unchanged 1");
|
||||
assert_ufrags_not_equals(newUfrags1[1], oldUfrags1[1], "Restarted 2");
|
||||
await negotiationNeededPromise;
|
||||
await pc1.setLocalDescription(await pc1.createOffer());
|
||||
const newestUfrags1 = getUfrags(pc1.localDescription);
|
||||
assert_ufrags_not_equals(newestUfrags1[0], oldUfrags1[0], "Restarted 1");
|
||||
assert_ufrags_not_equals(newestUfrags1[1], oldUfrags1[1], "Restarted 2");
|
||||
await assertNoNegotiationNeeded(t, pc1);
|
||||
}, "restartIce() survives remote offer containing partial restart");
|
||||
const [oldUfrag1] = getUfrags(pc1.localDescription);
|
||||
const [oldUfrag2] = getUfrags(pc2.localDescription);
|
||||
|
||||
pc1.restartIce();
|
||||
await new Promise(r => pc1.onnegotiationneeded = r);
|
||||
await pc1.setLocalDescription(await pc1.createOffer({iceRestart: false}));
|
||||
await pc2.setRemoteDescription(pc1.localDescription);
|
||||
await negotiator.setAnswer(pc2);
|
||||
await pc1.setRemoteDescription(pc2.localDescription);
|
||||
const [newUfrag1] = getUfrags(pc1.localDescription);
|
||||
const [newUfrag2] = getUfrags(pc2.localDescription);
|
||||
assert_ufrags_not_equals(newUfrag1, oldUfrag1, "ufrag 1 changed");
|
||||
assert_ufrags_not_equals(newUfrag1, oldUfrag2, "ufrag 2 changed");
|
||||
await assertNoNegotiationNeeded(t, pc1);
|
||||
}, `restartIce() trumps {iceRestart: false}${tag}`);
|
||||
|
||||
promise_test(async t => {
|
||||
const pc1 = new RTCPeerConnection();
|
||||
const pc2 = new RTCPeerConnection();
|
||||
t.add_cleanup(() => pc1.close());
|
||||
t.add_cleanup(() => pc2.close());
|
||||
|
||||
pc1.addTransceiver("audio");
|
||||
await new Promise(r => pc1.onnegotiationneeded = r);
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2, negotiator);
|
||||
|
||||
const [oldUfrag1] = getUfrags(pc1.localDescription);
|
||||
const [oldUfrag2] = getUfrags(pc2.localDescription);
|
||||
|
||||
pc1.restartIce();
|
||||
await new Promise(r => pc1.onnegotiationneeded = r);
|
||||
await negotiator.setOffer(pc1);
|
||||
const negotiationNeededPromise =
|
||||
new Promise(r => pc1.onnegotiationneeded = r);
|
||||
await pc1.setLocalDescription({type: "rollback"});
|
||||
await negotiationNeededPromise;
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2, negotiator);
|
||||
const [newUfrag1] = getUfrags(pc1.localDescription);
|
||||
const [newUfrag2] = getUfrags(pc2.localDescription);
|
||||
assert_ufrags_not_equals(newUfrag1, oldUfrag1, "ufrag 1 changed");
|
||||
assert_ufrags_not_equals(newUfrag1, oldUfrag2, "ufrag 2 changed");
|
||||
await assertNoNegotiationNeeded(t, pc1);
|
||||
}, `restartIce() survives rollback${tag}`);
|
||||
|
||||
promise_test(async t => {
|
||||
const pc1 = new RTCPeerConnection({bundlePolicy: "max-compat"});
|
||||
const pc2 = new RTCPeerConnection({bundlePolicy: "max-compat"});
|
||||
t.add_cleanup(() => pc1.close());
|
||||
t.add_cleanup(() => pc2.close());
|
||||
|
||||
pc1.addTransceiver("audio");
|
||||
pc1.addTransceiver("video");
|
||||
await new Promise(r => pc1.onnegotiationneeded = r);
|
||||
await exchangeOfferAnswerEndOnFirst(pc1, pc2, negotiator);
|
||||
|
||||
const oldUfrags1 = getUfrags(pc1.localDescription);
|
||||
const oldUfrags2 = getUfrags(pc2.localDescription);
|
||||
const oldPwds2 = getPwds(pc2.localDescription);
|
||||
|
||||
pc1.restartIce();
|
||||
await new Promise(r => pc1.onnegotiationneeded = r);
|
||||
|
||||
// Engineer a partial ICE restart from pc2
|
||||
pc2.restartIce();
|
||||
await negotiator.setOffer(pc2);
|
||||
{
|
||||
let {type, sdp} = pc2.localDescription;
|
||||
// Restore both old ice-ufrag and old ice-pwd to trigger a partial restart
|
||||
sdp = sdp.replace(getUfrags({sdp})[0], oldUfrags2[0]);
|
||||
sdp = sdp.replace(getPwds({sdp})[0], oldPwds2[0]);
|
||||
const newUfrags2 = getUfrags({sdp});
|
||||
const newPwds2 = getPwds({sdp});
|
||||
assert_ufrags_equals(newUfrags2[0], oldUfrags2[0], "control ufrag match");
|
||||
assert_ufrags_equals(newPwds2[0], oldPwds2[0], "control pwd match");
|
||||
assert_ufrags_not_equals(newUfrags2[1], oldUfrags2[1], "control ufrag non-match");
|
||||
assert_ufrags_not_equals(newPwds2[1], oldPwds2[1], "control pwd non-match");
|
||||
await pc1.setRemoteDescription({type, sdp});
|
||||
}
|
||||
const negotiationNeededPromise =
|
||||
new Promise(r => pc1.onnegotiationneeded = r);
|
||||
await negotiator.setAnswer(pc1);
|
||||
const newUfrags1 = getUfrags(pc1.localDescription);
|
||||
assert_ufrags_equals(newUfrags1[0], oldUfrags1[0], "Unchanged 1");
|
||||
assert_ufrags_not_equals(newUfrags1[1], oldUfrags1[1], "Restarted 2");
|
||||
await negotiationNeededPromise;
|
||||
await negotiator.setOffer(pc1);
|
||||
const newestUfrags1 = getUfrags(pc1.localDescription);
|
||||
assert_ufrags_not_equals(newestUfrags1[0], oldUfrags1[0], "Restarted 1");
|
||||
assert_ufrags_not_equals(newestUfrags1[1], oldUfrags1[1], "Restarted 2");
|
||||
await assertNoNegotiationNeeded(t, pc1);
|
||||
}, `restartIce() survives remote offer containing partial restart${tag}`);
|
||||
|
||||
}
|
||||
|
||||
</script>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue