o
    ¯bš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                   @   ó   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ÚthreadsÚ_team)ÚselfÚteam© r,   úE/usr/lib/python3/dist-packages/twisted/internet/test/test_resolver.pyÚ__init__4   s
   
z DeterministicThreadPool.__init__N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r.   r,   r,   r,   r-   r#   /   ó    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,   ©Úworkerr,   r-   Ú<lambda>I   ó    z#deterministicPool.<locals>.<lambda>c                   S   s   d S r4   r,   r,   r,   r,   r-   r7   I   r8   )r   r#   r   r   r   r   )Údoerr,   r5   r-   ÚdeterministicPool?   s   
 ÿür:   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   ˆˆ i ˆ¤ŽS r4   r,   r,   ©ÚaÚfÚkr,   r-   r7   [   s    zIdeterministicReactorThreads.<locals>.CFT.callFromThread.<locals>.<lambda>)Údo)r*   r=   r<   r>   r5   r;   r-   ÚcallFromThreadZ   s   z7deterministicReactorThreads.<locals>.CFT.callFromThreadN)r/   r0   r1   r@   r,   r5   r,   r-   ÚCFTY   s    rA   )r   )r9   rA   r,   r5   r-   ÚdeterministicReactorThreadsO   s   

rB   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   s4   | 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)rD   ÚappendrF   r
   r   )r*   ÚhostÚportÚfamilyÚsocktypeÚprotoÚflagsrF   r,   r,   r-   r   l   s
   

zFakeAddrInfoGetter.getaddrinfoó    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)rF   rH   )r*   rI   ÚsockaddrrK   rL   rM   Ú	canonnamer,   r,   r-   ÚaddResultForHost…   s   $z#FakeAddrInfoGetter.addResultForHostN)r   r   r   r   )
r/   r0   r1   r2   r.   r   r   r	   r   rR   r,   r,   r,   r-   rC   `   s    
ùrC   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)Ú	_testCase)r*   ÚtestCaser,   r,   r-   r.   µ   ó   
zResultHolder.__init__c                 C   s   d| _ || _g | _dS )zg
        Hostname resolution began.

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

        @param address: see L{IResolutionReceiver}
        N)rY   rH   )r*   Úaddressr,   r,   r-   ÚaddressResolvedÅ   s   zResultHolder.addressResolvedc                 C   s
   d| _ dS )z2
        Hostname resolution is complete.
        TN)Ú_endedrG   r,   r,   r-   ÚresolutionCompleteÍ   rV   zResultHolder.resolutionCompleteN)
r/   r0   r1   r2   rW   r^   r.   r[   r]   r_   r,   r,   r,   r-   rS   ¬   s    
rS   c                   @   r"   )Ú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)r:   ÚpoolÚdoThreadWorkÚcallInThreadÚassertEqualÚlenÚflushLoggedErrorsÚZeroDivisionError)r*   ra   r,   r,   r-   Útest_logErrorsInThreadsÙ   s
   z#HelperTests.test_logErrorsInThreadsN)r/   r0   r1   r2   ri   r,   r,   r,   r-   r`   Ô   r3   r`   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                      ó   ˆ j S r4   ©rb   r,   rG   r,   r-   r7   õ   ó    z/HostnameResolutionTests.setUp.<locals>.<lambda>N)r:   rb   rc   rB   ÚreactorÚdoReactorWorkrC   Úgetterr   r   ÚresolverrG   r,   rG   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ÚTCPrt   r   N)rS   rp   rR   rq   ÚresolveHostNameÚassertIsrX   re   rW   r^   rc   ro   rY   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$   é   rs   ú::1r   )rK   TFru   N)rS   rp   rR   r   rq   rv   rw   rX   re   rW   r^   rc   ro   rY   r   )r*   ry   ÚflowInfoÚscopeIDrz   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.
        rs   TN)rS   rq   rv   rw   rX   rc   ro   re   rW   r^   rY   rx   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
        rs   )ÚaddressTypesr   N)
rS   rq   rv   rw   rX   rc   ro   rp   rD   re   )r*   Ú	addrTypesÚ
expectedAFry   rz   rI   rJ   rK   rL   rM   rN   r,   r,   r-   Ú_resolveOnlyTest1  s   	ÿz(HostnameResolutionTests._resolveOnlyTestc                 C   ó   |   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)r…   r   r   rG   r,   r,   r-   Útest_resolveOnlyIPv4D  ó   z,HostnameResolutionTests.test_resolveOnlyIPv4c                 C   r†   )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   rG   r,   r,   r-   Útest_resolveOnlyIPv6K  rˆ   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)r…   r   r   r   rG   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.comru   )ÚtransportSemanticsÚUDPr   r$   N)
rS   rq   rv   rc   ro   rp   rD   re   r	   r   )
r*   ry   Ú	receiver2rI   rJ   rK   Ú	socktypeTrM   rN   Ú	socktypeUr,   r,   r-   Ú#test_transportSemanticsToSocketType[  s   ÿz;HostnameResolutionTests.test_transportSemanticsToSocketTypec           	      C   s¶   t | ƒ}d}d}ttfD ]}| 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$   r|   r‹   r}   r   )rK   rL   )z	127.0.0.3r   ru   r�   N)rS   r	   r   rp   rR   r   r   rq   rv   rc   ro   rY   re   Útype)	r*   ry   r~   r   rL   Ústream4Ústream6Údgram4Údgram6r,   r,   r-   Útest_socketTypeToAddressTypep  s*   
üÿz4HostnameResolutionTests.test_socketTypeToAddressTypeN)r/   r0   r1   r2   rr   r{   r€   r�   r…   r‡   r‰   rŠ   r‘   r—   r,   r,   r,   r-   rj   è   s    	rj   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)Ú	_requestsrG   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™   rH   r   )r*   r'   Útimeoutr,   r,   r-   ÚgetHostByNameš  s   

z!SillyResolverSimple.getHostByNameN)r,   )r/   r0   r1   r2   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}.
        Fr‹   Tr   ú192.168.1.1ru   N)r˜   r   rS   re   rW   rv   r^   rY   r™   Úcallbackr   ©r*   ÚsimpleÚcomplexry   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.
        Fr‹   Tr   ÚnopeN)r˜   r   rS   re   rW   rv   r^   rY   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.
        Fr‹   Tr   Úzowr$   N)r˜   r   rS   re   rW   rv   r^   rY   r™   r¥   rh   rf   rg   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                      rk   r4   rl   r,   rG   r,   r-   r7   î  rm   z:LegacyCompatibilityTests.test_simplifier.<locals>.<lambda>r‹   )ú192.168.3.4éá  znx.example.comr©   N)r:   rb   rc   rB   rn   ro   rC   rp   r   r   rq   r   rR   rœ   re   ÚfailureResultOfr’   r   ÚsuccessResultOf)r*   ÚsimpleResolverÚsuccessÚfailurer,   rG   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.
        r‹   rª   TFr   rž   ru   N)r˜   r   rS   rv   re   rW   r^   rY   r™   rŸ   r   r    r,   r,   r-   Útest_portNumberû  s   z(LegacyCompatibilityTests.test_portNumberN)	r/   r0   r1   r2   r£   r¦   r¨   r°   r±   r,   r,   r,   r-   r�   ¨  s    r�   c                   @   r"   )ÚJustEnoughReactorzT
    Just enough subclass implementation to be a valid L{ReactorBase} subclass.
    c                 C   s   dS )z
        Do nothing.
        Nr,   rG   r,   r,   r-   ÚinstallWaker  r8   zJustEnoughReactor.installWakerN)r/   r0   r1   r2   r³   r,   r,   r,   r-   r²     r3   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   rq   r   ÚnameResolver©r*   rn   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   ÚinstallResolverÚassertIsInstancerµ   r   rw   Ú_simpleResolver)r*   rn   Ú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   rw   Ú_getaddrinfor   rq   r   Ú_reactorÚ_nameResolverr¶   r,   r,   r-   Útest_defaultToGAIResolver3  s   z2ReactorInstallationTests.test_defaultToGAIResolverN)r/   r0   r1   r2   r·   r¼   rÀ   r,   r,   r,   r-   r´     s
    
r´   N);r2   Ú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:   rB   rC   rS   r`   rj   r˜   r�   r²   r´   r,   r,   r,   r-   Ú<module>   s:   ,L' &d