Skip to content

Commit

Permalink
Refactor: Add test for OSError when writing csv report
Browse files Browse the repository at this point in the history
  • Loading branch information
gmuloc committed Jul 17, 2024
1 parent 61a5629 commit 00beea2
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 8 deletions.
11 changes: 8 additions & 3 deletions anta/cli/nrfu/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from rich.progress import BarColumn, MofNCompleteColumn, Progress, SpinnerColumn, TextColumn, TimeElapsedColumn, TimeRemainingColumn

from anta.cli.console import console
from anta.cli.utils import ExitCode
from anta.models import AntaTest
from anta.reporter import ReportJinja, ReportTable
from anta.reporter.csv_reporter import ReportCsv
Expand Down Expand Up @@ -126,9 +127,13 @@ def print_jinja(results: ResultManager, template: pathlib.Path, output: pathlib.

def save_to_csv(ctx: click.Context, csv_file: pathlib.Path) -> None:
"""Save results to a CSV file."""
ReportCsv.generate(results=_get_result_manager(ctx), csv_filename=csv_file)
checkmark = Emoji("white_check_mark")
console.print(f"CSV report saved to {csv_file} {checkmark}", style="cyan")
try:
ReportCsv.generate(results=_get_result_manager(ctx), csv_filename=csv_file)
checkmark = Emoji("white_check_mark")
console.print(f"CSV report saved to {csv_file} {checkmark}", style="cyan")
except OSError:
console.print(f"Failed to save CSV report to {csv_file} ❌", style="cyan")
ctx.exit(ExitCode.USAGE_ERROR)


# Adding our own ANTA spinner - overriding rich SPINNERS for our own
Expand Down
19 changes: 14 additions & 5 deletions anta/reporter/csv_reporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@

import csv
import logging
import pathlib
from dataclasses import dataclass
from typing import TYPE_CHECKING

from anta.logger import anta_log_exception

if TYPE_CHECKING:
import pathlib

from anta.result_manager import ResultManager
from anta.result_manager.models import TestResult

Expand Down Expand Up @@ -73,10 +76,14 @@ def convert_to_list(cls, result: TestResult) -> list[str]:
def generate(cls, results: ResultManager, csv_filename: pathlib.Path) -> None:
"""Build CSV flle with tests results.
Args:
----
Parameter
---------
results: A ResultManager instance.
csv_filename: File path where to save CSV data.
Raise
-----
OSError if any is raised while writing the CSV file.
"""
headers = [
cls.Headers.device,
Expand All @@ -88,7 +95,7 @@ def generate(cls, results: ResultManager, csv_filename: pathlib.Path) -> None:
]

try:
with pathlib.Path.open(csv_filename, "w", encoding="utf-8") as csvfile:
with csv_filename.open(mode="w", encoding="utf-8") as csvfile:
csvwriter = csv.writer(
csvfile,
delimiter=",",
Expand All @@ -97,4 +104,6 @@ def generate(cls, results: ResultManager, csv_filename: pathlib.Path) -> None:
for entry in results.results:
csvwriter.writerow(cls.convert_to_list(entry))
except OSError as exc:
logger.error("Error: %s", exc)
message = f"OSError caught while writing the CSV file '{csv_filename.resolve()}'."
anta_log_exception(exc, message, logger)
raise
9 changes: 9 additions & 0 deletions tests/units/cli/nrfu/test_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import re
from pathlib import Path
from typing import TYPE_CHECKING
from unittest.mock import patch

from anta.cli import anta
from anta.cli.utils import ExitCode
Expand Down Expand Up @@ -101,3 +102,11 @@ def test_anta_nrfu_csv(click_runner: CliRunner) -> None:
result = click_runner.invoke(anta, ["nrfu", "csv", "--csv-output", "test.csv"])
assert result.exit_code == ExitCode.OK
assert "CSV report saved to" in result.output


def test_anta_nrfu_csv_failure(click_runner: CliRunner) -> None:
"""Test anta nrfu csv."""
with patch("anta.reporter.csv_reporter.ReportCsv.generate", side_effect=OSError()):
result = click_runner.invoke(anta, ["nrfu", "csv", "--csv-output", "read_test.csv"])
assert result.exit_code == ExitCode.USAGE_ERROR
assert "Failed to save CSV report to" in result.output
24 changes: 24 additions & 0 deletions tests/units/reporter/test_csv.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import pathlib
from typing import Any, Callable

import pytest

from anta.reporter.csv_reporter import ReportCsv
from anta.result_manager import ResultManager

Expand Down Expand Up @@ -67,3 +69,25 @@ def test_report_csv_generate(

# 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

0 comments on commit 00beea2

Please sign in to comment.