ϪfRFdZddlmZddlmZ ddlZeZddlm Z ddl m Z ddl m Z mZddlmZdd lmZmZdd lmZdd lmZdd lmZdd lmZddlmZmZmZm Z m!Z!ddl"m#Z#ddl$m%Z%ddl&m'Z'm(Z(Gdde jRZ*GddejVZ+Gdde,Z-GddeZ.GddZ/GddeZ0y#e$rdZYwxYw)z# Tests for L{twisted.web.distrib}. )abspath) parseStringN)skipIf) verifyObject)deferreactor)globalLogPublisher)failurefilepath)pb SIZE_LIMIT) proto_helpers)TestCase)clientdistribresourceserverstatic)Headers)_render) DummyChannel DummyRequestc eZdZy)MySiteN)__name__ __module__ __qualname__?/usr/lib/python3/dist-packages/twisted/web/test/test_distrib.pyrr#sr rceZdZdZdZdZy)PBServerFactoryz A PB server factory which keeps track of the most recent protocol it created. @ivar proto: L{None} or the L{Broker} instance most recently returned from C{buildProtocol}. Ncdtjj|||_|jSN)r r# buildProtocolproto)selfaddrs r!r&zPBServerFactory.buildProtocol2s&''55dDA zzr )rrr__doc__r'r&rr r!r#r#'s Er r#ceZdZdZy)ArbitraryErrorz% An exception for this test. N)rrrr*rr r!r,r,7sr r,cjeZdZdZdZdZdZdZdZdZ dZ dZ dZ dZ d Zd Zd Zd Zd ZdZy) DistribTestsNcRtjtjg|j?|jj)|jjj fdndj d|j |j jk|j jjj fd|j jjjjndj d|j)j|jj|j)j|jjtjS)z Clean up all the event sources left behind by either directly by test methods or indirectly via some distrib API. Nc,djdSNrcallbackdlsr!z'DistribTests.tearDown..JsRU^^D5Ir rc,djdS)Nr2r4sr!r6z'DistribTests.tearDown..NsAPTAUr r8)rDeferredf1r'notifyOnDisconnectr3sub publisherbroker transportloseConnectionport1append stopListeningport2 gatherResults)r(r5s @r!tearDownzDistribTests.tearDownCs nn 0 1 77 477==#< GGMM , ,-I J qENN4 88 DHH$6$6$B HH   % % 8 89U V HH   % % / / > > @ qENN4 :: ! IIdjj..0 1 :: ! IIdjj..0 1""2&&r ctj}|jdtjddt j |}ttj||_ tjd|j|_ tjd|jjj |_tj}|jd|j"t%|}tjd||_t)j*t}d|j&jj d}|j-d }|j/d |}|j1t(j2|j1|j4d|S) Nstheresrootz text/plainr 127.0.0.1sherezhttp://127.0.0.1:z /here/thereasciiGET)rResourceputChildrDatarSiter#rResourcePublisherr:r listenTCPrAResourceSubscriptiongetHostportr<rrDrAgentencoderequest addCallbackreadBody assertEqual)r(r1site1r2f2agenturlds r! testDistribzDistribTests.testDistribXs@     Hfkk'<@A B!'";";E"BC&&q$''2 // TZZ=O=O=Q=V=VW     GTXX& BZ&&q"-  W%!$**"4"4"6";";![Q   112""$%::499diiPP8;;x($$QKH ../##%!!r c "|j|\}}tjt}d|jd|j d}|j d}|jd|fi|}|jtj|S)a Set up a resource on a distrib site using L{ResourcePublisher} and then retrieve it from a L{ResourceSubscription} via an HTTP client. @param child: The resource to publish using distrib. @param **kwargs: Extra keyword arguments to pass to L{Agent.request} when requesting the resource. @return: A L{Deferred} which fires with the result of the request. http://:/childrIrJ) rorrTrrerSrUrVrWrX)r(rfkwargsrmrnr^r_r`s r! _requestTestzDistribTests._requestTests}"55e<( W% a f=jj! EMM&# 0 0 foo&r c |j|\}}d|jd|jd}|jd}t j t jd|fi|}d}|j||S)a; Set up a resource on a distrib site using L{ResourcePublisher} and then retrieve it from a L{ResourceSubscription} via an HTTP client. @param child: The resource to publish using distrib. @param **kwargs: Extra keyword arguments to pass to L{Agent.request} when requesting the resource. @return: A L{Deferred} which fires with a tuple consisting of a L{twisted.test.proto_helpers.AccumulatingProtocol} containing the body of the response and an L{IResponse} with the response itself. rqrrrsrIrJctjjtjx}_|j fd|S)Nc fSr%r)_protocolresponses r!r6zGDistribTests._requestAgentTest..cbCollectBody..s Xx$8r )rAccumulatingProtocol deliverBodyrr9closedDeferredrW)r{r`rzs` @r! cbCollectBodyz5DistribTests._requestAgentTest..cbCollectBodysE$99;H   **/..*: :A' MM8 9Hr ) rorerSrUrrTrrVrW)r(rfrtrmrnr_r`rs r!_requestAgentTestzDistribTests._requestAgentTests}"55e<( a f=jj! )FLL ! ) )&# @ @  m$r c*itjtjdgGfddtj }fdj |tddgi}fd}|j||S) z The request headers are available on the request object passed to a distributed resource's C{render} method. NceZdZfdZy)>DistribTests.test_requestHeaders..ReportRequestHeadersct|d<jt|jjy)Nrr )updatedictrequestHeadersgetAllRawHeaders)r(rVreqrs r!renderzEDistribTests.test_requestHeaders..ReportRequestHeaders.renders1 A%%d7+A+A+R+R+T&UVr Nrrrr)rrsr!ReportRequestHeadersrs r rcDcgc]}|d }}jd|jd|jd|tjycc}w)N log_formatzconnected to publisherz3could not connect to distributed web service: {msg}r)assertInr removeObserver)emsgs logObserverrr(s r! check_logsz4DistribTests.test_requestHeaders..check_logss^-89AlO9D9 MM2D 9 MMOQU V MM#a&$ '  - -k : :s A#foobar)headersc|jjjjddgy)NsFoosbar)r:r'r;rY)resultrrr(s r! cbRequestedz5DistribTests.test_requestHeaders..cbRequesteds0 GGMM , ,Z 8   ^F3fX >r ) rEventLoggingObserverr addObserverrrKrurrW)r(rrVrrrrrs` @@@@r!test_requestHeadersz DistribTests.test_requestHeaderss #88: &&{3f 8#4#4   ;## "GUUG4D,E$  ? K(r cGddtj}j|}fd}|j||S)z The response code can be set by the request object passed to a distributed resource's C{render} method. ceZdZdZy)>DistribTests.test_requestResponseCode..SetResponseCodec&|jdy)NsetResponseCoder(rVs r!rzEDistribTests.test_requestResponseCode..SetResponseCode.renders'',r Nrrr r!SetResponseCoder r rcj|djdj|djdj|djdy)Nrr r8rsOKrYdatacodephraserr(s r!rz:DistribTests.test_requestResponseCode..cbRequestedsM   VAY^^S 1   VAY^^S 1   VAY--u 5r rrKrrWr(rrVrs` r!test_requestResponseCodez%DistribTests.test_requestResponseCodesD  h//  (():; 6 K(r cGddtj}j|}fd}|j||S)z The response code and message can be set by the request object passed to a distributed resource's C{render} method. ceZdZdZy)EDistribTests.test_requestResponseCodeMessage..SetResponseCodec(|jddy)Nr some-messagerrrs r!rzLDistribTests.test_requestResponseCodeMessage..SetResponseCode.renders''_=r Nrrr r!rrrr rcj|djdj|djdj|djdy)Nrr r8rrrrs r!rzADistribTests.test_requestResponseCodeMessage..cbRequestedsM   VAY^^S 1   VAY^^S 1   VAY-- ?r rrs` r!test_requestResponseCodeMessagez,DistribTests.test_requestResponseCodeMessagesE  h//  (():; @ K(r cGddtj}|j|}|j|jdt zdz|S)z If a string longer than the Banana size limit is passed to the L{distrib.Request} passed to the remote resource, it is broken into smaller strings to be transported over the PB connection. ceZdZdZy)0DistribTests.test_largeWrite..LargeWritecx|jdtzdz|jtjSNxy)writerfinishr NOT_DONE_YETrs r!rz7DistribTests.test_largeWrite..LargeWrite.render s. dZ/$67 ***r Nrrr r! LargeWriter s +r rrrrrKrurWrYr)r(rrVs r!test_largeWritezDistribTests.test_largeWritesM +** + ##JL1D,,dZ.?$.FGr cGddtj}|j|}|j|jdt zdz|S)z Like L{test_largeWrite}, but for the case where C{render} returns a long string rather than explicitly passing it to L{Request.write}. ceZdZdZy)2DistribTests.test_largeReturn..LargeReturncdtzdzSrr rs r!rz9DistribTests.test_largeReturn..LargeReturn.rendersj(4//r Nrrr r! LargeReturnrs 0r rrrr)r(rrVs r!test_largeReturnzDistribTests.test_largeReturnsM  0(++ 0##KM2D,,dZ.?$.FGr cTttjx_}t j d|x_}tjd|jjx_ }tdgt|}fd}|j||S)zz If there is an error issuing the request to the remote publisher, an error response is returned. rrHr cjjdjtj}jt |dgd}jdj |gjy)Nir8) r ss: 500 - Server Connection Losts s#

Server Connection Lost

s

Connection to distributed server lost:

[Failure instance: Traceback from remote host -- twisted.spread.flavors.NoSuchMethod: No such method: remote_requests]

s sr  )rY responseCodeflushLoggedErrorsr NoSuchMethodlenjoinwritten)ignorederrorsexpectedrVr(s r! cbRenderedz4DistribTests.test_connectionLost..cbRendered2sl   W113 7++BOO"> ++-22#  <u% L' * F2 j!r cPtjj|t}t j t }tdg}tj|}|j||jdt||jd|ddy)zQ When a request fails, the string form of the failure is logged. r r8zFailure instancerrN)rrcreateWithCleanupr r Failurer,rrIssuefailed assertEqualsrr)r(rfrVissues r!test_logFailedzDistribTests.test_logFailedNs$88JJ $  OON, -u% g& Q !S-. (+a.*FGr cvtjj|t}t }t j |}tjt}|j||jt|jdt||j|dd|y)zf When L{twisted.web.distrib.Request}'s fail is called, the failure is logged. r8r log_failureN)rrrr r,r rrRequestrfailrrrassertIs)r(rerrrrs r!test_requestFailzDistribTests.test_requestFail]s $88JJ $  OOC ooln-   ~. !S-. k!n]3Q7r )rrrrArDr<r:rFrarorurrrrrrrrrrr r!r.r.=sZ E E C B'*("6&: D**" *X H8r r.ceZdZdZdZdZy)_PasswordDatabasec||_yr%)_users)r(userss r!__init__z_PasswordDatabase.__init__os  r c,t|jSr%)iterrr(s r!getpwallz_PasswordDatabase.getpwallrsDKK  r cP|jD]}|d|k(s |cStr1)rKeyError)r(usernameusers r!getpwnamz_PasswordDatabase.getpwnamus0KK DAw("  jr N)rrrrrrrr r!rrns!r rcpeZdZdZdZdZdeddfdZdZd Z d Z d Z d Z d Z ee ddZy)UserDirectoryTestszj Tests for L{UserDirectory}, a resource for listing all user resources available on a system. cddddd|jdf|_dddd d |jdf|_t|j|jg|_t j |j|_y) Nalicex{izAlice,,,z/bin/shbobi7zBob,,,)mktemprrrdatabaser UserDirectory directoryrs r!setUpzUserDirectoryTests.setUpsisCj$++-S 3S(DKKM9M)4::txx*@A  ..t}}=r cj|jttj|jy)zK L{UserDirectory} instances provide L{resource.IResource}. N) assertTruerr IResourcerrs r!test_interfacez!UserDirectoryTests.test_interfaces!  X%7%7HIr namereturnNcKt|g}|jj||}t||}|d{|j |j dy7!w)zr Verify that requesting the C{name} child of C{self.directory} results in a 404 response. Ni)rrgetChildrrYr)r(rrVrr`s r!_404TestzUserDirectoryTests._404TestsX v&((w7 FG $ --s3 s:A A"A cBK|jdd{y7w)z L{UserDirectory.getChild} returns a resource which renders a 404 response when passed a string which does not correspond to any known user. scarolNrrs r!test_getInvalidUserz&UserDirectoryTests.test_getInvalidUser mmH%%% cBK|jdd{y7w)z L{UserDirectory.getChild} returns a resource which renders a 404 response when passed a string which corresponds to a known user who has neither a user directory nor a user distrib socket. saliceNrrs r!test_getUserWithoutResourcez.UserDirectoryTests.test_getUserWithoutResourcerrcftj|jd}|jd}|j t dg}|j jd|}|j|tj|j|j|jy)z L{UserDirectory.getChild} returns a L{static.File} instance when passed the name of a user with a home directory containing a I{public_html} directory. public_htmlrsbobN) r FilePathrrfmakedirsrrrassertIsInstancerFilerYpath)r(homerrVrs r!test_getPublicHTMLChildz*UserDirectoryTests.test_getPublicHTMLChilds   ".jj/ w'((9 ffkk2 k&6&67r ctj|jd}|j|j d}t dg}|j jd|}|j|tj|j|jd|jt|j|jy)z L{UserDirectory.getChild} returns a L{ResourceSubscription} instance when passed the name of a user suffixed with C{".twistd"} who has a home directory containing a I{.twistd-web-pb} socket. r.twistd-web-pbrs bob.twistdunixN)r rrrrfrrrrrrQrYrerrSr!)r(r"webrVrs r!test_getDistribChildz'UserDirectoryTests.test_getDistribChilds   ". jj)*w'((@ fg&B&BC f- -sxx8r ctdg}d|_|jtj|j j |y)zr L{UserDirectory.render} raises L{UnsupportedMethod} in response to a non-I{GET} request. rPOSTN)rmethod assertRaisesrUnsupportedMethodrrrs r!test_invalidMethodz%UserDirectoryTests.test_invalidMethods9 t$ &22DNN4I4I7Sr ctjjdjd}|j tjj d}|j |jdj dtdgtj}fd}|j||S)z} L{UserDirectory} renders a list of links to available user content in response to a I{GET} request. rrr%r rcztdjj}|jd\}}j |j j dj |j jddj |j j jdj |j j dj |j jddj |j j jdy) Nr liahrefzalice/z Alice (file)z bob.twistd/z Bob (twistd)) rrrgetElementsByTagNamerY firstChildtagName getAttributer)rdocumentrrrVr(s r!rz2UserDirectoryTests.test_render..cbRendereds"388GOO#<=H$88>LUC   U--55s ;   U--::6BH M   U--88==~ N   S^^33S 9   S^^88@- P   S^^66;;^ Lr ) r rrrfrr setContentrrrrW)r(rr'rrrVs` @r! test_renderzUserDirectoryTests.test_renders '' 27==mL  -  "#..s3t$1 M :& r zpwd module requiredcltj}|j|jty)z If L{UserDirectory} is instantiated with no arguments, it uses the L{pwd} module as its password database. N)rrassertIdentical_pwdpwd)r(rs r!test_passwordDatabasez(UserDirectoryTests.test_passwordDatabases& ))+  Y^^S1r )rrrr*r r bytesrrrr#r(r.r:rr>r?rr r!rr|sc > J 45 4T 4&& 8 9T@ G*+2,2r r)1r*os.pathrxml.dom.minidomrr>r= ImportErrorunittestrzope.interface.verifyrtwisted.internetrrtwisted.loggerr twisted.pythonr r twisted.spreadr twisted.spread.bananar twisted.testrtwisted.trial.unittestr twisted.webrrrrrtwisted.web.http_headersrtwisted.web.test._utilrtwisted.web.test.requesthelperrrrNrr# Exceptionr,r.rrrr r!rRs' C.+-,,&+AA,*E V[[  b((  Y n88n8b  z2z2_  CsCCC