1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.core; 18 19 import junit.framework.TestCase; 20 21 import java.io.IOException; 22 import java.net.DatagramPacket; 23 import java.net.DatagramSocket; 24 import java.net.InetAddress; 25 import java.net.SocketTimeoutException; 26 import android.test.suitebuilder.annotation.LargeTest; 27 28 /** 29 * Implements some simple tests for datagrams. Not as excessive as the core 30 * tests, but good enough for the harness. 31 */ 32 public class DatagramTest extends TestCase { 33 34 /** 35 * Helper class that listens to incoming datagrams and reflects them to the 36 * sender. Incoming datagram is interpreted as a String. It is uppercased 37 * before being sent back. 38 */ 39 40 class Reflector extends Thread { 41 // Helper class for reflecting incoming datagrams. 42 DatagramSocket socket; 43 44 boolean alive = true; 45 46 byte[] buffer = new byte[256]; 47 48 DatagramPacket packet; 49 50 /** 51 * Main loop. Receives datagrams and reflects them. 52 */ 53 @Override run()54 public void run() { 55 try { 56 while (alive) { 57 try { 58 packet.setLength(buffer.length); 59 socket.receive(packet); 60 String s = stringFromPacket(packet); 61 // System.out.println(s + " (from " + packet.getAddress() + ":" + packet.getPort() + ")"); 62 63 try { 64 Thread.sleep(100); 65 } catch (InterruptedException ex) { 66 // Ignore. 67 } 68 69 stringToPacket(s.toUpperCase(), packet); 70 71 packet.setAddress(InetAddress.getLocalHost()); 72 packet.setPort(2345); 73 74 socket.send(packet); 75 } catch (java.io.InterruptedIOException e) { 76 } 77 } 78 } catch (java.io.IOException ex) { 79 ex.printStackTrace(); 80 } finally { 81 socket.close(); 82 } 83 } 84 85 /** 86 * Creates a new Relfector object for the given local address and port. 87 */ Reflector(int port, InetAddress address)88 public Reflector(int port, InetAddress address) { 89 try { 90 packet = new DatagramPacket(buffer, buffer.length); 91 socket = new DatagramSocket(port, address); 92 } catch (IOException ex) { 93 throw new RuntimeException( 94 "Creating datagram reflector failed", ex); 95 } 96 } 97 } 98 99 /** 100 * Converts a given datagram packet's contents to a String. 101 */ stringFromPacket(DatagramPacket packet)102 static String stringFromPacket(DatagramPacket packet) { 103 return new String(packet.getData(), 0, packet.getLength()); 104 } 105 106 /** 107 * Converts a given String into a datagram packet. 108 */ stringToPacket(String s, DatagramPacket packet)109 static void stringToPacket(String s, DatagramPacket packet) { 110 byte[] bytes = s.getBytes(); 111 System.arraycopy(bytes, 0, packet.getData(), 0, bytes.length); 112 packet.setLength(bytes.length); 113 } 114 115 /** 116 * Implements the main part of the Datagram test. 117 */ 118 @LargeTest testDatagram()119 public void testDatagram() throws Exception { 120 121 Reflector reflector = null; 122 DatagramSocket socket = null; 123 124 try { 125 // Setup the reflector, so we have a partner to send to 126 reflector = new Reflector(1234, InetAddress.getLocalHost()); 127 reflector.start(); 128 129 byte[] buffer = new byte[256]; 130 131 DatagramPacket packet = new DatagramPacket(buffer, buffer.length); 132 socket = new DatagramSocket(2345, InetAddress.getLocalHost()); 133 134 // Send ten simple packets and check for the expected responses. 135 for (int i = 1; i <= 10; i++) { 136 String s = "Hello, Android world #" + i + "!"; 137 stringToPacket(s, packet); 138 139 packet.setAddress(InetAddress.getLocalHost()); 140 packet.setPort(1234); 141 142 socket.send(packet); 143 144 try { 145 Thread.sleep(100); 146 } catch (InterruptedException ex) { 147 // Ignore. 148 } 149 150 packet.setLength(buffer.length); 151 socket.receive(packet); 152 String t = stringFromPacket(packet); 153 // System.out.println(t + " (from " + packet.getAddress() + ":" + packet.getPort() + ")"); 154 155 assertEquals(s.toUpperCase(), t); 156 } 157 } finally { 158 if (reflector != null) { 159 reflector.alive = false; 160 } 161 162 if (socket != null) { 163 socket.close(); 164 } 165 } 166 } 167 168 // Regression test for issue 1018003: DatagramSocket ignored a set timeout. 169 @LargeTest testDatagramSocketSetSOTimeout()170 public void testDatagramSocketSetSOTimeout() throws Exception { 171 DatagramSocket sock = null; 172 int timeout = 5000; 173 long start = System.currentTimeMillis(); 174 try { 175 sock = new DatagramSocket(); 176 DatagramPacket pack = new DatagramPacket(new byte[100], 100); 177 sock.setSoTimeout(timeout); 178 sock.receive(pack); 179 } catch (SocketTimeoutException e) { 180 // expected 181 long delay = System.currentTimeMillis() - start; 182 if (Math.abs(delay - timeout) > 1000) { 183 fail("timeout was not accurate. expected: " + timeout 184 + " actual: " + delay + " miliseconds."); 185 } 186 } finally { 187 if (sock != null) { 188 sock.close(); 189 } 190 } 191 } 192 } 193