// Tags: JDK1.4 /* Copyright (C) 2006, 2016 Chris Gray, KIFFER Ltd. This file is part of Mauve. Mauve is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. Mauve is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Mauve; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package gnu.testlet.wonka.net.Socket; import gnu.testlet.Testlet; import gnu.testlet.TestHarness; import java.net.*; import java.util.Vector; import java.io.*; public class KSocketTest implements Testlet { protected TestHarness th; private static String server = "www.k-embedded-java.com"; private static int port = 80; private Object lock = new Object(); private boolean reading; private boolean readInterrupted; private String ifconfig; public void test (TestHarness harness) { th = harness; th.setclass("java.net.Socket"); ifconfig = getIfconfigOutput(); test_closeSocket(); // We run the following test several times to be sure that a hanging // connection does not interfere with subsequent attempts test_timedConnect(1); test_timedConnect(2); test_timedConnect(3); test_getLocalAddress(); test_getLocalSocketAddress(); } private String getIfconfigOutput() { final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final Runtime r = Runtime.getRuntime(); try { final Process p = r.exec("ifconfig"); new Thread(new Runnable() { public void run() { try { InputStream is = p.getInputStream(); int ch = is.read(); while (ch >= 0) { baos.write(ch); ch = is.read(); } } catch (IOException ioe) { System.err.println("error when reading from ifconfig stdout"); ioe.printStackTrace(); } } }, "readStdout").start(); new Thread(new Runnable() { public void run() { try { InputStream is = p.getErrorStream(); int ch = is.read(); while (ch >= 0) { ch = is.read(); } } catch (IOException ioe) { System.err.println("error when reading from ifconfig stdout"); ioe.printStackTrace(); } } }, "readStderr").start(); int rc = p.waitFor(); if (rc != 0) { System.err.println("exec ifconfig failed with return code " + rc); } } catch (IOException ioe) { System.err.println("error when executing ifconfig"); ioe.printStackTrace(); return null; } catch (InterruptedException ie) { System.err.println("interrupted!"); } System.out.println("ifconfig output:\n\n" + baos); return baos.toString(); } private void test_closeSocket() { SocketTest test = new SocketTest(server, port); try { new Thread(new Runnable() { public void run() { try { long t0 = System.currentTimeMillis(); synchronized(lock) { while (!readInterrupted && System.currentTimeMillis() - t0 < 2000) { lock.wait(); } if (!readInterrupted) { th.fail("close() failed tu interrupt read()"); } } } catch (InterruptedException ie) { ie.printStackTrace(); } } }).start(); synchronized(lock) { test.start(); while (!reading) { lock.wait(); } // wait a bit longer so the read() is really executing lock.wait(1000); test.closeSocket(); while (!readInterrupted) { lock.wait(); } } } catch (InterruptedException ie) { ie.printStackTrace(); } } private void test_timedConnect(int n) { try { InetAddress inetAddress = InetAddress.getByName("google.com"); SocketAddress socketAddress = new InetSocketAddress(inetAddress, 22); Socket s = new Socket(); s.connect(socketAddress, 1000); th.fail("Apparently google.com allowed us to connect to port 22? Must be something wrong here. (Attempt #" + n + ")"); } catch (UnknownHostException uhe) { th.fail("Unable to locate google.com - is DNS set up properly? (Attempt #" + n + ")"); } catch (SocketTimeoutException ste) { // Expected result } catch (IOException ioe) { ioe.printStackTrace(); th.fail("Unexpected IOException (Attempt #" + n + ")"); } } private void test_getLocalAddress() { try { Socket s = new Socket(); final InetAddress unboundLocalAddress = s.getLocalAddress(); System.out.println("unboundLocalAddress = " + unboundLocalAddress.getClass() + " " + unboundLocalAddress); try { System.out.println(unboundLocalAddress.getClass().getMethod("isAnyLocalAddress", new Class[0])); } catch (Exception e) {e.printStackTrace();} if (!unboundLocalAddress.isAnyLocalAddress()) { th.fail("local address of an unbound socket should be the wildcard address"); } s.connect(new InetSocketAddress("kiffer.ltd.uk", 80)); final InetAddress localAddress = s.getLocalAddress(); final byte[] localAddressBytes = localAddress.getAddress(); String localNumericAddress = Integer.toString(localAddressBytes[0] & 0xff); for (int i = 1; i < localAddressBytes.length; ++i) { localNumericAddress += "." + Integer.toString(localAddressBytes[i] & 0xff); } System.out.println("getLocalAddress.getHostAddress().getAddress(): " + localNumericAddress); if (ifconfig.indexOf(localNumericAddress) < 0) { th.fail("could not find IP of socket local address (" + localNumericAddress + ") anywhere in ifconfig output"); } // Not testing getHostName() as no reliable way to get own host name } catch (UnknownHostException uhe) { th.fail("Unable to locate kiffer.ltd.uk - is DNS set up properly?"); } catch (IOException ioe) { ioe.printStackTrace(); th.fail("Unexpected IOException"); } } private void test_getLocalSocketAddress() { try { Socket s = new Socket(); System.out.println(s.getLocalSocketAddress()); if (s.getLocalSocketAddress() != null) { th.fail("local socket address of an unbound socket should be null"); } s.connect(new InetSocketAddress("kiffer.ltd.uk", 80)); final SocketAddress localSocketAddress = s.getLocalSocketAddress(); // Not testing getHostName() as no reliable way to get own host name } catch (UnknownHostException uhe) { th.fail("Unable to locate kiffer.ltd.uk - is DNS set up properly?"); } catch (IOException ioe) { ioe.printStackTrace(); th.fail("Unexpected IOException"); } } private class SocketTest extends Thread { private Socket socket; SocketTest(String server, int port) { try { this.socket = new Socket(server, port); } catch (IOException ioe) { ioe.printStackTrace(); th.fail("Unable to create connection to " + socket + ":" + port + " - check your network settings"); } } public void run() { try { while (!isInterrupted()) { InputStream i = this.socket.getInputStream(); // Read incoming data and interpret it as a frame synchronized (lock) { reading = true; lock.notifyAll(); } i.read(); } } catch (IOException e) { synchronized (lock) { readInterrupted = true; lock.notifyAll(); } } } public void closeSocket() { // close streams and socket if (this.socket != null) { try { InputStream in = this.socket.getInputStream(); if (in != null) { in.close(); } } catch (IOException e) { th.fail("Failed to close connection input stream : " + e.toString()); e.printStackTrace(); } try { this.socket.close(); } catch (IOException e) { th.fail("Failed to close connection socket : " + e.toString()); e.printStackTrace(); } } } } }