U
    
W[d  ã                   @   s²   d Z zddlZW n ek
r(   dZY nX ddlmZ ddlmZ ddlmZ ddl	m
Z
 ddlmZ ddlmZ dd	lmZ G d
d„ deƒZG dd„ deƒZeƒ  e ¡ ¡ dS )z6
Tests for implementations of L{IReactorWin32Events}.
é    N)ÚverifyObject)ÚFailure)ÚisInIOThread)ÚIReactorWin32Events)ÚDeferred)ÚReactorBuilder)ÚgetThreadIDc                   @   sP   e Zd ZdZdZd Z ZZdd„ Zdd„ Z	dd	„ Z
d
d„ Zdd„ Zdd„ ZdS )ÚListeneraÔ  
    L{Listener} is an object that can be added to a L{IReactorWin32Events}
    reactor to receive callback notification when a Windows event is set.  It
    records what thread its callback is invoked in and fires a Deferred.

    @ivar success: A flag which is set to C{True} when the event callback is
        called.

    @ivar logThreadID: The id of the thread in which the C{logPrefix} method is
        called.

    @ivar eventThreadID: The id of the thread in which the event callback is
        called.

    @ivar connLostThreadID: The id of the thread in which the C{connectionLost}
        method is called.

    @ivar _finished: The L{Deferred} which will be fired when the event callback
        is called.
    FNc                 C   s
   || _ d S ©N)Ú	_finished)ÚselfÚfinished© r   úH/usr/lib/python3/dist-packages/twisted/internet/test/test_win32events.pyÚ__init__/   s    zListener.__init__c                 C   s   t ƒ | _dS )Nr	   )r   ÚlogThreadID©r   r   r   r   Ú	logPrefix3   s    zListener.logPrefixc                 C   s   d| _ tƒ | _| j d ¡ d S )NT)Úsuccessr   ÚeventThreadIDr   Úcallbackr   r   r   r   Úoccurred8   s    zListener.occurredc                 C   s   t dƒ‚d S )NzSome problem)ÚRuntimeErrorr   r   r   r   ÚbrokenOccurred>   s    zListener.brokenOccurredc                 C   s   t dƒS )NzEntirely different problem)ÚEnvironmentErrorr   r   r   r   ÚreturnValueOccurredB   s    zListener.returnValueOccurredc                 C   s   t ƒ | _| j |¡ d S r
   )r   ÚconnLostThreadIDr   Zerrback)r   Úreasonr   r   r   ÚconnectionLostF   s    zListener.connectionLost)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r   r   r   r   r   r   r   r   r   r   r	      s   r	   c                   @   sF   e Zd ZdZegZdd„ Zdd„ Zdd„ Zdd	„ Z	d
d„ Z
dd„ ZdS )ÚWin32EventsTestsBuilderzD
    Builder defining tests relating to L{IReactorWin32Events}.
    c                 C   s   |   ¡ }tt|ƒ dS )zn
        An instance of the reactor has all of the methods defined on
        L{IReactorWin32Events}.
        N)ÚbuildReactorr   r   )r   Úreactorr   r   r   Útest_interfaceR   s    z&Win32EventsTestsBuilder.test_interfacec                    s   t ƒ }|  ¡ ‰ t dddd¡}tƒ }| ‡ fdd„¡ t|ƒ}ˆ  ||d¡ ˆ  tj	|¡ |  
ˆ ¡ |  |j¡ |  ||j¡ |  ||j¡ dS )zš
        When an event which has been added to the reactor is set, the action
        associated with the event is invoked in the reactor thread.
        NFc                    s   ˆ   ¡ S r
   ©Ústop©Zignored©r%   r   r   Ú<lambda>d   ó    z7Win32EventsTestsBuilder.test_addEvent.<locals>.<lambda>r   )r   r$   Ú
win32eventÚCreateEventr   ÚaddCallbackr	   ÚaddEventÚcallWhenRunningÚSetEventÚ
runReactorÚ
assertTruer   ÚassertEqualr   r   )r   ÚreactorThreadIDÚeventr   Úlistenerr   r*   r   Útest_addEvent[   s    
z%Win32EventsTestsBuilder.test_addEventc                    s†   g ‰‡ ‡fdd„}|   ¡ ‰ t dddd¡}tƒ }t|ƒ}| |¡ ˆ  ||d¡ ˆ  tj|¡ |  	ˆ ¡ |  
|j¡ |  dgˆ¡ dS )z{
        Using L{IReactorWin32Events.addEvent} does not change which thread is
        reported as the I/O thread.
        c                    s   ˆ  tƒ ¡ ˆ  ¡  d S r
   )Úappendr   r(   r)   ©r%   Zresultsr   r   Úcheckt   s    zAWin32EventsTestsBuilder.test_ioThreadDoesNotChange.<locals>.checkNFr   T)r$   r-   r.   r   r	   r/   r0   r1   r2   r3   r4   r   r5   )r   r<   r7   r   r8   r   r;   r   Útest_ioThreadDoesNotChangen   s    

z2Win32EventsTestsBuilder.test_ioThreadDoesNotChangec                    sº   t ƒ }|  ¡ ‰ t dddd¡}g }tƒ }| |j¡ | ‡ fdd„¡ t|ƒ}ˆ  ||d¡ ˆ  	tj
|¡ |  ˆ ¡ |  |d t¡ |d  t¡ |  ||j¡ |  dt|  t¡ƒ¡ dS )zÕ
        If the event handler raises an exception, the event is removed from the
        reactor and the handler's C{connectionLost} method is called in the I/O
        thread and the exception is logged.
        NFc                    s   ˆ   ¡ S r
   r'   r)   r*   r   r   r+      r,   zBWin32EventsTestsBuilder.test_disconnectedOnError.<locals>.<lambda>r   r   é   )r   r$   r-   r.   r   ÚaddBothr:   r	   r0   r1   r2   r3   ÚassertIsInstancer   Útrapr   r5   r   ÚlenZflushLoggedErrors©r   r6   r7   Úresultr   r8   r   r*   r   Útest_disconnectedOnErrorƒ   s    
z0Win32EventsTestsBuilder.test_disconnectedOnErrorc                    s¤   t ƒ }|  ¡ ‰ t dddd¡}g }tƒ }| |j¡ | ‡ fdd„¡ t|ƒ}ˆ  ||d¡ ˆ  	tj
|¡ |  ˆ ¡ |  |d t¡ |d  t¡ |  ||j¡ dS )zµ
        If the event handler returns a value, the event is removed from the
        reactor and the handler's C{connectionLost} method is called in the I/O
        thread.
        NFc                    s   ˆ   ¡ S r
   r'   r)   r*   r   r   r+   «   r,   zFWin32EventsTestsBuilder.test_disconnectOnReturnValue.<locals>.<lambda>r   r   )r   r$   r-   r.   r   r?   r:   r	   r0   r1   r2   r3   r@   r   rA   r   r5   r   rC   r   r*   r   Útest_disconnectOnReturnValuež   s    
z4Win32EventsTestsBuilder.test_disconnectOnReturnValuec                 C   sZ   |   ¡ }t dddd¡}tƒ }t|ƒ}| ||d¡ | |j¡ |  |¡ |  	|j
¡ dS )z¾
        Event handlers added with L{IReactorWin32Events.addEvent} do not have
        C{connectionLost} called on them if they are still active when the
        reactor shuts down.
        NFr   )r$   r-   r.   r   r	   r0   r1   r(   r3   ZassertIsNoner   )r   r%   r7   r   r8   r   r   r   Útest_notDisconnectedOnShutdown¸   s    
z6Win32EventsTestsBuilder.test_notDisconnectedOnShutdownN)r   r    r!   r"   r   ZrequiredInterfacesr&   r9   r=   rE   rF   rG   r   r   r   r   r#   L   s   	r#   )r"   r-   ÚImportErrorZzope.interface.verifyr   Ztwisted.python.failurer   Ztwisted.python.threadabler   Ztwisted.internet.interfacesr   Ztwisted.internet.deferr   Z#twisted.internet.test.reactormixinsr   r   Úobjectr	   r#   ÚglobalsÚupdateZmakeTestCaseClassesr   r   r   r   Ú<module>   s   
5{