U
    n5{i1  ã                   @   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mZ G d	d
„ d
ƒZG dd„ de
ƒZeƒ  e ¡ ¡ dS )z6
Tests for implementations of L{IReactorWin32Events}.
é    N)ÚverifyObject)ÚDeferred)ÚIReactorWin32Events)ÚReactorBuilder)ÚFailure)ÚgetThreadIDÚisInIOThreadc                   @   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   úJ/tmp/pip-unpacked-wheel-mnhg7r0q/twisted/internet/test/test_win32events.pyÚ__init__/   s    zListener.__init__c                 C   s   t ƒ | _dS )Nr	   )r   ÚlogThreadID©r   r   r   r   Ú	logPrefix2   s    zListener.logPrefixc                 C   s   d| _ tƒ | _| j d ¡ d S )NT)Úsuccessr   ÚeventThreadIDr   Úcallbackr   r   r   r   Úoccurred6   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   ÚreturnValueOccurred>   s    zListener.returnValueOccurredc                 C   s   t ƒ | _| j |¡ d S r
   )r   ÚconnLostThreadIDr   Zerrback)r   Úreasonr   r   r   ÚconnectionLostA   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_interfaceM   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>^   ó    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_addEventU   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%   Úresultsr   r   Úcheckn   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_ioThreadDoesNotChangeg   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   rA   r   rB   r   r5   r   rD   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>   rF   rG   rH   r   r   r   r   r#   F   s   r#   )r"   r-   ÚImportErrorZzope.interface.verifyr   Ztwisted.internet.deferr   Ztwisted.internet.interfacesr   Z#twisted.internet.test.reactormixinsr   Ztwisted.python.failurer   Ztwisted.python.threadabler   r   r	   r#   ÚglobalsÚupdateZmakeTestCaseClassesr   r   r   r   Ú<module>   s   
0z