
    Ϫf.k                         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	      Z G d
 deej(                        Z G d deej,                        Z G d de      Z G d de      Z G d dej(                        Z e ej8                  e	d       d       G d de             Z e ej8                  e	d       d       G d de             Z e ej>                  e	d       d       G d de             Z y)zG
Tests for implementations of L{IReactorUDP} and L{IReactorMulticast}.
    N)skipIf)defererror
interfacesprotocolreactorudp)DeferredgatherResultsmaybeDeferred)runtime)TestCasec                   *    e Zd ZdZdZdZd Zd Zd Zy)Mixinr   Nc                     g | _         y N)packetsselfs    7/usr/lib/python3/dist-packages/twisted/test/test_udp.py__init__zMixin.__init__   s	        c                 v    d| _         | j                  &| j                  d c}| _        |j                  d        y y N   )startedstartedDeferredcallbackr   ds     r   startProtocolzMixin.startProtocol   s;    +&*&:&:D#At#JJt ,r   c                     d| _         y r   )stoppedr   s    r   stopProtocolzMixin.stopProtocol"   s	    r   )	__name__
__module____qualname__r   r#   r   r   r!   r$    r   r   r   r      s     GGOr   r   c                       e Zd ZdZdZd Zy)ServerNr   c                     | j                   j                  ||f       | j                  &| j                  d c}| _        |j                  d        y y r   r   appendpacketReceivedr   )r   dataaddrr    s       r   datagramReceivedzServer.datagramReceived*   sJ    T4L)*%)%8%8$"At"JJt +r   )r%   r&   r'   r.   refusedr1   r(   r   r   r*   r*   &   s    NGr   r*   c                   &    e Zd ZdZdZd Zd Zd Zy)ClientNr   c                     | j                   j                  |       | j                  &| j                  d c}| _        |j                  d        y y r   r,   )r   r/   r    s      r   r1   zClient.datagramReceived5   sF    D!*%)%8%8$"At"JJt +r   c                 t    | j                   %| j                   d c}| _         |j                  |       || _        y r   )r   errbackfailure)r   r8   r    s      r   connectionFailedzClient.connectionFailed;   s6    +&*&:&:D#At#IIgr   c                     | j                   8| j                   d c}| _         |j                  t        j                  d             d| _        y Nyupr   r   r7   r   ConnectionRefusedErrorr2   r   s     r   connectionRefusedzClient.connectionRefusedA   A    +&*&:&:D#At#IIe2259:r   )r%   r&   r'   r.   r2   r1   r9   r?   r(   r   r   r4   r4   1   s    NGr   r4   c                       e Zd Zd Zy)
GoodClientc                     | j                   8| j                   d c}| _         |j                  t        j                  d             d| _        y r;   r=   r   s     r   r?   zGoodClient.connectionRefusedI   r@   r   N)r%   r&   r'   r?   r(   r   r   rB   rB   H   s    r   rB   c                       e Zd ZdZy)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   rE   rE   P   s    r   rE   c                        e Zd ZdZdZd Zd Zy)	BadClientz
    A DatagramProtocol which always raises an exception from datagramReceived.
    Used to test error handling behavior in the reactor for that method.
    Nc                     || _         y)ze
        Set the Deferred which will be called back when datagramReceived is
        called.
        N)r    r   s     r   setDeferredzBadClient.setDeferred_   s    
 r   c                 z    | j                   %| j                   d c}| _         |j                  |       t        d      )NzApplication code is very buggy!)r    r   rE   )r   bytesr0   r    s       r   r1   zBadClient.datagramReceivedf   s5    66IAtvJJu>??r   )r%   r&   r'   rF   r    rJ   r1   r(   r   r   rH   rH   W   s    
 	A@r   rH   !This reactor does not support UDPc                       e Zd Zd Zd Zd Zd Zd Z ee	j                  j                  d      dk(  d      d	        Zd
 Zd Zd Zd Zy)UDPTestsc                      t               }t        j                         x}|_        t	        j
                  d|d       fd}|j                  |      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                 |    j                         }j                  |j                  d       j                         S )NUDP)getHostassertEqualtypestopListening)ignoredr0   pr   s     r   	cbStartedz+UDPTests.test_oldAddress.<locals>.cbStartedx   s/    99;DTYY.??$$r   r*   r   r
   r   r   	listenUDPaddCallback)r   serverr    r\   r[   s   `   @r   test_oldAddresszUDPTests.test_oldAddresso   sJ    
 %*^^%55F"a;?	%
 }}Y''r   c                      t               t        j                         x}_        t	        j
                  dd       fd} fd}|j                  |      j                  |      S )z
        The L{DatagramProtocol}'s C{startProtocol} and C{stopProtocol}
        methods are called when its transports starts and stops listening,
        respectively.
        r   rQ   rR   c                     j                  j                  d       j                  j                  d       j                         S )Nr   r   )rW   r   r#   rY   )rZ   port1r   r`   s    r   r\   z*UDPTests.test_startStop.<locals>.cbStarted   s:    V^^Q/V^^Q/&&((r   c                 >    j                  j                  d       y r   )rW   r#   )rZ   r   r`   s    r   	cbStoppedz*UDPTests.test_startStop.<locals>.cbStopped   s    V^^Q/r   r]   )r   r    r\   rf   rd   r`   s   `   @@r   test_startStopzUDPTests.test_startStop   sZ     %*^^%55F"!!!V{C	)
	0 }}Y'33I>>r   c                     t               t        j                         x}_        t	        j
                  dd      }d fd}|j                  |      S )zr
        Re-listening with the same L{DatagramProtocol} re-invokes the
        C{startProtocol} callback.
        r   rQ   rR   c                 "    |j                         S r   rY   rZ   ports     r   r\   z'UDPTests.test_rebind.<locals>.cbStarted   s    %%''r   c                     t        j                         x}_        t        j                  dd      }|j                  |      S Nr   rQ   rR   )r   r
   r   r   r^   r_   )rZ   r    r[   r\   r`   s      r   rf   z'UDPTests.test_rebind.<locals>.cbStopped   s<    ).)99A&!!!V{CA==A..r   r]   )r   r    r[   rf   r\   r`   s       @@r   test_rebindzUDPTests.test_rebind   sQ    
 %*^^%55F"a;?	(	/
 }}Y**r   c                      t               t        j                         x}_        t	        j
                  dd       fd}|j                  |       fd}|j                  |       |S )z
        A L{CannotListenError} exception is raised when attempting to bind a
        second protocol instance to an already bound port
        r   rQ   rR   c                    j                  j                         j                  j                                t               }j	                  t
        j                  t        j                  j                         j                  |d       y )NrQ   rR   )
rW   rV   	transportr*   assertRaisesr   CannotListenErrorr   r^   rl   )rZ   server2rl   r   r`   s     r   r\   z*UDPTests.test_bindError.<locals>.cbStarted   si    T\\^V-=-=-E-E-GHhG''!!##%  r   c                 $    j                         S r   rj   rk   s    r   
cbFinishedz+UDPTests.test_bindError.<locals>.cbFinished   s    %%''r   r]   )r   r    r\   rw   rl   r`   s   `   @@r   test_bindErrorzUDPTests.test_bindError   s_    
 %*^^%55F"  FkB		 	
i 	( 	
j!r   c                    	
 t               
t        j                         x}
_        t	        j
                  d
d      	t               t        j                         x_         fd}|j                  |      }
fd}|j                  |        
fd}|j                  |       	 fd}|j                  |       |S )z
        Datagrams can be sent with the transport's C{write} method and
        received via the C{datagramReceived} callback method.
        r   rQ   rR   c                 B    t        j                  dd      _        S rn   )r   r^   port2)rZ   clientclientStartedr   s    r   cbServerStartedz2UDPTests.test_sendPackets.<locals>.cbServerStarted   s     **1fLDJ  r   c                    j                   j                  dj                   j                         j                         j                   j                         }j                   j                         }t	        j
                         x}_        j                   j                  d|j                  |j                  f       ddd|j                  |j                  ffgfdt	        j                   d       |gd      S )	NrQ      hello)   a)   bN   cc                     rVt        j                         x}_        |j                          j                  j
                  j                  d        |S y Nr   )r   r
   r.   r_   rr   writepop)rZ   nextClientWritecbClientSendr|   clientWritesr`   s     r   r   zHUDPTests.test_sendPackets.<locals>.cbClientStarted.<locals>.cbClientSend   sT    >Cnn>NNOf&;#//=*F$$**L,<,<Q,?@**	  r   TfireOnOneErrback)
rr   connectrV   rl   r   r
   r.   r   hostDeferredList)rZ   cAddrsAddr
serverSendr   r   r|   r`   s       @@r   cbClientStartedz2UDPTests.test_sendPackets.<locals>.cbClientStarted   s    $$[&2B2B2J2J2L2Q2QR$$,,.E$$,,.E161AAJ.""8ejj%**-EF#\D5::uzz:R3STL+ %%d#Z04 r   c                 R   j                   j                         }j                   j                         }j                  j                  d|j                  |j
                  ffg       |j                  |j
                  f}j                  j                  d|fd|fd|fg       y )Nr   r   r   r   )rr   rV   rW   r   r   rl   )rZ   r   r   
clientAddrr|   r   r`   s       r   cbSendsFinishedz2UDPTests.test_sendPackets.<locals>.cbSendsFinished   s    $$,,.E$$,,.EV^^x%**ejj9Q.R-ST**ejj1J
#dJ%7$
9KLr   c                     t        j                  t        j                  j                        t        j                  j                  j                        gd      S NTr   )r   r   r   rY   r{   )rZ   rd   r   s    r   rw   z-UDPTests.test_sendPackets.<locals>.cbFinished   sL    %%''(;(;<''

(@(@A "& r   )r*   r   r
   r   r   r^   rB   r_   )r   serverStartedr~   r    r   r   rw   r|   r}   rd   r`   s   `      @@@@r   test_sendPacketszUDPTests.test_sendPackets   s    
 161AA.!!!V{C161AA.	! %%o6	0 	
o&	 	
o&	 	
j!r   INFRASTRUCTUREAZUREPIPELINESz"Hangs on Pipelines due to firewallc                    	 t               t        j                         x}_        t	        j
                  dd      t               	t        j                         x}	_        t	        j
                  d	d      t        j                  ||gd      } 	fd}|j                  |       fd}|j                  |       |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   rQ   rR   Tr   c                 P   t        j                         x}_        j                  j	                  dd       t        d      D ]A  }j                  j                  d|fz         j                  j                  d|fz  d       C j                  |t        j                        S )NrQ   P   
      %drQ   r   )
r   r
   r   rr   r   ranger   assertFailurer   r>   )rZ   r?   ir|   r   r`   s      r   r\   z2UDPTests.test_connectionRefused.<locals>.cbStarted  s    9>9II 6$$["52Y H  &&ut|4  &&ut|5FGH %%&79U9UVVr   c                     t        j                  t        j                  j                        t        j                  j                        gd      S r   r   r   r   rY   )rZ   rl   r{   s    r   rw   z3UDPTests.test_connectionRefused.<locals>.cbFinished'  sH    %%''(:(:;''(;(;< "& r   )	rB   r   r
   r   r   r^   r*   r   r_   )
r   r}   r   r    r\   rw   r|   rl   r{   r`   s
   `     @@@@r   test_connectionRefusedzUDPTests.test_connectionRefused  s     161AA.  FkB161AA.!!!V{C}=PTU	W 	
i 	 	
j!r   c                 4   	
 t               	t        j                         x}	_        t	        j
                  d	d      
dt               t        j                         x}_        t        j                         x}_        t	        j
                  dd      t        j                  ||gd      }	fd}|j                  |       t        j                  ||gd      } fd}|j                  |       
fd	}|j                  |       |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   rQ   rR   s   Sending test packet to serverTr   c                     j                   j                  dd       j                   j                  dj                  f       y )Ns$   write to port no one is listening tor   rQ   )rr   r   _realPortNumber)rZ   r|   r`   
serverPorttest_data_to_sends    r   cbClientAndServerStartedzAUDPTests.test_serverReadFailure.<locals>.cbClientAndServerStartedJ  sE     ""79J ""!K1K1K#Lr   c                 J    j                  j                  d   d          y r   rW   r   )rZ   r   r`   r   s    r   verify_server_got_dataz?UDPTests.test_serverReadFailure.<locals>.verify_server_got_data]  s"    V^^A.q13DEr   c                     t        j                  t        j                  j                        t        j                  j                        gd      S r   r   )rZ   
clientPortr   s    r   cleanupz0UDPTests.test_serverReadFailure.<locals>.cleanupb  sH    %%''
(@(@A''
(@(@A "& r   )
rB   r   r
   r   r   r^   r*   r.   r   r_   )r   r}   r   serverGotDataserver_client_started_dr   all_data_sentr   r   r|   r   r`   r   r   s   `        @@@@@r   test_serverReadFailurezUDPTests.test_serverReadFailure3  s     161AA.&&q&KH
<161AA.050@@-&&q&KH
"'"4"4M*T#
	 	 ++,DE**$m4t
	F 	!!"89	 	!!'*r   c                 b   t               }t        j                  d|d      }| j                  t        j
                  |j                  j                  dd       |j                  j                  dd       | j                  t        |j                  j                  dd       |j                         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   rQ   rR   	localhostr   )
rB   r   r^   rs   r   InvalidAddressErrorrr   r   RuntimeErrorrY   )r   r|   rl   s      r   test_badConnectzUDPTests.test_badConnecto  s       FkB%%v'7'7'?'?b	
 	  b1,(8(8(@(@+rR!!##r   c                 J   	 t        j                          fd}j                  |       t               t	        j
                  dd      fd}j                  |       j                         t        t        d            g 	 	fd         S )zr
        When datagramReceived raises an exception it is logged but the port
        is not disconnected.
        c                     j                  t              }j                  t        |      ddt        |      fz         y)z
            Flush the exceptions which the reactor should have logged and make
            sure they're actually there.
               z'Incorrectly found %d errors, expected 2N)flushLoggedErrorsrE   rW   len)ignerrsr   s     r   cbCompletedz8UDPTests.test_datagramReceivedError.<locals>.cbCompleted  s:    
 )).9DD	1G3t9,Vr   r   rQ   rR   c                 h     t        j                  j                        j                   f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   results    r   <lambda>zHUDPTests.test_datagramReceivedError.<locals>.cbCleanup.<locals>.<lambda>  s    v r   )r   r   rY   addBoth)r   rl   s   `r   	cbCleanupz6UDPTests.test_datagramReceivedError.<locals>.cbCleanup  s(    
 &&t'9'9:BBCUVVr   <   c                  ^   s	 
j                  d       
j                  j                  dd       dj                  d      fz  } t        j                         }j                  |       j                  j                  | j                  j                  f       	fd}	fd}|j                  ||       |j                  j                         t        j                  d|j                  t!        j"                  d	            y# t        $ r j                          Y w xY w)
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                     j                          j                  |        t              dk(  r"t        j                  dj
                  d       y         y)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timeoutCalls    r   cbPacketReceivedzRUDPTests.test_datagramReceivedError.<locals>.makeAttempt.<locals>.cbPacketReceived  sL    
 ""$!((0()Q.
 %%a)?)?FMr   c                              y)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(   )errr   s    r   ebPacketTimeoutzQUDPTests.test_datagramReceivedError.<locals>.makeAttempt.<locals>.ebPacketTimeout  s
     r   g?z&Timed out in testDatagramReceivedError)fail	Exceptionr7   failIfIdenticalrr   r   r   r
   rJ   r   r   rl   addCallbacks
addErrbackr   r   r   TimeoutError)r   packetDeferredr   r   r   r0   attemptsr|   r   r   r   r   s       @r   r   z8UDPTests.test_datagramReceivedError.<locals>.makeAttempt  s    ,II;<     $(I hll1o//F"^^-N~.""6DIItyy+AB" 	 ''(8/J%%m&;&;<!++&&""#KLKU ! ,!))+,s   D D,+D,)
r   r
   r_   rH   r   r^   r   rV   listr   )
r   r   r   r0   r   r|   r   r   rl   r   s
   `  @@@@@@@r   test_datagramReceivedErrorz#UDPTests.test_datagramReceivedError  s    
 (	 	!!+.  FkB	W 	i(||~ b	?8	 8	t 	r   c                      G d d      }t        j                  dt                     } |       |_        |j	                  dd       | j                  | j                  g      }| j                  t        |      d       y)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                       e Zd Zd Zy)6UDPTests.test_NoWarningOnBroadcast.<locals>.fakeSocketc                      y r   r(   )r   foobars      r   sendtoz=UDPTests.test_NoWarningOnBroadcast.<locals>.fakeSocket.sendto  s    r   N)r%   r&   r'   r   r(   r   r   
fakeSocketr     s    r   r   r   s   test)z<broadcast>i  N)	r	   Portr*   socketr   flushWarningstest_NoWarningOnBroadcastrW   r   )r   r   r[   warningss       r   r   z"UDPTests.test_NoWarningOnBroadcast  se    	 	 HHQ!<	./%%t'E'E&FGX*r   N)r%   r&   r'   ra   rg   ro   rx   r   r   osenvirongetr   r   r   r   r   r(   r   r   rO   rO   m   sh    ( ?(+&8BH 


'(,<<,'	'R:x$$gR+r   rO   c                   L    e Zd ZdZ ej
                  ed      sdZd Zd Z	d Z
y)ReactorShutdownInteractionTestsz!Test reactor shutdown interactionNrM   c                 p    t               | _        t        j                  d| j                  d      | _        y)zStart a UDP portr   rQ   rR   N)r*   r`   r   r^   rl   r   s    r   setUpz%ReactorShutdownInteractionTests.setUp  s%    h%%aL	r   c                 6    | j                   j                         S )zStop the UDP port)rl   rY   r   s    r   tearDownz(ReactorShutdownInteractionTests.tearDown  s    yy&&((r   c                 ~    t        j                         t        j                         x} j                  _         fd}|j	                  |        fd}j	                  |        j                  j
                  j                  dd j                  j
                  j                         j                  f       S )z0Test reactor shutdown while in a recvfrom() loopc                     j                   j                  j                          t        j                  dj
                  d        y r   )r`   rr   connectionLostr   r   r   )rZ   finishedr   s    r   pktRecezQReactorShutdownInteractionTests.testShutdownFromDatagramReceived.<locals>.pktRece  s3    KK!!002 a!2!2D9r   c                 &    j                          y r   )r   rZ   r   s    r   flushErrorszUReactorShutdownInteractionTests.testShutdownFromDatagramReceived.<locals>.flushErrors(  s    
 ""$r   s@                                                                   rQ   )	r   r
   r`   r.   r_   rr   r   rV   rl   )r   prr   r  r   s   `   @r    testShutdownFromDatagramReceivedz@ReactorShutdownInteractionTests.testShutdownFromDatagramReceived  s     >>#*/..*::T[['	: 	w	% 	[)##dkk&;&;&C&C&E&J&JK	
 r   )r%   r&   r'   rF   r   IReactorUDPr   skipr   r   r  r(   r   r   r   r     s,    +!:!!'402M
)$r   r   'This reactor does not support multicastc                      e Zd Zej                  j                  d      dk(  rej                  j                         rdZ	 e
j                  ed      sdZ	d Zd Zd Zd	 Zd
 Zd Z eej                  j)                         xr ej                  j+                          d      d        Zd Z eej                  j)                         d      d        Zy)MulticastTestsr   r   z Does not work on Azure PipelinesNr  c                 x   t               | _        t               | _        t	        j
                  d| j                        | _        t	        j
                  d| j                        | _        | j                  j                  j                  d| j                  j                  j                         j                         y )Nr   rQ   )r*   r`   r4   r|   r   listenMulticastrd   r{   rr   r   rV   rl   r   s    r   r   zMulticastTests.setUpD  sw    hh,,Q<
,,Q<
%%k4;;3H3H3P3P3R3W3WXr   c                     t        t        | j                  j                        t        | j                  j                        g      S r   )r   r   rd   rY   r{   r   s    r   r   zMulticastTests.tearDownL  s8    djj667djj667
 	
r   c                    | j                   | j                  fD ]q  }| j                  |j                  j	                         d       |j                  j                  d       | j                  |j                  j	                         d       s y )Nr   r   )r|   r`   rW   rr   getTTLsetTTL)r   os     r   testTTLzMulticastTests.testTTLT  sj    dkk) 	6AQ[[//115KKq!Q[[//115	6r   c                      j                   j                  j                  j                         d        j                  j                  j	                          j                  j                  j                  d      } fd}|j                  |        fd}|j                  |        fd}|j                  |       |S )zv
        Test that after loopback mode has been set, multicast packets are
        delivered to their sender.
        r   225.0.0.250c                     t               x}j                  _        j                  j                  j	                  ddj
                  f       |S )Nr   r  r
   r`   r.   rr   r   rl   rZ   r    r0   r   s     r   cbJoinedz.MulticastTests.test_loopback.<locals>.cbJoinedc  s>    -5Z7A*KK!!''=$))2LMHr   c                    j                  t        j                  j                        d       j                  j                  j                  d       j                  j                  j                  j                         d       j                  j                  j                  ddj                  f       t               }t        j                  d|j                  d        |S )Nr   r   r   r  )rW   r   r`   r   rr   setLoopbackModegetLoopbackModer   rl   r
   r   r   r   r  s     r   cbPacketz.MulticastTests.test_loopback.<locals>.cbPacketj  s    S!4!45q9KK!!11!4T[[22BBDaHKK!!''=$))2LM 
AaT2Hr   c                 d    j                  t        j                  j                        d       y r   )rW   r   r`   r   r   s    r   
cbNoPacketz0MulticastTests.test_loopback.<locals>.cbNoPacketw  s"    S!4!45q9r   )rW   r`   rr   r  rV   	joinGroupr_   )r   joinedr  r  r  r0   s   `    @r   test_loopbackzMulticastTests.test_loopbackZ  s    
 	..>>@!D{{$$,,.&&00?	
 	8$		 	8$	: 	:&r   c                      j                   j                  j                  j                         d        j                   j                  j                  j                         d        j                  j                  j                  d      } j                  j                  j                  d      }t        ||g      } fd}|j                  |       |S )zK
        Test C{getOutgoingInterface} and C{setOutgoingInterface}.
        z0.0.0.0rQ   c                     j                  j                  j                  j                         d       j                  j                  j                  j                         d       y )NrQ   )rW   r|   rr   getOutgoingInterfacer`   r   s    r   cbInterfacesz3MulticastTests.test_interface.<locals>.cbInterfaces  sI    T[[22GGI;WT[[22GGI;Wr   )rW   r|   rr   r"  r`   setOutgoingInterfacer   r_   )r   d1d2r   r#  s   `    r   test_interfacezMulticastTests.test_interface~  s     	..CCEyQ..CCEyQ[[""77D[[""77DBx(	X 	<(r   c                       j                   j                  j                  d      } fd}|j                  |        fd}|j                  |        fd}|j                  |       |S )zE
        Test that multicast a group can be joined and left.
        r  c                 N    j                   j                  j                  d      S Nr  )r|   rr   
leaveGroupr   s    r   clientJoinedz3MulticastTests.test_joinLeave.<locals>.clientJoined      ;;((33MBBr   c                 N    j                   j                  j                  d      S r*  )r`   rr   r  r   s    r   
clientLeftz1MulticastTests.test_joinLeave.<locals>.clientLeft  s    ;;((22=AAr   c                 N    j                   j                  j                  d      S r*  )r`   rr   r+  r   s    r   serverJoinedz3MulticastTests.test_joinLeave.<locals>.serverJoined  r-  r   )r|   rr   r  r_   )r   r    r,  r/  r1  s   `    r   test_joinLeavezMulticastTests.test_joinLeave  s`     KK!!++M:	C 	
l#	B 	
j!	C 	
l#r   z2Windows' UDP multicast is not yet fully supported.c                     | j                  | j                  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}.
        rQ   )r   r|   rr   r  r   MulticastJoinErrorr   s    r   test_joinFailurezMulticastTests.test_joinFailure  s7     !!KK!!++K8%:R:R
 	
r   c                 h    t               t        j                  d       j                  j                  j                          j                  j                  j                  d      } fd}|j                  |        fd}|j                  |       fd}|j                  |       |S )zn
        Test that a multicast group can be joined and messages sent to and
        received from it.
        r   r  c                     t               x}j                  _        j                  j	                  ddj
                  f       |S )N   hello worldr  r  )rZ   r    r0   cr   s     r   r  z/MulticastTests.test_multicast.<locals>.cbJoined  s8    -5Z7A*KKn}dii.HIHr   c                 ^    j                  j                  j                  d   d   d       y Nr   r8  )rW   r`   r   r   s    r   r  z/MulticastTests.test_multicast.<locals>.cbPacket  s'    T[[003A6Gr   c                 \     t        j                        }|j                   fd       |S )Nc                     S r   r(   r   passthroughs    r   r   z@MulticastTests.test_multicast.<locals>.cleanup.<locals>.<lambda>      ; r   )r   rY   r_   )r?  r   r[   s   ` r   r   z.MulticastTests.test_multicast.<locals>.cleanup  s%    "1??3F67Mr   )r*   r   r
  r`   rr   rV   r  r_   )r   r  r  r  r   r0   r9  r[   s   `    @@@r   test_multicastzMulticastTests.test_multicast  s    
 H##Aq){{$$,,.&&00?	
 	8$	H 	8$	
 	7#r   zjon non-linux platforms it appears multiple processes can listen, but not multiple sockets in same process?c                    	
 t               t        j                  dd      j                         j                  t               t        j                  d      	d
t         j                  j                  j                  
      j                  
      	j                  
      g      }
fd}|j                  |        fd}|j                  |       	fd}|j                  |       |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                     t               x}_        t               x}_        j                  j                  df       t	        ||g      S )Nr8  )r
   r.   rr   r   r   )rZ   r%  r&  firstClientportnosecondClienttheGroups      r   r1  z5MulticastTests.test_multiListen.<locals>.serverJoined  sK    .6j8B+/7z9B,!!''68JK "b**r   c                     j                  j                  d   d   d       j                  j                  d   d   d       y r;  r   )rZ   rE  rG  r   s    r   
gotPacketsz3MulticastTests.test_multiListen.<locals>.gotPackets  sC    [003A6G\11!4Q7Hr   c                      t        t        j                        t        j                        g      }|j                   fd       |S )Nc                     S r   r(   r>  s    r   r   zBMulticastTests.test_multiListen.<locals>.cleanup.<locals>.<lambda>  r@  r   )r   r   rY   r_   )r?  r   	firstPort
secondPorts   ` r   r   z0MulticastTests.test_multiListen.<locals>.cleanup   sD    "!)"9"9:!*":":;F 67Mr   )r*   r   r
  rV   rl   r   r`   rr   r  r_   r   )r   r  r1  rJ  r   rE  rM  rF  rG  rN  rH  s   `    @@@@@@r   test_multiListenzMulticastTests.test_multiListen  s     h++A{4P	""$))x,,V\RVW
 %%//9##H-$$X.
	+ 	<(	I 	:&	 	wr   )r%   r&   r'   r   r   r   r   platformisMacOSXr  r   IReactorMulticastr   r   r   r  r  r'  r2  r   	isWindowsisVistar5  rA  rO  r(   r   r   r  r  6  s     	

'(,<<%%'1':''68Y
6"H$0 ""$GW-=-=-E-E-G)G<
	
@ ""$	//r   r  )!rF   r   unittestr   twisted.internetr   r   r   r   r   r	   twisted.internet.deferr
   r   r   twisted.pythonr   twisted.trial.unittestr   r   DatagramProtocolr*   ConnectedDatagramProtocolr4   rB   r   rE   rH   r  rO   r   rR  r  r(   r   r   <module>r\     s0  

 
  M M I I " + &UH-- UH66 . Y @)) @, "J""7D113VWN+x N+ XN+b "J""7D113VW3h 3 X3l $
$$Wd33-QX Q	Qr   