2 * Copyright (c) 2013 Cisco Systems, Inc. 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
9 package org.opendaylight.openflowplugin.openflow.md.core;
11 import java.math.BigInteger;
12 import java.util.ArrayList;
13 import java.util.Collection;
14 import java.util.HashMap;
15 import java.util.List;
17 import java.util.Stack;
18 import java.util.concurrent.ScheduledThreadPoolExecutor;
19 import java.util.concurrent.TimeUnit;
21 import org.junit.After;
22 import org.junit.Assert;
23 import org.junit.Before;
24 import org.junit.Test;
25 import org.junit.runner.RunWith;
26 import org.mockito.ArgumentCaptor;
27 import org.mockito.Matchers;
28 import org.mockito.Mock;
29 import org.mockito.Mockito;
30 import org.mockito.runners.MockitoJUnitRunner;
31 import org.opendaylight.openflowplugin.openflow.md.OFConstants;
32 import org.opendaylight.openflowplugin.openflow.md.core.plan.ConnectionAdapterStackImpl;
33 import org.opendaylight.openflowplugin.openflow.md.core.plan.EventFactory;
34 import org.opendaylight.openflowplugin.openflow.md.core.plan.SwitchTestEvent;
35 import org.opendaylight.openflowplugin.openflow.md.core.session.SessionContext;
36 import org.opendaylight.openflowplugin.openflow.md.queue.PopListener;
37 import org.opendaylight.openflowplugin.openflow.md.queue.QueueKeeperLightImpl;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Capabilities;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ErrorType;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeatures;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeaturesV10;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortReason;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessageBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessage;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessageBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterInputBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterMessage;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterMessageBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessage;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessageBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutputBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloMessageBuilder;
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.PacketInMessage;
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.PortStatusMessage;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessageBuilder;
58 import org.opendaylight.yangtools.yang.binding.DataObject;
59 import org.slf4j.Logger;
60 import org.slf4j.LoggerFactory;
62 @RunWith(MockitoJUnitRunner.class)
63 public class ConnectionConductorImplTest {
65 protected static final Logger LOG = LoggerFactory
66 .getLogger(ConnectionConductorImplTest.class);
69 private final int maxProcessingTimeout = 500;
71 protected ConnectionAdapterStackImpl adapter;
72 private ConnectionConductorImpl connectionConductor;
73 private MDController controller;
74 private Stack<SwitchTestEvent> eventPlan;
76 private Thread libSimulation;
77 private ScheduledThreadPoolExecutor pool = new ScheduledThreadPoolExecutor(
80 private QueueKeeperLightImpl queueKeeper;
82 private PopListener<DataObject> popListener;
84 private int experimenterMessageCounter;
85 private int packetinMessageCounter;
86 private int flowremovedMessageCounter;
87 private int portstatusAddMessageCounter;
88 private int portstatusDeleteMessageCounter;
89 private int portstatusModifyMessageCounter;
90 private int errorMessageCounter;
93 private ErrorHandlerSimpleImpl errorHandler;
95 private int expectedErrors = 0;
97 public void incrExperimenterMessageCounter() {
98 this.experimenterMessageCounter++;
101 public void incrPacketinMessageCounter() {
102 this.packetinMessageCounter++;
105 public void incrFlowremovedMessageCounter() {
106 this.flowremovedMessageCounter++;
109 public void incrPortstatusAddMessageCounter() {
110 this.portstatusAddMessageCounter++;
113 public void incrPortstatusDeleteMessageCounter() {
114 this.portstatusDeleteMessageCounter++;
117 public void incrPortstatusModifyMessageCounter() {
118 this.portstatusModifyMessageCounter++;
121 public void incrErrorMessageCounter() {
122 this.errorMessageCounter++;
127 * @throws java.lang.Exception
130 public void setUp() throws Exception {
131 adapter = new ConnectionAdapterStackImpl();
133 popListener = new PopListenerCountingImpl<>();
135 queueKeeper = new QueueKeeperLightImpl();
137 connectionConductor = new ConnectionConductorImpl(adapter);
138 connectionConductor.setQueueKeeper(queueKeeper);
139 connectionConductor.init();
140 connectionConductor.setErrorHandler(errorHandler);
141 controller = new MDController();
143 queueKeeper.setTranslatorMapping(controller.getMessageTranslators());
144 eventPlan = new Stack<>();
145 adapter.setEventPlan(eventPlan);
146 adapter.setProceedTimeout(5000L);
147 adapter.checkListeners();
149 controller.getMessageTranslators().putAll(assembleTranslatorMapping());
150 queueKeeper.setPopListenersMapping(assemblePopListenerMapping());
157 private Map<Class<? extends DataObject>, Collection<PopListener<DataObject>>> assemblePopListenerMapping() {
158 Map<Class<? extends DataObject>, Collection<PopListener<DataObject>>> mapping = new HashMap<>();
159 Collection<PopListener<DataObject>> popListenerBag = new ArrayList<>();
160 popListenerBag.add(popListener);
161 //TODO: add testing registered types
162 mapping.put(DataObject.class, popListenerBag);
167 * @throws java.lang.Exception
170 public void tearDown() throws Exception {
171 if (libSimulation != null) {
172 libSimulation.join();
174 queueKeeper.shutdown();
175 connectionConductor.shutdownPool();
177 for (Exception problem : adapter.getOccuredExceptions()) {
178 LOG.error("during simulation on adapter side: "
179 + problem.getMessage());
181 Assert.assertEquals(0, adapter.getOccuredExceptions().size());
183 if (LOG.isDebugEnabled()) {
184 if (eventPlan.size() > 0) {
185 LOG.debug("eventPlan size: " + eventPlan.size());
186 for (SwitchTestEvent event : eventPlan) {
187 LOG.debug(" # EVENT:: " + event.toString());
191 Assert.assertTrue("plan is not finished", eventPlan.isEmpty());
195 // logging errors if occurred
196 ArgumentCaptor<Throwable> errorCaptor = ArgumentCaptor.forClass(Throwable.class);
197 Mockito.verify(errorHandler, Mockito.atMost(1)).handleException(
198 errorCaptor.capture(), Matchers.any(SessionContext.class));
199 for (Throwable problem : errorCaptor.getAllValues()) {
200 LOG.warn(problem.getMessage(), problem);
203 Mockito.verify(errorHandler, Mockito.times(expectedErrors )).handleException(
204 Matchers.any(Throwable.class), Matchers.any(SessionContext.class));
209 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onEchoRequestMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessage)}
214 public void testOnEchoRequestMessage() throws Exception {
215 simulateV13PostHandshakeState(connectionConductor);
217 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
218 EventFactory.DEFAULT_VERSION, new EchoRequestMessageBuilder()));
220 EventFactory.createDefaultWaitForRpcEvent(42, "echoReply"));
225 * Test of handshake, covering version negotiation and features.
226 * Switch delivers first helloMessage with default version.
230 public void testHandshake1() throws Exception {
231 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
232 EventFactory.DEFAULT_VERSION, new HelloMessageBuilder()));
233 eventPlan.add(0, EventFactory.createDefaultWaitForAllEvent(
234 EventFactory.createDefaultWaitForRpcEvent(43, "helloReply"),
235 EventFactory.createDefaultWaitForRpcEvent(44, "getFeatures")));
236 eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(44,
237 EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
239 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(1, "multipartRequestInput"));
240 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(2, "multipartRequestInput"));
241 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(3, "multipartRequestInput"));
242 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(4, "multipartRequestInput"));
245 Assert.assertEquals(ConnectionConductor.CONDUCTOR_STATE.WORKING,
246 connectionConductor.getConductorState());
247 Assert.assertEquals((short) 0x04, connectionConductor.getVersion()
252 * Test of handshake, covering version negotiation and features.
253 * Controller sends first helloMessage with default version
257 public void testHandshake1SwitchStarts() throws Exception {
258 eventPlan.add(0, EventFactory.createConnectionReadyCallback(connectionConductor));
259 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(21, "helloReply"));
260 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
261 EventFactory.DEFAULT_VERSION, new HelloMessageBuilder()));
262 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(43, "getFeatures"));
263 eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(43,
264 EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
266 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(1, "multipartRequestInput"));
267 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(2, "multipartRequestInput"));
268 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(3, "multipartRequestInput"));
269 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(4, "multipartRequestInput"));
273 Assert.assertEquals(ConnectionConductor.CONDUCTOR_STATE.WORKING,
274 connectionConductor.getConductorState());
275 Assert.assertEquals((short) 0x04, connectionConductor.getVersion()
280 * Test of handshake, covering version negotiation and features.
281 * Switch delivers first helloMessage with version 0x05
282 * and negotiates following versions: 0x03, 0x01
286 public void testHandshake2() throws Exception {
287 connectionConductor.setBitmapNegotiationEnable(false);
288 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
289 (short) 0x05, new HelloMessageBuilder()));
291 EventFactory.createDefaultWaitForRpcEvent(43, "helloReply"));
292 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(43L,
293 (short) 0x03, new HelloMessageBuilder()));
295 EventFactory.createDefaultWaitForRpcEvent(44, "helloReply"));
296 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(44L,
297 (short) 0x01, new HelloMessageBuilder()));
299 EventFactory.createDefaultWaitForRpcEvent(45, "getFeatures"));
301 eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(45,
302 EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
304 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(1, "multipartRequestInput"));
305 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(2, "multipartRequestInput"));
309 Assert.assertEquals(ConnectionConductor.CONDUCTOR_STATE.WORKING,
310 connectionConductor.getConductorState());
311 Assert.assertEquals((short) 0x01, connectionConductor.getVersion()
316 * Test of handshake, covering version negotiation and features.
317 * Controller sends first helloMessage with default version
318 * and switch negotiates following versions: 0x05, 0x03, 0x01
322 public void testHandshake2SwitchStarts() throws Exception {
323 connectionConductor.setBitmapNegotiationEnable(false);
324 eventPlan.add(0, EventFactory.createConnectionReadyCallback(connectionConductor));
326 EventFactory.createDefaultWaitForRpcEvent(21, "helloReply"));
327 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
328 (short) 0x05, new HelloMessageBuilder()));
329 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(43L,
330 (short) 0x03, new HelloMessageBuilder()));
332 EventFactory.createDefaultWaitForRpcEvent(44, "helloReply"));
333 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(44L,
334 (short) 0x01, new HelloMessageBuilder()));
336 EventFactory.createDefaultWaitForRpcEvent(45, "getFeatures"));
338 eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(45,
339 EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
341 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(1, "multipartRequestInput"));
342 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(2, "multipartRequestInput"));
346 Assert.assertEquals(ConnectionConductor.CONDUCTOR_STATE.WORKING,
347 connectionConductor.getConductorState());
348 Assert.assertEquals((short) 0x01, connectionConductor.getVersion()
354 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onExperimenterMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterMessage)}
356 * @throws InterruptedException
359 public void testOnExperimenterMessage1() throws InterruptedException {
360 simulateV13PostHandshakeState(connectionConductor);
363 EventFactory.createDefaultWaitForRpcEvent(42, "experimenter"));
364 ExperimenterMessageBuilder builder1 = new ExperimenterMessageBuilder();
365 builder1.setExperimenter(84L).setExpType(4L);
366 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
367 EventFactory.DEFAULT_VERSION, builder1));
371 Runnable sendExperimenterCmd = new Runnable() {
375 ExperimenterInputBuilder builder2 = new ExperimenterInputBuilder();
376 builder2.setExperimenter(84L).setExpType(4L);
377 EventFactory.setupHeader(42L, builder2);
378 adapter.experimenter(builder2.build());
381 pool.schedule(sendExperimenterCmd,
382 ConnectionAdapterStackImpl.JOB_DELAY, TimeUnit.MILLISECONDS);
387 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onExperimenterMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterMessage)}
389 * @throws InterruptedException
392 public void testOnExperimenterMessage2() throws InterruptedException {
393 simulateV13PostHandshakeState(connectionConductor);
396 EventFactory.createDefaultWaitForRpcEvent(42, "experimenter"));
397 ErrorMessageBuilder builder1 = new ErrorMessageBuilder();
398 builder1.setType(ErrorType.BADREQUEST.getIntValue()).setCode(3)
399 .setData(new byte[] { 1, 2, 3 });
401 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
402 EventFactory.DEFAULT_VERSION, builder1));
406 Runnable sendExperimenterCmd = new Runnable() {
410 ExperimenterInputBuilder builder2 = new ExperimenterInputBuilder();
411 builder2.setExperimenter(84L).setExpType(4L);
412 EventFactory.setupHeader(42L, builder2);
413 adapter.experimenter(builder2.build());
416 pool.schedule(sendExperimenterCmd,
417 ConnectionAdapterStackImpl.JOB_DELAY, TimeUnit.MILLISECONDS);
422 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onFlowRemovedMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessage)}
424 * @throws InterruptedException
427 public void testOnFlowRemovedMessage() throws InterruptedException {
428 IMDMessageTranslator<OfHeader, List<DataObject>> objFms = new FlowRemovedMessageService() ;
429 controller.addMessageTranslator(FlowRemovedMessage.class, 4, objFms);
431 simulateV13PostHandshakeState(connectionConductor);
433 // Now send Flow Removed messages
434 FlowRemovedMessageBuilder builder1 = new FlowRemovedMessageBuilder();
435 builder1.setVersion((short) 4);
437 connectionConductor.onFlowRemovedMessage(builder1.build());
438 synchronized (popListener) {
439 LOG.debug("about to wait for popListener");
440 popListener.wait(maxProcessingTimeout);
442 Assert.assertEquals(1, flowremovedMessageCounter);
444 connectionConductor.onFlowRemovedMessage(builder1.build());
445 synchronized (popListener) {
446 popListener.wait(maxProcessingTimeout);
448 Assert.assertEquals(2, flowremovedMessageCounter);
453 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onMultipartReplyMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage)}
457 public void testOnMultipartReplyMessage() {
458 // fail("Not yet implemented");
464 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onPacketInMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessage)}
466 * @throws InterruptedException
469 public void testOnPacketInMessage() throws InterruptedException {
470 IMDMessageTranslator<OfHeader, List<DataObject>> objPms = new PacketInMessageService() ;
471 controller.addMessageTranslator(PacketInMessage.class, 4, objPms);
473 simulateV13PostHandshakeState(connectionConductor);
476 PacketInMessageBuilder builder1 = new PacketInMessageBuilder();
477 builder1.setVersion((short) 4);
478 builder1.setBufferId((long)1);
479 connectionConductor.onPacketInMessage(builder1.build());
480 synchronized (popListener) {
481 popListener.wait(maxProcessingTimeout);
483 Assert.assertEquals(1, packetinMessageCounter);
484 builder1.setBufferId((long)2);
485 connectionConductor.onPacketInMessage(builder1.build());
486 synchronized (popListener) {
487 popListener.wait(maxProcessingTimeout);
489 Assert.assertEquals(2, packetinMessageCounter);
494 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onPortStatusMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage)}
496 * @throws InterruptedException
499 public void testOnPortStatusMessage() throws InterruptedException {
500 IMDMessageTranslator<OfHeader, List<DataObject>> objPSms = new PortStatusMessageService() ;
501 controller.addMessageTranslator(PortStatusMessage.class, 4, objPSms);
503 simulateV13PostHandshakeState(connectionConductor);
505 // Send Port Status messages
506 PortStatusMessageBuilder builder1 = new PortStatusMessageBuilder();
507 builder1.setVersion((short) 4);
508 PortFeatures features = new PortFeatures(true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false);
509 builder1.setPortNo(90L).setReason(PortReason.OFPPRADD).setCurrentFeatures(features);
510 connectionConductor.onPortStatusMessage(builder1.build());
511 synchronized (popListener) {
512 popListener.wait(maxProcessingTimeout);
514 Assert.assertEquals(1, portstatusAddMessageCounter);
515 builder1.setPortNo(90L).setReason(PortReason.OFPPRMODIFY).setCurrentFeatures(features);
516 connectionConductor.onPortStatusMessage(builder1.build());
517 synchronized (popListener) {
518 popListener.wait(maxProcessingTimeout);
520 Assert.assertEquals(1, portstatusModifyMessageCounter);
521 builder1.setPortNo(90L).setReason(PortReason.OFPPRDELETE).setCurrentFeatures(features);
522 connectionConductor.onPortStatusMessage(builder1.build());
523 synchronized (popListener) {
524 popListener.wait(maxProcessingTimeout);
526 Assert.assertEquals(1, portstatusDeleteMessageCounter);
530 * @throws InterruptedException
532 private void executeLater() throws InterruptedException {
537 * @throws InterruptedException
539 private void executeNow() throws InterruptedException {
541 connectionConductor.shutdownPool();
545 * @throws InterruptedException
547 private void execute(boolean join) throws InterruptedException {
548 libSimulation = new Thread(adapter, "junit-adapter");
549 libSimulation.start();
551 libSimulation.join();
555 private static GetFeaturesOutputBuilder getFeatureResponseMsg() {
556 GetFeaturesOutputBuilder getFeaturesOutputBuilder = new GetFeaturesOutputBuilder();
557 getFeaturesOutputBuilder.setDatapathId(new BigInteger("102030405060"));
558 getFeaturesOutputBuilder.setAuxiliaryId((short) 0);
559 getFeaturesOutputBuilder.setBuffers(4L);
560 getFeaturesOutputBuilder.setReserved(0L);
561 getFeaturesOutputBuilder.setTables((short) 2);
562 getFeaturesOutputBuilder.setCapabilities(createCapabilities(84));
564 return getFeaturesOutputBuilder;
570 private static Capabilities createCapabilities(long input) {
571 final Boolean FLOW_STATS = (input & (1 << 0)) != 0;
572 final Boolean TABLE_STATS = (input & (1 << 1)) != 0;
573 final Boolean PORT_STATS = (input & (1 << 2)) != 0;
574 final Boolean GROUP_STATS = (input & (1 << 3)) != 0;
575 final Boolean IP_REASM = (input & (1 << 5)) != 0;
576 final Boolean QUEUE_STATS = (input & (1 << 6)) != 0;
577 final Boolean PORT_BLOCKED = (input & (1 << 8)) != 0;
578 Capabilities capabilities = new Capabilities(FLOW_STATS, GROUP_STATS, IP_REASM,
579 PORT_BLOCKED, PORT_STATS, QUEUE_STATS, TABLE_STATS);
583 public class ExperimenterMessageService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
585 public List<DataObject> translate(SwitchConnectionDistinguisher cookie, SessionContext sw, OfHeader msg) {
586 LOG.debug("Received a packet in Experimenter Service");
587 ConnectionConductorImplTest.this.incrExperimenterMessageCounter();
592 public class PacketInMessageService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
594 public List<DataObject> translate(SwitchConnectionDistinguisher cookie, SessionContext sw, OfHeader msg) {
595 LOG.debug("Received a packet in PacketIn Service");
596 ConnectionConductorImplTest.this.incrPacketinMessageCounter();
601 public class FlowRemovedMessageService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
603 public List<DataObject> translate(SwitchConnectionDistinguisher cookie, SessionContext sw, OfHeader msg) {
604 LOG.debug("Received a packet in FlowRemoved Service");
605 ConnectionConductorImplTest.this.incrFlowremovedMessageCounter();
610 public class PortStatusMessageService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
612 public List<DataObject> translate(SwitchConnectionDistinguisher cookie, SessionContext sw, OfHeader msg) {
613 LOG.debug("Received a packet in PortStatus Service");
614 if ( (((PortStatusMessage)msg).getReason().equals(PortReason.OFPPRADD)) ) {
615 ConnectionConductorImplTest.this.incrPortstatusAddMessageCounter();
616 } else if (((PortStatusMessage)msg).getReason().equals(PortReason.OFPPRDELETE)){
617 ConnectionConductorImplTest.this.incrPortstatusDeleteMessageCounter();
618 } else if (((PortStatusMessage)msg).getReason().equals(PortReason.OFPPRMODIFY)) {
619 ConnectionConductorImplTest.this.incrPortstatusModifyMessageCounter();
625 public class ErrorMessageService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
627 public List<DataObject> translate(SwitchConnectionDistinguisher cookie, SessionContext sw, OfHeader msg) {
628 LOG.debug("Received a packet in Experimenter Service");
629 ConnectionConductorImplTest.this.incrErrorMessageCounter();
636 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onExperimenterMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterMessage)}
638 * @throws InterruptedException
641 public void testOnExperimenterMessage() throws InterruptedException {
642 simulateV13PostHandshakeState(connectionConductor);
644 ExperimenterMessageBuilder builder1 = new ExperimenterMessageBuilder();
645 builder1.setVersion((short) 4);
646 builder1.setExperimenter(84L).setExpType(4L);
647 connectionConductor.onExperimenterMessage(builder1.build());
648 synchronized (popListener) {
649 popListener.wait(maxProcessingTimeout);
651 Assert.assertEquals(1, experimenterMessageCounter);
653 builder1.setExperimenter(85L).setExpType(4L);
654 connectionConductor.onExperimenterMessage(builder1.build());
655 synchronized (popListener) {
656 popListener.wait(maxProcessingTimeout);
658 Assert.assertEquals(2, experimenterMessageCounter);
663 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onExperimenterMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessage)}
665 * @throws InterruptedException
668 public void testOnErrorMessage() throws InterruptedException {
669 simulateV13PostHandshakeState(connectionConductor);
671 ErrorMessageBuilder builder1 = new ErrorMessageBuilder();
672 builder1.setVersion((short) 4);
673 builder1.setCode(100);
674 connectionConductor.onErrorMessage(builder1.build());
675 synchronized (popListener) {
676 popListener.wait(maxProcessingTimeout);
678 Assert.assertEquals(1, errorMessageCounter);
679 builder1.setCode(200);
680 connectionConductor.onErrorMessage(builder1.build());
681 synchronized (popListener) {
682 popListener.wait(maxProcessingTimeout);
684 Assert.assertEquals(2, errorMessageCounter);
688 * @return listener mapping for:
690 * <li>experimenter</li>
694 private Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, List<DataObject>>>> assembleTranslatorMapping() {
695 Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, List<DataObject>>>> translatorMapping = new HashMap<>();
698 IMDMessageTranslator<OfHeader, List<DataObject>> objEms = new ExperimenterMessageService() ;
699 Collection<IMDMessageTranslator<OfHeader, List<DataObject>>> existingValues = new ArrayList<>();
700 existingValues.add(objEms);
701 tKey = new TranslatorKey(4, ExperimenterMessage.class.getName());
702 translatorMapping.put(tKey, existingValues);
703 IMDMessageTranslator<OfHeader, List<DataObject>> objErms = new ErrorMessageService() ;
704 existingValues.add(objErms);
705 tKey = new TranslatorKey(4, ErrorMessage.class.getName());
706 translatorMapping.put(tKey, existingValues);
707 return translatorMapping;
712 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#processPortStatusMsg(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage)}
714 * Tests for getting features from port status message by port version
716 * <li>features are malformed - one of them is null</li>
717 * <li>mismatch between port version and port features</li>
718 * <li>mismatch between port version and port features</li>
719 * <li>non-existing port version</li>
720 * <li>port version OF 1.0</li>
721 * <li>port version OF 1.3</li>
726 public void testProcessPortStatusMsg() {
727 simulateV13PostHandshakeState(connectionConductor);
729 long portNumber = 90L;
730 long portNumberV10 = 91L;
731 PortStatusMessage msg;
733 PortStatusMessageBuilder builder = new PortStatusMessageBuilder();
734 PortFeatures features = new PortFeatures(true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false);
735 PortFeatures featuresMal = new PortFeatures(true,false,false,false,null,false,false,false,false,false,false,false,false,false,false,false);
736 PortFeaturesV10 featuresV10 = new PortFeaturesV10(true,false,false,false,false,false,false,false,false,false,false,false);
739 builder.setVersion((short) 1).setPortNo(portNumber).setReason(PortReason.OFPPRADD).setCurrentFeatures(featuresMal);
740 connectionConductor.processPortStatusMsg(builder.build());
741 Assert.assertTrue(connectionConductor.getSessionContext().getPortsBandwidth().isEmpty());
742 Assert.assertTrue(connectionConductor.getSessionContext().getPhysicalPorts().isEmpty());
744 //Version-features mismatch
745 builder.setCurrentFeatures(features);
746 connectionConductor.processPortStatusMsg(builder.build());
747 Assert.assertTrue(connectionConductor.getSessionContext().getPortsBandwidth().isEmpty());
748 Assert.assertTrue(connectionConductor.getSessionContext().getPhysicalPorts().isEmpty());
750 //Non existing version
751 builder.setVersion((short) 0);
752 connectionConductor.processPortStatusMsg(builder.build());
753 Assert.assertTrue(connectionConductor.getSessionContext().getPortsBandwidth().isEmpty());
754 Assert.assertTrue(connectionConductor.getSessionContext().getPhysicalPorts().isEmpty());
757 builder.setVersion((short) 4);
758 msg = builder.build();
759 connectionConductor.processPortStatusMsg(builder.build());
760 Assert.assertTrue(connectionConductor.getSessionContext().getPortBandwidth(portNumber));
761 Assert.assertEquals(connectionConductor.getSessionContext().getPhysicalPort(portNumber), msg);
764 builder.setVersion((short) 1).setPortNo(portNumberV10).setCurrentFeatures(null).setCurrentFeaturesV10(featuresV10);
765 msg = builder.build();
766 connectionConductor.processPortStatusMsg(builder.build());
767 Assert.assertTrue(connectionConductor.getSessionContext().getPortBandwidth(portNumberV10));
768 Assert.assertEquals(connectionConductor.getSessionContext().getPhysicalPort(portNumberV10), msg);
771 private void simulateV13PostHandshakeState(ConnectionConductorImpl conductor) {
772 GetFeaturesOutputBuilder featureOutput = getFeatureResponseMsg();
773 conductor.postHandshakeBasic(featureOutput.build(), OFConstants.OFP_VERSION_1_3);