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.connection.HandshakeContext;
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.api.openflow.md.core.session.SessionContext;
38 import org.opendaylight.openflowplugin.api.openflow.md.queue.PopListener;
39 import org.opendaylight.openflowplugin.api.openflow.statistics.MessageSpy;
40 import org.opendaylight.openflowplugin.openflow.md.core.plan.ConnectionAdapterStackImpl;
41 import org.opendaylight.openflowplugin.openflow.md.core.plan.EventFactory;
42 import org.opendaylight.openflowplugin.openflow.md.core.plan.SwitchTestEvent;
43 import org.opendaylight.openflowplugin.openflow.md.queue.QueueProcessorLightImpl;
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.PortStatus;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessageBuilder;
62 import org.opendaylight.yangtools.yang.binding.DataContainer;
63 import org.opendaylight.yangtools.yang.binding.DataObject;
64 import org.slf4j.Logger;
65 import org.slf4j.LoggerFactory;
67 @RunWith(MockitoJUnitRunner.class)
68 public class ConnectionConductorImplTest {
70 protected static final Logger LOG = LoggerFactory
71 .getLogger(ConnectionConductorImplTest.class);
76 private final int maxProcessingTimeout = 500;
78 protected ConnectionAdapterStackImpl adapter;
79 private ConnectionConductorImpl connectionConductor;
80 private MDController controller;
81 private Stack<SwitchTestEvent> eventPlan;
83 private Thread libSimulation;
84 private ScheduledThreadPoolExecutor pool = new ScheduledThreadPoolExecutor(
87 protected QueueProcessorLightImpl queueProcessor;
89 private PopListener<DataObject> popListener;
91 private int experimenterMessageCounter;
92 private int packetinMessageCounter;
93 private int flowremovedMessageCounter;
94 private int portstatusAddMessageCounter;
95 private int portstatusDeleteMessageCounter;
96 private int portstatusModifyMessageCounter;
97 private int errorMessageCounter;
100 private ErrorHandlerSimpleImpl errorHandler;
102 private int expectedErrors = 0;
104 private MessageSpy<DataContainer> messageSpy;
106 HandshakeContext handshakeContext;
108 public void incrExperimenterMessageCounter() {
109 this.experimenterMessageCounter++;
112 public void incrPacketinMessageCounter() {
113 this.packetinMessageCounter++;
116 public void incrFlowremovedMessageCounter() {
117 this.flowremovedMessageCounter++;
120 public void incrPortstatusAddMessageCounter() {
121 this.portstatusAddMessageCounter++;
124 public void incrPortstatusDeleteMessageCounter() {
125 this.portstatusDeleteMessageCounter++;
128 public void incrPortstatusModifyMessageCounter() {
129 this.portstatusModifyMessageCounter++;
132 public void incrErrorMessageCounter() {
133 this.errorMessageCounter++;
138 * Test for ConnectionConductorFactory#createConductor
140 public void testCreateConductor() {
141 ConnectionConductor connectionConductor = ConnectionConductorFactory.createConductor(adapter, queueProcessor);
142 assertNotNull(connectionConductor);
146 * @throws java.lang.Exception
149 public void setUp() throws Exception {
150 adapter = new ConnectionAdapterStackImpl();
152 popListener = new PopListenerCountingImpl<>();
154 controller = new MDController();
156 controller.getMessageTranslators().putAll(assembleTranslatorMapping());
158 queueProcessor = new QueueProcessorLightImpl();
159 queueProcessor.setMessageSpy(messageSpy);
160 queueProcessor.setPopListenersMapping(assemblePopListenerMapping());
161 queueProcessor.setTranslatorMapping(controller.getMessageTranslators());
162 queueProcessor.init();
164 connectionConductor = new ConnectionConductorImpl(adapter);
165 connectionConductor.setQueueProcessor(queueProcessor);
166 connectionConductor.setErrorHandler(errorHandler);
167 connectionConductor.init();
168 connectionConductor.setHandshakeContext(handshakeContext);
169 eventPlan = new Stack<>();
170 adapter.setEventPlan(eventPlan);
171 adapter.setProceedTimeout(5000L);
172 adapter.checkListeners();
178 private Map<Class<? extends DataObject>, Collection<PopListener<DataObject>>> assemblePopListenerMapping() {
179 Map<Class<? extends DataObject>, Collection<PopListener<DataObject>>> mapping = new HashMap<>();
180 Collection<PopListener<DataObject>> popListenerBag = new ArrayList<>();
181 popListenerBag.add(popListener);
182 //TODO: add testing registered types
183 mapping.put(DataObject.class, popListenerBag);
188 * @throws java.lang.Exception
191 public void tearDown() throws Exception {
192 if (libSimulation != null) {
193 libSimulation.join();
195 queueProcessor.shutdown();
196 connectionConductor.getHsPool().shutdown();
198 for (Exception problem : adapter.getOccuredExceptions()) {
199 LOG.error("during simulation on adapter side: "
200 + problem.getMessage());
202 Assert.assertEquals(0, adapter.getOccuredExceptions().size());
204 if (LOG.isDebugEnabled()) {
205 if (eventPlan.size() > 0) {
206 LOG.debug("eventPlan size: " + eventPlan.size());
207 for (SwitchTestEvent event : eventPlan) {
208 LOG.debug(" # EVENT:: " + event.toString());
212 Assert.assertTrue("plan is not finished", eventPlan.isEmpty());
216 // logging errors if occurred
217 ArgumentCaptor<Throwable> errorCaptor = ArgumentCaptor.forClass(Throwable.class);
218 Mockito.verify(errorHandler, Mockito.atMost(1)).handleException(
219 errorCaptor.capture(), Matchers.any(SessionContext.class));
220 for (Throwable problem : errorCaptor.getAllValues()) {
221 LOG.warn(problem.getMessage(), problem);
224 Mockito.verify(errorHandler, Mockito.times(expectedErrors)).handleException(
225 Matchers.any(Throwable.class), Matchers.any(SessionContext.class));
230 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onEchoRequestMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.EchoRequestMessage)}
236 public void testOnEchoRequestMessage() throws Exception {
237 simulateV13PostHandshakeState(connectionConductor);
239 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
240 EventFactory.DEFAULT_VERSION, new EchoRequestMessageBuilder()));
242 EventFactory.createDefaultWaitForRpcEvent(42, "echoReply"));
247 * Test of handshake, covering version negotiation and features.
248 * Switch delivers first helloMessage with default version.
253 public void testHandshake1() throws Exception {
254 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
255 EventFactory.DEFAULT_VERSION, new HelloMessageBuilder()));
256 eventPlan.add(0, EventFactory.createDefaultWaitForAllEvent(
257 EventFactory.createDefaultWaitForRpcEvent(43, "helloReply"),
258 EventFactory.createDefaultWaitForRpcEvent(44, "getFeatures")));
259 eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(44,
260 EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
263 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
264 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
265 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
266 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
269 Assert.assertEquals(ConnectionConductor.CONDUCTOR_STATE.WORKING,
270 connectionConductor.getConductorState());
271 Assert.assertEquals((short) 0x04, connectionConductor.getVersion()
276 * Test of handshake, covering version negotiation and features.
277 * Controller sends first helloMessage with default version
282 public void testHandshake1SwitchStarts() throws Exception {
283 eventPlan.add(0, EventFactory.createConnectionReadyCallback(connectionConductor));
284 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(21, "helloReply"));
285 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
286 EventFactory.DEFAULT_VERSION, new HelloMessageBuilder()));
287 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(43, "getFeatures"));
288 eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(43,
289 EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
292 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
293 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
294 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
295 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
299 Assert.assertEquals(ConnectionConductor.CONDUCTOR_STATE.WORKING,
300 connectionConductor.getConductorState());
301 Assert.assertEquals((short) 0x04, connectionConductor.getVersion()
306 * Test of handshake, covering version negotiation and features.
307 * Switch delivers first helloMessage with version 0x05
308 * and negotiates following versions: 0x03, 0x01
313 public void testHandshake2() throws Exception {
314 connectionConductor.setBitmapNegotiationEnable(false);
315 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
316 (short) 0x05, new HelloMessageBuilder()));
318 EventFactory.createDefaultWaitForRpcEvent(43, "helloReply"));
319 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(43L,
320 (short) 0x03, new HelloMessageBuilder()));
322 EventFactory.createDefaultWaitForRpcEvent(44, "helloReply"));
323 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(44L,
324 (short) 0x01, new HelloMessageBuilder()));
326 EventFactory.createDefaultWaitForRpcEvent(45, "getFeatures"));
328 eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(45,
329 (short) 0x01, getFeatureResponseMsg()));
332 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
336 Assert.assertEquals(ConnectionConductor.CONDUCTOR_STATE.WORKING,
337 connectionConductor.getConductorState());
338 Assert.assertEquals((short) 0x01, connectionConductor.getVersion()
343 * Test of handshake, covering version negotiation and features.
344 * Controller sends first helloMessage with default version
345 * and switch negotiates following versions: 0x05, 0x03, 0x01
350 public void testHandshake2SwitchStarts() throws Exception {
351 connectionConductor.setBitmapNegotiationEnable(false);
352 eventPlan.add(0, EventFactory.createConnectionReadyCallback(connectionConductor));
354 EventFactory.createDefaultWaitForRpcEvent(21, "helloReply"));
355 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
356 (short) 0x05, new HelloMessageBuilder()));
357 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(43L,
358 (short) 0x03, new HelloMessageBuilder()));
360 EventFactory.createDefaultWaitForRpcEvent(44, "helloReply"));
361 eventPlan.add(0, EventFactory.createDefaultNotificationEvent(44L,
362 (short) 0x01, new HelloMessageBuilder()));
364 EventFactory.createDefaultWaitForRpcEvent(45, "getFeatures"));
366 eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(45,
367 (short) 0x01, getFeatureResponseMsg()));
370 eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(i++, "multipartRequestInput"));
374 Assert.assertEquals(ConnectionConductor.CONDUCTOR_STATE.WORKING,
375 connectionConductor.getConductorState());
376 Assert.assertEquals((short) 0x01, connectionConductor.getVersion()
382 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onFlowRemovedMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessage)}
385 * @throws InterruptedException
388 public void testOnFlowRemovedMessage() throws InterruptedException {
389 IMDMessageTranslator<OfHeader, List<DataObject>> objFms = new FlowRemovedMessageService();
390 controller.addMessageTranslator(FlowRemovedMessage.class, 4, objFms);
392 simulateV13PostHandshakeState(connectionConductor);
394 // Now send Flow Removed messages
395 FlowRemovedMessageBuilder builder1 = new FlowRemovedMessageBuilder();
396 builder1.setVersion((short) 4);
398 connectionConductor.onFlowRemovedMessage(builder1.build());
399 synchronized (popListener) {
400 LOG.debug("about to wait for popListener");
401 popListener.wait(maxProcessingTimeout);
403 Assert.assertEquals(1, flowremovedMessageCounter);
405 connectionConductor.onFlowRemovedMessage(builder1.build());
406 synchronized (popListener) {
407 popListener.wait(maxProcessingTimeout);
409 Assert.assertEquals(2, flowremovedMessageCounter);
414 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onMultipartReplyMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessage)}
418 public void testOnMultipartReplyMessage() {
419 // fail("Not yet implemented");
425 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onPacketInMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessage)}
428 * @throws InterruptedException
431 public void testOnPacketInMessage() throws InterruptedException {
432 IMDMessageTranslator<OfHeader, List<DataObject>> objPms = new PacketInMessageService();
433 controller.addMessageTranslator(PacketInMessage.class, 4, objPms);
435 simulateV13PostHandshakeState(connectionConductor);
438 PacketInMessageBuilder builder1 = new PacketInMessageBuilder();
439 builder1.setVersion((short) 4);
440 builder1.setBufferId((long) 1);
441 connectionConductor.onPacketInMessage(builder1.build());
442 synchronized (popListener) {
443 popListener.wait(maxProcessingTimeout);
445 Assert.assertEquals(1, packetinMessageCounter);
446 builder1.setBufferId((long) 2);
447 connectionConductor.onPacketInMessage(builder1.build());
448 synchronized (popListener) {
449 popListener.wait(maxProcessingTimeout);
451 Assert.assertEquals(2, packetinMessageCounter);
456 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onPortStatusMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage)}
459 * @throws InterruptedException
462 public void testOnPortStatusMessage() throws InterruptedException {
463 IMDMessageTranslator<OfHeader, List<DataObject>> objPSms = new PortStatusMessageService();
464 controller.addMessageTranslator(PortStatusMessage.class, 4, objPSms);
466 simulateV13PostHandshakeState(connectionConductor);
468 // Send Port Status messages
469 PortStatusMessageBuilder builder1 = new PortStatusMessageBuilder();
470 builder1.setVersion((short) 4);
471 PortFeatures features = new PortFeatures(true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false);
472 builder1.setPortNo(90L).setReason(PortReason.OFPPRADD).setCurrentFeatures(features);
473 connectionConductor.onPortStatusMessage(builder1.build());
474 synchronized (popListener) {
475 popListener.wait(maxProcessingTimeout);
477 Assert.assertEquals(1, portstatusAddMessageCounter);
478 builder1.setPortNo(90L).setReason(PortReason.OFPPRMODIFY).setCurrentFeatures(features);
479 connectionConductor.onPortStatusMessage(builder1.build());
480 synchronized (popListener) {
481 popListener.wait(maxProcessingTimeout);
483 Assert.assertEquals(1, portstatusModifyMessageCounter);
484 builder1.setPortNo(90L).setReason(PortReason.OFPPRDELETE).setCurrentFeatures(features);
485 connectionConductor.onPortStatusMessage(builder1.build());
486 synchronized (popListener) {
487 popListener.wait(maxProcessingTimeout);
489 Assert.assertEquals(1, portstatusDeleteMessageCounter);
493 * @throws InterruptedException
495 private void executeLater() throws InterruptedException {
500 * @throws InterruptedException
502 private void executeNow() throws InterruptedException {
504 connectionConductor.getHsPool().shutdown();
508 * @throws InterruptedException
510 private void execute(boolean join) throws InterruptedException {
511 libSimulation = new Thread(adapter, "junit-adapter");
512 libSimulation.start();
514 libSimulation.join();
518 private static GetFeaturesOutputBuilder getFeatureResponseMsg() {
519 GetFeaturesOutputBuilder getFeaturesOutputBuilder = new GetFeaturesOutputBuilder();
520 getFeaturesOutputBuilder.setDatapathId(new BigInteger("102030405060"));
521 getFeaturesOutputBuilder.setAuxiliaryId((short) 0);
522 getFeaturesOutputBuilder.setBuffers(4L);
523 getFeaturesOutputBuilder.setReserved(0L);
524 getFeaturesOutputBuilder.setTables((short) 2);
525 getFeaturesOutputBuilder.setCapabilities(createCapabilities(84));
527 return getFeaturesOutputBuilder;
533 private static Capabilities createCapabilities(long input) {
534 final Boolean FLOW_STATS = (input & (1 << 0)) != 0;
535 final Boolean TABLE_STATS = (input & (1 << 1)) != 0;
536 final Boolean PORT_STATS = (input & (1 << 2)) != 0;
537 final Boolean GROUP_STATS = (input & (1 << 3)) != 0;
538 final Boolean IP_REASM = (input & (1 << 5)) != 0;
539 final Boolean QUEUE_STATS = (input & (1 << 6)) != 0;
540 final Boolean PORT_BLOCKED = (input & (1 << 8)) != 0;
541 Capabilities capabilities = new Capabilities(FLOW_STATS, GROUP_STATS, IP_REASM,
542 PORT_BLOCKED, PORT_STATS, QUEUE_STATS, TABLE_STATS);
546 public class ExperimenterMessageService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
548 public List<DataObject> translate(SwitchConnectionDistinguisher cookie, SessionContext sw, OfHeader msg) {
549 LOG.debug("Received a packet in Experimenter Service");
550 ConnectionConductorImplTest.this.incrExperimenterMessageCounter();
555 public class PacketInMessageService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
557 public List<DataObject> translate(SwitchConnectionDistinguisher cookie, SessionContext sw, OfHeader msg) {
558 LOG.debug("Received a packet in PacketIn Service");
559 ConnectionConductorImplTest.this.incrPacketinMessageCounter();
564 public class FlowRemovedMessageService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
566 public List<DataObject> translate(SwitchConnectionDistinguisher cookie, SessionContext sw, OfHeader msg) {
567 LOG.debug("Received a packet in FlowRemoved Service");
568 ConnectionConductorImplTest.this.incrFlowremovedMessageCounter();
573 public class PortStatusMessageService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
575 public List<DataObject> translate(SwitchConnectionDistinguisher cookie, SessionContext sw, OfHeader msg) {
576 LOG.debug("Received a packet in PortStatus Service");
577 if ((((PortStatusMessage) msg).getReason().equals(PortReason.OFPPRADD))) {
578 ConnectionConductorImplTest.this.incrPortstatusAddMessageCounter();
579 } else if (((PortStatusMessage) msg).getReason().equals(PortReason.OFPPRDELETE)) {
580 ConnectionConductorImplTest.this.incrPortstatusDeleteMessageCounter();
581 } else if (((PortStatusMessage) msg).getReason().equals(PortReason.OFPPRMODIFY)) {
582 ConnectionConductorImplTest.this.incrPortstatusModifyMessageCounter();
588 public class ErrorMessageService implements IMDMessageTranslator<OfHeader, List<DataObject>> {
590 public List<DataObject> translate(SwitchConnectionDistinguisher cookie, SessionContext sw, OfHeader msg) {
591 LOG.debug("Received a packet in Experimenter Service");
592 ConnectionConductorImplTest.this.incrErrorMessageCounter();
599 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onExperimenterMessage(ExperimenterMessage)}
602 * @throws InterruptedException
605 public void testOnErrorMessage() throws InterruptedException {
606 simulateV13PostHandshakeState(connectionConductor);
608 ErrorMessageBuilder builder1 = new ErrorMessageBuilder();
609 builder1.setVersion((short) 4);
610 builder1.setCode(100);
611 connectionConductor.onErrorMessage(builder1.build());
612 synchronized (popListener) {
613 popListener.wait(maxProcessingTimeout);
615 Assert.assertEquals(1, errorMessageCounter);
616 builder1.setCode(200);
617 connectionConductor.onErrorMessage(builder1.build());
618 synchronized (popListener) {
619 popListener.wait(maxProcessingTimeout);
621 Assert.assertEquals(2, errorMessageCounter);
625 * @return listener mapping for:
627 * <li>experimenter</li>
631 private Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, List<DataObject>>>> assembleTranslatorMapping() {
632 Map<TranslatorKey, Collection<IMDMessageTranslator<OfHeader, List<DataObject>>>> translatorMapping = new HashMap<>();
635 IMDMessageTranslator<OfHeader, List<DataObject>> objEms = new ExperimenterMessageService();
636 Collection<IMDMessageTranslator<OfHeader, List<DataObject>>> existingValues = new ArrayList<>();
637 existingValues.add(objEms);
638 tKey = new TranslatorKey(4, ExperimenterMessage.class.getName());
639 translatorMapping.put(tKey, existingValues);
640 IMDMessageTranslator<OfHeader, List<DataObject>> objErms = new ErrorMessageService();
641 existingValues.add(objErms);
642 tKey = new TranslatorKey(4, ErrorMessage.class.getName());
643 translatorMapping.put(tKey, existingValues);
644 return translatorMapping;
649 * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#processPortStatusMsg(PortStatus)}
651 * Tests for getting features from port status message by port version
653 * <li>features are malformed - one of them is null</li>
654 * <li>mismatch between port version and port features</li>
655 * <li>mismatch between port version and port features</li>
656 * <li>non-existing port version</li>
657 * <li>port version OF 1.0</li>
658 * <li>port version OF 1.3</li>
662 public void testProcessPortStatusMsg() {
663 simulateV13PostHandshakeState(connectionConductor);
665 long portNumber = 90L;
666 long portNumberV10 = 91L;
667 PortStatusMessage msg;
669 PortStatusMessageBuilder builder = new PortStatusMessageBuilder();
670 PortFeatures features = new PortFeatures(true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false);
671 PortFeatures featuresMal = new PortFeatures(true, false, false, false, null, false, false, false, false, false, false, false, false, false, false, false);
672 PortFeaturesV10 featuresV10 = new PortFeaturesV10(true, false, false, false, false, false, false, false, false, false, false, false);
675 builder.setVersion((short) 1).setPortNo(portNumber).setReason(PortReason.OFPPRADD).setCurrentFeatures(featuresMal);
676 connectionConductor.processPortStatusMsg(builder.build());
677 Assert.assertTrue(connectionConductor.getSessionContext().getPortsBandwidth().isEmpty());
678 Assert.assertTrue(connectionConductor.getSessionContext().getPhysicalPorts().isEmpty());
680 //Version-features mismatch
681 builder.setCurrentFeatures(features);
682 connectionConductor.processPortStatusMsg(builder.build());
683 Assert.assertTrue(connectionConductor.getSessionContext().getPortsBandwidth().isEmpty());
684 Assert.assertTrue(connectionConductor.getSessionContext().getPhysicalPorts().isEmpty());
686 //Non existing version
687 builder.setVersion((short) 0);
688 connectionConductor.processPortStatusMsg(builder.build());
689 Assert.assertTrue(connectionConductor.getSessionContext().getPortsBandwidth().isEmpty());
690 Assert.assertTrue(connectionConductor.getSessionContext().getPhysicalPorts().isEmpty());
693 builder.setVersion((short) 4);
694 msg = builder.build();
695 connectionConductor.processPortStatusMsg(builder.build());
696 Assert.assertTrue(connectionConductor.getSessionContext().getPortBandwidth(portNumber));
697 Assert.assertEquals(connectionConductor.getSessionContext().getPhysicalPort(portNumber), msg);
700 builder.setVersion((short) 1).setPortNo(portNumberV10).setCurrentFeatures(null).setCurrentFeaturesV10(featuresV10);
701 msg = builder.build();
702 connectionConductor.processPortStatusMsg(builder.build());
703 Assert.assertTrue(connectionConductor.getSessionContext().getPortBandwidth(portNumberV10));
704 Assert.assertEquals(connectionConductor.getSessionContext().getPhysicalPort(portNumberV10), msg);
709 public void testHandshakeFailOperations(){
710 connectionConductor.onHandshakeFailure();
711 connectionConductor.checkState(ConnectionConductor.CONDUCTOR_STATE.RIP);
713 private void simulateV13PostHandshakeState(ConnectionConductorImpl conductor) {
714 GetFeaturesOutputBuilder featureOutput = getFeatureResponseMsg();
715 conductor.postHandshakeBasic(featureOutput.build(), OFConstants.OFP_VERSION_1_3);