mirror of
https://github.com/home-assistant/supervisor.git
synced 2025-12-11 04:12:26 -06:00
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
144 lines
4.6 KiB
Python
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
|