
    Vh@                     j   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e e!      ZFdeFfdZGe G d d              ZHe G d! d"             ZIe G d# d$             ZJd%eKd&e/deKfd'ZLd(eId)ee0   d&e<d*e
e<ee0   eDge	d   f   ddf
d+ZMe G d, d-             ZNy).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                       e Zd ZdZy)IDistTrialReactorz7
    The reactor interfaces required by disttrial.
    N)__name__
__module____qualname____doc__     M/home/dcms/DCMS/lib/python3.12/site-packages/twisted/trial/_dist/disttrial.pyr3   r3   3   s    r9   r3   returnc                      ddl mc m}  t        t	        j
                  |       t        j
                  |       g      rt        t        |       S t        d      )zR
    Get the default reactor, ensuring it is suitable for use with disttrial.
    r   Nz-Reactor does not provide the right interfaces)
twisted.internet.reactorinternetreactorallr   
providedByr   r   r3   	TypeError)defaultReactors    r:   _defaultReactorrD   9   sO     65
##N3&&~6	
 %~66
C
DDr9   c                   F    e Zd ZU dZeed<   ee   ed<   ee	   ed<   e	ed<   y)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)
r4   r5   r6   r7   int__annotations__r   r   r   strr8   r9   r:   rF   rF   M   s'     Osm#c]"Lr9   rF   c                       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dee   dd	fd
ZddZy	)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.
    rH   testDirLocktestLogworkers
ampWorkersworkerActionr;   Nc                 ^   K   t        fd| j                  D               d{    y7 w)zB
        Run an action on all of the workers in the pool.
        c              3   @   K   | ]  }t         |              y wN)r,   ).0workerrT   s     r:   	<genexpr>z(StartedWorkerPool.run.<locals>.<genexpr>   s       
4:M,v./
s   N)r   rS   )selfrT   s    `r:   runzStartedWorkerPool.run   s6       
>Boo
 
 	
 	
 	
s   "-+-c           	        K   t        | j                  D cg c]%  }t        j                  |j	                               ' c}d       d{   }t        |      D ]+  \  }\  }}|r| j                  j                  d| d|       - | j                  dd= | j                  dd= | j                  j                          | j                  j                          yc c}w 7 w)zv
        Shut down all of the workers in the pool.

        The pool is unusable after this method is called.
        T)consumeErrorsNzjoining disttrial worker #z failed)r   rR   r   fromCoroutineexit	enumerate_loggerfailurerS   rQ   closerP   unlock)r[   rY   resultsn	succeededrc   s         r:   joinzStartedWorkerPool.join   s      %AENvX##FKKM2N
 
 (1'9 	W#A#	7$$'A!G%LgV	W LLOOOA! O
s#   C$*C C$C"C$(A;C$)r;   N)r4   r5   r6   r7   r   r   rL   r   r   r	   r/   r0   r   rb   r1   r\   ri   r8   r9   r:   rO   rO   c   sX    $ sm#O+^$$hGl3&7 D "r9   rO   c            	       \    e Zd ZU dZeed<   dee   dee	   de
dee   fdZd Zd	edefd
Zy)
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	protocolsrH   rJ   r;   c                     t        |      D cg c]*  \  }}t        ||j                  t        |            |      , c}}S c c}}w )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.
        )ra   r/   childrM   )r[   rm   rH   rJ   xprotocols         r:   _createLocalWorkerszWorkerPool._createLocalWorkers   sF    *  )3
8 "2"8"8Q"@'J
 	
 
s   /Ac           
         t         d   j                  j                  }ddddddt        dt        di}t
        j                  j                         }t
        j                  j                  t        j                        |d<   |D ]@  }t        j                  |g}|j                  |        ||t        j                  |||       B y	)
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   filePathpathr(   r)   osenvironcopypathsepri   sys
executableextend)	r[   spawnerrm   	argumentsworkertrialPathrx   r}   rY   rw   s	            r:   _launchWorkerProcessesz!WorkerPool._launchWorkerProcesses   s     ((IJSSXXssss
 **//# !#

 9 	WFNNO4DKK	"FCNNgV	Wr9   r?   c                 D  K   t        | j                  j                        \  }}t        | j                  j                        r t        | j                  j                        }n%|j                  | j                  j                        }t        |      }t        | j                  j                        D cg c]  }t                }}| j                  |||      }| j                  |j                  || j                  j                         t        |||||      S c c}w w)z
        Launch all of the workers for this pool.

        @return: A started pool object that can run jobs using the workers.
        )r%   rl   rH   r   rJ   r   preauthChildr&   rangerG   r0   rr   r   spawnProcessrI   rO   )	r[   r?   testDirrP   testLogPathrQ   rp   rS   rR   s	            r:   startzWorkerPool.start   s       4LL)) 
 %%&"4<<#7#78K
 "..t||/C/CDKk*05dll6M6M0NO1n&O
O**

 	##  LL((	
 !
 	
 Ps   B3D 5DAD N)r4   r5   r6   r7   rF   rL   r   r0   r   r   r   r	   r/   rr   r   r   rO   r   r8   r9   r:   rk   rk      sb     
N+
 #3-
 	

 
k	
0W6&
? &
7H &
r9   rk   untilFailureresultc                 *    | xr |j                         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)r   r   s     r:   shouldContinuer     s     2F0022r9   pool	testCasesdriveWorkerc                    K   	 | j                  t        |||             d {    y 7 # t        $ r0 |j                  j	                  t        d      t                      Y y w xY ww)Nz
<runTests>)r\   r   	ExceptionoriginaladdErrorr$   r   )r   r   r   r   s       r:   runTestsr     sT     Fhhw{FI>??? F 	  L!979E	Fs1   A'+ )+ A'+ 6A$!A'#A$$A'c                      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	      
      Zee
d<    ed eej,                        
      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<   defdZ!d Z"dede#e$   de%ddfdZ&	 d$de'e(e)f   dedefdZ*d e'e(e)f   dede	fd!Z+d e'e(e)f   de	fd"Z,d e'e(e)f   de	fd#Z-y)%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_logfile_trial_temp_workingDirectory_workerPoolFactoryr;   c                     | j                  | j                  | j                  | j                        }| j                  rt        |      }| j                  |      S )zL
        Make reporter factory, and wrap it with a L{DistReporter}.
        )realtime)r   r   r   r   r   r#   _distReporterFactory)r[   reporters     r:   _makeResultzDistTrialRunner._makeResultJ  sV     ((KK..9M9M ) 
   5h?H((22r9   c                 $    |j                          y)z
        Write test run final outcome to result.

        @param result: A C{TestResult} which will print errors and the summary.
        N)done)r[   r   s     r:   writeResultszDistTrialRunner.writeResultsU  s     	r9   r   r   rY   c                 N   K   fd}|D ]  } ||       d{     y7 w)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                    K   	 j                  |        d {    y 7 # t        $ r' j                  j                  | t	                      Y y w xY wwrW   )r\   r   r   r   r   )caser   rY   s    r:   taskz*DistTrialRunner._driveWorker.<locals>.taskq  sD     :jjv... :((wy9:s1   A"  " A" -AAAANr8   )r[   r   r   rY   r   r   s    ` `  r:   _driveWorkerzDistTrialRunner._driveWorker]  s-     (	:  	Dt*	s   %#%suiter   c           	         K   t        t        |             j                  t        t	        t               j                        t         j                         j                   j                              } j                  j                  d|j                          d       |j                   j                         d{   t!        t"              }t$        dt&        dt(        f fd       }	 t+        ||       d{   j-                          d{    S 7 _7 7 	# j-                          d{  7   w xY ww)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.
Nrg   r;   c                   K   r"j                   j                  d| dz    d       j                         j                  rfd}nd }t	        t        |      j                         d {    j                         S 7 w)Nz
Test Pass r'   
c                 8    j                   j                         S rW   )r   r   )_r   s    r:   <lambda>z@DistTrialRunner.runAsync.<locals>.runAndReport.<locals>.<lambda>  s    6??+H+H+J r9   c                      yNTr8   )r   s    r:   r   z@DistTrialRunner.runAsync.<locals>.runAndReport.<locals>.<lambda>  s    r9   )r   writer   r   r   r.   r   r   )rg   casesConditionr   r[   startedPoolr   r   s     @r:   runAndReportz.DistTrialRunner.runAsync.<locals>.runAndReport  s      !!Jq1ugR"89%%'F "K!/.)4!!	   f%Ms   A/B3B4B)listr    r   rF   minlenr   r   r   r   r   r   r   countTestCasesr   r   r   r   r+   rK   r*   r-   ri   )r[   r   r   poolStarter	conditionr   r   r   s   ` `   @@r:   runAsynczDistTrialRunner.runAsyncz  s!    " u-.	 --C	ND$4$45//0%%
 	HU%9%9%;$<IFG (--dmm<< NL9	 
	# 	, 	 
	0	% &i>> ""$$$M =F ? %+""$$$sZ   CED'2E;D- 
D)D- E!D+"E)D- +E-EEEEtestc                 B    d ddt         t        t        f   dd ffd}dt        t        t
              ffd}dt
        dt
        f fd} j                  j                  dd	|       t	        j                   j                  ||            j                  |      j                  |       j                  j                          t        t              rj                          t        t              s
J  d
       t        t        j                         S )NFru   r;   c                 
    | y rW   r8   )ru   r   s    r:   capturez%DistTrialRunner._run.<locals>.capture  s    Fr9   c                  2    d j                          S y r   )cancel)reactorStoppingr   testsInProgresss   r:   maybeStopTestsz,DistTrialRunner._run.<locals>.maybeStopTests  s"    "O~&&(&&r9   r   c                 @    sj                   j                          | S rW   )r   stop)r   r   r[   s    r:   maybeStopReactorz.DistTrialRunner._run.<locals>.maybeStopReactor  s    """$Mr9   beforeshutdownz is not DistReporter)r   r   r*   r
   r   objectr   addSystemEventTriggerr_   r   addBothr\   
isinstanceraiseExceptionr   r!   r   )	r[   r   r   r   r   r   r   r   r   s	   `     @@@r:   _runzDistTrialRunner._run  s    59 %	uWl23 	 		&)9 : 		V 	 	
 	++Hj.Q ""4==|#DEWWW%& 	 	fg&!!#
 &,/PF8;O1PP/ Iv//r9   c                 (    | j                  |d      S )za
        Run a reactor and a test suite.

        @param test: The test or suite to run.
        Fr   r   r[   r   s     r:   r\   zDistTrialRunner.run  s     yyEy22r9   c                 (    | j                  |d      S )z|
        Run the tests with local worker processes until they fail.

        @param test: The test or suite to run.
        Tr   r   r   s     r:   runUntilFailurezDistTrialRunner.runUntilFailure  s     yyDy11r9   )F).r4   r5   r6   r7   r*   r   r   rb   r   r!   rL   rK   r	   rM   r   boolr   r   rD   r   r3   r   stdoutr   r   r   r   r   r   r   rk   r   rF   r   r   r   r"   r0   r   r   r   r   r   r   r\   r   r8   r9   r:   r   r   !  s    (hG sI~..3iJ"'!/:#H  4?3::3NOFFO%c%!OT!"d"Hc*s*CM"2!3Z!?@M	3\ 	3 I& 	
 
@ #J%Xy()J% J% 
	J%X*0x23 *04 *0I *0X3h	12 3y 32E(I*=$> 29 2r9   r   )Or7   r|   r   	functoolsr   os.pathr   typingr   r   r   r   r	   r
   r   r   r   r   unittestr   r   attrsr   r   r   attrs.convertersr   twisted.internet.deferr   r   r   twisted.internet.interfacesr   r   twisted.loggerr   twisted.python.failurer   twisted.python.filepathr   twisted.python.lockfiler   twisted.python.modulesr   _asyncrunnerr    itrialr!   r"   r   r#   runnerr$   utilr%   r&    r(   r)   distreporterr*   
functionalr+   r,   r-   r.   rY   r/   r0   r1   r3   rD   rF   rO   rk   r   r   r   r   r8   r9   r:   <module>r      sl  
 
 
     ) ' ' , H H E ! * , 2 0 ( ) 5  4 3 & M M = =o E* E(   * 5" 5" 5"p b
 b
 b
J
3 
3y 
3T 
3F
F	"F F 	x	*N;Yt_L	F 
F$ ^2 ^2 ^2r9   