Ϫf[SdZddlmZmZmZddlmZGddZGddZGdd ejZ Gd d e Z Gd d ejZ GddejZy)z_ This module contains tests for L{twisted.internet.task.Cooperator} and related functionality. )deferreactortask)unittestceZdZdZdZdZy)FakeDelayedCallzA Fake delayed call which lets us simulate the scheduler. c ||_d|_y)z+ A function to run, later. FN)func cancelledselfr s >/usr/lib/python3/dist-packages/twisted/test/test_cooperator.py__init__zFakeDelayedCall.__init__s cd|_y)z. Don't run my function later. TN)r r s rcancelzFakeDelayedCall.cancels rN)__name__ __module__ __qualname____doc__rrrrrrsrrc"eZdZdZdZdZdZy) FakeSchedulerz/ A fake scheduler for testing against. cg|_y)zD Create a fake scheduler with a list of work to do. N)workrs rrzFakeScheduler.__init__&s  rcRt|}|jj||S)z; Schedule a unit of work to be done later. )rrappend)r thunkunits r__call__zFakeScheduler.__call__,s%u%  rct|jgc}|_|D]}|jr|j!y)zL Do all of the work that is currently available to be done. N)rr r )r rr s rpumpzFakeScheduler.pump4s4))Rdi D>>  rN)rrrrrr!r#rrrrr!s rrcpeZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZy)CooperatorTestsdonecX|jtj|jSN)traprSchedulerStoppedRESULT)r errs rebIterzCooperatorTests.ebIterAs &&'{{rc$|jyr()fail)r igns rcbIterzCooperatorTests.cbIterEs  rcDfddjfdS)zU Test that Cooperators refuse new tasks when they have been stopped. ctj}|j|jt d|}|j j |jj|j fdS)Nrc<j|jSr( assertEqualr+resultr s rzNCooperatorTests.testStoppedRejectsNewTasks..testwith..Ss0@0@0Ur) r Cooperatorstop coiterateiter addCallbackr1 addErrbackr-)stuffcdr s rtestwithz.testwithMs\!A FFH DHe,A MM$++ & LL %==!UV VrNc8tjSr()rDeferred)r0rCs rr9z.Ushu~~?O6Pr)r>)r rCs`@rtestStoppedRejectsNewTasksz*CooperatorTests.testStoppedRejectsNewTasksHs!  W~))*PQQrc,tj}dd_|j}|j j |j j|jfd}|j ||S)zq Test that a running iterator will not run to completion when the cooperator is stopped. c36KtdEd{y7w)N)rangerrrmyiterz/CooperatorTests.testStopRunning..myiter^sQx  s cvj|jjjdyNrL)r6r+value)r8rKr s r doassertsz2CooperatorTests.testStopRunning..doassertsgs+   VT[[ 1   V\\2 .r) rr:rOr<r>r1r?r-r;)r rArBrPrKs` @rtestStopRunningzCooperatorTests.testStopRunningWsp OO   KK ! dkk" T[[!  / i rc~tjtjfd}tjj |}fd}j ||j j |jj|j fdS)z An iterator run with L{Cooperator.coiterate} paused on a L{Deferred} yielded by that iterator will fire its own L{Deferred} (the one returned by C{coiterate}) when L{Cooperator.stop} is called. c3xKtjdjdjywNr)r callLatercallbackr/) outstandingDr testControlDsrrKz3CooperatorTests.testStopOutstanding..myiterws.   a!6!6 =  IIKs7:cHjjdy)N arglebargle)r;rV)r0rArWs r stopAndGoz6CooperatorTests.testStopOutstanding..stopAndGos FFH  ! !- 0rc<j|jSr(r5r7s rr9z5CooperatorTests.testStopOutstanding..sD,<,r1r?r-)r rKrBr[rArWrXs` @@@rtestStopOutstandingz#CooperatorTests.testStopOutstandingns ~~' ~~'   OO  KK ! 1   + dkk" T[[!}}QRRrctj}d}|j|}|j|tS)Nc3 K twr() RuntimeErrorrrrrKz3CooperatorTests.testUnexpectedError..myiters#n$s rr:r< assertFailurer`)r rArKrBs rtestUnexpectedErrorz#CooperatorTests.testUnexpectedErrors8 OO  % KK !!!!\22rcd}tj}|j|}|j|tS)Nc3Ktj}tjd|jt |ywrT)rrErrUerrbackr`)Ds rrKz@CooperatorTests.testUnexpectedErrorActuallyLater..myiters/ A   aLN ;GsAArar rKrArBs r testUnexpectedErrorActuallyLaterz0CooperatorTests.testUnexpectedErrorActuallyLaters8  OO  KK !!!!\22rcd}tj}|j|}|j|tS)Nc3JKtjtywr()rr/r`rrrrKzCCooperatorTests.testUnexpectedErrorNotActuallyLater..myiters**\^, ,s!#rarhs r#testUnexpectedErrorNotActuallyLaterz3CooperatorTests.testUnexpectedErrorNotActuallyLaters8 - OO  KK !!!!\22rcgfd}gdtj}g}D](}|j|j||*t j |j fdS)Nc3FK|D]}j|dywr(r)thingsthLs rrKz/CooperatorTests.testCooperation..myiters&    s!)abcrIdef)cZjtttdSNr)r6tuplesumzip)r0rrgroupsOfThingsr s rr9z1CooperatorTests.testCooperation..s$((q3sN7KR3PQr)rr:rr<r DeferredListr>)r rKrAtasksr@rrrs` @@rtestCooperationzCooperatorTests.testCooperationsp   > OO # 5E LLVE]3 4 5!!%(44 Q  rcgfd}Gddtj}|j|j|j|j j |j|j|jj|jttdy)Nc3pKtdD]#}j||dk(rd_|%yw)Nd T)rJrstopped)i_TPFoutputs rrKz6CooperatorTests.testResourceExhaustion..myiters93Z  a 6#'DL  s36ceZdZdZdZy)4CooperatorTests.testResourceExhaustion.._TPFFc|jSr()rrs rr!z=CooperatorTests.testResourceExhaustion.._TPF.__call__s ||#rN)rrrrr!rrrrrs G $rr)terminationPredicateFactory )rr:r<r?r- _delayedCallr_tickr; assertTruerr6listrJ)r rKrArrs @@rtestResourceExhaustionz&CooperatorTests.testResourceExhaustions  $ $ OO = FH((5      % eBi1rcbgGddfd}tj|djtd}gfd}|j |d}sH|d z }r'j dj |d z }r'|d kDrjd sGy y ) a* If a callback to a deferred returned by coiterate calls coiterate on the same Cooperator, we should make sure to only do the minimal amount of scheduling work. (This test was added to demonstrate a specific bug that was found while writing the scheduler.) ceZdZdZdefdZy)9CooperatorTests.testCallbackReCoiterate..FakeCallc||_yr(r r s rrzBCooperatorTests.testCallbackReCoiterate..FakeCall.__init__s   rreturnc"d|jdS)Nz rrs r__repr__zBCooperatorTests.testCallbackReCoiterate..FakeCall.__repr__s#DII=22rN)rrrrstrrrrrFakeCallrs ! 3# 3rrcrjtj|dSrN) assertFalsereprr)frcallsr s rschedz6CooperatorTests.testCallbackReCoiterate..scheds1   UDK 0 LL! %9 rcdS)NcyNTrrrrr9zKCooperatorTests.testCallbackReCoiterate....rrrrrr9z9CooperatorTests.testCallbackReCoiterate..sr schedulerrrcljtdjjyr|)r<r=addBothr)r0rAr&s r anotherTaskz.anotherTasks" KKR ! ) )$++ 6rrru2zCooperator took too longN)rr:r<r=r>popr r/) r rrBrrrrArr&s ` @@@@rtestCallbackReCoiteratez'CooperatorTests.testCallbackReCoiterates 3 3  OO9M  KKR ! 7 k" AID ! !!# by 45 rcdgfd}tj|}|jtddg}|jtddg}|j dj |j |j|jdj|j |jd|j|jdj|j|j|jtddg|jdj|j |jdy)a If the last task in a Cooperator is removed, the scheduled call for the next tick is cancelled, since it is no longer necessary. This behavior is useful for tests that want to assert they have left no reactor state behind when they're done. Nc*t|d<dSrT)r)rrs rrzFCooperatorTests.test_removingLastTaskStopsScheduledCall..scheds&q)E!H8Or)rrurvr) rr: cooperater=r6r rr;rr rr assertIsNone)r rcooptask1task2rs @r'test_removingLastTaskStopsScheduledCallz7CooperatorTests.test_removingLastTaskStopsScheduledCalls% /tQF|,tQF|, q 3   q++, **E!H5   a**+ $++, tQF|$ q++, **E!H5rcbtj}|j|jy)zm L{Cooperator.running} reports C{True} if the L{Cooperator} was started on creation. N)rr:rrunningr rAs rtest_runningWhenStartedz'CooperatorTests.test_runningWhenStarted"s OO   "rcftjd}|j|jy)zk L{Cooperator.running} reports C{False} if the L{Cooperator} has not been started. FstartedN)rr:rrrs rtest_runningWhenNotStartedz*CooperatorTests.test_runningWhenNotStarted*s$ OOE * #rctjd}|j|j|j|j |j y)zb L{Cooperator.running} reports C{True} when the L{Cooperator} is running. FrN)rr:start addCleanupr;rrrs rtest_runningWhenRunningz'CooperatorTests.test_runningWhenRunning2s; OOE *     "rctjd}|j|j|j |j y)zj L{Cooperator.running} reports C{False} after the L{Cooperator} has been stopped. FrN)rr:rr;rrrs rtest_runningWhenStoppedz'CooperatorTests.test_runningWhenStopped<s6 OOE *    #rN)rrrr+r-r1rFrQr]rcrirlrrrrrrrrrrrr%r%>s[ F R.S6 333 &24(6T"6H#$#$rr%ceZdZdZy)UnhandledExceptionz0 An exception that should go unhandled. N)rrrrrrrrrGsrrceZdZdZdZy) AliasTestszg Integration test to verify that the global singleton aliases do what they're supposed to. ctjfd}|}tj|}|j |tj j S)zZ L{twisted.internet.task.cooperate} ought to run the generator that it is c3HKdddjdyw)NrurvrIyay)rV)rBsrdoitz'AliasTests.test_cooperate..doitYs"GGG JJu s")rrErrassertIn_theCooperator_tasks)r rittheTaskrBs @rtest_cooperatezAliasTests.test_cooperateSsL NN   V..$ gt2299:rN)rrrrrrrrrrMs  rrceZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZdZdZdZdZy) RunStateTestsz Tests to verify the behavior of L{CooperativeTask.pause}, L{CooperativeTask.resume}, L{CooperativeTask.stop}, exhausting the underlying iterator, and their interactions with each other. c8d|_d|_d|_g|_t |_t j|j d|_|jj|j|_|jjy)z Create a cooperator with a fake scheduler and a termination predicate that ensures only one unit of work will take place per tick. FcdS)Ncyrrrrrr9z7RunStateTests.setUp....zrrrrrrr9z%RunStateTests.setUp..zs rrN) _doDeferNext _doStopNext _doDieNextrrrrr: cooperatorrworkerrrs rsetUpzRunStateTests.setUplsu "  &//nn)=   OO--dkkm<  rc#.Kd} |dz }|jr;d|_tj}|jj ||nB|j ry|j r t|jj ||w)z This is a sample generator which yields Deferreds when we are testing deferral and an ascending integer count otherwise. rruFN)rrrErrrrr)r rrBs rrzRunStateTests.workers  FA  $)!NN$   #!!(**   #sBBc |`|`y)z Drop references to interesting parts of the fixture to allow Deferred errors to be noticed when things start failing. N)rrrs rtearDownzRunStateTests.tearDowns I Nrcd|_y)z@ Defer the next result from my worker iterator. TN)rrs r deferNextzRunStateTests.deferNexts !rcd|_y)zm Make the next result from my worker iterator be completion (raising StopIteration). TN)rrs rstopNextzRunStateTests.stopNexts  rcd}d|_y)zk Make the next result from my worker iterator be raising an L{UnhandledException}. c.|jtyr()r)r)failures rignoreUnhandledz.RunStateTests.dieNext..ignoreUnhandleds LL+ ,rTN)r)r rs rdieNextzRunStateTests.dieNexts  rcf|jj|j|jdg|jj|j|jddg|jj |jj|j|jddg|jj |j|jddg|jj|j|jgdy)z Cooperators should stop running their tasks when they're paused, and start again when they're resumed. rurvrtN)rr#r6rrpauseresumers rtest_pauseResumezRunStateTests.test_pauseResumes  QC(  QF+   QF+  QF+  I.rc<|jtj|jj|jj |jj|jtj|jjy)z L{CooperativeTask.resume} should raise a L{TaskNotPaused} exception if it was not paused; e.g. if L{CooperativeTask.pause} was not invoked more times than L{CooperativeTask.resume} on that object. N) assertRaisesr NotPausedrrrs rtest_resumeNotPausedz"RunStateTests.test_resumeNotPauseds^ $..$))*:*:;   $..$))*:*:;rc|jj|jj|j |j g|jj|jj|j |j g|jj |jj|j |j g|jj |jj|j |j dgy)z~ Pauses on tasks should behave like a stack. If a task is paused twice, it needs to be resumed twice. ruN)rrrr#r6rrrs rtest_pauseTwicezRunStateTests.test_pauseTwices   B'   B'   B'   QC(rc|j|jj|jt |j d|j |j dtj|jj|jt |j d|jj|jj|jt |j d|jj|jj|jt |j d|j djd|jj|jt |j d|j|j ddy)a C{pause()}ing a task while it is waiting on an outstanding L{defer.Deferred} should put the task into a state where the outstanding L{defer.Deferred} must be called back I{and} the task is C{resume}d before it will continue processing. rurzSTUFF!rvN) rrr#r6lenrassertIsInstancerrErrrrVrs rtest_pauseWhileDeferredz%RunStateTests.test_pauseWhileDeferreds>   TYY+ diilENN;  TYY+   TYY+   TYY+ ! h'  TYY+ 1q)rc|jj}|jj}ggg}g}fd}fd}|j||j||j|j|j|j|j |j j |jtd|jtd|jd|jj|jd|jj|j|dg|j|dgy)a/ L{CooperativeTask.whenDone} returns a Deferred which fires when the Cooperator's iterator is exhausted. It returns a new Deferred each time it is called; callbacks added to other invocations will not modify the value that subsequent invocations will fire with. c(j|y)Nruro)r8results1s r callbackOnez0RunStateTests.test_whenDone..callbackOne OOF #rc(j|y)Nrvro)r8results2s r callbackTwoz0RunStateTests.test_whenDone..callbackTworrrurrvN) rwhenDoner>rrrr#r6rassertIs _iterator) r deferred1 deferred2final1final2rrrrs @@r test_whenDonezRunStateTests.test_whenDones(II&&( II&&(    k*k*fmm,fmm,   X* X* hqk499#6#67 hqk499#6#67 !% !%rcT|jj}g}|j|j|j |j j |jt|d|j|djtty)z L{CooperativeTask.whenDone} returns a L{defer.Deferred} that will fail when the iterable's C{next} method raises an exception, with that exception. rurN) rrr?rrrr#r6rcheckr)r rresultss rtest_whenDoneErrorz RunStateTests.test_whenDoneError/s{ II&&( W^^,   Wq) ))*<=?QRrc\|jj}g}|j|j|jj |j t |d|j |djtjtjy)z L{CooperativeTask.whenDone} returns a L{defer.Deferred} that fails with L{TaskStopped} when the C{stop} method is called on that L{CooperativeTask}. rurN) rrr?rr;r6rr  TaskStopped)r rerrorss rtest_whenDoneStopzRunStateTests.test_whenDoneStop=sx II&&( V]]+  Va( )9)9:Drr6r)r rs rtest_whenDoneAlreadyDonez&RunStateTests.test_whenDoneAlreadyDoneJs^   ((8 499#6#6"78rc|jj|jj|j t |j d|jtj|jj|jtj|jj|jj|j |j gy)z C{stop()}ping a task should cause it to be removed from the run just as C{pause()}ing, with the distinction that C{resume()} will raise a L{TaskStopped} exception. rN) rr;rr#r6rrrrrrs rtest_stopStopszRunStateTests.test_stopStopsUs   TYY+ $**DIINN; $**DIIOO<  B'rc |jj|jj|jj|jj |j |jgy)z C{resume()}ing a paused, stopped task should be a no-op; it should not raise an exception, because it's paused, but neither should it actually do more work from the task. N)rrr;rrr#r6rrs rtest_pauseStopResumez"RunStateTests.test_pauseStopResumedsT     B'rcb|j|jj|jj }|j |j jdg}|j|j|jj|j j|jj|jd|jj|j |dg|j |jgy)a As a corrolary of the interaction of C{pause()} and C{unpause()}, C{stop()}ping a task which is waiting on a L{Deferred} should cause the task to gracefully shut down, meaning that it should not be unpaused when the deferred fires. ruN) rrr#rrr6r _pauseCountrrr;rV)r rBrs rtest_stopDeferredzRunStateTests.test_stopDeferredps   IIMMO ..2 '..!    1   4&) B'rc|j|jj|jtj |jj y)zx C{stop()}ping a L{CooperativeTask} whose iterator has been exhausted should raise L{TaskDone}. N)rrr#rrTaskDoner;rs rtest_stopExhaustedz RunStateTests.test_stopExhausteds9   $--8rc|j|jj|jtj |jj y)z C{stop()}ping a L{CooperativeTask} whose iterator has encountered an error should raise L{TaskFailed}. N)rrr#rr TaskFailedr;rs rtest_stopErroredzRunStateTests.test_stopErroreds9   $//499>>:rcgfd}jjj|jjj j jjdgy)a If a callback of a L{Deferred} from L{CooperativeTask.whenDone} calls C{Cooperator.stop} on its L{CooperativeTask._cooperator}, the L{Cooperator} will stop, but the L{CooperativeTask} whose callback is calling C{stop} should already be considered 'stopped' by the time the callback is running, and therefore removed from the L{CoooperativeTask}. c~j|jjjdy)Nr&)rrr;)r8callbackPhasesr s rstopitz;RunStateTests.test_stopCooperatorReentrancy..stopits1  ! !& ) OO "  ! !& )rr&N)rrr>rrr#r6r)r r'r&s` @rtest_stopCooperatorReentrancyz+RunStateTests.test_stopCooperatorReentrancysd * ((0   $))*=*=v)FGrN)rrrrrrrrrrrrrrr rrrrrrr r#r(rrrrreso  &*!   /, <),*0)&V S N 9 ( ((49;HrrN)rtwisted.internetrrr twisted.trialrrrTestCaser% Exceptionrrrrrrr-sr 21"&:F$h''F$R ""0MHH%%MHr