mirror of
https://github.com/kernelkit/infix.git
synced 2026-08-01 13:23:01 +02:00
Merge pull request #847 from kernelkit/test-log-sw
test: reproducible: Log software versions
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
- case: meta/reproducible.py
|
||||
- case: meta/wait.py
|
||||
- case: meta/reproducible.py
|
||||
|
||||
- name: Misc tests
|
||||
suite: misc/misc.yaml
|
||||
|
||||
@@ -13,4 +13,27 @@ with infamy.Test() as test:
|
||||
else:
|
||||
print(f"Specify PYTHONHASHSEED={seed} to reproduce this test environment")
|
||||
|
||||
with test.step("Discover topology and attach to available DUTs"):
|
||||
env = infamy.Env(False)
|
||||
ctrl = env.ptop.get_ctrl()
|
||||
|
||||
duts = {}
|
||||
for ix in env.ptop.get_infixen():
|
||||
cport, ixport = env.ptop.get_mgmt_link(ctrl, ix)
|
||||
print(f"Attaching to {ix}:{ixport} via {ctrl}:{cport}")
|
||||
duts[ix] = env.attach(ix, ixport)
|
||||
|
||||
with test.step("Log running software versions"):
|
||||
for name, tgt in duts.items():
|
||||
sys = tgt.get_data("/ietf-system:system-state")
|
||||
sw = sys["system-state"]["software"]
|
||||
plt = sys["system-state"]["platform"]
|
||||
|
||||
print(f"{name}:")
|
||||
for k,v in plt.items():
|
||||
print(f" {k:<16s} {v}")
|
||||
|
||||
for k in ("compatible", "booted"):
|
||||
print(f" {k:<16s} {sw[k]}")
|
||||
|
||||
test.succeed()
|
||||
|
||||
@@ -15,7 +15,6 @@ import libyang
|
||||
import lxml
|
||||
import netconf_client.connect
|
||||
import netconf_client.ncclient
|
||||
import infamy.iface as iface
|
||||
from infamy.transport import Transport,infer_put_dict
|
||||
from netconf_client.error import RpcError
|
||||
from . import env
|
||||
@@ -382,17 +381,6 @@ class Device(Transport):
|
||||
with open(outdir+"/"+schema["filename"], "w") as f:
|
||||
f.write(data.schema)
|
||||
|
||||
def get_iface(self, name):
|
||||
"""Fetch target dict for iface and extract param from JSON"""
|
||||
content = self.get_data(iface.get_xpath(name))
|
||||
interface = content.get("interfaces", {}).get("interface", None)
|
||||
|
||||
if interface is None:
|
||||
return None
|
||||
|
||||
# Restconf (rousette) address by id, otherwise (netopper2) by name
|
||||
return interface[name]
|
||||
|
||||
def delete_xpath(self, xpath):
|
||||
# Split out the model and the container from xpath'
|
||||
pattern = r"^/(?P<module>[^:]+):(?P<path>[^/]+)"
|
||||
|
||||
+3
-23
@@ -321,19 +321,11 @@ class Device(Transport):
|
||||
"""Get operational data"""
|
||||
uri = xpath_to_uri(xpath) if xpath is not None else None
|
||||
data = self.get_operational(uri, parse)
|
||||
if parse is False:
|
||||
return data
|
||||
|
||||
if data is None:
|
||||
return None
|
||||
if parse and data:
|
||||
return data.print_dict()
|
||||
|
||||
data = json.loads(data.print_mem("json", with_siblings=True,
|
||||
pretty=False))
|
||||
for k, v in data.items():
|
||||
model, container = k.split(":")
|
||||
break
|
||||
|
||||
return {container: v}
|
||||
return data
|
||||
|
||||
def copy(self, source, target):
|
||||
factory = self.get_datastore(source)
|
||||
@@ -372,18 +364,6 @@ class Device(Transport):
|
||||
data = json.loads(data)
|
||||
return data["ietf-system:system-state"]["clock"]["current-datetime"]
|
||||
|
||||
def get_iface(self, iface):
|
||||
"""Fetch target dict for iface and extract param from JSON"""
|
||||
xpath = f"/ietf-interfaces:interfaces/interface={iface}"
|
||||
content = self.get_data(xpath)
|
||||
interface = content.get("interfaces", {}).get("interface", None)
|
||||
if interface is None:
|
||||
return None
|
||||
|
||||
# RESTCONF (at least rousette) addresses by id, but NETCONF (at
|
||||
# least netopper2) addresses by name
|
||||
return interface[0]
|
||||
|
||||
def delete_xpath(self, xpath):
|
||||
"""Delete XPath from running config"""
|
||||
path = f"/ds/ietf-datastores:running/{xpath_to_uri(xpath)}"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
from abc import ABC, abstractmethod
|
||||
from infamy.neigh import ll6ping
|
||||
import infamy.iface
|
||||
|
||||
def infer_put_dict(name, models):
|
||||
if not models.get("ietf-system"):
|
||||
@@ -50,10 +51,13 @@ class Transport(ABC):
|
||||
def call_action(self, xpath):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def get_iface(self, iface):
|
||||
"""Should be common, but is not due to bug in rousette"""
|
||||
pass
|
||||
def get_iface(self, name):
|
||||
"""Fetch target dict for iface and extract param from JSON"""
|
||||
content = self.get_data(infamy.iface.get_xpath(name))
|
||||
interfaces = content.get("interfaces", {}).get("interface", {})
|
||||
|
||||
# KeyedList does not support `.get()`
|
||||
return interfaces[name] if name in interfaces else None
|
||||
|
||||
def get_mgmt_ip(self):
|
||||
"""Return managment IP address used for RESTCONF/NETCONF"""
|
||||
|
||||
Reference in New Issue
Block a user