a
    Lg:                     @   s  d dl 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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 e
jdkrd dlmZ nd dlmZ edd	d
dZeeee dddZG dd ded ZG dd dZG dd ded ZdS )    N)Path)Pool)ListOptionalAnySequenceDict)TestEnv)   	   )AbstractContextManager)ContextManager)pathreturnc                 C   s$   z|    W n ty   Y n0 d S N)unlinkOSError)r    r   H/home2/Puru_Virtio_Blk/virtio-demo/qemu/tests/qemu-iotests/testrunner.pysilent_unlink'   s    r   )file1file2r   c              	   C   s   t | dd}t |ddX}dd |D }dd |D }dd t||| |D }|W  d    W  d    S 1 sx0    Y  W d    n1 s0    Y  d S )Nutf-8encodingc                 S   s   g | ]}|  qS r   rstrip.0liner   r   r   
<listcomp>5       zfile_diff.<locals>.<listcomp>c                 S   s   g | ]}|  qS r   r   r   r   r   r   r    6   r!   c                 S   s   g | ]}|  qS r   r   r   r   r   r   r    7   s   )opendifflibZunified_diff)r   r   f1f2Zseq1Zseq2resr   r   r   	file_diff.   s    
r'   c                   @   s   e Zd ZdZeeddddZdeee ee dddZ	eedd	d
dZ
ddddZd dddZeeeddddZdS )LastElapsedTimez Cache for elapsed time for tests, to show it during new test run

    It is safe to use get() at any time.  To use update(), you must either
    use it inside with-block or use save() after update().
    N)
cache_fileenvr   c              	   C   sn   || _ || _|  z<t|dd}t|| _W d    n1 s@0    Y  W n ttfyh   i | _Y n0 d S )Nr   r   )r*   r)   r"   jsonloadcacher   
ValueError)selfr)   r*   fr   r   r   __init__B   s    .zLastElapsedTime.__init__)testdefaultr   c                 C   sB   || j vr|S | jj| j | vr$|S | j | | jj | jj|S r   )r-   r*   imgprotogetimgfmt)r/   r2   r3   r   r   r   r5   M   s    
zLastElapsedTime.get)r2   elapsedr   c                 C   s*   | j |i }||| jji | jj< d S r   )r-   
setdefaultr*   r4   r6   )r/   r2   r7   dr   r   r   updateX   s    zLastElapsedTime.updater   c                 C   sB   t | jddd}t| j| W d    n1 s40    Y  d S )Nwr   r   )r"   r)   r+   dumpr-   )r/   r0   r   r   r   save\   s    zLastElapsedTime.savec                 C   s   | S r   r   r/   r   r   r   	__enter__`   s    zLastElapsedTime.__enter__exc_type	exc_value	tracebackr   c                 C   s   |    d S r   )r>   r/   rB   rC   rD   r   r   r   __exit__c   s    zLastElapsedTime.__exit__)N)__name__
__module____qualname____doc__strr	   r1   r   floatr5   r:   r>   r@   r   rF   r   r   r   r   r(   <   s    r(   c                	   @   s0   e Zd Zdeeee ee eeddddZdS )	
TestResult Nr   F)statusdescriptionr7   diff
casenotruninterruptedr   c                 C   s(   || _ || _|| _|| _|| _|| _d S r   )rO   rP   r7   rQ   rR   rS   )r/   rO   rP   r7   rQ   rR   rS   r   r   r   r1   h   s    zTestResult.__init__)rN   Nr   rN   F)	rG   rH   rI   rK   r   rL   r   boolr1   r   r   r   r   rM   g   s      rM   c                   @   s   e Zd ZdZeeeedddZe	e eee	e dddZ
d%eeedd
ddZd dddZeeeddddZd&eeeee eee ee eedd
ddZeedddZeedddZd'eeeeddd Zd(e	e eed"d#d$ZdS ))
TestRunnerN)r2   test_field_widthr   c                 C   s"   t j}|d usJ |j| |ddS )NT)mp)rU   shared_selfrun_test)r2   rV   Zrunnerr   r   r   proc_run_testv   s    zTestRunner.proc_run_test)testsrV   jobsr   c              	   C   sd   t jd u sJ | t _t|.}|| jt||gt| }W d    n1 sP0    Y  d t _|S r   )rU   rX   r   starmaprZ   ziplen)r/   r[   rV   r\   presultsr   r   r   run_tests_pool}   s    
"zTestRunner.run_tests_poolFauto)r*   tapcolorr   c                 C   sH   || _ || _td|| _|dv s$J |dkp<|dko<tj | _|  d S )Nz.last-elapsed-cache)rc   onoffrf   rc   )r*   rd   r(   last_elapsedsysstdoutisattyre   )r/   r*   rd   re   r   r   r   r1      s    zTestRunner.__init__r;   c                 C   s*   t  | _| j| j | j| j | S r   )
contextlib	ExitStack_stackenter_contextr*   rh   r?   r   r   r   r@      s    
zTestRunner.__enter__rA   c                 C   s   | j   d S r   )rn   closerE   r   r   r   rF      s    zTestRunner.__exit__...rN   
)
r2   rV   	starttimeendtimerO   lasttimethistimerP   endr   c
                 C   sZ  t j|}|du rd}| jr|dkr@td| jj d|  nD|dkrbtd| jj d|  n"|dkrtd| jj d| d	 dS |rd
|dd}
nd}
|r|dd}nd}|rd| d}nd}| jr|dkrd}n |dkrd}n|dkrd}nd}d}nd}d}t|| d| |d| d| d|d|dd|
dd| |	d dS )z- Print short test info before/after test run N   passzok  failznot ok not runz # SKIPz (last: z.1fzs)rN   srq   []z[32mz	[1m[31mz[33mz[0mZ10z [z] Z135Z14)rw   )osr   basenamerd   printr*   r6   re   )r/   r2   rV   rs   rt   rO   ru   rv   rP   rw   Z
lasttime_sZ
thistime_sZcolZcol_endr   r   r   test_print_one_line   sX    	zTestRunner.test_print_one_line)r2   r   c                 C   sv   | j jdkr&| d}tj|r&|S | d| j j }tj|rH|S | d| j j d}tj|rl|S | dS )Nnonez.out.nocachez.out..z.out)r*   	cachemoder   r   isfiler6   qemu_default_machine)r/   r2   refr   r   r   find_reference   s    
zTestRunner.find_referencec              
   C   s  t |}t | |}| s0tdd| dS tt|tjsRt	d|  | sntdd| ddS t|
 g}| j|}dD ]J}tj|| | jj d	| jj d	|j ||< t || jd
d
d q|d }t ||jd }t ||jd }	t ||jd }
|	|
fD ]}t| qt }|jddd}tj|t|j|tj|tjdr}z|  W nN ty   |  |  tddd
d Y W  d   W  d   S 0 |j}W d   n1 s0    Y  W d   n1 s0    Y  tt | d}|dkrDtd|d| t t|t|dS |	 rftd|	j!dd" dS d}|
 r|
j!dd}t t|t|}|rtj#$dddurt%&t|t| t'd t'd t'd td|d| d||d S |(  td!||d"S dS )#z
        Run one test

        :param test: test file path

        Note: this method may be called from subprocess, so it does not
        change ``self`` object in any way!
        r{   zNo such test file: )rO   rP   zNot executable: r|   zNo qualified output (expected ))TEST_DIRSOCK_DIR-T)parentsexist_okr   z.out.badz.notrunz.casenotrunr<   r   r   )cwdr*   stdinrj   stderrzInterrupted by user)rO   rP   rS   N   r   zfailed, exit status )rO   r7   rP   rQ   rN   ZQEMU_IOTESTS_REGENz(########################################z(#####    REFERENCE FILE UPDATED    #####zoutput mismatch (see )rO   r7   rP   rQ   rR   ry   )rO   r7   rR   ))r   r   existsrM   r   accessrK   X_OKri   exitresolver*   prepare_subprocessr   joinr6   r4   namemkdirr   timer"   
subprocessPopenparentDEVNULLSTDOUTwaitKeyboardInterrupt	terminate
returncoderoundr'   	read_textstripenvironr5   shutilcopyfiler   r   )r/   r2   Zf_testZf_referenceargsr*   r9   test_dirZf_badZf_notrunZf_casenotrunr`   t0r0   procretr7   rR   rQ   r   r   r   do_run_test   s    
(F



zTestRunner.do_run_test)r2   rV   rW   r   c           	   
   C   s   | j |}tj d}| jsJ| j|||r2dnd|||r@dndd n$tj	|}t
d| jj d|  | |}tj d}| j|||j||||j|jd	 |jr| jrt
d
|jdd  n
t
|j tj  |S )a  
        Run one test and print short status

        :param test: test file path
        :param test_field_width: width for first field of status format
        :param mp: if true, we are in a multiprocessing environment, don't try
                   to rewrite things in stdout

        Note: this method may be called from subprocess, so it does not
        change ``self`` object in any way!
        z%H:%M:%Sstartedrq   rr   )r2   rV   rO   rs   ru   rw   z
# running rz   )r2   rV   rO   rs   rt   ru   rv   rP   #z
#)rh   r5   datetimeZnowstrftimerd   r   r   r   r   r   r*   r6   r   rO   r7   rP   rR   replaceri   rj   flush)	r/   r2   rV   rW   Zlast_elstartZtestnamer&   rw   r   r   r   rY   D  s6    




zTestRunner.run_testr   )r[   r\   r   c                 C   s  d}g }g }g }| j r<td | jd tdt|  n
| j  tdd |D d }|dkrr| |||}t|D ]\}	}
tj	
|
}|dkr||	 }n| |
|}|jd	v sJ |jr||
 |jd
kr|d7 }|jdkr.|| |jrr| j rtd|jtjd ntd|j nD|jd
krF|| n,|jdkrr|jd usbJ | j|
|j tj  |jrz qqz| j s |rtdd| |rtdd| |rtdd| tdt| d| d ntd| d | S )Nr   zTAP version 13z# z1..%dc                 s   s   | ]}t tj|V  qd S r   )r_   r   r   r   )r   tr   r   r   	<genexpr>  r!   z'TestRunner.run_tests.<locals>.<genexpr>   r   )ry   r{   r|   r|   r{   rr   )filery   zNot run:rz   zSome cases not run in:z	Failures:zFailed z of z iotestszPassed all )rd   r   r*   	print_envr_   maxrb   	enumerater   r   r   rY   rO   rR   appendrQ   r   ri   r   r7   rh   r:   rj   r   rS   )r/   r[   r\   Zn_runZfailedZnotrunrR   rV   ra   ir   r   r&   r   r   r   	run_testst  s\    





zTestRunner.run_tests)Frc   )Nrq   NNrN   rr   )F)r   )rG   rH   rI   rX   staticmethodrK   intrM   rZ   r   rb   r	   rT   r1   r@   r   rF   r   rL   r   r   r   rY   r   r   r   r   r   rU   s   sF   
       8\ 0rU   )r   pathlibr   r   r   r#   r   rl   r+   r   ri   Zmultiprocessingr   typingr   r   r   r   r   testenvr	   version_infor   r   r   rK   r'   r(   rM   rU   r   r   r   r   <module>   s(   
+