B
    Ue                 @   s   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 d dlmZ d dlmZ dZdZdd	 Zd
d ZG dd dZG dd dejZdd ZdS )    N)support)runtestINTERRUPTEDCHILD_ERRORPROGRESS_MIN_TIMEformat_test_result)setup_tests)format_durationg      >@g       @c          	   C   s   ddl m}m} t|}|| f}t|}tjft	 dddd|f}|j
rV|dg7 }||||dtjd	ktjd
}| | \}}	| }
W dQ R X |
||	fS )a)  Run the given test in a subprocess with --worker-args.

    ns is the option Namespace parsed from command-line arguments. regrtest
    is invoked in a subprocess with the --worker-args argument; when the
    subprocess exits, its return code, stdout and stderr are returned as a
    3-tuple.
    r   )PopenPIPEz-uz-mztest.regrtestz--worker-argsz--pgoTnt)stdoutstderrZuniversal_newlinesZ	close_fdscwdN)
subprocessr
   r   varsjsondumpssys
executabler   Zargs_from_interpreter_flagspgoosnameZSAVEDCWDZcommunicatewait)testnamensr
   r   ns_dictworker_argscmdpopenr   r   retcode r!   1/usr/lib/python3.7/test/libregrtest/runtest_mp.pyrun_test_in_subprocess   s&    



r#   c          
   C   s   t | \}}tjf |}t| yt||}W nR tk
rN   tdd f}Y n6 tk
r } zt	
  tt|f}W d d }~X Y nX t  tt |dd td d S )N T)flushr   )r   loadstypesSimpleNamespacer   r   KeyboardInterruptr   BaseException	traceback	print_excr   strprintr   r   exit)r   r   r   r   resulter!   r!   r"   run_tests_worker=   s    r2   c               @   s(   e Zd Z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   d| _ t | _|| _d S )NF)interrupted	threadingZLocklocktests)selfr7   r!   r!   r"   __init__U   s    
zMultiprocessIterator.__init__c             C   s   | S )Nr!   )r8   r!   r!   r"   __iter__Z   s    zMultiprocessIterator.__iter__c          	   C   s*   | j  | jrtdt| jS Q R X d S )Nztests interrupted)r6   r4   StopIterationnextr7   )r8   r!   r!   r"   __next__]   s    zMultiprocessIterator.__next__N)__name__
__module____qualname____doc__r9   r:   r=   r!   r!   r!   r"   r3   Q   s   r3   c                   s,   e Zd Z fddZdd Zdd Z  ZS )MultiprocessThreadc                s,   t    || _|| _|| _d | _d | _d S )N)superr9   pendingoutputr   current_test
start_time)r8   rD   rE   r   )	__class__r!   r"   r9   e   s    
zMultiprocessThread.__init__c             C   s  yt | j}W n  tk
r.   | jd dS X z&t | _|| _t	|| j
\}}}W d d | _X |dkrtd| d f}| j|| | |f dS | d\}}}|s| jd dS t|}t|dkstd|| j|| | |f dS )	N)NNNNTr   zExit code %sF
   zInvalid result tuple: )r<   rD   r;   rE   puttime	monotonicrG   rF   r#   r   r   rstripstrip
rpartitionr   r&   lenAssertionError)r8   testr    r   r   r0   _r!   r!   r"   _runtestm   s0    

zMultiprocessThread._runtestc             C   sB   yd}x|s|   }qW W n" tk
r<   | jd  Y nX d S )NF)NNNN)rU   r*   rE   rK   )r8   stopr!   r!   r"   run   s    zMultiprocessThread.run)r>   r?   r@   r9   rU   rW   __classcell__r!   r!   )rH   r"   rB   d   s    rB   c                s  t   tjjj}|d k	} fddtjjD }tdt	|  x|D ]}|
  qVW dd }d}d}ttt}zyx|jjk r|rtj|dd	 y j|d
}	W nB t jk
r   ||}
|
rjjstdd|
 dd wY nX |	\}}}}|d kr |d7 }q|| |\}}}t||}|ttfkrt|tkrtjjst|dt| 7 }n|tkrd||f }||}
|
rjjs|dd|
 7 }|| |rt|dd |rjjst|tjdd |d tkrt|d7 }qW W n( tk
r:   d_d_t  Y nX W d |rNt  X t  }xdd |D }
t!t"t#|
}
|
s~P t  | }dd|
t	|
f }|t$krd||f }t|dd x|D ]}|t$ qW qZW d S )Nc                s   g | ]}t  jqS r!   )rB   r   ).0i)rE   rD   regrtestr!   r"   
<listcomp>   s   z*run_tests_multiprocess.<locals>.<listcomp>z.Run tests in parallel using %s child processesc             S   sR   g }xH| D ]@}|j }|sq
t |j }|tkr
d|t|f }|| q
W |S )Nz%s (%s))rF   rL   rM   rG   r   r	   append)workersrunningworkerrF   dttextr!   r!   r"   get_running   s    
z+run_tests_multiprocess.<locals>.get_runningr      T)r/   )timeoutzrunning: %sz, )r%   z (%s)z%s (%s)z -- running: %s)filer%   c             S   s   g | ]
}|j qS r!   )rF   )rY   r`   r!   r!   r"   r\      s    zWaiting for %s (%s tests)z%s since %.0f sec)%queueZQueuer3   r7   r   re   rangeZuse_mpr.   rQ   startmaxPROGRESS_UPDATEr   faulthandlerZdump_traceback_latergetZEmptyr   joinZaccumulate_resultr   r   r   r	   Zdisplay_progressr   r   r)   r4   Zcancel_dump_traceback_laterrL   rM   listfilterboolWAIT_PROGRESS)r[   Ztest_timeoutZuse_timeoutr^   r`   rc   ZfinishedZ
test_indexZget_timeoutitemr_   rS   r   r   r0   okZ	test_timeZxml_datarb   Z
wait_startra   liner!   )rE   rD   r[   r"   run_tests_multiprocess   s    











rv   )rl   r   r   rg   r   r5   rL   r+   r'   rS   r   Ztest.libregrtest.runtestr   r   r   r   r   Ztest.libregrtest.setupr   Ztest.libregrtest.utilsr	   rk   rr   r#   r2   r3   ZThreadrB   rv   r!   r!   r!   r"   <module>   s&   #3