o
    ¯b´a  ã                   @   s<  d Z ddlZddlmZ ddlmZmZmZmZm	Z	m
Z
 ddlmZmZmZ ddlmZ ddlmZ G dd	„ d	ƒZG d
d„ deejƒZG dd„ deejƒZG dd„ deƒZG dd„ deƒZG dd„ dejƒZee e	d¡ dƒG dd„ deƒƒZee e	d¡ dƒG dd„ deƒƒZee e	d¡ dƒG dd„ deƒƒZ dS )zG
Tests for implementations of L{IReactorUDP} and L{IReactorMulticast}.
é    N)ÚskipIf)ÚdeferÚerrorÚ
interfacesÚprotocolÚreactorÚudp)ÚDeferredÚgatherResultsÚmaybeDeferred)Úruntime)ÚTestCasec                   @   s0   e Zd ZdZdZdZdd„ Zdd„ Zdd„ ZdS )	ÚMixinr   Nc                 C   s
   g | _ d S ©N)Úpackets©Úself© r   ú7/usr/lib/python3/dist-packages/twisted/test/test_udp.pyÚ__init__   ó   
zMixin.__init__c                 C   s0   d| _ | jd ur| jd }| _| d ¡ d S d S ©Né   )ÚstartedÚstartedDeferredÚcallback©r   Údr   r   r   ÚstartProtocol   s
   
þzMixin.startProtocolc                 C   s
   d| _ d S r   )Ústoppedr   r   r   r   ÚstopProtocol#   r   zMixin.stopProtocol)	Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r   r    r   r   r   r   r      s    r   c                   @   s   e Zd ZdZdZdd„ ZdS )ÚServerNr   c                 C   s:   | j  ||f¡ | jd ur| jd }| _| d ¡ d S d S r   ©r   ÚappendÚpacketReceivedr   )r   ÚdataÚaddrr   r   r   r   ÚdatagramReceived+   s
   
þzServer.datagramReceived)r!   r"   r#   r'   Úrefusedr*   r   r   r   r   r$   '   s    r$   c                   @   s,   e Zd ZdZdZdd„ Zdd„ Zdd„ ZdS )	ÚClientNr   c                 C   s6   | j  |¡ | jd ur| jd }| _| d ¡ d S d S r   r%   )r   r(   r   r   r   r   r*   7   s
   
þzClient.datagramReceivedc                 C   s,   | j d ur| j d }| _ | |¡ || _d S r   )r   ÚerrbackÚfailure)r   r.   r   r   r   r   ÚconnectionFailed=   s   


zClient.connectionFailedc                 C   ó2   | j d ur| j d }| _ | t d¡¡ d| _d S ©NÚyupr   ©r   r-   r   ÚConnectionRefusedErrorr+   r   r   r   r   ÚconnectionRefusedC   ó   

zClient.connectionRefused)r!   r"   r#   r'   r+   r*   r/   r5   r   r   r   r   r,   2   s    r,   c                   @   ó   e Zd Zdd„ ZdS )Ú
GoodClientc                 C   r0   r1   r3   r   r   r   r   r5   K   r6   zGoodClient.connectionRefusedN)r!   r"   r#   r5   r   r   r   r   r8   J   ó    r8   c                   @   s   e Zd ZdZdS )ÚBadClientErrorzf
    Raised by BadClient at the end of every datagramReceived call to try and
    screw stuff up.
    N)r!   r"   r#   Ú__doc__r   r   r   r   r:   R   s    r:   c                   @   s$   e Zd ZdZdZdd„ Zdd„ ZdS )Ú	BadClientz�
    A DatagramProtocol which always raises an exception from datagramReceived.
    Used to test error handling behavior in the reactor for that method.
    Nc                 C   s
   || _ dS )ze
        Set the Deferred which will be called back when datagramReceived is
        called.
        N)r   r   r   r   r   ÚsetDeferreda   s   
zBadClient.setDeferredc                 C   s*   | j d ur| j d }| _ | |¡ tdƒ‚)NzApplication code is very buggy!)r   r   r:   )r   Úbytesr)   r   r   r   r   r*   h   s   

zBadClient.datagramReceived)r!   r"   r#   r;   r   r=   r*   r   r   r   r   r<   Y   s
    r<   ú!This reactor does not support UDPc                   @   sj   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ Zee	j
 d¡dkdƒdd„ ƒZdd„ Zdd„ Zdd„ ZdS )ÚUDPTestsc                    s<   t ƒ }t ¡  }|_tjd|dd�‰ ‡ ‡fdd„}| |¡S )zu
        The C{type} of the host address of a listening L{DatagramProtocol}'s
        transport is C{"UDP"}.
        r   ú	127.0.0.1©Ú	interfacec                    s   ˆ   ¡ }ˆ |jd¡ ˆ  ¡ S )NÚUDP)ÚgetHostÚassertEqualÚtypeÚstopListening)Úignoredr)   ©Úpr   r   r   Ú	cbStartedz   s   z+UDPTests.test_oldAddress.<locals>.cbStarted©r$   r   r	   r   r   Ú	listenUDPÚaddCallback)r   Úserverr   rL   r   rJ   r   Útest_oldAddressq   s
   
zUDPTests.test_oldAddressc                    sR   t ƒ ‰t ¡  }ˆ_tjdˆdd�‰ ‡ ‡‡fdd„}‡‡fdd„}| |¡ |¡S )z±
        The L{DatagramProtocol}'s C{startProtocol} and C{stopProtocol}
        methods are called when its transports starts and stops listening,
        respectively.
        r   rA   rB   c                    s$   ˆ  ˆjd¡ ˆ  ˆjd¡ ˆ  ¡ S )Nr   r   )rF   r   r   rH   ©rI   ©Úport1r   rP   r   r   rL   ‹   s   z*UDPTests.test_startStop.<locals>.cbStartedc                    s   ˆ   ˆjd¡ d S r   )rF   r   rR   )r   rP   r   r   Ú	cbStopped�   s   z*UDPTests.test_startStop.<locals>.cbStoppedrM   )r   r   rL   rU   r   rS   r   Útest_startStop�   s   zUDPTests.test_startStopc                    sF   t ƒ ‰t ¡  }ˆ_tjdˆdd�}dd„ ‰ ‡ ‡fdd„}| ˆ |¡S )zr
        Re-listening with the same L{DatagramProtocol} re-invokes the
        C{startProtocol} callback.
        r   rA   rB   c                 S   s   |  ¡ S r   ©rH   )rI   Úportr   r   r   rL   ž   ó   z'UDPTests.test_rebind.<locals>.cbStartedc                    s*   t  ¡  }ˆ_tjdˆdd�}| ˆ |¡S ©Nr   rA   rB   )r   r	   r   r   rN   rO   )rI   r   rK   ©rL   rP   r   r   rU   ¡   s   z'UDPTests.test_rebind.<locals>.cbStoppedrM   )r   r   rK   rU   r   r[   r   Útest_rebind•   s   zUDPTests.test_rebindc                    sX   t ƒ ‰t ¡  }ˆ_tjdˆdd�‰ ‡ ‡‡fdd„}| |¡ ‡ fdd„}| |¡ |S )z�
        A L{CannotListenError} exception is raised when attempting to bind a
        second protocol instance to an already bound port
        r   rA   rB   c                    s>   ˆ  ˆ  ¡ ˆj ¡ ¡ tƒ }ˆjtjtjˆ  ¡ j	|dd� d S )NrA   rB   )
rF   rE   Ú	transportr$   ÚassertRaisesr   ÚCannotListenErrorr   rN   rX   )rI   Úserver2©rX   r   rP   r   r   rL   ±   s   
ûz*UDPTests.test_bindError.<locals>.cbStartedc                    s   ˆ   ¡ S r   rW   rR   ©rX   r   r   Ú
cbFinished¾   rY   z+UDPTests.test_bindError.<locals>.cbFinishedrM   )r   r   rL   rc   r   ra   r   Útest_bindError¨   s   

zUDPTests.test_bindErrorc                    s    t ƒ ‰t ¡  }ˆ_tjdˆdd�‰tƒ ‰ t ¡  ‰ˆ _‡ ‡‡fdd„}| |¡}‡ ‡fdd„}| |¡ ‡ ‡‡fdd	„}| |¡ ‡‡fd
d„}| |¡ |S )zŽ
        Datagrams can be sent with the transport's C{write} method and
        received via the C{datagramReceived} callback method.
        r   rA   rB   c                    s   t jdˆ dd�ˆ_ˆS rZ   )r   rN   Úport2rR   )ÚclientÚclientStartedr   r   r   ÚcbServerStartedÐ   s   z2UDPTests.test_sendPackets.<locals>.cbServerStartedc                    sŒ   ˆj  dˆj  ¡ j¡ ˆj  ¡ }ˆj  ¡ }t ¡  }ˆ_ˆj  d|j|jf¡ ddd|j|jffg‰‡ ‡‡‡fdd„‰ tj	ˆ d ƒ|gdd	�S )
NrA   ó   hello)ó   a)ó   bNó   cc                    s6   ˆrt  ¡  }ˆ_| ˆ ¡ ˆjjˆ d¡Ž  |S d S ©Nr   )r   r	   r'   rO   r]   ÚwriteÚpop)rI   ÚnextClientWrite)ÚcbClientSendrf   ÚclientWritesrP   r   r   rq   à   s   
üzHUDPTests.test_sendPackets.<locals>.cbClientStarted.<locals>.cbClientSendT©ÚfireOnOneErrback)
r]   ÚconnectrE   rX   r   r	   r'   rn   ÚhostÚDeferredList)rI   ÚcAddrÚsAddrÚ
serverSend)rf   rP   )rq   rr   r   ÚcbClientStartedÖ   s   


ÿz2UDPTests.test_sendPackets.<locals>.cbClientStartedc                    s`   ˆ j  ¡ }ˆj  ¡ }ˆ ˆ jd|j|jffg¡ |j|jf}ˆ ˆjd|fd|fd|fg¡ d S )Nri   rj   rk   rl   )r]   rE   rF   r   rv   rX   )rI   rx   ry   Ú
clientAddr©rf   r   rP   r   r   ÚcbSendsFinishedð   s   

þz2UDPTests.test_sendPackets.<locals>.cbSendsFinishedc                    s$   t jt  ˆ j¡t  ˆjj¡gdd�S ©NTrs   )r   rw   r   rH   re   rR   )rT   r   r   r   rc   ü   s   
þûz-UDPTests.test_sendPackets.<locals>.cbFinished)r$   r   r	   r   r   rN   r8   rO   )r   ÚserverStartedrh   r   r{   r~   rc   r   )rf   rg   rT   r   rP   r   Útest_sendPacketsÄ   s   




	zUDPTests.test_sendPacketsÚINFRASTRUCTUREÚAZUREPIPELINESz"Hangs on Pipelines due to firewallc                    s�   t ƒ ‰ t ¡  }ˆ _tjdˆ dd�‰tƒ ‰t ¡  }ˆ_tjdˆdd�‰tj||gdd�}‡ ‡‡fdd„}| |¡ ‡‡fdd	„}| |¡ |S )
zÎ
        A L{ConnectionRefusedError} exception is raised when a connection
        attempt is actively refused by the other end.

        Note: This test assumes no one is listening on port 80 UDP.
        r   rA   rB   Trs   c                    s^   t  ¡  }ˆ _ˆ j dd¡ tdƒD ]}ˆ j d|f ¡ ˆj d|f d¡ qˆ |tj	¡S )NrA   éP   é
   ó   %d)rA   r„   )
r   r	   r   r]   ru   Úrangern   ÚassertFailurer   r4   )rI   r5   Úir}   r   r   rL     s   z2UDPTests.test_connectionRefused.<locals>.cbStartedc                    s"   t jt  ˆ j¡t  ˆj¡gdd�S r   )r   rw   r   rH   rR   )rX   re   r   r   rc   )  s   

þûz3UDPTests.test_connectionRefused.<locals>.cbFinished)	r8   r   r	   r   r   rN   r$   rw   rO   )r   rg   r€   r   rL   rc   r   )rf   rX   re   r   rP   r   Útest_connectionRefused  s   


	zUDPTests.test_connectionRefusedc                 C   sV   t ƒ }tjd|dd�}|  tj|jjdd¡ |j dd¡ |  t|jjdd¡ | 	¡ S )a   
        A call to the transport's connect method fails with an
        L{InvalidAddressError} when a non-IP address is passed as the host
        value.

        A call to a transport's connect method fails with a L{RuntimeError}
        when the transport is already connected.
        r   rA   rB   Ú	localhostr„   )
r8   r   rN   r^   r   ÚInvalidAddressErrorr]   ru   ÚRuntimeErrorrH   )r   rf   rX   r   r   r   Útest_badConnect5  s   	ÿzUDPTests.test_badConnectc                    s„   t  ¡ ‰‡fdd„}ˆ |¡ tƒ ‰tjdˆdd�‰‡fdd„}ˆ |¡ ˆ ¡ ‰ tt	dƒƒ‰g ‰‡ ‡‡‡‡‡‡fd	d
„‰ˆƒ  ˆS )zr
        When datagramReceived raises an exception it is logged but the port
        is not disconnected.
        c                    s*   ˆ   t¡}ˆ  t|ƒddt|ƒf ¡ dS )z…
            Flush the exceptions which the reactor should have logged and make
            sure they're actually there.
            é   z'Incorrectly found %d errors, expected 2N)ÚflushLoggedErrorsr:   rF   Úlen)ÚignÚerrsr   r   r   ÚcbCompletedN  s   
ÿz8UDPTests.test_datagramReceivedError.<locals>.cbCompletedr   rA   rB   c                    s   t  ˆj¡ ‡ fdd„¡S )zƒ
            Disconnect the port we started and pass on whatever was given to us
            in case it was a Failure.
            c                    ó   ˆ S r   r   ©r’   ©Úresultr   r   Ú<lambda>b  ó    zHUDPTests.test_datagramReceivedError.<locals>.cbCleanup.<locals>.<lambda>)r   r   rH   ÚaddBothr—   rb   r—   r   Ú	cbCleanup]  s   z6UDPTests.test_datagramReceivedError.<locals>.cbCleanupé<   c                     sÆ   ˆszˆ  d¡ W n ty   ˆ ¡  Y nw ˆ ˆjdd¡ dˆ d¡f } t ¡ }ˆ |¡ ˆj 	| ˆj
ˆjf¡ ‡‡‡‡ fdd„}‡fdd	„}| ||¡ | ˆj¡ t d
|jt d¡¡‰ dS )a6  
            Send one packet to the listening BadClient.  Set up a 0.1 second
            timeout to do re-transmits in case the packet is dropped.  When two
            packets have been received by the BadClient, stop sending and let
            the finalDeferred's callbacks do some assertions.
            zNot enough packets receivedNzUDP Protocol lost its transportr†   r   c                    s<   ˆ  ¡  ˆ | ¡ tˆƒdkrt dˆ jd¡ dS ˆƒ  dS )z…
                A packet arrived.  Cancel the timeout for it, record it, and
                maybe finish the test.
                r�   r   N)Úcancelr&   r‘   r   Ú	callLaterr   )Úpacket)ÚfinalDeferredÚmakeAttemptÚsucceededAttemptsÚtimeoutCallr   r   ÚcbPacketReceived‰  s
   

zRUDPTests.test_datagramReceivedError.<locals>.makeAttempt.<locals>.cbPacketReceivedc                    s
   ˆ ƒ  dS )aÄ  
                The packet wasn't received quickly enough.  Try sending another
                one.  It doesn't matter if the packet for which this was the
                timeout eventually arrives: makeAttempt throws away the
                Deferred on which this function is the errback, so when
                datagramReceived callbacks, so it won't be on this Deferred, so
                it won't raise an AlreadyCalledError.
                Nr   )Úerr)r¢   r   r   ÚebPacketTimeout™  s   
	zQUDPTests.test_datagramReceivedError.<locals>.makeAttempt.<locals>.ebPacketTimeoutgš™™™™™¹?z&Timed out in testDatagramReceivedError)ÚfailÚ	Exceptionr-   ÚfailIfIdenticalr]   ro   r   r	   r=   rn   rv   rX   ÚaddCallbacksÚ
addErrbackr   rŸ   r   ÚTimeoutError)r    ÚpacketDeferredr¥   r§   )r)   Úattemptsrf   r¡   r¢   r   r£   )r¤   r   r¢   s  s,   ÿÿ
ýz8UDPTests.test_datagramReceivedError.<locals>.makeAttempt)
r   r	   rO   r<   r   rN   r›   rE   Úlistr‡   )r   r”   rœ   r   )r)   r¯   rf   r¡   r¢   rX   r   r£   r   Útest_datagramReceivedErrorG  s   



:z#UDPTests.test_datagramReceivedErrorc                 C   sR   G dd„ dƒ}t  dtƒ ¡}|ƒ |_| dd¡ |  | jg¡}|  t|ƒd¡ dS )ai  
        C{'<broadcast>'} is an alternative way to say C{'255.255.255.255'}
        ({socket.gethostbyname("<broadcast>")} returns C{'255.255.255.255'}),
        so because it becomes a valid IP address, no deprecation warning about
        passing hostnames to L{twisted.internet.udp.Port.write} needs to be
        emitted by C{write()} in this case.
        c                   @   r7   )z6UDPTests.test_NoWarningOnBroadcast.<locals>.fakeSocketc                 S   s   d S r   r   )r   ÚfooÚbarr   r   r   Úsendtoº  s   z=UDPTests.test_NoWarningOnBroadcast.<locals>.fakeSocket.sendtoN)r!   r"   r#   r´   r   r   r   r   Ú
fakeSocket¹  r9   rµ   r   s   test)z<broadcast>iÒ  N)	r   ÚPortr$   Úsocketrn   ÚflushWarningsÚtest_NoWarningOnBroadcastrF   r‘   )r   rµ   rK   Úwarningsr   r   r   r¹   °  s   	z"UDPTests.test_NoWarningOnBroadcastN)r!   r"   r#   rQ   rV   r\   rd   r�   r   ÚosÚenvironÚgetrŠ   rŽ   r±   r¹   r   r   r   r   r@   o   s    Dþ
)ir@   c                   @   s8   e Zd ZdZe ed¡sdZdd„ Zdd„ Z	dd	„ Z
dS )
ÚReactorShutdownInteractionTestsz!Test reactor shutdown interactionNr?   c                 C   s    t ƒ | _tjd| jdd�| _dS )zStart a UDP portr   rA   rB   N)r$   rP   r   rN   rX   r   r   r   r   ÚsetUpÌ  s   z%ReactorShutdownInteractionTests.setUpc                 C   s
   | j  ¡ S )zStop the UDP port)rX   rH   r   r   r   r   ÚtearDownÑ  s   
z(ReactorShutdownInteractionTests.tearDownc                    sh   t  ¡ ‰ t  ¡  }ˆj_‡ ‡fdd„}| |¡ ‡fdd„}ˆ  |¡ ˆjj ddˆjj ¡ jf¡ ˆ S )z0Test reactor shutdown while in a recvfrom() loopc                    s    ˆj j ¡  t dˆ jd ¡ d S rm   )rP   r]   ÚconnectionLostr   rŸ   r   rR   ©Úfinishedr   r   r   ÚpktReceä  s   zQReactorShutdownInteractionTests.testShutdownFromDatagramReceived.<locals>.pktRecec                    s   ˆ   ¡  d S r   )r�   rR   r   r   r   ÚflushErrorsî  s   zUReactorShutdownInteractionTests.testShutdownFromDatagramReceived.<locals>.flushErrorss@                                                                   rA   )	r   r	   rP   r'   rO   r]   rn   rE   rX   )r   ÚprrÄ   rÅ   r   rÂ   r   Ú testShutdownFromDatagramReceivedÕ  s   

ÿz@ReactorShutdownInteractionTests.testShutdownFromDatagramReceived)r!   r"   r#   r;   r   ÚIReactorUDPr   Úskipr¿   rÀ   rÇ   r   r   r   r   r¾   Å  s    r¾   ú'This reactor does not support multicastc                   @   s®   e Zd Zej d¡dkrej ¡ rdZ	e
 ed¡sdZ	dd„ Zdd	„ Zd
d„ Zdd„ Zdd„ Zdd„ Zeej ¡ o>ej ¡  dƒdd„ ƒZdd„ Zeej ¡ dƒdd„ ƒZdS )ÚMulticastTestsr‚   rƒ   z Does not work on Azure PipelinesNrÊ   c                 C   sN   t ƒ | _tƒ | _t d| j¡| _t d| j¡| _| jj 	d| jj 
¡ j¡ d S )Nr   rA   )r$   rP   r,   rf   r   ÚlistenMulticastrT   re   r]   ru   rE   rX   r   r   r   r   r¿     s
   zMulticastTests.setUpc                 C   s   t t| jjƒt| jjƒgƒS r   )r
   r   rT   rH   re   r   r   r   r   rÀ     s
   

þÿzMulticastTests.tearDownc                 C   sF   | j | jfD ]}|  |j ¡ d¡ |j d¡ |  |j ¡ d¡ qd S )Nr   r�   )rf   rP   rF   r]   ÚgetTTLÚsetTTL)r   Úor   r   r   ÚtestTTL  s
   ýzMulticastTests.testTTLc                    sx   ˆ  ˆjj ¡ d¡ ˆjj ¡ ‰ ˆjj d¡}‡ ‡fdd„}| |¡ ‡ ‡fdd„}| |¡ ‡fdd„}| |¡ |S )	zv
        Test that after loopback mode has been set, multicast packets are
        delivered to their sender.
        r   ú225.0.0.250c                    s(   t ƒ  }ˆj_ˆjj ddˆ jf¡ |S )Nri   rÑ   ©r	   rP   r'   r]   rn   rX   ©rI   r   ©r)   r   r   r   ÚcbJoined*  s   z.MulticastTests.test_loopback.<locals>.cbJoinedc                    sf   ˆ  tˆjjƒd¡ ˆjj d¡ ˆ  ˆjj ¡ d¡ ˆjj ddˆ jf¡ t	ƒ }t
 d|jd ¡ |S )Nr   r   ri   rÑ   )rF   r‘   rP   r   r]   ÚsetLoopbackModeÚgetLoopbackModern   rX   r	   r   rŸ   r   rÓ   rÔ   r   r   ÚcbPacket1  s   z.MulticastTests.test_loopback.<locals>.cbPacketc                    s   ˆ   tˆ jjƒd¡ d S r   )rF   r‘   rP   r   rR   r   r   r   Ú
cbNoPacket>  s   z0MulticastTests.test_loopback.<locals>.cbNoPacket)rF   rP   r]   r×   rE   Ú	joinGrouprO   )r   ÚjoinedrÕ   rØ   rÙ   r   rÔ   r   Útest_loopback!  s   


zMulticastTests.test_loopbackc                    sj   ˆ   ˆ jj ¡ d¡ ˆ   ˆ jj ¡ d¡ ˆ jj d¡}ˆ jj d¡}t||gƒ}‡ fdd„}| |¡ |S )zK
        Test C{getOutgoingInterface} and C{setOutgoingInterface}.
        z0.0.0.0rA   c                    s,   ˆ   ˆ jj ¡ d¡ ˆ   ˆ jj ¡ d¡ d S )NrA   )rF   rf   r]   ÚgetOutgoingInterfacerP   rR   r   r   r   ÚcbInterfacesP  s   z3MulticastTests.test_interface.<locals>.cbInterfaces)rF   rf   r]   rÝ   rP   ÚsetOutgoingInterfacer
   rO   )r   Úd1Úd2r˜   rÞ   r   r   r   Útest_interfaceE  s   
zMulticastTests.test_interfacec                    sT   ˆ j j d¡}‡ fdd„}| |¡ ‡ fdd„}| |¡ ‡ fdd„}| |¡ |S )zE
        Test that multicast a group can be joined and left.
        rÑ   c                    ó   ˆ j j d¡S ©NrÑ   )rf   r]   Ú
leaveGrouprR   r   r   r   ÚclientJoined]  ó   z3MulticastTests.test_joinLeave.<locals>.clientJoinedc                    rã   rä   )rP   r]   rÚ   rR   r   r   r   Ú
clientLeftb  rç   z1MulticastTests.test_joinLeave.<locals>.clientLeftc                    rã   rä   )rP   r]   rå   rR   r   r   r   ÚserverJoinedg  rç   z3MulticastTests.test_joinLeave.<locals>.serverJoined)rf   r]   rÚ   rO   )r   r   ræ   rè   ré   r   r   r   Útest_joinLeaveW  s   


zMulticastTests.test_joinLeavez2Windows' UDP multicast is not yet fully supported.c                 C   s   |   | jj d¡tj¡S )zŠ
        Test that an attempt to join an address which is not a multicast
        address fails with L{error.MulticastJoinError}.
        rA   )rˆ   rf   r]   rÚ   r   ÚMulticastJoinErrorr   r   r   r   Útest_joinFailureo  s   
ÿzMulticastTests.test_joinFailurec                    sv   t ƒ ‰t dˆ¡‰ˆjj ¡ ‰ ˆjj d¡}‡ ‡‡fdd„}| |¡ ‡fdd„}| |¡ ‡fdd„}| |¡ |S )	zn
        Test that a multicast group can be joined and messages sent to and
        received from it.
        r   rÑ   c                    s&   t ƒ  }ˆj_ˆj ddˆ jf¡ |S )Nó   hello worldrÑ   rÒ   rÓ   )r)   Úcr   r   r   rÕ   ˆ  s   z/MulticastTests.test_multicast.<locals>.cbJoinedc                    s   ˆ   ˆ jjd d d¡ d S ©Nr   rí   )rF   rP   r   rR   r   r   r   rØ   �  s   z/MulticastTests.test_multicast.<locals>.cbPacketc                    s    t ˆjƒ}| ‡ fdd„¡ |S )Nc                    r•   r   r   r–   ©Úpassthroughr   r   r™   –  rš   z@MulticastTests.test_multicast.<locals>.cleanup.<locals>.<lambda>)r   rH   rO   ©rñ   r˜   )rK   rð   r   Úcleanup”  s   
z.MulticastTests.test_multicast.<locals>.cleanup)r$   r   rÌ   rP   r]   rE   rÚ   rO   )r   rÛ   rÕ   rØ   ró   r   )r)   rî   rK   r   r   Útest_multicast}  s   


zMulticastTests.test_multicastzjon non-linux platforms it appears multiple processes can listen, but not multiple sockets in same process?c                    s°   t ƒ ‰ tjdˆ dd�‰ˆ ¡ j‰t ƒ ‰tjˆˆdd�‰d‰tˆjj ˆ¡ˆ ˆ¡ˆ ˆ¡gƒ}‡ ‡‡‡fdd„}| 	|¡ ‡ ‡‡fdd„}| 	|¡ ‡‡fd	d
„}| 
|¡ |S )z¢
        Test that multiple sockets can listen on the same multicast port and
        that they both receive multicast messages directed to that address.
        r   T)ÚlistenMultiplerÑ   c                    s6   t ƒ  }ˆ _t ƒ  }ˆ_ˆ j dˆˆf¡ t||gƒS )Nrí   )r	   r'   r]   rn   r
   )rI   rà   rá   )ÚfirstClientÚportnoÚsecondClientÚtheGroupr   r   ré   ¹  s   z5MulticastTests.test_multiListen.<locals>.serverJoinedc                    s0   ˆ  ˆ jd d d¡ ˆ  ˆjd d d¡ d S rï   )rF   r   rR   )rö   rø   r   r   r   Ú
gotPacketsÁ  s   z3MulticastTests.test_multiListen.<locals>.gotPacketsc                    s.   t tˆjƒtˆjƒgƒ}| ‡ fdd„¡ |S )Nc                    r•   r   r   r–   rð   r   r   r™   Î  rš   zBMulticastTests.test_multiListen.<locals>.cleanup.<locals>.<lambda>)r
   r   rH   rO   rò   )Ú	firstPortÚ
secondPortrð   r   ró   Ç  s   þÿz0MulticastTests.test_multiListen.<locals>.cleanup)r$   r   rÌ   rE   rX   r
   rP   r]   rÚ   rO   r›   )r   rÛ   ré   rú   ró   r   )rö   rû   r÷   rø   rü   r   rù   r   Útest_multiListen�  s&   
ýÿ



zMulticastTests.test_multiListen)r!   r"   r#   r»   r¼   r½   r   ÚplatformÚisMacOSXrÉ   r   ÚIReactorMulticastr   r¿   rÀ   rÐ   rÜ   râ   rê   r   Ú	isWindowsÚisVistarì   rô   rý   r   r   r   r   rË   ü  s0    ÿ$þ

 þrË   )!r;   r»   Úunittestr   Útwisted.internetr   r   r   r   r   r   Útwisted.internet.deferr	   r
   r   Útwisted.pythonr   Útwisted.trial.unittestr   r   ÚDatagramProtocolr$   ÚConnectedDatagramProtocolr,   r8   r©   r:   r<   rÈ   r@   r¾   r   rË   r   r   r   r   Ú<module>   s0      W6þ