mirror of
https://github.com/basnijholt/compose-farm.git
synced 2026-02-12 09:52:06 +00:00
112 lines
3.6 KiB
Python
112 lines
3.6 KiB
Python
"""Tests for operations module."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import inspect
|
|
from pathlib import Path
|
|
from unittest.mock import patch
|
|
|
|
import pytest
|
|
|
|
from compose_farm.cli import lifecycle
|
|
from compose_farm.config import Config, Host
|
|
from compose_farm.executor import CommandResult
|
|
from compose_farm.operations import _migrate_stack
|
|
|
|
|
|
@pytest.fixture
|
|
def basic_config(tmp_path: Path) -> Config:
|
|
"""Create a basic test config."""
|
|
compose_dir = tmp_path / "compose"
|
|
stack_dir = compose_dir / "test-service"
|
|
stack_dir.mkdir(parents=True)
|
|
(stack_dir / "docker-compose.yml").write_text("services: {}")
|
|
return Config(
|
|
compose_dir=compose_dir,
|
|
hosts={
|
|
"host1": Host(address="localhost"),
|
|
"host2": Host(address="localhost"),
|
|
},
|
|
stacks={"test-service": "host2"},
|
|
)
|
|
|
|
|
|
class TestMigrationCommands:
|
|
"""Tests for migration command sequence."""
|
|
|
|
@pytest.fixture
|
|
def config(self, tmp_path: Path) -> Config:
|
|
"""Create a test config."""
|
|
compose_dir = tmp_path / "compose"
|
|
stack_dir = compose_dir / "test-service"
|
|
stack_dir.mkdir(parents=True)
|
|
(stack_dir / "docker-compose.yml").write_text("services: {}")
|
|
return Config(
|
|
compose_dir=compose_dir,
|
|
hosts={
|
|
"host1": Host(address="localhost"),
|
|
"host2": Host(address="localhost"),
|
|
},
|
|
stacks={"test-service": "host2"},
|
|
)
|
|
|
|
async def test_migration_uses_pull_ignore_buildable(self, config: Config) -> None:
|
|
"""Migration should use 'pull --ignore-buildable' to skip buildable images."""
|
|
commands_called: list[str] = []
|
|
|
|
async def mock_run_compose_step(
|
|
cfg: Config,
|
|
stack: str,
|
|
command: str,
|
|
*,
|
|
raw: bool,
|
|
host: str | None = None,
|
|
) -> CommandResult:
|
|
commands_called.append(command)
|
|
return CommandResult(
|
|
stack=stack,
|
|
exit_code=0,
|
|
success=True,
|
|
)
|
|
|
|
with patch(
|
|
"compose_farm.operations._run_compose_step",
|
|
side_effect=mock_run_compose_step,
|
|
):
|
|
await _migrate_stack(
|
|
config,
|
|
"test-service",
|
|
current_host="host1",
|
|
target_host="host2",
|
|
prefix="[test]",
|
|
raw=False,
|
|
)
|
|
|
|
# Migration should call pull with --ignore-buildable, then build, then down
|
|
assert "pull --ignore-buildable" in commands_called
|
|
assert "build" in commands_called
|
|
assert "down" in commands_called
|
|
# pull should come before build
|
|
pull_idx = commands_called.index("pull --ignore-buildable")
|
|
build_idx = commands_called.index("build")
|
|
assert pull_idx < build_idx
|
|
|
|
|
|
class TestUpdateCommandSequence:
|
|
"""Tests for update command sequence."""
|
|
|
|
def test_update_command_sequence_includes_build(self) -> None:
|
|
"""Update command should use pull --ignore-buildable and build."""
|
|
# This is a static check of the command sequence in lifecycle.py
|
|
# The actual command sequence is defined in the update function
|
|
|
|
source = inspect.getsource(lifecycle.update)
|
|
|
|
# Verify the command sequence includes pull --ignore-buildable
|
|
assert "pull --ignore-buildable" in source
|
|
# Verify build is included
|
|
assert '"build"' in source or "'build'" in source
|
|
# Verify the sequence is pull, build, down, up
|
|
assert "down" in source
|
|
assert "up -d" in source
|