mirror of https://github.com/OpenVidu/openvidu.git
openvidu-test-e2e: add RTSP and SRT tests
parent
6ea42e82c0
commit
5fb3be503c
|
@ -12,6 +12,7 @@ import java.nio.file.Paths;
|
|||
import java.security.KeyManagementException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
@ -50,7 +51,8 @@ public class OpenViduTestE2e {
|
|||
|
||||
private final static WaitStrategy waitBrowser = Wait.forLogMessage("^.*Started Selenium Standalone.*$", 1);
|
||||
|
||||
protected static String MEDIA_SERVER_IMAGE = "livekit-server:latest";
|
||||
protected static String RTSP_SERVER_IMAGE = "lroktu/vlc-server:latest";
|
||||
protected static String SRT_SERVER_IMAGE = "linuxserver/ffmpeg:latest";
|
||||
|
||||
protected static String LIVEKIT_API_KEY = "devkey";
|
||||
protected static String LIVEKIT_API_SECRET = "secret";
|
||||
|
@ -80,8 +82,6 @@ public class OpenViduTestE2e {
|
|||
protected static RoomServiceClient LK;
|
||||
protected static IngressServiceClient LK_INGRESS;
|
||||
|
||||
private static boolean isMediaServerRestartTest = false;
|
||||
|
||||
protected static void checkFfmpegInstallation() {
|
||||
String ffmpegOutput = commandLine.executeCommand("which ffmpeg", 60);
|
||||
if (ffmpegOutput == null || ffmpegOutput.isEmpty()) {
|
||||
|
@ -141,6 +141,37 @@ public class OpenViduTestE2e {
|
|||
return edge;
|
||||
}
|
||||
|
||||
public void startRtspServer(boolean withAudio, boolean withVideo) throws Exception {
|
||||
GenericContainer<?> rtspServerContainer = new GenericContainer<>(DockerImageName.parse(RTSP_SERVER_IMAGE))
|
||||
.withCommand(getFileUrl(withAudio, withVideo)
|
||||
+ " --loop :sout=#gather:rtp{sdp=rtsp://:8554/} :network-caching=1500 :sout-all :sout-keep");
|
||||
rtspServerContainer.setPortBindings(Arrays.asList("8554:8554"));
|
||||
rtspServerContainer.start();
|
||||
containers.add(rtspServerContainer);
|
||||
}
|
||||
|
||||
public void startSrtServer(boolean withAudio, boolean withVideo) throws Exception {
|
||||
GenericContainer<?> srtServerContainer = new GenericContainer<>(DockerImageName.parse(SRT_SERVER_IMAGE))
|
||||
.withNetworkMode("host").withCommand(
|
||||
"-i " + getFileUrl(withAudio, withVideo) + " -c:v libx264 -f mpegts srt://:8554?mode=listener");
|
||||
srtServerContainer.start();
|
||||
containers.add(srtServerContainer);
|
||||
}
|
||||
|
||||
private String getFileUrl(boolean withAudio, boolean withVideo) throws Exception {
|
||||
String fileUrl;
|
||||
if (withAudio && withVideo) {
|
||||
fileUrl = "https://s3.eu-west-1.amazonaws.com/public.openvidu.io/bbb_sunflower_1080p_60fps_normal.mp4";
|
||||
} else if (!withAudio && withVideo) {
|
||||
fileUrl = "https://s3.eu-west-1.amazonaws.com/public.openvidu.io/bbb_sunflower_1080p_60fps_normal_noaudio.mp4";
|
||||
} else if (withAudio) {
|
||||
fileUrl = "https://s3.eu-west-1.amazonaws.com/public.openvidu.io/bbb_sunflower_1080p_60fps_normal_onlyaudio.mp3";
|
||||
} else {
|
||||
throw new Exception("Must have audio or video");
|
||||
}
|
||||
return fileUrl;
|
||||
}
|
||||
|
||||
protected static void setUpLiveKitClient() throws NoSuchAlgorithmException {
|
||||
URI uri = null;
|
||||
try {
|
||||
|
@ -209,12 +240,6 @@ public class OpenViduTestE2e {
|
|||
}
|
||||
log.info("Using api secret {} to connect to livekit-server", LIVEKIT_API_SECRET);
|
||||
|
||||
String mediaServerImage = System.getProperty("MEDIA_SERVER_IMAGE");
|
||||
if (mediaServerImage != null) {
|
||||
MEDIA_SERVER_IMAGE = mediaServerImage;
|
||||
}
|
||||
log.info("Using media server {} for e2e tests", MEDIA_SERVER_IMAGE);
|
||||
|
||||
String chromeVersion = System.getProperty("CHROME_VERSION");
|
||||
if (chromeVersion != null && !chromeVersion.isBlank()) {
|
||||
CHROME_VERSION = chromeVersion;
|
||||
|
@ -366,13 +391,6 @@ public class OpenViduTestE2e {
|
|||
// Close all remaining Rooms
|
||||
this.closeAllRooms(LK);
|
||||
|
||||
// Reset Media Server
|
||||
if (isMediaServerRestartTest) {
|
||||
this.stopMediaServer();
|
||||
this.startMediaServer();
|
||||
isMediaServerRestartTest = false;
|
||||
}
|
||||
|
||||
// Dispose all browsers users
|
||||
Iterator<BrowserUser> it1 = browserUsers.iterator();
|
||||
while (it1.hasNext()) {
|
||||
|
@ -458,17 +476,4 @@ public class OpenViduTestE2e {
|
|||
throw new Exception("File " + path.toAbsolutePath().toString() + " exists but is not readable");
|
||||
}
|
||||
}
|
||||
|
||||
protected void startMediaServer() {
|
||||
String command = "docker run --rm -p 1880:7880 -e LIVEKIT_KEYS=\"" + LIVEKIT_API_KEY + " : "
|
||||
+ LIVEKIT_API_SECRET + "\" " + MEDIA_SERVER_IMAGE;
|
||||
commandLine.executeCommand(command, 60);
|
||||
}
|
||||
|
||||
protected void stopMediaServer() {
|
||||
isMediaServerRestartTest = true;
|
||||
final String dockerRemoveCmd = "docker ps -a | awk '{ print $1,$2 }' | grep livekit-server | awk '{ print $1 }' | xargs -I {} docker rm -f {}";
|
||||
commandLine.executeCommand(dockerRemoveCmd, 60);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -54,6 +54,8 @@ import com.google.gson.JsonParser;
|
|||
|
||||
import io.openvidu.test.e2e.annotations.OnlyMediasoup;
|
||||
import io.openvidu.test.e2e.annotations.OnlyPion;
|
||||
import livekit.LivekitIngress.IngressInfo;
|
||||
import livekit.LivekitIngress.IngressState;
|
||||
|
||||
/**
|
||||
* E2E tests for openvidu-testapp.
|
||||
|
@ -1659,7 +1661,7 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
|
|||
user.getEventManager().waitUntilEventReaches("connected", "RoomEvent", 1);
|
||||
|
||||
// Try publishing H264 with 2 layer simulcast
|
||||
createIngress(user, "H264_540P_25FPS_2_LAYERS", null, true);
|
||||
createIngress(user, "H264_540P_25FPS_2_LAYERS", null, true, "HTTP");
|
||||
|
||||
user.getEventManager().waitUntilEventReaches("trackSubscribed", "ParticipantEvent", 1);
|
||||
user.getWaiter().until(ExpectedConditions.numberOfElementsToBe(By.tagName("video"), 1));
|
||||
|
@ -1688,7 +1690,7 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
|
|||
user.getEventManager().waitUntilEventReaches("participantDisconnected", "RoomEvent", 1);
|
||||
|
||||
// Try publishing H264 with 3 layer simulcast
|
||||
createIngress(user, "H264_1080P_30FPS_3_LAYERS_HIGH_MOTION", null, true);
|
||||
createIngress(user, "H264_1080P_30FPS_3_LAYERS_HIGH_MOTION", null, true, "HTTP");
|
||||
user.getEventManager().waitUntilEventReaches("trackSubscribed", "ParticipantEvent", 1);
|
||||
user.getWaiter().until(ExpectedConditions.numberOfElementsToBe(By.tagName("video"), 1));
|
||||
numberOfVideos = user.getDriver().findElements(By.tagName("video")).size();
|
||||
|
@ -1712,6 +1714,102 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
|
|||
this.waitUntilSubscriberFrameHeightIs(user, subscriberVideo, 1080);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("RTSP ingress")
|
||||
void rtspIngressTest() throws Exception {
|
||||
startRtspServer(true, true);
|
||||
urPullCommon("RTSP", true, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("RTSP ingress only video")
|
||||
void rtspIngressTestOnlyVideo() throws Exception {
|
||||
startRtspServer(false, true);
|
||||
urPullCommon("RTSP", false, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("RTSP ingress only audio")
|
||||
void rtspIngressTestOnlyAudio() throws Exception {
|
||||
startRtspServer(true, false);
|
||||
urPullCommon("RTSP", true, false);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("SRT ingress")
|
||||
void srtIngressTest() throws Exception {
|
||||
startSrtServer(true, true);
|
||||
urPullCommon("SRT", true, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("SRT ingress only video")
|
||||
void srtIngressTestOnlyVideo() throws Exception {
|
||||
startSrtServer(false, true);
|
||||
urPullCommon("SRT", false, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("SRT ingress only audio")
|
||||
void srtIngressTestOnlyAudio() throws Exception {
|
||||
startSrtServer(true, false);
|
||||
urPullCommon("SRT", true, false);
|
||||
}
|
||||
|
||||
private void urPullCommon(String urlType, boolean withAudio, boolean withVideo) throws Exception {
|
||||
OpenViduTestappUser user = setupBrowserAndConnectToOpenViduTestapp("chrome");
|
||||
this.addSubscriber(user, false);
|
||||
user.getDriver().findElements(By.className("connect-btn")).forEach(el -> el.sendKeys(Keys.ENTER));
|
||||
user.getEventManager().waitUntilEventReaches("connected", "RoomEvent", 1);
|
||||
createIngress(user, null, "VP8", false, urlType);
|
||||
|
||||
if (withAudio && withVideo) {
|
||||
user.getEventManager().waitUntilEventReaches("trackSubscribed", "ParticipantEvent", 2);
|
||||
} else {
|
||||
user.getEventManager().waitUntilEventReaches("trackSubscribed", "ParticipantEvent", 1);
|
||||
}
|
||||
|
||||
if (withAudio) {
|
||||
user.getWaiter().until(ExpectedConditions.numberOfElementsToBe(By.tagName("audio"), 1));
|
||||
final int numberOfAudios = user.getDriver().findElements(By.tagName("audio")).size();
|
||||
Assertions.assertEquals(1, numberOfAudios, "Wrong number of videos");
|
||||
Assertions.assertTrue(user.getBrowserUser().assertAllElementsHaveTracks("audio", true, false),
|
||||
"HTMLAudioElements were expected to have only one audio track");
|
||||
if (!withVideo) {
|
||||
final int numberOfVideos = user.getDriver().findElements(By.tagName("video")).size();
|
||||
Assertions.assertEquals(0, numberOfVideos, "Wrong number of videos");
|
||||
}
|
||||
}
|
||||
if (withVideo) {
|
||||
user.getWaiter().until(ExpectedConditions.numberOfElementsToBe(By.tagName("video"), 1));
|
||||
final int numberOfVideos = user.getDriver().findElements(By.tagName("video")).size();
|
||||
Assertions.assertEquals(1, numberOfVideos, "Wrong number of videos");
|
||||
Assertions.assertTrue(user.getBrowserUser().assertAllElementsHaveTracks("video", false, true),
|
||||
"HTMLVideoElements were expected to have only one video track");
|
||||
if (!withAudio) {
|
||||
final int numberOfAudios = user.getDriver().findElements(By.tagName("audio")).size();
|
||||
Assertions.assertEquals(0, numberOfAudios, "Wrong number of videos");
|
||||
}
|
||||
|
||||
WebElement subscriberVideo = user.getDriver()
|
||||
.findElement(By.cssSelector("#openvidu-instance-0 video.remote"));
|
||||
|
||||
waitUntilVideoLayersNotEmpty(user, subscriberVideo);
|
||||
long bytesReceived = this.getSubscriberVideoBytesReceived(user, subscriberVideo);
|
||||
this.waitUntilSubscriberBytesReceivedIncrease(user, subscriberVideo, bytesReceived);
|
||||
this.waitUntilSubscriberFramesPerSecondNotZero(user, subscriberVideo);
|
||||
JsonArray json = this.getLayersAsJsonArray(user, subscriberVideo);
|
||||
String subscriberCodec = json.get(0).getAsJsonObject().get("codec").getAsString();
|
||||
String expectedCodec = "video/VP8";
|
||||
Assertions.assertEquals(expectedCodec, subscriberCodec);
|
||||
}
|
||||
|
||||
List<IngressInfo> ingresses = LK_INGRESS.listIngress().execute().body();
|
||||
Assertions.assertEquals(1, ingresses.size());
|
||||
Assertions.assertTrue(ingresses.get(0).getUrl().startsWith(urlType.toLowerCase() + "://"));
|
||||
Assertions.assertEquals(IngressState.Status.ENDPOINT_PUBLISHING, ingresses.get(0).getState().getStatus());
|
||||
}
|
||||
|
||||
private void ingressSimulcastTest(OpenViduTestappUser user, boolean simulcast, String codec, String preset)
|
||||
throws Exception {
|
||||
|
||||
|
@ -1721,7 +1819,7 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
|
|||
|
||||
user.getEventManager().waitUntilEventReaches("connected", "RoomEvent", 1);
|
||||
|
||||
createIngress(user, preset, codec, simulcast);
|
||||
createIngress(user, preset, codec, simulcast, "HTTP");
|
||||
|
||||
user.getEventManager().waitUntilEventReaches("trackSubscribed", "ParticipantEvent", 1);
|
||||
|
||||
|
@ -2074,7 +2172,7 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
|
|||
}
|
||||
}
|
||||
|
||||
private void createIngress(OpenViduTestappUser user, String preset, String codec, boolean simulcast)
|
||||
private void createIngress(OpenViduTestappUser user, String preset, String codec, boolean simulcast, String urlType)
|
||||
throws InterruptedException {
|
||||
if (!user.getDriver().findElements(By.id("close-dialog-btn")).isEmpty()) {
|
||||
user.getDriver().findElement(By.id("close-dialog-btn")).click();
|
||||
|
@ -2094,6 +2192,11 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
|
|||
Thread.sleep(300);
|
||||
user.getDriver().findElement(By.cssSelector("#mat-option-" + codec.toUpperCase())).click();
|
||||
}
|
||||
if (urlType != null) {
|
||||
user.getDriver().findElement(By.cssSelector("#ingress-url-type-select")).click();
|
||||
Thread.sleep(300);
|
||||
user.getDriver().findElement(By.cssSelector("#mat-option-" + urlType.toUpperCase())).click();
|
||||
}
|
||||
user.getDriver().findElement(By.cssSelector("#create-ingress-api-btn")).click();
|
||||
user.getDriver().findElement(By.cssSelector("#close-dialog-btn")).click();
|
||||
Thread.sleep(300);
|
||||
|
|
Loading…
Reference in New Issue