duke | 6e45e10 | 2007-12-01 00:00:00 +0000 | [diff] [blame] | 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()) { |
| 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 | } |