
    Vh2d                        d Z ddlmZ ddlmZ ddlmZmZmZm	Z	 ddl
mZ ddlmZmZ ddlmZmZmZmZmZmZmZmZmZmZmZmZmZmZ ddlmZm Z  dd	l!m"Z" dd
l#m$Z$ ddl%m&Z& ddl'm(Z( ddl)m*Z*m+Z+ d Z,d Z- G d de+      Z. G d de/      Z0d Z1 G d de+      Z2g dZ3 ee       G d d             Z4 eee4        G d de*      Z5 G d d      Z6 e(jn                  e8d      Z9y )!z.
Test cases for Twisted.names' root resolver.
    )implementer)verifyClass)DeferredTimeoutErrorgatherResultssucceed)IResolverSimple)clientroot)CNAMEENAMEHSINNSOKAMessageNameQueryRecord_ARecord_CNAME	Record_NSRRHeader)DNSNameErrorResolverError)Resolver)MemoryReactor)msg)util)SynchronousTestCaseTestCasec                 ,    | \  }}}|d   j                   S )z
    From the result of a L{Deferred} returned by L{IResolver.lookupAddress},
    return the payload of the first record in the answer section.
    r   payloadresultsansauthadds       S/home/dcms/DCMS/lib/python3.12/site-packages/twisted/names/test/test_rootresolve.pygetOnePayloadr+   &   s    
 NCsq6>>    c                 4    t        |       j                         S )z
    From the result of a L{Deferred} returned by L{IResolver.lookupAddress},
    return the first IPv4 address from the answer section.
    )r+   
dottedQuadr&   s    r*   getOneAddressr0   /   s    
 !,,..r,   c                       e Zd ZdZd Zd Zd Zg g g efdZddZ	d Z
d Zd	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zy)RootResolverTestsz3
    Tests for L{twisted.names.root.Resolver}.
    c                 `   t               }t        g |      }|j                  t        dt        t
              dgd|      }|j                  j                         \  }}|j                  \  \  }}t               }	|	j                  |       | j                  |	j                  t        dt        t
              g       | j                  |	j                  g        | j                  |	j                  g        | j                  |	j                  g        g }
|j!                  |
j"                         | j                  |
g        |	j                  dd= d|	_        |	j                  j#                  t'        dt)        d                   |j*                  j-                  |	j/                         d       |
d	   S )
aK  
        Invoke L{Resolver._query} and verify that it sends the correct DNS
        query.  Deliver a canned response to the query and return whatever the
        L{Deferred} returned by L{Resolver._query} fires with.

        @param filter: The value to pass for the C{filter} parameter to
            L{Resolver._query}.
        )reactor   foo.example.com)1.1.2.3i  )   N   	5.8.13.21r#   r   )r   r   _queryr   r   r   udpPortspopitem_sentPacketsr   fromStrassertEqualqueriesanswers	authority
additionaladdCallbackappendanswerr   r   	_protocoldatagramReceivedtoStr)selffilterr4   resolverd
portNumber	transportpacketaddressmessageresponses              r*   
_queryTestzRootResolverTests._queryTest<   sg     /B0OO$a,/@.A5&

 !( 0 0 8 8 :
I (44	&') 	51CQ+K*LM"-**B/++R0	hoo&2& OOA'+1FG	
 	,,W]]_>OP{r,   c           
          | j                  d      \  }}}| j                  |t        dt        dd            g       | j                  |g        | j                  |g        y)a)  
        L{Resolver._query} accepts a L{Query} instance and an address, issues
        the query, and returns a L{Deferred} which fires with the response to
        the query.  If a true value is passed for the C{filter} parameter, the
        result is a three-tuple of lists of records.
        Tr5   r9   r   ttlr#   N)rT   r?   r   r   )rJ   rF   rB   rC   s       r*   test_filteredQueryz$RootResolverTests.test_filteredQueryg   sa     )-(=%	:X0(;TU:VWX	
 	B'R(r,   c           
      `   | j                  d      }| j                  |t               | j                  |j                  g        | j                  |j
                  t        dt        dd            g       | j                  |j                  g        | j                  |j                  g        y)z
        Similar to L{test_filteredQuery}, but for the case where a false value
        is passed for the C{filter} parameter.  In this case, the result is a
        L{Message} instance.
        Fr5   r9   r   rV   r#   N)
rT   assertIsInstancer   r?   r@   rA   r   r   rB   rC   )rJ   rR   s     r*   test_unfilteredQueryz&RootResolverTests.test_unfilteredQueryu   s     //%(gw/"-OO((;A2NOP	
 	**B/++R0r,   c                     t        |      }|j                  |f|j                  |f|j                  |ffD ]O  \  }}|j	                  |D 	cg c]-  \  }}	t        ||	j                  t        |	dt              |	      / c}	}       Q |S c c}	}w )a  
        Create a L{Message} suitable for use as a response to a query.

        @param answers: A C{list} of two-tuples giving data for the answers
            section of the message.  The first element of each tuple is a name
            for the L{RRHeader}.  The second element is the payload.
        @param authority: A C{list} like C{answers}, but for the authority
            section of the response.
        @param additional: A C{list} like C{answers}, but for the
            additional section of the response.
        @param rCode: The response code the message will be created with.

        @return: A new L{Message} initialized with the given values.
        )rCodeCLASSr#   )	r   rA   rB   rC   extendr   TYPEgetattrr   )
rJ   rA   rB   rC   r]   rS   sectiondatanamerecords
             r*   _respondzRootResolverTests._respond   s     'w'+  *-
 	MGT
 NN
 +/	 'v fkk767B+GQW	 s   2B
c                 B     dg}t        ||      } fd}||_        |S )a  
        Create and return a new L{root.Resolver} modified to resolve queries
        against the record data represented by C{servers}.

        @param serverResponses: A mapping from dns server addresses to
            mappings.  The inner mappings are from query two-tuples (name,
            type) to dictionaries suitable for use as **arguments to
            L{_respond}.  See that method for details.
        r6   c                     t        d| j                   d|       |D ]I  }	 |   }|| j                  j                  | j                  f   }t	         j
                  di |      c S  y # t        $ r Y Xw xY w)NzQuery for QNAME z at  )r   rd   KeyErrortyper   rf   )	queryserverAddressestimeoutrK   addrserverrecordsrJ   serverResponsess	          r*   rl   z-RootResolverTests._getResolver.<locals>.query   s    "5::,d?2EFG' 9,T2F !%**!<=}t}}7w7889   s   A,,	A87A8)r   r:   )rJ   rr   maximumQueriesrootsrL   rl   s   ``    r*   _getResolverzRootResolverTests._getResolver   s+     E>2	9  r,   c                 (   dt         fdt        d      fgdt        d      fgdidt         fddt        d      fgiid}| j                  |      }|j	                  d      }|j                  t               |j                  | j                  d       |S )a  
        L{root.Resolver.lookupAddress} looks up the I{A} records for the
        specified hostname by first querying one of the root servers the
        resolver was created with and then following the authority delegations
        until a result is received.
        r5      ns1.example.com34.55.89.144rB   rC   rA   10.0.0.1)r6   5   )rx   r|   r   r   r   ru   lookupAddressrD   r0   r?   rJ   serversrL   rM   s       r*   test_lookupAddressz$RootResolverTests.test_lookupAddress   s     $Q'#5yAS7T"U!V$68P#Q"R* $Q'!3Xj5I JK*#
 $$W-""#56	m$	d&&
3r,   c                 n   t        d      }t        |_        dt        fd|fgdt	        d      fgdt        d      fgdidt        fddt        d      fgiid}| j                  |      }|j                  d      }|j                  t               |j                  | j                  t        d             |S )	z
        If a response includes a record with a class different from the one
        in the query, it is ignored and lookup continues until a record with
        the right class is found.
        rz   r5   rw   10.0.0.2)rA   rB   rC   rA   10.0.0.3)r{   r   r|   )
r   r   r^   r   r   ru   r~   rD   r+   r?   )rJ   badClassr   rL   rM   s        r*   test_lookupChecksClassz(RootResolverTests.test_lookupChecksClass   s     J' $Q'!3X >?#5yAS7T"U!V$68L#M"N* $Q'!3Xj5I JK*
 $$W-""#56	m$	d&&(<=r,   c                 :   dt         fddt        d      fgidt         fddt        d      fgiidt         fddt        d      fgiid}| j                  |      }|j	                  d      }|j                  t               |j                  | j                  d       |S )z
        If an intermediate response includes no glue records for the
        authorities, separate queries are made to find those addresses.
        r5   rB   s   ns1.example.orgrA   rz   r   )r{   )rz   r|   r}   r   s       r*   test_missingGluez"RootResolverTests.test_missingGlue   s     $Q'#5yAS7T"U!V* $Q'!3Xj5I JK* $Q'!3Xj5I JK*
  $$W-""#56	m$	d&&
3r,   c                     ddt         fdt        iii}| j                  |      }|j                  d      }| j	                  |t
              S )z
        If a name is missing, L{Resolver.lookupAddress} returns a L{Deferred}
        which fails with L{DNSNameError}.
        r{   r5   r]   )r   r   ru   r~   assertFailurer   r   s       r*   test_missingNamez"RootResolverTests.test_missingName  s[     #Q'U*
 $$W-""#56!!!\22r,   c                     ddt         fi ii}| j                  |      }|j                  d      }| j                  |t              S )z
        If a query is responded to with no answers or nameserver records, the
        L{Deferred} returned by L{Resolver.lookupAddress} fires with
        L{ResolverError}.
        r{      example.com)r   ru   r~   r   r   r   s       r*   test_answerlessz!RootResolverTests.test_answerless  sR     #R

 $$W-"">2!!!]33r,   c                     ddt         fddt        d      fgidt         fdt        iii}| j                  |      }|j	                  d      }| j                  |t              S )z
        If there is an error resolving the nameserver in a delegation response,
        the L{Deferred} returned by L{Resolver.lookupAddress} fires with that
        error.
        r{   r   rB   rw   r]   )r   r   r   ru   r~   r   r   r   s       r*   test_delegationLookupErrorz,RootResolverTests.test_delegationLookupError.  s|     #>9=O3P"Q!R& $Q'U*		
 $$W-"">2!!!\22r,   c                     ddt         fddt        d      fgidt         fi ii}| j                  |      }|j                  d      }| j	                  |t
              S )z
        If there are no records in the response to a lookup of a delegation
        nameserver, the L{Deferred} returned by L{Resolver.lookupAddress} fires
        with L{ResolverError}.
        r{   r   rB   rw   )r   r   ru   r~   r   r   r   s       r*   test_delegationLookupEmptyz,RootResolverTests.test_delegationLookupEmptyB  st     #>9=O3P"Q!R& $Q'	
 $$W-"">2!!!]33r,   c           	         ddt         fdt        idt        fddt        d      fgiii}| j	                  |      }|j                  d      }d }|j                  |       |j                  | j                  t        d             |S )z
        L{Resolver.lookupNameservers} is like L{Resolver.lookupAddress}, except
        it queries for I{NS} records instead of I{A} records.
        r{   r   r]   rA   rw   c                 @    | \  }}}|d   j                   j                  S Nr   )r$   rd   r%   s       r*   
getOneNamez<RootResolverTests.test_lookupNameservers.<locals>.getOneNamef  s!    $NCsq6>>&&&r,   )	r   r   r   r   ru   lookupNameserversrD   r?   r   )rJ   r   rL   rM   r   s        r*   test_lookupNameserversz(RootResolverTests.test_lookupNameserversT  s     #U&  $;M1N OP'		
 $$W-&&~6	' 	
j!	d&&-?(@Ar,   c                 Z   ddt         fddt        d      fdt        d      fgiii}| j                  |      }|j	                  d      }|j                  d        |j                  | j                  t        dt        t        d            t        dt         t        d            g       |S )z
        If a I{CNAME} record is encountered as the answer to a query for
        another record type, that record is returned as the answer.
        r{   r   rA      example.netz10.0.0.7c                     | d   S r   ri   r/   s    r*   <lambda>z<RootResolverTests.test_returnCanonicalName.<locals>.<lambda>  
    gaj r,   r#   	r   r   r   ru   r~   rD   r?   r   r   r   s       r*   test_returnCanonicalNamez*RootResolverTests.test_returnCanonicalNamen  s     #'n)EF'*)=> &	
 $$W-"">2	01	^8TUHZ4HI	
 r,   c                 n   ddt         fddt        d      fgidt         fddt        d      fgiii}| j                  |      }|j	                  d      }|j                  d        |j                  | j                  t        dt        t        d            t        dt         t        d            g       |S )z
        If no record of the requested type is included in a response, but a
        I{CNAME} record for the query name is included, queries are made to
        resolve the value of the I{CNAME}.
        r{   r   rA   r   z10.0.0.5c                     | d   S r   ri   r/   s    r*   r   z<RootResolverTests.test_followCanonicalName.<locals>.<lambda>  r   r,   r#   r   r   s       r*   test_followCanonicalNamez*RootResolverTests.test_followCanonicalName  s     #n1M NO&  #*1E FG&		
 $$W-"">2	01	^8TUHZ4HI	
 r,   c                     ddt         fddt        d      fdt        d      fgiii}| j                  |      }|j                  d      }| j	                  |t
              S )z
        If there is a cycle between I{CNAME} records in a response, this is
        detected and the L{Deferred} returned by the lookup method fails
        with L{ResolverError}.
        r{   r   rA   r   )r   r   ru   r~   r   r   r   s       r*   test_detectCanonicalNameLoopz.RootResolverTests.test_detectCanonicalNameLoop  sw     #'n)EF'n)EF &	
 $$W-"">2!!!]33r,   c                    dt         fddt        d      fgidt         fddt        d      fgiidt         fdt        d      fgdt        d      fgdidt         fddt        d	      fgiid
}| j                  |d      }| j	                  |j                  d      t              }| j                  |d      }|j                  d      }|j                  t               |j                  | j                  t        d	             t        ||g      S )z
        L{Resolver.lookupAddress} won't issue more queries following
        delegations than the limit passed to its initializer.
        r   rB   rw   rA   r   s   ns2.example.comr   ry   z10.0.0.4)r{   r   )r   r|         )r   r   r   ru   r   r~   r   rD   r+   r?   r   )rJ   r   failerfailD	succeedersucceedDs         r*   test_boundedQueriesz%RootResolverTests.test_boundedQueries  s:     #>9=O3P"Q!R&
 $Q'!3Xj5I JK*   ##19=O3P"Q!R$68L#M"N&	  #*1E FG&-
B ""7A.""6#7#7#GW%%gq1	**>:]+T--x
/CDeX.//r,   N)
   )__name__
__module____qualname____doc__rT   rX   r[   r   rf   ru   r   r   r   r   r   r   r   r   r   r   r   r   ri   r,   r*   r2   r2   7   sh    )V)1   "RBb >44863 43(4$4684(.0r,   r2   c                       e Zd ZdZd Zy)ResolverFactoryArgumentszf
    Raised by L{raisingResolverFactory} with the *args and **kwargs passed to
    that function.
    c                      || _         || _        y)z
        Store the supplied args and kwargs as attributes.

        @param args: Positional arguments.
        @param kwargs: Keyword arguments.
        Nargskwargs)rJ   r   r   s      r*   __init__z!ResolverFactoryArguments.__init__  s     	r,   N)r   r   r   r   r   ri   r,   r*   r   r     s    
r,   r   c                      t        | |      )a=  
    Raise a L{ResolverFactoryArguments} exception containing the
    positional and keyword arguments passed to resolverFactory.

    @param args: A L{list} of all the positional arguments supplied by
        the caller.

    @param kwargs: A L{list} of all the keyword arguments supplied by
        the caller.
    )r   r   s     r*   raisingResolverFactoryr     s     #4
00r,   c                   "    e Zd ZdZd Zd Zd Zy) RootResolverResolverFactoryTestsz6
    Tests for L{root.Resolver._resolverFactory}.
    c                 h    t        dgt              }| j                  |j                  t               y)z
        L{root.Resolver.__init__} accepts a C{resolverFactory}
        argument and assigns it to C{self._resolverFactory}.
        N)hintsresolverFactory)r   r   assertIs_resolverFactoryrJ   rs     r*   #test_resolverFactoryArgumentPresentzDRootResolverResolverFactoryTests.test_resolverFactoryArgumentPresent  s(    
 D63IJa((*@Ar,   c                 r    t        dg      }| j                  |j                  t        j                          y)z
        L{root.Resolver.__init__} sets L{client.Resolver} as the
        C{_resolverFactory} if a C{resolverFactory} argument is not
        supplied.
        N)r   )r   r   r   r
   r   s     r*   "test_resolverFactoryArgumentAbsentzCRootResolverResolverFactoryTests.test_resolverFactoryArgumentAbsent  s(     D6"a((&//:r,   c                     t               }t        dgt        |      }| j                  t        |j
                  d      }| j                  d|dgdf|j                  |j                  f       y)zy
        L{root.Resolver._resolverFactory} is supplied with C{reactor} and
        C{servers} keyword arguments.
        192.0.2.101)r   r   r4   zexample.comri   )r   r|   )r4   r   N)	objectr   r   assertRaisesr   r~   r?   r   r   )rJ   dummyReactorr   es       r*   )test_resolverFactoryOnlyExpectedArgumentszJRootResolverResolverFactoryTests.test_resolverFactoryOnlyExpectedArguments  sj    
 x /2 
 6W\7J6KLMVVQXX	
r,   N)r   r   r   r   r   r   r   ri   r,   r*   r   r   	  s    B;
r,   r   )za.root-servers.netzb.root-servers.netzc.root-servers.netzd.root-servers.netze.root-servers.netzf.root-servers.netzg.root-servers.netzh.root-servers.netzi.root-servers.netzj.root-servers.netzk.root-servers.netzl.root-servers.netzm.root-servers.netc                       e Zd ZdZd Zd Zy)StubResolverz
    An L{IResolverSimple} implementer which traces all getHostByName
    calls and their deferred results. The deferred results can be
    accessed and fired synchronously.
    c                      g | _         g | _        y)z
        @type calls: L{list} of L{tuple} containing C{args} and
            C{kwargs} supplied to C{getHostByName} calls.
        @type pendingResults: L{list} of L{Deferred} returned by
            C{getHostByName}.
        N)callspendingResults)rJ   s    r*   r   zStubResolver.__init__L  s     
 r,   c                     | j                   j                  ||f       t               }| j                  j                  |       |S )al  
        A fake implementation of L{IResolverSimple.getHostByName}

        @param args: A L{list} of all the positional arguments supplied by
           the caller.

        @param kwargs: A L{list} of all the keyword arguments supplied by
           the caller.

        @return: A L{Deferred} which may be fired later from the test
            fixture.
        )r   rE   r   r   )rJ   r   r   rM   s       r*   getHostByNamezStubResolver.getHostByNameV  s:     	

4.)J""1%r,   N)r   r   r   r   r   r   ri   r,   r*   r   r   D  s    !r,   r   c                   :    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
y	)
BootstrapTestsz%
    Tests for L{root.bootstrap}
    c                 ~    t        j                  t                     }| j                  |t         j                         y)zl
        L{root.bootstrap} returns an object which is initially a
        L{root.DeferredResolver}.
        N)r   	bootstrapr   rZ   DeferredResolver)rJ   deferredResolvers     r*   test_returnsDeferredResolverz+BootstrapTests.test_returnsDeferredResolverq  s,    
  >>,.9.0E0EFr,   c                     t               }t        j                  |       | j                  |j                  t
        D cg c]  }|fi f	 c}       yc c}w )z
        The L{IResolverSimple} supplied to L{root.bootstrap} is used to lookup
        the IP addresses of the 13 root name servers.
        N)r   r   r   r?   r   ROOT_SERVERS)rJ   stubResolverss      r*   test_resolves13RootServersz)BootstrapTests.test_resolves13RootServersy  sA    
 $~|$++,-OQtRj-OP-Os   A
c                     t               }t        j                  |      }|j                  D ]  }|j	                  d        | j                  |t               y)z
        The L{root.DeferredResolver} initially returned by L{root.bootstrap}
        becomes a L{root.Resolver} when the supplied resolver has successfully
        looked up all root hints.
        r   N)r   r   r   r   callbackrZ   r   rJ   r   r   rM   s       r*   test_becomesResolverz#BootstrapTests.test_becomesResolver  sL     $~>>,7,, 	&AJJ}%	&.9r,   c                     t               }t        j                  |      }|j                  D ]  }|j	                  d        | j                  |j                  dgdz         y)z
        The L{root.Resolver} which eventually replaces L{root.DeferredResolver}
        is supplied with the IP addresses of the 13 root servers.
        r      N)r   r   r   r   r   r?   r   r   s       r*   test_resolverReceivesRootHintsz-BootstrapTests.test_resolverReceivesRootHints  sY    
 $~>>,7,, 	&AJJ}%	&)//-21EFr,   c                     t               }t        j                  |      t        |j                        }t        |      }|D ]  }|j                  d        |j                  t                       fd}|j                  |       y)z
        The L{root.Resolver} is eventually created, even if some of the root
        hint lookups fail. Only the working root hint IP addresses are supplied
        to the L{root.Resolver}.
        r   c                 F    j                  j                  dgdz         y )Nr      r?   r   resr   rJ   s    r*   
checkHintszFBootstrapTests.test_continuesWhenSomeRootHintsFail.<locals>.checkHints  s!    -33m_r5IJr,   N)
r   r   r   iterr   nextr   errbackr   addBothrJ   r   r&   d1rM   r   r   s   `     @r*   #test_continuesWhenSomeRootHintsFailz2BootstrapTests.test_continuesWhenSomeRootHintsFail  sq     $~>>,7|223'] 	&AJJ}%	&


<>"	K 	

:r,   c                 f    t               }t        j                  |      t        |j                        }t        |      }|D ]  }|j                  t                       |j                  t                       fd}|j                  |        j                   j                  t               y)z
        The L{root.Resolver} is eventually created, even if all of the root hint
        lookups fail. Pending and new lookups will then fail with
        AttributeError.
        c                 >    j                  j                  g        y Nr   r   s    r*   r   zEBootstrapTests.test_continuesWhenAllRootHintsFail.<locals>.checkHints  s    -33R8r,   N)r   r   r   r   r   r   r   r   r   
addCleanupflushLoggedErrorsr   s   `     @r*   "test_continuesWhenAllRootHintsFailz1BootstrapTests.test_continuesWhenAllRootHintsFail  s     $~>>,7|223'] 	&AIIln%	&


<>"	9 	

:..=r,   c                     t               }t        j                  |t              }|j                  D ]  }|j                  d        | j                  |j                  t               y)z
        L{root.bootstrap} accepts a C{resolverFactory} argument which is passed
        as an argument to L{root.Resolver} when it has successfully looked up
        root hints.
        )r   r   N)r   r   r   r   r   r   r   r   r   s       r*   test_passesResolverFactoryz)BootstrapTests.test_passesResolverFactory  s[     $~>>*@
 ,, 	&AJJ}%	& 	&779OPr,   N)r   r   r   r   r   r   r   r   r   r   r   ri   r,   r*   r   r   l  s.    GQ
:	G&>*Qr,   r   c                       e Zd ZdZd Zy)StubDNSDatagramProtocolz
    A do-nothing stand-in for L{DNSDatagramProtocol} which can be used to avoid
    network traffic in tests where that kind of thing doesn't matter.
    c                     t               S r   )r   )rJ   akws      r*   rl   zStubDNSDatagramProtocol.query  s
    zr,   N)r   r   r   r   rl   ri   r,   r*   r   r     s    
r,   r   zbtwisted.names.root.retry is deprecated since Twisted 10.0.  Use a Resolver object for retry logic.)categoryrR   N):r   zope.interfacer   zope.interface.verifyr   twisted.internet.deferr   r   r   r   twisted.internet.interfacesr	   twisted.namesr
   r   twisted.names.dnsr   r   r   r   r   r   r   r   r   r   r   r   r   r   twisted.names.errorr   r   twisted.names.rootr   twisted.names.test.test_utilr   twisted.python.logr   twisted.trialr   twisted.trial.unittestr    r!   r+   r0   r2   	Exceptionr   r   r   r   r   r   r   suppressDeprecationWarning_retrySuppressionri   r,   r*   <module>r     s    ' - Q Q 7 &     < ' 6 "  @/p0 p0fy "1'
x '
T" _! ! !H O\ *cQ( cQL  "DMM	+ r,   