o
    ¯bI  ã                   @   s¦   d Z zddlZW n ey   dZY nw 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   ú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   Ú	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ƒ‚)NzSome problem)ÚRuntimeErrorr   r   r   r   ÚbrokenOccurred;   ó   zListener.brokenOccurredc                 C   s   t dƒS )NzEntirely different problem)ÚEnvironmentErrorr   r   r   r   ÚreturnValueOccurred>   r   zListener.returnValueOccurredc                 C   s   t ƒ | _| j |¡ d S r
   )r   ÚconnLostThreadIDr   Ú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 r
   ©Ústop©Ú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&   r1   r2   r   r	   r3   r4   r5   r6   r7   r8   r   r9   )r   rA   r;   r   r<   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                    r)   r
   r*   r,   r.   r   r   r/   Š   r0   zBWin32EventsTestsBuilder.test_disconnectedOnError.<locals>.<lambda>r   r   é   )r   r&   r1   r2   r   ÚaddBothr>   r	   r4   r5   r6   r7   ÚassertIsInstancer   Útrapr   r9   r   ÚlenÚflushLoggedErrors©r   r:   r;   Úresultr   r<   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                    r)   r
   r*   r,   r.   r   r   r/   ¤   r0   zFWin32EventsTestsBuilder.test_disconnectOnReturnValue.<locals>.<lambda>r   r   )r   r&   r1   r2   r   rD   r>   r	   r4   r5   r6   r7   rE   r   rF   r   r9   r   rI   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&   r1   r2   r   r	   r4   r5   r+   r7   ÚassertIsNoner   )r   r'   r;   r   r<   r   r   r   Útest_notDisconnectedOnShutdown°   s   
z6Win32EventsTestsBuilder.test_notDisconnectedOnShutdownN)r!   r"   r#   r$   r   ÚrequiredInterfacesr(   r=   rB   rK   rL   rN   r   r   r   r   r%   F   s    r%   )r$   r1   ÚImportErrorÚzope.interface.verifyr   Útwisted.internet.deferr   Útwisted.internet.interfacesr   Ú#twisted.internet.test.reactormixinsr   Útwisted.python.failurer   Útwisted.python.threadabler   r   r	   r%   ÚglobalsÚupdateÚmakeTestCaseClassesr   r   r   r   Ú<module>   s   ÿ0z