U
     T‚gß@  ã                   @   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m	Z	m
Z
mZmZmZmZmZmZmZ ddlmZmZ ddlmZmZmZ ddlmZ dd	lmZmZ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/m0Z0 ddl1m2Z2 ddl3m4Z4 ddl5m6Z6m7Z7 ddl8m9Z9m:Z: ddl;m<Z< ddl=m>Z>m?Z?m@Z@mAZA ddlBmCZCmDZDmEZE G dd„ de e!ƒZFeFdœdd„ZGeG d d!„ d!ƒƒZHeG d"d#„ d#ƒƒZIeG d$d%„ d%ƒƒZJeKe/eKd&œd'd(„ZLeIee0 e<e
e<ee0 eDge	d f dd)œd*d+„ZMeG d,d-„ d-ƒƒZNd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)Úpartial)Úisabs)
ÚAnyÚ	AwaitableÚCallableÚIterableÚListÚOptionalÚSequenceÚTextIOÚUnionÚcast)ÚTestCaseÚ	TestSuite)ÚdefineÚfieldÚfrozen)Údefault_if_none)ÚDeferredÚDeferredListÚgatherResults)ÚIReactorCoreÚIReactorProcess)ÚLogger)ÚFailure)ÚFilePath)ÚFilesystemLock)ÚtheSystemPathé   )Ú_iterateTests)Ú	IReporterÚ	ITestCase)ÚUncleanWarningsReporterWrapper)Ú
TestHolder)Ú_unusedTestDirectoryÚopenTestLogé   )Ú_WORKER_AMP_STDINÚ_WORKER_AMP_STDOUT)ÚDistReporter)ÚcountingCallsÚdiscardResultÚiterateWhileÚ	takeWhile)ÚLocalWorkerÚLocalWorkerAMPÚWorkerActionc                   @   s   e Zd ZdZdS )ÚIDistTrialReactorz7
    The reactor interfaces required by disttrial.
    N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__© r6   r6   úA/tmp/pip-unpacked-wheel-1_7di8ic/twisted/trial/_dist/disttrial.pyr1   3   s   r1   ©Úreturnc                  C   s@   ddl m  m}  tt | ¡t | ¡gƒr4tt| ƒS t	dƒ‚dS )zR
    Get the default reactor, ensuring it is suitable for use with disttrial.
    r   Nz-Reactor does not provide the right interfaces)
Ztwisted.internet.reactorZinternetÚreactorÚallr   Z
providedByr   r   r1   Ú	TypeError)ZdefaultReactorr6   r6   r7   Ú_defaultReactor9   s    þÿ	
r=   c                   @   s:   e Zd ZU dZeed< ee ed< ee	 ed< e	ed< dS )ÚWorkerPoolConfiga’  
    Configuration parameters for a pool of test-running workers.

    @ivar numWorkers: The number of workers in the pool.

    @ivar workingDirectory: A directory in which working directories for each
        of the workers will be created.

    @ivar workerArguments: Extra arguments to pass the worker process in its
        argv.

    @ivar logFile: The basename of the overall test log file.
    Ú
numWorkersÚworkingDirectoryÚworkerArgumentsÚlogFileN)
r2   r3   r4   r5   ÚintÚ__annotations__r   r   r
   Ústrr6   r6   r6   r7   r>   M   s
   
r>   c                   @   sn   e Zd ZU dZee ed< eed< eed< e	e
 ed< e	e ed< eƒ Zee ddœd	d
„Zddœdd„ZdS )ÚStartedWorkerPoolaE  
    A pool of workers which have already been started.

    @ivar workingDirectory: A directory holding the working directories for
        each of the workers.

    @ivar testDirLock: An object representing the cooperative lock this pool
        holds on its working directory.

    @ivar testLog: The open overall test log file.

    @ivar workers: Objects corresponding to the worker child processes and
        adapting between process-related interfaces and C{IProtocol}.

    @ivar ampWorkers: AMP protocol instances corresponding to the worker child
        processes.
    r@   ÚtestDirLockÚtestLogÚworkersÚ
ampWorkersN)ÚworkerActionr9   c                 ƒ   s"   t ‡ fdd„| jD ƒƒI dH  dS )zB
        Run an action on all of the workers in the pool.
        c                 3   s   | ]}t ˆ |ƒƒV  qd S ©N)r+   ©Ú.0Úworker©rK   r6   r7   Ú	<genexpr>ƒ   s    z(StartedWorkerPool.run.<locals>.<genexpr>N)r   rJ   )ÚselfrK   r6   rP   r7   Úrun   s    ÿzStartedWorkerPool.runr8   c                 Ã   s~   t dd„ | jD ƒdd�I dH }t|ƒD ]&\}\}}|s&| j d|› d�|¡ q&| jdd…= | jdd…= | j ¡  | j 	¡  dS )zv
        Shut down all of the workers in the pool.

        The pool is unusable after this method is called.
        c                 S   s   g | ]}t  | ¡ ¡‘qS r6   )r   ÚfromCoroutineÚexitrM   r6   r6   r7   Ú
<listcomp>�   s     z*StartedWorkerPool.join.<locals>.<listcomp>T)ZconsumeErrorsNzjoining disttrial worker #z failed)
r   rI   Ú	enumerateÚ_loggerÚfailurerJ   rH   ÚcloserG   Zunlock)rR   ÚresultsÚnZ	succeededrY   r6   r6   r7   Újoinˆ   s    þ
zStartedWorkerPool.join)r2   r3   r4   r5   r   r   rD   r   r   r   r.   r/   r   rX   r0   rS   r]   r6   r6   r6   r7   rF   c   s   
	rF   c                   @   sR   e Zd ZU dZeed< ee ee	 e
ee dœdd„Zdd„ Zeedœd	d
„ZdS )Ú
WorkerPoolz 
    Manage a fixed-size collection of child processes which can run tests.

    @ivar _config: Configuration for the precise way in which the pool is run.
    Ú_config)Ú	protocolsr@   rB   r9   c                    s   ‡ ‡fdd„t |ƒD ƒS )aŒ  
        Create local worker protocol instances and return them.

        @param protocols: The process/protocol adapters to use for the created
        workers.

        @param workingDirectory: The base path in which we should run the
            workers.

        @param logFile: The test log, for workers to write to.

        @return: A list of C{quantity} C{LocalWorker} instances.
        c                    s&   g | ]\}}t |ˆ t|ƒ¡ˆ ƒ‘qS r6   )r.   ÚchildrE   )rN   ÚxÚprotocol©rB   r@   r6   r7   rV   ¹   s   ÿz2WorkerPool._createLocalWorkers.<locals>.<listcomp>)rW   )rR   r`   r@   rB   r6   rd   r7   Ú_createLocalWorkers¦   s    þzWorkerPool._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   Úwr&   Úrr   Ú
PYTHONPATH)ÚargsÚchildFDsÚenvN)r   ZfilePathÚpathr'   r(   ÚosÚenvironÚcopyÚpathsepr]   ÚsysÚ
executableÚextend)	rR   Zspawnerr`   Ú	argumentsZworkertrialPathrj   rn   rO   ri   r6   r6   r7   Ú_launchWorkerProcesses¾   s$    
     û


z!WorkerPool._launchWorkerProcesses)r:   r9   c                 Ã   sˆ   t | jjƒ\}}t| jjƒr*t| jjƒ}n| | jj¡}t|ƒ}dd„ t| jj	ƒD ƒ}|  
|||¡}|  |j|| jj¡ t|||||ƒS )z‡
        Launch all of the workers for this pool.

        @return: A started pool object that can run jobs using the workers.
        c                 S   s   g | ]
}t ƒ ‘qS r6   )r/   )rN   rb   r6   r6   r7   rV   í   s     z$WorkerPool.start.<locals>.<listcomp>)r$   r_   r@   r   rB   r   ZpreauthChildr%   Úranger?   re   ru   ZspawnProcessrA   rF   )rR   r:   ZtestDirrG   ZtestLogPathrH   rJ   rI   r6   r6   r7   ÚstartÙ   s2    ÿýýûzWorkerPool.startN)r2   r3   r4   r5   r>   rD   r   r/   r   r   r   r   r.   re   ru   r   rF   rw   r6   r6   r6   r7   r^   œ   s   
ûr^   )ÚuntilFailureÚresultr9   c                 C   s   | o
|  ¡ S )zû
    Determine whether the test suite should be iterated again.

    @param untilFailure: C{True} if the suite is supposed to run until
        failure.

    @param result: The test result of the test suite iteration which just
        completed.
    )ÚwasSuccessful)rx   ry   r6   r6   r7   ÚshouldContinue  s    
r{   )ÚpoolÚ	testCasesry   ÚdriveWorkerr9   c                 Ã   sJ   z|   t|||ƒ¡I d H  W n( tk
rD   |j tdƒtƒ ¡ Y nX d S )Nz
<runTests>)rS   r   Ú	ExceptionÚoriginalÚaddErrorr#   r   )r|   r}   ry   r~   r6   r6   r7   ÚrunTests  s    r‚   c                   @   sf  e Zd ZU dZeZeƒ Zede	f e
d< ee
d< ee e
d< dZee
d< edeed	�d
�Zee
d< edeejƒd
�Zee
d< dZee
d< dZee
d< dZee
d< dZee
d< dZee
d< eZee gef e
d< edœdd„Z!dd„ Z"ee#e$ e%ddœdd„Z&d)e'e(e)f eedœdd „Z*e'e(e)f ee	d!œd"d#„Z+e'e(e)f e	d$œd%d&„Z,e'e(e)f e	d$œd'd(„Z-dS )*ÚDistTrialRunneraç  
    A specialized runner for distributed trial. The runner launches a number of
    local worker processes which will run tests.

    @ivar _maxWorkers: the number of workers to be spawned.

    @ivar _exitFirst: ``True`` to stop the run as soon as a test case fails.
        ``False`` to run through the whole suite and report all of the results
        at the end.

    @ivar stream: stream which the reporter will use.

    @ivar _reporterFactory: the reporter class to be used.
    .Ú_reporterFactoryÚ_maxWorkersÚ_workerArgumentsFÚ
_exitFirstN)Úfactory)ÚdefaultÚ	converterÚ_reactorÚstreamr‰   Ú_tracebackFormatÚ_realTimeErrorsÚ_uncleanWarningsztest.logÚ_logfileZ_trial_tempÚ_workingDirectoryÚ_workerPoolFactoryr8   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)r„   rŒ   r�   rŽ   r�   r"   Ú_distReporterFactory)rR   Úreporterr6   r6   r7   Ú_makeResultJ  s      ÿzDistTrialRunner._makeResultc                 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)rR   ry   r6   r6   r7   ÚwriteResultsU  s    zDistTrialRunner.writeResults)ry   r}   rO   r9   c                 ƒ   s*   ‡ ‡fdd„}|D ]}||ƒI dH  q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.

        @return: A coroutine that completes after all of the tests have
            completed.
        c                 “   s@   zˆ  | ˆ ¡I d H  W n$ tk
r:   ˆ j | tƒ ¡ Y nX d S rL   )rS   r   r€   r�   r   )Úcase©ry   rO   r6   r7   Útaskq  s    z*DistTrialRunner._driveWorker.<locals>.taskNr6   )rR   ry   r}   rO   rš   r˜   r6   r™   r7   Ú_driveWorker]  s    zDistTrialRunner._driveWorker)Úsuiterx   r9   c                 ƒ   s²   t t|ƒƒ‰ˆ  tttˆƒˆ jƒtˆ jƒˆ j	ˆ j
ƒ¡}ˆ j d| ¡ › d�¡ | ˆ j¡I dH ‰ttˆƒ}tttdœ‡ ‡‡‡fdd„ƒ}zt||ƒI dH W ¢S ˆ ¡ I dH  X dS )a*  
        Spawn local worker processes and load tests. After that, run them.

        @param suite: A test or suite to be run.

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

        @return: A coroutine that completes with the test result.
        zRunning z tests.
N)r\   r9   c                 “   sj   ˆrˆj  d| d › d�¡ ˆ ¡ ‰ ˆjr8‡ fdd„}ndd„ }tˆt|ˆƒˆ ˆjƒI d H  ˆ ˆ ¡ ˆ S )Nz
Test Pass r&   Ú
c                    s
   ˆ j  ¡ S rL   )r€   rz   ©Ú_©ry   r6   r7   Ú<lambda>°  ó    z@DistTrialRunner.runAsync.<locals>.runAndReport.<locals>.<lambda>c                 S   s   dS ©NTr6   rž   r6   r6   r7   r¡   ²  r¢   )rŒ   Úwriter•   r‡   r‚   r-   r›   r—   )r\   ZcasesCondition©rR   ZstartedPoolr}   rx   r    r7   ÚrunAndReport¤  s    ü

z.DistTrialRunner.runAsync.<locals>.runAndReport)Úlistr   r’   r>   ÚminÚlenr…   r   r‘   r†   r�   rŒ   r¤   ZcountTestCasesrw   r‹   r   r{   r*   rC   r)   r]   r,   )rR   rœ   rx   ZpoolStarterÚ	conditionr¦   r6   r¥   r7   ÚrunAsyncz  s"    ûÿ
zDistTrialRunner.runAsync)Útestrx   r9   c                    sÆ   d ‰d‰ t ttf d dœ‡fdd„}ttt  dœ‡ ‡‡fdd„}ttdœ‡ ‡fd	d
„}ˆj dd|¡ t ˆ 	||¡¡ 
|¡ 
|¡‰ˆj ¡  tˆtƒr¢ˆ ¡  tˆtƒsºtˆ› d�ƒ‚ttˆjƒS )NF)rg   r9   c                    s   | ‰ d S rL   r6   )rg   r    r6   r7   ÚcaptureË  s    z%DistTrialRunner._run.<locals>.capturer8   c                      s   d‰ ˆd krˆ  ¡  ˆS d S r£   )Úcancelr6   )ÚreactorStoppingry   ÚtestsInProgressr6   r7   ÚmaybeStopTestsÏ  s
    z,DistTrialRunner._run.<locals>.maybeStopTests)ry   r9   c                    s   ˆ sˆj  ¡  | S rL   )r‹   Ústopr    )r¯   rR   r6   r7   ÚmaybeStopReactor×  s    
z.DistTrialRunner._run.<locals>.maybeStopReactorÚbeforeÚshutdownz is not DistReporter)r   r   r)   r	   r   Úobjectr‹   ZaddSystemEventTriggerrT   r«   ZaddBothrS   Ú
isinstanceZraiseExceptionÚAssertionErrorr   r    r€   )rR   r¬   rx   r­   r±   r³   r6   )r¯   ry   rR   r°   r7   Ú_runÆ  s"    ÿþÿ

zDistTrialRunner._run)r¬   r9   c                 C   s   | j |dd�S )za
        Run a reactor and a test suite.

        @param test: The test or suite to run.
        F©rx   ©r¹   ©rR   r¬   r6   r6   r7   rS   ò  s    zDistTrialRunner.runc                 C   s   | j |dd�S )z|
        Run the tests with local worker processes until they fail.

        @param test: The test or suite to run.
        Trº   r»   r¼   r6   r6   r7   ÚrunUntilFailureú  s    zDistTrialRunner.runUntilFailure)F).r2   r3   r4   r5   r)   r“   r   rX   r   r    rD   rC   r   rE   r‡   Úboolr   r   r=   r‹   r1   rq   ÚstdoutrŒ   r   r�   rŽ   r�   r�   r‘   r^   r’   r>   r•   r—   r
   r!   r/   r›   r   r   r   r«   r¹   rS   r½   r6   r6   r6   r7   rƒ   !  sD   
ý
û  ý
üL,rƒ   )Or5   rm   rq   Ú	functoolsr   Úos.pathr   Útypingr   r   r   r   r   r	   r
   r   r   r   Zunittestr   r   Úattrsr   r   r   Zattrs.convertersr   Ztwisted.internet.deferr   r   r   Ztwisted.internet.interfacesr   r   Ztwisted.loggerr   Ztwisted.python.failurer   Ztwisted.python.filepathr   Ztwisted.python.lockfiler   Ztwisted.python.modulesr   Z_asyncrunnerr   Zitrialr    r!   r”   r"   Úrunnerr#   Úutilr$   r%   Ú r'   r(   Zdistreporterr)   Z
functionalr*   r+   r,   r-   rO   r.   r/   r0   r1   r=   r>   rF   r^   r¾   r{   r‚   rƒ   r6   r6   r6   r7   Ú<module>   sV   08eÿù