mirror of
https://git.proxmox.com/git/mirror_frr
synced 2026-01-04 13:42:56 +00:00
tests: cleanup access to pytest config
Rather than create a new global dict and copy all the config into it, just expose the pytest config globally and use it directly. Signed-off-by: Christian Hopps <chopps@labn.net>
This commit is contained in:
parent
7592b2ccae
commit
249ac6f0f2
@ -1,3 +1,4 @@
|
||||
# -*- coding: utf-8 eval: (blacken-mode 1) -*-
|
||||
"""
|
||||
Topotest conftest.py file.
|
||||
"""
|
||||
@ -5,7 +6,6 @@ Topotest conftest.py file.
|
||||
|
||||
import glob
|
||||
import os
|
||||
import pdb
|
||||
import re
|
||||
import resource
|
||||
import subprocess
|
||||
@ -14,16 +14,16 @@ import time
|
||||
|
||||
import lib.fixtures
|
||||
import pytest
|
||||
from lib.micronet_compat import Mininet
|
||||
from lib.micronet_compat import ConfigOptionsProxy, Mininet
|
||||
from lib.topogen import diagnose_env, get_topogen
|
||||
from lib.topolog import logger
|
||||
from lib.topotest import g_extra_config as topotest_extra_config
|
||||
from lib.topotest import json_cmp_result
|
||||
from munet import cli
|
||||
from munet.base import Commander, proc_error
|
||||
from munet.cleanup import cleanup_current, cleanup_previous
|
||||
from munet.testing.util import pause_test
|
||||
|
||||
from lib import topolog
|
||||
from lib import topolog, topotest
|
||||
|
||||
|
||||
def pytest_addoption(parser):
|
||||
@ -135,7 +135,7 @@ def pytest_addoption(parser):
|
||||
|
||||
|
||||
def check_for_memleaks():
|
||||
assert topotest_extra_config["valgrind_memleaks"]
|
||||
assert topotest.g_pytest_config.option.valgrind_memleaks
|
||||
|
||||
leaks = []
|
||||
tgen = get_topogen() # pylint: disable=redefined-outer-name
|
||||
@ -179,16 +179,15 @@ def check_for_memleaks():
|
||||
|
||||
@pytest.fixture(autouse=True, scope="module")
|
||||
def module_check_memtest(request):
|
||||
del request # disable unused warning
|
||||
yield
|
||||
if topotest_extra_config["valgrind_memleaks"]:
|
||||
if request.config.option.valgrind_memleaks:
|
||||
if get_topogen() is not None:
|
||||
check_for_memleaks()
|
||||
|
||||
|
||||
def pytest_runtest_logstart(nodeid, location):
|
||||
# location is (filename, lineno, testname)
|
||||
topolog.logstart(nodeid, location, topotest_extra_config["rundir"])
|
||||
topolog.logstart(nodeid, location, topotest.g_pytest_config.option.rundir)
|
||||
|
||||
|
||||
def pytest_runtest_logfinish(nodeid, location):
|
||||
@ -199,10 +198,9 @@ def pytest_runtest_logfinish(nodeid, location):
|
||||
@pytest.hookimpl(hookwrapper=True)
|
||||
def pytest_runtest_call(item: pytest.Item) -> None:
|
||||
"Hook the function that is called to execute the test."
|
||||
del item # disable unused warning
|
||||
|
||||
# For topology only run the CLI then exit
|
||||
if topotest_extra_config["topology_only"]:
|
||||
if item.config.option.topology_only:
|
||||
get_topogen().cli()
|
||||
pytest.exit("exiting after --topology-only")
|
||||
|
||||
@ -210,7 +208,7 @@ def pytest_runtest_call(item: pytest.Item) -> None:
|
||||
yield
|
||||
|
||||
# Check for leaks if requested
|
||||
if topotest_extra_config["valgrind_memleaks"]:
|
||||
if item.config.option.valgrind_memleaks:
|
||||
check_for_memleaks()
|
||||
|
||||
|
||||
@ -233,6 +231,7 @@ def pytest_configure(config):
|
||||
"""
|
||||
Assert that the environment is correctly configured, and get extra config.
|
||||
"""
|
||||
topotest.g_pytest_config = ConfigOptionsProxy(config)
|
||||
|
||||
if config.getoption("--collect-only"):
|
||||
return
|
||||
@ -254,11 +253,13 @@ def pytest_configure(config):
|
||||
# Set some defaults for the pytest.ini [pytest] section
|
||||
# ---------------------------------------------------
|
||||
|
||||
rundir = config.getoption("--rundir")
|
||||
rundir = config.option.rundir
|
||||
if not rundir:
|
||||
rundir = config.getini("rundir")
|
||||
if not rundir:
|
||||
rundir = "/tmp/topotests"
|
||||
config.option.rundir = rundir
|
||||
|
||||
if not config.getoption("--junitxml"):
|
||||
config.option.xmlpath = os.path.join(rundir, "topotests.xml")
|
||||
xmlpath = config.option.xmlpath
|
||||
@ -271,8 +272,6 @@ def pytest_configure(config):
|
||||
mv_path = commander.get_exec_path("mv")
|
||||
commander.cmd_status([mv_path, xmlpath, xmlpath + suffix])
|
||||
|
||||
topotest_extra_config["rundir"] = rundir
|
||||
|
||||
# Set the log_file (exec) to inside the rundir if not specified
|
||||
if not config.getoption("--log-file") and not config.getini("log_file"):
|
||||
config.option.log_file = os.path.join(rundir, "exec.log")
|
||||
@ -302,69 +301,19 @@ def pytest_configure(config):
|
||||
elif b and not is_xdist and not have_windows:
|
||||
pytest.exit("{} use requires byobu/TMUX/SCREEN/XTerm".format(feature))
|
||||
|
||||
# ---------------------------------------
|
||||
# Record our options in global dictionary
|
||||
# ---------------------------------------
|
||||
#
|
||||
# Check for window capability if given options that require window
|
||||
#
|
||||
assert_feature_windows(config.option.gdb_routers, "GDB")
|
||||
assert_feature_windows(config.option.gdb_daemons, "GDB")
|
||||
assert_feature_windows(config.option.cli_on_error, "--cli-on-error")
|
||||
assert_feature_windows(config.option.shell, "--shell")
|
||||
assert_feature_windows(config.option.shell_on_error, "--shell-on-error")
|
||||
assert_feature_windows(config.option.vtysh, "--vtysh")
|
||||
assert_feature_windows(config.option.vtysh_on_error, "--vtysh-on-error")
|
||||
|
||||
topotest_extra_config["rundir"] = rundir
|
||||
|
||||
asan_abort = config.getoption("--asan-abort")
|
||||
topotest_extra_config["asan_abort"] = asan_abort
|
||||
|
||||
gdb_routers = config.getoption("--gdb-routers")
|
||||
gdb_routers = gdb_routers.split(",") if gdb_routers else []
|
||||
topotest_extra_config["gdb_routers"] = gdb_routers
|
||||
|
||||
gdb_daemons = config.getoption("--gdb-daemons")
|
||||
gdb_daemons = gdb_daemons.split(",") if gdb_daemons else []
|
||||
topotest_extra_config["gdb_daemons"] = gdb_daemons
|
||||
assert_feature_windows(gdb_routers or gdb_daemons, "GDB")
|
||||
|
||||
gdb_breakpoints = config.getoption("--gdb-breakpoints")
|
||||
gdb_breakpoints = gdb_breakpoints.split(",") if gdb_breakpoints else []
|
||||
topotest_extra_config["gdb_breakpoints"] = gdb_breakpoints
|
||||
|
||||
cli_on_error = config.getoption("--cli-on-error")
|
||||
topotest_extra_config["cli_on_error"] = cli_on_error
|
||||
assert_feature_windows(cli_on_error, "--cli-on-error")
|
||||
|
||||
shell = config.getoption("--shell")
|
||||
topotest_extra_config["shell"] = shell.split(",") if shell else []
|
||||
assert_feature_windows(shell, "--shell")
|
||||
|
||||
strace = config.getoption("--strace-daemons")
|
||||
topotest_extra_config["strace_daemons"] = strace.split(",") if strace else []
|
||||
|
||||
shell_on_error = config.getoption("--shell-on-error")
|
||||
topotest_extra_config["shell_on_error"] = shell_on_error
|
||||
assert_feature_windows(shell_on_error, "--shell-on-error")
|
||||
|
||||
topotest_extra_config["valgrind_extra"] = config.getoption("--valgrind-extra")
|
||||
topotest_extra_config["valgrind_memleaks"] = config.getoption("--valgrind-memleaks")
|
||||
|
||||
vtysh = config.getoption("--vtysh")
|
||||
topotest_extra_config["vtysh"] = vtysh.split(",") if vtysh else []
|
||||
assert_feature_windows(vtysh, "--vtysh")
|
||||
|
||||
vtysh_on_error = config.getoption("--vtysh-on-error")
|
||||
topotest_extra_config["vtysh_on_error"] = vtysh_on_error
|
||||
assert_feature_windows(vtysh_on_error, "--vtysh-on-error")
|
||||
|
||||
pause_on_error = vtysh or shell or config.getoption("--pause-on-error")
|
||||
if config.getoption("--no-pause-on-error"):
|
||||
pause_on_error = False
|
||||
|
||||
topotest_extra_config["pause_on_error"] = pause_on_error
|
||||
assert_feature_windows(pause_on_error, "--pause-on-error")
|
||||
|
||||
pause = config.getoption("--pause")
|
||||
topotest_extra_config["pause"] = pause
|
||||
assert_feature_windows(pause, "--pause")
|
||||
|
||||
topology_only = config.getoption("--topology-only")
|
||||
if topology_only and is_xdist:
|
||||
if config.option.topology_only and is_xdist:
|
||||
pytest.exit("Cannot use --topology-only with distributed test mode")
|
||||
topotest_extra_config["topology_only"] = topology_only
|
||||
|
||||
# Check environment now that we have config
|
||||
if not diagnose_env(rundir):
|
||||
@ -430,10 +379,7 @@ def pytest_runtest_makereport(item, call):
|
||||
# We want to pause, if requested, on any error not just test cases
|
||||
# (e.g., call.when == "setup")
|
||||
if not pause:
|
||||
pause = (
|
||||
topotest_extra_config["pause_on_error"]
|
||||
or topotest_extra_config["pause"]
|
||||
)
|
||||
pause = item.config.option.pause_on_error or item.config.option.pause
|
||||
|
||||
# (topogen) Set topology error to avoid advancing in the test.
|
||||
tgen = get_topogen() # pylint: disable=redefined-outer-name
|
||||
@ -445,9 +391,9 @@ def pytest_runtest_makereport(item, call):
|
||||
isatty = sys.stdout.isatty()
|
||||
error_cmd = None
|
||||
|
||||
if error and topotest_extra_config["vtysh_on_error"]:
|
||||
if error and item.config.option.vtysh_on_error:
|
||||
error_cmd = commander.get_exec_path(["vtysh"])
|
||||
elif error and topotest_extra_config["shell_on_error"]:
|
||||
elif error and item.config.option.shell_on_error:
|
||||
error_cmd = os.getenv("SHELL", commander.get_exec_path(["bash"]))
|
||||
|
||||
if error_cmd:
|
||||
@ -499,7 +445,7 @@ def pytest_runtest_makereport(item, call):
|
||||
if p.wait():
|
||||
logger.warning("xterm proc failed: %s:", proc_error(p, o, e))
|
||||
|
||||
if error and topotest_extra_config["cli_on_error"]:
|
||||
if error and item.config.option.cli_on_error:
|
||||
# Really would like something better than using this global here.
|
||||
# Not all tests use topogen though so get_topogen() won't work.
|
||||
if Mininet.g_mnet_inst:
|
||||
@ -507,23 +453,8 @@ def pytest_runtest_makereport(item, call):
|
||||
else:
|
||||
logger.error("Could not launch CLI b/c no mininet exists yet")
|
||||
|
||||
while pause and isatty:
|
||||
try:
|
||||
user = raw_input(
|
||||
'PAUSED, "cli" for CLI, "pdb" to debug, "Enter" to continue: '
|
||||
)
|
||||
except NameError:
|
||||
user = input('PAUSED, "cli" for CLI, "pdb" to debug, "Enter" to continue: ')
|
||||
user = user.strip()
|
||||
|
||||
if user == "cli":
|
||||
cli.cli(Mininet.g_mnet_inst)
|
||||
elif user == "pdb":
|
||||
pdb.set_trace() # pylint: disable=forgotten-debug-statement
|
||||
elif user:
|
||||
print('Unrecognized input: "%s"' % user)
|
||||
else:
|
||||
break
|
||||
if pause and isatty:
|
||||
pause_test()
|
||||
|
||||
|
||||
#
|
||||
|
||||
@ -12,6 +12,49 @@ from munet import cli
|
||||
from munet.base import BaseMunet, LinuxNamespace
|
||||
|
||||
|
||||
def cli_opt_list(option_list):
|
||||
if not option_list:
|
||||
return []
|
||||
if isinstance(option_list, str):
|
||||
return [x for x in option_list.split(",") if x]
|
||||
return [x for x in option_list if x]
|
||||
|
||||
|
||||
def name_in_cli_opt_str(name, option_list):
|
||||
ol = cli_opt_list(option_list)
|
||||
return name in ol or "all" in ol
|
||||
|
||||
|
||||
class ConfigOptionsProxy:
|
||||
def __init__(self, pytestconfig=None):
|
||||
if isinstance(pytestconfig, ConfigOptionsProxy):
|
||||
self.config = pytestconfig.config
|
||||
else:
|
||||
self.config = pytestconfig
|
||||
self.option = self.config.option
|
||||
|
||||
def getoption(self, opt, defval=None):
|
||||
if not self.config:
|
||||
return defval
|
||||
|
||||
value = self.config.getoption(opt)
|
||||
if value is None:
|
||||
return defval
|
||||
|
||||
return value
|
||||
|
||||
def get_option(self, opt, defval=None):
|
||||
return self.getoption(opt, defval)
|
||||
|
||||
def get_option_list(self, opt):
|
||||
value = self.get_option(opt, "")
|
||||
return cli_opt_list(value)
|
||||
|
||||
def name_in_option_list(self, name, opt):
|
||||
optlist = self.get_option_list(opt)
|
||||
return "all" in optlist or name in optlist
|
||||
|
||||
|
||||
class Node(LinuxNamespace):
|
||||
"""Node (mininet compat)."""
|
||||
|
||||
@ -120,7 +163,7 @@ class Mininet(BaseMunet):
|
||||
|
||||
g_mnet_inst = None
|
||||
|
||||
def __init__(self, rundir=None):
|
||||
def __init__(self, rundir=None, pytestconfig=None):
|
||||
"""
|
||||
Create a Micronet.
|
||||
"""
|
||||
@ -132,6 +175,8 @@ class Mininet(BaseMunet):
|
||||
self.host_params = {}
|
||||
self.prefix_len = 8
|
||||
|
||||
self.cfgopt = ConfigOptionsProxy(pytestconfig)
|
||||
|
||||
# SNMPd used to require this, which was set int he mininet shell
|
||||
# that all commands executed from. This is goofy default so let's not
|
||||
# do it if we don't have to. The snmpd.conf files have been updated
|
||||
@ -268,12 +313,9 @@ ff02::2\tip6-allrouters
|
||||
|
||||
cli.add_cli_config(self, cdict)
|
||||
|
||||
# shellopt = (
|
||||
# self.pytest_config.getoption("--shell") if self.pytest_config else None
|
||||
# )
|
||||
# shellopt = shellopt if shellopt is not None else ""
|
||||
# if shellopt == "all" or "." in shellopt.split(","):
|
||||
# self.run_in_window("bash")
|
||||
shellopt = self.cfgopt.get_option_list("--shell")
|
||||
if "all" in shellopt or "." in shellopt:
|
||||
self.run_in_window("bash")
|
||||
|
||||
# This is expected by newer munet CLI code
|
||||
self.config_dirname = ""
|
||||
|
||||
@ -43,7 +43,6 @@ import lib.topolog as topolog
|
||||
from lib.micronet import Commander
|
||||
from lib.micronet_compat import Mininet
|
||||
from lib.topolog import logger
|
||||
from lib.topotest import g_extra_config
|
||||
|
||||
from lib import topotest
|
||||
|
||||
@ -189,7 +188,7 @@ class Topogen(object):
|
||||
self._load_config()
|
||||
|
||||
# Create new log directory
|
||||
self.logdir = topotest.get_logs_path(g_extra_config["rundir"])
|
||||
self.logdir = topotest.get_logs_path(topotest.g_pytest_config.option.rundir)
|
||||
subprocess.check_call(
|
||||
"mkdir -p {0} && chmod 1777 {0}".format(self.logdir), shell=True
|
||||
)
|
||||
@ -209,7 +208,7 @@ class Topogen(object):
|
||||
# Mininet(Micronet) to build the actual topology.
|
||||
assert not inspect.isclass(topodef)
|
||||
|
||||
self.net = Mininet(rundir=self.logdir)
|
||||
self.net = Mininet(rundir=self.logdir, pytestconfig=topotest.g_pytest_config)
|
||||
|
||||
# Adjust the parent namespace
|
||||
topotest.fix_netns_limits(self.net)
|
||||
|
||||
@ -9,13 +9,13 @@
|
||||
# Network Device Education Foundation, Inc. ("NetDEF")
|
||||
#
|
||||
|
||||
import configparser
|
||||
import difflib
|
||||
import errno
|
||||
import functools
|
||||
import glob
|
||||
import json
|
||||
import os
|
||||
import pdb
|
||||
import platform
|
||||
import re
|
||||
import resource
|
||||
@ -24,22 +24,16 @@ import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import time
|
||||
from collections.abc import Mapping
|
||||
from copy import deepcopy
|
||||
|
||||
import lib.topolog as topolog
|
||||
from lib.micronet_compat import Node
|
||||
from lib.topolog import logger
|
||||
|
||||
if sys.version_info[0] > 2:
|
||||
import configparser
|
||||
from collections.abc import Mapping
|
||||
else:
|
||||
import ConfigParser as configparser
|
||||
from collections import Mapping
|
||||
|
||||
from lib import micronet
|
||||
from lib.micronet_compat import Node
|
||||
|
||||
g_extra_config = {}
|
||||
g_pytest_config = None
|
||||
|
||||
|
||||
def get_logs_path(rundir):
|
||||
@ -1339,7 +1333,7 @@ class Router(Node):
|
||||
# specified, then attempt to generate an unique logdir.
|
||||
self.logdir = params.get("logdir")
|
||||
if self.logdir is None:
|
||||
self.logdir = get_logs_path(g_extra_config["rundir"])
|
||||
self.logdir = get_logs_path(g_pytest_config.getoption("--rundir"))
|
||||
|
||||
if not params.get("logger"):
|
||||
# If logger is present topogen has already set this up
|
||||
@ -1532,7 +1526,7 @@ class Router(Node):
|
||||
)
|
||||
except Exception as ex:
|
||||
logger.error("%s can't remove IPs %s", self, str(ex))
|
||||
# pdb.set_trace()
|
||||
# breakpoint()
|
||||
# assert False, "can't remove IPs %s" % str(ex)
|
||||
|
||||
def checkCapability(self, daemon, param):
|
||||
@ -1598,10 +1592,7 @@ class Router(Node):
|
||||
|
||||
if (daemon == "zebra") and (self.daemons["mgmtd"] == 0):
|
||||
# Add mgmtd with zebra - if it exists
|
||||
try:
|
||||
mgmtd_path = os.path.join(self.daemondir, "mgmtd")
|
||||
except:
|
||||
pdb.set_trace()
|
||||
mgmtd_path = os.path.join(self.daemondir, "mgmtd")
|
||||
if os.path.isfile(mgmtd_path):
|
||||
self.daemons["mgmtd"] = 1
|
||||
self.daemons_options["mgmtd"] = ""
|
||||
@ -1609,11 +1600,7 @@ class Router(Node):
|
||||
|
||||
if (daemon == "zebra") and (self.daemons["staticd"] == 0):
|
||||
# Add staticd with zebra - if it exists
|
||||
try:
|
||||
staticd_path = os.path.join(self.daemondir, "staticd")
|
||||
except:
|
||||
pdb.set_trace()
|
||||
|
||||
staticd_path = os.path.join(self.daemondir, "staticd")
|
||||
if os.path.isfile(staticd_path):
|
||||
self.daemons["staticd"] = 1
|
||||
self.daemons_options["staticd"] = ""
|
||||
@ -1688,8 +1675,7 @@ class Router(Node):
|
||||
# used
|
||||
self.cmd("echo 100000 > /proc/sys/net/mpls/platform_labels")
|
||||
|
||||
shell_routers = g_extra_config["shell"]
|
||||
if "all" in shell_routers or self.name in shell_routers:
|
||||
if g_pytest_config.name_in_option_list(self.name, "--shell"):
|
||||
self.run_in_window(os.getenv("SHELL", "bash"), title="sh-%s" % self.name)
|
||||
|
||||
if self.daemons["eigrpd"] == 1:
|
||||
@ -1706,8 +1692,7 @@ class Router(Node):
|
||||
|
||||
status = self.startRouterDaemons(tgen=tgen)
|
||||
|
||||
vtysh_routers = g_extra_config["vtysh"]
|
||||
if "all" in vtysh_routers or self.name in vtysh_routers:
|
||||
if g_pytest_config.name_in_option_list(self.name, "--vtysh"):
|
||||
self.run_in_window("vtysh", title="vt-%s" % self.name)
|
||||
|
||||
if self.unified_config:
|
||||
@ -1727,13 +1712,13 @@ class Router(Node):
|
||||
def startRouterDaemons(self, daemons=None, tgen=None):
|
||||
"Starts FRR daemons for this router."
|
||||
|
||||
asan_abort = g_extra_config["asan_abort"]
|
||||
gdb_breakpoints = g_extra_config["gdb_breakpoints"]
|
||||
gdb_daemons = g_extra_config["gdb_daemons"]
|
||||
gdb_routers = g_extra_config["gdb_routers"]
|
||||
valgrind_extra = g_extra_config["valgrind_extra"]
|
||||
valgrind_memleaks = g_extra_config["valgrind_memleaks"]
|
||||
strace_daemons = g_extra_config["strace_daemons"]
|
||||
asan_abort = bool(g_pytest_config.option.asan_abort)
|
||||
gdb_breakpoints = g_pytest_config.get_option_list("--gdb-breakpoints")
|
||||
gdb_daemons = g_pytest_config.get_option_list("--gdb-daemons")
|
||||
gdb_routers = g_pytest_config.get_option_list("--gdb-routers")
|
||||
valgrind_extra = bool(g_pytest_config.option.valgrind_extra)
|
||||
valgrind_memleaks = bool(g_pytest_config.option.valgrind_memleaks)
|
||||
strace_daemons = g_pytest_config.get_option_list("--strace-daemons")
|
||||
|
||||
# Get global bundle data
|
||||
if not self.path_exists("/etc/frr/support_bundle_commands.conf"):
|
||||
@ -1757,7 +1742,7 @@ class Router(Node):
|
||||
self.reportCores = True
|
||||
|
||||
# XXX: glue code forward ported from removed function.
|
||||
if self.version == None:
|
||||
if self.version is None:
|
||||
self.version = self.cmd(
|
||||
os.path.join(self.daemondir, "bgpd") + " -v"
|
||||
).split()[2]
|
||||
|
||||
Loading…
Reference in New Issue
Block a user