o
    ¯bÕ1  ã                   @   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,   (ÿþý
ü