2 * Copyright (c) 2014 Pantheon Technologies s.r.o. and others. All rights reserved.
\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
9 package org.opendaylight.openflowjava.protocol.impl.connection;
\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
19 import java.net.InetSocketAddress;
\r
20 import java.util.concurrent.TimeUnit;
\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
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
64 * @author michal.polkorab
\r
68 public class ConnectionAdapterImplTest {
\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
74 public void onRemoval(
\r
75 final RemovalNotification<RpcResponseKey, ResponseExpectedRpcListener<?>> notification) {
\r
76 notification.getValue().discard();
\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
88 private ConnectionAdapterImpl adapter;
\r
89 private Cache<RpcResponseKey, ResponseExpectedRpcListener<?>> cache;
\r
92 * Initializes ConnectionAdapter
\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);
109 * Tests {@link ConnectionAdapterImpl#consume(DataObject)} with notifications
\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
149 * Tests {@link ConnectionAdapterImpl#consume(DataObject)} with unexpected rpc
\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
162 * Tests {@link ConnectionAdapterImpl#consume(DataObject)} with expected rpc
\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
182 * Test IsAlive method
185 public void testIsAlive(){
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());
192 connAddapter.disconnect();
193 Assert.assertFalse("Wrong - ConnectionAdapterImpl can not be alive after disconnet.", connAddapter.isAlive());
197 * Test throw exception if no listeners are present
199 @Test(expected = java.lang.IllegalStateException.class)
200 public void testMissingListeners(){
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();