U
    
W[ON                     @   s  d Z ddlmZmZ e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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) ddl*m+Z+m,Z,m-Z- ddl.m/Z/ ddl0m1Z1 ddl2m3Z3 G dd de"e4Z5dd Z6dd Z7G dd de4Z8eeG dd de4Z9G dd de Z:G dd de Z;eeG dd  d e4Z<G d!d" d"e e4Z=G d#d$ d$e3e4Z>G d%d& d&e e4Z?d'S )(zh
Tests for implementations of L{IHostnameResolver} and their interactions with
reactor implementations.
    )divisionabsolute_import)defaultdict)	getaddrinfogaierror
EAI_NONAMEAF_INETAF_INET6	AF_UNSPECSOCK_STREAM
SOCK_DGRAMIPPROTO_TCP)localLock)implementer)verifyObject)IResolutionReceiverIResolverSimpleIReactorPluggableNameResolverIHostnameResolver)SynchronousTestCase)
ThreadPool)createMemoryWorkerTeam
LockWorker)IPv4AddressIPv6Address)GAIResolverSimpleResolverComplexifierComplexResolverSimplifier)Deferred)DNSLookupError)ReactorBasec                   @   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nameZthreadsZ_team)selfZteam r)   E/usr/lib/python3/dist-packages/twisted/internet/test/test_resolver.py__init__2   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>H       z#deterministicPool.<locals>.<lambda>c                   S   s   d S r0   r)   r)   r)   r)   r*   r2   H   r3   )r   r#   r   r   r   r   )doerr)   r1   r*   deterministicPool>   s    

 r5   c                     s(   t  \ } G  fdddt}| | 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   Y   r3   zIdeterministicReactorThreads.<locals>.CFT.callFromThread.<locals>.<lambda>)Zdo)r(   r8   r7   r9   r1   r6   r*   callFromThreadX   s    z7deterministicReactorThreads.<locals>.CFT.callFromThreadN)r,   r-   r.   r:   r)   r1   r)   r*   CFTW   s   r;   )r   object)r4   r;   r)   r1   r*   deterministicReactorThreadsN   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+   c   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?   appendrA   r   r   )r(   hostportfamilysocktypeprotoflagsrA   r)   r)   r*   r   k   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)rA   rC   )r(   rD   ZsockaddrrF   rG   rH   Z	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   rC   )r(   Zaddressr)   r)   r*   addressResolved   s    zResultHolder.addressResolvedc                 C   s
   d| _ dS )z2
        Hostname resolution is complete.
        TN)_endedrB   r)   r)   r*   resolutionComplete   s    zResultHolder.resolutionCompleteN)
r,   r-   r.   r/   rL   rQ   r+   rO   rP   rR   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(   rT   r)   r)   r*   test_logErrorsInThreads   s
    z#HelperTests.test_logErrorsInThreadsN)r,   r-   r.   r/   r[   r)   r)   r)   r*   rS      s   rS   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   rU   r)   rB   r)   r*   r2      r3   z/HostnameResolutionTests.setUp.<locals>.<lambda>N)r5   rU   rV   r=   reactordoReactorWorkr>   getterr   r   resolverrB   r)   rB   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TCPrd   r   N)rK   r`   rJ   ra   resolveHostNameassertIsrM   rW   rL   rQ   rV   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$      rc   ::1r   )rF   TFre   N)rK   r`   rJ   r	   ra   rf   rg   rM   rW   rL   rQ   rV   r_   rN   r   )r(   ri   flowInfoscopeIDrj   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.
        rc   TN)rK   ra   rf   rg   rM   rV   r_   rW   rL   rQ   rN   rh   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
        rc   )ZaddressTypesr   N)
rK   ra   rf   rg   rM   rV   r_   r`   r?   rW   )r(   Z	addrTypesZ
expectedAFri   rj   rD   rE   rF   rG   rH   rI   r)   r)   r*   _resolveOnlyTest7  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)rr   r   r   rB   r)   r)   r*   test_resolveOnlyIPv4K  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)rr   r   r	   rB   r)   r)   r*   test_resolveOnlyIPv6S  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)rr   r   r   r
   rB   r)   r)   r*   test_resolveBoth[  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.comre   )ZtransportSemanticsUDPr   r$   N)
rK   ra   rf   rV   r_   r`   r?   rW   r   r   )
r(   ri   Z	receiver2rD   rE   rF   Z	socktypeTrH   rI   Z	socktypeUr)   r)   r*   #test_transportSemanticsToSocketTypee  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$   rl   rv   rm   r   )rF   rG   )z	127.0.0.3r   re   rw   N)rK   r   r   r`   rJ   r	   r   ra   rf   rV   r_   rN   rW   type)	r(   ri   rn   ro   rG   Zstream4Zstream6Zdgram4Zdgram6r)   r)   r*   test_socketTypeToAddressType{  s0     
   z4HostnameResolutionTests.test_socketTypeToAddressTypeN)r,   r-   r.   r/   rb   rk   rp   rq   rr   rs   rt   ru   rx   rz   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)	_requestsrB   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|   rC   r    )r(   r'   Z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}.
        Frv   Tr   192.168.1.1re   N)r{   r   rK   rW   rL   rf   rQ   rN   r|   callbackr   r(   Zsimplecomplexri   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.
        Frv   Tr   ZnopeN)r{   r   rK   rW   rL   rf   rQ   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.
        Frv   Tr   Zzowr$   N)r{   r   rK   rW   rL   rf   rQ   rN   r|   r   rZ   rX   rY   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)   rB   r)   r*   r2     r3   z:LegacyCompatibilityTests.test_simplifier.<locals>.<lambda>rv   )192.168.3.4  znx.example.comr   N)r5   rU   rV   r=   r^   r_   r>   r`   r   r   ra   r   rJ   r~   rW   ZfailureResultOfry   r!   ZsuccessResultOf)r(   ZsimpleResolverZsuccessZfailurer)   rB   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.
        rv   r   TFr   r   re   N)r{   r   rK   rf   rW   rL   rQ   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)   rB   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{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{ReactorBase} (and its subclasses) provide both
        L{IReactorPluggableNameResolver} and L{IReactorPluggableResolver}.
        N)r   r   r   r   ra   r   nameResolverr(   r^   r)   r)   r*   test_interfaceCompliance.  s    
z1ReactorInstallationTests.test_interfaceCompliancec                 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   assertIsInstancer   r   rg   Z_getaddrinfor   ra   r   Z_reactorZ_nameResolverr   r)   r)   r*   test_defaultToGAIResolver9  s    z2ReactorInstallationTests.test_defaultToGAIResolverc                 C   s>   t  }t }tt|| | |jt | |jj	| dS )zS
        L{ReactorBase} will wrap an L{IResolverSimple} in a complexifier.
        N)
r   r{   r   r   ZinstallResolverr   r   r   rg   Z_simpleResolver)r(   r^   itr)   r)   r*   test_installingOldStyleResolverE  s
    z8ReactorInstallationTests.test_installingOldStyleResolverN)r,   r-   r.   r/   r   r   r   r)   r)   r)   r*   r   (  s   r   N)@r/   Z
__future__r   r   ry   Z__metaclass__collectionsr   Zsocketr   r   r   r   r	   r
   r   r   r   Z	threadingr   r   Zzope.interfacer   Zzope.interface.verifyr   Ztwisted.internet.interfacesr   r   r   r   Ztwisted.trial.unittestr   ZUnitTestZtwisted.python.threadpoolr   Ztwisted._threadsr   r   r   Ztwisted.internet.addressr   r   Ztwisted.internet._resolverr   r   r   Ztwisted.internet.deferr    Ztwisted.internet.errorr!   Ztwisted.internet.baser"   r<   r#   r5   r=   r>   rK   rS   r\   r{   r   r   r   r)   r)   r)   r*   <module>   s<   ,L* 1i