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