4 # Copyright (c) 2020 by VMware, Inc. ("VMware")
5 # Used Copyright (c) 2018 by Network Device Education Foundation, Inc.
6 # ("NetDEF") in this file.
8 # Permission to use, copy, modify, and/or distribute this software
9 # for any purpose with or without fee is hereby granted, provided
10 # that the above copyright notice and this permission notice appear
13 # THE SOFTWARE IS PROVIDED "AS IS" AND VMWARE DISCLAIMS ALL WARRANTIES
14 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE BE LIABLE FOR
16 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
17 # DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18 # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
19 # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
24 """OSPF Basic Functionality Automation."""
29 from time
import sleep
30 from copy
import deepcopy
32 from lib
.topotest
import frr_unicode
34 # Save the Current Working Directory to find configuration files.
35 CWD
= os
.path
.dirname(os
.path
.realpath(__file__
))
36 sys
.path
.append(os
.path
.join(CWD
, "../"))
37 sys
.path
.append(os
.path
.join(CWD
, "../lib/"))
39 # pylint: disable=C0413
40 # Import topogen and topotest helpers
41 from mininet
.topo
import Topo
42 from lib
.topogen
import Topogen
, get_topogen
44 # Import topoJson from lib, to create topology and initial configuration
45 from lib
.common_config
import (
49 reset_config_on_routers
,
51 shutdown_bringup_interface
,
54 from lib
.topolog
import logger
55 from lib
.topojson
import build_topo_from_json
, build_config_from_json
56 from lib
.ospf
import verify_ospf_neighbor
, config_ospf_interface
, clear_ospf
57 from ipaddress
import IPv4Address
59 pytestmark
= [pytest
.mark
.ospfd
]
64 # Reading the data from JSON File for topology creation
65 jsonFile
= "{}/ospf_authentication.json".format(CWD
)
67 with
open(jsonFile
, "r") as topoJson
:
68 topo
= json
.load(topoJson
)
70 assert False, "Could not read file {}".format(jsonFile
)
73 Please view in a fixed-width font such as Courier.
75 +R1 +------------+R2 |
84 +R0 +-------------+R3 |
88 1. Verify ospf authentication with Simple password authentication.
89 2. Verify ospf authentication with MD5 authentication.
90 3. Verify ospf authentication with different authentication methods.
95 class CreateTopo(Topo
):
97 Test topology builder.
99 * `Topo`: Topology object
102 def build(self
, *_args
, **_opts
):
103 """Build function."""
104 tgen
= get_topogen(self
)
106 # Building topology from json file
107 build_topo_from_json(tgen
, topo
)
110 def setup_module(mod
):
112 Sets up the pytest environment
117 testsuite_run_time
= time
.asctime(time
.localtime(time
.time()))
118 logger
.info("Testsuite start time: {}".format(testsuite_run_time
))
119 logger
.info("=" * 40)
121 logger
.info("Running setup_module to create topology")
123 # This function initiates the topology build with Topogen...
124 tgen
= Topogen(CreateTopo
, mod
.__name
__)
125 # ... and here it calls Mininet initialization functions.
127 # get list of daemons needs to be started for this suite.
128 daemons
= topo_daemons(tgen
, topo
)
130 # Starting topology, create tmp files which are loaded to routers
131 # to start deamons and then start routers
132 start_topology(tgen
, daemons
)
134 # Creating configuration from JSON
135 build_config_from_json(tgen
, topo
)
137 # Don't run this test if we have any failure.
138 if tgen
.routers_have_failure():
139 pytest
.skip(tgen
.errors
)
141 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
)
142 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
146 logger
.info("Running setup_module() done")
149 def teardown_module(mod
):
151 Teardown the pytest environment.
156 logger
.info("Running teardown_module to delete topology")
160 # Stop toplogy and Remove tmp files
164 "Testsuite end time: {}".format(time
.asctime(time
.localtime(time
.time())))
166 logger
.info("=" * 40)
169 # ##################################
170 # Test cases start here.
171 # ##################################
174 def test_ospf_authentication_simple_pass_tc28_p1(request
):
176 OSPF Authentication - Verify ospf authentication with Simple
177 password authentication.
180 tc_name
= request
.node
.name
181 write_test_header(tc_name
)
184 step("Bring up the base config.")
185 reset_config_on_routers(tgen
)
187 "Configure ospf with on R1 and R2, enable ospf on R1 interface"
188 "connected to R2 with simple password authentication using ip ospf "
189 "authentication Simple password cmd."
195 "r2": {"ospf": {"authentication": True, "authentication-key": "ospf"}}
199 result
= config_ospf_interface(tgen
, topo
, r1_ospf_auth
)
200 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
202 step("clear ip ospf after configuring the authentication.")
203 clear_ospf(tgen
, "r1")
205 step("Verify that the neighbour is not FULL between R1 and R2.")
207 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
, expected
=False)
208 assert ospf_covergence
is not True, "setup_module :Failed \n Error:" " {}".format(
213 "On R2 enable ospf on interface with simple password authentication "
214 "using ip ospf authentication Simple password cmd."
220 "r1": {"ospf": {"authentication": True, "authentication-key": "ospf"}}
224 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
225 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
228 "Verify that the neighbour is FULL between R1 and R2 "
229 "using show ip ospf neighbor cmd."
233 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
234 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
239 "Disable simple password authentication on R2 using no ip ospf "
240 "authentication Simple password cmd."
247 "authentication": True,
248 "authentication-key": "ospf",
255 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
256 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
258 step("Verify on R1 neighbour is deleted for R2 after dead interval expiry")
259 # wait till the dead time expiry
262 ospf_covergence
= verify_ospf_neighbor(
263 tgen
, topo
, dut
=dut
, expected
=False, retry_timeout
=10
265 assert ospf_covergence
is not True, "setup_module :Failed \n Error:" " {}".format(
269 step("Again On R2 enable ospf on interface with Simple password auth")
273 "r1": {"ospf": {"authentication": True, "authentication-key": "ospf"}}
277 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
278 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
281 "Verify that the neighbour is FULL between R1 and R2 using"
282 " show ip ospf neighbor cmd."
286 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
287 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
291 step("Shut no shut interface on R1")
293 intf
= topo
["routers"]["r1"]["links"]["r2"]["interface"]
294 shutdown_bringup_interface(tgen
, dut
, intf
, False)
298 "Verify that the neighbour is not FULL between R1 and R2 using "
299 "show ip ospf neighbor cmd."
301 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
, expected
=False)
302 assert ospf_covergence
is not True, "setup_module :Failed \n Error:" " {}".format(
307 shutdown_bringup_interface(tgen
, dut
, intf
, True)
310 "Verify that the neighbour is FULL between R1 and R2 using "
311 "show ip ospf neighbor cmd."
315 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
316 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
320 step("Change Ip address on R1 and R2")
322 topo_modify_change_ip
= deepcopy(topo
)
323 intf_ip
= topo_modify_change_ip
["routers"]["r1"]["links"]["r2"]["ipv4"]
324 topo_modify_change_ip
["routers"]["r1"]["links"]["r2"]["ipv4"] = str(
325 IPv4Address(frr_unicode(intf_ip
.split("/")[0])) + 3
326 ) + "/{}".format(intf_ip
.split("/")[1])
328 build_config_from_json(tgen
, topo_modify_change_ip
, save_bkup
=False)
330 reset_config_on_routers(tgen
, routerName
="r1")
332 intf
= topo
["routers"]["r1"]["links"]["r2"]["interface"]
333 shutdown_bringup_interface(tgen
, dut
, intf
, False)
334 shutdown_bringup_interface(tgen
, dut
, intf
, True)
336 # clear ip ospf after configuring the authentication.
337 clear_ospf(tgen
, "r1")
342 "r2": {"ospf": {"authentication": True, "authentication-key": "ospf"}}
346 result
= config_ospf_interface(tgen
, topo
, r1_ospf_auth
)
347 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
350 "Verify that the neighbour is FULL between R1 and R2 with new "
351 "ip address using show ip ospf "
355 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
356 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
360 write_test_footer(tc_name
)
363 def test_ospf_authentication_md5_tc29_p1(request
):
365 OSPF Authentication - Verify ospf authentication with MD5 authentication.
368 tc_name
= request
.node
.name
369 write_test_header(tc_name
)
372 step("Bring up the base config.")
373 reset_config_on_routers(tgen
)
375 "Configure ospf with on R1 and R2, enable ospf on R1 interface "
376 "connected to R2 with message-digest authentication using ip "
377 "ospf authentication message-digest cmd."
385 "authentication": "message-digest",
386 "authentication-key": "ospf",
387 "message-digest-key": "10",
393 result
= config_ospf_interface(tgen
, topo
, r1_ospf_auth
)
394 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
396 step("Verify that the neighbour is not FULL between R1 and R2.")
397 # wait for dead time expiry.
400 ospf_covergence
= verify_ospf_neighbor(
401 tgen
, topo
, dut
=dut
, expected
=False, retry_timeout
=6
403 assert ospf_covergence
is not True, "setup_module :Failed \n Error:" " {}".format(
408 "On R2 enable ospf on interface with message-digest authentication"
409 " using ip ospf authentication message-digest password cmd."
417 "authentication": "message-digest",
418 "authentication-key": "ospf",
419 "message-digest-key": "10",
425 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
426 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
429 "Verify that the neighbour is FULL between R1 and R2 "
430 "using show ip ospf neighbor cmd."
434 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
435 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
440 "Disable message-digest authentication on R2 using no ip ospf "
441 "authentication message-digest password cmd."
449 "authentication": "message-digest",
450 "authentication-key": "ospf",
451 "message-digest-key": "10",
458 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
459 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
461 step("Verify on R1 ,nbr is deleted for R2 after dead interval expiry")
462 # wait till the dead timer expiry
465 ospf_covergence
= verify_ospf_neighbor(
466 tgen
, topo
, dut
=dut
, expected
=False, retry_timeout
=10
468 assert ospf_covergence
is not True, "setup_module :Failed \n Error:" " {}".format(
472 step("Again On R2 enable ospf on interface with message-digest auth")
478 "authentication": "message-digest",
479 "authentication-key": "ospf",
480 "message-digest-key": "10",
486 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
487 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
490 "Verify that the neighbour is FULL between R1 and R2 using"
491 " show ip ospf neighbor cmd."
495 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
496 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
500 step("Shut no shut interface on R1")
502 intf
= topo
["routers"]["r1"]["links"]["r2"]["interface"]
503 shutdown_bringup_interface(tgen
, dut
, intf
, False)
507 "Verify that the neighbour is not FULL between R1 and R2 using "
508 "show ip ospf neighbor cmd."
510 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
, expected
=False)
511 assert ospf_covergence
is not True, "setup_module :Failed \n Error:" " {}".format(
516 shutdown_bringup_interface(tgen
, dut
, intf
, True)
519 "Verify that the neighbour is FULL between R1 and R2 using "
520 "show ip ospf neighbor cmd."
524 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
525 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
529 step("Change Ip address on R1 and R2")
531 topo_modify_change_ip
= deepcopy(topo
)
533 intf_ip
= topo_modify_change_ip
["routers"]["r1"]["links"]["r2"]["ipv4"]
535 topo_modify_change_ip
["routers"]["r1"]["links"]["r2"]["ipv4"] = str(
536 IPv4Address(frr_unicode(intf_ip
.split("/")[0])) + 3
537 ) + "/{}".format(intf_ip
.split("/")[1])
539 build_config_from_json(tgen
, topo_modify_change_ip
, save_bkup
=False)
541 reset_config_on_routers(tgen
, routerName
="r1")
543 intf
= topo
["routers"]["r1"]["links"]["r2"]["interface"]
544 shutdown_bringup_interface(tgen
, dut
, intf
, False)
545 shutdown_bringup_interface(tgen
, dut
, intf
, True)
546 clear_ospf(tgen
, "r1")
552 "authentication": "message-digest",
553 "authentication-key": "ospf",
554 "message-digest-key": "10",
560 result
= config_ospf_interface(tgen
, topo
, r1_ospf_auth
)
561 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
564 "Verify that the neighbour is FULL between R1 and R2 with new "
565 "ip address using show ip ospf "
569 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
570 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
574 write_test_footer(tc_name
)
577 def test_ospf_authentication_different_auths_tc30_p1(request
):
579 OSPF Authentication - Verify ospf authentication with different
580 authentication methods.
583 tc_name
= request
.node
.name
584 write_test_header(tc_name
)
587 step("Bring up the base config.")
588 reset_config_on_routers(tgen
)
590 "Configure ospf with on R1 and R2, enable ospf on R1 interface "
591 "connected to R2 with message-digest authentication using ip "
592 "ospf authentication message-digest cmd."
600 "authentication": "message-digest",
601 "authentication-key": "ospf",
602 "message-digest-key": "10",
608 result
= config_ospf_interface(tgen
, topo
, r1_ospf_auth
)
609 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
611 # wait for dead timer expiry
613 step("Verify that the neighbour is not FULL between R1 and R2.")
615 ospf_covergence
= verify_ospf_neighbor(
616 tgen
, topo
, dut
=dut
, expected
=False, retry_timeout
=10
618 assert ospf_covergence
is not True, "setup_module :Failed \n Error:" " {}".format(
623 "On R2 enable ospf on interface with message-digest authentication"
624 " using ip ospf authentication message-digest password cmd."
632 "authentication": "message-digest",
633 "authentication-key": "ospf",
634 "message-digest-key": "10",
640 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
641 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
644 "Verify that the neighbour is FULL between R1 and R2 "
645 "using show ip ospf neighbor cmd."
649 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
650 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
654 step(" Delete the configured password on both the routers.")
661 "authentication": "message-digest",
662 "authentication-key": "ospf",
663 "message-digest-key": "10",
670 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
671 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
678 "authentication": "message-digest",
679 "authentication-key": "ospf",
680 "message-digest-key": "10",
687 result
= config_ospf_interface(tgen
, topo
, r1_ospf_auth
)
688 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
691 "Verify that the deletion is successful and neighbour is FULL"
692 " between R1 and R2 using show ip ospf neighbor cmd."
696 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
697 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
701 step("Change the authentication type to simple password.")
705 "r2": {"ospf": {"authentication": True, "authentication-key": "ospf"}}
709 result
= config_ospf_interface(tgen
, topo
, r1_ospf_auth
)
710 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
715 "r1": {"ospf": {"authentication": True, "authentication-key": "ospf"}}
719 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
720 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
723 "Verify that the deletion is successful and neighbour is"
724 " FULL between R1 and R2 using show ip "
728 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
729 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
733 step("Change the password in simple password.")
738 "r2": {"ospf": {"authentication": True, "authentication-key": "OSPFv4"}}
742 result
= config_ospf_interface(tgen
, topo
, r1_ospf_auth
)
743 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
748 "r1": {"ospf": {"authentication": True, "authentication-key": "OSPFv4"}}
752 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
753 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
756 "Verify that the deletion is successful and neighbour is"
757 " FULL between R1 and R2 using show ip "
761 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
762 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
766 step("Delete the password authentication on the interface ")
773 "authentication": True,
774 "authentication-key": "OSPFv4",
781 result
= config_ospf_interface(tgen
, topo
, r1_ospf_auth
)
782 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
789 "authentication": True,
790 "authentication-key": "OSPFv4",
797 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
798 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
801 "Verify that the deletion is successful and neighbour is"
802 " FULL between R1 and R2 using show ip "
806 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
807 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
811 step("Enable Md5 authentication on the interface")
818 "authentication": "message-digest",
819 "authentication-key": "ospf",
820 "message-digest-key": "10",
826 result
= config_ospf_interface(tgen
, topo
, r1_ospf_auth
)
827 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
834 "authentication": "message-digest",
835 "authentication-key": "ospf",
836 "message-digest-key": "10",
842 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
843 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
846 "Verify that the neighbour is FULL between R1 and R2 using"
847 " show ip ospf neighbor cmd."
851 ospf_covergence
= verify_ospf_neighbor(tgen
, topo
, dut
=dut
)
852 assert ospf_covergence
is True, "setup_module :Failed \n Error:" " {}".format(
856 step("Change the MD5 authentication password")
863 "authentication": "message-digest",
864 "authentication-key": "OSPFv4",
865 "message-digest-key": "10",
871 result
= config_ospf_interface(tgen
, topo
, r1_ospf_auth
)
872 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
879 "authentication": "message-digest",
880 "authentication-key": "OSPFv4",
881 "message-digest-key": "10",
887 result
= config_ospf_interface(tgen
, topo
, r2_ospf_auth
)
888 assert result
is True, "Testcase {} :Failed \n Error: {}".format(tc_name
, result
)
890 write_test_footer(tc_name
)
893 if __name__
== "__main__":
894 args
= ["-s"] + sys
.argv
[1:]
895 sys
.exit(pytest
.main(args
))