Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Topotato docs anatomy topology #131

Open
wants to merge 18 commits into
base: topotato-base
Choose a base branch
from
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
TOPOTATO TESTING FRAMEWORK (WORK IN PROGRESS)
==========================

LIVE DOCS: [https://docs.page/opensourcerouting/frr~docs](https://docs.page/opensourcerouting/frr~docs)

TODOs / Known issues
====================
Expand Down
68 changes: 68 additions & 0 deletions docs.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
{
"name": "Topotato",
"theme": "#36B9B9",
"sidebar": [
["About", "/"],
["Topotato 1.0 is here!", "/"],
["Todos & Known Issues", "/todos"],
["Getting started", "/getting-started"],
[
"Test Anatomy",
[
["Overview", "/anatomy/overview"],
["Topology", "/anatomy/topology"],
["FRR configuration", "/anatomy/frr-config"],
["Writing tests", "/anatomy/writing-tests"],
["Debug a test", "/anatomy/debug-test"]
]
],
[
"Assertions",
[
["Overview", "/assertions/overview"],
["Usage", "/assertions/usage"],
["AssertKernelRoutes", "/assertions/assert-kernel-routes"],
["AssertKernelRoutesV4", "/assertions/assert-kernel-routes-v4"],
["AssertKernelRoutesV6", "/assertions/assert-kernel-routes-v6"],
["AssertVtysh", "/assertions/assert-vtysh"],
["ReconfigureFRR", "/assertions/reconfigure-frr"],
["AssertPacket", "/assertions/assert-package"],
["AssertLog", "/assertions/assert-log"],
["Delay", "/assertions/delay"]
]
],
[
"Modifiers",
[
["Overview", "/modifiers/overview"],
["Usage", "/modifiers/usage"],
["DaemonRestart", "/modifiers/daemon-restart"],
["ModifyLinkStatus", "/modifiers/modify-link-status"],
["MulticastReceiver", "/modifiers/multicast-receiver"],
["ScapySend", "/modifiers/scapy-send"],
["ExaBGP", "/modifiers/exabgp"]
]
],
[
"How-tos",
[
["TODO", "/howtos/"]
]
],
[
"CLI commands",
[
["test", "/cli-commands/test"],
["bash", "/cli-commands/bash"],
["vm-start", "/cli-commands/vm-start"]
]
],
[
"Environments and CI",
[
["Overview", "/env-ci/overview"],
["Platforms", "/env-ci/platforms"]
]
]
]
}
17 changes: 17 additions & 0 deletions docs/anatomy/assets/anatomy.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
108 changes: 108 additions & 0 deletions docs/anatomy/overview.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# Anatomy of a Test

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.

<Image src="/anatomy/assets/anatomy.svg" caption="Topotato structure" />



### Header

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:

```python
#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2070 Some Body
"""
Check that the top of the potato has been baked properly.
"""

from topotato import *
```

A few points to note about the header:

- 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.
- A concise docstring describing the test's objective should be included.
- The `topotato` package is imported using a wildcard import (`*`), which is acceptable in this context.

#### Compatibility Markers

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:

```python
# Compatibility markers for topotato framework changes
__topotato_version__ = 1
__topotests_file__ = 'potato/test_top.py'
__topotests_rev__ = 'a770da1b1c6290f53cc69218a30360accd6a0068'
```

These markers provide information about the topotato version, the test file, and the revision, aiding in managing compatibility and version control.

</hr>

### Topology Definition

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`:

```python
@topology_fixture()
def topo1(topo):
"""
[ r1 ]---[ r2 ]
"""
# Optional modifier code operating on topo.* here
```

The ASCII diagram visually represents the topology. The function's name `topo1` identifies the topology. Defining multiple topologies in one file is possible.

<Info>But if complexity grows, it might be better to split the tests into separate files.</Info>

</hr>

### FRR Configurations

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:

<Warning>This Jinja2 template used has been customzied. See [`frr configuration section`](/anatomy/frr-config)</Warning>

```python
class Configs(FRRConfigs):
routers = ["r1"] # By default, all systems listed in the topology run FRR

zebra = """
#% extends "boilerplate.conf"
#% block main
#% for iface in router.ifaces
interface {{ iface.ifname }}
description {{ iface.other.endpoint.name }}
!
#% endfor
!
#% endblock
"""

# Configuration templates for other daemons like staticd, ospfd, etc.
```

These configurations can reference dynamic variables, making them more maintainable and easier to understand.

Each *daemon* can be configured for each routers by using their respective name and configuration.

</hr>

### Test Class(es)

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:

```python
class TestSomething(TestBase, AutoFixture, topo=topo1, configs=Configs):
"""
This docstring will be included in the HTML report, make it useful.
"""
```

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.
<Warning>However, due to pytest's design, the `__init__` constructor cannot be used.</Warning>
This structured approach to test organization in topotato simplifies the creation, execution, and debugging of tests while promoting consistency and maintainability.
Loading