1   /*
2    *   @(#) $Id: ConnectorTest.java 210062 2005-07-11 03:52:38Z trustin $
3    *
4    *   Copyright 2004 The Apache Software Foundation
5    *
6    *   Licensed under the Apache License, Version 2.0 (the "License");
7    *   you may not use this file except in compliance with the License.
8    *   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, software
13   *   distributed under the License is distributed on an "AS IS" BASIS,
14   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   *   See the License for the specific language governing permissions and
16   *   limitations under the License.
17   *
18   */
19  package org.apache.mina.examples.echoserver;
20  
21  import java.net.InetAddress;
22  import java.net.InetSocketAddress;
23  import java.net.SocketAddress;
24  
25  import junit.framework.Assert;
26  
27  import org.apache.mina.common.ByteBuffer;
28  import org.apache.mina.common.TransportType;
29  import org.apache.mina.examples.echoserver.ssl.BogusSSLContextFactory;
30  import org.apache.mina.io.IoAcceptor;
31  import org.apache.mina.io.IoConnector;
32  import org.apache.mina.io.IoHandlerAdapter;
33  import org.apache.mina.io.IoSession;
34  import org.apache.mina.io.datagram.DatagramConnector;
35  import org.apache.mina.io.filter.SSLFilter;
36  import org.apache.mina.io.socket.SocketConnector;
37  import org.apache.mina.util.AvailablePortFinder;
38  
39  /***
40   * Tests echo server example.
41   * 
42   * @author Trustin Lee (trustin@apache.org)
43   * @version $Rev: 210062 $, $Date: 2005-07-11 12:52:38 +0900 $
44   */
45  public class ConnectorTest extends AbstractTest
46  {
47      private int clientPort;
48      
49      public ConnectorTest()
50      {
51      }
52  
53      public void setUp() throws Exception
54      {
55          super.setUp();
56          clientPort = port;
57          clientPort = AvailablePortFinder.getNextAvailable( clientPort + 1 );
58          System.out.println( "Using port " + clientPort + " as local address" );
59      }
60      
61      public void testTCP() throws Exception
62      {
63          IoConnector connector = new SocketConnector();
64          testConnector( connector );
65      }
66      
67      /***
68       * Client-side SSL doesn't work for now.
69       */
70      public void testTCPWithSSL() throws Exception
71      {
72          // Add an SSL filter to acceptor
73          SSLFilter acceptorSSLFilter =
74              new SSLFilter( BogusSSLContextFactory.getInstance( true ) );
75          IoAcceptor acceptor = registry.getIoAcceptor( TransportType.SOCKET );
76          acceptor.getFilterChain().addLast( "SSL", acceptorSSLFilter );
77  
78          // Create a connector
79          IoConnector connector = new SocketConnector();
80          
81          // Add an SSL filter to connector
82          SSLFilter connectorSSLFilter =
83              new SSLFilter( BogusSSLContextFactory.getInstance( false ) );
84          connectorSSLFilter.setUseClientMode( true ); // set client mode
85          connector.getFilterChain().addLast( "SSL", connectorSSLFilter );
86  
87          testConnector( connector );
88      }
89      
90      public void testUDP() throws Exception
91      {
92          IoConnector connector = new DatagramConnector();
93          testConnector( connector );
94      }
95      
96      private void testConnector( IoConnector connector ) throws Exception
97      {
98          InetSocketAddress localAddress = new InetSocketAddress( clientPort );
99  
100         System.out.println("* Without localAddress and initializer");
101         testConnector( connector, null );
102         
103         System.out.println("* Without localAddress and with initializer");
104         testConnector( connector, null );
105 
106         // Tests below fail in Windows platform.
107         if( System.getProperty("os.name").toLowerCase().indexOf( "windows" ) >= 0 )
108         {
109             // skip further tests
110             System.out.println( "** Skipping some tests that fails in Windows platform." );
111             return;
112         }
113         
114         System.out.println("* With localAddress and without initializer");
115         testConnector( connector, localAddress );
116         
117         // It takes some time for local address to be cleared by OS,
118         // so let's just get a new one rather than waiting for it.
119         clientPort = AvailablePortFinder.getNextAvailable( clientPort + 1 );
120         localAddress = new InetSocketAddress( clientPort );
121 
122         System.out.println("* With localAddress and initializer");
123         testConnector( connector, localAddress );
124     }
125     
126     private void testConnector( IoConnector connector, SocketAddress localAddress ) throws Exception
127     {
128         EchoConnectorHandler handler = new EchoConnectorHandler();
129         ByteBuffer readBuf = handler.readBuf;
130         IoSession session = connector.connect(
131                 new InetSocketAddress( InetAddress.getLocalHost(), port ),
132                 localAddress,
133                 handler );
134         
135         for( int i = 0; i < 10; i ++ )
136         {
137             ByteBuffer buf = ByteBuffer.allocate( 16 );
138             buf.limit( 16 );
139             fillWriteBuffer( buf, i );
140             buf.flip();
141 
142             Object marker;
143             if( ( i & 1 ) == 0 )
144             {
145                 marker = new Integer( i );
146             }
147             else
148             {
149                 marker = null;
150             }
151 
152             session.write( buf, marker );
153 
154             // This will align message arrival order in UDP
155             for( int j = 0; j < 30; j ++ )
156             {
157                 if( readBuf.position() == ( i + 1 ) * 16 )
158                 {
159                     break;
160                 }
161                 Thread.sleep( 10 );
162             }
163         }
164         
165         for( int i = 0; i < 30; i++ ) {
166             if( readBuf.position() == 160 )
167             {
168                 break;
169             }
170             else
171             {
172                 Thread.sleep( 100 );
173             }
174         }
175 
176         session.close( true );
177         
178         Assert.assertEquals( 160, readBuf.position() );
179         readBuf.flip();
180         
181         ByteBuffer expectedBuf = ByteBuffer.allocate( 160 );
182         for( int i = 0; i < 10; i ++ ) {
183             expectedBuf.limit( ( i + 1 ) * 16 );
184             fillWriteBuffer( expectedBuf, i );
185         }
186         expectedBuf.position( 0 );
187         assertEquals(expectedBuf, readBuf);
188     }
189 
190     private void fillWriteBuffer( ByteBuffer writeBuf, int i )
191     {
192         while( writeBuf.remaining() > 0 )
193         {
194             writeBuf.put( ( byte ) ( i ++ ) );
195         }
196     }
197 
198     public static void main( String[] args )
199     {
200         junit.textui.TestRunner.run( ConnectorTest.class );
201     }
202     
203     private static class EchoConnectorHandler extends IoHandlerAdapter
204     {
205         private ByteBuffer readBuf = ByteBuffer.allocate( 1024 );
206         private int counter = 0;
207 
208         public void dataRead( IoSession session, ByteBuffer buf )
209         {
210             readBuf.put( buf );
211         }
212         
213         public void dataWritten( IoSession session, Object marker )
214         {
215             if( ( counter & 1 ) == 0 )
216             {
217                 Assert.assertEquals( new Integer( counter ), marker );
218             }
219             else
220             {
221                 Assert.assertNull( marker );
222             }
223             
224             counter ++;
225         }
226 
227         public void exceptionCaught( IoSession session, Throwable cause )
228         {
229             cause.printStackTrace();
230         }
231     }
232 }