--- /dev/null
+/*\r
+ * Copyright (c) 2014 Pantheon Technologies s.r.o. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.openflowjava.protocol.impl.core.connection;\r
+\r
+import static org.mockito.Matchers.any;\r
+import static org.mockito.Mockito.times;\r
+import static org.mockito.Mockito.verify;\r
+import static org.mockito.Mockito.when;\r
+import io.netty.channel.ChannelFuture;\r
+import io.netty.channel.ChannelPipeline;\r
+import io.netty.channel.socket.SocketChannel;\r
+\r
+import java.net.InetSocketAddress;\r
+import java.util.concurrent.TimeUnit;\r
+\r
+import org.junit.Assert;\r
+import org.junit.Before;\r
+import org.junit.Test;\r
+import org.mockito.Mock;\r
+import org.mockito.MockitoAnnotations;\r
+import org.opendaylight.openflowjava.protocol.api.connection.ConnectionReadyListener;\r
+import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;\r
+import org.opendaylight.openflowjava.protocol.impl.core.connection.ConnectionAdapterImpl;\r
+import org.opendaylight.openflowjava.protocol.impl.core.connection.ResponseExpectedRpcListener;\r
+import org.opendaylight.openflowjava.protocol.impl.core.connection.RpcResponseKey;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInput;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInputBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutput;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutputBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessage;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessageBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessage;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessageBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterMessage;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterMessageBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessage;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessageBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloMessage;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloMessageBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessageBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OpenflowProtocolListener;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessage;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessageBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessageBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.DisconnectEvent;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.DisconnectEventBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.SwitchIdleEvent;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.SwitchIdleEventBuilder;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.SystemNotificationsListener;\r
+import org.opendaylight.yangtools.yang.binding.DataObject;\r
+\r
+import com.google.common.cache.Cache;\r
+import com.google.common.cache.CacheBuilder;\r
+import com.google.common.cache.RemovalListener;\r
+import com.google.common.cache.RemovalNotification;\r
+\r
+/**\r
+ * @author michal.polkorab\r
+ * @author madamjak\r
+ *\r
+ */\r
+public class ConnectionAdapterImplTest {\r
+\r
+ private static final int RPC_RESPONSE_EXPIRATION = 1;\r
+ private static final RemovalListener<RpcResponseKey, ResponseExpectedRpcListener<?>> REMOVAL_LISTENER =\r
+ new RemovalListener<RpcResponseKey, ResponseExpectedRpcListener<?>>() {\r
+ @Override\r
+ public void onRemoval(\r
+ final RemovalNotification<RpcResponseKey, ResponseExpectedRpcListener<?>> notification) {\r
+ notification.getValue().discard();\r
+ }\r
+ };\r
+\r
+ @Mock SocketChannel channel;\r
+ @Mock ChannelPipeline pipeline;\r
+ @Mock OpenflowProtocolListener messageListener;\r
+ @Mock SystemNotificationsListener systemListener;\r
+ @Mock ConnectionReadyListener readyListener;\r
+ @Mock Cache<RpcResponseKey, ResponseExpectedRpcListener<?>> mockCache;\r
+ @Mock ChannelFuture channelFuture;\r
+
+ private ConnectionAdapterImpl adapter;\r
+ private Cache<RpcResponseKey, ResponseExpectedRpcListener<?>> cache;\r
+\r
+ /**\r
+ * Initializes ConnectionAdapter\r
+ */\r
+ @Before\r
+ public void setUp() {\r
+ MockitoAnnotations.initMocks(this);\r
+ when(channel.pipeline()).thenReturn(pipeline);\r
+ adapter = new ConnectionAdapterImpl(channel, InetSocketAddress.createUnresolved("10.0.0.1", 6653));\r
+ adapter.setMessageListener(messageListener);\r
+ adapter.setSystemListener(systemListener);\r
+ adapter.setConnectionReadyListener(readyListener);\r
+ cache = CacheBuilder.newBuilder().concurrencyLevel(1).expireAfterWrite(RPC_RESPONSE_EXPIRATION, TimeUnit.MINUTES)\r
+ .removalListener(REMOVAL_LISTENER).build();\r
+ adapter.setResponseCache(cache);
+ when(channel.disconnect()).thenReturn(channelFuture);
+ }\r
+\r
+ /**\r
+ * Tests {@link ConnectionAdapterImpl#consume(DataObject)} with notifications\r
+ */\r
+ @Test\r
+ public void testConsume() {\r
+ DataObject message = new EchoRequestMessageBuilder().build();\r
+ adapter.consume(message);\r
+ verify(messageListener, times(1)).onEchoRequestMessage((EchoRequestMessage) message);\r
+ message = new ErrorMessageBuilder().build();\r
+ adapter.consume(message);\r
+ verify(messageListener, times(1)).onErrorMessage((ErrorMessage) message);\r
+ message = new ExperimenterMessageBuilder().build();\r
+ adapter.consume(message);\r
+ verify(messageListener, times(1)).onExperimenterMessage((ExperimenterMessage) message);\r
+ message = new FlowRemovedMessageBuilder().build();\r
+ adapter.consume(message);\r
+ verify(messageListener, times(1)).onFlowRemovedMessage((FlowRemovedMessage) message);\r
+ message = new HelloMessageBuilder().build();\r
+ adapter.consume(message);\r
+ verify(messageListener, times(1)).onHelloMessage((HelloMessage) message);\r
+ message = new MultipartReplyMessageBuilder().build();\r
+ adapter.consume(message);\r
+ verify(messageListener, times(1)).onMultipartReplyMessage((MultipartReplyMessage) message);\r
+ message = new PacketInMessageBuilder().build();\r
+ adapter.consume(message);\r
+ verify(messageListener, times(1)).onPacketInMessage((PacketInMessage) message);\r
+ message = new PortStatusMessageBuilder().build();\r
+ adapter.consume(message);\r
+ verify(messageListener, times(1)).onPortStatusMessage((PortStatusMessage) message);\r
+ message = new SwitchIdleEventBuilder().build();\r
+ adapter.consume(message);\r
+ verify(systemListener, times(1)).onSwitchIdleEvent((SwitchIdleEvent) message);\r
+ message = new DisconnectEventBuilder().build();\r
+ adapter.consume(message);\r
+ verify(systemListener, times(1)).onDisconnectEvent((DisconnectEvent) message);\r
+ message = new EchoRequestMessageBuilder().build();\r
+ adapter.consume(message);\r
+ verify(messageListener, times(1)).onEchoRequestMessage((EchoRequestMessage) message);\r
+ }\r
+\r
+ /**\r
+ * Tests {@link ConnectionAdapterImpl#consume(DataObject)} with unexpected rpc\r
+ */\r
+ @Test\r
+ public void testConsume2() {\r
+ adapter.setResponseCache(mockCache);\r
+ BarrierOutputBuilder barrierBuilder = new BarrierOutputBuilder();\r
+ barrierBuilder.setXid(42L);\r
+ BarrierOutput barrier = barrierBuilder.build();\r
+ adapter.consume(barrier);\r
+ verify(mockCache, times(1)).getIfPresent(any(RpcResponseKey.class));\r
+ }\r
+\r
+ /**\r
+ * Tests {@link ConnectionAdapterImpl#consume(DataObject)} with expected rpc\r
+ */\r
+ @Test\r
+ public void testConsume3() {\r
+ BarrierInputBuilder inputBuilder = new BarrierInputBuilder();\r
+ inputBuilder.setVersion((short) EncodeConstants.OF13_VERSION_ID);\r
+ inputBuilder.setXid(42L);\r
+ BarrierInput barrierInput = inputBuilder.build();\r
+ RpcResponseKey key = new RpcResponseKey(42L, "org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutput");\r
+ ResponseExpectedRpcListener<OfHeader> listener = new ResponseExpectedRpcListener<>(barrierInput,\r
+ "failure", mockCache, key);\r
+ cache.put(key, listener);\r
+ BarrierOutputBuilder barrierBuilder = new BarrierOutputBuilder();\r
+ barrierBuilder.setXid(42L);\r
+ BarrierOutput barrierOutput = barrierBuilder.build();\r
+ adapter.consume(barrierOutput);\r
+ ResponseExpectedRpcListener<?> ifPresent = cache.getIfPresent(key);\r
+ Assert.assertNull("Listener was not discarded", ifPresent);\r
+ }
+ /**
+ * Test IsAlive method
+ */
+ @Test
+ public void testIsAlive(){
+ int port = 9876;
+ String host ="localhost";
+ InetSocketAddress inetSockAddr = InetSocketAddress.createUnresolved(host, port);
+ ConnectionAdapterImpl connAddapter = new ConnectionAdapterImpl(channel,inetSockAddr);
+ Assert.assertEquals("Wrong - diffrence between channel.isOpen() and ConnectionAdapterImpl.isAlive()", channel.isOpen(), connAddapter.isAlive());
+
+ connAddapter.disconnect();
+ Assert.assertFalse("Wrong - ConnectionAdapterImpl can not be alive after disconnet.", connAddapter.isAlive());
+ }
+
+ /**
+ * Test throw exception if no listeners are present
+ */
+ @Test(expected = java.lang.IllegalStateException.class)
+ public void testMissingListeners(){
+ int port = 9876;
+ String host ="localhost";
+ InetSocketAddress inetSockAddr = InetSocketAddress.createUnresolved(host, port);
+ ConnectionAdapterImpl connAddapter = new ConnectionAdapterImpl(channel,inetSockAddr);
+ connAddapter.setSystemListener(null);
+ connAddapter.setMessageListener(null);
+ connAddapter.setConnectionReadyListener(null);
+ connAddapter.checkListeners();
+ }
+}