U
     T‚gÆÆ  ã                   @   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Zddl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 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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+ ddl,m-Z- ddl.m/Z/ e-dƒZ0e-dƒZ1e0�rªz\ddl2m3Z3 ddl4m5Z5 ddl6m7Z7 ddl8m9Z9 ddl:m;Z;m<Z< ddl=m>Z> ddlm?Z? W n e@k
�r¨   Y nX dZAde1e0e Bed¡fk�rÊdZAeeAdƒG d d!„ d!e/ƒƒZCG d"d#„ d#e/ƒZDG d$d%„ d%e!ƒZEG d&d'„ d'ƒZFG d(d)„ d)ƒZGeeƒG d*d+„ d+e	ƒƒZHeeAdƒG d,d-„ d-e/ƒƒZIG d.d/„ d/ƒZJG d0d1„ d1ejKƒZLG d2d3„ d3eƒZMeeAdƒG d4d5„ d5eMƒƒZNeeAdƒG d6d7„ d7eMƒƒZOeeAdƒee+d8ƒ d9ƒee+d:ƒ d;ƒG d<d=„ d=eMƒƒƒƒZPdS )>z*
Tests for L{twisted.conch.scripts.cftp}.
é    N)ÚBytesIOÚTextIOWrapper)ÚskipIf)Úimplementer)Úls)Ú	ISFTPFile)ÚFileTransferTestAvatarÚSFTPTestBase)Úportal)ÚdeferÚerrorÚ
interfacesÚprotocolÚreactor)ÚClock)ÚStringTransport)ÚgetProcessOutputAndValue)Úlog)ÚUserDatabase)ÚFilePath)Úwhich)ÚrequireModule)ÚTestCaseÚcryptographyztwisted.conch.unix)Úcftp)Ú
SSHSession)Úfiletransfer)ÚEXTENDED_DATA_STDERR)Ú
test_conchÚtest_ssh)Ú	FakeStdio)ÚFileTransferForTestAvatarFTz*don't run w/o spawnProcess or cryptographyc                   @   s:   e Zd ZdZddœdd„Zddœdd„Zddœdd	„ZdS )
ÚSSHSessionTestsz=
    Tests for L{twisted.conch.scripts.cftp.SSHSession}.
    N)Úreturnc                 C   s<   t ƒ | _tƒ | _| j| j_tƒ | _t| jƒ| _| j| j_d S ©N)r    Ústdior   Úchannelr   ÚstderrBufferr   Ústderr©Úself© r+   ú@/tmp/pip-unpacked-wheel-1_7di8ic/twisted/conch/test/test_cftp.pyÚsetUp>   s    
zSSHSessionTests.setUpc                 C   s   | j  ¡  |  | jj¡ dS )z|
        L{twisted.conch.scripts.cftp.SSHSession.eofReceived} loses the write
        half of its stdio connection.
        N)r&   ZeofReceivedÚ
assertTruer%   ZwriteConnLostr)   r+   r+   r,   Útest_eofReceivedF   s    
z SSHSessionTests.test_eofReceivedc                 C   s:   d}|  d¡}| j t|d ¡ |  | j ¡ |d ¡ dS )zÉ
        L{twisted.conch.scripts.cftp.SSHSession.extReceived} decodes
        stderr data using UTF-8 with the "backslashescape" error handling and
        writes the result to its own stderr.
        u   â˜ƒúutf-8ó   ÿs   \xffN)Úencoder&   ZextReceivedr   ÚassertEqualr'   Úgetvalue)r*   Z	errorTextZ
errorBytesr+   r+   r,   Útest_extReceivedStderrN   s    
þþz&SSHSessionTests.test_extReceivedStderr)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r-   r/   r5   r+   r+   r+   r,   r"   8   s   r"   c                
   @   s¶   e Zd ZdZeeddƒdkr dZdd„ Zdd„ Zd	d
„ Z	dd„ Z
dd„ Ze ¡ Zz6ze ejd¡ W n ejk
r~   dZY nX dZW 5 e eje¡ X eedƒdd„ ƒZdd„ ZdS )ÚListingTestszƒ
    Tests for L{lsLine}, the function which generates an entry for a file or
    directory in an SFTP I{ls} command's output.
    ÚtzsetNz8Cannot test timestamp formatting code without time.tzsetc                    sh   dˆ _ ‡ fdd„}ˆ  td|¡ dtjkrRˆ  tjtjdtjd ¡ ˆ  tj	¡ ndd„ }ˆ  |¡ dS )	zo
        Patch the L{ls} module's time function so the results of L{lsLine} are
        deterministic.
        iÍ[c                      s   ˆ j S r$   )Únowr+   r)   r+   r,   ÚfakeTimep   s    z$ListingTests.setUp.<locals>.fakeTimeÚtimeÚTZc                   S   s.   zt jd= W n tk
r    Y nX t ¡  d S )Nr?   )ÚosÚenvironÚKeyErrorr>   r;   r+   r+   r+   r,   Úcleanup|   s
    z#ListingTests.setUp.<locals>.cleanupN)
r<   Úpatchr   r@   rA   Ú
addCleanupÚoperatorÚsetitemr>   r;   )r*   r=   rC   r+   r)   r,   r-   i   s    
zListingTests.setUpc                 C   s   |t jd< t ¡  t d|¡S )zl
        Call L{ls.lsLine} after setting the timezone to C{timezone} and return
        the result.
        r?   Úfoo)r@   rA   r>   r;   r   ZlsLine)r*   ÚtimezoneÚstatr+   r+   r,   Ú_lsInTimezone†   s    
zListingTests._lsInTimezonec                 C   sT   | j d }t dddddddd|df
¡}|  |  d|¡d¡ |  |  d|¡d¡ dS )z‘
        A file with an mtime six months (approximately) or more in the past has
        a listing including a low-resolution timestamp.
        é€r   úAmerica/New_Yorkz;!---------    0 0        0               0 Apr 26  1973 fooúPacific/Aucklandz;!---------    0 0        0               0 Apr 27  1973 fooN©r<   r@   Ústat_resultr3   rK   ©r*   ÚthenrJ   r+   r+   r,   Útest_oldFile‘   s    

þ
þzListingTests.test_oldFilec                 C   sX   | j d d }t dddddddd|df
¡}|  |  d|¡d¡ |  |  d|¡d¡ dS )	úæ
        A file with a high-resolution timestamp which falls on a day of the
        month which can be represented by one decimal digit is formatted with
        one padding 0 to preserve the columns which come after it.
        rL   i€— r   rM   z;!---------    0 0        0               0 May 01  1973 foorN   z;!---------    0 0        0               0 May 02  1973 fooNrO   rQ   r+   r+   r,   Útest_oldSingleDigitDayOfMonth£   s    
þ
þz*ListingTests.test_oldSingleDigitDayOfMonthc                 C   sT   | j d }t dddddddd|df
¡}|  |  d|¡d¡ |  |  d|¡d¡ dS )z¨
        A file with an mtime fewer than six months (approximately) in the past
        has a listing including a high-resolution timestamp excluding the year.
        é€›z r   rM   ú;!---------    0 0        0               0 Aug 28 17:33 foorN   ú;!---------    0 0        0               0 Aug 29 09:33 fooNrO   rQ   r+   r+   r,   Útest_newFile·   s    

þ
þzListingTests.test_newFileú
es_AR.UTF8TFz'The es_AR.UTF8 locale is not installed.c                 C   s|   | j d }t dddddddd|df
¡}t ¡ }t tjd¡ |  tjtj|¡ |  |  	d|¡d¡ |  |  	d|¡d¡ dS )	zC
        The month name in the date is locale independent.
        rV   r   rZ   rM   rW   rN   rX   N)
r<   r@   rP   ÚlocaleÚ	getlocaleÚ	setlocaleÚLC_ALLrE   r3   rK   )r*   rR   rJ   ÚcurrentLocaler+   r+   r,   Útest_localeIndependentÖ   s    

þ
þz#ListingTests.test_localeIndependentc                 C   sX   | j d d }t dddddddd|df
¡}|  |  d|¡d¡ |  |  d|¡d¡ dS )	rT   rV   i F r   rM   z;!---------    0 0        0               0 Sep 01 17:33 foorN   z;!---------    0 0        0               0 Sep 02 09:33 fooNrO   rQ   r+   r+   r,   Útest_newSingleDigitDayOfMonthí   s    
þ
þz*ListingTests.test_newSingleDigitDayOfMonth)r6   r7   r8   r9   Úgetattrr>   Úskipr-   rK   rS   rU   rY   r[   r\   r_   r]   r^   ÚErrorZ
localeSkipr   r`   ra   r+   r+   r+   r,   r:   `   s&   

r:   c                       s    e Zd ZdZ‡ fdd„Z‡  ZS )ÚInMemorySSHChannelzp
    Minimal implementation of a L{SSHChannel} like class which only reads and
    writes data from memory.
    c                    s   || _ d| _tƒ  ¡  dS )zt
        @param conn: The SSH connection associated with this channel.
        @type conn: L{SSHConnection}
        r   N)ÚconnZlocalClosedÚsuperÚ__init__)r*   rf   ©Ú	__class__r+   r,   rh     s    zInMemorySSHChannel.__init__)r6   r7   r8   r9   rh   Ú__classcell__r+   r+   ri   r,   re     s   re   c                   @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	ÚFilesystemAccessExpectationszC
    A test helper used to support expected filesystem access.
    c                 C   s
   i | _ d S r$   ©Ú_cacher)   r+   r+   r,   rh     s    z%FilesystemAccessExpectations.__init__c                 C   s   || j ||f< dS )zü

        @param path: Path at which the stream is requested.
        @type path: L{str}

        @param path: Flags with which the stream is requested.
        @type path: L{str}

        @param stream: A stream.
        @type stream: C{File}
        Nrm   )r*   ÚpathÚflagsÚstreamr+   r+   r,   Úput  s    z FilesystemAccessExpectations.putc                 C   s   | j  ||f¡S )a  
        Remove a stream from the memory.

        @param path: Path at which the stream is requested.
        @type path: L{str}

        @param path: Flags with which the stream is requested.
        @type path: L{str}

        @return: A stream.
        @rtype: C{File}
        )rn   Úpop)r*   ro   rp   r+   r+   r,   rs   (  s    z FilesystemAccessExpectations.popN)r6   r7   r8   r9   rh   rr   rs   r+   r+   r+   r,   rl     s   rl   c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )ÚInMemorySFTPClienta'  
    A L{filetransfer.FileTransferClient} which does filesystem operations in
    memory, without touching the local disc or the network interface.

    @ivar _availableFiles: File like objects which are available to the SFTP
        client.
    @type _availableFiles: L{FilesystemRegister}
    c                 C   s    t | ƒ| _dddœ| _|| _d S )Né   é
   )ÚrequestsÚ
buffersize)re   Ú	transportÚoptionsÚ_availableFiles)r*   ZavailableFilesr+   r+   r,   rh   B  s
    
þzInMemorySFTPClient.__init__c                 C   s   | j  ||¡S )z}
        @see: L{filetransfer.FileTransferClient.openFile}.

        Retrieve and remove cached file based on flags.
        )r{   rs   )r*   Úfilenamerp   Úattrsr+   r+   r,   ÚopenFileJ  s    zInMemorySFTPClient.openFileN)r6   r7   r8   r9   rh   r~   r+   r+   r+   r,   rt   8  s   	rt   c                   @   sH   e Zd 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S )ÚInMemoryRemoteFilez;
    An L{ISFTPFile} which handles all data in memory.
    c                 C   s   || _ t | ¡ dS )zL
        @param name: Name of this file.
        @type name: L{str}
        N)Únamer   rh   )r*   r€   r+   r+   r,   rh   Y  s    zInMemoryRemoteFile.__init__c                 C   s   |   |¡ |  |¡ t | ¡S )z/
        @see: L{ISFTPFile.writeChunk}
        )ÚseekÚwriter   Úsucceed)r*   ÚstartÚdatar+   r+   r,   Ú
writeChunka  s    

zInMemoryRemoteFile.writeChunkc                 C   s
   d| _ dS )zo
        @see: L{ISFTPFile.writeChunk}

        Keeps data after file was closed to help with testing.
        TN)Ú_closedr)   r+   r+   r,   Úclosei  s    zInMemoryRemoteFile.closec                 C   s   d S r$   r+   r)   r+   r+   r,   ÚgetAttrsq  s    zInMemoryRemoteFile.getAttrsc                 C   s   d S r$   r+   )r*   ÚoffsetÚlengthr+   r+   r,   Ú	readChunku  s    zInMemoryRemoteFile.readChunkc                 C   s   d S r$   r+   )r*   r}   r+   r+   r,   ÚsetAttrsy  s    zInMemoryRemoteFile.setAttrsc                 C   s
   t  | ¡S )zb
        Get current data of file.

        Allow reading data event when file is closed.
        )r   r4   r)   r+   r+   r,   r4   }  s    zInMemoryRemoteFile.getvalueN)r6   r7   r8   r9   rh   r†   rˆ   r‰   rŒ   r�   r4   r+   r+   r+   r,   r   S  s   r   c                   @   s¤   e Zd 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d„Zd*dd „Zd!d"„ Zd#d$„ Zd%d&„ Zd'd(„ ZdS )+ÚStdioClientTestsz(
    Tests for L{cftp.StdioClient}.
    c                 C   sT   t ƒ | _t| jƒ}t |¡| _d| j_tƒ  | _| j_	|  
dd¡ | jjj| j_dS )zm
        Create a L{cftp.StdioClient} hooked up to dummy transport and a fake
        user database.
        ú/iô  é   N)rl   ÚfakeFilesystemrt   r   ÚStdioClientÚclientZcurrentDirectoryr   ÚdatabaseÚ_pwdÚsetKnownConsoleSizery   )r*   Z
sftpClientr+   r+   r,   r-   Œ  s    
zStdioClientTests.setUpc              	   C   s@   | j  t ¡ dt ¡ dddtj¡ | j 	d¡}| 
| jd¡ |S )zs
        The I{exec} command runs its arguments locally in a child process
        using the user's shell.
        ÚsecretéÒ  rH   Úbarzexec print(1 + 2)s   3
)r”   ÚaddUserÚgetpassÚgetuserr@   ÚgetuidÚsysÚ
executabler“   Ú_dispatchCommandÚaddCallbackr3   ©r*   Údr+   r+   r,   Ú	test_execŸ  s          ÿzStdioClientTests.test_execc              	   C   s>   | j  t ¡ dt ¡ dddd¡ | j d¡}| | j	d¡ |S )zr
        If the local user has no shell, the I{exec} command runs its arguments
        using I{/bin/sh}.
        r—   r˜   rH   r™   Ú zexec echo helloó   hello
©
r”   rš   r›   rœ   r@   r�   r“   r    r¡   r3   r¢   r+   r+   r,   Útest_execWithoutShell¬  s          ÿz&StdioClientTests.test_execWithoutShellc              	   C   s>   | j  t ¡ dt ¡ dddd¡ | j d¡}| | j	d¡ |S )zO
        The I{exec} command is run for lines which start with C{"!"}.
        r—   r˜   rH   r™   z/bin/shz!echo hellor¦   r§   r¢   r+   r+   r,   Ú	test_bang¹  s          ÿzStdioClientTests.test_bangc                    s2   ddl ‰G ‡ ‡‡fdd„dƒ}|  td|ƒ ¡ dS )a  
        For the duration of this test, patch C{cftp}'s C{fcntl} module to return
        a fixed width and height.

        @param width: the width in characters
        @type width: L{int}
        @param height: the height in characters
        @type height: L{int}
        r   Nc                       s   e Zd Z‡ ‡‡fdd„ZdS )z7StdioClientTests.setKnownConsoleSize.<locals>.FakeFcntlc                    s&   |ˆj kr|  d¡ t dˆ ˆdd¡S )Nz#Only window-size queries supported.Z4Hr   )Ú
TIOCGWINSZZfailÚstructÚpack)r*   ÚfdÚoptZmutate©ÚheightÚttyÚwidthr+   r,   ÚioctlÓ  s    

z=StdioClientTests.setKnownConsoleSize.<locals>.FakeFcntl.ioctlN)r6   r7   r8   r³   r+   r¯   r+   r,   Ú	FakeFcntlÒ  s   r´   Zfcntl)r±   rD   r   )r*   r²   r°   r´   r+   r¯   r,   r–   Å  s    z$StdioClientTests.setKnownConsoleSizec                 C   s‚   |   dd¡ tƒ  }| j_tdƒ}d|_t |¡}d|_| 	¡ }| 
d¡ | jd7  _| j ||¡ d}|  | jj ¡ |¡ d	S )
a(  
        L{StdioClient._printProgressBar} prints a progress description,
        including percent done, amount transferred, transfer rate, and time
        remaining, all based the given start time, the given L{FileWrapper}'s
        progress information and the reactor's current time.
        rv   é"   ó   xó   samplei (  g       @i   s#   b'sample' 40% 4.0kB 2.0kBps 00:03 N)r–   r   r“   r   r   r€   r   ÚFileWrapperÚsizeÚsecondsZadvanceÚtotalÚ_printProgressBarr3   ry   Úvalue©r*   ZclockÚwrappedÚwrapperZ	startTimeÚresultr+   r+   r,   Útest_printProgressBarReportingÚ  s    	

z/StdioClientTests.test_printProgressBarReportingc                 C   sd   |   dd¡ tƒ  }| j_tdƒ}d|_t |¡}| ¡ }| j 	||¡ d}|  
| jj ¡ |¡ dS )z½
        L{StdioClient._printProgressBar} prints a progress description that
        indicates 0 bytes transferred if no bytes have been transferred and no
        time has passed.
        rv   rµ   r¶   r·   s!   b'sample'  0% 0.0B 0.0Bps 00:00 N)r–   r   r“   r   r   r€   r   r¸   rº   r¼   r3   ry   r½   r¾   r+   r+   r,   Útest_printProgressBarNoProgressò  s    
z0StdioClientTests.test_printProgressBarNoProgressc                 C   sL   |   dd¡ tƒ }d|_t |¡}| j |d¡ d}|  || jj 	¡ ¡ dS )z5
        Print the progress for empty files.
        rv   rµ   s
   empty-filer   s%   b'empty-file'100% 0.0B 0.0Bps 00:00 N)
r–   r   r€   r   r¸   r“   r¼   r3   ry   r½   )r*   r¿   rÀ   rÁ   r+   r+   r,   Útest_printProgressBarEmptyFile  s    
z/StdioClientTests.test_printProgressBarEmptyFilec                 C   s   | j  d¡}|  d|¡ dS )zK
        Returns empty value for both filename and remaining data.
        z  )r¥   r¥   N©r“   Z_getFilenamer3   ©r*   rÁ   r+   r+   r,   Útest_getFilenameEmpty  s    z&StdioClientTests.test_getFilenameEmptyc                 C   s   | j  d¡}|  d|¡ dS )zd
        Returns empty value for remaining data when line contains
        only a filename.
        ú
only-local)rÈ   r¥   NrÅ   rÆ   r+   r+   r,   Útest_getFilenameOnlyLocal  s    z*StdioClientTests.test_getFilenameOnlyLocalc                 C   s   | j  d¡}|  d|¡ dS )ze
        Returns filename and remaining data striped of leading and trailing
        spaces.
        z local  remote file  )Úlocalzremote fileNrÅ   rÆ   r+   r+   r,   Útest_getFilenameNotQuoted#  s    z*StdioClientTests.test_getFilenameNotQuotedc                 C   s   | j  d¡}|  d|¡ dS )z‰
        Returns filename and remaining data not striped of leading and trailing
        spaces when quoted paths are requested.
        z" " local file "  " remote  file " )z local file z" remote  file "NrÅ   rÆ   r+   r+   r,   Útest_getFilenameQuoted,  s    z'StdioClientTests.test_getFilenameQuotedNó    c              	   C   s4   |dkr|   ¡ }t|dƒ�}| |¡ W 5 Q R X |S )ab  
        Create a local file and return its path.

        When `path` is L{None}, it will create a new temporary file.

        @param path: Optional path for the new file.
        @type path: L{str}

        @param content: Content to be written in the new file.
        @type content: L{bytes}

        @return: Path to the newly create file.
        NÚwb)ÚmktempÚopenr‚   )r*   ro   ÚcontentÚfiler+   r+   r,   ÚmakeFile5  s
    zStdioClientTests.makeFileFc                 C   sj  | j j ¡ }| d¡}| d¡}g }g }|D ]þ\}}}g }	|D ]}
|	 |› d|
› �¡ q>|	 d|› d|› �¡ | |	¡ | d¡ d¡ d¡}|dd	… }|d	  d
¡ d
¡}| |¡ g }|dd	… D ]H}
|
 ¡  	dd¡d }
|
 ¡  dd¡}
| |
d › d|
d  ¡ › �¡ qÈ| |d	 ¡ | |¡ q,|�rH|  
t|ƒt|ƒ¡ n|  
||¡ |  
dt|ƒd¡ dS )a  
        Check output of cftp client for a put request.


        @param transfers: List with tuple of (local, remote, progress).
        @param randomOrder: When set to C{True}, it will ignore the order
            in which put reposes are received

        r0   z
ú zTransferred z to r   úNéÿÿÿÿÚ
é   ru   z5There are still put responses which were not checked.)r“   ry   r½   ÚdecodeÚsplitÚappendrs   ÚstripÚextendÚrsplitr3   ÚsortedÚlen)r*   Z	transfersÚrandomOrderÚoutputÚexpectedOutputZactualOutputrÊ   ÚremoteÚexpectedZexpectedTransferÚlineZprogressPartsÚactualÚlastZactualTransferr+   r+   r,   ÚcheckPutMessageI  s<    




"ýz StdioClientTests.checkPutMessagec                 C   s²   d}| j |d�}tjtjB tjB }tj dtj |¡¡}t	|ƒ}| j
 ||t |¡¡ d| jjjd< | j |¡}|  |¡ |  || ¡ ¡ |  |j¡ |  ||dddgfg¡ dS )	z�
        A name based on local path is used when remote path is not
        provided.

        The progress is updated while chunks are transferred.
        s   Test
Content)rÑ   r�   rv   rx   z	76% 10.0Bz
100% 13.0BN)rÓ   r   Ú	FXF_WRITEÚ	FXF_CREATÚ	FXF_TRUNCr@   ro   ÚjoinÚbasenamer   r‘   rr   r   rƒ   r“   rz   Úcmd_PUTÚsuccessResultOfr3   r4   r.   r‡   ré   )r*   rÑ   Ú	localPathrp   Ú
remoteNameÚ
remoteFileÚdeferredr+   r+   r,   Útest_cmd_PUTSingleNoRemotePath†  s    
ÿz/StdioClientTests.test_cmd_PUTSingleNoRemotePathc                 C   s’   |   ¡ }tjtjB tjB }d}t|ƒ}| j ||t 	|¡¡ | j
 |› d|› d�¡}|  |¡ |  ||dgfg¡ |  |j¡ |  d| ¡ ¡ dS )z€
        Remote path is extracted from first filename after local file.

        Any other data in the line is ignored.
        z/remote-pathrÔ   z ignoredú	100% 0.0BrÍ   N)rÓ   r   rê   rë   rì   r   r‘   rr   r   rƒ   r“   rï   rð   ré   r.   r‡   r3   r4   )r*   rñ   rp   rò   ró   rô   r+   r+   r,   Útest_cmd_PUTSingleRemotePathž  s    
z-StdioClientTests.test_cmd_PUTSingleRemotePathc                 C   s  |   ¡ }tj |¡}d}tj |¡}| j tj ||¡d�}tjtjB tj	B }d|› �}d|› �}t
|ƒ}	t
|ƒ}
| j ||t |	¡¡ | j ||t |
¡¡ | j tj |d¡¡}|  |¡ |  |	j¡ |  d|	 ¡ ¡ |  |
j¡ |  d|
 ¡ ¡ | j||dgf||dgfgdd� d	S )
z„
        When a gobbing expression is used local files are transferred with
        remote file names based on local names.
        úsecond-name©ro   r�   Ú*rÍ   rö   T©rá   N)rÓ   r@   ro   rî   Údirnamerí   r   rê   rë   rì   r   r‘   rr   r   rƒ   r“   rï   rð   r.   r‡   r3   r4   ré   )r*   ÚfirstÚ	firstNameÚ
secondNameÚparentÚsecondrp   ÚfirstRemotePathÚsecondRemotePathÚfirstRemoteFileÚsecondRemoteFilerô   r+   r+   r,   Ú test_cmd_PUTMultipleNoRemotePath±  s8    

  ÿ


þûz1StdioClientTests.test_cmd_PUTMultipleNoRemotePathc                 C   s   |   ¡ }tj |¡}d}tj |¡}| j tj ||¡d�}tjtjB tj	B }t
|ƒ}t
|ƒ}d|› �}	d|› �}
| j |	|t |¡¡ | j |
|t |¡¡ | j d tj |d¡¡¡}|  |¡ |  |j¡ |  d| ¡ ¡ |  |j¡ |  d| ¡ ¡ | j||dgf||dgfgdd	� d
S )zõ
        When a gobbing expression is used local files are transferred with
        remote file names based on local names.
        when a remote folder is requested remote paths are composed from
        remote path and local filename.
        rø   rù   z/remote/z	{} remoterú   rÍ   rö   Trû   N)rÓ   r@   ro   rî   rü   rí   r   rê   rë   rì   r   r‘   rr   r   rƒ   r“   rï   Úformatrð   r.   r‡   r3   r4   ré   )r*   rý   rþ   rÿ   r   r  rp   r  r  r  r  rô   r+   r+   r,   Ú"test_cmd_PUTMultipleWithRemotePathÔ  s8    

  ÿ


þûz3StdioClientTests.test_cmd_PUTMultipleWithRemotePath)NrÍ   )F)r6   r7   r8   r9   r-   r¤   r¨   r©   r–   rÂ   rÃ   rÄ   rÇ   rÉ   rË   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S )ÚFileTransferTestRealmc                 C   s
   || _ d S r$   )ÚtestDir)r*   r
  r+   r+   r,   rh   û  s    zFileTransferTestRealm.__init__c                 G   s   t | jƒ}|d |dd„ fS )Nr   c                   S   s   d S r$   r+   r+   r+   r+   r,   Ú<lambda>   rÍ   z5FileTransferTestRealm.requestAvatar.<locals>.<lambda>)r   r
  )r*   ZavatarIDZmindr   Úar+   r+   r,   ÚrequestAvatarþ  s    
z#FileTransferTestRealm.requestAvatarN)r6   r7   r8   rh   r  r+   r+   r+   r,   r	  ú  s   r	  c                   @   s`   e Zd 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S )ÚSFTPTestProcessz³
    Protocol for testing cftp. Provides an interface between Python (where all
    the tests are) and the cftp client process (which does the work that is
    being tested).
    c                 C   s$   |   ¡  || _d| _d| _d| _dS )zr
        @param onOutReceived: A L{Deferred} to be fired as soon as data is
        received from stdout.
        NF)ÚclearBufferÚonOutReceivedÚonProcessEndÚ_expectingCommandÚ_processEnded)r*   r  r+   r+   r,   rh   
  s
    zSFTPTestProcess.__init__c                 C   s   d| _ g | _d| _dS )zR
        Clear any buffered data received from stdout. Should be private.
        rÍ   N)ÚbufferÚ_linesReceivedÚ_lineBufferr)   r+   r+   r,   r    s    zSFTPTestProcess.clearBufferc                 C   sr   t  d| ¡ | j|  d¡}| d¡| _| j |¡ | jdk	rX| jd }| _| |¡ |  j	|7  _	|  
¡  dS )zO
        Called by Twisted when the cftp client prints data to stdout.
        zgot %ró   
rÖ   N)r   Úmsgr  rÚ   rs   r  rÝ   r  Úcallbackr  Ú_checkForCommand)r*   r…   Úlinesr£   r+   r+   r,   ÚoutReceived  s    

zSFTPTestProcess.outReceivedc                 C   s^   d}| j rZ| j|krZd | j¡}| |¡r:|t|ƒd … }|  ¡  | j d  }| _ | |¡ d S )Ns   cftp> r  )r  r  rí   r  Ú
startswithrà   r  r  )r*   ÚpromptÚbufr£   r+   r+   r,   r  .  s    
z SFTPTestProcess._checkForCommandc                 C   s   t  d| ¡ dS )zO
        Called by Twisted when the cftp client prints data to stderr.
        zerr: %sN)r   r  )r*   r…   r+   r+   r,   ÚerrReceived8  s    zSFTPTestProcess.errReceivedc                 C   s   | j S )zQ
        Return the contents of the buffer of data received from stdout.
        )r  r)   r+   r+   r,   Ú	getBuffer>  s    zSFTPTestProcess.getBufferc                 C   s<   t  ¡ | _|  ¡  t|tƒr&| d¡}| j |d ¡ | jS )a¬  
        Issue the given command via the cftp client. Return a C{Deferred} that
        fires when the server returns a result. Note that the C{Deferred} will
        callback even if the server returns some kind of error.

        @param command: A string containing an sftp command.

        @return: A C{Deferred} that fires when the sftp server returns a
        result. The payload is the server's response string.
        r0   r  )	r   ÚDeferredr  r  Ú
isinstanceÚstrr2   ry   r‚   ©r*   Úcommandr+   r+   r,   Ú
runCommandD  s    


zSFTPTestProcess.runCommandc                    s(   t  d¡‰‡ ‡fdd„|D ƒ}t  |¡S )ax  
        Run each command in sequence and return a Deferred that fires when all
        commands are completed.

        @param commands: A list of strings containing sftp commands.

        @return: A C{Deferred} that fires when all commands are completed. The
        payload is a list of response strings from the server, in the same
        order as the commands.
        ru   c                    s   g | ]}ˆ  ˆ j|¡‘qS r+   )Úrunr'  )Ú.0r&  ©r*   Zsemr+   r,   Ú
<listcomp>b  s     z-SFTPTestProcess.runScript.<locals>.<listcomp>)r   ZDeferredSemaphoreZgatherResults)r*   ÚcommandsÚdlr+   r*  r,   Ú	runScriptV  s    
zSFTPTestProcess.runScriptc                 C   s,   | j rt d¡S t ¡ | _| j d¡ | jS )zø
        Kill the process if it is still running.

        If the process is still running, sends a KILL signal to the transport
        and returns a C{Deferred} which fires when L{processEnded} is called.

        @return: a C{Deferred}.
        NÚKILL)r  r   rƒ   r"  r  ry   ÚsignalProcessr)   r+   r+   r,   ÚkillProcesse  s
    	

zSFTPTestProcess.killProcessc                 C   s(   d| _ | jr$| jd }| _| d¡ dS )zF
        Called by Twisted when the cftp client process ends.
        TN)r  r  r  )r*   Úreasonr£   r+   r+   r,   ÚprocessEndedt  s    zSFTPTestProcess.processEndedN)r6   r7   r8   r9   rh   r  r  r  r   r!  r'  r.  r1  r3  r+   r+   r+   r,   r    s   
r  c                   @   s4   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ ZdS )ÚCFTPClientTestBasec              	   C   s€   t ddƒ�}| tj¡ W 5 Q R X t ddƒ�}| tj¡ W 5 Q R X t dd¡ t ddƒ�}| dtj ¡ W 5 Q R X t | ¡S )Núrsa_test.pubrÎ   Úrsa_testi€�  Úkh_tests
   127.0.0.1 )	rÐ   r‚   r   ZpublicRSA_opensshZprivateRSA_opensshr@   Úchmodr	   r-   ©r*   Úfr+   r+   r,   r-     s    zCFTPClientTestBase.setUpc                 C   sF   t | jƒ}t |¡}| t ¡ ¡ t ¡ }||_tj	d|dd�| _
d S )Nr   z	127.0.0.1)Z	interface)r	  r
  r
   ZPortalZregisterCheckerr   ZconchTestPublicKeyCheckerZConchTestServerFactoryr   Z	listenTCPÚserver)r*   ÚrealmÚpZfacr+   r+   r,   ÚstartServer‰  s    

zCFTPClientTestBase.startServerc                 C   sH   t | jjdƒs|  d ¡S d| jjj_t | jjjjj	¡}| 
| j¡ |S )NÚprotoru   )Úhasattrr;  ÚfactoryÚ_cbStopServerr?  ÚexpectedLoseConnectionr   ÚmaybeDeferredry   ZloseConnectionr¡   r¢   r+   r+   r,   Ú
stopServer‘  s    
zCFTPClientTestBase.stopServerc                 C   s   t  | jj¡S r$   )r   rD  r;  ÚstopListening©r*   Úignoredr+   r+   r,   rB  ™  s    z CFTPClientTestBase._cbStopServerc              	   C   s8   dD ](}zt  |¡ W q tk
r*   Y qX qt | ¡S )N)r5  r6  r7  )r@   ÚremoveÚBaseExceptionr	   ÚtearDownr9  r+   r+   r,   rK  œ  s    zCFTPClientTestBase.tearDownN)r6   r7   r8   r-   r>  rE  rB  rK  r+   r+   r+   r,   r4  ~  s
   
r4  c                   @   sº   e Zd 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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 ).ÚOurServerCmdLineClientTestszí
    Functional tests which launch a SFTP server over TCP on localhost and check
    cftp command line interface using a spawned process.

    Due to the spawned process you can not add a debugger breakpoint for the
    client code.
    c           
         s0  t  ˆ ¡ ˆ  ¡  d}ˆ j ¡ j}tj||  ¡ dd�}t	 
dtj› d|› �¡ t ¡ }t|ƒˆ _| ‡ fdd„¡ tj ¡ }tj tj¡|d< g }i }|D ]"}t|tƒr´| d	¡}| |¡ qœ|D ]<}|| }	t|tƒrä| d	¡}t|	tƒrø|	 d	¡}	|	||< qÄt	 
|¡ t	 
|¡ tjˆ jtj||d
� |S )Nz‚-p %i -l testuser --known-hosts kh_test --user-authentications publickey --host-key-algorithms ssh-rsa -i rsa_test -a -v 127.0.0.1r   ©Úmodúrunning rÔ   c                    s
   ˆ j  ¡ S r$   )ÚprocessProtocolr  ©Ú_r)   r+   r,   r  Â  rÍ   z3OurServerCmdLineClientTests.setUp.<locals>.<lambda>Ú
PYTHONPATHr0   ©Úenv)r4  r-   r>  r;  ÚgetHostÚportr   Ú	_makeArgsrÚ   r   r  rž   rŸ   r   r"  r  rP  r¡   r@   rA   ÚcopyÚpathseprí   ro   r#  r$  r2   rÛ   r   ZspawnProcess)
r*   ÚcmdsrW  r£   rU  ZencodedCmdsZ
encodedEnvÚcmdÚvarÚvalr+   r)   r,   r-   ¯  sD    
ÿ











   ÿz!OurServerCmdLineClientTests.setUpc                    s   ˆ   ¡ }| ‡ fdd„¡ |S )Nc                    s
   ˆ j  ¡ S r$   )rP  r1  rQ  r)   r+   r,   r  Û  rÍ   z6OurServerCmdLineClientTests.tearDown.<locals>.<lambda>)rE  r¡   r¢   r+   r)   r,   rK  Ù  s    z$OurServerCmdLineClientTests.tearDownc                 C   s.   z| j j d¡ W n tjk
r(   Y nX d S )Nr/  )rP  ry   r0  r   ZProcessExitedAlreadyrG  r+   r+   r,   Ú_killProcessÞ  s    z(OurServerCmdLineClientTests._killProcessc                 C   s   | j  |¡S )z¼
        Run the given command with the cftp client. Return a C{Deferred} that
        fires when the command is complete. Payload is the server's output for
        that command.
        )rP  r'  r%  r+   r+   r,   r'  ä  s    z&OurServerCmdLineClientTests.runCommandc                 G   s   | j  |¡S )zÓ
        Run the given commands with the cftp client. Returns a C{Deferred}
        that fires when the commands are all complete. The C{Deferred}'s
        payload is a list of output for each command.
        )rP  r.  )r*   r,  r+   r+   r,   r.  ì  s    z%OurServerCmdLineClientTests.runScriptc                 C   sL   | j }|  ddddd¡}dd„ }| |¡ | | j|jt ¡ d|jg¡ |S )zý
        Test that 'pwd' reports the current remote directory, that 'lpwd'
        reports the current local directory, and that changing to a
        subdirectory then changing to its parent leaves you in the original
        remote directory.
        ÚpwdZlpwdzcd testDirectoryúcd ..c                 S   sD   g }| D ]"}t |tƒr | d¡}| |¡ q|dd… |dd…  S )zH
            Callback function for handling command output.
            r0   Né   é   )r#  ÚbytesrÙ   rÛ   )râ   r[  r\  r+   r+   r,   Ú	cmdOutputÿ  s    

z8OurServerCmdLineClientTests.testCdPwd.<locals>.cmdOutputr¥   )r
  r.  r¡   r3   ro   r@   Úgetcwd)r*   ZhomeDirr£   re  r+   r+   r,   Ú	testCdPwdô  s    
z%OurServerCmdLineClientTests.testCdPwdc                    s&   ‡ fdd„}ˆ   dddd¡}| |¡S )zŒ
        Check that 'ls -l' output includes the access permissions and that
        this output changes appropriately with 'chmod'.
        c                    sZ   ˆ   ¡  ˆ  | d  d¡¡ ˆ  | d d¡ ˆ  | d  d¡| d ¡ ˆ  | d d¡ d S )Nr   s
   -rw-r--r--ru   rÍ   rØ   s
   ----------rb  )ÚflushLoggedErrorsr.   r  r3   ©Úresultsr)   r+   r,   Ú_check  s
    z7OurServerCmdLineClientTests.testChAttrs.<locals>._checkzls -l testfile1zchmod 0 testfile1zchmod 644 testfile1©r.  r¡   ©r*   rk  r£   r+   r)   r,   ÚtestChAttrs  s    üz'OurServerCmdLineClientTests.testChAttrsc                    s@   ‡ fdd„}ˆ   ddˆ j ¡  ddd¡}| dd	„ ¡ | |¡S )
zŽ
        Check 'ls' works as expected. Checks for wildcards, hidden files,
        listing directories and listing empty directories.
        c                    sp   ˆ   | d ddddg¡ ˆ   | d ddddg¡ ˆ   | d ddg¡ ˆ   | d d	ddg¡ ˆ   | d
 dg¡ d S )Nr   ó   testDirectoryó   testRemoveFileó   testRenameFileó	   testfile1ru   rØ   rb  s   .testHiddenFilerc  rÍ   ©r3   ri  r)   r+   r,   rk  *  s    
þ
þ ÿz4OurServerCmdLineClientTests.testList.<locals>._checkr   zls ../zls *Filezls -a *Filezls -l testDirectoryc                 S   s   dd„ | D ƒS )Nc                 S   s   g | ]}|  d ¡‘qS )r  )rÚ   )r)  Úxr+   r+   r,   r+  @  s     zJOurServerCmdLineClientTests.testList.<locals>.<lambda>.<locals>.<listcomp>r+   )Úxsr+   r+   r,   r  @  rÍ   z6OurServerCmdLineClientTests.testList.<locals>.<lambda>)r.  r
  rî   r¡   rm  r+   r)   r,   ÚtestList$  s    ûz$OurServerCmdLineClientTests.testListc                 C   sD   |   d¡}t d¡ d¡ ¡ }t|tƒr2| d¡}| | j	|¡ |S )zB
        Check that running the '?' command returns help.
        ú?Nr¥   r0   )
r'  r   r’   Zcmd_HELPrÜ   r#  r$  r2   r¡   r3   )r*   r£   ZhelpTextr+   r+   r,   ÚtestHelpC  s    


z$OurServerCmdLineClientTests.testHelpNc                 C   s   |   | ¡ | ¡ |¡ dS )zg
        Assert that the files at C{name1} and C{name2} contain exactly the
        same data.
        N)r3   Z
getContent)r*   Zname1Zname2r  r+   r+   r,   ÚassertFilesEqualO  s    z,OurServerCmdLineClientTests.assertFilesEqualc                    sl   d  ˆjjˆjj¡‰ tˆ tƒr(ˆ  d¡‰ ‡ ‡fdd„}ˆ dˆjj› d�¡}| |¡ | ‡fdd„¡ |S )	z³
        Test that 'get' saves the remote file to the correct local location,
        that the output of 'get' is correct and that 'rm' actually removes
        the file.
        z)Transferred {}/testfile1 to {}/test file2r0   c                    s8   ˆ  |  ˆ ¡¡ ˆ ˆj d¡ˆj d¡d¡ ˆ d¡S )NÚ	testfile1ú
test file2z
get failedzrm "test file2")r.   Úendswithry  r
  Úchildr'  ©rÁ   ©rã   r*   r+   r,   Ú	_checkGetd  s    

ýz6OurServerCmdLineClientTests.testGet.<locals>._checkGetzget testfile1 "z/test file2"c                    s   ˆ   ˆ j d¡ ¡ ¡S )Nr{  ©ZassertFalser
  r}  ÚexistsrQ  r)   r+   r,   r  p  rÍ   z5OurServerCmdLineClientTests.testGet.<locals>.<lambda>)r  r
  ro   r#  r$  r2   r'  r¡   )r*   r€  r£   r+   r  r,   ÚtestGetV  s    þ

	

ÿz#OurServerCmdLineClientTests.testGetc                    s    ‡ fdd„}ˆ   d¡}| |¡S )zQ
        Test that 'get' works correctly when given wildcard parameters.
        c                    s8   ˆ   ˆ j d¡tdƒd¡ ˆ   ˆ j d¡tdƒd¡ d S )NÚtestRemoveFileútestRemoveFile get failedÚtestRenameFileútestRenameFile get failed)ry  r
  r}  r   )rH  r)   r+   r,   rk  y  s    
ý
ýz;OurServerCmdLineClientTests.testWildcardGet.<locals>._checkz
get testR*)r'  r¡   rm  r+   r)   r,   ÚtestWildcardGett  s    
z+OurServerCmdLineClientTests.testWildcardGetc                    sh   dˆj  ¡ j d ˆj  ¡ j d ‰ ‡ ‡fdd„}ˆ dˆj j› d�¡}| |¡ | ‡fdd	„¡ |S )
z—
        Check that 'put' uploads files correctly and that they can be
        successfully removed. Also check the output of the put command.
        s   Transferred s   /testfile1 to s   /test"file2c                    s6   ˆ  ˆj d¡ˆj d¡¡ ˆ |  ˆ ¡¡ ˆ d¡S )Nrz  ú
test"file2zrm "test\"file2")ry  r
  r}  r.   r|  r'  r~  r  r+   r,   Ú	_checkPut–  s    
 
ÿz6OurServerCmdLineClientTests.testPut.<locals>._checkPutúput z/testfile1 "test\"file2"c                    s   ˆ   ˆ j d¡ ¡ ¡S )Nr‰  r�  rQ  r)   r+   r,   r     rÍ   z5OurServerCmdLineClientTests.testPut.<locals>.<lambda>)r
  ÚasBytesModero   r'  r¡   )r*   rŠ  r£   r+   r  r,   ÚtestPutˆ  s"    
ÿþ
ýüÿ

ÿz#OurServerCmdLineClientTests.testPutc              	      s„   ˆ j  d¡jdd��}| d¡ W 5 Q R X ˆ j  d¡jdd��}| d¡ W 5 Q R X ‡ fdd„}ˆ  d	ˆ j j› d
�¡}| |¡ |S )zb
        Check that 'put' uploads files correctly when overwriting a longer
        file.
        ÚshorterFileÚw©Úmodeó   aÚ
longerFileó   bbc                    s    ˆ   ˆ j d¡ˆ j d¡¡ d S )NrŽ  r“  )ry  r
  r}  r~  r)   r+   r,   rŠ  ¯  s    
 
ÿzEOurServerCmdLineClientTests.test_putOverLongerFile.<locals>._checkPutr‹  z/shorterFile longerFile)r
  r}  rÐ   r‚   r'  ro   r¡   ©r*   r:  rŠ  r£   r+   r)   r,   Útest_putOverLongerFile¤  s    
z2OurServerCmdLineClientTests.test_putOverLongerFilec              	      s˜   ˆ j  d¡‰ˆ ¡  ˆ d¡jdd��}| d¡ W 5 Q R X ˆ j  d¡jdd��}| d¡ W 5 Q R X ‡ ‡fdd„}ˆ  d	ˆ j j› d
�¡}| |¡ |S )z˜
        Check that 'put' uploads files correctly when overwriting a longer
        file and you use a wildcard to specify the files to upload.
        ÚdirrÒ   r�  r�  r’  r”  c                    s   ˆ   ˆ d¡ˆ j d¡¡ d S )NrÒ   )ry  r}  r
  r~  ©r*   ZsomeDirr+   r,   rŠ  Å  s    zMOurServerCmdLineClientTests.test_putMultipleOverLongerFile.<locals>._checkPutr‹  z/dir/*)r
  r}  ZcreateDirectoryrÐ   r‚   r'  ro   r¡   r•  r+   r˜  r,   Útest_putMultipleOverLongerFile¸  s    
z:OurServerCmdLineClientTests.test_putMultipleOverLongerFilec                    s>   ‡ fdd„}ˆ   ddˆ jj› d�dˆ j ¡  ¡}| |¡ |S )zÍ
        What happens if you issue a 'put' command and include a wildcard (i.e.
        '*') in parameter? Check that all files matching the wildcard are
        uploaded to the correct directory.
        c                    sh   ˆ   | d d¡ ˆ   | d d¡ ˆ  ˆ j d¡ˆ j ¡  d¡d¡ ˆ  ˆ j d¡ˆ j ¡  d¡d¡ d S )Nr   rÍ   rØ   r„  r…  r†  r‡  )r3   ry  r
  r}  r   ri  r)   r+   r,   ÚcheckÓ  s    
ý
ýz:OurServerCmdLineClientTests.testWildcardPut.<locals>.checkra  r‹  z/testR*zcd %s)r.  r
  ro   rî   r¡   )r*   rš  r£   r+   r)   r,   ÚtestWildcardPutÌ  s    ý
z+OurServerCmdLineClientTests.testWildcardPutc                    s4   ‡ fdd„}ˆ   dd¡}| |¡ | ˆ jd¡ |S )z 
        Test that 'ln' creates a file which appears as a link in the output of
        'ls'. Check that removing the new file succeeds without output.
        c                    s8   ˆ   ¡  ˆ  | d d¡ ˆ  | d  d¡d¡ ˆ  d¡S )Nr   rÍ   ru   ó   lzlink failedzrm testLink)rh  r3   r.   r  r'  ri  r)   r+   r,   rk  ð  s    z4OurServerCmdLineClientTests.testLink.<locals>._checkzln testLink testfile1zls -l testLinkrÍ   ©r.  r¡   r3   rm  r+   r)   r,   ÚtestLinkê  s
    
z$OurServerCmdLineClientTests.testLinkc                    s4   ‡ fdd„}ˆ   dd¡}| |¡ | ˆ jd¡ |S )zV
        Test that we can create and remove directories with the cftp client.
        c                    s.   ˆ   | d d¡ ˆ  | d  d¡¡ ˆ  d¡S )Nr   rÍ   ru   ó   dzrmdir testMakeDirectory)r3   r.   r  r'  ri  r)   r+   r,   rk     s    z?OurServerCmdLineClientTests.testRemoteDirectory.<locals>._checkúmkdir testMakeDirectoryzls -l testMakeDirector?rÍ   r�  rm  r+   r)   r,   ÚtestRemoteDirectoryû  s
    
z/OurServerCmdLineClientTests.testRemoteDirectoryc                    s&   ‡ fdd„}ˆ   dd¡}| |¡ |S )z—
        Test that a C{mkdir} on an existing directory fails with the
        appropriate error, and doesn't log an useless error server side.
        c                    s$   ˆ   | d d¡ ˆ   | d d¡ d S )Nr   rÍ   ru   s   remote error 11: mkdir failedrs  ri  r)   r+   r,   rk    s    zHOurServerCmdLineClientTests.test_existingRemoteDirectory.<locals>._checkr   rl  rm  r+   r)   r,   Útest_existingRemoteDirectory
  s    
z8OurServerCmdLineClientTests.test_existingRemoteDirectoryc                    sH   ˆ   dˆ jj› d�¡}| ˆ jd¡ | ‡ fdd„¡ | ˆ jd¡ |S )zÂ
        Test that we can create a directory locally and remove it with the
        cftp client. This test works because the 'remote' server is running
        out of a local directory.
        zlmkdir z/testLocalDirectoryrÍ   c                    s
   ˆ   d¡S )Nzrmdir testLocalDirectory)r'  rQ  r)   r+   r,   r     rÍ   z@OurServerCmdLineClientTests.testLocalDirectory.<locals>.<lambda>)r'  r
  ro   r¡   r3   r¢   r+   r)   r,   ÚtestLocalDirectory  s
    z.OurServerCmdLineClientTests.testLocalDirectoryc                    s4   ‡ fdd„}ˆ   dd¡}| |¡ | ˆ jd¡ |S )z1
        Test that we can rename a file.
        c                    s*   ˆ   | d d¡ ˆ   | d d¡ ˆ  d¡S )Nr   rÍ   ru   s	   testfile2zrename testfile2 testfile1)r3   r'  ri  r)   r+   r,   rk  )  s    z6OurServerCmdLineClientTests.testRename.<locals>._checkzrename testfile1 testfile2zls testfile?rÍ   r�  rm  r+   r)   r,   Ú
testRename$  s
    
z&OurServerCmdLineClientTests.testRename)N)r6   r7   r8   r9   r-   rK  r_  r'  r.  rg  rn  rv  rx  ry  rƒ  rˆ  r�  r–  r™  r›  rž  r¡  r¢  r£  r¤  r+   r+   r+   r,   rL  ¥  s,   *
rL  c                   @   s@   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dS )ÚOurServerBatchFileTestszm
    Functional tests which launch a SFTP server over localhost and checks csftp
    in batch interface.
    c                 C   s   t  | ¡ |  ¡  d S r$   ©r4  r-   r>  r)   r+   r+   r,   r-   ;  s    
zOurServerBatchFileTests.setUpc                 C   s   t  | ¡ |  ¡ S r$   )r4  rK  rE  r)   r+   r+   r,   rK  ?  s    
z OurServerBatchFileTests.tearDownc              	      sÐ   |   ¡ ‰ tˆ dƒ�}| |¡ W 5 Q R X | j ¡ j}d|ˆ f }tj| ¡ dd�dd … }t	 
dtj› d|› �¡ tj ¡ }tj tj¡|d< d| jj_ttj||d	�}‡ fd
d„}| dd„ ¡ | |¡ |S )Nr�  zˆ-p %i -l testuser --known-hosts kh_test --user-authentications publickey --host-key-algorithms ssh-rsa -i rsa_test -a -v -b %s 127.0.0.1r   rM  ru   rO  rÔ   rS  rT  c                    s   t  ˆ ¡ | S r$   )r@   rI  ©Úres©Úfnr+   r,   Ú_cleanupZ  s    
z9OurServerBatchFileTests._getBatchOutput.<locals>._cleanupc                 S   s   | d S )Nr   r+   r§  r+   r+   r,   r  ^  rÍ   z9OurServerBatchFileTests._getBatchOutput.<locals>.<lambda>)rÏ   rÐ   r‚   r;  rV  rW  r   rX  rÚ   r   r  rž   rŸ   r@   rA   rY  rZ  rí   ro   rA  rC  r   r¡   ZaddBoth)r*   r:  ÚfprW  r[  rU  r£   r«  r+   r©  r,   Ú_getBatchOutputC  s"    ø	


z'OurServerBatchFileTests._getBatchOutputc                    s(   d}‡ fdd„}ˆ   |¡}| |¡ |S )zš
        Test whether batch file function of cftp ('cftp -b batchfile').
        This works by treating the file as a list of commands to be run.
        zpwd
ls
exit
c                    sT   |   d¡} t dt| ƒ ¡ ˆ  ˆ j ¡ j| d ¡ ˆ  | dd… dddd	g¡ d S )
Nr  zRES %sru   rb  éþÿÿÿro  rp  rq  rr  )	rÚ   r   r  ÚreprÚassertInr
  rŒ  ro   r3   r§  r)   r+   r,   Ú_cbCheckResultm  s    


þz=OurServerBatchFileTests.testBatchFile.<locals>._cbCheckResult©r­  r¡   ©r*   r[  r±  r£   r+   r)   r,   ÚtestBatchFilec  s
    	

z%OurServerBatchFileTests.testBatchFilec                    s(   d}‡ fdd„}ˆ   |¡}| |¡ |S )zO
        Test that an error in the batch file stops running the batch.
        zchown 0 missingFile
pwd
exit
c                    s   ˆ   ˆ j ¡ j| ¡ d S r$   )ZassertNotInr
  rŒ  ro   r§  r)   r+   r,   r±  ƒ  s    z9OurServerBatchFileTests.testError.<locals>._cbCheckResultr²  r³  r+   r)   r,   Ú	testErrorz  s
    

z!OurServerBatchFileTests.testErrorc                    s(   d}‡ fdd„}ˆ   |¡}| |¡ |S )z_
        Test that a minus sign '-' at the front of a line ignores
        any errors.
        z-chown 0 missingFile
pwd
exit
c                    s   ˆ   ˆ j ¡ j| ¡ d S r$   )r°  r
  rŒ  ro   r§  r)   r+   r,   r±  ”  s    z@OurServerBatchFileTests.testIgnoredError.<locals>._cbCheckResultr²  r³  r+   r)   r,   ÚtestIgnoredErrorŠ  s
    

z(OurServerBatchFileTests.testIgnoredErrorN)
r6   r7   r8   r9   r-   rK  r­  r´  rµ  r¶  r+   r+   r+   r,   r¥  4  s    r¥  Ússhz$no ssh command-line client availableÚsftpz%no sftp command-line client availablec                   @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	ÚOurServerSftpClientTestsz@
    Test the sftp server against sftp command line client.
    c                 C   s   t  | ¡ |  ¡ S r$   r¦  r)   r+   r+   r,   r-   ¤  s    
zOurServerSftpClientTests.setUpc                 C   s   |   ¡ S r$   )rE  r)   r+   r+   r,   rK  ¨  s    z!OurServerSftpClientTests.tearDownc           	         s²   t tjƒ}ˆ ¡ }t|dƒ�}| d¡ W 5 Q R X ˆj ¡ j}t	j
‰ ‡ fdd„}ˆ t	d|¡ dˆjj_ddd	d
d	dd	dd	dd	d|f d|df}‡fdd„}td||ƒ}| |¡S )a  
        Test the return of extended attributes by the server: the sftp client
        should ignore them, but still be able to parse the response correctly.

        This test is mainly here to check that
        L{filetransfer.FILEXFER_ATTR_EXTENDED} has the correct value.
        r�  z	ls .
exitc                    s   ˆ | |ƒ}d|d< |S )Nr™   Zext_foor+   )r*   Úsr}   )Ú
oldGetAttrr+   r,   Ú	_getAttrs¾  s    
zCOurServerSftpClientTests.test_extendedAttributes.<locals>._getAttrsr¼  Tz-Fz	/dev/nullz-ozIdentitiesOnly=yeszIdentityFile=rsa_testzUserKnownHostsFile=kh_testzHostKeyAlgorithms=ssh-rsazPort=%iz-bztestuser@127.0.0.1c                    s:   ˆ   | d d| d  d¡¡ dD ]}ˆ  || d ¡ q d S )NrØ   r   ru   Úascii)ro  rp  rq  rr  )r3   rÙ   r°  )rÁ   Úir)   r+   r,   rš  Û  s    z?OurServerSftpClientTests.test_extendedAttributes.<locals>.checkr¸  )Údictr@   rA   rÏ   rÐ   r‚   r;  rV  rW  r!   r¼  rD   rA  rC  r   r¡   )	r*   rU  rª  r:  rW  r¼  Úargsrš  r£   r+   )r»  r*   r,   Útest_extendedAttributes«  s8    


ñ
z0OurServerSftpClientTests.test_extendedAttributesN)r6   r7   r8   r9   r-   rK  rÁ  r+   r+   r+   r,   r¹  œ  s   r¹  )Qr9   r›   r[   rF   r@   r«   rž   r>   Úior   r   Zunittestr   Zzope.interfacer   Ztwisted.conchr   Ztwisted.conch.interfacesr   Z$twisted.conch.test.test_filetransferr   r	   Ztwisted.credr
   Ztwisted.internetr   r   r   r   r   Ztwisted.internet.taskr   Ztwisted.internet.testingr   Ztwisted.internet.utilsr   Ztwisted.pythonr   Ztwisted.python.fakepwdr   Ztwisted.python.filepathr   Ztwisted.python.procutilsr   Ztwisted.python.reflectr   Ztwisted.trial.unittestr   r   ÚunixZtwisted.conch.scriptsr   Ztwisted.conch.scripts.cftpr   Ztwisted.conch.sshr   Ztwisted.conch.ssh.connectionr   Ztwisted.conch.testr   r   Ztwisted.conch.test.test_conchr    r!   ÚImportErrorZ	skipTestsZIReactorProcessr"   r:   re   rl   rt   r   rŽ   r	  ZProcessProtocolr  r4  rL  r¥  r¹  r+   r+   r+   r,   Ú<module>   s†   ' #&2  u	{'   g