
    Vhp8                     l   d Z ddlZddlmZmZmZmZmZmZm	Z	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mZ dd	lmZ dd
lmZ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&m'Z' ddl(m)Z)m*Z*m+Z+m,Z, ddl-m.Z. ddl/m0Z0 ddl1m2Z2m3Z3 ddl4m5Z5 ddl6m7Z7m8Z8m9Z9  ed       G d de:             Z; G d de      Z< G d de      Z= e
d       Z>ee=gee>   f   Z? G d! d"e!      Z@ G d# d$e!      ZA ee       G d% d&             ZB ee       G d' d(             ZC G d) d*e:      ZD G d+ d,e      ZEy)-z:
This module implements the worker classes.

@since: 12.3
    N)Any	AwaitableCallableDictListOptionalTextIOTypeVar)TestCase)implementer)frozen)Protocol	TypedDict)DeferredDeferredList)ProcessDone)IAddress
ITransport)ProcessProtocol)Logger)AMP)Failure)FilePath)namedObject)_WORKER_AMP_STDIN_WORKER_AMP_STDOUTmanagercommandsworkercommands)WorkerReporter)
TestResult)
TestLoader
TrialSuite)Todo   )
StreamOpenStreamReceiverStreamWriteF)auto_excc                       e Zd ZU dZeed<   y)WorkerExceptionz
    An exception was reported by a test running in a worker process.

    @ivar message: An error message describing the exception.
    messageN)__name__
__module____qualname____doc__str__annotations__     J/home/dcms/DCMS/lib/python3.12/site-packages/twisted/trial/_dist/worker.pyr*   r*   +   s     Lr3   r*   c                       e Zd ZU dZeed<   y)	RunResultzB
    Represent the result of a L{workercommands.Run} command.
    successN)r,   r-   r.   r/   boolr1   r2   r3   r4   r6   r6   6   s     Mr3   r6   c                   $    e Zd ZdZdededefdZy)Workerz)
    An object that can run actions.
    caseresultreturnc                    K   yw)z"
        Run a test case.
        Nr2   )selfr;   r<   s      r4   runz
Worker.runC   s     s   N)r,   r-   r.   r/   r   r    r6   r@   r2   r3   r4   r:   r:   >   s!    h 
 y r3   r:   _Tc                       e Zd ZdZ e       ZddZej                  j                  de
defd       Zej                  j                  d        Zy)	WorkerProtocolz5
    The worker-side trial distributed protocol.
    c                 P    t               | _        t        |       | _        || _        y N)r!   _loaderr   _result_forceGarbageCollection)r?   forceGarbageCollections     r4   __init__zWorkerProtocol.__init__T   s    !|%d+'=$r3   testCaser=   c                 4  K   | j                   j                         5 }| j                  j                  |      }t	        |g| j
                        }|j                  | j                          ddd       d}t        d       d{   D ]M  \  }}|r	d}| j                  j                  d||       	 | j                   j                  ||       d{    O d|iS # 1 sw Y   txY w7 d7 # t        $ r | j                  j                  d       Y w xY ww)	z*
        Run a test case by name.
        NT)consumeErrorsFz Result reporting for {id} failed)failureidz5Additionally, reporting the reporting failure failed.r7   )rG   gatherReportingResultsrF   
loadByNamer"   rH   r@   r   loggerrN   addErrorFallibleBaseException)r?   rK   resultsr;   suiteallSucceededr7   r<   s           r4   r@   zWorkerProtocol.runY   s#    
 \\002 	$g<<**84Dvt'C'CDEIIdll#	$
 %1'%NN 	OGV !L KK2	   ll33  '	@ <((M	$ 	$  O&
 !  ##K	s_   DAC+DC*-D4C.C,C.DC'#D,C..$DDDDc                 4    t        j                  |       ddiS )zb
        Set up the worker, moving into given directory for tests to run in
        them.
        r7   T)oschdir)r?   	directorys     r4   startzWorkerProtocol.start   s     	4  r3   N)F)r,   r-   r.   r/   r   rR   rJ   r   Run	responderr0   r6   r@   Startr\   r2   r3   r4   rC   rC   M   sd     XF>
 !!*)# *)) *) "*)X ##! $!r3   rC   c                       e Zd ZdZd fd	Zej                  d        Zej                  d        Z	e
j                  j                  d        Zdededee   d	efd
Ze
j$                  j                  dedededed	eeef   f
d       Ze
j.                  j                  dedededed	eeef   f
d       Ze
j2                  j                  d        Ze
j6                  j                  dededee   d	eeef   fd       Ze
j<                  j                  d        Ze
j@                  j                  d        Z!de"de#d	e$fdZ%d Z& xZ'S )LocalWorkerAMPz7
    Local implementation of the manager commands.
    c                 D    t         |   ||       t               | _        y rE   )superrJ   r&   _streams)r?   boxReceiverlocator	__class__s      r4   rJ   zLocalWorkerAMP.__init__   s    g.&(r3   c                 :    d| j                   j                         iS )NstreamId)rd   openr?   s    r4   
streamOpenzLocalWorkerAMP.streamOpen   s    DMM..011r3   c                 >    | j                   j                  ||       i S rE   )rd   write)r?   ri   datas      r4   streamWritezLocalWorkerAMP.streamWrite   s    Hd+	r3   c                 T    | j                   j                  | j                         ddiS )z0
        Add a success to the reporter.
        r7   T)rG   
addSuccess	_testCase)r?   testNames     r4   rr   zLocalWorkerAMP.addSuccess   s%    
 	/4  r3   error
errorClassframesr=   c           
          t        |      }t        ||      }t        dt        |      d      D ]:  }|j                  j                  ||   ||dz      t        ||dz            g g f       < |S )a  
        Helper to build a C{Failure} with some traceback.

        @param error: An C{Exception} instance.

        @param errorClass: The class name of the C{error} class.

        @param frames: A flat list of strings representing the information need
            to approximatively rebuild C{Failure} frames.

        @return: A L{Failure} instance with enough information about a test
           error.
        r      r$      )r   r   rangelenrw   appendint)r?   ru   rv   rw   	errorTyperN   is          r4   _buildFailurezLocalWorkerAMP._buildFailure   sv    &  
+	%+q#f+q) 	ANN!!F1q5M3va!e}+=r2F	 r3   rt   errorStreamIdframesStreamIdc                 x   dj                  | j                  j                  |            j                  d      }| j                  j                  |      D cg c]  }|j                  d       }}| j	                  t        |      ||      }| j                  j                  | j                  |       ddiS c c}w )a  
        Add an error to the reporter.

        @param errorStreamId: The identifier of a stream over which the text
            of this error was previously completely sent to the peer.

        @param framesStreamId: The identifier of a stream over which the lines
            of the traceback for this error were previously completely sent to
            the peer.

        @param error: A message describing the error.
        r3   utf-8r7   T)	joinrd   finishdecoder   r*   rG   addErrorrs   )	r?   rt   rv   r   r   ru   framerw   rN   s	            r4   r   zLocalWorkerAMP.addError   s    ( --m<=DDWM/3}}/C/CN/S
&+ELL!
 
 $$_U%;ZPdnng64  
   B7failStreamId	failClassc                 x   dj                  | j                  j                  |            j                  d      }| j                  j                  |      D cg c]  }|j                  d       }}| j	                  t        |      ||      }| j                  j                  | j                  |       ddiS c c}w )az  
        Add a failure to the reporter.

        @param failStreamId: The identifier of a stream over which the text of
            this failure was previously completely sent to the peer.

        @param framesStreamId: The identifier of a stream over which the lines
            of the traceback for this error were previously completely sent to the
            peer.
        r3   r   r7   T)	r   rd   r   r   r   r*   rG   
addFailurers   )	r?   rt   r   r   r   failr   rw   rN   s	            r4   r   zLocalWorkerAMP.addFailure   s    $ xx,,\:;BB7K/3}}/C/CN/S
&+ELL!
 
 $$_T%:IvN84  
r   c                 V    | j                   j                  | j                  |       ddiS )z-
        Add a skip to the reporter.
        r7   T)rG   addSkiprs   )r?   rt   reasons      r4   r   zLocalWorkerAMP.addSkip   s'    
 	T^^V44  r3   todoc                     dj                  | j                  j                  |            j                  d      }t	        |dn|      }| j
                  j                  | j                  ||       ddiS )z
        Add an expected failure to the reporter.

        @param errorStreamId: The identifier of a stream over which the text
            of this error was previously completely sent to the peer.
        r3   r   z	<unknown>r7   T)r   rd   r   r   r#   rG   addExpectedFailurers   )r?   rt   r   r   ru   _todos         r4   r   z!LocalWorkerAMP.addExpectedFailure  sa     --m<=DDWMDL[d;''uE4  r3   c                 V    | j                   j                  | j                  |       ddiS )z<
        Add an unexpected success to the reporter.
        r7   T)rG   addUnexpectedSuccessrs   )r?   rt   r   s      r4   r   z#LocalWorkerAMP.addUnexpectedSuccess  s'    
 	))$..$?4  r3   c                 z    | j                   j                  |dz          | j                   j                          ddiS )z4
        Print test output from the worker.
        
r7   T)_testStreamrn   flush)r?   outs     r4   	testWritezLocalWorkerAMP.testWrite  s9    
 	sTz* 4  r3   rK   r<   c                 J  K   || _         || _        | j                  j                  |       |j                         }	 | j	                  t
        j                  |       d{   | j                  j                  |       S 7 # | j                  j                  |       w xY ww)z
        Run a test.
        )rK   N)rs   rG   	startTestrO   
callRemoter   r]   stopTest)r?   rK   r<   
testCaseIds       r4   r@   zLocalWorkerAMP.run(  s|      "x([[]
	,););jQQLL!!(+ RLL!!(+s.   :B#$B !B"B %B#B B  B#c                     || _         y)z?
        Set the stream used to log output from tests.
        N)r   )r?   streams     r4   setTestStreamzLocalWorkerAMP.setTestStream5  s     "r3   )NN)(r,   r-   r.   r/   rJ   r%   r^   rl   r'   rp   r   
AddSuccessrr   r*   r0   r   r   r   AddErrorr~   r   r8   r   
AddFailurer   AddSkipr   AddExpectedFailurer   r   AddUnexpectedSuccessr   	TestWriter   r   r    r6   r@   r   __classcell__)rg   s   @r4   ra   ra      s   ) 2 2   ))! *!  S		
 
6 ''!! ! 	!
 ! 
c4i! (!> ))!! ! 	!
 ! 
c4i! *!4 &&! '! ''11!!,/!7?}!	c4i! 2! ))33! 4! ((! )!,( ,J ,9 ,"r3   ra   c                       e Zd ZdZy)LocalWorkerAddressz
    A L{IAddress} implementation meant to provide stub addresses for
    L{ITransport.getPeer} and L{ITransport.getHost}.
    Nr,   r-   r.   r/   r2   r3   r4   r   r   <  s    r3   r   c                   4    e Zd ZdZd Zd Zd Zd Zd Zd Z	y)	LocalWorkerTransportzi
    A stub transport implementation used to support L{AMP} over a
    L{ProcessProtocol} transport.
    c                     || _         y rE   )
_transport)r?   	transports     r4   rJ   zLocalWorkerTransport.__init__K  s	    #r3   c                 D    | j                   j                  t        |       y)z,
        Forward data to transport.
        Nr   writeToChildr   r?   ro   s     r4   rn   zLocalWorkerTransport.writeN  s     	$$%6=r3   c                 R    |D ]"  }| j                   j                  t        |       $ y)zP
        Emulate C{writeSequence} by iterating data in the C{sequence}.
        Nr   )r?   sequencero   s      r4   writeSequencez"LocalWorkerTransport.writeSequenceT  s*      	BDOO(():DA	Br3   c                 8    | j                   j                          y)z'
        Closes the transport.
        N)r   loseConnectionrk   s    r4   r   z#LocalWorkerTransport.loseConnection[  s     	&&(r3   c                     t               S z:
        Return a L{LocalWorkerAddress} instance.
        r   rk   s    r4   getHostzLocalWorkerTransport.getHosta       "##r3   c                     t               S r   r   rk   s    r4   getPeerzLocalWorkerTransport.getPeerg  r   r3   N)
r,   r-   r.   r/   rJ   rn   r   r   r   r   r2   r3   r4   r   r   D  s&    
$>B)$$r3   r   c                       e Zd ZdZy)
NotRunningzN
    An operation was attempted on a worker process which is not running.
    Nr   r2   r3   r4   r   r   n  s    r3   r   c                   `    e Zd ZdZdedee   defdZddZ	d	 Z
d
 ZdeddfdZd Zd Zd Zy)LocalWorkeraL  
    Local process worker protocol. This worker runs as a local process and
    communicates via stdin/out.

    @ivar _ampProtocol: The L{AMP} protocol instance used to communicate with
        the worker.

    @ivar _logDirectory: The directory where logs will reside.

    @ivar _logFile: The main log file for tests output.
    ampProtocollogDirectorylogFilec                 L    || _         || _        || _        t               | _        y rE   )_ampProtocol_logDirectory_logFiler   endDeferred)r?   r   r   r   s       r4   rJ   zLocalWorker.__init__  s%     ()+3:r3   r=   Nc                    K   | j                   
t               | j                  }| j                   j                  t               	 | d{    y7 # t
        $ r Y yw xY ww)z3
        Cause the worker process to exit.
        N)r   r   r   closeChildFDr   r   )r?   r   s     r4   exitzLocalWorker.exit  sW      >>!,&&##$56	 		s<   AA!A 
AA A!A 	AA!AA!c                 @   | j                   j                  t        | j                               | j                  j                  d       | j                  j                  d      j                  d      | _        | j                  j                  d      j                  d      | _	        | j                   j                  | j                         | j                   j                  t        j                  | j                  j                        }|j!                  d        y)	zL
        When connection is made, create the AMP protocol instance.
        T)ignoreExistingDirectoryzout.logwzerr.log)r[   c                      y rE   r2   )xs    r4   <lambda>z,LocalWorker.connectionMade.<locals>.<lambda>  s    r3   N)r   makeConnectionr   r   r   makedirschildrj   _outLog_errLogr   r   r   r   r_   path
addErrback)r?   ds     r4   connectionMadezLocalWorker.connectionMade  s     	(()=dnn)MN##D#A))//	:??D))//	:??D''6((  ((-- ) 
 	
^$r3   c                 z    | j                   j                          | j                  j                          d| _        y)zk
        On connection lost, close the log files that we're managing for stdin
        and stdout.
        N)r   closer   r   r?   r   s     r4   connectionLostzLocalWorker.connectionLost  s+    
 	r3   r   c                     | j                  |       | j                  j                  |       | j                  j                  |       y)z
        When the process closes, call C{connectionLost} for cleanup purposes
        and forward the information to the C{_ampProtocol}.
        N)r   r   r   callbackr   s     r4   processEndedzLocalWorker.processEnded  s:    
 	F#((0!!&)r3   c                 :    | j                   j                  |       y)z8
        Send data received from stdout to log.
        N)r   rn   r   s     r4   outReceivedzLocalWorker.outReceived  s    
 	4 r3   c                 :    | j                   j                  |       y)z*
        Write error data to log.
        N)r   rn   r   s     r4   errReceivedzLocalWorker.errReceived  s     	4 r3   c                 |    |t         k(  r| j                  j                  |       yt        j                  | ||       y)zT
        Handle data received on the specific pipe for the C{_ampProtocol}.
        N)r   r   dataReceivedr   childDataReceived)r?   childFDro   s      r4   r   zLocalWorker.childDataReceived  s3     ((**40--dGTBr3   )r=   N)r,   r-   r.   r/   ra   r   r   r	   rJ   r   r   r   r   r   r   r   r   r2   r3   r4   r   r   t  s^    
	6#	6 sm	6 		6%"*7 *t *!!Cr3   r   )Fr/   rY   typingr   r   r   r   r   r   r	   r
   unittestr   zope.interfacer   attrsr   typing_extensionsr   r   twisted.internet.deferr   r   twisted.internet.errorr   twisted.internet.interfacesr   r   twisted.internet.protocolr   twisted.loggerr   twisted.protocols.ampr   twisted.python.failurer   twisted.python.filepathr   twisted.python.reflectr   twisted.trial._distr   r   r   r   "twisted.trial._dist.workerreporterr   twisted.trial.reporterr    twisted.trial.runnerr!   r"   twisted.trial.unittestr#   r   r%   r&   r'   	Exceptionr*   r6   r:   rA   WorkerActionrC   ra   r   r   r   r   r2   r3   r4   <module>r
     s,   
 R R R  &  1 9 . < 5 ! % * , .  > - 7 ' ; ; i  	 X  T])B-/0@!S @!Fi"S i"X X   Z&$ &$ &$R ]C/ ]Cr3   