ó
[³XMc           @   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 d d l	 m
 Z
 d d l m Z m Z m Z m Z m Z d d l m Z d Z d Z e
 j ƒ  rÝ y d d l Z WqÝ e k
 rÙ d	 Z qÝ Xn  d
 e j f d „  ƒ  YZ d e j f d „  ƒ  YZ d S(   s&   
Tests for L{twisted.internet.stdio}.
iÿÿÿÿN(   t   unittest(   t   filepatht   log(   t   platform(   t   errort   defert   protocolt   stdiot   reactor(   t   ConnectionLostNotifyingProtocols   xyz123abc Twisted is great!sI   On windows, spawnProcess is not available in the absence of win32process.t   StandardIOTestProcessProtocolc           B   s8   e  Z d  Z d Z d „  Z d „  Z d „  Z d „  Z RS(   sÕ  
    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
    C{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 C{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.
    c         C   s+   t  j ƒ  |  _ t  j ƒ  |  _ i  |  _ d  S(   N(   R   t   Deferredt   onConnectiont   onCompletiont   data(   t   self(    (    s;   /usr/lib/python2.7/dist-packages/twisted/test/test_stdio.pyt   __init__5   s    c         C   s   |  j  j d  ƒ d  S(   N(   R   t   callbackt   None(   R   (    (    s;   /usr/lib/python2.7/dist-packages/twisted/test/test_stdio.pyt   connectionMade;   s    c         C   sV   |  j  j | d ƒ | |  j  | <|  j d k	 rR |  j d } |  _ | j |  ƒ n  d S(   s“   
        Record all bytes received from the child process in the C{data}
        dictionary.  Fire C{onDataReceived} if it is not C{None}.
        t    N(   R   t   gett   onDataReceivedR   R   (   R   t   namet   bytest   d(    (    s;   /usr/lib/python2.7/dist-packages/twisted/test/test_stdio.pyt   childDataReceived?   s     c         C   s   |  j  j | ƒ d  S(   N(   R   R   (   R   t   reason(    (    s;   /usr/lib/python2.7/dist-packages/twisted/test/test_stdio.pyt   processEndedJ   s    N(	   t   __name__t
   __module__t   __doc__R   R   R   R   R   R   (    (    (    s;   /usr/lib/python2.7/dist-packages/twisted/test/test_stdio.pyR
   !   s   			t   StandardInputOutputTestCasec           B   s×   e  Z e Z d  „  Z d „  Z d „  Z d „  Z d „  Z d „  Z	 d „  Z
 d „  Z d „  Z d	 „  Z d
 „  Z d „  Z e j j  d k r– d e _ n e j ƒ  r® d e _ n  d „  Z e j j  d k rÕ d e _ n  RS(   c         O   sÀ   d d l  } t t j ƒ } t j j t j j t j j t j j | j	 ƒ ƒ ƒ | j
 d d ƒ g ƒ | d <t j t j t	 ƒ j | ƒ j t j j g t | ƒ } t j | t j | d | | S(   s_  
        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.
        iÿÿÿÿNt
   PYTHONPATHR   t   env(   t   twistedt   dictt   ost   environt   pathsept   joint   patht   abspatht   dirnamet   __file__R   t   syst
   executableR   t   FilePatht   siblingR   t	   __class__R   t   listt   spawnProcess(   R   t   protoR0   t   argst   kwR#   t   subenv(    (    s;   /usr/lib/python2.7/dist-packages/twisted/test/test_stdio.pyt   _spawnProcessS   s    		!c            s.   ‡ f d †  } ‡  f d †  } | j  | | ƒ S(   Nc            s   ˆ  j  d |  f ƒ d  S(   Ns'   Process terminated with non-Failure: %r(   t   fail(   t   result(   R   (    s;   /usr/lib/python2.7/dist-packages/twisted/test/test_stdio.pyt   cbx   s    c            s
   ˆ  |  ƒ S(   N(    (   t   err(   R   (    s;   /usr/lib/python2.7/dist-packages/twisted/test/test_stdio.pyt   ebz   s    (   t   addCallbacks(   R   R   R   R;   R=   (    (   R   R   s;   /usr/lib/python2.7/dist-packages/twisted/test/test_stdio.pyt   _requireFailurew   s    c            sg   ˆ  j  ƒ  ‰ t j d ˆ ƒ t ƒ  ‰ ˆ j } ˆ  j ˆ d ˆ ƒ ‡  ‡ ‡ f d †  } ˆ  j | | ƒ S(   s„   
        Verify that a protocol connected to L{StandardIO} can disconnect
        itself using C{transport.loseConnection}.
        s   Child process logging to s   stdio_test_loseconn.pyc            sU   x+ t  ˆ ƒ D] } t j d | j ƒ  ƒ q Wˆ  j d ˆ j ƒ |  j t j ƒ d  S(   Ns   Child logged: i   (	   t   fileR   t   msgt   rstript   failIfInR   t   trapR   t   ProcessDone(   R   t   line(   R   t   pt   errorLogFile(    s;   /usr/lib/python2.7/dist-packages/twisted/test/test_stdio.pyR   Š   s    (   t   mktempR   RA   R
   R   R8   R?   (   R   R   R   (    (   R   RG   RH   s;   /usr/lib/python2.7/dist-packages/twisted/test/test_stdio.pyt   test_loseConnection   s    		c            s‰   |  j  ƒ  } t j d | ƒ t ƒ  ‰  t j ƒ  ˆ  _ ‡  f d †  } ˆ  j j | ƒ d „  } |  j ˆ  j | ƒ } |  j	 ˆ  d | ƒ | S(   s´   
        When stdin is closed and the protocol connected to it implements
        L{IHalfCloseableProtocol}, the protocol's C{readConnectionLost} method
        is called.
        s   Child process logging to c            s   ˆ  j  } ˆ  j j ƒ  | S(   N(   R   t	   transportt
   closeStdin(   t   ignoredR   (   RG   (    s;   /usr/lib/python2.7/dist-packages/twisted/test/test_stdio.pyt   cbBytesŸ   s    	c         S   s   |  j  t j ƒ d  S(   N(   RD   R   RE   (   R   (    (    s;   /usr/lib/python2.7/dist-packages/twisted/test/test_stdio.pyR   ¥   s    s   stdio_test_halfclose.py(
   RI   R   RA   R
   R   R   R   t   addCallbackR?   R8   (   R   RH   RN   R   R   (    (   RG   s;   /usr/lib/python2.7/dist-packages/twisted/test/test_stdio.pyt   test_readConnectionLost”   s    		c            sv   t  ƒ  ‰ y ˆ  j ˆ d t d t ƒWn( t k
 rP } t j t | ƒ ƒ ‚ n X‡ ‡  f d †  } ˆ  j ˆ j	 | ƒ S(   s¶   
        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_lastwrite.pyt   usePTYc            s>   ˆ j  ˆ  j d j t ƒ d ˆ  j f ƒ |  j t j ƒ d S(   s‰   
            Asserts that the parent received the bytes written by the child
            immediately after the child starts.
            i   s4   Received %r from child, did not find expected bytes.N(   t
   assertTrueR   t   endswitht   UNIQUE_LAST_WRITE_STRINGRD   R   RE   (   R   (   RG   R   (    s;   /usr/lib/python2.7/dist-packages/twisted/test/test_stdio.pyR   È   s
    (
   R
   R8   RT   t   Truet
   ValueErrorR    t   SkipTestt   strR?   R   (   R   t   eR   (    (   R   RG   s;   /usr/lib/python2.7/dist-packages/twisted/test/test_stdio.pyt   test_lastWriteReceived®   s    	
c            sD   t  ƒ  ‰  ˆ  j } ˆ j ˆ  d ƒ ‡ ‡  f d †  } ˆ j | | ƒ S(   sƒ   
        Verify that the transport of a protocol connected to L{StandardIO}
        has C{getHost} and C{getPeer} methods.
        s   stdio_test_hostpeer.pyc            sG   ˆ j  d j ƒ  \ } } ˆ  j | ƒ ˆ  j | ƒ |  j t j ƒ d  S(   Ni   (   R   t
   splitlinest
   failUnlessRD   R   RE   (   R   t   hostt   peer(   R   RG   (    s;   /usr/lib/python2.7/dist-packages/twisted/test/test_stdio.pyR   Þ   s    (   R
   R   R8   R?   (   R   R   R   (    (   RG   R   s;   /usr/lib/python2.7/dist-packages/twisted/test/test_stdio.pyt   test_hostAndPeerÕ   s
    		c            sD   t  ƒ  ‰  ˆ  j } ˆ j ˆ  d ƒ ‡  ‡ f d †  } ˆ j | | ƒ S(   s   
        Verify that the C{write} method of the transport of a protocol
        connected to L{StandardIO} sends bytes to standard out.
        s   stdio_test_write.pyc            s+   ˆ j  ˆ  j d d ƒ |  j t j ƒ d  S(   Ni   s   ok!(   t   assertEqualsR   RD   R   RE   (   R   (   RG   R   (    s;   /usr/lib/python2.7/dist-packages/twisted/test/test_stdio.pyR   ð   s    (   R
   R   R8   R?   (   R   R   R   (    (   RG   R   s;   /usr/lib/python2.7/dist-packages/twisted/test/test_stdio.pyt
   test_writeæ   s
    		c            sD   t  ƒ  ‰  ˆ  j } ˆ j ˆ  d ƒ ‡  ‡ f d †  } ˆ j | | ƒ S(   s˜   
        Verify that the C{writeSequence} method of the transport of a
        protocol connected to L{StandardIO} sends bytes to standard out.
        s   stdio_test_writeseq.pyc            s+   ˆ j  ˆ  j d d ƒ |  j t j ƒ d  S(   Ni   s   ok!(   R`   R   RD   R   RE   (   R   (   RG   R   (    s;   /usr/lib/python2.7/dist-packages/twisted/test/test_stdio.pyR      s    (   R
   R   R8   R?   (   R   R   R   (    (   RG   R   s;   /usr/lib/python2.7/dist-packages/twisted/test/test_stdio.pyt   test_writeSequenceö   s
    		c         C   sW   |  j  ƒ  } t | d ƒ } x+ t d ƒ D] } | j t | ƒ d ƒ q( W| j ƒ  | S(   Nt   wi   s   
(   RI   R@   t   xranget   writeRX   t   close(   R   t   junkPatht   junkFilet   i(    (    s;   /usr/lib/python2.7/dist-packages/twisted/test/test_stdio.pyt	   _junkPath  s    
c            s†   t  ƒ  ‰ ˆ j } g  ‰ t d ƒ ‰ ‡  ‡ ‡ ‡ f d †  ‰  ˆ j ˆ d ƒ ‰ ˆ j j ˆ  ƒ ‡ ‡ ‡ ‡ f d †  } ˆ j | | ƒ S(   s€   
        Verify that the transport of a protocol connected to L{StandardIO}
        is a working L{IProducer} provider.
        id   c            sN   ˆ rJ ˆ j  t ˆ j ƒ  ƒ d ƒ ˆ j ˆ d ƒ t j d ˆ  d  ƒ n  d  S(   Ns   
iÿÿÿÿg{®Gáz„?(   t   appendRX   t   popRe   R   t	   callLaterR   (   t   ign(   R   t   toWritet   writtent   proc(    s;   /usr/lib/python2.7/dist-packages/twisted/test/test_stdio.pyR     s    s   stdio_test_producer.pyc            sQ   ˆ j  ˆ j d d j ˆ ƒ ƒ ˆ j ˆ  d t ˆ  ƒ f ƒ |  j t j ƒ d  S(   Ni   R   s*   Connection lost with %d writes left to go.(   R`   R   R(   t   failIft   lenRD   R   RE   (   R   (   Ro   R   Rp   RG   (    s;   /usr/lib/python2.7/dist-packages/twisted/test/test_stdio.pyR   $  s     (   R
   R   t   rangeR8   R   RO   R?   (   R   R   R   (    (   R   Ro   R   RG   Rp   Rq   s;   /usr/lib/python2.7/dist-packages/twisted/test/test_stdio.pyt   test_producer  s    		c            sV   t  ƒ  ‰ ˆ j } ˆ j ƒ  ‰  ˆ j ˆ d ˆ  ƒ ‡  ‡ ‡ f d †  } ˆ j | | ƒ S(   s€   
        Verify that the transport of a protocol connected to L{StandardIO}
        is a working L{IConsumer} provider.
        s   stdio_test_consumer.pyc            s7   ˆ j  ˆ j d t ˆ  ƒ j ƒ  ƒ |  j t j ƒ d  S(   Ni   (   R`   R   R@   t   readRD   R   RE   (   R   (   Rg   R   RG   (    s;   /usr/lib/python2.7/dist-packages/twisted/test/test_stdio.pyR   7  s    #(   R
   R   Rj   R8   R?   (   R   R   R   (    (   Rg   R   RG   s;   /usr/lib/python2.7/dist-packages/twisted/test/test_stdio.pyt   test_consumer+  s    		c            s.  t  j ƒ  } t | ƒ } t j ˆ j ƒ  ƒ ‰ ˆ j d ƒ ˆ _ } ˆ j | j	 ƒ t
 d | j ƒ  ƒ } t j ƒ  s¹ t j ƒ  \ } } ˆ j t j	 | ƒ ˆ j t j	 | ƒ | | d <n  t j | |  ‰ d ‰  t j ƒ  ‰ ‡ ‡  ‡ ‡ f d †  ‰ t j d ˆ ƒ ‡ ‡  ‡ ‡ f d †  } | j | ƒ | S(   sE  
        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.
        Rc   t   stdoutt   stdini   c             sS   x< ˆ  D]4 }  |  ˆ k r' ˆ j  ƒ  d  Sˆ j t |  ƒ ƒ Pq Wt j d ˆ ƒ d  S(   Ni    (   t   loseConnectionRe   RX   R   Rm   (   t   value(   t   countt   howManyt
   connectiont   spin(    s;   /usr/lib/python2.7/dist-packages/twisted/test/test_stdio.pyR   \  s    
i    c            sL   ˆ j  ˆ  j ƒ  ˆ d ƒ ˆ j  ˆ j ƒ  d j t t t ˆ ƒ ƒ ƒ ƒ d  S(   Ni   R   (   R`   t   nextt
   getContentR(   t   mapRX   Rt   (   R   (   R|   R}   R   R)   (    s;   /usr/lib/python2.7/dist-packages/twisted/test/test_stdio.pyt   cbLosth  s    	(   R   R   R	   R   R/   RI   t   opent   normalt
   addCleanupRf   R$   t   filenoR   t	   isWindowsR%   t   pipeR   t
   StandardIOt	   itertoolsR|   R   Rm   RO   (   R   t
   onConnLostR4   R…   t   kwargst   rRc   Rƒ   (    (   R}   R   R)   R   R|   R~   s;   /usr/lib/python2.7/dist-packages/twisted/test/test_stdio.pyt   test_normalFileStandardOut=  s&    t   EPollReactorsr   epoll(7) does not support normal files.  See #4429.  This should be a todo but technical limitations prevent this.sp   StandardIO does not accept stdout as an argument to Windows.  Testing redirection to a file is therefore harder.c         C   s”   t  j |  j ƒ  ƒ } | j d ƒ } | j ƒ  } |  j | j ƒ |  j t t	 j
 t j ƒ  d | ƒ} |  j t | ƒ d | t j | ƒ j f ƒ d S(   sÚ   
        Using StandardIO with epollreactor with stdout redirected to a
        normal file fails with a comprehensible error (until it is
        supported, when #4429 is resolved).  See also #2259 and #3442.
        Rc   Rx   s’   This reactor does not support this type of file descriptor (fd %d, mode %d) (for example, epollreactor does not support normal files.  See #4429).N(   R   R/   RI   R„   R‡   R†   Rf   t   assertRaisest   RuntimeErrorR   RŠ   R   t   ProtocolR`   RX   R%   t   fstatt   st_mode(   R   R)   R…   t   fdt   exc(    (    s;   /usr/lib/python2.7/dist-packages/twisted/test/test_stdio.pyt(   test_normalFileStandardOutGoodEpollErrorz  s    	sN   Only epollreactor is expected to fail with stdout redirected to a normal file.(   R   R   t   skipWindowsNopywin32t   skipR8   R?   RJ   RP   RZ   R_   Ra   Rb   Rj   Ru   Rw   R   R   R1   R   Rˆ   R˜   (    (    (    s;   /usr/lib/python2.7/dist-packages/twisted/test/test_stdio.pyR    O   s(   	$				'								2	(   R   R%   R-   R‹   t   twisted.trialR    t   twisted.pythonR   R   t   twisted.python.runtimeR   t   twisted.internetR   R   R   R   R   t   twisted.test.test_tcpR	   RT   R   R™   Rˆ   t   win32processt   ImportErrort   ProcessProtocolR
   t   TestCaseR    (    (    (    s;   /usr/lib/python2.7/dist-packages/twisted/test/test_stdio.pyt   <module>   s   $(.