]>
git.proxmox.com Git - mirror_frr.git/blob - tests/topotests/config_timing/test_config_timing.py
2 # SPDX-License-Identifier: ISC
4 # June 2 2021, Christian Hopps <chopps@labn.net>
6 # Copyright (c) 2021, LabN Consulting, L.L.C.
7 # Copyright (c) 2019-2020 by
8 # Donatas Abraitis <donatas.abraitis@gmail.com>
12 Test the timing of config operations.
14 The initial add of 10k routes is used as a baseline for timing and all future
15 operations are expected to complete in under 2 times that baseline. This is a
16 lot of slop; however, the pre-batching code some of these operations (e.g.,
17 adding the same set of 10k routes) would take 100 times longer, so the intention
18 is to catch those types of regressions.
29 CWD
= os
.path
.dirname(os
.path
.realpath(__file__
))
30 sys
.path
.append(os
.path
.join(CWD
, "../"))
32 # pylint: disable=C0413
33 from lib
.topogen
import Topogen
, TopoRouter
, get_topogen
34 from lib
.topolog
import logger
36 pytestmark
= [pytest
.mark
.staticd
]
41 switch
= tgen
.add_switch("s1")
42 switch
.add_link(tgen
.gears
["r1"])
45 def setup_module(mod
):
46 tgen
= Topogen(build_topo
, mod
.__name
__)
49 router_list
= tgen
.routers()
50 for rname
, router
in router_list
.items():
53 os
.path
.join(CWD
, "{}/zebra.conf".format(rname
)),
56 TopoRouter
.RD_STATIC
, os
.path
.join(CWD
, "{}/staticd.conf".format(rname
))
62 def teardown_module(mod
):
67 def get_ip_networks(super_prefix
, base_count
, count
):
68 count_log2
= math
.log(base_count
, 2)
69 if count_log2
!= int(count_log2
):
70 count_log2
= int(count_log2
) + 1
72 count_log2
= int(count_log2
)
73 network
= ipaddress
.ip_network(super_prefix
)
74 return tuple(network
.subnets(count_log2
))[0:count
]
77 def test_static_timing():
80 if tgen
.routers_have_failure():
81 pytest
.skip(tgen
.errors
)
94 router_list
= tgen
.routers()
97 optype
= "adding" if add
else "removing"
98 iptype
= "IPv6" if do_ipv6
else "IPv4"
99 if super_prefix
is None:
100 super_prefix
= u
"2001::/48" if do_ipv6
else u
"10.0.0.0/8"
102 optyped
= "added" if add
else "removed"
104 for rname
, router
in router_list
.items():
105 router
.logger
.info("{} {} static {} routes".format(optype
, count
, iptype
))
107 # Generate config file.
108 config_file
= os
.path
.join(
109 router
.logdir
, rname
, "{}-routes-{}.conf".format(iptype
.lower(), optype
)
111 with
open(config_file
, "w") as f
:
112 for i
, net
in enumerate(get_ip_networks(super_prefix
, base_count
, count
)):
115 f
.write("ip route {} {} bad_input\n".format(net
, via
))
117 f
.write("no ip route {} {} bad_input\n".format(net
, via
))
119 f
.write("ip route {} {}\n".format(net
, via
))
121 f
.write("no ip route {} {}\n".format(net
, via
))
125 router
.vtysh_cmd("debug northbound callbacks configuration")
128 load_command
= 'vtysh -f "{}"'.format(config_file
)
129 tstamp
= datetime
.datetime
.now()
130 output
= router
.run(load_command
)
131 delta
= (datetime
.datetime
.now() - tstamp
).total_seconds()
135 "\nvtysh command => {}\nvtysh output <= {}\nin {}s".format(
136 load_command
, output
, delta
140 limit_delta
= base_delta
* d_multiplier
142 "{} {} {} static routes under {} in {}s (limit: {}s)".format(
143 optyped
, count
, iptype
.lower(), super_prefix
, tot_delta
, limit_delta
147 assert tot_delta
<= limit_delta
152 # Number of static routes
153 router
= tgen
.gears
["r1"]
154 output
= router
.run("vtysh -h | grep address-sanitizer")
156 logger
.info("No Address Sanitizer, generating 10000 routes")
159 logger
.info("Address Sanitizer build, only testing 50 routes")
163 [u
"10.0.0.0/8", u
"11.0.0.0/8"],
164 [u
"2100:1111:2220::/44", u
"2100:3333:4440::/44"],
168 for ipv6
in [False, True]:
169 base_delta
= do_config(
170 prefix_count
, prefix_count
, bad_indices
, 0, 0, True, ipv6
, prefix_base
[ipv6
][0]
173 # Another set of same number of prefixes
175 prefix_count
, prefix_count
, bad_indices
, base_delta
, 3, True, ipv6
, prefix_base
[ipv6
][1]
180 prefix_count
, prefix_count
, bad_indices
, base_delta
, 3, True, ipv6
, prefix_base
[ipv6
][0]
183 # Remove 1/2 of duplicate
192 prefix_base
[ipv6
][0],
195 # Add all back in so 1/2 replicate 1/2 new
197 prefix_count
, prefix_count
, bad_indices
, base_delta
, 3, True, ipv6
, prefix_base
[ipv6
][0]
202 prefix_count
, prefix_count
, bad_indices
, base_delta
, 3, False, ipv6
, prefix_base
[ipv6
][0]
205 prefix_count
, prefix_count
, bad_indices
, base_delta
, 3, False, ipv6
, prefix_base
[ipv6
][1]
209 if __name__
== "__main__":
210 args
= ["-s"] + sys
.argv
[1:]
211 sys
.exit(pytest
.main(args
))