Repository: mina
Updated Branches:
  refs/heads/2.0 eee4c5a5a -> 478d25139


Added tests for issues DIRMINA-1076 and DIRMINA-1077.


Project: http://git-wip-us.apache.org/repos/asf/mina/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina/commit/4f9b2c60
Tree: http://git-wip-us.apache.org/repos/asf/mina/tree/4f9b2c60
Diff: http://git-wip-us.apache.org/repos/asf/mina/diff/4f9b2c60

Branch: refs/heads/2.0
Commit: 4f9b2c609aff491702619258babd9ce51dbc1b11
Parents: 3433440
Author: chrjohn <christoph.j...@macd.com>
Authored: Sat Mar 3 22:58:53 2018 +0100
Committer: chrjohn <christoph.j...@macd.com>
Committed: Sat Mar 3 22:58:53 2018 +0100

----------------------------------------------------------------------
 .../AbstractIoServiceDIRMINA1076Test.java       | 172 +++++++++++++++++
 ...slTestHandshakeExceptionDIRMINA1077Test.java | 186 +++++++++++++++++++
 .../mina/filter/ssl/emptykeystore.sslTest       | Bin 0 -> 32 bytes
 3 files changed, 358 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina/blob/4f9b2c60/mina-core/src/test/java/org/apache/mina/core/service/AbstractIoServiceDIRMINA1076Test.java
----------------------------------------------------------------------
diff --git 
a/mina-core/src/test/java/org/apache/mina/core/service/AbstractIoServiceDIRMINA1076Test.java
 
b/mina-core/src/test/java/org/apache/mina/core/service/AbstractIoServiceDIRMINA1076Test.java
new file mode 100644
index 0000000..9c1d69f
--- /dev/null
+++ 
b/mina-core/src/test/java/org/apache/mina/core/service/AbstractIoServiceDIRMINA1076Test.java
@@ -0,0 +1,172 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+
+package org.apache.mina.core.service;
+
+import static org.junit.Assert.fail;
+
+import org.apache.mina.core.future.CloseFuture;
+import org.apache.mina.core.future.ConnectFuture;
+import org.apache.mina.core.session.IdleStatus;
+import org.apache.mina.core.session.IoSession;
+import org.apache.mina.filter.codec.ProtocolCodecFilter;
+import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
+import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
+import org.apache.mina.transport.socket.nio.NioSocketConnector;
+import org.apache.mina.util.AvailablePortFinder;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.nio.charset.Charset;
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * Test disposal of AbstractIoService. This test should not hang or timeout 
when DIRMINA-1076 is fixed.
+ * 
+ * @author chrjohn
+ */
+public class AbstractIoServiceDIRMINA1076Test {
+
+    @Test( timeout = 15000 )
+    public void testDispose()
+        throws Exception {
+
+        long startTime = System.currentTimeMillis();
+        // without DIRMINA-1076 fixed, the test will hang after short time
+        while ( System.currentTimeMillis() < startTime + 10000 ) {
+            Thread thread = new Thread() {
+
+                public void run() {
+
+                    final IoAcceptor acceptor = new NioSocketAcceptor();
+                    acceptor.getFilterChain()
+                            .addLast( "codec",
+                                      new ProtocolCodecFilter( new 
TextLineCodecFactory( Charset.forName( "UTF-8" ) ) ) );
+
+                    acceptor.setHandler( new ServerHandler() );
+
+                    acceptor.getSessionConfig().setReadBufferSize( 2048 );
+                    acceptor.getSessionConfig().setIdleTime( 
IdleStatus.BOTH_IDLE, 10 );
+                    int nextAvailable = AvailablePortFinder.getNextAvailable();
+                    try {
+                        acceptor.bind( new InetSocketAddress( nextAvailable ) 
);
+                    } catch ( IOException e1 ) {
+                        // ignore
+                    }
+
+                    final NioSocketConnector connector = new 
NioSocketConnector();
+
+                    // Set connect timeout.
+                    connector.setConnectTimeoutMillis( 30 * 1000L );
+
+                    connector.setHandler( new ClientHandler() );
+                    connector.getFilterChain()
+                             .addLast( "codec",
+                                       new ProtocolCodecFilter( new 
TextLineCodecFactory( Charset.forName( "UTF-8" ) ) ) );
+
+                    // Start communication.
+                    ConnectFuture cf = connector.connect( new 
InetSocketAddress( "localhost", nextAvailable ) );
+                    cf.awaitUninterruptibly();
+
+                    IoSession session = cf.getSession();
+
+                    // send a message
+                    session.write( "Hello World!\r" );
+
+                    // wait until response is received
+                    CountDownLatch latch = 
(CountDownLatch)session.getAttribute( "latch" );
+                    try {
+                        latch.await();
+                    } catch ( InterruptedException e1 ) {
+                        Thread.currentThread().interrupt();
+                    }
+
+                    // close the session
+                    CloseFuture closeFuture = session.closeOnFlush();
+
+                    connector.dispose( true );
+
+                    closeFuture.awaitUninterruptibly();
+                    acceptor.dispose( true );
+                }
+            };
+            thread.setDaemon( true );
+            thread.start();
+            thread.join( 1000 );
+
+            if ( thread.isAlive() ) {
+                for ( StackTraceElement stackTraceElement : 
thread.getStackTrace() ) {
+                    if ( "dispose".equals( stackTraceElement.getMethodName() )
+                         && AbstractIoService.class.getCanonicalName().equals( 
stackTraceElement.getClassName() ) ) {
+                        System.err.println( "Detected hang in 
AbstractIoService.dispose()!" );
+                    }
+                }
+                fail( "Thread should have died by now, supposed hang in 
AbstractIoService.dispose()" );
+            }
+        }
+        ;
+    }
+
+    public static class ClientHandler
+        extends
+        IoHandlerAdapter {
+
+        @Override
+        public void sessionCreated( IoSession session )
+            throws Exception {
+            session.setAttribute( "latch", new CountDownLatch( 1 ) );
+        }
+
+
+
+        @Override
+        public void messageReceived( IoSession session, Object message )
+            throws Exception {
+            CountDownLatch latch = (CountDownLatch)session.getAttribute( 
"latch" );
+            latch.countDown();
+        }
+
+
+
+        @Override
+        public void exceptionCaught( IoSession session, Throwable cause )
+            throws Exception {}
+    }
+
+    public static class ServerHandler
+        extends
+        IoHandlerAdapter {
+
+        @Override
+        public void messageReceived( IoSession session, Object message )
+            throws Exception {
+            session.write( message.toString() );
+        }
+
+
+
+        @Override
+        public void exceptionCaught( IoSession session, Throwable cause )
+            throws Exception {}
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/4f9b2c60/mina-core/src/test/java/org/apache/mina/core/service/SslTestHandshakeExceptionDIRMINA1077Test.java
----------------------------------------------------------------------
diff --git 
a/mina-core/src/test/java/org/apache/mina/core/service/SslTestHandshakeExceptionDIRMINA1077Test.java
 
b/mina-core/src/test/java/org/apache/mina/core/service/SslTestHandshakeExceptionDIRMINA1077Test.java
new file mode 100644
index 0000000..88c3b23
--- /dev/null
+++ 
b/mina-core/src/test/java/org/apache/mina/core/service/SslTestHandshakeExceptionDIRMINA1077Test.java
@@ -0,0 +1,186 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+
+package org.apache.mina.filter.ssl;
+
+import static org.junit.Assert.fail;
+
+import org.apache.mina.core.filterchain.DefaultIoFilterChainBuilder;
+import org.apache.mina.core.future.ConnectFuture;
+import org.apache.mina.core.service.AbstractIoService;
+import org.apache.mina.core.service.IoHandlerAdapter;
+import org.apache.mina.core.session.IoSession;
+import org.apache.mina.filter.codec.ProtocolCodecFilter;
+import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
+import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
+import org.apache.mina.transport.socket.nio.NioSocketConnector;
+import org.apache.mina.util.AvailablePortFinder;
+import org.junit.Test;
+
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManagerFactory;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.security.Security;
+
+/**
+ * Test a SSL session and provoke HandshakeException.
+ * This test should not hang or timeout when DIRMINA-1076/1077 is fixed.
+ * 
+ * @author chrjohn
+ */
+public class SslTestHandshakeExceptionDIRMINA1077Test {
+    private int port = AvailablePortFinder.getNextAvailable();
+    private static InetAddress address;
+    private static NioSocketAcceptor acceptor;
+
+    /** A JVM independant KEY_MANAGER_FACTORY algorithm */
+    private static final String KEY_MANAGER_FACTORY_ALGORITHM;
+
+    static {
+        String algorithm = 
Security.getProperty("ssl.KeyManagerFactory.algorithm");
+        if (algorithm == null) {
+            algorithm = KeyManagerFactory.getDefaultAlgorithm();
+        }
+
+        KEY_MANAGER_FACTORY_ALGORITHM = algorithm;
+    }
+
+
+    private static class TestHandler extends IoHandlerAdapter {
+        public void messageReceived(IoSession session, Object message) throws 
Exception {}
+
+        @Override
+        public void exceptionCaught( IoSession session, Throwable cause )
+            throws Exception {}
+    }
+
+    /**
+     * Starts a Server with the SSL Filter and a simple text line 
+     * protocol codec filter
+     */
+    private void startServer() throws Exception {
+        acceptor = new NioSocketAcceptor();
+
+        acceptor.setReuseAddress(true);
+        DefaultIoFilterChainBuilder filters = acceptor.getFilterChain();
+
+        // Inject the SSL filter
+        SslFilter sslFilter = new SslFilter(createSSLContext(true));
+        filters.addLast("sslFilter", sslFilter);
+        sslFilter.setNeedClientAuth(true);
+
+        // Inject the TestLine codec filter
+        filters.addLast("text", new ProtocolCodecFilter(new 
TextLineCodecFactory()));
+
+        acceptor.setHandler(new TestHandler());
+        acceptor.bind(new InetSocketAddress(port));
+    }
+    
+    private static void stopServer() {
+        acceptor.dispose(true);
+    }
+
+    private void startAndStopClient() throws Exception {
+        NioSocketConnector nioSocketConnector = new NioSocketConnector();
+        nioSocketConnector.setHandler(new TestHandler());
+        DefaultIoFilterChainBuilder filters = 
nioSocketConnector.getFilterChain();
+
+        // Inject the SSL filter
+        SslFilter sslFilter = new SslFilter(createSSLContext(false));
+        sslFilter.setUseClientMode( true );
+        filters.addLast("sslFilter", sslFilter);
+
+        address = InetAddress.getByName("localhost");
+        SocketAddress remoteAddress = new InetSocketAddress( address, port );
+        ConnectFuture connect = nioSocketConnector.connect( remoteAddress );
+        connect.awaitUninterruptibly();
+//        System.out.println( "Closing connection..." );
+        nioSocketConnector.dispose( true );
+//        System.out.println( "Connection closed!" );
+    }
+
+    private static SSLContext createSSLContext(boolean emptyKeystore) throws 
IOException, GeneralSecurityException {
+        char[] passphrase = "password".toCharArray();
+
+        SSLContext ctx = SSLContext.getInstance("TLSv1.2");
+        KeyManagerFactory kmf = 
KeyManagerFactory.getInstance(KEY_MANAGER_FACTORY_ALGORITHM);
+        TrustManagerFactory tmf = 
TrustManagerFactory.getInstance(KEY_MANAGER_FACTORY_ALGORITHM);
+
+        KeyStore ks = KeyStore.getInstance("JKS");
+        KeyStore ts = KeyStore.getInstance("JKS");
+
+        // use empty keystore to provoke handshake exception
+        if (emptyKeystore) {
+            
ks.load(SslTestHandshakeExceptionDIRMINA1077Test.class.getResourceAsStream("emptykeystore.sslTest"),
 passphrase);
+        } else {
+            
ks.load(SslTestHandshakeExceptionDIRMINA1077Test.class.getResourceAsStream("keystore.sslTest"),
 passphrase);
+        }
+        
ts.load(SslTestHandshakeExceptionDIRMINA1077Test.class.getResourceAsStream("truststore.sslTest"),
 passphrase);
+
+        kmf.init(ks, passphrase);
+        tmf.init(ts);
+
+        ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+
+        return ctx;
+    }
+
+    @Test(timeout=15000)
+    public void testSSL() throws Exception {
+        long startTime = System.currentTimeMillis();
+        // without DIRMINA-1076/1077 fixed, the test will hang after short time
+        while (System.currentTimeMillis() < startTime + 10000) {
+            try {
+                startServer();
+                
+                Thread t = new Thread() {
+                    public void run() {
+                        try {
+                            startAndStopClient();
+                        } catch ( Exception e ) {}
+                    }
+                };
+                t.setDaemon( true );
+                t.start();
+                t.join( 1000 );
+
+                if ( t.isAlive() ) {
+                    for ( StackTraceElement stackTraceElement : 
t.getStackTrace() ) {
+                        if ( "dispose".equals( 
stackTraceElement.getMethodName() )
+                             && AbstractIoService.class.getCanonicalName()
+                                                       .equals( 
stackTraceElement.getClassName() ) ) {
+                            System.err.println( "Detected hang in 
AbstractIoService.dispose()!" );
+                        }
+                    }
+                    fail( "Thread should have died by now, supposed hang in 
AbstractIoService.dispose()" );
+                }
+            } finally {
+                stopServer();
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina/blob/4f9b2c60/mina-core/src/test/resources/org/apache/mina/filter/ssl/emptykeystore.sslTest
----------------------------------------------------------------------
diff --git 
a/mina-core/src/test/resources/org/apache/mina/filter/ssl/emptykeystore.sslTest 
b/mina-core/src/test/resources/org/apache/mina/filter/ssl/emptykeystore.sslTest
new file mode 100644
index 0000000..65d4b65
Binary files /dev/null and 
b/mina-core/src/test/resources/org/apache/mina/filter/ssl/emptykeystore.sslTest 
differ

Reply via email to