65cbd6a896df056bc325c8e8247674416850fdad
[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;
87     private ConnectionAdapterImpl adapter;\r
88     private Cache<RpcResponseKey, ResponseExpectedRpcListener<?>> cache;\r
89 \r
90     /**\r
91      * Initializes ConnectionAdapter\r
92      */\r
93     @Before\r
94     public void setUp() {\r
95         MockitoAnnotations.initMocks(this);\r
96         when(channel.pipeline()).thenReturn(pipeline);\r
97         adapter = new ConnectionAdapterImpl(channel, InetSocketAddress.createUnresolved("10.0.0.1", 6653));\r
98         adapter.setMessageListener(messageListener);\r
99         adapter.setSystemListener(systemListener);\r
100         adapter.setConnectionReadyListener(readyListener);\r
101         cache = CacheBuilder.newBuilder().concurrencyLevel(1).expireAfterWrite(RPC_RESPONSE_EXPIRATION, TimeUnit.MINUTES)\r
102                 .removalListener(REMOVAL_LISTENER).build();\r
103         adapter.setResponseCache(cache);
104         when(channel.disconnect()).thenReturn(channelFuture);
105     }\r
106 \r
107     /**\r
108      * Tests {@link ConnectionAdapterImpl#consume(DataObject)} with notifications\r
109      */\r
110     @Test\r
111     public void testConsume() {\r
112         DataObject message = new EchoRequestMessageBuilder().build();\r
113         adapter.consume(message);\r
114         verify(messageListener, times(1)).onEchoRequestMessage((EchoRequestMessage) message);\r
115         message = new ErrorMessageBuilder().build();\r
116         adapter.consume(message);\r
117         verify(messageListener, times(1)).onErrorMessage((ErrorMessage) message);\r
118         message = new ExperimenterMessageBuilder().build();\r
119         adapter.consume(message);\r
120         verify(messageListener, times(1)).onExperimenterMessage((ExperimenterMessage) message);\r
121         message = new FlowRemovedMessageBuilder().build();\r
122         adapter.consume(message);\r
123         verify(messageListener, times(1)).onFlowRemovedMessage((FlowRemovedMessage) message);\r
124         message = new HelloMessageBuilder().build();\r
125         adapter.consume(message);\r
126         verify(messageListener, times(1)).onHelloMessage((HelloMessage) message);\r
127         message = new MultipartReplyMessageBuilder().build();\r
128         adapter.consume(message);\r
129         verify(messageListener, times(1)).onMultipartReplyMessage((MultipartReplyMessage) message);\r
130         message = new PacketInMessageBuilder().build();\r
131         adapter.consume(message);\r
132         verify(messageListener, times(1)).onPacketInMessage((PacketInMessage) message);\r
133         message = new PortStatusMessageBuilder().build();\r
134         adapter.consume(message);\r
135         verify(messageListener, times(1)).onPortStatusMessage((PortStatusMessage) message);\r
136         message = new SwitchIdleEventBuilder().build();\r
137         adapter.consume(message);\r
138         verify(systemListener, times(1)).onSwitchIdleEvent((SwitchIdleEvent) message);\r
139         message = new DisconnectEventBuilder().build();\r
140         adapter.consume(message);\r
141         verify(systemListener, times(1)).onDisconnectEvent((DisconnectEvent) message);\r
142         message = new EchoRequestMessageBuilder().build();\r
143         adapter.consume(message);\r
144         verify(messageListener, times(1)).onEchoRequestMessage((EchoRequestMessage) message);\r
145     }\r
146 \r
147     /**\r
148      * Tests {@link ConnectionAdapterImpl#consume(DataObject)} with unexpected rpc\r
149      */\r
150     @Test\r
151     public void testConsume2() {\r
152         adapter.setResponseCache(mockCache);\r
153         BarrierOutputBuilder barrierBuilder = new BarrierOutputBuilder();\r
154         barrierBuilder.setXid(42L);\r
155         BarrierOutput barrier = barrierBuilder.build();\r
156         adapter.consume(barrier);\r
157         verify(mockCache, times(1)).getIfPresent(any(RpcResponseKey.class));\r
158     }\r
159 \r
160     /**\r
161      * Tests {@link ConnectionAdapterImpl#consume(DataObject)} with expected rpc\r
162      */\r
163     @Test\r
164     public void testConsume3() {\r
165         BarrierInputBuilder inputBuilder = new BarrierInputBuilder();\r
166         inputBuilder.setVersion((short) EncodeConstants.OF13_VERSION_ID);\r
167         inputBuilder.setXid(42L);\r
168         BarrierInput barrierInput = inputBuilder.build();\r
169         RpcResponseKey key = new RpcResponseKey(42L, "org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutput");\r
170         ResponseExpectedRpcListener<OfHeader> listener = new ResponseExpectedRpcListener<>(barrierInput,\r
171                 "failure", mockCache, key);\r
172         cache.put(key, listener);\r
173         BarrierOutputBuilder barrierBuilder = new BarrierOutputBuilder();\r
174         barrierBuilder.setXid(42L);\r
175         BarrierOutput barrierOutput = barrierBuilder.build();\r
176         adapter.consume(barrierOutput);\r
177         ResponseExpectedRpcListener<?> ifPresent = cache.getIfPresent(key);\r
178         Assert.assertNull("Listener was not discarded", ifPresent);\r
179     }
180     /**
181      * Test IsAlive method
182      */
183     @Test
184     public void testIsAlive(){
185         int port = 9876;
186         String host ="localhost";
187         InetSocketAddress inetSockAddr = InetSocketAddress.createUnresolved(host, port);
188         ConnectionAdapterImpl connAddapter = new ConnectionAdapterImpl(channel,inetSockAddr);
189         Assert.assertEquals("Wrong - diffrence between channel.isOpen() and ConnectionAdapterImpl.isAlive()", channel.isOpen(), connAddapter.isAlive());
190
191         connAddapter.disconnect();
192         Assert.assertFalse("Wrong - ConnectionAdapterImpl can not be aliva after disconnet.", connAddapter.isAlive());
193     }
194
195     /**
196      * Test throw exception if no listener are present
197      */
198     @Test(expected = java.lang.IllegalStateException.class)
199     public void testMissingListeners(){
200         int port = 9876;
201         String host ="localhost";
202         InetSocketAddress inetSockAddr = InetSocketAddress.createUnresolved(host, port);
203         ConnectionAdapterImpl connAddapter = new ConnectionAdapterImpl(channel,inetSockAddr);
204         connAddapter.setSystemListener(null);
205         connAddapter.setMessageListener(null);
206         connAddapter.setConnectionReadyListener(null);
207         connAddapter.checkListeners();
208     }
209
210 }