U
    f»{j‰J  ã                   @   sè  d Z ddlZddlZddlZddlZddlZddlZddlZddlm	Z	 ddl
Z
dZe
je ƒ Ze
je ƒ ZdZeedƒZer„dZndZd	 ¡ Zd
 ¡ Zd ¡ Zd ¡ Zd ¡ Zdddhae	dddddgƒZe
jdd„ ƒZG dd„ dƒZdd„ Ze
jdd„ ƒZ e
jdd�d d!„ ƒZ!e
jdd�d"d#„ ƒZ"e
jdd$�d%d&„ ƒZ#e
jdd$�d'd(„ ƒZ$e
jd)d*„ ƒZ%dGd+d,„Z&d-a'e
jdd.�d/d0„ ƒZ(e
jdd.�d1d2„ ƒZ)d3d4„ Z*dHd5d6„Z+d7d8„ Z,d9d:„ Z-d;d<„ Z.d=d>„ Z/d?d@„ Z0dAdB„ Z1dCdD„ Z2dEdF„ Z3dS )Ia!  Timeout for tests to stop hanging testruns.

This plugin will dump the stack and terminate the test.  This can be
useful when running tests on a continuous integration server.

If the platform supports SIGALRM this is used to raise an exception in
the test, otherwise os._exit(1) is used.
é    N)Ú
namedtuple)Úis_debuggingÚSettingsz#Timeout (>%ss) from pytest-timeout.ÚSIGALRMÚsignalÚthreadzU
Timeout in seconds before dumping the stacks.  Default is 0 which
means no timeout.
z²
Timeout mechanism to use.  'signal' uses SIGALRM, 'thread' uses a timer
thread.  If unspecified 'signal' is used on platforms which support
SIGALRM, otherwise 'thread' is used.
z›
When set to True, defers the timeout evaluation to only the test
function body, ignoring the time it takes when evaluating any fixtures
used in the test.
zv
When specified, disables debugger detection. breakpoint(), pdb.set_trace(), etc.
will be interrupted by the timeout.
zž
Timeout in seconds for entire session.  Default is None which
means no timeout. Timeout is checked between tests, and will not interrupt a test
in progress.
ZpydevdZbdbZpydevd_frame_evaluatorr   ÚtimeoutÚmethodÚ	func_onlyÚdisable_debugger_detectionc              	   C   sÀ   |   dd¡}|jdttd� |jddddgd	d
� |jdddddgtd� |jdddtd� |jddddtdtd� |  dt¡ |  dt¡ | jdtddd� | jdtddd� |  dt¡ dS )z*Add options to control the timeout plugin.r   zHInterrupt test run and dump stacks of all threads after a test times outz	--timeout)ÚtypeÚhelpz--timeout_methodÚstorer   r   z Deprecated, use --timeout-method)ÚactionÚchoicesr   z--timeout-methodÚtimeout_method)Údestr   r   r   z$--timeout-disable-debugger-detectionÚ"timeout_disable_debugger_detectionÚ
store_true)r   r   r   z--session-timeoutÚsession_timeoutNZSECONDS)r   r   Údefaultr   Úmetavarr   Útimeout_func_onlyÚboolF)r   r   )	ZgetgroupZ	addoptionÚfloatÚTIMEOUT_DESCÚMETHOD_DESCÚDISABLE_DEBUGGER_DETECTION_DESCÚSESSION_TIMEOUT_DESCZaddiniÚFUNC_ONLY_DESC)ÚparserÚgroup© r"   úM/var/www/html/bwave/python/venv/lib/python3.8/site-packages/pytest_timeout.pyÚpytest_addoption?   sV    þüûüù	ür$   c                   @   s8   e Zd ZdZejdd�dd„ ƒZejdd�dd„ ƒZdS )	ÚTimeoutHookszTimeout specific hooks.T)Zfirstresultc                 C   s   dS )z²Called at timeout setup.

        'item' is a pytest node to setup timeout for.

        Can be overridden by plugins for alternative timeout implementation strategies.

        Nr"   ©ÚitemÚsettingsr"   r"   r#   Úpytest_timeout_set_timerr   s    z%TimeoutHooks.pytest_timeout_set_timerc                 C   s   dS )zÁCalled at timeout teardown.

        'item' is a pytest node which was used for timeout setup.

        Can be overridden by plugins for alternative timeout implementation strategies.

        Nr"   ©r'   r"   r"   r#   Úpytest_timeout_cancel_timer|   s    z(TimeoutHooks.pytest_timeout_cancel_timerN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚpytestZhookspecr)   r+   r"   r"   r"   r#   r%   o   s
   

	
r%   c                 C   s   |   t¡ dS )z Register timeout-specific hooks.N)Zadd_hookspecsr%   )Úpluginmanagerr"   r"   r#   Úpytest_addhooks‡   s    r2   c                 C   sš   |   dd¡ t| ƒ}|j| _|j| _|j| _|j| _	|  
d¡}|dkrd|  d¡}|rdt|  d¡dƒ}|dk	rzt ¡ | }nd}d}|| jt< || jt< dS )z7Register the marker so it shows up in --markers output.Úmarkersaw  timeout(timeout, method=None, func_only=False, disable_debugger_detection=False): Set a timeout, timeout method and func_only evaluation on just one test item.  The first argument, *timeout*, is the timeout in seconds while the keyword, *method*, takes the same values as the --timeout-method option. The *func_only* keyword, when set to True, defers the timeout evaluation to only the test function body, ignoring the time it takes when evaluating any fixtures used in the test. The *disable_debugger_detection* keyword, when set to True, disables debugger detection, allowing breakpoint(), pdb.set_trace(), etc. to be interruptedr   Núconfig filer   )Zaddinivalue_lineÚget_env_settingsr   Ú_env_timeoutr	   Ú_env_timeout_methodr
   Ú_env_timeout_func_onlyr   Ú'_env_timeout_disable_debugger_detectionÚ	getoptionÚgetiniÚ_validate_timeoutÚtimeÚstashÚSESSION_TIMEOUT_KEYÚSESSION_EXPIRE_KEY)Úconfigr(   r   ÚiniÚexpire_timer"   r"   r#   Úpytest_configureŒ   s(    þ


rD   T)Zhookwrapperc                 c   s¢   | j jj}t| ƒ}|jdk	o$|jdk}|rB|jdkrB|j| |d� dV  |rb|jdkrb|j| d� | jj j	t
 }|rž|t ¡ k rž| jj j	t }d|› d�| j_dS )zÐHook in timeouts to the runtest protocol.

    If the timeout is set on the entire test, including setup and
    teardown, then this hook installs the timeout.  Otherwise
    pytest_runtest_call is used.
    Nr   Fr&   r*   zsession-timeout: z sec exceeded)rA   r1   ÚhookÚ_get_item_settingsr   r
   r)   r+   Úsessionr>   r@   r=   r?   Z
shouldfail)r'   Úhooksr(   Ú
is_timeoutrC   r   r"   r"   r#   Úpytest_runtest_protocol²   s    
rJ   c                 c   sf   | j jj}t| ƒ}|jdk	o$|jdk}|rB|jdkrB|j| |d� dV  |rb|jdkrb|j| d� dS )z¹Hook in timeouts to the test function call only.

    If the timeout is set on only the test function this hook installs
    the timeout, otherwise pytest_runtest_protocol is used.
    Nr   Tr&   r*   )rA   r1   rE   rF   r   r
   r)   r+   )r'   rH   r(   rI   r"   r"   r#   Úpytest_runtest_callÊ   s    
rK   )Ztryfirstc                 C   sL   g }| j r$| d| j | j| jf ¡ |  d¡}|r@| d| ¡ |rH|S dS )z$Add timeout config to pytest header.z5timeout: %ss
timeout method: %s
timeout func_only: %sr   zsession timeout: %ssN)r6   Úappendr7   r8   r:   )rA   Ztimeout_headerr   r"   r"   r#   Úpytest_report_headerÛ   s    ýÿÿ	
rM   c                 C   s   | j jj}|j| d� dS )z<Stop the timeout when pytest enters pdb in post-mortem mode.r*   N)rA   r1   rE   r+   )ÚnoderH   r"   r"   r#   Úpytest_exception_interactñ   s    
rO   c                   C   s   da dS )z“Stop the timeouts when we entered pdb.

    This stops timeouts from triggering when pytest's builting pdb
    support notices we entered pdb.
    TN)ÚSUPPRESS_TIMEOUTr"   r"   r"   r#   Úpytest_enter_pdbø   s    rQ   c                    sŽ   t rdS | dkrt ¡ } d}| r6t | ¡p4t | j¡}|rl|j d¡}tD ] ‰ t	‡ fdd„|D ƒƒrJ dS qJt
tdƒrŠtj tjj¡dkS dS )a(  Detect if a debugging session is in progress.

    This looks at both pytest's builtin pdb support as well as
    externally installed debuggers using some heuristics.

     This is done by checking if either of the following conditions is
     true:

     1. Examines the trace function to see if the module it originates
        from is in KNOWN_DEBUGGING_MODULES.
     2. Check is SUPPRESS_TIMEOUT is set to True.

    :param trace_func: the current trace function, if not given will use
        sys.gettrace(). Used to unit-test this function.
    TNÚ.c                 3   s   | ]}|  ˆ ¡V  qd S ©N)Ú
startswith)Ú.0Úpart©Únamer"   r#   Ú	<genexpr>#  s     zis_debugging.<locals>.<genexpr>Ú
monitoringF)rP   ÚsysÚgettraceÚinspectÚ	getmoduleÚ	__class__r,   ÚsplitÚKNOWN_DEBUGGING_MODULESÚanyÚhasattrrZ   Zget_toolZDEBUGGER_ID)Z
trace_funcZtrace_moduleÚpartsr"   rW   r#   r     s"    ÿ
r   F)Ztrylastc                    s°   ˆj }|dkr"t ¡ t ¡ k	r"d}|dkrf‡ ‡fdd„}dd„ }|ˆ _t tj|¡ t tjˆj	¡ nF|dkr¬t 
ˆj	tˆ ˆf¡‰dtˆ jf ˆ_‡fdd„}|ˆ _ˆ ¡  d	S )
z'Setup up a timeout trigger and handler.r   r   c                    s   d}t ˆ ˆƒ d S )NT)Útimeout_sigalrm)ÚsignumÚframeÚ__tracebackhide__r&   r"   r#   Úhandler;  s    z)pytest_timeout_set_timer.<locals>.handlerc                   S   s"   t  t jd¡ t   t jt j¡ d S )Nr   )r   Ú	setitimerÚITIMER_REALr   ÚSIG_DFLr"   r"   r"   r#   Úcancel?  s    z(pytest_timeout_set_timer.<locals>.cancelz%s %sc                      s   ˆ   ¡  ˆ  ¡  d S rS   )rm   Újoinr"   )Útimerr"   r#   rm   J  s    T)r	   Ú	threadingÚcurrent_threadÚmain_threadÚcancel_timeoutr   r   rj   rk   r   ÚTimerÚtimeout_timerr,   ZnodeidrX   Ústart)r'   r(   r   ri   rm   r"   )r'   r(   ro   r#   r)   /  s&    ÿþr)   c                 C   s   t | ddƒ}|r|ƒ  dS )z)Cancel the timeout trigger if it was set.rs   NT)Úgetattr)r'   rm   r"   r"   r#   r+   S  s    r+   c                 C   s¼   |   d¡}|dkr$ttj d¡dƒ}|dkrD|  d¡}|rDt|dƒ}|   d¡}|dkrn|  d¡}|rnt|dƒ}|dkrzt}|  d¡}|   d¡}|dkr®|  d¡}|r®t|dƒ}t	||||ƒS )	zpReturn the configured timeout settings.

    This looks up the settings in the environment and config file.
    r   NZPYTEST_TIMEOUTz#PYTEST_TIMEOUT environment variabler4   r   r   r   )
Úgetvaluer<   ÚosÚenvironÚgetr;   Ú_validate_methodÚDEFAULT_METHODÚ$_validate_disable_debugger_detectionr   )rA   r   rB   r	   r
   r   r"   r"   r#   r5   `  s6    

 ÿ







 ÿr5   c                 C   s´   d } } }}|s|   d¡}|dk	rft| j dd�ƒ}t|jdƒ}t|jdƒ}t|jdƒ}t|j	dƒ}|dkrv| j
j}|dkr†| j
j}|dkr–| j
j}|dkr¦| j
j}t||||ƒS )z%Return (timeout, method) for an item.Nr   rW   Úmarker)Zget_closest_markerÚ_parse_markerr<   r   r|   r	   Ú_validate_func_onlyr
   r~   r   rA   r6   r7   r8   r9   r   )r'   r   r   r	   r
   r   r(   r"   r"   r#   rF   „  s*    
 ÿrF   c                 C   s.  | j s| jstdƒ‚tƒ  } } }}| j ¡ D ]>\}}|dkrF|}q0|dkrT|}q0|dkrb|}q0td| ƒ‚q0t| j ƒdkr�||k	r�tdƒ‚nt| j ƒdkr¨| j d }t| j ƒd	krÈ||k	rÈtd
ƒ‚nt| j ƒd	krà| j d }t| j ƒd	krötdƒ‚||k�rd}||k�rd}||k�r d}t|||dƒS )z¡Return (timeout, method) tuple from marker.

    Either could be None.  The values are not interpreted, so
    could still be bogus and even the wrong type.
    z.Timeout marker must have at least one argumentr   r	   r
   z/Invalid keyword argument for timeout marker: %sé   z6Multiple values for timeout argument of timeout markerr   é   z5Multiple values for method argument of timeout markerz%Too many arguments for timeout markerN)ÚargsÚkwargsÚ	TypeErrorÚobjectÚitemsÚlenr   )r   r   r	   r
   ÚNOTSETÚkwÚvalr"   r"   r#   r€   œ  s8    






r€   c                 C   s@   | d krd S z
t | ƒW S  tk
r:   td| |f ƒ‚Y nX d S )NzInvalid timeout %s from %s)r   Ú
ValueError)r   Úwherer"   r"   r#   r<   Á  s    
r<   c                 C   s(   | d krd S | dkr$t d| |f ƒ‚| S )N)r   r   zInvalid method %s from %s)r�   )r	   rŽ   r"   r"   r#   r|   Ê  s
    r|   c                 C   s*   | d krd S t | tƒs&td| |f ƒ‚| S )Nz"Invalid func_only value %s from %s©Ú
isinstancer   r�   )r
   rŽ   r"   r"   r#   r�   Ò  s
    
r�   c                 C   s*   | d krd S t | tƒs&td| |f ƒ‚| S )Nz3Invalid disable_debugger_detection value %s from %sr�   )r   rŽ   r"   r"   r#   r~   Ú  s    
ÿÿr~   c                 C   sr   |j stƒ rdS d}tt ¡ ƒ}| j ¡ }|dkr@|jddd� t|ƒ |dkr^|jddd� t	 
t|j ¡ dS )zÈDump stack of threads and raise an exception.

    This will output the stacks of any threads other then the
    current to stderr and then raise an AssertionError, thus
    terminating the test.
    NTr‚   ú+ÚTimeout©Útitle)r   r   r‰   rp   Ú	enumeraterA   Úget_terminal_writerÚsepÚdump_stacksr0   ZfailÚPYTEST_FAILURE_MESSAGEr   )r'   r(   rh   ZnthreadsÚterminalr"   r"   r#   re   å  s    
re   c              	   C   sB  |j stƒ rdS | j ¡ }zúzÖ| jj
 d¡}|rH| | ¡ | ¡ \}}nd\}}|jddd� | jj
 d¡}|r¢t| d	ƒr¢| jj ¡ }|r¢|jd
dd� | |¡ |r¾|jd
dd� | |¡ |rÚ|jd
dd� | |¡ t|ƒ |jddd� W n tk
�r   t ¡  Y nX W 5 | ¡  tj ¡  tj ¡  t 	d¡ X dS )z¬Dump stack of threads and call os._exit().

    This disables the capturemanager and dumps stdout and stderr.
    Then the stacks are dumped and os._exit(1) is called.
    Nr‚   Zcapturemanager)NNr‘   r’   r“   Z_capturelogÚcapturelog_handlerú~zCaptured logzCaptured stdoutzCaptured stderr)r   r   rA   r–   Úflushr[   ÚstdoutÚstderrry   Ú_exitr1   Z	getpluginZsuspend_global_captureZread_global_capturer—   rc   r›   Ústreamrx   Úwriter˜   Ú	ExceptionÚ	tracebackÚ	print_exc)r'   r(   rš   Zcapmanrž   rŸ   ZcaplogÚlogr"   r"   r#   ru   ù  s<    






ru   c                 C   s€   t  ¡ j}t ¡  ¡ D ]d\}}||kr(qt  ¡ D ]}|j|kr0|j} qNq0d}| jdd||f d� |  	d 
t |¡¡¡ qdS )z9Dump the stacks of all threads except the current thread.z	<unknown>rœ   zStack of %s (%s)r“   Ú N)rp   rq   Úidentr[   Ú_current_framesrˆ   r•   rX   r—   r¢   rn   r¤   Úformat_stack)rš   Zcurrent_identZthread_identrg   ÚtZthread_namer"   r"   r#   r˜   !  s    

r˜   )N)N)4r/   r]   ry   r   r[   rp   r=   r¤   Úcollectionsr   r0   Ú__all__ZStashKeyr   r?   r@   r™   rc   ZHAVE_SIGALRMr}   Ústripr   r   r   r   r   ra   r   Zhookimplr$   r%   r2   rD   rJ   rK   rM   rO   rQ   r   rP   r)   r+   r5   rF   r€   r<   r|   r�   r~   re   ru   r˜   r"   r"   r"   r#   Ú<module>   sv   

 
ÿ
/
%









&

#

$
%	(