Files

82 lines
2.4 KiB
Python
Raw Permalink Normal View History

"""Network retries must never turn findings or incomplete audits into success."""
import importlib.util
import json
from pathlib import Path
from types import SimpleNamespace
import pytest
@pytest.fixture
def audit(monkeypatch, tmp_path):
spec = importlib.util.spec_from_file_location(
"ci_audit", Path(__file__).parents[1] / "scripts/ci-audit.py"
)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
monkeypatch.setattr(module.tempfile, "gettempdir", lambda: str(tmp_path))
monkeypatch.setattr(module.time, "sleep", lambda _: None)
monkeypatch.delenv("CI_AUDIT_TIMEOUT", raising=False)
monkeypatch.delenv("CI_AUDIT_ATTEMPTS", raising=False)
return module
def result(code=0, stderr="", vulns=None, dependencies=None):
report = {
"dependencies": dependencies
if dependencies is not None
else [{"name": "example", "vulns": vulns or []}]
}
return SimpleNamespace(returncode=code, stderr=stderr, stdout=json.dumps(report))
def test_transient_retry_then_complete(audit, monkeypatch):
replies = iter([result(1, "ReadTimeout"), result()])
calls = []
def run(command, **kwargs):
calls.append(command)
return next(replies)
monkeypatch.setattr(audit.subprocess, "run", run)
audit.main()
assert len(calls) == 2
assert calls[0] == calls[1]
assert "--cache-dir" in calls[0] and "--disable-pip" in calls[0]
@pytest.mark.parametrize(
"reply",
[
result(1, vulns=[{"id": "CVE-test"}]),
result(dependencies=[]),
result(dependencies=[{"name": "example", "skip_reason": "unavailable"}]),
result(2),
],
)
def test_no_retry_for_findings_or_incomplete(audit, monkeypatch, reply):
calls = []
monkeypatch.setattr(
audit.subprocess, "run", lambda *a, **k: calls.append(a) or reply
)
with pytest.raises(SystemExit):
audit.main()
assert len(calls) == 1
def test_network_exhaustion_blocks_and_redacts(audit, monkeypatch, capsys):
calls = []
monkeypatch.setattr(
audit.subprocess,
"run",
lambda *a, **k: (
calls.append(a)
or result(1, "ConnectionError https://user:secret@example.invalid")
),
)
with pytest.raises(SystemExit):
audit.main()
assert len(calls) == 3
assert "secret" not in capsys.readouterr().out