mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-22 01:13:00 +02:00
test: add DHCPv4 client hostname resend regression test
Signed-off-by: Ejub Sabic <ejub1946@outlook.com>
This commit is contained in:
@@ -7,6 +7,7 @@ Tests verifying DHCPv4/DHCPv6 client and server functionality:
|
||||
- DHCPv4 client with default gateway assignment
|
||||
- DHCPv4 client with static route configuration
|
||||
- DHCPv4 client hostname management and priority
|
||||
- DHCPv4 client hostname option is resent after system hostname changes
|
||||
- Basic DHCPv6 client operation with address assignment
|
||||
- DHCPv6 client with prefix delegation (IA_PD)
|
||||
- DHCPv6 SLAAC/RA (Stateless)
|
||||
@@ -30,6 +31,10 @@ include::client_hostname/Readme.adoc[]
|
||||
|
||||
<<<
|
||||
|
||||
include::client_hostname_resend/Readme.adoc[]
|
||||
|
||||
<<<
|
||||
|
||||
include::client6_basic/Readme.adoc[]
|
||||
|
||||
<<<
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
test.adoc
|
||||
@@ -0,0 +1,30 @@
|
||||
=== DHCP Hostname Resend
|
||||
|
||||
ifdef::topdoc[:imagesdir: {topdoc}../../test/case/dhcp/client_hostname_resend]
|
||||
|
||||
==== Description
|
||||
|
||||
Verify that updating the system hostname regenerates the DHCP client
|
||||
Finit service file so subsequent DHCP requests advertise the current
|
||||
hostname (option 12, RFC 2132).
|
||||
|
||||
Regression test for a bug where the DHCP client callback only reacts
|
||||
on diffs in infix-dhcp-client, so a standalone change of
|
||||
ietf-system:system/hostname leaves the previously written
|
||||
/etc/finit.d/available/dhcp-client-<iface>.conf untouched and the
|
||||
running udhcpc keeps announcing the old name.
|
||||
|
||||
==== Topology
|
||||
|
||||
image::topology.svg[DHCP Hostname Resend topology, align=center, scaledwidth=75%]
|
||||
|
||||
==== Sequence
|
||||
|
||||
. Set up topology and attach to target DUT
|
||||
. Configure initial hostname '{HOSTNM_A}'
|
||||
. Enable DHCP client sending hostname option
|
||||
. Verify Finit service carries hostname '{HOSTNM_A}'
|
||||
. Update system hostname to '{HOSTNM_B}'
|
||||
. Verify Finit service is regenerated with '{HOSTNM_B}'
|
||||
|
||||
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
#!/usr/bin/env python3
|
||||
"""DHCP Hostname Resend
|
||||
|
||||
Verify that updating the system hostname regenerates the DHCP client
|
||||
Finit service file so subsequent DHCP requests advertise the current
|
||||
hostname (option 12, RFC 2132).
|
||||
|
||||
Regression test for a bug where the DHCP client callback only reacts
|
||||
on diffs in infix-dhcp-client, so a standalone change of
|
||||
ietf-system:system/hostname leaves the previously written
|
||||
/etc/finit.d/available/dhcp-client-<iface>.conf untouched and the
|
||||
running udhcpc keeps announcing the old name.
|
||||
|
||||
"""
|
||||
|
||||
import infamy
|
||||
from infamy.util import until
|
||||
|
||||
|
||||
def finit_conf(ssh, ifname):
|
||||
"""Return the contents of the generated DHCP client Finit service file."""
|
||||
path = f"/etc/finit.d/available/dhcp-client-{ifname}.conf"
|
||||
cmd = ssh.runsh(f"cat {path} 2>/dev/null")
|
||||
return cmd.stdout
|
||||
|
||||
|
||||
def udhcpc_cmdline(ssh, ifname):
|
||||
"""Return the NUL-separated argv of the running udhcpc for ifname."""
|
||||
pidfile = f"/run/dhcp-client-{ifname}.pid"
|
||||
cmd = ssh.runsh(
|
||||
f"p=$(cat {pidfile} 2>/dev/null); "
|
||||
f"[ -n \"$p\" ] && tr '\\0' ' ' < /proc/$p/cmdline"
|
||||
)
|
||||
return cmd.stdout
|
||||
|
||||
|
||||
def running_hostname(ssh, ifname):
|
||||
"""Extract the hostname udhcpc is currently announcing (-x hostname:<name>)."""
|
||||
for tok in udhcpc_cmdline(ssh, ifname).split():
|
||||
if tok.startswith("hostname:"):
|
||||
return tok.split(":", 1)[1]
|
||||
return None
|
||||
|
||||
|
||||
with infamy.Test() as test:
|
||||
HOSTNM_A = "infix-resend-a"
|
||||
HOSTNM_B = "infix-resend-b"
|
||||
|
||||
with test.step("Set up topology and attach to target DUT"):
|
||||
env = infamy.Env()
|
||||
client = env.attach("client", "mgmt")
|
||||
clissh = env.attach("client", "mgmt", "ssh")
|
||||
_, port = env.ltop.xlate("client", "mgmt")
|
||||
|
||||
with test.step(f"Configure initial hostname '{HOSTNM_A}'"):
|
||||
client.put_config_dict("ietf-system", {
|
||||
"system": {
|
||||
"hostname": HOSTNM_A
|
||||
}
|
||||
})
|
||||
until(lambda: client.get_data("/ietf-system:system")
|
||||
.get("system", {}).get("hostname") == HOSTNM_A)
|
||||
|
||||
with test.step("Enable DHCP client sending hostname option"):
|
||||
client.put_config_dict("ietf-interfaces", {
|
||||
"interfaces": {
|
||||
"interface": [{
|
||||
"name": port,
|
||||
"ipv4": {
|
||||
"infix-dhcp-client:dhcp": {
|
||||
"option": [
|
||||
{"id": "vendor-class", "value": "infamy"},
|
||||
{"id": "hostname", "value": "auto"},
|
||||
{"id": "netmask"},
|
||||
{"id": "router"}
|
||||
]
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
})
|
||||
|
||||
with test.step(f"Verify running udhcpc announces hostname '{HOSTNM_A}'"):
|
||||
until(lambda: running_hostname(clissh, port) == HOSTNM_A)
|
||||
|
||||
with test.step(f"Update system hostname to '{HOSTNM_B}'"):
|
||||
client.put_config_dict("ietf-system", {
|
||||
"system": {
|
||||
"hostname": HOSTNM_B
|
||||
}
|
||||
})
|
||||
until(lambda: client.get_data("/ietf-system:system")
|
||||
.get("system", {}).get("hostname") == HOSTNM_B)
|
||||
|
||||
with test.step(f"Verify running udhcpc announces hostname '{HOSTNM_B}'"):
|
||||
try:
|
||||
until(lambda: running_hostname(clissh, port) == HOSTNM_B,
|
||||
attempts=15)
|
||||
except Exception:
|
||||
cur = running_hostname(clissh, port)
|
||||
print(f"udhcpc still announcing hostname '{cur}', expected '{HOSTNM_B}'")
|
||||
test.fail()
|
||||
|
||||
test.succeed()
|
||||
@@ -0,0 +1,22 @@
|
||||
graph "1x1" {
|
||||
layout="neato";
|
||||
overlap="false";
|
||||
esep="+100";
|
||||
|
||||
node [shape=record, fontname="DejaVu Sans Mono, Book"];
|
||||
edge [color="cornflowerblue", penwidth="2", fontname="DejaVu Serif, Book"];
|
||||
|
||||
host [
|
||||
label="host | { <mgmt> mgmt }",
|
||||
pos="0,20!",
|
||||
requires="controller",
|
||||
];
|
||||
|
||||
client [
|
||||
label="{ <mgmt> mgmt } | client",
|
||||
pos="200,20!",
|
||||
requires="infix",
|
||||
];
|
||||
|
||||
host:mgmt -- client:mgmt [requires="mgmt", color=lightgrey]
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?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: 1x1 Pages: 1 -->
|
||||
<svg width="474pt" height="45pt"
|
||||
viewBox="0.00 0.00 474.04 45.00" 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 41)">
|
||||
<title>1x1</title>
|
||||
<polygon fill="white" stroke="transparent" points="-4,4 -4,-41 470.04,-41 470.04,4 -4,4"/>
|
||||
<!-- host -->
|
||||
<g id="node1" class="node">
|
||||
<title>host</title>
|
||||
<polygon fill="none" stroke="black" points="0,-0.5 0,-36.5 100,-36.5 100,-0.5 0,-0.5"/>
|
||||
<text text-anchor="middle" x="25" y="-14.8" font-family="DejaVu Sans Mono, Book" font-size="14.00">host</text>
|
||||
<polyline fill="none" stroke="black" points="50,-0.5 50,-36.5 "/>
|
||||
<text text-anchor="middle" x="75" y="-14.8" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||
</g>
|
||||
<!-- client -->
|
||||
<g id="node2" class="node">
|
||||
<title>client</title>
|
||||
<polygon fill="none" stroke="black" points="350.04,-0.5 350.04,-36.5 466.04,-36.5 466.04,-0.5 350.04,-0.5"/>
|
||||
<text text-anchor="middle" x="375.04" y="-14.8" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||
<polyline fill="none" stroke="black" points="400.04,-0.5 400.04,-36.5 "/>
|
||||
<text text-anchor="middle" x="433.04" y="-14.8" font-family="DejaVu Sans Mono, Book" font-size="14.00">client</text>
|
||||
</g>
|
||||
<!-- host--client -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>host:mgmt--client:mgmt</title>
|
||||
<path fill="none" stroke="lightgrey" stroke-width="2" d="M100,-18.5C100,-18.5 350.04,-18.5 350.04,-18.5"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
@@ -14,6 +14,9 @@
|
||||
- name: DHCP Hostname Priority
|
||||
case: client_hostname/test.py
|
||||
|
||||
- name: DHCP Hostname Resend
|
||||
case: client_hostname_resend/test.py
|
||||
|
||||
- name: DHCPv6 Basic
|
||||
case: client6_basic/test.py
|
||||
|
||||
|
||||
Reference in New Issue
Block a user