ϪfLdZddlmZddlmZmZmZmZmZm Z m Z m Z m Z ddl mZmZddlmZddlmZddlmZmZmZddlmZmZmZdd lmZmZdd lm Z m!Z!dd l"m#Z#dd l$m%Z%dd l&m'Z'm(Z(m)Z)m*Z*ddl+m,Z,ddl-m.Z/Gdde,Z0dZ1dZ2GddZ3ee)GddZ4Gdde/Z5Gdde/Z6ee*GddZ7Gdde/Z8Gd d!e!Z9Gd"d#e/Z:y$)%zh Tests for implementations of L{IHostnameResolver} and their interactions with reactor implementations. ) defaultdict) AF_INETAF_INET6 AF_UNSPEC EAI_NONAME IPPROTO_TCP SOCK_DGRAM SOCK_STREAMgaierror getaddrinfo)Locklocal) implementer) verifyObject) LockWorkerTeamcreateMemoryWorker)ComplexResolverSimplifier GAIResolverSimpleResolverComplexifier) IPv4Address IPv6Address)PluggableResolverMixin ReactorBase)Deferred)DNSLookupError)IHostnameResolverIReactorPluggableNameResolverIResolutionReceiverIResolverSimple) ThreadPool)SynchronousTestCaseceZdZdZdZy)DeterministicThreadPoolz6 Create a deterministic L{ThreadPool} object. cJd|_d|_d|_g|_||_y)zE Create a L{DeterministicThreadPool} from a L{Team}. N)minmaxnamethreads_team)selfteams E/usr/lib/python3/dist-packages/twisted/internet/test/test_resolver.py__init__z DeterministicThreadPool.__init__4s'   N)__name__ __module__ __qualname____doc__r/r0r.r$r$/s r0r$c t\}tttt t fdd|fS)z Create a deterministic threadpool. @return: 2-tuple of L{ThreadPool}, 0-argument C{work} callable; when C{work} is called, do the work. cSNr5workersr.z#deterministicPool..Isvr0cyr8r5r5r0r.r;z#deterministicPool..Ir0)rr$rrr r)doerr:s @r.deterministicPoolr??s?&'LFD DFEG,~ M   r0cHt\}Gfdd}||fS)z Create a deterministic L{IReactorThreads} @return: a 2-tuple consisting of an L{IReactorThreads}-like object and a 0-argument callable that will perform one unit of work invoked via that object's C{callFromThread} method. ceZdZfdZy)(deterministicReactorThreads..CFTc8jfdy)NciSr8r5)afksr.r;zIdeterministicReactorThreads..CFT.callFromThread..[sajajr0)do)r,rFrErGr:s ```r.callFromThreadz7deterministicReactorThreads..CFT.callFromThreadZs II( )r0N)r1r2r3rIr9sr.CFTrBYs *r0rJ)r)r>rJr:s @r.deterministicReactorThreadsrKOs)&'LFD** 5$;r0c.eZdZdZdZddZeeedfdZ y)FakeAddrInfoGetterz/ Test object implementing getaddrinfo. c:g|_tt|_y)z1 Create a L{FakeAddrInfoGetter}. N)callsrlistresultsr,s r.r/zFakeAddrInfoGetter.__init__es "4( r0c|jj||||||f|j|}|r|Sttd)a Mock for L{socket.getaddrinfo}. @param host: see L{socket.getaddrinfo} @param port: see L{socket.getaddrinfo} @param family: see L{socket.getaddrinfo} @param socktype: see L{socket.getaddrinfo} @param proto: see L{socket.getaddrinfo} @param flags: see L{socket.getaddrinfo} @return: L{socket.getaddrinfo} z,nodename nor servname provided, or not known)rOappendrQr r)r,hostportfamilysocktypeprotoflagsrQs r.r zFakeAddrInfoGetter.getaddrinfolsG$ 4vxFG,,t$ N:'UV Vr0r0cJ|j|j|||||fy)a Add a result for a given hostname. When this hostname is resolved, the result will be a L{list} of all results C{addResultForHost} has been called with using that hostname so far. @param host: The hostname to give this result for. This will be the next result from L{FakeAddrInfoGetter.getaddrinfo} when passed this host. @type canonname: native L{str} @param sockaddr: The resulting socket address; should be a 2-tuple for IPv4 or a 4-tuple for IPv6. @param family: An C{AF_*} constant that will be returned from C{getaddrinfo}. @param socktype: A C{SOCK_*} constant that will be returned from C{getaddrinfo}. @param proto: An C{IPPROTO_*} constant that will be returned from C{getaddrinfo}. @param canonname: A canonical name that will be returned from C{getaddrinfo}. @type canonname: native L{str} N)rQrT)r,rUsockaddrrWrXrY canonnames r.addResultForHostz#FakeAddrInfoGetter.addResultForHosts'H T!!68UIx"PQr0N)rrrr) r1r2r3r4r/r rr rr^r5r0r.rMrM`s&)W:$Rr0rMc0eZdZdZdZdZdZdZdZdZ y) ResultHolderzI A resolution receiver which holds onto the results it received. Fc||_y)z> Create a L{ResultHolder} with a L{UnitTest}. N) _testCase)r,testCases r.r/zResultHolder.__init__s "r0c.d|_||_g|_y)zg Hostname resolution began. @param hostResolution: see L{IResolutionReceiver} TN)_started _resolution _addresses)r,hostResolutions r.resolutionBeganzResultHolder.resolutionBegans  )r0c:|jj|y)z^ An address was resolved. @param address: see L{IResolutionReceiver} N)rgrT)r,addresss r.addressResolvedzResultHolder.addressResolveds w'r0cd|_y)z2 Hostname resolution is complete. TN)_endedrRs r.resolutionCompletezResultHolder.resolutionCompletes  r0N) r1r2r3r4rernr/rirlror5r0r.r`r`s'H F" (r0r`ceZdZdZdZy) HelperTestsz? Tests for error cases of helpers used in this module. ct\|_|_d}|jj||j|j t |j tdy)zq L{DeterministicThreadPool} will log any exceptions that its "thread" workers encounter. c ddz S)Nr&rr5r5r0r. divideByZeroz9HelperTests.test_logErrorsInThreads..divideByZeros q5Lr0r&N)r?pool doThreadWork callInThread assertEquallenflushLoggedErrorsZeroDivisionError)r,rts r.test_logErrorsInThreadsz#HelperTests.test_logErrorsInThreadss\ (9':$ 4$  |,  T334EFGKr0N)r1r2r3r4r|r5r0r.rqrqs  Lr0rqcLeZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z y ) HostnameResolutionTestsz( Tests for hostname resolution. ct\__t\__t _tjfdjj_ y)z* Set up a L{GAIResolver}. cjSr8rurRsr.r;z/HostnameResolutionTests.setUp.. $))r0N) r?rurvrKreactor doReactorWorkrMgetterrr resolverrRs`r.setUpzHostnameResolutionTests.setUpsU(9':$ 4$+F+H( d((* # LL+T[[-D-D  r0ct|}|jjdd|jj |d}|j |j ||j|jd|j|jd|j|j|j|jd|j|jtdddgy) z Resolving an individual hostname that results in one address from getaddrinfo results in a single call each to C{resolutionBegan}, C{addressResolved}, and C{resolutionComplete}. sample.example.com)4.3.2.1rTFTCPrrN)r`rr^rresolveHostNameassertIsrfrxrernrvrrgrr,receiver resolutions r.test_resolveOneHostz+HostnameResolutionTests.test_resolveOneHosts  % $$%9>J]]228=QR  h**J7 **D1 %0   $/ ,,{5)Q/O.PQr0c t|}d}d}|jjddd||ft|jj |d}|j |j||j|jd|j|jd|j|j|j|jd|j|jtd dd||gy ) a Resolving an individual hostname that results in one address from getaddrinfo results in a single call each to C{resolutionBegan}, C{addressResolved}, and C{resolutionComplete}; C{addressResolved} will receive an L{IPv6Address}. r&r::1r)rWTFrN)r`rr^rrrrrfrxrernrvrrgr)r,rflowInfoscopeIDrs r.test_resolveOneIPv6Hostz/HostnameResolutionTests.test_resolveOneIPv6Host s % $$ 5!Xw"? % ]]228=QR  h**J7 **D1 %0   $/    +eUAx"Q!R r0crt|}|jj|d}|j|j||j |j |j|jd|j|jd|j|jgy)a  Resolving a hostname that results in C{getaddrinfo} raising a L{gaierror} will result in the L{IResolutionReceiver} receiving a call to C{resolutionComplete} with no C{addressResolved} calls in between; no failure is logged. rTN) r`rrrrfrvrrxrernrgrs r. test_gaierrorz%HostnameResolutionTests.test_gaierror!s %]]228=QR  h**J7   **D1 $/ ,,b1r0c2t|}|jj|d|}|j|j||j |j |jjd\}}}}} } |j||y)z Verify that the given set of address types results in the given C{AF_} constant being passed to C{getaddrinfo}. @param addrTypes: iterable of L{IAddress} implementers @param expectedAF: an C{AF_*} constant r) addressTypesrN) r`rrrrfrvrrrOrx) r, addrTypes expectedAFrrrUrVrWrXrYrZs r._resolveOnlyTestz(HostnameResolutionTests._resolveOnlyTest1s %]]22 *3  h**J7  59[[5F5Fq5I2dFHeU ,r0c:|jtgty)z When passed an C{addressTypes} parameter containing only L{IPv4Address}, L{GAIResolver} will pass C{AF_INET} to C{getaddrinfo}. N)rrrrRs r.test_resolveOnlyIPv4z,HostnameResolutionTests.test_resolveOnlyIPv4Ds {mW5r0c:|jtgty)z When passed an C{addressTypes} parameter containing only L{IPv6Address}, L{GAIResolver} will pass C{AF_INET6} to C{getaddrinfo}. N)rrrrRs r.test_resolveOnlyIPv6z,HostnameResolutionTests.test_resolveOnlyIPv6Ks {mX6r0cp|jttgt|jdty)z When passed an C{addressTypes} parameter containing both L{IPv4Address} and L{IPv6Address} (or the default of C{None}, which carries the same meaning), L{GAIResolver} will pass C{AF_UNSPEC} to C{getaddrinfo}. N)rrrrrRs r.test_resolveBothz(HostnameResolutionTests.test_resolveBothRs) {K8)D dI.r0ct|}|jj|ddt|}|jj|dd|j|j |j|j |j j d\}}}}}}|j j d\}}}} }}|j|t|j| ty)z When passed a C{transportSemantics} paramter, C{'TCP'} (the value present in L{IPv4Address.type} to indicate a stream transport) maps to C{SOCK_STREAM} and C{'UDP'} maps to C{SOCK_DGRAM}. example.comr)transportSemanticsUDPrr&N) r`rrrvrrrOrxr r ) r,r receiver2rUrVrW socktypeTrYrZ socktypeUs r.#test_transportSemanticsToSocketTypez;HostnameResolutionTests.test_transportSemanticsToSocketType[s  % %%h RW%X &  %% } &     6:kk6G6G6J3dFIue6:kk6G6G6J3dFIue K0 J/r0cRt|}d}d}ttfD]L}|jj ddd||ft ||jj ddt |N|jj|d|j|j|j\}}}}|j|jd|j|jd|j|jd |j|jd y ) z When L{GAIResolver} receives a C{SOCK_DGRAM} result from C{getaddrinfo}, it returns a C{'TCP'} L{IPv4Address} or L{IPv6Address}; if it receives C{SOCK_STREAM} then it returns a C{'UDP'} type of same. r&rrrr)rWrX)z 127.0.0.3rrrN)r`r r rr^rrrrrvrrgrxtype) r,rrrrXstream4stream6dgram4dgram6s r.test_socketTypeToAddressTypez4HostnameResolutionTests.test_socketTypeToAddressTypeps   %#Z/ H KK ( (8W-! )  KK ( (/( )   %%h >  +3+>+>(&& u- u- e, e,r0N)r1r2r3r4rrrrrrrrrrr5r0r.r~r~s:  R" 02 -&67/0*-r0r~ceZdZdZdZddZy)SillyResolverSimplez6 Trivial implementation of L{IResolverSimple} cg|_y)zd Create a L{SillyResolverSimple} with a queue of requests it is working on. N) _requestsrRs r.r/zSillyResolverSimple.__init__s r0cf|jjt|jdS)z Implement L{IResolverSimple.getHostByName}. @param name: see L{IResolverSimple.getHostByName}. @param timeout: see L{IResolverSimple.getHostByName}. @return: see L{IResolverSimple.getHostByName}. )rrTr)r,r)timeouts r. getHostByNamez!SillyResolverSimple.getHostByNames' hj)~~b!!r0N)r5)r1r2r3r4r/rr5r0r.rrs "r0rc.eZdZdZdZdZdZdZdZy)LegacyCompatibilityTestsz Older applications may supply an object to the reactor via C{installResolver} that only provides L{IResolverSimple}. L{SimpleResolverComplexifier} is a wrapper for an L{IResolverSimple}. c t}t|}t|}|j|jd|j |d|j|jd|j|j d|j|jg|jdjd|j|jtdddg|j|j dy)z L{SimpleResolverComplexifier} translates C{resolveHostName} into L{IResolutionReceiver.addressResolved}. FrTr 192.168.1.1rN) rrr`rxrerrnrgrcallbackrr,simplecomplexrs r. test_successz%LegacyCompatibilityTests.test_successs %&,V4% **E2-8 **D1 %0 ,,b1$$]3 ,,{5-QR/S.TU $/r0ct}t|}t|}|j|jd|j |d|j|jd|j|j d|j|jg|jdjtd|j|j d|j|jgy)z L{SimpleResolverComplexifier} translates a known error result from L{IResolverSimple.resolveHostName} into an empty result. FrTrnopeN) rrr`rxrerrnrgrerrbackrrs r. test_failurez%LegacyCompatibilityTests.test_failures %&,V4% **E2-8 **D1 %0 ,,b1##N6$:; $/ ,,b1r0cbt}t|}t|}|j|jd|j |d|j|jd|j|j d|j|jg|jdjtd|jt|jtd|j|j d|j|jgy)z L{SimpleResolverComplexifier} translates an unknown error result from L{IResolverSimple.resolveHostName} into an empty result and a logged error. FrTrzowr&N) rrr`rxrerrnrgrrr{ryrzrs r. test_errorz#LegacyCompatibilityTests.test_errors %&,V4% **E2-8 **D1 %0 ,,b1##$5e$<= T334EFGK $/ ,,b1r0ct\__t\__t _tjfdjj_ tj}jjdd|jd}|jd}jj jj jj|j t"jj%|dy)z L{ComplexResolverSimplifier} translates an L{IHostnameResolver} into an L{IResolverSimple} for applications that still expect the old interfaces to be in place. cjSr8rrRsr.r;z:LegacyCompatibilityTests.test_simplifier..rr0r) 192.168.3.4znx.example.comrN)r?rurvrKrrrMrrr rrr^rrxfailureResultOfrrsuccessResultOf)r,simpleResolversuccessfailures` r.test_simplifierz(LegacyCompatibilityTests.test_simplifiers (9':$ 4$+F+H( d((* # LL+T[[-D-D  34==A $$]4IJ ..}= ../?@     --g6;;^L --g6 Fr0ct}t|}t|}|j|dd|j |j d|j |j d|j |jg|jdjd|j |jtdddg|j |j dy) z L{SimpleResolverComplexifier} preserves the C{port} argument passed to C{resolveHostName} in its returned addresses. rrTFrrrN) rrr`rrxrernrgrrrrs r.test_portNumberz(LegacyCompatibilityTests.test_portNumbers %&,V4%-> **D1 %0 ,,b1$$]3 ,,{5-QU/V.WX $/r0N) r1r2r3r4rrrrrr5r0r.rrs! 0"2"2&G.0r0rceZdZdZdZy)JustEnoughReactorzT Just enough subclass implementation to be a valid L{ReactorBase} subclass. cy)z Do nothing. Nr5rRs r. installWakerzJustEnoughReactor.installWakerr=r0N)r1r2r3r4rr5r0r.rr s  r0rc"eZdZdZdZdZdZy)ReactorInstallationTestsz Tests for installing old and new resolvers onto a L{PluggableResolverMixin} and L{ReactorBase} (from which all of Twisted's reactor implementations derive). ct}tt|tt|jtt |j y)z L{PluggableResolverMixin} (and its subclasses) implement both L{IReactorPluggableNameResolver} and L{IReactorPluggableResolver}. N)rrrr rr nameResolverr,rs r.test_interfaceCompliancez1ReactorInstallationTests.test_interfaceCompliances8 )*2G<_g&6&67&(<(<=r0ct}t}tt|j ||j |j t|j|j j|y)zf L{PluggableResolverMixin} will wrap an L{IResolverSimple} in a complexifier. N) rrrr installResolverassertIsInstancerrr_simpleResolver)r,rits r.test_installingOldStyleResolverz8ReactorInstallationTests.test_installingOldStyleResolver(sZ )* "_g&=&=b&AB g224NO g**::B?r0ct}|j|jt|j |jj t |j|jt|j |jj||j |jj|jy)zD L{ReactorBase} defaults to using a L{GAIResolver}. N) rrrrr _getaddrinfor rr_reactor _nameResolverrs r.test_defaultToGAIResolverz2ReactorInstallationTests.test_defaultToGAIResolver3s$% g22K@ g**77E g..0IJ g**33W= g&&44g6J6JKr0N)r1r2r3r4rrrr5r0r.rrs > @ Lr0rN);r4 collectionsrsocketrrrrrr r r r threadingr rzope.interfacerzope.interface.verifyrtwisted._threadsrrrtwisted.internet._resolverrrrtwisted.internet.addressrrtwisted.internet.baserrtwisted.internet.deferrtwisted.internet.errorrtwisted.internet.interfacesrrrr twisted.python.threadpoolr!twisted.trial.unittestr"UnitTestr$r?rKrMr`rqr~rrrrr5r0r.rs $   "&.AA >E+1 1B j   "IRIRX !$$"$NL(L(b-hb-J _"""4a0xa0H  %Lx%Lr0