Rename snapshot -> backup (#53851)

pull/49395/head
Joakim Sørensen 2021-08-02 11:07:21 +02:00 committed by GitHub
parent 38832618bf
commit da3419945c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 181 additions and 82 deletions

View File

@ -89,6 +89,8 @@ SERVICE_HOST_SHUTDOWN = "host_shutdown"
SERVICE_HOST_REBOOT = "host_reboot" SERVICE_HOST_REBOOT = "host_reboot"
SERVICE_SNAPSHOT_FULL = "snapshot_full" SERVICE_SNAPSHOT_FULL = "snapshot_full"
SERVICE_SNAPSHOT_PARTIAL = "snapshot_partial" SERVICE_SNAPSHOT_PARTIAL = "snapshot_partial"
SERVICE_BACKUP_FULL = "backup_full"
SERVICE_BACKUP_PARTIAL = "backup_partial"
SERVICE_RESTORE_FULL = "restore_full" SERVICE_RESTORE_FULL = "restore_full"
SERVICE_RESTORE_PARTIAL = "restore_partial" SERVICE_RESTORE_PARTIAL = "restore_partial"
@ -101,11 +103,11 @@ SCHEMA_ADDON_STDIN = SCHEMA_ADDON.extend(
{vol.Required(ATTR_INPUT): vol.Any(dict, cv.string)} {vol.Required(ATTR_INPUT): vol.Any(dict, cv.string)}
) )
SCHEMA_SNAPSHOT_FULL = vol.Schema( SCHEMA_BACKUP_FULL = vol.Schema(
{vol.Optional(ATTR_NAME): cv.string, vol.Optional(ATTR_PASSWORD): cv.string} {vol.Optional(ATTR_NAME): cv.string, vol.Optional(ATTR_PASSWORD): cv.string}
) )
SCHEMA_SNAPSHOT_PARTIAL = SCHEMA_SNAPSHOT_FULL.extend( SCHEMA_BACKUP_PARTIAL = SCHEMA_BACKUP_FULL.extend(
{ {
vol.Optional(ATTR_FOLDERS): vol.All(cv.ensure_list, [cv.string]), vol.Optional(ATTR_FOLDERS): vol.All(cv.ensure_list, [cv.string]),
vol.Optional(ATTR_ADDONS): vol.All(cv.ensure_list, [cv.string]), vol.Optional(ATTR_ADDONS): vol.All(cv.ensure_list, [cv.string]),
@ -113,7 +115,12 @@ SCHEMA_SNAPSHOT_PARTIAL = SCHEMA_SNAPSHOT_FULL.extend(
) )
SCHEMA_RESTORE_FULL = vol.Schema( SCHEMA_RESTORE_FULL = vol.Schema(
{vol.Required(ATTR_SNAPSHOT): cv.slug, vol.Optional(ATTR_PASSWORD): cv.string} {
vol.Exclusive(ATTR_SLUG, ATTR_SLUG): cv.slug,
vol.Exclusive(ATTR_SNAPSHOT, ATTR_SLUG): cv.slug,
vol.Optional(ATTR_PASSWORD): cv.string,
},
cv.has_at_least_one_key(ATTR_SLUG, ATTR_SNAPSHOT),
) )
SCHEMA_RESTORE_PARTIAL = SCHEMA_RESTORE_FULL.extend( SCHEMA_RESTORE_PARTIAL = SCHEMA_RESTORE_FULL.extend(
@ -133,25 +140,32 @@ MAP_SERVICE_API = {
SERVICE_ADDON_STDIN: ("/addons/{addon}/stdin", SCHEMA_ADDON_STDIN, 60, False), SERVICE_ADDON_STDIN: ("/addons/{addon}/stdin", SCHEMA_ADDON_STDIN, 60, False),
SERVICE_HOST_SHUTDOWN: ("/host/shutdown", SCHEMA_NO_DATA, 60, False), SERVICE_HOST_SHUTDOWN: ("/host/shutdown", SCHEMA_NO_DATA, 60, False),
SERVICE_HOST_REBOOT: ("/host/reboot", SCHEMA_NO_DATA, 60, False), SERVICE_HOST_REBOOT: ("/host/reboot", SCHEMA_NO_DATA, 60, False),
SERVICE_SNAPSHOT_FULL: ("/snapshots/new/full", SCHEMA_SNAPSHOT_FULL, 300, True), SERVICE_BACKUP_FULL: ("/backups/new/full", SCHEMA_BACKUP_FULL, 300, True),
SERVICE_SNAPSHOT_PARTIAL: ( SERVICE_BACKUP_PARTIAL: (
"/snapshots/new/partial", "/backups/new/partial",
SCHEMA_SNAPSHOT_PARTIAL, SCHEMA_BACKUP_PARTIAL,
300, 300,
True, True,
), ),
SERVICE_RESTORE_FULL: ( SERVICE_RESTORE_FULL: (
"/snapshots/{snapshot}/restore/full", "/backups/{slug}/restore/full",
SCHEMA_RESTORE_FULL, SCHEMA_RESTORE_FULL,
300, 300,
True, True,
), ),
SERVICE_RESTORE_PARTIAL: ( SERVICE_RESTORE_PARTIAL: (
"/snapshots/{snapshot}/restore/partial", "/backups/{slug}/restore/partial",
SCHEMA_RESTORE_PARTIAL, SCHEMA_RESTORE_PARTIAL,
300, 300,
True, True,
), ),
SERVICE_SNAPSHOT_FULL: ("/backups/new/full", SCHEMA_BACKUP_FULL, 300, True),
SERVICE_SNAPSHOT_PARTIAL: (
"/backups/new/partial",
SCHEMA_BACKUP_PARTIAL,
300,
True,
),
} }
@ -272,16 +286,16 @@ async def async_get_addon_discovery_info(hass: HomeAssistant, slug: str) -> dict
@bind_hass @bind_hass
@api_data @api_data
async def async_create_snapshot( async def async_create_backup(
hass: HomeAssistant, payload: dict, partial: bool = False hass: HomeAssistant, payload: dict, partial: bool = False
) -> dict: ) -> dict:
"""Create a full or partial snapshot. """Create a full or partial backup.
The caller of the function should handle HassioAPIError. The caller of the function should handle HassioAPIError.
""" """
hassio = hass.data[DOMAIN] hassio = hass.data[DOMAIN]
snapshot_type = "partial" if partial else "full" backup_type = "partial" if partial else "full"
command = f"/snapshots/new/{snapshot_type}" command = f"/backups/new/{backup_type}"
return await hassio.send_command(command, payload=payload, timeout=None) return await hassio.send_command(command, payload=payload, timeout=None)
@ -453,9 +467,22 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: # noqa:
async def async_service_handler(service): async def async_service_handler(service):
"""Handle service calls for Hass.io.""" """Handle service calls for Hass.io."""
api_command = MAP_SERVICE_API[service.service][0] api_command = MAP_SERVICE_API[service.service][0]
if "snapshot" in service.service:
_LOGGER.warning(
"The service '%s' is deprecated and will be removed in Home Assistant 2021.11, use '%s' instead",
service.service,
service.service.replace("snapshot", "backup"),
)
data = service.data.copy() data = service.data.copy()
addon = data.pop(ATTR_ADDON, None) addon = data.pop(ATTR_ADDON, None)
slug = data.pop(ATTR_SLUG, None)
snapshot = data.pop(ATTR_SNAPSHOT, None) snapshot = data.pop(ATTR_SNAPSHOT, None)
if snapshot is not None:
_LOGGER.warning(
"Using 'snapshot' is deprecated and will be removed in Home Assistant 2021.11, use 'slug' instead"
)
slug = snapshot
payload = None payload = None
# Pass data to Hass.io API # Pass data to Hass.io API
@ -467,12 +494,12 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: # noqa:
# Call API # Call API
try: try:
await hassio.send_command( await hassio.send_command(
api_command.format(addon=addon, snapshot=snapshot), api_command.format(addon=addon, slug=slug),
payload=payload, payload=payload,
timeout=MAP_SERVICE_API[service.service][2], timeout=MAP_SERVICE_API[service.service][2],
) )
except HassioAPIError as err: except HassioAPIError as err:
_LOGGER.error("Error on Hass.io API: %s", err) _LOGGER.error("Error on Supervisor API: %s", err)
for service, settings in MAP_SERVICE_API.items(): for service, settings in MAP_SERVICE_API.items():
hass.services.async_register( hass.services.async_register(

View File

@ -29,6 +29,9 @@ NO_TIMEOUT = re.compile(
r"|hassos/update/cli" r"|hassos/update/cli"
r"|supervisor/update" r"|supervisor/update"
r"|addons/[^/]+/(?:update|install|rebuild)" r"|addons/[^/]+/(?:update|install|rebuild)"
r"|backups/.+/full"
r"|backups/.+/partial"
r"|backups/[^/]+/(?:upload|download)"
r"|snapshots/.+/full" r"|snapshots/.+/full"
r"|snapshots/.+/partial" r"|snapshots/.+/partial"
r"|snapshots/[^/]+/(?:upload|download)" r"|snapshots/[^/]+/(?:upload|download)"
@ -36,7 +39,7 @@ NO_TIMEOUT = re.compile(
) )
NO_AUTH_ONBOARDING = re.compile( NO_AUTH_ONBOARDING = re.compile(
r"^(?:" r"|supervisor/logs" r"|snapshots/[^/]+/.+" r")$" r"^(?:" r"|supervisor/logs" r"|backups/[^/]+/.+" r"|snapshots/[^/]+/.+" r")$"
) )
NO_AUTH = re.compile( NO_AUTH = re.compile(
@ -81,13 +84,13 @@ class HassIOView(HomeAssistantView):
client_timeout = 10 client_timeout = 10
data = None data = None
headers = _init_header(request) headers = _init_header(request)
if path == "snapshots/new/upload": if path in ("snapshots/new/upload", "backups/new/upload"):
# We need to reuse the full content type that includes the boundary # We need to reuse the full content type that includes the boundary
headers[ headers[
"Content-Type" "Content-Type"
] = request._stored_content_type # pylint: disable=protected-access ] = request._stored_content_type # pylint: disable=protected-access
# Snapshots are big, so we need to adjust the allowed size # Backups are big, so we need to adjust the allowed size
request._client_max_size = ( # pylint: disable=protected-access request._client_max_size = ( # pylint: disable=protected-access
MAX_UPLOAD_SIZE MAX_UPLOAD_SIZE
) )

View File

@ -67,13 +67,13 @@ host_shutdown:
description: Poweroff the host system. description: Poweroff the host system.
snapshot_full: snapshot_full:
name: Create a full snapshot. name: Create a full backup.
description: Create a full snapshot. description: Create a full backup (deprecated, use backup_full instead).
fields: fields:
name: name:
name: Name name: Name
description: Optional or it will be the current date and time. description: Optional or it will be the current date and time.
example: "Snapshot 1" example: "backup 1"
selector: selector:
text: text:
password: password:
@ -84,8 +84,8 @@ snapshot_full:
text: text:
snapshot_partial: snapshot_partial:
name: Create a partial snapshot. name: Create a partial backup.
description: Create a partial snapshot. description: Create a partial backup (deprecated, use backup_partial instead).
fields: fields:
addons: addons:
name: Add-ons name: Add-ons
@ -102,7 +102,53 @@ snapshot_partial:
name: name:
name: Name name: Name
description: Optional or it will be the current date and time. description: Optional or it will be the current date and time.
example: "Partial Snapshot 1" example: "Partial backup 1"
selector:
text:
password:
name: Password
description: Optional password.
example: "password"
selector:
text:
backup_full:
name: Create a full backup.
description: Create a full backup.
fields:
name:
name: Name
description: Optional or it will be the current date and time.
example: "backup 1"
selector:
text:
password:
name: Password
description: Optional password.
example: "password"
selector:
text:
backup_partial:
name: Create a partial backup.
description: Create a partial backup.
fields:
addons:
name: Add-ons
description: Optional list of addon slugs.
example: ["core_ssh", "core_samba", "core_mosquitto"]
selector:
object:
folders:
name: Folders
description: Optional list of directories.
example: ["homeassistant", "share"]
selector:
object:
name:
name: Name
description: Optional or it will be the current date and time.
example: "Partial backup 1"
selector: selector:
text: text:
password: password:

View File

@ -547,7 +547,7 @@ async def async_remove_entry(hass: HomeAssistant, entry: ConfigEntry) -> None:
LOGGER.error(err) LOGGER.error(err)
return return
try: try:
await addon_manager.async_create_snapshot() await addon_manager.async_create_backup()
except AddonError as err: except AddonError as err:
LOGGER.error(err) LOGGER.error(err)
return return

View File

@ -8,7 +8,7 @@ from functools import partial
from typing import Any, Callable, TypeVar, cast from typing import Any, Callable, TypeVar, cast
from homeassistant.components.hassio import ( from homeassistant.components.hassio import (
async_create_snapshot, async_create_backup,
async_get_addon_discovery_info, async_get_addon_discovery_info,
async_get_addon_info, async_get_addon_info,
async_install_addon, async_install_addon,
@ -202,7 +202,7 @@ class AddonManager:
if not addon_info.update_available: if not addon_info.update_available:
return return
await self.async_create_snapshot() await self.async_create_backup()
await async_update_addon(self._hass, ADDON_SLUG) await async_update_addon(self._hass, ADDON_SLUG)
@callback @callback
@ -289,14 +289,14 @@ class AddonManager:
) )
return self._start_task return self._start_task
@api_error("Failed to create a snapshot of the Z-Wave JS add-on.") @api_error("Failed to create a backup of the Z-Wave JS add-on.")
async def async_create_snapshot(self) -> None: async def async_create_backup(self) -> None:
"""Create a partial snapshot of the Z-Wave JS add-on.""" """Create a partial backup of the Z-Wave JS add-on."""
addon_info = await self.async_get_addon_info() addon_info = await self.async_get_addon_info()
name = f"addon_{ADDON_SLUG}_{addon_info.version}" name = f"addon_{ADDON_SLUG}_{addon_info.version}"
LOGGER.debug("Creating snapshot: %s", name) LOGGER.debug("Creating backup: %s", name)
await async_create_snapshot( await async_create_backup(
self._hass, self._hass,
{"name": name, "addons": [ADDON_SLUG]}, {"name": name, "addons": [ADDON_SLUG]},
partial=True, partial=True,

View File

@ -132,13 +132,13 @@ async def test_forwarding_user_info(hassio_client, hass_admin_user, aioclient_mo
assert req_headers["X-Hass-Is-Admin"] == "1" assert req_headers["X-Hass-Is-Admin"] == "1"
async def test_snapshot_upload_headers(hassio_client, aioclient_mock): async def test_backup_upload_headers(hassio_client, aioclient_mock, caplog):
"""Test that we forward the full header for snapshot upload.""" """Test that we forward the full header for backup upload."""
content_type = "multipart/form-data; boundary='--webkit'" content_type = "multipart/form-data; boundary='--webkit'"
aioclient_mock.get("http://127.0.0.1/snapshots/new/upload") aioclient_mock.get("http://127.0.0.1/backups/new/upload")
resp = await hassio_client.get( resp = await hassio_client.get(
"/api/hassio/snapshots/new/upload", headers={"Content-Type": content_type} "/api/hassio/backups/new/upload", headers={"Content-Type": content_type}
) )
# Check we got right response # Check we got right response
@ -150,18 +150,18 @@ async def test_snapshot_upload_headers(hassio_client, aioclient_mock):
assert req_headers["Content-Type"] == content_type assert req_headers["Content-Type"] == content_type
async def test_snapshot_download_headers(hassio_client, aioclient_mock): async def test_backup_download_headers(hassio_client, aioclient_mock):
"""Test that we forward the full header for snapshot download.""" """Test that we forward the full header for backup download."""
content_disposition = "attachment; filename=test.tar" content_disposition = "attachment; filename=test.tar"
aioclient_mock.get( aioclient_mock.get(
"http://127.0.0.1/snapshots/slug/download", "http://127.0.0.1/backups/slug/download",
headers={ headers={
"Content-Length": "50000000", "Content-Length": "50000000",
"Content-Disposition": content_disposition, "Content-Disposition": content_disposition,
}, },
) )
resp = await hassio_client.get("/api/hassio/snapshots/slug/download") resp = await hassio_client.get("/api/hassio/backups/slug/download")
# Check we got right response # Check we got right response
assert resp.status == 200 assert resp.status == 200
@ -174,9 +174,9 @@ async def test_snapshot_download_headers(hassio_client, aioclient_mock):
def test_need_auth(hass): def test_need_auth(hass):
"""Test if the requested path needs authentication.""" """Test if the requested path needs authentication."""
assert not _need_auth(hass, "addons/test/logo") assert not _need_auth(hass, "addons/test/logo")
assert _need_auth(hass, "snapshots/new/upload") assert _need_auth(hass, "backups/new/upload")
assert _need_auth(hass, "supervisor/logs") assert _need_auth(hass, "supervisor/logs")
hass.data["onboarding"] = False hass.data["onboarding"] = False
assert not _need_auth(hass, "snapshots/new/upload") assert not _need_auth(hass, "backups/new/upload")
assert not _need_auth(hass, "supervisor/logs") assert not _need_auth(hass, "supervisor/logs")

View File

@ -303,11 +303,13 @@ async def test_service_register(hassio_env, hass):
assert hass.services.has_service("hassio", "host_reboot") assert hass.services.has_service("hassio", "host_reboot")
assert hass.services.has_service("hassio", "snapshot_full") assert hass.services.has_service("hassio", "snapshot_full")
assert hass.services.has_service("hassio", "snapshot_partial") assert hass.services.has_service("hassio", "snapshot_partial")
assert hass.services.has_service("hassio", "backup_full")
assert hass.services.has_service("hassio", "backup_partial")
assert hass.services.has_service("hassio", "restore_full") assert hass.services.has_service("hassio", "restore_full")
assert hass.services.has_service("hassio", "restore_partial") assert hass.services.has_service("hassio", "restore_partial")
async def test_service_calls(hassio_env, hass, aioclient_mock): async def test_service_calls(hassio_env, hass, aioclient_mock, caplog):
"""Call service and check the API calls behind that.""" """Call service and check the API calls behind that."""
assert await async_setup_component(hass, "hassio", {}) assert await async_setup_component(hass, "hassio", {})
@ -318,13 +320,13 @@ async def test_service_calls(hassio_env, hass, aioclient_mock):
aioclient_mock.post("http://127.0.0.1/addons/test/stdin", json={"result": "ok"}) aioclient_mock.post("http://127.0.0.1/addons/test/stdin", json={"result": "ok"})
aioclient_mock.post("http://127.0.0.1/host/shutdown", json={"result": "ok"}) aioclient_mock.post("http://127.0.0.1/host/shutdown", json={"result": "ok"})
aioclient_mock.post("http://127.0.0.1/host/reboot", json={"result": "ok"}) aioclient_mock.post("http://127.0.0.1/host/reboot", json={"result": "ok"})
aioclient_mock.post("http://127.0.0.1/snapshots/new/full", json={"result": "ok"}) aioclient_mock.post("http://127.0.0.1/backups/new/full", json={"result": "ok"})
aioclient_mock.post("http://127.0.0.1/snapshots/new/partial", json={"result": "ok"}) aioclient_mock.post("http://127.0.0.1/backups/new/partial", json={"result": "ok"})
aioclient_mock.post( aioclient_mock.post(
"http://127.0.0.1/snapshots/test/restore/full", json={"result": "ok"} "http://127.0.0.1/backups/test/restore/full", json={"result": "ok"}
) )
aioclient_mock.post( aioclient_mock.post(
"http://127.0.0.1/snapshots/test/restore/partial", json={"result": "ok"} "http://127.0.0.1/backups/test/restore/partial", json={"result": "ok"}
) )
await hass.services.async_call("hassio", "addon_start", {"addon": "test"}) await hass.services.async_call("hassio", "addon_start", {"addon": "test"})
@ -345,27 +347,48 @@ async def test_service_calls(hassio_env, hass, aioclient_mock):
assert aioclient_mock.call_count == 10 assert aioclient_mock.call_count == 10
await hass.services.async_call("hassio", "backup_full", {})
await hass.services.async_call(
"hassio",
"backup_partial",
{"addons": ["test"], "folders": ["ssl"], "password": "123456"},
)
await hass.services.async_call("hassio", "snapshot_full", {}) await hass.services.async_call("hassio", "snapshot_full", {})
await hass.services.async_call( await hass.services.async_call(
"hassio", "hassio",
"snapshot_partial", "snapshot_partial",
{"addons": ["test"], "folders": ["ssl"], "password": "123456"}, {"addons": ["test"], "folders": ["ssl"]},
) )
await hass.async_block_till_done() await hass.async_block_till_done()
assert (
"The service 'snapshot_full' is deprecated and will be removed in Home Assistant 2021.11, use 'backup_full' instead"
in caplog.text
)
assert (
"The service 'snapshot_partial' is deprecated and will be removed in Home Assistant 2021.11, use 'backup_partial' instead"
in caplog.text
)
assert aioclient_mock.call_count == 12 assert aioclient_mock.call_count == 14
assert aioclient_mock.mock_calls[-1][2] == { assert aioclient_mock.mock_calls[-3][2] == {
"addons": ["test"], "addons": ["test"],
"folders": ["ssl"], "folders": ["ssl"],
"password": "123456", "password": "123456",
} }
await hass.services.async_call("hassio", "restore_full", {"slug": "test"})
await hass.services.async_call("hassio", "restore_full", {"snapshot": "test"}) await hass.services.async_call("hassio", "restore_full", {"snapshot": "test"})
await hass.async_block_till_done()
assert (
"Using 'snapshot' is deprecated and will be removed in Home Assistant 2021.11, use 'slug' instead"
in caplog.text
)
await hass.services.async_call( await hass.services.async_call(
"hassio", "hassio",
"restore_partial", "restore_partial",
{ {
"snapshot": "test", "slug": "test",
"homeassistant": False, "homeassistant": False,
"addons": ["test"], "addons": ["test"],
"folders": ["ssl"], "folders": ["ssl"],
@ -374,7 +397,7 @@ async def test_service_calls(hassio_env, hass, aioclient_mock):
) )
await hass.async_block_till_done() await hass.async_block_till_done()
assert aioclient_mock.call_count == 14 assert aioclient_mock.call_count == 17
assert aioclient_mock.mock_calls[-1][2] == { assert aioclient_mock.mock_calls[-1][2] == {
"addons": ["test"], "addons": ["test"],
"folders": ["ssl"], "folders": ["ssl"],

View File

@ -61,7 +61,7 @@ async def test_websocket_supervisor_api(
assert await async_setup_component(hass, "hassio", {}) assert await async_setup_component(hass, "hassio", {})
websocket_client = await hass_ws_client(hass) websocket_client = await hass_ws_client(hass)
aioclient_mock.post( aioclient_mock.post(
"http://127.0.0.1/snapshots/new/partial", "http://127.0.0.1/backups/new/partial",
json={"result": "ok", "data": {"slug": "sn_slug"}}, json={"result": "ok", "data": {"slug": "sn_slug"}},
) )
@ -69,7 +69,7 @@ async def test_websocket_supervisor_api(
{ {
WS_ID: 1, WS_ID: 1,
WS_TYPE: WS_TYPE_API, WS_TYPE: WS_TYPE_API,
ATTR_ENDPOINT: "/snapshots/new/partial", ATTR_ENDPOINT: "/backups/new/partial",
ATTR_METHOD: "post", ATTR_METHOD: "post",
} }
) )

View File

@ -171,13 +171,13 @@ def uninstall_addon_fixture():
yield uninstall_addon yield uninstall_addon
@pytest.fixture(name="create_shapshot") @pytest.fixture(name="create_backup")
def create_snapshot_fixture(): def create_backup_fixture():
"""Mock create snapshot.""" """Mock create backup."""
with patch( with patch(
"homeassistant.components.zwave_js.addon.async_create_snapshot" "homeassistant.components.zwave_js.addon.async_create_backup"
) as create_shapshot: ) as create_backup:
yield create_shapshot yield create_backup
@pytest.fixture(name="controller_state", scope="session") @pytest.fixture(name="controller_state", scope="session")

View File

@ -365,8 +365,8 @@ async def test_addon_options_changed(
@pytest.mark.parametrize( @pytest.mark.parametrize(
"addon_version, update_available, update_calls, snapshot_calls, " "addon_version, update_available, update_calls, backup_calls, "
"update_addon_side_effect, create_shapshot_side_effect", "update_addon_side_effect, create_backup_side_effect",
[ [
("1.0", True, 1, 1, None, None), ("1.0", True, 1, 1, None, None),
("1.0", False, 0, 0, None, None), ("1.0", False, 0, 0, None, None),
@ -380,15 +380,15 @@ async def test_update_addon(
addon_info, addon_info,
addon_installed, addon_installed,
addon_running, addon_running,
create_shapshot, create_backup,
update_addon, update_addon,
addon_options, addon_options,
addon_version, addon_version,
update_available, update_available,
update_calls, update_calls,
snapshot_calls, backup_calls,
update_addon_side_effect, update_addon_side_effect,
create_shapshot_side_effect, create_backup_side_effect,
): ):
"""Test update the Z-Wave JS add-on during entry setup.""" """Test update the Z-Wave JS add-on during entry setup."""
device = "/test" device = "/test"
@ -397,7 +397,7 @@ async def test_update_addon(
addon_options["network_key"] = network_key addon_options["network_key"] = network_key
addon_info.return_value["version"] = addon_version addon_info.return_value["version"] = addon_version
addon_info.return_value["update_available"] = update_available addon_info.return_value["update_available"] = update_available
create_shapshot.side_effect = create_shapshot_side_effect create_backup.side_effect = create_backup_side_effect
update_addon.side_effect = update_addon_side_effect update_addon.side_effect = update_addon_side_effect
client.connect.side_effect = InvalidServerVersion("Invalid version") client.connect.side_effect = InvalidServerVersion("Invalid version")
entry = MockConfigEntry( entry = MockConfigEntry(
@ -416,7 +416,7 @@ async def test_update_addon(
await hass.async_block_till_done() await hass.async_block_till_done()
assert entry.state is ConfigEntryState.SETUP_RETRY assert entry.state is ConfigEntryState.SETUP_RETRY
assert create_shapshot.call_count == snapshot_calls assert create_backup.call_count == backup_calls
assert update_addon.call_count == update_calls assert update_addon.call_count == update_calls
@ -469,7 +469,7 @@ async def test_stop_addon(
async def test_remove_entry( async def test_remove_entry(
hass, addon_installed, stop_addon, create_shapshot, uninstall_addon, caplog hass, addon_installed, stop_addon, create_backup, uninstall_addon, caplog
): ):
"""Test remove the config entry.""" """Test remove the config entry."""
# test successful remove without created add-on # test successful remove without created add-on
@ -500,8 +500,8 @@ async def test_remove_entry(
assert stop_addon.call_count == 1 assert stop_addon.call_count == 1
assert stop_addon.call_args == call(hass, "core_zwave_js") assert stop_addon.call_args == call(hass, "core_zwave_js")
assert create_shapshot.call_count == 1 assert create_backup.call_count == 1
assert create_shapshot.call_args == call( assert create_backup.call_args == call(
hass, hass,
{"name": "addon_core_zwave_js_1.0", "addons": ["core_zwave_js"]}, {"name": "addon_core_zwave_js_1.0", "addons": ["core_zwave_js"]},
partial=True, partial=True,
@ -511,7 +511,7 @@ async def test_remove_entry(
assert entry.state is ConfigEntryState.NOT_LOADED assert entry.state is ConfigEntryState.NOT_LOADED
assert len(hass.config_entries.async_entries(DOMAIN)) == 0 assert len(hass.config_entries.async_entries(DOMAIN)) == 0
stop_addon.reset_mock() stop_addon.reset_mock()
create_shapshot.reset_mock() create_backup.reset_mock()
uninstall_addon.reset_mock() uninstall_addon.reset_mock()
# test add-on stop failure # test add-on stop failure
@ -523,27 +523,27 @@ async def test_remove_entry(
assert stop_addon.call_count == 1 assert stop_addon.call_count == 1
assert stop_addon.call_args == call(hass, "core_zwave_js") assert stop_addon.call_args == call(hass, "core_zwave_js")
assert create_shapshot.call_count == 0 assert create_backup.call_count == 0
assert uninstall_addon.call_count == 0 assert uninstall_addon.call_count == 0
assert entry.state is ConfigEntryState.NOT_LOADED assert entry.state is ConfigEntryState.NOT_LOADED
assert len(hass.config_entries.async_entries(DOMAIN)) == 0 assert len(hass.config_entries.async_entries(DOMAIN)) == 0
assert "Failed to stop the Z-Wave JS add-on" in caplog.text assert "Failed to stop the Z-Wave JS add-on" in caplog.text
stop_addon.side_effect = None stop_addon.side_effect = None
stop_addon.reset_mock() stop_addon.reset_mock()
create_shapshot.reset_mock() create_backup.reset_mock()
uninstall_addon.reset_mock() uninstall_addon.reset_mock()
# test create snapshot failure # test create backup failure
entry.add_to_hass(hass) entry.add_to_hass(hass)
assert len(hass.config_entries.async_entries(DOMAIN)) == 1 assert len(hass.config_entries.async_entries(DOMAIN)) == 1
create_shapshot.side_effect = HassioAPIError() create_backup.side_effect = HassioAPIError()
await hass.config_entries.async_remove(entry.entry_id) await hass.config_entries.async_remove(entry.entry_id)
assert stop_addon.call_count == 1 assert stop_addon.call_count == 1
assert stop_addon.call_args == call(hass, "core_zwave_js") assert stop_addon.call_args == call(hass, "core_zwave_js")
assert create_shapshot.call_count == 1 assert create_backup.call_count == 1
assert create_shapshot.call_args == call( assert create_backup.call_args == call(
hass, hass,
{"name": "addon_core_zwave_js_1.0", "addons": ["core_zwave_js"]}, {"name": "addon_core_zwave_js_1.0", "addons": ["core_zwave_js"]},
partial=True, partial=True,
@ -551,10 +551,10 @@ async def test_remove_entry(
assert uninstall_addon.call_count == 0 assert uninstall_addon.call_count == 0
assert entry.state is ConfigEntryState.NOT_LOADED assert entry.state is ConfigEntryState.NOT_LOADED
assert len(hass.config_entries.async_entries(DOMAIN)) == 0 assert len(hass.config_entries.async_entries(DOMAIN)) == 0
assert "Failed to create a snapshot of the Z-Wave JS add-on" in caplog.text assert "Failed to create a backup of the Z-Wave JS add-on" in caplog.text
create_shapshot.side_effect = None create_backup.side_effect = None
stop_addon.reset_mock() stop_addon.reset_mock()
create_shapshot.reset_mock() create_backup.reset_mock()
uninstall_addon.reset_mock() uninstall_addon.reset_mock()
# test add-on uninstall failure # test add-on uninstall failure
@ -566,8 +566,8 @@ async def test_remove_entry(
assert stop_addon.call_count == 1 assert stop_addon.call_count == 1
assert stop_addon.call_args == call(hass, "core_zwave_js") assert stop_addon.call_args == call(hass, "core_zwave_js")
assert create_shapshot.call_count == 1 assert create_backup.call_count == 1
assert create_shapshot.call_args == call( assert create_backup.call_args == call(
hass, hass,
{"name": "addon_core_zwave_js_1.0", "addons": ["core_zwave_js"]}, {"name": "addon_core_zwave_js_1.0", "addons": ["core_zwave_js"]},
partial=True, partial=True,