Skip to content

[REST] az rest: Add --scope argument#30105

Open
jiasli wants to merge 1 commit intoAzure:devfrom
jiasli:rest-scope
Open

[REST] az rest: Add --scope argument#30105
jiasli wants to merge 1 commit intoAzure:devfrom
jiasli:rest-scope

Conversation

@jiasli
Copy link
Copy Markdown
Member

@jiasli jiasli commented Oct 16, 2024

Related command
az rest

Description
MSAL uses scopes (e.g. https://management.core.windows.net//.default) instead of ADAL-styled resource (e.g. https://management.core.windows.net/).

Since az login and az account get-access-token already support --scope, az rest should do the same.

Testing Guide

az rest -m get -u https://graph.microsoft.com/v1.0/applications/7d32a4a2-122b-458c-93f8-0ac5621b8a20

az rest -m get -u https://graph.microsoft.com/v1.0/applications/7d32a4a2-122b-458c-93f8-0ac5621b8a20 --scope https://graph.microsoft.com//.default

az rest -m get -u https://graph.microsoft.com/v1.0/applications/7d32a4a2-122b-458c-93f8-0ac5621b8a20 --resource https://graph.microsoft.com/

History Notes

[REST] az rest: Add --scope argument

@azure-client-tools-bot-prd
Copy link
Copy Markdown

azure-client-tools-bot-prd bot commented Oct 16, 2024

❌AzureCLI-FullTest
️✔️acr
️✔️2020-09-01-hybrid
️✔️3.12
️✔️3.9
️✔️latest
️✔️3.12
️✔️3.9
️✔️acs
️✔️2020-09-01-hybrid
️✔️3.12
️✔️3.9
️✔️latest
️✔️3.12
️✔️3.9
️✔️advisor
️✔️latest
️✔️3.12
️✔️3.9
️✔️ams
️✔️latest
️✔️3.12
️✔️3.9
️✔️apim
️✔️latest
️✔️3.12
️✔️3.9
️✔️appconfig
️✔️latest
️✔️3.12
️✔️3.9
️✔️appservice
️✔️latest
️✔️3.12
️✔️3.9
️✔️aro
️✔️latest
️✔️3.12
️✔️3.9
️✔️backup
️✔️latest
️✔️3.12
️✔️3.9
️✔️batch
️✔️latest
️✔️3.12
️✔️3.9
️✔️batchai
️✔️latest
️✔️3.12
️✔️3.9
️✔️billing
️✔️latest
️✔️3.12
️✔️3.9
️✔️botservice
️✔️latest
️✔️3.12
️✔️3.9
️✔️cdn
️✔️latest
️✔️3.12
️✔️3.9
️✔️cloud
️✔️latest
️✔️3.12
️✔️3.9
️✔️cognitiveservices
️✔️latest
️✔️3.12
️✔️3.9
️✔️compute_recommender
️✔️latest
️✔️3.12
️✔️3.9
️✔️computefleet
️✔️latest
️✔️3.12
️✔️3.9
️✔️config
️✔️latest
️✔️3.12
️✔️3.9
️✔️configure
️✔️latest
️✔️3.12
️✔️3.9
️✔️consumption
️✔️latest
️✔️3.12
️✔️3.9
️✔️container
️✔️latest
️✔️3.12
️✔️3.9
️✔️containerapp
️✔️latest
️✔️3.12
️✔️3.9
❌core
❌2018-03-01-hybrid
❌3.12
Type Test Case Error Message Line
Failed test_send_raw_requests self = <azure.cli.core.tests.test_util.TestUtils testMethod=test_send_raw_requests>
send_mock = <function send at 0x7fdede7c1940>
get_raw_token_mock = <function get_raw_token at 0x7fdede7c2020>

    @mock.patch.dict('os.environ')
    @mock.patch('azure.cli.core.profile.Profile.get_raw_token', autospec=True)
    @mock.patch('requests.Session.send', autospec=True)
    def test_send_raw_requests(self, send_mock, get_raw_token_mock):
        if 'AZURE_HTTP_USER_AGENT' in os.environ:
            del os.environ['AZURE_HTTP_USER_AGENT']  # Clear env var possibly added by DevOps
    
        return_val = mock.MagicMock()
        return_val.is_ok = True
        send_mock.return_value = return_val
        get_raw_token_mock.return_value = ("Bearer", "eyJ0eXAiOiJKV1", None), None, None
    
        cli_ctx = DummyCli()
        cli_ctx.data = {
            'command': 'rest',
            'safe_params': ['method', 'uri']
        }
        test_arm_active_directory_resource_id = 'https://management.core.windows.net/'
        test_arm_endpoint = 'https://management.azure.com/'
        subscription_id = '00000001-0000-0000-0000-000000000000'
        arm_resource_id = '/subscriptions/{}/resourcegroups/02?api-version=2019-07-01'.format(subscription_id)
        full_arm_rest_url = test_arm_endpoint.rstrip('/') + arm_resource_id
        test_body = '{"b1": "v1"}'
    
        expected_header = {
            'User-Agent': get_az_rest_user_agent(),
            'Accept-Encoding': 'gzip, deflate',
            'Accept': '/',
            'Connection': 'keep-alive',
            'Content-Type': 'application/json',
            'CommandName': 'rest',
            'ParameterSetName': 'method uri',
            'Content-Length': '12'
        }
        expected_header_with_auth = expected_header.copy()
        expected_header_with_auth['Authorization'] = 'Bearer eyJ0eXAiOiJKV1'
    
        # Test basic usage
        # Mock Put Blob https://docs.microsoft.com/en-us/rest/api/storageservices/put-blob
        # Authenticate with service SAS https://docs.microsoft.com/en-us/rest/api/storageservices/create-service-sas
        sas_token = ['sv=2019-02-02', '{"srt": "s"}', "{'ss': 'bf'}"]
        send_raw_request(cli_ctx, 'PUT', 'https://myaccount.blob.core.windows.net/mycontainer/myblob?timeout=30',
                         uri_parameters=sas_token, body=test_body,
                         generated_client_request_id_name=None)
    
        get_raw_token_mock.assert_not_called()
        request = send_mock.call_args[0][1]
        self.assertEqual(request.method, 'PUT')
        self.assertEqual(request.url, 'https://myaccount.blob.core.windows.net/mycontainer/myblob?timeout=30&sv=2019-02-02&srt=s&ss=bf')
        self.assertEqual(request.body, '{"b1": "v1"}')
        # Verify no Authorization header
        self.assertDictEqual(dict(request.headers), expected_header)
        self.assertEqual(send_mock.call_args[1]["verify"], not should_disable_connection_verify())
    
        # Test Authorization header is skipped
        send_raw_request(cli_ctx, 'GET', full_arm_rest_url, body=test_body, skip_authorization_header=True,
                         generated_client_request_id_name=None)
    
        get_raw_token_mock.assert_not_called()
        request = send_mock.call_args[0][1]
        self.assertDictEqual(dict(request.headers), expected_header)
    
        # Test Authorization header is already provided
        send_raw_request(cli_ctx, 'GET', full_arm_rest_url,
                         body=test_body, headers={'Authorization=Basic ABCDE'},
                         generated_client_request_id_name=None)
    
        get_raw_token_mock.assert_not_called()
        request = send_mock.call_args[0][1]
        self.assertDictEqual(dict(request.headers), {**expected_header, 'Authorization': 'Basic ABCDE'})
    
        # Test Authorization header is auto appended
        send_raw_request(cli_ctx, 'GET', full_arm_rest_url,
                         body=test_body,
                         generated_client_request_id_name=None)
    
>       get_raw_token_mock.assert_called_with(mock.ANY, test_arm_active_directory_resource_id, subscription=subscription_id)

src/azure-cli-core/azure/cli/core/tests/test_util.py:310: 
                                        
/opt/hostedtoolcache/Python/3.12.7/x64/lib/python3.12/unittest/mock.py:212: in assert_called_with
    return mock.assert_called_with(*args, **kwargs)
                                       _ 

self = <MagicMock name='get_raw_token' spec='function' id='140595192173664'>
args = (, 'https://management.core.windows.net/')
kwargs = {'subscription': '00000001-0000-0000-0000-000000000000'}
expected = call('', (, 'https://management.core.windows.net/'),&nbsp;{'subscription':&nbsp;'00000001-0000-0000-0000-000000000000'})
actual = call('', (<azure.cli.core._profile.Profile object at 0x7fdede7a6fc0>,), {'scopes': ['https://management.core.windows.net//.default'], 'subscription': '00000001-0000-0000-0000-000000000000'})
_error_message = <function NonCallableMock.assert_called_with.._error_message at 0x7fdede7c2c00>
cause = None

    def assert_called_with(self, /, *args, **kwargs):
        """assert that the last call was made with the specified arguments.
    
        Raises an AssertionError if the args and keyword args passed in are
        different to the last call to the mock."""
        if self.call_args is None:
            expected = self._format_mock_call_signature(args, kwargs)
            actual = 'not called.'
            error_message = ('expected call not found.\nExpected: %s\n  Actual: %s'
                    % (expected, actual))
            raise AssertionError(error_message)
    
        def _error_message():
            msg = self._format_mock_failure_message(args, kwargs)
            return msg
        expected = self._call_matcher(_Call((args, kwargs), two=True))
        actual = self._call_matcher(self.call_args)
        if actual != expected:
            cause = expected if isinstance(expected, Exception) else None
>           raise AssertionError(_error_message()) from cause
E           AssertionError: expected call not found.
E           Expected: get_raw_token(, 'https://management.core.windows.net/',&nbsp;subscription='00000001-0000-0000-0000-000000000000')
E             Actual: get_raw_token(<azure.cli.core._profile.Profile object at 0x7fdede7a6fc0>, scopes=['https://management.core.windows.net//.default'], subscription='00000001-0000-0000-0000-000000000000')

/opt/hostedtoolcache/Python/3.12.7/x64/lib/python3.12/unittest/mock.py:949: AssertionError
src/azure-cli-core/azure/cli/core/tests/test_util.py:233
❌3.9
Type Test Case Error Message Line
Failed test_send_raw_requests self = <azure.cli.core.tests.test_util.TestUtils testMethod=test_send_raw_requests>
send_mock = <function send at 0x7f4975bef0d0>
get_raw_token_mock = <function get_raw_token at 0x7f4975bef5e0>

    @mock.patch.dict('os.environ')
    @mock.patch('azure.cli.core.profile.Profile.get_raw_token', autospec=True)
    @mock.patch('requests.Session.send', autospec=True)
    def test_send_raw_requests(self, send_mock, get_raw_token_mock):
        if 'AZURE_HTTP_USER_AGENT' in os.environ:
            del os.environ['AZURE_HTTP_USER_AGENT']  # Clear env var possibly added by DevOps
    
        return_val = mock.MagicMock()
        return_val.is_ok = True
        send_mock.return_value = return_val
        get_raw_token_mock.return_value = ("Bearer", "eyJ0eXAiOiJKV1", None), None, None
    
        cli_ctx = DummyCli()
        cli_ctx.data = {
            'command': 'rest',
            'safe_params': ['method', 'uri']
        }
        test_arm_active_directory_resource_id = 'https://management.core.windows.net/'
        test_arm_endpoint = 'https://management.azure.com/'
        subscription_id = '00000001-0000-0000-0000-000000000000'
        arm_resource_id = '/subscriptions/{}/resourcegroups/02?api-version=2019-07-01'.format(subscription_id)
        full_arm_rest_url = test_arm_endpoint.rstrip('/') + arm_resource_id
        test_body = '{"b1": "v1"}'
    
        expected_header = {
            'User-Agent': get_az_rest_user_agent(),
            'Accept-Encoding': 'gzip, deflate',
            'Accept': '/',
            'Connection': 'keep-alive',
            'Content-Type': 'application/json',
            'CommandName': 'rest',
            'ParameterSetName': 'method uri',
            'Content-Length': '12'
        }
        expected_header_with_auth = expected_header.copy()
        expected_header_with_auth['Authorization'] = 'Bearer eyJ0eXAiOiJKV1'
    
        # Test basic usage
        # Mock Put Blob https://docs.microsoft.com/en-us/rest/api/storageservices/put-blob
        # Authenticate with service SAS https://docs.microsoft.com/en-us/rest/api/storageservices/create-service-sas
        sas_token = ['sv=2019-02-02', '{"srt": "s"}', "{'ss': 'bf'}"]
        send_raw_request(cli_ctx, 'PUT', 'https://myaccount.blob.core.windows.net/mycontainer/myblob?timeout=30',
                         uri_parameters=sas_token, body=test_body,
                         generated_client_request_id_name=None)
    
        get_raw_token_mock.assert_not_called()
        request = send_mock.call_args[0][1]
        self.assertEqual(request.method, 'PUT')
        self.assertEqual(request.url, 'https://myaccount.blob.core.windows.net/mycontainer/myblob?timeout=30&sv=2019-02-02&srt=s&ss=bf')
        self.assertEqual(request.body, '{"b1": "v1"}')
        # Verify no Authorization header
        self.assertDictEqual(dict(request.headers), expected_header)
        self.assertEqual(send_mock.call_args[1]["verify"], not should_disable_connection_verify())
    
        # Test Authorization header is skipped
        send_raw_request(cli_ctx, 'GET', full_arm_rest_url, body=test_body, skip_authorization_header=True,
                         generated_client_request_id_name=None)
    
        get_raw_token_mock.assert_not_called()
        request = send_mock.call_args[0][1]
        self.assertDictEqual(dict(request.headers), expected_header)
    
        # Test Authorization header is already provided
        send_raw_request(cli_ctx, 'GET', full_arm_rest_url,
                         body=test_body, headers={'Authorization=Basic ABCDE'},
                         generated_client_request_id_name=None)
    
        get_raw_token_mock.assert_not_called()
        request = send_mock.call_args[0][1]
        self.assertDictEqual(dict(request.headers), {**expected_header, 'Authorization': 'Basic ABCDE'})
    
        # Test Authorization header is auto appended
        send_raw_request(cli_ctx, 'GET', full_arm_rest_url,
                         body=test_body,
                         generated_client_request_id_name=None)
    
>       get_raw_token_mock.assert_called_with(mock.ANY, test_arm_active_directory_resource_id, subscription=subscription_id)

src/azure-cli-core/azure/cli/core/tests/test_util.py:310: 
                                        
/opt/hostedtoolcache/Python/3.9.20/x64/lib/python3.9/unittest/mock.py:200: in assert_called_with
    return mock.assert_called_with(*args, **kwargs)
                                       _ 

self = <MagicMock name='get_raw_token' spec='function' id='139953484801696'>
args = (, 'https://management.core.windows.net/')
kwargs = {'subscription': '00000001-0000-0000-0000-000000000000'}
expected = call('', (, 'https://management.core.windows.net/'),&nbsp;{'subscription':&nbsp;'00000001-0000-0000-0000-000000000000'})
actual = call('', (<azure.cli.core._profile.Profile object at 0x7f4975c02b50>,), {'scopes': ['https://management.core.windows.net//.default'], 'subscription': '00000001-0000-0000-0000-000000000000'})
_error_message = <function NonCallableMock.assert_called_with.._error_message at 0x7f4975c11700>
cause = None

    def assert_called_with(self, /, *args, **kwargs):
        """assert that the last call was made with the specified arguments.
    
        Raises an AssertionError if the args and keyword args passed in are
        different to the last call to the mock."""
        if self.call_args is None:
            expected = self._format_mock_call_signature(args, kwargs)
            actual = 'not called.'
            error_message = ('expected call not found.\nExpected: %s\nActual: %s'
                    % (expected, actual))
            raise AssertionError(error_message)
    
        def _error_message():
            msg = self._format_mock_failure_message(args, kwargs)
            return msg
        expected = self._call_matcher(_Call((args, kwargs), two=True))
        actual = self._call_matcher(self.call_args)
        if actual != expected:
            cause = expected if isinstance(expected, Exception) else None
>           raise AssertionError(_error_message()) from cause
E           AssertionError: expected call not found.
E           Expected: get_raw_token(, 'https://management.core.windows.net/',&nbsp;subscription='00000001-0000-0000-0000-000000000000')
E           Actual: get_raw_token(<azure.cli.core._profile.Profile object at 0x7f4975c02b50>, scopes=['https://management.core.windows.net//.default'], subscription='00000001-0000-0000-0000-000000000000')

/opt/hostedtoolcache/Python/3.9.20/x64/lib/python3.9/unittest/mock.py:907: AssertionError
src/azure-cli-core/azure/cli/core/tests/test_util.py:233
❌2019-03-01-hybrid
❌3.12
Type Test Case Error Message Line
Failed test_send_raw_requests self = <azure.cli.core.tests.test_util.TestUtils testMethod=test_send_raw_requests>
send_mock = <function send at 0x7fba2d93b240>
get_raw_token_mock = <function get_raw_token at 0x7fba2d93b7e0>

    @mock.patch.dict('os.environ')
    @mock.patch('azure.cli.core.profile.Profile.get_raw_token', autospec=True)
    @mock.patch('requests.Session.send', autospec=True)
    def test_send_raw_requests(self, send_mock, get_raw_token_mock):
        if 'AZURE_HTTP_USER_AGENT' in os.environ:
            del os.environ['AZURE_HTTP_USER_AGENT']  # Clear env var possibly added by DevOps
    
        return_val = mock.MagicMock()
        return_val.is_ok = True
        send_mock.return_value = return_val
        get_raw_token_mock.return_value = ("Bearer", "eyJ0eXAiOiJKV1", None), None, None
    
        cli_ctx = DummyCli()
        cli_ctx.data = {
            'command': 'rest',
            'safe_params': ['method', 'uri']
        }
        test_arm_active_directory_resource_id = 'https://management.core.windows.net/'
        test_arm_endpoint = 'https://management.azure.com/'
        subscription_id = '00000001-0000-0000-0000-000000000000'
        arm_resource_id = '/subscriptions/{}/resourcegroups/02?api-version=2019-07-01'.format(subscription_id)
        full_arm_rest_url = test_arm_endpoint.rstrip('/') + arm_resource_id
        test_body = '{"b1": "v1"}'
    
        expected_header = {
            'User-Agent': get_az_rest_user_agent(),
            'Accept-Encoding': 'gzip, deflate',
            'Accept': '/',
            'Connection': 'keep-alive',
            'Content-Type': 'application/json',
            'CommandName': 'rest',
            'ParameterSetName': 'method uri',
            'Content-Length': '12'
        }
        expected_header_with_auth = expected_header.copy()
        expected_header_with_auth['Authorization'] = 'Bearer eyJ0eXAiOiJKV1'
    
        # Test basic usage
        # Mock Put Blob https://docs.microsoft.com/en-us/rest/api/storageservices/put-blob
        # Authenticate with service SAS https://docs.microsoft.com/en-us/rest/api/storageservices/create-service-sas
        sas_token = ['sv=2019-02-02', '{"srt": "s"}', "{'ss': 'bf'}"]
        send_raw_request(cli_ctx, 'PUT', 'https://myaccount.blob.core.windows.net/mycontainer/myblob?timeout=30',
                         uri_parameters=sas_token, body=test_body,
                         generated_client_request_id_name=None)
    
        get_raw_token_mock.assert_not_called()
        request = send_mock.call_args[0][1]
        self.assertEqual(request.method, 'PUT')
        self.assertEqual(request.url, 'https://myaccount.blob.core.windows.net/mycontainer/myblob?timeout=30&sv=2019-02-02&srt=s&ss=bf')
        self.assertEqual(request.body, '{"b1": "v1"}')
        # Verify no Authorization header
        self.assertDictEqual(dict(request.headers), expected_header)
        self.assertEqual(send_mock.call_args[1]["verify"], not should_disable_connection_verify())
    
        # Test Authorization header is skipped
        send_raw_request(cli_ctx, 'GET', full_arm_rest_url, body=test_body, skip_authorization_header=True,
                         generated_client_request_id_name=None)
    
        get_raw_token_mock.assert_not_called()
        request = send_mock.call_args[0][1]
        self.assertDictEqual(dict(request.headers), expected_header)
    
        # Test Authorization header is already provided
        send_raw_request(cli_ctx, 'GET', full_arm_rest_url,
                         body=test_body, headers={'Authorization=Basic ABCDE'},
                         generated_client_request_id_name=None)
    
        get_raw_token_mock.assert_not_called()
        request = send_mock.call_args[0][1]
        self.assertDictEqual(dict(request.headers), {**expected_header, 'Authorization': 'Basic ABCDE'})
    
        # Test Authorization header is auto appended
        send_raw_request(cli_ctx, 'GET', full_arm_rest_url,
                         body=test_body,
                         generated_client_request_id_name=None)
    
>       get_raw_token_mock.assert_called_with(mock.ANY, test_arm_active_directory_resource_id, subscription=subscription_id)

src/azure-cli-core/azure/cli/core/tests/test_util.py:310: 
                                        
/opt/hostedtoolcache/Python/3.12.7/x64/lib/python3.12/unittest/mock.py:212: in assert_called_with
    return mock.assert_called_with(*args, **kwargs)
                                       _ 

self = <MagicMock name='get_raw_token' spec='function' id='140437605448256'>
args = (, 'https://management.core.windows.net/')
kwargs = {'subscription': '00000001-0000-0000-0000-000000000000'}
expected = call('', (, 'https://management.core.windows.net/'),&nbsp;{'subscription':&nbsp;'00000001-0000-0000-0000-000000000000'})
actual = call('', (<azure.cli.core._profile.Profile object at 0x7fba2d977a70>,), {'scopes': ['https://management.core.windows.net//.default'], 'subscription': '00000001-0000-0000-0000-000000000000'})
_error_message = <function NonCallableMock.assert_called_with.._error_message at 0x7fba2d93afc0>
cause = None

    def assert_called_with(self, /, *args, **kwargs):
        """assert that the last call was made with the specified arguments.
    
        Raises an AssertionError if the args and keyword args passed in are
        different to the last call to the mock."""
        if self.call_args is None:
            expected = self._format_mock_call_signature(args, kwargs)
            actual = 'not called.'
            error_message = ('expected call not found.\nExpected: %s\n  Actual: %s'
                    % (expected, actual))
            raise AssertionError(error_message)
    
        def _error_message():
            msg = self._format_mock_failure_message(args, kwargs)
            return msg
        expected = self._call_matcher(_Call((args, kwargs), two=True))
        actual = self._call_matcher(self.call_args)
        if actual != expected:
            cause = expected if isinstance(expected, Exception) else None
>           raise AssertionError(_error_message()) from cause
E           AssertionError: expected call not found.
E           Expected: get_raw_token(, 'https://management.core.windows.net/',&nbsp;subscription='00000001-0000-0000-0000-000000000000')
E             Actual: get_raw_token(<azure.cli.core._profile.Profile object at 0x7fba2d977a70>, scopes=['https://management.core.windows.net//.default'], subscription='00000001-0000-0000-0000-000000000000')

/opt/hostedtoolcache/Python/3.12.7/x64/lib/python3.12/unittest/mock.py:949: AssertionError
src/azure-cli-core/azure/cli/core/tests/test_util.py:233
❌3.9
Type Test Case Error Message Line
Failed test_send_raw_requests self = <azure.cli.core.tests.test_util.TestUtils testMethod=test_send_raw_requests>
send_mock = <function send at 0x7f24cfe065e0>
get_raw_token_mock = <function get_raw_token at 0x7f24cfe06af0>

    @mock.patch.dict('os.environ')
    @mock.patch('azure.cli.core.profile.Profile.get_raw_token', autospec=True)
    @mock.patch('requests.Session.send', autospec=True)
    def test_send_raw_requests(self, send_mock, get_raw_token_mock):
        if 'AZURE_HTTP_USER_AGENT' in os.environ:
            del os.environ['AZURE_HTTP_USER_AGENT']  # Clear env var possibly added by DevOps
    
        return_val = mock.MagicMock()
        return_val.is_ok = True
        send_mock.return_value = return_val
        get_raw_token_mock.return_value = ("Bearer", "eyJ0eXAiOiJKV1", None), None, None
    
        cli_ctx = DummyCli()
        cli_ctx.data = {
            'command': 'rest',
            'safe_params': ['method', 'uri']
        }
        test_arm_active_directory_resource_id = 'https://management.core.windows.net/'
        test_arm_endpoint = 'https://management.azure.com/'
        subscription_id = '00000001-0000-0000-0000-000000000000'
        arm_resource_id = '/subscriptions/{}/resourcegroups/02?api-version=2019-07-01'.format(subscription_id)
        full_arm_rest_url = test_arm_endpoint.rstrip('/') + arm_resource_id
        test_body = '{"b1": "v1"}'
    
        expected_header = {
            'User-Agent': get_az_rest_user_agent(),
            'Accept-Encoding': 'gzip, deflate',
            'Accept': '/',
            'Connection': 'keep-alive',
            'Content-Type': 'application/json',
            'CommandName': 'rest',
            'ParameterSetName': 'method uri',
            'Content-Length': '12'
        }
        expected_header_with_auth = expected_header.copy()
        expected_header_with_auth['Authorization'] = 'Bearer eyJ0eXAiOiJKV1'
    
        # Test basic usage
        # Mock Put Blob https://docs.microsoft.com/en-us/rest/api/storageservices/put-blob
        # Authenticate with service SAS https://docs.microsoft.com/en-us/rest/api/storageservices/create-service-sas
        sas_token = ['sv=2019-02-02', '{"srt": "s"}', "{'ss': 'bf'}"]
        send_raw_request(cli_ctx, 'PUT', 'https://myaccount.blob.core.windows.net/mycontainer/myblob?timeout=30',
                         uri_parameters=sas_token, body=test_body,
                         generated_client_request_id_name=None)
    
        get_raw_token_mock.assert_not_called()
        request = send_mock.call_args[0][1]
        self.assertEqual(request.method, 'PUT')
        self.assertEqual(request.url, 'https://myaccount.blob.core.windows.net/mycontainer/myblob?timeout=30&sv=2019-02-02&srt=s&ss=bf')
        self.assertEqual(request.body, '{"b1": "v1"}')
        # Verify no Authorization header
        self.assertDictEqual(dict(request.headers), expected_header)
        self.assertEqual(send_mock.call_args[1]["verify"], not should_disable_connection_verify())
    
        # Test Authorization header is skipped
        send_raw_request(cli_ctx, 'GET', full_arm_rest_url, body=test_body, skip_authorization_header=True,
                         generated_client_request_id_name=None)
    
        get_raw_token_mock.assert_not_called()
        request = send_mock.call_args[0][1]
        self.assertDictEqual(dict(request.headers), expected_header)
    
        # Test Authorization header is already provided
        send_raw_request(cli_ctx, 'GET', full_arm_rest_url,
                         body=test_body, headers={'Authorization=Basic ABCDE'},
                         generated_client_request_id_name=None)
    
        get_raw_token_mock.assert_not_called()
        request = send_mock.call_args[0][1]
        self.assertDictEqual(dict(request.headers), {**expected_header, 'Authorization': 'Basic ABCDE'})
    
        # Test Authorization header is auto appended
        send_raw_request(cli_ctx, 'GET', full_arm_rest_url,
                         body=test_body,
                         generated_client_request_id_name=None)
    
>       get_raw_token_mock.assert_called_with(mock.ANY, test_arm_active_directory_resource_id, subscription=subscription_id)

src/azure-cli-core/azure/cli/core/tests/test_util.py:310: 
                                        
/opt/hostedtoolcache/Python/3.9.20/x64/lib/python3.9/unittest/mock.py:200: in assert_called_with
    return mock.assert_called_with(*args, **kwargs)
                                       _ 

self = <MagicMock name='get_raw_token' spec='function' id='139796082732768'>
args = (, 'https://management.core.windows.net/')
kwargs = {'subscription': '00000001-0000-0000-0000-000000000000'}
expected = call('', (, 'https://management.core.windows.net/'),&nbsp;{'subscription':&nbsp;'00000001-0000-0000-0000-000000000000'})
actual = call('', (<azure.cli.core._profile.Profile object at 0x7f24cfdb1dc0>,), {'scopes': ['https://management.core.windows.net//.default'], 'subscription': '00000001-0000-0000-0000-000000000000'})
_error_message = <function NonCallableMock.assert_called_with.._error_message at 0x7f24cfdb2a60>
cause = None

    def assert_called_with(self, /, *args, **kwargs):
        """assert that the last call was made with the specified arguments.
    
        Raises an AssertionError if the args and keyword args passed in are
        different to the last call to the mock."""
        if self.call_args is None:
            expected = self._format_mock_call_signature(args, kwargs)
            actual = 'not called.'
            error_message = ('expected call not found.\nExpected: %s\nActual: %s'
                    % (expected, actual))
            raise AssertionError(error_message)
    
        def _error_message():
            msg = self._format_mock_failure_message(args, kwargs)
            return msg
        expected = self._call_matcher(_Call((args, kwargs), two=True))
        actual = self._call_matcher(self.call_args)
        if actual != expected:
            cause = expected if isinstance(expected, Exception) else None
>           raise AssertionError(_error_message()) from cause
E           AssertionError: expected call not found.
E           Expected: get_raw_token(, 'https://management.core.windows.net/',&nbsp;subscription='00000001-0000-0000-0000-000000000000')
E           Actual: get_raw_token(<azure.cli.core._profile.Profile object at 0x7f24cfdb1dc0>, scopes=['https://management.core.windows.net//.default'], subscription='00000001-0000-0000-0000-000000000000')

/opt/hostedtoolcache/Python/3.9.20/x64/lib/python3.9/unittest/mock.py:907: AssertionError
src/azure-cli-core/azure/cli/core/tests/test_util.py:233
❌2020-09-01-hybrid
❌3.12
Type Test Case Error Message Line
Failed test_send_raw_requests self = <azure.cli.core.tests.test_util.TestUtils testMethod=test_send_raw_requests>
send_mock = <function send at 0x7f5df8163e20>
get_raw_token_mock = <function get_raw_token at 0x7f5df7fa8540>

    @mock.patch.dict('os.environ')
    @mock.patch('azure.cli.core.profile.Profile.get_raw_token', autospec=True)
    @mock.patch('requests.Session.send', autospec=True)
    def test_send_raw_requests(self, send_mock, get_raw_token_mock):
        if 'AZURE_HTTP_USER_AGENT' in os.environ:
            del os.environ['AZURE_HTTP_USER_AGENT']  # Clear env var possibly added by DevOps
    
        return_val = mock.MagicMock()
        return_val.is_ok = True
        send_mock.return_value = return_val
        get_raw_token_mock.return_value = ("Bearer", "eyJ0eXAiOiJKV1", None), None, None
    
        cli_ctx = DummyCli()
        cli_ctx.data = {
            'command': 'rest',
            'safe_params': ['method', 'uri']
        }
        test_arm_active_directory_resource_id = 'https://management.core.windows.net/'
        test_arm_endpoint = 'https://management.azure.com/'
        subscription_id = '00000001-0000-0000-0000-000000000000'
        arm_resource_id = '/subscriptions/{}/resourcegroups/02?api-version=2019-07-01'.format(subscription_id)
        full_arm_rest_url = test_arm_endpoint.rstrip('/') + arm_resource_id
        test_body = '{"b1": "v1"}'
    
        expected_header = {
            'User-Agent': get_az_rest_user_agent(),
            'Accept-Encoding': 'gzip, deflate',
            'Accept': '/',
            'Connection': 'keep-alive',
            'Content-Type': 'application/json',
            'CommandName': 'rest',
            'ParameterSetName': 'method uri',
            'Content-Length': '12'
        }
        expected_header_with_auth = expected_header.copy()
        expected_header_with_auth['Authorization'] = 'Bearer eyJ0eXAiOiJKV1'
    
        # Test basic usage
        # Mock Put Blob https://docs.microsoft.com/en-us/rest/api/storageservices/put-blob
        # Authenticate with service SAS https://docs.microsoft.com/en-us/rest/api/storageservices/create-service-sas
        sas_token = ['sv=2019-02-02', '{"srt": "s"}', "{'ss': 'bf'}"]
        send_raw_request(cli_ctx, 'PUT', 'https://myaccount.blob.core.windows.net/mycontainer/myblob?timeout=30',
                         uri_parameters=sas_token, body=test_body,
                         generated_client_request_id_name=None)
    
        get_raw_token_mock.assert_not_called()
        request = send_mock.call_args[0][1]
        self.assertEqual(request.method, 'PUT')
        self.assertEqual(request.url, 'https://myaccount.blob.core.windows.net/mycontainer/myblob?timeout=30&sv=2019-02-02&srt=s&ss=bf')
        self.assertEqual(request.body, '{"b1": "v1"}')
        # Verify no Authorization header
        self.assertDictEqual(dict(request.headers), expected_header)
        self.assertEqual(send_mock.call_args[1]["verify"], not should_disable_connection_verify())
    
        # Test Authorization header is skipped
        send_raw_request(cli_ctx, 'GET', full_arm_rest_url, body=test_body, skip_authorization_header=True,
                         generated_client_request_id_name=None)
    
        get_raw_token_mock.assert_not_called()
        request = send_mock.call_args[0][1]
        self.assertDictEqual(dict(request.headers), expected_header)
    
        # Test Authorization header is already provided
        send_raw_request(cli_ctx, 'GET', full_arm_rest_url,
                         body=test_body, headers={'Authorization=Basic ABCDE'},
                         generated_client_request_id_name=None)
    
        get_raw_token_mock.assert_not_called()
        request = send_mock.call_args[0][1]
        self.assertDictEqual(dict(request.headers), {**expected_header, 'Authorization': 'Basic ABCDE'})
    
        # Test Authorization header is auto appended
        send_raw_request(cli_ctx, 'GET', full_arm_rest_url,
                         body=test_body,
                         generated_client_request_id_name=None)
    
>       get_raw_token_mock.assert_called_with(mock.ANY, test_arm_active_directory_resource_id, subscription=subscription_id)

src/azure-cli-core/azure/cli/core/tests/test_util.py:310: 
                                        
/opt/hostedtoolcache/Python/3.12.7/x64/lib/python3.12/unittest/mock.py:212: in assert_called_with
    return mock.assert_called_with(*args, **kwargs)
                                       _ 

self = <MagicMock name='get_raw_token' spec='function' id='140041570293216'>
args = (, 'https://management.core.windows.net/')
kwargs = {'subscription': '00000001-0000-0000-0000-000000000000'}
expected = call('', (, 'https://management.core.windows.net/'),&nbsp;{'subscription':&nbsp;'00000001-0000-0000-0000-000000000000'})
actual = call('', (<azure.cli.core._profile.Profile object at 0x7f5df800c7d0>,), {'scopes': ['https://management.core.windows.net//.default'], 'subscription': '00000001-0000-0000-0000-000000000000'})
_error_message = <function NonCallableMock.assert_called_with.._error_message at 0x7f5df8163c40>
cause = None

    def assert_called_with(self, /, *args, **kwargs):
        """assert that the last call was made with the specified arguments.
    
        Raises an AssertionError if the args and keyword args passed in are
        different to the last call to the mock."""
        if self.call_args is None:
            expected = self._format_mock_call_signature(args, kwargs)
            actual = 'not called.'
            error_message = ('expected call not found.\nExpected: %s\n  Actual: %s'
                    % (expected, actual))
            raise AssertionError(error_message)
    
        def _error_message():
            msg = self._format_mock_failure_message(args, kwargs)
            return msg
        expected = self._call_matcher(_Call((args, kwargs), two=True))
        actual = self._call_matcher(self.call_args)
        if actual != expected:
            cause = expected if isinstance(expected, Exception) else None
>           raise AssertionError(_error_message()) from cause
E           AssertionError: expected call not found.
E           Expected: get_raw_token(, 'https://management.core.windows.net/',&nbsp;subscription='00000001-0000-0000-0000-000000000000')
E             Actual: get_raw_token(<azure.cli.core._profile.Profile object at 0x7f5df800c7d0>, scopes=['https://management.core.windows.net//.default'], subscription='00000001-0000-0000-0000-000000000000')

/opt/hostedtoolcache/Python/3.12.7/x64/lib/python3.12/unittest/mock.py:949: AssertionError
src/azure-cli-core/azure/cli/core/tests/test_util.py:233
❌3.9
Type Test Case Error Message Line
Failed test_send_raw_requests self = <azure.cli.core.tests.test_util.TestUtils testMethod=test_send_raw_requests>
send_mock = <function send at 0x7f45d63ad430>
get_raw_token_mock = <function get_raw_token at 0x7f45d63ad940>

    @mock.patch.dict('os.environ')
    @mock.patch('azure.cli.core.profile.Profile.get_raw_token', autospec=True)
    @mock.patch('requests.Session.send', autospec=True)
    def test_send_raw_requests(self, send_mock, get_raw_token_mock):
        if 'AZURE_HTTP_USER_AGENT' in os.environ:
            del os.environ['AZURE_HTTP_USER_AGENT']  # Clear env var possibly added by DevOps
    
        return_val = mock.MagicMock()
        return_val.is_ok = True
        send_mock.return_value = return_val
        get_raw_token_mock.return_value = ("Bearer", "eyJ0eXAiOiJKV1", None), None, None
    
        cli_ctx = DummyCli()
        cli_ctx.data = {
            'command': 'rest',
            'safe_params': ['method', 'uri']
        }
        test_arm_active_directory_resource_id = 'https://management.core.windows.net/'
        test_arm_endpoint = 'https://management.azure.com/'
        subscription_id = '00000001-0000-0000-0000-000000000000'
        arm_resource_id = '/subscriptions/{}/resourcegroups/02?api-version=2019-07-01'.format(subscription_id)
        full_arm_rest_url = test_arm_endpoint.rstrip('/') + arm_resource_id
        test_body = '{"b1": "v1"}'
    
        expected_header = {
            'User-Agent': get_az_rest_user_agent(),
            'Accept-Encoding': 'gzip, deflate',
            'Accept': '/',
            'Connection': 'keep-alive',
            'Content-Type': 'application/json',
            'CommandName': 'rest',
            'ParameterSetName': 'method uri',
            'Content-Length': '12'
        }
        expected_header_with_auth = expected_header.copy()
        expected_header_with_auth['Authorization'] = 'Bearer eyJ0eXAiOiJKV1'
    
        # Test basic usage
        # Mock Put Blob https://docs.microsoft.com/en-us/rest/api/storageservices/put-blob
        # Authenticate with service SAS https://docs.microsoft.com/en-us/rest/api/storageservices/create-service-sas
        sas_token = ['sv=2019-02-02', '{"srt": "s"}', "{'ss': 'bf'}"]
        send_raw_request(cli_ctx, 'PUT', 'https://myaccount.blob.core.windows.net/mycontainer/myblob?timeout=30',
                         uri_parameters=sas_token, body=test_body,
                         generated_client_request_id_name=None)
    
        get_raw_token_mock.assert_not_called()
        request = send_mock.call_args[0][1]
        self.assertEqual(request.method, 'PUT')
        self.assertEqual(request.url, 'https://myaccount.blob.core.windows.net/mycontainer/myblob?timeout=30&sv=2019-02-02&srt=s&ss=bf')
        self.assertEqual(request.body, '{"b1": "v1"}')
        # Verify no Authorization header
        self.assertDictEqual(dict(request.headers), expected_header)
        self.assertEqual(send_mock.call_args[1]["verify"], not should_disable_connection_verify())
    
        # Test Authorization header is skipped
        send_raw_request(cli_ctx, 'GET', full_arm_rest_url, body=test_body, skip_authorization_header=True,
                         generated_client_request_id_name=None)
    
        get_raw_token_mock.assert_not_called()
        request = send_mock.call_args[0][1]
        self.assertDictEqual(dict(request.headers), expected_header)
    
        # Test Authorization header is already provided
        send_raw_request(cli_ctx, 'GET', full_arm_rest_url,
                         body=test_body, headers={'Authorization=Basic ABCDE'},
                         generated_client_request_id_name=None)
    
        get_raw_token_mock.assert_not_called()
        request = send_mock.call_args[0][1]
        self.assertDictEqual(dict(request.headers), {**expected_header, 'Authorization': 'Basic ABCDE'})
    
        # Test Authorization header is auto appended
        send_raw_request(cli_ctx, 'GET', full_arm_rest_url,
                         body=test_body,
                         generated_client_request_id_name=None)
    
>       get_raw_token_mock.assert_called_with(mock.ANY, test_arm_active_directory_resource_id, subscription=subscription_id)

src/azure-cli-core/azure/cli/core/tests/test_util.py:310: 
                                        
/opt/hostedtoolcache/Python/3.9.20/x64/lib/python3.9/unittest/mock.py:200: in assert_called_with
    return mock.assert_called_with(*args, **kwargs)
                                       _ 

self = <MagicMock name='get_raw_token' spec='function' id='139937923243744'>
args = (, 'https://management.core.windows.net/')
kwargs = {'subscription': '00000001-0000-0000-0000-000000000000'}
expected = call('', (, 'https://management.core.windows.net/'),&nbsp;{'subscription':&nbsp;'00000001-0000-0000-0000-000000000000'})
actual = call('', (<azure.cli.core._profile.Profile object at 0x7f45d6356b20>,), {'scopes': ['https://management.core.windows.net//.default'], 'subscription': '00000001-0000-0000-0000-000000000000'})
_error_message = <function NonCallableMock.assert_called_with.._error_message at 0x7f45d63608b0>
cause = None

    def assert_called_with(self, /, *args, **kwargs):
        """assert that the last call was made with the specified arguments.
    
        Raises an AssertionError if the args and keyword args passed in are
        different to the last call to the mock."""
        if self.call_args is None:
            expected = self._format_mock_call_signature(args, kwargs)
            actual = 'not called.'
            error_message = ('expected call not found.\nExpected: %s\nActual: %s'
                    % (expected, actual))
            raise AssertionError(error_message)
    
        def _error_message():
            msg = self._format_mock_failure_message(args, kwargs)
            return msg
        expected = self._call_matcher(_Call((args, kwargs), two=True))
        actual = self._call_matcher(self.call_args)
        if actual != expected:
            cause = expected if isinstance(expected, Exception) else None
>           raise AssertionError(_error_message()) from cause
E           AssertionError: expected call not found.
E           Expected: get_raw_token(, 'https://management.core.windows.net/',&nbsp;subscription='00000001-0000-0000-0000-000000000000')
E           Actual: get_raw_token(<azure.cli.core._profile.Profile object at 0x7f45d6356b20>, scopes=['https://management.core.windows.net//.default'], subscription='00000001-0000-0000-0000-000000000000')

/opt/hostedtoolcache/Python/3.9.20/x64/lib/python3.9/unittest/mock.py:907: AssertionError
src/azure-cli-core/azure/cli/core/tests/test_util.py:233
❌latest
❌3.12
Type Test Case Error Message Line
Failed test_send_raw_requests self = <azure.cli.core.tests.test_util.TestUtils testMethod=test_send_raw_requests>
send_mock = <function send at 0x7efeb69c7420>
get_raw_token_mock = <function get_raw_token at 0x7efeb69c7b00>

    @mock.patch.dict('os.environ')
    @mock.patch('azure.cli.core.profile.Profile.get_raw_token', autospec=True)
    @mock.patch('requests.Session.send', autospec=True)
    def test_send_raw_requests(self, send_mock, get_raw_token_mock):
        if 'AZURE_HTTP_USER_AGENT' in os.environ:
            del os.environ['AZURE_HTTP_USER_AGENT']  # Clear env var possibly added by DevOps
    
        return_val = mock.MagicMock()
        return_val.is_ok = True
        send_mock.return_value = return_val
        get_raw_token_mock.return_value = ("Bearer", "eyJ0eXAiOiJKV1", None), None, None
    
        cli_ctx = DummyCli()
        cli_ctx.data = {
            'command': 'rest',
            'safe_params': ['method', 'uri']
        }
        test_arm_active_directory_resource_id = 'https://management.core.windows.net/'
        test_arm_endpoint = 'https://management.azure.com/'
        subscription_id = '00000001-0000-0000-0000-000000000000'
        arm_resource_id = '/subscriptions/{}/resourcegroups/02?api-version=2019-07-01'.format(subscription_id)
        full_arm_rest_url = test_arm_endpoint.rstrip('/') + arm_resource_id
        test_body = '{"b1": "v1"}'
    
        expected_header = {
            'User-Agent': get_az_rest_user_agent(),
            'Accept-Encoding': 'gzip, deflate',
            'Accept': '/',
            'Connection': 'keep-alive',
            'Content-Type': 'application/json',
            'CommandName': 'rest',
            'ParameterSetName': 'method uri',
            'Content-Length': '12'
        }
        expected_header_with_auth = expected_header.copy()
        expected_header_with_auth['Authorization'] = 'Bearer eyJ0eXAiOiJKV1'
    
        # Test basic usage
        # Mock Put Blob https://docs.microsoft.com/en-us/rest/api/storageservices/put-blob
        # Authenticate with service SAS https://docs.microsoft.com/en-us/rest/api/storageservices/create-service-sas
        sas_token = ['sv=2019-02-02', '{"srt": "s"}', "{'ss': 'bf'}"]
        send_raw_request(cli_ctx, 'PUT', 'https://myaccount.blob.core.windows.net/mycontainer/myblob?timeout=30',
                         uri_parameters=sas_token, body=test_body,
                         generated_client_request_id_name=None)
    
        get_raw_token_mock.assert_not_called()
        request = send_mock.call_args[0][1]
        self.assertEqual(request.method, 'PUT')
        self.assertEqual(request.url, 'https://myaccount.blob.core.windows.net/mycontainer/myblob?timeout=30&sv=2019-02-02&srt=s&ss=bf')
        self.assertEqual(request.body, '{"b1": "v1"}')
        # Verify no Authorization header
        self.assertDictEqual(dict(request.headers), expected_header)
        self.assertEqual(send_mock.call_args[1]["verify"], not should_disable_connection_verify())
    
        # Test Authorization header is skipped
        send_raw_request(cli_ctx, 'GET', full_arm_rest_url, body=test_body, skip_authorization_header=True,
                         generated_client_request_id_name=None)
    
        get_raw_token_mock.assert_not_called()
        request = send_mock.call_args[0][1]
        self.assertDictEqual(dict(request.headers), expected_header)
    
        # Test Authorization header is already provided
        send_raw_request(cli_ctx, 'GET', full_arm_rest_url,
                         body=test_body, headers={'Authorization=Basic ABCDE'},
                         generated_client_request_id_name=None)
    
        get_raw_token_mock.assert_not_called()
        request = send_mock.call_args[0][1]
        self.assertDictEqual(dict(request.headers), {**expected_header, 'Authorization': 'Basic ABCDE'})
    
        # Test Authorization header is auto appended
        send_raw_request(cli_ctx, 'GET', full_arm_rest_url,
                         body=test_body,
                         generated_client_request_id_name=None)
    
>       get_raw_token_mock.assert_called_with(mock.ANY, test_arm_active_directory_resource_id, subscription=subscription_id)

src/azure-cli-core/azure/cli/core/tests/test_util.py:310: 
                                        
/opt/hostedtoolcache/Python/3.12.7/x64/lib/python3.12/unittest/mock.py:212: in assert_called_with
    return mock.assert_called_with(*args, **kwargs)
                                       _ 

self = <MagicMock name='get_raw_token' spec='function' id='139632450659312'>
args = (, 'https://management.core.windows.net/')
kwargs = {'subscription': '00000001-0000-0000-0000-000000000000'}
expected = call('', (, 'https://management.core.windows.net/'),&nbsp;{'subscription':&nbsp;'00000001-0000-0000-0000-000000000000'})
actual = call('', (<azure.cli.core._profile.Profile object at 0x7efeb6a21af0>,), {'scopes': ['https://management.core.windows.net//.default'], 'subscription': '00000001-0000-0000-0000-000000000000'})
_error_message = <function NonCallableMock.assert_called_with.._error_message at 0x7efeb69c7240>
cause = None

    def assert_called_with(self, /, *args, **kwargs):
        """assert that the last call was made with the specified arguments.
    
        Raises an AssertionError if the args and keyword args passed in are
        different to the last call to the mock."""
        if self.call_args is None:
            expected = self._format_mock_call_signature(args, kwargs)
            actual = 'not called.'
            error_message = ('expected call not found.\nExpected: %s\n  Actual: %s'
                    % (expected, actual))
            raise AssertionError(error_message)
    
        def _error_message():
            msg = self._format_mock_failure_message(args, kwargs)
            return msg
        expected = self._call_matcher(_Call((args, kwargs), two=True))
        actual = self._call_matcher(self.call_args)
        if actual != expected:
            cause = expected if isinstance(expected, Exception) else None
>           raise AssertionError(_error_message()) from cause
E           AssertionError: expected call not found.
E           Expected: get_raw_token(, 'https://management.core.windows.net/',&nbsp;subscription='00000001-0000-0000-0000-000000000000')
E             Actual: get_raw_token(<azure.cli.core._profile.Profile object at 0x7efeb6a21af0>, scopes=['https://management.core.windows.net//.default'], subscription='00000001-0000-0000-0000-000000000000')

/opt/hostedtoolcache/Python/3.12.7/x64/lib/python3.12/unittest/mock.py:949: AssertionError
src/azure-cli-core/azure/cli/core/tests/test_util.py:233
❌3.9
Type Test Case Error Message Line
Failed test_send_raw_requests self = <azure.cli.core.tests.test_util.TestUtils testMethod=test_send_raw_requests>
send_mock = <function send at 0x7fb740ffb700>
get_raw_token_mock = <function get_raw_token at 0x7fb740ffbc10>

    @mock.patch.dict('os.environ')
    @mock.patch('azure.cli.core.profile.Profile.get_raw_token', autospec=True)
    @mock.patch('requests.Session.send', autospec=True)
    def test_send_raw_requests(self, send_mock, get_raw_token_mock):
        if 'AZURE_HTTP_USER_AGENT' in os.environ:
            del os.environ['AZURE_HTTP_USER_AGENT']  # Clear env var possibly added by DevOps
    
        return_val = mock.MagicMock()
        return_val.is_ok = True
        send_mock.return_value = return_val
        get_raw_token_mock.return_value = ("Bearer", "eyJ0eXAiOiJKV1", None), None, None
    
        cli_ctx = DummyCli()
        cli_ctx.data = {
            'command': 'rest',
            'safe_params': ['method', 'uri']
        }
        test_arm_active_directory_resource_id = 'https://management.core.windows.net/'
        test_arm_endpoint = 'https://management.azure.com/'
        subscription_id = '00000001-0000-0000-0000-000000000000'
        arm_resource_id = '/subscriptions/{}/resourcegroups/02?api-version=2019-07-01'.format(subscription_id)
        full_arm_rest_url = test_arm_endpoint.rstrip('/') + arm_resource_id
        test_body = '{"b1": "v1"}'
    
        expected_header = {
            'User-Agent': get_az_rest_user_agent(),
            'Accept-Encoding': 'gzip, deflate',
            'Accept': '/',
            'Connection': 'keep-alive',
            'Content-Type': 'application/json',
            'CommandName': 'rest',
            'ParameterSetName': 'method uri',
            'Content-Length': '12'
        }
        expected_header_with_auth = expected_header.copy()
        expected_header_with_auth['Authorization'] = 'Bearer eyJ0eXAiOiJKV1'
    
        # Test basic usage
        # Mock Put Blob https://docs.microsoft.com/en-us/rest/api/storageservices/put-blob
        # Authenticate with service SAS https://docs.microsoft.com/en-us/rest/api/storageservices/create-service-sas
        sas_token = ['sv=2019-02-02', '{"srt": "s"}', "{'ss': 'bf'}"]
        send_raw_request(cli_ctx, 'PUT', 'https://myaccount.blob.core.windows.net/mycontainer/myblob?timeout=30',
                         uri_parameters=sas_token, body=test_body,
                         generated_client_request_id_name=None)
    
        get_raw_token_mock.assert_not_called()
        request = send_mock.call_args[0][1]
        self.assertEqual(request.method, 'PUT')
        self.assertEqual(request.url, 'https://myaccount.blob.core.windows.net/mycontainer/myblob?timeout=30&sv=2019-02-02&srt=s&ss=bf')
        self.assertEqual(request.body, '{"b1": "v1"}')
        # Verify no Authorization header
        self.assertDictEqual(dict(request.headers), expected_header)
        self.assertEqual(send_mock.call_args[1]["verify"], not should_disable_connection_verify())
    
        # Test Authorization header is skipped
        send_raw_request(cli_ctx, 'GET', full_arm_rest_url, body=test_body, skip_authorization_header=True,
                         generated_client_request_id_name=None)
    
        get_raw_token_mock.assert_not_called()
        request = send_mock.call_args[0][1]
        self.assertDictEqual(dict(request.headers), expected_header)
    
        # Test Authorization header is already provided
        send_raw_request(cli_ctx, 'GET', full_arm_rest_url,
                         body=test_body, headers={'Authorization=Basic ABCDE'},
                         generated_client_request_id_name=None)
    
        get_raw_token_mock.assert_not_called()
        request = send_mock.call_args[0][1]
        self.assertDictEqual(dict(request.headers), {**expected_header, 'Authorization': 'Basic ABCDE'})
    
        # Test Authorization header is auto appended
        send_raw_request(cli_ctx, 'GET', full_arm_rest_url,
                         body=test_body,
                         generated_client_request_id_name=None)
    
>       get_raw_token_mock.assert_called_with(mock.ANY, test_arm_active_directory_resource_id, subscription=subscription_id)

src/azure-cli-core/azure/cli/core/tests/test_util.py:310: 
                                        
/opt/hostedtoolcache/Python/3.9.20/x64/lib/python3.9/unittest/mock.py:200: in assert_called_with
    return mock.assert_called_with(*args, **kwargs)
                                       _ 

self = <MagicMock name='get_raw_token' spec='function' id='140425046378144'>
args = (, 'https://management.core.windows.net/')
kwargs = {'subscription': '00000001-0000-0000-0000-000000000000'}
expected = call('', (, 'https://management.core.windows.net/'),&nbsp;{'subscription':&nbsp;'00000001-0000-0000-0000-000000000000'})
actual = call('', (<azure.cli.core._profile.Profile object at 0x7fb740faab50>,), {'scopes': ['https://management.core.windows.net//.default'], 'subscription': '00000001-0000-0000-0000-000000000000'})
_error_message = <function NonCallableMock.assert_called_with.._error_message at 0x7fb741020b80>
cause = None

    def assert_called_with(self, /, *args, **kwargs):
        """assert that the last call was made with the specified arguments.
    
        Raises an AssertionError if the args and keyword args passed in are
        different to the last call to the mock."""
        if self.call_args is None:
            expected = self._format_mock_call_signature(args, kwargs)
            actual = 'not called.'
            error_message = ('expected call not found.\nExpected: %s\nActual: %s'
                    % (expected, actual))
            raise AssertionError(error_message)
    
        def _error_message():
            msg = self._format_mock_failure_message(args, kwargs)
            return msg
        expected = self._call_matcher(_Call((args, kwargs), two=True))
        actual = self._call_matcher(self.call_args)
        if actual != expected:
            cause = expected if isinstance(expected, Exception) else None
>           raise AssertionError(_error_message()) from cause
E           AssertionError: expected call not found.
E           Expected: get_raw_token(, 'https://management.core.windows.net/',&nbsp;subscription='00000001-0000-0000-0000-000000000000')
E           Actual: get_raw_token(<azure.cli.core._profile.Profile object at 0x7fb740faab50>, scopes=['https://management.core.windows.net//.default'], subscription='00000001-0000-0000-0000-000000000000')

/opt/hostedtoolcache/Python/3.9.20/x64/lib/python3.9/unittest/mock.py:907: AssertionError
src/azure-cli-core/azure/cli/core/tests/test_util.py:233
️✔️cosmosdb
️✔️latest
️✔️3.12
️✔️3.9
️✔️databoxedge
️✔️2019-03-01-hybrid
️✔️3.12
️✔️3.9
️✔️2020-09-01-hybrid
️✔️3.12
️✔️3.9
️✔️latest
️✔️3.12
️✔️3.9
️✔️dls
️✔️latest
️✔️3.12
️✔️3.9
️✔️dms
️✔️latest
️✔️3.12
️✔️3.9
️✔️eventgrid
️✔️latest
️✔️3.12
️✔️3.9
️✔️eventhubs
️✔️latest
️✔️3.12
️✔️3.9
️✔️feedback
️✔️latest
️✔️3.12
️✔️3.9
️✔️find
️✔️latest
️✔️3.12
️✔️3.9
️✔️hdinsight
️✔️latest
️✔️3.12
️✔️3.9
️✔️identity
️✔️latest
️✔️3.12
️✔️3.9
️✔️iot
️✔️2019-03-01-hybrid
️✔️3.12
️✔️3.9
️✔️2020-09-01-hybrid
️✔️3.12
️✔️3.9
️✔️latest
️✔️3.12
️✔️3.9
️✔️keyvault
️✔️2018-03-01-hybrid
️✔️3.12
️✔️3.9
️✔️2020-09-01-hybrid
️✔️3.12
️✔️3.9
️✔️latest
️✔️3.12
️✔️3.9
️✔️lab
️✔️latest
️✔️3.12
️✔️3.9
️✔️managedservices
️✔️latest
️✔️3.12
️✔️3.9
️✔️maps
️✔️latest
️✔️3.12
️✔️3.9
️✔️marketplaceordering
️✔️latest
️✔️3.12
️✔️3.9
️✔️monitor
️✔️latest
️✔️3.12
️✔️3.9
️✔️mysql
️✔️latest
️✔️3.12
️✔️3.9
️✔️netappfiles
️✔️latest
️✔️3.12
️✔️3.9
️✔️network
️✔️2018-03-01-hybrid
️✔️3.12
️✔️3.9
️✔️latest
️✔️3.12
️✔️3.9
️✔️policyinsights
️✔️latest
️✔️3.12
️✔️3.9
️✔️privatedns
️✔️latest
️✔️3.12
️✔️3.9
️✔️profile
️✔️latest
️✔️3.12
️✔️3.9
️✔️rdbms
️✔️latest
️✔️3.12
️✔️3.9
️✔️redis
️✔️latest
️✔️3.12
️✔️3.9
️✔️relay
️✔️latest
️✔️3.12
️✔️3.9
️✔️resource
️✔️2018-03-01-hybrid
️✔️3.12
️✔️3.9
️✔️2019-03-01-hybrid
️✔️3.12
️✔️3.9
️✔️latest
️✔️3.12
️✔️3.9
️✔️role
️✔️latest
️✔️3.12
️✔️3.9
️✔️search
️✔️latest
️✔️3.12
️✔️3.9
️✔️security
️✔️latest
️✔️3.12
️✔️3.9
️✔️servicebus
️✔️latest
️✔️3.12
️✔️3.9
️✔️serviceconnector
️✔️latest
️✔️3.12
️✔️3.9
️✔️servicefabric
️✔️latest
️✔️3.12
️✔️3.9
️✔️signalr
️✔️latest
️✔️3.12
️✔️3.9
️✔️sql
️✔️latest
️✔️3.12
️✔️3.9
️✔️sqlvm
️✔️latest
️✔️3.12
️✔️3.9
️✔️storage
️✔️2018-03-01-hybrid
️✔️3.12
️✔️3.9
️✔️2019-03-01-hybrid
️✔️3.12
️✔️3.9
️✔️2020-09-01-hybrid
️✔️3.12
️✔️3.9
️✔️latest
️✔️3.12
️✔️3.9
️✔️synapse
️✔️latest
️✔️3.12
️✔️3.9
️✔️telemetry
️✔️2018-03-01-hybrid
️✔️3.12
️✔️3.9
️✔️2019-03-01-hybrid
️✔️3.12
️✔️3.9
️✔️2020-09-01-hybrid
️✔️3.12
️✔️3.9
️✔️latest
️✔️3.12
️✔️3.9
️✔️util
️✔️latest
️✔️3.12
️✔️3.9
️✔️vm
️✔️2018-03-01-hybrid
️✔️3.12
️✔️3.9
️✔️2019-03-01-hybrid
️✔️3.12
️✔️3.9
️✔️2020-09-01-hybrid
️✔️3.12
️✔️3.9
️✔️latest
️✔️3.12
️✔️3.9

@azure-client-tools-bot-prd
Copy link
Copy Markdown

azure-client-tools-bot-prd bot commented Oct 16, 2024

⚠️AzureCLI-BreakingChangeTest
⚠️util
rule cmd_name rule_message suggest_message
⚠️ 1006 - ParaAdd rest cmd rest added parameter scopes

@yonzhan
Copy link
Copy Markdown
Collaborator

yonzhan commented Oct 16, 2024

Thank you for your contribution! We will review the pull request and get back to you soon.

@microsoft-github-policy-service microsoft-github-policy-service bot added the Auto-Assign Auto assign by bot label Oct 16, 2024
@microsoft-github-policy-service microsoft-github-policy-service bot added the ARM az resource/group/lock/tag/deployment/policy/managementapp/account management-group label Oct 16, 2024
@microsoft-github-policy-service microsoft-github-policy-service bot added the Account az login/account label Oct 16, 2024
@jiasli jiasli mentioned this pull request Oct 16, 2024
3 tasks
@jiasli jiasli changed the title [REST] az rest: Add --scope argument {Core} Add scopes argument to send_raw_request Oct 16, 2024
@jiasli jiasli changed the title {Core} Add scopes argument to send_raw_request [REST] az rest: Add --scope argument Nov 20, 2024
@jiasli jiasli marked this pull request as ready for review November 20, 2024 04:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Account az login/account act-identity-squad ARM az resource/group/lock/tag/deployment/policy/managementapp/account management-group Auto-Assign Auto assign by bot

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants