U
    
W["                     @   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 dd	lmZmZ dd
lmZ ddlmZ ddlmZmZ G dd de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)FilePath)theSystemPath)DeferredList	cooperate)_unusedTestDirectory)_iterateTests)LocalWorkerLocalWorkerAMP)DistReporter)UncleanWarningsReporterWrapper)_WORKER_AMP_STDIN_WORKER_AMP_STDOUTc                   @   s^   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}.
        )Zrealtime)_reporterFactory_stream	_tbformat	_rterrors_uncleanWarningsr   _distReporterFactory)selfZ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 kr tj}|| _|| _|| _|| _d | _	|	| _
|| _d | _d | _d| _d S )NF)_workerNumber_workerArgumentsr   sysstdoutr   r   r   r   Z_result_workingDirectory_logFileZ_logFileObserverZ_logFileObjectZ_logWarnings)
r   ZreporterFactoryworkerNumberZworkerArgumentsstreamZtracebackFormatZrealTimeErrorsZuncleanWarningsZlogfileworkingDirectoryr   r   r   __init__6   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)Zdone)r   resultr   r   r   writeResultsN   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xZprotocolr   r%   r   r   
<listcomp>c   s
   z6DistTrialRunner.createLocalWorkers.<locals>.<listcomp>)	enumerate)r   	protocolsr%   r   r/   r   createLocalWorkersW   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 qDd	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   ZTRIAL_PYTHONPATH)argschildFDsenvN)r   ZfilePathr*   r   r   r)   environcopypathsepr+   r   
executableextend)	r   Zspawnerr2   Z	argumentsZworkertrialPathr9   r;   workerr8   r   r   r   launchWorkerProcessesi   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)originalZ
addFailure)errorcase)r'   r   r   resultErrback   s    z3DistTrialRunner._driveWorker.<locals>.resultErrbackc                    s    |  }||  |S rB   )runZ
addErrback)rE   d)r'   rF   r@   r   r   task   s    z*DistTrialRunner._driveWorker.<locals>.taskc                 3   s   | ]} |V  qd S rB   r   )r-   rE   )rI   r   r   	<genexpr>   s     z/DistTrialRunner._driveWorker.<locals>.<genexpr>)ZwhenDone)r   r@   r'   	testCasesr   r   )r'   rF   rI   r@   r   _driveWorker   s    zDistTrialRunner._driveWorkerc                    s@  dkrddl m  
 }jd|f  |sT
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   r0      s     z'DistTrialRunner.run.<locals>.<listcomp>c                 S   s   g | ]
}|j qS r   )ZendDeferred)r-   r@   r   r   r   r0      s     c               	      sD   t tt} g } D ]}|j|| d qt|dddS )Nr   T)consumeErrorsZfireOnOneErrback)iterlistr   appendrL   r   )rK   ZworkerDeferredsr@   )
ampWorkersr   r'   r   suiter   r   runTests   s    
z%DistTrialRunner.run.<locals>.runTestsc                    s.     sd S  sd S  }| S rB   )r(   ZwasSuccessfuladdCallback)ignrH   )nextRunr'   rT   r   untilFailurer   r   rW      s    
z$DistTrialRunner.run.<locals>.nextRunc                    s"      sd     d S rB   )ZunlockrQ   stoprV   )rM   stoppingtestDirLockr   r   rY      s    
z!DistTrialRunner.run.<locals>.stopc                     s(   s$ d  tdd} |  S d S )NT)rN   )rQ   r   rU   )rH   )continueShutdownprocessEndDeferredsr[   r   r   beforeShutDown   s    
z+DistTrialRunner.run.<locals>.beforeShutDownc                    s      | S rB   )r(   rZ   )r'   r   r   r   r]      s    
z-DistTrialRunner.run.<locals>.continueShutdownZbeforeZshutdown)Ztwisted.internetrM   r   ZcountTestCasesr   writerG   rC   r(   r   r   r!   minr   ranger3   r*   rA   ZspawnProcessr   rU   ZaddBothZaddSystemEventTrigger)r   rS   rM   r   rX   countZtestDirr#   ZworkersrY   r_   rH   r   )rR   r]   r   rW   r^   rM   r'   rT   r   r[   rS   r\   rX   r   rG      s>    

	

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)rX   )rG   )r   rS   r   r   r   runUntilFailure   s    zDistTrialRunner.runUntilFailure)Nr   FFr   r   )__name__
__module____qualname____doc__r   r   r   r&   r(   r3   rA   rL   r   rG   rd   r   r   r   r   r      s$         
	
[r   )rh   r)   r   Ztwisted.python.filepathr   Ztwisted.python.modulesr   Ztwisted.internet.deferr   Ztwisted.internet.taskr   Ztwisted.trial.utilr   Ztwisted.trial._asyncrunnerr   Ztwisted.trial._dist.workerr	   r
   Z twisted.trial._dist.distreporterr   Ztwisted.trial.reporterr   Ztwisted.trial._distr   r   objectr   r   r   r   r   <module>   s   