Files
pkgmgr/tests/e2e/test_version_commands.py
Kevin Veen-Birkenbach f5d428950e
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 / mark-stable (push) Has been cancelled
**Replace main.py with module-based entry point and unify CLI execution**
* Remove legacy *main.py* and introduce *pkgmgr* module entry via *python -m pkgmgr*
* Add ***main**.py* as the canonical entry point delegating to the CLI
* Export *PYTHONPATH=src* in Makefile to ensure reliable imports in dev and CI
* Update setup scripts (venv & nix) to use module execution
* Refactor all E2E tests to execute the real module entry instead of file paths

This aligns pkgmgr with standard Python packaging practices and simplifies testing, setup, and execution across environments.

https://chatgpt.com/share/693c9056-716c-800f-b583-fc9245eab2b4
2025-12-12 22:59:46 +01:00

188 lines
6.2 KiB
Python

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
End-to-end tests for the `pkgmgr version` command.
We verify three usage patterns:
1) pkgmgr version
- Run from inside the package-manager repository
so that "current repository" resolution works.
2) pkgmgr version pkgmgr
- Run from inside the package-manager repository
with an explicit identifier.
3) pkgmgr version --all
- Run from the project root (or wherever the tests are started),
ensuring that the --all flag does not depend on the current
working directory.
"""
from __future__ import annotations
import os
import runpy
import sys
import unittest
from typing import List
from pkgmgr.core.config.load import load_config
# Resolve project root (the repo where main.py lives, e.g. /src)
PROJECT_ROOT = os.path.abspath(
os.path.join(os.path.dirname(__file__), "..", "..")
)
CONFIG_PATH = os.path.join(PROJECT_ROOT, "config", "config.yaml")
def _load_pkgmgr_repo_dir() -> str:
"""
Load the merged configuration (defaults + user config) and determine
the directory of the package-manager repository managed by pkgmgr.
We keep this lookup deliberately flexible to avoid depending on
specific provider/account values. We match either
repository == "package-manager" OR
alias == "pkgmgr"
and then derive the repository directory from either an explicit
'directory' field or from the base repositories directory plus
provider/account/repository.
"""
cfg = load_config(CONFIG_PATH) or {}
directories = cfg.get("directories", {})
base_repos_dir = os.path.expanduser(directories.get("repositories", ""))
candidates: List[dict] = cfg.get("repositories", []) or []
for repo in candidates:
repo_name = (repo.get("repository") or "").strip()
alias = (repo.get("alias") or "").strip()
if repo_name == "package-manager" or alias == "pkgmgr":
# Prefer an explicit directory if present.
repo_dir = repo.get("directory")
if not repo_dir:
provider = (repo.get("provider") or "").strip()
account = (repo.get("account") or "").strip()
# Best-effort reconstruction of the directory path.
if provider and account and repo_name:
repo_dir = os.path.join(
base_repos_dir, provider, account, repo_name
)
elif repo_name:
# Fallback: place directly under the base repo dir
repo_dir = os.path.join(base_repos_dir, repo_name)
else:
# If we still have nothing usable, skip this entry.
continue
return os.path.expanduser(repo_dir)
raise RuntimeError(
"Could not locate a 'package-manager' repository entry in the merged "
"configuration (no entry with repository='package-manager' or "
"alias='pkgmgr' found)."
)
class TestIntegrationVersionCommands(unittest.TestCase):
"""
E2E tests for the pkgmgr 'version' command.
Important:
- We treat any non-zero SystemExit as a test failure and print
helpful diagnostics (command, working directory, exit code).
"""
@classmethod
def setUpClass(cls) -> None:
# Determine the package-manager repo directory from the merged config
cls.pkgmgr_repo_dir = _load_pkgmgr_repo_dir()
# ------------------------------------------------------------------
# Helper
# ------------------------------------------------------------------
def _run_pkgmgr_version(self, extra_args, cwd: str | None = None) -> None:
"""
Run `pkgmgr version` with optional extra arguments and
an optional working directory override.
Any non-zero exit code is turned into an AssertionError
with additional diagnostics.
"""
if extra_args is None:
extra_args = []
cmd_repr = "pkgmgr version " + " ".join(extra_args)
original_argv = list(sys.argv)
original_cwd = os.getcwd()
try:
if cwd is not None:
os.chdir(cwd)
sys.argv = ["pkgmgr", "version"] + 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("[TEST] SystemExit caught while running pkgmgr version")
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 output printed before failure."
) from exc
# exit code 0 is considered success
finally:
# Restore environment
os.chdir(original_cwd)
sys.argv = original_argv
# ------------------------------------------------------------------
# Tests
# ------------------------------------------------------------------
def test_version_current_repo(self) -> None:
"""
Run: pkgmgr version
We run this from inside the package-manager repository so that
"current repository" resolution works and no identifier lookup
for 'src' (or similar) is performed.
"""
self._run_pkgmgr_version(extra_args=[], cwd=self.pkgmgr_repo_dir)
def test_version_specific_identifier(self) -> None:
"""
Run: pkgmgr version pkgmgr
Also executed from inside the package-manager repository, but
with an explicit identifier.
"""
self._run_pkgmgr_version(extra_args=["pkgmgr"], cwd=self.pkgmgr_repo_dir)
def test_version_all_repositories(self) -> None:
"""
Run: pkgmgr version --all
This does not depend on the current working directory, but we
run it from PROJECT_ROOT for clarity and to mirror typical usage
in CI.
"""
self._run_pkgmgr_version(extra_args=["--all"], cwd=PROJECT_ROOT)
if __name__ == "__main__":
unittest.main()