Skip to content

Commit

Permalink
Feat: Add customization of fields for TestResults at AntaTest creation
Browse files Browse the repository at this point in the history
  • Loading branch information
gmuloc committed Jul 26, 2023
1 parent 3017f46 commit 100b8b2
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 31 deletions.
22 changes: 20 additions & 2 deletions anta/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ class AntaTest(ABC):
TODO - complete doctstring with example
"""

# pylint: disable=too-many-instance-attributes

# Mandatory class attributes
# TODO - find a way to tell mypy these are mandatory for child classes - maybe Protocol
name: ClassVar[str]
Expand All @@ -161,16 +163,32 @@ def __init__(
self,
device: AntaDevice,
template_params: list[dict[str, Any]] | None = None,
result_description: str | None = None,
result_categories: list[str] | None = None,
result_custom_field: str | None = None,
# TODO document very well the order of eos_data
eos_data: list[dict[Any, Any] | str] | None = None,
labels: list[str] | None = None,
):
"""Class constructor"""
"""
AntaTest Constructor
Doc to be completed
Arguments:
result_custom_field (str): a free string that is included in the TestResult object
"""
# Accept 6 input arguments
# pylint: disable=R0913
self.logger: logging.Logger = logging.getLogger(f"{self.__module__}.{self.__class__.__name__}")
self.device: AntaDevice = device
self.result: TestResult = TestResult(name=device.name, test=self.name, test_category=self.categories, test_description=self.description)
self.result: TestResult = TestResult(
name=device.name,
test=self.name,
categories=result_categories or self.categories,
description=result_description or self.description,
custom_field=result_custom_field,
)
self.labels: List[str] = labels or []
self.instance_commands: List[AntaCommand] = []

Expand Down
8 changes: 4 additions & 4 deletions anta/reporter/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,8 @@ def report_all(
if (host is None and testcase is None) or (host is not None and str(result.name) == host) or (testcase is not None and testcase == str(result.test)):
state = self._color_result(status=str(result.result), output_type="str")
message = self._split_list_to_txt_list(result.messages) if len(result.messages) > 0 else ""
test_categories = ", ".join(result.test_category)
table.add_row(str(result.name), result.test, state, message, result.test_description, test_categories)
categories = ", ".join(result.categories)
table.add_row(str(result.name), result.test, state, message, result.description, categories)
return table

def report_summary_tests(
Expand Down Expand Up @@ -242,8 +242,8 @@ def render(self, data: List[Dict[str, Any]], trim_blocks: bool = True, lstrip_bl
test: ...,
result: ...,
messages: [...]
test_category: ...,
test_description: ...,
categories: ...,
description: ...,
}
]
Expand Down
12 changes: 7 additions & 5 deletions anta/result_manager/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Models related to anta.result_manager module."""

from typing import Iterator, List
from typing import Iterator, List, Optional

from pydantic import BaseModel, RootModel, field_validator

Expand All @@ -14,18 +14,20 @@ class TestResult(BaseModel):
Attributes:
name (str): Device name where the test has run.
test (str): Test name runs on the device.
test_category (List[str]): List of test categories the test belongs to.
test_description (str): Test description.
categories (List[str]): List of categories the TestResult belongs to, by default the AntaTest categories.
description (str): TestResult description, by default the AntaTest description.
results (str): Result of the test. Can be one of ["unset", "success", "failure", "error", "skipped"].
message (str, optional): Message to report after the test if any.
custom_field (str, optional): Custom field to store a string for flexibility in integrating with ANTA
"""

name: str
test: str
test_category: List[str]
test_description: str
categories: List[str]
description: str
result: str = "unset"
messages: List[str] = []
custom_field: Optional[str] = None

@classmethod
@field_validator("result")
Expand Down
13 changes: 9 additions & 4 deletions anta/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@
logger = logging.getLogger(__name__)

# Key from YAML file tranfered to AntaTemplate of the test.
TEST_TPL_PARAMS = "template_params"
TEST_CATALOG_PARAMS = [
"result_description",
"result_categories",
"result_custom_field",
"template_params",
]


async def main(
Expand Down Expand Up @@ -55,11 +60,11 @@ async def main(

coros = []
for device, test in itertools.product(inventory.get_inventory(established_only=established_only, tags=tags).values(), tests):
test_params = {k: v for k, v in test[1].items() if k != TEST_TPL_PARAMS}
template_params = test[1].get(TEST_TPL_PARAMS)
kwargs = {k: v for k, v in test[1].items() if k in TEST_CATALOG_PARAMS}
test_params = {k: v for k, v in test[1].items() if k not in TEST_CATALOG_PARAMS}
try:
# Instantiate AntaTest object
test_instance = test[0](device=device, template_params=template_params)
test_instance = test[0](device=device, **kwargs)
coros.append(test_instance.test(eos_data=None, **test_params))
except Exception as e: # pylint: disable=broad-exception-caught
message = "Error when creating ANTA tests"
Expand Down
8 changes: 5 additions & 3 deletions docs/advanced_usages/as-python-lib.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,12 +224,14 @@ class VerifyTransceiversManufacturers(AntaTest):

The test itself does not return any value, but the result is directly availble from your AntaTest object and exposes a `anta.result_manager.models.TestResult` object with result, name of the test and optional messages:


- `name` (str): Device name where the test has run.
- `test` (str): Test name runs on the device.
- `test_category` (List[str]): List of test categories the test belongs to.
- `test_description` (str): Test description.
- `categories` (List[str]): List of categories the TestResult belongs to, by default the AntaTest categories.
- `description` (str): TestResult description, by default the AntaTest description.
- `results` (str): Result of the test. Can be one of ["unset", "success", "failure", "error", "skipped"].
- `messages` (List[str], optional): Messages to report after the test if any.
- `message` (str, optional): Message to report after the test if any.
- `custom_field` (str, optional): Custom field to store a string for flexibility in integrating with ANTA

```python
from anta.tests.hardware import VerifyTemperature
Expand Down
14 changes: 8 additions & 6 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -242,22 +242,24 @@ $ anta \
{
"name": "leaf01",
"test": "VerifyEOSVersion",
"test_category": [
"categories": [
"software"
],
"test_description": "Verifies the device is running one of the allowed EOS version.",
"description": "Verifies the device is running one of the allowed EOS version.",
"result": "success",
"messages": []
"messages": [],
"custom_field": "None",
},
{
"name": "leaf01",
"test": "VerifyTerminAttrVersion",
"test_category": [
"categories": [
"software"
],
"test_description": "Verifies the device is running one of the allowed TerminAttr version.",
"description": "Verifies the device is running one of the allowed TerminAttr version.",
"result": "success",
"messages": []
"messages": [],
"custom_field": "None",
},
[...]
]
Expand Down
2 changes: 1 addition & 1 deletion examples/template.j2
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{% for d in data %}
* {{ d.test }} is [green]{{ d.result | upper}}[/green] for {{ d.name }}
{% endfor %}
{% endfor %}
4 changes: 2 additions & 2 deletions tests/lib/fixture.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ def _create(index: int = 0) -> TestResult:
return TestResult(
name=mocked_device.name,
test=f"VerifyTest{index}",
test_category=["test"],
test_description=f"Verifies Test {index}",
categories=["test"],
description=f"Verifies Test {index}",
)

return _create
Expand Down
40 changes: 36 additions & 4 deletions tests/units/tools/test_pydantic.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,44 @@
from anta.result_manager.models import ListResult

EXPECTED_ONE_ENTRY = [
{"name": "testdevice", "test": "VerifyTest0", "test_category": ["test"], "test_description": "Verifies Test 0", "result": "unset", "messages": []}
{
"name": "testdevice",
"test": "VerifyTest0",
"categories": ["test"],
"description": "Verifies Test 0",
"result": "unset",
"messages": [],
"custom_field": "None",
}
]
EXPECTED_THREE_ENTRIES = [
{"name": "testdevice", "test": "VerifyTest0", "test_category": ["test"], "test_description": "Verifies Test 0", "result": "unset", "messages": []},
{"name": "testdevice", "test": "VerifyTest1", "test_category": ["test"], "test_description": "Verifies Test 1", "result": "unset", "messages": []},
{"name": "testdevice", "test": "VerifyTest2", "test_category": ["test"], "test_description": "Verifies Test 2", "result": "unset", "messages": []},
{
"name": "testdevice",
"test": "VerifyTest0",
"categories": ["test"],
"description": "Verifies Test 0",
"result": "unset",
"messages": [],
"custom_field": "None",
},
{
"name": "testdevice",
"test": "VerifyTest1",
"categories": ["test"],
"description": "Verifies Test 1",
"result": "unset",
"messages": [],
"custom_field": "None",
},
{
"name": "testdevice",
"test": "VerifyTest2",
"categories": ["test"],
"description": "Verifies Test 2",
"result": "unset",
"messages": [],
"custom_field": "None",
},
]


Expand Down

0 comments on commit 100b8b2

Please sign in to comment.