a
    mzf9A                     @   s0  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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mZmZ ddlmZmZmZmZ ddlmZmZmZ ddlmZ dd	lmZmZmZ epeZ e
j!j"e#ed
 ddZ$e
j!j"eddZ%e
j&dddd Z'e
j&dd Z(e
j&dd Z)dd Z*dd Z+e
j!,de-e.e/e0fdd Z1dd Z2e
j!,deefd d! Z3e$d"d# Z4e$d$d% Z5d&Z6d'Z7G d(d) d)eZ8e
j&d*d+ Z9e$e%e
j!j:d,dd-d.d/ Z;e
j!j"e d0de$e%d1d2 Z<e
j!j"ed3de
j!j,d4d5d6d7e
j!=d8d9d: Z>e
j!j"e#ed; d<de
j!,deefd=d> Z?eZ@esxe@sxe
j!Ae>Z>e
j&d?d@ ZBe
j&dAd4 ZCe
j&dBd8 ZDe
j!,dCdDdEeEdFfdDdGeEdFfdHdIdDeEdFeEdFfddEeEdFfddGeEdFfdJdeEdFeEdFff	dKdL ZFe
j!,dMdNdOdP ZGdQdR ZHdS )SzTests for the HTTP server.    N)	DefaultGc   )btonntob)IS_LINUXIS_MACOS
IS_WINDOWSSYS_PLATFORM)IS_UID_GID_RESOLVABLEGateway
HTTPServer)
ThreadPool)ANY_INTERFACE_IPV4ANY_INTERFACE_IPV6EPHEMERAL_PORTAF_UNIXz:UNIX domain sockets are only available under UNIX-based OSreasonz9Peercreds lookup does not work under macOS/BSD currently.)Zabstractfile)paramsc                 C   s   dj f i t }| |S )9Check that bound UNIX socket address is stored in server.zunix_{request.param}_sock)formatlocalsgetfixturevalue)requestname r   F/var/www/media/lib/python3.9/site-packages/cheroot/test/test_server.pyunix_sock_file,   s    r   c                   C   s4   t stdjtd ddttt	 f
 S )z'Return an abstract UNIX socket address.z2{os} does not support an abstract socket namespace)os    s    cheroot-test-socket)r   pytestskipr   r	   joinr   struuiduuid4decoder   r   r   r   unix_abstract_sock3   s    r(   c                  c   s*   t  \} }|V  t|  t| dS )zYield a unix file socket.N)tempfilemkstempr   closeunlink)Ztmp_sock_fhZtmp_sock_fnamer   r   r   unix_file_sockA   s    
r-   c                  C   s~   t ttftd} | jrJ | jjr&J |   | js8J | jjsDJ | jjD ]}|jsLJ qL|   | jjrpJ | jrzJ dS )zBCheck that prepare() makes the server ready, and stop() clears it.	bind_addrgatewayN)	r   r   r   r   readyrequests_threadspreparestop)
httpserverZthrr   r   r   test_prepare_makes_server_readyL   s    

r7   c                  C   sf   t ttftd} |   tj| jd}|  |	d |
 sDJ |   |	d |
 rbJ dS )0Check that stop() interrupts running of serve().r.   target      ?N)r   r   r   r   r4   	threadingThreadservestartr#   is_aliver5   )r6   serve_threadr   r   r   test_stop_interrupts_servec   s    

rB   exc_clsc                    s   dj t dt tttftdt	  fdd}
  tj|d}|  |d | stJ  _|d | rJ  u sJ dS )	z0Check that assigning interrupt stops the server.zshould catch {uuid!s})r%   r.   c               
      sL   z   W n:  yF }  z"t| kr2 W Y d } ~ n
d } ~ 0 0 d S N)r>   r$   put)erC   r6   Zinterrupt_msgZraise_marker_sentinelZresult_qr   r   rA      s
    z+test_server_interrupt.<locals>.serve_threadr9   r;   N)r   r%   r&   objectr   r   r   r   queueQueuer4   r<   r=   r?   r#   r@   Z	interrupt
get_nowait)rC   rA   r   rG   r   test_server_interruptw   s"    


rL   c                  C   s|   t ttftd} |   dd }|| jj_tj	| j
d}|  || jtrPdnd  | rdJ | jjrpJ |   dS )r8   r.   c                  _   s
   t  d S rD   )KeyboardInterrupt)argskwargsr   r   r   raise_keyboard_interrupt   s    zTtest_serving_is_false_and_stop_returns_after_ctrlc.<locals>.raise_keyboard_interruptr9      r   N)r   r   r   r   r4   Z_connections	_selectorselectr<   r=   r>   r?   r#   Zexpiration_intervalIS_SLOW_ENVr@   Z_servingr5   )r6   rP   rA   r   r   r   2test_serving_is_false_and_stop_returns_after_ctrlc   s    
rU   ip_addrc                 C   s6   |  |tf}|jd |ks J |jd tks2J dS )z0Check that bound IP address is stored in server.r      N)sendr   r/   )http_serverrV   r6   r   r   r   test_bind_addr_inet   s    	rZ   c                 C   s   |  |}|j|ksJ dS )r   NrX   r/   rY   r   r6   r   r   r   test_bind_addr_unix   s    
r]   c                 C   s   |  |}|j|ksJ dS )zBCheck that bound UNIX abstract socket address is stored in server.Nr[   )rY   r(   r6   r   r   r   test_bind_addr_unix_abstract   s    
r^   z/peer_creds/idsz/peer_creds/textsc                       s$   e Zd Z fddZdd Z  ZS )_TestGatewayc                    sz   | j }|j}t|j}|tkrH|j|j|jf}| d	t
t| d S |tkrl| d	|j|jf d S tt|  S )N|!)reqconnr   uriPEERCRED_IDS_URIZpeer_pidZpeer_uidZpeer_gidsend_payloadr#   mapr$   PEERCRED_TEXTS_URIZ	peer_userZ
peer_groupsuperr_   respond)selfrb   rc   Zreq_uriZ
peer_creds	__class__r   r   rj      s    
z_TestGateway.respondc                 C   s&   | j }d|_|  |t| d S )Ns   200 OK)rb   statusZensure_headers_sentwriter   )rk   payloadrb   r   r   r   rf      s    z_TestGateway.send_payload)__name__
__module____qualname__rj   rf   __classcell__r   r   rl   r   r_      s   r_   c                 C   s   |  |}t|_d|_|S )z3Construct a test server with ``peercreds_enabled``.T)rX   r_   r0   Zpeercreds_enabledr\   r   r   r   peercreds_enabled_server   s    
ru      )ZrerunsZreruns_delayc           	      C   s   |}|j }t|tr| }tjj|dd}djf i t }t	
 t	 t	 f}dtt|}t X tj|t | d}|  |j|ksJ tj|t | d}|jdksJ W d   n1 s0    Y  dS )z2Check that ``PEERCRED`` lookup works when enabled. safehttp+unix://{quoted}r`   timeouti  N)r/   
isinstancebytesr'   urllibparsequoter   r   r   getpidgetuidgetgidr#   rg   r$   requests_unixsocketmonkeypatchr2   getre   raise_for_statustextrh   status_code)	http_request_timeoutru   r6   r/   quotedunix_base_uriZexpected_peercredsZpeercreds_resppeercreds_text_respr   r   r   test_peercreds_unix_sock  s(    

r   zDModules `grp` and `pwd` are not available under the current platformc           
      C   s   |}d|_ |j}t|tr"| }tjj|dd}djf i t	 }ddl
}ddl}|t j|t jf}dtt|}t 8 tj|t | d}	|	  |	j|ksJ W d   n1 s0    Y  dS )	z6Check that ``PEERCRED`` resolution works when enabled.Trw   rx   rz   r   Nra   r{   )Zpeercreds_resolve_enabledr/   r}   r~   r'   r   r   r   r   r   grppwdgetpwuidr   r   pw_namegetgrgidr   gr_namer#   rg   r$   r   r   r2   r   rh   r   r   )
r   ru   r6   r/   r   r   r   r   Zexpected_textcredsr   r   r   r   $test_peercreds_unix_sock_with_lookup"  s(    

r   z\This regression test is for a Linux bug, and the resource module is not available on Windowsresource_limit)i   i   r   )Zindirectmany_open_socketsc                    sb   | j j  fddt _| j _| d tjdksBJ tfddjD s^J dS )a>  Test the server does not crash with a high file-descriptor value.

    This test shouldn't cause a server crash when trying to access
    file-descriptor higher than 1024.

    The earlier implementation used to rely on ``select()`` syscall that
    doesn't support file descriptors with numbers higher than 1024.
    c                    s   j | j   | S rD   )filenosaddsocketfileno)rc   )_old_process_connnative_process_connr   r   r   g  s    zAtest_high_number_of_file_descriptors.<locals>.native_process_conn/r   c                 3   s   | ]}| kV  qd S rD   r   ).0fnr   r   r   	<genexpr>u  r    z7test_high_number_of_file_descriptors.<locals>.<genexpr>N)Zserver_instanceZprocess_connsetr   connectlenany)Znative_server_clientr   r   )r   r   r   r   $test_high_number_of_file_descriptorsJ  s    
r   SO_REUSEPORTz5socket.SO_REUSEPORT is not supported on this platformc                 C   s   t |td d }t  |}|t jt jd ||tf t| dd t	dd}|
|d}|  |  |  |jdu sJ dS )z5Check that port initialized externally can be reused.r   rW   Nr   T)r/   r0   
reuse_portr4   )r   getaddrinfor   
setsockopt
SOL_SOCKETr   bindr   getsocknamer   spyr4   r5   r+   Zspy_exception)rY   rV   Zmockerfamilysserverr   r   r   r   test_reuse_portx  s    
r   c                   c   s4   t    dV  W d   n1 s&0    Y  dS )z7Disable garbage collection when this fixture is in use.N)r   Znogcr   r   r   r   _garbage_bin  s    r   c                 c   sn   t jddd}||j\}}||j| jd |f z| jV  W ||j||f n||j||f 0 dS )z7Set the resource limit two times bigger then requested.resourcez&The "resource" module is Unix-specificr   r   N)r!   ZimportorskipZ	getrlimitZRLIMIT_NOFILEZ	setrlimitparam)r   r   Z
soft_limitZ
hard_limitr   r   r   r     s    
c              	   c   s   |  d g }zdt|D ]&}t }|| | |kr q@q|d  }||ksXJ |V  W |D ]}|  qdn|D ]}|  qx0 dS )z<Allocate a lot of file descriptors by opening dummy sockets.r   N)r   ranger   appendr   r+   )r   r   Ztest_sockets_sockZthe_highest_filenoZtest_socketr   r   r   r     s    

)
minthreads
maxthreadsinited_maxthreadsrW   infr   )rW   rW   rW   )rW   r   r   )r   r   r   c                 C   s.   t d| |d}|j| ksJ |j|ks*J dS )zTest setting the number of threads in a ThreadPool.

    The ThreadPool should properly set the min+max number of the threads to use
    in the pool if those limits are valid.
    Nr   minmax)r   r   r   )r   r   r   tpr   r   r   test_threadpool_threadrange_set  s    r   r   r   error))r   r   min=-1 must be > 0)r   r   r   )r   rW   r   )r   r   r   )r   r   min=0 must be > 0)r   r   r   )r   rW   r   )r   r   r   )rW   r   KExpected an integer or the infinity value for the `max` argument but got 0.)rW   r;   zMExpected an integer or the infinity value for the `max` argument but got 0.5.)r   r   r   )r   1zMExpected an integer or the infinity value for the `max` argument but got '1'.)r   rW   zmax=1 must be > min=2c                 C   sD   t jttf|d td| |d W d   n1 s60    Y  dS )zTest that a ThreadPool rejects invalid min/max values.

    The ThreadPool should raise an error with the proper message when
    initialized with an invalid min+max number of threads.
    matchNr   )r!   raises
ValueError	TypeErrorr   r   r   r   r   #test_threadpool_invalid_threadrange  s    r   c                 C   s^   |  tddd  tdd}|  tjtdd |  W d   n1 sP0    Y  dS )zTest for ThreadPool multi-start behavior.

    Tests that when calling start() on a ThreadPool multiple times raises a
    :exc:`RuntimeError`
    Z_spawn_workerc                 S   s   t jddS )NT)r1   )typesSimpleNamespace)r   r   r   r   <lambda>(  r    z7test_threadpool_multistart_validation.<locals>.<lambda>N)r   z%Threadpools can only be started once.r   )setattrr   r?   r!   r   RuntimeError)r   r   r   r   r   %test_threadpool_multistart_validation  s    
r   )I__doc__r   rI   r   r)   r<   r   r%   urllib.parser   r!   r2   r   Zpypytools.gc.customr   _compatr   r   r   r   r   r	   r   r
   r   r   Zworkers.threadpoolr   Ztestingr   r   r   rT   markZskipifhasattrZunix_only_sock_testZnon_macos_sock_testZfixturer   r(   r-   r7   rB   ZparametrizeIOErrorrM   OSErrorr   rL   rU   rZ   r]   r^   re   rh   r_   ru   Zflakyr   r   Zusefixturesr   r   ZISSUE511Zforkedr   r   r   floatr   r   r   r   r   r   r   <module>   s   





	
$



!
 





