blob: a9c4d8b595b0c49b02787f9a8b849ebc68d98ae4 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 */
23
24/* @test
25 * @bug 4208804
26 *
27 * @summary Incoming connections should be subject to timeout
28 * @author Adrian Colley
29 *
30 * @library ../../testlibrary
31 * @build TestIface
32 * @build TestImpl
33 * @build TestImpl_Stub
34 * @build ReadTimeoutTest
35 * @run main/othervm/policy=security.policy/timeout=60 -Dsun.rmi.transport.tcp.readTimeout=5000 ReadTimeoutTest
36 */
37
38/* This test sets a very short read timeout, exports an object, and then
39 * connects to the port and does nothing. The server should close the
40 * connection after the timeout. If that doesn't happen, the test fails.
41 *
42 * A background thread does the read. The foreground waits for DELAY*4
43 * and then aborts. This should give sufficient margin for timing slop.
44 */
45
46import java.rmi.*;
47import java.rmi.server.RMISocketFactory;
48import java.io.*;
49import java.net.*;
50
51public class ReadTimeoutTest
52{
53 private static final int DELAY = 5000; // milliseconds
54
55 public static void main(String[] args)
56 throws Exception
57 {
58 // Make trouble for ourselves
59 if (System.getSecurityManager() == null)
60 System.setSecurityManager(new RMISecurityManager());
61
62 // Flaky code alert - hope this is executed before TCPTransport.<clinit>
63 System.setProperty("sun.rmi.transport.tcp.readTimeout", Integer.toString(DELAY));
64
65 // Set the socket factory.
66 System.err.println("(installing socket factory)");
67 SomeFactory fac = new SomeFactory();
68 RMISocketFactory.setSocketFactory(fac);
69
70 // Create remote object
71 TestImpl impl = new TestImpl();
72
73 // Export and get which port.
74 System.err.println("(exporting remote object)");
75 TestIface stub = impl.export();
76 Socket DoS = null;
77 try {
78 int port = fac.whichPort();
79
80 // Sanity
81 if (port == 0)
82 throw new Error("TEST FAILED: export didn't reserve a port(?)");
83
84 // Now, connect to that port
85 //Thread.sleep(2000);
86 System.err.println("(connecting to listening port on 127.0.0.1:" +
87 port + ")");
88 DoS = new Socket("127.0.0.1", port);
89 InputStream stream = DoS.getInputStream();
90
91 // Read on the socket in the background
92 boolean[] successful = new boolean[] { false };
93 (new SomeReader(stream, successful)).start();
94
95 // Wait for completion
96 int nretries = 4;
97 while (nretries-- > 0) {
98 if (successful[0])
99 break;
100 Thread.sleep(DELAY);
101 }
102
103 if (successful[0]) {
104 System.err.println("TEST PASSED.");
105 } else {
106 throw new Error("TEST FAILED.");
107 }
108
109 } finally {
110 try {
111 if (DoS != null)
112 DoS.close(); // aborts the reader if still blocked
113 impl.unexport();
114 } catch (Throwable unmatter) {
115 }
116 }
117
118 // Should exit here
119 }
120
121 private static class SomeFactory
122 extends RMISocketFactory
123 {
124 private int servport = 0;
125
126 public Socket createSocket(String h, int p)
127 throws IOException
128 {
129 return (new Socket(h, p));
130 }
131
132 /** Create a server socket and remember which port it's on.
133 * Aborts if createServerSocket(0) is called twice, because then
134 * it doesn't know whether to remember the first or second port.
135 */
136 public ServerSocket createServerSocket(int p)
137 throws IOException
138 {
139 ServerSocket ss;
140 ss = new ServerSocket(p);
141 if (p == 0) {
142 if (servport != 0) {
143 System.err.println("TEST FAILED: " +
144 "Duplicate createServerSocket(0)");
145 throw new Error("Test aborted (createServerSocket)");
146 }
147 servport = ss.getLocalPort();
148 }
149 return (ss);
150 }
151
152 /** Return which port was reserved by createServerSocket(0).
153 * If the return value was 0, createServerSocket(0) wasn't called.
154 */
155 public int whichPort() {
156 return (servport);
157 }
158 } // end class SomeFactory
159
160 protected static class SomeReader extends Thread {
161 private InputStream readon;
162 private boolean[] vec;
163
164 public SomeReader(InputStream s, boolean[] successvec) {
165 super();
166 this.setDaemon(true);
167 this.readon = s;
168 this.vec = successvec;
169 }
170
171 public void run() {
172 try {
173 int c = this.readon.read();
174 if (c != -1)
175 throw new Error ("Server returned " + c);
176 this.vec[0] = true;
177
178 } catch (IOException e) {
179 e.printStackTrace();
180 }
181 }
182 } // end class SomeReader
183}