X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=bgp%2Fparser-impl%2Fsrc%2Ftest%2Fjava%2Forg%2Fopendaylight%2Fprotocol%2Fbgp%2Fparser%2Fimpl%2FParserTest.java;h=75577bff2a00e4e81f2fddaaa6eaacc322c77329;hb=0fdeddbe3d072a88428599421191f0f60b2864e4;hp=1d46bbdbb0e0b8386ff430b46f3fbed3b2ae6583;hpb=c55a210ae10488e4cda316018577ead2a41461a9;p=bgpcep.git diff --git a/bgp/parser-impl/src/test/java/org/opendaylight/protocol/bgp/parser/impl/ParserTest.java b/bgp/parser-impl/src/test/java/org/opendaylight/protocol/bgp/parser/impl/ParserTest.java index 1d46bbdbb0..75577bff2a 100644 --- a/bgp/parser-impl/src/test/java/org/opendaylight/protocol/bgp/parser/impl/ParserTest.java +++ b/bgp/parser-impl/src/test/java/org/opendaylight/protocol/bgp/parser/impl/ParserTest.java @@ -7,294 +7,407 @@ */ package org.opendaylight.protocol.bgp.parser.impl; +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import static org.junit.matchers.JUnitMatchers.containsString; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; import java.net.UnknownHostException; -import java.util.Arrays; -import java.util.List; -import java.util.Map; - import org.junit.BeforeClass; import org.junit.Test; import org.opendaylight.protocol.bgp.parser.BGPDocumentedException; import org.opendaylight.protocol.bgp.parser.BGPError; import org.opendaylight.protocol.bgp.parser.BGPParsingException; -import org.opendaylight.protocol.bgp.parser.BgpTableTypeImpl; +import org.opendaylight.protocol.bgp.parser.impl.message.update.NextHopAttributeParser; +import org.opendaylight.protocol.bgp.parser.impl.message.update.OriginAttributeParser; import org.opendaylight.protocol.bgp.parser.spi.MessageRegistry; import org.opendaylight.protocol.bgp.parser.spi.pojo.ServiceLoaderBGPExtensionProviderContext; import org.opendaylight.protocol.util.ByteArray; -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.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.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.NotifyBuilder; -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.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.types.rev130919.Ipv4AddressFamily; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.UnicastSubsequentAddressFamily; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.Keepalive; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.KeepaliveBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.Notify; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.NotifyBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.Open; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.OpenBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.ProtocolVersion; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.Update; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.RouteRefresh; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.RouteRefreshBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.Ipv4AddressFamily; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.UnicastSubsequentAddressFamily; import org.opendaylight.yangtools.yang.binding.Notification; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; +import org.opendaylight.yangtools.yang.common.Uint16; +import org.opendaylight.yangtools.yang.common.Uint8; public class ParserTest { - - public static final byte[] openBMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - (byte) 0xff, (byte) 0x00, (byte) 0x1d, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4, - (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x00 }; - - public static final byte[] keepAliveBMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - (byte) 0xff, (byte) 0x00, (byte) 0x13, (byte) 0x04 }; - - public static final byte[] notificationBMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - (byte) 0xff, (byte) 0xff, (byte) 0x00, (byte) 0x17, (byte) 0x03, (byte) 0x02, (byte) 0x04, (byte) 0x04, (byte) 0x09 }; - - public static final byte[] openWithCpblt1 = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - (byte) 0xff, (byte) 0x00, (byte) 0x2d, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x48, (byte) 0x00, (byte) 0xb4, - (byte) 0xac, (byte) 0x14, (byte) 0xa0, (byte) 0xaa, (byte) 0x10, (byte) 0x02, (byte) 0x06, (byte) 0x01, (byte) 0x04, - (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x01, (byte) 0x02, (byte) 0x06, (byte) 0x01, (byte) 0x04, (byte) 0x40, - (byte) 0x04, (byte) 0x00, (byte) 0x47 }; - - public static final byte[] openWithCpblt2 = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - (byte) 0xff, (byte) 0x00, (byte) 0x2d, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x48, (byte) 0x00, (byte) 0xb4, - (byte) 0xac, (byte) 0x14, (byte) 0xa0, (byte) 0xaa, (byte) 0x10, (byte) 0x02, (byte) 0x06, (byte) 0x01, (byte) 0x04, - (byte) 0x40, (byte) 0x04, (byte) 0x00, (byte) 0x47, (byte) 0x02, (byte) 0x06, (byte) 0x01, (byte) 0x04, (byte) 0x00, - (byte) 0x01, (byte) 0x00, (byte) 0x01 }; - - static MessageRegistry reg; - - @BeforeClass - public static void setupClass() throws Exception { - reg = ServiceLoaderBGPExtensionProviderContext.createConsumerContext().getMessageRegistry(); - } - - @Test - public void testHeaderErrors() throws BGPParsingException, BGPDocumentedException { - byte[] wrong = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x00 }; - wrong = ByteArray.cutBytes(wrong, 16); - try { - ParserTest.reg.parseMessage(wrong); - fail("Exception should have occcured."); - } catch (final IllegalArgumentException e) { - assertEquals("Too few bytes in passed array. Passed: " + wrong.length + ". Expected: >= 19.", e.getMessage()); - return; - } - fail(); - } - - @Test - public void testBadMsgType() throws BGPParsingException { - final byte[] bytes = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - (byte) 0x00, (byte) 0x13, (byte) 0x08 }; - try { - ParserTest.reg.parseMessage(bytes); - fail("Exception should have occured."); - } catch (final BGPDocumentedException e) { - assertEquals(BGPError.BAD_MSG_TYPE, e.getError()); - return; - } - fail(); - } - - @Test - public void testKeepAliveMsg() throws BGPParsingException, BGPDocumentedException { - final Notification keepAlive = new KeepaliveBuilder().build(); - final byte[] bytes = ParserTest.reg.serializeMessage(keepAlive); - assertArrayEquals(keepAliveBMsg, bytes); - - final Notification m = ParserTest.reg.parseMessage(bytes); - - assertTrue(m instanceof Keepalive); - } - - @Test - public void testBadKeepAliveMsg() throws BGPParsingException { - final byte[] bytes = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - (byte) 0x00, (byte) 0x14, (byte) 0x04, (byte) 0x05 }; - - try { - ParserTest.reg.parseMessage(bytes); - fail("Exception should have occured."); - } catch (final BGPDocumentedException e) { - assertThat(e.getMessage(), containsString("Message length field not within valid range.")); - assertEquals(BGPError.BAD_MSG_LENGTH, e.getError()); - return; - } - fail(); - } - - @Test - public void testOpenMessage() throws UnknownHostException, BGPParsingException, BGPDocumentedException { - final Notification open = new OpenBuilder().setMyAsNumber(100).setHoldTimer(180).setBgpIdentifier(new Ipv4Address("20.20.20.20")).setVersion( - new ProtocolVersion((short) 4)).build(); - final byte[] bytes = ParserTest.reg.serializeMessage(open); - assertArrayEquals(openBMsg, bytes); - - final Notification m = ParserTest.reg.parseMessage(bytes); - - assertTrue(m instanceof Open); - assertEquals(100, ((Open) m).getMyAsNumber().intValue()); - assertEquals(180, ((Open) m).getHoldTimer().intValue()); - assertEquals(new Ipv4Address("20.20.20.20"), ((Open) m).getBgpIdentifier()); - assertTrue(((Open) m).getBgpParameters().isEmpty()); - } - - @Test - public void testBadHoldTimeError() throws BGPParsingException { - final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - (byte) 0x00, (byte) 0x1d, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0x01, (byte) 0x14, - (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x00 }; - - try { - ParserTest.reg.parseMessage(bMsg); - fail("Exception should have occured."); - } catch (final BGPDocumentedException e) { - assertEquals("Hold time value not acceptable.", e.getMessage()); - assertEquals(BGPError.HOLD_TIME_NOT_ACC, e.getError()); - return; - } - fail(); - } - - @Test - public void testBadMsgLength() throws BGPParsingException { - final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - (byte) 0x00, (byte) 0x1b, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4, (byte) 0xff, - (byte) 0xff, (byte) 0xff }; - - try { - ParserTest.reg.parseMessage(bMsg); - fail("Exception should have occured."); - } catch (final BGPDocumentedException e) { - assertEquals("Open message too small.", e.getMessage()); - assertEquals(BGPError.BAD_MSG_LENGTH, e.getError()); - } - } - - @Test - public void testBadVersion() throws BGPParsingException { - final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - (byte) 0x00, (byte) 0x1d, (byte) 0x01, (byte) 0x08, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4, (byte) 0x14, - (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x00 }; - - try { - ParserTest.reg.parseMessage(bMsg); - fail("Exception should have occured."); - } catch (final BGPDocumentedException e) { - assertEquals("BGP Protocol version 8 not supported.", e.getMessage()); - assertEquals(BGPError.VERSION_NOT_SUPPORTED, e.getError()); - return; - } - fail(); - } - - @Test - public void testNotificationMsg() throws BGPParsingException, BGPDocumentedException { - Notification notMsg = new NotifyBuilder().setErrorCode(BGPError.OPT_PARAM_NOT_SUPPORTED.getCode()).setErrorSubcode( - BGPError.OPT_PARAM_NOT_SUPPORTED.getSubcode()).setData(new byte[] { 4, 9 }).build(); - byte[] bytes = ParserTest.reg.serializeMessage(notMsg); - assertArrayEquals(notificationBMsg, bytes); - - Notification m = ParserTest.reg.parseMessage(bytes); - - assertTrue(m instanceof Notify); - assertEquals(BGPError.OPT_PARAM_NOT_SUPPORTED, BGPError.forValue(((Notify) m).getErrorCode(), ((Notify) m).getErrorSubcode())); - assertArrayEquals(new byte[] { 4, 9 }, ((Notify) m).getData()); - - notMsg = new NotifyBuilder().setErrorCode(BGPError.CONNECTION_NOT_SYNC.getCode()).setErrorSubcode( - BGPError.CONNECTION_NOT_SYNC.getSubcode()).build(); - bytes = ParserTest.reg.serializeMessage(notMsg); - - m = ParserTest.reg.parseMessage(bytes); - - assertTrue(m instanceof Notify); - assertEquals(BGPError.CONNECTION_NOT_SYNC, BGPError.forValue(((Notify) m).getErrorCode(), ((Notify) m).getErrorSubcode())); - assertNull(((Notify) m).getData()); - } - - @Test - public void testWrongLength() throws BGPParsingException { - final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - (byte) 0x00, (byte) 0x14, (byte) 0x03, (byte) 0x02 }; - - try { - ParserTest.reg.parseMessage(bMsg); - fail("Exception should have occured."); - } catch (final BGPDocumentedException e) { - assertEquals("Notification message too small.", e.getMessage()); - assertEquals(BGPError.BAD_MSG_LENGTH, e.getError()); - return; - } - fail(); - } - - @Test - public void testUnrecognizedError() throws BGPParsingException, BGPDocumentedException { - final byte[] bMsg = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, - (byte) 0x00, (byte) 0x15, (byte) 0x03, (byte) 0x02, (byte) 0xaa }; - - try { - ParserTest.reg.parseMessage(bMsg); - fail("Exception should have occured."); - } catch (final IllegalArgumentException e) { - assertEquals("BGP Error code 2 and subcode 170 not recognized.", e.getMessage()); - return; - } - fail(); - } - - @Test - public void testTLVParser() throws UnknownHostException { - - final BgpTableType t1 = new BgpTableTypeImpl(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class); - final BgpTableType t2 = new BgpTableTypeImpl(LinkstateAddressFamily.class, UnicastSubsequentAddressFamily.class); - - final List tlvs = Lists.newArrayList(); - - tlvs.add(new BgpParametersBuilder().setCParameters( - new CMultiprotocolBuilder().setMultiprotocolCapability( - new MultiprotocolCapabilityBuilder().setAfi(LinkstateAddressFamily.class).setSafi( - LinkstateSubsequentAddressFamily.class).build()).build()).build()); - tlvs.add(new BgpParametersBuilder().setCParameters( - new CMultiprotocolBuilder().setMultiprotocolCapability( - new MultiprotocolCapabilityBuilder().setAfi(Ipv4AddressFamily.class).setSafi(UnicastSubsequentAddressFamily.class).build()).build()).build()); - - final Map tableTypes = Maps.newHashMap(); - tableTypes.put(t1, true); - tableTypes.put(t2, true); - final Open open = new OpenBuilder().setMyAsNumber(72).setHoldTimer(180).setBgpIdentifier(new Ipv4Address("172.20.160.170")).setVersion( - new ProtocolVersion((short) 4)).setBgpParameters(tlvs).build(); - - final byte[] result = ParserTest.reg.serializeMessage(open); - - // the capabilities can be swapped. - assertTrue(Arrays.equals(openWithCpblt1, result) || Arrays.equals(openWithCpblt2, result)); - } + private static final byte[] OPEN_BMSG = new byte[] { + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0x00, (byte) 0x1d, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4, + (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x00 + }; + + private static final byte[] KEEPALIVE_BMSG = new byte[] { + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0x00, (byte) 0x13, (byte) 0x04 + }; + + private static final byte[] NOTIFICATION_BMSG = new byte[] { + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0x00, (byte) 0x17, (byte) 0x03, (byte) 0x02, (byte) 0x04, (byte) 0x04, (byte) 0x09 + }; + + private static final byte[] UPD_MSG_WITH_UNRECOGNIZED_ATTRIBUTE = new byte[] { + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0x00, (byte) 0x79, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x62, (byte) 0x90, (byte) 0x0e, (byte) 0x00, (byte) 0x34, (byte) 0x40, (byte) 0x04, (byte) 0x47, + (byte) 0x04, (byte) 0x0a, (byte) 0x19, (byte) 0x02, (byte) 0x1b, (byte) 0x00, (byte) 0x00, (byte) 0x01, + (byte) 0x00, (byte) 0x27, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x1a, (byte) 0x02, + (byte) 0x00, (byte) 0x00, (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x48, (byte) 0x02, + (byte) 0x01, (byte) 0x00, (byte) 0x04, (byte) 0x28, (byte) 0x28, (byte) 0x28, (byte) 0x28, (byte) 0x02, + (byte) 0x03, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x43, (byte) 0x40, (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x40, (byte) 0x02, (byte) 0x00, + (byte) 0x40, (byte) 0x05, (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte )0x64, (byte) 0x00, + (byte) 0x63, (byte) 0x19, (byte) 0x04, (byte) 0x02, (byte) 0x00, (byte) 0x08, (byte) 0x4f, (byte) 0x66, + (byte) 0x2d, (byte) 0x39, (byte) 0x6b, (byte) 0x2d, (byte) 0x30, (byte) 0x33, (byte) 0x04, (byte) 0x03, + (byte) 0x00, (byte) 0x01, (byte) 0x72, (byte) 0x04, (byte) 0x04, (byte) 0x00, (byte) 0x04, (byte) 0x2b, + (byte) 0x2b, (byte) 0x2b, (byte) 0x2b + }; + + // Update message with one IPv4 prefix NLRI and all mandatory path attributes present + private static final byte[] UPD_MSG_WITH_MANDATORY_ATTRIBUTES_PRESENT = new byte[] { + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0x00, (byte) 0x38, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x1c, (byte) 0x40, + (byte) 0x01, (byte) 0x01, (byte) 0x00, (byte) 0x40, (byte) 0x02, (byte) 0x00, (byte) 0x40, (byte) 0x03, + (byte) 0x04, (byte) 0x0a, (byte) 0x12, (byte) 0xa2, (byte) 0xf1, (byte) 0x80, (byte) 0x04, (byte) 0x04, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x40, (byte) 0x05, (byte) 0x04, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x64, (byte) 0x20, (byte) 0xc0, (byte) 0xa8, (byte) 0xfe, (byte) 0x03 + }; + + // Update message with one IPv4 prefix NLRI and all mandatory path attributes except ORIGIN present + private static final byte[] UPD_MSG_WITH_ONE_MANDATORY_ATTRIBUTE_NOT_PRESENT = new byte[] { + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0x00, (byte) 0x34, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x18, (byte) 0x40, + (byte) 0x02, (byte) 0x00, (byte) 0x40, (byte) 0x03, (byte) 0x04, (byte) 0x0a, (byte) 0x12, (byte) 0xa2, + (byte) 0xf1, (byte) 0x80, (byte) 0x04, (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x40, (byte) 0x05, (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x64, (byte) 0x20, + (byte) 0xc0, (byte) 0xa8, (byte) 0xfe, (byte) 0x03 + }; + + // Update message with one IPv4 prefix NLRI and ORIGIN, AS_PATH and NEXT_HOP mandatory path attributes not present + private static final byte[] UPD_MSG_WITH_MULTIPLE_MANDATORY_ATTRIBUTES_NOT_PRESENT = new byte[] { + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0x00, (byte) 0x2a, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0e, (byte) 0x80, + (byte) 0x04, (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x40, (byte) 0x05, + (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x64, (byte) 0x20, (byte) 0xc0, (byte) 0xa8, + (byte) 0xfe, (byte) 0x03 + }; + + private static final byte[] RR_MSG = new byte[] { + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0x00, (byte) 0x17, (byte) 0x05, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x01 + }; + + private static MessageRegistry reg; + + @BeforeClass + public static void setupClass() throws Exception { + reg = ServiceLoaderBGPExtensionProviderContext.getSingletonInstance().getMessageRegistry(); + } + + @Test + public void testHeaderErrors() throws BGPParsingException, BGPDocumentedException { + byte[] wrong = new byte[] { + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0x00 + }; + wrong = ByteArray.cutBytes(wrong, 16); + try { + ParserTest.reg.parseMessage(Unpooled.copiedBuffer(wrong), null); + fail("Exception should have occcured."); + } catch (final IllegalArgumentException e) { + assertEquals("Too few bytes in passed array. Passed: " + wrong.length + ". Expected: >= 19.", + e.getMessage()); + return; + } + fail(); + } + + @Test + public void testBadMsgType() throws BGPParsingException { + final byte[] bytes = { + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0x00, (byte) 0x13, (byte) 0x08 + }; + try { + ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bytes), null); + fail("Exception should have occured."); + } catch (final BGPDocumentedException e) { + assertEquals(BGPError.BAD_MSG_TYPE, e.getError()); + return; + } + fail(); + } + + @Test + public void testKeepAliveMsg() throws BGPParsingException, BGPDocumentedException { + final Notification keepAlive = new KeepaliveBuilder().build(); + final ByteBuf buffer = Unpooled.buffer(); + ParserTest.reg.serializeMessage(keepAlive, buffer); + assertArrayEquals(KEEPALIVE_BMSG, ByteArray.getAllBytes(buffer)); + + final Notification m = ParserTest.reg.parseMessage(Unpooled.copiedBuffer(ByteArray.getAllBytes(buffer)), null); + assertTrue(m instanceof Keepalive); + } + + @Test + public void testBadKeepAliveMsg() throws BGPParsingException { + final byte[] bytes = new byte[] { + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0x00, (byte) 0x14, (byte) 0x04, (byte) 0x05 + }; + + try { + ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bytes), null); + fail("Exception should have occured."); + } catch (final BGPDocumentedException e) { + assertThat(e.getMessage(), containsString("Message length field not within valid range.")); + assertEquals(BGPError.BAD_MSG_LENGTH, e.getError()); + return; + } + fail(); + } + + @Test + public void testOpenMessage() throws UnknownHostException, BGPParsingException, BGPDocumentedException { + final Notification open = new OpenBuilder() + .setMyAsNumber(Uint16.valueOf(100)) + .setHoldTimer(Uint16.valueOf(180)) + .setBgpIdentifier(new Ipv4AddressNoZone("20.20.20.20")) + .setVersion(new ProtocolVersion(Uint8.valueOf(4))) + .build(); + final ByteBuf bytes = Unpooled.buffer(); + ParserTest.reg.serializeMessage(open, bytes); + assertArrayEquals(OPEN_BMSG, ByteArray.getAllBytes(bytes)); + + final Notification m = ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bytes), null); + assertTrue(m instanceof Open); + + final Open mo = (Open) m; + assertEquals(100, mo.getMyAsNumber().intValue()); + assertEquals(180, mo.getHoldTimer().intValue()); + assertEquals(new Ipv4Address("20.20.20.20"), mo.getBgpIdentifier()); + assertTrue(mo.getBgpParameters().isEmpty()); + } + + @Test + public void testBadHoldTimeError() throws BGPParsingException { + final byte[] bMsg = new byte[] { + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0x00, (byte) 0x1d, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0x01, + (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x00 + }; + + try { + ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bMsg), null); + fail("Exception should have occured."); + } catch (final BGPDocumentedException e) { + assertEquals("Hold time value not acceptable.", e.getMessage()); + assertEquals(BGPError.HOLD_TIME_NOT_ACC, e.getError()); + return; + } + fail(); + } + + @Test + public void testBadMsgLength() throws BGPParsingException { + final byte[] bMsg = new byte[] { + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0x00, (byte) 0x1b, (byte) 0x01, (byte) 0x04, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4, + (byte) 0xff, (byte) 0xff, (byte) 0xff + }; + + try { + ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bMsg), null); + fail("Exception should have occured."); + } catch (final BGPDocumentedException e) { + assertEquals("Open message too small.", e.getMessage()); + assertEquals(BGPError.BAD_MSG_LENGTH, e.getError()); + } + } + + @Test + public void testBadVersion() throws BGPParsingException { + final byte[] bMsg = new byte[] { + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0x00, (byte) 0x1d, (byte) 0x01, (byte) 0x08, (byte) 0x00, (byte) 0x64, (byte) 0x00, (byte) 0xb4, + (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x14, (byte) 0x00 + }; + + try { + ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bMsg), null); + fail("Exception should have occured."); + } catch (final BGPDocumentedException e) { + assertEquals("BGP Protocol version 8 not supported.", e.getMessage()); + assertEquals(BGPError.VERSION_NOT_SUPPORTED, e.getError()); + return; + } + fail(); + } + + @Test + public void testNotificationMsg() throws BGPParsingException, BGPDocumentedException { + Notification notMsg = new NotifyBuilder().setErrorCode(BGPError.OPT_PARAM_NOT_SUPPORTED.getCode()) + .setErrorSubcode(BGPError.OPT_PARAM_NOT_SUPPORTED.getSubcode()).setData(new byte[] { 4, 9 }).build(); + final ByteBuf bytes = Unpooled.buffer(); + ParserTest.reg.serializeMessage(notMsg, bytes); + assertArrayEquals(NOTIFICATION_BMSG, ByteArray.subByte(bytes.array(),0,bytes.writerIndex())); + + Notification msg = ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bytes), null); + + assertTrue(msg instanceof Notify); + assertEquals(BGPError.OPT_PARAM_NOT_SUPPORTED, BGPError.forValue(((Notify) msg).getErrorCode(), + ((Notify) msg).getErrorSubcode())); + assertArrayEquals(new byte[] { 4, 9 }, ((Notify) msg).getData()); + + notMsg = new NotifyBuilder().setErrorCode(BGPError.CONNECTION_NOT_SYNC.getCode()).setErrorSubcode( + BGPError.CONNECTION_NOT_SYNC.getSubcode()).build(); + + bytes.clear(); + + ParserTest.reg.serializeMessage(notMsg, bytes); + + msg = ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bytes), null); + + assertTrue(msg instanceof Notify); + assertEquals(BGPError.CONNECTION_NOT_SYNC, BGPError.forValue(((Notify) msg).getErrorCode(), + ((Notify) msg).getErrorSubcode())); + assertNull(((Notify) msg).getData()); + } + + @Test + public void testWrongLength() throws BGPParsingException { + final byte[] bMsg = new byte[] { + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0x00, (byte) 0x14, (byte) 0x03, (byte) 0x02 + }; + + try { + ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bMsg), null); + fail("Exception should have occured."); + } catch (final BGPDocumentedException e) { + assertEquals("Notification message too small.", e.getMessage()); + assertEquals(BGPError.BAD_MSG_LENGTH, e.getError()); + return; + } + fail(); + } + + @Test + public void testUnrecognizedError() throws BGPParsingException, BGPDocumentedException { + final byte[] bMsg = new byte[] { + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, + (byte) 0x00, (byte) 0x15, (byte) 0x03, (byte) 0x02, (byte) 0xaa + }; + + try { + ParserTest.reg.parseMessage(Unpooled.copiedBuffer(bMsg), null); + fail("Exception should have occured."); + } catch (final IllegalArgumentException e) { + assertEquals("BGP Error code 2 and subcode 170 not recognized.", e.getMessage()); + return; + } + fail(); + } + + @Test + public void testParseUpdMsgWithUnrecognizedAttribute() throws BGPDocumentedException, BGPParsingException { + try { + reg.parseMessage(Unpooled.copiedBuffer(UPD_MSG_WITH_UNRECOGNIZED_ATTRIBUTE), null); + fail("Exception should have occured."); + } catch (final BGPDocumentedException e) { + assertEquals("Well known attribute not recognized.", e.getMessage()); + assertEquals(BGPError.WELL_KNOWN_ATTR_NOT_RECOGNIZED, e.getError()); + return; + } + fail(); + } + + @Test + public void testParseUpdMsgWithMandatoryAttributesPresent() throws BGPDocumentedException, BGPParsingException { + try { + final Notification msg = reg.parseMessage(Unpooled.copiedBuffer(UPD_MSG_WITH_MANDATORY_ATTRIBUTES_PRESENT), + null); + assertTrue(msg instanceof Update); + } catch (final BGPDocumentedException e) { + fail("Exception should not have occured."); + } + } + + @Test + public void testParseUpdMsgWithOneMandatoryAttributeNotPresent() + throws BGPDocumentedException, BGPParsingException { + try { + reg.parseMessage(Unpooled.copiedBuffer(UPD_MSG_WITH_ONE_MANDATORY_ATTRIBUTE_NOT_PRESENT), null); + fail("Exception should have occured."); + } catch (final BGPDocumentedException e) { + assertEquals(BGPError.MANDATORY_ATTR_MISSING_MSG + "ORIGIN", e.getMessage()); + assertEquals(BGPError.WELL_KNOWN_ATTR_MISSING, e.getError()); + assertArrayEquals(new byte[] { OriginAttributeParser.TYPE }, e.getData()); + return; + } + fail(); + } + + @Test + public void testParseUpdMsgWithMultipleMandatoryAttributesNotPresent() + throws BGPDocumentedException, BGPParsingException { + try { + reg.parseMessage(Unpooled.copiedBuffer(UPD_MSG_WITH_MULTIPLE_MANDATORY_ATTRIBUTES_NOT_PRESENT), null); + fail("Exception should have occured."); + } catch (final BGPDocumentedException e) { + assertEquals(BGPError.MANDATORY_ATTR_MISSING_MSG + "NEXT_HOP", e.getMessage()); + assertEquals(BGPError.WELL_KNOWN_ATTR_MISSING, e.getError()); + assertArrayEquals(new byte[] { NextHopAttributeParser.TYPE }, e.getData()); + return; + } + fail(); + } + + @Test + public void testRouteRefreshMsg() throws BGPDocumentedException, BGPParsingException { + final Notification rrMsg = new RouteRefreshBuilder().setAfi(Ipv4AddressFamily.class) + .setSafi(UnicastSubsequentAddressFamily.class).build(); + final ByteBuf buffer = Unpooled.buffer(); + ParserTest.reg.serializeMessage(rrMsg, buffer); + assertArrayEquals(RR_MSG, ByteArray.getAllBytes(buffer)); + + final Notification m = ParserTest.reg.parseMessage( + Unpooled.copiedBuffer(ByteArray.getAllBytes(buffer)), null); + + assertTrue(m instanceof RouteRefresh); + } }