test: bridge_stp_basic: Add

This commit is contained in:
Tobias Waldekranz
2025-01-08 10:14:46 +01:00
parent 44b60956a8
commit 3ef40031dd
6 changed files with 348 additions and 0 deletions
+2
View File
@@ -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[]
@@ -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
View File
@@ -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()
@@ -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
}
@@ -0,0 +1,168 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- Title: stp Pages: 1 -->
<svg width="648pt" height="607pt"
viewBox="0.00 0.00 648.05 606.55" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 602.55)">
<title>stp</title>
<polygon fill="white" stroke="transparent" points="-4,4 -4,-602.55 644.05,-602.55 644.05,4 -4,4"/>
<!-- host -->
<g id="node1" class="node">
<title>host</title>
<polygon fill="none" stroke="grey" points="154.03,-0.5 154.03,-46.5 486.03,-46.5 486.03,-0.5 154.03,-0.5"/>
<text text-anchor="middle" x="183.03" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00" fill="grey">mgmtd</text>
<polyline fill="none" stroke="grey" points="212.03,-23.5 212.03,-46.5 "/>
<text text-anchor="middle" x="224.53" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00" fill="grey">d</text>
<polyline fill="none" stroke="grey" points="237.03,-23.5 237.03,-46.5 "/>
<text text-anchor="middle" x="266.03" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00" fill="grey">mgmta</text>
<polyline fill="none" stroke="grey" points="295.03,-23.5 295.03,-46.5 "/>
<text text-anchor="middle" x="307.53" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00" fill="grey">a</text>
<polyline fill="none" stroke="grey" points="320.03,-23.5 320.03,-46.5 "/>
<text text-anchor="middle" x="332.53" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00" fill="grey">b</text>
<polyline fill="none" stroke="grey" points="345.03,-23.5 345.03,-46.5 "/>
<text text-anchor="middle" x="374.03" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00" fill="grey">mgmtb</text>
<polyline fill="none" stroke="grey" points="403.03,-23.5 403.03,-46.5 "/>
<text text-anchor="middle" x="415.53" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00" fill="grey">c</text>
<polyline fill="none" stroke="grey" points="428.03,-23.5 428.03,-46.5 "/>
<text text-anchor="middle" x="457.03" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00" fill="grey">mgmtc</text>
<polyline fill="none" stroke="grey" points="154.03,-23.5 486.03,-23.5 "/>
<text text-anchor="middle" x="320.03" y="-8.3" font-family="DejaVu Sans Mono, Book" font-size="14.00" fill="grey">host</text>
</g>
<!-- A -->
<g id="node2" class="node">
<title>A</title>
<polygon fill="none" stroke="black" points="0,-529.05 0,-598.05 100,-598.05 100,-529.05 0,-529.05"/>
<text text-anchor="middle" x="37.5" y="-577.35" font-family="DejaVu Sans Mono, Book" font-size="14.00">A</text>
<polyline fill="none" stroke="black" points="0,-564.05 75,-564.05 "/>
<text text-anchor="middle" x="25" y="-542.85" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
<polyline fill="none" stroke="black" points="50,-529.05 50,-564.05 "/>
<text text-anchor="middle" x="62.5" y="-542.85" font-family="DejaVu Sans Mono, Book" font-size="14.00">h</text>
<polyline fill="none" stroke="black" points="75,-529.05 75,-598.05 "/>
<text text-anchor="middle" x="87.5" y="-582.85" font-family="DejaVu Sans Mono, Book" font-size="14.00">b</text>
<polyline fill="none" stroke="black" points="75,-575.05 100,-575.05 "/>
<text text-anchor="middle" x="87.5" y="-559.85" font-family="DejaVu Sans Mono, Book" font-size="14.00">c</text>
<polyline fill="none" stroke="black" points="75,-552.05 100,-552.05 "/>
<text text-anchor="middle" x="87.5" y="-536.85" font-family="DejaVu Sans Mono, Book" font-size="14.00">d</text>
</g>
<!-- host&#45;&#45;A -->
<g id="edge1" class="edge">
<title>host:mgmta&#45;&#45;A:mgmt</title>
<path fill="none" stroke="lightgrey" stroke-width="2" d="M266.03,-46.5C266.03,-46.5 25,-528.55 25,-528.55"/>
</g>
<!-- host&#45;&#45;A -->
<g id="edge5" class="edge">
<title>host:a&#45;&#45;A:h</title>
<path fill="none" stroke="cornflowerblue" stroke-width="2" d="M307.03,-46.5C307.03,-46.5 63,-528.55 63,-528.55"/>
</g>
<!-- B -->
<g id="node3" class="node">
<title>B</title>
<polygon fill="none" stroke="black" points="540.05,-529.05 540.05,-598.05 640.05,-598.05 640.05,-529.05 540.05,-529.05"/>
<text text-anchor="middle" x="552.55" y="-582.85" font-family="DejaVu Sans Mono, Book" font-size="14.00">a</text>
<polyline fill="none" stroke="black" points="540.05,-575.05 565.05,-575.05 "/>
<text text-anchor="middle" x="552.55" y="-559.85" font-family="DejaVu Sans Mono, Book" font-size="14.00">d</text>
<polyline fill="none" stroke="black" points="540.05,-552.05 565.05,-552.05 "/>
<text text-anchor="middle" x="552.55" y="-536.85" font-family="DejaVu Sans Mono, Book" font-size="14.00">c</text>
<polyline fill="none" stroke="black" points="565.05,-529.05 565.05,-598.05 "/>
<text text-anchor="middle" x="602.55" y="-577.35" font-family="DejaVu Sans Mono, Book" font-size="14.00">B</text>
<polyline fill="none" stroke="black" points="565.05,-564.05 640.05,-564.05 "/>
<text text-anchor="middle" x="577.55" y="-542.85" font-family="DejaVu Sans Mono, Book" font-size="14.00">h</text>
<polyline fill="none" stroke="black" points="590.05,-529.05 590.05,-564.05 "/>
<text text-anchor="middle" x="615.05" y="-542.85" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
</g>
<!-- host&#45;&#45;B -->
<g id="edge2" class="edge">
<title>host:mgmtb&#45;&#45;B:mgmt</title>
<path fill="none" stroke="lightgrey" stroke-width="2" d="M374.03,-46.5C374.03,-46.5 615.05,-528.55 615.05,-528.55"/>
</g>
<!-- host&#45;&#45;B -->
<g id="edge6" class="edge">
<title>host:b&#45;&#45;B:h</title>
<path fill="none" stroke="cornflowerblue" stroke-width="2" d="M333.03,-46.5C333.03,-46.5 577.05,-528.55 577.05,-528.55"/>
</g>
<!-- C -->
<g id="node4" class="node">
<title>C</title>
<polygon fill="none" stroke="black" points="540.05,-259.03 540.05,-328.03 640.05,-328.03 640.05,-259.03 540.05,-259.03"/>
<text text-anchor="middle" x="552.55" y="-312.83" font-family="DejaVu Sans Mono, Book" font-size="14.00">b</text>
<polyline fill="none" stroke="black" points="540.05,-305.03 565.05,-305.03 "/>
<text text-anchor="middle" x="552.55" y="-289.83" font-family="DejaVu Sans Mono, Book" font-size="14.00">a</text>
<polyline fill="none" stroke="black" points="540.05,-282.03 565.05,-282.03 "/>
<text text-anchor="middle" x="552.55" y="-266.83" font-family="DejaVu Sans Mono, Book" font-size="14.00">d</text>
<polyline fill="none" stroke="black" points="565.05,-259.03 565.05,-328.03 "/>
<text text-anchor="middle" x="602.55" y="-307.33" font-family="DejaVu Sans Mono, Book" font-size="14.00">C</text>
<polyline fill="none" stroke="black" points="565.05,-294.03 640.05,-294.03 "/>
<text text-anchor="middle" x="577.55" y="-272.83" font-family="DejaVu Sans Mono, Book" font-size="14.00">h</text>
<polyline fill="none" stroke="black" points="590.05,-259.03 590.05,-294.03 "/>
<text text-anchor="middle" x="615.05" y="-272.83" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
</g>
<!-- host&#45;&#45;C -->
<g id="edge3" class="edge">
<title>host:mgmtc&#45;&#45;C:mgmt</title>
<path fill="none" stroke="lightgrey" stroke-width="2" d="M486.03,-35.5C486.03,-35.5 615.05,-258.53 615.05,-258.53"/>
</g>
<!-- host&#45;&#45;C -->
<g id="edge7" class="edge">
<title>host:c&#45;&#45;C:h</title>
<path fill="none" stroke="cornflowerblue" stroke-width="2" d="M416.03,-46.5C416.03,-46.5 577.05,-258.53 577.05,-258.53"/>
</g>
<!-- D -->
<g id="node5" class="node">
<title>D</title>
<polygon fill="none" stroke="black" points="0,-259.03 0,-328.03 100,-328.03 100,-259.03 0,-259.03"/>
<text text-anchor="middle" x="37.5" y="-307.33" font-family="DejaVu Sans Mono, Book" font-size="14.00">D</text>
<polyline fill="none" stroke="black" points="0,-294.03 75,-294.03 "/>
<text text-anchor="middle" x="25" y="-272.83" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
<polyline fill="none" stroke="black" points="50,-259.03 50,-294.03 "/>
<text text-anchor="middle" x="62.5" y="-272.83" font-family="DejaVu Sans Mono, Book" font-size="14.00">h</text>
<polyline fill="none" stroke="black" points="75,-259.03 75,-328.03 "/>
<text text-anchor="middle" x="87.5" y="-312.83" font-family="DejaVu Sans Mono, Book" font-size="14.00">a</text>
<polyline fill="none" stroke="black" points="75,-305.03 100,-305.03 "/>
<text text-anchor="middle" x="87.5" y="-289.83" font-family="DejaVu Sans Mono, Book" font-size="14.00">b</text>
<polyline fill="none" stroke="black" points="75,-282.03 100,-282.03 "/>
<text text-anchor="middle" x="87.5" y="-266.83" font-family="DejaVu Sans Mono, Book" font-size="14.00">c</text>
</g>
<!-- host&#45;&#45;D -->
<g id="edge4" class="edge">
<title>host:mgmtd&#45;&#45;D:mgmt</title>
<path fill="none" stroke="lightgrey" stroke-width="2" d="M154.03,-35.5C154.03,-35.5 25,-258.53 25,-258.53"/>
</g>
<!-- host&#45;&#45;D -->
<g id="edge8" class="edge">
<title>host:d&#45;&#45;D:h</title>
<path fill="none" stroke="cornflowerblue" stroke-width="2" d="M224.03,-46.5C224.03,-46.5 63,-258.53 63,-258.53"/>
</g>
<!-- A&#45;&#45;B -->
<g id="edge9" class="edge">
<title>A:b&#45;&#45;B:a</title>
<path fill="none" stroke="black" stroke-width="2" d="M100,-586.55C100,-586.55 540.05,-586.55 540.05,-586.55"/>
</g>
<!-- A&#45;&#45;C -->
<g id="edge13" class="edge">
<title>A:c&#45;&#45;C:a</title>
<path fill="none" stroke="black" stroke-width="2" d="M100,-563.55C100,-563.55 540.05,-293.53 540.05,-293.53"/>
</g>
<!-- B&#45;&#45;C -->
<g id="edge10" class="edge">
<title>B:c&#45;&#45;C:b</title>
<path fill="none" stroke="black" stroke-width="2" d="M552.05,-528.55C552.05,-528.55 552.05,-328.53 552.05,-328.53"/>
</g>
<!-- B&#45;&#45;D -->
<g id="edge14" class="edge">
<title>B:d&#45;&#45;D:b</title>
<path fill="none" stroke="black" stroke-width="2" d="M540.05,-563.55C540.05,-563.55 100,-293.53 100,-293.53"/>
</g>
<!-- C&#45;&#45;D -->
<g id="edge11" class="edge">
<title>C:d&#45;&#45;D:c</title>
<path fill="none" stroke="black" stroke-width="2" d="M540.05,-270.53C540.05,-270.53 100,-270.53 100,-270.53"/>
</g>
<!-- D&#45;&#45;A -->
<g id="edge12" class="edge">
<title>D:a&#45;&#45;A:d</title>
<path fill="none" stroke="black" stroke-width="2" d="M88,-328.53C88,-328.53 88,-528.55 88,-528.55"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 10 KiB

@@ -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