
    Vh&                        d 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mZmZ  G d
 d eed            Z G d de      Zy)z&
Tests for L{twisted._threads._team}.
    )annotations)Callable)proxyForInterface)callget)Failure)SynchronousTestCase   )AlreadyQuitIWorkerTeamcreateMemoryWorkerc                  ,     e Zd ZdZddZd fdZ xZS )ContextualWorkerz:
    A worker implementation that supplies a context.
    c                     || _         || _        y)z:
        Create with a real worker and a context.
        N)_realWorker_context)self
realWorkerctxs      O/home/dcms/DCMS/lib/python3.12/site-packages/twisted/_threads/test/test_team.py__init__zContextualWorker.__init__   s     &    c                0     t             fd       y)z
        Perform the given work with the context given to __init__.

        @param work: the work to pass on to the real worker.
        c                 0    t         j                        S N)r   r   )r   works   r   <lambda>z%ContextualWorker.do.<locals>.<lambda>%   s    4t4 r   N)superdo)r   r   	__class__s   ``r   r    zContextualWorker.do   s     	
45r   )r   r   r   objectreturnNone)r   zCallable[[], object]r#   r$   )__name__
__module____qualname____doc__r   r    __classcell__)r!   s   @r   r   r      s    6 6r   r   r   c                      e Zd ZdZddZddZddZddZddZddZ	ddZ
dd	Zdd
ZddZddZddZddZddZddZddZy)	TeamTestsz
    Tests for L{Team}
    c                     t               \  } _        t        |d       _        g  _        g  _        g  _        g  _        d  _        d fd}g  _	        d fd}t        |||       _        y)	zl
        Set up a L{Team} with inspectable, synchronous workers that can be
        single-stepped.
        coordinatorworkerc                      y)NF r1   r   r   r   z!TeamTests.setUp.<locals>.<lambda>8       r   c                    j                         ry t               \  } j                  j                         j                  j                         t        | t        j                              j                  j                         j                  j                         j                  dfd}|_	        S )Nr.   c                              j                   j                          j                  j                         y r   )allUnquitWorkersremoveactivePerformers)cw	performerrealQuitr   s   r   quitAndRemovez<TeamTests.setUp.<locals>.createWorker.<locals>.quitAndRemoveE   s0    
%%,,R0%%,,Y7r   r#   r$   )
noMoreWorkersr   workerPerformersappendr7   r   lenallWorkersEverr5   quit)r/   r;   r8   r9   r:   r   s     @@@r   createWorkerz%TeamTests.setUp.<locals>.createWorker:   s    !!# 2 4FI!!((3!!((3!&T5J5J1KLB&&r*!!((,wwH8 8
 $BGIr   c                 L     j                   j                  t                      y r   )failuresr?   r   r   s   r   logExceptionz%TeamTests.setUp.<locals>.logExceptionO   s    MM  +r   N)r#   zContextualWorker | Noner<   )r   coordinateOncer   r-   r>   rA   r5   r7   r=   rE   r   team)r   r-   rC   rG   s   `   r   setUpzTeamTests.setUp-   sq    
 ,>+?(T(+KN<>688:<>*	& (*	, lLA	r   c                P    d}| j                         rd}| j                         r|S )z
        Perform all work currently scheduled in the coordinator.

        @return: whether any coordination work was performed; if the
            coordinator was idle when this was called, return L{False}
            (otherwise L{True}).
        FT)rH   )r   dids     r   
coordinatezTeamTests.coordinateT   s-     !!#C !!#
r   c                    d}|rO| j                         }| j                  D ]  }|| j                  v s |         |xs | j                         }|rNyy)zj
        Perform all work on the coordinator and worker performers that needs to
        be done.
        TN)rM   r>   r7   )r   
continuingr9   s      r   performAllOutstandingWorkz#TeamTests.performAllOutstandingWorka   sX    
 
*J!22  	 5 55K  $8t'8J r   c                   ddfd}| j                   j                  |       | j                          | j                  | j                   j	                         j
                  d       | j                          | j                  d       | j                  | j                   j	                         j
                  d       y)zd
        L{Team.do} does the work in a worker created by the createWorker
        callable.
        Nc                     t        d       y )Nr/   )r   )whos   r   	somethingz4TeamTests.test_doDoesWorkInWorker.<locals>.somethingu   s    h-Cr      r   r<   )rI   r    rM   assertEqual
statisticsbusyWorkerCountrP   )r   rT   rS   s     @r   test_doDoesWorkInWorkerz!TeamTests.test_doDoesWorkInWorkern   s    
 	  			Y--/??C&&(a --/??Cr   c                    | j                   j                         }| j                  |j                  d       | j                  |j                  d       | j                  |j
                  d       y)z
        L{Team.statistics} returns an object with idleWorkerCount,
        busyWorkerCount, and backloggedWorkCount integer attributes.
        r   N)rI   rW   rV   idleWorkerCountrX   backloggedWorkCount)r   statss     r   test_initialStatisticsz TeamTests.test_initialStatistics   sX    
 		$$&..2..222A6r   c                    | j                   j                  d       | j                          | j                  t	        | j
                        d       y)zN
        L{Team.grow} increases the number of available idle workers.
           N)rI   growrP   rV   r@   r>   rF   s    r   test_growCreatesIdleWorkersz%TeamTests.test_growCreatesIdleWorkers   s;     			q&&(T223Q7r   c                "     fd _          j                  j                  d        j                           j	                  t         j                        d        j	                   j                  j                         j                  d       y)z
        L{Team.grow} increases the number of available idle workers until the
        C{createWorker} callable starts returning None.
        c                 4    t         j                        dk\  S )N   )r@   rA   rF   s   r   r   z0TeamTests.test_growCreateLimit.<locals>.<lambda>   s    S)<)<%=%B r   r`   re   N)	r=   rI   ra   rP   rV   r@   rA   rW   r[   rF   s   `r   test_growCreateLimitzTeamTests.test_growCreateLimit   sh    
 C		q&&(T00115--/??Cr   c                    | j                   j                  d       | j                          | j                   j                  d       | j                          | j	                  t        | j                        d       y)zG
        L{Team.shrink} will quit the given number of workers.
        r`   re   r
   N)rI   ra   rP   shrinkrV   r@   r5   rF   s    r   test_shrinkQuitsWorkersz!TeamTests.test_shrinkQuitsWorkers   sY     			q&&(		&&(T223Q7r   c                   | j                   j                  d       | j                          | j                  t	        | j
                        d       | j                   j                          | j                  t	        | j
                        d       | j                          | j                  t	        | j
                        d       y)zU
        L{Team.shrink} with no arguments will stop all outstanding workers.
        
   r   N)rI   ra   rP   rV   r@   r5   rh   rF   s    r   test_shrinkToZerozTeamTests.test_shrinkToZero   s     			r&&(T223R8		T223R8&&(T223Q7r   c                   | j                   j                  d       | j                          ddfd}| j                  | j                   j	                         j
                  d       t        d      D ]  }| j                   j                  |        | j                          | j                  | j                   j	                         j
                  d       d | _        | j                   j                  |       | j                          | j                  | j                   j	                         j
                  d       | j                  | j                   j	                         j                  d       | j                          | j                  | j                   j	                         j                  d       | j                  d       y)	z
        When no additional workers are available, the given work is backlogged,
        and then performed later when the work was.
        re   r   c                      dz   y )NrU   r1   )timess   r   rT   z@TeamTests.test_moreWorkWhenNoWorkersAvailable.<locals>.something   s    QJEr   c                      y)NTr1   r1   r   r   r   z?TeamTests.test_moreWorkWhenNoWorkersAvailable.<locals>.<lambda>   r2   r   rU      Nr<   )rI   ra   rM   rV   rW   r[   ranger    r=   r\   rP   )r   rT   iro   s      @r   #test_moreWorkWhenNoWorkersAvailablez-TeamTests.test_moreWorkWhenNoWorkersAvailable   sG   
 			q	 	--/??Cq 	$AIILL#	$ 	--/??C)		Y--/??C--/CCQG&&(--/CCQG"r   c                    | j                   j                  d        | j                          | j                  t	        | j
                        d       | j                  | j
                  d   j                  t               y)z
        When an exception is raised in a task passed to L{Team.do}, the
        C{logException} given to the L{Team} at construction is invoked in the
        exception context.
        c                     ddz  S )NrU   r   r1   r1   r   r   r   z0TeamTests.test_exceptionInTask.<locals>.<lambda>   s
    QU r   rU   r   N)rI   r    rP   rV   r@   rE   typeZeroDivisionErrorrF   s    r   test_exceptionInTaskzTeamTests.test_exceptionInTask   sY     			]#&&(T]]+Q/q)..0ABr   c                    | j                   j                          | j                  t        | j                   j                         | j                  t        | j                   j                  t
               y)zx
        L{Team.quit} causes future invocations of L{Team.do} and L{Team.quit}
        to raise L{AlreadyQuit}.
        N)rI   rB   assertRaisesr   r    listrF   s    r   	test_quitzTeamTests.test_quit   sD    
 			+tyy~~6+tyy||T:r   c                t   t        d      D ]!  }| j                  j                  t               # | j	                          | j                  j                          | j	                          | j                  t        | j                        d       | j                  t        | j                  j
                         y)zk
        L{Team.quit} causes all idle workers, as well as the coordinator
        worker, to quit.
        rk   r   N)rr   rI   r    r|   rP   rB   rV   r@   r5   r{   r   r-   r   xs     r   test_quitQuitszTeamTests.test_quitQuits   s    
 r 	AIILL	&&(		&&(T223Q7+t'7'7'<'<=r   c                   | j                   j                  d       t        d      D ]!  }| j                   j                  t               # | j                          | j                   j                          | j                          | j                  t        | j                        d       | j                          | j                  t        | j                        d       | j                  t        | j                  j                         y)z|
        L{Team.quit} causes all busy workers to be quit once they've finished
        the work they've been given.
        rk   r`   r   N)rI   ra   rr   r    r|   rM   rB   rV   r@   r5   rP   r{   r   r-   r   s     r   test_quitQuitsLaterWhenBusyz%TeamTests.test_quitQuitsLaterWhenBusy   s    
 			rq 	AIILL			T223Q7&&(T223Q7+t'7'7'<'<=r   c                     j                   j                  t                j                   j                  j                  d fd}| j                   j                  _         j                   j                           j                  t         j                   j
                          j                  t         j                   j                  t               y)z
        If work happens after L{Team.quit} sets its C{Quit} flag, but before
        any other work takes place, the L{Team} should still exit gracefully.
        c                 4              j                          y r   )rP   )originalSetr   s   r   performWorkConcurrentlyzOTeamTests.test_quitConcurrentWithWorkHappening.<locals>.performWorkConcurrently	  s    M**,r   Nr<   )rI   r    r|   _quitsetrB   r{   r   )r   r   r   s   ` @r   $test_quitConcurrentWithWorkHappeningz.TeamTests.test_quitConcurrentWithWorkHappening  s    
 			Tiioo))	- 6				+tyy~~6+tyy||T:r   c                l   t        d      D ]!  }| j                  j                  t               # | j	                          | j                  t        | j                        d       | j                  j                  d       | j                          | j                  t        | j                        d       y)zl
        L{Team.shrink} will wait for busy workers to finish being busy and then
        quit them.
        rk      re   N)
rr   rI   r    r|   rM   rV   r@   r5   rh   rP   r   s     r   test_shrinkWhenBusyzTeamTests.test_shrinkWhenBusy  s    
 r 	AIILL	T223R8		&&(T223Q7r   Nr<   )r#   bool)r%   r&   r'   r(   rJ   rM   rP   rY   r^   rb   rf   ri   rl   rt   ry   r}   r   r   r   r   r1   r   r   r+   r+   (   s\    %BN9D$78	D8
8#:	C;>> ;"8r   r+   N)r(   
__future__r   typingr   twisted.python.componentsr   twisted.python.contextr   r   twisted.python.failurer   twisted.trial.unittestr	    r   r   r   r   r   r+   r1   r   r   <module>r      sG    #  7 , * 6 = =6(-@ 6*v8# v8r   