o
    éT•jsD  ã                   @   sb  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mZmZ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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sxJ ‚dZ&e&e%ks€J ‚d
Z'e(edƒo‹e(edƒZ)dedede*fdd„Z+de,ee-f fdd„Z.de-dedej/fdd„Z0dede-defdd„Z1G dd„ dƒZ2G dd„ deƒZ3e-Z4e,ed e3f e,ed  e4f B Z5G d!d"„ d"e6ƒZ7G d#d$„ d$ej8ƒZ9d%e:e9 de:e9 fd&d'„Z;G d(d)„ d)ƒZ<d*eddfd+d,„Z=G d-d.„ d.ej>ƒZ?d/e@e-ef dee@e-ef B fd0d1„ZAdeBeCe  fd2d3„ZDdS )4é    N)Ú
NamedTupleÚNoReturnÚLiteralÚAny)Úsupport)Ú	os_helper)Ú	Namespace)ÚRegrtest)ÚruntestÚ	is_failedÚ
TestResultÚInterruptedÚTimeoutÚ
ChildErrorÚPROGRESS_MIN_TIME)Úsetup_tests)Úformat_durationÚprint_warningg      >@g     Àr@ÚsetsidÚkillpgÚresultÚnsÚreturnc                 C   s&   t | tƒrdS |jrt| |ƒrdS dS )NTF)Ú
isinstancer   Úfailfastr   )r   r   © r   ú2/usr/lib/python3.10/test/libregrtest/runtest_mp.pyÚ	must_stop)   s
   
r   c                 C   s$   t  | ¡\}}tdi |¤Ž}||fS )Nr   )ÚjsonÚloadsr   )Úworker_argsÚns_dictÚ	test_namer   r   r   r   Úparse_worker_args1   s   r#   Útestnamec                 C   sx   t |ƒ}|| f}t |¡}tjgt ¡ ¢d‘d‘d‘d‘|‘}i }tr'd|d< tj	|ftj
tj
dtjdktjdœ|¤ŽS )	Nz-uz-mztest.regrtestz--worker-argsTÚstart_new_sessionÚnt)ÚstdoutÚstderrÚuniversal_newlinesÚ	close_fdsÚcwd)Úvarsr   ÚdumpsÚsysÚ
executabler   Úargs_from_interpreter_flagsÚUSE_PROCESS_GROUPÚ
subprocessÚPopenÚPIPEÚosÚnamer   ÚSAVEDCWD)r$   r   r!   r    ÚcmdÚkwr   r   r   Úrun_test_in_subprocess7   s4   
ÿþþýýûúr:   r"   c                 C   s<   t | ƒ t| |ƒ}tƒ  ttj|td�dd� t d¡ d S )N)ÚclsT©Úflushr   )r   r
   Úprintr   r-   ÚEncodeTestResultr.   Úexit)r   r"   r   r   r   r   Úrun_tests_workerP   s
   
rA   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 ©N)Ú	threadingÚLockÚlockÚ
tests_iter)ÚselfrG   r   r   r   Ú__init__a   s   

zMultiprocessIterator.__init__c                 C   s   | S rC   r   ©rH   r   r   r   Ú__iter__e   s   zMultiprocessIterator.__iter__c                 C   sB   | j � | jd u rt‚t| jƒW  d   ƒ S 1 sw   Y  d S rC   )rF   rG   ÚStopIterationÚnextrJ   r   r   r   Ú__next__h   s
   
$ýzMultiprocessIterator.__next__c                 C   s2   | j � d | _W d   ƒ d S 1 sw   Y  d S rC   )rF   rG   rJ   r   r   r   Ústopn   s   "ÿzMultiprocessIterator.stopN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rI   rK   rN   rO   r   r   r   r   rB   ]   s    rB   c                   @   s.   e Zd ZU eed< eed< eed< eed< dS )ÚMultiprocessResultr   r'   r(   Ú	error_msgN)rP   rQ   rR   r   Ú__annotations__Ústrr   r   r   r   rT   s   s
   
 rT   FTc                   @   s   e Zd ZdS )Ú
ExitThreadN)rP   rQ   rR   r   r   r   r   rX   ~   s    rX   c                	       sÂ   e Zd Zdeddddf‡ fdd„Zdefdd	„Zd d
d„Zd dd„Z			d!de	dedede
fdd„Zdedeeeef fdd„Zdede
fdd„Zd dd„Zd dd„Zdeddfdd„Z‡  ZS )"ÚTestWorkerProcessÚ	worker_idÚrunnerÚMultiprocessTestRunnerr   Nc                    sZ   t ƒ  ¡  || _|j| _|j| _|j| _|j| _|j| _d | _	d | _
d | _d| _d| _d S )NF)ÚsuperrI   rZ   ÚpendingÚoutputr   Úworker_timeoutÚtimeoutÚregrtestÚcurrent_test_nameÚ
start_timeÚ_popenÚ_killedÚ_stopped)rH   rZ   r[   ©Ú	__class__r   r   rI   ƒ   s   

zTestWorkerProcess.__init__c                 C   s’   d| j › �g}|  ¡ r| d¡ n| d¡ | j}|r#| d|› �¡ | j}|d urBt ¡ | j }| d| jj	› �dt
|ƒ› �f¡ dd |¡ S )	NzTestWorkerProcess #ÚrunningÚstoppedztest=zpid=ztime=z<%s>ú )rZ   Úis_aliveÚappendrc   re   ÚtimeÚ	monotonicrd   ÚextendÚpidr   Újoin)rH   Ú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r| › d�}n| › }td|› �tjdd� ztr5t |jt	j
¡ W d S | ¡  W d S  tyE   Y d S  tya } ztd|› d|›�ƒ W Y d }~d S d }~ww )NTz process groupzKill ©Úfiler=   zFailed to kill z: )re   rf   r1   r>   r.   r(   r5   r   rr   ÚsignalÚSIGKILLÚkillÚProcessLookupErrorÚOSErrorr   )rH   rv   ÚwhatÚexcr   r   r   Ú_kill¡   s(   "€ÿzTestWorkerProcess._killc                 C   s   d| _ |  ¡  d S )NT)rg   r‚   rJ   r   r   r   rO   ½   s   zTestWorkerProcess.stopÚ Útest_resultr'   r(   c                 C   s   t  ¡ | j |_t||||ƒS rC   )ro   rp   rd   Úduration_secrT   )rH   r„   r'   r(   Úerr_msgr   r   r   Úmp_result_errorÂ   s   z!TestWorkerProcess.mp_result_errorr"   c                 C   s  t  ¡ | _|| _zt|| jƒ}d| _|| _W n   d | _‚ zez\| jr)|  	¡  t
‚z|j| jd�\}}|j}|d us<J ‚W n% tjyV   | jrJt
‚|  	¡  d }d }}Y n tyb   | jrat
‚‚ w | ¡ }| ¡ }|||fW W |  ¡  d | _d | _S    |  	¡  ‚ |  ¡  d | _d | _w )NF©ra   rƒ   )ro   rp   rd   rc   r:   r   rf   re   rg   r‚   rX   Úcommunicatera   Ú
returncoder2   ÚTimeoutExpiredr   ÚstripÚrstripÚ_wait_completed)rH   r"   rv   r'   r(   Úretcoder   r   r   Ú_run_processÌ   sP   

ûúzTestWorkerProcess._run_processc           	   
   C   sÌ   |   |¡\}}}|d u r|  t|ƒ||¡S d }|dkr d| }n1| d¡\}}}| ¡ }|s1d}n z	tj|td�}W n tyP } z
d| }W Y d }~nd }~ww |d ur_|  t	|ƒ|||¡S t
||||ƒS )Nr   zExit code %sÚ
zFailed to parse worker stdout)Úobject_hookzFailed to parse worker JSON: %s)r�   r‡   r   Ú
rpartitionr�   r   r   Údecode_test_resultÚ	Exceptionr   rT   )	rH   r"   r�   r'   r(   r†   Ú_r   r�   r   r   r   Ú_runtest  s*   
€ÿ
ÿzTestWorkerProcess._runtestc                 C   s¨   | j sRz,zt| jƒ}W n ty   Y W d S w |  |¡}| j d|f¡ t|j| j	ƒr.W d S W n t
y9   Y d S  tyL   | j dt ¡ f¡ Y d S w | j rd S d S )NFT)rg   rM   r^   rL   r—   r_   Úputr   r   r   rX   ÚBaseExceptionÚ	tracebackÚ
format_exc)rH   r"   Ú	mp_resultr   r   r   Úrun"  s&   ÿ
ÿþòzTestWorkerProcess.runc              
   C   sv   | j }|j ¡  |j ¡  z| t¡ W d S  tjtfy: } zt	d| › dt
tƒ› d|›�ƒ W Y d }~d S d }~ww )NzFailed to wait for z completion (timeout=z): )re   r'   Úcloser(   ÚwaitÚJOIN_TIMEOUTr2   r‹   r   r   r   )rH   rv   r�   r   r   r   rŽ   5  s   


ÿþ€ÿz!TestWorkerProcess._wait_completedrd   c                 C   sf   	 |   d¡ |  ¡ sd S t ¡ | }| j d| › dt|ƒ› �¡ |tkr2td| › dt|ƒ› �ƒ d S q)NTg      ð?zWaiting for z thread for zFailed to join z in )	rs   rm   ro   rp   rb   Úlogr   r    r   )rH   rd   rw   r   r   r   Úwait_stoppedD  s   
ÿözTestWorkerProcess.wait_stopped©r   N)rƒ   rƒ   N)rP   rQ   rR   ÚintrI   rW   rx   r‚   rO   r   rT   r‡   Útupler�   r—   r�   rŽ   Úfloatr¢   Ú__classcell__r   r   rh   r   rY   ‚   s,    

ûþýü
ú
;

rY   Úworkersc                 C   sN   g }| D ] }|j }|sqt ¡ |j }|tkr$d|t|ƒf }| |¡ q|S )Nz%s (%s))rc   ro   rp   rd   r   r   rn   )r¨   rj   Úworkerrc   rw   Útextr   r   r   Úget_running\  s   
€r«   c                   @   sr   e Zd Zdeddfdd„Zddd„Zddd	„ZdedB fd
d„Zde	ddfdd„Z
dedefdd„Zddd„ZdS )r\   rb   r   Nc                 C   sj   || _ | j j| _|j| _t ¡ | _t| j jƒ| _| jj	d ur-t
| jj	d | jj	d ƒ| _nd | _d | _d S )Ng      ø?i,  )rb   r¡   r   ÚqueueÚQueuer_   rB   Útestsr^   ra   Úminr`   r¨   )rH   rb   r   r   r   rI   j  s   


ÿ
zMultiprocessTestRunner.__init__c                    s|   ‡ fdd„t dˆ jjd ƒD ƒˆ _dtˆ jƒ› d�}ˆ jjr-|dtˆ jjƒtˆ jƒf 7 }ˆ  |¡ ˆ jD ]}| 	¡  q5d S )Nc                    s   g | ]}t |ˆ ƒ‘qS r   )rY   )Ú.0ÚindexrJ   r   r   Ú
<listcomp>{  s    ÿz8MultiprocessTestRunner.start_workers.<locals>.<listcomp>é   zRun tests in parallel using z child processesz" (timeout: %s, worker timeout: %s))
Úranger   Úuse_mpr¨   Úlenra   r   r`   r¡   Ústart)rH   Úmsgr©   r   rJ   r   Ústart_workersz  s   
ÿ
ÿÿ


ÿz$MultiprocessTestRunner.start_workersc                 C   s6   t  ¡ }| jD ]}| ¡  q| jD ]}| |¡ qd S rC   )ro   rp   r¨   rO   r¢   )rH   rd   r©   r   r   r   Ústop_workers†  s   


ÿz#MultiprocessTestRunner.stop_workersc                 C   sÂ   | j jd u}t}tdd„ | jD ƒƒrM|rtjtdd� z| jj	|d�W S  t
jy-   Y nw t| jƒ}|rC| j jsC|  dd |¡ ¡ tdd„ | jD ƒƒsz| jj	dd�W S  t
jy`   Y d S w )	Nc                 s   s   � | ]}|  ¡ V  qd S rC   )rm   )r°   r©   r   r   r   Ú	<genexpr>“  s   € z5MultiprocessTestRunner._get_result.<locals>.<genexpr>T)r@   rˆ   zrunning: %sú, r   )r   ra   ÚPROGRESS_UPDATEÚanyr¨   ÚfaulthandlerÚdump_traceback_laterÚMAIN_PROCESS_TIMEOUTr_   Úgetr¬   ÚEmptyr«   Úpgor¡   rs   )rH   Úuse_faulthandlerra   rj   r   r   r   Ú_get_result�  s*   ÿÿ
òÿz"MultiprocessTestRunner._get_resultrœ   c                 C   sˆ   |j }t|ƒ}|jd ur|d|j 7 }n|jtkr&| jjs&|dt|jƒ 7 }t| j	ƒ}|r:| jjs:|dd 
|¡ 7 }| j | j|¡ d S )Nz (%s)z -- running: %sr¼   )r   rW   rU   r…   r   r   rÄ   r   r«   r¨   rs   rb   Údisplay_progressÚ
test_index)rH   rœ   r   rª   rj   r   r   r   Údisplay_result©  s   

z%MultiprocessTestRunner.display_resultÚitemc                 C   sš   |d r|d }t d|› �ƒ dS |  jd7  _|d }| j |j¡ |  |¡ |jr2t|jdd� |jrB| j	j
sBt|jtjdd� t|j| j	ƒrKdS dS )z&Returns True if test runner must stop.r   r³   zregrtest worker thread failed: Tr<   ry   F)r   rÈ   rb   Úaccumulate_resultr   rÉ   r'   r>   r(   r   rÄ   r.   r   )rH   rÊ   r›   rœ   r   r   r   Ú_process_result·  s   
z&MultiprocessTestRunner._process_resultc                 C   s°   |   ¡  d| _z<z	 |  ¡ }|d u rn	|  |¡}|rnq
W n ty-   tƒ  d| j_Y nw W | jj	d ur9t
 ¡  | j ¡  |  ¡  d S | jj	d urNt
 ¡  | j ¡  |  ¡  w )Nr   T)r¹   rÈ   rÆ   rÌ   ÚKeyboardInterruptr>   rb   Úinterruptedr   ra   r¿   Úcancel_dump_traceback_laterr^   rO   rº   )rH   rÊ   rO   r   r   r   Ú	run_testsÎ  s2   
ù€þ€
ú

z MultiprocessTestRunner.run_testsr£   )rP   rQ   rR   r	   rI   r¹   rº   ÚQueueOutputrÆ   rT   rÉ   ÚboolrÌ   rÐ   r   r   r   r   r\   i  s    

r\   rb   c                 C   s   t | ƒ ¡  d S rC   )r\   rÐ   )rb   r   r   r   Úrun_tests_multiprocessè  s   rÓ   c                       s2   e Zd ZdZdedeeef f‡ fdd„Z‡  ZS )r?   z7Encode a TestResult (sub)class object into a JSON dict.Úor   c                    s.   t |tƒrt|ƒ}|jj|d< |S tƒ  |¡S )NÚ__test_result__)r   r   r,   ri   rP   r]   Údefault)rH   rÔ   r   rh   r   r   rÖ   ï  s
   
zEncodeTestResult.default)	rP   rQ   rR   rS   r   ÚdictrW   rÖ   r§   r   r   rh   r   r?   ì  s    &r?   Údc                 C   sB   d| vr| S |   d¡}tƒ D ]}|j|kr|di | ¤Ž  S qdS )z7Decode a TestResult (sub)class object from a JSON dict.rÕ   Nr   )ÚpopÚget_all_test_result_classesrP   )rØ   Úcls_namer;   r   r   r   r”   ø  s   


ÿÿr”   c                  C   sT   d} t h}t|ƒ| kr(t|ƒ} g }|D ]	}| | ¡ ¡ q| |¡ t|ƒ| ks|S )Nr   )r   r¶   rq   Ú__subclasses__Úupdate)Ú
prev_countÚclassesÚto_addr;   r   r   r   rÚ     s   
ûrÚ   )EÚcollectionsr¿   r   r5   r¬   r{   r2   r.   rD   ro   rš   Útypingr   r   r   r   ru   r   Útest.supportr   Útest.libregrtest.cmdliner   Útest.libregrtest.mainr	   Útest.libregrtest.runtestr
   r   r   r   r   r   r   Útest.libregrtest.setupr   Útest.libregrtest.utilsr   r   r½   rÁ   r    Úhasattrr1   rÒ   r   r¥   rW   r#   r3   r:   rA   rB   rT   ÚExcStrrÑ   r•   rX   ÚThreadrY   Úlistr«   r\   rÓ   ÚJSONEncoderr?   r×   r”   ÚsetÚtyperÚ   r   r   r   r   Ú<module>   sT    $  [&