Prevent otbr creating multiple config entries (#96783)

This commit is contained in:
Erik Montnemery 2023-07-17 21:22:50 +02:00 committed by GitHub
parent d02bf837a6
commit 1e3fdcc4d1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 85 additions and 0 deletions

View file

@ -130,6 +130,11 @@ class OTBRConfigFlow(ConfigFlow, domain=DOMAIN):
url = f"http://{config['host']}:{config['port']}"
config_entry_data = {"url": url}
if self._async_in_progress(include_uninitialized=True):
# We currently don't handle multiple config entries, abort if hassio
# discovers multiple addons with otbr support
return self.async_abort(reason="single_instance_allowed")
if current_entries := self._async_current_entries():
for current_entry in current_entries:
if current_entry.source != SOURCE_HASSIO:

View file

@ -23,6 +23,12 @@ HASSIO_DATA = hassio.HassioServiceInfo(
slug="otbr",
uuid="12345",
)
HASSIO_DATA_2 = hassio.HassioServiceInfo(
config={"host": "core-silabs-multiprotocol_2", "port": 8082},
name="Silicon Labs Multiprotocol",
slug="other_addon",
uuid="23456",
)
@pytest.fixture(name="addon_info")
@ -313,6 +319,80 @@ async def test_hassio_discovery_flow_sky_connect(
assert config_entry.unique_id == HASSIO_DATA.uuid
async def test_hassio_discovery_flow_2x_addons(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker, addon_info
) -> None:
"""Test the hassio discovery flow when the user has 2 addons with otbr support."""
url1 = "http://core-silabs-multiprotocol:8081"
url2 = "http://core-silabs-multiprotocol_2:8081"
aioclient_mock.get(f"{url1}/node/dataset/active", text="aa")
aioclient_mock.get(f"{url2}/node/dataset/active", text="bb")
async def _addon_info(hass, slug):
await asyncio.sleep(0)
if slug == "otbr":
return {
"available": True,
"hostname": None,
"options": {
"device": (
"/dev/serial/by-id/usb-Nabu_Casa_SkyConnect_v1.0_"
"9e2adbd75b8beb119fe564a0f320645d-if00-port0"
)
},
"state": None,
"update_available": False,
"version": None,
}
return {
"available": True,
"hostname": None,
"options": {
"device": (
"/dev/serial/by-id/usb-Nabu_Casa_SkyConnect_v1.0_"
"9e2adbd75b8beb119fe564a0f320645d-if00-port1"
)
},
"state": None,
"update_available": False,
"version": None,
}
addon_info.side_effect = _addon_info
with patch(
"homeassistant.components.otbr.async_setup_entry",
return_value=True,
) as mock_setup_entry:
results = await asyncio.gather(
hass.config_entries.flow.async_init(
otbr.DOMAIN, context={"source": "hassio"}, data=HASSIO_DATA
),
hass.config_entries.flow.async_init(
otbr.DOMAIN, context={"source": "hassio"}, data=HASSIO_DATA_2
),
)
expected_data = {
"url": f"http://{HASSIO_DATA.config['host']}:{HASSIO_DATA.config['port']}",
}
assert results[0]["type"] == FlowResultType.CREATE_ENTRY
assert results[0]["title"] == "Home Assistant SkyConnect"
assert results[0]["data"] == expected_data
assert results[0]["options"] == {}
assert results[1]["type"] == FlowResultType.ABORT
assert results[1]["reason"] == "single_instance_allowed"
assert len(hass.config_entries.async_entries(otbr.DOMAIN)) == 1
assert len(mock_setup_entry.mock_calls) == 1
config_entry = hass.config_entries.async_entries(otbr.DOMAIN)[0]
assert config_entry.data == expected_data
assert config_entry.options == {}
assert config_entry.title == "Home Assistant SkyConnect"
assert config_entry.unique_id == HASSIO_DATA.uuid
async def test_hassio_discovery_flow_router_not_setup(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker, addon_info
) -> None: