Ϫf?dZddlZddlZddlZddlZddlZddlZddlZddlm Z m Z ddl m Z ddl mZddlmZddlmZddlmZmZdd lmZdd lmZmZmZmZmZdd lmZdd l m!Z!dd l"m#Z#m$Z$ddl%m&Z&ddl'm(Z(ddl)m*Z*ddl+m,Z,ddl-m.Z.ddl/m0Z0e.dZ1e.dZ2e1r- ddl3m4Z4ddl5m6Z6ddl7m8Z8ddl9m:Z:ddl;mm?Z?ddlm@Z@dZBde2e1ejedfvrdZBe eBdGd d!e0ZDGd"d#e0ZEGd$d%e!ZFGd&d'ZGGd(d)ZHeeGd*d+e ZIe eBdGd,d-e0ZJGd.d/ZKGd0d1ejZMGd2d3eZNe eBdGd4d5eNZOe eBdGd6d7eNZPe eBde e,d8 d9e e,d: d;Gd<d=eNZQy#eA$rY(wxYw)>z* Tests for L{twisted.conch.scripts.cftp}. N)BytesIO TextIOWrapper)skipIf) implementer)ls) ISFTPFile)FileTransferTestAvatar SFTPTestBase)portal)defererror interfacesprotocolreactor)Clock)StringTransport)getProcessOutputAndValuegetProcessValue)log) UserDatabase)FilePath)which) requireModule)TestCase cryptographyztwisted.conch.unix)cftp) SSHSession) filetransfer)EXTENDED_DATA_STDERR) test_conchtest_ssh) FakeStdio)FileTransferForTestAvatarFTz*don't run w/o spawnProcess or cryptographyc(eZdZdZddZddZddZy)SSHSessionTestsz= Tests for L{twisted.conch.scripts.cftp.SSHSession}. Nct|_t|_|j|j_t |_t |j |_|j|j_yN)r"stdiorchannelr stderrBufferrstderrselfs >/usr/lib/python3/dist-packages/twisted/conch/test/test_cftp.pysetUpzSSHSessionTests.setUp>sP[ !| !ZZ #I#D$5$56 "kk c|jj|j|jjy)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_eofReceivedFs*   "  001r0cd}|jd}|jjt|dz|j |j j |dzy)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-8s\xffN)encoder) extReceivedr assertEqualr*getvalue)r- errorText errorBytess r.test_extReceivedStderrz&SSHSessionTests.test_extReceivedStderrNs` " %%g.           & & (  ! r0)returnN)__name__ __module__ __qualname____doc__r/r5r?r0r.r%r%8s*2 r0r%czeZdZdZeedddZdZdZdZ dZ d Z e jZ e je j d d Ze je j eeed dZdZy#e j$$rd ZYCwxYw#e je j ewxYw) 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.tzsetcZd_fd}jtd|dtjvraj t jtjdtjdj tjyd}j |y)zo Patch the L{ls} module's time function so the results of L{lsLine} are deterministic. i[cjSr')nowr,sr.fakeTimez$ListingTests.setUp..fakeTimeps 88Or0timeTZcn tjd=tjy#t$rY wxYw)NrN)osenvironKeyErrorrMrHrEr0r.cleanupz#ListingTests.setUp..cleanup|s2 4(  s ( 44N) rKpatchrrPrQ addCleanupoperatorsetitemrMrH)r-rLrSs` r.r/zListingTests.setUpisy   2vx( 2::  OOH,,bjj$ 4@P Q OODJJ '  OOG $r0c||tjd<tjt j d|S)zl Call L{ls.lsLine} after setting the timezone to C{timezone} and return the result. rNfoo)rPrQrMrHrlsLine)r-timezonestats r. _lsInTimezonezListingTests._lsInTimezones,$ 4 yy%%r0c |jdz }tjdddddddd|df }|j|j d|d|j|j d|dy)z A file with an mtime six months (approximately) or more in the past has a listing including a low-resolution timestamp. rAmerica/New_Yorkz;!--------- 0 0 0 0 Apr 26 1973 fooPacific/Aucklandz;!--------- 0 0 0 0 Apr 27 1973 fooNrKrP stat_resultr;r]r-thenr\s r. test_oldFilezListingTests.test_oldFile| xx01~~q!Q1aAtQ?@    14 8 I     14 8 I r0c |jdz dz}tjdddddddd|df }|j|j d|d|j|j d|dy) 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_irr`z;!--------- 0 0 0 0 May 01 1973 fooraz;!--------- 0 0 0 0 May 02 1973 fooNrbrds r.test_oldSingleDigitDayOfMonthz*ListingTests.test_oldSingleDigitDayOfMonthxx015EF~~q!Q1aAtQ?@    14 8 I     14 8 I r0c |jdz }tjdddddddd|df }|j|j d|d|j|j d|dy)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. 逛zrr`;!--------- 0 0 0 0 Aug 28 17:33 foora;!--------- 0 0 0 0 Aug 29 09:33 fooNrbrds r. test_newFilezListingTests.test_newFilergr0 es_AR.UTF8FTz'The es_AR.UTF8 locale is not installed.c |jdz }tjdddddddd|df }tj}tj tj d|jtj tj ||j|jd|d|j|jd|dy) zC The month name in the date is locale independent. rmrrqr`rnraroN) rKrPrclocale getlocale setlocaleLC_ALLrUr;r])r-rer\ currentLocales r.test_localeIndependentz#ListingTests.test_localeIndependents xx01~~q!Q1aAtQ?@((*  5 ((&--G    14 8 I     14 8 I r0c |jdz dz}tjdddddddd|df }|j|j d|d|j|j d|dy) rirmiFrr`z;!--------- 0 0 0 0 Sep 01 17:33 fooraz;!--------- 0 0 0 0 Sep 02 09:33 fooNrbrds r.test_newSingleDigitDayOfMonthz*ListingTests.test_newSingleDigitDayOfMonthrkr0)rArBrCrDgetattrrMskipr/r]rfrjrprsrtrwrurv localeSkipErrorrrxrzrEr0r.rGrG`s tWd#+I%: & $ ( (%F$$&M7  F  V]]L 9J 6 JAB C , =|| J   6s)BBBBBBB:rGc"eZdZdZfdZxZS)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} rN)conn localClosedsuper__init__)r-r __class__s r.rzInMemorySSHChannel.__init__s   r0)rArBrCrDr __classcell__)rs@r.rrs r0rc"eZdZdZdZdZdZy)FilesystemAccessExpectationszC A test helper used to support expected filesystem access. ci|_yr'_cacher,s r.rz%FilesystemAccessExpectations.__init__s  r0c&||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-pathflagsstreams r.putz FilesystemAccessExpectations.puts&, T5M"r0c<|jj||fS)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} )rpop)r-rrs r.rz FilesystemAccessExpectations.pop(s{{e}--r0N)rArBrCrDrrrrEr0r.rrs , .r0rceZdZdZdZdZy)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} cFt||_ddd|_||_y)N )requests buffersize)r transportoptions_availableFiles)r-availableFiless r.rzInMemorySFTPClient.__init__Bs'+D1   .r0c:|jj||S)z} @see: L{filetransfer.FileTransferClient.openFile}. Retrieve and remove cached file based on flags. )rr)r-filenamerattrss r.openFilezInMemorySFTPClient.openFileJs ##''%88r0N)rArBrCrDrrrEr0r.rr8s.9r0rc:eZdZdZdZdZdZdZdZdZ dZ y ) InMemoryRemoteFilez; An L{ISFTPFile} which handles all data in memory. c<||_tj|y)zL @param name: Name of this file. @type name: L{str} N)namerr)r-rs r.rzInMemoryRemoteFile.__init__Ys  r0cp|j||j|tj|S)z/ @see: L{ISFTPFile.writeChunk} )seekwriter succeed)r-startdatas r. writeChunkzInMemoryRemoteFile.writeChunkas+ % 4}}T""r0cd|_y)zo @see: L{ISFTPFile.writeChunk} Keeps data after file was closed to help with testing. TN)_closedr,s r.closezInMemoryRemoteFile.closeis  r0cyr'rEr,s r.getAttrszInMemoryRemoteFile.getAttrsq r0cyr'rE)r-offsetlengths r. readChunkzInMemoryRemoteFile.readChunkurr0cyr'rE)r-rs r.setAttrszInMemoryRemoteFile.setAttrsyrr0c,tj|S)zb Get current data of file. Allow reading data event when file is closed. )rr<r,s r.r<zInMemoryRemoteFile.getvalue}s %%r0N) rArBrCrDrrrrrrr<rEr0r.rrSs*#   &r0rceZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZddZddZdZdZdZdZy)StdioClientTestsz( Tests for L{cftp.StdioClient}. cdt|_t|j}tj||_d|j _tx|_|j _ |jdd|j j j|j _ y)zm Create a L{cftp.StdioClient} hooked up to dummy transport and a fake user database. /iN) rfakeFilesystemrr StdioClientclientcurrentDirectoryrdatabase_pwdsetKnownConsoleSizer)r- sftpClients r.r/zStdioClientTests.setUps ;<'(;(;< &&z2 '* $+7>9  (   b)!% 2 2 < < r0c |jjtjdt j dddt j|jjd}|j|jd|S)zs The I{exec} command runs its arguments locally in a child process using the user's shell. secretrYbarzexec print(1 + 2)s3 ) raddUsergetpassgetuserrPgetuidsys executabler_dispatchCommand addCallbackr;r-ds r. test_execzStdioClientTests.test_execsf  OO xdE5#..  KK ( ()< = d&&/r0c |jjtjdt j dddd|j jd}|j|jd|S)zr If the local user has no shell, the I{exec} command runs its arguments using I{/bin/sh}. rrrYrzexec echo hellohello rrrrrPrrrrr;rs r.test_execWithoutShellz&StdioClientTests.test_execWithoutShellsb  OO xdE5"  KK ( (): ; d&& 3r0c |jjtjdt j dddd|j jd}|j|jd|S)zO The I{exec} command is run for lines which start with C{"!"}. rrrYrz/bin/shz !echo hellorrrs r. test_bangzStdioClientTests.test_bangsa  OO xdE5)  KK ( ( 7 d&& 3r0cfddlGfdd}|jtd|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} rNceZdZfdZy)7StdioClientTests.setKnownConsoleSize..FakeFcntlcv|jk7r|jdtjdddS)Nz#Only window-size queries supported.4Hr) TIOCGWINSZfailstructpack)r-fdoptmutateheightttywidths r.ioctlz=StdioClientTests.setKnownConsoleSize..FakeFcntl.ioctls3#..(IICD{{41==r0N)rArBrCr)rrrsr. FakeFcntlrs >r0rfcntl)rrTr)r-rrrrs `` @r.rz$StdioClientTests.setKnownConsoleSizes&  > > 4)+.r0c|jddtx}|j_t d}d|_t j|}d|_|j}|jd|xjdz c_ |jj||d}|j|jjj|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"xsamplei(g@is# b'sample' 40% 4.0kB 2.0kBps 00:03 N)rrrrrrr FileWrappersizesecondsadvancetotal_printProgressBarr;rvaluer-clockwrappedwrapper startTimeresults r.test_printProgressBarReportingz/StdioClientTests.test_printProgressBarReportings   R(&+g- #$-  ""7+  MMO  c   %%gy98 ..446?r0cp|jddtx}|j_t d}d|_t j|}|j}|jj||d}|j|jjj|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. rrrrs! b'sample' 0% 0.0B 0.0Bps 00:00 N) rrrrrrrrrrr;rrrs r.test_printProgressBarNoProgressz0StdioClientTests.test_printProgressBarNoProgresss   R(&+g- #$-  ""7+MMO  %%gy96 ..446?r0c|jddt}d|_tj|}|j j |dd}|j||j jjy)z5 Print the progress for empty files. rrs empty-filers% b'empty-file'100% 0.0B 0.0Bps 00:00 N) rrrrrrrr;rr)r-rrrs r.test_printProgressBarEmptyFilez/StdioClientTests.test_printProgressBarEmptyFilesn   R()$ ""7+ %%gq1: !6!6!?r0c^|jjd}|jd|y)zK Returns empty value for both filename and remaining data. z )rrNr _getFilenamer;r-rs r.test_getFilenameEmptyz&StdioClientTests.test_getFilenameEmptys())$/ 6*r0c^|jjd}|jd|y)zd Returns empty value for remaining data when line contains only a filename. only-local)r rNrr s r.test_getFilenameOnlyLocalz*StdioClientTests.test_getFilenameOnlyLocals) )),7 +V4r0c^|jjd}|jd|y)ze Returns filename and remaining data striped of leading and trailing spaces. z local remote file )localz remote fileNrr s r.test_getFilenameNotQuotedz*StdioClientTests.test_getFilenameNotQuoted#s* ))*AB 16:r0c^|jjd}|jd|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 "Nrr s r.test_getFilenameQuotedz'StdioClientTests.test_getFilenameQuoted,s* ))*NO =vFr0Nc||j}t|d5}|j|ddd|S#1swY|SxYw)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. Nwb)mktempopenr)r-rcontentfiles r.makeFilezStdioClientTests.makeFile5sF <;;=D $   JJw     s ;Ac|jjj}|jd}|j d}g}g}|D]T\}}}g} |D]} | j |d| | j d|d||j | |j djdj d} | dd } | d jd j d } | j| g}| dd D]o} | jjdd d} | jj dd } |j | dd| d jq|j | d |j |W|r%|jt|t|n|j|||jdt|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 r7z  z Transferred z to r N rz5There are still put responses which were not checked.) rrrdecodesplitappendrstripextendrsplitr;sortedlen)r- transfers randomOrderoutputexpectedOutput actualOutputrremoteexpectedexpectedTransferline progressPartsactuallastactualTransfers r.checkPutMessagez StdioClientTests.checkPutMessageIs&&,,.w'f% '0 0 #E68 "   ; ''5'4&(9: ;  # #l5'fX$F G  ! !"2 3"JJqM//5;;DAM"3B'F $**4066tr5r3rr;r<)r-r?rr@rArBs r.test_cmd_PUTSingleRemotePathz-StdioClientTests.test_cmd_PUTSingleRemotePaths MMO &&)?)??,BXBXX# ' 3   E5==3LM;;&&)Aj\'JK X& y*{mDEF  **+ j1134r0c"|j}tjj|}d}tjj |}|jtjj ||}t jt jzt jz}d|}d|}t|} t|} |jj||tj| |jj||tj| |jj!tjj |d} |j#| |j%| j&|j)d| j+|j%| j&|j)d| j+|j-||dgf||dgfgdy ) z When a gobbing expression is used local files are transferred with remote file names based on local names. second-namerr*r0rETr)N)rrPrr<dirnamer;rr8r9r:rrrr rrr=r>r3rr;r<r5) r-first firstName secondNameparentsecondrfirstRemotePathsecondRemotePathfirstRemoteFilesecondRemoteFilerBs r. test_cmd_PUTMultipleNoRemotePathz1StdioClientTests.test_cmd_PUTMultipleNoRemotePaths  GG$$U+ " 'BGGLL$DE&&)?)??,BXBXXi[/zl+,_=-.>?  o8VW  eU]]3C%D ;;&&rww||FC'@A X& //0 o6689 (001 .779: +7)K=9   r0c@|j}tjj|}d}tjj |}|jtjj ||}t jt jzt jz}t|}t|}d|} d|} |jj| |tj||jj| |tj||jj!dj#tjj |d} |j%| |j'|j(|j+d|j-|j'|j(|j+d|j-|j/||dgf||dgfgd 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. rHrIz/remote/z {} remoterJr0rETrKN)rrPrr<rLr;rr8r9r:rrrr rrr=formatr>r3rr;r<r5) r-rMrNrOrPrQrrTrUrRrSrBs r."test_cmd_PUTMultipleWithRemotePathz3StdioClientTests.test_cmd_PUTMultipleWithRemotePaths GG$$U+ " 'BGGLL$DE&&)?)??,BXBXX,Y7-j9$YK0%j\2  o8VW  eU]]3C%D ;;&&{'9'9"'',,vs:S'TU X& //0 o6689 (001 .779:  K=1k]3   r0)Nr0)F)rArBrCrDr/rrrrrrrr r rrrr5rCrFrVrYrEr0r.rrsg=&   /*@0@$ @+5;G(; z 05&! F# r0rceZdZdZdZy)FileTransferTestRealmc||_yr')testDir)r-r]s r.rzFileTransferTestRealm.__init__s  r0c>t|j}|d|dfS)Nrcyr'rErEr0r.z5FileTransferTestRealm.requestAvatar..sr0)r r])r-avatarIDmindras r. requestAvatarz#FileTransferTestRealm.requestAvatars! "4<< 0!}a--r0N)rArBrCrrdrEr0r.r[r[s .r0r[cLeZdZdZdZdZdZdZdZdZ dZ 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-ris r.rzSFTPTestProcess.__init__ s0 * !%"r0c.d|_g|_d|_y)zR Clear any buffered data received from stdout. Should be private. r0N)buffer_linesReceived _lineBufferr,s r.rhzSFTPTestProcess.clearBuffers  r0c~tjd|z|j|zjd}|j d|_|j j ||j%|jdc}|_|j||xj|z c_ |jy)zO Called by Twisted when the cftp client prints data to stdout. zgot %r rN) rmsgrpr!rror$ricallbackrn_checkForCommand)r-rlinesrs r. outReceivedzSFTPTestProcess.outReceiveds 4 !!D(//6 99R= ""5)    )$($6$6 !At! JJt  t  r0c d}|jr|j|k(rpdj|j}|j |r|t |d}|j |jdc}|_|j|yyy)Nscftp> rr)rkrpr;ro startswithr'rhrt)r-promptbufrs r.ruz SFTPTestProcess._checkForCommand.s  ! !d&6&6&&@**T001C~~f%#f+-(    (,(>(> %At% JJsO 'A !r0c4tjd|zy)zO Called by Twisted when the cftp client prints data to stderr. zerr: %sN)rrs)r-rs r. errReceivedzSFTPTestProcess.errReceived8s  D !r0c|jS)zQ Return the contents of the buffer of data received from stdout. )rnr,s r. getBufferzSFTPTestProcess.getBuffer>s{{r0ctj|_|jt |t r|j d}|jj|dz|jS)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. r7rr) r Deferredrkrh isinstancestrr9rrr-commands r. runCommandzSFTPTestProcess.runCommandDsY"'!1  gs #nnW-G Wu_-%%%r0ctjd}|Dcgc]}|j|j| }}tj|Scc}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 DeferredSemaphorerunr gatherResults)r-commandssemrdls r. runScriptzSFTPTestProcess.runScriptVsM%%a(?G HGcggdoow/ H H""2&&Is#Ac|jrtjdStj|_|j j d|jS)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}. NKILL)rlr rrrjr signalProcessr,s r. killProcesszSFTPTestProcess.killProcessesI   ==& &!NN, $$V,   r0cvd|_|jr&|jdc}|_|jdyy)zF Called by Twisted when the cftp client process ends. TN)rlrjrt)r-reasonrs r. processEndedzSFTPTestProcess.processEndedts;"   #'#4#4d At JJt  r0N)rArBrCrDrrhrwrur}rrrrrrEr0r.rfrfs9 # ""  &$ ' !r0rfc*eZdZdZdZdZdZdZy)CFTPClientTestBasectdd5}|jtjdddtdd5}|jtjdddt j ddtdd5}|jdtjzdddtj|S#1swYxYw#1swYwxYw#1swY6xYw)N dsa_test.pubrdsa_testikh_tests 127.0.0.1 ) rrr!publicDSA_opensshprivateDSA_opensshrPchmodpublicRSA_opensshr r/r-fs r.r/zCFTPClientTestBase.setUps .$ ' 01 GGH.. / 0 *d # 1q GGH// 0 1 U# )T " @a GGMH$>$>> ? @!!$'' 0 0 1 1 @ @s# C  C #C# CC #C,ct|j}tj|}|j t j t j}||_tjd|d|_ y)Nrz 127.0.0.1) interface) r[r]r PortalregisterCheckerr!conchTestPublicKeyCheckerConchTestServerFactoryr listenTCPserver)r-realmpfacs r. startServerzCFTPClientTestBase.startServers`%dll3 MM%  (<<>?--/ ''3+F r0cvt|jjds|jdSd|jjj_t j|jjjjj}|j|j|S)Nprotor) hasattrrfactory _cbStopServerrexpectedLoseConnectionr maybeDeferredrloseConnectionrrs r. stopServerzCFTPClientTestBase.stopServerst{{**G4%%d+ +;< !!8    3 3 9 9 C C R R S d(()r0cTtj|jjSr')r rr stopListeningr-ignoreds r.rz CFTPClientTestBase._cbStopServers""4;;#<#<==r0cdD]} tj|tj|S#t$rY;wxYw)N)rrr)rPremove BaseExceptionr tearDownrs r.rzCFTPClientTestBase.tearDownsH8 A  !   $$T**!  s 3 ??N)rArBrCr/rrrrrEr0r.rr~s(G>+r0rceZdZdZdZdZdZdZdZdZ dZ d Z d Z dd Z d ZdZdZdZdZdZdZdZdZdZdZy )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"tjjd}jj j }t j||zjd}tjdtjd|tj}t|_|j#fdt$j&j)}t$j*j-tj.|d<g}i}|D]4}t1|t2r|j5d}|j7|6|D]N}||} t1|t2r|j5d}t1| t2r| j5d} | ||<Ptj|tj|t9j:j tj|| |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.1rmodrunning rc8jjSr')processProtocolrh_r-s r.r`z3OurServerCmdLineClientTests.setUp.. 4 4 @ @ Br0 PYTHONPATHr7env)rr/rrgetHostportr _makeArgsr!rrsrrr rrfrrrPrQcopypathsepr;rrrr9r"r spawnProcess) r-cmdsrrr encodedCmds encodedEnvcmdvarvals ` r.r/z!OurServerCmdLineClientTests.setUps  &   {{""$))##TD[$7$7$9vF (3>>*!D623 NN .q1 BCjjooJJOOCHH5L   $C#s#jj)   s # $ "Cc(C#s#jj)#s#jj)!JsO  "      #..+: r0cPj}|jfd|S)Nc8jjSr')rrrs r.r`z6OurServerCmdLineClientTests.tearDown..rr0)rrrs` r.rz$OurServerCmdLineClientTests.tearDowns! OO  BCr0c |jjjdy#tj$rYywxYw)Nr)rrrr ProcessExitedAlreadyrs r. _killProcessz(OurServerCmdLineClientTests._killProcesss9   * * 8 8 @))   s %(>>c8|jj|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. )rrrs r.rz&OurServerCmdLineClientTests.runCommands ##..w77r0c8|jj|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. )rr)r-rs r.rz%OurServerCmdLineClientTests.runScripts ##--h77r0c|j}|jddddd}d}|j||j|j|jt j d|jg|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. pwdlpwdzcd testDirectorycd ..cg}|D]4}t|tr|jd}|j|6|dd|ddzS)zH Callback function for handling command output. r7N)rbytesr r")r*rrs r. cmdOutputz8OurServerCmdLineClientTests.testCdPwd..cmdOutputsUD !c5)**W-C C  !8d12h& &r0r)r]rrr;rrPgetcwd)r-homeDirrrs r. testCdPwdz%OurServerCmdLineClientTests.testCdPwdsg,, NN5&*._checkss  " " $ OOGAJ11-@ A   WQZ - OOGAJ11-@'!* M   WQZ -r0zls -l testfile1zchmod 0 testfile1zchmod 644 testfile1rrr-rrs` r. testChAttrsz'OurServerCmdLineClientTests.testChAttrss5  . NN    !   }}V$$r0cfd}jddjjzddd}|jd|j|S)z Check 'ls' works as expected. Checks for wildcards, hidden files, listing directories and listing empty directories. cj|dgdj|dgdj|dddgj|dgdj|d d gy) Nrs testDirectorytestRemoveFiletestRenameFiles testfile1rrrrr)s.testHiddenFilerrrr0r;rs r.rz4OurServerCmdLineClientTests.testList.._check*s    V     V    WQZ*;=N)O P    V    WQZ# /r0rzls ../zls *Filez ls -a *Filezls -l testDirectorycJ|Dcgc]}|jdc}Scc}w)Nrr)r!)xsxs r.r`z6OurServerCmdLineClientTests.testList..@s"!=Q!''%.!=!=s )rr]r<rrs` r.testListz$OurServerCmdLineClientTests.testList$sW 0 NN  t||,,. .   !   =>}}V$$r0c|jd}tjdjdj }t |t r|jd}|j|j||S)zB Check that running the '?' command returns help. ?Nrr7) rrrcmd_HELPr#rrr9rr;)r-rhelpTexts r.testHelpz$OurServerCmdLineClientTests.testHelpCsg OOC ##D)2226<<> h $w/H d&&1r0Ncb|j|j|j|y)zg Assert that the files at C{name1} and C{name2} contain exactly the same data. N)r; getContent)r-name1name2rss r.assertFilesEqualz,OurServerCmdLineClientTests.assertFilesEqualOs( ))+U-=-=-?Er0chdjjjjjttrj dfd}j djjd}|j||jfd|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 file2r7cj|jjjj djj ddj dS)N testfile1 test file2z get failedzrm "test file2")r3endswithrr]childrrr+r-s r. _checkGetz6OurServerCmdLineClientTests.testGet.._checkGetds_ OOFOON; <  ! ! "";/ ""<0  ??#45 5r0zget testfile1 "z /test file2"ctjjjdjS)Nr  assertFalser]rexistsrs r.r`z5OurServerCmdLineClientTests.testGet..p*d&&t||'9'9,'G'N'N'PQr0)rXr]rrrr9rr)r-rrr+s` @r.testGetz#OurServerCmdLineClientTests.testGetVsEKK LL   LL    nc *+227;N 6 OOodll.?.?-@ M N i  Q r0cRfd}jd}|j|S)zQ Test that 'get' works correctly when given wildcard parameters. cjjjdtddjjjdtddy)NtestRemoveFiletestRemoveFile get failedtestRenameFiletestRenameFile get failed)rr]rr)rr-s r.rz;OurServerCmdLineClientTests.testWildcardGet.._checkys_  ! ! ""#34)*+   ! ! ""#34)*+ r0z get testR*)rrrs` r.testWildcardGetz+OurServerCmdLineClientTests.testWildcardGetts'  OOL )}}V$$r0cVdjjjzdzjjjzdzfd}jdjjd}|j ||j fd|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"file2cjjjdjjdj|j j dS)Nr  test"file2zrm "test\"file2")rr]rr3r rrs r. _checkPutz6OurServerCmdLineClientTests.testPut.._checkPuts[  ! ! "";/1C1CL1Q  OOFOON; <??#67 7r0put z/testfile1 "test\"file2"ctjjjdjS)Nr rrs r.r`z5OurServerCmdLineClientTests.testPut..rr0)r] asBytesModerrr)r-r!rr+s` @r.testPutz#OurServerCmdLineClientTests.testPuts ll&&(-- . ll&&(-- .    8 OOd4<<#4#4"55NO P i  Q r0cjjdjd5}|jddddjjdjd5}|jddddfd}j d jj d }|j ||S#1swYxYw#1swYVxYw) zb Check that 'put' uploads files correctly when overwriting a longer file. shorterFilewmodeaN longerFilebbcjjjdjjdy)Nr'r,)rr]r)rr-s r.r!zEOurServerCmdLineClientTests.test_putOverLongerFile.._checkPuts4  ! ! ""=14<<3E3El3S r0r"z/shorterFile longerFile)r]rrrrrr)r-rr!rs` r.test_putOverLongerFilez2OurServerCmdLineClientTests.test_putOverLongerFiles \\   . 3 3 3 =  GGDM  \\   - 2 2 2 <  GGEN   OOd4<<#4#4"55LM N i     sC 2C CC"cjjdjjdjd5}|j ddddjjdjd5}|j ddddfd}j d jj d }|j||S#1swYxYw#1swYWxYw) z Check that 'put' uploads files correctly when overwriting a longer file and you use a wildcard to specify the files to upload. dirrr(r)r+Nr-czjjdjjdy)Nr)rrr])rr-someDirs r.r!zMOurServerCmdLineClientTests.test_putMultipleOverLongerFile.._checkPuts+  ! !'--"79K9KF9S Tr0r"z/dir/*)r]rcreateDirectoryrrrrr)r-rr!rr3s` @r.test_putMultipleOverLongerFilez:OurServerCmdLineClientTests.test_putMultipleOverLongerFiles ,,$$U+! ]]6 " ' 'S ' 1 Q GGDM  \\   ' , ,# , 6 ! GGEN  U OOd4<<#4#4"5V< = i     sC0C<0C9<Dcfd}jddjjddjjz}|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. cj|ddj|ddjjjdjj jddjjjdjj jddy)Nrr0rrrrr)r;rr]rrPrs r.checkz:OurServerCmdLineClientTests.testWildcardPut..checks   WQZ -   WQZ -  ! ! ""#34 ##%++,<=+   ! ! ""#34 ##%++,<=+ r0rr"z/testR*zcd %s)rr]rr<r)r-r8rs` r.testWildcardPutz+OurServerCmdLineClientTests.testWildcardPutsZ  NN 4<<$$%W - dll++- -  er0cfd}jdd}|j||jjd|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. cjj|ddj|djddj dS)Nrr0rlz link failedz rm testLink)rr;r3ryrrs r.rz4OurServerCmdLineClientTests.testLink.._checksO  " " $   WQZ - OOGAJ11$7 G??=1 1r0zln testLink testfile1zls -l testLinkr0rrr;rs` r.testLinkz$OurServerCmdLineClientTests.testLinksA  2 NN24D E f d&&,r0cfd}jdd}|j||jjd|S)zV Test that we can create and remove directories with the cftp client. cj|ddj|djdjdS)Nrr0rdzrmdir testMakeDirectory)r;r3ryrrs r.rz?OurServerCmdLineClientTests.testRemoteDirectory.._checksB   WQZ - OOGAJ11$7 8??#<= =r0mkdir testMakeDirectoryzls -l testMakeDirector?r0r=rs` r.testRemoteDirectoryz/OurServerCmdLineClientTests.testRemoteDirectorysA  > NN46O P f d&&,r0cXfd}jdd}|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. cZj|ddj|ddy)Nrr0rsremote error 11: mkdir failedrrs r.rzHOurServerCmdLineClientTests.test_existingRemoteDirectory.._checks,   WQZ -   WQZ)I Jr0rBrrs` r.test_existingRemoteDirectoryz8OurServerCmdLineClientTests.test_existingRemoteDirectory s.  K NN46O P fr0cjdjjd}|jjd|jfd|jjd|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. zlmkdir z/testLocalDirectoryr0c&jdS)Nzrmdir testLocalDirectory)rrs r.r`z@OurServerCmdLineClientTests.testLocalDirectory.. s0J Kr0)rr]rrr;rs` r.testLocalDirectoryz.OurServerCmdLineClientTests.testLocalDirectorysb OOgdll&7&7%88KL M d&&, KL d&&,r0cfd}jdd}|j||jjd|S)z1 Test that we can rename a file. czj|ddj|ddjdS)Nrr0rs testfile2zrename testfile2 testfile1)r;rrs r.rz6OurServerCmdLineClientTests.testRename.._check)s;   WQZ -   WQZ 6??#?@ @r0zrename testfile1 testfile2z ls testfile?r0r=rs` r. testRenamez&OurServerCmdLineClientTests.testRename$sA  A NN7 H f d&&,r0r')rArBrCrDr/rrrrrrrrrrrr%r/r5r9r>rCrFrIrLrEr0r.rrsr(T  884%,%> F<%(8((<"    r0rc4eZdZdZdZdZdZdZdZdZ y) OurServerBatchFileTestszm Functional tests which launch a SFTP server over localhost and checks csftp in batch interface. cNtj||jyr'rr/rr,s r.r/zOurServerBatchFileTests.setUp;s  & r0cLtj||jSr')rrrr,s r.rz OurServerBatchFileTests.tearDown?s##D)  r0c|jtd5}|j|ddd|jj j }d|fz}t j|jddd}tjdtjd|tjj}tj j#tj$|d<d|jj&_t+tj|| }fd }|j-d |j/||S#1swY5xYw) 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.1rrrrrrrc2tj|Sr')rPr)resfns r._cleanupz9OurServerBatchFileTests._getBatchOutput.._cleanupZs IIbMJr0c |dS)NrrE)rTs r.r`z9OurServerBatchFileTests._getBatchOutput..^s #a&r0)rrrrrrr rr!rrsrrrPrQrrr;rrrrraddBoth) r-rfprrrrrVrUs @r._getBatchOutputz'OurServerBatchFileTests._getBatchOutputCs [[] "c] b HHQK {{""$)) !2J##DJJLf=abA (3>>*!D623jjooJJOOCHH5L56 2 $S^^Ts C  () (9  s E##E-cZd}fd}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|jd}tjdt|zj j j j|dj|ddgdy)NrrzRES %srrr) r!rrsreprassertInr]r$rr;rTr-s r._cbCheckResultz=OurServerBatchFileTests.testBatchFile.._cbCheckResultmse))E"C GGHtCy( ) MM$,,224993q6 B   Ab V r0rZrr-rrars` r. testBatchFilez%OurServerBatchFileTests.testBatchFilecs2      & n%r0cZd}fd}j|}|j||S)zO Test that an error in the batch file stops running the batch. zchown 0 missingFile pwd exit cnjjjj|yr') assertNotInr]r$rr`s r.raz9OurServerBatchFileTests.testError.._cbCheckResults&   T\\557<._cbCheckResults$ MM$,,224993 ?r0rbrcs` r.testIgnoredErrorz(OurServerBatchFileTests.testIgnoredErrors3   @   & n%r0N) rArBrCrDr/rrZrdrhrkrEr0r.rNrN4s& !@. r0rNsshz$no ssh command-line client availablesftpz%no sftp command-line client availablec"eZdZdZdZdZdZy)OurServerSftpClientTestsz@ Test the sftp server against sftp command line client. cLtj||jSr'rPr,s r.r/zOurServerSftpClientTests.setUps  &!!r0c"|jSr')rr,s r.rz!OurServerSftpClientTests.tearDowns  r0c4 ttjjt d5}|j ddddj jj tjfd}jtd|dj j_ tdd} fd }fd }|j||jfd |j|S#1swYxYw) 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)Nrext_foorE)r-sr oldGetAttrs r. _getAttrszCOurServerSftpClientTests.test_extendedAttributes.._getAttrsstQ'E$E) Lr0rwTrl)-oPubkeyAcceptedKeyTypes=ssh-dssz-VcH|dk(rd}nd}|dddddddd dd fzd d f z }|S) Nr)rxryrEz-Fz /dev/nullrxzIdentityFile=dsa_testzUserKnownHostsFile=kh_testzHostKeyAlgorithms=ssh-rsazPort=%iz-bztestuser@127.0.0.1rE)statusargsrUrs r.hasPAKTzAOurServerSftpClientTests.test_extendedAttributes..hasPAKTsZ{? ',+TG#$ DKr0cj|dd|djddD]}j||dy)Nrrrasciir)r;r r_)rir-s r.r8z?OurServerSftpClientTests.test_extendedAttributes..checksM   VAY6!9+;+;G+D E ,  a+  ,r0ctd|S)Nrm)r)r|rs r.r`zBOurServerSftpClientTests.test_extendedAttributes..s#;FD##Nr0)dictrPrQrrrrrrr#rwrTrrrr) r-rrwrr}r8rrUrvrs ` @@@@r.test_extendedAttributesz0OurServerSftpClientTests.test_extendedAttributess2:: [[] "c] "a GGL ! "{{""$)).88   ,k9E59 2 E#QSV W 2 , g NO}}U##s " "s DDN)rArBrCrDr/rrrEr0r.roros"!F$r0ro)RrDrrsrVrPrrrMiorrunittestrzope.interfacer twisted.conchrtwisted.conch.interfacesr$twisted.conch.test.test_filetransferr r twisted.credr twisted.internetr r rrrtwisted.internet.taskrtwisted.internet.testingrtwisted.internet.utilsrrtwisted.pythonrtwisted.python.fakepwdrtwisted.python.filepathrtwisted.python.procutilsrtwisted.python.reflectrtwisted.trial.unittestrrunixtwisted.conch.scriptsrtwisted.conch.scripts.cftprtwisted.conch.sshrtwisted.conch.ssh.connectionrtwisted.conch.testr r!twisted.conch.test.test_conchr"r# ImportError skipTestsIReactorProcessr%rGrrrrrr[ProcessProtocolrfrrrNrorEr0r.rs=   %&.UHH'4L/,*0+^, )*  .92E;;R  D, : : :7D I JJI ?@$ h$ A$ N_ 8_ D   #.#.L996 Y/&/&/&d ?@p xp Ap f ..xh..xv$+$+N ?@K"4KAK\  ?@d0dAdN ?@E%L@AE&MBCR$1R$DBAR$_+    s&,G22G;:G;