From ff50fa45f0203a2ac445580a863f512a165efb97 Mon Sep 17 00:00:00 2001 From: pabloFuente Date: Fri, 29 Oct 2021 13:38:20 +0200 Subject: [PATCH] Use kurento docker image with tests. Infinite media server reconnection on CE --- .../io/openvidu/server/core/EndReason.java | 4 +- .../server/kurento/core/KurentoSession.java | 12 +++- .../kurento/kms/FixedOneKmsManager.java | 7 +- .../server/kurento/kms/KmsManager.java | 13 ++-- openvidu-test-e2e/jenkins/Jenkinsfile | 58 ++++++++--------- .../jenkins/commonFunctions.groovy | 46 +++++++------ .../e2e/AbstractOpenViduTestAppE2eTest.java | 65 +++++++++++++------ .../test/e2e/OpenViduTestAppE2eTest.java | 55 +++++++++------- .../test/e2e/annotations/OnlyKurento.java | 2 +- 9 files changed, 159 insertions(+), 103 deletions(-) diff --git a/openvidu-server/src/main/java/io/openvidu/server/core/EndReason.java b/openvidu-server/src/main/java/io/openvidu/server/core/EndReason.java index 152ff122..f4b8cc5f 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/core/EndReason.java +++ b/openvidu-server/src/main/java/io/openvidu/server/core/EndReason.java @@ -102,8 +102,8 @@ public enum EndReason { mediaServerDisconnect, /** - * A media server disconnected, but was able to reconnect again. Nevertheless - * all of the media endpoints were destroyed in the process. Applies to + * A media server disconnected, and a new one automatically reconnected. All of + * the media endpoints were destroyed in the process. Applies to * webrtcConnectionDestroyed and recordingStatusChanged */ mediaServerReconnect, diff --git a/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSession.java b/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSession.java index ca849e6d..4b5f5cd4 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSession.java +++ b/openvidu-server/src/main/java/io/openvidu/server/kurento/core/KurentoSession.java @@ -293,7 +293,7 @@ public class KurentoSession extends Session { .collect(Collectors.toSet()); } - public void restartStatusInKurentoAfterReconnection(Long kmsDisconnectionTime) { + public void restartStatusInKurentoAfterReconnectionToNewKms(Long kmsDisconnectionTime) { log.info("Resetting process: resetting remote media objects for active session {}", this.sessionId); @@ -313,8 +313,14 @@ public class KurentoSession extends Session { mediaOptionsMap.put(kParticipant.getParticipantPublicId(), kParticipant.getPublisher().getMediaOptions()); } - kParticipant.releaseAllFilters(); - kParticipant.close(EndReason.mediaServerReconnect, false, kmsDisconnectionTime); + try { + // Skip remote operations to non-existant KMS + RemoteOperationUtils.setToSkipRemoteOperations(); + kParticipant.releaseAllFilters(); + kParticipant.close(EndReason.mediaServerReconnect, false, kmsDisconnectionTime); + } finally { + RemoteOperationUtils.revertToRunRemoteOperations(); + } if (wasStreaming) { kurentoSessionHandler.onUnpublishMedia(kParticipant, this.getParticipants(), null, null, null, EndReason.mediaServerReconnect); diff --git a/openvidu-server/src/main/java/io/openvidu/server/kurento/kms/FixedOneKmsManager.java b/openvidu-server/src/main/java/io/openvidu/server/kurento/kms/FixedOneKmsManager.java index 7dc41750..63a46feb 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/kurento/kms/FixedOneKmsManager.java +++ b/openvidu-server/src/main/java/io/openvidu/server/kurento/kms/FixedOneKmsManager.java @@ -24,7 +24,6 @@ import java.util.NoSuchElementException; import javax.annotation.PostConstruct; -import io.openvidu.server.core.MediaServer; import org.kurento.client.KurentoClient; import org.kurento.client.ServerInfo; import org.kurento.commons.exception.KurentoException; @@ -32,6 +31,7 @@ import org.kurento.jsonrpc.client.JsonRpcClientNettyWebSocket; import org.kurento.jsonrpc.client.JsonRpcWSConnectionListener; import io.openvidu.java.client.RecordingProperties; +import io.openvidu.server.core.MediaServer; import io.openvidu.server.core.Session; import io.openvidu.server.core.SessionManager; @@ -101,6 +101,11 @@ public class FixedOneKmsManager extends KmsManager { return null; } + @Override + protected boolean infiniteRetry() { + return true; + } + @Override @PostConstruct protected void postConstructInitKurentoClients() { diff --git a/openvidu-server/src/main/java/io/openvidu/server/kurento/kms/KmsManager.java b/openvidu-server/src/main/java/io/openvidu/server/kurento/kms/KmsManager.java index a15fced9..55376403 100644 --- a/openvidu-server/src/main/java/io/openvidu/server/kurento/kms/KmsManager.java +++ b/openvidu-server/src/main/java/io/openvidu/server/kurento/kms/KmsManager.java @@ -240,12 +240,15 @@ public abstract class KmsManager { sessionEventsHandler.onMediaNodeCrashed(kms, environmentId, timeOfKurentoDisconnection, affectedSessionIds, affectedRecordingIds); + if (infiniteRetry()) { + disconnected(); + } + } else { - // KurentoClient connection timeout may exceed the limit. - // This happens if not only kms process has crashed, but the instance itself is - // not reachable if ((System.currentTimeMillis() - initTime) > maxReconnectTimeMillis) { + // KurentoClient connection timeout exceeds the limit. This happens if not only + // media server process has crashed, but the instance itself is not reachable iteration.set(0); return; } @@ -276,7 +279,7 @@ public abstract class KmsManager { kms.getUri(), kms.getKurentoSessions().size(), kms.getKurentoSessions().stream() .map(s -> s.getSessionId()).collect(Collectors.joining(",", "[", "]"))); kms.getKurentoSessions().forEach(kSession -> { - kSession.restartStatusInKurentoAfterReconnection(timeOfKurentoDisconnection); + kSession.restartStatusInKurentoAfterReconnectionToNewKms(timeOfKurentoDisconnection); }); } else { log.info("KMS with URI {} is the same process. Nothing must be done", kms.getUri()); @@ -342,6 +345,8 @@ public abstract class KmsManager { @PostConstruct protected abstract void postConstructInitKurentoClients(); + protected abstract boolean infiniteRetry(); + public void closeAllKurentoClients() { log.info("Closing all KurentoClients"); this.kmss.values().forEach(kms -> { diff --git a/openvidu-test-e2e/jenkins/Jenkinsfile b/openvidu-test-e2e/jenkins/Jenkinsfile index cf01dfbd..27ae2d06 100644 --- a/openvidu-test-e2e/jenkins/Jenkinsfile +++ b/openvidu-test-e2e/jenkins/Jenkinsfile @@ -17,27 +17,6 @@ node('container') { // Run openvidu/openvidu-test-e2e container docker.image('openvidu/openvidu-test-e2e:$DISTRO').inside('--name e2e -p 4200:4200 -p 4443:4443 -p 5555:5555 -u root -e MY_UID=0 ' + "${bindsArray}" + ' --privileged') { - stage('Preparation') { - sh(script: '''#!/bin/bash -xe - if [[ $KURENTO_JAVA_COMMIT != "default" ]]; then - git clone https://github.com/Kurento/kurento-java.git - cd kurento-java - git checkout -f $KURENTO_JAVA_COMMIT - mvn -B clean install - fi - '''.stripIndent()) - sh(script: '''#!/bin/bash -xe - if $KURENTO_MEDIA_SERVER_DEV ; then - echo "Upgrading KMS to dev version" - sudo apt-get update && sudo apt-get install -y aptitude - sudo aptitude remove -y kurento-media-server - DISTRO=`lsb_release --codename | cut -f2` - sudo echo "deb [arch=amd64] http://ubuntu.openvidu.io/dev $DISTRO kms6" | sudo tee /etc/apt/sources.list.d/kurento.list - sudo apt-get update && sudo apt-get --yes -o Dpkg::Options::="--force-confnew" install kurento-media-server - fi - '''.stripIndent()) - } - stage('Build 1') { parallel 'OpenVidu Browser build': { stage('OpenVidu Browser build') { @@ -95,7 +74,11 @@ node('container') { stage('OpenVidu parent build') { sh(script: '''#!/bin/bash -xe if [[ $KURENTO_JAVA_COMMIT != "default" ]]; then - cd kurento-java && MVN_VERSION=$(mvn -B -q -Dexec.executable=echo -Dexec.args='${project.version}' --non-recursive exec:exec) + git clone https://github.com/Kurento/kurento-java.git + cd kurento-java + git checkout -f $KURENTO_JAVA_COMMIT + mvn -B clean install + MVN_VERSION=$(mvn -B -q -Dexec.executable=echo -Dexec.args='${project.version}' --non-recursive exec:exec) cd ../openvidu && mvn -B versions:set-property -Dproperty=version.kurento -DnewVersion=$MVN_VERSION fi '''.stripIndent()) @@ -182,14 +165,19 @@ def environmentLaunch(mediaServer) { sh 'openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -subj "/CN=www.mydom.com/O=My Company LTD./C=US" -keyout /opt/openvidu/testapp/key.pem -out /opt/openvidu/testapp/cert.pem' sh 'cd /opt/openvidu/testapp && http-server -S -p 4200 &> /opt/openvidu/testapp.log &' if (mediaServer == 'kurento') { - sh '/usr/bin/kurento-media-server &> /kms.log &' + sh(script: '''#!/bin/bash -xe + docker run -e KMS_UID=$(id -u) --network=host --detach=true --volume=/opt/openvidu/recordings:/opt/openvidu/recordings kurento/kurento-media-server:$KURENTO_MEDIA_SERVER_VERSION + '''.stripIndent()) } else if (mediaServer == 'mediasoup') { sh(script: '''#!/bin/bash -xe - docker run --name=mediasoup --env=KMS_MIN_PORT=40000 --env=KMS_MAX_PORT=65535 \ + docker run --network=host --restart=always --detach=true \ + --env=KMS_MIN_PORT=40000 \ + --env=KMS_MAX_PORT=65535 \ --env=OPENVIDU_PRO_LICENSE=$OPENVIDU_PRO_LICENSE \ --env=OPENVIDU_PRO_LICENSE_API=$OPENVIDU_PRO_LICENSE_API \ - --env=WEBRTC_LISTENIPS_0_ANNOUNCEDIP=172.17.0.1 --env=WEBRTC_LISTENIPS_0_IP=172.17.0.1 \ - --volume=/opt/openvidu/recordings:/opt/openvidu/recordings --network=host --restart=always --detach=true \ + --env=WEBRTC_LISTENIPS_0_ANNOUNCEDIP=172.17.0.1 \ + --env=WEBRTC_LISTENIPS_0_IP=172.17.0.1 \ + --volume=/opt/openvidu/recordings:/opt/openvidu/recordings \ openvidu/mediasoup-controller:$MEDIASOUP_CONTROLLER_DOCKER_VERSION '''.stripIndent()) } @@ -214,14 +202,24 @@ def environmentLaunch(mediaServer) { } def environmentStop() { - sh 'kill -9 $(pidof kurento-media-server) || true' sh 'kill -9 $(pgrep -f /opt/openvidu/openvidu-server) || true' - sh 'docker rm -f mediasoup || true' + sh(script: '''#!/bin/bash -xe + declare -a arr=("openvidu/mediasoup-controller:" + "kurento/kurento-media-server:") + for image in "${arr[@]}" + do + docker ps -a | awk '{ print $1,$2 }' | grep "$image" | awk '{ print $1 }' | xargs -I {} docker rm -f {} + done + '''.stripIndent()) } def openViduE2ETest(mediaServer) { script { - env.mediaServer = mediaServer + if [ "$mediaServer" = "kurento" ]; then + env.mediaServerImage="kurento/kurento-media-server:$KURENTO_MEDIA_SERVER_VERSION" + elif [ "$mediaServer" = "mediasoup" ]; then + env.mediaServerImage="openvidu/mediasoup-controller:$MEDIASOUP_CONTROLLER_DOCKER_VERSION" + fi sh(script: '''#!/bin/bash -xe cd openvidu/openvidu-test-browsers mvn -B versions:set -DnewVersion=TEST && mvn -B clean install @@ -230,7 +228,7 @@ def openViduE2ETest(mediaServer) { mvn -B versions:set-property -Dproperty=version.openvidu.test.browsers -DnewVersion=TEST cd openvidu-test-e2e mvn -B -DskipTests=true clean install - sudo mvn -B -DMEDIA_SERVER=${mediaServer} -Dtest=OpenViduTestAppE2eTest -DAPP_URL=https://172.17.0.1:4200/ -DOPENVIDU_URL=https://172.17.0.1:4443/ -DREMOTE_URL_CHROME=http://172.17.0.1:6666/wd/hub/ -DREMOTE_URL_FIREFOX=http://172.17.0.1:6667/wd/hub/ -DREMOTE_URL_OPERA=http://172.17.0.1:6668/wd/hub/ -DEXTERNAL_CUSTOM_LAYOUT_URL=http://172.17.0.1:5555 -DEXTERNAL_CUSTOM_LAYOUT_PARAMS=sessionId,CUSTOM_LAYOUT_SESSION,secret,MY_SECRET test + sudo mvn -B -DMEDIA_SERVER_IMAGE=${mediaServerImage} -Dtest=OpenViduTestAppE2eTest -DAPP_URL=https://172.17.0.1:4200/ -DOPENVIDU_URL=https://172.17.0.1:4443/ -DREMOTE_URL_CHROME=http://172.17.0.1:6666/wd/hub/ -DREMOTE_URL_FIREFOX=http://172.17.0.1:6667/wd/hub/ -DREMOTE_URL_OPERA=http://172.17.0.1:6668/wd/hub/ -DEXTERNAL_CUSTOM_LAYOUT_URL=http://172.17.0.1:5555 -DEXTERNAL_CUSTOM_LAYOUT_PARAMS=sessionId,CUSTOM_LAYOUT_SESSION,secret,MY_SECRET test '''.stripIndent()) } } diff --git a/openvidu-test-e2e/jenkins/commonFunctions.groovy b/openvidu-test-e2e/jenkins/commonFunctions.groovy index aedef1f4..561fa3e9 100644 --- a/openvidu-test-e2e/jenkins/commonFunctions.groovy +++ b/openvidu-test-e2e/jenkins/commonFunctions.groovy @@ -6,7 +6,6 @@ def prepareTestingEnvironment() { sh 'sudo rm -rf /opt/openvidu/* || true' }, 'Deleting repository openvidu': { - sh 'echo $(readlink -f .)' sh 'sudo rm -rf openvidu || true' }, 'Deleting repository openvidu-pro': { @@ -23,27 +22,27 @@ def prepareTestingEnvironment() { }, 'Removing stranded containers': { sh(script: '''#!/bin/bash -xe - declare -a arr=('openvidu/openvidu-test-e2e:', - 'openvidu/openvidu-pro-test-e2e:', - 'selenium/standalone-chrome:', - 'selenium/standalone-firefox:', - 'selenium/standalone-opera:', - 'openvidu/mediasoup-controller:', - 'openvidu/openvidu-server-pro:', - 'openvidu/openvidu-redis:', - 'openvidu/openvidu-coturn:', - 'openvidu/openvidu-proxy:', - 'openvidu/replication-manager:', - 'docker.elastic.co/elasticsearch/elasticsearch:', - 'docker.elastic.co/kibana/kibana:', - 'docker.elastic.co/beats/metricbeat-oss:', - 'docker.elastic.co/beats/filebeat-oss:', - 'openvidu/openvidu-pro-dind-media-node:', - 'kurento/kurento-media-server:', - 'openvidu/media-node-controller:') - for image in "${containersToRemove[@]}" + declare -a arr=("openvidu/openvidu-test-e2e:" + "openvidu/openvidu-pro-test-e2e:" + "selenium/standalone-chrome:" + "selenium/standalone-firefox:" + "selenium/standalone-opera:" + "openvidu/mediasoup-controller:" + "openvidu/openvidu-server-pro:" + "openvidu/openvidu-redis:" + "openvidu/openvidu-coturn:" + "openvidu/openvidu-proxy:" + "openvidu/replication-manager:" + "docker.elastic.co/elasticsearch/elasticsearch:" + "docker.elastic.co/kibana/kibana:" + "docker.elastic.co/beats/metricbeat-oss:" + "docker.elastic.co/beats/filebeat-oss:" + "openvidu/openvidu-pro-dind-media-node:" + "kurento/kurento-media-server:" + "openvidu/media-node-controller:") + for image in "${arr[@]}" do - docker ps -a | awk \'{ print $1,$2 }\' | grep "$image" | awk \'{ print $1 }\' | xargs -I {} docker rm -f {} + docker ps -a | awk '{ print $1,$2 }' | grep "$image" | awk '{ print $1 }' | xargs -I {} docker rm -f {} done '''.stripIndent()) } @@ -75,6 +74,11 @@ def prepareTestingEnvironment() { docker.image('openvidu/mediasoup-controller:$MEDIASOUP_CONTROLLER_DOCKER_VERSION').pull() } }, + 'Pull kurento/kurento-media-server': { + if (env.KURENTO_MEDIA_SERVER_VERSION) { + docker.image('kurento/kurento-media-server:$KURENTO_MEDIA_SERVER_VERSION').pull() + } + }, 'Download fake video': { sh(script: '''#!/bin/bash -xe FAKE_VIDEO=/opt/openvidu-cache/barcode.y4m diff --git a/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/AbstractOpenViduTestAppE2eTest.java b/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/AbstractOpenViduTestAppE2eTest.java index 3e7ba928..862f6dd1 100644 --- a/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/AbstractOpenViduTestAppE2eTest.java +++ b/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/AbstractOpenViduTestAppE2eTest.java @@ -36,10 +36,10 @@ import io.openvidu.java.client.OpenViduHttpException; import io.openvidu.java.client.OpenViduJavaClientException; import io.openvidu.java.client.VideoCodec; import io.openvidu.test.browsers.BrowserUser; +import io.openvidu.test.browsers.ChromeAndroidUser; import io.openvidu.test.browsers.ChromeUser; import io.openvidu.test.browsers.FirefoxUser; import io.openvidu.test.browsers.OperaUser; -import io.openvidu.test.browsers.ChromeAndroidUser; import io.openvidu.test.browsers.utils.CommandLineExecutor; import io.openvidu.test.browsers.utils.CustomHttpClient; import io.openvidu.test.browsers.utils.RecordingUtils; @@ -47,7 +47,9 @@ import io.openvidu.test.browsers.utils.RecordingUtils; public class AbstractOpenViduTestAppE2eTest { // Media server variables - public static String MEDIA_SERVER = "kurento"; + final protected static String KURENTO_IMAGE = "kurento/kurento-media-server"; + final protected static String MEDIASOUP_IMAGE = "openvidu/mediasoup-controller"; + protected static String MEDIA_SERVER_IMAGE = KURENTO_IMAGE + ":6.16.0"; final protected String DEFAULT_JSON_SESSION = "{'id':'STR','object':'session','sessionId':'STR','createdAt':0,'mediaMode':'STR','recordingMode':'STR','defaultRecordingProperties':{'hasVideo':true,'frameRate':25,'hasAudio':true,'shmSize':536870912,'name':'','outputMode':'COMPOSED','resolution':'1280x720','recordingLayout':'BEST_FIT'},'customSessionId':'STR','connections':{'numberOfElements':0,'content':[]},'recording':false,'forcedVideoCodec':'STR','allowTranscoding':false}"; final protected String DEFAULT_JSON_PENDING_CONNECTION = "{'id':'STR','object':'connection','type':'WEBRTC','status':'pending','connectionId':'STR','sessionId':'STR','createdAt':0,'activeAt':null,'location':null,'ip':null,'platform':null,'token':'STR','serverData':'STR','record':true,'role':'STR','kurentoOptions':null,'rtspUri':null,'adaptativeBitrate':null,'onlyPlayWithSubscribers':null,'networkCache':null,'clientData':null,'publishers':null,'subscribers':null}"; @@ -59,6 +61,8 @@ public class AbstractOpenViduTestAppE2eTest { protected static String OPENVIDU_URL = "https://localhost:4443/"; protected static String APP_URL = "http://localhost:4200/"; protected static String EXTERNAL_CUSTOM_LAYOUT_URL = "http://localhost:5555"; + protected static String OPENVIDU_PRO_LICENSE = "not_valid"; + protected static String OPENVIDU_PRO_LICENSE_API = "not_valid"; protected static String EXTERNAL_CUSTOM_LAYOUT_PARAMS = "sessionId,CUSTOM_LAYOUT_SESSION,secret,MY_SECRET"; protected static Exception ex = null; protected final Object lock = new Object(); @@ -158,11 +162,21 @@ public class AbstractOpenViduTestAppE2eTest { } log.info("Using secret {} to connect to openvidu-server", OPENVIDU_SECRET); - String mediaServer = System.getProperty("MEDIA_SERVER"); - if (mediaServer != null) { - MEDIA_SERVER = mediaServer; + 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 openviduProLicense = System.getProperty("OPENVIDU_PRO_LICENSE"); + if (openviduProLicense != null) { + OPENVIDU_PRO_LICENSE = openviduProLicense; + } + + String openviduProLicenseApi = System.getProperty("OPENVIDU_PRO_LICENSE_API"); + if (openviduProLicenseApi != null) { + OPENVIDU_PRO_LICENSE_API = openviduProLicenseApi; } - log.info("Using media server {} for e2e tests"); } protected void setupBrowser(String browser) { @@ -305,27 +319,39 @@ public class AbstractOpenViduTestAppE2eTest { } protected void startMediaServer() { - if ("kurento".equals(MEDIA_SERVER)) { - log.info("Starting KMS"); - commandLine.executeCommand("/usr/bin/kurento-media-server &>> /kms.log &"); - } else if ("mediasoup".equals(MEDIA_SERVER)) { - log.info("Starting MediaSoup"); - // TODO?: Test which use this method are disabled + String command = null; + if (MEDIA_SERVER_IMAGE.startsWith(KURENTO_IMAGE)) { + log.info("Starting kurento"); + command = "docker run -e KMS_UID=$(id -u) --network=host --detach=true" + + " --volume=/opt/openvidu/recordings:/opt/openvidu/recordings " + MEDIA_SERVER_IMAGE; + } else if (MEDIA_SERVER_IMAGE.startsWith(MEDIASOUP_IMAGE)) { + log.info("Starting mediaSoup"); + command = "docker run --network=host --restart=always --detach=true --env=KMS_MIN_PORT=40000 --env=KMS_MAX_PORT=65535" + + " --env=OPENVIDU_PRO_LICENSE=" + OPENVIDU_PRO_LICENSE + " --env=OPENVIDU_PRO_LICENSE_API=" + + OPENVIDU_PRO_LICENSE_API + + " --env=WEBRTC_LISTENIPS_0_ANNOUNCEDIP=172.17.0.1 --env=WEBRTC_LISTENIPS_0_IP=172.17.0.1" + + " --volume=/opt/openvidu/recordings:/opt/openvidu/recordings " + MEDIA_SERVER_IMAGE; } else { - log.error("Unrecognized MEDIA_SERVER: {}", MEDIA_SERVER); + log.error("Unrecognized MEDIA_SERVER_IMAGE: {}", MEDIA_SERVER_IMAGE); System.exit(1); } + commandLine.executeCommand(command); } protected void stopMediaServer() { - if ("kurento".equals(MEDIA_SERVER)) { - log.info("Stopping KMS"); - commandLine.executeCommand("kill -9 $(pidof kurento-media-server)"); - } else if ("mediasoup".equals(MEDIA_SERVER)) { + final String dockerRemoveCmd = "docker ps -a | awk '{ print $1,$2 }' | grep GREP_PARAMETER | awk '{ print $1 }' | xargs -I {} docker rm -f {}"; + String grep = null; + if (MEDIA_SERVER_IMAGE.startsWith(KURENTO_IMAGE)) { + log.info("Stopping kurento"); + grep = KURENTO_IMAGE + ":"; + } else if (MEDIA_SERVER_IMAGE.startsWith(MEDIASOUP_IMAGE)) { log.info("Stopping mediasoup"); - commandLine.executeCommand("docker rm -f mediasoup"); + grep = MEDIASOUP_IMAGE + ":"; + } else { + log.error("Unrecognized MEDIA_SERVER_IMAGE: {}", MEDIA_SERVER_IMAGE); + System.exit(1); } - + commandLine.executeCommand(dockerRemoveCmd.replaceFirst("GREP_PARAMETER", grep)); } protected void restartMediaServer() { @@ -333,6 +359,7 @@ public class AbstractOpenViduTestAppE2eTest { try { Thread.sleep(1000); } catch (InterruptedException e) { + System.err.println("Error restarting media server"); e.printStackTrace(); } this.startMediaServer(); diff --git a/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/OpenViduTestAppE2eTest.java b/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/OpenViduTestAppE2eTest.java index 326d288b..e6e2b61d 100644 --- a/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/OpenViduTestAppE2eTest.java +++ b/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/OpenViduTestAppE2eTest.java @@ -31,11 +31,12 @@ import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import io.openvidu.java.client.*; -import io.openvidu.test.e2e.annotations.OnlyKurento; import org.apache.http.HttpStatus; import org.junit.Assert; -import org.junit.jupiter.api.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.openqa.selenium.Alert; import org.openqa.selenium.By; @@ -45,8 +46,6 @@ import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.ui.ExpectedCondition; import org.openqa.selenium.support.ui.ExpectedConditions; -import org.springframework.test.context.junit.jupiter.DisabledIf; -import org.springframework.test.context.junit.jupiter.EnabledIf; import org.springframework.test.context.junit.jupiter.SpringExtension; import com.google.gson.JsonArray; @@ -55,12 +54,29 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.mashape.unirest.http.HttpMethod; +import io.openvidu.java.client.Connection; +import io.openvidu.java.client.ConnectionProperties; +import io.openvidu.java.client.ConnectionType; +import io.openvidu.java.client.KurentoOptions; +import io.openvidu.java.client.MediaMode; +import io.openvidu.java.client.OpenVidu; +import io.openvidu.java.client.OpenViduHttpException; +import io.openvidu.java.client.OpenViduRole; +import io.openvidu.java.client.Publisher; +import io.openvidu.java.client.Recording; import io.openvidu.java.client.Recording.OutputMode; +import io.openvidu.java.client.RecordingLayout; +import io.openvidu.java.client.RecordingMode; +import io.openvidu.java.client.RecordingProperties; +import io.openvidu.java.client.Session; +import io.openvidu.java.client.SessionProperties; +import io.openvidu.java.client.VideoCodec; import io.openvidu.test.browsers.FirefoxUser; import io.openvidu.test.browsers.utils.CustomHttpClient; import io.openvidu.test.browsers.utils.RecordingUtils; import io.openvidu.test.browsers.utils.layout.CustomLayoutHandler; import io.openvidu.test.browsers.utils.webhook.CustomWebhook; +import io.openvidu.test.e2e.annotations.OnlyKurento; /** * E2E tests for openvidu-testapp. @@ -3228,7 +3244,6 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestAppE2eTest { @Test @DisplayName("Kurento reconnect test") - @Disabled void kurentoReconnectTest() throws Exception { isRecordingTest = true; isKurentoRestartTest = true; @@ -3248,7 +3263,6 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestAppE2eTest { // Connect one publisher with no connection to KMS user.getDriver().findElement(By.id("add-user-btn")).click(); - user.getDriver().findElement(By.className("subscribe-remote-check")).click(); user.getDriver().findElement(By.className("join-btn")).click(); user.getWaiter().until(ExpectedConditions.alertIsPresent()); @@ -3262,10 +3276,11 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestAppE2eTest { user.getDriver().findElement(By.id("remove-user-btn")).sendKeys(Keys.ENTER); this.startMediaServer(); - Thread.sleep(3000); + Thread.sleep(5000); - // Connect one subscriber with connection to KMS -> restart KMS -> connect a - // publisher -> restart KMS -> check streamDestroyed events + // Connect one subscriber with connection to KMS -> restart KMS -> -> check the + // session is still OK -> connect a publisher -> restart KMS -> check + // streamDestroyed events user.getDriver().findElement(By.id("add-user-btn")).click(); user.getDriver().findElements(By.className("publish-checkbox")).forEach(el -> el.click()); @@ -3278,7 +3293,7 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestAppE2eTest { Assert.assertEquals("Expected 1 active sessions but found " + sessions.size(), 1, sessions.size()); this.restartMediaServer(); - Thread.sleep(3000); + Thread.sleep(5000); OV.fetch(); sessions = OV.getActiveSessions(); @@ -3310,33 +3325,33 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestAppE2eTest { new RecordingProperties.Builder().outputMode(OutputMode.INDIVIDUAL).build()); user.getEventManager().waitUntilEventReaches("recordingStarted", 2); - long recStartTime = System.currentTimeMillis(); + Thread.sleep(5000); final CountDownLatch latch = new CountDownLatch(4); user.getEventManager().on("recordingStopped", (event) -> { String reason = event.get("reason").getAsString(); - Assert.assertEquals("Expected 'recordingStopped' reason 'mediaServerDisconnect'", "mediaServerDisconnect", + Assert.assertEquals("Expected 'recordingStopped' reason 'mediaServerReconnect'", "mediaServerReconnect", reason); latch.countDown(); }); user.getEventManager().on("streamDestroyed", (event) -> { String reason = event.get("reason").getAsString(); - Assert.assertEquals("Expected 'streamDestroyed' reason 'mediaServerDisconnect'", "mediaServerDisconnect", + Assert.assertEquals("Expected 'streamDestroyed' reason 'mediaServerReconnect'", "mediaServerReconnect", reason); latch.countDown(); }); - long recEndTime = System.currentTimeMillis(); this.restartMediaServer(); user.getEventManager().waitUntilEventReaches("recordingStopped", 2); user.getEventManager().waitUntilEventReaches("streamDestroyed", 2); if (!latch.await(5000, TimeUnit.MILLISECONDS)) { gracefullyLeaveParticipants(2); - fail("Waiting for 2 streamDestroyed events with reason 'mediaServerDisconnect' to happen in total"); + fail("Waiting for 2 recordingStopped and 2 streamDestroyed events with reason 'mediaServerReconnect' to happen in total"); return; } + user.getEventManager().off("recordingStopped"); user.getEventManager().off("streamDestroyed"); session.fetch(); @@ -3348,18 +3363,14 @@ public class OpenViduTestAppE2eTest extends AbstractOpenViduTestAppE2eTest { Assert.assertEquals("Expected no active subscribers but found " + subs, 0, subs); Recording rec = OV.getRecording("TestSession"); - double differenceInDuration = Math.abs(rec.getDuration() - ((recEndTime - recStartTime) / 1000)); - Assert.assertTrue("Recording duration exceeds valid value. Expected no more than 0.2 seconds, got " - + differenceInDuration, differenceInDuration < 0.2); + Assert.assertTrue("Recording duration is 0", rec.getDuration() > 0); + Assert.assertTrue("Recording size is 0", rec.getSize() > 0); this.recordingUtils.checkIndividualRecording("/opt/openvidu/recordings/TestSession/", rec, 1, "opus", "vp8", true); WebElement pubBtn = user.getDriver().findElements(By.cssSelector("#openvidu-instance-1 .pub-btn")).get(0); pubBtn.click(); - // This is not real, only in testapp (user is not streaming media after KMS - // restarted) - user.getEventManager().waitUntilEventReaches("streamDestroyed", 3); pubBtn.click(); user.getEventManager().waitUntilEventReaches("streamCreated", 4); user.getEventManager().waitUntilEventReaches("streamPlaying", 4); diff --git a/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/annotations/OnlyKurento.java b/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/annotations/OnlyKurento.java index edcdaf8d..78089d8a 100644 --- a/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/annotations/OnlyKurento.java +++ b/openvidu-test-e2e/src/test/java/io/openvidu/test/e2e/annotations/OnlyKurento.java @@ -11,7 +11,7 @@ import java.lang.annotation.Target; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) -@DisabledIf(expression = "#{systemProperties['MEDIA_SERVER'].toLowerCase().equals('mediasoup')}") +@DisabledIf(expression = "#{systemProperties['MEDIA_SERVER_IMAGE'].toLowerCase().contains('openvidu/mediasoup-controller')}") public @interface OnlyKurento { }