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.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.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.openflow.md.core.plan.ConnectionAdapterStackImpl;
37 import org.opendaylight.openflowplugin.openflow.md.core.plan.EventFactory;
38 import org.opendaylight.openflowplugin.openflow.md.core.plan.SwitchTestEvent;
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.openflow.md.queue.QueueProcessorLightImpl;
42 import org.opendaylight.openflowplugin.api.statistics.MessageSpy;
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.PortStatusMessage;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessageBuilder;
60 import org.opendaylight.yangtools.yang.binding.DataContainer;
61 import org.opendaylight.yangtools.yang.binding.DataObject;
62 import org.slf4j.Logger;
63 import org.slf4j.LoggerFactory;
65 @RunWith(MockitoJUnitRunner.class)
66 public class ConnectionConductorImplTest {
68 protected static final Logger LOG = LoggerFactory
69 .getLogger(ConnectionConductorImplTest.class);
74 private final int maxProcessingTimeout = 500;
76 protected ConnectionAdapterStackImpl adapter;
77 private ConnectionConductorImpl connectionConductor;
78 private MDController controller;
79 private Stack<SwitchTestEvent> eventPlan;
81 private Thread libSimulation;
82 private ScheduledThreadPoolExecutor pool = new ScheduledThreadPoolExecutor(
85 protected QueueProcessorLightImpl queueProcessor;
87 private PopListener<DataObject> popListener;
89 private int experimenterMessageCounter;
90 private int packetinMessageCounter;
91 private int flowremovedMessageCounter;
92 private int portstatusAddMessageCounter;
93 private int portstatusDeleteMessageCounter;
94 private int portstatusModifyMessageCounter;
95 private int errorMessageCounter;
98 private ErrorHandlerSimpleImpl errorHandler;
100 private int expectedErrors = 0;
102 private MessageSpy<DataContainer> messageSpy;
104 public void incrExperimenterMessageCounter() {
105 this.experimenterMessageCounter++;
108 public void incrPacketinMessageCounter() {
109 this.packetinMessageCounter++;
112 public void incrFlowremovedMessageCounter() {
113 this.flowremovedMessageCounter++;
116 public void incrPortstatusAddMessageCounter() {
117 this.portstatusAddMessageCounter++;
120 public void incrPortstatusDeleteMessageCounter() {
121 this.portstatusDeleteMessageCounter++;
124 public void incrPortstatusModifyMessageCounter() {
125 this.portstatusModifyMessageCounter++;
128 public void incrErrorMessageCounter() {
129 this.errorMessageCounter++;
134 * Test for ConnectionConductorFactory#createConductor
136 public void testCreateConductor() {
137 ConnectionConductor connectionConductor = ConnectionConductorFactory.createConductor(adapter, queueProcessor);
138 assertNotNull(connectionConductor);
142 * @throws java.lang.Exception
145 public void setUp() throws Exception {
146 adapter = new ConnectionAdapterStackImpl();
148 popListener = new PopListenerCountingImpl<>();
150 controller = new MDController();
152 controller.getMessageTranslators().putAll(assembleTranslatorMapping());
154 queueProcessor = new QueueProcessorLightImpl();
155 queueProcessor.setMessageSpy(messageSpy);
156 queueProcessor.setPopListenersMapping(assemblePopListenerMapping());
157 queueProcessor.setTranslatorMapping(controller.getMessageTranslators());
158 queueProcessor.init();
160 connectionConductor = new ConnectionConductorImpl(adapter);
161 connectionConductor.setQueueProcessor(queueProcessor);
162 connectionConductor.setErrorHandler(errorHandler);
163 connectionConductor.init();
164 eventPlan = new Stack<>();
165 adapter.setEventPlan(eventPlan);
166 adapter.setProceedTimeout(5000L);
167 adapter.checkListeners();
173 private Map<Class<? extends DataObject>, Collection<PopListener<DataObject>>> assemblePopListenerMapping() {
174 Map<Class<? extends DataObject>, Collection<PopListener<DataObject>>> mapping = new HashMap<>();
175 Collection<PopListener<DataObject>> popListenerBag = new ArrayList<>();
176 popListenerBag.add(popListener);
177 //TODO: add testing registered types
178 mapping.put(DataObject.class, popListenerBag);
183 * @throws java.lang.Exception
186 public void tearDown() throws Exception {
187 if (libSimulation != null) {
188 libSimulation.join();
190 queueProcessor.shutdown();
191 connectionConductor.shutdownPool();
193 for (Exception problem : adapter.getOccuredExceptions()) {
194 LOG.error("during simulation on adapter side: "
195 + problem.getMessage());
197 Assert.assertEquals(0, adapter.getOccuredExceptions().size());
199 if (LOG.isDebugEnabled()) {
200 if (eventPlan.size() > 0) {
201 LOG.debug("eventPlan size: " + eventPlan.size());
202 for (SwitchTestEvent event : eventPlan) {
203 LOG.debug(" # EVENT:: " + event.toString());
207 Assert.assertTrue("plan is not finished", eventPlan.isEmpty());
211 // logging errors if occurred
212 ArgumentCaptor<Throwable> errorCaptor = ArgumentCaptor.forClass(Throwable.class);
213 Mockito.verify(errorHandler, Mockito.atMost(1)).handleException(
214 errorCaptor.capture(), Matchers.any(SessionContext.class));
215 for (Throwable problem : errorCaptor.getAllValues()) {
216 LOG.warn(problem.getMessage(), problem);
219 Mockito.verify(errorHandler, Mockito.times(expectedErrors)).handleException(
220 Matchers.any(Throwable.class), Matchers.any(SessionContext.class));
225 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onEchoRequestMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessage)}
231 public void testOnEchoRequestMessage() throws Exception {
232 simulateV13PostHandshakeState(connectionConductor);
234 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
235 EventFactory.DEFAULT_VERSION, new EchoRequestMessageBuilder()));
237 EventFactory.createDefaultWaitForRpcEvent(42, "echoReply"));
242 * Test of handshake, covering version negotiation and features.
243 * Switch delivers first helloMessage with default version.
248 public void testHandshake1() throws Exception {
249 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
250 EventFactory.DEFAULT_VERSION, new HelloMessageBuilder()));
251 eventPlan.add(0, EventFactory.createDefaultWaitForAllEvent(
252 EventFactory.createDefaultWaitForRpcEvent(43, "helloReply"),
253 EventFactory.createDefaultWaitForRpcEvent(44, "getFeatures")));
254 eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(44,
255 EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
258 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "setConfig"));
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++, "setConfig"));
289 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
290 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
291 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
292 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
296 Assert.assertEquals(ConnectionConductor.CONDUCTOR_STATE.WORKING,
297 connectionConductor.getConductorState());
298 Assert.assertEquals((short) 0x04, connectionConductor.getVersion()
303 * Test of handshake, covering version negotiation and features.
304 * Switch delivers first helloMessage with version 0x05
305 * and negotiates following versions: 0x03, 0x01
310 public void testHandshake2() throws Exception {
311 connectionConductor.setBitmapNegotiationEnable(false);
312 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
313 (short) 0x05, new HelloMessageBuilder()));
315 EventFactory.createDefaultWaitForRpcEvent(43, "helloReply"));
316 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(43L,
317 (short) 0x03, new HelloMessageBuilder()));
319 EventFactory.createDefaultWaitForRpcEvent(44, "helloReply"));
320 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(44L,
321 (short) 0x01, new HelloMessageBuilder()));
323 EventFactory.createDefaultWaitForRpcEvent(45, "getFeatures"));
325 eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(45,
326 EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
329 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "setConfig"));
330 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
334 Assert.assertEquals(ConnectionConductor.CONDUCTOR_STATE.WORKING,
335 connectionConductor.getConductorState());
336 Assert.assertEquals((short) 0x01, connectionConductor.getVersion()
341 * Test of handshake, covering version negotiation and features.
342 * Controller sends first helloMessage with default version
343 * and switch negotiates following versions: 0x05, 0x03, 0x01
348 public void testHandshake2SwitchStarts() throws Exception {
349 connectionConductor.setBitmapNegotiationEnable(false);
350 eventPlan.add(0, EventFactory.createConnectionReadyCallback(connectionConductor));
352 EventFactory.createDefaultWaitForRpcEvent(21, "helloReply"));
353 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
354 (short) 0x05, new HelloMessageBuilder()));
355 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(43L,
356 (short) 0x03, new HelloMessageBuilder()));
358 EventFactory.createDefaultWaitForRpcEvent(44, "helloReply"));
359 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(44L,
360 (short) 0x01, new HelloMessageBuilder()));
362 EventFactory.createDefaultWaitForRpcEvent(45, "getFeatures"));
364 eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(45,
365 EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
368 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "setConfig"));
369 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
373 Assert.assertEquals(ConnectionConductor.CONDUCTOR_STATE.WORKING,
374 connectionConductor.getConductorState());
375 Assert.assertEquals((short) 0x01, connectionConductor.getVersion()
381 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onFlowRemovedMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessage)}
384 * @throws InterruptedException
387 public void testOnFlowRemovedMessage() throws InterruptedException {
388 IMDMessageTranslator<OfHeader, List<DataObject>> objFms = new FlowRemovedMessageService();
389 controller.addMessageTranslator(FlowRemovedMessage.class, 4, objFms);
391 simulateV13PostHandshakeState(connectionConductor);
393 // Now send Flow Removed messages
394 FlowRemovedMessageBuilder builder1 = new FlowRemovedMessageBuilder();
395 builder1.setVersion((short) 4);
397 connectionConductor.onFlowRemovedMessage(builder1.build());
398 synchronized (popListener) {
399 LOG.debug("about to wait for popListener");
400 popListener.wait(maxProcessingTimeout);
402 Assert.assertEquals(1, flowremovedMessageCounter);
404 connectionConductor.onFlowRemovedMessage(builder1.build());
405 synchronized (popListener) {
406 popListener.wait(maxProcessingTimeout);
408 Assert.assertEquals(2, flowremovedMessageCounter);
413 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onMultipartReplyMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage)}
417 public void testOnMultipartReplyMessage() {
418 // fail("Not yet implemented");
424 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onPacketInMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessage)}
427 * @throws InterruptedException
430 public void testOnPacketInMessage() throws InterruptedException {
431 IMDMessageTranslator<OfHeader, List<DataObject>> objPms = new PacketInMessageService();
432 controller.addMessageTranslator(PacketInMessage.class, 4, objPms);
434 simulateV13PostHandshakeState(connectionConductor);
437 PacketInMessageBuilder builder1 = new PacketInMessageBuilder();
438 builder1.setVersion((short) 4);
439 builder1.setBufferId((long) 1);
440 connectionConductor.onPacketInMessage(builder1.build());
441 synchronized (popListener) {
442 popListener.wait(maxProcessingTimeout);
444 Assert.assertEquals(1, packetinMessageCounter);
445 builder1.setBufferId((long) 2);
446 connectionConductor.onPacketInMessage(builder1.build());
447 synchronized (popListener) {
448 popListener.wait(maxProcessingTimeout);
450 Assert.assertEquals(2, packetinMessageCounter);
455 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onPortStatusMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage)}
458 * @throws InterruptedException
461 public void testOnPortStatusMessage() throws InterruptedException {
462 IMDMessageTranslator<OfHeader, List<DataObject>> objPSms = new PortStatusMessageService();
463 controller.addMessageTranslator(PortStatusMessage.class, 4, objPSms);
465 simulateV13PostHandshakeState(connectionConductor);
467 // Send Port Status messages
468 PortStatusMessageBuilder builder1 = new PortStatusMessageBuilder();
469 builder1.setVersion((short) 4);
470 PortFeatures features = new PortFeatures(true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false);
471 builder1.setPortNo(90L).setReason(PortReason.OFPPRADD).setCurrentFeatures(features);
472 connectionConductor.onPortStatusMessage(builder1.build());
473 synchronized (popListener) {
474 popListener.wait(maxProcessingTimeout);
476 Assert.assertEquals(1, portstatusAddMessageCounter);
477 builder1.setPortNo(90L).setReason(PortReason.OFPPRMODIFY).setCurrentFeatures(features);
478 connectionConductor.onPortStatusMessage(builder1.build());
479 synchronized (popListener) {
480 popListener.wait(maxProcessingTimeout);
482 Assert.assertEquals(1, portstatusModifyMessageCounter);
483 builder1.setPortNo(90L).setReason(PortReason.OFPPRDELETE).setCurrentFeatures(features);
484 connectionConductor.onPortStatusMessage(builder1.build());
485 synchronized (popListener) {
486 popListener.wait(maxProcessingTimeout);
488 Assert.assertEquals(1, portstatusDeleteMessageCounter);
492 * @throws InterruptedException
494 private void executeLater() throws InterruptedException {
499 * @throws InterruptedException
501 private void executeNow() throws InterruptedException {
503 connectionConductor.shutdownPool();
507 * @throws InterruptedException
509 private void execute(boolean join) throws InterruptedException {
510 libSimulation = new Thread(adapter, "junit-adapter");
511 libSimulation.start();
513 libSimulation.join();
517 private static GetFeaturesOutputBuilder getFeatureResponseMsg() {
518 GetFeaturesOutputBuilder getFeaturesOutputBuilder = new GetFeaturesOutputBuilder();
519 getFeaturesOutputBuilder.setDatapathId(new BigInteger("102030405060"));
520 getFeaturesOutputBuilder.setAuxiliaryId((short) 0);
521 getFeaturesOutputBuilder.setBuffers(4L);
522 getFeaturesOutputBuilder.setReserved(0L);
523 getFeaturesOutputBuilder.setTables((short) 2);
524 getFeaturesOutputBuilder.setCapabilities(createCapabilities(84));
526 return getFeaturesOutputBuilder;
532 private static Capabilities createCapabilities(long input) {
533 final Boolean FLOW_STATS = (input & (1 << 0)) != 0;
534 final Boolean TABLE_STATS = (input & (1 << 1)) != 0;
535 final Boolean PORT_STATS = (input & (1 << 2)) != 0;
536 final Boolean GROUP_STATS = (input & (1 << 3)) != 0;
537 final Boolean IP_REASM = (input & (1 << 5)) != 0;
538 final Boolean QUEUE_STATS = (input & (1 << 6)) != 0;
539 final Boolean PORT_BLOCKED = (input & (1 << 8)) != 0;
540 Capabilities capabilities = new Capabilities(FLOW_STATS, GROUP_STATS, IP_REASM,
541 PORT_BLOCKED, PORT_STATS, QUEUE_STATS, TABLE_STATS);
545 public class ExperimenterMessageService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
547 public List<DataObject> translate(SwitchConnectionDistinguisher cookie, SessionContext sw, OfHeader msg) {
548 LOG.debug("Received a packet in Experimenter Service");
549 ConnectionConductorImplTest.this.incrExperimenterMessageCounter();
554 public class PacketInMessageService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
556 public List<DataObject> translate(SwitchConnectionDistinguisher cookie, SessionContext sw, OfHeader msg) {
557 LOG.debug("Received a packet in PacketIn Service");
558 ConnectionConductorImplTest.this.incrPacketinMessageCounter();
563 public class FlowRemovedMessageService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
565 public List<DataObject> translate(SwitchConnectionDistinguisher cookie, SessionContext sw, OfHeader msg) {
566 LOG.debug("Received a packet in FlowRemoved Service");
567 ConnectionConductorImplTest.this.incrFlowremovedMessageCounter();
572 public class PortStatusMessageService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
574 public List<DataObject> translate(SwitchConnectionDistinguisher cookie, SessionContext sw, OfHeader msg) {
575 LOG.debug("Received a packet in PortStatus Service");
576 if ((((PortStatusMessage) msg).getReason().equals(PortReason.OFPPRADD))) {
577 ConnectionConductorImplTest.this.incrPortstatusAddMessageCounter();
578 } else if (((PortStatusMessage) msg).getReason().equals(PortReason.OFPPRDELETE)) {
579 ConnectionConductorImplTest.this.incrPortstatusDeleteMessageCounter();
580 } else if (((PortStatusMessage) msg).getReason().equals(PortReason.OFPPRMODIFY)) {
581 ConnectionConductorImplTest.this.incrPortstatusModifyMessageCounter();
587 public class ErrorMessageService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
589 public List<DataObject> translate(SwitchConnectionDistinguisher cookie, SessionContext sw, OfHeader msg) {
590 LOG.debug("Received a packet in Experimenter Service");
591 ConnectionConductorImplTest.this.incrErrorMessageCounter();
598 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onExperimenterMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessage)}
601 * @throws InterruptedException
604 public void testOnErrorMessage() throws InterruptedException {
605 simulateV13PostHandshakeState(connectionConductor);
607 ErrorMessageBuilder builder1 = new ErrorMessageBuilder();
608 builder1.setVersion((short) 4);
609 builder1.setCode(100);
610 connectionConductor.onErrorMessage(builder1.build());
611 synchronized (popListener) {
612 popListener.wait(maxProcessingTimeout);
614 Assert.assertEquals(1, errorMessageCounter);
615 builder1.setCode(200);
616 connectionConductor.onErrorMessage(builder1.build());
617 synchronized (popListener) {
618 popListener.wait(maxProcessingTimeout);
620 Assert.assertEquals(2, errorMessageCounter);
624 * @return listener mapping for:
626 * <li>experimenter</li>
630 private Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, List<DataObject>>>> assembleTranslatorMapping() {
631 Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, List<DataObject>>>> translatorMapping = new HashMap<>();
634 IMDMessageTranslator<OfHeader, List<DataObject>> objEms = new ExperimenterMessageService();
635 Collection<IMDMessageTranslator<OfHeader, List<DataObject>>> existingValues = new ArrayList<>();
636 existingValues.add(objEms);
637 tKey = new TranslatorKey(4, ExperimenterMessage.class.getName());
638 translatorMapping.put(tKey, existingValues);
639 IMDMessageTranslator<OfHeader, List<DataObject>> objErms = new ErrorMessageService();
640 existingValues.add(objErms);
641 tKey = new TranslatorKey(4, ErrorMessage.class.getName());
642 translatorMapping.put(tKey, existingValues);
643 return translatorMapping;
648 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#processPortStatusMsg(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage)}
650 * Tests for getting features from port status message by port version
652 * <li>features are malformed - one of them is null</li>
653 * <li>mismatch between port version and port features</li>
654 * <li>mismatch between port version and port features</li>
655 * <li>non-existing port version</li>
656 * <li>port version OF 1.0</li>
657 * <li>port version OF 1.3</li>
661 public void testProcessPortStatusMsg() {
662 simulateV13PostHandshakeState(connectionConductor);
664 long portNumber = 90L;
665 long portNumberV10 = 91L;
666 PortStatusMessage msg;
668 PortStatusMessageBuilder builder = new PortStatusMessageBuilder();
669 PortFeatures features = new PortFeatures(true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false);
670 PortFeatures featuresMal = new PortFeatures(true, false, false, false, null, false, false, false, false, false, false, false, false, false, false, false);
671 PortFeaturesV10 featuresV10 = new PortFeaturesV10(true, false, false, false, false, false, false, false, false, false, false, false);
674 builder.setVersion((short) 1).setPortNo(portNumber).setReason(PortReason.OFPPRADD).setCurrentFeatures(featuresMal);
675 connectionConductor.processPortStatusMsg(builder.build());
676 Assert.assertTrue(connectionConductor.getSessionContext().getPortsBandwidth().isEmpty());
677 Assert.assertTrue(connectionConductor.getSessionContext().getPhysicalPorts().isEmpty());
679 //Version-features mismatch
680 builder.setCurrentFeatures(features);
681 connectionConductor.processPortStatusMsg(builder.build());
682 Assert.assertTrue(connectionConductor.getSessionContext().getPortsBandwidth().isEmpty());
683 Assert.assertTrue(connectionConductor.getSessionContext().getPhysicalPorts().isEmpty());
685 //Non existing version
686 builder.setVersion((short) 0);
687 connectionConductor.processPortStatusMsg(builder.build());
688 Assert.assertTrue(connectionConductor.getSessionContext().getPortsBandwidth().isEmpty());
689 Assert.assertTrue(connectionConductor.getSessionContext().getPhysicalPorts().isEmpty());
692 builder.setVersion((short) 4);
693 msg = builder.build();
694 connectionConductor.processPortStatusMsg(builder.build());
695 Assert.assertTrue(connectionConductor.getSessionContext().getPortBandwidth(portNumber));
696 Assert.assertEquals(connectionConductor.getSessionContext().getPhysicalPort(portNumber), msg);
699 builder.setVersion((short) 1).setPortNo(portNumberV10).setCurrentFeatures(null).setCurrentFeaturesV10(featuresV10);
700 msg = builder.build();
701 connectionConductor.processPortStatusMsg(builder.build());
702 Assert.assertTrue(connectionConductor.getSessionContext().getPortBandwidth(portNumberV10));
703 Assert.assertEquals(connectionConductor.getSessionContext().getPhysicalPort(portNumberV10), msg);
706 private void simulateV13PostHandshakeState(ConnectionConductorImpl conductor) {
707 GetFeaturesOutputBuilder featureOutput = getFeatureResponseMsg();
708 conductor.postHandshakeBasic(featureOutput.build(), OFConstants.OFP_VERSION_1_3);