2 * Copyright (c) 2013-2014 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 static org.junit.Assert.assertNotNull;
13 import java.math.BigInteger;
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.HashMap;
17 import java.util.List;
19 import java.util.Stack;
20 import java.util.concurrent.CountDownLatch;
21 import java.util.concurrent.ScheduledThreadPoolExecutor;
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.ArgumentCaptor;
29 import org.mockito.Matchers;
30 import org.mockito.Mock;
31 import org.mockito.Mockito;
32 import org.mockito.runners.MockitoJUnitRunner;
33 import org.opendaylight.openflowplugin.api.OFConstants;
34 import org.opendaylight.openflowplugin.api.openflow.connection.HandshakeContext;
35 import org.opendaylight.openflowplugin.api.openflow.md.core.ConnectionConductor;
36 import org.opendaylight.openflowplugin.api.openflow.md.core.IMDMessageTranslator;
37 import org.opendaylight.openflowplugin.api.openflow.md.core.SwitchConnectionDistinguisher;
38 import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey;
39 import org.opendaylight.openflowplugin.api.openflow.md.core.session.SessionContext;
40 import org.opendaylight.openflowplugin.api.openflow.md.queue.PopListener;
41 import org.opendaylight.openflowplugin.api.openflow.statistics.MessageSpy;
42 import org.opendaylight.openflowplugin.openflow.md.core.plan.ConnectionAdapterStackImpl;
43 import org.opendaylight.openflowplugin.openflow.md.core.plan.EventFactory;
44 import org.opendaylight.openflowplugin.openflow.md.core.plan.SwitchTestEvent;
45 import org.opendaylight.openflowplugin.openflow.md.queue.QueueProcessorLightImpl;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Capabilities;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeatures;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeaturesV10;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortReason;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessageBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessage;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessageBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterMessage;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessage;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessageBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutputBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloMessageBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessage;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessageBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatus;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessageBuilder;
64 import org.opendaylight.yangtools.yang.binding.DataContainer;
65 import org.opendaylight.yangtools.yang.binding.DataObject;
66 import org.slf4j.Logger;
67 import org.slf4j.LoggerFactory;
69 @RunWith(MockitoJUnitRunner.class)
70 public class ConnectionConductorImplTest {
72 protected static final Logger LOG = LoggerFactory
73 .getLogger(ConnectionConductorImplTest.class);
78 private final int maxProcessingTimeout = 500;
80 protected ConnectionAdapterStackImpl adapter;
81 private ConnectionConductorImpl connectionConductor;
82 private MDController controller;
83 private Stack<SwitchTestEvent> eventPlan;
85 private Thread libSimulation;
86 private final ScheduledThreadPoolExecutor pool = new ScheduledThreadPoolExecutor(
89 protected QueueProcessorLightImpl queueProcessor;
91 private PopListenerCountingImpl<DataObject> popListener;
93 private int experimenterMessageCounter;
94 private int packetinMessageCounter;
95 private int flowremovedMessageCounter;
96 private int portstatusAddMessageCounter;
97 private int portstatusDeleteMessageCounter;
98 private int portstatusModifyMessageCounter;
99 private int errorMessageCounter;
102 private ErrorHandlerSimpleImpl errorHandler;
104 private final int expectedErrors = 0;
106 private MessageSpy<DataContainer> messageSpy;
108 HandshakeContext handshakeContext;
109 private ErrorMessageService objErms;
111 public void incrExperimenterMessageCounter() {
112 this.experimenterMessageCounter++;
115 public void incrPacketinMessageCounter() {
116 this.packetinMessageCounter++;
119 public void incrFlowremovedMessageCounter() {
120 this.flowremovedMessageCounter++;
123 public void incrPortstatusAddMessageCounter() {
124 this.portstatusAddMessageCounter++;
127 public void incrPortstatusDeleteMessageCounter() {
128 this.portstatusDeleteMessageCounter++;
131 public void incrPortstatusModifyMessageCounter() {
132 this.portstatusModifyMessageCounter++;
135 public void incrErrorMessageCounter() {
136 this.errorMessageCounter++;
141 * Test for ConnectionConductorFactory#createConductor
143 public void testCreateConductor() {
144 ConnectionConductor connectionConductor = ConnectionConductorFactory.createConductor(adapter, queueProcessor);
145 assertNotNull(connectionConductor);
149 * @throws java.lang.Exception
152 public void setUp() throws Exception {
153 adapter = new ConnectionAdapterStackImpl();
155 popListener = new PopListenerCountingImpl<>();
157 controller = new MDController();
159 controller.getMessageTranslators().putAll(assembleTranslatorMapping());
161 queueProcessor = new QueueProcessorLightImpl();
162 queueProcessor.setMessageSpy(messageSpy);
163 queueProcessor.setPopListenersMapping(assemblePopListenerMapping());
164 queueProcessor.setTranslatorMapping(controller.getMessageTranslators());
165 queueProcessor.init();
167 connectionConductor = new ConnectionConductorImpl(adapter);
168 connectionConductor.setQueueProcessor(queueProcessor);
169 connectionConductor.setErrorHandler(errorHandler);
170 connectionConductor.init();
171 connectionConductor.setHandshakeContext(handshakeContext);
172 eventPlan = new Stack<>();
173 adapter.setEventPlan(eventPlan);
174 adapter.setProceedTimeout(5000L);
175 adapter.checkListeners();
181 private Map<Class<? extends DataObject>, Collection<PopListener<DataObject>>> assemblePopListenerMapping() {
182 Map<Class<? extends DataObject>, Collection<PopListener<DataObject>>> mapping = new HashMap<>();
183 Collection<PopListener<DataObject>> popListenerBag = new ArrayList<>();
184 popListenerBag.add(popListener);
185 //TODO: add testing registered types
186 mapping.put(DataObject.class, popListenerBag);
191 * @throws java.lang.Exception
194 public void tearDown() throws Exception {
195 if (libSimulation != null) {
196 libSimulation.join();
198 queueProcessor.shutdown();
199 connectionConductor.getHsPool().shutdown();
201 for (Exception problem : adapter.getOccuredExceptions()) {
202 LOG.error("during simulation on adapter side: "
203 + problem.getMessage());
205 Assert.assertEquals(0, adapter.getOccuredExceptions().size());
207 if (LOG.isDebugEnabled()) {
208 if (eventPlan.size() > 0) {
209 LOG.debug("eventPlan size: " + eventPlan.size());
210 for (SwitchTestEvent event : eventPlan) {
211 LOG.debug(" # EVENT:: " + event);
215 Assert.assertTrue("plan is not finished", eventPlan.isEmpty());
219 // logging errors if occurred
220 ArgumentCaptor<Throwable> errorCaptor = ArgumentCaptor.forClass(Throwable.class);
221 Mockito.verify(errorHandler, Mockito.atMost(1)).handleException(
222 errorCaptor.capture(), Matchers.any(SessionContext.class));
223 for (Throwable problem : errorCaptor.getAllValues()) {
224 LOG.warn(problem.getMessage(), problem);
227 Mockito.verify(errorHandler, Mockito.times(expectedErrors)).handleException(
228 Matchers.any(Throwable.class), Matchers.any(SessionContext.class));
233 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onEchoRequestMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessage)}
239 public void testOnEchoRequestMessage() throws Exception {
240 simulateV13PostHandshakeState(connectionConductor);
242 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
243 EventFactory.DEFAULT_VERSION, new EchoRequestMessageBuilder()));
245 EventFactory.createDefaultWaitForRpcEvent(42, "echoReply"));
250 * Test of handshake, covering version negotiation and features.
251 * Switch delivers first helloMessage with default version.
256 public void testHandshake1() throws Exception {
257 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
258 EventFactory.DEFAULT_VERSION, new HelloMessageBuilder()));
259 eventPlan.add(0, EventFactory.createDefaultWaitForAllEvent(
260 EventFactory.createDefaultWaitForRpcEvent(43, "helloReply"),
261 EventFactory.createDefaultWaitForRpcEvent(44, "getFeatures")));
262 eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(44,
263 EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
266 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
267 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
270 Assert.assertEquals(ConnectionConductor.CONDUCTOR_STATE.WORKING,
271 connectionConductor.getConductorState());
272 Assert.assertEquals((short) 0x04, connectionConductor.getVersion()
277 * Test of handshake, covering version negotiation and features.
278 * Controller sends first helloMessage with default version
283 public void testHandshake1SwitchStarts() throws Exception {
284 eventPlan.add(0, EventFactory.createConnectionReadyCallback(connectionConductor));
285 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(21, "helloReply"));
286 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
287 EventFactory.DEFAULT_VERSION, new HelloMessageBuilder()));
288 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(43, "getFeatures"));
289 eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(43,
290 EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
293 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
294 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
298 Assert.assertEquals(ConnectionConductor.CONDUCTOR_STATE.WORKING,
299 connectionConductor.getConductorState());
300 Assert.assertEquals((short) 0x04, connectionConductor.getVersion()
305 * Test of handshake, covering version negotiation and features.
306 * Switch delivers first helloMessage with version 0x05
307 * and negotiates following versions: 0x03, 0x01
312 public void testHandshake2() throws Exception {
313 connectionConductor.setBitmapNegotiationEnable(false);
314 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
315 (short) 0x05, new HelloMessageBuilder()));
317 EventFactory.createDefaultWaitForRpcEvent(43, "helloReply"));
318 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(43L,
319 (short) 0x03, new HelloMessageBuilder()));
321 EventFactory.createDefaultWaitForRpcEvent(44, "helloReply"));
322 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(44L,
323 (short) 0x01, new HelloMessageBuilder()));
325 EventFactory.createDefaultWaitForRpcEvent(45, "getFeatures"));
327 eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(45,
328 (short) 0x01, getFeatureResponseMsg()));
331 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
335 Assert.assertEquals(ConnectionConductor.CONDUCTOR_STATE.WORKING,
336 connectionConductor.getConductorState());
337 Assert.assertEquals((short) 0x01, connectionConductor.getVersion()
342 * Test of handshake, covering version negotiation and features.
343 * Controller sends first helloMessage with default version
344 * and switch negotiates following versions: 0x05, 0x03, 0x01
349 public void testHandshake2SwitchStarts() throws Exception {
350 connectionConductor.setBitmapNegotiationEnable(false);
351 eventPlan.add(0, EventFactory.createConnectionReadyCallback(connectionConductor));
353 EventFactory.createDefaultWaitForRpcEvent(21, "helloReply"));
354 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
355 (short) 0x05, new HelloMessageBuilder()));
356 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(43L,
357 (short) 0x03, new HelloMessageBuilder()));
359 EventFactory.createDefaultWaitForRpcEvent(44, "helloReply"));
360 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(44L,
361 (short) 0x01, new HelloMessageBuilder()));
363 EventFactory.createDefaultWaitForRpcEvent(45, "getFeatures"));
365 eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(45,
366 (short) 0x01, getFeatureResponseMsg()));
369 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
373 Assert.assertEquals(ConnectionConductor.CONDUCTOR_STATE.WORKING,
374 connectionConductor.getConductorState());
375 Assert.assertEquals((short) 0x01, connectionConductor.getVersion()
381 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onFlowRemovedMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessage)}
384 * @throws InterruptedException
387 public void testOnFlowRemovedMessage() throws InterruptedException {
388 FlowRemovedMessageService objFms = new FlowRemovedMessageService();
389 controller.addMessageTranslator(FlowRemovedMessage.class, 4, objFms);
391 simulateV13PostHandshakeState(connectionConductor);
392 objFms.resetLatch(2);
394 // Now send Flow Removed messages
395 FlowRemovedMessageBuilder builder1 = new FlowRemovedMessageBuilder();
396 builder1.setVersion((short) 4);
398 connectionConductor.onFlowRemovedMessage(builder1.build());
399 LOG.debug("about to wait for popListener");
401 connectionConductor.onFlowRemovedMessage(builder1.build());
403 flushMessageProcessing();
404 Assert.assertTrue(objFms.await(maxProcessingTimeout, TimeUnit.MILLISECONDS));
405 Assert.assertEquals(2, flowremovedMessageCounter);
410 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onMultipartReplyMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage)}
414 public void testOnMultipartReplyMessage() {
415 // fail("Not yet implemented");
421 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onPacketInMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessage)}
424 * @throws InterruptedException
427 public void testOnPacketInMessage() throws InterruptedException {
428 PacketInMessageService objPms = new PacketInMessageService();
429 controller.addMessageTranslator(PacketInMessage.class, 4, objPms);
431 simulateV13PostHandshakeState(connectionConductor);
434 PacketInMessageBuilder builder1 = new PacketInMessageBuilder();
435 builder1.setVersion((short) 4);
436 builder1.setBufferId((long) 1);
437 connectionConductor.onPacketInMessage(builder1.build());
438 builder1.setBufferId((long) 2);
439 connectionConductor.onPacketInMessage(builder1.build());
441 flushMessageProcessing();
442 Assert.assertTrue(objPms.await(maxProcessingTimeout, TimeUnit.MILLISECONDS));
443 Assert.assertEquals(2, packetinMessageCounter);
448 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onPortStatusMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage)}
451 * @throws InterruptedException
454 public void testOnPortStatusMessage() throws InterruptedException {
455 PortStatusMessageService objPSms = new PortStatusMessageService();
456 controller.addMessageTranslator(PortStatusMessage.class, 4, objPSms);
458 simulateV13PostHandshakeState(connectionConductor);
460 // Send Port Status messages
461 PortStatusMessageBuilder builder1 = new PortStatusMessageBuilder();
462 builder1.setVersion((short) 4);
463 PortFeatures features = new PortFeatures(true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false);
464 builder1.setPortNo(90L).setReason(PortReason.OFPPRADD).setCurrentFeatures(features);
465 objPSms.resetLatch(3);
466 LOG.debug("sending port message");
467 connectionConductor.onPortStatusMessage(builder1.build());
468 builder1.setPortNo(90L).setReason(PortReason.OFPPRMODIFY).setCurrentFeatures(features);
469 connectionConductor.onPortStatusMessage(builder1.build());
470 builder1.setPortNo(90L).setReason(PortReason.OFPPRDELETE).setCurrentFeatures(features);
471 connectionConductor.onPortStatusMessage(builder1.build());
473 flushMessageProcessing();
474 Assert.assertTrue(objPSms.await(maxProcessingTimeout, TimeUnit.MILLISECONDS));
475 Assert.assertEquals(1, portstatusModifyMessageCounter);
476 Assert.assertEquals(1, portstatusAddMessageCounter);
477 Assert.assertEquals(1, portstatusDeleteMessageCounter);
480 private void flushMessageProcessing() throws InterruptedException {
481 // make sure that harvester sleeps deeply
482 Thread.sleep(maxProcessingTimeout);
484 queueProcessor.getHarvesterHandle().ping();
488 * @throws InterruptedException
490 private void executeLater() throws InterruptedException {
495 * @throws InterruptedException
497 private void executeNow() throws InterruptedException {
499 connectionConductor.getHsPool().shutdown();
503 * @throws InterruptedException
505 private void execute(final boolean join) throws InterruptedException {
506 libSimulation = new Thread(adapter, "junit-adapter");
507 libSimulation.start();
509 libSimulation.join();
513 private static GetFeaturesOutputBuilder getFeatureResponseMsg() {
514 GetFeaturesOutputBuilder getFeaturesOutputBuilder = new GetFeaturesOutputBuilder();
515 getFeaturesOutputBuilder.setDatapathId(new BigInteger("102030405060"));
516 getFeaturesOutputBuilder.setAuxiliaryId((short) 0);
517 getFeaturesOutputBuilder.setBuffers(4L);
518 getFeaturesOutputBuilder.setReserved(0L);
519 getFeaturesOutputBuilder.setTables((short) 2);
520 getFeaturesOutputBuilder.setCapabilities(createCapabilities(84));
522 return getFeaturesOutputBuilder;
528 private static Capabilities createCapabilities(final long input) {
529 final Boolean FLOW_STATS = (input & (1 << 0)) != 0;
530 final Boolean TABLE_STATS = (input & (1 << 1)) != 0;
531 final Boolean PORT_STATS = (input & (1 << 2)) != 0;
532 final Boolean GROUP_STATS = (input & (1 << 3)) != 0;
533 final Boolean IP_REASM = (input & (1 << 5)) != 0;
534 final Boolean QUEUE_STATS = (input & (1 << 6)) != 0;
535 final Boolean PORT_BLOCKED = (input & (1 << 8)) != 0;
536 Capabilities capabilities = new Capabilities(FLOW_STATS, GROUP_STATS, IP_REASM,
537 PORT_BLOCKED, PORT_STATS, QUEUE_STATS, TABLE_STATS);
541 public abstract class ProcessingLatchService {
542 private CountDownLatch processingLatch = new CountDownLatch(0);
544 public void resetLatch(int passAmount) {
545 processingLatch = new CountDownLatch(passAmount);
548 protected void countDown() {
549 processingLatch.countDown();
552 public boolean await(long timeout, TimeUnit unit) throws InterruptedException {
553 return processingLatch.await(timeout, unit);
557 public class ExperimenterMessageService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
559 public List<DataObject> translate(final SwitchConnectionDistinguisher cookie, final SessionContext sw, final OfHeader msg) {
560 LOG.debug("Received a packet in Experimenter Service");
561 ConnectionConductorImplTest.this.incrExperimenterMessageCounter();
566 public class PacketInMessageService extends ProcessingLatchService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
568 public List<DataObject> translate(final SwitchConnectionDistinguisher cookie, final SessionContext sw, final OfHeader msg) {
569 LOG.debug("Received a packet in PacketIn Service");
570 ConnectionConductorImplTest.this.incrPacketinMessageCounter();
576 public class FlowRemovedMessageService extends ProcessingLatchService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
578 public List<DataObject> translate(final SwitchConnectionDistinguisher cookie, final SessionContext sw, final OfHeader msg) {
579 LOG.debug("Received a packet in FlowRemoved Service");
580 ConnectionConductorImplTest.this.incrFlowremovedMessageCounter();
586 public class PortStatusMessageService extends ProcessingLatchService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
588 public List<DataObject> translate(final SwitchConnectionDistinguisher cookie, final SessionContext sw, final OfHeader msg) {
589 LOG.debug("Received a packet in PortStatus Service");
590 if ((((PortStatusMessage) msg).getReason().equals(PortReason.OFPPRADD))) {
591 ConnectionConductorImplTest.this.incrPortstatusAddMessageCounter();
592 } else if (((PortStatusMessage) msg).getReason().equals(PortReason.OFPPRDELETE)) {
593 ConnectionConductorImplTest.this.incrPortstatusDeleteMessageCounter();
594 } else if (((PortStatusMessage) msg).getReason().equals(PortReason.OFPPRMODIFY)) {
595 ConnectionConductorImplTest.this.incrPortstatusModifyMessageCounter();
602 public class ErrorMessageService extends ProcessingLatchService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
604 public List<DataObject> translate(final SwitchConnectionDistinguisher cookie, final SessionContext sw, final OfHeader msg) {
605 LOG.debug("Received a packet in Experimenter Service");
606 ConnectionConductorImplTest.this.incrErrorMessageCounter();
614 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onExperimenterMessage(ExperimenterMessage)}
617 * @throws InterruptedException
620 public void testOnErrorMessage() throws InterruptedException {
621 simulateV13PostHandshakeState(connectionConductor);
622 final int messageAmount = 2;
624 objErms.resetLatch(messageAmount);
625 ErrorMessageBuilder builder1 = new ErrorMessageBuilder();
626 builder1.setVersion((short) 4);
627 builder1.setCode(100);
628 connectionConductor.onErrorMessage(builder1.build());
629 builder1.setCode(200);
630 connectionConductor.onErrorMessage(builder1.build());
632 flushMessageProcessing();
633 Assert.assertTrue(objErms.await(maxProcessingTimeout, TimeUnit.MILLISECONDS));
634 Assert.assertEquals(messageAmount, errorMessageCounter);
638 * @return listener mapping for:
640 * <li>experimenter</li>
644 private Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, List<DataObject>>>> assembleTranslatorMapping() {
645 Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, List<DataObject>>>> translatorMapping = new HashMap<>();
648 IMDMessageTranslator<OfHeader, List<DataObject>> objEms = new ExperimenterMessageService();
649 Collection<IMDMessageTranslator<OfHeader, List<DataObject>>> existingValues = new ArrayList<>();
650 existingValues.add(objEms);
651 tKey = new TranslatorKey(4, ExperimenterMessage.class.getName());
652 translatorMapping.put(tKey, existingValues);
653 objErms = new ErrorMessageService();
654 existingValues.add(objErms);
655 tKey = new TranslatorKey(4, ErrorMessage.class.getName());
656 translatorMapping.put(tKey, existingValues);
657 return translatorMapping;
662 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#processPortStatusMsg(PortStatus)}
664 * Tests for getting features from port status message by port version
666 * <li>features are malformed - one of them is null</li>
667 * <li>mismatch between port version and port features</li>
668 * <li>mismatch between port version and port features</li>
669 * <li>non-existing port version</li>
670 * <li>port version OF 1.0</li>
671 * <li>port version OF 1.3</li>
675 public void testProcessPortStatusMsg() {
676 simulateV13PostHandshakeState(connectionConductor);
678 long portNumber = 90L;
679 long portNumberV10 = 91L;
680 PortStatusMessage msg;
682 PortStatusMessageBuilder builder = new PortStatusMessageBuilder();
683 PortFeatures features = new PortFeatures(true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false);
684 PortFeatures featuresMal = new PortFeatures(true, false, false, false, null, false, false, false, false, false, false, false, false, false, false, false);
685 PortFeaturesV10 featuresV10 = new PortFeaturesV10(true, false, false, false, false, false, false, false, false, false, false, false);
688 builder.setVersion((short) 1).setPortNo(portNumber).setReason(PortReason.OFPPRADD).setCurrentFeatures(featuresMal);
689 connectionConductor.processPortStatusMsg(builder.build());
690 Assert.assertTrue(connectionConductor.getSessionContext().getPortsBandwidth().isEmpty());
691 Assert.assertTrue(connectionConductor.getSessionContext().getPhysicalPorts().isEmpty());
693 //Version-features mismatch
694 builder.setCurrentFeatures(features);
695 connectionConductor.processPortStatusMsg(builder.build());
696 Assert.assertTrue(connectionConductor.getSessionContext().getPortsBandwidth().isEmpty());
697 Assert.assertTrue(connectionConductor.getSessionContext().getPhysicalPorts().isEmpty());
699 //Non existing version
700 builder.setVersion((short) 0);
701 connectionConductor.processPortStatusMsg(builder.build());
702 Assert.assertTrue(connectionConductor.getSessionContext().getPortsBandwidth().isEmpty());
703 Assert.assertTrue(connectionConductor.getSessionContext().getPhysicalPorts().isEmpty());
706 builder.setVersion((short) 4);
707 msg = builder.build();
708 connectionConductor.processPortStatusMsg(builder.build());
709 Assert.assertTrue(connectionConductor.getSessionContext().getPortBandwidth(portNumber));
710 Assert.assertEquals(connectionConductor.getSessionContext().getPhysicalPort(portNumber), msg);
713 builder.setVersion((short) 1).setPortNo(portNumberV10).setCurrentFeatures(null).setCurrentFeaturesV10(featuresV10);
714 msg = builder.build();
715 connectionConductor.processPortStatusMsg(builder.build());
716 Assert.assertTrue(connectionConductor.getSessionContext().getPortBandwidth(portNumberV10));
717 Assert.assertEquals(connectionConductor.getSessionContext().getPhysicalPort(portNumberV10), msg);
722 public void testHandshakeFailOperations(){
723 connectionConductor.onHandshakeFailure();
724 connectionConductor.checkState(ConnectionConductor.CONDUCTOR_STATE.RIP);
726 private static void simulateV13PostHandshakeState(final ConnectionConductorImpl conductor) {
727 GetFeaturesOutputBuilder featureOutput = getFeatureResponseMsg();
728 conductor.postHandshakeBasic(featureOutput.build(), OFConstants.OFP_VERSION_1_3);
729 LOG.debug("simulating post handshake event done");