1 /*
   2  * Copyright 2003-2005 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 import java.net.*;
  25 import java.io.*;
  26 import java.util.*;
  27 
  28 public class Tests {
  29     /**
  30      * performs a simple exchange of data between the two sockets
  31      * and throws an exception if there is any problem.
  32      */
  33     public static void simpleDataExchange (Socket s1, Socket s2)
  34         throws Exception {
  35 
  36         InputStream i1 = s1.getInputStream();
  37         InputStream i2 = s2.getInputStream();
  38         OutputStream o1 = s1.getOutputStream();
  39         OutputStream o2 = s2.getOutputStream();
  40 
  41         simpleWrite (o1, 100);
  42         simpleWrite (o2, 200);
  43         simpleRead (i2, 100);
  44         simpleRead (i1, 200);
  45     }
  46 
  47     /**
  48      * Send a packet from s1 to s2 (ia2/s2.localPort) and check it
  49      * Send a packet from s2 to s1 (ia1/s1.localPort) and check it
  50      */
  51     public static void simpleDataExchange (DatagramSocket s1, InetAddress ia1,
  52                                            DatagramSocket s2, InetAddress ia2)
  53         throws Exception {
  54 
  55         SocketAddress dest1 = new InetSocketAddress (ia1, s1.getLocalPort());
  56         dprintln ("dest1 = " + dest1);
  57         SocketAddress dest2 = new InetSocketAddress (ia2, s2.getLocalPort());
  58         dprintln ("dest2 = " + dest2);
  59 
  60         byte[] ba = "Hello world".getBytes();
  61         byte[] bb = "HELLO WORLD1".getBytes();
  62         DatagramPacket p1 = new DatagramPacket (ba, ba.length, dest1);
  63         DatagramPacket p2 = new DatagramPacket (ba, ba.length, dest2);
  64 
  65         DatagramPacket r1 = new DatagramPacket (new byte[256], 256);
  66         DatagramPacket r2 = new DatagramPacket (new byte[256], 256);
  67 
  68         s2.send (p1);
  69         s1.send (p2);
  70         s1.receive (r1);
  71         s2.receive (r2);
  72         comparePackets (p1, r1);
  73         comparePackets (p2, r2);
  74     }
  75 
  76     /**
  77      * Send a packet from s1 to s2 (ia2/s2.localPort) and send same packet
  78      * back from s2 to sender. Check s1 receives original packet
  79      */
  80 
  81     public static void datagramEcho (DatagramSocket s1, DatagramSocket s2,
  82                                      InetAddress ia2)
  83         throws Exception {
  84 
  85         byte[] ba = "Hello world".getBytes();
  86         DatagramPacket p1;
  87 
  88         SocketAddress dest2 = null;
  89         if (ia2 != null) {
  90             dest2 = new InetSocketAddress (ia2, s2.getLocalPort());
  91             p1 = new DatagramPacket (ba, ba.length, dest2);
  92         } else {
  93             p1 = new DatagramPacket (ba, ba.length);
  94         }
  95 
  96         dprintln ("dest2 = " + dest2);
  97 
  98 
  99         DatagramPacket r1 = new DatagramPacket (new byte[256], 256);
 100         DatagramPacket r2 = new DatagramPacket (new byte[256], 256);
 101 
 102         s1.send (p1);
 103         s2.receive (r1);
 104         s2.send (r1);
 105         s1.receive (r2);
 106         comparePackets (p1, r1);
 107         comparePackets (p1, r2);
 108     }
 109 
 110     public static void comparePackets (DatagramPacket p1, DatagramPacket p2)
 111         throws Exception {
 112 
 113         byte[] b1 = p1.getData();
 114         byte[] b2 = p2.getData();
 115         int len = p1.getLength () > p2.getLength() ? p2.getLength()
 116                                                    : p1.getLength();
 117         for (int i=0; i<len; i++) {
 118             if (b1[i] != b2[i]) {
 119                 throw new Exception ("packets not the same");
 120             }
 121         }
 122     }
 123 
 124     /* check the time got is within 20% of the time expected */
 125     public static void checkTime (long got, long expected) {
 126         dprintln ("checkTime: got " + got + " expected " + expected);
 127         long upper = expected + (expected / 5);
 128         long lower = expected - (expected / 5);
 129         if (got > upper || got < lower) {
 130             throw new RuntimeException ("checkTime failed: got " + got + " expected " + expected);
 131         }
 132     }
 133 
 134     static boolean debug = false;
 135 
 136     public static void checkDebug (String[] args) {
 137         debug = args.length > 0 && args[0].equals("-d");
 138     }
 139 
 140     public static void dprint (String s) {
 141         if (debug) {
 142             System.out.print (s);
 143         }
 144     }
 145 
 146     public static void dprintln (String s) {
 147         if (debug) {
 148             System.out.println (s);
 149         }
 150     }
 151 
 152     static int numberInterfaces () {
 153         try {
 154             Enumeration ifs = NetworkInterface.getNetworkInterfaces();
 155             int nifs=0;
 156             while (ifs.hasMoreElements()) {
 157                 nifs++;
 158                 ifs.nextElement();
 159             }
 160             return nifs;
 161         } catch (SocketException e) {
 162             return 0;
 163         }
 164     }
 165 
 166     public static Enumeration ipv4Addresses() {
 167         return new AddrEnum (Inet4Address.class);
 168     }
 169 
 170     public static Inet4Address getFirstLocalIPv4Address () {
 171         Enumeration e = ipv4Addresses();
 172         if (!e.hasMoreElements()) {
 173             return null;
 174         }
 175         return (Inet4Address)e.nextElement();
 176     }
 177 
 178     public static Inet6Address getFirstLocalIPv6Address () {
 179         Enumeration e = ipv6Addresses();
 180         if (!e.hasMoreElements()) {
 181             return null;
 182         }
 183         return (Inet6Address)e.nextElement();
 184     }
 185 
 186     public static Enumeration ipv6Addresses() {
 187         return new AddrEnum (Inet6Address.class);
 188     }
 189 
 190     /* enumerates the Inet4Addresses or Inet6Addresses on the system */
 191 
 192     private static class AddrEnum implements Enumeration {
 193 
 194         Enumeration ifs;
 195         NetworkInterface currIf = null;
 196         InetAddress nextAddr=null;
 197         Enumeration addrs=null;
 198         Class filter;
 199 
 200         static final byte[] fe80_loopback = new byte [] {
 201             (byte)0xfe,(byte)0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,1
 202         };
 203 
 204         AddrEnum (Class filter) {
 205             this.filter = filter;
 206             try {
 207                 ifs = NetworkInterface.getNetworkInterfaces();
 208             } catch (SocketException e) {}
 209         }
 210 
 211         public boolean hasMoreElements () {
 212             if (nextAddr == null) {
 213                 nextAddr = getNext();
 214             }
 215             return (nextAddr != null);
 216         }
 217 
 218         public Object nextElement () {
 219             if (!hasMoreElements()) {
 220                 throw new NoSuchElementException ("no more addresses");
 221             }
 222             Object next = nextAddr;
 223             nextAddr = null;
 224             return next;
 225         }
 226 
 227         private InetAddress getNext() {
 228             while (true) {
 229                 if (currIf == null) {
 230                     currIf = getNextIf();
 231                     if (currIf == null) {
 232                         return null;
 233                     }
 234                     addrs = currIf.getInetAddresses();
 235                 }
 236                 while (addrs.hasMoreElements()) {
 237                     InetAddress addr = (InetAddress) addrs.nextElement();
 238                     if (filter.isInstance (addr) && !addr.isLoopbackAddress() && !addr.isLinkLocalAddress()) {
 239                         if (Arrays.equals (addr.getAddress(), fe80_loopback)) {
 240                             continue;
 241                         }
 242                         return addr;
 243                     }
 244                 }
 245                 currIf = null;
 246             }
 247         }
 248 
 249         private NetworkInterface getNextIf () {
 250             while (ifs.hasMoreElements()) {
 251                 NetworkInterface nic = (NetworkInterface)ifs.nextElement();
 252                 try {
 253                     if (nic.isUp() && !nic.isLoopback())
 254                         return nic;
 255                 } catch (SocketException e) {
 256                     // ignore
 257                 }
 258             }
 259 
 260             return null;
 261         }
 262     }
 263 
 264     /**
 265      * Throws a RuntimeException if the boolean condition is false
 266      */
 267     public static void t_assert (boolean assertion) {
 268         if (assertion) {
 269             return;
 270         }
 271         Throwable t = new Throwable();
 272         StackTraceElement[] strace = t.getStackTrace();
 273         String msg = "Assertion failed at: " + strace[1].toString();
 274         throw new RuntimeException (msg);
 275     }
 276 
 277     private static void simpleRead (InputStream is, int start) throws Exception {
 278         byte b[] = new byte [2];
 279         for (int i=start; i<start+100; i++) {
 280             int x = is.read (b);
 281             if (x == 1) {
 282                 x += is.read (b,1,1);
 283             }
 284             if (x!=2) {
 285                 throw new Exception ("read error");
 286             }
 287             int r = bytes (b[0], b[1]);
 288             if (r != i) {
 289                 throw new Exception ("read " + r + " expected " +i);
 290             }
 291         }
 292     }
 293 
 294     /* convert signed bytes to unisigned int */
 295     private static int bytes (byte b1, byte b2) {
 296         int i1 = (int)b1 & 0xFF;
 297         int i2 = (int)b2 & 0xFF;
 298         return i1 * 256 + i2;
 299     }
 300 
 301     static void simpleWrite (OutputStream os, int start) throws Exception {
 302         byte b[] = new byte [2];
 303         for (int i=start; i<start+100; i++) {
 304             b[0] = (byte) (i / 256);
 305             b[1] = (byte) (i % 256);
 306             os.write (b);
 307         }
 308     }
 309 
 310     private static class Runner extends Thread {
 311         Runnable runnee;
 312         long delay;
 313 
 314         Runner (Runnable runnee, long delay) {
 315             super();
 316             this.runnee = runnee;
 317             this.delay = delay;
 318         }
 319 
 320         public void run () {
 321             try {
 322                 Thread.sleep (delay);
 323                 runnee.run ();
 324             } catch (Exception e) {
 325                 e.printStackTrace();
 326             }
 327         }
 328     }
 329 
 330     /*
 331      * Take the given Runnable and run it in a spawned thread
 332      * after the given time has elapsed. runAfter() returns immediately
 333      */
 334     public static void runAfter (long millis, Runnable runnee) {
 335         Runner runner = new Runner (runnee, millis);
 336         runner.start ();
 337     }
 338 
 339     static String osname;
 340 
 341     static {
 342         osname = System.getProperty ("os.name");
 343     }
 344 
 345     static boolean isLinux () {
 346         return osname.equals ("Linux");
 347     }
 348 
 349     static boolean isWindows () {
 350         return osname.startsWith ("Windows");
 351     }
 352 }