U
    
W[¼V  ã                   @   sò   d Z ddlmZm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
 ddlmZ ddlmZmZmZmZ ddlmZmZ G dd	„ d	eƒ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eƒZG dd„ dejƒZdS )z(
Tests for L{twisted.python.threadpool}
é    )ÚdivisionÚabsolute_importN)Úrange)Úunittest)Ú
threadpoolÚ
threadableÚfailureÚcontext)ÚTeamÚcreateMemoryWorkerc                   @   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   ú>/usr/lib/python3/dist-packages/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&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   Ú
getTimeoutF   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)r   r   r   r   Úfail)r   r   ÚitemsÚir   r   r   Ú_waitForLockM   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_attributesW   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   Úthreadsr2   r   r   r   Ú
test_starta   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.   r7   r9   ZadjustPoolsizer/   r   r:   r2   r   r   r   Útest_adjustingWhenPoolStoppedq   s
    
z-ThreadPoolTests.test_adjustingWhenPoolStoppedc                 C   s¶   t  dd¡}| ¡  |  |j¡ |  |jg ¡ dd„ }G dd„ dtƒ}|ƒ }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   rA   N)r   r.   r7   r8   r9   r/   r:   ÚobjectÚweakrefÚrefÚcallInThreadr   ÚEventÚsetÚwaitr'   ÚgcÚcollectÚassertIsNone)r   Útpr?   rA   ÚuniqueÚ	workerRefÚ	uniqueRefÚeventr   r   r   Útest_threadCreationArguments}   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
 |¡‰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 )NrN   rO   )rI   rJ   rH   r'   rG   r    rC   rD   ©ÚsuccessÚresult)ÚonResultDoneÚonResultWaitÚrefdictÚ	resultRefr   rO   rN   r   r   ÚonResult¾   s    

zVThreadPoolTests.test_threadCreationArgumentsCallInThreadWithCallback.<locals>.onResultc                    s   ˆ ƒ S r   r   )r>   Útest)rA   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   rA   Í   s   rA   )rZ   N)r   r.   r7   r8   r9   r/   r:   r   rF   rB   rC   rD   ÚcallInThreadWithCallbackrG   rH   r'   rI   rJ   rK   ÚlistÚvalues)r   rL   rY   r?   rM   ZonResultRefr   )rA   rU   rV   rW   rX   r   rO   rN   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/   r0   r1   ÚpickleÚloadsÚdumps)r   r3   Úcopyr   r   r   Útest_persistenceó   s    z ThreadPoolTests.test_persistencec                 C   sv   d}t  ¡ }| ¡  |  |j¡ t ¡ }| ¡  t||ƒ}t	|ƒD ]}|||ƒ qB|  
|¡ |  |jd |j¡¡ 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.
        r6   zrun() re-entered {} timesN)r   r.   r7   r8   r9   r   r   r   r   r   r+   ÚassertFalser   Úformat)r   Úmethodr   rL   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   )rE   r"   )rL   ri   r   r   r   Ú<lambda>&  ó    z3ThreadPoolTests.test_callInThread.<locals>.<lambda>)rj   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   rn   c                      s
   ˆ ƒ ‚d S r   r   r   ©rn   r   r   Ú
raiseError1  s    z>ThreadPoolTests.test_callInThreadException.<locals>.raiseErrorr   r   N)	Ú	Exceptionr   r.   rE   r7   r9   ÚflushLoggedErrorsr/   r   )r   rp   rL   Úerrorsr   ro   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    rR   ©ÚresultsÚwaiterr   r   rY   H  s    
z?ThreadPoolTests.test_callInThreadWithCallback.<locals>.onResultr   r   c                   S   s   dS )NrZ   r   r   r   r   r   rk   N  rl   z?ThreadPoolTests.test_callInThreadWithCallback.<locals>.<lambda>rZ   N)r   r   r   r   r.   r[   r7   r9   r+   Ú
assertTruer/   )r   rY   rL   r   rv   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   rn   `  s   rn   c                      s
   ˆ ƒ ‚d S r   r   r   ro   r   r   rp   c  s    zTThreadPoolTests.test_callInThreadWithCallbackExceptionInCallback.<locals>.raiseErrorc                    s    ˆ  ¡  ˆ  | ¡ ˆ  |¡ d S r   ru   rR   rv   r   r   rY   k  s    
zRThreadPoolTests.test_callInThreadWithCallbackExceptionInCallback.<locals>.onResultr   r   N)rq   r   r   r   r   r.   r[   r7   r9   r+   rf   ZassertIsInstancer   ZFailurery   Ú
issubclassÚtype)r   rp   rY   rL   r   )rn   rw   rx   r   Ú0test_callInThreadWithCallbackExceptionInCallbackZ  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   rn   ƒ  s   rn   c                    s   ˆ  | ¡ ˆ  |¡ ˆ ƒ ‚d S r   )r    rR   ©rn   rw   r   r   rY   ‹  s    

zRThreadPoolTests.test_callInThreadWithCallbackExceptionInOnResult.<locals>.onResultr   r   c                   S   s   d S r   r   r   r   r   r   rk   ‘  rl   zRThreadPoolTests.test_callInThreadWithCallbackExceptionInOnResult.<locals>.<lambda>N)rq   r   r   r   r   r.   r[   rE   r   r7   r9   r+   rr   r/   r   ry   rK   )r   rx   rY   rL   rs   r   r~   r   Ú0test_callInThreadWithCallbackExceptionInOnResult~  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   ÚcurrentThreadÚidentrG   rR   ©rP   Ú	threadIdsr   r   rY   ª  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   rF   r   r.   r[   r7   r8   r9   rH   r'   r/   r   )r   rY   r„   rL   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    rG   )rS   rT   Úctx©rŠ   rP   r   r   rY   È  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   rF   r   r.   r[   r7   r8   r9   rH   r'   r/   r   )r   ZmyctxrY   r„   rL   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.   rE   r   r7   r9   r+   )r   rx   rL   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 )Nr6   )rG   rH   r   ©ZthreadFinishZthreadWorkingr   r   Ú_thread  s    z;ThreadPoolTests.test_workerStateTransition.<locals>._threadr6   gü©ñÒMb@?N)r   r.   r7   r8   r9   r/   Úworkersr   ÚwaitersZworkingr   rF   rE   rH   rG   r   r   )r   r3   r   r   r   r   Útest_workerStateTransitionð  s&    


z*ThreadPoolTests.test_workerStateTransitionN)r#   r$   r%   Ú__doc__r'   r+   r4   r;   r=   rQ   r^   re   rj   rm   rt   rz   r}   r   r…   r   rŽ   r“   r   r   r   r   r&   A   s&   

+K$#"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   r6   c                      s   ˆ j  ¡  ˆ ` d S r   )r   r9   r   r!   r   r   Údone  s    
z&RaceConditionTests.setUp.<locals>.done)r   r.   r   rF   rP   r7   r8   )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.
        r5   z9'set' did not run in thread; timed out waiting on 'wait'.N)
r'   r   rE   rP   rG   rH   Úclearr   ZisSetr(   )r   Z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  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   )Zstats©ÚcurrentLimitr   Zteamr   r   ÚrespectLimitx  s    ÿÿz&MemoryPool._pool.<locals>.respectLimit)rž   ZcreateWorkerZlogException)r
   r›   rœ   )r   r£   ZthreadFactoryr¤   r   r¢   r   Ú_poolk  s    	þzMemoryPool._poolN)r#   r$   r%   r”   r   r¥   r   r   r   r   rš   M  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¦   ˆ  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   r6   r   c                   S   s   d S r   r   r   r   r   r   rk   È  rl   z;MemoryBackedTests.test_workBeforeStarting.<locals>.<lambda>N)	r¦   r   r   rE   r¨   r/   r‘   r7   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   r6   é2   c                   S   s   d S r   r   r   r   r   r   rk   Ù  rl   zBMemoryBackedTests.test_tooMuchWorkBeforeStarting.<locals>.<lambda>N)
r¦   r   r   rE   r¨   r/   r‘   r7   r   r1   rª   r   r   r   Útest_tooMuchWorkBeforeStartingÐ  s    
z0MemoryBackedTests.test_tooMuchWorkBeforeStartingN)r#   r$   r%   r”   r®   r°   r   r   r   r   r©   ¹  s   r©   )r”   Z
__future__r   r   ra   r   rC   rI   r   Ztwisted.python.compatr   Ztwisted.trialr   Ztwisted.pythonr   r   r   r	   Ztwisted._threadsr
   r   rB   r   ZsynchronizeZSynchronousTestCaser&   r•   r.   rš   r¦   r©   r   r   r   r   Ú<module>   s(   %
   Y6;1