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  * Used in conjunction to EchoService to test System.inheritedChannel().
28  *
29  * The first test is the TCP echo test. A service is launched with a TCP
30  * socket and a TCP message is sent to the service. The test checks that
31  * the message is correctly echoed.
32  *
33  * The second test is a UDP echo test. A service is launched with a UDP
34  * socket and a UDP packet is sent to the service. The test checks that
35  * the packet is correctly echoed.
36  *
37  */
38 import java.io.IOException;
39 import java.net.DatagramPacket;
40 import java.nio.ByteBuffer;
41 import java.nio.channels.DatagramChannel;
42 import java.nio.channels.SelectionKey;
43 import java.nio.channels.Selector;
44 import java.nio.channels.SocketChannel;
45 import java.util.Random;
46 
47 import jdk.test.lib.Utils;
48 
49 public class EchoTest {
50 
51     private static int failures = 0;
52 
53     private static String ECHO_SERVICE = "EchoService";
54 
55     /*
56      * Sends a message with random bytes to the service, and then waits for
57      * a reply (with timeout). Once the reply is received it is checked to ensure
58      * that it matches the original message.
59      */
TCPEchoTest()60     private static void TCPEchoTest() throws IOException {
61         SocketChannel sc = Launcher.launchWithInetSocketChannel(ECHO_SERVICE, null);
62 
63         String msg = "Where's that damn torpedo?";
64         int repeat = 100;
65         int size = msg.length() * repeat;
66 
67         // generate bytes into a buffer and send it to the service
68 
69         ByteBuffer bb1 = ByteBuffer.allocate(size);
70         Random gen = new Random();
71         for (int i=0; i<repeat; i++) {
72             bb1.put(msg.getBytes("UTF-8"));
73         }
74         bb1.flip();
75         sc.write(bb1);
76 
77         // now we put the channel into non-blocking mode and we read the
78         // reply from the service into a second buffer.
79 
80         ByteBuffer bb2 = ByteBuffer.allocate(size+100);
81         sc.configureBlocking(false);
82         Selector sel = sc.provider().openSelector();
83         SelectionKey sk = sc.register(sel, SelectionKey.OP_READ);
84         int nread = 0;
85         long to = Utils.adjustTimeout(5000);
86         while (nread < size) {
87             long st = System.currentTimeMillis();
88             sel.select(to);
89             if (sk.isReadable()) {
90                 int n = sc.read(bb2);
91                 if (n > 0) {
92                     nread += n;
93                 }
94                 if (n < 0) {
95                     break;              // EOF
96                 }
97             }
98             sel.selectedKeys().remove(sk);
99             to -= System.currentTimeMillis() - st;
100             if (to <= 0) {
101                 break;
102             }
103         }
104         sc.close();
105 
106         // and compare the response
107 
108         boolean err = false;
109 
110         if (nread != size) {
111             err = true;
112         } else {
113             bb1.flip();
114             bb2.flip();
115             while (bb1.hasRemaining()) {
116                 if (bb1.get() != bb2.get()) {
117                     err = true;
118                 }
119             }
120         }
121 
122         // if error print out the response from the service (could be a stack trace)
123         if (err) {
124             System.err.println("Bad response or premature EOF, bytes read: ");
125             bb2.flip();
126             while (bb2.hasRemaining()) {
127                 char c = (char)bb2.get();
128                 System.out.print(c);
129             }
130             throw new RuntimeException("Bad response or premature EOF from service");
131         }
132     }
133 
134     /*
135      * Send a UDP packet to the service, wait for a reply (with timeout). Finally
136      * check that the packet is the same length as the original.
137      */
UDPEchoTest()138     private static void UDPEchoTest() throws IOException {
139         DatagramChannel dc = Launcher.launchWithDatagramChannel(ECHO_SERVICE, null);
140 
141         String msg = "I was out saving the galaxy when your grandfather was in diapers";
142 
143         ByteBuffer bb = ByteBuffer.wrap(msg.getBytes("UTF-8"));
144         dc.write(bb);
145 
146         // and receive the echo
147         byte b[] = new byte[msg.length() + 100];
148         DatagramPacket pkt2 = new DatagramPacket(b, b.length);
149         dc.socket().setSoTimeout((int)Utils.adjustTimeout(5000));
150         dc.socket().receive(pkt2);
151 
152         if (pkt2.getLength() != msg.length()) {
153             throw new RuntimeException("Received packet of incorrect length");
154         }
155 
156         dc.close();
157     }
158 
main(String args[])159     public static void main(String args[]) throws IOException {
160 
161         // TCP echo
162         try {
163             TCPEchoTest();
164             System.out.println("TCP echo test passed.");
165         } catch (Exception x) {
166             System.err.println(x);
167             failures++;
168         }
169 
170         // UDP echo
171         try {
172             UDPEchoTest();
173             System.out.println("UDP echo test passed.");
174         } catch (Exception x) {
175             x.printStackTrace();
176             System.err.println(x);
177             failures++;
178         }
179 
180         if (failures > 0) {
181             throw new RuntimeException("Test failed - see log for details");
182         }
183     }
184 
185 }
186