o
    uJAf\                    @  sZ  U 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	 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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   m!Z" dd	l#m$Z$ dd
l#m%Z% ddl#m&Z& ddl'm(Z(m)Z) ddl'm*Z+ ddl,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4 ddl5m6Z6m7Z7 ddl8m9Z9 ddl:m;Z;m<Z< ej=rej>d Z?dZ@dZAdZBg dZCdeDd< ejEdkreCFg d dd eCD ZGeHddIeG d ZJdd"d#ZKdd$d%ZLd&dd&dddd'ZMdd+d,ZNdd-d.ZOdd2d3ZPdd4d5ZQdd8d9ZRdd<d=ZSdd?d@ZTdAdB ZUdCeDdD< eK s>ejVZUddGdHZWG dIdJ dJe-ZXejYG dKdL dLejZZ[ejYG dMdN dNejZZ\G dOdP dPZ]G dQdR dRZ^G dSdT dTe^Z_G dUdV dVe^Z`G dWdX dXe_ZaG dYdZ dZe_ZbG d[d\ d\e^ZcG d]d^ d^ZdG d_d` d`edZeeeedjfe;jg< G dadb dbeeZhehedjfe;ji< G dcdd ddedZjejedjfe;jk< G dedf dfedZleledjfe;jm< ddhdiZnddldmZoddsdtZpddvdwZqddzd{ZrdddZsdddZt	ddddZuG dd dZvG dd dZwG dd dZxdddZydddZzdddZ{dddZ|dS )    )annotations)Path)deque)suppress)deepcopy)fnmatchN   )build)environment)mlog)MesonVersionMismatchExceptionmajor_versions_differversion)MesonException	OptionKey
OrderedSetRealPathActionget_wine_shortpath	join_args
split_argssetup_vsenv)get_infodirload_info_file)ExternalProgram)TestProtocolTestSerialisation)TAPParser.TestTAPParser.ErrorTAPParser.VersionTAPParser.PlanTAPParser.UnknownLineTAPParser.BailoutM   c      ))r      )      )      )      )      )i  i  )i  i  zT.List[T.Tuple[int, int]]UNENCODABLE_XML_UNICHRSi   ))i i )i i )i i )i i )i i )i i )i i )i i )i	 i	 )i
 i
 )i i )i i )i i )i i )i i )i i c                 C  s&   g | ]\}}t | d t | qS )-)chr).0lowhigh r5   5/usr/lib/python3.10/site-packages/mesonbuild/mtest.py
<listcomp>[   s   & r7   z([ z])returnboolc                  C  s   t   } | dkS )Nwindows)platformsystemlower)platnamer5   r5   r6   
is_windows_   s   r@   c                   C  s
   t jdkS )Ncygwin)sysr<   r5   r5   r5   r6   	is_cygwinc      
rC      )FHWZNaNAsstrintc                 C  s(   d}| D ]}t |}|t| 7 }q|S )Nr   )unicodedataZeast_asian_widthUNIWIDTH_MAPPING)rK   resultcwr5   r5   r6   uniwidthg   s
   
rS   c                  C  st   d} | t jv r&z
tt j|  }W |S  ty%   td|  d d}Y |S w zt }W |S  ty9   d}Y |S w )NZMESON_TESTTHREADSzInvalid value in z, using 1 thread.r   )osenvironrM   
ValueErrorprintmultiprocessing	cpu_count	Exception)varnameZnum_workersr5   r5   r6   determine_worker_countn   s"   

r\   parserargparse.ArgumentParserNonec                 C  s  | j ddtdd | j dddtdd	 | j d
dddd | j dddddd | j ddddd | j dddddd | j dd dtdd	 | j ddtdd  | j d!g d"d#d$d%d& | j d'g d(d#d$d)d& | j d*d+d,d-d.d | j d/ddd0d | j d1ddd2d | j d3d4d5d6 | j d7d8t td9d | j d:d;ddd<d | j d=d>ddd?d | j d@dAtd dBdC | j dDd dEdFd | j dGg tdHd | j dIdJdKdL d S )MNz	--maxfailr   zbNumber of failing tests before aborting the test run. (default: 0, to disable aborting on failure))defaulttypehelpz--repeatr   repeatz!Number of times to run the tests.)r`   destra   rb   z--no-rebuildF
store_truez$Do not rebuild before running tests.)r`   actionrb   z--gdbgdbzRun test under gdb.)r`   rd   rf   rb   z
--gdb-pathgdb_pathz&Path to the gdb binary (default: gdb).)r`   rd   rb   z--listlistzList available tests.z	--wrapperwrapperz)wrapper to run tests with (e.g. Valgrind)-Cwdz#directory to cd into before running)rd   rf   rb   z--suiteinclude_suitesappendZSUITEz,Only run tests belonging to the given suite.)r`   rd   rf   metavarrb   z
--no-suiteexclude_suitesz.Do not run tests belonging to the given suite.z--no-stdsplitTsplitstore_falsez,Do not split stderr and stdout in test logs.z--print-errorlogsz%Whether to print failing tests' logs.z--benchmarkz Run benchmarks instead of tests.z	--logbaseZtestlogzBase name for log file.)r`   rb   z-jz--num-processesz#How many parallel processes to use.z-vz	--verbosez!Do not redirect stdout and stderrz-q--quietz$Produce less output to the terminal.z-tz--timeout-multiplierzDefine a multiplier for test timeout, for example  when running tests in particular conditions they might take more time to execute. (<= 0 to disable timeout))ra   r`   rb   z--setupsetupzWhich test setup to use.z--test-argsz7Arguments to pass to the specified test(s) or all testsargs*zOptional list of test names to run. "testname" to run all tests with that name, "subprojname:testname" to specifically run "testname" from "subprojname", "subprojname:" to run all tests defined by "subprojname".)nargsrb   )add_argumentrM   r   r   r\   float)r]   r5   r5   r6   add_arguments   s~   








rz   c                 C  s\   | d dkrdnd}z	t | |d W d S  ty-   | jdddd} t | |d Y d S w )N
r8   endasciibackslashreplaceerrors)rW   UnicodeEncodeErrorencodedecode)rK   r~   r5   r5   r6   
print_safe   s   r   abc                 C  s   | s|S |s| S | d | S Nr|   r5   )r   r   r5   r5   r6   
join_lines   s
   r   dashcolsc                 C  sL   | s|| S d|  d } t | }|| d }|| |  } | ||| |   S )N rE   )rS   )rK   r   r   widthfirstr5   r5   r6   dashes   s   r   retcodec                 C  s   | dk r#|  }zt |j}W n ty   d}Y nw d| d| S | dkr,d|  S | d }zt |j}W n tyC   d}Y nw d|  d| d| d	S )
Nr   Z
SIGinvalidzkilled by signal r      zexit status z(exit status z or signal ))signalSignalsnamerV   )r   signumsignamer5   r5   r6   returncode_to_status   s"   
r   c                 C     | S Nr5   )xr5   r5   r6   <lambda>   s    r   zT.Callable[[str], str]sh_quoteenvT.Iterable[T.Tuple[str, str]]c                 C  s   d dd | D S )Nr8   c                 S  s    g | ]\}}d  |t|qS )z{}={} )formatr   )r2   kvr5   r5   r6   r7      s     z$env_tuple_to_str.<locals>.<listcomp>)join)r   r5   r5   r6   env_tuple_to_str      r   c                   @  s   e Zd ZdS )TestExceptionN)__name__
__module____qualname__r5   r5   r5   r6   r      s    r   c                   @  s   e Zd ZdZdZdZdS )ConsoleUserr   r   rE   N)r   r   r   LOGGERGDBSTDOUTr5   r5   r5   r6   r      s    r   c                   @  s   e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zd
Zed#ddZd$ddZd$ddZd$ddZd$ddZd%ddZd&ddZd'd d!Zd"S )(
TestResultPENDINGRUNNINGOKTIMEOUT	INTERRUPTSKIPFAILEXPECTEDFAILUNEXPECTEDPASSERRORr9   rM   c                   C     dS )Nr)   r5   r5   r5   r5   r6   maxlen     zTestResult.maxlenr:   c                 C  s   | t jt jhv S r   )r   r   r   selfr5   r5   r6   is_ok     zTestResult.is_okc                 C  s   | t jt jt jt jt jhv S r   )r   r   r   r   r   r   r   r5   r5   r6   is_bad  s   zTestResult.is_badc                 C  s   | t jt jhvS r   )r   r   r   r   r5   r5   r6   is_finished  r   zTestResult.is_finishedc                 C  s   | t jt jfv S r   )r   r   r   r   r5   r5   r6   
was_killed  r   zTestResult.was_killedrK   rL   mlog.AnsiDecoratorc                 C  sX   |   rtj}||S | tjtjfv rtj}||S |  r%tj}||S tj	}||S r   )
r   r   redr   r   r   yellowr   greenblue)r   rK   	decoratorr5   r5   r6   colorize  s   zTestResult.colorizer   c                 C  s$   dj | j|  d}| ||S )Nz{res:{reslen}})resZreslen)r   valuer   r   get_text)r   r   Z
result_strr5   r5   r6   r   (  s   zTestResult.get_textc                 C  s   t | dS )Nz>>> )rL   r   r   r5   r5   r6   get_command_marker,     zTestResult.get_command_markerNr9   rM   r9   r:   )rK   rL   r9   r   )r   r:   r9   rL   r9   rL   )r   r   r   r   r   r   r   r   r   r   r   r   r   staticmethodr   r   r   r   r   r   r   r   r5   r5   r5   r6   r      s(    





r   c                   @  s4  e Zd ZU G dd dejZG dd dejZG dd dejZG dd dejZG d	d
 d
ejZ	G dd dejZ
dZdZdZedZedZedej Zedej ZedZedZedZdZdZdZded< dZdZdZded< dZeZ dZ!d:d+d,Z"d;d0d1Z#d<d5d6Z$d=d8d9Z%dS )>	TAPParserc                   @  s.   e Zd ZU ded< ded< ded< ded< dS )	r    rM   	num_testsr:   lateskippedT.Optional[str]explanationNr   r   r   __annotations__r5   r5   r5   r6   Plan1  s
   
 r   c                   @     e Zd ZU ded< dS )r"   rL   messageNr   r5   r5   r5   r6   Bailout7     
 r   c                   @  s8   e Zd ZU ded< ded< ded< ded< dd
dZdS )r   rM   numberrL   r   r   rP   r   r   r9   c                 C  s   | j  d| j  S )Nr   )r   r   stripr   r5   r5   r6   __str__@  s   zTAPParser.Test.__str__Nr   )r   r   r   r   r   r5   r5   r5   r6   Test:  s   
 r   c                   @  r   )r   rL   r   Nr   r5   r5   r5   r6   ErrorC  r   r   c                   @  s   e Zd ZU ded< ded< dS )r!   rL   r   rM   linenoNr   r5   r5   r5   r6   UnknownLineF  s   
 r   c                   @  r   )r   rM   r   Nr   r5   r5   r5   r6   VersionJ  r   r   r   rE   r%   zBail out!\s*(.*)z<(?:\s*\#\s*([Ss][Kk][Ii][Pp]\S*|[Tt][Oo][Dd][Oo])\b\s*(.*))?z1\.\.([0-9]+)z'((?:not )?ok)\s*(?:([0-9]+)\s*)?([^#]*)zTAP version ([0-9]+)z
(\s+)---.*z\s+\.\.\.\s*FNzT.Optional[Plan]planr   T.Optional[int]yaml_linenor8   r(   okr:   numrM   r   rL   	directiver   r   r9   ET.Generator[T.Union['TAPParser.Test', 'TAPParser.Error'], None, None]c                 c  s    |  }|r|  nd }|d urH| }|dr)|r(| ||tj|V  d S n|dkr>| |||r6tjntj|V  d S | d| dV  | |||rQtj	ntj
|V  d S )Nr   ZTODOzinvalid directive "")r   upper
startswithr   r   r   r   r   r   r   r   )r   r   r   r   r   r   r5   r5   r6   
parse_testc  s   
"zTAPParser.parse_testlinesT.AsyncIterator[str]T.AsyncIterator[TYPE_TAPResult]c                 C sF   |2 z3 d H W }|  |D ]}|V  qq6 |  d D ]}|V  qd S r   
parse_line)r   r   lineeventr5   r5   r6   parse_asyncu  s   zTAPParser.parse_asyncioT.Iterator[str]T.Iterator[TYPE_TAPResult]c                 c  s0    |D ]
}|  |E d H  q|  d E d H  d S r   r   )r   r   r   r5   r5   r6   parse|  s   zTAPParser.parser   c              	   c  s   |d ur|  j d7  _ | }| j| jkr9| jdkr4| j|}|r4| j| _| j | _|	d| _
d S | j| _n)| j| jkrb| j|rK| j| _d S || j
rSd S | d| j dV  | j| _| j| jksjJ |rq|drsd S | j|}|r| jr| jjr| js| dV  d| _|  jd7  _|	dd u r| jnt|	d}|| jkr| d	V  | |	dd
k||	d|	d|	dE d H  | j| _d S | j|}|r+| jr| dV  d S t|	d}|dk}|	dr|	d dr|dkr| dV  d}n| dV  | j|| jdk||	dd| _| jV  d S | j|}|rB| |	dV  d| _d S | j|}|ry| j dkrY| dV  d S t|	d| _| jdk ro| dV  d S | j| jdV  d S | || j V  d S | j| jkr| d| j dV  | js| jr| j| jjkr| j| jjk r| d| jj d| j dV  d S | d| jj d| j dV  d S d S d S d S )Nr      z+YAML block not terminated (started on line r   #zunexpected test after late planTrE   zout of order test numbersr   r%         zmore than one plan foundr   r   zinvalid SKIP directive for planzinvalid directive for plan)r   r   r   r   z(version number must be on the first linez$version number should be at least 13r   zToo few tests run (expected z, got zToo many tests run (expected )r   rstripstate_AFTER_TESTr   _RE_YAML_STARTmatch_YAMLr   groupyaml_indent_MAIN_RE_YAML_ENDr   r   _RE_TESTr   r   found_late_testr   rM   r   _RE_PLANr   r   _RE_BAILOUTr   
bailed_out_RE_VERSIONr   r   )r   r   mr   r   r   r5   r5   r6   r     s   


"



 $$zTAPParser.parse_line)r   r:   r   rM   r   rL   r   r   r   r   r9   r   )r   r   r9   r   )r   r   r9   r   )r   r   r9   r   )&r   r   r   T
NamedTupler   r   r   r   r   r   r  r  r	  recompiler  Z_RE_DIRECTIVEpatternr  r  r  r  r  r  r  r   r   r   r   r   r  r  r   r   r   r   r   r5   r5   r5   r6   r   0  s<   
 	







r   c                   @  sR   e Zd ZdddZdddZdddZdddZdddZdddZdddZ	dS ) 
TestLoggerr9   r_   c                 C     d S r   r5   r   r5   r5   r6   flush     zTestLogger.flushharness'TestHarness'c                 C  r  r   r5   r   r  r5   r5   r6   start  r  zTestLogger.starttest	'TestRun'c                 C  r  r   r5   r   r  r"  r5   r5   r6   
start_test  r  zTestLogger.start_testrK   rL   r   r   c                 C  r  r   r5   )r   r  r"  rK   r   r5   r5   r6   log_subtest  r  zTestLogger.log_subtestrP   c                 C  r  r   r5   )r   r  rP   r5   r5   r6   log  r  zTestLogger.logc                   s   d S r   r5   r   r5   r5   r6   finish  s   zTestLogger.finishc                 C  r  r   r5   r   r5   r5   r6   close  r  zTestLogger.closeNr9   r_   r  r  r9   r_   r  r  r"  r#  r9   r_   )
r  r  r"  r#  rK   rL   r   r   r9   r_   r  r  rP   r#  r9   r_   )
r   r   r   r  r!  r%  r&  r'  r(  r)  r5   r5   r5   r6   r    s    





r  c                   @  s"   e Zd ZddddZdd	d
ZdS )TestFileLoggerreplacefilenamerL   r   r9   r_   c                 C  s   || _ t|dd|d| _d S )NrR   utf-8encodingr   )r0  openfile)r   r0  r   r5   r5   r6   __init__  s   zTestFileLogger.__init__c                 C  s   | j r| j   d | _ d S d S r   )r5  r)  r   r5   r5   r6   r)    s   

zTestFileLogger.closeN)r/  )r0  rL   r   rL   r9   r_   r*  )r   r   r   r6  r)  r5   r5   r5   r6   r.    s    r.  c                   @  s   e Zd Zg dZg dZdZdZdZd*dd	Zd*d
dZ	d+ddZ
d*ddZd,ddZd,ddZd-ddZd.ddZd/dd Zd0d#d$Zd/d%d&Zd,d'd(Zd)S )1ConsoleLogger)z..z:.z.:)u   🌑u   🌒u   🌓u   🌔u   🌕u   🌖u   🌗u   🌘u   ✀ u   ―u   ▶ r9   r_   c                 C  s  t  | _d | _d | _d| _d| _|  d| _d| _d| _d| _	zt
d\| _}d| _W n ty:   d| _d| _Y nw t| j| j| jd | _td| j| jd | _| j| _| j| _z| jtjjpcd W d S  ty   td	d
| jd | _tdd
| jd | _d| _| j| _Y d S w )Nr   Fr8   r   TP   rE   r   z8<r0   z| )r   running_testsprogress_testprogress_taskmax_left_widthstopshould_erase_line
test_countstarted_testsspinner_indexrT   get_terminal_sizer   is_ttyOSErrorr   SCISSORSHLINEoutput_start
output_endRTRIsubSPINNERspinnerr   rB   stdoutr3  r   ASCII_SPINNER)r   _r5   r5   r6   r6  
  s:   

zConsoleLogger.__init__c                 C  s"   | j rt| j dd d| _ d S d S )Nr8   r}   )r>  rW   r   r5   r5   r6   r  *  s   
zConsoleLogger.flushr   rL   c                 C  s   t | j|ddd d| _d S )Nr8   )sepr~   z[K)rW   r>  )r   r   r5   r5   r6   print_progress/  s   
zConsoleLogger.print_progressc                 C  s   | j   d S r   )updatesetr   r5   r5   r6   request_update3  r   zConsoleLogger.request_updater  r  c                 C  s  | j d u r|   d S t| jdkr| j d| j }nd| jt| j d | j| j}d|| j| j }| jd t| j | _djdt	
  tt | j j |jd}| j jrg|dj| j j|jd	7 }|d
7 }| j  }|rx|d| 7 }|j| j d| j||d}| | d S )Nr   /z{}-{}/{}z[{}] {} z{spaces} {dur:{durlen}}r   )spacesdurdurlenz/{timeout:{durlen}})timeoutrY  rK      T)r   r<  leftright)r:  r  lenr9  r@  r?  r   rL  rA  r   r   rM   time	starttimeduration_max_lenrZ  get_detailsr<  rR  )r   r  countr\  r]  detailsr   r5   r5   r6   emit_progress6  s:   



zConsoleLogger.emit_progressc                   st   d fdd}t  _ j_tj jd _jr6 js8dt	t
j d _t | _d S d S d S )	Nr9   r_   c                    s   t  } d}  js\j I d H  j  |  |kr1d _|  d }| 	|j jr>jj
tjur>d _jsTjsEqjjdd_jj   jr  d S )Ng        r   Flast)asyncioget_running_looprU  r=  rS  waitclearr_  r:  Zcall_atr   r   r   r9  popaddre  r  )loopZnext_updater  r   r5   r6   report_progressW  s,   

z,ConsoleLogger.start.<locals>.report_progress   r%   r&   r*  )rh  EventrS  r?  maxr   r<  rC  need_consoler^  rL   ensure_futurer;  )r   r  rp  r5   ro  r6   r!  V  s   
zConsoleLogger.startr"  r#  c              	   C  s   |j r;|jr;|   t|j|t | j|j	t d t|j
 |j  |jr3t| jdd n|js;tdd |  jd7  _| j| | jj|dd |   d S )N)r<  r]  Tr  r   Frf  )verbosecmdliner  rW   r   r   colorize_consoler<  r   r   r   direct_stdoutrG  needs_parsingr@  r9  rm  move_to_endrU  r$  r5   r5   r6   r%  }  s   
zConsoleLogger.start_testrP   c                 C  sh   |j s	|jjs	dS |jt |jd}|j r|S | }t|dk r$|S t	t
dd|dd   S )Nr8   )stderr_onlyd   z1Listing only the last 100 lines from a long log.
r|   i)rw  optionsprint_errorlogsget_logr   ry  r{  
splitlinesr^  rL   boldr   )r   r  rP   r'  r   r5   r5   r6   shorten_log  s   
 zConsoleLogger.shorten_logc                 C  sn   |j s|j}|st|j |j  d S t|j |  | ||}|r5t| j t| t| j	 d S d S r   )
rw  rx  rW   r   r   stdor  rG  r   rH  )r   r  rP   rx  r'  r5   r5   r6   	print_log  s   
zConsoleLogger.print_logrK   r   c                 C  sb   |j s|jjr-| r/|   t|j|t | j	| j
||t ddd |   d S d S d S )N)r<  prefixmiddler]  Trv  )rw  r  r  r   r  rW   r   r   ry  r<  rJ  r   rU  )r   r  r"  rK   rP   r5   r5   r6   r&    s   zConsoleLogger.log_subtestc                 C  s$  | j | |jtju r#|js|jjr#|   t	|j
 d|j d |jjr,|j s|   |jrI|jrIt	| j t	|j|t | jd nt	|j|t | jddd |js`|j rf| || |jrt	dd |jD ]}t	|dd qqt	dd |js|j rt	dd |   d S )Nz time out (After z	 seconds))r<  Trv  )r9  remover   r   r   rw  r  r  r  rW   r   rZ  quietr   rx  rz  rH  r   r   ry  r<  r   r  warningsrU  )r   r  rP   rR   r5   r5   r6   r'    s0   




zConsoleLogger.logc                   sz   d| _ |   | jr| jI d H  |jr5|jjs|jjr5td t|jdD ]\}}t|	|t
  q&t|  d S )NTz
Summary of Failures:
r   )r=  rU  r;  collected_failuresr  r  rw  rW   	enumerater   r   ry  summaryr   r  irP   r5   r5   r6   r(    s   zConsoleLogger.finishNr*  )r   rL   r9   r_   r+  r,  )r  r  rP   r#  r9   rL   r-  )
r  r  r"  r#  rK   rL   rP   r   r9   r_   )r   r   r   rN  rK  rE  rF  rI  r6  r  rR  rU  re  r!  r%  r  r  r&  r'  r(  r5   r5   r5   r6   r7    s$    

 



 
'




r7  c                   @  s*   e Zd ZdddZdd	d
ZdddZdS )TextLogfileBuilderr  r  r9   r_   c                 C  sD   | j dtj   d ttj }| j d| d d S )NzLog of Meson test suite run on 

zInherited environment: )	r5  writedatetimenow	isoformatr   rT   rU   items)r   r  Zinherit_envr5   r5   r6   r!    s   zTextLogfileBuilder.startrP   r#  c                 C  s:  |j  d|j }| jt|ddd  | jd|j d  tdt|j	}| jd| d  | jdd	|j
  d  | jd
|  d  |jr[| jd|j d  |jry|jjrddnd}| jt|ddd  | j|j |jr| jtdddd  | j|j | jtdddd  d S )NrV  =N   r|   ztest:         z%H:%M:%Szstart time:   zduration:     z%.2fszresult:       zcommand:      rM  outputr0   stderrr8   r  )r   r?  r5  r  r   r   r_  strftimegmtimer`  durationget_exit_statusrx  r  r  rq   stde)r   r  rP   titleZstarttime_strr   r5   r5   r6   r'    s"   zTextLogfileBuilder.logc                   sf   |j r!| jd t|j dD ]\}}| j||dd  q| j|  td| j  d S )Nz
Summary of Failures:

r   Fr|   zFull log written to )r  r5  r  r  r   r  rW   r0  r  r5   r5   r6   r(    s   zTextLogfileBuilder.finishNr+  r-  )r   r   r   r!  r'  r(  r5   r5   r5   r6   r    s    

r  c                   @  s   e Zd Zd
ddZd	S )JsonLogfileBuilderr  r  rP   r#  r9   r_   c              	   C  sR   |j |j|jj|j|j|j|j|jd}|j	r|j	|d< | j
t|d  d S )N)r   rM  rP   r`  r  
returncoder   commandr  r|   )r   r  r   r   r`  r  r  r   cmdr  r5  r  jsondumps)r   r  rP   Zjresultr5   r5   r6   r'    s   

zJsonLogfileBuilder.logNr-  )r   r   r   r'  r5   r5   r5   r6   r    s    r  c                   @  s.   e Zd ZdZdddZdddZdddZdS )JunitBuildera  Builder for Junit test results.

    Junit is impossible to stream out, it requires attributes counting the
    total number of tests, failures, skips, and errors in the root element
    and in each test suite. As such, we use a builder class to track each
    test case, and calculate all metadata before writing it out.

    For tests with multiple results (like from a TAP test), we record the
    test as a suite with the project_name.test_name. This allows us to track
    each result separately. For tests with only one result (such as exit-code
    tests) we record each one into a suite with the name project_name. The use
    of the project_name allows us to sort subproject tests separately from
    the root project.
    r0  rL   r9   r_   c                 C  s$   || _ tjddddd| _i | _d S )NZ
testsuites0testsr   failures)r0  etElementrootsuites)r   r0  r5   r5   r6   r6  $  s
   
zJunitBuilder.__init__r  r  r"  r#  c              
   C  s   |j durU|j dD ]G}d|j|j|jd |jd< |dD ]}|jd= q!|dD ]}|jd= q-|d	D ]}|jd
= q9|dD ]}|jd= qE| j| qdS |jrD|j d|j }|| j	vsq|j
jdksqJ dtjd|tt|jttdd |jD ttdd |jD ttdd |jD t|jd }| j	|< |jD ]p}tj|dt||d}|jtju rt|d nJ|jtju rt|d n=|jtju rt|d n0|jtju rt|d}d|_n |jtju rt|d}d|_n|jtju rt|d}d|_|jr|jt|d_q|jr.t|d}	t|j |	_|j rBt|d}
t|j  |
_dS dS |j| j	vrbtjd|jd d!d!d!t|jd }| j	|j< n| j	|j }tt!|jd" d |jd"< tj|d|j|jt|jd#}|j"tju rt|d tt!|jd d |jd< n7|j"tju rt|d tt!|jd$ d |jd$< n|j"tju rt|d tt!|jd% d |jd%< |jrt|d}	t|j |	_|j rt|d}
t|j  |
_dS dS )&zLog a single test case.Nz.//testsuitez{}.{}.{}r   z.//testcase[@result]rP   z.//testcase[@timestamp]	timestampz.//testcase[@file]r5  z.//testcase[@line]r   .r   zduplicate suiteZ	testsuitec                 s  s&    | ]}|j tjtjhv rd V  qdS r   N)rP   r   r   r   r2   rr5   r5   r6   	<genexpr>H  s   
 
z#JunitBuilder.log.<locals>.<genexpr>c                 s  s*    | ]}|j tjtjtjhv rd V  qdS r  )rP   r   r   r   r   r  r5   r5   r6   r  J  s   
 c                 s  s     | ]}|j tju rd V  qdS r  rP   r   r   r  r5   r5   r6   r  L  s    )r   r  r   r  r   r_  testcase)r   	classnamer   errorZfailurezTest unexpected passed.zTest was interrupted by user.z.Test did not finish before configured timeout.z
system-outz
system-err1r  r  )r   r  r_  r   r  )#junitfindallr   projectr   attribr  rn   resultsr  r  rc   r  r  rL   r^  sumr  Z
SubElementrP   r   r   r   r   r   textr   r   r   r  replace_unencodable_xml_charsr  r  rM   r   )r   r  r"  suitecaseZ	suitenameZsubtestr  Zfailouterrr5   r5   r6   r'  *  s   






zJunitBuilder.logc                   s   | j  D ]"}| j| dD ]}tt| jj| t|j|  | jj|< qqt| j}t	| j
d}|j|ddd W d   dS 1 sIw   Y  dS )z9Calculate total test counts and write out the xml result.r  wbr1  T)r3  Zxml_declarationN)r  valuesr  rn   rL   rM   r  r  ElementTreer4  r0  r  )r   r  r  attrtreefr5   r5   r6   r(    s   ,"zJunitBuilder.finishN)r0  rL   r9   r_   r,  r+  )r   r   r   __doc__r6  r'  r(  r5   r5   r5   r6   r    s
    

\r  c                      s   e Zd ZU dZi Zded< d= fd
dZd>ddZd?ddZe	d@ddZ
e	dAdd ZdBd!d"ZdBd#d$ZdBd%d&ZdCd'd(Ze	dDd*d+ZdCd,d-ZdCd.d/ZdEdFd3d4Ze	dAd5d6ZdGd;d<Z  ZS )HTestRunr   z'T.Dict[TestProtocol, T.Type['TestRun']]PROTOCOL_TO_CLASSr"  r   ru   T.Anykwargsr9   c                   s   t  tj|j S r   )super__new__r  r  protocol)clsr"  ru   r  	__class__r5   r6   r    r   zTestRun.__new__test_envT.Dict[str, str]r   rL   rZ  r   is_parallelr:   rw  c                 C  s   t j| _|| _d | _|| _|| _g | _d | _d | _	d | _
d| _d| _d| _d | _|| _|j| _|j| _d | _|| _|| _g | _d S Nr8   )r   r   r   r"  _numr   rZ  r  r  r`  r  r  r  additional_errorr  r   should_failproject_namer  r  r  rw  r  )r   r"  r  r   rZ  r  rw  r5   r5   r6   r6    s(   
zTestRun.__init__r  T.List[str]r_   c                 C  s   t j| _t | _|| _d S r   )r   r   r   r_  r`  r  )r   r  r5   r5   r6   r!    s   

zTestRun.startrM   c                 C  s&   | j d u rt jd7  _tj| _ | j S Nr   )r  r  TEST_NUMr   r5   r5   r6   r     s   
zTestRun.numc                 C  s   | j o
| j o
| j S r   )rw  r  r{  r   r5   r5   r6   rz    s   zTestRun.direct_stdoutc                 C  sT   | j r(tdd | j D }tdd | j D }||kr | dS | d| dS dS )Nc                 s  s    | ]}|j  V  qd S r   )rP   r   r2   r   r5   r5   r6   r        z&TestRun.get_results.<locals>.<genexpr>c                 s      | ]	}|j tjuV  qd S r   r  r  r5   r5   r6   r        z subtests passedrV  r8   )r  r  )r   ZpassedZranr5   r5   r6   get_results  s   
zTestRun.get_resultsc                 C  s
   t | jS r   )r   r  r   r5   r5   r6   r    rD   zTestRun.get_exit_statusc                 C  s&   | j tju rdS | jr|  S |  S r  )r   r   r   r  r  r  r   r5   r5   r6   rb    s
   zTestRun.get_detailsc                 C  s   | j tjkr
tj| _ t| j tsJ | jr+| j tjtjfv r+| j tju r'tjntj| _ | j	r;| j	
ds;|  j	d7  _	| jrK| j
dsK|  jd7  _t | j | _d S r   )r   r   r   r   
isinstancer  r   r   r   r  endswithr  r_  r`  r  r   r5   r5   r6   	_complete  s   zTestRun._completer   c                 C  sD   | j sd S t| j ttj  }t|ddd | j D  S )Nr   c                 s  s    | ]}t |V  qd S r   )r   r  r5   r5   r6   r    s    z"TestRun.cmdline.<locals>.<genexpr>)r  rT  r   r  rT   rU   r   r   )r   Ztest_only_envr5   r5   r6   rx    s   zTestRun.cmdlinec                 C  s$   t   | _t| _tj| _|   d S r   )r_  r`  GNU_SKIP_RETURNCODEr  r   r   r   r  r   r5   r5   r6   complete_skip  s   
zTestRun.complete_skipc                 C     |    d S r   )r  r   r5   r5   r6   complete     zTestRun.completeFr   r}  c                 C  s   |rdn| j }| js| jrCd}|r-|td|d 7 }||7 }|dd  dkr-|d7 }|td|d 7 }|t| j| j7 }n|}|rS|dd  dkrS|d7 }|S )Nr8   zstdout:r|   r{   zstderr:)r  r  r  r   cyanr   r   )r   r   r}  r  r   r5   r5   r6   r    s   zTestRun.get_logc                 C  r   )NFr5   r   r5   r5   r6   r{    r   zTestRun.needs_parsingr  r  r   r   c                   s   |2 z3 d H W }q6 d S r   r5   )r   r  r   lr5   r5   r6   r     s   zTestRun.parse)r"  r   ru   r  r  r  r9   r  )r"  r   r  r  r   rL   rZ  r   r  r:   rw  r:   )r  r  r9   r_   r   r   r   r*  r9   r   )FF)r   r:   r}  r:   r9   rL   r  r  r   r   r9   r_   )r   r   r   r  r  r   r  r6  r!  propertyr   rz  r  r  rb  r  rx  r  r  r  r{  r   __classcell__r5   r5   r  r6   r    s,   
 







r  c                         e Zd Zd fddZ  ZS )TestRunExitCoder9   r_   c                   s\   | j tjkrn | jtkrtj| _ n| jtkrtj| _ nt| jr#tj	ntj
| _ t   d S r   )r   r   r   r  r  r   GNU_ERROR_RETURNCODEr   r:   r   r   r  r  r   r  r5   r6   r    s   



zTestRunExitCode.completer*  r   r   r   r  r  r5   r5   r  r6   r    s    r  c                      r  )TestRunGTestr9   r_   c              
     s   | j j d}| j jrtj| j j|}z t|dddd}t|| _	W d    n1 s.w   Y  W n& t
y=   Y n tjyZ } ztd| d| W Y d }~nd }~ww t   d S )N.xmlr  utf8r/  r2  zUnable to parse : )r"  r   workdirrT   pathr   r4  r  r   r  FileNotFoundErrorZ
ParseErrorr   r  r  r  )r   r0  r  er  r5   r6   r    s   "zTestRunGTest.completer*  r  r5   r5   r  r6   r    s    r  c                      s6   e Zd ZedddZd fddZdddZ  ZS )
TestRunTAPr9   r:   c                 C  r   NTr5   r   r5   r5   r6   r{  5  r   zTestRunTAP.needs_parsingr_   c                   sN   | j dkr | j s tj| _| jpd| _|  jd| j  d7  _t   d S )Nr   r8   z'
(test program exited with status code r   )r  r   r   r   r   r  r  r  r   r  r5   r6   r  9  s
   zTestRunTAP.completer  r  r   r   c           
   	     s  d }g }d}t  |2 ze3 d H W }t|t jr|j}qt|t jr/tj}|| |j	| qt|t j
rS| j| |j rCtj}|| |jpNd|j |j qt|t jr_|| qt|t jrr|  jd|j	 7  _tj}q6 |rttd}tttdd |D }|D ]}	| jd|	j| d| d|	j	  q|d	kr| jd
 n| jttdd  tdd | jD rtj}|r| jtj kr|| _d S d S d S )Nr(   zsubtest zTAP parsing error: UNKNOWNc                 s  s    | ]}|j V  qd S r   )r   )r2   r  r5   r5   r6   r  X  s    z#TestRunTAP.parse.<locals>.<genexpr>zstdout: r  r   zUnknown TAP output lines have been ignored. Please open a feature request to
implement them, or prefix them with a # if they are not TAP syntax.r   z: Unknown TAP output lines for a supported TAP version.
This is probably a bug in the test; if they are not TAP syntax, prefix them with a #c                 s      | ]	}|j tju V  qd S r   r  r2   tr5   r5   r6   r  a  r  )!r   r   r  r   r   r   r   r   r&  r   r   r  rn   rP   r   r   r   r   r   r   r  rL   r   r   r^  rs  r  r   r   allr   r   r   )
r   r  r   r   r  r   r  unknownr   rR   r5   r5   r6   r   @  sF   
 (
zTestRunTAP.parser   r*  r  )r   r   r   r  r{  r  r   r  r5   r5   r  r6   r  4  s
    r  c                   @  s$   e Zd ZedddZdd
dZdS )TestRunRustr9   r:   c                 C  r   r  r5   r   r5   r5   r6   r{  l  r   zTestRunRust.needs_parsingr  r  r   r   r_   c                   s  ddd	}d
}|2 z93 d H W }| drC| dsC| d\}}}}|dd}||||}	| j|	 || ||	j |d
7 }q
6 d }
tdd | jD rUt	j
}
ntdd | jD rct	j}
ntdd | jD rpt	j}
|
r}| jt	jkr|
| _d S d S d S )NnrM   r   rL   rP   r9   r   c                 S  sf   |dkrt | |tjd S |dkrt | |tjd S |dkr't | |tjd S t | |tjd| S )Nr   ZignoredZFAILEDz#Unsupported output from rust test: )r   r   r   r   r   r   r   )r  r   rP   r5   r5   r6   	parse_resq  s   z$TestRunRust.parse.<locals>.parse_resr   ztest ztest resultr   z::r  c                 s  r  r   r  r  r5   r5   r6   r    r  z$TestRunRust.parse.<locals>.<genexpr>c                 s  r  r   )rP   r   r   r  r5   r5   r6   r    r  c                 s  r  r   )rP   r   r   r  r5   r5   r6   r    r  )r  rM   r   rL   rP   rL   r9   r   )r   r  rq   r/  r  rn   r&  rP   r	  r   r   anyr   r   r   r   )r   r  r   r  r  r   rO  r   rP   r  r   r5   r5   r6   r   p  s.   

	
zTestRunRust.parseNr   r  )r   r   r   r  r{  r   r5   r5   r5   r6   r  k  s    r  original_strc                 C  s   dd }t || S )Nc                 S  s   t |  dd S )Nr   r{   )reprr
  )Zillegal_chrr5   r5   r6   r         z/replace_unencodable_xml_chars.<locals>.<lambda>)UNENCODABLE_XML_CHRS_RErJ  )r  Zreplacement_lambdar5   r5   r6   r    s   r  streamT.Union[None, bytes]c                 C  s:   | d u rdS z|  dW S  ty   | j ddd Y S w )Nr8   r1  z
iso-8859-1ignorer   )r   UnicodeDecodeError)r  r5   r5   r6   r     s   r   readerasyncio.StreamReaderqueue,T.Optional['asyncio.Queue[T.Optional[str]]']console_modec              
     sF  g }zzw|   sjz
| dI d H }W n1 tjy) } z	|j}W Y d }~n d }~w tjyD } z| |jI d H }W Y d }~nd }~ww |rft|}|	| |t
ju r\t|ddd |rf||I d H  |   r	d|W W |r{|d I d H  S S  tjy   d| Y W |r|d I d H  S S w |r|d I d H  w w )N   
r8   T)r~   r  )Zat_eofZ	readuntilrh  ZIncompleteReadErrorpartialZLimitOverrunErrorZreadexactlyconsumedr   rn   r   r   rW   putr   CancelledError)r  r  r  Z
stdo_linesZ
line_bytesr  r   r5   r5   r6   read_decode  sD   

r!  fnamec                 C  s   |  dot p
t  S )Nz.exe)r  r@   rC   )r"  r5   r5   r6   run_with_mono  s   r#  objsT.List[TestSerialisation]c                 C  sb   t | ts
tdt| D ]"}t |tstdtt|ds"tdtt|jtr.t|jtq| S )Nz	<unknown>r   )r  ri   r   coredata_versionr   hasattrr   r   )r$  objr5   r5   r6   check_testdata  s   





r)  q 'asyncio.Queue[T.Optional[str]]'r   c                 C s.   	 |   I d H }|   |d u rd S |V  qr   )getZ	task_done)r*  itemr5   r5   r6   
queue_iter  s   r.  futureasyncio.Futurec                   s*   z| I dH  W dS  t jy   Y dS w )z?Wait for completion of the given future, ignoring cancellation.N)rh  r   )r/  r5   r5   r6   r    s   r  futuresT.Iterable[asyncio.Future]rZ  T.Optional[T.Union[int, float]]c                   s   d
dd}t  }|du rdn| | }| rD|du s |dkrDt j| |t jd	I dH \}} || |r:||  }| rD|du s |dks ||  dS )a9  Wait for completion of all the given futures, ignoring cancellation.
       If timeout is not None, raise an asyncio.TimeoutError after the given
       time has passed.  asyncio.TimeoutError is only raised if some futures
       have not completed and none have raised exceptions, even if timeout
       is zero.r1  r2  r9   r_   c                 S  s:   d}| D ]}|  sd}q| s|  q|rtjd S NFT)done	cancelledrP   rh  TimeoutError)r1  r\  r  r5   r5   r6   check_futures  s   z#complete_all.<locals>.check_futuresNr   )rZ  Zreturn_when)r1  r2  r9   r_   )rh  ri  r_  rj  ZFIRST_EXCEPTION)r1  rZ  r8  rn  Zdeadliner5  r5   r5   r6   complete_all  s   
r9  c                   @  sB   e Zd Z	ddd	d
ZdddZdddZd ddZd!ddZdS )"TestSubprocessNpasyncio.subprocess.ProcessrM  r   r  postwait_fnT.Callable[[], None]c                 C  s4   || _ || _|| _d | _d | _|| _g | _d | _d S r   )_processrM  r  	stdo_task	stde_taskr=  all_futuresr  )r   r;  rM  r  r=  r5   r5   r6   r6    s   
zTestSubprocess.__init__r9   r   c                 C  s   t  | _t| jS r   )rh  Queuer  r.  r   r5   r5   r6   stdout_lines  s   

zTestSubprocess.stdout_linesr"  r#  r  r   CT.Tuple[T.Optional[T.Awaitable[str]], T.Optional[T.Awaitable[str]]]c                   s   d fd	d
}ddd} j d u r+ jd ur+|| jj|}t| _  j j   jd urL jtjj	krL|| jj|}t| _
 j j
  j  j
fS )Nr"  r#  r  r  r  r   r9   r_   c                   s   t | j|I d H | _d S r   )r!  r  r  r"  r  r  r   r5   r6   collect_stdo  s   z0TestSubprocess.communicate.<locals>.collect_stdoc                   s   t |d |I d H | _d S r   )r!  r  rF  r5   r5   r6   collect_stde  s   z0TestSubprocess.communicate.<locals>.collect_stde)r"  r#  r  r  r  r   r9   r_   )r@  rM  r?  rh  ru  rB  rn   r  
subprocessr   rA  )r   r"  r  rG  rH  Zdecode_coror5   r   r6   communicate  s   
zTestSubprocess.communicater   c                   sb  | j }zzt rtddddt|jg nLt|jtj	 t
tj tj| ddI d H  W d    n1 s<w   Y  |jd ur\W W | jrP| j  | jrZ| j  d S d S t|jtj t
tj tj| ddI d H  W d    n1 sw   Y  |jd urW W | jr| j  | jr| j  d S d S |  t
tj tj| ddI d H  W d    n1 sw   Y  |jd urW W | jr| j  | jr| j  d S d S W W | jr| j  | jr| j  dS dS  ty   | I d H  Y W | jr| j  | jr| j  d S d S w | jr&| j  | jr0| j  w w )	NZtaskkillz/Fz/Tz/PIDg      ?rZ  r   z!Test process could not be killed.)r?  r@   rI  runrL   pidrT   killpgr   SIGTERMr   rh  r7  wait_forrj  r  r@  cancelrA  SIGKILLkillProcessLookupError)r   r;  r5   r5   r6   _kill,  st   




	



zTestSubprocess._killr_   c                   s   | j }| jt|  zNzt| j|jdI d H  W n7 tjy9   | j	| 
 I d H p0d7  _	tj|_Y n tjyT   | j	| 
 I d H pKd7  _	tj|_Y nw W | jr]|   n	| jrf|   w w |jpkd|_d S )NrK  r8   r   )r?  rB  rn   rh  ru  rj  r9  rZ  r7  r  rU  r   r   r   r   r   r=  r  )r   r"  r;  r5   r5   r6   rj  \  s(   
zTestSubprocess.waitr   )r;  r<  rM  r   r  r   r=  r>  )r9   r   )r"  r#  r  r   r9   rE  r  )r"  r#  r9   r_   )r   r   r   r6  rD  rJ  rU  rj  r5   r5   r5   r6   r:     s    


0r:  c                   @  sr   e Zd Zd,d	d
Zd-ddZd-ddZed.ddZed/ddZed0ddZ	d1ddZ
d2d%d&Zd3d)d*Zd+S )4SingleTestRunnerr"  r   r   r  r   rL   r  argparse.Namespacec           
      C  s  || _ || _|  | _| jrU| j jrUtj| j jdg |d  |d< g }| jD ],}|| tj	
|drTt|dd | j jD |ddd | j j|d<  nq(d|vs]|d sj|jsjttd	d
|d< d|vsr|d svd|d< d|vs~|d sd|d< | jjs| j jd u s| j jdkrd }n| jjd u r| j j}n| jjdkrd }n| j j| jj }|jo| jjd	ko| jj }|js| jjo| jj }	t||||||	| _| jjrtj| _d S | jj rtj!| _d S tj"| _d S )Nr8   PATHwinec                 S  s   g | ]}d | qS )zZ:r5   )r2   r;  r5   r5   r6   r7     r  z-SingleTestRunner.__init__.<locals>.<listcomp>WINEPATH;ZMALLOC_PERTURB_r      ZASAN_OPTIONSz0halt_on_error=1:abort_on_error=1:print_summary=1ZUBSAN_OPTIONSzChalt_on_error=1:abort_on_error=1:print_summary=1:print_stacktrace=1r   )#r"  r  _get_cmdr  extra_pathsrT   pathsepr   rn   r   basenamer   r   r,  rq   r  	benchmarkrL   randomrandintrg   rZ  timeout_multiplierr  num_processesrw  r  r  runobjr   r   r  rz  r   r   )
r   r"  r   r   r  winecmdrQ   rZ  r  rw  r5   r5   r6   r6  q  sJ   
"

" 
zSingleTestRunner.__init__r9   T.Optional[T.List[str]]c                 C  s   | j jd }| jjr| j jrtj|std|d|	dr)ddg| j j S | j j
s8t|r8dg| j j S | j jrl| j j
rl| j jrl| j jd u rLd S | j jrl| j j sbd}t|| j jj| j j | j j S | j jS )	Nr   zThe test program z7 does not exist. Cannot run tests before building them.z.jarjavaz-jarmonozmThe exe_wrapper defined in the cross file {!r} was not found. Please check the command and/or add it to PATH.)r"  r"  r  
no_rebuildcmd_is_builtrT   r   isfiler   r  is_cross_builtr#  
cmd_is_exeneeds_exe_wrapperexe_wrapperfoundr   r   get_command)r   Z	testentrymsgr5   r5   r6   _get_test_cmd  s    
zSingleTestRunner._get_test_cmdc                 C  s    |   }|sd S t| j| S r   )ru  TestHarnessget_wrapperr  )r   Ztest_cmdr5   r5   r6   r]    s   zSingleTestRunner._get_cmdr:   c                 C     | j jS r   )rf  r  r   r5   r5   r6   r       zSingleTestRunner.is_parallelc                 C  rx  r   )rf  r   r   r5   r5   r6   visible_name  ry  zSingleTestRunner.visible_namer   c                 C  rx  r   )rf  rZ  r   r5   r5   r6   rZ    ry  zSingleTestRunner.timeoutr  r  r  c                   st   | j d u rd| _|| j | j  | jS | j | jj | jj }| j	| || j | 
||I d H  | jS )Nz7Not run because cannot execute cross compiled binaries.)r  r  log_start_testrf  r  r"  cmd_argsr  Z	test_argsr!  _run_cmd)r   r  r  r5   r5   r6   rL    s   

zSingleTestRunner.runru   r  rM  r  cwdr   r:  c          	        s   j jrttj ttjtj d	fdd}d	 fdd}tj|||||t s.|nd dI d H }t	|||t sA|dS d dS )
Nr9   r_   c                     s(    j jrttjtj d S t  d S r   )r  rg   r   SIGINTSIG_DFLrT   setsidr5   r   r5   r6   
preexec_fn  s   z4SingleTestRunner._run_subprocess.<locals>.preexec_fnc                     s   j jrttj  d S d S r   )r  rg   r   r  r5   Zprevious_sigint_handlerr   r5   r6   r=    s   z5SingleTestRunner._run_subprocess.<locals>.postwait_fn)rM  r  r   r~  r  )rM  r  r=  r*  )
r  rg   r   	getsignalr  SIG_IGNrh  Zcreate_subprocess_execr@   r:  )	r   ru   rM  r  r   r~  r  r=  r;  r5   r  r6   _run_subprocess  s$   z SingleTestRunner._run_subprocessr  r_   c                   s8  | j tju rd }d }ntjj}| jjs| jj	stjj
ntjj}g }| jjtju rE| jj}| jjr<tj| jj| jj}|d| d | j|| ||| jj| jjdI d H }| jj	rk| j|| }t|}	nd }	|| j| j \}
}|| jI d H  |	r|	I d H  |
r|
I d H  |r|I d H  | j  d S )Nz--gtest_output=xml:r  )rM  r  r   r~  )r  r   r   rh  rI  PIPEr  rq   rf  r{  r   r"  r  r   GTESTr   r  rT   r   r   rn   r  r   r   rD  ru  rJ  rj  r  )r   r  r  rM  r  Z	extra_cmdZ	gtestnamer;  Z
parse_coroZ
parse_taskr@  rA  r5   r5   r6   r}     sH   




zSingleTestRunner._run_cmdN)r"  r   r   r  r   rL   r  rW  )r9   rh  r   r   )r9   r   )r  r  r9   r  )ru   r  rM  r   r  r   r   r  r~  r   r9   r:  )r  r  r  r  r9   r_   )r   r   r   r6  ru  r]  r  r  rz  rZ  rL  r  r}  r5   r5   r5   r6   rV  o  s    

8


"rV  c                   @  sn  e Zd ZdpddZdqddZdrd
dZdrddZdsddZdtddZduddZ	drddZ
dvd!d"Zdwd%d&Zdxd(d)Zdyd,d-Zedzd/d0Zedzd1d2Zd{d4d5Z	6	7	8	8	8d|d}dAdBZd~dCdDZdzdEdFZdzdGdHZeddKdLZeddOdPZddQdRZddUdVZdddYdZZdrd[d\Zdrd]d^Zedd_d`ZddadbZ ddedfZ!ddjdkZ"ddldmZ#ddndoZ$d8S )rv  r  rW  c                 C  s<  || _ g | _d| _d| _d| _d| _d| _d| _d| _d| _	d| _
g | _t | _| j| j d| _d | _d | _| j jr{| j js{d }tj| j jd| j j| _| j jr`tj| | j d }n| j jrl| j jdd}|r{|  jd|dd 7  _|   |   t }| j D ]}|j!D ]}|"| qqt#|| _$d S )Nr   Fz
meson-logs:rO  r0   r   )%r  r  
fail_countexpectedfail_countunexpectedpass_countsuccess_count
skip_counttimeout_countr?  name_max_lenis_runloggersr7  console_loggerrn   rt  ninjalogfile_baseZlogbaserg   rT   r   r   rl   rj   r`  rw  rt   r/  prepare_buildload_metadatarT  r  r  rm  ri   r  )r   r  Znamebasessr  rK   r5   r5   r6   r6  +  sD   

zTestHarness.__init__r9   'ConsoleLogger'c                 C  s   | j sJ | j S r   )r  r   r5   r5   r6   get_console_loggerS  s   
zTestHarness.get_console_loggerr_   c                 C  s6   | j jrd S t | _| jstd td d S d S )Nz%Can't find ninja, can't rebuild test.r+   )r  rk  r
   detect_ninjar  rW   rB   exitr   r5   r5   r6   r  W  s   
zTestHarness.prepare_buildc              	   C  s  t  }zxt | jj | jjsJtj| jddg ddj	}d|vrJd|vrJ| jj
r,tjntj	}tj| jdg | d}|jdkrJtd	| jjtt  | _| jjs\| jj| j_| jjrg| d
| _n| d| _W t | d S W t | d S t | w )Nz-nzbuild.ninjaT)capture_outputs   ninja: no work to do.s   samu: nothing to do)rM  r   zCould not configure zmeson_benchmark_setup.datzmeson_test_setup.dat)rT   getcwdchdirr  rl   rk  rI  rL  r  rM  ri   rB   r  filenor  r   r	   load
build_datart   test_setup_default_namera  
load_testsr  )r   startdirZteststdor  retr5   r5   r6   r  d  s&   
zTestHarness.load_metadata	file_namerL   r%  c                 C  sf   t d| }| std| jjd|d}tt|}W d    |S 1 s,w   Y  |S )Nzmeson-privatez
Directory z- does not seem to be a Meson build directory.rb)	r   is_filer   r  rl   r4  r)  pickler  )r   r  datafiler  r$  r5   r5   r6   r    s   
zTestHarness.load_testsr  c                 C  r   r   r5   r   r5   r5   r6   	__enter__  r  zTestHarness.__enter__exc_typer  	exc_value	tracebackc                 C  r  r   )close_logfiles)r   r  r  r  r5   r5   r6   __exit__  r  zTestHarness.__exit__c                 C  s   | j D ]}|  qd | _d S r   )r  r)  r  r   r  r5   r5   r6   r    s   


zTestHarness.close_logfilesr"  T.Optional[TestSerialisation]build.TestSetupc                 C  s   d| j jv r!| j j| jjvrtd| j j d | jj| j j S |jd | j j }|| jjvr?td| j j d|j d | jj| S )Nr  zUnknown test setup 'z'.zTest setup 'z' not found from project ')r  rt   r  test_setupsrB   r  r  )r   r"  Z	full_namer5   r5   r6   get_test_setup  s   zTestHarness.get_test_setupr   r  c                 C  sl   |  |}|js|j|_|jrd|_|jd u r|j|_|jd u r%|j|_n|jr-td |j	t
j S )NTzBConflict: both test setup and command line specify an exe wrapper.)r  rg   rw  rd  rj   rq  rB   r  r   get_envrT   rU   copy)r   r  r"  currentr5   r5   r6   merge_setup_options  s   




zTestHarness.merge_setup_optionsrV  c                 C  s   |  |}t| j}| jjr| ||}ntj }|j	|}|
| |jr<|jr<|jr<|j r<t|j |d< t||||S )NZMESON_EXE_WRAPPER)get_pretty_suiter   r  rt   r  rT   rU   r  r   r  rS  rn  rp  rq  rr  r   rs  rV  )r   r"  r   r  r   r  r5   r5   r6   get_test_runner  s   



zTestHarness.get_test_runnerrP   r  c                 C  s   |j tju r|  jd7  _nT|j tju r|  jd7  _nF|j tju r*|  jd7  _n8|j tjtj	tj
hv r=|  jd7  _n%|j tju rK|  jd7  _n|j tju rY|  jd7  _n	td|j   |j  rm| j| | jD ]}|| | qpd S )Nr   z!Unknown test result encountered: )r   r   r   r  r   r  r   r  r   r   r   r  r   r  r   r  rB   r  r   r  rn   r  r'  )r   rP   r  r5   r5   r6   process_test_result  s$   

zTestHarness.process_test_resultrM   c                 C  s   t t| jS r   )r^  rL   r?  r   r5   r5   r6   numlen     zTestHarness.numlenc                 C  s   d| j  d S )NrE   )r  r   r5   r5   r6   r<    r  zTestHarness.max_left_widthr   c                 C  s   dj | j|| jdS )Nz{num:{numlen}}/{testcount} )r  r   Z	testcount)r   r  r?  )r   r   r5   r5   r6   get_test_num_prefix  s   zTestHarness.get_test_num_prefixr   r8   Nr   r:   r<  r  r\  r   r  r]  c           
      C  s   |d u r
|  |j}t|| j}|d u r|j}|| j d t| t| t| }|dtd| 7 }|d u rSdj|j	||j
| jd d}| }	|	rS|d|	 7 }|| | | S )Nr   r   z{res} {dur:{durlen}.2f}sr%   )r   rX  rY  r[  )r  r   rs  r<  r   r  rS   r   r   r   r  ra  rb  )
r   rP   r   r<  r  r\  r  r]  Zextra_mid_widthrd  r5   r5   r6   r     s"   &
zTestHarness.formatc                 C  s&   t d| j| j| j| j| j| jS )Nz
            Ok:                 {:<4}
            Expected Fail:      {:<4}
            Fail:               {:<4}
            Unexpected Pass:    {:<4}
            Skipped:            {:<4}
            Timeout:            {:<4}
            )	textwrapdedentr   r  r  r  r  r  r  r   r5   r5   r6   r    s
   zTestHarness.summaryc                 C  s   | j | j | j S r   )r  r  r  r   r5   r5   r6   total_failure_count  s   zTestHarness.total_failure_countc              	     s(   j rtdd _   }|sdS  jjs$t j jj|s$t	d t
 fdd|D  _t jjt| jj  j_t }zJt jj g }t jjD ]&}| fdd|D  |dkryt
dd |D  _td	d |D  _qSt| _ | W t|   S t| w )
Nz*Test harness object can only be used once.Tr   }   c                 3  s    | ]
}t  |V  qd S r   )rS   r  r2   r"  r   r5   r6   r        z#TestHarness.doit.<locals>.<genexpr>c                 3  s    | ]}  |V  qd S r   )r  r  r   r5   r6   r    r  c                 s  s&    | ]}t tt|jpd V  qdS )r$   N)r^  rL   rM   rZ  r2   runnerr5   r5   r6   r     s    c                 s  r  r   )r  r   r   r  r5   r5   r6   r  #  s    )r  RuntimeError	get_testsr  rk  rebuild_depsr  rl   rB   r  rs  r  minre  r^  rc   rT   r  r  rangeextendra  r  rt  r?  	run_testsr  )r   r  r  runnersr  r5   r   r6   doit  s>   




zTestHarness.doitr  T.Tuple[str, str]c                 C  s<   d| v r|  dd}t|dksJ |d |d fS | dfS )Nr  r   rE   r   r8   )rq   r^  )r  rq   r5   r5   r6   split_suite_string,  s
   zTestHarness.split_suite_stringr  r  c                 C  sl   |D ]1}t |\}}| jD ]$}t |\}}|s!||kr!  dS |r(||kr(q|r/||kr/q  dS qdS NTF)rv  r  r  )r"  r  r  Z	prj_matchZst_matchZprjstprjstr5   r5   r6   test_in_suites5  s   
zTestHarness.test_in_suitesc                 C  sT   t || jjr
dS | jjrt || jjS | jjr(| |}t ||jr(dS dS r4  )rv  r  r  rp   rm   rt   r  )r   r"  rt   r5   r5   r6   test_suitableU  s   
zTestHarness.test_suitabler  *T.Generator[TestSerialisation, None, None]c                 c  s   i }| j jD ]'}d|v r#|jddd\}}|dkrd}|dkr"d}nd|}}d|||f< q|D ]"}t|D ]\}}t|j|rRt|j|rRd|||f< |V   nq7q1| D ]1\\}}}|s| d| }|D ]}t|j|rt|j|rt	| d  nqit
| d	qXd
S )a  
        Allow specifying test names like "meson test foo1 foo2", where test('foo1', ...)

        Also support specifying the subproject to run tests from like
        "meson test subproj:" (all tests inside subproj) or "meson test subproj:foo1"
        to run foo1 inside subproj. Coincidentally also "meson test :foo1" to
        run all tests with that name across all subprojects, which is
        identical to "meson test foo1"
        r  r   )maxsplitr8   rv   FTz( test name is redundant and was not usedz" test name does not match any testN)r  ru   rq   ri   r   r  r   r  r   warningr   )r   r  patternsargZsubprojr   r  Zwas_usedr5   r5   r6   tests_from_argse  s<   

zTestHarness.tests_from_args	errorfileT.Optional[T.IO]c                   sX    j std|d g S  fdd j D } jjr t |}|s*td|d g S |S )NzNo tests defined.)r5  c                   s   g | ]	}  |r|qS r5   )r  r  r   r5   r6   r7     s    z)TestHarness.get_tests.<locals>.<listcomp>zNo suitable tests defined.)r  rW   r  ru   ri   r  )r   r  r  r5   r   r6   r    s   zTestHarness.get_testsc                 C  s   | j D ]}|  qd S r   )r  r  r  r5   r5   r6   flush_logfiles  s   

zTestHarness.flush_logfilesc                 C  sT   | j sd S | jt| j d  | jt| j d  | jt| j d dd d S )Nz
.junit.xmlz.jsonz.txtsurrogateescaper   )r  r  rn   r  r  r  r   r5   r5   r6   open_logfiles  s
   zTestHarness.open_logfilesc                 C  sH   g }| j r| jdg}| jdkr|g d7 }|dg7 }| jr"|| j7 }|S )Nrs   r   )-exrL  r  quitz--args)rg   rh   rc   rj   )r  wrapr5   r5   r6   rw    s   



zTestHarness.get_wrapperc                 C  sb   t | jdkr.|jr.t|jd d }ddd |jD }|r%|d7 }|| d |j S |jS )Nr   r   +c                 s  s    | ]
}t |d  V  qdS r  )rv  r  )r2   rK   r5   r5   r6   r    r  z/TestHarness.get_pretty_suite.<locals>.<genexpr>r  z / )r^  r  r  rv  r  r   r   )r   r"  rvrK   r5   r5   r6   r    s   zTestHarness.get_pretty_suiter  T.List[SingleTestRunner]c                 C  sJ   z|    tjdkrtt  t| | W |   d S |   w )Nwin32)	r  rB   r<   rh  Zset_event_loop_policyZWindowsProactorEventLoopPolicyrL  
_run_testsr  )r   r  r5   r5   r6   r    s   
zTestHarness.run_testsrK   r   r   c                 C  s    | j D ]
}|| ||| qd S r   )r  r&  )r   r"  rK   r   r  r5   r5   r6   r&    s   
zTestHarness.log_subtestc                 C  s   | j D ]}|| | qd S r   )r  r%  )r   r"  r  r5   r5   r6   r{    s   
zTestHarness.log_start_testc           	   
     s
  t jjt i dttdt  d fdd}dfdd}dfdddfdd d fdd}d fdd}jD ]}| qUt	j
dkrtdt krstj| ntj| tj| zc|D ]7}|jstI d H  t ||}| |j|< || |jst|I d H  jjdkrjr nqtI d H  W t	j
dkrՈtj tj jD ]
}|I d H  qd S t	j
dkrtj tj jD ]
}|I d H  qw )NF)r   r"  rV  r9   r_   c              	     s   4 I d H d sj jdkrjr	 W d   I d H  d S | I d H }| j j}|rJj|krU|j r`   W d   I d H  d S W d   I d H  d S W d   I d H  d S W d   I d H  d S 1 I d H sqw   Y  d S r  )r  rc   r  rL  r  maxfailr   r   )r"  r   r  )cancel_all_testsinterruptedr   	semaphorer5   r6   run_test  s"   
.z(TestHarness._run_tests.<locals>.run_testr  r0  c                   s<   |   s|    |  z| = W d S  ty   Y d S w r   )r6  rP   r  KeyError)r  )r1  r9  r5   r6   	test_done  s   
z)TestHarness._run_tests.<locals>.test_donewarnr:   c                   sD      } | | r  td|  |= |  d S )Nz CTRL-C detected, interrupting {})popleftrn   r  r   r  r   rQ  )r  r/  )r1  r9  r   r5   r6   cancel_one_test  s   
z/TestHarness._run_tests.<locals>.cancel_one_testc                     s   dr d sd S d S r  r5   r5   )r  r  r9  r5   r6   r    s   z0TestHarness._run_tests.<locals>.cancel_all_testsc                     s$   rd S    td    d S )NzReceived SIGTERM, exiting)r  r   r  r5   )r  r  r   r5   r6   sigterm_handler
  s
   

z/TestHarness._run_tests.<locals>.sigterm_handlerc                     s|   rd S    ttkr)d d  dk r)  td    d S r1d d S   td dd S )Nr{   r   r   zCTRL-C detected, exitingT)rn   r_  r^  	MAX_CTRLCr  r   r  r5   )r  r  ctrlc_timesr  rn  r9  r   r5   r6   sigint_handler  s    


z.TestHarness._run_tests.<locals>.sigint_handlerr  r   r   )r"  rV  r9   r_   )r  r0  r9   r_   )r  r:   r9   r_   r*  )rh  	Semaphorer  re  r   r  ri  r  r!  rB   r<   rT   getpgidgetpidZadd_signal_handlerr   r  rO  r  r9  ru  rn   rz  Zadd_done_callbackr  rc   r  Zremove_signal_handlerr(  )	r   r  r  r  r  r  r  r  r/  r5   )	r  r  r  r1  r  rn  r9  r   r  r6   r    s\   

		








zTestHarness._run_tests)r  rW  )r9   r  r*  )r  rL   r9   r%  )r9   r  )r  r  r  r  r  r  r9   r_   )r"  r  r9   r  )r  rW  r"  r   r9   r  )r"  r   r9   rV  )rP   r  r9   r_   r   )r   rM   r9   rL   )r   r8   NNN)rP   r  r   r:   r<  rM   r  rL   r\  r   r  r   r]  r   r9   rL   r   )r  rL   r9   r  )r"  r   r  r  r9   r:   )r"  r   r9   r:   )r  r%  r9   r  r   )r  r  r9   r%  )r  rW  r9   r  )r"  r   r9   rL   )r  r  r9   r_   )r"  r  rK   rL   r   r   r9   r_   )r"  r  r9   r_   )%r   r   r   r6  r  r  r  r  r  r  r  r  r  r  r  r  r  r<  r  r   r  r  r  r   r  r  r  r  r  r  r  rw  r  r  r&  r{  r  r5   r5   r5   r6   rv  *  sV    

(













%

5






rv  thc                 C  s,   | j tjd}|D ]	}t| | q	| S )N)r  )r  rB   r  rW   r  )r  r  r  r5   r5   r6   
list_testsA  s   r  r  r  rl   r  c           
        s   dfdd t | dksJ t }t }i }ttddD ]} fd	d
|d D ||d < q|D ]}|jD ]}||v r?q8|| |||  q8q3t| dg t| j	}	|	dkrht
d  dS dS )Nr   rL   r9   c                   s*   t j|  } t jdkr| t jd} | S )NrV  )rT   r   relpathrQ  r/  )r   )rl   r5   r6   convert_path_to_targetH  s   
z,rebuild_deps.<locals>.convert_path_to_targetr   targets)kindc                   s   g | ]} |qS r5   r5   )r2   r  )r   r5   r6   r7   T  s    z rebuild_deps.<locals>.<listcomp>r0  idrk   zCould not rebuild FT)r   rL   r9   rL   )r^  rT  r   r   dependsrS  rI  rL  sortedr  rW   )
r  rl   r  r  r  Zintro_targetstargetr  dr  r5   )r   rl   r6   r  G  s*   


r  r  rW  c                 C  s  | j rd| _| jr| jrtd dS d }| jr%d| _| jr#td dS d}| jr-| jd }|d urDt|dd}| sDtd| dS t	
| j}td	|jjtd
}t| | jsz|jjtd}|dkrod| _n|dkrztd d| _t| F}z| jrt|W W  d    S | W W  d    S  ty } ztd tjdr|t| W Y d }~W d    dS d }~ww 1 sw   Y  d S )Nr   z3Can not be both quiet and verbose at the same time.Tz9Must not specify both a wrapper and gdb at the same time.rg   r   )silentz"Could not find requested program: r:   vsenvbackendnoner  zEOnly ninja backend is supported to rebuild tests before running them.z!Meson test encountered an error:
MESON_FORCE_BACKTRACE)ra  re  rw  r  rW   rg   rj   r   rr  r	   r  rl   r  castr
   coredata
get_optionr   r   rk  rv  ri   r  r  r   rT   rU   r,  )r  Z	check_binexer   
need_vsenvr
  r  r  r5   r5   r6   rL  e  s\   


rL  ru   c                 C  s&   t jdd}t| || }t|S )Nz
meson test)prog)argparseArgumentParserrz   
parse_argsrL  )ru   r]   r  r5   r5   r6   run_with_args  s   
r  r   )rK   rL   r9   rM   r   )r]   r^   r9   r_   )rK   rL   r9   r_   )r   rL   r   rL   r9   rL   )rK   rL   r   rL   r   rM   r9   rL   )r   rM   r9   rL   )r   r   r9   rL   )r  rL   r9   rL   )r  r  r9   rL   )r  r  r  r  r  r   r9   rL   )r"  rL   r9   r:   )r$  r%  r9   r%  )r*  r+  r9   r   )r/  r0  r9   r_   r   )r1  r2  rZ  r3  r9   r_   )r  rv  r9   r:   )r  r  rl   rL   r  r%  r9   r:   )r  rW  r9   rM   )ru   r  r9   rM   )}
__future__r   pathlibr   collectionsr   
contextlibr   r  r   r   r  rh  r  enumr  rX   rT   r  r<   rb  r  r   rI  shlexrB   r  r_  typingr  rN   Zxml.etree.ElementTreeZetreer  r  r8   r	   r
   r   r  r   r   r   r&  mesonlibr   r   r   r   r   r   r   r   mintror   r   programsr   Zbackend.backendsr   r   TYPE_CHECKINGUnionZTYPE_TAPResultr  r  r  r/   r   
maxunicoder  ZUNENCODABLE_XML_CHR_RANGESr  r   r  r@   rC   rO   rS   r\   rz   r   r   r   r   r   quoter   r   uniqueEnumr   r   r   r  r.  r7  r  r  r  r  r  r  EXITCODEr  r  r  TAPr  RUSTr  r   r!  r#  r)  r.  r  r9  r:  rV  rv  r  r  rL  r  r5   r5   r5   r6   <module>   s   (


	





2


	
1 0 _# z4'






!o <    


4