o
    b$                     @   s  d Z ddlZddl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mZmZmZ ddlmZ ddlmZmZ ddlmZ G dd deZG dd deZeeG dd dZeeG dd dZ G dd de
Z!dS )z:
This module implements the worker classes.

@since: 12.3
    N)implementer)Deferred)IAddress
ITransport)ProcessProtocol)AMP)Failure)namedObject)_WORKER_AMP_STDIN_WORKER_AMP_STDOUTmanagercommandsworkercommands)WorkerReporter)
TestLoader
TrialSuite)Todoc                   @   sB   e Zd ZdZd
ddZdd Zeje dd Z	ej
e	 d	S )WorkerProtocolz5
    The worker-side trial distributed protocol.
    Fc                 C   s   t  | _t| | _|| _d S N)r   _loaderr   _result_forceGarbageCollection)selfforceGarbageCollection r   </usr/lib/python3/dist-packages/twisted/trial/_dist/worker.py__init__&   s   

zWorkerProtocol.__init__c                 C   s.   | j |}t|g| j}|| j ddiS )z*
        Run a test case by name.
        successT)r   
loadByNamer   r   runr   )r   testCasecasesuiter   r   r   r   +   s   zWorkerProtocol.runc                 C   s   t | ddiS )zb
        Set up the worker, moving into given directory for tests to run in
        them.
        r   T)oschdir)r   	directoryr   r   r   start6   s   
zWorkerProtocol.startN)F)__name__
__module____qualname____doc__r   r   r   Run	responderr%   Startr   r   r   r   r   !   s    
	r   c                   @   s   e Zd ZdZdd Zeje dd Zdd Z	ej
e	 dd	 Zeje d
d Zeje dd Zeje dd Zeje dd Zeje dd Zdd Zdd ZdS )LocalWorkerAMPz7
    Local implementation of the manager commands.
    c                 C   s   | j | j ddiS )z0
        Add a success to the reporter.
        r   T)r   
addSuccess	_testCase)r   testNamer   r   r   r.   F   s   zLocalWorkerAMP.addSuccessc              	   C   sZ   t |}t||}tdt|dD ]}|j|| ||d  t||d  g g f q|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   rangelenframesappendint)r   error
errorClassr6   	errorTypefailureir   r   r   _buildFailureO   s   
$zLocalWorkerAMP._buildFailurec                 C   &   |  |||}| j| j| ddiS )z/
        Add an error to the reporter.
        r   T)r>   r   addErrorr/   )r   r0   r9   r:   r6   r<   r   r   r   r@   e      zLocalWorkerAMP.addErrorc                 C   r?   )z0
        Add a failure to the reporter.
        r   T)r>   r   
addFailurer/   )r   r0   fail	failClassr6   r<   r   r   r   rB   o   rA   zLocalWorkerAMP.addFailurec                 C      | j | j| ddiS )z-
        Add a skip to the reporter.
        r   T)r   addSkipr/   )r   r0   reasonr   r   r   rF   y      zLocalWorkerAMP.addSkipc                 C   s"   t |}| j| j|| ddiS )z:
        Add an expected failure to the reporter.
        r   T)r   r   addExpectedFailurer/   )r   r0   r9   todo_todor   r   r   rI      s   z!LocalWorkerAMP.addExpectedFailurec                 C   rE   )z<
        Add an unexpected success to the reporter.
        r   T)r   addUnexpectedSuccessr/   )r   r0   rJ   r   r   r   rL      rH   z#LocalWorkerAMP.addUnexpectedSuccessc                 C   s"   | j |d  | j   ddiS )z4
        Print test output from the worker.
        
r   T)_testStreamwriteflush)r   outr   r   r   	testWrite   s   
zLocalWorkerAMP.testWritec                 C   s   | j | j |S )zL
        Stop the current running test case, forwarding the result.
        )r   stopTestr/   )r   resultr   r   r   	_stopTest   s   zLocalWorkerAMP._stopTestc                 C   s<   || _ || _| j| | }| jtj|d}|| jS )z
        Run a test.
        )r   )	r/   r   	startTestid
callRemoter   r*   addCallbackrU   )r   r   rT   
testCaseIddr   r   r   r      s   zLocalWorkerAMP.runc                 C   s
   || _ dS )z?
        Set the stream used to log output from tests.
        N)rN   )r   streamr   r   r   setTestStream   s   
zLocalWorkerAMP.setTestStreamN)r&   r'   r(   r)   r.   r   
AddSuccessr+   r>   r@   AddErrorrB   
AddFailurerF   AddSkiprI   AddExpectedFailurerL   AddUnexpectedSuccessrR   	TestWriterU   r   r]   r   r   r   r   r-   A   s(    r-   c                   @   s   e Zd ZdZdS )LocalWorkerAddressz
    A L{IAddress} implementation meant to provide stub addresses for
    L{ITransport.getPeer} and L{ITransport.getHost}.
    N)r&   r'   r(   r)   r   r   r   r   re      s    re   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 )LocalWorkerTransportzi
    A stub transport implementation used to support L{AMP} over a
    L{ProcessProtocol} transport.
    c                 C   s
   || _ d S r   )
_transport)r   	transportr   r   r   r      s   
zLocalWorkerTransport.__init__c                 C   s   | j t| dS )z,
        Forward data to transport.
        Nrg   writeToChildr
   r   datar   r   r   rO      s   zLocalWorkerTransport.writec                 C   s   |D ]	}| j t| qdS )zP
        Emulate C{writeSequence} by iterating data in the C{sequence}.
        Nri   )r   sequencerl   r   r   r   writeSequence   s   z"LocalWorkerTransport.writeSequencec                 C   s   | j   dS )z'
        Closes the transport.
        N)rg   loseConnectionr   r   r   r   ro      s   z#LocalWorkerTransport.loseConnectionc                 C      t  S z:
        Return a L{LocalWorkerAddress} instance.
        re   rp   r   r   r   getHost      zLocalWorkerTransport.getHostc                 C   rq   rr   rs   rp   r   r   r   getPeer   ru   zLocalWorkerTransport.getPeerN)
r&   r'   r(   r)   r   rO   rn   ro   rt   rv   r   r   r   r   rf      s    rf   c                   @   sH   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d Z
dS )LocalWorkeraX  
    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 name of the main log file for tests output.
    c                 C   s   || _ || _|| _t | _d S r   )_ampProtocol_logDirectory_logFiler   endDeferred)r   ampProtocollogDirectorylogFiler   r   r   r      s   zLocalWorker.__init__c                 C   s   | j t| j tj| jst| j t	tj
| jdd| _t	tj
| jdd| _t	tj
| j| jdddd| _| j | j | j}| j jtj|d}|d	d
  dS )zL
        When connection is made, create the AMP protocol instance.
        zout.logwbzerr.logwzutf-8strict)encodingerrors)r$   c                 S   s   d S r   r   )xr   r   r   <lambda>  s    z,LocalWorker.connectionMade.<locals>.<lambda>N)rx   makeConnectionrf   rh   r"   pathexistsry   makedirsopenjoin_outLog_errLogrz   _testLogr]   rX   r   r,   
addErrback)r   r}   r[   r   r   r   connectionMade   s   zLocalWorker.connectionMadec                 C   s"   | j   | j  | j  dS )zk
        On connection lost, close the log files that we're managing for stdin
        and stdout.
        N)r   closer   r   r   rG   r   r   r   connectionLost  s   

zLocalWorker.connectionLostc                 C   s&   |  | | j | | j| dS )z
        When the process closes, call C{connectionLost} for cleanup purposes
        and forward the information to the C{_ampProtocol}.
        N)r   rx   r{   callbackr   r   r   r   processEnded  s   
zLocalWorker.processEndedc                 C      | j | dS )z8
        Send data received from stdout to log.
        N)r   rO   rk   r   r   r   outReceived(  s   zLocalWorker.outReceivedc                 C   r   )z*
        Write error data to log.
        N)r   rO   rk   r   r   r   errReceived/  s   zLocalWorker.errReceivedc                 C   s*   |t kr| j| dS t| || dS )zT
        Handle data received on the specific pipe for the C{_ampProtocol}.
        N)r   rx   dataReceivedr   childDataReceived)r   childFDrl   r   r   r   r   5  s   zLocalWorker.childDataReceivedN)r&   r'   r(   r)   r   r   r   r   r   r   r   r   r   r   r   rw      s    		rw   )"r)   r"   zope.interfacer   twisted.internet.deferr   twisted.internet.interfacesr   r   twisted.internet.protocolr   twisted.protocols.ampr   twisted.python.failurer   twisted.python.reflectr	   twisted.trial._distr
   r   r   r   "twisted.trial._dist.workerreporterr   twisted.trial.runnerr   r   twisted.trial.unittestr   r   r-   re   rf   rw   r   r   r   r   <module>   s(    w)