U
    2ÜŸj@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k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   sB   |   ¡ }t|dƒ�}| tj |¡tj ¡ W 5 Q R X tj |¡S )zj
        Write the given list of lines to a text file and return the absolute
        path to it.
        Úwt)ÚmktempÚopenÚwriteÚosÚlinesepÚjoinÚpathÚabspath)ÚselfZsourceLinesÚscriptÚ
scriptFile© r   ú</tmp/pip-unpacked-wheel-4b529toj/twisted/test/test_iutils.pyÚmakeSourceFile$   s    "z ProcessUtilsTests.makeSourceFilec                 C   s4   |   dddddg¡}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)ÚassertFailureZprocessEndedr   ZProcessDone)Úerr©r   r   r   ÚcbFailedL   s    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   s8   |   dddddg¡}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)Z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                    s:   ˆ   ddddg¡}‡ 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!
r0   ©r"   ©Zout_err_codeÚoutr(   Úcoder)   r   r   ÚgotOutputAndValue�   s    
z@ProcessUtilsTests.test_outputAndValue.<locals>.gotOutputAndValuer   ©r   r   ÚgetProcessOutputAndValuer    r!   ©r   r   r7   r$   r   r)   r   Útest_outputAndValueq   s    üÿ	z%ProcessUtilsTests.test_outputAndValuez"Windows doesn't have real signals.c                    sJ   ˆ   ddddddg¡}‡ 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')r-   r.   z$os.kill(os.getpid(), signal.SIGKILL)c                    s4   | \}}}ˆ   |d¡ ˆ   |d¡ ˆ   |tj¡ d S )Ns   stdout bytes
s   stderr bytes
)r"   ÚsignalÚSIGKILL)Zout_err_sigr5   r(   Úsigr)   r   r   r7       s    
z>ProcessUtilsTests.test_outputSignal.<locals>.gotOutputAndValuer   )r   r   r9   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   s   |   tj| j¡S )z
        L{getProcessOutput} runs the given command with the working directory
        given by the C{path} parameter.
        )rI   r   r   r"   r)   r   r   r   Útest_getProcessOutputPath´   s    z+ProcessUtilsTests.test_getProcessOutputPathc                    s   ‡ fdd„}ˆ   tj|¡S )z~
        L{getProcessValue} runs the given command with the working directory
        given by the C{path} parameter.
        c                    s   ˆ   | d¡ d S ©Nr   r3   ©ÚresultZignoredr)   r   r   rG   Á   s    z9ProcessUtilsTests.test_getProcessValuePath.<locals>.check)rI   r   r1   ©r   rG   r   r)   r   Útest_getProcessValuePath»   s    z*ProcessUtilsTests.test_getProcessValuePathc                    s   ‡ fdd„}ˆ   tj|¡S )z‡
        L{getProcessOutputAndValue} runs the given command with the working
        directory given by the C{path} parameter.
        c                    s&   | \}}}ˆ   ||¡ ˆ   |d¡ d S rK   r3   ©Zout_err_statusrH   r5   r(   Ústatusr)   r   r   rG   Ì   s    
zBProcessUtilsTests.test_getProcessOutputAndValuePath.<locals>.check)rI   r   r9   rN   r   r)   r   Ú!test_getProcessOutputAndValuePathÆ   s    z3ProcessUtilsTests.test_getProcessOutputAndValuePathc                 C   s¦   t j |  ¡ ¡}t  |¡ |  dddg¡}|  t jt  ¡ ¡ t  |¡ t	 
t  	d¡j¡}t  |t	jt	jB ¡ |  t j||¡ || jd|gƒ}| || t ¡ ¡¡ |S )NrA   zcdir = os.getcwd()zsys.stdout.write(cdir)Ú.r   )r   r   r   r   rB   r   Z
addCleanupÚchdirÚgetcwdÚstatÚS_IMODEÚst_modeÚchmodÚS_IXUSRÚS_IRUSRr    r!   rC   rD   rE   )r   rF   rG   rH   r   ZoriginalModer$   r   r   r   Ú_defaultPathTestÓ   s    
ÿ
z"ProcessUtilsTests._defaultPathTestc                 C   s   |   tj| j¡S )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.
        )r\   r   r   r"   r)   r   r   r   Ú test_getProcessOutputDefaultPathñ   s    z2ProcessUtilsTests.test_getProcessOutputDefaultPathc                    s   ‡ fdd„}ˆ   tj|¡S )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                    s   ˆ   | d¡ d S rK   r3   rL   r)   r   r   rG     s    z@ProcessUtilsTests.test_getProcessValueDefaultPath.<locals>.check)r\   r   r1   rN   r   r)   r   Útest_getProcessValueDefaultPathú   s    z1ProcessUtilsTests.test_getProcessValueDefaultPathc                    s   ‡ fdd„}ˆ   tj|¡S )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                    s&   | \}}}ˆ   ||¡ ˆ   |d¡ d S rK   r3   rP   r)   r   r   rG     s    
zIProcessUtilsTests.test_getProcessOutputAndValueDefaultPath.<locals>.check)r\   r   r9   rN   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 rK   )ZassertInr"   r4   ©r   r`   r   r   r7   (  s    
zPProcessUtilsTests.test_get_processOutputAndValueStdin.<locals>.gotOutputAndValuer8   )r   r   r$   r7   r   ra   r   Ú#test_get_processOutputAndValueStdin  s    þÿý
z5ProcessUtilsTests.test_get_processOutputAndValueStdin) Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   ZIReactorProcessr   ÚskipÚoutputÚvaluerD   Ú
executabler    r   r%   r,   r/   r2   r;   r   r   Z	isWindowsr@   rI   rJ   rO   rR   r\   r]   r^   r_   rb   r   r   r   r   r      s.   



	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©rM   r   r   Úshowwarning@  s    z@SuppressWarningsTests.test_suppressWarnings.<locals>.showwarningrp   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 messager0   zUnignored messageé   N)Úpatchrq   r   ZsuppressWarningsÚdictr"   Úlen)r   rp   rt   Úgr   ro   r   Útest_suppressWarnings9  s    z+SuppressWarningsTests.test_suppressWarningsN)rc   rd   re   rf   r}   r   r   r   r   rk   4  s   rk   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.
        ©ru   z.*foo.*©ru   z.*bar.*c                      s   ˆ S r&   r   r   ro   r   r   Ú<lambda>l  ó    zGDeferredSuppressedWarningsTests.test_deferredCallback.<locals>.<lambda>ú
ignore fooé   úignore foo 2c                 S   s   g | ]}|d  ‘qS rv   r   ©Ú.0Úwr   r   r   Ú
<listcomp>p  s     zIDeferredSuppressedWarningsTests.test_deferredCallback.<locals>.<listcomp>N)r   ÚrunWithWarningsSuppressedrq   rr   Úcallbackr"   ÚflushWarnings)r   Úfiltersr   ro   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                      s   ˆ S r&   r   r   ro   r   r   r�   z  r‚   zFDeferredSuppressedWarningsTests.test_deferredErrback.<locals>.<lambda>rƒ   c                 S   s
   |   t¡S r&   )ZtrapÚZeroDivisionError)rt   r   r   r   r�   }  r‚   r…   c                 S   s   g | ]}|d  ‘qS rv   r   r†   r   r   r   r‰     s     zHDeferredSuppressedWarningsTests.test_deferredErrback.<locals>.<listcomp>N)	r   rŠ   rq   rr   Zerrbackr�   Z
addErrbackr"   rŒ   )r   r�   r$   r   ro   r   Útest_deferredErrbackr  s    

z4DeferredSuppressedWarningsTests.test_deferredErrbackN)	rc   rd   re   rf   Ústaticmethodr   rŠ   rŽ   r�   r   r   r   r   r~   Z  s   
r~   )rf   r   r<   rV   rD   rq   Zunittestr   Ztwisted.internetr   r   r   r   Ztwisted.internet.deferr   Ztwisted.python.runtimer   Ztwisted.python.test.test_utilr	   Ztwisted.trial.unittestr
   r   r   rk   r~   r   r   r   r   Ú<module>   s      &