B
    u9ag  ã               @   s˜   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„ Zdd„ Zdd„ Zd	d
„ Zddd„Zdd„ Zdd„ Zedkr”eƒ  dS )añ  
Command line tool to bisect failing CPython tests.

Find the test_os test method which alters the environment:

    ./python -m test.bisect_cmd --fail-env-changed test_os

Find a reference leak in "test_os", write the list of failing tests into the
"bisect" file:

    ./python -m test.bisect_cmd -o bisect -R 3:3 test_os

Load an existing list of tests from a file using -i option:

    ./python -m test --list-cases -m FileTests test_os > tests
    ./python -m test.bisect_cmd -i tests test_os
é    Nc          	   C   s<   t | dƒ(}x|D ]}t||d qW | ¡  W d Q R X d S )NÚw)Úfile)ÚopenÚprintÚflush)ÚfilenameÚtestsÚfpÚname© r   ú /usr/lib/python3.7/bisect_cmd.pyÚwrite_tests   s    
r   c             C   s*   | sd S t dt|ƒ| f ƒ t| |ƒ | S )NzWriting %s tests into %s)r   Úlenr   )r   r   r   r   r   Úwrite_output&   s
    
r   c             C   s
   d  | ¡S )Nú )Újoin)Úargsr   r   r   Úformat_shell_args.   s    r   c             C   sf   t jdddg}| | j¡ tj|tjdd}|j}|rXt|ƒ}t	d||f ƒ t  
|¡ |j ¡ }|S )Nz-mÚtestz--list-casesT)ÚstdoutZuniversal_newlinesz1Failed to list tests: %s failed with exit code %s)ÚsysÚ
executableÚextendÚ	test_argsÚ
subprocessÚrunÚPIPEÚ
returncoder   r   Úexitr   Ú
splitlines)r   ÚcmdÚprocÚexitcoder   r   r   r   Ú
list_cases2   s    

r#   c          	   C   sl   t  ¡ }zFt||ƒ tjddd|g}| | j¡ tdt|ƒ ƒ t	 
|¡}|jS tj |¡rft |¡ X d S )Nz-mr   z--matchfilez+ %s)ÚtempfileZmktempr   r   r   r   r   r   r   r   r   r   ÚosÚpathÚexistsÚunlink)r   r   Z
huntrleaksZtmpr    r!   r   r   r   Ú	run_testsB   s    

r)   c              C   sf   t  ¡ } | jdddd | jdddd | jdd	td
dd | jddtddd |  ¡ \}}||_|S )Nz-iz--inputzUTest names produced by --list-tests written into a file. If not set, run --list-tests)Úhelpz-oz--outputzResult of the bisectionz-nz--max-testsé   z:Maximum number of tests to stop the bisection (default: 1))ÚtypeÚdefaultr*   z-Nz
--max-iteréd   z5Maximum number of bisection iterations (default: 100))ÚargparseÚArgumentParserÚadd_argumentÚintÚparse_known_argsr   )Úparserr   r   r   r   r   Ú
parse_argsQ   s    r5   c           	   C   s&  t ƒ } | jr2t| jƒ}dd„ |D ƒ}W d Q R X nt| ƒ}tdt|ƒ ƒ tdt| jƒ ƒ td| j| j	f ƒ t
| j|ƒ}tƒ  t ¡ }d}yÆxÀt|ƒ| jkrP|| j	krPt|ƒ}t|d dƒ}t ||¡}td|t|ƒt|ƒf ƒ tƒ  t| |ƒ}td	|t|ƒf ƒ td
|ƒ |r8tdƒ |}t
| j|ƒ}ntdƒ tƒ  |d7 }q’W W n* tk
r~   tƒ  tdƒ tƒ  Y nX tdt|ƒ ƒ x|D ]}	td|	 ƒ q–W tƒ  |rÄtd| ƒ t t ¡ | ¡}
t|ƒ| jkr
td|tj|
df ƒ t d¡ ntd|tj|
df ƒ d S )Nc             S   s   g | ]}|  ¡ ‘qS r   )Ústrip)Ú.0Úliner   r   r   ú
<listcomp>j   s    zmain.<locals>.<listcomp>zStart bisection with %s testszTest arguments: %szxBisection will stop when getting %s or less tests (-n/--max-tests option), or after %s iterations (-N/--max-iter option)r+   é   z![+] Iteration %s: run %s tests/%szran %s tests/%sr   z*Tests failed: continuing with this subtestz;Tests succeeded: skipping this subtest, trying a new subsetzBisection interrupted!zTests (%s):z* %szOutput written into %sz+Bisection completed in %s iterations and %s)Zsecondsz+Bisection failed after %s iterations and %s)r5   Úinputr   r#   r   r   r   r   Z	max_testsZmax_iterr   ÚoutputÚtimeZ	monotonicÚmaxÚrandomZsampler)   ÚKeyboardInterruptÚmathZceilÚdatetimeZ	timedeltar   r   )r   r	   r   r<   Z
start_timeZ	iterationZntestZsubtestsr"   r   Zdtr   r   r   Úmaine   s`    


rC   Ú__main__)N)Ú__doc__r/   rB   Zos.pathr%   rA   r?   r   r   r$   r=   r   r   r   r#   r)   r5   rC   Ú__name__r   r   r   r   Ú<module>   s$   
A