o
    ¯bº1  ã                   @   sÎ   d 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
mZ ddl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 d
ZeejƒZej ej¡ed< G dd„ de	jƒZ G dd„ deƒZ!dS )z¯
Tests for L{twisted.internet.stdio}.

@var properEnv: A copy of L{os.environ} which has L{bytes} keys/values on POSIX
    platforms and native L{str} keys/values on Windows.
é    N)ÚskipIf)ÚdeferÚerrorÚprotocolÚreactorÚstdio)ÚfilepathÚlog)ÚrequireModule)Úplatform)ÚConnectionLostNotifyingProtocol)ÚSkipTestÚTestCases   xyz123abc Twisted is great!Ú
PYTHONPATHc                   @   s4   e Zd ZdZdZdd„ Zdd„ Zdd„ Zd	d
„ ZdS )ÚStandardIOTestProcessProtocolaÕ  
    Test helper for collecting output from a child process and notifying
    something when it exits.

    @ivar onConnection: A L{defer.Deferred} which will be called back with
    L{None} when the connection to the child process is established.

    @ivar onCompletion: A L{defer.Deferred} which will be errbacked with the
    failure associated with the child process exiting when it exits.

    @ivar onDataReceived: A L{defer.Deferred} which will be called back with
    this instance whenever C{childDataReceived} is called, or L{None} to
    suppress these callbacks.

    @ivar data: A C{dict} mapping file descriptors to strings containing all
    bytes received from the child process on each file descriptor.
    Nc                 C   s   t  ¡ | _t  ¡ | _i | _d S ©N)r   ÚDeferredÚonConnectionÚonCompletionÚdata©Úself© r   ú9/usr/lib/python3/dist-packages/twisted/test/test_stdio.pyÚ__init__8   s   


z&StandardIOTestProcessProtocol.__init__c                 C   s   | j  d ¡ d S r   )r   Úcallbackr   r   r   r   ÚconnectionMade=   ó   z,StandardIOTestProcessProtocol.connectionMadec                 C   sB   | j  |d¡| | j |< | jdur| jd}| _| | ¡ dS dS )z“
        Record all bytes received from the child process in the C{data}
        dictionary.  Fire C{onDataReceived} if it is not L{None}.
        ó    N)r   ÚgetÚonDataReceivedr   )r   ÚnameÚbytesÚdr   r   r   ÚchildDataReceived@   s
   
þz/StandardIOTestProcessProtocol.childDataReceivedc                 C   s   | j  |¡ d S r   )r   r   )r   Úreasonr   r   r   ÚprocessEndedJ   r   z*StandardIOTestProcessProtocol.processEnded)	Ú__name__Ú
__module__Ú__qualname__Ú__doc__r    r   r   r$   r&   r   r   r   r   r   #   s    
r   c                   @   s’   e Zd Ze ¡ redƒdu r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ee ¡ dƒdd„ ƒZdS )ÚStandardInputOutputTestsÚwin32processNzIOn windows, spawnProcess is not available in the absence of win32process.c                 O   s:   t jdd| tjjgt|ƒ }tj|t j|fdti|¤ŽS )a_  
        Launch a child Python process and communicate with it using the
        given ProcessProtocol.

        @param proto: A L{ProcessProtocol} instance which will be connected
        to the child process.

        @param sibling: The basename of a file containing the Python program
        to run in the child process.

        @param *args: strings which will be passed to the child process on
        the command line as C{argv[2:]}.

        @param **kw: additional arguments to pass to L{reactor.spawnProcess}.

        @return: The L{IProcessTransport} provider for the spawned process.
        s   -ms   twisted.test.Úenv)ÚsysÚ
executabler   Ú	__class__r(   ÚlistÚspawnProcessÚ	properEnv)r   ÚprotoÚsiblingÚargsÚkwr   r   r   Ú_spawnProcessV   s   üûz&StandardInputOutputTests._spawnProcessc                    s$   ‡fdd„}‡ fdd„}|  ||¡S )Nc                    s   ˆ   d| ›�¡ d S )Nz%Process terminated with non-Failure: )Úfail)Úresultr   r   r   Úcbq   s   z4StandardInputOutputTests._requireFailure.<locals>.cbc                    s   ˆ | ƒS r   r   )Úerr)r   r   r   Úebt   s   z4StandardInputOutputTests._requireFailure.<locals>.eb)ÚaddCallbacks)r   r#   r   r;   r=   r   )r   r   r   Ú_requireFailurep   s   z(StandardInputOutputTests._requireFailurec                    sL   ˆ  ¡ ‰ t dˆ  ¡ tƒ ‰ˆj}ˆ ˆdˆ ¡ ‡ ‡‡fdd„}ˆ ||¡S )z„
        Verify that a protocol connected to L{StandardIO} can disconnect
        itself using C{transport.loseConnection}.
        úChild process logging to s   stdio_test_loseconnc                    sb   t ˆ ƒ�}|D ]}t d| ¡  ¡ qW d   ƒ n1 sw   Y  ˆ dˆj¡ |  tj¡ d S )NzChild logged: é   )	Úopenr	   ÚmsgÚrstripÚfailIfInr   Útrapr   ÚProcessDone)r%   ÚfÚline©ÚerrorLogFileÚpr   r   r   r&   „   s   
ÿÿzBStandardInputOutputTests.test_loseConnection.<locals>.processEnded)Úmktempr	   rC   r   r   r8   r?   ©r   r#   r&   r   rJ   r   Útest_loseConnectiony   s   	z,StandardInputOutputTests.test_loseConnectionc                    sf   |   ¡ }t d| ¡ tƒ ‰ t ¡ ˆ _‡ fdd„}ˆ j |¡ dd„ }|  ˆ j|¡}|  	ˆ d|¡ |S )z´
        When stdin is closed and the protocol connected to it implements
        L{IHalfCloseableProtocol}, the protocol's C{readConnectionLost} method
        is called.
        r@   c                    s   ˆ j }ˆ j ¡  |S r   )r   Ú	transportÚ
closeStdin)Úignoredr#   ©rL   r   r   ÚcbBytesš   s   
zAStandardInputOutputTests.test_readConnectionLost.<locals>.cbBytesc                 S   s   |   tj¡ d S r   )rF   r   rG   ©r%   r   r   r   r&   ¡   r   zFStandardInputOutputTests.test_readConnectionLost.<locals>.processEndeds   stdio_test_halfclose)
rM   r	   rC   r   r   r   r    ÚaddCallbackr?   r8   )r   rK   rT   r&   r#   r   rS   r   Útest_readConnectionLost�   s   
z0StandardInputOutputTests.test_readConnectionLostc              
      s^   t ƒ ‰ zˆjˆ dtdd� W n ty  } ztt|ƒƒ‚d}~ww ‡ ‡fdd„}ˆ ˆ j|¡S )z¶
        Verify that a write made directly to stdout using L{os.write}
        after StandardIO has finished is reliably received by the
        process reading that stdout.
        s   stdio_test_lastwriteT)ÚusePTYNc                    s2   ˆ  ˆ jd  t¡dˆ j›d�¡ |  tj¡ dS )z‰
            Asserts that the parent received the bytes written by the child
            immediately after the child starts.
            rA   z	Received z) from child, did not find expected bytes.N)Ú
assertTruer   ÚendswithÚUNIQUE_LAST_WRITE_STRINGrF   r   rG   rU   ©rL   r   r   r   r&   Ã   s
   þzEStandardInputOutputTests.test_lastWriteReceived.<locals>.processEnded)r   r8   r[   Ú
ValueErrorr   Ústrr?   r   )r   Úer&   r   r\   r   Útest_lastWriteReceived©   s   
ÿ€þz/StandardInputOutputTests.test_lastWriteReceivedc                    ó2   t ƒ ‰ ˆ j}ˆ ˆ d¡ ‡ ‡fdd„}ˆ ||¡S )zƒ
        Verify that the transport of a protocol connected to L{StandardIO}
        has C{getHost} and C{getPeer} methods.
        s   stdio_test_hostpeerc                    s6   ˆ j d  ¡ \}}ˆ |¡ ˆ |¡ |  tj¡ d S )NrA   )r   Ú
splitlinesrY   rF   r   rG   )r%   ÚhostÚpeerr\   r   r   r&   Ù   s   

z?StandardInputOutputTests.test_hostAndPeer.<locals>.processEnded©r   r   r8   r?   rN   r   r\   r   Útest_hostAndPeerÐ   s
   z)StandardInputOutputTests.test_hostAndPeerc                    ra   )z�
        Verify that the C{write} method of the transport of a protocol
        connected to L{StandardIO} sends bytes to standard out.
        s   stdio_test_writec                    ó"   ˆ  ˆ jd d¡ |  tj¡ d S ©NrA   s   ok!©ÚassertEqualr   rF   r   rG   rU   r\   r   r   r&   ë   ó   z9StandardInputOutputTests.test_write.<locals>.processEndedre   rN   r   r\   r   Ú
test_writeá   ó
   z#StandardInputOutputTests.test_writec                    ra   )z˜
        Verify that the C{writeSequence} method of the transport of a
        protocol connected to L{StandardIO} sends bytes to standard out.
        s   stdio_test_writeseqc                    rg   rh   ri   rU   r\   r   r   r&   û   rk   zAStandardInputOutputTests.test_writeSequence.<locals>.processEndedre   rN   r   r\   r   Útest_writeSequenceñ   rm   z+StandardInputOutputTests.test_writeSequencec                 C   sV   |   ¡ }t|dƒ�}tdƒD ]
}| d|f ¡ qW d   ƒ |S 1 s$w   Y  |S )NÚwbi   ó   %d
)rM   rB   ÚrangeÚwrite)r   ÚjunkPathÚjunkFileÚir   r   r   Ú	_junkPath  s   ÿ
ÿýz"StandardInputOutputTests._junkPathc                    sd   t ƒ ‰ˆj}g ‰ttdƒƒ‰‡ ‡‡‡fdd„‰ ˆ ˆd¡‰ˆj ˆ ¡ ‡‡‡‡fdd„}ˆ ||¡S )z€
        Verify that the transport of a protocol connected to L{StandardIO}
        is a working L{IProducer} provider.
        éd   c                    s<   ˆrˆ  dˆ ¡ f ¡ ˆ ˆd ¡ t dˆ d ¡ d S d S )Nrp   éÿÿÿÿg{®Gáz„?)ÚappendÚpoprr   r   Ú	callLater)Úign)r   ÚprocÚtoWriteÚwrittenr   r   r     s
   ýz>StandardInputOutputTests.test_producer.<locals>.connectionMades   stdio_test_producerc                    s>   ˆ  ˆ jd d ˆ¡¡ ˆ ˆdtˆƒf ¡ |  tj¡ d S )NrA   r   z*Connection lost with %d writes left to go.)rj   r   ÚjoinÚassertFalseÚlenrF   r   rG   rU   )rL   r   r~   r   r   r   r&     s
   ÿz<StandardInputOutputTests.test_producer.<locals>.processEnded)r   r   r1   rq   r8   r   rV   r?   rN   r   )r   rL   r}   r   r~   r   r   Útest_producer  s   z&StandardInputOutputTests.test_producerc                    s>   t ƒ ‰ˆj}ˆ ¡ ‰ ˆ ˆdˆ ¡ ‡ ‡‡fdd„}ˆ ||¡S )z€
        Verify that the transport of a protocol connected to L{StandardIO}
        is a working L{IConsumer} provider.
        s   stdio_test_consumerc                    sP   t ˆ dƒ�}ˆ ˆjd | ¡ ¡ W d   ƒ n1 sw   Y  |  tj¡ d S )NÚrbrA   )rB   rj   r   ÚreadrF   r   rG   )r%   rH   ©rs   rL   r   r   r   r&   2  s   ÿz<StandardInputOutputTests.test_consumer.<locals>.processEnded)r   r   rv   r8   r?   rN   r   r†   r   Útest_consumer&  s   z&StandardInputOutputTests.test_consumerzpStandardIO does not accept stdout as an argument to Windows.  Testing redirection to a file is therefore harder.c                    sÜ   t  ¡ }t|ƒ}t ˆ ¡ ¡‰ˆ d¡ ˆ_}ˆ |j	¡ t
| ¡ d�}t ¡ s@t ¡ \}}ˆ tj	|¡ ˆ tj	|¡ ||d< tj|fi |¤Ž‰ d‰t ¡ ‰‡ ‡‡‡fdd„‰t dˆ¡ ‡‡‡‡fdd	„}| |¡ |S )
aE  
        If L{StandardIO} is created with a file descriptor which refers to a
        normal file (ie, a file from the filesystem), L{StandardIO.write}
        writes bytes to that file.  In particular, it does not immediately
        consider the file closed or call its protocol's C{connectionLost}
        method.
        ro   )ÚstdoutÚstdiné   c                     s@   ˆD ]} | ˆkrˆ   ¡   d S ˆ  d| f ¡  t dˆ¡ d S )Nó   %dr   )ÚloseConnectionrr   r   r{   )Úvalue)Ú
connectionÚcountÚhowManyÚspinr   r   r‘   ]  s   zAStandardInputOutputTests.test_normalFileStandardOut.<locals>.spinr   c                    s<   ˆ  tˆ ƒˆd ¡ ˆ  ˆ ¡ d dd„ tˆƒD ƒ¡¡ d S )NrA   r   c                 s   s   � | ]}d |f V  qdS )r‹   Nr   )Ú.0ru   r   r   r   Ú	<genexpr>m  s   € zVStandardInputOutputTests.test_normalFileStandardOut.<locals>.cbLost.<locals>.<genexpr>)rj   ÚnextÚ
getContentr€   rq   rU   )r�   r�   Úpathr   r   r   ÚcbLostj  s   ÿzCStandardInputOutputTests.test_normalFileStandardOut.<locals>.cbLost)r   r   r   r   ÚFilePathrM   rB   ÚnormalÚ
addCleanupÚcloseÚdictÚfilenor   Ú	isWindowsÚosÚpiper   Ú
StandardIOÚ	itertoolsr�   r   r{   rV   )r   Ú
onConnLostr4   r™   ÚkwargsÚrÚwr—   r   )rŽ   r�   r�   r–   r   r‘   r   Útest_normalFileStandardOut9  s&   	
z3StandardInputOutputTests.test_normalFileStandardOut)r'   r(   r)   r   rž   r
   Úskipr8   r?   rO   rW   r`   rf   rl   rn   rv   rƒ   r‡   r   r§   r   r   r   r   r+   N   s(    ÿ	'þr+   )"r*   r¢   rŸ   r.   Úunittestr   Útwisted.internetr   r   r   r   r   Útwisted.pythonr   r	   Útwisted.python.reflectr
   Útwisted.python.runtimer   Útwisted.test.test_tcpr   Útwisted.trial.unittestr   r   r[   rœ   Úenvironr3   Úpathsepr€   r–   ÚProcessProtocolr   r+   r   r   r   r   Ú<module>   s    
+