mirror_frr/tests/topotests/mgmt_config/test_config.py
Nathan Bahr ba0a6868e5 test: Fix tests for zebra changes
Remove use of `ip multicast rpf-lookup-mode` from unrelated tests.
Looks like this test was just unlucky enough to pick that command as an
example for use here. Just changed it to something less likely to be
removed in the future.
Update route table output to include AFI SAFI output.

Signed-off-by: Nathan Bahr <nbahr@atcorp.com>
2024-12-12 13:50:31 +00:00

373 lines
13 KiB
Python

# -*- coding: utf-8 eval: (blacken-mode 1) -*-
# SPDX-License-Identifier: ISC
#
# June 10 2023, Christian Hopps <chopps@labn.net>
#
# Copyright (c) 2023, LabN Consulting, L.L.C.
#
"""
Test mgmtd parsing of configs.
So:
MGMTD matches zebra:
one exit file: ONE: vty -f file
one exit redir: ONE: vty < file
early exit file: ONE: vty -f file
early exit redir: ONE: vty < file
early end file: ALL: vty -f file
early end redir: ONE: vty < file
Raw tests:
FAILED mgmt_config/test_config.py::test_mgmtd_one_exit_file - AssertionError: vtysh < didn't work after exit
FAILED mgmt_config/test_config.py::test_mgmtd_one_exit_redir - AssertionError: vtysh < didn't work after exit
FAILED mgmt_config/test_config.py::test_mgmtd_early_exit_file - AssertionError: vtysh -f didn't work after 1 exit
FAILED mgmt_config/test_config.py::test_mgmtd_early_exit_redir - AssertionError: vtysh < didn't work after 1 exits
FAILED mgmt_config/test_config.py::test_mgmtd_early_end_redir - AssertionError: vtysh < didn't work after 1 end
FAILED mgmt_config/test_config.py::test_zebra_one_exit_file - AssertionError: zebra second conf missing
FAILED mgmt_config/test_config.py::test_zebra_one_exit_redir - AssertionError: zebra second conf missing
FAILED mgmt_config/test_config.py::test_zebra_early_exit_file - AssertionError: zebra second conf missing
FAILED mgmt_config/test_config.py::test_zebra_early_exit_redir - AssertionError: zebra second conf missing
FAILED mgmt_config/test_config.py::test_zebra_early_end_redir - AssertionError: zebra second conf missing
Before fixed:
one exit file: NONE: vty -f file
early exit file: NONE: vty -f file
FAILED mgmt_config/test_config.py::test_mgmtd_one_exit_file - AssertionError: vtysh -f didn't work before exit
FAILED mgmt_config/test_config.py::test_mgmtd_one_exit_redir - AssertionError: vtysh < didn't work after exit
FAILED mgmt_config/test_config.py::test_mgmtd_early_exit_file - AssertionError: vtysh -f didn't work before exit
FAILED mgmt_config/test_config.py::test_mgmtd_early_exit_redir - AssertionError: vtysh < didn't work after 1 exits
FAILED mgmt_config/test_config.py::test_mgmtd_early_end_redir - AssertionError: vtysh < didn't work after 1 end
FAILED mgmt_config/test_config.py::test_zebra_one_exit_file - AssertionError: zebra second conf missing
FAILED mgmt_config/test_config.py::test_zebra_one_exit_redir - AssertionError: zebra second conf missing
FAILED mgmt_config/test_config.py::test_zebra_early_exit_file - AssertionError: zebra second conf missing
FAILED mgmt_config/test_config.py::test_zebra_early_exit_redir - AssertionError: zebra second conf missing
FAILED mgmt_config/test_config.py::test_zebra_early_end_redir - AssertionError: zebra second conf missing
"""
import ipaddress
import logging
import os
import re
from pathlib import Path
import pytest
from lib.common_config import retry, step
from lib.topogen import Topogen, TopoRouter
pytestmark = [pytest.mark.staticd, pytest.mark.mgmtd]
@retry(retry_timeout=1, initial_wait=0.1)
def check_kernel(r1, prefix, expected=True):
net = ipaddress.ip_network(prefix)
if net.version == 6:
kernel = r1.cmd_nostatus("ip -6 route show", warn=not expected)
else:
kernel = r1.cmd_nostatus("ip -4 route show", warn=not expected)
logging.debug("checking kernel routing table:\n%0.1920s", 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:.1920}'"
elif not expected and m:
return f"Failed found \n'{route}'\n in \n'{kernel:.1920}'"
return None
@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)
tgen.start_router()
yield tgen
tgen.stop_topology()
def save_log_snippet(logfile, content, savepath=None):
os.sync()
os.sync()
os.sync()
with open(logfile, encoding="utf-8") as f:
buf = f.read()
assert content == buf[: len(content)]
newcontent = buf[len(content) :]
if savepath:
with open(savepath, "w", encoding="utf-8") as f:
f.write(newcontent)
return buf
def mapname(lname):
return lname.replace(".conf", "") + "-log.txt"
logbuf = ""
@pytest.fixture(scope="module")
def r1(tgen):
return tgen.gears["r1"].net
@pytest.fixture(scope="module")
def confdir():
return Path(os.environ["PYTEST_TOPOTEST_SCRIPTDIR"]) / "r1"
@pytest.fixture(scope="module")
def tempdir(r1):
return Path(r1.rundir)
@pytest.fixture(scope="module")
def logpath(tempdir):
return tempdir / "mgmtd.log"
@pytest.fixture(autouse=True, scope="function")
def cleanup_config(r1, tempdir, logpath):
global logbuf
logbuf = save_log_snippet(logpath, logbuf, "/dev/null")
yield
r1.cmd_nostatus("vtysh -c 'conf t' -c 'no allow-external-route-update'")
r1.cmd_nostatus("vtysh -c 'conf t' -c 'no router-id 1.2.3.4'")
r1.cmd_nostatus("vtysh -c 'conf t' -c 'no ip table range 2 3'")
logbuf = save_log_snippet(logpath, logbuf, "/dev/null")
def test_staticd_startup(r1):
r1.cmd_nostatus(
"vtysh -c 'debug mgmt client frontend' "
"-c 'debug mgmt client backend' "
"-c 'debug mgmt backend frontend datastore transaction'"
)
step("Verifying routes are present on r1")
result = check_kernel(r1, "12.0.0.0/24", retry_timeout=3.0)
assert result is None
def test_mgmtd_one_exit_file(r1, confdir, tempdir, logpath):
global logbuf
conf = "one-exit.conf"
step(f"load {conf} file with vtysh -f ")
output = r1.cmd_nostatus(f"vtysh -f {confdir / conf}")
logbuf = save_log_snippet(logpath, logbuf, tempdir / mapname(conf))
print(output)
result1 = check_kernel(r1, "20.1.0.0/24")
result2 = check_kernel(r1, "20.2.0.0/24")
assert result1 is None, "vtysh -f didn't work before exit"
assert result2 is not None, "vtysh < worked after exit, unexpected"
def test_mgmtd_one_exit_redir(r1, confdir, tempdir, logpath):
global logbuf
conf = "one-exit2.conf"
step(f"Redirect {conf} file into vtysh")
output = r1.cmd_nostatus(f"vtysh < {confdir / conf}")
logbuf = save_log_snippet(logpath, logbuf, tempdir / mapname(conf))
print(output)
result1 = check_kernel(r1, "21.1.0.0/24")
result2 = check_kernel(r1, "21.2.0.0/24")
assert result1 is None, "vtysh < didn't work before exit"
assert result2 is not None, "vtysh < worked after exit, unexpected"
def test_mgmtd_early_exit_file(r1, confdir, tempdir, logpath):
global logbuf
conf = "early-exit.conf"
step(f"load {conf} file with vtysh -f ")
output = r1.cmd_nostatus(f"vtysh -f {confdir / conf}")
logbuf = save_log_snippet(logpath, logbuf, tempdir / mapname(conf))
print(output)
result1 = check_kernel(r1, "13.1.0.0/24")
result2 = check_kernel(r1, "13.2.0.0/24")
result3 = check_kernel(r1, "13.3.0.0/24")
assert result1 is None, "vtysh -f didn't work before exit"
assert result2 is not None, "vtysh -f worked after 1 exit, unexpected"
assert result3 is not None, "vtysh -f worked after 2 exit, unexpected"
def test_mgmtd_early_exit_redir(r1, confdir, tempdir, logpath):
global logbuf
conf = "early-exit2.conf"
step(f"Redirect {conf} file into vtysh")
output = r1.cmd_nostatus(f"vtysh < {confdir / conf}")
logbuf = save_log_snippet(logpath, logbuf, tempdir / mapname(conf))
print(output)
result1 = check_kernel(r1, "14.1.0.0/24")
result2 = check_kernel(r1, "14.2.0.0/24")
result3 = check_kernel(r1, "14.3.0.0/24")
assert result1 is None, "vtysh < didn't work before exit"
assert result2 is not None, "vtysh < worked after 1 exits, unexpected"
assert result3 is not None, "vtysh < worked after 2 exits, unexpected"
def test_mgmtd_early_end_file(r1, confdir, tempdir, logpath):
global logbuf
conf = "early-end.conf"
step(f"load {conf} file with vtysh -f ")
output = r1.cmd_nostatus(f"vtysh -f {confdir / conf}")
logbuf = save_log_snippet(logpath, logbuf, tempdir / mapname(conf))
print(output)
result1 = check_kernel(r1, "15.1.0.0/24")
result2 = check_kernel(r1, "15.2.0.0/24")
result3 = check_kernel(r1, "15.3.0.0/24")
assert result1 is None, "vtysh -f didn't work before end"
assert result2 is None, "vtysh -f didn't work after 1 end"
assert result3 is None, "vtysh -f didn't work after 2 ends"
def test_mgmtd_early_end_redir(r1, confdir, tempdir, logpath):
global logbuf
conf = "early-end2.conf"
step(f"Redirect {conf} file into vtysh")
output = r1.cmd_nostatus(f"vtysh < {confdir / conf}")
logbuf = save_log_snippet(logpath, logbuf, tempdir / mapname(conf))
print(output)
result1 = check_kernel(r1, "16.1.0.0/24")
result2 = check_kernel(r1, "16.2.0.0/24")
result3 = check_kernel(r1, "16.3.0.0/24")
assert result1 is None, "vtysh < didn't work before end"
assert result2 is not None, "vtysh < worked after 1 end, unexpected"
assert result3 is not None, "vtysh < worked after 2 end, unexpected"
#
# Zebra
#
def test_zebra_one_exit_file(r1, confdir, tempdir, logpath):
global logbuf
conf = "one-exit-zebra.conf"
step(f"load {conf} file with vtysh -f ")
output = r1.cmd_nostatus(f"vtysh -f {confdir / conf}")
logbuf = save_log_snippet(logpath, logbuf, tempdir / mapname(conf))
print(output)
showrun = r1.cmd_nostatus("vtysh -c 'show running'")
assert "allow-external-route-update" in showrun, "zebra conf missing"
assert "router-id 1.2.3.4" not in showrun, "zebra second conf present, unexpected"
def test_zebra_one_exit_redir(r1, confdir, tempdir, logpath):
global logbuf
conf = "one-exit2-zebra.conf"
step(f"Redirect {conf} file into vtysh")
output = r1.cmd_nostatus(f"vtysh < {confdir / conf}")
logbuf = save_log_snippet(logpath, logbuf, tempdir / mapname(conf))
print(output)
showrun = r1.cmd_nostatus("vtysh -c 'show running'")
assert "allow-external-route-update" in showrun, "zebra conf missing"
assert "router-id 1.2.3.4" not in showrun, "zebra second conf present, unexpected"
def test_zebra_early_exit_file(r1, confdir, tempdir, logpath):
global logbuf
conf = "early-exit-zebra.conf"
step(f"load {conf} file with vtysh -f ")
output = r1.cmd_nostatus(f"vtysh -f {confdir / conf}")
logbuf = save_log_snippet(logpath, logbuf, tempdir / mapname(conf))
print(output)
showrun = r1.cmd_nostatus("vtysh -c 'show running'")
assert "allow-external-route-update" in showrun, "zebra conf missing"
assert "router-id 1.2.3.4" not in showrun, "zebra second conf present, unexpected"
assert "ip table range 2 3" not in showrun, "zebra third conf present, unexpected"
def test_zebra_early_exit_redir(r1, confdir, tempdir, logpath):
global logbuf
conf = "early-exit2-zebra.conf"
step(f"Redirect {conf} file into vtysh")
output = r1.cmd_nostatus(f"vtysh < {confdir / conf}")
logbuf = save_log_snippet(logpath, logbuf, tempdir / mapname(conf))
print(output)
showrun = r1.cmd_nostatus("vtysh -c 'show running'")
assert "allow-external-route-update" in showrun, "zebra conf missing"
assert "router-id 1.2.3.4" not in showrun, "zebra second conf present, unexpected"
assert "ip table range 2 3" not in showrun, "zebra third conf present, unexpected"
def test_zebra_early_end_file(r1, confdir, tempdir, logpath):
global logbuf
conf = "early-end-zebra.conf"
step(f"load {conf} file with vtysh -f ")
output = r1.cmd_nostatus(f"vtysh -f {confdir / conf}")
logbuf = save_log_snippet(logpath, logbuf, tempdir / mapname(conf))
print(output)
showrun = r1.cmd_nostatus("vtysh -c 'show running'")
assert "allow-external-route-update" in showrun, "zebra conf missing"
assert "router-id 1.2.3.4" in showrun, "zebra second conf missing"
assert "ip table range 2 3" in showrun, "zebra third missing"
def test_zebra_early_end_redir(r1, confdir, tempdir, logpath):
global logbuf
conf = "early-end2-zebra.conf"
step(f"Redirect {conf} file into vtysh")
output = r1.cmd_nostatus(f"vtysh < {confdir / conf}")
logbuf = save_log_snippet(logpath, logbuf, tempdir / mapname(conf))
print(output)
showrun = r1.cmd_nostatus("vtysh -c 'show running'")
assert "allow-external-route-update" in showrun, "zebra conf missing"
assert "router-id 1.2.3.4" not in showrun, "zebra second conf present, unexpected"
assert "ip table range 2 3" not in showrun, "zebra third conf present, unexpected"