Test models
Test definition¶
UML Diagram¶
AntaTest ¶
AntaTest(device: AntaDevice, inputs: Optional[dict[str, Any]], eos_data: Optional[list[dict[Any, Any] | str]] = None)
Bases: ABC
Abstract class defining a test in ANTA
The goal of this class is to handle the heavy lifting and make writing a test as simple as possible.
Examples:
The following is an example of an AntaTest subclass implementation:
class VerifyReachability(AntaTest):
name = "VerifyReachability"
description = "Test the network reachability to one or many destination IP(s)."
categories = ["connectivity"]
commands = [AntaTemplate(template="ping vrf {vrf} {dst} source {src} repeat 2")]
class Input(AntaTest.Input):
hosts: list[Host]
class Host(BaseModel):
dst: IPv4Address
src: IPv4Address
vrf: str = "default"
def render(self, template: AntaTemplate) -> list[AntaCommand]:
return [template.render({"dst": host.dst, "src": host.src, "vrf": host.vrf}) for host in self.inputs.hosts]
@AntaTest.anta_test
def test(self) -> None:
failures = []
for command in self.instance_commands:
if command.params and ("src" and "dst") in command.params:
src, dst = command.params["src"], command.params["dst"]
if "2 received" not in command.json_output["messages"][0]:
failures.append((str(src), str(dst)))
if not failures:
self.result.is_success()
else:
self.result.is_failure(f"Connectivity test failed for the following source-destination pairs: {failures}")
Parameters:
Name | Type | Description | Default |
---|---|---|---|
device |
AntaDevice
|
AntaDevice instance on which the test will be run |
required |
inputs |
Optional[dict[str, Any]]
|
dictionary of attributes used to instantiate the AntaTest.Input instance |
required |
eos_data |
Optional[list[dict[Any, Any] | str]]
|
Populate outputs of the test commands instead of collecting from devices.
This list must have the same length and order than the |
None
|
Source code in anta/models.py
302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 |
|
collected
property
¶
collected: bool
Returns True if all commands for this test have been collected.
failed_commands
property
¶
failed_commands: list[AntaCommand]
Returns a list of all the commands that have failed.
Input ¶
Bases: BaseModel
Class defining inputs for a test in ANTA.
Examples:
A valid test catalog will look like the following:
<Python module>:
- <AntaTest subclass>:
result_overwrite:
categories:
- "Overwritten category 1"
description: "Test with overwritten description"
custom_field: "Test run by John Doe"
ResultOverwrite ¶
Bases: BaseModel
Test inputs model to overwrite result fields
Attributes:
Name | Type | Description |
---|---|---|
description |
Optional[str]
|
overwrite TestResult.description |
categories |
Optional[List[str]]
|
overwrite TestResult.categories |
custom_field |
Optional[str]
|
a free string that will be included in the TestResult object |
anta_test
staticmethod
¶
anta_test(function: F) -> Callable[..., Coroutine[Any, Any, TestResult]]
Decorator for the test()
method.
This decorator implements (in this order):
- Instantiate the command outputs if
eos_data
is provided to thetest()
method - Collect the commands from the device
- Run the
test()
method - Catches any exception in
test()
user code and set theresult
instance attribute
Source code in anta/models.py
426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 |
|
collect
async
¶
collect() -> None
Method used to collect outputs of all commands of this test class from the device of this test instance.
Source code in anta/models.py
415 416 417 418 419 420 421 422 423 424 |
|
render ¶
render(template: AntaTemplate) -> list[AntaCommand]
Render an AntaTemplate instance of this AntaTest using the provided AntaTest.Input instance at self.inputs.
This is not an abstract method because it does not need to be implemented if there is no AntaTemplate for this test.
Source code in anta/models.py
407 408 409 410 411 412 413 |
|
save_commands_data ¶
save_commands_data(eos_data: list[dict[str, Any] | str]) -> None
Populate output of all AntaCommand instances in instance_commands
Source code in anta/models.py
379 380 381 382 383 384 385 386 387 388 |
|
test
abstractmethod
¶
test() -> Coroutine[Any, Any, TestResult]
This abstract method is the core of the test logic.
It must set the correct status of the result
instance attribute
with the appropriate outcome of the test.
Examples:
It must be implemented using the AntaTest.anta_test
decorator:
@AntaTest.anta_test
def test(self) -> None:
self.result.is_success()
for command in self.instance_commands:
if not self._test_command(command): # _test_command() is an arbitrary test logic
self.result.is_failure("Failure reson")
Source code in anta/models.py
505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 |
|
Command definition¶
UML Diagram¶
AntaCommand ¶
Bases: BaseModel
Class to define a command.
Info
eAPI models are revisioned, this means that if a model is modified in a non-backwards compatible way, then its revision will be bumped up (revisions are numbers, default value is 1).
By default an eAPI request will return revision 1 of the model instance, this ensures that older management software will not suddenly stop working when a switch is upgraded. A revision applies to a particular CLI command whereas a version is global and is internally translated to a specific revision for each CLI command in the RPC.
Revision has precedence over version.
Attributes:
Name | Type | Description |
---|---|---|
command |
str
|
Device command |
version |
Literal[1, 'latest']
|
eAPI version - valid values are 1 or “latest” - default is “latest” |
revision |
Optional[conint(ge=1, le=99)]
|
eAPI revision of the command. Valid values are 1 to 99. Revision has precedence over version. |
ofmt |
Literal['json', 'text']
|
eAPI output - json or text - default is json |
output |
Optional[Union[Dict[str, Any], str]]
|
Output of the command populated by the collect() function |
template |
Optional[AntaTemplate]
|
AntaTemplate object used to render this command |
params |
Dict[str, Any]
|
Dictionary of variables with string values to render the template |
failed |
Optional[Exception]
|
If the command execution fails, the Exception object is stored in this field |
use_cache |
bool
|
Enable or disable caching for this AntaCommand if the AntaDevice supports it - default is True |
Template definition¶
UML Diagram¶
AntaTemplate ¶
Bases: BaseModel
Class to define a command template as Python f-string. Can render a command from parameters.
Attributes:
Name | Type | Description |
---|---|---|
template |
str
|
Python f-string. Example: ‘show vlan {vlan_id}’ |
version |
Literal[1, 'latest']
|
eAPI version - valid values are 1 or “latest” - default is “latest” |
revision |
Optional[conint(ge=1, le=99)]
|
Revision of the command. Valid values are 1 to 99. Revision has precedence over version. |
ofmt |
Literal['json', 'text']
|
eAPI output - json or text - default is json |
use_cache |
bool
|
Enable or disable caching for this AntaTemplate if the AntaDevice supports it - default is True |
render ¶
render(**params: dict[str, Any]) -> AntaCommand
Render an AntaCommand from an AntaTemplate instance. Keep the parameters used in the AntaTemplate instance.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
params |
dict[str, Any]
|
dictionary of variables with string values to render the Python f-string |
{}
|
Returns:
Name | Type | Description |
---|---|---|
command |
AntaCommand
|
The rendered AntaCommand. This AntaCommand instance have a template attribute that references this AntaTemplate instance. |
Source code in anta/models.py
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
|