Ϫf4dZddlZddlZddlZddlmZddlmZddlm Z ddl m Z m Z ddl mZmZddlmZdd lmZdd lmZd ZGd d eZee GddZej5ej7y)z0 Tests for implementations of L{IReactorFDSet}. N)skipIf) implementer)FileDescriptor) IReactorFDSetIReadDescriptor) EINPROGRESS EWOULDBLOCK)ReactorBuilder)platform)SkipTestc tj}|jd|jd tj} |jd |j d|j df|j\}} |j||fS#t $r&}|jdttfvrYd}~Rd}~wwxYw#t$r|jwxYw#|jwxYw)N) 127.0.0.1rFrr) socketbindlisten setblockingconnect getsocknameOSErrorargsrr accept BaseExceptionclose) serverSocketclienteserveraddrs B/usr/lib/python3/dist-packages/twisted/internet/test/test_fdset.py socketpairr!s==?L&'    u %  \-E-E-G-JKL(..0LFD  6> 66!9[+$>>?   LLN   sGC; C$B+C+ C4CCCCC88C;;D ceZdZdZegZdZdZdZdZ dZ dZ dZ d Z d Zd Zd Zd Zeej(ddZdZy)ReactorFDSetTestsBuilderz> Builder defining tests relating to L{IReactorFDSet}. ct\}}|j|j|j|j||fS)zL Return the two sockets which make up a new TCP connection. )r! addCleanuprselfrrs r _connectedPairz'ReactorFDSetTestsBuilder._connectedPair8s9$  %  %v~c|j}|j\}}t|}|j|_|||fSN) buildReactorr(rfileno)r'reactorrrfds r _simpleSetupz%ReactorFDSetTestsBuilder._simpleSetupAsD##%,,. G $MM F""r)c|j\}fd}|_j|jd|j y)z C{reactor.addReader()} accepts an L{IReadDescriptor} provider and calls its C{doRead} method when there may be data available on its C{fileno}. cHjjyr+) removeReaderstopr/r.sr removeAndStopz>ReactorFDSetTestsBuilder.test_addReader..removeAndStopR   $ LLNr)xN)r0doRead addReadersendall runReactorr'rr6r/r.s @@r test_addReaderz'ReactorFDSetTestsBuilder.test_addReaderKsP #//1V " "t  r)cj\}}}fd}||_|j||j||j d|j d|j d|j j|y)z L{reactor.removeReader()} accepts an L{IReadDescriptor} provider previously passed to C{reactor.addReader()} and causes it to no longer be monitored for input events. c(jdyNzdoRead should not be calledfailr'sr rCz8ReactorFDSetTestsBuilder.test_removeReader..failfs II3 4r)r8rN)r0r9r:r3r; callLaterr4r<r'r.r/rrCs` r test_removeReaderz*ReactorFDSetTestsBuilder.test_removeReader^s| #//1V 5 "R t !W..7<<@  r)c|j\}fd}|_j|jy)z C{reactor.addWriter()} accepts an L{IWriteDescriptor} provider and calls its C{doWrite} method when it may be possible to write to its C{fileno}. cHjjyr+) removeWriterr4r5sr r6z>ReactorFDSetTestsBuilder.test_addWriter..removeAndStop~r7r)N)r0doWrite addWriterr<r=s @@r test_addWriterz'ReactorFDSetTestsBuilder.test_addWritervsB #//1V # "  r)c|j}t|d|zdz}t|d|z}t|d|z}|j\}}|j|||j|||||j |||j|||||j|||j||y)z= Helper for getReaders and getWriters tests. getsaddremoveN)r,getattrr( assertNotInassertIn)r'kindr.rOrQrRrrs r _getFDTestz#ReactorFDSetTestsBuilder._getFDTests##%gut|c12gut|,(T/2,,. ' ' F  fce$ 'v ' 'r)c&|jdy)z L{IReactorFDSet.getReaders} reflects the additions and removals made with L{IReactorFDSet.addReader} and L{IReactorFDSet.removeReader}. ReaderNrWrDs r test_getReadersz(ReactorFDSetTestsBuilder.test_getReaders !r)cj\}}}fd}||_|j||j||j d|jd|j j |y)z L{reactor.removeWriter()} accepts an L{IWriteDescriptor} provider previously passed to C{reactor.addWriter()} and causes it to no longer be monitored for outputability. c(jdyNzdoWrite should not be calledrBrDsr rCz8ReactorFDSetTestsBuilder.test_removeWriter..fails II4 5r)rN)r0rKrLrJrEr4r<rFs` r test_removeWriterz*ReactorFDSetTestsBuilder.test_removeWritersp #//1V 6 "R  !W..7<<@  r)c&|jdy)z L{IReactorFDSet.getWriters} reflects the additions and removals made with L{IReactorFDSet.addWriter} and L{IReactorFDSet.removeWriter}. WriterNrZrDs r test_getWritersz(ReactorFDSetTestsBuilder.test_getWritersr\r)cj}j\}}}fd|_fd|_|j d|j ||j ||j}|jd|jd|jj|j||gy)z C{reactor.removeAll()} removes all registered L{IReadDescriptor} providers and all registered L{IWriteDescriptor} providers and returns them. c&jdSrArBrDsr z9ReactorFDSetTestsBuilder.test_removeAll..sDII&CDr)c&jdSr_rBrDsr rfz9ReactorFDSetTestsBuilder.test_removeAll..sTYY'EFr)r8rN) r,r0r9rKr;r:rL removeAllrEr4r< assertEqual)r'r.r/rremoveds` r test_removeAllz'ReactorFDSetTestsBuilder.test_removeAlls ##%"//1VD F t""##% !W..7<<@   2$'r)c|j}t|}|j|j|j ||j |j gy)z A descriptor's C{fileno} method should not be called after the descriptor has been removed from the reactor. N)r,RemovingDescriptorcallWhenRunningstartr<ricalls)r'r. descriptors r test_removedFromReactorz0ReactorFDSetTestsBuilder.test_removedFromReactorsR ##%'0  0 01   ))2.r)c$|j|j\Gfddt}|}j|j d|j |j |jdy)zp If L{FileDescriptor.fileno} returns C{-1}, the descriptor is removed from the reactor. cPeZdZWjZdZdZfdZfdZy)WReactorFDSetTestsBuilder.test_negativeOneFileDescriptor..DisappearingDescriptorr)c|jSr+)_filenorDs r r-z^ReactorFDSetTestsBuilder.test_negativeOneFileDescriptor..DisappearingDescriptor.filenos ||#r)c~d|_|xjjdz c_jdy)Nry)rw _receivedrecvsendr&s r r9z^ReactorFDSetTestsBuilder.test_negativeOneFileDescriptor..DisappearingDescriptor.doReads,! &++a.0 D!r)c&jyr+r4r'reasonr.s r connectionLostzfReactorFDSetTestsBuilder.test_negativeOneFileDescriptor..DisappearingDescriptor.connectionLosts  r)N)__name__ __module__ __qualname__r-rwr{r9r)rr.rsr DisappearingDescriptorrus"mmoGI $ "  r)rr8N)r,r(rr:r}r<rir{)r'rrqrr.rs @@@r test_negativeOneFileDescriptorz7ReactorFDSetTestsBuilder.test_negativeOneFileDescriptors~ ##%,,.  ^  ,G4 *% D   --t4r)z*Cannot duplicate socket filenos on Windowscjjj}|dvrt|dj \}Gfddt }j |fd}jd|jjtjy)a The file descriptor underlying a FileDescriptor may be closed and replaced by another at some point. Bytes which arrive on the new descriptor must not be delivered to the FileDescriptor which was originally registered with the original descriptor of the same number. Practically speaking, this is difficult or impossible to detect. The implementation relies on C{fileno} raising an exception if the original descriptor has gone away. If C{fileno} continues to return the original file descriptor value, the reactor may deliver events from that descriptor. This is a best effort attempt to ease certain debugging situations. Applications should not rely on it intentionally. ) EPollReactor KQueueReactor CFReactorAsyncioSelectorReactorz$ cannot detect lost file descriptorsc,eZdZdZfdZdZfdZy)@ReactorFDSetTestsBuilder.test_lostFileDescriptor..Victima This L{FileDescriptor} will have its socket closed out from under it and another socket will take its place. It will raise a socket.error from C{fileno} after this happens (because socket objects remember whether they have been closed), so as long as the reactor calls the C{fileno} method the problem will be detected. c$jSr+)r-)r'rs r r-zGReactorFDSetTestsBuilder.test_lostFileDescriptor..Victim.fileno3s}}&r)ctd)Nz$Victim.doRead should never be called) ExceptionrDs r r9zGReactorFDSetTestsBuilder.test_lostFileDescriptor..Victim.doRead6s FGGr)c&jy)z When the problem is detected, the reactor should disconnect this file descriptor. When that happens, stop the reactor so the test ends. Nrrs r rzOReactorFDSetTestsBuilder.test_lostFileDescriptor..Victim.connectionLost9s  r)N)rrr__doc__r-r9r)r.rsr Victimr*s  ' H r)rcj\}}j}jtj|j||j dy)Nr8)r(r-rosdup2r})newCnewSr-r'rs r messItUpzBReactorFDSetTestsBuilder.test_lostFileDescriptor..messItUpHsH,,.JD$]]_F LLN GGDKKM6 * IIdOr)rN) r, __class__rr r(rr:rEr<flushLoggedErrorsrerror)r'namerrrr.rs` @@r test_lostFileDescriptorz0ReactorFDSetTestsBuilder.test_lostFileDescriptor s##%  ))   dX%IJK K,,. ^ . &(#  !X&   v||,r)c|j}Gddt}|j\}}||}|j|_||}|j|_|j ||j ||j |j|j||j|j|j|jy)z Any file descriptors added to the reactor have their C{connectionLost} called when C{reactor.stop} is called. ceZdZdZdZy)SReactorFDSetTestsBuilder.test_connectionLostOnShutdown..DoNothingDescriptorcyr+rDs r r9zZReactorFDSetTestsBuilder.test_connectionLostOnShutdown..DoNothingDescriptor.doRead_r)cyr+rrDs r rKz[ReactorFDSetTestsBuilder.test_connectionLostOnShutdown..DoNothingDescriptor.doWritebrr)N)rrrr9rKrr)r DoNothingDescriptorr^s   r)rN) r,rr(r-r:rLrnr4r< assertTrue disconnected)r'r.rrrfd1fd2s r test_connectionLostOnShutdownz6ReactorFDSetTestsBuilder.test_connectionLostOnShutdownWs ##% . ,,.!'*]] !'*]] ## -   (() (()r)N)rrrrrrequiredInterfacesr(r0r>rGrMrWr[r`rcrkrrrrr isWindowsrrrr)r r#r#1s~(#!&!0!$(,"!."(: /5> H   "NOJ-PJ-X*r)r#c4eZdZdZdZdZdZdZdZdZ y) rma A read descriptor which removes itself from the reactor as soon as it gets a chance to do a read and keeps track of when its own C{fileno} method is called. @ivar insideReactor: A flag which is true as long as the reactor has this descriptor as a reader. @ivar calls: A list of the bottom of the call stack for any call to C{fileno} when C{insideReactor} is false. c\||_d|_g|_t\|_|_yNF)r. insideReactorrpr!readwrite)r'r.s r __init__zRemovingDescriptor.__init__s( " *  4:r)c~d|_|jj||jj dy)NTa)rr.r:rr}rDs r rozRemovingDescriptor.starts,! t$ r)cy)NfoorrDs r logPrefixzRemovingDescriptor.logPrefixsr)c|jj|d|_|jj|jj |j j yr)r.r3rr4rrrrDs r r9zRemovingDescriptor.doReadsJ !!$'"   r)c|js2|jjtjddd|j j S)N)limitry)rrpappend traceback extract_stackrr-rDs r r-zRemovingDescriptor.filenosB!! JJ  i55A>sC Dyy!!r)cyr+r)r'rs r rz!RemovingDescriptor.connectionLosts r)N) rrrrrrorr9r-rrr)r rmrmts% -  "  r)rm)rrrrunittestrzope.interfacertwisted.internet.abstractrtwisted.internet.interfacesrrtwisted.internet.tcprr #twisted.internet.test.reactormixinsr twisted.python.runtimer twisted.trial.unittestr r!r#rmglobalsupdatemakeTestCaseClassesrr)r rs~ &4F:>++.@*~@*F  _+ + + \ )==?@r)