o
    Yi8                     @   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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yg   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/ Z/d0d1 Z0d2d3 Z1d4d5 Z2d6d7 Z3d8d9 Z4d:d; Z5d<d= Z6d>d? Z7d@dA Z8dBdC Z9dDdE Z:dFdG Z;dHdI Z<dJdK Z=dLdM Z>dNdO Z?dPe@fdQdRZAdPe@fdSdTZBdPe@fdUdVZCdWdX ZDdYdZ ZEd[d\ ZFd]d^ ZGd_d` ZHdadb ZIdcdd ZJdedf ZKdgdh ZLdidj ZMdkdl ZNdmdn ZOdodp ZPdqdr ZQdsdt ZRdudv ZSdwdx ZTdydz ZUd{d| ZVd}d~ ZWdd ZXdd ZYdd ZZdd Z[dd Z\ejjdd Z]ejjdd Z^dd Z_ejjdd Z`ejjdd Zaejjdd 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ejjdd Zid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)Zautousec                   c   s    d V  dt _d S )NF)
api_clienthas_aiohttp r   r   n/home/kim/smarthome/.venv/lib/python3.10/site-packages/google/genai/tests/client/test_client_initialization.pyreset_has_aiohttp2   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Zraising
setenvdelenvr   modelsr   vertexaiapi_key
isinstancer   BaseApiClientmonkeypatchr   clientr   r   r    test_ml_dev_from_gemini_env_only8      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_emptyD   s   r#   c                 C   r   )Ngoogle_api_keyr   r   Fr   r   r   r   r   r    test_ml_dev_from_google_env_onlyP   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   r1   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   r0   r   r   r   r   r   test_api_key_with_new_linen   s
   r3   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_constructorx   s   
r5   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 )NZv1main!https://placeholder-fake-url.com/X-Custom-HeaderZcustom_value_mldevi'  )api_versionbase_urlheaderstimeoutv1Bhttps://{self.location}-aiplatform.googleapis.com/{{api_version}}/Zcustom_value_vertexaii*  r$   r   http_optionsr9   r8   r:   r;   Tfake_project_idfake-locationr   projectlocationr?   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   	



rL   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<   r6   r7   custom_value)invalid_version_keyr9   r:   r=   )r8   r9   invalid_header_keyr$   r>   rN   Tr@   rA   rB   rO   )r   	Exceptionr   
ValueErrorstr)rH   rI   _er   r   r   .test_constructor_with_invalid_http_options_key   s6   
rU   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<   r6   r7   rM   )r8   r9   r:   r=   r$   r>   r9   r8   r:   Tr@   rA   rB   )
r	   HttpOptionsr   r   r   r   rF   r9   r8   r:   rG   r   r   r   3test_constructor_with_http_options_as_pydantic_type   sf   	



rW   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 )Nr@   rA   GOOGLE_GENAI_USE_VERTEXAI1GOOGLE_CLOUD_PROJECTGOOGLE_CLOUD_LOCATIONr   r   r   r   r   rC   rD   r   
project_idrD   r   r   r   r   test_vertexai_from_env_11     r`   c                 C   rX   )Nr@   rA   rY   truer[   r\   r]   r^   r   r   r   test_vertexai_from_env_true?  ra   rc   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 )Nr@   rA   Tr   rC   rD   )	r   r   r   r   rC   rD   r   r   r   )r_   rD   r   r   r   r   test_vertexai_from_constructorM  s   re   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"   r\   r   r   c                 S      dS N)NNr   Zscopesr   r   r   mock_auth_defaultd     zBtest_invalid_vertexai_constructor_empty.<locals>.mock_auth_defaultdefaultTr   N)pytestraisesrQ   r   setattrgoogleauthr   )r   ri   r   r   r   'test_invalid_vertexai_constructor_empty]  s   
"rs   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"   r\   r   r   c                 S   rf   rg   r   rh   r   r   r   ri   q  rj   zLtest_vertexai_constructor_empty_base_url_override.<locals>.mock_auth_defaultrk   Tr9   zhttps://override.com/r   r?   rm   )r   rp   rq   rr   r   r   r   rD   )r   ri   r   r   r   r   1test_vertexai_constructor_empty_base_url_overridek  s   
ru   c                 C   sN   t t | dd | dd t  W d    d S 1 s w   Y  d S )Nr   r"   r   )rn   ro   rQ   r   r   )r   r   r   r   $test_invalid_mldev_constructor_empty{  s
   "rv   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 )Nr@   rA   fake-api_keyT)r   rC   rD   r   r   rP   r   rQ   r_   rD   r   rT   r   r   r   "test_invalid_vertexai_constructor1  s   rz   c                  C   sJ   t  } d}tt td| |d W d    d S 1 sw   Y  d S )Nrw   T)r   r   r   )r   AnonymousCredentialsrn   ro   rQ   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 )Nr\   Fr   r@   Tr   rC   global)contextr   r   r   r   rD   )r   mr_   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 )
Nr@   r\   Fr   r   r"   T)r   r   rC   r   )
r   r{   r   r   r   r   r   r   rD   rC   )r   r|   r_   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 )NZexplicit_project_idenv_api_keyr\   Fr   r[   r   Tr~   r   	r   r   r   r   r   r   rD   rC   r   r   r_   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_idr\   Fr   r[   Tr9   zhttps://fake-url.googleapis.comrt   r   r   r   r   r   r   r   rD   rC   r   r_   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   r\   Fr   r[   Tr9   zhttps://fake-url.comrt   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   r\   Fr   r[   r   Trl   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 )Nr@   zus-central1r\   Fr   Trd   )r   r   r   r   r   rD   rC   r   r_   rD   r   r   r   r   r   >test_vertexai_no_default_location_when_location_explicitly_set  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 )Nr@   zus-west1r\   r[   Trl   )r   r   r   r   r   rD   rC   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_keyr\   Fr   r[   r   r"   Tr   r   r   )r   r   r   r   r   r   r   2test_vertexai_no_default_location_with_apikey_only  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[   r@   r\   rA   r   r   T)r   r   )r   r{   r   r   r   r   r   rC   rD   r   _credentialsr   r   r   )r   r|   r   r   r   r   "test_vertexai_explicit_credentials!  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 )NZconstructor_project_idzconstructor-locationr[   r   r\   Zenv_locationr   r"   Trd   r   r   r   r   r   rC   rD   r   r   r   r   r^   r   r   r   &test_vertexai_explicit_arg_precedence14  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 )	NZconstructor_apikeyr[   r"   r\   r   r   Tr   r   r   r   r   r   &test_vertexai_explicit_arg_precedence2I  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 )Nr@   rA   rw   )rC   rD   r   rx   ry   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'   Zconstructor_api_keyr   Zgoogle_env_api_keyr   Zgemini_env_api_keyr4   r)   r*   r2   r   r   r   "test_mldev_explicit_arg_precedencej  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 )Nr@   rA   rY   rZ   r[   r\   r   r   r   r   r   r   r   r   )
r   r   r   r   r   rC   rD   r   r   r   )r   r   r_   rD   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   Zclient1Z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   r\   r"   r[   T)r   r   
aiplatform)r   r   r   r   r   rC   rD   r   _http_optionsr9   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   r\   r"   r[   Trl   r   r   r   r   r   r   r   r   rC   rD   r   r9   r   r   r   r   r   r   r   1test_vertexai_apikey_from_env_google_api_key_only     
r   c                 C   r   )Nr   r   r   Fr   r\   r"   r[   Trl   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"   r\   r[   Trl   r   r   r   r   r   r   r   rC   rD   r   r9   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   r\   r"   r[   Trl   r   r)   )r+   r,   r-   r   r   r   r   r   r   rC   rD   r   r9   r   r   r   r.   r/   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   r@   rA   T)r   rC   rD   r   )rn   ro   rQ   r   )r   r_   rD   r   r   r   )test_vertexai_apikey_invalid_constructor1   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   r@   rA   r[   r\   r   r"   Tr   r   r   r   r   r_   rD   r   r   r   r   test_vertexai_apikey_combo1/  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   r@   rA   r[   r"   r\   r   Trd   r   r   r   r   r   r   test_vertexai_apikey_combo2C  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 )
Nr@   rA   r   r[   r\   r   Trl   r   r   )r   r_   rD   r   r   r   r   r   test_vertexai_apikey_combo3W  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 )Nr@   r   r[   r\   T)r   rD   z"https://aiplatform.googleapis.com/)r   r   r   r   r   rC   rD   r   r9   r   r   r   r^   r   r   r   test_vertexai_global_endpointk  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'   r@   rA   r   r[   r\   Tr   INFOz8The user provided Vertex AI API key will take precedence)r+   r,   r-   r   r   r.   )r   r0   r_   rD   r   rS   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	   rV   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	   rV   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   Z	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 )
Nr9   r6   r=   r$   r>   Tr@   rA   rB   rE   rG   r   r   r   0test_constructor_with_base_url_from_http_options  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/Z
gemini_urlZ
vertex_urlr$   r4   r9   Tr@   rA   rd   r9   set_default_base_urlsr   r   r   r   rF   )rJ   rK   r   r   r   9test_constructor_with_base_url_from_set_default_base_urls1  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 )Nr9   (https://gemini-constructor-base-url.com/(https://vertex-constructor-base-url.com/r   r   r   r$   r>   Tr@   rA   rB   r   rG   r   r   r   Jtest_constructor_with_constructor_base_url_overrides_set_default_base_urlsL  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/r9   r   r   r$   r>   Tr@   rA   rB   r   )r   r   r   r   r   rF   r9   r   )r   rH   rI   rJ   rK   r   r   r   Jtest_constructor_with_constructor_base_url_overrides_environment_variablesq  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$   r4   r9   Tr@   rA   rd   )r   r9   r   r   r   r   r   rF   r   rJ   rK   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$   r4   r9   Tr@   rA   rd   )r   r   r   r   r   rF   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 )NTr@   rA   rd   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 )NTr@   rA   r   rB   F)r   r	   rV   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 )NTr@   rA   	transportr   rB   F)	r   r	   rV   httpxZ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.Tr@   rA   rd   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.Tr@   rA   rd   N)r   r   r   r   r   r   )r   lock1lock2Zlock3r   r   r   .test_get_async_auth_lock_returns_same_instance  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jdi dd}tj|d}| tjd| tdddd d j_tjjdd& fddtdD }tj|D ]}| jdks|J qqW 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sJ dS )z1Tests that synchronous API calls are thread-safe.r   Fr   specinitial-tokenNtest-projectreturn_valuerk   c                       d _ d _d S Nrefreshed-tokenFtokenexpiredrequest
mock_credsr   r   refresh_side_effect/     
zCtest_threaded_generate_content_locking.<locals>.refresh_side_effectZside_effect   z@{"candidates": [{"content": {"parts": [{"text": "response"}]}}]})status_coder:   r.   r  Tr@   rA   rd   r   )max_workersc                    $   g | ]}j  jjd t|dqS z
gemini-pro)modelcontentsZsubmitr   Zgenerate_contentrR   .0ir   executorr   r   
<listcomp>G      z:test_threaded_generate_content_locking.<locals>.<listcomp>
   responsec                    r  r  r  r  r  r   r   r!  W  r"     )r   r   Mockr   Credentialsr  r  quota_project_idrp   rq   rr   refreshr   Responser   ZSyncHttpxClientr   r   r   
concurrentfuturesZThreadPoolExecutorrangeZas_completedresultr.   assert_called_onceassert_not_calledZ
call_count)r   ri   r  mock_refreshZmock_httpx_responseZmock_requestr,  futurer   )r   r   r  r   &test_threaded_generate_content_locking!  sX   

r3  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  rk   c                    r  r  r
  r  r  r   r   r  s  r  z<test_async_access_token_locking.<locals>.refresh_side_effectr  Tr@   rA   rd   )r  r  r  )r	  r	  r	  )r   r&  r   r'  r  r  r(  rp   rq   rr   r)  r   r   r   r   gatherZ_async_access_tokenr/  r0  )r   ri   r  r1  r   tokensr   r  r   test_async_access_token_lockinge  s>   

r6  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.Tr@   rA   rd   task_idc                        j  I d H }| t|fS rm   r   r   id)r7  r   r   r   r   get_lock_task     zAtest_get_async_auth_lock_concurrent_access.<locals>.get_lock_taskc                       g | ]} |qS r   r   r  )r;  r   r   r!        z>test_get_async_auth_lock_concurrent_access.<locals>.<listcomp>r%  Nc                 S      g | ]}|d  qS    r   r  r.  r   r   r   r!    r>  c                 3       | ]	}| d  kV  qdS r   Nr   r  Z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   r?  r   r   rB  r   r   r   r!    r>  zAll tasks should complete)r   intr-  r   r4  allsortedlist)tasksresultstask_idsr   )r   r;  rG  r   *test_get_async_auth_lock_concurrent_access  s   
 rR  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.Tr@   rA   rd   op_idc                    s&   t dI d H   |  d|  S )Ng{Gz?Z
operation_)r   sleepappend)rS  )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   r  rS   r   r   r   r!        zJtest_get_async_auth_lock_doesnt_block_other_operations.<locals>.<listcomp>r#  c                    r=  r   r   r  )rW  r   r   r!    r>     Nz&All auth lock requests should completezAll work tasks should completez$All async operations should completec                 S   s   g | ]}t |qS r   )r:  r  r   r   r   r   r!    r>  c                 3   rC  rD  r   rE  rF  r   r   rH        zItest_get_async_auth_lock_doesnt_block_other_operations.<locals>.<genexpr>皙?zOperations took too long (.3fz s), suggesting blocking occurred)	r   rK  r   get_event_looptimer-  r4  lenrL  )
start_time
auth_tasksZ
work_tasksauth_resultsZwork_resultsZend_time
total_timer   )r   rV  rG  rW  r   6test_get_async_auth_lock_doesnt_block_other_operations  s,   
rh  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.Tr@   rA   rd   N)r   r   r   _async_auth_lock_creation_lockr   r   r   r   )r   r   Zcreation_lockr   r   r   r   0test_get_async_auth_lock_creation_lock_lifecycle  s    rj  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.Tr@   rA   rd   d   call_idc                    s<   t   } j I d H }t   }| t||| fS rm   )r   ra  rb  r   r   r:  )rl  startr   endr   r   r   get_lock_with_timing  s
   zAtest_get_async_auth_lock_under_load.<locals>.get_lock_with_timingc                    r=  r   r   r  )ro  r   r   r!    r>  z7test_get_async_auth_lock_under_load.<locals>.<listcomp>Nc                 S   r?  rJ  r   r  rr   r   r   r!    r>  c                 S   r?  r@  r   rp  r   r   r   r!    r>  c                 S   r?  )   r   rp  r   r   r   r!    r>  c                 3   rC  rD  r   rE  rF  r   r   rH    rI  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   rK  r   ra  rb  r-  r4  rc  rM  rN  rL  max)Znum_concurrent_callsrd  rO  rP  rg  Zcall_idsZ
call_timesZmax_call_timer   )r   ro  rG  r   #test_get_async_auth_lock_under_load  s2   

rt  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.Tr@   rA   rd   r  z
test-tokenFNrS  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   rT  )rS  r   r   r   r   auth_operation6  s   0zQtest_get_async_auth_lock_interleaved_with_auth_operations.<locals>.auth_operationreq_idc                    r8  rm   r9  )rx  r   r   r   r   lock_request=  r<  zOtest_get_async_auth_lock_interleaved_with_auth_operations.<locals>.lock_requestc                    r=  r   r   r  )rw  r   r   r!  B  r>  zMtest_get_async_auth_lock_interleaved_with_auth_operations.<locals>.<listcomp>r#  c                    r=  r   r   r  )ry  r   r   r!  C  r>  c                 S   r?  r@  r   rB  r   r   r   r!  N  r>  c                 3   rC  rD  r   rE  rF  r   r   rH  O  r^  zLtest_get_async_auth_lock_interleaved_with_auth_operations.<locals>.<genexpr>c                 s   s    | ]}| d V  qdS )rv  N)
startswithrB  r   r   r   rH  R  s    )r   r   r&  r   r'  r  r  r(  r   r   rK  r-  r   r4  rc  rL  )r  re  Z
lock_tasksrf  Zlock_resultsr   )rw  r   rG  ry  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 )NTr@   rA   rd   )r   r   r   r   r   r   r   create_client_and_get_lockY  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 )Nru  success)r   rT  r   r   r   r   test_lock_functionalityj  s
   0zPtest_get_async_auth_lock_with_event_loop_switch.<locals>.test_lock_functionalityr}  )r   r   r   r   r   )r|  r   r   r  r.  r   r~  r   /test_get_async_auth_lock_with_event_loop_switchU  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.Tr@   rA   rd   r   c                    s    d  d7  < | S )Nr   rA  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                    rX  r   rY  rZ  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 rD  r   r]  )locksr   r   rH    r^  zBtest_get_async_auth_lock_double_checked_locking.<locals>.<genexpr>   zCreated z locks, expected ~2)r   r   r   __init__r-  r4  rL  )r  rO  r   )r   r  r  r  r   /test_get_async_auth_lock_double_checked_lockings  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.Tr@   rA   rd   Nrk  )r   r   r   ri  r-  )r   Zinitial_lockZinitial_creation_lockrS   r   Z
final_lockZ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.Tr@   rA   rd   N)r   r   r   r   Z_get_aiohttp_session)r   Zinitial_sessionsessionr   r   r   test_get_aiohttp_session  s   r  )j__doc__r   concurrent.futuresr+  r,   r   r   Zunittestr   r   Zgoogle.authrq   r   r   rn   r"   r   r   r   r9   r   r   r   r	   r   ZAIOHTTP_NOT_INSTALLEDr   Z	MagicMockmarkZskipifZrequires_aiohttpZfixturer   r    r#   r%   r1   r3   r5   rL   rU   rW   r`   rc   re   rs   ru   rv   rz   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   r3  r6  rR  rh  rj  rt  r{  r  r  r  r  r   r   r   r   <module>   s   


	K$A	 "%*$

D
7

+

'
-

"
