mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 09:41:54 +00:00
Flock tests: saving Linux KRT contents (used in ospf-base)
This commit is contained in:
parent
6a52780652
commit
f7f06db288
1
.gitignore
vendored
1
.gitignore
vendored
@ -14,3 +14,4 @@
|
|||||||
/sysdep/autoconf.h.in~
|
/sysdep/autoconf.h.in~
|
||||||
/cscope.*
|
/cscope.*
|
||||||
*.tar.gz
|
*.tar.gz
|
||||||
|
__pycache__
|
||||||
|
1102
flock/ospf-base/dump-0002-fib-startup.yaml
Normal file
1102
flock/ospf-base/dump-0002-fib-startup.yaml
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/bin/python3
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
from python.BIRD.Test import Test, BIRDInstance, DumpRIB
|
from python.BIRD.Test import Test, BIRDInstance, DumpRIB, DumpLinuxKRT
|
||||||
from python.BIRD.LogChecker import LogExpectedStub
|
from python.BIRD.LogChecker import LogExpectedStub
|
||||||
|
|
||||||
class ThisTest(Test):
|
class ThisTest(Test):
|
||||||
@ -32,4 +32,7 @@ class ThisTest(Test):
|
|||||||
|
|
||||||
async def test(self):
|
async def test(self):
|
||||||
# Startup check
|
# Startup check
|
||||||
await DumpRIB(self, 30, "startup")()
|
await asyncio.gather(*[
|
||||||
|
DumpRIB(self, 30, "rib-startup")(),
|
||||||
|
DumpLinuxKRT(self, 30, "fib-startup")(),
|
||||||
|
])
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import ipaddress
|
import ipaddress
|
||||||
import jinja2
|
import jinja2
|
||||||
|
import json
|
||||||
import os
|
import os
|
||||||
import pathlib
|
import pathlib
|
||||||
import sys
|
import sys
|
||||||
@ -17,6 +18,7 @@ from flock.Hypervisor import Hypervisor
|
|||||||
from flock.Machine import Machine
|
from flock.Machine import Machine
|
||||||
from .CLI import CLI, Transport
|
from .CLI import CLI, Transport
|
||||||
from .LogChecker import LogChecker, LogExpectedFuture
|
from .LogChecker import LogChecker, LogExpectedFuture
|
||||||
|
from .Aux import dict_gather, dict_expand
|
||||||
|
|
||||||
# TODO: move this to some aux file
|
# TODO: move this to some aux file
|
||||||
class Differs(Exception):
|
class Differs(Exception):
|
||||||
@ -32,6 +34,56 @@ class Differs(Exception):
|
|||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
class ComparableDict(dict):
|
||||||
|
def __lt__(self, other):
|
||||||
|
if type(other) is dict:
|
||||||
|
return self < ComparableDict(other)
|
||||||
|
elif type(other) is ComparableDict:
|
||||||
|
sk = sorted(list(self.keys()))
|
||||||
|
ok = sorted(list(other.keys()))
|
||||||
|
|
||||||
|
if sk == ok:
|
||||||
|
for k in sk:
|
||||||
|
if self[k] < other[k]:
|
||||||
|
return True
|
||||||
|
if self[k] > other[k]:
|
||||||
|
return False
|
||||||
|
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return sk < ok
|
||||||
|
else:
|
||||||
|
raise TypeError("Inequality impossible between ComparableDict and non-dict")
|
||||||
|
|
||||||
|
def __gt__(self, other):
|
||||||
|
if type(other) is dict:
|
||||||
|
return ComparableDict(other) < self
|
||||||
|
else:
|
||||||
|
return other < self
|
||||||
|
|
||||||
|
def __le__(self, other):
|
||||||
|
if self == other:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return self < other
|
||||||
|
|
||||||
|
def __ge__(self, other):
|
||||||
|
if self == other:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return self > other
|
||||||
|
|
||||||
|
def sort_arrays(a):
|
||||||
|
if type(a) is str:
|
||||||
|
return a
|
||||||
|
if type(a) is int:
|
||||||
|
return a
|
||||||
|
|
||||||
|
try:
|
||||||
|
return { k: sort_arrays(v) for k,v in a.items() }
|
||||||
|
except AttributeError:
|
||||||
|
return sorted([sort_arrays(v) for v in a ], key=lambda v: ComparableDict(v) if type(v) is dict else v)
|
||||||
|
|
||||||
def deep_eq(a, b, deep=False):
|
def deep_eq(a, b, deep=False):
|
||||||
if a == b:
|
if a == b:
|
||||||
return True
|
return True
|
||||||
@ -224,6 +276,7 @@ class BIRDInstance(CLI):
|
|||||||
|
|
||||||
class DumpCheck:
|
class DumpCheck:
|
||||||
def __init__(self, test, timeout, name, check_timeout=None, check_id=None, check_retry_timeout=0.5):
|
def __init__(self, test, timeout, name, check_timeout=None, check_id=None, check_retry_timeout=0.5):
|
||||||
|
self.test = test
|
||||||
self.timeout = timeout
|
self.timeout = timeout
|
||||||
self.check_timeout = timeout if check_timeout is None else check_timeout
|
self.check_timeout = timeout if check_timeout is None else check_timeout
|
||||||
self.check_retry_timeout = check_retry_timeout
|
self.check_retry_timeout = check_retry_timeout
|
||||||
@ -298,15 +351,15 @@ class DumpCheck:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
class DumpOnMachines(DumpCheck):
|
class DumpOnMachines(DumpCheck):
|
||||||
def __init__(self, test, *args, machines=None, **kwargs):
|
def __init__(self, *args, machines=None, **kwargs):
|
||||||
super().__init__(test, *args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
# Collect machines to dump
|
# Collect machines to dump
|
||||||
if machines is None:
|
if machines is None:
|
||||||
self.machines = test.machine_index.values()
|
self.machines = self.test.machine_index.values()
|
||||||
else:
|
else:
|
||||||
self.machines = [
|
self.machines = [
|
||||||
m if isinstance(m, CLI) else test.machine_index[m]
|
m if isinstance(m, CLI) else self.test.machine_index[m]
|
||||||
for m in machines
|
for m in machines
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -337,7 +390,27 @@ class DumpRIB(DumpOnMachines):
|
|||||||
del r[k]
|
del r[k]
|
||||||
return d
|
return d
|
||||||
|
|
||||||
|
class DumpLinuxKRT(DumpOnMachines):
|
||||||
|
def __init__(self, *args, cmdargs=None, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
if cmdargs is None:
|
||||||
|
self.cmdargs = []
|
||||||
|
else:
|
||||||
|
self.cmdargs = cmdargs
|
||||||
|
|
||||||
|
async def obtain_on_machine(self, mach):
|
||||||
|
raw = await dict_gather({
|
||||||
|
fam:
|
||||||
|
self.test.hypervisor.control_socket.send_cmd(
|
||||||
|
"run_in", mach.mach.name, "ip", "-j", f"-{fam}", "route", "show", *self.cmdargs)
|
||||||
|
for fam in ("4", "6", "M")
|
||||||
|
})
|
||||||
|
|
||||||
|
for k,v in raw.items():
|
||||||
|
if v["ret"] != 0 or len(v["err"]) != 0:
|
||||||
|
raise Exception(f"Failed to gather krt dump for {k}: ret={v['ret']}, {v['err']}")
|
||||||
|
|
||||||
|
return { k: sort_arrays(json.loads(v["out"])) for k,v in raw.items() }
|
||||||
|
|
||||||
class Test:
|
class Test:
|
||||||
ipv6_prefix = ipaddress.ip_network("2001:db8::/32")
|
ipv6_prefix = ipaddress.ip_network("2001:db8::/32")
|
||||||
@ -470,6 +543,36 @@ class Test:
|
|||||||
await self.cleanup()
|
await self.cleanup()
|
||||||
|
|
||||||
|
|
||||||
|
async def krt_dump(self, timeout, name, *args, full=True, machines=None, check_timeout=10, check_retry_timeout=0.5):
|
||||||
|
# Collect machines to dump
|
||||||
|
if machines is None:
|
||||||
|
machines = self.machine_index.values()
|
||||||
|
else:
|
||||||
|
machines = [
|
||||||
|
m if isinstance(m, CLI) else self.machine_index[m]
|
||||||
|
for m in machines
|
||||||
|
]
|
||||||
|
|
||||||
|
raw = await dict_gather({
|
||||||
|
(mach.mach.name, fam):
|
||||||
|
mach.mach.hypervisor.control_socket.send_cmd(
|
||||||
|
"run_in", mach.mach.name, "ip", "-j", f"-{fam}", "route", "show", *args)
|
||||||
|
for mach in machines
|
||||||
|
for fam in ("4", "6", "M")
|
||||||
|
})
|
||||||
|
|
||||||
|
for k,v in raw.items():
|
||||||
|
if v["ret"] != 0 or len(v["err"]) != 0:
|
||||||
|
raise Exception(f"Failed to gather krt dump for {k}: ret={v['ret']}, {v['err']}")
|
||||||
|
|
||||||
|
dump = dict_expand({ k: json.loads(v["out"]) for k,v in raw.items()})
|
||||||
|
print(dump)
|
||||||
|
|
||||||
|
name = "krt.yaml"
|
||||||
|
with open(name, "w") as y:
|
||||||
|
yaml.dump(dump, y)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
name = sys.argv[1]
|
name = sys.argv[1]
|
||||||
mode = Test.CHECK
|
mode = Test.CHECK
|
||||||
|
Loading…
Reference in New Issue
Block a user