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 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.ScheduledThreadPoolExecutor;
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.api.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.QueueProcessorLightImpl;
38 import org.opendaylight.openflowplugin.statistics.MessageSpy;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Capabilities;
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.ExperimenterMessage;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessage;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessageBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutputBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloMessageBuilder;
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.PacketInMessage;
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.PortStatusMessage;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessageBuilder;
56 import org.opendaylight.yangtools.yang.binding.DataContainer;
57 import org.opendaylight.yangtools.yang.binding.DataObject;
58 import org.slf4j.Logger;
59 import org.slf4j.LoggerFactory;
61 @RunWith(MockitoJUnitRunner.class)
62 public class ConnectionConductorImplTest {
64 protected static final Logger LOG = LoggerFactory
65 .getLogger(ConnectionConductorImplTest.class);
70 private final int maxProcessingTimeout = 500;
72 protected ConnectionAdapterStackImpl adapter;
73 private ConnectionConductorImpl connectionConductor;
74 private MDController controller;
75 private Stack<SwitchTestEvent> eventPlan;
77 private Thread libSimulation;
78 private ScheduledThreadPoolExecutor pool = new ScheduledThreadPoolExecutor(
81 protected QueueProcessorLightImpl queueProcessor;
83 private PopListener<DataObject> popListener;
85 private int experimenterMessageCounter;
86 private int packetinMessageCounter;
87 private int flowremovedMessageCounter;
88 private int portstatusAddMessageCounter;
89 private int portstatusDeleteMessageCounter;
90 private int portstatusModifyMessageCounter;
91 private int errorMessageCounter;
94 private ErrorHandlerSimpleImpl errorHandler;
96 private int expectedErrors = 0;
98 private MessageSpy<DataContainer> messageSpy;
100 public void incrExperimenterMessageCounter() {
101 this.experimenterMessageCounter++;
104 public void incrPacketinMessageCounter() {
105 this.packetinMessageCounter++;
108 public void incrFlowremovedMessageCounter() {
109 this.flowremovedMessageCounter++;
112 public void incrPortstatusAddMessageCounter() {
113 this.portstatusAddMessageCounter++;
116 public void incrPortstatusDeleteMessageCounter() {
117 this.portstatusDeleteMessageCounter++;
120 public void incrPortstatusModifyMessageCounter() {
121 this.portstatusModifyMessageCounter++;
124 public void incrErrorMessageCounter() {
125 this.errorMessageCounter++;
130 * Test for ConnectionConductorFactory#createConductor
132 public void testCreateConductor() {
133 ConnectionConductor connectionConductor = ConnectionConductorFactory.createConductor(adapter, queueProcessor);
134 assertNotNull(connectionConductor);
138 * @throws java.lang.Exception
141 public void setUp() throws Exception {
142 adapter = new ConnectionAdapterStackImpl();
144 popListener = new PopListenerCountingImpl<>();
146 controller = new MDController();
148 controller.getMessageTranslators().putAll(assembleTranslatorMapping());
150 queueProcessor = new QueueProcessorLightImpl();
151 queueProcessor.setMessageSpy(messageSpy);
152 queueProcessor.setPopListenersMapping(assemblePopListenerMapping());
153 queueProcessor.setTranslatorMapping(controller.getMessageTranslators());
154 queueProcessor.init();
156 connectionConductor = new ConnectionConductorImpl(adapter);
157 connectionConductor.setQueueProcessor(queueProcessor);
158 connectionConductor.setErrorHandler(errorHandler);
159 connectionConductor.init();
160 eventPlan = new Stack<>();
161 adapter.setEventPlan(eventPlan);
162 adapter.setProceedTimeout(5000L);
163 adapter.checkListeners();
169 private Map<Class<? extends DataObject>, Collection<PopListener<DataObject>>> assemblePopListenerMapping() {
170 Map<Class<? extends DataObject>, Collection<PopListener<DataObject>>> mapping = new HashMap<>();
171 Collection<PopListener<DataObject>> popListenerBag = new ArrayList<>();
172 popListenerBag.add(popListener);
173 //TODO: add testing registered types
174 mapping.put(DataObject.class, popListenerBag);
179 * @throws java.lang.Exception
182 public void tearDown() throws Exception {
183 if (libSimulation != null) {
184 libSimulation.join();
186 queueProcessor.shutdown();
187 connectionConductor.shutdownPool();
189 for (Exception problem : adapter.getOccuredExceptions()) {
190 LOG.error("during simulation on adapter side: "
191 + problem.getMessage());
193 Assert.assertEquals(0, adapter.getOccuredExceptions().size());
195 if (LOG.isDebugEnabled()) {
196 if (eventPlan.size() > 0) {
197 LOG.debug("eventPlan size: " + eventPlan.size());
198 for (SwitchTestEvent event : eventPlan) {
199 LOG.debug(" # EVENT:: " + event.toString());
203 Assert.assertTrue("plan is not finished", eventPlan.isEmpty());
207 // logging errors if occurred
208 ArgumentCaptor<Throwable> errorCaptor = ArgumentCaptor.forClass(Throwable.class);
209 Mockito.verify(errorHandler, Mockito.atMost(1)).handleException(
210 errorCaptor.capture(), Matchers.any(SessionContext.class));
211 for (Throwable problem : errorCaptor.getAllValues()) {
212 LOG.warn(problem.getMessage(), problem);
215 Mockito.verify(errorHandler, Mockito.times(expectedErrors)).handleException(
216 Matchers.any(Throwable.class), Matchers.any(SessionContext.class));
221 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onEchoRequestMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessage)}
227 public void testOnEchoRequestMessage() throws Exception {
228 simulateV13PostHandshakeState(connectionConductor);
230 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
231 EventFactory.DEFAULT_VERSION, new EchoRequestMessageBuilder()));
233 EventFactory.createDefaultWaitForRpcEvent(42, "echoReply"));
238 * Test of handshake, covering version negotiation and features.
239 * Switch delivers first helloMessage with default version.
244 public void testHandshake1() throws Exception {
245 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
246 EventFactory.DEFAULT_VERSION, new HelloMessageBuilder()));
247 eventPlan.add(0, EventFactory.createDefaultWaitForAllEvent(
248 EventFactory.createDefaultWaitForRpcEvent(43, "helloReply"),
249 EventFactory.createDefaultWaitForRpcEvent(44, "getFeatures")));
250 eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(44,
251 EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
254 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "setConfig"));
255 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
256 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
257 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
258 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
261 Assert.assertEquals(ConnectionConductor.CONDUCTOR_STATE.WORKING,
262 connectionConductor.getConductorState());
263 Assert.assertEquals((short) 0x04, connectionConductor.getVersion()
268 * Test of handshake, covering version negotiation and features.
269 * Controller sends first helloMessage with default version
274 public void testHandshake1SwitchStarts() throws Exception {
275 eventPlan.add(0, EventFactory.createConnectionReadyCallback(connectionConductor));
276 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(21, "helloReply"));
277 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
278 EventFactory.DEFAULT_VERSION, new HelloMessageBuilder()));
279 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(43, "getFeatures"));
280 eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(43,
281 EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
284 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "setConfig"));
285 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
286 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
287 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
288 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
292 Assert.assertEquals(ConnectionConductor.CONDUCTOR_STATE.WORKING,
293 connectionConductor.getConductorState());
294 Assert.assertEquals((short) 0x04, connectionConductor.getVersion()
299 * Test of handshake, covering version negotiation and features.
300 * Switch delivers first helloMessage with version 0x05
301 * and negotiates following versions: 0x03, 0x01
306 public void testHandshake2() throws Exception {
307 connectionConductor.setBitmapNegotiationEnable(false);
308 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
309 (short) 0x05, new HelloMessageBuilder()));
311 EventFactory.createDefaultWaitForRpcEvent(43, "helloReply"));
312 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(43L,
313 (short) 0x03, new HelloMessageBuilder()));
315 EventFactory.createDefaultWaitForRpcEvent(44, "helloReply"));
316 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(44L,
317 (short) 0x01, new HelloMessageBuilder()));
319 EventFactory.createDefaultWaitForRpcEvent(45, "getFeatures"));
321 eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(45,
322 EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
324 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(1, "multipartRequestInput"));
328 Assert.assertEquals(ConnectionConductor.CONDUCTOR_STATE.WORKING,
329 connectionConductor.getConductorState());
330 Assert.assertEquals((short) 0x01, connectionConductor.getVersion()
335 * Test of handshake, covering version negotiation and features.
336 * Controller sends first helloMessage with default version
337 * and switch negotiates following versions: 0x05, 0x03, 0x01
342 public void testHandshake2SwitchStarts() throws Exception {
343 connectionConductor.setBitmapNegotiationEnable(false);
344 eventPlan.add(0, EventFactory.createConnectionReadyCallback(connectionConductor));
346 EventFactory.createDefaultWaitForRpcEvent(21, "helloReply"));
347 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
348 (short) 0x05, new HelloMessageBuilder()));
349 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(43L,
350 (short) 0x03, new HelloMessageBuilder()));
352 EventFactory.createDefaultWaitForRpcEvent(44, "helloReply"));
353 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(44L,
354 (short) 0x01, new HelloMessageBuilder()));
356 EventFactory.createDefaultWaitForRpcEvent(45, "getFeatures"));
358 eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(45,
359 EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
361 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(1, "multipartRequestInput"));
365 Assert.assertEquals(ConnectionConductor.CONDUCTOR_STATE.WORKING,
366 connectionConductor.getConductorState());
367 Assert.assertEquals((short) 0x01, connectionConductor.getVersion()
373 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onFlowRemovedMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessage)}
376 * @throws InterruptedException
379 public void testOnFlowRemovedMessage() throws InterruptedException {
380 IMDMessageTranslator<OfHeader, List<DataObject>> objFms = new FlowRemovedMessageService();
381 controller.addMessageTranslator(FlowRemovedMessage.class, 4, objFms);
383 simulateV13PostHandshakeState(connectionConductor);
385 // Now send Flow Removed messages
386 FlowRemovedMessageBuilder builder1 = new FlowRemovedMessageBuilder();
387 builder1.setVersion((short) 4);
389 connectionConductor.onFlowRemovedMessage(builder1.build());
390 synchronized (popListener) {
391 LOG.debug("about to wait for popListener");
392 popListener.wait(maxProcessingTimeout);
394 Assert.assertEquals(1, flowremovedMessageCounter);
396 connectionConductor.onFlowRemovedMessage(builder1.build());
397 synchronized (popListener) {
398 popListener.wait(maxProcessingTimeout);
400 Assert.assertEquals(2, flowremovedMessageCounter);
405 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onMultipartReplyMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage)}
409 public void testOnMultipartReplyMessage() {
410 // fail("Not yet implemented");
416 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onPacketInMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessage)}
419 * @throws InterruptedException
422 public void testOnPacketInMessage() throws InterruptedException {
423 IMDMessageTranslator<OfHeader, List<DataObject>> objPms = new PacketInMessageService();
424 controller.addMessageTranslator(PacketInMessage.class, 4, objPms);
426 simulateV13PostHandshakeState(connectionConductor);
429 PacketInMessageBuilder builder1 = new PacketInMessageBuilder();
430 builder1.setVersion((short) 4);
431 builder1.setBufferId((long) 1);
432 connectionConductor.onPacketInMessage(builder1.build());
433 synchronized (popListener) {
434 popListener.wait(maxProcessingTimeout);
436 Assert.assertEquals(1, packetinMessageCounter);
437 builder1.setBufferId((long) 2);
438 connectionConductor.onPacketInMessage(builder1.build());
439 synchronized (popListener) {
440 popListener.wait(maxProcessingTimeout);
442 Assert.assertEquals(2, packetinMessageCounter);
447 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onPortStatusMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage)}
450 * @throws InterruptedException
453 public void testOnPortStatusMessage() throws InterruptedException {
454 IMDMessageTranslator<OfHeader, List<DataObject>> objPSms = new PortStatusMessageService();
455 controller.addMessageTranslator(PortStatusMessage.class, 4, objPSms);
457 simulateV13PostHandshakeState(connectionConductor);
459 // Send Port Status messages
460 PortStatusMessageBuilder builder1 = new PortStatusMessageBuilder();
461 builder1.setVersion((short) 4);
462 PortFeatures features = new PortFeatures(true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false);
463 builder1.setPortNo(90L).setReason(PortReason.OFPPRADD).setCurrentFeatures(features);
464 connectionConductor.onPortStatusMessage(builder1.build());
465 synchronized (popListener) {
466 popListener.wait(maxProcessingTimeout);
468 Assert.assertEquals(1, portstatusAddMessageCounter);
469 builder1.setPortNo(90L).setReason(PortReason.OFPPRMODIFY).setCurrentFeatures(features);
470 connectionConductor.onPortStatusMessage(builder1.build());
471 synchronized (popListener) {
472 popListener.wait(maxProcessingTimeout);
474 Assert.assertEquals(1, portstatusModifyMessageCounter);
475 builder1.setPortNo(90L).setReason(PortReason.OFPPRDELETE).setCurrentFeatures(features);
476 connectionConductor.onPortStatusMessage(builder1.build());
477 synchronized (popListener) {
478 popListener.wait(maxProcessingTimeout);
480 Assert.assertEquals(1, portstatusDeleteMessageCounter);
484 * @throws InterruptedException
486 private void executeLater() throws InterruptedException {
491 * @throws InterruptedException
493 private void executeNow() throws InterruptedException {
495 connectionConductor.shutdownPool();
499 * @throws InterruptedException
501 private void execute(boolean join) throws InterruptedException {
502 libSimulation = new Thread(adapter, "junit-adapter");
503 libSimulation.start();
505 libSimulation.join();
509 private static GetFeaturesOutputBuilder getFeatureResponseMsg() {
510 GetFeaturesOutputBuilder getFeaturesOutputBuilder = new GetFeaturesOutputBuilder();
511 getFeaturesOutputBuilder.setDatapathId(new BigInteger("102030405060"));
512 getFeaturesOutputBuilder.setAuxiliaryId((short) 0);
513 getFeaturesOutputBuilder.setBuffers(4L);
514 getFeaturesOutputBuilder.setReserved(0L);
515 getFeaturesOutputBuilder.setTables((short) 2);
516 getFeaturesOutputBuilder.setCapabilities(createCapabilities(84));
518 return getFeaturesOutputBuilder;
524 private static Capabilities createCapabilities(long input) {
525 final Boolean FLOW_STATS = (input & (1 << 0)) != 0;
526 final Boolean TABLE_STATS = (input & (1 << 1)) != 0;
527 final Boolean PORT_STATS = (input & (1 << 2)) != 0;
528 final Boolean GROUP_STATS = (input & (1 << 3)) != 0;
529 final Boolean IP_REASM = (input & (1 << 5)) != 0;
530 final Boolean QUEUE_STATS = (input & (1 << 6)) != 0;
531 final Boolean PORT_BLOCKED = (input & (1 << 8)) != 0;
532 Capabilities capabilities = new Capabilities(FLOW_STATS, GROUP_STATS, IP_REASM,
533 PORT_BLOCKED, PORT_STATS, QUEUE_STATS, TABLE_STATS);
537 public class ExperimenterMessageService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
539 public List<DataObject> translate(SwitchConnectionDistinguisher cookie, SessionContext sw, OfHeader msg) {
540 LOG.debug("Received a packet in Experimenter Service");
541 ConnectionConductorImplTest.this.incrExperimenterMessageCounter();
546 public class PacketInMessageService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
548 public List<DataObject> translate(SwitchConnectionDistinguisher cookie, SessionContext sw, OfHeader msg) {
549 LOG.debug("Received a packet in PacketIn Service");
550 ConnectionConductorImplTest.this.incrPacketinMessageCounter();
555 public class FlowRemovedMessageService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
557 public List<DataObject> translate(SwitchConnectionDistinguisher cookie, SessionContext sw, OfHeader msg) {
558 LOG.debug("Received a packet in FlowRemoved Service");
559 ConnectionConductorImplTest.this.incrFlowremovedMessageCounter();
564 public class PortStatusMessageService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
566 public List<DataObject> translate(SwitchConnectionDistinguisher cookie, SessionContext sw, OfHeader msg) {
567 LOG.debug("Received a packet in PortStatus Service");
568 if ((((PortStatusMessage) msg).getReason().equals(PortReason.OFPPRADD))) {
569 ConnectionConductorImplTest.this.incrPortstatusAddMessageCounter();
570 } else if (((PortStatusMessage) msg).getReason().equals(PortReason.OFPPRDELETE)) {
571 ConnectionConductorImplTest.this.incrPortstatusDeleteMessageCounter();
572 } else if (((PortStatusMessage) msg).getReason().equals(PortReason.OFPPRMODIFY)) {
573 ConnectionConductorImplTest.this.incrPortstatusModifyMessageCounter();
579 public class ErrorMessageService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
581 public List<DataObject> translate(SwitchConnectionDistinguisher cookie, SessionContext sw, OfHeader msg) {
582 LOG.debug("Received a packet in Experimenter Service");
583 ConnectionConductorImplTest.this.incrErrorMessageCounter();
590 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onExperimenterMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessage)}
593 * @throws InterruptedException
596 public void testOnErrorMessage() throws InterruptedException {
597 simulateV13PostHandshakeState(connectionConductor);
599 ErrorMessageBuilder builder1 = new ErrorMessageBuilder();
600 builder1.setVersion((short) 4);
601 builder1.setCode(100);
602 connectionConductor.onErrorMessage(builder1.build());
603 synchronized (popListener) {
604 popListener.wait(maxProcessingTimeout);
606 Assert.assertEquals(1, errorMessageCounter);
607 builder1.setCode(200);
608 connectionConductor.onErrorMessage(builder1.build());
609 synchronized (popListener) {
610 popListener.wait(maxProcessingTimeout);
612 Assert.assertEquals(2, errorMessageCounter);
616 * @return listener mapping for:
618 * <li>experimenter</li>
622 private Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, List<DataObject>>>> assembleTranslatorMapping() {
623 Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, List<DataObject>>>> translatorMapping = new HashMap<>();
626 IMDMessageTranslator<OfHeader, List<DataObject>> objEms = new ExperimenterMessageService();
627 Collection<IMDMessageTranslator<OfHeader, List<DataObject>>> existingValues = new ArrayList<>();
628 existingValues.add(objEms);
629 tKey = new TranslatorKey(4, ExperimenterMessage.class.getName());
630 translatorMapping.put(tKey, existingValues);
631 IMDMessageTranslator<OfHeader, List<DataObject>> objErms = new ErrorMessageService();
632 existingValues.add(objErms);
633 tKey = new TranslatorKey(4, ErrorMessage.class.getName());
634 translatorMapping.put(tKey, existingValues);
635 return translatorMapping;
640 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#processPortStatusMsg(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage)}
642 * Tests for getting features from port status message by port version
644 * <li>features are malformed - one of them is null</li>
645 * <li>mismatch between port version and port features</li>
646 * <li>mismatch between port version and port features</li>
647 * <li>non-existing port version</li>
648 * <li>port version OF 1.0</li>
649 * <li>port version OF 1.3</li>
653 public void testProcessPortStatusMsg() {
654 simulateV13PostHandshakeState(connectionConductor);
656 long portNumber = 90L;
657 long portNumberV10 = 91L;
658 PortStatusMessage msg;
660 PortStatusMessageBuilder builder = new PortStatusMessageBuilder();
661 PortFeatures features = new PortFeatures(true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false);
662 PortFeatures featuresMal = new PortFeatures(true, false, false, false, null, false, false, false, false, false, false, false, false, false, false, false);
663 PortFeaturesV10 featuresV10 = new PortFeaturesV10(true, false, false, false, false, false, false, false, false, false, false, false);
666 builder.setVersion((short) 1).setPortNo(portNumber).setReason(PortReason.OFPPRADD).setCurrentFeatures(featuresMal);
667 connectionConductor.processPortStatusMsg(builder.build());
668 Assert.assertTrue(connectionConductor.getSessionContext().getPortsBandwidth().isEmpty());
669 Assert.assertTrue(connectionConductor.getSessionContext().getPhysicalPorts().isEmpty());
671 //Version-features mismatch
672 builder.setCurrentFeatures(features);
673 connectionConductor.processPortStatusMsg(builder.build());
674 Assert.assertTrue(connectionConductor.getSessionContext().getPortsBandwidth().isEmpty());
675 Assert.assertTrue(connectionConductor.getSessionContext().getPhysicalPorts().isEmpty());
677 //Non existing version
678 builder.setVersion((short) 0);
679 connectionConductor.processPortStatusMsg(builder.build());
680 Assert.assertTrue(connectionConductor.getSessionContext().getPortsBandwidth().isEmpty());
681 Assert.assertTrue(connectionConductor.getSessionContext().getPhysicalPorts().isEmpty());
684 builder.setVersion((short) 4);
685 msg = builder.build();
686 connectionConductor.processPortStatusMsg(builder.build());
687 Assert.assertTrue(connectionConductor.getSessionContext().getPortBandwidth(portNumber));
688 Assert.assertEquals(connectionConductor.getSessionContext().getPhysicalPort(portNumber), msg);
691 builder.setVersion((short) 1).setPortNo(portNumberV10).setCurrentFeatures(null).setCurrentFeaturesV10(featuresV10);
692 msg = builder.build();
693 connectionConductor.processPortStatusMsg(builder.build());
694 Assert.assertTrue(connectionConductor.getSessionContext().getPortBandwidth(portNumberV10));
695 Assert.assertEquals(connectionConductor.getSessionContext().getPhysicalPort(portNumberV10), msg);
698 private void simulateV13PostHandshakeState(ConnectionConductorImpl conductor) {
699 GetFeaturesOutputBuilder featureOutput = getFeatureResponseMsg();
700 conductor.postHandshakeBasic(featureOutput.build(), OFConstants.OFP_VERSION_1_3);