U
    sÍ@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	 ddl
mZ ddlmZ ddlmZ edƒZedƒZed	ƒZdZeröerözPd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  W n e!k
rô   Y nX 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+m,Z,m-Z-m.Z.m/Z/ ddl0m1Z1m2Z2 ddl3m4Z4 ddl5m6Z6m7Z7 ddl8m9Z9 ddl:m;Z; ddl<m=Z= ddl>m?Z? G dd„ de?ƒZ@G dd „ d e?ƒZAG d!d"„ d"e;eBƒZCG d#d$„ d$eBƒZDG d%d&„ d&eBƒZEee%ƒG d'd(„ d(e	ƒƒZFG d)d*„ d*e?ƒZGG d+d,„ d,ƒZHG d-d.„ d.e,jIƒZJG d/d0„ d0e&ƒZKG d1d2„ d2eKƒZLG d3d4„ d4eKƒZMG d5d6„ d6eKƒZNdeeee- Oe+d¡fkrÌedkr¬d7ZeeL_PeeM_PeeN_PeeG_Pee@_Pndd8lQmRZR eRd9ƒsèd:eN_PdS );z*
Tests for L{twisted.conch.scripts.cftp}.
é    N)ÚBytesIO)ÚFilePath)ÚrequireModule)ÚimplementerÚpyasn1Úcryptographyztwisted.conch.unix)Úcftp)Ú
SSHSession)Úfiletransfer)ÚFileTransferForTestAvatar)Útest_sshÚ
test_conch)Ú	FakeStdio)Úls)Ú	ISFTPFile)ÚSFTPTestBase)ÚFileTransferTestAvatar)Úportal)ÚreactorÚprotocolÚ
interfacesÚdeferÚerror)ÚgetProcessOutputAndValueÚgetProcessValue)Úlog)Ú_PY3Úunicode)ÚUserDatabase)ÚStringTransport)ÚClock)ÚTestCasec                   @   s   e Zd ZdZdd„ ZdS )ÚSSHSessionTestsz=
    Tests for L{twisted.conch.scripts.cftp.SSHSession}.
    c                 C   s*   t ƒ }tƒ }||_| ¡  |  |j¡ dS )z|
        L{twisted.conch.scripts.cftp.SSHSession.eofReceived} loses the write
        half of its stdio connection.
        N)r   r	   ÚstdioZeofReceivedÚ
assertTrueZwriteConnLost)Úselfr#   Zchannel© r&   ú>/usr/lib/python3/dist-packages/twisted/conch/test/test_cftp.pyÚtest_eofReceived6   s
    z SSHSessionTests.test_eofReceivedN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r(   r&   r&   r&   r'   r"   2   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dd„ Ze ¡ ZzBze ejd¡ W n ejk
rˆ   de_Y nX e eje¡ W n   Y nX 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 ©N)Únowr&   ©r%   r&   r'   ÚfakeTimeR   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 )Nr4   )ÚosÚenvironÚKeyErrorr3   r.   r&   r&   r&   r'   Úcleanup\   s
    z#ListingTests.setUp.<locals>.cleanupN)
r0   Úpatchr   r5   r6   Ú
addCleanupÚoperatorÚsetitemr3   r.   )r%   r2   r8   r&   r1   r'   ÚsetUpL   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.
        r4   Úfoo)r5   r6   r3   r.   r   ZlsLine)r%   ÚtimezoneÚstatr&   r&   r'   Ú_lsInTimezonef   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©r0   r5   Ústat_resultÚassertEqualrA   ©r%   Úthenr@   r&   r&   r'   Útest_oldFiler   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.
        rB   i€— r   rC   z;!---------    0 0        0               0 May 01  1973 foorD   z;!---------    0 0        0               0 May 02  1973 fooNrE   rH   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   rC   ú;!---------    0 0        0               0 Aug 28 17:33 foorD   ú;!---------    0 0        0               0 Aug 29 09:33 fooNrE   rH   r&   r&   r'   Útest_newFile–   s    

þ
þzListingTests.test_newFilec                 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.
        rM   r   ú
es_AR.UTF8rC   rN   rD   rO   N)
r0   r5   rF   ÚlocaleÚ	getlocaleÚ	setlocaleÚLC_ALLr:   rG   rA   )r%   rI   r@   ÚcurrentLocaler&   r&   r'   Útest_localeIndependent§   s    

þ
þz#ListingTests.test_localeIndependentrQ   z'The es_AR.UTF8 locale is not installed.c                 C   sX   | j d d }t dddddddd|df
¡}|  |  d|¡d¡ |  |  d|¡d¡ dS )	rK   rM   i F r   rC   z;!---------    0 0        0               0 Sep 01 17:33 foorD   z;!---------    0 0        0               0 Sep 02 09:33 fooNrE   rH   r&   r&   r'   Útest_newSingleDigitDayOfMonthÉ   s    
þ
þz*ListingTests.test_newSingleDigitDayOfMonth)r)   r*   r+   r,   Úgetattrr3   Úskipr=   rA   rJ   rL   rP   rW   rR   rS   rV   rT   rU   ÚErrorrX   r&   r&   r&   r'   r-   C   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t| ƒ ¡  dS )zt
        @param conn: The SSH connection associated with this channel.
        @type conn: L{SSHConnection}
        r   N)ÚconnZlocalClosedÚsuperr\   Ú__init__)r%   r]   ©Ú	__class__r&   r'   r_   ã   s    zInMemorySSHChannel.__init__)r)   r*   r+   r,   r_   Ú__classcell__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S )	ÚFilesystemAccessExpectationszC
    A test helper used to support expected filesystem access.
    c                 C   s
   i | _ d S r/   ©Ú_cacher1   r&   r&   r'   r_   ó   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}
        Nrd   )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}
        )re   Úpop)r%   rf   rg   r&   r&   r'   rj     s    z FilesystemAccessExpectations.popN)r)   r*   r+   r,   r_   ri   rj   r&   r&   r&   r'   rc   î   s   rc   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é   é
   )ZrequestsÚ
buffersize)r\   Ú	transportÚoptionsÚ_availableFiles)r%   ZavailableFilesr&   r&   r'   r_   !  s
    
þzInMemorySFTPClient.__init__c                 C   s   | j  ||¡S )z}
        @see: L{filetransfer.FileTransferClient.openFile}.

        Retrieve and remove cached file based on flags.
        )rq   rj   )r%   Úfilenamerg   Úattrsr&   r&   r'   ÚopenFile*  s    zInMemorySFTPClient.openFileN)r)   r*   r+   r,   r_   rt   r&   r&   r&   r'   rk     s   		rk   c                   @   s0   e Zd Z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   r_   )r%   rv   r&   r&   r'   r_   :  s    zInMemoryRemoteFile.__init__c                 C   s   |   |¡ |  |¡ t | ¡S )z/
        @see: L{ISFTPFile.writeChunk}
        )ÚseekÚwriter   Úsucceed)r%   ÚstartÚdatar&   r&   r'   Ú
writeChunkC  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)Ú_closedr1   r&   r&   r'   ÚcloseL  s    zInMemoryRemoteFile.closec                 C   s
   t  | ¡S )zb
        Get current data of file.

        Allow reading data event when file is closed.
        )r   Úgetvaluer1   r&   r&   r'   r   U  s    zInMemoryRemoteFile.getvalueN)r)   r*   r+   r,   r_   r|   r~   r   r&   r&   r&   r'   ru   4  s
   			ru   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)rc   ÚfakeFilesystemrk   r   ÚStdioClientÚclientZcurrentDirectoryr   ÚdatabaseZ_pwdÚsetKnownConsoleSizero   )r%   Z
sftpClientr&   r&   r'   r=   c  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éÒ  r>   Úbarzexec print(1 + 2)s   3
)r†   ÚaddUserÚgetpassÚgetuserr5   ÚgetuidÚsysÚ
executabler…   Ú_dispatchCommandÚaddCallbackrG   ©r%   Údr&   r&   r'   Ú	test_execw  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‰   r>   rŠ   Ú zexec echo helloó   hello
©
r†   r‹   rŒ   r   r5   rŽ   r…   r‘   r’   rG   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‰   r>   rŠ   z/bin/shz!echo hellor—   r˜   r“   r&   r&   r'   Ú	test_bang’  s         þzStdioClientTests.test_bangc                    s4   ddl ‰G ‡ ‡‡fdd„dtƒ}|  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   )Z
TIOCGWINSZZfailÚstructZpack)r%   ÚfdZoptZmutate©ÚheightÚttyÚwidthr&   r'   Úioctl¬  s    

z=StdioClientTests.setKnownConsoleSize.<locals>.FakeFcntl.ioctlN)r)   r*   r+   r¡   r&   r   r&   r'   Ú	FakeFcntl«  s   r¢   Zfcntl)rŸ   Úobjectr9   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 ||¡ trpd}n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.
        rm   é"   ó   xó   samplei (  g       @i   s#   b'sample' 40% 4.0kB 2.0kBps 00:03 z sample 40% 4.0kB 2.0kBps 00:03 N)r‡   r    r…   r   r   rv   r   ÚFileWrapperÚsizeÚsecondsZadvanceZtotalÚ_printProgressBarr   rG   ro   Úvalue©r%   ZclockÚwrappedÚwrapperZ	startTimeÚresultr&   r&   r'   Útest_printProgressBarReporting³  s    	

z/StdioClientTests.test_printProgressBarReportingc                 C   sn   |   dd¡ tƒ  }| j_tdƒ}d|_t |¡}| ¡ }| j 	||¡ t
rRd}n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.
        rm   r¤   r¥   r¦   s!   b'sample'  0% 0.0B 0.0Bps 00:00 zsample  0% 0.0B 0.0Bps 00:00 N)r‡   r    r…   r   r   rv   r   r§   r©   rª   r   rG   ro   r«   r¬   r&   r&   r'   Útest_printProgressBarNoProgressÏ  s    
z0StdioClientTests.test_printProgressBarNoProgressc                 C   sV   |   dd¡ tƒ }d|_t |¡}| j |d¡ tr:d}nd}|  || jj	 
¡ ¡ dS )z5
        Print the progress for empty files.
        rm   r¤   s
   empty-filer   s%   b'empty-file'100% 0.0B 0.0Bps 00:00 z"empty-file100% 0.0B 0.0Bps 00:00 N)r‡   r   rv   r   r§   r…   rª   r   rG   ro   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_getFilenamerG   ©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Úopenrx   )r%   rf   ÚcontentÚfiler&   r&   r'   ÚmakeFile  s
    zStdioClientTests.makeFileFc                 C   sf  | j j ¡ }tr| d¡}| d¡}g }g }|D ]ö\}}}g }	|D ]}
|	 d||
f ¡ qB|	 d||f ¡ | |	¡ | d¡ d¡ d¡}|dd… }|d  d	¡ d	¡}| 	|¡ g }|dd… D ]F}
|
 ¡  
d
d¡d }
|
 ¡  d
d¡}
| d|
d |
d  ¡ f ¡ qÆ| |d ¡ | |¡ q0|rD|  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

        úutf-8z
z%s %szTransferred %s to %sr   úNéÿÿÿÿÚ
ú é   rl   z5There are still put responses which were not checked.)r…   ro   r«   r   ÚdecodeÚsplitÚappendrj   ÚstripÚextendÚrsplitrG   ÚsortedÚlen)r%   Z	transfersÚrandomOrderÚoutputÚexpectedOutputZactualOutputr¸   ZremoteZexpectedZexpectedTransferÚlineZprogressPartsZactualZlastZactualTransferr&   r&   r'   ÚcheckPutMessage3  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   rm   rn   z	76% 10.0Bz
100% 13.0BN)rÁ   r
   Ú	FXF_WRITEÚ	FXF_CREATÚ	FXF_TRUNCr5   rf   ÚjoinÚbasenameru   rƒ   ri   r   ry   r…   rp   Úcmd_PUTÚsuccessResultOfrG   r   r$   r}   rÔ   )r%   r¿   Ú	localPathrg   Ú
remoteNameÚ
remoteFileÚdeferredr&   r&   r'   Útest_cmd_PUTSingleNoRemotePathq  s*    ÿþÿ
ÿÿz/StdioClientTests.test_cmd_PUTSingleNoRemotePathc                 C   sŽ   |   ¡ }tjtjB tjB }d}t|ƒ}| j ||t 	|¡¡ | j
 d||f ¡}|  |¡ |  ||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-pathz%s %s ignoredú	100% 0.0Br»   N)rÁ   r
   rÕ   rÖ   r×   ru   rƒ   ri   r   ry   r…   rÚ   rÛ   rÔ   r$   r}   rG   r   )r%   rÜ   rg   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|f }d|f }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©rf   z/%sÚ*r»   rá   T©rÐ   N©rÁ   r5   rf   rÙ   ÚdirnamerØ   r
   rÕ   rÖ   r×   ru   rƒ   ri   r   ry   r…   rÚ   rÛ   r$   r}   rG   r   rÔ   )r%   ÚfirstÚ	firstNameÚ
secondNameÚparentÚsecondrg   ÚfirstRemotePathÚsecondRemotePathÚfirstRemoteFileÚsecondRemoteFilerß   r&   r&   r'   Ú test_cmd_PUTMultipleNoRemotePath§  sJ    ÿþÿ

  ÿ  ÿ


þü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|f }	d|f }
| j |	|t |¡¡ | j |
|t |¡¡ | j dtj |d¡f ¡}|  |¡ |  |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/%sz	%s remoterå   r»   rá   Træ   Nrç   )r%   ré   rê   rë   rì   rí   rg   rð   rñ   rî   rï   rß   r&   r&   r'   Ú"test_cmd_PUTMultipleWithRemotePathÎ  sN    ÿþÿ

  ÿ  ÿÿ


þüz3StdioClientTests.test_cmd_PUTMultipleWithRemotePath)Nr»   )F)r)   r*   r+   r,   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'   r_   ú  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)r)   r*   r+   r_   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'   r_     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Ú_lineBufferr1   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É   rj   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%   ÚpromptZbufr”   r&   r&   r'   r  2  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'   ÚerrReceived=  s    zSFTPTestProcess.errReceivedc                 C   s   | j S )zQ
        Return the contents of the buffer of data received from stdout.
        )rÿ   r1   r&   r&   r'   Ú	getBufferD  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.
        rÂ   r  )	r   ÚDeferredrý   rú   Ú
isinstancer   Úencodero   rx   ©r%   Úcommandr&   r&   r'   Ú
runCommandK  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.
        rl   c                    s   g | ]}ˆ  ˆ j|¡‘qS r&   )Úrunr  )Ú.0r  ©r%   Zsemr&   r'   Ú
<listcomp>j  s     z-SFTPTestProcess.runScript.<locals>.<listcomp>)r   ZDeferredSemaphoreZgatherResults)r%   ÚcommandsZdlr&   r  r'   Ú	runScript^  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   ry   r  rü   ro   ÚsignalProcessr1   r&   r&   r'   ÚkillProcessn  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'   ÚprocessEnded~  s    zSFTPTestProcess.processEndedN)r)   r*   r+   r,   r_   rú   r  r  r
  r  r  r  r  r  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údsa_test.pubr¼   Údsa_testi€  Úkh_tests
   127.0.0.1 )
r¾   rx   r   ZpublicDSA_opensshZprivateDSA_opensshr5   ÚchmodZpublicRSA_opensshr   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%   Z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Úprotorl   )Úhasattrr$  ÚfactoryÚ_cbStopServerr'  ÚexpectedLoseConnectionr   ÚmaybeDeferredro   ZloseConnectionr’   r“   r&   r&   r'   Ú
stopServerž  s    
ÿzCFTPClientTestBase.stopServerc                 C   s   t  | jj¡S r/   )r   r,  r$  ZstopListening©r%   Úignoredr&   r&   r'   r*  ¨  s    z CFTPClientTestBase._cbStopServerc                 C   s0   dD ] }zt  |¡ W q   Y qX qt | ¡S )N)r  r  r   )r5   Úremover   ÚtearDownr"  r&   r&   r'   r1  ¬  s    zCFTPClientTestBase.tearDownN)r)   r*   r+   r=   r&  r-  r*  r1  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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           
         s,  t  ˆ ¡ ˆ  ¡  d}ˆ j ¡ j}tj||  ¡ dd}t	 
dtj|f ¡ 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 dsa_test -a -v 127.0.0.1r   ©Úmodúrunning %s %sc                    s
   ˆ j  ¡ S r/   )ÚprocessProtocolrú   ©Ú_r1   r&   r'   rö   Ð  r»   z3OurServerCmdLineClientTests.setUp.<locals>.<lambda>Ú
PYTHONPATHrÂ   ©Úenv)r  r=   r&  r$  ÚgetHostÚportr   Ú	_makeArgsrÉ   r   r  r   r   r   r  rù   r6  r’   r5   r6   ÚcopyÚpathseprØ   rf   r  r   r  rÊ   r   ZspawnProcess)
r%   Úcmdsr=  r”   r;  ZencodedCmdsZ
encodedEnvÚcmdÚvarÚvalr&   r1   r'   r=   ¿  s<    











ÿz!OurServerCmdLineClientTests.setUpc                    s   ˆ   ¡ }| ‡ fdd„¡ |S )Nc                    s
   ˆ j  ¡ S r/   )r6  r  r7  r1   r&   r'   rö   é  r»   z6OurServerCmdLineClientTests.tearDown.<locals>.<lambda>)r-  r’   r“   r&   r1   r'   r1  ç  s    z$OurServerCmdLineClientTests.tearDownc                 C   s.   z| j j d¡ W n tjk
r(   Y nX d S )Nr  )r6  ro   r  r   ZProcessExitedAlreadyr.  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.
        )r6  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.
        )r6  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   sH   g }| D ]&}t r$t|tƒr$| d¡}| |¡ q|dd… |dd…  S )zH
            Callback function for handling command output.
            rÂ   Né   é   )r   r  ÚbytesrÈ   rÊ   )rÑ   rA  rB  r&   r&   r'   Ú	cmdOutput  s    
z8OurServerCmdLineClientTests.testCdPwd.<locals>.cmdOutputr–   )rõ   r  r’   rG   rf   r5   Úgetcwd)r%   ZhomeDirr”   rK  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--rl   r»   rÇ   s
   ----------rH  )ÚflushLoggedErrorsr$   r  rG   ©Zresultsr1   r&   r'   Ú_check'  s
    z7OurServerCmdLineClientTests.testChAttrs.<locals>._checkzls -l testfile1zchmod 0 testfile1zchmod 644 testfile1©r  r’   ©r%   rP  r”   r&   r1   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ó	   testfile1rl   rÇ   rH  s   .testHiddenFilerI  r»   ©rG   rO  r1   r&   r'   rP  9  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  D  s     zJOurServerCmdLineClientTests.testList.<locals>.<lambda>.<locals>.<listcomp>r&   )Zxsr&   r&   r'   rö   D  r»   z6OurServerCmdLineClientTests.testList.<locals>.<lambda>)r  rõ   rÙ   r’   rR  r&   r1   r'   ÚtestList4  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–   rÂ   )
r  r   r„   Zcmd_HELPrË   r  r   r  r’   rG   )r%   r”   ZhelpTextr&   r&   r'   ÚtestHelpH  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)rG   Z
getContent)r%   Zname1Zname2r  r&   r&   r'   ÚassertFilesEqualU  s    z,OurServerCmdLineClientTests.assertFilesEqualc                    sj   dˆj jˆj jf ‰ tˆ tƒr(ˆ  d¡‰ ‡ ‡fdd„}ˆ dˆj jf ¡}| |¡ | ‡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 %s/testfile1 to %s/test file2rÂ   c                    s8   ˆ  |  ˆ ¡¡ ˆ ˆj d¡ˆj d¡d¡ ˆ d¡S )NÚ	testfile1ú
test file2z
get failedzrm "test file2")r$   Úendswithr]  rõ   Úchildr  ©r¯   ©rÒ   r%   r&   r'   Ú	_checkGeth  s    
þz6OurServerCmdLineClientTests.testGet.<locals>._checkGetzget testfile1 "%s/test file2"c                    s   ˆ   ˆ j d¡ ¡ ¡S )Nr_  ©ZassertFalserõ   ra  Úexistsr7  r1   r&   r'   rö   q  s   ÿz5OurServerCmdLineClientTests.testGet.<locals>.<lambda>)rõ   rf   r  r   r  r  r’   )r%   rd  r”   r&   rc  r'   ÚtestGet]  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)r]  rõ   ra  r   )r/  r1   r&   r'   rP  z  s    þþz;OurServerCmdLineClientTests.testWildcardGet.<locals>._checkz
get testR*)r  r’   rR  r&   r1   r'   ÚtestWildcardGetv  s    
z+OurServerCmdLineClientTests.testWildcardGetc                    sf   dˆj  ¡ j d ˆj  ¡ j d ‰ ‡ ‡fdd„}ˆ dˆj jf ¡}| |¡ | ‡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 )Nr^  ú
test"file2zrm "test\"file2")r]  rõ   ra  r$   r`  r  rb  rc  r&   r'   Ú	_checkPut  s
    
ÿz6OurServerCmdLineClientTests.testPut.<locals>._checkPutzput %s/testfile1 "test\"file2"c                    s   ˆ   ˆ j d¡ ¡ ¡S )Nrm  re  r7  r1   r&   r'   rö   ˜  s   ÿz5OurServerCmdLineClientTests.testPut.<locals>.<lambda>)rõ   ÚasBytesModerf   r  r’   )r%   rn  r”   r&   rc  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f ¡}| |¡ |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 )Nrq  rv  )r]  rõ   ra  rb  r1   r&   r'   rn  §  s    
ÿzEOurServerCmdLineClientTests.test_putOverLongerFile.<locals>._checkPutzput %s/shorterFile longerFile)rõ   ra  r¾   rx   r  rf   r’   ©r%   r#  rn  r”   r&   r1   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f ¡}| |¡ |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À   rr  rs  ru  rw  c                    s   ˆ   ˆ d¡ˆ j d¡¡ d S )NrÀ   )r]  ra  rõ   rb  ©r%   ZsomeDirr&   r'   rn  ½  s    
ÿzMOurServerCmdLineClientTests.test_putMultipleOverLongerFile.<locals>._checkPutzput %s/dir/*)rõ   ra  ZcreateDirectoryr¾   rx   r  rf   r’   rx  r&   r{  r'   Útest_putMultipleOverLongerFile±  s    ÿ
z:OurServerCmdLineClientTests.test_putMultipleOverLongerFilec                    s<   ‡ fdd„}ˆ   ddˆ jjf 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Ç   rh  ri  rj  rk  )rG   r]  rõ   ra  rì   rO  r1   r&   r'   ÚcheckÍ  s    þþz:OurServerCmdLineClientTests.testWildcardPut.<locals>.checkrG  zput %s/testR*zcd %s)r  rõ   rf   rÙ   r’   )r%   r}  r”   r&   r1   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»   rl   ó   lzlink failedzrm testLink)rN  rG   r$   r  r  rO  r1   r&   r'   rP  ä  s    z4OurServerCmdLineClientTests.testLink.<locals>._checkzln testLink testfile1zls -l testLinkr»   ©r  r’   rG   rR  r&   r1   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»   rl   ó   dzrmdir testMakeDirectory)rG   r$   r  r  rO  r1   r&   r'   rP  ô  s    z?OurServerCmdLineClientTests.testRemoteDirectory.<locals>._checkúmkdir testMakeDirectoryzls -l testMakeDirector?r»   r€  rR  r&   r1   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»   rl   s   remote error 11: mkdir failedrX  rO  r1   r&   r'   rP    s    
ÿzHOurServerCmdLineClientTests.test_existingRemoteDirectory.<locals>._checkrƒ  rQ  rR  r&   r1   r'   Útest_existingRemoteDirectory   s    ÿ
z8OurServerCmdLineClientTests.test_existingRemoteDirectoryc                    sF   ˆ   dˆ jjf ¡}| ˆ 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 %s/testLocalDirectoryr»   c                    s
   ˆ   d¡S )Nzrmdir testLocalDirectory)r  r7  r1   r&   r'   rö     r»   z@OurServerCmdLineClientTests.testLocalDirectory.<locals>.<lambda>)r  rõ   rf   r’   rG   r“   r&   r1   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»   rl   s	   testfile2zrename testfile2 testfile1)rG   r  rO  r1   r&   r'   rP  !  s    z6OurServerCmdLineClientTests.testRename.<locals>._checkzrename testfile1 testfile2zls testfile?r»   r€  rR  r&   r1   r'   Ú
testRename  s
    
z&OurServerCmdLineClientTests.testRename)N)r)   r*   r+   r,   r=   r1  rE  r  r  rM  rS  rZ  r\  r]  rg  rl  rp  ry  r|  r~  r  r„  r…  r†  r‡  r&   r&   r&   r'   r2  ¶  s,   (		
r2  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/   ©r  r=   r&  r1   r&   r&   r'   r=   3  s    
zOurServerBatchFileTests.setUpc                 C   s   t  | ¡ |  ¡ S r/   )r  r1  r-  r1   r&   r&   r'   r1  8  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|f ¡ tj ¡ }tj tj¡|d< d| jj_ttj||d}‡ fd	d
„}| dd„ ¡ | |¡ |S )Nrr  zˆ-p %i -l testuser --known-hosts kh_test --user-authentications publickey --host-key-algorithms ssh-rsa -i dsa_test -a -v -b %s 127.0.0.1r   r3  rl   r5  r9  r:  c                    s   t  ˆ ¡ | S r/   )r5   r0  ©Úres©Úfnr&   r'   Ú_cleanupR  s    
z9OurServerBatchFileTests._getBatchOutput.<locals>._cleanupc                 S   s   | d S )Nr   r&   rŠ  r&   r&   r'   rö   V  r»   z9OurServerBatchFileTests._getBatchOutput.<locals>.<lambda>)r½   r¾   rx   r$  r<  r=  r   r>  rÉ   r   r  r   r   r5   r6   r?  r@  rØ   rf   r)  r+  r   r’   ZaddBoth)r%   r#  Úfpr=  rA  r;  r”   rŽ  r&   rŒ  r'   Ú_getBatchOutput=  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 %srl   rH  éþÿÿÿrT  rU  rV  rW  )	rÉ   r   r  ÚreprÚassertInrõ   ro  rf   rG   rŠ  r1   r&   r'   Ú_cbCheckResultf  s    
 ÿz=OurServerBatchFileTests.testBatchFile.<locals>._cbCheckResult©r  r’   ©r%   rA  r”  r”   r&   r1   r'   ÚtestBatchFile\  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õ   ro  rf   rŠ  r1   r&   r'   r”  {  s    z9OurServerBatchFileTests.testError.<locals>._cbCheckResultr•  r–  r&   r1   r'   Ú	testErrorr  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õ   ro  rf   rŠ  r1   r&   r'   r”  Œ  s    z@OurServerBatchFileTests.testIgnoredError.<locals>._cbCheckResultr•  r–  r&   r1   r'   ÚtestIgnoredErrorƒ  s
    

z(OurServerBatchFileTests.testIgnoredErrorN)
r)   r*   r+   r,   r=   r1  r  r—  r˜  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S )	ÚOurServerSftpClientTestsz@
    Test the sftp server against sftp command line client.
    c                 C   s   t  | ¡ |  ¡ S r/   r‰  r1   r&   r&   r'   r=   š  s    
zOurServerSftpClientTests.setUpc                 C   s   |   ¡ S r/   )r-  r1   r&   r&   r'   r1  Ÿ  s    z!OurServerSftpClientTests.tearDownc              	      s¤   ˆ  ¡ ‰ tˆ dƒ}| d¡ W 5 Q R X ˆj ¡ j‰tj‰‡fdd„}ˆ td|¡ dˆjj	_
tddƒ}‡ ‡fd	d
„}‡fdd„}| |¡ | d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.
        rr  z	ls .
exitc                    s   ˆ | |ƒ}d|d< |S )NrŠ   Zext_foor&   )r%   Úsrs   )Ú
oldGetAttrr&   r'   Ú	_getAttrs±  s    
zCOurServerSftpClientTests.test_extendedAttributes.<locals>._getAttrsr  TZssh)ú-oúPubkeyAcceptedKeyTypes=ssh-dssz-Vc                    s>   | dkrd}nd}|dddddddd	dd
ˆf dˆ df7 }|S )Nr   )rž  rŸ  r&   z-Fz	/dev/nullrž  zIdentityFile=dsa_testzUserKnownHostsFile=kh_testzHostKeyAlgorithms=ssh-rsazPort=%iz-bztestuser@127.0.0.1r&   )ZstatusÚargs)r  r=  r&   r'   ÚhasPAKT¿  s"           üzAOurServerSftpClientTests.test_extendedAttributes.<locals>.hasPAKTc                    s.   ˆ   | d d¡ dD ]}ˆ  || d ¡ qd S )NrÇ   r   )rT  rU  rV  rW  )rG   r“  )r¯   Úir1   r&   r'   r}  Î  s    z?OurServerSftpClientTests.test_extendedAttributes.<locals>.checkc                 S   s
   t d| ƒS )NÚsftp)r   )r   r&   r&   r'   rö   Ô  r»   zBOurServerSftpClientTests.test_extendedAttributes.<locals>.<lambda>)r½   r¾   rx   r$  r<  r=  r   r  r9   r)  r+  r   r’   )r%   r#  r  r”   r¡  r}  r&   )r  rœ  r=  r%   r'   Útest_extendedAttributes£  s"    
 ÿ
z0OurServerSftpClientTests.test_extendedAttributesN)r)   r*   r+   r,   r=   r1  r¤  r&   r&   r&   r'   rš  •  s   rš  z4don't run w/o spawnProcess or cryptography or pyasn1)Úwhichr£  z%no sftp command-line client available)Sr,   rR   r3   r   r5   r;   rŒ   r›   Úior   Ztwisted.python.filepathr   Ztwisted.python.reflectr   Zzope.interfacer   r   r   ZunixZ_reasonZtwisted.conch.scriptsr   Ztwisted.conch.scripts.cftpr	   Ztwisted.conch.sshr
   Z$twisted.conch.test.test_filetransferr   Ztwisted.conch.testr   r   Ztwisted.conch.test.test_conchr   ÚImportErrorZtwisted.conchr   Ztwisted.conch.interfacesr   r   r   Ztwisted.credr   Ztwisted.internetr   r   r   r   r   Ztwisted.internet.utilsr   r   Ztwisted.pythonr   Ztwisted.python.compatr   r   Ztwisted.python.fakepwdr   Ztwisted.test.proto_helpersr   Ztwisted.internet.taskr    Ztwisted.trial.unittestr!   r"   r-   r£   r\   rc   rk   ru   r€   rô   ZProcessProtocolrù   r  r2  rˆ  rš  ZIReactorProcessrZ   Ztwisted.python.procutilsr¥  r&   r&   r&   r'   Ú<module>   s†   0 )*    -  yhD
ÿ

