Files
pkgmgr/tests/e2e/test_changelog_commands.py
Kevin Veen-Birkenbach 997c265cfb
Some checks failed
Mark stable commit / test-unit (push) Has been cancelled
Mark stable commit / test-integration (push) Has been cancelled
Mark stable commit / test-env-virtual (push) Has been cancelled
Mark stable commit / test-env-nix (push) Has been cancelled
Mark stable commit / test-e2e (push) Has been cancelled
Mark stable commit / test-virgin-user (push) Has been cancelled
Mark stable commit / test-virgin-root (push) Has been cancelled
Mark stable commit / lint-shell (push) Has been cancelled
Mark stable commit / lint-python (push) Has been cancelled
Mark stable commit / mark-stable (push) Has been cancelled
refactor(git): introduce GitRunError hierarchy, surface non-repo errors, and improve verification queries
* Replace legacy GitError usage with a clearer exception hierarchy:

  * GitBaseError as the common root for all git-related failures
  * GitRunError for subprocess execution failures
  * GitQueryError for read-only query failures
  * GitCommandError for state-changing command failures
  * GitNotRepositoryError to explicitly signal “not a git repository” situations
* Update git runner to detect “not a git repository” stderr and raise GitNotRepositoryError with rich context (cwd, command, stderr)
* Refactor repository verification to use dedicated query helpers instead of ad-hoc subprocess calls:

  * get_remote_head_commit (ls-remote) for pull mode
  * get_head_commit for local mode
  * get_latest_signing_key (%GK) for signature verification
* Add strict vs best-effort behavior in verify_repository:

  * Best-effort collection for reporting (does not block when no verification config exists)
  * Strict retrieval and explicit error messages when verification is configured
  * Clear failure cases when commit/signing key cannot be determined
* Add new unit tests covering:

  * get_latest_signing_key output stripping and error wrapping
  * get_remote_head_commit parsing, empty output, and error wrapping
  * verify_repository success/failure scenarios and “do not swallow GitNotRepositoryError”
* Adjust imports and exception handling across actions/commands/queries to align with GitRunError-based handling while keeping GitNotRepositoryError uncaught for debugging clarity

https://chatgpt.com/share/6943173c-508c-800f-8879-af75d131c79b
2025-12-17 21:48:03 +01:00

126 lines
4.2 KiB
Python

from __future__ import annotations
import os
import runpy
import sys
import unittest
from test_version_commands import (
_load_pkgmgr_repo_dir,
PROJECT_ROOT,
)
class TestIntegrationChangelogCommands(unittest.TestCase):
@classmethod
def setUpClass(cls) -> None:
"""
Versuche, das pkgmgr-Repository-Verzeichnis aus der Config zu laden.
Wenn es im aktuellen Test-Container nicht existiert, merken wir uns
None und überspringen repo-spezifische Tests später sauber.
"""
try:
repo_dir = _load_pkgmgr_repo_dir()
except Exception:
repo_dir = None
if repo_dir is not None and not os.path.isdir(repo_dir):
repo_dir = None
cls.pkgmgr_repo_dir = repo_dir
def _run_pkgmgr_changelog(
self,
extra_args: list[str] | None = None,
cwd: str | None = None,
) -> None:
"""
Helper that executes the pkgmgr CLI with the 'changelog' command
via runpy, similar to the existing version integration tests.
"""
if extra_args is None:
extra_args = []
cmd_repr = "pkgmgr changelog " + " ".join(extra_args)
original_argv = list(sys.argv)
original_cwd = os.getcwd()
try:
if cwd is not None and os.path.isdir(cwd):
os.chdir(cwd)
# Simulate CLI invocation: pkgmgr changelog <args...>
sys.argv = ["pkgmgr", "changelog"] + list(extra_args)
try:
runpy.run_module("pkgmgr", run_name="__main__")
except SystemExit as exc:
code = exc.code if isinstance(exc.code, int) else str(exc.code)
if code != 0:
print()
print(f"[TEST] Command : {cmd_repr}")
print(f"[TEST] Working directory: {os.getcwd()}")
print(f"[TEST] Exit code : {code}")
raise AssertionError(
f"{cmd_repr!r} failed with exit code {code}. "
"Scroll up to inspect the pkgmgr output before failure."
) from exc
finally:
os.chdir(original_cwd)
sys.argv = original_argv
def test_changelog_default_range_current_repo(self) -> None:
"""
Run 'pkgmgr changelog' inside the pkgmgr repo, using the default range
(last two SemVer tags or fallback to full history).
Wird übersprungen, wenn das pkgmgr-Repo in dieser Umgebung
nicht lokal vorhanden ist.
"""
if self.pkgmgr_repo_dir is None:
self.skipTest(
"pkgmgr repo directory not available in this environment; "
"skipping repo-local changelog test."
)
self._run_pkgmgr_changelog(extra_args=[], cwd=self.pkgmgr_repo_dir)
def test_changelog_explicit_range_head_history(self) -> None:
"""
Run 'pkgmgr changelog HEAD~5..HEAD' inside the pkgmgr repo.
Selbst wenn HEAD~5 nicht existiert, sollte der Befehl den
GitBaseError intern behandeln und mit Exit-Code 0 beenden
(es wird dann eine [ERROR]-Zeile gedruckt).
Wird übersprungen, wenn das pkgmgr-Repo nicht lokal vorhanden ist.
"""
if self.pkgmgr_repo_dir is None:
self.skipTest(
"pkgmgr repo directory not available in this environment; "
"skipping repo-local changelog range test."
)
self._run_pkgmgr_changelog(
extra_args=["HEAD~5..HEAD"],
cwd=self.pkgmgr_repo_dir,
)
def test_changelog_all_repositories_default(self) -> None:
"""
Run 'pkgmgr changelog --all' from the project root to ensure
that repository selection + changelog pipeline work in the
multi-repo scenario.
Dieser Test ist robust, selbst wenn einige Repos aus der Config
physisch nicht existieren: handle_changelog überspringt sie
mit einer INFO-Meldung.
"""
self._run_pkgmgr_changelog(
extra_args=["--all"],
cwd=PROJECT_ROOT,
)
if __name__ == "__main__":
unittest.main()