Add unit test - fully covered SwitchConnectionProviderImpl, ConnectionAdapterImpl
[openflowjava.git] / openflow-protocol-impl / src / test / java / org / opendaylight / openflowjava / protocol / impl / connection / ConnectionAdapterImplTest.java
1 /*\r
2  * Copyright (c) 2014 Pantheon Technologies s.r.o. and others. All rights reserved.\r
3  *\r
4  * This program and the accompanying materials are made available under the\r
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
6  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
7  */\r
8 \r
9 package org.opendaylight.openflowjava.protocol.impl.connection;\r
10 \r
11 import static org.mockito.Matchers.any;\r
12 import static org.mockito.Mockito.times;\r
13 import static org.mockito.Mockito.verify;\r
14 import static org.mockito.Mockito.when;\r
15 import io.netty.channel.ChannelFuture;\r
16 import io.netty.channel.ChannelPipeline;\r
17 import io.netty.channel.socket.SocketChannel;\r
18 \r
19 import java.net.InetSocketAddress;\r
20 import java.util.concurrent.TimeUnit;\r
21 \r
22 import org.junit.Assert;\r
23 import org.junit.Before;\r
24 import org.junit.Test;\r
25 import org.mockito.Mock;\r
26 import org.mockito.MockitoAnnotations;\r
27 import org.opendaylight.openflowjava.protocol.api.connection.ConnectionReadyListener;\r
28 import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;\r
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInput;\r
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInputBuilder;\r
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutput;\r
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutputBuilder;\r
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessage;\r
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessageBuilder;\r
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessage;\r
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessageBuilder;\r
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterMessage;\r
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterMessageBuilder;\r
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessage;\r
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessageBuilder;\r
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloMessage;\r
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloMessageBuilder;\r
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage;\r
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessageBuilder;\r
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;\r
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OpenflowProtocolListener;\r
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessage;\r
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessageBuilder;\r
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage;\r
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessageBuilder;\r
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.DisconnectEvent;\r
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.DisconnectEventBuilder;\r
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.SwitchIdleEvent;\r
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.SwitchIdleEventBuilder;\r
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.SystemNotificationsListener;\r
56 import org.opendaylight.yangtools.yang.binding.DataObject;\r
57 \r
58 import com.google.common.cache.Cache;\r
59 import com.google.common.cache.CacheBuilder;\r
60 import com.google.common.cache.RemovalListener;\r
61 import com.google.common.cache.RemovalNotification;\r
62 \r
63 /**\r
64  * @author michal.polkorab\r
65  * @author madamjak\r
66  *\r
67  */\r
68 public class ConnectionAdapterImplTest {\r
69 \r
70     private static final int RPC_RESPONSE_EXPIRATION = 1;\r
71     private static final RemovalListener<RpcResponseKey, ResponseExpectedRpcListener<?>> REMOVAL_LISTENER =\r
72             new RemovalListener<RpcResponseKey, ResponseExpectedRpcListener<?>>() {\r
73         @Override\r
74         public void onRemoval(\r
75                 final RemovalNotification<RpcResponseKey, ResponseExpectedRpcListener<?>> notification) {\r
76             notification.getValue().discard();\r
77         }\r
78     };\r
79 \r
80     @Mock SocketChannel channel;\r
81     @Mock ChannelPipeline pipeline;\r
82     @Mock OpenflowProtocolListener messageListener;\r
83     @Mock SystemNotificationsListener systemListener;\r
84     @Mock ConnectionReadyListener readyListener;\r
85     @Mock Cache<RpcResponseKey, ResponseExpectedRpcListener<?>> mockCache;\r
86     @Mock ChannelFuture channelFuture;\r
87
88     private ConnectionAdapterImpl adapter;\r
89     private Cache<RpcResponseKey, ResponseExpectedRpcListener<?>> cache;\r
90 \r
91     /**\r
92      * Initializes ConnectionAdapter\r
93      */\r
94     @Before\r
95     public void setUp() {\r
96         MockitoAnnotations.initMocks(this);\r
97         when(channel.pipeline()).thenReturn(pipeline);\r
98         adapter = new ConnectionAdapterImpl(channel, InetSocketAddress.createUnresolved("10.0.0.1", 6653));\r
99         adapter.setMessageListener(messageListener);\r
100         adapter.setSystemListener(systemListener);\r
101         adapter.setConnectionReadyListener(readyListener);\r
102         cache = CacheBuilder.newBuilder().concurrencyLevel(1).expireAfterWrite(RPC_RESPONSE_EXPIRATION, TimeUnit.MINUTES)\r
103                 .removalListener(REMOVAL_LISTENER).build();\r
104         adapter.setResponseCache(cache);
105         when(channel.disconnect()).thenReturn(channelFuture);
106     }\r
107 \r
108     /**\r
109      * Tests {@link ConnectionAdapterImpl#consume(DataObject)} with notifications\r
110      */\r
111     @Test\r
112     public void testConsume() {\r
113         DataObject message = new EchoRequestMessageBuilder().build();\r
114         adapter.consume(message);\r
115         verify(messageListener, times(1)).onEchoRequestMessage((EchoRequestMessage) message);\r
116         message = new ErrorMessageBuilder().build();\r
117         adapter.consume(message);\r
118         verify(messageListener, times(1)).onErrorMessage((ErrorMessage) message);\r
119         message = new ExperimenterMessageBuilder().build();\r
120         adapter.consume(message);\r
121         verify(messageListener, times(1)).onExperimenterMessage((ExperimenterMessage) message);\r
122         message = new FlowRemovedMessageBuilder().build();\r
123         adapter.consume(message);\r
124         verify(messageListener, times(1)).onFlowRemovedMessage((FlowRemovedMessage) message);\r
125         message = new HelloMessageBuilder().build();\r
126         adapter.consume(message);\r
127         verify(messageListener, times(1)).onHelloMessage((HelloMessage) message);\r
128         message = new MultipartReplyMessageBuilder().build();\r
129         adapter.consume(message);\r
130         verify(messageListener, times(1)).onMultipartReplyMessage((MultipartReplyMessage) message);\r
131         message = new PacketInMessageBuilder().build();\r
132         adapter.consume(message);\r
133         verify(messageListener, times(1)).onPacketInMessage((PacketInMessage) message);\r
134         message = new PortStatusMessageBuilder().build();\r
135         adapter.consume(message);\r
136         verify(messageListener, times(1)).onPortStatusMessage((PortStatusMessage) message);\r
137         message = new SwitchIdleEventBuilder().build();\r
138         adapter.consume(message);\r
139         verify(systemListener, times(1)).onSwitchIdleEvent((SwitchIdleEvent) message);\r
140         message = new DisconnectEventBuilder().build();\r
141         adapter.consume(message);\r
142         verify(systemListener, times(1)).onDisconnectEvent((DisconnectEvent) message);\r
143         message = new EchoRequestMessageBuilder().build();\r
144         adapter.consume(message);\r
145         verify(messageListener, times(1)).onEchoRequestMessage((EchoRequestMessage) message);\r
146     }\r
147 \r
148     /**\r
149      * Tests {@link ConnectionAdapterImpl#consume(DataObject)} with unexpected rpc\r
150      */\r
151     @Test\r
152     public void testConsume2() {\r
153         adapter.setResponseCache(mockCache);\r
154         BarrierOutputBuilder barrierBuilder = new BarrierOutputBuilder();\r
155         barrierBuilder.setXid(42L);\r
156         BarrierOutput barrier = barrierBuilder.build();\r
157         adapter.consume(barrier);\r
158         verify(mockCache, times(1)).getIfPresent(any(RpcResponseKey.class));\r
159     }\r
160 \r
161     /**\r
162      * Tests {@link ConnectionAdapterImpl#consume(DataObject)} with expected rpc\r
163      */\r
164     @Test\r
165     public void testConsume3() {\r
166         BarrierInputBuilder inputBuilder = new BarrierInputBuilder();\r
167         inputBuilder.setVersion((short) EncodeConstants.OF13_VERSION_ID);\r
168         inputBuilder.setXid(42L);\r
169         BarrierInput barrierInput = inputBuilder.build();\r
170         RpcResponseKey key = new RpcResponseKey(42L, "org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutput");\r
171         ResponseExpectedRpcListener<OfHeader> listener = new ResponseExpectedRpcListener<>(barrierInput,\r
172                 "failure", mockCache, key);\r
173         cache.put(key, listener);\r
174         BarrierOutputBuilder barrierBuilder = new BarrierOutputBuilder();\r
175         barrierBuilder.setXid(42L);\r
176         BarrierOutput barrierOutput = barrierBuilder.build();\r
177         adapter.consume(barrierOutput);\r
178         ResponseExpectedRpcListener<?> ifPresent = cache.getIfPresent(key);\r
179         Assert.assertNull("Listener was not discarded", ifPresent);\r
180     }
181     /**
182      * Test IsAlive method
183      */
184     @Test
185     public void testIsAlive(){
186         int port = 9876;
187         String host ="localhost";
188         InetSocketAddress inetSockAddr = InetSocketAddress.createUnresolved(host, port);
189         ConnectionAdapterImpl connAddapter = new ConnectionAdapterImpl(channel,inetSockAddr);
190         Assert.assertEquals("Wrong - diffrence between channel.isOpen() and ConnectionAdapterImpl.isAlive()", channel.isOpen(), connAddapter.isAlive());
191
192         connAddapter.disconnect();
193         Assert.assertFalse("Wrong - ConnectionAdapterImpl can not be alive after disconnet.", connAddapter.isAlive());
194     }
195
196     /**
197      * Test throw exception if no listeners are present
198      */
199     @Test(expected = java.lang.IllegalStateException.class)
200     public void testMissingListeners(){
201         int port = 9876;
202         String host ="localhost";
203         InetSocketAddress inetSockAddr = InetSocketAddress.createUnresolved(host, port);
204         ConnectionAdapterImpl connAddapter = new ConnectionAdapterImpl(channel,inetSockAddr);
205         connAddapter.setSystemListener(null);
206         connAddapter.setMessageListener(null);
207         connAddapter.setConnectionReadyListener(null);
208         connAddapter.checkListeners();
209     }
210 }