U
     T‚gÈ¢  ã                   @   sî   d 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 ddlmZmZ ddlmZ G dd	„ d	eƒZd
d„ ZG dd„ dejƒZG dd„ dejƒZG dd„ dƒZG dd„ dƒZG dd„ dƒZG dd„ dƒZdd„ ZG dd„ dejƒZdS )z)
Test cases for L{twisted.names.server}.
é    )ÚverifyClass)Údefer)ÚIProtocolFactory)ÚdnsÚerrorÚresolveÚserver)ÚfailureÚlog)Úunittestc                   @   s   e Zd ZdZdd„ ZdS )ÚRaisedArgumentszD
    An exception containing the arguments raised by L{raiser}.
    c                 C   s   || _ || _d S ©N©ÚargsÚkwargs©Úselfr   r   © r   úB/tmp/pip-unpacked-wheel-1_7di8ic/twisted/names/test/test_server.pyÚ__init__   s    zRaisedArguments.__init__N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r   r      s   r   c                  O   s   t | |ƒ‚dS )z¡
    Raise a L{RaisedArguments} exception containing the supplied arguments.

    Used as a fake when testing the call signatures of  methods and functions.
    N)r   r   r   r   r   Úraiser   s    r   c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )ÚNoResponseDNSServerFactorya  
    A L{server.DNSServerFactory} subclass which does not attempt to reply to any
    received messages.

    Used for testing logged messages in C{messageReceived} without having to
    fake or patch the preceding code which attempts to deliver a response
    message.
    c                 C   s   dS )a  
        Deny all queries.

        @param message: See L{server.DNSServerFactory.allowQuery}
        @param protocol: See L{server.DNSServerFactory.allowQuery}
        @param address: See L{server.DNSServerFactory.allowQuery}

        @return: L{False}
        @rtype: L{bool}
        Fr   )r   ÚmessageÚprotocolÚaddressr   r   r   Ú
allowQuery.   s    z%NoResponseDNSServerFactory.allowQueryc                 C   s   dS )zé
        A noop send reply.

        @param protocol: See L{server.DNSServerFactory.sendReply}
        @param message: See L{server.DNSServerFactory.sendReply}
        @param address: See L{server.DNSServerFactory.sendReply}
        Nr   )r   r   r   r   r   r   r   Ú	sendReply;   s    z$NoResponseDNSServerFactory.sendReplyN)r   r   r   r   r   r    r   r   r   r   r   $   s   	r   c                   @   s(   e Zd ZdZG dd„ deƒZdd„ ZdS )ÚRaisingDNSServerFactoryzÚ
    A L{server.DNSServerFactory} subclass whose methods raise an exception
    containing the supplied arguments.

    Used for stopping L{messageReceived} and testing the arguments supplied to
    L{allowQuery}.
    c                   @   s   e Zd ZdZdS )z+RaisingDNSServerFactory.AllowQueryArgumentsúG
        Contains positional and keyword arguments in C{args}.
        N©r   r   r   r   r   r   r   r   ÚAllowQueryArgumentsN   s   r$   c                 O   s   |   ||¡‚dS )aC  
        Raise the arguments supplied to L{allowQuery}.

        @param args: Positional arguments which will be recorded in the raised
            exception.
        @type args: L{tuple}

        @param kwargs: Keyword args which will be recorded in the raised
            exception.
        @type kwargs: L{dict}
        N)r$   r   r   r   r   r   S   s    z"RaisingDNSServerFactory.allowQueryN)r   r   r   r   Ú	Exceptionr$   r   r   r   r   r   r!   E   s   r!   c                   @   s(   e Zd ZdZG dd„ deƒZdd„ ZdS )ÚRaisingProtocolzm
    A partial fake L{IProtocol} whose methods raise an exception containing the
    supplied arguments.
    c                   @   s   e Zd ZdZdS )z%RaisingProtocol.WriteMessageArgumentsr"   Nr#   r   r   r   r   ÚWriteMessageArgumentsh   s   r'   c                 O   s   |   ||¡‚dS ©z»
        Raises the supplied arguments.

        @param args: Positional arguments
        @type args: L{tuple}

        @param kwargs: Keyword args
        @type kwargs: L{dict}
        N)r'   r   r   r   r   ÚwriteMessagem   s    
zRaisingProtocol.writeMessageN)r   r   r   r   r%   r'   r)   r   r   r   r   r&   b   s   r&   c                   @   s   e Zd ZdZdd„ ZdS )ÚNoopProtocolzT
    A partial fake L{dns.DNSProtocolMixin} with a noop L{writeMessage} method.
    c                 O   s   dS )zÔ
        A noop version of L{dns.DNSProtocolMixin.writeMessage}.

        @param args: Positional arguments
        @type args: L{tuple}

        @param kwargs: Keyword args
        @type kwargs: L{dict}
        Nr   r   r   r   r   r)      s    zNoopProtocol.writeMessageN)r   r   r   r   r)   r   r   r   r   r*   z   s   r*   c                   @   s(   e Zd ZdZG dd„ deƒZdd„ ZdS )ÚRaisingResolverzm
    A partial fake L{IResolver} whose methods raise an exception containing the
    supplied arguments.
    c                   @   s   e Zd ZdZdS )zRaisingResolver.QueryArgumentsr"   Nr#   r   r   r   r   ÚQueryArguments‘   s   r,   c                 O   s   |   ||¡‚dS r(   )r,   r   r   r   r   Úquery–   s    
zRaisingResolver.queryN)r   r   r   r   r%   r,   r-   r   r   r   r   r+   ‹   s   r+   c                   @   s(   e Zd ZdZG dd„ deƒZdd„ ZdS )ÚRaisingCachez}
    A partial fake L{twisted.names.cache.Cache} whose methods raise an exception
    containing the supplied arguments.
    c                   @   s   e Zd ZdZdS )z!RaisingCache.CacheResultArgumentsr"   Nr#   r   r   r   r   ÚCacheResultArguments©   s   r/   c                 O   s   |   ||¡‚dS r(   )r/   r   r   r   r   ÚcacheResult®   s    
zRaisingCache.cacheResultN)r   r   r   r   r%   r/   r0   r   r   r   r   r.   £   s   r.   c                 O   sD   g }t  |j¡ |  t j|j¡ |||Ž |  dd„ |D ƒ|¡ dS )a  
    Assert that the callable logs the expected messages when called.

    XXX: Put this somewhere where it can be re-used elsewhere. See #6677.

    @param testCase: The test case controlling the test which triggers the
        logged messages and on which assertions will be called.
    @type testCase: L{unittest.SynchronousTestCase}

    @param expectedMessages: A L{list} of the expected log messages
    @type expectedMessages: L{list}

    @param callable: The function which is expected to produce the
        C{expectedMessages} when called.
    @type callable: L{callable}

    @param args: Positional arguments to be passed to C{callable}.
    @type args: L{list}

    @param kwargs: Keyword arguments to be passed to C{callable}.
    @type kwargs: L{dict}
    c                 S   s   g | ]}|d  d ‘qS )r   r   r   )Ú.0Úmr   r   r   Ú
<listcomp>Ø   s     z$assertLogMessage.<locals>.<listcomp>N)r
   ZaddObserverÚappendZ
addCleanupZremoveObserverÚassertEqual)ZtestCaseZexpectedMessagesÚcallabler   r   ZloggedMessagesr   r   r   ÚassertLogMessage»   s
    
r7   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:d;„ Z d<d=„ Z!d>d?„ Z"d@dA„ Z#dBdC„ Z$dDdE„ Z%dFdG„ Z&dHdI„ Z'dJdK„ Z(dLdM„ Z)dNdO„ Z*dPdQ„ Z+dRdS„ Z,dTdU„ Z-dVdW„ Z.dXdY„ Z/dZd[„ Z0d\d]„ Z1d^d_„ Z2d`da„ Z3dbdc„ Z4ddde„ Z5dfdg„ Z6dhdi„ Z7djdk„ Z8dldm„ Z9dndo„ Z:dpdq„ Z;drds„ Z<dtdu„ Z=dvdw„ Z>dxdy„ Z?dzd{„ Z@d|d}„ ZAd~d„ ZBd€d�„ ZCd‚S )ƒÚDNSServerFactoryTestsz/
    Tests for L{server.DNSServerFactory}.
    c                 C   s   |   t ¡ jtj¡ dS )zd
        L{server.DNSServerFactory.resolver} is a L{resolve.ResolverChain}
        instance
        N)ZassertIsInstancer   ÚDNSServerFactoryÚresolverr   ZResolverChain©r   r   r   r   Útest_resolverTypeà   s    z'DNSServerFactoryTests.test_resolverTypec                 C   s   |   t ¡ jjg ¡ dS )zn
        L{server.DNSServerFactory.resolver} is an empty L{resolve.ResolverChain}
        by default.
        N©r5   r   r9   r:   Ú	resolversr;   r   r   r   Útest_resolverDefaultEmptyç   s    z/DNSServerFactoryTests.test_resolverDefaultEmptyc                 C   s&   t ƒ }|  tj|gd�jj|g¡ dS )zÎ
        L{server.DNSServerFactory.__init__} accepts an C{authorities}
        argument. The value of this argument is a list and is used to extend the
        C{resolver} L{resolve.ResolverChain}.
        )ÚauthoritiesN©Úobjectr5   r   r9   r:   r>   ©r   ZdummyResolverr   r   r   Útest_authoritiesî   s
    þz&DNSServerFactoryTests.test_authoritiesc                 C   s&   t ƒ }|  tj|gd�jj|g¡ dS )zÈ
        L{server.DNSServerFactory.__init__} accepts a C{caches} argument. The
        value of this argument is a list and is used to extend the C{resolver}
        L{resolve.ResolverChain}.
        ©ÚcachesNrA   rC   r   r   r   Útest_cachesú   s
    þz!DNSServerFactoryTests.test_cachesc                 C   s&   t ƒ }|  tj|gd�jj|g¡ dS )zÉ
        L{server.DNSServerFactory.__init__} accepts a C{clients} argument. The
        value of this argument is a list and is used to extend the C{resolver}
        L{resolve.ResolverChain}.
        ©ÚclientsNrA   rC   r   r   r   Útest_clients  s
    þz"DNSServerFactoryTests.test_clientsc                 C   sV   G dd„ dƒ}G dd„ dƒ}G dd„ dƒ}|   tj|g|g|gd�jj|||g¡ dS )	zz
        L{server.DNSServerFactory.resolver} contains an ordered list of
        authorities, caches and clients.
        c                   @   s   e Zd ZdS )z@DNSServerFactoryTests.test_resolverOrder.<locals>.DummyAuthorityN©r   r   r   r   r   r   r   ÚDummyAuthority  s   rL   c                   @   s   e Zd ZdS )z<DNSServerFactoryTests.test_resolverOrder.<locals>.DummyCacheNrK   r   r   r   r   Ú
DummyCache  s   rM   c                   @   s   e Zd ZdS )z=DNSServerFactoryTests.test_resolverOrder.<locals>.DummyClientNrK   r   r   r   r   ÚDummyClient  s   rN   )r@   rF   rI   Nr=   )r   rL   rM   rN   r   r   r   Útest_resolverOrder  s      ÿüz(DNSServerFactoryTests.test_resolverOrderc                 C   s   |   t ¡ j¡ dS )zI
        L{server.DNSServerFactory.cache} is L{None} by default.
        N)ZassertIsNoner   r9   Úcacher;   r   r   r   Útest_cacheDefault)  s    z'DNSServerFactoryTests.test_cacheDefaultc                 C   s&   t ƒ }|  tjt ƒ |gd�j|¡ dS )z�
        L{server.DNSServerFactory.__init__} assigns the last object in the
        C{caches} list to L{server.DNSServerFactory.cache}.
        rE   N)rB   r5   r   r9   rP   rC   r   r   r   Útest_cacheOverride/  s
    þz(DNSServerFactoryTests.test_cacheOverridec                 C   s   |   t ¡ j¡ dS )z¶
        L{server.DNSServerFactory.canRecurse} is a flag indicating that this
        server is capable of performing recursive DNS lookups. It defaults to
        L{False}.
        N)ÚassertFalser   r9   Ú
canRecurser;   r   r   r   Útest_canRecurseDefault:  s    z,DNSServerFactoryTests.test_canRecurseDefaultc                 C   s   |   tjdgd�jd¡ dS )z~
        L{server.DNSServerFactory.__init__} sets C{canRecurse} to L{True} if it
        is supplied with C{clients}.
        NrH   T)r5   r   r9   rT   r;   r   r   r   Útest_canRecurseOverrideB  s    z-DNSServerFactoryTests.test_canRecurseOverridec                 C   s   |   t ¡ j¡ dS )zJ
        L{server.DNSServerFactory.verbose} defaults to L{False}.
        N)rS   r   r9   Úverboser;   r   r   r   Útest_verboseDefaultI  s    z)DNSServerFactoryTests.test_verboseDefaultc                 C   s   |   tjdd�j¡ dS )z�
        L{server.DNSServerFactory.__init__} accepts a C{verbose} argument which
        overrides L{server.DNSServerFactory.verbose}.
        T©rW   N)Ú
assertTruer   r9   rW   r;   r   r   r   Útest_verboseOverrideO  s    z*DNSServerFactoryTests.test_verboseOverridec                 C   s   |   tttjƒ¡ dS )zL
        L{server.DNSServerFactory} implements L{IProtocolFactory}.
        N)rZ   r   r   r   r9   r;   r   r   r   Útest_interfaceV  s    z$DNSServerFactoryTests.test_interfacec                 C   s   |   tjjtj¡ dS )zU
        L{server.DNSServerFactory.protocol} defaults to L{dns.DNSProtocol}.
        N)ÚassertIsr   r9   r   r   ZDNSProtocolr;   r   r   r   Útest_defaultProtocol\  s    z*DNSServerFactoryTests.test_defaultProtocolc                    s\   G dd„ dƒ}|ƒ ‰ ‡ fdd„}t  ¡ }||_|jdd�}|  ˆ |fi f||j|jf¡ dS )z³
        L{server.DNSServerFactory.buildProtocol} builds a protocol by calling
        L{server.DNSServerFactory.protocol} with its self as a positional
        argument.
        c                   @   s   e Zd ZdZdZdZdS )zNDNSServerFactoryTests.test_buildProtocolProtocolOverride.<locals>.FakeProtocolN)r   r   r   Úfactoryr   r   r   r   r   r   ÚFakeProtocoli  s   r`   c                     s   | ˆ _ |ˆ _ˆ S r   r   r   ©ÚstubProtocolr   r   ÚfakeProtocolFactoryp  s    zUDNSServerFactoryTests.test_buildProtocolProtocolOverride.<locals>.fakeProtocolFactoryN)Úaddr)r   r9   r   ZbuildProtocolr5   r   r   )r   r`   rc   ÚfÚpr   ra   r   Ú"test_buildProtocolProtocolOverrideb  s    z8DNSServerFactoryTests.test_buildProtocolProtocolOverridec                 C   s   t  ¡ }t| g |jdƒ dS )zm
        L{server.DNSServerFactory._verboseLog} does not log messages unless
        C{verbose > 0}.
        úFoo BarN©r   r9   r7   Z_verboseLog©r   re   r   r   r   Útest_verboseLogQuiet{  s    z*DNSServerFactoryTests.test_verboseLogQuietc                 C   s"   t jdd�}t| dg|jdƒ dS )zZ
        L{server.DNSServerFactory._verboseLog} logs a message if C{verbose > 0}.
        é   rY   rh   Nri   rj   r   r   r   Útest_verboseLogVerboseƒ  s    z,DNSServerFactoryTests.test_verboseLogVerbosec                 C   s.   t  ¡ }tdd�}t| dg|j|ddd� dS )z•
        L{server.DNSServerFactory.messageReceived} logs about an empty query if
        the message had no queries and C{verbose} is C{>0}.
        rl   rY   z$Empty query from ('192.0.2.100', 53)N©z192.0.2.100é5   ©r   Úprotor   )r   ÚMessager   r7   ÚmessageReceived©r   r2   re   r   r   r   Ú"test_messageReceivedLoggingNoQueryŠ  s    
úz8DNSServerFactoryTests.test_messageReceivedLoggingNoQueryc                 C   sN   t  ¡ }|jdt jd� |jdt jd� tdd�}t| dg|j|ddd� dS )	z•
        L{server.DNSServerFactory.messageReceived} logs the query types of all
        queries in the message if C{verbose} is set to C{1}.
        úexample.com©ÚnameÚtyperl   rY   z&MX AAAA query from ('192.0.2.100', 53)Nrn   rp   ©r   rr   ÚaddQueryZMXZAAAAr   r7   rs   rt   r   r   r   Útest_messageReceivedLogging1›  s    
úz2DNSServerFactoryTests.test_messageReceivedLogging1c                 C   sN   t  ¡ }|jdt jd� |jdt jd� tdd�}t| dg|j|ddd� dS )	zŽ
        L{server.DNSServerFactory.messageReceived} logs the repr of all queries
        in the message if C{verbose} is set to C{2}.
        rv   rw   é   rY   zT<Query example.com MX IN> <Query example.com AAAA IN> query from ('192.0.2.100', 53)Nrn   rp   rz   rt   r   r   r   Útest_messageReceivedLogging2®  s    
ÿ÷z2DNSServerFactoryTests.test_messageReceivedLogging2c                    sN   t  ¡ }tƒ }tƒ ‰ |  tjd‡ fdd„¡ |j|ddd� |  |j	ˆ ¡ dS )zv
        L{server.DNSServerFactory.messageReceived} assigns a unix timestamp to
        the received message.
        Útimec                      s   ˆ S r   r   r   ©Útr   r   Ú<lambda>Ì  ó    zEDNSServerFactoryTests.test_messageReceivedTimestamp.<locals>.<lambda>Nrp   )
r   rr   r   rB   Úpatchr   r   rs   r5   ÚtimeReceivedrt   r   r€   r   Útest_messageReceivedTimestampÄ  s    z3DNSServerFactoryTests.test_messageReceivedTimestampc                 C   s^   t  ¡ }tƒ }tƒ }tƒ }| jtj|j|||d�}|j\}}|  ||||f¡ |  |i ¡ dS )z¿
        L{server.DNSServerFactory.messageReceived} passes all messages to
        L{server.DNSServerFactory.allowQuery} along with the receiving protocol
        and origin address.
        rp   N)	r   rr   rB   r!   ÚassertRaisesr$   rs   r   r5   )r   r   ZdummyProtocolÚdummyAddressre   Úer   r   r   r   r   Útest_messageReceivedAllowQueryÑ  s    û
z4DNSServerFactoryTests.test_messageReceivedAllowQueryc                    sj   G dd„ dt ƒ‰ G ‡ fdd„dtjƒ}|ƒ }| jˆ |jt ¡ ddd�}|j\\}}}}|  |j	tj
¡ dS )z»
        If C{allowQuery} returns C{False},
        L{server.DNSServerFactory.messageReceived} calls L{server.sendReply}
        with a message whose C{rCode} is L{dns.EREFUSED}.
        c                   @   s   e Zd ZdS )zFDNSServerFactoryTests.test_allowQueryFalse.<locals>.SendReplyExceptionNrK   r   r   r   r   ÚSendReplyExceptionî  s   r‹   c                       s    e Zd Zdd„ Z‡ fdd„ZdS )zKDNSServerFactoryTests.test_allowQueryFalse.<locals>.RaisingDNSServerFactoryc                 _   s   dS )NFr   r   r   r   r   r   ò  s    zVDNSServerFactoryTests.test_allowQueryFalse.<locals>.RaisingDNSServerFactory.allowQueryc                    s   ˆ ||ƒ‚d S r   r   r   ©r‹   r   r   r    õ  s    zUDNSServerFactoryTests.test_allowQueryFalse.<locals>.RaisingDNSServerFactory.sendReplyN)r   r   r   r   r    r   rŒ   r   r   r!   ñ  s   r!   Nrp   )r%   r   r9   r‡   rs   r   rr   r   r5   ÚrCodeZEREFUSED)r   r!   re   r‰   rq   r   r   r   r   rŒ   r   Útest_allowQueryFalseç  s    ûz*DNSServerFactoryTests.test_allowQueryFalsec                    sX   dg|_ g ‰ ‡ fdd„}tƒ }t d¡}t|||ƒ | ||¡ |  ˆ ||dfg¡ dS )a¤  
        Assert that the named method is called with the given message when it is
        passed to L{DNSServerFactory.messageReceived}.

        @param methodName: The name of the method which is expected to be
            called.
        @type methodName: L{str}

        @param message: The message which is expected to be passed to the
            C{methodName} method.
        @type message: L{dns.Message}
        Nc                    s   ˆ   | ||f¡ d S r   ©r4   ©r   r   r   ©ZreceivedMessagesr   r   ÚfakeHandler  s    z?DNSServerFactoryTests._messageReceivedTest.<locals>.fakeHandler)Úqueriesr*   r   r9   Úsetattrrs   r5   )r   Ú
methodNamer   r’   r   r_   r   r‘   r   Ú_messageReceivedTest  s    
z*DNSServerFactoryTests._messageReceivedTestc                 C   s   |   dtjtjd�¡ dS )z’
        L{DNSServerFactory.messageReceived} passes messages with an opcode of
        C{OP_QUERY} on to L{DNSServerFactory.handleQuery}.
        ÚhandleQuery©ZopCodeN)r–   r   rr   ZOP_QUERYr;   r   r   r   Útest_queryMessageReceived   s    z/DNSServerFactoryTests.test_queryMessageReceivedc                 C   s   |   dtjtjd�¡ dS )z›
        L{DNSServerFactory.messageReceived} passes messages with an opcode of
        C{OP_INVERSE} on to L{DNSServerFactory.handleInverseQuery}.
        ÚhandleInverseQueryr˜   N)r–   r   rr   Z
OP_INVERSEr;   r   r   r   Ú test_inverseQueryMessageReceived'  s     ÿz6DNSServerFactoryTests.test_inverseQueryMessageReceivedc                 C   s   |   dtjtjd�¡ dS )z”
        L{DNSServerFactory.messageReceived} passes messages with an opcode of
        C{OP_STATUS} on to L{DNSServerFactory.handleStatus}.
        ÚhandleStatusr˜   N)r–   r   rr   Z	OP_STATUSr;   r   r   r   Útest_statusMessageReceived0  s    z0DNSServerFactoryTests.test_statusMessageReceivedc                 C   s   |   dtjtjd�¡ dS )z”
        L{DNSServerFactory.messageReceived} passes messages with an opcode of
        C{OP_NOTIFY} on to L{DNSServerFactory.handleNotify}.
        ÚhandleNotifyr˜   N)r–   r   rr   Z	OP_NOTIFYr;   r   r   r   Útest_notifyMessageReceived7  s    z0DNSServerFactoryTests.test_notifyMessageReceivedc                 C   s   |   dtjtjd�¡ dS )zß
        L{DNSServerFactory.messageReceived} passes messages with an opcode of
        C{OP_UPDATE} on to L{DNSServerFactory.handleOther}.

        This may change if the implementation ever covers update messages.
        ÚhandleOtherr˜   N)r–   r   rr   Z	OP_UPDATEr;   r   r   r   Útest_updateMessageReceived>  s    z0DNSServerFactoryTests.test_updateMessageReceivedc                 C   s‚   t ƒ t ƒ  }}t ¡ }| |¡ |  |j|g¡ | |¡ |  |j||g¡ | |¡ |  |j|g¡ | |¡ |  |jg ¡ dS )zÌ
        The C{connectionMade} and C{connectionLost} methods of
        L{DNSServerFactory} cooperate to keep track of all L{DNSProtocol}
        objects created by a factory which are connected.
        N)rB   r   r9   ZconnectionMader5   ÚconnectionsZconnectionLost)r   ZprotoAZprotoBr_   r   r   r   Útest_connectionTrackingG  s    



z-DNSServerFactoryTests.test_connectionTrackingc                 C   sh   t  ¡ }| d¡ | d¡ t ¡ }tƒ |_| jtj|j	|t
ƒ dd�}|j\\}}|  ||jd ¡ dS )z¸
        L{server.DNSServerFactory.handleQuery} takes the first query from the
        supplied message and dispatches it to
        L{server.DNSServerFactory.resolver.query}.
        ó   one.example.coms   two.example.comNr�   r   )r   rr   r{   r   r9   r+   r:   r‡   r,   r—   r*   r   r5   r“   )r   r2   re   r‰   r-   r   r   r   r   Útest_handleQueryX  s    

ûz&DNSServerFactoryTests.test_handleQueryc                    sœ   t  ¡ }t ¡ ‰ G ‡ fdd„dƒ}|ƒ |_g ‰‡fdd„}||_t ¡ }| d¡ t	ƒ }t
ƒ }|j|||d� t
ƒ }ˆ  |¡ |  ˆ||||fi fg¡ dS )aC  
        L{server.DNSServerFactory.handleQuery} adds
        L{server.DNSServerFactory.resolver.gotResolverResponse} as a callback to
        the deferred returned by L{server.DNSServerFactory.resolver.query}. It
        is called with the query response, the original protocol, message and
        origin address.
        c                       s   e Zd Z‡ fdd„ZdS )zDDNSServerFactoryTests.test_handleQueryCallback.<locals>.FakeResolverc                    s   ˆ S r   r   r   ©Údr   r   r-   {  s    zJDNSServerFactoryTests.test_handleQueryCallback.<locals>.FakeResolver.queryN©r   r   r   r-   r   r¦   r   r   ÚFakeResolverz  s   r©   c                     s   ˆ   | |f¡ d S r   r�   r   )ÚgotResolverResponseArgsr   r   ÚfakeGotResolverResponse‚  s    zODNSServerFactoryTests.test_handleQueryCallback.<locals>.fakeGotResolverResponser¤   r�   N)r   r9   r   ÚDeferredr:   ÚgotResolverResponser   rr   r{   r*   rB   r—   Úcallbackr5   )r   re   r©   r«   r2   rb   rˆ   ZdummyResponser   )r§   rª   r   Útest_handleQueryCallbackn  s$    

þz.DNSServerFactoryTests.test_handleQueryCallbackc                    s¢   t  ¡ }t ¡ ‰ G ‡ fdd„dƒ}|ƒ |_g ‰‡fdd„}||_t ¡ }| d¡ t	ƒ }t
ƒ }|j|||d� t tƒ ¡}ˆ  |¡ |  ˆ||||fi fg¡ dS )a?  
        L{server.DNSServerFactory.handleQuery} adds
        L{server.DNSServerFactory.resolver.gotResolverError} as an errback to
        the deferred returned by L{server.DNSServerFactory.resolver.query}. It
        is called with the query failure, the original protocol, message and
        origin address.
        c                       s   e Zd Z‡ fdd„ZdS )zCDNSServerFactoryTests.test_handleQueryErrback.<locals>.FakeResolverc                    s   ˆ S r   r   r   r¦   r   r   r-   £  s    zIDNSServerFactoryTests.test_handleQueryErrback.<locals>.FakeResolver.queryNr¨   r   r¦   r   r   r©   ¢  s   r©   c                     s   ˆ   | |f¡ d S r   r�   r   )ÚgotResolverErrorArgsr   r   ÚfakeGotResolverErrorª  s    zKDNSServerFactoryTests.test_handleQueryErrback.<locals>.fakeGotResolverErrorr¤   r�   N)r   r9   r   r¬   r:   ÚgotResolverErrorr   rr   r{   r*   rB   r—   r	   ÚFailurer%   Zerrbackr5   )r   re   r©   r±   r2   rb   rˆ   ZstubFailurer   )r§   r°   r   Útest_handleQueryErrback–  s$    

 ÿz-DNSServerFactoryTests.test_handleQueryErrbackc                 C   st   t  ¡ }g }g }g }| jtj|j|||ftƒ t ¡ dd�}|j\\}}|  	|j
|¡ |  	|j|¡ |  	|j|¡ dS )zÁ
        L{server.DNSServerFactory.gotResolverResponse} accepts a tuple of
        resource record lists and triggers a response message containing those
        resource record lists.
        N©r   r   r   )r   r9   r‡   r&   r'   r­   r   rr   r   r]   ÚanswersÚ	authorityÚ
additional)r   re   r¶   r·   r¸   r‰   r   r   r   r   r   Útest_gotResolverResponse½  s     úz.DNSServerFactoryTests.test_gotResolverResponsec              
   C   sd   t ƒ }t|_t ¡ }d|_| jt|jg g g fd|dd�}|  	dt
|tjg g g d�f|j|jf¡ dS )z–
        L{server.DNSServerFactory.gotResolverResponse} calls
        L{server.DNSServerFactory._responseFromMessage} to generate a response.
        rl   Nrµ   r   )r   r�   r¶   r·   r¸   )r   r   Ú_responseFromMessager   rr   r…   r‡   r   r­   r5   ÚdictÚOKr   r   ©r   r_   Úrequestr‰   r   r   r   Ú0test_gotResolverResponseCallsResponseFromMessageÕ  s0    úûþ

õzFDNSServerFactoryTests.test_gotResolverResponseCallsResponseFromMessagec                 C   s4   t  ¡ }tjddd�}|j|d�f}|  ||¡ dS )zŽ
        L{server.DNSServerFactory._responseFromMessage} generates a response
        message which is a copy of the request message.
        F)ÚanswerÚrecAv©r   N)r   r9   r   rr   rº   ZassertIsNot©r   r_   r¾   Úresponser   r   r   Ú"test_responseFromMessageNewMessageö  s    z8DNSServerFactoryTests.test_responseFromMessageNewMessagec                 C   sT   t  ¡ }d|_|jtjdd�d�}d|_|jtjdd�d�}|  d|j|jf¡ dS )zÇ
        L{server.DNSServerFactory._responseFromMessage} generates a response
        message whose C{recAV} attribute is L{True} if
        L{server.DNSServerFactory.canRecurse} is L{True}.
        TF)rÁ   rÂ   ©TFN)r   r9   rT   rº   r   rr   r5   rÁ   ©r   r_   Z	response1Z	response2r   r   r   Ú*test_responseFromMessageRecursionAvailable  s    z@DNSServerFactoryTests.test_responseFromMessageRecursionAvailablec                 C   s6   t  ¡ }t ¡ }d|_|j|d�}|  |j|j¡ dS )z¿
        L{server.DNSServerFactory._responseFromMessage} generates a response
        message whose C{timeReceived} attribute has the same value as that found
        on the request.
        iÒ  rÂ   N)r   r9   r   rr   r…   rº   r5   rÃ   r   r   r   Ú$test_responseFromMessageTimeReceived  s
    z:DNSServerFactoryTests.test_responseFromMessageTimeReceivedc                 C   s6   t  ¡ }t ¡ }d|_|j|d�}|  |j|j¡ dS )zº
        L{server.DNSServerFactory._responseFromMessage} generates a response
        message whose C{maxSize} attribute has the same value as that found
        on the request.
        r   rÂ   N)r   r9   r   rr   ZmaxSizerº   r5   rÃ   r   r   r   Útest_responseFromMessageMaxSize  s
    z5DNSServerFactoryTests.test_responseFromMessageMaxSizec                 C   s   |   tjtjj¡ dS )z{
        L{server.DNSServerFactory} has a C{_messageFactory} attribute which is
        L{dns.Message} by default.
        N)r]   r   rr   r   r9   Ú_messageFactoryr;   r   r   r   Útest_messageFactory(  s    z)DNSServerFactoryTests.test_messageFactoryc              
   C   sd   t  ¡ }|  tdt¡ t ¡ }| jt|j|tj	d�}|  
dt|j|tj	|jdd�f|j|jf¡ dS )a4  
        L{server.DNSServerFactory._responseFromMessage} calls
        C{dns._responseFromMessage} to generate a response
        message from the request message. It supplies the request message and
        other keyword arguments which should be passed to the response message
        initialiser.
        rº   ©r   r�   r   F)ZresponseConstructorr   r�   rÁ   ÚauthN)r   r9   r„   r   r   rr   r‡   r   rº   r¼   r5   r»   rË   rT   r   r   r½   r   r   r   Ú+test_responseFromMessageCallsMessageFactory/  s*       ÿûþ

õzADNSServerFactoryTests.test_responseFromMessageCallsMessageFactoryc                 C   sX   t  ¡ }|jt ¡ tjdd�gd�}|jt ¡ tjdd�gd�}|  d|j|jf¡ dS )z¥
        L{server.DNSServerFactory._responseFromMessage} marks the response
        message as authoritative if any of the answer records are authoritative.
        T)rÎ   )r   r¶   FrÆ   N)r   r9   rº   r   rr   ÚRRHeaderr5   rÎ   rÇ   r   r   r   Ú,test_responseFromMessageAuthoritativeMessageL  s     ÿ ÿ
þzBDNSServerFactoryTests.test_responseFromMessageAuthoritativeMessagec              	   C   sR   t dd�}t ¡ g}t ¡ g}t ¡ g}t| dg|j|||ftƒ t ¡ dd� dS )zŒ
        L{server.DNSServerFactory.gotResolverResponse} logs the total number of
        records in the response if C{verbose > 0}.
        rl   rY   zLookup found 3 recordsNrµ   )r   r   rÐ   r7   r­   r*   rr   )r   re   r¶   r·   r¸   r   r   r   Útest_gotResolverResponseLogging]  s    



ùz5DNSServerFactoryTests.test_gotResolverResponseLoggingc                 C   s    t tƒ gd�}t ¡ }| d¡ t ¡ g}g }g }| jtj|j|||ft	ƒ |dd�}|j
\\}\}}	}
}|  |jjd¡ |  ||¡ |  |	|¡ |  |
|¡ dS )z“
        L{server.DNSServerFactory.gotResolverResponse} caches the response if at
        least one cache was provided in the constructor.
        rE   s   example.comNrµ   )r   r.   r   rr   r{   rÐ   r‡   r/   r­   r*   r   r5   rx   r]   )r   re   r2   ZexpectedAnswersZexpectedAuthorityZexpectedAdditionalr‰   r-   r¶   r·   r¸   r   r   r   r   Útest_gotResolverResponseCachingq  s&    

úz5DNSServerFactoryTests.test_gotResolverResponseCachingc                 C   sb   t ƒ }t|_t ¡ }d|_| jt|jt	 
t ¡ ¡d|dd�}|  dt|tjd�f|j|jf¡ dS )z“
        L{server.DNSServerFactory.gotResolverError} calls
        L{server.DNSServerFactory._responseFromMessage} to generate a response.
        rl   Nrµ   r   rÍ   )r   r   rº   r   rr   r…   r‡   r   r²   r	   r³   r   ÚDomainErrorr5   r»   ÚENAMEr   r   r½   r   r   r   Ú-test_gotResolverErrorCallsResponseFromMessage�  s     ú 
ÿzCDNSServerFactoryTests.test_gotResolverErrorCallsResponseFromMessagec                 C   sL   t  ¡ }| jtj|jt |¡tƒ t 	¡ dd�}|j
\\}}|  |j|¡ dS )a{  
        L{server.DNSServerFactory.gotResolver} accepts a L{failure.Failure} and
        triggers a response message whose rCode corresponds to the DNS error
        contained in the C{Failure}.

        @param responseError: The L{Exception} instance which is expected to
            trigger C{expectedMessageCode} when it is supplied to
            C{gotResolverError}
        @type responseError: L{Exception}

        @param expectedMessageCode: The C{rCode} which is expected in the
            message returned by C{gotResolverError} in response to
            C{responseError}.
        @type expectedMessageCode: L{int}
        Nrµ   )r   r9   r‡   r&   r'   r²   r	   r³   r   rr   r   r5   r�   )r   ZresponseErrorZexpectedMessageCodere   r‰   r   r   r   r   r   Ú_assertMessageRcodeForError¤  s    úz1DNSServerFactoryTests._assertMessageRcodeForErrorc                 C   s   |   t ¡ tj¡ dS )z¦
        L{server.DNSServerFactory.gotResolver} triggers a response message with
        an C{rCode} of L{dns.ENAME} if supplied with a L{error.DomainError}.
        N)r×   r   rÔ   r   rÕ   r;   r   r   r   Ú test_gotResolverErrorDomainErrorÁ  s    z6DNSServerFactoryTests.test_gotResolverErrorDomainErrorc                 C   s   |   t ¡ tj¡ dS )z»
        L{server.DNSServerFactory.gotResolver} triggers a response message with
        an C{rCode} of L{dns.ENAME} if supplied with a
        L{error.AuthoritativeDomainError}.
        N)r×   r   ZAuthoritativeDomainErrorr   rÕ   r;   r   r   r   Ú-test_gotResolverErrorAuthoritativeDomainErrorÈ  s    zCDNSServerFactoryTests.test_gotResolverErrorAuthoritativeDomainErrorc                 C   s.   |   tƒ tj¡ |  t¡}|  t|ƒd¡ dS )zÂ
        L{server.DNSServerFactory.gotResolver} triggers a response message with
        an C{rCode} of L{dns.ESERVER} if supplied with another type of error and
        logs the error.
        rl   N)r×   ÚKeyErrorr   ZESERVERZflushLoggedErrorsr5   Úlen)r   r‰   r   r   r   Útest_gotResolverErrorOtherErrorÐ  s    
z5DNSServerFactoryTests.test_gotResolverErrorOtherErrorc              	   C   s8   t dd�}t| dg|jt t ¡ ¡tƒ t 	¡ dd� dS )zZ
        L{server.DNSServerFactory.gotResolver} logs a message if C{verbose > 0}.
        rl   rY   zLookup failedNrµ   )
r   r7   r²   r	   r³   r   rÔ   r*   r   rr   rj   r   r   r   Útest_gotResolverErrorLoggingÚ  s    
ùz2DNSServerFactoryTests.test_gotResolverErrorLoggingc                    sŠ   t  ¡ }g ‰ ‡ fdd„|_tjddd�}tƒ tƒ g|_tƒ tƒ g|_tƒ tƒ g|_|j	t
 t ¡ ¡d|dd� |  tjddd�gˆ ¡ dS )	zÙ
        L{server.DNSServerFactory.gotResolverError} does not allow request
        attributes to leak into the response ie it sends a response with AD, CD
        set to 0 and empty response record sections.
        c                    s
   ˆ   |¡S r   r�   ©r   rÄ   r   ©Ú	responsesr   r   r‚   ñ  s   ÿzUDNSServerFactoryTests.test_gotResolverErrorResetsResponseAttributes.<locals>.<lambda>T©ZauthenticDataZcheckingDisabledNrµ   é   ©r�   rÀ   )r   r9   r    r   rr   rB   r¶   r·   r¸   r²   r	   r³   r   rÔ   r5   ©r   r_   r¾   r   rß   r   Ú-test_gotResolverErrorResetsResponseAttributesé  s    üzCDNSServerFactoryTests.test_gotResolverErrorResetsResponseAttributesc                    s†   t  ¡ }g ‰ ‡ fdd„|_tjddd�}tƒ tƒ g|_tƒ tƒ g|_tƒ tƒ g|_|j	g g g fd|dd� |  
tjddd�gˆ ¡ dS )	a  
        L{server.DNSServerFactory.gotResolverResponse} does not allow request
        attributes to leak into the response ie it sends a response with AD, CD
        set to 0 and none of the records in the request answer sections are
        copied to the response.
        c                    s
   ˆ   |¡S r   r�   rÞ   rß   r   r   r‚   
  s   ÿzXDNSServerFactoryTests.test_gotResolverResponseResetsResponseAttributes.<locals>.<lambda>Trá   Nrµ   r   rã   )r   r9   r    r   rr   rB   r¶   r·   r¸   r­   r5   rä   r   rß   r   Ú0test_gotResolverResponseResetsResponseAttributes  s       ÿzFDNSServerFactoryTests.test_gotResolverResponseResetsResponseAttributesc                 C   sZ   t  ¡ }tƒ }t ¡ }| jtj|jtƒ ||d�}|j	\}}|  
|||f¡ |  
|i ¡ dS )zµ
        If L{server.DNSServerFactory.sendReply} is supplied with a protocol
        *and* an address tuple it will supply that address to
        C{protocol.writeMessage}.
        rµ   N)r   rr   rB   r   r9   r‡   r&   r'   r    r   r5   )r   r2   rˆ   re   r‰   r   r   r   r   r   Útest_sendReplyWithAddress  s    û
z/DNSServerFactoryTests.test_sendReplyWithAddressc                 C   sR   t  ¡ }t ¡ }| jtj|jtƒ |dd�}|j\}}|  	||f¡ |  	|i ¡ dS )zµ
        If L{server.DNSServerFactory.sendReply} is supplied with a protocol but
        no address tuple it will supply only a message to
        C{protocol.writeMessage}.
        Nrµ   )
r   rr   r   r9   r‡   r&   r'   r    r   r5   )r   r2   re   r‰   r   r   r   r   r   Útest_sendReplyWithoutAddress,  s    û
z2DNSServerFactoryTests.test_sendReplyWithoutAddressc                 C   sN   |   tjddd„ ¡ t ¡ }d|_tjdd�}t| ddg|jt	ƒ |d	d
� d	S )z…
        If L{server.DNSServerFactory.sendReply} logs a "no answers" message if
        the supplied message has no answers.
        r   c                   S   s   dS ©Ni‚Q r   r   r   r   r   r‚   D  rƒ   zFDNSServerFactoryTests.test_sendReplyLoggingNoAnswers.<locals>.<lambda>é�Q r}   rY   zReplying with no answersú Processed query in 1.000 secondsNrµ   )
r„   r   r   r   rr   r…   r9   r7   r    r*   rt   r   r   r   Útest_sendReplyLoggingNoAnswers?  s    úz4DNSServerFactoryTests.test_sendReplyLoggingNoAnswersc                 C   s    |   tjddd„ ¡ t ¡ }|j tjt d¡d�¡ |j	 tjt d¡d�¡ |j
 tjt d¡d�¡ d|_tjdd�}t| d	d
ddg|jtƒ |dd� dS )z»
        If L{server.DNSServerFactory.sendReply} logs a message for answers,
        authority, additional if the supplied a message has records in any of
        those sections.
        r   c                   S   s   dS ré   r   r   r   r   r   r‚   W  rƒ   zHDNSServerFactoryTests.test_sendReplyLoggingWithAnswers.<locals>.<lambda>z	127.0.0.1)Úpayloadrê   r}   rY   z*Answers are <A address=127.0.0.1 ttl=None>z+Authority is <A address=127.0.0.1 ttl=None>z,Additional is <A address=127.0.0.1 ttl=None>rë   Nrµ   )r„   r   r   r   rr   r¶   r4   rÐ   ZRecord_Ar·   r¸   r…   r9   r7   r    r*   rt   r   r   r   Ú test_sendReplyLoggingWithAnswersQ  s&    üõz6DNSServerFactoryTests.test_sendReplyLoggingWithAnswersc                 C   sF   t  ¡ }| jtj|jt ¡ tƒ dd�}|j\\}}|  	|j
tj¡ dS )z—
        L{server.DNSServerFactory.handleInverseQuery} triggers the sending of a
        response message with C{rCode} set to L{dns.ENOTIMP}.
        Nr�   )r   r9   r‡   r&   r'   rš   r   rr   r   r5   r�   ÚENOTIMP©r   re   r‰   r   r   r   r   r   Útest_handleInverseQueryl  s    ûz-DNSServerFactoryTests.test_handleInverseQueryc                 C   s,   t dd�}t| dg|jt ¡ tƒ dd� dS )zz
        L{server.DNSServerFactory.handleInverseQuery} logs the message origin
        address if C{verbose > 0}.
        rl   rY   zInverse query from ('::1', 53)©z::1ro   r�   N)r   r7   rš   r   rr   r*   rj   r   r   r   Útest_handleInverseQueryLogging}  s    
úz4DNSServerFactoryTests.test_handleInverseQueryLoggingc                 C   sF   t  ¡ }| jtj|jt ¡ tƒ dd�}|j\\}}|  	|j
tj¡ dS )z‘
        L{server.DNSServerFactory.handleStatus} triggers the sending of a
        response message with C{rCode} set to L{dns.ENOTIMP}.
        Nr�   )r   r9   r‡   r&   r'   rœ   r   rr   r   r5   r�   rï   rð   r   r   r   Útest_handleStatusŒ  s    ûz'DNSServerFactoryTests.test_handleStatusc                 C   s,   t dd�}t| dg|jt ¡ tƒ dd� dS )zt
        L{server.DNSServerFactory.handleStatus} logs the message origin address
        if C{verbose > 0}.
        rl   rY   zStatus request from ('::1', 53)rò   r�   N)r   r7   rœ   r   rr   r*   rj   r   r   r   Útest_handleStatusLogging�  s    
úz.DNSServerFactoryTests.test_handleStatusLoggingc                 C   sF   t  ¡ }| jtj|jt ¡ tƒ dd�}|j\\}}|  	|j
tj¡ dS )z‘
        L{server.DNSServerFactory.handleNotify} triggers the sending of a
        response message with C{rCode} set to L{dns.ENOTIMP}.
        Nr�   )r   r9   r‡   r&   r'   rž   r   rr   r   r5   r�   rï   rð   r   r   r   Útest_handleNotify¬  s    ûz'DNSServerFactoryTests.test_handleNotifyc                 C   s,   t dd�}t| dg|jt ¡ tƒ dd� dS )zt
        L{server.DNSServerFactory.handleNotify} logs the message origin address
        if C{verbose > 0}.
        rl   rY   zNotify message from ('::1', 53)rò   r�   N)r   r7   rž   r   rr   r*   rj   r   r   r   Útest_handleNotifyLogging½  s    
úz.DNSServerFactoryTests.test_handleNotifyLoggingc                 C   sF   t  ¡ }| jtj|jt ¡ tƒ dd�}|j\\}}|  	|j
tj¡ dS )z�
        L{server.DNSServerFactory.handleOther} triggers the sending of a
        response message with C{rCode} set to L{dns.ENOTIMP}.
        Nr�   )r   r9   r‡   r&   r'   r    r   rr   r   r5   r�   rï   rð   r   r   r   Útest_handleOtherÌ  s    ûz&DNSServerFactoryTests.test_handleOtherc                 C   s,   t dd�}t| dg|jt ¡ tƒ dd� dS )zs
        L{server.DNSServerFactory.handleOther} logs the message origin address
        if C{verbose > 0}.
        rl   rY   z$Unknown op code (0) from ('::1', 53)rò   r�   N)r   r7   r    r   rr   r*   rj   r   r   r   Útest_handleOtherLoggingÝ  s    
úz-DNSServerFactoryTests.test_handleOtherLoggingN)Dr   r   r   r   r<   r?   rD   rG   rJ   rO   rQ   rR   rU   rV   rX   r[   r\   r^   rg   rk   rm   ru   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Ó   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   Û   s‚   		('!
r8   N)r   Zzope.interface.verifyr   Ztwisted.internetr   Ztwisted.internet.interfacesr   Ztwisted.namesr   r   r   r   Ztwisted.pythonr	   r
   Ztwisted.trialr   r%   r   r   r9   r   r!   r&   r*   r+   r.   r7   ZTestCaser8   r   r   r   r   Ú<module>   s    
	! 