fix: reuse cached config profile git mounts
- Reuse valid deterministic git mount clones on repeated starts - Remove incomplete clone destinations before retrying - Add regression coverage for cached and partial clones - Document OpenSpec change fix-config-profile-git-mount-clone-reuse Quality gates: pytest (13 passed), ruff, mypy
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
"""Unit tests for the tool instance service."""
|
||||
|
||||
import hashlib
|
||||
import uuid
|
||||
from unittest.mock import MagicMock, AsyncMock
|
||||
|
||||
@@ -8,6 +9,7 @@ import pytest
|
||||
from src.services.tool.instance_service import (
|
||||
_get_repository_mount_name,
|
||||
_stack_profile_mounts_with_git_mounts,
|
||||
clone_git_repo,
|
||||
modify_compose_file,
|
||||
prepare_manifest_instance,
|
||||
)
|
||||
@@ -67,6 +69,61 @@ class TestGetRepositoryMountName:
|
||||
assert _get_repository_mount_name(project, repo) == "project-v2-0"
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
class TestCloneGitRepo:
|
||||
"""Regression tests for reusable config-profile git mount clones."""
|
||||
|
||||
def test_reuses_existing_clone(self, monkeypatch, tmp_path) -> None:
|
||||
from src.services.tool import instance_service
|
||||
|
||||
remote_url = "https://gitlab.com/example/dotfiles"
|
||||
branch = None
|
||||
clone_parent = str(tmp_path)
|
||||
url_hash = hashlib.md5(f"{remote_url}:default".encode()).hexdigest()[:12]
|
||||
repo_path = (
|
||||
tmp_path
|
||||
/ "git-mounts"
|
||||
/ f"dotfiles-{url_hash}"
|
||||
/ "repo-clone"
|
||||
)
|
||||
(repo_path / ".git").mkdir(parents=True)
|
||||
|
||||
clone = MagicMock(side_effect=AssertionError("existing clone must be reused"))
|
||||
pull = MagicMock()
|
||||
monkeypatch.setattr(instance_service, "clone_repository", clone)
|
||||
monkeypatch.setattr(instance_service, "pull_repository_updates", pull)
|
||||
|
||||
result = clone_git_repo(remote_url, branch, clone_parent)
|
||||
|
||||
assert result == str(repo_path)
|
||||
clone.assert_not_called()
|
||||
pull.assert_called_once_with(str(repo_path), remote_url)
|
||||
|
||||
def test_replaces_incomplete_clone_before_retry(self, monkeypatch, tmp_path) -> None:
|
||||
from src.services.tool import instance_service
|
||||
|
||||
remote_url = "https://gitlab.com/example/dotfiles"
|
||||
url_hash = hashlib.md5(f"{remote_url}:main".encode()).hexdigest()[:12]
|
||||
clone_dir = tmp_path / "git-mounts" / f"dotfiles-{url_hash}"
|
||||
repo_path = clone_dir / "repo-clone"
|
||||
repo_path.mkdir(parents=True)
|
||||
(repo_path / "partial-file").write_text("incomplete")
|
||||
|
||||
def clone(_url, _key, destination, _branch, project_name=None):
|
||||
assert destination == str(clone_dir)
|
||||
assert project_name is None
|
||||
assert not repo_path.exists()
|
||||
(repo_path / ".git").mkdir(parents=True)
|
||||
return str(repo_path)
|
||||
|
||||
monkeypatch.setattr(instance_service, "clone_repository", clone)
|
||||
|
||||
result = clone_git_repo(remote_url, "main", str(tmp_path))
|
||||
|
||||
assert result == str(repo_path)
|
||||
assert (repo_path / ".git").is_dir()
|
||||
|
||||
|
||||
@pytest.mark.unit
|
||||
class TestStackProfileMountsWithGitMounts:
|
||||
"""Tests for _stack_profile_mounts_with_git_mounts."""
|
||||
|
||||
Reference in New Issue
Block a user