1 /* 2 * Copyright (c) 2011, 2013, 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 @test 26 @summary This tests the basic functionality of sockets and selectors via local channels. 27 @summary It starts a server on one Thread, then it starts a client on another thread. 28 @summary It then checks for the validity of the data transfered betweenthem. 29 @summary If the data is not transmitted correctly the tests reports an error. 30 @summary com.apple.junit.java.nio.Selector 31 @library ../../regtesthelpers 32 @run junit TestNIOLocalChannels 33 */ 34 35 import junit.framework.*; 36 37 import java.io.IOException; 38 import java.io.InputStream; 39 import java.net.InetSocketAddress; 40 import java.net.URL; 41 import java.nio.ByteBuffer; 42 import java.nio.channels.*; 43 import java.util.Iterator; 44 45 public class TestNIOLocalChannels extends TestCase 46 { 47 static final int PORT = 10000; 48 49 public static Object lock = new Object(); 50 public static boolean finishedReading = false; 51 public static int correctAnswers = 0; 52 53 54 protected void setUp() 55 { 56 new Server().start(); 57 58 } 59 60 protected void tearDown() 61 { 62 } 63 64 public void testTestMe() throws Exception 65 { 66 int count = 0; 67 while (true) 68 { 69 count++; 70 synchronized(lock) 71 { 72 if (finishedReading) 73 { 74 assertTrue(" The transfered data from the server to the client didn't match exactly", correctAnswers > 50); 75 break; 76 } 77 } 78 Thread.sleep(200); 79 80 // this means that the test hung - ABORT 81 if (count == 1000) 82 { 83 finishedReading = true; 84 assertTrue(" The test hung - ABORTING", false); 85 break; 86 } 87 } 88 } 89 90 public static Test suite() 91 { 92 return new TestSuite(TestNIOLocalChannels.class); 93 } 94 95 public static void main (String[] args) 96 { 97 junit.textui.TestRunner.run(suite()); 98 } 99 } 100 101 /* 102 * Simple HTTP response server, adapted from O'Reilly NIO book's echo 103 * server example. 104 */ 105 class Server extends Thread { 106 107 static final byte [] RESPONSE_BYTES = 108 "HTTP/1.0 200 OK\r\nContent-Type: image/gif\r\nContent-Length: 2\r\nServer: D1\r\nConnection: close\r\n\r\nHello".getBytes(); 109 110 final ByteBuffer mRequestBuf; 111 final ByteBuffer mResponseBuf; 112 113 Server() { 114 mRequestBuf = ByteBuffer.allocateDirect(4096); 115 mResponseBuf = ByteBuffer.allocateDirect(RESPONSE_BYTES.length); 116 mResponseBuf.put(RESPONSE_BYTES); 117 mResponseBuf.flip(); 118 } 119 120 public void run() { 121 try { 122 123 final ServerSocketChannel serverChannel = ServerSocketChannel.open(); 124 125 serverChannel.socket().bind(new InetSocketAddress(TestNIOLocalChannels.PORT)); 126 serverChannel.configureBlocking(false); 127 128 final Selector selector = Selector.open(); 129 serverChannel.register(selector, SelectionKey.OP_ACCEPT); 130 131 // now we can run our client thread 132 new Client().start(); 133 134 while (true) { 135 136 synchronized(TestNIOLocalChannels.lock) 137 { 138 if (TestNIOLocalChannels.finishedReading) 139 { 140 break; 141 } 142 } 143 144 // Block and spin until at least one key is ready. 145 if (selector.select(1000) == 0) 146 continue; 147 148 final Iterator keyItr = selector.selectedKeys().iterator(); 149 while (keyItr.hasNext()) { 150 151 final SelectionKey key = (SelectionKey) keyItr.next(); 152 153 // Set new connections to readable. 154 if (key.isAcceptable()) { 155 final SocketChannel ch = ((ServerSocketChannel) key.channel()).accept(); 156 if (ch == null) 157 return; 158 ch.configureBlocking(false); 159 ch.register(selector, SelectionKey.OP_READ); 160 } 161 162 // Handle readable connections. 163 else if (key.isReadable()) { 164 final SocketChannel ch = (SocketChannel) key.channel(); 165 ch.read(mRequestBuf); 166 mRequestBuf.clear(); // don't need data for testing. 167 mResponseBuf.rewind(); 168 ch.write(mResponseBuf); 169 ch.close(); 170 } 171 172 // assert increment(); 173 keyItr.remove(); 174 } 175 } 176 177 } catch (Exception e) { 178 System.err.println("PixelServer: exception in main select loop!"); 179 e.printStackTrace(); 180 } 181 } 182 } 183 184 /** 185 * Simple HTTP client with statistics logging. 186 */ 187 class Client extends Thread { 188 public void run() { 189 try { 190 final byte [] buf = new byte[4096]; 191 char[] expectedResponse = { 'H', 'e', 'l', 'l', 'o' }; 192 int count = 0; 193 while (true) { 194 195 synchronized(TestNIOLocalChannels.lock) 196 { 197 if (TestNIOLocalChannels.finishedReading) 198 { 199 break; 200 } 201 } 202 203 final InputStream is = new URL("http://localhost:"+TestNIOLocalChannels.PORT+"/" + count).openStream(); 204 int num = 0; 205 while (num != -1) 206 { 207 num = is.read(buf); 208 for (int i = 0; i < num; i++) 209 { 210 if (((char) buf[i]) == expectedResponse[i]) 211 { 212 TestNIOLocalChannels.correctAnswers++; 213 } 214 else 215 { 216 TestNIOLocalChannels.correctAnswers = -1; 217 break; 218 } 219 } 220 } 221 is.close(); 222 223 // we got 50 correct answers, we can break now 224 if (TestNIOLocalChannels.correctAnswers > 50) 225 { 226 break; 227 } 228 229 if (TestNIOLocalChannels.correctAnswers == -1) 230 { 231 break; 232 } 233 // if (count % 5000 == 0) { 234 // long t = System.currentTimeMillis(); 235 // System.out.println("5k hits in " + (t - time) + "ms"); 236 // time = t; 237 // } 238 } 239 } catch (IOException e) { 240 e.printStackTrace(); 241 } 242 243 synchronized(TestNIOLocalChannels.lock) 244 { 245 TestNIOLocalChannels.finishedReading = true; 246 } 247 } 248 }