mirror of
https://github.com/home-assistant/supervisor.git
synced 2026-05-19 22:28:52 +01:00
eb3c388618
* Migrate persisted 'addon' field to 'app' in discovery and services config
Rename the 'addon' key to 'app' in persisted configuration files for
discovery messages (discovery.json), service modules (services.json),
and supervisor config (supervisor.json), as part of the broader
addon->app terminology migration.
Changes:
- Add ATTR_ADDON = "addon" to const.py for V1 API compat/migration
- Add ATTR_ADDONS_CUSTOM_LIST = "addons_custom_list" to const.py for migration
- Change ATTR_APPS_CUSTOM_LIST value from "addons_custom_list" to "apps_custom_list"
- Add _migrate_supervisor_config() schema pre-processor in validate.py to
transparently load old supervisor.json files using the old key
- Add ATTR_ADDON to services/const.py; change ATTR_APP value to "app"
- Add _migrate_addon_to_app() pre-processors to MQTT, MySQL, and discovery
schemas to load old config files that used the "addon" key
- Rename Message.addon -> Message.app in Discovery and update all references
- Keep hassio_push/discovery payload using "addon" key for HA compatibility
- GET /services/{service} and GET /discovery: V1 returns "addon" key,
V2 returns "app" key, via dedicated _v1 handler methods following the
backups/store pattern, registered with AppVersion guards in
_register_services() and _register_discovery()
- Broaden FileConfiguration schema type annotation to accept vol.All
validators in addition to vol.Schema
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Add schema migration tests for addon->app config key rename
Test that backwards-compatible migration of old 'addon'/'addons_custom_list'
keys to 'app'/'apps_custom_list' works correctly in all affected schemas,
and that the new keys are accepted without modification.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Add an __init__ to discovery tests
* Add app_api_client_with_prefix fixture and update V1/V2 tests
Move the app-level V1/V2 fixture to tests/api/conftest.py as
app_api_client_with_prefix for use across any endpoint that requires
app-level credentials (services_role, app.discovery, etc.).
- Add app_api_client_with_prefix fixture to conftest.py
- Update test_set_service_already_provided and test_del_service_not_provided
to use app_api_client_with_prefix (covers both v1 and v2)
- Add test_get_service_v1_v2_keys asserting addon/app key per version
- Update test_api_discovery_forbidden, test_api_send_del_discovery,
test_api_invalid_discovery to use app_api_client_with_prefix
- Split test_discovery_not_found into test_discovery_not_found_get
(uses api_client_with_prefix, GET requires homeassistant) and
test_discovery_not_found_delete (uses app_api_client_with_prefix)
- Add test_get_discovery_v1_v2_keys asserting addon/app key per version
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
152 lines
4.5 KiB
Python
152 lines
4.5 KiB
Python
"""Test validators."""
|
|
|
|
import pytest
|
|
import voluptuous as vol
|
|
|
|
from supervisor import validate
|
|
from supervisor.validate import SCHEMA_SUPERVISOR_CONFIG
|
|
|
|
DNS_GOOD_V4 = [
|
|
"dns://10.0.0.1", # random local
|
|
"dns://254.254.254.254", # random high numbers
|
|
"DNS://1.1.1.1", # cloudflare
|
|
"dns://9.9.9.9", # quad-9
|
|
]
|
|
DNS_GOOD_V6 = [
|
|
"dns://2606:4700:4700::1111", # cloudflare
|
|
"DNS://2606:4700:4700::1001", # cloudflare
|
|
]
|
|
DNS_BAD = ["hello world", "https://foo.bar", "", "dns://example.com"]
|
|
IMAGE_NAME_GOOD = [
|
|
"ghcr.io/home-assistant/{machine}-homeassistant",
|
|
"ghcr.io/home-assistant/{arch}-homeassistant",
|
|
"homeassistant/{arch}-homeassistant",
|
|
"doocker.io/homeassistant/{arch}-homeassistant",
|
|
"ghcr.io/home-assistant/amd64-homeassistant",
|
|
"homeassistant/amd64-homeassistant",
|
|
"ttl.sh/homeassistant",
|
|
"myreg.local:8080/homeassistant",
|
|
"localhost/myimage",
|
|
"localhost:5000/myimage",
|
|
"127.0.0.1/myimage",
|
|
"127.0.0.1:5000/org/myimage",
|
|
"[::1]:5000/myimage",
|
|
"dockeruser/nice-app-1.2",
|
|
"ghcr.io/blakeblackshear/frigate",
|
|
]
|
|
IMAGE_NAME_BAD = [
|
|
"ghcr.io/home-assistant/homeassistant:123",
|
|
"ghcr.io/blakeblackshear/frigate:stable-rocm",
|
|
".ghcr.io/home-assistant/homeassistant",
|
|
"HOMEASSISTANT/homeassistant",
|
|
"homeassistant/HOMEASSISTANT",
|
|
"homeassistant/_homeassistant",
|
|
"homeassistant/-homeassistant",
|
|
"GHCR.IO/home-assistant/homeassistant",
|
|
]
|
|
|
|
|
|
def test_dns_url_v4_good():
|
|
"""Test the DNS validator with known-good IPv4 DNS URLs."""
|
|
for url in DNS_GOOD_V4:
|
|
assert validate.dns_url(url)
|
|
|
|
|
|
def test_dns_url_v6_good():
|
|
"""Test the DNS validator with known-good IPv6 DNS URLs."""
|
|
with pytest.raises(vol.error.Invalid):
|
|
for url in DNS_GOOD_V6:
|
|
assert validate.dns_url(url)
|
|
|
|
|
|
def test_dns_server_list_v4():
|
|
"""Test a list with v4 addresses."""
|
|
assert validate.dns_server_list(DNS_GOOD_V4)
|
|
|
|
|
|
def test_dns_server_list_v6():
|
|
"""Test a list with v6 addresses."""
|
|
with pytest.raises(vol.error.Invalid):
|
|
assert validate.dns_server_list(DNS_GOOD_V6)
|
|
|
|
|
|
def test_dns_server_list_combined():
|
|
"""Test a list with both v4 and v6 addresses."""
|
|
combined = DNS_GOOD_V4 + DNS_GOOD_V6
|
|
# test the matches
|
|
with pytest.raises(vol.error.Invalid):
|
|
validate.dns_server_list(combined)
|
|
# test max_length is OK still
|
|
with pytest.raises(vol.error.Invalid):
|
|
validate.dns_server_list(combined)
|
|
# test that it fails when the list is too long
|
|
with pytest.raises(vol.error.Invalid):
|
|
validate.dns_server_list(combined + combined + combined + combined)
|
|
|
|
|
|
def test_dns_server_list_bad():
|
|
"""Test the bad list."""
|
|
# test the matches
|
|
with pytest.raises(vol.error.Invalid):
|
|
assert validate.dns_server_list(DNS_BAD)
|
|
|
|
|
|
def test_dns_server_list_bad_combined():
|
|
"""Test the bad list, combined with the good."""
|
|
combined = DNS_GOOD_V4 + DNS_GOOD_V6 + DNS_BAD
|
|
|
|
with pytest.raises(vol.error.Invalid):
|
|
# bad list
|
|
assert validate.dns_server_list(combined)
|
|
|
|
|
|
def test_image_name_good():
|
|
"""Test container image names validator with known-good image names."""
|
|
for image_name in IMAGE_NAME_GOOD:
|
|
assert validate.docker_image(image_name)
|
|
|
|
|
|
def test_image_name_bad():
|
|
"""Test container image names validator with known-bad image names."""
|
|
for image_name in IMAGE_NAME_BAD:
|
|
with pytest.raises(vol.error.Invalid):
|
|
assert validate.docker_image(image_name)
|
|
|
|
|
|
def test_version_complex():
|
|
"""Test version simple with good version."""
|
|
for version in (
|
|
"landingpage",
|
|
"dev",
|
|
"1c002dd",
|
|
"1.1.1",
|
|
"1.0",
|
|
"0.150.1",
|
|
"0.150.1b1",
|
|
"0.150.1.dev20200715",
|
|
"1",
|
|
"alpine-5.4",
|
|
1,
|
|
1.1,
|
|
):
|
|
assert validate.version_tag(version) == str(version)
|
|
|
|
assert validate.version_tag(None) is None
|
|
|
|
|
|
def test_supervisor_config_migration_addons_custom_list():
|
|
"""Test that old 'addons_custom_list' key is migrated to 'apps_custom_list'."""
|
|
result = SCHEMA_SUPERVISOR_CONFIG(
|
|
{"addons_custom_list": ["https://example.com/repo"]}
|
|
)
|
|
assert result["apps_custom_list"] == ["https://example.com/repo"]
|
|
assert "addons_custom_list" not in result
|
|
|
|
|
|
def test_supervisor_config_apps_custom_list_unchanged():
|
|
"""Test that new 'apps_custom_list' key passes through unchanged."""
|
|
result = SCHEMA_SUPERVISOR_CONFIG(
|
|
{"apps_custom_list": ["https://example.com/repo"]}
|
|
)
|
|
assert result["apps_custom_list"] == ["https://example.com/repo"]
|