From 90299d1ba32fc68b188541593af26aae34826a8a Mon Sep 17 00:00:00 2001 From: Carl Baillargeon Date: Tue, 27 Aug 2024 20:01:55 -0400 Subject: [PATCH] fix(anta): Remove JSON output when saving to a file (#800) --- anta/cli/nrfu/commands.py | 2 +- anta/cli/nrfu/utils.py | 21 ++++++++++----- docs/cli/nrfu.md | 6 ++--- tests/units/cli/nrfu/test_commands.py | 39 ++++++++++++++++++++++++++- 4 files changed, 56 insertions(+), 12 deletions(-) diff --git a/anta/cli/nrfu/commands.py b/anta/cli/nrfu/commands.py index cd750cb85..6043dbef9 100644 --- a/anta/cli/nrfu/commands.py +++ b/anta/cli/nrfu/commands.py @@ -42,7 +42,7 @@ def table(ctx: click.Context, group_by: Literal["device", "test"] | None) -> Non type=click.Path(file_okay=True, dir_okay=False, exists=False, writable=True, path_type=pathlib.Path), show_envvar=True, required=False, - help="Path to save report as a file", + help="Path to save report as a JSON file", ) def json(ctx: click.Context, output: pathlib.Path | None) -> None: """ANTA command to check network state with JSON result.""" diff --git a/anta/cli/nrfu/utils.py b/anta/cli/nrfu/utils.py index 284c9b709..cfc2e1ed1 100644 --- a/anta/cli/nrfu/utils.py +++ b/anta/cli/nrfu/utils.py @@ -94,14 +94,21 @@ def print_table(ctx: click.Context, group_by: Literal["device", "test"] | None = def print_json(ctx: click.Context, output: pathlib.Path | None = None) -> None: - """Print result in a json format.""" + """Print results as JSON. If output is provided, save to file instead.""" results = _get_result_manager(ctx) - console.print() - console.print(Panel("JSON results", style="cyan")) - rich.print_json(results.json) - if output is not None: - with output.open(mode="w", encoding="utf-8") as fout: - fout.write(results.json) + + if output is None: + console.print() + console.print(Panel("JSON results", style="cyan")) + rich.print_json(results.json) + else: + try: + with output.open(mode="w", encoding="utf-8") as file: + file.write(results.json) + console.print(f"JSON results saved to {output} ✅", style="cyan") + except OSError: + console.print(f"Failed to save JSON results to {output} ❌", style="cyan") + ctx.exit(ExitCode.USAGE_ERROR) def print_text(ctx: click.Context) -> None: diff --git a/docs/cli/nrfu.md b/docs/cli/nrfu.md index afed25949..2f4e7eedc 100644 --- a/docs/cli/nrfu.md +++ b/docs/cli/nrfu.md @@ -120,7 +120,7 @@ anta nrfu --test VerifyZeroTouch table ## Performing NRFU with JSON rendering -The JSON rendering command in NRFU testing is useful in generating a JSON output that can subsequently be passed on to another tool for reporting purposes. +The JSON rendering command in NRFU testing will generate an output of all test results in JSON format. ### Command overview @@ -131,12 +131,12 @@ Usage: anta nrfu json [OPTIONS] ANTA command to check network state with JSON result. Options: - -o, --output FILE Path to save report as a file [env var: + -o, --output FILE Path to save report as a JSON file [env var: ANTA_NRFU_JSON_OUTPUT] --help Show this message and exit. ``` -The `--output` option allows you to save the JSON report as a file. +The `--output` option allows you to save the JSON report as a file. If specified, no output will be displayed in the terminal. This is useful for further processing or integration with other tools. ### Example diff --git a/tests/units/cli/nrfu/test_commands.py b/tests/units/cli/nrfu/test_commands.py index 8ad7745f4..803c8f803 100644 --- a/tests/units/cli/nrfu/test_commands.py +++ b/tests/units/cli/nrfu/test_commands.py @@ -8,7 +8,7 @@ import json import re from pathlib import Path -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Any from unittest.mock import patch from anta.cli import anta @@ -90,6 +90,43 @@ def test_anta_nrfu_json(click_runner: CliRunner) -> None: assert res["result"] == "success" +def test_anta_nrfu_json_output(click_runner: CliRunner, tmp_path: Path) -> None: + """Test anta nrfu json with output file.""" + json_output = tmp_path / "test.json" + result = click_runner.invoke(anta, ["nrfu", "json", "--output", str(json_output)]) + + # Making sure the output is not printed to stdout + match = re.search(r"\[\n {2}{[\s\S]+ {2}}\n\]", result.output) + assert match is None + + assert result.exit_code == ExitCode.OK + assert "JSON results saved to" in result.output + assert json_output.exists() + + +def test_anta_nrfu_json_output_failure(click_runner: CliRunner, tmp_path: Path) -> None: + """Test anta nrfu json with output file.""" + json_output = tmp_path / "test.json" + + original_open = Path.open + + def mock_path_open(*args: Any, **kwargs: Any) -> Path: # noqa: ANN401 + """Mock Path.open only for the json_output file of this test.""" + if args[0] == json_output: + msg = "Simulated OSError" + raise OSError(msg) + + # If not the json_output file, call the original Path.open + return original_open(*args, **kwargs) + + with patch("pathlib.Path.open", mock_path_open): + result = click_runner.invoke(anta, ["nrfu", "json", "--output", str(json_output)]) + + assert result.exit_code == ExitCode.USAGE_ERROR + assert "Failed to save JSON results to" in result.output + assert not json_output.exists() + + def test_anta_nrfu_template(click_runner: CliRunner) -> None: """Test anta nrfu, catalog is given via env.""" result = click_runner.invoke(anta, ["nrfu", "tpl-report", "--template", str(DATA_DIR / "template.j2")])