1 /*
2  * Copyright (c) 2003, 2020, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 /*
25  *
26  *
27  * A test service for use in the inetd/System.inheritedChannel unit
28  * tests.
29  *
30  * The test checks that the channel returned by System.inheritedChannel
31  * is in blocking mode and is bound. In addition, in the case of a
32  * SocketChannel checks that the socket is connected.
33  *
34  * The test service is launched with an argument that is the reply port.
35  * This reply port is used as an out-of-band connection to the unit test
36  * so that the test status can be reported. When the test completes it
37  * establishes a TCP connection to the port and sends a PASSED/FAILED
38  * message to indicate the test result.
39  */
40 import java.io.IOException;
41 import java.io.OutputStream;
42 import java.io.PrintStream;
43 import java.net.InetAddress;
44 import java.net.InetSocketAddress;
45 import java.nio.ByteBuffer;
46 import java.nio.channels.Channel;
47 import java.nio.channels.DatagramChannel;
48 import java.nio.channels.ServerSocketChannel;
49 import java.nio.channels.SocketChannel;
50 import java.nio.file.Files;
51 import java.nio.file.Path;
52 
53 import static java.nio.file.StandardOpenOption.APPEND;
54 import static java.nio.file.StandardOpenOption.CREATE;
55 
56 public class StateTestService {
57 
58     static boolean failed = false;
59     static int reply_port;
60 
check(boolean okay)61     static void check(boolean okay) {
62         println("check " + okay);
63         if (!okay) {
64             failed = true;
65         }
66     }
67 
68     static String logDir;
69     static PrintStream out;
70     static boolean initialized = false;
71 
72     // Opens named log file in ${test.classes}
initLogFile()73     static void initLogFile() {
74         if (initialized)
75             return;
76 
77         try {
78             OutputStream f = Files.newOutputStream(Path.of(logDir, "statetest.txt"), APPEND, CREATE);
79             out = new PrintStream(f);
80         } catch (Exception e) {}
81         initialized = true;
82     }
83 
println(String msg)84     static void println(String msg) {
85         initLogFile();
86         out.println(msg);
87     }
88 
reply(String msg)89     private static void reply(String msg) throws IOException {
90         println("REPLYING: "  + msg);
91         InetSocketAddress isa = new InetSocketAddress(InetAddress.getLocalHost(), reply_port);
92         SocketChannel sc = SocketChannel.open(isa);
93         byte b[] = msg.getBytes("UTF-8");
94         ByteBuffer bb = ByteBuffer.wrap(b);
95         sc.write(bb);
96         sc.close();
97     }
98 
main(String args[])99     public static void main(String args[]) throws IOException {
100         try {
101             if (args.length == 0) {
102                 System.err.println("Usage: StateTestService [reply-port]");
103                 return;
104             }
105             reply_port = Integer.parseInt(args[0]);
106             logDir = System.getProperty("test.classes");
107 
108             Channel c = null;
109             try {
110                 c = System.inheritedChannel();
111             } catch (SecurityException se) {
112                 // ignore
113             }
114             if (c == null) {
115                 println("c == null");
116                 reply("FAILED");
117                 return;
118             }
119 
120             if (c instanceof SocketChannel) {
121                 SocketChannel sc = (SocketChannel)c;
122                 check( sc.isBlocking() );
123                 check( sc.socket().isBound() );
124                 check( sc.socket().isConnected() );
125             }
126 
127             if (c instanceof ServerSocketChannel) {
128                 ServerSocketChannel ssc = (ServerSocketChannel)c;
129                 check( ssc.isBlocking() );
130                 check( ssc.socket().isBound() );
131             }
132 
133             if (c instanceof DatagramChannel) {
134                 DatagramChannel dc = (DatagramChannel)c;
135                 check( dc.isBlocking() );
136                 check( dc.socket().isBound() );
137             }
138 
139             if (failed) {
140                 reply("FAILED");
141             } else {
142                 reply("PASSED");
143             }
144         } catch (Throwable t) {
145             t.printStackTrace(out);
146             throw t;
147         }
148     }
149 }
150