B
    °F.\/  ã               @   s²  d dl mZmZmZ d dlm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mZ d dlmZ d dlmZ d d	lmZ d d
lmZmZmZ dd„ Zdd„ Zd4dd„Zdd„ Zdd„ Z dd„ Z!eeƒ dd„ ƒƒZ"eƒ dd„ ƒZ#ej$j%ej&dkddeƒ dd„ ƒƒZ'eƒ d d!„ ƒZ(eƒ d"d#„ ƒZ)eƒ d$d%„ ƒZ*eƒ d&d'„ ƒZ+ej$j%e	j, -d(¡d)deƒ d*d+„ ƒƒZ.eƒ d,d-„ ƒZ/d.d/„ Z0d0d1„ Z1d2d3„ Z2dS )5é    )Úprint_functionÚdivisionÚabsolute_import)Ú	timedeltaN)Úsleep)Úgen)ÚEvent)Útime)ÚAsyncProcess)Ú
mp_context)Úgen_testÚpristine_loopÚnodebugc             C   s   | j dd}| |¡ d S )Né   )Útimeout)ÚgetÚput)Zin_qZout_qÚobj© r   úBlib/python3.7/site-packages/distributed/tests/test_asyncprocess.pyÚfeed   s    r   c             C   s   t  |  ¡ ¡ d S )N)ÚsysÚexitr   )Úqr   r   r   r      s    r   c             C   s   t  | ¡ d S )N)r   r   )Úrcr   r   r   Úexit_now   s    r   c             C   s2   t   t jt j¡ xt t ¡ | ¡ tdƒ qW d S )Ng{®Gáz„?)ÚsignalÚSIGINTÚSIG_DFLÚosÚkillÚgetpidr   )Zsignumr   r   r   Úexit_with_signal#   s    r"   c               C   s   xt dƒ qW d S )Ng{®Gáz„?)r   r   r   r   r   Úwait*   s    r#   c             C   s&   |   tt ¡ ƒ¡ |   t ¡ j¡ d S )N)r   ÚlenÚ	threadingÚ	enumerateZcurrent_threadÚname)r   r   r   r   Úthreads_info/   s    r(   c           	   #   s  t  ¡ } t  ¡ }tt| |fd}| ¡ r,t‚|jd ks:t‚|jd ksHt‚|jrRt‚d|_|jsbt‚t	 
|¡}t	 
|j¡}t t¡ | ¡ V  W d Q R X | ¡ V  | ¡ s®t‚|jd k	s¼t‚|jd ksÊt‚tƒ }|jddV  tƒ | }d|  krþdksn t‚| ¡ st‚|jd k	s"t‚|jd ks2t‚t t¡ d|_W d Q R X |  d¡ | ¡ dksjt‚tƒ }|jd	dV  tƒ | }|d
ks–t‚| ¡ r¤t‚|jd k	s´t‚|jdksÄt‚tƒ }| ¡ V  tƒ | }|dksìt‚~t ¡  tƒ }x2|ƒ d k	r.tƒ |d k r.tdƒ t ¡  qþW |ƒ d k	rÎddlm‰  |ƒ }|d k	rÄt |¡}	t |¡}
~td|	|
ƒ ‡ fdd„|
D ƒ}x6t|ƒD ]*\}}td| |jj|jjt |j!ƒƒ q–W t "d¡ tƒ }x>|ƒ d k	rt# d¡V  t ¡  tƒ | }|dk sÖt‚qÖW d S )N)ÚtargetÚargsTg{®Gáz”?)r   gš™™™™™É?g{®Gáz„?Fr   é
   g      ð?r   g333333ã?é   gü©ñÒMbP?)Ú	FrameTypezrefs to proc:c                s   g | ]}t |ˆ ƒr|‘qS r   )Ú
isinstance)Ú.0Úr)r-   r   r   ú
<listcomp>}   s    ztest_simple.<locals>.<listcomp>zframes #%d:z'AsyncProcess should have been destroyedg       @)$r   ÚQueuer
   r   Úis_aliveÚAssertionErrorÚpidÚexitcodeÚdaemonÚweakrefÚrefZ_processÚpytestÚraisesÚjoinÚstartr	   r   r   ÚgcZcollectr   Útypesr-   r   ÚgetrefcountZget_referrersÚprintr&   Úf_codeÚco_nameÚco_filenameÚsortedÚf_localsZfailr   )Úto_childÚ
from_childÚprocZwr1Zwr2Zt1Zdtr=   Úpr   ZrefsZframesÚiÚfr   )r-   r   Útest_simple4   s€    













rM   c              c   s’   t  ¡ } ttd| id}d|_| ¡ r*t‚|jd ks8t‚| ¡ V  | ¡ sNt‚|jd ks\t‚|  	d¡ |j
ddV  | ¡ r€t‚|jdksŽt‚d S )Nr   )r)   ÚkwargsTr   g      @)r   )r   r2   r
   r   r7   r3   r4   r6   r=   r   r<   )r   rI   r   r   r   Útest_exitcodeŠ   s    

rO   Úntz
POSIX only)Úreasonc              c   sÂ   t ttjfd} d| _|  ¡ r"t‚| jd ks0t‚|  ¡ V  | j	ddV  |  ¡ rTt‚| jtj dfksjt‚t t
d} |  ¡ V  t | jtj¡ | j	ddV  |  ¡ r¨t‚| jtj dfks¾t‚d S )N)r)   r*   Tg      @)r   éÿ   )r)   )r
   r"   r   r   r7   r3   r4   r6   r=   r<   r#   r   r    r5   ÚSIGTERM)rI   r   r   r   Útest_signal   s    


rT   c              c   sX   t td} d| _|  ¡ V  |  ¡ V  | jddV  |  ¡ r>t‚| jt	j
 dfksTt‚d S )N)r)   Tg      @)r   rR   )r
   r#   r7   r=   Ú	terminater<   r3   r4   r6   r   rS   )rI   r   r   r   Útest_terminateµ   s    


rV   c           	   c   sÀ   t td} |  ¡  t t¡ |  ¡ V  W d Q R X t td} |  ¡ V  |  ¡  t t¡ |  ¡ V  W d Q R X t td} |  ¡ V  |  ¡ V  |  ¡  t t¡ |  ¡ V  W d Q R X |  ¡  d S )N)r)   )	r
   r   Úcloser:   r;   Ú
ValueErrorr=   rU   r<   )rI   r   r   r   Ú
test_closeÁ   s     





rY   c              #   s4  t  ¡ } t  ¡ }tƒ ‰ tj‡ ‡fdd„ƒ}tt| |fd‰ˆ  ¡  ˆ |¡ dˆ_	ˆ 
¡ V  t d¡V  ˆ ¡ stt‚ˆ  ¡ r€t‚|  d ¡ ˆ  tdd¡V  ˆ  ¡ s¨t‚ˆ ¡ r´t‚ttd‰ˆ  ¡  ˆ |¡ dˆ_	ˆ 
¡ V  t d¡V  ˆ ¡ søt‚ˆ  ¡ rt‚ˆ ¡ V  ˆ  tdd¡V  ˆ  ¡ s0t‚d S )	Nc             3   s    | ˆkst ‚tjV  ˆ  ¡  d S )N)r4   r   ZmomentÚset)Ú_proc)ÚevtrI   r   r   Úon_stopÝ   s    z#test_exit_callback.<locals>.on_stop)r)   r*   Tgš™™™™™©?é   )Zseconds)r)   )r   r2   r   r   Ú	coroutiner
   r   ÚclearZset_exit_callbackr7   r=   r   r3   r4   Zis_setr   r#   r   rU   )rG   rH   r]   r   )r\   rI   r   Útest_exit_callback×   s6    






ra   c              c   sr   t  ¡ } tt| fd}| ¡ V  | ¡ V  |  ¡ }|  ¡ }|dksFt‚|dksRt‚|  ¡  | j	 ¡  | j
 ¡  dS )zE
    The main thread in the child should be called "MainThread".
    )r)   r*   r^   Z
MainThreadN)r   r2   r
   r(   r=   r<   r   r4   rW   Z_readerZ_writer)r   rI   Z	n_threadsÚ	main_namer   r   r   Útest_child_main_thread  s    


rc   Úwinz num_fds not supported on windowsc              c   sÆ   t  d¡} ttd}d|_| ¡ V  | ¡ V  |  ¡ }| ¡ }ttd}d|_| ¡ V  | ¡ V  | 	¡ rnt
‚|jdks|t
‚tƒ }x>| ¡ |krÀt d¡V  td|| ¡ ƒ tƒ |d k s„t
‚q„W d S )NÚpsutil)r)   Tr   gš™™™™™¹?zfds:r+   )r:   Zimportorskipr
   r   r7   r=   r<   ÚProcessZnum_fdsr3   r4   r6   r	   r   r   rA   )re   rI   rJ   Zbeforer=   r   r   r   Útest_num_fds  s$    






rg   c              c   s0   t tdd} |  ¡ V  t d¡V  |  ¡ V  d S )N)r   )r)   r*   gš™™™™™¹?)r
   r   r=   r   rU   )rI   r   r   r   Útest_terminate_after_stop2  s    
rh   c             C   s"   |   ¡  d}t|ƒ | d¡ d S )Ng      @zchild should have exited by now)rZ   r   Úsend)Úworker_readyÚ
child_pipeZshorter_timeoutr   r   r   Ú_worker_process:  s    	rl   c          	      sN   ‡ fdd„}t ƒ 2}z|jt |¡dd W d| ¡  tdƒ‚X W dQ R X dS )z¶ Simulate starting an AsyncProcess and then dying.

    The child_alive pipe is held open for as long as the child is alive, and can
    be used to determine if it exited correctly. c              3   s8   t  ¡ } tt| ˆ fd}| ¡ V  |  ¡  t d¡ d S )N)r)   r*   rR   )r   r   r
   rl   r=   r#   r   Ú_exit)rj   Zworker)rk   r   r   Úparent_process_coroutineS  s    
z1_parent_process.<locals>.parent_process_coroutiner+   )r   Nz*this should be unreachable due to os._exit)r   Zrun_syncr   r_   ÚstopÚRuntimeError)rk   rn   Zloopr   )rk   r   Ú_parent_processN  s    rq   c              C   sê   t jdd\} }zÊt jt|fd}| ¡  | ¡  | ¡  d}y|  |¡}W n, tk
rx   t	j
 d¡sptdƒ‚d}Y nX |s‚t‚y|  ¡ }W n: tk
r¢   Y n6 tk
rÈ   t	j
 d¡sÄtdƒ‚Y nX td |¡ƒ‚W d	|  ¡  X d	S )
aI   Check that a child process started by AsyncProcess exits if its parent
    exits.

    The motivation is to ensure that if an AsyncProcess is created and the
    creator process dies unexpectedly (e.g, via Out-of-memory SIGKILL), the
    child process and resources held by it should not be leaked.

    The child should monitor its parent and exit promptly if the parent exits.

    [test process] -> [parent using AsyncProcess (dies)] -> [worker process]
                 \                                          /
                  \________ <--   child_pipe   <-- ________/
    F)Zduplex)r)   r*   g      @rd   zshould only raise on windowsTzunreachable: {}N)r   ZPiperf   rq   r=   rW   r<   ZpollÚEnvironmentErrorr   ÚplatformÚ
startswithr4   ZrecvÚEOFErrorrp   Úformat)Zchildren_aliverk   ÚparentZshort_timeoutÚreadableÚresultr   r   r   Ú/test_asyncprocess_child_teardown_on_parent_exitl  s*    
rz   )r   )3Z
__future__r   r   r   Zdatetimer   r>   r   r   r   r%   r	   r   r8   r:   Ztornador   Ztornado.locksr   Zdistributed.metricsZdistributed.processr
   Zdistributed.utilsr   Zdistributed.utils_testr   r   r   r   r   r   r"   r#   r(   rM   rO   ZmarkZskipifr'   rT   rV   rY   ra   rc   rs   rt   rg   rh   rl   rq   rz   r   r   r   r   Ú<module>   sJ   
U,