ReadTimeoutTest.java revision 0
0N/A/*
0N/A * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
0N/A * published by the Free Software Foundation.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
0N/A * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0N/A * CA 95054 USA or visit www.sun.com if you need additional information or
0N/A * have any questions.
0N/A */
0N/A
0N/A/* @test
0N/A * @bug 4208804
0N/A *
0N/A * @summary Incoming connections should be subject to timeout
0N/A * @author Adrian Colley
0N/A *
0N/A * @library ../../testlibrary
0N/A * @build TestIface
0N/A * @build TestImpl
0N/A * @build TestImpl_Stub
0N/A * @build ReadTimeoutTest
0N/A * @run main/othervm/policy=security.policy/timeout=60 -Dsun.rmi.transport.tcp.readTimeout=5000 ReadTimeoutTest
0N/A */
0N/A
0N/A/* This test sets a very short read timeout, exports an object, and then
0N/A * connects to the port and does nothing. The server should close the
0N/A * connection after the timeout. If that doesn't happen, the test fails.
0N/A *
0N/A * A background thread does the read. The foreground waits for DELAY*4
0N/A * and then aborts. This should give sufficient margin for timing slop.
0N/A */
0N/A
0N/Aimport java.rmi.*;
0N/Aimport java.rmi.server.RMISocketFactory;
0N/Aimport java.io.*;
0N/Aimport java.net.*;
0N/A
0N/Apublic class ReadTimeoutTest
0N/A{
0N/A private static final int DELAY = 5000; // milliseconds
0N/A
0N/A public static void main(String[] args)
0N/A throws Exception
0N/A {
0N/A // Make trouble for ourselves
0N/A if (System.getSecurityManager() == null)
0N/A System.setSecurityManager(new RMISecurityManager());
0N/A
0N/A // Flaky code alert - hope this is executed before TCPTransport.<clinit>
0N/A System.setProperty("sun.rmi.transport.tcp.readTimeout", Integer.toString(DELAY));
0N/A
0N/A // Set the socket factory.
0N/A System.err.println("(installing socket factory)");
0N/A SomeFactory fac = new SomeFactory();
0N/A RMISocketFactory.setSocketFactory(fac);
0N/A
0N/A // Create remote object
0N/A TestImpl impl = new TestImpl();
0N/A
0N/A // Export and get which port.
0N/A System.err.println("(exporting remote object)");
0N/A TestIface stub = impl.export();
0N/A Socket DoS = null;
0N/A try {
0N/A int port = fac.whichPort();
0N/A
0N/A // Sanity
0N/A if (port == 0)
0N/A throw new Error("TEST FAILED: export didn't reserve a port(?)");
0N/A
0N/A // Now, connect to that port
0N/A //Thread.sleep(2000);
0N/A System.err.println("(connecting to listening port on 127.0.0.1:" +
0N/A port + ")");
0N/A DoS = new Socket("127.0.0.1", port);
0N/A InputStream stream = DoS.getInputStream();
0N/A
0N/A // Read on the socket in the background
0N/A boolean[] successful = new boolean[] { false };
0N/A (new SomeReader(stream, successful)).start();
0N/A
0N/A // Wait for completion
0N/A int nretries = 4;
0N/A while (nretries-- > 0) {
0N/A if (successful[0])
0N/A break;
0N/A Thread.sleep(DELAY);
0N/A }
0N/A
0N/A if (successful[0]) {
0N/A System.err.println("TEST PASSED.");
0N/A } else {
0N/A throw new Error("TEST FAILED.");
0N/A }
0N/A
0N/A } finally {
0N/A try {
0N/A if (DoS != null)
0N/A DoS.close(); // aborts the reader if still blocked
0N/A impl.unexport();
0N/A } catch (Throwable unmatter) {
0N/A }
0N/A }
0N/A
0N/A // Should exit here
0N/A }
0N/A
0N/A private static class SomeFactory
0N/A extends RMISocketFactory
0N/A {
0N/A private int servport = 0;
0N/A
0N/A public Socket createSocket(String h, int p)
0N/A throws IOException
0N/A {
0N/A return (new Socket(h, p));
0N/A }
0N/A
0N/A /** Create a server socket and remember which port it's on.
0N/A * Aborts if createServerSocket(0) is called twice, because then
0N/A * it doesn't know whether to remember the first or second port.
0N/A */
0N/A public ServerSocket createServerSocket(int p)
0N/A throws IOException
0N/A {
0N/A ServerSocket ss;
0N/A ss = new ServerSocket(p);
0N/A if (p == 0) {
0N/A if (servport != 0) {
0N/A System.err.println("TEST FAILED: " +
0N/A "Duplicate createServerSocket(0)");
0N/A throw new Error("Test aborted (createServerSocket)");
0N/A }
0N/A servport = ss.getLocalPort();
0N/A }
0N/A return (ss);
0N/A }
0N/A
0N/A /** Return which port was reserved by createServerSocket(0).
0N/A * If the return value was 0, createServerSocket(0) wasn't called.
0N/A */
0N/A public int whichPort() {
0N/A return (servport);
0N/A }
0N/A } // end class SomeFactory
0N/A
0N/A protected static class SomeReader extends Thread {
0N/A private InputStream readon;
0N/A private boolean[] vec;
0N/A
0N/A public SomeReader(InputStream s, boolean[] successvec) {
0N/A super();
0N/A this.setDaemon(true);
0N/A this.readon = s;
0N/A this.vec = successvec;
0N/A }
0N/A
0N/A public void run() {
0N/A try {
0N/A int c = this.readon.read();
0N/A if (c != -1)
0N/A throw new Error ("Server returned " + c);
0N/A this.vec[0] = true;
0N/A
0N/A } catch (IOException e) {
0N/A e.printStackTrace();
0N/A }
0N/A }
0N/A } // end class SomeReader
0N/A}