
    Ϫf$                         d 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}.
    )proxyForInterface)callget)Failure)SynchronousTestCase   )AlreadyQuitIWorkerTeamcreateMemoryWorkerc                   (     e Zd ZdZd Z 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      A/usr/lib/python3/dist-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   )__name__
__module____qualname____doc__r   r   __classcell__)r   s   @r   r   r      s    6 6r   r   r   c                   p    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zy)	TeamTestsz
    Tests for L{Team}
    c                      t               \  } _        t        |d       _        g  _        g  _        g  _        g  _        d  _         fd}g  _	         fd}t        |||       _        y)zl
        Set up a L{Team} with inspectable, synchronous workers that can be
        single-stepped.
        coordinatorworkerc                       y)NF r,   r   r   r   z!TeamTests.setUp.<locals>.<lambda>5       r   c                     j                         ry t               \  } j                  j                         j                  j                         t        | t        j                              j                  j                         j                  j                         j                  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>.quitAndRemoveB   s0    
%%,,R0%%,,Y7r   )
noMoreWorkersr   workerPerformersappendr2   r   lenallWorkersEverr0   quit)r*   r6   r3   r4   r5   r   s     @@@r   createWorkerz%TeamTests.setUp.<locals>.createWorker7   s    !!# 2 4FI!!((3!!((3!&T5J5J1KLB&&r*!!((,wwH8
 $BGIr   c                  L     j                   j                  t                      y r   )failuresr9   r   r   s   r   logExceptionz%TeamTests.setUp.<locals>.logExceptionL   s    MM  +r   N)r   coordinateOncer   r(   r8   r;   r0   r2   r7   r?   r   team)r   r(   r=   rA   s   `   r   setUpzTeamTests.setUp*   sq    
 ,>+?(T(+KN "  " "*	& 	, lLA	r   c                 P    d}| j                         rd}| j                         r|S )a  
        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}).
        @rtype: L{bool}
        FT)rB   )r   dids     r   
coordinatezTeamTests.coordinateQ   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)rG   r8   r2   )r   
continuingr4   s      r   performAllOutstandingWorkz#TeamTests.performAllOutstandingWork_   sX    
 
*J!22  	 5 55K  $8t'8J r   c                    fd| j                   j                         | j                          | j                  | j                   j	                         j
                  d       | j                          | j                  j                  d       | j                  | j                   j	                         j
                  d       y)zd
        L{Team.do} does the work in a worker created by the createWorker
        callable.
        c                  &    t        d       _        y )Nr*   )r   who	somethings   r   rO   z4TeamTests.test_doDoesWorkInWorker.<locals>.somethingr   s    MIMr      r   N)rC   r   rG   assertEqual
statisticsbusyWorkerCountrJ   rM   )r   rO   s    @r   test_doDoesWorkInWorkerz!TeamTests.test_doDoesWorkInWorkerl   s    	* 			Y--/??C&&(*--/??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)rC   rR   rQ   idleWorkerCountrS   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)rC   growrJ   rQ   r:   r8   r@   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:   r;   r@   s   r   r   z0TeamTests.test_growCreateLimit.<locals>.<lambda>   s    S)<)<%=%B r   r[   r`   N)	r7   rC   r\   rJ   rQ   r:   r;   rR   rV   r@   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[   r`   r   N)rC   r\   rJ   shrinkrQ   r:   r0   r@   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)rC   r\   rJ   rQ   r:   r0   rc   r@   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                          fd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	                  j                  d       y)z
        When no additional workers are available, the given work is backlogged,
        and then performed later when the work was.
        r`   c                  0     xj                   dz  c_         y )NrP   )timesrN   s   r   rO   z@TeamTests.test_moreWorkWhenNoWorkersAvailable.<locals>.something   s    OOq Or   r   c                       y)NTr,   r,   r   r   r   z?TeamTests.test_moreWorkWhenNoWorkersAvailable.<locals>.<lambda>   r-   r   rP      N)rC   r\   rG   rj   rQ   rR   rV   ranger   r7   rW   rJ   )r   irO   s     @r   #test_moreWorkWhenNoWorkersAvailablez-TeamTests.test_moreWorkWhenNoWorkersAvailable   sM   
 			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 )NrP   r   r,   r,   r   r   r   z0TeamTests.test_exceptionInTask.<locals>.<lambda>   s
    QU r   rP   r   N)rC   r   rJ   rQ   r:   r?   typeZeroDivisionErrorr@   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)rC   r<   assertRaisesr	   r   listr@   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.
        rf   r   N)rm   rC   r   rw   rJ   r<   rQ   r:   r0   rv   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.
        rf   r[   r   N)rC   r\   rm   r   rw   rG   r<   rQ   r:   r0   rJ   rv   r	   r(   rz   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                   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   )rJ   )originalSetr   s   r   performWorkConcurrentlyzOTeamTests.test_quitConcurrentWithWorkHappening.<locals>.performWorkConcurrently  s    M**,r   N)rC   r   rw   _quitsetr<   rv   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.
        rf      r`   N)
rm   rC   r   rw   rG   rQ   r:   r0   rc   rJ   rz   s     r   test_shrinkWhenBusyzTeamTests.test_shrinkWhenBusy  s    
 r 	AIILL	T223R8		&&(T223Q7r   N)r    r!   r"   r#   rD   rG   rJ   rT   rY   r]   ra   rd   rg   ro   rt   rx   r|   r~   r   r   r,   r   r   r&   r&   %   s\    %BN9D 78	D8
8-8	C;>> ;"8r   r&   N)r#   twisted.python.componentsr   twisted.python.contextr   r   twisted.python.failurer   twisted.trial.unittestr    r	   r
   r   r   r   r&   r,   r   r   <module>r      sA   
 8 , * 6 = =6(-@ 6*t8# t8r   