mirror of
https://github.com/home-assistant/core.git
synced 2025-07-25 06:07:17 +00:00
Do not factory reset old Z-Wave controller during migration (#147576)
* Do not factory reset old Z-Wave controller during migration * PR comments * remove obsolete test
This commit is contained in:
parent
f93ab8d519
commit
28dfc997f3
@ -845,11 +845,8 @@ class ZWaveJSConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
},
|
||||
)
|
||||
|
||||
if user_input is not None:
|
||||
self._migrating = True
|
||||
return await self.async_step_backup_nvm()
|
||||
|
||||
return self.async_show_form(step_id="intent_migrate")
|
||||
self._migrating = True
|
||||
return await self.async_step_backup_nvm()
|
||||
|
||||
async def async_step_backup_nvm(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
@ -904,7 +901,7 @@ class ZWaveJSConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
async def async_step_instruct_unplug(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
"""Reset the current controller, and instruct the user to unplug it."""
|
||||
"""Instruct the user to unplug the old controller."""
|
||||
|
||||
if user_input is not None:
|
||||
if self.usb_path:
|
||||
@ -914,63 +911,9 @@ class ZWaveJSConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
# Now that the old controller is gone, we can scan for serial ports again
|
||||
return await self.async_step_choose_serial_port()
|
||||
|
||||
try:
|
||||
driver = self._get_driver()
|
||||
except AbortFlow:
|
||||
return self.async_abort(reason="config_entry_not_loaded")
|
||||
|
||||
@callback
|
||||
def set_driver_ready(event: dict) -> None:
|
||||
"Set the driver ready event."
|
||||
wait_driver_ready.set()
|
||||
|
||||
wait_driver_ready = asyncio.Event()
|
||||
|
||||
unsubscribe = driver.once("driver ready", set_driver_ready)
|
||||
|
||||
# reset the old controller
|
||||
try:
|
||||
await driver.async_hard_reset()
|
||||
except FailedCommand as err:
|
||||
unsubscribe()
|
||||
_LOGGER.error("Failed to reset controller: %s", err)
|
||||
return self.async_abort(reason="reset_failed")
|
||||
|
||||
# Update the unique id of the config entry
|
||||
# to the new home id, which requires waiting for the driver
|
||||
# to be ready before getting the new home id.
|
||||
# If the backup restore, done later in the flow, fails,
|
||||
# the config entry unique id should be the new home id
|
||||
# after the controller reset.
|
||||
try:
|
||||
async with asyncio.timeout(DRIVER_READY_TIMEOUT):
|
||||
await wait_driver_ready.wait()
|
||||
except TimeoutError:
|
||||
pass
|
||||
finally:
|
||||
unsubscribe()
|
||||
|
||||
config_entry = self._reconfigure_config_entry
|
||||
assert config_entry is not None
|
||||
|
||||
try:
|
||||
version_info = await async_get_version_info(
|
||||
self.hass, config_entry.data[CONF_URL]
|
||||
)
|
||||
except CannotConnect:
|
||||
# Just log this error, as there's nothing to do about it here.
|
||||
# The stale unique id needs to be handled by a repair flow,
|
||||
# after the config entry has been reloaded, if the backup restore
|
||||
# also fails.
|
||||
_LOGGER.debug(
|
||||
"Failed to get server version, cannot update config entry "
|
||||
"unique id with new home id, after controller reset"
|
||||
)
|
||||
else:
|
||||
self.hass.config_entries.async_update_entry(
|
||||
config_entry, unique_id=str(version_info.home_id)
|
||||
)
|
||||
|
||||
# Unload the config entry before asking the user to unplug the controller.
|
||||
await self.hass.config_entries.async_unload(config_entry.entry_id)
|
||||
|
||||
|
@ -108,13 +108,9 @@
|
||||
"intent_reconfigure": "Re-configure the current controller"
|
||||
}
|
||||
},
|
||||
"intent_migrate": {
|
||||
"title": "[%key:component::zwave_js::config::step::reconfigure::menu_options::intent_migrate%]",
|
||||
"description": "Before setting up your new controller, your old controller needs to be reset. A backup will be performed first.\n\nDo you wish to continue?"
|
||||
},
|
||||
"instruct_unplug": {
|
||||
"title": "Unplug your old controller",
|
||||
"description": "Backup saved to \"{file_path}\"\n\nYour old controller has been reset. If the hardware is no longer needed, you can now unplug it.\n\nPlease make sure your new controller is plugged in before continuing."
|
||||
"description": "Backup saved to \"{file_path}\"\n\nYour old controller has not been reset. You should now unplug it to prevent it from interfering with the new controller.\n\nPlease make sure your new controller is plugged in before continuing."
|
||||
},
|
||||
"restore_failed": {
|
||||
"title": "Restoring unsuccessful",
|
||||
|
@ -867,8 +867,6 @@ async def test_usb_discovery_migration(
|
||||
get_server_version: AsyncMock,
|
||||
) -> None:
|
||||
"""Test usb discovery migration."""
|
||||
version_info = get_server_version.return_value
|
||||
version_info.home_id = 4321
|
||||
addon_options["device"] = "/dev/ttyUSB0"
|
||||
entry = integration
|
||||
assert client.connect.call_count == 1
|
||||
@ -893,13 +891,6 @@ async def test_usb_discovery_migration(
|
||||
side_effect=mock_backup_nvm_raw
|
||||
)
|
||||
|
||||
async def mock_reset_controller():
|
||||
client.driver.emit(
|
||||
"driver ready", {"event": "driver ready", "source": "driver"}
|
||||
)
|
||||
|
||||
client.driver.async_hard_reset = AsyncMock(side_effect=mock_reset_controller)
|
||||
|
||||
async def mock_restore_nvm(data: bytes, options: dict[str, bool] | None = None):
|
||||
client.driver.controller.emit(
|
||||
"nvm convert progress",
|
||||
@ -927,10 +918,6 @@ async def test_usb_discovery_migration(
|
||||
)
|
||||
|
||||
assert mock_usb_serial_by_id.call_count == 2
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "intent_migrate"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
|
||||
|
||||
assert result["type"] is FlowResultType.SHOW_PROGRESS
|
||||
assert result["step_id"] == "backup_nvm"
|
||||
@ -947,7 +934,6 @@ async def test_usb_discovery_migration(
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "instruct_unplug"
|
||||
assert entry.unique_id == "4321"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
|
||||
|
||||
@ -962,6 +948,7 @@ async def test_usb_discovery_migration(
|
||||
|
||||
assert restart_addon.call_args == call("core_zwave_js")
|
||||
|
||||
version_info = get_server_version.return_value
|
||||
version_info.home_id = 5678
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
@ -1024,13 +1011,6 @@ async def test_usb_discovery_migration_restore_driver_ready_timeout(
|
||||
side_effect=mock_backup_nvm_raw
|
||||
)
|
||||
|
||||
async def mock_reset_controller():
|
||||
client.driver.emit(
|
||||
"driver ready", {"event": "driver ready", "source": "driver"}
|
||||
)
|
||||
|
||||
client.driver.async_hard_reset = AsyncMock(side_effect=mock_reset_controller)
|
||||
|
||||
async def mock_restore_nvm(data: bytes, options: dict[str, bool] | None = None):
|
||||
client.driver.controller.emit(
|
||||
"nvm convert progress",
|
||||
@ -1055,10 +1035,6 @@ async def test_usb_discovery_migration_restore_driver_ready_timeout(
|
||||
)
|
||||
|
||||
assert mock_usb_serial_by_id.call_count == 2
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "intent_migrate"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
|
||||
|
||||
assert result["type"] is FlowResultType.SHOW_PROGRESS
|
||||
assert result["step_id"] == "backup_nvm"
|
||||
@ -3401,21 +3377,12 @@ async def test_reconfigure_migrate_low_sdk_version(
|
||||
@pytest.mark.usefixtures("supervisor", "addon_running")
|
||||
@pytest.mark.parametrize(
|
||||
(
|
||||
"reset_server_version_side_effect",
|
||||
"reset_unique_id",
|
||||
"restore_server_version_side_effect",
|
||||
"final_unique_id",
|
||||
),
|
||||
[
|
||||
(None, "4321", None, "3245146787"),
|
||||
(aiohttp.ClientError("Boom"), "3245146787", None, "3245146787"),
|
||||
(None, "4321", aiohttp.ClientError("Boom"), "5678"),
|
||||
(
|
||||
aiohttp.ClientError("Boom"),
|
||||
"3245146787",
|
||||
aiohttp.ClientError("Boom"),
|
||||
"5678",
|
||||
),
|
||||
(None, "3245146787"),
|
||||
(aiohttp.ClientError("Boom"), "5678"),
|
||||
],
|
||||
)
|
||||
async def test_reconfigure_migrate_with_addon(
|
||||
@ -3428,15 +3395,11 @@ async def test_reconfigure_migrate_with_addon(
|
||||
addon_options: dict[str, Any],
|
||||
set_addon_options: AsyncMock,
|
||||
get_server_version: AsyncMock,
|
||||
reset_server_version_side_effect: Exception | None,
|
||||
reset_unique_id: str,
|
||||
restore_server_version_side_effect: Exception | None,
|
||||
final_unique_id: str,
|
||||
) -> None:
|
||||
"""Test migration flow with add-on."""
|
||||
get_server_version.side_effect = reset_server_version_side_effect
|
||||
version_info = get_server_version.return_value
|
||||
version_info.home_id = 4321
|
||||
entry = integration
|
||||
assert client.connect.call_count == 1
|
||||
assert client.driver.controller.home_id == 3245146787
|
||||
@ -3494,13 +3457,6 @@ async def test_reconfigure_migrate_with_addon(
|
||||
side_effect=mock_backup_nvm_raw
|
||||
)
|
||||
|
||||
async def mock_reset_controller():
|
||||
client.driver.emit(
|
||||
"driver ready", {"event": "driver ready", "source": "driver"}
|
||||
)
|
||||
|
||||
client.driver.async_hard_reset = AsyncMock(side_effect=mock_reset_controller)
|
||||
|
||||
async def mock_restore_nvm(data: bytes, options: dict[str, bool] | None = None):
|
||||
client.driver.controller.emit(
|
||||
"nvm convert progress",
|
||||
@ -3531,11 +3487,6 @@ async def test_reconfigure_migrate_with_addon(
|
||||
result["flow_id"], {"next_step_id": "intent_migrate"}
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "intent_migrate"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
|
||||
|
||||
assert result["type"] is FlowResultType.SHOW_PROGRESS
|
||||
assert result["step_id"] == "backup_nvm"
|
||||
|
||||
@ -3552,7 +3503,6 @@ async def test_reconfigure_migrate_with_addon(
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "instruct_unplug"
|
||||
assert entry.state is config_entries.ConfigEntryState.NOT_LOADED
|
||||
assert entry.unique_id == reset_unique_id
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
|
||||
|
||||
@ -3565,8 +3515,6 @@ async def test_reconfigure_migrate_with_addon(
|
||||
with pytest.raises(InInvalid):
|
||||
data_schema.schema[CONF_USB_PATH](addon_options["device"])
|
||||
|
||||
# Reset side effect before starting the add-on.
|
||||
get_server_version.side_effect = None
|
||||
version_info.home_id = 5678
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
@ -3646,156 +3594,6 @@ async def test_reconfigure_migrate_with_addon(
|
||||
assert client.driver.controller.home_id == 3245146787
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("supervisor", "addon_running")
|
||||
async def test_reconfigure_migrate_reset_driver_ready_timeout(
|
||||
hass: HomeAssistant,
|
||||
client: MagicMock,
|
||||
integration: MockConfigEntry,
|
||||
restart_addon: AsyncMock,
|
||||
set_addon_options: AsyncMock,
|
||||
get_server_version: AsyncMock,
|
||||
) -> None:
|
||||
"""Test migration flow with driver ready timeout after controller reset."""
|
||||
version_info = get_server_version.return_value
|
||||
version_info.home_id = 4321
|
||||
entry = integration
|
||||
assert client.connect.call_count == 1
|
||||
hass.config_entries.async_update_entry(
|
||||
entry,
|
||||
unique_id="1234",
|
||||
data={
|
||||
"url": "ws://localhost:3000",
|
||||
"use_addon": True,
|
||||
"usb_path": "/dev/ttyUSB0",
|
||||
},
|
||||
)
|
||||
|
||||
async def mock_backup_nvm_raw():
|
||||
await asyncio.sleep(0)
|
||||
client.driver.controller.emit(
|
||||
"nvm backup progress", {"bytesRead": 100, "total": 200}
|
||||
)
|
||||
return b"test_nvm_data"
|
||||
|
||||
client.driver.controller.async_backup_nvm_raw = AsyncMock(
|
||||
side_effect=mock_backup_nvm_raw
|
||||
)
|
||||
|
||||
async def mock_reset_controller():
|
||||
await asyncio.sleep(0)
|
||||
|
||||
client.driver.async_hard_reset = AsyncMock(side_effect=mock_reset_controller)
|
||||
|
||||
async def mock_restore_nvm(data: bytes, options: dict[str, bool] | None = None):
|
||||
client.driver.controller.emit(
|
||||
"nvm convert progress",
|
||||
{"event": "nvm convert progress", "bytesRead": 100, "total": 200},
|
||||
)
|
||||
await asyncio.sleep(0)
|
||||
client.driver.controller.emit(
|
||||
"nvm restore progress",
|
||||
{"event": "nvm restore progress", "bytesWritten": 100, "total": 200},
|
||||
)
|
||||
client.driver.emit(
|
||||
"driver ready", {"event": "driver ready", "source": "driver"}
|
||||
)
|
||||
|
||||
client.driver.controller.async_restore_nvm = AsyncMock(side_effect=mock_restore_nvm)
|
||||
|
||||
events = async_capture_events(
|
||||
hass, data_entry_flow.EVENT_DATA_ENTRY_FLOW_PROGRESS_UPDATE
|
||||
)
|
||||
|
||||
result = await entry.start_reconfigure_flow(hass)
|
||||
|
||||
assert result["type"] is FlowResultType.MENU
|
||||
assert result["step_id"] == "reconfigure"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], {"next_step_id": "intent_migrate"}
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "intent_migrate"
|
||||
|
||||
with (
|
||||
patch(
|
||||
("homeassistant.components.zwave_js.config_flow.DRIVER_READY_TIMEOUT"),
|
||||
new=0,
|
||||
),
|
||||
patch("pathlib.Path.write_bytes") as mock_file,
|
||||
):
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
|
||||
|
||||
assert result["type"] is FlowResultType.SHOW_PROGRESS
|
||||
assert result["step_id"] == "backup_nvm"
|
||||
|
||||
await hass.async_block_till_done()
|
||||
assert client.driver.controller.async_backup_nvm_raw.call_count == 1
|
||||
assert mock_file.call_count == 1
|
||||
assert len(events) == 1
|
||||
assert events[0].data["progress"] == 0.5
|
||||
events.clear()
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "instruct_unplug"
|
||||
assert entry.state is config_entries.ConfigEntryState.NOT_LOADED
|
||||
assert entry.unique_id == "4321"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "choose_serial_port"
|
||||
data_schema = result["data_schema"]
|
||||
assert data_schema is not None
|
||||
assert data_schema.schema[CONF_USB_PATH]
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
user_input={
|
||||
CONF_USB_PATH: "/test",
|
||||
},
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.SHOW_PROGRESS
|
||||
assert result["step_id"] == "start_addon"
|
||||
assert set_addon_options.call_args == call(
|
||||
"core_zwave_js", AddonsOptions(config={"device": "/test"})
|
||||
)
|
||||
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert restart_addon.call_args == call("core_zwave_js")
|
||||
|
||||
version_info.home_id = 5678
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
|
||||
assert result["type"] is FlowResultType.SHOW_PROGRESS
|
||||
assert result["step_id"] == "restore_nvm"
|
||||
assert client.connect.call_count == 2
|
||||
|
||||
await hass.async_block_till_done()
|
||||
assert client.connect.call_count == 4
|
||||
assert entry.state is config_entries.ConfigEntryState.LOADED
|
||||
assert client.driver.controller.async_restore_nvm.call_count == 1
|
||||
assert len(events) == 2
|
||||
assert events[0].data["progress"] == 0.25
|
||||
assert events[1].data["progress"] == 0.75
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
assert result["reason"] == "migration_successful"
|
||||
assert entry.data["url"] == "ws://host1:3001"
|
||||
assert entry.data["usb_path"] == "/test"
|
||||
assert entry.data["use_addon"] is True
|
||||
assert entry.unique_id == "5678"
|
||||
assert "keep_old_devices" not in entry.data
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("supervisor", "addon_running")
|
||||
async def test_reconfigure_migrate_restore_driver_ready_timeout(
|
||||
hass: HomeAssistant,
|
||||
@ -3828,13 +3626,6 @@ async def test_reconfigure_migrate_restore_driver_ready_timeout(
|
||||
side_effect=mock_backup_nvm_raw
|
||||
)
|
||||
|
||||
async def mock_reset_controller():
|
||||
client.driver.emit(
|
||||
"driver ready", {"event": "driver ready", "source": "driver"}
|
||||
)
|
||||
|
||||
client.driver.async_hard_reset = AsyncMock(side_effect=mock_reset_controller)
|
||||
|
||||
async def mock_restore_nvm(data: bytes, options: dict[str, bool] | None = None):
|
||||
client.driver.controller.emit(
|
||||
"nvm convert progress",
|
||||
@ -3861,11 +3652,6 @@ async def test_reconfigure_migrate_restore_driver_ready_timeout(
|
||||
result["flow_id"], {"next_step_id": "intent_migrate"}
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "intent_migrate"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
|
||||
|
||||
assert result["type"] is FlowResultType.SHOW_PROGRESS
|
||||
assert result["step_id"] == "backup_nvm"
|
||||
|
||||
@ -3960,11 +3746,6 @@ async def test_reconfigure_migrate_backup_failure(
|
||||
result["flow_id"], {"next_step_id": "intent_migrate"}
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "intent_migrate"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
|
||||
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
assert result["reason"] == "backup_failed"
|
||||
assert "keep_old_devices" not in entry.data
|
||||
@ -3998,11 +3779,6 @@ async def test_reconfigure_migrate_backup_file_failure(
|
||||
result["flow_id"], {"next_step_id": "intent_migrate"}
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "intent_migrate"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
|
||||
|
||||
assert result["type"] is FlowResultType.SHOW_PROGRESS
|
||||
assert result["step_id"] == "backup_nvm"
|
||||
|
||||
@ -4040,13 +3816,6 @@ async def test_reconfigure_migrate_start_addon_failure(
|
||||
side_effect=mock_backup_nvm_raw
|
||||
)
|
||||
|
||||
async def mock_reset_controller():
|
||||
client.driver.emit(
|
||||
"driver ready", {"event": "driver ready", "source": "driver"}
|
||||
)
|
||||
|
||||
client.driver.async_hard_reset = AsyncMock(side_effect=mock_reset_controller)
|
||||
|
||||
result = await entry.start_reconfigure_flow(hass)
|
||||
|
||||
assert result["type"] is FlowResultType.MENU
|
||||
@ -4056,11 +3825,6 @@ async def test_reconfigure_migrate_start_addon_failure(
|
||||
result["flow_id"], {"next_step_id": "intent_migrate"}
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "intent_migrate"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
|
||||
|
||||
assert result["type"] is FlowResultType.SHOW_PROGRESS
|
||||
assert result["step_id"] == "backup_nvm"
|
||||
|
||||
@ -4124,12 +3888,6 @@ async def test_reconfigure_migrate_restore_failure(
|
||||
side_effect=mock_backup_nvm_raw
|
||||
)
|
||||
|
||||
async def mock_reset_controller():
|
||||
client.driver.emit(
|
||||
"driver ready", {"event": "driver ready", "source": "driver"}
|
||||
)
|
||||
|
||||
client.driver.async_hard_reset = AsyncMock(side_effect=mock_reset_controller)
|
||||
client.driver.controller.async_restore_nvm = AsyncMock(
|
||||
side_effect=FailedCommand("test_error", "unknown_error")
|
||||
)
|
||||
@ -4143,11 +3901,6 @@ async def test_reconfigure_migrate_restore_failure(
|
||||
result["flow_id"], {"next_step_id": "intent_migrate"}
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "intent_migrate"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
|
||||
|
||||
assert result["type"] is FlowResultType.SHOW_PROGRESS
|
||||
assert result["step_id"] == "backup_nvm"
|
||||
|
||||
@ -4242,106 +3995,6 @@ async def test_get_driver_failure_intent_migrate(
|
||||
assert "keep_old_devices" not in entry.data
|
||||
|
||||
|
||||
async def test_get_driver_failure_instruct_unplug(
|
||||
hass: HomeAssistant,
|
||||
client: MagicMock,
|
||||
integration: MockConfigEntry,
|
||||
) -> None:
|
||||
"""Test get driver failure in instruct unplug step."""
|
||||
|
||||
async def mock_backup_nvm_raw():
|
||||
await asyncio.sleep(0)
|
||||
client.driver.controller.emit(
|
||||
"nvm backup progress", {"bytesRead": 100, "total": 200}
|
||||
)
|
||||
return b"test_nvm_data"
|
||||
|
||||
client.driver.controller.async_backup_nvm_raw = AsyncMock(
|
||||
side_effect=mock_backup_nvm_raw
|
||||
)
|
||||
entry = integration
|
||||
hass.config_entries.async_update_entry(
|
||||
entry, unique_id="1234", data={**entry.data, "use_addon": True}
|
||||
)
|
||||
result = await entry.start_reconfigure_flow(hass)
|
||||
assert result["type"] is FlowResultType.MENU
|
||||
assert result["step_id"] == "reconfigure"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], {"next_step_id": "intent_migrate"}
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "intent_migrate"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
|
||||
|
||||
assert result["type"] is FlowResultType.SHOW_PROGRESS
|
||||
assert result["step_id"] == "backup_nvm"
|
||||
|
||||
with patch("pathlib.Path.write_bytes") as mock_file:
|
||||
await hass.async_block_till_done()
|
||||
assert client.driver.controller.async_backup_nvm_raw.call_count == 1
|
||||
assert mock_file.call_count == 1
|
||||
|
||||
await hass.config_entries.async_unload(entry.entry_id)
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
assert result["reason"] == "config_entry_not_loaded"
|
||||
|
||||
|
||||
async def test_hard_reset_failure(
|
||||
hass: HomeAssistant,
|
||||
integration: MockConfigEntry,
|
||||
client: MagicMock,
|
||||
) -> None:
|
||||
"""Test hard reset failure."""
|
||||
entry = integration
|
||||
hass.config_entries.async_update_entry(
|
||||
entry, unique_id="1234", data={**entry.data, "use_addon": True}
|
||||
)
|
||||
|
||||
async def mock_backup_nvm_raw():
|
||||
await asyncio.sleep(0)
|
||||
return b"test_nvm_data"
|
||||
|
||||
client.driver.controller.async_backup_nvm_raw = AsyncMock(
|
||||
side_effect=mock_backup_nvm_raw
|
||||
)
|
||||
client.driver.async_hard_reset = AsyncMock(
|
||||
side_effect=FailedCommand("test_error", "unknown_error")
|
||||
)
|
||||
|
||||
result = await entry.start_reconfigure_flow(hass)
|
||||
|
||||
assert result["type"] is FlowResultType.MENU
|
||||
assert result["step_id"] == "reconfigure"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], {"next_step_id": "intent_migrate"}
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "intent_migrate"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
|
||||
|
||||
assert result["type"] is FlowResultType.SHOW_PROGRESS
|
||||
assert result["step_id"] == "backup_nvm"
|
||||
|
||||
with patch("pathlib.Path.write_bytes") as mock_file:
|
||||
await hass.async_block_till_done()
|
||||
assert client.driver.controller.async_backup_nvm_raw.call_count == 1
|
||||
assert mock_file.call_count == 1
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
assert result["reason"] == "reset_failed"
|
||||
|
||||
|
||||
async def test_choose_serial_port_usb_ports_failure(
|
||||
hass: HomeAssistant,
|
||||
integration: MockConfigEntry,
|
||||
@ -4361,13 +4014,6 @@ async def test_choose_serial_port_usb_ports_failure(
|
||||
side_effect=mock_backup_nvm_raw
|
||||
)
|
||||
|
||||
async def mock_reset_controller():
|
||||
client.driver.emit(
|
||||
"driver ready", {"event": "driver ready", "source": "driver"}
|
||||
)
|
||||
|
||||
client.driver.async_hard_reset = AsyncMock(side_effect=mock_reset_controller)
|
||||
|
||||
result = await entry.start_reconfigure_flow(hass)
|
||||
|
||||
assert result["type"] is FlowResultType.MENU
|
||||
@ -4377,11 +4023,6 @@ async def test_choose_serial_port_usb_ports_failure(
|
||||
result["flow_id"], {"next_step_id": "intent_migrate"}
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "intent_migrate"
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"], {})
|
||||
|
||||
assert result["type"] is FlowResultType.SHOW_PROGRESS
|
||||
assert result["step_id"] == "backup_nvm"
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user