698ef63e67
Co-authored-by: ayattara <alassane.yattara@savoirfairelinux.com> Co-authored-by: Carlos Florencio <carlosmflorencio@gmail.com>
156 lines
5.4 KiB
Python
156 lines
5.4 KiB
Python
#!/usr/bin/env python3
|
|
"""Behavior tests for the bounded GitHub Actions step-summary writer."""
|
|
|
|
from pathlib import Path
|
|
import subprocess
|
|
import tempfile
|
|
import unittest
|
|
|
|
|
|
REPO_ROOT = Path(__file__).resolve().parents[2]
|
|
SCRIPT = REPO_ROOT / ".github" / "scripts" / "bounded-step-summary.py"
|
|
|
|
|
|
class BoundedStepSummaryTest(unittest.TestCase):
|
|
def run_writer(self, summary: str, *, max_bytes: int = 983_040) -> bytes:
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
tmp_path = Path(tmp)
|
|
source = tmp_path / "generated-summary.md"
|
|
output = tmp_path / "github-step-summary.md"
|
|
source.write_text(summary, encoding="utf-8")
|
|
|
|
result = subprocess.run(
|
|
[
|
|
"python3",
|
|
str(SCRIPT),
|
|
"--input",
|
|
str(source),
|
|
"--output",
|
|
str(output),
|
|
"--diagnostics-label",
|
|
"backend-test-results-1",
|
|
"--diagnostics-url",
|
|
"https://github.example.test/kdlbs/kandev/actions/runs/123#artifacts",
|
|
"--max-bytes",
|
|
str(max_bytes),
|
|
],
|
|
capture_output=True,
|
|
text=True,
|
|
check=False,
|
|
)
|
|
|
|
self.assertEqual(result.returncode, 0, result.stderr)
|
|
return output.read_bytes()
|
|
|
|
def test_normal_summary_is_unchanged(self) -> None:
|
|
summary = "## 📝 Test results\n\n🔴 `TestWorkspaceFailure` failed\n"
|
|
|
|
self.assertEqual(self.run_writer(summary), summary.encode("utf-8"))
|
|
|
|
def test_oversized_summary_is_bounded_explicit_and_utf8_safe(self) -> None:
|
|
summary = (
|
|
"## 📝 Test results\n\n"
|
|
"🔴 `TestWorkspaceFailure` failed\n\n"
|
|
"boundary-padding-12"
|
|
+ "diagnostic=失敗🔥\n" * 60_000
|
|
)
|
|
source_bytes = summary.encode("utf-8")
|
|
self.assertGreater(len(source_bytes), 1_048_576)
|
|
|
|
first = self.run_writer(summary)
|
|
second = self.run_writer(summary)
|
|
rendered = first.decode("utf-8")
|
|
|
|
self.assertLessEqual(len(first), 983_040)
|
|
self.assertEqual(first, second)
|
|
self.assertIn("TestWorkspaceFailure", rendered)
|
|
self.assertIn("truncated", rendered.lower())
|
|
self.assertIn("backend-test-results-1", rendered)
|
|
self.assertIn(
|
|
"https://github.example.test/kdlbs/kandev/actions/runs/123#artifacts",
|
|
rendered,
|
|
)
|
|
|
|
def test_oversized_summary_retains_later_failure_identity(self) -> None:
|
|
summary = (
|
|
"<h2>📝 Test results</h2>\n"
|
|
"<table><tr><td><ul>"
|
|
"<li>🔴<code>TestEarlyFailure</code></li>"
|
|
"</ul></td></tr></table>\n"
|
|
+ "diagnostic=失敗🔥\n" * 200_000
|
|
+ "<table><tr><td><ul>"
|
|
"<li>🔴<code>TestLaterFailure</code></li>"
|
|
"</ul></td></tr></table>\n"
|
|
)
|
|
|
|
rendered = self.run_writer(summary).decode("utf-8")
|
|
|
|
self.assertIn("TestEarlyFailure", rendered)
|
|
self.assertIn("TestLaterFailure", rendered)
|
|
|
|
def test_invalid_utf8_input_is_rejected(self) -> None:
|
|
# Contract coverage for the writer's existing UTF-8 validation.
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
tmp_path = Path(tmp)
|
|
source = tmp_path / "generated-summary.md"
|
|
output = tmp_path / "github-step-summary.md"
|
|
source.write_bytes(b"valid prefix\xff")
|
|
|
|
result = subprocess.run(
|
|
[
|
|
"python3",
|
|
str(SCRIPT),
|
|
"--input",
|
|
str(source),
|
|
"--output",
|
|
str(output),
|
|
"--diagnostics-label",
|
|
"backend-test-results-1",
|
|
"--diagnostics-url",
|
|
"https://github.example.test/kdlbs/kandev/actions/runs/123#artifacts",
|
|
],
|
|
capture_output=True,
|
|
text=True,
|
|
check=False,
|
|
)
|
|
|
|
self.assertNotEqual(result.returncode, 0)
|
|
self.assertIn("UnicodeDecodeError", result.stderr)
|
|
|
|
def test_impossibly_small_max_bytes_is_rejected(self) -> None:
|
|
with tempfile.TemporaryDirectory() as tmp:
|
|
tmp_path = Path(tmp)
|
|
source = tmp_path / "generated-summary.md"
|
|
output = tmp_path / "github-step-summary.md"
|
|
source.write_text("oversized summary", encoding="utf-8")
|
|
|
|
result = subprocess.run(
|
|
[
|
|
"python3",
|
|
str(SCRIPT),
|
|
"--input",
|
|
str(source),
|
|
"--output",
|
|
str(output),
|
|
"--diagnostics-label",
|
|
"backend-test-results-1",
|
|
"--diagnostics-url",
|
|
"https://github.example.test/kdlbs/kandev/actions/runs/123#artifacts",
|
|
"--max-bytes",
|
|
"1",
|
|
],
|
|
capture_output=True,
|
|
text=True,
|
|
check=False,
|
|
)
|
|
|
|
self.assertNotEqual(result.returncode, 0)
|
|
self.assertIn(
|
|
"max bytes is too small for the truncation notice",
|
|
result.stderr,
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|