U
    ¸~HjšL  ã                   @   s¢  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„ de,ƒZ0dd„ Z1dd„ Z2G dd„ dƒZ3ee)ƒG dd„ dƒƒZ4G dd„ de/ƒZ5G dd„ de/ƒZ6ee*ƒG dd„ dƒƒZ7G d d!„ d!e/ƒZ8G d"d#„ d#e!ƒZ9G d$d%„ d%e/ƒZ:d&S )'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                   @   s   e Zd ZdZdd„ ZdS )ÚDeterministicThreadPoolz6
    Create a deterministic L{ThreadPool} object.
    c                 C   s"   d| _ d| _d| _g | _|| _dS )zE
        Create a L{DeterministicThreadPool} from a L{Team}.
        é   N)ÚminÚmaxÚnameÚthreadsZ_team)ÚselfZteam© r)   úG/tmp/pip-unpacked-wheel-ewod1tgb/twisted/internet/test/test_resolver.pyÚ__init__4   s
    z DeterministicThreadPool.__init__N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r+   r)   r)   r)   r*   r"   /   s   r"   c                     s4   t ƒ \‰ } ttttƒ tƒ ƒ‡ fdd„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   ˆ S ©Nr)   r)   ©Zworkerr)   r*   Ú<lambda>I   ó    z#deterministicPool.<locals>.<lambda>c                   S   s   d S r0   r)   r)   r)   r)   r*   r2   I   r3   )r   r"   r   r   r   r   )Údoerr)   r1   r*   ÚdeterministicPool?   s    
 ÿür5   c                     s&   t ƒ \‰ } G ‡ fd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                       s   e Zd Z‡ fdd„ZdS )z(deterministicReactorThreads.<locals>.CFTc                    s   ˆ  ‡ ‡‡fdd„¡ d S )Nc                      s
   ˆˆ ˆŽS r0   r)   r)   ©ÚaÚfÚkr)   r*   r2   [   r3   zIdeterministicReactorThreads.<locals>.CFT.callFromThread.<locals>.<lambda>)Zdo)r(   r8   r7   r9   r1   r6   r*   ÚcallFromThreadZ   s    z7deterministicReactorThreads.<locals>.CFT.callFromThreadN)r,   r-   r.   r:   r)   r1   r)   r*   ÚCFTY   s   r;   )r   )r4   r;   r)   r1   r*   ÚdeterministicReactorThreadsO   s    
r<   c                   @   s4   e Zd ZdZdd„ Zddd„Zeeedfdd	„Z	d
S )ÚFakeAddrInfoGetterz/
    Test object implementing getaddrinfo.
    c                 C   s   g | _ ttƒ| _dS )z1
        Create a L{FakeAddrInfoGetter}.
        N)Úcallsr   ÚlistÚresults©r(   r)   r)   r*   r+   e   s    zFakeAddrInfoGetter.__init__r   c                 C   s8   | j  ||||||f¡ | j| }|r*|S ttdƒ‚dS )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 knownN)r>   Úappendr@   r
   r   )r(   ÚhostÚportÚfamilyÚsocktypeÚprotoÚflagsr@   r)   r)   r*   r   l   s
    
zFakeAddrInfoGetter.getaddrinfor3   c                 C   s   | j |  |||||f¡ dS )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)r@   rB   )r(   rC   ZsockaddrrE   rF   rG   Ú	canonnamer)   r)   r*   ÚaddResultForHost…   s    $z#FakeAddrInfoGetter.addResultForHostN)r   r   r   r   )
r,   r-   r.   r/   r+   r   r   r	   r   rJ   r)   r)   r)   r*   r=   `   s   
ùr=   c                   @   s8   e Zd ZdZdZdZdd„ Zdd„ Zdd„ Zd	d
„ Z	dS )ÚResultHolderzI
    A resolution receiver which holds onto the results it received.
    Fc                 C   s
   || _ dS )z>
        Create a L{ResultHolder} with a L{UnitTest}.
        N)Z	_testCase)r(   ZtestCaser)   r)   r*   r+   µ   s    zResultHolder.__init__c                 C   s   d| _ || _g | _dS )zg
        Hostname resolution began.

        @param hostResolution: see L{IResolutionReceiver}
        TN)Ú_startedÚ_resolutionÚ
_addresses)r(   ZhostResolutionr)   r)   r*   ÚresolutionBegan»   s    zResultHolder.resolutionBeganc                 C   s   | j  |¡ dS )z^
        An address was resolved.

        @param address: see L{IResolutionReceiver}
        N)rN   rB   )r(   Úaddressr)   r)   r*   ÚaddressResolvedÅ   s    zResultHolder.addressResolvedc                 C   s
   d| _ dS )z2
        Hostname resolution is complete.
        TN)Ú_endedrA   r)   r)   r*   ÚresolutionCompleteÍ   s    zResultHolder.resolutionCompleteN)
r,   r-   r.   r/   rL   rR   r+   rO   rQ   rS   r)   r)   r)   r*   rK   ¬   s   
rK   c                   @   s   e Zd ZdZdd„ ZdS )ÚHelperTestsz?
    Tests for error cases of helpers used in this module.
    c                 C   sD   t ƒ \| _| _dd„ }| j |¡ |  ¡  |  t|  t¡ƒd¡ dS )zq
        L{DeterministicThreadPool} will log any exceptions that its "thread"
        workers encounter.
        c                   S   s   dd S )Nr#   r   r)   r)   r)   r)   r*   ÚdivideByZeroà   s    z9HelperTests.test_logErrorsInThreads.<locals>.divideByZeror#   N)r5   ÚpoolÚdoThreadWorkZcallInThreadÚassertEqualÚlenÚflushLoggedErrorsÚZeroDivisionError)r(   rU   r)   r)   r*   Útest_logErrorsInThreadsÙ   s
    z#HelperTests.test_logErrorsInThreadsN)r,   r-   r.   r/   r\   r)   r)   r)   r*   rT   Ô   s   rT   c                   @   s`   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ ZdS )ÚHostnameResolutionTestsz(
    Tests for hostname resolution.
    c                    sD   t ƒ \ˆ _ˆ _tƒ \ˆ _ˆ _tƒ ˆ _tˆ j‡ fdd„ˆ jj	ƒˆ _
dS )z*
        Set up a L{GAIResolver}.
        c                      s   ˆ j S r0   ©rV   r)   rA   r)   r*   r2   õ   r3   z/HostnameResolutionTests.setUp.<locals>.<lambda>N)r5   rV   rW   r<   ÚreactorÚdoReactorWorkr=   Úgetterr   r   ÚresolverrA   r)   rA   r*   ÚsetUpí   s     
 ÿzHostnameResolutionTests.setUpc                 C   sˆ   t | ƒ}| j dd¡ | j |d¡}|  |j|¡ |  |jd¡ |  |j	d¡ |  
¡  |  ¡  |  |j	d¡ |  |jtdddƒg¡ dS )	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ÚTCPre   r   N)rK   ra   rJ   rb   ÚresolveHostNameÚassertIsrM   rX   rL   rR   rW   r`   rN   r   ©r(   ÚreceiverÚ
resolutionr)   r)   r*   Útest_resolveOneHostø   s    z+HostnameResolutionTests.test_resolveOneHostc              	   C   s    t | ƒ}d}d}| jjddd||ftd� | j |d¡}|  |j|¡ |  |j	d¡ |  |j
d¡ |  ¡  |  ¡  |  |j
d¡ |  |jtd	dd||ƒg¡ d
S )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#   é   rd   ú::1r   )rE   TFrf   N)rK   ra   rJ   r   rb   rg   rh   rM   rX   rL   rR   rW   r`   rN   r   )r(   rj   ÚflowInfoÚscopeIDrk   r)   r)   r*   Útest_resolveOneIPv6Host	  s&     
 ÿ ÿz/HostnameResolutionTests.test_resolveOneIPv6Hostc                 C   sb   t | ƒ}| j |d¡}|  |j|¡ |  ¡  |  ¡  |  |jd¡ |  |j	d¡ |  |j
g ¡ dS )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.
        rd   TN)rK   rb   rg   rh   rM   rW   r`   rX   rL   rR   rN   ri   r)   r)   r*   Útest_gaierror!  s    z%HostnameResolutionTests.test_gaierrorc                 C   s`   t | ƒ}| jj|d|d�}|  |j|¡ |  ¡  |  ¡  | jjd \}}}}}	}
|  	||¡ dS )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
        rd   )ZaddressTypesr   N)
rK   rb   rg   rh   rM   rW   r`   ra   r>   rX   )r(   Z	addrTypesZ
expectedAFrj   rk   rC   rD   rE   rF   rG   rH   r)   r)   r*   Ú_resolveOnlyTest1  s    	  ÿz(HostnameResolutionTests._resolveOnlyTestc                 C   s   |   tgt¡ dS )z™
        When passed an C{addressTypes} parameter containing only
        L{IPv4Address}, L{GAIResolver} will pass C{AF_INET} to C{getaddrinfo}.
        N)rs   r   r   rA   r)   r)   r*   Útest_resolveOnlyIPv4D  s    z,HostnameResolutionTests.test_resolveOnlyIPv4c                 C   s   |   tgt¡ dS )zš
        When passed an C{addressTypes} parameter containing only
        L{IPv6Address}, L{GAIResolver} will pass C{AF_INET6} to C{getaddrinfo}.
        N)rs   r   r   rA   r)   r)   r*   Útest_resolveOnlyIPv6K  s    z,HostnameResolutionTests.test_resolveOnlyIPv6c                 C   s    |   ttgt¡ |   dt¡ dS )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)rs   r   r   r   rA   r)   r)   r*   Útest_resolveBothR  s    z(HostnameResolutionTests.test_resolveBothc           
      C   s    t | ƒ}| jj|ddd� t | ƒ}| jj|ddd� |  ¡  |  ¡  |  ¡  |  ¡  | jjd \}}}}}}| jjd \}}}}	}}|  |t¡ |  |	t	¡ dS )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.comrf   )ZtransportSemanticsÚUDPr   r#   N)
rK   rb   rg   rW   r`   ra   r>   rX   r	   r   )
r(   rj   Z	receiver2rC   rD   rE   Z	socktypeTrG   rH   Z	socktypeUr)   r)   r*   Ú#test_transportSemanticsToSocketType[  s       ÿz;HostnameResolutionTests.test_transportSemanticsToSocketTypec           	      C   s¶   t | ƒ}d}d}ttfD ]4}| jjddd||ft|d� | jjddt|d� q| j |d¡ |  	¡  |  
¡  |j\}}}}|  |jd¡ |  |jd¡ |  |jd	¡ |  |jd	¡ d
S )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#   rm   rw   rn   r   )rE   rF   )z	127.0.0.3r   rf   rx   N)rK   r	   r   ra   rJ   r   r   rb   rg   rW   r`   rN   rX   Útype)	r(   rj   ro   rp   rF   Zstream4Zstream6Zdgram4Zdgram6r)   r)   r*   Útest_socketTypeToAddressTypep  s0    
ü   ÿz4HostnameResolutionTests.test_socketTypeToAddressTypeN)r,   r-   r.   r/   rc   rl   rq   rr   rs   rt   ru   rv   ry   r{   r)   r)   r)   r*   r]   è   s   	r]   c                   @   s"   e Zd ZdZdd„ Zddd„ZdS )	ÚSillyResolverSimplez6
    Trivial implementation of L{IResolverSimple}
    c                 C   s
   g | _ dS )zd
        Create a L{SillyResolverSimple} with a queue of requests it is working
        on.
        N)Ú	_requestsrA   r)   r)   r*   r+   “  s    zSillyResolverSimple.__init__r)   c                 C   s   | 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}   rB   r   )r(   r&   Útimeoutr)   r)   r*   ÚgetHostByNameš  s    
z!SillyResolverSimple.getHostByNameN)r)   )r,   r-   r.   r/   r+   r€   r)   r)   r)   r*   r|   �  s   r|   c                   @   s8   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ ZdS )Ú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                 C   s”   t ƒ }t|ƒ}t| ƒ}|  |jd¡ | |d¡ |  |jd¡ |  |jd¡ |  |jg ¡ |jd  	d¡ |  |jt
dddƒg¡ |  |jd¡ dS )z‚
        L{SimpleResolverComplexifier} translates C{resolveHostName} into
        L{IResolutionReceiver.addressResolved}.
        Frw   Tr   ú192.168.1.1rf   N)r|   r   rK   rX   rL   rg   rR   rN   r}   Úcallbackr   ©r(   ÚsimpleÚcomplexrj   r)   r)   r*   Útest_success¯  s    z%LegacyCompatibilityTests.test_successc                 C   sŽ   t ƒ }t|ƒ}t| ƒ}|  |jd¡ | |d¡ |  |jd¡ |  |jd¡ |  |jg ¡ |jd  	t
dƒ¡ |  |jd¡ |  |jg ¡ dS )z•
        L{SimpleResolverComplexifier} translates a known error result from
        L{IResolverSimple.resolveHostName} into an empty result.
        Frw   Tr   ZnopeN)r|   r   rK   rX   rL   rg   rR   rN   r}   Úerrbackr   r„   r)   r)   r*   Útest_failureÀ  s    z%LegacyCompatibilityTests.test_failurec                 C   s¤   t ƒ }t|ƒ}t| ƒ}|  |jd¡ | |d¡ |  |jd¡ |  |jd¡ |  |jg ¡ |jd  	t
dƒ¡ |  t|  t
¡ƒd¡ |  |jd¡ |  |jg ¡ dS )z³
        L{SimpleResolverComplexifier} translates an unknown error result from
        L{IResolverSimple.resolveHostName} into an empty result and a logged
        error.
        Frw   Tr   Zzowr#   N)r|   r   rK   rX   rL   rg   rR   rN   r}   rˆ   r[   rY   rZ   r„   r)   r)   r*   Ú
test_errorÑ  s    z#LegacyCompatibilityTests.test_errorc                    s¶   t ƒ \ˆ _ˆ _tƒ \ˆ _ˆ _tƒ ˆ _tˆ j‡ fdd„ˆ jj	ƒˆ _
tˆ j
ƒ}ˆ j dd¡ | d¡}| d¡}ˆ  ¡  ˆ  ¡  ˆ  ¡  ˆ  ¡  ˆ  ˆ  |¡jt¡ ˆ  ˆ  |¡d¡ dS )zÂ
        L{ComplexResolverSimplifier} translates an L{IHostnameResolver} into an
        L{IResolverSimple} for applications that still expect the old
        interfaces to be in place.
        c                      s   ˆ j S r0   r^   r)   rA   r)   r*   r2   î  r3   z:LegacyCompatibilityTests.test_simplifier.<locals>.<lambda>rw   )ú192.168.3.4éá  znx.example.comr‹   N)r5   rV   rW   r<   r_   r`   r=   ra   r   r   rb   r   rJ   r€   rX   ZfailureResultOfrz   r   ZsuccessResultOf)r(   ZsimpleResolverÚsuccessZfailurer)   rA   r*   Útest_simplifierä  s$     
 ÿ


z(LegacyCompatibilityTests.test_simplifierc                 C   sˆ   t ƒ }t|ƒ}t| ƒ}| |dd¡ |  |jd¡ |  |jd¡ |  |jg ¡ |jd  	d¡ |  |jt
dddƒg¡ |  |jd¡ dS )	zŽ
        L{SimpleResolverComplexifier} preserves the C{port} argument passed to
        C{resolveHostName} in its returned addresses.
        rw   rŒ   TFr   r‚   rf   N)r|   r   rK   rg   rX   rL   rR   rN   r}   rƒ   r   r„   r)   r)   r*   Útest_portNumberû  s    z(LegacyCompatibilityTests.test_portNumberN)	r,   r-   r.   r/   r‡   r‰   rŠ   rŽ   r�   r)   r)   r)   r*   r�   ¨  s   r�   c                   @   s   e Zd ZdZdd„ ZdS )ÚJustEnoughReactorzT
    Just enough subclass implementation to be a valid L{ReactorBase} subclass.
    c                 C   s   dS )z
        Do nothing.
        Nr)   rA   r)   r)   r*   ÚinstallWaker  s    zJustEnoughReactor.installWakerN)r,   r-   r.   r/   r‘   r)   r)   r)   r*   r�     s   r�   c                   @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	Ú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                 C   s,   t ƒ }tt|ƒ tt|jƒ tt|jƒ dS )zš
        L{PluggableResolverMixin} (and its subclasses) implement both
        L{IReactorPluggableNameResolver} and L{IReactorPluggableResolver}.
        N)r   r   r   r   rb   r   ÚnameResolver©r(   r_   r)   r)   r*   Útest_interfaceCompliance  s    
z1ReactorInstallationTests.test_interfaceCompliancec                 C   s>   t ƒ }tƒ }tt| |¡ƒ |  |jt¡ |  |jj	|¡ dS )zf
        L{PluggableResolverMixin} will wrap an L{IResolverSimple} in a
        complexifier.
        N)
r   r|   r   r   ZinstallResolverÚassertIsInstancer“   r   rh   Z_simpleResolver)r(   r_   Úitr)   r)   r*   Útest_installingOldStyleResolver(  s
    z8ReactorInstallationTests.test_installingOldStyleResolverc                 C   sX   t ƒ }|  |jt¡ |  |jjt¡ |  |jt¡ |  |jj	|¡ |  |jj
|j¡ dS )zD
        L{ReactorBase} defaults to using a L{GAIResolver}.
        N)r�   r–   r“   r   rh   Z_getaddrinfor   rb   r   Z_reactorZ_nameResolverr”   r)   r)   r*   Útest_defaultToGAIResolver3  s    z2ReactorInstallationTests.test_defaultToGAIResolverN)r,   r-   r.   r/   r•   r˜   r™   r)   r)   r)   r*   r’     s   
r’   N);r/   Úcollectionsr   Úsocketr   r   r   r   r   r   r	   r
   r   Ú	threadingr   r   Zzope.interfacer   Zzope.interface.verifyr   Ztwisted._threadsr   r   r   Ztwisted.internet._resolverr   r   r   Ztwisted.internet.addressr   r   Ztwisted.internet.baser   r   Ztwisted.internet.deferr   Ztwisted.internet.errorr   Ztwisted.internet.interfacesr   r   r   r   Ztwisted.python.threadpoolr    Ztwisted.trial.unittestr!   ZUnitTestr"   r5   r<   r=   rK   rT   r]   r|   r�   r�   r’   r)   r)   r)   r*   Ú<module>   s8   ,L' &d