a
    kxÛg=  ã                   @   sf  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Zd dlmZ d dlmZmZmZmZmZmZmZmZ d dlmZ d dlmZmZ dZeeksÀJ ‚dZeeksÐJ ‚dZeedƒoæeed	ƒZ d
d„ Z!dd„ Z"dd„ Z#dd„ Z$G dd„ dƒZ%e  &dd¡Z'G dd„ de(ƒZ)G dd„ dej*ƒZ+dd„ Z,G dd„ dƒZ-dd„ Z.dS ) é    N)Úsupport)ÚruntestÚINTERRUPTEDÚCHILD_ERRORÚPROGRESS_MIN_TIMEÚformat_test_resultÚ
TestResultÚ	is_failedÚTIMEOUT)Úsetup_tests)Úformat_durationÚprint_warningg      >@g     Àr@ÚsetsidÚkillpgc                 C   s&   | j tkrdS |jr"t| |ƒr"dS dS )NTF)Úresultr   Zfailfastr	   )r   Úns© r   ú1/usr/lib/python3.9/test/libregrtest/runtest_mp.pyÚ	must_stop&   s
    
r   c                 C   s&   t  | ¡\}}tjf i |¤Ž}||fS ©N)ÚjsonÚloadsÚtypesÚSimpleNamespace)Úworker_argsÚns_dictÚ	test_namer   r   r   r   Úparse_worker_args.   s    r   c                 C   sx   t |ƒ}|| f}t |¡}tjgt ¡ ¢d‘d‘d‘d‘|‘}i }trNd|d< tj	|ftj
tj
dtjdktjdœ|¤ŽS )	Nz-uz-mztest.regrtestz--worker-argsTZstart_new_sessionÚnt)ÚstdoutÚstderrZuniversal_newlinesZ	close_fdsÚcwd)Úvarsr   ÚdumpsÚsysÚ
executabler   Zargs_from_interpreter_flagsÚUSE_PROCESS_GROUPÚ
subprocessÚPopenÚPIPEÚosÚnameZSAVEDCWD)Ztestnamer   r   r   ÚcmdÚkwr   r   r   Úrun_test_in_subprocess4   s4    
ÿþþýýûúr.   c                 C   s<   t | ƒ t| |ƒ}tƒ  tt t|ƒ¡dd t d¡ d S )NT©Úflushr   )r   r   Úprintr   r#   Úlistr$   Úexit)r   r   r   r   r   r   Úrun_tests_workerM   s
    
r4   c                   @   s0   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
S )ÚMultiprocessIteratorz8A thread-safe iterator over tests for multiprocess mode.c                 C   s   t  ¡ | _|| _d S r   )Ú	threadingZLockÚlockÚ
tests_iter)Úselfr8   r   r   r   Ú__init__^   s    
zMultiprocessIterator.__init__c                 C   s   | S r   r   ©r9   r   r   r   Ú__iter__b   s    zMultiprocessIterator.__iter__c                 C   sB   | j ( | jd u rt‚t| jƒW  d   ƒ S 1 s40    Y  d S r   )r7   r8   ÚStopIterationÚnextr;   r   r   r   Ú__next__e   s    
zMultiprocessIterator.__next__c                 C   s0   | j  d | _W d   ƒ n1 s"0    Y  d S r   )r7   r8   r;   r   r   r   Ústopk   s    zMultiprocessIterator.stopN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r:   r<   r?   r@   r   r   r   r   r5   Z   s
   r5   ÚMultiprocessResultzresult stdout stderr error_msgc                   @   s   e Zd ZdS )Ú
ExitThreadN)rA   rB   rC   r   r   r   r   rF   s   s   rF   c                       sf   e Zd Z‡ fdd„Zdd„ Zdd„ Zdd„ Zddd„Zdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ Z‡  ZS )ÚTestWorkerProcessc                    sZ   t ƒ  ¡  || _|j| _|j| _|j| _|j| _|j| _d | _	d | _
d | _d| _d| _d S )NF)Úsuperr:   Ú	worker_idÚpendingÚoutputr   Úworker_timeoutÚtimeoutÚregrtestÚcurrent_test_nameÚ
start_timeÚ_popenÚ_killedÚ_stopped)r9   rI   Zrunner©Ú	__class__r   r   r:   x   s    
zTestWorkerProcess.__init__c                 C   s’   d| j › g}|  ¡ r"| d¡ n
| d¡ | j}|rF| d|› ¡ | j}|d ur„t ¡ | j }| d| jj	› dt
|ƒ› f¡ dd |¡ S )	NzTestWorkerProcess #ÚrunningZstoppedztest=zpid=ztime=z<%s>ú )rI   Úis_aliveÚappendrO   rQ   ÚtimeÚ	monotonicrP   ÚextendÚpidr   Újoin)r9   ÚinfoÚtestÚpopenÚdtr   r   r   Ú__repr__†   s    
ÿzTestWorkerProcess.__repr__c              
   C   s¾   | j }|d u rd S | jrd S d| _tr2| › d}n| › }td|› tjdd z"trft |jt	j
¡ n| ¡  W nH ty‚   Y n8 ty¸ } z td|› d|›ƒ W Y d }~n
d }~0 0 d S )NTz process groupzKill ©Úfiler0   zFailed to kill z: )rQ   rR   r&   r1   r$   r    r*   r   r]   ÚsignalÚSIGKILLÚkillÚProcessLookupErrorÚOSErrorr   )r9   ra   ZwhatÚexcr   r   r   Ú_kill–   s$    zTestWorkerProcess._killc                 C   s   d| _ |  ¡  d S )NT)rS   rl   r;   r   r   r   r@   ²   s    zTestWorkerProcess.stopÚ Nc                 C   s*   t  ¡ | j }t|||d ƒ}t||||ƒS r   )rZ   r[   rP   r   rE   )r9   r   Z
error_typer   r    Úerr_msgÚ	test_timer   r   r   r   Úmp_result_error·   s    z!TestWorkerProcess.mp_result_errorc                 C   sJ  t  ¡ | _|| _zt|| jƒ}d| _|| _W n   d | _‚ Y n0 zìz¼| jrX|  	¡  t
‚z(|j| jd\}}|j}|d us~J ‚W nN tjy²   | jršt
‚|  	¡  d }d }}Y n. tyÎ   | jrÈt
‚‚ Y n0 | ¡ }| ¡ }|||fW W |  ¡  d | _d | _S    |  	¡  ‚ Y n0 W |  ¡  d | _d | _n|  ¡  d | _d | _0 d S )NF©rM   rm   )rZ   r[   rP   rO   r.   r   rR   rQ   rS   rl   rF   ZcommunicaterM   Ú
returncoder'   ÚTimeoutExpiredrj   ÚstripÚrstripÚ_wait_completed)r9   r   ra   r   r    Úretcoder   r   r   Ú_run_process½   sV    

ù
þzTestWorkerProcess._run_processc           	   
   C   sÌ   |   |¡\}}}|d u r(|  |t||¡S d }|dkr>d| }nf| d¡\}}}| ¡ }|s`d}nDzt |¡}t|Ž }W n, ty¢ } zd| }W Y d }~n
d }~0 0 |d ur¾|  |t	|||¡S t
||||ƒS )Nr   zExit code %sÚ
zFailed to parse worker stdoutzFailed to parse worker JSON: %s)rx   rp   r
   Ú
rpartitionru   r   r   r   Ú	Exceptionr   rE   )	r9   r   rw   r   r    rn   Ú_r   rk   r   r   r   Ú_runtestø   s(    

ÿzTestWorkerProcess._runtestc                 C   s¤   | j s zXzt| jƒ}W n ty.   Y W q Y n0 |  |¡}| j d|f¡ t|j| j	ƒr\W q W q  t
yt   Y q Y q  tyœ   | j dt ¡ f¡ Y q Y q 0 q d S )NFT)rS   r>   rJ   r=   r}   rK   Zputr   r   r   rF   ÚBaseExceptionÚ	tracebackÚ
format_exc)r9   r   Ú	mp_resultr   r   r   Úrun  s    
zTestWorkerProcess.runc              
   C   sv   | j }|j ¡  |j ¡  z| t¡ W nH tjtfyp } z*t	d| › dt
tƒ› d|›ƒ W Y d }~n
d }~0 0 d S )NzFailed to wait for z completion (timeout=z): )rQ   r   Úcloser    ÚwaitÚJOIN_TIMEOUTr'   rs   rj   r   r   )r9   ra   rk   r   r   r   rv   '  s    


ÿþz!TestWorkerProcess._wait_completedc                 C   sd   |   d¡ |  ¡ sq`t ¡ | }| j d| › dt|ƒ› ¡ |tkr td| › dt|ƒ› ƒ q`q d S )Ng      ð?zWaiting for z thread for zFailed to join z in )	r^   rX   rZ   r[   rN   Úlogr   r…   r   )r9   rP   rb   r   r   r   Úwait_stopped6  s    
ÿzTestWorkerProcess.wait_stopped)rm   rm   N)rA   rB   rC   r:   rc   rl   r@   rp   rx   r}   r‚   rv   r‡   Ú__classcell__r   r   rT   r   rG   w   s     ÿ
;rG   c                 C   sN   g }| D ]@}|j }|sqt ¡ |j }|tkrd|t|ƒf }| |¡ q|S )Nz%s (%s))rO   rZ   r[   rP   r   r   rY   )ÚworkersrV   ÚworkerrO   rb   Útextr   r   r   Úget_runningN  s    rŒ   c                   @   sD   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	dS )ÚMultiprocessTestRunnerc                 C   sj   || _ | j j| _|j| _t ¡ | _t| j jƒ| _| jj	d urZt
| jj	d | jj	d ƒ| _nd | _d | _d S )Ng      ø?i,  )rN   r†   r   ÚqueueZQueuerK   r5   ZtestsrJ   rM   ÚminrL   r‰   )r9   rN   r   r   r   r:   \  s    


ÿzMultiprocessTestRunner.__init__c                    s|   ‡ fdd„t dˆ jjd ƒD ƒˆ _dtˆ jƒ› d}ˆ jjrZ|dtˆ jjƒtˆ jƒf 7 }ˆ  |¡ ˆ jD ]}| 	¡  qjd S )Nc                    s   g | ]}t |ˆ ƒ‘qS r   )rG   )Ú.0Úindexr;   r   r   Ú
<listcomp>m  s   ÿz8MultiprocessTestRunner.start_workers.<locals>.<listcomp>é   zRun tests in parallel using z child processesz" (timeout: %s, worker timeout: %s))
Úranger   Zuse_mpr‰   ÚlenrM   r   rL   r†   Ústart)r9   ÚmsgrŠ   r   r;   r   Ústart_workersl  s    
ÿ
ÿÿ

z$MultiprocessTestRunner.start_workersc                 C   s6   t  ¡ }| jD ]}| ¡  q| jD ]}| |¡ q"d S r   )rZ   r[   r‰   r@   r‡   )r9   rP   rŠ   r   r   r   Ústop_workersx  s
    


z#MultiprocessTestRunner.stop_workersc                 C   s´   t dd„ | jD ƒƒs<z| jjddW S  tjy:   Y d S 0 | jjd u}t}|r^t	j
tdd z| jj|dW S  tjy‚   Y n0 t| jƒ}|rL| jjsL|  dd |¡ ¡ qLd S )	Nc                 s   s   | ]}|  ¡ V  qd S r   )rX   )r   rŠ   r   r   r   Ú	<genexpr>€  ó    z5MultiprocessTestRunner._get_result.<locals>.<genexpr>r   rq   T)r3   zrunning: %sú, )Úanyr‰   rK   ÚgetrŽ   ZEmptyr   rM   ÚPROGRESS_UPDATEÚfaulthandlerZdump_traceback_laterÚMAIN_PROCESS_TIMEOUTrŒ   Úpgor†   r^   )r9   Zuse_faulthandlerrM   rV   r   r   r   Ú_get_result  s$    ÿ
z"MultiprocessTestRunner._get_resultc                 C   sˆ   |j }t|ƒ}|jd ur(|d|j 7 }n$|jtkrL| jjsL|dt|jƒ 7 }t| j	ƒ}|rt| jjst|dd 
|¡ 7 }| j | j|¡ d S )Nz (%s)z -- running: %srœ   )r   r   Z	error_msgro   r   r   r¢   r   rŒ   r‰   r^   rN   Zdisplay_progressÚ
test_index)r9   r   r   r‹   rV   r   r   r   Údisplay_result™  s    

z%MultiprocessTestRunner.display_resultc                 C   sš   |d r"|d }t d|› ƒ dS |  jd7  _|d }| j |j¡ |  |¡ |jrdt|jdd |jr„| j	j
s„t|jtjdd t|j| j	ƒr–dS dS )Nr   r“   zregrtest worker thread failed: Tr/   rd   F)r   r¤   rN   Zaccumulate_resultr   r¥   r   r1   r    r   r¢   r$   r   )r9   Úitemr€   r   r   r   r   Ú_process_result§  s    
z&MultiprocessTestRunner._process_resultc                 C   s°   |   ¡  d| _ztz(|  ¡ }|d u r$q6|  |¡}|rq6qW n  tyX   tƒ  d| j_Y n0 W | jj	d urpt
 ¡  | j ¡  |  ¡  n(| jj	d ur˜t
 ¡  | j ¡  |  ¡  0 d S )Nr   T)r˜   r¤   r£   r§   ÚKeyboardInterruptr1   rN   Zinterruptedr   rM   r    Zcancel_dump_traceback_laterrJ   r@   r™   )r9   r¦   r@   r   r   r   Ú	run_tests½  s(    


ú
z MultiprocessTestRunner.run_testsN)
rA   rB   rC   r:   r˜   r™   r£   r¥   r§   r©   r   r   r   r   r   [  s   r   c                 C   s   t | ƒ ¡  d S r   )r   r©   )rN   r   r   r   Úrun_tests_multiprocess×  s    rª   )/Úcollectionsr    r   r*   rŽ   rf   r'   r$   r6   rZ   r   r   r`   r   Ztest.libregrtest.runtestr   r   r   r   r   r   r	   r
   Ztest.libregrtest.setupr   Ztest.libregrtest.utilsr   r   rŸ   r¡   r…   Úhasattrr&   r   r   r.   r4   r5   Ú
namedtuplerE   r{   rF   ZThreadrG   rŒ   r   rª   r   r   r   r   Ú<module>   sF   (ÿ X|