
    VhO@                        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dl%m&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+       jY                  e)j[                                 e+       jY                  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)skipWithoutIPv6)SkipTestc                   "    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    N/home/dcms/DCMS/lib/python3.12/site-packages/twisted/internet/test/test_udp.py	logPrefixz[DatagramTransportTestsMixin.test_startedListeningLogMessage.<locals>.SomeProtocol.logPrefix1   s    '    N)__name__
__module____qualname__r$   r    r%   r#   SomeProtocolr   /   s    (r%   r)   zCrazy Protocol starting on %dr   messageN)	observebuildReactorr   r   r   getListeningPortgetHostportassertEqual)r"   loggedMessagesreactorr)   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ignoredr2   s    r#   stopReactorzNDatagramTransportTestsMixin.test_connectionLostLogMessage.<locals>.stopReactorD   s    LLNr%   c                  X     d d = t        j                        j                         y r9   )r
   stopListeningaddCallback)r1   r4   r>   s   r#   doStopListeningzRDatagramTransportTestsMixin.test_connectionLostLogMessage.<locals>.doStopListeningG   s"    q!!//*66{Cr%   r   r*   N)	r+   r,   r-   r   r.   r/   callWhenRunning
runReactorr0   )r"   r5   rB   r1   r4   r2   r>   s      @@@@r#   test_connectionLostLogMessagez9DatagramTransportTestsMixin.test_connectionLostLogMessage:   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	transportr@   r!   s    r#   startProtocolzdDatagramTransportTestsMixin.test_stopProtocolScheduling.<locals>.DisconnectingProtocol.startProtocol]   s)    #'+$,,.',$r%   c                 V    d| _         | j                  | _        j                          y )NT)stoppedrK   stoppedInStartr;   r"   r2   s    r#   stopProtocolzcDatagramTransportTestsMixin.test_stopProtocolScheduling.<locals>.DisconnectingProtocol.stopProtocolc   s!    #&*&:&:#r%   N)	r&   r'   r(   rJ   rO   rK   rP   rM   rR   )r2   s   r#   DisconnectingProtocolrH   W   s!    GG#O"N-r%   rS   N)	r   r,   r-   rD   
assertTruerJ   rO   assertFalserP   )r"   rS   r3   r2   s      @r#   test_stopProtocolSchedulingz7DatagramTransportTestsMixin.test_stopProtocolSchedulingP   s|    	$4 	" ##%(*gx0 (()(()001r%   N)r&   r'   r(   __doc__r6   rE   rV   r    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   rT   r   r   r"   r2   r/   s      r#   test_interfacez UDPPortTestsMixin.test_interfacex   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   socket
SOCK_DGRAMr,   r-   r   r0   r.   r   )r"   host
portNumberr2   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.
        ::1r_   N)r,   r-   r   r.   r0   rc   assertIsInstancer   )r"   r2   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.comrh   N)r,   assertRaisesr   InvalidAddressError	listenUDPr   rQ   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 r9   )_prefixr	   system)r"   prefixs     r#   __init__zRUDPPortTestsMixin.test_logPrefix.<locals>.CustomLogPrefixDatagramProtocol.__init__   s    %&jr%   c                     | j                   S r9   )ru   r!   s    r#   r$   zSUDPPortTestsMixin.test_logPrefix.<locals>.CustomLogPrefixDatagramProtocol.logPrefix   s    ||#r%   c                     | j                   ?| j                   }d | _         |j                  t        j                  t              d          y y )Nrv   )rv   callbackr   getr   )r"   bytesrj   rv   s       r#   datagramReceivedzZUDPPortTestsMixin.test_logPrefix.<locals>.CustomLogPrefixDatagramProtocol.datagramReceived   s;    ;;*![[F"&DKOOGKK$<X$FG +r%   N)r&   r'   r(   rx   r$   r~   r    r%   r#   CustomLogPrefixDatagramProtocolrs      s    )$Hr%   r   zCustom Datagramsc                 *    j                  d|        y )NzCustom Datagrams (UDP))r0   )rv   r"   s    r#   	gotSystemz3UDPPortTestsMixin.test_logPrefix.<locals>.gotSystem   s    5v>r%   c                 $    j                         S r9   r:   r<   s    r#   <lambda>z2UDPPortTestsMixin.test_logPrefix.<locals>.<lambda>   s    glln r%   s
   some bytes	127.0.0.1N)r   r,   rv   r-   r.   rA   
addErrbackr   writer/   rD   )r"   r   r3   dr/   addressr   r2   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 r9   )r	   r   r!   s    r#   rx   zMUDPPortTestsMixin.test_writeSequence.<locals>.SimpleDatagramProtocol.__init__   s    %Z
r%   c                 :    | j                   j                  |       y r9   )r   r{   )r"   datarj   s      r#   r~   zUUDPPortTestsMixin.test_writeSequence.<locals>.SimpleDatagramProtocol.datagramReceived   s    

##D)r%   N)r&   r'   r(   rx   r~   r    r%   r#   SimpleDatagramProtocolr      s    (*r%   r   )s   somes   bytess   tos   writec                 H    j                  dj                        |        y )Nr%   )r0   join)r   dataToWriter"   s    r#   gotDataz5UDPPortTestsMixin.test_writeSequence.<locals>.gotData   s    SXXk2D9r%   c                 $    j                         S r9   r:   r<   s    r#   r   z6UDPPortTestsMixin.test_writeSequence.<locals>.<lambda>   s    ',,. r%   r   N)r   r,   r   r-   r.   rA   r   r   writeSequencer/   rD   )	r"   r   r3   r   r/   r   r   r   r2   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/   r[   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   r[   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.
        rg   rh   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.
               spamrg   )rL   r   r.   r/   r   r	   packetReceivedr=   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}
            Nr:   r<   s    r#   cbServerReceivedzEUDPPortTestsMixin.test_writeToIPv6Interface.<locals>.cbServerReceived  s     LLNr%   r   r   Nr,   r   r   r	   startedDeferredr-   r   rL   r.   gatherResultsrA   r   r   rD   packetsr0   rc   r/   r"   serverStartedclientStartedcAddrr   r   r   packetr   r2   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.
        rg   rh   c                     j                   j                  dj                   j                         j                         j                   j	                  d       t        j                         x}_        |S )r   rg   r   )rL   connectr.   r/   r   r   r	   r   r   s     r#   r   zMUDPPortTestsMixin.test_connectedWriteToIPv6Interface.<locals>.cbClientStarted4  s^     $$UF,<,<,D,D,F,K,KL""7+5:^^5EENV2!!r%   c                 &    j                          yr   r:   r<   s    r#   r   zNUDPPortTestsMixin.test_connectedWriteToIPv6Interface.<locals>.cbServerReceivedB  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   rm   r   rn   r   r[   s      r#   /test_writingToHostnameRaisesInvalidAddressErrorzAUDPPortTestsMixin.test_writingToHostnameRaisesInvalidAddressErrorU  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   rh   r   )rg   r   Nr   r[   s      r#   1test_writingToIPv6OnIPv4RaisesInvalidAddressErrorzCUDPPortTestsMixin.test_writingToIPv6OnIPv4RaisesInvalidAddressError`  sK     ##%$$W.>.@K$X%33TZZTr%   c                     | j                         }| j                  |t               d      }| j                  t        j
                  |j                  dd       y)r   rg   rh   r   )r   r   Nr   r[   s      r#   1test_writingToIPv4OnIPv6RaisesInvalidAddressErrorzCUDPPortTestsMixin.test_writingToIPv4OnIPv6RaisesInvalidAddressErrorj  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   rm   r   rn   r   r[   s      r#   2test_connectingToHostnameRaisesInvalidAddressErrorzDUDPPortTestsMixin.test_connectingToHostnameRaisesInvalidAddressErrorv  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   setBroadcastAllowedrT   getBroadcastAllowedr[   s      r#   test_allowBroadcastz%UDPPortTestsMixin.test_allowBroadcast  sK    
 ##%$$W.>.@A  &0023r%   N)r&   r'   r(   rW   r\   re   r   rk   rp   r   r   r   r   r   r   r   r   r   r   r   r    r%   r#   rY   rY   r   s    
<O 	1 	1
"!H!8;< *F *FX .F .F`	
 U U 	
 	
Y4r%   rY   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.
        )r_   maxPacketSize)ro   )r"   r2   r3   r/   r_   r   s         r#   r-   z&UDPServerTestsBuilder.getListeningPort  s%       (i} ! 
 	
r%   Nr    i    )r&   r'   r(   rW   r   requiredInterfacesr-   r    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   
providedByra   AF_INET6getaddrinfoAF_INETrb   bindsetblockingadoptDatagramPortfilenofamilycloser   )	r"   r2   r3   r/   r_   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   )r&   r'   r(   rW   r   r   r-   r    r%   r#   r   r     s     )* FJ-Fr%   r   ).rW   ra   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.test.testutilsr   twisted.trial.unittestr   r   rY   r   r   globalsupdatemakeTestCaseClassesr    r%   r#   <module>r      s     & . ) = :  7 Q > " / 4 2 +M2"2 M2`U4 U4p
%'B
86F%'B6Fr 	  &::< = 	  (<<> ?r%   