Signed-off-by: IWASE Yusuke <[email protected]>
---
 .../packet_data/mrt/rib.20161101.0000_pick.bz2     | Bin 0 -> 271 bytes
 .../packet_data/mrt/updates.20161101.0000.bz2      | Bin 0 -> 20939 bytes
 ryu/tests/unit/lib/test_mrtlib.py                  | 761 +++++++++++++++++++++
 3 files changed, 761 insertions(+)
 create mode 100644 ryu/tests/packet_data/mrt/rib.20161101.0000_pick.bz2
 create mode 100644 ryu/tests/packet_data/mrt/updates.20161101.0000.bz2
 create mode 100644 ryu/tests/unit/lib/test_mrtlib.py

diff --git a/ryu/tests/packet_data/mrt/rib.20161101.0000_pick.bz2 
b/ryu/tests/packet_data/mrt/rib.20161101.0000_pick.bz2
new file mode 100644
index 
0000000000000000000000000000000000000000..0e02ef2d3f35da9bb1656939530f293786a8e692
GIT binary patch
literal 271
zcmV+q0r37pT4*^jL0KkKS&-1YZU6v^fB*llHP%8P02DxkNx(=!KnMU>2#^6F5?Ce}
z1V|8o2q7>4%Ak}gpXyIk^gwM)5s{-zX)<9n(@i#!=BOn#C;$Ke003wJ&<2Mv38n!u
z7yt=^U;qKfBgAw$wlL*pVN&odbK}>$5hv<Z)P5cEOisx_FCayv$emh=OKB7wfxMxi
zi3z)%h=B>2v5pM^IO#qXBoxvaOvG=h1s#}rLQ}!n6BtY~h$bN>`h0UfCTNJ}$|^Oy
z4ricnMt_0C@(>!50R+TZE$3cTz=3J0IBW_*!h!|0BAidJ>I9f8OM?FAkg6<Qb(AV8
VO8~@UbV1MYcO+AV2?-4g#^4PFX%_$h

literal 0
HcmV?d00001

diff --git a/ryu/tests/packet_data/mrt/updates.20161101.0000.bz2 
b/ryu/tests/packet_data/mrt/updates.20161101.0000.bz2
new file mode 100644
index 
0000000000000000000000000000000000000000..6caefe23e7fa0cdc26598cb40bb653b6aa87f347
GIT binary patch
literal 20939
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

literal 0
HcmV?d00001

diff --git a/ryu/tests/unit/lib/test_mrtlib.py 
b/ryu/tests/unit/lib/test_mrtlib.py
new file mode 100644
index 0000000..44856ce
--- /dev/null
+++ b/ryu/tests/unit/lib/test_mrtlib.py
@@ -0,0 +1,761 @@
+# Copyright (C) 2016 Nippon Telegraph and Telephone Corporation.
+#
+# 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.
+
+from __future__ import print_function
+
+import bz2
+import io
+import logging
+import os
+import sys
+import unittest
+
+try:
+    import mock  # Python 2
+except ImportError:
+    from unittest import mock  # Python 3
+
+from nose.tools import eq_
+from nose.tools import ok_
+
+from ryu.lib import addrconv
+from ryu.lib import mrtlib
+from ryu.lib.packet import bgp
+from ryu.utils import binary_str
+
+
+LOG = logging.getLogger(__name__)
+
+MRT_DATA_DIR = os.path.join(
+    os.path.dirname(sys.modules[__name__].__file__), '../../packet_data/mrt/')
+
+
+class TestMrtlib(unittest.TestCase):
+    """
+    Test case for ryu.lib.mrtlib.
+    """
+
+    def test_reader(self):
+        files = [
+            'rib.20161101.0000_pick.bz2',
+            'updates.20161101.0000.bz2',
+        ]
+
+        for f in files:
+            # print('\n*** testing mrtlib.Reader with %s ...' % f)
+            counter = 0
+            input_file = os.path.join(MRT_DATA_DIR, f)
+            for record in mrtlib.Reader(bz2.BZ2File(input_file, 'rb')):
+                # print('* No.%d\n%s' % (counter, record))
+                ok_(not isinstance(record, mrtlib.UnknownMrtRecord))
+                counter += 1
+
+    def test_writer(self):
+        files = [
+            'rib.20161101.0000_pick.bz2',
+            'updates.20161101.0000.bz2',
+        ]
+
+        for f in files:
+            # print('\n*** testing mrtlib.Writer with %s ...' % f)
+            input_file = os.path.join(MRT_DATA_DIR, f)
+            input_buf = bz2.BZ2File(input_file, 'rb').read()
+            input_records = list(mrtlib.Reader(bz2.BZ2File(input_file, 'rb')))
+
+            counter = 0
+            f = io.BytesIO()
+            mrt_writer = mrtlib.Writer(f)
+            for record in input_records:
+                # print('* No.%d\n%s' % (counter, record))
+                mrt_writer.write(record)
+                counter += 1
+
+            output_buf = f.getvalue()
+
+            eq_(binary_str(input_buf), binary_str(output_buf))
+
+            del mrt_writer
+
+
+class TestMrtlibMrtRecord(unittest.TestCase):
+    """
+    Test case for ryu.lib.mrtlib.MrtRecord.
+    """
+
+    def test_init_without_type_subtype(self):
+        type_ = mrtlib.MrtRecord.TYPE_TABLE_DUMP
+        subtype = mrtlib.TableDumpMrtRecord.SUBTYPE_AFI_IPv4
+
+        message = mrtlib.TableDumpAfiIPv4MrtMessage(
+            view_num=1,
+            seq_num=2,
+            prefix='192.168.1.0',
+            prefix_len=24,
+            status=1,
+            originated_time=0,
+            peer_ip='10.0.0.1',
+            peer_as=65000,
+            bgp_attributes=[],
+        )
+        record = mrtlib.TableDumpMrtRecord(message)
+
+        eq_(type_, record.type)
+        eq_(subtype, record.subtype)
+
+    def test_parse_pre_with_type_et(self):
+        buf = (
+            b'\x00\x00\x00\x00'  # timestamp
+            b'\x00\x11\x00\x00'  # type=TYPE_BGP4MP_ET(17), subtype
+            b'\x00\x00\x00\xaa'  # length
+        )
+
+        required_len = mrtlib.MrtRecord.parse_pre(buf)
+
+        eq_(0xaa + mrtlib.ExtendedTimestampMrtRecord.HEADER_SIZE,
+            required_len)
+
+
+# Note: MrtCommonRecord is tested in TestMrtlibMrtRecord.
+# class TestMrtlibMrtCommonRecord(unittest.TestCase):
+
+
+class TestMrtlibExtendedTimestampMrtRecord(unittest.TestCase):
+    """
+    Test case for ryu.lib.mrtlib.ExtendedTimestampMrtRecord.
+    """
+
+    def test_parse_extended_header(self):
+        body = b'test'
+        buf = (
+            b'\x11\x11\x11\x11'  # ms_timestamp
+            + body
+        )
+
+        (headers,
+         rest) = mrtlib.ExtendedTimestampMrtRecord.parse_extended_header(buf)
+
+        ok_(isinstance(headers, list))
+        eq_(1, len(headers))
+        eq_(0x11111111, headers[0])
+        eq_(body, rest)
+
+    def test_serialize(self):
+        body = b'test'  # 4 bytes
+        buf = (
+            b'\x11\x11\x11\x11'  # timestamp
+            b'\x22\x22\x33\x33'  # type, subtype
+            b'\x00\x00\x00\x04'  # length=len(body)
+            b'\x44\x44\x44\x44'  # ms_timestamp
+            + body
+        )
+
+        message_mock = mock.MagicMock(spec=mrtlib.MrtMessage)
+        message_mock.serialize.return_value = body
+
+        record = mrtlib.ExtendedTimestampMrtRecord(
+            message=message_mock,
+            timestamp=0x11111111,
+            type_=0x2222, subtype=0x3333,
+            ms_timestamp=0x44444444,
+            length=0x00000004,
+        )
+
+        output = record.serialize()
+
+        eq_(buf, output)
+
+
+class TestMrtlibUnknownMrtRecord(unittest.TestCase):
+    """
+    Test case for ryu.lib.mrtlib.UnknownMrtRecord.
+    """
+
+    def test_parse(self):
+        body = b'test'  # 4 bytes
+        buf = (
+            b'\x11\x11\x11\x11'  # timestamp
+            b'\x22\x22\x33\x33'  # type, subtype
+            b'\x00\x00\x00\x04'  # length=len(body)
+            + body
+        )
+
+        (record, rest) = mrtlib.MrtRecord.parse(buf)
+
+        eq_(0x11111111, record.timestamp)
+        eq_(0x2222, record.type)
+        eq_(0x3333, record.subtype)
+        eq_(0x00000004, record.length)
+        eq_(body, record.message.buf)
+        eq_(b'', rest)
+
+    def test_serialize(self):
+        body = b'test'  # 4 bytes
+        buf = (
+            b'\x11\x11\x11\x11'  # timestamp
+            b'\x22\x22\x33\x33'  # type, subtype
+            b'\x00\x00\x00\x04'  # length=len(body)
+            + body
+        )
+
+        message = mrtlib.UnknownMrtMessage(buf=body)
+        record = mrtlib.UnknownMrtRecord(
+            message=message,
+            timestamp=0x11111111,
+            type_=0x2222, subtype=0x3333,
+            length=0x00000004,
+        )
+
+        output = record.serialize()
+
+        eq_(buf, output)
+
+
+class TestMrtlibOspf2MrtRecord(unittest.TestCase):
+    """
+    Test case for ryu.lib.mrtlib.Ospf2MrtRecord.
+    """
+
+    @mock.patch('ryu.lib.packet.ospf.ospf.parser')
+    def test_parse(self, mock_ospf_parser):
+        remote_ip = '10.0.0.1'
+        local_ip = '10.0.0.2'
+        body = b'test'  # 4 bytes
+        buf = (
+            b'\x11\x11\x11\x11'  # timestamp
+            b'\x00\x0b\x00\x00'  # type=TYPE_OSPFv2(11), subtype
+            b'\x00\x00\x00\x0c'  # length=len(remote_ip + local_ip + body)
+            + addrconv.ipv4.text_to_bin(remote_ip)  # remote_ip
+            + addrconv.ipv4.text_to_bin(local_ip)   # local_ip
+            + body               # ospf_message
+        )
+
+        mock_ospf_parser.return_value = (body, None, '')
+
+        (record, rest) = mrtlib.MrtRecord.parse(buf)
+
+        eq_(0x11111111, record.timestamp)
+        eq_(mrtlib.MrtRecord.TYPE_OSPFv2, record.type)
+        eq_(0x0000, record.subtype)
+        eq_(0x0000000c, record.length)
+        eq_(remote_ip, record.message.remote_ip)
+        eq_(local_ip, record.message.local_ip)
+        eq_(body, record.message.ospf_message)
+        eq_(b'', rest)
+
+    def test_serialize(self):
+        remote_ip = '10.0.0.1'
+        local_ip = '10.0.0.2'
+        body = b'test'  # 4 bytes
+        buf = (
+            b'\x11\x11\x11\x11'  # timestamp
+            b'\x00\x0b\x00\x00'  # type=TYPE_OSPFv2(11), subtype
+            b'\x00\x00\x00\x0c'  # length=len(remote_ip + local_ip + body)
+            + addrconv.ipv4.text_to_bin(remote_ip)  # remote_ip
+            + addrconv.ipv4.text_to_bin(local_ip)   # local_ip
+            + body               # ospf_message
+        )
+
+        mock_ospf_message = mock.MagicMock()
+        mock_ospf_message.serialize.return_value = body
+
+        message = mrtlib.Ospf2MrtMessage(
+            remote_ip=remote_ip,
+            local_ip=local_ip,
+            ospf_message=mock_ospf_message,
+        )
+        record = mrtlib.Ospf2MrtRecord(
+            message=message,
+            timestamp=0x11111111,
+            # type_=None,
+            # subtype=None,
+            # length=None,
+        )
+
+        output = record.serialize()
+
+        eq_(buf, output)
+
+
+class TestMrtlibTableDumpMrtRecord(unittest.TestCase):
+    """
+    Test case for ryu.lib.mrtlib.TableDumpMrtRecord.
+    """
+
+    @mock.patch('ryu.lib.packet.bgp._PathAttribute.parser')
+    def test_parse_afi_ipv4(self, mock_bgp_attr_parser):
+        prefix = '10.0.0.0'
+        peer_ip = '172.16.0.1'
+        body = b'test'  # 4 bytes
+        buf = (
+            b'\x11\x11\x11\x11'  # timestamp
+            b'\x00\x0c\x00\x01'  # type=TYPE_TABLE_DUMP(12),
+                                 # subtype=SUBTYPE_AFI_IPv4(1)
+            b'\x00\x00\x00\x1a'  # length=26
+            b'\x22\x22\x33\x33'  # view_num, seq_num
+            + addrconv.ipv4.text_to_bin(prefix) +  # prefix
+            b'\x18\x01'          # prefix_len=24, status=1
+            b'\x44\x44\x44\x44'  # originated_time
+            + addrconv.ipv4.text_to_bin(peer_ip) +  # peer_ip
+            b'\xfd\xe8\x00\x04'  # peer_as=65000, attr_len=len(body)
+            + body               # bgp_attributes
+        )
+
+        mock_bgp_attr = mock.MagicMock(spec=bgp._PathAttribute)
+        mock_bgp_attr_parser.return_value = (mock_bgp_attr, b'')
+
+        (record, rest) = mrtlib.MrtRecord.parse(buf)
+
+        eq_(0x11111111, record.timestamp)
+        eq_(mrtlib.MrtRecord.TYPE_TABLE_DUMP, record.type)
+        eq_(mrtlib.TableDumpMrtRecord.SUBTYPE_AFI_IPv4, record.subtype)
+        eq_(0x0000001a, record.length)
+        eq_(0x2222, record.message.view_num)
+        eq_(0x3333, record.message.seq_num)
+        eq_(prefix, record.message.prefix)
+        eq_(24, record.message.prefix_len)
+        eq_(1, record.message.status)
+        eq_(0x44444444, record.message.originated_time)
+        eq_(peer_ip, record.message.peer_ip)
+        eq_(65000, record.message.peer_as)
+        eq_(0x0004, record.message.attr_len)
+        eq_([mock_bgp_attr], record.message.bgp_attributes)
+        eq_(b'', rest)
+
+    def test_serialize_afi_ipv4(self):
+        prefix = '10.0.0.0'
+        peer_ip = '172.16.0.1'
+        body = b'test'  # 4 bytes
+        buf = (
+            b'\x11\x11\x11\x11'  # timestamp
+            b'\x00\x0c\x00\x01'  # type=TYPE_TABLE_DUMP(12),
+                                 # subtype=SUBTYPE_AFI_IPv4(1)
+            b'\x00\x00\x00\x1a'  # length=26
+            b'\x22\x22\x33\x33'  # view_num, seq_num
+            + addrconv.ipv4.text_to_bin(prefix) +  # prefix
+            b'\x18\x01'          # prefix_len=24, status=1
+            b'\x44\x44\x44\x44'  # originated_time
+            + addrconv.ipv4.text_to_bin(peer_ip) +  # peer_ip
+            b'\xfd\xe8\x00\x04'  # peer_as=65000, attr_len=len(body)
+            + body               # bgp_attributes
+        )
+
+        mock_bgp_attr = mock.MagicMock(spec=bgp._PathAttribute)
+        mock_bgp_attr.serialize.return_value = body
+
+        message = mrtlib.TableDumpAfiIPv4MrtMessage(
+            view_num=0x2222,
+            seq_num=0x3333,
+            prefix=prefix,
+            prefix_len=24,
+            status=1,
+            originated_time=0x44444444,
+            peer_ip=peer_ip,
+            peer_as=65000,
+            bgp_attributes=[mock_bgp_attr],
+            # attr_len=4
+        )
+        record = mrtlib.TableDumpMrtRecord(
+            message=message,
+            timestamp=0x11111111,
+            # type_=None,
+            # subtype=None,
+            # length=None,
+        )
+
+        output = record.serialize()
+
+        eq_(buf, output)
+
+    @mock.patch('ryu.lib.packet.bgp._PathAttribute.parser')
+    def test_parse_afi_ipv6(self, mock_bgp_attr_parser):
+        prefix = '2001:db8::1'
+        peer_ip = 'fe80::1'
+        body = b'test'  # 4 bytes
+        buf = (
+            b'\x11\x11\x11\x11'  # timestamp
+            b'\x00\x0c\x00\x02'  # type=TYPE_TABLE_DUMP(12),
+                                 # subtype=SUBTYPE_AFI_IPv6(2)
+            b'\x00\x00\x00\x32'  # length=50
+            b'\x22\x22\x33\x33'  # view_num, seq_num
+            + addrconv.ipv6.text_to_bin(prefix) +  # prefix
+            b'\x40\x01'          # prefix_len=64, status=1
+            b'\x44\x44\x44\x44'  # originated_time
+            + addrconv.ipv6.text_to_bin(peer_ip) +  # peer_ip
+            b'\xfd\xe8\x00\x04'  # peer_as=65000, attr_len=len(body)
+            + body               # bgp_attributes
+        )
+
+        mock_bgp_attr = mock.MagicMock(spec=bgp._PathAttribute)
+        mock_bgp_attr_parser.return_value = (mock_bgp_attr, b'')
+
+        (record, rest) = mrtlib.MrtRecord.parse(buf)
+
+        eq_(0x11111111, record.timestamp)
+        eq_(mrtlib.MrtRecord.TYPE_TABLE_DUMP, record.type)
+        eq_(mrtlib.TableDumpMrtRecord.SUBTYPE_AFI_IPv6, record.subtype)
+        eq_(0x00000032, record.length)
+        eq_(0x2222, record.message.view_num)
+        eq_(0x3333, record.message.seq_num)
+        eq_(prefix, record.message.prefix)
+        eq_(64, record.message.prefix_len)
+        eq_(1, record.message.status)
+        eq_(0x44444444, record.message.originated_time)
+        eq_(peer_ip, record.message.peer_ip)
+        eq_(65000, record.message.peer_as)
+        eq_(0x0004, record.message.attr_len)
+        eq_([mock_bgp_attr], record.message.bgp_attributes)
+        eq_(b'', rest)
+
+    def test_serialize_afi_ipv6(self):
+        prefix = '2001:db8::1'
+        peer_ip = 'fe80::1'
+        body = b'test'  # 4 bytes
+        buf = (
+            b'\x11\x11\x11\x11'  # timestamp
+            b'\x00\x0c\x00\x02'  # type=TYPE_TABLE_DUMP(12),
+                                 # subtype=SUBTYPE_AFI_IPv6(2)
+            b'\x00\x00\x00\x32'  # length=50
+            b'\x22\x22\x33\x33'  # view_num, seq_num
+            + addrconv.ipv6.text_to_bin(prefix) +  # prefix
+            b'\x40\x01'          # prefix_len=64, status=1
+            b'\x44\x44\x44\x44'  # originated_time
+            + addrconv.ipv6.text_to_bin(peer_ip) +  # peer_ip
+            b'\xfd\xe8\x00\x04'  # peer_as=65000, attr_len=len(body)
+            + body               # bgp_attributes
+        )
+
+        mock_bgp_attr = mock.MagicMock(spec=bgp._PathAttribute)
+        mock_bgp_attr.serialize.return_value = body
+
+        message = mrtlib.TableDumpAfiIPv6MrtMessage(
+            view_num=0x2222,
+            seq_num=0x3333,
+            prefix=prefix,
+            prefix_len=64,
+            status=1,
+            originated_time=0x44444444,
+            peer_ip=peer_ip,
+            peer_as=65000,
+            bgp_attributes=[mock_bgp_attr],
+            # attr_len=4
+        )
+        record = mrtlib.TableDumpMrtRecord(
+            message=message,
+            timestamp=0x11111111,
+            # type_=None,
+            # subtype=None,
+            # length=None,
+        )
+
+        output = record.serialize()
+
+        eq_(buf, output)
+
+
+class TestMrtlibTableDump2MrtRecord(unittest.TestCase):
+    """
+    Test case for ryu.lib.mrtlib.TableDump2MrtRecord.
+    """
+
+    # Note: The classes corresponding to the following subtypes are
+    # tested in TestMrtlibMrtRecord.
+    # - SUBTYPE_PEER_INDEX_TABLE = 1
+    # - SUBTYPE_RIB_IPV4_UNICAST = 2
+    # - SUBTYPE_RIB_IPV4_MULTICAST = 3
+    # - SUBTYPE_RIB_IPV6_UNICAST = 4
+    # - SUBTYPE_RIB_IPV6_MULTICAST = 5
+
+    @mock.patch('ryu.lib.mrtlib.MrtRibEntry.parse')
+    @mock.patch('ryu.lib.packet.bgp.BGPNLRI.parser')
+    def test_parse_rib_generic(self, mock_nlri_parser, mock_rib_entry_parser):
+        nlri_bin = b'nlri'  # 4 bytes
+        rib_entries_bin = b'ribs'  # 4 bytes
+        buf = (
+            b'\x11\x11\x11\x11'  # timestamp
+            b'\x00\x0d\x00\x06'  # type=TYPE_TABLE_DUMP_V2(13),
+                                 # subtype=SUBTYPE_RIB_GENERIC(6)
+            b'\x00\x00\x00\x11'  # length=17
+            b'\x22\x22\x22\x22'  # seq_num
+            b'\x33\x33\x44'      # afi, safi
+            + nlri_bin +         # nlri
+            b'\x00\x01'          # entry_count
+            + rib_entries_bin    # rib_entries
+        )
+        buf_entries = (
+            b'\x00\x01'          # entry_count
+            + rib_entries_bin    # rib_entries
+        )
+
+        mock_bgp_nlri = mock.MagicMock(spec=bgp._AddrPrefix)
+        mock_nlri_parser.return_value = (mock_bgp_nlri, buf_entries)
+
+        mock_rib_entry = mock.MagicMock(spec=mrtlib.MrtRibEntry)
+        mock_rib_entry_parser.return_value = (mock_rib_entry, b'')
+
+        (record, rest) = mrtlib.MrtRecord.parse(buf)
+
+        eq_(0x11111111, record.timestamp)
+        eq_(mrtlib.MrtRecord.TYPE_TABLE_DUMP_V2, record.type)
+        eq_(mrtlib.TableDump2MrtRecord.SUBTYPE_RIB_GENERIC, record.subtype)
+        eq_(0x00000011, record.length)
+        eq_(0x22222222, record.message.seq_num)
+        eq_(0x3333, record.message.afi)
+        eq_(0x44, record.message.safi)
+        eq_(mock_bgp_nlri, record.message.nlri)
+        eq_(0x0001, record.message.entry_count)
+        eq_([mock_rib_entry], record.message.rib_entries)
+        eq_(b'', rest)
+
+    def test_serialize_rib_generic(self):
+        nlri_bin = b'nlri'  # 4 bytes
+        rib_entries_bin = b'ribs'  # 4 bytes
+        buf = (
+            b'\x11\x11\x11\x11'  # timestamp
+            b'\x00\x0d\x00\x06'  # type=TYPE_TABLE_DUMP_V2(13),
+                                 # subtype=SUBTYPE_RIB_GENERIC(6)
+            b'\x00\x00\x00\x11'  # length=17
+            b'\x22\x22\x22\x22'  # seq_num
+            b'\x33\x33\x44'      # afi, safi
+            + nlri_bin +         # nlri
+            b'\x00\x01'          # entry_count
+            + rib_entries_bin    # rib_entries
+        )
+
+        mock_bgp_nlri = mock.MagicMock(spec=bgp._AddrPrefix)
+        mock_bgp_nlri.serialize.return_value = nlri_bin
+
+        mock_rib_entry = mock.MagicMock(spec=mrtlib.MrtRibEntry)
+        mock_rib_entry.serialize.return_value = rib_entries_bin
+
+        message = mrtlib.TableDump2RibGenericMrtMessage(
+            seq_num=0x22222222,
+            afi=0x3333,
+            safi=0x44,
+            nlri=mock_bgp_nlri,
+            rib_entries=[mock_rib_entry],
+            # entry_count=1,
+        )
+        record = mrtlib.TableDump2MrtRecord(
+            message=message,
+            timestamp=0x11111111,
+            # type_=None,
+            # subtype=None,
+            # length=None,
+        )
+
+        output = record.serialize()
+
+        eq_(buf, output)
+
+
+class TestMrtlibMrtPeer(unittest.TestCase):
+    """
+    Test case for ryu.lib.mrtlib.MrtPeer.
+    """
+
+    def test_parse_two_octet_as(self):
+        bgp_id = '1.1.1.1'
+        ip_addr = '10.0.0.1'
+        buf = (
+            b'\x00'      # type
+            + addrconv.ipv4.text_to_bin(bgp_id)     # bgp_id
+            + addrconv.ipv4.text_to_bin(ip_addr) +  # ip_addr
+            b'\xfd\xe8'  # as_num
+        )
+
+        peer, rest = mrtlib.MrtPeer.parse(buf)
+
+        eq_(0, peer.type)
+        eq_(bgp_id, peer.bgp_id)
+        eq_(ip_addr, peer.ip_addr)
+        eq_(65000, peer.as_num)
+        eq_(b'', rest)
+
+    def test_serialize_two_octet_as(self):
+        bgp_id = '1.1.1.1'
+        ip_addr = '10.0.0.1'
+        buf = (
+            b'\x00'      # type
+            + addrconv.ipv4.text_to_bin(bgp_id)     # bgp_id
+            + addrconv.ipv4.text_to_bin(ip_addr) +  # ip_addr
+            b'\xfd\xe8'  # as_num
+        )
+
+        peer = mrtlib.MrtPeer(
+            bgp_id=bgp_id,
+            ip_addr=ip_addr,
+            as_num=65000,
+            # type_=0,
+        )
+
+        output = peer.serialize()
+
+        eq_(buf, output)
+
+
+class TestMrtlibBgp4MpMrtRecord(unittest.TestCase):
+    """
+    Test case for ryu.lib.mrtlib.Bgp4MpMrtRecord.
+    """
+
+    # Note: The classes corresponding to the following subtypes are
+    # tested in TestMrtlibMrtRecord.
+    # - SUBTYPE_BGP4MP_MESSAGE = 1
+    # - SUBTYPE_BGP4MP_MESSAGE_AS4 = 4
+    # - SUBTYPE_BGP4MP_STATE_CHANGE_AS4 = 5
+    # - SUBTYPE_BGP4MP_MESSAGE_LOCAL = 6
+    # - SUBTYPE_BGP4MP_MESSAGE_AS4_LOCAL = 7
+
+    def test_parse_state_change_afi_ipv4(self):
+        peer_ip = '10.0.0.1'
+        local_ip = '10.0.0.2'
+        buf = (
+            b'\x11\x11\x11\x11'  # timestamp
+            b'\x00\x10\x00\x00'  # type=TYPE_BGP4MP(16),
+                                 # subtype=SUBTYPE_BGP4MP_STATE_CHANGE(0)
+            b'\x00\x00\x00\x14'  # length=20
+            b'\xfd\xe9\xfd\xea'  # peer_as=65001, local_as=65002
+            b'\x22\x22\x00\x01'  # if_index, addr_family=AFI_IPv4(1)
+            + addrconv.ipv4.text_to_bin(peer_ip)     # peer_ip
+            + addrconv.ipv4.text_to_bin(local_ip) +  # local_ip
+            b'\x00\x01\x00\x02'  # old_state=STATE_IDLE(1),
+                                 # new_state=STATE_CONNECT(2)
+        )
+
+        (record, rest) = mrtlib.MrtRecord.parse(buf)
+
+        eq_(0x11111111, record.timestamp)
+        eq_(mrtlib.MrtRecord.TYPE_BGP4MP, record.type)
+        eq_(mrtlib.Bgp4MpMrtRecord.SUBTYPE_BGP4MP_STATE_CHANGE, record.subtype)
+        eq_(0x00000014, record.length)
+        eq_(65001, record.message.peer_as)
+        eq_(65002, record.message.local_as)
+        eq_(0x2222, record.message.if_index)
+        eq_(mrtlib.Bgp4MpStateChangeMrtMessage.AFI_IPv4,
+            record.message.afi)
+        eq_(mrtlib.Bgp4MpStateChangeMrtMessage.STATE_IDLE,
+            record.message.old_state)
+        eq_(mrtlib.Bgp4MpStateChangeMrtMessage.STATE_CONNECT,
+            record.message.new_state)
+        eq_(b'', rest)
+
+    def test_serialize_state_change_afi_ipv4(self):
+        peer_ip = '10.0.0.1'
+        local_ip = '10.0.0.2'
+        buf = (
+            b'\x11\x11\x11\x11'  # timestamp
+            b'\x00\x10\x00\x00'  # type=TYPE_BGP4MP(16),
+                                 # subtype=SUBTYPE_BGP4MP_STATE_CHANGE(0)
+            b'\x00\x00\x00\x14'  # length=20
+            b'\xfd\xe9\xfd\xea'  # peer_as=65001, local_as=65002
+            b'\x22\x22\x00\x01'  # if_index, addr_family=AFI_IPv4(1)
+            + addrconv.ipv4.text_to_bin(peer_ip)     # peer_ip
+            + addrconv.ipv4.text_to_bin(local_ip) +  # local_ip
+            b'\x00\x01\x00\x02'  # old_state=STATE_IDLE(1),
+                                 # new_state=STATE_CONNECT(2)
+        )
+
+        message = mrtlib.Bgp4MpStateChangeMrtMessage(
+            peer_as=65001,
+            local_as=65002,
+            if_index=0x2222,
+            peer_ip=peer_ip,
+            local_ip=local_ip,
+            old_state=mrtlib.Bgp4MpStateChangeMrtMessage.STATE_IDLE,
+            new_state=mrtlib.Bgp4MpStateChangeMrtMessage.STATE_CONNECT,
+            # afi=mrtlib.Bgp4MpStateChangeMrtMessage.AFI_IPv4,
+        )
+        record = mrtlib.Bgp4MpMrtRecord(
+            message=message,
+            timestamp=0x11111111,
+            # type_=None,
+            # subtype=None,
+            # length=None,
+        )
+
+        output = record.serialize()
+
+        eq_(buf, output)
+
+    def test_parse_state_change_afi_ipv6(self):
+        peer_ip = 'fe80::1'
+        local_ip = 'fe80::2'
+        buf = (
+            b'\x11\x11\x11\x11'  # timestamp
+            b'\x00\x10\x00\x00'  # type=TYPE_BGP4MP(16),
+                                 # subtype=SUBTYPE_BGP4MP_STATE_CHANGE(0)
+            b'\x00\x00\x00\x2c'  # length=44
+            b'\xfd\xe9\xfd\xea'  # peer_as=65001, local_as=65002
+            b'\x22\x22\x00\x02'  # if_index, addr_family=AFI_IPv6(2)
+            + addrconv.ipv6.text_to_bin(peer_ip)     # peer_ip
+            + addrconv.ipv6.text_to_bin(local_ip) +  # local_ip
+            b'\x00\x01\x00\x02'  # old_state=STATE_IDLE(1),
+                                 # new_state=STATE_CONNECT(2)
+        )
+
+        (record, rest) = mrtlib.MrtRecord.parse(buf)
+
+        eq_(0x11111111, record.timestamp)
+        eq_(mrtlib.MrtRecord.TYPE_BGP4MP, record.type)
+        eq_(mrtlib.Bgp4MpMrtRecord.SUBTYPE_BGP4MP_STATE_CHANGE, record.subtype)
+        eq_(0x0000002c, record.length)
+        eq_(65001, record.message.peer_as)
+        eq_(65002, record.message.local_as)
+        eq_(0x2222, record.message.if_index)
+        eq_(mrtlib.Bgp4MpStateChangeMrtMessage.AFI_IPv6,
+            record.message.afi)
+        eq_(mrtlib.Bgp4MpStateChangeMrtMessage.STATE_IDLE,
+            record.message.old_state)
+        eq_(mrtlib.Bgp4MpStateChangeMrtMessage.STATE_CONNECT,
+            record.message.new_state)
+        eq_(b'', rest)
+
+    def test_serialize_state_change_afi_ipv6(self):
+        peer_ip = 'fe80::1'
+        local_ip = 'fe80::2'
+        buf = (
+            b'\x11\x11\x11\x11'  # timestamp
+            b'\x00\x10\x00\x00'  # type=TYPE_BGP4MP(16),
+                                 # subtype=SUBTYPE_BGP4MP_STATE_CHANGE(0)
+            b'\x00\x00\x00\x2c'  # length=44
+            b'\xfd\xe9\xfd\xea'  # peer_as=65001, local_as=65002
+            b'\x22\x22\x00\x02'  # if_index, addr_family=AFI_IPv6(2)
+            + addrconv.ipv6.text_to_bin(peer_ip)     # peer_ip
+            + addrconv.ipv6.text_to_bin(local_ip) +  # local_ip
+            b'\x00\x01\x00\x02'  # old_state=STATE_IDLE(1),
+                                 # new_state=STATE_CONNECT(2)
+        )
+
+        message = mrtlib.Bgp4MpStateChangeMrtMessage(
+            peer_as=65001,
+            local_as=65002,
+            if_index=0x2222,
+            peer_ip=peer_ip,
+            local_ip=local_ip,
+            old_state=mrtlib.Bgp4MpStateChangeMrtMessage.STATE_IDLE,
+            new_state=mrtlib.Bgp4MpStateChangeMrtMessage.STATE_CONNECT,
+            # afi=mrtlib.Bgp4MpStateChangeMrtMessage.AFI_IPv4,
+        )
+        record = mrtlib.Bgp4MpMrtRecord(
+            message=message,
+            timestamp=0x11111111,
+            # type_=None,
+            # subtype=None,
+            # length=None,
+        )
+
+        output = record.serialize()
+
+        eq_(buf, output)
-- 
2.7.4


------------------------------------------------------------------------------
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to