/**
* Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
package org.opendaylight.openflowplugin.openflow.md.core;
import com.google.common.collect.Lists;
import com.google.common.util.concurrent.Futures;
import java.util.ArrayList;
import java.util.List;
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.openflowjava.protocol.api.connection.ConnectionAdapter;
import org.opendaylight.openflowplugin.api.OFConstants;
import org.opendaylight.openflowplugin.api.openflow.md.core.ConnectionConductor;
import org.opendaylight.openflowplugin.api.openflow.md.core.ErrorHandler;
import org.opendaylight.openflowplugin.api.openflow.md.core.HandshakeListener;
import org.opendaylight.openflowplugin.api.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.RpcResult;
import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* testing handshake
*/
@RunWith(MockitoJUnitRunner.class)
public class HandshakeManagerImplTest {
private static final Logger LOG = LoggerFactory
.getLogger(HandshakeManagerImplTest.class);
private HandshakeManagerImpl handshakeManager;
@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() {
handshakeManager = new HandshakeManagerImpl(adapter, OFConstants.OFP_VERSION_1_3,
ConnectionConductor.VERSION_ORDER);
handshakeManager.setErrorHandler(errorHandler);
handshakeManager.setHandshakeListener(handshakeListener);
handshakeManager.setUseVersionBitmap(false);
resultFeatures = RpcResultBuilder.success(new GetFeaturesOutputBuilder().build()).build();
Mockito.when(adapter.hello(Matchers.any(HelloInput.class)))
.thenReturn(Futures.immediateFuture(
RpcResultBuilder.success((Void) null).build()));
}
/**
* 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));
}
/**
* Test method for {@link org.opendaylight.openflowplugin.openflow.md.core.HandshakeManagerImpl#proposeCommonBitmapVersion(java.util.List)}.
*/
@Test
public void testProposeCommonBitmapVersion() {
Boolean[][] versions = new Boolean[][] {
{true, true, true, false, false, false},
{true, true, true, false, false}
};
for (Boolean[] verasionList : versions) {
ElementsBuilder elementsBuilder = new ElementsBuilder();
elementsBuilder.setVersionBitmap(Lists.newArrayList(verasionList));
Elements element = elementsBuilder.build();
List<Elements> elements = Lists.newArrayList(element );
Short proposal = handshakeManager.proposeCommonBitmapVersion(elements);
Assert.assertEquals(Short.valueOf((short)1), proposal);
}
}
/**
* Test method for {@link org.opendaylight.openflowplugin.openflow.md.core.HandshakeManagerImpl#proposeNextVersion(short)}.
*/
@Test
public void testProposeNextVersion() {
short[] remoteVer = new short[] { 0x05, 0x04, 0x03, 0x02, 0x01, 0x8f,
0xff };
short[] expectedProposal = new short[] { 0x04, 0x04, 0x01, 0x01, 0x01,
0x04, 0x04 };
for (int i = 0; i < remoteVer.length; i++) {
short actualProposal = handshakeManager
.proposeNextVersion(remoteVer[i]);
Assert.assertEquals(
String.format("proposing for version: %04x", remoteVer[i]),
expectedProposal[i], actualProposal);
}
try {
handshakeManager.proposeNextVersion((short) 0);
Assert.fail("there should be no proposition for this version");
} catch (Exception e) {
// expected
}
}
//////// 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(null);
handshakeManager.shake(createHelloMessage(version, helloXid).build());
Mockito.verify(handshakeListener).onHandshakeSuccessful(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.shake(createHelloMessage(version, helloXid).build());
Mockito.verify(handshakeListener).onHandshakeSuccessful(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.shake(createHelloMessage(version, helloXid).build());
Mockito.verify(handshakeListener, Mockito.never()).onHandshakeSuccessful(
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(null);
handshakeManager.shake(createHelloMessage(version, helloXid).build());
Mockito.verify(handshakeListener, Mockito.never()).onHandshakeSuccessful(
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.shake(createHelloMessage(version, helloXid).build());
handshakeManager.shake(createHelloMessage(expVersion, helloXid).build());
Mockito.verify(handshakeListener).onHandshakeSuccessful(
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(null);
handshakeManager.shake(createHelloMessage(version, helloXid).build());
handshakeManager.shake(createHelloMessage(expVersion, helloXid).build());
Mockito.verify(handshakeListener).onHandshakeSuccessful(
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.shake(createHelloMessage(version, helloXid).build());
Mockito.verify(handshakeListener).onHandshakeSuccessful(
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(null);
handshakeManager.shake(createHelloMessage(version, helloXid).build());
Mockito.verify(handshakeListener).onHandshakeSuccessful(
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.shake(createHelloMessage(version, helloXid).build());
handshakeManager.shake(createHelloMessage(expVersion, helloXid).build());
Mockito.verify(handshakeListener).onHandshakeSuccessful(
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.shake(createHelloMessage(version, helloXid).build());
handshakeManager.shake(createHelloMessage(expVersion, helloXid).build());
Mockito.verify(handshakeListener).onHandshakeSuccessful(
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.shake(createHelloMessage(version, helloXid).build());
handshakeManager.shake(createHelloMessage(version, helloXid).build());
Mockito.verify(handshakeListener, Mockito.never()).onHandshakeSuccessful(
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(null);
handshakeManager.shake(createHelloMessage(version, helloXid).build());
handshakeManager.shake(createHelloMessage(version, helloXid).build());
Mockito.verify(handshakeListener, Mockito.never()).onHandshakeSuccessful(
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.shake(helloMessage.build());
Mockito.verify(handshakeListener).onHandshakeSuccessful(
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(null);
handshakeManager.shake(helloMessage.build());
Mockito.verify(handshakeListener).onHandshakeSuccessful(
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.shake(helloMessage.build());
Mockito.verify(handshakeListener).onHandshakeSuccessful(
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(null);
handshakeManager.shake(helloMessage.build());
Mockito.verify(handshakeListener).onHandshakeSuccessful(
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.shake(helloMessage.build());
Mockito.verify(handshakeListener, Mockito.never()).onHandshakeSuccessful(
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(null);
handshakeManager.shake(helloMessage.build());
Mockito.verify(handshakeListener, Mockito.never()).onHandshakeSuccessful(
Matchers.any(GetFeaturesOutput.class), Matchers.anyShort());
}
/**
* @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;
}
}