
    Vh                        d 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mZ ddlmZmZ ddlmZmZ ddlmZ dd	lmZ dd
lmZ  ej2                  d       G d d             ZddZddZddZy)zTimeout management for tests.    )annotationsN   )read_json_file)CommonConfig
TestConfig)displayTimeoutExpiredError)WrappedThread)TIMEOUT_PATH)TestTimeoutT)frozenc                  h    e Zd ZU dZdZded<   ded<   edd       ZddZe	dd	       Z
e	dd
       Zy)TimeoutDetailz8Details required to enforce a timeout on test execution.z%Y-%m-%dT%H:%M:%SZzdatetime.datetimedeadlineint | floatdurationc                    | j                   t        j                  j                  t        j                  j                        j                  d      z
  S )ztThe amount of time remaining before the timeout occurs. If the timeout has passed, this will be a negative duration.)tzr   microsecond)r   datetimenowtimezoneutcreplaceselfs    N/home/dcms/DCMS/lib/python3.12/site-packages/ansible_test/_internal/timeout.py	remainingzTimeoutDetail.remaining0   sB     }}x00448I8I8M8M4NVVcdVeee    c                v    t        | j                  j                  | j                        | j                        S )zGReturn timeout details as a dictionary suitable for JSON serialization.r   r   )dictr   strftime_DEADLINE_FORMATr   r   s    r   to_dictzTimeoutDetail.to_dict5   s.    ]]++D,A,AB]]
 	
r    c                    t        t        j                  j                  | d   t         j                        j	                  t        j
                  j                        | d         S )zOReturn a TimeoutDetail instance using the value previously returned by to_dict.r   )tzinfor   r"   )r   r   strptimer%   r   r   r   )values    r   	from_dictzTimeoutDetail.from_dict<   sh     &&//j0A=CaCabjjrz  sD  sD  sH  sHj  I:&
 	
r    c           	     $   | sy| t        |       k(  rt        |       } t        t        j                  j                  t        j                  j
                        j                  d      t        j                  t        | dz              z   |       S )zmReturn a new TimeoutDetail instance for the specified duration (in minutes), or None if the duration is zero.Nr   r   <   )secondsr"   )intr   r   r   r   r   r   	timedelta)r   s    r   createzTimeoutDetail.createD   s     s8}$8}H&&**8+<+<+@+@AIIVWIX[c[m[mvy  {C  FH  {H  wI  \J  J
 	
r    N)returnzdatetime.timedelta)r2   dict[str, t.Any])r*   r3   r2   r   )r   r   r2   TimeoutDetail | None)__name__
__module____qualname____doc__r%   __annotations__propertyr   r&   staticmethodr+   r1    r    r   r   r   '   sX    B+f f
 
 
 
 
r    r   c                 f    	 t         j                  t        t                    S # t        $ r Y yw xY w)zNReturn details about the currently set timeout, if any, otherwise return None.N)r   r+   r   r   FileNotFoundErrorr<   r    r   get_timeoutr?   S   s/    &&~l'CDD s   !$ 	00c                <    t        | t              rt        |        yy)zConfigure the timeout.N)
isinstancer   configure_test_timeout)argss    r   configure_timeoutrD   [   s    $
#t$ $r    c           	     `    t               syj                  }t        j                        |t	        j
                         k  r=j                          t        dj                   d|dz   dj                   d      t        j                  dj                   d| dj                   dd	
       d fd}dd}t        j                  t        j                  |       t        t        j                  ||j!                                     }d|_        |j%                          y)zConfigure the test timeout.NzThe z minute test timeout expired z ago at .z  minute test timeout expires in z at r   )	verbosityc                X    j                         t        dj                   d      )zRuns when SIGUSR1 is received.z"Tests aborted after exceeding the z minute time limit.)writer	   r   )_dummy1_dummy2rC   test_timeouttimeouts     r   timeout_handlerz/configure_test_timeout.<locals>.timeout_handlers   s.    4 !$FwGWGWFXXk"lmmr    c                    t        j                  |        t        j                  t        j                         t
        j                         y)zMBackground thread which will kill the current process if the timeout elapses.N)timesleeposkillgetpidsignalSIGUSR1)timeout_secondss    r   timeout_waiterz.configure_test_timeout.<locals>.timeout_waitery   s&    

?#
		V^^,r    T)rK   t.AnyrL   rZ   r2   None)rX   floatr2   r[   )r?   r   r   r   r   r0   rJ   r	   r   r   inforV   rW   r
   	functoolspartialtotal_secondsdaemonstart)rC   timeout_remainingrO   rY   instancerM   rN   s   `    @@r   rB   rB   a   s.   mG))w//0LH..004 !D)9)9(::WXilnXnWoowx  yI  yI  xJ  JK  #L  M  	MLL4(())IJ[I\\`ahaqaq`rrst  AB  Cn-
 MM&../2Y..~?P?^?^?`abHHONNr    )r2   r4   )rC   r   r2   r[   )rC   r   r2   r[   )r8   
__future__r   dataclassesr   r^   rS   rV   rQ   typingtior   configr   r   utilr   r	   threadr
   	constantsr   testr   	dataclassr   r?   rD   rB   r<   r    r   <module>rp      st    # "    	   


 d#(
 (
 $(
V%!r    