mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-22 01:13:00 +02:00
test: add test for ntp client
This commit is contained in:
@@ -16,3 +16,5 @@ include::timezone_utc_offset/Readme.adoc[]
|
||||
include::ssh_key_authentication/Readme.adoc[]
|
||||
|
||||
include::upgrade/Readme.adoc[]
|
||||
|
||||
include::ntp_client/Readme.adoc[]
|
||||
|
||||
@@ -16,3 +16,6 @@
|
||||
|
||||
- name: ssh_key_authentication
|
||||
case: ssh_key_authentication/test.py
|
||||
|
||||
- name: ntp_client
|
||||
case: ntp_client/test.py
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
=== Simple NTP client test
|
||||
==== Description
|
||||
Verify NTP client to multiple NTP servers and verify that one get selected
|
||||
|
||||
==== Topology
|
||||
ifdef::topdoc[]
|
||||
image::../../test/case/ietf_system/ntp_client/topology.svg[Simple NTP client test topology]
|
||||
endif::topdoc[]
|
||||
ifndef::topdoc[]
|
||||
ifdef::testgroup[]
|
||||
image::ntp_client/topology.svg[Simple NTP client test topology]
|
||||
endif::testgroup[]
|
||||
ifndef::testgroup[]
|
||||
image::topology.svg[Simple NTP client test topology]
|
||||
endif::testgroup[]
|
||||
endif::topdoc[]
|
||||
==== Test sequence
|
||||
. Set up topology and attach to target DUT
|
||||
. Configure NTP client on 'target'
|
||||
. Verify one source is in 'selected' state on 'target'
|
||||
|
||||
|
||||
<<<
|
||||
|
||||
Executable
+109
@@ -0,0 +1,109 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Basic NTP client test
|
||||
|
||||
Verify NTP client with multiple servers, ensure one get selected.
|
||||
"""
|
||||
|
||||
import infamy
|
||||
import infamy.ntp_server as ntp_server
|
||||
import infamy.ntp as ntp
|
||||
import infamy.util as util
|
||||
def config_target(dut, data1, data2, data3):
|
||||
dut.put_config_dicts({
|
||||
"ietf-interfaces": {
|
||||
"interfaces": {
|
||||
"interface": [
|
||||
{
|
||||
"name": data1,
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"address": [{
|
||||
"ip": "192.168.1.2",
|
||||
"prefix-length": 24
|
||||
}]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": data2,
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"address": [{
|
||||
"ip": "192.168.2.2",
|
||||
"prefix-length": 24
|
||||
}]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": data3,
|
||||
"enabled": True,
|
||||
"ipv4": {
|
||||
"address": [{
|
||||
|
||||
"ip": "192.168.3.2",
|
||||
"prefix-length": 24
|
||||
}]
|
||||
}
|
||||
}]
|
||||
}
|
||||
},
|
||||
"ietf-system": {
|
||||
"system": {
|
||||
"ntp": {
|
||||
"enabled": True,
|
||||
"server": [{
|
||||
"name": "Server1",
|
||||
"udp": {
|
||||
"address": "192.168.1.1"
|
||||
},
|
||||
"iburst": True
|
||||
},{
|
||||
"name": "Server2",
|
||||
"udp": {
|
||||
"address": "192.168.2.1"
|
||||
},
|
||||
"iburst": True
|
||||
},{
|
||||
"name": "Server3",
|
||||
"udp": {
|
||||
"address": "192.168.3.1"
|
||||
},
|
||||
"iburst": True
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
with infamy.Test() as test:
|
||||
with test.step("Set up topology and attach to target DUT"):
|
||||
env = infamy.Env()
|
||||
target = env.attach("target", "mgmt")
|
||||
|
||||
with test.step("Configure NTP client on 'target'"):
|
||||
_, data1 = env.ltop.xlate("target", "data1")
|
||||
_, data2 = env.ltop.xlate("target", "data2")
|
||||
_, data3 = env.ltop.xlate("target", "data3")
|
||||
|
||||
config_target(target, data1, data2, data3)
|
||||
|
||||
_, hport1 = env.ltop.xlate("host", "data1")
|
||||
_, hport2 = env.ltop.xlate("host", "data2")
|
||||
_, hport3 = env.ltop.xlate("host", "data3")
|
||||
|
||||
with infamy.IsolatedMacVlan(hport1) as ns1, \
|
||||
infamy.IsolatedMacVlan(hport2) as ns2, \
|
||||
infamy.IsolatedMacVlan(hport3) as ns3:
|
||||
ns1.addip("192.168.1.1")
|
||||
ns2.addip("192.168.2.1")
|
||||
ns3.addip("192.168.3.1")
|
||||
|
||||
with ntp_server.Server(ns1) as ntp1, \
|
||||
ntp_server.Server(ns2) as ntp2, \
|
||||
ntp_server.Server(ns3) as ntp3:
|
||||
with test.step("Verify one source is in 'selected' state on 'target'"):
|
||||
util.until(lambda: ntp.any_source_selected(target), attempts=200)
|
||||
with test.step("Verify three sources exist in NTP client on 'target'"):
|
||||
assert(ntp.number_of_sources(target) == 3)
|
||||
|
||||
test.succeed()
|
||||
@@ -0,0 +1 @@
|
||||
../../../infamy/topologies/1x4.dot
|
||||
@@ -0,0 +1,60 @@
|
||||
<?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: 1x4 Pages: 1 -->
|
||||
<svg width="440pt" height="101pt"
|
||||
viewBox="0.00 0.00 440.03 101.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 97)">
|
||||
<title>1x4</title>
|
||||
<polygon fill="white" stroke="transparent" points="-4,4 -4,-97 436.03,-97 436.03,4 -4,4"/>
|
||||
<!-- host -->
|
||||
<g id="node1" class="node">
|
||||
<title>host</title>
|
||||
<polygon fill="none" stroke="black" points="0,-0.5 0,-92.5 108,-92.5 108,-0.5 0,-0.5"/>
|
||||
<text text-anchor="middle" x="25" y="-42.8" font-family="DejaVu Sans Mono, Book" font-size="14.00">host</text>
|
||||
<polyline fill="none" stroke="black" points="50,-0.5 50,-92.5 "/>
|
||||
<text text-anchor="middle" x="79" y="-77.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||
<polyline fill="none" stroke="black" points="50,-69.5 108,-69.5 "/>
|
||||
<text text-anchor="middle" x="79" y="-54.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">data1</text>
|
||||
<polyline fill="none" stroke="black" points="50,-46.5 108,-46.5 "/>
|
||||
<text text-anchor="middle" x="79" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">data2</text>
|
||||
<polyline fill="none" stroke="black" points="50,-23.5 108,-23.5 "/>
|
||||
<text text-anchor="middle" x="79" y="-8.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">data3</text>
|
||||
</g>
|
||||
<!-- target -->
|
||||
<g id="node2" class="node">
|
||||
<title>target</title>
|
||||
<polygon fill="none" stroke="black" points="308.03,-0.5 308.03,-92.5 432.03,-92.5 432.03,-0.5 308.03,-0.5"/>
|
||||
<text text-anchor="middle" x="337.03" y="-77.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">mgmt</text>
|
||||
<polyline fill="none" stroke="black" points="308.03,-69.5 366.03,-69.5 "/>
|
||||
<text text-anchor="middle" x="337.03" y="-54.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">data1</text>
|
||||
<polyline fill="none" stroke="black" points="308.03,-46.5 366.03,-46.5 "/>
|
||||
<text text-anchor="middle" x="337.03" y="-31.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">data2</text>
|
||||
<polyline fill="none" stroke="black" points="308.03,-23.5 366.03,-23.5 "/>
|
||||
<text text-anchor="middle" x="337.03" y="-8.3" font-family="DejaVu Sans Mono, Book" font-size="14.00">data3</text>
|
||||
<polyline fill="none" stroke="black" points="366.03,-0.5 366.03,-92.5 "/>
|
||||
<text text-anchor="middle" x="399.03" y="-42.8" font-family="DejaVu Sans Mono, Book" font-size="14.00">target</text>
|
||||
</g>
|
||||
<!-- host--target -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>host:mgmt--target:mgmt</title>
|
||||
<path fill="none" stroke="cornflowerblue" stroke-width="2" d="M108,-81.5C108,-81.5 308.03,-81.5 308.03,-81.5"/>
|
||||
</g>
|
||||
<!-- host--target -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>host:data1--target:data1</title>
|
||||
<path fill="none" stroke="black" stroke-width="2" d="M108,-58.5C108,-58.5 308.03,-58.5 308.03,-58.5"/>
|
||||
</g>
|
||||
<!-- host--target -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>host:data2--target:data2</title>
|
||||
<path fill="none" stroke="black" stroke-width="2" d="M108,-34.5C108,-34.5 308.03,-34.5 308.03,-34.5"/>
|
||||
</g>
|
||||
<!-- host--target -->
|
||||
<g id="edge4" class="edge">
|
||||
<title>host:data3--target:data3</title>
|
||||
<path fill="none" stroke="black" stroke-width="2" d="M108,-11.5C108,-11.5 308.03,-11.5 308.03,-11.5"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.4 KiB |
@@ -0,0 +1,38 @@
|
||||
"""
|
||||
NTP client helper
|
||||
"""
|
||||
|
||||
|
||||
def _get_ntp(target):
|
||||
xpath = "/ietf-system:system-state/infix-system:ntp"
|
||||
data = target.get_data(xpath)
|
||||
|
||||
if data is None:
|
||||
return None
|
||||
|
||||
return data["system-state"].get("infix-system:ntp", None) or data["system-state"].get("ntp", None)
|
||||
|
||||
|
||||
def _get_ntp_sources(target):
|
||||
ntp = _get_ntp(target)
|
||||
|
||||
if ntp is None:
|
||||
return []
|
||||
|
||||
return ntp["sources"]["source"]
|
||||
|
||||
|
||||
def any_source_selected(target):
|
||||
sources = _get_ntp_sources(target)
|
||||
|
||||
for source in sources:
|
||||
if source["state"] == "selected":
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def number_of_sources(target):
|
||||
sources = _get_ntp_sources(target)
|
||||
|
||||
return len(sources)
|
||||
@@ -0,0 +1,24 @@
|
||||
"""Start NTP server in the background"""
|
||||
import subprocess
|
||||
|
||||
class Server:
|
||||
def __init__(self, netns, iface="iface"):
|
||||
self.iface = iface
|
||||
self.process = None
|
||||
self.netns = netns
|
||||
|
||||
def __enter__(self):
|
||||
self.start()
|
||||
|
||||
def __exit__(self, _, __, ___):
|
||||
self.stop()
|
||||
|
||||
def start(self):
|
||||
cmd=f"ntpd -w -n -l -I {self.iface}"
|
||||
self.process = self.netns.popen(cmd.split(" "),stderr=subprocess.DEVNULL)
|
||||
|
||||
def stop(self):
|
||||
if self.process:
|
||||
self.process.terminate()
|
||||
self.process.wait()
|
||||
self.process = None
|
||||
@@ -7,20 +7,20 @@ graph "1x4" {
|
||||
edge [color="cornflowerblue", penwidth="2", fontname="DejaVu Serif, Book"];
|
||||
|
||||
host [
|
||||
label="host | { <tgt> tgt | <data0> data0 | <data1> data1 | <data2> data2 }",
|
||||
label="host | { <mgmt> mgmt | <data1> data1 | <data2> data2 | <data3> data3 }",
|
||||
pos="0,12!",
|
||||
kind="controller",
|
||||
];
|
||||
|
||||
target [
|
||||
label="{ <mgmt> mgmt | <data0> data0 | <data1> data1 | <data2> data2 } | target",
|
||||
label="{ <mgmt> mgmt | <data1> data1 | <data2> data2 | <data3> data3 } | target",
|
||||
pos="10,12!",
|
||||
|
||||
kind="infix",
|
||||
];
|
||||
|
||||
host:tgt -- target:mgmt [kind=mgmt]
|
||||
host:data0 -- target:data0 [color=black]
|
||||
host:mgmt -- target:mgmt [kind=mgmt]
|
||||
host:data1 -- target:data1 [color=black]
|
||||
host:data2 -- target:data2 [color=black]
|
||||
host:data3 -- target:data3 [color=black]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user