Ϫf2ddZddlmZddlmZddlmZmZmZm Z ddl m Z ddl m Z mZddlmZmZmZmZmZmZmZmZmZmZmZmZmZmZddlmZm Z dd l!m"Z"dd l#m$Z$dd l%m&Z&dd l'm(Z(dd l)m*Z*m+Z+dZ,dZ-Gdde+Z.Gdde/Z0dZ1Gdde+Z2gdZ3ee GddZ4ee e4Gdde*Z5GddZ6e(jne8dZ9y )!z. Test cases for Twisted.names' root resolver. ) implementer) verifyClass)Deferred TimeoutError gatherResultssucceed)IResolverSimple)clientroot)CNAMEENAMEHSINNSOKAMessageNameQueryRecord_A Record_CNAME Record_NSRRHeader) DNSNameError ResolverError)Resolver) MemoryReactor)msg)util)SynchronousTestCaseTestCasec,|\}}}|djS)z From the result of a L{Deferred} returned by L{IResolver.lookupAddress}, return the payload of the first record in the answer section. rpayloadresultsansauthadds E/usr/lib/python3/dist-packages/twisted/names/test/test_rootresolve.py getOnePayloadr+&s NCs q6>>c4t|jS)z From the result of a L{Deferred} returned by L{IResolver.lookupAddress}, return the first IPv4 address from the answer section. )r+ dottedQuadr&s r* getOneAddressr0/s  ! , , ..r,ceZdZdZdZdZdZgggefdZddZ dZ dZ d Z d Z d Zd Zd ZdZdZdZdZdZy)RootResolverTestsz3 Tests for L{twisted.names.root.Resolver}. c`t}tg|}|jtdtt dgd|}|j j\}}|j\\}}t} | j||j| jtdtt g|j| jg|j| jg|j| jgg} |j!| j"|j| g| jdd=d| _| jj#t'dt)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}. )reactorfoo.example.com)1.1.2.3i)N 5.8.13.21r#r)rr_queryrrrudpPortspopitem _sentPacketsrfromStr assertEqualqueriesanswers authority additional addCallbackappendanswerrr _protocoldatagramReceivedtoStr) selffilterr4resolverd portNumber transportpacketaddressmessageresponses r* _queryTestzRootResolverTests._queryTest<sg /B0 OO $a ,/@.A5&  !( 0 0 8 8 : I(44 &') 51CQ+K*LM "- **B/ ++R0 hoo& 2& OOA  '+1F G  ,,W]]_>OP{r,c |jd\}}}|j|tdtddg|j|g|j|gy)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. Tr5r9rttlr#N)rTr?rr)rJrFrBrCs r*test_filteredQueryz$RootResolverTests.test_filteredQuerygsa)-(=% :  X0(;TU:VWX  B' R(r,c `|jd}|j|t|j|jg|j|j t dtddg|j|jg|j|jgy)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. Fr5r9rrVr#N) rTassertIsInstancerr?r@rArrrBrC)rJrRs r*test_unfilteredQueryz&RootResolverTests.test_unfilteredQueryus //%( gw/ "-  OO ((;A2N O P  **B/ ++R0r,c t|}|j|f|j|f|j|ffD]O\}}|j |D cgc]-\}} t || j t| dt| /c} }Q|Scc} }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. )rCodeCLASSr#) rrArBrCextendrTYPEgetattrr) rJrArBrCr]rSsectiondatanamerecords r*_respondzRootResolverTests._responds'   w '    +  * - MGT NN +/ 'vfkk767B+GQW  s 2B cBdg}t||}fd}||_|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. r6ctd|jd||D]I} |}||jj|jf}t j di|cSy#t$rYXwxYw)NzQuery for QNAME z at )rrdKeyErrortyperrf) queryserverAddressestimeoutrKaddrserverrecordsrJserverResponsess r*rlz-RootResolverTests._getResolver..querys "5::,d?2EF G' 9,T2F!%**!<=}t}}7w788  9 sA,, A87A8)rr:)rJrrmaximumQueriesrootsrLrls`` r* _getResolverzRootResolverTests._getResolvers+ E>2 9 r,c(dtfdtdfgdtdfgdidtfddtdfgiid}|j|}|j d}|j t |j |jd|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. r5ns1.example.com 34.55.89.144rBrCrA10.0.0.1)r65)rxr|rrrru lookupAddressrDr0r?rJserversrLrMs r*test_lookupAddressz$RootResolverTests.test_lookupAddresss$Q'#5yAS7T"U!V$68P#Q"R*$Q'!3Xj5I JK*#  $$W-  " "#5 6 m$ d&& 3r,cntd}t|_dtfd|fgdt dfgdtdfgdidtfddtdfgiid}|j |}|j d}|jt|j|jtd|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. rzr5rw10.0.0.2)rArBrCrA10.0.0.3)r{rr|) rrr^rrrur~rDr+r?)rJbadClassrrLrMs r*test_lookupChecksClassz(RootResolverTests.test_lookupChecksClasss J'$Q'!3X >?#5yAS7T"U!V$68L#M"N*$Q'!3Xj5I JK*  $$W-  " "#5 6 m$ d&&(<=r,c:dtfddtdfgidtfddtdfgiidtfddtdfgiid}|j|}|j d}|j t |j |jd|S)z If an intermediate response includes no glue records for the authorities, separate queries are made to find those addresses. r5rBsns1.example.orgrArzr)r{)rzr|r}rs r*test_missingGluez"RootResolverTests.test_missingGlues$Q'#5yAS7T"U!V*$Q'!3Xj5I JK* $Q'!3Xj5I JK*  $$W-  " "#5 6 m$ d&& 3r,cddtfdtiii}|j|}|jd}|j |t S)z If a name is missing, L{Resolver.lookupAddress} returns a L{Deferred} which fails with L{DNSNameError}. r{r5r])rr rur~ assertFailurerrs r*test_missingNamez"RootResolverTests.test_missingNames[ #Q'U* $$W-  " "#5 6!!!\22r,cddtfiii}|j|}|jd}|j|tS)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)rrur~rrrs r*test_answerlessz!RootResolverTests.test_answerlesssR #R  $$W-  " "> 2!!!]33r,cddtfddtdfgidtfdtiii}|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{rrBrwr])rrr rur~rrrs r*test_delegationLookupErrorz,RootResolverTests.test_delegationLookupError.s| #>9=O3P"Q!R&$Q'U*   $$W-  " "> 2!!!\22r,cddtfddtdfgidtfiii}|j|}|jd}|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{rrBrw)rrrur~rrrs r*test_delegationLookupEmptyz,RootResolverTests.test_delegationLookupEmptyBst #>9=O3P"Q!R&$Q'  $$W-  " "> 2!!!]33r,c  ddtfdtidtfddtdfgiii}|j |}|j d}d}|j ||j |jtd|S)z L{Resolver.lookupNameservers} is like L{Resolver.lookupAddress}, except it queries for I{NS} records instead of I{A} records. r{rr]rArwc@|\}}}|djjSNr)r$rdr%s r* getOneNamez.getOneNamefs!$NCsq6>>&& &r,) rr rrrulookupNameserversrDr?r)rJrrLrMrs r*test_lookupNameserversz(RootResolverTests.test_lookupNameserversTs #U& $;M1N OP'   $$W-  & &~ 6 ' j! d&&-?(@Ar,c Zddtfddtdfdtdfgiii}|j|}|j d}|j d|j |j tdttdtdttdg|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{rrA example.netz10.0.0.7c |dSrrir/s r*z. gajr,r# rrrrur~rDr?rr rs r*test_returnCanonicalNamez*RootResolverTests.test_returnCanonicalNamens #'n)EF'*)=> &  $$W-  " "> 2 01    ^8TUHZ4HI  r,c nddtfddtdfgidtfddtdfgiii}|j|}|j d}|j d|j |j tdttdtdttdg|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{rrArz10.0.0.5c |dSrrir/s r*rz.rr,r#rrs r*test_followCanonicalNamez*RootResolverTests.test_followCanonicalNames #n1M NO& #*1E FG&   $$W-  " "> 2 01    ^8TUHZ4HI  r,cddtfddtdfdtdfgiii}|j|}|jd}|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{rrAr)rrrur~rrrs r*test_detectCanonicalNameLoopz.RootResolverTests.test_detectCanonicalNameLoopsw #'n)EF'n)EF &  $$W-  " "> 2!!!]33r,cdtfddtdfgidtfddtdfgiidtfdtdfgdtdfgdidtfddtd fgiid }|j|d }|j |j dt }|j|d }|j d}|jt|j|jtd t||gS) z L{Resolver.lookupAddress} won't issue more queries following delegations than the limit passed to its initializer. rrBrwrArsns2.example.comrryz10.0.0.4)r{r)rr|) rrrrurr~rrDr+r?r)rJrfailerfailD succeedersucceedDs r*test_boundedQueriesz%RootResolverTests.test_boundedQueriess: #>9=O3P"Q!R& $Q'!3Xj5I JK*   ##19=O3P"Q!R$68L#M"N&  #*1E FG&- B""7A.""6#7#7#GW%%gq1 **>:]+T--x /CDeX.//r,N) )__name__ __module__ __qualname____doc__rTrXr[rrfrurrrrrrrrrrrrrir,r*r2r27sh)V )1 "RBb>44863 43(4$4684(.0r,r2ceZdZdZdZy)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. Nargskwargs)rJrrs r*__init__z!ResolverFactoryArguments.__init__s  r,N)rrrrrrir,r*rrs  r,rct||)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. )rrs r*raisingResolverFactoryrs #4 00r,c"eZdZdZdZdZdZy) RootResolverResolverFactoryTestsz6 Tests for L{root.Resolver._resolverFactory}. chtdgt}|j|jty)z L{root.Resolver.__init__} accepts a C{resolverFactory} argument and assigns it to C{self._resolverFactory}. N)hintsresolverFactory)rrassertIs_resolverFactoryrJrs r*#test_resolverFactoryArgumentPresentzDRootResolverResolverFactoryTests.test_resolverFactoryArgumentPresents( D63I J a((*@Ar,crtdg}|j|jtjy)z L{root.Resolver.__init__} sets L{client.Resolver} as the C{_resolverFactory} if a C{resolverFactory} argument is not supplied. N)r)rrrr rs r*"test_resolverFactoryArgumentAbsentzCRootResolverResolverFactoryTests.test_resolverFactoryArgumentAbsents( D6 " a((&//:r,ct}tdgt|}|jt|j d}|j d|dgdf|j|jfy)zy L{root.Resolver._resolverFactory} is supplied with C{reactor} and C{servers} keyword arguments. 192.0.2.101)rrr4z example.comri)rr|)r4rN) objectrr assertRaisesrr~r?rr)rJ dummyReactorres r*)test_resolverFactoryOnlyExpectedArgumentszJRootResolverResolverFactoryTests.test_resolverFactoryOnlyExpectedArgumentssj x  /2     6 W  \7J6KL M VVQXX  r,N)rrrrrrrrir,r*rr sB; r,r) za.root-servers.netzb.root-servers.netzc.root-servers.netzd.root-servers.netze.root-servers.netzf.root-servers.netzg.root-servers.netzh.root-servers.netzi.root-servers.netzj.root-servers.netzk.root-servers.netzl.root-servers.netzm.root-servers.netceZdZdZdZdZy) 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)callspendingResults)rJs r*rzStubResolver.__init__Ls  r,c|jj||ft}|jj||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. )rrErr)rJrrrMs r* getHostByNamezStubResolver.getHostByNameVs: 4.) J ""1%r,N)rrrrrrrir,r*rrDs !r,rc:eZdZdZdZdZdZdZdZdZ dZ y ) BootstrapTestsz% Tests for L{root.bootstrap} c~tjt}|j|tjy)zl L{root.bootstrap} returns an object which is initially a L{root.DeferredResolver}. N)r bootstraprrZDeferredResolver)rJdeferredResolvers r*test_returnsDeferredResolverz+BootstrapTests.test_returnsDeferredResolverqs,  >>,.9 .0E0EFr,ct}tj||j|jt Dcgc]}|fif c}ycc}w)z The L{IResolverSimple} supplied to L{root.bootstrap} is used to lookup the IP addresses of the 13 root name servers. N)rr rr?r ROOT_SERVERS)rJ stubResolverss r*test_resolves13RootServersz)BootstrapTests.test_resolves13RootServersysA $~  |$ ++,-OQtRj-OP-Os A ct}tj|}|jD]}|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. rN)rr rrcallbackrZrrJrrrMs r*test_becomesResolverz#BootstrapTests.test_becomesResolversL $~ >>,7,, &A JJ} % & .9r,ct}tj|}|jD]}|j d|j |j dgdzy)z The L{root.Resolver} which eventually replaces L{root.DeferredResolver} is supplied with the IP addresses of the 13 root servers. r N)rr rrrr?rrs r*test_resolverReceivesRootHintsz-BootstrapTests.test_resolverReceivesRootHintssY $~ >>,7,, &A JJ} % & )//-21EFr,ct}tj|t|j}t |}|D]}|j d|jtfd}|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}. rcFjjdgdzy)Nr r?rresrrJs r* checkHintszFBootstrapTests.test_continuesWhenSomeRootHintsFail..checkHintss!   -33m_r5I Jr,N) rr riterrnextrerrbackraddBothrJrr&d1rMrrs` @r*#test_continuesWhenSomeRootHintsFailz2BootstrapTests.test_continuesWhenSomeRootHintsFailsq $~ >>,7|223 '] &A JJ} % & <>" K :r,cft}tj|t|j}t |}|D]}|j t|j tfd}|j|jjty)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>jjgyNrrs r*rzEBootstrapTests.test_continuesWhenAllRootHintsFail..checkHintss   -33R 8r,N) rr rrrrrrr addCleanupflushLoggedErrorsrs` @r*"test_continuesWhenAllRootHintsFailz1BootstrapTests.test_continuesWhenAllRootHintsFails $~ >>,7|223 '] &A IIln % & <>" 9 : .. =r,ct}tj|t}|jD]}|j d|j |jty)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. )rrN)rr rrrrrrrs r*test_passesResolverFactoryz)BootstrapTests.test_passesResolverFactorys[ $~ >> *@ ,, &A JJ} % & &779OPr,N) rrrrrrrrrrrrir,r*rrls.GQ : G&>*Qr,rceZdZdZdZy)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. ctSr)r)rJakws r*rlzStubDNSDatagramProtocol.querys zr,N)rrrrrlrir,r*rrs  r,rzbtwisted.names.root.retry is deprecated since Twisted 10.0. Use a Resolver object for retry logic.)categoryrRN):rzope.interfacerzope.interface.verifyrtwisted.internet.deferrrrrtwisted.internet.interfacesr twisted.namesr r twisted.names.dnsr r rrrrrrrrrrrrtwisted.names.errorrrtwisted.names.rootrtwisted.names.test.test_utilrtwisted.python.logr twisted.trialrtwisted.trial.unittestr r!r+r0r2 ExceptionrrrrrrrsuppressDeprecationWarning_retrySuppressionrir,r*rs'-QQ7& <'6"@/p0p0f y" 1' x' T " _!!!H O\*cQ(cQL"DMM  +r,