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