UDP support implementation
[openflowjava.git] / openflow-protocol-impl / src / test / java / org / opendaylight / openflowjava / protocol / impl / core / TcpHandlerTest.java
index 47b2a33415b56564ccea9bfb0be73a071fc8fc63..129a86681d1e188e9ac98fc583dc585dee29f5c0 100644 (file)
-/* Copyright (C)2013 Pantheon Technologies, s.r.o. All rights reserved. */
+/*
+ * Copyright (c) 2014 Brocade Communications Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
 package org.opendaylight.openflowjava.protocol.impl.core;
 
-import io.netty.channel.Channel;
-import io.netty.util.concurrent.Future;
+import static org.junit.Assert.assertEquals;
+import io.netty.channel.ChannelHandlerContext;
 
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
+import java.io.IOException;
+import java.net.BindException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
 import java.util.concurrent.ExecutionException;
-import java.util.concurrent.TimeUnit;
 
-import org.junit.After;
 import org.junit.Assert;
-import org.junit.Before;
 import org.junit.Test;
-import org.opendaylight.openflowjava.protocol.impl.clients.SimpleClient;
-import org.opendaylight.openflowjava.protocol.impl.core.PublishingChannelInitializer;
-import org.opendaylight.openflowjava.protocol.impl.core.TcpHandler;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.openflowjava.protocol.api.connection.SwitchConnectionHandler;
+import org.opendaylight.openflowjava.protocol.impl.deserialization.DeserializationFactory;
+import org.opendaylight.openflowjava.protocol.impl.serialization.SerializationFactory;
+
+import com.google.common.util.concurrent.ListenableFuture;
 
 /**
- * 
- * @author michal.polkorab
+ *
+ * @author jameshall
  */
 public class TcpHandlerTest {
 
-    /** Name of file in which OpenFLow protocol messages are stored in binary format */
-    private static final String OF_BINARY_MESSAGE_INPUT_TXT = "OFBinaryMessageInput.txt";
+    private InetAddress serverAddress = InetAddress.getLoopbackAddress() ;
+    @Mock ChannelHandlerContext mockChHndlrCtx ;
+    @Mock TcpChannelInitializer mockChannelInitializer;
+    @Mock SwitchConnectionHandler mockSwitchConnHndler ;
+    @Mock SerializationFactory mockSerializationFactory ;
+    @Mock DeserializationFactory mockDeserializationFactory ;
 
-    protected static final Logger LOGGER = LoggerFactory
-            .getLogger(TcpHandlerTest.class);
+    TcpHandler tcpHandler ;
 
-    private static final long CONNECTION_TIMEOUT = 2000;
-
-    protected int port;
-    protected String address;
-    protected TcpHandler tcphandler;
+    /**
+     * Initialize mocks
+     */
+    public TcpHandlerTest() {
+        MockitoAnnotations.initMocks(this);
+    }
 
     /**
+     * Test run with null address set
+     * @throws IOException
      * @throws InterruptedException
      * @throws ExecutionException
      */
-    @Before
-    public void setUp() throws InterruptedException, ExecutionException {
-        tcphandler = new TcpHandler(0);
-        tcphandler.start();
-        tcphandler.getIsOnlineFuture().get();
-        port = tcphandler.getPort();
-        address = tcphandler.getAddress();
+    @Test
+    public void testRunWithNullAddress() throws IOException, InterruptedException, ExecutionException  {
+
+        tcpHandler = new TcpHandler(null, 0);
+        tcpHandler.setChannelInitializer(mockChannelInitializer);
+
+        assertEquals("failed to start server", true, startupServer()) ;
+        assertEquals("failed to connect client", true, clientConnection(tcpHandler.getPort())) ;
+        shutdownServer();
     }
-    
+
     /**
-     * stop {@link TcpHandler}
+     * Test run with address set
+     * @throws IOException
+     * @throws InterruptedException
+     * @throws ExecutionException
      */
-    @After
-    public void tearDown() {
-        tcphandler.shutdown();
+    @Test
+    public void testRunWithAddress() throws IOException, InterruptedException, ExecutionException  {
+
+        tcpHandler = new TcpHandler(serverAddress, 0);
+        tcpHandler.setChannelInitializer(mockChannelInitializer);
+
+        assertEquals("failed to start server", true, startupServer()) ;
+        assertEquals("failed to connect client", true, clientConnection(tcpHandler.getPort())) ;
+        shutdownServer();
     }
 
     /**
-     * Test of connections in {@link TcpHandler} - accepting connection of 1
-     * client
-     * @throws InterruptedException 
-     * @throws ExecutionException 
+     * Test run with encryption
+     * @throws InterruptedException
+     * @throws IOException
+     * @throws ExecutionException
      */
     @Test
-    public void testConnectOneClient() throws InterruptedException, ExecutionException {
-        int amountOfCLients = 1;
-        createAndStartClient(amountOfCLients);
-        int actualConnections = tcphandler.getNumberOfConnections();
-        Assert.assertEquals(amountOfCLients, actualConnections);
-        PublishingChannelInitializer channelInitializer = tcphandler.getChannelInitializer();
-        for (Iterator<Channel> iterator = channelInitializer.getConnectionIterator(); iterator.hasNext();) {
-            Channel channel =  iterator.next();
-            try {
-                channel.close().sync();
-            } catch (InterruptedException e) {
-                LOGGER.error(e.getMessage(), e);
-            }
-        }
-        actualConnections = tcphandler.getNumberOfConnections();
-        Assert.assertEquals(0, actualConnections);
+    public void testRunWithEncryption () throws InterruptedException, IOException, ExecutionException {
+        int serverPort = 28001;
+        tcpHandler = new TcpHandler(serverAddress, serverPort);
+        tcpHandler.setChannelInitializer(mockChannelInitializer);
+
+        assertEquals( "failed to start server", true, startupServer()) ;
+        assertEquals( "wrong connection count", 0, tcpHandler.getNumberOfConnections() );
+        assertEquals( "wrong port", serverPort, tcpHandler.getPort() );
+        assertEquals( "wrong address", serverAddress.getHostAddress(), tcpHandler.getAddress()) ;
+
+        assertEquals("failed to connect client", true, clientConnection(tcpHandler.getPort())) ;
+
+        shutdownServer();
     }
-    
+
     /**
-     * Test of connections in {@link TcpHandler} - accepting connection of 10
-     * clients
-     * @throws InterruptedException 
-     * @throws ExecutionException 
+     * Test run on already used port
+     * @throws IOException
      */
     @Test
-    public void testConnectTenClients() throws InterruptedException, ExecutionException {
-        int amountOfCLients = 10;
-        createAndStartClient(amountOfCLients);
-        int actualConnections = tcphandler.getNumberOfConnections();
-        Assert.assertEquals(amountOfCLients, actualConnections);
-        PublishingChannelInitializer channelInitializer = tcphandler.getChannelInitializer();
-        for (Iterator<Channel> iterator = channelInitializer.getConnectionIterator(); iterator.hasNext();) {
-            Channel channel =  iterator.next();
-            try {
-                channel.close().sync();
-            } catch (InterruptedException e) {
-                LOGGER.error(e.getMessage(), e);
+    public void testSocketAlreadyInUse() throws IOException {
+        int serverPort = 28001;
+        Socket firstBinder = new Socket();
+        boolean exceptionThrown = false;
+        try {
+            firstBinder.bind(new InetSocketAddress(serverAddress, serverPort));
+        } catch (Exception e) {
+            Assert.fail("Test precondition failed - not able to bind socket to port " + serverPort);
+        }
+        try {
+            tcpHandler = new TcpHandler(serverAddress, serverPort);
+            tcpHandler.setChannelInitializer(mockChannelInitializer);
+            tcpHandler.run();
+        } catch (Exception e) {
+            if (e instanceof BindException) {
+                exceptionThrown = true;
             }
         }
-        actualConnections = tcphandler.getNumberOfConnections();
-        Assert.assertEquals(0, actualConnections);
+        firstBinder.close();
+        Assert.assertTrue("Expected BindException has not been thrown", exceptionThrown == true);
     }
-    
+
     /**
-     * Test of disconnecting in {@link TcpHandler} - shutting down connection of 10
-     * clients
-     * @throws InterruptedException 
-     * @throws ExecutionException 
+     * Trigger the server shutdown and wait 2 seconds for completion
      */
-    @Test
-    public void testDisconnectTenClients() throws InterruptedException, ExecutionException {
-        int amountOfCLients = 10;
-        List<SimpleClient> clients = createAndStartClient(amountOfCLients);
-        int actualConnections = tcphandler.getNumberOfConnections();
-        Assert.assertEquals(amountOfCLients, actualConnections);
-        
-        disconnectClients(clients);
-
-        actualConnections = tcphandler.getNumberOfConnections();
-        Assert.assertEquals(0, actualConnections);
+    private void shutdownServer() throws InterruptedException, ExecutionException {
+        ListenableFuture<Boolean> shutdownRet = tcpHandler.shutdown() ;
+        while ( shutdownRet.isDone() != true )
+            Thread.sleep(100) ;
+        assertEquals("shutdown failed", true, shutdownRet.get());
     }
 
     /**
-     * @param amountOfCLients 
-     * @return new clients up and running
      * @throws InterruptedException
+     * @throws IOException
      * @throws ExecutionException
      */
-    private List<SimpleClient> createAndStartClient(int amountOfCLients)
-            throws InterruptedException, ExecutionException {
-        List<SimpleClient> clientsHorde = new ArrayList<>();
-        for (int i = 0; i < amountOfCLients; i++) {
-            SimpleClient sc = new SimpleClient(address, port, getClass().getResourceAsStream(
-                    OF_BINARY_MESSAGE_INPUT_TXT));
-            sc.setSecuredClient(true);
-            clientsHorde.add(sc);
-            sc.start();
-        }
-        for (SimpleClient sc : clientsHorde) {
-            try {
-                sc.getIsOnlineFuture().get(CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS);
-            } catch (Exception e) {
-                LOGGER.error(e.getMessage(), e);
-                throw new ExecutionException(e);
+    private Boolean startupServer() throws InterruptedException, IOException, ExecutionException {
+        ListenableFuture<Boolean> online = tcpHandler.getIsOnlineFuture();
+
+            (new Thread(tcpHandler)).start();
+            int retry = 0;
+            while (online.isDone() != true && retry++ < 20) {
+                Thread.sleep(100);
             }
-        }
-        return clientsHorde;
+        return online.isDone() ;
     }
-    
     /**
-     * Test of disconnecting in {@link TcpHandler} - shutting down connection of 1
-     * client
-     * @throws InterruptedException 
-     * @throws ExecutionException 
+     * @throws IOException
      */
-    @Test
-    public void testDisconnectOneClient() throws InterruptedException, ExecutionException {
-        int amountOfCLients = 1;
-        List<SimpleClient> clients = createAndStartClient(amountOfCLients);
-        int actualConnections = tcphandler.getNumberOfConnections();
-        Assert.assertEquals(amountOfCLients, actualConnections);
-        disconnectClients(clients);
-        actualConnections = tcphandler.getNumberOfConnections();
-        Assert.assertEquals(0, actualConnections);
-    }
-
-    /**
-     * @param clients
-     * @throws InterruptedException 
-     */
-    private static void disconnectClients(List<SimpleClient> clients) throws InterruptedException {
-        List<Future<?>> disconnectFutureBag = new ArrayList<>();
-        for (SimpleClient simpleClient : clients) {
-            disconnectFutureBag.add(simpleClient.disconnect());
-        }
-        for (Future<?> toBeDisconnected : disconnectFutureBag) {
-            toBeDisconnected.sync();
-        }
+    private static Boolean clientConnection(int port) throws IOException {
+        // Connect, and disconnect
+        Socket socket = new Socket(InetAddress.getLoopbackAddress(), port );
+        Boolean result = socket.isConnected();
+        socket.close() ;
+        return result ;
     }
 }