o
    ¯b@5  ã                   @   s¸   d Z ddlZddlZddlZddlZddlZddlmZ ddlm	Z	m
Z
mZmZ ddlmZ ddlmZ ddlmZ ddlmZmZ G d	d
„ d
eƒZG dd„ deƒZG dd„ deƒZdS )zD
Test running processes with the APIs in L{twisted.internet.utils}.
é    N)ÚskipIf)ÚerrorÚ
interfacesÚreactorÚutils)ÚDeferred)Úplatform)ÚSuppressedWarningsTests)ÚSynchronousTestCaseÚTestCasec                   @   sÀ   e Zd ZdZe ed¡du rdZdZdZ	e
jZdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Zdd„ Zee ¡ dƒ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 )%ÚProcessUtilsTestszt
    Test running a process using L{getProcessOutput}, L{getProcessValue}, and
    L{getProcessOutputAndValue}.
    Nz)reactor doesn't implement IReactorProcessc                 C   sV   |   ¡ }t|dƒ�}| tj |¡tj ¡ W d  ƒ n1 s w   Y  tj |¡S )zj
        Write the given list of lines to a text file and return the absolute
        path to it.
        ÚwtN)ÚmktempÚopenÚwriteÚosÚlinesepÚjoinÚpathÚabspath)ÚselfÚsourceLinesÚscriptÚ
scriptFile© r   ú:/usr/lib/python3/dist-packages/twisted/test/test_iutils.pyÚmakeSourceFile$   s
   ÿz ProcessUtilsTests.makeSourceFilec                 C   s.   |   g d¢¡}t | jd|g¡}| | jd¡S )z™
        L{getProcessOutput} returns a L{Deferred} which fires with the complete
        output of the process it runs after that process exits.
        )ú
import syszfor s in b'hello world\n':z    s = bytes([s])z    sys.stdout.buffer.write(s)z    sys.stdout.flush()ú-us   hello world
©r   r   ÚgetProcessOutputÚexeÚaddCallbackÚassertEqual©r   r   Údr   r   r   Útest_output.   s
   ÿ	zProcessUtilsTests.test_outputc                    sF   ˆ   ddg¡}t ˆ jd|g¡}ˆ  |t¡}‡ fdd„}| |¡ |S )z—
        The L{Deferred} returned by L{getProcessOutput} is fired with an
        L{IOError} L{Failure} if the child process writes to stderr.
        r   z!sys.stderr.write("hello world\n")r   c                    s   ˆ   | jtj¡S ©N)ÚassertFailureÚprocessEndedr   ÚProcessDone)Úerr©r   r   r   ÚcbFailedL   ó   z?ProcessUtilsTests.test_outputWithErrorIgnored.<locals>.cbFailed)r   r   r    r!   r(   ÚIOErrorr"   )r   r   r%   r-   r   r,   r   Útest_outputWithErrorIgnored?   s   ÿ
z-ProcessUtilsTests.test_outputWithErrorIgnoredc                 C   s2   |   g d¢¡}tj| jd|gdd�}| | jd¡S )zÒ
        If a C{True} value is supplied for the C{errortoo} parameter to
        L{getProcessOutput}, the returned L{Deferred} fires with the child's
        stderr output as well as its stdout output.
        )r   zsys.stdout.write("foo")úsys.stdout.flush()zsys.stderr.write("foo")úsys.stderr.flush()r   T)Úerrortoos   foofoor   r$   r   r   r   Útest_outputWithErrorCollectedR   s
   ÿz/ProcessUtilsTests.test_outputWithErrorCollectedc                 C   s,   |   dg¡}t | jd|g¡}| | jd¡S )z|
        The L{Deferred} returned by L{getProcessValue} is fired with the exit
        status of the child process.
        zraise SystemExit(1)r   é   )r   r   ÚgetProcessValuer!   r"   r#   r$   r   r   r   Ú
test_valueg   s   zProcessUtilsTests.test_valuec                    s6   ˆ   g d¢¡}‡ fdd„}t ˆ jd|g¡}| |¡S )a  
        The L{Deferred} returned by L{getProcessOutputAndValue} fires with a
        three-tuple, the elements of which give the data written to the child's
        stdout, the data written to the child's stderr, and the exit status of
        the child.
        )r   z*sys.stdout.buffer.write(b'hello world!\n')z,sys.stderr.buffer.write(b'goodbye world!\n')zsys.exit(1)c                    s2   | \}}}ˆ   |d¡ ˆ   |d¡ ˆ   |d¡ d S )Ns   hello world!
s   goodbye world!
r5   ©r#   ©Úout_err_codeÚoutr+   Úcoder,   r   r   ÚgotOutputAndValue�   s   
z@ProcessUtilsTests.test_outputAndValue.<locals>.gotOutputAndValuer   ©r   r   ÚgetProcessOutputAndValuer!   r"   ©r   r   r=   r%   r   r,   r   Útest_outputAndValueq   s   ÿ	
z%ProcessUtilsTests.test_outputAndValuez"Windows doesn't have real signals.c                    sB   ˆ   g d¢¡}‡ fdd„}t ˆ jd|g¡}ˆ  |t¡}| |¡S )zþ
        If the child process exits because of a signal, the L{Deferred}
        returned by L{getProcessOutputAndValue} fires a L{Failure} of a tuple
        containing the child's stdout, stderr, and the signal which caused
        it to exit.
        )zimport sys, os, signalz"sys.stdout.write('stdout bytes\n')z"sys.stderr.write('stderr bytes\n')r1   r2   z$os.kill(os.getpid(), signal.SIGKILL)c                    s4   | \}}}ˆ   |d¡ ˆ   |d¡ ˆ   |tj¡ d S )Ns   stdout bytes
s   stderr bytes
)r#   ÚsignalÚSIGKILL)Úout_err_sigr;   r+   Úsigr,   r   r   r=       s   
z>ProcessUtilsTests.test_outputSignal.<locals>.gotOutputAndValuer   )r   r   r?   r!   r(   Útupler"   r@   r   r,   r   Útest_outputSignalŠ   s   ÿ
z#ProcessUtilsTests.test_outputSignalc                 C   sV   t j |  ¡ ¡}t  |¡ |  ddg¡}|| jd|g|d�}| || t	 
¡ ¡¡ |S )Núimport os, syszsys.stdout.write(os.getcwd())r   )r   )r   r   r   r   Úmakedirsr   r!   r"   ÚencodeÚsysÚgetfilesystemencoding)r   ÚutilFuncÚcheckÚdirr   r%   r   r   r   Ú	_pathTestª   s   
ÿzProcessUtilsTests._pathTestc                 C   ó   |   tj| j¡S )z
        L{getProcessOutput} runs the given command with the working directory
        given by the C{path} parameter.
        )rP   r   r    r#   r,   r   r   r   Útest_getProcessOutputPath´   s   z+ProcessUtilsTests.test_getProcessOutputPathc                    ó   ‡ fdd„}ˆ   tj|¡S )z~
        L{getProcessValue} runs the given command with the working directory
        given by the C{path} parameter.
        c                    ó   ˆ   | d¡ d S ©Nr   r8   ©ÚresultÚignoredr,   r   r   rN   Á   r.   z9ProcessUtilsTests.test_getProcessValuePath.<locals>.check)rP   r   r6   ©r   rN   r   r,   r   Útest_getProcessValuePath»   s   z*ProcessUtilsTests.test_getProcessValuePathc                    rS   )z‡
        L{getProcessOutputAndValue} runs the given command with the working
        directory given by the C{path} parameter.
        c                    ó&   | \}}}ˆ   ||¡ ˆ   |d¡ d S rU   r8   ©Úout_err_statusrO   r;   r+   Ústatusr,   r   r   rN   Ì   ó   
zBProcessUtilsTests.test_getProcessOutputAndValuePath.<locals>.check)rP   r   r?   rY   r   r,   r   Ú!test_getProcessOutputAndValuePathÆ   s   z3ProcessUtilsTests.test_getProcessOutputAndValuePathc                 C   s¤   t j |  ¡ ¡}t  |¡ |  g d¢¡}|  t jt  ¡ ¡ t  |¡ t	 
t  	d¡j¡}t  |t	jt	jB ¡ |  t j||¡ || jd|gƒ}| || t ¡ ¡¡ |S )N)rH   zcdir = os.getcwd()zsys.stdout.write(cdir)Ú.r   )r   r   r   r   rI   r   Ú
addCleanupÚchdirÚgetcwdÚstatÚS_IMODEÚst_modeÚchmodÚS_IXUSRÚS_IRUSRr!   r"   rJ   rK   rL   )r   rM   rN   rO   r   ÚoriginalModer%   r   r   r   Ú_defaultPathTestÓ   s   
ÿ
z"ProcessUtilsTests._defaultPathTestc                 C   rQ   )a  
        If no value is supplied for the C{path} parameter, L{getProcessOutput}
        runs the given command in the same working directory as the parent
        process and succeeds even if the current working directory is not
        accessible.
        )rl   r   r    r#   r,   r   r   r   Ú test_getProcessOutputDefaultPathñ   s   z2ProcessUtilsTests.test_getProcessOutputDefaultPathc                    rS   )a   
        If no value is supplied for the C{path} parameter, L{getProcessValue}
        runs the given command in the same working directory as the parent
        process and succeeds even if the current working directory is not
        accessible.
        c                    rT   rU   r8   rV   r,   r   r   rN     r.   z@ProcessUtilsTests.test_getProcessValueDefaultPath.<locals>.check)rl   r   r6   rY   r   r,   r   Útest_getProcessValueDefaultPathú   s   z1ProcessUtilsTests.test_getProcessValueDefaultPathc                    rS   )a	  
        If no value is supplied for the C{path} parameter,
        L{getProcessOutputAndValue} runs the given command in the same working
        directory as the parent process and succeeds even if the current
        working directory is not accessible.
        c                    r[   rU   r8   r\   r,   r   r   rN     r_   zIProcessUtilsTests.test_getProcessOutputAndValueDefaultPath.<locals>.check)rl   r   r?   rY   r   r,   r   Ú(test_getProcessOutputAndValueDefaultPath  s   z:ProcessUtilsTests.test_getProcessOutputAndValueDefaultPathc                    sD   ˆ   ddg¡}d‰tjˆ jd|gˆd�}‡ ‡fdd„}| |¡ |S )z„
        Standard input can be made available to the child process by passing
        bytes for the `stdinBytes` parameter.
        r   z"sys.stdout.write(sys.stdin.read())s   These are the bytes to see.r   )Ú
stdinBytesc                    s&   | \}}}ˆ   ˆ|¡ ˆ  d|¡ d S rU   )ÚassertInr#   r9   ©r   rp   r   r   r=   (  s   
zPProcessUtilsTests.test_get_processOutputAndValueStdin.<locals>.gotOutputAndValuer>   )r   r   r%   r=   r   rr   r   Ú#test_get_processOutputAndValueStdin  s   þÿý
z5ProcessUtilsTests.test_get_processOutputAndValueStdin) Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   ÚIReactorProcessr   ÚskipÚoutputÚvaluerK   Ú
executabler!   r   r&   r0   r4   r7   rA   r   r   Ú	isWindowsrG   rP   rR   rZ   r`   rl   rm   rn   ro   rs   r   r   r   r   r      s0    



	r   c                   @   s   e Zd ZdZdd„ ZdS )ÚSuppressWarningsTestsz.
    Tests for L{utils.suppressWarnings}.
    c                    sˆ   g ‰ ‡ fdd„}|   td|¡ dd„ }t |dtdd�f¡}|d	ƒ |  tˆ ƒd
¡ |dƒ |  tˆ ƒd
¡ |dƒ |  tˆ ƒd¡ dS )zs
        L{utils.suppressWarnings} decorates a function so that the given
        warnings are suppressed.
        c                    s   ˆ   ||f¡ d S r'   )Úappend)r   ÚaÚkw©rW   r   r   Úshowwarning@  s   z@SuppressWarningsTests.test_suppressWarnings.<locals>.showwarningrƒ   c                 S   s   t  | ¡ d S r'   )ÚwarningsÚwarn)Úmsgr   r   r   ÚfE  s   z6SuppressWarningsTests.test_suppressWarnings.<locals>.f)ÚignorezThis is message©ÚmessagezSanity check messager5   zUnignored messageé   N)Úpatchr„   r   ÚsuppressWarningsÚdictr#   Úlen)r   rƒ   r‡   Úgr   r‚   r   Útest_suppressWarnings9  s   z+SuppressWarningsTests.test_suppressWarningsN)rt   ru   rv   rw   r‘   r   r   r   r   r~   4  s    r~   c                   @   s*   e Zd ZdZeejƒZdd„ Zdd„ ZdS )ÚDeferredSuppressedWarningsTestsz`
    Tests for L{utils.runWithWarningsSuppressed}, the version that supports
    Deferreds.
    c                    sh   di fdi fg}t ƒ ‰ |  |‡ fdd„¡ t d¡ ˆ  d¡ t d¡ |  dgdd	„ |  ¡ D ƒ¡ d
S )z²
        If the function called by L{utils.runWithWarningsSuppressed} returns a
        C{Deferred}, the warning filters aren't removed until the Deferred
        fires.
        ©rˆ   z.*foo.*©rˆ   z.*bar.*c                      ó   ˆ S r'   r   r   r‚   r   r   Ú<lambda>l  ó    zGDeferredSuppressedWarningsTests.test_deferredCallback.<locals>.<lambda>ú
ignore fooé   úignore foo 2c                 S   ó   g | ]}|d  ‘qS r‰   r   ©Ú.0Úwr   r   r   Ú
<listcomp>p  ó    zIDeferredSuppressedWarningsTests.test_deferredCallback.<locals>.<listcomp>N)r   ÚrunWithWarningsSuppressedr„   r…   Úcallbackr#   ÚflushWarnings)r   Úfiltersr   r‚   r   Útest_deferredCallbackd  s   


 z5DeferredSuppressedWarningsTests.test_deferredCallbackc                    sx   di fdi fg}t ƒ ‰ |  |‡ fdd„¡}t d¡ ˆ  tƒ ¡ | dd„ ¡ t d¡ |  dgdd	„ |  ¡ D ƒ¡ d
S )zÂ
        If the function called by L{utils.runWithWarningsSuppressed} returns a
        C{Deferred}, the warning filters aren't removed until the Deferred
        fires with an errback.
        r“   r”   c                      r•   r'   r   r   r‚   r   r   r–   z  r—   zFDeferredSuppressedWarningsTests.test_deferredErrback.<locals>.<lambda>r˜   c                 S   s
   |   t¡S r'   )ÚtrapÚZeroDivisionError)r‡   r   r   r   r–   }  s   
 rš   c                 S   r›   r‰   r   rœ   r   r   r   rŸ     r    zHDeferredSuppressedWarningsTests.test_deferredErrback.<locals>.<listcomp>N)	r   r¡   r„   r…   Úerrbackr§   Ú
addErrbackr#   r£   )r   r¤   r%   r   r‚   r   Útest_deferredErrbackr  s   

 z4DeferredSuppressedWarningsTests.test_deferredErrbackN)	rt   ru   rv   rw   Ústaticmethodr   r¡   r¥   rª   r   r   r   r   r’   Z  s
    
r’   )rw   r   rB   re   rK   r„   Úunittestr   Útwisted.internetr   r   r   r   Útwisted.internet.deferr   Útwisted.python.runtimer   Útwisted.python.test.test_utilr	   Útwisted.trial.unittestr
   r   r   r~   r’   r   r   r   r   Ú<module>   s"     &