o
    b1                     @   s   d Z ddlZddlmZmZmZmZmZmZm	Z	m
Z
 ddlmZ ddlmZ ddlmZ ddlmZmZ dd	lmZmZ dd
lmZ ddlmZ ddlmZ ddlmZ dejdee dee ddfddZ G dd dejZ!dS )z+
Test cases for L{twisted.logger._global}.
    N)IOAnyListOptionalTextIOTupleTypecast)Failure)unittest   )textFileLogObserver)MORE_THAN_ONCE_WARNINGLogBeginner)ILogObserverLogEvent)LogLevel)Logger)LogPublisher)nextLinetestactualEventsexpectedEventsreturnc                    st   t |t |kr| || t  |D ]
} t| O  qdtdtf fddfdd|D }| || dS )a7  
    Compare two sequences of log events, examining only the the keys which are
    present in both.

    @param test: a test case doing the comparison
    @param actualEvents: A list of log events that were emitted by a logger.
    @param expectedEvents: A list of log events that were expected by a test.
    eventr   c                    s,   |   }|  D ]}| vr|| q|S N)copykeyspop)r   r   key)allMergedKeys A/usr/lib/python3/dist-packages/twisted/logger/test/test_global.pysimplify*   s   
zcompareEvents.<locals>.simplifyc                    s   g | ]} |qS r!   r!   .0r   )r#   r!   r"   
<listcomp>1   s    z!compareEvents.<locals>.<listcomp>N)lenassertEqualsetr   r   )r   r   r   r   simplifiedActualr!   )r    r#   r"   compareEvents   s   r+   c                   @   s   e Zd ZdZd"ddZd"ddZd"dd	Zd
ededdfddZ	d"ddZ
d"ddZd"ddZd"ddZd"ddZd"ddZd"ddZd"ddZd"ddZd"d d!ZdS )#LogBeginnerTestsz#
    Tests for L{LogBeginner}.
    r   Nc                 C   sZ   t  | _t | _G dd d}G dd d}| | _| | _t| j| j| j| j| _d S )Nc                   @   s   e Zd Ze Ze ZdS )z&LogBeginnerTests.setUp.<locals>.NotSysN)__name__
__module____qualname__objectstdoutstderrr!   r!   r!   r"   NotSys>   s    
r3   c                   @   sR   e Zd ZdddZ		ddedee deded	ee	e
  d
ee ddfddZdS )z+LogBeginnerTests.setUp.<locals>.NotWarningsr   Nc                 S   s
   g | _ d S r   )warnings)selfr!   r!   r"   __init__C   s   z4LogBeginnerTests.setUp.<locals>.NotWarnings.__init__messagecategoryfilenamelinenofilelinec                 S   s   | j ||||||f dS )a  
                Emulate warnings.showwarning.

                @param message: A warning message to emit.
                @param category: A warning category to associate with
                    C{message}.
                @param filename: A file name for the source code file issuing
                    the warning.
                @param lineno: A line number in the source file where the
                    warning was issued.
                @param file: A file to write the warning message to.  If
                    L{None}, write to L{sys.stderr}.
                @param line: A line of source code to include with the warning
                    message. If L{None}, attempt to read the line from
                    C{filename} and C{lineno}.
                N)r4   append)r5   r7   r8   r9   r:   r;   r<   r!   r!   r"   showwarningJ   s   z7LogBeginnerTests.setUp.<locals>.NotWarnings.showwarningr   N)NN)r-   r.   r/   r6   strr   Warningintr   r   r   r>   r!   r!   r!   r"   NotWarningsB   s&    

rC   )	r   	publisherioStringIOerrorStream	sysModulewarningsModuler   beginner)r5   r3   rC   r!   r!   r"   setUp:   s   
#
zLogBeginnerTests.setUpc                    sr   t ddd}g  g tt fdd}ttfdd}| j||f | | | |g  | |g dS )z?
        Test that C{beginLoggingTo()} adds observers.
           r   foobarc                    
     | S r   r=   eevents1r!   r"   <lambda>t      
 zBLogBeginnerTests.test_beginLoggingToAddObservers.<locals>.<lambda>c                    rP   r   rQ   rR   events2r!   r"   rV   u   rW   N)dictr	   r   rJ   beginLoggingTorD   r(   r5   r   o1o2r!   rU   rY   r"   test_beginLoggingToAddObserversk   s   
z0LogBeginnerTests.test_beginLoggingToAddObserversc                    sr   t ddd}g  g tt fdd}ttfdd}| | | j||f | |g  | |g dS )z\
        Test that events are buffered until C{beginLoggingTo()} is
        called.
        rL   r   rM   c                    rP   r   rQ   rR   rT   r!   r"   rV      rW   zDLogBeginnerTests.test_beginLoggingToBufferedEvents.<locals>.<lambda>c                    rP   r   rQ   rR   rX   r!   r"   rV      rW   N)rZ   r	   r   rD   rJ   r[   r(   r\   r!   r_   r"   !test_beginLoggingToBufferedEvents}   s   
z2LogBeginnerTests.test_beginLoggingToBufferedEventslimitrJ   c                 C   sf   t |d D ]
}| t|d qg }|tt|jg | tt d|d tdd |D  dS )a  
        Verify that when more than C{limit} events are logged to L{LogBeginner},
        only the last C{limit} are replayed by L{LogBeginner.beginLoggingTo}.

        @param limit: The maximum number of events the log beginner should
            buffer.
        @param beginner: The L{LogBeginner} against which to verify.

        @raise: C{self.failureException} if the wrong events are replayed by
            C{beginner}.
        rL   )countc                 s   s    | ]}|d  V  qdS )rc   Nr!   r$   r!   r!   r"   	<genexpr>   s    z4LogBeginnerTests._bufferLimitTest.<locals>.<genexpr>N)	rangerD   rZ   r[   r	   r   r=   r(   list)r5   rb   rJ   rc   eventsr!   r!   r"   _bufferLimitTest   s   z!LogBeginnerTests._bufferLimitTestc                 C   s   t j}| || j dS )z
        Up to C{LogBeginner._DEFAULT_BUFFER_SIZE} log events are buffered for
        replay by L{LogBeginner.beginLoggingTo}.
        N)r   _DEFAULT_BUFFER_SIZErh   rJ   )r5   rb   r!   r!   r"   test_defaultBufferLimit   s   z(LogBeginnerTests.test_defaultBufferLimitc                 C   s.   d}t | j| j| j| j|d}| || dS )z
        The size of the L{LogBeginner} event buffer can be overridden with the
        C{initialBufferSize} initilizer argument.
           )initialBufferSizeN)r   rD   rG   rH   rI   rh   )r5   rb   rJ   r!   r!   r"   test_overrideBufferLimit   s   z)LogBeginnerTests.test_overrideBufferLimitc              	   C   s$  g }g }t  }t|}| tdd t \}}| jtt	|j
|g | tdd t \}}| jtt	|j
|g | tdd tttj||||d}	d| _t| |tddtdd|	tddg t| ||	tddg | }
| d| d| d	|
 | d| d| d	|
 dS )
z
        When invoked twice, L{LogBeginner.beginLoggingTo} will emit a log
        message warning the user that they previously began logging, and add
        the new log observers.
        	prebuffer)r   
postbufferpostwarn)
log_format	log_levelfileNowlineNowfileThenlineThenN<:>)rE   rF   r   rD   rZ   r   rJ   r[   r	   r   r=   r   r   warnmaxDiffr+   getvalueassertIn)r5   rU   rY   
fileHandletextObserverfirstFilename	firstLinesecondFilename
secondLinewarningoutputr!   r!   r"   test_beginLoggingToTwice   sB   

	
z)LogBeginnerTests.test_beginLoggingToTwicec                 C   s:   t | jd}|d |jddd | | j d dS )zP
        Critical messages will be written as text to the error stream.
        observerzignore thisza critical {message}r7   )r7   za critical message
N)r   rD   infocriticalr(   rG   r|   r5   logr!   r!   r"   test_criticalLogging   s   
z%LogBeginnerTests.test_criticalLoggingc                 C   s8   t | jd}| jd |d | | j d dS )z
        Once logging has begun with C{beginLoggingTo}, critical messages are no
        longer written to the output stream.
        r   r!   zanother critical message N)r   rD   rJ   r[   r   r(   rG   r|   r   r!   r!   r"   test_criticalLoggingStops   s   
z*LogBeginnerTests.test_criticalLoggingStopsc                 C   s   g }| j tt|jg tdtt| jjd t	| |t
dddg |dd= tdtt| jjd t	| |t
dddg dS )z
        L{LogBeginner.beginLoggingTo} will re-direct the standard output and
        error streams by setting the C{stdio} and C{stderr} attributes on its
        sys module object.
        zHello, world.r;   r1   )log_namespacelog_ioNzError, world.r2   )rJ   r[   r	   r   r=   printr   rH   r1   r+   rZ   r2   )r5   rg   r!   r!   r"   %test_beginLoggingToRedirectStandardIO   s   
z6LogBeginnerTests.test_beginLoggingToRedirectStandardIOc                 C   sD   | j j}| j j}| jjddd | | j j| | | j j| dS )z
        L{LogBeginner.beginLoggingTo} will leave the existing stdout/stderr in
        place if it has been told not to replace them.
        r!   F)redirectStandardION)rH   r1   r2   rJ   r[   assertIs)r5   oldOutoldErrr!   r!   r"   test_beginLoggingToDontRedirect  s
   z0LogBeginnerTests.test_beginLoggingToDontRedirectc                 C   s   t t  d}t t  d}|| j_|| j_g }| jtt	|j
g tt| jj}tt| jj}| |jd | |jd |d |d t| |tddtddg dS )	z
        When L{LogBeginner.beginLoggingTo} redirects stdout/stderr streams, the
        replacement streams will preserve the encoding of the replaced streams,
        to minimally disrupt any application relying on a specific encoding.
        z	shift-JISbig5s   
s   
u   李)r   u   瑩N)rE   TextIOWrapperBytesIOrH   r1   r2   rJ   r[   r	   r   r=   r   r(   encodingwriter+   rZ   )r5   weirdweirderrrg   r1   r2   r!   r!   r"   $test_beginLoggingToPreservesEncoding  s   

 z5LogBeginnerTests.test_beginLoggingToPreservesEncodingc              
   C   s   | j dttd g }| jtt|jg | j dttd t	
 }| j jdttd|d | | j jdttdddfdttd|dfg t| |tdtjd	 tj tdd
g dS )z
        L{LogBeginner.beginLoggingTo} will redirect the warnings of its
        warnings module into the logging system.
        z	a messagerL   zanother messager   zyet anotherrk   r   N.)r   r8   r9   r:   )rI   r>   DeprecationWarning__file__rJ   r[   r	   r   r=   rE   rF   r(   r4   r+   rZ   r.   r-   )r5   rg   fr!   r!   r"   test_warningsModule/  s>   
z$LogBeginnerTests.test_warningsModulec                 C   sX   t td}t| jd}|jd|d | j }| d| | d| | d| dS )zR
        The string resulting from a logged failure contains a traceback.
        z,this is not the behavior you are looking forr   z	a failure)failure	TracebackN)r
   	Exceptionr   rD   r   rG   r|   r}   )r5   r   r   msgr!   r!   r"   test_failuresAppendTracebacksV  s   
z.LogBeginnerTests.test_failuresAppendTracebacksr?   )r-   r.   r/   __doc__rK   r`   ra   rB   r   rh   rj   rm   r   r   r   r   r   r   r   r   r!   r!   r!   r"   r,   5   s     

1




+
	




'r,   )"r   rE   typingr   r   r   r   r   r   r   r	   twisted.python.failurer
   twisted.trialr   _filer   _globalr   r   _interfacesr   r   _levelsr   _loggerr   	_observerr   test.test_stdlibr   TestCaser+   r,   r!   r!   r!   r"   <module>   s,   (
