View Javadoc

    1   /*
    2    *  Licensed to the Apache Software Foundation (ASF) under one
    3    *  or more contributor license agreements.  See the NOTICE file
    4    *  distributed with this work for additional information
    5    *  regarding copyright ownership.  The ASF licenses this file
    6    *  to you under the Apache License, Version 2.0 (the
    7    *  "License"); you may not use this file except in compliance
    8    *  with the License.  You may obtain a copy of the License at
    9    *
    10   *    http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   *  Unless required by applicable law or agreed to in writing,
    13   *  software distributed under the License is distributed on an
    14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    15   *  KIND, either express or implied.  See the License for the
    16   *  specific language governing permissions and limitations
    17   *  under the License.
    18   *
    19   */
    20  package org.apache.mina.transport;
    21
    22  import static org.junit.Assert.assertEquals;
    23  import static org.junit.Assert.assertFalse;
    24  import static org.junit.Assert.assertSame;
    25  import static org.junit.Assert.assertTrue;
    26  import static org.junit.Assert.fail;
    27
    28  import java.net.InetSocketAddress;
    29  import java.util.concurrent.CountDownLatch;
    30  import java.util.concurrent.TimeUnit;
    31  import java.util.regex.Pattern;
    32
    33  import org.apache.mina.core.RuntimeIoException;
    34  import org.apache.mina.core.future.ConnectFuture;
    35  import org.apache.mina.core.service.IoAcceptor;
    36  import org.apache.mina.core.service.IoConnector;
    37  import org.apache.mina.core.service.IoHandlerAdapter;
    38  import org.apache.mina.core.session.IoSession;
    39  import org.apache.mina.core.session.IoSessionInitializer;
    40  import org.apache.mina.util.AvailablePortFinder;
    41  import org.junit.Test;
    42
    43  /**
    44   * Tests a generic {@link IoConnector}.
    45   *
    46   * @author <a href="http://mina.apache.org">Apache MINA Project</a>
    47   */
    48  public abstract class AbstractConnectorTest {
    49
    50      protected abstract IoAcceptor createAcceptor();
    51
    52      protected abstract IoConnector createConnector();
    53
    54      @Test
    55      public void testConnectFutureSuccessTiming() throws Exception {
    56          int port = AvailablePortFinder.getNextAvailable(1025);
    57          IoAcceptor acceptor = createAcceptor();
    58          acceptor.setHandler(new IoHandlerAdapter());
    59          acceptor.bind(new InetSocketAddress(port));
    60
    61          try {
    62              final StringBuffer buf = new StringBuffer();
    63              IoConnector connector = createConnector();
    64              connector.setHandler(new IoHandlerAdapter() {
    65                  @Override
    66                  public void sessionCreated(IoSession session) {
    67                      buf.append("1");
    68                  }
    69
    70                  @Override
    71                  public void sessionOpened(IoSession session) {
    72                      buf.append("2");
    73                  }
    74
    75                  @Override
    76                  public void exceptionCaught(IoSession session, Throwable cause) {
    77                      buf.append("X");
    78                  }
    79              });
    80              ConnectFuture future = connector.connect(new InetSocketAddress("localhost", port));
    81              future.awaitUninterruptibly();
    82              buf.append("3");
    83              future.getSession().close(true);
    84              // sessionCreated() will fire before the connect future completes
    85              // but sessionOpened() may not
    86              assertTrue(Pattern.matches("12?32?", buf.toString()));
    87          } finally {
    88              acceptor.dispose();
    89          }
    90      }
    91
    92      @Test
    93      public void testConnectFutureFailureTiming() throws Exception {
    94          int port = AvailablePortFinder.getNextAvailable(1025);
    95          final StringBuffer buf = new StringBuffer();
    96
    97          IoConnector connector = createConnector();
    98          connector.setHandler(new IoHandlerAdapter() {
    99              @Override
    100             public void sessionCreated(IoSession session) {
    101                 buf.append("X");
    102             }
    103
    104             @Override
    105             public void sessionOpened(IoSession session) {
    106                 buf.append("Y");
    107             }
    108
    109             @Override
    110             public void exceptionCaught(IoSession session, Throwable cause) {
    111                 buf.append("Z");
    112             }
    113         });
    114
    115         try {
    116             ConnectFuture future = connector.connect(new InetSocketAddress("localhost", port));
    117             future.awaitUninterruptibly();
    118             buf.append("1");
    119             try {
    120                 future.getSession().close(true);
    121                 fail();
    122             } catch (RuntimeIoException e) {
    123                 // Signifies a successful test execution
    124                 assertTrue(true);
    125             }
    126             assertEquals("1", buf.toString());
    127         } finally {
    128             connector.dispose();
    129         }
    130     }
    131
    132     /**
    133      * Test to make sure the SessionCallback gets invoked before IoHandler.sessionCreated.
    134      */
    135     @Test
    136     public void testSessionCallbackInvocation() throws Exception {
    137         final int callbackInvoked = 0;
    138         final int sessionCreatedInvoked = 1;
    139         final int sessionCreatedInvokedBeforeCallback = 2;
    140         final boolean[] assertions = { false, false, false };
    141         final CountDownLatch latch = new CountDownLatch(2);
    142         final ConnectFuture[] callbackFuture = new ConnectFuture[1];
    143
    144         int port = AvailablePortFinder.getNextAvailable(1025);
    145
    146         IoAcceptor acceptor = createAcceptor();
    147         IoConnector connector = createConnector();
    148
    149         try {
    150             acceptor.setHandler(new IoHandlerAdapter());
    151             InetSocketAddress address = new InetSocketAddress(port);
    152             acceptor.bind(address);
    153
    154             connector.setHandler(new IoHandlerAdapter() {
    155                 @Override
    156                 public void sessionCreated(IoSession session) throws Exception {
    157                     assertions[sessionCreatedInvoked] = true;
    158                     assertions[sessionCreatedInvokedBeforeCallback] = !assertions[callbackInvoked];
    159                     latch.countDown();
    160                 }
    161             });
    162
    163             ConnectFuture future = connector.connect(new InetSocketAddress("127.0.0.1", port),
    164                     new IoSessionInitializer<ConnectFuture>() {
    165                         public void initializeSession(IoSession session, ConnectFuture future) {
    166                             assertions[callbackInvoked] = true;
    167                             callbackFuture[0] = future;
    168                             latch.countDown();
    169                         }
    170                     });
    171
    172             assertTrue("Timed out waiting for callback and IoHandler.sessionCreated to be invoked",
    173                     latch.await(5, TimeUnit.SECONDS));
    174             assertTrue("Callback was not invoked", assertions[callbackInvoked]);
    175             assertTrue("IoHandler.sessionCreated was not invoked", assertions[sessionCreatedInvoked]);
    176             assertFalse("IoHandler.sessionCreated was invoked before session callback",
    177                     assertions[sessionCreatedInvokedBeforeCallback]);
    178             assertSame("Callback future should have been same future as returned by connect", future, callbackFuture[0]);
    179         } finally {
    180             try {
    181                 connector.dispose();
    182             } finally {
    183                 acceptor.dispose();
    184             }
    185         }
    186     }
    187 }