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 static org.junit.Assert.assertTrue;
14 import java.math.BigInteger;
15 import java.util.ArrayList;
16 import java.util.Collection;
17 import java.util.HashMap;
18 import java.util.List;
20 import java.util.Stack;
21 import java.util.concurrent.ScheduledThreadPoolExecutor;
22 import org.junit.After;
23 import org.junit.Assert;
24 import org.junit.Before;
25 import org.junit.Test;
26 import org.junit.runner.RunWith;
27 import org.mockito.ArgumentCaptor;
28 import org.mockito.Matchers;
29 import org.mockito.Mock;
30 import org.mockito.Mockito;
31 import org.mockito.runners.MockitoJUnitRunner;
32 import org.opendaylight.openflowplugin.api.OFConstants;
33 import org.opendaylight.openflowplugin.api.openflow.md.core.ConnectionConductor;
34 import org.opendaylight.openflowplugin.api.openflow.md.core.IMDMessageTranslator;
35 import org.opendaylight.openflowplugin.api.openflow.md.core.SwitchConnectionDistinguisher;
36 import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey;
37 import org.opendaylight.openflowplugin.openflow.md.core.plan.ConnectionAdapterStackImpl;
38 import org.opendaylight.openflowplugin.openflow.md.core.plan.EventFactory;
39 import org.opendaylight.openflowplugin.openflow.md.core.plan.SwitchTestEvent;
40 import org.opendaylight.openflowplugin.api.openflow.md.core.session.SessionContext;
41 import org.opendaylight.openflowplugin.api.openflow.md.queue.PopListener;
42 import org.opendaylight.openflowplugin.openflow.md.queue.QueueProcessorLightImpl;
43 import org.opendaylight.openflowplugin.api.statistics.MessageSpy;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Capabilities;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeatures;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeaturesV10;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortReason;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessageBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessage;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessageBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterMessage;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessage;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessageBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutputBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloMessageBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessage;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessageBuilder;
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 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 int expectedErrors = 0;
103 private MessageSpy<DataContainer> messageSpy;
105 public void incrExperimenterMessageCounter() {
106 this.experimenterMessageCounter++;
109 public void incrPacketinMessageCounter() {
110 this.packetinMessageCounter++;
113 public void incrFlowremovedMessageCounter() {
114 this.flowremovedMessageCounter++;
117 public void incrPortstatusAddMessageCounter() {
118 this.portstatusAddMessageCounter++;
121 public void incrPortstatusDeleteMessageCounter() {
122 this.portstatusDeleteMessageCounter++;
125 public void incrPortstatusModifyMessageCounter() {
126 this.portstatusModifyMessageCounter++;
129 public void incrErrorMessageCounter() {
130 this.errorMessageCounter++;
135 * Test for ConnectionConductorFactory#createConductor
137 public void testCreateConductor() {
138 ConnectionConductor connectionConductor = ConnectionConductorFactory.createConductor(adapter, queueProcessor);
139 assertNotNull(connectionConductor);
143 * @throws java.lang.Exception
146 public void setUp() throws Exception {
147 adapter = new ConnectionAdapterStackImpl();
149 popListener = new PopListenerCountingImpl<>();
151 controller = new MDController();
153 controller.getMessageTranslators().putAll(assembleTranslatorMapping());
155 queueProcessor = new QueueProcessorLightImpl();
156 queueProcessor.setMessageSpy(messageSpy);
157 queueProcessor.setPopListenersMapping(assemblePopListenerMapping());
158 queueProcessor.setTranslatorMapping(controller.getMessageTranslators());
159 queueProcessor.init();
161 connectionConductor = new ConnectionConductorImpl(adapter);
162 connectionConductor.setQueueProcessor(queueProcessor);
163 connectionConductor.setErrorHandler(errorHandler);
164 connectionConductor.init();
165 eventPlan = new Stack<>();
166 adapter.setEventPlan(eventPlan);
167 adapter.setProceedTimeout(5000L);
168 adapter.checkListeners();
174 private Map<Class<? extends DataObject>, Collection<PopListener<DataObject>>> assemblePopListenerMapping() {
175 Map<Class<? extends DataObject>, Collection<PopListener<DataObject>>> mapping = new HashMap<>();
176 Collection<PopListener<DataObject>> popListenerBag = new ArrayList<>();
177 popListenerBag.add(popListener);
178 //TODO: add testing registered types
179 mapping.put(DataObject.class, popListenerBag);
184 * @throws java.lang.Exception
187 public void tearDown() throws Exception {
188 if (libSimulation != null) {
189 libSimulation.join();
191 queueProcessor.shutdown();
192 connectionConductor.shutdownPool();
194 for (Exception problem : adapter.getOccuredExceptions()) {
195 LOG.error("during simulation on adapter side: "
196 + problem.getMessage());
198 Assert.assertEquals(0, adapter.getOccuredExceptions().size());
200 if (LOG.isDebugEnabled()) {
201 if (eventPlan.size() > 0) {
202 LOG.debug("eventPlan size: " + eventPlan.size());
203 for (SwitchTestEvent event : eventPlan) {
204 LOG.debug(" # EVENT:: " + event.toString());
208 Assert.assertTrue("plan is not finished", eventPlan.isEmpty());
212 // logging errors if occurred
213 ArgumentCaptor<Throwable> errorCaptor = ArgumentCaptor.forClass(Throwable.class);
214 Mockito.verify(errorHandler, Mockito.atMost(1)).handleException(
215 errorCaptor.capture(), Matchers.any(SessionContext.class));
216 for (Throwable problem : errorCaptor.getAllValues()) {
217 LOG.warn(problem.getMessage(), problem);
220 Mockito.verify(errorHandler, Mockito.times(expectedErrors)).handleException(
221 Matchers.any(Throwable.class), Matchers.any(SessionContext.class));
226 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onEchoRequestMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessage)}
232 public void testOnEchoRequestMessage() throws Exception {
233 simulateV13PostHandshakeState(connectionConductor);
235 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
236 EventFactory.DEFAULT_VERSION, new EchoRequestMessageBuilder()));
238 EventFactory.createDefaultWaitForRpcEvent(42, "echoReply"));
243 * Test of handshake, covering version negotiation and features.
244 * Switch delivers first helloMessage with default version.
249 public void testHandshake1() throws Exception {
250 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
251 EventFactory.DEFAULT_VERSION, new HelloMessageBuilder()));
252 eventPlan.add(0, EventFactory.createDefaultWaitForAllEvent(
253 EventFactory.createDefaultWaitForRpcEvent(43, "helloReply"),
254 EventFactory.createDefaultWaitForRpcEvent(44, "getFeatures")));
255 eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(44,
256 EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
259 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
260 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
261 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
262 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
265 Assert.assertEquals(ConnectionConductor.CONDUCTOR_STATE.WORKING,
266 connectionConductor.getConductorState());
267 Assert.assertEquals((short) 0x04, connectionConductor.getVersion()
272 * Test of handshake, covering version negotiation and features.
273 * Controller sends first helloMessage with default version
278 public void testHandshake1SwitchStarts() throws Exception {
279 eventPlan.add(0, EventFactory.createConnectionReadyCallback(connectionConductor));
280 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(21, "helloReply"));
281 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
282 EventFactory.DEFAULT_VERSION, new HelloMessageBuilder()));
283 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(43, "getFeatures"));
284 eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(43,
285 EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
288 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
289 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
290 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
291 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
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 EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
328 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
332 Assert.assertEquals(ConnectionConductor.CONDUCTOR_STATE.WORKING,
333 connectionConductor.getConductorState());
334 Assert.assertEquals((short) 0x01, connectionConductor.getVersion()
339 * Test of handshake, covering version negotiation and features.
340 * Controller sends first helloMessage with default version
341 * and switch negotiates following versions: 0x05, 0x03, 0x01
346 public void testHandshake2SwitchStarts() throws Exception {
347 connectionConductor.setBitmapNegotiationEnable(false);
348 eventPlan.add(0, EventFactory.createConnectionReadyCallback(connectionConductor));
350 EventFactory.createDefaultWaitForRpcEvent(21, "helloReply"));
351 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
352 (short) 0x05, new HelloMessageBuilder()));
353 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(43L,
354 (short) 0x03, new HelloMessageBuilder()));
356 EventFactory.createDefaultWaitForRpcEvent(44, "helloReply"));
357 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(44L,
358 (short) 0x01, new HelloMessageBuilder()));
360 EventFactory.createDefaultWaitForRpcEvent(45, "getFeatures"));
362 eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(45,
363 EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
366 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
370 Assert.assertEquals(ConnectionConductor.CONDUCTOR_STATE.WORKING,
371 connectionConductor.getConductorState());
372 Assert.assertEquals((short) 0x01, connectionConductor.getVersion()
378 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onFlowRemovedMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessage)}
381 * @throws InterruptedException
384 public void testOnFlowRemovedMessage() throws InterruptedException {
385 IMDMessageTranslator<OfHeader, List<DataObject>> objFms = new FlowRemovedMessageService();
386 controller.addMessageTranslator(FlowRemovedMessage.class, 4, objFms);
388 simulateV13PostHandshakeState(connectionConductor);
390 // Now send Flow Removed messages
391 FlowRemovedMessageBuilder builder1 = new FlowRemovedMessageBuilder();
392 builder1.setVersion((short) 4);
394 connectionConductor.onFlowRemovedMessage(builder1.build());
395 synchronized (popListener) {
396 LOG.debug("about to wait for popListener");
397 popListener.wait(maxProcessingTimeout);
399 Assert.assertEquals(1, flowremovedMessageCounter);
401 connectionConductor.onFlowRemovedMessage(builder1.build());
402 synchronized (popListener) {
403 popListener.wait(maxProcessingTimeout);
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 IMDMessageTranslator<OfHeader, List<DataObject>> 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 synchronized (popListener) {
439 popListener.wait(maxProcessingTimeout);
441 Assert.assertEquals(1, packetinMessageCounter);
442 builder1.setBufferId((long) 2);
443 connectionConductor.onPacketInMessage(builder1.build());
444 synchronized (popListener) {
445 popListener.wait(maxProcessingTimeout);
447 Assert.assertEquals(2, packetinMessageCounter);
452 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onPortStatusMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage)}
455 * @throws InterruptedException
458 public void testOnPortStatusMessage() throws InterruptedException {
459 IMDMessageTranslator<OfHeader, List<DataObject>> objPSms = new PortStatusMessageService();
460 controller.addMessageTranslator(PortStatusMessage.class, 4, objPSms);
462 simulateV13PostHandshakeState(connectionConductor);
464 // Send Port Status messages
465 PortStatusMessageBuilder builder1 = new PortStatusMessageBuilder();
466 builder1.setVersion((short) 4);
467 PortFeatures features = new PortFeatures(true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false);
468 builder1.setPortNo(90L).setReason(PortReason.OFPPRADD).setCurrentFeatures(features);
469 connectionConductor.onPortStatusMessage(builder1.build());
470 synchronized (popListener) {
471 popListener.wait(maxProcessingTimeout);
473 Assert.assertEquals(1, portstatusAddMessageCounter);
474 builder1.setPortNo(90L).setReason(PortReason.OFPPRMODIFY).setCurrentFeatures(features);
475 connectionConductor.onPortStatusMessage(builder1.build());
476 synchronized (popListener) {
477 popListener.wait(maxProcessingTimeout);
479 Assert.assertEquals(1, portstatusModifyMessageCounter);
480 builder1.setPortNo(90L).setReason(PortReason.OFPPRDELETE).setCurrentFeatures(features);
481 connectionConductor.onPortStatusMessage(builder1.build());
482 synchronized (popListener) {
483 popListener.wait(maxProcessingTimeout);
485 Assert.assertEquals(1, portstatusDeleteMessageCounter);
489 * @throws InterruptedException
491 private void executeLater() throws InterruptedException {
496 * @throws InterruptedException
498 private void executeNow() throws InterruptedException {
500 connectionConductor.shutdownPool();
504 * @throws InterruptedException
506 private void execute(boolean join) throws InterruptedException {
507 libSimulation = new Thread(adapter, "junit-adapter");
508 libSimulation.start();
510 libSimulation.join();
514 private static GetFeaturesOutputBuilder getFeatureResponseMsg() {
515 GetFeaturesOutputBuilder getFeaturesOutputBuilder = new GetFeaturesOutputBuilder();
516 getFeaturesOutputBuilder.setDatapathId(new BigInteger("102030405060"));
517 getFeaturesOutputBuilder.setAuxiliaryId((short) 0);
518 getFeaturesOutputBuilder.setBuffers(4L);
519 getFeaturesOutputBuilder.setReserved(0L);
520 getFeaturesOutputBuilder.setTables((short) 2);
521 getFeaturesOutputBuilder.setCapabilities(createCapabilities(84));
523 return getFeaturesOutputBuilder;
529 private static Capabilities createCapabilities(long input) {
530 final Boolean FLOW_STATS = (input & (1 << 0)) != 0;
531 final Boolean TABLE_STATS = (input & (1 << 1)) != 0;
532 final Boolean PORT_STATS = (input & (1 << 2)) != 0;
533 final Boolean GROUP_STATS = (input & (1 << 3)) != 0;
534 final Boolean IP_REASM = (input & (1 << 5)) != 0;
535 final Boolean QUEUE_STATS = (input & (1 << 6)) != 0;
536 final Boolean PORT_BLOCKED = (input & (1 << 8)) != 0;
537 Capabilities capabilities = new Capabilities(FLOW_STATS, GROUP_STATS, IP_REASM,
538 PORT_BLOCKED, PORT_STATS, QUEUE_STATS, TABLE_STATS);
542 public class ExperimenterMessageService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
544 public List<DataObject> translate(SwitchConnectionDistinguisher cookie, SessionContext sw, OfHeader msg) {
545 LOG.debug("Received a packet in Experimenter Service");
546 ConnectionConductorImplTest.this.incrExperimenterMessageCounter();
551 public class PacketInMessageService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
553 public List<DataObject> translate(SwitchConnectionDistinguisher cookie, SessionContext sw, OfHeader msg) {
554 LOG.debug("Received a packet in PacketIn Service");
555 ConnectionConductorImplTest.this.incrPacketinMessageCounter();
560 public class FlowRemovedMessageService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
562 public List<DataObject> translate(SwitchConnectionDistinguisher cookie, SessionContext sw, OfHeader msg) {
563 LOG.debug("Received a packet in FlowRemoved Service");
564 ConnectionConductorImplTest.this.incrFlowremovedMessageCounter();
569 public class PortStatusMessageService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
571 public List<DataObject> translate(SwitchConnectionDistinguisher cookie, SessionContext sw, OfHeader msg) {
572 LOG.debug("Received a packet in PortStatus Service");
573 if ((((PortStatusMessage) msg).getReason().equals(PortReason.OFPPRADD))) {
574 ConnectionConductorImplTest.this.incrPortstatusAddMessageCounter();
575 } else if (((PortStatusMessage) msg).getReason().equals(PortReason.OFPPRDELETE)) {
576 ConnectionConductorImplTest.this.incrPortstatusDeleteMessageCounter();
577 } else if (((PortStatusMessage) msg).getReason().equals(PortReason.OFPPRMODIFY)) {
578 ConnectionConductorImplTest.this.incrPortstatusModifyMessageCounter();
584 public class ErrorMessageService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
586 public List<DataObject> translate(SwitchConnectionDistinguisher cookie, SessionContext sw, OfHeader msg) {
587 LOG.debug("Received a packet in Experimenter Service");
588 ConnectionConductorImplTest.this.incrErrorMessageCounter();
595 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onExperimenterMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessage)}
598 * @throws InterruptedException
601 public void testOnErrorMessage() throws InterruptedException {
602 simulateV13PostHandshakeState(connectionConductor);
604 ErrorMessageBuilder builder1 = new ErrorMessageBuilder();
605 builder1.setVersion((short) 4);
606 builder1.setCode(100);
607 connectionConductor.onErrorMessage(builder1.build());
608 synchronized (popListener) {
609 popListener.wait(maxProcessingTimeout);
611 Assert.assertEquals(1, errorMessageCounter);
612 builder1.setCode(200);
613 connectionConductor.onErrorMessage(builder1.build());
614 synchronized (popListener) {
615 popListener.wait(maxProcessingTimeout);
617 Assert.assertEquals(2, errorMessageCounter);
621 * @return listener mapping for:
623 * <li>experimenter</li>
627 private Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, List<DataObject>>>> assembleTranslatorMapping() {
628 Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, List<DataObject>>>> translatorMapping = new HashMap<>();
631 IMDMessageTranslator<OfHeader, List<DataObject>> objEms = new ExperimenterMessageService();
632 Collection<IMDMessageTranslator<OfHeader, List<DataObject>>> existingValues = new ArrayList<>();
633 existingValues.add(objEms);
634 tKey = new TranslatorKey(4, ExperimenterMessage.class.getName());
635 translatorMapping.put(tKey, existingValues);
636 IMDMessageTranslator<OfHeader, List<DataObject>> objErms = new ErrorMessageService();
637 existingValues.add(objErms);
638 tKey = new TranslatorKey(4, ErrorMessage.class.getName());
639 translatorMapping.put(tKey, existingValues);
640 return translatorMapping;
645 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#processPortStatusMsg(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage)}
647 * Tests for getting features from port status message by port version
649 * <li>features are malformed - one of them is null</li>
650 * <li>mismatch between port version and port features</li>
651 * <li>mismatch between port version and port features</li>
652 * <li>non-existing port version</li>
653 * <li>port version OF 1.0</li>
654 * <li>port version OF 1.3</li>
658 public void testProcessPortStatusMsg() {
659 simulateV13PostHandshakeState(connectionConductor);
661 long portNumber = 90L;
662 long portNumberV10 = 91L;
663 PortStatusMessage msg;
665 PortStatusMessageBuilder builder = new PortStatusMessageBuilder();
666 PortFeatures features = new PortFeatures(true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false);
667 PortFeatures featuresMal = new PortFeatures(true, false, false, false, null, false, false, false, false, false, false, false, false, false, false, false);
668 PortFeaturesV10 featuresV10 = new PortFeaturesV10(true, false, false, false, false, false, false, false, false, false, false, false);
671 builder.setVersion((short) 1).setPortNo(portNumber).setReason(PortReason.OFPPRADD).setCurrentFeatures(featuresMal);
672 connectionConductor.processPortStatusMsg(builder.build());
673 Assert.assertTrue(connectionConductor.getSessionContext().getPortsBandwidth().isEmpty());
674 Assert.assertTrue(connectionConductor.getSessionContext().getPhysicalPorts().isEmpty());
676 //Version-features mismatch
677 builder.setCurrentFeatures(features);
678 connectionConductor.processPortStatusMsg(builder.build());
679 Assert.assertTrue(connectionConductor.getSessionContext().getPortsBandwidth().isEmpty());
680 Assert.assertTrue(connectionConductor.getSessionContext().getPhysicalPorts().isEmpty());
682 //Non existing version
683 builder.setVersion((short) 0);
684 connectionConductor.processPortStatusMsg(builder.build());
685 Assert.assertTrue(connectionConductor.getSessionContext().getPortsBandwidth().isEmpty());
686 Assert.assertTrue(connectionConductor.getSessionContext().getPhysicalPorts().isEmpty());
689 builder.setVersion((short) 4);
690 msg = builder.build();
691 connectionConductor.processPortStatusMsg(builder.build());
692 Assert.assertTrue(connectionConductor.getSessionContext().getPortBandwidth(portNumber));
693 Assert.assertEquals(connectionConductor.getSessionContext().getPhysicalPort(portNumber), msg);
696 builder.setVersion((short) 1).setPortNo(portNumberV10).setCurrentFeatures(null).setCurrentFeaturesV10(featuresV10);
697 msg = builder.build();
698 connectionConductor.processPortStatusMsg(builder.build());
699 Assert.assertTrue(connectionConductor.getSessionContext().getPortBandwidth(portNumberV10));
700 Assert.assertEquals(connectionConductor.getSessionContext().getPhysicalPort(portNumberV10), msg);
705 public void testHandshakeFailOperations(){
706 connectionConductor.onHandshakeFailure();
707 connectionConductor.checkState(ConnectionConductor.CONDUCTOR_STATE.RIP);
709 private void simulateV13PostHandshakeState(ConnectionConductorImpl conductor) {
710 GetFeaturesOutputBuilder featureOutput = getFeatureResponseMsg();
711 conductor.postHandshakeBasic(featureOutput.build(), OFConstants.OFP_VERSION_1_3);