Skip to content

Commit a1b9ae9

Browse files
committed
test: stabilize ice restart candidate exchange
1 parent f238113 commit a1b9ae9

1 file changed

Lines changed: 46 additions & 6 deletions

File tree

test/basic.test.js

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,14 +79,47 @@ function collectMessages(channel, count, timeout = 10000) {
7979
});
8080
}
8181

82+
async function addIceCandidateBestEffort(peerConnection, candidate) {
83+
try {
84+
await peerConnection.addIceCandidate(candidate);
85+
} catch {
86+
// ICE restart can leave older gathered candidates in flight. Unit helpers
87+
// mirror browser-style candidate exchange and keep those races non-fatal.
88+
}
89+
}
90+
91+
function exchangeIceCandidates(offerer, answerer) {
92+
offerer.addEventListener("icecandidate", (event) => {
93+
if (event.candidate && answerer.signalingState !== "closed") {
94+
addIceCandidateBestEffort(answerer, event.candidate);
95+
}
96+
});
97+
98+
answerer.addEventListener("icecandidate", (event) => {
99+
if (event.candidate && offerer.signalingState !== "closed") {
100+
addIceCandidateBestEffort(offerer, event.candidate);
101+
}
102+
});
103+
}
104+
105+
async function exchangeSessionDescriptions(offerer, answerer) {
106+
const offer = await offerer.createOffer();
107+
await offerer.setLocalDescription(offer);
108+
await answerer.setRemoteDescription(offerer.localDescription);
109+
110+
const answer = await answerer.createAnswer();
111+
await answerer.setLocalDescription(answer);
112+
await offerer.setRemoteDescription(answerer.localDescription);
113+
}
114+
82115
async function exchangeOfferAnswer(offerer, answerer) {
83116
const offererCandidates = [];
84117
const answererCandidates = [];
85118

86119
offerer.onicecandidate = (event) => {
87120
if (!event.candidate) return;
88121
if (answerer.remoteDescription) {
89-
answerer.addIceCandidate(event.candidate);
122+
addIceCandidateBestEffort(answerer, event.candidate);
90123
} else {
91124
offererCandidates.push(event.candidate);
92125
}
@@ -95,7 +128,7 @@ async function exchangeOfferAnswer(offerer, answerer) {
95128
answerer.onicecandidate = (event) => {
96129
if (!event.candidate) return;
97130
if (offerer.remoteDescription) {
98-
offerer.addIceCandidate(event.candidate);
131+
addIceCandidateBestEffort(offerer, event.candidate);
99132
} else {
100133
answererCandidates.push(event.candidate);
101134
}
@@ -104,12 +137,16 @@ async function exchangeOfferAnswer(offerer, answerer) {
104137
const offer = await offerer.createOffer();
105138
await offerer.setLocalDescription(offer);
106139
await answerer.setRemoteDescription(offerer.localDescription);
107-
for (const candidate of offererCandidates.splice(0)) await answerer.addIceCandidate(candidate);
140+
for (const candidate of offererCandidates.splice(0)) {
141+
await addIceCandidateBestEffort(answerer, candidate);
142+
}
108143

109144
const answer = await answerer.createAnswer();
110145
await answerer.setLocalDescription(answer);
111146
await offerer.setRemoteDescription(answerer.localDescription);
112-
for (const candidate of answererCandidates.splice(0)) await offerer.addIceCandidate(candidate);
147+
for (const candidate of answererCandidates.splice(0)) {
148+
await addIceCandidateBestEffort(offerer, candidate);
149+
}
113150
}
114151

115152
function closeAll(...peers) {
@@ -293,14 +330,17 @@ test("restartIce renegotiates without closing data channels", async (t) => {
293330
t.after(() => closeAllAndWait(offerer, answerer));
294331
const local = offerer.createDataChannel("restart");
295332
const remotePromise = waitFor(answerer, "datachannel");
333+
exchangeIceCandidates(offerer, answerer);
296334

297-
await exchangeOfferAnswer(offerer, answerer);
335+
await exchangeSessionDescriptions(offerer, answerer);
298336
const remote = (await remotePromise).channel;
299337
await waitForOpen(local);
300338
await waitForOpen(remote);
301339

302340
offerer.restartIce();
303-
await exchangeOfferAnswer(offerer, answerer);
341+
await exchangeSessionDescriptions(offerer, answerer);
342+
await waitForOpen(local);
343+
await waitForOpen(remote);
304344

305345
const messagePromise = waitFor(remote, "message");
306346
local.send("after-restart");

0 commit comments

Comments
 (0)