dividing handshake tests to controller fist and switch first scenarios 73/4373/1
authorMichal Rehak <mirehak@cisco.com>
Sat, 18 Jan 2014 13:37:49 +0000 (14:37 +0100)
committerMichal Rehak <mirehak@cisco.com>
Sat, 18 Jan 2014 23:36:04 +0000 (00:36 +0100)
added exception catching after tests
added posthandshake stuff to tests
added negotiation moved to pure handshake testing

Change-Id: Ic9bbc095f36ec605295af0ffdeddc1902ece3e9d
Signed-off-by: Michal Rehak <mirehak@cisco.com>
openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/ConnectionConductorImpl.java
openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/HandshakeManagerImpl.java
openflowplugin/src/test/java/org/opendaylight/openflowplugin/openflow/md/core/ConnectionConductorImplTest.java
openflowplugin/src/test/java/org/opendaylight/openflowplugin/openflow/md/core/HandshakeManagerImplTest.java

index 912cc6e72c5f223b218da7109a3e6da88b057052..95f1b2727277d3f04d6a37421fe2dea70dd27ab9 100644 (file)
@@ -376,11 +376,9 @@ public class ConnectionConductorImpl implements OpenflowProtocolListener,
     @Override
     public void onHandshakeSuccessfull(GetFeaturesOutput featureOutput,
             Short negotiatedVersion) {
-        version = negotiatedVersion;
-        conductorState = CONDUCTOR_STATE.WORKING;
-        OFSessionUtil.registerSession(this, featureOutput, negotiatedVersion);
-        requestDesc();
-        requestPorts();
+        postHandshakeBasic(featureOutput, negotiatedVersion);
+        
+        // post-handshake actions
         if(version == OFConstants.OFP_VERSION_1_3){
             requestGroupFeatures();
             requestMeterFeatures();
@@ -390,6 +388,21 @@ public class ConnectionConductorImpl implements OpenflowProtocolListener,
             //  it up for parsing to convert into a NodeConnectorUpdate
             queueKeeper.push(featureOutput, this);
         }
+        
+        requestDesc();
+        requestPorts();
+    }
+
+    /**
+     * used by tests
+     * @param featureOutput
+     * @param negotiatedVersion
+     */
+    protected void postHandshakeBasic(GetFeaturesOutput featureOutput,
+            Short negotiatedVersion) {
+        version = negotiatedVersion;
+        conductorState = CONDUCTOR_STATE.WORKING;
+        OFSessionUtil.registerSession(this, featureOutput, negotiatedVersion);
     }
 
     /*
index 50567adefd06df6eed3dd3e1a2854184328cfb26..2c1f91cf97b03e5539c3c2c0730b49dd6f1de7f0 100644 (file)
@@ -116,6 +116,14 @@ public class HandshakeManagerImpl implements HandshakeManager {
     private void handleStepByStepVersionNegotiation(Short remoteVersion) throws Throwable {
         LOG.debug("remoteVersion:{} lastProposedVersion:{}, highestVersion:{}", 
                 remoteVersion, lastProposedVersion, highestVersion);
+        
+        if (lastProposedVersion == null) {
+            // first hello has not been sent yet, send it and either wait for next remote 
+            // version or proceed
+            lastProposedVersion = proposeNextVersion(remoteVersion);
+            sendHelloMessage(lastProposedVersion, getNextXid());
+        }
+        
         if (remoteVersion == lastProposedVersion) {
             postHandshake(lastProposedVersion, getNextXid());
             LOG.debug("ret - OK - switch answered with lastProposedVersion");
@@ -158,6 +166,10 @@ public class HandshakeManagerImpl implements HandshakeManager {
     private void handleVersionBitmapNegotiation(List<Elements> elements) throws Throwable {
         Short proposedVersion;
         proposedVersion = proposeCommonBitmapVersion(elements);
+        if (lastProposedVersion == null) {
+            // first hello has not been sent yet
+            sendHelloMessage(proposedVersion, getNextXid());
+        }
         postHandshake(proposedVersion, getNextXid());
         LOG.debug("ret - OK - versionBitmap");
     }
@@ -185,6 +197,7 @@ public class HandshakeManagerImpl implements HandshakeManager {
         if (lastReceivedVersion != null && lastReceivedVersion.equals(remoteVersion)) {
             throw new IllegalStateException("version negotiation stalled: version = "+remoteVersion);
         }
+        lastReceivedVersion = remoteVersion;
     }
 
     @Override
@@ -256,7 +269,7 @@ public class HandshakeManagerImpl implements HandshakeManager {
         //final Long helloXid = 21L;
         HelloInput helloInput = MessageFactory.createHelloInput(helloVersion, helloXid, versionOrder);
         
-        LOG.debug("sending first hello message: version{}, xid={}, version bitmap={}", 
+        LOG.debug("sending hello message: version{}, xid={}, version bitmap={}", 
                 helloVersion, helloXid, MessageFactory.digVersions(helloInput.getElements()));
         
         try {
index bdf270c67e5b40fcba2d1c6dd818f0d06be866cc..d06cbc0b5929d49403e9768734351a5213e43fae 100644 (file)
@@ -22,16 +22,21 @@ import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.openflowplugin.openflow.md.OFConstants;
 import org.opendaylight.openflowplugin.openflow.md.core.plan.ConnectionAdapterStackImpl;
 import org.opendaylight.openflowplugin.openflow.md.core.plan.EventFactory;
 import org.opendaylight.openflowplugin.openflow.md.core.plan.SwitchTestEvent;
 import org.opendaylight.openflowplugin.openflow.md.core.session.SessionContext;
-import org.opendaylight.openflowplugin.openflow.md.core.session.SessionContextOFImpl;
 import org.opendaylight.openflowplugin.openflow.md.queue.PopListener;
 import org.opendaylight.openflowplugin.openflow.md.queue.QueueKeeperLightImpl;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Capabilities;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ErrorType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.HelloElementType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeatures;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortFeaturesV10;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortReason;
@@ -45,22 +50,18 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.FlowRemovedMessageBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloMessageBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartReplyMessageBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessage;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessageBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessage;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PortStatusMessageBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.hello.Elements;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.hello.ElementsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.multipart.reply.multipart.reply.body.multipart.reply.group.features._case.MultipartReplyGroupFeaturesBuilder;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.collect.Lists;
-
-/**
- * @author mirehak
- */
+@RunWith(MockitoJUnitRunner.class)
 public class ConnectionConductorImplTest {
 
     protected static final Logger LOG = LoggerFactory
@@ -90,8 +91,11 @@ public class ConnectionConductorImplTest {
     private int portstatusModifyMessageCounter;
     private int errorMessageCounter;
 
+    @Mock
     private ErrorHandlerQueueImpl errorHandler;
 
+    private int expectedErrors = 0;
+
     public void incrExperimenterMessageCounter() {
         this.experimenterMessageCounter++;
     }
@@ -135,7 +139,6 @@ public class ConnectionConductorImplTest {
         connectionConductor = new ConnectionConductorImpl(adapter);
         connectionConductor.setQueueKeeper(queueKeeper);
         connectionConductor.init();
-        errorHandler = new ErrorHandlerQueueImpl();
         pool.execute(errorHandler);
         connectionConductor.setErrorHandler(errorHandler);
         controller = new MDController();
@@ -191,7 +194,17 @@ public class ConnectionConductorImplTest {
         Assert.assertTrue("plan is not finished", eventPlan.isEmpty());
         eventPlan = null;
         controller = null;
-        errorHandler = null;
+        
+        // logging errors if occurred
+        ArgumentCaptor<Throwable> errorCaptor = ArgumentCaptor.forClass(Throwable.class);
+        Mockito.verify(errorHandler, Mockito.atMost(1)).handleException(
+                errorCaptor.capture(), Matchers.any(SessionContext.class));
+        for (Throwable problem : errorCaptor.getAllValues()) {
+            LOG.warn(problem.getMessage(), problem);
+        }
+        
+        Mockito.verify(errorHandler, Mockito.times(expectedErrors )).handleException(
+                Matchers.any(Throwable.class), Matchers.any(SessionContext.class));
     }
 
     /**
@@ -202,6 +215,8 @@ public class ConnectionConductorImplTest {
      */
     @Test
     public void testOnEchoRequestMessage() throws Exception {
+        simulateV13PostHandshakeState(connectionConductor);
+        
         eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
                 EventFactory.DEFAULT_VERSION, new EchoRequestMessageBuilder()));
         eventPlan.add(0,
@@ -210,19 +225,51 @@ public class ConnectionConductorImplTest {
     }
 
     /**
-     * Test of handshake, covering version negotiation and features .
+     * Test of handshake, covering version negotiation and features.
+     * Switch delivers first helloMessage with default version.
      * @throws Exception
      */
     @Test
     public void testHandshake1() throws Exception {
-        eventPlan.add(0, EventFactory.createConnectionReadyCallback(connectionConductor));
         eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
                 EventFactory.DEFAULT_VERSION, new HelloMessageBuilder()));
         eventPlan.add(0, EventFactory.createDefaultWaitForAllEvent(
-                EventFactory.createDefaultWaitForRpcEvent(21, "helloReply"),
-                EventFactory.createDefaultWaitForRpcEvent(43, "getFeatures")));
+                EventFactory.createDefaultWaitForRpcEvent(43, "helloReply"),
+                EventFactory.createDefaultWaitForRpcEvent(44, "getFeatures")));
+        eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(44,
+                EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
+        
+        eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(1, "multipartRequestInput"));
+        eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(2, "multipartRequestInput"));
+        eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(3, "multipartRequestInput"));
+        eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(4, "multipartRequestInput"));
+        executeNow();
+
+        Assert.assertEquals(ConnectionConductor.CONDUCTOR_STATE.WORKING,
+                connectionConductor.getConductorState());
+        Assert.assertEquals((short) 0x04, connectionConductor.getVersion()
+                .shortValue());
+    }
+    
+    /**
+     * Test of handshake, covering version negotiation and features.
+     * Controller sends first helloMessage with default version 
+     * @throws Exception
+     */
+    @Test
+    public void testHandshake1SwitchStarts() throws Exception {
+        eventPlan.add(0, EventFactory.createConnectionReadyCallback(connectionConductor));
+        eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(21, "helloReply"));
+        eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
+                EventFactory.DEFAULT_VERSION, new HelloMessageBuilder()));
+        eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(43, "getFeatures"));
         eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(43,
                 EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
+        
+        eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(1, "multipartRequestInput"));
+        eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(2, "multipartRequestInput"));
+        eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(3, "multipartRequestInput"));
+        eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(4, "multipartRequestInput"));
 
         executeNow();
 
@@ -233,17 +280,18 @@ public class ConnectionConductorImplTest {
     }
 
     /**
-     * Test of handshake, covering version negotiation and features .
+     * Test of handshake, covering version negotiation and features.
+     * Switch delivers first helloMessage with version 0x05 
+     * and negotiates following versions: 0x03, 0x01 
      * @throws Exception
      */
     @Test
     public void testHandshake2() throws Exception {
         connectionConductor.setBitmapNegotiationEnable(false);
-        eventPlan.add(0, EventFactory.createConnectionReadyCallback(connectionConductor));
         eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
                 (short) 0x05, new HelloMessageBuilder()));
         eventPlan.add(0,
-                EventFactory.createDefaultWaitForRpcEvent(21, "helloReply"));
+                EventFactory.createDefaultWaitForRpcEvent(43, "helloReply"));
         eventPlan.add(0, EventFactory.createDefaultNotificationEvent(43L,
                 (short) 0x03, new HelloMessageBuilder()));
         eventPlan.add(0,
@@ -255,6 +303,9 @@ public class ConnectionConductorImplTest {
 
         eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(45,
                 EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
+        
+        eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(1, "multipartRequestInput"));
+        eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(2, "multipartRequestInput"));
 
         executeNow();
 
@@ -263,20 +314,42 @@ public class ConnectionConductorImplTest {
         Assert.assertEquals((short) 0x01, connectionConductor.getVersion()
                 .shortValue());
     }
-
+    
     /**
-     * Test of handshake, covering version negotiation and features .
+     * Test of handshake, covering version negotiation and features.
+     * Controller sends first helloMessage with default version 
+     * and switch negotiates following versions: 0x05, 0x03, 0x01 
      * @throws Exception
      */
     @Test
-    public void testHandshake3() throws Exception {
+    public void testHandshake2SwitchStarts() throws Exception {
+        connectionConductor.setBitmapNegotiationEnable(false);
+        eventPlan.add(0, EventFactory.createConnectionReadyCallback(connectionConductor));
+        eventPlan.add(0,
+                EventFactory.createDefaultWaitForRpcEvent(21, "helloReply"));
         eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
-                (short) 0x00, new HelloMessageBuilder()));
+                (short) 0x05, new HelloMessageBuilder()));
+        eventPlan.add(0, EventFactory.createDefaultNotificationEvent(43L,
+                (short) 0x03, new HelloMessageBuilder()));
+        eventPlan.add(0,
+                EventFactory.createDefaultWaitForRpcEvent(44, "helloReply"));
+        eventPlan.add(0, EventFactory.createDefaultNotificationEvent(44L,
+                (short) 0x01, new HelloMessageBuilder()));
+        eventPlan.add(0,
+                EventFactory.createDefaultWaitForRpcEvent(45, "getFeatures"));
+
+        eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(45,
+                EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
+        
+        eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(1, "multipartRequestInput"));
+        eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(2, "multipartRequestInput"));
 
         executeNow();
-        Assert.assertEquals(ConnectionConductor.CONDUCTOR_STATE.HANDSHAKING,
+
+        Assert.assertEquals(ConnectionConductor.CONDUCTOR_STATE.WORKING,
                 connectionConductor.getConductorState());
-        Assert.assertNull(connectionConductor.getVersion());
+        Assert.assertEquals((short) 0x01, connectionConductor.getVersion()
+                .shortValue());
     }
 
     /**
@@ -287,6 +360,8 @@ public class ConnectionConductorImplTest {
      */
     @Test
     public void testOnExperimenterMessage1() throws InterruptedException {
+        simulateV13PostHandshakeState(connectionConductor);
+        
         eventPlan.add(0,
                 EventFactory.createDefaultWaitForRpcEvent(42, "experimenter"));
         ExperimenterMessageBuilder builder1 = new ExperimenterMessageBuilder();
@@ -318,6 +393,8 @@ public class ConnectionConductorImplTest {
      */
     @Test
     public void testOnExperimenterMessage2() throws InterruptedException {
+        simulateV13PostHandshakeState(connectionConductor);
+        
         eventPlan.add(0,
                 EventFactory.createDefaultWaitForRpcEvent(42, "experimenter"));
         ErrorMessageBuilder builder1 = new ErrorMessageBuilder();
@@ -354,16 +431,7 @@ public class ConnectionConductorImplTest {
         IMDMessageTranslator<OfHeader, List<DataObject>> objFms = new FlowRemovedMessageService() ;
         controller.addMessageTranslator(FlowRemovedMessage.class, 4, objFms);
 
-        // Complete HandShake
-        eventPlan.add(0, EventFactory.createConnectionReadyCallback(connectionConductor));
-        eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
-                EventFactory.DEFAULT_VERSION, new HelloMessageBuilder()));
-        eventPlan.add(0, EventFactory.createDefaultWaitForAllEvent(
-                EventFactory.createDefaultWaitForRpcEvent(21, "helloReply"),
-                EventFactory.createDefaultWaitForRpcEvent(43, "getFeatures")));
-        eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(43,
-          EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
-        execute(true);
+        simulateV13PostHandshakeState(connectionConductor);
 
         // Now send Flow Removed messages
         FlowRemovedMessageBuilder builder1 = new FlowRemovedMessageBuilder();
@@ -394,17 +462,6 @@ public class ConnectionConductorImplTest {
         // TODO:: add test
     }
 
-    /**
-     * Test method for
-     * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onMultipartRequestMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.MultipartRequestMessage)}
-     * .
-     */
-    @Test
-    public void testOnMultipartRequestMessage() {
-        // fail("Not yet implemented");
-        // TODO:: add test
-    }
-
     /**
      * Test method for
      * {@link org.opendaylight.openflowplugin.openflow.md.core.ConnectionConductorImpl#onPacketInMessage(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.PacketInMessage)}
@@ -416,16 +473,7 @@ public class ConnectionConductorImplTest {
         IMDMessageTranslator<OfHeader, List<DataObject>> objPms = new PacketInMessageService() ;
         controller.addMessageTranslator(PacketInMessage.class, 4, objPms);
 
-        // Complete HandShake
-        eventPlan.add(0, EventFactory.createConnectionReadyCallback(connectionConductor));
-        eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
-        EventFactory.DEFAULT_VERSION, new HelloMessageBuilder()));
-        eventPlan.add(0, EventFactory.createDefaultWaitForAllEvent(
-                EventFactory.createDefaultWaitForRpcEvent(21, "helloReply"),
-                EventFactory.createDefaultWaitForRpcEvent(43, "getFeatures")));
-        eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(43,
-          EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
-        execute(true);
+        simulateV13PostHandshakeState(connectionConductor);
 
         // Now send PacketIn
         PacketInMessageBuilder builder1 = new PacketInMessageBuilder();
@@ -452,20 +500,10 @@ public class ConnectionConductorImplTest {
      */
     @Test
     public void testOnPortStatusMessage() throws InterruptedException {
-
         IMDMessageTranslator<OfHeader, List<DataObject>> objPSms = new PortStatusMessageService() ;
         controller.addMessageTranslator(PortStatusMessage.class, 4, objPSms);
 
-        // Complete HandShake
-        eventPlan.add(0, EventFactory.createConnectionReadyCallback(connectionConductor));
-        eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L,
-        EventFactory.DEFAULT_VERSION, new HelloMessageBuilder()));
-        eventPlan.add(0, EventFactory.createDefaultWaitForAllEvent(
-                EventFactory.createDefaultWaitForRpcEvent(21, "helloReply"),
-                EventFactory.createDefaultWaitForRpcEvent(43, "getFeatures")));
-        eventPlan.add(0, EventFactory.createDefaultRpcResponseEvent(43,
-          EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
-        execute(true);
+        simulateV13PostHandshakeState(connectionConductor);
 
         // Send Port Status messages
         PortStatusMessageBuilder builder1 = new PortStatusMessageBuilder();
@@ -517,233 +555,7 @@ public class ConnectionConductorImplTest {
         }
     }
 
-    //////// Start - Version Negotiation Test //////////////
-
-    /**
-     * Test of version negotiation Where switch version = 1.0
-     *
-     * @throws Exception
-     */
-    @Test
-    public void testVersionNegotiation10() throws Exception {
-        LOG.debug("testVersionNegotiation10");
-        Short version = (short) 0x01;
-        eventPlan.add(0, EventFactory.createConnectionReadyCallback(connectionConductor));
-        eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42, version, new HelloMessageBuilder()));
-        eventPlan.add(0, EventFactory.createDefaultWaitForAllEvent(
-                EventFactory.createDefaultWaitForRpcEvent(21, "helloReply"),
-                EventFactory.createDefaultWaitForRpcEvent(43, "helloReply")));
-        eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(44, "getFeatures"));
-        eventPlan.add(0,
-                EventFactory.createDefaultRpcResponseEvent(44, EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
-
-        executeNow();
-        Assert.assertEquals(version, connectionConductor.getVersion());
-    }
-
-    /**
-     * Test of version negotiation Where switch version < 1.0
-     *
-     * @throws Exception
-     */
-    @Test
-    public void testVersionNegotiation00() throws Exception {
-        Short version = (short) 0x00;
-        eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L, version, new HelloMessageBuilder()));
-        executeNow();
-        Assert.assertNull(connectionConductor.getVersion());
-    }
-
-    /**
-     * Test of version negotiation Where 1.0 < switch version < 1.3
-     *
-     * @throws Exception
-     */
-    @Test
-    public void testVersionNegotiation11() throws Exception {
-        LOG.debug("testVersionNegotiation11");
-        connectionConductor.setBitmapNegotiationEnable(false);
-        Short version = (short) 0x02;
-        Short expVersion = (short) 0x01;
-        Assert.assertNull(connectionConductor.getVersion());
-
-        eventPlan.add(0, EventFactory.createConnectionReadyCallback(connectionConductor));
-        eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L, version, new HelloMessageBuilder()));
-        eventPlan.add(0, EventFactory.createDefaultWaitForAllEvent(
-                EventFactory.createDefaultWaitForRpcEvent(21, "helloReply"),
-                EventFactory.createDefaultWaitForRpcEvent(43, "helloReply")));
-        eventPlan.add(0, EventFactory.createDefaultNotificationEvent(44, expVersion, new HelloMessageBuilder()));
-        eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(45, "getFeatures"));
-        eventPlan.add(0,
-                EventFactory.createDefaultRpcResponseEvent(45, EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
-        executeNow();
-        Assert.assertEquals(expVersion, connectionConductor.getVersion());
-
-    }
-
-    /**
-     * Test of version negotiation Where switch version = 1.3
-     *
-     * @throws Exception
-     */
-    @Test
-    public void testVersionNegotiation13() throws Exception {
-        LOG.debug("testVersionNegotiation13");
-        Short version = (short) 0x04;
-        eventPlan.add(0, EventFactory.createConnectionReadyCallback(connectionConductor));
-        eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L, version, new HelloMessageBuilder()));
-        eventPlan.add(0, EventFactory.createDefaultWaitForAllEvent(
-                EventFactory.createDefaultWaitForRpcEvent(21, "helloReply"),
-                EventFactory.createDefaultWaitForRpcEvent(43, "getFeatures")));
-        eventPlan.add(0,
-                EventFactory.createDefaultRpcResponseEvent(43, EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
-
-        executeNow();
-        Assert.assertEquals(version, connectionConductor.getVersion());
-    }
-
-    /**
-     * Test of version negotiation Where switch version >= 1.3
-     *
-     * @throws Exception
-     */
-    @Test
-    public void testVersionNegotiation15() throws Exception {
-        LOG.debug("testVersionNegotiation15");
-        connectionConductor.setBitmapNegotiationEnable(false);
-        Short version = (short) 0x06;
-        Short expVersion = (short) 0x04;
-        Assert.assertNull(connectionConductor.getVersion());
-
-        eventPlan.add(0, EventFactory.createConnectionReadyCallback(connectionConductor));
-        eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42L, version, new HelloMessageBuilder()));
-        eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(21, "helloReply"));
-        eventPlan.add(0, EventFactory.createDefaultNotificationEvent(44, expVersion, new HelloMessageBuilder()));
-        eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(45, "getFeatures"));
-        eventPlan.add(0,
-                EventFactory.createDefaultRpcResponseEvent(45, EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
-        executeNow();
-        Assert.assertEquals(expVersion, connectionConductor.getVersion());
-    }
-
-    /**
-     * Test of version negotiation Where switch version > 1.3
-     *
-     * @throws Exception
-     */
-    @Test
-    public void testVersionNegotiation15_MultipleCall() throws Exception {
-        LOG.debug("testVersionNegotiation15_MultipleCall");
-        connectionConductor.setBitmapNegotiationEnable(false);
-        Short version = (short) 0x06;
-        Assert.assertNull(connectionConductor.getVersion());
-
-        eventPlan.add(0, EventFactory.createConnectionReadyCallback(connectionConductor));
-        eventPlan.add(0, EventFactory.createDefaultWaitForRpcEvent(21, "helloReply"));
-        eventPlan.add(0, EventFactory.createDefaultNotificationEvent(42, version, new HelloMessageBuilder()));
-        eventPlan.add(0, EventFactory.createDefaultNotificationEvent(44, version, new HelloMessageBuilder()));
-        executeNow();
-        // TODO : check for connection termination
-        Assert.assertNull(connectionConductor.getVersion());
-    }
-
-    /**
-     * Test of version negotiation Where bitmap version {0x05,0x01}
-     *
-     * @throws Exception
-     */
-    @Test
-    public void testVersionNegotiation10InBitmap() throws Exception {
-        LOG.debug("testVersionNegotiation10InBitmap");
-        Short version = (short) 0x01;
-
-        eventPlan.add(0, EventFactory.createConnectionReadyCallback(connectionConductor));
-        eventPlan.add(
-                0,
-                EventFactory.createDefaultNotificationEvent(42L, (short) 0x05,
-                        getHelloBitmapMessage(Lists.newArrayList((short) 0x05, (short) 0x01))));
-        eventPlan.add(0, EventFactory.createDefaultWaitForAllEvent(
-                EventFactory.createDefaultWaitForRpcEvent(21, "helloReply"),
-                EventFactory.createDefaultWaitForRpcEvent(43, "getFeatures")));
-        eventPlan.add(0,
-                EventFactory.createDefaultRpcResponseEvent(43, EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
-
-        executeNow();
-        Assert.assertEquals(version, connectionConductor.getVersion());
-    }
-
-    /**
-     * Test of version negotiation Where bitmap version {0x05,0x04}
-     *
-     * @throws Exception
-     */
-    @Test
-    public void testVersionNegotiation13InBitmap() throws Exception {
-        LOG.debug("testVersionNegotiation13InBitmap");
-        Short version = (short) 0x04;
-
-        eventPlan.add(0, EventFactory.createConnectionReadyCallback(connectionConductor));
-        eventPlan.add(
-                0,
-                EventFactory.createDefaultNotificationEvent(42L, (short) 0x05,
-                        getHelloBitmapMessage(Lists.newArrayList((short) 0x05, (short) 0x04))));
-        eventPlan.add(0, EventFactory.createDefaultWaitForAllEvent(
-                EventFactory.createDefaultWaitForRpcEvent(21, "helloReply"),
-                EventFactory.createDefaultWaitForRpcEvent(43, "getFeatures")));
-        eventPlan.add(0,
-                EventFactory.createDefaultRpcResponseEvent(43, EventFactory.DEFAULT_VERSION, getFeatureResponseMsg()));
-
-        executeNow();
-        Assert.assertEquals(version, connectionConductor.getVersion());
-    }
-
-    /**
-     * Test of version negotiation Where bitmap version {0x05,0x02}
-     *
-     * @throws Exception
-     */
-    @Test
-    public void testVersionNegotiationNoCommonVersionInBitmap() throws Exception {
-        eventPlan.add(
-                0,
-                EventFactory.createDefaultNotificationEvent(42L, (short) 0x05,
-                        getHelloBitmapMessage(Lists.newArrayList((short) 0x05, (short) 0x02))));
-        executeNow();
-        Assert.assertNull(connectionConductor.getVersion());
-    }
-
-    private HelloMessageBuilder getHelloBitmapMessage(List<Short> versionOrder) {
-        short highestVersion = versionOrder.get(0);
-        int elementsCount = highestVersion / Integer.SIZE;
-        ElementsBuilder elementsBuilder = new ElementsBuilder();
-
-        List<Elements> elementList = new ArrayList<>();
-        int orderIndex = versionOrder.size();
-        int value = versionOrder.get(--orderIndex);
-        for (int index = 0; index <= elementsCount; index++) {
-            List<Boolean> booleanList = new ArrayList<>();
-            for (int i = 0; i < Integer.SIZE; i++) {
-                if (value == ((index * Integer.SIZE) + i)) {
-                    booleanList.add(true);
-                    value = (orderIndex == 0) ? highestVersion : versionOrder.get(--orderIndex);
-                } else {
-                    booleanList.add(false);
-                }
-            }
-            elementsBuilder.setType(HelloElementType.forValue(1));
-            elementsBuilder.setVersionBitmap(booleanList);
-            elementList.add(elementsBuilder.build());
-        }
-
-        HelloMessageBuilder builder = new HelloMessageBuilder();
-        builder.setXid(10L);
-        builder.setVersion(highestVersion);
-        builder.setElements(elementList);
-        return builder;
-
-    }
-
-    private GetFeaturesOutputBuilder getFeatureResponseMsg() {
+    private static GetFeaturesOutputBuilder getFeatureResponseMsg() {
         GetFeaturesOutputBuilder getFeaturesOutputBuilder = new GetFeaturesOutputBuilder();
         getFeaturesOutputBuilder.setDatapathId(new BigInteger("102030405060"));
         getFeaturesOutputBuilder.setAuxiliaryId((short) 0);
@@ -830,6 +642,8 @@ public class ConnectionConductorImplTest {
      */
     @Test
     public void testOnExperimenterMessage() throws InterruptedException {
+        simulateV13PostHandshakeState(connectionConductor);
+        
         ExperimenterMessageBuilder builder1 = new ExperimenterMessageBuilder();
         builder1.setVersion((short) 4);
         builder1.setExperimenter(84L).setExpType(4L);
@@ -855,6 +669,8 @@ public class ConnectionConductorImplTest {
      */
     @Test
     public void testOnErrorMessage() throws InterruptedException {
+        simulateV13PostHandshakeState(connectionConductor);
+        
         ErrorMessageBuilder builder1 = new ErrorMessageBuilder();
         builder1.setVersion((short) 4);
         builder1.setCode(100);
@@ -910,10 +726,9 @@ public class ConnectionConductorImplTest {
      * 
      */
     @Test
-    public void testProcessPortStatusMsg()  {
-               SessionContextOFImpl ctx = new SessionContextOFImpl();
-               connectionConductor.setSessionContext(ctx);
-               
+    public void testProcessPortStatusMsg() {
+        simulateV13PostHandshakeState(connectionConductor);
+        
                long portNumber = 90L;
                long portNumberV10 = 91L;
                PortStatusMessage msg;
@@ -955,4 +770,9 @@ public class ConnectionConductorImplTest {
                Assert.assertTrue(connectionConductor.getSessionContext().getPortBandwidth(portNumberV10));
                Assert.assertEquals(connectionConductor.getSessionContext().getPhysicalPort(portNumberV10), msg);
     }
+    
+    private void simulateV13PostHandshakeState(ConnectionConductorImpl conductor) {
+        GetFeaturesOutputBuilder featureOutput = getFeatureResponseMsg();
+        conductor.postHandshakeBasic(featureOutput.build(), OFConstants.OFP_VERSION_1_3);
+    }
 }
index ff22fe58b3bcfcec8fe84f0d67372f6fbb7916ed..becb56d5cb9ff5e6b49410912adc3fe4cd4f0a4d 100644 (file)
@@ -7,33 +7,96 @@
  */
 package org.opendaylight.openflowplugin.openflow.md.core;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 
+import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
-import org.opendaylight.openflowplugin.openflow.md.core.plan.ConnectionAdapterStackImpl;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.controller.sal.common.util.Futures;
+import org.opendaylight.controller.sal.common.util.Rpcs;
+import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter;
+import org.opendaylight.openflowplugin.openflow.md.OFConstants;
+import org.opendaylight.openflowplugin.openflow.md.core.session.SessionContext;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.HelloElementType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.GetFeaturesOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.HelloMessageBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.hello.Elements;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.hello.ElementsBuilder;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.common.collect.Lists;
 
 /**
- * @author mirehak
- *
+ * testing handshake
  */
+@RunWith(MockitoJUnitRunner.class)
 public class HandshakeManagerImplTest {
     
+    private static final Logger LOG = LoggerFactory
+            .getLogger(HandshakeManagerImplTest.class);
+    
     private HandshakeManagerImpl handshakeManager;
-    protected ConnectionAdapterStackImpl adapter;
+    @Mock
+    private ConnectionAdapter adapter;
+    @Mock
+    private ErrorHandler errorHandler;
+    @Mock
+    private HandshakeListener handshakeListener;
+
+    private RpcResult<GetFeaturesOutput> resultFeatures;
+
+    private long helloXid = 42L;
+
+    private int expectedErrors = 0;
     
     /**
      * invoked before every test method
      */
     @Before
     public void setUp() {
-        adapter = new ConnectionAdapterStackImpl();
-        handshakeManager = new HandshakeManagerImpl(adapter, (short) 4, ConnectionConductor.versionOrder);
+        handshakeManager = new HandshakeManagerImpl(adapter, OFConstants.OFP_VERSION_1_3, 
+                ConnectionConductor.versionOrder);
+        handshakeManager.setErrorHandler(errorHandler);
+        handshakeManager.setHandshakeListener(handshakeListener);
+        handshakeManager.setUseVersionBitmap(false);
+        
+        resultFeatures = createRpcResult(true, new GetFeaturesOutputBuilder().build(), null);
+        
+        Mockito.when(adapter.hello(Matchers.any(HelloInput.class)))
+            .thenReturn(Futures.immediateFuture(createRpcResult(true, (Void) null, null)));
+    }
+    
+    /**
+     * invoked after each test method
+     */
+    @After
+    public void teardown() {
+        // logging errors if occurred
+        ArgumentCaptor<Throwable> errorCaptor = ArgumentCaptor.forClass(Throwable.class);
+        Mockito.verify(errorHandler, Mockito.atMost(1)).handleException(
+                errorCaptor.capture(), Matchers.any(SessionContext.class));
+        for (Throwable problem : errorCaptor.getAllValues()) {
+            LOG.warn(problem.getMessage(), problem);
+        }
+        
+        Mockito.verify(errorHandler, Mockito.times(expectedErrors)).handleException(
+                Matchers.any(Throwable.class), Matchers.any(SessionContext.class));
     }
 
     /**
@@ -82,4 +145,470 @@ public class HandshakeManagerImplTest {
         }
     }
 
+    //////// Version Negotiation Tests //////////////
+    
+    /**
+     * Test of version negotiation Where switch version = 1.0
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testVersionNegotiation10() throws Exception {
+        LOG.debug("testVersionNegotiation10");
+        Short version = OFConstants.OFP_VERSION_1_0;
+        
+        Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
+            .thenReturn(Futures.immediateFuture(resultFeatures));
+        
+        handshakeManager.shake();
+        
+        handshakeManager.setReceivedHello(createHelloMessage(version, helloXid).build());
+        handshakeManager.shake();
+        
+        Mockito.verify(handshakeListener).onHandshakeSuccessfull(resultFeatures.getResult(), version);
+    }
+    
+    /**
+     * Test of version negotiation Where switch version = 1.0
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testVersionNegotiation10SwitchStarts() throws Exception {
+        LOG.debug("testVersionNegotiation10-ss");
+        Short version = OFConstants.OFP_VERSION_1_0;
+        
+        Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
+            .thenReturn(Futures.immediateFuture(resultFeatures));
+        
+        handshakeManager.setReceivedHello(createHelloMessage(version, helloXid).build());
+        handshakeManager.shake();
+        
+        Mockito.verify(handshakeListener).onHandshakeSuccessfull(resultFeatures.getResult(), version);
+    }
+
+    /**
+     * Test of version negotiation Where switch version < 1.0
+     * Switch delivers first helloMessage with version 0x00 = negotiation unsuccessful 
+     * @throws Exception
+     */
+    @Test
+    public void testVersionNegotiation00() throws Exception {
+        LOG.debug("testVersionNegotiation00");
+        expectedErrors = 1;
+        Short version = (short) 0x00;
+        
+        handshakeManager.setReceivedHello(createHelloMessage(version, helloXid).build());
+        handshakeManager.shake();
+        
+        Mockito.verify(handshakeListener, Mockito.never()).onHandshakeSuccessfull(
+                Matchers.any(GetFeaturesOutput.class), Matchers.anyShort());
+    }
+    
+    /**
+     * Test of version negotiation Where switch version < 1.0
+     * Switch delivers first helloMessage with version 0x00 = negotiation unsuccessful 
+     * @throws Exception
+     */
+    @Test
+    public void testVersionNegotiation00SwitchStarts() throws Exception {
+        LOG.debug("testVersionNegotiation00-ss");
+        expectedErrors = 1;
+        Short version = (short) 0x00;
+        
+        handshakeManager.shake();
+        
+        handshakeManager.setReceivedHello(createHelloMessage(version, helloXid).build());
+        handshakeManager.shake();
+        
+        Mockito.verify(handshakeListener, Mockito.never()).onHandshakeSuccessfull(
+                Matchers.any(GetFeaturesOutput.class), Matchers.anyShort());
+    }
+
+    /**
+     * Test of version negotiation Where 1.0 < switch version < 1.3
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testVersionNegotiation11() throws Exception {
+        LOG.debug("testVersionNegotiation11");
+        Short version = (short) 0x02;
+        Short expVersion = (short) 0x01;
+    
+        Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
+            .thenReturn(Futures.immediateFuture(resultFeatures));
+        
+        handshakeManager.setReceivedHello(createHelloMessage(version, helloXid).build());
+        handshakeManager.shake();
+        
+        handshakeManager.setReceivedHello(createHelloMessage(expVersion, helloXid).build());
+        handshakeManager.shake();
+        
+        Mockito.verify(handshakeListener).onHandshakeSuccessfull(
+                resultFeatures.getResult(), expVersion);
+    }
+    
+    /**
+     * Test of version negotiation Where 1.0 < switch version < 1.3
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testVersionNegotiation11SwitchStarts() throws Exception {
+        LOG.debug("testVersionNegotiation11-ss");
+        Short version = (short) 0x02;
+        Short expVersion = (short) 0x01;
+    
+        Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
+            .thenReturn(Futures.immediateFuture(resultFeatures));
+        
+        handshakeManager.shake();
+        
+        handshakeManager.setReceivedHello(createHelloMessage(version, helloXid).build());
+        handshakeManager.shake();
+        
+        handshakeManager.setReceivedHello(createHelloMessage(expVersion, helloXid).build());
+        handshakeManager.shake();
+        
+        Mockito.verify(handshakeListener).onHandshakeSuccessfull(
+                resultFeatures.getResult(), expVersion);
+    }
+
+    /**
+     * Test of version negotiation Where switch version = 1.3
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testVersionNegotiation13() throws Exception {
+        LOG.debug("testVersionNegotiation13");
+        Short version = OFConstants.OFP_VERSION_1_3;
+        
+        Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
+            .thenReturn(Futures.immediateFuture(resultFeatures));
+        
+        handshakeManager.setReceivedHello(createHelloMessage(version, helloXid).build());
+        handshakeManager.shake();
+        
+        Mockito.verify(handshakeListener).onHandshakeSuccessfull(
+                resultFeatures.getResult(), version);
+    }
+    
+    /**
+     * Test of version negotiation Where switch version = 1.3
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testVersionNegotiation13SwitchStarts() throws Exception {
+        LOG.debug("testVersionNegotiation13-ss");
+        Short version = OFConstants.OFP_VERSION_1_3;
+        
+        Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
+            .thenReturn(Futures.immediateFuture(resultFeatures));
+        
+        handshakeManager.shake();
+        
+        handshakeManager.setReceivedHello(createHelloMessage(version, helloXid).build());
+        handshakeManager.shake();
+    
+        Mockito.verify(handshakeListener).onHandshakeSuccessfull(
+                resultFeatures.getResult(), version);
+    }
+
+    /**
+     * Test of version negotiation Where switch version >= 1.3
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testVersionNegotiation15() throws Exception {
+        LOG.debug("testVersionNegotiation15");
+        Short version = (short) 0x06;
+        Short expVersion =  OFConstants.OFP_VERSION_1_3;
+        
+        Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
+            .thenReturn(Futures.immediateFuture(resultFeatures));
+    
+        handshakeManager.setReceivedHello(createHelloMessage(version, helloXid).build());
+        handshakeManager.shake();
+        
+        handshakeManager.setReceivedHello(createHelloMessage(expVersion, helloXid).build());
+        handshakeManager.shake();
+        
+        Mockito.verify(handshakeListener).onHandshakeSuccessfull(
+                resultFeatures.getResult(), expVersion);
+    }
+    
+    /**
+     * Test of version negotiation Where switch version >= 1.3
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testVersionNegotiation15SwitchStart() throws Exception {
+        LOG.debug("testVersionNegotiation15-ss");
+        Short version = (short) 0x06;
+        Short expVersion =  OFConstants.OFP_VERSION_1_3;
+        
+        Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
+            .thenReturn(Futures.immediateFuture(resultFeatures));
+    
+        handshakeManager.setReceivedHello(createHelloMessage(version, helloXid).build());
+        handshakeManager.shake();
+        
+        handshakeManager.setReceivedHello(createHelloMessage(expVersion, helloXid).build());
+        handshakeManager.shake();
+        
+        Mockito.verify(handshakeListener).onHandshakeSuccessfull(
+                resultFeatures.getResult(), expVersion);
+    }
+
+    /**
+     * Test of version negotiation Where switch version > 1.3
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testVersionNegotiation15_MultipleCall() throws Exception {
+        LOG.debug("testVersionNegotiation15_MultipleCall");
+        Short version = (short) 0x06;
+        expectedErrors = 1;
+    
+        handshakeManager.setReceivedHello(createHelloMessage(version, helloXid).build());
+        handshakeManager.shake();
+        
+        handshakeManager.setReceivedHello(createHelloMessage(version, helloXid).build());
+        handshakeManager.shake();
+        
+        Mockito.verify(handshakeListener, Mockito.never()).onHandshakeSuccessfull(
+                Matchers.any(GetFeaturesOutput.class), Matchers.anyShort());
+    }
+    
+    /**
+     * Test of version negotiation Where switch version > 1.3
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testVersionNegotiation15_MultipleCallSwitchStarts() throws Exception {
+        LOG.debug("testVersionNegotiation15_MultipleCall-ss");
+        Short version = (short) 0x06;
+        expectedErrors = 1;
+    
+        handshakeManager.shake();
+        
+        handshakeManager.setReceivedHello(createHelloMessage(version, helloXid).build());
+        handshakeManager.shake();
+        
+        handshakeManager.setReceivedHello(createHelloMessage(version, helloXid).build());
+        handshakeManager.shake();
+        
+        Mockito.verify(handshakeListener, Mockito.never()).onHandshakeSuccessfull(
+                Matchers.any(GetFeaturesOutput.class), Matchers.anyShort());
+    }
+
+    /**
+     * Test of version negotiation Where bitmap version {0x05,0x01}
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testVersionNegotiation10InBitmap() throws Exception {
+        LOG.debug("testVersionNegotiation10InBitmap");
+        Short version = OFConstants.OFP_VERSION_1_0;
+        handshakeManager.setUseVersionBitmap(true);
+
+        HelloMessageBuilder helloMessage = createHelloMessage(version, helloXid);
+        addVersionBitmap(Lists.newArrayList((short) 0x05, OFConstants.OFP_VERSION_1_0), helloMessage);
+    
+        Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
+            .thenReturn(Futures.immediateFuture(resultFeatures));
+        
+        handshakeManager.setReceivedHello(helloMessage.build());
+        handshakeManager.shake();
+        
+        Mockito.verify(handshakeListener).onHandshakeSuccessfull(
+                resultFeatures.getResult(), version);
+    }
+    
+    /**
+     * Test of version negotiation Where bitmap version {0x05,0x01}
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testVersionNegotiation10InBitmapSwitchStarts() throws Exception {
+        LOG.debug("testVersionNegotiation10InBitmap-ss");
+        Short version = OFConstants.OFP_VERSION_1_0;
+        handshakeManager.setUseVersionBitmap(true);
+
+        HelloMessageBuilder helloMessage = createHelloMessage(version, helloXid);
+        addVersionBitmap(Lists.newArrayList((short) 0x05, OFConstants.OFP_VERSION_1_0), helloMessage);
+    
+        Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
+            .thenReturn(Futures.immediateFuture(resultFeatures));
+        
+        handshakeManager.shake();
+        
+        handshakeManager.setReceivedHello(helloMessage.build());
+        handshakeManager.shake();
+        
+        Mockito.verify(handshakeListener).onHandshakeSuccessfull(
+                resultFeatures.getResult(), version);
+    }
+
+    /**
+     * Test of version negotiation Where bitmap version {0x05,0x04}
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testVersionNegotiation13InBitmap() throws Exception {
+        LOG.debug("testVersionNegotiation13InBitmap");
+        Short version = OFConstants.OFP_VERSION_1_3;
+        handshakeManager.setUseVersionBitmap(true);
+
+        HelloMessageBuilder helloMessage = createHelloMessage(version, helloXid);
+        addVersionBitmap(Lists.newArrayList((short) 0x05, OFConstants.OFP_VERSION_1_3), helloMessage);
+    
+        Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
+            .thenReturn(Futures.immediateFuture(resultFeatures));
+    
+        handshakeManager.setReceivedHello(helloMessage.build());
+        handshakeManager.shake();
+    
+        Mockito.verify(handshakeListener).onHandshakeSuccessfull(
+                resultFeatures.getResult(), version);
+    }
+    
+    /**
+     * Test of version negotiation Where bitmap version {0x05,0x04}
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testVersionNegotiation13InBitmapSwitchFirst() throws Exception {
+        LOG.debug("testVersionNegotiation13InBitmap-ss");
+        Short version = OFConstants.OFP_VERSION_1_3;
+        handshakeManager.setUseVersionBitmap(true);
+
+        HelloMessageBuilder helloMessage = createHelloMessage(version, helloXid);
+        addVersionBitmap(Lists.newArrayList((short) 0x05, OFConstants.OFP_VERSION_1_3), helloMessage);
+    
+        Mockito.when(adapter.getFeatures(Matchers.any(GetFeaturesInput.class)))
+            .thenReturn(Futures.immediateFuture(resultFeatures));
+    
+        handshakeManager.shake();
+        
+        handshakeManager.setReceivedHello(helloMessage.build());
+        handshakeManager.shake();
+    
+        Mockito.verify(handshakeListener).onHandshakeSuccessfull(
+                resultFeatures.getResult(), version);
+    }
+
+    /**
+     * Test of version negotiation Where bitmap version {0x05,0x02}
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testVersionNegotiationNoCommonVersionInBitmap() throws Exception {
+        LOG.debug("testVersionNegotiationNoCommonVersionInBitmap");
+        Short version = (short) 0x05;
+        expectedErrors = 1;
+        handshakeManager.setUseVersionBitmap(true);
+        
+        HelloMessageBuilder helloMessage = createHelloMessage(version, helloXid);
+        addVersionBitmap(Lists.newArrayList((short) 0x05, (short) 0x02), helloMessage);
+        
+        handshakeManager.setReceivedHello(helloMessage.build());
+        handshakeManager.shake();
+        
+        Mockito.verify(handshakeListener, Mockito.never()).onHandshakeSuccessfull(
+                Matchers.any(GetFeaturesOutput.class), Matchers.anyShort());
+    }
+    
+    /**
+     * Test of version negotiation Where bitmap version {0x05,0x02}
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testVersionNegotiationNoCommonVersionInBitmapSwitchStarts() throws Exception {
+        LOG.debug("testVersionNegotiationNoCommonVersionInBitmap-ss");
+        Short version = (short) 0x05;
+        expectedErrors = 1;
+        handshakeManager.setUseVersionBitmap(true);
+        
+        HelloMessageBuilder helloMessage = createHelloMessage(version, helloXid);
+        addVersionBitmap(Lists.newArrayList((short) 0x05, (short) 0x02), helloMessage);
+        
+        handshakeManager.shake();
+        
+        handshakeManager.setReceivedHello(helloMessage.build());
+        handshakeManager.shake();
+        
+        Mockito.verify(handshakeListener, Mockito.never()).onHandshakeSuccessfull(
+                Matchers.any(GetFeaturesOutput.class), Matchers.anyShort());
+    }
+
+    /**
+     * @param success
+     * @param result
+     * @param errors
+     * @return
+     */
+    private static <T> RpcResult<T> createRpcResult(boolean success, T result, Collection<RpcError> errorsArg) {
+        Collection<RpcError> errors = errorsArg;
+        if (errors == null) {
+            errors = Collections.emptyList();
+        }
+        return Rpcs.getRpcResult(success, result, errors);
+    }
+
+    /**
+     * @param ofpVersion10
+     * @param helloXid
+     * @return
+     */
+    private static HelloMessageBuilder createHelloMessage(short ofpVersion10, long helloXid) {
+        return new HelloMessageBuilder().setVersion(ofpVersion10).setXid(helloXid);
+    }
+    
+    /**
+     * @param versionOrder
+     * @param helloBuilder
+     * @return
+     */
+    private static HelloMessageBuilder addVersionBitmap(List<Short> versionOrder, 
+            HelloMessageBuilder helloBuilder) {
+        short highestVersion = versionOrder.get(0);
+        int elementsCount = highestVersion / Integer.SIZE;
+        ElementsBuilder elementsBuilder = new ElementsBuilder();
+
+        List<Elements> elementList = new ArrayList<>();
+        int orderIndex = versionOrder.size();
+        int value = versionOrder.get(--orderIndex);
+        for (int index = 0; index <= elementsCount; index++) {
+            List<Boolean> booleanList = new ArrayList<>();
+            for (int i = 0; i < Integer.SIZE; i++) {
+                if (value == ((index * Integer.SIZE) + i)) {
+                    booleanList.add(true);
+                    value = (orderIndex == 0) ? highestVersion : versionOrder.get(--orderIndex);
+                } else {
+                    booleanList.add(false);
+                }
+            }
+            elementsBuilder.setType(HelloElementType.forValue(1));
+            elementsBuilder.setVersionBitmap(booleanList);
+            elementList.add(elementsBuilder.build());
+        }
+
+        helloBuilder.setElements(elementList);
+        return helloBuilder;
+    }
+
 }