ϪfVdZddlmZddlZddlZddlZddlmZddlm Z ddl m Z ddl m Z mZddlmZdd lmZdd lmZdd lmZdd lmZdd lmZddlmZmZmZmZm Z GddeZ!GddeZ"GddZ#GddZ$GddeZ%GddeZ&GddeZ'GddeZ(Gdd eZ)Gd!d"eZ*y)#z! Tests for L{twisted.trial.util} ) annotationsN)StringIO) Generator) implementer) assert_thatequal_to) DelayedCall)IProcessTransport)filepath)Failure)util)SynchronousTestCase)DirtyReactorAggregateError_JanitoracquireAttributeexcInfoOrFailureToExcInfo openTestLogc0eZdZdZddZddZddZddZy) MktempTestszm Tests for L{TestCase.mktemp}, a helper function for creating temporary file or directory names. c|j}tjj|j tj dd}|j |gdy)z The path name returned by C{mktemp} is directly beneath a directory which identifies the test method which created the name. N)ztwisted.trial.test.test_utilr test_name)mktempospathdirnamesplitsep assertEqual)selfnamedirss >/usr/lib/python3/dist-packages/twisted/trial/test/test_util.pyrzMktempTests.test_name)sK {{}wwt$**26623B7  N cd|j}|j||jy)zF Repeated calls to C{mktemp} return different values. N)rassertNotEqual)r r!s r# test_uniquezMktempTests.test_unique4s%{{} D$++-0r$c|j}tjj|}|j tjj ||j tjj |y)zS The directory part of the path name returned by C{mktemp} exists. N)rrrr assertTrueexists assertFalse)r r!rs r# test_createdzMktempTests.test_created;sU{{}''//$' w/0 -.r$ctjj|j}|j |j tj y)zZ The path returned by C{mktemp} is beneath the current working directory. N)rrabspathrr) startswithgetcwd)r rs r# test_locationzMktempTests.test_locationDs7wwt{{}-  45r$NreturnNone)__name__ __module__ __qualname____doc__rr'r,r1r$r#rr#s  1/6r$rc(eZdZdZddZddZddZy)DirtyReactorAggregateErrorTestsz6 Tests for the L{DirtyReactorAggregateError}. cTtddg}|jt|dy)z5 Delayed calls are formatted nicely. FoobarzhReactor was unclean. DelayedCalls: (set twisted.internet.base.DelayedCall.debug = True to debug) Foo barNrrstrr errors r#test_formatDelayedCallz6DirtyReactorAggregateErrorTests.test_formatDelayedCallQs,+E5>:  J  r$cVtgddg}|jt|dy)z3 Selectables are formatted nicely. z selectable 1z selectable 2z;Reactor was unclean. Selectables: selectable 1 selectable 2Nr?rAs r#test_formatSelectablesz6DirtyReactorAggregateErrorTests.test_formatSelectables_s/+2/OP  J  r$cZtddgddg}|jt|dy)zR Both delayed calls and selectables can appear in the same error. bleckBoozoSel1Sel2zReactor was unclean. DelayedCalls: (set twisted.internet.base.DelayedCall.debug = True to debug) bleck Boozo Selectables: Sel1 Sel2Nr?rAs r#%test_formatDelayedCallsAndSelectableszEDirtyReactorAggregateErrorTests.test_formatDelayedCallsAndSelectablesms4+GW+=?OP  J  r$Nr2)r5r6r7r8rCrErKr9r$r#r;r;Ls     r$r;c@eZdZdZ d ddZdd dZd dZd dZy) StubReactora~ A reactor stub which contains enough functionality to be used with the L{_Janitor}. @ivar iterations: A list of the arguments passed to L{iterate}. @ivar removeAllCalled: Number of times that L{removeAll} was called. @ivar selectables: The value that will be returned from L{removeAll}. @ivar delayedCalls: The value to return from L{getDelayedCalls}. NcD||_g|_d|_|sg}||_y)z @param delayedCalls: See L{StubReactor.delayedCalls}. @param selectables: See L{StubReactor.selectables}. rN) delayedCalls iterationsremoveAllCalled selectables)r rOrRs r#__init__zStubReactor.__init__s+).0 K&r$c:|jj|y)z/ Increment C{self.iterations}. N)rPappend)r timeouts r#iteratezStubReactor.iterates w'r$c|jS)z. Return C{self.delayedCalls}. )rOr s r#getDelayedCallszStubReactor.getDelayedCallss   r$cD|xjdz c_|jS)zS Increment C{self.removeAllCalled} and return C{self.selectables}. )rQrRrYs r# removeAllzStubReactor.removeAlls! !r$N)rOlist[DelayedCall]rRzlist[object] | Noner3r4)rVz float | Noner3r4)r3r_)r3z list[object])r5r6r7r8rSrWrZr]r9r$r#rMrMs:SW '- '|jj||fy)z6 Record parameters in C{self.errors}. N)rcrU)r testrBs r#addErrorzStubErrorReporter.addErrors D%=)r$Nr2)reobjectrBr r3r4)r5r6r7r8rSrfr9r$r#raras7*r$racheZdZdZddZddZddZddZddZddZ ddZ dd Z dd Z dd Z dd Zy ) JanitorTestsz Tests for L{_Janitor}! ctg}tdd|}|j|j|jddgy)a During pending-call cleanup, the reactor will be spun twice with an instant timeout. This is not a requirement, it is only a test for current behavior. Hopefully Trial will eventually not do this kind of reactor stuff. Nreactorr)rMr _cleanPendingrrPr rljans r#test_cleanPendingSpinsReactorz*JanitorTests.test_cleanPendingSpinsReactorsAb/tT73  ++aV4r$cdd}g}td|di|jd}t|g}tdd|}|j |j ||gy)zW During pending-call cleanup, the janitor cancels pending timed calls. cy)NLulzr9r9r$r#funcz8JanitorTests.test_cleanPendingCancelsCalls..funcsr$,r9cyr^r9xs r#z.r$Nrkr3r@)r rUrMrrmr)r rt cancelled delayedCallrlros r#test_cleanPendingCancelsCallsz*JanitorTests.test_cleanPendingCancelsCallss`  (* !#tRY5E5E~V {m,tT73  [M2r$c tdddiddd}t|}t|g}tdd|}|j }|j ||gy) aK The Janitor produces string representations of delayed calls from the delayed call cleanup method. It gets the string representations *before* cancelling the calls; this is important because cancelling the call removes critical debugging information from the string representation. rucyr^r9r9r$r#ryzIJanitorTests.test_cleanPendingReturnsDelayedCallStrings..rzr$r9cyr^r9rws r#ryzIJanitorTests.test_cleanPendingReturnsDelayedCallStrings..rzr$cyNrr9r9r$r#ryzIJanitorTests.test_cleanPendingReturnsDelayedCallStrings..rzr$secondsNrk)r r@rMrrmr)r r}delayedCallStringrlrostringss r#*test_cleanPendingReturnsDelayedCallStringsz7JanitorTests.test_cleanPendingReturnsDelayedCallStringssf" r2~~y  ,{m,tT73##% #4"56r$ctg}tdd|}|j|j|jdy)zM The Janitor will remove selectables during reactor cleanup. Nrkr\)rMr _cleanReactorrrQrns r##test_cleanReactorRemovesSelectablesz0JanitorTests.test_cleanReactorRemovesSelectabless=b/tT73  00!4r$cttGdd}|}tg|g}tdd|}|j |j |j dgy)zI The Janitor will kill processes during reactor cleanup. c eZdZdZddZddZy)JJanitorTests.test_cleanReactorKillsProcesses..StubProcessTransportz A stub L{IProcessTransport} provider which records signals. @ivar signals: The signals passed to L{signalProcess}. cg|_yr^)signalsrYs r#rSzSJanitorTests.test_cleanReactorKillsProcesses..StubProcessTransport.__init__s 02 r$c:|jj|y)zF Append C{signal} to C{self.signals}. N)rrU)r signals r# signalProcesszXJanitorTests.test_cleanReactorKillsProcesses..StubProcessTransport.signalProcesss ##F+r$Nr2)rz str | intr3r4)r5r6r7r8rSrr9r$r#StubProcessTransportrs   3 ,r$rNrkKILL)rr rMrrrr)r rptrlros r#test_cleanReactorKillsProcessesz,JanitorTests.test_cleanReactorKillsProcessessi & ' , , ( ," #b2$'tT73  fX.r$cGdd}tg|g}tdd|}|j|jdgy)z The Janitor returns string representations of the selectables that it cleaned up from the reactor cleanup method. ceZdZdZddZy)JJanitorTests.test_cleanReactorReturnsSelectableStrings..Selectablezl A stub Selectable which only has an interesting string representation. cy)N (SELECTABLE!)r9rYs r#__repr__zSJanitorTests.test_cleanReactorReturnsSelectableStrings..Selectable.__repr__ s&r$Nr{)r5r6r7r8rr9r$r# Selectablers    'r$rNrkr)rMrrr)r rrlros r#)test_cleanReactorReturnsSelectableStringsz6JanitorTests.test_cleanReactorReturnsSelectableStringssH  ' 'b:<.1tT73 **,.?@r$ctg}t}t}t|||}|j |j |j |jgy)z The post-case cleanup method will return True and not call C{addError} on the result if there are no pending calls. rkN)rMrgrarr)postCaseCleanuprrcr rlrereporterros r#test_postCaseCleanupNoErrorsz)JanitorTests.test_postCaseCleanupNoErrors'sS b/x$&tXw7 ++-. "-r$c tdddiddd}t|}t|gg}t}t }t |||}|j |j|jt|jd|j|jd djj|gy ) z The post-case cleanup method will return False and call C{addError} on the result with a L{DirtyReactorAggregateError} Failure if there are pending calls. rucyr^r9r9r$r#ryz=JanitorTests.test_postCaseCleanupWithErrors..:rzr$r9cyr^r9rws r#ryz=JanitorTests.test_postCaseCleanupWithErrors..:rzr$cyrr9r9r$r#ryz=JanitorTests.test_postCaseCleanupWithErrors..:rzr$rrkr\rN) r r@rMrgrarr+rrlenrcvaluerOr r}rrlrerros r#test_postCaseCleanupWithErrorsz+JanitorTests.test_postCaseCleanupWithErrors3s " r2~~y  ,{mR0x$&tXw7 ,,./ X__-q1 +A.44AADUCVWr$ctg}t}t}t|||}|j |j |j gy)z The post-class cleanup method will not call C{addError} on the result if there are no pending calls or selectables. rkN)rMrgrarpostClassCleanuprrcrs r#test_postClassCleanupNoErrorsz*JanitorTests.test_postClassCleanupNoErrorsEsJ b/x$&tXw7  "-r$c |tdddiddd}t|}t|gg}t}t }t |||}|j |jt|jd|j|jd djj|gy ) z The post-class cleanup method call C{addError} on the result with a L{DirtyReactorAggregateError} Failure if there are pending calls. rucyr^r9r9r$r#ryzIJanitorTests.test_postClassCleanupWithPendingCallErrors..Wrzr$r9cyr^r9rws r#ryzIJanitorTests.test_postClassCleanupWithPendingCallErrors..Wrzr$cyrr9r9r$r#ryzIJanitorTests.test_postClassCleanupWithPendingCallErrors..Wrzr$rrkr\rN) r r@rMrgrarrrrrcrrOrs r#*test_postClassCleanupWithPendingCallErrorsz7JanitorTests.test_postClassCleanupWithPendingCallErrorsQs " r2~~y  ,{mR0x$&tXw7  X__-q1 +A.44AADUCVWr$cPd}tg|g}t}t}t|||}|j |j t |jd|j |jddjjt|gy)z The post-class cleanup method call C{addError} on the result with a L{DirtyReactorAggregateError} Failure if there are selectables. zSELECTABLE HERErkr\rN) rMrgrarrrrrcrrRrepr)r selectablerlrerros r#)test_postClassCleanupWithSelectableErrorsz6JanitorTests.test_postClassCleanupWithSelectableErrorsbs ' b:,/x$&tXw7  X__-q1 +A.44@@4 CSBTUr$Nr2)r5r6r7r8rpr~rrrrrrrrrr9r$r#ririsB 5 37"5/6A& .X$ .X" Vr$ric(eZdZdZddZddZddZy)RemoveSafelyTestsz* Tests for L{util._removeSafely}. c|jjd}tj|t j |}|j tjtj|y)z If a path doesn't contain a node named C{"_trial_marker"}, that path is not removed by L{util._removeSafely} and a L{util._NoTrialMarker} exception is raised instead. utf-8N) rencodermkdirr FilePath assertRaisesr _NoTrialMarker _removeSafely)r directorydirPaths r#test_removeSafelyNoTrialMarkerz0RemoveSafelyTests.test_removeSafelyNoTrialMarkervsT KKM((1  ##I. $--t/A/A7Kr$cdd}t}|jtd||jj d}t j |tj|}|jdj||_ tj||jd|jy)z If an L{OSError} is raised while removing a path in L{util._removeSafely}, an attempt is made to move the path to a new name. ct) Raise an C{OSError} to emulate the branch of L{util._removeSafely} in which path removal fails. OSErrorr9r$r# dummyRemovezORemoveSafelyTests.test_removeSafelyRemoveFailsMoveSucceeds..dummyRemoves )Or$stdoutr _trial_markercould not remove FilePathNr2)rpatchsysrrrrr rchildtouchremover rassertIngetvalue)r routrrs r#(test_removeSafelyRemoveFailsMoveSucceedsz:RemoveSafelyTests.test_removeSafelyRemoveFailsMoveSucceedss j 3#&KKM((1  ##I. &'--/$ 7# 13<<>Br$cd d}d d d}t}|jtd||jj d}t j |tj|}|jdj||_ ||_ |jttj |}|j#t%|d|j'd|j)y) z If an L{OSError} is raised while removing a path in L{util._removeSafely}, an attempt is made to move the path to a new name. If that attempt fails, the L{OSError} is re-raised. ctd)rzpath removal failedrr9r$r#rzLRemoveSafelyTests.test_removeSafelyRemoveFailsMoveFails..dummyRemoves /0 0r$ctd)z Raise an C{OSError} to emulate the branch of L{util._removeSafely} in which path movement fails. path movement failedr) destination followLinkss r# dummyMoveTozLRemoveSafelyTests.test_removeSafelyRemoveFailsMoveFails..dummyMoveTos 01 1r$rrrrrNr2)T)rrgrboolr3r4)rrrrrrrr rrrrmoveTorrr rrr@rr)r rrrrrrBs r#%test_removeSafelyRemoveFailsMoveFailsz7RemoveSafelyTests.test_removeSafelyRemoveFailsMoveFailss 1 2j 3#&KKM((1  ##I. &'--/%$!!'4+=+=wG U%;< 13<<>Br$Nr2)r5r6r7r8rrrr9r$r#rrqs LC:%Cr$rc eZdZdZddZddZy) ExcInfoTestsz1 Tests for L{excInfoOrFailureToExcInfo}. c`ttddf}|j|t|uy)z L{excInfoOrFailureToExcInfo} returns exactly what it is passed, if it is passed a tuple like the one returned by L{sys.exc_info}. fooN) ValueErrorr)r)r infos r# test_excInfozExcInfoTests.test_excInfos, Ju-t4  9$ ??@r$c ddz |jj|j|j ft |y#t$r t}YRwxYw)z When called with a L{Failure} instance, L{excInfoOrFailureToExcInfo} returns a tuple like the one returned by L{sys.exc_info}, with the elements taken from the type, value, and traceback of the failure. r\rN) BaseExceptionr rtypertbr)r fs r# test_failurezExcInfoTests.test_failuresQ   E !&&!''14402KA2NO  A sAAANr2)r5r6r7r8rrr9r$r#rrsA Pr$rc0eZdZdZddZddZddZddZy)AcquireAttributeTestsz( Tests for L{acquireAttribute}. cttx|_}|j|t|tgduy)z The value returned by L{acquireAttribute} is the value of the requested attribute on the first object in the list passed in which has that attribute. rNrgrr)rr rs r#test_foundOnEarlierObjectz/AcquireAttributeTests.test_foundOnEarlierObjects2 $X% U !142BG!LLMr$cttx|_}|j|tt|gduy)z The same as L{test_foundOnEarlierObject}, but for the case where the 2nd element in the object list has the attribute and the first does not. rNrrs r#test_foundOnLaterObjectz-AcquireAttributeTests.test_foundOnLaterObjects2 $X% U !168T2BG!LLMr$cN|jtttgdy)z If none of the objects passed in the list to L{acquireAttribute} have the requested attribute, L{AttributeError} is raised. rN)rAttributeErrorrrgrYs r#test_notFoundExceptionz,AcquireAttributeTests.test_notFoundExceptions .*:VXJNr$cft}|j|ttgd|uy)z If none of the objects passed in the list to L{acquireAttribute} have the requested attribute and a default value is given, the default value is returned. rN)rgr)r)r defaults r#test_notFoundDefaultz*AcquireAttributeTests.test_notFoundDefaults* ( #3VXJw#OOPr$Nr2)r5r6r7r8rrrrr9r$r#rrsNNOQr$rcXeZdZdZd dZd dZd dZd dZd dZd dZ d dZ d d Z d d Z y ) ListToPhraseTestsz Input is transformed into a string representation of the list, with each item separated by delimiter (defaulting to a comma) and the final two being separated by a final delimiter. c\g}d}tj|d}|j||y)zB If things is empty, an empty string is returned. andNr _listToPhraserr sampleexpectedresults r# test_emptyzListToPhraseTests.test_emptys0 ##FE2 6*r$c^dg}d}tj|d}|j||y)z; With a single item, the item is returned. OnerNrrs r# test_oneWordzListToPhraseTests.test_oneWords2##FE2 6*r$c`ddg}d}tj|d}|j||y)zA Two words are separated by the final delimiter. r Twoz One and TworNrrs r# test_twoWordszListToPhraseTests.test_twoWords s4 ##FE2 6*r$c`gd}d}tj|d}|j||y)zY With more than two words, the first two are separated by the delimiter. )r r ThreezOne, Two, and ThreerNrrs r#test_threeWordsz!ListToPhraseTests.test_threeWords)s0)(##FE2 6*r$cdgd}d}tj|dd}|j||y)zW If a delimiter is specified, it is used instead of the default comma. )r r rFourzOne; Two; Three; or Fourorz; ) delimiterNrrs r#test_fourWordsz ListToPhraseTests.test_fourWords2s21-##FDDA 6*r$c`gd}d}tj|d}|j||y)zS If something in things is not a string, it is converted into one. )r\threez1, 2, and threerNrrs r#test_notStringz ListToPhraseTests.test_notString;s0!$##FE2 6*r$cd}|jttj|d}|j t |dy)z? If things is a string, a TypeError is raised. zOne, two, threer Things must be a list or a tupleNr TypeErrorr rrr@r rrBs r#test_stringTypeErrorz&ListToPhraseTests.test_stringTypeErrorDs:#!!)T-?-?O U%GHr$ctgd}|jttj|d}|j t |dy)zB If things is an iterator, a TypeError is raised. )r\rrrN)iterrrr rrr@rs r#test_iteratorTypeErrorz(ListToPhraseTests.test_iteratorTypeErrorLs>i!!)T-?-?O U%GHr$cdd}|jttj|d}|j t |dy)zB If things is a generator, a TypeError is raised. c36KtdEd{y7w)Nr)ranger9r$r#rz9ListToPhraseTests.test_generatorTypeError..sampleYsQx  s rrN)r3zGenerator[int, None, None]rrs r#test_generatorTypeErrorz)ListToPhraseTests.test_generatorTypeErrorTs:  !!)T-?-?O U%GHr$Nr2) r5r6r7r8rr rrrrr r$r(r9r$r#rrs7 ++++++II Ir$rc eZdZdZddZddZy)OpenTestLogTestsz# Tests for C{openTestLog}. c<tj}|jtjtj|tjtjdd}t j |j}t|5}|j|dddt|jd5}|j}dddt|jdty#1swY]xYw#1swY:xYw)zR The log file is opened in text mode and uses UTF-8 for encoding. )CasciiuHere comes the ☉Nrbr)locale getlocale addCleanup setlocaleLC_ALLr rrrwriteopenrreadrrr)r currentLocaletextprwrittens r# test_utf8zOpenTestLogTests.test_utf8es((*  ((&--G7'   dkkm , ^ q GGDM !&&$  1ffhG  DKK((7*;<     sDDDDcd}d}dtjdtj}tj|j }t |5}|j |dddt |5}|j |dddt|jjdt|y#1swYaxYw#1swYHxYw)z The log file is opened in append mode so if runner configuration specifies an existing log file its contents are not wiped out. zHello, world. zGoodbye, world. z Hello, world.z Goodbye, world.Nr) rlinesepr rrrr4r getContentdecoder)r existingTextnewTextrr9rs r# test_appendzOpenTestLogTests.test_append{s * %"2::,.>rzzlK   dkkm , ^ "q GGL ! " ^ q GGG    LLN ! !' * X   " "  sC <C CCNr2)r5r6r7r8r;rBr9r$r#r*r*`s=, r$r*)+r8 __future__rr/rriortypingrzope.interfacerhamcrestrrtwisted.internet.baser twisted.internet.interfacesr twisted.pythonr twisted.python.failurer twisted.trialr twisted.trial.unittestrtwisted.trial.utilrrrrrrr;rMrarirrrrr*r9r$r#rOs # &*-9#*6&6%&6R0 &90 f* * Z**&oV&oVdRC+RCjP&P4$Q/$QNVI+VIr, *, r$