Move backup/* WS commands to the backup integration (#110651)
* Move backup/* WS commands to the backup integration * Call correct command * Use debug for logging * Remove assertion of hass.data for setup test * parametrize token fixturepull/106311/head^2
parent
52621f9609
commit
ec4e6c3a74
|
@ -115,6 +115,7 @@ DEFAULT_INTEGRATIONS = {
|
|||
#
|
||||
# Integrations providing core functionality:
|
||||
"application_credentials",
|
||||
"backup",
|
||||
"frontend",
|
||||
"hardware",
|
||||
"logger",
|
||||
|
@ -148,10 +149,6 @@ DEFAULT_INTEGRATIONS_SUPERVISOR = {
|
|||
# These integrations are set up if using the Supervisor
|
||||
"hassio",
|
||||
}
|
||||
DEFAULT_INTEGRATIONS_NON_SUPERVISOR = {
|
||||
# These integrations are set up if not using the Supervisor
|
||||
"backup",
|
||||
}
|
||||
CRITICAL_INTEGRATIONS = {
|
||||
# Recovery mode is activated if these integrations fail to set up
|
||||
"frontend",
|
||||
|
@ -541,8 +538,6 @@ def _get_domains(hass: core.HomeAssistant, config: dict[str, Any]) -> set[str]:
|
|||
# Add domains depending on if the Supervisor is used or not
|
||||
if "SUPERVISOR" in os.environ:
|
||||
domains.update(DEFAULT_INTEGRATIONS_SUPERVISOR)
|
||||
else:
|
||||
domains.update(DEFAULT_INTEGRATIONS_NON_SUPERVISOR)
|
||||
|
||||
return domains
|
||||
|
||||
|
|
|
@ -14,23 +14,27 @@ CONFIG_SCHEMA = cv.empty_config_schema(DOMAIN)
|
|||
|
||||
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||
"""Set up the Backup integration."""
|
||||
if is_hassio(hass):
|
||||
LOGGER.error(
|
||||
"The backup integration is not supported on this installation method, "
|
||||
"please remove it from your configuration"
|
||||
)
|
||||
return False
|
||||
|
||||
backup_manager = BackupManager(hass)
|
||||
hass.data[DOMAIN] = backup_manager
|
||||
|
||||
with_hassio = is_hassio(hass)
|
||||
|
||||
async_register_websocket_handlers(hass, with_hassio)
|
||||
|
||||
if with_hassio:
|
||||
if DOMAIN in config:
|
||||
LOGGER.error(
|
||||
"The backup integration is not supported on this installation method, "
|
||||
"please remove it from your configuration"
|
||||
)
|
||||
return True
|
||||
|
||||
async def async_handle_create_service(call: ServiceCall) -> None:
|
||||
"""Service handler for creating backups."""
|
||||
await backup_manager.generate_backup()
|
||||
|
||||
hass.services.async_register(DOMAIN, "create", async_handle_create_service)
|
||||
|
||||
async_register_websocket_handlers(hass)
|
||||
async_register_http_views(hass)
|
||||
|
||||
return True
|
||||
|
|
|
@ -6,13 +6,18 @@ import voluptuous as vol
|
|||
from homeassistant.components import websocket_api
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
|
||||
from .const import DOMAIN
|
||||
from .const import DOMAIN, LOGGER
|
||||
from .manager import BackupManager
|
||||
|
||||
|
||||
@callback
|
||||
def async_register_websocket_handlers(hass: HomeAssistant) -> None:
|
||||
def async_register_websocket_handlers(hass: HomeAssistant, with_hassio: bool) -> None:
|
||||
"""Register websocket commands."""
|
||||
if with_hassio:
|
||||
websocket_api.async_register_command(hass, handle_backup_end)
|
||||
websocket_api.async_register_command(hass, handle_backup_start)
|
||||
return
|
||||
|
||||
websocket_api.async_register_command(hass, handle_info)
|
||||
websocket_api.async_register_command(hass, handle_create)
|
||||
websocket_api.async_register_command(hass, handle_remove)
|
||||
|
@ -69,3 +74,47 @@ async def handle_create(
|
|||
manager: BackupManager = hass.data[DOMAIN]
|
||||
backup = await manager.generate_backup()
|
||||
connection.send_result(msg["id"], backup)
|
||||
|
||||
|
||||
@websocket_api.ws_require_user(only_supervisor=True)
|
||||
@websocket_api.websocket_command({vol.Required("type"): "backup/start"})
|
||||
@websocket_api.async_response
|
||||
async def handle_backup_start(
|
||||
hass: HomeAssistant,
|
||||
connection: websocket_api.ActiveConnection,
|
||||
msg: dict[str, Any],
|
||||
) -> None:
|
||||
"""Backup start notification."""
|
||||
manager: BackupManager = hass.data[DOMAIN]
|
||||
manager.backing_up = True
|
||||
LOGGER.debug("Backup start notification")
|
||||
|
||||
try:
|
||||
await manager.pre_backup_actions()
|
||||
except Exception as err: # pylint: disable=broad-except
|
||||
connection.send_error(msg["id"], "pre_backup_actions_failed", str(err))
|
||||
return
|
||||
|
||||
connection.send_result(msg["id"])
|
||||
|
||||
|
||||
@websocket_api.ws_require_user(only_supervisor=True)
|
||||
@websocket_api.websocket_command({vol.Required("type"): "backup/end"})
|
||||
@websocket_api.async_response
|
||||
async def handle_backup_end(
|
||||
hass: HomeAssistant,
|
||||
connection: websocket_api.ActiveConnection,
|
||||
msg: dict[str, Any],
|
||||
) -> None:
|
||||
"""Backup end notification."""
|
||||
manager: BackupManager = hass.data[DOMAIN]
|
||||
manager.backing_up = False
|
||||
LOGGER.debug("Backup end notification")
|
||||
|
||||
try:
|
||||
await manager.post_backup_actions()
|
||||
except Exception as err: # pylint: disable=broad-except
|
||||
connection.send_error(msg["id"], "post_backup_actions_failed", str(err))
|
||||
return
|
||||
|
||||
connection.send_result(msg["id"])
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime as dt
|
||||
import logging
|
||||
from typing import Any, Literal, cast
|
||||
|
||||
import voluptuous as vol
|
||||
|
@ -46,8 +45,6 @@ from .statistics import (
|
|||
)
|
||||
from .util import PERIOD_SCHEMA, get_instance, resolve_period
|
||||
|
||||
_LOGGER: logging.Logger = logging.getLogger(__package__)
|
||||
|
||||
UNIT_SCHEMA = vol.Schema(
|
||||
{
|
||||
vol.Optional("data_rate"): vol.In(DataRateConverter.VALID_UNITS),
|
||||
|
@ -73,8 +70,6 @@ UNIT_SCHEMA = vol.Schema(
|
|||
def async_setup(hass: HomeAssistant) -> None:
|
||||
"""Set up the recorder websocket API."""
|
||||
websocket_api.async_register_command(hass, ws_adjust_sum_statistics)
|
||||
websocket_api.async_register_command(hass, ws_backup_end)
|
||||
websocket_api.async_register_command(hass, ws_backup_start)
|
||||
websocket_api.async_register_command(hass, ws_change_statistics_unit)
|
||||
websocket_api.async_register_command(hass, ws_clear_statistics)
|
||||
websocket_api.async_register_command(hass, ws_get_statistic_during_period)
|
||||
|
@ -517,38 +512,3 @@ def ws_info(
|
|||
"thread_running": is_running,
|
||||
}
|
||||
connection.send_result(msg["id"], recorder_info)
|
||||
|
||||
|
||||
@websocket_api.ws_require_user(only_supervisor=True)
|
||||
@websocket_api.websocket_command({vol.Required("type"): "backup/start"})
|
||||
@websocket_api.async_response
|
||||
async def ws_backup_start(
|
||||
hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict[str, Any]
|
||||
) -> None:
|
||||
"""Backup start notification."""
|
||||
|
||||
_LOGGER.info("Backup start notification, locking database for writes")
|
||||
instance = get_instance(hass)
|
||||
try:
|
||||
await instance.lock_database()
|
||||
except TimeoutError as err:
|
||||
connection.send_error(msg["id"], "timeout_error", str(err))
|
||||
return
|
||||
connection.send_result(msg["id"])
|
||||
|
||||
|
||||
@websocket_api.ws_require_user(only_supervisor=True)
|
||||
@websocket_api.websocket_command({vol.Required("type"): "backup/end"})
|
||||
@websocket_api.async_response
|
||||
async def ws_backup_end(
|
||||
hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict[str, Any]
|
||||
) -> None:
|
||||
"""Backup end notification."""
|
||||
|
||||
instance = get_instance(hass)
|
||||
_LOGGER.info("Backup end notification, releasing write lock")
|
||||
if not instance.unlock_database():
|
||||
connection.send_error(
|
||||
msg["id"], "database_unlock_failed", "Failed to unlock database."
|
||||
)
|
||||
connection.send_result(msg["id"])
|
||||
|
|
|
@ -0,0 +1,223 @@
|
|||
# serializer version: 1
|
||||
# name: test_backup_end[with_hassio-hass_access_token]
|
||||
dict({
|
||||
'error': dict({
|
||||
'code': 'only_supervisor',
|
||||
'message': 'Only allowed as Supervisor',
|
||||
}),
|
||||
'id': 1,
|
||||
'success': False,
|
||||
'type': 'result',
|
||||
})
|
||||
# ---
|
||||
# name: test_backup_end[with_hassio-hass_supervisor_access_token]
|
||||
dict({
|
||||
'id': 1,
|
||||
'result': None,
|
||||
'success': True,
|
||||
'type': 'result',
|
||||
})
|
||||
# ---
|
||||
# name: test_backup_end[without_hassio-hass_access_token]
|
||||
dict({
|
||||
'error': dict({
|
||||
'code': 'unknown_command',
|
||||
'message': 'Unknown command.',
|
||||
}),
|
||||
'id': 1,
|
||||
'success': False,
|
||||
'type': 'result',
|
||||
})
|
||||
# ---
|
||||
# name: test_backup_end[without_hassio-hass_supervisor_access_token]
|
||||
dict({
|
||||
'error': dict({
|
||||
'code': 'unknown_command',
|
||||
'message': 'Unknown command.',
|
||||
}),
|
||||
'id': 1,
|
||||
'success': False,
|
||||
'type': 'result',
|
||||
})
|
||||
# ---
|
||||
# name: test_backup_end_excepion[exception0]
|
||||
dict({
|
||||
'error': dict({
|
||||
'code': 'post_backup_actions_failed',
|
||||
'message': '',
|
||||
}),
|
||||
'id': 1,
|
||||
'success': False,
|
||||
'type': 'result',
|
||||
})
|
||||
# ---
|
||||
# name: test_backup_end_excepion[exception1]
|
||||
dict({
|
||||
'error': dict({
|
||||
'code': 'post_backup_actions_failed',
|
||||
'message': 'Boom',
|
||||
}),
|
||||
'id': 1,
|
||||
'success': False,
|
||||
'type': 'result',
|
||||
})
|
||||
# ---
|
||||
# name: test_backup_end_excepion[exception2]
|
||||
dict({
|
||||
'error': dict({
|
||||
'code': 'post_backup_actions_failed',
|
||||
'message': 'Boom',
|
||||
}),
|
||||
'id': 1,
|
||||
'success': False,
|
||||
'type': 'result',
|
||||
})
|
||||
# ---
|
||||
# name: test_backup_start[with_hassio-hass_access_token]
|
||||
dict({
|
||||
'error': dict({
|
||||
'code': 'only_supervisor',
|
||||
'message': 'Only allowed as Supervisor',
|
||||
}),
|
||||
'id': 1,
|
||||
'success': False,
|
||||
'type': 'result',
|
||||
})
|
||||
# ---
|
||||
# name: test_backup_start[with_hassio-hass_supervisor_access_token]
|
||||
dict({
|
||||
'id': 1,
|
||||
'result': None,
|
||||
'success': True,
|
||||
'type': 'result',
|
||||
})
|
||||
# ---
|
||||
# name: test_backup_start[without_hassio-hass_access_token]
|
||||
dict({
|
||||
'error': dict({
|
||||
'code': 'unknown_command',
|
||||
'message': 'Unknown command.',
|
||||
}),
|
||||
'id': 1,
|
||||
'success': False,
|
||||
'type': 'result',
|
||||
})
|
||||
# ---
|
||||
# name: test_backup_start[without_hassio-hass_supervisor_access_token]
|
||||
dict({
|
||||
'error': dict({
|
||||
'code': 'unknown_command',
|
||||
'message': 'Unknown command.',
|
||||
}),
|
||||
'id': 1,
|
||||
'success': False,
|
||||
'type': 'result',
|
||||
})
|
||||
# ---
|
||||
# name: test_backup_start_excepion[exception0]
|
||||
dict({
|
||||
'error': dict({
|
||||
'code': 'pre_backup_actions_failed',
|
||||
'message': '',
|
||||
}),
|
||||
'id': 1,
|
||||
'success': False,
|
||||
'type': 'result',
|
||||
})
|
||||
# ---
|
||||
# name: test_backup_start_excepion[exception1]
|
||||
dict({
|
||||
'error': dict({
|
||||
'code': 'pre_backup_actions_failed',
|
||||
'message': 'Boom',
|
||||
}),
|
||||
'id': 1,
|
||||
'success': False,
|
||||
'type': 'result',
|
||||
})
|
||||
# ---
|
||||
# name: test_backup_start_excepion[exception2]
|
||||
dict({
|
||||
'error': dict({
|
||||
'code': 'pre_backup_actions_failed',
|
||||
'message': 'Boom',
|
||||
}),
|
||||
'id': 1,
|
||||
'success': False,
|
||||
'type': 'result',
|
||||
})
|
||||
# ---
|
||||
# name: test_generate[with_hassio]
|
||||
dict({
|
||||
'error': dict({
|
||||
'code': 'unknown_command',
|
||||
'message': 'Unknown command.',
|
||||
}),
|
||||
'id': 1,
|
||||
'success': False,
|
||||
'type': 'result',
|
||||
})
|
||||
# ---
|
||||
# name: test_generate[without_hassio]
|
||||
dict({
|
||||
'id': 1,
|
||||
'result': dict({
|
||||
'date': '1970-01-01T00:00:00.000Z',
|
||||
'name': 'Test',
|
||||
'path': 'abc123.tar',
|
||||
'size': 0.0,
|
||||
'slug': 'abc123',
|
||||
}),
|
||||
'success': True,
|
||||
'type': 'result',
|
||||
})
|
||||
# ---
|
||||
# name: test_info[with_hassio]
|
||||
dict({
|
||||
'error': dict({
|
||||
'code': 'unknown_command',
|
||||
'message': 'Unknown command.',
|
||||
}),
|
||||
'id': 1,
|
||||
'success': False,
|
||||
'type': 'result',
|
||||
})
|
||||
# ---
|
||||
# name: test_info[without_hassio]
|
||||
dict({
|
||||
'id': 1,
|
||||
'result': dict({
|
||||
'backing_up': False,
|
||||
'backups': list([
|
||||
dict({
|
||||
'date': '1970-01-01T00:00:00.000Z',
|
||||
'name': 'Test',
|
||||
'path': 'abc123.tar',
|
||||
'size': 0.0,
|
||||
'slug': 'abc123',
|
||||
}),
|
||||
]),
|
||||
}),
|
||||
'success': True,
|
||||
'type': 'result',
|
||||
})
|
||||
# ---
|
||||
# name: test_remove[with_hassio]
|
||||
dict({
|
||||
'error': dict({
|
||||
'code': 'unknown_command',
|
||||
'message': 'Unknown command.',
|
||||
}),
|
||||
'id': 1,
|
||||
'success': False,
|
||||
'type': 'result',
|
||||
})
|
||||
# ---
|
||||
# name: test_remove[without_hassio]
|
||||
dict({
|
||||
'id': 1,
|
||||
'result': None,
|
||||
'success': True,
|
||||
'type': 'result',
|
||||
})
|
||||
# ---
|
|
@ -14,7 +14,11 @@ async def test_setup_with_hassio(
|
|||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""Test the setup of the integration with hassio enabled."""
|
||||
assert not await setup_backup_integration(hass=hass, with_hassio=True)
|
||||
assert await setup_backup_integration(
|
||||
hass=hass,
|
||||
with_hassio=True,
|
||||
configuration={DOMAIN: {}},
|
||||
)
|
||||
assert (
|
||||
"The backup integration is not supported on this installation method, please"
|
||||
" remove it from your configuration"
|
||||
|
|
|
@ -2,20 +2,43 @@
|
|||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
from syrupy import SnapshotAssertion
|
||||
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
|
||||
from .common import TEST_BACKUP, setup_backup_integration
|
||||
|
||||
from tests.typing import WebSocketGenerator
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def sync_access_token_proxy(
|
||||
access_token_fixture_name: str,
|
||||
request: pytest.FixtureRequest,
|
||||
) -> str:
|
||||
"""Non-async proxy for the *_access_token fixture.
|
||||
|
||||
Workaround for https://github.com/pytest-dev/pytest-asyncio/issues/112
|
||||
"""
|
||||
return request.getfixturevalue(access_token_fixture_name)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"with_hassio",
|
||||
(
|
||||
pytest.param(True, id="with_hassio"),
|
||||
pytest.param(False, id="without_hassio"),
|
||||
),
|
||||
)
|
||||
async def test_info(
|
||||
hass: HomeAssistant,
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
snapshot: SnapshotAssertion,
|
||||
with_hassio: bool,
|
||||
) -> None:
|
||||
"""Test getting backup info."""
|
||||
await setup_backup_integration(hass)
|
||||
await setup_backup_integration(hass, with_hassio=with_hassio)
|
||||
|
||||
client = await hass_ws_client(hass)
|
||||
await hass.async_block_till_done()
|
||||
|
@ -24,21 +47,25 @@ async def test_info(
|
|||
"homeassistant.components.backup.websocket.BackupManager.get_backups",
|
||||
return_value={TEST_BACKUP.slug: TEST_BACKUP},
|
||||
):
|
||||
await client.send_json({"id": 1, "type": "backup/info"})
|
||||
msg = await client.receive_json()
|
||||
|
||||
assert msg["id"] == 1
|
||||
assert msg["success"]
|
||||
assert msg["result"] == {"backing_up": False, "backups": [TEST_BACKUP.as_dict()]}
|
||||
await client.send_json_auto_id({"type": "backup/info"})
|
||||
assert snapshot == await client.receive_json()
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"with_hassio",
|
||||
(
|
||||
pytest.param(True, id="with_hassio"),
|
||||
pytest.param(False, id="without_hassio"),
|
||||
),
|
||||
)
|
||||
async def test_remove(
|
||||
hass: HomeAssistant,
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
snapshot: SnapshotAssertion,
|
||||
with_hassio: bool,
|
||||
) -> None:
|
||||
"""Test removing a backup file."""
|
||||
await setup_backup_integration(hass)
|
||||
await setup_backup_integration(hass, with_hassio=with_hassio)
|
||||
|
||||
client = await hass_ws_client(hass)
|
||||
await hass.async_block_till_done()
|
||||
|
@ -46,19 +73,25 @@ async def test_remove(
|
|||
with patch(
|
||||
"homeassistant.components.backup.websocket.BackupManager.remove_backup",
|
||||
):
|
||||
await client.send_json({"id": 1, "type": "backup/remove", "slug": "abc123"})
|
||||
msg = await client.receive_json()
|
||||
|
||||
assert msg["id"] == 1
|
||||
assert msg["success"]
|
||||
await client.send_json_auto_id({"type": "backup/remove", "slug": "abc123"})
|
||||
assert snapshot == await client.receive_json()
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"with_hassio",
|
||||
(
|
||||
pytest.param(True, id="with_hassio"),
|
||||
pytest.param(False, id="without_hassio"),
|
||||
),
|
||||
)
|
||||
async def test_generate(
|
||||
hass: HomeAssistant,
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
snapshot: SnapshotAssertion,
|
||||
with_hassio: bool,
|
||||
) -> None:
|
||||
"""Test removing a backup file."""
|
||||
await setup_backup_integration(hass)
|
||||
"""Test generating a backup."""
|
||||
await setup_backup_integration(hass, with_hassio=with_hassio)
|
||||
|
||||
client = await hass_ws_client(hass)
|
||||
await hass.async_block_till_done()
|
||||
|
@ -67,9 +100,130 @@ async def test_generate(
|
|||
"homeassistant.components.backup.websocket.BackupManager.generate_backup",
|
||||
return_value=TEST_BACKUP,
|
||||
):
|
||||
await client.send_json({"id": 1, "type": "backup/generate"})
|
||||
msg = await client.receive_json()
|
||||
await client.send_json_auto_id({"type": "backup/generate"})
|
||||
assert snapshot == await client.receive_json()
|
||||
|
||||
assert msg["id"] == 1
|
||||
assert msg["success"]
|
||||
assert msg["result"] == TEST_BACKUP.as_dict()
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"access_token_fixture_name",
|
||||
["hass_access_token", "hass_supervisor_access_token"],
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
("with_hassio"),
|
||||
(
|
||||
pytest.param(True, id="with_hassio"),
|
||||
pytest.param(False, id="without_hassio"),
|
||||
),
|
||||
)
|
||||
async def test_backup_end(
|
||||
hass: HomeAssistant,
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
snapshot: SnapshotAssertion,
|
||||
request: pytest.FixtureRequest,
|
||||
sync_access_token_proxy: str,
|
||||
*,
|
||||
access_token_fixture_name: str,
|
||||
with_hassio: bool,
|
||||
) -> None:
|
||||
"""Test handling of post backup actions from a WS command."""
|
||||
await setup_backup_integration(hass, with_hassio=with_hassio)
|
||||
|
||||
client = await hass_ws_client(hass, sync_access_token_proxy)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.backup.websocket.BackupManager.post_backup_actions",
|
||||
):
|
||||
await client.send_json_auto_id({"type": "backup/end"})
|
||||
assert snapshot == await client.receive_json()
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"access_token_fixture_name",
|
||||
["hass_access_token", "hass_supervisor_access_token"],
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
("with_hassio"),
|
||||
(
|
||||
pytest.param(True, id="with_hassio"),
|
||||
pytest.param(False, id="without_hassio"),
|
||||
),
|
||||
)
|
||||
async def test_backup_start(
|
||||
hass: HomeAssistant,
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
snapshot: SnapshotAssertion,
|
||||
sync_access_token_proxy: str,
|
||||
*,
|
||||
access_token_fixture_name: str,
|
||||
with_hassio: bool,
|
||||
) -> None:
|
||||
"""Test handling of pre backup actions from a WS command."""
|
||||
await setup_backup_integration(hass, with_hassio=with_hassio)
|
||||
|
||||
client = await hass_ws_client(hass, sync_access_token_proxy)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.backup.websocket.BackupManager.pre_backup_actions",
|
||||
):
|
||||
await client.send_json_auto_id({"type": "backup/start"})
|
||||
assert snapshot == await client.receive_json()
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"exception",
|
||||
(
|
||||
TimeoutError(),
|
||||
HomeAssistantError("Boom"),
|
||||
Exception("Boom"),
|
||||
),
|
||||
)
|
||||
async def test_backup_end_excepion(
|
||||
hass: HomeAssistant,
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
snapshot: SnapshotAssertion,
|
||||
hass_supervisor_access_token: str,
|
||||
exception: Exception,
|
||||
) -> None:
|
||||
"""Test exception handling while running post backup actions from a WS command."""
|
||||
await setup_backup_integration(hass, with_hassio=True)
|
||||
|
||||
client = await hass_ws_client(hass, hass_supervisor_access_token)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.backup.websocket.BackupManager.post_backup_actions",
|
||||
side_effect=exception,
|
||||
):
|
||||
await client.send_json_auto_id({"type": "backup/end"})
|
||||
assert snapshot == await client.receive_json()
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"exception",
|
||||
(
|
||||
TimeoutError(),
|
||||
HomeAssistantError("Boom"),
|
||||
Exception("Boom"),
|
||||
),
|
||||
)
|
||||
async def test_backup_start_excepion(
|
||||
hass: HomeAssistant,
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
snapshot: SnapshotAssertion,
|
||||
hass_supervisor_access_token: str,
|
||||
exception: Exception,
|
||||
) -> None:
|
||||
"""Test exception handling while running pre backup actions from a WS command."""
|
||||
await setup_backup_integration(hass, with_hassio=True)
|
||||
|
||||
client = await hass_ws_client(hass, hass_supervisor_access_token)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.backup.websocket.BackupManager.pre_backup_actions",
|
||||
side_effect=exception,
|
||||
):
|
||||
await client.send_json_auto_id({"type": "backup/start"})
|
||||
assert snapshot == await client.receive_json()
|
||||
|
|
|
@ -2227,77 +2227,6 @@ async def test_backup_start_no_recorder(
|
|||
assert response["error"]["code"] == "unknown_command"
|
||||
|
||||
|
||||
async def test_backup_start_timeout(
|
||||
recorder_mock: Recorder,
|
||||
hass: HomeAssistant,
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
hass_supervisor_access_token: str,
|
||||
recorder_db_url: str,
|
||||
) -> None:
|
||||
"""Test getting backup start when recorder is not present."""
|
||||
if recorder_db_url.startswith(("mysql://", "postgresql://")):
|
||||
# This test is specific for SQLite: Locking is not implemented for other engines
|
||||
return
|
||||
|
||||
client = await hass_ws_client(hass, hass_supervisor_access_token)
|
||||
|
||||
# Ensure there are no queued events
|
||||
await async_wait_recording_done(hass)
|
||||
|
||||
with patch.object(recorder.core, "DB_LOCK_TIMEOUT", 0):
|
||||
try:
|
||||
await client.send_json_auto_id({"type": "backup/start"})
|
||||
response = await client.receive_json()
|
||||
assert not response["success"]
|
||||
assert response["error"]["code"] == "timeout_error"
|
||||
finally:
|
||||
await client.send_json_auto_id({"type": "backup/end"})
|
||||
|
||||
|
||||
async def test_backup_end(
|
||||
recorder_mock: Recorder,
|
||||
hass: HomeAssistant,
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
hass_supervisor_access_token: str,
|
||||
) -> None:
|
||||
"""Test backup start."""
|
||||
client = await hass_ws_client(hass, hass_supervisor_access_token)
|
||||
|
||||
# Ensure there are no queued events
|
||||
await async_wait_recording_done(hass)
|
||||
|
||||
await client.send_json_auto_id({"type": "backup/start"})
|
||||
response = await client.receive_json()
|
||||
assert response["success"]
|
||||
|
||||
await client.send_json_auto_id({"type": "backup/end"})
|
||||
response = await client.receive_json()
|
||||
assert response["success"]
|
||||
|
||||
|
||||
async def test_backup_end_without_start(
|
||||
recorder_mock: Recorder,
|
||||
hass: HomeAssistant,
|
||||
hass_ws_client: WebSocketGenerator,
|
||||
hass_supervisor_access_token: str,
|
||||
recorder_db_url: str,
|
||||
) -> None:
|
||||
"""Test backup start."""
|
||||
if recorder_db_url.startswith(("mysql://", "postgresql://")):
|
||||
# This test is specific for SQLite: Locking is not implemented for other engines
|
||||
return
|
||||
|
||||
client = await hass_ws_client(hass, hass_supervisor_access_token)
|
||||
|
||||
# Ensure there are no queued events
|
||||
await async_wait_recording_done(hass)
|
||||
|
||||
await client.send_json_auto_id({"type": "backup/end"})
|
||||
response = await client.receive_json()
|
||||
assert not response["success"]
|
||||
assert response["error"]["code"] == "database_unlock_failed"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("units", "attributes", "unit", "unit_class"),
|
||||
[
|
||||
|
|
|
@ -95,15 +95,6 @@ async def test_load_hassio(hass: HomeAssistant) -> None:
|
|||
assert "hassio" in bootstrap._get_domains(hass, {})
|
||||
|
||||
|
||||
async def test_load_backup(hass: HomeAssistant) -> None:
|
||||
"""Test that we load the backup integration when not using Supervisor."""
|
||||
with patch.dict(os.environ, {}, clear=True):
|
||||
assert "backup" in bootstrap._get_domains(hass, {})
|
||||
|
||||
with patch.dict(os.environ, {"SUPERVISOR": "1"}):
|
||||
assert "backup" not in bootstrap._get_domains(hass, {})
|
||||
|
||||
|
||||
@pytest.mark.parametrize("load_registries", [False])
|
||||
async def test_empty_setup(hass: HomeAssistant) -> None:
|
||||
"""Test an empty set up loads the core."""
|
||||
|
|
Loading…
Reference in New Issue