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