mirror of https://github.com/OpenVidu/openvidu.git
openvidu-test-e2e: EndReason test
parent
9cdca285a2
commit
c670bee1aa
|
@ -66,10 +66,9 @@ public enum EndReason {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The last participant left the session, which caused the session to be closed.
|
* The last participant left the session, which caused the session to be closed.
|
||||||
* Applies to events webrtcConnectionDestroyed, participantLeft,
|
* Applies to events recordingStatusChanged, broadcastStopped and
|
||||||
* recordingStatusChanged and sessionDestroyed. Can be triggered from other
|
* sessionDestroyed. Can be triggered from other events with other end reasons
|
||||||
* events with other end reasons (disconnect, forceDisconnectByUser,
|
* (disconnect, forceDisconnectByServer, networkDisconnect)
|
||||||
* forceDisconnectByServer, networkDisconnect)
|
|
||||||
*/
|
*/
|
||||||
lastParticipantLeft,
|
lastParticipantLeft,
|
||||||
|
|
||||||
|
@ -79,10 +78,16 @@ public enum EndReason {
|
||||||
*/
|
*/
|
||||||
recordingStoppedByServer,
|
recordingStoppedByServer,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The server application called the REST operation to stop a broadcast. Applies
|
||||||
|
* to event broadcastStopped
|
||||||
|
*/
|
||||||
|
broadcastStoppedByServer,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The server application called the REST operation to close a session. Applies
|
* The server application called the REST operation to close a session. Applies
|
||||||
* to events webrtcConnectionDestroyed, participantLeft, recordingStatusChanged
|
* to events webrtcConnectionDestroyed, participantLeft, recordingStatusChanged,
|
||||||
* and sessionDestroyed
|
* broadcastStopped and sessionDestroyed
|
||||||
*/
|
*/
|
||||||
sessionClosedByServer,
|
sessionClosedByServer,
|
||||||
|
|
||||||
|
@ -96,8 +101,8 @@ public enum EndReason {
|
||||||
/**
|
/**
|
||||||
* A media server disconnected. This is reserved for Media Nodes being
|
* A media server disconnected. This is reserved for Media Nodes being
|
||||||
* gracefully removed from an OpenVidu Pro cluster. Applies to events
|
* gracefully removed from an OpenVidu Pro cluster. Applies to events
|
||||||
* webrtcConnectionDestroyed, participantLeft, recordingStatusChanged and
|
* webrtcConnectionDestroyed, participantLeft, recordingStatusChanged,
|
||||||
* sessionDestroyed
|
* broadcastStopped and sessionDestroyed
|
||||||
*/
|
*/
|
||||||
mediaServerDisconnect,
|
mediaServerDisconnect,
|
||||||
|
|
||||||
|
@ -110,22 +115,24 @@ public enum EndReason {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A node has crashed. For now this means a Media Node has crashed. Applies to
|
* A node has crashed. For now this means a Media Node has crashed. Applies to
|
||||||
* events webrtcConnectionDestroyed, participantLeft, recordingStatusChanged and
|
* events webrtcConnectionDestroyed, participantLeft, recordingStatusChanged,
|
||||||
* sessionDestroyed
|
* broadcastStopped and sessionDestroyed
|
||||||
*/
|
*/
|
||||||
nodeCrashed,
|
nodeCrashed,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OpenVidu Server has gracefully stopped. This is reserved for OpenVidu Pro
|
* OpenVidu Server has gracefully stopped. This is reserved for OpenVidu Pro
|
||||||
* restart operation. Applies to events webrtcConnectionDestroyed,
|
* restart operation. Applies to events webrtcConnectionDestroyed,
|
||||||
* participantLeft, recordingStatusChanged and sessionDestroyed
|
* participantLeft, recordingStatusChanged, broadcastStopped and
|
||||||
|
* sessionDestroyed
|
||||||
*/
|
*/
|
||||||
openviduServerStopped,
|
openviduServerStopped,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A recording has been stopped automatically
|
* A recording has been stopped automatically
|
||||||
* (https://docs.openvidu.io/en/stable/advanced-features/recording/#automatic-stop-of-recordings).
|
* (https://docs.openvidu.io/en/stable/advanced-features/recording/#automatic-stop-of-recordings).
|
||||||
* Applies to event recordingStatusChanged
|
* Applies to event recordingStatusChanged and sessionDestroyed (in case the
|
||||||
|
* session was inactive except for the recording)
|
||||||
*/
|
*/
|
||||||
automaticStop
|
automaticStop
|
||||||
|
|
||||||
|
|
|
@ -192,7 +192,7 @@ public abstract class SessionManager {
|
||||||
public abstract void onUnsubscribeFromSpeechToText(Participant participant, Integer transactionId,
|
public abstract void onUnsubscribeFromSpeechToText(Participant participant, Integer transactionId,
|
||||||
String connectionId);
|
String connectionId);
|
||||||
|
|
||||||
public abstract void stopBroadcastIfNecessary(Session session);
|
public abstract void stopBroadcastIfNecessary(Session session, EndReason reason);
|
||||||
|
|
||||||
public void onEcho(String participantPrivateId, Integer requestId) {
|
public void onEcho(String participantPrivateId, Integer requestId) {
|
||||||
sessionEventsHandler.onEcho(participantPrivateId, requestId);
|
sessionEventsHandler.onEcho(participantPrivateId, requestId);
|
||||||
|
|
|
@ -262,6 +262,8 @@ public class KurentoSessionManager extends SessionManager {
|
||||||
// "SessionManager.closeSessionAndEmptyCollections"
|
// "SessionManager.closeSessionAndEmptyCollections"
|
||||||
if (!EndReason.sessionClosedByServer.equals(reason)) {
|
if (!EndReason.sessionClosedByServer.equals(reason)) {
|
||||||
|
|
||||||
|
final long autoStopTimeout = this.openviduConfig.getOpenviduRecordingAutostopTimeout();
|
||||||
|
|
||||||
if (remainingParticipants.isEmpty()) {
|
if (remainingParticipants.isEmpty()) {
|
||||||
if (this.recordingManager.sessionIsBeingRecorded(sessionId)) {
|
if (this.recordingManager.sessionIsBeingRecorded(sessionId)) {
|
||||||
// Start countdown to stop recording. Will be aborted if a Publisher starts
|
// Start countdown to stop recording. Will be aborted if a Publisher starts
|
||||||
|
@ -269,8 +271,9 @@ public class KurentoSessionManager extends SessionManager {
|
||||||
// recordings it would still remain a recorder participant
|
// recordings it would still remain a recorder participant
|
||||||
log.info(
|
log.info(
|
||||||
"Last participant left. Starting {} seconds countdown for stopping recording of session {}",
|
"Last participant left. Starting {} seconds countdown for stopping recording of session {}",
|
||||||
this.openviduConfig.getOpenviduRecordingAutostopTimeout(), sessionId);
|
autoStopTimeout, sessionId);
|
||||||
recordingManager.initAutomaticRecordingStopThread(session);
|
recordingManager.initAutomaticRecordingStopThread(session,
|
||||||
|
autoStopTimeout == 0 ? EndReason.lastParticipantLeft : EndReason.automaticStop);
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
if (session.closingLock.writeLock().tryLock(15, TimeUnit.SECONDS)) {
|
if (session.closingLock.writeLock().tryLock(15, TimeUnit.SECONDS)) {
|
||||||
|
@ -310,8 +313,10 @@ public class KurentoSessionManager extends SessionManager {
|
||||||
// RECORDER or STT participant is the last one standing. Start countdown
|
// RECORDER or STT participant is the last one standing. Start countdown
|
||||||
log.info(
|
log.info(
|
||||||
"Last participant left. Starting {} seconds countdown for stopping recording of session {}",
|
"Last participant left. Starting {} seconds countdown for stopping recording of session {}",
|
||||||
this.openviduConfig.getOpenviduRecordingAutostopTimeout(), sessionId);
|
autoStopTimeout, sessionId);
|
||||||
recordingManager.initAutomaticRecordingStopThread(session);
|
recordingManager.initAutomaticRecordingStopThread(session,
|
||||||
|
autoStopTimeout == 0 ? EndReason.lastParticipantLeft
|
||||||
|
: EndReason.automaticStop);
|
||||||
|
|
||||||
} else if (session.getSessionProperties().defaultRecordingProperties().outputMode()
|
} else if (session.getSessionProperties().defaultRecordingProperties().outputMode()
|
||||||
.equals(Recording.OutputMode.COMPOSED_QUICK_START)) {
|
.equals(Recording.OutputMode.COMPOSED_QUICK_START)) {
|
||||||
|
@ -329,7 +334,7 @@ public class KurentoSessionManager extends SessionManager {
|
||||||
&& remainingParticipants.stream().anyMatch(p -> p.isBroadcastParticipant());
|
&& remainingParticipants.stream().anyMatch(p -> p.isBroadcastParticipant());
|
||||||
|
|
||||||
if (broadcastParticipantLeft) {
|
if (broadcastParticipantLeft) {
|
||||||
this.stopBroadcastIfNecessary(session);
|
this.stopBroadcastIfNecessary(session, reason);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1425,7 +1430,7 @@ public class KurentoSessionManager extends SessionManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stopBroadcastIfNecessary(Session session) {
|
public void stopBroadcastIfNecessary(Session session, EndReason reason) {
|
||||||
}
|
}
|
||||||
|
|
||||||
private io.openvidu.server.recording.Recording getActiveRecordingIfAllowedByParticipantRole(
|
private io.openvidu.server.recording.Recording getActiveRecordingIfAllowedByParticipantRole(
|
||||||
|
|
|
@ -316,7 +316,7 @@ public class RecordingManager {
|
||||||
"No publisher in session {}. Starting {} seconds countdown for stopping recording",
|
"No publisher in session {}. Starting {} seconds countdown for stopping recording",
|
||||||
session.getSessionId(),
|
session.getSessionId(),
|
||||||
this.openviduConfig.getOpenviduRecordingAutostopTimeout());
|
this.openviduConfig.getOpenviduRecordingAutostopTimeout());
|
||||||
this.initAutomaticRecordingStopThread(session);
|
this.initAutomaticRecordingStopThread(session, EndReason.automaticStop);
|
||||||
}
|
}
|
||||||
return recording;
|
return recording;
|
||||||
}
|
}
|
||||||
|
@ -676,7 +676,7 @@ public class RecordingManager {
|
||||||
return recordingManagerUtils.getRecordingUrl(recording);
|
return recordingManagerUtils.getRecordingUrl(recording);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initAutomaticRecordingStopThread(final Session session) {
|
public void initAutomaticRecordingStopThread(final Session session, final EndReason reason) {
|
||||||
final String recordingId = this.sessionsRecordings.get(session.getSessionId()).getId();
|
final String recordingId = this.sessionsRecordings.get(session.getSessionId()).getId();
|
||||||
|
|
||||||
this.automaticRecordingStopThreads.computeIfAbsent(session.getSessionId(), f -> {
|
this.automaticRecordingStopThreads.computeIfAbsent(session.getSessionId(), f -> {
|
||||||
|
@ -695,12 +695,11 @@ public class RecordingManager {
|
||||||
}
|
}
|
||||||
if (session.getParticipants().size() == 0
|
if (session.getParticipants().size() == 0
|
||||||
|| session.onlyRecorderAndOrSttAndOrBroadcastParticipant()) {
|
|| session.onlyRecorderAndOrSttAndOrBroadcastParticipant()) {
|
||||||
// Close session if there are no participants connected (RECORDER/STT/BROADCAST do
|
// Close session if there are no participants connected (RECORDER/STT/BROADCAST
|
||||||
// not count) and publishing
|
// do not count) and publishing
|
||||||
log.info("Closing session {} after automatic stop of recording {}",
|
log.info("Closing session {} after automatic stop of recording {}",
|
||||||
session.getSessionId(), recordingId);
|
session.getSessionId(), recordingId);
|
||||||
sessionManager.closeSessionAndEmptyCollections(session, EndReason.automaticStop,
|
sessionManager.closeSessionAndEmptyCollections(session, reason, true);
|
||||||
true);
|
|
||||||
} else {
|
} else {
|
||||||
// There are users connected, but no one is publishing
|
// There are users connected, but no one is publishing
|
||||||
// We don't need the lock if session is not closing
|
// We don't need the lock if session is not closing
|
||||||
|
@ -709,7 +708,7 @@ public class RecordingManager {
|
||||||
log.info(
|
log.info(
|
||||||
"Automatic stopping recording {}. There are users connected to session {}, but no one is publishing",
|
"Automatic stopping recording {}. There are users connected to session {}, but no one is publishing",
|
||||||
recordingId, session.getSessionId());
|
recordingId, session.getSessionId());
|
||||||
this.stopRecording(session, recordingId, EndReason.automaticStop);
|
this.stopRecording(session, recordingId, reason);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
if (!alreadyUnlocked) {
|
if (!alreadyUnlocked) {
|
||||||
|
@ -750,8 +749,9 @@ public class RecordingManager {
|
||||||
if (session.getParticipants().size() == 0
|
if (session.getParticipants().size() == 0
|
||||||
|| session.onlyRecorderAndOrSttAndOrBroadcastParticipant()) {
|
|| session.onlyRecorderAndOrSttAndOrBroadcastParticipant()) {
|
||||||
// Close session if there are no participants connected (except for
|
// Close session if there are no participants connected (except for
|
||||||
// RECORDER/STT/BROADCAST). This code will only be executed if recording is manually
|
// RECORDER/STT/BROADCAST). This code will only be executed if recording is
|
||||||
// stopped during the automatic stop timeout, so the session must be also closed
|
// manually stopped during the automatic stop timeout, so the session must be
|
||||||
|
// also closed
|
||||||
log.info(
|
log.info(
|
||||||
"Ongoing recording of session {} was explicetly stopped within timeout for automatic recording stop. Closing session",
|
"Ongoing recording of session {} was explicetly stopped within timeout for automatic recording stop. Closing session",
|
||||||
session.getSessionId());
|
session.getSessionId());
|
||||||
|
|
|
@ -217,11 +217,9 @@ public abstract class RecordingService {
|
||||||
|
|
||||||
protected void uploadRecording(final Recording recording, EndReason reason) {
|
protected void uploadRecording(final Recording recording, EndReason reason) {
|
||||||
recordingUploader.uploadRecording(recording, () -> {
|
recordingUploader.uploadRecording(recording, () -> {
|
||||||
final long timestamp = System.currentTimeMillis();
|
cdr.recordRecordingStatusChanged(recording, reason, System.currentTimeMillis(), recording.getStatus());
|
||||||
cdr.recordRecordingStatusChanged(recording, reason, timestamp, recording.getStatus());
|
|
||||||
}, () -> {
|
}, () -> {
|
||||||
final long timestamp = System.currentTimeMillis();
|
cdr.recordRecordingStatusChanged(recording, reason, System.currentTimeMillis(),
|
||||||
cdr.recordRecordingStatusChanged(recording, reason, timestamp,
|
|
||||||
io.openvidu.java.client.Recording.Status.failed);
|
io.openvidu.java.client.Recording.Status.failed);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ public class CustomWebhook {
|
||||||
public static CountDownLatch initLatch;
|
public static CountDownLatch initLatch;
|
||||||
public static int accumulatedNumberOfEvents = 0;
|
public static int accumulatedNumberOfEvents = 0;
|
||||||
public final static ConcurrentMap<String, List<JsonObject>> accumulatedEvents = new ConcurrentHashMap<>();
|
public final static ConcurrentMap<String, List<JsonObject>> accumulatedEvents = new ConcurrentHashMap<>();
|
||||||
static final ConcurrentMap<String, BlockingQueue<JsonObject>> events = new ConcurrentHashMap<>();
|
public static final ConcurrentMap<String, BlockingQueue<JsonObject>> events = new ConcurrentHashMap<>();
|
||||||
static final BlockingQueue<JsonObject> eventsInOrder = new LinkedBlockingDeque<>();
|
static final BlockingQueue<JsonObject> eventsInOrder = new LinkedBlockingDeque<>();
|
||||||
|
|
||||||
public static void main(String[] args, CountDownLatch initLatch) {
|
public static void main(String[] args, CountDownLatch initLatch) {
|
||||||
|
|
|
@ -102,6 +102,11 @@
|
||||||
<artifactId>openvidu-java-client</artifactId>
|
<artifactId>openvidu-java-client</artifactId>
|
||||||
<version>${version.openvidu.java.client}</version>
|
<version>${version.openvidu.java.client}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.docker-java</groupId>
|
||||||
|
<artifactId>docker-java</artifactId>
|
||||||
|
<version>${version.dockerjava}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.testcontainers</groupId>
|
<groupId>org.testcontainers</groupId>
|
||||||
<artifactId>testcontainers</artifactId>
|
<artifactId>testcontainers</artifactId>
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
package io.openvidu.test.e2e;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.github.dockerjava.api.DockerClient;
|
||||||
|
import com.github.dockerjava.api.async.ResultCallback;
|
||||||
|
import com.github.dockerjava.api.command.ExecCreateCmdResponse;
|
||||||
|
import com.github.dockerjava.core.DefaultDockerClientConfig;
|
||||||
|
import com.github.dockerjava.core.DockerClientBuilder;
|
||||||
|
import com.github.dockerjava.core.DockerClientConfig;
|
||||||
|
import com.github.dockerjava.jaxrs.JerseyDockerHttpClient;
|
||||||
|
import com.github.dockerjava.transport.DockerHttpClient;
|
||||||
|
|
||||||
|
public class MediaNodeDockerUtils {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(MediaNodeDockerUtils.class);
|
||||||
|
|
||||||
|
public static void crashMediaNode(String containerId) {
|
||||||
|
log.info("Stopping Media Node container");
|
||||||
|
DockerClient dockerClient = getDockerClient();
|
||||||
|
dockerClient.removeContainerCmd(containerId).withForce(true).exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getMediaNodeIp(String containerId) {
|
||||||
|
DockerClient dockerClient = getDockerClient();
|
||||||
|
return dockerClient.inspectContainerCmd(containerId).exec().getNetworkSettings().getNetworks().get("bridge")
|
||||||
|
.getIpAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void crashMediaServerInsideMediaNode(String containerId) {
|
||||||
|
log.info("Stopping KMS container inside Media Node");
|
||||||
|
DockerClient dockerClient = getDockerClient();
|
||||||
|
ExecCreateCmdResponse execCreateCmdResponse = dockerClient.execCreateCmd(containerId).withAttachStdout(true)
|
||||||
|
.withAttachStderr(true).withCmd("bash", "-c", "docker rm -f kms").exec();
|
||||||
|
|
||||||
|
dockerClient.execStartCmd(execCreateCmdResponse.getId()).exec(new ResultCallback.Adapter<>() {
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void stopMediaServerInsideMediaNodeAndRecover(String containerId, int millisStop) {
|
||||||
|
log.info("Stopping and starting KMS container inside Media Node " + containerId + "waiting " + millisStop
|
||||||
|
+ " ms");
|
||||||
|
DockerClient dockerClient = getDockerClient();
|
||||||
|
ExecCreateCmdResponse execCreateCmdResponse = dockerClient.execCreateCmd(containerId).withAttachStdout(true)
|
||||||
|
.withAttachStderr(true)
|
||||||
|
.withCmd("bash", "-c", "docker stop kms && sleep " + (millisStop / 1000) + " && docker start kms")
|
||||||
|
.exec();
|
||||||
|
dockerClient.execStartCmd(execCreateCmdResponse.getId()).exec(new ResultCallback.Adapter<>() {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DockerClient getDockerClient() {
|
||||||
|
DockerClientConfig dockerClientConfig = DefaultDockerClientConfig.createDefaultConfigBuilder().build();
|
||||||
|
DockerHttpClient dockerHttpClient = new JerseyDockerHttpClient.Builder()
|
||||||
|
.dockerHost(dockerClientConfig.getDockerHost()).sslConfig(dockerClientConfig.getSSLConfig()).build();
|
||||||
|
return DockerClientBuilder.getInstance(dockerClientConfig).withDockerHttpClient(dockerHttpClient).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -210,6 +210,357 @@ public class OpenViduProTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Go through every EndReason and test that all affected entities trigger the
|
||||||
|
* required Webhook events when being destroyed for that specific reason. Check
|
||||||
|
* that "reason" property of every event is right and that there are no extra
|
||||||
|
* events triggered.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
@DisplayName("End reason")
|
||||||
|
void endReasonTest() throws Exception {
|
||||||
|
|
||||||
|
isRecordingTest = true;
|
||||||
|
|
||||||
|
log.info("End reason test");
|
||||||
|
|
||||||
|
CountDownLatch initLatch = new CountDownLatch(1);
|
||||||
|
io.openvidu.test.browsers.utils.webhook.CustomWebhook.main(new String[0], initLatch);
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
if (!initLatch.await(30, TimeUnit.SECONDS)) {
|
||||||
|
Assertions.fail("Timeout waiting for webhook springboot app to start");
|
||||||
|
CustomWebhook.shutDown();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomHttpClient restClient = new CustomHttpClient(OpenViduTestAppE2eTest.OPENVIDU_URL, "OPENVIDUAPP",
|
||||||
|
OpenViduTestAppE2eTest.OPENVIDU_SECRET);
|
||||||
|
JsonObject config = restClient.rest(HttpMethod.GET, "/openvidu/api/config", HttpURLConnection.HTTP_OK);
|
||||||
|
|
||||||
|
String defaultOpenViduWebhookEndpoint = null;
|
||||||
|
Integer defaultOpenViduRecordingAutostopTimeout = null;
|
||||||
|
if (config.has("OPENVIDU_WEBHOOK_ENDPOINT")) {
|
||||||
|
defaultOpenViduWebhookEndpoint = config.get("OPENVIDU_WEBHOOK_ENDPOINT").getAsString();
|
||||||
|
}
|
||||||
|
if (config.has("OPENVIDU_RECORDING_AUTOSTOP_TIMEOUT")) {
|
||||||
|
defaultOpenViduRecordingAutostopTimeout = config.get("OPENVIDU_RECORDING_AUTOSTOP_TIMEOUT").getAsInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
Map<String, Object> newConfig = Map.of("OPENVIDU_WEBHOOK", true, "OPENVIDU_WEBHOOK_ENDPOINT",
|
||||||
|
"http://127.0.0.1:7777/webhook", "OPENVIDU_RECORDING_AUTOSTOP_TIMEOUT", 0);
|
||||||
|
restartOpenViduServer(newConfig);
|
||||||
|
|
||||||
|
OpenViduTestappUser user = setupBrowserAndConnectToOpenViduTestapp("chrome");
|
||||||
|
|
||||||
|
// unsubscribe: webrtcConnectionDestroyed
|
||||||
|
this.connectTwoUsers(user, restClient, false, false, false);
|
||||||
|
user.getDriver().findElement(By.cssSelector("#openvidu-instance-1 .sub-btn")).click();
|
||||||
|
Assertions.assertEquals("unsubscribe",
|
||||||
|
CustomWebhook.waitForEvent("webrtcConnectionDestroyed", 2).get("reason").getAsString());
|
||||||
|
CustomWebhook.events.values().forEach(collection -> Assertions.assertTrue(collection.isEmpty()));
|
||||||
|
|
||||||
|
// unpublish: webrtcConnectionDestroyed
|
||||||
|
this.connectTwoUsers(user, restClient, false, false, false);
|
||||||
|
user.getDriver().findElement(By.cssSelector("#openvidu-instance-0 .pub-btn")).click();
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
Assertions.assertEquals("unpublish",
|
||||||
|
CustomWebhook.waitForEvent("webrtcConnectionDestroyed", 2).get("reason").getAsString());
|
||||||
|
}
|
||||||
|
CustomWebhook.events.values().forEach(collection -> Assertions.assertTrue(collection.isEmpty()));
|
||||||
|
|
||||||
|
// disconnect: webrtcConnectionDestroyed, participantLeft (and subsequent
|
||||||
|
// lastParticipantLeft triggered events for sessionDestroyed,
|
||||||
|
// recordingStatusChanged, [broadcastStopped])
|
||||||
|
this.connectTwoUsers(user, restClient, false, true, true);
|
||||||
|
// First user out
|
||||||
|
user.getDriver().findElement(By.cssSelector("#openvidu-instance-0 .leave-btn")).click();
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
Assertions.assertEquals("disconnect",
|
||||||
|
CustomWebhook.waitForEvent("webrtcConnectionDestroyed", 2).get("reason").getAsString());
|
||||||
|
}
|
||||||
|
Assertions.assertEquals("disconnect",
|
||||||
|
CustomWebhook.waitForEvent("participantLeft", 2).get("reason").getAsString());
|
||||||
|
// Second user out
|
||||||
|
user.getDriver().findElement(By.cssSelector("#openvidu-instance-1 .leave-btn")).click();
|
||||||
|
Assertions.assertEquals("disconnect",
|
||||||
|
CustomWebhook.waitForEvent("webrtcConnectionDestroyed", 2).get("reason").getAsString());
|
||||||
|
Assertions.assertEquals("disconnect",
|
||||||
|
CustomWebhook.waitForEvent("participantLeft", 2).get("reason").getAsString());
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
Assertions.assertEquals("lastParticipantLeft",
|
||||||
|
CustomWebhook.waitForEvent("recordingStatusChanged", 2).get("reason").getAsString());
|
||||||
|
}
|
||||||
|
Assertions.assertEquals("lastParticipantLeft",
|
||||||
|
CustomWebhook.waitForEvent("sessionDestroyed", 2).get("reason").getAsString());
|
||||||
|
CustomWebhook.events.values().forEach(collection -> Assertions.assertTrue(collection.isEmpty()));
|
||||||
|
|
||||||
|
// forceUnpublishByUser: webrtcConnectionDestroyed
|
||||||
|
this.connectTwoUsers(user, restClient, true, false, false);
|
||||||
|
user.getDriver().findElement(By.cssSelector("#openvidu-instance-0 .force-unpub-btn")).click();
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
Assertions.assertEquals("forceUnpublishByUser",
|
||||||
|
CustomWebhook.waitForEvent("webrtcConnectionDestroyed", 2).get("reason").getAsString());
|
||||||
|
}
|
||||||
|
CustomWebhook.events.values().forEach(collection -> Assertions.assertTrue(collection.isEmpty()));
|
||||||
|
|
||||||
|
// forceUnpublishByServer: webrtcConnectionDestroyed
|
||||||
|
this.connectTwoUsers(user, restClient, false, false, false);
|
||||||
|
String streamId = restClient
|
||||||
|
.rest(HttpMethod.GET, "/openvidu/api/sessions/TestSession", HttpURLConnection.HTTP_OK)
|
||||||
|
.get("connections").getAsJsonObject().get("content").getAsJsonArray().asList().stream()
|
||||||
|
.filter(con -> con.getAsJsonObject().get("role").getAsString().equals("PUBLISHER")).findFirst()
|
||||||
|
.get().getAsJsonObject().get("publishers").getAsJsonArray().get(0).getAsJsonObject()
|
||||||
|
.get("streamId").getAsString();
|
||||||
|
restClient.rest(HttpMethod.DELETE, "/openvidu/api/sessions/TestSession/stream/" + streamId,
|
||||||
|
HttpURLConnection.HTTP_NO_CONTENT);
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
Assertions.assertEquals("forceUnpublishByServer",
|
||||||
|
CustomWebhook.waitForEvent("webrtcConnectionDestroyed", 2).get("reason").getAsString());
|
||||||
|
}
|
||||||
|
CustomWebhook.events.values().forEach(collection -> Assertions.assertTrue(collection.isEmpty()));
|
||||||
|
|
||||||
|
// forceDisconnectByUser: webrtcConnectionDestroyed, participantLeft
|
||||||
|
this.connectTwoUsers(user, restClient, true, true, true);
|
||||||
|
user.getDriver().findElement(By.cssSelector("#openvidu-instance-0 .force-disconnect-btn")).click();
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
Assertions.assertEquals("forceDisconnectByUser",
|
||||||
|
CustomWebhook.waitForEvent("webrtcConnectionDestroyed", 2).get("reason").getAsString());
|
||||||
|
}
|
||||||
|
Assertions.assertEquals("forceDisconnectByUser",
|
||||||
|
CustomWebhook.waitForEvent("participantLeft", 2).get("reason").getAsString());
|
||||||
|
CustomWebhook.events.values().forEach(collection -> Assertions.assertTrue(collection.isEmpty()));
|
||||||
|
|
||||||
|
// forceDisconnectByServer: webrtcConnectionDestroyed, participantLeft (and
|
||||||
|
// subsequent lastParticipantLeft triggered events for sessionDestroyed,
|
||||||
|
// recordingStatusChanged, [broadcastStopped])
|
||||||
|
this.connectTwoUsers(user, restClient, false, true, true);
|
||||||
|
String[] connectionIds = restClient
|
||||||
|
.rest(HttpMethod.GET, "/openvidu/api/sessions/TestSession", HttpURLConnection.HTTP_OK)
|
||||||
|
.get("connections").getAsJsonObject().get("content").getAsJsonArray().asList().stream()
|
||||||
|
.map(con -> con.getAsJsonObject().get("connectionId").getAsString()).toArray(String[]::new);
|
||||||
|
// First user out
|
||||||
|
restClient.rest(HttpMethod.DELETE, "/openvidu/api/sessions/TestSession/connection/" + connectionIds[0],
|
||||||
|
HttpURLConnection.HTTP_NO_CONTENT);
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
Assertions.assertEquals("forceDisconnectByServer",
|
||||||
|
CustomWebhook.waitForEvent("webrtcConnectionDestroyed", 2).get("reason").getAsString());
|
||||||
|
}
|
||||||
|
Assertions.assertEquals("forceDisconnectByServer",
|
||||||
|
CustomWebhook.waitForEvent("participantLeft", 2).get("reason").getAsString());
|
||||||
|
// Second user out
|
||||||
|
restClient.rest(HttpMethod.DELETE, "/openvidu/api/sessions/TestSession/connection/" + connectionIds[1],
|
||||||
|
HttpURLConnection.HTTP_NO_CONTENT);
|
||||||
|
Assertions.assertEquals("forceDisconnectByServer",
|
||||||
|
CustomWebhook.waitForEvent("webrtcConnectionDestroyed", 2).get("reason").getAsString());
|
||||||
|
Assertions.assertEquals("forceDisconnectByServer",
|
||||||
|
CustomWebhook.waitForEvent("participantLeft", 2).get("reason").getAsString());
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
Assertions.assertEquals("lastParticipantLeft",
|
||||||
|
CustomWebhook.waitForEvent("recordingStatusChanged", 2).get("reason").getAsString());
|
||||||
|
}
|
||||||
|
Assertions.assertEquals("lastParticipantLeft",
|
||||||
|
CustomWebhook.waitForEvent("sessionDestroyed", 2).get("reason").getAsString());
|
||||||
|
CustomWebhook.events.values().forEach(collection -> Assertions.assertTrue(collection.isEmpty()));
|
||||||
|
|
||||||
|
// sessionClosedByServer: webrtcConnectionDestroyed, participantLeft,
|
||||||
|
// sessionDestroyed, recordingStatusChanged
|
||||||
|
this.connectTwoUsers(user, restClient, false, true, true);
|
||||||
|
restClient.rest(HttpMethod.DELETE, "/openvidu/api/sessions/TestSession",
|
||||||
|
HttpURLConnection.HTTP_NO_CONTENT);
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
Assertions.assertEquals("sessionClosedByServer",
|
||||||
|
CustomWebhook.waitForEvent("webrtcConnectionDestroyed", 2).get("reason").getAsString());
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
Assertions.assertEquals("sessionClosedByServer",
|
||||||
|
CustomWebhook.waitForEvent("participantLeft", 2).get("reason").getAsString());
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
Assertions.assertEquals("sessionClosedByServer",
|
||||||
|
CustomWebhook.waitForEvent("recordingStatusChanged", 2).get("reason").getAsString());
|
||||||
|
}
|
||||||
|
Assertions.assertEquals("sessionClosedByServer",
|
||||||
|
CustomWebhook.waitForEvent("sessionDestroyed", 2).get("reason").getAsString());
|
||||||
|
CustomWebhook.events.values().forEach(collection -> Assertions.assertTrue(collection.isEmpty()));
|
||||||
|
|
||||||
|
// networkDisconnect: webrtcConnectionDestroyed, participantLeft (and
|
||||||
|
// subsequent lastParticipantLeft triggered events for sessionDestroyed,
|
||||||
|
// recordingStatusChanged, [broadcastStopped])
|
||||||
|
this.connectTwoUsers(user, restClient, false, true, true);
|
||||||
|
// First user out
|
||||||
|
user.getDriver().findElement(By.cssSelector("#openvidu-instance-0 .network-drop-btn")).click();
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
Assertions.assertEquals("networkDisconnect",
|
||||||
|
CustomWebhook.waitForEvent("webrtcConnectionDestroyed", 20).get("reason").getAsString());
|
||||||
|
}
|
||||||
|
Assertions.assertEquals("networkDisconnect",
|
||||||
|
CustomWebhook.waitForEvent("participantLeft", 2).get("reason").getAsString());
|
||||||
|
// Second user out
|
||||||
|
user.getDriver().findElement(By.cssSelector("#openvidu-instance-1 .network-drop-btn")).click();
|
||||||
|
Assertions.assertEquals("networkDisconnect",
|
||||||
|
CustomWebhook.waitForEvent("webrtcConnectionDestroyed", 20).get("reason").getAsString());
|
||||||
|
Assertions.assertEquals("networkDisconnect",
|
||||||
|
CustomWebhook.waitForEvent("participantLeft", 2).get("reason").getAsString());
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
Assertions.assertEquals("lastParticipantLeft",
|
||||||
|
CustomWebhook.waitForEvent("recordingStatusChanged", 2).get("reason").getAsString());
|
||||||
|
}
|
||||||
|
Assertions.assertEquals("lastParticipantLeft",
|
||||||
|
CustomWebhook.waitForEvent("sessionDestroyed", 2).get("reason").getAsString());
|
||||||
|
CustomWebhook.events.values().forEach(collection -> Assertions.assertTrue(collection.isEmpty()));
|
||||||
|
|
||||||
|
// mediaServerDisconnect: webrtcConnectionDestroyed, participantLeft,
|
||||||
|
// sessionDestroyed, recordingStatusChanged, [broadcastStopped]
|
||||||
|
this.connectTwoUsers(user, restClient, false, true, true);
|
||||||
|
String mediaNodeId = restClient
|
||||||
|
.rest(HttpMethod.GET, "/openvidu/api/media-nodes", HttpURLConnection.HTTP_OK).get("content")
|
||||||
|
.getAsJsonArray().get(0).getAsJsonObject().get("id").getAsString();
|
||||||
|
restClient.rest(HttpMethod.DELETE,
|
||||||
|
"/openvidu/api/media-nodes/" + mediaNodeId + "?wait=false&deletion-strategy=now",
|
||||||
|
HttpURLConnection.HTTP_OK);
|
||||||
|
CustomWebhook.waitForEvent("mediaNodeStatusChanged", 3);
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
Assertions.assertEquals("mediaServerDisconnect",
|
||||||
|
CustomWebhook.waitForEvent("webrtcConnectionDestroyed", 20).get("reason").getAsString());
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
Assertions.assertEquals("mediaServerDisconnect",
|
||||||
|
CustomWebhook.waitForEvent("participantLeft", 2).get("reason").getAsString());
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
Assertions.assertEquals("mediaServerDisconnect",
|
||||||
|
CustomWebhook.waitForEvent("recordingStatusChanged", 4).get("reason").getAsString());
|
||||||
|
}
|
||||||
|
Assertions.assertEquals("mediaServerDisconnect",
|
||||||
|
CustomWebhook.waitForEvent("sessionDestroyed", 2).get("reason").getAsString());
|
||||||
|
CustomWebhook.waitForEvent("mediaNodeStatusChanged", 5);
|
||||||
|
CustomWebhook.events.values().forEach(collection -> Assertions.assertTrue(collection.isEmpty()));
|
||||||
|
restartOpenViduServer(new HashMap<>(), true, HttpURLConnection.HTTP_OK);
|
||||||
|
|
||||||
|
// mediaServerReconnect: webrtcConnectionDestroyed, recordingStatusChanged
|
||||||
|
this.connectTwoUsers(user, restClient, false, true, true);
|
||||||
|
String containerId = restClient
|
||||||
|
.rest(HttpMethod.GET, "/openvidu/api/media-nodes", HttpURLConnection.HTTP_OK).get("content")
|
||||||
|
.getAsJsonArray().get(0).getAsJsonObject().get("environmentId").getAsString();
|
||||||
|
MediaNodeDockerUtils.stopMediaServerInsideMediaNodeAndRecover(containerId, 400);
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
Assertions.assertEquals("mediaServerReconnect",
|
||||||
|
CustomWebhook.waitForEvent("webrtcConnectionDestroyed", 2).get("reason").getAsString());
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
Assertions.assertEquals("mediaServerReconnect",
|
||||||
|
CustomWebhook.waitForEvent("recordingStatusChanged", 2).get("reason").getAsString());
|
||||||
|
}
|
||||||
|
CustomWebhook.events.values().forEach(collection -> Assertions.assertTrue(collection.isEmpty()));
|
||||||
|
|
||||||
|
// nodeCrashed: webrtcConnectionDestroyed, participantLeft, sessionDestroyed,
|
||||||
|
// recordingStatusChanged, [broadcastStopped]
|
||||||
|
this.connectTwoUsers(user, restClient, false, true, true);
|
||||||
|
containerId = restClient.rest(HttpMethod.GET, "/openvidu/api/media-nodes", HttpURLConnection.HTTP_OK)
|
||||||
|
.get("content").getAsJsonArray().get(0).getAsJsonObject().get("environmentId").getAsString();
|
||||||
|
MediaNodeDockerUtils.crashMediaNode(containerId);
|
||||||
|
CustomWebhook.waitForEvent("nodeCrashed", 10);
|
||||||
|
CustomWebhook.waitForEvent("mediaNodeStatusChanged", 2);
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
Assertions.assertEquals("nodeCrashed",
|
||||||
|
CustomWebhook.waitForEvent("webrtcConnectionDestroyed", 2).get("reason").getAsString());
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
Assertions.assertEquals("nodeCrashed",
|
||||||
|
CustomWebhook.waitForEvent("participantLeft", 2).get("reason").getAsString());
|
||||||
|
}
|
||||||
|
// Only status "stopped" for recording. Not "ready" if node crash
|
||||||
|
Assertions.assertEquals("nodeCrashed",
|
||||||
|
CustomWebhook.waitForEvent("recordingStatusChanged", 2).get("reason").getAsString());
|
||||||
|
Assertions.assertEquals("nodeCrashed",
|
||||||
|
CustomWebhook.waitForEvent("sessionDestroyed", 2).get("reason").getAsString());
|
||||||
|
CustomWebhook.waitForEvent("mediaNodeStatusChanged", 2);
|
||||||
|
CustomWebhook.events.values().forEach(collection -> Assertions.assertTrue(collection.isEmpty()));
|
||||||
|
restartOpenViduServer(new HashMap<>(), true, HttpURLConnection.HTTP_OK);
|
||||||
|
|
||||||
|
// openviduServerStopped: webrtcConnectionDestroyed, participantLeft,
|
||||||
|
// sessionDestroyed, recordingStatusChanged, [broadcastStopped]
|
||||||
|
this.connectTwoUsers(user, restClient, false, true, true);
|
||||||
|
restartOpenViduServer(new HashMap<>(), true, HttpURLConnection.HTTP_OK);
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
Assertions.assertEquals("openviduServerStopped",
|
||||||
|
CustomWebhook.waitForEvent("webrtcConnectionDestroyed", 20).get("reason").getAsString());
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
Assertions.assertEquals("openviduServerStopped",
|
||||||
|
CustomWebhook.waitForEvent("participantLeft", 2).get("reason").getAsString());
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
Assertions.assertEquals("openviduServerStopped",
|
||||||
|
CustomWebhook.waitForEvent("recordingStatusChanged", 4).get("reason").getAsString());
|
||||||
|
}
|
||||||
|
Assertions.assertEquals("openviduServerStopped",
|
||||||
|
CustomWebhook.waitForEvent("sessionDestroyed", 2).get("reason").getAsString());
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
CustomWebhook.waitForEvent("mediaNodeStatusChanged", 15);
|
||||||
|
}
|
||||||
|
CustomWebhook.events.values().forEach(collection -> Assertions.assertTrue(collection.isEmpty()));
|
||||||
|
|
||||||
|
// automaticStop: sessionDestroyed, recordingStatusChanged
|
||||||
|
newConfig = Map.of("OPENVIDU_RECORDING_AUTOSTOP_TIMEOUT", 1);
|
||||||
|
restartOpenViduServer(newConfig);
|
||||||
|
this.connectTwoUsers(user, restClient, false, true, true);
|
||||||
|
user.getDriver().findElement(By.cssSelector("#openvidu-instance-0 .leave-btn")).click();
|
||||||
|
user.getDriver().findElement(By.cssSelector("#openvidu-instance-1 .leave-btn")).click();
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
Assertions.assertEquals("disconnect",
|
||||||
|
CustomWebhook.waitForEvent("webrtcConnectionDestroyed", 2).get("reason").getAsString());
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
Assertions.assertEquals("disconnect",
|
||||||
|
CustomWebhook.waitForEvent("participantLeft", 2).get("reason").getAsString());
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
Assertions.assertEquals("automaticStop",
|
||||||
|
CustomWebhook.waitForEvent("recordingStatusChanged", 4).get("reason").getAsString());
|
||||||
|
}
|
||||||
|
Assertions.assertEquals("automaticStop",
|
||||||
|
CustomWebhook.waitForEvent("sessionDestroyed", 2).get("reason").getAsString());
|
||||||
|
CustomWebhook.events.values().forEach(collection -> Assertions.assertTrue(collection.isEmpty()));
|
||||||
|
|
||||||
|
// recordingStoppedByServer
|
||||||
|
this.connectTwoUsers(user, restClient, false, true, true);
|
||||||
|
String recordingId = restClient
|
||||||
|
.rest(HttpMethod.GET, "/openvidu/api/recordings", HttpURLConnection.HTTP_OK).get("items")
|
||||||
|
.getAsJsonArray().asList().stream()
|
||||||
|
.filter(rec -> rec.getAsJsonObject().get("status").getAsString()
|
||||||
|
.equals(Recording.Status.started.name()))
|
||||||
|
.findFirst().get().getAsJsonObject().get("id").getAsString();
|
||||||
|
restClient.rest(HttpMethod.POST, "/openvidu/api/recordings/stop/" + recordingId,
|
||||||
|
HttpURLConnection.HTTP_OK);
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
Assertions.assertEquals("recordingStoppedByServer",
|
||||||
|
CustomWebhook.waitForEvent("recordingStatusChanged", 4).get("reason").getAsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
// [broadcastStoppedByServer]
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
Map<String, Object> oldConfig = new HashMap<>();
|
||||||
|
oldConfig.put("OPENVIDU_WEBHOOK", false);
|
||||||
|
if (defaultOpenViduWebhookEndpoint != null) {
|
||||||
|
oldConfig.put("OPENVIDU_WEBHOOK_ENDPOINT", defaultOpenViduWebhookEndpoint);
|
||||||
|
}
|
||||||
|
if (defaultOpenViduRecordingAutostopTimeout != null) {
|
||||||
|
oldConfig.put("OPENVIDU_RECORDING_AUTOSTOP_TIMEOUT", defaultOpenViduRecordingAutostopTimeout);
|
||||||
|
}
|
||||||
|
restartOpenViduServer(oldConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
CustomWebhook.shutDown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisplayName("Individual dynamic record")
|
@DisplayName("Individual dynamic record")
|
||||||
void individualDynamicRecordTest() throws Exception {
|
void individualDynamicRecordTest() throws Exception {
|
||||||
|
@ -2552,4 +2903,40 @@ public class OpenViduProTestAppE2eTest extends AbstractOpenViduTestappE2eTest {
|
||||||
sttUnsubUser(user, 0, 0, false, true);
|
sttUnsubUser(user, 0, 0, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void connectTwoUsers(OpenViduTestappUser user, CustomHttpClient restClient, boolean firstUserIsModerator,
|
||||||
|
boolean startRecording, boolean startBroadcast) throws Exception {
|
||||||
|
this.closeAllSessions(OV);
|
||||||
|
user.getDriver().findElement(By.id("remove-all-users-btn")).click();
|
||||||
|
user.getEventManager().clearAllCurrentEvents();
|
||||||
|
CustomWebhook.clean();
|
||||||
|
user.getDriver().findElement(By.id("add-user-btn")).click();
|
||||||
|
if (firstUserIsModerator) {
|
||||||
|
user.getDriver().findElement(By.id("session-settings-btn-0")).click();
|
||||||
|
Thread.sleep(500);
|
||||||
|
user.getDriver().findElement(By.id("radio-btn-mod")).click();
|
||||||
|
user.getDriver().findElement(By.id("save-btn")).click();
|
||||||
|
Thread.sleep(500);
|
||||||
|
}
|
||||||
|
user.getDriver().findElement(By.id("add-user-btn")).click();
|
||||||
|
user.getDriver().findElements(By.className("join-btn")).forEach(el -> el.sendKeys(Keys.ENTER));
|
||||||
|
user.getEventManager().waitUntilEventReaches("streamPlaying", 4);
|
||||||
|
CustomWebhook.waitForEvent("sessionCreated", 1);
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
CustomWebhook.waitForEvent("participantJoined", 1);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
CustomWebhook.waitForEvent("webrtcConnectionCreated", 1);
|
||||||
|
}
|
||||||
|
if (startRecording) {
|
||||||
|
restClient.rest(HttpMethod.POST, "/openvidu/api/recordings/start",
|
||||||
|
"{'session':'TestSession','outputMode':'INDIVIDUAL'}", HttpURLConnection.HTTP_OK);
|
||||||
|
user.getEventManager().waitUntilEventReaches("recordingStarted", 2);
|
||||||
|
Assertions.assertEquals(Recording.Status.started.name(),
|
||||||
|
CustomWebhook.waitForEvent("recordingStatusChanged", 3).get("status").getAsString());
|
||||||
|
}
|
||||||
|
if (startBroadcast) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,6 +124,9 @@
|
||||||
<button class="message-btn" (click)="sendMessage()" title="Broadcast message">
|
<button class="message-btn" (click)="sendMessage()" title="Broadcast message">
|
||||||
<mat-icon aria-label="Send message button" style="font-size: 20px">chat</mat-icon>
|
<mat-icon aria-label="Send message button" style="font-size: 20px">chat</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
|
<button class="network-drop-btn" (click)="simulateNetworkDrop()" title="Simulate network drop">
|
||||||
|
<mat-icon aria-label="Simulate network drop button" style="font-size: 20px">wifi_off</mat-icon>
|
||||||
|
</button>
|
||||||
<button class="leave-btn" (click)="leaveSession()" title="Leave session">
|
<button class="leave-btn" (click)="leaveSession()" title="Leave session">
|
||||||
<mat-icon aria-label="Leave button">clear</mat-icon>
|
<mat-icon aria-label="Leave button">clear</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -284,6 +284,11 @@ export class OpenviduInstanceComponent implements OnInit, OnChanges, OnDestroy {
|
||||||
this.subscribers = [];
|
this.subscribers = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private simulateNetworkDrop(): void {
|
||||||
|
const jsonRpClient = (this.OV as any).jsonRpcClient;
|
||||||
|
jsonRpClient.close();
|
||||||
|
}
|
||||||
|
|
||||||
updateEventList(eventName: string, eventContent: string, event: Event) {
|
updateEventList(eventName: string, eventContent: string, event: Event) {
|
||||||
const eventInterface: OpenViduEvent = { eventName, eventContent, event };
|
const eventInterface: OpenViduEvent = { eventName, eventContent, event };
|
||||||
this.events.push(eventInterface);
|
this.events.push(eventInterface);
|
||||||
|
|
Loading…
Reference in New Issue