1 .. _topotests-snippets:
6 This document will describe common snippets of code that are frequently needed
7 to perform some test checks.
9 Checking for router / test failures
10 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12 The following check uses the topogen API to check for software failure (e.g.
13 zebra died) and/or for errors manually set by ``Topogen.set_error()``.
17 # Get the topology reference
20 # Check for errors in the topology
21 if tgen.routers_have_failure():
22 # Skip the test with the topology errors as reason
23 pytest.skip(tgen.errors)
25 Checking FRR routers version
26 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
28 This code snippet is usually run after the topology setup to make sure all
29 routers instantiated in the topology have the correct software version.
33 # Get the topology reference
37 router_list = tgen.routers()
39 # Run the check for all routers
40 for router in router_list.values():
41 if router.has_version('<', '3'):
42 # Set topology error, so the next tests are skipped
43 tgen.set_error('unsupported version')
45 A sample of this snippet in a test can be found `here
46 <ldp-vpls-topo1/test_ldp_vpls_topo1.py>`__.
48 Interacting with equipment
49 ^^^^^^^^^^^^^^^^^^^^^^^^^^
51 You might want to interact with the topology equipment during the tests and
52 there are different ways to do so.
56 1. When using the Topogen API, all the equipment code derives from ``Topogear``
57 (`lib/topogen.py <lib/topogen.py>`__). If you feel brave you can look by
58 yourself how the abstractions that will be mentioned here work.
60 2. When not using the ``Topogen`` API there is only one way to interact with
61 the equipment, which is by calling the ``mininet`` API functions directly
64 Interacting with the Linux sandbox
65 """"""""""""""""""""""""""""""""""
72 output = net['r1'].cmd('echo "foobar"')
73 print 'output is: {}'.format(output)
80 output = tgen.gears['r1'].run('echo "foobar"')
81 print 'output is: {}'.format(output)
83 Interacting with VTYSH
84 """"""""""""""""""""""
91 output = net['r1'].cmd('vtysh "show ip route" 2>/dev/null')
92 print 'output is: {}'.format(output)
99 output = tgen.gears['r1'].vtysh_cmd("show ip route")
100 print 'output is: {}'.format(output)
102 ``Topogen`` also supports sending multiple lines of command:
107 output = tgen.gears['r1'].vtysh_cmd("""
110 bgp router-id 10.0.255.1
111 neighbor 1.2.3.4 remote-as 10
114 bgp router-id 10.0.255.2
117 print 'output is: {}'.format(output)
119 You might also want to run multiple commands and get only the commands that
125 output = tgen.gears['r1'].vtysh_multicmd("""
128 bgp router-id 10.0.255.1
129 neighbor 1.2.3.4 remote-as 10
132 bgp router-id 10.0.255.2
134 """, pretty_output=false)
135 print 'output is: {}'.format(output)
137 Translating vtysh JSON output into Python structures:
142 json_output = tgen.gears['r1'].vtysh_cmd("show ip route json", isjson=True)
143 output = json.dumps(json_output, indent=4)
144 print 'output is: {}'.format(output)
146 # You can also access the data structure as normal. For example:
147 # protocol = json_output['1.1.1.1/32']['protocol']
148 # assert protocol == "ospf", "wrong protocol"
152 ``vtysh_(multi)cmd`` is only available for router types of equipment.
173 Loading a normal text file content in the current directory:
177 # If you are using Topogen
180 # Otherwise find the directory manually:
181 CURDIR = os.path.dirname(os.path.realpath(__file__))
183 file_name = '{}/r1/show_ip_route.txt'.format(CURDIR)
184 file_content = open(file_name).read()
186 Loading JSON from a file:
192 file_name = '{}/r1/show_ip_route.json'.format(CURDIR)
193 file_content = json.loads(open(file_name).read())
195 Comparing JSON output
196 ^^^^^^^^^^^^^^^^^^^^^
198 After obtaining JSON output formatted with Python data structures, you may use
199 it to assert a minimalist schema:
204 json_output = tgen.gears['r1'].vtysh_cmd("show ip route json", isjson=True)
212 assertmsg = "route 1.1.1.1/32 was not learned through OSPF"
213 assert json_cmp(json_output, expect) is None, assertmsg
215 ``json_cmp`` function description (it might be outdated, you can find the
216 latest description in the source code at
217 :file:`tests/topotests/lib/topotest.py`
221 JSON compare function. Receives two parameters:
223 * `d2`: json subset which we expect
225 Returns `None` when all keys that `d1` has matches `d2`,
226 otherwise a string containing what failed.
228 Note: key absence can be tested by adding a key with value `None`.
233 Preferably, choose the ``sleep`` function that ``topotest`` provides, as it
234 prints a notice during the test execution to help debug topology test execution
239 # Using the topotest sleep
240 from lib import topotest
242 topotest.sleep(10, 'waiting 10 seconds for bla')
243 # or just tell it the time:
245 # It will print 'Sleeping for 10 seconds'.
247 # Or you can also use the Python sleep, but it won't show anything
248 from time import sleep
251 iproute2 Linux commands as JSON
252 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
254 ``topotest`` has two helpers implemented that parses the output of ``ip route``
255 commands to JSON. It might simplify your comparison needs by only needing to
256 provide a Python dictionary.
260 from lib import topotest
263 routes = topotest.ip4_route(tgen.gears['r1'])
271 assertmsg = "failed to find 10.0.1.0/24 and/or 10.0.2.0/24"
272 assert json_cmp(routes, expected) is None, assertmsg