@@ -1702,6 +1702,44 @@ async def test_setup_raise_not_ready(
17021702 assert entry .reason is None
17031703
17041704
1705+ async def test_setup_not_ready_exponential_backoff (
1706+ hass : HomeAssistant ,
1707+ manager : config_entries .ConfigEntries ,
1708+ freezer : FrozenDateTimeFactory ,
1709+ ) -> None :
1710+ """Test setup retry uses exponential backoff capped at 10 minutes."""
1711+ entry = MockConfigEntry (domain = "test" )
1712+ entry .add_to_hass (hass )
1713+
1714+ attempts = 0
1715+
1716+ async def _mock_setup_entry (hass : HomeAssistant , entry : ConfigEntry ) -> bool :
1717+ nonlocal attempts
1718+ attempts += 1
1719+ raise ConfigEntryNotReady
1720+
1721+ mock_integration (hass , MockModule ("test" , async_setup_entry = _mock_setup_entry ))
1722+ mock_platform (hass , "test.config_flow" , None )
1723+
1724+ await manager .async_setup (entry .entry_id )
1725+ assert attempts == 1
1726+
1727+ expected_waits = [5 , 10 , 20 , 40 , 80 , 160 , 320 , 600 , 600 ]
1728+ for i , wait in enumerate (expected_waits ):
1729+ # Advance to just before the retry should fire
1730+ freezer .tick (wait - 1 )
1731+ async_fire_time_changed (hass )
1732+ await hass .async_block_till_done ()
1733+ assert attempts == i + 1 , f"Retry { i + 1 } fired too early"
1734+
1735+ # Advance past the retry point (+ 1s for jitter)
1736+ freezer .tick (2 )
1737+ async_fire_time_changed (hass )
1738+ await hass .async_block_till_done ()
1739+ assert attempts == i + 2 , f"Retry { i + 1 } did not fire"
1740+ assert entry .state is config_entries .ConfigEntryState .SETUP_RETRY
1741+
1742+
17051743async def test_setup_raise_not_ready_from_exception (
17061744 hass : HomeAssistant ,
17071745 manager : config_entries .ConfigEntries ,
0 commit comments