
    VhL                        d Z ddlmZ ddlmZmZmZmZmZm	Z	m
Z
mZ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mZ ddlmZmZ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% ddl&m'Z'm(Z(m)Z)m*Z* ddl+m,Z, ddl-m.Z/  G d de,      Z0d Z1d Z2 G d d      Z3 ee)       G d d             Z4 G d de/      Z5 G d de/      Z6 ee*       G d d             Z7 G d de/      Z8 G d  d!e!      Z9 G d" d#e/      Z:y$)%zh
Tests for implementations of L{IHostnameResolver} and their interactions with
reactor implementations.
    )defaultdict)	AF_INETAF_INET6	AF_UNSPEC
EAI_NONAMEIPPROTO_TCP
SOCK_DGRAMSOCK_STREAMgaierrorgetaddrinfo)Locklocal)implementer)verifyObject)
LockWorkerTeamcreateMemoryWorker)ComplexResolverSimplifierGAIResolverSimpleResolverComplexifier)IPv4AddressIPv6Address)PluggableResolverMixinReactorBase)Deferred)DNSLookupError)IHostnameResolverIReactorPluggableNameResolverIResolutionReceiverIResolverSimple)
ThreadPool)SynchronousTestCasec                       e Zd ZdZd Zy)DeterministicThreadPoolz6
    Create a deterministic L{ThreadPool} object.
    c                 J    d| _         d| _        d| _        g | _        || _        y)zE
        Create a L{DeterministicThreadPool} from a L{Team}.
           N)minmaxnamethreads_team)selfteams     S/home/dcms/DCMS/lib/python3.12/site-packages/twisted/internet/test/test_resolver.py__init__z DeterministicThreadPool.__init__4   s'     	
    N)__name__
__module____qualname____doc__r/    r0   r.   r$   r$   /   s    r0   r$   c            	          t               \  } t        t        t        t	               t                     fdd             | fS )z
    Create a deterministic threadpool.

    @return: 2-tuple of L{ThreadPool}, 0-argument C{work} callable; when
        C{work} is called, do the work.
    c                       S Nr5   workers   r.   <lambda>z#deterministicPool.<locals>.<lambda>I   s    v r0   c                       y r8   r5   r5   r0   r.   r;   z#deterministicPool.<locals>.<lambda>I       r0   )r   r$   r   r   r   r   )doerr:   s    @r.   deterministicPoolr?   ?   s?     &'LFDDFEG,~M	
 		 r0   c                  H    t               \  }  G fdd      } |       | fS )z
    Create a deterministic L{IReactorThreads}

    @return: a 2-tuple consisting of an L{IReactorThreads}-like object and a
        0-argument callable that will perform one unit of work invoked via that
        object's C{callFromThread} method.
    c                       e Zd Z fdZy)(deterministicReactorThreads.<locals>.CFTc                 8    j                  fd       y )Nc                        i S r8   r5   )afks   r.   r;   zIdeterministicReactorThreads.<locals>.CFT.callFromThread.<locals>.<lambda>[   s    ajaj r0   )do)r,   rF   rE   rG   r:   s    ```r.   callFromThreadz7deterministicReactorThreads.<locals>.CFT.callFromThreadZ   s    II()r0   N)r1   r2   r3   rI   r9   s   r.   CFTrB   Y   s    	*r0   rJ   )r   )r>   rJ   r:   s     @r.   deterministicReactorThreadsrK   O   s)     &'LFD* * 5$;r0   c                   .    e Zd ZdZd ZddZeeedfdZ	y)FakeAddrInfoGetterz/
    Test object implementing getaddrinfo.
    c                 :    g | _         t        t              | _        y)z1
        Create a L{FakeAddrInfoGetter}.
        N)callsr   listresultsr,   s    r.   r/   zFakeAddrInfoGetter.__init__e   s     
"4(r0   c                     | j                   j                  ||||||f       | j                  |   }|r|S t        t        d      )a  
        Mock for L{socket.getaddrinfo}.

        @param host: see L{socket.getaddrinfo}

        @param port: see L{socket.getaddrinfo}

        @param family: see L{socket.getaddrinfo}

        @param socktype: see L{socket.getaddrinfo}

        @param proto: see L{socket.getaddrinfo}

        @param flags: see L{socket.getaddrinfo}

        @return: L{socket.getaddrinfo}
        z,nodename nor servname provided, or not known)rO   appendrQ   r   r   )r,   hostportfamilysocktypeprotoflagsrQ   s           r.   r   zFakeAddrInfoGetter.getaddrinfol   sG    $ 	

4vxFG,,t$N:'UVVr0   r0   c                 J    | j                   |   j                  |||||f       y)a  
        Add a result for a given hostname.  When this hostname is resolved, the
        result will be a L{list} of all results C{addResultForHost} has been
        called with using that hostname so far.

        @param host: The hostname to give this result for.  This will be the
            next result from L{FakeAddrInfoGetter.getaddrinfo} when passed this
            host.

        @type canonname: native L{str}

        @param sockaddr: The resulting socket address; should be a 2-tuple for
            IPv4 or a 4-tuple for IPv6.

        @param family: An C{AF_*} constant that will be returned from
            C{getaddrinfo}.

        @param socktype: A C{SOCK_*} constant that will be returned from
            C{getaddrinfo}.

        @param proto: An C{IPPROTO_*} constant that will be returned from
            C{getaddrinfo}.

        @param canonname: A canonical name that will be returned from
            C{getaddrinfo}.
        @type canonname: native L{str}
        N)rQ   rT   )r,   rU   sockaddrrW   rX   rY   	canonnames          r.   addResultForHostz#FakeAddrInfoGetter.addResultForHost   s'    H 	T!!68UIx"PQr0   N)r   r   r   r   )
r1   r2   r3   r4   r/   r   r   r
   r   r^   r5   r0   r.   rM   rM   `   s&    )W: $Rr0   rM   c                   0    e Zd ZdZdZdZd Zd Zd Zd Z	y)ResultHolderzI
    A resolution receiver which holds onto the results it received.
    Fc                     || _         y)z>
        Create a L{ResultHolder} with a L{UnitTest}.
        N)	_testCase)r,   testCases     r.   r/   zResultHolder.__init__   s     "r0   c                 .    d| _         || _        g | _        y)zg
        Hostname resolution began.

        @param hostResolution: see L{IResolutionReceiver}
        TN)_started_resolution
_addresses)r,   hostResolutions     r.   resolutionBeganzResultHolder.resolutionBegan   s     )r0   c                 :    | j                   j                  |       y)z^
        An address was resolved.

        @param address: see L{IResolutionReceiver}
        N)rg   rT   )r,   addresss     r.   addressResolvedzResultHolder.addressResolved   s     	w'r0   c                     d| _         y)z2
        Hostname resolution is complete.
        TN)_endedrR   s    r.   resolutionCompletezResultHolder.resolutionComplete   s     r0   N)
r1   r2   r3   r4   re   rn   r/   ri   rl   ro   r5   r0   r.   r`   r`      s'     HF"(r0   r`   c                       e Zd ZdZd Zy)HelperTestsz?
    Tests for error cases of helpers used in this module.
    c                     t               \  | _        | _        d }| j                  j                  |       | j                          | j	                  t        | j                  t                    d       y)zq
        L{DeterministicThreadPool} will log any exceptions that its "thread"
        workers encounter.
        c                      ddz  S )Nr&   r   r5   r5   r0   r.   divideByZeroz9HelperTests.test_logErrorsInThreads.<locals>.divideByZero   s    q5Lr0   r&   N)r?   pooldoThreadWorkcallInThreadassertEquallenflushLoggedErrorsZeroDivisionError)r,   rt   s     r.   test_logErrorsInThreadsz#HelperTests.test_logErrorsInThreads   s\    
 (9':$	4$	 			|,T334EFGKr0   N)r1   r2   r3   r4   r|   r5   r0   r.   rq   rq      s    Lr0   rq   c                   L    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zy)HostnameResolutionTestsz(
    Tests for hostname resolution.
    c                      t               \   _         _        t               \   _         _        t                _        t         j                   fd j                  j                         _
        y)z*
        Set up a L{GAIResolver}.
        c                       j                   S r8   ru   rR   s   r.   r;   z/HostnameResolutionTests.setUp.<locals>.<lambda>       $)) r0   N)r?   ru   rv   rK   reactordoReactorWorkrM   getterr   r   resolverrR   s   `r.   setUpzHostnameResolutionTests.setUp   sU     (9':$	4$+F+H(d((*#LL+T[[-D-D
r0   c                    t        |       }| j                  j                  dd       | j                  j	                  |d      }| j                  |j                  |       | j                  |j                  d       | j                  |j                  d       | j                          | j                          | j                  |j                  d       | j                  |j                  t        ddd      g       y)	z
        Resolving an individual hostname that results in one address from
        getaddrinfo results in a single call each to C{resolutionBegan},
        C{addressResolved}, and C{resolutionComplete}.
        sample.example.com)4.3.2.1r   TFTCPr   r   N)r`   r   r^   r   resolveHostNameassertIsrf   rx   re   rn   rv   r   rg   r   r,   receiver
resolutions      r.   test_resolveOneHostz+HostnameResolutionTests.test_resolveOneHost   s      %$$%9>J]]228=QR
h**J7**D1%0$/,,{5)Q/O.PQr0   c           
         t        |       }d}d}| j                  j                  ddd||ft               | j                  j                  |d      }| j                  |j                  |       | j                  |j                  d       | j                  |j                  d       | j                          | j                          | j                  |j                  d       | j                  |j                  t        d	dd||      g       y
)a  
        Resolving an individual hostname that results in one address from
        getaddrinfo results in a single call each to C{resolutionBegan},
        C{addressResolved}, and C{resolutionComplete}; C{addressResolved} will
        receive an L{IPv6Address}.
        r&      r   ::1r   )rW   TFr   N)r`   r   r^   r   r   r   r   rf   rx   re   rn   rv   r   rg   r   )r,   r   flowInfoscopeIDr   s        r.   test_resolveOneIPv6Hostz/HostnameResolutionTests.test_resolveOneIPv6Host	  s      %$$ 5!Xw"? 	% 	
 ]]228=QR
h**J7**D1%0$/+eUAx"Q!R	
r0   c                 r   t        |       }| j                  j                  |d      }| j                  |j                  |       | j                          | j                          | j                  |j                  d       | j                  |j                  d       | j                  |j                  g        y)a
  
        Resolving a hostname that results in C{getaddrinfo} raising a
        L{gaierror} will result in the L{IResolutionReceiver} receiving a call
        to C{resolutionComplete} with no C{addressResolved} calls in between;
        no failure is logged.
        r   TN)r`   r   r   r   rf   rv   r   rx   re   rn   rg   r   s      r.   test_gaierrorz%HostnameResolutionTests.test_gaierror!  s      %]]228=QR
h**J7**D1$/,,b1r0   c                 2   t        |       }| j                  j                  |d|      }| j                  |j                  |       | j                          | j                          | j                  j                  d   \  }}}}}	}
| j                  ||       y)z
        Verify that the given set of address types results in the given C{AF_}
        constant being passed to C{getaddrinfo}.

        @param addrTypes: iterable of L{IAddress} implementers

        @param expectedAF: an C{AF_*} constant
        r   )addressTypesr   N)
r`   r   r   r   rf   rv   r   r   rO   rx   )r,   	addrTypes
expectedAFr   r   rU   rV   rW   rX   rY   rZ   s              r.   _resolveOnlyTestz(HostnameResolutionTests._resolveOnlyTest1  s      %]]22* 3 

 	h**J759[[5F5Fq5I2dFHeU,r0   c                 :    | j                  t        gt               y)z
        When passed an C{addressTypes} parameter containing only
        L{IPv4Address}, L{GAIResolver} will pass C{AF_INET} to C{getaddrinfo}.
        N)r   r   r   rR   s    r.   test_resolveOnlyIPv4z,HostnameResolutionTests.test_resolveOnlyIPv4D  s    
 	{mW5r0   c                 :    | j                  t        gt               y)z
        When passed an C{addressTypes} parameter containing only
        L{IPv6Address}, L{GAIResolver} will pass C{AF_INET6} to C{getaddrinfo}.
        N)r   r   r   rR   s    r.   test_resolveOnlyIPv6z,HostnameResolutionTests.test_resolveOnlyIPv6K  s    
 	{mX6r0   c                 p    | j                  t        t        gt               | j                  dt               y)z
        When passed an C{addressTypes} parameter containing both L{IPv4Address}
        and L{IPv6Address} (or the default of C{None}, which carries the same
        meaning), L{GAIResolver} will pass C{AF_UNSPEC} to C{getaddrinfo}.
        N)r   r   r   r   rR   s    r.   test_resolveBothz(HostnameResolutionTests.test_resolveBothR  s)     	{K8)DdI.r0   c                     t        |       }| j                  j                  |dd       t        |       }| j                  j                  |dd       | j                          | j	                          | j                          | j	                          | j
                  j                  d   \  }}}}}}| j
                  j                  d   \  }}}}	}}| j                  |t               | j                  |	t               y)z
        When passed a C{transportSemantics} paramter, C{'TCP'} (the value
        present in L{IPv4Address.type} to indicate a stream transport) maps to
        C{SOCK_STREAM} and C{'UDP'} maps to C{SOCK_DGRAM}.
        example.comr   )transportSemanticsUDPr   r&   N)
r`   r   r   rv   r   r   rO   rx   r
   r	   )
r,   r   	receiver2rU   rV   rW   	socktypeTrY   rZ   	socktypeUs
             r.   #test_transportSemanticsToSocketTypez;HostnameResolutionTests.test_transportSemanticsToSocketType[  s      %%%hRW%X &	%%} 	& 	
 	6:kk6G6G6J3dFIue6:kk6G6G6J3dFIueK0J/r0   c                 R   t        |       }d}d}t        t        fD ]L  }| j                  j	                  ddd||ft
        |       | j                  j	                  ddt        |       N | j                  j                  |d       | j                          | j                          |j                  \  }}}}| j                  |j                  d       | j                  |j                  d       | j                  |j                  d	       | j                  |j                  d	       y
)z
        When L{GAIResolver} receives a C{SOCK_DGRAM} result from
        C{getaddrinfo}, it returns a C{'TCP'} L{IPv4Address} or L{IPv6Address};
        if it receives C{SOCK_STREAM} then it returns a C{'UDP'} type of same.
        r&   r   r   r   r   )rW   rX   )z	127.0.0.3r   r   r   N)r`   r
   r	   r   r^   r   r   r   r   rv   r   rg   rx   type)	r,   r   r   r   rX   stream4stream6dgram4dgram6s	            r.   test_socketTypeToAddressTypez4HostnameResolutionTests.test_socketTypeToAddressTypep  s     %#Z/ 		HKK((8W-!	 )  KK((/( ) 		 	%%h>+3+>+>(&&u-u-e,e,r0   N)r1   r2   r3   r4   r   r   r   r   r   r   r   r   r   r   r5   r0   r.   r~   r~      s:    	
R"
02 -&67/0*-r0   r~   c                       e Zd ZdZd ZddZy)SillyResolverSimplez6
    Trivial implementation of L{IResolverSimple}
    c                     g | _         y)zd
        Create a L{SillyResolverSimple} with a queue of requests it is working
        on.
        N)	_requestsrR   s    r.   r/   zSillyResolverSimple.__init__  s    
 r0   c                 f    | j                   j                  t                      | j                   d   S )z
        Implement L{IResolverSimple.getHostByName}.

        @param name: see L{IResolverSimple.getHostByName}.

        @param timeout: see L{IResolverSimple.getHostByName}.

        @return: see L{IResolverSimple.getHostByName}.
        )r   rT   r   )r,   r)   timeouts      r.   getHostByNamez!SillyResolverSimple.getHostByName  s'     	hj)~~b!!r0   N)r5   )r1   r2   r3   r4   r/   r   r5   r0   r.   r   r     s    "r0   r   c                   .    e Zd ZdZd Zd Zd Zd Zd Zy)LegacyCompatibilityTestsz
    Older applications may supply an object to the reactor via
    C{installResolver} that only provides L{IResolverSimple}.
    L{SimpleResolverComplexifier} is a wrapper for an L{IResolverSimple}.
    c                    t               }t        |      }t        |       }| j                  |j                  d       |j                  |d       | j                  |j                  d       | j                  |j                  d       | j                  |j                  g        |j                  d   j                  d       | j                  |j                  t        ddd      g       | j                  |j                  d       y)z
        L{SimpleResolverComplexifier} translates C{resolveHostName} into
        L{IResolutionReceiver.addressResolved}.
        Fr   Tr   192.168.1.1r   N)r   r   r`   rx   re   r   rn   rg   r   callbackr   r,   simplecomplexr   s       r.   test_successz%LegacyCompatibilityTests.test_success  s    
 %&,V4%**E2-8**D1%0,,b1$$]3,,{5-QR/S.TU$/r0   c                    t               }t        |      }t        |       }| j                  |j                  d       |j                  |d       | j                  |j                  d       | j                  |j                  d       | j                  |j                  g        |j                  d   j                  t        d             | j                  |j                  d       | j                  |j                  g        y)z
        L{SimpleResolverComplexifier} translates a known error result from
        L{IResolverSimple.resolveHostName} into an empty result.
        Fr   Tr   nopeN)r   r   r`   rx   re   r   rn   rg   r   errbackr   r   s       r.   test_failurez%LegacyCompatibilityTests.test_failure  s    
 %&,V4%**E2-8**D1%0,,b1##N6$:;$/,,b1r0   c                 b   t               }t        |      }t        |       }| j                  |j                  d       |j                  |d       | j                  |j                  d       | j                  |j                  d       | j                  |j                  g        |j                  d   j                  t        d             | j                  t        | j                  t                    d       | j                  |j                  d       | j                  |j                  g        y)z
        L{SimpleResolverComplexifier} translates an unknown error result from
        L{IResolverSimple.resolveHostName} into an empty result and a logged
        error.
        Fr   Tr   zowr&   N)r   r   r`   rx   re   r   rn   rg   r   r   r{   ry   rz   r   s       r.   
test_errorz#LegacyCompatibilityTests.test_error  s     %&,V4%**E2-8**D1%0,,b1##$5e$<=T334EFGK$/,,b1r0   c                     t               \   _         _        t               \   _         _        t                _        t         j                   fd j                  j                         _
        t         j                        } j                  j                  dd       |j                  d      }|j                  d      } j                           j                           j                           j                           j                   j                  |      j                   t"                j                   j%                  |      d       y)z
        L{ComplexResolverSimplifier} translates an L{IHostnameResolver} into an
        L{IResolverSimple} for applications that still expect the old
        interfaces to be in place.
        c                       j                   S r8   r   rR   s   r.   r;   z:LegacyCompatibilityTests.test_simplifier.<locals>.<lambda>  r   r0   r   )192.168.3.4  znx.example.comr   N)r?   ru   rv   rK   r   r   rM   r   r   r   r   r   r^   r   rx   failureResultOfr   r   successResultOf)r,   simpleResolversuccessfailures   `   r.   test_simplifierz(LegacyCompatibilityTests.test_simplifier  s    (9':$	4$+F+H(d((*#LL+T[[-D-D
 34==A$$]4IJ ..}= ../?@--g6;;^L--g6Fr0   c                    t               }t        |      }t        |       }|j                  |dd       | j	                  |j
                  d       | j	                  |j                  d       | j	                  |j                  g        |j                  d   j                  d       | j	                  |j                  t        ddd      g       | j	                  |j                  d       y)	z
        L{SimpleResolverComplexifier} preserves the C{port} argument passed to
        C{resolveHostName} in its returned addresses.
        r   r   TFr   r   r   N)r   r   r`   r   rx   re   rn   rg   r   r   r   r   s       r.   test_portNumberz(LegacyCompatibilityTests.test_portNumber  s    
 %&,V4%->**D1%0,,b1$$]3,,{5-QU/V.WX$/r0   N)	r1   r2   r3   r4   r   r   r   r   r   r5   r0   r.   r   r     s!    0"2"2&G.0r0   r   c                       e Zd ZdZd Zy)JustEnoughReactorzT
    Just enough subclass implementation to be a valid L{ReactorBase} subclass.
    c                      y)z
        Do nothing.
        Nr5   rR   s    r.   installWakerzJustEnoughReactor.installWaker  r=   r0   N)r1   r2   r3   r4   r   r5   r0   r.   r   r     s    r0   r   c                   "    e Zd ZdZd Zd Zd Zy)ReactorInstallationTestsz
    Tests for installing old and new resolvers onto a
    L{PluggableResolverMixin} and L{ReactorBase} (from which all of Twisted's
    reactor implementations derive).
    c                     t               }t        t        |       t        t        |j                         t        t
        |j                         y)z
        L{PluggableResolverMixin} (and its subclasses) implement both
        L{IReactorPluggableNameResolver} and L{IReactorPluggableResolver}.
        N)r   r   r   r    r   r   nameResolverr,   r   s     r.   test_interfaceCompliancez1ReactorInstallationTests.test_interfaceCompliance  s8    
 )*2G<_g&6&67&(<(<=r0   c                     t               }t               }t        t        |j	                  |             | j                  |j                  t               | j                  |j                  j                  |       y)zf
        L{PluggableResolverMixin} will wrap an L{IResolverSimple} in a
        complexifier.
        N)
r   r   r   r    installResolverassertIsInstancer   r   r   _simpleResolver)r,   r   its      r.   test_installingOldStyleResolverz8ReactorInstallationTests.test_installingOldStyleResolver(  sZ    
 )* "_g&=&=b&ABg224NOg**::B?r0   c                    t               }| j                  |j                  t               | j	                  |j                  j
                  t               | j                  |j                  t               | j	                  |j                  j                  |       | j	                  |j                  j                  |j                         y)zD
        L{ReactorBase} defaults to using a L{GAIResolver}.
        N)r   r   r   r   r   _getaddrinfor   r   r   _reactor_nameResolverr   s     r.   test_defaultToGAIResolverz2ReactorInstallationTests.test_defaultToGAIResolver3  s     $%g22K@g**77Eg..0IJg**33W=g&&44g6J6JKr0   N)r1   r2   r3   r4   r   r   r   r5   r0   r.   r   r     s    >	@	Lr0   r   N);r4   collectionsr   socketr   r   r   r   r   r	   r
   r   r   	threadingr   r   zope.interfacer   zope.interface.verifyr   twisted._threadsr   r   r   twisted.internet._resolverr   r   r   twisted.internet.addressr   r   twisted.internet.baser   r   twisted.internet.deferr   twisted.internet.errorr   twisted.internet.interfacesr   r   r   r    twisted.python.threadpoolr!   twisted.trial.unittestr"   UnitTestr$   r?   rK   rM   r`   rq   r~   r   r   r   r   r5   r0   r.   <module>r      s   $
 
 
 " & . A A 
 > E + 1  1 Bj   "IR IRX  !$ $ "$NL( L(b-h b-J _" " "4a0x a0H %Lx %Lr0   