Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(anta): Add support of CSV file export #672

Merged
merged 43 commits into from
Jul 17, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
c272163
feat(anta): Add support of CSV file export
titom73 May 13, 2024
daa60d2
fix(anta.cli): Move --save-to-csv at NRFU level
titom73 May 16, 2024
9cdf026
fix(anta.cli): rename csv option to --csv-output
titom73 May 16, 2024
12e7b67
Merge branch 'main' into feat/csv-export
titom73 Jun 7, 2024
b4bf68e
Merge branch 'main' into feat/csv-export
titom73 Jul 1, 2024
66c812e
Merge branch 'main' into feat/csv-export
titom73 Jul 5, 2024
c8266e9
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 5, 2024
4e16158
fix(anta.reporter): Define constants to manage table headers - sonarc…
titom73 Jul 5, 2024
13a6b48
fix(anta.reporter): Define constants to manage table headers - sonarc…
titom73 Jul 5, 2024
dd4d0ab
Merge branch 'main' into feat/csv-export
titom73 Jul 5, 2024
09b6577
refactor: Move to a click command for csv
titom73 Jul 5, 2024
bf501e2
refactor: ReportCsv to dedicated module
titom73 Jul 5, 2024
030c502
Merge branch 'main' into feat/csv-export
titom73 Jul 5, 2024
29afb2f
Merge branch 'main' into feat/csv-export
titom73 Jul 5, 2024
f010737
refactor: Code review
titom73 Jul 5, 2024
3365125
Merge branch 'main' into feat/csv-export
gmuloc Jul 5, 2024
5dd6f96
fix: Implement unit test for anta nrfu csv
titom73 Jul 6, 2024
f9c0c8a
fix: Implement unit test for anta nrfu csv
titom73 Jul 6, 2024
2cb770a
fix: Implement unit test for anta nrfu csv
titom73 Jul 7, 2024
c166cdb
doc: Add anta nrfu csv initial documentation
titom73 Jul 8, 2024
fd0bdbb
Merge branch 'main' into feat/csv-export
titom73 Jul 8, 2024
734cd7c
doc: Add anta nrfu csv documentation
titom73 Jul 8, 2024
99bd02b
Merge branch 'main' into feat/csv-export
gmuloc Jul 9, 2024
c8b5dde
Update docs/cli/nrfu.md
titom73 Jul 10, 2024
25639c3
Update docs/snippets/anta_nrfu_help.txt
titom73 Jul 10, 2024
434a975
Update docs/cli/nrfu.md
titom73 Jul 10, 2024
c35d721
Update tests/units/reporter/test_csv.py
titom73 Jul 10, 2024
ef2bab7
Update tests/units/cli/nrfu/test_commands.py
titom73 Jul 10, 2024
e9be744
Update anta/reporter/csv_reporter.py
titom73 Jul 10, 2024
ccbce5f
Update anta/reporter/csv_reporter.py
titom73 Jul 10, 2024
c6c3a50
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Jul 10, 2024
20d63c7
ci: Cleanup pytest
titom73 Jul 10, 2024
8173f2a
fix: Update cli help message
titom73 Jul 10, 2024
469496f
fix: Increase coverage: multiline
titom73 Jul 10, 2024
c572d85
fix: Update code
titom73 Jul 11, 2024
0a8f952
fix: Update code
titom73 Jul 11, 2024
1ad77d7
fix: Remove useless comment in CLI help message
titom73 Jul 12, 2024
a8626b6
update as per code review
titom73 Jul 16, 2024
e4a0197
fix: Capture error when opening CSV file
titom73 Jul 16, 2024
61a5629
doc: Fix doc
gmuloc Jul 16, 2024
00beea2
Refactor: Add test for OSError when writing csv report
gmuloc Jul 17, 2024
d92d829
Apply suggestions from code review
gmuloc Jul 17, 2024
3baf7ae
Test: Avoid creating test.csv in repo
gmuloc Jul 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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")
gmuloc marked this conversation as resolved.
Show resolved Hide resolved
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
Loading