-/* 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 ;
}
}