opensourcerouting / frr

Free Range Routing Protocol Suite
Other
37 stars 12 forks source link

topotato: test_bgp_dynamic_capability_role.py & test_bgp_dynamic_capability_software_version.py #124

Open Chromico opened 1 year ago

Chromico commented 1 year ago

test_bgp_dynamic_capability_role.py:

The bgp_check_if_session_not_reset function fails. The bgp state becomes "Idle". Here's a command log:

➜  basetato4 git:(bgp-dynamic-capability) ✗ sudo ./run_userns.sh --frr-builddir=/root/buildfrr/ --log-cli-level=DEBUG -v -v  -x --pause-on-fail test_bgp_dynamic_capability_role.py           
======================================================= topotato initialization =======================================================

-------------------------------------------------------- live log sessionstart --------------------------------------------------------
DEBUG    topotato:pretty.py:145 executable dot found: /usr/bin/dot
DEBUG    topotato:core.py:170 FRR build directory: '/root/buildfrr/'
DEBUG    topotato:core.py:192 FRR source directory: '/root/buildfrr'
INFO     topotato:core.py:236 FRR daemons: zebra, mgmtd, staticd, babeld, bfdd, bgpd, eigrpd, fabricd, isisd, ldpd, nhrpd, ospf6d, ospfd, pathd, pbrd, pim6d, pimd, ripd, ripngd, vrrpd
DEBUG    topotato:core.py:248 zebra => zebra/zebra
DEBUG    topotato:core.py:246 ignoring target 'watchfrr/watchfrr'
DEBUG    topotato:core.py:246 ignoring target 'tools/ssd'
DEBUG    topotato:core.py:248 mgmtd => mgmtd/mgmtd
DEBUG    topotato:core.py:248 bgpd => bgpd/bgpd
DEBUG    topotato:core.py:248 ripd => ripd/ripd
DEBUG    topotato:core.py:248 ripngd => ripngd/ripngd
DEBUG    topotato:core.py:248 ospfd => ospfd/ospfd
DEBUG    topotato:core.py:248 ospf6d => ospf6d/ospf6d
DEBUG    topotato:core.py:248 isisd => isisd/isisd
DEBUG    topotato:core.py:248 fabricd => isisd/fabricd
DEBUG    topotato:core.py:248 nhrpd => nhrpd/nhrpd
DEBUG    topotato:core.py:248 ldpd => ldpd/ldpd
DEBUG    topotato:core.py:248 babeld => babeld/babeld
DEBUG    topotato:core.py:248 eigrpd => eigrpd/eigrpd
DEBUG    topotato:core.py:248 pimd => pimd/pimd
DEBUG    topotato:core.py:248 pim6d => pimd/pim6d
DEBUG    topotato:core.py:248 pbrd => pbrd/pbrd
DEBUG    topotato:core.py:248 staticd => staticd/staticd
DEBUG    topotato:core.py:248 bfdd => bfdd/bfdd
DEBUG    topotato:core.py:248 vrrpd => vrrpd/vrrpd
DEBUG    topotato:core.py:248 pathd => pathd/pathd
DEBUG    topotato:core.py:246 ignoring target 'lib/grammar_sandbox'
DEBUG    topotato:core.py:246 ignoring target 'lib/clippy'
DEBUG    topotato:core.py:246 ignoring target 'tools/permutations'
DEBUG    topotato:core.py:246 ignoring target 'tools/gen_northbound_callbacks'
DEBUG    topotato:core.py:246 ignoring target 'tools/gen_yang_deviations'
DEBUG    topotato:core.py:246 ignoring target 'bgpd/bgp_btoa'
DEBUG    topotato:core.py:246 ignoring target 'bgpd/rfp-example/rfptest/rfptest'
DEBUG    topotato:core.py:246 ignoring target 'ospfclient/ospfclient'
DEBUG    topotato:core.py:246 ignoring target 'pimd/test_igmpv3_join'
DEBUG    topotato:core.py:246 ignoring target 'pceplib/pcep_pcc'
DEBUG    topotato:topolinux.py:92 executable unshare found: /usr/bin/unshare
DEBUG    topotato:topolinux.py:92 executable nsenter found: /usr/bin/nsenter
DEBUG    topotato:topolinux.py:92 executable tini found: /usr/bin/tini
DEBUG    topotato:topolinux.py:92 executable ip found: /usr/sbin/ip
========================================================= test session starts =========================================================
platform linux -- Python 3.11.4, pytest-7.3.1, pluggy-0.13.0 -- /usr/bin/python3
cachedir: .pytest_cache
rootdir: /home/chromico/basetato4
configfile: pytest.ini
collecting ... --------------------------------------------------------- live log collection ---------------------------------------------------------
DEBUG    topotato:base.py:278 _topotato_makeitem(<Module test_bgp_dynamic_capability_role.py>, 'TestBase', <class 'topotato.base.TestBase'>)
DEBUG    topotato:base.py:278 _topotato_makeitem(<Module test_bgp_dynamic_capability_role.py>, 'BGPDynamicCapabilityRole', <class 'test_bgp_dynamic_capability_role.BGPDynamicCapabilityRole'>)
DEBUG    topotato:base.py:278 _topotato_makeitem(<TopotatoClass BGPDynamicCapabilityRole>, 'bgp_converge', <topotato.base.TopotatoWrapped object at 0x7f83cb3eecd0>)
DEBUG    topotato:base.py:278 _topotato_makeitem(<TopotatoClass BGPDynamicCapabilityRole>, 'bgp_check_if_session_not_reset', <topotato.base.TopotatoWrapped object at 0x7f83cb3ee1d0>)
DEBUG    topotato:base.py:686 collect on: <TopotatoFunction bgp_converge> test: <AssertVtysh #85:r1/bgpd/vtysh[show bgp neighbor json]>
DEBUG    topotato:base.py:686 collect on: <TopotatoFunction bgp_check_if_session_not_reset> test: <AssertVtysh #109:r1/vtysh/vtysh[;             configure terminal;             router bgp;              neighbor 192.168.1.2 local-role customer; ;             ]>
DEBUG    topotato:base.py:686 collect on: <TopotatoFunction bgp_check_if_session_not_reset> test: <AssertVtysh #121:r2/vtysh/vtysh[;             configure terminal;             router bgp;              neighbor 192.168.1.1 local-role customer; ;             ]>
DEBUG    topotato:base.py:686 collect on: <TopotatoFunction bgp_check_if_session_not_reset> test: <AssertVtysh #133:r1/bgpd/vtysh[show bgp neighbor json]>
collected 6 items                                                                                                                     

test_bgp_dynamic_capability_role.py::BGPDynamicCapabilityRole::startup 
----------------------------------------------------------- live log setup ------------------------------------------------------------
DEBUG    topotato.topolinux:topolinux.py:326 <topotato.network.TopotatoNetwork object at 0x7f83cb3f8b50> tempdir created: /tmp/tmpbnxvglo2
DEBUG    topotato.topolinux:topolinux.py:114 <topotato.network.TopotatoNetwork object at 0x7f83cb3f8b50> temp-subdir for <SwitchyNS: 'switch-ns'> created: /tmp/tmpbnxvglo2/switch-ns
DEBUG    topotato.topolinux:topolinux.py:114 <topotato.network.TopotatoNetwork object at 0x7f83cb3f8b50> temp-subdir for <FRRRouterNS: 'r1'> created: /tmp/tmpbnxvglo2/r1
DEBUG    topotato.topolinux:topolinux.py:114 <topotato.network.TopotatoNetwork object at 0x7f83cb3f8b50> temp-subdir for <FRRRouterNS: 'r2'> created: /tmp/tmpbnxvglo2/r2
PASSED (3.52)                                                                                                                   [ 16%]
test_bgp_dynamic_capability_role.py::BGPDynamicCapabilityRole::bgp_converge:#85:r1/bgpd/vtysh[show bgp neighbor json] PASSED (0.72) [ 33%]
test_bgp_dynamic_capability_role.py::BGPDynamicCapabilityRole::bgp_check_if_session_not_reset:#109:r1/vtysh/vtysh[;             configure terminal;             router bgp;              neighbor 192.168.1.2 local-role customer; ;             ] PASSED (0.41) [ 50%]
test_bgp_dynamic_capability_role.py::BGPDynamicCapabilityRole::bgp_check_if_session_not_reset:#121:r2/vtysh/vtysh[;             configure terminal;             router bgp;              neighbor 192.168.1.1 local-role customer; ;             ] PASSED (0.12) [ 66%]
test_bgp_dynamic_capability_role.py::BGPDynamicCapabilityRole::bgp_check_if_session_not_reset:#133:r1/bgpd/vtysh[show bgp neighbor json] 
══════════════════════════════════════════════════════════ paused on failure ══════════════════════════════════════════════════════════

self = <test_bgp_dynamic_capability_role.BGPDynamicCapabilityRole object at 0x7f83c9bc76d0>, r1 = <Router 1 "r1">, r2 = <Router 2 "r2">

    @topotatofunc
    def bgp_check_if_session_not_reset(self, r1, r2):
        expected = {
            str(r2.iface_to("s1").ip4[0].ip): {
                "bgpState": "Established",
                "localRole": "customer",
                "remoteRole": "provider",
                "neighborCapabilities": {
                    "dynamic": "advertisedAndReceived",
                    "role": "advertisedAndReceived",
                },
                "connectionsEstablished": 1,
                "connectionsDropped": 0,
            }
        }

        yield from AssertVtysh.make(
            r1,
            "vtysh",
            """
            configure terminal
            router bgp
             neighbor 192.168.1.2 local-role customer

            """,
            compare="",
        )

        yield from AssertVtysh.make(
            r2,
            "vtysh",
            """
            configure terminal
            router bgp
             neighbor 192.168.1.1 local-role customer

            """,
            compare="",
        )

>       yield from AssertVtysh.make(
            r1,
            "bgpd",
            f"show bgp neighbor json",
            maxwait=5.0,
            compare=expected,
        )
E       topotato.exceptions.TopotatoCLICompareFail: expected key(s) ['neighborCapabilities'] in json["192.168.1.2"] (have ['remoteAs', 'lastResetDueTo', 'messageStats', 'externalBgpNbrMaxHopsAway', 'connectionsEstablished', 'localAs', 'nexthopLocal', 'nexthop', 'bgpTimerLastRead', 'bgpState', 'lastErrorCodeSubcode', 'gracefulRestartInfo', 'remoteRouterId', 'bgpTimerLastWrite', 'portLocal', 'localRole', 'bgpInUpdateElapsedTimeMsecs', 'nbrExternalLink', 'bgpConnection', 'bgpTimerConfiguredHoldTimeMsecs', 'bgpTimerHoldTimeMsecs', 'remoteRole', 'bgpTimerKeepAliveIntervalMsecs', 'addressFamilyInfo', 'nextStartTimerDueInMsecs', 'minBtwnAdvertisementRunsTimerMsecs', 'hostname', 'bgpTimerConfiguredConditionalAdvertisementsSec', 'lastNotificationReason', 'connectionsDropped', 'bgpTimerConfiguredKeepAliveIntervalMsecs', 'lastResetCode', 'lastNotificationHardReset', 'hostLocal', 'nexthopGlobal', 'connectRetryTimer', 'softwareVersion', 'extendedOptionalParametersLength', 'bgpVersion', 'portForeign', 'readThread', 'lastResetTimerMsecs', 'hostForeign', 'writeThread', 'localRouterId']):
E       --- Expected value
E       +++ Current value
E       @@ -2,2 +2,19 @@
E       -    "bgpState": "Established",
E       -    "connectionsDropped": 0,
E       +    "addressFamilyInfo": {
E       +        "ipv4Unicast": {
E       +            "acceptedPrefixCounter": 0,
E       +            "commAttriSentToNbr": "extendedAndStandard"
E       +        }
E       +    },
E       +    "bgpConnection": "sharedNetwork",
E       +    "bgpInUpdateElapsedTimeMsecs": 36786000,
E       +    "bgpState": "Idle",
E       +    "bgpTimerConfiguredConditionalAdvertisementsSec": 60,
E       +    "bgpTimerConfiguredHoldTimeMsecs": 3000,
E       +    "bgpTimerConfiguredKeepAliveIntervalMsecs": 1000,
E       +    "bgpTimerHoldTimeMsecs": 3000,
E       +    "bgpTimerKeepAliveIntervalMsecs": 1000,
E       +    "bgpTimerLastRead": 7000,
E       +    "bgpTimerLastWrite": 3000,
E       +    "bgpVersion": 4,
E       +    "connectRetryTimer": 1,
E       +    "connectionsDropped": 1,
E       @@ -4,0 +22,24 @@
E       +    "extendedOptionalParametersLength": false,
E       +    "externalBgpNbrMaxHopsAway": 1,
E       +    "gracefulRestartInfo": {
E       +        "endOfRibRecv": {},
E       +        "endOfRibSend": {},
E       +        "localGrMode": "Helper*",
E       +        "nBit": false,
E       +        "rBit": false,
E       +        "remoteGrMode": "NotApplicable",
E       +        "timers": {
E       +            "configuredRestartTimer": 120,
E       +            "receivedRestartTimer": 120
E       +        }
E       +    },
E       +    "hostForeign": "192.168.1.2",
E       +    "hostLocal": "192.168.1.1",
E       +    "hostname": "r2",
E       +    "lastErrorCodeSubcode": "020B",
E       +    "lastNotificationHardReset": false,
E       +    "lastNotificationReason": "OPEN Message Error/Role Mismatch",
E       +    "lastResetCode": 14,
E       +    "lastResetDueTo": "BGP Notification send",
E       +    "lastResetTimerMsecs": 5000,
E       +    "localAs": 65001,
E       @@ -6,3 +47,18 @@
E       -    "neighborCapabilities": {
E       -        "dynamic": "advertisedAndReceived",
E       -        "role": "advertisedAndReceived"
E       +    "localRouterId": "10.255.0.1",
E       +    "messageStats": {
E       +        "capabilityRecv": 0,
E       +        "capabilitySent": 0,
E       +        "depthInq": 0,
E       +        "depthOutq": 0,
E       +        "keepalivesRecv": 1,
E       +        "keepalivesSent": 1,
E       +        "notificationsRecv": 0,
E       +        "notificationsSent": 3,
E       +        "opensRecv": 3,
E       +        "opensSent": 3,
E       +        "routeRefreshRecv": 0,
E       +        "routeRefreshSent": 0,
E       +        "totalRecv": 4,
E       +        "totalSent": 7,
E       +        "updatesRecv": 0,
E       +        "updatesSent": 0
E       @@ -10 +66,14 @@
E       -    "remoteRole": "provider"
E       +    "minBtwnAdvertisementRunsTimerMsecs": 0,
E       +    "nbrExternalLink": true,
E       +    "nextStartTimerDueInMsecs": 1000,
E       +    "nexthop": "192.168.1.1",
E       +    "nexthopGlobal": "fdbc:1::fc01:ff:febc:100",
E       +    "nexthopLocal": "fe80::fc01:ff:febc:100",
E       +    "portForeign": 179,
E       +    "portLocal": 41958,
E       +    "readThread": "off",
E       +    "remoteAs": 65002,
E       +    "remoteRole": "undefined",
E       +    "remoteRouterId": "10.255.0.2",
E       +    "softwareVersion": "n/a",
E       +    "writeThread": "off"
E       json["192.168.1.2"]["remoteRole"] dict value is different (
E       --- Expected value
E       +++ Current value
E       @@ -1 +1 @@
E       -"provider"
E       +"undefined")
E       json["192.168.1.2"]["bgpState"] dict value is different (
E       --- Expected value
E       +++ Current value
E       @@ -1 +1 @@
E       -"Established"
E       +"Idle")
E       json["192.168.1.2"]["connectionsDropped"] dict value is different (
E       --- Expected value
E       +++ Current value
E       @@ -1 +1 @@
E       -0
E       +1)

/home/chromico/basetato4/test_bgp_dynamic_capability_role.py:133: TopotatoCLICompareFail

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ paused on failure ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
━━━━━ topology definition ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

        [ r1 ]
          |
        { s1 }
          |
        [ r2 ]

━━━━━ r1 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
                lo   10.255.0.1/32, fd00::1/128
             r1-s1   → s1         192.168.1.1/24, fdbc:1::fc01:ff:febc:100/64
━━━━━ r2 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
                lo   10.255.0.2/32, fd00::2/128
             r2-s1   → s1         192.168.1.2/24, fdbc:1::fc02:ff:febc:100/64
━━━━━ s1 (LAN) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
                r1   192.168.1.1/24, fdbc:1::fc01:ff:febc:100/64
                r2   192.168.1.2/24, fdbc:1::fc02:ff:febc:100/64

test_bgp_dynamic_capability_software_version.py:

The function for getting the software version and storing them for the JSON compare is still a work in progress.

@eqvinox what would be the best way to implement this bit from the original topotest?

        def _bgp_software_version():
            try:
                versions = output["192.168.1.2"]["neighborCapabilities"][
                    "softwareVersion"
                ]
                adv = versions["advertisedSoftwareVersion"]
                rcv = versions["receivedSoftwareVersion"]

                if not adv and not rcv:
                    return ""

                pattern = "FRRouting/\\d.+"
                if re.search(pattern, adv) and re.search(pattern, rcv):
                    return adv, rcv
            except:
                return ""

        output = json.loads(r1.vtysh_cmd("show bgp neighbor json"))
        adv, rcv = _bgp_software_version()