Adding upstream version 1.1.0.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-05 11:54:23 +01:00
parent f13b7abbd8
commit 77504588ab
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
196 changed files with 10121 additions and 3780 deletions

View file

@ -0,0 +1,8 @@
# 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.
"""See https://docs.pytest.org/en/stable/reference/fixtures.html#conftest-py-sharing-fixtures-across-multiple-files."""
from tests.units.result_manager.conftest import list_result_factory, result_manager, result_manager_factory, test_result_factory
__all__ = ["result_manager", "result_manager_factory", "list_result_factory", "test_result_factory"]

View file

@ -13,9 +13,9 @@ from rich.table import Table
from anta import RICH_COLOR_PALETTE
from anta.reporter import ReportJinja, ReportTable
from anta.result_manager.models import AntaTestStatus
if TYPE_CHECKING:
from anta.custom_types import TestStatus
from anta.result_manager import ResultManager
@ -47,7 +47,6 @@ class TestReportTable:
)
def test__split_list_to_txt_list(self, usr_list: list[str], delimiter: str | None, expected_output: str) -> None:
"""Test _split_list_to_txt_list."""
# pylint: disable=protected-access
report = ReportTable()
assert report._split_list_to_txt_list(usr_list, delimiter) == expected_output
@ -61,7 +60,6 @@ class TestReportTable:
)
def test__build_headers(self, headers: list[str]) -> None:
"""Test _build_headers."""
# pylint: disable=protected-access
report = ReportTable()
table = Table()
table_column_before = len(table.columns)
@ -73,17 +71,15 @@ class TestReportTable:
@pytest.mark.parametrize(
("status", "expected_status"),
[
pytest.param("unknown", "unknown", id="unknown status"),
pytest.param("unset", "[grey74]unset", id="unset status"),
pytest.param("skipped", "[bold orange4]skipped", id="skipped status"),
pytest.param("failure", "[bold red]failure", id="failure status"),
pytest.param("error", "[indian_red]error", id="error status"),
pytest.param("success", "[green4]success", id="success status"),
pytest.param(AntaTestStatus.UNSET, "[grey74]unset", id="unset status"),
pytest.param(AntaTestStatus.SKIPPED, "[bold orange4]skipped", id="skipped status"),
pytest.param(AntaTestStatus.FAILURE, "[bold red]failure", id="failure status"),
pytest.param(AntaTestStatus.ERROR, "[indian_red]error", id="error status"),
pytest.param(AntaTestStatus.SUCCESS, "[green4]success", id="success status"),
],
)
def test__color_result(self, status: TestStatus, expected_status: str) -> None:
def test__color_result(self, status: AntaTestStatus, expected_status: str) -> None:
"""Test _build_headers."""
# pylint: disable=protected-access
report = ReportTable()
assert report._color_result(status) == expected_status
@ -104,7 +100,6 @@ class TestReportTable:
expected_length: int,
) -> None:
"""Test report_all."""
# pylint: disable=too-many-arguments
manager = result_manager_factory(number_of_tests)
report = ReportTable()
@ -133,14 +128,13 @@ class TestReportTable:
expected_length: int,
) -> None:
"""Test report_summary_tests."""
# pylint: disable=too-many-arguments
# TODO: refactor this later... this is injecting double test results by modyfing the device name
# should be a fixture
manager = result_manager_factory(number_of_tests)
new_results = [result.model_copy() for result in manager.results]
for result in new_results:
result.name = "test_device"
result.result = "failure"
result.result = AntaTestStatus.FAILURE
report = ReportTable()
kwargs = {"tests": [test] if test is not None else None, "title": title}
@ -168,14 +162,13 @@ class TestReportTable:
expected_length: int,
) -> None:
"""Test report_summary_devices."""
# pylint: disable=too-many-arguments
# TODO: refactor this later... this is injecting double test results by modyfing the device name
# should be a fixture
manager = result_manager_factory(number_of_tests)
new_results = [result.model_copy() for result in manager.results]
for result in new_results:
result.name = dev or "test_device"
result.result = "failure"
result.result = AntaTestStatus.FAILURE
manager.results = new_results
report = ReportTable()

View file

@ -0,0 +1,94 @@
# 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.
"""Test anta.report.csv_reporter.py."""
# pylint: disable=too-few-public-methods
import csv
import pathlib
from typing import Any, Callable
import pytest
from anta.reporter.csv_reporter import ReportCsv
from anta.result_manager import ResultManager
from anta.tools import convert_categories
class TestReportCsv:
"""Tester for ReportCsv class."""
def compare_csv_and_result(self, rows: list[Any], index: int, result_manager: ResultManager) -> None:
"""Compare CSV and TestResult."""
assert rows[index + 1][0] == result_manager.results[index].name
assert rows[index + 1][1] == result_manager.results[index].test
assert rows[index + 1][2] == result_manager.results[index].result
assert rows[index + 1][3] == ReportCsv().split_list_to_txt_list(result_manager.results[index].messages)
assert rows[index + 1][4] == result_manager.results[index].description
assert rows[index + 1][5] == ReportCsv().split_list_to_txt_list(convert_categories(result_manager.results[index].categories))
def test_report_csv_generate(
self,
result_manager_factory: Callable[[int], ResultManager],
tmp_path: pathlib.Path,
) -> None:
"""Test CSV reporter."""
max_test_entries = 10
# Create a temporary CSV file path
csv_filename = tmp_path / "test.csv"
# Create a ResultManager instance with dummy test results
result_manager = result_manager_factory(max_test_entries)
# Test usecase with list of messages
result_manager.results[0].messages = ["Message 1", "Message 2"]
# Test usecase with list of categories
result_manager.results[1].messages = ["Cat 1", "Cat 2"]
# Generate the CSV report
ReportCsv.generate(result_manager, csv_filename)
# Read the generated CSV file
with pathlib.Path.open(csv_filename, encoding="utf-8") as csvfile:
reader = csv.reader(csvfile, delimiter=",")
rows = list(reader)
# Assert the headers
assert rows[0] == [
ReportCsv.Headers.device,
ReportCsv.Headers.test_name,
ReportCsv.Headers.test_status,
ReportCsv.Headers.messages,
ReportCsv.Headers.description,
ReportCsv.Headers.categories,
]
# Assert the test result rows
for index in [0, max_test_entries - 1]:
self.compare_csv_and_result(rows, index, result_manager)
# Assert number of lines: Number of TestResults + CSV Headers
assert len(rows) == len(result_manager.results) + 1
def test_report_csv_generate_os_error(
self,
result_manager_factory: Callable[[int], ResultManager],
tmp_path: pathlib.Path,
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test CSV reporter OSError."""
# Create a ResultManager instance with dummy test results
max_test_entries = 10
result_manager = result_manager_factory(max_test_entries)
# Create a temporary CSV file path and make tmp_path read_only
tmp_path.chmod(0o400)
csv_filename = tmp_path / "read_only.csv"
with pytest.raises(OSError, match="Permission denied"):
# Generate the CSV report
ReportCsv.generate(result_manager, csv_filename)
assert len(caplog.record_tuples) == 1
assert "OSError caught while writing the CSV file" in caplog.text

View file

@ -0,0 +1,54 @@
# 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.
"""Test anta.reporter.md_reporter.py."""
from __future__ import annotations
from io import StringIO
from pathlib import Path
import pytest
from anta.reporter.md_reporter import MDReportBase, MDReportGenerator
from anta.result_manager import ResultManager
DATA_DIR: Path = Path(__file__).parent.parent.parent.resolve() / "data"
def test_md_report_generate(tmp_path: Path, result_manager: ResultManager) -> None:
"""Test the MDReportGenerator class."""
md_filename = tmp_path / "test.md"
expected_report = "test_md_report.md"
# Generate the Markdown report
MDReportGenerator.generate(result_manager, md_filename)
assert md_filename.exists()
# Load the existing Markdown report to compare with the generated one
with (DATA_DIR / expected_report).open("r", encoding="utf-8") as f:
expected_content = f.read()
# Check the content of the Markdown file
content = md_filename.read_text(encoding="utf-8")
assert content == expected_content
def test_md_report_base() -> None:
"""Test the MDReportBase class."""
class FakeMDReportBase(MDReportBase):
"""Fake MDReportBase class."""
def generate_section(self) -> None:
pass
results = ResultManager()
with StringIO() as mock_file:
report = FakeMDReportBase(mock_file, results)
assert report.generate_heading_name() == "Fake MD Report Base"
with pytest.raises(NotImplementedError, match="Subclasses should implement this method"):
report.generate_rows()