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:
168
tests/test_clone_repos.py
Normal file
168
tests/test_clone_repos.py
Normal 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
129
tests/test_install_repos.py
Normal 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()
|
||||
47
tests/test_integration_install_all_shallow.py
Normal file
47
tests/test_integration_install_all_shallow.py
Normal 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
19
tests/test_main.py
Normal 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()
|
||||
Reference in New Issue
Block a user