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   