diff --git a/homeassistant/helpers/script.py b/homeassistant/helpers/script.py index 1de5600f208..b7e7c05478c 100644 --- a/homeassistant/helpers/script.py +++ b/homeassistant/helpers/script.py @@ -860,12 +860,13 @@ class _QueuedScriptRun(_ScriptRun): {lock_task, stop_task}, return_when=asyncio.FIRST_COMPLETED ) except asyncio.CancelledError: - lock_task.cancel() self._finish() raise + else: + self.lock_acquired = lock_task.done() and not lock_task.cancelled() finally: + lock_task.cancel() stop_task.cancel() - self.lock_acquired = lock_task.done() and not lock_task.cancelled() # If we've been told to stop, then just finish up. Otherwise, we've acquired the # lock so we can go ahead and start the run. diff --git a/tests/helpers/test_script.py b/tests/helpers/test_script.py index 03a91ce1261..dc1a498e465 100644 --- a/tests/helpers/test_script.py +++ b/tests/helpers/test_script.py @@ -3203,6 +3203,37 @@ async def test_script_mode_queued_cancel(hass): raise +async def test_script_mode_queued_stop(hass): + """Test stopping with a queued run.""" + script_obj = script.Script( + hass, + cv.SCRIPT_SCHEMA({"wait_template": "{{ false }}"}), + "Test Name", + "test_domain", + script_mode="queued", + max_runs=3, + ) + wait_started_flag = async_watch_for_action(script_obj, "wait") + + assert not script_obj.is_running + assert script_obj.runs == 0 + + hass.async_create_task(script_obj.async_run(context=Context())) + await asyncio.wait_for(wait_started_flag.wait(), 1) + hass.async_create_task(script_obj.async_run(context=Context())) + await asyncio.sleep(0) + hass.async_create_task(script_obj.async_run(context=Context())) + await asyncio.sleep(0) + + assert script_obj.is_running + assert script_obj.runs == 3 + + await script_obj.async_stop() + + assert not script_obj.is_running + assert script_obj.runs == 0 + + async def test_script_logging(hass, caplog): """Test script logging.""" script_obj = script.Script(hass, [], "Script with % Name", "test_domain")