2021-03-24 14:36:23 +01:00
|
|
|
"""Test Supervisor API."""
|
2021-11-17 09:28:46 +01:00
|
|
|
# pylint: disable=protected-access
|
2022-10-13 17:40:11 +02:00
|
|
|
from unittest.mock import MagicMock, patch
|
2022-05-23 09:16:42 +02:00
|
|
|
|
|
|
|
from aiohttp.test_utils import TestClient
|
2021-03-24 14:36:23 +01:00
|
|
|
import pytest
|
|
|
|
|
|
|
|
from supervisor.coresys import CoreSys
|
2022-05-23 09:16:42 +02:00
|
|
|
from supervisor.exceptions import StoreGitError, StoreNotFound
|
|
|
|
from supervisor.store.repository import Repository
|
|
|
|
|
2023-03-21 07:30:31 +01:00
|
|
|
from tests.dbus_service_mocks.base import DBusServiceMock
|
|
|
|
from tests.dbus_service_mocks.os_agent import OSAgent as OSAgentService
|
|
|
|
|
2022-05-23 09:16:42 +02:00
|
|
|
REPO_URL = "https://github.com/awesome-developer/awesome-repo"
|
2021-03-24 14:36:23 +01:00
|
|
|
|
|
|
|
|
2022-05-23 09:16:42 +02:00
|
|
|
async def test_api_supervisor_options_debug(api_client: TestClient, coresys: CoreSys):
|
2021-05-10 14:27:50 +02:00
|
|
|
"""Test security options force security."""
|
|
|
|
assert not coresys.config.debug
|
2021-03-24 14:36:23 +01:00
|
|
|
|
2021-05-10 14:27:50 +02:00
|
|
|
await api_client.post("/supervisor/options", json={"debug": True})
|
2021-03-24 14:36:23 +01:00
|
|
|
|
2021-05-10 14:27:50 +02:00
|
|
|
assert coresys.config.debug
|
2022-05-23 09:16:42 +02:00
|
|
|
|
|
|
|
|
|
|
|
async def test_api_supervisor_options_add_repository(
|
|
|
|
api_client: TestClient, coresys: CoreSys
|
|
|
|
):
|
|
|
|
"""Test add a repository via POST /supervisor/options REST API."""
|
2022-06-07 10:02:21 +02:00
|
|
|
assert REPO_URL not in coresys.store.repository_urls
|
2022-05-23 09:16:42 +02:00
|
|
|
with pytest.raises(StoreNotFound):
|
|
|
|
coresys.store.get_from_url(REPO_URL)
|
|
|
|
|
|
|
|
with patch("supervisor.store.repository.Repository.load", return_value=None), patch(
|
|
|
|
"supervisor.store.repository.Repository.validate", return_value=True
|
|
|
|
):
|
|
|
|
response = await api_client.post(
|
|
|
|
"/supervisor/options", json={"addons_repositories": [REPO_URL]}
|
|
|
|
)
|
|
|
|
|
|
|
|
assert response.status == 200
|
2022-06-07 10:02:21 +02:00
|
|
|
assert REPO_URL in coresys.store.repository_urls
|
2022-05-23 09:16:42 +02:00
|
|
|
assert isinstance(coresys.store.get_from_url(REPO_URL), Repository)
|
|
|
|
|
|
|
|
|
|
|
|
async def test_api_supervisor_options_remove_repository(
|
|
|
|
api_client: TestClient, coresys: CoreSys, repository: Repository
|
|
|
|
):
|
|
|
|
"""Test remove a repository via POST /supervisor/options REST API."""
|
2022-06-07 17:55:53 +02:00
|
|
|
assert repository.source in coresys.store.repository_urls
|
2022-05-23 09:16:42 +02:00
|
|
|
assert repository.slug in coresys.store.repositories
|
|
|
|
|
|
|
|
response = await api_client.post(
|
|
|
|
"/supervisor/options", json={"addons_repositories": []}
|
|
|
|
)
|
|
|
|
|
|
|
|
assert response.status == 200
|
2022-06-07 17:55:53 +02:00
|
|
|
assert repository.source not in coresys.store.repository_urls
|
2022-05-23 09:16:42 +02:00
|
|
|
assert repository.slug not in coresys.store.repositories
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize("git_error", [None, StoreGitError()])
|
|
|
|
async def test_api_supervisor_options_repositories_skipped_on_error(
|
|
|
|
api_client: TestClient, coresys: CoreSys, git_error: StoreGitError
|
|
|
|
):
|
|
|
|
"""Test repositories skipped on error via POST /supervisor/options REST API."""
|
|
|
|
with patch(
|
|
|
|
"supervisor.store.repository.Repository.load", side_effect=git_error
|
2022-06-07 10:02:21 +02:00
|
|
|
), patch(
|
|
|
|
"supervisor.store.repository.Repository.validate", return_value=False
|
|
|
|
), patch(
|
|
|
|
"supervisor.store.repository.Repository.remove"
|
|
|
|
):
|
2022-05-23 09:16:42 +02:00
|
|
|
response = await api_client.post(
|
|
|
|
"/supervisor/options", json={"addons_repositories": [REPO_URL]}
|
|
|
|
)
|
|
|
|
|
|
|
|
assert response.status == 400
|
|
|
|
assert len(coresys.resolution.suggestions) == 0
|
2022-06-07 10:02:21 +02:00
|
|
|
assert REPO_URL not in coresys.store.repository_urls
|
2022-05-23 09:16:42 +02:00
|
|
|
with pytest.raises(StoreNotFound):
|
|
|
|
coresys.store.get_from_url(REPO_URL)
|
|
|
|
|
|
|
|
|
|
|
|
async def test_api_supervisor_options_repo_error_with_config_change(
|
|
|
|
api_client: TestClient, coresys: CoreSys
|
|
|
|
):
|
|
|
|
"""Test config change with add repository error via POST /supervisor/options REST API."""
|
|
|
|
assert not coresys.config.debug
|
|
|
|
|
|
|
|
with patch(
|
|
|
|
"supervisor.store.repository.Repository.load", side_effect=StoreGitError()
|
|
|
|
):
|
|
|
|
response = await api_client.post(
|
|
|
|
"/supervisor/options",
|
|
|
|
json={"debug": True, "addons_repositories": [REPO_URL]},
|
|
|
|
)
|
|
|
|
|
|
|
|
assert response.status == 400
|
2022-06-07 10:02:21 +02:00
|
|
|
assert REPO_URL not in coresys.store.repository_urls
|
2022-05-23 09:16:42 +02:00
|
|
|
|
|
|
|
assert coresys.config.debug
|
|
|
|
coresys.updater.save_data.assert_called_once()
|
|
|
|
coresys.config.save_data.assert_called_once()
|
2022-08-15 18:13:22 +02:00
|
|
|
|
|
|
|
|
|
|
|
async def test_api_supervisor_options_auto_update(
|
|
|
|
api_client: TestClient, coresys: CoreSys
|
|
|
|
):
|
|
|
|
"""Test disabling auto update via api."""
|
|
|
|
assert coresys.updater.auto_update is True
|
|
|
|
|
|
|
|
response = await api_client.post("/supervisor/options", json={"auto_update": False})
|
|
|
|
|
|
|
|
assert response.status == 200
|
|
|
|
|
|
|
|
assert coresys.updater.auto_update is False
|
2022-09-29 18:13:02 +02:00
|
|
|
|
|
|
|
|
|
|
|
async def test_api_supervisor_options_diagnostics(
|
2023-03-21 07:30:31 +01:00
|
|
|
api_client: TestClient,
|
|
|
|
coresys: CoreSys,
|
|
|
|
os_agent_services: dict[str, DBusServiceMock | dict[str, DBusServiceMock]],
|
2022-09-29 18:13:02 +02:00
|
|
|
):
|
|
|
|
"""Test changing diagnostics."""
|
2023-03-21 07:30:31 +01:00
|
|
|
os_agent_service: OSAgentService = os_agent_services["os_agent"]
|
|
|
|
os_agent_service.Diagnostics = False
|
|
|
|
await os_agent_service.ping()
|
|
|
|
assert coresys.dbus.agent.diagnostics is False
|
2022-09-29 18:13:02 +02:00
|
|
|
|
2022-11-13 21:23:52 +01:00
|
|
|
with patch("supervisor.utils.sentry.sentry_sdk.init") as sentry_init:
|
|
|
|
response = await api_client.post(
|
|
|
|
"/supervisor/options", json={"diagnostics": True}
|
|
|
|
)
|
|
|
|
assert response.status == 200
|
|
|
|
sentry_init.assert_called_once()
|
|
|
|
|
2023-03-21 07:30:31 +01:00
|
|
|
await os_agent_service.ping()
|
|
|
|
assert coresys.dbus.agent.diagnostics is True
|
2022-09-29 18:13:02 +02:00
|
|
|
|
2022-11-13 21:23:52 +01:00
|
|
|
with patch("supervisor.api.supervisor.close_sentry") as close_sentry:
|
|
|
|
response = await api_client.post(
|
|
|
|
"/supervisor/options", json={"diagnostics": False}
|
|
|
|
)
|
|
|
|
assert response.status == 200
|
|
|
|
close_sentry.assert_called_once()
|
|
|
|
|
2023-03-21 07:30:31 +01:00
|
|
|
await os_agent_service.ping()
|
|
|
|
assert coresys.dbus.agent.diagnostics is False
|
2022-10-13 17:40:11 +02:00
|
|
|
|
|
|
|
|
|
|
|
async def test_api_supervisor_logs(api_client: TestClient, docker_logs: MagicMock):
|
|
|
|
"""Test supervisor logs."""
|
|
|
|
resp = await api_client.get("/supervisor/logs")
|
|
|
|
assert resp.status == 200
|
|
|
|
assert resp.content_type == "application/octet-stream"
|
|
|
|
content = await resp.text()
|
|
|
|
assert content.split("\n")[0:2] == [
|
|
|
|
"\x1b[36m22-10-11 14:04:23 DEBUG (MainThread) [supervisor.utils.dbus] D-Bus call - org.freedesktop.DBus.Properties.call_get_all on /io/hass/os\x1b[0m",
|
|
|
|
"\x1b[36m22-10-11 14:04:23 DEBUG (MainThread) [supervisor.utils.dbus] D-Bus call - org.freedesktop.DBus.Properties.call_get_all on /io/hass/os/AppArmor\x1b[0m",
|
|
|
|
]
|