o
    i                     @   s  d Z ddlZddlZddlZddlZddlZddlZddlm	Z	 ddl
Z
ddlZddlmZ ddlZddlZddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZ zddlZdZW n eyk   dZe	 ZY nw ejjeddZej dddd Z!dd Z"dd Z#dd Z$dd Z%dd Z&dd Z'dd Z(d d! Z)d"d# Z*d$d% Z+d&d' Z,d(d) Z-d*d+ Z.d,d- Z/d.d/ Z0d0d1 Z1d2d3 Z2d4d5 Z3d6d7 Z4d8d9 Z5d:d; Z6d<d= Z7d>d? Z8d@dA Z9dBdC Z:dDdE Z;dFdG Z<dHdI Z=dJdK Z>dLdM Z?dNdO Z@dPdQ ZAdRdS ZBdTeCfdUdVZDdTeCfdWdXZEdTeCfdYdZZFd[d\ ZGd]d^ ZHd_d` ZIdadb ZJdcdd ZKdedf ZLdgdh ZMdidj ZNdkdl ZOdmdn ZPdodp ZQdqdr ZRdsdt ZSdudv ZTdwdx ZUdydz ZVd{d| ZWd}d~ ZXdd ZYdd ZZdd Z[dd Z\dd Z]dd Z^dd Z_ejjdd Z`ejjdd Zadd Zbejjdd Zcejjdd Zdejjdd Zeejjdd Zfejjdd Zgejjdd Zhejjdd Ziejjdd Zjejjdd Zkeejjdd ZldS )z Tests for client initialization.    N)mock)credentials   )_api_client)	_base_url)_replay_api_client)Client)typesFTz(aiohttp is not installed, skipping test.)reason)autousec                   c   s    d V  dt _d S )NF)
api_clienthas_aiohttp r   r   l/home/livre-enfant/venv/lib/python3.10/site-packages/google/genai/tests/client/test_client_initialization.pyreset_has_aiohttp3   s   
r   c                 C   \   d}|  d| | jddd t }|jjjrJ |jjj|ks"J t|jjtj	s,J d S )Ngemini_api_keyGEMINI_API_KEYGOOGLE_API_KEYFraising
setenvdelenvr   modelsr   vertexaiapi_key
isinstancer   BaseApiClientmonkeypatchr   clientr   r   r    test_ml_dev_from_gemini_env_only9      r"   c                 C   sZ   d}|  d| |  dd t }|jjjrJ |jjj|ks!J t|jjtjs+J d S )Nr   r   r    )	r   r   r   r   r   r   r   r   r   r   r   r   r   1test_ml_dev_from_gemini_env_with_google_env_emptyE   s   r%   c                 C   r   )Ngoogle_api_keyr   r   Fr   r   r   r   r   r    test_ml_dev_from_google_env_onlyQ   r#   r'   c                 C   s|   |j tjdd d}d}| d| | d| t }|jjjr"J |jjj|ks+J t	|jjt
js5J d|jv s<J d S )Ngoogle_genai._api_clientloggerr&   r   r   r   EBoth GOOGLE_API_KEY and GEMINI_API_KEY are set. Using GOOGLE_API_KEY.	set_levelloggingDEBUGr   r   r   r   r   r   r   r   r   textr    caplogr&   r   r!   r   r   r   test_ml_dev_both_env_key_set]   s   r3   c                 C   s<   |j tjdd d}| d| t }|jjjdksJ d S )Nr(   r)   zgemini_api_key
r   r   )r-   r.   r/   r   r   r   r   r   r    r2   r   r!   r   r   r   test_api_key_with_new_lineo   s
   r5   c                  C   s2   d} t | d}|jjjrJ |jjj| ksJ d S )Nr&   r   )r   r   r   r   r   )r   r!   r   r   r   test_ml_dev_from_constructory   s   
r7   c                  C   s(  ddddidd} dddd	id
d}t d| d}|jjjrJ |jj d dks+J |jj d dks7J |jj d d dksEJ |jj d dksQJ t ddd|d}|jjjs`J |jj d dkslJ |jj d dksxJ |jj d d d	ksJ |jj d d
ksJ d S )Nv1main!https://placeholder-fake-url.com/X-Custom-Headercustom_value_mldevi'  )api_versionbase_urlheaderstimeoutv1Bhttps://{self.location}-aiplatform.googleapis.com/{{api_version}}/custom_value_vertexaii*  r&   r   http_optionsr=   r<   r>   r?   Tfake_project_idfake-locationr   projectlocationrD   r   r   r   r   get_read_only_http_optionsmldev_http_optionsvertexai_http_optionsmldev_clientvertexai_clientr   r   r   "test_constructor_with_http_options   sr   	



rQ   c               
   C   s   ddddid} ddddid}zt d| d	}W n! ty9 } zt|ts'J d
t|v s/J W Y d }~nd }~ww zt ddd|d}W d S  tyg } zt|tsTJ dt|v s\J W Y d }~d S d }~ww )Nr@   r9   r:   custom_value)invalid_version_keyr=   r>   rA   )r<   r=   invalid_header_keyr&   rC   rS   TrE   rF   rG   rT   )r   	Exceptionr   
ValueErrorstr)rM   rN   _er   r   r   .test_constructor_with_invalid_http_options_key   s6   
rZ   c                  C   s  t jddddid} t jddddid}td| d}|jjjr!J |jj d	 | jks.J |jj d
 | jks;J |jj d d | j	d ksLJ tddd|d}|jjjs[J |jj d	 |jkshJ |jj d
 |jksuJ |jj d d |j	d ksJ d S )Nr@   r9   r:   rR   )r<   r=   r>   rA   r&   rC   r=   r<   r>   TrE   rF   rG   )
r	   HttpOptionsr   r   r   r   rK   r=   r<   r>   rL   r   r   r   3test_constructor_with_http_options_as_pydantic_type   sf   	



r\   c                 C   h   d}d}|  dd |  d| |  d| t }|jjjs J |jjj|ks)J |jjj|ks2J d S )NrE   rF   GOOGLE_GENAI_USE_VERTEXAI1GOOGLE_CLOUD_PROJECTGOOGLE_CLOUD_LOCATIONr   r   r   r   r   rH   rI   r    
project_idrI   r!   r   r   r   test_vertexai_from_env_12     re   c                 C   r]   )NrE   rF   r^   truer`   ra   rb   rc   r   r   r   test_vertexai_from_env_true@  rf   rh   c                  C   s`   d} d}t d| |d}|jjjsJ |jjj| ksJ |jjj|ks$J t|jjtjs.J d S )NrE   rF   Tr   rH   rI   )	r   r   r   r   rH   rI   r   r   r   )rd   rI   r!   r   r   r   test_vertexai_from_constructorN  s   rj   c                 C   s   t t3 | dd | dd | dd | dd ddd}| tjd| td	d
 W d    d S 1 s;w   Y  d S )Nr`   r$   ra   r   r   c                 S      dS N)NNr   scopesr   r   r   mock_auth_defaulte     zBtest_invalid_vertexai_constructor_empty.<locals>.mock_auth_defaultdefaultTr   N)pytestraisesrV   r   setattrgoogleauthr   )r    ro   r   r   r   'test_invalid_vertexai_constructor_empty^  s   
"ry   c                 C   sp   |  dd |  dd |  dd |  dd ddd}| tjd| td	d
did}|jjjd u s6J d S )Nr`   r$   ra   r   r   c                 S   rk   rl   r   rm   r   r   r   ro   r  rp   zLtest_vertexai_constructor_empty_base_url_override.<locals>.mock_auth_defaultrq   Tr=   zhttps://override.com/r   rD   rs   )r   rv   rw   rx   r   r   r   rI   )r    ro   r!   r   r   r   1test_vertexai_constructor_empty_base_url_overridel  s   
r{   c                 C   sN   t t | dd | dd t  W d    d S 1 s w   Y  d S )Nr   r$   r   )rt   ru   rV   r   r   )r    r   r   r   $test_invalid_mldev_constructor_empty|  s
   "r|   c               
   C   sX   d} d}d}zt d| ||d W d S  ty+ } zt|ts J W Y d }~d S d }~ww )NrE   rF   fake-api_keyT)r   rH   rI   r   r   rU   r   rV   rd   rI   r   rY   r   r   r   "test_invalid_vertexai_constructor1  s   r   c                  C   sJ   t  } d}tt td| |d W d    d S 1 sw   Y  d S )Nr}   T)r   r   r   )r   AnonymousCredentialsrt   ru   rV   r   )credsr   r   r   r   "test_invalid_vertexai_constructor2  s   "r   c                 C   s^   |   !}|jddd d}td|d}|jjjdksJ W d    d S 1 s(w   Y  d S )Nra   Fr   rE   Tr   rH   global)contextr   r   r   r   rI   )r    mrd   r!   r   r   r   (test_vertexai_default_location_to_global  s   
"r   c                 C   s   t  }d}|  /}|jddd |dd td||d}|jjjd	ks(J |jjj	|ks1J W d    d S 1 s<w   Y  d S )
NrE   ra   Fr   r   r$   T)r   r   rH   r   )
r   r   r   r   r   r   r   r   rI   rH   )r    r   rd   r   r!   r   r   r   9test_vertexai_default_location_to_global_with_credentials  s   
"r   c                 C   s   d}d}|   <}|jddd |jddd |d| td|d	}|jjjd
ks,J |jjj|ks5J |jjjr<J W d    d S 1 sGw   Y  d S )Nexplicit_project_idenv_api_keyra   Fr   r`   r   Tr   r   	r   r   r   r   r   r   rI   rH   r   r    rd   r   r   r!   r   r   r   Mtest_vertexai_default_location_to_global_with_explicit_project_and_env_apikey  s   
"r   c                 C   s   d}|   0}|jddd |d| tdddid	}|jjjd
ks%J |jjj|ks.J W d    d S 1 s9w   Y  d S )Nenv_project_idra   Fr   r`   Tr=   zhttps://fake-url.googleapis.comrz   r   r   r   r   r   r   r   rI   rH   r    rd   r   r!   r   r   r   ?test_vertexai_default_location_to_global_with_vertexai_base_url  s   
"r   c                 C   sx   d}|   ,}|jddd |d| tdddid	}|jjjr#J |jjjr*J W d    d S 1 s5w   Y  d S )
Nr   ra   Fr   r`   Tr=   zhttps://fake-url.comrz   r   r   r   r   r   @test_vertexai_default_location_to_global_with_arbitrary_base_url  s   
"r   c                 C   s   d}d}|   :}|jddd |d| |d| tdd	}|jjjd
ks*J |jjj|ks3J |jjjr:J W d    d S 1 sEw   Y  d S )Nr   r   ra   Fr   r`   r   Trr   r   r   r   r   r   r   Htest_vertexai_default_location_to_global_with_env_project_and_env_apikey  s   

"r   c                 C   sv   d}d}|   )}|jddd td||d}|jjj|ks J |jjj|ks)J W d    d S 1 s4w   Y  d S )NrE   zus-central1ra   Fr   Tri   )r   r   r   r   r   rI   rH   r    rd   rI   r   r!   r   r   r   >test_vertexai_no_default_location_when_location_explicitly_set  s   
"r   c                 C   s   d}d}|   5}|jddd td||d}|jjj|ks J |jjj|ks)J |jj d d	ks5J W d    d S 1 s@w   Y  d S )
NrE   usra   Fr   Tri   r=   z)https://aiplatform.us.rep.googleapis.com/r   r   r   r   r   rI   rH   rK   r   r   r   r   !test_vertexai_location_us_routing  s   

"r   c                 C   s   d}d}|   8}|jddd td||ddid	}|jjj|ks#J |jjj|ks,J |jj d dks8J W d    d S 1 sCw   Y  d S )
NrE   r   ra   Fr   Tr=   zhttps://my-custom-url.com/rG   r   r   r   r   r   3test_vertexai_location_us_routing_base_url_override  s    

"r   c                 C   s|   d}d}|   ,}|d| |d| tdd}|jjj|ks#J |jjj|ks,J W d    d S 1 s7w   Y  d S )NrE   zus-west1ra   r`   Trr   )r   r   r   r   r   rI   rH   r   r   r   r   7test_vertexai_no_default_location_when_env_location_set,  s   

"r   c                 C   s   d}|   :}|jddd |jddd |dd td|d	}|jjjr(J |jjjr/J |jjj|ks8J W d    d S 1 sCw   Y  d S )
Nvertexai_api_keyra   Fr   r`   r   r$   Tr   r   r   )r    r   r   r!   r   r   r   2test_vertexai_no_default_location_with_apikey_only9  s   
"r   c                 C   s   t  }| dd | dd | dd td|d}|jjjs#J |jjjs*J |jjjs1J |jjj	r8J |jjj
|u sAJ t|jjtjsKJ d S )	Nr`   rE   ra   rF   r   r   T)r   r   )r   r   r   r   r   r   r   rH   rI   r   _credentialsr   r   r   )r    r   r!   r   r   r   "test_vertexai_explicit_credentialsG  s   r   c                 C   s   d}d}|  dd |  dd |  dd td	||d
}|jjjs$J |jjj|ks-J |jjj|ks6J |jjjr=J t|jjt	j
sGJ d S )Nconstructor_project_idzconstructor-locationr`   r   ra   env_locationr   r$   Tri   r   r   r   r   r   rH   rI   r   r   r   r   rc   r   r   r   &test_vertexai_explicit_arg_precedence1Z  s   r   c                 C   s   d}|  dd |  dd |  dd td|d}|jjjs!J |jjjr(J |jjjr/J |jjj|ks8J t|jjt	j
sBJ d S )	Nconstructor_apikeyr`   r$   ra   r   r   Tr   r   r   r   r   r   &test_vertexai_explicit_arg_precedence2o  s   r   c               
   C   sV   d} d}d}z
t | ||d W d S  ty* } zt|tsJ W Y d }~d S d }~ww )NrE   rF   r}   )rH   rI   r   r~   r   r   r   r   test_invalid_mldev_constructor  s   r   c                 C   s|   |j tjdd d}| dd | dd t|d}|jjjr"J |jjj|ks+J t	|jjt
js5J d	|jv s<J d S )
Nr(   r)   constructor_api_keyr   google_env_api_keyr   gemini_env_api_keyr6   r+   r,   r4   r   r   r   "test_mldev_explicit_arg_precedence  s   
r   
use_vertexc                 C   s   d}|  d| |  dd |rdnd}|  dd|  |  d	d
 t }|jjjr,J |jjj|ks5J t|jjtjs?J d S )Nr&   r   GOOGLE_GENAI_CLIENT_MODEreplayvertexmldevGOOGLE_GENAI_REPLAY_IDtest_replay_id.GOOGLE_GENAI_REPLAYS_DIRECTORYtest_replay_data)	r   r   r   r   r   r   r   replay_api_clientReplayApiClient)r    r   r   api_typer!   r   r   r   "test_replay_client_ml_dev_from_env  s   
r   c                 C   s   d}d}|  dd |  d| |  d| |  dd |r d	nd
}|  dd|  |  dd t }|jjjs:J |jjj|ksCJ |jjj|ksLJ t|jjtj	sVJ d S )NrE   rF   r^   r_   r`   ra   r   r   r   r   r   r   r   r   )
r   r   r   r   r   rH   rI   r   r   r   )r    r   rd   rI   r   r!   r   r   r   $test_replay_client_vertexai_from_env  s    
r   c                 C   s`   d}|  d| |  dd t }t|jjtjsJ |  dd t }t|jjtjs.J d S )Nr&   r   r   r   r$   )	r   r   r   r   r   r   r   r   r   )r    r   r   client1client2r   r   r    test_change_client_mode_from_env  s   
r   c                 C   s   d}|  dd |  dd t|dd}|jjjsJ |jjjr"J |jjjr)J |jjj|ks2J d|jjj	v s;J t
|jjtjsEJ d S )Nr   ra   r$   r`   T)r   r   
aiplatform)r   r   r   r   r   rH   rI   r   _http_optionsr=   r   r   r   r   r   r   r   %test_vertexai_apikey_from_constructor  s   r   c                 C      d}|  d| | jddd |  dd |  dd td	d
}|jjjs'J |jjj|ks0J |jjjr7J |jjjr>J d|jj	j
v sGJ t|jjtjsQJ d S )Nr   r   r   Fr   ra   r$   r`   Trr   r   r   r   r   r   r   r   r   rH   rI   r   r=   r   r   r   r   r   r   r   1test_vertexai_apikey_from_env_google_api_key_only     
r   c                 C   r   )Nr   r   r   Fr   ra   r$   r`   Trr   r   r   r   r   r   r   1test_vertexai_apikey_from_env_gemini_api_key_only  r   r   c                 C   s   d}|  d| |  dd |  dd |  dd tdd}|jjjs&J |jjj|ks/J |jjjr6J |jjjr=J d	|jjj	v sFJ t
|jjtjsPJ d S )
Nr   r   r   r$   ra   r`   Trr   r   r   r   r   r   r   r   rH   rI   r   r=   r   r   r   r   r   r   r   Ftest_vertexai_apikey_from_env_gemini_api_key_with_google_api_key_empty  s   
r   c                 C   s   |j tjdd d}d}| d| | d| | dd | d	d td
d}|jjjs0J |jjj|ks9J |jjj	r@J |jjj
rGJ d|jjjv sPJ t|jjtjsZJ d|jv saJ d S )Nr(   r)   r&   r   r   r   ra   r$   r`   Trr   r   r+   )r-   r.   r/   r   r   r   r   r   r   rH   rI   r   r=   r   r   r   r0   r1   r   r   r   +test_vertexai_apikey_from_env_both_api_keys+  s"   
r   c                  C   sL   d} d}d}t t t| ||dd W d    d S 1 sw   Y  d S )Nr   rE   rF   T)r   rH   rI   r   )rt   ru   rV   r   )r   rd   rI   r   r   r   )test_vertexai_apikey_invalid_constructor1F  s   "r   c                 C   s   d}d}d}|  d| |  d| |  dd td|d	}|jjjs%J |jjj|ks.J |jjjr5J |jjjr<J d
|jjj	v sEJ t
|jjtjsOJ d S )Nr   rE   rF   r`   ra   r   r$   Tr   r   r   r    r   rd   rI   r!   r   r   r   test_vertexai_apikey_combo1U  s   r   c                 C   s   d}d}d}|  dd |  dd |  d| td||d	}|jjjs&J |jjjr-J |jjj|ks6J |jjj|ks?J d
|jjj	v sHJ t
|jjtjsRJ d S )Nr   rE   rF   r`   r$   ra   r   Tri   r   r   r   r   r   r   test_vertexai_apikey_combo2i  s   r   c                 C   s   d}d}d}|  d| |  d| |  d| tdd}|jjjs$J |jjjr+J |jjj|ks4J |jjj|ks=J d	|jjj	v sFJ t
|jjtjsPJ d S )
NrE   rF   r   r`   ra   r   Trr   r   r   )r    rd   rI   r   r!   r   r   r   test_vertexai_apikey_combo3}  s   
r   c                 C   s   d}d}|  d| |  d| td|d}|jjjsJ |jjj|ks&J |jjj|ks/J |jjjjdks9J t	|jjt
jsCJ d S )NrE   r   r`   ra   T)r   rI   z"https://aiplatform.googleapis.com/)r   r   r   r   r   rH   rI   r   r=   r   r   r   rc   r   r   r   test_vertexai_global_endpoint  s   
r   c                 C   s`   |j tjdd d}d}d}| d| | d| td|d	}d
|jv s'J d|jv s.J d S )Nr(   r)   rE   rF   r   r`   ra   Tr   INFOz8The user provided Vertex AI API key will take precedence)r-   r.   r/   r   r   r0   )r    r2   rd   rI   r   rX   r   r   r   #test_client_logs_to_logger_instance  s   r   c                  C   s   t jt \} }| d sJ t| d tjsJ zdd l}t j	t }|d s-J t|d tjs7J W d S  t
yS   |d sFJ t|d tjsPJ Y d S w )Nverifyr   ssl)r   r   _ensure_httpx_ssl_ctxr	   r[   r   r   
SSLContextaiohttp_ensure_aiohttp_ssl_ctxImportError)client_argsasync_client_argsr   r   r   r   /test_client_ssl_context_implicit_initialization  s   r   c                  C   s   t jtjdt tjdd} tjd| id| id}t	j
|\}}|d | ks-J zdd l}t	j
|}|d s>J t|d t jsHJ W d S  tyd   |d sWJ t|d t jsaJ Y d S w NSSL_CERT_FILESSL_CERT_DIRcafilecapathr   )r   r   r   r   r   create_default_contextosenvirongetcertifiwherer	   r[   r   r   r   r   r   r   r   r   ctxoptionsr   r   r   r   r   r   9test_client_ssl_context_explicit_initialization_same_args  s*   

r   c                  C   s   t jtjdt tjdd} t jtjdt tjdd}tjd| id|id}t	j
|\}}|d | ks?J zdd l}t	j
|}|d sPJ t|d t jsZJ W d S  tyv   |d siJ t|d t jssJ Y d S w r   r   )r   	async_ctxr   r   r   r   r   r   r   =test_client_ssl_context_explicit_initialization_separate_args  s2   


r   c                  C      t jtjdt tjdd} tjd| id}t	j
|\}}|d | ks*J zdd l}t	j
|}|d s;J t|d t jsEJ W d S  tya   |d sTJ t|d t js^J Y d S w )Nr   r   r   r   )r   r   r   r   r   r   r   r   9test_client_ssl_context_explicit_initialization_sync_args  &   

r   c                  C   r   )Nr   r   r   r   r   r   r   r   r   r   r   r   :test_client_ssl_context_explicit_initialization_async_args  r   r   c                  C   s|   ddi} ddi}t d| d}|jjjrJ |jj d dks!J t ddd|d	}|jjjs0J |jj d dks<J d S )
Nr=   r9   rA   r&   rC   TrE   rF   rG   rJ   rL   r   r   r   0test_constructor_with_base_url_from_http_options5  s0   
r   c                  C   s   t jddd tdd} | jjjrJ | jj d dksJ tddd	d
}|jjjs-J |jj d dks9J t jd d d d S )Nhttps://gemini-base-url.com/https://vertex-base-url.com/
gemini_url
vertex_urlr&   r6   r=   TrE   rF   ri   r=   set_default_base_urlsr   r   r   r   rK   )rO   rP   r   r   r   9test_constructor_with_base_url_from_set_default_base_urlsW  s*   

r   c                  C   s   ddi} ddi}t jddd td| d}|jjjrJ |jj d dks(J td	d
d|d}|jjjs7J |jj d dksCJ t jd d d d S )Nr=   (https://gemini-constructor-base-url.com/(https://vertex-constructor-base-url.com/r   r   r   r&   rC   TrE   rF   rG   r   rL   r   r   r   Jtest_constructor_with_constructor_base_url_overrides_set_default_base_urlsr  s8   
r   c                 C   s   |  dd |  dd ddi}ddi}td|d	}|jjjr!J |jj d dks-J td
dd|d}|jjjs<J |jj d dksHJ tjd d d d S )NGOOGLE_GEMINI_BASE_URL https://gemini-env-base-url.com/GOOGLE_VERTEX_BASE_URL https://vertex-env-base-url.com/r=   r   r   r&   rC   TrE   rF   rG   r   )r   r   r   r   r   rK   r=   r   )r    rM   rN   rO   rP   r   r   r   Jtest_constructor_with_constructor_base_url_overrides_environment_variables  s<   
r  c                 C   s   |  dd |  dd tjddd tdd	}|jjjrJ |jj d
 dks+J tdddd}|jjjs9J |jj d
 dksEJ tjd d d d S )Nr   r   r   r  r   r   r   r&   r6   r=   TrE   rF   ri   )r   r=   r   r   r   r   r   rK   r    rO   rP   r   r   r   Ytest_constructor_with_base_url_from_set_default_base_urls_overrides_environment_variables  s6   

r  c                 C   s   |  dd |  dd tdd}|jjjrJ |jj d dks$J tdd	d
d}|jjjs2J |jj d dks>J d S )Nr   r   r   r   r&   r6   r=   TrE   rF   ri   )r   r   r   r   r   rK   r  r   r   r   9test_constructor_with_base_url_from_environment_variables  s$   

r  c                  C   s:   t dddd} dt_| j rJ dt_| j sJ d S )NTrE   rF   ri   F)r   r   r   r   _use_aiohttpr!   r   r   r   6test_async_transport_absence_allows_aiohttp_to_be_used  s   r  c                  C   sD   t dddtji dd} dt_| j rJ dt_| j s J d S )NTrE   rF   r   rG   F)r   r	   r[   r   r   r   r  r  r   r   r   Htest_async_async_client_args_without_transport_allows_aiohttp_to_be_used  s   
r	  c                  C   sL   t dddtjdt idd} dt_| j rJ dt_| j r$J d S )NTrE   rF   	transportr   rG   F)	r   r	   r[   httpxAsyncBaseTransportr   r   r   r  r  r   r   r   Dtest_async_transport_forces_httpx_regardless_of_aiohttp_availability  s   
	r  c                     sD   t dddd} | j I dH }t|tjsJ | jj|u s J dS )z8Tests that _get_async_auth_lock returns an asyncio.Lock.TrE   rF   ri   N)r   r   _get_async_auth_lockr   asyncioLock_async_auth_lockr!   lockr   r   r   ,test_get_async_auth_lock_basic_functionality-  s   r  c                     sl   t dddd} | j I dH }| j I dH }| j I dH }||u s&J ||u s,J t|tjs4J dS )z8Tests that multiple calls return the same lock instance.TrE   rF   ri   N)r   r   r  r   r  r  )r!   lock1lock2lock3r   r   r   .test_get_async_auth_lock_returns_same_instance9  s   r  c           	         s  | j ddd tjtjdd_d_d_tjdfd}| t	j
d	| fd
d}tj|d}|_tdddd  j rat }d|_i |_d|_tj|d}| t	j
jjjd| ntjdi dd}tj|d}| tjd| d j_tjjdd& fddtdD }tj|D ]}| j dksJ qW d   n1 sw   Y  |!  |"  |j#dksJ d_tjjdd& fddtdD }tj|D ]}| j dksJ qW d   n1 sw   Y  |!  |!  |j#dksJ dS )z1Tests that synchronous API calls are thread-safe.r   Fr   specinitial-tokenNtest-projectreturn_valuerq   c                       d _ d _d S Nrefreshed-tokenFtokenexpiredrequest
mock_credsr   r   refresh_side_effectU     
zCtest_threaded_generate_content_locking.<locals>.refresh_side_effectside_effectTrE   rF   ri      s@   {"candidates": [{"content": {"parts": [{"text": "response"}]}}]}r&  z@{"candidates": [{"content": {"parts": [{"text": "response"}]}}]})status_coder>   r0   sendr   )max_workersc                    $   g | ]}j  jjd t|dqS z
gemini-pro)modelcontentssubmitr   generate_contentrW   .0ir!   executorr   r   
<listcomp>{      z:test_threaded_generate_content_locking.<locals>.<listcomp>
   responsec                    r1  r2  r5  r8  r;  r   r   r=    r>     )$r   r   Mockr   Credentialsr#  r$  quota_project_idrv   rw   rx   refreshr   r   _use_google_auth_syncrequestsResponser.  r>   _contentr
  AuthorizedSessionr  r   SyncHttpxClientr   
concurrentfuturesThreadPoolExecutorrangeas_completedresultr0   assert_called_onceassert_not_called
call_count)	r    ro   r)  mock_refreshmock_http_responsemock_requestmock_httpx_responserM  futurer   )r!   r<  r(  r   &test_threaded_generate_content_lockingG  sl   


rZ  c                    s  t jtjd d _d _d _t j dfd}| tj	d|  fdd	}t j|d
}| _
tdddd}d|j_t|j |j |j I dH }|g dksVJ |  |  d _t|j |j |j I dH }|g dks|J |  |  dS )zETests that _async_access_token uses locks to prevent race conditions.r  r  FNr  r  rq   c                    r  r   r"  r%  r'  r   r   r)    r*  z<test_async_access_token_locking.<locals>.refresh_side_effectr+  TrE   rF   ri   )r  r  r  )r!  r!  r!  )r   rB  r   rC  r#  r$  rD  rv   rw   rx   rE  r   r   r   r  gather_async_access_tokenrR  rS  )r    ro   r)  rU  r!   tokensr   r'  r   test_async_access_token_locking  s>   

r^  c                     s   t dddd dtf fddfdd	td
D } tj|  I dH }dd	 |D tfddD s:J ddd	 |D }t|ttd
ksOJ ddS )zDTests that concurrent access to _get_async_auth_lock is thread-safe.TrE   rF   ri   task_idc                        j  I d H }| t|fS rs   r   r  id)r_  r  r  r   r   get_lock_task     zAtest_get_async_auth_lock_concurrent_access.<locals>.get_lock_taskc                       g | ]} |qS r   r   r8  )rc  r   r   r=        z>test_get_async_auth_lock_concurrent_access.<locals>.<listcomp>rA  Nc                 S      g | ]}|d  qS    r   r9  rQ  r   r   r   r=    rf  c                 3       | ]	}| d  kV  qdS r   Nr   r9  lock_idlock_idsr   r   	<genexpr>      
z=test_get_async_auth_lock_concurrent_access.<locals>.<genexpr>z+All tasks should get the same lock instancec                 S   rg  r   r   rj  r   r   r   r=    rf  zAll tasks should complete)r   intrO  r  r[  allsortedlist)tasksresultstask_idsr   )r!   rc  rp  r   *test_get_async_auth_lock_concurrent_access  s   
 r{  c                     s  t dddd g dtffddt  }  fdd	td
D }fdd	tdD }ttj| tj| I dH \}}t  }||  }t|d
ksTJ dt|dks^J dtdkshJ ddd	 |D tfddD s|J |dk sJ d|dddS )zNTests that _get_async_auth_lock doesn't interfere with other async operations.TrE   rF   ri   op_idc                    s&   t dI d H   |  d|  S )Ng{Gz?
operation_)r  sleepappend)r|  )completed_operationsr   r   mock_async_operation  s   

zTtest_get_async_auth_lock_doesnt_block_other_operations.<locals>.mock_async_operationc                       g | ]} j  qS r   r   r  r9  rX   r  r   r   r=        zJtest_get_async_auth_lock_doesnt_block_other_operations.<locals>.<listcomp>r?  c                    re  r   r   r8  )r  r   r   r=    rf     Nz&All auth lock requests should completezAll work tasks should completez$All async operations should completec                 S   s   g | ]}t |qS r   )rb  r9  r  r   r   r   r=    rf  c                 3   rk  rl  r   rm  ro  r   r   rq        zItest_get_async_auth_lock_doesnt_block_other_operations.<locals>.<genexpr>皙?zOperations took too long (.3fz s), suggesting blocking occurred)	r   rt  r  get_event_looptimerO  r[  lenru  )
start_time
auth_tasks
work_tasksauth_resultswork_resultsend_time
total_timer   )r!   r  rp  r  r   6test_get_async_auth_lock_doesnt_block_other_operations  s,   
r  c                     s   t dddd} | jjdu sJ | jjdu sJ | j I dH }| jjdus(J | jjdus0J t|tjs8J | jj}||usBJ t|tjsJJ | j I dH }||u sXJ | jj|u s`J dS )z.Tests the creation lock lifecycle and cleanup.TrE   rF   ri   N)r   r   r  _async_auth_lock_creation_lockr  r   r  r  )r!   r  creation_lockr  r   r   r   0test_get_async_auth_lock_creation_lock_lifecycle  s    r  c                     s  t dddd d} dtf fddt  }fd	d
t| D }tj| I dH }t  | }dd
 |D }dd
 |D dd
 |D }t|| ksQJ t|t	t| ks]J t
fddD slJ dt|}|dk s}J d|dd|dk sJ d|dddS )z7Tests _get_async_auth_lock under heavy concurrent load.TrE   rF   ri   d   call_idc                    s<   t   } j I d H }t   }| t||| fS rs   )r  r  r  r   r  rb  )r  startr  endr  r   r   get_lock_with_timing<  s
   zAtest_get_async_auth_lock_under_load.<locals>.get_lock_with_timingc                    re  r   r   r8  )r  r   r   r=  D  rf  z7test_get_async_auth_lock_under_load.<locals>.<listcomp>Nc                 S   rg  rs  r   r9  rr   r   r   r=  I  rf  c                 S   rg  rh  r   r  r   r   r   r=  J  rf  c                 S   rg  )   r   r  r   r   r   r=  K  rf  c                 3   rk  rl  r   rm  ro  r   r   rq  O  rr  z6test_get_async_auth_lock_under_load.<locals>.<genexpr>zAll calls should get same lockg      ?zTotal time (r  zs) suggests blockingr  zMax individual call time (zs) too high)r   rt  r  r  r  rO  r[  r  rv  rw  ru  max)num_concurrent_callsr  rx  ry  r  call_ids
call_timesmax_call_timer   )r!   r  rp  r   #test_get_async_auth_lock_under_load3  s2   

r  c                     s  t ddddtjtjd} d| _d| _d| _| j_	d	t
ffd
d dt
ffdd fddtdD }fddtdD }ttj| tj| I dH \}}t|dks]J t|dkseJ dd |D tfddD syJ tdd |D sJ dS )zITests _get_async_auth_lock working correctly with actual auth operations.TrE   rF   ri   r  z
test-tokenFNr|  c              	      sh    j  I d H }|4 I d H  tdI d H  d|  W  d   I d H  S 1 I d H s-w   Y  d S )NMbP?auth_op_)r   r  r  r~  )r|  r  r  r   r   auth_operationj  s   0zQtest_get_async_auth_lock_interleaved_with_auth_operations.<locals>.auth_operationreq_idc                    r`  rs   ra  )r  r  r  r   r   lock_requestq  rd  zOtest_get_async_auth_lock_interleaved_with_auth_operations.<locals>.lock_requestc                    re  r   r   r8  )r  r   r   r=  v  rf  zMtest_get_async_auth_lock_interleaved_with_auth_operations.<locals>.<listcomp>r?  c                    re  r   r   r8  )r  r   r   r=  w  rf  c                 S   rg  rh  r   rj  r   r   r   r=    rf  c                 3   rk  rl  r   rm  ro  r   r   rq    r  zLtest_get_async_auth_lock_interleaved_with_auth_operations.<locals>.<genexpr>c                 s   s    | ]}| d V  qdS )r  N)
startswithrj  r   r   r   rq    s    )r   r   rB  r   rC  r#  r$  rD  r   r   rt  rO  r  r[  r  ru  )r(  r  
lock_tasksr  lock_resultsr   )r  r!   rp  r  r   9test_get_async_auth_lock_interleaved_with_auth_operations[  s*   r  c                     sn   dd } |  I dH \} |j  I dH } |u sJ t tjs#J  fdd}| I dH }|dks5J dS )zHTests that _get_async_auth_lock works correctly with event loop context.c                     s(   t dddd} | j I d H }| |fS )NTrE   rF   ri   )r   r   r  r  r   r   r   create_client_and_get_lock  s   zStest_get_async_auth_lock_with_event_loop_switch.<locals>.create_client_and_get_lockNc                	      sR    4 I d H  t dI d H  	 W d   I d H  dS 1 I d H s"w   Y  d S )Nr  success)r  r~  r   r  r   r   test_lock_functionality  s
   0zPtest_get_async_auth_lock_with_event_loop_switch.<locals>.test_lock_functionalityr  )r   r  r   r  r  )r  r!   r  r  rQ  r   r  r   /test_get_async_auth_lock_with_event_loop_switch  s   r  c                     s   t dddd tjjdgfdd} | tj_z7 fdd	td
D }tj| I dH tfddD s;J d dksKJ dd  dW tj_dS tj_w )z8Tests the double-checked locking pattern implementation.TrE   rF   ri   r   c                    s    d  d7  < | S )Nr   ri  r   )self)lock_creation_countoriginal_lock_initr   r   counting_lock_init  s   zKtest_get_async_auth_lock_double_checked_locking.<locals>.counting_lock_initc                    r  r   r  r  r  r   r   r=    r  zCtest_get_async_auth_lock_double_checked_locking.<locals>.<listcomp>2   Nc                 3   s    | ]	}| d  u V  qdS rl  r   r  )locksr   r   rq    r  zBtest_get_async_auth_lock_double_checked_locking.<locals>.<genexpr>   zCreated z locks, expected ~2)r   r  r  __init__rO  r[  ru  )r  rx  r   )r!   r  r  r  r   /test_get_async_auth_lock_double_checked_locking  s    r  c                     s   t dddd} | j I dH }| jj}tdD ]}| j I dH }||u s(J | jj|u s0J q| j I dH }| jj}||u sCJ ||u sIJ dS )zGTests that _get_async_auth_lock doesn't leak memory under repeated use.TrE   rF   ri   Nr  )r   r   r  r  rO  )r!   initial_lockinitial_creation_lockrX   r  
final_lockfinal_creation_lockr   r   r   *test_get_async_auth_lock_memory_efficiency  s    
r  c                     sR   t dddd} dt_| j I dH }|dusJ | j I dH }||u s'J dS )zJTests that _get_async_auth_lock works correctly with aiohttp session lock.TrE   rF   ri   N)r   r   r   r   _get_aiohttp_session)r!   initial_sessionsessionr   r   r   test_get_aiohttp_session  s   r  )m__doc__r  concurrent.futuresrL  r.   r   rG  r   unittestr   r   google.authrw   r   r  rt   r$   r   r   r   r=   r   r   r   r	   r   AIOHTTP_NOT_INSTALLEDr   	MagicMockmarkskipifrequires_aiohttpfixturer   r"   r%   r'   r3   r5   r7   rQ   rZ   r\   re   rh   rj   ry   r{   r|   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   boolr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r	  r  r  r  rZ  r^  r{  r  r  r  r  r  r  r  r  r   r   r   r   <module>   s   


	K$A	 "%*$

R
7

+

'
-

"
