From f72deace68996e7fdef1c78f4ee860d80ff544a5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 15 Jun 2026 21:08:14 +0000 Subject: [PATCH 1/6] Initial plan From ccb36e784dd03037210f8dcfad6713ee765ed9d1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 15 Jun 2026 21:13:20 +0000 Subject: [PATCH 2/6] Add check CLI junitxml coverage tests --- tests/test_check.py | 47 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/tests/test_check.py b/tests/test_check.py index 5fa0c39..a82261f 100644 --- a/tests/test_check.py +++ b/tests/test_check.py @@ -1,7 +1,18 @@ from click.testing import CliRunner +from pathlib import Path +import xml.etree.ElementTree as ET +import pytest from sigma.cli.check import check +TEST_FILES_DIR = Path(__file__).parent / "files" + + +def _require_junitxml_option(cli): + help_result = cli.invoke(check, ["--help"]) + if "--junitxml" not in help_result.output: + pytest.skip("--junitxml option is not available in this branch") + def test_check_help(): cli = CliRunner() @@ -88,3 +99,39 @@ def test_check_exclude(): assert "Invalid validators name" in result.stdout assert "myvalidator" in result.stdout assert "Check failure" in result.stdout + + +def test_check_junitxml_created_and_well_formed(tmp_path): + cli = CliRunner() + _require_junitxml_option(cli) + report_path = tmp_path / "check-report.xml" + result = cli.invoke( + check, + [ + "--junitxml", + str(report_path), + str(TEST_FILES_DIR / "invalid"), + ], + ) + assert result.exit_code == 1 + assert report_path.exists() + root = ET.parse(report_path).getroot() + assert root.tag == "testsuites" + + +def test_check_junitxml_reports_failures_for_invalid_rules(tmp_path): + cli = CliRunner() + _require_junitxml_option(cli) + report_path = tmp_path / "check-report.xml" + result = cli.invoke( + check, + [ + "--junitxml", + str(report_path), + str(TEST_FILES_DIR / "invalid"), + ], + ) + assert result.exit_code == 1 + root = ET.parse(report_path).getroot() + failures = root.findall(".//failure") + assert len(failures) > 0 From e0e8b77a6f2acf6d87c52cd60d6cfb0735504297 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 15 Jun 2026 21:14:30 +0000 Subject: [PATCH 3/6] Harden junitxml test guards and XML assertions --- tests/test_check.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_check.py b/tests/test_check.py index a82261f..6b1091f 100644 --- a/tests/test_check.py +++ b/tests/test_check.py @@ -9,8 +9,7 @@ def _require_junitxml_option(cli): - help_result = cli.invoke(check, ["--help"]) - if "--junitxml" not in help_result.output: + if "junitxml" not in {param.name for param in check.params}: pytest.skip("--junitxml option is not available in this branch") @@ -117,6 +116,7 @@ def test_check_junitxml_created_and_well_formed(tmp_path): assert report_path.exists() root = ET.parse(report_path).getroot() assert root.tag == "testsuites" + assert len(root.findall("testsuite")) > 0 def test_check_junitxml_reports_failures_for_invalid_rules(tmp_path): From 31523961d3467ac4a71f5bea495c886eb4b5ce63 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 15 Jun 2026 21:15:18 +0000 Subject: [PATCH 4/6] Refine junitxml test compatibility checks --- tests/test_check.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tests/test_check.py b/tests/test_check.py index 6b1091f..4acf4da 100644 --- a/tests/test_check.py +++ b/tests/test_check.py @@ -8,7 +8,7 @@ TEST_FILES_DIR = Path(__file__).parent / "files" -def _require_junitxml_option(cli): +def _require_junitxml_option(): if "junitxml" not in {param.name for param in check.params}: pytest.skip("--junitxml option is not available in this branch") @@ -102,7 +102,7 @@ def test_check_exclude(): def test_check_junitxml_created_and_well_formed(tmp_path): cli = CliRunner() - _require_junitxml_option(cli) + _require_junitxml_option() report_path = tmp_path / "check-report.xml" result = cli.invoke( check, @@ -115,13 +115,14 @@ def test_check_junitxml_created_and_well_formed(tmp_path): assert result.exit_code == 1 assert report_path.exists() root = ET.parse(report_path).getroot() - assert root.tag == "testsuites" - assert len(root.findall("testsuite")) > 0 + assert root.tag in {"testsuites", "testsuite"} + if root.tag == "testsuites": + assert len(root.findall("testsuite")) > 0 def test_check_junitxml_reports_failures_for_invalid_rules(tmp_path): cli = CliRunner() - _require_junitxml_option(cli) + _require_junitxml_option() report_path = tmp_path / "check-report.xml" result = cli.invoke( check, From 1dd9dde4b6dec07466a04088ca63a209e1c92713 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 15 Jun 2026 21:16:14 +0000 Subject: [PATCH 5/6] Polish junitxml test helper naming --- tests/test_check.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/test_check.py b/tests/test_check.py index 4acf4da..0ea3c3c 100644 --- a/tests/test_check.py +++ b/tests/test_check.py @@ -8,7 +8,7 @@ TEST_FILES_DIR = Path(__file__).parent / "files" -def _require_junitxml_option(): +def _skip_if_junitxml_unavailable(): if "junitxml" not in {param.name for param in check.params}: pytest.skip("--junitxml option is not available in this branch") @@ -101,10 +101,10 @@ def test_check_exclude(): def test_check_junitxml_created_and_well_formed(tmp_path): - cli = CliRunner() - _require_junitxml_option() + runner = CliRunner() + _skip_if_junitxml_unavailable() report_path = tmp_path / "check-report.xml" - result = cli.invoke( + result = runner.invoke( check, [ "--junitxml", @@ -121,10 +121,10 @@ def test_check_junitxml_created_and_well_formed(tmp_path): def test_check_junitxml_reports_failures_for_invalid_rules(tmp_path): - cli = CliRunner() - _require_junitxml_option() + runner = CliRunner() + _skip_if_junitxml_unavailable() report_path = tmp_path / "check-report.xml" - result = cli.invoke( + result = runner.invoke( check, [ "--junitxml", From 59ce97e2676c7714c98c10ced327f470f61e3495 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 15 Jun 2026 21:17:09 +0000 Subject: [PATCH 6/6] Clarify junitxml test helper and root-tag check --- tests/test_check.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/test_check.py b/tests/test_check.py index 0ea3c3c..3518fc5 100644 --- a/tests/test_check.py +++ b/tests/test_check.py @@ -8,7 +8,7 @@ TEST_FILES_DIR = Path(__file__).parent / "files" -def _skip_if_junitxml_unavailable(): +def skip_if_junitxml_unavailable(): if "junitxml" not in {param.name for param in check.params}: pytest.skip("--junitxml option is not available in this branch") @@ -102,7 +102,7 @@ def test_check_exclude(): def test_check_junitxml_created_and_well_formed(tmp_path): runner = CliRunner() - _skip_if_junitxml_unavailable() + skip_if_junitxml_unavailable() report_path = tmp_path / "check-report.xml" result = runner.invoke( check, @@ -115,6 +115,8 @@ def test_check_junitxml_created_and_well_formed(tmp_path): assert result.exit_code == 1 assert report_path.exists() root = ET.parse(report_path).getroot() + # JUnit XML producers can emit either a single "testsuite" root + # or a "testsuites" wrapper for multiple suites. assert root.tag in {"testsuites", "testsuite"} if root.tag == "testsuites": assert len(root.findall("testsuite")) > 0 @@ -122,7 +124,7 @@ def test_check_junitxml_created_and_well_formed(tmp_path): def test_check_junitxml_reports_failures_for_invalid_rules(tmp_path): runner = CliRunner() - _skip_if_junitxml_unavailable() + skip_if_junitxml_unavailable() report_path = tmp_path / "check-report.xml" result = runner.invoke( check,