JConsole support for statistics collection
[openflowjava.git] / 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.when;
11 import io.netty.channel.ChannelFuture;
12 import io.netty.channel.ChannelOutboundHandlerAdapter;
13 import io.netty.channel.ChannelPipeline;
14 import io.netty.channel.embedded.EmbeddedChannel;
15 import io.netty.channel.socket.SocketChannel;
16
17 import java.net.InetSocketAddress;
18 import java.util.concurrent.TimeUnit;
19
20 import org.junit.After;
21 import org.junit.Assert;
22 import org.junit.Before;
23 import org.junit.Test;
24 import org.mockito.Mock;
25 import org.mockito.MockitoAnnotations;
26 import org.opendaylight.openflowjava.protocol.api.connection.ConnectionReadyListener;
27 import org.opendaylight.openflowjava.statistics.CounterEventTypes;
28 import org.opendaylight.openflowjava.statistics.StatisticsCounters;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInput;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoInput;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoReplyInput;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessageBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessageBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterInput;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterMessageBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInput;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessageBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncInput;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigInput;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesInput;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetQueueConfigInput;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GroupModInput;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloInput;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloMessageBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MeterModInput;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessageBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestInput;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OpenflowProtocolListener;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessageBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInput;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInput;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessageBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.RoleRequestInput;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetAsyncInput;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetConfigInput;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.TableModInput;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.SystemNotificationsListener;
58 import org.opendaylight.yangtools.yang.binding.DataObject;
59
60 import com.google.common.cache.Cache;
61 import com.google.common.cache.CacheBuilder;
62 import com.google.common.cache.RemovalListener;
63 import com.google.common.cache.RemovalNotification;
64
65 /**
66  * Test counters in ConnectionAdapter (at least DS_ENTERED_OFJAVA, DS_FLOW_MODS_ENTERED and US_MESSAGE_PASS counters have to be enabled)
67  * @author madamjak
68  *
69  */
70 public class ConnectionAdapterImplStatisticsTest {
71
72     private static final int RPC_RESPONSE_EXPIRATION = 1;
73     private static final RemovalListener<RpcResponseKey, ResponseExpectedRpcListener<?>> REMOVAL_LISTENER =
74             new RemovalListener<RpcResponseKey, ResponseExpectedRpcListener<?>>() {
75         @Override
76         public void onRemoval(
77                 final RemovalNotification<RpcResponseKey, ResponseExpectedRpcListener<?>> notification) {
78             notification.getValue().discard();
79         }
80     };
81
82     @Mock SystemNotificationsListener systemListener;
83     @Mock ConnectionReadyListener readyListener;
84     @Mock ChannelFuture channelFuture;
85     @Mock OpenflowProtocolListener messageListener;
86     @Mock SocketChannel channel;
87     @Mock ChannelPipeline pipeline;
88     @Mock EchoInput echoInput;
89     @Mock BarrierInput barrierInput;
90     @Mock EchoReplyInput echoReplyInput;
91     @Mock ExperimenterInput experimenterInput;
92     @Mock FlowModInput flowModInput;
93     @Mock GetConfigInput getConfigInput;
94     @Mock GetFeaturesInput getFeaturesInput;
95     @Mock GetQueueConfigInput getQueueConfigInput;
96     @Mock GroupModInput groupModInput;
97     @Mock HelloInput helloInput;
98     @Mock MeterModInput meterModInput;
99     @Mock PacketOutInput packetOutInput;
100     @Mock MultipartRequestInput multipartRequestInput;
101     @Mock PortModInput portModInput;
102     @Mock RoleRequestInput roleRequestInput;
103     @Mock SetConfigInput setConfigInput;
104     @Mock TableModInput tableModInput;
105     @Mock GetAsyncInput getAsyncInput;
106     @Mock SetAsyncInput setAsyncInput;
107
108     private ConnectionAdapterImpl adapter;
109     private Cache<RpcResponseKey, ResponseExpectedRpcListener<?>> cache;
110     private StatisticsCounters statCounters;
111
112     /**
113      * Initialize mocks
114      * Start counting and reset counters before each test
115      */
116     @Before
117     public void setUp() {
118         MockitoAnnotations.initMocks(this);
119         statCounters = StatisticsCounters.getInstance();
120         statCounters.startCounting(false, 0);
121     }
122
123     /**
124      * Disconnect adapter
125      * Stop counting after each test
126      */
127     @After
128     public void tierDown(){
129         if (adapter != null && adapter.isAlive()) {
130             adapter.disconnect();
131         }
132         statCounters.stopCounting();
133     }
134
135     /**
136      * Test statistic counter for all rpc calls (counters DS_ENTERED_OFJAVA and DS_FLOW_MODS_ENTERED have to be enabled)
137      */
138     @Test
139     public void testEnterOFJavaCounter() {
140         if(!statCounters.isCounterEnabled(CounterEventTypes.DS_ENTERED_OFJAVA)){
141             Assert.fail("Counter " + CounterEventTypes.DS_ENTERED_OFJAVA + " is not enabled");
142         }
143         if(!statCounters.isCounterEnabled(CounterEventTypes.DS_FLOW_MODS_ENTERED)){
144             Assert.fail("Counter " + CounterEventTypes.DS_FLOW_MODS_ENTERED + " is not enabled");
145         }
146         EmbeddedChannel embChannel = new EmbeddedChannel(new EmbededChannelHandler());
147         adapter = new ConnectionAdapterImpl(embChannel,InetSocketAddress.createUnresolved("localhost", 9876));
148         cache = CacheBuilder.newBuilder().concurrencyLevel(1).expireAfterWrite(RPC_RESPONSE_EXPIRATION, TimeUnit.MINUTES)
149                 .removalListener(REMOVAL_LISTENER).build();
150         adapter.setResponseCache(cache);
151         adapter.barrier(barrierInput);
152         embChannel.runPendingTasks();
153         adapter.echo(echoInput);
154         embChannel.runPendingTasks();
155         adapter.echoReply(echoReplyInput);
156         embChannel.runPendingTasks();
157         adapter.experimenter(experimenterInput);
158         embChannel.runPendingTasks();
159         adapter.flowMod(flowModInput);
160         embChannel.runPendingTasks();
161         adapter.getConfig(getConfigInput);
162         embChannel.runPendingTasks();
163         adapter.getFeatures(getFeaturesInput);
164         embChannel.runPendingTasks();
165         adapter.getQueueConfig(getQueueConfigInput);
166         embChannel.runPendingTasks();
167         adapter.groupMod(groupModInput);
168         embChannel.runPendingTasks();
169         adapter.hello(helloInput);
170         embChannel.runPendingTasks();
171         adapter.meterMod(meterModInput);
172         embChannel.runPendingTasks();
173         adapter.packetOut(packetOutInput);
174         embChannel.runPendingTasks();
175         adapter.multipartRequest(multipartRequestInput);
176         embChannel.runPendingTasks();
177         adapter.portMod(portModInput);
178         embChannel.runPendingTasks();
179         adapter.roleRequest(roleRequestInput);
180         embChannel.runPendingTasks();
181         adapter.setConfig(setConfigInput);
182         embChannel.runPendingTasks();
183         adapter.tableMod(tableModInput);
184         embChannel.runPendingTasks();
185         adapter.getAsync(getAsyncInput);
186         embChannel.runPendingTasks();
187         adapter.setAsync(setAsyncInput);
188         embChannel.runPendingTasks();
189         Assert.assertEquals("Wrong - bad counter value for ConnectionAdapterImpl rpc methods", 19, statCounters.getCounter(CounterEventTypes.DS_ENTERED_OFJAVA).getCounterValue());
190         Assert.assertEquals("Wrong - bad counter value for ConnectionAdapterImpl flow-mod entered", 1, statCounters.getCounter(CounterEventTypes.DS_FLOW_MODS_ENTERED).getCounterValue());
191         adapter.disconnect();
192     }
193
194     /**
195      * Test counter for pass messages to consumer (counter US_MESSAGE_PASS has to be enabled)
196      */
197     @Test
198     public void testMessagePassCounter() {
199         if(!statCounters.isCounterEnabled(CounterEventTypes.US_MESSAGE_PASS)){
200             Assert.fail("Counter " + CounterEventTypes.US_MESSAGE_PASS + " is not enabled");
201         }
202         when(channel.pipeline()).thenReturn(pipeline);
203         adapter = new ConnectionAdapterImpl(channel, InetSocketAddress.createUnresolved("10.0.0.1", 6653));
204         adapter.setMessageListener(messageListener);
205         adapter.setSystemListener(systemListener);
206         adapter.setConnectionReadyListener(readyListener);
207         cache = CacheBuilder.newBuilder().concurrencyLevel(1).expireAfterWrite(RPC_RESPONSE_EXPIRATION, TimeUnit.MINUTES)
208                 .removalListener(REMOVAL_LISTENER).build();
209         adapter.setResponseCache(cache);
210         when(channel.disconnect()).thenReturn(channelFuture);
211         DataObject message = new EchoRequestMessageBuilder().build();
212         adapter.consume(message);
213         message = new ErrorMessageBuilder().build();
214         adapter.consume(message);
215         message = new ExperimenterMessageBuilder().build();
216         adapter.consume(message);
217         message = new FlowRemovedMessageBuilder().build();
218         adapter.consume(message);
219         message = new HelloMessageBuilder().build();
220         adapter.consume(message);
221         message = new MultipartReplyMessageBuilder().build();
222         adapter.consume(message);
223         message = new PacketInMessageBuilder().build();
224         adapter.consume(message);
225         message = new PortStatusMessageBuilder().build();
226         adapter.consume(message);
227         message = new EchoRequestMessageBuilder().build();
228         adapter.consume(message);
229         Assert.assertEquals("Wrong - bad counter value for ConnectionAdapterImpl consume method", 9, statCounters.getCounter(CounterEventTypes.US_MESSAGE_PASS).getCounterValue());
230         adapter.disconnect();
231     }
232
233     /**
234      * Empty channel Handler for testing
235      * @author madamjak
236      *
237      */
238     private class EmbededChannelHandler extends ChannelOutboundHandlerAdapter {
239         // no operation need to test
240     }
241 }