mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-29 04:25:43 +00:00
doc: minor update based on mininet removal
Signed-off-by: Christian Hopps <chopps@labn.net>
This commit is contained in:
parent
351bc82cac
commit
77f3acb45e
@ -12,8 +12,8 @@ Installing Dependencies
|
||||
sudo apt update
|
||||
sudo apt-get install \
|
||||
git autoconf automake libtool make libreadline-dev texinfo \
|
||||
pkg-config libpam0g-dev libjson-c-dev bison flex python3-pytest \
|
||||
libc-ares-dev python3-dev python-ipaddress python3-sphinx \
|
||||
pkg-config libpam0g-dev libjson-c-dev bison flex \
|
||||
libc-ares-dev python3-dev python3-sphinx \
|
||||
install-info build-essential libsnmp-dev perl libcap-dev \
|
||||
libelf-dev
|
||||
|
||||
|
@ -12,8 +12,8 @@ Installing Dependencies
|
||||
sudo apt update
|
||||
sudo apt-get install \
|
||||
git autoconf automake libtool make libreadline-dev texinfo \
|
||||
pkg-config libpam0g-dev libjson-c-dev bison flex python3-pytest \
|
||||
libc-ares-dev python3-dev python-ipaddress python3-sphinx \
|
||||
pkg-config libpam0g-dev libjson-c-dev bison flex \
|
||||
libc-ares-dev python3-dev python3-sphinx \
|
||||
install-info build-essential libsnmp-dev perl \
|
||||
libcap-dev python2 libelf-dev
|
||||
|
||||
|
@ -373,23 +373,18 @@ Building topology and configurations
|
||||
Topology and initial configuration will be created in setup_module(). Following
|
||||
is the sample code::
|
||||
|
||||
class TemplateTopo(Topo):
|
||||
def build(self, *_args, **_opts):
|
||||
"Build function"
|
||||
tgen = get_topogen(self)
|
||||
|
||||
# Building topology from json file
|
||||
build_topo_from_json(tgen, topo)
|
||||
|
||||
def setup_module(mod):
|
||||
tgen = Topogen(TemplateTopo, mod.__name__)
|
||||
json_file = "{}/my_test_name.json".format(CWD)
|
||||
tgen = Topogen(json_file, mod.__name__)
|
||||
|
||||
# json topo object is now available in tgen.json_topo
|
||||
|
||||
# Starting topology, create tmp files which are loaded to routers
|
||||
# to start deamons and then start routers
|
||||
start_topology(tgen)
|
||||
|
||||
# Creating configuration from JSON
|
||||
build_config_from_json(tgen, topo)
|
||||
build_config_from_json(tgen)
|
||||
|
||||
def teardown_module(mod):
|
||||
tgen = get_topogen()
|
||||
@ -412,10 +407,12 @@ configurations are like, static routes, prefixlists and route maps etc configs,
|
||||
these configs can be used by any other protocols as it is.
|
||||
BGP config will be specific to BGP protocol testing.
|
||||
|
||||
* JSON file is passed to API build_config_from_json(), which looks for
|
||||
configuration tags in JSON file.
|
||||
* If tag is found in JSON, configuration is created as per input and written
|
||||
to file frr_json.conf
|
||||
* json file is passed to API Topogen() which saves the JSON object in
|
||||
`self.json_topo`
|
||||
* The Topogen object is then passed to API build_config_from_json(), which looks
|
||||
for configuration tags in new JSON object.
|
||||
* If tag is found in the JSON object, configuration is created as per input and
|
||||
written to file frr_json.conf
|
||||
* Once JSON parsing is over, frr_json.conf is loaded onto respective router.
|
||||
Config loading is done using 'vtysh -f <file>'. Initial config at this point
|
||||
is also saved frr_json_initial.conf. This file can be used to reset
|
||||
@ -428,10 +425,10 @@ Writing Tests
|
||||
"""""""""""""
|
||||
|
||||
Test topologies should always be bootstrapped from the
|
||||
example-test/test_example.py, because it contains important boilerplate code
|
||||
that can't be avoided, like:
|
||||
example_test/test_template_json.py, because it contains important boilerplate
|
||||
code that can't be avoided, like:
|
||||
|
||||
imports: os, sys, pytest, topotest/topogen and mininet topology class
|
||||
imports: os, sys, pytest, and topotest/topogen.
|
||||
|
||||
The global variable CWD (Current Working directory): which is most likely going
|
||||
to be used to reference the routers configuration file location
|
||||
|
@ -3,32 +3,37 @@
|
||||
Topotests
|
||||
=========
|
||||
|
||||
Topotests is a suite of topology tests for FRR built on top of Mininet.
|
||||
Topotests is a suite of topology tests for FRR built on top of micronet.
|
||||
|
||||
Installation and Setup
|
||||
----------------------
|
||||
|
||||
Only tested with Ubuntu 16.04 and Ubuntu 18.04 (which uses Mininet 2.2.x).
|
||||
Topotests run under python3. Additionally, for ExaBGP (which is used in some of
|
||||
the BGP tests) an older python2 version must be installed.
|
||||
|
||||
Tested with Ubuntu 20.04 and Ubuntu 18.04 and Debian 11.
|
||||
|
||||
Instructions are the same for all setups (i.e. ExaBGP is only used for BGP
|
||||
tests).
|
||||
|
||||
Installing Mininet Infrastructure
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Installing Topotest Requirements
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code:: shell
|
||||
|
||||
apt-get install mininet
|
||||
apt-get install python-pip
|
||||
apt-get install iproute
|
||||
apt-get install iperf
|
||||
pip install ipaddr
|
||||
pip install "pytest<5"
|
||||
pip install "scapy>=2.4.2"
|
||||
pip install exabgp==3.4.17 (Newer 4.0 version of exabgp is not yet
|
||||
supported)
|
||||
apt-get install iproute2
|
||||
apt-get install net-tools
|
||||
apt-get install python3-pip
|
||||
python3 -m pip install wheel
|
||||
python3 -m pip install 'pytest>=6.2.4'
|
||||
python3 -m pip install 'pytest-xdist>=2.3.0'
|
||||
python3 -m pip install 'scapy>=2.4.5'
|
||||
python3 -m pip install xmltodict
|
||||
# Use python2 pip to install older ExaBGP
|
||||
python2 -m pip install 'exabgp<4.0.0'
|
||||
useradd -d /var/run/exabgp/ -s /bin/false exabgp
|
||||
|
||||
|
||||
Enable Coredumps
|
||||
""""""""""""""""
|
||||
|
||||
@ -125,20 +130,125 @@ And create ``frr`` user and ``frrvty`` group as follows:
|
||||
Executing Tests
|
||||
---------------
|
||||
|
||||
Execute all tests with output to console
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Execute all tests in distributed test mode
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. code:: shell
|
||||
|
||||
py.test -s -v --tb=no
|
||||
py.test -s -v -nauto --dist=loadfile
|
||||
|
||||
The above command must be executed from inside the topotests directory.
|
||||
|
||||
All test\_\* scripts in subdirectories are detected and executed (unless
|
||||
disabled in ``pytest.ini`` file).
|
||||
disabled in ``pytest.ini`` file). Pytest will execute up to N tests in parallel
|
||||
where N is based on the number of cores on the host.
|
||||
|
||||
Analyze Test Results (``analyze.py``)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
By default router and execution logs are saved in ``/tmp/topotests`` and an XML
|
||||
results file is saved in ``/tmp/topotests.xml``. An analysis tool ``analyze.py``
|
||||
is provided to archive and analyze these results after the run completes.
|
||||
|
||||
After the test run completes one should pick an archive directory to store the
|
||||
results in and pass this value to ``analyze.py``. On first execution the results
|
||||
are copied to that directory from ``/tmp``, and subsequent runs use that
|
||||
directory for analyzing the results. Below is an example of this which also
|
||||
shows the default behavior which is to display all failed and errored tests in
|
||||
the run.
|
||||
|
||||
.. code:: shell
|
||||
|
||||
~/frr/tests/topotests# ./analyze.py -Ar run-save
|
||||
bgp_multiview_topo1/test_bgp_multiview_topo1.py::test_bgp_converge
|
||||
ospf_basic_functionality/test_ospf_lan.py::test_ospf_lan_tc1_p0
|
||||
bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2.py::test_BGP_GR_10_p2
|
||||
bgp_multiview_topo1/test_bgp_multiview_topo1.py::test_bgp_routingTable
|
||||
|
||||
Here we see that 4 tests have failed. We an dig deeper by displaying the
|
||||
captured logs and errors. First let's redisplay the results enumerated by adding
|
||||
the ``-E`` flag
|
||||
|
||||
.. code:: shell
|
||||
|
||||
~/frr/tests/topotests# ./analyze.py -Ar run-save -E
|
||||
0 bgp_multiview_topo1/test_bgp_multiview_topo1.py::test_bgp_converge
|
||||
1 ospf_basic_functionality/test_ospf_lan.py::test_ospf_lan_tc1_p0
|
||||
2 bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2.py::test_BGP_GR_10_p2
|
||||
3 bgp_multiview_topo1/test_bgp_multiview_topo1.py::test_bgp_routingTable
|
||||
|
||||
Now to look at the error message for a failed test we use ``-T N`` where N is
|
||||
the number of the test we are interested in along with ``--errmsg`` option.
|
||||
|
||||
.. code:: shell
|
||||
|
||||
~/frr/tests/topotests# ./analyze.py -Ar run-save -T0 --errmsg
|
||||
bgp_multiview_topo1/test_bgp_multiview_topo1.py::test_bgp_converge: AssertionError: BGP did not converge:
|
||||
|
||||
IPv4 Unicast Summary (VIEW 1):
|
||||
BGP router identifier 172.30.1.1, local AS number 100 vrf-id -1
|
||||
BGP table version 1
|
||||
RIB entries 1, using 184 bytes of memory
|
||||
Peers 3, using 2169 KiB of memory
|
||||
|
||||
Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd PfxSnt Desc
|
||||
172.16.1.1 4 65001 0 0 0 0 0 never Connect 0 N/A
|
||||
172.16.1.2 4 65002 0 0 0 0 0 never Connect 0 N/A
|
||||
172.16.1.5 4 65005 0 0 0 0 0 never Connect 0 N/A
|
||||
|
||||
Total number of neighbors 3
|
||||
|
||||
assert False
|
||||
|
||||
Now to look at the full text of the error for a failed test we use ``-T N``
|
||||
where N is the number of the test we are interested in along with ``--errtext``
|
||||
option.
|
||||
|
||||
.. code:: shell
|
||||
|
||||
~/frr/tests/topotests# ./analyze.py -Ar run-save -T0 --errtext
|
||||
bgp_multiview_topo1/test_bgp_multiview_topo1.py::test_bgp_converge: def test_bgp_converge():
|
||||
"Check for BGP converged on all peers and BGP views"
|
||||
|
||||
global fatal_error
|
||||
global net
|
||||
[...]
|
||||
else:
|
||||
# Bail out with error if a router fails to converge
|
||||
bgpStatus = net["r%s" % i].cmd('vtysh -c "show ip bgp view %s summary"' % view)
|
||||
> assert False, "BGP did not converge:\n%s" % bgpStatus
|
||||
E AssertionError: BGP did not converge:
|
||||
E
|
||||
E IPv4 Unicast Summary (VIEW 1):
|
||||
E BGP router identifier 172.30.1.1, local AS number 100 vrf-id -1
|
||||
[...]
|
||||
E Neighbor V AS MsgRcvd MsgSent TblVer InQ OutQ Up/Down State/PfxRcd PfxSnt Desc
|
||||
E 172.16.1.1 4 65001 0 0 0 0 0 never Connect 0 N/A
|
||||
E 172.16.1.2 4 65002 0 0 0 0 0 never Connect 0 N/A
|
||||
[...]
|
||||
|
||||
To look at the full capture for a test including the stdout and stderr which
|
||||
includes full debug logs, just use the ``-T N`` option without the ``--errmsg``
|
||||
or ``--errtext`` options.
|
||||
|
||||
.. code:: shell
|
||||
|
||||
~/frr/tests/topotests# ./analyze.py -Ar run-save -T0
|
||||
@classname: bgp_multiview_topo1.test_bgp_multiview_topo1
|
||||
@name: test_bgp_converge
|
||||
@time: 141.401
|
||||
@message: AssertionError: BGP did not converge:
|
||||
[...]
|
||||
system-out: --------------------------------- Captured Log ---------------------------------
|
||||
2021-08-09 02:55:06,581 DEBUG: lib.micronet_compat.topo: Topo(unnamed): Creating
|
||||
2021-08-09 02:55:06,581 DEBUG: lib.micronet_compat.topo: Topo(unnamed): addHost r1
|
||||
[...]
|
||||
2021-08-09 02:57:16,932 DEBUG: topolog.r1: LinuxNamespace(r1): cmd_status("['/bin/bash', '-c', 'vtysh -c "show ip bgp view 1 summary" 2> /dev/null | grep ^[0-9] | grep -vP " 11\\s+(\\d+)"']", kwargs: {'encoding': 'utf-8', 'stdout': -1, 'stderr': -2, 'shell': False})
|
||||
2021-08-09 02:57:22,290 DEBUG: topolog.r1: LinuxNamespace(r1): cmd_status("['/bin/bash', '-c', 'vtysh -c "show ip bgp view 1 summary" 2> /dev/null | grep ^[0-9] | grep -vP " 11\\s+(\\d+)"']", kwargs: {'encoding': 'utf-8', 'stdout': -1, 'stderr': -2, 'shell': False})
|
||||
2021-08-09 02:57:27,636 DEBUG: topolog.r1: LinuxNamespace(r1): cmd_status("['/bin/bash', '-c', 'vtysh -c "show ip bgp view 1 summary"']", kwargs: {'encoding': 'utf-8', 'stdout': -1, 'stderr': -2, 'shell': False})
|
||||
--------------------------------- Captured Out ---------------------------------
|
||||
system-err: --------------------------------- Captured Err ---------------------------------
|
||||
|
||||
``--tb=no`` disables the python traceback which might be irrelevant unless the
|
||||
test script itself is debugged.
|
||||
|
||||
Execute single test
|
||||
^^^^^^^^^^^^^^^^^^^
|
||||
@ -161,9 +271,6 @@ Test will set exit code which can be used with ``git bisect``.
|
||||
|
||||
For the simulated topology, see the description in the python file.
|
||||
|
||||
If you need to clear the mininet setup between tests (if it isn't cleanly
|
||||
shutdown), then use the ``mn -c`` command to clean up the environment.
|
||||
|
||||
StdErr log from daemos after exit
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
@ -235,18 +342,64 @@ and create ``frr`` user and ``frrvty`` group as shown above.
|
||||
Debugging Topotest Failures
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
For the below debugging options which launch programs, if the topotest is run
|
||||
within screen_ or tmux_, ``gdb``, the shell or ``vtysh`` will be launched using
|
||||
that windowing program, otherwise mininet's ``xterm`` functionality will be used
|
||||
to launch the given program.
|
||||
Install and run tests inside ``tmux`` or ``byobu`` for best results.
|
||||
|
||||
If you wish to force the use of ``xterm`` rather than ``tmux`` or ``screen``, or
|
||||
wish to use ``gnome-terminal`` instead of ``xterm``, set the environment
|
||||
variable ``FRR_TOPO_TERMINAL`` to either ``xterm`` or ``gnome-terminal``.
|
||||
``XTerm`` is also fully supported. GNU ``screen`` can be used in most
|
||||
situations; however, it does not work as well with launching ``vtysh`` or shell
|
||||
on error.
|
||||
|
||||
For the below debugging options which launch programs or CLIs, topotest should
|
||||
be run within ``tmux`` (or ``screen``)_, as ``gdb``, the shell or ``vtysh`` will
|
||||
be launched using that windowing program, otherwise ``xterm`` will be attempted
|
||||
to launch the given programs.
|
||||
|
||||
.. _screen: https://www.gnu.org/software/screen/
|
||||
.. _tmux: https://github.com/tmux/tmux/wiki
|
||||
|
||||
Spawning Debugging CLI, ``vtysh`` or Shells on Routers on Test Failure
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
One can have a debugging CLI invoked on test failures by specifying the
|
||||
``--cli-on-error`` CLI option as shown in the example below.
|
||||
|
||||
.. code:: shell
|
||||
|
||||
pytest --cli-on-error all-protocol-startup
|
||||
|
||||
The debugging CLI can run shell or vtysh commands on any combination of routers
|
||||
It can also open shells or vtysh in their own windows for any combination of
|
||||
routers. This is usually the most useful option when debugging failures. Here is
|
||||
the help command from within a CLI launched on error:
|
||||
|
||||
.. code:: shell
|
||||
|
||||
test_bgp_multiview_topo1/test_bgp_routingTable> help
|
||||
|
||||
Commands:
|
||||
help :: this help
|
||||
sh [hosts] <shell-command> :: execute <shell-command> on <host>
|
||||
term [hosts] :: open shell terminals for hosts
|
||||
vtysh [hosts] :: open vtysh terminals for hosts
|
||||
[hosts] <vtysh-command> :: execute vtysh-command on hosts
|
||||
|
||||
test_bgp_multiview_topo1/test_bgp_routingTable> r1 show int br
|
||||
------ Host: r1 ------
|
||||
Interface Status VRF Addresses
|
||||
--------- ------ --- ---------
|
||||
erspan0 down default
|
||||
gre0 down default
|
||||
gretap0 down default
|
||||
lo up default
|
||||
r1-eth0 up default 172.16.1.254/24
|
||||
r1-stub up default 172.20.0.1/28
|
||||
|
||||
----------------------
|
||||
test_bgp_multiview_topo1/test_bgp_routingTable>
|
||||
|
||||
Additionally, one can have ``vtysh`` or a shell launched on all routers when a
|
||||
test fails. To launch the given process on each router after a test failure
|
||||
specify one of ``--shell-on-error`` or ``--vtysh-on-error``.
|
||||
|
||||
Spawning ``vtysh`` or Shells on Routers
|
||||
"""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
@ -255,8 +408,8 @@ a test. This is enabled by specifying 1 of 2 CLI arguments ``--shell`` or
|
||||
``--vtysh``. Both of these options can be set to a single router value, multiple
|
||||
comma-seperated values, or ``all``.
|
||||
|
||||
When either of these options are specified topotest will pause after each test
|
||||
to allow for inspection of the router state.
|
||||
When either of these options are specified topotest will pause after setup and
|
||||
each test to allow for inspection of the router state.
|
||||
|
||||
Here's an example of launching ``vtysh`` on routers ``rt1`` and ``rt2``.
|
||||
|
||||
@ -264,29 +417,6 @@ Here's an example of launching ``vtysh`` on routers ``rt1`` and ``rt2``.
|
||||
|
||||
pytest --vtysh=rt1,rt2 all-protocol-startup
|
||||
|
||||
Spawning Mininet CLI, ``vtysh`` or Shells on Routers on Test Failure
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
Similar to the previous section one can have ``vtysh`` or a shell launched on
|
||||
routers, but in this case only when a test fails. To launch the given process on
|
||||
each router after a test failure specify one of ``--shell-on-error`` or
|
||||
``--vtysh-on-error``.
|
||||
|
||||
|
||||
Here's an example of having ``vtysh`` launched on test failure.
|
||||
|
||||
.. code:: shell
|
||||
|
||||
pytest --vtysh-on-error all-protocol-startup
|
||||
|
||||
|
||||
Additionally, one can have the mininet CLI invoked on test failures by
|
||||
specifying the ``--mininet-on-error`` CLI option as shown in the example below.
|
||||
|
||||
.. code:: shell
|
||||
|
||||
pytest --mininet-on-error all-protocol-startup
|
||||
|
||||
Debugging with GDB
|
||||
""""""""""""""""""
|
||||
|
||||
@ -424,7 +554,7 @@ top level directory of topotest:
|
||||
|
||||
$ # Change to the top level directory of topotests.
|
||||
$ cd path/to/topotests
|
||||
$ # Tests must be run as root, since Mininet requires it.
|
||||
$ # Tests must be run as root, since micronet requires it.
|
||||
$ sudo pytest
|
||||
|
||||
In order to run a specific test, you can use the following command:
|
||||
@ -493,15 +623,16 @@ Some things to keep in mind:
|
||||
- Avoid including unstable data in your test: don't rely on link-local
|
||||
addresses or ifindex values, for example, because these can change
|
||||
from run to run.
|
||||
- Using sleep is almost never appropriate to wait for some convergence
|
||||
event as the sole item done. As an example: if the test resets the peers
|
||||
in BGP, the test should look for the peers reconverging instead of just
|
||||
sleeping an arbitrary amount of time and continuing on. It is ok to
|
||||
use sleep in a tight loop with appropriate show commands to ensure that
|
||||
the protocol reaches the desired state. This should be bounded by
|
||||
appropriate timeouts for the protocol in question though. See
|
||||
verify_bgp_convergence as a good example of this. If you are having
|
||||
troubles figuring out what to look for, please do not be afraid to ask.
|
||||
- Using sleep is almost never appropriate. As an example: if the test resets the
|
||||
peers in BGP, the test should look for the peers re-converging instead of just
|
||||
sleeping an arbitrary amount of time and continuing on. See
|
||||
`verify_bgp_convergence` as a good example of this. In particular look at it's
|
||||
use of the `@retry` decorator. If you are having troubles figuring out what to
|
||||
look for, please do not be afraid to ask.
|
||||
- Don't duplicate effort. There exists many protocol utility functions that can
|
||||
be found in their eponymous module under `tests/topotests/lib/` (e.g.,
|
||||
`ospf.py`)
|
||||
|
||||
|
||||
|
||||
Topotest File Hierarchy
|
||||
@ -661,25 +792,32 @@ Here is the template topology described in the previous section in python code:
|
||||
|
||||
.. code:: py
|
||||
|
||||
class TemplateTopo(Topo):
|
||||
"Test topology builder"
|
||||
def build(self, *_args, **_opts):
|
||||
"Build function"
|
||||
tgen = get_topogen(self)
|
||||
topodef = {
|
||||
"s1": "r1"
|
||||
"s2": ("r1", "r2")
|
||||
}
|
||||
|
||||
# Create 2 routers
|
||||
for routern in range(1, 3):
|
||||
tgen.add_router('r{}'.format(routern))
|
||||
If more specialized topology definitions, or router initialization arguments are
|
||||
required a build function can be used instead of a dictionary:
|
||||
|
||||
# Create a switch with just one router connected to it to simulate a
|
||||
# empty network.
|
||||
switch = tgen.add_switch('s1')
|
||||
switch.add_link(tgen.gears['r1'])
|
||||
.. code:: py
|
||||
|
||||
# Create a connection between r1 and r2
|
||||
switch = tgen.add_switch('s2')
|
||||
switch.add_link(tgen.gears['r1'])
|
||||
switch.add_link(tgen.gears['r2'])
|
||||
def build_topo(tgen):
|
||||
"Build function"
|
||||
|
||||
# Create 2 routers
|
||||
for routern in range(1, 3):
|
||||
tgen.add_router("r{}".format(routern))
|
||||
|
||||
# Create a switch with just one router connected to it to simulate a
|
||||
# empty network.
|
||||
switch = tgen.add_switch("s1")
|
||||
switch.add_link(tgen.gears["r1"])
|
||||
|
||||
# Create a connection between r1 and r2
|
||||
switch = tgen.add_switch("s2")
|
||||
switch.add_link(tgen.gears["r1"])
|
||||
switch.add_link(tgen.gears["r2"])
|
||||
|
||||
- Run the topology
|
||||
|
||||
@ -701,8 +839,8 @@ Parameters explanation:
|
||||
|
||||
.. option:: -s
|
||||
|
||||
Actives input/output capture. This is required by mininet in order to show
|
||||
the interactive shell.
|
||||
Actives input/output capture. If this is not specified a new window will be
|
||||
opened for the interactive CLI, otherwise it will be activated inline.
|
||||
|
||||
.. option:: --topology-only
|
||||
|
||||
@ -713,110 +851,84 @@ output:
|
||||
|
||||
.. code:: shell
|
||||
|
||||
=== test session starts ===
|
||||
platform linux2 -- Python 2.7.12, pytest-3.1.2, py-1.4.34, pluggy-0.4.0
|
||||
rootdir: /media/sf_src/topotests, inifile: pytest.ini
|
||||
collected 3 items
|
||||
frr/tests/topotests# sudo pytest -s --topology-only ospf_topo1/test_ospf_topo1.py
|
||||
============================= test session starts ==============================
|
||||
platform linux -- Python 3.9.2, pytest-6.2.4, py-1.10.0, pluggy-0.13.1
|
||||
rootdir: /home/chopps/w/frr/tests/topotests, configfile: pytest.ini
|
||||
plugins: forked-1.3.0, xdist-2.3.0
|
||||
collected 11 items
|
||||
|
||||
ospf-topo1/test_ospf_topo1.py *** Starting controller
|
||||
[...]
|
||||
unet>
|
||||
|
||||
*** Starting 6 switches
|
||||
switch1 switch2 switch3 switch4 switch5 switch6 ...
|
||||
r2: frr zebra started
|
||||
r2: frr ospfd started
|
||||
r3: frr zebra started
|
||||
r3: frr ospfd started
|
||||
r1: frr zebra started
|
||||
r1: frr ospfd started
|
||||
r4: frr zebra started
|
||||
r4: frr ospfd started
|
||||
*** Starting CLI:
|
||||
mininet>
|
||||
|
||||
The last line shows us that we are now using the Mininet CLI (Command Line
|
||||
The last line shows us that we are now using the CLI (Command Line
|
||||
Interface), from here you can call your router ``vtysh`` or even bash.
|
||||
|
||||
Here's the help text:
|
||||
|
||||
.. code:: shell
|
||||
unet> help
|
||||
|
||||
Commands:
|
||||
help :: this help
|
||||
sh [hosts] <shell-command> :: execute <shell-command> on <host>
|
||||
term [hosts] :: open shell terminals for hosts
|
||||
vtysh [hosts] :: open vtysh terminals for hosts
|
||||
[hosts] <vtysh-command> :: execute vtysh-command on hosts
|
||||
|
||||
.. code:: shell
|
||||
|
||||
Here are some commands example:
|
||||
|
||||
.. code:: shell
|
||||
|
||||
mininet> r1 ping 10.0.3.1
|
||||
PING 10.0.3.1 (10.0.3.1) 56(84) bytes of data.
|
||||
64 bytes from 10.0.3.1: icmp_seq=1 ttl=64 time=0.576 ms
|
||||
64 bytes from 10.0.3.1: icmp_seq=2 ttl=64 time=0.083 ms
|
||||
64 bytes from 10.0.3.1: icmp_seq=3 ttl=64 time=0.088 ms
|
||||
^C
|
||||
--- 10.0.3.1 ping statistics ---
|
||||
3 packets transmitted, 3 received, 0% packet loss, time 1998ms
|
||||
rtt min/avg/max/mdev = 0.083/0.249/0.576/0.231 ms
|
||||
unet> sh r1 ping 10.0.3.1
|
||||
PING 10.0.3.1 (10.0.3.1) 56(84) bytes of data.
|
||||
64 bytes from 10.0.3.1: icmp_seq=1 ttl=64 time=0.576 ms
|
||||
64 bytes from 10.0.3.1: icmp_seq=2 ttl=64 time=0.083 ms
|
||||
64 bytes from 10.0.3.1: icmp_seq=3 ttl=64 time=0.088 ms
|
||||
^C
|
||||
--- 10.0.3.1 ping statistics ---
|
||||
3 packets transmitted, 3 received, 0% packet loss, time 1998ms
|
||||
rtt min/avg/max/mdev = 0.083/0.249/0.576/0.231 ms
|
||||
|
||||
unet> r1 show run
|
||||
Building configuration...
|
||||
|
||||
Current configuration:
|
||||
!
|
||||
frr version 8.1-dev-my-manual-build
|
||||
frr defaults traditional
|
||||
hostname r1
|
||||
log file /tmp/topotests/ospf_topo1.test_ospf_topo1/r1/zebra.log
|
||||
[...]
|
||||
end
|
||||
|
||||
mininet> r1 ping 10.0.3.3
|
||||
PING 10.0.3.3 (10.0.3.3) 56(84) bytes of data.
|
||||
64 bytes from 10.0.3.3: icmp_seq=1 ttl=64 time=2.87 ms
|
||||
64 bytes from 10.0.3.3: icmp_seq=2 ttl=64 time=0.080 ms
|
||||
64 bytes from 10.0.3.3: icmp_seq=3 ttl=64 time=0.091 ms
|
||||
^C
|
||||
--- 10.0.3.3 ping statistics ---
|
||||
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
|
||||
rtt min/avg/max/mdev = 0.080/1.014/2.872/1.313 ms
|
||||
|
||||
|
||||
|
||||
mininet> r3 vtysh
|
||||
|
||||
Hello, this is FRRouting (version 3.1-devrzalamena-build).
|
||||
Copyright 1996-2005 Kunihiro Ishiguro, et al.
|
||||
|
||||
frr-1# show running-config
|
||||
Building configuration...
|
||||
|
||||
Current configuration:
|
||||
!
|
||||
frr version 3.1-devrzalamena-build
|
||||
frr defaults traditional
|
||||
hostname r3
|
||||
no service integrated-vtysh-config
|
||||
!
|
||||
log file zebra.log
|
||||
!
|
||||
log file ospfd.log
|
||||
!
|
||||
interface r3-eth0
|
||||
ip address 10.0.3.1/24
|
||||
!
|
||||
interface r3-eth1
|
||||
ip address 10.0.10.1/24
|
||||
!
|
||||
interface r3-eth2
|
||||
ip address 172.16.0.2/24
|
||||
!
|
||||
router ospf
|
||||
ospf router-id 10.0.255.3
|
||||
redistribute kernel
|
||||
redistribute connected
|
||||
redistribute static
|
||||
network 10.0.3.0/24 area 0
|
||||
network 10.0.10.0/24 area 0
|
||||
network 172.16.0.0/24 area 1
|
||||
!
|
||||
line vty
|
||||
!
|
||||
end
|
||||
frr-1#
|
||||
unet> show daemons
|
||||
------ Host: r1 ------
|
||||
zebra ospfd ospf6d staticd
|
||||
------- End: r1 ------
|
||||
------ Host: r2 ------
|
||||
zebra ospfd ospf6d staticd
|
||||
------- End: r2 ------
|
||||
------ Host: r3 ------
|
||||
zebra ospfd ospf6d staticd
|
||||
------- End: r3 ------
|
||||
------ Host: r4 ------
|
||||
zebra ospfd ospf6d staticd
|
||||
------- End: r4 ------
|
||||
|
||||
After you successfully configured your topology, you can obtain the
|
||||
configuration files (per-daemon) using the following commands:
|
||||
|
||||
.. code:: shell
|
||||
|
||||
mininet> r3 vtysh -d ospfd
|
||||
unet> sh r3 vtysh -d ospfd
|
||||
|
||||
Hello, this is FRRouting (version 3.1-devrzalamena-build).
|
||||
Copyright 1996-2005 Kunihiro Ishiguro, et al.
|
||||
|
||||
frr-1# show running-config
|
||||
r1# show running-config
|
||||
Building configuration...
|
||||
|
||||
Current configuration:
|
||||
@ -839,7 +951,7 @@ configuration files (per-daemon) using the following commands:
|
||||
line vty
|
||||
!
|
||||
end
|
||||
frr-1#
|
||||
r1#
|
||||
|
||||
Writing Tests
|
||||
"""""""""""""
|
||||
@ -848,15 +960,12 @@ Test topologies should always be bootstrapped from
|
||||
:file:`tests/topotests/example-test/test_template.py` because it contains
|
||||
important boilerplate code that can't be avoided, like:
|
||||
|
||||
- imports: os, sys, pytest, topotest/topogen and mininet topology class
|
||||
- The global variable CWD (Current Working directory): which is most likely
|
||||
going to be used to reference the routers configuration file location
|
||||
|
||||
Example:
|
||||
|
||||
.. code:: py
|
||||
|
||||
# For all registered routers, load the zebra configuration file
|
||||
CWD = os.path.dirname(os.path.realpath(__file__))
|
||||
for rname, router in router_list.items():
|
||||
router.load_config(
|
||||
TopoRouter.RD_ZEBRA,
|
||||
@ -865,21 +974,28 @@ Example:
|
||||
# os.path.join() joins the CWD string with arguments adding the necessary
|
||||
# slashes ('/'). Arguments must not begin with '/'.
|
||||
|
||||
- The topology class that inherits from Mininet Topo class:
|
||||
- The topology definition or build function
|
||||
|
||||
.. code:: py
|
||||
|
||||
class TemplateTopo(Topo):
|
||||
def build(self, *_args, **_opts):
|
||||
tgen = get_topogen(self)
|
||||
topodef = {
|
||||
"s1": ("r1", "r2"),
|
||||
"s2": ("r2", "r3")
|
||||
}
|
||||
|
||||
def build_topo(tgen):
|
||||
# topology build code
|
||||
...
|
||||
|
||||
- pytest ``setup_module()`` and ``teardown_module()`` to start the topology
|
||||
|
||||
.. code:: py
|
||||
|
||||
def setup_module(_m):
|
||||
tgen = Topogen(TemplateTopo)
|
||||
def setup_module(module):
|
||||
tgen = Topogen(topodef, module.__name__)
|
||||
# or
|
||||
tgen = Topogen(build_topo, module.__name__)
|
||||
|
||||
tgen.start_topology('debug')
|
||||
|
||||
def teardown_module(_m):
|
||||
@ -1042,11 +1158,10 @@ Example of pdb usage:
|
||||
(Pdb) router1 = tgen.gears[router]
|
||||
(Pdb) router1.vtysh_cmd('show ip ospf route')
|
||||
'============ OSPF network routing table ============\r\nN 10.0.1.0/24 [10] area: 0.0.0.0\r\n directly attached to r1-eth0\r\nN 10.0.2.0/24 [20] area: 0.0.0.0\r\n via 10.0.3.3, r1-eth1\r\nN 10.0.3.0/24 [10] area: 0.0.0.0\r\n directly attached to r1-eth1\r\nN 10.0.10.0/24 [20] area: 0.0.0.0\r\n via 10.0.3.1, r1-eth1\r\nN IA 172.16.0.0/24 [20] area: 0.0.0.0\r\n via 10.0.3.1, r1-eth1\r\nN IA 172.16.1.0/24 [30] area: 0.0.0.0\r\n via 10.0.3.1, r1-eth1\r\n\r\n============ OSPF router routing table =============\r\nR 10.0.255.2 [10] area: 0.0.0.0, ASBR\r\n via 10.0.3.3, r1-eth1\r\nR 10.0.255.3 [10] area: 0.0.0.0, ABR, ASBR\r\n via 10.0.3.1, r1-eth1\r\nR 10.0.255.4 IA [20] area: 0.0.0.0, ASBR\r\n via 10.0.3.1, r1-eth1\r\n\r\n============ OSPF external routing table ===========\r\n\r\n\r\n'
|
||||
(Pdb) tgen.mininet_cli()
|
||||
*** Starting CLI:
|
||||
mininet>
|
||||
(Pdb) tgen.cli()
|
||||
unet>
|
||||
|
||||
To enable more debug messages in other Topogen subsystems (like Mininet), more
|
||||
To enable more debug messages in other Topogen subsystems, more
|
||||
logging messages can be displayed by modifying the test configuration file
|
||||
``pytest.ini``:
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user