
    VhbG                     >   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Z, G d de      Z- G d de      Z. G d de      Z/y)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                 t    | j                  |t               | j                  |j                  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   s     M/home/dcms/DCMS/lib/python3.12/site-packages/twisted/logger/test/test_json.pysavedJSONInvariantsr(   !   s3     i-.2    c                   p    e Zd ZdZdedef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y)SaveLoadTestsz2
    Tests for loading and saving log events.
    eventr    c                 ,    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,   s     r'   savedEventJSONzSaveLoadTests.savedEventJSON6   s     #4U);<<r)   Nc                 X    | j                  t        | j                  i             i        y)zX
        Saving and loading an empty dictionary results in an empty dictionary.
        Nr%   r   r/   r.   s    r'   test_simpleSaveLoadz!SaveLoadTests.test_simpleSaveLoadA   s$     	t':':2'>?Dr)   c           	      d    | j                  t        | j                  ddd            ddd       y)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1r7   Nr1   r2   s    r'   test_saveLoadzSaveLoadTests.test_saveLoadG   s2     	$--!#.>?@#	
r)   c           	      x    | j                  t        | j                  dt               d            dddid       y)zx
        Saving and loading an object which cannot be represented in JSON will
        result in a placeholder.
        r   r8   unpersistableTNr%   r   r/   objectr2   s    r'   test_saveUnPersistablez$SaveLoadTests.test_saveUnPersistableS   s9    
 	$--AFH.EFG?D12	
r)   c           	      x    | j                  t        | j                  dt               d            dddid       y)zD
        Non-ASCII keys and values can be saved and loaded.
        u   䌡)u   ሴr7   r<   TNr=   r2   s    r'   test_saveNonASCIIzSaveLoadTests.test_saveNonASCII]   s9     	$--.QRS&=>	
r)   c           	          dt        t        d            i}|j                  ddi       | j                  t	        | j                  |            dt        t        d            j                  d      i       y)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.   
inputEvents     r'   test_saveByteszSaveLoadTests.test_saveBytesf   si    
 uU3Z01
 	:v./$--j9:eE#J'..y9:	
r)   c                      G d d      }d |d      d}t        | j                  |            }| j                  t        |      d       y)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                   (    e Zd ZdeddfdZdefdZy)@SaveLoadTests.test_saveUnPersistableThenFormat.<locals>.Reprablevaluer    Nc                     || _         y NrP   )r.   rP   s     r'   __init__zISaveLoadTests.test_saveUnPersistableThenFormat.<locals>.Reprable.__init__~   s	    "
r)   c                      y)Nreprable r2   s    r'   __repr__zISaveLoadTests.test_saveUnPersistableThenFormat.<locals>.Reprable.__repr__   s    !r)   )__name__
__module____qualname__r>   rT   r$   rX   rW   r)   r'   ReprablerO   }   s!    #f # #"# "r)   r\   z{object} {object.value}   
log_formatr>   z
reprable 7N)r   r/   r%   r   )r.   r\   rK   outputEvents       r'    test_saveUnPersistableThenFormatz.SaveLoadTests.test_saveUnPersistableThenFormatu   sG    	" 	" %>RSU
#D$7$7
$CD[1<@r)   c                     G d d      }t        d |             }t        | j                  |            }| j                  t	        d|      d       | j                  t        t        d|       | j                  t        t        d|       y)	zs
        L{extractField} can extract fields from an object that's been saved and
        loaded from JSON.
        c                       e Zd ZddZy)8SaveLoadTests.test_extractingFieldsPostLoad.<locals>.ObjNc                     d| _         y )NY  rS   r2   s    r'   rT   zASaveLoadTests.test_extractingFieldsPostLoad.<locals>.Obj.__init__   s	     
r)   r    N)rY   rZ   r[   rT   rW   r)   r'   Objrd      s    !r)   rh   z{object.value}r^   zobject.valuerf   r>   N)dictr   r/   r%   r   assertRaisesKeyError)r.   rh   rK   loadedEvents       r'   test_extractingFieldsPostLoadz+SaveLoadTests.test_extractingFieldsPostLoad   ss    	! 	! %5ceD
#D$7$7
$CDnkBCH
 	(L(KH(L(JGr)   c                    g }t        t        t        |j                              }	 ddz   | j                  t        |      d       t        | j                  |d               d   }| j                  |t
               | j                  |j                  t                     | j                  |j                         t               y# t        $ r t               }|j                  d|       Y w xY w)zl
        Round-tripping a failure through L{eventAsJSON} preserves its class and
        structure.
        observerr6   r   za message about failurelog_failureN)r   r
   r   appendZeroDivisionErrorr   failurer%   lenr   r/   r#   
assertTruecheckgetTracebackr$   )r.   eventsr   floadeds        r'   test_failureStructurePreservedz,SaveLoadTests.test_failureStructurePreserved   s    
 "$d<?@	6E 	Va(t226!9=>}Mfg.%678f113S9 ! 	6	AKK115	6s   C %C/.C/c                     t        t        j                        }t        | j	                  |            }| j                  |d   t        j                         y)zo
        It's important that the C{log_level} key remain a
        L{constantly.NamedConstant} object.
        	log_levelr   N)ri   r   warnr   r/   assertIs)r.   rK   rl   s      r'   test_saveLoadLevelz SaveLoadTests.test_saveLoadLevel   s>    
 HMM2
#D$7$7
$CDk+.>r)   c                 R    t        d      }| j                  |t        d             y)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"}}Nr~   )r   r%   ri   )r.   rl   s     r'   test_saveLoadUnknownLevelz'SaveLoadTests.test_saveLoadUnknownLevel   s+    
 $I
 	dT&:;r)   rg   )rY   rZ   r[   __doc__r   r$   r/   r3   r:   r?   rA   rL   ra   rm   r|   r   r   rW   r)   r'   r+   r+   1   sO    	=H 	= 	=E




A&H(:$?	<r)   r+   c                   B    e Zd ZdZd
dZddeddfdZd
dZd
dZd
d	Z	y)FileLogObserverTestsz+
    Tests for L{jsonFileLogObserver}.
    r    Nc                     t               5 }t        |      }	 t        t        |       ddd       y# t        $ r}| j                  |       Y d}~(d}~ww xY w# 1 sw Y   yxY w)zh
        A L{FileLogObserver} returned by L{jsonFileLogObserver} is an
        L{ILogObserver}.
        N)r   r   r   r   r   fail)r.   
fileHandlerp   es       r'   test_interfacez#FileLogObserverTests.test_interface   s]    
 Z 	:*:6H\84	 	 . 		!		 	s+   A1	AAAAAA!recordSeparatorc                     t               5 }t        ||      }t        d      } ||       | j                  |j	                         | d       ddd       y# 1 sw Y   yxY w)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}
        r6   xz	{"x": 1}
N)r   r   ri   r%   getvalue)r.   r   r   rp   r,   s        r'   assertObserverWritesJSONz-FileLogObserverTests.assertObserverWritesJSON   sa     Z 	V:*:GH1IEUOZ0026G|4TU		V 	V 	Vs   AAA!c                 $    | j                          y)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   r2   s    r'   (test_observeWritesDefaultRecordSeparatorz=FileLogObserverTests.test_observeWritesDefaultRecordSeparator   s     	%%'r)   c                 (    | j                  d       y)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{""}.
         r   Nr   r2   s    r'   &test_observeWritesEmptyRecordSeparatorz;FileLogObserverTests.test_observeWritesEmptyRecordSeparator   s     	%%b%9r)   c                     t               }t               }g }|j                  t        t        |j
                               |j                  t        |             t        |      }	 ddz   t        |j                               }t        t        |            }dt        t           ddf fd} ||        ||       y# t        $ r |j                  d       Y ow xY w)	z
        A L{FileLogObserver} created by L{jsonFileLogObserver} writes failures
        serialized as JSON text to a file when it observes events.
        ro   r6   r   zfailed as expected	logEventsr    Nc                 b   j                  t        |       d       | \  }j                  d|       |d   }j                  |t               |j                         }j                  |j                  j                  j                  j                  d      t        j                  d             y )Nr6   rq   co)r%   ru   assertInr#   r   getTracebackObjecttb_framef_codeco_filenamerstrip__file__)r   failureEventfailureObjecttracebackObjectr.   s       r'   checkEventsz@FileLogObserverTests.test_failureFormatting.<locals>.checkEvents  s    S^Q/&N\MM-6(7M!!-9+>>@O((//;;BB4H%r)   )r   r   addObserverr
   r   rr   r   r   BaseExceptionrt   r   listr   r	   r   )r.   io	publisherloggedloggerreaderdeserializedr   s   `       r'   test_failureFormattingz+FileLogObserverTests.test_failureFormatting   s    
 Z N	!#d<?@1"56+	1E "++-(1&9:
	8H#5 
	$ 
	 	FL!%  	1NN/0	1s   (C   CCrg   ))
rY   rZ   r[   r   r   r$   r   r   r   r   rW   r)   r'   r   r      s1    
V V V(:"r)   r   c            	           e Zd ZdZddZddZ	 	 ddee   dee	   de
ddf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y)LogFileReaderTestsz-
    Tests for L{eventsFromJSONLogFile}.
    r    Nc                      g  _         t        t              dt        dd f fd       }| _        t        j                  |       y )Nr,   r    c                 t    | d   t         j                  k(  r!d| v rj                  j                  |        y y y )Nlog_namespacerecord)jsonLog	namespaceerrorEventsrr   )r,   r.   s    r'   rp   z*LogFileReaderTests.setUp.<locals>.observer  s;    _%):)::x5?P  ''. @Q:r)   )r   r   r   r   logObserverr   r   )r.   rp   s   ` r'   setUpzLogFileReaderTests.setUp  sH    +-	\	"	/H 	/ 	/ 
#	/ $&&x0r)   c                 B    t        j                  | j                         y rR   )r   removeObserverr   r2   s    r'   tearDownzLogFileReaderTests.tearDown&  s    ))$*:*:;r)   inFiler   
bufferSizec                     t        t        |||            }| j                  t        |      ddi       | j                  t        |      ddi       | j	                  t
        t        |       y)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}
        r   r6   yr   N)iterr   r%   nextrj   StopIteration)r.   r   r   r   ry   s        r'   _readEventszLogFileReaderTests._readEvents)  sZ     +FOZPQfQx0fQx0-v6r)   c                     t        d      5 }| j                  |       | j                  t        | j                        d       ddd       y# 1 sw Y   yxY w)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%   ru   r   r.   r   s     r'   &test_readEventsAutoWithRecordSeparatorz9LogFileReaderTests.test_readEventsAutoWithRecordSeparator>  sM    
 78 	7JZ(S!1!12A6	7 	7 	7   7AAc                     t        d      5 }| j                  |       | j                  t        | j                        d       ddd       y# 1 sw Y   yxY w)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   s     r'   'test_readEventsAutoEmptyRecordSeparatorz:LogFileReaderTests.test_readEventsAutoEmptyRecordSeparatorG  sM    
 /0 	7JZ(S!1!12A6	7 	7 	7r   c                     t        d      5 }| j                  |d       | j                  t        | j                        d       ddd       y# 1 sw Y   yxY w)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   s     r'   &test_readEventsExplicitRecordSeparatorz9LogFileReaderTests.test_readEventsExplicitRecordSeparatorP  sR     78 	7JZ@S!1!12A6	7 	7 	7   9AAc                     t        d      5 }| j                  |d       | j                  t        | j                        d       ddd       y# 1 sw Y   yxY w)zM
        L{eventsFromJSONLogFile} handles buffering a partial event.
        r   r6   r   r   Nr   r   s     r'   test_readEventsPartialBufferz/LogFileReaderTests.test_readEventsPartialBufferZ  sR     78 	7JZA6S!1!12A6	7 	7 	7r   c                    t        d      5 }t        t        |            }| j                  t	        |      ddi       | j                  t        t        |       | j                  t        | j                        d       | j                  | j                  d   d   d       | j                  | j                  d   d   d	       d
d
d
       y
# 1 sw Y   y
xY w)zF
        If the JSON text for a record is truncated, skip it.
        z{"x": 1{"y": 2}
r   r   r6   r   r_   z0Unable to read truncated JSON record: {record!r}r   s   {"x": 1N	r   r   r   r%   r   rj   r   ru   r   r.   r   ry   s      r'   test_readTruncatedz%LogFileReaderTests.test_readTruncatedc  s     45 	H/
;<FT&\C84mT6: S!1!12A6  #L1B T--a0:JG	H 	H 	H   B6CCc                 &   t        d      5 }t        t        |            }| j                  t	        |      ddi       | j                  t        t        |       | j                  t        | j                        d       ddd       y# 1 sw Y   yxY w)zc
        If the file being read from vends L{str}, strings decode from JSON
        as-is.
        u   {"currency": "€"}
currency   €r   Nr   r   s      r'   test_readUnicodez#LogFileReaderTests.test_readUnicodeu  sz     45 	7/
;<FT&\J+ABmT6:S!1!12A6	7 	7 	7   A2BBc                 &   t        d      5 }t        t        |            }| j                  t	        |      ddi       | j                  t        t        |       | j                  t        | j                        d       ddd       y# 1 sw Y   yxY w)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   rj   r   ru   r   r   s      r'   test_readUTF8Bytesz%LogFileReaderTests.test_readUTF8Bytes  s|     :; 	7z/
;<F T&\J+ABmT6:S!1!12A6	7 	7 	7r   c                 *   t        d      5 }t        t        |d            }| j                  t	        |      ddi       | j                  t        t        |       | j                  t        | j                        d       ddd       y# 1 sw Y   yxY w)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   r   r   r   Nr   r   s      r'   test_readTruncatedUTF8Bytesz.LogFileReaderTests.test_readTruncatedUTF8Bytes  s{     34 	7
/
qIJFT&\C?;mT6:S!1!12A6	7 	7 	7s   A4B		Bc                    t        d      5 }t        t        |            }| j                  t	        |      ddi       | j                  t        t        |       | j                  t        | j                        d       | j                  | j                  d   d   d       | j                  | j                  d   d   d	       d
d
d
       y
# 1 sw Y   y
xY w)zh
        If the JSON text for a record contains invalid UTF-8 text, ignore that
        record.
        s   {"x": ""}
{"y": 2}
r   r   r6   r   r_   z2Unable to decode UTF-8 for JSON record: {record!r}r   s   {"x": ""}
Nr   r   s      r'   test_readInvalidUTF8Bytesz,LogFileReaderTests.test_readInvalidUTF8Bytes  s     AB 	Tj/
;<FT&\C84mT6: S!1!12A6  #L1D T--a0:<RS	T 	T 	Tr   c                    t        d      5 }t        t        |            }| j                  t	        |      ddi       | j                  t        t        |       | j                  t        | j                        d       | j                  | j                  d   d   d       | j                  | j                  d   d   d	       d
d
d
       y
# 1 sw Y   y
xY w)zD
        If the JSON text for a record is invalid, skip it.
        z{"x": }
{"y": 2}
r   r   r6   r   r_   &Unable to read JSON record: {record!r}r   s   {"x": }
Nr   r   s      r'   test_readInvalidJSONz'LogFileReaderTests.test_readInvalidJSON  s     67 	J:/
;<FT&\C84mT6: S!1!12A6  #L18 T--a0:LI	J 	J 	Jr   c                 b   t        d      5 }t        |      }| j                  t        t        |       | j                  t        | j                        d       | j                  | j                  d   d   d       | j                  | j                  d   d   d       ddd       y# 1 sw Y   yxY w)	zI
        Multiple events without a record separator are skipped.
        z{"x": 1}
{"y": 2}
r6   r   r_   r   r   s   {"x": 1}
{"y": 2}
N)r   r   rj   r   r   r%   ru   r   r   s      r'   test_readUnseparatedz'LogFileReaderTests.test_readUnseparated  s     34 	U
*:6FmT6: S!1!12A6  #L18 T--a0:<ST	U 	U 	Us   BB%%B.c                 :   t        d      }t               5 }t        |      } ||       |j                  d       t	        |      }| j                  t        |      |f       | j                  t        | j                        d       ddd       y# 1 sw Y   yxY w)z
        Data written by a L{FileLogObserver} returned by L{jsonFileLogObserver}
        and read by L{eventsFromJSONLogFile} is reconstructed properly.
        r6   r   r   N)	ri   r   r   seekr   r%   tupleru   r   )r.   r,   r   rp   ry   s        r'   test_roundTripz!LogFileReaderTests.test_roundTrip  s    
 q	Z 	7:*:6HUOOOA*:6FU6]UH5S!1!12A6	7 	7 	7s   A1BBrg   )Ni   )rY   rZ   r[   r   r   r   r   r   r   r$   intr   r   r   r   r   r   r   r   r   r   r   r   r   rW   r)   r'   r   r     s    
1< *.	737 "#7 	7
 
7*7777H$777T(J$U"7r)   r   N)0r   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+   r   r   rW   r)   r'   <module>r     s    ! : : & @ . * + # ! ( 0    $( s s  O<H O<dO"8 O"dP7 P7r)   