Ϫf) dZddlZddlZddlmZmZmZmZddlm Z ddl m Z ddl m Z mZddlmZmZmZmZmZmZddlmZdd lmZdd lmZdd lmZdd lmZdd l m!Z! ddlm"Z#e#jHsdZ"ne#Z" e"dZ&ndZ&ejNjQesdZ)ndZ)ejTjVZ,GddejZZ.Gddej^Z0Gdde1Z2Gdde1Z3Gdde1Z4GddejjZ6GddejnZ8Gdd e8Z9Gd!d"ejnZ:Gd#d$ejnZ;Gd%d&ejnZ<Gd'd(ejnZ=Gd)d*ejnZ>Gd+d,ejnZ?Gd-d.ejnZ@Gd/d0ejnZAGd1d2ejZCGd3d4ejZEd5ZFGd6d7e1ZGGd8d9ej^ZHGd:d;eHZIGd<d=eIZJGd>d?eIZKGd@dAeIZLe0e0fdBZMGdCdDejZZNGdEdFej^ZOGdGdHe!ZPGdIdJe!ZQGdKdLZRGdMdNZSGdOdPe!ZTGdQdRejnZUGdSdTejZWGdUdVeWZXGdWdXeXZYGdYdZej^ZZGd[d\e!Z[d]Z\d^Z]Gd_d`e!Z^Gdadbe!Z_GdcddZ`GdedfZaGdgdheaZbGdidjeaZcGdkdleaZdGdmdneHZee e&doe e)dpGdqdre!ZfGdsdte!ZgGdudve1ZhGdwdxe1ZiGdydzejnZjGd{d|ejZkGd}d~ejZlGddej^ZmGddej^ZnGddej^ZoGdde!ZpdZqGddZrdZsdZte"etZue e&doe e)dpGddere!ZvGddeIZwe e&doe e)dpGddere!Zxe e&doe e)dpGddere!ZyGddejjZzGddejnZ{GddejnZ|Gddej^Z}edZ~edZGddee~efZGdde{ZGdde!ZGddZGdde!eZGdde!eZGdde!eZGdde!eZGdde!eZGdde!ZGdde!ZGdde!eZGdde!Ze ejGddZe ejee ejeGdde!ZGdde!ZGdde!ZGdde!Zy#e%$rdZ"YwxYw)z% Tests for L{twisted.protocols.amp}. N)ClassVarDictTypeTypeVar)skipIf) implementer) verifyClass verifyObject)addressdefererror interfacesprotocolreactor)StringTransport)amp)filepath)Failure)iosim)TestCasesslTFc8eZdZdZdZdZdZdZdZde fdZ y ) TestProtoz A trivial protocol for use in testing where a L{Protocol} is expected. @ivar instanceId: the id of this instance @ivar onConnLost: deferred that will fired when the connection is lost @ivar dataToSend: data to send on the protocol rct|tsJt|||_||_t j |_t j dzt _y)N) isinstancebytesrepr onConnLost dataToSendr instanceCount instanceId)selfr r!s 7/usr/lib/python3/dist-packages/twisted/test/test_amp.py__init__zTestProto.__init__=sJ*e,>d:.>>,$$#11"+"9"9A"= c\g|_|jj|jyN)data transportwriter!r$s r%connectionMadezTestProto.connectionMadeDs  T__-r'c:|jj|yr))r*append)r$rs r% dataReceivedzTestProto.dataReceivedHs r'cN|jj|jyr))r callbackr*r$reasons r%connectionLostzTestProto.connectionLostKs   +r'returnc"d|jfzS)z Custom repr for testing to avoid coupling amp tests with repr from L{Protocol} Returns a string which contains a unique identifier that can be looked up using the instanceId property:: z)r#r-s r%__repr__zTestProto.__repr__Ns!DOO#555r'N) __name__ __module__ __qualname____doc__r"r&r.r1r6strr9r'r%rr2s.M>. , 6# 6r'rceZdZdZdZy)SimpleSymmetricProtocolc(|jd|SNhellohello)callRemoteStringr$texts r% sendHelloz!SimpleSymmetricProtocol.sendHello\s$$XT$::r'c4tj|dSrCrBoxr$boxs r% amp_HELLOz!SimpleSymmetricProtocol.amp_HELLO_swwS]++r'N)r:r;r<rJrPr?r'r%rArA[s ;,r'rAceZdZdZy)UnfriendlyGreeting!Greeting was insufficiently kind.Nr:r;r<r=r?r'r%rRrRc+r'rRceZdZdZy) DeathThreatrSNrTr?r'r%rWrWgrUr'rWceZdZdZy)UnknownProtocolz&Asked to switch to the wrong protocol.NrTr?r'r%rYrYks0r'rYceZdZdZdZdZy) TransportPeercy)Nr'r?)r$dnameprotos r%retrievezTransportPeer.retrieversr'c6|jjSr))r+getPeer)r$ notAStringr_s r%fromStringProtozTransportPeer.fromStringProtous&&((r'cyr)r?)r$r^stringsobjectsr_s r%toBoxzTransportPeer.toBoxxsr'N)r:r;r<r`rdrhr?r'r%r[r[os)r'r[c eZdZUdZdej fdej dfdejdfdedfdej dfdej dfd ej dfgZ dej fdejdfgZ e d iZ e eeeefed <ed iZe eeeefed <y)HellorDoptionalToptionalprintfrom mixedCasedash-argunderscore_arg UNFRIENDLYerrorssDEAD fatalErrorsN)r:r;r< commandNamerStringBooleanUnicoder[ argumentsresponserRrtrrr Exceptionr__annotations__rWrur?r'r%rjrj|sK :3::< kckk401 ;3;;-. -./ zszz401 jcjj$/0 JCJJ56I:3::<(8[S[[$5O*PQH6H-5XFHT$y/501 2X;F:PK$tI567Pr'rjc(eZdZejZdZy) NoAnswerHelloFN)r:r;r<rjrvrequiresAnswerr?r'r%rrs##KNr'rceZdZdZdej fdej dfdejdfdedfdej dfgZ dej fdejdfgZ e diZ y ) FutureHellorDrkTrlrnrosbonusrsN) r:r;r<rvrrwrxryr[rzr{rRrtr?r'r%rrsK :3::< kckk401 ;3;;-. -./ :3::t,- I:3::<(8[S[[$5O*PQH - 0Fr'rceZdZdZy)WTFz+ An example of an invalid command. NrTr?r'r%rrr'rceZdZdZdZy) BrokenReturnz[An example of a perfectly good command, but the handler is going to return None... s broken_returnN)r:r;r<r=rvr?r'r%rrs#Kr'rcLeZdZdejfgZej Zy)GoodbyesgoodbyeN)r:r;r<rrwr{QuitBox responseTyper?r'r%rrs ZSZZ\*+H;;Lr'rceZdZdZy) WaitForevers wait_foreverN)r:r;r<rvr?r'r%rrs!Kr'rceZdZdZdej fgZdejdej fgfgZy)GetListsgetlistslengthbodyxN) r:r;r<rvrIntegerrzAmpListr{r?r'r%rrsDK[[]+,I+#++kckkm'<&=>?@Hr'rceZdZdZdej fdej dej fgdfgZdej fgZy) DontRejectMes dontrejectmes magicWordslistnameTrlsresponseN) r:r;r<rvrryrrzr{r?r'r%rrsZ!K {s{{}% +#++784HIIkckkm,-Hr'rc4eZdZdejfgZy) SecuredPingspingedN)r:r;r<rrxr{r?r'r%rrsKCKKM*+Hr'rc@eZdZdZdej fgZediZy)TestSwitchProtos Switch-ProtorsUNKNOWNN) r:r;r<rvrrwrzrYrtr?r'r%rrs,!K *#**,Iz *Fr'rc"eZdZdZdZdZdZy)SingleUseFactoryc4||_||j_yr))r_factory)r$r_s r%r&zSingleUseFactory.__init__s ! r'c.|jdc}|_|Sr))r_)r$addrps r% buildProtocolzSingleUseFactory.buildProtocols D 4:r'Nc||_yr)) reasonFailedr$ connectorr5s r%clientConnectionFailedz'SingleUseFactory.clientConnectionFaileds "r')r:r;r<r&rrrr?r'r%rrs"Lr'rs gwebol nargoc eZdZy)ThingIDontUnderstandErrorN)r:r;r<r?r'r%rrsr'rc>eZdZdZdZdZejey)FactoryNotifierNc|jN||j_t|jdr&|jjj dyyy)NonMade)rtheProtohasattrrr3r-s r%r.zFactoryNotifier.connectionMadesH << #$(DLL !t||X. ##,,T2/ $r'cbddlm}|j|js t dddiS)Nr) ISSLTransportz+only send secure pings over secure channelspingedT)twisted.internet.interfacesr providedByr+rW)r$rs r%emitpongzFactoryNotifier.emitpongs.=''7KL L$r')r:r;r<rr.rr responderr?r'r%rrs!G3  (#r'rcVeZdZdZddZdZdZdZ ddZe jedZ e je ddZ eje d Zejed Zejedd Zd Zejed Zejey)SimpleSymmetricCommandProtocolNcPtjj|||_yr))rAMPr&r )r$r s r%r&z'SimpleSymmetricCommandProtocol.__init__ s $r'c0|jt|S)NrE callRemoterjrHs r%rJz(SimpleSymmetricCommandProtocol.sendHellosuD11r'c2|jt||S)NrFPrintr)r$rI translations r%sendUnicodeHelloz/SimpleSymmetricCommandProtocol.sendUnicodeHellosuD DDr'Fc"||jjk(sJ|tk(r t|j dr t d|dk(r t dt|}||jt|d|_ |S)NsfuckDon't be a dick.die aieeeeeeeeerE)rT) r+rbTHING_I_DONT_UNDERSTANDr startswithrRrWdictupdategreeted) r$rFFromrmr mixedCasedash_argunderscore_argresults r%cmdHelloz'SimpleSymmetricCommandProtocol.cmdHellost~~--//// + ++- -   G $$%78 8 F?m, ,E"   MM$U+ ,  r'c&dtdg|ziS)Nbodyr)xr)r$lengths r% cmdGetlistz)SimpleSymmetricCommandProtocol.cmdGetlist/s f,--r'c:|d}n d|ddz}t|S)N list omittedz %s acceptedrr^)r{r)r$ magicWordlistr{s r%okiwontz&SimpleSymmetricCommandProtocol.okiwont4s) <%H$Q8HX&&r'cLtj|_|jSr))r Deferredwaitingr-s r% waitforitz(SimpleSymmetricCommandProtocol.waitforit=s~~' ||r'ctdS)Neveryone)goodbyerr-s r%saybyez%SimpleSymmetricCommandProtocol.saybyeCs K((r'c|rd}nd}t|jt|jtt |j fdS)Nsno-proto test-proto)r^cSr)r?)ignrs r%zESimpleSymmetricCommandProtocol.switchToTestProtocol..Ps!r')rr SWITCH_CLIENT_DATArrr addCallback)r$failr^rs @r%switchToTestProtocolz3SimpleSymmetricCommandProtocol.switchToTestProtocolHsN D D doo'9 : -a0t +m $ %r'cV|dk(rt|jtSt|Nr)rr SWITCH_SERVER_DATArYr$r^s r%switchitz'SimpleSymmetricCommandProtocol.switchitRs' = T__.@A Ad##r'cyr)r?r-s r% donothingz(SimpleSymmetricCommandProtocol.donothingYr'r)NNNNN)F)r:r;r< maybeLaterr&rJrrrrjrrrrrrrrrrrrrrr?r'r%rrsJ%2EG . OOH. j!'7#)$) f%$ h'9%r'rc4eZdZdZej ey) DeferredSymmetricCommandProtocolc|dk(rDt|jt|_t j |_|j Syr)rr rmaybeLaterProtor rrrs r%rz)DeferredSymmetricCommandProtocol.switchit`s; = #,T__>P#QD #nn.DO?? " !r'N)r:r;r<rrrr?r'r%rr_s# h'r'rc@eZdZ ddZej ey)BadNoAnswerCommandProtocolNcy)zQ This responder does nothing and forgets to return a dictionary. Nr?r$rFrrmrrrrs r% badResponderz'BadNoAnswerCommandProtocol.badResponderjr'r)r:r;r<rrrr?r'r%rris(   L)r'rc@eZdZ ddZej ey)NoAnswerCommandProtocolNc t|dzS)Ns -noanswerrErrs r%goodNoAnswerResponderz-NoAnswerCommandProtocol.goodNoAnswerResponder|s%,.//r'r)r:r;r<rrrr?r'r%rr{s)  012r'rc6tj||g|i|S)z)Returns a 3-tuple: (client, server, pump))rconnectedServerAndClient) ServerClass ClientClassakws r%rrs!  ) )+{ MQ M" MMr'ceZdZdZdZy)TotallyDumbProtocolr'c.|xj|z c_yr))bufr$r*s r%r1z TotallyDumbProtocol.dataReceiveds Dr'N)r:r;r<rr1r?r'r%r r s Cr'r ceZdZdZdZy) LiteralAmpcg|_yr))boxesr-s r%r&zLiteralAmp.__init__s  r'c:|jj|yr)rr0rNs r%ampBoxReceivedzLiteralAmp.ampBoxReceiveds #r'N)r:r;r<r&rr?r'r%rrs r'rc"eZdZdZdZdZdZy) AmpBoxTestszm Test a few essential properties of AMP boxes, mostly with respect to serialization correctness. ctjd}|jt|j t y)z8 Make sure that strs serialize to strs. svaluekeyN)rAmpBox assertEqualtype serializerr$r s r%test_serializeStrzAmpBoxTests.test_serializeStrs- JJ8 $ akkm,e4r'crtjdiddi}|jt|jy)zX Verify that TypeError is raised when trying to serialize Unicode keys. rvalueNr?rr assertRaises TypeErrorr r!s r%test_serializeUnicodeKeyRaisesz*AmpBoxTests.test_serializeUnicodeKeyRaisess. JJ *%) * )Q[[1r'cptjd}|jt|jy)zb Verify that TypeError is raised when trying to serialize Unicode values. r$rNr%r!s r% test_serializeUnicodeValueRaisesz,AmpBoxTests.test_serializeUnicodeValueRaisess& JJ7 # )Q[[1r'N)r:r;r<r=r"r(r*r?r'r%rrs 522r'rc$eZdZdZdZdZdZy) ParsingTestsctj}|j|jd|j |jd|j t |jd|j t |jd|j t |jd|j|jdd|j|jddy) ze Verify that the Boolean parser parses 'True' and 'False', but nothing else. sTruesFalsesninjastruesTRUETFN) rrx assertTrue fromString assertFalser&r'rtoString)r$bs r%test_booleanValueszParsingTests.test_booleanValuess KKM  W-. h/0 )Q\\8< )Q\\7; )Q\\7; D)73 E*H5r'ctj|j}tj}|j |}|j |}|j|||j||y)zL Verify the 'Path' argument can parse and emit a file path. N) rFilePathmktemprPathr1r/ assertIsNotr)r$fprsvs r%test_pathValueRoundTripz$ParsingTests.test_pathValueRoundTrips_  t{{} - HHJ JJrN LLO Q Qr'ctj}|jtj|jtj S)zk Test that empty boxes raise an error; they aren't supposed to be sent on purpose. )rrr& NoEmptyBoxesrrMr!s r%test_sillyEmptyThingz!ParsingTests.test_sillyEmptyThings6 GGI  !1!113C3CSWWYOOr'c zttt\}}}d}d}d}d}d}d} d} |g|| g||g||g||||g|||g|||| g| ||gg} | D]p} tj} | j t | | j ||j|j|jd | ry ) zq Verify that various kinds of data make it through the encode/parse round-trip unharmed. )r r)simplestest)sceqs: )scrteststest )slftestshello )snewlinestest one two)snewline2stest one two)rsblah testtestN) rrrrMrr_sendToflushrr)r$cr:rSIMPLECECRLFNEWLINENEWLINE2BODYTESTtestDatatestjbs r%test_ParsingRoundTripz"ParsingTests.test_ParsingRoundTrips +"  1a&  # $585H X  RL RL RR RL Wb( + vw '   .DB IId4j ! JJqM GGI   QWWR[" -  .r'N)r:r;r<r3r<r?rPr?r'r%r,r,s 6  P!.r'r,ceZdZdZdZdZy) FakeLocatorzZ This is a fake implementation of the interface implied by L{CommandLocator}. ci|_y)zN Remember the given keyword arguments as a set of responders. Ncommandsr-s r%r&zFakeLocator.__init__ s  r'c |j|S)zz Look up and return a function passed as a keyword argument of the given name to the constructor. rT)r$rvs r%locateResponderzFakeLocator.locateResponders }}[))r'N)r:r;r<r=r&rWr?r'r%rRrRs  *r'rRc(eZdZdZdZdZdZdZy) FakeSenderz\ This is a fake implementation of the 'box sender' interface implied by L{AMP}. c.g|_g|_d|_y)zn Create a fake sender and initialize the list of received boxes and unhandled errors. rN) sentBoxesunhandledErrorsexpectedErrorsr-s r%r&zFakeSender.__init__s !r'c.|xjdz c_y)zB Expect one error, so that the test doesn't fail. rN)r]r-s r% expectErrorzFakeSender.expectError(s q r'c:|jj|y)z6 Accept a box, but don't do anything. N)r[r0rNs r%sendBoxzFakeSender.sendBox.s c"r'c|xjdzc_|jdkr|jy|jj|y)zW Deal with failures by instantly re-raising them for easier debugging. rrN)r]raiseExceptionr\r0)r$failures r%unhandledErrorzFakeSender.unhandledError4sC q     "  " " $  ' ' 0r'N)r:r;r<r=r&r_rarer?r'r%rYrYs  ! # 1r'rYc@eZdZdZdZdZdZdZdZdZ dZ d Z y ) CommandDispatchTestsa The AMP CommandDispatcher class dispatches converts AMP boxes into commands and responses using Command.responder decorator. Note: Originally, AMP's factoring was such that many tests for this functionality are now implemented as full round-trip tests in L{AMPTests}. Future tests should be written at this level instead, to ensure API compatibility and to provide more granular, readable units of test coverage. ct|_t|_t j |j|_|j j|jy)z- Create a dispatcher to use. N)rRlocatorrYsenderr BoxDispatcher dispatcherstartReceivingBoxesr-s r%setUpzCommandDispatchTests.setUpKsB#}  l ++DLL9 ++DKK8r'cgfd}tjddd}||jjd<|jj ||j |gy)z L{CommandDispatcher.ampBoxReceived} should locate the appropriate command in its responder lookup, based on the '_ask' key. cTj|tjddiS)NrFr)r0rrM)rOreceiveds r%thunkz4CommandDispatchTests.test_receivedAsk..thunk[s# OOC 77GY/0 0r'rFtest-command-idworld_command_askrFN)rrMrirUrlrr)r$rrinputrqs @r%test_receivedAskz%CommandDispatchTests.test_receivedAskTs\  1/@P). g& &&u- E7+r'cZtd}|jj|jj t ||j t|jjd|j |jjdj|y)zy L{CommandDispatcher} should relay its unhandled errors in responding to boxes to its boxSender. zsomething went wrong, oh norrN) RuntimeErrorrjr_rlrerrlenr\r$)r$errs r%test_sendUnhandledErrorz,CommandDispatchTests.test_sendUnhandledErrordsy 89 ! &&ws|4 T[[8891= 44Q7==sCr'ctdfd}||jjd<tjddd}|j j |jj||jt|j jd|j|j jdjy ) zp Errors during serialization ought to be relayed to the sender's unhandledError method. zsomething undefined went wrongcHGfddtj}|S)NceZdZfdZy)WCommandDispatchTests.test_unhandledSerializationError..thunk..BrokenBoxcr)r?)r$r_r}s r%rCz_CommandDispatchTests.test_unhandledSerializationError..thunk..BrokenBox._sendToxsIr'N)r:r;r<rC)r}sr% BrokenBoxrwsr'rrL)rrr}s r%rrzDCommandDispatchTests.test_unhandledSerializationError..thunkvs CGG ; r'rFrsrtrurrN) r{rirUrrMrjr_rlrrr|r\r$)r$rrrxr}s @r% test_unhandledSerializationErrorz5CommandDispatchTests.test_unhandledSerializationErroros ;< */ g&/@P ! &&u- T[[8891= 44Q7==sCr'c|jjtd}|j|jj t jdddgg}|j|j|j|g|jjt jdddd|j|tdd gy ) a[ L{CommandDispatcher.callRemote} should emit a properly formatted '_ask' box to its boxSender and record an outstanding L{Deferred}. When a corresponding '_answer' packet is received, the L{Deferred} should be fired, and the results translated via the given L{Command}'s response de-serialization. worldrErD1ruyayignoredrDrns_answerignoredrN) rlrrjrrjr[rrrr0rr)r$Danswerss r%test_callRemotez$CommandDispatchTests.test_callRemotes OO & &uH & =  KK ! ! ZZH E F  gnn% "% && JJ&JDQ R  4fI#F"GHr'c0g}|j|j|jdt|jj |j |jj djt|jdg|y)z Verify that C{callResult} completes with a L{None} result and that an unhandled error has been logged. rrN) addBothr0rr|rjr\assertIsInstancer$ZeroDivisionError)r$ callResult finalResults r%_localCallbackErrorLoggingTestz3CommandDispatchTests._localCallbackErrorLoggingTestst  ;--. C ; ;<= dkk99!<BBDUV $-r'c$|jj|jjtd}|j d|jj tjdddd|j|y) z If the last callback on the L{Deferred} returned by C{callRemote} (added by application code calling C{callRemote}) fails, the failure is passed to the sender's C{unhandledError} method. rrEc ddzSNrrr?rs r%rzVCommandDispatchTests.test_callRemoteSuccessLocalCallbackErrorLogging..s a1fr'rrrrN) rjr_rlrrjrrrrrr$rs r%/test_callRemoteSuccessLocalCallbackErrorLoggingzDCommandDispatchTests.test_callRemoteSuccessLocalCallbackErrorLoggingsq !__//X/F 45 && JJ&JDQ R  ++J7r'c$|jj|jjtd}|j d|jj tjdddd|j|y) z Like L{test_callRemoteSuccessLocalCallbackErrorLogging}, but for the case where the L{Deferred} returned by C{callRemote} fails. rrEc ddzSrr?rs r%rzTCommandDispatchTests.test_callRemoteErrorLocalCallbackErrorLogging..s Q!Vr'rsbugssstuff)_error _error_code_error_descriptionN) rjr_rlrrj addErrbackrrrrrs r%-test_callRemoteErrorLocalCallbackErrorLoggingzBCommandDispatchTests.test_callRemoteErrorLocalCallbackErrorLoggingsx !__//X/F 34 && JJ#$++3   ++J7r'N) r:r;r<r=rnryr~rrrrrr?r'r%rgrg?s2 9, DD*I* .8"8r'rgceZdZdZdZdej fdejfgZdejfgZ y)SimpleGreetingzN A very simple greeting command that uses a few basic argument types. rAsgreetingscookies cookieplusN) r:r;r<r=rvrryrrzr{r?r'r%rrsGK{s{{}- ;3;;=/IJI  ./Hr'rc>eZdZdZdZdZejeZy) TestLocatorzI A locator which implements a responder to the 'simple' command. cg|_yr)) greetingsr-s r%r&zTestLocator.__init__s r'cZ|jj||ft|dzSN cookieplusrr0rr$greetingcookies r%greetingResponderzTestLocator.greetingResponder( x01vz**r'N)r:r;r<r=r&rrrr?r'r%rrs%+'001BCr'rc8eZdZdZdZej eZy)OverridingLocatorzJ A locator which overrides the responder to the 'simple' command. cZ|jj||ft|dzS)zV Return a different cookieplus than L{TestLocator.greetingResponder}. rrrs r%rz#OverridingLocator.greetingResponders* x01vz**r'N)r:r;r<r=rrrr?r'r%rrs +'001BCr'rceZdZdZy)InheritingLocatorzN This locator should inherit the responder from L{OverridingLocator}. NrTr?r'r%rrrr'rcLeZdZdZfdZdZejeZxZS)OverrideLocatorAMPctjj|t|_d|ji|_g|_yNscustom)rrr&objectcustomResponder expectationsrr-s r%r&zOverrideLocatorAMP.__init__s8 %x&(<(<=r'c`||jvr|j|}|St| |S)zB Override the deprecated lookupFunction function. )rsuperlookupFunction)r$r^r __class__s r%rz!OverrideLocatorAMP.lookupFunctions8 4$$ $&&t,FM7)$/ /r'cZ|jj||ft|dzSrrrs r%rz$OverrideLocatorAMP.greetingResponder rr') r:r;r<r&rrrr __classcell__)rs@r%rrs& 0+'001BCr'rc4eZdZdZdZdZdZdZdZdZ y) CommandLocatorTestsz The CommandLocator should enable users to specify responders to commands as functions that take structured objects, annotated with metadata. c|}|jd}|tjdd}fd}|j|S)z Check that a locator of type C{locatorClass} finds a responder for command named I{simple} and that the found responder answers with the C{expected} result to a C{SimpleGreeting<"ni hao", 5>} command. rAni hao5rrcZj|tjdfzy)Ns%drrrr)valuesexpectedr$s r%donez6CommandLocatorTests._checkSimpleGreeting..done%s#   VSZZ5H;;N%O Pr')rWrrMr)r$ locatorClassrriresponderCallablerrs` ` r%_checkSimpleGreetingz(CommandLocatorTests._checkSimpleGreetingsK.#33I>"377Id#KL Q!!$''r'c.|jtdS)z A method on a L{CommandLocator} subclass decorated with a L{Command} subclass's L{responder} decorator should be returned from locateResponder, wrapped in logic to serialize and deserialize its arguments. )rrr-s r%test_responderDecoratorz+CommandLocatorTests.test_responderDecorator*s((a88r'c.|jtdS)z L{CommandLocator} subclasses can override a responder inherited from a base class by using the L{Command.responder} decorator to register a new responder method. )rrr-s r%test_responderOverridingz,CommandLocatorTests.test_responderOverriding3s (():A>>r'c.|jtdS)z Responder lookup follows the same rules as normal method lookup rules, particularly with respect to inheritance. r)rrr-s r%test_responderInheritancez-CommandLocatorTests.test_responderInheritance;s (():A>>r'c4tjtdtfd}j j |jtdtfd}|t jdd}fd}|j|S)a0 Subclasses which override locateResponder under its old name, lookupFunction, should have the override invoked instead. (This tests an AMP subclass, because in the version of the code that could invoke this deprecated code path, there was no L{CommandLocator}.) z-Override locateResponder, not lookupFunction.c&jdSrrWrisr%rzKCommandLocatorTests.test_lookupFunctionDeprecatedOverride..NG++I6r'c&jdSNrArrsr%rzKCommandLocatorTests.test_lookupFunctionDeprecatedOverride..Vrr'rrrcRj|tjdyN8rrrr$s r%rzGCommandLocatorTests.test_lookupFunctionDeprecatedOverride..doneZ   VSZZ4%@ Ar') r assertWarnsPendingDeprecationWarning__file__rrrrMr)r$customResponderObjectnormalResponderObjectrrris` @r%%test_lookupFunctionDeprecatedOverridez9CommandLocatorTests.test_lookupFunctionDeprecatedOverrideBs%& $ 0 0 % ;  6 !  002GH $ 0 0 % ;  6 !  'sww $'OP B!!$''r'ctjtdtfd}|t j dd}fd}|j |S)z Invoking locateResponder under its old name, lookupFunction, should emit a deprecation warning, but do the same thing. z)Call locateResponder, not lookupFunction.c&jdSr)rrsr%rzICommandLocatorTests.test_lookupFunctionDeprecatedInvoke..isG**95r'rrrcRj|tjdyrrrs r%rzECommandLocatorTests.test_lookupFunctionDeprecatedInvoke..donemrr')rrrrrrMr)r$rrrris` @r%#test_lookupFunctionDeprecatedInvokez7CommandLocatorTests.test_lookupFunctionDeprecatedInvoke_sY - ,, % 7  5   #377Id#KL B!!$''r'N) r:r;r<r=rrrrrrr?r'r%rrs% ( 9??(:(r'rsSuccess!sNo, really. Success.ceZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZy)BinaryProtocolTestsz Tests for L{amp.BinaryBoxProtocol}. @ivar _boxSender: After C{startReceivingBoxes} is called, the L{IBoxSender} which was passed to it. c g|_g|_y)zz Keep track of all boxes received by this test in its capacity as an L{IBoxReceiver} implementor. N)rr*r-s r%rnzBinaryProtocolTests.setUps   r'c||_y)zm Implement L{IBoxReceiver.startReceivingBoxes} to just remember the value passed in. N) _boxSenderr$rjs r%rmz'BinaryProtocolTests.startReceivingBoxess !r'c:|jj|y)z5 A box was received by the protocol. NrrNs r%rz"BinaryProtocolTests.ampBoxReceiveds #r'Nc||_y)zD Record the reason that we stopped receiving boxes. N) stopReasonr4s r%stopReceivingBoxesz&BinaryProtocolTests.stopReceivingBoxess !r'cy)Nzno peerr?r-s r%rbzBinaryProtocolTests.getPeerr'cy)Nzno hostr?r-s r%getHostzBinaryProtocolTests.getHostrr'cf|j|t|jj|yr))rrr*r0rs r%r,zBinaryProtocolTests.writes$ dE* r'ctj|}|jd|j|j|y)z When L{amp.BinaryBoxProtocol} is connected to a transport, it calls C{startReceivingBoxes} on its L{IBoxReceiver} with itself as the L{IBoxSender} parameter. N)rBinaryBoxProtocolmakeConnectionassertIsrr$rs r%test_startReceivingBoxesz,BinaryProtocolTests.test_startReceivingBoxess6 ((.% doox0r'cGdd}t}tj|}|j||j |j dy)z The L{IBoxReceiver} which is started when L{amp.BinaryBoxProtocol} is connected to a transport can call C{sendBox} on the L{IBoxSender} passed to it before C{startReceivingBoxes} returns and have that box sent. ceZdZdZy)[BinaryProtocolTests.test_sendBoxInStartReceivingBoxes..SynchronouslySendingReceivercP|jtjddiy)Nfoobar)rarrMrs r%rmzoBinaryProtocolTests.test_sendBoxInStartReceivingBoxes..SynchronouslySendingReceiver.startReceivingBoxesssww'789r'N)r:r;r<rmr?r'r%SynchronouslySendingReceiverr s :r'rs foobarN)rrrrrr$)r$rr+rs r%!test_sendBoxInStartReceivingBoxesz5BinaryProtocolTests.test_sendBoxInStartReceivingBoxessR : :$% (()E)GH * *,MNr'ctj|}|jd|jd|jd|j|jtj dgy)z When a binary box protocol receives: * a key * a value * an empty string it should emit a box and send it to its boxReceiver. rDrr'rEN)rrstringReceivedrrrr!s r%test_receiveBoxStateMachinez/BinaryProtocolTests.test_receiveBoxStateMachines^  ! !$ ' " "  cjjx&@%ABr'ct}tj|}|j||jd|j |j y)z L{amp.BinaryBoxProtocol} drops its connection if the length prefix for the first a key it receives is larger than 255. N)rrrrr1r. disconnectingr$r+rs r%$test_firstBoxFirstKeyExcessiveLengthz8BinaryProtocolTests.test_firstBoxFirstKeyExcessiveLengthsN $% ((. *k*  //0r'ct}tj|}|j||jd|j |j |jd|j|j y)z L{amp.BinaryBoxProtocol} drops its connection if the length prefix for a subsequent key in the first box it receives is larger than 255. skvrNrrrrr1r0rr.rs r%)test_firstBoxSubsequentKeyExcessiveLengthz=BinaryProtocolTests.test_firstBoxSubsequentKeyExcessiveLengthss $% ((. *34 001k*  //0r'ct}tj|}|j||jd|j |j |jd|j|j y)z L{amp.BinaryBoxProtocol} drops its connection if the length prefix for the first key in a subsequent box it receives is larger than 255. skvrNrrs r%)test_subsequentBoxFirstKeyExcessiveLengthz=BinaryProtocolTests.test_subsequentBoxFirstKeyExcessiveLengthss $% ((. *;< 001k*  //0r'ctj|}|jt|jd|j t tjd|jjtj|j|jjj|j|jjj |j#|jjj|j#|jjj$y)z If L{amp.BinaryBoxProtocol} disconnects because it received a key length prefix which was too large, the L{IBoxReceiver}'s C{stopReceivingBoxes} method is called with a L{TooLong} failure. rzsimulated connection doneN)rrrrr1r6rr ConnectionDonertrapTooLongr.r$isKeyr0isLocal assertIsNonekeyNamers r%test_excessiveKeyFailurez,BinaryProtocolTests.test_excessiveKeyFailures ((. 12k* E(()DE F  S[[) --334 ..667 $////556 $////778r'c@t}tj|}|j||jt t d|jdt|jt |j|jy)z~ L{amp.BinaryBoxProtocol.unhandledError} logs the failure passed to it and disconnects its transport. Fake errorrN) rrrrrerr{rr|flushLoggedErrorsr.rrs r% test_unhandledErrorWithTransportz4BinaryProtocolTests.test_unhandledErrorWithTransportsx $% ((. * \(B CD C 6 6| DEF  //0r'cNtj|}|jt|jt t d|jt td|jdt|jty)z L{amp.BinaryBoxProtocol.unhandledError} completes without error when there is no associated transport. Simulatedr(rN) rrrrr6rr|rer{rr|r)rs r%#test_unhandledErrorWithoutTransportz7BinaryProtocolTests.test_unhandledErrorWithoutTransports{ ((. 12 +(> ?@ \(B CD C 6 6| DEFr'ctj|}|jtjdddj |j |j tjdddgy)z When a binary box protocol receives the serialized form of an AMP box, it should emit a similar box to its boxReceiver. valueTests anotherValue)testKeys anotherKeyN)rrr1rMr rrr!s r%test_receiveBoxDataz'BinaryProtocolTests.test_receiveBoxDatasf  ! !$ '  GG)/J ik  JJ WW,O P Q r'cxd}d|z}t}tj|}|j||jtj d|ij |j|jtj d|ig|j|jy)z An L{amp.BinaryBoxProtocol} can receive serialized AMP boxes with values of up to (2 ** 16 - 1) bytes. irkN) rrrrr1rMr rrr0r)r$rr$r+rs r%test_receiveLongerBoxDataz-BinaryProtocolTests.test_receiveLongerBoxData.s v #% ((. *cggsEl3==?@ cggsEl&;%<= 001r'c6tj|}|j|tjddd}|j||j ||j dj |j|jy)z When a binary box protocol sends a box, it should emit the serialized bytes of that box to its transport. r/rD)r0ssomeDatar'N) rrrrMrarjoinr*r )r$r aBoxs r% test_sendBoxz BinaryProtocolTests.test_sendBox<sr  ! !$ ' wwLxHI  $ $)),dnn.>?r'ctj|}|j|tt }|j ||j |j|y)z When a binary box protocol loses its connection, it should notify its box receiver that it has stopped receiving boxes. N)rrrrr{r6rr)r$r connectionFailures r%#test_connectionLostStopSendingBoxesz7BinaryProtocolTests.test_connectionLostStopSendingBoxesHsQ  ! !$ ' #LN3 *+ doo'89r'ctdd|Gfdd}tj|tjddd}j ||j dz}j ||jj||jd jjd|j|jdgj d |jd jjd |jtjj|y) z L{BinaryBoxProtocol} has the capacity to switch to a different protocol on a box boundary. When a protocol is in the process of switching, it cannot receive traffic. N outgoing datac&eZdZdZdZfdZy)@BinaryProtocolTests.test_protocolSwitch..SwitchyReceiverFcyr)r?rs r%rmzTBinaryProtocolTests.test_protocolSwitch..SwitchyReceiver.startReceivingBoxes_sr'cj|jdd|_jjy)NzShould only receive one box!T)r0switched_lockForSwitch _switchTo)r$rOr  otherProtorNs r%rzOBinaryProtocolTests.test_protocolSwitch..SwitchyReceiver.ampBoxReceivedbs7  0NO $   " J'r'N)r:r;r<rBrmr)r rErNsr%SwitchyReceiverr?\sH  (r'rFslotsdata)sincludesofsHello, world!r's more datasHello, world!more data)rrrrMrr r1rr+rr6r*r&ProtocolSwitchedra)r$rF anyOldBoxmoreThanOneBoxr rErNs @@@r%test_protocolSwitchz'BinaryProtocolTests.test_protocolSwitchSs  t%56  ( (  ! !/"3 4GGAB  #,,.1II ~& j**D1 *//24LM %5$67 |$ *//24UV #.. 9Er'ctj|}|j|tdd}|j ||j |j gy)z After switching to a different protocol, if no extra bytes beyond the switch box were delivered, an empty string is not passed to the switched protocol's C{dataReceived} method. Nr')rrrrrDrr*)r$r rEs r%test_protocolSwitchEmptyBufferz2BinaryProtocolTests.test_protocolSwitchEmptyBufferwsN  ! !$ ' tS)  J "-r'cVtj|}|j|tjddi}|j |j tj |j||j|j||jdj|j|j|j tdd}|j||j tj |jy)a8 In order to make sure the protocol never gets any invalid data sent into the middle of a box, it must be locked for switching before it is switched. It can only be unlocked if the switch failed, and attempting to send a box while it is locked should raise an exception. ssomerGr'Nr=)rrrrMrCr&rHra_unlockFromSwitchrr6r*r rrD)r$r  sampleBoxrEs r% test_protocolSwitchInvalidStatesz4BinaryProtocolTests.test_protocolSwitchInvalidStatess  ! !$ ' GGWg./   #.. 9E  ) $)),i.A.A.CD t%56  J #..0C0CDr'cRGddtj}|}tj|}|j ||j |j |tt}|j||j|j|y)zo When the protocol is switched, it should notify its nested protocol of disconnection. ceZdZdZdZy)DBinaryProtocolTests.test_protocolSwitchLoseConnection..LoserNc||_yr)r5r4s r%r6zSBinaryProtocolTests.test_protocolSwitchLoseConnection..Loser.connectionLost $ r')r:r;r<r5r6r?r'r%LoserrT F %r'rXN) rProtocolrrrrCrDrr{r6rr5)r$rXconnectionLoserr r:s r%!test_protocolSwitchLoseConnectionz5BinaryProtocolTests.test_protocolSwitchLoseConnections  %H%% %  '  ! !$ '   O$#LN3 *+ //1BCr'c^Gdd}tj|}tj}|}|j ||j |j ||tt}|j||j|j|y)z~ When the protocol is switched, it should notify its nested client protocol factory of disconnection. ceZdZdZdZy)PBinaryProtocolTests.test_protocolSwitchLoseClientConnection..ClientLoserNc||_yr)rVrs r%clientConnectionLostzeBinaryProtocolTests.test_protocolSwitchLoseClientConnection..ClientLoser.clientConnectionLostrWr')r:r;r<r5rar?r'r% ClientLoserr_rYr'rbN) rrrrZrrCrDrr{r6rr5)r$rbr r[ clientLoserr:s r%'test_protocolSwitchLoseClientConnectionz;BinaryProtocolTests.test_protocolSwitchLoseClientConnections  % %  ! !$ '"++-!m    O[1#LN3 *+ ++->?r')r:r;r<r=rnrmrrrrbrr,rrrrrrr&r*r-r1r4r8r;rKrMrQr\rdr?r'r%rrws! J!1O" C 1 1 19$ 1 G 2 @ :"FH .E(D*@r'rceZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zeed dZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZ dZ!dZ"e#d d fd!Z$d"Z%e#fd#Z&d$Z'd%Z(d&Z)d'Z*d(Z+y))*AMPTestsctjtjftjtjftj tj ftj tjftjtjftjtjftj tjffD],\}}|j|j||d|d.y)z~ The classes in the amp module ought to implement the interfaces that are declared for their benefit. z does not implements()N) r IBoxSenderr IBoxReceiverrkIResponderLocatorCommandLocatorSimpleStringLocatorrr. implementedBy)r$ interfaceimplementations r%test_interfaceDeclarationsz#AMPTests.test_interfaceDeclarationss ^^S22 3   s00 1  " "C$6$6 7  " "C$;$; < ^^SWW %   sww '  " "CGG ,*  %I~ OO''7!""7 {!D  r'ct\}}}g}d}|j|j|j|j |j |dd|y)z Verify that a simple command can be sent and its response received with the simple low-level string-based API. rrrDNrrJrr0rDrr$rEr:rLHELLOs r%test_helloWorldzAMPTests.test_helloWorldX +,1a  E&&qxx0   1h/r'ct\}}}g}d}|j|j|j|j |j |dd|y)z} Verify that mixed-case, underscored and dashed arguments are mapped to their python names properly. rrrDNrsrts r%test_wireFormatRoundTripz!AMPTests.test_wireFormatRoundTriprxr'cttt\}}}g}d}d}|j||j|j|j |j |dd||j |dd|y)zK Verify that unicode arguments can be encoded and decoded. rr ruworሴldrrFrN)rrrrr0rDr)r$rEr:rrurv HELLO_UNICODEs r%test_helloWorldUnicodezAMPTests.test_helloWorldUnicodes+66 1a %  5-0< #r'ct\}}}g}d}|jdj|j|j|j |j |jdd}|j|j|j|j |j |dd|y)z Verify that unknown commands using low-level APIs will be rejected with an error, but will NOT terminate the connection. cB|jtjyz: You can't propagate the error... OKr rUnhandledCommandes r% clearAndAddz4AMPTests.test_unknownCommandLow..clearAndAdd FF3'' (r'rrrrrDN) rrGrrr0rDrpoprJr$rEr:rrurrvs r%test_unknownCommandLowzAMPTests.test_unknownCommandLows +,1a   6"--k:FFqxxP   $' E&&qxx0   1h/r'ct\}}}g}d}|jtj|j |j |j |j|jdd}|j|j |j |j |j|dd|y)z Verify that unknown commands using high-level APIs will be rejected with an error, but will NOT terminate the connection. cB|jtjyrrrs r%rz5AMPTests.test_unknownCommandHigh..clearAndAdd'rr'rrrrDN) rrrrrr0rDrrrJrs r%test_unknownCommandHighz AMPTests.test_unknownCommandHighs +,1a   S$$[1==ahhG   $' E&&qxx0   1h/r'cDg}tjtjtj j |j|djtj|jdt|djy)a It can be very confusing if you write some code which responds to a command, but gets the return value wrong. Most commonly you end up returning None instead of a dictionary. Verify that if that happens, the framework logs a useful error. )rvrNoneN) rdispatchCommandrrrrvrr0r BadLocalReturn failUnlessInrr$)r$rus r%test_brokenReturnValuezAMPTests.test_brokenReturnValue6sm &(88 JJ 8 8 9 *QXX  ! #$$% &$qtzz"23r'cttt\}}}g}d}|jt|dj |j |j |j|dd|y)z Verify that unknown arguments are ignored, and not passed to a Python function which can't accept them. r|rsI'm not in the book!)rFbonusrrFN)rrrrrr0rDrrts r%test_unknownArgumentzAMPTests.test_unknownArgumentEsn +66 1a  u,C  +ahh    1g.r'c |jtttjdt |jtttj t |jtttjt |jdttjy)zS Verify that the various Box objects repr properly, for debugging. r rN) rrrr _SwitchBoxr>rrassertInr-s r%test_simpleReprszAMPTests.test_simpleReprsWs d3>>##678#> d3;;=12C8 d3::<0137 hSZZ\ 23r'ctdd}tj}||_|j t |d|j t|fzy)zQ Verify that L{AMP} objects output their innerProtocol when set. Nr=z# at 0x%x>)rrr innerProtocolrrr#id)r$rEr s r%test_innerProtocolInReprz!AMPTests.test_innerProtocolInRepr`sOt%56 GGI$  G 1Z5J5JBqE4R R r'c~tj}|jt|dt |ddy)zh Verify that L{AMP} objects do not output 'inner' when no innerProtocol is set. z N)rrrrrr!s r%test_innerProtocolNotInReprz$AMPTests.test_innerProtocolNotInReprms2 GGI aJr!uQiq"9:r'SSL not availablecx|jtttjt y)z; L{amp._TLSBox.__repr__} returns a string. N)rrrr_TLSBoxr>r-s r%test_simpleSSLReprzAMPTests.test_simpleSSLReprus$ d3;;=12C8r'c t\}}}d}|jtj|jdfi|di}|j |j |j |j|j|j|j|j|jd|jtt|t!||jdt!|y)zl Verify that a key that is too long will immediately raise a synchronous exception. HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHsHelloshiasciirN)rr&rr!rGr.r"r#r$r%rr$encoderr>r|rr$rEr:rrtls r%test_keyTooLongzAMPTests.test_keyTooLong|s +,1a  T  s{{A,>,> WQPUJ W !  # "**% 188G#45 c#a&k48, eT"X&r'cBt\}}}ddz}|jtj|j|}|j |j |j|j|j|j|jd|j|j||jtt!|t#||jdt#||jdt#|y)zs Verify that attempting to send value longer than 64k will immediately raise an exception. HirDr$rFN)rr&rr!rJrDr0r"r.r#rr%failUnlessIdenticalr$rr>r|rrs r%test_valueTooLongzAMPTests.test_valueTooLongs +,1a J    s{{AKK ;   "  # X.   1- c#a&k48, gtBx( gtBx(r'cttt\}}}g}d}|j|j|j|j |j |dd|y)z Verify that a simple command can be sent and its response received with the high-level value parsing API. r|rrrFN)rrrJrr0rDrrts r%test_helloWorldCommandzAMPTests.test_helloWorldCommandsb +66 1a  E&&qxx0   1g.r'c2g}ttt\}}}d}|j|j|j|j |dj t|jt|djdy)z Verify that if a known error type is raised and handled, it will be properly relayed to the other end of the connection and translated into an exception, and no error will be logged. r|fuck yourrN) rrrJrr0rDr rRrr>r$r$rurEr:rrvs r%test_helloErrorHandlingz AMPTests.test_helloErrorHandlingsx *66 1a E%%ahh/   ! $% QqTZZ*<=r'cg}ttt\}}}d}|j|j|j|j |j jt|j|j|j|j |j jtjy)a  Verify that if a known, fatal error type is raised and handled, it will be properly relayed to the other end of the connection and translated into an exception, no error will be logged, and the connection will be terminated. r|rN) rrrJrr0rDrr rWr rrs r%test_helloFatalErrorHandlingz%AMPTests.test_helloFatalErrorHandlings *66 1a E%%ahh/    [! E%%ahh/    U))*r'cg}ttt\}}}t}|j|j |j |j |j}|jtj|j|j |j |j}|jtj|j|jty)z Verify that if an unknown error type is raised, it will be relayed to the other end of the connection and translated into an exception, it will be logged, and then the connection will be dropped. r|N)rrrrJrr0rDrr rUnknownRemoteErrorr rr.r)r)r$rurEr:rrvurecls r%test_helloNoErrorHandlingz"AMPTests.test_helloNoErrorHandlings *66 1a( E%%ahh/  eeg ''( E%%ahh/ UUW $$% ../HIJr'cttt\}}}g}|jtj |j |j |j|g|jj|j |jjtj|jji|jS)z Verify that a command that does not get answered until after the connection terminates will not cause any errors. r|)rrrrrr0rDrr+loseConnectionrr r rrr3r$rEr:rrus r%test_lateAnswerzAMPTests.test_lateAnswers +66 1a  [!,,QXX6   B ""$    U))* 2yyr'cttt\}}}d}|jt||j |j |j y)zG Verify that a command that requires no answer is run. r|rrEN)rrrrrDr.r)r$rEr:rrvs r%test_requiresNoAnswerzAMPTests.test_requiresNoAnswersJ+66 1a ]% 0    "r'cg}ttt\}}}d}|jt||j |j |j tjd}|jt|j|j|j |jjtj|j!|j"y)z] Verify that commands sent after a failed no-answer request do not complete. r|rrErN)rrrrrDr.r)rRemoteAmpErrorrjrr0rr r rr0rrs r%test_requiresNoAnswerFailz"AMPTests.test_requiresNoAnswerFails *66 1a ]% 0   ..s/A/ABC U% (33AHH=    U))* #r'cttt\}}}|jj|j |j t d}|j|dy)zv No-answer commands sent after the connection has been torn down do not return a L{Deferred}. r|rrEN)rrr+rrDrrr)r$rEr:rrs r%test_requiresNoAnswerAfterFailz'AMPTests.test_requiresNoAnswerAfterFailsU +66 1a ""$  m:> fd#r'cttt\}}}|jtd|j |j tj}|jt|dy)a+ Verify that responders of requiresAnswer=False commands have to return a dictionary anyway. (requiresAnswer is a hint from the _client_ - the server may be called upon to answer commands in any case, if the client wants to know when they complete.) r|rDrErN) rrrrrrDr)rrrr|)r$rEr:rles r%test_noAnswerResponderBadAnswerz(AMPTests.test_noAnswerResponderBadAnswer)s_+26 1a ]( 3   # #C$6$6 7 R!$r'c,ttt\}}}g}|jtdj |j |j|jt|d|j|tddgy)z Verify that responders with requiresAnswer=False will actually respond if the client sets requiresAnswer=True. In other words, verify that requiresAnswer is a hint honored only by the client. r|sHello!rErsHello!-noanswerNr) rrrrrjrr0rDrr|rrs r%$test_noAnswerResponderAskedForAnswerz-AMPTests.test_noAnswerResponderAskedForAnswer;s{ +/6 1a  U) ,88B   Q#  -T:; r'c(ttt\}}}g}|jtdj |j |j |jjd}|j|ddigdzy)zN Test encoding of an argument that uses the AmpList encoding. r| )rrrrN) rrrrrr0rDrgetr)r$rEr:rrurs r%test_ampListCommandzAMPTests.test_ampListCommandMsw+66 1a  WR (44QXX>  V$ 3(b1r'cttt\}}}g}|jtdj |j |j |jjd}|j|dy)z Sending a command with an omitted AmpList argument that is designated as optional does not raise an InvalidSignature error. r|please)rr{rN rrrrrr0rDrrrr$rEr:rrur{s r%test_optionalAmpListOmittedz$AMPTests.test_optionalAmpListOmitted[sm +66 1a  \X 6BB188L  557;;z* >2r'c$ttt\}}}g}|jtdddigj |j |j |jjd}|j|dy) zV Sanity check that optional AmpList arguments are processed normally. r|rr^foo)rrr{z foo acceptedNrrs r%test_optionalAmpListPresentz$AMPTests.test_optionalAmpListPresentjs{+66 1a  HVUO3D  +ahh   557;;z* >2r'cL|jtjty)z~ Verify that if we pass an invalid argument list (omitting an argument), an exception will be raised. N)r&rInvalidSignaturerjr-s r%test_failEarlyOnArgSendingz#AMPTests.test_failEarlyOnArgSendingzs #..6r'cVtj}t|tj}t|tfdfd\}}fd}j j ||j jjy)z As a debugging aid, a protocol system should raise a L{ProtocolSwitched} exception when asked to switch a protocol that is already switched. cSr)r? serverProtosr%rz4AMPTests.test_doubleProtocolSwitch.. r'cSr)r? clientProtosr%rz4AMPTests.test_doubleProtocolSwitch..r'r|chjtjjd_yNT)r&rrHr testSucceeded)rrEr$s r%rBz4AMPTests.test_doubleProtocolSwitch..switcheds'   c22A4J4J K!%D r'N) r rrrrrrDr.r) r$serverDeferredclientDeferredr:rrBrErrs ` @@@r%test_doubleProtocolSwitchz"AMPTests.test_doubleProtocolSwitchs )4^D )4^D *+9L 1a &  ,,X6   **+r'Fc d_tj | tj |  tfd fd\}}}|r0g}|j t j |j|j}|r+jtj|jdfd fd} |j| |jj5jj!j"|j|r]|r0|j$j'tj(d d n|j$j!i|j|j*j-|jj/jy) z Verify that it is possible to switch to another protocol mid-connection and send data to it successfully. FcSr)r?rsr%rz.AMPTests.test_protocolSwitch..rr'cSr)r?rsr%rz.AMPTests.test_protocolSwitch..rr'r|rc|\\}}\}}j|j|jdj|tjdj|td_y)Nr'T)r.rr6rrr)info serverSuccess serverData clientSuccess clientDatar$s r% cbConnsLostz1AMPTests.test_protocolSwitch..cbConnsLostskIM F (mZ*E=* OOM * OOM *   SXXj13E F   SXXj13E F!%D r'cPtjgjSr))r DeferredListr)r_rrrs r%cbSwitchz.AMPTests.test_protocolSwitch..cbSwitchs)%%~~&FGSS r'NsSPURIOUSz,Here's some traffic in the form of an error.)rr rrrrrr0rr&rrHrJrrDrr3rrerrbackrr+rr.)r$switcherspuriousTraffic spuriousErrorrEr:rwfdrswitchDeferredrrrrrrs` @@@@@r%rKzAMPTests.test_protocolSwitchsi#)~. )~. *+9L 1a D LL % 0 0 =//1    c22AKK J &  ""8,   ! ! -  " " + +K,G,G H GGI  !!&&#%S  ""2& GGI ""$   **+r'c.|jtS)z Verify that protocol-switching even works if the value returned from the command that does the switch is deferred. )r)rKrr-s r%test_protocolSwitchDeferredz$AMPTests.test_protocolSwitchDeferreds ''1Q'RRr'cd d|_tj}|| tj}||t fdfd\}}}g}|j dj |j |j|jjt|j|j|jdj|j |j|j|jddy ) z Verify that if we try to switch protocols and it fails, the connection stays up and we can go back to speaking AMP. FcSr)r?rsr%rz2AMPTests.test_protocolSwitchFail..rr'cSr)r?rsr%rz2AMPTests.test_protocolSwitchFail..rr'r|T)rrrFN)rr rrrrr0rDrr rYr0rJrr) r$rrrrEr:rrurrs @@r%test_protocolSwitchFailz AMPTests.test_protocolSwitchFails #)~. )~. *+9L 1a  D)44QXX>    _% ++, H))!((3   )84r'c&|jdS)zs Verify that attempts to send traffic after a switch will not corrupt the nested protocol. T)rrKr-s r%test_trafficAfterSwitchz AMPTests.test_trafficAfterSwitchs '''==r'c(|jddS)zh Returning an error after a protocol switch should record the underlying error. T)rrr r-s r%test_errorAfterSwitchzAMPTests.test_errorAfterSwitchs ''D'QQr'clttt\}}}g}d}d}|j|j|j|j |j |jd||jtj|j|j |j |jd||j|j|j|jjtjy)zt Verify that commands with a responseType of QuitBox will in fact terminate the connection. r|rrrFrN)rrrJrr0rDrrrrrr r r)r$rEr:rrurvGOODBYEs r%test_quitBoxQuitszAMPTests.test_quitBoxQuitss +66 1a  E&&qxx0   )51 W))!((3   +W5 E%%ahh/  U))*r'ct\}}}g}|j|_|jtdddd|j |j t|ddtjfdd d d fD])\}}|j |d j||+|d jd |j |d iy)z Verify that the command dictionaries for a callRemoteN look correct after being serialized and parsed. hello testmixed case arg testryrFrrrr_command)rDr)rpr)rqr)rrrrB_askN) rr0rrrjrDrr|rvr)r$rEr:rrur3r;s r%test_basicLiteralEmitzAMPTests.test_basicLiteralEmits +,1a 88 ,     Q# %++ , % 2  %   .DAq   QrUYYq\1 - . " ' 2#r'c gGfddtj}t|\}}}|jtddddj j |j|jtd |jd d tdddd|jjd d f|jdtd dy )z Verify that a call similar to basicLiteralEmit's is handled properly with high-level quoting and passing to Python methods, and that argument names are correctly handled. c:eZdZfdZej ey):AMPTests.test_basicStructuredEmit..StructuredHellocBj||ftdS)NaaarE)r0r)r$r r3rus r%hz.StructuredHello.h=s!Q &))r'N)r:r;r<rrjr)rusr%StructuredHellor<s * OOA r'r )rrrrrrrr?N)rFrrrrrrmrr)rrF) rrrrrjrr0rDrr|rr+rb)r$r rEr:rrus @r%test_basicStructuredEmitz!AMPTests.test_basicStructuredEmit4s  cgg +G1a ,  +ahh    Q#  aD'4!#',,.!   $ 1t$f=>r'N),r:r;r<rqrwrzr~rrrrrrrrrskipSSLrrrrrrrrrrrrrrrrrrrrKrr r rrrr"r?r'r%rfrfs& 0 07 0.0. 4/$4  ; G()9*9 ')" />"+(K,( #$( $%$ $ 2 33 7,00 ;,zS0N52>R+,$8+?r'rfceZdZdZy)!PretendRemoteCertificateAuthoritycyrr?r-s r%checkIsPretendRemotez6PretendRemoteCertificateAuthority.checkIsPretendRemotecrr'N)r:r;r<r'r?r'r%r%r%bsr'r%ceZdZdZdZdZy) IOSimCertrc|Sr)r?)r$rs r%optionszIOSimCert.optionsjs r'c:||usJ|xjdz c_y)a This isn't a real certificate, and wouldn't work on a real socket, but iosim specifies a different API so that we don't have to do any crypto math to demonstrate that the right functions get called in the right places. rT verifyCountr$ otherCerts r% iosimVerifyzIOSimCert.iosimVerifyms&D    Ar'N)r:r;r<r.r+r1r?r'r%r)r)gsK r'r)ceZdZdZy)OKCertc*|jsJ|Sr))r')r$rs r%r+zOKCert.optionszs%%''' r'N)r:r;r<r+r?r'r%r3r3ysr'r3ceZdZdZy) GrumpyCertc.|xjdz c_y)NrFr-r/s r%r1zGrumpyCert.iosimVerifys Ar'N)r:r;r<r1r?r'r%r6r6sr'r6ceZdZdZdZy) DroppyCertc||_yr))toDrop)r$r;s r%r&zDroppyCert.__init__s  r'cb|xjdz c_|jjy)NrT)r.r;rr/s r%r1zDroppyCert.iosimVerifys& A ""$r'N)r:r;r<r&r1r?r'r%r9r9s r'r9cReZdZdZdZdZejjey)SecurableProtoNctgSr))r%r-s r% verifyFactoryzSecurableProto.verifyFactorys1344r'c\|j}|j}t||S)Ntls_localCertificatetls_verifyAuthorities) certFactoryr@r)r$certverifys r% getTLSVarszSecurableProto.getTLSVarss+!##%VLLr') r:r;r<rr@rHrStartTLSrr?r'r%r>r>s&G5M LL:&r'r>rz2This test case requires SSL support in the reactorc$eZdZdZdZdZdZy)TLSTestscttt\}}}tfd|_|j t j tgg}|j tj|j|j|jjdg}|j tj|j|j|j|dddiy) z Verify that starting TLS and succeeding at handshaking sends all the notifications to all the right places. r|cSr)r?okcsr%rz+TLSTests.test_startingTLS..#r'rBr!rrTN)rr>r3rErrrIr%rrr0rDrr.)r$clisvrrrurOs @r%test_startingTLSzTLSTests.test_startingTLSs /&N S!h%  LL!$#D#F"G    {#//9   !,  {#//9   1$/0r'cnttt\}}}tfd|_|j t j tg|jd|_ |jt j|jt j tgy)zz Verify that the protocol will complain if we attempt to renegotiate TLS, which we don't support. r|cSr)r?rNsr%rz1TLSTests.test_startTooManyTimes..rPr'rBTN) rr>r3rErrrIr%rDnoPeerCertificater& OnlyOneTLSr$rQrRrrOs @r%test_startTooManyTimeszTLSTests.test_startTooManyTimess /&N S!h%  LL!$#D#F"G   $  NN NN LL!$#D#F"G  r'ctttt\}}}fd|_|j t j |j|jjd|j t}|j|j|tjy)z Verify that starting TLS and failing on both sides at handshaking sends notifications to all the right places and terminates the connection. r|cSr)r?)badCertsr%rz1TLSTests.test_negotiationFailed..s'r'rCr!N)r6rr>rErrrIrDrr.r assertFailurerNativeOpenSSLError)r$rQrRrr]r\s @r%test_negotiationFailedzTLSTests.test_negotiationFaileds ,.&N S!* s||'B   ,,a0 NN; '   1e667r'cttt\}}}t|jfd|_|j t j|j|jjd|j t}|j|j|tjy)z Verify that starting TLS and failing by way of a lost connection notices that it is probably an SSL problem. r|cSr)r?) droppyCertsr%rz:TLSTests.test_negotiationFailedByClosing..s*r'r]r!N)rr>r9r+rErrrIrDrr.rr^r PeerVerifyError)r$rQrRrr]rcs @r%test_negotiationFailedByClosingz(TLSTests.test_negotiationFailedByClosings /&N S!  . , s||*E   //3 NN; '   1e334r'N)r:r;r<rSrYr`rer?r'r%rKrKs1: 68,5r'rKc(eZdZdZdZdZdZdZy)TLSNotAvailableTestszP Tests what happened when ssl is not available in current installation. cDtj|_dt_y)z% Disable ssl in amp. N)rrr-s r%rnzTLSNotAvailableTests.setUp s77r'c.|jt_y)z% Restore ssl module. N)rrr-s r%tearDownzTLSNotAvailableTests.tearDowns((r'cttt\}}}tfd|_|j |j t jtgtS)zg Check that callRemote raises an exception when called with a L{amp.StartTLS}. r|cSr)r?rNsr%rz;TLSNotAvailableTests.test_callRemoteError..$rPr'rB) rr>r3rEr^rrrIr%r{rXs @r%test_callRemoteErrorz)TLSNotAvailableTests.test_callRemoteErrorsf /&N S!h%!! NN %('H'J&K      r'c&t}tfd|_tj}d|d<d|d<g}|j |_|jt|j||j|ddddgy ) z| When a client with SSL enabled talks to a server without SSL, it should return a meaningful error. cSr)r?rNsr%rz@TLSNotAvailableTests.test_messageReceivedError..6rPr'sStartTLSrrrs TLS_ERRORsTLS not available)rrrN) r>r3rErrMr0rarrrr)r$rRrOrrOs @r%test_messageReceivedErrorz.TLSNotAvailableTests.test_messageReceivedError/s h%ggi&KG ll  ?,- 3  %1#+?  r'N)r:r;r<r=rnrjrmrpr?r'r%rgrgs  * r'rgceZdZdZy)InheritedErrorz2 This error is used to check inheritance. NrTr?r'r%rrrrJrr'rrceZdZdZy)OtherInheritedErrorz< This is a distinct error for checking inheritance. NrTr?r'r%rtrtPrr'rtc:eZdZUdZediZeeee e fe d<y) BaseCommandz: This provides a command that will be subclassed. sINHERITED_ERRORrtN) r:r;r<r=rrrtrrrr|rr}r?r'r%rvrvVs0 *6FHT$y/501 2r'rvceZdZdZy)InheritedCommandz` This is a command which subclasses another command but does not override anything. NrTr?r'r%rxrx`sr'rxcbeZdZUdZdej fgZediZe e e e e fed<y)AddErrorsCommandz] This is a command which subclasses another command but adds errors to the list. sothersOTHER_INHERITED_ERRORrtN)r:r;r<r=rrxrzrtrtrrrr|rr}r?r'r%rzrzgsE KCKKM*+I56FHT$y/501 2r'rzc8eZdZdZdZej ey)NormalCommandProtocolz This is a protocol which responds to L{BaseCommand}, and is used to test that inheritance does not interfere with the normal handling of errors. ctr)rrr-s r%respzNormalCommandProtocol.respy r'N)r:r;r<r=rrvrr?r'r%r|r|ss $r'r|c8eZdZdZdZej ey)InheritedCommandProtocolz This is a protocol which responds to L{InheritedCommand}, and is used to test that inherited commands inherit their bases' errors if they do not respond to any of their own. ctr)r~r-s r%rzInheritedCommandProtocol.resprr'N)r:r;r<r=rrxrr?r'r%rrs t$r'rc8eZdZdZdZej ey)AddedCommandProtocolz This is a protocol which responds to L{AddErrorsCommand}, and is used to test that inherited commands can add their own new types of errors, but still respond in the same way to their parents types of errors. c.|r ttr))rtrr)r$others r%rzAddedCommandProtocol.resps %' ' " "r'N)r:r;r<r=rrzrr?r'r%rrs # t$r'rc.eZdZdZdZdZdZdZdZy)CommandInheritanceTestszM These tests verify that commands inherit error conditions properly. c t||\}}}|j|fi|}|j||} |j| S)z~ Check that the appropriate kind of error is raised when a given command is sent to a given protocol. r|)rrfailUnlessFailurerD) r$r}r_cmdr rEr:rr]d2s r% errorCheckz"CommandInheritanceTests.errorChecksK +u%P1a ALL # #  # #As +   r'c@|jtttS)zx Verify that errors specified in a superclass are respected normally even if it has subclasses. )rrrr|rvr-s r%test_basicErrorPropagationz2CommandInheritanceTests.test_basicErrorPropagations ~/DkRRr'c@|jtttS)zp Verify that errors specified in a superclass command are propagated to its subclasses. )rrrrrxr-s r%test_inheritedErrorPropagationz6CommandInheritanceTests.test_inheritedErrorPropagations  46F  r'cD|jtttdS)z Verify that new errors specified in a subclass of an existing command are honored even if the superclass defines some errors. Tr)rrtrrzr-s r%test_inheritedErrorAdditionz3CommandInheritanceTests.test_inheritedErrorAdditions%  !57Gt  r'cD|jtttdS)z Verify that errors specified in a command's superclass are respected even if that command defines new errors itself. Fr)rrrrrzr-s r%test_additionWithOriginalErrorz6CommandInheritanceTests.test_additionWithOriginalErrors%  02B%  r'N) r:r;r<r=rrrrrr?r'r%rrs! S   r'rc|jtjtj|`|j |yr))r r ConnectionLostrr6)r}r_s r% _loseAndPassrs0HHU ! !5#7#78  r'ceZdZdZdZdZy) LiveFireBasez4 Utility for connected reactor-using tests. cxddlm}tj_j j_tj _jj_tjj_ tjj_ |jdj_ jjj|j djj#j$j_jj&j(fd}tj*jjjjg}|j-|S)zB Create an amp server and connect a client to it. r)rz 127.0.0.1crjj_jj_yr)) clientFactoryrrQ serverFactoryrR)rlstr$s r% getProtosz%LiveFireBase.setUp..getProtoss)))22DH))22DHr')twisted.internetrr ServerFactoryrr ClientFactoryrrr rr listenTCP serverPort addCleanup stopListening connectTCPrport clientConn disconnectrr)r$rrdls` r%rnzLiveFireBase.setUps= -%335&*&6&6#%335&*&6&6#$)NN$4!$)NN$4!+'++At/A/AB 556,',, 002779K9K  223 3  !3!3!:!:D. su{{?U?Ur') rQrRr+r rrrrr6rr0 gatherResults)r$ruconnr]s r%rjzLiveFireBase.tearDowns HHdhh& D~~)NN$// dC&'ii#--/  ""1%001UVVr'N)r:r;r<r=rnrjr?r'r%rrs)4 Wr'rc|ddl}|jj|dz|jjy)Nr )sysstdoutr,rD)rrs r%showr s+JJQXJJr'cddlm}|jd}|jj }|j |}|j ||dd}|j|}|S)Nrrshared)CNcyrr?)dns r%rz tempSelfSigned.. rr'i)rrDNKeyPairgeneratecertificateRequestsignCertificateRequestnewCertificate)rsharedDNrcrsscrdrFs r%tempSelfSignedr sb$vvv"H ++   C   )B  & &x_g NE   e $D Kr'ceZdZeZeZdZy)LiveFireTLSTestsctfdj_fdj_fd}jj t jgj|S)aH Using real, live TLS, actually negotiate a connection. This also looks at the 'peerCertificate' attribute's correctness, since that's actually loaded using OpenSSL calls, but the main purpose is to make sure that we didn't miss anything obvious in iosim about TLS negotiations. c gSr)r?rFsr%rz9LiveFireTLSTests.test_liveFireCustomTLS..- s $r'cSr)r?rsr%rz9LiveFireTLSTests.test_liveFireCustomTLS... str'cjfd}jjtj |S)Ncjjjjjjjjjj jjjj jjyr))rrQhostCertificatedigestpeerCertificaterR)rslt2r$rs r%rzHLiveFireTLSTests.test_liveFireCustomTLS..secured..pinged4 s   DHH$<$<$C$C$EF  DHH$<$<$C$C$EF  DHH$<$<$C$C$EF  DHH$<$<$C$C$EFr')rrQrrr)rsltrrrFr$s @r%securedz8LiveFireTLSTests.test_liveFireCustomTLS..secured1 s6 A G88&&{3??G Gr'rB) tempcertrRr@rErQrrrIr)r$rrFs` @r%test_liveFireCustomTLSz'LiveFireTLSTests.test_liveFireCustomTLS! s]!/+ Hxx"" LLtD6# +g  r'N)r:r;r<r>rrrr?r'r%rr s!K K!r'rcLeZdZdZdZej jey)SlightlySmartTLSz_ Specific implementation of server side protocol with different management of TLS. c"ttS)zS @return: the global C{tempcert} certificate as local certificate. r])rrr-s r%rHzSlightlySmartTLS.getTLSVarsK s22r'N)r:r;r<r=rHrrIrr?r'r%rrE s  3 LL:&r'rceZdZeZeZdZy)PlainVanillaLiveFireTestsc~fd}jjtjj |S)z Verify that out of the box, we can start TLS to at least encrypt the connection, even if we don't have any certificates to use. cBjjtSr)rQrrrr$s r%rzBPlainVanillaLiveFireTests.test_liveFireDefaultTLS..secured` 88&&{3 3r')rQrrrIrr$rs` r%test_liveFireDefaultTLSz1PlainVanillaLiveFireTests.test_liveFireDefaultTLSZ s.  4xx""3<<0<.securedq rr')rD)rQrrrIrrrs` r%test_anonymousVerifyingClientz(r'c||f|_|S)z Don't do any serializing, just jam the input strings and protocol onto the C{protocol.makeArgumentsArguments} attribute as a two-tuple. Return the original strings. )makeArgumentsArguments)rrgrs r% makeArgumentsz MagicSchemaCommand.makeArguments rr'N)r:r;r<r= classmethodrrrr?r'r%rr sC r'rc:eZdZdZdZej dy)NoNetworkProtocola An L{amp.AMP} subclass which overrides private methods to avoid testing the network. It also provides a responder for L{MagicSchemaCommand} that does nothing, so that tests can test aspects of the interaction of L{amp.Command}s and L{amp.AMP}. @ivar parseArgumentsArguments: Arguments that have been passed to any L{MagicSchemaCommand}, if L{MagicSchemaCommand} has been handled by this protocol. @ivar parseResponseArguments: Responses that have been returned from a L{MagicSchemaCommand}, if L{MagicSchemaCommand} has been handled by this protocol. @ivar makeArgumentsArguments: Arguments that have been serialized by any L{MagicSchemaCommand}, if L{MagicSchemaCommand} has been handled by this protocol. c,tj|S)zJ Return a Deferred which fires with the original strings. )r succeed)r$rvrfrs r%_sendBoxCommandz!NoNetworkProtocol._sendBoxCommand s}}W%%r'ciSr)r?)r:weirds r%rzNoNetworkProtocol. s"r'N)r:r;r<r=rrrr?r'r%rr s&&   !45r'r_KT_VTceZdZdZy)MyBoxz! A unique dict subclass. NrTr?r'r%rr rr'rceZdZdZeZy)0ProtocolIncludingCommandWithDifferentCommandTypezN A L{ProtocolIncludingCommand} subclass whose commandType is L{MyBox} N)r:r;r<r=r commandTyper?r'r%rr sKr'rc|eZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZdZdZy) CommandTestsz7 Tests for L{amp.Argument} and L{amp.Command}. cz|jttjtjy)zE L{Argument} instances provide L{amp.IArgumentType}. N)r.r r IArgumentTypeArgumentr-s r%test_argumentInterfacez#CommandTests.test_argumentInterface s#  S%6%6 GHr'cxt}d}d|i}|jtj||d||fiy)z There should be a class method of Command which accepts a mapping of argument names to serialized forms and returns a similar mapping whose values have been parsed via the Command's response schema. whateverrr N)rrrrr$rrrfs r%test_parseResponsezCommandTests.test_parseResponse sE8V$  $ 2 27H E vx( ) r'ctdjt}fd}|j||S)z Making a remote call on a L{amp.Command} subclass which overrides the C{parseResponse} method should call that C{parseResponse} method to get the response. sweeoor cFjjdifyNr )rr)rclientr$thingys r% gotResponsezCCommandTests.test_callRemoteCallsParseResponse..gotResponse s$   V::gv=NPV.6 s'((00GX3F2Qr')rrWrrvrrr)r$rr{r(rs` @@r%!test_responderCallsParseArgumentsz.CommandTests.test_responderCallsParseArguments+ sV %&,H,,-?-K-KL 8T12  r'ct}t}d|i}dt|t|fz}|jtj ||d|j diy)z There should be a class method of L{amp.Command} which accepts a mapping of argument names to objects and returns a similar mapping whose values have been serialized via the command's argument schema. r rrrN)rrrrrr)r$rr(rgrs r%test_makeArgumentszCommandTests.test_makeArguments< sb88H%2h<H66  $ 2 27H E u||G, - r'ct}ddi}tj||}|jt |t y)z L{amp.Command.makeArguments}'s return type should be the type of the result of L{amp.Command.commandType}. r rN)rrrrrr)r$rrgrs r%!test_makeArgumentsUsesCommandTypez.CommandTests.test_makeArgumentsUsesCommandTypeL s> 8K(AOO X  d6lE*r'cttjt}fd}|j ||S)z Making a remote call on a L{amp.Command} subclass which overrides the C{makeArguments} method should call that C{makeArguments} method to get the response. rcFjjdifyr)rr)rr(r r$s r%r"zCCommandTests.test_callRemoteCallsMakeArguments..gotResponsec s&   --(0CV/L r')rrrrr)r$r{r"r(r s` @@r%!test_callRemoteCallsMakeArgumentsz.CommandTests.test_callRemoteCallsMakeArgumentsY sD #$8$$%7x$H  [)r'c |jtjtjt dt dy)z L{Command.makeArguments} raises L{amp.InvalidSignature} if the objects dictionary passed to it includes a key which does not correspond to the Python identifier for a defined argument. rF)rF bogusArgumentN)r&rrrjrrrr-s r%test_extraArgumentsDisallowedz*CommandTests.test_extraArgumentsDisallowedk s3      wfh 7   r'c ~|jtjtjt dddiddidy)a If a command argument conflicts with a Python keyword, the untransformed argument name is not allowed as a key in the dictionary passed to L{Command.makeArguments}. If it is supplied, L{amp.InvalidSignature} is raised. This may be a pointless implementation restriction which may be lifted. The current behavior is tested to verify that such arguments are not silently dropped on the floor (the previous behavior). rFrequiredprintz print valueNr?)r&rrrjrrr-s r%test_wireSpellingDisallowedz(CommandTests.test_wireSpellingDisallowedx s<       >z >g}%= >   r'cnGddtj}|jd|jy)zj A L{Command} subclass without a defined C{commandName} that's not a byte string. ceZdZdZy)PCommandTests.test_commandNameDefaultsToClassNameAsByteString..NewCommandz( A new command. NrTr?r'r% NewCommandr: s r'r;s NewCommandN)rCommandrrvr$r;s r%/test_commandNameDefaultsToClassNameAsByteStringz(>?r'c|jttdtjfddi}|j t |dy)zq A L{Command} subclass cannot be defined with a C{commandName} that's not a byte string. r;rvFOOz2^Command names must be byte strings, got: u?'FOO'$Nr&r'rrr< assertRegexr>r$r s r%!test_commandNameMustBeAByteStringz.CommandTests.test_commandNameMustBeAByteString sD !! t\CKK>M5;Q   JL r'c|jttdtjfddgi}|j t |dy)zS A L{Command} subclass's C{arguments} must have byte string names. r;rzrNz3^Argument names must be byte strings, got: u?'foo'$NrArCs r%/test_commandArgumentsMustBeNamedWithByteStringszJ;X   JM r'czGddtj}|jtdi|jy)zN A L{Command} subclass's C{errors} is coerced into a C{dict}. ceZdZedfgZy)DCommandTests.test_commandErrorsIsConvertedToDict..NewCommandZDEN)r:r;r<rrtr?r'r%r;rL s(&12Fr'r;rMN)rr<rrrtr=s r%#test_commandErrorsIsConvertedToDictz0CommandTests.test_commandErrorsIsConvertedToDict s0  3 3 +V4j6G6GHr'c |jttdtjfdt dfgi}|j t|dy)zX A L{Command} subclass's C{errors} must map exceptions to byte strings. r;rtrz0^Error names must be byte strings, got: u?'foo'$Nr&r'rrr<rrBr>rCs r%5test_commandErrorsMustUseBytesForOnWireRepresentationzBCommandTests.test_commandErrorsMustUseBytesForOnWireRepresentation sN!!    [[N *E23 4   U%WXr'czGddtj}|jtdi|jy)zS A L{Command} subclass's C{fatalErrors} is coerced into a C{dict}. ceZdZedfgZy)ICommandTests.test_commandFatalErrorsIsConvertedToDict..NewCommandrMN)r:r;r<rrur?r'r%r;rT s-v67Kr'r;rMN)rr<rrrur=s r%(test_commandFatalErrorsIsConvertedToDictz5CommandTests.test_commandFatalErrorsIsConvertedToDict s0  8 8 +V4j6L6LMr'c |jttdtjfdt dfgi}|j t|dy)ze A L{Command} subclass's C{fatalErrors} must map exceptions to byte strings. r;rurz6^Fatal error names must be byte strings, got: u?'foo'$NrPrCs r%:test_commandFatalErrorsMustUseBytesForOnWireRepresentationzGCommandTests.test_commandFatalErrorsMustUseBytesForOnWireRepresentation sQ !!    [[N /78 9    JS r'N)r:r;r<r=rrr#r%r)r+r-r0r3r7r>rDrGrIrNrQrUrWr?r'r%rr sfI    " +$   $ @      I YN r'rceZdZdZdZdZy)ListOfTestsMixina Base class for testing L{ListOf}, a parameterized zero-or-more argument type. @ivar elementType: Subclasses should set this to an L{Argument} instance. The tests will make a L{ListOf} using this. @ivar strings: Subclasses should set this to a dictionary mapping some number of keys -- as BYTE strings -- to the correct serialized form for some example values. These should agree with what L{elementType} produces/accepts. @ivar objects: Subclasses should set this to a dictionary with the same keys as C{strings} -- as NATIVE strings -- and with values which are the lists which should serialize to the values in the C{strings} dictionary. c:tj|j}tj}|jD]=}|j |j d||jjd?|j||jy)a L{ListOf.toBox} extracts the list of objects from the C{objects} dictionary passed to it, using the C{name} key also passed to it, serializes each of the elements in that list using the L{Argument} instance previously passed to its initializer, combines the serialized results, and inserts the result into the C{strings} dictionary using the same C{name} key. rN) rListOf elementTyperrgrhrcopyrrf)r$ stringListrfrs r% test_toBoxzListOfTestsMixin.test_toBox swZZ 0 01 **,<< VC   SZZ0'4<<;L;L;NPT U V $,,/r'ctj|j}i}|jD].}|j ||jj |d0|j ||jy)X L{ListOf.fromBox} reverses the operation performed by L{ListOf.toBox}. N)rr[r\rffromBoxr]rrg)r$r^rgrs r% test_fromBoxzListOfTestsMixin.test_fromBox sgZZ 0 01 << HC   sDLL$5$5$7$ G H $,,/r'N)r:r;r<r=r_rcr?r'r%rYrY s$ 00r'rYcPeZdZdZej ZddddZgdggddZy ) ListOfStringsTestsz: Tests for L{ListOf} combined with L{amp.String}. r'foosbarbazquuxemptysinglemultipler )rsbazsquuxemptysinglemultipleN) r:r;r<r=rrwr\rfrgr?r'r%rere s9#**,K!:G vh>wG H G"7??5)* GOOJ ' GOOK (  GOOI & GOOJ ' GOOJ ' GOOJ ' GOOK ( GOOK (   GOOE " GOOH % 'Gr'rwceZdZdZej ZddiZdej dej dej dej dgiZ d Z y ) ListOfDecimalNanTestszS Tests for L{ListOf} combined with L{amp.Decimal} for not-a-number values. snansNaN-NaNsNaN-sNaNnanNaNz-NaNsNaNz-sNaNcd}d}d}tj|j}i}|jD].}|j ||jj |d0|d}|j ||dxr ||d |j ||dxr ||d|j ||dxr ||d |j ||d xr ||d y) rac:dt|vxr dt|vS)Nrrr>r~s r%is_qnanz3ListOfDecimalNanTests.test_fromBox..is_qnan sCL(GV3w<-G Gr'cdt|vS)Nrrrs r%is_snanz3ListOfDecimalNanTests.test_fromBox..is_snan sS\) )r'cdt|vS)N-rrs r% is_signedz5ListOfDecimalNanTests.test_fromBox..is_signed s#g,& &r'Nrrrr!r)rr[r\rfrbr]r.)r$rrrr^rgrns r%rcz"ListOfDecimalNanTests.test_fromBox s H * ' ZZ 0 01 << HC   sDLL$5$5$7$ G H EN ! =i!o*=> ! 9)AaD/: ! =i!o*=> ! 9)AaD/:r'N) r:r;r<r=rr}r\rfr~rgrcr?r'r%rr ss#++-K CG  GOOE " GOOF # GOOF # GOOG $  G;r'rceZdZdZdZy) DecimalTestsz# Tests for L{amp.Decimal}. ctj}|jt|jd|jt|jd|jt|jdy)z L{amp.Decimal.toString} raises L{ValueError} if passed an object which is not an instance of C{decimal.Decimal}. 1.234X9v?N)rr}r& ValueErrorr1r$r(s r%test_nonDecimalzDecimalTests.test_nonDecimal sW ;;= *h&7&7A *h&7&7? *h&7&7>r'N)r:r;r<r=rr?r'r%rr s ?r'rceZdZdZdZdZy) FloatTestsz! Tests for L{amp.Float}. ctj}|jt|jd|jt|jd|jt|jdy)zq L{amp.Float.toString} raises L{ValueError} if passed an object which is not a L{float}. r1.234rN)rFloatr&rr1rs r% test_nonFloatzFloatTests.test_nonFloat sW 99; *h&7&7A *h&7&7B *h&7&7>r'cntj}|j|jddy)zY L{amp.Float.toString} returns a bytestring when it is given a L{float}. rrN)rrrr1rs r% test_floatzFloatTests.test_float s*99; **518ListOfOptionalTests.test_optionalArgumentWithKeyMissingOmitted9 s9 ZZ = SZZ\OQ3GNr'ctjtjd}i}|jdi|d|j |ddiy)z L{ListOf.fromBox} correctly reverses the operation performed by L{ListOf.toBox} for optional arguments. TrlrNr)rr[rrbr)r$r^rgs r%.test_omittedOptionalArgumentDeserializesAsNonezBListOfOptionalTests.test_omittedOptionalArgumentDeserializesAsNoneA sH ZZ = :r7D9 9d"34r'N) r:r;r<r=rrrrrr?r'r%rr s!  &  O5r'rc:eZdZdZdZdZdZdZdZdZ dZ y ) UNIXStringTransportar An in-memory implementation of L{interfaces.IUNIXTransport} which collects all data given to it for later inspection. @ivar _queue: A C{list} of the data which has been given to this transport, eg via C{write} or C{sendFileDescriptor}. Elements are two-tuples of a string (identifying the destination of the data) and the data itself. c ||_g|_y)zp @param descriptorFuzz: An offset to apply to descriptors. @type descriptorFuzz: C{int} N)_fuzz_queue)r$descriptorFuzzs r%r&zUNIXStringTransport.__init__W s $  r'cX|jjd||jzfy)NfileDescriptorReceived)rr0r)r$ descriptors r%sendFileDescriptorz&UNIXStringTransport.sendFileDescriptor_ s# 4j4::6MNOr'c>|jjd|fy)Nr1)rr0rs r%r,zUNIXStringTransport.writeb s ND12r'c4|D]}|j|yr))r,)r$seqr*s r% writeSequencez!UNIXStringTransport.writeSequencee s D JJt  r'ct|jjdttjfy)Nr6)rr0rr rr-s r%rz"UNIXStringTransport.loseConnectioni s( ,ge6J6J6L.MNOr'c,tjdS)Nz/tmp/some-pathr UNIXAddressr-s r%rzUNIXStringTransport.getHostl s""#344r'c,tjdS)Nz/tmp/another-pathrr-s r%rbzUNIXStringTransport.getPeero s""#677r'N) r:r;r<r=r&rr,rrrrbr?r'r%rrL s,P3P58r'rc(eZdZdZdZdZdZdZy)DescriptorTestsz Tests for L{amp.Descriptor}, an argument type for passing a file descriptor over an AMP connection over a UNIX domain socket. cd|_t|j|_tjtj tj |_|jj|jy)Nr)r) fuzzrr+rrrkrlrrr-s r%rnzDescriptorTests.setUp~ sU ,DIIF--c.?.?@R@R@T.UV  $$T^^4r'c"tj}|jjd|jjd|jjd|j d|j d|j|j d|j d|j|j d|j d|j|j i|jj y)a| L{Descriptor.fromStringProto} constructs a file descriptor value by extracting a previously received file descriptor corresponding to the wire value of the argument from the L{_DescriptorExchanger} state of the protocol passed to it. This is a whitebox test which involves direct L{_DescriptorExchanger} state inspection. rrr012N)r Descriptorrrrrd _descriptorsrs r%test_fromStringProtoz$DescriptorTests.test_fromStringProto s>># ,,Q/ ,,Q/ ,,Q/ H44S$--HI H44S$--HI H44S$--HI T]]778r'ctj}|jd|jd|j|jdd|j zf|j jjd|jd|jd|j|jdd|j zf|j jjd|jd|jd|j|jdd|j zf|j jjd|ji|jjy ) a= To send a file descriptor, L{Descriptor.toStringProto} uses the L{IUNIXTransport.sendFileDescriptor} implementation of the transport of the protocol passed to it to copy the file descriptor. Each subsequent descriptor sent over a particular AMP connection is assigned the next integer value, starting from 0. The base ten string representation of this value is the byte encoding of the argument. This is a whitebox test which involves direct L{_DescriptorExchanger} state inspection and mutation. 0r!rrrr2rN) rrrrrrr+rrrrs r%test_toStringProtoz"DescriptorTests.test_toStringProto s5>># x55aGH  %q499} 5t~~7L7L7P7PQR7S  x55aGH  %q499} 5t~~7L7L7P7PQR7S  x55aGH  %q499} 5t~~7L7L7P7PQR7S  T]]778r'cd}|jd}i}d}||i}tj}|j|||j |j tj tjtj}|jjD]}t||d|ddi} |j||j | ||j||jz| |y)z L{amp.Descriptor.fromBox} can interpret an L{amp.AmpBox} constructed by L{amp.Descriptor.toBox} to reconstruct a file descriptor value. alpharrrN)rrrrhr]rrrkrlr+rgetattrrbrr) r$r^ nameAsBytesrfr sendObjectsr(receivereventreceiveObjectss r%test_roundTripzDescriptorTests.test_roundTrip s kk'*  Z( >>#{G[-=-=-?O(():):3;M;M;O)PQ^^** 4E 'GHeAh 'qr 3 4gllnnhO dii/1EFr'N)r:r;r<r=rnrrrr?r'r%rrx s 5 9&96Gr'rc reZdZdZdZedddZejdddddd d eZd Z d Z d Z dZ y) DateTimeTestszO Tests for L{amp.DateTime}, L{amp._FixedOffsetTZInfo}, and L{amp.utc}. s 9876-01-23T12:34:56.054321-01:23rri&r"8i1cntj}|jt|jdy)z L{amp.DateTime.fromString} raises L{ValueError} when passed a string which does not represent a timestamp in the proper format. abcN)rrr&rr/r$r]s r%test_invalidStringz DateTimeTests.test_invalidString s% LLN *allE:r'c tj}|jt|jt j ddddddy)z L{amp.DateTime.toString} raises L{ValueError} when passed a naive datetime (a datetime with no timezone information). rrrrN)rrr&rr1rrs r%test_invalidDatetimez"DateTimeTests.test_invalidDatetime s= LLN   H$5$5dBAq!$L r'ctj}|j|j}|j ||j y)z L{amp.DateTime.fromString} returns a C{datetime.datetime} with all of its fields populated from the string passed to it. N)rrr/rrrr$r(r$s r%test_fromStringzDateTimeTests.test_fromString s7 <<>##DKK0  ,r'ctj}|j|j}|j ||j y)z L{amp.DateTime.toString} returns a C{str} in the wire format including all of the information from the C{datetime.datetime} passed into it, including the timezone offset. N)rrr1rrrrs r% test_toStringzDateTimeTests.test_toString s7 <<>!!$++.  ,r'N) r:r;r<r=rrrrrrrrrr?r'r%rr sO1F Q^F X  tQBBv FF; --r'rc(eZdZdZdZdZdZdZy)UTCTestsz Tests for L{amp.utc}. cb|jtjjddy)z8 L{amp.utc.tzname} returns C{"+00:00"}. Nz+00:00)rrrtznamer-s r% test_tznamezUTCTests.test_tzname s! -x8r'c|jtjjdt j dy)z: L{amp.utc.dst} returns a zero timedelta. Nr)rrrdstr timedeltar-s r%test_dstzUTCTests.test_dst s, T*H,>,>q,ABr'c|jtjjdt j dy)z@ L{amp.utc.utcoffset} returns a zero timedelta. Nr)rrr utcoffsetrrr-s r%test_utcoffsetzUTCTests.test_utcoffset s. **40(2D2DQ2GHr'c>|jttdddy)z L{amp._FixedOffsetTZInfo.fromSignHoursMinutes} raises L{ValueError} if passed an offset sign other than C{'+'} or C{'-'}. ?rN)r&rrr-s r% test_badSignzUTCTests.test_badSign s *b#q!4r'N)r:r;r<r=rrr rr?r'r%rr s9 C I 5r'rc"eZdZdZdZdZdZy)RemoteAmpErrorTestsz* Tests for L{amp.RemoteAmpError}. cftjdd}|jdt|y)z L{amp.RemoteAmpError} renders the given C{errorCode} (C{bytes}) and C{description} into a native string. BROKENSomething has brokenz"Code: Something has brokenNrrrr>rCs r%test_stringMessagez&RemoteAmpErrorTests.test_stringMessage s, ""9.DE =s5zJr'cftjdd}|jdt|y)z When C{errorCode} contains non-ASCII characters, L{amp.RemoteAmpError} renders then as backslash-escape sequences. sBROKEN-rz'Code: Something has brokenNrrCs r%&test_stringMessageReplacesNonAsciiTextz:RemoteAmpErrorTests.test_stringMessageReplacesNonAsciiText( s, "">3IJ CSZPr'cttd}tjdd|}|j t |dy)zs L{amp.RemoteAmpError} renders local errors with a "(local)" marker and a brief traceback. zSomething came looserr)localz}^Code [(]local[)]: Something has broken Traceback [(]failure with no frames[)]: <.+Exception.>: Something came loose N)rr|rrrBr>)r$rdr s r%"test_stringMessageWithLocalFailurez6RemoteAmpErrorTests.test_stringMessageWithLocalFailure0 sC )$:;<""9.DGT  J9 r'N)r:r;r<r=rrrr?r'r%rr sKQ r'r)r=rr~typingrrrrunittestrzope.interfacerzope.interface.verifyr r rr r r rrrtwisted.internet.testingrtwisted.protocolsrtwisted.pythonrtwisted.python.failurer twisted.testrtwisted.trial.unittestrr_ssl supported ImportErrorr# IReactorSSLrreactorLacksSSL_FixedOffsetTZInfofromSignHoursMinutesrrZrrrAr|rRrWrYrr[r<rjrrrrrrrrrProtocolSwitchCommandrrrrrrrrrrrr rrr,rRrYrgrrlrrrrrrrrrfr%r)r3r6r9r>rKrgrrrtrvrxrzr|rrrrrrrrrrrrrrrrr r rrrrYrerprurwrrrrrIUNIXTransportr ITransportrrrrr?r'r%r/s  00&;QQ4!#*+, >>;GG((1OO 00&6!!&6R,cgg,,,,),1i1 CLL QCKKQ(E 1#++1&#++ #3;;#ckk "#++"AckkA .3;;.,#++, +c//+ x--  *  $cgg$&U&_U&p('E(*!?*$ 3< 3"(5LN(++2(2:C.8C.L**(#1#1LL88L8^0S[[0 D#$$ D D D) DD0\((\(~!-I@(I@X \ ?x\ ?~ $Y   '_ '$%MNf5xf5O&f5R? 8? DY ) #++{ {   CGG   %sww % %377 % 0 h0 f,W,W^?H$%MN%|X%O&%P '5 '$%MN F h FO& F $%MN\8O&"% %69s{{9""J66:en enDcN 7Oz 8z z*0*0Z W#3 W ($4:#3(,#3,^/;H&6/;d ?8 ? ==.#($4#L>5(>5B Z & &'#8#8(#8N J ! !#67 J % %':;RGhRGj,-H,-^5x5># (# g Cs X22X=<X=