ϪfdZddlZddlZddlZddlZddlZddlmZddlm Z ddl m Z ddl m Z mZmZddlmZddlmZdd lmZmZmZmZmZdd lmZdd lmZmZmZdd l m!Z!m"Z"m#Z#dd l$m%Z%ddl&m'Z'e#jPjSsdZ*ndZ*GddejVZ,GddejZZ.dSdZ/Gdde'Z0Gdde0Z1Gdde0Z2Gdde0Z3Gdde0Z4Gdd e4Z5Gd!d"e'Z6Gd#d$e'Z7Gd%d&ejZZ8Gd'd(ejrZ:Gd)d*e'Z;Gd+d,e'Z<Gd-d.e'Z=Gd/d0e'Z>Gd1d2e'Z?Gd3d4e'Z@Gd5d6e'ZAGd7d8e'ZBGd9d:e'ZCGd;de'ZEGd?d@ZFGdAdBe'eFZGe eGdCdDZHGdEdFZIGdGdHZJGdIdJe'eJZKe ejGdKdLZMGdMdNZNGdOdPe'ZOGdQdRe'ZPy)Tz FTP tests. N)BytesIO) implementer) verifyClass)checkers credentialsportal)UnauthorizedLogin)IRealm)defererrorprotocolreactortask) IConsumer)basicftploopback)failurefilepathruntime) proto_helpers)TestCasezCannot run on Windowsc.eZdZdZdZdZdZdZdZy)DummyNc g|_g|_yN)linesrawDataselfs 7/usr/lib/python3/dist-packages/twisted/test/test_ftp.py__init__zDummy.__init__%s  c&|j|_yr)factoryfrs r!connectionMadezDummy.connectionMade)s r#c:|jj|yr)rappendr lines r! lineReceivedzDummy.lineReceived, $r#c:|jj|yr)rr)r datas r!rawDataReceivedzDummy.rawDataReceived/s D!r#cyrr*s r!lineLengthExceededzDummy.lineLengthExceeded2s r#) __name__ __module__ __qualname__lognamer"r'r,r1r4r3r#r!rr"s G " r#rceZdZdZdZdZy)_BufferingProtocolcDd|_tj|_yNr#)bufferr Deferreddrs r!r'z!_BufferingProtocol.connectionMade7s !r#c.|xj|z c_yrr=r/s r! dataReceivedz_BufferingProtocol.dataReceived;s t r#c:|jj|yr)r?callback)r reasons r!connectionLostz!_BufferingProtocol.connectionLost>s r#N)r5r6r7r'rBrFr3r#r!r:r:6s"r#r:cldtj||d}|j|jS)z Construct a passive mode message with the correct encoding @param protocol: the FTP protocol from which to base the encoding @param host: the hostname @param port: the port @return: the passive mode message z227 Entering Passive Mode (z).)rencodeHostPortencode _encoding)r hostportmsgs r!passivemode_msgrNBs5 ((:(:4(F'Gr JC ::h(( ))r#cNeZdZdZej ZdZdZd dZ d dZ dZ dZ y) FTPServerTestCasezw Simple tests for an FTP server with the default settings. @ivar clientFactory: class used as ftp client. anonymousc g j_tjjt j j_tjtjjj}|jtjtjtj }d_d_|j'j"j$|j|tj(tj*|j,_t1j2dj.dx_}j7|j8j.j: t=j> fd}|j._|jAj4}tCjDt0jF}|jId|} fd }|jK|j7tLjNt0 t=jP |gS) N) anonymousRootuserHomez test-userz test-password)r userAnonymousr 127.0.0.1 interfacecj`|}|j_fd}j |j dj ||S)Nc|jj%jjjyyrserverProtocol transportloseConnectionrsr! cleanupServerzQFTPServerTestCase.setUp.._rememberProtocolInstance..cleanupServers2&&00<''11@@B=r#)r% buildProtocolwrappedProtocolr\ addCleanuprDr))addrr r_r`d1 protocolsr s r!_rememberProtocolInstancez:FTPServerTestCase.setUp.._rememberProtocolInstance{sX *$T*H"*":":D  C OOM * KK    X &Or#c|_jjjjj jyr)clientrbr]r^r))rhrer s r! gotClientz*FTPServerTestCase.setUp..gotClients8 DK OODKK11@@ A   T[[ )r#))mktemp directoryosmkdirrFilePathdirPathrPortalrFTPRealmregisterCheckerrAllowAnonymousAccessr IAnonymous'InMemoryUsernamePasswordDatabaseDontUseusernamepasswordaddUserIUsernamePassword FTPFactoryrUr%r listenTCPrLrb stopListeningr`r r>getHostr ClientCreator clientFactory connectTCP addCallbackrwaitUntilAllDisconnected gatherResults) r p users_checkerrLrfportNum clientCreatord2rir`rdres ` @@@r!setUpzFTPServerTestCase.setUpYs   ((8  MM LL"nn   (779;;Q;QR HHJ # ' dmmT]]; -)F)FG~~Qd>P>PQ ",,Q TT D **+ 22 ^^   &? ",,.%% ..w8J8JK  % %k7 ; * y!  >>S""B8,,r#Ncf|tjd}fd}|j|S)z Asserts that a sending an FTP command receives the expected response. Returns a Deferred. Optionally accepts a deferred to chain its actions to. Nchjj}fd}|j|S)Nc*j|yr assertEqual) responseLinesexpectedResponseLinesr s r! gotResponsezRFTPServerTestCase.assertCommandResponse..queueCommand..gotResponses  !6 Fr#rhqueueStringCommandr)ignoredr?rcommandrr s r! queueCommandz=FTPServerTestCase.assertCommandResponse..queueCommands. ..w7A G==- -r#)r succeedr)r rr chainDeferredrs``` r!assertCommandResponsez'FTPServerTestCase.assertCommandResponses1  !MM$/M .((66r#c|tjd}fd}|j|j|tj fd}|j|S)Nc:jjSrrhr)rrr s r!rz;FTPServerTestCase.assertCommandFailed..queueCommands;;11': :r#cJ j|jdyyNrrargs) exceptionexpectedResponser s r!failedz5FTPServerTestCase.assertCommandFailed..faileds(+  !19>>!3DE,r#)r rr assertFailurer CommandFailed)r rrrrrs``` r!assertCommandFailedz%FTPServerTestCase.assertCommandFaileds[  !MM$/M ; !!,/ =#*;*;< F((00r#cR|jddg}|jddg|S)NUSER anonymous8331 Guest login ok, type your email address as password.PASS test@twistedmatrix.com2230 Anonymous login ok, access restrictions apply.rrr r?s r!_anonymousLoginz!FTPServerTestCase._anonymousLoginsA  & &  G H )) ) A B*  r#c|jd|jzd|jzg}|jd|jzdg|S)zx Authenticates the FTP client using the test account. @return: L{Deferred} of command response zUSER %sz331 Password required for %s.zPASS %sz230 User logged in, proceedr)rrvrwrs r! _userLoginzFTPServerTestCase._userLogins^  & &  ' , > ? ))  ' * +*  r#r)NN) r5r6r7__doc__rFTPClientBasicrrUrrrrrr3r#r!rPrPOs4 &&MMA-F7*1   r#rPceZdZdZdZdZy)FTPAnonymousTestsz Simple tests for an FTP server with different anonymous username. The new anonymous username used in this test case is "guest" guestcR|jddg}|jddg|S)a Tests whether the changing of the anonymous username is working or not. The FTP server should not comply about the need of password for the username 'guest', letting it login as anonymous asking just an email address as password. z USER guestrrrrrrs r!test_anonymousLoginz%FTPAnonymousTests.test_anonymousLoginsC  & & UV )) ) A B*  r#N)r5r6r7rrUrr3r#r!rrs M r#rceZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZy)BasicFTPServerTestsz, Basic functionality of FTP server. cdj_tjtt }|j djjj}|jd}|jfd}|S)zn When the connection limit is reached, the server should send an appropriate response rVc|jSr)r?)protos r!riz>BasicFTPServerTests.test_tooManyConnections..gotClients 77Nr#c>jd|jy)Ns;421 Too many users right now, try again in a few minutes. rr=)rr s r!onConnectionLostzEBasicFTPServerTests.test_tooManyConnections..onConnectionLosts   T  r#) r%connectionLimitr r~rr:rrLr}r)r ccr?rirs` r!test_tooManyConnectionsz+BasicFTPServerTests.test_tooManyConnectionss| () $  # #G-? @ MM+tyy'8'8':'?'? @         r#cgd}dg}fd}fd}g}|D]`}jj|}j|tj|j |||j |b|D]@}jj|}|j |||j |Btj|dS)z When not logged in, most commands other than USER and PASS should get NOT_LOGGED_IN errors, but some can be called before USER and PASS. ) CDUPCWDLISTMODEPASVPWDRETRSTRUSYSTTYPEFEATc||jd}j|djd|d|dy)Nr530z# - Response didn't start with 530: )r assertTrue startswith)rrfailureResponseLinesr s r!checkFailResponsezDBasicFTPServerTests.test_NotLoggedInReply..checkFailResponse%sC#,>>!#4 OO$R(33E:(, r#c\|d}j|jd|d|y)Nrrz - Response start with 530: ) assertFalser)resultrr s r!checkPassResponsezDBasicFTPServerTests.test_NotLoggedInReply..checkPassResponse0s5AYF   !!%( r#TfireOnOneErrback) rhrrrrrr)r DeferredList)r loginRequiredCommandListloginNotRequiredCommandListrr deferredsrdeferreds` r!test_NotLoggedInReplyz)BasicFTPServerTests.test_NotLoggedInReplys $  (.h#   / 'G{{55g>H   x):): ;  !2G <   X &  ' 3 'G{{55g>H  !2G <   X & ' !!)dCCr#c(|jddgS)z@ Issuing PASS before USER should give an error. zPASS fooz=503 Incorrect sequence of commands: USER required before PASSrrs r!test_PASSBeforeUSERz'BasicFTPServerTests.test_PASSBeforeUSERIs ''  O P  r#c(|jddgS)zD Issuing USER without a username is a syntax error. USERz,500 Syntax error: USER requires an argument.rrs r!test_NoParamsForUSERz(BasicFTPServerTests.test_NoParamsForUSERRs '' CD  r#cb|jjd}|jddg|S)zD Issuing PASS without a password is a syntax error. USER fooPASSz,500 Syntax error: PASS requires an argument.r)rhrrrs r!test_NoParamsForPASSz(BasicFTPServerTests.test_NoParamsForPASSZs< KK * *: 6'' CDTU(  r#cd}|jj_jj d}j ddg||j fd}|S)zI Unexpected exceptions from the login handler are caught c>tjtdS)Nztest exceptionr failAssertionError)rkwargss r!_fake_loginhandlerz?BasicFTPServerTests.test_loginError.._fake_loginhandlerhs::n-=>? ?r#rzPASS barz5550 Requested action not taken: internal server errorrcj}jdt|j|djt y)NrrflushLoggedErrorsrlenassertIsInstancevaluerrlogsr s r! checkLogsz6BasicFTPServerTests.test_loginError..checkLogsss=))+D   QD *  ! !$q'-- @r#)r\rloginrhrrr)r rr?rs` r!test_loginErrorz#BasicFTPServerTests.test_loginErrorcss  @,>""( KK * *: 6    D E !  A  A r#c"|jS)z/ Login with userid 'anonymous' )rrs r!test_AnonymousLoginz'BasicFTPServerTests.test_AnonymousLogin{s##%%r#cL|j}|jddg|S)zm Issuing QUIT should return a 221 message. @return: L{Deferred} of command response QUITz 221 Goodbye.rrrrs r! test_QuitzBasicFTPServerTests.test_Quits.  "))&>2BRS)TTr#c2d|j_tj}|jjj |t j|jddg}|jddg|}|jddg|}|S) z Reconfigure the server to disallow anonymous access, and to have an IUsernamePassword checker that always rejects. @return: L{Deferred} of command response Frz$331 Password required for anonymous.rz!530 Sorry, Authentication failed.rrz$530 Please login with USER and PASS.) r%allowAnonymousrrurrrrryrr)r denyAlwaysCheckerr?s r!test_AnonymousLoginDeniedz-BasicFTPServerTests.test_AnonymousLoginDenieds', #$LLN ++ {<<  & & EF   $ $ ) 0 1 %   $ $ :;1 % r#cL|j}|jddg|S)z When an anonymous user attempts to edit the server-side filesystem, they will receive a 550 error with a descriptive message. @return: L{Deferred} of command response z MKD newdirz:550 Anonymous users are forbidden to change the filesystemrrrrs r!test_anonymousWriteDeniedz-BasicFTPServerTests.test_anonymousWriteDenieds6  "''  I J(  r#cL|j}|jddg|S)z\ Send an invalid command. @return: L{Deferred} of command response GIBBERISHz'502 Command 'GIBBERISH' not implementedrr rs r!test_UnknownCommandz'BasicFTPServerTests.test_UnknownCommands6  "'' CDTU(  r#cL|j}|jddg|S)zb Send RETR before sending PORT. @return: L{Deferred} of command response RETR foozE503 Incorrect sequence of commands: PORT or PASV required before RETRrr rs r!test_RETRBeforePORTz'BasicFTPServerTests.test_RETRBeforePORT<  "'' 4  (  r#cL|j}|jddg|S)zb Send STOR before sending PORT. @return: L{Deferred} of command response zSTOR foozE503 Incorrect sequence of commands: PORT or PASV required before STORrr rs r!test_STORBeforePORTz'BasicFTPServerTests.test_STORBeforePORTrr#cz|j}|jddg||jddg||S)zd Send command with bad arguments. @return: L{Deferred} of command response zMODE zz&504 Not implemented for parameter 'z'.rzSTRU Iz&504 Not implemented for parameter 'I'.r rs r!test_BadCommandArgsz'BasicFTPServerTests.test_BadCommandArgssY  "   ?@PQ !    ?@PQ ! r#c,|jtjddtd}tdD]V}t |}d||<dj t t|}|jttj|Xy)z% Decode a host port. z25,234,129,22,100,23)z 25.234.129.22id,N) rrdecodeHostPortrangelistjoinmapstr assertRaises ValueError)r numsibadValuess r!test_DecodeHostPortz'BasicFTPServerTests.test_DecodeHostPorts    5 68P Qxq AADzHHQKS(+,A   j#*<*z/BasicFTPServerTests.test_PASV..s > >v Fr#ctj|ddd\}}j|jjj j y)z Extract the host and port from the resonse, and verify the server is listening of the port it claims to be. rN)rrrr\dtpPortr}rL)rrKrLr s r!cbz)BasicFTPServerTests.test_PASV..cb sP ++M",=ab,ABJD$   T4#6#6#>#>#F#F#H#M#M Nr#cLjjjSrr[r+s r!r-z/BasicFTPServerTests.test_PASV..s 3 3 = = L L Nr#rrr r?r1s` r! test_PASVzBasicFTPServerTests.test_PASVsF  " FG O b NOr#cP|j}|jddg||S)z? SYST command will always return UNIX Type: L8 rz215 UNIX Type: L8rrrs r! test_SYSTzBasicFTPServerTests.test_SYSTs1  " ""6,?+@PQ"Rr#cjjjjjjjjdj j }j ddg|j ddg|fd}|j||S)z Sending the RNFR command followed by RNTO, with valid filenames, will perform a successful rename operation. fooRNFR foo6350 Requested file action pending further information.rzRNTO bar&250 Requested File Action Completed OKcjjjjjdj |SNbar)rrochildrvexistsrr s r! check_renamez:BasicFTPServerTests.test_RNFRandRNTO..check_rename1s; OODLL..t}}=CCEJQQS TMr#)ror@rvcreateDirectorytouchrrr)r r?rCs` r!test_RNFRandRNTOz$BasicFTPServerTests.test_RNFRandRNTOs 4==)99; 4==)//6<<> OO  ""  E F # "" ABRS #   l#r#cz|j}|jddg||jddg||S)z Sending the RNFR command followed by any command other than RNTO should return an error informing users that RNFR should be followed by RNTO. r:r;rzOTHER don-tcarez<503 Incorrect sequence of commands: RNTO required after RNFR)rrrrs r!test_RNFRwithoutRNTOz(BasicFTPServerTests.test_RNFRwithoutRNTO8sY  " ""  E F #    K L ! r#cd}||j_|jt|jjt j y)z Exceptions other than L{error.CannotListenError} which are raised by C{listenFactory} should be raised to the caller of L{FTP.getDTPPort}. ctr) RuntimeError portNumberr%s r! listenFactoryzEBasicFTPServerTests.test_portRangeForwardError..listenFactoryQs . r#N)r\rNr"rK getDTPPortr Factory)r rNs r!test_portRangeForwardErrorz.BasicFTPServerTests.test_portRangeForwardErrorKsA  !-:)  $--88(:J:J:L r#c"d}||j_|jjtj}|j |dt dd|j_|jjtj}|j |dt dd|j_|jtj|jjtjy)a3 L{FTP.passivePortRange} should determine the ports which L{FTP.getDTPPort} attempts to bind. If no port from that iterator can be bound, L{error.CannotListenError} should be raised, otherwise the first successful result from L{FTP.listenFactory} should be returned. c<|dvrtjd|d|S)N)ViViV localhostr )r CannotListenErrorrLs r!rNz9BasicFTPServerTests.test_portRange..listenFactorybs&22--k:wOO r#rrTiiVN) r\rNrOr rPrrpassivePortRanger"r rV)r rNrLs r!test_portRangez"BasicFTPServerTests.test_portRangeZs  -:)""--h.>.>.@A q!/4UE/B,""--h.>.>.@A u%/4UE/B,   # #T%8%8%C%CXEUEUEW r#ctdd}||j_|jjd}|j ||j jy)z The L{FTP} instances created by L{ftp.FTPFactory.buildProtocol} have their C{passivePortRange} attribute set to the same object the factory's C{passivePortRange} attribute is set to. iiN)rr%rWr`rra)r portRanger s r!"test_portRangeInheritedFromFactoryz6BasicFTPServerTests.test_portRangeInheritedFromFactoryusL $% (1 %<<--d3 H$<$<$M$MNr#cfjjd}fd}|j|S)z When the server receives 'FEAT', it should report the list of supported features. (Additionally, ensure that the server reports various particular features that are supported by all Twisted FTP servers.) rcjd|djd|jd|jd|jd|jd|dy) Nz 211-Features:rz MDTMz PASVz TYPE A;Iz SIZEz211 Endr)rassertIn)rr s r!rz2BasicFTPServerTests.test_FEAT..gotResponsese   _mA.> ? MM'= 1 MM'= 1 MM+} 5 MM'= 1   Y b(9 :r#r)r r?rs` r! test_FEATzBasicFTPServerTests.test_FEATs/ KK * *6 2 ;}}[))r#cP|j}|jddg||S)z When the server receives 'OPTS something', it should report that the FTP server does not support the option called 'something'. zOPTS somethingz'502 Option 'something' not implemented.rr rs r! test_OPTSzBasicFTPServerTests.test_OPTSs8  "    6 7 ! r#cjjjjjjjjdjj }fd}fd}|j ||j |j ddg||S)zl Any FTP error raised inside STOR while opening the file is returned to the client. folderc:jjdS)zE Send the PASV command required before port. rrrBs r!sendPASVzCBasicFTPServerTests.test_STORreturnsErrorFromOpen..sendPASVs;;11&9 9r#cjjjjdt j_|S)z Fake an incoming connection and create a mock DTPInstance so that PORT command will start processing the request. N)r\ dtpFactoryrrDobject dtpInstancerBs r!mockDTPInstancezJBasicFTPServerTests.test_STORreturnsErrorFromOpen..mockDTPInstances:    * * 3 3 < .failingOpenForWritings::n./ /r#c:jjdS)z Send the PASV command required before port. @param result: parameter used in L{Deferred} rrrBs r!rezNBasicFTPServerTests.test_STORunknownErrorBecomesFileNotFound..sendPASVs ;;11&9 9r#cjjjjdt j_jj _|S)z Fake an incoming connection and create a mock DTPInstance so that PORT command will start processing the request. @param result: parameter used in L{Deferred} N)r\rgrrDrhrishellopenForWriting)rror s r!rjzUBasicFTPServerTests.test_STORunknownErrorBecomesFileNotFound..mockDTPInstancesN    * * 3 3 < .checkLogss? ))+D   QD *  ! !$q'-- @r#zSTOR somethingz)550 something: No such file or directory.r)rrr)r r?rerjrros` @r!(test_STORunknownErrorBecomesFileNotFoundz       A.4&   6 O*$ "H:r#rc@eZdZdZej ZdZdZdZ dZ y)FTPServerAdvancedClientTestsz: Test FTP server with the L{ftp.FTPClient} class. cfd}jjd\}}|j|tj||gS)zl Try to make an STOR as anonymous, and check that we got a permission denied error. c|jtjj|jj dddy)Nrz550 foo: Permission denied.)traprrrrrresr s r!ebz;FTPServerAdvancedClientTests.test_anonymousSTOR..eb s8 HHS&& '   SYY^^A.q13P Qr#r9)rh storeFile addErrbackr r)r r}rdrs` r!test_anonymousSTORz/FTPServerAdvancedClientTests.test_anonymousSTORsD  R&&u-B b""B8,,r#cGddtjfd}jtjd|fd}jj d\}}|j |tj||gS)zm Any FTP error raised by STOR while transferring the file is returned to the client. ceZdZdZy)XFTPServerAdvancedClientTests.test_STORtransferErrorIsReturned..FailingFileWritercRtjtjdS)N failing_filer rrIsADirectoryErrorrs r!receivez`FTPServerAdvancedClientTests.test_STORtransferErrorIsReturned..FailingFileWriter.receiveszz#"7"7"GHHr#Nr5r6r7rr3r#r!FailingFileWriterrs Ir#rc:tjdSrr rabrs r! failingSTORzRFTPServerAdvancedClientTests.test_STORtransferErrorIsReturned..failingSTOR ==!24!89 9r#rscL|jtjj}j dt |j |djtjj |jjdddy)Nrrz 550 failing_file: is a directory) rzrrrrrrrrrr|rr s r!r}zIFTPServerAdvancedClientTests.test_STORtransferErrorIsReturned..eb'sx HHS&& '))+D   QD *  ! !$q'--1F1F G   SYY^^A.q13U Vr#r r _FileWriterpatchFTPAnonymousShellrhr~rr rr rr}rdrrs` @r! test_STORtransferErrorIsReturnedz=FTPServerAdvancedClientTests.test_STORtransferErrorIsReturnedst I I : 3((*:KH W&&~6B b""B8,,r#cGddtjfd}jtjd|fd}jj d\}}|j |tj||gS)z Any non FTP error raised by STOR while transferring the file is converted into a critical error and transfer is closed. The unknown error is logged. ceZdZdZy)aFTPServerAdvancedClientTests.test_STORunknownTransferErrorBecomesAbort..FailingFileWriterc<tjtSrrrs r!rziFTPServerAdvancedClientTests.test_STORunknownTransferErrorBecomesAbort..FailingFileWriter.receive;szz."233r#Nrr3r#r!rr:s 4r#rc:tjdSrrrs r!rz[FTPServerAdvancedClientTests.test_STORunknownTransferErrorBecomesAbort..failingSTOR>rr#rsc8|jtjj}j dt |j |djtj |jjdddy)Nrrz.426 Transfer aborted. Data connection closed.) rzrrrrrrrrrrs r!r}zRFTPServerAdvancedClientTests.test_STORunknownTransferErrorBecomesAbort..ebEsu HHS&& '))+D   QD *  ! !$q'-- @    q!!$&V r#rrrs` @r!)test_STORunknownTransferErrorBecomesAbortzFFTPServerAdvancedClientTests.test_STORunknownTransferErrorBecomesAbort2sq 4 4 : 3((*:KH &&~6B b""B8,,r#cGddtjfd}jtjd|fd}t }j j d|}|j||S)zj Any errors during reading a file inside a RETR should be returned to the client. ceZdZdZy)JFTPServerAdvancedClientTests.test_RETRreadError..FailingFileReadercRtjtjdS)Nblahr)r consumers r!sendzOFTPServerAdvancedClientTests.test_RETRreadError..FailingFileReader.sendZszz#"7"7"?@@r#N)r5r6r7rr3r#r!FailingFileReaderrYs Ar#rc:tjdSrr)rrrs r! failingRETRzDFTPServerAdvancedClientTests.test_RETRreadError..failingRETR]rr#openForReadingcj|jtjj |j j dddj |j j dddy)Nrz3125 Data connection already open, starting transferrz550 blah: is a directory)rrzrrrrr)rr s r!check_responsezGFTPServerAdvancedClientTests.test_RETRreadError..check_responsedsr  " " $ GLL** +    ""1%a(E    W]]//2157Q Rr#r)r _FileReaderrrr:rh retrieveFiler)r rrrr?rs` @r!test_RETRreadErrorz/FTPServerAdvancedClientTests.test_RETRreadErrorRsj A A : 3((*:KH S#$ KK $ $^U ; ^$r#N) r5r6r7rr FTPClientrrrrrr3r#r!rwrws'MMM --:-@r#rwcneZdZdZddZddZdZdZdZdZ d Z d Z d Z d Z d ZdZdZdZdZy) FTPServerPasvDataConnectionTestsz PASV data connection. Nc`|jjd}d}|j|S)z Establish a passive data connection (i.e. client connecting to server). @param ignored: ignored @return: L{Deferred.addCallback} rctj|ddd\}}tjtt }|j d|S)Nrr/rV)rrr r~rr:r)rrKrLrs r!gotPASVzEFTPServerPasvDataConnectionTests._makeDataConnection..gotPASVsF++M",=ab,ABJD$''1CDB==d3 3r#r)r rr?rs r!_makeDataConnectionz4FTPServerPasvDataConnectionTests._makeDataConnectionxs. KK * *6 2 4 }}W%%r#c|tjd}|jjfd}|j|d}|j|S)z Download file. @param command: command to run @param chainDeferred: L{Deferred} used to queue commands. @return: L{Deferred} of command response Ncjj}|j}tj||gSr)rhrr?r r) downloaderrdrrr s r!rz@FTPServerPasvDataConnectionTests._download..queueCommands7//8BB&&Bx0 0r#c$|\}}|jSrrA)rrrs r! downloadDonez@FTPServerPasvDataConnectionTests._download..downloadDones$* !Wj$$ $r#)r rrr)r rrrrs`` r! _downloadz*FTPServerPasvDataConnectionTests._downloadsZ  !MM$/M!!$":":; 1 !!,/ %((66r#cvj}jd|fd}|j|S)zM When listing empty folders, LIST returns an empty response. rrc*jd|yr<rrBs r! checkEmptyzCFTPServerPasvDataConnectionTests.test_LISTEmpty..checkEmptys   S& )r#rrr)r r?rs` r!test_LISTEmptyz/FTPServerPasvDataConnectionTests.test_LISTEmptys;  " vQ/ *}}Z((r#cjtjtjjjdtjtjjjdj }j d|fd}|j|S)z} LIST ignores requests for folder with names like '-al' and will list the content of current folder. r9r?zLIST -aLrcg}|jD]%}|j|jdd'jdt |j d|j d|y)N rfoobar) splitlinesr)splitrrr^)downloadnamesr+r s r! checkDownloadzOFTPServerPasvDataConnectionTests.test_LISTWithBinLsFlags..checkDownloadsjE ++- 3 TZZ-b12 3   QE + MM&% ( MM&% (r#rlrmpathrrkrrrr r?rs` r!test_LISTWithBinLsFlagsz8FTPServerPasvDataConnectionTests.test_LISTWithBinLsFlagssy dnne45 dnne45  " z3 )}}]++r#ctjtjjjdtjtjjjdj }j d|fd}|j|j d|fd}|j|j d|fd }|j|fd }|j|j d|fd }|j|S) z LIST returns all folder's members, each member listed on a separate line and with name and other details. r9r?rrc`jdt|ddjdy)Nr )rrrrr s r!rzLFTPServerPasvDataConnectionTests.test_LISTWithContent..checkDownloads)   QHSbM$7$7$@ A Br#NLST cv|ddjd}|jjddg|y)Nrrrrrsortrr filenamesr s r!rzLFTPServerPasvDataConnectionTests.test_LISTWithContent..checkDownloads8 " ++G4I NN    ff-y 9r#zLIST fooc*jd|yr<rrs r!rzLFTPServerPasvDataConnectionTests.test_LISTWithContent..checkDownload   S( +r#c:jjdS)NzCWD foor)rr s r!chdirzDFTPServerPasvDataConnectionTests.test_LISTWithContent..chdirs;;11)< .checkDownloadrr#r)r r?rrs` r!test_LISTWithContentz5FTPServerPasvDataConnectionTests.test_LISTWithContents dnne45 dnne45  " vQ/ C m$ wa0 : m$ z3 , m$ = e vQ/ ,}}]++r#cj}dfd fd}|j|j|d|fd}|j|S)a5 Exercise handling by the implementation of I{LIST} or I{NLST} of certain return values and types from an L{IFTPShell.list} implementation. This will issue C{command} and assert that if the L{IFTPShell.list} implementation includes C{listOutput} as one of the file entries then the result given to the client is matches C{expectedOutput}. @param command: Either C{b"LIST"} or C{b"NLST"} @type command: L{bytes} @param listOutput: A value suitable to be used as an element of the list returned by L{IFTPShell.list}. Vary the values and types of the contents to exercise different code paths in the server's handling of this result. @param expectedOutput: A line of output to expect as a result of C{listOutput} being transformed into a response to the command issued. @type expectedOutput: L{bytes} @return: A L{Deferred} which fires when the test is done, either with an L{Failure} if the test failed or with a function object if it succeeds. The function object is the function which implements L{IFTPShell.list} (and is useful to make assertions about what warnings might have been emitted). @rtype: L{Deferred} c0tjgSrr)segmentskeys listOutputs r! patchedListzEFTPServerPasvDataConnectionTests._listTestHelper..patchedLists==*. .r#c>jj_|Sr)r\rrr)rrr s r!loggedInzBFTPServerPasvDataConnectionTests._listTestHelper..loggedIn"s-8D   % % *Mr#z somethingrc,j|Srr)rexpectedOutputrr s r!rzGFTPServerPasvDataConnectionTests._listTestHelper..checkDownload*s   ^X 6 r#)r3)rrr)r rrrr?rrrs` `` @r!_listTestHelperz0FTPServerPasvDataConnectionTests._listTestHelpersX<  " /  h '*-Q? }}]++r#c `|jddddtjdddddffdS) z Unicode filenames returned from L{IFTPShell.list} are encoded using UTF-8 before being sent with the response. r my resumérrusergroupLdrwxrwxrwx 0 user group 0 Jan 01 1970 my resumé rr Permissionsrs r!test_LISTUnicodez1FTPServerPasvDataConnectionTests.test_LISTUnicode0sD ## Ax++E2Aq&'J  3   r#c `|jddddtjdddddffdS) z When LIST receive a filename as byte string from L{IFTPShell.list} it will just pass the data to lower level without any change. @return: L{_listTestHelper} r my resumérrrrrrrrs r!test_LISTNonASCIIBytesz7FTPServerPasvDataConnectionTests.test_LISTNonASCIIBytes?sD## #Ax++E2Aq&'J  3   r#clj}tdddD]}ttjj j d|fzd5}|jd|zdddjd|fz| |ffd }|j||S#1swY.checkDownload`s  s8}5r#) rropenrlrrrkwriterr)r r?rfObjrs` r!test_ManyLargeDownloadsz8FTPServerPasvDataConnectionTests.test_ManyLargeDownloadsPs  "&&#. )Dbggll4>>8tg3EFM (QU 4$;' ( NN=D72!N D-1 6 MM- ( ) ( (s B**B3 c0jjdjj}|j j fd}|j |d}|j |fd}|j ||S)zo When RETR is called for a folder, it will fail complaining that the path is a folder. r9cr|jjjjd}|S)Nr)r]r^rhr)rrr s r! retrFolderzHFTPServerPasvDataConnectionTests.test_downloadFolder..retrFolderqs.  / / 1{{55jAHOr#ctd)Nz(Downloading a folder should not succeed.)r)rs r! failOnSuccesszKFTPServerPasvDataConnectionTests.test_downloadFolder..failOnSuccessxs !KL Lr#c|jtjjdg|jj dj }jdt|dy)Nz550 foo: is a directoryrz6No errors should be logged while downloading a folder.)rzrrrrrrr)rcurrent_errorsr s r! checkErrorzHFTPServerPasvDataConnectionTests.test_downloadFolder..checkError}sd GLL** +   78'--:L:LQ:O P!335N   N#H r#)ror@rDrrrr)r r?rrr s` r!test_downloadFolderz4FTPServerPasvDataConnectionTests.test_downloadFolderfs 5!113  " d../  j! M m$  Z r#cj}jjdjjjdj j d|fd}|j |S)zp NLST with no argument returns the directory listing for the current working directory. test.txtr9rrcv|ddjd}|jjddg|y)Nrrrtest.txtrrs r!rzFFTPServerPasvDataConnectionTests.test_NLSTEmpty..checkDownloads8 " ++G4I NN    fk2I >r#)rror@rErDrrrs` r!test_NLSTEmptyz/FTPServerPasvDataConnectionTests.test_NLSTEmptysq  " :&,,. 5!113 wa0 ? }}]++r#cvj}jd|fd}|j|S)zH NLST on a non-existent file/directory returns nothing. zNLST nonexistent.txtrc*jd|yr<rrs r!rzLFTPServerPasvDataConnectionTests.test_NLSTNonexistent..checkDownloadrr#rrs` r!test_NLSTNonexistentz5FTPServerPasvDataConnectionTests.test_NLSTNonexistents:  " -Q? ,}}]++r#c `|jddddtjdddddffdS) zs NLST will receive Unicode filenames for IFTPShell.list, and will encode them using UTF-8. NLSTrrrrrr my resumé rrs r!test_NLSTUnicodez1FTPServerPasvDataConnectionTests.test_NLSTUnicodesD ## Ax++E2Aq&'J  $   r#c `|jddddtjdddddffdS) zJ NLST will just pass the non-Unicode data to lower level. rrrrrrrrrrs r!test_NLSTNonASCIIBytesz7FTPServerPasvDataConnectionTests.test_NLSTNonASCIIBytessD## #Ax++E2Aq&'J  $   r#cj}jjdjj d|fd}|j |S)zN NLST on an existent file returns only the path to that file. rz NLST test.txtrcT|ddjd}jdg|y)Nrrr)rrrs r!rzMFTPServerPasvDataConnectionTests.test_NLSTOnPathToFile..checkDownloads+ " ++G4I   k]I 6r#)rror@rErrrs` r!test_NLSTOnPathToFilez6FTPServerPasvDataConnectionTests.test_NLSTOnPathToFilesV  " :&,,. a8 7}}]++r#r)r5r6r7rrrrrrrrrrr rrrrrr3r#r!rrssU&"78 ),.3,j/,b   ","H,, ,    ,r#rc,eZdZdZddZdZdZdZy) FTPServerPortDataConnectionTestsc:g|_tj|Sr) dataPortsrrrs r!rz&FTPServerPortDataConnectionTests.setUps/55d;;r#NcntjGfddtj}t j d|d}|j j|dtjd|jjz}|jj|S)NceZdZeZfdZy)IFTPServerPortDataConnectionTests._makeDataConnection..DataFactoryctjj||}tjdj ||Sr)r ServerFactoryr`r callLaterrD)r rcrrs r!r`zWFTPServerPortDataConnectionTests._makeDataConnection..DataFactory.buildProtocols8**88tD!!!X%6%6:r#N)r5r6r7r:r r`)rsr! DataFactoryr$s )H r#r(rrVrWPORT )r r>r r&rr{r!r)rrHr}rLrhr)r rr(dataPortcmdrs @r!rz4FTPServerPortDataConnectionTests._makeDataConnections>># (00 $$Q M h'**;8H8H8J8O8OPP &&s+r#c|jDcgc]!}tj|j#}}tjtj |}|j |tj|dScc}w)zS Tear down the connection. @return: L{defer.DeferredList} Tr)r!r maybeDeferredr|rtearDownr)r)r rLlr?s r!r.z)FTPServerPortDataConnectionTests.tearDownsk BF PU !3!3 4 P P    @ I I4 P  !!!d;; Qs&Bcxj}d}|j|fd}|j|S)z Listen on a port, and immediately stop listening as a way to find a port number that is definitely closed. ctjdtjd}|j j |j }|jfd|S)NrrVrWcSrr3)r,rs r!r-z[FTPServerPortDataConnectionTests.test_PORTCannotConnect..loggedIn.. sGr#)rr{r rPr}rLr|r)rrLr?rs @r!rzIFTPServerPortDataConnectionTests.test_PORTCannotConnect..loggedInsQ$$Q(8(8(:kRDlln))G""$A MM+ ,Hr#cXjdtjd|zdgS)Nr)rVz425 Can't open data connection.)rrrH)rr s r! gotPortNumzKFTPServerPortDataConnectionTests.test_PORTCannotConnect..gotPortNums1++#,,['BB23 r#r3)r r?rr4s` r!test_PORTCannotConnectz7FTPServerPortDataConnectionTests.test_PORTCannotConnects<  "  h  }}Z((r#cljjdjjjdjjjdjj}j d|fd}|j |S)zv When Unix shell globbing is used with NLST only files matching the pattern will be returned. rzceva.txtzno.matchz NLST *.txtrcv|ddjd}|jjddg|y)Nrrsceva.txtrrrs r!rzIFTPServerPortDataConnectionTests.test_nlstGlobbing..checkDownload&s8 " ++G4I NN    k;7 Cr#)ror@rErrrrs` r!test_nlstGlobbingz2FTPServerPortDataConnectionTests.test_nlstGlobbings :&,,. :&,,. :&,,.  " |15 D }}]++r#r)r5r6r7rrr.r5r8r3r#r!rrs<& <)6,r#rc:eZdZdZdZdZdZdZdZdZ dZ y ) DTPFactoryTestsz& Tests for L{ftp.DTPFactory}. ctj|_Gdd}||_t j |jd|j|_y)zf Create a fake protocol interpreter and a L{ftp.DTPFactory} instance to test. ceZdZdZy)2DTPFactoryTests.setUp..ProtocolInterpreterNr5r6r7rir3r#r!ProtocolInterpreterr=:Kr#r?N)rClockrprotocolInterpreterr DTPFactoryr%r r?s r!rzDTPFactoryTests.setUp3sF zz|   $7#8 ~~d&>&>dllS r#cg}|j|jjtj}|j |j |jjd|jjd|j||jjd|j||j|jjy)z L{ftp.DTPFactory.setTimeout} uses the reactor passed to its initializer to set up a timed event to time out the DTP setup after the specified number of seconds. rrN) rr%rrPortConnectionErrorrr) setTimeoutradvancerrcallsr finishedr?s r!test_setTimeoutzDTPFactoryTests.test_setTimeout@s   t||44c6M6M N hoo& " Q " Q ! ++,r#c|jjd}|j|tj|j |jjdy)z A L{ftp.DTPFactory} instance's C{buildProtocol} method can be used once to create a L{ftp.DTP} instance. N)r%r`rrDTP assertIsNone)r r s r!test_buildProtocolOncez&DTPFactoryTests.test_buildProtocolOnce]sK <<--d3 h0 $,,44T:;r#c|jjd|jjd|j|jj y)z If a timeout has been set up using L{ftp.DTPFactory.setTimeout}, it is cancelled by L{ftp.DTPFactory.buildProtocol}. N)r%rHr`rrrJrs r!test_timeoutAfterConnectionz+DTPFactoryTests.test_timeoutAfterConnectionhs@ # ""4( ++,r#c.|j|jjtj}|jj d|j jd|j|jjd|S)z If L{ftp.DTPFactory.buildProtocol} is called after the timeout specified by L{ftp.DTPFactory.setTimeout} has elapsed, L{None} is returned. rSN) rr%rrrGrHrrIrPr`rs r!test_connectionAfterTimeoutz+DTPFactoryTests.test_connectionAfterTimeoutrsr   t||44c6M6M N # R  $,,44T:;r#cg}|j|jjtj}|j |j |jjd|j||jjdd|j||jjd|S)a  L{ftp.DTPFactory.deferred} fails with L{PortConnectionError} when L{ftp.DTPFactory.clientConnectionFailed} is called. If the timeout specified with L{ftp.DTPFactory.setTimeout} expires after that, nothing additional happens. rSN) rr%rrrGrr)rHrclientConnectionFailedrrrIrKs r!!test_timeoutAfterConnectionFailedz1DTPFactoryTests.test_timeoutAfterConnectionFaileds   t||44c6M6M N hoo& # " ++D$7 ! R r#c8|j|jjtj}|jj d|j jd|jjdtjd|S)z If L{ftp.DTPFactory.clientConnectionFailed} is called after the timeout specified by L{ftp.DTPFactory.setTimeout} has elapsed, nothing beyond the normal timeout before happens. rSNr9) rr%rrrGrHrrIrXr TimeoutErrorrs r!!test_connectionFailedAfterTimeoutz1DTPFactoryTests.test_connectionFailedAfterTimeoutst   t||44c6M6M N # R  ++D%2D2DU2KLr#N) r5r6r7rrrMrQrTrVrYr\r3r#r!r:r:.s+ T-: <-($r#r:ceZdZdZdZdZy)DTPTestszx Tests for L{ftp.DTP}. The DTP instances in these tests are generated using DTPFactory.buildProtocol() ctj|_Gdd}||_t j |jd|j|_tj|_ y)z Create a fake protocol interpreter, a L{ftp.DTPFactory} instance, and dummy transport to help with tests. ceZdZdZy)+DTPTests.setUp..ProtocolInterpreterNr>r3r#r!r?rar@r#r?N) rrArrBrrCr%r StringTransportWithDisconnectionr]rDs r!rzDTPTests.setUpsV zz|   $7#8 ~~d&>&>dllS &GGIr#c|jjd}|j|jd}|j ||jj }|j |dz|y)zr L{ftp.DTP.sendLine} writes the line passed to it plus a line delimiter to its transport. Ns line contentr)r%r`makeConnectionr]sendLinerr)r ri lineContentdataSents r!test_sendLineNewlinezDTPTests.test_sendLineNewlinesd ll006 ""4>>2% [)>>'') w.9r#N)r5r6r7rrrhr3r#r!r^r^s J :r#r^ceZdZdZdZdZy) PrintLinesz3 Helper class used by FTPFileListingTests. c||_yr)_lines)r rs r!r"zPrintLines.__init__s  r#c|jD]/}|jj|jddz1|jj y)Nzlatin-1r)rlr]rrIr^r*s r!r'zPrintLines.connectionMadesGKK CD NN Y!7'!A B C %%'r#N)r5r6r7rr"r'r3r#r!rjrjs(r#rjceZdZdZdZy)MyFTPFileListProtocolcPg|_tjj|yr)otherrFTPFileListProtocolr"rs r!r"zMyFTPFileListProtocol.__init__s  ((.r#c:|jj|yr)rqr)r*s r! unknownLinez!MyFTPFileListProtocol.unknownLiner-r#N)r5r6r7r"rtr3r#r!roros / r#roc6eZdZdZdZdZdZdZdZdZ y) FTPFileListingTestscttjt|}|j fd|S)Nc4jjfSr)filesrq)r,fileLists r!r-z6FTPFileListingTests.getFilesForLines..s @r#)ror loopbackAsyncrjr)r rr?rzs @r!getFilesForLinesz$FTPFileListingTests.getFilesForLiness4(*  " ":e#4h ? @Ar#cTd}fd}j|gj|S)z This example line taken from the docstring for FTPFileListProtocol @return: L{Deferred} of command response z<-rw-r--r-- 1 root other 531 Jan 29 03:26 READMEc|\\}}j|dt|j|ddk(dj|ddk(dj|dd k(dj|d d k(dj|d d k(dj|ddk(dj|ddk(dj|ddk(dj|ddy)Nzunexpect unparsable lines: filetype-misparsed fileitemperms rw-r--r--misparsed permsownerrootrrqrdate Jan 29 03:26filenameREADMEnlinksrmisparsed nlinks linktargetmisparsed linktarget)rreprr) fileOtherfilerqr s r!checkz/FTPFileListingTests.test_OneLine..checks( Wde   U&A$u+$O P OOD,35I J OODM[8:K L OODMV35I J OODMW46J K OODLC/1E F OODLN:

Azwoohoo! c|\\}}\}j|dk(dj|ddk(dj|ddk(dj|d d k(d j|d d k(dj|ddk(dj|ddk(dj|ddk(dj|ddk(dj|ddj|ddk(dj|ddk(dj|d d k(d j|d d k(dj|ddk(dj|ddk(dj|dd k(dj|ddk(dj|ddk(dy)!Nz woohoo! zincorrect other linerr?rrrrrrzmisparsed ownerrrqzmisparsed grouprrzmisparsed sizerz Jan 9 2003zmisparsed daterAmisparsed filenamerrrrrr/rrB)rr)rfile1file2rqr s r!rz4FTPFileListingTests.test_VariantLines..checks)/ &^eUXe OOE\13I J OOE*-46J K OOE'Nk9;L M OOE'Nf46G H OOE'Ng57H I OOE&MS02B C OOE&M^;=M N OOE*-46J K OOE(Oq02D E   U<02H I OOE*-46J K OOE'Nk9;L M OOE'Nf46G H OOE'Ng57H I OOE&MQ.0@ A OOE&M^;=M N OOE*-46J K OOE(Oq02D E OOE,/368N Or#r)r line1line2line3rs` r!test_VariantLinesz%FTPFileListingTests.test_VariantLines s@JN P0$$eUE%:;GGNNr#cRfd}jddgj|S)z Unknown lines. cz|\}}j|dj|ddgk(dt|zy)Nzunexpected file entrieszABC z not a file zincorrect unparsable lines: %s)rrrrryothersr s r!rz3FTPFileListingTests.test_UnknownLine..check3sB$OUF   U$= > OO7N3304<? r#ABCz not a filer)r rs` r!test_UnknownLinez$FTPFileListingTests.test_UnknownLine.s+  $$e\%:;GGNNr#cZd}d}fd}j||gj|S)ze Will parse filenames and linktargets containing unescaped space characters. z9drw-r--r-- 2 root other 531 Jan 9 2003 A BzDlrw-r--r-- 1 root other 1 Jan 29 03:26 B A -> D C/A Bc|\}}jg|djd|dddjd|dddjd|dd d y Nzunexpected others entrieszA BrrrzB ArzD C/A Brrrrs r!rzBFTPFileListingTests.test_filenameWithUnescapedSpace..checkGs$OUF   R)D E   UE!HZ$8:N O   UE!HZ$8:N O   Ya(>@V Wr#rr rrrs` r!test_filenameWithUnescapedSpacez3FTPFileListingTests.test_filenameWithUnescapedSpace=s; L U  X$$eU^4@@GGr#cZd}d}fd}j||gj|S)zc Will parse filenames and linktargets containing escaped space characters. z:drw-r--r-- 2 root other 531 Jan 9 2003 A\ BzElrw-r--r-- 1 root other 1 Jan 29 03:26 B A -> D\ C/A Bc|\}}jg|djd|dddjd|dddjd|dd d yrrrs r!rz@FTPFileListingTests.test_filenameWithEscapedSpace..checkZrr#rrs` r!test_filenameWithEscapedSpacez1FTPFileListingTests.test_filenameWithEscapedSpacePs; N W  X$$eU^4@@GGr#ctjdGfddtj}fd}t j |}|j |S)z{ This example derived from bug description in issue 514. @return: L{Deferred} of command response s<-rw-r--r-- 1 root other 531 Jan 29 2003 README ceZdZfdZy)0FTPFileListingTests.test_Year..PrintLinecp|jj|jjyr)r]rr^)r exampleLines r!r'z?FTPFileListingTests.test_Year..PrintLine.connectionMadems%$$[1--/r#N)r5r6r7r')rsr! PrintLinerls 0r#rcjd}j|ddk(dj|ddk(dj|ddk(dy) Nrrrrrz Jan 29 2003rr)ryr)rrrzr s r!rz,FTPFileListingTests.test_Year..checkqsZ>>!$D OODLC/1E F OODLM9;O P OOD,8:N Or#)rrrr Protocolrr{r)r rrr?rrzs` @@r! test_YearzFTPFileListingTests.test_YearcsU **,V  0)) 0  P  " "9; 9}}U##r#N) r5r6r7r|rrrrrrr3r#r!rvrvs+ @. OD OH&H&$r#rvceZdZdZdZdZy)1FTPClientFailedRETRAndErrbacksUponDisconnectTestsz: FTP client fails and RETR fails and disconnects. ctj}d|_tjd|d}|j |j |jj}ddddd|d z |d zfzd gfd |_ tjttjd }|jd|}d}|j||j|tj S)z RETR fails. rrVrWz1220 ready, dude (vsFTPd 1.0.0: beat me, break me)z 331 Please specify the password.z230 Login successful. Have fun.z200 Binary it is, then.z+227 Entering Passive Mode (127,0,0,1,%d,%d)z550 Failed to open file.ctSr)rj)rc responsess r!r-zSFTPClientFailedRETRAndErrbacksUponDisconnectTests.test_FailedRETR..s z)'<r#r)passivecNtj}|jd|S)Nz/file/that/doesnt/exist)r rr)rhrs r!rizTFTPClientFailedRETRAndErrbacksUponDisconnectTests.test_FailedRETR..gotClients$!!#A&&'@!D Dr#)r rPnoisyrr{rbr|r}rLr`r~rrrrrr)r r&rLrrr?rirs @r!test_FailedRETRzAFTPClientFailedRETRAndErrbacksUponDisconnectTests.test_FailedRETRs      A= **+,,.%% @ . - % 9!|Wt^, - '  =  # #GS]]A F MM+w / E i !!!S%6%677r#cdtj}tj}|j |||_|j dt}gfd}|j|ddl m }|jtj||j|S)zl Test the ftp command errbacks when a connection lost happens during the operation. z some pathc(j|yrr))rms r!_ebzZFTPClientFailedRETRAndErrbacksUponDisconnectTests.test_errbacksUponDisconnect.._ebs HHW r#r)CONNECTION_LOST)rrrrbrdr rrrtwisted.internet.mainrrFrFailurer)r ftpClienttrr?rrrs @r!test_errbacksUponDisconnectzMFTPClientFailedRETRAndErrbacksUponDisconnectTests.test_errbacksUponDisconnects MMO  ; ; =  $ NN; 0   S9  !AB 1r#N)r5r6r7rrrr3r#r!rr{s"8Hr#rceZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZ dZ!d Z"d!Z#d"Z$d#Z%d$Z&d%Z'd&Z(d'Z)d(Z*d)Z+d*Z,y+),FTPClientTestsz, Test advanced FTP client commands. ctj|_tj|_|jj |j |j|j _y)zG Create a FTP client and connect it to fake transport. N)rrrhrrbr]rdr rs r!rzFTPClientTests.setUpsGmmo &GGI ""4>>2"&++r#c^|jjtjy)z Deliver disconnection notification to the client so that it can perform any cleanup which may be required. N)rhrFr ConnectionLostrs r!r.zFTPClientTests.tearDowns ""5#7#7#9:r#c |j|jjd|jj d|j|jjd|jj |jj d|j|jjd|jj |jj dy)z& Test the login part. r#s8331 Guest login ok, type your email address as password.sUSER anonymous s2230 Anonymous login ok, access restrictions apply.sTYPE I s200 Type set to I.N)rr]rrhr,clearrs r! _testLoginzFTPClientTests._testLogins --/5   G  --/1FG    !VW --/?    !67r#c*|j|jjd|jj d|j|jjd|jj d|j|jjd|jj |jj d|j|jjdy)z5 Test encoding behaviour of sendLine r#Nrés )rr]rrhrerrs r! test_sendLinezFTPClientTests.test_sendLines --/5 T" --/5 R  --/9  V$ --/=r#cBfd}jjjj|}j j j dj jjjd|S)a Test the CDUP command. L{ftp.FTPClient.cdup} should return a Deferred which fires with a sequence of one element which is the string the server sent indicating that the command was executed successfully. (XXX - This is a bad API) c0j|ddyNrr<rr{s r!cbCdupz(FTPClientTests.test_CDUP..cbCdup   SV%M Nr#CDUP &250 Requested File Action Completed OK) rrhcduprrr]rrr,)r rr?s` r! test_CDUPzFTPClientTests.test_CDUPsw O  KK    * *6 2 --/=    !JKr#cX|j|jj}|j|tj |j |jjd|jj|jjd|S)z Test L{ftp.FTPClient.cdup}'s handling of a failed CDUP command. When the CDUP command fails, the returned Deferred should errback with L{ftp.CommandFailed}. rs!550 ..: No such file or directory) rrhrrrrrr]rrr,rs r!test_failedCDUPzFTPClientTests.test_failedCDUPs{  KK    1c//0 --/=    !EFr#cfd}jjjj|}j j j djjd|S)a Test the PWD command. L{ftp.FTPClient.pwd} should return a Deferred which fires with a sequence of one element which is a string representing the current working directory on the server. (XXX - This is a bad API) cVjtj|ddy)Nr/bar/baz)rrparsePWDResponser{s r!cbPwdz&FTPClientTests.test_PWD..cbPwds"   S11#a&9: Fr#PWD 257 "/bar/baz")rrhpwdrrr]rr,)r rr?s` r!test_PWDzFTPClientTests.test_PWDse G  KKOO  ) )% 0 --/<   !23r#c$|j|jj}|j|tj |j |jjd|jjd|S)z Test a failure in PWD command. When the PWD command fails, the returned Deferred should errback with L{ftp.CommandFailed}. r'550 /bar/baz: No such file or directory) rrhrrrrrr]rr,rs r!test_failedPWDzFTPClientTests.test_failedPWD%si  KKOO  1c//0 --/<   !KLr#cfd}jjjdj|}j j j djjd|S)a Test the CWD command. L{ftp.FTPClient.cwd} should return a Deferred which fires with a sequence of one element which is the string the server sent indicating that the command was executed successfully. (XXX - This is a bad API) c0j|ddyrrr{s r!cbCwdz&FTPClientTests.test_CWD..cbCwd>rr#bar/foo CWD bar/foo r)rrhcwdrrr]rr,)r rr?s` r!test_CWDzFTPClientTests.test_CWD3sh O  KKOOI & 2 25 9 --/1CD   !JKr#c&|j|jjd}|j|tj |j |jjd|jjd|S)z Test a failure in CWD command. When the PWD command fails, the returned Deferred should errback with L{ftp.CommandFailed}. rrs&550 bar/foo: No such file or directory) rrhrrrrrr]rr,rs r!test_failedCWDzFTPClientTests.test_failedCWDGsl  KKOOI & 1c//0 --/1CD   !JKr#cpfd}fd}|j_jt}jj d|}|j ||j jjdjjjjtjj jjdjjjjd|S)aN Test the RETR command in passive mode: get a file and verify its content. L{ftp.FTPClient.retrieveFile} should return a Deferred which fires with the protocol instance passed to it after the download has completed. (XXX - This API should be based on producers and consumers) c>j|jdyNxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxrr|rr s r!cbRetrz/FTPClientTests.test_passiveRETR..cbRetra   U\\; 7r#cj|dj|d|j||f}|jtjj j d|jd|jtjtjdy)NrV904150 File status okay; about to open data connection.rr rr`rdrStringTransportrhr,rBrFrrr ConnectionDonerKrLr%rr s r! cbConnectz2FTPClientTests.test_passiveRETR..cbConnectds   T; /   T5 )))4,7E  !>!>!@ A KK $ $G    { +  1E1Eb1I!J Kr#spamPASV RETR spam 226 Transfer Complete.) rhconnectFactoryrr:rrrr]rrr,rN)r rr rr?s` r!test_passiveRETRzFTPClientTests.test_passiveRETRUs 8 L&/ " "$ KK $ $VU 3 fe$ --/=    !=> --/1AB    !:;r#c dj_d}fd}|j_jt }jj d|}|j ||jjjdjtjddjjjjjjj!djjjd jjjj!d |S) z Test the RETR command in non-passive mode. Like L{test_passiveRETR} but in the configuration where the server establishes the data connection to the client, rather than the other way around. Fcjdjtjdd|_|jj t j|jjd|jjtjtjdy)NPORT {}rV&rr)formatrrHtextr rdrrrBrFrrr r)portCmds r! generatePortz.FTPClientTests.test_RETR..generatePorts{$++C,>,>{D,QRGL    + +M,I,I,K L    ) )+ 6    + +GOOEj|jdyrrrs r!rz(FTPClientTests.test_RETR..cbRetrrr#r  PORT {} rVr 200 PORT OKr r )rhrgeneratePortCommandrr:rrrr]rrrrHrIrJrr,)r rrrr?s` r! test_RETRzFTPClientTests.test_RETR|s$  W  8+7 ' "$ KK $ $VU 3 fe$  NN "  ! !#"4"4[$"G H P P %%     0 --/1AB    !:;r#cfd}|j_jt}jj d|}j |t jjjjdjjjjtjjjjdjjjjd|S)z Try to RETR an unexisting file. L{ftp.FTPClient.retrieveFile} should return a Deferred which errbacks with L{ftp.CommandFailed} if the server indicates the file cannot be transferred for some reason. c^j|dj|d|j||f}|jtjj j d|jtjtjdyNrVrrr rr`rdrrrhr,rFrrr rrs r!r z1FTPClientTests.test_failedRETR..cbConnect   T; /   T5 )))4,7E  !>!>!@ A KK $ $G   1E1Eb1I!J Kr#r r r s#550 spam: No such file or directory)rhrrr:rrrrrr]rrr,rN)r r rr?s` r!test_failedRETRzFTPClientTests.test_failedRETRs L&/ " "$ KK $ $VU 3 1c//0 --/=    !=> --/1AB    !GHr#c  d|j_gfd}||j_|jt }|jj d|}|j |jjdjtjddj|jj|jj|jjd|j |jjd|j!d j#|jj#|j%|tj&|S) z Try a RETR, but disconnect during the transfer. L{ftp.FTPClient.retrieveFile} should return a Deferred which errbacks with L{ftp.ConnectionLost) Fc2djtjdd|_t j }|j j||j |_|j jdj|y)NrrVrsxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx) rrrHrrrbr rdrBr))rrr/s r!rz2FTPClientTests.test_lostRETR..generatePortsp$++C,>,>{D,QRGL??AB    + +B /!**BK    ) )* 5 HHRLr#r rrVrrr r)rhrrrr:rrr]rrrrHrIrJrr,rr^rr)r rrr?r/s @r! test_lostRETRzFTPClientTests.test_lostRETRs+ $   +7 ' "$ KK $ $VU 3  NN "  ! !#"4"4[$"G H P P %%     0 --/1AB  ! %%' 1c001r#ctjfd}fd}fd}|j_j jj d\}}|j ||j |jjjdjjjjtjjjjdjjjjdtj||gS)a Test the STOR command: send a file and verify its content. L{ftp.FTPClient.storeFile} should return a two-tuple of Deferreds. The first of which should fire with a protocol instance when the data connection has been established and is responsible for sending the contents of the file. The second of which should fire when the upload has completed, the data connection has been closed, and the server has acknowledged receipt of the file. (XXX - storeFile should take a producer as an argument, instead, and only return a Deferred which fires when the upload has succeeded or failed). cjjd|jjd|j |j t jtjdyNrrr rhr,r]rfinishrFrrr rsenderr s r!cbStorez0FTPClientTests.test_passiveSTOR..cbStoreY KK $ $G     " "; / MMO  ! !'//%2F2Fr2J"K Lr#cFjjdyrrrignr rs r!cbFinishz1FTPClientTests.test_passiveSTOR..cbFinish   RXXZ 5r#cj|dj|d|j||f}|jyNrVrrr`rdrKrLr%rr rs r!r z2FTPClientTests.test_passiveSTOR..cbConnectE   T; /   T5 )))4,7E   $r#r r  STOR spam r )rrrhrrr~rrr]rrr,rNr r)r r-r3r rdrrs` @r!test_passiveSTORzFTPClientTests.test_passiveSTORs  * * , M 6 % &/ " &&v.B w x  --/=    !=> --/1AB    !:;""B8,,r#ctjfd}fd}|j_j jj d\}}|j |j|tjjjjdjjjjtjjjjdjjjjdt!j"||gS)z Test a failure in the STOR command. If the server does not acknowledge successful receipt of the uploaded file, the second Deferred returned by L{ftp.FTPClient.storeFile} should errback with L{ftp.CommandFailed}. cjjd|jjd|j |j t jtjdyr(r)r+s r!r-z/FTPClientTests.test_failedSTOR..cbStore r.r#cj|dj|d|j||f}|jyr6r7r8s r!r z1FTPClientTests.test_failedSTOR..cbConnect(r9r#r r r:s.426 Transfer aborted. Data connection closed.)rrrhrrr~rrrrrr]rrr,rNr r)r r-r rdrrs` @r!test_failedSTORzFTPClientTests.test_failedSTORs * * , M % &/ " &&v.B w 2s001 --/=    !=> --/1AB    !RS""B8,,r#c`tjdj_fd}fd}fd}|j_j jj d\}}|j||j|tj||gS)z Test the STOR command in non-passive mode. Like L{test_passiveSTOR} but in the configuration where the server establishes the data connection to the client, rather than the other way around. Fcxdtjddz|_|jj y)Nr)rVr)rrHrr rd)rrs r!rz.FTPClientTests.test_STOR..generatePortFs0"S%7%7 T%JJGL    + +B /r#c jjjdjt j ddj jjjjjjdjjjdjjjjd|jjd|j|jtjt!j"djjd y) NrrVrrr:rrrr )rr]rrrrHrIrhrJrr,rr*rFrrr rr+s r!r-z)FTPClientTests.test_STOR..cbStoreJs   $$&%%c&8&8d&KLTTKK))  NN " KK $ $^ 4   T^^1135E F NN " KK $ $G     " "; / MMO  ! !'//%2F2Fr2J"K L KK $ $%> ?r#cFjjdyrr0r1s r!r3z*FTPClientTests.test_STOR..cbFinish]r4r#r ) rrrhrrrr~rr r)r rr-r3rdrrs` @r! test_STORzFTPClientTests.test_STOR;s * * ,#  0 @& 6+7 ' &&v.B w x ""B8,,r#cLfd}fd}|j_jtj}jj d|j ||}jjjdjjjjtjjjjdjjd|S)a{ Test the LIST command. L{ftp.FTPClient.list} should return a Deferred which fires with a protocol instance which was passed to list after the command has succeeded. (XXX - This is a very unfortunate API; if my understanding is correct, the results are always at least line-oriented, so allowing a per-line parser function to be specified would make this simpler, but a default implementation should really be provided which knows how to deal with all the formats used in real servers, so application developers never have to care about this insanity. It would also be nice to either get back a Deferred of a list of filenames or to be able to consume the files as they are received (which the current API does allow, but in a somewhat inconvenient fashion) -exarkun) c|jDcgc]}|d }}gd}|j|jj||ycc}wNrr9r?bazryrrr|rzr&flsexpectedr s r!cbListz/FTPClientTests.test_passiveLIST..cbList{J*2..9Q1Z=9C9,H MMO HHJ   S( + : Acj|dj|d|j||f}|jtjj j dgd}|D]}|j||jtjtjdy)NrVrrs8-rw-r--r-- 0 spam egg 100 Oct 10 2006 foo s8-rw-r--r-- 3 spam egg 100 Oct 10 2006 bar s8-rw-r--r-- 4 spam egg 100 Oct 10 2006 baz rr)rKrLr%rsendingr%r s r!r z2FTPClientTests.test_passiveLIST..cbConnects   T; /   T5 )))4,7E  !>!>!@ A KK $ $G G  &""1% &  1E1Eb1I!J Kr#foo/barr LIST foo/bar r ) rhrrrrrrrrr]rrr,rN)r rNr rzr?s` r!test_passiveLISTzFTPClientTests.test_passiveLISTgs( , L"&/ " **, KK  Y 1 = =fh O --/=    !=> --/1DE   !:;r#c dj_fd}fd}|j_jt j }jj d|j||}jjjdjt jddjjjjjjj!djjjd jjjj!d |S) z Test the LIST command in non-passive mode. Like L{test_passiveLIST} but in the configuration where the server establishes the data connection to the client, rather than the other way around. Fcdjtjdd|_|jj t jjjdgd}|D]}|jj||jjtjtjdy)NrrVrrrRrrrrHrr rdrrrhr,rBrFrrr r)rrSr%r s r!rz.FTPClientTests.test_LIST..generatePorts$++C,>,>{D,QRGL    + +M,I,I,K L KK $ $G G  1  --a0 1    + +GOOE.cbListrOrPrTrrVrrrUr )rhrrrrrrrrrr]rrrHrIrJrr,)r rrNrzr?s` r! test_LISTzFTPClientTests.test_LISTs $  W ,+7 ' **, KK  Y 1 = =fh O  NN "  ! !#"4"4[$"G H P P %%     0 --/1DE    !:;r#cbfd}|j_jtj}jj d|}j |tjjjjdjjjjtjjjjdjjd|S)z Test a failure in LIST command. L{ftp.FTPClient.list} should return a Deferred which fails with L{ftp.CommandFailed} if the server indicates the indicated path is invalid for some reason. c^j|dj|d|j||f}|jtjj j d|jtjtjdyrr rs r!r z1FTPClientTests.test_failedLIST..cbConnectr!r#rTr rU&550 foo/bar: No such file or directory)rhrrrrrrrrrr]rrr,rN)r r rzr?s` r!test_failedLISTzFTPClientTests.test_failedLISTs L&/ " **, KK  Y 1 1c//0 --/=    !=> --/1DE   !JKr#c dj_fd}fd}|j_jt }jj d|j ||}jjjdjtjddjjjjjjj!djjjd jj!d |S) z Test the NLST command in non-passive mode. L{ftp.FTPClient.nlst} should return a Deferred which fires with a list of filenames when the list command has completed. Fcdjtjdd|_|jj t jjjd|jjd|jjd|jjd|jjtjtjdy) NrrVrrfoo bar baz rrY)rr s r!rz.FTPClientTests.test_NLST..generatePorts$++C,>,>{D,QRGL    + +M,I,I,K L KK $ $G     ) )* 5    ) )* 5    ) )* 5    + +GOOE.cbList sQ,,%%dkk&;&;<GGIC,H MMO HHJ   S( +r#rTrrVrrNLST foo/bar r )rhrrrr:nlstrrr]rrrrHrIrJrr,)r rrNlstprotor?s` r! test_NLSTzFTPClientTests.test_NLSTs $  W ,+7 ' %' KK  Y 1 = =fh O  NN "  ! !#"4"4[$"G H P P %%     0 --/1DE   !:;r#c8fd}fd}|j_jt}jj d|j ||}j jjdjjjjtjj jjdjjd|S)z Test the NLST command. Like L{test_passiveNLST} but in the configuration where the server establishes the data connection to the client, rather than the other way around. c|jj}gd}|j|jj||y)N)rrsbaz)r=rrrrgs r!rNz/FTPClientTests.test_passiveNLST..cbList" s<,,))+C/H MMO HHJ   S( +r#cj|dj|d|j||f}|jtjj j d|jd|jd|jd|jtjtjdy)NrVrrrbrcrdrrrs r!r z2FTPClientTests.test_passiveNLST..cbConnect) s   T; /   T5 )))4,7E  !>!>!@ A KK $ $G    z *   z *   z *  1E1Eb1I!J Kr#rTr rhr ) rhrrr:rirrr]rrr,rN)r rNr rjr?s` r!test_passiveNLSTzFTPClientTests.test_passiveNLST s , L&/ " %' KK  Y 1 = =fh O --/=    !=> --/1DE   !:;r#cztjfd}|j_j t }jj d|}j|tjjjjdjjjjtjjjjdjjd|S)z Test a failure in NLST command. L{ftp.FTPClient.nlst} should return a Deferred which fails with L{ftp.CommandFailed} if the server indicates the indicated path is invalid for some reason. c:j|dj|d|j||f}|jjj d|j t jtjdyr) rr`rdrhr,rFrrr rr8s r!r z1FTPClientTests.test_failedNLST..cbConnectK s~   T; /   T5 )))4,7E   $ KK $ $G   1E1Eb1I!J Kr#rTr rhr^)rrrhrrr:rirrrrr]rrr,rN)r r rjr?rs` @r!test_failedNLSTzFTPClientTests.test_failedNLSTA s * * , L&/ " %' KK  Y 1 1c//0 --/=    !=> --/1DE   !JKr#cz|j|jjdd}|j|jj d|jj d}|jj|j|jj|j|jj dd}|jj|j|jj|j|j|g|gf|S)z L{ftp.FTPClient.rename} issues I{RNTO} and I{RNFR} commands and returns a L{Deferred} which fires when a file has successfully been renamed. /spam/ham RNFR /spam z8350 Requested file action pending further information. RNTO /ham r<) rrhrenamerr]rrr,rIrJr)r r? fromResponse toResponses r!test_renameFromToz FTPClientTests.test_renameFromToa s  KK  w / --/1BC S    !4!4T[[5J5J!KL --/1AB=    !2!24;;3H3H!IJ d&&,*(FGr#c$|jd}d}|jj|||jjd|jjd|j |j j dy)z L{ftp.FTPClient.rename} issues I{RNTO} and I{RNFR} commands with paths escaped according to U{http://cr.yp.to/ftp/filesystem.html}. z /foo/ba r/bazz/qu uxs350 s250 s!RNFR /foo/bar/baz RNTO /quux N)rrhrxr,rr]r)r fromFiletoFiles r!test_renameFromToEscapesPathsz,FTPClientTests.test_renameFromToEscapesPathsu sq # 8V,   )   )  NN "$V r#c|j|jjdd}|j|jj d|jj |jjd|j|jj d|j|tjS)z The L{Deferred} returned by L{ftp.FTPClient.rename} is errbacked with L{CommandFailed} if the I{RNFR} command receives an error response code (for example, because the file does not exist). rtrurv!550 Requested file unavailable. r# rrhrxrr]rrr,rrrrs r!$test_renameFromToFailingOnFirstErrorz3FTPClientTests.test_renameFromToFailingOnFirstError s  KK  w / --/1BC    !GH --/5!!!S%6%677r#c|j|jjdd}|j|jj d|jj |jjd|j|jj d|jjd|j|tjS)z The L{Deferred} returned by L{ftp.FTPClient.rename} is errbacked with L{CommandFailed} if the I{RNTO} command receives an error response code (for example, because the destination directory does not exist). rtrurvs8350 Requested file action pending further information. rwrrrs r!"test_renameFromToFailingOnRenameToz1FTPClientTests.test_renameFromToFailingOnRenameTo s  KK  w / --/1BC    I  --/1AB   !GH!!!S%6%677r#c|j|jjd}|j|jj d|jj d|j|jdgS)z L{ftp.FTPClient.makeDirectory} issues a I{MKD} command and returns a L{Deferred} which is called back with the server's response if the directory is created. rt MKD /spam s257 "/spam" created.z257 "/spam" created.)rrh makeDirectoryrr]rr,rrs r!test_makeDirectoryz!FTPClientTests.test_makeDirectory sn  KK % %g . --/1AB   !89}}T--0F/GHHr#c|j|jjd}|j|jj d|jj d|S)z L{ftp.FTPClient.makeDirectory} escapes the path name it sends according to U{http://cr.yp.to/ftp/filesystem.html}. z/sp ams MKD /spam s257 win)rrhrrr]rr,rs r!test_makeDirectoryPathEscapez+FTPClientTests.test_makeDirectoryPathEscape sY  KK % %i 0 --/1EF   ,r#c"|j|jjd}|j|jj d|jj d|j|tjS)z L{ftp.FTPClient.makeDirectory} returns a L{Deferred} which is errbacked with L{CommandFailed} if the server returns an error response code. rtrs550 PERMISSION DENIED) rrhrrr]rr,rrrrs r!test_failedMakeDirectoryz'FTPClientTests.test_failedMakeDirectory sl  KK % %g . --/1AB   !9:!!!S%6%677r#cfd}jjjj|}j j j djjd|S)z Test the getDirectory method. L{ftp.FTPClient.getDirectory} should return a Deferred which fires with the current directory on the server. It wraps PWD command. c*j|dy)Nrrr{s r!cbGetz/FTPClientTests.test_getDirectory..cbGet s   S* -r#rr)rrh getDirectoryrrr]rr,)r rr?s` r!test_getDirectoryz FTPClientTests.test_getDirectory sf .  KK $ $ & 2 25 9 --/<   !23r#c$|j|jj}|j|tj |j |jjd|jjd|S)zj Test a failure in getDirectory method. The behaviour should be the same as PWD. rr rrhrrrrrr]rr,rs r!test_failedGetDirectoryz&FTPClientTests.test_failedGetDirectory sk  KK $ $ & 1c//0 --/<   !KLr#c$|j|jj}|j|tj |j |jjd|jjd|S)z Test a different failure in getDirectory method. The response should be quoted to be parsed, so it returns an error otherwise. rs 257 /bar/bazrrs r!test_anotherFailedGetDirectoryz-FTPClientTests.test_anotherFailedGetDirectory sj  KK $ $ & 1c//0 --/<   1r#cf|j|jjd}|j|jj dd}|jj |j|jj|j|j|gS)z L{ftp.FTPClient.removeFile} sends a I{DELE} command to the server for the indicated file and returns a Deferred which fires after the server sends a 250 response code. /tmp/testDELE /tmp/test *250 Requested file action okay, completed.) rrh removeFilerr]rr,rIrJrr r?responses r!test_removeFilezFTPClientTests.test_removeFile s  KK " "; / --/1FG?   1F1F!GH}}T--z::r#cjjjd}jjj ddjj jjjj|tj}|jfd|S)a If the server returns a response code other than 250 in response to a I{DELE} sent by L{ftp.FTPClient.removeFile}, the L{Deferred} returned by C{removeFile} is errbacked with a L{Failure} wrapping a L{CommandFailed}. rr,501 Syntax error in parameters or arguments.c@j|jgfSrrexcrr s r!r-z6FTPClientTests.test_failedRemoveFile.. $"2"2388xj]"Kr#) rrhrrr]rr,rIrJrrrrrs` @r!test_failedRemoveFilez$FTPClientTests.test_failedRemoveFile s  KK " "; / --/1FGA   1F1F!GH   q#"3"3 4 KLr#cJjjjd}djjj jj j |tj}|jfd|S)z If the server returns a response line which cannot be parsed, the L{Deferred} returned by L{ftp.FTPClient.removeFile} is errbacked with a L{BadResponse} containing the response. r765 blah blah blahc@j|jgfSrrrs r!r-zBFTPClientTests.test_unparsableRemoveFileResponse..% rr#) rrhrr,rIrJrr BadResponserrs` @r!!test_unparsableRemoveFileResponsez0FTPClientTests.test_unparsableRemoveFileResponse su  KK " "; /'   1F1F!GH   q#// 2 KLr#c|j|jjd}|jjd|jjd|j |j S)z If the server returns multiple response lines, the L{Deferred} returned by L{ftp.FTPClient.removeFile} is still fired with a true value if the ultimate response code is 250. r250-perhaps a progress report250 okay)rrhrr,rrrs r! test_multilineRemoveFileResponsez/FTPClientTests.test_multilineRemoveFileResponse( sZ  KK " "; /   !AB   -}}T__--r#cf|j|jjd}|j|jj dd}|jj |j|jj|j|j|gS)z L{ftp.FTPClient.removeDirectory} sends a I{RMD} command to the server for the indicated directory and returns a Deferred which fires after the server sends a 250 response code. rRMD /tmp/test r) rrhremoveDirectoryrr]rr,rIrJrrs r!test_removeDirectoryz#FTPClientTests.test_removeDirectory4 s  KK ' ' 4 --/1EF?   1F1F!GH}}T--z::r#cjjjd}jjj ddjj jjjj|tj}|jfd|S)a  If the server returns a response code other than 250 in response to a I{RMD} sent by L{ftp.FTPClient.removeDirectory}, the L{Deferred} returned by C{removeDirectory} is errbacked with a L{Failure} wrapping a L{CommandFailed}. rrrc@j|jgfSrrrs r!r-z;FTPClientTests.test_failedRemoveDirectory..N rr#) rrhrrr]rr,rIrJrrrrrs` @r!test_failedRemoveDirectoryz)FTPClientTests.test_failedRemoveDirectoryA s  KK ' ' 4 --/1EFA   1F1F!GH   q#"3"3 4 KLr#cJjjjd}djjj jj j |tj}|jfd|S)z If the server returns a response line which cannot be parsed, the L{Deferred} returned by L{ftp.FTPClient.removeDirectory} is errbacked with a L{BadResponse} containing the response. rrc@j|jgfSrrrs r!r-zGFTPClientTests.test_unparsableRemoveDirectoryResponse..\ rr#) rrhrr,rIrJrrrrrs` @r!&test_unparsableRemoveDirectoryResponsez5FTPClientTests.test_unparsableRemoveDirectoryResponseQ su  KK ' ' 4'   1F1F!GH   q#// 2 KLr#c|j|jjd}|jjd|jjd|j |j S)z If the server returns multiple response lines, the L{Deferred} returned by L{ftp.FTPClient.removeDirectory} is still fired with a true value if the ultimate response code is 250. rrr)rrhrr,rrrs r!%test_multilineRemoveDirectoryResponsez4FTPClientTests.test_multilineRemoveDirectoryResponse_ sZ  KK ' ' 4   !AB   -}}T__--r#N)-r5r6r7rrr.rrrrrrrrrrr"r%r;r?rDrVr[r_rkrorrr{rrrrrrrrrrrrrrrrrr3r#r!rrs.; 8 >* ( ( %N#J@$L--^#-J*-X5n/b>)V&P@( 8$8& I  8"   ;  . ;  .r#rc.eZdZdZdZdZdZdZdZy)FTPClientBasicTestsz FTP client ctj}|jd|jdg|jy)z? The first response is captured as a greeting. 220 Imaginary FTP.z220 Imaginary FTP.Nrrr,rgreetingr rs r! test_greetingz!FTPClientBasicTests.test_greetingq s;&&( 45 ./1C1CDr#ctj}|jd|jdg|jy)z Responses with no message are still valid, i.e. three digits followed by a space is complete response. s220 z220 Nrrs r!test_responseWithNoMessagez.FTPClientBasicTests.test_responseWithNoMessagey s8 &&( w' &9#5#56r#ctj}tj|_|j d|j d}g}|j|j|j|j|j d|jg||j d|jg||j d|jg||j d|jg||j d|jg||j d|jg||j d |jgd |d y ) z$ Multiline response rBLAHs210-First line.s123-Second line.sJust some text.sHir#s321s 210 Done.)z210-First line.z123-Second line.zJust some text.Hir321z 210 Done.rN) rrrrr]r,rrr)rrr)r rrrs r!test_MultilineResponsez*FTPClientBasicTests.test_MultilineResponse s\&&( +;;= 45//7V]]+DII& 12 V$ 23 V$ 12 V$ u% V$ s# V$ v& V$ |,   1I r#ctj}tj|_|j d|j dd|jd|jj|jj|j d|jd|jjy)zO Passing None as the password avoids sending the PASS command. 220 Welcome to Imaginary FTP.bobN USER bob s200 Hello bob.r# rrrrr]r, queueLoginrrrrs r!test_noPasswordGivenz(FTPClientBasicTests.test_noPasswordGiven s &&( +;;= ?@ UD) )*=*=*C*C*EF !!#01 i11779:r#ctj}tj|_|j d|j dd|jd|jj|jj|j d|jd|jjy)zQ Receiving a 230 response to USER prevents PASS from being sent. rrsecretrs#230 Hello bob. No password needed.r#Nrrs r!test_noPasswordNeededz)FTPClientBasicTests.test_noPasswordNeeded s &&( +;;= ?@ UH- )*=*=*C*C*EF !!#EF i11779:r#N) r5r6r7rrrrrrr3r#r!rrl s"E74 l;*;r#rceZdZdZdZy)PathHandlingTestsz Handling paths. c ddgfddgfdgfdgdfdgdfddgfddgffD]+\}}|jtjg||-d dd gfd dd gfd d gfd d gfd gdfdgdfdd dgfdd dgffD],\}}|jtjdg||.dgfddgfddgfddd gffD]+\}}|jtjg||-dgfdd gfdgdffD],\}}|jtjdg||.dgfdgfddgfdgfddgfddgfdddgfd ddgfd!dgfd"dgfd#gfd$gff D],\}}|jtjdg||.d%D]2}|jtjtjg|4d&D]3}|jtjtjdg|5y')(z" Normalize paths. rz/a/za/b/c)rrcz/a/b/cz/a/za/rzb/z/bz/b/zb/czb/c/z/b/crz/b/c/z//z//aza//za//bz//bzb//c..../za/..xz/a/..z/a/b/..z/a/b/../z /a/b/../cz /a/b/../c/z /a/b/../../cz /a/b/../../c/z/a/b/../../c/..z/a/b/../../c/../) rrza/../..za/../../z/..z/../z/a/../..z /a/../../z /a/b/../../..)z../..z../../z ../a/../..N)rr toSegmentsr" InvalidPath)r inpoutps r!test_Normalizerz!PathHandlingTests.test_Normalizer s 3%L C5M "I o &  ' SEN C5M  ?2J SEN SEN c3Z    ?2J BK cUO bM   #  3* % C: & cU # se $  #  $   ?IC   S^^SE37 > ?  HC   coos~~r3 G H5 KC   coos~~uc J Kr#N)r5r6r7rrr3r#r!rr sDKr#rc"eZdZdZdZdZdZy)IsGlobbingExpressionTestsz; Tests for _isGlobbingExpression utility function. c|jtj|jtjg|jtjdy)z^ _isGlobbingExpression will return False for None, or empty segments. Nrr_isGlobbingExpressionrs r!&test_isGlobbingExpressionEmptySegmentsz@IsGlobbingExpressionTests.test_isGlobbingExpressionEmptySegments5 sM 2245 22267 22489r#c|jtjddg|jtjddgy)z _isGlobbingExpression will return False for plain segments. Also, it only checks the last segment part (filename) and will not check the path name. rnexpr*.txtNrrs r!test_isGlobbingExpressionNoGlobz9IsGlobbingExpressionTests.test_isGlobbingExpressionNoGlob> s@ 22Hf3EFG 22GV3DEFr#c|jtjddg|jtjddg|jtjddgy)z _isGlobbingExpression will return True for segments which contains globbing characters in the last segment part (filename). rnrz [a-b].txtzfil?.txtN)rrrrs r!test_isGlobbingExpressionGlobz7IsGlobbingExpressionTests.test_isGlobbingExpressionGlobH sX 118W2EFG 118[2IJK 118Z2HIJr#N)r5r6r7rrrrr3r#r!rr0 s:GKr#rc(eZdZdZdZdZdZdZy)BaseFTPRealmTestsz Tests for L{ftp.BaseFTPRealm}, a base class to help define L{IFTPShell} realms with different user home directory policies. c^|jtttjy)z; L{ftp.BaseFTPRealm} implements L{IRealm}. N)rrr r BaseFTPRealmrs r!test_interfacez BaseFTPRealmTests.test_interfaceX s  FC,<,<=>r#cxtj|jgGfddtj}||j}|j ddtj \}}}|j|tj|j|jy)z L{ftp.BaseFTPRealm} calls its C{getHomeDirectory} method with the avatarId being requested to determine the home directory for that avatar. ceZdZfdZy):BaseFTPRealmTests.test_getHomeDirectory..TestRealmc*j|Srr)r avatarIdavatarsrs r!getHomeDirectoryzKBaseFTPRealmTests.test_getHomeDirectory..TestRealm.getHomeDirectoryh sx( r#N)r5r6r7r)rrsr! TestRealmrg s r#ralice@example.comN) rrnrjrr requestAvatar IFTPShellrFTPShellrfilesystemRoot)r rrealmifaceavatarlogoutrrs @@r!test_getHomeDirectoryz'BaseFTPRealmTests.test_getHomeDirectory^ s ""4;;=1 ((  $++-( % 3 3 s}}! vv fcll3 ..7r#cR|j}tj|}|jtj dtj \}}}|j|tj|j|jtj|y)zy L{ftp.BaseFTPRealm} returns an L{ftp.FTPAnonymousShell} instance for anonymous avatar requests. N) rjrrrr ANONYMOUSrrrrrrrn)r rQrrrrs r!test_anonymousz BaseFTPRealmTests.test_anonymouss s KKM   + % 3 3   cmm! vv fc&;&;< ..0A0A)0LMr#ctj|j}|jt|j t y)z L{ftp.BaseFTPRealm.getHomeDirectory} should be overridden by a subclass and raises L{NotImplementedError} if it is not. N)rrrjr"NotImplementedErrorrrh)r rs r!test_notImplementedz%BaseFTPRealmTests.test_notImplemented s5   / -u/E/EvxPr#N)r5r6r7rrrrr r3r#r!rrR s ? 8* NQr#rceZdZdZdZdZy) FTPRealmTestsz$ Tests for L{ftp.FTPRealm}. cd}tj|j|}|jd}|j t j |jd|y)z L{ftp.FTPRealm} accepts an extra directory to its initializer and treats the avatarId passed to L{ftp.FTPRealm.getHomeDirectory} as a single path segment to construct a child of that directory. z /path/to/homerN)rrqrjrrrrnr@)r baserhomes r!rz#FTPRealmTests.test_getHomeDirectory sW  T[[]D1%%&9: **40667JKTRr#ctj|j}|jd}|j t j d|y)z If no extra directory is passed to L{ftp.FTPRealm}, it uses C{"/home"} as the base directory containing all user home directories. rz/home/alice@example.comN)rrqrjrrrrn)r rrs r!test_defaultHomeDirectoryz'FTPRealmTests.test_defaultHomeDirectory sE  T[[]+%%&9: **+DEtLr#N)r5r6r7rrrr3r#r!r r  s SMr#r c eZdZdZeZdZdZy)SystemFTPRealmTestsz* Tests for L{ftp.SystemFTPRealm}. ctj}ddl}|j|j}t j |j}|j|}|j|tj|y)z L{ftp.SystemFTPRealm.getHomeDirectory} treats the avatarId passed to it as a username in the underlying platform and returns that account's home directory. rN) getpassgetuserrgetpwnampw_dirrSystemFTPRealmrjrrrrn)r rrrMrrs r!rz)SystemFTPRealmTests.test_getHomeDirectory sj  <<%,,""4;;=1%%d+ x00:;r#ctjtjdj dt dDz}t j|j}|jt|j|y)z L{ftp.SystemFTPRealm.getHomeDirectory} raises L{UnauthorizedLogin} when passed a username which has no corresponding home directory in the system's accounts database. rc3K|]8}tjtjtjz:ywr)randomchoicestring ascii_lettersdigits).0r,s r! z6SystemFTPRealmTests.test_noSuchUser.. s-= DEFMM&..> ?= s>Ar/N) rrrrrrrrrjr"r r)r rrs r!test_noSuchUserz#SystemFTPRealmTests.test_noSuchUser sj}}V112RWW= INq= 6  ""4;;=1 +U-C-CTJr#N)r5r6r7r nonPOSIXSkipskiprr#r3r#r!rr s D<( Kr#rc:eZdZdZdZdZdZdZdZdZ dZ y ) ErrnoToFailureTestsz9 Tests for L{ftp.errnoToFailure} errno checking. ctjtjd}|j |tj S)zS C{errno.ENOENT} should be translated to L{ftp.FileNotFoundError}. r9)rerrnoToFailureerrnoENOENTrFileNotFoundErrorrs r! test_notFoundz!ErrnoToFailureTests.test_notFound 3   u||U 3!!!S%:%:;;r#ctjtjd}|j |tj S)zV C{errno.EPERM} should be translated to L{ftp.PermissionDeniedError}. r9)rr)r*EPERMrPermissionDeniedErrorrs r!test_permissionDeniedz)ErrnoToFailureTests.test_permissionDenied s3   u{{E 2!!!S%>%>??r#ctjtjd}|j |tj S)zW C{errno.EACCES} should be translated to L{ftp.PermissionDeniedError}. r9)rr)r*EACCESrr1rs r!test_accessDeniedz%ErrnoToFailureTests.test_accessDenied s3   u||U 3!!!S%>%>??r#ctjtjd}|j |tj S)zW C{errno.ENOTDIR} should be translated to L{ftp.IsNotADirectoryError}. r9)rr)r*ENOTDIRrIsNotADirectoryErrorrs r!test_notDirectoryz%ErrnoToFailureTests.test_notDirectory s3   u}}e 4!!!S%=%=>>r#ctjtjd}|j |tj S)zQ C{errno.EEXIST} should be translated to L{ftp.FileExistsError}. r9)rr)r*EEXISTrFileExistsErrorrs r!test_fileExistsz#ErrnoToFailureTests.test_fileExists s3   u||U 3!!!S%8%899r#ctjtjd}|j |tj S)zS C{errno.EISDIR} should be translated to L{ftp.IsADirectoryError}. r9)rr)r*EISDIRrrrs r!test_isDirectoryz$ErrnoToFailureTests.test_isDirectory r.r#c td#t$r/tjdd}|j |tcYSwxYw)z If an unknown errno is passed to L{ftp.errnoToFailure}, it should let the originating exception pass through. r?rr9)rK BaseExceptionrr)rrs r!test_passThroughz$ErrnoToFailureTests.test_passThrough sF  7u% % 7""2u-A%%a6 6 7s 5AAN) r5r6r7rr-r2r5r9r=r@rCr3r#r!r'r' s,<@@?:< 7r#r'ceZdZdZdZy)AnonymousFTPShellTestsz* Test anonymous shell properties. ctjd}|jd}|j|tj|S)zt Check that L{ftp.FTPAnonymousShell} returns an error when trying to open it in write mode. rr9)rrrsrr1)r rrr?s r!test_anonymousWritez*AnonymousFTPShellTests.test_anonymousWrite s? %%b)   * 1c778r#N)r5r6r7rrHr3r#r!rErE s r#rEceZdZdZdZdZdZd'dZdZdZ dZ d Z d Z d Z d Zd ZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZdZ dZ!d Z"d!Z#d"Z$d#Z%d$Z&d%Z'y&)(IFTPShellTestsMixinz7 Generic tests for the C{IFTPShell} interface. ct)a  Test if the directory exists at C{path}. @param path: the relative path to check. @type path: C{str}. @return: C{True} if C{path} exists and is a directory, C{False} if it's not the case @rtype: C{bool} r r rs r!directoryExistsz#IFTPShellTestsMixin.directoryExists "##r#ct)z Create a directory in C{path}. @param path: the relative path of the directory to create, with one segment. @type path: C{str} rLrMs r!rDz#IFTPShellTestsMixin.createDirectory) s "##r#ct)a Test if the file exists at C{path}. @param path: the relative path to check. @type path: C{str}. @return: C{True} if C{path} exists and is a file, C{False} if it's not the case. @rtype: C{bool} rLrMs r! fileExistszIFTPShellTestsMixin.fileExists3 rOr#ct)a Create a file named C{path} with some content. @param path: the relative path of the file to create, without directory. @type path: C{str} @param fileContent: the content of the file. @type fileContent: C{str} rLr r fileContents r! createFilezIFTPShellTestsMixin.createFile@ rOr#c|j|jd|jd|j|jdy)z C{directoryExists} should report correctly about directory existence, and C{createDirectory} should create a directory detectable by C{directoryExists}. r?N)rrNrDrrs r!test_createDirectoryz(IFTPShellTestsMixin.test_createDirectoryM sB --e45 U# ,,U34r#c|j|jd|jd|j|jdy)z C{fileExists} should report correctly about file existence, and C{createFile} should create a file detectable by C{fileExists}. file.txtN)rrRrVrrs r!test_createFilez#IFTPShellTestsMixin.test_createFileW s< 45  #  34r#cfjjd}fd}|j|S)zI Create a directory and check it ends in the filesystem. rGcFjjdy)Nr9)rrNrBs r!r1z2IFTPShellTestsMixin.test_makeDirectory..cbf s OOD007 8r#)rrrrr4s` r!rz&IFTPShellTestsMixin.test_makeDirectory` s/ JJ $ $X . 9}}R  r#c|jd|jjd}|j|tj S)zm Creating a directory that already exists should fail with a C{ftp.FileExistsError}. r9rG)rDrrrrrr<rs r!test_makeDirectoryErrorz+IFTPShellTestsMixin.test_makeDirectoryErrork s? U# JJ $ $X .!!!S%8%899r#cjdjjd}fd}|j|S)zW Try to remove a directory and check it's removed from the filesystem. r?r?cFjjdyr>)rrNrBs r!r1z4IFTPShellTestsMixin.test_removeDirectory..cb{ s   T11%8 9r#)rDrrrrr4s` r!rz(IFTPShellTestsMixin.test_removeDirectoryt s= U# JJ & &x 0 :}}R  r#c|jd|jjd}|j|tj S)zn removeDirectory should not work in file and fail with a C{ftp.IsNotADirectoryError}. rZrZ)rVrrrrrr8rs r!test_removeDirectoryOnFilez.IFTPShellTestsMixin.test_removeDirectoryOnFile s=  # JJ & &} 5!!!S%=%=>>r#cx|jjd}|j|tjS)zl Removing directory that doesn't exist should fail with a C{ftp.FileNotFoundError}. ra)rrrrrr,rs r!test_removeNotExistingDirectoryz3IFTPShellTestsMixin.test_removeNotExistingDirectory s1 JJ & &x 0!!!S%:%:;;r#cjdjjd}fd}|j||S)zR Try to remove a file and check it's removed from the filesystem. rZrdcFjjdyNrZ)rrRr{s r!r1z/IFTPShellTestsMixin.test_removeFile..cb s   T__Z8 9r#)rVrrrrr4s` r!rz#IFTPShellTestsMixin.test_removeFile s=  # JJ ! !- 0 : br#c|jd|jjd}|j|tj S)z: removeFile should not work on directory. nedrl)rDrrrrrrrs r!test_removeFileOnDirectoryz.IFTPShellTestsMixin.test_removeFileOnDirectory s? U# JJ ! !( +!!!S%:%:;;r#cx|jjd}|j|tjS)zl Try to remove a non existent file, and check it raises a L{ftp.FileNotFoundError}. rG)rrrrrr,rs r!test_removeNotExistingFilez.IFTPShellTestsMixin.test_removeNotExistingFile s1 JJ ! !( +!!!S%:%:;;r#cjdjdjjd}fd}|j |S)z6 Check the output of the list method. rlrZ.cV|jj|dgfdgfgy)NrZrlrrr/r s r!r1z)IFTPShellTestsMixin.test_list..cb s* FFH   Q*b!1E2; ? @r#rDrVrrrrr4s` r! test_listzIFTPShellTestsMixin.test_list sH U#  # JJOOF # A}}R  r#cjdjdjjdd}fd}|j |S)z< Check the output of list with asked stats. rlrZrr)r permissionsc@|jjt|dj|dddj|dddjt|dddjt|dddy)NrrrZrrl)rrrrvs r!r1z1IFTPShellTestsMixin.test_listWithStat..cb s FFH   SVQ '   QqT!Wj 1   QqT!We ,   S1a\1 -   S1a\1 -r#rwr4s` r!test_listWithStatz%IFTPShellTestsMixin.test_listWithStat sO U#  # JJOO    .}}R  r#c|jd|jjdd}|j|tS)P Querying an invalid stat should result to a C{AttributeError}. rlrrr whateverstat)rDrrrrAttributeErrorrs r!test_listWithInvalidStatz,IFTPShellTestsMixin.test_listWithInvalidStat sA U# JJOO   !!!^44r#cjdjjd}fd}|j|S)z@ Check the output of the list method on a file. rZrdcP|jj|dgfgyrjrurvs r!r1z-IFTPShellTestsMixin.test_listFile..cb s$ FFH   Q*b!1 2 3r#)rVrrrrr4s` r! test_listFilez!IFTPShellTestsMixin.test_listFile s9  # JJOOM * 4}}R  r#cx|jjd}|j|tjS)zm list on a directory that doesn't exist should fail with a L{ftp.FileNotFoundError}. rG)rrrrrr,rs r!test_listNotExistingDirectoryz1IFTPShellTestsMixin.test_listNotExistingDirectory s/ JJOOH %!!!S%:%:;;r#c^|jd|jjd}|S)z+ Try to access a resource. rlrm)rDrraccessrs r! test_accesszIFTPShellTestsMixin.test_access s+ U# JJ  h 'r#cx|jjd}|j|tjS)zF access should fail on a resource that doesn't exist. rG)rrrrrr,rs r!test_accessNotFoundz'IFTPShellTestsMixin.test_accessNotFound s1 JJ  h '!!!S%:%:;;r#cjdjjd}fd}|j||S)zY Check that openForReading returns an object providing C{ftp.IReadFile}. rZrdcbjtjj|yr)rr IReadFile providedByr{s r!r1z3IFTPShellTestsMixin.test_openForReading..cb s OOCMM44S9 :r#)rVrrrrr4s` r!test_openForReadingz'IFTPShellTestsMixin.test_openForReading s=  # JJ % %m 4 ; br#cx|jjd}|j|tjS)zr openForReading should fail with a C{ftp.FileNotFoundError} on a file that doesn't exist. rm)rrrrrr,rs r!test_openForReadingNotFoundz/IFTPShellTestsMixin.test_openForReadingNotFound s1 JJ % %h /!!!S%:%:;;r#c|jd|jjd}|j|tj S)z> openForReading should not work on directory. rlrm)rDrrrrrrrs r!test_openForReadingOnDirectoryz2IFTPShellTestsMixin.test_openForReadingOnDirectory s? U# JJ % %h /!!!S%:%:;;r#cxjjd}fd}fd|j||S)zZ Check that openForWriting returns an object providing C{ftp.IWriteFile}. rGcjtjj||j j Sr)rr IWriteFilerrr)r|cb2r s r!cb1z4IFTPShellTestsMixin.test_openForWriting..cb1+ s5 OOCNN55c: ;;;=,,S1 1r#cNjtj|yr)rrrr{s r!rz4IFTPShellTestsMixin.test_openForWriting..cb2/ s OOI005 6r#)rrrsr)r r?rrs` @r!test_openForWritingz'IFTPShellTestsMixin.test_openForWriting% s6 JJ % %h / 2 7 cr#c|jd|jjd}|j|tj S)zd openForWriting should not be able to open a directory that already exists. rlrm)rDrrrsrrrrs r!$test_openForWritingExistingDirectoryz8IFTPShellTestsMixin.test_openForWritingExistingDirectory5 s? U# JJ % %h /!!!S%:%:;;r#c|jd|jjd}|j|tj S)z openForWring should fail with a L{ftp.FileNotFoundError} if you specify a file in a directory that doesn't exist. rl)rl idonotexistr9)rDrrrsrrr,rs r!)test_openForWritingInNotExistingDirectoryz=IFTPShellTestsMixin.test_openForWritingInNotExistingDirectory> s@ U# JJ % %&C D!!!S%:%:;;r#cdjdjjdd}fd}|j||S)z@ Check the output of the stat method on a file. wobble rZrdrrkcjj|dtj|dy)Nrr)rrr)r|rUr s r!r1z-IFTPShellTestsMixin.test_statFile..cbO s.   SVS%5 6   SV $r#)rVrrstatr)r r?r1rUs` @r! test_statFilez!IFTPShellTestsMixin.test_statFileG sE"   K0 JJOOM+@ A % br#cjdjjdd}fd}|j||S)zE Check the output of the stat method on a directory. rlrmrc.j|dy)Nr)rr{s r!r1z2IFTPShellTestsMixin.test_statDirectory..cb] s OOCF #r#rDrrrrr4s` r!test_statDirectoryz&IFTPShellTestsMixin.test_statDirectoryV s@ U# JJOOH&; < $ br#cjdjjdd}fd}|j||S)z3 Check the owner and groups stats. rlrmrrc<jt|dy)Nrrr{s r!r1z3IFTPShellTestsMixin.test_statOwnerGroup..cbj s   SXq )r#rr4s` r!test_statOwnerGroupz'IFTPShellTestsMixin.test_statOwnerGroupc s@ U# JJOOH&8 9 * br#c|jjdfd}||j_|jd|jjdd}|j |j |dgy)z If L{twisted.python.filepath.FilePath.getNumberOfHardLinks} is not implemented, the number returned is 0 ctrrLr3r#r!raiseNotImplementedzQIFTPShellTestsMixin.test_statHardlinksNotImplemented..raiseNotImplementedw % %r#c&|}|_|Sr)getNumberOfHardLinksrr&pathFuncrs r!notImplementedFilePathzTIFTPShellTestsMixin.test_statHardlinksNotImplemented..notImplementedFilePathz sA%8A "Hr#rlrm) hardlinksrNrr_pathrDrrsuccessResultOfr rr?rrs @@r! test_statHardlinksNotImplementedz4IFTPShellTestsMixin.test_statHardlinksNotImplementedp sk ::## &  2  U# JJOOHn 5 --a01#6r#c|jjdfd}||j_|jd|jjdd}|j |j |ddgy)z If L{twisted.python.filepath.FilePath.getUserID} or L{twisted.python.filepath.FilePath.getGroupID} are not implemented, the owner returned is "0" and the group is returned as "0" ctrrLr3r#r!rzRIFTPShellTestsMixin.test_statOwnerGroupNotImplemented..raiseNotImplemented rr#c4|}|_|_|Sr) getUserID getGroupIDrs r!rzUIFTPShellTestsMixin.test_statOwnerGroupNotImplemented..notImplementedFilePath sA-AK.ALHr#rlrmr0Nrrs @@r!!test_statOwnerGroupNotImplementedz5IFTPShellTestsMixin.test_statOwnerGroupNotImplemented sn ::## &  2  U# JJOOH&8 9 --a03*=r#cz|jjdd}|j|tjS)zf stat should fail with L{ftp.FileNotFoundError} on a file that doesn't exist. rGr)rrrrrr,rs r!test_statNotExistingz(IFTPShellTestsMixin.test_statNotExisting s2 JJOOH&; <!!!S%:%:;;r#c|jd|jjdd}|j|tS)r~rlrmr)rDrrrrrrs r!test_invalidStatz$IFTPShellTestsMixin.test_invalidStat s: U# JJOOH&> ?!!!^44r#cjdjjdd}fd}|j|S)z, Try to rename a directory. rlrmrGcjjdjjdy)Nr9rl)rrNrr{s r!r1z+IFTPShellTestsMixin.test_rename..cb s3 OOD007 8   T11%8 9r#)rDrrrxrr4s` r! test_renamezIFTPShellTestsMixin.test_rename s? U# JJ  h 1 :}}R  r#cz|jjdd}|j|tjS)zl Renaming a directory that doesn't exist should fail with L{ftp.FileNotFoundError}. rGra)rrrxrrr,rs r!test_renameNotExistingz*IFTPShellTestsMixin.test_renameNotExisting s3 JJ  h 1!!!S%:%:;;r#Nr#)(r5r6r7rrNrDrRrVrXr[rr_rrergrrnrprxr|rrrrrrrrrrrrrrrrrrrrr3r#r!rJrJ s $$ $ $55 !: !?< << !!4 5 !<< << <<   7*>.<5 !.cbGetIs;;x(44V< .cbSendLs   SXXhoo6 @r#)rrr)r rrrrs` @@@r! test_readzIReadWriteTestsMixin.test_read@s: > = A!!'*66u==r#cndfd}fdfdjj|S)a Test L{ftp.IWriteFile}: the implementation should have a receive method returning a C{Deferred} which fires with a consumer ready to receive data to be written. It should also have a close() method that returns a Deferred. selbbow cD|jj|Sr)rr)writer cbReceives r!rz.IReadWriteTestsMixin.test_write..cbGetZs>>#// 6B Br#ct|}|jdd|j|j|j j S)NT)rrrrcloser)rrrcbClosers r!rz2IReadWriteTestsMixin.test_write..cbReceive]sL#GX6H  % %dD 1 NN   ' ' )<<>--g6 6r#cFjjyr)rr)rrr s r!rz0IReadWriteTestsMixin.test_write..cbCloseds   T002G "7r#rc(eZdZdZdZdZdZdZy)FTPReadWriteTestsz Tests for C{ftp._FileReader} and C{ftp._FileWriter}, the objects returned by the shell in C{openForReading}/C{openForWriting}. ctj|j|_|jj t j |j|_d|_y)z5 Create a temporary file used later. rZN) rrnrjrrDrrrrrrs r!rzFTPReadWriteTests.setUppsG%%dkkm4  !!#\\$)), " r#c|jj|jj||jj |jfS)zV Return a C{ftp._FileReader} instance with a file opened for reading. )rr@rrrrrrs r!rzFTPReadWriteTests.getFileReaderys?  &11':zz(($--)9::r#cN|jj|jfS)zV Return a C{ftp._FileWriter} instance with a file opened for writing. )rrrsrrs r!rzFTPReadWriteTests.getFileWriters zz(($--)9::r#ch|jj|jjS)z; Return the content of the temporary file. )rr@r getContentrs r!rz FTPReadWriteTests.getFileContents$yyt}}-88::r#N)r5r6r7rrrrrr3r#r!rrjs #;; ;r#rc eZdZdZdZdZdZy)CloseTestWriterz" Close writing to a file. Fct|_tj|j}t j |S)z> Receive bytes. @return: L{Deferred} )rr=r FileConsumerr r)r fcs r!rzCloseTestWriter.receives0 i   dkk *}}R  r#c(d|_|jS)z< Close bytes. @return: L{Deferred} T) closeStartedr?rs r!rzCloseTestWriter.closes !vv r#N)r5r6r7rrrrr3r#r!r r sL!r#r ceZdZdZdZy)CloseTestShellz Close writing shell. c@tj|jSr)r rr)r segss r!rszCloseTestShell.openForWritings}}T[[))r#N)r5r6r7rrsr3r#r!rrs *r#rceZdZdZdZy) FTPCloseTestsz8 Tests that the server invokes IWriteFile.close c\tj}dg|_t|_t |j_tj|jj _ tj|_ d|j_ |jttj}tj ||_ ||_|jdg}|j%d}|j'|j(|j+|jj j,d|j/d|j+|jj j,d|j1d|j3|jj j,d|j+||jj jj5d|j3||S) z Confirm that FTP uploads (i.e. ftp_STOR) correctly call and wait upon the IWriteFile object's close() method rNrzclose() called earlyssome data herezreason is ignoredzclose() not calledzallow close() to finish)rFTPworkingDirectoryrrrr rr r>r?rzr%timeOutrdrrOrCriftp_STORrr)rrrBrFrrD)r r&di stor_doner?s r!rzFTPCloseTests.test_writesz GGI$X "(* >>+NN$    # WWY^^A&   $ JJv  i&&' 446LM )* 446LM -. 335IJ # !!";<  "r#N)r5r6r7rrr3r#r!rrs !r#rceZdZdZdZy)FTPResponseCodeTestsz4 Tests relating directly to response codes. c rttj}t}ttj D]t\}}t |t s|js(|j||dj|||j||d|d||j|vy)z All of the response code globals (for example C{RESTART_MARKER_REPLY} or C{USR_NAME_OK_NEED_PASS}) have unique values and are present in the C{RESPONSE} dictionary. z4Code {!r} with value {!r} missing from RESPONSE dictzDuplicate code z with value N) setrRESPONSEvarsitems isinstancer!isupperr^r assertNotInadd)r allValues seenValueskeyrs r! test_uniquez FTPResponseCodeTests.test_uniques  % U s)//+ &JC%%#++- JQQU  %cWL B u% &r#N)r5r6r7rr-r3r#r!r r s &r#r )rVr)Qrr*rrlrriorzope.interfacerzope.interface.verifyr twisted.credrrrtwisted.cred.errorr twisted.cred.portalr twisted.internetr r r rrtwisted.internet.interfacesrtwisted.protocolsrrrtwisted.pythonrrr twisted.testrtwisted.trial.unittestrplatform isWindowsr$ LineReceiverrrr:rNrPrrrwrrr:r^rjrrrorvrrrrrrr rr'rErJrrrrrrr rrr r3r#r!r=ss  &-660&BB12255&+!!#L*L E   ( **  *K K \ ) 2G+GTp#4pff,'8f,R O,'GO,d~h~B":x":P ("" ( C33 J$(J$Z>>Bm.Xm.`u;(u;pIKIKXKKD4Q4QnMHM4&K(&KR87(87v X  h<h