diff --git a/main/advanced_usages/as-python-lib/index.html b/main/advanced_usages/as-python-lib/index.html index f026524173..aec04f29f5 100644 --- a/main/advanced_usages/as-python-lib/index.html +++ b/main/advanced_usages/as-python-lib/index.html @@ -2320,7 +2320,7 @@
Tip
If you are unfamiliar with asyncio, refer to the Python documentation relevant to your Python version - https://docs.python.org/3/library/asyncio.html
-A device is represented in ANTA as a instance of a subclass of the AntaDevice abstract class. There are few abstract methods that needs to be implemented by child classes:
The copy() coroutine is used to copy files to and from the device. It does not need to be implemented if tests are not using it.
-The AsyncEOSDevice class is an implementation of AntaDevice for Arista EOS. It uses the aio-eapi eAPI client and the AsyncSSH library.
is_online
attribute accordingly. If the TCP connection succeeds, it sends a show version
command to gather the hardware model of the device and updates the established
and hw_model
attributes.
The AntaInventory class is a subclass of the standard Python type dict. The keys of this dictionary are the device names, the values are AntaDevice instances.
AntaInventory provides methods to interact with the ANTA inventory:
All the test classes inherit from the same abstract Base Class AntaTest. The Class definition indicates which commands are required for the test and the user should focus only on writing the test
function with optional keywords argument. The instance of the class upon creation instantiates a TestResult object that can be accessed later on to check the status of the test ([unset, skipped, success, failure, error]).
All tests are built on a class named AntaTest
which provides a complete toolset for a test:
To make it easier to get data, ANTA defines 2 different classes to manage commands to send to devices:
-Represent a command with following information:
Because some command can require more dynamic than just a command with no parameter provided by user, ANTA supports command template: you define a template in your test class and user provide parameters when creating test object.
class RunArbitraryTemplateCommand(AntaTest):
"""
diff --git a/main/advanced_usages/caching/index.html b/main/advanced_usages/caching/index.html
index 8b3c6f67d3..3985cdda55 100644
--- a/main/advanced_usages/caching/index.html
+++ b/main/advanced_usages/caching/index.html
@@ -2204,7 +2204,7 @@ Caching in ANTA
-->
ANTA is a streamlined Python framework designed for efficient interaction with network devices. This section outlines how ANTA incorporates caching mechanisms to collect command outputs from network devices.
-Configuration¶
+Configuration¶
By default, ANTA utilizes aiocache’s memory cache backend, also called 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 abstract class initializes the cache. Child classes can override this method to tweak the cache configuration:
def _init_cache(self) -> None:
@@ -2215,14 +2215,14 @@ Configurationself.cache_locks = defaultdict(asyncio.Lock)
The cache is also configured with aiocache
’s HitMissRatioPlugin
plugin to calculate the ratio of hits the cache has and give useful statistics for logging purposes in ANTA.
-Cache key design¶
+Cache key design¶
The cache is initialized per AntaDevice
and uses the following cache key design:
<device_name>:<uid>
The uid
is an attribute of 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.
-Mechanisms¶
+Mechanisms¶
By default, once the cache is initialized, it is used in the collect()
method of AntaDevice
. The collect()
method prioritizes retrieving the output of the command from the cache. If the output is not in the cache, the private _collect()
method will retrieve and then store it for future access.
-How to disable caching¶
+How to disable caching¶
Caching is enabled by default in ANTA following the previous configuration and mechanisms.
There might be scenarios where caching is not wanted. You can disable caching in multiple ways in ANTA:
@@ -2257,7 +2257,7 @@ How to disable cachingFor tests developers, caching can be disabled for a specific AntaCommand
or 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
¶
+Disable caching in a child class of AntaDevice
¶
Since caching is implemented at the AntaDevice
abstract class level, all subclasses will inherit that default behavior. As a result, if you need to disable caching in any custom implementation of AntaDevice
outside of the ANTA framework, you must initialize AntaDevice
with disable_cache
set to True
:
class AnsibleEOSDevice(AntaDevice):
"""
diff --git a/main/advanced_usages/custom-tests/index.html b/main/advanced_usages/custom-tests/index.html
index 9efa2bea8d..dc49132635 100644
--- a/main/advanced_usages/custom-tests/index.html
+++ b/main/advanced_usages/custom-tests/index.html
@@ -2535,7 +2535,7 @@ Developing ANTA tests
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.
-Generic approach¶
+Generic approach¶
A test is a Python class where a test function is defined and will be run by the framework.
ANTA provides an abstract class AntaTest. This class does the heavy lifting and provide the logic to define, collect and test data. The code below is an example of a simple test in ANTA, which is an AntaTest subclass:
from anta.models import AntaTest, AntaCommand
@@ -2575,8 +2575,9 @@ Generic approachself.result.is_failure(f"Device temperature exceeds acceptable limits. Current system status: '{temperature_status}'")
AntaTest also provide more advanced capabilities like AntaCommand templating using the AntaTemplate class or test inputs definition and validation using AntaTest.Input pydantic model. This will be discussed in the sections below.
-AntaTest structure¶
-Class Attributes¶
+AntaTest structure¶
+Full AntaTest API documentation is available in the API documentation section
+Class Attributes¶
name
(str
): Name of the test. Used during reporting.
description
(str
): A human readable description of your test.
@@ -2587,55 +2588,56 @@ Class AttributesInfo
All these class attributes are mandatory. If any attribute is missing, a NotImplementedError
exception will be raised during class instantiation.
Info
You can access an instance attribute in your code using the self
reference. E.g. you can access the test input values using self.inputs
.
Attributes:
-Name | -Type | -Description | -||||||
---|---|---|---|---|---|---|---|---|
device |
-
- AntaDevice instance on which this test is run
- |
-
-
-
+ inputs: AntaTest.Input instance carrying the test inputs + Attributes: +
|
+
Logger object
@@ -2663,50 +2664,52 @@Even if device
is not a private attribute, you should not need to access this object in your code.
AntaTest.Input is a pydantic model that allow test developers to define their test inputs. pydantic provides out of the box error handling for test input validation based on the type hints defined by the test developer.
The base definition of AntaTest.Input provides common test inputs for all AntaTest instances:
-Full Input
model documentation is available in API documentation section
Attributes:
-Name | -Type | -Description | -|||
---|---|---|---|---|---|
result_overwrite |
-
- Define fields to overwrite in the TestResult object
- |
-
-
-
-
- |
+
Name | +Type | +Description |
---|
result_overwrite
Define fields to overwrite in the TestResult object
+ Full ResultOverwrite
model documentation is available in API documentation section
Attributes:
-Name | -Type | -Description | -|||
---|---|---|---|---|---|
description |
-
- overwrite TestResult.description
- |
-
-
-
- categories: overwrite TestResult.categories -custom_field: a free string that will be included in the TestResult object - |
+
Name | +Type | +Description |
---|
description
overwrite TestResult.description
+ categories: overwrite TestResult.categories +custom_field: a free string that will be included in the TestResult object
+Note
The pydantic model is configured using the extra=forbid
that will fail input validation if extra fields are provided.
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.commands
class attribute. It will be called for every AntaTemplate occurrence and must return a list of AntaCommand using the AntaTemplate.render() method. It can access test inputs using the inputs
instance attribute.Below is a high level description of the test execution flow in ANTA:
In this section, we will go into all the details of writing an AntaTest subclass.
-Import anta.models.AntaTest and define your own class. Define the mandatory class attributes using anta.models.AntaCommand, anta.models.AntaTemplate or both.
If the user needs to provide inputs for your test, you need to define a pydantic model that defines the schema of the test inputs:
class <YourTestName>(AntaTest):
"""Verifies ...
@@ -2883,7 +2886,7 @@ Inputs definitionNote
All the pydantic
features are supported. For instance you can define validators for complex input validation.
Define the render()
method if you have AntaTemplate instances in your commands
class attribute:
class <YourTestName>(AntaTest):
...
@@ -2891,7 +2894,7 @@ Template renderingreturn [template.render(<template param>=input_value) for input_value in self.inputs.<input_field>]
You can access test inputs and render as many AntaCommand as desired.
-Implement the test()
method with your test logic:
class <YourTestName>(AntaTest):
...
@@ -2937,7 +2940,7 @@ Test definition$ ANTA_DEBUG=true anta nrfu --catalog test_custom.yml text
In addition to the required AntaTest.anta_tests
decorator, ANTA offers a set of optional decorators for further test customization:
anta.decorators.deprecated_test
: Use this to log a message of WARNING severity when a test is deprecated.This section is required only if you are not merging your development into ANTA. Otherwise, just follow contribution guide.
AntaCatalog(tests: list[AntaTestDefinition] | None = None, filename: str | Path | None = None)
Class representing an ANTA Catalog.
It can be instantiated using its constructor or one of the static methods: parse()
, from_list()
or from_dict()
tests: A list of AntaTestDefinition instances.
filename: The path from which the catalog is loaded.
anta/catalog.py
250 +
-
- build_indexes + build_indexes ¶
+ Indexes tests by their tags for quick access during filtering operations. If a - tests_without_tags: A set of tests that do not have any tags.Once the indexes are built, the
- Source code in
- |
401 +
-
- dump + dump ¶
+ Return an AntaCatalogFile instance from this AntaCatalog instance. - -Returns: -
-
+
-
Source code in
- |
388 + + + |
anta/catalog.py
388 389 390 391 @@ -2888,20 +2886,18 @@ |
staticmethod
@@ -2910,22 +2906,23 @@ from_dict(data: RawCatalogInput, filename: str | Path | None = None) -> AntaCatalog
Create an AntaCatalog instance from a dictionary data structure.
See RawCatalogInput type alias for details.
It is the data structure returned by yaml.load()
function of a valid
YAML Test Catalog file.
data: Python dictionary used to instantiate the AntaCatalog instance
filename: value to be set as AntaCatalog instance attribute
anta/catalog.py
320 +
-
- from_list
+ from_list
+
-
|
356 +
-
- get_tests_by_tags + get_tests_by_tags ¶
+ Return all tests that match a given set of tags, according to the specified strictness. +Args:
Returns: -
Raises: -
Raises: +
-
+
-
Source code in
- |
427 + + + |
anta/catalog.py
427 428 429 430 @@ -3204,60 +3197,58 @@ |
merge(catalog: AntaCatalog) -> AntaCatalog
Merge two AntaCatalog instances.
+catalog: AntaCatalog instance to merge to this instance.
Returns:
-Type | -Description | -||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
- A new AntaCatalog instance containing the tests of the two instances.
- |
-
-
-
-
- |
+
Type | +Description |
---|
anta/catalog.py
375 + + + |
anta/catalog.py
375 376 377 378 @@ -3281,20 +3272,18 @@ |
staticmethod
@@ -3303,18 +3292,19 @@ parse(filename: str | Path) -> AntaCatalog
Create an AntaCatalog instance from a test catalog file.
+filename: Path to test catalog YAML file
anta/catalog.py
300 +
-
+
+
-
+
- AntaTestDefinition + AntaTestDefinition ¶
-
- Bases:
+
+ Bases: Define a test with its associated inputs. @@ -3390,9 +3381,9 @@-
- Source code in
- |
65 + |