o
    Óó·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   úbC:\Users\psant\Downloads\PAF backend\school\venv\Lib\site-packages\twisted/test/test_threadpool.pyÚ__init__   s   

zSynchronization.__init__c                 C   s|   | j  d¡rt| jƒd st d¡ | j  ¡  n|  jd7  _| j  ¡  | j d ¡ t| jƒ| j	kr7| 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)„Zd'S )+ÚThreadPoolTestsz
    Test threadpools.
    c                 C   ó   dS )zD
        Return number of seconds to wait before giving up.
        r   Nr   r   r   r   r   Ú
getTimeout@   ó   zThreadPoolTests.getTimeoutc                 C   s:   t dƒ}|D ]}| d¡r d S t 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   Úthreadsr2   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.   r7   r9   ZadjustPoolsizer/   r   r:   r2   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   ó   d S r
   r   )Úargr   r   r   Úworker�   s   z<ThreadPoolTests.test_threadCreationArguments.<locals>.workerc                   @   ó   e Zd ZdS )z:ThreadPoolTests.test_threadCreationArguments.<locals>.DumbN©r    r!   r"   r   r   r   r   ÚDumb…   ó    rC   N)r   r.   r7   r8   r9   r/   r:   ÚweakrefÚrefÚcallInThreadr   ÚEventÚsetÚwaitr%   ÚgcÚcollectÚassertIsNone)r   Útpr@   rC   Ú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 )NrP   rQ   )rK   rL   rJ   r%   rI   r   rE   rF   ©ÚsuccessÚresult)ÚonResultDoneÚonResultWaitÚrefdictÚ	resultRefr   rQ   rP   r   r   ÚonResult²   s   

zVThreadPoolTests.test_threadCreationArgumentsCallInThreadWithCallback.<locals>.onResultc                    s   ˆ ƒ S r
   r   )r?   Útest)rC   r   r   r@   ½   ó   zTThreadPoolTests.test_threadCreationArgumentsCallInThreadWithCallback.<locals>.workerc                   @   rA   )zRThreadPoolTests.test_threadCreationArgumentsCallInThreadWithCallback.<locals>.DumbNrB   r   r   r   r   rC   Á   rD   rC   )r\   N)r   r.   r7   r8   r9   r/   r:   r   rH   rE   rF   ÚcallInThreadWithCallbackrI   rJ   r%   rK   rL   rM   ÚlistÚvalues)r   rN   r[   r@   rO   ZonResultRefr   )rC   rW   rX   rY   rZ   r   rQ   rP   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   sx   d}t  ¡ }| ¡  |  |j¡ t ¡ }| ¡  t||ƒ}t	|ƒD ]}|||ƒ q!|  
|¡ |  |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.
        r6   zrun() re-entered z timesN)r   r.   r7   r8   r9   r   r   r   r	   r'   r+   ÚassertFalser   )r   Úmethodr   rN   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
   )rG   r   )rN   rk   r   r   r   Ú<lambda>  s    z3ThreadPoolTests.test_callInThread.<locals>.<lambda>N)rl   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                   @   rA   )z<ThreadPoolTests.test_callInThreadException.<locals>.NewErrorNrB   r   r   r   r   ÚNewError  rD   ro   c                      ó   ˆ ƒ ‚r
   r   r   ©ro   r   r   Ú
raiseError  r]   z>ThreadPoolTests.test_callInThreadException.<locals>.raiseErrorr   r   N)	Ú	Exceptionr   r.   rG   r7   r9   ÚflushLoggedErrorsr/   r   )r   rr   rN   Úerrorsr   rq   r   Útest_callInThreadException  s   

z*ThreadPoolTests.test_callInThreadExceptionc                    sŠ   t  ¡ ‰ˆ ¡  g ‰ ‡ ‡fdd„}t dd¡}| |dd„ ¡ | ¡  z|  ˆ¡ W | ¡  n| ¡  w |  	ˆ 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                    ó    ˆ  ¡  ˆ  | ¡ ˆ  |¡ d S r
   ©r   r   rT   ©ÚresultsÚwaiterr   r   r[   5  ó   
z?ThreadPoolTests.test_callInThreadWithCallback.<locals>.onResultr   r   c                   S   r$   )Nr\   r   r   r   r   r   rm   ;  ó    z?ThreadPoolTests.test_callInThreadWithCallback.<locals>.<lambda>r\   N)r   r   r   r   r.   r^   r7   r+   r9   Ú
assertTruer/   )r   r[   rN   r   ry   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 | 	¡  n| 	¡  w |  
ˆ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                   @   rA   )zRThreadPoolTests.test_callInThreadWithCallbackExceptionInCallback.<locals>.NewErrorNrB   r   r   r   r   ro   M  rD   ro   c                      rp   r
   r   r   rq   r   r   rr   P  r]   zTThreadPoolTests.test_callInThreadWithCallbackExceptionInCallback.<locals>.raiseErrorc                    rw   r
   rx   rT   ry   r   r   r[   X  r|   zRThreadPoolTests.test_callInThreadWithCallbackExceptionInCallback.<locals>.onResultr   r   N)rs   r   r   r   r   r.   r^   r7   r+   r9   ri   ZassertIsInstancer   ZFailurer~   Ú
issubclassÚtype)r   rr   r[   rN   r   )ro   rz   r{   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 | ¡  n| ¡  w |  ˆ ¡}|  t|ƒd¡ |  ˆd ¡ |  ˆd ¡ d	S )
zj
        L{ThreadPool.callInThreadWithCallback} logs the exception raised by
        C{onResult}.
        c                   @   rA   )zRThreadPoolTests.test_callInThreadWithCallbackExceptionInOnResult.<locals>.NewErrorNrB   r   r   r   r   ro   p  rD   ro   c                    s   ˆ  | ¡ ˆ  |¡ ˆ ƒ ‚r
   )r   rT   ©ro   rz   r   r   r[   x  s   

zRThreadPoolTests.test_callInThreadWithCallbackExceptionInOnResult.<locals>.onResultr   r   c                   S   r>   r
   r   r   r   r   r   rm   ~  r}   zRThreadPoolTests.test_callInThreadWithCallbackExceptionInOnResult.<locals>.<lambda>N)rs   r   r   r   r   r.   r^   rG   r   r7   r+   r9   rt   r/   r   r~   rM   )r   r{   r[   rN   ru   r   rƒ   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ÚidentrI   rT   ©rR   Ú	threadIdsr   r   r[   –  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   rH   r   r.   r^   r7   r8   r9   rJ   r%   r/   r   )r   r[   r‰   rN   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   rI   )rU   rV   Úctx©r�   rR   r   r   r[   ³  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   rH   r   r.   r^   r7   r8   r9   rJ   r%   r/   r   )r   Zmyctxr[   r‰   rN   r   r‘   r   Útest_callbackContext¦  s   z$ThreadPoolTests.test_callbackContextc                 C   sT   t  ¡ }| ¡  t dd¡}| |j¡ | ¡  z|  |¡ W | 	¡  dS | 	¡  w )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.   rG   r   r7   r+   r9   )r   r{   rN   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ƒsnt d¡ t|jƒrd|  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   )rI   rJ   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   rH   rG   rJ   rI   r   r   )r   r3   r•   r   r”   r   Útest_workerStateTransitionÙ  s(   




ÿz*ThreadPoolTests.test_workerStateTransitionÚreturnNc                 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Úqsizer2   r   r   r   Útest_qþ  s   zThreadPoolTests.test_q)r™   N)r    r!   r"   Ú__doc__r%   r+   r4   r;   r=   rS   ra   rh   rl   rn   rv   r   r‚   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   r6   c                      s   ˆ j  ¡  ˆ ` d S r
   )r   r9   r   r   r   r   Údone  s   
z&RaceConditionTests.setUp.<locals>.done)r   r.   r   rH   rR   r7   r8   )r   rŸ   r   r   r   ÚsetUp  s
   

zRaceConditionTests.setUpc                 C   r$   )z=
        A reasonable number of seconds to time out.
        r   Nr   r   r   r   r   r%     r&   zRaceConditionTests.getTimeoutc                 C   sŽ   |   ¡ }| j | jj¡ | j |¡ | j ¡  tdƒD ]
}| j | jj¡ q| j | jj¡ | j |¡ | j ¡ sE| j ¡  |  	d¡ dS 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   rG   rR   rI   rJ   Ú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                   @   ó    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   s0   || _ || _|| _tjj| g|¢R i |¤Ž 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
   )Ú
statisticsZbusyWorkerCountZidleWorkerCountr©   )Ústats©ÚcurrentLimitr   Zteamr   r   ÚrespectLimita  s   z&MemoryPool._pool.<locals>.respectLimit)rª   ZcreateWorkerZlogExceptionN)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                   @   r¥   )Ú
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|g|¢R i |¤Žˆ _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	 |   ¡ sdS 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                   @   r¥   )Ú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   r>   r
   r   r   r   r   r   rm   ±  r}   z;MemoryBackedTests.test_workBeforeStarting.<locals>.<lambda>N)	r´   r'   r   rG   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   r>   r
   r   r   r   r   r   rm   Á  r}   zBMemoryBackedTests.test_tooMuchWorkBeforeStarting.<locals>.<lambda>N)
r´   r'   r   rG   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�   rK   rd   r   r   rE   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