/*
* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
/*
* Created on Aug 13, 2005
*/
package org.jboss.test.remoting.transport.multiplex;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.net.BindException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import javax.net.SocketFactory;
import org.jboss.remoting.transport.multiplex.MasterServerSocket;
import org.jboss.remoting.transport.multiplex.MultiplexingManager;
import org.jboss.remoting.transport.multiplex.SocketId;
import org.jboss.remoting.transport.multiplex.VirtualSocket;
import org.jboss.remoting.transport.multiplex.VirtualSocketFactory;
/**
* A BasicBehaviorClient.
* @author <a href="mailto:r.sigal@computer.org">Ron Sigal</a>
* @version $Revision: 996 $
* <p>
* Copyright (c) 2005
* </p>
*/
public class BasicSocketBehaviorClient extends ShutdownClient implements MultiplexConstants
{
public void testSocketIds() throws Exception
{
try
{
byte[] script = new byte[] {CLOSE_TEST_SOCKET};
scriptStream.write(script.length);
scriptStream.write(script);
}
catch (IOException e1)
{
log.error(e1);
}
SocketId sid = new SocketId();
int port = sid.getPort();
int maxPort = port + 10;
SocketId.setMaxPort(maxPort);
for (int i = port + 1; i <= maxPort; i++)
new SocketId().releasePort();
sid = new SocketId();
sid.releasePort();
assertTrue(sid.getPort() == port + 1);
for (int i = port + 2; i <= maxPort; i++)
new SocketId().releasePort();
sid = new SocketId();
assertTrue(sid.getPort() == port + 1);
for (int i = port + 2; i <= maxPort; i++)
new SocketId();
class TestThread extends Thread
{
SocketId s;
SocketId getS() {return s;}
public void run()
{
s = new SocketId();
}
};
TestThread t = new TestThread();
t.start();
assertNull(t.getS());
sid.releasePort();
Thread.sleep(1000);
assertTrue(t.getS().getPort() == port + 1);
SocketId.setMaxPort(Integer.MAX_VALUE - 1);
log.info("testSocketIds() PASSES");
}
/**
* If underlying InputStream gets EOF, virtual InputStream should indicate EOF.
*
*/
public void testSocketEOF()
{
log.info("entering testSocketEOF()");
try
{
byte[] script = new byte[] {CLOSE_TEST_SOCKET};
scriptStream.write(script.length);
scriptStream.write(script);
}
catch (IOException e1)
{
log.error(e1);
}
class ServerThread extends Thread
{
public void run()
{
try
{
MasterServerSocket ss = new MasterServerSocket(5343);
VirtualSocket s = (VirtualSocket) ss.accept();
Thread.sleep(2000);
s.getMultiplexingManager().getSocket().close();
s.close();
ss.close();
}
catch (Exception e)
{
log.error(e);
}
}
}
try
{
new ServerThread().start();
Thread.sleep(1000);
VirtualSocket s = new VirtualSocket("localhost", 5343);
is = s.getInputStream();
assertTrue(is.read() == -1);
s.close();
}
catch (Exception e)
{
log.error(e);
}
log.info("testSocketEOF() PASSES");
}
public void testDisconnectCallbacks()
{
class LocalDisconnectListener implements VirtualSocket.DisconnectListener
{
private boolean notified;
private VirtualSocket vs;
public void notifyDisconnected(VirtualSocket vs) {this.vs = vs; notified = true;}
public VirtualSocket getVirtualSocket() {return vs;}
public boolean isNotified() {return notified;}
}
log.info("entering testDisconnectCallbacks()");
try
{
byte[] script = new byte[] {READ, SHUTDOWN_OUTPUT, READ, CLOSE_TEST_SOCKET};
scriptStream.write(script.length);
scriptStream.write(script);
}
catch (IOException e1)
{
log.error(e1);
}
try
{
LocalDisconnectListener listener = new LocalDisconnectListener();
((VirtualSocket) testSocket).addDisconnectListener(listener);
assertFalse(listener.isNotified());
os = testSocket.getOutputStream();
// Tell server to shut down output.
os.write(3);
assertFalse(listener.isNotified());
// Tell server to close socket.
os.write(5);
for (int i = 0; i < 3; i++)
{
Thread.sleep((i + 1) * 2000);
if (listener.isNotified())
break;
}
assertTrue(listener.isNotified());
assertTrue(testSocket == listener.getVirtualSocket());
}
catch (Exception e)
{
log.error(e);
e.printStackTrace();
fail();
}
log.info("testDisconnectCallbacks() PASSES");
}
/**
* FIXME Comment this
*
*
*/
public void testVirtualSocketConstructors()
{
log.info("entering testVirtualSocketConstructors()");
try
{
// This script is for server thread created for testSocket,
// which we don't use in this test.
byte[] script = new byte[] {CLOSE_TEST_SOCKET};
scriptStream.write(script.length);
scriptStream.write(script);
}
catch (IOException e1)
{
log.error(e1);
}
try
{
while (true)
{
try
{
int localPort = random.nextInt() & 0xffff;
VirtualSocket socket1 = new VirtualSocket();
socket1.bind(new InetSocketAddress(localPort));
socket1.connect(basicBehaviorServerSocketAddress);
assertTrue(doOneConstructorTest(socket1, localPort));
break;
}
catch (BindException e)
{
log.info("looking for a free socket");
}
}
}
catch (Exception e)
{
log.error(e);
e.printStackTrace();
fail();
}
try
{
VirtualSocket socket2 = new VirtualSocket(basicBehaviorServerHost , basicBehaviorServerPort);
assertTrue(doOneConstructorTest(socket2, socket2.getLocalPort()));
}
catch (Exception e)
{
log.error(e);
e.printStackTrace();
fail();
}
try
{
VirtualSocket socket3 = new VirtualSocket(basicBehaviorServerHost , basicBehaviorServerPort, false);
fail();
}
catch (SocketException e)
{
assertTrue(e.getMessage().equals("Deprecated: use DataGramSocket instead of stream = false"));
}
catch (Exception e)
{
log.error(e);
e.printStackTrace();
fail();
}
try
{
VirtualSocket socket4 = new VirtualSocket(basicBehaviorServerHost , basicBehaviorServerPort, true);
assertTrue(doOneConstructorTest(socket4, socket4.getLocalPort()));
}
catch (Exception e)
{
log.error(e);
e.printStackTrace();
fail();
}
try
{
InetAddress inetAddress = InetAddress.getByName(basicBehaviorServerHost);
VirtualSocket socket5 = new VirtualSocket(inetAddress , basicBehaviorServerPort);
assertTrue(doOneConstructorTest(socket5, socket5.getLocalPort()));
}
catch (Exception e)
{
log.error(e);
e.printStackTrace();
fail();
}
try
{
InetAddress inetAddress = InetAddress.getByName(basicBehaviorServerHost);
VirtualSocket socket6 = new VirtualSocket(inetAddress , basicBehaviorServerPort, false);
fail();
}
catch (SocketException e)
{
assertTrue(e.getMessage().equals("Deprecated: use DataGramSocket instead of stream = false"));
}
catch (Exception e)
{
log.error(e);
e.printStackTrace();
fail();
}
try
{
InetAddress inetAddress = InetAddress.getByName(basicBehaviorServerHost);
VirtualSocket socket7 = new VirtualSocket(inetAddress , basicBehaviorServerPort, true);
assertTrue(doOneConstructorTest(socket7, socket7.getLocalPort()));
}
catch (Exception e)
{
log.error(e);
e.printStackTrace();
fail();
}
try
{
while (true)
{
try
{
int localPort = random.nextInt() & 0xffff;
InetAddress inetAddress = InetAddress.getByName("localhost");
VirtualSocket socket8 = new VirtualSocket(basicBehaviorServerHost, basicBehaviorServerPort, inetAddress , localPort);
assertTrue(doOneConstructorTest(socket8, localPort));
break;
}
catch (BindException e)
{
log.info("looking for a free socket");
}
}
}
catch (Exception e)
{
log.error(e);
e.printStackTrace();
fail();
}
try
{
while (true)
{
try
{
int localPort = random.nextInt() & 0xffff;
InetAddress remoteAddress = InetAddress.getByName(basicBehaviorServerHost);
InetAddress localAddress = InetAddress.getByName("localhost");
VirtualSocket socket9 = new VirtualSocket(remoteAddress, basicBehaviorServerPort, localAddress , localPort);
assertTrue(doOneConstructorTest(socket9, localPort));
break;
}
catch (BindException e)
{
log.info("looking for a free socket");
}
}
}
catch (Exception e)
{
log.error(e);
e.printStackTrace();
fail();
}
log.info("testVirtualSocketConstructors() PASSES");
}
/**
* FIXME Comment this
*
*
*/
protected boolean doOneConstructorTest(VirtualSocket socket, int localPort)
{
boolean success = true;
try
{
byte[] script = new byte[] {READ, CLOSE_TEST_SOCKET};
scriptStream.write(script.length);
scriptStream.write(script);
}
catch (IOException e1)
{
e1.printStackTrace();
log.error(e1);
}
assertTrue(socket.isBound());
assertTrue(socket.isConnected());
assertTrue(socket.getLocalPort() == localPort);
assertTrue(socket.getPort() == basicBehaviorServerPort);
try
{
InetAddress localAddress = InetAddress.getByName("localhost");
InetSocketAddress localSocketAddress = new InetSocketAddress(localAddress, localPort);
InetAddress ia = socket.getLocalAddress();
assertTrue(socket.getLocalAddress().equals(localAddress));
assertTrue(socket.getLocalSocketAddress().equals(localSocketAddress));
}
catch (UnknownHostException e)
{
e.printStackTrace();
log.error(e);
fail();
}
try
{
InetAddress remoteAddress = InetAddress.getByName(basicBehaviorServerHost);
assertTrue(socket.getInetAddress().equals(remoteAddress));
assertTrue(socket.getRemoteSocketAddress().equals(basicBehaviorServerSocketAddress));
}
catch (UnknownHostException e)
{
e.printStackTrace();
log.error(e);
fail();
}
try
{
// end script on server
os = socket.getOutputStream();
os.write(3);
}
catch (IOException e)
{
e.printStackTrace();
log.error(e);
fail();
}
try
{
socket.close();
}
catch (IOException e)
{
e.printStackTrace();
log.error(e);
fail();
}
return success;
}
/**
* FIXME Comment this
*
*
*/
public void testArrayRead()
{
log.info("entering testArrayRead()");
try
{
byte[] script = new byte[]
{
READ,
WRITE,
READ,
WRITE,
READ,
WRITE,
READ,
WRITE,
READ,
WRITE,
CLOSE_TEST_SOCKET
}
;
scriptStream.write(script.length);
scriptStream.write(script);
is = testSocket.getInputStream();
os = testSocket.getOutputStream();
os.write(3);
os.write(5);
os.write(7);
os.write(9);
os.write(11);
while(is.available() < 3)
try
{
Thread.sleep(500);
}
catch (InterruptedException e) {}
byte[] bytes = new byte[3];
int n = is.read(bytes, 0, 3);
log.info("n = " + n);
assertTrue(n == 3);
assertTrue(bytes[0] == 3);
assertTrue(bytes[1] == 5);
assertTrue(bytes[2] == 7);
while(is.available() < 2)
try
{
Thread.sleep(500);
}
catch (InterruptedException e) {}
n = is.read(bytes, 1, 2);
log.info("n = " + n);
assertTrue(n == 2);
assertTrue(bytes[1] == 9);
assertTrue(bytes[2] == 11);
}
catch (Throwable t)
{
t.printStackTrace();
log.error(t);
fail();
}
log.info("testArrayRead() PASSES");
}
/**
* FIXME Comment this
*
*
*/
public void testSkip()
{
log.info("entering testSkip()");
try
{
byte[] script = new byte[]
{
READ,
WRITE,
READ,
WRITE,
READ,
WRITE,
READ,
WRITE,
READ,
WRITE,
READ,
WRITE,
READ,
WRITE,
READ,
WRITE,
READ,
CLOSE_TEST_SOCKET
};
scriptStream.write(script.length);
scriptStream.write(script);
is = testSocket.getInputStream();
os = testSocket.getOutputStream();
assertTrue(is.skip(-1) == 0);
log.info("skip 1");
os.write(3);
os.write(5);
os.write(7);
os.write(9);
assertTrue(is.read() == 3);
int k = (int) is.skip(2);
if (k == 1)
is.skip(1);
log.info("skip 2");
assertTrue(is.read() == 9);
os.write(11);
os.write(13);
os.write(15);
os.write(17);
assertTrue(is.read() == 11);
k = (int) is.skip(2);
if (k == 1)
is.skip(1);
log.info("skip 3");
assertTrue(is.read() == 17);
try
{
testSocket.setSoTimeout(1000);
log.info("" + is.skip(1));
fail();
}
catch (Exception e)
{
log.info("skip 4");
assertTrue(e instanceof SocketTimeoutException && e.getMessage().equals("Read timed out"));
}
os.write(19);
// Give remote socket a chance to close.
try
{
Thread.sleep(2000);
}
catch (InterruptedException ignored) {}
assertTrue(is.skip(1) == 0);
log.info("skip 5");
}
catch (Throwable t)
{
t.printStackTrace();
log.error(t);
fail();
}
log.info("testSkip() PASSES");
}
/**
* FIXME Comment this
*
* @throws Exception
*/
public void testLocalInputShutdown() throws Exception
{
log.info("entering testLocalInputShutdown()");
try
{
byte[] script = new byte[] {READ, WRITE, READ, READ, CLOSE_TEST_SOCKET};
scriptStream.write(script.length);
scriptStream.write(script);
is = testSocket.getInputStream();
os = testSocket.getOutputStream();
os.write(3);
int b = is.read();
assertTrue(b == 3);
testSocket.shutdownInput();
assertTrue(testSocket.isConnected());
assertTrue(testSocket.isBound());
assertTrue(!testSocket.isClosed());
assertTrue(testSocket.isInputShutdown());
assertTrue(!testSocket.isOutputShutdown());
b = is.read();
assertTrue(b == -1);
os.write(5);
os = testSocket.getOutputStream();
os.write(7);
testSocket.shutdownOutput();
}
catch (Throwable t)
{
t.printStackTrace();
log.error(t);
fail();
}
try
{
testSocket.getInputStream();
fail();
}
catch (SocketException e)
{
assertTrue(e.getMessage().equals("Socket input is shutdown"));
}
catch (Throwable t)
{
t.printStackTrace();
log.error(t);
fail();
}
try
{
testSocket.shutdownInput();
fail();
}
catch (SocketException e)
{
assertTrue(e.getMessage().equals("Socket input is already shutdown"));
}
catch (Throwable t)
{
t.printStackTrace();
log.error(t);
fail();
}
log.info("testLocalInputShutdown() PASSES");
}
public void testLocalOutputShutdown() throws Exception
{
log.info("entering testLocalOutputShutdown()");
try
{
byte[] script = new byte[] {READ, WRITE, READ, WRITE, CLOSE_TEST_SOCKET};
scriptStream.write(script.length);
scriptStream.write(script);
is = testSocket.getInputStream();
os = testSocket.getOutputStream();
os.write(3);
os.write(5);
int b = is.read();
assertTrue(b == 3);
testSocket.shutdownOutput();
assertTrue(testSocket.isConnected());
assertTrue(testSocket.isBound());
assertTrue(!testSocket.isClosed());
assertTrue(!testSocket.isInputShutdown());
assertTrue( testSocket.isOutputShutdown());
is = testSocket.getInputStream();
b = is.read();
assertTrue(b == 5);
testSocket.shutdownInput();
}
catch (Exception e)
{
e.printStackTrace();
log.error(e);
fail();
}
try
{
// Note. Real sockets allow the first write to succeed. Is this important?
os.write(5);
log.error("write() should have failed");
fail();
}
catch (SocketException e)
{
log.debug(e);
assertTrue(e.getMessage().equals("Broken pipe"));
}
catch (Exception e)
{
e.printStackTrace();
log.error(e);
fail();
}
try
{
testSocket.getInputStream();
log.error("getInputStream() should have failed");
fail();
}
catch (SocketException e)
{
log.debug(e);
assertTrue(e.getMessage().equals("Socket input is shutdown"));
}
catch (Exception e)
{
e.printStackTrace();
log.error(e);
fail();
}
try
{
testSocket.shutdownOutput();
log.error("shutdownOutput() should have failed");
fail();
}
catch (SocketException e)
{
log.debug(e);
assertTrue(e.getMessage().equals("Socket output is already shutdown"));
}
log.info("testLocalOutputShutdown() PASSES");
}
class LocalSocketCloseThread extends Thread
{
Socket socket;
boolean success = false;
boolean done = false;
LocalSocketCloseThread(Socket socket) {this.socket = socket;}
boolean getSuccess() {return success;}
void setDone() {done = true;}
public void run()
{
synchronized (this)
{
notifyAll();
}
try
{
InputStream is = socket.getInputStream();
log.info("" + is.read());
}
catch (IOException e)
{
log.debug(e);
success = e.getMessage().equals("Socket closed");
}
while (!done)
{
try
{
Thread.sleep(500);
}
catch (InterruptedException ignored) {}
synchronized (this)
{
notifyAll();
}
}
}
}
/**
* FIXME Comment this
*
* @throws Exception
*/
public void testLocalSocketClose() throws Exception
{
log.info("entering testLocalSocketClose()");
try
{
byte[] script = new byte[] {READ, WRITE, SLEEP, 0x10, 0x00, CLOSE_TEST_SOCKET};
scriptStream.write(script.length);
scriptStream.write(script);
is = testSocket.getInputStream();
os = testSocket.getOutputStream();
os.write(3);
assertTrue((is.read() == 3));
LocalSocketCloseThread t = new LocalSocketCloseThread(testSocket);
t.start();
Thread.sleep(2000);
testSocket.close();
synchronized (t)
{
t.wait(4000);
}
t.setDone();
assertTrue(t.getSuccess());
assertTrue(testSocket.isConnected());
assertTrue(testSocket.isBound());
assertTrue(testSocket.isClosed());
assertTrue(!testSocket.isInputShutdown());
assertTrue(!testSocket.isOutputShutdown());
}
catch (Exception e)
{
e.printStackTrace();
log.error(e);
fail();
}
try
{
int b = is.read();
// read() should have failed
fail();
}
catch (SocketException e)
{
log.debug(e);
assertTrue(e.getMessage().equals("Socket closed"));
}
catch (Exception e)
{
e.printStackTrace();
log.error(e);
fail();
}
try
{
// Note. Real sockets allow the first write to succeed. Is this important?
os.write(7);
log.error("write() should have failed");
fail();
}
catch (SocketException e)
{
log.debug(e);
assertTrue(e.getMessage().equals("Socket closed"));
}
catch (Exception e)
{
e.printStackTrace();
log.error(e);
fail();
}
try
{
testSocket.getInputStream();
log.error("getInputStream() should have failed");
fail();
}
catch (SocketException e)
{
log.debug(e);
assertTrue(e.getMessage().equals("Socket is closed"));
}
catch (Exception e)
{
e.printStackTrace();
log.error(e);
fail();
}
try
{
testSocket.getOutputStream();
log.error("getOutputStream() should have failed");
fail();
}
catch (SocketException e)
{
log.debug(e);
assertTrue(e.getMessage().equals("Socket is closed"));
}
catch (Exception e)
{
e.printStackTrace();
log.error(e);
fail();
}
try
{
testSocket.shutdownInput();
log.error("shutdownInput() should have failed");
fail();
}
catch (SocketException e)
{
log.debug(e);
assertTrue(e.getMessage().equals("Socket is closed"));
}
catch (Exception e)
{
e.printStackTrace();
log.error(e);
fail();
}
try
{
testSocket.shutdownOutput();
log.error("shutdownOutput() should have failed");
fail();
}
catch (SocketException e)
{
log.debug(e);
assertTrue(e.getMessage().equals("Socket is closed"));
}
catch (Exception e)
{
e.printStackTrace();
log.error(e);
fail();
}
log.info("testLocalSocketClose() PASSES");
}
/**
* FIXME Comment this
*
* @throws Exception
*/
public void testRemoteInputShutdown() throws Exception
{
log.info("entering testRemoteInputShutdown()");
try
{
byte[] script = new byte[]
{
READ,
WRITE,
READ,
SHUTDOWN_INPUT,
WRITE,
SLEEP, 0x08, 0x00, // sleep 2048 milliseconds
CLOSE_TEST_SOCKET
};
scriptStream.write(script.length);
scriptStream.write(script);
is = testSocket.getInputStream();
os = testSocket.getOutputStream();
os.write(3);
int b = is.read();
assertTrue(b == 3);
assertTrue(testSocket.isConnected());
assertTrue(testSocket.isBound());
assertTrue(!testSocket.isClosed());
assertTrue(!testSocket.isInputShutdown());
assertTrue(!testSocket.isOutputShutdown());
os.write(5);
// remote socket will shut down input after reading 5
assertTrue(testSocket.isConnected());
assertTrue(testSocket.isBound());
assertTrue(!testSocket.isClosed());
assertTrue(!testSocket.isInputShutdown());
assertTrue(!testSocket.isOutputShutdown());
b = is.read();
assertTrue(b == 5);
os.write(7);
is = testSocket.getInputStream();
os = testSocket.getOutputStream();
os.write(11);
testSocket.shutdownInput();
testSocket.shutdownOutput();
testSocket.close();
}
catch (Throwable t)
{
t.printStackTrace();
log.error(t);
fail();
}
log.info("testRemoteInputShutdown() PASSES");
}
/**
* FIXME Comment this
*
* @throws Exception
*/
public void testRemoteOutputShutdown() throws Exception
{
log.info("entering testRemoteOutputShutdown()");
try
{
byte[] script = new byte[] {READ, WRITE, READ, WRITE, READ, SHUTDOWN_OUTPUT, READ, CLOSE_TEST_SOCKET};
scriptStream.write(script.length);
scriptStream.write(script);
is = testSocket.getInputStream();
os = testSocket.getOutputStream();
os.write(3);
int b = is.read();
assertTrue(b == 3);
os.write(5);
assertTrue(testSocket.isConnected());
assertTrue(testSocket.isBound());
assertTrue(!testSocket.isClosed());
assertTrue(!testSocket.isInputShutdown());
assertTrue(!testSocket.isOutputShutdown());
os.write(7);
Thread.sleep(5000);
// remote socket will shut down output after reading 7
assertTrue(testSocket.isConnected());
assertTrue(testSocket.isBound());
assertTrue(!testSocket.isClosed());
assertTrue(!testSocket.isInputShutdown());
assertTrue(!testSocket.isOutputShutdown());
b = is.read();
assertTrue(b == 5);
is = testSocket.getInputStream();
os = testSocket.getOutputStream();
b = is.read();
assertTrue(b == -1);
os.write(9);
}
catch (Throwable t)
{
t.printStackTrace();
log.error(t);
fail();
}
log.info("testRemoteOutputShutdown() PASSES");
}
/**
* FIXME Comment this
*
* @throws Exception
*/
public void testRemoteSocketClose() throws Exception
{
log.info("entering testRemoteSocketClose()");
try
{
byte[] script = new byte[] {READ, WRITE, CLOSE_TEST_SOCKET};
scriptStream.write(script.length);
scriptStream.write(script);
is = testSocket.getInputStream();
os = testSocket.getOutputStream();
assertTrue(testSocket.isConnected());
assertTrue(testSocket.isBound());
assertTrue(!testSocket.isClosed());
assertTrue(!testSocket.isInputShutdown());
assertTrue(!testSocket.isOutputShutdown());
os.write(3);
// give remote socket time to close
Thread.sleep(4000);
int b = is.read();
assertTrue(b == 3);
assertTrue(testSocket.isConnected());
assertTrue(testSocket.isBound());
assertTrue(!testSocket.isClosed());
assertTrue(!testSocket.isInputShutdown());
assertTrue(!testSocket.isOutputShutdown());
is = testSocket.getInputStream();
os = testSocket.getOutputStream();
b = is.read();
assertTrue(b == -1);
}
catch (Throwable t)
{
log.error(t);
t.printStackTrace();
fail();
}
try
{
// remote socket should be closed by now, but just in case ...
Thread.sleep(1000);
os.write(5);
try
{
os.write(7);
fail();
}
catch (SocketException e)
{
assertTrue(e.getMessage().equals("Broken pipe"));
}
try
{
os.write(11);
fail();
}
catch (SocketException e)
{
assertTrue(e.getMessage().equals("Broken pipe"));
}
}
catch (Throwable t)
{
t.printStackTrace();
log.error(t);
fail();
}
log.info("testRemoteSocketClose() PASSES");
}
/**
* FIXME Comment this
*
*
*/
public void testSocketFactory()
{
log.info("entering testSocketFactory()");
try
{
// This script is for server thread created for testSocket,
// which we don't use in this test.
byte[] script = new byte[] {CLOSE_TEST_SOCKET};
scriptStream.write(script.length);
scriptStream.write(script);
}
catch (IOException e1)
{
log.error(e1);
}
SocketFactory socketFactory = VirtualSocketFactory.getDefault();
Socket socket = null;
try
{
socket = socketFactory.createSocket();
socket.connect(basicBehaviorServerSocketAddress);
assertTrue(doOneSocketFactoryTest(socket));
}
catch (Exception e)
{
log.error(e);
e.printStackTrace();
fail();
}
try
{
socket = socketFactory.createSocket(basicBehaviorServerHost, basicBehaviorServerPort);
assertTrue(doOneSocketFactoryTest(socket));
}
catch (Exception e)
{
log.error(e);
e.printStackTrace();
fail();
}
try
{
InetAddress inetAddress = InetAddress.getByName("localhost");
int localPort = random.nextInt() & 0xffff;
while (true)
{
try
{
socket = socketFactory.createSocket(basicBehaviorServerHost, basicBehaviorServerPort, inetAddress , localPort);
break;
}
catch (BindException e)
{
log.info("unable to bind to: " + localPort);
localPort = random.nextInt() & 0xffff;
}
catch (Exception e)
{
log.error(e);
e.printStackTrace();
fail();
}
}
assertTrue(socket.getLocalAddress().equals(inetAddress));
assertTrue(socket.getLocalPort() == localPort);
assertTrue(doOneSocketFactoryTest(socket));
}
catch (Exception e)
{
log.error(e);
e.printStackTrace();
fail();
}
try
{
InetAddress inetAddress = InetAddress.getByName(basicBehaviorServerHost);
socket = socketFactory.createSocket(inetAddress, basicBehaviorServerPort);
assertTrue(doOneSocketFactoryTest(socket));
}
catch (Exception e)
{
log.error(e);
e.printStackTrace();
fail();
}
try
{
while (true)
{
try
{
InetAddress remoteAddress = InetAddress.getByName(basicBehaviorServerHost);
InetAddress localAddress = InetAddress.getByName("localhost");
int localPort = random.nextInt() & 0xffff;
socket = socketFactory.createSocket(remoteAddress, basicBehaviorServerPort, localAddress , localPort);
assertTrue(socket.getLocalAddress().equals(localAddress));
assertTrue(socket.getLocalPort() == localPort);
assertTrue(doOneSocketFactoryTest(socket));
break;
}
catch (BindException e)
{
log.info("looking for a free socket");
}
}
}
catch (Exception e)
{
log.error(e);
e.printStackTrace();
fail();
}
log.info("testSocketFactory() PASSES");
}
/**
* FIXME Comment this
*
* @param socket
* @return
*/
protected boolean doOneSocketFactoryTest(Socket socket)
{
log.info("entering doOneFactoryTest()");
boolean success = true;
try
{
byte[] script = new byte[]
{
READ,
WRITE,
READ,
CLOSE_TEST_SOCKET
};
scriptStream.write(script.length);
scriptStream.write(script);
}
catch (IOException e)
{
log.error(e);
}
InputStream is = null;
OutputStream os = null;
try
{
is = socket.getInputStream();
os = socket.getOutputStream();
os.write(3);
assertTrue(is.read() == 3);
os.write(5);
socket.close();
}
catch (Exception e)
{
log.error(e);
e.printStackTrace();
fail();
}
return success;
}
public void testMultipleManagers()
{
log.info("entering testMultipleManagers()");
try
{
byte[] script = new byte[] {RUN_VIRTUALSERVERSOCKET, CLOSE_TEST_SOCKET};
scriptStream.write(script.length);
scriptStream.write(script);
is = testSocket.getInputStream();
is.read();
Socket virtualSocket1 = new VirtualSocket(basicBehaviorServerHost, basicBehaviorServerPort + 1);
Socket virtualSocket2 = new VirtualSocket(basicBehaviorServerHost, basicBehaviorServerPort + 1);
is.read();
Socket virtualSocket3 = new VirtualSocket(basicBehaviorServerHost, basicBehaviorServerPort + 1);
os = virtualSocket3.getOutputStream();
DataInputStream dis = new DataInputStream(virtualSocket3.getInputStream());
int correctPort = dis.readInt();
log.info("correct port: " + correctPort);
assertTrue((virtualSocket3.getPort() == correctPort));
virtualSocket1.close();
virtualSocket2.close();
virtualSocket3.close();
}
catch (Exception e)
{
log.error(e);
e.printStackTrace();
fail();
}
log.info("testMultipleManagers() PASSES");
}
public void testTimeout()
{
log.info("entering testTimeouts()");
try
{
byte[] script = new byte[]
{
WRITE,
WRITE,
READ,
SLEEP, 0x02, 0x00, // sleep 512 milliseconds
WRITE,
READ,
SLEEP, 0x08, 0x00, // sleep 2048 milliseconds
READ,
WRITE,
READ,
WRITE,
WRITE,
READ,
CLOSE_TEST_SOCKET
};
scriptStream.write(script.length);
scriptStream.write(script);
is = testSocket.getInputStream();
os = testSocket.getOutputStream();
is.read();
testSocket.setSoTimeout(2048);
is.read(); // byte should already be available
os.write(3);
is.read(); // should have to wait, then get byte
os.write(5);
try
{
is.read(); // should timeout
fail();
}
catch (SocketTimeoutException e)
{
if (e.getMessage().equals("Read timed out"))
log.info("received expected timeout");
else
{
log.error("received unexpected exception", e);
fail();
}
}
os.write(7);
testSocket.setSoTimeout(0);
// The 7 should have been read before setSoTimeout(0), but should still be available.
assertTrue(is.read() == 7);
testSocket.setSoTimeout(1024);
byte[] bytes = new byte[3];
os.write(9);
int n = is.read(bytes, 0, 3);
log.info("n = " + n);
assertTrue((n == 1 || n == 2));
if (n == 1)
{
testSocket.setSoTimeout(0);
is.read();
testSocket.setSoTimeout(1024);
}
os.write(11);
Thread.sleep(1000);
assertTrue(is.read() == -1);
}
catch (Exception e)
{
log.error(e);
e.printStackTrace();
fail();
}
log.info("testTimeouts() PASSES");
}
static class C implements Serializable
{
static final int SIZE = 64 * 1024;
byte[] bytes;
C()
{
bytes = new byte[SIZE];
for (int i = 0; i < SIZE; i++)
bytes[i] = (byte) i;
}
C(InputStream is) throws IOException
{
bytes = new byte[SIZE];
int total = 0;
int n = 0;
while (total < SIZE && n >= 0)
{
n = is.read(bytes, total, SIZE-total);
total += n;
}
for (int i = 0; i < SIZE; i++)
if ((0xff & bytes[i]) != (i % 256))
log.info("read discrepancy [" + i + "]: " + (0xff & bytes[i]) + " <->" + i % 256);
}
void write(OutputStream os) throws IOException
{
os.write(bytes);
}
boolean equals(C c)
{
boolean result = true;
for (int i = 0; i < SIZE; i++)
{
if (bytes[i] != c.bytes[i])
{
log.info("equals discrepancy [" + i + " (" + (i % 256) + "]: " + (0xff & bytes[i]) + " != " + (0xff & c.bytes[i]));
result = false;
}
}
return result;
}
static void echo(InputStream is, OutputStream os) throws IOException
{
byte[] tempBytes = new byte[SIZE];
int total = 0;
int n = 0;
while (total < SIZE && n >= 0)
{
n = is.read(tempBytes, total, SIZE-total);
total += n;
}
for (int i = 0; i < SIZE; i++)
if ((0xff & tempBytes[i]) != (i % 256))
log.info("echo discrepancy [" + i + "]: " + (0xff & tempBytes[i]) + " <->" + i % 256);
os.write(tempBytes);
}
}
public void testLongMessages()
{
log.info("entering testLongMessages()");
try
{
byte[] script = new byte[] {RUN_LONG_MESSAGE_TEST, WRITE, CLOSE_TEST_SOCKET};
scriptStream.write(script.length);
scriptStream.write(script);
}
catch (IOException e1)
{
log.error(e1);
}
try
{
is = testSocket.getInputStream();
is.read();
int port = ((VirtualSocket) testSocket).getPort();
VirtualSocket vs1 = new VirtualSocket(clientServerSocketHost, port);
VirtualSocket vs2 = new VirtualSocket(clientServerSocketHost, port);
VirtualSocket vs3 = new VirtualSocket(clientServerSocketHost, port);
final C c = new C();
final OutputStream os1 = vs1.getOutputStream();
final OutputStream os2 = vs2.getOutputStream();
final OutputStream os3 = vs3.getOutputStream();
Thread t1 = new Thread()
{
public void run()
{
try
{
c.write(os1);
c.write(os2);
c.write(os3);
}
catch (Exception e)
{
log.error(e);
}
}
};
Thread t2 = new Thread()
{
public void run()
{
try
{
c.write(os1);
c.write(os2);
c.write(os3);
}
catch (Exception e)
{
log.error(e);
}
}
};
Thread t3 = new Thread()
{
public void run()
{
try
{
c.write(os1);
c.write(os2);
c.write(os3);
}
catch (Exception e)
{
log.error(e);
}
}
};
t1.start();
t2.start();
t3.start();
t1.join();
t2.join();
t3.join();
InputStream is1 = vs1.getInputStream();
InputStream is2 = vs2.getInputStream();
InputStream is3 = vs3.getInputStream();
assertTrue(new C(is1).equals(c));
assertTrue(new C(is1).equals(c));
assertTrue(new C(is1).equals(c));
assertTrue(new C(is2).equals(c));
assertTrue(new C(is2).equals(c));
assertTrue(new C(is2).equals(c));
assertTrue(new C(is3).equals(c));
assertTrue(new C(is3).equals(c));
assertTrue(new C(is3).equals(c));
vs1.close();
vs2.close();
vs3.close();
// Give VSS on server time to unregister on this side.
MultiplexingManager manager = vs1.getMultiplexingManager();
while (manager.isRemoteServerSocketRegistered())
{
try
{
Thread.sleep(500);
}
catch (InterruptedException ignored) {}
}
}
catch (Exception e)
{
log.error(e);
e.printStackTrace();
fail();
}
log.info("testLongMessages() PASSES");
}
static class ReaderThread1 extends Thread
{
InputStream is;
int id;
int counter;
int n;
boolean running;
ReaderThread1(InputStream is, int id) {this.is = is; this.id = id;}
public void run()
{
try
{
running = true;
while ((n = is.read()) != -1)
{
counter++;
log.debug(id + ": " + counter + ": " + (0xff & n));
sleep(10);
}
log.debug("done: " + id);
running = false;
}
catch (Exception e)
{
log.error(e);
e.printStackTrace();
}
}
int getCounter() {return counter;}
boolean isRunning() {return running;}
}
static class ReaderThread2 extends Thread
{
InputStream is;
int id;
int counter;
int n;
byte[] bytes = new byte[2];
boolean running;
ReaderThread2(InputStream is, int id) {this.is = is; this.id = id;}
public void run()
{
running = true;
try
{
while ((n = is.read(bytes)) != -1)
{
counter += n;
log.debug(id + ": " + n + ", " + counter + ": " + (0xff & bytes[0]));
sleep(10);
}
log.debug("done: " + id);
running = false;
}
catch (Exception e)
{
log.error(e);
e.printStackTrace();
}
}
int getCounter() {return counter;}
boolean isRunning() {return running;}
}
static class SkipThread extends Thread
{
InputStream is;
int id;
int n;
int counter;
boolean running;
SkipThread(InputStream is, int id) {this.is = is; this.id = id;}
public void run()
{
running = true;
try
{
while ((n = (int) is.skip(3)) != 0)
{
counter += n;
log.debug(id + ": " + n + ", " + counter);
sleep(10);
}
log.debug("done: " + id);
running = false;
}
catch (Exception e)
{
log.error(e);
e.printStackTrace();
}
}
int getCounter() {return counter;}
boolean isRunning() {return running;}
}
public void testMultipleReadersCloseEarly()
{
log.info("entering testMultipleReadersCloseEarly()");
try
{
byte[] script = new byte[] {RUN_MULTIPLE_READERS_TEST, CLOSE_TEST_SOCKET};
scriptStream.write(script.length);
scriptStream.write(script);
}
catch (IOException e1)
{
log.error(e1);
}
try
{
is = testSocket.getInputStream();
ReaderThread1 rt1 = new ReaderThread1(is, 1);
ReaderThread2 rt2 = new ReaderThread2(is, 2);
SkipThread st = new SkipThread(is, 3);
rt1.start();
rt2.start();
st.start();
rt1.join();
rt2.join();
st.join();
assertTrue(rt1.getCounter() + rt2.getCounter() + st.getCounter() == 1000);
assertFalse(rt1.isRunning());
assertFalse(rt2.isRunning());
assertFalse(st.isRunning());
}
catch (Exception e)
{
log.error(e);
e.printStackTrace();
fail();
}
log.info("testMultipleReadersCloseEarly() PASSES");
}
public void testMultipleReadersCloseLate()
{
log.info("entering testMultipleReadersCloseLate()");
try
{
byte[] script = new byte[]
{
RUN_MULTIPLE_READERS_TEST,
READ,
SHUTDOWN_OUTPUT,
READ,
CLOSE_TEST_SOCKET};
scriptStream.write(script.length);
scriptStream.write(script);
}
catch (IOException e1)
{
log.error(e1);
}
try
{
is = testSocket.getInputStream();
log.info("timeout: " + testSocket.getSoTimeout());
ReaderThread1 rt1 = new ReaderThread1(is, 1);
ReaderThread2 rt2 = new ReaderThread2(is, 2);
SkipThread st = new SkipThread(is, 3);
rt1.start();
rt2.start();
st.start();
while (rt1.getCounter() + rt2.getCounter() + st.getCounter() < 1000)
{
Thread.sleep(500);
}
assertTrue(rt1.getCounter() + rt2.getCounter() + st.getCounter() == 1000);
assertTrue(rt1.isRunning());
assertTrue(rt2.isRunning());
assertTrue(st.isRunning());
os = testSocket.getOutputStream();
is = testSocket.getInputStream();
// Tell server to shut down output.
os.write(3);
while(rt1.isRunning() || rt2.isRunning() || st.isRunning())
{
Thread.sleep(500);
}
assertFalse(rt1.isRunning());
assertFalse(rt2.isRunning());
assertFalse(st.isRunning());
os.write(5);
}
catch (Exception e)
{
log.error(e);
e.printStackTrace();
fail();
}
log.info("testMultipleReadersCloseLate() PASSES");
}
}