
    Yf1                        d Z ddlZddlZddlmZmZ ddlmZ ddlm	Z	m
Z
mZ  G d de          Z G d	 d
e          Z G d d          Z G d d          Z G d d          Z G d de          Z G d de          ZdS )z.
Tests for L{twisted._threads._threadworker}.
    N)ThreadErrorlocal)SynchronousTestCase   )AlreadyQuit
LockWorkerThreadWorkerc                       e Zd ZdZdS )FakeQueueEmptyz8
    L{FakeQueue}'s C{get} has exhausted the queue.
    N__name__
__module____qualname____doc__     Y/var/www/html/env/lib/python3.11/site-packages/twisted/_threads/test/test_threadworker.pyr   r      s           r   r   c                       e Zd ZdZdS )WouldDeadlockzf
    If this were a real lock, you'd be deadlocked because the lock would be
    double-acquired.
    Nr   r   r   r   r   r      s           r   r   c                       e Zd ZdZd Zd ZdS )
FakeThreadz
    A fake L{threading.Thread}.

    @ivar target: A target function to run.
    @type target: L{callable}

    @ivar started: Has this thread been started?
    @type started: L{bool}
    c                 "    || _         d| _        dS )z7
        Create a L{FakeThread} with a target.
        FN)targetstarted)selfr   s     r   __init__zFakeThread.__init__)   s     r   c                     d| _         dS )z)
        Set the "started" flag.
        TN)r   r   s    r   startzFakeThread.start0   s     r   N)r   r   r   r   r   r   r   r   r   r   r      s<               r   r   c                   $    e Zd ZdZd Zd Zd ZdS )	FakeQueuez
    A fake L{Queue} implementing C{put} and C{get}.

    @ivar items: A lit of items placed by C{put} but not yet retrieved by
        C{get}.
    @type items: L{list}
    c                     g | _         dS )z(
        Create a L{FakeQueue}.
        N)itemsr   s    r   r   zFakeQueue.__init__@   s     


r   c                 :    | j                             |           dS )zv
        Put an item into the queue for later retrieval by L{FakeQueue.get}.

        @param item: any object
        N)r#   append)r   items     r   putzFakeQueue.putF   s      	
$r   c                 `    | j         st                      | j                             d          S )zR
        Get an item.

        @return: an item previously put by C{put}.
        r   )r#   r   popr   s    r   getzFakeQueue.getN   s.     z 	# """z~~a   r   N)r   r   r   r   r   r'   r*   r   r   r   r!   r!   7   sK                ! ! ! ! !r   r!   c                   $    e Zd ZdZd Zd Zd ZdS )FakeLockzi
    A stand-in for L{threading.Lock}.

    @ivar acquired: Whether this lock is presently acquired.
    c                     d| _         dS )z9
        Create a lock in the un-acquired state.
        FN)acquiredr   s    r   r   zFakeLock.__init__`   s     r   c                 >    | j         rt                      d| _         dS )zX
        Acquire the lock.  Raise an exception if the lock is already acquired.
        TN)r.   r   r   s    r   acquirezFakeLock.acquiref   s#     = 	"//!r   c                 >    | j         st                      d| _         dS )zf
        Release the lock.  Raise an exception if the lock is not presently
        acquired.
        FN)r.   r   r   s    r   releasezFakeLock.releasen   s#    
 } 	 --r   N)r   r   r   r   r   r0   r2   r   r   r   r,   r,   Y   sK                 r   r,   c                   $    e Zd ZdZd Zd Zd ZdS )ThreadWorkerTestsz$
    Tests for L{ThreadWorker}.
    c                 z     g  _         t                       _         fd}t          | j                   _        dS )z4
        Create a worker with fake threads.
        c                     t          |           }|                                 j                            |           |S )N)r   )r   r   fakeThreadsr%   )r   	newThreadr   s     r   startThreadz,ThreadWorkerTests.setUp.<locals>.startThread   s@    "&111IOO##I...r   N)r7   r!   	fakeQueuer	   worker)r   r9   s   ` r   setUpzThreadWorkerTests.setUp}   sJ     "	 	 	 	 	 #;??r   c                    |                      t          | j                  d           |                      | j        d         j        d           fdd_        | j                                       |                      j        d           |                     t          | j        d         j	                   |                      j        d           dS )z
        L{ThreadWorker} calls its C{createThread} callable to create a thread,
        its C{createQueue} callable to create a queue, and then the thread's
        target pulls work from that queue.
           r   Tc                      d _         d S NT)done)doIts   r   rB   z@ThreadWorkerTests.test_startsThreadAndPerformsWork.<locals>.doIt   s    DIIIr   FN)
assertEquallenr7   r   rA   r;   doassertRaisesr   r   )r   rB   s    @r    test_startsThreadAndPerformsWorkz2ThreadWorkerTests.test_startsThreadAndPerformsWork   s     	T-..222)!,4d;;;	 	 	 	 	 	tE***.$*:1*=*DEEED)))))r   c                     | j                                          |                     t          | j         j                   |                     t          | j         j        t
                     dS )z
        L{ThreadWorker.quit} causes future calls to L{ThreadWorker.do} and
        L{ThreadWorker.quit} to raise L{AlreadyQuit}.
        N)r;   quitrF   r   rE   listr   s    r   test_quitPreventsFutureCallsz.ThreadWorkerTests.test_quitPreventsFutureCalls   sU    
 	+t{'7888+t{~t<<<<<r   N)r   r   r   r   r<   rG   rK   r   r   r   r4   r4   x   sN         @ @ @* * *$= = = = =r   r4   c                   <    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	S )
LockWorkerTestsz"
    Tests for L{LockWorker}.
    c                     t                      }|                                 |                     t          |j                   dS )ze
        The L{FakeLock} test fixture will alert us if there's a potential
        deadlock.
        N)r,   r0   rF   r   r   locks     r   test_fakeDeadlockz!LockWorkerTests.test_fakeDeadlock   s8    
 zz-66666r   c                    t                      }|                     t          |j                   |                                 |                     d|                                           |                     t          |j                   dS )zk
        The L{FakeLock} test fixture will alert us if there's a potential
        double-release.
        N)r,   rF   r   r2   r0   rC   rO   s     r   test_fakeDoubleReleasez&LockWorkerTests.test_fakeDoubleRelease   sn    
 zz+t|444t||~~...+t|44444r   c                 H   t                      }t                      t          |          }fdd_        |                               |                     j        d           |                     j        d           |                     j        d           dS )zp
        L{LockWorker.do} immediately performs the work it's given, while the
        lock is acquired.
        c                  .    d_          j        _        d S r@   )rA   r.   )rP   works   r   rV   z@LockWorkerTests.test_doExecutesImmediatelyWithLock.<locals>.work   s    DI MDMMMr   FTN)r   r,   r   rA   rE   rC   r.   )r   storager;   rP   rV   s      @@r   "test_doExecutesImmediatelyWithLockz2LockWorkerTests.test_doExecutesImmediatelyWithLock   s    
 ''zzD'**	* 	* 	* 	* 	* 	* 			$D)))---.....r   c                    t                      t          t                                g g fdd_                                       |                     ddg           |                     ddg           dS )z
        If L{LockWorker.do} is called recursively, it postpones the inner call
        until the outer one is complete.
        c                      xj         dz  c_                             j                                         j                   t                    dk     r                               xj         dz  c_         d S )Nr>   r   )levelr%   r.   rD   rE   )r.   levelsrP   rV   r;   s   r   rV   z6LockWorkerTests.test_doUnwindsReentrancy.<locals>.work   sk    JJ!OJJMM$*%%%OODM***6{{Q		$JJ!OJJJJr   r   r>   TN)r,   r   r   r[   rE   rC   )r   r.   r\   rP   rV   r;   s    @@@@@r   test_doUnwindsReentrancyz(LockWorkerTests.test_doUnwindsReentrancy   s    
 zzD%''**	 	 	 	 	 	 	 	 	 
		$!Q(((D$<00000r   c                    t                      }t          j        |          }t          |t	                                }d}|                      |            d           |                                 t          j                     | 	                     |            d           | 
                    t          |j                   | 
                    t          |j        t                     dS )z
        L{LockWorker.quit} frees the resources associated with its lock and
        causes further calls to C{do} and C{quit} to fail.
        N)r,   weakrefrefr   r   assertIsNotrI   gccollectassertIsrF   r   rE   rJ   )r   rP   r`   r;   s       r   	test_quitzLockWorkerTests.test_quit   s    
 zzk$D%''**%%%

cceeT"""+v{333+vy$77777r   c                     t                      t          j                  }t          t	                                 fdd_        fdd_                                                            j        d                                j        d                                j        d           dt          j
                                           |            d           dS )z
        If L{LockWorker.quit} is invoked during a call to L{LockWorker.do}, all
        recursive work scheduled with L{LockWorker.do} will be completed and
        the lock will be released.
        c                                                                                                           t          j         t                     d _        d S r@   )rE   rI   rF   r   rJ   complete)phase1phase2r   r;   s   r   ri   z5LockWorkerTests.test_quitWhileWorking.<locals>.phase1  sG    IIfKKMMMk69d;;;"FOOOr   Fc                  .    d_          j        _        d S r@   )rh   r.   )rP   rj   s   r   rj   z5LockWorkerTests.test_quitWhileWorking.<locals>.phase2  s    "FO"mFOOOr   TN)r,   r_   r`   r   r   rh   rE   rC   r.   rb   rc   rd   )r   r`   rP   ri   rj   r;   s   ` @@@@r   test_quitWhileWorkingz%LockWorkerTests.test_quitWhileWorking   s    zzk$D%''**	# 	# 	# 	# 	# 	# 	# 	#  	, 	, 	, 	, 	, 	,  		&$///$///...

cceeT"""""r   c                      G d dt                     } |t                      t                                }|                     t          |j        t                     dS )z
        If L{LockWorker.do} is called concurrently with L{LockWorker.quit}, and
        C{quit} wins the race before C{do} gets the lock attribute, then
        L{AlreadyQuit} will be raised.
        c                   D    e Zd Zed             Zej        d             ZdS )ALockWorkerTests.test_quitWhileGettingLock.<locals>.RacyLockWorkerc                 D    |                                   | j        d         S N_lock)rI   __dict__r   s    r   rr   zGLockWorkerTests.test_quitWhileGettingLock.<locals>.RacyLockWorker._lock"  s    		}W--r   c                     || j         d<   d S rq   )rs   )r   values     r   rr   zGLockWorkerTests.test_quitWhileGettingLock.<locals>.RacyLockWorker._lock'  s    ).g&&&r   N)r   r   r   propertyrr   setterr   r   r   RacyLockWorkerro   !  sJ        . . X. \/ / \/ / /r   rx   N)r   r,   r   rF   r   rE   rJ   )r   rx   r;   s      r   test_quitWhileGettingLockz)LockWorkerTests.test_quitWhileGettingLock  sg    	/ 	/ 	/ 	/ 	/Z 	/ 	/ 	/  

EGG44+vy$77777r   N)r   r   r   r   rQ   rS   rX   r]   re   rl   ry   r   r   r   rM   rM      s         7 7 7	5 	5 	5/ / /&1 1 1.8 8 8 # # #>8 8 8 8 8r   rM   )r   rb   r_   	threadingr   r   twisted.trial.unittestr    r   r   r	   	Exceptionr   r   r   r!   r,   r4   rM   r   r   r   <module>r~      s   
 
			  ( ( ( ( ( ( ( ( 6 6 6 6 6 6 4 4 4 4 4 4 4 4 4 4    Y       I          2! ! ! ! ! ! ! !D       >-= -= -= -= -=+ -= -= -=`D8 D8 D8 D8 D8) D8 D8 D8 D8 D8r   