mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-28 15:36:25 +00:00
tests: add some more mgmtd tests
Signed-off-by: Christian Hopps <chopps@labn.net>
This commit is contained in:
parent
0327be91d1
commit
e3c4bd2472
13
tests/topotests/mgmt_startup/r1/mgmtd.conf
Normal file
13
tests/topotests/mgmt_startup/r1/mgmtd.conf
Normal file
@ -0,0 +1,13 @@
|
||||
debug northbound notifications
|
||||
debug northbound libyang
|
||||
debug northbound events
|
||||
debug northbound callbacks
|
||||
debug mgmt backend datastore frontend transaction
|
||||
debug mgmt client backend
|
||||
debug mgmt client frontend
|
||||
|
||||
ip route 12.0.0.0/24 101.0.0.2
|
||||
ip route 13.0.0.0/24 101.0.0.3
|
||||
|
||||
ipv6 route 2012::/48 2101::2
|
||||
ipv6 route 2013::/48 2101::3
|
7
tests/topotests/mgmt_startup/r1/zebra.conf
Normal file
7
tests/topotests/mgmt_startup/r1/zebra.conf
Normal file
@ -0,0 +1,7 @@
|
||||
log timestamp precision 3
|
||||
log file frr2.log
|
||||
|
||||
interface r1-eth0
|
||||
ip address 101.0.0.1/24
|
||||
ipv6 address 2101::1/64
|
||||
exit
|
7
tests/topotests/mgmt_startup/r2/staticd.conf
Normal file
7
tests/topotests/mgmt_startup/r2/staticd.conf
Normal file
@ -0,0 +1,7 @@
|
||||
log timestamp precision 3
|
||||
|
||||
ip route 11.0.0.0/24 101.0.0.1
|
||||
ip route 13.0.0.0/24 101.0.0.3
|
||||
|
||||
ipv6 route 2011::/48 2102::1
|
||||
ipv6 route 2013::/48 2102::3
|
12
tests/topotests/mgmt_startup/r2/zebra.conf
Normal file
12
tests/topotests/mgmt_startup/r2/zebra.conf
Normal file
@ -0,0 +1,12 @@
|
||||
log timestamp precision 3
|
||||
debug northbound notifications
|
||||
debug northbound libyang
|
||||
debug northbound events
|
||||
debug northbound callbacks
|
||||
debug mgmt backend datastore frontend transaction
|
||||
debug mgmt client backend
|
||||
debug mgmt client frontend
|
||||
|
||||
interface r2-eth0
|
||||
ip address 101.0.0.2/24
|
||||
ipv6 address 2101::2/64
|
18
tests/topotests/mgmt_startup/r3/zebra.conf
Normal file
18
tests/topotests/mgmt_startup/r3/zebra.conf
Normal file
@ -0,0 +1,18 @@
|
||||
log timestamp precision 3
|
||||
debug northbound notifications
|
||||
debug northbound libyang
|
||||
debug northbound events
|
||||
debug northbound callbacks
|
||||
debug mgmt backend datastore frontend transaction
|
||||
debug mgmt client backend
|
||||
debug mgmt client frontend
|
||||
|
||||
interface r3-eth0
|
||||
ip address 101.0.0.3/24
|
||||
ipv6 address 2101::3/64
|
||||
|
||||
ip route 11.0.0.0/24 101.0.0.1
|
||||
ip route 12.0.0.0/24 101.0.0.2
|
||||
|
||||
ipv6 route 2011::/48 2101::1
|
||||
ipv6 route 2012::/48 2101::2
|
127
tests/topotests/mgmt_startup/test_bigconf.py
Normal file
127
tests/topotests/mgmt_startup/test_bigconf.py
Normal file
@ -0,0 +1,127 @@
|
||||
# -*- coding: utf-8 eval: (blacken-mode 1) -*-
|
||||
# SPDX-License-Identifier: ISC
|
||||
#
|
||||
# May 2 2023, Christian Hopps <chopps@labn.net>
|
||||
#
|
||||
# Copyright (c) 2023, LabN Consulting, L.L.C.
|
||||
#
|
||||
"""
|
||||
Test static route startup functionality
|
||||
"""
|
||||
|
||||
import datetime
|
||||
import ipaddress
|
||||
import logging
|
||||
import math
|
||||
import os
|
||||
import re
|
||||
|
||||
import pytest
|
||||
from lib.common_config import retry, step
|
||||
from lib.topogen import Topogen, TopoRouter
|
||||
from lib.topolog import logger
|
||||
from munet.base import Timeout
|
||||
|
||||
CWD = os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
# pytestmark = [pytest.mark.staticd, pytest.mark.mgmtd]
|
||||
pytestmark = [pytest.mark.staticd]
|
||||
|
||||
|
||||
def get_ip_networks(super_prefix, count):
|
||||
count_log2 = math.log(count, 2)
|
||||
if count_log2 != int(count_log2):
|
||||
count_log2 = int(count_log2) + 1
|
||||
else:
|
||||
count_log2 = int(count_log2)
|
||||
network = ipaddress.ip_network(super_prefix)
|
||||
return tuple(network.subnets(count_log2))[0:count]
|
||||
|
||||
|
||||
track = Timeout(0)
|
||||
ROUTE_COUNT = 5000
|
||||
ROUTE_RANGE = [None, None]
|
||||
|
||||
|
||||
def write_big_route_conf(rtr, super_prefix, count):
|
||||
start = None
|
||||
end = None
|
||||
with open(f"{CWD}/{rtr.name}/big.conf", "w+", encoding="ascii") as f:
|
||||
for net in get_ip_networks(super_prefix, count):
|
||||
end = net
|
||||
if not start:
|
||||
start = net
|
||||
f.write(f"ip route {net} lo\n")
|
||||
|
||||
return start, end
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def tgen(request):
|
||||
"Setup/Teardown the environment and provide tgen argument to tests"
|
||||
|
||||
global start_time
|
||||
topodef = {
|
||||
"s1": ("r1",),
|
||||
}
|
||||
|
||||
tgen = Topogen(topodef, request.module.__name__)
|
||||
tgen.start_topology()
|
||||
|
||||
start, end = write_big_route_conf(tgen.gears["r1"].net, "10.0.0.0/8", ROUTE_COUNT)
|
||||
ROUTE_RANGE[0] = start
|
||||
ROUTE_RANGE[1] = end
|
||||
|
||||
# configure mgmtd using current mgmtd config file
|
||||
tgen.gears["r1"].load_config(TopoRouter.RD_ZEBRA, "zebra.conf")
|
||||
tgen.gears["r1"].load_config(TopoRouter.RD_MGMTD, "big.conf")
|
||||
|
||||
track.started_on = datetime.datetime.now()
|
||||
|
||||
tgen.start_router()
|
||||
yield tgen
|
||||
tgen.stop_topology()
|
||||
|
||||
|
||||
@retry(retry_timeout=3, initial_wait=0.1)
|
||||
def check_kernel(r1, prefix, expected=True):
|
||||
net = ipaddress.ip_network(prefix)
|
||||
if net.version == 6:
|
||||
kernel = r1.net.cmd_nostatus("ip -6 route show", warn=not expected)
|
||||
else:
|
||||
kernel = r1.net.cmd_nostatus("ip -4 route show", warn=not expected)
|
||||
|
||||
logger.debug("checking kernel routing table:\n%s", kernel)
|
||||
route = f"{str(net)}(?: nhid [0-9]+)?.*proto (static|196)"
|
||||
m = re.search(route, kernel)
|
||||
if expected and not m:
|
||||
return f"Failed to find \n'{route}'\n in \n'{kernel}'"
|
||||
elif not expected and m:
|
||||
return f"Failed found \n'{route}'\n in \n'{kernel}'"
|
||||
return None
|
||||
|
||||
|
||||
def test_staticd_late_start(tgen):
|
||||
if tgen.routers_have_failure():
|
||||
pytest.skip(tgen.errors)
|
||||
|
||||
r1 = tgen.routers()["r1"]
|
||||
|
||||
step(f"Verifying {ROUTE_COUNT} startup routes are present")
|
||||
|
||||
timeo = Timeout(30)
|
||||
for remaining in timeo:
|
||||
rc, o, e = r1.net.cmd_status("vtysh -c 'show version'")
|
||||
if not rc:
|
||||
break
|
||||
print("nogo: ", rc, o, e)
|
||||
assert not timeo.is_expired()
|
||||
logging.info("r1: vtysh connected after %ss", track.elapsed())
|
||||
|
||||
result = check_kernel(r1, ROUTE_RANGE[0], retry_timeout=20)
|
||||
assert result is None
|
||||
logging.info("r1: first route installed after %ss", track.elapsed())
|
||||
|
||||
result = check_kernel(r1, ROUTE_RANGE[1], retry_timeout=20)
|
||||
assert result is None
|
||||
logging.info("r1: last route installed after %ss", track.elapsed())
|
120
tests/topotests/mgmt_startup/test_config.py
Normal file
120
tests/topotests/mgmt_startup/test_config.py
Normal file
@ -0,0 +1,120 @@
|
||||
# -*- coding: utf-8 eval: (blacken-mode 1) -*-
|
||||
# SPDX-License-Identifier: ISC
|
||||
#
|
||||
# May 2 2023, Christian Hopps <chopps@labn.net>
|
||||
#
|
||||
# Copyright (c) 2023, LabN Consulting, L.L.C.
|
||||
#
|
||||
"""
|
||||
Test static route functionality using old or new configuration files.
|
||||
|
||||
User compat:
|
||||
|
||||
- mgmtd split config will first look to `/etc/frr/zebra.conf`
|
||||
then `/etc/frr/staticd.conf` and finally `/etc/frr/mgmtd.conf`
|
||||
|
||||
- When new components are converted to mgmtd their split config should be
|
||||
added here too.
|
||||
|
||||
Topotest compat:
|
||||
|
||||
- `mgmtd.conf` is copied to `/etc/frr/` for use by mgmtd when implicit load,
|
||||
or explicit load no config specified.
|
||||
|
||||
- `staticd.conf` is copied to `/etc/frr/` for use by mgmtd when staticd
|
||||
is explicit load implict config, and explicit config.
|
||||
|
||||
"""
|
||||
|
||||
import ipaddress
|
||||
import re
|
||||
|
||||
import pytest
|
||||
from lib.common_config import retry, step
|
||||
from lib.topogen import Topogen, TopoRouter
|
||||
from lib.topolog import logger
|
||||
|
||||
# pytestmark = [pytest.mark.staticd, pytest.mark.mgmtd]
|
||||
pytestmark = [pytest.mark.staticd]
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def tgen(request):
|
||||
"Setup/Teardown the environment and provide tgen argument to tests"
|
||||
|
||||
topodef = {
|
||||
"s1": ("r1", "r2", "r3"),
|
||||
}
|
||||
|
||||
tgen = Topogen(topodef, request.module.__name__)
|
||||
tgen.start_topology()
|
||||
|
||||
# configure mgmtd using current mgmtd config file
|
||||
tgen.gears["r1"].load_config(TopoRouter.RD_ZEBRA, "zebra.conf")
|
||||
tgen.gears["r1"].load_config(TopoRouter.RD_MGMTD, "mgmtd.conf")
|
||||
|
||||
# user/topotest compat:
|
||||
# configure mgmtd using old staticd config file, with explicity staticd
|
||||
# load.
|
||||
tgen.gears["r2"].load_config(TopoRouter.RD_ZEBRA, "zebra.conf")
|
||||
tgen.gears["r2"].load_config(TopoRouter.RD_STATIC, "staticd.conf")
|
||||
|
||||
# user compat:
|
||||
# configure mgmtd using backup config file `zebra.conf`
|
||||
tgen.gears["r3"].load_config(TopoRouter.RD_ZEBRA, "zebra.conf")
|
||||
|
||||
tgen.start_router()
|
||||
yield tgen
|
||||
tgen.stop_topology()
|
||||
|
||||
|
||||
@retry(retry_timeout=3, initial_wait=0.1)
|
||||
def check_kernel(r1, prefix, expected=True):
|
||||
net = ipaddress.ip_network(prefix)
|
||||
if net.version == 6:
|
||||
kernel = r1.net.cmd_nostatus("ip -6 route show", warn=not expected)
|
||||
else:
|
||||
kernel = r1.net.cmd_nostatus("ip -4 route show", warn=not expected)
|
||||
|
||||
logger.debug("checking kernel routing table:\n%s", kernel)
|
||||
route = f"{str(net)}(?: nhid [0-9]+)?.*proto (static|196)"
|
||||
m = re.search(route, kernel)
|
||||
if expected and not m:
|
||||
return f"Failed to find \n'{route}'\n in \n'{kernel}'"
|
||||
elif not expected and m:
|
||||
return f"Failed found \n'{route}'\n in \n'{kernel}'"
|
||||
return None
|
||||
|
||||
|
||||
def test_staticd_late_start(tgen):
|
||||
if tgen.routers_have_failure():
|
||||
pytest.skip(tgen.errors)
|
||||
|
||||
for x in ["r1", "r2", "r3"]:
|
||||
tgen.gears[x].net.cmd_nostatus(
|
||||
"vtysh -c 'debug mgmt client frontend' "
|
||||
"-c 'debug mgmt client backend' "
|
||||
"-c 'debug mgmt backend frontend datastore transaction'"
|
||||
)
|
||||
|
||||
r1 = tgen.routers()["r1"]
|
||||
r2 = tgen.routers()["r2"]
|
||||
r3 = tgen.routers()["r3"]
|
||||
|
||||
step("Verifying routes are present on r1")
|
||||
result = check_kernel(r1, "12.0.0.0/24")
|
||||
assert result is None
|
||||
result = check_kernel(r1, "13.0.0.0/24")
|
||||
assert result is None
|
||||
|
||||
step("Verifying routes are present on r2")
|
||||
result = check_kernel(r2, "11.0.0.0/24")
|
||||
assert result is None
|
||||
result = check_kernel(r2, "13.0.0.0/24")
|
||||
assert result is None
|
||||
|
||||
step("Verifying routes are present on r3")
|
||||
result = check_kernel(r3, "11.0.0.0/24")
|
||||
assert result is None
|
||||
result = check_kernel(r3, "12.0.0.0/24")
|
||||
assert result is None
|
114
tests/topotests/mgmt_startup/test_startup.py
Normal file
114
tests/topotests/mgmt_startup/test_startup.py
Normal file
@ -0,0 +1,114 @@
|
||||
# -*- coding: utf-8 eval: (blacken-mode 1) -*-
|
||||
# SPDX-License-Identifier: ISC
|
||||
#
|
||||
# May 2 2023, Christian Hopps <chopps@labn.net>
|
||||
#
|
||||
# Copyright (c) 2023, LabN Consulting, L.L.C.
|
||||
#
|
||||
"""
|
||||
Test static route functionality using old or new configuration files.
|
||||
|
||||
User compat:
|
||||
|
||||
- mgmtd split config will first look to `/etc/frr/zebra.conf`
|
||||
then `/etc/frr/staticd.conf` and finally `/etc/frr/mgmtd.conf`
|
||||
|
||||
- When new components are converted to mgmtd their split config should be
|
||||
added here too.
|
||||
|
||||
Topotest compat:
|
||||
|
||||
- `mgmtd.conf` is copied to `/etc/frr/` for use by mgmtd when implicit load,
|
||||
or explicit load no config specified.
|
||||
|
||||
- `staticd.conf` is copied to `/etc/frr/` for use by mgmtd when staticd
|
||||
is explicit load implict config, and explicit config.
|
||||
|
||||
"""
|
||||
|
||||
import ipaddress
|
||||
import re
|
||||
import time
|
||||
|
||||
import pytest
|
||||
from lib.common_config import create_static_routes, retry, step, verify_rib
|
||||
from lib.topogen import Topogen, TopoRouter
|
||||
from lib.topolog import logger
|
||||
|
||||
# pytestmark = [pytest.mark.staticd, pytest.mark.mgmtd]
|
||||
pytestmark = [pytest.mark.staticd]
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def tgen(request):
|
||||
"Setup/Teardown the environment and provide tgen argument to tests"
|
||||
|
||||
topodef = {
|
||||
"s1": ("r1",),
|
||||
}
|
||||
|
||||
tgen = Topogen(topodef, request.module.__name__)
|
||||
tgen.start_topology()
|
||||
|
||||
# configure mgmtd using current mgmtd config file
|
||||
tgen.gears["r1"].load_config(TopoRouter.RD_ZEBRA, "zebra.conf")
|
||||
tgen.gears["r1"].load_config(TopoRouter.RD_MGMTD)
|
||||
|
||||
# Explicit disable staticd now..
|
||||
tgen.gears["r1"].net.daemons["staticd"] = 0
|
||||
|
||||
tgen.start_router()
|
||||
yield tgen
|
||||
tgen.stop_topology()
|
||||
|
||||
|
||||
@retry(retry_timeout=3, initial_wait=0.1)
|
||||
def check_kernel(r1, prefix, expected=True):
|
||||
net = ipaddress.ip_network(prefix)
|
||||
if net.version == 6:
|
||||
kernel = r1.net.cmd_nostatus("ip -6 route show", warn=not expected)
|
||||
else:
|
||||
kernel = r1.net.cmd_nostatus("ip -4 route show", warn=not expected)
|
||||
|
||||
logger.debug("checking kernel routing table:\n%s", kernel)
|
||||
route = f"{str(net)}(?: nhid [0-9]+)?.*proto (static|196)"
|
||||
m = re.search(route, kernel)
|
||||
if expected and not m:
|
||||
return f"Failed to find \n'{route}'\n in \n'{kernel}'"
|
||||
elif not expected and m:
|
||||
return f"Failed found \n'{route}'\n in \n'{kernel}'"
|
||||
return None
|
||||
|
||||
|
||||
def test_staticd_late_start(tgen):
|
||||
if tgen.routers_have_failure():
|
||||
pytest.skip(tgen.errors)
|
||||
|
||||
# for x in ["r1"]:
|
||||
# tgen.gears[x].net.cmd_nostatus(
|
||||
# "vtysh -c 'debug mgmt client frontend' "
|
||||
# "-c 'debug mgmt client backend' "
|
||||
# "-c 'debug mgmt backend frontend datastore transaction'"
|
||||
# )
|
||||
|
||||
r1 = tgen.routers()["r1"]
|
||||
|
||||
step("Verifying startup route is not present w/o staticd running")
|
||||
result = check_kernel(r1, "12.0.0.0/24", expected=False)
|
||||
assert result is not None
|
||||
|
||||
step("Configure another static route verify is not present w/o staticd running")
|
||||
r1.net.cmd_nostatus("vtysh -c 'config t' -c 'ip route 12.1.0.0/24 101.0.0.2'")
|
||||
result = check_kernel(r1, "12.0.0.0/24", expected=False)
|
||||
assert result is not None
|
||||
result = check_kernel(r1, "12.1.0.0/24", expected=False)
|
||||
assert result is not None
|
||||
|
||||
step("Starting staticd")
|
||||
r1.startDaemons(["staticd"])
|
||||
|
||||
step("Verifying both routes are present")
|
||||
result = check_kernel(r1, "12.0.0.0/24")
|
||||
assert result is None
|
||||
result = check_kernel(r1, "12.1.0.0/24")
|
||||
assert result is None
|
Loading…
Reference in New Issue
Block a user