o
    SiS                     @   s(  d Z ddlZddlZddlZddlZddlZddlZddlmZ ddl	Z	ddl
mZ ddlmZ eeddh d Zdd	 eD Zd
ddddddZee edZdd Zdd Zdd Zd'ddZejZdedefddZG dd  d ZG d!d" d"ZG d#d$ d$ej Z!G d%d& d&e	j"Z#dS )(zGA Python test reporter that generates test reports in JUnit XML format.    N)Any)saxutils)_pretty_print_reporter    >   	   
      c                 C   s   i | ]}t |d |dqS )z\x02x)chr).0i r   M/home/ubuntu/.local/lib/python3.10/site-packages/absl/testing/xml_reporter.py
<dictcomp>!   s    r   z&quot;z&apos;z&#xA;z&#x9;z&#xD;z&#x20;)"'
	 z^(\w+) \((\S+)\)$c                 C   s   t | tS )zEscapes xml attributes.)r   escape_escape_xml_attr_conversions)contentr   r   r   _escape_xml_attr9   s   r   c                 C   s*   t  D ]
\}}| ||} q| ddS )a  Escapes a string to be used as XML CDATA.

  CDATA characters are treated strictly as character data, not as XML markup,
  but there are still certain restrictions on them.

  Args:
    s: the string to be escaped.
  Returns:
    An escaped version of the input string.
  z]]>z]] >)_control_character_conversionsitemsreplace)scharescapedr   r   r   _escape_cdata?   s   r    c                 C   s,   | du s| dk r
dS t j j| t jjd S )zProduces an ISO8601 datetime.

  Args:
    timestamp: an Epoch based timestamp in seconds.

  Returns:
    A iso8601 format timestamp if the input is a valid timestamp, None otherwise
  Nr   )tz)datetimefromtimestamptimezoneutc	isoformat)	timestampr   r   r   _iso8601_timestampO   s   	r(    c                 C   sh   | d|| f  |D ]!}t|dkr,|d dur,|d dur,| d|d |d f  q| d dS )a+  Prints an XML header of an arbitrary element.

  Args:
    element: element name (testsuites, testsuite, testcase)
    attributes: 2-tuple list with (attributes, values) already escaped
    stream: output stream to write test report XML to
    indentation: indentation added to the element header
  z%s<%s   r   N   z %s="%s"z>
)writelen)element
attributesstreamindentation	attributer   r   r   _print_xml_element_header^   s   	r3   objreturnc                 C   s6   zt | W S  ty   dt| jt| jf  Y S w )z-Returns a string representation of an object.z<unprintable %s.%s object>)str	Exceptiontype
__module____name__)r4   r   r   r   	_safe_strs   s   

r;   c                   @   s8   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d ZdS )_TestCaseResultaj  Private helper for _TextAndXMLTestResult that represents a test result.

  Attributes:
    test: A TestCase instance of an individual test method.
    name: The name of the individual test method.
    full_class_name: The full name of the test class.
    run_time: The duration (in seconds) it took to run the test.
    start_time: Epoch relative timestamp of when test started (in seconds)
    errors: A list of error 4-tuples. Error tuple entries are
        1) a string identifier of either "failure" or "error"
        2) an exception_type
        3) an exception_message
        4) a string version of a sys.exc_info()-style tuple of values
           ('error', err[0], err[1], self._exc_info_to_string(err))
           If the length of errors is 0, then the test is either passed or
           skipped.
    skip_reason: A string explaining why the test was skipped.
  c                 C   s   d| _ d| _d | _g | _|| _| pt|}t|}|r)|	d}|	d}n@t
j|j}t|t
jjr?t
j|jj}||d rS|t|d d  }|}n|dd}|d }t|dkrg|d nd}t|| _t|| _d S )Nr+   r*   .r   r)   )run_time
start_timeskip_reasonerrorstestidr6   &_CLASS_OR_MODULE_LEVEL_TEST_DESC_REGEXmatchgroupunittestutilstrclass	__class__
isinstancecase_SubTest	test_case
startswithr-   rsplitr   namefull_class_name)selfrC   	test_descrF   rR   rS   
class_namepartsr   r   r   __init__   s*   


z_TestCaseResult.__init__c                 C   
   || _ d S N)r?   rT   time_in_secsr   r   r   set_run_time      
z_TestCaseResult.set_run_timec                 C   rY   rZ   r@   r[   r   r   r   set_start_time   r^   z_TestCaseResult.set_start_timec                 C   s   | j du r
d}d}nd}d}dd| j fdd| fd	d| fd
d| j fd| jfdt| jfg}td||d | | |d dS )aQ  Prints an XML Summary of a TestCase.

    Status and result are populated as per JUnit XML test result reporter.
    A test that has been skipped will always have a skip reason,
    as every skip method in Python's unittest requires the reason arg to be
    passed.

    Args:
      stream: output stream to write test report XML to
    Nrun	completednotrun
suppressedrR   %sstatusresulttime%.3f	classnamer'   testcasez  z  </testcase>
)	rA   rR   r?   rS   r(   r@   r3   _print_testcase_detailsr,   )rT   r0   rf   rg   test_case_attributesr   r   r   print_xml_summary   s   



z!_TestCaseResult.print_xml_summaryc              	   C   sT   | j D ]$}|\}}}}tt|}tt|}t|}|d|||||f  qd S )Nz1  <%s message="%s" type="%s"><![CDATA[%s]]></%s>
)rB   r   r;   r6   r    r,   )rT   r0   erroroutcomeexception_typemessage	error_msgr   r   r   rl      s   
z'_TestCaseResult._print_testcase_detailsN)	r:   r9   __qualname____doc__rX   r]   r`   rn   rl   r   r   r   r   r<   ~   s    %r<   c                   @   s@   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dS )_TestSuiteResultz)Private helper for _TextAndXMLTestResult.c                 C   s(   i | _ i | _i | _d| _d| _i | _d S )Nr=   )suitesfailure_countserror_countsoverall_start_timeoverall_end_time_testsuites_propertiesrT   r   r   r   rX      s   
z_TestSuiteResult.__init__c                 C   s   t |jj}|dkr|jdd }t|jtjjr!t |jj	j}| 
| | j| | |jD ]&}|d dkrE| j|  d7  <  d S |d dkrW| j|  d7  <  d S q1d S )N_ErrorHolderr>   r=   r   failurer+   ro   )r8   rC   r:   rS   rQ   rL   rH   rM   rN   rO   _setup_test_suiterw   appendrB   rx   ry   )rT   test_case_result
suite_namero   r   r   r   add_test_case_result   s    

z%_TestSuiteResult.add_test_case_resultc              	   C   s  t dd | j D }t | j }t | j }ddd| fdd| fdd| fdd	| j| j  fd
t| jfg}td|| | j	ri|
d t| j	 D ]\}}|
dt|tt|f  qP|
d | jD ]b}| j| }	tdd |	D }
tdd |	D }| j| }| j| }dd| fddt|	 fdd| fdd| fdd	|
|  fd
t|fg}td|| t|	dd dD ]}|| q|
d ql|
d d S )Nc                 s   s    | ]}t |V  qd S rZ   )r-   r   xr   r   r   	<genexpr>	  s    z5_TestSuiteResult.print_xml_summary.<locals>.<genexpr>)rR   r)   testsz%dfailuresrB   rh   ri   r'   
testsuitesz    <properties>
z1      <property name="%s" value="%s"></property>
z    </properties>
c                 s   s    | ]	}|j |j V  qd S rZ   )r@   r?   r   r   r   r   r     s    c                 s   s    | ]}|j V  qd S rZ   r_   r   r   r   r   r     s    rR   re   	testsuitec                 S   s   | j S rZ   )rR   )tr   r   r   <lambda>.  s    z4_TestSuiteResult.print_xml_summary.<locals>.<lambda>)keyz</testsuite>
z</testsuites>
)sumrw   valuesrx   ry   r{   rz   r(   r3   r|   r,   sortedr   r   r6   maxminr-   rn   )rT   r0   overall_test_countoverall_failuresoverall_errorsoverall_attributesrR   valuer   suitesuite_end_timesuite_start_timer   rB   suite_attributesr   r   r   r   rn     sH   












z"_TestSuiteResult.print_xml_summaryc                 C   s0   || j v rdS g | j |< d| j|< d| j|< dS )zAdds a test suite to the set of suites tracked by this test run.

    Args:
      suite_name: string, The name of the test suite being initialized.
    Nr   )rw   rx   ry   )rT   r   r   r   r   r   3  s
   


z"_TestSuiteResult._setup_test_suitec                 C   
   || _ dS )zvSets the start timestamp of this test suite.

    Args:
      timestamp_in_secs: timestamp in seconds since epoch
    N)r{   rT   timestamp_in_secsr   r   r   set_end_time?     
z_TestSuiteResult.set_end_timec                 C   r   )ztSets the end timestamp of this test suite.

    Args:
      timestamp_in_secs: timestamp in seconds since epoch
    N)rz   r   r   r   r   r`   G  r   z_TestSuiteResult.set_start_timeN)
r:   r9   rt   ru   rX   r   rn   r   r   r`   r   r   r   r   rv      s    +rv   c                       s   e Zd ZdZeZeZedf fdd	Z	 fddZ
 fddZ fd	d
Zdd Zd% fdd	Z		d&ddZdd Zdd Z fddZ fddZ fddZ fddZ fddZ fdd Z fd!d"Z fd#d$Z  ZS )'_TextAndXMLTestResultzoPrivate TestResult class that produces both formatted text results and XML.

  Used by TextAndXMLTestRunner.
  Nc                    sF   t  ||| || _i | _|  | _|r|| j_|| _t	 | _
d S rZ   )superrX   
xml_streampending_test_case_results_TEST_SUITE_RESULT_CLASSr   r|   time_getter	threadingRLock_pending_test_case_results_lock)rT   r   r0   descriptions	verbosityr   testsuites_propertiesrK   r   r   rX   Y  s   
z_TextAndXMLTestResult.__init__c                    s   |   | _t | d S rZ   )r   r@   r   	startTestrT   rC   r   r   r   r   f  s   
z_TextAndXMLTestResult.startTestc                    s   | j \ t | | |}|s*| pt|}tjd|  	 W d    d S t	| dd d u r7| 
 | _t|}| 
 | j }|| || j | j| | j|= W d    d S 1 sbw   Y  d S )NzNo pending test case: %s
r@   )r   r   stopTestget_pending_test_case_resultrD   r6   sysstderrr,   getattrr   r@   r]   r`   r   r   r   )rT   rC   rg   	test_nametest_idr?   r   r   r   r   j  s"   



"z_TextAndXMLTestResult.stopTestc                    s   | j |   t   d S rZ   )r   r`   r   r   startTestRunr}   r   r   r   r   }  s   z"_TextAndXMLTestResult.startTestRunc                 C   s   | j |   | j9 | jD ]'}| j| }t| dd d ur0| j j| j }|| |	| j | j 
| q| j  W d    d S 1 sGw   Y  d S )Nr@   )r   r   r   r   r   r   r{   r@   r]   r`   r   clear)rT   r   rg   r?   r   r   r   stopTestRun  s   


"z!_TextAndXMLTestResult.stopTestRunc                    s"   |r	t  ||S dtj| S )aW  Converts a sys.exc_info()-style tuple of values into a string.

    This method must be overridden because the method signature in
    unittest.TestResult changed between Python 2.2 and 2.4.

    Args:
      err: A sys.exc_info() tuple of values for an error.
      test: The test method.

    Returns:
      A formatted exception string.
    r)   )r   _exc_info_to_stringjoin	tracebackformat_exception)rT   errrC   r   r   r   r     s   z)_TextAndXMLTestResult._exc_info_to_stringc                 C   s   | j 5 t|}|| jvr| || j|< |r | j| j| |r0|| j| _W d   dS W d   dS 1 s;w   Y  dS )a  Adds result information to a test case result which may still be running.

    If a result entry for the test already exists, add_pending_test_case_result
    will add error summary tuples and/or overwrite skip_reason for the result.
    If it does not yet exist, a result entry will be created.
    Note that a test result is considered to have been run and passed
    only if there are no errors or skip_reason.

    Args:
      test: A test method as defined by unittest
      error_summary: A 4-tuple with the following entries:
          1) a string identifier of either "failure" or "error"
          2) an exception_type
          3) an exception_message
          4) a string version of a sys.exc_info()-style tuple of values
             ('error', err[0], err[1], self._exc_info_to_string(err))
             If the length of errors is 0, then the test is either passed or
             skipped.
      skip_reason: a string explaining why the test was skipped
    N)r   rD   r   _TEST_CASE_RESULT_CLASSrB   r   rA   )rT   rC   error_summaryrA   r   r   r   r   add_pending_test_case_result  s   

"z2_TextAndXMLTestResult.add_pending_test_case_resultc                 C   s<   | j  t|}| j|= W d    d S 1 sw   Y  d S rZ   )r   rD   r   rT   rC   r   r   r   r   delete_pending_test_case_result  s   
"z5_TextAndXMLTestResult.delete_pending_test_case_resultc                 C   s   t |}| j|d S rZ   )rD   r   getr   r   r   r   r     s   z2_TextAndXMLTestResult.get_pending_test_case_resultc                    s   t  | | | d S rZ   )r   
addSuccessr   r   r   r   r   r     s   z _TextAndXMLTestResult.addSuccessc                    >   t  || d|d |d | j||df}| j||d d S )Nro   r   r+   rC   r   )r   addErrorr   r   rT   rC   r   r   r   r   r   r     
   z_TextAndXMLTestResult.addErrorc                    r   )Nr   r   r+   r   r   )r   
addFailurer   r   r   r   r   r   r     r   z _TextAndXMLTestResult.addFailurec                    s    t  || | j||d d S )N)rA   )r   addSkipr   )rT   rC   reasonr   r   r   r     s   z_TextAndXMLTestResult.addSkipc                    sB   t  || tt|dd r|d| j||d | | d S )NrecordPropertyEXPECTED_FAILUREr   )r   addExpectedFailurecallabler   r   r   r   )rT   rC   r   r   r   r   r     s   z(_TextAndXMLTestResult.addExpectedFailurec                    s>   t  | | pt|}dddd| f}| j||d d S )Nro   r)   z,Test case %s should have failed, but passed.r   )r   addUnexpectedSuccessrD   r6   r   )rT   rC   r   r   r   r   r   r     s   z*_TextAndXMLTestResult.addUnexpectedSuccessc                    s~   t  ||| |d ur4t|d |jr$d|d |d | j||df}nd|d |d | j||df}nd }| j||d d S )Nr   r   r+   r   ro   r   )r   
addSubTest
issubclassfailureExceptionr   r   )rT   rC   subtestr   r   r   r   r   r     s   z _TextAndXMLTestResult.addSubTestc                    s(   t    | jd | j| j d S )Nz<?xml version="1.0"?>
)r   printErrorsr   r,   r   rn   r}   r   r   r   r      s   
z!_TextAndXMLTestResult.printErrorsrZ   )NN)r:   r9   rt   ru   rv   r   r<   r   
_time_copyrX   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   __classcell__r   r   r   r   r   P  s0    
 r   c                       sd   e Zd ZU dZeZdZi Zee	e	f e
d< d fdd	Zedd Z fdd	Zed
d Z  ZS )TextAndXMLTestRunnerzA test runner that produces both formatted text results and XML.

  It prints out the names of tests as they are run, errors as they
  occur, and a summary of the results at the end of the test run.
  Nr|   c                    s(   t  j|i | |dur|| _dS dS )a  Initialize a TextAndXMLTestRunner.

    Args:
      xml_stream: file-like or None; XML-formatted test results are output
          via this object's write() method.  If None (the default), the
          new instance behaves as described in the set_default_xml_stream method
          documentation below.
      *args: passed unmodified to unittest.TextTestRunner.__init__.
      **kwargs: passed unmodified to unittest.TextTestRunner.__init__.
    N)r   rX   _xml_stream)rT   r   argskwargsr   r   r   rX     s   
zTextAndXMLTestRunner.__init__c                 C   r   )a  Sets the default XML stream for the class.

    Args:
      xml_stream: file-like or None; used for instances when xml_stream is None
          or not passed to their constructors.  If None is passed, instances
          created with xml_stream=None will act as ordinary TextTestRunner
          instances; this is the default state before any calls to this method
          have been made.
    N)r   )clsr   r   r   r   set_default_xml_stream#  s   
z+TextAndXMLTestRunner.set_default_xml_streamc                    s2   | j d u r
t  S | j| j | j| j| j| jdS )N)r   )r   r   _makeResult_TEST_RESULT_CLASSr0   r   r   r|   r}   r   r   r   r   0  s   

z TextAndXMLTestRunner._makeResultc                 C   s   || j |< d S rZ   )r|   )r   r   r   r   r   r   set_testsuites_property8  s   z,TextAndXMLTestRunner.set_testsuites_propertyrZ   )r:   r9   rt   ru   r   r   r   r|   dictr   __annotations__rX   classmethodr   r   r   r   r   r   r   r   r     s   
 
r   )r)   )$ru   r"   rer   r   rh   r   typingr   rH   xml.saxr   absl.testingr   setrange_bad_control_character_codesr   r   updatecompilerE   r   r    r(   r3   r   objectr6   r;   r<   rv   TextTestResultr   TextTestRunnerr   r   r   r   r   <module>   sF   


hj 7