Files
swift-mirror/utils/update_checkout/tests/test_git_command.py
T

101 lines
3.6 KiB
Python

import subprocess
import unittest
from pathlib import Path
from unittest.mock import MagicMock, patch
from update_checkout.git_command import Git, GitException
from update_checkout.update_checkout import confirm_tag_in_repo
FAKE_PATH = Path("/fake_path")
SSH_WARNING = (
"** WARNING: connection is not using a post-quantum key exchange algorithm.\n"
"** This session may be vulnerable to \"store now, decrypt later\" attacks.\n"
"** The server may need to be upgraded. See https://openssh.com/pq.html\n"
)
def _make_process_result(stdout="", stderr="", returncode=0):
result = MagicMock()
result.stdout = stdout
result.stderr = stderr
result.returncode = returncode
if returncode != 0:
result.check_returncode.side_effect = subprocess.CalledProcessError(
returncode, ["git"]
)
return result
class TestGitRunStderrIsolation(unittest.TestCase):
@patch("subprocess.run")
def test_ssh_warning_on_stderr_not_returned_as_output(self, mock_run):
"""SSH warnings emitted to stderr must not appear in the returned output."""
mock_run.return_value = _make_process_result(stdout="", stderr=SSH_WARNING)
output, _, _ = Git.run(FAKE_PATH, ["ls-remote", "--tags", "origin", "some-tag"])
self.assertEqual(output, "")
@patch("subprocess.run")
def test_stdout_returned_when_tag_exists(self, mock_run):
"""Real tag data in stdout is returned correctly even with SSH warnings."""
tag_line = "abc123\trefs/tags/fake-tag\n"
mock_run.return_value = _make_process_result(
stdout=tag_line, stderr=SSH_WARNING
)
output, _, _ = Git.run(FAKE_PATH, ["ls-remote", "--tags", "origin", "some-tag"])
self.assertIn("refs/tags/", output)
@patch("subprocess.run")
def test_stderr_included_in_exception_on_failure(self, mock_run):
"""On failure, GitException must include stderr content for diagnostics."""
mock_run.return_value = _make_process_result(
stdout="", stderr=SSH_WARNING, returncode=128
)
with self.assertRaises(GitException) as ctx:
Git.run(FAKE_PATH, ["fetch", "origin", "some-tag"])
self.assertIn("post-quantum", ctx.exception.stderr)
class TestConfirmTagInRepo(unittest.TestCase):
@patch("builtins.print")
@patch("subprocess.run")
def test_returns_none_when_tag_absent_with_ssh_warning(self, mock_run, _mock_print):
"""confirm_tag_in_repo must return None when the tag does not exist,
even if an SSH warning is present on stderr.
"""
mock_run.return_value = _make_process_result(stdout="", stderr=SSH_WARNING)
result = confirm_tag_in_repo(FAKE_PATH, "fake-tag", "llbuild")
self.assertIsNone(result)
@patch("subprocess.run")
def test_returns_tag_when_tag_exists_with_ssh_warning(self, mock_run):
"""confirm_tag_in_repo must return the tag name when it exists,
regardless of SSH warnings on stderr.
"""
tag_line = "abc123\trefs/tags/fake-tag\n"
mock_run.return_value = _make_process_result(
stdout=tag_line, stderr=SSH_WARNING
)
result = confirm_tag_in_repo(FAKE_PATH, "fake-tag", "llbuild")
self.assertEqual(result, "fake-tag")
@patch("builtins.print")
@patch("subprocess.run")
def test_returns_none_when_tag_absent_without_ssh_warning(self, mock_run, _mock_print):
"""confirm_tag_in_repo must return None for a missing tag (baseline case)."""
mock_run.return_value = _make_process_result(stdout="", stderr="")
result = confirm_tag_in_repo(FAKE_PATH, "fake-tag", "llbuild")
self.assertIsNone(result)