Ditch use of SystemNotificationsListener
[openflowplugin.git] / openflowjava / openflow-protocol-impl / src / test / java / org / opendaylight / openflowjava / protocol / impl / core / connection / ConnectionAdapterImplStatisticsTest.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 package org.opendaylight.openflowjava.protocol.impl.core.connection;
9
10 import static org.mockito.Mockito.doReturn;
11 import static org.mockito.Mockito.when;
12
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;
65
66 /**
67  * Test counters in ConnectionAdapter (at least DS_ENTERED_OFJAVA, DS_FLOW_MODS_ENTERED and US_MESSAGE_PASS counters
68  * have to be enabled).
69  *
70  * @author madamjak
71  */
72 @RunWith(MockitoJUnitRunner.class)
73 public class ConnectionAdapterImplStatisticsTest {
74
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();
79
80     @Mock
81     private SystemListener systemListener;
82     @Mock
83     private ConnectionReadyListener readyListener;
84     @Mock
85     private ChannelFuture channelFuture;
86     @Mock
87     private OpenflowProtocolListener messageListener;
88     @Mock
89     private SocketChannel channel;
90     @Mock
91     private ChannelPipeline pipeline;
92     @Mock
93     private EchoInput echoInput;
94     @Mock
95     private BarrierInput barrierInput;
96     @Mock
97     private EchoReplyInput echoReplyInput;
98     @Mock
99     private ExperimenterInput experimenterInput;
100     @Mock
101     private FlowModInput flowModInput;
102     @Mock
103     private GetConfigInput getConfigInput;
104     @Mock
105     private GetFeaturesInput getFeaturesInput;
106     @Mock
107     private GetQueueConfigInput getQueueConfigInput;
108     @Mock
109     private GroupModInput groupModInput;
110     @Mock
111     private HelloInput helloInput;
112     @Mock
113     private MeterModInput meterModInput;
114     @Mock
115     private PacketOutInput packetOutInput;
116     @Mock
117     private MultipartRequestInput multipartRequestInput;
118     @Mock
119     private PortModInput portModInput;
120     @Mock
121     private RoleRequestInput roleRequestInput;
122     @Mock
123     private SetConfigInput setConfigInput;
124     @Mock
125     private TableModInput tableModInput;
126     @Mock
127     private GetAsyncInput getAsyncInput;
128     @Mock
129     private SetAsyncInput setAsyncInput;
130
131     private ConnectionAdapterImpl adapter;
132     private Cache<RpcResponseKey, ResponseExpectedRpcListener<?>> cache;
133     private StatisticsCounters statCounters;
134
135     /**
136      * Initialize mocks.
137      * Start counting and reset counters before each test.
138      */
139     @Before
140     public void setUp() {
141         mockXid(barrierInput);
142         mockXid(echoInput);
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);
153
154         statCounters = StatisticsCounters.getInstance();
155         statCounters.startCounting(false, 0);
156     }
157
158     private static void mockXid(final OfHeader message) {
159         doReturn(Uint32.ZERO).when(message).getXid();
160     }
161
162     /**
163      * Disconnect adapter.
164      * Stop counting after each test.
165      */
166     @After
167     public void tearDown() {
168         if (adapter != null && adapter.isAlive()) {
169             adapter.disconnect();
170         }
171         statCounters.stopCounting();
172     }
173
174     /**
175      * Test statistic counter for all rpc calls (counters DS_ENTERED_OFJAVA and DS_FLOW_MODS_ENTERED have to be
176      * enabled).
177      */
178     @Test
179     public void testEnterOFJavaCounter() {
180         if (!statCounters.isCounterEnabled(CounterEventTypes.DS_ENTERED_OFJAVA)) {
181             Assert.fail("Counter " + CounterEventTypes.DS_ENTERED_OFJAVA + " is not enabled");
182         }
183         if (!statCounters.isCounterEnabled(CounterEventTypes.DS_FLOW_MODS_ENTERED)) {
184             Assert.fail("Counter " + CounterEventTypes.DS_FLOW_MODS_ENTERED + " is not enabled");
185         }
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();
235     }
236
237     /**
238      * Test counter for pass messages to consumer (counter US_MESSAGE_PASS has to be enabled).
239      */
240     @Test
241     public void testMessagePassCounter() {
242         if (!statCounters.isCounterEnabled(CounterEventTypes.US_MESSAGE_PASS)) {
243             Assert.fail("Counter " + CounterEventTypes.US_MESSAGE_PASS + " is not enabled");
244         }
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();
276     }
277
278     /**
279      * Empty channel Handler for testing.
280      * @author madamjak
281      */
282     private static final class EmbededChannelHandler extends ChannelOutboundHandlerAdapter {
283         // no operation need to test
284     }
285 }