From 77f3acb45e81c7c454e343cb41dafc59316c729a Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Sun, 18 Jul 2021 15:59:40 +0000 Subject: [PATCH] doc: minor update based on mininet removal Signed-off-by: Christian Hopps --- doc/developer/building-frr-for-ubuntu1804.rst | 4 +- doc/developer/building-frr-for-ubuntu2004.rst | 4 +- doc/developer/topotests-jsontopo.rst | 31 +- doc/developer/topotests.rst | 479 +++++++++++------- 4 files changed, 315 insertions(+), 203 deletions(-) diff --git a/doc/developer/building-frr-for-ubuntu1804.rst b/doc/developer/building-frr-for-ubuntu1804.rst index 39a17fc01c..3e8c6c0d0b 100644 --- a/doc/developer/building-frr-for-ubuntu1804.rst +++ b/doc/developer/building-frr-for-ubuntu1804.rst @@ -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 diff --git a/doc/developer/building-frr-for-ubuntu2004.rst b/doc/developer/building-frr-for-ubuntu2004.rst index 92ddead4a5..28e7ca6518 100644 --- a/doc/developer/building-frr-for-ubuntu2004.rst +++ b/doc/developer/building-frr-for-ubuntu2004.rst @@ -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 diff --git a/doc/developer/topotests-jsontopo.rst b/doc/developer/topotests-jsontopo.rst index 07f1f05114..866f27337f 100644 --- a/doc/developer/topotests-jsontopo.rst +++ b/doc/developer/topotests-jsontopo.rst @@ -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 '. 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 diff --git a/doc/developer/topotests.rst b/doc/developer/topotests.rst index 18317cd33c..4a8f7bd27d 100644 --- a/doc/developer/topotests.rst +++ b/doc/developer/topotests.rst @@ -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,57 +342,80 @@ 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. + +``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. -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``. +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 ``vtysh`` or Shells on Routers -""""""""""""""""""""""""""""""""""""""" - -Topotest can automatically launch a shell or ``vtysh`` for any or all routers in -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. +Spawning Debugging CLI, ``vtysh`` or Shells on Routers on Test Failure +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" -Here's an example of launching ``vtysh`` on routers ``rt1`` and ``rt2``. +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 --vtysh=rt1,rt2 all-protocol-startup - -Spawning Mininet CLI, ``vtysh`` or Shells on Routers on Test Failure -"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + pytest --cli-on-error all-protocol-startup -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``. +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 -Here's an example of having ``vtysh`` launched on test failure. + test_bgp_multiview_topo1/test_bgp_routingTable> help + + Commands: + help :: this help + sh [hosts] :: execute on + term [hosts] :: open shell terminals for hosts + vtysh [hosts] :: open vtysh terminals for hosts + [hosts] :: 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``. -.. code:: shell +Spawning ``vtysh`` or Shells on Routers +""""""""""""""""""""""""""""""""""""""" - pytest --vtysh-on-error all-protocol-startup +Topotest can automatically launch a shell or ``vtysh`` for any or all routers in +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 setup and +each test to allow for inspection of the router state. -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. +Here's an example of launching ``vtysh`` on routers ``rt1`` and ``rt2``. .. code:: shell - pytest --mininet-on-error all-protocol-startup + pytest --vtysh=rt1,rt2 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") + } + +If more specialized topology definitions, or router initialization arguments are +required a build function can be used instead of a dictionary: + +.. code:: py + + def build_topo(tgen): + "Build function" - # Create 2 routers - for routern in range(1, 3): - tgen.add_router('r{}'.format(routern)) + # 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 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']) + # 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 - - ospf-topo1/test_ospf_topo1.py *** Starting controller - - *** 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 -Interface), from here you can call your router ``vtysh`` or even bash. - -Here are some commands example: + 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 -.. 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> +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: - 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 +.. code:: shell + unet> help + Commands: + help :: this help + sh [hosts] :: execute on + term [hosts] :: open shell terminals for hosts + vtysh [hosts] :: open vtysh terminals for hosts + [hosts] :: execute vtysh-command on hosts +.. code:: shell - mininet> r3 vtysh +Here are some commands example: - Hello, this is FRRouting (version 3.1-devrzalamena-build). - Copyright 1996-2005 Kunihiro Ishiguro, et al. +.. code:: shell - 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> 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 + + 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``: -- 2.39.5