padding
This commit is contained in:
1 parent
77d064627a
commit
0fe06f2ba5
3 files changed
+68
-22
No files matched your search
+48
-15
@@ -9,6 +9,7 @@ from __future__ import annotations
|
||||
import io
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import socketserver
|
||||
import subprocess
|
||||
@@ -85,6 +86,11 @@ def container(
|
||||
return entry
|
||||
|
||||
|
||||
def table_row_pattern(cells: list[str]) -> str:
|
||||
"""Regex matching a table row regardless of column padding."""
|
||||
return r"\|\s*" + r"\s*\|\s*".join(re.escape(cell) for cell in cells) + r"\s*\|"
|
||||
|
||||
|
||||
class DockerDiscoveryTests(unittest.TestCase):
|
||||
def test_images_in_use_returns_running_images(self) -> None:
|
||||
with FakeDocker([container("a" * 64, "testphp-php"), container("b" * 64, "redis:7")]) as docker:
|
||||
@@ -489,9 +495,9 @@ class ReportTests(unittest.TestCase):
|
||||
body = scan.build_important_body(
|
||||
"web", target, result, "/reports/x.json", "HIGH"
|
||||
)
|
||||
self.assertIn("| Image | Container | C | H |", body)
|
||||
self.assertIn("| nginx:1.27 | web | 1/1 | 1/2 |", body)
|
||||
self.assertNotIn("| M |", body)
|
||||
self.assertRegex(body, table_row_pattern(["Image", "Container", "C", "H"]))
|
||||
self.assertRegex(body, table_row_pattern(["nginx:1.27", "web", "1/1", "1/2"]))
|
||||
self.assertNotRegex(body, r"\|\s*M\s*\|")
|
||||
self.assertIn("CVE-1", body)
|
||||
self.assertIn("CVE-2", body)
|
||||
self.assertIn("CVE-5", body)
|
||||
@@ -507,9 +513,9 @@ class ReportTests(unittest.TestCase):
|
||||
self.assertIn("CVE-1", body)
|
||||
self.assertNotIn("CVE-2", body)
|
||||
self.assertNotIn("CVE-5", body)
|
||||
self.assertIn("| Image | Container | C |", body)
|
||||
self.assertIn("| nginx:1.27 | web | 1/1 |", body)
|
||||
self.assertNotIn("| H |", body)
|
||||
self.assertRegex(body, table_row_pattern(["Image", "Container", "C"]))
|
||||
self.assertRegex(body, table_row_pattern(["nginx:1.27", "web", "1/1"]))
|
||||
self.assertNotRegex(body, r"\|\s*H\s*\|")
|
||||
self.assertNotIn("Total:", body)
|
||||
|
||||
def test_build_other_containers_body_has_counts_per_container(self) -> None:
|
||||
@@ -522,10 +528,12 @@ class ReportTests(unittest.TestCase):
|
||||
)
|
||||
body = bodies[0]
|
||||
self.assertIn("Other containers with findings", body)
|
||||
self.assertIn("| Image | Container | C | H |", body)
|
||||
self.assertIn("| nginx:1.27 | web-worker | 1/1 | 1/2 |", body)
|
||||
self.assertIn("| redis:7 | cache | 0/0 | 0/4 |", body)
|
||||
self.assertNotIn("| M |", body)
|
||||
self.assertRegex(body, table_row_pattern(["Image", "Container", "C", "H"]))
|
||||
self.assertRegex(
|
||||
body, table_row_pattern(["nginx:1.27", "web-worker", "1/1", "1/2"])
|
||||
)
|
||||
self.assertRegex(body, table_row_pattern(["redis:7", "cache", "0/0", "0/4"]))
|
||||
self.assertNotRegex(body, r"\|\s*M\s*\|")
|
||||
self.assertNotIn("Total:", body)
|
||||
self.assertNotIn("Overall:", body)
|
||||
|
||||
@@ -544,8 +552,8 @@ class ReportTests(unittest.TestCase):
|
||||
[("web", target, result)], all_rows, "HIGH"
|
||||
)
|
||||
self.assertIn("Important containers:", body)
|
||||
self.assertIn("| Image | Container | C | H |", body)
|
||||
self.assertIn("| nginx:1.27 | web | 1/1 | 1/2 |", body)
|
||||
self.assertRegex(body, table_row_pattern(["Image", "Container", "C", "H"]))
|
||||
self.assertRegex(body, table_row_pattern(["nginx:1.27", "web", "1/1", "1/2"]))
|
||||
self.assertIn("Packages:", body)
|
||||
self.assertIn("libc 1.0 -> 1.1", body)
|
||||
self.assertIn("openssl 3.0.1 -> 3.0.2", body)
|
||||
@@ -554,6 +562,31 @@ class ReportTests(unittest.TestCase):
|
||||
self.assertIn("Overall: 2/3 fixable/total in 1 container(s)", body)
|
||||
self.assertNotIn("Total:", body)
|
||||
|
||||
def test_summary_table_pads_every_column(self) -> None:
|
||||
table = scan.summary_table(
|
||||
[
|
||||
(
|
||||
"nginx:1.27",
|
||||
"web",
|
||||
{"CRITICAL": 1, "HIGH": 2, "MEDIUM": 0, "LOW": 0},
|
||||
{"CRITICAL": 1, "HIGH": 1, "MEDIUM": 0, "LOW": 0},
|
||||
)
|
||||
],
|
||||
["CRITICAL", "HIGH"],
|
||||
)
|
||||
self.assertEqual(
|
||||
table,
|
||||
"\n".join(
|
||||
[
|
||||
"```",
|
||||
"| Image | Container | C | H |",
|
||||
"| ---------- | --------- | --- | --- |",
|
||||
"| nginx:1.27 | web | 1/1 | 1/2 |",
|
||||
"```",
|
||||
]
|
||||
),
|
||||
)
|
||||
|
||||
def test_build_missing_body_separates_missing_and_unscanned(self) -> None:
|
||||
body = scan.build_missing_body(["gone"], ["web"])
|
||||
self.assertIn("not running", body)
|
||||
@@ -690,7 +723,7 @@ printf '%s\\n' "$*" >> "$APPRISE_LOG"
|
||||
self.assertNotIn("Total:", notification)
|
||||
self.assertIn("No CVEs at or above", notification)
|
||||
self.assertIn("Vulnerability scan: summary", notification)
|
||||
self.assertIn("| alpine:3.20 | web | 0/0 | 0/0 |", notification)
|
||||
self.assertRegex(notification, table_row_pattern(["alpine:3.20", "web", "0/0", "0/0"]))
|
||||
self.assertIn("Overall: 0/0 fixable/total in 1 container(s)", notification)
|
||||
|
||||
def test_notification_includes_container(self) -> None:
|
||||
@@ -716,10 +749,10 @@ printf '%s\\n' "$*" >> "$APPRISE_LOG"
|
||||
self.assertEqual(code, 1)
|
||||
notification = Path(self.apprise_log).read_text()
|
||||
self.assertIn("Vulnerability scan: web (testphp-php)", notification)
|
||||
self.assertIn("| testphp-php | web | 1/1 | 0/0 |", notification)
|
||||
self.assertRegex(notification, table_row_pattern(["testphp-php", "web", "1/1", "0/0"]))
|
||||
self.assertIn("CVE-2026-0001", notification)
|
||||
self.assertIn("Vulnerability scan: other containers", notification)
|
||||
self.assertIn("| redis:7 | cache | 1/1 | 0/0 |", notification)
|
||||
self.assertRegex(notification, table_row_pattern(["redis:7", "cache", "1/1", "0/0"]))
|
||||
self.assertNotIn("Total:", notification)
|
||||
self.assertIn("Vulnerability scan: summary", notification)
|
||||
self.assertIn("Overall: 2/2 fixable/total in 2 container(s)", notification)
|
||||
|
||||
Reference in new issue
Block a user