From 94bd5b9347d527da468c3109fdb9beb283b189ad Mon Sep 17 00:00:00 2001 From: Anuradha Karuppiah Date: Thu, 6 Feb 2020 09:31:05 -0800 Subject: [PATCH] tests: Add a evpn-pim test case This is a basic setup and test of evpn-pim. Create a vxlan device ensure that pim notices this and setups the appropriate groups and sends them to the RP. Signed-off-by: Donald Sharp --- tests/topotests/evpn-pim-1/host1/bgpd.conf | 1 + tests/topotests/evpn-pim-1/host1/pimd.conf | 4 + tests/topotests/evpn-pim-1/host1/zebra.conf | 5 + tests/topotests/evpn-pim-1/host2/bgpd.conf | 1 + tests/topotests/evpn-pim-1/host2/pimd.conf | 4 + tests/topotests/evpn-pim-1/host2/zebra.conf | 5 + tests/topotests/evpn-pim-1/leaf1/bgpd.conf | 9 + tests/topotests/evpn-pim-1/leaf1/pimd.conf | 15 ++ tests/topotests/evpn-pim-1/leaf1/zebra.conf | 6 + tests/topotests/evpn-pim-1/leaf2/bgpd.conf | 9 + tests/topotests/evpn-pim-1/leaf2/pimd.conf | 13 ++ tests/topotests/evpn-pim-1/leaf2/zebra.conf | 6 + .../topotests/evpn-pim-1/spine/bgp.summ.json | 44 ++++ tests/topotests/evpn-pim-1/spine/bgpd.conf | 10 + .../topotests/evpn-pim-1/spine/join-info.json | 34 +++ tests/topotests/evpn-pim-1/spine/pimd.conf | 13 ++ tests/topotests/evpn-pim-1/spine/zebra.conf | 8 + .../evpn-pim-1/test_evpn_pim_topo1.py | 215 ++++++++++++++++++ 18 files changed, 402 insertions(+) create mode 100644 tests/topotests/evpn-pim-1/host1/bgpd.conf create mode 100644 tests/topotests/evpn-pim-1/host1/pimd.conf create mode 100644 tests/topotests/evpn-pim-1/host1/zebra.conf create mode 100644 tests/topotests/evpn-pim-1/host2/bgpd.conf create mode 100644 tests/topotests/evpn-pim-1/host2/pimd.conf create mode 100644 tests/topotests/evpn-pim-1/host2/zebra.conf create mode 100644 tests/topotests/evpn-pim-1/leaf1/bgpd.conf create mode 100644 tests/topotests/evpn-pim-1/leaf1/pimd.conf create mode 100644 tests/topotests/evpn-pim-1/leaf1/zebra.conf create mode 100644 tests/topotests/evpn-pim-1/leaf2/bgpd.conf create mode 100644 tests/topotests/evpn-pim-1/leaf2/pimd.conf create mode 100644 tests/topotests/evpn-pim-1/leaf2/zebra.conf create mode 100644 tests/topotests/evpn-pim-1/spine/bgp.summ.json create mode 100644 tests/topotests/evpn-pim-1/spine/bgpd.conf create mode 100644 tests/topotests/evpn-pim-1/spine/join-info.json create mode 100644 tests/topotests/evpn-pim-1/spine/pimd.conf create mode 100644 tests/topotests/evpn-pim-1/spine/zebra.conf create mode 100755 tests/topotests/evpn-pim-1/test_evpn_pim_topo1.py diff --git a/tests/topotests/evpn-pim-1/host1/bgpd.conf b/tests/topotests/evpn-pim-1/host1/bgpd.conf new file mode 100644 index 0000000000..cdf4cb4feb --- /dev/null +++ b/tests/topotests/evpn-pim-1/host1/bgpd.conf @@ -0,0 +1 @@ +! diff --git a/tests/topotests/evpn-pim-1/host1/pimd.conf b/tests/topotests/evpn-pim-1/host1/pimd.conf new file mode 100644 index 0000000000..63a44c1333 --- /dev/null +++ b/tests/topotests/evpn-pim-1/host1/pimd.conf @@ -0,0 +1,4 @@ +int lo +! + + diff --git a/tests/topotests/evpn-pim-1/host1/zebra.conf b/tests/topotests/evpn-pim-1/host1/zebra.conf new file mode 100644 index 0000000000..45ad031017 --- /dev/null +++ b/tests/topotests/evpn-pim-1/host1/zebra.conf @@ -0,0 +1,5 @@ +int host1-eth0 + ip addr 192.168.3.4/24 + +int lo + ip addr 192.168.100.4/32 diff --git a/tests/topotests/evpn-pim-1/host2/bgpd.conf b/tests/topotests/evpn-pim-1/host2/bgpd.conf new file mode 100644 index 0000000000..cdf4cb4feb --- /dev/null +++ b/tests/topotests/evpn-pim-1/host2/bgpd.conf @@ -0,0 +1 @@ +! diff --git a/tests/topotests/evpn-pim-1/host2/pimd.conf b/tests/topotests/evpn-pim-1/host2/pimd.conf new file mode 100644 index 0000000000..63a44c1333 --- /dev/null +++ b/tests/topotests/evpn-pim-1/host2/pimd.conf @@ -0,0 +1,4 @@ +int lo +! + + diff --git a/tests/topotests/evpn-pim-1/host2/zebra.conf b/tests/topotests/evpn-pim-1/host2/zebra.conf new file mode 100644 index 0000000000..bfae53017f --- /dev/null +++ b/tests/topotests/evpn-pim-1/host2/zebra.conf @@ -0,0 +1,5 @@ +int host-eth0 + ip addr 192.168.4.5/24 + +int lo + ip addr 192.168.100.5/32 diff --git a/tests/topotests/evpn-pim-1/leaf1/bgpd.conf b/tests/topotests/evpn-pim-1/leaf1/bgpd.conf new file mode 100644 index 0000000000..33d34db677 --- /dev/null +++ b/tests/topotests/evpn-pim-1/leaf1/bgpd.conf @@ -0,0 +1,9 @@ + +router bgp 65002 + neighbor 192.168.1.1 remote-as external + redistribute connected + address-family l2vpn evpn + neighbor 192.168.1.1 activate + advertise-all-vni + ! +! \ No newline at end of file diff --git a/tests/topotests/evpn-pim-1/leaf1/pimd.conf b/tests/topotests/evpn-pim-1/leaf1/pimd.conf new file mode 100644 index 0000000000..293e252086 --- /dev/null +++ b/tests/topotests/evpn-pim-1/leaf1/pimd.conf @@ -0,0 +1,15 @@ +debug pim events +debug pim nht +debug pim zebra +ip pim rp 192.168.100.1 +! +int lo + ip pim +! +int leaf1-eth0 + ip pim +! +int leaf1-eth1 + ip pim + ip igmp + diff --git a/tests/topotests/evpn-pim-1/leaf1/zebra.conf b/tests/topotests/evpn-pim-1/leaf1/zebra.conf new file mode 100644 index 0000000000..581cc6e7be --- /dev/null +++ b/tests/topotests/evpn-pim-1/leaf1/zebra.conf @@ -0,0 +1,6 @@ +int leaf1-eth0 + ip addr 192.168.1.2/24 +int leaf1-eth1 + ip addr 192.168.3.2/24 +int lo + ip addr 192.168.100.2/32 diff --git a/tests/topotests/evpn-pim-1/leaf2/bgpd.conf b/tests/topotests/evpn-pim-1/leaf2/bgpd.conf new file mode 100644 index 0000000000..3dd9f237be --- /dev/null +++ b/tests/topotests/evpn-pim-1/leaf2/bgpd.conf @@ -0,0 +1,9 @@ + +router bgp 65003 + neighbor 192.168.2.1 remote-as external + redistribute connected + address-family l2vpn evpn + neighbor 192.168.2.1 activate + advertise-all-vni + ! +! \ No newline at end of file diff --git a/tests/topotests/evpn-pim-1/leaf2/pimd.conf b/tests/topotests/evpn-pim-1/leaf2/pimd.conf new file mode 100644 index 0000000000..08d5a19a2a --- /dev/null +++ b/tests/topotests/evpn-pim-1/leaf2/pimd.conf @@ -0,0 +1,13 @@ +ip pim rp 192.168.100.1 +! +int lo + ip pim +! +int leaf2-eth0 + ip pim +! +int leaf2-eth1 + ip pim + ip igmp +! + diff --git a/tests/topotests/evpn-pim-1/leaf2/zebra.conf b/tests/topotests/evpn-pim-1/leaf2/zebra.conf new file mode 100644 index 0000000000..1bcf8e1ded --- /dev/null +++ b/tests/topotests/evpn-pim-1/leaf2/zebra.conf @@ -0,0 +1,6 @@ +int leaf2-eth0 + ip addr 192.168.2.3/24 +int leaf2-eth1 + ip addr 192.168.4.3/24 +int lo + ip addr 192.168.100.3/32 diff --git a/tests/topotests/evpn-pim-1/spine/bgp.summ.json b/tests/topotests/evpn-pim-1/spine/bgp.summ.json new file mode 100644 index 0000000000..faf40c8d43 --- /dev/null +++ b/tests/topotests/evpn-pim-1/spine/bgp.summ.json @@ -0,0 +1,44 @@ +{ + "routerId":"192.168.100.1", + "as":65001, + "vrfId":0, + "vrfName":"default", + "tableVersion":7, + "peerCount":2, + "peers":{ + "192.168.1.2":{ + "remoteAs":65002, + "version":4, + "tableVersion":0, + "outq":0, + "inq":0, + "prefixReceivedCount":3, + "pfxRcd":3, + "pfxSnt":7, + "state":"Established", + "connectionsEstablished":1, + "connectionsDropped":0, + "idType":"ipv4" + }, + "192.168.2.3":{ + "remoteAs":65003, + "version":4, + "tableVersion":0, + "outq":0, + "inq":0, + "prefixReceivedCount":3, + "pfxRcd":3, + "pfxSnt":7, + "state":"Established", + "connectionsEstablished":1, + "connectionsDropped":0, + "idType":"ipv4" + } + }, + "failedPeers":0, + "totalPeers":2, + "dynamicPeers":0, + "bestPath":{ + "multiPathRelax":"false" + } +} diff --git a/tests/topotests/evpn-pim-1/spine/bgpd.conf b/tests/topotests/evpn-pim-1/spine/bgpd.conf new file mode 100644 index 0000000000..9a845043e9 --- /dev/null +++ b/tests/topotests/evpn-pim-1/spine/bgpd.conf @@ -0,0 +1,10 @@ + +router bgp 65001 + neighbor 192.168.1.2 remote-as external + neighbor 192.168.2.3 remote-as external + redistribute connected + address-family l2vpn evpn + neighbor 192.168.1.2 activate + neighbor 192.168.2.3 activate + exit-address-family +! diff --git a/tests/topotests/evpn-pim-1/spine/join-info.json b/tests/topotests/evpn-pim-1/spine/join-info.json new file mode 100644 index 0000000000..3d135fb964 --- /dev/null +++ b/tests/topotests/evpn-pim-1/spine/join-info.json @@ -0,0 +1,34 @@ +{ + "spine-eth0":{ + "name":"spine-eth0", + "state":"up", + "address":"192.168.1.1", + "flagMulticast":true, + "flagBroadcast":true, + "lanDelayEnabled":true, + "239.1.1.1":{ + "*":{ + "source":"*", + "group":"239.1.1.1", + "prune":"--:--", + "channelJoinName":"JOIN" + } + } + }, + "spine-eth1":{ + "name":"spine-eth1", + "state":"up", + "address":"192.168.2.1", + "flagMulticast":true, + "flagBroadcast":true, + "lanDelayEnabled":true, + "239.1.1.1":{ + "*":{ + "source":"*", + "group":"239.1.1.1", + "prune":"--:--", + "channelJoinName":"JOIN" + } + } + } +} diff --git a/tests/topotests/evpn-pim-1/spine/pimd.conf b/tests/topotests/evpn-pim-1/spine/pimd.conf new file mode 100644 index 0000000000..56adda5cc4 --- /dev/null +++ b/tests/topotests/evpn-pim-1/spine/pimd.conf @@ -0,0 +1,13 @@ +ip pim rp 192.168.100.1 +! +int lo + ip pim +! +int spine-eth0 + ip pim +! +int spine-eth1 + ip pim +! + + diff --git a/tests/topotests/evpn-pim-1/spine/zebra.conf b/tests/topotests/evpn-pim-1/spine/zebra.conf new file mode 100644 index 0000000000..2cb719486e --- /dev/null +++ b/tests/topotests/evpn-pim-1/spine/zebra.conf @@ -0,0 +1,8 @@ +int spine-eth0 + ip addr 192.168.1.1/24 +! +int spine-eth1 + ip addr 192.168.2.1/24 +! +int lo + ip addr 192.168.100.1/32 diff --git a/tests/topotests/evpn-pim-1/test_evpn_pim_topo1.py b/tests/topotests/evpn-pim-1/test_evpn_pim_topo1.py new file mode 100755 index 0000000000..dafe2e03ac --- /dev/null +++ b/tests/topotests/evpn-pim-1/test_evpn_pim_topo1.py @@ -0,0 +1,215 @@ +#!/usr/bin/env python + +# +# test_evpn-pim_topo1.py +# +# Copyright (c) 2017 by +# Cumulus Networks, Inc. +# Donald Sharp +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +""" +test_evpn_pim_topo1.py: Testing evpn-pim + +""" + +import os +import re +import sys +import pytest +import json +from functools import partial + +# Save the Current Working Directory to find configuration files. +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, '../')) + +# pylint: disable=C0413 +# Import topogen and topotest helpers +from lib import topotest +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topolog import logger + +# Required to instantiate the topology builder class. +from mininet.topo import Topo + +##################################################### +## +## Network Topology Definition +## +##################################################### + +class NetworkTopo(Topo): + "evpn-pim Topology 1" + + def build(self, **_opts): + "Build function" + + tgen = get_topogen(self) + + tgen.add_router('spine') + tgen.add_router('leaf1') + tgen.add_router('leaf2') + tgen.add_router('host1') + tgen.add_router('host2') + + # On main router + # First switch is for a dummy interface (for local network) + # spine-eth0 is connected to leaf1-eth0 + switch = tgen.add_switch('sw1') + switch.add_link(tgen.gears['spine']) + switch.add_link(tgen.gears['leaf1']) + + # spine-eth1 is connected to leaf2-eth0 + switch = tgen.add_switch('sw2') + switch.add_link(tgen.gears['spine']) + switch.add_link(tgen.gears['leaf2']) + + # leaf1-eth1 is connected to host1-eth0 + switch = tgen.add_switch('sw3') + switch.add_link(tgen.gears['leaf1']) + switch.add_link(tgen.gears['host1']) + + # leaf2-eth1 is connected to host2-eth0 + switch = tgen.add_switch('sw4') + switch.add_link(tgen.gears['leaf2']) + switch.add_link(tgen.gears['host2']) + + + +##################################################### +## +## Tests starting +## +##################################################### + +def setup_module(module): + "Setup topology" + tgen = Topogen(NetworkTopo, module.__name__) + tgen.start_topology() + + leaf1 = tgen.gears['leaf1'] + leaf2 = tgen.gears['leaf2'] + + leaf1.run('brctl addbr brleaf1') + leaf2.run('brctl addbr brleaf2') + leaf1.run('ip link set dev brleaf1 up') + leaf2.run('ip link set dev brleaf2 up') + leaf1.run('ip link add vxlan0 type vxlan id 42 group 239.1.1.1 dev leaf1-eth1 dstport 4789') + leaf2.run('ip link add vxlan0 type vxlan id 42 group 239.1.1.1 dev leaf2-eth1 dstport 4789') + leaf1.run('brctl addif brleaf1 vxlan0') + leaf2.run('brctl addif brleaf2 vxlan0') + leaf1.run('ip link set up dev vxlan0') + leaf2.run('ip link set up dev vxlan0') + #tgen.mininet_cli() + # This is a sample of configuration loading. + router_list = tgen.routers() + for rname, router in router_list.iteritems(): + router.load_config( + TopoRouter.RD_ZEBRA, + os.path.join(CWD, '{}/zebra.conf'.format(rname)) + ) + router.load_config( + TopoRouter.RD_BGP, + os.path.join(CWD, '{}/bgpd.conf'.format(rname)) + ) + router.load_config( + TopoRouter.RD_PIM, + os.path.join(CWD, '{}/pimd.conf'.format(rname)) + ) + tgen.start_router() + #tgen.mininet_cli() + +def teardown_module(_mod): + "Teardown the pytest environment" + tgen = get_topogen() + + # This function tears down the whole topology. + tgen.stop_topology() + + +def test_converge_protocols(): + "Wait for protocol convergence" + + tgen = get_topogen() + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + spine = tgen.gears['spine'] + json_file = '{}/{}/bgp.summ.json'.format(CWD, spine.name) + expected = json.loads(open(json_file).read()) + + test_func = partial(topotest.router_json_cmp, + spine, 'show bgp ipv4 uni summ json', expected) + _, result = topotest.run_and_expect(test_func, None, count=125, wait=1) + assertmsg = '"{}" JSON output mismatches'.format(spine.name) + assert result is None, assertmsg + #tgen.mininet_cli() + +def test_multicast_groups_on_rp(): + "Ensure the multicast groups show up on the spine" + # This test implicitly tests the auto mcast groups + # of the created vlans and then the auto-joins that + # pim will do to the RP( spine ) + + tgen = get_topogen() + + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + spine = tgen.gears['spine'] + json_file = '{}/{}/join-info.json'.format(CWD, spine.name) + expected = json.loads(open(json_file).read()) + + test_func = partial(topotest.router_json_cmp, + spine, 'show ip pim join json', expected) + _, result = topotest.run_and_expect(test_func, None, count=30, wait=1) + assertmsg = '"{}" JSON output mismatches'.format(spine.name) + assert result is None, assertmsg + #tgen.mininet_cli() + +def test_shutdown_check_stderr(): + if os.environ.get('TOPOTESTS_CHECK_STDERR') is None: + pytest.skip('Skipping test for Stderr output and memory leaks') + + tgen = get_topogen() + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + logger.info("Verifying unexpected STDERR output from daemons") + + router_list = tgen.routers().values() + for router in router_list: + router.stop() + + log = tgen.net[router.name].getStdErr('pimd') + if log: + logger.error('PIMd StdErr Log:' + log) + log = tgen.net[router.name].getStdErr('bgpd') + if log: + logger.error('BGPd StdErr Log:' + log) + log = tgen.net[router.name].getStdErr('zebra') + if log: + logger.error('Zebra StdErr Log:' + log) + + +if __name__ == '__main__': + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) + -- 2.39.5