o
    ¯bÇ¢  ã                   @   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                   @   ó   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   ú@/usr/lib/python3/dist-packages/twisted/names/test/test_server.pyÚ__init__   s   
zRaisedArguments.__init__N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r   r      ó    r   c                  O   s
   t | |ƒ‚)z¡
    Raise a L{RaisedArguments} exception containing the supplied arguments.

    Used as a fake when testing the call signatures of  methods and functions.
    )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   ó   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   r   )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;   ó    z$NoResponseDNSServerFactory.sendReplyN)r   r   r   r   r"   r#   r   r   r   r   r   $   s    	r   c                   @   ó(   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                   @   ó   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   ó    r*   c                 O   ó   |   ||¡‚)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}
        )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                   @   r%   )ÚRaisingProtocolzm
    A partial fake L{IProtocol} whose methods raise an exception containing the
    supplied arguments.
    c                   @   r'   )z%RaisingProtocol.WriteMessageArgumentsr(   Nr)   r   r   r   r   ÚWriteMessageArgumentsh   r+   r/   c                 O   r,   ©z»
        Raises the supplied arguments.

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

        @param kwargs: Keyword args
        @type kwargs: L{dict}
        )r/   r   r   r   r   ÚwriteMessagem   ó   
zRaisingProtocol.writeMessageN)r   r   r   r   r-   r/   r1   r   r   r   r   r.   b   ó    r.   c                   @   r   )ÚNoopProtocolzT
    A partial fake L{dns.DNSProtocolMixin} with a noop L{writeMessage} method.
    c                 O   r   )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   r1      r$   zNoopProtocol.writeMessageN)r   r   r   r   r1   r   r   r   r   r4   z   r   r4   c                   @   r%   )ÚRaisingResolverzm
    A partial fake L{IResolver} whose methods raise an exception containing the
    supplied arguments.
    c                   @   r'   )zRaisingResolver.QueryArgumentsr(   Nr)   r   r   r   r   ÚQueryArguments‘   r+   r6   c                 O   r,   r0   )r6   r   r   r   r   Úquery–   r2   zRaisingResolver.queryN)r   r   r   r   r-   r6   r7   r   r   r   r   r5   ‹   r3   r5   c                   @   r%   )ÚRaisingCachez}
    A partial fake L{twisted.names.cache.Cache} whose methods raise an exception
    containing the supplied arguments.
    c                   @   r'   )z!RaisingCache.CacheResultArgumentsr(   Nr)   r   r   r   r   ÚCacheResultArguments©   r+   r9   c                 O   r,   r0   )r9   r   r   r   r   ÚcacheResult®   r2   zRaisingCache.cacheResultN)r   r   r   r   r-   r9   r:   r   r   r   r   r8   £   r3   r8   c                 O   sH   g }t  |j¡ |  t j|j¡ ||i |¤Ž |  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
   ÚaddObserverÚappendÚ
addCleanupÚremoveObserverÚassertEqual)ÚtestCaseÚexpectedMessagesÚcallabler   r   ÚloggedMessagesr   r   r   ÚassertLogMessage»   s
   rG   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)ÚassertIsInstancer   ÚDNSServerFactoryÚresolverr   ÚResolverChain©r   r   r   r   Útest_resolverTypeà   ó   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©rB   r   rJ   rK   Ú	resolversrM   r   r   r   Útest_resolverDefaultEmptyç   rO   z/DNSServerFactoryTests.test_resolverDefaultEmptyc                 C   ó&   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©ÚobjectrB   r   rJ   rK   rQ   ©r   ÚdummyResolverr   r   r   Útest_authoritiesî   ó
   þz&DNSServerFactoryTests.test_authoritiesc                 C   rS   )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}.
        ©ÚcachesNrU   rW   r   r   r   Útest_cachesú   rZ   z!DNSServerFactoryTests.test_cachesc                 C   rS   )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}.
        ©ÚclientsNrU   rW   r   r   r   Útest_clients  rZ   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                   @   ó   e Zd ZdS )z@DNSServerFactoryTests.test_resolverOrder.<locals>.DummyAuthorityN©r   r   r   r   r   r   r   ÚDummyAuthority  ó    rc   c                   @   ra   )z<DNSServerFactoryTests.test_resolverOrder.<locals>.DummyCacheNrb   r   r   r   r   Ú
DummyCache  rd   re   c                   @   ra   )z=DNSServerFactoryTests.test_resolverOrder.<locals>.DummyClientNrb   r   r   r   r   ÚDummyClient  rd   rf   )rT   r\   r_   NrP   )r   rc   re   rf   r   r   r   Útest_resolverOrder  s   ÿüz(DNSServerFactoryTests.test_resolverOrderc                 C   ó   |   t ¡ j¡ dS )zI
        L{server.DNSServerFactory.cache} is L{None} by default.
        N)ÚassertIsNoner   rJ   ÚcacherM   r   r   r   Útest_cacheDefault(  ó   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}.
        r[   N)rV   rB   r   rJ   rj   rW   r   r   r   Útest_cacheOverride.  s
   þz(DNSServerFactoryTests.test_cacheOverridec                 C   rh   )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   rJ   Ú
canRecurserM   r   r   r   Útest_canRecurseDefault9  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}.
        Nr^   T)rB   r   rJ   ro   rM   r   r   r   Útest_canRecurseOverrideA  s   z-DNSServerFactoryTests.test_canRecurseOverridec                 C   rh   )zJ
        L{server.DNSServerFactory.verbose} defaults to L{False}.
        N)rn   r   rJ   ÚverboserM   r   r   r   Útest_verboseDefaultH  rl   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©rr   N)Ú
assertTruer   rJ   rr   rM   r   r   r   Útest_verboseOverrideN  rO   z*DNSServerFactoryTests.test_verboseOverridec                 C   s   |   tttjƒ¡ dS )zL
        L{server.DNSServerFactory} implements L{IProtocolFactory}.
        N)ru   r   r   r   rJ   rM   r   r   r   Útest_interfaceU  ó   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   rJ   r    r   ÚDNSProtocolrM   r   r   r   Útest_defaultProtocol[  rx   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   ÚFakeProtocolh  s    r}   c                     s   | ˆ _ |ˆ _ˆ S r   r   r   ©ÚstubProtocolr   r   ÚfakeProtocolFactoryo  s   zUDNSServerFactoryTests.test_buildProtocolProtocolOverride.<locals>.fakeProtocolFactoryN)Úaddr)r   rJ   r    ÚbuildProtocolrB   r   r   )r   r}   r€   ÚfÚpr   r~   r   Ú"test_buildProtocolProtocolOverridea  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   rJ   rG   Ú_verboseLog©r   rƒ   r   r   r   Útest_verboseLogQuietz  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}.
        é   rt   r†   Nr‡   r‰   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}.
        r‹   rt   z$Empty query from ('192.0.2.100', 53)N©z192.0.2.100é5   ©r   Úprotor!   )r   ÚMessager   rG   ÚmessageReceived©r   r<   rƒ   r   r   r   Ú"test_messageReceivedLoggingNoQuery‰  s   

úz8DNSServerFactoryTests.test_messageReceivedLoggingNoQueryc                 C   óN   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Útyper‹   rt   z&MX AAAA query from ('192.0.2.100', 53)Nr�   r�   ©r   r‘   ÚaddQueryÚMXÚAAAAr   rG   r’   r“   r   r   r   Útest_messageReceivedLogging1š  s   

úz2DNSServerFactoryTests.test_messageReceivedLogging1c                 C   r•   )	zŽ
        L{server.DNSServerFactory.messageReceived} logs the repr of all queries
        in the message if C{verbose} is set to C{2}.
        r–   r—   é   rt   zT<Query example.com MX IN> <Query example.com AAAA IN> query from ('192.0.2.100', 53)Nr�   r�   rš   r“   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 r   r   r   ©Útr   r   Ú<lambda>Ë  r$   zEDNSServerFactoryTests.test_messageReceivedTimestamp.<locals>.<lambda>Nr�   )
r   r‘   r   rV   Úpatchr   r¡   r’   rB   ÚtimeReceivedr“   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.
        r�   N)	r   r‘   rV   r&   ÚassertRaisesr*   r’   r   rB   )r   r   ÚdummyProtocolÚdummyAddressrƒ   Ú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                   @   ra   )zFDNSServerFactoryTests.test_allowQueryFalse.<locals>.SendReplyExceptionNrb   r   r   r   r   ÚSendReplyExceptioní  rd   r®   c                       s    e Zd Zdd„ Z‡ fdd„ZdS )zKDNSServerFactoryTests.test_allowQueryFalse.<locals>.RaisingDNSServerFactoryc                 _   r   )NFr   r   r   r   r   r"   ñ  ó   zVDNSServerFactoryTests.test_allowQueryFalse.<locals>.RaisingDNSServerFactory.allowQueryc                    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&   Nr�   )r-   r   rJ   r©   r’   r   r‘   r   rB   ÚrCodeÚEREFUSED)r   r&   rƒ   r¬   r�   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   ©r?   ©r   r    r!   ©ÚreceivedMessagesr   r   ÚfakeHandler  s   z?DNSServerFactoryTests._messageReceivedTest.<locals>.fakeHandler)Úqueriesr4   r   rJ   Úsetattrr’   rB   )r   Ú
methodNamer   r¸   r    r|   r   r¶   r   Ú_messageReceivedTest  s   
z*DNSServerFactoryTests._messageReceivedTestc                 C   ó   |   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©ÚopCodeN)r¼   r   r‘   ÚOP_QUERYrM   r   r   r   Útest_queryMessageReceived  ó   z/DNSServerFactoryTests.test_queryMessageReceivedc                 C   r½   )z›
        L{DNSServerFactory.messageReceived} passes messages with an opcode of
        C{OP_INVERSE} on to L{DNSServerFactory.handleInverseQuery}.
        ÚhandleInverseQueryr¿   N)r¼   r   r‘   Ú
OP_INVERSErM   r   r   r   Ú test_inverseQueryMessageReceived&  s   ÿz6DNSServerFactoryTests.test_inverseQueryMessageReceivedc                 C   r½   )z”
        L{DNSServerFactory.messageReceived} passes messages with an opcode of
        C{OP_STATUS} on to L{DNSServerFactory.handleStatus}.
        ÚhandleStatusr¿   N)r¼   r   r‘   Ú	OP_STATUSrM   r   r   r   Útest_statusMessageReceived/  rÃ   z0DNSServerFactoryTests.test_statusMessageReceivedc                 C   r½   )z”
        L{DNSServerFactory.messageReceived} passes messages with an opcode of
        C{OP_NOTIFY} on to L{DNSServerFactory.handleNotify}.
        ÚhandleNotifyr¿   N)r¼   r   r‘   Ú	OP_NOTIFYrM   r   r   r   Útest_notifyMessageReceived6  rÃ   z0DNSServerFactoryTests.test_notifyMessageReceivedc                 C   r½   )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   r‘   Ú	OP_UPDATErM   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)rV   r   rJ   ÚconnectionMaderB   ÚconnectionsÚconnectionLost)r   ÚprotoAÚprotoBr|   r   r   r   Útest_connectionTrackingF  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   r‘   r›   r   rJ   r5   rK   r©   r6   r¾   r4   r   rB   r¹   )r   r<   rƒ   r¬   r7   r   r   r   r   Útest_handleQueryW  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                       ó   e Zd Z‡ fdd„ZdS )zDDNSServerFactoryTests.test_handleQueryCallback.<locals>.FakeResolverc                    r¢   r   r   r   ©Údr   r   r7   z  r¯   zJDNSServerFactoryTests.test_handleQueryCallback.<locals>.FakeResolver.queryN©r   r   r   r7   r   rÙ   r   r   ÚFakeResolvery  ó    rÜ   c                     ó   ˆ   | |f¡ d S r   r´   r   )ÚgotResolverResponseArgsr   r   ÚfakeGotResolverResponse�  ó   zODNSServerFactoryTests.test_handleQueryCallback.<locals>.fakeGotResolverResponserÖ   rµ   N)r   rJ   r   ÚDeferredrK   ÚgotResolverResponser   r‘   r›   r4   rV   r¾   ÚcallbackrB   )r   rƒ   rÜ   rà   r<   r   r«   ÚdummyResponser   )rÚ   rß   r   Útest_handleQueryCallbackm  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                       rØ   )zCDNSServerFactoryTests.test_handleQueryErrback.<locals>.FakeResolverc                    r¢   r   r   r   rÙ   r   r   r7   ¢  r¯   zIDNSServerFactoryTests.test_handleQueryErrback.<locals>.FakeResolver.queryNrÛ   r   rÙ   r   r   rÜ   ¡  rÝ   rÜ   c                     rÞ   r   r´   r   )ÚgotResolverErrorArgsr   r   ÚfakeGotResolverError©  rá   zKDNSServerFactoryTests.test_handleQueryErrback.<locals>.fakeGotResolverErrorrÖ   rµ   N)r   rJ   r   râ   rK   ÚgotResolverErrorr   r‘   r›   r4   rV   r¾   r	   ÚFailurer-   ÚerrbackrB   )r   rƒ   rÜ   rè   r<   r   r«   Ú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   rJ   r©   r.   r/   rã   r   r‘   r   ry   ÚanswersÚ	authorityÚ
additional)r   rƒ   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.
        r‹   Nrî   r   )r   r±   rï   rð   rñ   )r   r   Ú_responseFromMessager   r‘   r§   r©   r   rã   rB   Ú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   rJ   r   r‘   ró   Ú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   rJ   ro   ró   r   r‘   rB   rú   ©r   r|   Ú	response1Ú	response2r   r   r   Ú*test_responseFromMessageRecursionAvailable   s   z@DNSServerFactoryTests.test_responseFromMessageRecursionAvailablec                 C   ó6   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   rJ   r   r‘   r§   ró   rB   rý   r   r   r   Ú$test_responseFromMessageTimeReceived  ó
   z:DNSServerFactoryTests.test_responseFromMessageTimeReceivedc                 C   r  )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   rJ   r   r‘   ÚmaxSizeró   rB   rý   r   r   r   Útest_responseFromMessageMaxSize  r  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)ry   r   r‘   r   rJ   Ú_messageFactoryrM   r   r   r   Útest_messageFactory'  ó   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)ÚresponseConstructorr   r±   rú   ÚauthN)r   rJ   r¦   r   r   r‘   r©   r   ró   rõ   rB   rô   r
  ro   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   rJ   ró   r   r‘   ÚRRHeaderrB   r  r  r   r   r   Ú,test_responseFromMessageAuthoritativeMessageK  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}.
        r‹   rt   zLookup found 3 recordsNrî   )r   r   r  rG   rã   r4   r‘   )r   rƒ   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.
        r[   s   example.comNrî   )r   r8   r   r‘   r›   r  r©   r9   rã   r4   r   rB   r˜   ry   )r   rƒ   r<   ÚexpectedAnswersÚexpectedAuthorityÚexpectedAdditionalr¬   r7   rï   rð   rñ   r   r   r   r   Útest_gotResolverResponseCachingp  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.
        r‹   Nrî   r   r  )r   r   ró   r   r‘   r§   r©   r   ré   r	   rê   r   ÚDomainErrorrB   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   rJ   r©   r.   r/   ré   r	   rê   r   r‘   r   rB   r±   )r   ÚresponseErrorÚexpectedMessageCoderƒ   r¬   r   r   r   r   r   Ú_assertMessageRcodeForError£  s   úz1DNSServerFactoryTests._assertMessageRcodeForErrorc                 C   ó   |   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  rM   r   r   r   Ú test_gotResolverErrorDomainErrorÀ  r  z6DNSServerFactoryTests.test_gotResolverErrorDomainErrorc                 C   r  )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   ÚAuthoritativeDomainErrorr   r  rM   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.
        r‹   N)r  ÚKeyErrorr   ÚESERVERÚflushLoggedErrorsrB   Ú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}.
        r‹   rt   zLookup failedNrî   )
r   rG   ré   r	   rê   r   r  r4   r   r‘   r‰   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 r   r´   ©r    rþ   r!   ©Ú	responsesr   r   r¥   ð  ó    ÿzUDNSServerFactoryTests.test_gotResolverErrorResetsResponseAttributes.<locals>.<lambda>T©ÚauthenticDataÚcheckingDisabledNrî   é   ©r±   rù   )r   rJ   r#   r   r‘   rV   rï   rð   rñ   ré   r	   rê   r   r  rB   ©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                    r(  r   r´   r)  r*  r   r   r¥   	  r,  zXDNSServerFactoryTests.test_gotResolverResponseResetsResponseAttributes.<locals>.<lambda>Tr-  Nrî   r   r1  )r   rJ   r#   r   r‘   rV   rï   rð   rñ   rã   rB   r2  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   r‘   rV   r   rJ   r©   r.   r/   r#   r   rB   )r   r<   r«   rƒ   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   r‘   r   rJ   r©   r.   r/   r#   r   rB   )r   r<   rƒ   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   r   ©Ni‚Q r   r   r   r   r   r¥   C  r$   zFDNSServerFactoryTests.test_sendReplyLoggingNoAnswers.<locals>.<lambda>é�Q rŸ   rt   zReplying with no answersú Processed query in 1.000 secondsNrî   )
r¦   r   r¡   r   r‘   r§   rJ   rG   r#   r4   r“   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| g d	¢|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   r   r7  r   r   r   r   r   r¥   V  r$   zHDNSServerFactoryTests.test_sendReplyLoggingWithAnswers.<locals>.<lambda>z	127.0.0.1)Úpayloadr8  rŸ   rt   )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>r9  Nrî   )r¦   r   r¡   r   r‘   rï   r?   r  ÚRecord_Arð   rñ   r§   rJ   rG   r#   r4   r“   r   r   r   Ú test_sendReplyLoggingWithAnswersP  s   
õz6DNSServerFactoryTests.test_sendReplyLoggingWithAnswersc                 C   óF   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   rJ   r©   r.   r/   rÄ   r   r‘   r   rB   r±   ÚENOTIMP©r   rƒ   r¬   r   r   r   r   r   Útest_handleInverseQueryk  ó   ûz-DNSServerFactoryTests.test_handleInverseQueryc                 C   ó,   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}.
        r‹   rt   zInverse query from ('::1', 53)©z::1rŽ   rµ   N)r   rG   rÄ   r   r‘   r4   r‰   r   r   r   Útest_handleInverseQueryLogging|  ó   

úz4DNSServerFactoryTests.test_handleInverseQueryLoggingc                 C   r>  )z‘
        L{server.DNSServerFactory.handleStatus} triggers the sending of a
        response message with C{rCode} set to L{dns.ENOTIMP}.
        Nrµ   )r   rJ   r©   r.   r/   rÇ   r   r‘   r   rB   r±   r?  r@  r   r   r   Útest_handleStatus‹  rB  z'DNSServerFactoryTests.test_handleStatusc                 C   rC  )zt
        L{server.DNSServerFactory.handleStatus} logs the message origin address
        if C{verbose > 0}.
        r‹   rt   zStatus request from ('::1', 53)rD  rµ   N)r   rG   rÇ   r   r‘   r4   r‰   r   r   r   Útest_handleStatusLoggingœ  rF  z.DNSServerFactoryTests.test_handleStatusLoggingc                 C   r>  )z‘
        L{server.DNSServerFactory.handleNotify} triggers the sending of a
        response message with C{rCode} set to L{dns.ENOTIMP}.
        Nrµ   )r   rJ   r©   r.   r/   rÊ   r   r‘   r   rB   r±   r?  r@  r   r   r   Útest_handleNotify«  rB  z'DNSServerFactoryTests.test_handleNotifyc                 C   rC  )zt
        L{server.DNSServerFactory.handleNotify} logs the message origin address
        if C{verbose > 0}.
        r‹   rt   zNotify message from ('::1', 53)rD  rµ   N)r   rG   rÊ   r   r‘   r4   r‰   r   r   r   Útest_handleNotifyLogging¼  rF  z.DNSServerFactoryTests.test_handleNotifyLoggingc                 C   r>  )z�
        L{server.DNSServerFactory.handleOther} triggers the sending of a
        response message with C{rCode} set to L{dns.ENOTIMP}.
        Nrµ   )r   rJ   r©   r.   r/   rÍ   r   r‘   r   rB   r±   r?  r@  r   r   r   Útest_handleOtherË  rB  z&DNSServerFactoryTests.test_handleOtherc                 C   rC  )zs
        L{server.DNSServerFactory.handleOther} logs the message origin address
        if C{verbose > 0}.
        r‹   rt   z$Unknown op code (0) from ('::1', 53)rD  rµ   N)r   rG   rÍ   r   r‘   r4   r‰   r   r   r   Útest_handleOtherLoggingÜ  rF  z-DNSServerFactoryTests.test_handleOtherLoggingN)Dr   r   r   r   rN   rR   rY   r]   r`   rg   rk   rm   rp   rq   rs   rv   rw   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'  r3  r4  r5  r6  r:  r=  rA  rE  rG  rH  rI  rJ  rK  rL  r   r   r   r   rH   Û   s„    		('!
rH   N)r   Úzope.interface.verifyr   Útwisted.internetr   Útwisted.internet.interfacesr   Útwisted.namesr   r   r   r   Útwisted.pythonr	   r
   Útwisted.trialr   r-   r   r   rJ   r   r&   r.   r4   r5   r8   rG   ÚTestCaserH   r   r   r   r   Ú<module>   s"   
	! 