33import os
44import sys
55import time
6+ import uuid
67from typing import List , Optional
78import unittest
89try :
3233)
3334from msal .token_cache import is_subdict_of
3435
36+ EXPECTED_SKU = "MSAL.Python" # Hardcoded constant, not imported from product
37+
3538
3639class ManagedIdentityTestCase (unittest .TestCase ):
3740 def test_helper_class_should_be_interchangable_with_dict_which_could_be_loaded_from_file_or_env_var (self ):
@@ -181,14 +184,23 @@ def _test_happy_path(self) -> callable:
181184 return mocked_method
182185
183186 def test_happy_path_of_vm (self ):
184- self ._test_happy_path ().assert_called_with (
187+ mock_get = self ._test_happy_path ()
188+ mock_get .assert_called_with (
185189 # The last call contained claims_challenge
186190 # but since IMDS doesn't support token_sha256_to_refresh,
187191 # the request shall remain the same as before
188192 'http://169.254.169.254/metadata/identity/oauth2/token' ,
189193 params = {'api-version' : '2018-02-01' , 'resource' : 'R' },
190- headers = {'Metadata' : 'true' },
194+ headers = {
195+ 'Metadata' : 'true' ,
196+ 'x-client-SKU' : EXPECTED_SKU ,
197+ 'x-client-Ver' : ANY ,
198+ 'x-ms-client-request-id' : ANY ,
199+ },
191200 )
201+ # Validate correlation ID is a valid UUID
202+ corr_id = mock_get .call_args .kwargs ["headers" ]["x-ms-client-request-id" ]
203+ uuid .UUID (corr_id )
192204
193205 @patch .object (ManagedIdentityClient , "_ManagedIdentityClient__instance" , "MixedCaseHostName" )
194206 def test_happy_path_of_theoretical_mixed_case_hostname (self ):
@@ -200,11 +212,20 @@ def test_happy_path_of_theoretical_mixed_case_hostname(self):
200212
201213 @patch .dict (os .environ , {"AZURE_POD_IDENTITY_AUTHORITY_HOST" : "http://localhost:1234//" })
202214 def test_happy_path_of_pod_identity (self ):
203- self ._test_happy_path ().assert_called_with (
215+ mock_get = self ._test_happy_path ()
216+ mock_get .assert_called_with (
204217 'http://localhost:1234/metadata/identity/oauth2/token' ,
205218 params = {'api-version' : '2018-02-01' , 'resource' : 'R' },
206- headers = {'Metadata' : 'true' },
219+ headers = {
220+ 'Metadata' : 'true' ,
221+ 'x-client-SKU' : EXPECTED_SKU ,
222+ 'x-client-Ver' : ANY ,
223+ 'x-ms-client-request-id' : ANY ,
224+ },
207225 )
226+ # Validate correlation ID is a valid UUID
227+ corr_id = mock_get .call_args .kwargs ["headers" ]["x-ms-client-request-id" ]
228+ uuid .UUID (corr_id )
208229
209230 def test_vm_error_should_be_returned_as_is (self ):
210231 raw_error = '{"raw": "error format is undefined"}'
@@ -229,8 +250,16 @@ def test_vm_resource_id_parameter_should_be_msi_res_id(self):
229250 mocked_method .assert_called_with (
230251 'http://169.254.169.254/metadata/identity/oauth2/token' ,
231252 params = {'api-version' : '2018-02-01' , 'resource' : 'R' , 'msi_res_id' : '1234' },
232- headers = {'Metadata' : 'true' },
253+ headers = {
254+ 'Metadata' : 'true' ,
255+ 'x-client-SKU' : EXPECTED_SKU ,
256+ 'x-client-Ver' : ANY ,
257+ 'x-ms-client-request-id' : ANY ,
258+ },
233259 )
260+ # Validate correlation ID is a valid UUID
261+ corr_id = mocked_method .call_args .kwargs ["headers" ]["x-ms-client-request-id" ]
262+ uuid .UUID (corr_id )
234263
235264
236265@patch .dict (os .environ , {"IDENTITY_ENDPOINT" : "http://localhost" , "IDENTITY_HEADER" : "foo" })
0 commit comments