U
    2ÜŸj}w  ã                	   @  s8  d Z ddlmZ ddlZddlmZmZmZmZm	Z	m
Z
mZmZmZmZm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 ddlmZmZmZ dd	lm Z  dd
l!m"Z"m#Z#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.ej/ƒZ0G dd„ de.ej1ƒZ2G dd„ de0ƒZ3G dd„ de4ƒZ5G dd„ dej/ƒZ6ee 7ed¡ dƒG dd„ de-ƒƒZ8ee 7ed¡ dƒG dd„ de-ƒƒZ9d d!d!d"d"d#d$œd%d&„Z:ee #ed¡ d'ƒee:eeed(d)ƒ d*ƒG d+d,„ d,e-ƒƒƒZ;ee #ed¡ d'ƒe*ee:ee	e
d-d.ƒ d/ƒG d0d1„ d1e;ƒƒƒƒZ<dS )2zG
Tests for implementations of L{IReactorUDP} and L{IReactorMulticast}.
é    )ÚannotationsN)ÚAF_INETÚAF_INET6ÚIP_ADD_MEMBERSHIPÚ
IPPROTO_IPÚIPPROTO_IPV6ÚIPV6_JOIN_GROUPÚ
SOCK_DGRAMÚAddressFamilyÚif_nameindexÚ	inet_ptonÚsocket)ÚskipIf)ÚdeferÚerrorÚ
interfacesÚprotocolÚreactorÚudp)ÚIPv4AddressÚIPv6Address)ÚDeferredÚgatherResultsÚmaybeDeferred)ÚMulticastJoinError)ÚIMulticastTransportÚIReactorMulticastÚIReactorTime)Ú
deferLater)Úruntime)ÚskipWithoutIPv6)ÚSkipTestÚ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(   ú9/tmp/pip-unpacked-wheel-4b529toj/twisted/test/test_udp.pyÚ__init__0   s    zMixin.__init__c                 C  s,   d| _ | jd k	r(| jd  }| _| d ¡ d S ©Né   )ÚstartedÚstartedDeferredÚcallback©r'   Údr(   r(   r)   ÚstartProtocol3   s    
zMixin.startProtocolc                 C  s
   d| _ d S r+   )Ústoppedr&   r(   r(   r)   ÚstopProtocol9   s    zMixin.stopProtocol)	Ú__name__Ú
__module__Ú__qualname__r-   r3   r.   r*   r2   r4   r(   r(   r(   r)   r#   *   s   r#   c                   @  s.   e Zd ZU dZded< dZded< dd„ ZdS )	ÚServerNzDeferred[None] | NoneÚpacketReceivedr   r   Ú	transportc                 C  s6   | j  ||f¡ | jd k	r2| jd  }| _| d ¡ d S r$   ©r%   Úappendr9   r/   )r'   ÚdataÚaddrr1   r(   r(   r)   ÚdatagramReceivedB   s    
zServer.datagramReceived)r5   r6   r7   r9   Ú__annotations__Úrefusedr?   r(   r(   r(   r)   r8   =   s   
r8   c                   @  s,   e Zd ZdZdZdd„ Zdd„ Zdd„ ZdS )	ÚClientNr   c                 C  s2   | j  |¡ | jd k	r.| jd  }| _| d ¡ d S r$   r;   )r'   r=   r1   r(   r(   r)   r?   M   s    
zClient.datagramReceivedc                 C  s,   | j d k	r"| j d  }| _ | |¡ || _d S r$   )r.   ÚerrbackÚfailure)r'   rD   r1   r(   r(   r)   ÚconnectionFailedS   s    

zClient.connectionFailedc                 C  s2   | j d k	r(| j d  }| _ | t d¡¡ d| _d S ©NZyupr,   ©r.   rC   r   ÚConnectionRefusedErrorrA   r0   r(   r(   r)   ÚconnectionRefusedY   s    
zClient.connectionRefused)r5   r6   r7   r9   rA   r?   rE   rI   r(   r(   r(   r)   rB   I   s
   rB   c                   @  s   e Zd Zdd„ ZdS )Ú
GoodClientc                 C  s2   | j d k	r(| j d  }| _ | t d¡¡ d| _d S rF   rG   r0   r(   r(   r)   rI   a   s    
zGoodClient.connectionRefusedN)r5   r6   r7   rI   r(   r(   r(   r)   rJ   `   s   rJ   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)r5   r6   r7   Ú__doc__r(   r(   r(   r)   rK   h   s   rK   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)r1   r0   r(   r(   r)   ÚsetDeferredw   s    zBadClient.setDeferredc                 C  s.   | j d k	r"| j d  }| _ | |¡ tdƒ‚d S )NzApplication code is very buggy!)r1   r/   rK   )r'   Úbytesr>   r1   r(   r(   r)   r?   ~   s    

zBadClient.datagramReceived)r5   r6   r7   rL   r1   rN   r?   r(   r(   r(   r)   rM   o   s   rM   ú!This reactor does not support UDPc                   @  sr   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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 )NZUDP)ÚgetHostÚassertEqualÚtypeÚstopListening)Úignoredr>   ©Úpr'   r(   r)   Ú	cbStarted�   s    z+UDPTests.test_oldAddress.<locals>.cbStarted©r8   r   r   r.   r   Ú	listenUDPÚaddCallback)r'   Úserverr1   r\   r(   rZ   r)   Útest_oldAddress‡   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   rR   rS   c                   s$   ˆ  ˆjd¡ ˆ  ˆjd¡ ˆ  ¡ S )Nr,   r   )rV   r-   r3   rX   ©rY   ©Úport1r'   r`   r(   r)   r\   ¡   s    z*UDPTests.test_startStop.<locals>.cbStartedc                   s   ˆ   ˆjd¡ d S r+   )rV   r3   rb   )r'   r`   r(   r)   Ú	cbStopped¦   s    z*UDPTests.test_startStop.<locals>.cbStoppedr]   )r'   r1   r\   re   r(   rc   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   rR   rS   c                 S  s   |  ¡ S r$   ©rX   )rY   Úportr(   r(   r)   r\   ´   s    z'UDPTests.test_rebind.<locals>.cbStartedc                   s*   t  ¡  }ˆ_tjdˆdd�}| ˆ |¡S ©Nr   rR   rS   )r   r   r.   r   r^   r_   )rY   r1   r[   ©r\   r`   r(   r)   re   ·   s    z'UDPTests.test_rebind.<locals>.cbStoppedr]   )r'   r1   r[   re   r(   rj   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   rR   rS   c                   s>   ˆ  ˆ  ¡ ˆj ¡ ¡ tƒ }ˆjtjtjˆ  ¡ j	|dd� d S )NrR   rS   )
rV   rU   r:   r8   ÚassertRaisesr   ZCannotListenErrorr   r^   rh   )rY   Zserver2©rh   r'   r`   r(   r)   r\   Ç   s    ûz*UDPTests.test_bindError.<locals>.cbStartedc                   s   ˆ   ¡ S r$   rg   rb   ©rh   r(   r)   Ú
cbFinishedÔ   s    z+UDPTests.test_bindError.<locals>.cbFinishedr]   )r'   r1   r\   ro   r(   rm   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   rR   rS   c                   s   t jdˆ dd�ˆ_ˆS ri   )r   r^   Úport2rb   )Ú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 )
NrR   ó   hello)ó   a)ó   bNó   cc                   s6   ˆr2t  ¡  }ˆ_| ˆ ¡ ˆjjˆ d¡Ž  |S d S ©Nr   )r   r   r9   r_   r:   ÚwriteÚpop)rY   ZnextClientWrite)ÚcbClientSendrr   ÚclientWritesr`   r(   r)   r|   ö   s
    
zHUDPTests.test_sendPackets.<locals>.cbClientStarted.<locals>.cbClientSendT©ZfireOnOneErrback)
r:   ÚconnectrU   rh   r   r   r9   rz   ÚhostÚDeferredList)rY   ÚcAddrÚsAddrZ
serverSend)rr   r`   )r|   r}   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 )Nru   rv   rw   rx   )r:   rU   rV   r%   r€   rh   )rY   r‚   rƒ   Z
clientAddr©rr   r'   r`   r(   r)   ÚcbSendsFinished  s    

þz2UDPTests.test_sendPackets.<locals>.cbSendsFinishedc                   s$   t jt  ˆ j¡t  ˆjj¡gdd�S ©NTr~   )r   r�   r   rX   rq   rb   )rd   r'   r(   r)   ro     s    
þûz-UDPTests.test_sendPackets.<locals>.cbFinished)r8   r   r   r.   r   r^   rJ   r_   )r'   ÚserverStartedrt   r1   r„   r†   ro   r(   )rr   rs   rd   r'   r`   r)   Útest_sendPacketsÚ   s    



	
zUDPTests.test_sendPacketsZINFRASTRUCTUREZ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   rR   rS   Tr~   c                   s^   t  ¡  }ˆ _ˆ j dd¡ tdƒD ]*}ˆ j d|f ¡ ˆj d|f d¡ q$ˆ |tj	¡S )NrR   éP   é
   ó   %d©rR   rŠ   )
r   r   r.   r:   r   Úrangerz   ÚassertFailurer   rH   )rY   rI   Úir…   r(   r)   r\   3  s    z2UDPTests.test_connectionRefused.<locals>.cbStartedc                   s"   t jt  ˆ j¡t  ˆj¡gdd�S r‡   ©r   r�   r   rX   rb   )rh   rq   r(   r)   ro   ?  s    

þûz3UDPTests.test_connectionRefused.<locals>.cbFinished)	rJ   r   r   r.   r   r^   r8   r�   r_   )r'   rs   rˆ   r1   r\   ro   r(   )rr   rh   rq   r'   r`   r)   Útest_connectionRefused  s    

	
zUDPTests.test_connectionRefusedc           	        sÐ   t ƒ ‰ t ¡  }ˆ _tjdˆ dd�‰d‰tƒ ‰t ¡  }ˆ_t ¡  }ˆ_tjdˆdd�‰tj||gdd�}‡ ‡‡‡fdd„}| 	|¡ tj||gdd�}‡‡‡fd	d
„}| 	|¡ ‡‡fdd„}| 	|¡ |S )as  
        When a server fails to successfully read a packet the server should
        still be able to process future packets.
        The IOCP reactor had a historical problem where a failure to read caused
        the reactor to ignore any future reads. This test should prevent a regression.

        Note: This test assumes no one is listening on port 80 UDP.
        r   rR   rS   s   Sending test packet to serverTr~   c                   s&   ˆj  dd¡ ˆ j  ˆdˆjf¡ d S )Ns$   write to port no one is listening tor�   rR   )r:   rz   Z_realPortNumberrb   )rr   r`   Ú
serverPortÚtest_data_to_sendr(   r)   ÚcbClientAndServerStartedb  s     ÿ ÿzAUDPTests.test_serverReadFailure.<locals>.cbClientAndServerStartedc                   s   ˆ   ˆjd d ˆ¡ d S ry   )rV   r%   rb   )r'   r`   r”   r(   r)   Úverify_server_got_datau  s    z?UDPTests.test_serverReadFailure.<locals>.verify_server_got_datac                   s"   t jt  ˆ j¡t  ˆj¡gdd�S r‡   r‘   rb   )Ú
clientPortr“   r(   r)   Úcleanupz  s    

þûz0UDPTests.test_serverReadFailure.<locals>.cleanup)
rJ   r   r   r.   r   r^   r8   r9   r�   r_   )	r'   rs   rˆ   ZserverGotDataZserver_client_started_dr•   Zall_data_sentr–   r˜   r(   )rr   r—   r'   r`   r“   r”   r)   Útest_serverReadFailureK  s.    	 ÿ
 ÿ
	
zUDPTests.test_serverReadFailurec                 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   rR   rS   Ú	localhostrŠ   )
rJ   r   r^   rl   r   ZInvalidAddressErrorr:   r   ÚRuntimeErrorrX   )r'   rr   rh   r(   r(   r)   Útest_badConnect‡  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)ÚflushLoggedErrorsrK   rV   Úlen)ÚignZerrsr&   r(   r)   ÚcbCompleted   s    
  ÿz8UDPTests.test_datagramReceivedError.<locals>.cbCompletedr   rR   rS   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   ˆ S r$   r(   ©r    ©Úresultr(   r)   Ú<lambda>´  ó    zHUDPTests.test_datagramReceivedError.<locals>.cbCleanup.<locals>.<lambda>)r   r   rX   ÚaddBothr£   rn   r£   r)   Ú	cbCleanup¯  s    z6UDPTests.test_datagramReceivedError.<locals>.cbCleanupé<   c                    sÈ   ˆs0zˆ  d¡ W n tk
r.   ˆ ¡  Y nX ˆ ˆ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r0t dˆ jd¡ nˆƒ  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)ZfailÚ	ExceptionrC   ZfailIfIdenticalr:   r{   r   r   rN   rz   r€   rh   ZaddCallbacksZ
addErrbackr   r«   r   ÚTimeoutError)r¬   ZpacketDeferredr±   r³   )r>   Úattemptsrr   r­   r®   r'   r¯   )r°   r)   r®   Å  s.      ÿ
ýz8UDPTests.test_datagramReceivedError.<locals>.makeAttempt)
r   r   r_   rM   r   r^   r§   rU   ÚlistrŽ   )r'   r¡   r¨   r(   )r>   r¶   rr   r­   r®   rh   r'   r¯   r)   Útest_datagramReceivedError™  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                   @  s   e Zd Zdd„ ZdS )z6UDPTests.test_NoWarningOnBroadcast.<locals>.fakeSocketc                 S  s   d S r$   r(   )r'   ZfooÚbarr(   r(   r)   Úsendto  s    z=UDPTests.test_NoWarningOnBroadcast.<locals>.fakeSocket.sendtoN)r5   r6   r7   rº   r(   r(   r(   r)   Ú
fakeSocket  s   r»   r   s   test)z<broadcast>iÒ  N)	r   ZPortr8   r   rz   ZflushWarningsÚtest_NoWarningOnBroadcastrV   rŸ   )r'   r»   r[   Úwarningsr(   r(   r)   r¼     s    	z"UDPTests.test_NoWarningOnBroadcastN)r5   r6   r7   ra   rf   rk   rp   r‰   r   ÚosÚenvironÚgetr’   r™   rœ   r¸   r¼   r(   r(   r(   r)   rQ   …   s   Dþ
)<irQ   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 interactionNrP   c                 C  s    t ƒ | _tjd| jdd�| _dS )zStart a UDP portr   rR   rS   N)r8   r`   r   r^   rh   r&   r(   r(   r)   ÚsetUp  s    z%ReactorShutdownInteractionTests.setUpc                 C  s
   | j  ¡ S )zStop the UDP port)rh   rX   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 ry   )r`   r:   ZconnectionLostr   r«   r/   rb   ©Úfinishedr'   r(   r)   ÚpktRece6  s    zQReactorShutdownInteractionTests.testShutdownFromDatagramReceived.<locals>.pktRecec                   s   ˆ   ¡  d S r$   )rž   rb   r&   r(   r)   ÚflushErrors@  s    zUReactorShutdownInteractionTests.testShutdownFromDatagramReceived.<locals>.flushErrorss@                                                                   rR   )	r   r   r`   r9   r_   r:   rz   rU   rh   )r'   ÚprrÆ   rÇ   r(   rÄ   r)   Ú testShutdownFromDatagramReceived'  s    

 ÿz@ReactorShutdownInteractionTests.testShutdownFromDatagramReceived)r5   r6   r7   rL   r   ÚIReactorUDPr   ÚskiprÂ   rÃ   rÉ   r(   r(   r(   r)   rÁ     s   rÁ   r
   ÚintÚstrÚbool)ÚafÚipprotoÚjoinÚgroupÚbindtoÚreturnc                 C  sz   t | tƒ}| |df¡ t| |ƒ}t| |ƒ}z>z| |||| ¡ W n tk
r^   Y W ¢dS X W ¢dS W 5 | ¡  X dS )a	  
    Bind a socket to the given network interface and attempt to join a
    multicast group with the given address family.  This is used to determine
    whether the local networking stack configuration allows for multicast
    within the given address family.
    r   FTN)r   r	   Úbindr   ÚcloseÚ
setsockoptÚOSError)rÏ   rÐ   rÑ   rÒ   rÓ   ÚsZ	packgroupZpackifr(   r(   r)   ÚcheckMulticastAvailabilityN  s    	


rÚ   z'This reactor does not support multicastú225.0.0.250ú0.0.0.0z:The local networking stack does not enable IPv4 multicast.c                   @  s  e Zd ZU dZdZded< dZded< dZded< d	Zded
< dZ	ded< dZ
ded< dZded< dZded< dd„ Zdd„ Zddœdd„Zddœdd„Zddœdd„Zddœdd„Zddœdd „Zeej ¡ oÚej ¡  d!ƒd"d#„ ƒZd$d%„ Zeej ¡ d&ƒddœd'd(„ƒZd)S )*ÚMulticastTestszs
    Tests for sending and receiving multicast datagrams.  (This suite supports
    IPv4, see below for IPv6.)
    rÜ   rÍ   rT   ú	str | intÚexpectedInterfacerR   ÚclientAddressrÛ   ÚmulticastGroupÚalternateInterfacerš   ÚinterfaceSynonymÚinvalidGroupú::1ÚwrongAddressFamilyc                 C  sX   t ƒ | _tƒ | _t d| j| j¡| _t d| j| j¡| _| jj	 
| j| jj	 ¡ j¡ d S ry   )r8   r`   rB   rr   r   ÚlistenMulticastrT   rd   rq   r:   r   rà   rU   rh   r&   r(   r(   r)   rÂ   €  s    þzMulticastTests.setUpc                 C  s   t t| jjƒt| jjƒgƒS r$   )r   r   rd   rX   rq   r&   r(   r(   r)   rÃ   ‹  s
    

þÿzMulticastTests.tearDownÚNone)rÔ   c                   sB   ˆ j jjtkrtdƒ‚dddœ‡ fdd„}|ˆ jƒ |ˆ j ƒ d S )Nz+only IPv4 multicast has TTLs, IPv6 has hopszServer | Clientrè   )ÚorÔ   c                   sD   t  | j¡st‚ˆ  | j ¡ d¡ | j d¡ ˆ  | j ¡ d¡ d S )Nr,   r�   )r   Z
providedByr:   ÚAssertionErrorrV   ZgetTTLZsetTTL)ré   r&   r(   r)   Úcheckttl—  s    z(MulticastTests.testTTL.<locals>.checkttl)r`   r:   ZaddressFamilyr   r!   rr   )r'   rë   r(   r&   r)   ÚtestTTL“  s
    
zMulticastTests.testTTLc                 Ã  sà   | j }|  | jj ¡ d¡ | jj ¡ }| jj |¡I dH  tƒ | j_| jj 	d||j
f¡ | jjI dH  |  t| jjƒd¡ | jj d¡ |  | jj ¡ d¡ | jj 	d||j
f¡ tttƒdƒI dH  |  t| jjƒd¡ dS )zv
        Test that after loopback mode has been set, multicast packets are
        delivered to their sender.
        r,   Nru   r   )rá   rV   r`   r:   ZgetLoopbackModerU   Ú	joinGroupr   r9   rz   rh   rŸ   r%   ZsetLoopbackModer   r   r   )r'   rÒ   r>   r(   r(   r)   Útest_loopback   s    
zMulticastTests.test_loopbackc              	   Ã  s6   |   t¡�" | jjj| j| jd�I dH  W 5 Q R X dS )z”
        A sensible error will be reported when using the wrong address family
        literal for the 'interface' argument to 'joinGroup'.
        rS   N)rl   r   r`   r:   rí   rá   ræ   r&   r(   r(   r)   Útest_wrongFamilyInterfaceJoin¸  s
     ÿz,MulticastTests.test_wrongFamilyInterfaceJoinc                 Ã  sˆ   |   | jj ¡ | j¡ |   | jj ¡ | j¡ | jj | j¡I dH  | jj | j¡I dH  |   | jj ¡ | j¡ |   | jj ¡ | j¡ dS )zK
        Test C{getOutgoingInterface} and C{setOutgoingInterface}.
        N)	rV   rr   r:   ZgetOutgoingInterfacerß   r`   ZsetOutgoingInterfacerâ   rã   r&   r(   r(   r)   Útest_interfaceÂ  s$    
 ÿ
 ÿ
þ
þzMulticastTests.test_interfacec                 Ã  s\   | j j | j¡I dH  | j j | j¡I dH  | jj | j¡I dH  | jj | j¡I dH  dS )zE
        Test that multicast a group can be joined and left.
        N)rr   r:   rí   rá   Z
leaveGroupr`   r&   r(   r(   r)   Útest_joinLeaveÙ  s    zMulticastTests.test_joinLeavez2Windows' UDP multicast is not yet fully supported.c                 C  s   |   | jj | j¡tj¡S )zŠ
        Test that an attempt to join an address which is not a multicast
        address fails with L{error.MulticastJoinError}.
        )r�   rr   r:   rí   rä   r   r   r&   r(   r(   r)   Útest_joinFailureã  s    
 ÿzMulticastTests.test_joinFailurec                   s|   t ƒ ‰t dˆˆj¡‰ˆjj ¡ ‰ ˆjj ˆj¡}‡ ‡‡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   c                   s(   t ƒ  }ˆj_ˆj dˆjˆ jf¡ |S )Nó   hello world)r   r`   r9   r:   rz   rá   rh   )rY   r1   )r>   Úcr'   r(   r)   ÚcbJoinedü  s    z/MulticastTests.test_multicast.<locals>.cbJoinedc                   s   ˆ   ˆ jjd d d¡ d S )Nr   ró   )rV   r`   r%   rb   r&   r(   r)   ÚcbPacket  s    z/MulticastTests.test_multicast.<locals>.cbPacketc                   s    t ˆjƒ}| ‡ fdd„¡ |S )Nc                   s   ˆ S r$   r(   r¢   ©Úpassthroughr(   r)   r¥   
  r¦   z@MulticastTests.test_multicast.<locals>.cleanup.<locals>.<lambda>)r   rX   r_   )rø   r¤   )r[   r÷   r)   r˜     s    
z.MulticastTests.test_multicast.<locals>.cleanup)
r8   r   rç   rT   r`   r:   rU   rí   rá   r_   )r'   Zjoinedrõ   rö   r˜   r(   )r>   rô   r[   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tƒ}|jd|d| jd�}| ¡ }t|ttfƒs<t	‚|j
}t ƒ }|j||d| jd�}t| jj | j¡| | j¡| | j¡gƒI dH  tƒ  }|_tƒ  }	|_|j d| j|f¡ t||	gƒI dH  |  |jd d d¡ |  |jd d d¡ tt|jƒt|jƒgƒI dH  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)ZlistenMultiplerT   Nró   )r8   r   r   rç   rT   rU   Ú
isinstancer   r   rê   rh   r   r`   r:   rí   rá   r   r9   rz   rV   r%   r   rX   )
r'   ZfirstClientZmreactorZ	firstPortZfpAddrZportnoZsecondClientZ
secondPortÚd1Zd2r(   r(   r)   Útest_multiListen  sF       ÿü

ýÿ
	þÿzMulticastTests.test_multiListenN)r5   r6   r7   rL   rT   r@   rß   rà   rá   râ   rã   rä   ræ   rÂ   rÃ   rì   rî   rï   rð   rñ   r   r   ÚplatformZ	isWindowsZisVistarò   rù   rü   r(   r(   r(   r)   rÝ   e  s6   


þ

 þrÝ   úff03::1ú::z/The local stack does not enable IPv6 multicast.c                   @  s‚   e Zd ZU dZdZded< dZded< dZded< ed	d
„ e	ƒ D ƒƒZ
ded< e
Zded< dZded< dZded< dZded< dS )ÚMulticastTestsIPv6zC
    Tests for sending and receiving IPv6 multicast datagrams.
    rÿ   rÍ   rT   rå   rà   rþ   rá   c                 c  s$   | ]}|d    d¡r|d V  qdS )r,   Úlor   N)Ú
startswith)Ú.0Zidxnmr(   r(   r)   Ú	<genexpr>^  s      zMulticastTestsIPv6.<genexpr>rÞ   râ   rã   rä   r   rß   rR   ræ   N)r5   r6   r7   rL   rT   r@   rà   rá   Únextr   râ   rã   rä   rß   ræ   r(   r(   r(   r)   r   H  s   
ÿr   )=rL   Ú
__future__r   r¾   r   r   r   r   r   r   r   r	   r
   r   r   Zunittestr   Ztwisted.internetr   r   r   r   r   r   Ztwisted.internet.addressr   r   Ztwisted.internet.deferr   r   r   Ztwisted.internet.errorr   Ztwisted.internet.interfacesr   r   r   Ztwisted.internet.taskr   Ztwisted.pythonr   Ztwisted.test.testutilsr    Ztwisted.trial.unittestr!   r"   r#   ZDatagramProtocolr8   ZConnectedDatagramProtocolrB   rJ   r´   rK   rM   rÊ   rQ   rÁ   rÚ   rÝ   r   r(   r(   r(   r)   Ú<module>   sv   4    6þ    ÿü Zþ    ÿü