summaryrefslogtreecommitdiffstats
path: root/tests/units/reporter
diff options
context:
space:
mode:
Diffstat (limited to 'tests/units/reporter')
-rw-r--r--tests/units/reporter/conftest.py8
-rw-r--r--tests/units/reporter/test__init__.py25
-rw-r--r--tests/units/reporter/test_csv.py94
-rw-r--r--tests/units/reporter/test_md_reporter.py54
4 files changed, 165 insertions, 16 deletions
diff --git a/tests/units/reporter/conftest.py b/tests/units/reporter/conftest.py
new file mode 100644
index 0000000..ae7d3df
--- /dev/null
+++ b/tests/units/reporter/conftest.py
@@ -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"]
diff --git a/tests/units/reporter/test__init__.py b/tests/units/reporter/test__init__.py
index 2fc62ce..af26b54 100644
--- a/tests/units/reporter/test__init__.py
+++ b/tests/units/reporter/test__init__.py
@@ -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()
diff --git a/tests/units/reporter/test_csv.py b/tests/units/reporter/test_csv.py
new file mode 100644
index 0000000..1d59dae
--- /dev/null
+++ b/tests/units/reporter/test_csv.py
@@ -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
diff --git a/tests/units/reporter/test_md_reporter.py b/tests/units/reporter/test_md_reporter.py
new file mode 100644
index 0000000..a607733
--- /dev/null
+++ b/tests/units/reporter/test_md_reporter.py
@@ -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()