BUG-1075: ingress back pressure
[openflowplugin.git] / openflowplugin / src / test / java / org / opendaylight / openflowplugin / openflow / md / core / session / MessageDispatchServiceImplTest.java
1 /**
2  * Copyright IBM Corporation, 2013.  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.openflowplugin.openflow.md.core.session;
9
10 import java.util.HashMap;
11 import java.util.List;
12 import java.util.Map;
13 import java.util.Map.Entry;
14 import java.util.Set;
15 import java.util.concurrent.Future;
16
17 import org.junit.Assert;
18 import org.junit.Before;
19 import org.junit.Test;
20 import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter;
21 import org.opendaylight.openflowjava.protocol.api.connection.ConnectionReadyListener;
22 import org.opendaylight.openflowplugin.openflow.md.ModelDrivenSwitch;
23 import org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductor;
24 import org.opendaylight.openflowplugin.openflow.md.core.ErrorHandler;
25 import org.opendaylight.openflowplugin.openflow.md.core.SwitchConnectionDistinguisher;
26 import org.opendaylight.openflowplugin.openflow.md.queue.QueueProcessor;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInput;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierInputBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.BarrierOutput;
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.EchoOutput;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoReplyInput;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterInput;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowModInput;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncInput;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetAsyncOutput;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigInput;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetConfigOutput;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesInput;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput;
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.GetQueueConfigOutput;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GroupModInput;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloInput;
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.MultipartRequestInput;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
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.PacketOutInput;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketOutInputBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortGrouping;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortModInput;
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.RoleRequestOutput;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetAsyncInput;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.SetConfigInput;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.TableModInput;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.system.rev130927.SystemNotificationsListener;
59 import org.opendaylight.yangtools.concepts.CompositeObjectRegistration;
60 import org.opendaylight.yangtools.yang.binding.DataObject;
61 import org.opendaylight.yangtools.yang.common.RpcResult;
62
63 /**
64  * test for {@link MessageDispatchServiceImpl}
65  */
66 public class MessageDispatchServiceImplTest {
67
68     MockSessionContext session;
69
70     /**
71      * @throws java.lang.Exception
72      */
73     @Before
74     public void setUp() throws Exception {
75         session = new MockSessionContext(0);
76
77     }
78
79     /**
80      * Test barrier message for null cookie
81      *
82      * @throws Exception
83      */
84     @Test
85     public void testBarrierMessageForPrimary() throws Exception {
86         MockConnectionConductor conductor = new MockConnectionConductor(1);
87         SwitchConnectionDistinguisher cookie = conductor.getAuxiliaryKey();       
88         BarrierInputBuilder barrierMsg = new BarrierInputBuilder();
89         session.getMessageDispatchService().barrier(barrierMsg.build(), cookie);
90         Assert.assertEquals(MessageType.BARRIER, session.getPrimaryConductor().getMessageType());
91     }
92
93     /**
94      * Test packet out message for primary connection
95      *
96      * @throws Exception
97      */
98     @Test
99     public void testPacketOutMessageForPrimary() throws Exception {
100         session.getMessageDispatchService().packetOut(null, null);
101         Assert.assertEquals(MessageType.PACKETOUT, session.getPrimaryConductor().getMessageType());
102     }
103
104     /**
105      * Test packet out message for auxiliary connection
106      *
107      * @throws Exception
108      */
109     @Test
110     public void testPacketOutMessageForAuxiliary() throws Exception {
111         MockConnectionConductor conductor = new MockConnectionConductor(1);
112         SwitchConnectionDistinguisher cookie = conductor.getAuxiliaryKey();
113         session.addAuxiliaryConductor(cookie, conductor);
114         session.getMessageDispatchService().packetOut(null, cookie);
115         Assert.assertEquals(MessageType.NONE, session.getPrimaryConductor().getMessageType());
116         conductor = (MockConnectionConductor) session.getAuxiliaryConductor(cookie);
117         Assert.assertEquals(MessageType.PACKETOUT, conductor.getMessageType());
118     }
119
120     /**
121      * Test packet out message when multiple auxiliary connection exist
122      *
123      * @throws Exception
124      */
125     @Test
126     public void testPacketOutMessageForMultipleAuxiliary() throws Exception {
127         MockConnectionConductor conductor1 = new MockConnectionConductor(1);
128         SwitchConnectionDistinguisher cookie1 = conductor1.getAuxiliaryKey();
129         session.addAuxiliaryConductor(cookie1, conductor1);
130         MockConnectionConductor conductor2 = new MockConnectionConductor(2);
131         SwitchConnectionDistinguisher cookie2 = conductor2.getAuxiliaryKey();
132         session.addAuxiliaryConductor(cookie2, conductor2);
133         MockConnectionConductor conductor3 = new MockConnectionConductor(3);
134         SwitchConnectionDistinguisher cookie3 = conductor3.getAuxiliaryKey();
135         session.addAuxiliaryConductor(cookie3, conductor3);
136         PacketOutInputBuilder builder = new PacketOutInputBuilder();
137         // send message
138         session.getMessageDispatchService().packetOut(builder.build(), cookie2);
139
140         Assert.assertEquals(MessageType.NONE, session.getPrimaryConductor().getMessageType());
141
142         conductor3 = (MockConnectionConductor) session.getAuxiliaryConductor(cookie3);
143         Assert.assertEquals(MessageType.NONE, conductor3.getMessageType());
144
145         conductor2 = (MockConnectionConductor) session.getAuxiliaryConductor(cookie2);
146         Assert.assertEquals(MessageType.PACKETOUT, conductor2.getMessageType());
147
148         conductor1 = (MockConnectionConductor) session.getAuxiliaryConductor(cookie1);
149         Assert.assertEquals(MessageType.NONE, conductor1.getMessageType());
150
151     }
152
153     /**
154      * Test for invalid session
155      *
156      * @throws Exception
157      */
158     @Test
159     public void testInvalidSession() throws Exception {
160         session.setValid(false);
161         try {
162             session.getMessageDispatchService().packetOut(null, null);
163             Assert.assertTrue(false);
164         } catch (IllegalArgumentException ex) {
165             Assert.assertTrue(true);
166         }
167     }
168
169 }
170
171 class MockSessionContext implements SessionContext {
172     private MockConnectionConductor conductor;
173     private Map<SwitchConnectionDistinguisher, ConnectionConductor> map;
174     private IMessageDispatchService messageService;
175     private boolean isValid = true;
176     private CompositeObjectRegistration<ModelDrivenSwitch> registration;
177     private int seed;
178
179     MockSessionContext(int conductorNum) {
180         conductor = new MockConnectionConductor(conductorNum);
181         map = new HashMap<SwitchConnectionDistinguisher, ConnectionConductor>();
182         messageService = new MessageDispatchServiceImpl(this);
183     }
184
185     @Override
186     public MockConnectionConductor getPrimaryConductor() {
187         // TODO Auto-generated method stub
188         return conductor;
189     }
190
191     @Override
192     public GetFeaturesOutput getFeatures() {
193         // TODO Auto-generated method stub
194         return null;
195     }
196
197     @Override
198     public ConnectionConductor getAuxiliaryConductor(SwitchConnectionDistinguisher auxiliaryKey) {
199
200         return map.get(auxiliaryKey);
201     }
202
203     @Override
204     public Set<Entry<SwitchConnectionDistinguisher, ConnectionConductor>> getAuxiliaryConductors() {
205         // TODO Auto-generated method stub
206         return null;
207     }
208
209     @Override
210     public void addAuxiliaryConductor(SwitchConnectionDistinguisher auxiliaryKey, ConnectionConductor conductorArg) {
211         map.put(auxiliaryKey, conductorArg);
212     }
213
214     @Override
215     public ConnectionConductor removeAuxiliaryConductor(SwitchConnectionDistinguisher connectionCookie) {
216         return map.remove(connectionCookie);
217     }
218
219     @Override
220     public boolean isValid() {
221         // TODO Auto-generated method stub
222         return isValid;
223     }
224
225     @Override
226     public void setValid(boolean valid) {
227         isValid = valid;
228     }
229
230     @Override
231     public SwitchSessionKeyOF getSessionKey() {
232         // TODO Auto-generated method stub
233         return null;
234     }
235     
236     @Override
237     public IMessageDispatchService getMessageDispatchService() {
238         // TODO Auto-generated method stub
239         return messageService;
240     }
241
242     @Override
243     public Long getNextXid() {
244         // TODO Auto-generated method stub
245         return null;
246     }
247
248     @Override
249     public Map<Long, PortGrouping> getPhysicalPorts() {
250         // TODO Auto-generated method stub
251         return null;
252     }
253
254     @Override
255     public Set<Long> getPorts() {
256         // TODO Auto-generated method stub
257         return null;
258     }
259
260     @Override
261     public PortGrouping getPhysicalPort(Long portNumber) {
262         // TODO Auto-generated method stub
263         return null;
264     }
265
266     @Override
267     public Boolean getPortBandwidth(Long portNumber) {
268         // TODO Auto-generated method stub
269         return null;
270     }
271
272     @Override
273     public boolean isPortEnabled(long portNumber) {
274         // TODO Auto-generated method stub
275         return false;
276     }
277
278     @Override
279     public boolean isPortEnabled(PortGrouping port) {
280         // TODO Auto-generated method stub
281         return false;
282     }
283
284     @Override
285     public List<PortGrouping> getEnabledPorts() {
286         // TODO Auto-generated method stub
287         return null;
288     }
289
290     @Override
291     public Map<Long, Boolean> getPortsBandwidth() {
292         // TODO Auto-generated method stub
293         return null;
294     }
295
296     @Override
297     public CompositeObjectRegistration<ModelDrivenSwitch> getProviderRegistration() {
298         return registration;
299     }
300
301     @Override
302     public void setProviderRegistration(
303             CompositeObjectRegistration<ModelDrivenSwitch> registration) {
304         this.registration = registration;
305     }
306
307     @Override
308     public int getSeed() {
309         return seed;
310     }
311     
312     /**
313      * @param seed the seed to set
314      */
315     public void setSeed(int seed) {
316         this.seed = seed;
317     }
318 }
319
320 class MockConnectionConductor implements ConnectionConductor {
321
322     private int conductorNum;
323     private MockConnectionAdapter adapter;
324
325     public MockConnectionConductor(int conductorNumber) {
326         conductorNum = conductorNumber;
327         adapter = new MockConnectionAdapter();
328     }
329
330     @Override
331     public void init() {
332         // TODO Auto-generated method stub
333
334     }
335
336     @Override
337     public Short getVersion() {
338         // TODO Auto-generated method stub
339         return null;
340     }
341
342     @Override
343     public CONDUCTOR_STATE getConductorState() {
344         // TODO Auto-generated method stub
345         return null;
346     }
347
348     @Override
349     public void setConductorState(CONDUCTOR_STATE conductorState) {
350         // TODO Auto-generated method stub
351
352     }
353
354     @Override
355     public Future<Boolean> disconnect() {
356         // TODO Auto-generated method stub
357         return null;
358     }
359
360     @Override
361     public void setSessionContext(SessionContext context) {
362         // TODO Auto-generated method stub
363
364     }
365
366     @Override
367     public void setConnectionCookie(SwitchConnectionDistinguisher auxiliaryKey) {
368         // TODO Auto-generated method stub
369
370     }
371
372     @Override
373     public SessionContext getSessionContext() {
374         // TODO Auto-generated method stub
375         return null;
376     }
377
378     @Override
379     public SwitchConnectionDistinguisher getAuxiliaryKey() {
380         if (0 != conductorNum) {
381             SwitchConnectionCookieOFImpl key = new SwitchConnectionCookieOFImpl();
382             key.setAuxiliaryId((short) conductorNum);
383             key.init(42);
384             return key;
385         }
386         return null;
387     }
388
389     @Override
390     public ConnectionAdapter getConnectionAdapter() {
391         // TODO Auto-generated method stub
392         return adapter;
393     }
394
395     public MessageType getMessageType() {
396         return adapter.getMessageType();
397     }
398
399     @Override
400     public void setQueueProcessor(QueueProcessor<OfHeader, DataObject> queueKeeper) {
401         // NOOP
402     }
403
404     @Override
405     public void setErrorHandler(ErrorHandler errorHandler) {
406         // NOOP
407     }
408
409     @Override
410     public void setId(int conductorId) {
411         // NOOP
412     }
413 }
414
415 enum MessageType {
416     NONE, BARRIER, FLOWMOD, TABLEMOD, PACKETOUT;
417 }
418
419 class MockConnectionAdapter implements ConnectionAdapter {
420
421     private MessageType messageType;
422     private ConnectionReadyListener connectionReadyListener;
423
424     public MockConnectionAdapter() {
425         setMessageType(MessageType.NONE);
426     }
427
428     @Override
429     public Future<RpcResult<BarrierOutput>> barrier(BarrierInput input) {
430         setMessageType(MessageType.BARRIER);
431         return null;
432     }
433
434     @Override
435     public Future<RpcResult<EchoOutput>> echo(EchoInput input) {
436         // TODO Auto-generated method stub
437         return null;
438     }
439
440     @Override
441     public Future<RpcResult<Void>> echoReply(EchoReplyInput input) {
442         // TODO Auto-generated method stub
443         return null;
444     }
445
446     @Override
447     public Future<RpcResult<Void>> experimenter(ExperimenterInput input) {
448         // TODO Auto-generated method stub
449         return null;
450     }
451
452     @Override
453     public Future<RpcResult<Void>> flowMod(FlowModInput input) {
454         setMessageType(MessageType.FLOWMOD);
455         return null;
456     }
457
458     @Override
459     public Future<RpcResult<GetAsyncOutput>> getAsync(GetAsyncInput input) {
460         // TODO Auto-generated method stub
461         return null;
462     }
463
464     @Override
465     public Future<RpcResult<GetConfigOutput>> getConfig(GetConfigInput input) {
466         // TODO Auto-generated method stub
467         return null;
468     }
469
470     @Override
471     public Future<RpcResult<GetFeaturesOutput>> getFeatures(GetFeaturesInput input) {
472         // TODO Auto-generated method stub
473         return null;
474     }
475
476     @Override
477     public Future<RpcResult<GetQueueConfigOutput>> getQueueConfig(GetQueueConfigInput input) {
478         // TODO Auto-generated method stub
479         return null;
480     }
481
482     @Override
483     public Future<RpcResult<Void>> groupMod(GroupModInput input) {
484         // TODO Auto-generated method stub
485         return null;
486     }
487
488     @Override
489     public Future<RpcResult<Void>> hello(HelloInput input) {
490         // TODO Auto-generated method stub
491         return null;
492     }
493
494     @Override
495     public Future<RpcResult<Void>> meterMod(MeterModInput input) {
496         // TODO Auto-generated method stub
497         return null;
498     }
499
500     @Override
501     public Future<RpcResult<Void>> packetOut(PacketOutInput input) {
502         setMessageType(MessageType.PACKETOUT);
503         return null;
504     }
505
506     @Override
507     public Future<RpcResult<Void>> portMod(PortModInput input) {
508         // TODO Auto-generated method stub
509         return null;
510     }
511
512     @Override
513     public Future<RpcResult<RoleRequestOutput>> roleRequest(RoleRequestInput input) {
514         // TODO Auto-generated method stub
515         return null;
516     }
517
518     @Override
519     public Future<RpcResult<Void>> setAsync(SetAsyncInput input) {
520         // TODO Auto-generated method stub
521         return null;
522     }
523
524     @Override
525     public Future<RpcResult<Void>> setConfig(SetConfigInput input) {
526         // TODO Auto-generated method stub
527         return null;
528     }
529
530     @Override
531     public Future<RpcResult<Void>> tableMod(TableModInput input) {
532         setMessageType(MessageType.TABLEMOD);
533         return null;
534     }
535
536     @Override
537     public Future<Boolean> disconnect() {
538         // TODO Auto-generated method stub
539         return null;
540     }
541
542     @Override
543     public boolean isAlive() {
544         // TODO Auto-generated method stub
545         return false;
546     }
547
548     @Override
549     public void setMessageListener(OpenflowProtocolListener messageListener) {
550         // TODO Auto-generated method stub
551
552     }
553
554     @Override
555     public void setSystemListener(SystemNotificationsListener systemListener) {
556         // TODO Auto-generated method stub
557
558     }
559
560     @Override
561     public void checkListeners() {
562         // TODO Auto-generated method stub
563
564     }
565
566     /**
567      * @return the messageType
568      */
569     public MessageType getMessageType() {
570         return messageType;
571     }
572
573     /**
574      * @param messageType
575      *            the messageType to set
576      */
577     public void setMessageType(MessageType messageType) {
578         this.messageType = messageType;
579     }
580
581     @Override
582     public void fireConnectionReadyNotification() {
583             connectionReadyListener.onConnectionReady();
584     }
585
586     @Override
587     public void setConnectionReadyListener(
588             ConnectionReadyListener connectionReadyListener) {
589         this.connectionReadyListener = connectionReadyListener;
590     }
591
592     @Override
593     public Future<RpcResult<Void>> multipartRequest(
594             MultipartRequestInput input) {
595         // TODO Auto-generated method stub
596         return null;
597     }
598 }