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;
12 import java.math.BigInteger;
13 import java.util.ArrayList;
14 import java.util.Collection;
15 import java.util.HashMap;
16 import java.util.List;
18 import java.util.Stack;
19 import java.util.concurrent.ScheduledThreadPoolExecutor;
20 import org.junit.After;
21 import org.junit.Assert;
22 import org.junit.Before;
23 import org.junit.Test;
24 import org.junit.runner.RunWith;
25 import org.mockito.ArgumentCaptor;
26 import org.mockito.Matchers;
27 import org.mockito.Mock;
28 import org.mockito.Mockito;
29 import org.mockito.runners.MockitoJUnitRunner;
30 import org.opendaylight.openflowplugin.api.OFConstants;
31 import org.opendaylight.openflowplugin.api.openflow.connection.HandshakeContext;
32 import org.opendaylight.openflowplugin.api.openflow.md.core.ConnectionConductor;
33 import org.opendaylight.openflowplugin.api.openflow.md.core.IMDMessageTranslator;
34 import org.opendaylight.openflowplugin.api.openflow.md.core.SwitchConnectionDistinguisher;
35 import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey;
36 import org.opendaylight.openflowplugin.api.openflow.md.core.session.SessionContext;
37 import org.opendaylight.openflowplugin.api.openflow.md.queue.PopListener;
38 import org.opendaylight.openflowplugin.api.openflow.statistics.MessageSpy;
39 import org.opendaylight.openflowplugin.openflow.md.core.plan.ConnectionAdapterStackImpl;
40 import org.opendaylight.openflowplugin.openflow.md.core.plan.EventFactory;
41 import org.opendaylight.openflowplugin.openflow.md.core.plan.SwitchTestEvent;
42 import org.opendaylight.openflowplugin.openflow.md.queue.QueueProcessorLightImpl;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Capabilities;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeatures;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeaturesV10;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortReason;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessageBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessage;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessageBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterMessage;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessage;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessageBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutputBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloMessageBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessage;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessageBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatus;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessageBuilder;
61 import org.opendaylight.yangtools.yang.binding.DataContainer;
62 import org.opendaylight.yangtools.yang.binding.DataObject;
63 import org.slf4j.Logger;
64 import org.slf4j.LoggerFactory;
66 @RunWith(MockitoJUnitRunner.class)
67 public class ConnectionConductorImplTest {
69 protected static final Logger LOG = LoggerFactory
70 .getLogger(ConnectionConductorImplTest.class);
75 private final int maxProcessingTimeout = 500;
77 protected ConnectionAdapterStackImpl adapter;
78 private ConnectionConductorImpl connectionConductor;
79 private MDController controller;
80 private Stack<SwitchTestEvent> eventPlan;
82 private Thread libSimulation;
83 private final ScheduledThreadPoolExecutor pool = new ScheduledThreadPoolExecutor(
86 protected QueueProcessorLightImpl queueProcessor;
88 private PopListener<DataObject> popListener;
90 private int experimenterMessageCounter;
91 private int packetinMessageCounter;
92 private int flowremovedMessageCounter;
93 private int portstatusAddMessageCounter;
94 private int portstatusDeleteMessageCounter;
95 private int portstatusModifyMessageCounter;
96 private int errorMessageCounter;
99 private ErrorHandlerSimpleImpl errorHandler;
101 private final int expectedErrors = 0;
103 private MessageSpy<DataContainer> messageSpy;
105 HandshakeContext handshakeContext;
107 public void incrExperimenterMessageCounter() {
108 this.experimenterMessageCounter++;
111 public void incrPacketinMessageCounter() {
112 this.packetinMessageCounter++;
115 public void incrFlowremovedMessageCounter() {
116 this.flowremovedMessageCounter++;
119 public void incrPortstatusAddMessageCounter() {
120 this.portstatusAddMessageCounter++;
123 public void incrPortstatusDeleteMessageCounter() {
124 this.portstatusDeleteMessageCounter++;
127 public void incrPortstatusModifyMessageCounter() {
128 this.portstatusModifyMessageCounter++;
131 public void incrErrorMessageCounter() {
132 this.errorMessageCounter++;
137 * Test for ConnectionConductorFactory#createConductor
139 public void testCreateConductor() {
140 ConnectionConductor connectionConductor = ConnectionConductorFactory.createConductor(adapter, queueProcessor);
141 assertNotNull(connectionConductor);
145 * @throws java.lang.Exception
148 public void setUp() throws Exception {
149 adapter = new ConnectionAdapterStackImpl();
151 popListener = new PopListenerCountingImpl<>();
153 controller = new MDController();
155 controller.getMessageTranslators().putAll(assembleTranslatorMapping());
157 queueProcessor = new QueueProcessorLightImpl();
158 queueProcessor.setMessageSpy(messageSpy);
159 queueProcessor.setPopListenersMapping(assemblePopListenerMapping());
160 queueProcessor.setTranslatorMapping(controller.getMessageTranslators());
161 queueProcessor.init();
163 connectionConductor = new ConnectionConductorImpl(adapter);
164 connectionConductor.setQueueProcessor(queueProcessor);
165 connectionConductor.setErrorHandler(errorHandler);
166 connectionConductor.init();
167 connectionConductor.setHandshakeContext(handshakeContext);
168 eventPlan = new Stack<>();
169 adapter.setEventPlan(eventPlan);
170 adapter.setProceedTimeout(5000L);
171 adapter.checkListeners();
177 private Map<Class<? extends DataObject>, Collection<PopListener<DataObject>>> assemblePopListenerMapping() {
178 Map<Class<? extends DataObject>, Collection<PopListener<DataObject>>> mapping = new HashMap<>();
179 Collection<PopListener<DataObject>> popListenerBag = new ArrayList<>();
180 popListenerBag.add(popListener);
181 //TODO: add testing registered types
182 mapping.put(DataObject.class, popListenerBag);
187 * @throws java.lang.Exception
190 public void tearDown() throws Exception {
191 if (libSimulation != null) {
192 libSimulation.join();
194 queueProcessor.shutdown();
195 connectionConductor.getHsPool().shutdown();
197 for (Exception problem : adapter.getOccuredExceptions()) {
198 LOG.error("during simulation on adapter side: "
199 + problem.getMessage());
201 Assert.assertEquals(0, adapter.getOccuredExceptions().size());
203 if (LOG.isDebugEnabled()) {
204 if (eventPlan.size() > 0) {
205 LOG.debug("eventPlan size: " + eventPlan.size());
206 for (SwitchTestEvent event : eventPlan) {
207 LOG.debug(" # EVENT:: " + event.toString());
211 Assert.assertTrue("plan is not finished", eventPlan.isEmpty());
215 // logging errors if occurred
216 ArgumentCaptor<Throwable> errorCaptor = ArgumentCaptor.forClass(Throwable.class);
217 Mockito.verify(errorHandler, Mockito.atMost(1)).handleException(
218 errorCaptor.capture(), Matchers.any(SessionContext.class));
219 for (Throwable problem : errorCaptor.getAllValues()) {
220 LOG.warn(problem.getMessage(), problem);
223 Mockito.verify(errorHandler, Mockito.times(expectedErrors)).handleException(
224 Matchers.any(Throwable.class), Matchers.any(SessionContext.class));
229 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onEchoRequestMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessage)}
235 public void testOnEchoRequestMessage() throws Exception {
236 simulateV13PostHandshakeState(connectionConductor);
238 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
239 EventFactory.DEFAULT_VERSION, new EchoRequestMessageBuilder()));
241 EventFactory.createDefaultWaitForRpcEvent(42, "echoReply"));
246 * Test of handshake, covering version negotiation and features.
247 * Switch delivers first helloMessage with default version.
252 public void testHandshake1() throws Exception {
253 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
254 EventFactory.DEFAULT_VERSION, new HelloMessageBuilder()));
255 eventPlan.add(0, EventFactory.createDefaultWaitForAllEvent(
256 EventFactory.createDefaultWaitForRpcEvent(43, "helloReply"),
257 EventFactory.createDefaultWaitForRpcEvent(44, "getFeatures")));
258 eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(44,
259 EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
262 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
263 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
266 Assert.assertEquals(ConnectionConductor.CONDUCTOR_STATE.WORKING,
267 connectionConductor.getConductorState());
268 Assert.assertEquals((short) 0x04, connectionConductor.getVersion()
273 * Test of handshake, covering version negotiation and features.
274 * Controller sends first helloMessage with default version
279 public void testHandshake1SwitchStarts() throws Exception {
280 eventPlan.add(0, EventFactory.createConnectionReadyCallback(connectionConductor));
281 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(21, "helloReply"));
282 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
283 EventFactory.DEFAULT_VERSION, new HelloMessageBuilder()));
284 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(43, "getFeatures"));
285 eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(43,
286 EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
289 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
290 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
294 Assert.assertEquals(ConnectionConductor.CONDUCTOR_STATE.WORKING,
295 connectionConductor.getConductorState());
296 Assert.assertEquals((short) 0x04, connectionConductor.getVersion()
301 * Test of handshake, covering version negotiation and features.
302 * Switch delivers first helloMessage with version 0x05
303 * and negotiates following versions: 0x03, 0x01
308 public void testHandshake2() throws Exception {
309 connectionConductor.setBitmapNegotiationEnable(false);
310 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
311 (short) 0x05, new HelloMessageBuilder()));
313 EventFactory.createDefaultWaitForRpcEvent(43, "helloReply"));
314 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(43L,
315 (short) 0x03, new HelloMessageBuilder()));
317 EventFactory.createDefaultWaitForRpcEvent(44, "helloReply"));
318 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(44L,
319 (short) 0x01, new HelloMessageBuilder()));
321 EventFactory.createDefaultWaitForRpcEvent(45, "getFeatures"));
323 eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(45,
324 (short) 0x01, getFeatureResponseMsg()));
327 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
331 Assert.assertEquals(ConnectionConductor.CONDUCTOR_STATE.WORKING,
332 connectionConductor.getConductorState());
333 Assert.assertEquals((short) 0x01, connectionConductor.getVersion()
338 * Test of handshake, covering version negotiation and features.
339 * Controller sends first helloMessage with default version
340 * and switch negotiates following versions: 0x05, 0x03, 0x01
345 public void testHandshake2SwitchStarts() throws Exception {
346 connectionConductor.setBitmapNegotiationEnable(false);
347 eventPlan.add(0, EventFactory.createConnectionReadyCallback(connectionConductor));
349 EventFactory.createDefaultWaitForRpcEvent(21, "helloReply"));
350 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
351 (short) 0x05, new HelloMessageBuilder()));
352 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(43L,
353 (short) 0x03, new HelloMessageBuilder()));
355 EventFactory.createDefaultWaitForRpcEvent(44, "helloReply"));
356 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(44L,
357 (short) 0x01, new HelloMessageBuilder()));
359 EventFactory.createDefaultWaitForRpcEvent(45, "getFeatures"));
361 eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(45,
362 (short) 0x01, getFeatureResponseMsg()));
365 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
369 Assert.assertEquals(ConnectionConductor.CONDUCTOR_STATE.WORKING,
370 connectionConductor.getConductorState());
371 Assert.assertEquals((short) 0x01, connectionConductor.getVersion()
377 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onFlowRemovedMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessage)}
380 * @throws InterruptedException
383 public void testOnFlowRemovedMessage() throws InterruptedException {
384 IMDMessageTranslator<OfHeader, List<DataObject>> objFms = new FlowRemovedMessageService();
385 controller.addMessageTranslator(FlowRemovedMessage.class, 4, objFms);
387 simulateV13PostHandshakeState(connectionConductor);
389 // Now send Flow Removed messages
390 FlowRemovedMessageBuilder builder1 = new FlowRemovedMessageBuilder();
391 builder1.setVersion((short) 4);
393 connectionConductor.onFlowRemovedMessage(builder1.build());
394 synchronized (popListener) {
395 LOG.debug("about to wait for popListener");
396 popListener.wait(maxProcessingTimeout);
398 Assert.assertEquals(1, flowremovedMessageCounter);
400 connectionConductor.onFlowRemovedMessage(builder1.build());
401 synchronized (popListener) {
402 popListener.wait(maxProcessingTimeout);
404 Assert.assertEquals(2, flowremovedMessageCounter);
409 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onMultipartReplyMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage)}
413 public void testOnMultipartReplyMessage() {
414 // fail("Not yet implemented");
420 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onPacketInMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessage)}
423 * @throws InterruptedException
426 public void testOnPacketInMessage() throws InterruptedException {
427 IMDMessageTranslator<OfHeader, List<DataObject>> objPms = new PacketInMessageService();
428 controller.addMessageTranslator(PacketInMessage.class, 4, objPms);
430 simulateV13PostHandshakeState(connectionConductor);
433 PacketInMessageBuilder builder1 = new PacketInMessageBuilder();
434 builder1.setVersion((short) 4);
435 builder1.setBufferId((long) 1);
436 connectionConductor.onPacketInMessage(builder1.build());
437 synchronized (popListener) {
438 popListener.wait(maxProcessingTimeout);
440 Assert.assertEquals(1, packetinMessageCounter);
441 builder1.setBufferId((long) 2);
442 connectionConductor.onPacketInMessage(builder1.build());
443 synchronized (popListener) {
444 popListener.wait(maxProcessingTimeout);
446 Assert.assertEquals(2, packetinMessageCounter);
451 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onPortStatusMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage)}
454 * @throws InterruptedException
457 public void testOnPortStatusMessage() throws InterruptedException {
458 IMDMessageTranslator<OfHeader, List<DataObject>> objPSms = new PortStatusMessageService();
459 controller.addMessageTranslator(PortStatusMessage.class, 4, objPSms);
461 simulateV13PostHandshakeState(connectionConductor);
463 // Send Port Status messages
464 PortStatusMessageBuilder builder1 = new PortStatusMessageBuilder();
465 builder1.setVersion((short) 4);
466 PortFeatures features = new PortFeatures(true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false);
467 builder1.setPortNo(90L).setReason(PortReason.OFPPRADD).setCurrentFeatures(features);
468 connectionConductor.onPortStatusMessage(builder1.build());
469 synchronized (popListener) {
470 popListener.wait(maxProcessingTimeout);
472 Assert.assertEquals(1, portstatusAddMessageCounter);
473 builder1.setPortNo(90L).setReason(PortReason.OFPPRMODIFY).setCurrentFeatures(features);
474 connectionConductor.onPortStatusMessage(builder1.build());
475 synchronized (popListener) {
476 popListener.wait(maxProcessingTimeout);
478 Assert.assertEquals(1, portstatusModifyMessageCounter);
479 builder1.setPortNo(90L).setReason(PortReason.OFPPRDELETE).setCurrentFeatures(features);
480 connectionConductor.onPortStatusMessage(builder1.build());
481 synchronized (popListener) {
482 popListener.wait(maxProcessingTimeout);
484 Assert.assertEquals(1, portstatusDeleteMessageCounter);
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 class ExperimenterMessageService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
543 public List<DataObject> translate(final SwitchConnectionDistinguisher cookie, final SessionContext sw, final OfHeader msg) {
544 LOG.debug("Received a packet in Experimenter Service");
545 ConnectionConductorImplTest.this.incrExperimenterMessageCounter();
550 public class PacketInMessageService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
552 public List<DataObject> translate(final SwitchConnectionDistinguisher cookie, final SessionContext sw, final OfHeader msg) {
553 LOG.debug("Received a packet in PacketIn Service");
554 ConnectionConductorImplTest.this.incrPacketinMessageCounter();
559 public class FlowRemovedMessageService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
561 public List<DataObject> translate(final SwitchConnectionDistinguisher cookie, final SessionContext sw, final OfHeader msg) {
562 LOG.debug("Received a packet in FlowRemoved Service");
563 ConnectionConductorImplTest.this.incrFlowremovedMessageCounter();
568 public class PortStatusMessageService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
570 public List<DataObject> translate(final SwitchConnectionDistinguisher cookie, final SessionContext sw, final OfHeader msg) {
571 LOG.debug("Received a packet in PortStatus Service");
572 if ((((PortStatusMessage) msg).getReason().equals(PortReason.OFPPRADD))) {
573 ConnectionConductorImplTest.this.incrPortstatusAddMessageCounter();
574 } else if (((PortStatusMessage) msg).getReason().equals(PortReason.OFPPRDELETE)) {
575 ConnectionConductorImplTest.this.incrPortstatusDeleteMessageCounter();
576 } else if (((PortStatusMessage) msg).getReason().equals(PortReason.OFPPRMODIFY)) {
577 ConnectionConductorImplTest.this.incrPortstatusModifyMessageCounter();
583 public class ErrorMessageService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
585 public List<DataObject> translate(final SwitchConnectionDistinguisher cookie, final SessionContext sw, final OfHeader msg) {
586 LOG.debug("Received a packet in Experimenter Service");
587 ConnectionConductorImplTest.this.incrErrorMessageCounter();
594 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onExperimenterMessage(ExperimenterMessage)}
597 * @throws InterruptedException
600 public void testOnErrorMessage() throws InterruptedException {
601 simulateV13PostHandshakeState(connectionConductor);
603 ErrorMessageBuilder builder1 = new ErrorMessageBuilder();
604 builder1.setVersion((short) 4);
605 builder1.setCode(100);
606 connectionConductor.onErrorMessage(builder1.build());
607 synchronized (popListener) {
608 popListener.wait(maxProcessingTimeout);
610 Assert.assertEquals(1, errorMessageCounter);
611 builder1.setCode(200);
612 connectionConductor.onErrorMessage(builder1.build());
613 synchronized (popListener) {
614 popListener.wait(maxProcessingTimeout);
616 Assert.assertEquals(2, errorMessageCounter);
620 * @return listener mapping for:
622 * <li>experimenter</li>
626 private Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, List<DataObject>>>> assembleTranslatorMapping() {
627 Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, List<DataObject>>>> translatorMapping = new HashMap<>();
630 IMDMessageTranslator<OfHeader, List<DataObject>> objEms = new ExperimenterMessageService();
631 Collection<IMDMessageTranslator<OfHeader, List<DataObject>>> existingValues = new ArrayList<>();
632 existingValues.add(objEms);
633 tKey = new TranslatorKey(4, ExperimenterMessage.class.getName());
634 translatorMapping.put(tKey, existingValues);
635 IMDMessageTranslator<OfHeader, List<DataObject>> objErms = new ErrorMessageService();
636 existingValues.add(objErms);
637 tKey = new TranslatorKey(4, ErrorMessage.class.getName());
638 translatorMapping.put(tKey, existingValues);
639 return translatorMapping;
644 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#processPortStatusMsg(PortStatus)}
646 * Tests for getting features from port status message by port version
648 * <li>features are malformed - one of them is null</li>
649 * <li>mismatch between port version and port features</li>
650 * <li>mismatch between port version and port features</li>
651 * <li>non-existing port version</li>
652 * <li>port version OF 1.0</li>
653 * <li>port version OF 1.3</li>
657 public void testProcessPortStatusMsg() {
658 simulateV13PostHandshakeState(connectionConductor);
660 long portNumber = 90L;
661 long portNumberV10 = 91L;
662 PortStatusMessage msg;
664 PortStatusMessageBuilder builder = new PortStatusMessageBuilder();
665 PortFeatures features = new PortFeatures(true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false);
666 PortFeatures featuresMal = new PortFeatures(true, false, false, false, null, false, false, false, false, false, false, false, false, false, false, false);
667 PortFeaturesV10 featuresV10 = new PortFeaturesV10(true, false, false, false, false, false, false, false, false, false, false, false);
670 builder.setVersion((short) 1).setPortNo(portNumber).setReason(PortReason.OFPPRADD).setCurrentFeatures(featuresMal);
671 connectionConductor.processPortStatusMsg(builder.build());
672 Assert.assertTrue(connectionConductor.getSessionContext().getPortsBandwidth().isEmpty());
673 Assert.assertTrue(connectionConductor.getSessionContext().getPhysicalPorts().isEmpty());
675 //Version-features mismatch
676 builder.setCurrentFeatures(features);
677 connectionConductor.processPortStatusMsg(builder.build());
678 Assert.assertTrue(connectionConductor.getSessionContext().getPortsBandwidth().isEmpty());
679 Assert.assertTrue(connectionConductor.getSessionContext().getPhysicalPorts().isEmpty());
681 //Non existing version
682 builder.setVersion((short) 0);
683 connectionConductor.processPortStatusMsg(builder.build());
684 Assert.assertTrue(connectionConductor.getSessionContext().getPortsBandwidth().isEmpty());
685 Assert.assertTrue(connectionConductor.getSessionContext().getPhysicalPorts().isEmpty());
688 builder.setVersion((short) 4);
689 msg = builder.build();
690 connectionConductor.processPortStatusMsg(builder.build());
691 Assert.assertTrue(connectionConductor.getSessionContext().getPortBandwidth(portNumber));
692 Assert.assertEquals(connectionConductor.getSessionContext().getPhysicalPort(portNumber), msg);
695 builder.setVersion((short) 1).setPortNo(portNumberV10).setCurrentFeatures(null).setCurrentFeaturesV10(featuresV10);
696 msg = builder.build();
697 connectionConductor.processPortStatusMsg(builder.build());
698 Assert.assertTrue(connectionConductor.getSessionContext().getPortBandwidth(portNumberV10));
699 Assert.assertEquals(connectionConductor.getSessionContext().getPhysicalPort(portNumberV10), msg);
704 public void testHandshakeFailOperations(){
705 connectionConductor.onHandshakeFailure();
706 connectionConductor.checkState(ConnectionConductor.CONDUCTOR_STATE.RIP);
708 private static void simulateV13PostHandshakeState(final ConnectionConductorImpl conductor) {
709 GetFeaturesOutputBuilder featureOutput = getFeatureResponseMsg();
710 conductor.postHandshakeBasic(featureOutput.build(), OFConstants.OFP_VERSION_1_3);