ϪfqdZddlmZddlZddlZddlZddlZddlZddlZddl m Z m Z ddl m Z mZddlmZddl mZddlmZmZmZmZmZdd lmZdd lmZmZdd lmZdd l m!Z!Gd de"Z#Gdde!jHZ%Gdde!jHZ&Gddee'Z(e jRe(GddZ*GddZ+Gdde*e+Z,GddeZ-GddZ.Gdd e.e!jHZ/Gd!d"e.e!jHZ0Gd#d$e!jHZ1Gd%d&e!jHZ2Gd'd(e!jHZ3Gd)d*e!jHZ4y)+z" Tests for L{twisted.python.log}. ) annotationsN)IOBaseStringIO)CallableList) implementer)Protocol) ILogObserver LogBeginner LoggingFileLogLevel LogPublisher)handlerAndBytesIO)failurelog)r)unittestceZdZdZy) FakeWarningz A unique L{Warning} subclass used by tests for interactions of L{twisted.python.log} with the L{warnings} module. N)__name__ __module__ __qualname____doc__7/usr/lib/python3/dist-packages/twisted/test/test_log.pyrr#srrc@eZdZdZd dZd dZd dZd dZd dZd dZ y) TextFromEventDictTestsz) Tests for L{textFromEventDict}. cjtd}tj|}|j|dy)zj The C{"message"} value, when specified, is concatenated to generate the message. )abc)messageza b cNdictrtextFromEventDict assertEqualself eventDicttexts r test_messagez#TextFromEventDictTests.test_message/s. 1 $$Y/ w'rcptdddd}tj|}|j|dy)zW The C{"format"} value, when specified, is used to format the message. rrzHello, %(foo)s!dude)r"isErrorformatfooz Hello, dude!Nr#r's r test_formatz"TextFromEventDictTests.test_format8s5Q7HfU $$Y/ ~.rcjtdd}tj|}|j|y)zb If C{"format"} is unspecified and C{"message"} is empty, return L{None}. rrr"r.N)r$rr% assertIsNoner's rtest_noMessageNoFormatz-TextFromEventDictTests.test_noMessageNoFormat@s. Q/ $$Y/ $rc t#t$r]tddtjd}t j |}|J|j|jdYywxYw)zO The C{"why"} value, when specified, is first part of message. rr0)r"r.rwhyNzfoo RuntimeError BaseExceptionr$rFailurerr% assertTrue startswithr's rtest_whySpecifiedz(TextFromEventDictTests.test_whySpecifiedIsk 6.  6Aw/@eI((3D# ## OODOOG4 5  6s A#A21A2c t#t$r\tddtj}t j |}|J|j|jdYywxYw)zY The C{"why"} value, when unspecified, defaults to C{"Unhandled Error"}. rr7r"r.rNzUnhandled Error r9r's rtest_whyDefaultz&TextFromEventDictTests.test_whyDefaultWsh B.  BRGOOrrcTeZdZd dZd dZd dZd dZd dZd dZd dZ d dZ d d Z y ) LogTestscg|_|jj|_tj|j|j tj |jyN)catcherappendobserverr addObserver addCleanupremoveObserverr(s rsetUpzLogTests.setUposB,.  ++   & **DMM:rc|j}tjdd|j}|j |ddd|j |d|j d||j t|dy)NtestT)testShouldCatchr"rrXtime)rNrmsgpopr&r=rElenr(rNis rtestObservationzLogTests.testObservationusp,, - KKM 9a&1 +,- fa  Wq)rcd|j}tjddddtjdditjdd |j }|j |dd|j |d d|j |d d|j |d d dy)Nznot the defaultrr!) subsystem subsubsystemotherrbr r0d)rcrarcr"r)rNrcallWithContextrZr[r&r]s r testContextzLogTests.testContext~s,, +S3 O    S ! GG    KKM >*C0 ;):; 7S) 9a%0rc&dttftjttffD]Z\}}t j ||j j}|j|dd|j|\y)N hello worldrir.r7 KeyErrorrr<r:rerrrNr[r&flushLoggedErrorsr(eigr^s r testErrorszLogTests.testErrorssx * Z " __\^ ,l ;  'EAr GGAJ   "A   Qy\1 -  " "2 & 'rcRdttftjttffD]p\}}t j |d|j j}|j|dd|j|dd|j|ry)Nrhfoobarr.r7r8rjrns rtestErrorsWithWhyzLogTests.testErrorsWithWhys * Z " __\^ ,l ; 'EAr GGAx    "A   Qy\1 -   QuXx 0  " "2 & 'rcfg}g}d d}|j||jfD]7}tj||jtj|9t dD]}g|ddg|ddtj dg|jt}|jdd=|jt|d|jt|d|jt|d|j|dd d |j|dd d y) a Exceptions raised by log observers are logged but the observer which raised the exception remains registered with the publisher. These exceptions do not prevent the event from being sent to other observers registered with the publisher. cddzyNr7rr)events rbrokenz-LogTests.test_erroneousErrors..brokens FrN Howdy, y'all.) log_tracer7rr")r{rx log.EventDictrHrI) rOrrQrRrSrangerZrmZeroDivisionErrorrNr&r\)r(L1L2ryrPr^excss rtest_erroneousErrorszLogTests.test_erroneousErrorss#%"$ FBII6 :H OOH % OOC.. 9 :q CABqEBqE GGOr 2))*;.logErrors+}}Y' i 2889(rctd)N*test_publisherLocalyReportsBrokenObservers)r:r)s rfailzDLogTests.test_publisherReportsBrokenObserversPrivately..failsKL LrHello!r7rNr)rrHrI) rrrQrZr&set observersr\assertIsInstancer:)r(rrrrs @r-test_publisherReportsBrokenObserversPrivatelyz6LogTests.test_publisherReportsBrokenObserversPrivatelys  : M$$& h'd# h Y001Hd3CD Va( fQi6rNrG) rrrrUr_rfrqrtrrrrrrrrKrKns2; *1 ' '%CN&+P <7rrKceZdZddZddZy)FakeFilec&|j|yrMrO)r(bytess rwritezFakeFile.write+s ErcyrMrrTs rflushzFakeFile.flush.s rN)rrrHrIrG)rrrrrrrrrr*s  rrceZdZddZy)EvilStrctddzSrwstrrTs r__str__zEvilStr.__str__616{rNrHr)rrrrrrrrr5srrceZdZddZddZy)EvilReprcy)NzHappy Evil ReprrrTs rrzEvilRepr.__str__;s rctddzSrwrrTs r__repr__zEvilRepr.__repr__>rrNr)rrrrrrrrrr:s !rrc eZdZy) EvilReprStrN)rrrrrrrrBsrrc0eZdZUded< ddZy)_LogPublisherTestCaseMixinBaseroutcyrMr)r(instance classOrTupler"s rrz/_LogPublisherTestCaseMixinBase.assertIsInstanceIs rN)rrDrtyper"rrHrI)rrr__annotations__rrrrrrFs, M  .2 =@  rrceZdZddZddZy)LogPublisherTestCaseMixinct|_tj|_tj |j|_|jj|j jy)z Add a log observer which records log events in C{self.out}. Also, make sure the default string encoding is ASCII so that L{testSingleUnicode} can test the behavior of logging unencodable unicode messages. N) rrrrlpFileLogObserverflorQemitrTs rrUzLogPublisherTestCaseMixin.setUpPsM:""$&&txx0 DHHMM*rcZ|jD]}|j|t|dy)z Verify that everything written to the fake file C{self.out} was a C{str}. Also, restore the default string encoding to its previous setting, if it was modified by L{setUp}. z was not a stringN)rrr)r(chunks rtearDownz"LogPublisherTestCaseMixin.tearDown\s3 XX ME  ! !% 9J.K L MrNrG)r(rrHrI)rrrrUrrrrrrOs  +Mrrc$eZdZddZddZddZy)LogPublisherTestsc|jjd|jt|jdy)N Hello, world.r7rrZr&r\rrTs rtestSingleStringz"LogPublisherTests.testSingleStringgs*  O$ TXX*rc|jjdd|jt|jdy)NzHello, zworld.r7rrTs rtestMultipleStringz$LogPublisherTests.testMultipleStringks.  Ix( TXX*rcd}|jj||jt|jd|j ||jdy)z L{log.LogPublisher.msg} does not accept non-ASCII Unicode on Python 2, logging an error instead. On Python 3, where Unicode is default message type, the message is logged normally. Hello, ½ world.r7rN)rrZr&r\rrE)r(r"s rtest_singleUnicodez$LogPublisherTests.test_singleUnicodersG?  G TXX* gtxx{+rNrG)rrrrrrrrrrrfs++ ,rrceZdZdZdZdZdZdZdZdZ dZ d d Z d!d Z d!d Z d!d Zd!d Zd!dZd!dZd!dZd!dZd!dZd!dZd!dZd!dZd!dZd!dZd!dZd!dZd!dZd!dZd!dZd!dZd!dZ y)"FileObserverTestsz( Tests for L{log.FileObserver}. zInvalid format stringzUNFORMATTABLE OBJECTz>$5* %BJJt  JJL"B {{#56H"C  ;;'9:   HH..x8HH..x8 0   'JJt$#3 4 JJL1! "^3'H ( 'JJt$#3 4 JJLs2AD: D"AD:"D74D:6D77D::=E7c*|jdddy)a! Attempt to verify that L{FileLogObserver.getTimezoneOffset} returns correct values for the current C{TZ} environment setting for at least some cases. This test method exercises a timezone that is west of UTC (and should produce positive results). zAmerica/New_Yorki@8PFNrrTs rtest_getTimezoneOffsetWestOfUTCz1FileObserverTests.test_getTimezoneOffsetWestOfUTCs ##$6uErc*|jdddy)a! Attempt to verify that L{FileLogObserver.getTimezoneOffset} returns correct values for the current C{TZ} environment setting for at least some cases. This test method exercises a timezone that is east of UTC (and should produce negative results). z Europe/BerlinNrrTs rtest_getTimezoneOffsetEastOfUTCz1FileObserverTests.test_getTimezoneOffsetEastOfUTCs ##OUEBrc*|jdddy)af Attempt to verify that L{FileLogObserver.getTimezoneOffset} returns correct values for the current C{TZ} environment setting for at least some cases. This test method exercises a timezone that does not use daylight saving time at all (so both summer and winter time test values should have the same offset). zAfrica/JohannesburgrNrrTs r/test_getTimezoneOffsetWithoutDaylightSavingTimezAFileObserverTests.test_getTimezoneOffsetWithoutDaylightSavingTimes ##$95%Hrctjd}d|j_|j |jj |dd|j_|j |jj |dd|j_|j |jj |dd|j_|j |jj |d d |j_|j |jj |d d |j_|j |jj |d d|j_|j |jj |dd|j_|j |jj |dy)zu Test the method of L{FileLogObserver} which turns a timestamp into a human-readable string. ) ir}rzrrrcy)Nrrwhens rz7FileObserverTests.test_timeFormatting..rz2001-02-02 23:05:06-0500cy)Nrrrs rrz7FileObserverTests.test_timeFormatting..r rz2001-02-03 05:05:06+0100cy)NiPerrs rrz7FileObserverTests.test_timeFormatting..r rz2001-02-03 15:05:06+1100cy)Nirrs rrz7FileObserverTests.test_timeFormatting..r rz2001-02-03 02:35:06-0130cy)Nirrs rrz7FileObserverTests.test_timeFormatting.. r rz2001-02-03 05:35:06+0130cy)Nirrs rrz7FileObserverTests.test_timeFormatting..r rz2001-02-03 03:35:06-0030cy)Nirrs rrz7FileObserverTests.test_timeFormatting..r rz2001-02-03 04:35:06+0030z%Y %mz2001 02N)calendartimegmrrr& formatTime timeFormat)r(rs rtest_timeFormattingz%FileObserverTests.test_timeFormattings =>&8" ,,T24NO&8" ,,T24NO&9" ,,T24NO&7" ,,T24NO&8" ,,T24NO&7" ,,T24NO&8" ,,T24NO & ,,T2I>rc|d|j_|jd|jjdy)z L{FileLogObserver.formatTime} supports a value of C{timeFormat} which includes C{"%f"}, a L{datetime}-only format specifier for microseconds. z%f600000gm@N)rrr&rrTs r#test_microsecondTimestampFormattingz5FileObserverTests.test_microsecondTimestampFormattings/ # 488#6#6x#@Arc|jjt|jt |j d|j |j|j dyrw)rrZrr&r\r assertNotInERROR_UNFORMATTABLE_OBJECTrTs r%test_loggingAnObjectWithBroken__str__z7FileObserverTests.test_loggingAnObjectWithBroken__str__'sJ  GI TXX* 88$((1+Frc|jjdt|jt |j d|j |j|j dyNz%(blat)sr/blatr7r)rrZrr&r\rrEERROR_INVALID_FORMATrTs r(test_formattingAnObjectWithBroken__str__z:FileObserverTests.test_formattingAnObjectWithBroken__str__.sL  :GI 6 TXX* d//!=rc|jjdt|jt |j d|j |j|j dyNhuh)systemr7r)rrZrr&r\rrE ERROR_FORMATrTs rtest_brokenSystem__str__z*FileObserverTests.test_brokenSystem__str__3sL  E') , TXX* d''!5rc|jjdtg|jt |j d|j |j|j dyrrrZrr&r\rrErrTs r1test_formattingAnObjectWithBroken__repr__IndirectzCFileObserverTests.test_formattingAnObjectWithBroken__repr__Indirect8sN  :XZL 9 TXX* d55txx{Crc|jjdtg|jt |j d|j |j|j dyr#r)rTs r%test_systemWithBroker__repr__Indirectz7FileObserverTests.test_systemWithBroker__repr__Indirect=sN  E8:, / TXX* d55txx{Crc|jjdd|jt|jd|j |j |jdy)Nz hooj %s %sr7rrrrZr&r\rrEr rTs rtest_simpleBrokenFormatz)FileObserverTests.test_simpleBrokenFormatBsJ  .observejs OOE "rrrrr.r7Nr~) r@rr startLoggingrQprintr?r;r&)r(fakeFilerDrCs @rtest_printToStderrSetsIsErrorz/FileObserverTests.test_printToStderrSetsIsErrorase !!#: " #)+   oCJJ/ !Y/3rcVtjtj}}|jt }t j |}|j|jt jd|jd|j|jtjt|jtjjt j"t%|dd}|stj&}|jtjj(j+|j+|jtjt|jtjjt j,t%|dd}|stj&}|jtjj(j+|j+y)zj startLogging() installs FileLogObserver and overrides sys.stdout and sys.stderr. rencodingN)r?r:r;r@rrrErRstoprZrErrr r&level NewLogLevelinforgetdefaultencodingrJuppererror)r( origStdout origStderrrGrPrJs rtest_startLoggingz#FileObserverTests.test_startLoggingsse "%SZZJ  !!#:##H-  &  h 1 1 34 cjj+6 ));+;+;<:z48--/H ,,224hnn6FG cjj+6 ));+<+<=:z48--/H ,,224hnn6FGrc&|jtt_dd}t j ||j tj|t jtj}|j |j|jtjttj}t jtj}|jtj|y)z There are some obscure error conditions that can occur when logging is started twice. See http://twistedmatrix.com/trac/ticket/3289 for more information. cp|dr1tjj|djyyr)r? __stdout__r getTracebackrs r showErrorz;FileObserverTests.test_startLoggingTwice..showErrors/#$$Yy%9%F%F%HI$rNr) r@rr?r:rrQrRrSrErKrr assertIs)r(rYrP fakeStdouts rtest_startLoggingTwicez(FileObserverTests.test_startLoggingTwices !!#Z  J  " **I6##CJJ/  & cjj+6ZZ ##CJJ/ cjj*-rc l|jt}Gdd}t||t|t |t }|j td|dt_t }ddi}gttGfdd }|||j|tj|d |j|j|jgt j d |j#}|j%d |y)z startLogging() overrides global C{warnings.showwarning} such that warnings go to Twisted log observers. c(eZdZeZeZy)FFileObserverTests.test_startLoggingOverridesWarning..SysModuleN)rrrrDr:r;rrr SysModuler_sXFXFrr`) logBeginnerr<N pre-startrxceZdZdfd Zy)MFileObserverTests.test_startLoggingOverridesWarning..PreStartObservercNd|jvrj|yy)Nrb)keysrO)r(r)receiveds r__call__zVFileObserverTests.test_startLoggingOverridesWarning..PreStartObserver.__call__s#).."22OOI.3rNr)rrrrh)rgsrPreStartObserverrds /rriF) setStdoutzhello!zUserWarning: hello!)r@NewLogPublisherrr rrpatchr_oldshowwarningrr rQrErRr=r&warnrrE) r( newPublisherr`tempLogPublisherrGevtrirrgs @r!test_startLoggingOverridesWarningz3FileObserverTests.test_startLoggingOverridesWarnings !!#&(   (  #L(*iR  3)+;<#:G$ \ " / / # / S  !1!34 U3 (556 2& h""$ +V4rct}tj|gd fd }tj}|j ||j d|j tdd}|j}djj|d|d}|j|j||d |y ) zk FileLogObserver.emit() will add a timestamp and system prefix to its file output. cJj|j|yrM)rOr)rxeventsrs rrPz3FileObserverTests.test_emitPrefix..observers MM% HHUOrrr7rz{time} [{system}] rYr%)rYr%z does not start with Nr~) rrrrrQrZr&r\rr/rr=r>) r(rrPrrxresultprefixrurs @@rtest_emitPrefixz!FileObserverTests.test_emitPrefixs !!&)  $$& h' h Va(q "%,,f .?-     f %j-fZ 8 rc2t}tj|}tj}|j |j |j d|j}d}|j|j||d|y)zR FileLogObserver.emit() will append a newline to its file output. rzHello! z does not end with N) rrrrrQrrZrr=endswith)r(rrrrvsuffixs rtest_emitNewlinez"FileObserverTests.test_emitNewlines!!&)$$& chh' h"  OOF #j+F: 6 rN)rrrintrr}rHrIrG)!rrrrr rr&r4ERROR_NO_FORMATERROR_UNFORMATTABLE_SYSTEMERROR_MESSAGE_LOSTrrrrrrrr!r'r*r,r/r2r5r8r@rHrTr\rrrxr|rrrrrs3!7QL-.O!2DDD+.D@CD DLFC I)?VBG> 6 D D > > < +<4$H4.435j @ rrc@eZdZdZd dZd dZd dZd dZd dZd dZ y) PythonLoggingObserverTestsz5 Test the bridge with python logging module. ctjdjjtjj dfd }t \__jjj dfd }tj_ tj_jjjj y)Nr7c(jyrM)setLevel) originalLevel rootLoggersr restoreLevelz6PythonLoggingObserverTests.setUp..restoreLevels    .rcpjjjjyrM) removeHandlerhdlrclose)rr(sr removeLoggerz6PythonLoggingObserverTests.setUp..removeLogger"s#  $ $TYY / IIOO rrG)logging getLoggergetEffectiveLevelrDEBUGrRrrr addHandlerrrrPythonLoggingObserverobsrQr)r(rrrrs` @@rrUz PythonLoggingObserverTests.setUps&&r* "446 GMM*  /  /01 48dii(    ""$,,. DHHMM*rc|jjd|jd|jj |jd|jj y)z< Test simple output, and default log level. rs Hello, world.sINFONrrZrErrrTs rtest_singleStringz,PythonLoggingObserverTests.test_singleString+sK  O$ &(9(9(;< gtxx0023rctjtd}|jj |dd}|j j }|j|j|d|d|y)z$ Test error output. z That is bad.T)rr.s CRITICAL:zDoes not start with z: N) rr< ValueErrorrrZrrr=r>)r(frwrs rtest_errorStringz+PythonLoggingObserverTests.test_errorString3sl OOJ~6 7  At ,""$    f %"6*Bvj 9 rc|jjddd|jd|jj y)z- Test logging with a format. z%(bar)s oo %(foo)sHelloworld)r/barr0sHello oo worldNrrTs rtest_formatStringz,PythonLoggingObserverTests.test_formatString@s7  /W' J '):):)<=rcl|jjdtj|j d|j j |j d|j j |j jdd|j j|jjdtj|j d|j j |j d|j j y ) zG Test the logLevel keyword for customizing level used. z Spam egg.)logLevels Spam egg.sERRORrzFoo bar.sFoo bar.sWARNINGN) rrZrERRORrErrseektruncateWARNINGrTs rtest_customLevelz+PythonLoggingObserverTests.test_customLevelGs  K'-- 8 lDHH$5$5$78 h 1 1 34  a   J 9 k488#4#4#67 j$(("3"3"56rc|jjdd|j|jj dy)zx Verify that an event dictionary which is not an error and has an empty message isn't recorded. r7Fr3rN)rrZr&rrrTs rr8z0PythonLoggingObserverTests.test_strangeEventDictTs5  B . **,c2rNrG) rrrrrUrrrrr8rrrrrs%+*4  > 73rrc eZdZdZddZddZy)PythonLoggingIntegrationTestsz4 Test integration of python logging bridge. ctj}tj}g} |jt_|jt_tj }|j |j|d|j|j|jt|d|t_|t_y#|t_|t_wxYw)z~ Test that start and stop methods of the observer actually register and unregister to the log system. rN) rrQrSrOremoverstartr&rrKr\)r(oldAddObserveroldRemoveObserverlrs rtest_startStopObserverz4PythonLoggingIntegrationTests.test_startStopObserverbs ..35 3hhCO!"C ++-C IIK   QqT388 , HHJ   SVQ ',CO!2C -CO!2C s BCC+cjGddtj}|}g}tjj} |jtj_|jddi|j |ddig|tj_y#|tj_wxYw)z Test that we can inherit L{log.PythonLoggingObserver} and use super: that's basically a validation that L{log.PythonLoggingObserver} is new-style class. c eZdZdfd ZxZS)BPythonLoggingIntegrationTests.test_inheritance..MyObserverc$t||yrM)superr)r(r) __class__s rrzGPythonLoggingIntegrationTests.test_inheritance..MyObserver.emit~s Y'rr)rrrr __classcell__)rs@r MyObserverr}s  ( (rrr0rN)rrrrOr&)r(rrroldEmits rtest_inheritancez.PythonLoggingIntegrationTests.test_inheritancevs (22 (l!#++00 5-.XXC % % * HHeU^ $   Q% 0 1-4C % % *WC % % *s ABB2NrG)rrrrrrrrrrr]s3(5rrc eZdZdZddZddZy)DefaultObserverTestsz$ Test the default observer. c`g|_|jj|_tj|j|j tj |jtj}t|_ |j|j |jd}tjt||j}|j||jj!|j#t%|dy)zu The reason argument passed to log.err() appears in the report generated by DefaultObserver. z The reason.r7N)rNrOrPrrQrRrSDefaultObserverrr;rrKrl ExceptionrmrErr&r\)r(rreasonrs rtest_failureLoggerz'DefaultObserverTests.test_failureLoggers -/  ++   & **DMM:!!#Z   !  V$'') fcjj1134 Va(rc6Gdd}d|f}t|d}tj}t5}||_|j ||j |jjddddy#1swYyxYw)z DefaultObserver.emit() does not raise when it observes an error event with a message that causes L{repr} to raise. ceZdZddZy)?DefaultObserverTests.test_emitEventWithBrokenRepr..Ouchctddz SrwrrTs rrzHDefaultObserverTests.test_emitEventWithBrokenRepr..Ouch.__repr__s1q5z!rNr)rrrrrrrOuchrs "rrr0r7r3zfoo )r(rr"rxrPrs rtest_emitEventWithBrokenReprz1DefaultObserverTests.test_emitEventWithBrokenReprs  " "$&/Wa0&&( Z P6$HO MM% OOFOO-889MN O P P Ps ABBNrG)rrrrrrrrrrrs),PrrcXeZdZdZd dZd dZd dZd dZd dZd dZ d dZ d d Z d d Z y )StdioOnnaStickTestszF StdioOnnaStick should act like the normal sys.stdout object. cdg|_tj|jjyrM) resultLogsrrQrOrTs rrUzStdioOnnaStickTests.setUps/1 ../rcVtj|jjyrM)rrSrrOrTs rrzStdioOnnaStickTests.tearDowns 4??112rcd|jDcgc]}dj|dc}Scc}w)Nr7r")rjoin)r(rds rgetLogMessagesz"StdioOnnaStickTests.getLogMessagess'/3?!) %???s-ctj}|jd|j|j dg|jd|j|j ddgy)z Writing to a StdioOnnaStick instance results in Twisted log messages. Log messages are generated every time a '\n' is encountered. zHello there This is a testz Hello therez! zThis is a test!N)rStdioOnnaStickrr&rr(stdios r test_writezStdioOnnaStickTests.test_writese ""$ 12 ,,.@ E ,,.@Q0RSrctj}|jd|j|jdd|j |jddy)z{ The log messages written by StdioOnnaStick have printed=1 keyword, and by default are not errors. zhello rr.printedN)rrr assertFalserr=rs r test_metadataz!StdioOnnaStickTests.test_metadatasT ""$ I +I67 *956rctj}|jddg|j|j ddgy)zT Writing lines to a StdioOnnaStick results in Twisted log messages. zlog 1zlog 2N)rr writelinesr&rrs rtest_writeLinesz#StdioOnnaStickTests.test_writeLinessC""$ '7+, ,,.'0BCrctj}tjt_|j t td|t ddt d|j|jdgy)zW When StdioOnnaStick is set as sys.stdout, prints become log messages. r:This )endz is a testzThis is a testN) r?r:rrrRr>rFr&r)r( oldStdouts r test_printzStdioOnnaStickTests.test_prints^JJ '')  h : f# k ,,.1A0BCrctjd}|jd|j|jddy)zR StdioOnnaStick created with isError=True log messages as errors. T)r.zlog 1 rr.N)rrrr=rrs r test_errorzStdioOnnaStickTests.test_errors:""40 I *956rcd}tjd}|j|jd|j |dz|j d|zgt j}|t _|jtt d|t||j|j|d|z|gy)z StdioOnnaStick converts unicode prints to byte strings on Python 2, in order to be compatible with the normal stdout/stderr objects. On Python 3, the prints are left unmodified. rzutf-8)rJ zAlso, r:N) rrr&rJrrr?r:rRr>rFr)r( unicodeStringrrs r test_unicodez StdioOnnaStickTests.test_unicodesE ""G4 1 MD() (]234JJ   h : m     ! H}4m D rNrG)rHz list[str]) rrrrrUrrrrrrrrrrrrrs803@ T7D D7 rr)5r __future__rrrrr?rYriorrtypingrrzope.interfacerr twisted.loggerr r r r rMrrktwisted.logger.test.test_stdlibrtwisted.pythonrrtwisted.python.log twisted.trialrWarningrSynchronousTestCaserrKrrregisterrrrrrrrrrrrrrrrsS# !&>'+"'A>X99A>Hy7x++y7x tE{   '8  X MM.,183O3O,4N 183O3ON b I3!=!=I3X,5H$@$@,5^,P877,P^T (66T r