o
    b                     @   s  d Z ddlZddl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 dd	lmZmZmZmZmZ dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZ ddl m!Z! ddl"m#Z# ddl$m%Z% ddl&m'Z' e#( sydZ)ndZ)G dd deZ*G dd dZ+G dd dZ,G dd de'j-Z.G dd de'j-eZ/G dd de'j-Z0G d d! d!e'j-Z1G d"d# d#e'j-Z2G d$d% d%Z3G d&d' d'e'j-Z4G d(d) d)e'j-Z5dS )*z)
Test cases for L{twisted.names.client}.
    N)verifyClassverifyObject)defer)CannotListenErrorConnectionRefusedError)	IResolver)Clock)AlternateReactor)cacheclientdnserrorhosts)ResolverBase)DNSQueryTimeoutError)	test_util)GoodTempPathMixin)failure)FilePath)platform)proto_helpers)unittestz:These tests need more work before they'll work on Windows.c                   @   s   e Zd Zdd ZdS )FakeResolverc           	   	   C   sZ   |dkrt j|t j|dt jdddd}n	t j|||dd}|g}g }g }t|||fS )z
        The getHostByNameTest does a different type of query that requires it
        return an A record from an ALL_RECORDS lookup, so we accommodate that
        here.
           getHostByNameTest<   	127.0.0.1)addressttl)nametypeclsr   payload)r   r   r    r   )r   RRHeaderARecord_Ar   succeed)	selfr   r    qtypetimeoutrrresults	authority
additional r-   @/usr/lib/python3/dist-packages/twisted/names/test/test_client.py_lookup$   s   zFakeResolver._lookupN)__name__
__module____qualname__r/   r-   r-   r-   r.   r   #   s    r   c                   @   s   e Zd ZdZdZdd ZdS )StubPortz
    A partial implementation of L{IListeningPort} which only keeps track of
    whether it has been stopped.

    @ivar disconnected: A C{bool} which is C{False} until C{stopListening} is
        called, C{True} afterwards.
    Fc                 C   s
   d| _ d S )NT)disconnectedr&   r-   r-   r.   stopListeningF   s   
zStubPort.stopListeningN)r0   r1   r2   __doc__r4   r6   r-   r-   r-   r.   r3   ;   s    r3   c                   @   s"   e Zd ZdZdd ZdddZdS )	StubDNSDatagramProtocolz
    L{dns.DNSDatagramProtocol}-alike.

    @ivar queries: A C{list} of tuples giving the arguments passed to
        C{query} along with the L{defer.Deferred} which was returned from
        the call.
    c                 C      g | _ t | _d S Nqueriesr3   	transportr5   r-   r-   r.   __init__S      z StubDNSDatagramProtocol.__init__
   Nc                 C   s"   t  }| j|||||f |S )zv
        Record the given arguments and return a Deferred which will not be
        called back by this code.
        )r   Deferredr<   append)r&   r   r<   r(   idresultr-   r-   r.   queryW   s   zStubDNSDatagramProtocol.queryr@   N)r0   r1   r2   r7   r>   rE   r-   r-   r-   r.   r8   J   s    r8   c                   @   s$   e Zd ZdZeZdd Zdd ZdS )GetResolverTestsz*
    Tests for L{client.getResolver}.
    c                 C   sF   t t  t }W d   n1 sw   Y  | tt| dS )zQ
        L{client.getResolver} returns an object providing L{IResolver}.
        N)r	   r   r   getResolver
assertTruer   r   r&   resolverr-   r-   r.   test_interfaceh   s   
zGetResolverTests.test_interfacec                 C   sJ   t t  t }t }W d   n1 sw   Y  | || dS )zn
        Multiple calls to L{client.getResolver} return the same L{IResolver}
        implementation.
        N)r	   r   r   rH   assertIs)r&   abr-   r-   r.   test_idempotentp   s
   
z GetResolverTests.test_idempotentN)r0   r1   r2   r7   windowsSkipskiprL   rP   r-   r-   r-   r.   rG   a   s
    rG   c                   @   sd   e Zd ZdZe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 )CreateResolverTestsz-
    Tests for L{client.createResolver}.
    c                 C   s6   dd |j D }| dt| | |d j| d S )Nc                 S      g | ]
}t |tjr|qS r-   )
isinstancer   Resolver.0rr-   r-   r.   
<listcomp>       z2CreateResolverTests._hostsTest.<locals>.<listcomp>   r   )	resolversassertEquallenfiler&   rK   filenameresr-   r-   r.   
_hostsTest   s   zCreateResolverTests._hostsTestc                 C   B   t t  t }W d   n1 sw   Y  | |d dS )z
        L{client.createResolver} returns a L{resolve.ResolverChain} including a
        L{hosts.Resolver} using I{/etc/hosts} if no alternate hosts file is
        specified.
        Ns
   /etc/hostsr	   r   r   createResolverrd   rJ   r-   r-   r.   test_defaultHosts      
z%CreateResolverTests.test_defaultHostsc                 C   F   t t  tjdd}W d   n1 sw   Y  | |d dS )z
        The I{hosts} parameter to L{client.createResolver} overrides the hosts
        file used by the L{hosts.Resolver} in the L{resolve.ResolverChain} it
        returns.
           /foo/bar)r   Nrf   rJ   r-   r-   r.   test_overrideHosts      z&CreateResolverTests.test_overrideHostsc                 C   s6   dd |j D }| dt| | |d j| dS )z|
        Verify that C{resolver} has a L{client.Resolver} with a configuration
        filename set to C{filename}.
        c                 S   rT   r-   rU   r   rV   rW   r-   r-   r.   rZ      r[   z7CreateResolverTests._resolvConfTest.<locals>.<listcomp>r\   r   N)r]   r^   r_   resolvra   r-   r-   r.   _resolvConfTest   s   z#CreateResolverTests._resolvConfTestc                 C   sl   t  }t| t }W d   n1 sw   Y  dd |jD }| dt| | ||d j dS )z
        The L{client.Resolver} included in the L{resolve.ResolverChain} returned
        by L{client.createResolver} uses the global reactor.
        Nc                 S   rT   r-   rn   rW   r-   r-   r.   rZ      r[   z4CreateResolverTests.test_reactor.<locals>.<listcomp>r\   r   )	r   r	   r   rg   r]   r^   r_   rM   _reactor)r&   reactorrK   rc   r-   r-   r.   test_reactor   s   

z CreateResolverTests.test_reactorc                 C   re   )z
        L{client.createResolver} returns a L{resolve.ResolverChain} including a
        L{client.Resolver} using I{/etc/resolv.conf} if no alternate resolver
        configuration file is specified.
        Ns   /etc/resolv.confr	   r   r   rg   rp   rJ   r-   r-   r.   test_defaultResolvConf   ri   z*CreateResolverTests.test_defaultResolvConfc                 C   rj   )z
        The I{resolvconf} parameter to L{client.createResolver} overrides the
        resolver configuration file used by the L{client.Resolver} in the
        L{resolve.ResolverChain} it returns.
        rk   
resolvconfNrt   rJ   r-   r-   r.   test_overrideResolvConf   rm   z+CreateResolverTests.test_overrideResolvConfc                 C   s   |   }|d tt  tj|j d}W d   n1 s w   Y  dd |jD }| dt| | g |d j	 | dg|d j
 dS )	z
        If no servers are given, addresses are taken from the file given by the
        I{resolvconf} parameter to L{client.createResolver}.
           nameserver 127.1.2.3
rv   Nc                 S   rT   r-   rn   rW   r-   r-   r.   rZ      r[   z;CreateResolverTests.test_defaultServers.<locals>.<listcomp>r\   r   z	127.1.2.35   path
setContentr	   r   r   rg   r]   r^   r_   servers
dynServersr&   rw   rK   rc   r-   r-   r.   test_defaultServers   s   
z'CreateResolverTests.test_defaultServersc                 C   s   |   }|d tt  tjdg|j d}W d   n1 s"w   Y  dd |jD }| dt| | dg|d j	 | d	g|d j
 dS )
z
        Servers passed to L{client.createResolver} are used in addition to any
        found in the file given by the I{resolvconf} parameter.
        ry   )z	127.3.2.1r{   )r   rw   Nc                 S   rT   r-   rn   rW   r-   r-   r.   rZ      r[   z<CreateResolverTests.test_overrideServers.<locals>.<listcomp>r\   r   rz   r|   r   r-   r-   r.   test_overrideServers   s   
z(CreateResolverTests.test_overrideServersc                 C   sV   t t  t }W d   n1 sw   Y  dd |jD }| dt| dS )zy
        L{client.createResolver} returns a L{resolve.ResolverChain} including a
        L{cache.CacheResolver}.
        Nc                 S   rT   r-   )rU   r
   CacheResolverrW   r-   r-   r.   rZ      r[   z2CreateResolverTests.test_cache.<locals>.<listcomp>r\   )r	   r   r   rg   r]   r^   r_   )r&   rK   rc   r-   r-   r.   
test_cache   s
   
zCreateResolverTests.test_cacheN)r0   r1   r2   r7   rQ   rR   rd   rh   rl   rp   rs   ru   rx   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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,d- Zd.d/ Zd0d1 Zd2d3 Zd4d5 Zd6d7 Zd8d9 Zd:S );ResolverTestsz'
    Tests for L{client.Resolver}.
    c                 C   s   t tt dS )z]
        L{client} provides L{IResolver} through a series of free
        functions.
        N)r   r   r   r5   r-   r-   r.   test_clientProvidesIResolver   s   z*ResolverTests.test_clientProvidesIResolverc                 C   s   t ttj dS )z;
        L{client.Resolver} provides L{IResolver}.
        N)r   r   r   rV   r5   r-   r-   r.   $test_clientResolverProvidesIResolver      z2ResolverTests.test_clientResolverProvidesIResolverc                 C   s   |  ttj dS )z
        L{client.Resolver} raises L{ValueError} if constructed with neither
        servers nor a nameserver configuration file.
        N)assertRaises
ValueErrorr   rV   r5   r-   r-   r.   test_noServers   s   zResolverTests.test_noServersc                 C   s(   t j|  t d}| dg|j dS )z
        A missing nameserver configuration file results in no server information
        being loaded from it (ie, not an exception) and a default server being
        provided.
        ro   rr   r   r{   N)r   rV   mktempr   r^   r   rJ   r-   r-   r.   test_missingConfiguration  s   z'ResolverTests.test_missingConfigurationc                    sR   t |  }|jdd G  fdddtj}|ddgdt d |  j d	S )
z
        As part of its constructor, C{StubResolver} opens C{/etc/resolv.conf};
        then, explicitly closes it and does not count on the GC to do so for
        it.
        zw+)modec                          e Zd Z fddZdS )z9ResolverTests.test_closesResolvConf.<locals>.StubResolverc                        S r:   r-   )r&   r   
resolvConfr-   r.   	_openFile  s   zCResolverTests.test_closesResolvConf.<locals>.StubResolver._openFileN)r0   r1   r2   r   r-   r   r-   r.   StubResolver      r   example.comr{   z/etc/resolv.conf)r   ro   rr   N)r   r   openr   rV   r   rI   closed)r&   handler   r-   r   r.   test_closesResolvConf  s   z#ResolverTests.test_closesResolvConfc                 C   s,   t jdgd}|dg | d|j dS )z
        L{client.Resolver.parseConfig} treats a I{domain} line without an
        argument as indicating a domain of C{b""}.
        r   r   s   domain
    N)r   rV   parseConfigr^   domainrJ   r-   r-   r.   test_domainEmptyArgument!     z&ResolverTests.test_domainEmptyArgumentc                 C   s,   t jdgd}|dg | g |j dS )z
        L{client.Resolver.parseConfig} treats a I{search} line without an
        argument as indicating an empty search suffix.
        r   r   s   search
N)r   rV   r   r^   searchrJ   r-   r-   r.   test_searchEmptyArgument*  r   z&ResolverTests.test_searchEmptyArgumentc                    sd  t   ddg}ddg}tj|d}||_ fdd|_t }|d}|| j| | t	 j
d	 |  j
d
 d
 |d
   j
d
 d td
 | t	 j
d |  j
d	 d
 |d	   j
d	 d td	 | t	 j
d |  j
d d
 |d
   j
d d td | t	 j
d |  j
d d
 |d	   j
d d | |S )a  
        L{client.Resolver.queryUDP} should issue queries to its
        L{dns.DNSDatagramProtocol} with server addresses taken from its own
        C{servers} and C{dynServers} lists, proceeding through them in order
        as L{DNSQueryTimeoutError}s occur.
        z::1r{   )z::2r{   )z::3r{   )z::4r{   r   c                    r   r:   r-   )	interfaceprotocolr-   r.   <lambda>@      z=ResolverTests.test_datagramQueryServerOrder.<locals>.<lambda>Nr\   r            )r8   r   rV   r   _connectedProtocolobjectqueryUDPaddCallbackr^   r_   r<   rM   errbackr   callback)r&   r   r   rK   expectedResultqueryResultr-   r   r.   test_datagramQueryServerOrder3  s,   
z+ResolverTests.test_datagramQueryServerOrderc           	         s   t  tjdgd}fdd|_j}tdtjtj}|	|}
t|d |	|}
t|d t  t }|j  | d | t||g} fdd	}|| |S )
z
        L{client.Resolver.query} only issues one request at a time per query.
        Subsequent requests made before responses to prior ones are received
        are queued and given the same response as is given to the first one.
        r   r{   r   c                      r   r:   r-   r-   r   r-   r.   r   ]  r   z<ResolverTests.test_singleConcurrentRequest.<locals>.<lambda>   foo.example.comr\   r   c                    s4   | \}} | gg g f  | gg g f d S r:   r^   )	responsesfirstResponsesecondResponse)answerr&   r-   r.   
cbFinishedr  s   z>ResolverTests.test_singleConcurrentRequest.<locals>.cbFinished)r8   r   rV   r   r<   r   Queryr#   INrE   r^   r_   r   MessageanswersrB   popr   r   gatherResultsr   )	r&   rK   r<   rE   firstResultsecondResultresponsedr   r-   )r   r   r&   r.   test_singleConcurrentRequestU  s"   


z*ResolverTests.test_singleConcurrentRequestc                    s   t   tjdgd} fdd|_ j}tdtj}|| | 	t
|d tdtj}|| | 	t
|d tdtj}|| | 	t
|d	 d
S )zh
        L{client.Resolver.query} issues a request for each different concurrent
        query.
        r   r   c                      r   r:   r-   r-   r   r-   r.   r     r   z?ResolverTests.test_multipleConcurrentRequests.<locals>.<lambda>r   r\      bar.example.comr   r   N)r8   r   rV   r   r<   r   r   r#   rE   r^   r_   A6)r&   rK   r<   
firstQuerysecondQuery
thirdQueryr-   r   r.   test_multipleConcurrentRequestsz  s   


z-ResolverTests.test_multipleConcurrentRequestsc                    s   t   tjdgd} fdd|_ j}tdtj}|| | 	t
|d | d t  || | 	t
|d dS )	z
        After a response is received to a query issued with
        L{client.Resolver.query}, another query with the same parameters
        results in a new network request.
        r   r   c                      r   r:   r-   r-   r   r-   r.   r     r   z?ResolverTests.test_multipleSequentialRequests.<locals>.<lambda>r   r\   r   N)r8   r   rV   r   r<   r   r   r#   rE   r^   r_   r   r   r   )r&   rK   r<   rE   r-   r   r.   test_multipleSequentialRequests  s   

z-ResolverTests.test_multipleSequentialRequestsc                    s   t   tjdgd} fdd|_ j}tdtj}||}||}G dd dt	}|
 d t|  t| ||| ||gS )	z
        If the result of a request is an error response, the Deferreds for all
        concurrently issued requests associated with that result fire with the
        L{Failure}.
        r   r   c                      r   r:   r-   r-   r   r-   r.   r     r   z>ResolverTests.test_multipleConcurrentFailure.<locals>.<lambda>r   c                   @      e Zd ZdS )zGResolverTests.test_multipleConcurrentFailure.<locals>.ExpectedExceptionNr0   r1   r2   r-   r-   r-   r.   ExpectedException      r   r   )r8   r   rV   r   r<   r   r   r#   rE   	Exceptionr   r   r   Failurer   r   assertFailure)r&   rK   r<   rE   r   r   r   r-   r   r.   test_multipleConcurrentFailure  s   



z,ResolverTests.test_multipleConcurrentFailurec                 C   st   t jdgd}| }| }| |j | |j | |j j|j j t	t
|jjt
|jjgS )z
        L{client.Resolver._connectedProtocol} returns a new
        L{DNSDatagramProtocol} connected to a new address with a
        cryptographically secure random port number.
        r   r   )r   rV   r   assertIsNotNoner=   assertNotEqualgetHostportr   r   maybeDeferredr6   )r&   rK   
firstProtosecondProtor-   r-   r.   test_connectedProtocol  s   z$ResolverTests.test_connectedProtocolc                 C   s4   t  }tj|  |d}| }| |j| dS )z
        If a reactor instance is supplied to L{client.Resolver}
        L{client.Resolver._connectedProtocol} should pass that reactor
        to L{twisted.names.dns.DNSDatagramProtocol}.
        r   N)r   MemoryReactorr   rV   r   r   rM   rq   )r&   rr   rK   protor-   r-   r.   )test_resolverUsesOnlyParameterizedReactor  s   z7ResolverTests.test_resolverUsesOnlyParameterizedReactorc                    sb   t jdgd}g  G  fddd}||_|td |td | tt d dS )	z
        L{client.Resolver._connectedProtocol} is called once each time a UDP
        request needs to be issued and the resulting protocol instance is used
        for that request.
        r   r   c                       s"   e Zd Zdd Zd fdd	ZdS )z:ResolverTests.test_differentProtocol.<locals>.FakeProtocolc                 S      t  | _d S r:   r3   r=   r5   r-   r-   r.   r>        zCResolverTests.test_differentProtocol.<locals>.FakeProtocol.__init__r@   Nc                    s     |  tt S r:   )rB   r   r%   r   r   r&   r   rE   r(   rC   	protocolsr-   r.   rE     s   
z@ResolverTests.test_differentProtocol.<locals>.FakeProtocol.queryrF   r0   r1   r2   r>   rE   r-   r   r-   r.   FakeProtocol  s    r   r   r   r   N)	r   rV   r   rE   r   r   r^   r_   setr&   rK   r   r-   r   r.   test_differentProtocol  s   z$ResolverTests.test_differentProtocolc                 C   sR   t  }tjdg|d}|td |j \\}}|	 j
}| d| dS )z<
        If the resolver is ipv6, open a ipv6 port.
        r   r   rr   r   z::N)r   r   r   rV   rE   r   r   udpPortsitemsr   hostr^   )r&   fakerK   r   r=   r   r-   r-   r.   test_ipv6Resolver   s   
zResolverTests.test_ipv6Resolverc                    sL   g  G  fddd}t jdgd}| |_|  | tt d dS )z
        If a port number is initially selected which cannot be bound, the
        L{CannotListenError} is handled and another port number is attempted.
        c                       r   )z6ResolverTests.test_disallowedPort.<locals>.FakeReactorc                    s&     | t dkrtd |d d S )Nr\   )rB   r_   r   r&   r   argskwargsportsr-   r.   	listenUDP  s   
z@ResolverTests.test_disallowedPort.<locals>.FakeReactor.listenUDPNr0   r1   r2   r   r-   r   r-   r.   FakeReactor  r   r   r   r   r   N)r   rV   rq   r   r^   r_   r   r&   r   rK   r-   r   r.   test_disallowedPort  s   z!ResolverTests.test_disallowedPortc                    sN   g  G  fddd}t jdgd}| |_| t|j | t d dS )z
        If port numbers that cannot be bound are repeatedly selected,
        L{resolver._connectedProtocol} will give up eventually.
        c                       r   )z@ResolverTests.test_disallowedPortRepeatedly.<locals>.FakeReactorc                    s     | td |d r:   )rB   r   r   r   r-   r.   r   '  s   
zJResolverTests.test_disallowedPortRepeatedly.<locals>.FakeReactor.listenUDPNr   r-   r   r-   r.   r   &  r   r   r   r   i  N)r   rV   rq   r   r   r   r^   r_   r   r-   r   r.   test_disallowedPortRepeatedly  s   z+ResolverTests.test_disallowedPortRepeatedlyc                    s`   g  G  fddd}t jdgd}| |_| t|j}| |jjtj	 | t
 d dS )zf
        If the process is out of files, L{Resolver._connectedProtocol}
        will give up.
        c                       r   )z5ResolverTests.test_runOutOfFiles.<locals>.FakeReactorc                    s"     | ttjd}td ||)NzOut of files :()rB   OSErrorerrnoEMFILEr   )r&   r   r   r   errr   r-   r.   r   :  s   
z?ResolverTests.test_runOutOfFiles.<locals>.FakeReactor.listenUDPNr   r-   r   r-   r.   r   9  r   r   r   r   r\   N)r   rV   rq   r   r   r   r^   socketErrorr  r  r_   )r&   r   rK   excr-   r   r.   test_runOutOfFiles2  s   z ResolverTests.test_runOutOfFilesc                    sv   t jdgd}g  tttdtt	 gG  fddd}||_
|td | tt d dS )z|
        When a query issued by L{client.Resolver.query} times out, the retry
        uses a new protocol instance.
        r   r   Nc                       $   e Zd Zdd Zd fdd	ZdS )zFResolverTests.test_differentProtocolAfterTimeout.<locals>.FakeProtocolc                 S   r   r:   r   r5   r-   r-   r.   r>   U  r   zOResolverTests.test_differentProtocolAfterTimeout.<locals>.FakeProtocol.__init__r@   Nc                         |  dS Nr   rB   r   r   r   r*   r-   r.   rE   X     

zLResolverTests.test_differentProtocolAfterTimeout.<locals>.FakeProtocol.queryrF   r   r-   r  r-   r.   r   T      r   r   r   )r   rV   r   failr   r   r   r%   r   r   r   rE   r   r^   r_   r   r   r-   r  r.   "test_differentProtocolAfterTimeoutH  s   z0ResolverTests.test_differentProtocolAfterTimeoutc                    sz   t jdgd}g  t G  fddd}||_|td |  d j	j
 t  |  d j	j
 dS )z
        After the L{Deferred} returned by L{DNSDatagramProtocol.query} is
        called back, the L{DNSDatagramProtocol} is disconnected from its
        transport.
        r   r   c                       r	  )z9ResolverTests.test_protocolShutDown.<locals>.FakeProtocolc                 S   r   r:   r   r5   r-   r-   r.   r>   k  r   zBResolverTests.test_protocolShutDown.<locals>.FakeProtocol.__init__r@   Nc                         |  S r:   rB   r   r   rD   r-   r.   rE   n     
z?ResolverTests.test_protocolShutDown.<locals>.FakeProtocol.queryrF   r   r-   r  r-   r.   r   j  r  r   r   r   N)r   rV   r   rA   r   rE   r   r   assertFalser=   r4   r   r   rI   r   r-   r  r.   test_protocolShutDown`  s   z#ResolverTests.test_protocolShutDownc                    s   t jdgd}g  t }tttd|gG  fddd}||_|	t
d |  d jj |t
  |  d jj dS )z
        The L{DNSDatagramProtocol} created when an interim timeout occurs is
        also disconnected from its transport after the Deferred returned by its
        query method completes.
        r   r   Nc                       r	  )zEResolverTests.test_protocolShutDownAfterTimeout.<locals>.FakeProtocolc                 S   r   r:   r   r5   r-   r-   r.   r>     r   zNResolverTests.test_protocolShutDownAfterTimeout.<locals>.FakeProtocol.__init__r@   Nc                    r
  r  r  r   r  r-   r.   rE     r  zKResolverTests.test_protocolShutDownAfterTimeout.<locals>.FakeProtocol.queryrF   r   r-   r  r-   r.   r     r  r   r   r\   )r   rV   r   rA   r  r   r   r   r   rE   r   r   r  r=   r4   r   r   rI   )r&   rK   rD   r   r-   r  r.   !test_protocolShutDownAfterTimeouty  s   z/ResolverTests.test_protocolShutDownAfterTimeoutc                    s   G dd dt }tjdgd}g  t G  fddd}||_|td}| 	 d j
j t|  |  d j
j | ||S )	z
        If the L{Deferred} returned by L{DNSDatagramProtocol.query} fires with
        a failure, the L{DNSDatagramProtocol} is still disconnected from its
        transport.
        c                   @   r   )zJResolverTests.test_protocolShutDownAfterFailure.<locals>.ExpectedExceptionNr   r-   r-   r-   r.   r     r   r   r   r   c                       r	  )zEResolverTests.test_protocolShutDownAfterFailure.<locals>.FakeProtocolc                 S   r   r:   r   r5   r-   r-   r.   r>     r   zNResolverTests.test_protocolShutDownAfterFailure.<locals>.FakeProtocol.__init__r@   Nc                    r  r:   r  r   r  r-   r.   rE     r  zKResolverTests.test_protocolShutDownAfterFailure.<locals>.FakeProtocol.queryrF   r   r-   r  r-   r.   r     r  r   r   r   )r   r   rV   r   rA   r   rE   r   r   r  r=   r4   r   r   r   rI   r   )r&   r   rK   r   r   r-   r  r.   !test_protocolShutDownAfterFailure  s   z/ResolverTests.test_protocolShutDownAfterFailurec                 C   sN   t jdgd}|jd}|d | ||j |d | ||j dS )z
        When a TCP DNS protocol associated with a Resolver disconnects, it is
        removed from the Resolver's connection list.
        r   r   N)	r   rV   factorybuildProtocolmakeConnectionassertInconnectionsconnectionLostassertNotIn)r&   rK   r   r-   r-   r.   (test_tcpDisconnectRemovesFromConnections  s   

z6ResolverTests.test_tcpDisconnectRemovesFromConnectionsc           
      C   sv   t  }tjdg|d}|td}|jd \}}}}}G dd dt}	|	|j
d t|	  | ||	 dS )z
        The deferred returned by L{client.Resolver.queryTCP} will
        errback when the TCP connection attempt fails. The reason for
        the connection failure is passed as the argument to errback.
        z192.0.2.100r{   r   r   r   c                   @   r   )zVResolverTests.test_singleTCPQueryErrbackOnConnectionFailure.<locals>.SentinelExceptionNr   r-   r-   r-   r.   SentinelException  r   r#  N)r   r   r   rV   queryTCPr   r   
tcpClientsr   clientConnectionFailed
connectorsr   r   failureResultOf)
r&   rr   rK   r   r   r   r  r(   bindAddressr#  r-   r-   r.   -test_singleTCPQueryErrbackOnConnectionFailure  s   z;ResolverTests.test_singleTCPQueryErrbackOnConnectionFailurec                 C   s   t  }tjdg|d}|td}|td}|jd \}}}}}	G dd dt}
|	|j
d t|
  | ||
}| ||
}| || dS )	z
        All pending L{resolver.queryTCP} C{deferred}s will C{errback}
        with the same C{Failure} if the connection attempt fails.
        r"  r   r   zexample.netr   c                   @   r   )zXResolverTests.test_multipleTCPQueryErrbackOnConnectionFailure.<locals>.SentinelExceptionNr   r-   r-   r-   r.   r#    r   r#  N)r   r   r   rV   r$  r   r   r%  r   r&  r'  r   r   r(  rM   )r&   rr   rK   d1d2r   r   r  r(   r)  r#  f1f2r-   r-   r.   /test_multipleTCPQueryErrbackOnConnectionFailure  s   z=ResolverTests.test_multipleTCPQueryErrbackOnConnectionFailurec                    s  t  }tjdg|dtd  } fdd}|| | t	|j
d | t	|jd |j
d \}}}}}tt }	||jd |	 | t	|j
d | t	|jd | | tt }
||jd |
 | |t}| ||
 d	S )
z{
        An errback on the deferred returned by
        L{client.Resolver.queryTCP} may trigger another TCP query.
        )r   iE'  r   r   c                    s   |  t  S r:   )trapr   r$  )eqrK   r-   r.   reissue  r  zOResolverTests.test_reentrantTCPQueryErrbackOnConnectionFailure.<locals>.reissuer\   r   r   N)r   r   r   rV   r   r   r$  
addErrbackr^   r_   r%  r'  r   r   r   r&  assertNoResultr(  rM   )r&   rr   r   r4  r   r   r  r(   r)  r-  r.  fr-   r2  r.   0test_reentrantTCPQueryErrbackOnConnectionFailure  s$   



z>ResolverTests.test_reentrantTCPQueryErrbackOnConnectionFailurec                 C   s   t  }tjdg|d}|td}|jd \}}}}}|j}	| 	t
|	d G dd dt}
||jd t|
  | ||
 | |j|	 | 	t
|	d dS )	z
        When the TCP connection attempt fails, the
        L{client.Resolver.pending} list is emptied in place. It is not
        replaced with a new empty list.
        r"  r   r   r   r\   c                   @   r   )zJResolverTests.test_pendingEmptiedInPlaceOnError.<locals>.SentinelExceptionNr   r-   r-   r-   r.   r#  '  r   r#  N)r   r   r   rV   r$  r   r   r%  pendingr^   r_   r   r&  r'  r   r   r(  rM   )r&   rr   rK   r   r   r   r  r(   r)  
prePendingr#  r-   r-   r.   !test_pendingEmptiedInPlaceOnError  s   z/ResolverTests.test_pendingEmptiedInPlaceOnErrorN) r0   r1   r2   r7   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r  r  r!  r*  r/  r8  r;  r-   r-   r-   r.   r      s<    			"%+r   c                   @   s   e 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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+d, Zd-d. Zd/d0 Zd1d2 Zd3d4 Zd5d6 Zd7d8 Zd9d: Zd;S )<ClientTestsc                 C   s   t  t_d| _d| _dS )z:
        Replace the resolver with a FakeResolver
           example.comr   N)r   r   theResolverhostnamehostnameForGetHostByNamer5   r-   r-   r.   setUp4  s   
zClientTests.setUpc                 C   s
   dt _dS )zp
        By setting the resolver to None, it will be recreated next time a name
        lookup is done.
        N)r   r>  r5   r-   r-   r.   tearDown<  s   
zClientTests.tearDownc                 C   s6   |\}}}|d }|  |jj| j |  |j| dS )zT
        Verify that the result is the same query type as what is expected.
        r   N)r^   r   r?  r   )r&   r*   r'   r   r+   r,   rD   r-   r-   r.   checkResultC  s   
zClientTests.checkResultc                 C   s   |  |d dS )zR
        Test that the getHostByName query returns the 127.0.0.1 address.
        r   Nr   r&   rD   r-   r-   r.   checkGetHostByNameL  r   zClientTests.checkGetHostByNamec                 C   s   t | j}|| j |S )zM
        do a getHostByName of a value that should return 127.0.0.1.
        )r   getHostByNamer@  r   rE  r&   r   r-   r-   r.   test_getHostByNameR  s   zClientTests.test_getHostByNamec                 C       t | j}|| jtj |S )z
        Do a lookup and test that the resolver will issue the correct type of
        query type. We do this by checking that FakeResolver returns a result
        record with the same query type as what we issued.
        )r   lookupAddressr?  r   rC  r   r#   rG  r-   r-   r.   test_lookupAddressZ  s   zClientTests.test_lookupAddressc                 C   rI  z+
        See L{test_lookupAddress}
        )r   lookupIPV6Addressr?  r   rC  r   AAAArG  r-   r-   r.   test_lookupIPV6Addressd     z"ClientTests.test_lookupIPV6Addressc                 C   rI  rL  )r   lookupAddress6r?  r   rC  r   r   rG  r-   r-   r.   test_lookupAddress6l  rP  zClientTests.test_lookupAddress6c                 C   rI  rL  )r   lookupNameserversr?  r   rC  r   NSrG  r-   r-   r.   test_lookupNameserverst  rP  z"ClientTests.test_lookupNameserversc                 C   rI  rL  )r   lookupCanonicalNamer?  r   rC  r   CNAMErG  r-   r-   r.   test_lookupCanonicalName|  rP  z$ClientTests.test_lookupCanonicalNamec                 C   rI  rL  )r   lookupAuthorityr?  r   rC  r   SOArG  r-   r-   r.   test_lookupAuthority  rP  z ClientTests.test_lookupAuthorityc                 C   rI  rL  )r   lookupMailBoxr?  r   rC  r   MBrG  r-   r-   r.   test_lookupMailBox  rP  zClientTests.test_lookupMailBoxc                 C   rI  rL  )r   lookupMailGroupr?  r   rC  r   MGrG  r-   r-   r.   test_lookupMailGroup  rP  z ClientTests.test_lookupMailGroupc                 C   rI  rL  )r   lookupMailRenamer?  r   rC  r   MRrG  r-   r-   r.   test_lookupMailRename  rP  z!ClientTests.test_lookupMailRenamec                 C   rI  rL  )r   
lookupNullr?  r   rC  r   NULLrG  r-   r-   r.   test_lookupNull  rP  zClientTests.test_lookupNullc                 C   rI  rL  )r   lookupWellKnownServicesr?  r   rC  r   WKSrG  r-   r-   r.   test_lookupWellKnownServices  rP  z(ClientTests.test_lookupWellKnownServicesc                 C   rI  rL  )r   lookupPointerr?  r   rC  r   PTRrG  r-   r-   r.   test_lookupPointer  rP  zClientTests.test_lookupPointerc                 C   rI  rL  )r   lookupHostInfor?  r   rC  r   HINFOrG  r-   r-   r.   test_lookupHostInfo  rP  zClientTests.test_lookupHostInfoc                 C   rI  rL  )r   lookupMailboxInfor?  r   rC  r   MINFOrG  r-   r-   r.   test_lookupMailboxInfo  rP  z"ClientTests.test_lookupMailboxInfoc                 C   rI  rL  )r   lookupMailExchanger?  r   rC  r   MXrG  r-   r-   r.   test_lookupMailExchange  rP  z#ClientTests.test_lookupMailExchangec                 C   rI  rL  )r   
lookupTextr?  r   rC  r   TXTrG  r-   r-   r.   test_lookupText  rP  zClientTests.test_lookupTextc                 C   rI  rL  )r   lookupSenderPolicyr?  r   rC  r   SPFrG  r-   r-   r.   test_lookupSenderPolicy  rP  z#ClientTests.test_lookupSenderPolicyc                 C   rI  rL  )r   lookupResponsibilityr?  r   rC  r   RPrG  r-   r-   r.   test_lookupResponsibility  rP  z%ClientTests.test_lookupResponsibilityc                 C   rI  rL  )r   lookupAFSDatabaser?  r   rC  r   AFSDBrG  r-   r-   r.   test_lookupAFSDatabase  rP  z"ClientTests.test_lookupAFSDatabasec                 C   rI  rL  )r   lookupServicer?  r   rC  r   SRVrG  r-   r-   r.   test_lookupService  rP  zClientTests.test_lookupServicec                 C   rI  rL  )r   
lookupZoner?  r   rC  r   AXFRrG  r-   r-   r.   test_lookupZone  rP  zClientTests.test_lookupZonec                 C   rI  rL  )r   lookupAllRecordsr?  r   rC  r   ALL_RECORDSrG  r-   r-   r.   test_lookupAllRecords  rP  z!ClientTests.test_lookupAllRecordsc                 C   rI  rL  )r   lookupNamingAuthorityPointerr?  r   rC  r   NAPTRrG  r-   r-   r.   !test_lookupNamingAuthorityPointer  rP  z-ClientTests.test_lookupNamingAuthorityPointerc                 C   s.   t | jt j}t|}|| jt j |S )a  
        L{client.query} accepts a L{dns.Query} instance and dispatches
        it to L{client.theResolver}.C{query}, which in turn dispatches
        to an appropriate C{lookup*} method of L{client.theResolver},
        based on the L{dns.Query} type.
        )r   r   r?  r#   r   rE   r   rC  )r&   r3  r   r-   r-   r.   
test_query  s   
zClientTests.test_queryN) r0   r1   r2   rA  rB  rC  rE  rH  rK  rO  rR  rU  rX  r[  r^  ra  rd  rg  rj  rm  rp  rs  rv  ry  r|  r  r  r  r  r  r  r  r-   r-   r-   r.   r<  3  s<    	
r<  c                   @   sX   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S )FilterAnswersTestsz|
    Test L{twisted.names.client.Resolver.filterAnswers}'s handling of various
    error conditions it might encounter.
    c                 C   s   t jdgd| _d S )N)z0.0.0.0r   r   )r   rV   rK   r5   r-   r-   r.   rA  '  s   zFilterAnswersTests.setUpc                    sV   t jdd  d  fdd}|j_j }|jdgdgdgf |S )	zf
        Test that a truncated message results in an equivalent request made via
        TCP.
        T)truncr=  c                    s8    |  j t }dg|_dg|_dg|_t|S )Nr   r+   r,   )	r^   r<   r   r   r   r+   r,   r   r%   )r<   r   mr&   r-   r.   r$  4  s   
z:FilterAnswersTests.test_truncatedMessage.<locals>.queryTCPr   r+   r,   )r   r   addQueryrK   r$  filterAnswersr   r^   )r&   r$  r   r-   r  r.   test_truncatedMessage,  s   
z(FilterAnswersTests.test_truncatedMessagec                 C   s&   t j|d}| j|}|| d S )N)rCode)r   r   rK   r  r0  )r&   rcoder  r  r  r-   r-   r.   
_rcodeTestA  s   zFilterAnswersTests._rcodeTestc                 C      |  tjtjS )z
        Test that a message with a result code of C{EFORMAT} results in a
        failure wrapped around L{DNSFormatError}.
        )r  r   EFORMATr   DNSFormatErrorr5   r-   r-   r.   test_formatErrorF  s   z#FilterAnswersTests.test_formatErrorc                 C   r  )zP
        Like L{test_formatError} but for C{ESERVER}/L{DNSServerError}.
        )r  r   ESERVERr   DNSServerErrorr5   r-   r-   r.   test_serverErrorM  r   z#FilterAnswersTests.test_serverErrorc                 C   r  )zL
        Like L{test_formatError} but for C{ENAME}/L{DNSNameError}.
        )r  r   ENAMEr   DNSNameErrorr5   r-   r-   r.   test_nameErrorS  r   z!FilterAnswersTests.test_nameErrorc                 C   r  )zX
        Like L{test_formatError} but for C{ENOTIMP}/L{DNSNotImplementedError}.
        )r  r   ENOTIMPr   DNSNotImplementedErrorr5   r-   r-   r.   test_notImplementedErrorY  r   z+FilterAnswersTests.test_notImplementedErrorc                 C   r  )zW
        Like L{test_formatError} but for C{EREFUSED}/L{DNSQueryRefusedError}.
        )r  r   EREFUSEDr   DNSQueryRefusedErrorr5   r-   r-   r.   test_refusedError_  r   z$FilterAnswersTests.test_refusedErrorc                 C   s   |  tjd tjS )zm
        Like L{test_formatError} but for an unrecognized error code and
        L{DNSUnknownError}.
        r\   )r  r   r  r   DNSUnknownErrorr5   r-   r-   r.   test_refusedErrorUnknowne  s   z+FilterAnswersTests.test_refusedErrorUnknownN)r0   r1   r2   r7   rA  r  r  r  r  r  r  r  r  r-   r-   r-   r.   r  !  s    r  c                   @   s&   e Zd Zdd Zd	ddZdd ZdS )
FakeDNSDatagramProtocolc                 C   r9   r:   r;   r5   r-   r-   r.   r>   n  r?   z FakeDNSDatagramProtocol.__init__r@   Nc                 C   s$   | j ||||f tt|S r:   )r<   rB   r   r  r   r   )r&   r   r<   r(   rC   r-   r-   r.   rE   r  s   zFakeDNSDatagramProtocol.queryc                 C   s   d S r:   r-   )r&   rC   r-   r-   r.   removeResendv  s   z$FakeDNSDatagramProtocol.removeResendrF   )r0   r1   r2   r>   rE   r  r-   r-   r-   r.   r  m  s    
r  c                   @   s0   e Zd ZdZg dZdd Zdd Zdd Zd	S )
RetryLogicTestszE
    Tests for query retrying implemented by L{client.Resolver}.
    )z1.2.3.4z4.3.2.1za.b.c.dzz.y.x.wc                    sN   dd | j D }tjd|d}t   fdd|_|d| j| j	 S )a  
        When timeouts occur waiting for responses to queries, the next
        configured server is issued the query.  When the query has been issued
        to all configured servers, the timeout is increased and the process
        begins again at the beginning.
        c                 S   s   g | ]}|d fqS )r{   r-   )rX   xr-   r-   r.   rZ     s    z:RetryLogicTests.test_roundRobinBackoff.<locals>.<listcomp>N)ro   r   c                      r   r:   r-   r-   r   r-   r.   r     r   z8RetryLogicTests.test_roundRobinBackoff.<locals>.<lambda>r   )
testServersr   rV   r  r   rJ  r   _cbRoundRobinBackoffr5  _ebRoundRobinBackoff)r&   addrsrY   r-   r  r.   test_roundRobinBackoff  s   
z&RetryLogicTests.test_roundRobinBackoffc                 C   s   |  d d S )Nz/Lookup address succeeded, should have timed out)r  rD  r-   r-   r.   r    s   z$RetryLogicTests._cbRoundRobinBackoffc                 C   s   | tj dD ]>}|jd t| j }|jd t| j= |  t| j}|  t||D ]\\}}}}	}
| 	||
df | 	|| q/q| 
|j d S )N)r\   r      -   r{   )r0  r   TimeoutErrorr<   r_   r  sortlistzipr^   r  )r&   r   	fakeProtottriesexpectedaddrrE   r(   rC   expectedAddrr-   r-   r.   r    s   
z$RetryLogicTests._ebRoundRobinBackoffN)r0   r1   r2   r7   r  r  r  r  r-   r-   r-   r.   r  {  s    r  c                   @   s   e Zd ZdZdd ZdS )ThreadedResolverTestsz/
    Tests for L{client.ThreadedResolver}.
    c                 C   sT   t   | j| jgd}| |d d d | |d d t | t|d dS )z
        L{client.ThreadedResolver} is deprecated.  Instantiating it emits a
        deprecation warning pointing at the code that does the instantiation.
        )offendingFunctionsr   messagezztwisted.names.client.ThreadedResolver is deprecated since Twisted 9.0, use twisted.internet.base.ThreadedResolver instead.categoryr\   N)r   ThreadedResolverflushWarningstest_deprecatedr^   DeprecationWarningr_   )r&   warningsr-   r-   r.   r    s   
z%ThreadedResolverTests.test_deprecatedN)r0   r1   r2   r7   r  r-   r-   r-   r.   r    s    r  )6r7   r  zope.interface.verifyr   r   twisted.internetr   twisted.internet.errorr   r   twisted.internet.interfacesr   twisted.internet.taskr   #twisted.internet.test.modulehelpersr	   twisted.namesr
   r   r   r   r   twisted.names.commonr   twisted.names.errorr   twisted.names.testr   twisted.names.test.test_hostsr   twisted.pythonr   twisted.python.filepathr   twisted.python.runtimer   twisted.testr   twisted.trialr   	isWindowsrQ   r   r3   r8   TestCaserG   rS   r   r<  r  r  r  r  r-   r-   r-   r.   <module>   sJ   r    J oL0