Files
supervisor/tests/docker/test_manifest.py
2025-12-07 00:39:58 +01:00

144 lines
4.6 KiB
Python

"""Tests for registry manifest fetcher."""
from unittest.mock import AsyncMock, MagicMock, patch
from supervisor.coresys import CoreSys
from supervisor.docker.manifest import (
DOCKER_HUB,
ImageManifest,
RegistryManifestFetcher,
parse_image_reference,
)
def test_parse_image_reference_ghcr_io():
"""Test parsing ghcr.io image."""
registry, repo, tag = parse_image_reference(
"ghcr.io/home-assistant/home-assistant", "2025.1.0"
)
assert registry == "ghcr.io"
assert repo == "home-assistant/home-assistant"
assert tag == "2025.1.0"
def test_parse_image_reference_docker_hub_with_org():
"""Test parsing Docker Hub image with organization."""
registry, repo, tag = parse_image_reference(
"homeassistant/home-assistant", "latest"
)
assert registry == DOCKER_HUB
assert repo == "homeassistant/home-assistant"
assert tag == "latest"
def test_parse_image_reference_docker_hub_official_image():
"""Test parsing Docker Hub official image (no org)."""
registry, repo, tag = parse_image_reference("alpine", "3.18")
assert registry == DOCKER_HUB
assert repo == "library/alpine"
assert tag == "3.18"
def test_parse_image_reference_gcr_io():
"""Test parsing gcr.io image."""
registry, repo, tag = parse_image_reference("gcr.io/project/image", "v1")
assert registry == "gcr.io"
assert repo == "project/image"
assert tag == "v1"
def test_image_manifest_layer_count():
"""Test ImageManifest layer_count property."""
manifest = ImageManifest(
digest="sha256:abc",
total_size=1000,
layers={"layer1": 500, "layer2": 500},
)
assert manifest.layer_count == 2
async def test_get_manifest_success(coresys: CoreSys, websession: MagicMock):
"""Test successful manifest fetch by mocking internal methods."""
fetcher = RegistryManifestFetcher(coresys)
manifest_data = {
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"config": {"digest": "sha256:abc123"},
"layers": [
{"digest": "sha256:layer1abc123def456789012", "size": 1000},
{"digest": "sha256:layer2def456abc789012345", "size": 2000},
],
}
# Mock the internal methods
with (
patch.object(
fetcher, "_get_auth_token", new=AsyncMock(return_value="test-token")
),
patch.object(
fetcher, "_fetch_manifest", new=AsyncMock(return_value=manifest_data)
),
):
result = await fetcher.get_manifest(
"test.io/org/image", "v1.0", platform="linux/amd64"
)
assert result is not None
assert result.total_size == 3000
assert result.layer_count == 2
# First 12 chars after sha256:
assert "layer1abc123" in result.layers
assert result.layers["layer1abc123"] == 1000
async def test_get_manifest_returns_none_on_failure(
coresys: CoreSys, websession: MagicMock
):
"""Test that get_manifest returns None on failure."""
fetcher = RegistryManifestFetcher(coresys)
with (
patch.object(
fetcher, "_get_auth_token", new=AsyncMock(return_value="test-token")
),
patch.object(fetcher, "_fetch_manifest", new=AsyncMock(return_value=None)),
):
result = await fetcher.get_manifest(
"test.io/org/image", "v1.0", platform="linux/amd64"
)
assert result is None
def test_get_credentials_docker_hub(coresys: CoreSys, websession: MagicMock):
"""Test getting Docker Hub credentials."""
coresys.docker.config._data["registries"] = { # pylint: disable=protected-access
"docker.io": {"username": "user", "password": "pass"}
}
fetcher = RegistryManifestFetcher(coresys)
creds = fetcher._get_credentials(DOCKER_HUB) # pylint: disable=protected-access
assert creds == ("user", "pass")
def test_get_credentials_custom_registry(coresys: CoreSys, websession: MagicMock):
"""Test getting credentials for custom registry."""
coresys.docker.config._data["registries"] = { # pylint: disable=protected-access
"ghcr.io": {"username": "user", "password": "token"}
}
fetcher = RegistryManifestFetcher(coresys)
creds = fetcher._get_credentials("ghcr.io") # pylint: disable=protected-access
assert creds == ("user", "token")
def test_get_credentials_not_found(coresys: CoreSys, websession: MagicMock):
"""Test no credentials found."""
coresys.docker.config._data["registries"] = {} # pylint: disable=protected-access
fetcher = RegistryManifestFetcher(coresys)
creds = fetcher._get_credentials("unknown.io") # pylint: disable=protected-access
assert creds is None