Skip to content

Commit

Permalink
test: add a test to verify all interfaces
Browse files Browse the repository at this point in the history
The test ensures that all interface types can be successfully created
and retrieved from the operational datastore. It also functions as a
regression test for issue kernelkit#618 and will apply to all future interface
variants.

Fixes kernelkit#622
  • Loading branch information
axkar committed Sep 26, 2024
1 parent c39a63e commit fb4fa5d
Show file tree
Hide file tree
Showing 4 changed files with 263 additions and 0 deletions.
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 @@ -49,3 +49,6 @@

- name: vlan_qos
case: vlan_qos/test.py

- name: verify_all_interface_types
case: verify_all_interface_types/test.py
235 changes: 235 additions & 0 deletions test/case/ietf_interfaces/verify_all_interface_types/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
#!/usr/bin/env python3
"""
```
lo br-0 br-Q.40 br-D br-X
| | | | |
o o eth-Q.10 br-Q veth0a.20 eth-X.30
\ / \ | |
eth-Q veth0b veth0a eth-X
`---------'
```
Verify that all interface types can be created:
1. Ethernet/Etherlike (ethX)
2. Loopback (lo)
3. Empty bridge (br-0)
4. Ethernet/Etherlike (ethQ) as a bridge port in br-Q
5. VETH pair: veth0a <--> veth0b, veth0b as a bridge port in br-Q
6. VLAN:
1. ethQ.10 (VLAN 10) on top of an Ethernet/Etherlike interface (ethQ)
2. br-Q.40 (VLAN 40) on top of a bridge (br-Q)
3. veth0a.20 (VLAN 20) on top of a VETH interface (veth0a) as a bridge port in br-D
4. ethX.30 (VLAN 30) as a bridge port in br-X
"""

import infamy
import infamy.iface as iface


def verify_interface(target, interface, expected_type):
assert iface.interface_exist(target, interface), f"Interface <{interface}> does not exist."

expected_type = f"infix-if-type:{expected_type}"
actual_type = iface._iface_get_param(target, interface, "type")

if expected_type == "infix-if-type:etherlike" and actual_type == "infix-if-type:ethernet":
return # Allow 'etherlike' to match 'ethernet'

assert actual_type == expected_type, f"Assertion failed! expected tpye: {expected_type}, actual type {actual_type}"


with infamy.Test() as test:
with test.step("Initialize"):
env = infamy.Env()
target = env.attach("target", "mgmt")

_, eth_Q = env.ltop.xlate("target", "ethQ")
_, eth_X = env.ltop.xlate("target", "ethX")

eth_Q_10 = f"{eth_Q}.10"
eth_X_30 = f"{eth_X}.30"

br_0 = "br-0"
br_X = "br-X"
br_D = "br-D"
br_Q = "br-Q"

veth_a = "veth0a"
veth_b = "veth0b"

veth_a_20 = f"{veth_a}.20"
br_Q_40 = f"{br_Q}.40"

with test.step("Configure an empty bridge"):
target.put_config_dict("ietf-interfaces", {
"interfaces": {
"interface": [
{
"name": br_0,
"type": "infix-if-type:bridge",
"enabled": True,
}
]
}
})

with test.step("Configure bridge brX and associated interfaces"):
target.put_config_dict("ietf-interfaces", {
"interfaces": {
"interface": [
{
"name": br_X,
"type": "infix-if-type:bridge",
"enabled": True
},
{
"name": eth_X_30,
"type": "infix-if-type:vlan",
"enabled": True,
"vlan": {
"lower-layer-if": eth_X,
"id": 30
},
"infix-interfaces:bridge-port": {
"bridge": br_X
}
}
]
}
})

with test.step("Configure VETH pair"):
target.put_config_dict("ietf-interfaces", {
"interfaces": {
"interface": [
{
"name": veth_a,
"type": "infix-if-type:veth",
"enabled": True,
"infix-interfaces:veth": {
"peer": veth_b
}
},
{
"name": veth_b,
"type": "infix-if-type:veth",
"enabled": True,
"infix-interfaces:veth": {
"peer": veth_a
}
}
]
}
})

with test.step("Configure bridge brD and associated interfaces"):
target.put_config_dict("ietf-interfaces", {
"interfaces": {
"interface": [
{
"name": br_D,
"type": "infix-if-type:bridge",
"enabled": True,
},
{
"name": veth_a_20,
"type": "infix-if-type:vlan",
"enabled": True,
"vlan": {
"lower-layer-if": "veth0a",
"id": 20
},
"infix-interfaces:bridge-port": {
"bridge": br_D
}
}
]
}
})

with test.step("Configure br-Q and associated interfaces"):
target.put_config_dict("ietf-interfaces", {
"interfaces": {
"interface": [
{
"name": br_Q,
"type": "infix-if-type:bridge",
"enabled": True,
},
{
"name": eth_Q,
"enabled": True,
"infix-interfaces:bridge-port": {
"bridge": br_Q
}
},
{
"name": veth_b,
"type": "infix-if-type:veth",
"enabled": True,
"infix-interfaces:bridge-port": {
"bridge": br_Q
}
},
{
"name": eth_Q_10,
"type": "infix-if-type:vlan",
"enabled": True,
"vlan": {
"lower-layer-if": eth_Q,
"id": 10
}
},
{
"name": br_Q_40,
"type": "infix-if-type:vlan",
"enabled": True,
"vlan": {
"lower-layer-if": br_Q,
"id": 40
}
}
]
}
})


with test.step("Verify loopback interface"):
verify_interface(target, "lo", "loopback")

with test.step("Verify Ethernet/Etherlike interface (ethX) with VLAN ethX.10"):
verify_interface(target, eth_X, "etherlike")

with test.step("Verify Ethernet/Etherlike interface (ethQ) as a bridge port"):
verify_interface(target, eth_Q, "etherlike")

with test.step("Verify empty bridge br-0"):
verify_interface(target, br_0, "bridge")

with test.step("Verify bridge br-Q with VLAN interface br-Q.40 on top"):
verify_interface(target, br_Q, "bridge")

with test.step("Verify bridge br-X with VLAN interface ethX.10 as bridge port"):
verify_interface(target, br_X, "bridge")

with test.step("Verify bridge br-D with VLAN interface veth0a.20 as bridge port"):
verify_interface(target, br_D, "bridge")

with test.step("Verify VETH interface veth0b as a bridge port in br-Q and VETH peer"):
verify_interface(target, veth_b, "veth")

with test.step("Verify VETH interface veth0a with VLAN veth0a.20 and VETH peer"):
verify_interface(target, veth_a, "veth")

with test.step("Verify VLAN interface veth0a.20 on top of veth0a as bridge port"):
verify_interface(target, veth_a_20, "vlan")

with test.step("Verify VLAN interface ethQ.10 on top of Ethernet/Etherlike ethQ"):
verify_interface(target, eth_Q_10, "vlan")

with test.step("Verify VLAN interface ethX.30 on top of Ethernet/Etherlike ethX as bridge port"):
verify_interface(target, eth_X_30, "vlan")

with test.step("Verify VLAN interface br-Q.40 on top of bridge br-Q"):
verify_interface(target, br_Q_40, "vlan")

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

node [shape=record, fontname="monospace"];
edge [color="cornflowerblue", penwidth="2"];

host [
label="host | { <tgt> tgt | <dummy0> dummy0 | <dummy1> dummy1 }",
pos="0,12!",
kind="controller",
];

target [
label="{ <mgmt> mgmt | <Dport> Dport | <Qport> Qport } | target",
pos="10,12!",

kind="infix",
];

host:tgt -- target:mgmt [kind=mgmt]
host:dummy0 -- target:ethQ [color=black]
host:dummy1 -- target:ethX [color=black]
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit fb4fa5d

Please sign in to comment.