o
    bn!                     @   s   d Z ddlZddl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 dd	lmZ dd
lmZmZ ddlmZ ddlmZ G dd dZdS )z
This module contains the trial distributed runner, the management class
responsible for coordinating all of trial's behavior at the highest level.

@since: 12.3
    N)DeferredList	cooperate)FilePath)theSystemPath)_iterateTests)_WORKER_AMP_STDIN_WORKER_AMP_STDOUT)DistReporter)LocalWorkerLocalWorkerAMP)UncleanWarningsReporterWrapper)_unusedTestDirectoryc                   @   sj   e Zd ZdZeZdd Z						dd	d
Zdd Zdd Z	dd Z
dd ZdedfddZdd ZdS )DistTrialRunneraY  
    A specialized runner for distributed trial. The runner launches a number of
    local worker processes which will run tests.

    @ivar _workerNumber: the number of workers to be spawned.
    @type _workerNumber: C{int}

    @ivar _stream: stream which the reporter will use.

    @ivar _reporterFactory: the reporter class to be used.
    c                 C   s.   | j | j| j| jd}| jrt|}| |S )zL
        Make reporter factory, and wrap it with a L{DistReporter}.
        )realtime)_reporterFactory_stream	_tbformat	_rterrors_uncleanWarningsr   _distReporterFactory)selfreporter r   ?/usr/lib/python3/dist-packages/twisted/trial/_dist/disttrial.py_makeResult*   s   
zDistTrialRunner._makeResultNdefaultFtest.log_trial_tempc
           
      C   s`   || _ || _|| _|d u rtj}|| _|| _|| _|| _d | _	|	| _
|| _d | _d | _d| _d S )NF)_workerNumber_workerArgumentsr   sysstdoutr   r   r   r   _result_workingDirectory_logFile_logFileObserver_logFileObject_logWarnings)
r   reporterFactoryworkerNumberworkerArgumentsstreamtracebackFormatrealTimeErrorsuncleanWarningslogfileworkingDirectoryr   r   r   __init__5   s   
zDistTrialRunner.__init__c                 C   s   |   dS )z
        Write test run final outcome to result.

        @param result: A C{TestResult} which will print errors and the summary.
        N)done)r   resultr   r   r   writeResultsQ   s   zDistTrialRunner.writeResultsc                    s    fddt |D S )aY  
        Create local worker protocol instances and return them.

        @param protocols: An iterable of L{LocalWorkerAMP} instances.

        @param workingDirectory: The base path in which we should run the
            workers.
        @type workingDirectory: C{str}

        @return: A list of C{quantity} C{LocalWorker} instances.
        c              	      s,   g | ]\}}t |tjt| jqS r   )r   ospathjoinstrr%   ).0xprotocolr   r1   r   r   
<listcomp>e   s    z6DistTrialRunner.createLocalWorkers.<locals>.<listcomp>)	enumerate)r   	protocolsr1   r   r=   r   createLocalWorkersY   s   z"DistTrialRunner.createLocalWorkersc           	   
   C   sv   t d jj}ddddddtdtdi}tj }tj	t
j|d< |D ]}t
j|g}|| ||t
j|||d q"d	S )
a  
        Spawn processes from a list of process protocols.

        @param spawner: A C{IReactorProcess.spawnProcess} implementation.

        @param protocols: An iterable of C{ProcessProtocol} instances.

        @param arguments: Extra arguments passed to the processes.
        ztwisted.trial._dist.workertrialr   w   r   TRIAL_PYTHONPATH)argschildFDsenvN)r   filePathr7   r   r	   r6   environcopypathsepr8   r!   
executableextend)	r   spawnerr@   	argumentsworkertrialPathrH   rK   workerrG   r   r   r   launchWorkerProcessesj   s   



z%DistTrialRunner.launchWorkerProcessesc                    s6    fdd fdd|fdd|D   S )a  
        Drive a L{LocalWorkerAMP} instance, iterating the tests and calling
        C{run} for every one of them.

        @param worker: The L{LocalWorkerAMP} to drive.

        @param result: The global L{DistReporter} instance.

        @param testCases: The global list of tests to iterate.

        @param cooperate: The cooperate function to use, to be customized in
            tests.
        @type cooperate: C{function}

        @return: A C{Deferred} firing when all the tests are finished.
        c                    s    j ||  | S N)original
addFailure)errorcase)r4   r   r   resultErrback   s   z3DistTrialRunner._driveWorker.<locals>.resultErrbackc                    s    |  }||  |S rU   )run
addErrback)rY   d)r4   rZ   rS   r   r   task   s   z*DistTrialRunner._driveWorker.<locals>.taskc                 3   s    | ]} |V  qd S rU   r   )r:   rY   )r^   r   r   	<genexpr>   s    z/DistTrialRunner._driveWorker.<locals>.<genexpr>)whenDone)r   rS   r4   	testCasesr   r   )r4   rZ   r^   rS   r   _driveWorker   s   zDistTrialRunner._driveWorkerc                    s@  du r
ddl m  
 }jd|f  |s*
j  S t	t
j\}t|j}dd t|D   |j}dd |D j|j  
fdd	g 	fd
d	fdd}		fdd}
fdd }| ||	 dd|
   S )a{  
        Spawn local worker processes and load tests. After that, run them.

        @param suite: A tests suite to be run.

        @param reactor: The reactor to use, to be customized in tests.
        @type reactor: A provider of
            L{twisted.internet.interfaces.IReactorProcess}

        @param cooperate: The cooperate function to use, to be customized in
            tests.
        @type cooperate: C{function}

        @param untilFailure: If C{True}, continue to run the tests until they
            fail.
        @type untilFailure: C{bool}.

        @return: The test result.
        @rtype: L{DistReporter}
        Nr   )reactorzRunning %d tests.
c                 S   s   g | ]}t  qS r   )r   )r:   r;   r   r   r   r>          z'DistTrialRunner.run.<locals>.<listcomp>c                 S   s   g | ]}|j qS r   )endDeferred)r:   rS   r   r   r   r>      rd   c               	      sD   t tt} g } D ]}|j|| d qt|dddS )Nr   T)consumeErrorsfireOnOneErrback)iterlistr   appendrb   r   )ra   workerDeferredsrS   )
ampWorkersr   r4   r   suiter   r   runTests   s   z%DistTrialRunner.run.<locals>.runTestsc                    s.     s	d S  sd S  }| S rU   )r5   wasSuccessfuladdCallback)ignr]   )nextRunr4   rn   r   untilFailurer   r   rr      s   

z$DistTrialRunner.run.<locals>.nextRunc                    s&      sd     d S d S rU   )unlockrj   stoprq   )rc   stoppingtestDirLockr   r   ru      s
   
z!DistTrialRunner.run.<locals>.stopc                     s(   s d  tdd} |  S d S )NT)rf   )rj   r   rp   )r]   )continueShutdownprocessEndDeferredsrw   r   r   beforeShutDown   s
   

z+DistTrialRunner.run.<locals>.beforeShutDownc                    s      | S rU   )r5   rv   )r4   r   r   r   ry      s   
z-DistTrialRunner.run.<locals>.continueShutdownbeforeshutdown)twisted.internetrc   r   countTestCasesr   writer[   rV   r5   r   r   r$   minr   rangerA   r7   rT   spawnProcessr    rp   addBothaddSystemEventTrigger)r   rm   rc   r   rs   counttestDirr*   workersru   r{   r]   r   )rl   ry   r   rr   rz   rc   r4   rn   r   rw   rm   rx   rs   r   r[      s6   
	

zDistTrialRunner.runc                 C   s   | j |ddS )z|
        Run the tests with local worker processes until they fail.

        @param suite: A tests suite to be run.
        T)rs   )r[   )r   rm   r   r   r   runUntilFailure   s   zDistTrialRunner.runUntilFailure)Nr   FFr   r   )__name__
__module____qualname____doc__r
   r   r   r2   r5   rA   rT   rb   r   r[   r   r   r   r   r   r      s"    
Xr   )r   r6   r!   twisted.internet.deferr   twisted.internet.taskr   twisted.python.filepathr   twisted.python.modulesr   twisted.trial._asyncrunnerr   twisted.trial._distr   r	    twisted.trial._dist.distreporterr
   twisted.trial._dist.workerr   r   twisted.trial.reporterr   twisted.trial.utilr   r   r   r   r   r   <module>   s   