1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17
18package org.apache.harmony.tests.java.nio.channels;
19
20import android.system.ErrnoException;
21import android.system.OsConstants;
22import java.io.IOException;
23import java.net.DatagramPacket;
24import java.net.DatagramSocket;
25import java.net.Inet6Address;
26import java.net.InetSocketAddress;
27import java.net.SocketAddress;
28import java.net.SocketException;
29import java.nio.ByteBuffer;
30import java.nio.channels.AsynchronousCloseException;
31import java.nio.channels.ClosedChannelException;
32import java.nio.channels.DatagramChannel;
33import java.nio.channels.IllegalBlockingModeException;
34import java.nio.channels.NotYetConnectedException;
35import java.nio.channels.UnresolvedAddressException;
36import java.nio.channels.UnsupportedAddressTypeException;
37import java.nio.channels.spi.SelectorProvider;
38import java.util.concurrent.atomic.AtomicReference;
39import junit.framework.TestCase;
40import libcore.io.IoUtils;
41import libcore.io.Libcore;
42
43/**
44 * Test for DatagramChannel
45 */
46public class DatagramChannelTest extends TestCase {
47
48    private static final int CAPACITY_NORMAL = 200;
49
50    private static final int CAPACITY_1KB = 1024;
51
52    private static final int CAPACITY_64KB = 65536;
53
54    private static final int CAPACITY_ZERO = 0;
55
56    private static final int CAPACITY_ONE = 1;
57
58    private static final int TIME_UNIT = 500;
59
60    private InetSocketAddress datagramSocket1Address;
61    private InetSocketAddress datagramSocket2Address;
62
63    private InetSocketAddress channel1Address;
64    private InetSocketAddress channel2Address;
65
66    private DatagramChannel channel1;
67    private DatagramChannel channel2;
68
69    private DatagramSocket datagramSocket1;
70    private DatagramSocket datagramSocket2;
71
72    protected void setUp() throws Exception {
73        super.setUp();
74
75        channel1 = DatagramChannel.open();
76        channel2 = DatagramChannel.open();
77
78        channel1.socket().bind(new InetSocketAddress(Inet6Address.LOOPBACK, 0));
79        channel2.socket().bind(new InetSocketAddress(Inet6Address.LOOPBACK, 0));
80
81        channel1Address = (InetSocketAddress) channel1.socket().getLocalSocketAddress();
82        channel2Address = (InetSocketAddress) channel2.socket().getLocalSocketAddress();
83
84        this.datagramSocket1 = new DatagramSocket(0, Inet6Address.LOOPBACK);
85        this.datagramSocket2 = new DatagramSocket(0, Inet6Address.LOOPBACK);
86
87        datagramSocket1Address = (InetSocketAddress) datagramSocket1.getLocalSocketAddress();
88        datagramSocket2Address = (InetSocketAddress) datagramSocket2.getLocalSocketAddress();
89    }
90
91    protected void tearDown() throws Exception {
92        IoUtils.closeQuietly(channel1);
93        IoUtils.closeQuietly(channel2);
94        IoUtils.closeQuietly(datagramSocket1);
95        IoUtils.closeQuietly(datagramSocket2);
96
97        datagramSocket1Address = null;
98        datagramSocket2Address = null;
99        super.tearDown();
100    }
101
102    // -------------------------------------------------------------------
103    // Test for methods in abstract class.
104    // -------------------------------------------------------------------
105    /*
106     * Test method for 'java.nio.channels.DatagramChannel.validOps()'
107     */
108    public void testValidOps() {
109        MockDatagramChannel testMock = new MockDatagramChannel(SelectorProvider
110                .provider());
111        MockDatagramChannel testMocknull = new MockDatagramChannel(null);
112        int val = this.channel1.validOps();
113        assertEquals(5, val);
114        assertEquals(val, testMock.validOps());
115        assertEquals(val, testMocknull.validOps());
116    }
117
118    /*
119     * Test method for 'java.nio.channels.DatagramChannel.open()'
120     */
121    public void testOpen() {
122        MockDatagramChannel testMock = new MockDatagramChannel(SelectorProvider
123                .provider());
124        MockDatagramChannel testMocknull = new MockDatagramChannel(null);
125        assertNull(testMocknull.provider());
126        assertNotNull(testMock.provider());
127        assertEquals(this.channel1.provider(), testMock.provider());
128        assertEquals(5, testMock.validOps());
129    }
130
131    /*
132     * Test method for 'java.nio.channels.DatagramChannel.read(ByteBuffer)'
133     */
134    public void testReadByteBufferArray() throws IOException {
135        final int testNum = 0;
136        MockDatagramChannel testMock = new MockDatagramChannel(SelectorProvider
137                .provider());
138        MockDatagramChannel testMocknull = new MockDatagramChannel(null);
139        int bufSize = 10;
140        ByteBuffer[] readBuf = null;
141        try {
142            this.channel1.read(readBuf);
143            fail("Should throw NPE");
144        } catch (NullPointerException e) {
145            // correct
146        }
147
148        long readres;
149        try {
150            readres = testMock.read(readBuf);
151            fail("Should throw NPE");
152        } catch (NullPointerException e) {
153            // correct
154        }
155        readBuf = new ByteBuffer[bufSize];
156        try {
157            readres = this.channel1.read(readBuf);
158            fail("Should throw NotYetConnectedException");
159        } catch (NotYetConnectedException expected) {
160        }
161
162        readres = testMock.read(readBuf);
163        assertEquals(testNum, readres);
164        readres = testMocknull.read(readBuf);
165        assertEquals(testNum, readres);
166    }
167
168    /*
169     * Test method for 'java.nio.channels.DatagramChannel.read(ByteBuffer)'
170     */
171    public void testReadByteBufferArray_BufNull() throws IOException {
172        MockDatagramChannel testMock = new MockDatagramChannel(SelectorProvider
173                .provider());
174        MockDatagramChannel testMocknull = new MockDatagramChannel(null);
175
176        ByteBuffer[] readBuf = null;
177        try {
178            this.channel1.read(readBuf);
179            fail("Should throw NPE");
180        } catch (NullPointerException expected) {
181        }
182        try {
183            testMock.read(readBuf);
184            fail("Should throw NPE");
185        } catch (NullPointerException expected) {
186        }
187        try {
188            testMocknull.read(readBuf);
189            fail("Should throw NPE");
190        } catch (NullPointerException expected) {
191        }
192    }
193
194    /*
195     * Test method for 'java.nio.channels.DatagramChannel.write(ByteBuffer)'
196     */
197    public void testWriteByteBuffer() throws IOException {
198        MockDatagramChannel testMock = new MockDatagramChannel(SelectorProvider
199                .provider());
200        MockDatagramChannel testMocknull = new MockDatagramChannel(null);
201        int bufSize = 10;
202        ByteBuffer[] readBuf = null;
203        try {
204            this.channel1.write(readBuf);
205            fail("Should throw NPE");
206        } catch (NullPointerException e) {
207            // correct
208        }
209        try {
210            testMock.write(readBuf);
211            fail("Should throw NPE");
212        } catch (NullPointerException e) {
213            // correct
214        }
215        readBuf = new ByteBuffer[bufSize];
216        try {
217            this.channel1.write(readBuf);
218            fail("Should throw NotYetConnectedException");
219        } catch (NotYetConnectedException e) {
220            // correct
221        }
222        long writeres = 0;
223        writeres = testMock.write(readBuf);
224
225        assertEquals(0, writeres);
226        writeres = testMocknull.write(readBuf);
227        assertEquals(0, writeres);
228    }
229
230    /*
231     * Test method for 'java.nio.channels.DatagramChannel.write(ByteBuffer)'
232     */
233    public void testWriteByteBuffer_Bufnull() throws IOException {
234        MockDatagramChannel testMock = new MockDatagramChannel(SelectorProvider
235                .provider());
236        MockDatagramChannel testMocknull = new MockDatagramChannel(null);
237        ByteBuffer[] readBuf = null;
238        try {
239            this.channel1.write(readBuf);
240            fail("Should throw NPE");
241        } catch (NullPointerException e) {
242            // correct
243        }
244        try {
245            testMock.write(readBuf);
246            fail("Should throw NPE");
247        } catch (NullPointerException e) {
248            // correct
249        }
250        try {
251            testMocknull.write(readBuf);
252            fail("Should throw NPE");
253        } catch (NullPointerException e) {
254            // correct
255        }
256    }
257
258    // -------------------------------------------------------------------
259    // Test for socket()
260    // -------------------------------------------------------------------
261
262    /**
263     * Test method for 'DatagramChannelImpl.socket()'
264     */
265    public void testSocket_BasicStatusBeforeConnect() throws Exception {
266        final DatagramChannel dc = DatagramChannel.open();
267
268        assertFalse(dc.isConnected());// not connected
269        DatagramSocket s1 = dc.socket();
270
271        assertFalse(s1.isBound());
272        assertFalse(s1.isClosed());
273        assertFalse(s1.isConnected());
274        assertFalse(s1.getBroadcast());
275        assertFalse(s1.getReuseAddress());
276        assertNull(s1.getInetAddress());
277        assertTrue(s1.getLocalAddress().isAnyLocalAddress());
278        assertEquals(s1.getLocalPort(), 0);
279        assertNull(s1.getLocalSocketAddress());
280        assertEquals(s1.getPort(), -1);
281        assertTrue(s1.getReceiveBufferSize() >= 8192);
282        assertNull(s1.getRemoteSocketAddress());
283        assertFalse(s1.getReuseAddress());
284        assertTrue(s1.getSendBufferSize() >= 8192);
285        assertEquals(s1.getSoTimeout(), 0);
286        assertEquals(s1.getTrafficClass(), 0);
287
288        DatagramSocket s2 = dc.socket();
289        // same
290        assertSame(s1, s2);
291
292        dc.close();
293    }
294
295    /**
296     * Test method for 'DatagramChannelImpl.socket()'
297     */
298    public void testSocket_Block_BasicStatusAfterConnect() throws IOException {
299        final DatagramChannel dc = DatagramChannel.open();
300
301        dc.connect(datagramSocket1Address);
302        DatagramSocket s1 = dc.socket();
303        assertSocketAfterConnect(s1);
304        DatagramSocket s2 = dc.socket();
305        // same
306        assertSame(s1, s2);
307
308        dc.close();
309    }
310
311    public void testSocket_NonBlock_BasicStatusAfterConnect() throws IOException {
312        final DatagramChannel dc = DatagramChannel.open();
313        dc.connect(datagramSocket1Address);
314        dc.configureBlocking(false);
315
316        DatagramSocket s1 = dc.socket();
317        assertSocketAfterConnect(s1);
318        DatagramSocket s2 = dc.socket();
319        // same
320        assertSame(s1, s2);
321
322        dc.close();
323    }
324
325    private void assertSocketAfterConnect(DatagramSocket s) throws SocketException {
326        assertTrue(s.isBound());
327        assertFalse(s.isClosed());
328        assertTrue(s.isConnected());
329        assertFalse(s.getBroadcast());
330        assertFalse(s.getReuseAddress());
331        assertNotNull(s.getLocalSocketAddress());
332        assertEquals(s.getPort(), datagramSocket1Address.getPort());
333        assertTrue(s.getReceiveBufferSize() >= 8192);
334        // not same , but equals
335        assertNotSame(s.getRemoteSocketAddress(), datagramSocket1Address);
336        assertEquals(s.getRemoteSocketAddress(), datagramSocket1Address);
337        assertFalse(s.getReuseAddress());
338        assertTrue(s.getSendBufferSize() >= 8192);
339        assertEquals(s.getSoTimeout(), 0);
340        assertEquals(s.getTrafficClass(), 0);
341    }
342
343    /**
344     * Test method for 'DatagramChannelImpl.socket()'
345     */
346    public void testSocket_ActionsBeforeConnect() throws IOException {
347        assertFalse(channel1.isConnected());// not connected
348        assertTrue(channel1.isBlocking());
349        DatagramSocket s = channel1.socket();
350
351        s.connect(datagramSocket2Address);
352        assertTrue(channel1.isConnected());
353        assertTrue(s.isConnected());
354
355        s.disconnect();
356        assertFalse(channel1.isConnected());
357        assertFalse(s.isConnected());
358
359        s.close();
360        assertTrue(s.isClosed());
361        assertFalse(channel1.isOpen());
362    }
363
364    /**
365     * Test method for 'DatagramChannelImpl.socket()'
366     */
367    public void testSocket_Block_ActionsAfterConnect() throws IOException {
368        assertFalse(this.channel1.isConnected());// not connected
369        this.channel1.connect(datagramSocket1Address);
370        DatagramSocket s = this.channel1.socket();
371        assertSocketActionAfterConnect(s);
372    }
373
374    public void testSocket_NonBlock_ActionsAfterConnect() throws IOException {
375        this.channel1.connect(datagramSocket1Address);
376        this.channel1.configureBlocking(false);
377        DatagramSocket s = this.channel1.socket();
378        assertSocketActionAfterConnect(s);
379    }
380
381    private void assertSocketActionAfterConnect(DatagramSocket s) throws IOException {
382        assertEquals(s.getPort(), datagramSocket1Address.getPort());
383        try {
384            s.connect(datagramSocket2Address);
385            fail();
386        } catch (IllegalStateException expected) {
387        }
388
389        assertTrue(this.channel1.isConnected());
390        assertTrue(s.isConnected());
391        // not changed
392        assertEquals(s.getPort(), datagramSocket1Address.getPort());
393
394        s.disconnect();
395        assertFalse(this.channel1.isConnected());
396        assertFalse(s.isConnected());
397
398        s.close();
399        assertTrue(s.isClosed());
400        assertFalse(this.channel1.isOpen());
401    }
402
403    // -------------------------------------------------------------------
404    // Test for isConnected()
405    // -------------------------------------------------------------------
406
407    /**
408     * Test method for 'DatagramChannelImpl.isConnected()'
409     */
410    public void testIsConnected_WithServer() throws IOException {
411        connectLocalServer();
412        disconnectAfterConnected();
413        this.datagramSocket1.close();
414        this.channel1.close();
415        assertFalse(this.channel1.isConnected());
416    }
417
418    // -------------------------------------------------------------------
419    // Test for connect()
420    // -------------------------------------------------------------------
421
422    /**
423     * Test method for 'DatagramChannelImpl.connect(SocketAddress)'
424     */
425    public void testConnect_BlockWithServer() throws IOException {
426        // blocking mode
427        assertTrue(this.channel1.isBlocking());
428        connectLocalServer();
429        datagramSocket1.close();
430        disconnectAfterConnected();
431    }
432
433    /**
434     * Test method for 'DatagramChannelImpl.connect(SocketAddress)'
435     */
436    public void testConnect_BlockNoServer() throws IOException {
437        connectWithoutServer();
438        disconnectAfterConnected();
439    }
440
441    /**
442     * Test method for 'DatagramChannelImpl.connect(SocketAddress)'
443     */
444    public void testConnect_NonBlockWithServer() throws IOException {
445        // Non blocking mode
446        this.channel1.configureBlocking(false);
447        connectLocalServer();
448        datagramSocket1.close();
449        disconnectAfterConnected();
450    }
451
452    /**
453     * Test method for 'DatagramChannelImpl.connect(SocketAddress)'
454     */
455    public void testConnect_Null() throws IOException {
456        assertFalse(this.channel1.isConnected());
457        try {
458            this.channel1.connect(null);
459            fail("Should throw an IllegalArgumentException here."); //$NON-NLS-1$
460        } catch (IllegalArgumentException e) {
461            // OK.
462        }
463    }
464
465    /**
466     * Test method for 'DatagramChannelImpl.connect(SocketAddress)'
467     */
468    public void testConnect_UnsupportedType() throws IOException {
469        assertFalse(this.channel1.isConnected());
470        class SubSocketAddress extends SocketAddress {
471            private static final long serialVersionUID = 1L;
472
473            public SubSocketAddress() {
474                super();
475            }
476        }
477        SocketAddress newTypeAddress = new SubSocketAddress();
478        try {
479            this.channel1.connect(newTypeAddress);
480            fail("Should throw an UnsupportedAddressTypeException here.");
481        } catch (UnsupportedAddressTypeException e) {
482            // OK.
483        }
484    }
485
486    /**
487     * Test method for 'DatagramChannelImpl.connect(SocketAddress)'
488     */
489    public void testConnect_Unresolved() throws IOException {
490        assertFalse(this.channel1.isConnected());
491        InetSocketAddress unresolved = new InetSocketAddress(
492                "unresolved address", 1080);
493        try {
494            this.channel1.connect(unresolved);
495            fail("Should throw an UnresolvedAddressException here."); //$NON-NLS-1$
496        } catch (UnresolvedAddressException e) {
497            // OK.
498        }
499    }
500
501    public void testConnect_EmptyHost() throws Exception {
502        assertFalse(this.channel1.isConnected());
503
504        assertEquals(this.channel1, this.channel1
505                .connect(new InetSocketAddress("", 1081)));
506
507    }
508
509    /**
510     * Test method for 'DatagramChannelImpl.connect(SocketAddress)'
511     */
512    public void testConnect_ClosedChannelException() throws IOException {
513        assertFalse(this.channel1.isConnected());
514        this.channel1.close();
515        assertFalse(this.channel1.isOpen());
516        try {
517            this.channel1.connect(datagramSocket1Address);
518            fail("Should throw ClosedChannelException."); //$NON-NLS-1$
519        } catch (ClosedChannelException e) {
520            // OK.
521        }
522    }
523
524    /**
525     * Test method for 'DatagramChannelImpl.connect(SocketAddress)'
526     */
527    public void testConnect_IllegalStateException() throws IOException {
528        assertFalse(this.channel1.isConnected());
529        this.channel1.connect(datagramSocket1Address);
530        assertTrue(this.channel1.isConnected());
531        // connect after connected.
532        try {
533            this.channel1.connect(datagramSocket1Address);
534            fail("Should throw IllegalStateException."); //$NON-NLS-1$
535        } catch (IllegalStateException e) {
536            // OK.
537        }
538    }
539
540    /**
541     * Test method for 'DatagramChannelImpl.connect(SocketAddress)'
542     */
543    public void testConnect_CheckOpenBeforeStatus() throws IOException {
544        assertFalse(this.channel1.isConnected());
545        this.channel1.connect(datagramSocket1Address);
546        assertTrue(this.channel1.isConnected());
547        // connect after connected.
548        this.channel1.close();
549        assertFalse(this.channel1.isOpen());
550        // checking open is before checking status.
551        try {
552            this.channel1.connect(datagramSocket1Address);
553            fail("Should throw ClosedChannelException."); //$NON-NLS-1$
554        } catch (ClosedChannelException e) {
555            // OK.
556        }
557    }
558
559    private void disconnectAfterConnected() throws IOException {
560        assertTrue(this.channel1.isConnected());
561        this.channel1.disconnect();
562        assertFalse(this.channel1.isConnected());
563    }
564
565    private void disconnectAfterClosed() throws IOException {
566        assertFalse(this.channel1.isOpen());
567        assertFalse(this.channel1.isConnected());
568        this.channel1.disconnect();
569        assertFalse(this.channel1.isConnected());
570    }
571
572    private void connectLocalServer() throws IOException {
573        assertFalse(this.channel1.isConnected());
574        assertTrue(this.datagramSocket1.isBound());
575        assertSame(this.channel1, this.channel1.connect(datagramSocket1Address));
576        assertTrue(this.channel1.isConnected());
577    }
578
579    private void connectWithoutServer() throws IOException {
580        assertFalse(this.channel1.isConnected());
581        this.datagramSocket1.close();
582        assertTrue(this.datagramSocket1.isClosed());
583        assertSame(this.channel1, this.channel1.connect(datagramSocket1Address));
584        assertTrue(this.channel1.isConnected());
585    }
586
587    // -------------------------------------------------------------------
588    // Test for disconnect()
589    // -------------------------------------------------------------------
590
591    /**
592     * Test method for 'DatagramChannelImpl.disconnect()'
593     */
594    public void testDisconnect_BeforeConnect() throws IOException {
595        assertFalse(this.channel1.isConnected());
596        assertEquals(this.channel1, this.channel1.disconnect());
597        assertFalse(this.channel1.isConnected());
598    }
599
600    /**
601     * Test method for 'DatagramChannelImpl.disconnect()'
602     */
603    public void testDisconnect_UnconnectedClosed() throws IOException {
604        assertFalse(this.channel1.isConnected());
605        this.channel1.close();
606        assertFalse(this.channel1.isOpen());
607        assertEquals(this.channel1, this.channel1.disconnect());
608        assertFalse(this.channel1.isConnected());
609    }
610
611    /**
612     * Test method for 'DatagramChannelImpl.disconnect()'
613     */
614    public void testDisconnect_BlockWithServerChannelClosed()
615            throws IOException {
616        assertTrue(this.channel1.isBlocking());
617        connectLocalServer();
618        // disconnect after channel close
619        this.channel1.close();
620        disconnectAfterClosed();
621    }
622
623    /**
624     * Test method for 'DatagramChannelImpl.disconnect()'
625     */
626    public void testDisconnect_NonBlockWithServerChannelClosed()
627            throws IOException {
628        this.channel1.configureBlocking(false);
629        connectLocalServer();
630        // disconnect after channel close
631        this.channel1.close();
632        disconnectAfterClosed();
633    }
634
635    /**
636     * Test method for 'DatagramChannelImpl.disconnect()'
637     */
638    public void testDisconnect_BlockWithServerServerClosed() throws IOException {
639        assertTrue(this.channel1.isBlocking());
640        connectLocalServer();
641        // disconnect after server close
642        this.datagramSocket1.close();
643        assertTrue(this.channel1.isOpen());
644        assertTrue(this.channel1.isConnected());
645        disconnectAfterConnected();
646    }
647
648    /**
649     * Test method for 'DatagramChannelImpl.disconnect()'
650     */
651    public void testDisconnect_NonBlockWithServerServerClosed()
652            throws IOException {
653        this.channel1.configureBlocking(false);
654        assertFalse(this.channel1.isBlocking());
655        connectLocalServer();
656        // disconnect after server close
657        this.datagramSocket1.close();
658        assertTrue(this.channel1.isOpen());
659        assertTrue(this.channel1.isConnected());
660        disconnectAfterConnected();
661    }
662
663    // -------------------------------------------------------------------
664    // Test for receive(): Behavior Without Server.
665    // -------------------------------------------------------------------
666
667    /**
668     * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
669     */
670    public void testReceive_UnconnectedNull() throws Exception {
671        assertFalse(this.channel1.isConnected());
672        try {
673            this.channel1.receive(null);
674            fail("Should throw a NPE here."); //$NON-NLS-1$
675        } catch (NullPointerException e) {
676            // OK.
677        }
678    }
679
680    /**
681     * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
682     */
683    public void testReceive_UnconnectedReadonly() throws Exception {
684        assertFalse(this.channel1.isConnected());
685        ByteBuffer dst = ByteBuffer.allocateDirect(CAPACITY_NORMAL)
686                .asReadOnlyBuffer();
687        assertTrue(dst.isReadOnly());
688        try {
689            this.channel1.receive(dst);
690            fail("Should throw an IllegalArgumentException here."); //$NON-NLS-1$
691        } catch (IllegalArgumentException e) {
692            // OK.
693        }
694    }
695
696    /**
697     * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
698     */
699    public void testReceive_UnconnectedBufEmpty() throws Exception {
700        this.channel1.configureBlocking(false);
701        assertFalse(this.channel1.isConnected());
702        ByteBuffer dst = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
703        assertNull(this.channel1.receive(dst));
704    }
705
706    public void testReceive_UnboundBufZero() throws Exception {
707        DatagramChannel dc = DatagramChannel.open();
708
709        assertFalse(dc.isConnected());
710        assertFalse(dc.socket().isBound());
711        ByteBuffer dst = ByteBuffer.allocateDirect(CAPACITY_ZERO);
712        assertNull(dc.receive(dst));
713
714        dc.close();
715    }
716
717    public void testReceive_UnboundBufNotEmpty() throws Exception {
718        DatagramChannel dc = DatagramChannel.open();
719        assertFalse(dc.isConnected());
720        assertFalse(dc.socket().isBound());
721
722        ByteBuffer dst = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
723        // buf is not empty
724        dst.put((byte) 88);
725        assertEquals(dst.position() + CAPACITY_NORMAL - 1, dst.limit());
726        assertNull(dc.receive(dst));
727
728        dc.close();
729    }
730
731    public void testReceive_UnboundBufFull() throws Exception {
732        DatagramChannel dc = DatagramChannel.open();
733
734        assertFalse(dc.isConnected());
735        assertFalse(dc.socket().isBound());
736        ByteBuffer dst = ByteBuffer.allocateDirect(CAPACITY_ONE);
737
738        // buf is full
739        dst.put((byte) 88);
740        assertEquals(dst.position(), dst.limit());
741        assertNull(dc.receive(dst));
742
743        dc.close();
744    }
745
746    /**
747     * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
748     */
749    public void testReceive_UnconnectedClose() throws Exception {
750        assertFalse(this.channel1.isConnected());
751        ByteBuffer dst = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
752        this.channel1.close();
753        assertFalse(this.channel1.isOpen());
754        try {
755            assertNull(this.channel1.receive(dst));
756            fail("Should throw a ClosedChannelException here."); //$NON-NLS-1$
757        } catch (ClosedChannelException e) {
758            // OK.
759        }
760    }
761
762    /**
763     * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
764     */
765    public void testReceive_UnconnectedCloseNull() throws Exception {
766        assertFalse(this.channel1.isConnected());
767        this.channel1.close();
768        assertFalse(this.channel1.isOpen());
769        // checking buffer before checking open
770        try {
771            this.channel1.receive(null);
772            fail("Should throw a NPE here."); //$NON-NLS-1$
773        } catch (NullPointerException e) {
774            // OK.
775        }
776    }
777
778    /**
779     * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
780     */
781    public void testReceive_UnconnectedCloseReadonly() throws Exception {
782        assertFalse(this.channel1.isConnected());
783        ByteBuffer dst = ByteBuffer.allocateDirect(CAPACITY_NORMAL)
784                .asReadOnlyBuffer();
785        assertTrue(dst.isReadOnly());
786        this.channel1.close();
787        assertFalse(this.channel1.isOpen());
788        try {
789            this.channel1.receive(dst);
790            fail("Should throw an IllegalArgumentException here."); //$NON-NLS-1$
791        } catch (IllegalArgumentException e) {
792            // OK.
793        }
794    }
795
796    /**
797     * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
798     */
799    public void testReceive_NonBlockNoServerBufEmpty() throws Exception {
800        this.channel1.configureBlocking(false);
801        receiveNonBlockNoServer(CAPACITY_NORMAL);
802    }
803
804    /**
805     * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
806     */
807    public void testReceive_BlockNoServerNull() throws Exception {
808        assertTrue(this.channel1.isBlocking());
809        receiveNoServerNull();
810    }
811
812    /**
813     * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
814     */
815    public void testReceive_NonBlockNoServerNull() throws Exception {
816        this.channel1.configureBlocking(false);
817        receiveNoServerNull();
818    }
819
820    /**
821     * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
822     */
823    public void testReceive_BlockNoServerReadonly() throws Exception {
824        assertTrue(this.channel1.isBlocking());
825        receiveNoServerReadonly();
826    }
827
828    /**
829     * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
830     */
831    public void testReceive_NonBlockNoServerReadonly() throws Exception {
832        this.channel1.configureBlocking(false);
833        receiveNoServerReadonly();
834    }
835
836    /**
837     * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
838     */
839    public void testReceive_NonBlockNoServerBufZero() throws Exception {
840        this.channel1.configureBlocking(false);
841        receiveNonBlockNoServer(CAPACITY_ZERO);
842    }
843
844    /**
845     * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
846     */
847    public void testReceive_NonBlockNoServerBufNotEmpty() throws Exception {
848        this.channel1.configureBlocking(false);
849        connectWithoutServer();
850        ByteBuffer dst = allocateNonEmptyBuf();
851        assertNull(this.channel1.receive(dst));
852    }
853
854
855    /**
856     * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
857     */
858    public void testReceive_NonBlockNoServerBufFull() throws Exception {
859        this.channel1.configureBlocking(false);
860        connectWithoutServer();
861        ByteBuffer dst = allocateFullBuf();
862        assertNull(this.channel1.receive(dst));
863    }
864
865    /**
866     * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
867     */
868    public void testReceive_BlockNoServerChannelClose() throws Exception {
869        assertTrue(this.channel1.isBlocking());
870        receiveNoServerChannelClose();
871    }
872
873    /**
874     * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
875     */
876    public void testReceive_NonBlockNoServerChannelClose() throws Exception {
877        this.channel1.configureBlocking(false);
878        receiveNoServerChannelClose();
879    }
880
881    /**
882     * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
883     */
884    public void testReceive_BlockNoServerCloseNull() throws Exception {
885        assertTrue(this.channel1.isBlocking());
886        receiveNoServerChannelCloseNull();
887    }
888
889    /**
890     * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
891     */
892    public void testReceive_NonBlockNoServerCloseNull() throws Exception {
893        this.channel1.configureBlocking(false);
894        receiveNoServerChannelCloseNull();
895    }
896
897    /**
898     * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
899     */
900    public void testReceive_NonBlockNoServerCloseReadonly() throws Exception {
901        this.channel1.configureBlocking(false);
902        receiveNoServerChannelCloseReadonly();
903    }
904
905    /**
906     * Test method for 'DatagramChannelImpl.receive(ByteBuffer)'
907     */
908    public void testReceive_BlockNoServerCloseReadonly() throws Exception {
909        assertTrue(this.channel1.isBlocking());
910        receiveNoServerChannelCloseReadonly();
911    }
912
913    private void receiveNoServerNull() throws IOException {
914        connectWithoutServer();
915        try {
916            this.channel1.receive(null);
917            fail("Should throw a NPE here."); //$NON-NLS-1$
918        } catch (NullPointerException e) {
919            // OK.
920        }
921    }
922
923    private void receiveNoServerReadonly() throws IOException {
924        connectWithoutServer();
925        ByteBuffer dst = ByteBuffer.allocateDirect(CAPACITY_NORMAL)
926                .asReadOnlyBuffer();
927        assertTrue(dst.isReadOnly());
928        try {
929            this.channel1.receive(dst);
930            fail("Should throw an IllegalArgumentException here."); //$NON-NLS-1$
931        } catch (IllegalArgumentException e) {
932            // OK.
933        }
934    }
935
936    private void receiveNonBlockNoServer(int size) throws IOException {
937        connectWithoutServer();
938        ByteBuffer dst = ByteBuffer.allocateDirect(size);
939        assertNull(this.channel1.receive(dst));
940    }
941
942    private void receiveNoServerChannelClose() throws IOException {
943        connectWithoutServer();
944        ByteBuffer dst = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
945        this.channel1.close();
946        assertFalse(this.channel1.isOpen());
947        try {
948            assertNull(this.channel1.receive(dst));
949            fail("Should throw a ClosedChannelException here."); //$NON-NLS-1$
950        } catch (ClosedChannelException e) {
951            // OK.
952        }
953    }
954
955    private void receiveNoServerChannelCloseNull() throws IOException {
956        connectWithoutServer();
957        this.channel1.close();
958        assertFalse(this.channel1.isOpen());
959        try {
960            this.channel1.receive(null);
961            fail("Should throw a NPE here."); //$NON-NLS-1$
962        } catch (NullPointerException e) {
963            // OK.
964        }
965    }
966
967    private void receiveNoServerChannelCloseReadonly() throws IOException {
968        connectWithoutServer();
969        this.channel1.close();
970        assertFalse(this.channel1.isOpen());
971        ByteBuffer dst = ByteBuffer.allocateDirect(CAPACITY_NORMAL)
972                .asReadOnlyBuffer();
973        assertTrue(dst.isReadOnly());
974        try {
975            this.channel1.receive(dst);
976            fail("Should throw an IllegalArgumentException here."); //$NON-NLS-1$
977        } catch (IllegalArgumentException e) {
978            // OK.
979        }
980    }
981
982    private ByteBuffer allocateFullBuf() {
983        ByteBuffer dst = ByteBuffer.allocateDirect(CAPACITY_ONE);
984        // buf is full
985        dst.put((byte) 88);
986        assertEquals(dst.position(), dst.limit());
987        return dst;
988    }
989
990    private ByteBuffer allocateNonEmptyBuf() {
991        ByteBuffer dst = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
992        // buf is not empty
993        dst.put((byte) 88);
994        dst.put((byte) 99);
995        assertEquals(dst.position() + CAPACITY_NORMAL - 2, dst.limit());
996        return dst;
997    }
998
999    // -------------------------------------------------------------------
1000    // Test for send(): Behavior without server.
1001    // -------------------------------------------------------------------
1002
1003    private void sendDataBlocking(InetSocketAddress addr, ByteBuffer writeBuf)
1004            throws IOException {
1005        InetSocketAddress ipAddr = addr;
1006        assertEquals(CAPACITY_NORMAL, this.channel1.send(writeBuf, ipAddr));
1007        assertTrue(this.channel1.isOpen());
1008        assertTrue(this.channel1.isBlocking());
1009        this.channel1.connect(ipAddr);
1010        assertTrue(this.channel1.isConnected());
1011    }
1012
1013    private void sendDataNonBlocking(InetSocketAddress addr, ByteBuffer writeBuf)
1014            throws IOException {
1015        InetSocketAddress ipAddr = addr;
1016        this.channel1.configureBlocking(false);
1017        assertEquals(CAPACITY_NORMAL, this.channel1.send(writeBuf, ipAddr));
1018        assertTrue(this.channel1.isOpen());
1019        assertFalse(this.channel1.isBlocking());
1020        this.channel1.connect(ipAddr);
1021        assertTrue(this.channel1.isConnected());
1022    }
1023
1024    /*
1025     * Test method for 'DatagramChannelImpl.send(ByteBuffer, SocketAddress)'
1026     */
1027    public void testSend_NoServerBlockingCommon() throws IOException {
1028        ByteBuffer writeBuf = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
1029        sendDataBlocking(datagramSocket1Address, writeBuf);
1030    }
1031
1032    public void testSend_NoServerNonblockingCommon() throws IOException {
1033        ByteBuffer writeBuf = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
1034        sendDataNonBlocking(datagramSocket1Address, writeBuf);
1035    }
1036
1037    public void testSend_NoServerTwice() throws IOException {
1038        ByteBuffer writeBuf = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
1039        sendDataBlocking(datagramSocket1Address, writeBuf);
1040        // can not buffer twice!
1041        assertEquals(0, this.channel1.send(writeBuf, datagramSocket1Address));
1042        try {
1043            channel1.send(writeBuf, datagramSocket2Address);
1044            fail("Should throw IllegalArgumentException");
1045        } catch (IllegalArgumentException e) {
1046            // correct
1047        }
1048    }
1049
1050    public void testSend_NoServerNonBlockingTwice() throws IOException {
1051        ByteBuffer writeBuf = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
1052        sendDataNonBlocking(datagramSocket1Address, writeBuf);
1053        // can not buffer twice!
1054        assertEquals(0, this.channel1.send(writeBuf, datagramSocket1Address));
1055        try {
1056            channel1.send(writeBuf, datagramSocket2Address);
1057            fail("Should throw IllegalArgumentException");
1058        } catch (IllegalArgumentException e) {
1059            // correct
1060        }
1061    }
1062
1063    public void testSend_NoServerBufNull() throws IOException {
1064        try {
1065            sendDataBlocking(datagramSocket1Address, null);
1066            fail("Should throw a NPE here.");
1067        } catch (NullPointerException e) {
1068            // correct
1069        }
1070    }
1071
1072    public void testSend_NoServerBufNullTwice() throws IOException {
1073        ByteBuffer writeBuf = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
1074        try {
1075            sendDataBlocking(datagramSocket1Address, null);
1076            fail("Should throw a NPE here.");
1077        } catch (NullPointerException e) {
1078            // correct
1079        }
1080        sendDataBlocking(datagramSocket1Address, writeBuf);
1081        try {
1082            channel1.send(null, datagramSocket2Address);
1083            fail("Should throw NPE");
1084        } catch (NullPointerException e) {
1085            // correct
1086        }
1087    }
1088
1089    public void testSend_NoServerAddrNull() throws IOException {
1090        ByteBuffer writeBuf = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
1091        try {
1092            sendDataBlocking(null, writeBuf);
1093            fail("Should throw a IAE here.");
1094        } catch (IllegalArgumentException expected) {
1095        }
1096    }
1097
1098    public void testSend_NoServerAddrNullTwice() throws IOException {
1099        ByteBuffer writeBuf = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
1100        try {
1101            sendDataBlocking(null, writeBuf);
1102            fail("Should throw a IAE here.");
1103        } catch (IllegalArgumentException expected) {
1104        }
1105
1106        sendDataBlocking(datagramSocket1Address, writeBuf);
1107        try {
1108            channel1.send(writeBuf, null);
1109            fail("Should throw a IAE here.");
1110        } catch (IllegalArgumentException expected) {
1111        }
1112    }
1113
1114    // -------------------------------------------------------------------
1115    // Test for receive()and send(): Send and Receive with Real Data
1116    // -------------------------------------------------------------------
1117
1118    public void testReceiveSend_Block_Normal() throws Exception {
1119        sendOnChannel2("some normal string in testReceiveSend_Normal",
1120                channel1Address);
1121        receiveOnChannel1AndClose(CAPACITY_NORMAL, channel2Address,
1122                "some normal string in testReceiveSend_Normal");
1123    }
1124
1125    public void testReceiveSend_NonBlock_NotBound() throws Exception {
1126        // not bound
1127        this.channel1.configureBlocking(false);
1128        this.channel2.configureBlocking(false);
1129        sendOnChannel2("some normal string in testReceiveSend_Normal",
1130                datagramSocket2Address);
1131        ByteBuffer buf = ByteBuffer.wrap(new byte[CAPACITY_NORMAL]);
1132        assertNull(this.channel1.receive(buf));
1133    }
1134
1135    public void testReceiveSend_Block_Normal_S2C() throws Exception {
1136        sendOnDatagramSocket1(
1137                "some normal string in testReceiveSend_Normal_S2C", channel1Address);
1138        receiveOnChannel1AndClose(CAPACITY_NORMAL, datagramSocket1Address,
1139                "some normal string in testReceiveSend_Normal_S2C");
1140    }
1141
1142    public void testReceiveSend_Block_Normal_C2S() throws Exception {
1143        String str1 = "some normal string in testReceiveSend_Normal_C2S";
1144        sendOnChannel2(str1, datagramSocket1Address);
1145        receiveOnDatagramSocket1(CAPACITY_NORMAL, str1);
1146    }
1147
1148    public void testReceiveSend_NonBlock_Normal_C2S() throws Exception {
1149        this.channel1.configureBlocking(false);
1150        this.channel2.configureBlocking(false);
1151        String str1 = "some normal string in testReceiveSend_Normal_C2S";
1152        sendOnChannel2(str1, datagramSocket1Address);
1153        receiveOnDatagramSocket1(CAPACITY_NORMAL, str1);
1154    }
1155
1156    public void testReceiveSend_Normal_S2S() throws Exception {
1157        String msg = "normal string in testReceiveSend_Normal_S2S";
1158        DatagramPacket rdp = new DatagramPacket(msg.getBytes(), msg.length(),
1159                datagramSocket2Address);
1160        this.datagramSocket1.send(rdp);
1161        byte[] buf = new byte[CAPACITY_NORMAL];
1162        this.datagramSocket2.setSoTimeout(TIME_UNIT);
1163        rdp = new DatagramPacket(buf, buf.length);
1164        this.datagramSocket2.receive(rdp);
1165        assertEquals(new String(buf, 0, CAPACITY_NORMAL).trim(), msg);
1166    }
1167
1168    public void testReceiveSend_Block_Empty() throws Exception {
1169        sendOnChannel2("", channel1Address);
1170        receiveOnChannel1AndClose(CAPACITY_NORMAL, channel2Address, "");
1171    }
1172
1173    public void testReceiveSend_NonBlock_Empty() throws Exception {
1174        this.channel1.configureBlocking(false);
1175        this.channel2.configureBlocking(false);
1176        sendOnChannel2("", channel1Address);
1177        receiveOnChannel1AndClose(CAPACITY_NORMAL, channel2Address, "");
1178    }
1179
1180    public void testReceiveSend_Block_Empty_S2C() throws Exception {
1181        sendOnDatagramSocket1("", channel1Address);
1182        receiveOnChannel1AndClose(CAPACITY_NORMAL, datagramSocket1Address, "");
1183    }
1184
1185    public void testReceiveSend_NonBlock_Empty_S2C() throws Exception {
1186        this.channel1.configureBlocking(false);
1187        this.channel2.configureBlocking(false);
1188        sendOnDatagramSocket1("", channel1Address);
1189        receiveOnChannel1AndClose(CAPACITY_NORMAL, datagramSocket1Address, "");
1190    }
1191
1192    public void testReceiveSend_Block_Empty_C2S() throws Exception {
1193        sendOnChannel2("", datagramSocket1Address);
1194        receiveOnDatagramSocket1(CAPACITY_NORMAL, "");
1195    }
1196
1197    public void testReceiveSend_NonBlock_Empty_C2S() throws Exception {
1198        this.channel1.configureBlocking(false);
1199        this.channel2.configureBlocking(false);
1200        sendOnChannel2("", datagramSocket1Address);
1201        receiveOnDatagramSocket1(CAPACITY_NORMAL, "");
1202    }
1203
1204    public void testReceiveSend_Empty_S2S() throws Exception {
1205        String msg = "";
1206        DatagramPacket rdp = new DatagramPacket(msg.getBytes(), msg.length(),
1207                datagramSocket2Address);
1208        this.datagramSocket1.send(rdp);
1209        byte[] buf = new byte[CAPACITY_NORMAL];
1210        this.datagramSocket2.setSoTimeout(TIME_UNIT);
1211        rdp = new DatagramPacket(buf, buf.length);
1212        this.datagramSocket2.receive(rdp);
1213        assertEquals(new String(buf, 0, CAPACITY_NORMAL).trim(), msg);
1214    }
1215
1216    public void testReceiveSend_Block_Oversize() throws Exception {
1217        sendOnChannel2("0123456789", channel1Address);
1218        receiveOnChannel1AndClose(5, channel2Address, "01234");
1219    }
1220
1221    public void testReceiveSend_Block_Oversize_C2S() throws Exception {
1222        sendOnChannel2("0123456789", datagramSocket1Address);
1223        receiveOnDatagramSocket1(5, "01234");
1224    }
1225
1226    public void testReceiveSend_NonBlock_Oversize_C2S() throws Exception {
1227        this.channel1.configureBlocking(false);
1228        this.channel2.configureBlocking(false);
1229        sendOnChannel2("0123456789", datagramSocket1Address);
1230        receiveOnDatagramSocket1(5, "01234");
1231    }
1232
1233    public void testReceiveSend_Block_Oversize_S2C() throws Exception {
1234        sendOnDatagramSocket1("0123456789", channel1Address);
1235        receiveOnChannel1AndClose(5, datagramSocket1Address, "01234");
1236    }
1237
1238    public void testReceiveSend_8K() throws Exception {
1239        StringBuffer str8k = new StringBuffer();
1240        for (int i = 0; i < 8 * CAPACITY_1KB; i++) {
1241            str8k.append('a');
1242        }
1243        String str = str8k.toString();
1244
1245        sendOnChannel2(str, channel1Address);
1246        receiveOnChannel1AndClose(8 * CAPACITY_1KB, channel2Address, str);
1247    }
1248
1249    public void testReceiveSend_64K() throws Exception {
1250        StringBuffer str64k = new StringBuffer();
1251        for (int i = 0; i < CAPACITY_64KB; i++) {
1252            str64k.append('a');
1253        }
1254        String str = str64k.toString();
1255        try {
1256            Thread.sleep(TIME_UNIT);
1257            channel2.send(ByteBuffer.wrap(str.getBytes()), datagramSocket1Address);
1258            fail("Should throw SocketException!");
1259        } catch (SocketException expected) {
1260        }
1261    }
1262
1263    private void sendOnChannel2(String data, SocketAddress address)
1264            throws IOException {
1265        assertEquals(data.length(), channel2.send(ByteBuffer.wrap(data.getBytes()), address));
1266    }
1267
1268    private void sendOnDatagramSocket1(String data, InetSocketAddress address)
1269            throws Exception {
1270        DatagramPacket rdp = new DatagramPacket(data.getBytes(), data.length(), address);
1271        this.datagramSocket1.send(rdp);
1272    }
1273
1274    private void receiveOnChannel1AndClose(int bufSize,
1275            InetSocketAddress expectedAddress, String expectedString) throws IOException {
1276        try {
1277            ByteBuffer buf = ByteBuffer.wrap(new byte[bufSize]);
1278            InetSocketAddress senderAddr;
1279            long startTime = System.currentTimeMillis();
1280            do {
1281                senderAddr = (InetSocketAddress) this.channel1.receive(buf);
1282                // continue loop when channel1 is non-blocking and no data was
1283                // received.
1284                if (channel1.isBlocking() || senderAddr != null) {
1285                    break;
1286                }
1287                // avoid dead loop
1288                assertTimeout(startTime, 10000);
1289            } while (true);
1290
1291            assertEquals(senderAddr.getAddress(), Inet6Address.LOOPBACK);
1292            assertEquals(expectedAddress.getPort(), senderAddr.getPort());
1293            assertEquals(new String(buf.array(), 0, buf.position()), expectedString);
1294        } finally {
1295            this.channel1.close();
1296        }
1297    }
1298
1299    /*
1300     * Fails if the difference between current time and start time is greater
1301     * than timeout.
1302     */
1303    private void assertTimeout(long startTime, long timeout) {
1304        long currentTime = System.currentTimeMillis();
1305        if ((currentTime - startTime) > timeout) {
1306            fail("Timeout");
1307        }
1308    }
1309
1310    private void receiveOnDatagramSocket1(int bufSize, String expectedString)
1311            throws IOException {
1312        byte[] buf = new byte[bufSize];
1313        this.datagramSocket1.setSoTimeout(6000);
1314        DatagramPacket rdp = new DatagramPacket(buf, buf.length);
1315        this.datagramSocket1.receive(rdp);
1316        assertEquals(new String(buf, 0, bufSize).trim(), expectedString);
1317    }
1318
1319    public void testRead_fromSend() throws Exception {
1320        ByteBuffer buf = ByteBuffer.allocate(CAPACITY_NORMAL);
1321        String strHello = "hello";
1322
1323        this.channel1.connect(channel2Address);
1324        this.channel2.send(ByteBuffer.wrap(strHello.getBytes()), channel1Address);
1325
1326        assertEquals(strHello.length(), this.channel1.read(buf));
1327        assertAscii(buf, strHello);
1328    }
1329
1330    public void testReceive_Peek_NoSecurity_Nonblocking() throws Exception {
1331        String strHello = "hello";
1332
1333        sendOnChannel2(strHello, channel1Address);
1334        this.channel1.configureBlocking(false);
1335        // for accepted addr, no problem.
1336        ByteBuffer buf = ByteBuffer.allocate(CAPACITY_NORMAL);
1337
1338        InetSocketAddress source = (InetSocketAddress) this.channel1.receive(buf);
1339        assertEquals(channel2Address, source);
1340        assertAscii(buf, strHello);
1341    }
1342
1343    private static void assertAscii(ByteBuffer b, String s) {
1344        assertEquals(s.length(), b.position());
1345        for (int i = 0; i < s.length(); ++i) {
1346            assertEquals(s.charAt(i), b.get(i));
1347        }
1348    }
1349
1350    // -------------------------------------------------------------------
1351    // Test for write()
1352    // -------------------------------------------------------------------
1353
1354    private void connectWriteBuf(InetSocketAddress ipAddr, ByteBuffer buf)
1355            throws IOException {
1356        this.channel1.connect(ipAddr);
1357        assertTrue(this.channel1.isConnected());
1358        assertEquals(CAPACITY_NORMAL, this.channel1.write(buf));
1359        assertEquals(0, this.channel1.write(buf));
1360    }
1361
1362    private void noconnectWrite(ByteBuffer buf) throws IOException {
1363        try {
1364            this.channel1.write(buf);
1365            fail("should throw NotYetConnectedException");
1366        } catch (NotYetConnectedException e) {
1367            // correct
1368        }
1369    }
1370
1371    /*
1372     * Test method for 'DatagramChannelImpl.write(ByteBuffer)'
1373     */
1374    public void testWriteByteBuffer_Block() throws IOException {
1375        ByteBuffer writeBuf = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
1376        connectWriteBuf(datagramSocket1Address, writeBuf);
1377    }
1378
1379    public void testWriteByteBuffer_NonBlock() throws IOException {
1380        ByteBuffer writeBuf = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
1381        this.channel1.configureBlocking(false);
1382        connectWriteBuf(datagramSocket1Address, writeBuf);
1383    }
1384
1385    public void testWriteByteBuffer_Block_closed() throws IOException {
1386        ByteBuffer writeBuf = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
1387        InetSocketAddress ipAddr = datagramSocket1Address;
1388        noconnectWrite(writeBuf);
1389        this.channel1.connect(ipAddr);
1390        assertTrue(this.channel1.isConnected());
1391        this.channel1.close();
1392        try {
1393            channel1.write(writeBuf);
1394            fail("should throw ClosedChannelException");
1395        } catch (ClosedChannelException e) {
1396            // correct
1397        }
1398    }
1399
1400    public void testWriteByteBuffer_NonBlock_closed() throws IOException {
1401        ByteBuffer writeBuf = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
1402        InetSocketAddress ipAddr = datagramSocket1Address;
1403        // non block mode
1404        this.channel1.configureBlocking(false);
1405        noconnectWrite(writeBuf);
1406        this.channel1.connect(ipAddr);
1407        assertTrue(this.channel1.isConnected());
1408        this.channel1.close();
1409        try {
1410            channel1.write(writeBuf);
1411            fail("should throw ClosedChannelException");
1412        } catch (ClosedChannelException e) {
1413            // correct
1414        }
1415    }
1416
1417    public void testWriteByteBuffer_Block_BufNull() throws IOException {
1418        ByteBuffer writeBuf = ByteBuffer.allocateDirect(0);
1419        InetSocketAddress ipAddr = datagramSocket1Address;
1420        try {
1421            this.channel1.write((ByteBuffer) null);
1422            fail("Should throw NPE.");
1423        } catch (NullPointerException e) {
1424            // correct
1425        }
1426        this.channel1.connect(ipAddr);
1427        assertTrue(this.channel1.isConnected());
1428        try {
1429            this.channel1.write((ByteBuffer) null);
1430            fail("Should throw NPE.");
1431        } catch (NullPointerException e) {
1432            // correct
1433        }
1434        assertEquals(0, this.channel1.write(writeBuf));
1435        datagramSocket1.close();
1436        try {
1437            this.channel1.write((ByteBuffer) null);
1438            fail("Should throw NPE.");
1439        } catch (NullPointerException e) {
1440            // correct
1441        }
1442    }
1443
1444    public void testWriteByteBuffer_NonBlock_BufNull() throws IOException {
1445        ByteBuffer writeBuf = ByteBuffer.allocateDirect(0);
1446        InetSocketAddress ipAddr = datagramSocket1Address;
1447
1448        // non block mode
1449        this.channel1.configureBlocking(false);
1450
1451        try {
1452            this.channel1.write((ByteBuffer) null);
1453            fail("Should throw NPE.");
1454        } catch (NullPointerException e) {
1455            // correct
1456        }
1457        this.channel1.connect(ipAddr);
1458        assertTrue(this.channel1.isConnected());
1459        try {
1460            this.channel1.write((ByteBuffer) null);
1461            fail("Should throw NPE.");
1462        } catch (NullPointerException e) {
1463            // correct
1464        }
1465        assertEquals(0, this.channel1.write(writeBuf));
1466        datagramSocket1.close();
1467        try {
1468            this.channel1.write((ByteBuffer) null);
1469            fail("Should throw NPE.");
1470        } catch (NullPointerException e) {
1471            // correct
1472        }
1473    }
1474
1475    /*
1476     * Test method for 'DatagramChannelImpl.write(ByteBuffer[], int, int)'
1477     */
1478    public void testWriteByteBufferArrayIntInt_Block() throws IOException {
1479        ByteBuffer[] writeBuf = new ByteBuffer[2];
1480        writeBuf[0] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
1481        writeBuf[1] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
1482        InetSocketAddress ipAddr = datagramSocket1Address;
1483        try {
1484            this.channel1.write(writeBuf, 0, 2);
1485            fail("Should throw NotYetConnectedException.");
1486        } catch (NotYetConnectedException e) {
1487            // correct
1488        }
1489        this.channel1.connect(ipAddr);
1490        assertTrue(this.channel1.isConnected());
1491        assertEquals(CAPACITY_NORMAL * 2, this.channel1.write(writeBuf, 0, 2));
1492        // cannot be buffered again!
1493        assertEquals(0, this.channel1.write(writeBuf, 0, 1));
1494
1495    }
1496
1497    public void testWriteByteBufferArrayIntInt_NonBlock() throws IOException {
1498        ByteBuffer[] writeBuf = new ByteBuffer[2];
1499        writeBuf[0] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
1500        writeBuf[1] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
1501        InetSocketAddress ipAddr = datagramSocket1Address;
1502        // non-block mode
1503        this.channel1.configureBlocking(false);
1504        try {
1505            this.channel1.write(writeBuf, 0, 2);
1506            fail("Should throw NotYetConnectedException.");
1507        } catch (NotYetConnectedException e) {
1508            // correct
1509        }
1510        this.channel1.connect(ipAddr);
1511        assertTrue(this.channel1.isConnected());
1512        assertEquals(CAPACITY_NORMAL * 2, this.channel1.write(writeBuf, 0, 2));
1513        // cannot be buffered again!
1514        assertEquals(0, this.channel1.write(writeBuf, 0, 1));
1515
1516    }
1517
1518    public void testWriteByteBufferArrayIntInt_NoConnectIndexBad()
1519            throws IOException {
1520        ByteBuffer[] writeBuf = new ByteBuffer[2];
1521        writeBuf[0] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
1522        writeBuf[1] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
1523        InetSocketAddress ipAddr = datagramSocket1Address;
1524        try {
1525            this.channel1.write(writeBuf, -1, 2);
1526            fail("should throw IndexOutOfBoundsException");
1527        } catch (IndexOutOfBoundsException e) {
1528            // correct
1529        }
1530        try {
1531            this.channel1.write(writeBuf, 0, -1);
1532            fail("should throw IndexOutOfBoundsException");
1533        } catch (IndexOutOfBoundsException e) {
1534            // correct
1535        }
1536        this.channel1.connect(ipAddr);
1537        assertTrue(this.channel1.isConnected());
1538        assertEquals(CAPACITY_NORMAL * 2, this.channel1.write(writeBuf, 0, 2));
1539        // cannot be buffered again!
1540        assertEquals(0, this.channel1.write(writeBuf, 0, 1));
1541    }
1542
1543    public void testWriteByteBufferArrayIntInt_ConnectedIndexBad()
1544            throws IOException {
1545        ByteBuffer[] writeBuf = new ByteBuffer[2];
1546        writeBuf[0] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
1547        writeBuf[1] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
1548        InetSocketAddress ipAddr = datagramSocket1Address;
1549        this.channel1.connect(ipAddr);
1550        assertTrue(this.channel1.isConnected());
1551        try {
1552            this.channel1.write(writeBuf, -1, 2);
1553            fail("should throw IndexOutOfBoundsException");
1554        } catch (IndexOutOfBoundsException e) {
1555            // correct
1556        }
1557        try {
1558            this.channel1.write(writeBuf, 0, -1);
1559            fail("should throw IndexOutOfBoundsException");
1560        } catch (IndexOutOfBoundsException e) {
1561            // correct
1562        }
1563    }
1564
1565    public void testWriteByteBufferArrayIntInt_BufNullNoConnect()
1566            throws IOException {
1567        ByteBuffer[] writeBuf = new ByteBuffer[2];
1568        writeBuf[0] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
1569        try {
1570            this.channel1.write(null, 0, 2);
1571            fail();
1572        } catch (NullPointerException expected) {
1573        }
1574        try {
1575            this.channel1.write(writeBuf, -1, 2);
1576            fail();
1577        } catch (IndexOutOfBoundsException expected) {
1578        }
1579        try {
1580            this.channel1.write(writeBuf, 0, 3);
1581            fail();
1582        } catch (IndexOutOfBoundsException expected) {
1583        }
1584    }
1585
1586    public void testWriteByteBufferArrayIntInt_BufNullConnect()
1587            throws IOException {
1588        ByteBuffer[] writeBuf = new ByteBuffer[2];
1589        writeBuf[0] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
1590        InetSocketAddress ipAddr = datagramSocket1Address;
1591        this.channel1.connect(ipAddr);
1592        assertTrue(this.channel1.isConnected());
1593        try {
1594            this.channel1.write(null, 0, 2);
1595            fail("should throw NPE");
1596        } catch (NullPointerException e) {
1597            // correct
1598        }
1599        try {
1600            this.channel1.write(writeBuf, 0, 3);
1601            fail("should throw IndexOutOfBoundsException");
1602        } catch (IndexOutOfBoundsException e) {
1603            // correct
1604        }
1605        datagramSocket1.close();
1606        try {
1607            this.channel1.write(null, 0, 2);
1608            fail("should throw NPE");
1609        } catch (NullPointerException e) {
1610            // correct
1611        }
1612    }
1613
1614    // -------------------------------------------------------------------
1615    // Test for read()
1616    // -------------------------------------------------------------------
1617
1618    /*
1619     * Test method for 'DatagramChannelImpl.read(ByteBuffer)'
1620     */
1621    public void testReadByteBuffer() throws IOException {
1622        ByteBuffer readBuf = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
1623        try {
1624            this.channel1.read(readBuf);
1625            fail("should throw NotYetConnectedException");
1626        } catch (NotYetConnectedException e) {
1627            // correct
1628        }
1629        this.channel1.connect(datagramSocket1Address);
1630        assertTrue(this.channel1.isConnected());
1631        this.channel1.configureBlocking(false);
1632        // note : blocking-mode will make the read process endless!
1633        assertEquals(0, this.channel1.read(readBuf));
1634        this.channel1.close();
1635        try {
1636            this.channel1.read(readBuf);
1637            fail("Should throw ClosedChannelException");
1638        } catch (ClosedChannelException e) {
1639            // OK.
1640        }
1641    }
1642
1643    public void testReadByteBuffer_bufNull() throws IOException {
1644        ByteBuffer readBuf = ByteBuffer.allocateDirect(0);
1645        InetSocketAddress ipAddr = datagramSocket1Address;
1646        try {
1647            this.channel1.read(readBuf);
1648            fail("should throw NotYetConnectedException");
1649        } catch (NotYetConnectedException e) {
1650            // correct
1651        }
1652        this.channel1.connect(ipAddr);
1653        assertTrue(this.channel1.isConnected());
1654        try {
1655            channel1.read((ByteBuffer) null);
1656            fail("should throw NPE");
1657        } catch (NullPointerException e) {
1658            // correct
1659        }
1660        this.channel1.configureBlocking(false);
1661        // note : blocking-mode will make the read process endless!
1662        assertEquals(0, this.channel1.read(readBuf));
1663        datagramSocket1.close();
1664    }
1665
1666    /*
1667     * Test method for 'DatagramChannelImpl.read(ByteBuffer[], int, int)'
1668     */
1669    public void testReadByteBufferArrayIntInt() throws IOException {
1670        ByteBuffer[] readBuf = new ByteBuffer[2];
1671        readBuf[0] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
1672        readBuf[1] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
1673        InetSocketAddress ipAddr = datagramSocket1Address;
1674        try {
1675            this.channel1.read(readBuf, 0, 2);
1676            fail("should throw NotYetConnectedException");
1677        } catch (NotYetConnectedException e) {
1678            // correct
1679        }
1680        this.channel1.connect(ipAddr);
1681        assertTrue(this.channel1.isConnected());
1682        this.channel1.configureBlocking(false);
1683        // note : blocking-mode will make the read process endless!
1684        assertEquals(0, this.channel1.read(readBuf, 0, 1));
1685        assertEquals(0, this.channel1.read(readBuf, 0, 2));
1686        datagramSocket1.close();
1687    }
1688
1689    public void testReadByteBufferArrayIntInt_exceptions() throws IOException {
1690        //regression test for HARMONY-932
1691        try {
1692            DatagramChannel.open().read(new ByteBuffer[] {}, 2, Integer.MAX_VALUE);
1693            fail();
1694        } catch (IndexOutOfBoundsException expected) {
1695        }
1696        try {
1697            DatagramChannel.open().read(new ByteBuffer[] {}, -1, 0);
1698            fail();
1699        } catch (IndexOutOfBoundsException expected) {
1700        }
1701        try {
1702            DatagramChannel.open().read((ByteBuffer[]) null, 0, 0);
1703            fail();
1704        } catch (NullPointerException expected) {
1705        }
1706    }
1707
1708    public void testReadByteBufferArrayIntInt_BufNull() throws IOException {
1709        ByteBuffer[] readBuf = new ByteBuffer[2];
1710        readBuf[0] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
1711        InetSocketAddress ipAddr = datagramSocket1Address;
1712        try {
1713            this.channel1.read(null, 0, 0);
1714            fail("should throw NPE");
1715        } catch (NullPointerException e) {
1716            // correct
1717        }
1718        this.channel1.connect(ipAddr);
1719        assertTrue(this.channel1.isConnected());
1720        this.channel1.configureBlocking(false);
1721        // note : blocking-mode will make the read process endless!
1722        try {
1723            this.channel1.read(null, 0, 0);
1724            fail("should throw NPE");
1725        } catch (NullPointerException e) {
1726            // correct
1727        }
1728        assertEquals(0, this.channel1.read(readBuf, 0, 1));
1729        try {
1730            this.channel1.read(readBuf, 0, 2);
1731            fail("should throw NPE");
1732        } catch (NullPointerException e) {
1733            // correct
1734        }
1735        try {
1736            this.channel1.read(readBuf, 0, 3);
1737            fail("should throw IndexOutOfBoundsException");
1738        } catch (IndexOutOfBoundsException e) {
1739            // correct
1740        }
1741        datagramSocket1.close();
1742    }
1743
1744    // -------------------------------------------------------------------
1745    // test read and write
1746    // -------------------------------------------------------------------
1747
1748    public static class A {
1749        protected int z;
1750    }
1751
1752    public static class B extends A {
1753        protected int z;
1754
1755        void foo() {
1756            super.z+=1;
1757        }
1758    }
1759
1760
1761    public void testReadWrite_asyncClose() throws Exception {
1762        byte[] targetArray = new byte[2];
1763        ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
1764
1765        channel2.connect(channel1Address);
1766        channel1.connect(channel2Address);
1767
1768        new Thread() {
1769            public void run() {
1770                try {
1771                    Thread.sleep(TIME_UNIT);
1772                    channel1.close();
1773                } catch (Exception e) {
1774                    //ignore
1775                }
1776            }
1777        }.start();
1778
1779        try {
1780            this.channel1.read(targetBuf);
1781            fail("should throw AsynchronousCloseException");
1782        } catch (AsynchronousCloseException e) {
1783            // ok
1784        }
1785    }
1786
1787    public void testReadWrite_Block_Zero() throws Exception {
1788        byte[] sourceArray = new byte[0];
1789        byte[] targetArray = new byte[0];
1790
1791        channel1.connect(channel2Address);
1792        channel2.connect(channel1Address);
1793
1794        // write
1795        ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
1796        assertEquals(0, this.channel1.write(sourceBuf));
1797
1798        // read
1799        ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
1800        int readCount = this.channel2.read(targetBuf);
1801
1802        assertEquals(0, readCount);
1803    }
1804
1805    public void testReadWrite_Block_Normal() throws Exception {
1806        byte[] sourceArray = new byte[CAPACITY_NORMAL];
1807        byte[] targetArray = new byte[CAPACITY_NORMAL];
1808        for (int i = 0; i < sourceArray.length; i++) {
1809            sourceArray[i] = (byte) i;
1810        }
1811
1812        channel1.connect(channel2Address);
1813        channel2.connect(channel1Address);
1814
1815        readWriteReadData(this.channel1, sourceArray, this.channel2,
1816                targetArray, CAPACITY_NORMAL, "testReadWrite_Block_Normal");
1817    }
1818
1819    public void testReadWrite_Block_Empty() throws Exception {
1820        // empty buf
1821        byte[] sourceArray = "".getBytes();
1822        byte[] targetArray = new byte[CAPACITY_NORMAL];
1823
1824        channel1.connect(channel2Address);
1825        channel2.connect(channel1Address);
1826
1827        // write
1828        ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
1829        assertEquals(0, this.channel1.write(sourceBuf));
1830
1831        // read
1832        ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
1833        // empty message let the reader blocked
1834        closeBlockedReaderChannel2(targetBuf);
1835    }
1836
1837    public void testReadWrite_changeBlock_Empty() throws Exception {
1838        // empty buf
1839        byte[] sourceArray = "".getBytes();
1840        byte[] targetArray = new byte[CAPACITY_NORMAL];
1841
1842        channel1.connect(channel2Address);
1843        channel2.connect(channel1Address);
1844
1845        // write
1846        ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
1847        assertEquals(0, this.channel1.write(sourceBuf));
1848
1849        // read
1850        ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
1851        // empty message let the reader blocked
1852        new Thread() {
1853            public void run() {
1854                try {
1855                    Thread.sleep(TIME_UNIT);
1856                    channel2.configureBlocking(false);
1857                    Thread.sleep(TIME_UNIT * 5);
1858                    channel2.close();
1859                } catch (Exception e) {
1860                    // do nothing
1861                }
1862            }
1863        }.start();
1864        try {
1865            assertTrue(this.channel2.isBlocking());
1866            this.channel2.read(targetBuf);
1867            fail("Should throw AsynchronousCloseException");
1868        } catch (AsynchronousCloseException e) {
1869            assertFalse(this.channel2.isBlocking());
1870            // OK.
1871        }
1872    }
1873
1874    public void testReadWrite_Block_8KB() throws Exception {
1875        byte[] sourceArray = new byte[CAPACITY_1KB * 8];
1876        byte[] targetArray = new byte[CAPACITY_1KB * 8];
1877        for (int i = 0; i < sourceArray.length; i++) {
1878            sourceArray[i] = (byte) i;
1879        }
1880
1881        channel1.connect(channel2Address);
1882        channel2.connect(channel1Address);
1883
1884        readWriteReadData(this.channel1, sourceArray, this.channel2,
1885                targetArray, 8 * CAPACITY_1KB, "testReadWrite_Block_8KB");
1886    }
1887
1888    /*
1889     * sender write the sourceArray whose size is dataSize, and receiver read
1890     * the data into targetArray
1891     */
1892    private void readWriteReadData(DatagramChannel sender, byte[] sourceArray,
1893            DatagramChannel receiver, byte[] targetArray, int dataSize,
1894            String methodName) throws IOException {
1895        // write
1896        ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
1897        assertEquals(dataSize, sender.write(sourceBuf));
1898
1899        // read
1900        ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
1901
1902        int count = 0;
1903        int total = 0;
1904        long beginTime = System.currentTimeMillis();
1905        while (total < dataSize && (count = receiver.read(targetBuf)) != -1) {
1906            total = total + count;
1907            // 3s timeout to avoid dead loop
1908            if (System.currentTimeMillis() - beginTime > 3000){
1909                break;
1910            }
1911        }
1912
1913        assertEquals(dataSize, total);
1914        assertEquals(targetBuf.position(), total);
1915        targetBuf.flip();
1916        targetArray = targetBuf.array();
1917        for (int i = 0; i < targetArray.length; i++) {
1918            assertEquals(targetArray[i], (byte) i);
1919        }
1920    }
1921
1922    public void testReadWrite_Block_64K() throws Exception {
1923        byte[] sourceArray = new byte[CAPACITY_64KB];
1924        for (int i = 0; i < sourceArray.length; i++) {
1925            sourceArray[i] = (byte) i;
1926        }
1927
1928        channel1.connect(channel2Address);
1929
1930        // write
1931        ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
1932        try {
1933            channel1.write(sourceBuf);
1934            fail("Should throw IOException");
1935        } catch (IOException expected) {
1936            // too big
1937        }
1938    }
1939
1940    public void testReadWrite_Block_DifferentAddr() throws Exception {
1941        byte[] sourceArray = new byte[CAPACITY_NORMAL];
1942        byte[] targetArray = new byte[CAPACITY_NORMAL];
1943        for (int i = 0; i < sourceArray.length; i++) {
1944            sourceArray[i] = (byte) i;
1945        }
1946
1947        this.channel1.connect(channel1.socket().getLocalSocketAddress());
1948        this.channel2.connect(datagramSocket1Address); // the different addr
1949
1950        // write
1951        ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
1952        assertEquals(CAPACITY_NORMAL, this.channel1.write(sourceBuf));
1953
1954        // read
1955        ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
1956        // the wrong connected addr will make the read blocked.
1957        // we close the blocked channel
1958        closeBlockedReaderChannel2(targetBuf);
1959    }
1960
1961    public void testReadWrite_Block_WriterNotBound() throws Exception {
1962        byte[] sourceArray = new byte[CAPACITY_NORMAL];
1963        byte[] targetArray = new byte[CAPACITY_NORMAL];
1964        for (int i = 0; i < sourceArray.length; i++) {
1965            sourceArray[i] = (byte) i;
1966        }
1967
1968        DatagramChannel dc = DatagramChannel.open();
1969        // The writer isn't bound, but is connected.
1970        dc.connect(channel1Address);
1971
1972        // write
1973        ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
1974        assertEquals(CAPACITY_NORMAL, dc.write(sourceBuf));
1975
1976        // Connect channel2 after data has been written.
1977        channel2.connect(dc.socket().getLocalSocketAddress());
1978
1979        // read
1980        ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
1981        closeBlockedReaderChannel2(targetBuf);
1982
1983        dc.close();
1984    }
1985
1986    // NOTE: The original harmony test tested that things still work
1987    // if there's no socket bound at the the address we're connecting to.
1988    //
1989    // It isn't really feasible to implement that in a non-racy way.
1990    public void testReadWrite_Block_WriterConnectLater() throws Exception {
1991
1992        byte[] targetArray = new byte[CAPACITY_NORMAL];
1993
1994        // The reader is bound & connected to channel1.
1995        channel2.connect(channel1Address);
1996
1997        // read
1998        ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
1999        new Thread() {
2000            public void run() {
2001                try {
2002                    Thread.sleep(TIME_UNIT);
2003                    // bind later
2004                    byte[] sourceArray = new byte[CAPACITY_NORMAL];
2005                    for (int i = 0; i < sourceArray.length; i++) {
2006                        sourceArray[i] = (byte) i;
2007                    }
2008
2009                    channel1.connect(channel2Address);
2010                    // write later
2011                    ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
2012                    assertEquals(CAPACITY_NORMAL, channel1.write(sourceBuf));
2013                } catch (Exception e) {
2014                    // do nothing
2015                }
2016            }
2017        }.start();
2018
2019        int count = 0;
2020        int total = 0;
2021        long beginTime = System.currentTimeMillis();
2022
2023        while (total < CAPACITY_NORMAL && (count = channel2.read(targetBuf)) != -1) {
2024            total = total + count;
2025            // 3s timeout to avoid dead loop
2026            if (System.currentTimeMillis() - beginTime > 3000){
2027                break;
2028            }
2029        }
2030
2031        assertEquals(CAPACITY_NORMAL, total);
2032        assertEquals(targetBuf.position(), total);
2033        targetBuf.flip();
2034        targetArray = targetBuf.array();
2035        for (int i = 0; i < targetArray.length; i++) {
2036            assertEquals(targetArray[i], (byte) i);
2037        }
2038    }
2039
2040    // NOTE: The original harmony test tested that things still work
2041    // if there's no socket bound at the the address we're connecting to.
2042    //
2043    // It isn't really feasible to implement that in a non-racy way.
2044    public void testReadWrite_Block_ReaderNotConnected() throws Exception {
2045        byte[] sourceArray = new byte[CAPACITY_NORMAL];
2046        byte[] targetArray = new byte[CAPACITY_NORMAL];
2047        for (int i = 0; i < sourceArray.length; i++) {
2048            sourceArray[i] = (byte) i;
2049        }
2050
2051        // reader channel2 is not connected.
2052        this.channel1.connect(channel2Address);
2053
2054        // write
2055        ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
2056        assertEquals(CAPACITY_NORMAL, this.channel1.write(sourceBuf));
2057
2058        // read
2059        ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
2060        try {
2061            this.channel2.read(targetBuf);
2062            fail();
2063        } catch (NotYetConnectedException expected) {
2064        }
2065    }
2066
2067    private void closeBlockedReaderChannel2(ByteBuffer targetBuf)
2068            throws IOException {
2069        assertTrue(this.channel2.isBlocking());
2070
2071        new Thread() {
2072            public void run() {
2073                try {
2074                    Thread.sleep(TIME_UNIT);
2075                } catch (InterruptedException ie) {
2076                    fail();
2077                }
2078                IoUtils.closeQuietly(channel2);
2079            }
2080        }.start();
2081
2082        try {
2083            this.channel2.read(targetBuf);
2084            fail("Should throw AsynchronousCloseException");
2085        } catch (AsynchronousCloseException e) {
2086            // OK.
2087        }
2088    }
2089
2090    // -------------------------------------------------------------------
2091    // Test read and write in non-block mode.
2092    // -------------------------------------------------------------------
2093    public void testReadWrite_NonBlock_Normal() throws Exception {
2094        byte[] sourceArray = new byte[CAPACITY_NORMAL];
2095        byte[] targetArray = new byte[CAPACITY_NORMAL];
2096        for (int i = 0; i < sourceArray.length; i++) {
2097            sourceArray[i] = (byte) i;
2098        }
2099
2100        this.channel1.configureBlocking(false);
2101        this.channel2.configureBlocking(false);
2102
2103        channel1.connect(channel2Address);
2104        channel2.connect(channel1Address);
2105
2106        readWriteReadData(this.channel1, sourceArray, this.channel2,
2107                targetArray, CAPACITY_NORMAL, "testReadWrite_NonBlock_Normal");
2108    }
2109
2110    public void testReadWrite_NonBlock_8KB() throws Exception {
2111        byte[] sourceArray = new byte[CAPACITY_1KB * 8];
2112        byte[] targetArray = new byte[CAPACITY_1KB * 8];
2113        for (int i = 0; i < sourceArray.length; i++) {
2114            sourceArray[i] = (byte) i;
2115        }
2116
2117        this.channel1.configureBlocking(false);
2118        this.channel2.configureBlocking(false);
2119
2120        // bind and connect
2121        channel1.connect(channel2Address);
2122        channel2.connect(channel1Address);
2123
2124        readWriteReadData(this.channel1, sourceArray, this.channel2,
2125                targetArray, 8 * CAPACITY_1KB, "testReadWrite_NonBlock_8KB");
2126    }
2127
2128    public void testReadWrite_NonBlock_DifferentAddr() throws Exception {
2129        byte[] sourceArray = new byte[CAPACITY_NORMAL];
2130        byte[] targetArray = new byte[CAPACITY_NORMAL];
2131        for (int i = 0; i < sourceArray.length; i++) {
2132            sourceArray[i] = (byte) i;
2133        }
2134
2135        this.channel1.configureBlocking(false);
2136        this.channel2.configureBlocking(false);
2137
2138        channel1.connect(channel2Address);
2139        channel2.connect(datagramSocket1Address);// the different addr
2140
2141        // write
2142        ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
2143        assertEquals(CAPACITY_NORMAL, this.channel1.write(sourceBuf));
2144
2145        // read
2146        ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
2147        assertEquals(0, this.channel2.read(targetBuf));
2148    }
2149
2150
2151    public void testReadWrite_NonBlock_WriterNotBound() throws Exception {
2152        byte[] sourceArray = new byte[CAPACITY_NORMAL];
2153        byte[] targetArray = new byte[CAPACITY_NORMAL];
2154        for (int i = 0; i < sourceArray.length; i++) {
2155            sourceArray[i] = (byte) i;
2156        }
2157
2158        DatagramChannel dc = DatagramChannel.open();
2159        // The writer isn't bound, but is connected.
2160        dc.connect(channel1Address);
2161        dc.configureBlocking(false);
2162        channel2.configureBlocking(false);
2163
2164        // write
2165        ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
2166        assertEquals(CAPACITY_NORMAL, dc.write(sourceBuf));
2167
2168        // Connect channel2 after data has been written.
2169        channel2.connect(dc.socket().getLocalSocketAddress());
2170
2171        // read
2172        ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
2173        assertEquals(0, this.channel2.read(targetBuf));
2174
2175        dc.close();
2176    }
2177
2178    // NOTE: The original harmony test tested that things still work
2179    // if there's no socket bound at the the address we're connecting to.
2180    //
2181    // It isn't really feasible to implement that in a non-racy way.
2182    public void testReadWrite_NonBlock_ReaderNotConnected() throws Exception {
2183        byte[] sourceArray = new byte[CAPACITY_NORMAL];
2184        byte[] targetArray = new byte[CAPACITY_NORMAL];
2185        for (int i = 0; i < sourceArray.length; i++) {
2186            sourceArray[i] = (byte) i;
2187        }
2188
2189        this.channel1.configureBlocking(false);
2190        this.channel2.configureBlocking(false);
2191
2192        channel1.connect(channel2Address);
2193
2194        // write
2195        ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
2196        assertEquals(CAPACITY_NORMAL, this.channel1.write(sourceBuf));
2197
2198        // read
2199        ByteBuffer targetBuf = ByteBuffer.wrap(targetArray);
2200
2201        try {
2202            assertEquals(0, this.channel2.read(targetBuf));
2203            fail();
2204        } catch (NotYetConnectedException expected) {
2205        }
2206    }
2207
2208    public void test_write_LBuffer_positioned() throws Exception {
2209        // Regression test for Harmony-683
2210        int position = 16;
2211        DatagramChannel dc = DatagramChannel.open();
2212        byte[] sourceArray = new byte[CAPACITY_NORMAL];
2213        dc.connect(datagramSocket1Address);
2214        // write
2215        ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
2216        sourceBuf.position(position);
2217        assertEquals(CAPACITY_NORMAL - position, dc.write(sourceBuf));
2218    }
2219
2220    public void test_send_LBuffer_LSocketAddress_PositionNotZero()
2221            throws Exception {
2222        // regression test for Harmony-701
2223        int CAPACITY_NORMAL = 256;
2224        int position = 16;
2225        DatagramChannel dc = DatagramChannel.open();
2226        byte[] sourceArray = new byte[CAPACITY_NORMAL];
2227        // send ByteBuffer whose position is not zero
2228        ByteBuffer sourceBuf = ByteBuffer.wrap(sourceArray);
2229        sourceBuf.position(position);
2230        int ret = dc.send(sourceBuf, datagramSocket1Address);
2231        // assert send (256 - 16) bytes
2232        assertEquals(CAPACITY_NORMAL - position, ret);
2233        // assert the position of ByteBuffer has been set
2234        assertEquals(CAPACITY_NORMAL, sourceBuf.position());
2235    }
2236
2237    /**
2238     * @tests DatagramChannel#read(ByteBuffer[])
2239     */
2240    public void test_read_$LByteBuffer() throws Exception {
2241        channel1.connect(channel2Address);
2242        channel2.connect(channel1Address);
2243
2244        // regression test for Harmony-754
2245        channel2.write(ByteBuffer.allocate(CAPACITY_NORMAL));
2246
2247        ByteBuffer[] readBuf = new ByteBuffer[2];
2248        readBuf[0] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
2249        readBuf[1] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
2250
2251        channel1.configureBlocking(true);
2252        assertEquals(CAPACITY_NORMAL, channel1.read(readBuf));
2253    }
2254
2255    /**
2256     * @tests DatagramChannel#read(ByteBuffer[],int,int)
2257     */
2258    public void test_read_$LByteBufferII() throws Exception {
2259        channel1.connect(channel2Address);
2260        channel2.connect(channel1Address);
2261
2262        // regression test for Harmony-754
2263        channel2.write(ByteBuffer.allocate(CAPACITY_NORMAL));
2264
2265        ByteBuffer[] readBuf = new ByteBuffer[2];
2266        readBuf[0] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
2267        readBuf[1] = ByteBuffer.allocateDirect(CAPACITY_NORMAL);
2268
2269        channel1.configureBlocking(true);
2270        assertEquals(CAPACITY_NORMAL, channel1.read(readBuf, 0, 2));
2271    }
2272
2273    /**
2274     * @tests DatagramChannel#read(ByteBuffer)
2275     */
2276    public void test_read_LByteBuffer_closed_nullBuf() throws Exception {
2277        // regression test for Harmony-754
2278        ByteBuffer c = null;
2279        DatagramChannel channel = DatagramChannel.open();
2280        channel.close();
2281        try{
2282            channel.read(c);
2283            fail("Should throw NullPointerException");
2284        } catch (NullPointerException e){
2285            // expected
2286        }
2287    }
2288
2289    /**
2290     * @tests DatagramChannel#read(ByteBuffer)
2291     */
2292    public void test_read_LByteBuffer_NotConnected_nullBuf() throws Exception {
2293        // regression test for Harmony-754
2294        ByteBuffer c = null;
2295        DatagramChannel channel = DatagramChannel.open();
2296        try{
2297            channel.read(c);
2298            fail("Should throw NullPointerException");
2299        } catch (NullPointerException e){
2300            // expected
2301        }
2302    }
2303
2304    /**
2305     * @tests DatagramChannel#read(ByteBuffer)
2306     */
2307    public void test_read_LByteBuffer_readOnlyBuf() throws Exception {
2308        // regression test for Harmony-754
2309        ByteBuffer c = ByteBuffer.allocate(1);
2310        DatagramChannel channel = DatagramChannel.open();
2311        try{
2312            channel.read(c.asReadOnlyBuffer());
2313            fail("Should throw NotYetConnectedException");
2314        } catch (NotYetConnectedException e){
2315        } catch (IllegalArgumentException e){
2316            // expected
2317        }
2318        channel.connect(datagramSocket1Address);
2319        try{
2320            channel.read(c.asReadOnlyBuffer());
2321            fail("Should throw IllegalArgumentException");
2322        } catch (IllegalArgumentException e){
2323            // expected
2324        }
2325    }
2326
2327    /**
2328     * @tests DatagramChannel#send(ByteBuffer, SocketAddress)
2329     */
2330    public void test_send_LByteBuffer_LSocketAddress_closed() throws IOException{
2331        // regression test for Harmony-913
2332        channel1.close();
2333        ByteBuffer buf = ByteBuffer.allocate(CAPACITY_NORMAL);
2334        try {
2335            channel1.send(buf, datagramSocket1Address);
2336            fail("Should throw ClosedChannelException");
2337        } catch (ClosedChannelException e) {
2338            //pass
2339        }
2340        try {
2341            channel1.send(null, datagramSocket1Address);
2342            fail("Should throw NullPointerException");
2343        } catch (NullPointerException e) {
2344            //pass
2345        }
2346        try {
2347            channel1.send(buf, null);
2348            fail("Should throw ClosedChannelException");
2349        } catch (ClosedChannelException e) {
2350            //pass
2351        }
2352        try {
2353            channel1.send(null, null);
2354            fail("Should throw NullPointerException");
2355        } catch (NullPointerException e) {
2356            //pass
2357        }
2358    }
2359
2360    /**
2361     * @tests DatagramChannel#socket()
2362     */
2363    public void test_socket_IllegalBlockingModeException() throws Exception {
2364        // regression test for Harmony-1036
2365        DatagramChannel channel = DatagramChannel.open();
2366        channel.configureBlocking(false);
2367        DatagramSocket socket = channel.socket();
2368        try {
2369            socket.send(null);
2370            fail("should throw IllegalBlockingModeException");
2371        } catch (IllegalBlockingModeException e) {
2372            // expected
2373        }
2374        try {
2375            socket.receive(null);
2376            fail("should throw IllegalBlockingModeException");
2377        } catch (IllegalBlockingModeException e) {
2378            // expected
2379        }
2380
2381        channel.close();
2382    }
2383
2384    public void test_bounded_harmony6493() throws IOException {
2385        DatagramChannel server = DatagramChannel.open();
2386        InetSocketAddress addr = new InetSocketAddress("localhost", 0);
2387        server.socket().bind(addr);
2388        SocketAddress boundedAddress = server.socket().getLocalSocketAddress();
2389
2390        DatagramChannel client = DatagramChannel.open();
2391        ByteBuffer sent = ByteBuffer.allocate(1024);
2392        sent.put("test".getBytes());
2393        sent.flip();
2394        client.send(sent, boundedAddress);
2395        assertTrue(client.socket().isBound());
2396
2397        server.close();
2398        client.close();
2399    }
2400
2401    public void test_bind_null() throws Exception {
2402        DatagramChannel dc = DatagramChannel.open();
2403        try {
2404            assertNull(dc.socket().getLocalSocketAddress());
2405
2406            dc.socket().bind(null);
2407
2408            InetSocketAddress localAddress = (InetSocketAddress) dc.socket().getLocalSocketAddress();
2409            assertTrue(localAddress.getAddress().isAnyLocalAddress());
2410            assertTrue(localAddress.getPort() > 0);
2411        } finally {
2412            dc.close();
2413        }
2414    }
2415
2416    public void test_bind_failure() throws Exception {
2417        DatagramChannel dc = DatagramChannel.open();
2418        try {
2419            // Bind to a local address that is in use
2420            dc.socket().bind(channel1Address);
2421            fail();
2422        } catch (IOException expected) {
2423        } finally {
2424            dc.close();
2425        }
2426    }
2427
2428    public void test_bind_closed() throws Exception {
2429        DatagramChannel dc = DatagramChannel.open();
2430        dc.close();
2431
2432        try {
2433            dc.socket().bind(null);
2434            fail();
2435        } catch (IOException expected) {
2436        } finally {
2437            dc.close();
2438        }
2439    }
2440
2441    public void test_bind_explicitPort() throws Exception {
2442        InetSocketAddress address = (InetSocketAddress) channel1.socket().getLocalSocketAddress();
2443        assertTrue(address.getPort() > 0);
2444
2445        DatagramChannel dc = DatagramChannel.open();
2446        // Allow the socket to bind to a port we know is already in use.
2447        dc.socket().setReuseAddress(true);
2448        InetSocketAddress bindAddress = new InetSocketAddress("localhost", address.getPort());
2449        dc.socket().bind(bindAddress);
2450
2451        InetSocketAddress boundAddress = (InetSocketAddress) dc.socket().getLocalSocketAddress();
2452        assertEquals(bindAddress.getHostName(), boundAddress.getHostName());
2453        assertEquals(bindAddress.getPort(), boundAddress.getPort());
2454
2455        dc.close();
2456        channel1.close();
2457    }
2458
2459    /** Checks that the SocketChannel and associated Socket agree on the socket state. */
2460    public void test_bind_socketSync() throws IOException {
2461        DatagramChannel dc = DatagramChannel.open();
2462        assertNull(dc.socket().getLocalSocketAddress());
2463
2464        DatagramSocket socket = dc.socket();
2465        assertNull(socket.getLocalSocketAddress());
2466        assertFalse(socket.isBound());
2467
2468        InetSocketAddress bindAddr = new InetSocketAddress("localhost", 0);
2469        dc.socket().bind(bindAddr);
2470
2471        InetSocketAddress actualAddr = (InetSocketAddress) dc.socket().getLocalSocketAddress();
2472        assertEquals(actualAddr, socket.getLocalSocketAddress());
2473        assertEquals(bindAddr.getHostName(), actualAddr.getHostName());
2474        assertTrue(socket.isBound());
2475        assertFalse(socket.isConnected());
2476        assertFalse(socket.isClosed());
2477
2478        dc.close();
2479
2480        assertFalse(dc.isOpen());
2481        assertTrue(socket.isClosed());
2482    }
2483
2484    /**
2485     * Checks that the SocketChannel and associated Socket agree on the socket state, even if
2486     * the Socket object is requested/created after bind().
2487     */
2488    public void test_bind_socketSyncAfterBind() throws IOException {
2489        DatagramChannel dc = DatagramChannel.open();
2490        assertNull(dc.socket().getLocalSocketAddress());
2491
2492        InetSocketAddress bindAddr = new InetSocketAddress("localhost", 0);
2493        dc.socket().bind(bindAddr);
2494
2495        // Socket creation after bind().
2496        DatagramSocket socket = dc.socket();
2497        InetSocketAddress actualAddr = (InetSocketAddress) dc.socket().getLocalSocketAddress();
2498        assertEquals(actualAddr, socket.getLocalSocketAddress());
2499        assertEquals(bindAddr.getHostName(), actualAddr.getHostName());
2500        assertTrue(socket.isBound());
2501        assertFalse(socket.isConnected());
2502        assertFalse(socket.isClosed());
2503
2504        dc.close();
2505
2506        assertFalse(dc.isOpen());
2507        assertTrue(socket.isClosed());
2508    }
2509
2510    public void test_getLocalSocketAddress_afterClose() throws IOException {
2511        DatagramChannel dc = DatagramChannel.open();
2512        assertNull(dc.socket().getLocalSocketAddress());
2513
2514        InetSocketAddress bindAddr = new InetSocketAddress("localhost", 0);
2515        dc.socket().bind(bindAddr);
2516
2517        assertNotNull(dc.socket().getLocalSocketAddress());
2518
2519        dc.close();
2520
2521        assertFalse(dc.isOpen());
2522
2523        dc.socket().getLocalSocketAddress();
2524    }
2525
2526    // b/27294715
2527    public void test_concurrentShutdown() throws Exception {
2528        DatagramChannel dc = DatagramChannel.open();
2529        dc.configureBlocking(true);
2530        dc.bind(new InetSocketAddress(Inet6Address.LOOPBACK, 0));
2531        // Set 4s timeout
2532        dc.socket().setSoTimeout(4000);
2533
2534        final AtomicReference<Exception> killerThreadException = new AtomicReference<Exception>(null);
2535        final Thread killer = new Thread(new Runnable() {
2536            public void run() {
2537                try {
2538                    Thread.sleep(2000);
2539                    try {
2540                        Libcore.os.shutdown(dc.socket().getFileDescriptor$(), OsConstants.SHUT_RDWR);
2541                    } catch (ErrnoException expected) {
2542                        if (OsConstants.ENOTCONN != expected.errno) {
2543                            killerThreadException.set(expected);
2544                        }
2545                    }
2546                } catch (Exception ex) {
2547                    killerThreadException.set(ex);
2548                }
2549            }
2550        });
2551        killer.start();
2552
2553        ByteBuffer dst = ByteBuffer.allocate(CAPACITY_NORMAL);
2554        assertEquals(null, dc.receive(dst));
2555        assertEquals(0, dst.position());
2556        dc.close();
2557
2558        killer.join();
2559        assertNull(killerThreadException.get());
2560    }
2561}
2562