B
    ”Ü‡\øQ  ã               @   s¾  d 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mZ ddlmZ ejd dk ršdd	lmZ G d
d„ de
jjƒZdZdZdd„ eD ƒZdd„ eD ƒe Ze dd e¡ ¡Z[[[e d¡Zdd„ Zdd„ Zi Z dddgie d< ddddgie d< e d  !¡ e d < ee d  e d ƒ e d e d!< G d"d#„ d#e"ƒZ#ej$d$d%„ ƒZ%ej$d&d'„ ƒZ&d(d)„ Z'd*d+„ Z(d,d-„ Z)d.d/„ Z*G d0d1„ d1e"ƒZ+dS )2a'  
    report test results in JUnit-XML format,
    for use with Jenkins and build integration servers.


Based on initial code from Ross Lawley.

Output conforms to https://github.com/jenkinsci/xunit-plugin/blob/master/
src/main/resources/org/jenkinsci/plugins/xunit/types/model/xsd/junit-10.xsd
é    )Úabsolute_import)Údivision)Úprint_functionN)Únodes)Úfilename_argé   )Úopenc               @   s   e Zd ZdS )ÚJunitN)Ú__name__Ú
__module__Ú__qualname__© r   r   ú/lib/python3.7/site-packages/_pytest/junitxml.pyr	   !   s   r	   )é	   é
   é   ))é    é~   )é€   iÿ×  )i à  iýÿ  )i   iÿÿ c             C   s2   g | ]*\}}|t jk rd t |¡t |¡f ‘qS )z%s-%s)ÚsysÚ
maxunicodeÚsixÚunichr)Ú.0ZlowZhighr   r   r   ú
<listcomp>-   s   r   c             C   s   g | ]}t  |¡‘qS r   )r   r   )r   Úxr   r   r   r   1   s    z[^%s]Ú z\.py$c             C   s$   dd„ }t j t |t j | ¡¡¡S )Nc             S   s(   t |  ¡ ƒ}|dkrd| S d| S d S )Néÿ   z#x%02Xz#x%04X)ÚordÚgroup)ZmatchobjÚir   r   r   Úrepl;   s    zbin_xml_escape.<locals>.repl)ÚpyÚxmlÚrawÚillegal_xml_reÚsubÚescape)Úargr!   r   r   r   Úbin_xml_escape:   s    r)   c             C   s`   i }xL|   ¡ D ]@\}}x6|  ¡ D ]*\}}t|tƒs>tt|ƒƒ‚|| ||< q W qW |  |¡ d S )N)ÚitemsÚ
isinstanceÚlistÚ	TypeErrorÚtypeÚupdate)ÚleftÚrightÚresultZklZvlZkrZvrr   r   r   Úmerge_familyE   s    
r3   ÚtestcaseÚ	classnameÚnameZ_baseÚfileÚlineÚurlZ_base_legacyÚxunit1Zxunit2c               @   sŽ   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ Zdd„ Z	d"dd„Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd d!„ ZdS )#Ú_NodeReporterc             C   sB   || _ || _| jj| _| jj| _d| _g | _g | _d | _i | _d S )Nr   )	Úidr#   Ú	add_statsÚfamilyÚdurationÚ
propertiesr   r4   Úattrs)ÚselfÚnodeidr#   r   r   r   Ú__init__\   s    

z_NodeReporter.__init__c             C   s"   | j  t|ƒj¡ | j |¡ d S )N)r#   r=   r.   r
   r   Úappend)rB   Únoder   r   r   rE   g   s    z_NodeReporter.appendc             C   s   | j  t|ƒt|ƒf¡ d S )N)r@   rE   Ústrr)   )rB   r6   Úvaluer   r   r   Úadd_propertyk   s    z_NodeReporter.add_propertyc             C   s   t |ƒ| jt|ƒ< d S )N)r)   rA   rG   )rB   r6   rH   r   r   r   Úadd_attributen   s    z_NodeReporter.add_attributec             C   s    | j rt  dd„ | j D ƒ¡S dS )zBReturn a Junit node containing custom properties, if any.
        c             S   s   g | ]\}}t j||d ‘qS ))r6   rH   )r	   Úproperty)r   r6   rH   r   r   r   r   w   s   z6_NodeReporter.make_properties_node.<locals>.<listcomp>r   )r@   r	   )rB   r   r   r   Úmake_properties_nodeq   s
    z"_NodeReporter.make_properties_nodec             C   sð   | j r
t‚t|jƒ}| j}|d d… }| jjr>| d| jj¡ d |¡t	|d ƒ|j
d dœ}|j
d d k	rz|j
d |d< t|dƒrŽ|j|d< || _| j |¡ | jdkr®d S i }x2| j ¡ D ]$}|t| j d	 kr¾| j| ||< q¾W || _d S )
Néÿÿÿÿr   Ú.)r5   r6   r7   é   r8   r9   r:   r4   )r4   ÚAssertionErrorÚmangle_test_addressrC   rA   r#   ÚprefixÚinsertÚjoinr)   ÚlocationÚhasattrr9   r/   r>   ÚkeysÚfamilies)rB   Z
testreportÚnamesZexisting_attrsZ
classnamesrA   Z
temp_attrsÚkeyr   r   r   Úrecord_testreport}   s,    





z_NodeReporter.record_testreportc             C   sH   t jf dd| j i| j—Ž}| |  ¡ ¡ x| jD ]}| |¡ q2W |S )NÚtimez%.3f)r	   r4   r?   rA   rE   rL   r   )rB   r4   rF   r   r   r   Úto_xmlœ   s
    z_NodeReporter.to_xmlNc             C   s"   t |ƒ}|||d}|  |¡ d S )N)Úmessage)r)   rE   )rB   Zkindr^   ÚdatarF   r   r   r   Ú_add_simple£   s    z_NodeReporter._add_simplec          	   C   sî   |j }|j}|j}|s|r~|rZ| jjdkrZ|rTd d dd¡|dd dd¡|g¡}q^|}n|}|r~ttdƒ}|  	|t
|ƒƒ¡ |s†|rê|rÆ| jjdkrÆ|rÀd d	 dd¡|dd dd¡|g¡}qÊ|}n|}|rêttdƒ}|  	|t
|ƒƒ¡ d S )
Nz
system-outÚ
z Captured Stdout éP   ú-r   z Captured Log z
system-errz Captured Stderr )Z	capstdoutZcaplogZ	capstderrr#   ÚloggingrT   ÚcenterÚgetattrr	   rE   r)   )rB   ÚreportZcontent_outZcontent_logZcontent_errZcontentÚtagr   r   r   Úwrite_captured_output¨   s>    







z#_NodeReporter.write_captured_outputc             C   s   |   d¡ d S )NÚpassed)r=   )rB   rg   r   r   r   Úappend_passÚ   s    z_NodeReporter.append_passc             C   s„   t |dƒr|  tjd¡ nft |jdƒr2|jjj}n t|jtj	ƒrH|j}n
t
|jƒ}t|ƒ}tj|d}| t|jƒ¡ |  |¡ d S )NÚwasxfailz%xfail-marked test passes unexpectedlyÚ	reprcrash)r^   )rV   r`   r	   ÚskippedÚlongreprrm   r^   r+   r   Zstring_typesrG   r)   ÚfailurerE   )rB   rg   r^   Zfailr   r   r   Úappend_failureÝ   s    

z_NodeReporter.append_failurec             C   s   |   tjt|jƒdd¡ d S )Nzcollection failure)r^   )rE   r	   Úerrorr)   ro   )rB   rg   r   r   r   Úappend_collect_errorí   s    z"_NodeReporter.append_collect_errorc             C   s   |   tjd|j¡ d S )Nzcollection skipped)r`   r	   rn   ro   )rB   rg   r   r   r   Úappend_collect_skippedó   s    z$_NodeReporter.append_collect_skippedc             C   s*   |j dkrd}nd}|  tj||j¡ d S )NÚteardownztest teardown failureztest setup failure)Úwhenr`   r	   rr   ro   )rB   rg   Úmsgr   r   r   Úappend_errorö   s    
z_NodeReporter.append_errorc             C   sz   t |dƒr|  tjd|j¡ nX|j\}}}| d¡r@|dd … }d|||f }|  tjt|ƒdt|ƒd¡ |  	|¡ d S )Nrl   zexpected test failurez	Skipped: r   z	%s:%s: %szpytest.skip)r.   r^   )
rV   r`   r	   rn   rl   ro   Ú
startswithrE   r)   ri   )rB   rg   ÚfilenameÚlinenoZ
skipreasonZdetailsr   r   r   Úappend_skippedý   s    

z_NodeReporter.append_skippedc                s,   |   ¡ jdd‰ | j ¡  ‡ fdd„| _ d S )Nr   )Úindentc                  s   t j ˆ ¡S )N)r"   r#   r$   r   )r_   r   r   Ú<lambda>  s    z(_NodeReporter.finalize.<locals>.<lambda>)r]   ÚunicodeÚ__dict__Úclear)rB   r   )r_   r   Úfinalize  s    
z_NodeReporter.finalize)N)r
   r   r   rD   rE   rI   rJ   rL   r[   r]   r`   ri   rk   rq   rs   rt   rx   r|   r‚   r   r   r   r   r;   [   s    
2r;   c                s   ‡ fdd„}|S )ar  Add an extra properties the calling test.
    User properties become part of the test report and are available to the
    configured reporters, like JUnit XML.
    The fixture is callable with ``(name, value)``, with value being automatically
    xml-encoded.

    Example::

        def test_function(record_property):
            record_property("example_key", 1)
    c                s   ˆ j j | |f¡ d S )N)rF   Úuser_propertiesrE   )r6   rH   )Úrequestr   r   Úappend_property#  s    z(record_property.<locals>.append_propertyr   )r„   r…   r   )r„   r   Úrecord_property  s    r†   c             C   s€   ddl m} | j |dƒ¡ dd„ }|}t| jddƒ}|dk	r`|jdkr`| j |d	|j ƒ¡ n|dk	r|| | jj¡}|j	}|S )
z¡Add extra xml attributes to the tag for the calling test.
    The fixture is callable with ``(name, value)``, with value being
    automatically xml-encoded
    r   )ÚPytestWarningz/record_xml_attribute is an experimental featurec             S   s   d S )Nr   )r6   rH   r   r   r   Úadd_attr_noop4  s    z+record_xml_attribute.<locals>.add_attr_noopÚ_xmlNr:   zOrecord_xml_attribute is incompatible with junit_family: %s (use: legacy|xunit1))
Z_pytest.warning_typesr‡   rF   Úwarnrf   Úconfigr>   Únode_reporterrC   rJ   )r„   r‡   rˆ   Z	attr_funcr#   rŒ   r   r   r   Úrecord_xml_attribute)  s    r   c          
   C   sˆ   |   d¡}|jdddddtjtddd dd	 |jd
dddd dd | jdddd | jdddd | jdddd | jdddd d S )Nzterminal reportingz
--junitxmlz--junit-xmlZstoreÚxmlpathÚpath)Zoptnamez1create junit-xml style report file at given path.)ÚactionÚdestÚmetavarr.   ÚdefaultÚhelpz--junitprefixz--junit-prefixrG   z0prepend prefix to classnames in junit-xml output)r   r’   r“   r”   Újunit_suite_namez Test suite name for JUnit reportÚpytest)r“   Újunit_loggingzLWrite captured log messages to JUnit report: one of no|system-out|system-errÚnoÚjunit_duration_reportz*Duration time to report: one of total|callÚtotalÚjunit_familyz0Emit XML for schema: one of legacy|xunit1|xunit2r:   )ZgetgroupZ	addoptionÚ	functoolsÚpartialr   Zaddini)Úparserr   r   r   r   Úpytest_addoptionH  s>    
rŸ   c          	   C   sX   | j j}|rTt| dƒsTt|| j j|  d¡|  d¡|  d¡|  d¡ƒ| _| j | j¡ d S )NZ
slaveinputr•   r—   r™   r›   )	ZoptionrŽ   rV   ÚLogXMLZjunitprefixZgetinir‰   ÚpluginmanagerÚregister)r‹   rŽ   r   r   r   Úpytest_configureq  s    r£   c             C   s$   t | dd ƒ}|r | `| j |¡ d S )Nr‰   )rf   r‰   r¡   Z
unregister)r‹   r#   r   r   r   Úpytest_unconfigure€  s    r¤   c             C   s€   |   d¡\}}}| d¡}y| d¡ W n tk
r<   Y nX |d  tjd¡|d< t d|d ¡|d< |d  || 7  < |S )Nú[z::z()r   rN   r   rM   )	Ú	partitionÚsplitÚremoveÚ
ValueErrorÚreplacer   ZSEPÚ
_py_ext_rer&   )Zaddressr   Zpossible_open_bracketZparamsrY   r   r   r   rQ   ‡  s    
rQ   c               @   s~   e Zd Zd"dd„Zdd„ Zd	d
„ Zdd„ Zdd„ Zdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd „ Zd!S )#r    r–   r˜   rš   r:   c             C   s   t j t j |¡¡}t j t j |¡¡| _|| _|| _|| _	|| _
|| _t ddddgd¡| _i | _g | _g | _g | _d| _| jdkrŒd| _d S )Nrr   rj   rp   rn   r   Zlegacyr:   )Úosr   Ú
expanduserÚ
expandvarsÚnormpathÚabspathÚlogfilerR   Ú
suite_namerd   Úreport_durationr>   ÚdictÚfromkeysÚstatsÚnode_reportersÚnode_reporters_orderedÚglobal_propertiesÚopen_reportsÚcnt_double_fail_tests)rB   r±   rR   r²   rd   r³   r>   r   r   r   rD   —  s    	
zLogXML.__init__c             C   s<   t |d|ƒ}t |dd ƒ}| j ||f¡}|d k	r8| ¡  d S )NrC   rF   )rf   r·   Úpopr‚   )rB   rg   rC   Ú	slavenodeÚreporterr   r   r   r‚   ³  s
    zLogXML.finalizec             C   sX   t |d|ƒ}t |dd ƒ}||f}|| jkr4| j| S t|| ƒ}|| j|< | j |¡ |S )NrC   rF   )rf   r·   r;   r¸   rE   )rB   rg   rC   r½   rZ   r¾   r   r   r   rŒ   »  s    



zLogXML.node_reporterc             C   s    || j kr| j |  d7  < d S )NrO   )r¶   )rB   rZ   r   r   r   r=   Í  s    
zLogXML.add_statsc             C   s   |   |¡}| |¡ |S )N)rŒ   r[   )rB   rg   r¾   r   r   r   Ú_opentestcaseÑ  s    

zLogXML._opentestcasec                s€  d}ˆ j r*ˆ jdkrÞ|  ˆ ¡}| ˆ ¡ n´ˆ jrÄˆ jdkrŒtˆ ddƒ‰tˆ ddƒ‰t‡ ‡‡fdd„| jD ƒdƒ}|rŒ|  |¡ |  j	d7  _	|  ˆ ¡}ˆ jdkr¸| 
ˆ ¡ | j ˆ ¡ qÞ| ˆ ¡ nˆ jrÞ|  ˆ ¡}| ˆ ¡ |  ˆ ¡ ˆ jdkr||  ˆ ¡}| ˆ ¡ x ˆ jD ]\}}| ||¡ qW |  ˆ ¡ tˆ ddƒ‰tˆ ddƒ‰t‡ ‡‡fd	d„| jD ƒdƒ}|r|| j |¡ dS )
a  handle a setup/call/teardown report, generating the appropriate
        xml tags as necessary.

        note: due to plugins like xdist, this hook may be called in interlaced
        order with reports from other nodes. for example:

        usual call order:
            -> setup node1
            -> call node1
            -> teardown node1
            -> setup node2
            -> call node2
            -> teardown node2

        possible call order in xdist:
            -> setup node1
            -> call node1
            -> setup node2
            -> call node2
            -> teardown node2
            -> teardown node1
        NZcallru   Ú	worker_idÚ
item_indexc             3   s>   | ]6}|j ˆ j krt|d dƒˆkrt|ddƒˆkr|V  qdS )rÁ   NrÀ   )rC   rf   )r   Úrep)rg   Ú	report_iiÚ
report_widr   r   ú	<genexpr>ù  s   z2LogXML.pytest_runtest_logreport.<locals>.<genexpr>rO   c             3   s>   | ]6}|j ˆ j krt|d dƒˆkrt|ddƒˆkr|V  qdS )rÁ   NrÀ   )rC   rf   )r   rÂ   )rg   rÃ   rÄ   r   r   rÅ     s   )rj   rv   r¿   rk   Úfailedrf   Únextrº   r‚   r»   rq   rE   rx   rn   r|   Úupdate_testcase_durationri   rƒ   rI   r¨   )rB   rg   Zclose_reportr¾   ZpropnameZ	propvaluer   )rg   rÃ   rÄ   r   Úpytest_runtest_logreportÖ  sN    












zLogXML.pytest_runtest_logreportc             C   s:   | j dks|j| j kr6|  |¡}| jt|ddƒ7  _dS )zŽaccumulates total duration for nodeid from given report and updates
        the Junit.testcase with the new total if already created.
        rš   r?   g        N)r³   rv   rŒ   r?   rf   )rB   rg   r¾   r   r   r   rÈ   ,  s    
zLogXML.update_testcase_durationc             C   s0   |j s,|  |¡}|jr"| |¡ n
| |¡ d S )N)rj   r¿   rÆ   rs   rt   )rB   rg   r¾   r   r   r   Úpytest_collectreport4  s
    
zLogXML.pytest_collectreportc             C   s.   |   d¡}|jjddd | tjd|¡ d S )NZinternalr–   )r5   r6   zinternal error)rŒ   rA   r/   r`   r	   rr   )rB   Zexcreprr¾   r   r   r   Úpytest_internalerror<  s    
zLogXML.pytest_internalerrorc             C   s   t   ¡ | _d S )N)r\   Úsuite_start_time)rB   r   r   r   Úpytest_sessionstartA  s    zLogXML.pytest_sessionstartc             C   sâ   t j t j | j¡¡}t j |¡s,t  |¡ t| jddd}t ¡ }|| j	 }| j
d | j
d  | j
d  | j
d  | j }| d¡ | tj|  ¡ d	d
„ | jD ƒ| j| j
d | j
d | j
d |d| djdd¡ | ¡  d S )NÚwzutf-8)Úencodingrj   rp   rn   rr   z&<?xml version="1.0" encoding="utf-8"?>c             S   s   g | ]}|  ¡ ‘qS r   )r]   )r   r   r   r   r   r   X  s    z/LogXML.pytest_sessionfinish.<locals>.<listcomp>z%.3f)r6   ÚerrorsZfailuresrn   Ztestsr\   r   )r}   )r¬   r   Údirnamer°   r±   ÚisdirÚmakedirsr   r\   rÌ   r¶   r»   Úwriter	   Z	testsuiteÚ_get_global_properties_noder¸   r²   r   Úclose)rB   rÑ   r±   Zsuite_stop_timeZsuite_time_deltaZnumtestsr   r   r   Úpytest_sessionfinishD  s(    

.

zLogXML.pytest_sessionfinishc             C   s   |  dd| j ¡ d S )Nrc   zgenerated xml file: %s)Z	write_sepr±   )rB   Zterminalreporterr   r   r   Úpytest_terminal_summaryc  s    zLogXML.pytest_terminal_summaryc             C   s   | j  t|ƒt|ƒf¡ d S )N)r¹   rE   rG   r)   )rB   r6   rH   r   r   r   Úadd_global_propertyf  s    zLogXML.add_global_propertyc             C   s    | j rt dd„ | j D ƒ¡S dS )zBReturn a Junit node containing custom properties, if any.
        c             S   s   g | ]\}}t j||d ‘qS ))r6   rH   )r	   rK   )r   r6   rH   r   r   r   r   o  s   z6LogXML._get_global_properties_node.<locals>.<listcomp>r   )r¹   r	   r@   )rB   r   r   r   rÕ   i  s
    z"LogXML._get_global_properties_nodeN)r–   r˜   rš   r:   )r
   r   r   rD   r‚   rŒ   r=   r¿   rÉ   rÈ   rÊ   rË   rÍ   r×   rØ   rÙ   rÕ   r   r   r   r   r    –  s"      
Vr    ),Ú__doc__Z
__future__r   r   r   rœ   r¬   Úrer   r\   r"   r   r–   Z_pytestr   Z_pytest.configr   Úversion_infoÚcodecsr   r#   Z	Namespacer	   Z_legal_charsZ_legal_rangesZ_legal_xml_reÚcompilerT   r%   r«   r)   r3   rX   ÚcopyÚobjectr;   Zfixturer†   r   rŸ   r£   r¤   rQ   r    r   r   r   r   Ú<module>
   sV   	

 ;)