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.core.sal.convertor.ConvertorManager;
46 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManagerFactory;
47 import org.opendaylight.openflowplugin.openflow.md.queue.QueueProcessorLightImpl;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Capabilities;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeatures;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeaturesV10;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortReason;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessageBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessage;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessageBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterMessage;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessage;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessageBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutputBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloMessageBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessage;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessageBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatus;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessageBuilder;
66 import org.opendaylight.yangtools.yang.binding.DataContainer;
67 import org.opendaylight.yangtools.yang.binding.DataObject;
68 import org.slf4j.Logger;
69 import org.slf4j.LoggerFactory;
71 @RunWith(MockitoJUnitRunner.class)
72 public class ConnectionConductorImplTest {
74 protected static final Logger LOG = LoggerFactory
75 .getLogger(ConnectionConductorImplTest.class);
80 private final int maxProcessingTimeout = 500;
82 protected ConnectionAdapterStackImpl adapter;
83 private ConnectionConductorImpl connectionConductor;
84 private MDController controller;
85 private Stack<SwitchTestEvent> eventPlan;
87 private Thread libSimulation;
88 private final ScheduledThreadPoolExecutor pool = new ScheduledThreadPoolExecutor(
91 protected QueueProcessorLightImpl queueProcessor;
93 private PopListenerCountingImpl<DataObject> popListener;
95 private int experimenterMessageCounter;
96 private int packetinMessageCounter;
97 private int flowremovedMessageCounter;
98 private int portstatusAddMessageCounter;
99 private int portstatusDeleteMessageCounter;
100 private int portstatusModifyMessageCounter;
101 private int errorMessageCounter;
104 private ErrorHandlerSimpleImpl errorHandler;
106 private final int expectedErrors = 0;
108 private MessageSpy<DataContainer> messageSpy;
110 HandshakeContext handshakeContext;
111 private ErrorMessageService objErms;
113 public void incrExperimenterMessageCounter() {
114 this.experimenterMessageCounter++;
117 public void incrPacketinMessageCounter() {
118 this.packetinMessageCounter++;
121 public void incrFlowremovedMessageCounter() {
122 this.flowremovedMessageCounter++;
125 public void incrPortstatusAddMessageCounter() {
126 this.portstatusAddMessageCounter++;
129 public void incrPortstatusDeleteMessageCounter() {
130 this.portstatusDeleteMessageCounter++;
133 public void incrPortstatusModifyMessageCounter() {
134 this.portstatusModifyMessageCounter++;
137 public void incrErrorMessageCounter() {
138 this.errorMessageCounter++;
143 * Test for ConnectionConductorFactory#createConductor
145 public void testCreateConductor() {
146 ConnectionConductor connectionConductor = ConnectionConductorFactory.createConductor(adapter, queueProcessor);
147 assertNotNull(connectionConductor);
151 * @throws java.lang.Exception
154 public void setUp() throws Exception {
155 adapter = new ConnectionAdapterStackImpl();
157 popListener = new PopListenerCountingImpl<>();
159 final ConvertorManager convertorManager = ConvertorManagerFactory.createDefaultManager();
160 controller = new MDController(convertorManager);
162 controller.getMessageTranslators().putAll(assembleTranslatorMapping());
164 queueProcessor = new QueueProcessorLightImpl();
165 queueProcessor.setMessageSpy(messageSpy);
166 queueProcessor.setPopListenersMapping(assemblePopListenerMapping());
167 queueProcessor.setTranslatorMapping(controller.getMessageTranslators());
168 queueProcessor.init();
170 connectionConductor = new ConnectionConductorImpl(adapter);
171 connectionConductor.setQueueProcessor(queueProcessor);
172 connectionConductor.setErrorHandler(errorHandler);
173 connectionConductor.init();
174 connectionConductor.setHandshakeContext(handshakeContext);
175 eventPlan = new Stack<>();
176 adapter.setEventPlan(eventPlan);
177 adapter.setProceedTimeout(5000L);
178 adapter.checkListeners();
184 private Map<Class<? extends DataObject>, Collection<PopListener<DataObject>>> assemblePopListenerMapping() {
185 Map<Class<? extends DataObject>, Collection<PopListener<DataObject>>> mapping = new HashMap<>();
186 Collection<PopListener<DataObject>> popListenerBag = new ArrayList<>();
187 popListenerBag.add(popListener);
188 //TODO: add testing registered types
189 mapping.put(DataObject.class, popListenerBag);
194 * @throws java.lang.Exception
197 public void tearDown() throws Exception {
198 if (libSimulation != null) {
199 libSimulation.join();
201 queueProcessor.shutdown();
202 connectionConductor.getHsPool().shutdown();
204 for (Exception problem : adapter.getOccuredExceptions()) {
205 LOG.error("during simulation on adapter side: "
206 + problem.getMessage());
208 Assert.assertEquals(0, adapter.getOccuredExceptions().size());
210 if (LOG.isDebugEnabled()) {
211 if (eventPlan.size() > 0) {
212 LOG.debug("eventPlan size: " + eventPlan.size());
213 for (SwitchTestEvent event : eventPlan) {
214 LOG.debug(" # EVENT:: " + event);
218 Assert.assertTrue("plan is not finished", eventPlan.isEmpty());
222 // logging errors if occurred
223 ArgumentCaptor<Throwable> errorCaptor = ArgumentCaptor.forClass(Throwable.class);
224 Mockito.verify(errorHandler, Mockito.atMost(1)).handleException(
225 errorCaptor.capture(), Matchers.any(SessionContext.class));
226 for (Throwable problem : errorCaptor.getAllValues()) {
227 LOG.warn(problem.getMessage(), problem);
230 Mockito.verify(errorHandler, Mockito.times(expectedErrors)).handleException(
231 Matchers.any(Throwable.class), Matchers.any(SessionContext.class));
236 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onEchoRequestMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessage)}
242 public void testOnEchoRequestMessage() throws Exception {
243 simulateV13PostHandshakeState(connectionConductor);
245 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
246 EventFactory.DEFAULT_VERSION, new EchoRequestMessageBuilder()));
248 EventFactory.createDefaultWaitForRpcEvent(42, "echoReply"));
253 * Test of handshake, covering version negotiation and features.
254 * Switch delivers first helloMessage with default version.
259 public void testHandshake1() throws Exception {
260 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
261 EventFactory.DEFAULT_VERSION, new HelloMessageBuilder()));
262 eventPlan.add(0, EventFactory.createDefaultWaitForAllEvent(
263 EventFactory.createDefaultWaitForRpcEvent(43, "helloReply"),
264 EventFactory.createDefaultWaitForRpcEvent(44, "getFeatures")));
265 eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(44,
266 EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
271 Assert.assertEquals(ConnectionConductor.CONDUCTOR_STATE.WORKING,
272 connectionConductor.getConductorState());
273 Assert.assertEquals((short) 0x04, connectionConductor.getVersion()
278 * Test of handshake, covering version negotiation and features.
279 * Controller sends first helloMessage with default version
284 public void testHandshake1SwitchStarts() throws Exception {
285 eventPlan.add(0, EventFactory.createConnectionReadyCallback(connectionConductor));
286 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(21, "helloReply"));
287 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
288 EventFactory.DEFAULT_VERSION, new HelloMessageBuilder()));
289 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(43, "getFeatures"));
290 eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(43,
291 EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
295 Assert.assertEquals(ConnectionConductor.CONDUCTOR_STATE.WORKING,
296 connectionConductor.getConductorState());
297 Assert.assertEquals((short) 0x04, connectionConductor.getVersion()
302 * Test of handshake, covering version negotiation and features.
303 * Switch delivers first helloMessage with version 0x05
304 * and negotiates following versions: 0x03, 0x01
309 public void testHandshake2() throws Exception {
310 connectionConductor.setBitmapNegotiationEnable(false);
311 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
312 (short) 0x05, new HelloMessageBuilder()));
314 EventFactory.createDefaultWaitForRpcEvent(43, "helloReply"));
315 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(43L,
316 (short) 0x03, new HelloMessageBuilder()));
318 EventFactory.createDefaultWaitForRpcEvent(44, "helloReply"));
319 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(44L,
320 (short) 0x01, new HelloMessageBuilder()));
322 EventFactory.createDefaultWaitForRpcEvent(45, "getFeatures"));
324 eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(45,
325 (short) 0x01, getFeatureResponseMsg()));
329 Assert.assertEquals(ConnectionConductor.CONDUCTOR_STATE.WORKING,
330 connectionConductor.getConductorState());
331 Assert.assertEquals((short) 0x01, connectionConductor.getVersion()
336 * Test of handshake, covering version negotiation and features.
337 * Controller sends first helloMessage with default version
338 * and switch negotiates following versions: 0x05, 0x03, 0x01
343 public void testHandshake2SwitchStarts() throws Exception {
344 connectionConductor.setBitmapNegotiationEnable(false);
345 eventPlan.add(0, EventFactory.createConnectionReadyCallback(connectionConductor));
347 EventFactory.createDefaultWaitForRpcEvent(21, "helloReply"));
348 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
349 (short) 0x05, new HelloMessageBuilder()));
350 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(43L,
351 (short) 0x03, new HelloMessageBuilder()));
353 EventFactory.createDefaultWaitForRpcEvent(44, "helloReply"));
354 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(44L,
355 (short) 0x01, new HelloMessageBuilder()));
357 EventFactory.createDefaultWaitForRpcEvent(45, "getFeatures"));
359 eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(45,
360 (short) 0x01, getFeatureResponseMsg()));
364 Assert.assertEquals(ConnectionConductor.CONDUCTOR_STATE.WORKING,
365 connectionConductor.getConductorState());
366 Assert.assertEquals((short) 0x01, connectionConductor.getVersion()
372 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onFlowRemovedMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessage)}
375 * @throws InterruptedException
378 public void testOnFlowRemovedMessage() throws InterruptedException {
379 FlowRemovedMessageService objFms = new FlowRemovedMessageService();
380 controller.addMessageTranslator(FlowRemovedMessage.class, 4, objFms);
382 simulateV13PostHandshakeState(connectionConductor);
383 objFms.resetLatch(2);
385 // Now send Flow Removed messages
386 FlowRemovedMessageBuilder builder1 = new FlowRemovedMessageBuilder();
387 builder1.setVersion((short) 4);
389 connectionConductor.onFlowRemovedMessage(builder1.build());
390 LOG.debug("about to wait for popListener");
392 connectionConductor.onFlowRemovedMessage(builder1.build());
394 flushMessageProcessing();
395 Assert.assertTrue(objFms.await(maxProcessingTimeout, TimeUnit.MILLISECONDS));
396 Assert.assertEquals(2, flowremovedMessageCounter);
401 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onMultipartReplyMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage)}
405 public void testOnMultipartReplyMessage() {
406 // fail("Not yet implemented");
412 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onPacketInMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessage)}
415 * @throws InterruptedException
418 public void testOnPacketInMessage() throws InterruptedException {
419 PacketInMessageService objPms = new PacketInMessageService();
420 controller.addMessageTranslator(PacketInMessage.class, 4, objPms);
422 simulateV13PostHandshakeState(connectionConductor);
425 PacketInMessageBuilder builder1 = new PacketInMessageBuilder();
426 builder1.setVersion((short) 4);
427 builder1.setBufferId((long) 1);
428 connectionConductor.onPacketInMessage(builder1.build());
429 builder1.setBufferId((long) 2);
430 connectionConductor.onPacketInMessage(builder1.build());
432 flushMessageProcessing();
433 Assert.assertTrue(objPms.await(maxProcessingTimeout, TimeUnit.MILLISECONDS));
434 Assert.assertEquals(2, packetinMessageCounter);
439 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onPortStatusMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage)}
442 * @throws InterruptedException
445 public void testOnPortStatusMessage() throws InterruptedException {
446 PortStatusMessageService objPSms = new PortStatusMessageService();
447 controller.addMessageTranslator(PortStatusMessage.class, 4, objPSms);
449 simulateV13PostHandshakeState(connectionConductor);
451 // Send Port Status messages
452 PortStatusMessageBuilder builder1 = new PortStatusMessageBuilder();
453 builder1.setVersion((short) 4);
454 PortFeatures features = new PortFeatures(true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false);
455 builder1.setPortNo(90L).setReason(PortReason.OFPPRADD).setCurrentFeatures(features);
456 objPSms.resetLatch(3);
457 LOG.debug("sending port message");
458 connectionConductor.onPortStatusMessage(builder1.build());
459 builder1.setPortNo(90L).setReason(PortReason.OFPPRMODIFY).setCurrentFeatures(features);
460 connectionConductor.onPortStatusMessage(builder1.build());
461 builder1.setPortNo(90L).setReason(PortReason.OFPPRDELETE).setCurrentFeatures(features);
462 connectionConductor.onPortStatusMessage(builder1.build());
464 flushMessageProcessing();
465 Assert.assertTrue(objPSms.await(maxProcessingTimeout, TimeUnit.MILLISECONDS));
466 Assert.assertEquals(1, portstatusModifyMessageCounter);
467 Assert.assertEquals(1, portstatusAddMessageCounter);
468 Assert.assertEquals(1, portstatusDeleteMessageCounter);
471 private void flushMessageProcessing() throws InterruptedException {
472 // make sure that harvester sleeps deeply
473 Thread.sleep(maxProcessingTimeout);
475 queueProcessor.getHarvesterHandle().ping();
479 * @throws InterruptedException
481 private void executeLater() throws InterruptedException {
486 * @throws InterruptedException
488 private void executeNow() throws InterruptedException {
490 connectionConductor.getHsPool().shutdown();
494 * @throws InterruptedException
496 private void execute(final boolean join) throws InterruptedException {
497 libSimulation = new Thread(adapter, "junit-adapter");
498 libSimulation.start();
500 libSimulation.join();
504 private static GetFeaturesOutputBuilder getFeatureResponseMsg() {
505 GetFeaturesOutputBuilder getFeaturesOutputBuilder = new GetFeaturesOutputBuilder();
506 getFeaturesOutputBuilder.setDatapathId(new BigInteger("102030405060"));
507 getFeaturesOutputBuilder.setAuxiliaryId((short) 0);
508 getFeaturesOutputBuilder.setBuffers(4L);
509 getFeaturesOutputBuilder.setReserved(0L);
510 getFeaturesOutputBuilder.setTables((short) 2);
511 getFeaturesOutputBuilder.setCapabilities(createCapabilities(84));
513 return getFeaturesOutputBuilder;
519 private static Capabilities createCapabilities(final long input) {
520 final Boolean FLOW_STATS = (input & (1 << 0)) != 0;
521 final Boolean TABLE_STATS = (input & (1 << 1)) != 0;
522 final Boolean PORT_STATS = (input & (1 << 2)) != 0;
523 final Boolean GROUP_STATS = (input & (1 << 3)) != 0;
524 final Boolean IP_REASM = (input & (1 << 5)) != 0;
525 final Boolean QUEUE_STATS = (input & (1 << 6)) != 0;
526 final Boolean PORT_BLOCKED = (input & (1 << 8)) != 0;
527 Capabilities capabilities = new Capabilities(FLOW_STATS, GROUP_STATS, IP_REASM,
528 PORT_BLOCKED, PORT_STATS, QUEUE_STATS, TABLE_STATS);
532 public abstract class ProcessingLatchService {
533 private CountDownLatch processingLatch = new CountDownLatch(0);
535 public void resetLatch(int passAmount) {
536 processingLatch = new CountDownLatch(passAmount);
539 protected void countDown() {
540 processingLatch.countDown();
543 public boolean await(long timeout, TimeUnit unit) throws InterruptedException {
544 return processingLatch.await(timeout, unit);
548 public class ExperimenterMessageService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
550 public List<DataObject> translate(final SwitchConnectionDistinguisher cookie, final SessionContext sw, final OfHeader msg) {
551 LOG.debug("Received a packet in Experimenter Service");
552 ConnectionConductorImplTest.this.incrExperimenterMessageCounter();
557 public class PacketInMessageService extends ProcessingLatchService 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 PacketIn Service");
561 ConnectionConductorImplTest.this.incrPacketinMessageCounter();
567 public class FlowRemovedMessageService extends ProcessingLatchService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
569 public List<DataObject> translate(final SwitchConnectionDistinguisher cookie, final SessionContext sw, final OfHeader msg) {
570 LOG.debug("Received a packet in FlowRemoved Service");
571 ConnectionConductorImplTest.this.incrFlowremovedMessageCounter();
577 public class PortStatusMessageService extends ProcessingLatchService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
579 public List<DataObject> translate(final SwitchConnectionDistinguisher cookie, final SessionContext sw, final OfHeader msg) {
580 LOG.debug("Received a packet in PortStatus Service");
581 if ((((PortStatusMessage) msg).getReason().equals(PortReason.OFPPRADD))) {
582 ConnectionConductorImplTest.this.incrPortstatusAddMessageCounter();
583 } else if (((PortStatusMessage) msg).getReason().equals(PortReason.OFPPRDELETE)) {
584 ConnectionConductorImplTest.this.incrPortstatusDeleteMessageCounter();
585 } else if (((PortStatusMessage) msg).getReason().equals(PortReason.OFPPRMODIFY)) {
586 ConnectionConductorImplTest.this.incrPortstatusModifyMessageCounter();
593 public class ErrorMessageService extends ProcessingLatchService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
595 public List<DataObject> translate(final SwitchConnectionDistinguisher cookie, final SessionContext sw, final OfHeader msg) {
596 LOG.debug("Received a packet in Experimenter Service");
597 ConnectionConductorImplTest.this.incrErrorMessageCounter();
605 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onExperimenterMessage(ExperimenterMessage)}
608 * @throws InterruptedException
611 public void testOnErrorMessage() throws InterruptedException {
612 simulateV13PostHandshakeState(connectionConductor);
613 final int messageAmount = 2;
615 objErms.resetLatch(messageAmount);
616 ErrorMessageBuilder builder1 = new ErrorMessageBuilder();
617 builder1.setVersion((short) 4);
618 builder1.setCode(100);
619 connectionConductor.onErrorMessage(builder1.build());
620 builder1.setCode(200);
621 connectionConductor.onErrorMessage(builder1.build());
623 flushMessageProcessing();
624 Assert.assertTrue(objErms.await(maxProcessingTimeout, TimeUnit.MILLISECONDS));
625 Assert.assertEquals(messageAmount, errorMessageCounter);
629 * @return listener mapping for:
631 * <li>experimenter</li>
635 private Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, List<DataObject>>>> assembleTranslatorMapping() {
636 Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, List<DataObject>>>> translatorMapping = new HashMap<>();
639 IMDMessageTranslator<OfHeader, List<DataObject>> objEms = new ExperimenterMessageService();
640 Collection<IMDMessageTranslator<OfHeader, List<DataObject>>> existingValues = new ArrayList<>();
641 existingValues.add(objEms);
642 tKey = new TranslatorKey(4, ExperimenterMessage.class.getName());
643 translatorMapping.put(tKey, existingValues);
644 objErms = new ErrorMessageService();
645 existingValues.add(objErms);
646 tKey = new TranslatorKey(4, ErrorMessage.class.getName());
647 translatorMapping.put(tKey, existingValues);
648 return translatorMapping;
653 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#processPortStatusMsg(PortStatus)}
655 * Tests for getting features from port status message by port version
657 * <li>features are malformed - one of them is null</li>
658 * <li>mismatch between port version and port features</li>
659 * <li>mismatch between port version and port features</li>
660 * <li>non-existing port version</li>
661 * <li>port version OF 1.0</li>
662 * <li>port version OF 1.3</li>
666 public void testProcessPortStatusMsg() {
667 simulateV13PostHandshakeState(connectionConductor);
669 long portNumber = 90L;
670 long portNumberV10 = 91L;
671 PortStatusMessage msg;
673 PortStatusMessageBuilder builder = new PortStatusMessageBuilder();
674 PortFeatures features = new PortFeatures(true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false);
675 PortFeatures featuresMal = new PortFeatures(true, false, false, false, null, false, false, false, false, false, false, false, false, false, false, false);
676 PortFeaturesV10 featuresV10 = new PortFeaturesV10(true, false, false, false, false, false, false, false, false, false, false, false);
679 builder.setVersion((short) 1).setPortNo(portNumber).setReason(PortReason.OFPPRADD).setCurrentFeatures(featuresMal);
680 connectionConductor.processPortStatusMsg(builder.build());
681 Assert.assertTrue(connectionConductor.getSessionContext().getPortsBandwidth().isEmpty());
682 Assert.assertTrue(connectionConductor.getSessionContext().getPhysicalPorts().isEmpty());
684 //Version-features mismatch
685 builder.setCurrentFeatures(features);
686 connectionConductor.processPortStatusMsg(builder.build());
687 Assert.assertTrue(connectionConductor.getSessionContext().getPortsBandwidth().isEmpty());
688 Assert.assertTrue(connectionConductor.getSessionContext().getPhysicalPorts().isEmpty());
690 //Non existing version
691 builder.setVersion((short) 0);
692 connectionConductor.processPortStatusMsg(builder.build());
693 Assert.assertTrue(connectionConductor.getSessionContext().getPortsBandwidth().isEmpty());
694 Assert.assertTrue(connectionConductor.getSessionContext().getPhysicalPorts().isEmpty());
697 builder.setVersion((short) 4);
698 msg = builder.build();
699 connectionConductor.processPortStatusMsg(builder.build());
700 Assert.assertTrue(connectionConductor.getSessionContext().getPortBandwidth(portNumber));
701 Assert.assertEquals(connectionConductor.getSessionContext().getPhysicalPort(portNumber), msg);
704 builder.setVersion((short) 1).setPortNo(portNumberV10).setCurrentFeatures(null).setCurrentFeaturesV10(featuresV10);
705 msg = builder.build();
706 connectionConductor.processPortStatusMsg(builder.build());
707 Assert.assertTrue(connectionConductor.getSessionContext().getPortBandwidth(portNumberV10));
708 Assert.assertEquals(connectionConductor.getSessionContext().getPhysicalPort(portNumberV10), msg);
713 public void testHandshakeFailOperations(){
714 connectionConductor.onHandshakeFailure();
715 connectionConductor.checkState(ConnectionConductor.CONDUCTOR_STATE.RIP);
717 private static void simulateV13PostHandshakeState(final ConnectionConductorImpl conductor) {
718 GetFeaturesOutputBuilder featureOutput = getFeatureResponseMsg();
719 conductor.postHandshakeBasic(featureOutput.build(), OFConstants.OFP_VERSION_1_3);
720 LOG.debug("simulating post handshake event done");