
    ϪfA                        d Z ddlZddlmZ ddlmZ ddlmZmZ ddl	m
Z
mZ ddlmZmZ ddlmZmZmZmZ dd	lmZ dd
lmZmZ ddlmZ ddlmZ ddlmZmZ ddl m!Z!m"Z" ddl#m$Z$ d Z% e%       Z&d Z' G d de      Z( G d d      Z) G d dee)e(      Z* G d dee)e(      Z+ e,       j[                  e*j]                                 e,       j[                  e+j]                                y)zU
Tests for implementations of L{IReactorUDP} and the UDP parts of
L{IReactorSocket}.
    N)implementer)verifyObject)defererror)IPv4AddressIPv6Address)DeferredmaybeDeferred)IListeningPortILoggingContextIReactorSocketIReactorUDP)DatagramProtocol)LogObserverMixinfindFreePort)ReactorBuilder)context)ILogContexterr)
GoodClientServer)SkipTestc                      d} d}	 t        j                   t         j                        } | j                  d       d}| r| j	                          |S # t        $ r Y w xY w)z4Returns True if the system can bind an IPv6 address.NF)::1r   T)socketAF_INET6bindOSErrorclose)sockhas_ipv6s     @/usr/lib/python3/dist-packages/twisted/internet/test/test_udp.py	_has_ipv6r#   !   s[    DH}}V__-		* 

O  s   6A 	AAc                      t         sd| _        | S )Nz.Does not work on systems without IPv6 support.)HAS_IPV6skip)fs    r"   skipWithoutIPv6r(   5   s    AH    c                   "    e Zd ZdZd Zd Zd Zy)DatagramTransportTestsMixinzP
    Mixin defining tests which apply to any port/datagram based transport.
    c                 &   | j                         }| j                         }t        t               G d dt                     } |       }| j                  ||      }d|j                         j                  fz  }| j                  |f|d   d          y)zu
        When a port starts, a message including a description of the associated
        protocol is logged.
        c                       e Zd Zd Zy)QDatagramTransportTestsMixin.test_startedListeningLogMessage.<locals>.SomeProtocolc                      y)NzCrazy Protocol selfs    r"   	logPrefixz[DatagramTransportTestsMixin.test_startedListeningLogMessage.<locals>.SomeProtocol.logPrefixJ   s    'r)   N)__name__
__module____qualname__r3   r0   r)   r"   SomeProtocolr.   H   s    (r)   r7   zCrazy Protocol starting on %dr   messageN)	observebuildReactorr   r   r   getListeningPortgetHostportassertEqual)r2   loggedMessagesreactorr7   protocolpexpectedMessages          r"   test_startedListeningLogMessagez;DatagramTransportTestsMixin.test_startedListeningLogMessage@   s    
 ##%	_	%	(+ 	( 
&	(  >!!'849QYY[=M=M<OO/+^A->y-IJr)   c                 J   | j                         | j                         | j                  t                     dj	                         j
                   d}fdfd}j                  |       | j                         | j                  |fd   d          y)z
        When a connection is lost a message is logged containing an
        address identifying the port and the fact that it was closed.
        z
(UDP Port z Closed)c                 &    j                          y Nstopignoredr@   s    r"   stopReactorzNDatagramTransportTestsMixin.test_connectionLostLogMessage.<locals>.stopReactor]   s    LLNr)   c                  X     d d = t        j                        j                         y rG   )r
   stopListeningaddCallback)r?   rB   rL   s   r"   doStopListeningzRDatagramTransportTestsMixin.test_connectionLostLogMessage.<locals>.doStopListening`   s"    q!!//*66{Cr)   r   r8   N)	r9   r:   r;   r   r<   r=   callWhenRunning
runReactorr>   )r2   rC   rP   r?   rB   r@   rL   s      @@@@r"   test_connectionLostLogMessagez9DatagramTransportTestsMixin.test_connectionLostLogMessageS   s    
 ##%!!'+;+=>&qyy{'7'7&8A		D 	0 /+^A->y-IJr)   c                 >    G fddt               }| j                          |       }| j                  |       | j                         | j	                  |j
                         | j	                  |j                         | j                  |j                         y)z
        L{DatagramProtocol.stopProtocol} is called asynchronously (ie, not
        re-entrantly) when C{stopListening} is used to stop the datagram
        transport.
        c                   .    e Zd ZdZdZdZdZd Z fdZy)VDatagramTransportTestsMixin.test_stopProtocolScheduling.<locals>.DisconnectingProtocolFc                 b    d| _         d| _        | j                  j                          d| _        y )NTF)startedinStartProtocol	transportrN   r1   s    r"   startProtocolzdDatagramTransportTestsMixin.test_stopProtocolScheduling.<locals>.DisconnectingProtocol.startProtocolv   s)    #'+$,,.',$r)   c                 V    d| _         | j                  | _        j                          y )NT)stoppedrY   stoppedInStartrI   r2   r@   s    r"   stopProtocolzcDatagramTransportTestsMixin.test_stopProtocolScheduling.<locals>.DisconnectingProtocol.stopProtocol|   s!    #&*&:&:#r)   N)	r4   r5   r6   rX   r]   rY   r^   r[   r`   )r@   s   r"   DisconnectingProtocolrV   p   s!    GG#O"N-r)   ra   N)	r   r:   r;   rR   
assertTruerX   r]   assertFalser^   )r2   ra   rA   r@   s      @r"   test_stopProtocolSchedulingz7DatagramTransportTestsMixin.test_stopProtocolSchedulingi   s|    	$4 	" ##%(*gx0 (()(()001r)   N)r4   r5   r6   __doc__rD   rS   rd   r0   r)   r"   r+   r+   ;   s    K&K,2r)   r+   c                       e Zd ZdZd Zd Zed        Zd Zd Z	d Z
d Zd	 Zed
        Zed        Zd Zed        Zed        Zd Zd Zy)UDPPortTestsMixinzY
    Tests for L{IReactorUDP.listenUDP} and
    L{IReactorSocket.adoptDatagramPort}.
    c                     | j                         }| j                  |t                     }| j                  t	        t
        |             y)zY
        L{IReactorUDP.listenUDP} returns an object providing L{IListeningPort}.
        N)r:   r;   r   rb   r   r   r2   r@   r=   s      r"   test_interfacez UDPPortTestsMixin.test_interface   s;     ##%$$W.>.@A^T:;r)   c                     t        t        j                        \  }}| j                         }| j	                  |t               ||      }| j                  |j                         t        d||             y)z
        L{IListeningPort.getHost} returns an L{IPv4Address} giving a
        dotted-quad of the IPv4 address the port is listening on as well as
        the port number.
        )type)r=   	interfaceUDPN)	r   r   
SOCK_DGRAMr:   r;   r   r>   r<   r   )r2   host
portNumberr@   r=   s        r"   test_getHostzUDPPortTestsMixin.test_getHost   sj     (V->->?j##%$$%'jD % 
 	UD*)MNr)   c                     | j                         }| j                  |t               d      }|j                         }| j	                  |j
                  d       | j                  |t               y)zr
        L{IListeningPort.getHost} returns an L{IPv6Address} when listening on
        an IPv6 interface.
        r   rm   N)r:   r;   r   r<   r>   rp   assertIsInstancer   )r2   r@   r=   addrs       r"   test_getHostIPv6z"UDPPortTestsMixin.test_getHostIPv6   s\     ##%$$W.>.@E$R||~E*dK0r)   c                     | j                         }| j                  t        j                  |j                  t               dd       y)z
        An L{InvalidAddressError} is raised when trying to listen on an address
        that isn't a valid IPv4 or IPv6 address.
        r   zexample.comrt   N)r:   assertRaisesr   InvalidAddressError	listenUDPr   r_   s     r"   test_invalidInterfacez'UDPPortTestsMixin.test_invalidInterface   sC    
 ##%%%# 	 	
r)   c                      G d dt               } j                          |d      }|j                  } j                  |      }|j	                         } fd}|j                  |       |j                  t               |j                  fd       |j                  dd|j                  f        j                         y)	z
        Datagram transports implement L{ILoggingContext.logPrefix} to return a
        message reflecting the protocol they are running.
        c                       e Zd Zd Zd Zd Zy)IUDPPortTestsMixin.test_logPrefix.<locals>.CustomLogPrefixDatagramProtocolc                 0    || _         t               | _        y rG   )_prefixr	   system)r2   prefixs     r"   __init__zRUDPPortTestsMixin.test_logPrefix.<locals>.CustomLogPrefixDatagramProtocol.__init__   s    %&jr)   c                     | j                   S rG   )r   r1   s    r"   r3   zSUDPPortTestsMixin.test_logPrefix.<locals>.CustomLogPrefixDatagramProtocol.logPrefix   s    ||#r)   c                     | j                   ?| j                   }d | _         |j                  t        j                  t              d          y y )Nr   )r   callbackr   getr   )r2   bytesrv   r   s       r"   datagramReceivedzZUDPPortTestsMixin.test_logPrefix.<locals>.CustomLogPrefixDatagramProtocol.datagramReceived   s;    ;;*![[F"&DKOOGKK$<X$FG +r)   N)r4   r5   r6   r   r3   r   r0   r)   r"   CustomLogPrefixDatagramProtocolr      s    )$Hr)   r   zCustom Datagramsc                 *    j                  d|        y )NzCustom Datagrams (UDP))r>   )r   r2   s    r"   	gotSystemz3UDPPortTestsMixin.test_logPrefix.<locals>.gotSystem   s    5v>r)   c                 $    j                         S rG   rH   rJ   s    r"   <lambda>z2UDPPortTestsMixin.test_logPrefix.<locals>.<lambda>   s    glln r)   s
   some bytes	127.0.0.1N)r   r:   r   r;   r<   rO   
addErrbackr   writer=   rR   )r2   r   rA   dr=   addressr   r@   s   `      @r"   test_logPrefixz UDPPortTestsMixin.test_logPrefix   s    	H.> 	H ##%23EFOO$$Wh7,,.	? 	
i 	S	45

=;"=> r)   c                      G d dt               } j                          |       }|j                  } j                  |      }|j	                         }d fd} |j
                  |        |j                  t                |j
                  fd       |j                  d|j                  f        j                         y)zH
        Write a sequence of L{bytes} to a L{DatagramProtocol}.
        c                       e Zd Zd Zd Zy)DUDPPortTestsMixin.test_writeSequence.<locals>.SimpleDatagramProtocolc                 "    t               | _        y rG   )r	   r   r1   s    r"   r   zMUDPPortTestsMixin.test_writeSequence.<locals>.SimpleDatagramProtocol.__init__   s    %Z
r)   c                 :    | j                   j                  |       y rG   )r   r   )r2   datarv   s      r"   r   zUUDPPortTestsMixin.test_writeSequence.<locals>.SimpleDatagramProtocol.datagramReceived   s    

##D)r)   N)r4   r5   r6   r   r   r0   r)   r"   SimpleDatagramProtocolr      s    (*r)   r   )s   somes   bytess   tos   writec                 H    j                  dj                        |        y )Nr)   )r>   join)r   dataToWriter2   s    r"   gotDataz5UDPPortTestsMixin.test_writeSequence.<locals>.gotData   s    SXXk2D9r)   c                 $    j                         S rG   rH   rJ   s    r"   r   z6UDPPortTestsMixin.test_writeSequence.<locals>.<lambda>   s    ',,. r)   r   N)r   r:   r   r;   r<   rO   r   r   writeSequencer=   rR   )	r2   r   rA   r   r=   r   r   r   r@   s	   `      @@r"   test_writeSequencez$UDPPortTestsMixin.test_writeSequence   s    
	*%5 	* ##%)+$$Wh7,,.:	: 	'"89;gll(CD r)   c                     | j                         }| j                  |t                     }| j                  t	        |j                         j                        t	        |             y)zQ
        C{str()} on the listening port object includes the port number.
        N)r:   r;   r   assertInstrr<   r=   ri   s      r"   test_strzUDPPortTestsMixin.test_str   sK     ##%$$W.>.@Ac$,,.--.D	:r)   c                     | j                         }| j                  |t                     }| j                  t	        |j                         j                        t        |             y)zR
        C{repr()} on the listening port object includes the port number.
        N)r:   r;   r   r   reprr<   r=   r   ri   s      r"   	test_reprzUDPPortTestsMixin.test_repr  sK     ##%$$W.>.@Ad4<<>../T;r)   c                   	
 | j                         	t               
t        j                         x}
_        | j                  	
d       t               t        j                         x}_        | j                  	d       j                  j                         }
fd}	fd}t        j                  ||g      }|j                  |       |j                  |       |j                  t               | j                  	       
j                  d   }| j                  |d|j                   |j"                  ff       y)zS
        Writing to an IPv6 UDP socket on the loopback interface succeeds.
        r   rt   c                     j                   j                  ddj                   j                         j                  f       t	        j
                         x}_        |S )
            Send a datagram from the client once it's started.

            @param ignored: a list of C{[None, None]}, which is ignored
            @returns: a deferred which fires when the server has received a
                datagram.
               spamr   )rZ   r   r<   r=   r   r	   packetReceivedrK   serverReceivedclientservers     r"   cbClientStartedzDUDPPortTestsMixin.test_writeToIPv6Interface.<locals>.cbClientStarted  sO     ""7UF4D4D4L4L4N4S4S,TU5:^^5EENV2!!r)   c                 &    j                          yz
            Stop the reactor after a datagram is received.

            @param ignored: L{None}, which is ignored
            @returns: L{None}
            NrH   rJ   s    r"   cbServerReceivedzEUDPPortTestsMixin.test_writeToIPv6Interface.<locals>.cbServerReceived+  s     LLNr)   r   r   Nr:   r   r   r	   startedDeferredr;   r   rZ   r<   gatherResultsrO   r   r   rR   packetsr>   rp   r=   r2   serverStartedclientStartedcAddrr   r   r   packetr   r@   r   s           @@@r"   test_writeToIPv6Interfacez+UDPPortTestsMixin.test_writeToIPv6Interface  s	   
 ##%161AA.gv?161AA.gv?  ((*
	"	  >?	o&	&'	S "'EJJ

+C!DEr)   c                   	
 | j                         	t               
t        j                         x}
_        | j                  	
d       t               t        j                         x}_        | j                  	d       j                  j                         }
fd}	fd}t        j                  ||g      }|j                  |       |j                  |       |j                  t               | j                  	       
j                  d   }| j                  |d|j                   |j"                  ff       y)z
        An IPv6 address can be passed as the C{interface} argument to
        L{listenUDP}. The resulting Port accepts IPv6 datagrams.
        r   rt   c                     j                   j                  dj                   j                         j                         j                   j	                  d       t        j                         x}_        |S )r   r   r   )rZ   connectr<   r=   r   r   r	   r   r   s     r"   r   zMUDPPortTestsMixin.test_connectedWriteToIPv6Interface.<locals>.cbClientStartedM  s^     $$UF,<,<,D,D,F,K,KL""7+5:^^5EENV2!!r)   c                 &    j                          yr   rH   rJ   s    r"   r   zNUDPPortTestsMixin.test_connectedWriteToIPv6Interface.<locals>.cbServerReceived[  s     LLNr)   r   r   Nr   r   s           @@@r"   "test_connectedWriteToIPv6Interfacez4UDPPortTestsMixin.test_connectedWriteToIPv6Interface=  s	    ##%161AA.gv?161AA.gv?  ((*	"	  >?	o&	&'	S "'EJJ

+C!DEr)   c                     | j                         }| j                  |t                     }| j                  t        j
                  |j                  dd       y)zn
        Writing to a hostname instead of an IP address will raise an
        L{InvalidAddressError}.
        spam)example.invalid   Nr:   r;   r   ry   r   rz   r   ri   s      r"   /test_writingToHostnameRaisesInvalidAddressErrorzAUDPPortTestsMixin.test_writingToHostnameRaisesInvalidAddressErrorn  sJ    
 ##%$$W.>.@A%%tzz6;Q	
r)   c                     | j                         }| j                  |t               d      }| j                  t        j
                  |j                  dd       y)l
        Writing to an IPv6 address on an IPv4 socket will raise an
        L{InvalidAddressError}.
        r   rt   r   )r   r   Nr   ri   s      r"   1test_writingToIPv6OnIPv4RaisesInvalidAddressErrorzCUDPPortTestsMixin.test_writingToIPv6OnIPv4RaisesInvalidAddressErrory  sK     ##%$$W.>.@K$X%33TZZTr)   c                     | j                         }| j                  |t               d      }| j                  t        j
                  |j                  dd       y)r   r   rt   r   )r   r   Nr   ri   s      r"   1test_writingToIPv4OnIPv6RaisesInvalidAddressErrorzCUDPPortTestsMixin.test_writingToIPv4OnIPv6RaisesInvalidAddressError  sO     ##%$$W.>.@E$R%%tzz6;K	
r)   c                     | j                         }| j                  |t                     }| j                  t        j
                  |j                  dd       y)zq
        Connecting to a hostname instead of an IP address will raise an
        L{InvalidAddressError}.
        r   r   N)r:   r;   r   ry   r   rz   r   ri   s      r"   2test_connectingToHostnameRaisesInvalidAddressErrorzDUDPPortTestsMixin.test_connectingToHostnameRaisesInvalidAddressError  sH    
 ##%$$W.>.@A%33T\\CTVWXr)   c                     | j                         }| j                  |t                     }|j                  d       | j	                  |j                                y)zk
        L{IListeningPort.setBroadcastAllowed} sets broadcast to be allowed
        on the socket.
        TN)r:   r;   r   setBroadcastAllowedrb   getBroadcastAllowedri   s      r"   test_allowBroadcastz%UDPPortTestsMixin.test_allowBroadcast  sK    
 ##%$$W.>.@A  &0023r)   N)r4   r5   r6   re   rj   rr   r(   rw   r|   r   r   r   r   r   r   r   r   r   r   r   r0   r)   r"   rg   rg      s    
<O 	1 	1
"!H!8;< *F *FX .F .F`	
 U U 	
 	
Y4r)   rg   c                        e Zd ZdZefZ	 ddZy)UDPServerTestsBuilderzM
    Run L{UDPPortTestsMixin} tests using newly created UDP
    sockets.
    c                 ,    |j                  ||||      S )aB  
        Get a UDP port from a reactor.

        @param reactor: A reactor used to build the returned
            L{IListeningPort} provider.
        @type reactor: L{twisted.internet.interfaces.IReactorUDP}

        @see: L{twisted.internet.IReactorUDP.listenUDP} for other
            argument and return types.
        )rm   maxPacketSize)r{   )r2   r@   rA   r=   rm   r   s         r"   r;   z&UDPServerTestsBuilder.getListeningPort  s%       (i} ! 
 	
r)   Nr    i    )r4   r5   r6   re   r   requiredInterfacesr;   r0   r)   r"   r   r     s    
 & FJ
r)   r   c                        e Zd ZdZefZ	 ddZy)UDPFDServerTestsBuilderzC
    Run L{UDPPortTestsMixin} tests using adopted UDP sockets.
    c                 <   t        j                  |      rd|v r-t        j                  }t        j                  ||      d   d   }nt        j
                  }||f}t        j                  |t        j                        }|j                  |       |j                  d       	 |j                  |j                         |j                  ||      |j                          |j                          S t        d      # |j                          |j                          w xY w)a  
        Get a UDP port from a reactor, wrapping an already-initialized file
        descriptor.

        @param reactor: A reactor used to build the returned
            L{IListeningPort} provider.
        @type reactor: L{twisted.internet.interfaces.IReactorSocket}

        @param port: A port number to which the adopted socket will be
            bound.
        @type port: C{int}

        @param interface: The local IPv4 or IPv6 address to which the
            adopted socket will be bound.  defaults to '', ie all IPv4
            addresses.
        @type interface: C{str}

        @see: L{twisted.internet.IReactorSocket.adoptDatagramPort} for other
            argument and return types.
        :r      Fz'Reactor does not provide IReactorSocket)r   
providedByr   r   getaddrinfoAF_INETro   r   setblockingadoptDatagramPortfilenofamilyr   r   )	r2   r@   rA   r=   rm   r   domainr   portSocks	            r"   r;   z(UDPFDServerTestsBuilder.getListeningPort  s    . $$W-i ,,Y=a@C$d+}}VV->->?HMM'"  '
!00OO%x- !  DEE !  s   "+C9 9"DNr   )r4   r5   r6   re   r   r   r;   r0   r)   r"   r   r     s     )* FJ-Fr)   r   )/re   r   zope.interfacer   zope.interface.verifyr   twisted.internetr   r   twisted.internet.addressr   r   twisted.internet.deferr	   r
   twisted.internet.interfacesr   r   r   r   twisted.internet.protocolr   &twisted.internet.test.connectionmixinsr   r   #twisted.internet.test.reactormixinsr   twisted.pythonr   twisted.python.logr   r   twisted.test.test_udpr   r   twisted.trial.unittestr   r#   r%   r(   r+   rg   r   r   globalsupdatemakeTestCaseClassesr0   r)   r"   <module>r      s     & . ) = :  7 Q > " / 4 +" ;M2"2 M2`U4 U4p
%'B
86F%'B6Fr 	  &::< = 	  (<<> ?r)   