o
    þâfØÑ  ã                   @   sÞ   d dl Z d dl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
 G dd	„ d	e jƒZG d
d„ de jƒZG dd„ de jƒZG dd„ de jƒZG dd„ de jƒZdd„ Zedkrme jdd dS dS )é    N)Úas_bytes)ÚDummyOptions)ÚDummyProcess)ÚDummyPConfig)ÚDummyLogger)Ú
DummyEventc                   @   sF   e Zd Zdd„ Zdd„ Zdd„ Zdd
d„Zdd„ Zdd„ Zdd„ Z	dS )ÚPDispatcherTestsc                 C   ó   ddl m} |ƒ  d S ©Nr   )Úclear©Úsupervisor.eventsr   ©Úselfr   © r   úT/var/www/html/venv/lib/python3.10/site-packages/supervisor/tests/test_dispatchers.pyÚsetUp   ó   
zPDispatcherTests.setUpc                 C   r	   r
   r   r   r   r   r   ÚtearDown   r   zPDispatcherTests.tearDownc                 C   ó   ddl m} |S )Nr   )ÚPDispatcher)Úsupervisor.dispatchersr   )r   r   r   r   r   Ú_getTargetClass   ó   z PDispatcherTests._getTargetClassNÚstdoutr   c                 C   s   |   ¡ |||ƒS ©N©r   )r   ÚprocessÚchannelÚfdr   r   r   Ú_makeOne   ó   zPDispatcherTests._makeOnec                 C   ó   |   ¡ }|  t|j¡ d S r   )r    ÚassertRaisesÚNotImplementedErrorÚreadable©r   Úinstr   r   r   Útest_readable   ó   zPDispatcherTests.test_readablec                 C   r"   r   )r    r#   r$   Úwritabler&   r   r   r   Útest_writable!   r)   zPDispatcherTests.test_writablec                 C   s   |   ¡ }|  | ¡ d ¡ d S r   )r    ÚassertEqualÚflushr&   r   r   r   Ú
test_flush%   s   zPDispatcherTests.test_flush©Nr   r   )
Ú__name__Ú
__module__Ú__qualname__r   r   r   r    r(   r+   r.   r   r   r   r   r      s    
r   c                   @   s  e Zd Zdd„ Zdd„ Zdd„ ZdGd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&d'„ Zd(d)„ Zd*d+„ Zd,d-„ Zd.d/„ Zd0d1„ Zd2d3„ Zd4d5„ Zd6d7„ Zd8d9„ Zd:d;„ Zd<d=„ Z d>d?„ Z!d@dA„ Z"dBdC„ Z#dDdE„ Z$dFS )HÚPOutputDispatcherTestsc                 C   r	   r
   r   r   r   r   r   r   *   r   zPOutputDispatcherTests.setUpc                 C   r	   r
   r   r   r   r   r   r   .   r   zPOutputDispatcherTests.tearDownc                 C   r   )Nr   )ÚPOutputDispatcher)r   r4   )r   r4   r   r   r   r   2   r   z&POutputDispatcherTests._getTargetClassr   c                 C   s.   ddl m} |j|jdœ}|  ¡ ||| dƒS )Nr   ©Úevents)r   Ústderr)Ú
supervisorr6   ÚProcessCommunicationStdoutEventÚProcessCommunicationStderrEventr   )r   r   r   r6   r   r   r   r    6   s
   ÿzPOutputDispatcherTests._makeOnec                 C   ó8   t ƒ }t|ddƒ}t|ƒ}|  |¡}|  | ¡ d¡ d S ©NÚprocess1ú/bin/process1F©r   r   r   r    r,   r*   ©r   ÚoptionsÚconfigr   Ú
dispatcherr   r   r   r+   =   ó
   
z$POutputDispatcherTests.test_writablec                 C   ó>   t ƒ }t|ddƒ}t|ƒ}|  |¡}d|_|  | ¡ d¡ d S ©Nr=   r>   FT©r   r   r   r    Úclosedr,   r%   r@   r   r   r   Útest_readable_openD   ó   
z)POutputDispatcherTests.test_readable_openc                 C   rE   ©Nr=   r>   TFrG   r@   r   r   r   Útest_readable_closedL   rJ   z+POutputDispatcherTests.test_readable_closedc                 C   ó6   t ƒ }t|ddƒ}t|ƒ}|  |¡}|  t|j¡ d S ©Nr=   r>   ©r   r   r   r    r#   r$   Úhandle_write_eventr@   r   r   r   Útest_handle_write_eventT   ó
   
z.POutputDispatcherTests.test_handle_write_eventc                 C   sP   t ƒ }d|_t|dddd}t|ƒ}|  |¡}|  | ¡ d ¡ |  |jd¡ d S )Nó   abcr=   r>   éd   ©Ústdout_capture_maxbytes)r   Úreadfd_resultr   r   r    r,   Úhandle_read_eventÚoutput_bufferr@   r   r   r   Útest_handle_read_event[   s   ÿ
z-POutputDispatcherTests.test_handle_read_eventc                 C   sh   t ƒ }d|_t|dddd}t|ƒ}|  |¡}|  |j¡ |  | ¡ d ¡ |  |j	d¡ |  
|j¡ d S )Nó    r=   r>   rT   rU   )r   rW   r   r   r    ÚassertFalserH   r,   rX   rY   Ú
assertTruer@   r   r   r   Ú%test_handle_read_event_no_data_closese   s   ÿ
z<POutputDispatcherTests.test_handle_read_event_no_data_closesc                 C   ó`   t ƒ }t|ddƒ}t|ƒ}|  |¡}ztdƒ‚   | ¡  Y |jjd }|  | 	d¡|¡ d S ©NÚtestú/testÚfoor   z,uncaptured python exception, closing channel©
r   r   r   r    Ú
ValueErrorÚhandle_errorÚloggerÚdatar]   Ú
startswith©r   rA   rB   r   rC   Úresultr   r   r   Útest_handle_errorq   ó   

ÿÿz(POutputDispatcherTests.test_handle_errorc                    s¼   t ƒ }t|ddddd}t|ƒ}d|_|  |¡}d|_dd	„ |j_g ‰ ‡ fd
d„}ddlm	} | 
|jj|¡ | ¡  |  tˆ ƒd¡ ˆ d }|  |j|¡ |  |jd¡ |  |jd¡ d S )Nr=   r>   ú/tmp/fooiô  ©Ústdout_logfilerV   i   Tc                   S   s   dS )NÚhallooor   r   r   r   r   Ú<lambda>‡   s    zLPOutputDispatcherTests.test_toggle_capturemode_sends_event.<locals>.<lambda>c                    ó   ˆ   | ¡ d S r   ©Úappend©Úevent©ÚLr   r   Údoit‰   ó   zHPOutputDispatcherTests.test_toggle_capturemode_sends_event.<locals>.doitr   r5   é   rq   )r   r   r   Úpidr    ÚcapturemodeÚ
capturelogÚgetvaluer8   r6   Ú	subscribeÚ
EventTypesÚPROCESS_COMMUNICATIONÚtoggle_capturemoder,   Úlenr   rh   ©r   rA   rB   r   rC   rz   r6   rw   r   rx   r   Ú#test_toggle_capturemode_sends_event~   s(   þ
z:POutputDispatcherTests.test_toggle_capturemode_sends_eventc                 C   sŒ   t ƒ }t|dddd}t|ƒ}|  |¡}| ¡  |  |jjd jd¡ |  |jjd j	d¡ |  |j
jd jd¡ |  |j
jd j	d¡ d S ©Nr=   r>   rn   ©rp   r   T)r   r   r   r    Ú
removelogsr,   Ú	normallogÚhandlersÚreopenedÚremovedÚchildlogr@   r   r   r   Útest_removelogs”   s   ÿ
z&POutputDispatcherTests.test_removelogsc                 C   s`   t ƒ }t|dddd}t|ƒ}|  |¡}| ¡  |  |jjd jd¡ |  |j	jd jd¡ d S rˆ   )
r   r   r   r    Ú
reopenlogsr,   r   rŒ   r   r‹   r@   r   r   r   Útest_reopenlogs    ó   ÿ
z&POutputDispatcherTests.test_reopenlogsc                 C   s„   t ƒ }ddlm} |jj|_t|dddd}t|ƒ}|  |¡}d|_	| 
¡  |  |jjdg¡ |  |jjd d¡ |  |j	d	¡ d S )
Nr   ©Úloggersr=   r>   rn   r‰   Úaz'process1' stdout output:
ar[   ©r   r8   r•   ÚLevelsByNameÚTRACÚloglevelr   r   r    rY   Úrecord_outputr,   r   rh   rg   ©r   rA   r•   rB   r   rC   r   r   r   Ú&test_record_output_log_non_capturemodeª   s   
ÿ
ÿz=POutputDispatcherTests.test_record_output_log_non_capturemodec                    óœ   t ƒ }t|dddd}t|ƒ}|  |d¡}d|_g ‰ ‡ fdd„}d	d
lm} | |jj	|¡ | 
¡  |  tˆ ƒd¡ ˆ d	 }|  |j|¡ |  |jd¡ d S )Nr=   r>   T©Ústdout_events_enabledr   ó   hello from stdoutc                    rs   r   rt   rv   rx   r   r   rz   Ä   r{   zWPOutputDispatcherTests.test_record_output_emits_stdout_event_when_enabled.<locals>.doitr   r5   r|   )r   r   r   r    rY   r8   r6   r   r‚   ÚPROCESS_LOG_STDOUTr›   r,   r…   r   rh   r†   r   rx   r   Ú2test_record_output_emits_stdout_event_when_enabled»   ó    ÿzIPOutputDispatcherTests.test_record_output_emits_stdout_event_when_enabledc                    óx   t ƒ }t|dddd}t|ƒ}|  |d¡}d|_g ‰ ‡ fdd„}d	d
lm} | |jj	|¡ | 
¡  |  tˆ ƒd	¡ d S )Nr=   r>   FrŸ   r   r¡   c                    rs   r   rt   rv   rx   r   r   rz   Ø   r{   z`POutputDispatcherTests.test_record_output_does_not_emit_stdout_event_when_disabled.<locals>.doitr   r5   )r   r   r   r    rY   r8   r6   r   r‚   r¢   r›   r,   r…   ©r   rA   rB   r   rC   rz   r6   r   rx   r   Ú;test_record_output_does_not_emit_stdout_event_when_disabledÏ   ó   ÿzRPOutputDispatcherTests.test_record_output_does_not_emit_stdout_event_when_disabledc                    rž   )Nr=   r>   T©Ústderr_events_enabledr7   ó   hello from stderrc                    rs   r   rt   rv   rx   r   r   rz   é   r{   zWPOutputDispatcherTests.test_record_output_emits_stderr_event_when_enabled.<locals>.doitr   r5   r|   )r   r   r   r    rY   r8   r6   r   r‚   ÚPROCESS_LOG_STDERRr›   r,   r…   r   rh   r†   r   rx   r   Ú2test_record_output_emits_stderr_event_when_enabledà   r¤   zIPOutputDispatcherTests.test_record_output_emits_stderr_event_when_enabledc                    r¥   )Nr=   r>   Fr©   r7   r«   c                    rs   r   rt   rv   rx   r   r   rz   ý   r{   z`POutputDispatcherTests.test_record_output_does_not_emit_stderr_event_when_disabled.<locals>.doitr   r5   )r   r   r   r    rY   r8   r6   r   r‚   r¬   r›   r,   r…   r¦   r   rx   r   Ú;test_record_output_does_not_emit_stderr_event_when_disabledô   r¨   zRPOutputDispatcherTests.test_record_output_does_not_emit_stderr_event_when_disabledc                 C   sx   t ƒ }ddlm} |jj|_t|ddddd}t|ƒ}|  |¡}d|_	| 
¡  |  |jjdg¡ |  |jjd d	¡ d S )
Nr   r”   r=   r>   rn   rT   ro   s!   stdout string longer than a tokenz;'process1' stdout output:
stdout string longer than a tokenr—   rœ   r   r   r   Ú7test_record_output_capturemode_string_longer_than_token  s"   
þ

ÿÿzNPOutputDispatcherTests.test_record_output_capturemode_string_longer_than_tokenc                 C   sZ   t ƒ }t|ddddd}t|ƒ}|  |¡}d|_| ¡  |  |jjg ¡ |  |jd¡ d S )Nr=   r>   rn   rT   ro   r–   )	r   r   r   r    rY   r›   r,   r   rh   r@   r   r   r   Ú;test_record_output_capturemode_string_not_longer_than_token  s   þ
zRPOutputDispatcherTests.test_record_output_capturemode_string_not_longer_than_tokenc                    s–  ddl m} ddl m} g ‰ ‡ fdd„}|||ƒ |j}|j}|d | }tƒ }ddlm} ||_d}	t|d	d
|	dd}
t	|
ƒ}|  
|¡}zh||_| ¡  |  tj |	¡d¡ |  t|jƒd¡ |  tˆ ƒd¡ ˆ d }ddl m} |  |j|¡ |  |j|¡ |  |jd¡ |  |jd¡ W z|j ¡  |j ¡  t |	¡ W d S  ttfy­   Y d S w z|j ¡  |j ¡  t |	¡ W w  ttfyÊ   Y w w )Nr   ©ÚProcessCommunicationEvent©r   c                    rs   r   rt   rv   r5   r   r   rz   -  r{   zJPOutputDispatcherTests.test_stdout_capturemode_single_buffer.<locals>.doits   hello©Ú	getLoggerú/tmp/logr=   r>   iè  ro   r|   ©r9   r   )r   r²   r   ÚBEGIN_TOKENÚ	END_TOKENr   Úsupervisor.loggersrµ   r   r   r    rY   r›   r,   ÚosÚpathÚgetsizer…   r9   Ú	__class__r   r   rh   r   Úcloser   ÚremoveÚOSErrorÚIOError)r   r²   r   rz   r¸   r¹   rh   rA   rµ   ÚlogfilerB   r   rC   rw   r9   r   r5   r   Ú%test_stdout_capturemode_single_buffer'  sX   
þ


ÿü

ÿz<POutputDispatcherTests.test_stdout_capturemode_single_bufferc                    sN  ddl m} ddl m} g ‰ ‡ fdd„}|||ƒ dd l}tt|d|jƒƒ}t|jƒd }|j}|j	}|| | | | }	d}
|	 
|
¡}|d |
 }|d	 |
 }|d
 }tƒ }ddlm} ||_d}t|dd|dd}t|ƒ}|  |¡}z||_| ¡  dd„ |jjD ƒ t|dƒ}|  | ¡ |¡ W d   ƒ n1 sžw   Y  |  |j|t|ƒd … ¡ |  tˆ ƒd¡ | j|7  _| ¡  |  tˆ ƒd¡ dd„ |jjD ƒ t|dƒ}|  | ¡ |¡ W d   ƒ n1 sìw   Y  |  |j|t|ƒd … ¡ |  tˆ ƒd¡ | j|7  _| ¡  dd„ |jjD ƒ t|dƒ}|  | ¡ |d
 ¡ W d   ƒ n	1 s5w   Y  |  tˆ ƒd	¡ ˆ d }ddl m} |  |j|¡ |  |j|¡ |  |jd¡ |  |j|¡ W z|j ¡  |j ¡  t  !|¡ W d S  t"t#fyˆ   Y d S w z|j ¡  |j ¡  t  !|¡ W w  t"t#fy¦   Y w w )Nr   r±   r³   c                    rs   r   rt   rv   r5   r   r   rz   W  r{   zMPOutputDispatcherTests.test_stdout_capturemode_multiple_buffers.<locals>.doitÚlettersé   ó   :r|   é   r´   r¶   r=   r>   i'  ro   c                 S   ó   g | ]}|  ¡ ‘qS r   ©r-   ©Ú.0Úxr   r   r   Ú
<listcomp>u  ó    zSPOutputDispatcherTests.test_stdout_capturemode_multiple_buffers.<locals>.<listcomp>Úrbc                 S   rÉ   r   rÊ   rË   r   r   r   rÎ   ~  rÏ   c                 S   rÉ   r   rÊ   rË   r   r   r   rÎ   †  rÏ   r·   r   )$r   r²   r   Ústringr   ÚgetattrÚascii_lettersÚdigitsr¸   r¹   Úsplitr   rº   rµ   r   r   r    rY   r›   r   rŒ   Úopenr,   Úreadr…   r9   r¾   r   r   rh   r   r¿   r»   rÀ   rÁ   rÂ   )r   r²   r   rz   rÑ   rÅ   rÔ   r¸   r¹   rh   ÚcolonÚbrokenÚfirstÚsecondÚthirdrA   rµ   rÃ   rB   r   rC   Úfrw   r9   r   r5   r   Ú(test_stdout_capturemode_multiple_buffersS  sŽ   

þ
ÿÿÿ

ÿü

ÿz?POutputDispatcherTests.test_stdout_capturemode_multiple_buffersc                 C   s¬   t ƒ }d|_t|dddd}t|ƒ}|  |¡}d}d}||_| ¡  |  t|j	j
ƒd¡ |  |j	j
d	 |¡ d
|_||_| ¡  |  t|j	j
ƒd¡ |  |j	j
d |¡ d S ©NTr=   r>   rn   r‰   ó4   [34mHello world... this is longer than a token![0mó+   Hello world... this is longer than a token!r|   r   FrÈ   )r   Ú
strip_ansir   r   r    rY   r›   r,   r…   r   rh   ©r   rA   rB   r   rC   ÚansiÚnoansir   r   r   Útest_strip_ansi™  ó$   ÿ
z&POutputDispatcherTests.test_strip_ansic                 C   s|   t ƒ }t|ddƒ}t|ƒ}|  |¡}|  |j|¡ |  |jd¡ |  |jd¡ |  |jd ¡ |  |j	d ¡ |  |j
d ¡ d S ©Nr=   r>   r   r   )r   r   r   r    r,   r   r   r   r   r‹   r   r@   r   r   r   Útest_ctor_no_logfiles¯  s   
z,POutputDispatcherTests.test_ctor_no_logfilesc                 C   s„   t ƒ }t|dddd}t|ƒ}|  |¡}|  |j|¡ |  |jd¡ |  |jd¡ |  |jd ¡ |  |j	j
t¡ |  |j|j	¡ d S ©Nr=   r>   rn   r‰   r   r   )r   r   r   r    r,   r   r   r   r   r‹   r¾   r   r   r@   r   r   r   Útest_ctor_logfile_only»  s   ÿ
z-POutputDispatcherTests.test_ctor_logfile_onlyc                 C   s‚   t ƒ }t|dddd}t|ƒ}|  |¡}|  |j|¡ |  |jd¡ |  |jd¡ |  |jj	t
¡ |  |jd ¡ |  |jd ¡ d S )Nr=   r>   i,  rU   r   r   )r   r   r   r    r,   r   r   r   r   r¾   r   r‹   r   r@   r   r   r   Útest_ctor_capturelog_onlyÈ  s   ÿ
z0POutputDispatcherTests.test_ctor_capturelog_onlyc                 C   st   ddl m} tƒ }t|dd|dƒd}t|ƒ}|  |¡}|  |j|¡ |  |jd¡ |  |j	d¡ |  |j
d ¡ d S )Nr   )Úlogfile_namer=   r>   Ú r‰   r   )Úsupervisor.datatypesrí   r   r   r   r    r,   r   r   r   r‹   )r   rí   rA   rB   r   rC   r   r   r   Ú(test_ctor_stdout_logfile_is_empty_stringÕ  s   ÿ
z?POutputDispatcherTests.test_ctor_stdout_logfile_is_empty_stringc                 C   s~   ddl m}m} tƒ }t|dd|dƒ|dƒd}t|ƒ}|  |¡}|  |j|¡ |  |j	d¡ |  |j
d¡ |  |jd ¡ d S )	Nr   ©Úbooleanrí   r=   r>   ÚNONEÚfalse©rp   Ústdout_syslogr   )rï   rò   rí   r   r   r   r    r,   r   r   r   r‹   )r   rò   rí   rA   rB   r   rC   r   r   r   Ú5test_ctor_stdout_logfile_none_and_stdout_syslog_falseá  s   þ
zLPOutputDispatcherTests.test_ctor_stdout_logfile_none_and_stdout_syslog_falsec           
      C   s¾   ddl m}m} ddlm}m} ddlm} |ƒ }|j|_	t
|dd|dƒ|dƒd	}t|ƒ}|  |¡}	|  |	j|¡ |  |	jd
¡ |  |	jd¡ |  t|	jjƒd¡ |  |	jjd j|¡ d S )Nr   rñ   )r˜   ÚSyslogHandler©ÚServerOptionsr=   r>   ró   Útruerõ   r   r|   )rï   rò   rí   rº   r˜   rø   Úsupervisor.optionsrú   r™   rš   r   r   r    r,   r   r   r   r…   r‹   rŒ   r¾   )
r   rò   rí   r˜   rø   rú   rA   rB   r   rC   r   r   r   Ú4test_ctor_stdout_logfile_none_and_stdout_syslog_trueî  s$   þ
ÿzKPOutputDispatcherTests.test_ctor_stdout_logfile_none_and_stdout_syslog_truec           
      C   sÈ   ddl m}m} ddlm}m} ddlm} |ƒ }|j|_	t
|dd|dƒ|dƒd	}t|ƒ}|  |¡}	|  |	j|¡ |  |	jd
¡ |  |	jd¡ |  t|	jjƒd¡ |  |	jjd j|¡ |	j ¡  d S )Nr   rñ   )ÚFileHandlerr˜   rù   r=   r>   rn   rô   rõ   r   r|   )rï   rò   rí   rº   rþ   r˜   rü   rú   r™   rš   r   r   r    r,   r   r   r   r…   r‹   rŒ   r¾   r¿   )
r   rò   rí   rþ   r˜   rú   rA   rB   r   rC   r   r   r   Ú4test_ctor_stdout_logfile_str_and_stdout_syslog_false   s"   þ
zKPOutputDispatcherTests.test_ctor_stdout_logfile_str_and_stdout_syslog_falsec           	         sö   ddl m}m} ddlm‰ m}m‰ ddlm} |ƒ }|j	|_
t|dd|dƒ|dƒd	}t|ƒ}|  |¡}|  |j|¡ |  |jd
¡ |  |jd¡ |  t|jjƒd¡ |  t‡ fdd„|jjD ƒƒ¡ |  t‡fdd„|jjD ƒƒ¡ |j ¡  d S )Nr   rñ   )rþ   r˜   rø   rù   r=   r>   rn   rû   rõ   r   rÈ   c                 3   ó    | ]}t |ˆ ƒV  qd S r   ©Ú
isinstance©rÌ   Úh)rþ   r   r   Ú	<genexpr>!  ó   € z]POutputDispatcherTests.test_ctor_stdout_logfile_str_and_stdout_syslog_true.<locals>.<genexpr>c                 3   r   r   r  r  )rø   r   r   r  #  r  )rï   rò   rí   rº   rþ   r˜   rø   rü   rú   r™   rš   r   r   r    r,   r   r   r   r…   r‹   rŒ   r]   Úanyr¿   )	r   rò   rí   r˜   rú   rA   rB   r   rC   r   )rþ   rø   r   Ú3test_ctor_stdout_logfile_str_and_stdout_syslog_true  s,   þ

ÿ
ÿzJPOutputDispatcherTests.test_ctor_stdout_logfile_str_and_stdout_syslog_truec                 C   ób   t ƒ }t|ddƒ}t|ƒ}|  |¡}t|ƒ}|  d|v ¡ |  | d¡d¡ |  | d¡|¡ d S )Nr=   r>   r4   ú"supervisor.tests.base.DummyProcesséÿÿÿÿú	(stdout)>©	r   r   r   r    Úreprr]   ÚassertNotEqualÚfindÚendswith©r   rA   rB   r   rC   Údreprr   r   r   Ú	test_repr'  ó   
þz POutputDispatcherTests.test_reprc                 C   óT   t ƒ }t|ddƒ}t|ƒ}|  |¡}| ¡  |  |jd¡ | ¡  |  |jd¡ d S ©Nr=   r>   T©r   r   r   r    r¿   r,   rH   r@   r   r   r   Ú
test_close3  ó   
z!POutputDispatcherTests.test_closeN)r   )%r0   r1   r2   r   r   r   r    r+   rI   rL   rQ   rZ   r^   rl   r‡   r   r’   r   r£   r§   r­   r®   r¯   r°   rÄ   rÞ   ræ   ré   rë   rì   rð   r÷   rý   rÿ   r  r  r  r   r   r   r   r3   )   sF    


,Fr3   c                   @   sŒ   e 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d„ Zdd „ Zd!S )"ÚPInputDispatcherTestsc                 C   r   )Nr   )ÚPInputDispatcher)r   r  )r   r  r   r   r   r   ?  r   z%PInputDispatcherTests._getTargetClassc                 C   ó   d}|   ¡ ||dƒS )NÚstdinr   r   ©r   r   r   r   r   r   r    C  ó   zPInputDispatcherTests._makeOnec                 C   ó2   t d ƒ}|  |¡}d|_d|_|  | ¡ d¡ d S )Nr–   FT©r   r    Úinput_bufferrH   r,   r*   ©r   r   rC   r   r   r   Útest_writable_open_nodataG  ó
   
z/PInputDispatcherTests.test_writable_open_nodatac                 C   s2   t d ƒ}|  |¡}d|_d|_|  | ¡ d¡ d S )Nrî   Fr"  r$  r   r   r   Útest_writable_open_withdataN  r&  z1PInputDispatcherTests.test_writable_open_withdatac                 C   r!  )Nr–   TFr"  r$  r   r   r   Útest_writable_closed_nodataU  r&  z1PInputDispatcherTests.test_writable_closed_nodatac                 C   r!  )Nrî   TFr"  r$  r   r   r   Útest_writable_closed_withdata\  r&  z3PInputDispatcherTests.test_writable_closed_withdatac                 C   s&   t d ƒ}|  |¡}|  | ¡ d¡ d S )NF)r   r    r,   r%   r$  r   r   r   r(   c  s   
z#PInputDispatcherTests.test_readablec                 C   sP   t ƒ }t|ddƒ}t|ƒ}|  |¡}d|_|  | ¡ d ¡ |  |jd d¡ d S )Nr=   r>   Úhalloooor   )r   r   r   r    r#  r,   rP   Úwrittenr@   r   r   r   rQ   h  s   
z-PInputDispatcherTests.test_handle_write_eventc                 C   sZ   t ƒ }t|ddƒ}t|ƒ}|  |¡}|  |jd¡ | ¡  |  |jd¡ |  |ji ¡ d S )Nra   rb   r[   )r   r   r   r    r,   r#  rP   r+  r@   r   r   r   Útest_handle_write_event_nodataq  s   
z4PInputDispatcherTests.test_handle_write_event_nodatac                 C   s’   t ƒ }t|ddƒ}t|ƒ}|  |¡}d|_dd l}t|jt 	|j¡ƒ|_
| ¡  |  |jd¡ |  |jjd  d¡¡ |  |jjd  d¡¡ d S )Nra   rb   r*  r   r[   zfd 0 closed, stopped monitoringú(stdin)>)r   r   r   r    r#  ÚerrnorÁ   ÚEPIPEr»   ÚstrerrorÚwrite_exceptionrP   r,   r]   rg   rh   ri   r  ©r   rA   rB   r   rC   r.  r   r   r   Ú$test_handle_write_event_epipe_raised{  s   

ÿÿz:PInputDispatcherTests.test_handle_write_event_epipe_raisedc                 C   sZ   t ƒ }t|ddƒ}t|ƒ}|  |¡}d|_dd l}t|jt 	|j¡ƒ|_
|  t|j¡ d S )Nra   rb   r*  r   )r   r   r   r    r#  r.  rÁ   ÚEBADFr»   r0  r1  r#   rP   r2  r   r   r   Ú'test_handle_write_event_uncaught_raisedŠ  s   

ÿz=PInputDispatcherTests.test_handle_write_event_uncaught_raisedc                 C   s`   t ƒ }t|ddƒ}t|ƒ}|  |¡}d|_d|_| ¡  |  t|jƒd¡ |  |j	d d¡ d S )Nra   rb   r|   Ú2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaé1   r   r–   )
r   r   r   r    Úwrite_acceptr#  rP   r,   r…   r+  r@   r   r   r   Ú%test_handle_write_event_over_os_limit•  s   
z;PInputDispatcherTests.test_handle_write_event_over_os_limitc                 C   s$   t d ƒ}|  |¡}|  t|j¡ d S r   )r   r    r#   r$   rX   r$  r   r   r   rZ      s   
z,PInputDispatcherTests.test_handle_read_eventc                 C   r_   r`   rd   rj   r   r   r   rl   ¥  rm   z'PInputDispatcherTests.test_handle_errorc                 C   r	  )Nr=   r>   r  r
  r  r-  r  r  r   r   r   r  ²  r  zPInputDispatcherTests.test_reprc                 C   r  r  r  r@   r   r   r   r  ¾  r  z PInputDispatcherTests.test_closeN)r0   r1   r2   r   r    r%  r'  r(  r)  r(   rQ   r,  r3  r5  r9  rZ   rl   r  r  r   r   r   r   r  >  s"    	
r  c                   @   s  e 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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/d0„ Zd1d2„ Zd3d4„ Zd5d6„ Zd7d8„ Zd9d:„ Zd;d<„ Z d=d>„ Z!d?d@„ Z"dAdB„ Z#dCdD„ Z$dES )FÚPEventListenerDispatcherTestsc                 C   r	   r
   r   r   r   r   r   r   É  r   z#PEventListenerDispatcherTests.setUpc                 C   r	   r
   r   r   r   r   r   r   Í  r   z&PEventListenerDispatcherTests.tearDownc                 C   r   )Nr   )ÚPEventListenerDispatcher)r   r;  )r   r;  r   r   r   r   Ñ  r   z-PEventListenerDispatcherTests._getTargetClassc                 C   r  r/   r   r  r   r   r   r    Õ  r   z&PEventListenerDispatcherTests._makeOnec                 C   r;   r<   r?   r@   r   r   r   r+   Ù  rD   z+PEventListenerDispatcherTests.test_writablec                 C   rE   rF   rG   r@   r   r   r   rI   à  rJ   z0PEventListenerDispatcherTests.test_readable_openc                 C   rE   rK   rG   r@   r   r   r   rL   è  rJ   z2PEventListenerDispatcherTests.test_readable_closedc                 C   rM   rN   rO   r@   r   r   r   rQ   ð  rR   z5PEventListenerDispatcherTests.test_handle_write_eventc                 C   s    t ƒ }t|dddd}t|ƒ}ddlm} |j|_|  |¡}|j|_	|  
| ¡ d ¡ |  
|j|j¡ |  
|jd¡ |  
t|jjƒd¡ |  
|jjd |j¡ d S )	Nr=   r>   rn   r‰   r   ©ÚEventListenerStatesr[   r|   )r   r   r   r   r=  ÚACKNOWLEDGEDÚlistener_stater    ÚREADY_FOR_EVENTS_TOKENrW   r,   rX   ÚREADYÚstate_bufferr…   r   rh   ©r   rA   rB   r   r=  rC   r   r   r   Ú9test_handle_read_event_calls_handle_listener_state_change÷  s    ÿ
ÿzWPEventListenerDispatcherTests.test_handle_read_event_calls_handle_listener_state_changec                 C   sj   t ƒ }d|_t|ddƒ}t|ƒ}|  |¡}|  | ¡ d ¡ |  |jd¡ ddlm	} |  |j
j|j¡ d S )Nrî   r=   r>   r[   r   r<  )r   rW   r   r   r    r,   rX   rB  r   r=  r   r?  r>  )r   rA   rB   r   rC   r=  r   r   r   Útest_handle_read_event_nodata  s   

ÿz;PEventListenerDispatcherTests.test_handle_read_event_nodatac                 C   sL   t ƒ }d|_t|ddƒ}t|ƒ}|  |¡}|  | ¡ d ¡ |  |jd ¡ d S )Nó"   supercalifragilisticexpialidociousr=   r>   )r   rW   r   r   r    r,   rX   r   r@   r   r   r   Ú%test_handle_read_event_logging_nologs  s   
zCPEventListenerDispatcherTests.test_handle_read_event_logging_nologsc                 C   sj   t ƒ }d|_t|dddd}t|ƒ}|  |¡}|  | ¡ d ¡ |  t|jj	ƒd¡ |  |jj	d d¡ d S )NrF  r=   r>   rn   r‰   r|   r   )
r   rW   r   r   r    r,   rX   r…   r   rh   r@   r   r   r   Ú'test_handle_read_event_logging_childlog  s   ÿ
ÿzEPEventListenerDispatcherTests.test_handle_read_event_logging_childlogc                 C   s€   t ƒ }t|ddƒ}t|ƒ}ddlm} |  |¡}|j|_d|_|  	| 
¡ d ¡ |  	|jd¡ |  	|jjg ¡ |  	|j|j¡ d S )Nr=   r>   r   r<  s   whateverr[   )r   r   r   r   r=  r    ÚUNKNOWNr?  rB  r,   Úhandle_listener_state_changerg   rh   rC  r   r   r   Ú.test_handle_listener_state_change_from_unknown*  s   
zLPEventListenerDispatcherTests.test_handle_listener_state_change_from_unknownc                 C   s„   t ƒ }t|ddƒ}t|ƒ}ddlm} |  |¡}|j|_d|_|  	| 
¡ d ¡ |  	|jd¡ |  	|jjd d¡ |  	|j|j¡ d S )Nr=   r>   r   r<  s   READY
r[   úprocess1: ACKNOWLEDGED -> READY)r   r   r   r   r=  r    r>  r?  rB  r,   rJ  rg   rh   rA  rC  r   r   r   Ú7test_handle_listener_state_change_acknowledged_to_ready7  s   
ÿzUPEventListenerDispatcherTests.test_handle_listener_state_change_acknowledged_to_readyc                 C   ó˜   t ƒ }t|ddƒ}t|ƒ}ddlm} |  |¡}|j|_d|_|  	| 
¡ d ¡ |  	|jd¡ |  	|jjd d¡ |  	|jjd d	¡ |  	|j|j¡ d S )
Nr=   r>   r   r<  s   READY
garbage
r[   rL  r|   úprocess1: READY -> UNKNOWN©r   r   r   r   r=  r    r>  r?  rB  r,   rJ  rg   rh   rI  rC  r   r   r   Ú6test_handle_listener_state_change_acknowledged_gobblesE  s    
ÿÿzTPEventListenerDispatcherTests.test_handle_listener_state_change_acknowledged_gobblesc                 C   s€   t ƒ }t|ddƒ}t|ƒ}ddlm} |  |¡}|j|_d|_|  	| 
¡ d ¡ |  	|jd¡ |  	|jjg ¡ |  	|j|j¡ d S )Nr=   r>   r   r<  s   RE)r   r   r   r   r=  r    r>  r?  rB  r,   rJ  rg   rh   rC  r   r   r   Ú>test_handle_listener_state_change_acknowledged_to_insufficientU  s   
ÿz\PEventListenerDispatcherTests.test_handle_listener_state_change_acknowledged_to_insufficientc                 C   rN  )
Nr=   r>   r   r<  ó   bogus data yor[   ú!process1: ACKNOWLEDGED -> UNKNOWNr|   ú‘process1: has entered the UNKNOWN state and will no longer receive events, this usually indicates the process violated the eventlistener protocolrP  rC  r   r   r   Ú9test_handle_listener_state_change_acknowledged_to_unknownc  ó    
ÿÿzWPEventListenerDispatcherTests.test_handle_listener_state_change_acknowledged_to_unknownc                 C   rN  )
Nr=   r>   r   r<  rS  r[   rO  r|   rU  )r   r   r   r   r=  r    rA  r?  rB  r,   rJ  rg   rh   rI  rC  r   r   r   Ú2test_handle_listener_state_change_ready_to_unknownu  rW  zPPEventListenerDispatcherTests.test_handle_listener_state_change_ready_to_unknownc                 C   sp   t ƒ }t|ddƒ}t|ƒ}ddlm} |  |¡}|j|_d|_|  	| 
¡ d ¡ |  	|jd¡ |  	|j|j¡ d S )Nr=   r>   r   r<  rS  )r   r   r   r   r=  r    ÚBUSYr?  rB  r,   rJ  rC  r   r   r   Ú6test_handle_listener_state_change_busy_to_insufficient‡  s   
zTPEventListenerDispatcherTests.test_handle_listener_state_change_busy_to_insufficientc                 C   óÎ   t ƒ }t|ddƒ}t|ƒ}ddlm} |  |¡}|j|_G dd„ dƒ}|ƒ |_|ƒ |j_	ddlm
} ||jj	_d|_|  | ¡ d ¡ |  |jd	¡ |  |jjd d
¡ |  |jjd d¡ |  |j|j¡ d S )Nr=   r>   r   r<  c                   @   ó   e Zd ZdS )ziPEventListenerDispatcherTests.test_handle_listener_state_change_busy_to_acknowledged_procd.<locals>.DummyN©r0   r1   r2   r   r   r   r   ÚDummyš  ó    r^  ©Údefault_handlers   RESULT 2
OKabcrS   úprocess1: event was processedr|   úprocess1: BUSY -> ACKNOWLEDGED©r   r   r   r   r=  r    rY  r?  ÚgrouprB   ra  Úresult_handlerrB  r,   rJ  rg   rh   r>  ©r   rA   rB   r   r=  rC   r^  ra  r   r   r   Ú<test_handle_listener_state_change_busy_to_acknowledged_procd“  ó.   


ÿÿÿzZPEventListenerDispatcherTests.test_handle_listener_state_change_busy_to_acknowledged_procdc                 C   r[  )Nr=   r>   r   r<  c                   @   r\  )zlPEventListenerDispatcherTests.test_handle_listener_state_change_busy_to_acknowledged_rejected.<locals>.DummyNr]  r   r   r   r   r^  ±  r_  r^  r`  s   RESULT 4
FAILabcrS   úprocess1: event was rejectedr|   rc  rd  rg  r   r   r   Ú?test_handle_listener_state_change_busy_to_acknowledged_rejectedª  ri  z]PEventListenerDispatcherTests.test_handle_listener_state_change_busy_to_acknowledged_rejectedc           
         s  ddl m} ddl m} g ‰ ‡ fdd„}|||ƒ tƒ }t|ddƒ}t|ƒ}ddlm} |  |¡}|j	|_
tƒ }	|	|_d	|_|  | ¡ d ¡ |  |jd
¡ |  |jjd d¡ |  |jjd d¡ |  |jjd d¡ |  |j
|j¡ |  ˆ d j|¡ |  ˆ d j|	¡ d S )Nr   )ÚEventRejectedEventr³   c                    rs   r   rt   rv   r5   r   r   rz   Å  r{   z]PEventListenerDispatcherTests.test_handle_listener_state_change_busy_to_unknown.<locals>.doitr=   r>   r<  s   bogus data
r[   z'process1: bad result line: 'bogus data'r|   úprocess1: BUSY -> UNKNOWNrÈ   rU  )r   rl  r   r   r   r   r   r=  r    rY  r?  r   rw   rB  r,   rJ  rg   rh   rI  r   )
r   rl  r   rz   rA   rB   r   r=  rC   Úcurrent_eventr   r5   r   Ú1test_handle_listener_state_change_busy_to_unknownÁ  s<   

ÿÿÿÿzOPEventListenerDispatcherTests.test_handle_listener_state_change_busy_to_unknownc                 C   sö   t ƒ }t|ddƒ}t|ƒ}ddlm} |  |¡}|j|_G dd„ dƒ}|ƒ |_|ƒ |j_	ddlm
} ||jj	_d|_|  | ¡ d ¡ |  |jd	¡ |  |jjd d
¡ |  |jjd d¡ |  |jjd d¡ |  |jjd d¡ |  |j|j¡ d S )Nr=   r>   r   r<  c                   @   r\  )zTPEventListenerDispatcherTests.test_handle_listener_state_busy_gobbles.<locals>.DummyNr]  r   r   r   r   r^  ç  r_  r^  r`  s   RESULT 2
OKbogus data
r[   rb  r|   rc  rÈ   rT  é   rU  )r   r   r   r   r=  r    rY  r?  re  rB   ra  rf  rB  r,   rJ  rg   rh   rI  rg  r   r   r   Ú'test_handle_listener_state_busy_gobblesà  s:   


ÿÿÿÿÿzEPEventListenerDispatcherTests.test_handle_listener_state_busy_gobblesc                    sô   ddl m} tƒ }t|ddƒ}t|ƒ}g ‰ ‡ fdd„}ddlm} ||j|ƒ ddlm	} |  
|¡}d	d
„ }	G dd„ dƒ}
|
ƒ |_|
ƒ |j_|	|jj_|j|_| d¡ |  tˆ ƒd¡ |  |j|j¡ |  |jjd d¡ |  |jjd d¡ d S )Nr   r³   r=   r>   c                    rs   r   rt   rv   rx   r   r   rz     r{   zEPEventListenerDispatcherTests.test_handle_result_accept.<locals>.doitr5   r<  c                 S   s   d S r   r   ©rw   rk   r   r   r   Úhandle	  ó   zGPEventListenerDispatcherTests.test_handle_result_accept.<locals>.handlec                   @   r\  )zFPEventListenerDispatcherTests.test_handle_result_accept.<locals>.DummyNr]  r   r   r   r   r^    r_  r^  rc   rb  r|   rc  )r   r   r   r   r   r8   r6   rl  r   r=  r    re  rB   rf  rY  r?  Úhandle_resultr,   r…   r>  rg   rh   )r   r   rA   rB   r   rz   r6   r=  rC   rs  r^  r   rx   r   Útest_handle_result_acceptý  s6   



ÿÿÿz7PEventListenerDispatcherTests.test_handle_result_acceptc                    s  ddl m} tƒ }t|ddƒ}t|ƒ}g ‰ ‡ fdd„}ddlm} ||j|ƒ ddlm	} |  
|¡}d	d
„ }	G dd„ dƒ}
|
ƒ |_|
ƒ |j_|	|jj_|j|_| d¡ |  tˆ ƒd¡ |  ˆ d j|j¡ |  |j|j¡ |  |jjd d¡ |  |jjd d¡ d S )Nr   r³   r=   r>   c                    rs   r   rt   rv   rx   r   r   rz      r{   zJPEventListenerDispatcherTests.test_handle_result_rejectevent.<locals>.doitr5   r<  c                 S   s   ddl m} ||ƒ‚)Nr   )ÚRejectEvent)r   rw  )rw   rk   rw  r   r   r   Úrejected&  ó   zNPEventListenerDispatcherTests.test_handle_result_rejectevent.<locals>.rejectedc                   @   r\  )zKPEventListenerDispatcherTests.test_handle_result_rejectevent.<locals>.DummyNr]  r   r   r   r   r^  )  r_  r^  rc   r|   rj  rc  )r   r   r   r   r   r8   r6   rl  r   r=  r    re  rB   rf  rY  r?  ru  r,   r…   r¾   r>  rg   rh   )r   r   rA   rB   r   rz   r6   r=  rC   rx  r^  r   rx   r   Útest_handle_result_rejectevent  s8   



ÿÿÿz<PEventListenerDispatcherTests.test_handle_result_rejecteventc                    s$  ddl m} tƒ }t|ddƒ}t|ƒ}g ‰ ‡ fdd„}ddlm} ||j|ƒ ddlm	} |  
|¡}d	d
„ }	G dd„ dƒ}
|
ƒ |_|
ƒ |j_|	|jj_|	|j_|j|_| d¡ |  tˆ ƒd¡ |  ˆ d j|j¡ |  |j|j¡ |  |jjd d¡ |  |jjd d¡ |  |jjd d¡ d S )Nr   r³   r=   r>   c                    rs   r   rt   rv   rx   r   r   rz   ?  r{   zHPEventListenerDispatcherTests.test_handle_result_exception.<locals>.doitr5   r<  c                 S   s   t ‚r   )re   rr  r   r   r   Ú	exceptionE  rt  zMPEventListenerDispatcherTests.test_handle_result_exception.<locals>.exceptionc                   @   r\  )zIPEventListenerDispatcherTests.test_handle_result_exception.<locals>.DummyNr]  r   r   r   r   r^  G  r_  r^  rc   r|   zprocess1: event caused an errorrm  rÈ   rU  )r   r   r   r   r   r8   r6   rl  r   r=  r    re  rB   rf  rY  r?  ru  r,   r…   r¾   rI  rg   rh   )r   r   rA   rB   r   rz   r6   r=  rC   r{  r^  r   rx   r   Útest_handle_result_exception9  s@   



ÿÿÿÿz:PEventListenerDispatcherTests.test_handle_result_exceptionc                 C   r_   r`   rd   rj   r   r   r   rl   \  rm   z/PEventListenerDispatcherTests.test_handle_errorc                 C   s`   t ƒ }t|dddd}t|ƒ}|  |¡}| ¡  |  |jjd jd¡ |  |jjd j	d¡ d S rˆ   )
r   r   r   r    rŠ   r,   r   rŒ   r   rŽ   r@   r   r   r   r   i  r“   z-PEventListenerDispatcherTests.test_removelogsc                 C   sJ   t ƒ }t|dddd}t|ƒ}|  |¡}| ¡  |  |jjd jd¡ d S rˆ   )	r   r   r   r    r‘   r,   r   rŒ   r   r@   r   r   r   r’   s  s   ÿ
z-PEventListenerDispatcherTests.test_reopenlogsc                 C   s¬   t ƒ }d|_t|dddd}t|ƒ}|  |¡}d}d}||_| ¡  |  t|j	j
ƒd¡ |  |j	j
d	 |¡ d
|_||_| ¡  |  t|j	j
ƒd¡ |  |j	j
d |¡ d S rß   )r   râ   r   r   r    rW   rX   r,   r…   r   rh   rã   r   r   r   ræ   |  rç   z-PEventListenerDispatcherTests.test_strip_ansic                 C   s`   t ƒ }t|ddƒ}t|ƒ}|  |¡}|  |j|¡ |  |jd¡ |  |jd¡ |  |jd ¡ d S rè   )	r   r   r   r    r,   r   r   r   r   r@   r   r   r   Útest_ctor_nologfiles’  s   
z2PEventListenerDispatcherTests.test_ctor_nologfilesc                 C   sf   t ƒ }t|dddd}t|ƒ}|  |¡}|  |j|¡ |  |jd¡ |  |jd¡ |  |jj	t
¡ d S rê   )r   r   r   r    r,   r   r   r   r   r¾   r   r@   r   r   r   rë   œ  s   ÿ
z4PEventListenerDispatcherTests.test_ctor_logfile_onlyc                 C   r	  )Nr=   r>   r;  r
  r  r  r  r  r   r   r   r  §  r  z'PEventListenerDispatcherTests.test_reprc                 C   r  r  r  r@   r   r   r   r  ³  r  z(PEventListenerDispatcherTests.test_closeN)%r0   r1   r2   r   r   r   r    r+   rI   rL   rQ   rD  rE  rG  rH  rK  rM  rQ  rR  rV  rX  rZ  rh  rk  ro  rq  rv  rz  r|  rl   r   r’   ræ   r}  rë   r  r  r   r   r   r   r:  È  sF    #
	
r:  c                   @   s,   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	S )
ÚstripEscapeTestsc                 C   s   ddl m} ||ƒS )Nr   )ÚstripEscapes)r   r  )r   Úsr  r   r   r   Ú_callFUT¿  ry  zstripEscapeTests._callFUTc                 C   s   |   |  d¡d¡ d S )Nr[   ©r,   r  )r   r   r   r   Útest_zero_length_stringÃ  s   z(stripEscapeTests.test_zero_length_stringc                 C   s   d}d}|   |  |¡|¡ d S )Nrà   rá   r‚  )r   rä   rå   r   r   r   Ú	test_ansiÆ  s   zstripEscapeTests.test_ansic                 C   s   d}|   |  |¡|¡ d S )Nrá   r‚  )r   rå   r   r   r   Útest_noansiË  s   zstripEscapeTests.test_noansiN)r0   r1   r2   r  rƒ  r„  r…  r   r   r   r   r~  ¾  s
    r~  c                   C   s   t  tjt ¡S r   )ÚunittestÚfindTestCasesÚsysÚmodulesr0   r   r   r   r   Ú
test_suiteÏ  r!   rŠ  Ú__main__)ÚdefaultTest)r†  r»   rˆ  Úsupervisor.compatr   Úsupervisor.tests.baser   r   r   r   r   ÚTestCaser   r3   r  r:  r~  rŠ  r0   Úmainr   r   r   r   Ú<module>   s4            yÿ