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