mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-07 20:34:33 +00:00
Merge pull request #13361 from LabNConsulting/chopps/munet-cfgopt-and-native
cfgopt in munet and native config support and example
This commit is contained in:
commit
766fcb6056
@ -5,6 +5,7 @@ Topotest conftest.py file.
|
|||||||
# pylint: disable=consider-using-f-string
|
# pylint: disable=consider-using-f-string
|
||||||
|
|
||||||
import glob
|
import glob
|
||||||
|
import logging
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import resource
|
import resource
|
||||||
@ -16,7 +17,7 @@ import lib.fixtures
|
|||||||
import pytest
|
import pytest
|
||||||
from lib.micronet_compat import ConfigOptionsProxy, Mininet
|
from lib.micronet_compat import ConfigOptionsProxy, Mininet
|
||||||
from lib.topogen import diagnose_env, get_topogen
|
from lib.topogen import diagnose_env, get_topogen
|
||||||
from lib.topolog import logger
|
from lib.topolog import get_test_logdir, logger
|
||||||
from lib.topotest import json_cmp_result
|
from lib.topotest import json_cmp_result
|
||||||
from munet import cli
|
from munet import cli
|
||||||
from munet.base import Commander, proc_error
|
from munet.base import Commander, proc_error
|
||||||
@ -25,6 +26,19 @@ from munet.testing.util import pause_test
|
|||||||
|
|
||||||
from lib import topolog, topotest
|
from lib import topolog, topotest
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Used by munet native tests
|
||||||
|
from munet.testing.fixtures import event_loop, unet # pylint: disable=all # noqa
|
||||||
|
|
||||||
|
@pytest.fixture(scope="module")
|
||||||
|
def rundir_module(pytestconfig):
|
||||||
|
d = os.path.join(pytestconfig.option.rundir, get_test_logdir())
|
||||||
|
logging.debug("rundir_module: test module rundir %s", d)
|
||||||
|
return d
|
||||||
|
|
||||||
|
except (AttributeError, ImportError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def pytest_addoption(parser):
|
def pytest_addoption(parser):
|
||||||
"""
|
"""
|
||||||
|
17
tests/topotests/example_munet/munet.yaml
Normal file
17
tests/topotests/example_munet/munet.yaml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
version: 1
|
||||||
|
topology:
|
||||||
|
ipv6-enable: true
|
||||||
|
networks-autonumber: true
|
||||||
|
networks:
|
||||||
|
- name: net1
|
||||||
|
- name: net2
|
||||||
|
nodes:
|
||||||
|
- name: r1
|
||||||
|
kind: frr
|
||||||
|
connections: ["net1"]
|
||||||
|
- name: r2
|
||||||
|
kind: frr
|
||||||
|
connections: ["net1", "net2"]
|
||||||
|
- name: r3
|
||||||
|
kind: frr
|
||||||
|
connections: ["net2"]
|
6
tests/topotests/example_munet/r1/daemons
Normal file
6
tests/topotests/example_munet/r1/daemons
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
zebra=1
|
||||||
|
staticd=1
|
||||||
|
vtysh_enable=1
|
||||||
|
watchfrr_enable=1
|
||||||
|
zebra_options="-d -F traditional --log=file:/var/log/frr/zebra.log"
|
||||||
|
staticd_options="-d -F traditional --log=file:/var/log/frr/staticd.log"
|
7
tests/topotests/example_munet/r1/frr.conf
Normal file
7
tests/topotests/example_munet/r1/frr.conf
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
log file /var/log/frr/frr.log
|
||||||
|
service integrated-vtysh-config
|
||||||
|
|
||||||
|
interface eth0
|
||||||
|
ip address 10.0.1.1/24
|
||||||
|
|
||||||
|
ip route 10.0.0.0/8 blackhole
|
1
tests/topotests/example_munet/r1/vtysh.conf
Normal file
1
tests/topotests/example_munet/r1/vtysh.conf
Normal file
@ -0,0 +1 @@
|
|||||||
|
service integrated-vtysh-config
|
6
tests/topotests/example_munet/r2/daemons
Normal file
6
tests/topotests/example_munet/r2/daemons
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
zebra=1
|
||||||
|
staticd=1
|
||||||
|
vtysh_enable=1
|
||||||
|
watchfrr_enable=1
|
||||||
|
zebra_options="-d -F traditional --log=file:/var/log/frr/zebra.log"
|
||||||
|
staticd_options="-d -F traditional --log=file:/var/log/frr/staticd.log"
|
10
tests/topotests/example_munet/r2/frr.conf
Normal file
10
tests/topotests/example_munet/r2/frr.conf
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
log file /var/log/frr/frr.log
|
||||||
|
service integrated-vtysh-config
|
||||||
|
|
||||||
|
interface eth0
|
||||||
|
ip address 10.0.1.2/24
|
||||||
|
|
||||||
|
interface eth1
|
||||||
|
ip address 10.0.2.2/24
|
||||||
|
|
||||||
|
ip route 10.0.0.0/8 blackhole
|
1
tests/topotests/example_munet/r2/vtysh.conf
Normal file
1
tests/topotests/example_munet/r2/vtysh.conf
Normal file
@ -0,0 +1 @@
|
|||||||
|
service integrated-vtysh-config
|
6
tests/topotests/example_munet/r3/daemons
Normal file
6
tests/topotests/example_munet/r3/daemons
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
zebra=1
|
||||||
|
staticd=1
|
||||||
|
vtysh_enable=1
|
||||||
|
watchfrr_enable=1
|
||||||
|
zebra_options="-d -F traditional --log=file:/var/log/frr/zebra.log"
|
||||||
|
staticd_options="-d -F traditional --log=file:/var/log/frr/staticd.log"
|
7
tests/topotests/example_munet/r3/frr.conf
Normal file
7
tests/topotests/example_munet/r3/frr.conf
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
log file /var/log/frr/frr.log
|
||||||
|
service integrated-vtysh-config
|
||||||
|
|
||||||
|
interface eth0
|
||||||
|
ip address 10.0.2.3/24
|
||||||
|
|
||||||
|
ip route 10.0.0.0/8 blackhole
|
1
tests/topotests/example_munet/r3/vtysh.conf
Normal file
1
tests/topotests/example_munet/r3/vtysh.conf
Normal file
@ -0,0 +1 @@
|
|||||||
|
service integrated-vtysh-config
|
10
tests/topotests/example_munet/test_munet.py
Normal file
10
tests/topotests/example_munet/test_munet.py
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# -*- coding: utf-8 eval: (blacken-mode 1) -*-
|
||||||
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
#
|
||||||
|
# April 23 2023, Christian Hopps <chopps@labn.net>
|
||||||
|
#
|
||||||
|
# Copyright (c) 2023, LabN Consulting, L.L.C.
|
||||||
|
#
|
||||||
|
async def test_native_test(unet):
|
||||||
|
o = unet.hosts["r1"].cmd_nostatus("ip addr")
|
||||||
|
print(o)
|
30
tests/topotests/kinds.yaml
Normal file
30
tests/topotests/kinds.yaml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
version: 1
|
||||||
|
kinds:
|
||||||
|
- name: frr
|
||||||
|
cmd: |
|
||||||
|
chown frr:frr -R /var/run/frr
|
||||||
|
chown frr:frr -R /var/log/frr
|
||||||
|
/usr/lib/frr/frrinit.sh start
|
||||||
|
tail -F /var/log/frr/frr.log
|
||||||
|
cleanup-cmd: |
|
||||||
|
/usr/lib/frr/frrinit.sh stop
|
||||||
|
volumes:
|
||||||
|
- "./%NAME%:/etc/frr"
|
||||||
|
- "%RUNDIR%/var.log.frr:/var/log/frr"
|
||||||
|
- "%RUNDIR%/var.run.frr:/var/run/frr"
|
||||||
|
cap-add:
|
||||||
|
- SYS_ADMIN
|
||||||
|
- AUDIT_WRITE
|
||||||
|
merge: ["volumes"]
|
||||||
|
cli:
|
||||||
|
commands:
|
||||||
|
- name: ""
|
||||||
|
exec: "vtysh -c '{}'"
|
||||||
|
format: "[ROUTER ...] COMMAND"
|
||||||
|
help: "execute vtysh COMMAND on the router[s]"
|
||||||
|
kinds: ["frr"]
|
||||||
|
- name: "vtysh"
|
||||||
|
exec: "/usr/bin/vtysh"
|
||||||
|
format: "vtysh ROUTER [ROUTER ...]"
|
||||||
|
new-window: true
|
||||||
|
kinds: ["frr"]
|
@ -59,7 +59,6 @@ class Node(LinuxNamespace):
|
|||||||
"""Node (mininet compat)."""
|
"""Node (mininet compat)."""
|
||||||
|
|
||||||
def __init__(self, name, rundir=None, **kwargs):
|
def __init__(self, name, rundir=None, **kwargs):
|
||||||
|
|
||||||
nkwargs = {}
|
nkwargs = {}
|
||||||
|
|
||||||
if "unet" in kwargs:
|
if "unet" in kwargs:
|
||||||
@ -177,8 +176,6 @@ class Mininet(BaseMunet):
|
|||||||
self.host_params = {}
|
self.host_params = {}
|
||||||
self.prefix_len = 8
|
self.prefix_len = 8
|
||||||
|
|
||||||
self.cfgopt = ConfigOptionsProxy(pytestconfig)
|
|
||||||
|
|
||||||
# SNMPd used to require this, which was set int he mininet shell
|
# 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
|
# 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
|
# do it if we don't have to. The snmpd.conf files have been updated
|
||||||
|
@ -26,6 +26,7 @@ from collections import defaultdict
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
|
from . import config as munet_config
|
||||||
from . import linux
|
from . import linux
|
||||||
|
|
||||||
|
|
||||||
@ -2493,7 +2494,15 @@ class Bridge(SharedNamespace, InterfaceMixin):
|
|||||||
class BaseMunet(LinuxNamespace):
|
class BaseMunet(LinuxNamespace):
|
||||||
"""Munet."""
|
"""Munet."""
|
||||||
|
|
||||||
def __init__(self, name="munet", isolated=True, pid=True, rundir=None, **kwargs):
|
def __init__(
|
||||||
|
self,
|
||||||
|
name="munet",
|
||||||
|
isolated=True,
|
||||||
|
pid=True,
|
||||||
|
rundir=None,
|
||||||
|
pytestconfig=None,
|
||||||
|
**kwargs,
|
||||||
|
):
|
||||||
"""Create a Munet."""
|
"""Create a Munet."""
|
||||||
# logging.warning("BaseMunet: %s", name)
|
# logging.warning("BaseMunet: %s", name)
|
||||||
|
|
||||||
@ -2562,6 +2571,8 @@ class BaseMunet(LinuxNamespace):
|
|||||||
|
|
||||||
roothost = self.rootcmd
|
roothost = self.rootcmd
|
||||||
|
|
||||||
|
self.cfgopt = munet_config.ConfigOptionsProxy(pytestconfig)
|
||||||
|
|
||||||
super().__init__(
|
super().__init__(
|
||||||
name, mount=True, net=isolated, uts=isolated, pid=pid, unet=None, **kwargs
|
name, mount=True, net=isolated, uts=isolated, pid=pid, unet=None, **kwargs
|
||||||
)
|
)
|
||||||
|
@ -11,8 +11,18 @@
|
|||||||
class PytestConfig:
|
class PytestConfig:
|
||||||
"""Pytest config duck-type-compatible object using argprase args."""
|
"""Pytest config duck-type-compatible object using argprase args."""
|
||||||
|
|
||||||
|
class Namespace:
|
||||||
|
"""A namespace defined by a dictionary of values."""
|
||||||
|
|
||||||
|
def __init__(self, args):
|
||||||
|
self.args = args
|
||||||
|
|
||||||
|
def __getattr__(self, attr):
|
||||||
|
return self.args[attr] if attr in self.args else None
|
||||||
|
|
||||||
def __init__(self, args):
|
def __init__(self, args):
|
||||||
self.args = vars(args)
|
self.args = vars(args)
|
||||||
|
self.option = PytestConfig.Namespace(self.args)
|
||||||
|
|
||||||
def getoption(self, name, default=None, skip=False):
|
def getoption(self, name, default=None, skip=False):
|
||||||
assert not skip
|
assert not skip
|
||||||
|
@ -156,3 +156,57 @@ def merge_kind_config(kconf, config):
|
|||||||
if k not in new:
|
if k not in new:
|
||||||
new[k] = config[k]
|
new[k] = config[k]
|
||||||
return new
|
return new
|
||||||
|
|
||||||
|
|
||||||
|
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:
|
||||||
|
"""Proxy options object to fill in for any missing pytest config."""
|
||||||
|
|
||||||
|
class DefNoneObject:
|
||||||
|
"""An object that returns None for any attribute access."""
|
||||||
|
|
||||||
|
def __getattr__(self, attr):
|
||||||
|
return None
|
||||||
|
|
||||||
|
def __init__(self, pytestconfig=None):
|
||||||
|
if isinstance(pytestconfig, ConfigOptionsProxy):
|
||||||
|
self.config = pytestconfig.config
|
||||||
|
self.option = self.config.option
|
||||||
|
else:
|
||||||
|
self.config = pytestconfig
|
||||||
|
if self.config:
|
||||||
|
self.option = self.config.option
|
||||||
|
else:
|
||||||
|
self.option = ConfigOptionsProxy.DefNoneObject()
|
||||||
|
|
||||||
|
def getoption(self, opt, defval=None):
|
||||||
|
if not self.config:
|
||||||
|
return defval
|
||||||
|
|
||||||
|
try:
|
||||||
|
return self.config.getoption(opt, default=defval)
|
||||||
|
except ValueError:
|
||||||
|
return defval
|
||||||
|
|
||||||
|
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
|
||||||
|
@ -423,37 +423,37 @@ class NodeMixin:
|
|||||||
stdout: file-like object with a ``name`` attribute, or a path to a file.
|
stdout: file-like object with a ``name`` attribute, or a path to a file.
|
||||||
stderr: file-like object with a ``name`` attribute, or a path to a file.
|
stderr: file-like object with a ``name`` attribute, or a path to a file.
|
||||||
"""
|
"""
|
||||||
if not self.unet or not self.unet.pytest_config:
|
if not self.unet:
|
||||||
return
|
return
|
||||||
|
|
||||||
outopt = self.unet.pytest_config.getoption("--stdout")
|
outopt = self.unet.cfgopt.getoption("--stdout")
|
||||||
outopt = outopt if outopt is not None else ""
|
outopt = outopt if outopt is not None else ""
|
||||||
if outopt == "all" or self.name in outopt.split(","):
|
if outopt == "all" or self.name in outopt.split(","):
|
||||||
outname = stdout.name if hasattr(stdout, "name") else stdout
|
outname = stdout.name if hasattr(stdout, "name") else stdout
|
||||||
self.run_in_window(f"tail -F {outname}", title=f"O:{self.name}")
|
self.run_in_window(f"tail -F {outname}", title=f"O:{self.name}")
|
||||||
|
|
||||||
if stderr:
|
if stderr:
|
||||||
erropt = self.unet.pytest_config.getoption("--stderr")
|
erropt = self.unet.cfgopt.getoption("--stderr")
|
||||||
erropt = erropt if erropt is not None else ""
|
erropt = erropt if erropt is not None else ""
|
||||||
if erropt == "all" or self.name in erropt.split(","):
|
if erropt == "all" or self.name in erropt.split(","):
|
||||||
errname = stderr.name if hasattr(stderr, "name") else stderr
|
errname = stderr.name if hasattr(stderr, "name") else stderr
|
||||||
self.run_in_window(f"tail -F {errname}", title=f"E:{self.name}")
|
self.run_in_window(f"tail -F {errname}", title=f"E:{self.name}")
|
||||||
|
|
||||||
def pytest_hook_open_shell(self):
|
def pytest_hook_open_shell(self):
|
||||||
if not self.unet or not self.unet.pytest_config:
|
if not self.unet:
|
||||||
return
|
return
|
||||||
|
|
||||||
gdbcmd = self.config.get("gdb-cmd")
|
gdbcmd = self.config.get("gdb-cmd")
|
||||||
shellopt = self.unet.pytest_config.getoption("--gdb", "")
|
shellopt = self.unet.cfgopt.getoption("--gdb", "")
|
||||||
should_gdb = gdbcmd and (shellopt == "all" or self.name in shellopt.split(","))
|
should_gdb = gdbcmd and (shellopt == "all" or self.name in shellopt.split(","))
|
||||||
use_emacs = self.unet.pytest_config.getoption("--gdb-use-emacs", False)
|
use_emacs = self.unet.cfgopt.getoption("--gdb-use-emacs", False)
|
||||||
|
|
||||||
if should_gdb and not use_emacs:
|
if should_gdb and not use_emacs:
|
||||||
cmds = self.config.get("gdb-target-cmds", [])
|
cmds = self.config.get("gdb-target-cmds", [])
|
||||||
for cmd in cmds:
|
for cmd in cmds:
|
||||||
gdbcmd += f" '-ex={cmd}'"
|
gdbcmd += f" '-ex={cmd}'"
|
||||||
|
|
||||||
bps = self.unet.pytest_config.getoption("--gdb-breakpoints", "").split(",")
|
bps = self.unet.cfgopt.getoption("--gdb-breakpoints", "").split(",")
|
||||||
for bp in bps:
|
for bp in bps:
|
||||||
gdbcmd += f" '-ex=b {bp}'"
|
gdbcmd += f" '-ex=b {bp}'"
|
||||||
|
|
||||||
@ -497,7 +497,7 @@ class NodeMixin:
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
bps = self.unet.pytest_config.getoption("--gdb-breakpoints", "").split(",")
|
bps = self.unet.cfgopt.getoption("--gdb-breakpoints", "").split(",")
|
||||||
for bp in bps:
|
for bp in bps:
|
||||||
cmd = f"br {bp}"
|
cmd = f"br {bp}"
|
||||||
self.cmd_raises(
|
self.cmd_raises(
|
||||||
@ -520,8 +520,8 @@ class NodeMixin:
|
|||||||
)
|
)
|
||||||
gdbcmd += f" '-ex={cmd}'"
|
gdbcmd += f" '-ex={cmd}'"
|
||||||
|
|
||||||
shellopt = self.unet.pytest_config.getoption("--shell")
|
shellopt = self.unet.cfgopt.getoption("--shell")
|
||||||
shellopt = shellopt if shellopt is not None else ""
|
shellopt = shellopt if shellopt else ""
|
||||||
if shellopt == "all" or self.name in shellopt.split(","):
|
if shellopt == "all" or self.name in shellopt.split(","):
|
||||||
self.run_in_window("bash")
|
self.run_in_window("bash")
|
||||||
|
|
||||||
@ -1968,7 +1968,7 @@ class L3QemuVM(L3NodeMixin, LinuxNamespace):
|
|||||||
con.cmd_raises(f"ip -6 route add default via {switch.ip6_address}")
|
con.cmd_raises(f"ip -6 route add default via {switch.ip6_address}")
|
||||||
con.cmd_raises("ip link set lo up")
|
con.cmd_raises("ip link set lo up")
|
||||||
|
|
||||||
if self.unet.pytest_config and self.unet.pytest_config.getoption("--coverage"):
|
if self.unet.cfgopt.getoption("--coverage"):
|
||||||
con.cmd_raises("mount -t debugfs none /sys/kernel/debug")
|
con.cmd_raises("mount -t debugfs none /sys/kernel/debug")
|
||||||
|
|
||||||
async def gather_coverage_data(self):
|
async def gather_coverage_data(self):
|
||||||
@ -2402,7 +2402,6 @@ class Munet(BaseMunet):
|
|||||||
self,
|
self,
|
||||||
rundir=None,
|
rundir=None,
|
||||||
config=None,
|
config=None,
|
||||||
pytestconfig=None,
|
|
||||||
pid=True,
|
pid=True,
|
||||||
logger=None,
|
logger=None,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
@ -2433,8 +2432,6 @@ class Munet(BaseMunet):
|
|||||||
self.config_pathname = ""
|
self.config_pathname = ""
|
||||||
self.config_dirname = ""
|
self.config_dirname = ""
|
||||||
|
|
||||||
self.pytest_config = pytestconfig
|
|
||||||
|
|
||||||
# Done in BaseMunet now
|
# Done in BaseMunet now
|
||||||
# # We need some way to actually get back to the root namespace
|
# # We need some way to actually get back to the root namespace
|
||||||
# if not self.isolated:
|
# if not self.isolated:
|
||||||
@ -2573,10 +2570,8 @@ ff02::2\tip6-allrouters
|
|||||||
# # Let's hide podman details
|
# # Let's hide podman details
|
||||||
# self.tmpfs_mount("/var/lib/containers/storage/overlay-containers")
|
# self.tmpfs_mount("/var/lib/containers/storage/overlay-containers")
|
||||||
|
|
||||||
shellopt = (
|
shellopt = self.cfgopt.getoption("--shell")
|
||||||
self.pytest_config.getoption("--shell") if self.pytest_config else None
|
shellopt = shellopt if shellopt else ""
|
||||||
)
|
|
||||||
shellopt = shellopt if shellopt is not None else ""
|
|
||||||
if shellopt == "all" or "." in shellopt.split(","):
|
if shellopt == "all" or "." in shellopt.split(","):
|
||||||
self.run_in_window("bash")
|
self.run_in_window("bash")
|
||||||
|
|
||||||
@ -2795,11 +2790,8 @@ ff02::2\tip6-allrouters
|
|||||||
x for x in hosts if hasattr(x, "has_ready_cmd") and x.has_ready_cmd()
|
x for x in hosts if hasattr(x, "has_ready_cmd") and x.has_ready_cmd()
|
||||||
]
|
]
|
||||||
|
|
||||||
if not self.pytest_config:
|
pcapopt = self.cfgopt.getoption("--pcap")
|
||||||
pcapopt = ""
|
pcapopt = pcapopt if pcapopt else ""
|
||||||
else:
|
|
||||||
pcapopt = self.pytest_config.getoption("--pcap")
|
|
||||||
pcapopt = pcapopt if pcapopt else ""
|
|
||||||
if pcapopt == "all":
|
if pcapopt == "all":
|
||||||
pcapopt = self.switches.keys()
|
pcapopt = self.switches.keys()
|
||||||
if pcapopt:
|
if pcapopt:
|
||||||
@ -2868,7 +2860,7 @@ ff02::2\tip6-allrouters
|
|||||||
|
|
||||||
self.logger.debug("%s: deleting.", self)
|
self.logger.debug("%s: deleting.", self)
|
||||||
|
|
||||||
if self.pytest_config and self.pytest_config.getoption("--coverage"):
|
if self.cfgopt.getoption("--coverage"):
|
||||||
nodes = (
|
nodes = (
|
||||||
x for x in self.hosts.values() if hasattr(x, "gather_coverage_data")
|
x for x in self.hosts.values() if hasattr(x, "gather_coverage_data")
|
||||||
)
|
)
|
||||||
@ -2877,11 +2869,8 @@ ff02::2\tip6-allrouters
|
|||||||
except Exception as error:
|
except Exception as error:
|
||||||
logging.warning("Error gathering coverage data: %s", error)
|
logging.warning("Error gathering coverage data: %s", error)
|
||||||
|
|
||||||
if not self.pytest_config:
|
pause = bool(self.cfgopt.getoption("--pause-at-end"))
|
||||||
pause = False
|
pause = pause or bool(self.cfgopt.getoption("--pause"))
|
||||||
else:
|
|
||||||
pause = bool(self.pytest_config.getoption("--pause-at-end"))
|
|
||||||
pause = pause or bool(self.pytest_config.getoption("--pause"))
|
|
||||||
if pause:
|
if pause:
|
||||||
try:
|
try:
|
||||||
await async_pause_test("Before MUNET delete")
|
await async_pause_test("Before MUNET delete")
|
||||||
|
@ -235,7 +235,7 @@ def load_kinds(args, search=None):
|
|||||||
if search is None:
|
if search is None:
|
||||||
search = [cwd]
|
search = [cwd]
|
||||||
with importlib.resources.path("munet", "kinds.yaml") as datapath:
|
with importlib.resources.path("munet", "kinds.yaml") as datapath:
|
||||||
search.append(str(datapath.parent))
|
search.insert(0, str(datapath.parent))
|
||||||
|
|
||||||
configs = []
|
configs = []
|
||||||
if args_config:
|
if args_config:
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
# Skip pytests example directory
|
# Skip pytests example directory
|
||||||
[pytest]
|
[pytest]
|
||||||
|
|
||||||
|
asyncio_mode = auto
|
||||||
|
|
||||||
# We always turn this on inside conftest.py, default shown
|
# We always turn this on inside conftest.py, default shown
|
||||||
# addopts = --junitxml=<rundir>/topotests.xml
|
# addopts = --junitxml=<rundir>/topotests.xml
|
||||||
|
|
||||||
@ -24,7 +26,7 @@ log_file_date_format = %Y-%m-%d %H:%M:%S
|
|||||||
junit_logging = all
|
junit_logging = all
|
||||||
junit_log_passing_tests = true
|
junit_log_passing_tests = true
|
||||||
|
|
||||||
norecursedirs = .git example_test example_topojson_test lib munet docker
|
norecursedirs = .git example_munet example_test example_topojson_test lib munet docker
|
||||||
|
|
||||||
# Directory to store test results and run logs in, default shown
|
# Directory to store test results and run logs in, default shown
|
||||||
# rundir = /tmp/topotests
|
# rundir = /tmp/topotests
|
||||||
|
Loading…
Reference in New Issue
Block a user