U
    `[/                     @   s   d Z ddlmZ ddlZddlmZ ddlmZ ddlm	Z	 ddl
mZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ dd ZG dd dejZdS )z+
Test cases for L{twisted.logger._global}.
    )print_functionN)unittest   )textFileLogObserver)LogPublisher)Logger)LogBeginner)MORE_THAN_ONCE_WARNING)LogLevel)nextLine)Failurec                    sj   t |t |kr| || t  |D ]} t| O  q& fddfdd|D }| || dS )a  
    Compare two sequences of log events, examining only the the keys which are
    present in both.

    @param test: a test case doing the comparison
    @type test: L{unittest.TestCase}

    @param actualEvents: A list of log events that were emitted by a logger.
    @type actualEvents: L{list} of L{dict}

    @param expectedEvents: A list of log events that were expected by a test.
    @type expected: L{list} of L{dict}
    c                    s,   |   }|  D ]}| kr|| q|S N)copykeyspop)eventr   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>5   s     z!compareEvents.<locals>.<listcomp>N)lenassertEqualsetr   )ZtestZactualEventsZexpectedEventsr   ZsimplifiedActualr   )r   r   r   compareEvents   s    r   c                   @   s   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd ZdS )LogBeginnerTestsz#
    Tests for L{LogBeginner}.
    c                 C   s^   t  | _t | _G dd dt}G dd dt}| | _| | _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   NotSysC   s   r%   c                   @   s   e Zd Zdd ZdddZdS )z+LogBeginnerTests.setUp.<locals>.NotWarningsc                 S   s
   g | _ d S r   )warnings)selfr   r   r   __init__H   s    z4LogBeginnerTests.setUp.<locals>.NotWarnings.__init__Nc                 S   s   | j ||||||f dS )a  
                Emulate warnings.showwarning.

                @param message: A warning message to emit.
                @type message: L{str}

                @param category: A warning category to associate with
                    C{message}.
                @type category: L{warnings.Warning}

                @param filename: A file name for the source code file issuing
                    the warning.
                @type warning: L{str}

                @param lineno: A line number in the source file where the
                    warning was issued.
                @type lineno: L{int}

                @param file: A file to write the warning message to.  If
                    L{None}, write to L{sys.stderr}.
                @type file: file-like object

                @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}.
                @type line: L{str}
                N)r&   append)r'   messagecategoryfilenamelinenofileliner   r   r   showwarningK   s    z7LogBeginnerTests.setUp.<locals>.NotWarnings.showwarning)NN)r   r    r!   r(   r0   r   r   r   r   NotWarningsG   s      r1   )
r   	publisherioStringIOerrorStreamr"   	sysModulewarningsModuler   beginner)r'   r%   r1   r   r   r   setUp?   s    
'  zLogBeginnerTests.setUpc                    sf   t ddd}g  g  fdd}fdd}| j||f | | | |g  | |g dS )z?
        Test that C{beginLoggingTo()} adds observers.
           r   ZfooZbarc                    s
     | S r   r)   eevents1r   r   <lambda>       zBLogBeginnerTests.test_beginLoggingToAddObservers.<locals>.<lambda>c                    s
     | S r   r<   r=   events2r   r   rA      rB   N)dictr8   beginLoggingTor2   r   r'   r   Zo1Zo2r   r@   rD   r   test_beginLoggingToAddObserversv   s    
z0LogBeginnerTests.test_beginLoggingToAddObserversc                    sf   t ddd}g  g  fdd}fdd}| | | j||f | |g  | |g dS )z\
        Test that events are buffered until C{beginLoggingTo()} is
        called.
        r:   r   r;   c                    s
     | S r   r<   r=   r?   r   r   rA      rB   zDLogBeginnerTests.test_beginLoggingToBufferedEvents.<locals>.<lambda>c                    s
     | S r   r<   r=   rC   r   r   rA      rB   N)rE   r2   r8   rF   r   rG   r   rH   r   !test_beginLoggingToBufferedEvents   s    
z2LogBeginnerTests.test_beginLoggingToBufferedEventsc                 C   s`   t |d D ]}| t|d qg }||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.
        @type limit: L{int}

        @param beginner: The L{LogBeginner} against which to verify.
        @type beginner: L{LogBeginner}

        @raise: C{self.failureException} if the wrong events are replayed by
            C{beginner}.

        @return: L{None}
        r:   )countc                 s   s   | ]}|d  V  qdS )rK   Nr   r   r   r   r   	<genexpr>   s     z4LogBeginnerTests._bufferLimitTest.<locals>.<genexpr>N)ranger2   rE   rF   r)   r   list)r'   limitr8   rK   Z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   Z_DEFAULT_BUFFER_SIZErP   r8   )r'   rO   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.
           )ZinitialBufferSizeN)r   r2   r5   r6   r7   rP   )r'   rO   r8   r   r   r   test_overrideBufferLimit   s       z)LogBeginnerTests.test_overrideBufferLimitc              	   C   s  g }g }t  }t|}| tdd t \}}| j|j|g | tdd t \}}| j|j|g | tdd tt	t
j||||d}	t| |tddtdd|	tddg t| ||	tddg | }
| 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.
        Z	prebuffer)r   Z
postbufferZpostwarn)Z
log_formatZ	log_levelZfileNowZlineNowZfileThenZlineThenz	<{0}:{1}>N)r3   r4   r   r2   rE   r   r8   rF   r)   r	   r
   warnr   getvalueassertInformat)r'   r@   rD   Z
fileHandleZtextObserverZfirstFilenameZ	firstLineZsecondFilenameZ
secondLinewarningoutputr   r   r   test_beginLoggingToTwice   sH    

   	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.
        Zobserverzignore thisza critical {message}r*   )r*   za critical message
N)r   r2   infocriticalr   r5   rU   r'   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   r2   r8   rF   r]   r   r5   rU   r^   r   r   r   test_criticalLoggingStops  s    
z*LogBeginnerTests.test_criticalLoggingStopsc                 C   sn   g }| j |jg td| jjd t| |tdddg |dd= td| 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.   r#   )Zlog_namespacelog_ioNzError, world.r$   )	r8   rF   r)   printr6   r#   r   rE   r$   )r'   xr   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)ZredirectStandardION)r6   r#   r$   r8   rF   ZassertIs)r'   ZoldOutZoldErrr   r   r   test_beginLoggingToDontRedirect   s
    z0LogBeginnerTests.test_beginLoggingToDontRedirectc                 C   s   t t  d}t t  d}|| j_|| j_g }| j|jg | 	| jjj
d | 	| jjj
d | jjd | jj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   李)rd   u   瑩N)r3   TextIOWrapperBytesIOr6   r#   r$   r8   rF   r)   r   encodingwriter   rE   )r'   ZweirdZweirderrrf   r   r   r   $test_beginLoggingToPreservesEncoding,  s      z5LogBeginnerTests.test_beginLoggingToPreservesEncodingc              
   C   s   | j dttd g }| j|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 messager:   zanother messager   zyet anotherrR   rc   N.)rX   r+   r,   r-   )r7   r0   DeprecationWarning__file__r8   rF   r)   r3   r4   r   r&   r   rE   r    r   )r'   rf   fr   r   r   test_warningsModuleE  sP                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   r2   rt   r5   rU   rV   )r'   rr   r_   msgr   r   r   test_failuresAppendTracebacksj  s    
z.LogBeginnerTests.test_failuresAppendTracebacksN)r   r    r!   __doc__r9   rI   rJ   rP   rQ   rS   rZ   r`   rb   rg   rh   rn   rs   rx   r   r   r   r   r   :   s   7	*
%r   )ry   Z
__future__r   r3   Ztwisted.trialr   Z_filer   Z	_observerr   Z_loggerr   Z_globalr   r	   Z_levelsr
   Ztest.test_stdlibr   Ztwisted.python.failurer   r   ZTestCaser   r   r   r   r   <module>   s   !