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:
25
.github/workflows/test.yml
vendored
Normal file
25
.github/workflows/test.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
name: Test package-manager
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
- develop
|
||||
- "*"
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Show Docker version
|
||||
run: docker version
|
||||
|
||||
- name: Run tests via make (builds Docker image and runs unit + integration tests)
|
||||
run: make test
|
||||
35
Dockerfile
35
Dockerfile
@@ -1,31 +1,40 @@
|
||||
FROM python:3.11-slim
|
||||
FROM archlinux:latest
|
||||
|
||||
# Install system dependencies (make, pip) as per README
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
# Update system and install core tooling
|
||||
RUN pacman -Syu --noconfirm \
|
||||
&& pacman -S --noconfirm --needed \
|
||||
git \
|
||||
make \
|
||||
python3-pip \
|
||||
python3-venv \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
sudo \
|
||||
python \
|
||||
python-pip \
|
||||
python-virtualenv \
|
||||
python-setuptools \
|
||||
python-wheel \
|
||||
&& pacman -Scc --noconfirm
|
||||
|
||||
# Ensure local bin is in PATH (for aliases) as per README
|
||||
# Ensure local bin is in PATH (for pkgmgr links)
|
||||
ENV PATH="/root/.local/bin:$PATH"
|
||||
|
||||
# Create and activate a virtual environment
|
||||
# Create virtual environment
|
||||
ENV VIRTUAL_ENV=/root/.venvs/pkgmgr
|
||||
RUN python3 -m venv $VIRTUAL_ENV
|
||||
RUN python -m venv $VIRTUAL_ENV
|
||||
ENV PATH="$VIRTUAL_ENV/bin:$PATH"
|
||||
|
||||
# Copy local package-manager source into the image
|
||||
# Working directory for the package-manager project
|
||||
WORKDIR /root/Repositories/github.com/kevinveenbirkenbach/package-manager
|
||||
|
||||
# Copy local package-manager source into container
|
||||
COPY . .
|
||||
|
||||
# Install Python dependencies and set up the tool non-interactively
|
||||
# Install Python dependencies and register pkgmgr inside the venv
|
||||
RUN pip install --upgrade pip \
|
||||
&& pip install PyYAML \
|
||||
&& chmod +x main.py \
|
||||
&& python main.py install package-manager --quiet --clone-mode https
|
||||
&& python main.py install package-manager --quiet --clone-mode shallow --no-verification
|
||||
|
||||
# Copy again to allow rebuild-based code changes
|
||||
COPY . .
|
||||
|
||||
# Default entrypoint for pkgmgr
|
||||
ENTRYPOINT ["pkgmgr"]
|
||||
CMD ["--help"]
|
||||
|
||||
4
Makefile
4
Makefile
@@ -3,6 +3,10 @@
|
||||
setup: install
|
||||
@python3 main.py install
|
||||
|
||||
test:
|
||||
docker build -t package-manager-test .
|
||||
docker run --rm --entrypoint python package-manager-test -m unittest discover -s tests -p "test_*.py"
|
||||
|
||||
install:
|
||||
@echo "Making 'main.py' executable..."
|
||||
@chmod +x main.py
|
||||
|
||||
47
main.py
47
main.py
@@ -112,10 +112,29 @@ For detailed help on each command, use:
|
||||
|
||||
def add_install_update_arguments(subparser):
|
||||
add_identifier_arguments(subparser)
|
||||
subparser.add_argument("-q", "--quiet", action="store_true", help="Suppress warnings and info messages")
|
||||
subparser.add_argument("--no-verification", action="store_true", default=False, help="Disable verification via commit/gpg")
|
||||
subparser.add_argument("--dependencies", action="store_true", help="Also pull and update dependencies")
|
||||
subparser.add_argument("--clone-mode", choices=["ssh", "https"], default="ssh", help="Specify the clone mode (default: ssh)")
|
||||
subparser.add_argument(
|
||||
"-q",
|
||||
"--quiet",
|
||||
action="store_true",
|
||||
help="Suppress warnings and info messages",
|
||||
)
|
||||
subparser.add_argument(
|
||||
"--no-verification",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="Disable verification via commit/gpg",
|
||||
)
|
||||
subparser.add_argument(
|
||||
"--dependencies",
|
||||
action="store_true",
|
||||
help="Also pull and update dependencies",
|
||||
)
|
||||
subparser.add_argument(
|
||||
"--clone-mode",
|
||||
choices=["ssh", "https", "shallow"],
|
||||
default="ssh",
|
||||
help="Specify the clone mode: ssh, https, or shallow (HTTPS shallow clone; default: ssh)",
|
||||
)
|
||||
|
||||
install_parser = subparsers.add_parser("install", help="Setup repository/repositories alias links to executables")
|
||||
add_install_update_arguments(install_parser)
|
||||
@@ -213,10 +232,20 @@ For detailed help on each command, use:
|
||||
description=f"Executes '{command} {subcommand}' for the identified repos.\nTo recieve more help execute '{command} {subcommand} --help'",
|
||||
formatter_class=argparse.RawTextHelpFormatter
|
||||
)
|
||||
if subcommand in ["pull","clone"]:
|
||||
proxy_command_parsers[f"{command}_{subcommand}"].add_argument("--no-verification", action="store_true", default=False, help="Disable verification via commit/gpg")
|
||||
if subcommand in ["pull", "clone"]:
|
||||
proxy_command_parsers[f"{command}_{subcommand}"].add_argument(
|
||||
"--no-verification",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="Disable verification via commit/gpg",
|
||||
)
|
||||
if subcommand == "clone":
|
||||
proxy_command_parsers[f"{command}_{subcommand}"].add_argument("--clone-mode", choices=["ssh", "https"], default="ssh", help="Specify the clone mode (default: ssh)")
|
||||
proxy_command_parsers[f"{command}_{subcommand}"].add_argument(
|
||||
"--clone-mode",
|
||||
choices=["ssh", "https", "shallow"],
|
||||
default="ssh",
|
||||
help="Specify the clone mode: ssh, https, or shallow (HTTPS shallow clone; default: ssh)",
|
||||
)
|
||||
add_identifier_arguments(proxy_command_parsers[f"{command}_{subcommand}"])
|
||||
|
||||
args = parser.parse_args()
|
||||
@@ -331,7 +360,7 @@ For detailed help on each command, use:
|
||||
status_repos(selected,REPOSITORIES_BASE_DIR, ALL_REPOSITORIES, args.extra_args, list_only=args.list, system_status=args.system, preview=args.preview)
|
||||
elif args.command == "explore":
|
||||
for repository in selected:
|
||||
run_command(f"nautilus {repository["directory"]} & disown")
|
||||
run_command(f"nautilus {repository['directory']} & disown")
|
||||
elif args.command == "code":
|
||||
if not selected:
|
||||
print("No repositories selected.")
|
||||
@@ -371,7 +400,7 @@ For detailed help on each command, use:
|
||||
# Join the provided shell command parts into one string.
|
||||
command_to_run = " ".join(args.shell_command)
|
||||
for repository in selected:
|
||||
print(f"Executing in '{repository["directory"]}': {command_to_run}")
|
||||
print(f"Executing in '{repository['directory']}': {command_to_run}")
|
||||
run_command(command_to_run, cwd=repository["directory"], preview=args.preview)
|
||||
elif args.command == "config":
|
||||
if args.subcommand == "show":
|
||||
|
||||
@@ -22,25 +22,48 @@ def clone_repos(
|
||||
parent_dir = os.path.dirname(repo_dir)
|
||||
os.makedirs(parent_dir, exist_ok=True)
|
||||
# Build clone URL based on the clone_mode
|
||||
# Build clone URL based on the clone_mode
|
||||
if clone_mode == "ssh":
|
||||
clone_url = f"git@{repo.get('provider')}:{repo.get('account')}/{repo.get('repository')}.git"
|
||||
elif clone_mode == "https":
|
||||
clone_url = (
|
||||
f"git@{repo.get('provider')}:"
|
||||
f"{repo.get('account')}/"
|
||||
f"{repo.get('repository')}.git"
|
||||
)
|
||||
elif clone_mode in ("https", "shallow"):
|
||||
# Use replacement if defined, otherwise construct from provider/account/repository
|
||||
if repo.get("replacement"):
|
||||
clone_url = f"https://{repo.get('replacement')}.git"
|
||||
else:
|
||||
clone_url = f"https://{repo.get('provider')}/{repo.get('account')}/{repo.get('repository')}.git"
|
||||
clone_url = (
|
||||
f"https://{repo.get('provider')}/"
|
||||
f"{repo.get('account')}/"
|
||||
f"{repo.get('repository')}.git"
|
||||
)
|
||||
else:
|
||||
print(f"Unknown clone mode '{clone_mode}'. Aborting clone for {repo_identifier}.")
|
||||
continue
|
||||
|
||||
print(f"[INFO] Attempting to clone '{repo_identifier}' using {clone_mode.upper()} from {clone_url} into '{repo_dir}'.")
|
||||
# Build base clone command
|
||||
base_clone_cmd = "git clone"
|
||||
if clone_mode == "shallow":
|
||||
# Shallow clone: only latest state via HTTPS, no full history
|
||||
base_clone_cmd += " --depth 1 --single-branch"
|
||||
|
||||
mode_label = "HTTPS (shallow)" if clone_mode == "shallow" else clone_mode.upper()
|
||||
print(
|
||||
f"[INFO] Attempting to clone '{repo_identifier}' using {mode_label} "
|
||||
f"from {clone_url} into '{repo_dir}'."
|
||||
)
|
||||
|
||||
if preview:
|
||||
print(f"[Preview] Would run: git clone {clone_url} {repo_dir} in {parent_dir}")
|
||||
print(f"[Preview] Would run: {base_clone_cmd} {clone_url} {repo_dir} in {parent_dir}")
|
||||
result = subprocess.CompletedProcess(args=[], returncode=0)
|
||||
else:
|
||||
result = subprocess.run(f"git clone {clone_url} {repo_dir}", cwd=parent_dir, shell=True)
|
||||
result = subprocess.run(
|
||||
f"{base_clone_cmd} {clone_url} {repo_dir}",
|
||||
cwd=parent_dir,
|
||||
shell=True,
|
||||
)
|
||||
|
||||
if result.returncode != 0:
|
||||
# Only offer fallback if the original mode was SSH.
|
||||
|
||||
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