Skip to content

Commit

Permalink
doc: Update doc and lint it (#847)
Browse files Browse the repository at this point in the history
Doc: Update doc and lint it
  • Loading branch information
gmuloc authored Oct 2, 2024
1 parent 2a309de commit fc644a1
Show file tree
Hide file tree
Showing 33 changed files with 237 additions and 107 deletions.
98 changes: 98 additions & 0 deletions .github/markdownlint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# markdownlint configuration
# the definitive list of rules for markdownlint can be found:
# https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md
#
# only deviations from the defaults are noted here or where there's an opinion
# being expressed.

# default state for all rules
default:
true

# heading style
MD003:
style: "atx"

# unordered list style
MD004:
style: "dash"

# unorderd list indentation (2-spaces)
# keep it tight yo!
MD007:
indent: 2

# line length
MD013:
false
# a lot of debate whether to wrap or not wrap

# multiple headings with the same content
# siblings_only is set here to allow for common header values in structured
# documents
MD024:
siblings_only: true

# Multiple top-level headings in the same document
MD025:
front_matter_title: ""

# MD029/ol-prefix - Ordered list item prefix
MD029:
# List style
style: "ordered"

# fenced code should be surrounded by blank lines default: true
MD031:
true

# lists should be surrounded by blank lines default: true
MD032:
true

# MD033/no-inline-html - Inline HTML
MD033:
false

# bare URL - bare URLs should be wrapped in angle brackets
# <https://eos.arista.com>
MD034:
false

# horizontal rule style default: consistent
MD035:
style: "---"

# first line in a file to be a top-level heading
# since we're using front-matter, this
MD041:
false

# proper-names - proper names to have the correct capitalization
# probably not entirely helpful in a technical writing environment.
MD044:
false

# block style - disabled to allow for admonitions
MD046:
false

# MD048/code-fence-style - Code fence style
MD048:
# Code fence style
style: "backtick"

# MD049/Emphasis style should be consistent
MD049:
# Emphasis style should be consistent
style: "asterisk"

# MD050/Strong style should be consistent
MD050:
# Strong style should be consistent
style: "asterisk"

# MD037/no-space-in-emphasis - Spaces inside emphasis markers
# This incorrectly catches stars used in table contents, so *foo | *bar is triggered to remove the space between | and *bar.
MD037:
false
Empty file added .github/markdownlintignore
Empty file.
10 changes: 10 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,13 @@ repos:
- types-pyOpenSSL
- pytest
files: ^(anta|tests)/

- repo: https://github.com/igorshubovych/markdownlint-cli
rev: v0.41.0
hooks:
- id: markdownlint
name: Check Markdown files style.
args:
- --config=.github/markdownlint.yaml
- --ignore-path=.github/markdownlintignore
- --fix
2 changes: 1 addition & 1 deletion anta/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ async def setup_inventory(inventory: AntaInventory, tags: set[str] | None, devic
devices
Devices on which to run tests. None means all devices.
established_only
If True use return only devices where a connection is established.
If True use return only devices where a connection is established.
Returns
-------
Expand Down
2 changes: 2 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ If you plan to use ANTA only as a CLI tool you can use `pipx` to install it.
[`pipx`](https://pipx.pypa.io/stable/) is a tool to install and run python applications in isolated environments. Refer to `pipx` instructions to install on your system.
`pipx` installs ANTA in an isolated python environment and makes it available globally.

<!-- markdownlint-disable no-emphasis-as-heading -->
**This is not recommended if you plan to contribute to ANTA**
<!-- markdownlint-enable no-emphasis-as-heading -->

```bash
# Install ANTA CLI with pipx
Expand Down
13 changes: 4 additions & 9 deletions docs/advanced_usages/as-python-lib.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ It uses the [aio-eapi](https://github.com/jeremyschulman/aio-eapi) eAPI client a

The [AntaInventory](../api/inventory.md#anta.inventory.AntaInventory) class is a subclass of the standard Python type [dict](https://docs.python.org/3/library/stdtypes.html#dict). The keys of this dictionary are the device names, the values are [AntaDevice](../api/device.md#anta.device.AntaDevice) instances.


[AntaInventory](../api/inventory.md#anta.inventory.AntaInventory) provides methods to interact with the ANTA inventory:

- The [add_device()](../api/inventory.md#anta.inventory.AntaInventory.add_device) method adds an [AntaDevice](../api/device.md#anta.device.AntaDevice) instance to the inventory. Adding an entry to [AntaInventory](../api/inventory.md#anta.inventory.AntaInventory) with a key different from the device name is not allowed.
Expand All @@ -42,13 +41,11 @@ The [AntaInventory](../api/inventory.md#anta.inventory.AntaInventory) class is a

## Examples

##### Parse an ANTA inventory file

> This script parses an ANTA inventory file, connects to devices and print their status
### Parse an ANTA inventory file

```python
"""
Example
This script parses an ANTA inventory file, connects to devices and print their status.
"""
import asyncio

Expand Down Expand Up @@ -84,13 +81,11 @@ if __name__ == "__main__":
??? note "How to create your inventory file"
Please visit this [dedicated section](../usage-inventory-catalog.md) for how to use inventory and catalog files.

##### Run EOS commands

> This script runs a list of EOS commands on reachable devices
### Run EOS commands

```python
"""
Example
This script runs a list of EOS commands on reachable devices.
"""
# This is needed to run the script for python < 3.10 for typing annotations
from __future__ import annotations
Expand Down
10 changes: 7 additions & 3 deletions docs/advanced_usages/caching.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ ANTA is a streamlined Python framework designed for efficient interaction with n

By default, ANTA utilizes [aiocache](https://github.com/aio-libs/aiocache)'s memory cache backend, also called [`SimpleMemoryCache`](https://aiocache.aio-libs.org/en/v0.12.2/caches.html#simplememorycache). This library aims for simplicity and supports asynchronous operations to go along with Python `asyncio` used in ANTA.

The `_init_cache()` method of the [AntaDevice](../advanced_usages/as-python-lib.md#antadevice-abstract-class) abstract class initializes the cache. Child classes can override this method to tweak the cache configuration:
The `_init_cache()` method of the [AntaDevice](../api/device.md#anta.device.AntaDevice) abstract class initializes the cache. Child classes can override this method to tweak the cache configuration:

```python
def _init_cache(self) -> None:
Expand All @@ -29,7 +29,7 @@ The cache is initialized per `AntaDevice` and uses the following cache key desig

`<device_name>:<uid>`

The `uid` is an attribute of [AntaCommand](../advanced_usages/as-python-lib.md#antacommand-class), which is a unique identifier generated from the command, version, revision and output format.
The `uid` is an attribute of [AntaCommand](../api/models.md#anta.models.AntaCommand), which is a unique identifier generated from the command, version, revision and output format.

Each UID has its own asyncio lock. This design allows coroutines that need to access the cache for different UIDs to do so concurrently. The locks are managed by the `self.cache_locks` dictionary.

Expand All @@ -44,10 +44,13 @@ Caching is enabled by default in ANTA following the previous configuration and m
There might be scenarios where caching is not wanted. You can disable caching in multiple ways in ANTA:

1. Caching can be disabled globally, for **ALL** commands on **ALL** devices, using the `--disable-cache` global flag when invoking anta at the [CLI](../cli/overview.md#invoking-anta-cli):

```bash
anta --disable-cache --username arista --password arista nrfu table
```

2. Caching can be disabled per device, network or range by setting the `disable_cache` key to `True` when defining the ANTA [Inventory](../usage-inventory-catalog.md#device-inventory) file:

```yaml
anta_inventory:
hosts:
Expand All @@ -69,9 +72,10 @@ There might be scenarios where caching is not wanted. You can disable caching in
end: 172.22.22.19
disable_cache: True
```

This approach effectively disables caching for **ALL** commands sent to devices targeted by the `disable_cache` key.

3. For tests developers, caching can be disabled for a specific [`AntaCommand`](../advanced_usages/as-python-lib.md#antacommand-class) or [`AntaTemplate`](../advanced_usages/as-python-lib.md#antatemplate-class) by setting the `use_cache` attribute to `False`. That means the command output will always be collected on the device and therefore, never use caching.
3. For tests developers, caching can be disabled for a specific [`AntaCommand`](../api/models.md#anta.models.AntaCommand) or [`AntaTemplate`](../api/models.md#anta.models.AntaTemplate) by setting the `use_cache` attribute to `False`. That means the command output will always be collected on the device and therefore, never use caching.

### Disable caching in a child class of `AntaDevice`

Expand Down
17 changes: 9 additions & 8 deletions docs/advanced_usages/custom-tests.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
~ that can be found in the LICENSE file.
-->

!!! info ""
!!! info
This documentation applies for both creating tests in ANTA or creating your own test package.

ANTA is not only a Python library with a CLI and a collection of built-in tests, it is also a framework you can extend by building your own tests.
Expand Down Expand Up @@ -64,7 +64,7 @@ Full AntaTest API documentation is available in the [API documentation section](
- `name` (`str`): Name of the test. Used during reporting.
- `description` (`str`): A human readable description of your test.
- `categories` (`list[str]`): A list of categories in which the test belongs.
- `commands` (`[list[AntaCommand | AntaTemplate]]`): A list of command to collect from devices. This list __must__ be a list of [AntaCommand](../api/models.md#anta.models.AntaCommand) or [AntaTemplate](../api/models.md#anta.models.AntaTemplate) instances. Rendering [AntaTemplate](../api/models.md#anta.models.AntaTemplate) instances will be discussed later.
- `commands` (`[list[AntaCommand | AntaTemplate]]`): A list of command to collect from devices. This list **must** be a list of [AntaCommand](../api/models.md#anta.models.AntaCommand) or [AntaTemplate](../api/models.md#anta.models.AntaTemplate) instances. Rendering [AntaTemplate](../api/models.md#anta.models.AntaTemplate) instances will be discussed later.

!!! info
All these class attributes are mandatory. If any attribute is missing, a `NotImplementedError` exception will be raised during class instantiation.
Expand All @@ -87,7 +87,6 @@ Full AntaTest API documentation is available in the [API documentation section](
show_root_toc_entry: false
heading_level: 10


!!! note "Logger object"
ANTA already provides comprehensive logging at every steps of a test execution. The [AntaTest](../api/models.md#anta.models.AntaTest) class also provides a `logger` attribute that is a Python logger specific to the test instance. See [Python documentation](https://docs.python.org/3/library/logging.html) for more information.

Expand Down Expand Up @@ -140,8 +139,8 @@ Full `ResultOverwrite` model documentation is available in [API documentation se

### Methods

- [test(self) -> None](../api/models.md#anta.models.AntaTest.test): This is an abstract method that __must__ be implemented. It contains the test logic that can access the collected command outputs using the `instance_commands` instance attribute, access the test inputs using the `inputs` instance attribute and __must__ set the `result` instance attribute accordingly. It must be implemented using the `AntaTest.anta_test` decorator that provides logging and will collect commands before executing the `test()` method.
- [render(self, template: AntaTemplate) -> list[AntaCommand]](../api/models.md#anta.models.AntaTest.render): This method only needs to be implemented if [AntaTemplate](../api/models.md#anta.models.AntaTemplate) instances are present in the `commands` class attribute. It will be called for every [AntaTemplate](../api/models.md#anta.models.AntaTemplate) occurrence and __must__ return a list of [AntaCommand](../api/models.md#anta.models.AntaCommand) using the [AntaTemplate.render()](../api/models.md#anta.models.AntaTemplate.render) method. It can access test inputs using the `inputs` instance attribute.
- [test(self) -> None](../api/models.md#anta.models.AntaTest.test): This is an abstract method that **must** be implemented. It contains the test logic that can access the collected command outputs using the `instance_commands` instance attribute, access the test inputs using the `inputs` instance attribute and **must** set the `result` instance attribute accordingly. It must be implemented using the `AntaTest.anta_test` decorator that provides logging and will collect commands before executing the `test()` method.
- [render(self, template: AntaTemplate) -> list[AntaCommand]](../api/models.md#anta.models.AntaTest.render): This method only needs to be implemented if [AntaTemplate](../api/models.md#anta.models.AntaTemplate) instances are present in the `commands` class attribute. It will be called for every [AntaTemplate](../api/models.md#anta.models.AntaTemplate) occurrence and **must** return a list of [AntaCommand](../api/models.md#anta.models.AntaCommand) using the [AntaTemplate.render()](../api/models.md#anta.models.AntaTemplate.render) method. It can access test inputs using the `inputs` instance attribute.

## Test execution

Expand Down Expand Up @@ -201,9 +200,9 @@ class <YourTestName>(AntaTest):

!!! tip "Command revision and version"
* Most of EOS commands return a JSON structure according to a model (some commands may not be modeled hence the necessity to use `text` outformat sometimes.
* The model can change across time (adding feature, ... ) and when the model is changed in a non backward-compatible way, the __revision__ number is bumped. The initial model starts with __revision__ 1.
* A __revision__ applies to a particular CLI command whereas a __version__ is global to an eAPI call. The __version__ is internally translated to a specific __revision__ for each CLI command in the RPC call. The currently supported __version__ values are `1` and `latest`.
* A __revision takes precedence over a version__ (e.g. if a command is run with version="latest" and revision=1, the first revision of the model is returned)
* The model can change across time (adding feature, ... ) and when the model is changed in a non backward-compatible way, the **revision** number is bumped. The initial model starts with **revision** 1.
* A **revision** applies to a particular CLI command whereas a **version** is global to an eAPI call. The **version** is internally translated to a specific **revision** for each CLI command in the RPC call. The currently supported **version** values are `1` and `latest`.
* A **revision takes precedence over a version** (e.g. if a command is run with version="latest" and revision=1, the first revision of the model is returned)
* By default, eAPI returns the first revision of each model to ensure that when upgrading, integrations with existing tools are not broken. This is done by using by default `version=1` in eAPI calls.

By default, ANTA uses `version="latest"` in AntaCommand, but when developing tests, the revision MUST be provided when the outformat of the command is `json`. As explained earlier, this is to ensure that the eAPI always returns the same output model and that the test remains always valid from the day it was created. For some commands, you may also want to run them with a different revision or version.
Expand Down Expand Up @@ -277,6 +276,7 @@ class <YourTestName>(AntaTest):
```

The logic usually includes the following different stages:

1. Parse the command outputs using the `self.instance_commands` instance attribute.
2. If needed, access the test inputs using the `self.inputs` instance attribute and write your conditional logic.
3. Set the `result` instance attribute to reflect the test result by either calling `self.result.is_success()` or `self.result.is_failure("<FAILURE REASON>")`. Sometimes, setting the test result to `skipped` using `self.result.is_skipped("<SKIPPED REASON>")` can make sense (e.g. testing the OSPF neighbor states but no neighbor was found). However, you should not need to catch any exception and set the test result to `error` since the error handling is done by the framework, see below.
Expand Down Expand Up @@ -357,6 +357,7 @@ anta_custom.dc_project:
- VerifyFeatureX:
minimum: 1
```
And now you can run your NRFU tests with the CLI:
```bash
Expand Down
1 change: 1 addition & 0 deletions docs/api/catalog.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
-->

### ::: anta.catalog.AntaCatalog

options:
filters: ["!^_[^_]", "!__str__"]

Expand Down
6 changes: 4 additions & 2 deletions docs/api/device.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,20 @@

# AntaDevice base class

![](../imgs/uml/anta.device.AntaDevice.jpeg)
![AntaDevice UML model](../imgs/uml/anta.device.AntaDevice.jpeg)

## ::: anta.device.AntaDevice

options:
filters: ["!^_[^_]", "!__(eq|rich_repr)__", "_collect"]

# Async EOS device class

![](../imgs/uml/anta.device.AsyncEOSDevice.jpeg)
![AsyncEOSDevice UML model](../imgs/uml/anta.device.AsyncEOSDevice.jpeg)

<!-- _collect must be last to be kept -->

## ::: anta.device.AsyncEOSDevice

options:
filters: ["!^_[^_]", "!__(eq|rich_repr)__", "_collect"]
1 change: 1 addition & 0 deletions docs/api/inventory.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
-->

### ::: anta.inventory.AntaInventory

options:
filters: ["!^_[^_]", "!__str__"]

Expand Down
13 changes: 7 additions & 6 deletions docs/api/models.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,18 @@

# Test definition

![](../imgs/uml/anta.models.AntaTest.jpeg)
![AntaTest UML model](../imgs/uml/anta.models.AntaTest.jpeg)

## ::: anta.models.AntaTest

### ::: anta.models.AntaTest
options:
filters: ["!^_[^_]", "!__init_subclass__", "!update_progress"]

# Command definition

![](../imgs/uml/anta.models.AntaCommand.jpeg)
![AntaCommand UML model](../imgs/uml/anta.models.AntaCommand.jpeg)

### ::: anta.models.AntaCommand
## ::: anta.models.AntaCommand

!!! warning
CLI commands are protected to avoid execution of critical commands such as `reload` or `write erase`.
Expand All @@ -27,6 +28,6 @@

# Template definition

![](../imgs/uml/anta.models.AntaTemplate.jpeg)
![AntaTemplate UML model](../imgs/uml/anta.models.AntaTemplate.jpeg)

### ::: anta.models.AntaTemplate
## ::: anta.models.AntaTemplate
5 changes: 3 additions & 2 deletions docs/api/result_manager.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@

# Result Manager definition

![](../imgs/uml/anta.result_manager.ResultManager.jpeg)
![ResultManager UML model](../imgs/uml/anta.result_manager.ResultManager.jpeg)

## ::: anta.result_manager.ResultManager

### ::: anta.result_manager.ResultManager
options:
filters: ["!^_[^_]", "!^__len__"]
5 changes: 3 additions & 2 deletions docs/api/result_manager_models.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@

# Test Result model

![](../imgs/uml/anta.result_manager.models.TestResult.jpeg)
![TestResult UML model](../imgs/uml/anta.result_manager.models.TestResult.jpeg)

## ::: anta.result_manager.models.TestResult

### ::: anta.result_manager.models.TestResult
options:
filters: ["!^_[^_]", "!__str__"]
1 change: 1 addition & 0 deletions docs/api/runner.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
-->

### ::: anta.runner

options:
filters: ["!^_[^_]", "!__str__"]
5 changes: 3 additions & 2 deletions docs/api/tests.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
---
anta_title: ANTA Tests Landing Page
---
<!--
~ Copyright (c) 2023-2024 Arista Networks, Inc.
~ Use of this source code is governed by the Apache License 2.0
~ that can be found in the LICENSE file.
-->

# ANTA Tests Landing Page

This section describes all the available tests provided by the ANTA package.

## Available Tests
Expand Down
Loading

0 comments on commit fc644a1

Please sign in to comment.