|
3 | 3 | Tests in the topotato framework are structured into different sections that collectively define the test's behavior, topology, and configurations. This document provides an overview of these sections and their components. |
4 | 4 |
|
5 | 5 | <Image src="/anatomy/assets/anatomy.svg" caption="Topotato structure" /> |
| 6 | + |
| 7 | + |
| 8 | + |
| 9 | +### Header |
| 10 | + |
| 11 | +Every test begins with a header that sets the initial context for the test script. The header typically includes the license information, copyright details, and a brief description of the test's purpose. The following Python code demonstrates a sample header: |
| 12 | + |
| 13 | +```python |
| 14 | +#!/usr/bin/env python3 |
| 15 | +# SPDX-License-Identifier: GPL-2.0-or-later |
| 16 | +# Copyright (C) 2070 Some Body |
| 17 | +""" |
| 18 | +Check that the top of the potato has been baked properly. |
| 19 | +""" |
| 20 | + |
| 21 | +from topotato import * |
| 22 | +``` |
| 23 | + |
| 24 | +A few points to note about the header: |
| 25 | + |
| 26 | +- The `topotato` package uses SPDX license identifiers. It's recommended to use the `GPL-2.0-or-later` license unless you have a compelling reason to choose otherwise. |
| 27 | +- A concise docstring describing the test's objective should be included. |
| 28 | +- The `topotato` package is imported using a wildcard import (`*`), which is acceptable in this context. |
| 29 | + |
| 30 | +#### Compatibility Markers |
| 31 | + |
| 32 | +The test script may include compatibility markers to handle changes in the topotato framework. These markers help manage compatibility issues when the framework evolves over time. For instance: |
| 33 | + |
| 34 | +```python |
| 35 | +# Compatibility markers for topotato framework changes |
| 36 | +__topotato_version__ = 1 |
| 37 | +__topotests_file__ = 'potato/test_top.py' |
| 38 | +__topotests_rev__ = 'a770da1b1c6290f53cc69218a30360accd6a0068' |
| 39 | +``` |
| 40 | + |
| 41 | +These markers provide information about the topotato version, the test file, and the revision, aiding in managing compatibility and version control. |
| 42 | + |
| 43 | +</hr> |
| 44 | + |
| 45 | +### Topology Definition |
| 46 | + |
| 47 | +In topotato, a test topology is defined using ASCII diagrams enclosed within a function marked with the `topology_fixture` decorator. Here's an example of defining a topology named `topo1`: |
| 48 | + |
| 49 | +```python |
| 50 | +@topology_fixture() |
| 51 | +def topo1(topo): |
| 52 | + """ |
| 53 | + [ r1 ]---[ r2 ] |
| 54 | + """ |
| 55 | + # Optional modifier code operating on topo.* here |
| 56 | +``` |
| 57 | + |
| 58 | +The ASCII diagram visually represents the topology. The function's name `topo1` identifies the topology. Defining multiple topologies in one file is possible. |
| 59 | + |
| 60 | +<Info>But if complexity grows, it might be better to split the tests into separate files.</Info> |
| 61 | + |
| 62 | +</hr> |
| 63 | + |
| 64 | +### FRR Configurations |
| 65 | + |
| 66 | +Topotato generates FRR configurations using [Jinja2](https://palletsprojects.com/p/jinja/) templates embedded within the test script. Configuration templates define various aspects of router behavior. Here's an example of defining FRR configurations: |
| 67 | + |
| 68 | +<Warning>This Jinja2 template used has been customzied. See [`frr configuration section`](/anatomy/frr-config)</Warning> |
| 69 | + |
| 70 | +```python |
| 71 | +class Configs(FRRConfigs): |
| 72 | + routers = ["r1"] # By default, all systems listed in the topology run FRR |
| 73 | + |
| 74 | + zebra = """ |
| 75 | + #% extends "boilerplate.conf" |
| 76 | + #% block main |
| 77 | + #% for iface in router.ifaces |
| 78 | + interface {{ iface.ifname }} |
| 79 | + description {{ iface.other.endpoint.name }} |
| 80 | + ! |
| 81 | + #% endfor |
| 82 | + ! |
| 83 | + #% endblock |
| 84 | + """ |
| 85 | + |
| 86 | + # Configuration templates for other daemons like staticd, ospfd, etc. |
| 87 | +``` |
| 88 | + |
| 89 | +These configurations can reference dynamic variables, making them more maintainable and easier to understand. |
| 90 | + |
| 91 | +Each *daemon* can be configured for each routers by using their respective name and configuration. |
| 92 | + |
| 93 | +</hr> |
| 94 | + |
| 95 | +### Test Classes |
| 96 | + |
| 97 | +All topotato tests are organized within classes that inherit from the `TestBase` class. The class definition binds together the test content, topology, and configurations. Here's an example: |
| 98 | + |
| 99 | +```python |
| 100 | +class TestSomething(TestBase, AutoFixture, topo=topo1, configs=Configs): |
| 101 | + """ |
| 102 | + This docstring will be included in the HTML report, make it useful. |
| 103 | + """ |
| 104 | +``` |
| 105 | + |
| 106 | +To execute tests, an instance of this class is created, and its test methods are executed in sequence. The test methods can carry data between each other using the `self` object. |
| 107 | +<Warning>However, due to pytest's design, the `__init__` constructor cannot be used.</Warning> |
| 108 | +This structured approach to test organization in topotato simplifies the creation, execution, and debugging of tests while promoting consistency and maintainability. |
0 commit comments