1990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson/*
2990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson * Copyright (C) 2008 The Android Open Source Project
3990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson *
4990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson * Licensed under the Apache License, Version 2.0 (the "License");
5990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson * you may not use this file except in compliance with the License.
6990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson * You may obtain a copy of the License at
7990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson *
8990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson *      http://www.apache.org/licenses/LICENSE-2.0
9990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson *
10990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson * Unless required by applicable law or agreed to in writing, software
11990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
12990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson * See the License for the specific language governing permissions and
14990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson * limitations under the License.
15990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson */
16990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson
17990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilsonpackage libcore.java.net;
18990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson
19990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilsonimport java.io.IOException;
20990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilsonimport java.net.DatagramPacket;
21990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilsonimport java.net.DatagramSocket;
22990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilsonimport java.net.InetAddress;
23255a6f4ab321614ed1ca26849d1df7fa9c0610f5Elliott Hughesimport java.net.InetSocketAddress;
24990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilsonimport java.net.SocketTimeoutException;
25255a6f4ab321614ed1ca26849d1df7fa9c0610f5Elliott Hughesimport java.nio.channels.DatagramChannel;
26990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilsonimport junit.framework.TestCase;
27990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson
28990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson/**
29990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson * Implements some simple tests for datagrams. Not as excessive as the core
30990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson * tests, but good enough for the harness.
31990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson */
32990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilsonpublic class OldAndroidDatagramTest extends TestCase {
33990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson
34990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson    /**
35990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson     * Helper class that listens to incoming datagrams and reflects them to the
36990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson     * sender. Incoming datagram is interpreted as a String. It is uppercased
37990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson     * before being sent back.
38990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson     */
39990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson
40990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson    class Reflector extends Thread {
41255a6f4ab321614ed1ca26849d1df7fa9c0610f5Elliott Hughes        // Helper class for reflecting incoming datagrams.
42990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson        DatagramSocket socket;
43990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson
44990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson        boolean alive = true;
45990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson
46990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson        byte[] buffer = new byte[256];
47990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson
48990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson        DatagramPacket packet;
49990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson
50990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson        /**
51990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson         * Main loop. Receives datagrams and reflects them.
52990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson         */
53990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson        @Override
54990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson        public void run() {
55990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson            try {
56990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                while (alive) {
57990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                    try {
58990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                        packet.setLength(buffer.length);
59990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                        socket.receive(packet);
60990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                        String s = stringFromPacket(packet);
61990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                        // System.out.println(s + " (from " + packet.getAddress() + ":" + packet.getPort() + ")");
62990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson
63990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                        try {
64990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                            Thread.sleep(100);
65990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                        } catch (InterruptedException ex) {
66990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                            // Ignore.
67990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                        }
68990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson
69990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                        stringToPacket(s.toUpperCase(), packet);
70990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson
71990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                        packet.setAddress(InetAddress.getLocalHost());
72990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                        packet.setPort(2345);
73990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson
74990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                        socket.send(packet);
75990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                    } catch (java.io.InterruptedIOException e) {
76990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                    }
77990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                }
78990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson            } catch (java.io.IOException ex) {
79990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                ex.printStackTrace();
80990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson            } finally {
81990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                socket.close();
82990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson            }
83990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson        }
84990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson
85990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson        /**
86990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson         * Creates a new Relfector object for the given local address and port.
87990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson         */
88990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson        public Reflector(int port, InetAddress address) {
89990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson            try {
90990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                packet = new DatagramPacket(buffer, buffer.length);
91990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                socket = new DatagramSocket(port, address);
92990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson            } catch (IOException ex) {
93990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                throw new RuntimeException(
94990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                        "Creating datagram reflector failed", ex);
95990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson            }
96990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson        }
97990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson    }
98990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson
99990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson    /**
100990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson     * Converts a given datagram packet's contents to a String.
101990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson     */
102990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson    static String stringFromPacket(DatagramPacket packet) {
103990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson        return new String(packet.getData(), 0, packet.getLength());
104990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson    }
105990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson
106990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson    /**
107990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson     * Converts a given String into a datagram packet.
108990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson     */
109990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson    static void stringToPacket(String s, DatagramPacket packet) {
110990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson        byte[] bytes = s.getBytes();
111990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson        System.arraycopy(bytes, 0, packet.getData(), 0, bytes.length);
112990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson        packet.setLength(bytes.length);
113990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson    }
114990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson
115990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson    /**
116990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson     * Implements the main part of the Datagram test.
117990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson     */
118990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson    public void testDatagram() throws Exception {
119990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson
120990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson        Reflector reflector = null;
121990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson        DatagramSocket socket = null;
122990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson
123990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson        try {
124990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson            // Setup the reflector, so we have a partner to send to
125990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson            reflector = new Reflector(1234, InetAddress.getLocalHost());
126990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson            reflector.start();
127990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson
128990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson            byte[] buffer = new byte[256];
129990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson
130990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson            DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
131990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson            socket = new DatagramSocket(2345, InetAddress.getLocalHost());
132990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson
133990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson            // Send ten simple packets and check for the expected responses.
134990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson            for (int i = 1; i <= 10; i++) {
135990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                String s = "Hello, Android world #" + i + "!";
136990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                stringToPacket(s, packet);
137990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson
138990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                packet.setAddress(InetAddress.getLocalHost());
139990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                packet.setPort(1234);
140990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson
141990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                socket.send(packet);
142990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson
143990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                try {
144990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                    Thread.sleep(100);
145990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                } catch (InterruptedException ex) {
146990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                    // Ignore.
147990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                }
148990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson
149990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                packet.setLength(buffer.length);
150990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                socket.receive(packet);
151990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                String t = stringFromPacket(packet);
152990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                // System.out.println(t + " (from " + packet.getAddress() + ":" + packet.getPort() + ")");
153990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson
154990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                assertEquals(s.toUpperCase(), t);
155990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson            }
156990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson        } finally {
157990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson            if (reflector != null) {
158990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                reflector.alive = false;
159990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson            }
160990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson
161990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson            if (socket != null) {
162990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                socket.close();
163990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson            }
164990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson        }
165990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson    }
166990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson
167990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson    // Regression test for issue 1018003: DatagramSocket ignored a set timeout.
168990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson    public void testDatagramSocketSetSOTimeout() throws Exception {
169990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson        DatagramSocket sock = null;
170990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson        int timeout = 5000;
171990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson        long start = System.currentTimeMillis();
172990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson        try {
173990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson            sock = new DatagramSocket();
174990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson            DatagramPacket pack = new DatagramPacket(new byte[100], 100);
175990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson            sock.setSoTimeout(timeout);
176990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson            sock.receive(pack);
177990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson        } catch (SocketTimeoutException e) {
178990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson            // expected
179990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson            long delay = System.currentTimeMillis() - start;
180990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson            if (Math.abs(delay - timeout) > 1000) {
181990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                fail("timeout was not accurate. expected: " + timeout
182990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                        + " actual: " + delay + " miliseconds.");
183990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson            }
184990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson        } finally {
185990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson            if (sock != null) {
186990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson                sock.close();
187990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson            }
188990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson        }
189990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson    }
190255a6f4ab321614ed1ca26849d1df7fa9c0610f5Elliott Hughes
191255a6f4ab321614ed1ca26849d1df7fa9c0610f5Elliott Hughes    public void test_54072_DatagramSocket() throws Exception {
192255a6f4ab321614ed1ca26849d1df7fa9c0610f5Elliott Hughes        DatagramSocket s = new DatagramSocket(null);
193255a6f4ab321614ed1ca26849d1df7fa9c0610f5Elliott Hughes        assertTrue(s.getLocalAddress().isAnyLocalAddress());
194255a6f4ab321614ed1ca26849d1df7fa9c0610f5Elliott Hughes        s.bind(new InetSocketAddress(8888));
195255a6f4ab321614ed1ca26849d1df7fa9c0610f5Elliott Hughes        assertTrue(s.getLocalAddress().isAnyLocalAddress());
196255a6f4ab321614ed1ca26849d1df7fa9c0610f5Elliott Hughes        s.close();
197255a6f4ab321614ed1ca26849d1df7fa9c0610f5Elliott Hughes        assertNull(s.getLocalAddress());
198255a6f4ab321614ed1ca26849d1df7fa9c0610f5Elliott Hughes    }
199255a6f4ab321614ed1ca26849d1df7fa9c0610f5Elliott Hughes
200255a6f4ab321614ed1ca26849d1df7fa9c0610f5Elliott Hughes    public void test_54072_DatagramChannel() throws Exception {
201255a6f4ab321614ed1ca26849d1df7fa9c0610f5Elliott Hughes        DatagramChannel ch = DatagramChannel.open();
202255a6f4ab321614ed1ca26849d1df7fa9c0610f5Elliott Hughes        DatagramSocket s = ch.socket();
203255a6f4ab321614ed1ca26849d1df7fa9c0610f5Elliott Hughes        assertTrue(s.getLocalAddress().isAnyLocalAddress());
204255a6f4ab321614ed1ca26849d1df7fa9c0610f5Elliott Hughes        s.bind(new InetSocketAddress(8888));
205255a6f4ab321614ed1ca26849d1df7fa9c0610f5Elliott Hughes        assertTrue(s.getLocalAddress().isAnyLocalAddress());
206255a6f4ab321614ed1ca26849d1df7fa9c0610f5Elliott Hughes        s.close();
207255a6f4ab321614ed1ca26849d1df7fa9c0610f5Elliott Hughes        assertNull(s.getLocalAddress());
208255a6f4ab321614ed1ca26849d1df7fa9c0610f5Elliott Hughes    }
209990640f1775dc6f429a5f8b9fc6cab6b4220c03aJesse Wilson}
210