X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=bgp%2Frib-impl%2Fsrc%2Ftest%2Fjava%2Forg%2Fopendaylight%2Fprotocol%2Fbgp%2Frib%2Fimpl%2FFSMTest.java;h=1ce90a132bfe8092b681dcd013bacf75685bbd47;hb=6d6e6da888ecb5df6a553b175ddb9c854f2bdf8e;hp=5ca8e1807828c2d5c3c033e480594d16025ddc93;hpb=e839341f0730816c55fec9313929f03b74262276;p=bgpcep.git diff --git a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/FSMTest.java b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/FSMTest.java index 5ca8e18078..1ce90a132b 100644 --- a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/FSMTest.java +++ b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/FSMTest.java @@ -8,24 +8,28 @@ package org.opendaylight.protocol.bgp.rib.impl; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; +import com.google.common.collect.Lists; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelPipeline; -import io.netty.util.HashedWheelTimer; +import io.netty.channel.EventLoop; import io.netty.util.concurrent.DefaultPromise; +import io.netty.util.concurrent.GenericFutureListener; import io.netty.util.concurrent.GlobalEventExecutor; - +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.UnknownHostException; import java.util.List; - +import java.util.concurrent.TimeUnit; import org.junit.After; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -33,132 +37,191 @@ import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.opendaylight.protocol.bgp.parser.BGPError; import org.opendaylight.protocol.bgp.parser.BgpTableTypeImpl; +import org.opendaylight.protocol.bgp.rib.impl.spi.BGPPeerRegistry; import org.opendaylight.protocol.bgp.rib.impl.spi.BGPSessionPreferences; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.LinkstateAddressFamily; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev131125.LinkstateSubsequentAddressFamily; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.AsNumber; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.LinkstateAddressFamily; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.LinkstateSubsequentAddressFamily; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Keepalive; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.KeepaliveBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Notify; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Open; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.OpenBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.ProtocolVersion; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.BgpParameters; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.BgpParametersBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.message.BgpParameters; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.message.BgpParametersBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.message.bgp.parameters.OptionalCapabilities; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.message.bgp.parameters.OptionalCapabilitiesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.message.bgp.parameters.optional.capabilities.CParametersBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.open.message.bgp.parameters.optional.capabilities.c.parameters.As4BytesCapabilityBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.BgpTableType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.open.bgp.parameters.c.parameters.CMultiprotocolBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.open.bgp.parameters.c.parameters.c.multiprotocol.MultiprotocolCapabilityBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.CParameters1; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.CParameters1Builder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.open.bgp.parameters.optional.capabilities.c.parameters.GracefulRestartCapabilityBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.open.bgp.parameters.optional.capabilities.c.parameters.MultiprotocolCapabilityBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.UnicastSubsequentAddressFamily; import org.opendaylight.yangtools.yang.binding.Notification; -import com.google.common.collect.Lists; - public class FSMTest { - private BGPSessionNegotiator clientSession; - - @Mock - private Channel speakerListener; - - @Mock - private ChannelPipeline pipeline; - - private final BgpTableType ipv4tt = new BgpTableTypeImpl(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class); - - private final BgpTableType linkstatett = new BgpTableTypeImpl(LinkstateAddressFamily.class, LinkstateSubsequentAddressFamily.class); - - private final List receivedMsgs = Lists.newArrayList(); - - private Open classicOpen; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - final List tlvs = Lists.newArrayList(); - - tlvs.add(new BgpParametersBuilder().setCParameters( - new CMultiprotocolBuilder().setMultiprotocolCapability( - new MultiprotocolCapabilityBuilder().setAfi(this.ipv4tt.getAfi()).setSafi( - this.ipv4tt.getSafi()).build()).build()).build()); - tlvs.add(new BgpParametersBuilder().setCParameters( - new CMultiprotocolBuilder().setMultiprotocolCapability( - new MultiprotocolCapabilityBuilder().setAfi(this.linkstatett.getAfi()).setSafi( - this.linkstatett.getSafi()).build()).build()).build()); - final BGPSessionPreferences prefs = new BGPSessionPreferences(30, (short) 3, null, tlvs); - this.clientSession = new BGPSessionNegotiator(new HashedWheelTimer(), new DefaultPromise(GlobalEventExecutor.INSTANCE), this.speakerListener, prefs, new SimpleSessionListener()); - doAnswer(new Answer() { - @Override - public Object answer(final InvocationOnMock invocation) { - final Object[] args = invocation.getArguments(); - FSMTest.this.receivedMsgs.add((Notification) args[0]); - return null; - } - }).when(this.speakerListener).writeAndFlush(any(Notification.class)); - doReturn("TestingChannel").when(this.speakerListener).toString(); - doReturn(this.pipeline).when(this.speakerListener).pipeline(); - doReturn(this.pipeline).when(this.pipeline).replace(any(ChannelHandler.class), any(String.class), any(ChannelHandler.class)); - doReturn(mock(ChannelFuture.class)).when(this.speakerListener).close(); - this.classicOpen = new OpenBuilder().setMyAsNumber(30).setHoldTimer(3).setVersion(new ProtocolVersion((short) 4)).setBgpParameters( - tlvs).build(); - } - - @Test - public void testAccSessionChar() throws InterruptedException { - this.clientSession.channelActive(null); - assertEquals(1, this.receivedMsgs.size()); - assertTrue(this.receivedMsgs.get(0) instanceof Open); - this.clientSession.handleMessage(this.classicOpen); - assertEquals(2, this.receivedMsgs.size()); - assertTrue(this.receivedMsgs.get(1) instanceof Keepalive); - this.clientSession.handleMessage(new KeepaliveBuilder().build()); - assertEquals(this.clientSession.getState(), BGPSessionNegotiator.State.Finished); - Thread.sleep(1000); - Thread.sleep(100); - assertEquals(3, this.receivedMsgs.size()); - assertTrue(this.receivedMsgs.get(2) instanceof Keepalive); // test of keepalive timer - } - - @Test - public void testNotAccChars() throws InterruptedException { - this.clientSession.channelActive(null); - assertEquals(1, this.receivedMsgs.size()); - assertTrue(this.receivedMsgs.get(0) instanceof Open); - this.clientSession.handleMessage(new OpenBuilder().setMyAsNumber(30).setHoldTimer(1).setVersion(new ProtocolVersion((short) 4)).build()); - assertEquals(2, this.receivedMsgs.size()); - assertTrue(this.receivedMsgs.get(1) instanceof Notify); - final Notification m = this.receivedMsgs.get(this.receivedMsgs.size() - 1); - assertEquals(BGPError.UNSPECIFIC_OPEN_ERROR, BGPError.forValue(((Notify) m).getErrorCode(), ((Notify) m).getErrorSubcode())); - } - - @Test - @Ignore - // long duration - public void testNoOpen() throws InterruptedException { - this.clientSession.channelActive(null); - assertEquals(1, this.receivedMsgs.size()); - assertTrue(this.receivedMsgs.get(0) instanceof Open); - Thread.sleep(BGPSessionNegotiator.INITIAL_HOLDTIMER * 1000 * 60); - Thread.sleep(100); - final Notification m = this.receivedMsgs.get(this.receivedMsgs.size() - 1); - assertEquals(BGPError.HOLD_TIMER_EXPIRED, BGPError.forValue(((Notify) m).getErrorCode(), ((Notify) m).getErrorSubcode())); - } - - @Test - public void sendNotification() { - this.clientSession.channelActive(null); - this.clientSession.handleMessage(this.classicOpen); - this.clientSession.handleMessage(new KeepaliveBuilder().build()); - assertEquals(this.clientSession.getState(), BGPSessionNegotiator.State.Finished); - this.clientSession.handleMessage(new OpenBuilder().setMyAsNumber(30).setHoldTimer(3).setVersion(new ProtocolVersion((short) 4)).build()); - assertEquals(3, this.receivedMsgs.size()); - assertTrue(this.receivedMsgs.get(2) instanceof Notify); - final Notification m = this.receivedMsgs.get(2); - assertEquals(BGPError.FSM_ERROR.getCode(), ((Notify) m).getErrorCode().shortValue()); - assertEquals(BGPError.FSM_ERROR.getSubcode(), ((Notify) m).getErrorSubcode().shortValue()); - } - - @After - public void tearDown() { - - } + + @Mock + private EventLoop eventLoop; + + private BGPClientSessionNegotiator clientSession; + + @Mock + private Channel speakerListener; + + @Mock + private ChannelPipeline pipeline; + + private final BgpTableType ipv4tt = new BgpTableTypeImpl(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class); + + private final BgpTableType linkstatett = new BgpTableTypeImpl(LinkstateAddressFamily.class, LinkstateSubsequentAddressFamily.class); + + private final List receivedMsgs = Lists.newArrayList(); + + private Open classicOpen; + + @Before + public void setUp() throws UnknownHostException { + MockitoAnnotations.initMocks(this); + final List tlvs = Lists.newArrayList(); + final List capas = Lists.newArrayList(); + + capas.add(new OptionalCapabilitiesBuilder().setCParameters(new CParametersBuilder().addAugmentation(CParameters1.class, + new CParameters1Builder().setMultiprotocolCapability(new MultiprotocolCapabilityBuilder() + .setAfi(this.ipv4tt.getAfi()).setSafi(this.ipv4tt.getSafi()).build()).build()).build()).build()); + capas.add(new OptionalCapabilitiesBuilder().setCParameters(new CParametersBuilder().addAugmentation(CParameters1.class, + new CParameters1Builder().setMultiprotocolCapability(new MultiprotocolCapabilityBuilder() + .setAfi(this.linkstatett.getAfi()).setSafi(this.linkstatett.getSafi()).build()).build()).build()).build()); + capas.add(new OptionalCapabilitiesBuilder().setCParameters(new CParametersBuilder().setAs4BytesCapability( + new As4BytesCapabilityBuilder().setAsNumber(new AsNumber(30L)).build()).build()).build()); + capas.add(new OptionalCapabilitiesBuilder().setCParameters(new CParametersBuilder().addAugmentation(CParameters1.class, + new CParameters1Builder().setGracefulRestartCapability(new GracefulRestartCapabilityBuilder().build()).build()).build()).build()); + + + tlvs.add(new BgpParametersBuilder().setOptionalCapabilities(capas).build()); + final BGPSessionPreferences prefs = new BGPSessionPreferences(new AsNumber(30L), (short) 3, new Ipv4Address("1.1.1.1"), new AsNumber(30L), tlvs); + + final ChannelFuture f = mock(ChannelFuture.class); + doReturn(null).when(f).addListener(any(GenericFutureListener.class)); + + final InetAddress peerAddress = InetAddress.getByName("1.1.1.2"); + final BGPPeerRegistry peerRegistry = new StrictBGPPeerRegistry(); + peerRegistry.addPeer(new IpAddress(new Ipv4Address(peerAddress.getHostAddress())), new SimpleSessionListener(), prefs); + + this.clientSession = new BGPClientSessionNegotiator(new DefaultPromise(GlobalEventExecutor.INSTANCE), this.speakerListener, peerRegistry); + doAnswer(new Answer() { + @Override + public Object answer(final InvocationOnMock invocation) { + final Object[] args = invocation.getArguments(); + FSMTest.this.receivedMsgs.add((Notification) args[0]); + return f; + } + }).when(this.speakerListener).writeAndFlush(any(Notification.class)); + doReturn(this.eventLoop).when(this.speakerListener).eventLoop(); + doReturn(null).when(this.eventLoop).schedule(any(Runnable.class), any(long.class), any(TimeUnit.class)); + doReturn("TestingChannel").when(this.speakerListener).toString(); + doReturn(new InetSocketAddress(peerAddress, 179)).when(this.speakerListener).remoteAddress(); + doReturn(new InetSocketAddress(peerAddress, 179)).when(this.speakerListener).localAddress(); + doReturn(this.pipeline).when(this.speakerListener).pipeline(); + doReturn(this.pipeline).when(this.pipeline).replace(any(ChannelHandler.class), any(String.class), any(ChannelHandler.class)); + doReturn(this.pipeline).when(this.pipeline).addLast(any(ChannelHandler.class)); + doReturn(mock(ChannelFuture.class)).when(this.speakerListener).close(); + this.classicOpen = new OpenBuilder().setMyAsNumber(30).setHoldTimer(3).setVersion(new ProtocolVersion((short) 4)).setBgpParameters( + tlvs).setBgpIdentifier(new Ipv4Address("1.1.1.2")).build(); + } + + @Test + public void testDenyPeer() { + this.clientSession = new BGPClientSessionNegotiator(new DefaultPromise(GlobalEventExecutor.INSTANCE), this.speakerListener, new StrictBGPPeerRegistry()); + this.clientSession.channelActive(null); + assertEquals(1, this.receivedMsgs.size()); + assertTrue(this.receivedMsgs.get(0) instanceof Notify); + } + + @Test + public void testAccSessionChar() throws InterruptedException { + this.clientSession.channelActive(null); + assertEquals(1, this.receivedMsgs.size()); + assertTrue(this.receivedMsgs.get(0) instanceof Open); + this.clientSession.handleMessage(this.classicOpen); + assertEquals(2, this.receivedMsgs.size()); + assertTrue(this.receivedMsgs.get(1) instanceof Keepalive); + this.clientSession.handleMessage(new KeepaliveBuilder().build()); + assertEquals(this.clientSession.getState(), BGPClientSessionNegotiator.State.FINISHED); + Thread.sleep(1000); + Thread.sleep(100); + } + + @Test + public void testNotAccChars() throws InterruptedException { + this.clientSession.channelActive(null); + assertEquals(1, this.receivedMsgs.size()); + assertTrue(this.receivedMsgs.get(0) instanceof Open); + this.clientSession.handleMessage(new OpenBuilder().setMyAsNumber(30).setHoldTimer(1).setBgpIdentifier(new Ipv4Address("127.0.0.1")).setVersion(new ProtocolVersion((short) 4)).build()); + assertEquals(2, this.receivedMsgs.size()); + assertTrue(this.receivedMsgs.get(1) instanceof Notify); + final Notification m = this.receivedMsgs.get(this.receivedMsgs.size() - 1); + assertEquals(BGPError.UNSPECIFIC_OPEN_ERROR, BGPError.forValue(((Notify) m).getErrorCode(), ((Notify) m).getErrorSubcode())); + } + + @Test + public void testNoAs4BytesCapability() { + this.clientSession.channelActive(null); + assertEquals(1, this.receivedMsgs.size()); + assertTrue(this.receivedMsgs.get(0) instanceof Open); + + final List tlvs = Lists.newArrayList(); + final List capas = Lists.newArrayList(); + capas.add(new OptionalCapabilitiesBuilder().setCParameters(new CParametersBuilder().addAugmentation(CParameters1.class, + new CParameters1Builder().setMultiprotocolCapability(new MultiprotocolCapabilityBuilder() + .setAfi(this.ipv4tt.getAfi()).setSafi(this.ipv4tt.getSafi()).build()).build()).build()).build()); + tlvs.add(new BgpParametersBuilder().setOptionalCapabilities(capas).build()); + // Open Message without advertised four-octet AS Number capability + this.clientSession.handleMessage(new OpenBuilder().setMyAsNumber(30).setHoldTimer(1).setVersion( + new ProtocolVersion((short) 4)).setBgpParameters(tlvs).setBgpIdentifier(new Ipv4Address("1.1.1.2")).build()); + assertEquals(2, this.receivedMsgs.size()); + assertTrue(this.receivedMsgs.get(1) instanceof Notify); + final Notification m = this.receivedMsgs.get(this.receivedMsgs.size() - 1); + assertEquals(BGPError.UNSUPPORTED_CAPABILITY, BGPError.forValue(((Notify) m).getErrorCode(), ((Notify) m).getErrorSubcode())); + assertNotNull(((Notify) m).getData()); + } + + @Test + public void sendNotification() { + this.clientSession.channelActive(null); + this.clientSession.handleMessage(this.classicOpen); + this.clientSession.handleMessage(new KeepaliveBuilder().build()); + assertEquals(this.clientSession.getState(), BGPClientSessionNegotiator.State.FINISHED); + this.clientSession.handleMessage(new OpenBuilder().setMyAsNumber(30).setHoldTimer(3).setVersion(new ProtocolVersion((short) 4)).build()); + assertEquals(3, this.receivedMsgs.size()); + assertTrue(this.receivedMsgs.get(2) instanceof Notify); + final Notification m = this.receivedMsgs.get(2); + assertEquals(BGPError.FSM_ERROR.getCode(), ((Notify) m).getErrorCode().shortValue()); + assertEquals(BGPError.FSM_ERROR.getSubcode(), ((Notify) m).getErrorSubcode().shortValue()); + } + + @Test + public void sameBGPIDs() { + this.clientSession.channelActive(null); + assertEquals(1, this.receivedMsgs.size()); + assertTrue(this.receivedMsgs.get(0) instanceof Open); + + this.clientSession.handleMessage(new OpenBuilder(this.classicOpen).setBgpIdentifier(new Ipv4Address("1.1.1.1")).build()); + assertEquals(2, this.receivedMsgs.size()); + assertTrue(this.receivedMsgs.get(1) instanceof Notify); + final Notification m = this.receivedMsgs.get(this.receivedMsgs.size() - 1); + assertEquals(BGPError.BAD_BGP_ID, BGPError.forValue(((Notify) m).getErrorCode(), ((Notify) m).getErrorSubcode())); + } + + @After + public void tearDown() { + + } }