o
    b	9                     @   s   d Z ddlZddl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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 G dd dejZ G dd dejZ!dS )z+
Test cases for L{twisted.logger._legacy}.
    N)time)Listcast)implementer)BrokenMethodImplementation)verifyObject)contextlog)Failure)unittest   )formatEvent)ILogObserverLogEvent)LegacyLogObserverWrapperpublishToNewObserver)LogLevelc                   @   s  e Zd ZdZd4ddZd4ddZdedefd	d
ZdedefddZd4ddZ	d4ddZ
d4ddZd4ddZd4ddZd4ddZd4ddZd4ddZd4ddZd4dd Zd4d!d"Zd4d#d$Zd4d%d&Zd4d'd(Zd)edefd*d+Zd4d,d-Zd4d.d/Zd4d0d1Zd4d2d3ZdS )5LegacyLogObserverWrapperTestsz0
    Tests for L{LegacyLogObserverWrapper}.
    returnNc              
   C   sZ   t tjdd }t|}ztt| W dS  ty, } z| | W Y d}~dS d}~ww )zD
        L{LegacyLogObserverWrapper} is an L{ILogObserver}.
        c                 S      d S N er   r   A/usr/lib/python3/dist-packages/twisted/logger/test/test_legacy.py<lambda>"   s    z>LegacyLogObserverWrapperTests.test_interface.<locals>.<lambda>N)r   	legacyLogr   r   r   r   fail)selflegacyObserverobserverr   r   r   r   test_interface   s   z,LegacyLogObserverWrapperTests.test_interfacec                 C   s6   t tjG dd d}t| }| t|d dS )zJ
        L{LegacyLogObserverWrapper} returns the expected string.
        c                   @   s.   e Zd ZdefddZdejddfddZdS )z?LegacyLogObserverWrapperTests.test_repr.<locals>.LegacyObserverr   c                 S   s   dS )Nz<Legacy Observer>r   r   r   r   r   __repr__0      zHLegacyLogObserverWrapperTests.test_repr.<locals>.LegacyObserver.__repr__	eventDictNc                 S   r   r   r   )r   r%   r   r   r   __call__3   r$   zHLegacyLogObserverWrapperTests.test_repr.<locals>.LegacyObserver.__call__)__name__
__module____qualname__strr#   r   	EventDictr&   r   r   r   r   LegacyObserver.   s    r,   z+LegacyLogObserverWrapper(<Legacy Observer>)N)r   r   r   r   assertEqualrepr)r   r,   r    r   r   r   	test_repr)   s   
z'LegacyLogObserverWrapperTests.test_repreventc                    s@   g  t tj fdd}t|}|| | t d  d S )z
        Send an event to a wrapped legacy observer and capture the event as
        seen by that observer.

        @param event: an event

        @return: the event as observed by the legacy wrapper
        c                    s
     | S r   )appendr   eventsr   r   r   E   s   
 z7LegacyLogObserverWrapperTests.observe.<locals>.<lambda>   r   )r   r   r   r   r-   len)r   r0   r   r    r   r2   r   observe:   s   	z%LegacyLogObserverWrapperTests.observec                 C   sX   | dt  | dd | dtj | t|}| D ]
\}}| || q|S )z
        Send an event to a wrapped legacy observer and verify that its data is
        preserved.

        @param event: an event

        @return: the event as observed by the legacy wrapper
        log_time
log_system-	log_level)
setdefaultr   r   infor6   dictitemsassertIn)r   r0   observedkeyvaluer   r   r   forwardAndVerifyL   s   
z.LegacyLogObserverWrapperTests.forwardAndVerifyc                 C   s   |  tddd dS )ze
        Basic forwarding: event keys as observed by a legacy observer are the
        same.
        r4   r   foobarN)rC   r=   r"   r   r   r   test_forwardc   s   z*LegacyLogObserverWrapperTests.test_forwardc                 C   s*   t  }| t|d}| |d | dS )zc
        The new-style C{"log_time"} key is copied to the old-style C{"time"}
        key.
        )r7   r   Nr   rC   r=   r-   r   stampr0   r   r   r   	test_timej   s   z'LegacyLogObserverWrapperTests.test_timec                 C   s0   t  }| t|d |d}| |d | dS )zr
        The new-style C{"log_time"} key does not step on a pre-existing
        old-style C{"time"} key.
        r4   )r7   r   r   NrH   rI   r   r   r   test_timeAlreadySets   s   z1LegacyLogObserverWrapperTests.test_timeAlreadySetc                 C   $   |  tdd}| |d d dS )zg
        The new-style C{"log_system"} key is copied to the old-style
        C{"system"} key.
        rE   )r8   systemNrC   r=   r-   r   r0   r   r   r   test_system|   s   z)LegacyLogObserverWrapperTests.test_systemc                 C   s&   |  tddd}| |d d dS )zv
        The new-style C{"log_system"} key does not step on a pre-existing
        old-style C{"system"} key.
        rE   rF   )r8   rN   rN   NrO   rP   r   r   r   test_systemAlreadySet   s   z3LegacyLogObserverWrapperTests.test_systemAlreadySetc                 C   s2   t t tjd}| t |}| |d d dS )zy
        If the new-style C{"log_system"} key is absent, the old-style
        C{"system"} key is set to C{"-"}.
        )r7   r:   rN   r9   N)r=   r   r   r<   r6   r-   )r   r0   r@   r   r   r   test_noSystem   s   z+LegacyLogObserverWrapperTests.test_noSystemc                 C   sT   |  ttjdd |  ttjdd |  ttjdd |  ttjdd dS )z
        If explicitly set, the C{isError} key will be preserved when forwarding
        from a new-style logging emitter to a legacy logging observer,
        regardless of log level.
        r4   )r:   isErrorr   N)rC   r=   r   r<   warnerrorcriticalr"   r   r   r   test_levelNotChange   s   z1LegacyLogObserverWrapperTests.test_levelNotChangec                 C   s"   |  ttjd}| d| dS )a)  
        The new-style C{"log_level"} key is not translated to the old-style
        C{"logLevel"} key.

        Events are forwarded from the old module from to new module and are
        then seen by old-style observers.
        We don't want to add unexpected keys to old-style events.
        )r:   logLevelN)rC   r=   r   r<   assertNotInrP   r   r   r   test_pythonLogLevelNotSet   s   	z7LegacyLogObserverWrapperTests.test_pythonLogLevelNotSetc                 C   rM   )a  
        If a stdlib log level was provided as a string (eg. C{"WARNING"}) in
        the legacy "logLevel" key, it does not get converted to a number.
        The documentation suggested that numerical values should be used but
        this was not a requirement.
        WARNINGrY   rY   NrO   rP   r   r   r   test_stringPythonLogLevel   s   z7LegacyLogObserverWrapperTests.test_stringPythonLogLevelc                 C   s    |  t }| |d d dS )z
        The old-style C{"message"} key is added, even if no new-style
        C{"log_format"} is given, as it is required, but may be empty.
        messager   NrO   rP   r   r   r   test_message      z*LegacyLogObserverWrapperTests.test_messagec                 C   rM   )zV
        The old-style C{"message"} key is not modified if it already exists.
        rD   )r_   r_   NrO   rP   r   r   r   test_messageAlreadySet   s   z4LegacyLogObserverWrapperTests.test_messageAlreadySetc                 C   (   |  tddd}| t|d dS )z
        Formatting is translated such that text is rendered correctly, even
        though old-style logging doesn't use PEP 3101 formatting.
        zHello, {who}!world)
log_formatwhoHello, world!NrC   r=   r-   r   textFromEventDictrP   r   r   r   test_format      z)LegacyLogObserverWrapperTests.test_formatc                 C   rc   )zo
        Using the message key, which is special in old-style, works for
        new-style formatting.
        zHello, {message}!rd   )re   r_   rg   Nrh   rP   r   r   r   test_formatMessage   s   
z0LegacyLogObserverWrapperTests.test_formatMessagec                 C   s(   |  tddd}| t|d dS )zd
        Formatting is not altered if the old-style C{"format"} key already
        exists.
        zHello!zHowdy!)re   formatNrh   rP   r   r   r   test_formatAlreadySet   rk   z3LegacyLogObserverWrapperTests.test_formatAlreadySetvaluesc                 K   s&   t td}| td|dd|S )z
        Create a new-style event with a captured failure.

        @param values: Additional values to include in the event.

        @return: the new event
        znyargh!	oopsie...)log_failurere   Nr   )r
   RuntimeErrorrC   r=   )r   ro   failurer   r   r   eventWithFailure   s   z.LegacyLogObserverWrapperTests.eventWithFailurec                 C   s>   |   }| |d |d  | |d  | |d d dS )z}
        Captured failures in the new style set the old-style C{"failure"},
        C{"isError"}, and C{"why"} keys.
        rs   rq   rT   whyrp   N)rt   assertIs
assertTruer-   rP   r   r   r   test_failure   s   z*LegacyLogObserverWrapperTests.test_failurec                 C   s,   t td}| j|d}| |d | dS )v
        Captured failures in the new style do not step on a pre-existing
        old-style C{"failure"} key.
        zWeak salsa!)rs   rs   N)r
   rr   rt   rv   )r   rs   r0   r   r   r   test_failureAlreadySet   s   z4LegacyLogObserverWrapperTests.test_failureAlreadySetc                 C       | j dd}| |d d dS )zv
        Captured failures in the new style do not step on a pre-existing
        old-style C{"isError"} key.
        r   rT   rT   Nrt   r-   rP   r   r   r   test_isErrorAlreadySet  ra   z4LegacyLogObserverWrapperTests.test_isErrorAlreadySetc                 C   r{   )ry   blah)ru   ru   Nr}   rP   r   r   r   test_whyAlreadySet  ra   z0LegacyLogObserverWrapperTests.test_whyAlreadySetr   N)r'   r(   r)   __doc__r!   r/   r   r6   rC   rG   rK   rL   rQ   rR   rS   rX   r[   r^   r`   rb   rj   rl   rn   objectrt   rx   rz   r~   r   r   r   r   r   r      s2    




	
	















	r   c                   @   s   e Zd ZdZdddZdededej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 )PublishToNewObserverTestsz,
    Tests for L{publishToNewObserver}.
    r   Nc                 C   s   g | _ tt| j j| _d S r   )r3   r   r   r1   r    r"   r   r   r   setUp  s   zPublishToNewObserverTests.setUpr_   ro   c                 O   sD   t tjpi  }|| ||d< t |d< d|vr d|d< |S )a  
        Return a basic old-style event as would be created by L{legacyLog.msg}.

        @param message: a message event value in the legacy event format
        @param values: additional event values in the legacy event format

        @return: a legacy event
        r_   r   rT   r   )r   getr   ILogContextcopyupdater   )r   r_   ro   r0   r   r   r   legacyEvent  s   	

z%PublishToNewObserverTests.legacyEventc                 C   s*   t | j|  tj | t| jd dS )z6
        The observer is called exactly once.
        r4   N)r   r    r   r   ri   r-   r5   r3   r"   r   r   r   test_observed/  s   z'PublishToNewObserverTests.test_observedc                 C   8   t | j|  tj | | jd d | jd d  dS )zc
        The old-style C{"time"} key is copied to the new-style C{"log_time"}
        key.
        r   r7   r   Nr   r    r   r   ri   r-   r3   r"   r   r   r   rK   8     $z#PublishToNewObserverTests.test_timec                 C   sN   dt dtfdd}| dd}||}t| j|| | t| jd | dS )	z
        A published old-style event should format as text in the same way as
        the given C{textFromEventDict} callable would format it.
        r0   r   c                 S   s   d td | d S )N  r_   )joinreversed)r0   r   r   r   ri   H  s   zAPublishToNewObserverTests.test_message.<locals>.textFromEventDictzHello,zworld!r   N)r   r*   r   r   r    r-   r   r3   )r   ri   r0   textr   r   r   r`   B  s
   z&PublishToNewObserverTests.test_messagec                 C   s0   t | j|  tj | | jd d tj dS )zL
        Published event should have log level of L{LogLevel.info}.
        r   r:   N)	r   r    r   r   ri   r-   r3   r   r<   r"   r   r   r   test_defaultLogLevelQ  s   z.PublishToNewObserverTests.test_defaultLogLevelc                 C   4   t | j| jddtj | | jd d tj dS )z
        If C{"isError"} is set to C{1} (true) on the legacy event, the
        C{"log_level"} key should get set to L{LogLevel.critical}.
        r4   r|   r   r:   N)	r   r    r   r   ri   r-   r3   r   rW   r"   r   r   r   test_isErrorZ  s   z&PublishToNewObserverTests.test_isErrorc                 C   s6   t | j| jtjdtj | | jd d t	j
 dS )z
        If the old-style C{"logLevel"} key is set to a standard library logging
        level, using a predefined (L{int}) constant, the new-style
        C{"log_level"} key should get set to the corresponding log level.
        r]   r   r:   N)r   r    r   
py_loggingr\   r   ri   r-   r3   r   rU   r"   r   r   r   test_stdlibLogLeveld  s   z-PublishToNewObserverTests.test_stdlibLogLevelc                 C   r   )z
        If the old-style C{"logLevel"} key is set to a standard library logging
        level, using a string value, the new-style C{"log_level"} key should
        get set to the corresponding log level.
        r\   r]   r   r:   N)	r   r    r   r   ri   r-   r3   r   rU   r"   r   r   r   test_stdlibLogLevelWithStringq  s   
z7PublishToNewObserverTests.test_stdlibLogLevelWithStringc                 C   s.   t | j| jddtj | d| jd  dS )z
        If the old-style C{"logLevel"} key is set to a standard library logging
        level, using an unknown value, the new-style C{"log_level"} key should
        not get set.
        zFoo!!!!!r]   r:   r   N)r   r    r   r   ri   rZ   r3   r"   r   r   r   test_stdlibLogLevelWithGarbage~  s   
z8PublishToNewObserverTests.test_stdlibLogLevelWithGarbagec                 C   s.   t | j|  tj | | jd d d dS )z
        Published event should have a namespace of C{"log_legacy"} to indicate
        that it was forwarded from legacy logging.
        r   log_namespace
log_legacyNr   r"   r   r   r   test_defaultNamespace  s   z/PublishToNewObserverTests.test_defaultNamespacec                 C   r   )zg
        The old-style C{"system"} key is copied to the new-style
        C{"log_system"} key.
        r   r8   rN   Nr   r"   r   r   r   rQ     r   z%PublishToNewObserverTests.test_systemr   )r'   r(   r)   r   r   r*   r   r   r+   r   r   rK   r`   r   r   r   r   r   r   rQ   r   r   r   r   r     s    


	



	





r   )"r   loggingr   r   typingr   r   zope.interfacer   zope.interface.exceptionsr   zope.interface.verifyr   twisted.pythonr   r	   r   twisted.python.failurer
   twisted.trialr   _formatr   _interfacesr   r   _legacyr   r   _levelsr   TestCaser   r   r   r   r   r   <module>   s"    }