U
    n5{i�V  ã                   @   sÒ   d Z ddlZddlZddlZddlZddlZddlmZmZ ddl	m
Z
mZmZmZ ddlmZ G dd„ dƒZe e¡ G dd	„ d	ejƒZG d
d„ dejƒZG dd„ dejƒZG dd„ dƒZG dd„ dejƒZdS )z(
Tests for L{twisted.python.threadpool}
é    N)ÚTeamÚcreateMemoryWorker)ÚcontextÚfailureÚ
threadableÚ
threadpool)Úunittestc                   @   s&   e Zd ZdZdd„ Zdd„ ZdgZdS )ÚSynchronizationr   c                 C   s    || _ || _t ¡ | _g | _d S ©N)ÚNÚwaitingÚ	threadingÚLockÚlockÚruns)Úselfr   r   © r   ú@/tmp/pip-unpacked-wheel-mnhg7r0q/twisted/test/test_threadpool.pyÚ__init__   s    
zSynchronization.__init__c                 C   s|   | j  d¡r0t| jƒd s$t d¡ | j  ¡  n|  jd7  _| j  ¡  | j d ¡ t| jƒ| j	krn| j
 ¡  | j  ¡  d S )NFé   g-Cëâ6*?é   )r   ÚacquireÚlenr   ÚtimeÚsleepÚreleaseÚfailuresÚappendr   r   ©r   r   r   r   Úrun   s    


zSynchronization.runr   N)Ú__name__Ú
__module__Ú__qualname__r   r   r   Zsynchronizedr   r   r   r   r	      s   r	   c                   @   s®   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d"d#„ Zd$d%„ Zd&d'œd(d)„Zd&S )*ÚThreadPoolTestsz
    Test threadpools.
    c                 C   s   dS )zD
        Return number of seconds to wait before giving up.
        r   r   r   r   r   r   Ú
getTimeout@   s    zThreadPoolTests.getTimeoutc                 C   s8   t dƒ}|D ]}| d¡r q4t d¡ q|  d¡ d S )Ni@B Fgñhãˆµøä>z%A long time passed without succeeding)Úranger   r   r   Úfail)r   r   ÚitemsÚir   r   r   Ú_waitForLockF   s    
zThreadPoolTests._waitForLockc                 C   s,   t  dd¡}|  |jd¡ |  |jd¡ dS )zy
        L{ThreadPool.min} and L{ThreadPool.max} are set to the values passed to
        L{ThreadPool.__init__}.
        é   é   N)r   Ú
ThreadPoolÚassertEqualÚminÚmax©r   Úpoolr   r   r   Útest_attributesO   s    zThreadPoolTests.test_attributesc                 C   sz   t  dd¡}| ¡  |  |j¡ |  t|jƒd¡ t  dd¡}|  t|jƒd¡ | ¡  |  |j¡ |  t|jƒd¡ dS )zV
        L{ThreadPool.start} creates the minimum number of threads specified.
        r   r   é   é
   N)r   r,   ÚstartÚ
addCleanupÚstopr-   r   Úthreadsr0   r   r   r   Ú
test_startX   s    zThreadPoolTests.test_startc                 C   s<   t  dd¡}| ¡  | ¡  | d¡ |  t|jƒd¡ dS )z�
        L{ThreadPool.adjustPoolsize} only modifies the pool size and does not
        start new workers while the pool is not running.
        r   r   é   N)r   r,   r5   r7   ZadjustPoolsizer-   r   r8   r0   r   r   r   Útest_adjustingWhenPoolStoppedg   s
    
z-ThreadPoolTests.test_adjustingWhenPoolStoppedc                 C   s´   t  dd¡}| ¡  |  |j¡ |  |jg ¡ dd„ }G dd„ dƒ}|ƒ }t |¡}t |¡}| 	||¡ t
 ¡ }| 	|j¡ | |  ¡ ¡ ~~t ¡  |  |ƒ ¡ |  |ƒ ¡ dS )zü
        Test that creating threads in the threadpool with application-level
        objects as arguments doesn't results in those objects never being
        freed, with the thread maintaining a reference to them as long as it
        exists.
        r   r   c                 S   s   d S r
   r   )Úargr   r   r   Úworker�   s    z<ThreadPoolTests.test_threadCreationArguments.<locals>.workerc                   @   s   e Zd ZdS )z:ThreadPoolTests.test_threadCreationArguments.<locals>.DumbN©r    r!   r"   r   r   r   r   ÚDumb…   s   r?   N)r   r,   r5   r6   r7   r-   r8   ÚweakrefÚrefÚcallInThreadr   ÚEventÚsetÚwaitr$   ÚgcÚcollectÚassertIsNone)r   Útpr=   r?   ÚuniqueÚ	workerRefÚ	uniqueRefÚeventr   r   r   Útest_threadCreationArgumentsr   s$    

z,ThreadPoolTests.test_threadCreationArgumentsc                    s*  t  dd¡}| ¡  ˆ |j¡ ˆ |jg ¡ i ‰t ¡ ‰t ¡ ‰g ‰‡‡‡‡‡‡‡fdd„}‡ fdd„}G dd„ dƒ‰ ˆ ƒ }t	 
|¡}t	 
|¡‰t	 
|¡‰|j||||d	� ~~ˆ ¡  ˆ ˆ ¡ ¡ t ¡  ˆ ˆƒ ¡ ˆ ˆƒ ¡ ~t ¡  ˆ |ƒ ¡ ˆ ˆd ƒ ¡ ˆ tˆ ¡ ƒd
d
g¡ d
S )ze
        As C{test_threadCreationArguments} above, but for
        callInThreadWithCallback.
        r   r   c                    sF   t  ¡  ˆ ˆ ¡ ¡ ˆƒ ˆd< ˆƒ ˆd< ˆ  ¡  ˆ t |¡¡ d S )NrK   rL   )rF   rG   rE   r$   rD   r   r@   rA   ©ÚsuccessÚresult)ÚonResultDoneÚonResultWaitÚrefdictÚ	resultRefr   rL   rK   r   r   ÚonResult²   s    

zVThreadPoolTests.test_threadCreationArgumentsCallInThreadWithCallback.<locals>.onResultc                    s   ˆ ƒ S r
   r   )r<   Útest)r?   r   r   r=   ½   s    zTThreadPoolTests.test_threadCreationArgumentsCallInThreadWithCallback.<locals>.workerc                   @   s   e Zd ZdS )zRThreadPoolTests.test_threadCreationArgumentsCallInThreadWithCallback.<locals>.DumbNr>   r   r   r   r   r?   Á   s   r?   )rW   N)r   r,   r5   r6   r7   r-   r8   r   rC   r@   rA   ÚcallInThreadWithCallbackrD   rE   r$   rF   rG   rH   ÚlistÚvalues)r   rI   rV   r=   rJ   ZonResultRefr   )r?   rR   rS   rT   rU   r   rL   rK   r   Ú4test_threadCreationArgumentsCallInThreadWithCallbackœ   s8    


zDThreadPoolTests.test_threadCreationArgumentsCallInThreadWithCallbackc                 C   sX   t  dd¡}|  |jd¡ |  |jd¡ t t |¡¡}|  |jd¡ |  |jd¡ dS )z…
        Threadpools can be pickled and unpickled, which should preserve the
        number of threads and other parameters.
        é   é   N)r   r,   r-   r.   r/   ÚpickleÚloadsÚdumps)r   r1   Úcopyr   r   r   Útest_persistenceæ   s    z ThreadPoolTests.test_persistencec                 C   sx   d}t  ¡ }| ¡  |  |j¡ t ¡ }| ¡  t||ƒ}t	|ƒD ]}|||ƒ qB|  
|¡ |  |jd|j› d�¡ dS )z 
        Test synchronization of calls made with C{method}, which should be
        one of the mechanisms of the threadpool to execute work in threads.
        r4   zrun() re-entered z timesN)r   r,   r5   r6   r7   r   r   r   r	   r%   r)   ÚassertFalser   )r   Úmethodr   rI   r   Úactorr(   r   r   r   Ú_threadpoolTestö   s    	

zThreadPoolTests._threadpoolTestc                 C   s   |   dd„ ¡S )z?
        Call C{_threadpoolTest} with C{callInThread}.
        c                 S   s   |   |j¡S r
   )rB   r   )rI   re   r   r   r   Ú<lambda>  ó    z3ThreadPoolTests.test_callInThread.<locals>.<lambda>)rf   r   r   r   r   Útest_callInThread  s    z!ThreadPoolTests.test_callInThreadc                    s`   G dd„ dt ƒ‰ ‡ fdd„}t dd¡}| |¡ | ¡  | ¡  |  ˆ ¡}|  t|ƒd¡ dS )zi
        L{ThreadPool.callInThread} logs exceptions raised by the callable it
        is passed.
        c                   @   s   e Zd ZdS )z<ThreadPoolTests.test_callInThreadException.<locals>.NewErrorNr>   r   r   r   r   ÚNewError  s   rj   c                      s
   ˆ ƒ ‚d S r
   r   r   ©rj   r   r   Ú
raiseError  s    z>ThreadPoolTests.test_callInThreadException.<locals>.raiseErrorr   r   N)	Ú	Exceptionr   r,   rB   r5   r7   ÚflushLoggedErrorsr-   r   )r   rl   rI   Úerrorsr   rk   r   Útest_callInThreadException  s    

z*ThreadPoolTests.test_callInThreadExceptionc                    s‚   t  ¡ ‰ˆ ¡  g ‰ ‡ ‡fdd„}t dd¡}| |dd„ ¡ | ¡  z|  ˆ¡ W 5 | ¡  X |  	ˆ d ¡ |  
ˆ d d¡ dS )	zÀ
        L{ThreadPool.callInThreadWithCallback} calls C{onResult} with a
        two-tuple of C{(True, result)} where C{result} is the value returned
        by the callable supplied.
        c                    s    ˆ  ¡  ˆ  | ¡ ˆ  |¡ d S r
   ©r   r   rO   ©ÚresultsÚwaiterr   r   rV   5  s    
z?ThreadPoolTests.test_callInThreadWithCallback.<locals>.onResultr   r   c                   S   s   dS )NrW   r   r   r   r   r   rg   ;  rh   z?ThreadPoolTests.test_callInThreadWithCallback.<locals>.<lambda>rW   N)r   r   r   r   r,   rX   r5   r7   r)   Ú
assertTruer-   )r   rV   rI   r   rr   r   Útest_callInThreadWithCallback*  s    
z-ThreadPoolTests.test_callInThreadWithCallbackc                    s²   G dd„ dt ƒ‰ ‡ fdd„}t ¡ ‰ˆ ¡  g ‰‡‡fdd„}t dd¡}| ||¡ | ¡  z|  	ˆ¡ W 5 | ¡  X |  
ˆd ¡ |  ˆd tj¡ |  tˆd jˆ ƒ¡ d	S )
zÍ
        L{ThreadPool.callInThreadWithCallback} calls C{onResult} with a
        two-tuple of C{(False, failure)} where C{failure} represents the
        exception raised by the callable supplied.
        c                   @   s   e Zd ZdS )zRThreadPoolTests.test_callInThreadWithCallbackExceptionInCallback.<locals>.NewErrorNr>   r   r   r   r   rj   M  s   rj   c                      s
   ˆ ƒ ‚d S r
   r   r   rk   r   r   rl   P  s    zTThreadPoolTests.test_callInThreadWithCallbackExceptionInCallback.<locals>.raiseErrorc                    s    ˆ  ¡  ˆ  | ¡ ˆ  |¡ d S r
   rq   rO   rr   r   r   rV   X  s    
zRThreadPoolTests.test_callInThreadWithCallbackExceptionInCallback.<locals>.onResultr   r   N)rm   r   r   r   r   r,   rX   r5   r7   r)   rc   ZassertIsInstancer   ZFailureru   Ú
issubclassÚtype)r   rl   rV   rI   r   )rj   rs   rt   r   Ú0test_callInThreadWithCallbackExceptionInCallbackF  s    
z@ThreadPoolTests.test_callInThreadWithCallbackExceptionInCallbackc                    s¶   G dd„ dt ƒ‰ t ¡ }| ¡  g ‰‡ ‡fdd„}t dd¡}| |dd„ ¡ | |j¡ | 	¡  z|  |¡ W 5 | 
¡  X |  ˆ ¡}|  t|ƒd¡ |  ˆd ¡ |  ˆd ¡ d	S )
zj
        L{ThreadPool.callInThreadWithCallback} logs the exception raised by
        C{onResult}.
        c                   @   s   e Zd ZdS )zRThreadPoolTests.test_callInThreadWithCallbackExceptionInOnResult.<locals>.NewErrorNr>   r   r   r   r   rj   p  s   rj   c                    s   ˆ  | ¡ ˆ  |¡ ˆ ƒ ‚d S r
   )r   rO   ©rj   rs   r   r   rV   x  s    

zRThreadPoolTests.test_callInThreadWithCallbackExceptionInOnResult.<locals>.onResultr   r   c                   S   s   d S r
   r   r   r   r   r   rg   ~  rh   zRThreadPoolTests.test_callInThreadWithCallbackExceptionInOnResult.<locals>.<lambda>N)rm   r   r   r   r   r,   rX   rB   r   r5   r7   r)   rn   r-   r   ru   rH   )r   rt   rV   rI   ro   r   rz   r   Ú0test_callInThreadWithCallbackExceptionInOnResultj  s     

z@ThreadPoolTests.test_callInThreadWithCallbackExceptionInOnResultc                    sˆ   g ‰t  ¡ ‰ ‡ ‡fdd„}‡fdd„}t dd¡}| ||¡ | ¡  |  |j¡ ˆ  |  	¡ ¡ |  
tˆƒd¡ |  
ˆd ˆd ¡ dS )	z�
        L{ThreadPool.callInThreadWithCallback} calls the function it is
        given and the C{onResult} callback in the same thread.
        c                    s   ˆ  t ¡ j¡ ˆ  ¡  d S r
   )r   r   Úcurrent_threadÚidentrD   rO   ©rM   Ú	threadIdsr   r   rV   –  s    z5ThreadPoolTests.test_callbackThread.<locals>.onResultc                      s   ˆ   t ¡ j¡ d S r
   )r   r   r|   r}   r   )r   r   r   Úfuncš  s    z1ThreadPoolTests.test_callbackThread.<locals>.funcr   r   r:   N)r   rC   r   r,   rX   r5   r6   r7   rE   r$   r-   r   )r   rV   r€   rI   r   r~   r   Útest_callbackThread�  s    z#ThreadPoolTests.test_callbackThreadc                    s¬   t j ¡ jd }d|d< g ‰ t ¡ ‰‡ ‡fdd„}‡ fdd„}t dd	¡}| ||¡ | 	¡  |  
|j¡ ˆ |  ¡ ¡ |  tˆ ƒd
¡ |  |ˆ d ¡ |  |ˆ d	 ¡ dS )z±
        The context L{ThreadPool.callInThreadWithCallback} is invoked in is
        shared by the context the callable and C{onResult} callback are
        invoked in.
        éÿÿÿÿzthis must be presentZtestingc                    s&   t j ¡ jd }ˆ  |¡ ˆ ¡  d S ©Nr‚   )r   ÚtheContextTrackerÚcurrentContextÚcontextsr   rD   )rP   rQ   Úctx©r†   rM   r   r   rV   ³  s    
z6ThreadPoolTests.test_callbackContext.<locals>.onResultc                     s   t j ¡ jd } ˆ  | ¡ d S rƒ   )r   r„   r…   r†   r   )r‡   )r†   r   r   r€   ¸  s    z2ThreadPoolTests.test_callbackContext.<locals>.funcr   r   r:   N)r   r„   r…   r†   r   rC   r   r,   rX   r5   r6   r7   rE   r$   r-   r   )r   ZmyctxrV   r€   rI   r   rˆ   r   Útest_callbackContext¦  s    z$ThreadPoolTests.test_callbackContextc                 C   sN   t  ¡ }| ¡  t dd¡}| |j¡ | ¡  z|  	|¡ W 5 | ¡  X dS )zÃ
        Work added to the threadpool before its start should be executed once
        the threadpool is started: this is ensured by trying to release a lock
        previously acquired.
        r   r   N)
r   r   r   r   r,   rB   r   r5   r7   r)   )r   rt   rI   r   r   r   Útest_existingWorkÇ  s    z!ThreadPoolTests.test_existingWorkc                    sü   t  dd¡}| ¡  |  |j¡ |  |jd¡ |  t|jƒd¡ |  t|j	ƒd¡ t
 ¡ ‰t
 ¡ ‰ ‡ ‡fdd„}| |¡ ˆ d¡ |  |jd¡ |  t|jƒd¡ |  t|j	ƒd¡ ˆ  ¡  t|jƒsÔt d¡ q¾|  t|jƒd¡ |  t|j	ƒd¡ dS )z{
        As the worker receives and completes work, it transitions between
        the working and waiting states.
        r   r   c                      s   ˆ  ¡  ˆ  d¡ d S )Nr4   )rD   rE   r   ©ZthreadFinishZthreadWorkingr   r   Ú_threadë  s    z;ThreadPoolTests.test_workerStateTransition.<locals>._threadr4   gü©ñÒMb@?N)r   r,   r5   r6   r7   r-   Úworkersr   ÚwaitersZworkingr   rC   rB   rE   rD   r   r   )r   r1   rŒ   r   r‹   r   Útest_workerStateTransitionÙ  s&    


z*ThreadPoolTests.test_workerStateTransitionN)Úreturnc                 C   s"   t  dd¡}|  |j ¡ d¡ dS )zB
        There is a property '_queue' for legacy purposes
        r   r   N)r   r,   r-   Ú_queueÚqsizer0   r   r   r   Útest_qþ  s    zThreadPoolTests.test_q)r    r!   r"   Ú__doc__r$   r)   r2   r9   r;   rN   r[   rb   rf   ri   rp   rv   ry   r{   r�   r‰   rŠ   r�   r“   r   r   r   r   r#   ;   s(   		*J$#!%r#   c                   @   s$   e Zd Zdd„ Zdd„ Zdd„ ZdS )ÚRaceConditionTestsc                    s<   t  dd¡ˆ _ t ¡ ˆ _ˆ j  ¡  ‡ fdd„}ˆ  |¡ d S )Nr   r4   c                      s   ˆ j  ¡  ˆ ` d S r
   )r   r7   r   r   r   r   Údone  s    
z&RaceConditionTests.setUp.<locals>.done)r   r,   r   rC   rM   r5   r6   )r   r–   r   r   r   ÚsetUp  s
    

zRaceConditionTests.setUpc                 C   s   dS )z=
        A reasonable number of seconds to time out.
        r   r   r   r   r   r   r$     s    zRaceConditionTests.getTimeoutc                 C   sŠ   |   ¡ }| j | jj¡ | j |¡ | j ¡  tdƒD ]}| j | jj¡ q6| j | jj¡ | j |¡ | j ¡ s†| j ¡  |  	d¡ dS )a�  
        If multiple threads are waiting on an event (via blocking on something
        in a callable passed to L{threadpool.ThreadPool.callInThread}), and
        there is spare capacity in the threadpool, sending another callable
        which will cause those to un-block to
        L{threadpool.ThreadPool.callInThread} will reliably run that callable
        and un-block the blocked threads promptly.

        @note: This is not really a unit test, it is a stress-test.  You may
            need to run it with C{trial -u} to fail reliably if there is a
            problem.  It is very hard to regression-test for this particular
            bug - one where the thread pool may consider itself as having
            "enough capacity" when it really needs to spin up a new thread if
            it possibly can - in a deterministic way, since the bug can only be
            provoked by subtle race conditions.
        r3   z9'set' did not run in thread; timed out waiting on 'wait'.N)
r$   r   rB   rM   rD   rE   Úclearr%   ÚisSetr&   )r   Útimeoutr(   r   r   r   Útest_synchronization  s    


z'RaceConditionTests.test_synchronizationN)r    r!   r"   r—   r$   r›   r   r   r   r   r•     s   r•   c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )Ú
MemoryPoolz
    A deterministic threadpool that uses in-memory data structures to queue
    work rather than threads to execute work.
    c                 O   s*   || _ || _|| _tjj| f|ž|Ž dS )aÄ  
        Initialize this L{MemoryPool} with a test case.

        @param coordinator: a worker used to coordinate work in the L{Team}
            underlying this threadpool.
        @type coordinator: L{twisted._threads.IExclusiveWorker}

        @param failTest: A 1-argument callable taking an exception and raising
            a test-failure exception.
        @type failTest: 1-argument callable taking (L{Failure}) and raising
            L{unittest.FailTest}.

        @param newWorker: a 0-argument callable that produces a new
            L{twisted._threads.IWorker} provider on each invocation.
        @type newWorker: 0-argument callable returning
            L{twisted._threads.IWorker}.
        N)Ú_coordinatorÚ	_failTestÚ
_newWorkerr   r,   r   )r   ÚcoordinatorZfailTestÚ	newWorkerÚargsÚkwargsr   r   r   r   <  s    zMemoryPool.__init__c                    s&   ‡ ‡‡fdd„}t ˆj|ˆjd�‰ˆS )a§  
        Override testing hook to create a deterministic threadpool.

        @param currentLimit: A 1-argument callable which returns the current
            threadpool size limit.

        @param threadFactory: ignored in this invocation; a 0-argument callable
            that would produce a thread.

        @return: a L{Team} backed by the coordinator and worker passed to
            L{MemoryPool.__init__}.
        c                     s&   ˆ  ¡ } | j| j ˆ ƒ krd S ˆ ¡ S r
   )Z
statisticsZbusyWorkerCountZidleWorkerCountrŸ   )Ústats©ÚcurrentLimitr   Zteamr   r   ÚrespectLimita  s    z&MemoryPool._pool.<locals>.respectLimit)r    ZcreateWorkerZlogException)r   r�   rž   )r   r¦   ZthreadFactoryr§   r   r¥   r   Ú_poolS  s    	ýzMemoryPool._poolN)r    r!   r"   r”   r   r¨   r   r   r   r   rœ   6  s   rœ   c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )Ú
PoolHelpera  
    A L{PoolHelper} constructs a L{threadpool.ThreadPool} that doesn't actually
    use threads, by using the internal interfaces in L{twisted._threads}.

    @ivar performCoordination: a 0-argument callable that will perform one unit
        of "coordination" - work involved in delegating work to other threads -
        and return L{True} if it did any work, L{False} otherwise.

    @ivar workers: the workers which represent the threads within the pool -
        the workers other than the coordinator.
    @type workers: L{list} of 2-tuple of (L{IWorker}, C{workPerformer}) where
        C{workPerformer} is a 0-argument callable like C{performCoordination}.

    @ivar threadpool: a modified L{threadpool.ThreadPool} to test.
    @type threadpool: L{MemoryPool}
    c                    s:   t ƒ \}ˆ _g ˆ _‡ fdd„}t||j|f|ž|Žˆ _dS )zû
        Create a L{PoolHelper}.

        @param testCase: a test case attached to this helper.

        @type args: The arguments passed to a L{threadpool.ThreadPool}.

        @type kwargs: The arguments passed to a L{threadpool.ThreadPool}
        c                      s   ˆ j  tƒ ¡ ˆ j d d S )Nr‚   r   )r�   r   r   r   r   r   r   r¡   ‘  s    z&PoolHelper.__init__.<locals>.newWorkerN)r   ÚperformCoordinationr�   rœ   r&   r   )r   ZtestCaser¢   r£   r    r¡   r   r   r   r   „  s    
  ÿÿÿzPoolHelper.__init__c                 C   s   |   ¡ r
q dS )z‰
        Perform all currently scheduled "coordination", which is the work
        involved in delegating work to other threads.
        N)rª   r   r   r   r   ÚperformAllCoordination™  s    z!PoolHelper.performAllCoordinationN)r    r!   r"   r”   r   r«   r   r   r   r   r©   r  s   r©   c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )ÚMemoryBackedTestszn
    Tests using L{PoolHelper} to deterministically test properties of the
    threadpool implementation.
    c                 C   sl   t | ddƒ}d}t|ƒD ]}|j dd„ ¡ q| ¡  |  |jg ¡ |j ¡  | ¡  |  t|jƒ|¡ dS )zÂ
        If a threadpool is told to do work before starting, then upon starting
        up, it will start enough workers to handle all of the enqueued work
        that it's been given.
        r   r4   r   c                   S   s   d S r
   r   r   r   r   r   rg   ±  rh   z;MemoryBackedTests.test_workBeforeStarting.<locals>.<lambda>N)	r©   r%   r   rB   r«   r-   r�   r5   r   ©r   ÚhelperÚnÚxr   r   r   Útest_workBeforeStarting¨  s    
z)MemoryBackedTests.test_workBeforeStartingc                 C   sp   t | ddƒ}d}t|ƒD ]}|j dd„ ¡ q| ¡  |  |jg ¡ |j ¡  | ¡  |  t|jƒ|jj	¡ dS )z°
        If the amount of work before starting exceeds the maximum number of
        threads allowed to the threadpool, only the maximum count will be
        started.
        r   r4   é2   c                   S   s   d S r
   r   r   r   r   r   rg   Á  rh   zBMemoryBackedTests.test_tooMuchWorkBeforeStarting.<locals>.<lambda>N)
r©   r%   r   rB   r«   r-   r�   r5   r   r/   r­   r   r   r   Útest_tooMuchWorkBeforeStarting¸  s    
z0MemoryBackedTests.test_tooMuchWorkBeforeStartingN)r    r!   r"   r”   r±   r³   r   r   r   r   r¬   ¢  s   r¬   )r”   rF   r^   r   r   r@   Ztwisted._threadsr   r   Ztwisted.pythonr   r   r   r   Ztwisted.trialr   r	   ZsynchronizeZSynchronousTestCaser#   r•   r,   rœ   r©   r¬   r   r   r   r   Ú<module>   s$   $
   N0<0