mirror of
https://git.proxmox.com/git/mirror_frr
synced 2026-01-05 21:48:46 +00:00
all-protocol-startup: Add test suite which runs all protocols at once and verifies startup and spurious errors of each
Signed-off-by: Martin Winter <mwinter@opensourcerouting.org>
This commit is contained in:
parent
80eeefb7da
commit
4501fbcaa8
47
tests/topotests/all-protocol-startup/r1/bgpd.conf
Normal file
47
tests/topotests/all-protocol-startup/r1/bgpd.conf
Normal file
@ -0,0 +1,47 @@
|
||||
log file /tmp/r1-bgpd.log
|
||||
!
|
||||
!
|
||||
router bgp 100
|
||||
bgp router-id 192.168.0.1
|
||||
bgp log-neighbor-changes
|
||||
neighbor 192.168.7.10 remote-as 100
|
||||
neighbor 192.168.7.20 remote-as 200
|
||||
neighbor fc00:0:0:8::1000 remote-as 100
|
||||
neighbor fc00:0:0:8::2000 remote-as 200
|
||||
!
|
||||
address-family ipv4 unicast
|
||||
network 192.168.0.0/24
|
||||
neighbor 192.168.7.10 route-map bgp-map in
|
||||
neighbor 192.168.7.10 filter-list bgp-filter-v4 out
|
||||
neighbor 192.168.7.20 route-map bgp-map in
|
||||
neighbor 192.168.7.20 filter-list bgp-filter-v4 out
|
||||
exit-address-family
|
||||
!
|
||||
address-family ipv6 unicast
|
||||
network fc00::/64
|
||||
neighbor fc00:0:0:8::1000 activate
|
||||
neighbor fc00:0:0:8::1000 route-map bgp-map in
|
||||
neighbor fc00:0:0:8::1000 filter-list bgp-filter-v6 out
|
||||
neighbor fc00:0:0:8::2000 activate
|
||||
neighbor fc00:0:0:8::2000 route-map bgp-map in
|
||||
neighbor fc00:0:0:8::2000 filter-list bgp-filter-v6 out
|
||||
exit-address-family
|
||||
!
|
||||
!
|
||||
ip prefix-list bgp-filter-v4 description dummy-test-prefix-list
|
||||
ip prefix-list bgp-filter-v4 seq 5 permit 192.168.0.0/24
|
||||
!
|
||||
ipv6 prefix-list bgp-filter-v4 seq 5 permit fc00::/64
|
||||
ipv6 prefix-list bgp-filter-v6 description dummy-test-prefix-list-v6
|
||||
!
|
||||
route-map bgp-map permit 10
|
||||
set community 100:100 additive
|
||||
set local-preference 100
|
||||
!
|
||||
route-map bgp-map permit 20
|
||||
set metric 10
|
||||
set local-preference 200
|
||||
!
|
||||
line vty
|
||||
!
|
||||
|
||||
21
tests/topotests/all-protocol-startup/r1/isisd.conf
Normal file
21
tests/topotests/all-protocol-startup/r1/isisd.conf
Normal file
@ -0,0 +1,21 @@
|
||||
log file /tmp/r1-isisd.log
|
||||
!
|
||||
debug isis events
|
||||
!
|
||||
!
|
||||
interface r1-eth5
|
||||
ip router isis test
|
||||
isis circuit-type level-1
|
||||
!
|
||||
interface r1-eth6
|
||||
ipv6 router isis test
|
||||
isis circuit-type level-2-only
|
||||
!
|
||||
!
|
||||
router isis test
|
||||
net 00.0001.00b0.64bc.43a0.00
|
||||
metric-style wide
|
||||
log-adjacency-changes
|
||||
!
|
||||
line vty
|
||||
!
|
||||
25
tests/topotests/all-protocol-startup/r1/ldpd.conf
Normal file
25
tests/topotests/all-protocol-startup/r1/ldpd.conf
Normal file
@ -0,0 +1,25 @@
|
||||
log file /tmp/r1-ldpd.log
|
||||
!
|
||||
debug mpls ldp event
|
||||
debug mpls ldp zebra
|
||||
!
|
||||
!
|
||||
mpls ldp
|
||||
router-id 192.168.0.1
|
||||
!
|
||||
address-family ipv4
|
||||
discovery transport-address 192.168.9.1
|
||||
!
|
||||
interface r1-eth9
|
||||
!
|
||||
!
|
||||
address-family ipv6
|
||||
discovery transport-address fc00:0:0:9::1
|
||||
!
|
||||
interface r1-eth9
|
||||
!
|
||||
!
|
||||
!
|
||||
!
|
||||
line vty
|
||||
!
|
||||
16
tests/topotests/all-protocol-startup/r1/ospf6d.conf
Normal file
16
tests/topotests/all-protocol-startup/r1/ospf6d.conf
Normal file
@ -0,0 +1,16 @@
|
||||
log file /tmp/r1-ospf6d.log
|
||||
!
|
||||
debug ospf6 lsa unknown
|
||||
debug ospf6 zebra
|
||||
debug ospf6 interface
|
||||
debug ospf6 neighbor
|
||||
!
|
||||
interface r1-eth4
|
||||
!
|
||||
router ospf6
|
||||
router-id 192.168.0.1
|
||||
log-adjacency-changes
|
||||
interface r1-eth4 area 0.0.0.0
|
||||
!
|
||||
line vty
|
||||
!
|
||||
13
tests/topotests/all-protocol-startup/r1/ospfd.conf
Normal file
13
tests/topotests/all-protocol-startup/r1/ospfd.conf
Normal file
@ -0,0 +1,13 @@
|
||||
log file /tmp/r1-ospfd.log
|
||||
!
|
||||
debug ospf event
|
||||
debug ospf zebra
|
||||
!
|
||||
router ospf
|
||||
ospf router-id 192.168.0.1
|
||||
log-adjacency-changes
|
||||
network 192.168.0.0/24 area 0.0.0.0
|
||||
network 192.168.3.0/24 area 0.0.0.0
|
||||
!
|
||||
line vty
|
||||
!
|
||||
15
tests/topotests/all-protocol-startup/r1/rip_status.ref
Normal file
15
tests/topotests/all-protocol-startup/r1/rip_status.ref
Normal file
@ -0,0 +1,15 @@
|
||||
Routing Protocol is "rip"
|
||||
Sending updates every 30 seconds with +/-50%, next due in XX seconds
|
||||
Timeout after 180 seconds, garbage collect after 120 seconds
|
||||
Outgoing update filter list for all interface is not set
|
||||
Incoming update filter list for all interface is not set
|
||||
Default redistribution metric is 1
|
||||
Redistributing:
|
||||
Default version control: send version 2, receive version 2
|
||||
Interface Send Recv Key-chain
|
||||
r1-eth1 2 2
|
||||
Routing for Networks:
|
||||
192.168.1.0/26
|
||||
Routing Information Sources:
|
||||
Gateway BadPackets BadRoutes Distance Last Update
|
||||
Distance: (default is 120)
|
||||
12
tests/topotests/all-protocol-startup/r1/ripd.conf
Normal file
12
tests/topotests/all-protocol-startup/r1/ripd.conf
Normal file
@ -0,0 +1,12 @@
|
||||
log file /tmp/r1-ripd.log
|
||||
!
|
||||
debug rip events
|
||||
debug rip zebra
|
||||
!
|
||||
router rip
|
||||
version 2
|
||||
network 192.168.1.0/26
|
||||
!
|
||||
line vty
|
||||
!
|
||||
|
||||
14
tests/topotests/all-protocol-startup/r1/ripng_status.ref
Normal file
14
tests/topotests/all-protocol-startup/r1/ripng_status.ref
Normal file
@ -0,0 +1,14 @@
|
||||
Routing Protocol is "RIPng"
|
||||
Sending updates every 30 seconds with +/-50%, next due in XX seconds
|
||||
Timeout after 180 seconds, garbage collect after 120 seconds
|
||||
Outgoing update filter list for all interface is not set
|
||||
Incoming update filter list for all interface is not set
|
||||
Default redistribution metric is 1
|
||||
Redistributing:
|
||||
Default version control: send version 1, receive version 1
|
||||
Interface Send Recv
|
||||
r1-eth2 1 1
|
||||
Routing for Networks:
|
||||
fc00:0:0:2::/64
|
||||
Routing Information Sources:
|
||||
Gateway BadPackets BadRoutes Distance Last Update
|
||||
11
tests/topotests/all-protocol-startup/r1/ripngd.conf
Normal file
11
tests/topotests/all-protocol-startup/r1/ripngd.conf
Normal file
@ -0,0 +1,11 @@
|
||||
log file /tmp/r1-ripngd.log
|
||||
!
|
||||
debug ripng events
|
||||
debug ripng zebra
|
||||
!
|
||||
router ripng
|
||||
network fc00:0:0:2::/64
|
||||
!
|
||||
line vty
|
||||
!
|
||||
|
||||
@ -0,0 +1,7 @@
|
||||
BGP table version is 1, local router ID is 192.168.0.1
|
||||
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
|
||||
i internal, r RIB-failure, S Stale, R Removed
|
||||
Origin codes: i - IGP, e - EGP, ? - incomplete
|
||||
|
||||
Network Next Hop Metric LocPrf Weight Path
|
||||
*> 192.168.0.0 0.0.0.0 0 32768 i
|
||||
@ -0,0 +1,7 @@
|
||||
BGP table version is 1, local router ID is 192.168.0.1
|
||||
Status codes: s suppressed, d damped, h history, * valid, > best, = multipath,
|
||||
i internal, r RIB-failure, S Stale, R Removed
|
||||
Origin codes: i - IGP, e - EGP, ? - incomplete
|
||||
|
||||
Network Next Hop Metric LocPrf Weight Path
|
||||
*> fc00::/64 :: 0 32768 i
|
||||
@ -0,0 +1,21 @@
|
||||
|
||||
IPv6 Unicast Summary:
|
||||
BGP router identifier 192.168.0.1, local AS number 100 vrf-id 0
|
||||
BGP table version 1
|
||||
RIB entries 1, using XXXX bytes of memory
|
||||
Peers 4, using XXXX KiB of memory
|
||||
|
||||
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd
|
||||
fc00:0:0:8::1000 4 100 0 0 0 0 0 never Active
|
||||
fc00:0:0:8::2000 4 200 0 0 0 0 0 never Active
|
||||
|
||||
Total number of neighbors 2
|
||||
|
||||
IPv6 Multicast Summary:
|
||||
No IPv6 Multicast neighbor is configured
|
||||
|
||||
IPv6 VPN Summary:
|
||||
No IPv6 VPN neighbor is configured
|
||||
|
||||
IPv6 Encap Summary:
|
||||
No IPv6 Encap neighbor is configured
|
||||
@ -0,0 +1,15 @@
|
||||
BGP router identifier 192.168.0.1, local AS number 100 vrf-id 0
|
||||
BGP table version 1
|
||||
RIB entries 1, using XXXX bytes of memory
|
||||
Peers 4, using XXXX KiB of memory
|
||||
|
||||
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/
|
||||
PfxRcd
|
||||
192.168.7.10 4 100 0 0 0 0 0 never
|
||||
Active
|
||||
192.168.7.20 4 200 0 0 0 0 0 never
|
||||
Active
|
||||
fc00:0:0:8::1000 4 100 0 0 0 0 0 never
|
||||
Active
|
||||
fc00:0:0:8::2000 4 200 0 0 0 0 0 never
|
||||
Active
|
||||
@ -0,0 +1,22 @@
|
||||
r1-eth0 is up
|
||||
ifindex 2, MTU 1500 bytes, BW XX Mbit <UP,BROADCAST,RUNNING,MULTICAST>
|
||||
Internet Address 192.168.0.1/24, Broadcast 192.168.0.255, Area 0.0.0.0
|
||||
MTU mismatch detection:enabled
|
||||
Router ID 192.168.0.1, Network Type BROADCAST, Cost: 10
|
||||
Transmit Delay is 1 sec, State DR, Priority 1
|
||||
No backup designated router on this network
|
||||
Multicast group memberships: OSPFAllRouters OSPFDesignatedRouters
|
||||
Timer intervals configured, Hello 10s, Dead 40s, Wait 40s, Retransmit 5
|
||||
Hello due in XX.XXXs
|
||||
Neighbor Count is 0, Adjacent neighbor count is 0
|
||||
r1-eth3 is up
|
||||
ifindex 5, MTU 1500 bytes, BW XX Mbit <UP,BROADCAST,RUNNING,MULTICAST>
|
||||
Internet Address 192.168.3.1/26, Broadcast 192.168.3.63, Area 0.0.0.0
|
||||
MTU mismatch detection:enabled
|
||||
Router ID 192.168.0.1, Network Type BROADCAST, Cost: 10
|
||||
Transmit Delay is 1 sec, State DR, Priority 1
|
||||
No backup designated router on this network
|
||||
Multicast group memberships: OSPFAllRouters OSPFDesignatedRouters
|
||||
Timer intervals configured, Hello 10s, Dead 40s, Wait 40s, Retransmit 5
|
||||
Hello due in XX.XXXs
|
||||
Neighbor Count is 0, Adjacent neighbor count is 0
|
||||
@ -0,0 +1,46 @@
|
||||
lo is up, type LOOPBACK
|
||||
Interface ID: 1
|
||||
OSPF not enabled on this interface
|
||||
r1-eth0 is up, type BROADCAST
|
||||
Interface ID: 2
|
||||
OSPF not enabled on this interface
|
||||
r1-eth1 is up, type BROADCAST
|
||||
Interface ID: 3
|
||||
OSPF not enabled on this interface
|
||||
r1-eth2 is up, type BROADCAST
|
||||
Interface ID: 4
|
||||
OSPF not enabled on this interface
|
||||
r1-eth3 is up, type BROADCAST
|
||||
Interface ID: 5
|
||||
OSPF not enabled on this interface
|
||||
r1-eth4 is up, type BROADCAST
|
||||
Interface ID: 6
|
||||
Internet Address:
|
||||
inet : 192.168.4.1/26
|
||||
inet6: fc00:0:0:4::1/64
|
||||
inet6: fe80::XXXX:XXXX:XXXX:XXXX/64
|
||||
Instance ID 0, Interface MTU 1500 (autodetect: 1500)
|
||||
MTU mismatch detection: enabled
|
||||
Area ID 0.0.0.0, Cost 10
|
||||
State DR, Transmit Delay 1 sec, Priority 1
|
||||
Timer intervals configured:
|
||||
Hello 10, Dead 40, Retransmit 5
|
||||
DR: 192.168.0.1 BDR: 0.0.0.0
|
||||
Number of I/F scoped LSAs is 1
|
||||
0 Pending LSAs for LSUpdate in Time 00:00:00 [thread off]
|
||||
0 Pending LSAs for LSAck in Time 00:00:00 [thread off]
|
||||
r1-eth5 is up, type BROADCAST
|
||||
Interface ID: 7
|
||||
OSPF not enabled on this interface
|
||||
r1-eth6 is up, type BROADCAST
|
||||
Interface ID: 8
|
||||
OSPF not enabled on this interface
|
||||
r1-eth7 is up, type BROADCAST
|
||||
Interface ID: 9
|
||||
OSPF not enabled on this interface
|
||||
r1-eth8 is up, type BROADCAST
|
||||
Interface ID: 10
|
||||
OSPF not enabled on this interface
|
||||
r1-eth9 is up, type BROADCAST
|
||||
Interface ID: 11
|
||||
OSPF not enabled on this interface
|
||||
@ -0,0 +1,28 @@
|
||||
Area test:
|
||||
Interface: r1-eth5, State: Up, Active, Circuit Id: 0x1
|
||||
Type: lan, Level: L1, SNPA: XXXX.XXXX.XXXX
|
||||
Level-1 Information:
|
||||
Metric: 10, Active neighbors: 0
|
||||
Hello interval: 3, Holddown count: 10 (pad)
|
||||
CNSP interval: 10, PSNP interval: 2
|
||||
LAN Priority: 64, is not DIS
|
||||
IP Prefix(es):
|
||||
192.168.5.1/26
|
||||
IPv6 Link-Locals:
|
||||
fe80::XXXX:XXXX:XXXX:XXXX/64
|
||||
IPv6 Prefixes:
|
||||
fc00:0:0:5::1/64
|
||||
|
||||
Interface: r1-eth6, State: Up, Active, Circuit Id: 0x1
|
||||
Type: lan, Level: L2, SNPA: XXXX.XXXX.XXXX
|
||||
Level-2 Information:
|
||||
Metric: 10, Active neighbors: 0
|
||||
Hello interval: 3, Holddown count: 10 (pad)
|
||||
CNSP interval: 10, PSNP interval: 2
|
||||
LAN Priority: 64, is not DIS
|
||||
IP Prefix(es):
|
||||
192.168.6.1/26
|
||||
IPv6 Link-Locals:
|
||||
fe80::XXXX:XXXX:XXXX:XXXX/64
|
||||
IPv6 Prefixes:
|
||||
fc00:0:0:6::1/64
|
||||
@ -0,0 +1,3 @@
|
||||
AF Interface State Uptime Hello Timers ac
|
||||
ipv4 r1-eth9 ACTIVE xx:xx:xx 5/15 0
|
||||
ipv6 r1-eth9 ACTIVE xx:xx:xx 5/15 0
|
||||
72
tests/topotests/all-protocol-startup/r1/zebra.conf
Normal file
72
tests/topotests/all-protocol-startup/r1/zebra.conf
Normal file
@ -0,0 +1,72 @@
|
||||
log file /tmp/r1-zebra.log
|
||||
!
|
||||
hostname r1
|
||||
!
|
||||
interface r1-eth0
|
||||
description to sw0 - no routing protocol
|
||||
ip address 192.168.0.1/24
|
||||
ipv6 address fc00:0:0:0::1/64
|
||||
!
|
||||
interface r1-eth1
|
||||
description to sw1 - RIP interface
|
||||
ip address 192.168.1.1/26
|
||||
ipv6 address fc00:0:0:1::1/64
|
||||
no link-detect
|
||||
!
|
||||
interface r1-eth2
|
||||
description to sw2 - RIPng interface
|
||||
ip address 192.168.2.1/26
|
||||
ipv6 address fc00:0:0:2::1/64
|
||||
no link-detect
|
||||
!
|
||||
interface r1-eth3
|
||||
description to sw3 - OSPFv2 interface
|
||||
ip address 192.168.3.1/26
|
||||
ipv6 address fc00:0:0:3::1/64
|
||||
no link-detect
|
||||
!
|
||||
interface r1-eth4
|
||||
description to sw4 - OSPFv3 interface
|
||||
ip address 192.168.4.1/26
|
||||
ipv6 address fc00:0:0:4::1/64
|
||||
no link-detect
|
||||
!
|
||||
interface r1-eth5
|
||||
description to sw5 - ISIS IPv4 interface
|
||||
ip address 192.168.5.1/26
|
||||
ipv6 address fc00:0:0:5::1/64
|
||||
no link-detect
|
||||
!
|
||||
interface r1-eth6
|
||||
description to sw6 - ISIS IPv6 interface
|
||||
ip address 192.168.6.1/26
|
||||
ipv6 address fc00:0:0:6::1/64
|
||||
no link-detect
|
||||
!
|
||||
interface r1-eth7
|
||||
description to sw7 - BGP IPv4 interface
|
||||
ip address 192.168.7.1/26
|
||||
ipv6 address fc00:0:0:7::1/64
|
||||
no link-detect
|
||||
!
|
||||
interface r1-eth8
|
||||
description to sw8 - BGP IPv6 interface
|
||||
ip address 192.168.8.1/26
|
||||
ipv6 address fc00:0:0:8::1/64
|
||||
no link-detect
|
||||
!
|
||||
interface r1-eth9
|
||||
description to sw9 - LDP interface
|
||||
ip address 192.168.9.1/26
|
||||
ipv6 address fc00:0:0:9::1/64
|
||||
|
||||
no link-detect
|
||||
!
|
||||
!
|
||||
ip forwarding
|
||||
ipv6 forwarding
|
||||
!
|
||||
!
|
||||
line vty
|
||||
!
|
||||
|
||||
@ -0,0 +1,61 @@
|
||||
## GraphViz file for test_all_protocol_startup
|
||||
##
|
||||
## Color coding:
|
||||
#########################
|
||||
## Main FRR: #f08080 red
|
||||
## No protocol: #d0e0d0 gray
|
||||
## RIP: #19e3d9 Cyan
|
||||
## RIPng: #fcb314 dark yellow
|
||||
## OSPFv2: #32b835 Green
|
||||
## OSPFv3: #19e3d9 Cyan
|
||||
## ISIS IPv4 #33ff99 light green
|
||||
## ISIS IPv6 #9a81ec purple
|
||||
## BGP IPv4 #eee3d3 beige
|
||||
## BGP IPv6 #fdff00 yellow
|
||||
## LDP IPv4 #fedbe2 light pink
|
||||
##### Colors (see http://www.color-hex.com/)
|
||||
|
||||
graph test_all_protocol_startup {
|
||||
|
||||
// title
|
||||
labelloc="t";
|
||||
label="Test Topologoy All Protocols Startup";
|
||||
|
||||
######################
|
||||
# Routers
|
||||
######################
|
||||
|
||||
# Main FRR Router with all protocols
|
||||
R1 [shape=doubleoctagon, label="R1 FRR\nMain Router", fillcolor="#f08080", style=filled];
|
||||
|
||||
######################
|
||||
# Network Lists
|
||||
######################
|
||||
|
||||
SW0_STUB [label="SW0 (no protocol)\n192.168.1.0/24\nfc00:0:0:0::/64", fillcolor="#d0e0d0", style=filled];
|
||||
|
||||
SW1_RIP [label="SW1 RIP\n192.168.1.0/24\nfc00:0:0:1::/64", fillcolor="#19e3d9", style=filled];
|
||||
SW2_RIPNG [label="SW2 RIPng\n192.168.2.0/24\nfc00:0:0:2::/64", fillcolor="#fcb314", style=filled];
|
||||
SW3_OSPF [label="SW3 OSPFv2\n192.168.3.0/24\nfc00:0:0:3::/64", fillcolor="#32b835", style=filled];
|
||||
SW4_OSPFV3 [label="SW4 OSPFv3\n192.168.4.0/24\nfc00:0:0:4::/64", fillcolor="#19e3d9", style=filled];
|
||||
SW5_ISIS_V4 [label="SW5 ISIS IPv4\n192.168.5.0/24\nfc00:0:0:5::/64", fillcolor="#33ff99", style=filled];
|
||||
SW6_ISIS_V6 [label="SW6 ISIS IPv6\n192.168.6.0/24\nfc00:0:0:6::/64", fillcolor="#9a81ec", style=filled];
|
||||
SW7_BGP_V4 [label="SW7 BGP IPv4\n192.168.7.0/24\nfc00:0:0:7::/64", fillcolor="#eee3d3", style=filled];
|
||||
SW8_BGP_V6 [label="SW8 BGP IPv6\n192.168.8.0/24\nfc00:0:0:8::/64", fillcolor="#fdff00", style=filled];
|
||||
SW9_LDP [label="SW9 LDP\n192.168.9.0/24\nfc00:0:0:9::/64", fillcolor="#fedbe2", style=filled];
|
||||
|
||||
######################
|
||||
# Network Connections
|
||||
######################
|
||||
R1 -- SW0_STUB [label = "eth0\n.1\n::1"];
|
||||
R1 -- SW1_RIP [label = "eth1\n.1\n::1"];
|
||||
R1 -- SW2_RIPNG [label = "eth2\n.1\n::1"];
|
||||
R1 -- SW3_OSPF [label = "eth3\n.1\n::1"];
|
||||
R1 -- SW4_OSPFV3 [label = "eth4\n.1\n::1"];
|
||||
R1 -- SW5_ISIS_V4 [label = "eth5\n.1\n::1"];
|
||||
R1 -- SW6_ISIS_V6 [label = "eth6\n.1\n::1"];
|
||||
R1 -- SW7_BGP_V4 [label = "eth7\n.1\n::1"];
|
||||
R1 -- SW8_BGP_V6 [label = "eth8\n.1\n::1"];
|
||||
R1 -- SW9_LDP [label = "eth9\n.1\n::1"];
|
||||
|
||||
}
|
||||
Binary file not shown.
785
tests/topotests/all-protocol-startup/test_all_protocol_startup.py
Executable file
785
tests/topotests/all-protocol-startup/test_all_protocol_startup.py
Executable file
@ -0,0 +1,785 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
#
|
||||
# test_all_protocol_startup.py
|
||||
# Part of NetDEF Topology Tests
|
||||
#
|
||||
# Copyright (c) 2017 by
|
||||
# Network Device Education Foundation, Inc. ("NetDEF")
|
||||
#
|
||||
# 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_all_protocol_startup.py: Test of all protocols at same time
|
||||
|
||||
"""
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import difflib
|
||||
import pytest
|
||||
from time import sleep
|
||||
|
||||
from mininet.topo import Topo
|
||||
from mininet.net import Mininet
|
||||
from mininet.node import Node, OVSSwitch, Host
|
||||
from mininet.log import setLogLevel, info
|
||||
from mininet.cli import CLI
|
||||
from mininet.link import Intf
|
||||
|
||||
from functools import partial
|
||||
|
||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
from lib import topotest
|
||||
|
||||
fatal_error = ""
|
||||
|
||||
|
||||
#####################################################
|
||||
##
|
||||
## Network Topology Definition
|
||||
##
|
||||
#####################################################
|
||||
|
||||
class NetworkTopo(Topo):
|
||||
"All Protocol Startup Test"
|
||||
|
||||
def build(self, **_opts):
|
||||
|
||||
# Setup Routers
|
||||
router = {}
|
||||
#
|
||||
# Setup Main Router
|
||||
router[1] = topotest.addRouter(self, 'r1')
|
||||
#
|
||||
|
||||
# Setup Switches
|
||||
switch = {}
|
||||
#
|
||||
for i in range(0, 10):
|
||||
switch[i] = self.addSwitch('sw%s' % i, cls=topotest.LegacySwitch)
|
||||
self.addLink(switch[i], router[1], intfName2='r1-eth%s' % i )
|
||||
|
||||
|
||||
#####################################################
|
||||
##
|
||||
## Tests starting
|
||||
##
|
||||
#####################################################
|
||||
|
||||
def setup_module(module):
|
||||
global topo, net
|
||||
global fatal_error
|
||||
|
||||
print("\n\n** %s: Setup Topology" % module.__name__)
|
||||
print("******************************************\n")
|
||||
|
||||
print("Cleanup old Mininet runs")
|
||||
os.system('sudo mn -c > /dev/null 2>&1')
|
||||
os.system('sudo rm /tmp/r* > /dev/null 2>&1')
|
||||
|
||||
thisDir = os.path.dirname(os.path.realpath(__file__))
|
||||
topo = NetworkTopo()
|
||||
|
||||
net = Mininet(controller=None, topo=topo)
|
||||
net.start()
|
||||
|
||||
if net['r1'].get_routertype() != 'frr':
|
||||
fatal_error = "Test is only implemented for FRR"
|
||||
sys.stderr.write('\n\nTest is only implemented for FRR - Skipping\n\n')
|
||||
pytest.skip(fatal_error)
|
||||
|
||||
# Starting Routers
|
||||
#
|
||||
# Main router
|
||||
for i in range(1, 2):
|
||||
net['r%s' % i].loadConf('zebra', '%s/r%s/zebra.conf' % (thisDir, i))
|
||||
net['r%s' % i].loadConf('ripd', '%s/r%s/ripd.conf' % (thisDir, i))
|
||||
net['r%s' % i].loadConf('ripngd', '%s/r%s/ripngd.conf' % (thisDir, i))
|
||||
net['r%s' % i].loadConf('ospfd', '%s/r%s/ospfd.conf' % (thisDir, i))
|
||||
net['r%s' % i].loadConf('ospf6d', '%s/r%s/ospf6d.conf' % (thisDir, i))
|
||||
net['r%s' % i].loadConf('isisd', '%s/r%s/isisd.conf' % (thisDir, i))
|
||||
net['r%s' % i].loadConf('bgpd', '%s/r%s/bgpd.conf' % (thisDir, i))
|
||||
if net['r%s' % i].daemon_available('ldpd'):
|
||||
# Only test LDPd if it's installed and Kernel >= 4.5
|
||||
net['r%s' % i].loadConf('ldpd', '%s/r%s/ldpd.conf' % (thisDir, i))
|
||||
net['r%s' % i].startRouter()
|
||||
|
||||
# For debugging after starting Quagga/FRR daemons, uncomment the next line
|
||||
# CLI(net)
|
||||
|
||||
|
||||
def teardown_module(module):
|
||||
global net
|
||||
|
||||
print("\n\n** %s: Shutdown Topology" % module.__name__)
|
||||
print("******************************************\n")
|
||||
|
||||
# End - Shutdown network
|
||||
net.stop()
|
||||
|
||||
|
||||
def test_router_running():
|
||||
global fatal_error
|
||||
global net
|
||||
|
||||
# Skip if previous fatal error condition is raised
|
||||
if (fatal_error != ""):
|
||||
pytest.skip(fatal_error)
|
||||
|
||||
print("\n\n** Check if FRR/Quagga is running on each Router node")
|
||||
print("******************************************\n")
|
||||
sleep(5)
|
||||
|
||||
# Starting Routers
|
||||
for i in range(1, 2):
|
||||
fatal_error = net['r%s' % i].checkRouterRunning()
|
||||
assert fatal_error == "", fatal_error
|
||||
|
||||
# For debugging after starting FRR/Quagga daemons, uncomment the next line
|
||||
# CLI(net)
|
||||
|
||||
|
||||
def test_error_messages_vtysh():
|
||||
global fatal_error
|
||||
global net
|
||||
|
||||
# Skip if previous fatal error condition is raised
|
||||
if (fatal_error != ""):
|
||||
pytest.skip(fatal_error)
|
||||
|
||||
print("\n\n** Check for error messages on VTYSH")
|
||||
print("******************************************\n")
|
||||
|
||||
failures = 0
|
||||
for i in range(1, 2):
|
||||
#
|
||||
# First checking Standard Output
|
||||
#
|
||||
|
||||
# VTYSH output from router
|
||||
vtystdout = net['r%s' % i].cmd('vtysh -c "show version" 2> /dev/null').rstrip()
|
||||
|
||||
# Fix newlines (make them all the same)
|
||||
vtystdout = ('\n'.join(vtystdout.splitlines()) + '\n').rstrip()
|
||||
# Drop everything starting with "FRRouting X.xx" message
|
||||
vtystdout = re.sub(r"FRRouting [0-9]+.*", "", vtystdout, flags=re.DOTALL)
|
||||
|
||||
if (vtystdout != ''):
|
||||
sys.stderr.write('\nr%s created some spurious VTYSH start StdOut messages:\n%s\n' % (i, vtystdout))
|
||||
failures += 1
|
||||
else:
|
||||
print("r%s StdOut ok" % i)
|
||||
|
||||
#
|
||||
# Second checking Standard Error
|
||||
#
|
||||
|
||||
# VTYSH StdErr output from router
|
||||
vtystderr = net['r%s' % i].cmd('vtysh -c "show version" > /dev/null').rstrip()
|
||||
|
||||
# Fix newlines (make them all the same)
|
||||
vtystderr = ('\n'.join(vtystderr.splitlines()) + '\n').rstrip()
|
||||
# # Drop everything starting with "FRRouting X.xx" message
|
||||
# vtystderr = re.sub(r"FRRouting [0-9]+.*", "", vtystderr, flags=re.DOTALL)
|
||||
|
||||
if (vtystderr != ''):
|
||||
sys.stderr.write('\nr%s created some spurious VTYSH start StdErr messages:\n<%s>\n' % (i, vtystderr))
|
||||
failures += 1
|
||||
else:
|
||||
print("r%s StdErr ok" % i)
|
||||
|
||||
assert failures == 0, "IP RIP status failed for router r%s:\n%s" % (i, diff)
|
||||
|
||||
# For debugging after starting FRR/Quagga daemons, uncomment the next line
|
||||
# CLI(net)
|
||||
|
||||
|
||||
def test_error_messages_daemons():
|
||||
global fatal_error
|
||||
global net
|
||||
|
||||
# Skip if previous fatal error condition is raised
|
||||
if (fatal_error != ""):
|
||||
pytest.skip(fatal_error)
|
||||
|
||||
print("\n\n** Check for error messages in daemons")
|
||||
print("******************************************\n")
|
||||
|
||||
error_logs = ""
|
||||
|
||||
for i in range(1, 2):
|
||||
log = net['r%s' % i].getStdErr('ripd')
|
||||
if log:
|
||||
error_logs += "r%s RIPd StdErr Output:\n" % i
|
||||
error_logs += log
|
||||
log = net['r%s' % i].getStdErr('ripngd')
|
||||
if log:
|
||||
error_logs += "r%s RIPngd StdErr Output:\n" % i
|
||||
error_logs += log
|
||||
log = net['r%s' % i].getStdErr('ospfd')
|
||||
if log:
|
||||
error_logs += "r%s OSPFd StdErr Output:\n" % i
|
||||
error_logs += log
|
||||
log = net['r%s' % i].getStdErr('ospf6d')
|
||||
if log:
|
||||
error_logs += "r%s OSPF6d StdErr Output:\n" % i
|
||||
error_logs += log
|
||||
log = net['r%s' % i].getStdErr('isisd')
|
||||
# ISIS shows debugging enabled status on StdErr
|
||||
# Remove these messages
|
||||
log = re.sub(r"^IS-IS .* debugging is on.*", "", log).rstrip()
|
||||
if log:
|
||||
error_logs += "r%s ISISd StdErr Output:\n" % i
|
||||
error_logs += log
|
||||
log = net['r%s' % i].getStdErr('bgpd')
|
||||
if log:
|
||||
error_logs += "r%s BGPd StdErr Output:\n" % i
|
||||
error_logs += log
|
||||
if (net['r%s' % i].daemon_available('ldpd')):
|
||||
log = net['r%s' % i].getStdErr('ldpd')
|
||||
if log:
|
||||
error_logs += "r%s LDPd StdErr Output:\n" % i
|
||||
error_logs += log
|
||||
log = net['r%s' % i].getStdErr('zebra')
|
||||
if log:
|
||||
error_logs += "r%s Zebra StdErr Output:\n"
|
||||
error_logs += log
|
||||
|
||||
if error_logs:
|
||||
sys.stderr.write('Failed check for StdErr Output on daemons:\n%s\n' % error_logs)
|
||||
|
||||
assert error_logs == "", "Daemons report errors to StdErr"
|
||||
|
||||
# For debugging after starting FRR/Quagga daemons, uncomment the next line
|
||||
# CLI(net)
|
||||
|
||||
|
||||
def test_converge_protocols():
|
||||
global fatal_error
|
||||
global net
|
||||
|
||||
# Skip if previous fatal error condition is raised
|
||||
if (fatal_error != ""):
|
||||
pytest.skip(fatal_error)
|
||||
|
||||
thisDir = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
print("\n\n** Waiting for protocols convergence")
|
||||
print("******************************************\n")
|
||||
|
||||
# Not really implemented yet - just sleep 60 secs for now
|
||||
sleep(60)
|
||||
|
||||
# For debugging after starting FRR/Quagga daemons, uncomment the next line
|
||||
## CLI(net)
|
||||
|
||||
|
||||
def test_rip_status():
|
||||
global fatal_error
|
||||
global net
|
||||
|
||||
# Skip if previous fatal error condition is raised
|
||||
if (fatal_error != ""):
|
||||
pytest.skip(fatal_error)
|
||||
|
||||
thisDir = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
# Verify RIP Status
|
||||
print("\n\n** Verifing RIP status")
|
||||
print("******************************************\n")
|
||||
failures = 0
|
||||
for i in range(1, 2):
|
||||
refTableFile = '%s/r%s/rip_status.ref' % (thisDir, i)
|
||||
if os.path.isfile(refTableFile):
|
||||
# Read expected result from file
|
||||
expected = open(refTableFile).read().rstrip()
|
||||
# Fix newlines (make them all the same)
|
||||
expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
|
||||
|
||||
# Actual output from router
|
||||
actual = net['r%s' % i].cmd('vtysh -c "show ip rip status" 2> /dev/null').rstrip()
|
||||
# Drop time in next due
|
||||
actual = re.sub(r"in [0-9]+ seconds", "in XX seconds", actual)
|
||||
# Drop time in last update
|
||||
actual = re.sub(r" [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", " XX:XX:XX", actual)
|
||||
# Fix newlines (make them all the same)
|
||||
actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
|
||||
|
||||
# Generate Diff
|
||||
diff = ''.join(difflib.context_diff(actual, expected,
|
||||
fromfile="actual IP RIP status",
|
||||
tofile="expected IP RIP status"))
|
||||
|
||||
# Empty string if it matches, otherwise diff contains unified diff
|
||||
if diff:
|
||||
sys.stderr.write('r%s failed IP RIP status check:\n%s\n' % (i, diff))
|
||||
failures += 1
|
||||
else:
|
||||
print("r%s ok" % i)
|
||||
|
||||
assert failures == 0, "IP RIP status failed for router r%s:\n%s" % (i, diff)
|
||||
|
||||
# For debugging after starting FRR/Quagga daemons, uncomment the next line
|
||||
# CLI(net)
|
||||
|
||||
|
||||
def test_ripng_status():
|
||||
global fatal_error
|
||||
global net
|
||||
|
||||
# Skip if previous fatal error condition is raised
|
||||
if (fatal_error != ""):
|
||||
pytest.skip(fatal_error)
|
||||
|
||||
thisDir = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
# Verify RIP Status
|
||||
print("\n\n** Verifing RIPng status")
|
||||
print("******************************************\n")
|
||||
failures = 0
|
||||
for i in range(1, 2):
|
||||
refTableFile = '%s/r%s/ripng_status.ref' % (thisDir, i)
|
||||
if os.path.isfile(refTableFile):
|
||||
# Read expected result from file
|
||||
expected = open(refTableFile).read().rstrip()
|
||||
# Fix newlines (make them all the same)
|
||||
expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
|
||||
|
||||
# Actual output from router
|
||||
actual = net['r%s' % i].cmd('vtysh -c "show ipv6 ripng status" 2> /dev/null').rstrip()
|
||||
# Mask out Link-Local mac address portion. They are random...
|
||||
actual = re.sub(r" fe80::[0-9a-f:]+", " fe80::XXXX:XXXX:XXXX:XXXX", actual)
|
||||
# Drop time in next due
|
||||
actual = re.sub(r"in [0-9]+ seconds", "in XX seconds", actual)
|
||||
# Drop time in last update
|
||||
actual = re.sub(r" [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", " XX:XX:XX", actual)
|
||||
# Fix newlines (make them all the same)
|
||||
actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
|
||||
|
||||
# Generate Diff
|
||||
diff = ''.join(difflib.context_diff(actual, expected,
|
||||
fromfile="actual IPv6 RIPng status",
|
||||
tofile="expected IPv6 RIPng status"))
|
||||
|
||||
# Empty string if it matches, otherwise diff contains unified diff
|
||||
if diff:
|
||||
sys.stderr.write('r%s failed IPv6 RIPng status check:\n%s\n' % (i, diff))
|
||||
failures += 1
|
||||
else:
|
||||
print("r%s ok" % i)
|
||||
|
||||
assert failures == 0, "IPv6 RIPng status failed for router r%s:\n%s" % (i, diff)
|
||||
|
||||
# For debugging after starting FRR/Quagga daemons, uncomment the next line
|
||||
# CLI(net)
|
||||
|
||||
|
||||
def test_ospfv2_interfaces():
|
||||
global fatal_error
|
||||
global net
|
||||
|
||||
# Skip if previous fatal error condition is raised
|
||||
if (fatal_error != ""):
|
||||
pytest.skip(fatal_error)
|
||||
|
||||
thisDir = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
# Verify RIP Status
|
||||
print("\n\n** Verifing OSPFv2 interfaces")
|
||||
print("******************************************\n")
|
||||
failures = 0
|
||||
for i in range(1, 2):
|
||||
refTableFile = '%s/r%s/show_ip_ospf_interface.ref' % (thisDir, i)
|
||||
if os.path.isfile(refTableFile):
|
||||
# Read expected result from file
|
||||
expected = open(refTableFile).read().rstrip()
|
||||
# Fix newlines (make them all the same)
|
||||
expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
|
||||
|
||||
# Actual output from router
|
||||
actual = net['r%s' % i].cmd('vtysh -c "show ip ospf interface" 2> /dev/null').rstrip()
|
||||
# Mask out Bandwidth portion. They may change..
|
||||
actual = re.sub(r"BW [0-9]+ Mbit", "BW XX Mbit", actual)
|
||||
# Drop time in next due
|
||||
actual = re.sub(r"Hello due in [0-9\.]+s", "Hello due in XX.XXXs", actual)
|
||||
# Fix newlines (make them all the same)
|
||||
actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
|
||||
|
||||
# Generate Diff
|
||||
diff = ''.join(difflib.context_diff(actual, expected,
|
||||
fromfile="actual SHOW IP OSPF INTERFACE",
|
||||
tofile="expected SHOW IP OSPF INTERFACE"))
|
||||
|
||||
# Empty string if it matches, otherwise diff contains unified diff
|
||||
if diff:
|
||||
sys.stderr.write('r%s failed SHOW IP OSPF INTERFACE check:\n%s\n' % (i, diff))
|
||||
failures += 1
|
||||
else:
|
||||
print("r%s ok" % i)
|
||||
|
||||
assert failures == 0, "SHOW IP OSPF INTERFACE failed for router r%s:\n%s" % (i, diff)
|
||||
|
||||
# For debugging after starting FRR/Quagga daemons, uncomment the next line
|
||||
# CLI(net)
|
||||
|
||||
|
||||
def test_isis_interfaces():
|
||||
global fatal_error
|
||||
global net
|
||||
|
||||
# Skip if previous fatal error condition is raised
|
||||
if (fatal_error != ""):
|
||||
pytest.skip(fatal_error)
|
||||
|
||||
thisDir = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
# Verify RIP Status
|
||||
print("\n\n** Verifing ISIS interfaces")
|
||||
print("******************************************\n")
|
||||
failures = 0
|
||||
for i in range(1, 2):
|
||||
refTableFile = '%s/r%s/show_isis_interface_detail.ref' % (thisDir, i)
|
||||
if os.path.isfile(refTableFile):
|
||||
# Read expected result from file
|
||||
expected = open(refTableFile).read().rstrip()
|
||||
# Fix newlines (make them all the same)
|
||||
expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
|
||||
|
||||
# Actual output from router
|
||||
actual = net['r%s' % i].cmd('vtysh -c "show isis interface detail" 2> /dev/null').rstrip()
|
||||
# Mask out Link-Local mac address portion. They are random...
|
||||
actual = re.sub(r"fe80::[0-9a-f:]+", "fe80::XXXX:XXXX:XXXX:XXXX", actual)
|
||||
# Mask out SNPA mac address portion. They are random...
|
||||
actual = re.sub(r"SNPA: [0-9a-f\.]+", "SNPA: XXXX.XXXX.XXXX", actual)
|
||||
# Fix newlines (make them all the same)
|
||||
actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
|
||||
|
||||
# Generate Diff
|
||||
diff = ''.join(difflib.context_diff(actual, expected,
|
||||
fromfile="actual SHOW ISIS INTERFACE DETAIL",
|
||||
tofile="expected SHOW ISIS OSPF6 INTERFACE DETAIL"))
|
||||
|
||||
# Empty string if it matches, otherwise diff contains unified diff
|
||||
if diff:
|
||||
sys.stderr.write('r%s failed SHOW ISIS INTERFACE DETAIL check:\n%s\n' % (i, diff))
|
||||
failures += 1
|
||||
else:
|
||||
print("r%s ok" % i)
|
||||
|
||||
assert failures == 0, "SHOW ISIS INTERFACE DETAIL failed for router r%s:\n%s" % (i, diff)
|
||||
|
||||
# For debugging after starting FRR/Quagga daemons, uncomment the next line
|
||||
# CLI(net)
|
||||
|
||||
|
||||
def test_bgp_summary():
|
||||
global fatal_error
|
||||
global net
|
||||
|
||||
# Skip if previous fatal error condition is raised
|
||||
if (fatal_error != ""):
|
||||
pytest.skip(fatal_error)
|
||||
|
||||
thisDir = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
# Verify RIP Status
|
||||
print("\n\n** Verifing BGP Summary")
|
||||
print("******************************************\n")
|
||||
failures = 0
|
||||
for i in range(1, 2):
|
||||
refTableFile = '%s/r%s/show_bgp_summary.ref' % (thisDir, i)
|
||||
if os.path.isfile(refTableFile):
|
||||
# Read expected result from file
|
||||
expected = open(refTableFile).read().rstrip()
|
||||
# Fix newlines (make them all the same)
|
||||
expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
|
||||
|
||||
# Actual output from router
|
||||
actual = net['r%s' % i].cmd('vtysh -c "show bgp summary" 2> /dev/null').rstrip()
|
||||
# Mask out "using XXiXX bytes" portion. They are random...
|
||||
actual = re.sub(r"using [0-9]+ bytes", "using XXXX bytes", actual)
|
||||
# Mask out "using XiXXX KiB" portion. They are random...
|
||||
actual = re.sub(r"using [0-9]+ KiB", "using XXXX KiB", actual)
|
||||
# Fix newlines (make them all the same)
|
||||
actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
|
||||
|
||||
# Generate Diff
|
||||
diff = ''.join(difflib.context_diff(actual, expected,
|
||||
fromfile="actual SHOW BGP SUMMARY",
|
||||
tofile="expected SHOW BGP SUMMARY"))
|
||||
|
||||
# Empty string if it matches, otherwise diff contains unified diff
|
||||
if diff:
|
||||
sys.stderr.write('r%s failed SHOW BGP SUMMARY check:\n%s\n' % (i, diff))
|
||||
failures += 1
|
||||
else:
|
||||
print("r%s ok" % i)
|
||||
|
||||
assert failures == 0, "SHOW SHOW BGP SUMMARY failed for router r%s:\n%s" % (i, diff)
|
||||
|
||||
# For debugging after starting FRR/Quagga daemons, uncomment the next line
|
||||
# CLI(net)
|
||||
|
||||
|
||||
def test_bgp_ipv6_summary():
|
||||
global fatal_error
|
||||
global net
|
||||
|
||||
# Skip if previous fatal error condition is raised
|
||||
if (fatal_error != ""):
|
||||
pytest.skip(fatal_error)
|
||||
|
||||
thisDir = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
# Verify RIP Status
|
||||
print("\n\n** Verifing BGP IPv6 Summary")
|
||||
print("******************************************\n")
|
||||
failures = 0
|
||||
for i in range(1, 2):
|
||||
refTableFile = '%s/r%s/show_bgp_ipv6_summary.ref' % (thisDir, i)
|
||||
if os.path.isfile(refTableFile):
|
||||
# Read expected result from file
|
||||
expected = open(refTableFile).read().rstrip()
|
||||
# Fix newlines (make them all the same)
|
||||
expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
|
||||
|
||||
# Actual output from router
|
||||
actual = net['r%s' % i].cmd('vtysh -c "show bgp ipv6 summary" 2> /dev/null').rstrip()
|
||||
# Mask out "using XXiXX bytes" portion. They are random...
|
||||
actual = re.sub(r"using [0-9]+ bytes", "using XXXX bytes", actual)
|
||||
# Mask out "using XiXXX KiB" portion. They are random...
|
||||
actual = re.sub(r"using [0-9]+ KiB", "using XXXX KiB", actual)
|
||||
# Fix newlines (make them all the same)
|
||||
actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
|
||||
|
||||
# Generate Diff
|
||||
diff = ''.join(difflib.context_diff(actual, expected,
|
||||
fromfile="actual SHOW BGP IPv6 SUMMARY",
|
||||
tofile="expected SHOW BGP IPv6 SUMMARY"))
|
||||
|
||||
# Empty string if it matches, otherwise diff contains unified diff
|
||||
if diff:
|
||||
sys.stderr.write('r%s failed SHOW BGP IPv6 SUMMARY check:\n%s\n' % (i, diff))
|
||||
failures += 1
|
||||
else:
|
||||
print("r%s ok" % i)
|
||||
|
||||
assert failures == 0, "SHOW BGP IPv6 SUMMARY failed for router r%s:\n%s" % (i, diff)
|
||||
|
||||
# For debugging after starting FRR/Quagga daemons, uncomment the next line
|
||||
# CLI(net)
|
||||
|
||||
|
||||
def test_bgp_ipv4():
|
||||
global fatal_error
|
||||
global net
|
||||
|
||||
# Skip if previous fatal error condition is raised
|
||||
if (fatal_error != ""):
|
||||
pytest.skip(fatal_error)
|
||||
|
||||
thisDir = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
# Verify RIP Status
|
||||
print("\n\n** Verifing BGP IPv4")
|
||||
print("******************************************\n")
|
||||
failures = 0
|
||||
for i in range(1, 2):
|
||||
refTableFile = '%s/r%s/show_bgp_ipv4.ref' % (thisDir, i)
|
||||
if os.path.isfile(refTableFile):
|
||||
# Read expected result from file
|
||||
expected = open(refTableFile).read().rstrip()
|
||||
# Fix newlines (make them all the same)
|
||||
expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
|
||||
|
||||
# Actual output from router
|
||||
actual = net['r%s' % i].cmd('vtysh -c "show bgp ipv4" 2> /dev/null').rstrip()
|
||||
# Remove summary line (changed recently)
|
||||
actual = re.sub(r'Total number.*', '', actual)
|
||||
actual = re.sub(r'Displayed.*', '', actual)
|
||||
actual = actual.rstrip()
|
||||
# Fix newlines (make them all the same)
|
||||
actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
|
||||
|
||||
# Generate Diff
|
||||
diff = ''.join(difflib.context_diff(actual, expected,
|
||||
fromfile="actual SHOW BGP IPv4",
|
||||
tofile="expected SHOW BGP IPv4"))
|
||||
|
||||
# Empty string if it matches, otherwise diff contains unified diff
|
||||
if diff:
|
||||
sys.stderr.write('r%s failed SHOW BGP IPv4 check:\n%s\n' % (i, diff))
|
||||
failures += 1
|
||||
else:
|
||||
print("r%s ok" % i)
|
||||
|
||||
assert failures == 0, "SHOW BGP IPv4 failed for router r%s:\n%s" % (i, diff)
|
||||
|
||||
# For debugging after starting FRR/Quagga daemons, uncomment the next line
|
||||
# CLI(net)
|
||||
|
||||
|
||||
def test_bgp_ipv6():
|
||||
global fatal_error
|
||||
global net
|
||||
|
||||
# Skip if previous fatal error condition is raised
|
||||
if (fatal_error != ""):
|
||||
pytest.skip(fatal_error)
|
||||
|
||||
thisDir = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
# Verify RIP Status
|
||||
print("\n\n** Verifing BGP IPv6")
|
||||
print("******************************************\n")
|
||||
failures = 0
|
||||
for i in range(1, 2):
|
||||
refTableFile = '%s/r%s/show_bgp_ipv6.ref' % (thisDir, i)
|
||||
if os.path.isfile(refTableFile):
|
||||
# Read expected result from file
|
||||
expected = open(refTableFile).read().rstrip()
|
||||
# Fix newlines (make them all the same)
|
||||
expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
|
||||
|
||||
# Actual output from router
|
||||
actual = net['r%s' % i].cmd('vtysh -c "show bgp ipv6" 2> /dev/null').rstrip()
|
||||
# Remove summary line (changed recently)
|
||||
actual = re.sub(r'Total number.*', '', actual)
|
||||
actual = re.sub(r'Displayed.*', '', actual)
|
||||
actual = actual.rstrip()
|
||||
# Fix newlines (make them all the same)
|
||||
actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
|
||||
|
||||
# Generate Diff
|
||||
diff = ''.join(difflib.context_diff(actual, expected,
|
||||
fromfile="actual SHOW BGP IPv6",
|
||||
tofile="expected SHOW BGP IPv6"))
|
||||
|
||||
# Empty string if it matches, otherwise diff contains unified diff
|
||||
if diff:
|
||||
sys.stderr.write('r%s failed SHOW BGP IPv6 check:\n%s\n' % (i, diff))
|
||||
failures += 1
|
||||
else:
|
||||
print("r%s ok" % i)
|
||||
|
||||
assert failures == 0, "SHOW BGP IPv6 failed for router r%s:\n%s" % (i, diff)
|
||||
|
||||
# For debugging after starting FRR/Quagga daemons, uncomment the next line
|
||||
# CLI(net)
|
||||
|
||||
|
||||
|
||||
def test_mpls_interfaces():
|
||||
global fatal_error
|
||||
global net
|
||||
|
||||
# Skip if previous fatal error condition is raised
|
||||
if (fatal_error != ""):
|
||||
pytest.skip(fatal_error)
|
||||
|
||||
# Skip if no LDP installed or old kernel
|
||||
if (net['r1'].daemon_available('ldpd') == False):
|
||||
pytest.skip("No MPLS or kernel < 4.5")
|
||||
|
||||
thisDir = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
# Verify OSPFv3 Routing Table
|
||||
print("\n\n** Verifing MPLS Interfaces")
|
||||
print("******************************************\n")
|
||||
failures = 0
|
||||
for i in range(1, 2):
|
||||
refTableFile = '%s/r%s/show_mpls_ldp_interface.ref' % (thisDir, i)
|
||||
if os.path.isfile(refTableFile):
|
||||
# Read expected result from file
|
||||
expected = open(refTableFile).read().rstrip()
|
||||
# Fix newlines (make them all the same)
|
||||
expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
|
||||
|
||||
# Actual output from router
|
||||
actual = net['r%s' % i].cmd('vtysh -c "show mpls ldp interface" 2> /dev/null').rstrip()
|
||||
# Mask out Timer in Uptime
|
||||
actual = re.sub(r" [0-9][0-9]:[0-9][0-9]:[0-9][0-9] ", " xx:xx:xx ", actual)
|
||||
# Fix newlines (make them all the same)
|
||||
actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
|
||||
|
||||
# Generate Diff
|
||||
diff = ''.join(difflib.context_diff(actual, expected,
|
||||
fromfile="actual MPLS LDP interface status",
|
||||
tofile="expected MPLS LDP interface status"))
|
||||
|
||||
# Empty string if it matches, otherwise diff contains unified diff
|
||||
if diff:
|
||||
sys.stderr.write('r%s failed MPLS LDP Interface status Check:\n%s\n' % (i, diff))
|
||||
failures += 1
|
||||
else:
|
||||
print("r%s ok" % i)
|
||||
|
||||
if failures>0:
|
||||
fatal_error = "MPLS LDP Interface status failed"
|
||||
|
||||
assert failures == 0, "MPLS LDP Interface status failed for router r%s:\n%s" % (i, diff)
|
||||
|
||||
# For debugging after starting FRR/Quagga daemons, uncomment the next line
|
||||
# CLI(net)
|
||||
|
||||
|
||||
def test_shutdown_check_stderr():
|
||||
global fatal_error
|
||||
global net
|
||||
|
||||
# Skip if previous fatal error condition is raised
|
||||
if (fatal_error != ""):
|
||||
pytest.skip(fatal_error)
|
||||
|
||||
print("\n\n** Verifing unexpected STDERR output from daemons")
|
||||
print("******************************************\n")
|
||||
|
||||
if os.environ.get('TOPOTESTS_CHECK_STDERR') is None:
|
||||
print("SKIPPED (Disabled) - TOPOTESTS_CHECK_STDERR undefined\n")
|
||||
pytest.skip('Skipping test for Stderr output and memory leaks')
|
||||
|
||||
thisDir = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
net['r1'].stopRouter()
|
||||
|
||||
log = net['r1'].getStdErr('ripd')
|
||||
print("\nRIPd StdErr Log:\n" + log)
|
||||
log = net['r1'].getStdErr('ripngd')
|
||||
print("\nRIPngd StdErr Log:\n" + log)
|
||||
log = net['r1'].getStdErr('ospfd')
|
||||
print("\nOSPFd StdErr Log:\n" + log)
|
||||
log = net['r1'].getStdErr('ospf6d')
|
||||
print("\nOSPF6d StdErr Log:\n" + log)
|
||||
log = net['r1'].getStdErr('isisd')
|
||||
print("\nISISd StdErr Log:\n" + log)
|
||||
log = net['r1'].getStdErr('bgpd')
|
||||
print("\nBGPd StdErr Log:\n" + log)
|
||||
if (net['r1'].daemon_available('ldpd')):
|
||||
log = net['r1'].getStdErr('ldpd')
|
||||
print("\nLDPd StdErr Log:\n" + log)
|
||||
log = net['r1'].getStdErr('zebra')
|
||||
print("\nZebra StdErr Log:\n" + log)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
setLogLevel('info')
|
||||
# To suppress tracebacks, either use the following pytest call or add "--tb=no" to cli
|
||||
# retval = pytest.main(["-s", "--tb=no"])
|
||||
retval = pytest.main(["-s"])
|
||||
sys.exit(retval)
|
||||
Loading…
Reference in New Issue
Block a user