From 7c01d086e74822fffd301cc129994094489aaa7c Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Sat, 29 Aug 2026 18:43:41 +0930 Subject: [PATCH] [Resource] Fix #34004: `az resource wait`: Raise CLIError on timeout instead of returning it * Initial plan * fix: raise CLIError on wait timeout instead of returning it Co-authored-by: a0x1ab <59631311+a0x1ab@users.noreply.github.com> * fix: raise CLIError on wait timeout; add unit tests Co-authored-by: a0x1ab <59631311+a0x1ab@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: a0x1ab <59631311+a0x1ab@users.noreply.github.com> --- .../cli/core/commands/command_operation.py | 2 +- .../core/tests/test_wait_command_operation.py | 63 +++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 src/azure-cli-core/azure/cli/core/tests/test_wait_command_operation.py diff --git a/src/azure-cli-core/azure/cli/core/commands/command_operation.py b/src/azure-cli-core/azure/cli/core/commands/command_operation.py index 97acd0efac3..21bbe31d5eb 100644 --- a/src/azure-cli-core/azure/cli/core/commands/command_operation.py +++ b/src/azure-cli-core/azure/cli/core/commands/command_operation.py @@ -458,7 +458,7 @@ def wait(cls, command_args, cli_ctx, getter): time.sleep(interval) progress_indicator.end() - return CLIError('Wait operation timed-out after {} seconds'.format(timeout)) + raise CLIError('Wait operation timed-out after {} seconds'.format(timeout)) @staticmethod def _get_provisioning_state(instance): diff --git a/src/azure-cli-core/azure/cli/core/tests/test_wait_command_operation.py b/src/azure-cli-core/azure/cli/core/tests/test_wait_command_operation.py new file mode 100644 index 00000000000..0662181f5b0 --- /dev/null +++ b/src/azure-cli-core/azure/cli/core/tests/test_wait_command_operation.py @@ -0,0 +1,63 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +import unittest +from unittest import mock + +from knack.util import CLIError + +from azure.cli.core.commands.command_operation import WaitCommandOperation +from azure.cli.core.mock import DummyCli + + +class TestWaitCommandOperationTimeout(unittest.TestCase): + + def test_wait_raises_on_timeout(self): + """wait() should raise CLIError on timeout, not return it.""" + cli_ctx = DummyCli() + + # A getter that always returns an instance with no satisfied condition + instance = mock.MagicMock() + instance.provisioning_state = None + getter = mock.MagicMock(return_value=instance) + + command_args = { + 'timeout': 1, + 'interval': 1, + 'created': False, + 'deleted': False, + 'updated': False, + 'exists': False, + 'custom': 'nonExistentProperty', + } + + with self.assertRaises(CLIError) as ctx: + WaitCommandOperation.wait(command_args, cli_ctx=cli_ctx, getter=getter) + + self.assertIn('timed-out', str(ctx.exception)) + + def test_wait_returns_none_on_success(self): + """wait() should return None when the condition is satisfied.""" + cli_ctx = DummyCli() + + # exists=True causes immediate return without inspecting provisioning_state + getter = mock.MagicMock(return_value=mock.MagicMock()) + + command_args = { + 'timeout': 30, + 'interval': 1, + 'created': False, + 'deleted': False, + 'updated': False, + 'exists': True, + 'custom': None, + } + + result = WaitCommandOperation.wait(command_args, cli_ctx=cli_ctx, getter=getter) + self.assertIsNone(result) + + +if __name__ == '__main__': + unittest.main()