mirror of https://github.com/OpenVidu/openvidu.git
openvidu-test-e2e: ICE candidate type tests read subscriptions and connection quality from livekit-client state
parent
2320998bfe
commit
d2b97f05f1
|
|
@ -1615,11 +1615,7 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
|
||||||
Assertions.assertTrue(assertAllElementsHaveTracks(punchbagUser, "audio.remote", true, false),
|
Assertions.assertTrue(assertAllElementsHaveTracks(punchbagUser, "audio.remote", true, false),
|
||||||
"PunchbagUser's HTMLAudioElements were expected to have only one audio track");
|
"PunchbagUser's HTMLAudioElements were expected to have only one audio track");
|
||||||
// ...with nothing lost on the way
|
// ...with nothing lost on the way
|
||||||
waitUntilConnectionQuality(punchbagUser, 0, "PunchbagUser", q -> q.contains("excellent"), 20,
|
assertConnectionQualityStaysExcellent(punchbagUser, regularUser, iceCandidateType);
|
||||||
"Expected PunchbagUser's own connection quality to be EXCELLENT through " + iceCandidateType);
|
|
||||||
waitUntilConnectionQuality(regularUser, 0, "PunchbagUser", q -> q.contains("excellent"), 20,
|
|
||||||
"Expected PunchbagUser's connection quality seen by RegularUser to be EXCELLENT through "
|
|
||||||
+ iceCandidateType);
|
|
||||||
|
|
||||||
// ...and through the forced candidate
|
// ...and through the forced candidate
|
||||||
assertConnectedThroughIceCandidateType(readPcTransportsInfoJson(punchbagUser, 0), iceCandidateType);
|
assertConnectedThroughIceCandidateType(readPcTransportsInfoJson(punchbagUser, 0), iceCandidateType);
|
||||||
|
|
@ -1764,9 +1760,14 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
|
||||||
*/
|
*/
|
||||||
private void assertMediaThroughIceCandidateType(OpenViduTestappUser punchbagUser, OpenViduTestappUser regularUser,
|
private void assertMediaThroughIceCandidateType(OpenViduTestappUser punchbagUser, OpenViduTestappUser regularUser,
|
||||||
IceCandidateType iceCandidateType, int connection) throws Exception {
|
IceCandidateType iceCandidateType, int connection) throws Exception {
|
||||||
// Every connection subscribes both users again to the other's audio and video
|
// Every connection subscribes both users again to the other's audio and video.
|
||||||
punchbagUser.getEventManager().waitUntilEventReaches("trackSubscribed", "RoomEvent", 2 * connection);
|
// RegularUser never reconnects, so its trackSubscribed RoomEvents add up; those
|
||||||
|
// of PunchbagUser can go missing after a reconnection (see
|
||||||
|
// waitUntilSubscribedToAudioAndVideo), so both users' subscriptions are also
|
||||||
|
// read from livekit-client's own state
|
||||||
regularUser.getEventManager().waitUntilEventReaches("trackSubscribed", "RoomEvent", 2 * connection);
|
regularUser.getEventManager().waitUntilEventReaches("trackSubscribed", "RoomEvent", 2 * connection);
|
||||||
|
waitUntilSubscribedToAudioAndVideo(punchbagUser, "RegularUser");
|
||||||
|
waitUntilSubscribedToAudioAndVideo(regularUser, "PunchbagUser");
|
||||||
|
|
||||||
// The PeerConnections of a reconnection are new: give them time to connect
|
// The PeerConnections of a reconnection are new: give them time to connect
|
||||||
final long deadline = System.currentTimeMillis() + 30000;
|
final long deadline = System.currentTimeMillis() + 30000;
|
||||||
|
|
@ -1788,11 +1789,78 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
|
||||||
waitUntilSubscriberFramesDecodedIncrease(user,
|
waitUntilSubscriberFramesDecodedIncrease(user,
|
||||||
user.getDriver().findElement(By.cssSelector("#openvidu-instance-0 video.remote")));
|
user.getDriver().findElement(By.cssSelector("#openvidu-instance-0 video.remote")));
|
||||||
}
|
}
|
||||||
waitUntilConnectionQuality(punchbagUser, 0, "PunchbagUser", q -> q.contains("excellent"), 20,
|
assertConnectionQualityStaysExcellent(punchbagUser, regularUser, iceCandidateType);
|
||||||
"Expected PunchbagUser's own connection quality to be EXCELLENT through " + iceCandidateType);
|
}
|
||||||
waitUntilConnectionQuality(regularUser, 0, "PunchbagUser", q -> q.contains("excellent"), 20,
|
|
||||||
"Expected PunchbagUser's connection quality seen by RegularUser to be EXCELLENT through "
|
/**
|
||||||
+ iceCandidateType);
|
* Wait until the livekit-client of {@code user} is subscribed to the audio and
|
||||||
|
* the video of {@code remoteIdentity} through its current PeerConnections: the
|
||||||
|
* Room is connected, and both tracks are live and received over a connected
|
||||||
|
* DTLS transport, which the closed PeerConnections of a previous connection no
|
||||||
|
* longer have.
|
||||||
|
*/
|
||||||
|
private void waitUntilSubscribedToAudioAndVideo(OpenViduTestappUser user, String remoteIdentity) {
|
||||||
|
// Empty when subscribed, what is missing otherwise
|
||||||
|
final String script = "const room = window['room_0'];"
|
||||||
|
+ "const who = room.localParticipant.identity + ' subscribing to ' + arguments[0] + ': ';"
|
||||||
|
+ "if (room.state !== 'connected') return who + 'room ' + room.state;"
|
||||||
|
+ "const participant = room.remoteParticipants.get(arguments[0]);"
|
||||||
|
+ "if (!participant) return who + 'no such participant';"
|
||||||
|
+ "const publications = Array.from(participant.trackPublications.values());"
|
||||||
|
+ "const missing = ['audio', 'video'].filter(kind => !publications.some(pub => pub.kind === kind"
|
||||||
|
+ " && pub.isSubscribed && pub.track?.mediaStreamTrack.readyState === 'live'"
|
||||||
|
+ " && pub.track.receiver?.transport?.state === 'connected'));"
|
||||||
|
+ "return missing.length ? who + 'no ' + missing.join(' or ')"
|
||||||
|
+ " + ' track received over a connected transport' : '';";
|
||||||
|
final JavascriptExecutor js = (JavascriptExecutor) user.getDriver();
|
||||||
|
try {
|
||||||
|
user.getWaiter().until(d -> "".equals(js.executeScript(script, remoteIdentity)));
|
||||||
|
} catch (org.openqa.selenium.TimeoutException e) {
|
||||||
|
Assertions.fail(String.valueOf(js.executeScript(script, remoteIdentity)), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assert that the connection quality for PunchbagUser's is EXCELLENT and that
|
||||||
|
* it stays EXCELLENT over time.
|
||||||
|
*/
|
||||||
|
private void assertConnectionQualityStaysExcellent(OpenViduTestappUser punchbagUser,
|
||||||
|
OpenViduTestappUser regularUser, IceCandidateType iceCandidateType) throws InterruptedException {
|
||||||
|
final long firstUpdateTimeoutMillis = 20000;
|
||||||
|
final long holdMillis = 15000;
|
||||||
|
final JavascriptExecutor punchbagJs = (JavascriptExecutor) punchbagUser.getDriver();
|
||||||
|
final JavascriptExecutor regularJs = (JavascriptExecutor) regularUser.getDriver();
|
||||||
|
final String sid = (String) punchbagJs.executeScript("return window['room_0'].localParticipant.sid;");
|
||||||
|
final String ownScript = "return window['room_0'].localParticipant.connectionQuality;";
|
||||||
|
final String seenScript = "const participant = window['room_0'].remoteParticipants.get('PunchbagUser');"
|
||||||
|
+ "return participant?.sid === arguments[0] ? participant.connectionQuality : 'unknown';";
|
||||||
|
final long start = System.currentTimeMillis();
|
||||||
|
long holdStart = -1;
|
||||||
|
while (true) {
|
||||||
|
final String own = (String) punchbagJs.executeScript(ownScript);
|
||||||
|
final String seen = (String) regularJs.executeScript(seenScript, sid);
|
||||||
|
final long now = System.currentTimeMillis();
|
||||||
|
final String levels = "own '" + own + "', seen by RegularUser '" + seen + "'";
|
||||||
|
if (holdStart < 0) {
|
||||||
|
// 'unknown' until the first update of the session reaches each browser
|
||||||
|
if (!"unknown".equals(own) && !"unknown".equals(seen)) {
|
||||||
|
holdStart = now;
|
||||||
|
} else if (now - start > firstUpdateTimeoutMillis) {
|
||||||
|
Assertions.fail("No connection quality reported for PunchbagUser's session " + sid + " through "
|
||||||
|
+ iceCandidateType + " (" + levels + ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (holdStart >= 0) {
|
||||||
|
if (!"excellent".equals(own) || !"excellent".equals(seen)) {
|
||||||
|
Assertions.fail("Expected PunchbagUser's connection quality to stay EXCELLENT through "
|
||||||
|
+ iceCandidateType + ", but " + (now - holdStart) / 1000 + " s in it was " + levels);
|
||||||
|
}
|
||||||
|
if (now - holdStart >= holdMillis) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Thread.sleep(1000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue