Add Arch-based Docker test setup, shallow clone mode support and pkgmgr tests (see ChatGPT conversation: https://chatgpt.com/share/693052a1-edd0-800f-a9d6-c154b8e7d8e0)

This commit is contained in:
Kevin Veen-Birkenbach
2025-12-03 16:09:42 +01:00
parent 71cf032506
commit c4395a4764
9 changed files with 484 additions and 31 deletions

168
tests/test_clone_repos.py Normal file
View File

@@ -0,0 +1,168 @@
# tests/test_clone_repos.py
import unittest
from unittest.mock import patch, MagicMock
from pkgmgr.clone_repos import clone_repos
class TestCloneRepos(unittest.TestCase):
def setUp(self):
self.repo = {
"provider": "github.com",
"account": "user",
"repository": "repo",
}
self.selected = [self.repo]
self.base_dir = "/tmp/repos"
self.all_repos = self.selected
@patch("pkgmgr.clone_repos.verify_repository")
@patch("pkgmgr.clone_repos.subprocess.run")
@patch("pkgmgr.clone_repos.os.makedirs")
@patch("pkgmgr.clone_repos.os.path.exists")
@patch("pkgmgr.clone_repos.get_repo_dir")
@patch("pkgmgr.clone_repos.get_repo_identifier")
def test_clone_ssh_mode_uses_ssh_url(
self,
mock_get_repo_identifier,
mock_get_repo_dir,
mock_exists,
mock_makedirs,
mock_run,
mock_verify,
):
mock_get_repo_identifier.return_value = "github.com/user/repo"
mock_get_repo_dir.return_value = "/tmp/repos/user/repo"
mock_exists.return_value = False
mock_run.return_value = MagicMock(returncode=0)
mock_verify.return_value = (True, [], "hash", "key")
clone_repos(
self.selected,
self.base_dir,
self.all_repos,
preview=False,
no_verification=True,
clone_mode="ssh",
)
mock_run.assert_called_once()
# subprocess.run wird mit positional args aufgerufen
cmd = mock_run.call_args[0][0]
cwd = mock_run.call_args[1]["cwd"]
self.assertIn("git clone", cmd)
self.assertIn("git@github.com:user/repo.git", cmd)
self.assertEqual(cwd, "/tmp/repos/user")
@patch("pkgmgr.clone_repos.verify_repository")
@patch("pkgmgr.clone_repos.subprocess.run")
@patch("pkgmgr.clone_repos.os.makedirs")
@patch("pkgmgr.clone_repos.os.path.exists")
@patch("pkgmgr.clone_repos.get_repo_dir")
@patch("pkgmgr.clone_repos.get_repo_identifier")
def test_clone_https_mode_uses_https_url(
self,
mock_get_repo_identifier,
mock_get_repo_dir,
mock_exists,
mock_makedirs,
mock_run,
mock_verify,
):
mock_get_repo_identifier.return_value = "github.com/user/repo"
mock_get_repo_dir.return_value = "/tmp/repos/user/repo"
mock_exists.return_value = False
mock_run.return_value = MagicMock(returncode=0)
mock_verify.return_value = (True, [], "hash", "key")
clone_repos(
self.selected,
self.base_dir,
self.all_repos,
preview=False,
no_verification=True,
clone_mode="https",
)
mock_run.assert_called_once()
cmd = mock_run.call_args[0][0]
cwd = mock_run.call_args[1]["cwd"]
self.assertIn("git clone", cmd)
self.assertIn("https://github.com/user/repo.git", cmd)
self.assertEqual(cwd, "/tmp/repos/user")
@patch("pkgmgr.clone_repos.verify_repository")
@patch("pkgmgr.clone_repos.subprocess.run")
@patch("pkgmgr.clone_repos.os.makedirs")
@patch("pkgmgr.clone_repos.os.path.exists")
@patch("pkgmgr.clone_repos.get_repo_dir")
@patch("pkgmgr.clone_repos.get_repo_identifier")
def test_clone_shallow_mode_uses_https_with_depth(
self,
mock_get_repo_identifier,
mock_get_repo_dir,
mock_exists,
mock_makedirs,
mock_run,
mock_verify,
):
mock_get_repo_identifier.return_value = "github.com/user/repo"
mock_get_repo_dir.return_value = "/tmp/repos/user/repo"
mock_exists.return_value = False
mock_run.return_value = MagicMock(returncode=0)
mock_verify.return_value = (True, [], "hash", "key")
clone_repos(
self.selected,
self.base_dir,
self.all_repos,
preview=False,
no_verification=True,
clone_mode="shallow",
)
mock_run.assert_called_once()
cmd = mock_run.call_args[0][0]
cwd = mock_run.call_args[1]["cwd"]
self.assertIn("git clone --depth 1 --single-branch", cmd)
self.assertIn("https://github.com/user/repo.git", cmd)
self.assertEqual(cwd, "/tmp/repos/user")
@patch("pkgmgr.clone_repos.verify_repository")
@patch("pkgmgr.clone_repos.subprocess.run")
@patch("pkgmgr.clone_repos.os.makedirs")
@patch("pkgmgr.clone_repos.os.path.exists")
@patch("pkgmgr.clone_repos.get_repo_dir")
@patch("pkgmgr.clone_repos.get_repo_identifier")
def test_preview_mode_does_not_call_subprocess_run(
self,
mock_get_repo_identifier,
mock_get_repo_dir,
mock_exists,
mock_makedirs,
mock_run,
mock_verify,
):
mock_get_repo_identifier.return_value = "github.com/user/repo"
mock_get_repo_dir.return_value = "/tmp/repos/user/repo"
mock_exists.return_value = False
mock_verify.return_value = (True, [], "hash", "key")
clone_repos(
self.selected,
self.base_dir,
self.all_repos,
preview=True,
no_verification=True,
clone_mode="shallow",
)
# Im Preview-Modus sollte subprocess.run nicht aufgerufen werden
mock_run.assert_not_called()
if __name__ == "__main__":
unittest.main()

129
tests/test_install_repos.py Normal file
View File

@@ -0,0 +1,129 @@
# tests/test_install_repos.py
import os
import unittest
from unittest.mock import patch, MagicMock, mock_open
from pkgmgr.install_repos import install_repos
class TestInstallRepos(unittest.TestCase):
def setUp(self):
self.repo = {
"provider": "github.com",
"account": "user",
"repository": "repo",
}
self.selected = [self.repo]
self.base_dir = "/tmp/repos"
self.bin_dir = "/tmp/bin"
self.all_repos = self.selected
@patch("pkgmgr.install_repos.clone_repos")
@patch("pkgmgr.install_repos.os.path.exists")
@patch("pkgmgr.install_repos.get_repo_dir")
@patch("pkgmgr.install_repos.get_repo_identifier")
def test_calls_clone_repos_with_clone_mode(
self,
mock_get_repo_identifier,
mock_get_repo_dir,
mock_exists,
mock_clone_repos,
):
mock_get_repo_identifier.return_value = "github.com/user/repo"
mock_get_repo_dir.return_value = "/tmp/repos/user/repo"
# Repo-Verzeichnis existiert nicht -> soll geklont werden
mock_exists.return_value = False
install_repos(
self.selected,
self.base_dir,
self.bin_dir,
self.all_repos,
no_verification=True,
preview=False,
quiet=True,
clone_mode="shallow",
update_dependencies=False,
)
mock_clone_repos.assert_called_once()
args, kwargs = mock_clone_repos.call_args
# clone_mode ist letztes Argument
self.assertEqual(args[-1], "shallow")
@patch("pkgmgr.install_repos.run_command")
@patch("pkgmgr.install_repos.open", new_callable=mock_open, create=True)
@patch("pkgmgr.install_repos.yaml.safe_load")
@patch("pkgmgr.install_repos.os.path.exists")
@patch("pkgmgr.install_repos.create_ink")
@patch("pkgmgr.install_repos.verify_repository")
@patch("pkgmgr.install_repos.get_repo_dir")
@patch("pkgmgr.install_repos.get_repo_identifier")
def test_pkgmgr_requirements_propagate_clone_mode(
self,
mock_get_repo_identifier,
mock_get_repo_dir,
mock_verify,
mock_create_ink,
mock_exists,
mock_safe_load,
mock_open_file,
mock_run_command,
):
mock_get_repo_identifier.return_value = "github.com/user/repo"
repo_dir = "/tmp/repos/user/repo"
mock_get_repo_dir.return_value = repo_dir
# exists() muss True für repo_dir & requirements.yml liefern,
# sonst werden die Anforderungen nie verarbeitet.
def exists_side_effect(path):
if path == repo_dir:
return True
if path == os.path.join(repo_dir, "requirements.yml"):
return True
# requirements.txt und Makefile sollen "nicht existieren"
return False
mock_exists.side_effect = exists_side_effect
mock_verify.return_value = (True, [], "hash", "key")
# requirements.yml enthält pkgmgr-Dependencies
mock_safe_load.return_value = {
"pkgmgr": ["github.com/other/account/dep"],
}
commands = []
def run_command_side_effect(cmd, cwd=None, preview=False):
commands.append((cmd, cwd, preview))
mock_run_command.side_effect = run_command_side_effect
install_repos(
self.selected,
self.base_dir,
self.bin_dir,
self.all_repos,
no_verification=False,
preview=False,
quiet=True,
clone_mode="shallow",
update_dependencies=False,
)
# Prüfen, dass ein pkgmgr install Befehl mit --clone-mode shallow gebaut wurde
pkgmgr_install_cmds = [
c for (c, cwd, preview) in commands if "pkgmgr install" in c
]
self.assertTrue(
pkgmgr_install_cmds,
f"No pkgmgr install command was executed. Commands seen: {commands}",
)
cmd = pkgmgr_install_cmds[0]
self.assertIn("--clone-mode shallow", cmd)
if __name__ == "__main__":
unittest.main()

View File

@@ -0,0 +1,47 @@
# tests/test_integration_install_all_shallow.py
"""
Integration test: install all configured repositories using
--clone-mode shallow (HTTPS shallow clone) and --no-verification.
This test is intended to be run inside the Docker container where:
- network access is available,
- the config/config.yaml is present,
- and it is safe to perform real git operations.
It passes if the command completes without raising an exception.
"""
import runpy
import sys
import unittest
class TestIntegrationInstallAllShallow(unittest.TestCase):
def test_install_all_repositories_shallow(self):
"""
Run: pkgmgr install --all --clone-mode shallow --no-verification
This will perform real installations/clones inside the container.
The test succeeds if no exception is raised.
"""
original_argv = sys.argv
try:
sys.argv = [
"pkgmgr",
"install",
"--all",
"--clone-mode",
"shallow",
"--no-verification",
]
# Execute main.py as if it was called from CLI.
# This will run the full install pipeline inside the container.
runpy.run_module("main", run_name="__main__")
finally:
sys.argv = original_argv
if __name__ == "__main__":
unittest.main()

19
tests/test_main.py Normal file
View File

@@ -0,0 +1,19 @@
# tests/test_main.py
import unittest
import main
class TestMainModule(unittest.TestCase):
def test_proxy_commands_defined(self):
"""
Basic sanity check: main.py should define PROXY_COMMANDS
with git/docker/docker compose entries.
"""
self.assertTrue(hasattr(main, "PROXY_COMMANDS"))
self.assertIn("git", main.PROXY_COMMANDS)
self.assertIn("docker", main.PROXY_COMMANDS)
self.assertIn("docker compose", main.PROXY_COMMANDS)
if __name__ == "__main__":
unittest.main()