2 * Copyright (c) 2014 Pantheon Technologies s.r.o. and others. All rights reserved.
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
8 package org.opendaylight.openflowjava.protocol.impl.core.connection;
10 import static org.mockito.Mockito.doReturn;
11 import static org.mockito.Mockito.when;
13 import com.google.common.cache.Cache;
14 import com.google.common.cache.CacheBuilder;
15 import com.google.common.cache.RemovalListener;
16 import io.netty.channel.ChannelFuture;
17 import io.netty.channel.ChannelOutboundHandlerAdapter;
18 import io.netty.channel.ChannelPipeline;
19 import io.netty.channel.embedded.EmbeddedChannel;
20 import io.netty.channel.socket.SocketChannel;
21 import java.net.InetSocketAddress;
22 import java.util.concurrent.TimeUnit;
23 import org.junit.After;
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.ConnectionAdapter.SystemListener;
31 import org.opendaylight.openflowjava.protocol.api.connection.ConnectionReadyListener;
32 import org.opendaylight.openflowjava.statistics.CounterEventTypes;
33 import org.opendaylight.openflowjava.statistics.StatisticsCounters;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInput;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoInput;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoReplyInput;
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.ErrorMessageBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterInput;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterMessageBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInput;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessageBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncInput;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigInput;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesInput;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigInput;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GroupModInput;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloInput;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloMessageBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MeterModInput;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessageBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OpenflowProtocolListener;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessageBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInput;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInput;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessageBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestInput;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetAsyncInput;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetConfigInput;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.TableModInput;
63 import org.opendaylight.yangtools.yang.binding.DataObject;
64 import org.opendaylight.yangtools.yang.common.Uint32;
67 * Test counters in ConnectionAdapter (at least DS_ENTERED_OFJAVA, DS_FLOW_MODS_ENTERED and US_MESSAGE_PASS counters
68 * have to be enabled).
72 @RunWith(MockitoJUnitRunner.class)
73 public class ConnectionAdapterImplStatisticsTest {
75 private static final int RPC_RESPONSE_EXPIRATION = 1;
76 private static final int CHANNEL_OUTBOUND_QUEUE_SIZE = 1024;
77 private static final RemovalListener<RpcResponseKey, ResponseExpectedRpcListener<?>> REMOVAL_LISTENER =
78 notification -> notification.getValue().discard();
81 private SystemListener systemListener;
83 private ConnectionReadyListener readyListener;
85 private ChannelFuture channelFuture;
87 private OpenflowProtocolListener messageListener;
89 private SocketChannel channel;
91 private ChannelPipeline pipeline;
93 private EchoInput echoInput;
95 private BarrierInput barrierInput;
97 private EchoReplyInput echoReplyInput;
99 private ExperimenterInput experimenterInput;
101 private FlowModInput flowModInput;
103 private GetConfigInput getConfigInput;
105 private GetFeaturesInput getFeaturesInput;
107 private GetQueueConfigInput getQueueConfigInput;
109 private GroupModInput groupModInput;
111 private HelloInput helloInput;
113 private MeterModInput meterModInput;
115 private PacketOutInput packetOutInput;
117 private MultipartRequestInput multipartRequestInput;
119 private PortModInput portModInput;
121 private RoleRequestInput roleRequestInput;
123 private SetConfigInput setConfigInput;
125 private TableModInput tableModInput;
127 private GetAsyncInput getAsyncInput;
129 private SetAsyncInput setAsyncInput;
131 private ConnectionAdapterImpl adapter;
132 private Cache<RpcResponseKey, ResponseExpectedRpcListener<?>> cache;
133 private StatisticsCounters statCounters;
137 * Start counting and reset counters before each test.
140 public void setUp() {
141 mockXid(barrierInput);
143 mockXid(echoReplyInput);
144 mockXid(getConfigInput);
145 mockXid(getFeaturesInput);
146 mockXid(getQueueConfigInput);
147 mockXid(groupModInput);
148 mockXid(roleRequestInput);
149 mockXid(setConfigInput);
150 mockXid(tableModInput);
151 mockXid(getAsyncInput);
152 mockXid(setAsyncInput);
154 statCounters = StatisticsCounters.getInstance();
155 statCounters.startCounting(false, 0);
158 private static void mockXid(final OfHeader message) {
159 doReturn(Uint32.ZERO).when(message).getXid();
163 * Disconnect adapter.
164 * Stop counting after each test.
167 public void tearDown() {
168 if (adapter != null && adapter.isAlive()) {
169 adapter.disconnect();
171 statCounters.stopCounting();
175 * Test statistic counter for all rpc calls (counters DS_ENTERED_OFJAVA and DS_FLOW_MODS_ENTERED have to be
179 public void testEnterOFJavaCounter() {
180 if (!statCounters.isCounterEnabled(CounterEventTypes.DS_ENTERED_OFJAVA)) {
181 Assert.fail("Counter " + CounterEventTypes.DS_ENTERED_OFJAVA + " is not enabled");
183 if (!statCounters.isCounterEnabled(CounterEventTypes.DS_FLOW_MODS_ENTERED)) {
184 Assert.fail("Counter " + CounterEventTypes.DS_FLOW_MODS_ENTERED + " is not enabled");
186 final EmbeddedChannel embChannel = new EmbeddedChannel(new EmbededChannelHandler());
187 adapter = new ConnectionAdapterImpl(embChannel, InetSocketAddress.createUnresolved("localhost", 9876), true,
188 CHANNEL_OUTBOUND_QUEUE_SIZE);
189 cache = CacheBuilder.newBuilder().concurrencyLevel(1)
190 .expireAfterWrite(RPC_RESPONSE_EXPIRATION, TimeUnit.MINUTES).removalListener(REMOVAL_LISTENER).build();
191 adapter.setResponseCache(cache);
192 adapter.barrier(barrierInput);
193 embChannel.runPendingTasks();
194 adapter.echo(echoInput);
195 embChannel.runPendingTasks();
196 adapter.echoReply(echoReplyInput);
197 embChannel.runPendingTasks();
198 adapter.experimenter(experimenterInput);
199 embChannel.runPendingTasks();
200 adapter.flowMod(flowModInput);
201 embChannel.runPendingTasks();
202 adapter.getConfig(getConfigInput);
203 embChannel.runPendingTasks();
204 adapter.getFeatures(getFeaturesInput);
205 embChannel.runPendingTasks();
206 adapter.getQueueConfig(getQueueConfigInput);
207 embChannel.runPendingTasks();
208 adapter.groupMod(groupModInput);
209 embChannel.runPendingTasks();
210 adapter.hello(helloInput);
211 embChannel.runPendingTasks();
212 adapter.meterMod(meterModInput);
213 embChannel.runPendingTasks();
214 adapter.packetOut(packetOutInput);
215 embChannel.runPendingTasks();
216 adapter.multipartRequest(multipartRequestInput);
217 embChannel.runPendingTasks();
218 adapter.portMod(portModInput);
219 embChannel.runPendingTasks();
220 adapter.roleRequest(roleRequestInput);
221 embChannel.runPendingTasks();
222 adapter.setConfig(setConfigInput);
223 embChannel.runPendingTasks();
224 adapter.tableMod(tableModInput);
225 embChannel.runPendingTasks();
226 adapter.getAsync(getAsyncInput);
227 embChannel.runPendingTasks();
228 adapter.setAsync(setAsyncInput);
229 embChannel.runPendingTasks();
230 Assert.assertEquals("Wrong - bad counter value for ConnectionAdapterImpl rpc methods", 19,
231 statCounters.getCounter(CounterEventTypes.DS_ENTERED_OFJAVA).getCounterValue());
232 Assert.assertEquals("Wrong - bad counter value for ConnectionAdapterImpl flow-mod entered", 1,
233 statCounters.getCounter(CounterEventTypes.DS_FLOW_MODS_ENTERED).getCounterValue());
234 adapter.disconnect();
238 * Test counter for pass messages to consumer (counter US_MESSAGE_PASS has to be enabled).
241 public void testMessagePassCounter() {
242 if (!statCounters.isCounterEnabled(CounterEventTypes.US_MESSAGE_PASS)) {
243 Assert.fail("Counter " + CounterEventTypes.US_MESSAGE_PASS + " is not enabled");
245 when(channel.pipeline()).thenReturn(pipeline);
246 adapter = new ConnectionAdapterImpl(channel, InetSocketAddress.createUnresolved("10.0.0.1", 6653), true,
247 CHANNEL_OUTBOUND_QUEUE_SIZE);
248 adapter.setMessageListener(messageListener);
249 adapter.setSystemListener(systemListener);
250 adapter.setConnectionReadyListener(readyListener);
251 cache = CacheBuilder.newBuilder().concurrencyLevel(1)
252 .expireAfterWrite(RPC_RESPONSE_EXPIRATION, TimeUnit.MINUTES).removalListener(REMOVAL_LISTENER).build();
253 adapter.setResponseCache(cache);
254 when(channel.disconnect()).thenReturn(channelFuture);
255 DataObject message = new EchoRequestMessageBuilder().build();
256 adapter.consume(message);
257 message = new ErrorMessageBuilder().build();
258 adapter.consume(message);
259 message = new ExperimenterMessageBuilder().build();
260 adapter.consume(message);
261 message = new FlowRemovedMessageBuilder().build();
262 adapter.consume(message);
263 message = new HelloMessageBuilder().build();
264 adapter.consume(message);
265 message = new MultipartReplyMessageBuilder().build();
266 adapter.consume(message);
267 message = new PacketInMessageBuilder().build();
268 adapter.consume(message);
269 message = new PortStatusMessageBuilder().build();
270 adapter.consume(message);
271 message = new EchoRequestMessageBuilder().build();
272 adapter.consume(message);
273 Assert.assertEquals("Wrong - bad counter value for ConnectionAdapterImpl consume method", 9,
274 statCounters.getCounter(CounterEventTypes.US_MESSAGE_PASS).getCounterValue());
275 adapter.disconnect();
279 * Empty channel Handler for testing.
282 private static final class EmbededChannelHandler extends ChannelOutboundHandlerAdapter {
283 // no operation need to test