jdk/test/java/nio/channels/AsynchronousDatagramChannel/Basic.java
changeset 7382 e1ed8c9e12e5
parent 7381 5d924959cd81
parent 7140 4951967a61b4
child 7383 cbd66f8db06b
equal deleted inserted replaced
7381:5d924959cd81 7382:e1ed8c9e12e5
     1 /*
       
     2  * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  */
       
    23 
       
    24 /* @test
       
    25  * @bug 4527345 6842687
       
    26  * @summary Unit test for AsynchronousDatagramChannel
       
    27  */
       
    28 
       
    29 import java.nio.ByteBuffer;
       
    30 import java.nio.channels.*;
       
    31 import java.net.*;
       
    32 import java.util.concurrent.*;
       
    33 import java.util.concurrent.atomic.*;
       
    34 
       
    35 public class Basic {
       
    36 
       
    37     public static void main(String[] args) throws Exception {
       
    38         doReceiveTests();
       
    39         doReadTests();
       
    40         doSendTests();
       
    41         doWriteTests();
       
    42         doCancelTests();
       
    43         doMulticastTests();
       
    44     }
       
    45 
       
    46     // basic receive tests
       
    47     static void doReceiveTests() throws Exception {
       
    48         final byte[] msg = "hello".getBytes();
       
    49 
       
    50         AsynchronousDatagramChannel ch = AsynchronousDatagramChannel.open()
       
    51             .bind(new InetSocketAddress(0));
       
    52         int port = ((InetSocketAddress)(ch.getLocalAddress())).getPort();
       
    53         InetAddress rh = InetAddress.getLocalHost();
       
    54         final SocketAddress sa = new InetSocketAddress(rh, port);
       
    55 
       
    56         DatagramChannel sender = DatagramChannel.open();
       
    57         ByteBuffer dst = ByteBuffer.allocateDirect(100);
       
    58 
       
    59         // Test: datagram packet received immediately
       
    60         sender.send(ByteBuffer.wrap(msg), sa);
       
    61         dst.clear();
       
    62         ch.receive(dst).get(1, TimeUnit.SECONDS);
       
    63         if (dst.flip().remaining() != msg.length)
       
    64             throw new RuntimeException("Unexpected number of bytes read");
       
    65 
       
    66         // Test: datagram packet not received immediately
       
    67         dst.clear();
       
    68         final CountDownLatch latch = new CountDownLatch(1);
       
    69         ch.receive(dst, (Void)null, new CompletionHandler<SocketAddress,Void>() {
       
    70             public void completed(SocketAddress source, Void att) {
       
    71                 latch.countDown();
       
    72             }
       
    73             public void failed (Throwable exc, Void att) {
       
    74             }
       
    75         });
       
    76         Thread.sleep(2000);
       
    77         sender.send(ByteBuffer.wrap(msg), sa);
       
    78         latch.await(2, TimeUnit.SECONDS);  // wait for completion handler
       
    79 
       
    80         // Test: timeout
       
    81         dst.clear();
       
    82         final AtomicReference<Throwable> exception = new AtomicReference<Throwable>();
       
    83         ch.receive(dst, 2, TimeUnit.SECONDS, (Void)null, new CompletionHandler<SocketAddress,Void>() {
       
    84             public void completed(SocketAddress source, Void att) {
       
    85             }
       
    86             public void failed (Throwable exc, Void att) {
       
    87                 exception.set(exc);
       
    88             }
       
    89         });
       
    90         Throwable result;
       
    91         while ((result = exception.get()) == null) {
       
    92             Thread.sleep(100);
       
    93         }
       
    94         if (!(result instanceof InterruptedByTimeoutException))
       
    95             throw new RuntimeException("InterruptedByTimeoutException expected");
       
    96 
       
    97         // AsynchronousCloseException
       
    98         dst = ByteBuffer.allocateDirect(100);
       
    99         exception.set(null);
       
   100         ch.receive(dst, (Void)null, new CompletionHandler<SocketAddress,Void>() {
       
   101             public void completed(SocketAddress source, Void att) {
       
   102             }
       
   103             public void failed (Throwable exc, Void att) {
       
   104                 exception.set(exc);
       
   105             }
       
   106         });
       
   107         ch.close();
       
   108         while ((result = exception.get()) == null) {
       
   109             Thread.sleep(100);
       
   110         }
       
   111         if (!(result instanceof AsynchronousCloseException))
       
   112             throw new RuntimeException("AsynchronousCloseException expected");
       
   113 
       
   114         // done
       
   115         sender.close();
       
   116     }
       
   117 
       
   118     // basic read tests
       
   119     static void doReadTests() throws Exception {
       
   120         final byte[] msg = "hello".getBytes();
       
   121 
       
   122         AsynchronousDatagramChannel ch = AsynchronousDatagramChannel.open()
       
   123             .bind(new InetSocketAddress(0));
       
   124         int port = ((InetSocketAddress)(ch.getLocalAddress())).getPort();
       
   125         InetAddress lh = InetAddress.getLocalHost();
       
   126         final SocketAddress sa = new InetSocketAddress(lh, port);
       
   127 
       
   128         DatagramChannel sender = DatagramChannel.open();
       
   129         ByteBuffer dst = ByteBuffer.allocateDirect(100);
       
   130 
       
   131         // Test: not connected
       
   132         try {
       
   133             ch.read(dst);
       
   134             throw new RuntimeException("NotYetConnectedException expected");
       
   135         } catch (NotYetConnectedException e) {
       
   136         }
       
   137 
       
   138         // connect the channel
       
   139         sender.bind(new InetSocketAddress(0));
       
   140         ch.connect(new InetSocketAddress(lh,
       
   141                 ((InetSocketAddress)(sender.getLocalAddress())).getPort()));
       
   142 
       
   143         // Test: datagram packet received immediately
       
   144         sender.send(ByteBuffer.wrap(msg), sa);
       
   145         dst.clear();
       
   146         ch.read(dst).get(1, TimeUnit.SECONDS);
       
   147         if (dst.flip().remaining() != msg.length)
       
   148             throw new RuntimeException("Unexpected number of bytes read");
       
   149 
       
   150         // Test: datagram packet not received immediately
       
   151         dst.clear();
       
   152         final CountDownLatch l1 = new CountDownLatch(1);
       
   153         ch.read(dst, (Void)null, new CompletionHandler<Integer,Void>() {
       
   154             public void completed(Integer bytesRead, Void att) {
       
   155                 l1.countDown();
       
   156             }
       
   157             public void failed (Throwable exc, Void att) {
       
   158             }
       
   159         });
       
   160         Thread.sleep(2000);
       
   161         sender.send(ByteBuffer.wrap(msg), sa);
       
   162         l1.await(2, TimeUnit.SECONDS);
       
   163 
       
   164         // Test: timeout
       
   165         dst.clear();
       
   166         final AtomicReference<Throwable> exception = new AtomicReference<Throwable>();
       
   167         ch.read(dst, 2, TimeUnit.SECONDS, (Void)null, new CompletionHandler<Integer,Void>() {
       
   168             public void completed(Integer bytesRead, Void att) {
       
   169             }
       
   170             public void failed (Throwable exc, Void att) {
       
   171                 exception.set(exc);
       
   172             }
       
   173         });
       
   174         Throwable result;
       
   175         while ((result = exception.get()) == null) {
       
   176             Thread.sleep(100);
       
   177         }
       
   178         if (!(result instanceof InterruptedByTimeoutException))
       
   179             throw new RuntimeException("InterruptedByTimeoutException expected");
       
   180 
       
   181         // AsynchronousCloseException
       
   182         dst.clear();
       
   183         exception.set(null);
       
   184         ch.read(dst, (Void)null, new CompletionHandler<Integer,Void>() {
       
   185             public void completed(Integer bytesRead, Void att) {
       
   186             }
       
   187             public void failed (Throwable exc, Void att) {
       
   188                 exception.set(exc);
       
   189             }
       
   190         });
       
   191         ch.close();
       
   192         while ((result = exception.get()) == null) {
       
   193             Thread.sleep(100);
       
   194         }
       
   195         if (!(result instanceof AsynchronousCloseException))
       
   196             throw new RuntimeException("AsynchronousCloseException expected");
       
   197 
       
   198         // done
       
   199         sender.close();
       
   200     }
       
   201 
       
   202     // basic send tests
       
   203     static void doSendTests() throws Exception {
       
   204         final byte[] msg = "hello".getBytes();
       
   205 
       
   206         DatagramChannel reader = DatagramChannel.open()
       
   207             .bind(new InetSocketAddress(0));
       
   208         int port = ((InetSocketAddress)(reader.getLocalAddress())).getPort();
       
   209         InetAddress rh = InetAddress.getLocalHost();
       
   210         SocketAddress sa = new InetSocketAddress(rh, port);
       
   211 
       
   212         AsynchronousDatagramChannel ch = AsynchronousDatagramChannel.open();
       
   213 
       
   214         // Test: send datagram packet to reader
       
   215         int bytesSent = ch.send(ByteBuffer.wrap(msg), sa).get();
       
   216         if (bytesSent != msg.length)
       
   217             throw new RuntimeException("Unexpected number of bytes sent");
       
   218 
       
   219         // check received
       
   220         ByteBuffer dst = ByteBuffer.allocateDirect(100);
       
   221         reader.receive(dst);
       
   222         dst.flip();
       
   223         if (dst.remaining() != msg.length)
       
   224             throw new RuntimeException("Unexpected number of bytes received");
       
   225 
       
   226         // Test: send datagram packet to reader and check completion handler
       
   227         // is invoked
       
   228         final CountDownLatch l2 = new CountDownLatch(1);
       
   229         ch.send(ByteBuffer.wrap(msg), sa, (Void)null, new CompletionHandler<Integer,Void>() {
       
   230             public void completed(Integer bytesSent, Void att) {
       
   231                 if (bytesSent != msg.length)
       
   232                     throw new RuntimeException("Unexpected number of bytes received");
       
   233                 l2.countDown();
       
   234             }
       
   235             public void failed (Throwable exc, Void att) {
       
   236             }
       
   237         });
       
   238         l2.await(5, TimeUnit.SECONDS);
       
   239 
       
   240         // check received
       
   241         dst.clear();
       
   242         reader.receive(dst);
       
   243         dst.flip();
       
   244         if (dst.remaining() != msg.length)
       
   245             throw new RuntimeException("Unexpected number of bytes received");
       
   246 
       
   247         // Test: check that failed method is invoked
       
   248         ch.close();
       
   249         final CountDownLatch l3 = new CountDownLatch(1);
       
   250         ch.send(ByteBuffer.wrap(msg), sa, (Void)null, new CompletionHandler<Integer,Void>() {
       
   251             public void completed(Integer bytesSent, Void att) {
       
   252                 throw new RuntimeException("completed method invoked");
       
   253             }
       
   254             public void failed (Throwable exc, Void att) {
       
   255                 if (exc instanceof ClosedChannelException) {
       
   256                     l3.countDown();
       
   257                 } else {
       
   258                     throw new RuntimeException(exc);
       
   259                 }
       
   260             }
       
   261         });
       
   262         l3.await(5, TimeUnit.SECONDS);
       
   263 
       
   264         // done
       
   265         reader.close();
       
   266     }
       
   267 
       
   268     // basic write tests
       
   269     static void doWriteTests() throws Exception {
       
   270         final byte[] msg = "hello".getBytes();
       
   271 
       
   272         DatagramChannel reader = DatagramChannel.open()
       
   273             .bind(new InetSocketAddress(0));
       
   274         int port = ((InetSocketAddress)(reader.getLocalAddress())).getPort();
       
   275         InetAddress rh = InetAddress.getLocalHost();
       
   276         SocketAddress sa = new InetSocketAddress(rh, port);
       
   277 
       
   278         AsynchronousDatagramChannel ch = AsynchronousDatagramChannel.open();
       
   279 
       
   280         // Test: unconnected
       
   281         try {
       
   282             ch.write(ByteBuffer.wrap(msg)).get();
       
   283             throw new RuntimeException("NotYetConnectedException expected");
       
   284         } catch (NotYetConnectedException e) {
       
   285         }
       
   286 
       
   287         // Test: connect, and write datagram
       
   288         ch.connect(sa);
       
   289         int bytesSent = ch.write(ByteBuffer.wrap(msg)).get();
       
   290         if (bytesSent != msg.length)
       
   291             throw new RuntimeException("Unexpected number of bytes sent");
       
   292 
       
   293         // check received
       
   294         ByteBuffer dst = ByteBuffer.allocateDirect(100);
       
   295         reader.receive(dst);
       
   296         dst.flip();
       
   297         if (dst.remaining() != msg.length)
       
   298             throw new RuntimeException("Unexpected number of bytes received");
       
   299 
       
   300         // Test: write datagram and check completion handler is invoked
       
   301         final CountDownLatch l2 = new CountDownLatch(1);
       
   302         ch.write(ByteBuffer.wrap(msg), (Void)null, new CompletionHandler<Integer,Void>() {
       
   303             public void completed(Integer bytesSent, Void att) {
       
   304                 if (bytesSent != msg.length)
       
   305                     throw new RuntimeException("Unexpected number of bytes received");
       
   306                 l2.countDown();
       
   307             }
       
   308             public void failed (Throwable exc, Void att) {
       
   309             }
       
   310         });
       
   311         l2.await(5, TimeUnit.SECONDS);
       
   312 
       
   313         // check received
       
   314         dst.clear();
       
   315         reader.receive(dst);
       
   316         dst.flip();
       
   317         if (dst.remaining() != msg.length)
       
   318             throw new RuntimeException("Unexpected number of bytes received");
       
   319 
       
   320         // done
       
   321         ch.close();
       
   322         reader.close();
       
   323     }
       
   324 
       
   325     static void cancelAndCheck(Future<?> result)
       
   326         throws InterruptedException
       
   327     {
       
   328         boolean cancelled = result.cancel(false);
       
   329         if (!cancelled)
       
   330             throw new RuntimeException("Not cancelled");
       
   331         if (!result.isDone())
       
   332             throw new RuntimeException("Should be done");
       
   333         try {
       
   334             result.get();
       
   335             throw new RuntimeException("Result not expected");
       
   336         } catch (CancellationException e) {
       
   337             // expected
       
   338         } catch (ExecutionException e) {
       
   339             throw new RuntimeException("Should not fail");
       
   340         }
       
   341     }
       
   342 
       
   343     // basic cancel tests
       
   344     static void doCancelTests() throws Exception {
       
   345         InetAddress lh = InetAddress.getLocalHost();
       
   346 
       
   347         // receive
       
   348         for (int i=0; i<2; i++) {
       
   349             AsynchronousDatagramChannel ch =
       
   350                 AsynchronousDatagramChannel.open().bind(new InetSocketAddress(0));
       
   351             Future<SocketAddress> remote = ch.receive(ByteBuffer.allocate(100));
       
   352             cancelAndCheck(remote);
       
   353             ch.close();
       
   354         }
       
   355 
       
   356         // read
       
   357         for (int i=0; i<2; i++) {
       
   358             AsynchronousDatagramChannel ch =
       
   359                 AsynchronousDatagramChannel.open().bind(new InetSocketAddress(0));
       
   360              ch.connect(new InetSocketAddress(lh,
       
   361                 ((InetSocketAddress)(ch.getLocalAddress())).getPort()));
       
   362             final CountDownLatch latch = new CountDownLatch(1);
       
   363             long timeout = (i == 0) ? 0L : 60L;
       
   364             Future<Integer> result = ch.read(ByteBuffer.allocate(100));
       
   365             cancelAndCheck(result);
       
   366             ch.close();
       
   367         }
       
   368     }
       
   369 
       
   370     // basic multicast test
       
   371     static void doMulticastTests() throws Exception {
       
   372         final byte[] msg = "hello".getBytes();
       
   373 
       
   374         InetAddress lh = InetAddress.getLocalHost();
       
   375         NetworkInterface interf = NetworkInterface.getByInetAddress(lh);
       
   376         if (interf.isLoopback() || !interf.supportsMulticast()) {
       
   377             System.out.println("Multicasting not tested");
       
   378             return;
       
   379         }
       
   380 
       
   381         AsynchronousDatagramChannel ch = AsynchronousDatagramChannel
       
   382             .open(StandardProtocolFamily.INET, null)
       
   383             .setOption(StandardSocketOption.SO_REUSEADDR, true)
       
   384             .bind(new InetSocketAddress(0));
       
   385 
       
   386         int port = ((InetSocketAddress)(ch.getLocalAddress())).getPort();
       
   387 
       
   388         // join group
       
   389         InetAddress group = InetAddress.getByName("225.4.5.6");
       
   390         MembershipKey key = ch.join(group, interf);
       
   391 
       
   392         // check key
       
   393         if (key.channel() != ch)
       
   394             throw new RuntimeException("Not the expected channel");
       
   395 
       
   396         // send message to group
       
   397         DatagramChannel sender = DatagramChannel.open();
       
   398         sender.send(ByteBuffer.wrap(msg), new InetSocketAddress(group, port));
       
   399         sender.close();
       
   400 
       
   401         // check message received
       
   402         ByteBuffer dst = ByteBuffer.allocate(200);
       
   403         SocketAddress source = ch.receive(dst).get(2, TimeUnit.SECONDS);
       
   404         if (!((InetSocketAddress)source).getAddress().equals(lh))
       
   405             throw new RuntimeException("Unexpected source");
       
   406 
       
   407         // done
       
   408         ch.close();
       
   409     }
       
   410 }