Skip to content

Commit 70e18fc

Browse files
authored
Fix WiZ Light config flow timeout by properly closing UDP connections (home-assistant#168456)
1 parent 526ddc4 commit 70e18fc

2 files changed

Lines changed: 32 additions & 16 deletions

File tree

homeassistant/components/wiz/config_flow.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ async def _async_connect_discovered_or_abort(self) -> None:
7979
exc_info=True,
8080
)
8181
raise AbortFlow("cannot_connect") from ex
82+
finally:
83+
await bulb.async_close()
8284
self._name = name_from_bulb_type_and_mac(bulbtype, device.mac_address)
8385

8486
async def async_step_discovery_confirm(
@@ -116,6 +118,8 @@ async def async_step_pick_device(
116118
bulbtype = await bulb.get_bulbtype()
117119
except WIZ_CONNECT_EXCEPTIONS:
118120
return self.async_abort(reason="cannot_connect")
121+
finally:
122+
await bulb.async_close()
119123

120124
return self.async_create_entry(
121125
title=name_from_bulb_type_and_mac(bulbtype, device.mac_address),
@@ -180,6 +184,8 @@ async def async_step_user(
180184
title=name,
181185
data=user_input,
182186
)
187+
finally:
188+
await bulb.async_close()
183189

184190
return self.async_show_form(
185191
step_id="user",

tests/components/wiz/test_config_flow.py

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,16 @@
4747

4848
async def test_form(hass: HomeAssistant) -> None:
4949
"""Test we get the form."""
50+
bulb = _mocked_wizlight(None, None, FAKE_DIMMABLE_BULB)
51+
5052
result = await hass.config_entries.flow.async_init(
5153
DOMAIN, context={"source": config_entries.SOURCE_USER}
5254
)
5355
assert result["type"] is FlowResultType.FORM
5456
assert result["errors"] == {}
5557
# Patch functions
5658
with (
57-
_patch_wizlight(),
59+
_patch_wizlight(device=bulb),
5860
patch(
5961
"homeassistant.components.wiz.async_setup_entry",
6062
return_value=True,
@@ -76,6 +78,7 @@ async def test_form(hass: HomeAssistant) -> None:
7678
}
7779
assert len(mock_setup.mock_calls) == 1
7880
assert len(mock_setup_entry.mock_calls) == 1
81+
bulb.async_close.assert_awaited_once()
7982

8083

8184
async def test_user_flow_enters_dns_name(hass: HomeAssistant) -> None:
@@ -137,17 +140,18 @@ async def test_user_form_exceptions(
137140
DOMAIN, context={"source": config_entries.SOURCE_USER}
138141
)
139142

140-
with patch(
141-
"homeassistant.components.wiz.wizlight.getBulbConfig",
142-
side_effect=side_effect,
143-
):
143+
bulb = _mocked_wizlight(None, None, FAKE_DIMMABLE_BULB)
144+
bulb.get_bulbtype = AsyncMock(side_effect=side_effect)
145+
146+
with _patch_wizlight(device=bulb):
144147
result2 = await hass.config_entries.flow.async_configure(
145148
result["flow_id"],
146149
TEST_CONNECTION,
147150
)
148151

149152
assert result2["type"] is FlowResultType.FORM
150153
assert result2["errors"] == {"base": error_base}
154+
bulb.async_close.assert_awaited_once()
151155

152156

153157
async def test_form_updates_unique_id(hass: HomeAssistant) -> None:
@@ -185,17 +189,18 @@ async def test_discovered_by_dhcp_connection_fails(
185189
hass: HomeAssistant, source, data
186190
) -> None:
187191
"""Test we abort on connection failure."""
188-
with patch(
189-
"homeassistant.components.wiz.wizlight.getBulbConfig",
190-
side_effect=WizLightTimeOutError,
191-
):
192+
bulb = _mocked_wizlight(None, None, FAKE_DIMMABLE_BULB)
193+
bulb.get_bulbtype = AsyncMock(side_effect=WizLightTimeOutError)
194+
195+
with _patch_wizlight(device=bulb):
192196
result = await hass.config_entries.flow.async_init(
193197
DOMAIN, context={"source": source}, data=data
194198
)
195199
await hass.async_block_till_done()
196200

197201
assert result["type"] is FlowResultType.ABORT
198202
assert result["reason"] == "cannot_connect"
203+
bulb.async_close.assert_awaited_once()
199204

200205

201206
@pytest.mark.parametrize(
@@ -263,21 +268,22 @@ async def test_discovered_by_dhcp_or_integration_discovery(
263268
hass: HomeAssistant, source, data, bulb_type, extended_white_range, name
264269
) -> None:
265270
"""Test we can configure when discovered from dhcp or discovery."""
266-
with _patch_wizlight(
267-
device=None, extended_white_range=extended_white_range, bulb_type=bulb_type
268-
):
271+
bulb = _mocked_wizlight(None, extended_white_range, bulb_type)
272+
273+
with _patch_wizlight(device=bulb):
269274
result = await hass.config_entries.flow.async_init(
270275
DOMAIN, context={"source": source}, data=data
271276
)
272277
await hass.async_block_till_done()
273278

274279
assert result["type"] is FlowResultType.FORM
275280
assert result["step_id"] == "discovery_confirm"
281+
bulb.async_close.assert_awaited_once()
282+
283+
bulb.async_close.reset_mock()
276284

277285
with (
278-
_patch_wizlight(
279-
device=None, extended_white_range=extended_white_range, bulb_type=bulb_type
280-
),
286+
_patch_wizlight(device=bulb),
281287
patch(
282288
"homeassistant.components.wiz.async_setup_entry",
283289
return_value=True,
@@ -299,6 +305,7 @@ async def test_discovered_by_dhcp_or_integration_discovery(
299305
}
300306
assert len(mock_setup.mock_calls) == 1
301307
assert len(mock_setup_entry.mock_calls) == 1
308+
bulb.async_close.assert_awaited_once()
302309

303310

304311
@pytest.mark.parametrize(
@@ -393,8 +400,10 @@ async def test_setup_via_discovery(hass: HomeAssistant) -> None:
393400
assert result2["step_id"] == "pick_device"
394401
assert not result2["errors"]
395402

403+
bulb = _mocked_wizlight(None, None, FAKE_DIMMABLE_BULB)
404+
396405
with (
397-
_patch_wizlight(),
406+
_patch_wizlight(device=bulb),
398407
patch(
399408
"homeassistant.components.wiz.async_setup", return_value=True
400409
) as mock_setup,
@@ -415,6 +424,7 @@ async def test_setup_via_discovery(hass: HomeAssistant) -> None:
415424
}
416425
assert len(mock_setup.mock_calls) == 1
417426
assert len(mock_setup_entry.mock_calls) == 1
427+
bulb.async_close.assert_awaited_once()
418428

419429
# ignore configured devices
420430
result = await hass.config_entries.flow.async_init(

0 commit comments

Comments
 (0)