
    \d1k                     R   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j        e	d           d           G d de                      Z e ej        e	d           d           G d de                      Z e ej        e	d           d           G 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                   ,    e Zd ZdZdZdZd Zd Zd ZdS )Mixinr   Nc                     g | _         d S N)packetsselfs    5lib/python3.11/site-packages/twisted/test/test_udp.py__init__zMixin.__init__   s        c                 n    d| _         | j        &| j        d c}| _        |                    d            d S d S N   )startedstartedDeferredcallbackr   ds     r   startProtocolzMixin.startProtocol   sD    +&*&:D#At#JJt ,+r   c                     d| _         d S r   )stoppedr   s    r   stopProtocolzMixin.stopProtocol#   s    r   )	__name__
__module____qualname__r   r#   r   r   r!   r$    r   r   r   r      sP        GGO        r   r   c                       e Zd ZdZdZd ZdS )ServerNr   c                     | j                             ||f           | j        &| j        d c}| _        |                    d            d S d S r   r   appendpacketReceivedr   )r   dataaddrr    s       r   datagramReceivedzServer.datagramReceived+   sW    T4L)))*%)%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dS )ClientNr   c                     | j                             |           | j        &| j        d c}| _        |                    d            d S d S r   r,   )r   r/   r    s      r   r1   zClient.datagramReceived7   sS    D!!!*%)%8$"At"JJt +*r   c                 j    | j         $| j         d c}| _         |                    |           || _        d S r   )r   errbackfailure)r   r8   r    s      r   connectionFailedzClient.connectionFailed=   s:    +&*&:D#At#IIgr   c                     | j         6| j         d c}| _         |                    t          j        d                     d| _        d S Nyupr   r   r7   r   ConnectionRefusedErrorr2   r   s     r   connectionRefusedzClient.connectionRefusedC   E    +&*&:D#At#IIe2599:::r   )r%   r&   r'   r.   r2   r1   r9   r?   r(   r   r   r4   r4   2   sK        NG        r   r4   c                       e Zd Zd ZdS )
GoodClientc                     | j         6| j         d c}| _         |                    t          j        d                     d| _        d S r;   r=   r   s     r   r?   zGoodClient.connectionRefusedK   r@   r   N)r%   r&   r'   r?   r(   r   r   rB   rB   J   s#            r   rB   c                       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   rE   rE   R   s           r   rE   c                   "    e Zd ZdZdZd Z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                     || _         dS )ze
        Set the Deferred which will be called back when datagramReceived is
        called.
        N)r    r   s     r   setDeferredzBadClient.setDeferreda   s    
 r   c                 v    | j         $| j         d c}| _         |                    |           t          d          )NzApplication code is very buggy!)r    r   rE   )r   bytesr0   r    s       r   r1   zBadClient.datagramReceivedh   s:    6IAtvJJu>???r   )r%   r&   r'   rF   r    rJ   r1   r(   r   r   rH   rH   Y   sH         
 	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
                            d          dk    d          d	             Zd
 Zd Zd Zd ZdS )UDPTestsc                      t                      }t          j                    x}|_        t	          j        d|d           f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                                                      }                    |j        d                                           S )NUDP)getHostassertEqualtypestopListening)ignoredr0   pr   s     r   	cbStartedz+UDPTests.test_oldAddress.<locals>.cbStartedz   s8    99;;DTY...??$$$r   r*   r   r
   r   r   	listenUDPaddCallback)r   serverr    r\   r[   s   `   @r   test_oldAddresszUDPTests.test_oldAddressq   sm    
 %*^%5%55F"a;???	% 	% 	% 	% 	% 	%
 }}Y'''r   c                      t                      t          j                    x}_        t	          j        dd           fd} fd}|                    |                              |          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        d                                j        d                                           S )Nr   r   )rW   r   r#   rY   )rZ   port1r   r`   s    r   r\   z*UDPTests.test_startStop.<locals>.cbStarted   sE    V^Q///V^Q///&&(((r   c                 >                         j        d           d S 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   s     %*^%5%55F"!!V{CCC	) 	) 	) 	) 	) 	) 	)
	0 	0 	0 	0 	0 	0 }}Y''33I>>>r   c                     t                      t          j                    x}_        t	          j        dd          }d fd}|                    |          S )zr
        Re-listening with the same L{DatagramProtocol} re-invokes the
        C{startProtocol} callback.
        r   rQ   rR   c                 *    |                                 S r   rY   rZ   ports     r   r\   z'UDPTests.test_rebind.<locals>.cbStarted   s    %%'''r   c                     t          j                    x}_        t          j        dd          }|                    |          S Nr   rQ   rR   )r   r
   r   r   r^   r_   )rZ   r    r[   r\   r`   s      r   rf   z'UDPTests.test_rebind.<locals>.cbStopped   sC    ).)9)99A&!!V{CCCA==A...r   r]   )r   r    r[   rf   r\   r`   s       @@r   test_rebindzUDPTests.test_rebind   s~    
 %*^%5%55F"a;???	( 	( 	(	/ 	/ 	/ 	/ 	/ 	/
 }}Y***r   c                      t                      t          j                    x}_        t	          j        dd           fd}|                    |           fd}|                    |           |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                                                   t                      }                    t
          j        t          j                                        j	        |d           d S )NrQ   rR   )
rW   rV   	transportr*   assertRaisesr   CannotListenErrorr   r^   rl   )rZ   server2rl   r   r`   s     r   r\   z*UDPTests.test_bindError.<locals>.cbStarted   s    T\\^^V-=-E-E-G-GHHHhhG'!#%      r   c                 ,                                     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5F" FkBBB		 		 		 		 		 		 		 	
i   	( 	( 	( 	( 	( 	
j!!!r   c                    	
 t                      
t          j                    x}
_        t	          j        d
d          	t                      t          j                    x_         fd}|                    |          }
fd}|                    |            
fd}|                    |           	 fd}|                    |           |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                 @    t          j        dd          _        S rn   )r   r^   port2)rZ   clientclientStartedr   s    r   cbServerStartedz2UDPTests.test_sendPackets.<locals>.cbServerStarted   s"     *1fLLLDJ  r   c                    j                             dj                                         j                   j                                         }j                                         }t	          j                    x}_        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                     rSt          j                    x}_        |                                j        j                            d            |S d S Nr   )r   r
   r.   r_   rr   writepop)rZ   nextClientWritecbClientSendr|   clientWritesr`   s     r   r   zHUDPTests.test_sendPackets.<locals>.cbClientStarted.<locals>.cbClientSend   se     +>Cn>N>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   $$[&2B2J2J2L2L2QRRR$,,..E$,,..E161A1AAJ.""8ej%*-EFFF#\D5:uz:R3STL+ + + + + + + + %d##Z04   r   c                 $   j                                         }j                                         }                    j        d|j        |j        ffg           |j        |j        f}                    j        d|fd|fd|fg           d S )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%*ej9Q.R-STTT*ej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   sK    %'(;<<'
(@A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   s4   
 161A1AA.!!V{CCC161A1AA.	! 	! 	! 	! 	! 	! 	! %%o6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}|                    |           f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   rQ   rR   Tr   c                 L   t          j                    x}_        j                            dd           t          d          D ]?}j                            d|fz             j                            d|fz  d           @                    |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>9I9II 6$$["5552YY H H &&ut|444 &&ut|5FGGGG%%&79UV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)  sI    %'(:;;'(;<< "&   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1A1AA. FkBBB161A1AA.!!V{CCC}=PTUUU	W 	W 	W 	W 	W 	W 	W 	
i   	 	 	 	 	 	 	
j!!!r   c                 N   	
 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}|	                    |           t          j        ||gd          } fd}|	                    |           
f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   rQ   rR   s   Sending test packet to serverTr   c                     j                             dd           j                             dj        f           d S )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>.cbClientAndServerStartedL  sZ     ""79J   ""!K1K#L    r   c                 V                         j        d         d                    d S 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EEEEEr   c                     t          j        t          j        j                  t          j        j                  gd          S r   r   )rZ   
clientPortr   s    r   cleanupz0UDPTests.test_serverReadFailure.<locals>.cleanupd  sI    %'
(@AA'
(@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_serverReadFailure5  s    161A1AA.&q&KHHH
<161A1AA.050@0@@-&q&KHHH
"'"4M*T#
 #
 #
	 	 	 	 	 	 	 	 	 ++,DEEE*$m4t
 
 
	F 	F 	F 	F 	F 	F 	F 	!!"8999	 	 	 	 	 	 	!!'***r   c                 P   t                      }t          j        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   rQ   rR   	localhostr   )
rB   r   r^   rs   r   InvalidAddressErrorrr   r   RuntimeErrorrY   )r   r|   rl   s      r   test_badConnectzUDPTests.test_badConnectq  s      FkBBB%v'7'?b	
 	
 	
 	  b111,(8(@+rRRR!!###r   c                 |   	 t          j                     fd}                    |           t                      t	          j        dd          fd}                    |                                           t          t          d                    g 	 	fd              S )zr
        When datagramReceived raises an exception it is logged but the port
        is not disconnected.
        c                                          t                    }                    t          |          ddt          |          fz             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)flushLoggedErrorsrE   rW   len)ignerrsr   s     r   cbCompletedz8UDPTests.test_datagramReceivedError.<locals>.cbCompleted  sU    
 )).99DD		1G3t99,V    r   r   rQ   rR   c                 d     t          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  s2    
 &t'9::BBCUCUCUCUVVVr   <   c                  `   s;	 
                     d           n$# t          $ r                                  Y nw xY w
                    j        dd           d                    d          fz  } t          j                    }                    |           j        	                    | j
        j        f           	fd}	fd}|                    ||           |                    j                   t          j        d|j        t!          j        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                                                                           |            t                    dk    rt          j        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timeoutCalls    r   cbPacketReceivedzRUDPTests.test_datagramReceivedError.<locals>.makeAttempt.<locals>.cbPacketReceived  sn    
 ""$$$!((000())Q..
 %a)?FFFFFKMMMMMr   c                                   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(   )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   hll1oo//F"^--N~...""6DIty+ABBB" " " " " " " " 	 	 	 	 	 ''(8/JJJ%%m&;<<<!+&"#KLL KKKs    ==)
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BB	W 	W 	W 	W 	W 	i(((||~~ b		??8	 8	 8	 8	 8	 8	 8	 8	 8	 8	 8	t 	r   c                 (    G d d          }t          j        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                       e Zd Zd ZdS )6UDPTests.test_NoWarningOnBroadcast.<locals>.fakeSocketc                     d S 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  s    	 	 	 	 	 	 	 	 HQ!!:<<	.///%%t'E&FG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   o   s        ( ( ( ? ? ?(+ + +&  8B B BH V

'((,<<, ' '	 'R: : :x$ $ $$g g gR+ + + + +r   rO   c                   J    e Zd ZdZ ej        ed          sdZd Zd Z	d Z
dS )ReactorShutdownInteractionTestsz!Test reactor shutdown interactionNrM   c                 n    t                      | _        t          j        d| j        d          | _        dS )zStart a UDP portr   rQ   rR   N)r*   r`   r   r^   rl   r   s    r   setUpz%ReactorShutdownInteractionTests.setUp  s,    hh%aLLL			r   c                 4    | j                                         S )zStop the UDP port)rl   rY   r   s    r   tearDownz(ReactorShutdownInteractionTests.tearDown  s    y&&(((r   c                 ^    t          j                    t          j                    x} j        _         fd}|                    |            fd}                    |            j        j                            dd j        j                                        j        f           S )z0Test reactor shutdown while in a recvfrom() loopc                 z    j         j                                         t          j        dj        d            d S r   )r`   rr   connectionLostr   r   r   )rZ   finishedr   s    r   pktRecezQReactorShutdownInteractionTests.testShutdownFromDatagramReceived.<locals>.pktRece   s:    K!00222 a!2D99999r   c                 0                                      d S 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	% 	% 	% 	% 	% 	[)))##dk&;&C&C&E&E&JK	
 	
 	
 r   )r%   r&   r'   rF   r   IReactorUDPr   skipr   r   r  r(   r   r   r   r     sf        ++!:!'400 32M M M
) ) )$ $ $ $ $r   r   'This reactor does not support multicastc                      e Zd Zej                            d          dk    re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                                        oej                                         d          d             Zd Z eej                                        d          d             ZdS )MulticastTestsr   r   z Does not work on Azure PipelinesNr  c                 P   t                      | _        t                      | _        t	          j        d| j                  | _        t	          j        d| j                  | _        | j        j        	                    d| j        j        
                                j                   d S )Nr   rQ   )r*   r`   r4   r|   r   listenMulticastrd   r{   rr   r   rV   rl   r   s    r   r   zMulticastTests.setUpG  sy    hhhh,Q<<
,Q<<
%%k4;3H3P3P3R3R3WXXXXXr   c                     t          t          | j        j                  t          | j        j                  g          S r   )r   r   rd   rY   r{   r   s    r   r   zMulticastTests.tearDownO  s9    dj677dj677
 
 	
r   c                    | j         | j        fD ]v}|                     |j                                        d           |j                            d           |                     |j                                        d           wd S )Nr   r   )r|   r`   rW   rr   getTTLsetTTL)r   os     r   testTTLzMulticastTests.testTTLW  s    dk) 	6 	6AQ[//111555Kq!!!Q[//1115555	6 	6r   c                                            j        j                                        d            j        j                                         j        j                            d          } fd}|                    |            fd}|                    |            fd}|                    |           |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                            ddj        f           |S )Nr   r  r
   r`   r.   rr   r   rl   rZ   r    r0   r   s     r   cbJoinedz.MulticastTests.test_loopback.<locals>.cbJoinedf  s=    -5ZZ7A*K!''=$)2LMMMHr   c                                         t          j        j                  d           j        j                            d                                j        j                                        d           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>.cbPacketm  s    S!455q999K!11!444T[2BBDDaHHHK!''=$)2LMMM 

AaT222Hr   c                 b                         t          j        j                  d           d S r   )rW   r   r`   r   r   s    r   
cbNoPacketz0MulticastTests.test_loopback.<locals>.cbNoPacketz  s,    S!455q99999r   )rW   r`   rr   r  rV   	joinGroupr_   )r   joinedr  r  r  r0   s   `    @r   test_loopbackzMulticastTests.test_loopback]  s    
 	.>>@@!DDD{$,,..&00??	 	 	 	 	 	
 	8$$$		 		 		 		 		 		 	8$$$	: 	: 	: 	: 	: 	:&&&r   c                                            j        j                                        d                                  j        j                                        d            j        j                            d          } j        j                            d          }t          ||g          } fd}|                    |           |S )zK
        Test C{getOutgoingInterface} and C{setOutgoingInterface}.
        z0.0.0.0rQ   c                                          j        j                                        d                                j        j                                        d           d S )NrQ   )rW   r|   rr   getOutgoingInterfacer`   r   s    r   cbInterfacesz3MulticastTests.test_interface.<locals>.cbInterfaces  sW    T[2GGII;WWWT[2GGII;WWWWWr   )rW   r|   rr   r"  r`   setOutgoingInterfacer   r_   )r   d1d2r   r#  s   `    r   test_interfacezMulticastTests.test_interface  s     	.CCEEyQQQ.CCEEyQQQ["77DD["77DDBx((	X 	X 	X 	X 	X 	<(((r   c                       j         j                            d          } fd}|                    |            fd}|                    |            fd}|                    |           |S )zE
        Test that multicast a group can be joined and left.
        r  c                 B    j         j                            d          S Nr  )r|   rr   
leaveGroupr   s    r   clientJoinedz3MulticastTests.test_joinLeave.<locals>.clientJoined      ;(33MBBBr   c                 B    j         j                            d          S r*  )r`   rr   r  r   s    r   
clientLeftz1MulticastTests.test_joinLeave.<locals>.clientLeft  s    ;(22=AAAr   c                 B    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     K!++M::	C 	C 	C 	C 	C 	
l###	B 	B 	B 	B 	B 	
j!!!	C 	C 	C 	C 	C 	
l###r   z2Windows' UDP multicast is not yet fully supported.c                 |    |                      | 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     !!K!++K88%:R
 
 	
r   c                 n    t                      t          j        d           j        j                                         j        j                            d          } fd}|                    |            fd}|                    |           fd}|                    |           |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                            ddj        f           |S )N   hello worldr  r  )rZ   r    r0   cr   s     r   r  z/MulticastTests.test_multicast.<locals>.cbJoined  s:    -5ZZ7A*Kn}di.HIIIHr   c                 `                         j        j        d         d         d           d S Nr   r8  )rW   r`   r   r   s    r   r  z/MulticastTests.test_multicast.<locals>.cbPacket  s.    T[03A6GGGGGr   c                 b     t          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  s6    "1?33F666677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    
 HH#Aq)){$,,..&00??	 	 	 	 	 	 	
 	8$$$	H 	H 	H 	H 	H 	8$$$	 	 	 	 	
 	7###r   zjon non-linux platforms it appears multiple processes can listen, but not multiple sockets in same process?c                 0   	
 t                      t          j        dd                                          j        t                      t          j        d          	d
t           j        j                            
                              
          	                    
          g          }
fd}|	                    |            fd}|	                    |           	f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                     t                      x}_        t                      x}_        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  sU    .6jj8B+/7zz9B,!''68JKKK "b***r   c                                          j        d         d         d                                j        d         d         d           d S r;  r   )rZ   rE  rG  r   s    r   
gotPacketsz3MulticastTests.test_multiListen.<locals>.gotPackets  sO    [03A6GGG\1!4Q7HHHHHr   c                      t          t          j                  t          j                  g          }|                     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  sY    "!)"9::!*":;; F 666677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  sf    hh+A{4PPP	""$$)xx,V\RVWWW
 %//99##H--$$X..
 
	+ 	+ 	+ 	+ 	+ 	+ 	+ 	+ 	<(((	I 	I 	I 	I 	I 	I 	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  8  sp        	
'((,<<<%%'' 	= 2':'66 98Y Y Y
 
 
6 6 6" " "H  $  0 V""$$GW-=-E-E-G-G)G< 
 
	 
  @ V""$$	 / / / / /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\     s  
 
 
			       M M M M M M M M M M M M M M M M I I I I I I I I I I " " " " " " + + + + + +       (    UH-       UH6   0           Y   @ @ @ @ @) @ @ @, "J"7D1113VWWN+ N+ N+ N+ N+x N+ N+ XWN+b "J"7D1113VWW3 3 3 3 3h 3 3 XW3l $
$Wd333- R R R R RX R R	 R R Rr   