package org.red5.client;
import static org.junit.Assert.assertTrue;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import org.apache.commons.lang3.RandomStringUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.red5.server.api.so.IClientSharedObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class RemoteSOTest {
private static Logger log = LoggerFactory.getLogger(RemoteSOTest.class);
private static boolean skipTest;
private int threads = 500;
static {
System.setProperty("red5.deployment.type", "junit");
}
@Before
public void setUp() throws Exception {
// skip the tests if red5 isnt listening
Socket s = null;
try {
s = new Socket();
SocketAddress sa = new InetSocketAddress("localhost", 1935);
s.connect(sa, 1000);
} catch (Exception e) {
//System.err.println(e.getMessage());
skipTest = true;
} finally {
if (s.isConnected()) {
s.close();
}
}
}
@After
public void tearDown() throws Exception {
}
@Test
public void testRemoteSO() throws Throwable {
// check for the presence of a red5 server or skip the test
if (!skipTest) {
// test runnables represent clients
List<SOClientWorker> tasks = new ArrayList<SOClientWorker>(threads);
for (int t = 0; t < threads; t++) {
tasks.add(new SOClientWorker(t));
}
ExecutorService executorService = Executors.newFixedThreadPool(threads);
// fires off threads
long start = System.nanoTime();
// invokeAll() blocks until all tasks have run...
List<Future<Object>> futures = executorService.invokeAll(tasks);
assertTrue(futures.size() == threads);
System.out.println("Runtime: " + (System.nanoTime() - start) + "ns");
for (SOClientWorker r : tasks) {
SOClientWorker cl = r;
log.debug("Worker: {}", cl.getId());
}
} else {
System.out.println("No red5 server detected for testing against");
}
}
private class SOClientWorker implements Callable<Object> {
int id;
volatile boolean running;
SharedObjectClient client;
IClientSharedObject so;
public SOClientWorker(int id) {
this.id = id;
}
@Override
public Object call() throws Exception {
log.debug("runTest#{}", id);
running = true;
client = new SharedObjectClient("localhost", 1935, "myapp", "myroom");
while (!client.isBandwidthCheckDone()) {
Thread.sleep(100L);
}
so = client.getSharedObject();
if (so != null) {
log.debug("Current so 'text' attribute: {}", so.getAttribute("text"));
so.beginUpdate();
so.setAttribute("text", RandomStringUtils.randomAlphabetic(16));
so.endUpdate();
} else {
log.debug("SO was null for client: {}", id);
}
Thread.sleep(100L);
client.disconnect();
running = false;
return null;
}
public int getId() {
return id;
}
@SuppressWarnings("unused")
public boolean isRunning() {
return running;
}
}
}