
    Ϫf?                        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#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/m0Z0  e.d      Z1 e.d      Z2e1r-	 ddl3m4Z4 ddl5m6Z6 ddl7m8Z8 ddl9m:Z: ddl;m<Z<m=Z= ddl>m?Z? ddlm@Z@ dZBde2e1 ej                  ed      fv rdZB eeBd       G d  d!e0             ZD G d" d#e0      ZE G d$ d%e!      ZF G d& d'      ZG G d( d)      ZH ee       G d* d+e	             ZI eeBd       G d, d-e0             ZJ G d. d/      ZK G d0 d1ej                        ZM G d2 d3e      ZN eeBd       G d4 d5eN             ZO eeBd       G d6 d7eN             ZP eeBd       e e,d8       d9       e e,d:       d;       G d< d=eN                           ZQy# eA$ r Y (w xY w)>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getProcessValue)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                   (    e Zd ZdZddZddZddZy)SSHSessionTestsz=
    Tests for L{twisted.conch.scripts.cftp.SSHSession}.
    Nc                     t               | _        t               | _        | j                  | j                  _        t	               | _        t        | j
                        | _        | j                  | j                  _        y N)r"   stdior   channelr   stderrBufferr   stderrselfs    >/usr/lib/python3/dist-packages/twisted/conch/test/test_cftp.pysetUpzSSHSessionTests.setUp>   sP    [
!|!ZZ#I#D$5$56"kk    c                     | j                   j                          | j                  | j                  j                         y)z|
        L{twisted.conch.scripts.cftp.SSHSession.eofReceived} loses the write
        half of its stdio connection.
        N)r)   eofReceived
assertTruer(   writeConnLostr,   s    r.   test_eofReceivedz SSHSessionTests.test_eofReceivedF   s*    
 	  "

001r0   c                     d}|j                  d      }| j                  j                  t        |dz          | j	                  | j
                  j                         |dz          y)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)   extReceivedr   assertEqualr*   getvalue)r-   	errorText
errorBytess      r.   test_extReceivedStderrz&SSHSessionTests.test_extReceivedStderrN   s`     "	%%g.
    	
 	&&(!	
r0   )returnN)__name__
__module____qualname____doc__r/   r5   r?    r0   r.   r%   r%   8   s    *2
r0   r%   c                   z   e Zd ZdZ eedd      dZd Zd Zd Z	d Z
d	 Z ej                         Z	 	  ej                  ej                   d
       dZ ej                  ej                   e        eed      d        Zd Zy# ej$                  $ r dZY Cw xY w#  ej                  ej                   e       w xY w)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                 Z    d _          fd} j                  t        d|       dt        j                  v ra j                  t        j                  t        j                  dt        j                  d           j                  t        j                         yd } j                  |       y)zo
        Patch the L{ls} module's time function so the results of L{lsLine} are
        deterministic.
        i[c                       j                   S r'   )nowr,   s   r.   fakeTimez$ListingTests.setUp.<locals>.fakeTimep   s    88Or0   timeTZc                  n    	 t         j                  d= t        j                          y # t        $ r Y  w xY w)NrN   )osenvironKeyErrorrM   rH   rE   r0   r.   cleanupz#ListingTests.setUp.<locals>.cleanup|   s2    

4( 

   s   ( 	44N)
rK   patchr   rP   rQ   
addCleanupoperatorsetitemrM   rH   )r-   rL   rS   s   `  r.   r/   zListingTests.setUpi   sy    
 	 	

2vx( 2::OOH,,bjj$

4@PQOODJJ' OOG$r0   c                 |    |t         j                  d<   t        j                          t	        j
                  d|      S )zl
        Call L{ls.lsLine} after setting the timezone to C{timezone} and return
        the result.
        rN   foo)rP   rQ   rM   rH   r   lsLine)r-   timezonestats      r.   _lsInTimezonezListingTests._lsInTimezone   s,     $

4

yy%%r0   c                     | j                   dz
  }t        j                  dddddddd|df
      }| j                  | j	                  d|      d       | j                  | j	                  d|      d       y)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rK   rP   stat_resultr;   r]   r-   thenr\   s      r.   test_oldFilezListingTests.test_oldFile   |     xx01~~q!Q1aAtQ?@148I	
 	148I	
r0   c                     | j                   dz
  dz   }t        j                  dddddddd|df
      }| j                  | j	                  d|      d       | j                  | j	                  d|      d       y)	
        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.
        r_   i r   r`   z;!---------    0 0        0               0 May 01  1973 foora   z;!---------    0 0        0               0 May 02  1973 fooNrb   rd   s      r.   test_oldSingleDigitDayOfMonthz*ListingTests.test_oldSingleDigitDayOfMonth        xx015EF~~q!Q1aAtQ?@148I	
 	148I	
r0   c                     | j                   dz
  }t        j                  dddddddd|df
      }| j                  | j	                  d|      d       | j                  | j	                  d|      d       y)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   r`   ;!---------    0 0        0               0 Aug 28 17:33 foora   ;!---------    0 0        0               0 Aug 29 09:33 fooNrb   rd   s      r.   test_newFilezListingTests.test_newFile   rg   r0   
es_AR.UTF8FTz'The es_AR.UTF8 locale is not installed.c                    | j                   dz
  }t        j                  dddddddd|df
      }t        j                         }t        j
                  t        j                  d       | j                  t        j
                  t        j                  |       | j                  | j                  d|      d       | j                  | j                  d|      d       y)	zC
        The month name in the date is locale independent.
        rm   r   rq   r`   rn   ra   ro   N)
rK   rP   rc   locale	getlocale	setlocaleLC_ALLrU   r;   r]   )r-   re   r\   currentLocales       r.   test_localeIndependentz#ListingTests.test_localeIndependent   s     xx01~~q!Q1aAtQ?@ ((*5((&--G148I	
 	148I	
r0   c                     | j                   dz
  dz   }t        j                  dddddddd|df
      }| j                  | j	                  d|      d       | j                  | j	                  d|      d       y)	ri   rm   i F r   r`   z;!---------    0 0        0               0 Sep 01 17:33 foora   z;!---------    0 0        0               0 Sep 02 09:33 fooNrb   rd   s      r.   test_newSingleDigitDayOfMonthz*ListingTests.test_newSingleDigitDayOfMonth   rk   r0   )rA   rB   rC   rD   getattrrM   skipr/   r]   rf   rj   rp   rs   rt   rw   ru   rv   
localeSkipErrorr   rx   rz   rE   r0   r.   rG   rG   `   s    
 tWd#+I%:	&
$
(
( %F$$&M7	FV]]L9 J6JAB
 C
,
= || 	J	
 	6s)   B B BB BB B:rG   c                   "     e Zd ZdZ fdZ xZS )InMemorySSHChannelzp
    Minimal implementation of a L{SSHChannel} like class which only reads and
    writes data from memory.
    c                 >    || _         d| _        t        |           y)zt
        @param conn: The SSH connection associated with this channel.
        @type conn: L{SSHConnection}
        r   N)connlocalClosedsuper__init__)r-   r   	__class__s     r.   r   zInMemorySSHChannel.__init__  s    
 	r0   )rA   rB   rC   rD   r   __classcell__)r   s   @r.   r   r     s    
 r0   r   c                   "    e Zd ZdZd Zd Zd Zy)FilesystemAccessExpectationszC
    A test helper used to support expected filesystem access.
    c                     i | _         y r'   _cacher,   s    r.   r   z%FilesystemAccessExpectations.__init__  s	    r0   c                 &    || j                   ||f<   y)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}
        Nr   )r-   pathflagsstreams       r.   putz FilesystemAccessExpectations.put  s     &,T5M"r0   c                 <    | j                   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}
        )r   pop)r-   r   r   s      r.   r   z FilesystemAccessExpectations.pop(  s     {{e}--r0   N)rA   rB   rC   rD   r   r   r   rE   r0   r.   r   r     s    ,.r0   r   c                       e Zd ZdZd Zd Zy)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                 F    t        |       | _        ddd| _        || _        y )N   
   )requests
buffersize)r   	transportoptions_availableFiles)r-   availableFiless     r.   r   zInMemorySFTPClient.__init__B  s'    +D1
  .r0   c                 :    | j                   j                  ||      S )z}
        @see: L{filetransfer.FileTransferClient.openFile}.

        Retrieve and remove cached file based on flags.
        )r   r   )r-   filenamer   attrss       r.   openFilezInMemorySFTPClient.openFileJ  s     ##''%88r0   N)rA   rB   rC   rD   r   r   rE   r0   r.   r   r   8  s    .9r0   r   c                   :    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
y	)
InMemoryRemoteFilez;
    An L{ISFTPFile} which handles all data in memory.
    c                 <    || _         t        j                  |        y)zL
        @param name: Name of this file.
        @type name: L{str}
        N)namer   r   )r-   r   s     r.   r   zInMemoryRemoteFile.__init__Y  s    
 	r0   c                 p    | j                  |       | j                  |       t        j                  |       S )z/
        @see: L{ISFTPFile.writeChunk}
        )seekwriter   succeed)r-   startdatas      r.   
writeChunkzInMemoryRemoteFile.writeChunka  s+     			%

4}}T""r0   c                     d| _         y)zo
        @see: L{ISFTPFile.writeChunk}

        Keeps data after file was closed to help with testing.
        TN)_closedr,   s    r.   closezInMemoryRemoteFile.closei  s     r0   c                      y r'   rE   r,   s    r.   getAttrszInMemoryRemoteFile.getAttrsq      r0   c                      y r'   rE   )r-   offsetlengths      r.   	readChunkzInMemoryRemoteFile.readChunku  r   r0   c                      y r'   rE   )r-   r   s     r.   setAttrszInMemoryRemoteFile.setAttrsy  r   r0   c                 ,    t        j                  |       S )zb
        Get current data of file.

        Allow reading data event when file is closed.
        )r   r<   r,   s    r.   r<   zInMemoryRemoteFile.getvalue}  s     %%r0   N)rA   rB   rC   rD   r   r   r   r   r   r   r<   rE   r0   r.   r   r   S  s*    #&r0   r   c                       e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd ZddZddZd Zd Zd Zd Zy)StdioClientTestsz(
    Tests for L{cftp.StdioClient}.
    c                 d   t               | _        t        | j                        }t        j                  |      | _        d| j
                  _        t               x| _        | j
                  _	        | j                  dd       | j
                  j
                  j                  | j
                  _        y)zm
        Create a L{cftp.StdioClient} hooked up to dummy transport and a fake
        user database.
        /i     N)r   fakeFilesystemr   r   StdioClientclientcurrentDirectoryr   database_pwdsetKnownConsoleSizer   )r-   
sftpClients     r.   r/   zStdioClientTests.setUp  s    
 ;<'(;(;<
&&z2'*$+7>9(
 	  b) !% 2 2 < <r0   c           	         | j                   j                  t        j                         dt	        j
                         dddt        j                         | j                  j                  d      }|j                  | j                  d       |S )zs
        The I{exec} command runs its arguments locally in a child process
        using the user's shell.
        secret  rY   barzexec print(1 + 2)s   3
)r   addUsergetpassgetuserrP   getuidsys
executabler   _dispatchCommandaddCallbackr;   r-   ds     r.   	test_execzStdioClientTests.test_exec  sf    
 	OOxdE5#..	
 KK(()<=	d&&/r0   c           	          | j                   j                  t        j                         dt	        j
                         dddd       | j                  j                  d      }|j                  | j                  d       |S )zr
        If the local user has no shell, the I{exec} command runs its arguments
        using I{/bin/sh}.
        r   r   rY   r    zexec echo hello   hello

r   r   r   r   rP   r   r   r   r   r;   r   s     r.   test_execWithoutShellz&StdioClientTests.test_execWithoutShell  sb    
 	OOxdE5"	
 KK(():;	d&&
3r0   c           	          | j                   j                  t        j                         dt	        j
                         dddd       | j                  j                  d      }|j                  | j                  d       |S )zO
        The I{exec} command is run for lines which start with C{"!"}.
        r   r   rY   r   z/bin/shz!echo hellor   r   r   s     r.   	test_bangzStdioClientTests.test_bang  sa     	OOxdE5)	
 KK((7	d&&
3r0   c                 f    ddl  G fdd      }| j                  t        d |              y)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                       e Zd Z fdZy)7StdioClientTests.setKnownConsoleSize.<locals>.FakeFcntlc                 v    |j                   k7  r| j                  d       t        j                  ddd      S )Nz#Only window-size queries supported.4Hr   )
TIOCGWINSZfailstructpack)r-   fdoptmutateheightttywidths       r.   ioctlz=StdioClientTests.setKnownConsoleSize.<locals>.FakeFcntl.ioctl  s3    #..(IICD{{41==r0   N)rA   rB   rC   r   )r   r   r   s   r.   	FakeFcntlr     s    >r0   r   fcntl)r   rT   r   )r-   r   r   r   r   s    `` @r.   r   z$StdioClientTests.setKnownConsoleSize  s&     		> 	> 	

4)+.r0   c                    | j                  dd       t               x}| j                  _        t	        d      }d|_        t        j                  |      }d|_        |j                         }|j                  d       |xj                  dz  c_        | j                  j                  ||       d}| j                  | j                  j                  j                         |       y	)
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.
        r   "      x   samplei (  g       @i   s#   b'sample' 40% 4.0kB 2.0kBps 00:03 N)r   r   r   r   r   r   r   FileWrappersizesecondsadvancetotal_printProgressBarr;   r   valuer-   clockwrappedwrapper	startTimeresults         r.   test_printProgressBarReportingz/StdioClientTests.test_printProgressBarReporting  s     	  R(&+g-#$- ""7+ MMO	c%%gy98..446?r0   c                 p   | j                  dd       t               x}| j                  _        t	        d      }d|_        t        j                  |      }|j                         }| j                  j                  ||       d}| j                  | j                  j                  j                         |       y)z
        L{StdioClient._printProgressBar} prints a progress description that
        indicates 0 bytes transferred if no bytes have been transferred and no
        time has passed.
        r   r   r   r   s!   b'sample'  0% 0.0B 0.0Bps 00:00 N)r   r   r   r   r   r   r   r   r   r   r;   r   r   r   s         r.   test_printProgressBarNoProgressz0StdioClientTests.test_printProgressBarNoProgress  s     	  R(&+g-#$- ""7+MMO	%%gy96..446?r0   c                    | j                  dd       t               }d|_        t        j                  |      }| j
                  j                  |d       d}| j                  || j
                  j                  j                                y)z5
        Print the progress for empty files.
        r   r   s
   empty-filer   s%   b'empty-file'100% 0.0B 0.0Bps 00:00 N)
r   r   r   r   r   r   r   r;   r   r   )r-   r   r   r   s       r.   test_printProgressBarEmptyFilez/StdioClientTests.test_printProgressBarEmptyFile  sn     	  R()$""7+%%gq1:!6!6!<!<!>?r0   c                 ^    | j                   j                  d      }| j                  d|       y)zK
        Returns empty value for both filename and remaining data.
        z  )r   r   Nr   _getFilenamer;   r-   r   s     r.   test_getFilenameEmptyz&StdioClientTests.test_getFilenameEmpty  s(     ))$/6*r0   c                 ^    | j                   j                  d      }| j                  d|       y)zd
        Returns empty value for remaining data when line contains
        only a filename.
        
only-local)r  r   Nr  r	  s     r.   test_getFilenameOnlyLocalz*StdioClientTests.test_getFilenameOnlyLocal  s)    
 )),7+V4r0   c                 ^    | j                   j                  d      }| j                  d|       y)ze
        Returns filename and remaining data striped of leading and trailing
        spaces.
        z local  remote file  )localzremote fileNr  r	  s     r.   test_getFilenameNotQuotedz*StdioClientTests.test_getFilenameNotQuoted#  s*    
 ))*AB16:r0   c                 ^    | j                   j                  d      }| j                  d|       y)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	  s     r.   test_getFilenameQuotedz'StdioClientTests.test_getFilenameQuoted,  s*    
 ))*NO=vFr0   Nc                     || j                         }t        |d      5 }|j                  |       ddd       |S # 1 sw Y   |S xY w)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-   r   contentfiles       r.   makeFilezStdioClientTests.makeFile5  sF     <;;=D$ 	 JJw	 	 s	   ;Ac                    | j                   j                  j                         }|j                  d      }|j	                  d      }g }g }|D ]T  \  }}}g }	|D ]  }
|	j                  | d|
         |	j                  d| d|        |j                  |	       |j                  d      j                  d      j	                  d      }|dd	 }|d	   j                  d
      j	                  d
      }|j                  |       g }|dd	 D ]o  }
|
j                         j                  dd      d   }
|
j                         j	                  dd      }
|j                  |
d    d|
d   j                                 q |j                  |d	          |j                  |       W |r%| j                  t        |      t        |             n| j                  ||       | j                  dt        |      d       y)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

        r7   z
 zTransferred z to r   N
   r   z5There are still put responses which were not checked.)r   r   r   decodesplitappendr   stripextendrsplitr;   sortedlen)r-   	transfersrandomOrderoutputexpectedOutputactualOutputr  remoteexpectedexpectedTransferlineprogressPartsactuallastactualTransfers                  r.   checkPutMessagez StdioClientTests.checkPutMessageI  s    &&,,.w'f%'0 	0#E68  "  ; ''5'4&(9:;##l5'fX$FG!!"23"JJqM//5;;DAM"3B'F $**4066t<DMM$N s F zz|**3215 zz|))#q1%%a	47==?2C&DEF !!&*-/?	0B VN3VL5IJ^\:KC	
r0   c                    d}| j                  |      }t        j                  t        j                  z  t        j                  z  }t
        j                  j                  dt
        j                  j                  |            }t        |      }| j                  j                  ||t        j                  |             d| j                  j                  j                  d<   | j                  j!                  |      }| j#                  |       | j%                  ||j'                                | j)                  |j*                         | j-                  ||g dfg       y)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   r   r   )z	76% 10.0B
100% 13.0Br7  N)r  r   	FXF_WRITE	FXF_CREAT	FXF_TRUNCrP   r   joinbasenamer   r   r   r   r   r   r   cmd_PUTsuccessResultOfr;   r<   r3   r   r5  )r-   r  	localPathr   
remoteName
remoteFiledeferreds          r.   test_cmd_PUTSingleNoRemotePathz/StdioClientTests.test_cmd_PUTSingleNoRemotePath  s    %MM'M2	&&)?)??,BXBXXWW\\#rww'7'7	'BC
'
3

E5==3LM35""<0;;&&y1X&*"5"5"78
**+%NOP	
r0   c                    | j                         }t        j                  t        j                  z  t        j                  z  }d}t        |      }| j                  j                  ||t        j                  |             | j                  j                  | d| d      }| j                  |       | j                  ||dgfg       | j                  |j                         | j!                  d|j#                                y)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.0Br0   N)r  r   r8  r9  r:  r   r   r   r   r   r   r=  r>  r5  r3   r   r;   r<   )r-   r?  r   r@  rA  rB  s         r.   test_cmd_PUTSingleRemotePathz-StdioClientTests.test_cmd_PUTSingleRemotePath  s     MMO	&&)?)??,BXBXX#
'
3

E5==3LM;;&&)Aj\'JKX&y*{mDEF
**+j1134r0   c                 "   | j                         }t        j                  j                  |      }d}t        j                  j	                  |      }| j                  t        j                  j                  ||            }t        j                  t        j                  z  t        j                  z  }d| }d| }t        |      }	t        |      }
| j                  j                  ||t        j                  |	             | j                  j                  ||t        j                  |
             | j                  j!                  t        j                  j                  |d            }| j#                  |       | j%                  |	j&                         | j)                  d|	j+                                | j%                  |
j&                         | j)                  d|
j+                                | j-                  ||dgf||dgfgd       y	)
z
        When a gobbing expression is used local files are transferred with
        remote file names based on local names.
        second-namer   r   *r0   rE  Tr)  N)r  rP   r   r<  dirnamer;  r   r8  r9  r:  r   r   r   r   r   r   r=  r>  r3   r   r;   r<   r5  )r-   first	firstName
secondNameparentsecondr   firstRemotePathsecondRemotePathfirstRemoteFilesecondRemoteFilerB  s               r.    test_cmd_PUTMultipleNoRemotePathz1StdioClientTests.test_cmd_PUTMultipleNoRemotePath  s   
 GG$$U+	"
'BGGLL$DE&&)?)??,BXBXXi[/zl+,_=-.>?o8VWeU]]3C%D	
 ;;&&rww||FC'@AX&//0o6689(001.779:+7)K=9  	 	
r0   c                 @   | j                         }t        j                  j                  |      }d}t        j                  j	                  |      }| j                  t        j                  j                  ||            }t        j                  t        j                  z  t        j                  z  }t        |      }t        |      }d| }	d| }
| j                  j                  |	|t        j                  |             | j                  j                  |
|t        j                  |             | j                  j!                  dj#                  t        j                  j                  |d                  }| j%                  |       | j'                  |j(                         | j+                  d|j-                                | j'                  |j(                         | j+                  d|j-                                | j/                  ||dgf||dgfgd	       y
)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.
        rH  rI  z/remote/z	{} remoterJ  r0   rE  TrK  N)r  rP   r   r<  rL  r;  r   r8  r9  r:  r   r   r   r   r   r   r=  formatr>  r3   r   r;   r<   r5  )r-   rM  rN  rO  rP  rQ  r   rT  rU  rR  rS  rB  s               r.   "test_cmd_PUTMultipleWithRemotePathz3StdioClientTests.test_cmd_PUTMultipleWithRemotePath  s    GG$$U+	"
'BGGLL$DE&&)?)??,BXBXX,Y7-j9$YK0%j\2o8VWeU]]3C%D	
 ;;&&{'9'9"'',,vs:S'TUX&//0o6689(001.779:	K=1k]3  	 	
r0   )Nr0   )F)rA   rB   rC   rD   r/   r   r   r   r   r  r  r  r
  r  r  r  r  r5  rC  rF  rV  rY  rE   r0   r.   r   r     sg    =&
/*@0@$@+5;G(;
z
05&!
F#
r0   r   c                       e Zd Zd Zd Zy)FileTransferTestRealmc                     || _         y r'   )testDir)r-   r]  s     r.   r   zFileTransferTestRealm.__init__  s	    r0   c                 >    t        | j                        }|d   |d fS )Nr   c                       y r'   rE   rE   r0   r.   <lambda>z5FileTransferTestRealm.requestAvatar.<locals>.<lambda>   s    r0   )r	   r]  )r-   avatarIDmindr   as        r.   requestAvatarz#FileTransferTestRealm.requestAvatar  s!    "4<<0!}a--r0   N)rA   rB   rC   r   rd  rE   r0   r.   r[  r[    s    .r0   r[  c                   L    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zy)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                 \    | j                          || _        d| _        d| _        d| _        y)zr
        @param onOutReceived: A L{Deferred} to be fired as soon as data is
        received from stdout.
        NF)clearBufferonOutReceivedonProcessEnd_expectingCommand_processEnded)r-   ri  s     r.   r   zSFTPTestProcess.__init__
  s0    
 	* !%"r0   c                 .    d| _         g | _        d| _        y)zR
        Clear any buffered data received from stdout. Should be private.
        r0   N)buffer_linesReceived_lineBufferr,   s    r.   rh  zSFTPTestProcess.clearBuffer  s      r0   c                 ~   t        j                  d|z         | j                  |z   j                  d      }|j	                  d      | _        | j
                  j                  |       | j                  %| j                  dc}| _        |j                  |       | xj                  |z  c_	        | j                          y)zO
        Called by Twisted when the cftp client prints data to stdout.
        zgot %r   
r  N)r   msgrp  r!  r   ro  r$  ri  callbackrn  _checkForCommand)r-   r   linesr   s       r.   outReceivedzSFTPTestProcess.outReceived  s     	4 !!D(//6 99R=""5) )$($6$6!At!JJttr0   c                     d}| j                   r| j                  |k(  rpdj                  | j                        }|j	                  |      r|t        |      d  }| j                          | j                   d c}| _         |j                  |       y y y )Ns   cftp> rr  )rk  rp  r;  ro  
startswithr'  rh  rt  )r-   promptbufr   s       r.   ru  z SFTPTestProcess._checkForCommand.  s    !!d&6&6&&@**T001C~~f%#f+-((,(>(>%At%JJsO 'A!r0   c                 4    t        j                  d|z         y)zO
        Called by Twisted when the cftp client prints data to stderr.
        zerr: %sN)r   rs  )r-   r   s     r.   errReceivedzSFTPTestProcess.errReceived8  s     		D !r0   c                     | j                   S )zQ
        Return the contents of the buffer of data received from stdout.
        )rn  r,   s    r.   	getBufferzSFTPTestProcess.getBuffer>  s     {{r0   c                     t        j                         | _        | j                          t	        |t
              r|j                  d      }| j                  j                  |dz          | 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.
        r7   rr  )	r   Deferredrk  rh  
isinstancestrr9   r   r   r-   commands     r.   
runCommandzSFTPTestProcess.runCommandD  sY     "'!1gs#nnW-GWu_-%%%r0   c                     t        j                  d      }|D cg c]  }|j                  | j                  |        }}t        j                  |      S c c}w )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.
        r   )r   DeferredSemaphorerunr  gatherResults)r-   commandssemr  dls        r.   	runScriptzSFTPTestProcess.runScriptV  sM     %%a(?GHGcggdoow/HH""2&& Is   #Ac                     | j                   rt        j                  d      S t        j                         | _        | j
                  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)rl  r   r   r  rj  r   signalProcessr,   s    r.   killProcesszSFTPTestProcess.killProcesse  sI     ==&&!NN,$$V,   r0   c                 v    d| _         | j                  r&| j                  dc}| _        |j                  d       yy)zF
        Called by Twisted when the cftp client process ends.
        TN)rl  rj  rt  )r-   reasonr   s      r.   processEndedzSFTPTestProcess.processEndedt  s;     "#'#4#4d At JJt r0   N)rA   rB   rC   rD   r   rh  rw  ru  r}  r  r  r  r  r  rE   r0   r.   rf  rf    s9    	# ""&$'!r0   rf  c                   *    e Zd Zd Zd Zd Zd Zd Zy)CFTPClientTestBasec                    t        dd      5 }|j                  t        j                         d d d        t        dd      5 }|j                  t        j                         d d d        t        j                  dd       t        dd      5 }|j                  dt        j                  z          d d d        t        j                  |       S # 1 sw Y   xY w# 1 sw Y   wxY w# 1 sw Y   6xY w)Ndsa_test.pubr  dsa_testi  kh_tests
   127.0.0.1 )
r  r   r!   publicDSA_opensshprivateDSA_opensshrP   chmodpublicRSA_opensshr
   r/   r-   fs     r.   r/   zCFTPClientTestBase.setUp  s    .$' 	01GGH../	0*d# 	1qGGH//0	1
U#)T" 	@aGGMH$>$>>?	@!!$''	0 	0	1 	1	@ 	@s#    C C#C#CC #C,c                    t        | j                        }t        j                  |      }|j	                  t        j                                t        j                         }||_        t        j                  d|d      | _
        y )Nr   z	127.0.0.1)	interface)r[  r]  r   PortalregisterCheckerr!   conchTestPublicKeyCheckerConchTestServerFactoryr   	listenTCPserver)r-   realmpfacs       r.   startServerzCFTPClientTestBase.startServer  s`    %dll3MM% 	(<<>?--/
''3+Fr0   c                 v   t        | j                  j                  d      s| j                  d       S d| j                  j                  j                  _        t        j                  | j                  j                  j                  j                  j                        }|j                  | j                         |S )Nprotor   )hasattrr  factory_cbStopServerr  expectedLoseConnectionr   maybeDeferredr   loseConnectionr   r   s     r.   
stopServerzCFTPClientTestBase.stopServer  s    t{{**G4%%d++;<!!8 3 3 9 9 C C R RS	d(()r0   c                 T    t        j                  | j                  j                        S r'   )r   r  r  stopListeningr-   ignoreds     r.   r  z CFTPClientTestBase._cbStopServer  s    ""4;;#<#<==r0   c                     dD ]  }	 t        j                  |        t        j                  |       S # t        $ r Y ;w xY w)N)r  r  r  )rP   removeBaseExceptionr
   tearDownr  s     r.   r  zCFTPClientTestBase.tearDown  sH    8 	A		!	
 $$T** ! s   3	??N)rA   rB   rC   r/   r  r  r  r  rE   r0   r.   r  r  ~  s    (G>+r0   r  c                       e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 ZddZd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zy)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                 "    t         j                           j                          d} j                  j	                         j
                  }t        j                  ||z  j                         d      }t        j                  dt        j                   d|        t        j                         }t        |       _        |j#                   fd       t$        j&                  j)                         }t$        j*                  j-                  t        j.                        |d<   g }i }|D ]4  }t1        |t2              r|j5                  d      }|j7                  |       6 |D ]N  }||   }	t1        |t2              r|j5                  d      }t1        |	t2              r|	j5                  d      }	|	||<   P t        j                  |       t        j                  |       t9        j:                   j                   t        j                  ||	       |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 r  c                 8    j                   j                         S r'   )processProtocolrh  _r-   s    r.   r`  z3OurServerCmdLineClientTests.setUp.<locals>.<lambda>       4 4 @ @ B r0   
PYTHONPATHr7   env)r  r/   r  r  getHostportr    	_makeArgsr!  r   rs  r   r   r   r  rf  r  r   rP   rQ   copypathsepr;  r   r  r  r9   r"  r   spawnProcess)
r-   cmdsr  r   r  encodedCmds
encodedEnvcmdvarvals
   `         r.   r/   z!OurServerCmdLineClientTests.setUp  s     & 	 {{""$))##TD[$7$7$9vF(3>>*!D623NN.q1	BCjjooJJOOCHH5L
 	$C#s#jj)s#	$  	"Cc(C#s#jj)#s#jj)!JsO	" 	
  #..+:	
 r0   c                 P      j                         }|j                   fd       |S )Nc                 8    j                   j                         S r'   )r  r  r  s    r.   r`  z6OurServerCmdLineClientTests.tearDown.<locals>.<lambda>  r  r0   )r  r   r   s   ` r.   r  z$OurServerCmdLineClientTests.tearDown  s!    OO	BCr0   c                     	 | j                   j                  j                  d       y # t        j                  $ r Y y w xY w)Nr  )r  r   r  r   ProcessExitedAlreadyr  s     r.   _killProcessz(OurServerCmdLineClientTests._killProcess  s9    	  **88@)) 		s   %( >>c                 8    | j                   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.
        )r  r  r  s     r.   r  z&OurServerCmdLineClientTests.runCommand  s     ##..w77r0   c                 8    | j                   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.
        )r  r  )r-   r  s     r.   r  z%OurServerCmdLineClientTests.runScript  s     ##--h77r0   c                     | j                   }| j                  ddddd      }d }|j                  |       |j                  | j                  |j                  t        j                         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.
        pwdlpwdzcd testDirectorycd ..c                     g }| D ]4  }t        |t              r|j                  d      }|j                  |       6 |dd |dd z   S )zH
            Callback function for handling command output.
            r7   N      )r  bytesr   r"  )r*  r  r  s      r.   	cmdOutputz8OurServerCmdLineClientTests.testCdPwd.<locals>.cmdOutput  sU     D !c5)**W-CC ! 8d12h&&r0   r   )r]  r  r   r;   r   rP   getcwd)r-   homeDirr   r  s       r.   	testCdPwdz%OurServerCmdLineClientTests.testCdPwd  sg     ,,NN5&*<guM		' 	
i 	d&&ryy{B(UVr0   c                 X      fd} j                  dddd      }|j                  |      S )z
        Check that 'ls -l' output includes the access permissions and that
        this output changes appropriately with 'chmod'.
        c                    j                          j                  | d   j                  d             j                  | d   d       j                  | d   j                  d      | d          j                  | d   d       y )Nr   s
   -rw-r--r--r   r0   r  s
   ----------r  )flushLoggedErrorsr3   ry  r;   resultsr-   s    r.   _checkz7OurServerCmdLineClientTests.testChAttrs.<locals>._check  ss    ""$OOGAJ11-@AWQZ-OOGAJ11-@'!*MWQZ-r0   zls -l testfile1zchmod 0 testfile1zchmod 644 testfile1r  r   r-   r  r   s   `  r.   testChAttrsz'OurServerCmdLineClientTests.testChAttrs  s5    	. NN!	
 }}V$$r0   c                       fd} j                  dd j                  j                         z   ddd      }|j                  d        |j                  |      S )z
        Check 'ls' works as expected. Checks for wildcards, hidden files,
        listing directories and listing empty directories.
        c                     j                  | d   g d       j                  | d   g d       j                  | d   ddg       j                  | d   g d       j                  | d	   d
g       y )Nr   s   testDirectory   testRemoveFile   testRenameFiles	   testfile1r   r  r  r  r  )s   .testHiddenFiler  r  r  r0   r;   r  s    r.   r  z4OurServerCmdLineClientTests.testList.<locals>._check*  s    
V 
V WQZ*;=N)OP
V WQZ#/r0   r   zls ../zls *Filezls -a *Filezls -l testDirectoryc                 J    | D cg c]  }|j                  d       c}S c c}w )Nrr  )r!  )xsxs     r.   r`  z6OurServerCmdLineClientTests.testList.<locals>.<lambda>@  s    "!=Q!''%.!= !=s    )r  r]  r<  r   r  s   `  r.   testListz$OurServerCmdLineClientTests.testList$  sW    	0 NNt||,,..!
 	
=>}}V$$r0   c                    | j                  d      }t        j                  d      j                  d      j	                         }t        |t              r|j                  d      }|j                  | j                  |       |S )zB
        Check that running the '?' command returns help.
        ?Nr   r7   )
r  r   r   cmd_HELPr#  r  r  r9   r   r;   )r-   r   helpTexts      r.   testHelpz$OurServerCmdLineClientTests.testHelpC  sg     OOC ##D)2226<<>h$w/H	d&&1r0   Nc                 b    | j                  |j                         |j                         |       y)zg
        Assert that the files at C{name1} and C{name2} contain exactly the
        same data.
        N)r;   
getContent)r-   name1name2rs  s       r.   assertFilesEqualz,OurServerCmdLineClientTests.assertFilesEqualO  s(    
 	))+U-=-=-?Er0   c                 h    dj                   j                  j                   j                  j                        t        t              rj                  d       fd} j                  d j                  j                   d      }|j                  |       |j                   f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 file2r7   c                     j                  | j                               j                  j                  j	                  d      j                  j	                  d      d       j                  d      S )N	testfile1
test file2z
get failedzrm "test file2")r3   endswithr  r]  childr  r   r+  r-   s    r.   	_checkGetz6OurServerCmdLineClientTests.testGet.<locals>._checkGetd  s_    OOFOON;<!!"";/""<0
 ??#455r0   zget testfile1 "z/test file2"c                 t    j                  j                  j                  d      j                               S )Nr  assertFalser]  r  existsr  s    r.   r`  z5OurServerCmdLineClientTests.testGet.<locals>.<lambda>p  *    d&&t||'9'9,'G'N'N'PQ r0   )rX  r]  r   r  r  r9   r  r   )r-   r  r   r+  s   `  @r.   testGetz#OurServerCmdLineClientTests.testGetV  s     EKKLLLL
 nc*+227;N	6 OOodll.?.?-@MN	i 	Q	
 r0   c                 R      fd} j                  d      }|j                  |      S )zQ
        Test that 'get' works correctly when given wildcard parameters.
        c                     j                  j                  j                  d      t        d      d       j                  j                  j                  d      t        d      d       y )NtestRemoveFiletestRemoveFile get failedtestRenameFiletestRenameFile get failed)r  r]  r  r   )r  r-   s    r.   r  z;OurServerCmdLineClientTests.testWildcardGet.<locals>._checky  s_    !!""#34)*+
 !!""#34)*+r0   z
get testR*)r  r   r  s   `  r.   testWildcardGetz+OurServerCmdLineClientTests.testWildcardGett  s'    

	 OOL)}}V$$r0   c                 V    d j                   j                         j                  z   dz    j                   j                         j                  z   dz    fd} j                  d j                   j                   d      }|j	                  |       |j	                   f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                     j                  j                  j                  d      j                  j                  d             j                  | j	                               j                  d      S )Nr  
test"file2zrm "test\"file2")r  r]  r  r3   r  r  r  s    r.   	_checkPutz6OurServerCmdLineClientTests.testPut.<locals>._checkPut  s[    !!"";/1C1CL1Q OOFOON;<??#677r0   put z/testfile1 "test\"file2"c                 t    j                  j                  j                  d      j                               S )Nr   r  r  s    r.   r`  z5OurServerCmdLineClientTests.testPut.<locals>.<lambda>  r  r0   )r]  asBytesModer   r  r   )r-   r!  r   r+  s   `  @r.   testPutz#OurServerCmdLineClientTests.testPut  s     ll&&(--.  ll&&(--. 	 		8 OOd4<<#4#4"55NOP	i 	Q	
 r0   c                      j                   j                  d      j                  d      5 }|j                  d       ddd        j                   j                  d      j                  d      5 }|j                  d       ddd        fd} j	                  d	 j                   j
                   d
      }|j                  |       |S # 1 sw Y   xY w# 1 sw Y   VxY w)zb
        Check that 'put' uploads files correctly when overwriting a longer
        file.
        shorterFilewmode   aN
longerFile   bbc                     j                  j                  j                  d      j                  j                  d             y )Nr'  r,  )r  r]  r  )r   r-   s    r.   r!  zEOurServerCmdLineClientTests.test_putOverLongerFile.<locals>._checkPut  s4    !!""=14<<3E3El3Sr0   r"  z/shorterFile longerFile)r]  r  r  r   r  r   r   )r-   r  r!  r   s   `   r.   test_putOverLongerFilez2OurServerCmdLineClientTests.test_putOverLongerFile  s     \\.333= 	GGDM	\\-222< 	GGEN		
 OOd4<<#4#4"55LMN	i 	 		 	s   C2CCC"c                      j                   j                  d      j                          j                  d      j                  d      5 }|j	                  d       ddd        j                   j                  d      j                  d      5 }|j	                  d       ddd        fd} j                  d	 j                   j                   d
      }|j                  |       |S # 1 sw Y   xY w# 1 sw Y   WxY w)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+  Nr-  c                 z    j                  j                  d      j                  j                  d             y )Nr  )r  r  r]  )r   r-   someDirs    r.   r!  zMOurServerCmdLineClientTests.test_putMultipleOverLongerFile.<locals>._checkPut  s+    !!'--"79K9KF9STr0   r"  z/dir/*)r]  r  createDirectoryr  r   r  r   r   )r-   r  r!  r   r3  s   `   @r.   test_putMultipleOverLongerFilez:OurServerCmdLineClientTests.test_putMultipleOverLongerFile  s     ,,$$U+!]]6"''S'1 	QGGDM	\\',,#,6 	!GGEN		U OOd4<<#4#4"5V<=	i 	 		 	s   C0C<0C9<Dc                       fd} j                  dd j                  j                   dd j                  j                         z        }|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                    j                  | d   d       j                  | d   d       j                  j                  j                  d      j                  j	                         j                  d      d       j                  j                  j                  d      j                  j	                         j                  d      d       y )Nr   r0   r  r  r  r  r  )r;   r  r]  r  rP  r  s    r.   checkz:OurServerCmdLineClientTests.testWildcardPut.<locals>.check  s    WQZ-WQZ-!!""#34##%++,<=+
 !!""#34##%++,<=+r0   r  r"  z/testR*zcd %s)r  r]  r   r<  r   )r-   r8  r   s   `  r.   testWildcardPutz+OurServerCmdLineClientTests.testWildcardPut  sZ    	 NN4<<$$%W-dll++--

 	
er0   c                       fd} j                  dd      }|j                  |       |j                   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                     j                          j                  | d   d       j                  | d   j                  d      d       j	                  d      S )Nr   r0   r      lzlink failedzrm testLink)r  r;   r3   ry  r  r  s    r.   r  z4OurServerCmdLineClientTests.testLink.<locals>._check  sO    ""$WQZ-OOGAJ11$7G??=11r0   zln testLink testfile1zls -l testLinkr0   r  r   r;   r  s   `  r.   testLinkz$OurServerCmdLineClientTests.testLink  sA    	2 NN24DE	f	d&&,r0   c                       fd} j                  dd      }|j                  |       |j                   j                  d       |S )zV
        Test that we can create and remove directories with the cftp client.
        c                     j                  | d   d       j                  | d   j                  d             j                  d      S )Nr   r0   r      dzrmdir testMakeDirectory)r;   r3   ry  r  r  s    r.   r  z?OurServerCmdLineClientTests.testRemoteDirectory.<locals>._check   sB    WQZ-OOGAJ11$78??#<==r0   mkdir testMakeDirectoryzls -l testMakeDirector?r0   r=  r  s   `  r.   testRemoteDirectoryz/OurServerCmdLineClientTests.testRemoteDirectory  sA    
	>
 NN46OP	f	d&&,r0   c                 X      fd} j                  dd      }|j                  |       |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                 Z    j                  | d   d       j                  | d   d       y )Nr   r0   r   s   remote error 11: mkdir failedr  r  s    r.   r  zHOurServerCmdLineClientTests.test_existingRemoteDirectory.<locals>._check  s,    WQZ-WQZ)IJr0   rB  r  r  s   `  r.   test_existingRemoteDirectoryz8OurServerCmdLineClientTests.test_existingRemoteDirectory
  s.    	K NN46OP	fr0   c                       j                  d j                  j                   d      }|j                   j                  d       |j                   fd       |j                   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/testLocalDirectoryr0   c                 &    j                  d      S )Nzrmdir testLocalDirectory)r  r  s    r.   r`  z@OurServerCmdLineClientTests.testLocalDirectory.<locals>.<lambda>   s    0J K r0   )r  r]  r   r   r;   r   s   ` r.   testLocalDirectoryz.OurServerCmdLineClientTests.testLocalDirectory  sb     OOgdll&7&7%88KLM	d&&,	KL	d&&,r0   c                       fd} j                  dd      }|j                  |       |j                   j                  d       |S )z1
        Test that we can rename a file.
        c                 z    j                  | d   d       j                  | d   d       j                  d      S )Nr   r0   r   s	   testfile2zrename testfile2 testfile1)r;   r  r  s    r.   r  z6OurServerCmdLineClientTests.testRename.<locals>._check)  s;    WQZ-WQZ6??#?@@r0   zrename testfile1 testfile2zls testfile?r0   r=  r  s   `  r.   
testRenamez&OurServerCmdLineClientTests.testRename$  sA    
	A
 NN7H	f	d&&,r0   r'   )rA   rB   rC   rD   r/   r  r  r  r  r  r  r  r  r  r  r  r%  r/  r5  r9  r>  rC  rF  rI  rL  rE   r0   r.   r  r    sr    (T
884%,%>
F<%(8((<"
r0   r  c                   4    e Zd ZdZd Zd Zd Zd Zd Zd Z	y)	OurServerBatchFileTestszm
    Functional tests which launch a SFTP server over localhost and checks csftp
    in batch interface.
    c                 N    t         j                  |        | j                          y r'   r  r/   r  r,   s    r.   r/   zOurServerBatchFileTests.setUp;  s      &r0   c                 L    t         j                  |        | j                         S r'   )r  r  r  r,   s    r.   r  z OurServerBatchFileTests.tearDown?  s    ##D)  r0   c                    | j                         t        d      5 }|j                  |       d d d        | j                  j	                         j
                  }d|fz  }t        j                  |j                         d      dd  }t        j                  dt        j                   d|        t        j                  j                         }t        j                   j#                  t        j$                        |d<   d| j                  j&                  _        t+        t        j                  ||	      }fd
}|j-                  d        |j/                  |       |S # 1 sw Y   5xY w)Nr(  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   r  r   r  r  r  r  c                 2    t        j                         | S r'   )rP   r  )resfns    r.   _cleanupz9OurServerBatchFileTests._getBatchOutput.<locals>._cleanupZ  s    IIbMJr0   c                     | d   S )Nr   rE   )rT  s    r.   r`  z9OurServerBatchFileTests._getBatchOutput.<locals>.<lambda>^  s
    #a& r0   )r  r  r   r  r  r  r    r  r!  r   rs  r   r   rP   rQ   r  r  r;  r   r  r  r   r   addBoth)	r-   r  fpr  r  r  r   rV  rU  s	           @r.   _getBatchOutputz'OurServerBatchFileTests._getBatchOutputC  s   [[]"c] 	bHHQK	{{""$))! 2J ##DJJLf=abA(3>>*!D623jjooJJOOCHH5L562$S^^TsC	 	
()			(9	 	s   E##E-c                 Z     d} fd} j                  |      }|j                  |       |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                    | j                  d      } t        j                  dt        |       z         j	                  j
                  j                         j                  | d          j                  | dd g d       y )Nrr  zRES %sr   r  r  )	r!  r   rs  reprassertInr]  r$  r   r;   rT  r-   s    r.   _cbCheckResultz=OurServerBatchFileTests.testBatchFile.<locals>._cbCheckResultm  se    ))E"CGGHtCy()MM$,,224993q6BAb	Vr0   rZ  r   r-   r  ra  r   s   `   r.   testBatchFilez%OurServerBatchFileTests.testBatchFilec  s2    

	   &	n%r0   c                 Z     d} fd} j                  |      }|j                  |       |S )zO
        Test that an error in the batch file stops running the batch.
        zchown 0 missingFile
pwd
exit
c                 n    j                  j                  j                         j                  |        y r'   )assertNotInr]  r$  r   r`  s    r.   ra  z9OurServerBatchFileTests.testError.<locals>._cbCheckResult  s&    T\\557<<cBr0   rb  rc  s   `   r.   	testErrorz!OurServerBatchFileTests.testErrorz  s3    
	C   &	n%r0   c                 Z     d} fd} j                  |      }|j                  |       |S )z_
        Test that a minus sign '-' at the front of a line ignores
        any errors.
        z-chown 0 missingFile
pwd
exit
c                 n    j                  j                  j                         j                  |        y r'   )r_  r]  r$  r   r`  s    r.   ra  z@OurServerBatchFileTests.testIgnoredError.<locals>._cbCheckResult  s$    MM$,,224993?r0   rb  rc  s   `   r.   testIgnoredErrorz(OurServerBatchFileTests.testIgnoredError  s3    

	@   &	n%r0   N)
rA   rB   rC   rD   r/   r  rZ  rd  rh  rk  rE   r0   r.   rN  rN  4  s&    
!@. r0   rN  sshz$no ssh command-line client availablesftpz%no sftp command-line client availablec                   "    e Zd ZdZd Zd Zd Zy)OurServerSftpClientTestsz@
    Test the sftp server against sftp command line client.
    c                 L    t         j                  |        | j                         S r'   rP  r,   s    r.   r/   zOurServerSftpClientTests.setUp  s      &!!r0   c                 "    | j                         S r'   )r  r,   s    r.   r  z!OurServerSftpClientTests.tearDown  s      r0   c                 4   	 t        t        j                         j                         t	        d      5 }|j                  d       ddd        j                  j                         j                  	t        j                  fd} j                  t        d|       d j                  j                  _        t        dd      }	fd	} fd
}|j                  |       |j                  fd       |j                  |      S # 1 sw Y   xY w)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 .
exitNc                 $     | |      }d|d<   |S )Nr   ext_foorE   )r-   sr   
oldGetAttrs      r.   	_getAttrszCOurServerSftpClientTests.test_extendedAttributes.<locals>._getAttrs  s    tQ'E$E)Lr0   rw  Trl  )-oPubkeyAcceptedKeyTypes=ssh-dssz-Vc                 H    | dk(  rd}nd}|dddddddd	dd
fz  ddfz  }|S )Nr   )rx  ry  rE   z-Fz	/dev/nullrx  zIdentityFile=dsa_testzUserKnownHostsFile=kh_testzHostKeyAlgorithms=ssh-rsazPort=%iz-bztestuser@127.0.0.1rE   )statusargsrU  r  s     r.   hasPAKTzAOurServerSftpClientTests.test_extendedAttributes.<locals>.hasPAKT  sZ    {? ',+TG#$ D Kr0   c                     j                  | d   d| d   j                  d             dD ]  }j                  || d           y )Nr  r   r   asciir  )r;   r   r_  )r   ir-   s     r.   r8  z?OurServerSftpClientTests.test_extendedAttributes.<locals>.check  sM    VAY6!9+;+;G+DE , a+,r0   c                     t        d|       S )Nrm  )r   )r|  r  s    r.   r`  zBOurServerSftpClientTests.test_extendedAttributes.<locals>.<lambda>  s    #;FD##N r0   )dictrP   rQ   r  r  r   r  r  r  r#   rw  rT   r  r  r   r   )
r-   r  rw  r   r}  r8  r  rU  rv  r  s
   `     @@@@r.   test_extendedAttributesz0OurServerSftpClientTests.test_extendedAttributes  s     2::[[]"c] 	"aGGL!	"{{""$)).88
	
 	

,k9E592 E#QSVW	2	, 	
g	NO}}U##s	" 	"s   DDN)rA   rB   rC   rD   r/   r  r  rE   r0   r.   ro  ro    s    "!F$r0   ro  )RrD   r   rs   rV   rP   r   r   rM   ior   r   unittestr   zope.interfacer   twisted.conchr   twisted.conch.interfacesr   $twisted.conch.test.test_filetransferr	   r
   twisted.credr   twisted.internetr   r   r   r   r   twisted.internet.taskr   twisted.internet.testingr   twisted.internet.utilsr   r   twisted.pythonr   twisted.python.fakepwdr   twisted.python.filepathr   twisted.python.procutilsr   twisted.python.reflectr   twisted.trial.unittestr   r   unixtwisted.conch.scriptsr   twisted.conch.scripts.cftpr   twisted.conch.sshr   twisted.conch.ssh.connectionr   twisted.conch.testr    r!   twisted.conch.test.test_conchr"   r#   ImportError	skipTestsIReactorProcessr%   rG   r   r   r   r   r   r[  ProcessProtocolrf  r  r  rN  ro  rE   r0   r.   <module>r     s=  
    	  
  %  &  . U  H H ' 4 L  / , * 0 +^,)*	.92E;;R 	D, :
 : :7D IJJI 	?@$
h $
 A$
N_
8 _
D  #. #.L9 96 Y/& /& /&d 	?@p
x p
 Ap
f. .xh.. xv$+ $+N 	?@K"4 K AK\ 	?@d0 d AdN 	?@E%L@AE&MBCR$1 R$ D B AR$_+  s   &,G2 2G;:G;