package conformance.rmi;
import test.*;
import rmi.*;
import java.net.*;
/** Performs basic tests on the public interface of {@link rmi.Skeleton}.
The tests performed are:
Both Skeleton constructors reject classes.
Both constructors reject non-remote interfaces.
Both constructors require the first two arguments to be
non-null.
The skeleton can be started and stopped, and accepts connections while
started.
*/
public class SkeletonTest extends Test
{
/** Test notice. */
public static final String notice = "checking skeleton public interface";
/** Socket address used for the creation of skeletons. */
private final InetSocketAddress address;
/** Dummy object used for testing calls to Skeleton
constructors. */
private final BadInterfaceImplementation dummy_server;
/** Regular server object. */
private final TestServer server;
/** The main skeleton used for testing. */
private final TestSkeleton skeleton;
/** Indicates whether the skeleton has stopped. */
private boolean stopped;
/** Creates a SkeletonTest object. */
public SkeletonTest()
{
address = new InetSocketAddress(7000);
dummy_server = new BadInterfaceImplementation();
server = new TestServer();
skeleton = new TestSkeleton();
stopped = false;
}
/** Performs the test. */
@Override
protected void perform() throws TestFailed
{
ensureClassRejected();
ensureNonRemoteInterfaceRejected();
ensureNullPointerExceptions();
ensureSkeletonRuns();
}
/** Performs tests with a running skeleton.
This method starts the skeleton and then stops it. In between, it probes
to see if the skeleton is accepting connections.
*/
private void ensureSkeletonRuns() throws TestFailed
{
if(probe())
throw new TestFailed("skeleton accepts connections before start");
try
{
skeleton.start();
}
catch(RMIException e)
{
throw new TestFailed("unable to start skeleton", e);
}
if(!probe())
throw new TestFailed("skeleton refuses connections after start");
skeleton.stop();
synchronized(this)
{
while(!stopped)
{
try
{
wait();
}
catch(InterruptedException e) { }
}
}
if(probe())
throw new TestFailed("skeleton accepts connections after stop");
}
/** Wakes ensureSkeletonRuns. */
private synchronized void wake()
{
stopped = true;
notifyAll();
}
/** Checks that it is possible to connect to the server.
@return true if the connection can be established, and
false if it cannot be.
*/
private boolean probe()
{
Socket socket = new Socket();
try
{
socket.connect(address);
}
catch(Exception e)
{
return false;
}
try
{
socket.close();
}
catch(Exception e) { }
return true;
}
/** Stops the skeleton server, if it is running, and attempts to wake the
test main thread. */
@Override
protected void clean()
{
skeleton.stop();
wake();
}
/** Ensures that a Skeleton cannot be constructed from a class
rather than an interface.
@throws TestFailed If a Skeleton is constructed from a
class, or if an unexpected exception occurs.
*/
private void ensureClassRejected() throws TestFailed
{
try
{
Skeleton