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.SwitchConnectionDistinguisher;
33 import org.opendaylight.openflowplugin.api.openflow.md.core.TranslatorKey;
34 import org.opendaylight.openflowplugin.openflow.md.core.plan.ConnectionAdapterStackImpl;
35 import org.opendaylight.openflowplugin.openflow.md.core.plan.EventFactory;
36 import org.opendaylight.openflowplugin.openflow.md.core.plan.SwitchTestEvent;
37 import org.opendaylight.openflowplugin.openflow.md.core.session.SessionContext;
38 import org.opendaylight.openflowplugin.openflow.md.queue.PopListener;
39 import org.opendaylight.openflowplugin.openflow.md.queue.QueueProcessorLightImpl;
40 import org.opendaylight.openflowplugin.api.statistics.MessageSpy;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Capabilities;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeatures;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeaturesV10;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortReason;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessageBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessage;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessageBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ExperimenterMessage;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessage;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessageBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutputBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloMessageBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessage;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessageBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessageBuilder;
58 import org.opendaylight.yangtools.yang.binding.DataContainer;
59 import org.opendaylight.yangtools.yang.binding.DataObject;
60 import org.slf4j.Logger;
61 import org.slf4j.LoggerFactory;
63 @RunWith(MockitoJUnitRunner.class)
64 public class ConnectionConductorImplTest {
66 protected static final Logger LOG = LoggerFactory
67 .getLogger(ConnectionConductorImplTest.class);
72 private final int maxProcessingTimeout = 500;
74 protected ConnectionAdapterStackImpl adapter;
75 private ConnectionConductorImpl connectionConductor;
76 private MDController controller;
77 private Stack<SwitchTestEvent> eventPlan;
79 private Thread libSimulation;
80 private ScheduledThreadPoolExecutor pool = new ScheduledThreadPoolExecutor(
83 protected QueueProcessorLightImpl queueProcessor;
85 private PopListener<DataObject> popListener;
87 private int experimenterMessageCounter;
88 private int packetinMessageCounter;
89 private int flowremovedMessageCounter;
90 private int portstatusAddMessageCounter;
91 private int portstatusDeleteMessageCounter;
92 private int portstatusModifyMessageCounter;
93 private int errorMessageCounter;
96 private ErrorHandlerSimpleImpl errorHandler;
98 private int expectedErrors = 0;
100 private MessageSpy<DataContainer> messageSpy;
102 public void incrExperimenterMessageCounter() {
103 this.experimenterMessageCounter++;
106 public void incrPacketinMessageCounter() {
107 this.packetinMessageCounter++;
110 public void incrFlowremovedMessageCounter() {
111 this.flowremovedMessageCounter++;
114 public void incrPortstatusAddMessageCounter() {
115 this.portstatusAddMessageCounter++;
118 public void incrPortstatusDeleteMessageCounter() {
119 this.portstatusDeleteMessageCounter++;
122 public void incrPortstatusModifyMessageCounter() {
123 this.portstatusModifyMessageCounter++;
126 public void incrErrorMessageCounter() {
127 this.errorMessageCounter++;
132 * Test for ConnectionConductorFactory#createConductor
134 public void testCreateConductor() {
135 ConnectionConductor connectionConductor = ConnectionConductorFactory.createConductor(adapter, queueProcessor);
136 assertNotNull(connectionConductor);
140 * @throws java.lang.Exception
143 public void setUp() throws Exception {
144 adapter = new ConnectionAdapterStackImpl();
146 popListener = new PopListenerCountingImpl<>();
148 controller = new MDController();
150 controller.getMessageTranslators().putAll(assembleTranslatorMapping());
152 queueProcessor = new QueueProcessorLightImpl();
153 queueProcessor.setMessageSpy(messageSpy);
154 queueProcessor.setPopListenersMapping(assemblePopListenerMapping());
155 queueProcessor.setTranslatorMapping(controller.getMessageTranslators());
156 queueProcessor.init();
158 connectionConductor = new ConnectionConductorImpl(adapter);
159 connectionConductor.setQueueProcessor(queueProcessor);
160 connectionConductor.setErrorHandler(errorHandler);
161 connectionConductor.init();
162 eventPlan = new Stack<>();
163 adapter.setEventPlan(eventPlan);
164 adapter.setProceedTimeout(5000L);
165 adapter.checkListeners();
171 private Map<Class<? extends DataObject>, Collection<PopListener<DataObject>>> assemblePopListenerMapping() {
172 Map<Class<? extends DataObject>, Collection<PopListener<DataObject>>> mapping = new HashMap<>();
173 Collection<PopListener<DataObject>> popListenerBag = new ArrayList<>();
174 popListenerBag.add(popListener);
175 //TODO: add testing registered types
176 mapping.put(DataObject.class, popListenerBag);
181 * @throws java.lang.Exception
184 public void tearDown() throws Exception {
185 if (libSimulation != null) {
186 libSimulation.join();
188 queueProcessor.shutdown();
189 connectionConductor.shutdownPool();
191 for (Exception problem : adapter.getOccuredExceptions()) {
192 LOG.error("during simulation on adapter side: "
193 + problem.getMessage());
195 Assert.assertEquals(0, adapter.getOccuredExceptions().size());
197 if (LOG.isDebugEnabled()) {
198 if (eventPlan.size() > 0) {
199 LOG.debug("eventPlan size: " + eventPlan.size());
200 for (SwitchTestEvent event : eventPlan) {
201 LOG.debug(" # EVENT:: " + event.toString());
205 Assert.assertTrue("plan is not finished", eventPlan.isEmpty());
209 // logging errors if occurred
210 ArgumentCaptor<Throwable> errorCaptor = ArgumentCaptor.forClass(Throwable.class);
211 Mockito.verify(errorHandler, Mockito.atMost(1)).handleException(
212 errorCaptor.capture(), Matchers.any(SessionContext.class));
213 for (Throwable problem : errorCaptor.getAllValues()) {
214 LOG.warn(problem.getMessage(), problem);
217 Mockito.verify(errorHandler, Mockito.times(expectedErrors)).handleException(
218 Matchers.any(Throwable.class), Matchers.any(SessionContext.class));
223 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onEchoRequestMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessage)}
229 public void testOnEchoRequestMessage() throws Exception {
230 simulateV13PostHandshakeState(connectionConductor);
232 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
233 EventFactory.DEFAULT_VERSION, new EchoRequestMessageBuilder()));
235 EventFactory.createDefaultWaitForRpcEvent(42, "echoReply"));
240 * Test of handshake, covering version negotiation and features.
241 * Switch delivers first helloMessage with default version.
246 public void testHandshake1() throws Exception {
247 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
248 EventFactory.DEFAULT_VERSION, new HelloMessageBuilder()));
249 eventPlan.add(0, EventFactory.createDefaultWaitForAllEvent(
250 EventFactory.createDefaultWaitForRpcEvent(43, "helloReply"),
251 EventFactory.createDefaultWaitForRpcEvent(44, "getFeatures")));
252 eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(44,
253 EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
256 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "setConfig"));
257 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
258 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
259 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
260 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
263 Assert.assertEquals(ConnectionConductor.CONDUCTOR_STATE.WORKING,
264 connectionConductor.getConductorState());
265 Assert.assertEquals((short) 0x04, connectionConductor.getVersion()
270 * Test of handshake, covering version negotiation and features.
271 * Controller sends first helloMessage with default version
276 public void testHandshake1SwitchStarts() throws Exception {
277 eventPlan.add(0, EventFactory.createConnectionReadyCallback(connectionConductor));
278 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(21, "helloReply"));
279 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
280 EventFactory.DEFAULT_VERSION, new HelloMessageBuilder()));
281 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(43, "getFeatures"));
282 eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(43,
283 EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
286 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "setConfig"));
287 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
288 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
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 EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
327 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "setConfig"));
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++, "setConfig"));
367 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
371 Assert.assertEquals(ConnectionConductor.CONDUCTOR_STATE.WORKING,
372 connectionConductor.getConductorState());
373 Assert.assertEquals((short) 0x01, connectionConductor.getVersion()
379 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onFlowRemovedMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessage)}
382 * @throws InterruptedException
385 public void testOnFlowRemovedMessage() throws InterruptedException {
386 IMDMessageTranslator<OfHeader, List<DataObject>> objFms = new FlowRemovedMessageService();
387 controller.addMessageTranslator(FlowRemovedMessage.class, 4, objFms);
389 simulateV13PostHandshakeState(connectionConductor);
391 // Now send Flow Removed messages
392 FlowRemovedMessageBuilder builder1 = new FlowRemovedMessageBuilder();
393 builder1.setVersion((short) 4);
395 connectionConductor.onFlowRemovedMessage(builder1.build());
396 synchronized (popListener) {
397 LOG.debug("about to wait for popListener");
398 popListener.wait(maxProcessingTimeout);
400 Assert.assertEquals(1, flowremovedMessageCounter);
402 connectionConductor.onFlowRemovedMessage(builder1.build());
403 synchronized (popListener) {
404 popListener.wait(maxProcessingTimeout);
406 Assert.assertEquals(2, flowremovedMessageCounter);
411 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onMultipartReplyMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage)}
415 public void testOnMultipartReplyMessage() {
416 // fail("Not yet implemented");
422 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onPacketInMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessage)}
425 * @throws InterruptedException
428 public void testOnPacketInMessage() throws InterruptedException {
429 IMDMessageTranslator<OfHeader, List<DataObject>> objPms = new PacketInMessageService();
430 controller.addMessageTranslator(PacketInMessage.class, 4, objPms);
432 simulateV13PostHandshakeState(connectionConductor);
435 PacketInMessageBuilder builder1 = new PacketInMessageBuilder();
436 builder1.setVersion((short) 4);
437 builder1.setBufferId((long) 1);
438 connectionConductor.onPacketInMessage(builder1.build());
439 synchronized (popListener) {
440 popListener.wait(maxProcessingTimeout);
442 Assert.assertEquals(1, packetinMessageCounter);
443 builder1.setBufferId((long) 2);
444 connectionConductor.onPacketInMessage(builder1.build());
445 synchronized (popListener) {
446 popListener.wait(maxProcessingTimeout);
448 Assert.assertEquals(2, packetinMessageCounter);
453 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onPortStatusMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage)}
456 * @throws InterruptedException
459 public void testOnPortStatusMessage() throws InterruptedException {
460 IMDMessageTranslator<OfHeader, List<DataObject>> objPSms = new PortStatusMessageService();
461 controller.addMessageTranslator(PortStatusMessage.class, 4, objPSms);
463 simulateV13PostHandshakeState(connectionConductor);
465 // Send Port Status messages
466 PortStatusMessageBuilder builder1 = new PortStatusMessageBuilder();
467 builder1.setVersion((short) 4);
468 PortFeatures features = new PortFeatures(true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false);
469 builder1.setPortNo(90L).setReason(PortReason.OFPPRADD).setCurrentFeatures(features);
470 connectionConductor.onPortStatusMessage(builder1.build());
471 synchronized (popListener) {
472 popListener.wait(maxProcessingTimeout);
474 Assert.assertEquals(1, portstatusAddMessageCounter);
475 builder1.setPortNo(90L).setReason(PortReason.OFPPRMODIFY).setCurrentFeatures(features);
476 connectionConductor.onPortStatusMessage(builder1.build());
477 synchronized (popListener) {
478 popListener.wait(maxProcessingTimeout);
480 Assert.assertEquals(1, portstatusModifyMessageCounter);
481 builder1.setPortNo(90L).setReason(PortReason.OFPPRDELETE).setCurrentFeatures(features);
482 connectionConductor.onPortStatusMessage(builder1.build());
483 synchronized (popListener) {
484 popListener.wait(maxProcessingTimeout);
486 Assert.assertEquals(1, portstatusDeleteMessageCounter);
490 * @throws InterruptedException
492 private void executeLater() throws InterruptedException {
497 * @throws InterruptedException
499 private void executeNow() throws InterruptedException {
501 connectionConductor.shutdownPool();
505 * @throws InterruptedException
507 private void execute(boolean join) throws InterruptedException {
508 libSimulation = new Thread(adapter, "junit-adapter");
509 libSimulation.start();
511 libSimulation.join();
515 private static GetFeaturesOutputBuilder getFeatureResponseMsg() {
516 GetFeaturesOutputBuilder getFeaturesOutputBuilder = new GetFeaturesOutputBuilder();
517 getFeaturesOutputBuilder.setDatapathId(new BigInteger("102030405060"));
518 getFeaturesOutputBuilder.setAuxiliaryId((short) 0);
519 getFeaturesOutputBuilder.setBuffers(4L);
520 getFeaturesOutputBuilder.setReserved(0L);
521 getFeaturesOutputBuilder.setTables((short) 2);
522 getFeaturesOutputBuilder.setCapabilities(createCapabilities(84));
524 return getFeaturesOutputBuilder;
530 private static Capabilities createCapabilities(long input) {
531 final Boolean FLOW_STATS = (input & (1 << 0)) != 0;
532 final Boolean TABLE_STATS = (input & (1 << 1)) != 0;
533 final Boolean PORT_STATS = (input & (1 << 2)) != 0;
534 final Boolean GROUP_STATS = (input & (1 << 3)) != 0;
535 final Boolean IP_REASM = (input & (1 << 5)) != 0;
536 final Boolean QUEUE_STATS = (input & (1 << 6)) != 0;
537 final Boolean PORT_BLOCKED = (input & (1 << 8)) != 0;
538 Capabilities capabilities = new Capabilities(FLOW_STATS, GROUP_STATS, IP_REASM,
539 PORT_BLOCKED, PORT_STATS, QUEUE_STATS, TABLE_STATS);
543 public class ExperimenterMessageService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
545 public List<DataObject> translate(SwitchConnectionDistinguisher cookie, SessionContext sw, OfHeader msg) {
546 LOG.debug("Received a packet in Experimenter Service");
547 ConnectionConductorImplTest.this.incrExperimenterMessageCounter();
552 public class PacketInMessageService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
554 public List<DataObject> translate(SwitchConnectionDistinguisher cookie, SessionContext sw, OfHeader msg) {
555 LOG.debug("Received a packet in PacketIn Service");
556 ConnectionConductorImplTest.this.incrPacketinMessageCounter();
561 public class FlowRemovedMessageService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
563 public List<DataObject> translate(SwitchConnectionDistinguisher cookie, SessionContext sw, OfHeader msg) {
564 LOG.debug("Received a packet in FlowRemoved Service");
565 ConnectionConductorImplTest.this.incrFlowremovedMessageCounter();
570 public class PortStatusMessageService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
572 public List<DataObject> translate(SwitchConnectionDistinguisher cookie, SessionContext sw, OfHeader msg) {
573 LOG.debug("Received a packet in PortStatus Service");
574 if ((((PortStatusMessage) msg).getReason().equals(PortReason.OFPPRADD))) {
575 ConnectionConductorImplTest.this.incrPortstatusAddMessageCounter();
576 } else if (((PortStatusMessage) msg).getReason().equals(PortReason.OFPPRDELETE)) {
577 ConnectionConductorImplTest.this.incrPortstatusDeleteMessageCounter();
578 } else if (((PortStatusMessage) msg).getReason().equals(PortReason.OFPPRMODIFY)) {
579 ConnectionConductorImplTest.this.incrPortstatusModifyMessageCounter();
585 public class ErrorMessageService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
587 public List<DataObject> translate(SwitchConnectionDistinguisher cookie, SessionContext sw, OfHeader msg) {
588 LOG.debug("Received a packet in Experimenter Service");
589 ConnectionConductorImplTest.this.incrErrorMessageCounter();
596 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onExperimenterMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.ErrorMessage)}
599 * @throws InterruptedException
602 public void testOnErrorMessage() throws InterruptedException {
603 simulateV13PostHandshakeState(connectionConductor);
605 ErrorMessageBuilder builder1 = new ErrorMessageBuilder();
606 builder1.setVersion((short) 4);
607 builder1.setCode(100);
608 connectionConductor.onErrorMessage(builder1.build());
609 synchronized (popListener) {
610 popListener.wait(maxProcessingTimeout);
612 Assert.assertEquals(1, errorMessageCounter);
613 builder1.setCode(200);
614 connectionConductor.onErrorMessage(builder1.build());
615 synchronized (popListener) {
616 popListener.wait(maxProcessingTimeout);
618 Assert.assertEquals(2, errorMessageCounter);
622 * @return listener mapping for:
624 * <li>experimenter</li>
628 private Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, List<DataObject>>>> assembleTranslatorMapping() {
629 Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, List<DataObject>>>> translatorMapping = new HashMap<>();
632 IMDMessageTranslator<OfHeader, List<DataObject>> objEms = new ExperimenterMessageService();
633 Collection<IMDMessageTranslator<OfHeader, List<DataObject>>> existingValues = new ArrayList<>();
634 existingValues.add(objEms);
635 tKey = new TranslatorKey(4, ExperimenterMessage.class.getName());
636 translatorMapping.put(tKey, existingValues);
637 IMDMessageTranslator<OfHeader, List<DataObject>> objErms = new ErrorMessageService();
638 existingValues.add(objErms);
639 tKey = new TranslatorKey(4, ErrorMessage.class.getName());
640 translatorMapping.put(tKey, existingValues);
641 return translatorMapping;
646 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#processPortStatusMsg(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage)}
648 * Tests for getting features from port status message by port version
650 * <li>features are malformed - one of them is null</li>
651 * <li>mismatch between port version and port features</li>
652 * <li>mismatch between port version and port features</li>
653 * <li>non-existing port version</li>
654 * <li>port version OF 1.0</li>
655 * <li>port version OF 1.3</li>
659 public void testProcessPortStatusMsg() {
660 simulateV13PostHandshakeState(connectionConductor);
662 long portNumber = 90L;
663 long portNumberV10 = 91L;
664 PortStatusMessage msg;
666 PortStatusMessageBuilder builder = new PortStatusMessageBuilder();
667 PortFeatures features = new PortFeatures(true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false);
668 PortFeatures featuresMal = new PortFeatures(true, false, false, false, null, false, false, false, false, false, false, false, false, false, false, false);
669 PortFeaturesV10 featuresV10 = new PortFeaturesV10(true, false, false, false, false, false, false, false, false, false, false, false);
672 builder.setVersion((short) 1).setPortNo(portNumber).setReason(PortReason.OFPPRADD).setCurrentFeatures(featuresMal);
673 connectionConductor.processPortStatusMsg(builder.build());
674 Assert.assertTrue(connectionConductor.getSessionContext().getPortsBandwidth().isEmpty());
675 Assert.assertTrue(connectionConductor.getSessionContext().getPhysicalPorts().isEmpty());
677 //Version-features mismatch
678 builder.setCurrentFeatures(features);
679 connectionConductor.processPortStatusMsg(builder.build());
680 Assert.assertTrue(connectionConductor.getSessionContext().getPortsBandwidth().isEmpty());
681 Assert.assertTrue(connectionConductor.getSessionContext().getPhysicalPorts().isEmpty());
683 //Non existing version
684 builder.setVersion((short) 0);
685 connectionConductor.processPortStatusMsg(builder.build());
686 Assert.assertTrue(connectionConductor.getSessionContext().getPortsBandwidth().isEmpty());
687 Assert.assertTrue(connectionConductor.getSessionContext().getPhysicalPorts().isEmpty());
690 builder.setVersion((short) 4);
691 msg = builder.build();
692 connectionConductor.processPortStatusMsg(builder.build());
693 Assert.assertTrue(connectionConductor.getSessionContext().getPortBandwidth(portNumber));
694 Assert.assertEquals(connectionConductor.getSessionContext().getPhysicalPort(portNumber), msg);
697 builder.setVersion((short) 1).setPortNo(portNumberV10).setCurrentFeatures(null).setCurrentFeaturesV10(featuresV10);
698 msg = builder.build();
699 connectionConductor.processPortStatusMsg(builder.build());
700 Assert.assertTrue(connectionConductor.getSessionContext().getPortBandwidth(portNumberV10));
701 Assert.assertEquals(connectionConductor.getSessionContext().getPhysicalPort(portNumberV10), msg);
704 private void simulateV13PostHandshakeState(ConnectionConductorImpl conductor) {
705 GetFeaturesOutputBuilder featureOutput = getFeatureResponseMsg();
706 conductor.postHandshakeBasic(featureOutput.build(), OFConstants.OFP_VERSION_1_3);