Skip to content

Commit

Permalink
test: bridge_stp_basic: Add
Browse files Browse the repository at this point in the history
  • Loading branch information
wkz committed Dec 20, 2024
1 parent cd26044 commit b93f2d6
Show file tree
Hide file tree
Showing 6 changed files with 348 additions and 1 deletion.
3 changes: 2 additions & 1 deletion test/case/ietf_interfaces/Readme.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ include::bridge_fwd_dual_dut/Readme.adoc[]

include::bridge_fwd_sgl_dut/Readme.adoc[]

include::bridge_stp_basic/Readme.adoc[]

include::bridge_veth/Readme.adoc[]

include::bridge_vlan/Readme.adoc[]
Expand All @@ -46,4 +48,3 @@ include::iface_enable_disable/Readme.adoc[]
include::veth_delete/Readme.adoc[]

include::vlan_iface_termination/Readme.adoc[]

31 changes: 31 additions & 0 deletions test/case/ietf_interfaces/bridge_stp_basic/Readme.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
=== Bridge STP Basic
==== Description
Verify that a fully connected mesh of 4 DUTs is pruned to a spanning
tree.

Since the mesh contains 3 redundant paths, can infer that a spanning
tree has been created if all host interfaces can reach each other
while exactly three links are in the blocking state.

==== Topology
ifdef::topdoc[]
image::../../test/case/ietf_interfaces/bridge_stp_basic/topology.svg[Bridge STP Basic topology]
endif::topdoc[]
ifndef::topdoc[]
ifdef::testgroup[]
image::bridge_stp_basic/topology.svg[Bridge STP Basic topology]
endif::testgroup[]
ifndef::testgroup[]
image::topology.svg[Bridge STP Basic topology]
endif::testgroup[]
endif::topdoc[]
==== Test sequence
. Set up topology and attach to target DUT
. Configure a bridge with spanning tree eneabled on dut a, b, c, and d
. Add an IP address to each host interface in the 10.0.0.0/24 subnet
. Verify that exactly three links are blocking
. Verify that host:a can reach host:{b,c,d}


<<<

89 changes: 89 additions & 0 deletions test/case/ietf_interfaces/bridge_stp_basic/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#!/usr/bin/env python3
r"""Bridge STP Basic
Verify that a fully connected mesh of 4 DUTs is pruned to a spanning
tree.
Since the mesh contains 3 redundant paths, can infer that a spanning
tree has been created if all host interfaces can reach each other
while exactly three links are in the blocking state.
"""
import infamy
from infamy.util import parallel, until

def addbr(dut):
ip = {
"A": "10.0.0.101",
"B": "10.0.0.102",
"C": "10.0.0.103",
"D": "10.0.0.104"
}[dut.name]

brports = [
{
"name": dut[n],
"infix-interfaces:bridge-port": {
"bridge": "br0",
}
} for n in ("a", "b", "c", "d", "h") if n != dut.name.lower()
]

dut.put_config_dicts({
"ietf-interfaces": {
"interfaces": {
"interface": [
{
"name": "br0",
"type": "infix-if-type:bridge",
"enabled": True,
"bridge": {
"stp": {},
},
"ipv4": {
"address": [
{
"ip": ip,
"prefix-length": 24,
}
]
},
}
] + brports,
}
}
})

def num_blocking(dut):
num = 0
for iface in dut.get_data("/ietf-interfaces:interfaces")["interfaces"]["interface"]:
if iface.get("bridge-port", {}).get("stp-state") == "blocking":
num += 1

return num

with infamy.Test() as test:
with test.step("Set up topology and attach to target DUT"):
env = infamy.Env()
a, b, c, d = parallel(lambda: env.attach("A"), lambda: env.attach("B"),
lambda: env.attach("C"), lambda: env.attach("D"))

host = { p: env.ltop.xlate("host", p)[1] for p in ("a", "b", "c", "d") }

with test.step("Configure a bridge with spanning tree eneabled on dut a, b, c, and d"):
parallel(lambda: addbr(a), lambda: addbr(b), lambda: addbr(c), lambda: addbr(d))

with test.step("Add an IP address to each host interface in the 10.0.0.0/24 subnet"):
ns = { p: infamy.IsolatedMacVlan(host[p]).start() for p in ("a", "b", "c", "d") }
parallel(lambda: ns["a"].addip("10.0.0.1"), lambda: ns["b"].addip("10.0.0.2"),
lambda: ns["c"].addip("10.0.0.3"), lambda: ns["d"].addip("10.0.0.4"))

with test.step("Verify that exactly three links are blocking"):
until(lambda: sum(map(num_blocking, (a, b, c, d))) == 3, 60)

with test.step("Verify that host:a can reach host:{b,c,d}"):
parallel(lambda: ns["a"].must_reach("10.0.0.2"),
lambda: ns["a"].must_reach("10.0.0.3"),
lambda: ns["a"].must_reach("10.0.0.4"))

test.succeed()
55 changes: 55 additions & 0 deletions test/case/ietf_interfaces/bridge_stp_basic/topology.dot
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
graph "stp" {
layout="neato";
overlap="false";
esep="+80";

node [shape=record, fontname="DejaVu Sans Mono, Book"];
edge [penwidth="2", fontname="DejaVu Serif, Book"];

host [
label="{ { <mgmtd> mgmtd | <d> d | <mgmta> mgmta | <a> a | <b> b | <mgmtb> mgmtb | <c> c | <mgmtc> mgmtc } | host }",
color="grey",fontcolor="grey",pos="9,0!",
kind="controller",
];

A [
label="{ A | { <mgmt> mgmt | <h> h } } | { <b> b | <c> c | <d> d }",
pos="6,6!",
kind="infix",
];
B [
label="{ <a> a | <d> d | <c> c } | { B | { <h> h | <mgmt> mgmt } }",
pos="12,6!",
kind="infix",
];
C [
label="{ <b> b | <a> a | <d> d } | { C | { <h> h | <mgmt> mgmt } }",
pos="12,3!",
kind="infix",
];
D [
label="{ D | { <mgmt> mgmt | <h> h } } | { <a> a | <b> b | <c> c }",
pos="6,3!",
kind="infix",
];

host:mgmta -- A:mgmt [kind=mgmt, color="lightgrey"]
host:mgmtb -- B:mgmt [kind=mgmt, color="lightgrey"]
host:mgmtc -- C:mgmt [kind=mgmt, color="lightgrey"]
host:mgmtd -- D:mgmt [kind=mgmt, color="lightgrey"]

host:a -- A:h [color="cornflowerblue"]
host:b -- B:h [color="cornflowerblue"]
host:c -- C:h [color="cornflowerblue"]
host:d -- D:h [color="cornflowerblue"]

# Ring
A:b -- B:a
B:c -- C:b
C:d -- D:c
D:a -- A:d

# Cross-links
A:c -- C:a
B:d -- D:b
}
168 changes: 168 additions & 0 deletions test/case/ietf_interfaces/bridge_stp_basic/topology.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions test/case/ietf_interfaces/ietf_interfaces.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@
- name: bridge_fwd_dual_dut
case: bridge_fwd_dual_dut/test.py

- name: bridge_stp_basic
case: bridge_stp_basic/test.py

- name: bridge_vlan_separation
case: bridge_vlan_separation/test.py

Expand Down

0 comments on commit b93f2d6

Please sign in to comment.