o
    ¯bbG  ã                   @   s.  d Z ddlmZmZ ddl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 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mZ d	dl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ede+de+fdd„Z,G dd„ deƒZ-G dd„ deƒZ.G dd„ deƒZ/dS )z$
Tests for L{twisted.logger._json}.
é    )ÚBytesIOÚStringIO)ÚIOÚAnyÚListÚOptionalÚSequenceÚcast)Úimplementer)ÚBrokenMethodImplementation)ÚverifyObject)ÚFailure)ÚTestCaseé   )ÚextractField)ÚformatEvent)ÚglobalLogPublisher)ÚILogObserverÚLogEvent)ÚeventAsJSONÚeventFromJSONÚeventsFromJSONLogFileÚjsonFileLogObserverÚlog)ÚLogLevel)ÚLogger)ÚLogPublisherÚtestCaseÚ	savedJSONÚreturnc                 C   s"   |   |t¡ |  | d¡d¡ |S )a*  
    Assert a few things about the result of L{eventAsJSON}, then return it.

    @param testCase: The L{TestCase} with which to perform the assertions.
    @param savedJSON: The result of L{eventAsJSON}.

    @return: C{savedJSON}

    @raise AssertionError: If any of the preconditions fail.
    Ú
r   )ÚassertIsInstanceÚstrÚassertEqualÚcount)r   r   © r%   ú?/usr/lib/python3/dist-packages/twisted/logger/test/test_json.pyÚsavedJSONInvariants!   s   r'   c                   @   s†   e Zd ZdZdede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 )ÚSaveLoadTestsz2
    Tests for loading and saving log events.
    Úeventr   c                 C   s   t | t|ƒƒS )zž
        Serialize some an events, assert some things about it, and return the
        JSON.

        @param event: An event.

        @return: JSON.
        )r'   r   )Úselfr)   r%   r%   r&   ÚsavedEventJSON6   s   	zSaveLoadTests.savedEventJSONNc                 C   s   |   t|  i ¡ƒi ¡ dS )zX
        Saving and loading an empty dictionary results in an empty dictionary.
        N©r#   r   r+   ©r*   r%   r%   r&   Útest_simpleSaveLoadA   s   z!SaveLoadTests.test_simpleSaveLoadc                 C   s&   |   t|  dddœ¡ƒdddœ¡ dS )a  
        Saving and loading a dictionary with some simple values in it results
        in those same simple values in the output; according to JSON's rules,
        though, all dictionary keys must be L{str} and any non-L{str}
        keys will be converted.
        r   Ú4)é   Ú3©Ú1r1   Nr,   r-   r%   r%   r&   Útest_saveLoadG   s   þzSaveLoadTests.test_saveLoadc                 C   ó,   |   t|  dtƒ dœ¡ƒdddidœ¡ dS )zx
        Saving and loading an object which cannot be represented in JSON will
        result in a placeholder.
        r   r2   ÚunpersistableTN©r#   r   r+   Úobjectr-   r%   r%   r&   Útest_saveUnPersistableS   s   þz$SaveLoadTests.test_saveUnPersistablec                 C   r5   )zD
        Non-ASCII keys and values can be saved and loaded.
        u   äŒ¡)u   áˆ´r1   r6   TNr7   r-   r%   r%   r&   Útest_saveNonASCII]   s   þzSaveLoadTests.test_saveNonASCIIc                 C   sJ   dt tdƒƒi}| ddi¡ |  t|  |¡ƒdt tdƒƒ d¡i¡ dS )zx
        Any L{bytes} objects will be saved as if they are latin-1 so they can
        be faithfully re-loaded.
        Úhelloéÿ   s   skippedÚokayÚcharmapN)ÚbytesÚrangeÚupdater#   r   r+   Údecode)r*   Ú
inputEventr%   r%   r&   Útest_saveBytesf   s   þzSaveLoadTests.test_saveBytesc                 C   s>   G dd„ dƒ}d|dƒdœ}t |  |¡ƒ}|  t|ƒd¡ dS )a
  
        Saving and loading an object which cannot be represented in JSON, but
        has a string representation which I{can} be saved as JSON, will result
        in the same string formatting; any extractable fields will retain their
        data types.
        c                   @   s,   e Zd Zdeddfdd„Zdefdd„ZdS )z@SaveLoadTests.test_saveUnPersistableThenFormat.<locals>.ReprableÚvaluer   Nc                 S   s
   || _ d S ©N©rE   )r*   rE   r%   r%   r&   Ú__init__~   ó   
zISaveLoadTests.test_saveUnPersistableThenFormat.<locals>.Reprable.__init__c                 S   s   dS )NÚreprabler%   r-   r%   r%   r&   Ú__repr__�   s   zISaveLoadTests.test_saveUnPersistableThenFormat.<locals>.Reprable.__repr__)Ú__name__Ú
__module__Ú__qualname__r8   rH   r"   rK   r%   r%   r%   r&   ÚReprable}   s    rO   z{object} {object.value}é   ©Ú
log_formatr8   z
reprable 7N)r   r+   r#   r   )r*   rO   rC   ÚoutputEventr%   r%   r&   Ú test_saveUnPersistableThenFormatu   s   z.SaveLoadTests.test_saveUnPersistableThenFormatc                 C   s`   G dd„ dƒ}t d|ƒ d�}t|  |¡ƒ}|  td|ƒd¡ |  ttd|¡ |  ttd|¡ dS )	zs
        L{extractField} can extract fields from an object that's been saved and
        loaded from JSON.
        c                   @   s   e Zd Zddd„ZdS )z8SaveLoadTests.test_extractingFieldsPostLoad.<locals>.Objr   Nc                 S   s
   d| _ d S )NéY  rG   r-   r%   r%   r&   rH   �   rI   zASaveLoadTests.test_extractingFieldsPostLoad.<locals>.Obj.__init__©r   N)rL   rM   rN   rH   r%   r%   r%   r&   ÚObjŽ   s    rW   z{object.value}rQ   zobject.valuerU   r8   N)Údictr   r+   r#   r   ÚassertRaisesÚKeyError)r*   rW   rC   ÚloadedEventr%   r%   r&   Útest_extractingFieldsPostLoadˆ   s   z+SaveLoadTests.test_extractingFieldsPostLoadc                 C   sž   g }t tt|jƒd�}zdd  W n ty#   tƒ }| d|¡ Y nw |  t|ƒd¡ t	|  
|d ¡ƒd }|  |t¡ |  | t¡¡ |  | ¡ t¡ dS )zl
        Round-tripping a failure through L{eventAsJSON} preserves its class and
        structure.
        ©Úobserverr0   r   za message about failureÚlog_failureN)r   r	   r   ÚappendÚZeroDivisionErrorr   Úfailurer#   Úlenr   r+   r!   Ú
assertTrueÚcheckÚgetTracebackr"   )r*   Úeventsr   ÚfÚloadedr%   r%   r&   Útest_failureStructurePreservedœ   s   þz,SaveLoadTests.test_failureStructurePreservedc                 C   s0   t tjd�}t|  |¡ƒ}|  |d tj¡ dS )zo
        It's important that the C{log_level} key remain a
        L{constantly.NamedConstant} object.
        ©Ú	log_levelrl   N)rX   r   Úwarnr   r+   ÚassertIs)r*   rC   r[   r%   r%   r&   Útest_saveLoadLevel®   s   z SaveLoadTests.test_saveLoadLevelc                 C   s   t dƒ}|  |tdd�¡ dS )zž
        If a saved bit of JSON (let's say, from a future version of Twisted)
        were to persist a different log_level, it will resolve as None.
        zZ{"log_level": {"name": "other", "__class_uuid__": "02E59486-F24D-46AD-8224-3ACDF2A5732A"}}Nrk   )r   r#   rX   )r*   r[   r%   r%   r&   Útest_saveLoadUnknownLevel·   s   ÿz'SaveLoadTests.test_saveLoadUnknownLevelrV   )rL   rM   rN   Ú__doc__r   r"   r+   r.   r4   r9   r:   rD   rT   r\   rj   ro   rp   r%   r%   r%   r&   r(   1   s    





	



	r(   c                   @   sL   e Zd ZdZddd„Zddeddfdd	„Zdd
d„Zddd„Zddd„Z	dS )ÚFileLogObserverTestsz+
    Tests for L{jsonFileLogObserver}.
    r   Nc                 C   s‚   t ƒ �4}t|ƒ}ztt|ƒ W n ty& } z|  |¡ W Y d}~nd}~ww W d  ƒ dS W d  ƒ dS 1 s:w   Y  dS )zh
        A L{FileLogObserver} returned by L{jsonFileLogObserver} is an
        L{ILogObserver}.
        N)r   r   r   r   r   Úfail)r*   Ú
fileHandler^   Úer%   r%   r&   Útest_interfaceÈ   s   €ÿÿý"ûz#FileLogObserverTests.test_interfaceúÚrecordSeparatorc                 C   s^   t ƒ �"}t||ƒ}tdd�}||ƒ |  | ¡ |› d�¡ W d  ƒ dS 1 s(w   Y  dS )a!  
        Asserts that an observer created by L{jsonFileLogObserver} with the
        given arguments writes events serialized as JSON text, using the given
        record separator.

        @param recordSeparator: C{recordSeparator} argument to
            L{jsonFileLogObserver}
        r0   ©Úxz	{"x": 1}
N)r   r   rX   r#   Úgetvalue)r*   rx   rt   r^   r)   r%   r%   r&   ÚassertObserverWritesJSONÔ   s   	

"üz-FileLogObserverTests.assertObserverWritesJSONc                 C   s   |   ¡  dS )zÏ
        A L{FileLogObserver} created by L{jsonFileLogObserver} writes events
        serialzed as JSON text to a file when it observes events.
        By default, the record separator is C{"\x1e"}.
        N©r|   r-   r%   r%   r&   Ú(test_observeWritesDefaultRecordSeparatorã   s   z=FileLogObserverTests.test_observeWritesDefaultRecordSeparatorc                 C   s   | j dd� dS )zÎ
        A L{FileLogObserver} created by L{jsonFileLogObserver} writes events
        serialzed as JSON text to a file when it observes events.
        This test sets the record separator to C{""}.
        Ú ©rx   Nr}   r-   r%   r%   r&   Ú&test_observeWritesEmptyRecordSeparatorë   s   z;FileLogObserverTests.test_observeWritesEmptyRecordSeparatorc                    sª   t ƒ }tƒ }g }| tt|jƒ¡ | t|ƒ¡ t|d�}zdd  W n ty1   | 	d¡ Y nw t | 
¡ ƒ}tt|ƒƒ}dtt ddf‡ fdd	„}||ƒ ||ƒ dS )
z›
        A L{FileLogObserver} created by L{jsonFileLogObserver} writes failures
        serialized as JSON text to a file when it observes events.
        r]   r0   r   zfailed as expectedÚ	logEventsr   Nc                    s`   ˆ   t| ƒd¡ | \}ˆ  d|¡ |d }ˆ  |t¡ | ¡ }ˆ   |jjj 	d¡t
 	d¡¡ d S )Nr0   r_   Úco)r#   rc   ÚassertInr!   r   ÚgetTracebackObjectÚtb_frameÚf_codeÚco_filenameÚrstripÚ__file__)r‚   ÚfailureEventÚfailureObjectÚtracebackObjectr-   r%   r&   ÚcheckEvents  s   þz@FileLogObserverTests.test_failureFormatting.<locals>.checkEvents)r   r   ÚaddObserverr	   r   r`   r   r   ÚBaseExceptionrb   r{   Úlistr   r   r   )r*   ÚioÚ	publisherÚloggedÚloggerÚreaderÚdeserializedrŽ   r%   r-   r&   Útest_failureFormattingó   s    
ÿz+FileLogObserverTests.test_failureFormattingrV   )rw   )
rL   rM   rN   rq   rv   r"   r|   r~   r�   r˜   r%   r%   r%   r&   rr   Ã   s    


rr   c                	   @   sÄ   e Zd ZdZd&dd„Zd&dd„Z		d'd	ee d
e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&d"d#„Zd&d$d%„ZdS )(ÚLogFileReaderTestsz-
    Tests for L{eventsFromJSONLogFile}.
    r   Nc                    s8   g ˆ _ ttƒdtdd f‡ fdd„ƒ}|ˆ _t |¡ d S )Nr)   r   c                    s.   | d t jkrd| v rˆ j | ¡ d S d S d S )NÚlog_namespaceÚrecord)ÚjsonLogÚ	namespaceÚerrorEventsr`   )r)   r-   r%   r&   r^     s   ÿz*LogFileReaderTests.setUp.<locals>.observer)rž   r
   r   r   ÚlogObserverr   r�   )r*   r^   r%   r-   r&   ÚsetUp  s
   zLogFileReaderTests.setUpc                 C   s   t  | j¡ d S rF   )r   ÚremoveObserverrŸ   r-   r%   r%   r&   ÚtearDown&  s   zLogFileReaderTests.tearDowné   ÚinFilerx   Ú
bufferSizec                 C   sJ   t t|||ƒƒ}|  t|ƒddi¡ |  t|ƒddi¡ |  tt|¡ dS )a|  
        Test that L{eventsFromJSONLogFile} reads two pre-defined events from a
        file: C{{"x": 1}} and C{{"y": 2}}.

        @param inFile: C{inFile} argument to L{eventsFromJSONLogFile}
        @param recordSeparator: C{recordSeparator} argument to
            L{eventsFromJSONLogFile}
        @param bufferSize: C{bufferSize} argument to L{eventsFromJSONLogFile}
        rz   r0   Úyr   N)Úiterr   r#   ÚnextrY   ÚStopIteration)r*   r¤   rx   r¥   rg   r%   r%   r&   Ú_readEvents)  s   zLogFileReaderTests._readEventsc                 C   óJ   t dƒ�}|  |¡ |  t| jƒd¡ W d  ƒ dS 1 sw   Y  dS )z�
        L{eventsFromJSONLogFile} reads events from a file and automatically
        detects use of C{"\x1e"} as the record separator.
        ú{"x": 1}
{"y": 2}
r   N©r   rª   r#   rc   rž   ©r*   rt   r%   r%   r&   Ú&test_readEventsAutoWithRecordSeparator>  ó   

"þz9LogFileReaderTests.test_readEventsAutoWithRecordSeparatorc                 C   r«   )z‹
        L{eventsFromJSONLogFile} reads events from a file and automatically
        detects use of C{""} as the record separator.
        z{"x": 1}
{"y": 2}
r   Nr­   r®   r%   r%   r&   Ú'test_readEventsAutoEmptyRecordSeparatorG  r°   z:LogFileReaderTests.test_readEventsAutoEmptyRecordSeparatorc                 C   óN   t dƒ�}| j|dd� |  t| jƒd¡ W d  ƒ dS 1 s w   Y  dS )z{
        L{eventsFromJSONLogFile} reads events from a file and is told to use
        a specific record separator.
        z{"x": 1}
{"y": 2}
úr€   r   Nr­   r®   r%   r%   r&   Ú&test_readEventsExplicitRecordSeparatorP  s   
"þz9LogFileReaderTests.test_readEventsExplicitRecordSeparatorc                 C   r²   )zM
        L{eventsFromJSONLogFile} handles buffering a partial event.
        r¬   r0   ©r¥   r   Nr­   r®   r%   r%   r&   Útest_readEventsPartialBufferZ  s   
"ýz/LogFileReaderTests.test_readEventsPartialBufferc                 C   óš   t dƒ�?}tt|ƒƒ}|  t|ƒddi¡ |  tt|¡ |  t| jƒd¡ |  | jd d d¡ |  | jd d d	¡ W d
  ƒ d
S 1 sFw   Y  d
S )zF
        If the JSON text for a record is truncated, skip it.
        z{"x": 1{"y": 2}
r¦   r   r0   r   rR   z0Unable to read truncated JSON record: {record!r}r›   s   {"x": 1N©	r   r§   r   r#   r¨   rY   r©   rc   rž   ©r*   rt   rg   r%   r%   r&   Útest_readTruncatedc  ó   
þ"ôz%LogFileReaderTests.test_readTruncatedc                 C   ón   t dƒ�)}tt|ƒƒ}|  t|ƒddi¡ |  tt|¡ |  t| jƒd¡ W d  ƒ dS 1 s0w   Y  dS )zc
        If the file being read from vends L{str}, strings decode from JSON
        as-is.
        u   {"currency": "â‚¬"}
Úcurrencyõ   â‚¬r   Nr¸   r¹   r%   r%   r&   Útest_readUnicodeu  s   
"ûz#LogFileReaderTests.test_readUnicodec                 C   r¼   )zh
        If the file being read from vends L{bytes}, strings decode from JSON as
        UTF-8.
        s   {"currency": "â‚¬"}
r½   r¾   r   N©	r   r§   r   r#   r¨   rY   r©   rc   rž   r¹   r%   r%   r&   Útest_readUTF8Bytes‚  s   
"úz%LogFileReaderTests.test_readUTF8Bytesc                 C   sr   t dƒ�+}tt|dd�ƒ}|  t|ƒddi¡ |  tt|¡ |  t| jƒd¡ W d  ƒ dS 1 s2w   Y  dS )zä
        If the JSON text for a record is truncated in the middle of a two-byte
        Unicode codepoint, we don't want to see a codec exception and the
        stream is read properly when the additional data arrives.
        s   {"x": "â‚¬"}
é   rµ   rz   r¾   r   NrÀ   r¹   r%   r%   r&   Útest_readTruncatedUTF8Bytes�  s   
"ûz.LogFileReaderTests.test_readTruncatedUTF8Bytesc                 C   r·   )zh
        If the JSON text for a record contains invalid UTF-8 text, ignore that
        record.
        s   {"x": "â¬"}
{"y": 2}
r¦   r   r0   r   rR   z2Unable to decode UTF-8 for JSON record: {record!r}r›   s   {"x": "â¬"}
NrÀ   r¹   r%   r%   r&   Útest_readInvalidUTF8BytesŸ  s   
þ"ôz,LogFileReaderTests.test_readInvalidUTF8Bytesc                 C   r·   )zD
        If the JSON text for a record is invalid, skip it.
        z{"x": }
{"y": 2}
r¦   r   r0   r   rR   ú&Unable to read JSON record: {record!r}r›   s   {"x": }
Nr¸   r¹   r%   r%   r&   Útest_readInvalidJSON³  r»   z'LogFileReaderTests.test_readInvalidJSONc                 C   s‚   t dƒ�3}t|ƒ}|  tt|¡ |  t| jƒd¡ |  | jd d d¡ |  | jd d d¡ W d  ƒ dS 1 s:w   Y  dS )	zI
        Multiple events without a record separator are skipped.
        z{"x": 1}
{"y": 2}
r0   r   rR   rÅ   r›   s   {"x": 1}
{"y": 2}
N)r   r   rY   r©   r¨   r#   rc   rž   r¹   r%   r%   r&   Útest_readUnseparatedÅ  s   
þ"õz'LogFileReaderTests.test_readUnseparatedc                 C   s|   t dd�}tƒ �,}t|ƒ}||ƒ | d¡ t|ƒ}|  t|ƒ|f¡ |  t| jƒd¡ W d  ƒ dS 1 s7w   Y  dS )z¡
        Data written by a L{FileLogObserver} returned by L{jsonFileLogObserver}
        and read by L{eventsFromJSONLogFile} is reconstructed properly.
        r0   ry   r   N)	rX   r   r   Úseekr   r#   Útuplerc   rž   )r*   r)   rt   r^   rg   r%   r%   r&   Útest_roundTripÖ  s   

"øz!LogFileReaderTests.test_roundTriprV   )Nr£   )rL   rM   rN   rq   r    r¢   r   r   r   r"   Úintrª   r¯   r±   r´   r¶   rº   r¿   rÁ   rÃ   rÄ   rÆ   rÇ   rÊ   r%   r%   r%   r&   r™     s6    

üþýü
û

	
	


	





r™   N)0rq   r’   r   r   Útypingr   r   r   r   r   r	   Úzope.interfacer
   Úzope.interface.exceptionsr   Úzope.interface.verifyr   Útwisted.python.failurer   Útwisted.trial.unittestr   Ú_flattenr   Ú_formatr   Ú_globalr   Ú_interfacesr   r   Ú_jsonr   r   r   r   r   rœ   Ú_levelsr   Ú_loggerr   Ú	_observerr   r"   r'   r(   rr   r™   r%   r%   r%   r&   Ú<module>   s*     R