package edu.washington.cs.oneswarm.test.integration;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.fail;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.logging.Logger;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import edu.washington.cs.oneswarm.f2f.datagram.DatagramConnection;
import edu.washington.cs.oneswarm.f2f.servicesharing.EchoServer;
import edu.washington.cs.oneswarm.f2f.servicesharing.ServiceSharingManager;
import edu.washington.cs.oneswarm.test.util.TestUtils;
import edu.washington.cs.oneswarm.test.util.ThreeProcessTestBase;
public class ServiceSharingChannelReuseTest extends ThreeProcessTestBase {
private static final int SEARCH_KEY = ServiceSharingSingleProcessTest.SEARCH_KEY;
private final static int ECHO_PORT = ServiceSharingSingleProcessTest.ECHO_PORT;
private final static int CLIENT_PORT = ServiceSharingSingleProcessTest.CLIENT_PORT;
private final static String LOCALHOST = ServiceSharingSingleProcessTest.LOCALHOST;
private static Logger logger = Logger.getLogger(ServiceSharingChannelReuseTest.class.getName());
@BeforeClass
public static void setUpClass() throws Exception {
ThreeProcessTestBase.startSelenium = false;
ThreeProcessTestBase.setUpClass();
}
@Before
public void setupLogging() {
logFinest(logger);
logFinest(ServiceSharingSingleProcessTest.logger);
logFinest(EchoServer.logger);
logFinest(DatagramConnection.logger);
// logFinest(DatagramRateLimitedChannelQueue.logger);
// logFinest(ReadController.logger);
// logFinest(ServiceSharingManager.logger);
// logFinest(ServiceConnection.logger);
// logFinest(SearchManager.logger);
}
@Test
public void testChannelResuse() throws InterruptedException {
/*
* Test plan:
* * Start OneSwarm (done in setupClass())
* * Start a remote copy of oneswarm with this one as a friend
* * Register one server service on the remote instance
* * Register one client service in local instance
* * Set up a couple concurrent connections between client & server.
*/
try {
tellRemoteToShareService("echo", SEARCH_KEY, LOCALHOST, ECHO_PORT);
// Register the client service
ServiceSharingManager.getInstance().registerClientService("echoclient", CLIENT_PORT,
SEARCH_KEY);
Thread.sleep(5000);
doConcurrentEchoTest();
} catch (Exception e) {
e.printStackTrace();
logger.severe(e.toString());
fail();
} finally {
logger.info("End testServiceSharing()");
}
}
void doConcurrentEchoTest() throws UnknownHostException, IOException,
UnsupportedEncodingException, InterruptedException {
// Echo server.
EchoServer echoServer = new EchoServer(ECHO_PORT);
echoServer.startDeamonThread(true);
Socket s1 = new Socket(LOCALHOST, CLIENT_PORT);
// Talk.
writeReadVerify("t".getBytes("UTF-8"), s1);
Socket s2 = new Socket(LOCALHOST, CLIENT_PORT);
writeReadVerify("t".getBytes("UTF-8"), s2);
// test a couple of bytes
writeReadVerify("hello".getBytes("UTF-8"), s1);
writeReadVerify("multiplex!".getBytes("UTF-8"), s2);
writeReadVerify("message3!".getBytes("UTF-8"), s2);
s2.close();
// Make sure the channel doesn't get killed by closing connections.
writeReadVerify("goodbye".getBytes("UTF-8"), s1);
}
private void writeReadVerify(byte[] out, Socket s) throws IOException {
long startTime = System.currentTimeMillis();
InputStream inStream = s.getInputStream();
OutputStream outStream = s.getOutputStream();
outStream.write(out);
logger.finest("\n#######################\nwrote: " + out.length);
byte[] in = new byte[out.length];
int total = 0;
while (total < out.length) {
int value = inStream.read(in, total, out.length - total);
if (value == -1) {
break;
}
total += value;
logger.finest("\n#######################\nread: " + total);
}
logger.info("time=" + (System.currentTimeMillis() - startTime));
assertEquals(in, out);
}
private void tellRemoteToShareService(String name, long searchKey, String address, int port) {
processB.getCoordinator().addCommand(
"inject edu.washington.cs.oneswarm.test.integration.ServiceSharingExperiment");
processB.getCoordinator().addCommand(
"share_service " + name + " " + searchKey + " " + address + " " + port);
}
/** Boilerplate code for running as executable. */
public static void main(String[] args) throws Exception {
TestUtils.swtCompatibleTestRunner(ServiceSharingChannelReuseTest.class);
}
}