diff options
Diffstat (limited to 'tests/topotests/example_test')
-rwxr-xr-x | tests/topotests/example_test/__init__.py | 0 | ||||
-rw-r--r-- | tests/topotests/example_test/r1/zebra.conf | 8 | ||||
-rw-r--r-- | tests/topotests/example_test/r2/zebra.conf | 4 | ||||
-rwxr-xr-x | tests/topotests/example_test/test_example.py | 70 | ||||
-rw-r--r-- | tests/topotests/example_test/test_template.dot | 51 | ||||
-rw-r--r-- | tests/topotests/example_test/test_template.jpg | bin | 0 -> 15470 bytes | |||
-rw-r--r-- | tests/topotests/example_test/test_template.py | 160 | ||||
-rw-r--r-- | tests/topotests/example_test/test_template_json.json | 188 | ||||
-rw-r--r-- | tests/topotests/example_test/test_template_json.py | 55 |
9 files changed, 536 insertions, 0 deletions
diff --git a/tests/topotests/example_test/__init__.py b/tests/topotests/example_test/__init__.py new file mode 100755 index 0000000..e69de29 --- /dev/null +++ b/tests/topotests/example_test/__init__.py diff --git a/tests/topotests/example_test/r1/zebra.conf b/tests/topotests/example_test/r1/zebra.conf new file mode 100644 index 0000000..b733b7b --- /dev/null +++ b/tests/topotests/example_test/r1/zebra.conf @@ -0,0 +1,8 @@ +interface r1-eth0 + ip address 192.168.1.1/24 + +interface r1-eth1 + ip address 192.168.2.1/24 + +interface r1-eth2 + ip address 192.168.3.1/24
\ No newline at end of file diff --git a/tests/topotests/example_test/r2/zebra.conf b/tests/topotests/example_test/r2/zebra.conf new file mode 100644 index 0000000..c0921f5 --- /dev/null +++ b/tests/topotests/example_test/r2/zebra.conf @@ -0,0 +1,4 @@ +interface r2-eth0 + ip address 192.168.1.2/24 +interface r2-eth1 + ip address 192.168.3.2/24 diff --git a/tests/topotests/example_test/test_example.py b/tests/topotests/example_test/test_example.py new file mode 100755 index 0000000..30c3d24 --- /dev/null +++ b/tests/topotests/example_test/test_example.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python + +import subprocess +import sys +import os +import time + +import pytest + +fatal_error = "" + + +def setup_module(module): + print("setup_module module:%s" % module.__name__) + + +def teardown_module(module): + print("teardown_module module:%s" % module.__name__) + + +def setup_function(function): + print("setup_function function:%s" % function.__name__) + + +def teardown_function(function): + print("teardown_function function:%s" % function.__name__) + + +def test_numbers_compare(): + a = 12 + print("Dummy Output") + assert a == 12 + + +def test_fail_example(): + assert True, "Some Text with explaination in case of failure" + + +@pytest.mark.xfail +def test_ls_exits_zero(): + "Tests for ls command on invalid file" + + global fatal_error + + proc = subprocess.Popen( + ["ls", "/some/nonexistant/file"], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) + stdout, stderr = proc.communicate() + + if proc.returncode != 0: + # Mark this as a fatal error which skips some other tests on failure + fatal_error = "test_fail_example failed" + assert proc.returncode == 0, "Return Code is non-Zero:\n%s" % stderr + + +def test_skipped_on_fatalerror(): + global fatal_error + + # Skip if previous fatal error condition is raised + if fatal_error != "": + pytest.skip(fatal_error) + + assert True, "Some Text with explaination in case of failure" + + +if __name__ == "__main__": + retval = pytest.main(["-s"]) + sys.exit(retval) diff --git a/tests/topotests/example_test/test_template.dot b/tests/topotests/example_test/test_template.dot new file mode 100644 index 0000000..b5e1202 --- /dev/null +++ b/tests/topotests/example_test/test_template.dot @@ -0,0 +1,51 @@ +## Color coding: +######################### +## Main FRR: #f08080 red +## Switches: #d0e0d0 gray +## RIP: #19e3d9 Cyan +## RIPng: #fcb314 dark yellow +## OSPFv2: #32b835 Green +## OSPFv3: #19e3d9 Cyan +## ISIS IPv4 #fcb314 dark yellow +## ISIS IPv6 #9a81ec purple +## BGP IPv4 #eee3d3 beige +## BGP IPv6 #fdff00 yellow +##### Colors (see http://www.color-hex.com/) + +graph template { + label="template"; + + # Routers + r1 [ + shape=doubleoctagon, + label="r1", + fillcolor="#f08080", + style=filled, + ]; + r2 [ + shape=doubleoctagon + label="r2", + fillcolor="#f08080", + style=filled, + ]; + + # Switches + s1 [ + shape=oval, + label="s1\n192.168.0.0/24", + fillcolor="#d0e0d0", + style=filled, + ]; + s2 [ + shape=oval, + label="s2\n192.168.1.0/24", + fillcolor="#d0e0d0", + style=filled, + ]; + + # Connections + r1 -- s1 [label="eth0\n.1"]; + + r1 -- s2 [label="eth1\n.100"]; + r2 -- s2 [label="eth0\n.1"]; +} diff --git a/tests/topotests/example_test/test_template.jpg b/tests/topotests/example_test/test_template.jpg Binary files differnew file mode 100644 index 0000000..b01ef73 --- /dev/null +++ b/tests/topotests/example_test/test_template.jpg diff --git a/tests/topotests/example_test/test_template.py b/tests/topotests/example_test/test_template.py new file mode 100644 index 0000000..2797548 --- /dev/null +++ b/tests/topotests/example_test/test_template.py @@ -0,0 +1,160 @@ +#!/usr/bin/env python +# -*- coding: utf-8 eval: (blacken-mode 1) -*- +# SPDX-License-Identifier: ISC +# +# <template>.py +# Part of NetDEF Topology Tests +# +# Copyright (c) 2017 by +# Network Device Education Foundation, Inc. ("NetDEF") +# + +""" +<template>.py: Test <template>. +""" + +import sys +import pytest + +from lib.topogen import Topogen, TopoRouter +from lib.topolog import logger + +# TODO: select markers based on daemons used during test +# pytest module level markers +pytestmark = [ + # pytest.mark.babeld, + # pytest.mark.bfdd, + # pytest.mark.bgpd, + # pytest.mark.eigrpd, + # pytest.mark.isisd, + # pytest.mark.ldpd, + # pytest.mark.nhrpd, + # pytest.mark.ospf6d, + pytest.mark.ospfd, + # pytest.mark.pathd, + # pytest.mark.pbrd, + # pytest.mark.pimd, + # pytest.mark.ripd, + # pytest.mark.ripngd, + # pytest.mark.sharpd, + # pytest.mark.staticd, + # pytest.mark.vrrpd, +] + +# Function we pass to Topogen to create the topology +def build_topo(tgen): + "Build function" + + # Create 2 routers + r1 = tgen.add_router("r1") + r2 = tgen.add_router("r2") + + # Create a p2p connection between r1 and r2 + tgen.add_link(r1, r2) + + # Create a switch with one router connected to it to simulate a empty network. + switch = tgen.add_switch("s1") + switch.add_link(r1) + + # Create a p2p connection between r1 and r2 + switch = tgen.add_switch("s2") + switch.add_link(r1) + switch.add_link(r2) + + +# New form of setup/teardown using pytest fixture +@pytest.fixture(scope="module") +def tgen(request): + "Setup/Teardown the environment and provide tgen argument to tests" + + # This function initiates the topology build with Topogen... + tgen = Topogen(build_topo, request.module.__name__) + + # A basic topology similar to the above could also have be more easily specified + # using a # dictionary, remove the build_topo function and use the following + # instead: + # + # topodef = { + # "s1": "r1" + # "s2": ("r1", "r2") + # } + # tgen = Topogen(topodef, request.module.__name__) + + # ... and here it calls initialization functions. + tgen.start_topology() + + # This is a sample of configuration loading. + router_list = tgen.routers() + + # For all routers arrange for: + # - starting zebra using config file from <rtrname>/zebra.conf + # - starting ospfd using an empty config file. + for rname, router in router_list.items(): + router.load_config(TopoRouter.RD_ZEBRA, "zebra.conf") + router.load_config(TopoRouter.RD_OSPF) + + # Start and configure the router daemons + tgen.start_router() + + # Provide tgen as argument to each test function + yield tgen + + # Teardown after last test runs + tgen.stop_topology() + + +# Fixture that executes before each test +@pytest.fixture(autouse=True) +def skip_on_failure(tgen): + if tgen.routers_have_failure(): + pytest.skip("skipped because of previous test failure") + + +# =================== +# The tests functions +# =================== + + +def test_get_version(tgen): + "Test the logs the FRR version" + + r1 = tgen.gears["r1"] + version = r1.vtysh_cmd("show version") + logger.info("FRR version is: " + version) + + +def test_connectivity(tgen): + "Test the logs the FRR version" + + r1 = tgen.gears["r1"] + r2 = tgen.gears["r2"] + output = r1.cmd_raises("ping -c1 192.168.1.2") + output = r2.cmd_raises("ping -c1 192.168.3.1") + + +@pytest.mark.xfail +def test_expect_failure(tgen): + "A test that is current expected to fail but should be fixed" + + assert False, "Example of temporary expected failure that will eventually be fixed" + + +@pytest.mark.skip +def test_will_be_skipped(tgen): + "A test that will be skipped" + assert False + + +# Memory leak test template +def test_memory_leak(tgen): + "Run the memory leak test and report results." + + if not tgen.is_memleak_enabled(): + pytest.skip("Memory leak test/report is disabled") + + tgen.report_memory_leaks() + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/tests/topotests/example_test/test_template_json.json b/tests/topotests/example_test/test_template_json.json new file mode 100644 index 0000000..1ed4a9d --- /dev/null +++ b/tests/topotests/example_test/test_template_json.json @@ -0,0 +1,188 @@ + +{ + "address_types": ["ipv4","ipv6"], + "ipv4base":"10.0.0.0", + "ipv4mask":30, + "ipv6base":"fd00::", + "ipv6mask":64, + "link_ip_start":{"ipv4":"10.0.0.0", "v4mask":30, "ipv6":"fd00::", "v6mask":64}, + "lo_prefix":{"ipv4":"1.0.", "v4mask":32, "ipv6":"2001:DB8:F::", "v6mask":128}, + "routers":{ + "r1":{ + "links":{ + "lo": {"ipv4": "auto", "ipv6": "auto", "type": "loopback"}, + "r2":{"ipv4":"auto", "ipv6":"auto"}, + "r3":{"ipv4":"auto", "ipv6":"auto"} + }, + "bgp":{ + "local_as":"100", + "address_family": { + "ipv4": { + "unicast": { + "neighbor": { + "r2": { + "dest_link": { + "r1": {} + } + }, + "r3": { + "dest_link": { + "r1": {} + } + } + } + } + }, + "ipv6": { + "unicast": { + "neighbor": { + "r2": { + "dest_link": { + "r1": {} + } + }, + "r3": { + "dest_link": { + "r1": {} + } + } + } + } + } + } + } + }, + "r2":{ + "links":{ + "lo": {"ipv4": "auto", "ipv6": "auto", "type": "loopback"}, + "r1":{"ipv4":"auto", "ipv6":"auto"}, + "r3":{"ipv4":"auto", "ipv6":"auto"} + }, + "bgp":{ + "local_as":"100", + "address_family": { + "ipv4": { + "unicast": { + "neighbor": { + "r1": { + "dest_link": { + "r2": {} + } + }, + "r3": { + "dest_link": { + "r2": {} + } + } + } + } + }, + "ipv6": { + "unicast": { + "neighbor": { + "r1": { + "dest_link": { + "r2": {} + } + }, + "r3": { + "dest_link": { + "r2": {} + } + } + } + } + } + } + } + }, + "r3":{ + "links":{ + "lo": {"ipv4": "auto", "ipv6": "auto", "type": "loopback"}, + "r1":{"ipv4":"auto", "ipv6":"auto"}, + "r2":{"ipv4":"auto", "ipv6":"auto"}, + "r4":{"ipv4":"auto", "ipv6":"auto"} + }, + "bgp":{ + "local_as":"100", + "address_family": { + "ipv4": { + "unicast": { + "neighbor": { + "r1": { + "dest_link": { + "r3": {} + } + }, + "r2": { + "dest_link": { + "r3": {} + } + }, + "r4": { + "dest_link": { + "r3": {} + } + } + } + } + }, + "ipv6": { + "unicast": { + "neighbor": { + "r1": { + "dest_link": { + "r3": {} + } + }, + "r2": { + "dest_link": { + "r3": {} + } + }, + "r4": { + "dest_link": { + "r3": {} + } + } + } + } + } + } + } + }, + "r4":{ + "links":{ + "lo": {"ipv4": "auto", "ipv6": "auto", "type": "loopback"}, + "r3":{"ipv4":"auto", "ipv6":"auto"} + }, + "bgp":{ + "local_as":"200", + "address_family": { + "ipv4": { + "unicast": { + "neighbor": { + "r3": { + "dest_link": { + "r4": {} + } + } + } + } + }, + "ipv6": { + "unicast": { + "neighbor": { + "r3": { + "dest_link": { + "r4": {} + } + } + } + } + } + } + } + } + } +} diff --git a/tests/topotests/example_test/test_template_json.py b/tests/topotests/example_test/test_template_json.py new file mode 100644 index 0000000..7a53260 --- /dev/null +++ b/tests/topotests/example_test/test_template_json.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: ISC +# +# September 5 2021, Christian Hopps <chopps@labn.net> +# +# Copyright (c) 2021, LabN Consulting, L.L.C. +# Copyright (c) 2017 by +# Network Device Education Foundation, Inc. ("NetDEF") +# + +""" +<template>.py: Test <template>. +""" + +import pytest + +# Import topogen and topotest helpers +from lib import bgp +from lib import fixtures + + +# TODO: select markers based on daemons used during test +pytestmark = [ + pytest.mark.bgpd, + # pytest.mark.ospfd, + # pytest.mark.ospf6d + # ... +] + +# Use tgen_json fixture (invoked by use test arg of same name) to +# setup/teardown standard JSON topotest +tgen = pytest.fixture(fixtures.tgen_json, scope="module") + + +# tgen is defined above +# topo is a fixture defined in ../conftest.py +def test_bgp_convergence(tgen, topo): + "Test for BGP convergence." + + # Don't run this test if we have any failure. + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + bgp_convergence = bgp.verify_bgp_convergence(tgen, topo) + assert bgp_convergence + + +# Memory leak test template +def test_memory_leak(tgen): + "Run the memory leak test and report results." + + if not tgen.is_memleak_enabled(): + pytest.skip("Memory leak test/report is disabled") + + tgen.report_memory_leaks() |