/*
 * Copyright 2015 Open Networking Laboratory
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.onosproject.bgpio.protocol;


import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.core.Is.is;

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.junit.Test;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.IpPrefix;
import org.onosproject.bgpio.exceptions.BgpParseException;
import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4.ProtocolType;
import org.onosproject.bgpio.protocol.ver4.BgpPathAttributes;
import org.onosproject.bgpio.types.AsPath;
import org.onosproject.bgpio.types.BgpHeader;
import org.onosproject.bgpio.types.BgpValueType;
import org.onosproject.bgpio.types.LinkStateAttributes;
import org.onosproject.bgpio.types.Med;
import org.onosproject.bgpio.types.MpReachNlri;
import org.onosproject.bgpio.types.Origin;
import org.onosproject.bgpio.types.Origin.OriginType;
import org.onosproject.bgpio.types.attr.BgpAttrNodeFlagBitTlv;
import org.onosproject.bgpio.types.attr.BgpAttrNodeIsIsAreaId;
import org.onosproject.bgpio.types.attr.BgpAttrNodeMultiTopologyId;
import org.onosproject.bgpio.types.attr.BgpAttrNodeName;
import org.onosproject.bgpio.types.attr.BgpAttrRouterIdV4;
import org.onosproject.bgpio.types.attr.BgpAttrOpaqueNode;
import org.onosproject.bgpio.types.attr.BgpLinkAttrIsIsAdminstGrp;
import org.onosproject.bgpio.types.attr.BgpLinkAttrMplsProtocolMask;
import org.onosproject.bgpio.types.attr.BgpLinkAttrOpaqLnkAttrib;
import org.onosproject.bgpio.types.attr.BgpLinkAttrProtectionType.ProtectionType;
import org.onosproject.bgpio.types.attr.BgpLinkAttrSrlg;
import org.onosproject.bgpio.types.attr.BgpLinkAttrTeDefaultMetric;
import org.onosproject.bgpio.types.attr.BgpPrefixAttrOpaqueData;
import org.onosproject.bgpio.types.attr.BgpLinkAttrProtectionType;
import org.onosproject.bgpio.types.attr.BgpPrefixAttrRouteTag;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;

/**
 * UT for Update Message (Link State Attribute and all its TLVs).
 */
public class BgpUpdateLinkStateAttrTest {

    /**
     * Test for LinkStateattribute BgpAttrNodeRouterId and BgpLinkAttrIGPMetric.
     *
     * @throws BgpParseException while parsing update message
     */
    @Test
    public void bgpUpdateMessageTest1() throws BgpParseException {
        byte[] updateMsg = 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, 0x00, (byte) 0x95,
                0x02, 0x00, 0x04,
                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
                0x00, 0x7A, //path attribute len
                0x04, 0x01, 0x01, 0x00, //origin
                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
                0x00, //reserved
                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
                0x00, (byte) 0x95, 0x02, 0x50, 0x21, //link nlri
                (byte) 0x80, 0x1d, 0x0f,  //linkstate attr
                0x04, 0x04, 0x00, 0x04, (byte) 0xbd, 0x59, 0x4c, 0x62, //BgpAttrNodeRouterId
                0x04, 0x47, 0x00, 0x03, 0x00, 0x00, 0x0a}; //BgpLinkAttrIGPMetric

        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
        buffer.writeBytes(updateMsg);

        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
        BgpMessage message = null;
        BgpHeader bgpHeader = new BgpHeader();

        message = reader.readFrom(buffer, bgpHeader);

        assertThat(message, instanceOf(BgpUpdateMsg.class));
        BgpUpdateMsg other = (BgpUpdateMsg) message;

        byte[] marker = 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 };

        assertThat(other.getHeader().getMarker(), is(marker));
        assertThat(other.getHeader().getType(), is((byte) 2));
        assertThat(other.getHeader().getLength(), is((short) 149));

        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};

        while (listIterator1.hasNext()) {
            IpPrefix testPrefixValue = listIterator1.next();
            assertThat(testPrefixValue.prefixLength(), is((int) 24));
            assertThat(testPrefixValue.address().toOctets(), is(prefix));
        }

        BgpValueType testPathAttribute = null;
        Origin origin;
        AsPath aspath;
        Med med;
        MpReachNlri mpReach;
        LinkStateAttributes linkStateAttr;
        List<BgpValueType> pathAttributeList = new LinkedList<>();
        BgpPathAttributes pathAttribute = other.bgpPathAttributes();
        pathAttributeList = pathAttribute.pathAttributes();
        ListIterator<BgpValueType> listIterator = pathAttributeList.listIterator();
        OriginType originValue = OriginType.IGP;

        //compare Origin
        testPathAttribute = listIterator.next();
        origin = (Origin) testPathAttribute;
        assertThat(origin.origin(), is(originValue));

        //compare Aspath
        testPathAttribute = listIterator.next();
        aspath = (AsPath) testPathAttribute;
        ListIterator<Short> listIterator2 = aspath.asPathSeq().listIterator();
        assertThat(listIterator2.next(), is((short) 65001));

        //compare MED
        testPathAttribute = listIterator.next();
        med = (Med) testPathAttribute;
        assertThat(med.med(), is(0));

        //compare Mpreach
        testPathAttribute = listIterator.next();
        mpReach = (MpReachNlri) testPathAttribute;
        assertThat(mpReach.mpReachNlriLen(), is((int) 83));
        assertThat(mpReach.getType(), is((short) 14));

        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
        testMpReachNlri = mpReach.mpReachNlri();

        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
        BgpLSNlri testnlri =  list1.next();
        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.LINK;
        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
        assertThat(testnlri.getIdentifier(), is((long) 0));
        assertThat(testnlri.getNlriType(), is(nlriType));
        assertThat(testnlri.getProtocolId(), is(protocolId));

        //compare LinkStateAttributes
        testPathAttribute = listIterator.next();
        linkStateAttr = (LinkStateAttributes) testPathAttribute;
        byte[] linkAttrbs = new byte[] {(byte) 0x80, 0x1d, 0x0f, 0x04, 0x04, 0x00, 0x04, (byte) 0xbd, 0x59, 0x4c,
                0x62, 0x04, 0x47, 0x00, 0x03, 0x00, 0x00, 0x0a };
        ChannelBuffer cb = ChannelBuffers.dynamicBuffer();
        cb.writeBytes(linkAttrbs);
        LinkStateAttributes obj = LinkStateAttributes.read(cb);

        assertThat(linkStateAttr.linkStateAttributes(), is(obj.linkStateAttributes()));
        assertThat(linkStateAttr.getType(), is((short) 29));
    }

    /**
     * Test for LinkStateattribute BgpAttrNodeRouterId and BgpAttrNodeRouterId.
     *
     * @throws BgpParseException while parsing update message
     */
    @Test
    public void bgpUpdateMessageTest2() throws BgpParseException {
        byte[] updateMsg = 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, 0x00, (byte) 0x96,
                0x02, 0x00, 0x04,
                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
                0x00, 0x7b, //path attribute len
                0x04, 0x01, 0x01, 0x00, //origin
                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
                0x00, //reserved
                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
                0x00, (byte) 0x95, 0x02, 0x50, 0x21, //link nlri
                (byte) 0x80, 0x1d, 0x10,  //linkstate attr
                0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15, 0x15, //BgpAttrNodeRouterId
                0x04, 0x06, 0x00, 0x04, 0x16, 0x16, 0x16, 0x16}; //BgpAttrNodeRouterId
        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
        buffer.writeBytes(updateMsg);

        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
        BgpMessage message = null;
        BgpHeader bgpHeader = new BgpHeader();

        message = reader.readFrom(buffer, bgpHeader);

        assertThat(message, instanceOf(BgpUpdateMsg.class));
        BgpUpdateMsg other = (BgpUpdateMsg) message;

        byte[] marker = 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 };

        assertThat(other.getHeader().getMarker(), is(marker));
        assertThat(other.getHeader().getType(), is((byte) 2));
        assertThat(other.getHeader().getLength(), is((short) 150));

        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};

        while (listIterator1.hasNext()) {
            IpPrefix testPrefixValue = listIterator1.next();
            assertThat(testPrefixValue.prefixLength(), is((int) 24));
            assertThat(testPrefixValue.address().toOctets(), is(prefix));
        }

        BgpValueType testPathAttribute = null;
        Origin origin;
        AsPath asPath;
        Med med;
        MpReachNlri mpReach;
        LinkStateAttributes linkStateAttr;
        List<BgpValueType> pathAttributeList = new LinkedList<>();
        BgpPathAttributes pathAttribute = other.bgpPathAttributes();
        pathAttributeList = pathAttribute.pathAttributes();
        ListIterator<BgpValueType> listIterator = pathAttributeList.listIterator();
        OriginType originValue = OriginType.IGP;

        testPathAttribute = listIterator.next();
        origin = (Origin) testPathAttribute;
        assertThat(origin.origin(), is(originValue));

        testPathAttribute = listIterator.next();
        asPath = (AsPath) testPathAttribute;
        ListIterator<Short> listIterator2 = asPath.asPathSeq().listIterator();
        assertThat(listIterator2.next(), is((short) 65001));

        testPathAttribute = listIterator.next();
        med = (Med) testPathAttribute;
        assertThat(med.med(), is(0));

        testPathAttribute = listIterator.next();
        mpReach = (MpReachNlri) testPathAttribute;
        assertThat(mpReach.mpReachNlriLen(), is((int) 83));
        assertThat(mpReach.getType(), is((short) 14));

        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
        testMpReachNlri = mpReach.mpReachNlri();

        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
        BgpLSNlri testnlri =  list1.next();
        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.LINK;
        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
        assertThat(testnlri.getIdentifier(), is((long) 0));
        assertThat(testnlri.getNlriType(), is(nlriType));
        assertThat(testnlri.getProtocolId(), is(protocolId));

        testPathAttribute = listIterator.next();
        linkStateAttr = (LinkStateAttributes) testPathAttribute;
        byte[] linkAttrbs = new byte[] {(byte) 0x80, 0x1d, 0x10, 0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15,
                0x15, 0x04, 0x06, 0x00, 0x04, 0x16, 0x16, 0x16, 0x16 };
        ChannelBuffer cb = ChannelBuffers.dynamicBuffer();
        cb.writeBytes(linkAttrbs);
        LinkStateAttributes obj = LinkStateAttributes.read(cb);

        assertThat(linkStateAttr.linkStateAttributes(), is(obj.linkStateAttributes()));
        assertThat(linkStateAttr.getType(), is((short) 29));
    }

    /**
     * Test for LinkStateattribute BgpAttrNodeRouterId and BgpPrefixAttrMetric.
     *
     * @throws BgpParseException while parsing update message
     */
    @Test
    public void bgpUpdateMessageTest3() throws BgpParseException {
        byte[] updateMsg = 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, 0x00, (byte) 0x96,
                0x02, 0x00, 0x04,
                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
                0x00, 0x7b, //path attribute len
                0x04, 0x01, 0x01, 0x00, //origin
                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
                0x00, //reserved
                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
                0x00, (byte) 0x95, 0x02, 0x50, 0x21, //link nlri
                (byte) 0x80, 0x1d, 0x10,  //linkstate attr
                0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15, 0x15, //BgpAttrNodeRouterId
                0x04, (byte) 0x83, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00}; //BgpPrefixAttrMetric
        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
        buffer.writeBytes(updateMsg);

        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
        BgpMessage message = null;
        BgpHeader bgpHeader = new BgpHeader();

        message = reader.readFrom(buffer, bgpHeader);

        assertThat(message, instanceOf(BgpUpdateMsg.class));
        BgpUpdateMsg other = (BgpUpdateMsg) message;

        byte[] marker = 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 };

        assertThat(other.getHeader().getMarker(), is(marker));
        assertThat(other.getHeader().getType(), is((byte) 2));
        assertThat(other.getHeader().getLength(), is((short) 150));

        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};

        while (listIterator1.hasNext()) {
            IpPrefix testPrefixValue = listIterator1.next();
            assertThat(testPrefixValue.prefixLength(), is((int) 24));
            assertThat(testPrefixValue.address().toOctets(), is(prefix));
        }

        BgpValueType testPathAttribute = null;
        Origin origin;
        AsPath aspath;
        Med med;
        MpReachNlri mpReach;
        LinkStateAttributes linkStateAttr;
        List<BgpValueType> pathAttributeList = new LinkedList<>();
        BgpPathAttributes pathAttribute = other.bgpPathAttributes();
        pathAttributeList = pathAttribute.pathAttributes();
        ListIterator<BgpValueType> listIterator = pathAttributeList.listIterator();
        OriginType originValue = OriginType.IGP;

        testPathAttribute = listIterator.next();
        origin = (Origin) testPathAttribute;
        assertThat(origin.origin(), is(originValue));

        testPathAttribute = listIterator.next();
        aspath = (AsPath) testPathAttribute;
        ListIterator<Short> listIterator2 = aspath.asPathSeq().listIterator();
        assertThat(listIterator2.next(), is((short) 65001));

        testPathAttribute = listIterator.next();
        med = (Med) testPathAttribute;
        assertThat(med.med(), is(0));

        testPathAttribute = listIterator.next();
        mpReach = (MpReachNlri) testPathAttribute;
        assertThat(mpReach.mpReachNlriLen(), is((int) 83));
        assertThat(mpReach.getType(), is((short) 14));

        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
        testMpReachNlri = mpReach.mpReachNlri();

        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
        BgpLSNlri testnlri =  list1.next();
        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.LINK;
        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
        assertThat(testnlri.getIdentifier(), is((long) 0));
        assertThat(testnlri.getNlriType(), is(nlriType));
        assertThat(testnlri.getProtocolId(), is(protocolId));

        testPathAttribute = listIterator.next();
        linkStateAttr = (LinkStateAttributes) testPathAttribute;
        byte[] linkAttrbs = new byte[] {(byte) 0x80, 0x1d, 0x10, 0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15,
                0x15, 0x04, (byte) 0x83, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00 };
        ChannelBuffer cb = ChannelBuffers.dynamicBuffer();
        cb.writeBytes(linkAttrbs);
        LinkStateAttributes obj = LinkStateAttributes.read(cb);

        assertThat(linkStateAttr.linkStateAttributes(), is(obj.linkStateAttributes()));
        assertThat(linkStateAttr.getType(), is((short) 29));
    }

    /**
     * Test for LinkStateattribute BgpAttrNodeRouterId and BgpAttrNodeName.
     *
     * @throws BgpParseException while parsing update message
     */
    @Test
    public void bgpUpdateMessageTest4() throws BgpParseException {
        byte[] updateMsg = 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, 0x00, (byte) 0x98,
                0x02, 0x00, 0x04,
                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
                0x00, 0x7d, //path attribute len
                0x04, 0x01, 0x01, 0x00, //origin
                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
                0x00, //reserved
                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
                0x00, (byte) 0x95, 0x02, 0x50, 0x21, //link nlri
                (byte) 0x80, 0x1d, 0x12,  //linkstate attr
                0x04, 0x04, 0x00, 0x04, 0x15, 0x15, 0x15, 0x15, //BgpAttrNodeRouterId
                0x04, 0x02, 0x00, 0x06, 0x37, 0x37, 0x35, 0x30, 0x2d, 0x31 }; //BgpAttrNodeName

        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
        buffer.writeBytes(updateMsg);

        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
        BgpMessage message = null;
        BgpHeader bgpHeader = new BgpHeader();

        message = reader.readFrom(buffer, bgpHeader);

        assertThat(message, instanceOf(BgpUpdateMsg.class));
        BgpUpdateMsg other = (BgpUpdateMsg) message;

        byte[] marker = 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 };

        assertThat(other.getHeader().getMarker(), is(marker));
        assertThat(other.getHeader().getType(), is((byte) 2));
        assertThat(other.getHeader().getLength(), is((short) 152));

        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};

        while (listIterator1.hasNext()) {
            IpPrefix testPrefixValue = listIterator1.next();
            assertThat(testPrefixValue.prefixLength(), is((int) 24));
            assertThat(testPrefixValue.address().toOctets(), is(prefix));
        }

        BgpValueType testPathAttribute = null;
        Origin origin;
        AsPath aspath;
        Med med;
        MpReachNlri mpReach;
        LinkStateAttributes linkStateAttr;
        List<BgpValueType> pathAttributeList = new LinkedList<>();
        BgpPathAttributes pathAttribute = other.bgpPathAttributes();
        pathAttributeList = pathAttribute.pathAttributes();
        ListIterator<BgpValueType> listIterator = pathAttributeList.listIterator();
        OriginType originValue = OriginType.IGP;

        testPathAttribute = listIterator.next();
        origin = (Origin) testPathAttribute;
        assertThat(origin.origin(), is(originValue));

        testPathAttribute = listIterator.next();
        aspath = (AsPath) testPathAttribute;
        ListIterator<Short> listIterator2 = aspath.asPathSeq().listIterator();
        assertThat(listIterator2.next(), is((short) 65001));

        testPathAttribute = listIterator.next();
        med = (Med) testPathAttribute;
        assertThat(med.med(), is(0));

        testPathAttribute = listIterator.next();
        mpReach = (MpReachNlri) testPathAttribute;
        assertThat(mpReach.mpReachNlriLen(), is((int) 83));
        assertThat(mpReach.getType(), is((short) 14));

        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
        testMpReachNlri = mpReach.mpReachNlri();

        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
        BgpLSNlri testnlri =  list1.next();
        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.LINK;
        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
        assertThat(testnlri.getIdentifier(), is((long) 0));
        assertThat(testnlri.getNlriType(), is(nlriType));
        assertThat(testnlri.getProtocolId(), is(protocolId));

        testPathAttribute = listIterator.next();
        linkStateAttr = (LinkStateAttributes) testPathAttribute;
        byte[] linkAttrbs = new byte[] {(byte) 0x80, 0x1d, 0x12, 0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15,
                0x15, 0x04, 0x02, 0x00, 0x06, 0x37, 0x37, 0x35, 0x30, 0x2d, 0x31 };
        ChannelBuffer cb = ChannelBuffers.dynamicBuffer();
        cb.writeBytes(linkAttrbs);
        LinkStateAttributes obj = LinkStateAttributes.read(cb);

        ListIterator<BgpValueType> list = obj.linkStateAttributes().listIterator();
        ListIterator<BgpValueType> list2 = linkStateAttr.linkStateAttributes().listIterator();
        assertThat(list.next(), is(list2.next()));
        assertThat(((BgpAttrNodeName) list2.next()).attrNodeName(), is(((BgpAttrNodeName) list.next()).attrNodeName()));
        assertThat(linkStateAttr.getType(), is((short) 29));
    }

    /**
     * Test for LinkStateattribute BgpAttrNodeRouterId and BgpAttrNodeIsIsAreaId.
     *
     * @throws BgpParseException while parsing update message
     */
    @Test
    public void bgpUpdateMessageTest5() throws BgpParseException {
        byte[] updateMsg = 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, 0x00, (byte) 0x95,
                0x02, 0x00, 0x04,
                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
                0x00, 0x7A, //path attribute len
                0x04, 0x01, 0x01, 0x00, //origin
                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
                0x00, //reserved
                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
                0x00, (byte) 0x95, 0x02, 0x50, 0x21, //link nlri
                (byte) 0x80, 0x1d, 0x0f,  //linkstate attr
                0x04, 0x04, 0x00, 0x04, (byte) 0xbd, 0x59, 0x4c, 0x62, //BgpAttrNodeRouterId
                0x04, 0x03, 0x00, 0x03, 0x40, 0x01, 0x00}; //BgpAttrNodeIsIsAreaId

        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
        buffer.writeBytes(updateMsg);

        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
        BgpMessage message = null;
        BgpHeader bgpHeader = new BgpHeader();

        message = reader.readFrom(buffer, bgpHeader);

        assertThat(message, instanceOf(BgpUpdateMsg.class));
        BgpUpdateMsg other = (BgpUpdateMsg) message;

        byte[] marker = 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 };

        assertThat(other.getHeader().getMarker(), is(marker));
        assertThat(other.getHeader().getType(), is((byte) 2));
        assertThat(other.getHeader().getLength(), is((short) 149));

        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};

        while (listIterator1.hasNext()) {
            IpPrefix testPrefixValue = listIterator1.next();
            assertThat(testPrefixValue.prefixLength(), is((int) 24));
            assertThat(testPrefixValue.address().toOctets(), is(prefix));
        }

        BgpValueType testPathAttribute = null;
        Origin origin;
        AsPath aspath;
        Med med;
        MpReachNlri mpReach;
        LinkStateAttributes linkStateAttr;
        List<BgpValueType> pathAttributeList = new LinkedList<>();
        BgpPathAttributes pathAttribute = other.bgpPathAttributes();
        pathAttributeList = pathAttribute.pathAttributes();
        ListIterator<BgpValueType> listIterator = pathAttributeList.listIterator();
        OriginType originValue = OriginType.IGP;

        testPathAttribute = listIterator.next();
        origin = (Origin) testPathAttribute;
        assertThat(origin.origin(), is(originValue));

        testPathAttribute = listIterator.next();
        aspath = (AsPath) testPathAttribute;
        ListIterator<Short> listIterator2 = aspath.asPathSeq().listIterator();
        assertThat(listIterator2.next(), is((short) 65001));

        testPathAttribute = listIterator.next();
        med = (Med) testPathAttribute;
        assertThat(med.med(), is(0));

        testPathAttribute = listIterator.next();
        mpReach = (MpReachNlri) testPathAttribute;
        assertThat(mpReach.mpReachNlriLen(), is((int) 83));
        assertThat(mpReach.getType(), is((short) 14));

        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
        testMpReachNlri = mpReach.mpReachNlri();

        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
        BgpLSNlri testnlri =  list1.next();
        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.LINK;
        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
        assertThat(testnlri.getIdentifier(), is((long) 0));
        assertThat(testnlri.getNlriType(), is(nlriType));
        assertThat(testnlri.getProtocolId(), is(protocolId));

        testPathAttribute = listIterator.next();
        linkStateAttr = (LinkStateAttributes) testPathAttribute;
        byte[] linkAttrbs = new byte[] {(byte) 0x80, 0x1d, 0x0f, 0x04, 0x04, 0x00, 0x04, (byte) 0xbd, 0x59, 0x4c,
                0x62, 0x04, 0x03, 0x00, 0x03, 0x40, 0x01, 0x00 };
        ChannelBuffer cb = ChannelBuffers.dynamicBuffer();
        cb.writeBytes(linkAttrbs);
        LinkStateAttributes obj = LinkStateAttributes.read(cb);

        ListIterator<BgpValueType> list = obj.linkStateAttributes().listIterator();
        ListIterator<BgpValueType> list2 = linkStateAttr.linkStateAttributes().listIterator();
        assertThat(list.next(), is(list2.next()));
        assertThat(((BgpAttrNodeIsIsAreaId) list2.next()).attrNodeIsIsAreaId(),
                is(((BgpAttrNodeIsIsAreaId) list.next()).attrNodeIsIsAreaId()));
        assertThat(linkStateAttr.getType(), is((short) 29));
    }

    /**
     * Test for LinkStateattribute BgpAttrNodeRouterId and BgpAttrRouterIdV6.
     *
     * @throws BgpParseException while parsing update message
     */
    @Test
    public void bgpUpdateMessageTest6() throws BgpParseException {
        byte[] updateMsg = 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, 0x00, (byte) 0xA2,
                0x02, 0x00, 0x04,
                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
                0x00, (byte) 0x87, //path attribute len
                0x04, 0x01, 0x01, 0x00, //origin
                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
                0x00, //reserved
                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
                0x00, (byte) 0x95, 0x02, 0x50, 0x21, //link nlri
                (byte) 0x80, 0x1d, 0x1C,  //linkstate attr
                0x04, 0x04, 0x00, 0x04, 0x15, 0x15, 0x15, 0x15, //BgpAttrNodeRouterId
                0x04, 0x05, 0x00, 0x10, 0x01, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x01}; //BgpAttrRouterIdV6
        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
        buffer.writeBytes(updateMsg);

        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
        BgpMessage message = null;
        BgpHeader bgpHeader = new BgpHeader();

        message = reader.readFrom(buffer, bgpHeader);

        assertThat(message, instanceOf(BgpUpdateMsg.class));
        BgpUpdateMsg other = (BgpUpdateMsg) message;

        byte[] marker = 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 };

        assertThat(other.getHeader().getMarker(), is(marker));
        assertThat(other.getHeader().getType(), is((byte) 2));
        assertThat(other.getHeader().getLength(), is((short) 162));

        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};

        while (listIterator1.hasNext()) {
            IpPrefix testPrefixValue = listIterator1.next();
            assertThat(testPrefixValue.prefixLength(), is((int) 24));
            assertThat(testPrefixValue.address().toOctets(), is(prefix));
        }

        BgpValueType testPathAttribute = null;
        Origin origin;
        AsPath aspath;
        Med med;
        MpReachNlri mpReach;
        LinkStateAttributes linkStateAttr;
        List<BgpValueType> pathAttributeList = new LinkedList<>();
        BgpPathAttributes pathAttribute = other.bgpPathAttributes();
        pathAttributeList = pathAttribute.pathAttributes();
        ListIterator<BgpValueType> listIterator = pathAttributeList.listIterator();

        OriginType originValue = OriginType.IGP;

        testPathAttribute = listIterator.next();
        origin = (Origin) testPathAttribute;
        assertThat(origin.origin(), is(originValue));

        testPathAttribute = listIterator.next();
        aspath = (AsPath) testPathAttribute;
        ListIterator<Short> listIterator2 = aspath.asPathSeq().listIterator();
        assertThat(listIterator2.next(), is((short) 65001));

        testPathAttribute = listIterator.next();
        med = (Med) testPathAttribute;
        assertThat(med.med(), is(0));

        testPathAttribute = listIterator.next();
        mpReach = (MpReachNlri) testPathAttribute;
        assertThat(mpReach.mpReachNlriLen(), is((int) 83));
        assertThat(mpReach.getType(), is((short) 14));

        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
        testMpReachNlri = mpReach.mpReachNlri();

        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
        BgpLSNlri testnlri =  list1.next();
        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.LINK;
        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
        assertThat(testnlri.getIdentifier(), is((long) 0));
        assertThat(testnlri.getNlriType(), is(nlriType));
        assertThat(testnlri.getProtocolId(), is(protocolId));

        testPathAttribute = listIterator.next();
        linkStateAttr = (LinkStateAttributes) testPathAttribute;
        byte[] linkAttrbs = new byte[] {(byte) 0x80, 0x1d, 0x1C, 0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15,
                0x15, 0x04, 0x05, 0x00, 0x10, 0x01, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x01 };
        ChannelBuffer cb = ChannelBuffers.dynamicBuffer();
        cb.writeBytes(linkAttrbs);
        LinkStateAttributes obj = LinkStateAttributes.read(cb);

        assertThat(linkStateAttr.linkStateAttributes(), is(obj.linkStateAttributes()));
        assertThat(linkStateAttr.getType(), is((short) 29));
    }

    /**
     * Test for LinkStateattribute BgpAttrNodeRouterId and BgpAttrNodeMultiTopologyId.
     *
     * @throws BgpParseException while parsing update message
     */
    @Test
    public void bgpUpdateMessageTest7() throws BgpParseException {
        byte[] updateMsg = 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, 0x00, (byte) 0x96,
                0x02, 0x00, 0x04,
                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
                0x00, 0x7b, //path attribute len
                0x04, 0x01, 0x01, 0x00, //origin
                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
                0x00, //reserved
                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
                0x00, (byte) 0x95, 0x02, 0x50, 0x21, //link nlri
                (byte) 0x80, 0x1d, 0x10,  //linkstate attr
                0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15, 0x15, //BgpAttrNodeRouterId
                0x01, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02}; //BgpAttrNodeMultiTopologyId
        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
        buffer.writeBytes(updateMsg);

        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
        BgpMessage message = null;
        BgpHeader bgpHeader = new BgpHeader();

        message = reader.readFrom(buffer, bgpHeader);

        assertThat(message, instanceOf(BgpUpdateMsg.class));
        BgpUpdateMsg other = (BgpUpdateMsg) message;

        byte[] marker = 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 };

        assertThat(other.getHeader().getMarker(), is(marker));
        assertThat(other.getHeader().getType(), is((byte) 2));
        assertThat(other.getHeader().getLength(), is((short) 150));

        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};

        while (listIterator1.hasNext()) {
            IpPrefix testPrefixValue = listIterator1.next();
            assertThat(testPrefixValue.prefixLength(), is((int) 24));
            assertThat(testPrefixValue.address().toOctets(), is(prefix));
        }

        BgpValueType testPathAttribute = null;
        Origin origin;
        AsPath aspath;
        Med med;
        MpReachNlri mpReach;
        LinkStateAttributes linkStateAttr;
        List<BgpValueType> pathAttributeList = new LinkedList<>();
        BgpPathAttributes pathAttribute = other.bgpPathAttributes();
        pathAttributeList = pathAttribute.pathAttributes();
        ListIterator<BgpValueType> listIterator = pathAttributeList.listIterator();
        OriginType originValue = OriginType.IGP;

        testPathAttribute = listIterator.next();
        origin = (Origin) testPathAttribute;
        assertThat(origin.origin(), is(originValue));

        testPathAttribute = listIterator.next();
        aspath = (AsPath) testPathAttribute;
        ListIterator<Short> listIterator2 = aspath.asPathSeq().listIterator();
        assertThat(listIterator2.next(), is((short) 65001));

        testPathAttribute = listIterator.next();
        med = (Med) testPathAttribute;
        assertThat(med.med(), is(0));

        testPathAttribute = listIterator.next();
        mpReach = (MpReachNlri) testPathAttribute;
        assertThat(mpReach.mpReachNlriLen(), is((int) 83));
        assertThat(mpReach.getType(), is((short) 14));

        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
        testMpReachNlri = mpReach.mpReachNlri();

        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
        BgpLSNlri testnlri =  list1.next();
        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.LINK;
        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
        assertThat(testnlri.getIdentifier(), is((long) 0));
        assertThat(testnlri.getNlriType(), is(nlriType));
        assertThat(testnlri.getProtocolId(), is(protocolId));

        testPathAttribute = listIterator.next();
        linkStateAttr = (LinkStateAttributes) testPathAttribute;
        byte[] linkAttrbs = new byte[] {(byte) 0x80, 0x1d, 0x10, 0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15,
                0x15, 0x01, 0x07, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02 };
        ChannelBuffer cb = ChannelBuffers.dynamicBuffer();
        cb.writeBytes(linkAttrbs);
        LinkStateAttributes obj = LinkStateAttributes.read(cb);

        ListIterator<BgpValueType> list = obj.linkStateAttributes().listIterator();
        ListIterator<BgpValueType> list2 = linkStateAttr.linkStateAttributes().listIterator();
        assertThat(list.next(), is(list2.next()));
        assertThat(((BgpAttrNodeMultiTopologyId) list2.next()).attrMultiTopologyId(),
                is(((BgpAttrNodeMultiTopologyId) list.next()).attrMultiTopologyId()));

        assertThat(linkStateAttr.getType(), is((short) 29));
    }

    /**
     * Test for LinkStateattribute BgpAttrNodeRouterId and BgpPrefixAttrRouteTag.
     *
     * @throws BgpParseException while parsing update message
     */
    @Test
    public void bgpUpdateMessageTest8() throws BgpParseException {
        byte[] updateMsg = 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, 0x00, (byte) 0x96,
                0x02, 0x00, 0x04,
                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
                0x00, 0x7b, //path attribute len
                0x04, 0x01, 0x01, 0x00, //origin
                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
                0x00, //reserved
                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
                0x00, (byte) 0x95, 0x02, 0x50, 0x21, //link nlri
                (byte) 0x80, 0x1d, 0x10,  //linkstate attr
                0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15, 0x15, //BgpAttrNodeRouterId
                0x04, (byte) 0x81, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01}; //BgpPrefixAttrRouteTag
        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
        buffer.writeBytes(updateMsg);

        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
        BgpMessage message = null;
        BgpHeader bgpHeader = new BgpHeader();

        message = reader.readFrom(buffer, bgpHeader);

        assertThat(message, instanceOf(BgpUpdateMsg.class));
        BgpUpdateMsg other = (BgpUpdateMsg) message;

        byte[] marker = 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 };

        assertThat(other.getHeader().getMarker(), is(marker));
        assertThat(other.getHeader().getType(), is((byte) 2));
        assertThat(other.getHeader().getLength(), is((short) 150));

        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};

        while (listIterator1.hasNext()) {
            IpPrefix testPrefixValue = listIterator1.next();
            assertThat(testPrefixValue.prefixLength(), is((int) 24));
            assertThat(testPrefixValue.address().toOctets(), is(prefix));
        }

        BgpValueType testPathAttribute = null;
        Origin origin;
        AsPath aspath;
        Med med;
        MpReachNlri mpReach;
        LinkStateAttributes linkStateAttr;
        List<BgpValueType> pathAttributeList = new LinkedList<>();
        BgpPathAttributes pathAttribute = other.bgpPathAttributes();
        pathAttributeList = pathAttribute.pathAttributes();
        ListIterator<BgpValueType> listIterator = pathAttributeList.listIterator();
        OriginType originValue = OriginType.IGP;

        testPathAttribute = listIterator.next();
        origin = (Origin) testPathAttribute;
        assertThat(origin.origin(), is(originValue));

        testPathAttribute = listIterator.next();
        aspath = (AsPath) testPathAttribute;
        ListIterator<Short> listIterator2 = aspath.asPathSeq().listIterator();
        assertThat(listIterator2.next(), is((short) 65001));

        testPathAttribute = listIterator.next();
        med = (Med) testPathAttribute;
        assertThat(med.med(), is(0));

        testPathAttribute = listIterator.next();
        mpReach = (MpReachNlri) testPathAttribute;
        assertThat(mpReach.mpReachNlriLen(), is((int) 83));
        assertThat(mpReach.getType(), is((short) 14));

        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
        testMpReachNlri = mpReach.mpReachNlri();

        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
        BgpLSNlri testnlri =  list1.next();
        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.LINK;
        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
        assertThat(testnlri.getIdentifier(), is((long) 0));
        assertThat(testnlri.getNlriType(), is(nlriType));
        assertThat(testnlri.getProtocolId(), is(protocolId));

        testPathAttribute = listIterator.next();
        linkStateAttr = (LinkStateAttributes) testPathAttribute;
        byte[] linkAttrbs = new byte[] {(byte) 0x80, 0x1d, 0x10, 0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15,
                0x15, 0x04, (byte) 0x81, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01 };
        ChannelBuffer cb = ChannelBuffers.dynamicBuffer();
        cb.writeBytes(linkAttrbs);
        LinkStateAttributes obj = LinkStateAttributes.read(cb);

        ListIterator<BgpValueType> list = obj.linkStateAttributes().listIterator();
        ListIterator<BgpValueType> list2 = linkStateAttr.linkStateAttributes().listIterator();
        assertThat(list.next(), is(list2.next()));
        assertThat(((BgpPrefixAttrRouteTag) list2.next()).getPfxRouteTag(),
                is(((BgpPrefixAttrRouteTag) list.next()).getPfxRouteTag()));

        assertThat(linkStateAttr.getType(), is((short) 29));
    }

    /**
     * Test for LinkStateattribute BgpAttrNodeRouterId and BgpLinkAttrIsIsAdminstGrp.
     *
     * @throws BgpParseException while parsing update message
     */
    @Test
    public void bgpUpdateMessageTest9() throws BgpParseException {
        byte[] updateMsg = 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, 0x00, (byte) 0x96,
                0x02, 0x00, 0x04,
                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
                0x00, 0x7b, //path attribute len
                0x04, 0x01, 0x01, 0x00, //origin
                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
                0x00, //reserved
                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
                0x00, (byte) 0x95, 0x02, 0x50, 0x21, //link nlri
                (byte) 0x80, 0x1d, 0x10,  //linkstate attr
                0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15, 0x15, //BgpAttrNodeRouterId
                0x04, 0x40, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00}; //BgpLinkAttrIsIsAdminstGrp
        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
        buffer.writeBytes(updateMsg);

        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
        BgpMessage message = null;
        BgpHeader bgpHeader = new BgpHeader();

        message = reader.readFrom(buffer, bgpHeader);

        assertThat(message, instanceOf(BgpUpdateMsg.class));
        BgpUpdateMsg other = (BgpUpdateMsg) message;

        byte[] marker = 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 };

        assertThat(other.getHeader().getMarker(), is(marker));
        assertThat(other.getHeader().getType(), is((byte) 2));
        assertThat(other.getHeader().getLength(), is((short) 150));

        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};

        while (listIterator1.hasNext()) {
            IpPrefix testPrefixValue = listIterator1.next();
            assertThat(testPrefixValue.prefixLength(), is((int) 24));
            assertThat(testPrefixValue.address().toOctets(), is(prefix));
        }

        BgpValueType testPathAttribute = null;
        Origin origin;
        AsPath aspath;
        Med med;
        MpReachNlri mpReach;
        LinkStateAttributes linkStateAttr;
        List<BgpValueType> pathAttributeList = new LinkedList<>();
        BgpPathAttributes pathAttribute = other.bgpPathAttributes();
        pathAttributeList = pathAttribute.pathAttributes();
        ListIterator<BgpValueType> listIterator = pathAttributeList.listIterator();
        OriginType originValue = OriginType.IGP;

        testPathAttribute = listIterator.next();
        origin = (Origin) testPathAttribute;
        assertThat(origin.origin(), is(originValue));

        testPathAttribute = listIterator.next();
        aspath = (AsPath) testPathAttribute;
        ListIterator<Short> listIterator2 = aspath.asPathSeq().listIterator();
        assertThat(listIterator2.next(), is((short) 65001));

        testPathAttribute = listIterator.next();
        med = (Med) testPathAttribute;
        assertThat(med.med(), is(0));

        testPathAttribute = listIterator.next();
        mpReach = (MpReachNlri) testPathAttribute;
        assertThat(mpReach.mpReachNlriLen(), is((int) 83));
        assertThat(mpReach.getType(), is((short) 14));

        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
        testMpReachNlri = mpReach.mpReachNlri();

        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
        BgpLSNlri testnlri =  list1.next();
        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.LINK;
        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
        assertThat(testnlri.getIdentifier(), is((long) 0));
        assertThat(testnlri.getNlriType(), is(nlriType));
        assertThat(testnlri.getProtocolId(), is(protocolId));

        testPathAttribute = listIterator.next();
        linkStateAttr = (LinkStateAttributes) testPathAttribute;

        assertThat(linkStateAttr.getType(), is((short) 29));
        ListIterator<BgpValueType> list = linkStateAttr.linkStateAttributes().listIterator();
        byte[] ipBytes = new byte[] {(byte) 0x15, 0x15, 0x15, 0x15 };
        Ip4Address ip4RouterId = Ip4Address.valueOf(ipBytes);
        assertThat(((BgpAttrRouterIdV4) list.next()).attrRouterId(), is(ip4RouterId));
        assertThat(((BgpLinkAttrIsIsAdminstGrp) list.next()).linkAttrIsIsAdminGrp(), is((long) 0));
    }

    /**
     * Test for LinkStateattribute BgpAttrNodeRouterId and BgpAttrNodeFlagBitTlv.
     *
     * @throws BgpParseException while parsing update message
     */
    @Test
    public void bgpUpdateMessageTest10() throws BgpParseException {
        byte[] updateMsg = 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, 0x00, (byte) 0x93,
                0x02, 0x00, 0x04,
                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
                0x00, 0x78, //path attribute len
                0x04, 0x01, 0x01, 0x00, //origin
                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
                0x00, //reserved
                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
                0x00, (byte) 0x95, 0x02, 0x50, 0x21, //link nlri
                (byte) 0x80, 0x1d, 0x0D,  //linkstate attr
                0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15, 0x15, //BgpAttrNodeRouterId
                0x04, 0x00, 0x00, 0x01, 0x20}; //BgpAttrNodeFlagBitTlv
        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
        buffer.writeBytes(updateMsg);

        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
        BgpMessage message = null;
        BgpHeader bgpHeader = new BgpHeader();

        message = reader.readFrom(buffer, bgpHeader);

        assertThat(message, instanceOf(BgpUpdateMsg.class));
        BgpUpdateMsg other = (BgpUpdateMsg) message;

        byte[] marker = 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 };

        assertThat(other.getHeader().getMarker(), is(marker));
        assertThat(other.getHeader().getType(), is((byte) 2));
        assertThat(other.getHeader().getLength(), is((short) 147));

        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};

        while (listIterator1.hasNext()) {
            IpPrefix testPrefixValue = listIterator1.next();
            assertThat(testPrefixValue.prefixLength(), is((int) 24));
            assertThat(testPrefixValue.address().toOctets(), is(prefix));
        }

        BgpValueType testPathAttribute = null;
        Origin origin;
        AsPath aspath;
        Med med;
        MpReachNlri mpReach;
        LinkStateAttributes linkStateAttr;
        List<BgpValueType> pathAttributeList = new LinkedList<>();
        BgpPathAttributes pathAttribute = other.bgpPathAttributes();
        pathAttributeList = pathAttribute.pathAttributes();
        ListIterator<BgpValueType> listIterator = pathAttributeList.listIterator();
        OriginType originValue = OriginType.IGP;

        testPathAttribute = listIterator.next();
        origin = (Origin) testPathAttribute;
        assertThat(origin.origin(), is(originValue));

        testPathAttribute = listIterator.next();
        aspath = (AsPath) testPathAttribute;
        ListIterator<Short> listIterator2 = aspath.asPathSeq().listIterator();
        assertThat(listIterator2.next(), is((short) 65001));

        testPathAttribute = listIterator.next();
        med = (Med) testPathAttribute;
        assertThat(med.med(), is(0));

        testPathAttribute = listIterator.next();
        mpReach = (MpReachNlri) testPathAttribute;
        assertThat(mpReach.mpReachNlriLen(), is((int) 83));
        assertThat(mpReach.getType(), is((short) 14));

        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
        testMpReachNlri = mpReach.mpReachNlri();

        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
        BgpLSNlri testnlri =  list1.next();
        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.LINK;
        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
        assertThat(testnlri.getIdentifier(), is((long) 0));
        assertThat(testnlri.getNlriType(), is(nlriType));
        assertThat(testnlri.getProtocolId(), is(protocolId));

        testPathAttribute = listIterator.next();
        linkStateAttr = (LinkStateAttributes) testPathAttribute;

        assertThat(linkStateAttr.getType(), is((short) 29));
        ListIterator<BgpValueType> list = linkStateAttr.linkStateAttributes().listIterator();
        byte[] ipBytes = new byte[] {(byte) 0x15, 0x15, 0x15, 0x15 };
        Ip4Address ip4RouterId = Ip4Address.valueOf(ipBytes);
        assertThat(((BgpAttrRouterIdV4) list.next()).attrRouterId(), is(ip4RouterId));
        BgpAttrNodeFlagBitTlv obj = new BgpAttrNodeFlagBitTlv(false, false, true, false);
        assertThat(((BgpAttrNodeFlagBitTlv) list.next()).equals(obj), is(true));
    }

    /**
     * Test for LinkStateattribute BgpAttrNodeRouterId and BgpLinkAttrTeDefaultMetric.
     *
     * @throws BgpParseException while parsing update message
     */
    @Test
    public void bgpUpdateMessageTest11() throws BgpParseException {
        byte[] updateMsg = 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, 0x00, (byte) 0x96,
                0x02, 0x00, 0x04,
                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
                0x00, 0x7B, //path attribute len
                0x04, 0x01, 0x01, 0x00, //origin
                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
                0x00, //reserved
                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
                0x00, (byte) 0x95, 0x02, 0x50, 0x21, //link nlri
                (byte) 0x80, 0x1d, 0x10,  //linkstate attr
                0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15, 0x15, //BgpAttrNodeRouterId
                0x04, 0x44, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0a}; //BgpLinkAttrTeDefaultMetric
        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
        buffer.writeBytes(updateMsg);

        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
        BgpMessage message = null;
        BgpHeader bgpHeader = new BgpHeader();

        message = reader.readFrom(buffer, bgpHeader);

        assertThat(message, instanceOf(BgpUpdateMsg.class));
        BgpUpdateMsg other = (BgpUpdateMsg) message;

        byte[] marker = 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 };

        assertThat(other.getHeader().getMarker(), is(marker));
        assertThat(other.getHeader().getType(), is((byte) 2));
        assertThat(other.getHeader().getLength(), is((short) 150));

        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};

        while (listIterator1.hasNext()) {
            IpPrefix testPrefixValue = listIterator1.next();
            assertThat(testPrefixValue.prefixLength(), is((int) 24));
            assertThat(testPrefixValue.address().toOctets(), is(prefix));
        }

        BgpValueType testPathAttribute = null;
        Origin origin;
        AsPath aspath;
        Med med;
        MpReachNlri mpReach;
        LinkStateAttributes linkStateAttr;
        List<BgpValueType> pathAttributeList = new LinkedList<>();
        BgpPathAttributes pathAttribute = other.bgpPathAttributes();
        pathAttributeList = pathAttribute.pathAttributes();
        ListIterator<BgpValueType> listIterator = pathAttributeList.listIterator();
        OriginType originValue = OriginType.IGP;

        testPathAttribute = listIterator.next();
        origin = (Origin) testPathAttribute;
        assertThat(origin.origin(), is(originValue));

        testPathAttribute = listIterator.next();
        aspath = (AsPath) testPathAttribute;
        ListIterator<Short> listIterator2 = aspath.asPathSeq().listIterator();
        assertThat(listIterator2.next(), is((short) 65001));

        testPathAttribute = listIterator.next();
        med = (Med) testPathAttribute;
        assertThat(med.med(), is(0));

        testPathAttribute = listIterator.next();
        mpReach = (MpReachNlri) testPathAttribute;
        assertThat(mpReach.mpReachNlriLen(), is((int) 83));
        assertThat(mpReach.getType(), is((short) 14));

        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
        testMpReachNlri = mpReach.mpReachNlri();

        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
        BgpLSNlri testnlri =  list1.next();
        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.LINK;
        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
        assertThat(testnlri.getIdentifier(), is((long) 0));
        assertThat(testnlri.getNlriType(), is(nlriType));
        assertThat(testnlri.getProtocolId(), is(protocolId));

        testPathAttribute = listIterator.next();
        linkStateAttr = (LinkStateAttributes) testPathAttribute;

        assertThat(linkStateAttr.getType(), is((short) 29));
        ListIterator<BgpValueType> list = linkStateAttr.linkStateAttributes().listIterator();
        byte[] ipBytes = new byte[] {(byte) 0x15, 0x15, 0x15, 0x15 };
        Ip4Address ip4RouterId = Ip4Address.valueOf(ipBytes);
        assertThat(((BgpAttrRouterIdV4) list.next()).attrRouterId(), is(ip4RouterId));
        assertThat(((BgpLinkAttrTeDefaultMetric) list.next()).attrLinkDefTeMetric(), is(10));
    }

    /**
     * Test for LinkStateattribute BgpAttrNodeRouterId and BgpAttrOpaqueNode.
     *
     * @throws BgpParseException while parsing update message
     */
    @Test
    public void bgpUpdateMessageTest12() throws BgpParseException {
        byte[] updateMsg = 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, 0x00, (byte) 0x96,
                0x02, 0x00, 0x04,
                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
                0x00, 0x7B, //path attribute len
                0x04, 0x01, 0x01, 0x00, //origin
                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
                0x00, //reserved
                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
                0x00, (byte) 0x95, 0x02, 0x50, 0x21, //link nlri
                (byte) 0x80, 0x1d, 0x10,  //linkstate attr
                0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15, 0x15, //BgpAttrRouterIdV4
                0x04, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0a}; //BgpAttrOpaqueNode
        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
        buffer.writeBytes(updateMsg);

        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
        BgpMessage message = null;
        BgpHeader bgpHeader = new BgpHeader();

        message = reader.readFrom(buffer, bgpHeader);

        assertThat(message, instanceOf(BgpUpdateMsg.class));
        BgpUpdateMsg other = (BgpUpdateMsg) message;

        byte[] marker = 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 };

        assertThat(other.getHeader().getMarker(), is(marker));
        assertThat(other.getHeader().getType(), is((byte) 2));
        assertThat(other.getHeader().getLength(), is((short) 150));

        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};

        while (listIterator1.hasNext()) {
            IpPrefix testPrefixValue = listIterator1.next();
            assertThat(testPrefixValue.prefixLength(), is((int) 24));
            assertThat(testPrefixValue.address().toOctets(), is(prefix));
        }

        BgpValueType testPathAttribute = null;
        Origin origin;
        AsPath aspath;
        Med med;
        MpReachNlri mpReach;
        LinkStateAttributes linkStateAttr;
        List<BgpValueType> pathAttributeList = new LinkedList<>();
        BgpPathAttributes pathAttribute = other.bgpPathAttributes();
        pathAttributeList = pathAttribute.pathAttributes();
        ListIterator<BgpValueType> listIterator = pathAttributeList.listIterator();
        OriginType originValue = OriginType.IGP;

        testPathAttribute = listIterator.next();
        origin = (Origin) testPathAttribute;
        assertThat(origin.origin(), is(originValue));

        testPathAttribute = listIterator.next();
        aspath = (AsPath) testPathAttribute;
        ListIterator<Short> listIterator2 = aspath.asPathSeq().listIterator();
        assertThat(listIterator2.next(), is((short) 65001));

        testPathAttribute = listIterator.next();
        med = (Med) testPathAttribute;
        assertThat(med.med(), is(0));

        testPathAttribute = listIterator.next();
        mpReach = (MpReachNlri) testPathAttribute;
        assertThat(mpReach.mpReachNlriLen(), is((int) 83));
        assertThat(mpReach.getType(), is((short) 14));

        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
        testMpReachNlri = mpReach.mpReachNlri();

        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
        BgpLSNlri testnlri =  list1.next();
        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.LINK;
        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
        assertThat(testnlri.getIdentifier(), is((long) 0));
        assertThat(testnlri.getNlriType(), is(nlriType));
        assertThat(testnlri.getProtocolId(), is(protocolId));

        testPathAttribute = listIterator.next();
        linkStateAttr = (LinkStateAttributes) testPathAttribute;

        assertThat(linkStateAttr.getType(), is((short) 29));
        ListIterator<BgpValueType> list = linkStateAttr.linkStateAttributes().listIterator();
        byte[] ipBytes = new byte[] {(byte) 0x15, 0x15, 0x15, 0x15 };
        Ip4Address ip4RouterId = Ip4Address.valueOf(ipBytes);
        assertThat(((BgpAttrRouterIdV4) list.next()).attrRouterId(), is(ip4RouterId));
        byte[] opaqueNode = new byte[] {0x00, 0x00, 0x00, 0x0a };
        assertThat(((BgpAttrOpaqueNode) list.next()).attrOpaqueNode(), is(opaqueNode));
    }

    /**
     * Test for LinkStateattribute BgpAttrNodeRouterId and BgpLinkAttrProtectionType.
     *
     * @throws BgpParseException while parsing update message
     */
    @Test
    public void bgpUpdateMessageTest13() throws BgpParseException {
        byte[] updateMsg = 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, 0x00, (byte) 0x94,
                0x02, 0x00, 0x04,
                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
                0x00, 0x79, //path attribute len
                0x04, 0x01, 0x01, 0x00, //origin
                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
                0x00, //reserved
                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
                0x00, (byte) 0x95, 0x02, 0x50, 0x21, //link nlri
                (byte) 0x80, 0x1d, 0x0E,  //linkstate attr
                0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15, 0x15, //BgpAttrRouterIdV4
                0x04, 0x45, 0x00, 0x02, 0x10, 0x00}; //BgpLinkAttrProtectionType
        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
        buffer.writeBytes(updateMsg);

        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
        BgpMessage message = null;
        BgpHeader bgpHeader = new BgpHeader();

        message = reader.readFrom(buffer, bgpHeader);

        assertThat(message, instanceOf(BgpUpdateMsg.class));
        BgpUpdateMsg other = (BgpUpdateMsg) message;

        byte[] marker = 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 };

        assertThat(other.getHeader().getMarker(), is(marker));
        assertThat(other.getHeader().getType(), is((byte) 2));
        assertThat(other.getHeader().getLength(), is((short) 148));

        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};

        while (listIterator1.hasNext()) {
            IpPrefix testPrefixValue = listIterator1.next();
            assertThat(testPrefixValue.prefixLength(), is((int) 24));
            assertThat(testPrefixValue.address().toOctets(), is(prefix));
        }

        BgpValueType testPathAttribute = null;
        Origin origin;
        AsPath aspath;
        Med med;
        MpReachNlri mpReach;
        LinkStateAttributes linkStateAttr;
        List<BgpValueType> pathAttributeList = new LinkedList<>();
        BgpPathAttributes pathAttribute = other.bgpPathAttributes();
        pathAttributeList = pathAttribute.pathAttributes();
        ListIterator<BgpValueType> listIterator = pathAttributeList.listIterator();
        OriginType originValue = OriginType.IGP;

        testPathAttribute = listIterator.next();
        origin = (Origin) testPathAttribute;
        assertThat(origin.origin(), is(originValue));

        testPathAttribute = listIterator.next();
        aspath = (AsPath) testPathAttribute;
        ListIterator<Short> listIterator2 = aspath.asPathSeq().listIterator();
        assertThat(listIterator2.next(), is((short) 65001));

        testPathAttribute = listIterator.next();
        med = (Med) testPathAttribute;
        assertThat(med.med(), is(0));

        testPathAttribute = listIterator.next();
        mpReach = (MpReachNlri) testPathAttribute;
        assertThat(mpReach.mpReachNlriLen(), is((int) 83));
        assertThat(mpReach.getType(), is((short) 14));

        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
        testMpReachNlri = mpReach.mpReachNlri();

        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
        BgpLSNlri testnlri =  list1.next();
        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.LINK;
        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
        assertThat(testnlri.getIdentifier(), is((long) 0));
        assertThat(testnlri.getNlriType(), is(nlriType));
        assertThat(testnlri.getProtocolId(), is(protocolId));

        testPathAttribute = listIterator.next();
        linkStateAttr = (LinkStateAttributes) testPathAttribute;

        assertThat(linkStateAttr.getType(), is((short) 29));
        ListIterator<BgpValueType> list = linkStateAttr.linkStateAttributes().listIterator();
        byte[] ipBytes = new byte[] {(byte) 0x15, 0x15, 0x15, 0x15 };
        Ip4Address ip4RouterId = Ip4Address.valueOf(ipBytes);
        assertThat(((BgpAttrRouterIdV4) list.next()).attrRouterId(), is(ip4RouterId));
        assertThat(((BgpLinkAttrProtectionType) list.next()).protectionType(),
                is(ProtectionType.DEDICATED_ONE_PLUS_ONE));
    }

    /**
     * Test for LinkStateattribute BgpAttrNodeRouterId and BgpLinkAttrMplsProtocolMask.
     *
     * @throws BgpParseException while parsing update message
     */
    @Test
    public void bgpUpdateMessageTest14() throws BgpParseException {
        byte[] updateMsg = 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, 0x00, (byte) 0x93,
                0x02, 0x00, 0x04,
                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
                0x00, 0x78, //path attribute len
                0x04, 0x01, 0x01, 0x00, //origin
                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
                0x00, //reserved
                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
                0x00, (byte) 0x95, 0x02, 0x50, 0x21, //link nlri
                (byte) 0x80, 0x1d, 0x0D,  //linkstate attr
                0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15, 0x15, //BgpAttrRouterIdV4
                0x04, 0x46, 0x00, 0x01, (byte) 0xC0}; //BgpLinkAttrMplsProtocolMask
        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
        buffer.writeBytes(updateMsg);

        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
        BgpMessage message = null;
        BgpHeader bgpHeader = new BgpHeader();

        message = reader.readFrom(buffer, bgpHeader);

        assertThat(message, instanceOf(BgpUpdateMsg.class));
        BgpUpdateMsg other = (BgpUpdateMsg) message;

        byte[] marker = 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 };

        assertThat(other.getHeader().getMarker(), is(marker));
        assertThat(other.getHeader().getType(), is((byte) 2));
        assertThat(other.getHeader().getLength(), is((short) 147));

        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};

        while (listIterator1.hasNext()) {
            IpPrefix testPrefixValue = listIterator1.next();
            assertThat(testPrefixValue.prefixLength(), is((int) 24));
            assertThat(testPrefixValue.address().toOctets(), is(prefix));
        }

        BgpValueType testPathAttribute = null;
        Origin origin;
        AsPath aspath;
        Med med;
        MpReachNlri mpReach;
        LinkStateAttributes linkStateAttr;
        List<BgpValueType> pathAttributeList = new LinkedList<>();
        BgpPathAttributes pathAttribute = other.bgpPathAttributes();
        pathAttributeList = pathAttribute.pathAttributes();
        ListIterator<BgpValueType> listIterator = pathAttributeList.listIterator();
        OriginType originValue = OriginType.IGP;

        testPathAttribute = listIterator.next();
        origin = (Origin) testPathAttribute;
        assertThat(origin.origin(), is(originValue));

        testPathAttribute = listIterator.next();
        aspath = (AsPath) testPathAttribute;
        ListIterator<Short> listIterator2 = aspath.asPathSeq().listIterator();
        assertThat(listIterator2.next(), is((short) 65001));

        testPathAttribute = listIterator.next();
        med = (Med) testPathAttribute;
        assertThat(med.med(), is(0));

        testPathAttribute = listIterator.next();
        mpReach = (MpReachNlri) testPathAttribute;
        assertThat(mpReach.mpReachNlriLen(), is((int) 83));
        assertThat(mpReach.getType(), is((short) 14));

        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
        testMpReachNlri = mpReach.mpReachNlri();

        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
        BgpLSNlri testnlri =  list1.next();
        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.LINK;
        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
        assertThat(testnlri.getIdentifier(), is((long) 0));
        assertThat(testnlri.getNlriType(), is(nlriType));
        assertThat(testnlri.getProtocolId(), is(protocolId));

        testPathAttribute = listIterator.next();
        linkStateAttr = (LinkStateAttributes) testPathAttribute;

        assertThat(linkStateAttr.getType(), is((short) 29));
        ListIterator<BgpValueType> list = linkStateAttr.linkStateAttributes().listIterator();
        byte[] ipBytes = new byte[] {(byte) 0x15, 0x15, 0x15, 0x15 };
        Ip4Address ip4RouterId = Ip4Address.valueOf(ipBytes);
        assertThat(((BgpAttrRouterIdV4) list.next()).attrRouterId(), is(ip4RouterId));
        BgpLinkAttrMplsProtocolMask obj = new BgpLinkAttrMplsProtocolMask(true, true);
        assertThat(((BgpLinkAttrMplsProtocolMask) list.next()).equals(obj), is(true));
    }

    /**
     * Test for LinkStateattribute BgpAttrNodeRouterId and BgpLinkAttrSRLG.
     *
     * @throws BgpParseException while parsing update message
     */
    @Test
    public void bgpUpdateMessageTest15() throws BgpParseException {
        byte[] updateMsg = 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, 0x00, (byte) 0x9A,
                0x02, 0x00, 0x04,
                0x18, 0x0a, 0x01, 0x01, //withdrawn routes
                0x00, 0x7F, //path attribute len
                0x04, 0x01, 0x01, 0x00, //origin
                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
                0x04, 0x04, 0x00, 0x00, 0x01, //nexthop
                0x00, //reserved
                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
                0x00, (byte) 0x95, 0x02, 0x50, 0x21, //link nlri
                (byte) 0x80, 0x1d, 0x14,  //linkstate attr
                0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15, 0x15, //BgpAttrRouterIdV4
                0x04, 0x48, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b}; //BgpLinkAttrSRLG
        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
        buffer.writeBytes(updateMsg);

        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
        BgpMessage message = null;
        BgpHeader bgpHeader = new BgpHeader();

        message = reader.readFrom(buffer, bgpHeader);

        assertThat(message, instanceOf(BgpUpdateMsg.class));
        BgpUpdateMsg other = (BgpUpdateMsg) message;

        byte[] marker = 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 };

        assertThat(other.getHeader().getMarker(), is(marker));
        assertThat(other.getHeader().getType(), is((byte) 2));
        assertThat(other.getHeader().getLength(), is((short) 154));

        ListIterator<IpPrefix> listIterator1 = other.withdrawnRoutes().listIterator();
        byte[] prefix = new byte[] {0x0a, 0x01, 0x01, 0x00};

        while (listIterator1.hasNext()) {
            IpPrefix testPrefixValue = listIterator1.next();
            assertThat(testPrefixValue.prefixLength(), is((int) 24));
            assertThat(testPrefixValue.address().toOctets(), is(prefix));
        }

        BgpValueType testPathAttribute = null;
        Origin origin;
        AsPath aspath;
        Med med;
        MpReachNlri mpReach;
        LinkStateAttributes linkStateAttr;
        List<BgpValueType> pathAttributeList = new LinkedList<>();
        BgpPathAttributes pathAttribute = other.bgpPathAttributes();
        pathAttributeList = pathAttribute.pathAttributes();
        ListIterator<BgpValueType> listIterator = pathAttributeList.listIterator();
        OriginType originValue = OriginType.IGP;

        testPathAttribute = listIterator.next();
        origin = (Origin) testPathAttribute;
        assertThat(origin.origin(), is(originValue));

        testPathAttribute = listIterator.next();
        aspath = (AsPath) testPathAttribute;
        ListIterator<Short> listIterator2 = aspath.asPathSeq().listIterator();
        assertThat(listIterator2.next(), is((short) 65001));

        testPathAttribute = listIterator.next();
        med = (Med) testPathAttribute;
        assertThat(med.med(), is(0));

        testPathAttribute = listIterator.next();
        mpReach = (MpReachNlri) testPathAttribute;
        assertThat(mpReach.mpReachNlriLen(), is((int) 83));
        assertThat(mpReach.getType(), is((short) 14));

        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
        testMpReachNlri = mpReach.mpReachNlri();

        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
        BgpLSNlri testnlri =  list1.next();
        NlriType nlriType = org.onosproject.bgpio.protocol.NlriType.LINK;
        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
        assertThat(testnlri.getIdentifier(), is((long) 0));
        assertThat(testnlri.getNlriType(), is(nlriType));
        assertThat(testnlri.getProtocolId(), is(protocolId));

        testPathAttribute = listIterator.next();
        linkStateAttr = (LinkStateAttributes) testPathAttribute;

        assertThat(linkStateAttr.getType(), is((short) 29));
        ListIterator<BgpValueType> list = linkStateAttr.linkStateAttributes().listIterator();
        byte[] ipBytes = new byte[] {(byte) 0x15, 0x15, 0x15, 0x15 };
        Ip4Address ip4RouterId = Ip4Address.valueOf(ipBytes);
        assertThat(((BgpAttrRouterIdV4) list.next()).attrRouterId(), is(ip4RouterId));
        List<Integer> attrSrlg = new ArrayList<Integer>();
        attrSrlg.add(10);
        attrSrlg.add(11);
        assertThat(((BgpLinkAttrSrlg) list.next()).attrSrlg(), is(attrSrlg));
    }

    /**
     * Test for LinkStateattribute BgpAttrNodeRouterId and BgpLinkAttrOpaqLnkAttrib.
     *
     * @throws BgpParseException while parsing update message
     */
    @Test
    public void bgpUpdateMessageTest16() throws BgpParseException {
        byte[] updateMsg = 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, 0x00, (byte) 0x9A,
                0x02, 0x00, 0x04, 0x18, 0x0a, 0x01, 0x01, //withdrawn routes
                0x00, 0x7F, 0x04, 0x01, 0x01, 0x00, //origin
                0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
                0x04, 0x04, 0x00, 0x00, 0x01,  0x00,
                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
                0x00, (byte) 0x95, 0x02, 0x50, 0x21, (byte) 0x80, 0x1d, 0x14,  //linkstate attr
                0x04, 0x04, 0x00, 0x04, (byte) 0x15, 0x15, 0x15, 0x15, //BgpAttrRouterIdV4
                0x04, 0x49, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b}; //BgpLinkAttrOpaqLnkAttrib
        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
        buffer.writeBytes(updateMsg);

        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
        BgpMessage message = null;
        BgpHeader bgpHeader = new BgpHeader();

        message = reader.readFrom(buffer, bgpHeader);

        assertThat(message, instanceOf(BgpUpdateMsg.class));
        BgpUpdateMsg other = (BgpUpdateMsg) message;

        byte[] marker = 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 };

        assertThat(other.getHeader().getMarker(), is(marker));
        assertThat(other.getHeader().getType(), is((byte) 2));
        assertThat(other.getHeader().getLength(), is((short) 154));

        BgpValueType testPathAttribute = null;
        Origin origin;
        AsPath aspath;
        Med med;
        MpReachNlri mpReach;
        LinkStateAttributes linkStateAttr;
        List<BgpValueType> pathAttributeList = new LinkedList<>();
        BgpPathAttributes pathAttribute = other.bgpPathAttributes();
        pathAttributeList = pathAttribute.pathAttributes();
        ListIterator<BgpValueType> listIterator = pathAttributeList.listIterator();
        OriginType originValue = OriginType.IGP;

        testPathAttribute = listIterator.next();
        origin = (Origin) testPathAttribute;
        assertThat(origin.origin(), is(originValue));

        testPathAttribute = listIterator.next();
        aspath = (AsPath) testPathAttribute;
        ListIterator<Short> listIterator2 = aspath.asPathSeq().listIterator();
        assertThat(listIterator2.next(), is((short) 65001));

        testPathAttribute = listIterator.next();
        med = (Med) testPathAttribute;
        assertThat(med.med(), is(0));

        testPathAttribute = listIterator.next();
        mpReach = (MpReachNlri) testPathAttribute;
        assertThat(mpReach.mpReachNlriLen(), is((int) 83));
        assertThat(mpReach.getType(), is((short) 14));

        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
        testMpReachNlri = mpReach.mpReachNlri();

        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
        BgpLSNlri testnlri =  list1.next();
        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
        assertThat(testnlri.getProtocolId(), is(protocolId));

        testPathAttribute = listIterator.next();
        linkStateAttr = (LinkStateAttributes) testPathAttribute;

        assertThat(linkStateAttr.getType(), is((short) 29));
        ListIterator<BgpValueType> list = linkStateAttr.linkStateAttributes().listIterator();
        byte[] ipBytes = new byte[] {(byte) 0x15, 0x15, 0x15, 0x15 };
        Ip4Address ip4RouterId = Ip4Address.valueOf(ipBytes);
        assertThat(((BgpAttrRouterIdV4) list.next()).attrRouterId(), is(ip4RouterId));
        byte[] attrOpaqLnkAttrib = new byte[] {0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b };
        assertThat(((BgpLinkAttrOpaqLnkAttrib) list.next()).attrOpaqueLnk(), is(attrOpaqLnkAttrib));
    }

    /**
     * Test for LinkStateattribute BgpAttrNodeRouterId and BgpPrefixAttrOpaqueData.
     *
     * @throws BgpParseException while parsing update message
     */
    @Test
    public void bgpUpdateMessageTest17() throws BgpParseException {
        byte[] updateMsg = 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, 0x00, (byte) 0x96, 0x02, 0x00, 0x04,
                0x18, 0x0a, 0x01, 0x01, 0x00, 0x7B, //path attribute len
                0x04, 0x01, 0x01, 0x00, 0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd, (byte) 0xe9, //as_path
                (byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, //med
                (byte) 0x80, 0x0e, 0x53, 0x40, 0x04, 0x47, //mpreach
                0x04, 0x04, 0x00, 0x00, 0x01, 0x00, //reserved
                0x00, 0x02, 0x00, 0x46, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x1b, 0x02, 0x00, 0x00,
                0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00, 0x04,
                0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x07, 0x19, 0x00,
                (byte) 0x95, 0x02, 0x50, 0x21, 0x03, 0x01, 0x01, 0x00, 0x1a, 0x02,
                0x00, 0x00, 0x04, 0x00, 0x00, 0x08, (byte) 0xae, 0x02, 0x01, 0x00,
                0x04, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x00, 0x06, 0x19,
                0x00, (byte) 0x95, 0x02, 0x50, 0x21, (byte) 0x80, 0x1d, 0x10,  //linkstate attr
                0x04, 0x04, 0x00, 0x04, 0x15, 0x15, 0x15, 0x15, //BgpAttrRouterIdV4
                0x04, (byte) 0x85, 0x00, 0x04, 0x0a, 0x0a, 0x0a, 0x0a}; //BgpPrefixAttrOpaqueData
        ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
        buffer.writeBytes(updateMsg);

        BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
        BgpMessage message = null;
        BgpHeader bgpHeader = new BgpHeader();

        message = reader.readFrom(buffer, bgpHeader);

        assertThat(message, instanceOf(BgpUpdateMsg.class));
        BgpUpdateMsg other = (BgpUpdateMsg) message;

        byte[] marker = 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 };

        assertThat(other.getHeader().getMarker(), is(marker));
        assertThat(other.getHeader().getType(), is((byte) 2));
        assertThat(other.getHeader().getLength(), is((short) 150));
        BgpValueType testPathAttribute = null;
        Origin origin;
        AsPath aspath;
        Med med;
        MpReachNlri mpReach;
        LinkStateAttributes linkStateAttr;
        List<BgpValueType> pathAttributeList = new LinkedList<>();
        BgpPathAttributes pathAttribute = other.bgpPathAttributes();
        pathAttributeList = pathAttribute.pathAttributes();
        ListIterator<BgpValueType> listIterator = pathAttributeList.listIterator();
        OriginType originValue = OriginType.IGP;

        testPathAttribute = listIterator.next();
        origin = (Origin) testPathAttribute;
        assertThat(origin.origin(), is(originValue));

        testPathAttribute = listIterator.next();
        aspath = (AsPath) testPathAttribute;
        ListIterator<Short> listIterator2 = aspath.asPathSeq().listIterator();
        assertThat(listIterator2.next(), is((short) 65001));

        testPathAttribute = listIterator.next();
        med = (Med) testPathAttribute;
        assertThat(med.med(), is(0));

        testPathAttribute = listIterator.next();
        mpReach = (MpReachNlri) testPathAttribute;
        List<BgpLSNlri> testMpReachNlri = new LinkedList<>();
        testMpReachNlri = mpReach.mpReachNlri();

        ListIterator<BgpLSNlri> list1 = testMpReachNlri.listIterator();
        BgpLSNlri testnlri =  list1.next();
        ProtocolType protocolId = org.onosproject.bgpio.protocol.linkstate.
            BgpNodeLSNlriVer4.ProtocolType.ISIS_LEVEL_TWO;
        assertThat(testnlri.getProtocolId(), is(protocolId));

        testPathAttribute = listIterator.next();
        linkStateAttr = (LinkStateAttributes) testPathAttribute;

        assertThat(linkStateAttr.getType(), is((short) 29));
        ListIterator<BgpValueType> list = linkStateAttr.linkStateAttributes().listIterator();
        byte[] ipBytes = new byte[] {(byte) 0x15, 0x15, 0x15, 0x15 };
        Ip4Address ip4RouterId = Ip4Address.valueOf(ipBytes);
        assertThat(((BgpAttrRouterIdV4) list.next()).attrRouterId(), is(ip4RouterId));
        byte[] opaquePrefixAttr = new byte[] {0x0a, 0x0a, 0x0a, 0x0a };
        assertThat(((BgpPrefixAttrOpaqueData) list.next()).getOpaquePrefixAttribute(), is(opaquePrefixAttr));
    }
}
