@@ -1024,3 +1024,36 @@ async def connect(connection):
10241024 client = get_redis_async_client ()
10251025
10261026 assert isinstance (client , async_redis .RedisCluster )
1027+
1028+
1029+ @pytest .mark .parametrize (
1030+ "markers, provider_cls" ,
1031+ [
1032+ (AZURE_AD_CONNECT_FUNC , AzureADCredentialProvider ),
1033+ (GCP_IAM_CONNECT_FUNC , GCPIAMCredentialProvider ),
1034+ ],
1035+ ids = ["azure_ad" , "gcp_iam" ],
1036+ )
1037+ def test_async_sentinel_keeps_the_credential_provider_off_the_monitors (markers , provider_cls ):
1038+ """The Sentinel monitors authenticate with their own password, and redis-py refuses a password
1039+ passed alongside a credential provider, so only the data node may carry the provider.
1040+ """
1041+ redis_kwargs = {
1042+ "sentinel_nodes" : [("sentinel-1" , 26379 )],
1043+ "sentinel_password" : "sentinel-secret" ,
1044+ "service_name" : "mymaster" ,
1045+ "redis_connect_func" : SimpleNamespace (** markers ),
1046+ }
1047+
1048+ with patch ("litellm._redis.async_redis.Sentinel" ) as mock_sentinel_cls :
1049+ with patch ("litellm._redis._get_redis_client_logic" , return_value = redis_kwargs ):
1050+ get_redis_async_client ()
1051+
1052+ sentinel_kwargs = mock_sentinel_cls .call_args [1 ]["sentinel_kwargs" ]
1053+ assert sentinel_kwargs ["password" ] == "sentinel-secret"
1054+ assert "credential_provider" not in sentinel_kwargs
1055+ async_redis .Connection (host = "sentinel-1" , port = 26379 , ** sentinel_kwargs )
1056+
1057+ master_kwargs = mock_sentinel_cls .return_value .master_for .call_args [1 ]
1058+ assert isinstance (master_kwargs ["credential_provider" ], provider_cls )
1059+ assert "password" not in master_kwargs
0 commit comments