Your IP : 216.73.216.213


Current Path : /opt/alt/python37/lib64/python3.7/site-packages/twisted/test/__pycache__/
Upload File :
Current File : //opt/alt/python37/lib64/python3.7/site-packages/twisted/test/__pycache__/test_ftp.cpython-37.pyc

B

;��]��@sfdZddlZddlZddlmZddlZddlZddlZddlm	Z	ddl
mZddlm
Z
mZmZddlmZddlmZdd	lmZmZmZmZmZdd
lmZddlmZddlmZm Z m!Z!dd
l"m#Z#ddl$m%Z%ddl&m'Z'ddlm(Z(m)Z)e!j*�+��r
dZ,ndZ,Gdd�dej-�Z.Gdd�dej/�Z0dXdd�Z1Gdd�de'j2�Z3Gdd�de3�Z4Gdd�de3�Z5Gd d!�d!e3�Z6Gd"d#�d#e3�Z7Gd$d%�d%e7�Z8Gd&d'�d'e'j2�Z9Gd(d)�d)e'j2�Z:Gd*d+�d+ej/�Z;Gd,d-�d-e(j<�Z=Gd.d/�d/e'j2�Z>Gd0d1�d1e'j2�Z?Gd2d3�d3e'j2�Z@Gd4d5�d5e'j2�ZAGd6d7�d7e'j2�ZBGd8d9�d9e'j2�ZCGd:d;�d;e'j2�ZDGd<d=�d=e'j2�ZEGd>d?�d?e'j2�ZFGd@dA�dAe'j2�ZGGdBdC�dCe'j2�ZHGdDdE�dE�ZIGdFdG�dGe'j2eI�ZJe	e�GdHdI�dIeK��ZLGdJdK�dKeK�ZMGdLdM�dM�ZNGdNdO�dOe'j2eN�ZOe	e(jP�GdPdQ�dQ��ZQGdRdS�dS�ZRGdTdU�dUe'j2�ZSGdVdW�dWe'j2�ZTdS)Yz
FTP tests.
�N)�BytesIO)�implementer)�verifyClass)�portal�checkers�credentials)�UnauthorizedLogin)�IRealm)�reactor�task�protocol�defer�error)�	IConsumer)�basic)�failure�filepath�runtime)�range)�
proto_helpers)�unittest)�ftp�loopbackzCannot run on Windowsc@s8eZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�ZdS)�DummyNcCsg|_g|_dS)N)�lines�rawData)�self�r�H/opt/alt/python37/lib64/python3.7/site-packages/twisted/test/test_ftp.py�__init__)szDummy.__init__cCs|j|_dS)N)�factory�f)rrrr�connectionMade.szDummy.connectionMadecCs|j�|�dS)N)r�append)r�linerrr�lineReceived2szDummy.lineReceivedcCs|j�|�dS)N)rr#)r�datarrr�rawDataReceived6szDummy.rawDataReceivedcCsdS)Nr)rr$rrr�lineLengthExceeded:szDummy.lineLengthExceeded)	�__name__�
__module__�__qualname__Zlognamerr"r%r'r(rrrrr'src@s$eZdZdd�Zdd�Zdd�ZdS)�_BufferingProtocolcCsd|_t��|_dS)N�)�bufferr
�Deferred�d)rrrrr"@sz!_BufferingProtocol.connectionMadecCs|j|7_dS)N)r.)rr&rrr�dataReceivedEsz_BufferingProtocol.dataReceivedcCs|j�|�dS)N)r0�callback)r�reasonrrr�connectionLostIsz!_BufferingProtocol.connectionLostN)r)r*r+r"r1r4rrrrr,?sr,�	127.0.0.1�90cCsdt�||�f}|�|j�S)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 (%s).)r�encodeHostPort�encode�	_encoding)r�host�port�msgrrr�passivemode_msgNs	r=c@sFeZdZdZejZdZdd�Zddd�Z	ddd	�Z
d
d�Zdd
�ZdS)�FTPServerTestCasezw
    Simple tests for an FTP server with the default settings.

    @ivar clientFactory: class used as ftp client.
    �	anonymousc	s>g�����_t��j�t��j��_t�t	j
�j�jd��}|�t�
�tj�t��}d�_d�_|��j�j�|�|tj�t	j|�jd��_tjd�jdd��_}��|j��jj�t�������fdd	�}|�j_|� �j}t!�"t�j#�}|�$d|�}��fd
d�}|�%|���t&j't��t�(�|g�S)N)Z
anonymousRootZuserHomez	test-userz
test-password)r�
userAnonymousrz	127.0.0.1)�	interfacecsD�j`�|�}|j�_�fdd�}��|���d���|�|S)Ncs�jjdk	r�jj��dS)N)�serverProtocol�	transport�loseConnectionr)rrr�
cleanupServer�szQFTPServerTestCase.setUp.<locals>._rememberProtocolInstance.<locals>.cleanupServer)r �
buildProtocol�wrappedProtocolrB�
addCleanupr2r#)�addrrrE)rF�d1�	protocolsrrr�_rememberProtocolInstance�s


z:FTPServerTestCase.setUp.<locals>._rememberProtocolInstancecs&|�_���jjj����j�dS)N)�clientrHrCrDr#)rM)rKrrr�	gotClient�sz*FTPServerTestCase.setUp.<locals>.gotClient))�mktemp�	directory�os�mkdirr�FilePath�dirPathrZPortalr�FTPRealm�registerCheckerrZAllowAnonymousAccessrZ
IAnonymous�'InMemoryUsernamePasswordDatabaseDontUse�username�passwordZaddUser�IUsernamePassword�
FTPFactoryr@r r
�	listenTCPr;rH�
stopListeningrFr
r/�getHostr�
ClientCreator�
clientFactory�
connectTCP�addCallbackrZwaitUntilAllDisconnected�
gatherResults)	r�pZ
users_checkerr;rL�portNumZ
clientCreator�d2rNr)rFrJrKrr�setUpes>




zFTPServerTestCase.setUpNcs,|dkrt�d�}���fdd�}|�|�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.
        Ncs$�j���}��fdd�}|�|�S)Ncs���|�dS)N)�assertEqual)�
responseLines)�expectedResponseLinesrrr�gotResponse�szRFTPServerTestCase.assertCommandResponse.<locals>.queueCommand.<locals>.gotResponse)rM�queueStringCommandrb)�ignoredr0rk)�commandrjrrr�queueCommand�sz=FTPServerTestCase.assertCommandResponse.<locals>.queueCommand)r
�succeedrb)rrnrj�
chainDeferredror)rnrjrr�assertCommandResponse�s	
z'FTPServerTestCase.assertCommandResponsecsP|dkrt�d�}��fdd�}|�|���|tj���fdd�}|�|�S)Ncs�j���S)N)rMrl)rm)rnrrrro�sz;FTPServerTestCase.assertCommandFailed.<locals>.queueCommandcs�dk	r���|jd�dS)Nr)rh�args)�	exception)�expectedResponserrr�failed�sz5FTPServerTestCase.assertCommandFailed.<locals>.failed)r
rprb�
assertFailurer�
CommandFailed)rrnrurqrorvr)rnrurr�assertCommandFailed�s

z%FTPServerTestCase.assertCommandFailedcCs |�ddg�}|jddg|d�S)NzUSER anonymousz8331 Guest login ok, type your email address as password.zPASS test@twistedmatrix.comz2230 Anonymous login ok, access restrictions apply.)rq)rr)rr0rrr�_anonymousLogin�sz!FTPServerTestCase._anonymousLogincCs2|�d|jd|jg�}|jd|jdg|d�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, proceed)rq)rrrXrY)rr0rrr�
_userLogin�szFTPServerTestCase._userLogin)N)NN)
r)r*r+�__doc__r�FTPClientBasicr`r@rgrrryrzr{rrrrr>\sA


r>c@seZdZdZdZdd�ZdS)�FTPAnonymousTestsz�
    Simple tests for an FTP server with different anonymous username.
    The new anonymous username used in this test case is "guest"
    ZguestcCs |�ddg�}|jddg|d�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 guestz8331 Guest login ok, type your email address as password.zPASS test@twistedmatrix.comz2230 Anonymous login ok, access restrictions apply.)rq)rr)rr0rrr�test_anonymousLogin�sz%FTPAnonymousTests.test_anonymousLoginN)r)r*r+r|r@rrrrrr~�sr~c@s�eZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd�Zd d!�Zd"d#�Zd$d%�Zd&d'�Zd(d)�Zd*d+�Zd,d-�Zd.d/�Zd0d1�Zd2d3�Zd4d5�Zd6S)7�BasicFTPServerTestsz,
    Basic functionality of FTP server.
    csLd�j_t�tt�}|�d�j��j�}|j	dd��}|j	�fdd��}|S)zn
        When the connection limit is reached, the server should send an
        appropriate response
        �z	127.0.0.1cSs|jS)N)r0)�protorrrrNsz>BasicFTPServerTests.test_tooManyConnections.<locals>.gotClientcs��d|j�dS)Ns;421 Too many users right now, try again in a few minutes.
)rhr.)r�)rrr�onConnectionLostszEBasicFTPServerTests.test_tooManyConnections.<locals>.onConnectionLost)
r ZconnectionLimitrr_r
r,rar;r^rb)r�ccr0rNr�r)rr�test_tooManyConnections�sz+BasicFTPServerTests.test_tooManyConnectionsc
s�ddddddddd	d
g
}dg}�fdd
�}�fdd�}g}x<|D]4}�j�|�}��|tj�|�||�|�|�q@Wx.|D]&}�j�|�}|�||�|�|�q~Wtj|dd�S)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.
        ZCDUPZCWD�LISTZMODE�PASV�PWDZRETRZSTRU�SYSTZTYPE�FEATcs0|jd}��|d�d�d||df�dS)Nr����530z'%s - Response didn't start with 530: %r)rs�
assertTrue�
startswith)rtrnZfailureResponseLines)rrr�checkFailResponse s
zDBasicFTPServerTests.test_NotLoggedInReply.<locals>.checkFailResponsecs&|d}��|�d�d||f�dS)Nrr�z %s - Response start with 530: %r)�assertFalser�)�resultrn)rrr�checkPassResponse&szDBasicFTPServerTests.test_NotLoggedInReply.<locals>.checkPassResponseT)�fireOnOneErrback)	rMrlrwrrxrbr#r
�DeferredList)rZloginRequiredCommandListZloginNotRequiredCommandListr�r�Z	deferredsrn�deferredr)rr�test_NotLoggedInReplys 


z)BasicFTPServerTests.test_NotLoggedInReplycCs|�ddg�S)z@
        Issuing PASS before USER should give an error.
        zPASS fooz=503 Incorrect sequence of commands: USER required before PASS)ry)rrrr�test_PASSBeforeUSER;sz'BasicFTPServerTests.test_PASSBeforeUSERcCs|�ddg�S)zD
        Issuing USER without a username is a syntax error.
        ZUSERz,500 Syntax error: USER requires an argument.)ry)rrrr�test_NoParamsForUSEREsz(BasicFTPServerTests.test_NoParamsForUSERcCs|j�d�}|jddg|d�S)zD
        Issuing PASS without a password is a syntax error.
        zUSER fooZPASSz,500 Syntax error: PASS requires an argument.)rq)rMrlry)rr0rrr�test_NoParamsForPASSNs
z(BasicFTPServerTests.test_NoParamsForPASScsFdd�}|�jj_�j�d�}�jddg|d�|j�fdd��}|S)	zI
        Unexpected exceptions from the login handler are caught
        c_st�td��S)Nztest exception)r
�fail�AssertionError)rs�kwargsrrr�_fake_loginhandler]sz?BasicFTPServerTests.test_loginError.<locals>._fake_loginhandlerzUSER foozPASS barz5550 Requested action not taken: internal server error)rqcs.���}��dt|����|djt�dS)Nr�r)�flushLoggedErrorsrh�len�assertIsInstance�valuer�)r��logs)rrr�	checkLogsgsz6BasicFTPServerTests.test_loginError.<locals>.checkLogs)rBrZloginrMrlryrb)rr�r0r�r)rr�test_loginErrorYs
z#BasicFTPServerTests.test_loginErrorcCs|��S)z/
        Login with userid 'anonymous'
        )rz)rrrr�test_AnonymousLoginpsz'BasicFTPServerTests.test_AnonymousLogincCs|��}|jddg|d�S)zm
        Issuing QUIT should return a 221 message.

        @return: L{Deferred} of command response
        ZQUITz221 Goodbye.)rq)rzrr)rr0rrr�	test_Quitws
zBasicFTPServerTests.test_QuitcCsXd|j_t��}|jj�|tj�|�ddg�}|j	ddg|d�}|j	ddg|d�}|S)	z�
        Reconfigure the server to disallow anonymous access, and to have an
        IUsernamePassword checker that always rejects.

        @return: L{Deferred} of command response
        FzUSER anonymousz$331 Password required for anonymous.zPASS test@twistedmatrix.comz!530 Sorry, Authentication failed.)rqr�z$530 Please login with USER and PASS.)
r ZallowAnonymousrrWrrVrrZrrry)rZdenyAlwaysCheckerr0rrr�test_AnonymousLoginDenied�s 
z-BasicFTPServerTests.test_AnonymousLoginDeniedcCs|��}|jddg|d�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 filesystem)rq)rzry)rr0rrr�test_anonymousWriteDenied�s
z-BasicFTPServerTests.test_anonymousWriteDeniedcCs|��}|jddg|d�S)z\
        Send an invalid command.

        @return: L{Deferred} of command response
        Z	GIBBERISHz'502 Command 'GIBBERISH' not implemented)rq)rzry)rr0rrr�test_UnknownCommand�s
z'BasicFTPServerTests.test_UnknownCommandcCs|��}|jddg|d�S)zb
        Send RETR before sending PORT.

        @return: L{Deferred} of command response
        zRETR foozE503 Incorrect sequence of commands: PORT or PASV required before RETR)rq)rzry)rr0rrr�test_RETRBeforePORT�s
z'BasicFTPServerTests.test_RETRBeforePORTcCs|��}|jddg|d�S)zb
        Send STOR before sending PORT.

        @return: L{Deferred} of command response
        zSTOR foozE503 Incorrect sequence of commands: PORT or PASV required before STOR)rq)rzry)rr0rrr�test_STORBeforePORT�s
z'BasicFTPServerTests.test_STORBeforePORTcCs0|��}|jddg|d�|jddg|d�|S)zd
        Send command with bad arguments.

        @return: L{Deferred} of command response
        zMODE zz&504 Not implemented for parameter 'z'.)rqzSTRU Iz&504 Not implemented for parameter 'I'.)rzry)rr0rrr�test_BadCommandArgs�sz'BasicFTPServerTests.test_BadCommandArgscCs`|�t�d�d�td�}x@td�D]4}t|�}d||<d�tt|��}|�t	tj|�q$WdS)z%
        Decode a host port.
        z25,234,129,22,100,23)z
25.234.129.22id���,N)
rhr�decodeHostPortr�list�join�map�str�assertRaises�
ValueError)r�nums�iZbadValue�srrr�test_DecodeHostPort�sz'BasicFTPServerTests.test_DecodeHostPortcsF���}|��fdd���fdd�}|�|�|��fdd��|S)z�
        When the client sends the command C{PASV}, the server responds with a
        host and port, and is listening on that port.
        cs�j�d�S)Nr�)rMrl)�_)rrr�<lambda>r-z/BasicFTPServerTests.test_PASV.<locals>.<lambda>cs4t�|ddd��\}}��|�jj��j�dS)z�
            Extract the host and port from the resonse, and
            verify the server is listening of the port it claims to be.
            r��N)rr�rhrBZdtpPortr^r;)rir:r;)rrr�cbsz)BasicFTPServerTests.test_PASV.<locals>.cbcs�jj��S)N)rBrCrD)r�)rrrr�r-)rzrb)rr0r�r)rr�	test_PASV�s
zBasicFTPServerTests.test_PASVcCs|��}|jddg|d�|S)z?
        SYST command will always return UNIX Type: L8
        r�z215 UNIX Type: L8)rq)rzrr)rr0rrr�	test_SYSTs
zBasicFTPServerTests.test_SYSTcsp�j��j����j��j��d������}�jddg|d��jddg|d��fdd�}|�|�|S)	z�
        Sending the RNFR command followed by RNTO, with valid filenames, will
        perform a successful rename operation.
        �foozRNFR fooz6350 Requested file action pending further information.)rqzRNTO barz&250 Requested File Action Completed OKcs"���j��j��d����|S)N�bar)r�rT�childrX�exists)r�)rrr�check_rename-sz:BasicFTPServerTests.test_RNFRandRNTO.<locals>.check_rename)rTr�rX�createDirectory�touchr{rrrb)rr0r�r)rr�test_RNFRandRNTOs
z$BasicFTPServerTests.test_RNFRandRNTOcCs0|��}|jddg|d�|jddg|d�|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.
        zRNFR fooz6350 Requested file action pending further information.)rqzOTHER don-tcarez<503 Incorrect sequence of commands: RNTO required after RNFR)rzrrry)rr0rrr�test_RNFRwithoutRNTO6sz(BasicFTPServerTests.test_RNFRwithoutRNTOcCs*dd�}||j_|�t|jjt���dS)z�
        Exceptions other than L{error.CannotListenError} which are raised by
        C{listenFactory} should be raised to the caller of L{FTP.getDTPPort}.
        cSs
t��dS)N)�RuntimeError)�
portNumberr rrr�
listenFactoryMszEBasicFTPServerTests.test_portRangeForwardError.<locals>.listenFactoryN)rBr�r�r��
getDTPPortr�Factory)rr�rrr�test_portRangeForwardErrorHsz.BasicFTPServerTests.test_portRangeForwardErrorcCs�dd�}||j_|j�t���}|�|d�tdd�|j_|j�t���}|�|d�tdd�|j_|�t	j
|jjt���dS)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.
        cSs|dkrt�d|d��|S)N)iViViVZ	localhostr)r�CannotListenError)r�r rrrr�\sz9BasicFTPServerTests.test_portRange.<locals>.listenFactoryriViiVN)rBr�r�rr�rhr�passivePortRanger�rr�)rr�r;rrr�test_portRangeUsz"BasicFTPServerTests.test_portRangecCs2tdd�}||j_|j�d�}|�||jj�dS)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.
        i�i�N)rr r�rFrhrG)rZ	portRangerrrr�"test_portRangeInheritedFromFactoryos
z6BasicFTPServerTests.test_portRangeInheritedFromFactorycs"�j�d�}�fdd�}|�|�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.)
        r�csT��d|d���d|���d|���d|���d|���d|d�dS)	Nz
211-Features:rz MDTMz PASVz	 TYPE A;Iz SIZEz211 Endr�)rh�assertIn)ri)rrrrk�sz2BasicFTPServerTests.test_FEAT.<locals>.gotResponse)rMrlrb)rr0rkr)rr�	test_FEAT{szBasicFTPServerTests.test_FEATcCs|��}|jddg|d�|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.)rq)rzry)rr0rrr�	test_OPTS�szBasicFTPServerTests.test_OPTScst�j��j����j��j��d������}�fdd�}�fdd�}|�|�|�|��jddg|d�|S)	zl
        Any FTP error raised inside STOR while opening the file is returned
        to the client.
        Zfoldercs�j�d�S)zE
            Send the PASV command required before port.
            r�)rMrl)r�)rrr�sendPASV�szCBasicFTPServerTests.test_STORreturnsErrorFromOpen.<locals>.sendPASVcs�jjj�d�t��j_|S)z�
            Fake an incoming connection and create a mock DTPInstance so
            that PORT command will start processing the request.
            N)rB�
dtpFactoryr�r2�object�dtpInstance)r�)rrr�mockDTPInstance�s
zJBasicFTPServerTests.test_STORreturnsErrorFromOpen.<locals>.mockDTPInstancezSTOR folderz550 folder: is a directory)rq)rTr�rXr�r{rbry)rr0r�r�r)rr�test_STORreturnsErrorFromOpen�s	

z1BasicFTPServerTests.test_STORreturnsErrorFromOpencsj���}dd���fdd�}��fdd�}�fdd�}|�|�|�|��jd	d
g|d�|�|�|S)z�
        Any non FTP error raised inside STOR while opening the file is
        converted into FileNotFound error and returned to the client together
        with the path.

        The unknown error is logged.
        cSst�t��S)z�
            Override openForWriting.

            @param ignore: ignored, used for callback
            @return: an error
            )r
r�r�)�ignorerrr�failingOpenForWriting�sz[BasicFTPServerTests.test_STORunknownErrorBecomesFileNotFound.<locals>.failingOpenForWritingcs�j�d�S)z
            Send the PASV command required before port.

            @param result: parameter used in L{Deferred}
            r�)rMrl)r�)rrrr��szNBasicFTPServerTests.test_STORunknownErrorBecomesFileNotFound.<locals>.sendPASVcs(�jjj�d�t��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)rBr�r�r2r�r��shell�openForWriting)r�)r�rrrr��s

zUBasicFTPServerTests.test_STORunknownErrorBecomesFileNotFound.<locals>.mockDTPInstancecs.���}��dt|����|djt�dS)zy
            Check that unknown errors are logged.

            @param result: parameter used in L{Deferred}
            r�rN)r�rhr�r�r�r�)r�r�)rrrr��szOBasicFTPServerTests.test_STORunknownErrorBecomesFileNotFound.<locals>.checkLogszSTOR somethingz)550 something: No such file or directory.)rq)r{rbry)rr0r�r�r�r)r�rr�(test_STORunknownErrorBecomesFileNotFound�s	



z<BasicFTPServerTests.test_STORunknownErrorBecomesFileNotFoundN)r)r*r+r|r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rrrrr��s6%
	



%r�c@s6eZdZdZejZdd�Zdd�Zdd�Z	dd	�Z
d
S)�FTPServerAdvancedClientTestsz:
    Test FTP server with the L{ftp.FTPClient} class.
    cs4�fdd�}�j�d�\}}|�|�t�||g�S)zl
        Try to make an STOR as anonymous, and check that we got a permission
        denied error.
        cs(|�tj���|jjddd�dS)Nrz550 foo: Permission denied.)�traprrxrhr�rs)�res)rrr�ebsz;FTPServerAdvancedClientTests.test_anonymousSTOR.<locals>.ebr�)rM�	storeFile�
addErrbackr
rc)rr�rJrfr)rr�test_anonymousSTORs
z/FTPServerAdvancedClientTests.test_anonymousSTORcsbGdd�dtj���fdd�}��tjd|��fdd�}�j�d�\}}|�|�t�||g�S)	zm
        Any FTP error raised by STOR while transferring the file is returned
        to the client.
        c@seZdZdd�ZdS)zXFTPServerAdvancedClientTests.test_STORtransferErrorIsReturned.<locals>.FailingFileWritercSst�t�d��S)N�failing_file)r
r�r�IsADirectoryError)rrrr�receivesz`FTPServerAdvancedClientTests.test_STORtransferErrorIsReturned.<locals>.FailingFileWriter.receiveN)r)r*r+r�rrrr�FailingFileWritersr�cst��d��S)N)r
rp)�a�b)r�rr�failingSTORszRFTPServerAdvancedClientTests.test_STORtransferErrorIsReturned.<locals>.failingSTORr�csT|�tj����}��dt|����|djtj���|jj	ddd�dS)Nr�rz 550 failing_file: is a directory)
r�rrxr�rhr�r�r�r�rs)r�r�)rrrr�"szIFTPServerAdvancedClientTests.test_STORtransferErrorIsReturned.<locals>.ebr�)	r�_FileWriter�patch�FTPAnonymousShellrMr�r�r
rc)rr�r�rJrfr)r�rr� test_STORtransferErrorIsReturneds
z=FTPServerAdvancedClientTests.test_STORtransferErrorIsReturnedcsbGdd�dtj���fdd�}��tjd|��fdd�}�j�d�\}}|�|�t�||g�S)	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.
        c@seZdZdd�ZdS)zaFTPServerAdvancedClientTests.test_STORunknownTransferErrorBecomesAbort.<locals>.FailingFileWritercSst�t��S)N)r
r�r�)rrrrr�7sziFTPServerAdvancedClientTests.test_STORunknownTransferErrorBecomesAbort.<locals>.FailingFileWriter.receiveN)r)r*r+r�rrrrr�6sr�cst��d��S)N)r
rp)r�r�)r�rrr�:sz[FTPServerAdvancedClientTests.test_STORunknownTransferErrorBecomesAbort.<locals>.failingSTORr�csR|�tj����}��dt|����|djt���|jj	ddd�dS)Nr�rz.426 Transfer aborted.  Data connection closed.)
r�rrxr�rhr�r�r�r�rs)r�r�)rrrr�AszRFTPServerAdvancedClientTests.test_STORunknownTransferErrorBecomesAbort.<locals>.ebr�)	rr�r�r�rMr�r�r
rc)rr�r�rJrfr)r�rr�)test_STORunknownTransferErrorBecomesAbort/s
zFFTPServerAdvancedClientTests.test_STORunknownTransferErrorBecomesAbortcs\Gdd�dtj���fdd�}��tjd|��fdd�}t�}�j�d|�}|�|�|S)	zj
        Any errors during reading a file inside a RETR should be returned to
        the client.
        c@seZdZdd�ZdS)zJFTPServerAdvancedClientTests.test_RETRreadError.<locals>.FailingFileReadercSst�t�d��S)NZblah)r
r�rr�)r�consumerrrr�sendUszOFTPServerAdvancedClientTests.test_RETRreadError.<locals>.FailingFileReader.sendN)r)r*r+r�rrrr�FailingFileReaderTsr�cst��d��S)N)r
rp)r�r�)r�rr�failingRETRXszDFTPServerAdvancedClientTests.test_RETRreadError.<locals>.failingRETR�openForReadingcsH���|�tj���|jjddd���|jjddd�dS)Nrz3125 Data connection already open, starting transferr�z550 blah: is a directory)r�r�rrxrhr�rs)r)rrr�check_response_szGFTPServerAdvancedClientTests.test_RETRreadError.<locals>.check_responser�)rZ_FileReaderr�r�r,rM�retrieveFiler�)rr�r�r�r0r)r�rr�test_RETRreadErrorNs

z/FTPServerAdvancedClientTests.test_RETRreadErrorN)r)r*r+r|r�	FTPClientr`r�r�r�r�rrrrr��sr�c@s�eZdZdZd!dd�Zd"dd�Zdd�Zd	d
�Zdd�Zd
d�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd �ZdS)#� FTPServerPasvDataConnectionTestsz
    PASV data connection.
    NcCs|j�d�}dd�}|�|�S)z�
        Establish a passive data connection (i.e. client connecting to
        server).

        @param ignored: ignored
        @return: L{Deferred.addCallback}
        r�cSs2t�|ddd��\}}t�tt�}|�d|�S)Nr�r�z	127.0.0.1)rr�rr_r
r,ra)rir:r;r�rrr�gotPASV}szEFTPServerPasvDataConnectionTests._makeDataConnection.<locals>.gotPASV)rMrlrb)rrmr0r�rrr�_makeDataConnectiontsz4FTPServerPasvDataConnectionTests._makeDataConnectioncsH|dkrt�d�}|��j���fdd�}|�|�dd�}|�|�S)z�
        Download file.

        @param command: command to run
        @param chainDeferred: L{Deferred} used to queue commands.
        @return: L{Deferred} of command response
        Ncs �j���}|j}t�||g�S)N)rMrlr0r
rc)�
downloaderrJrf)rnrrrro�sz@FTPServerPasvDataConnectionTests._download.<locals>.queueCommandcSs|\}}|jS)N)r.)r�rmrrrr�downloadDone�sz@FTPServerPasvDataConnectionTests._download.<locals>.downloadDone)r
rprbr)rrnrqrorr)rnrr�	_download�s

z*FTPServerPasvDataConnectionTests._downloadcs,���}�jd|d��fdd�}|�|�S)zM
        When listing empty folders, LIST returns an empty response.
        r�)rqcs��d|�dS)Nr-)rh)r�)rrr�
checkEmpty�szCFTPServerPasvDataConnectionTests.test_LISTEmpty.<locals>.checkEmpty)rzrrb)rr0rr)rr�test_LISTEmpty�sz/FTPServerPasvDataConnectionTests.test_LISTEmptycsXt�tj��jd��t�tj��jd�����}�jd|d��fdd�}|�|�S)z}
        LIST ignores requests for folder with names like '-al' and will list
        the content of current folder.
        r�r�zLIST -aL)rqcsVg}x$|��D]}|�|�d�d�qW��dt|����d|���d|�dS)N� r��sfoosbar)�
splitlinesr#�splitrhr�r�)�download�namesr$)rrr�
checkDownload�szOFTPServerPasvDataConnectionTests.test_LISTWithBinLsFlags.<locals>.checkDownload)rQrR�pathr�rPrzrrb)rr0rr)rr�test_LISTWithBinLsFlags�sz8FTPServerPasvDataConnectionTests.test_LISTWithBinLsFlagscs�t�tj��jd��t�tj��jd�����}�jd|d��fdd�}|�|��jd|d��fdd�}|�|��jd	|d��fd
d�}|�|��fdd�}|�|��jd|d��fd
d�}|�|�S)z�
        LIST returns all folder's members, each member listed on a separate
        line and with name and other details.
        r�r�r�)rqcs"��dt|dd��d���dS)Nr���s
)rhr�r	)r
)rrrr�szLFTPServerPasvDataConnectionTests.test_LISTWithContent.<locals>.checkDownloadzNLST cs.|dd��d�}|����ddg|�dS)Nrs
sbarsfoo)r	�sortrh)r
�	filenames)rrrr�szLIST foocs��d|�dS)Nr-)rh)r
)rrrr�scs�j�d�S)NzCWD foo)rMrl)rm)rrr�chdir�szDFTPServerPasvDataConnectionTests.test_LISTWithContent.<locals>.chdircs��d|�dS)Nr-)rh)r
)rrrr�s)rQrRr
r�rPrzrrb)rr0rrr)rr�test_LISTWithContent�s"



z5FTPServerPasvDataConnectionTests.test_LISTWithContentcs\���}d
�fdd�	���fdd�}|�|��jd|f|d����fdd	�}|�|�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}
        rcst��g�S)N)r
rp)�segments�keys)�
listOutputrr�patchedListszEFTPServerPasvDataConnectionTests._listTestHelper.<locals>.patchedListcs��jj_|S)N)rBr�r�)r�)rrrr�loggedIns
zBFTPServerPasvDataConnectionTests._listTestHelper.<locals>.loggedInz%s something)rqcs���|��S)N)rh)r
)�expectedOutputrrrrrszGFTPServerPasvDataConnectionTests._listTestHelper.<locals>.checkDownload)r)rzrbr)rrnrrr0rrr)rrrrr�_listTestHelper�s
z0FTPServerPasvDataConnectionTests._listTestHelpercCs&|�ddddt�d�ddddffd�S)	z�
        Unicode filenames returned from L{IFTPShell.list} are encoded using
        UTF-8 before being sent with the response.
        r�u
my resumérr�i��user�groupsLdrwxrwxrwx   0 user      group                   0 Jan 01  1970 my resumé
)rr�Permissions)rrrr�test_LISTUnicode!s
z1FTPServerPasvDataConnectionTests.test_LISTUnicodecCs&|�ddddt�d�ddddffd�S)	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�s
my resumérr�i�rrsLdrwxrwxrwx   0 user      group                   0 Jan 01  1970 my resumé
)rrr)rrrr�test_LISTNonASCIIBytes.s
z7FTPServerPasvDataConnectionTests.test_LISTNonASCIIBytesc
s����}xxtddd�D]h}ttj��jd|f�d��}|�d|�WdQRX�jd|f|d	�|f�fd
d�	}|�	|�qW|S)zJ
        Download many large files.

        @return: L{Deferred}
        i��i��i�z%d.txt�wb�xNzRETR %d.txt)rqcs��|t|��dS)N)rhr�)r
�size)rrrrMszOFTPServerPasvDataConnectionTests.test_ManyLargeDownloads.<locals>.checkDownload)
rzr�openrQr
r�rP�writerrb)rr0r"ZfObjrr)rr�test_ManyLargeDownloads=sz8FTPServerPasvDataConnectionTests.test_ManyLargeDownloadscsf�j�d������}|��j��fdd�}|�|�dd�}|�|��fdd�}|�|�|S)zo
        When RETR is called for a folder, it will fail complaining that
        the path is a folder.
        r�cs|j���j�d�}|S)NzRETR foo)rCrDrMrl)rr�)rrr�
retrFolder^s
zHFTPServerPasvDataConnectionTests.test_downloadFolder.<locals>.retrFoldercSstd��dS)Nz(Downloading a folder should not succeed.)r�)r�rrr�
failOnSuccessdszKFTPServerPasvDataConnectionTests.test_downloadFolder.<locals>.failOnSuccesscs@|�tj���dg|jjd����}��dt|�d�dS)Nz550 foo: is a directoryrz6No errors should be logged while downloading a folder.)r�rrxrhr�rsr�r�)rZcurrent_errors)rrr�
checkErrorhszHFTPServerPasvDataConnectionTests.test_downloadFolder.<locals>.checkError)rTr�r�rzrbrr�)rr0r&r'r(r)rr�test_downloadFolderSs


z4FTPServerPasvDataConnectionTests.test_downloadFoldercsL���}�j�d����j�d����jd|d��fdd�}|�|�S)zp
        NLST with no argument returns the directory listing for the current
        working directory.
        ztest.txtr�zNLST )rqcs.|dd��d�}|����ddg|�dS)Nrs
sfoostest.txt)r	rrh)r
r)rrrr�szFFTPServerPasvDataConnectionTests.test_NLSTEmpty.<locals>.checkDownload)rzrTr�r�r�rrb)rr0rr)rr�test_NLSTEmptytsz/FTPServerPasvDataConnectionTests.test_NLSTEmptycs,���}�jd|d��fdd�}|�|�S)zH
        NLST on a non-existent file/directory returns nothing.
        zNLST nonexistent.txt)rqcs��d|�dS)Nr-)rh)r
)rrrr�szLFTPServerPasvDataConnectionTests.test_NLSTNonexistent.<locals>.checkDownload)rzrrb)rr0rr)rr�test_NLSTNonexistent�sz5FTPServerPasvDataConnectionTests.test_NLSTNonexistentcCs&|�ddddt�d�ddddffd�S)	zs
        NLST will receive Unicode filenames for IFTPShell.list, and will
        encode them using UTF-8.
        �NLSTu
my resumérr�i�rrsmy resumé
)rrr)rrrr�test_NLSTUnicode�s
z1FTPServerPasvDataConnectionTests.test_NLSTUnicodecCs&|�ddddt�d�ddddffd�S)	zJ
        NLST will just pass the non-Unicode data to lower level.
        r,s
my resumérr�i�rrsmy resumé
)rrr)rrrr�test_NLSTNonASCIIBytes�s
z7FTPServerPasvDataConnectionTests.test_NLSTNonASCIIBytescs<���}�j�d����jd|d��fdd�}|�|�S)zN
        NLST on an existent file returns only the path to that file.
        ztest.txtz
NLST test.txt)rqcs$|dd��d�}��dg|�dS)Nrs
stest.txt)r	rh)r
r)rrrr�szMFTPServerPasvDataConnectionTests.test_NLSTOnPathToFile.<locals>.checkDownload)rzrTr�r�rrb)rr0rr)rr�test_NLSTOnPathToFile�s
z6FTPServerPasvDataConnectionTests.test_NLSTOnPathToFile)N)N)r)r*r+r|rrrrrrrrr%r)r*r+r-r.r/rrrrr�ps 


-1
!
r�c@s6eZdZdd�Zddd�Zdd�Zdd	�Zd
d�ZdS)
� FTPServerPortDataConnectionTestscCsg|_t�|�S)N)�	dataPortsr�rg)rrrrrg�sz&FTPServerPortDataConnectionTests.setUpNcsbt���G�fdd�dtj�}tjd|�dd�}|j�|�dt�	d|�
�j�}|j�
|��S)NcseZdZeZ�fdd�ZdS)zIFTPServerPortDataConnectionTests._makeDataConnection.<locals>.DataFactorycs"tj�||�}t�d�j|�|S)Nr)r�
ServerFactoryrFr
Z	callLaterr2)rrIrd)r�rrrF�szWFTPServerPortDataConnectionTests._makeDataConnection.<locals>.DataFactory.buildProtocolN)r)r*r+r,rrFr)r�rr�DataFactory�sr3rz	127.0.0.1)rAzPORT )r
r/rr2r
r\r1r#rr7r^r;rMrl)rrmr3ZdataPort�cmdr)r�rr�sz4FTPServerPortDataConnectionTests._makeDataConnectioncCs6dd�|jD�}t�tj|�}|�|�tj|dd�S)zS
        Tear down the connection.

        @return: L{defer.DeferredList}
        cSsg|]}t�|j��qSr)r
�
maybeDeferredr])�.0r;rrr�
<listcomp>�sz=FTPServerPortDataConnectionTests.tearDown.<locals>.<listcomp>T)r�)r1r
r5r��tearDownr#r�)r�lr0rrrr8�s


z)FTPServerPortDataConnectionTests.tearDowncs0���}dd�}|�|��fdd�}|�|�S)z�
        Listen on a port, and immediately stop listening as a way to find a
        port number that is definitely closed.
        cs<tjdt��dd�}|��j�|��}|��fdd��|S)Nrz	127.0.0.1)rAcs�S)Nr)r�)rerrr��r-z[FTPServerPortDataConnectionTests.test_PORTCannotConnect.<locals>.loggedIn.<locals>.<lambda>)r
r\rr�r^r;r]rb)rmr;r0r)rerr�s
zIFTPServerPortDataConnectionTests.test_PORTCannotConnect.<locals>.loggedIncs��dt�d|�dg�S)NzPORT z	127.0.0.1z425 Can't open data connection.)ryrr7)re)rrr�
gotPortNum�szKFTPServerPortDataConnectionTests.test_PORTCannotConnect.<locals>.gotPortNum)rzrb)rr0rr:r)rr�test_PORTCannotConnect�s

z7FTPServerPortDataConnectionTests.test_PORTCannotConnectcs\�j�d����j�d����j�d������}�jd|d��fdd�}|�|�S)zv
        When Unix shell globbing is used with NLST only files matching the
        pattern will be returned.
        ztest.txtzceva.txtzno.matchz
NLST *.txt)rqcs.|dd��d�}|����ddg|�dS)Nrs
sceva.txtstest.txt)r	rrh)r
r)rrrrszIFTPServerPortDataConnectionTests.test_nlstGlobbing.<locals>.checkDownload)rTr�r�rzrrb)rr0rr)rr�test_nlstGlobbingsz2FTPServerPortDataConnectionTests.test_nlstGlobbing)N)r)r*r+rgrr8r;r<rrrrr0�s

r0c@sHeZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Z	dd�Z
dS)�DTPFactoryTestsz&
    Tests for L{ftp.DTPFactory}.
    cCs:t��|_Gdd�dt�}|�|_t�|jd|j�|_dS)zf
        Create a fake protocol interpreter and a L{ftp.DTPFactory} instance to
        test.
        c@seZdZdZdS)z2DTPFactoryTests.setUp.<locals>.ProtocolInterpreterN)r)r*r+r�rrrr�ProtocolInterpreter sr>N)r�Clockr
r��protocolInterpreterr�
DTPFactoryr )rr>rrrrgs

zDTPFactoryTests.setUpcCslg}|�|jjtj�}|�|j�|j�d�|j�	d�|�
|�|j�	d�|�|�|�
|jj�dS)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.
        r��r�N)
rwr r�r�PortConnectionErrorrbr#�
setTimeoutr
�advancer�r��calls)r�finishedr0rrr�test_setTimeout(s

zDTPFactoryTests.test_setTimeoutcCs0|j�d�}|�|tj�|�|j�d��dS)z�
        A L{ftp.DTPFactory} instance's C{buildProtocol} method can be used once
        to create a L{ftp.DTP} instance.
        N)r rFr�r�DTP�assertIsNone)rrrrr�test_buildProtocolOnceFsz&DTPFactoryTests.test_buildProtocolOncecCs*|j�d�|j�d�|�|jj�dS)z�
        If a timeout has been set up using L{ftp.DTPFactory.setTimeout}, it is
        cancelled by L{ftp.DTPFactory.buildProtocol}.
        �
N)r rDrFr�r
rF)rrrr�test_timeoutAfterConnectionRsz+DTPFactoryTests.test_timeoutAfterConnectioncCs@|�|jjtj�}|j�d�|j�d�|�|j�	d��|S)z�
        If L{ftp.DTPFactory.buildProtocol} is called after the timeout
        specified by L{ftp.DTPFactory.setTimeout} has elapsed, L{None} is
        returned.
        rLN)
rwr r�rrCrDr
rErJrF)rr0rrr�test_connectionAfterTimeout]s
z+DTPFactoryTests.test_connectionAfterTimeoutcCs`g}|�|jjtj�}|�|j�|j�d�|�|�|j�	dd�|�
|�|j�d�|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.
        rLN)
rwr r�rrCrbr#rDr��clientConnectionFailedr�r
rE)rrGr0rrr�!test_timeoutAfterConnectionFailedrs

z1DTPFactoryTests.test_timeoutAfterConnectionFailedcCsB|�|jjtj�}|j�d�|j�d�|j�dt	�
d��|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.
        rLNr�)rwr r�rrCrDr
rErOr
�TimeoutError)rr0rrr�!test_connectionFailedAfterTimeout�s
z1DTPFactoryTests.test_connectionFailedAfterTimeoutN)r)r*r+r|rgrHrKrMrNrPrRrrrrr=sr=c@s eZdZdZdd�Zdd�ZdS)�DTPTestszx
    Tests for L{ftp.DTP}.

    The DTP instances in these tests are generated using
    DTPFactory.buildProtocol()
    cCsDt��|_Gdd�dt�}|�|_t�|jd|j�|_t�	�|_
dS)z�
        Create a fake protocol interpreter, a L{ftp.DTPFactory} instance,
        and dummy transport to help with tests.
        c@seZdZdZdS)z+DTPTests.setUp.<locals>.ProtocolInterpreterN)r)r*r+r�rrrrr>�sr>N)rr?r
r�r@rrAr r� StringTransportWithDisconnectionrC)rr>rrrrg�s
zDTPTests.setUpcCsD|j�d�}|�|j�d}|�|�|j��}|�|d|�dS)zr
        L{ftp.DTP.sendLine} writes the line passed to it plus a line delimiter
        to its transport.
        Nsline contents
)r rF�makeConnectionrC�sendLiner�rh)rr�ZlineContentZdataSentrrr�test_sendLineNewline�s

zDTPTests.test_sendLineNewlineN)r)r*r+r|rgrWrrrrrS�srSc@s eZdZdZdd�Zdd�ZdS)�
PrintLinesz3
    Helper class used by FTPFileListingTests.
    cCs
||_dS)N)�_lines)rrrrrr�szPrintLines.__init__cCs4x$|jD]}|j�|�d�d�qW|j��dS)Nzlatin-1s
)rYrCr$r8rD)rr$rrrr"�szPrintLines.connectionMadeN)r)r*r+r|rr"rrrrrX�srXc@seZdZdd�Zdd�ZdS)�MyFTPFileListProtocolcCsg|_tj�|�dS)N)�otherr�FTPFileListProtocolr)rrrrr�szMyFTPFileListProtocol.__init__cCs|j�|�dS)N)r[r#)rr$rrr�unknownLine�sz!MyFTPFileListProtocol.unknownLineN)r)r*r+rr]rrrrrZ�srZc@sDeZdZdd�Zdd�Zdd�Zdd�Zd	d
�Zdd�Zd
d�Z	dS)�FTPFileListingTestscs,t��t�t|���}|��fdd��|S)Ncs�j�jfS)N)�filesr[)r�)�fileListrrr��r-z6FTPFileListingTests.getFilesForLines.<locals>.<lambda>)rZr�
loopbackAsyncrXrb)rrr0r)r`r�getFilesForLines�sz$FTPFileListingTests.getFilesForLinescs"d}�fdd�}��|g��|�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 READMEcs�|\\}}��|dt|�f���|ddkd���|ddkd���|dd	kd���|d
dkd���|dd
kd���|ddkd���|ddkd���|ddkd���|dd�dS)Nzunexpect unparsable lines: %s�filetype�-zmisparsed fileitem�permsz	rw-r--r--zmisparsed perms�owner�rootrr[r"i�datezJan 29 03:26�filename�README�nlinksr�zmisparsed nlinks�
linktargetzmisparsed linktarget)r��reprr�)Z	fileOther�filer[)rrr�check�s
z/FTPFileListingTests.test_OneLine.<locals>.check)rbrb)rr$ror)rr�test_OneLine�s
z FTPFileListingTests.test_OneLinecs.d}d}d}�fdd�}��|||g��|�S)z 
        Variant lines.
        z7drw-r--r--   2 root     other        531 Jan  9  2003 Az<lrw-r--r--   1 root     other          1 Jan 29 03:26 B -> Azwoohoo! cs�|\\}}\}��|dkd���|ddkd���|ddkd���|d	d
kd���|dd
kd���|ddkd���|ddkd���|ddkd���|ddkd���|dd���|ddkd���|ddkd���|d	d
kd���|dd
kd���|ddkd���|ddkd���|dd kd���|ddkd���|ddkd�dS)!Nz	woohoo! 
zincorrect other linercr0zmisparsed fileitemrez	rw-r--r--zmisparsed permsrfrgzmisparsed ownerrr[zmisparsed groupr"izmisparsed sizerhzJan  9  2003zmisparsed dateri�Azmisparsed filenamerkrzmisparsed nlinksrlzmisparsed linktargetr9r�zJan 29 03:26�B)r�r�)r�Zfile1Zfile2r[)rrrros(z4FTPFileListingTests.test_VariantLines.<locals>.check)rbrb)r�line1�line2Zline3ror)rr�test_VariantLiness
z%FTPFileListingTests.test_VariantLinescs �fdd�}��ddg��|�S)z 
        Unknown lines.
        cs4|\}}��|d���|ddgkdt|��dS)Nzunexpected file entrieszABC
znot a file
zincorrect unparsable lines: %s)r�r�rm)r�r_�others)rrrro&sz3FTPFileListingTests.test_UnknownLine.<locals>.check�ABCz
not a file)rbrb)rror)rr�test_UnknownLine"sz$FTPFileListingTests.test_UnknownLinecs(d}d}�fdd�}��||g��|�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 Bcs\|\}}��g|d���d|ddd���d|ddd���d|dd	d
�dS)Nzunexpected others entrieszA Brrizmisparsed filenamezB Ar�zD C/A Brlzmisparsed linktarget)rh)r�r_rv)rrrro9szBFTPFileListingTests.test_filenameWithUnescapedSpace.<locals>.check)rbrb)rrsrtror)rr�test_filenameWithUnescapedSpace.s	z3FTPFileListingTests.test_filenameWithUnescapedSpacecs(d}d}�fdd�}��||g��|�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 Bcs\|\}}��g|d���d|ddd���d|ddd���d|dd	d
�dS)Nzunexpected others entrieszA Brrizmisparsed filenamezB Ar�zD C/A Brlzmisparsed linktarget)rh)r�r_rv)rrrroPsz@FTPFileListingTests.test_filenameWithEscapedSpace.<locals>.check)rbrb)rrsrtror)rr�test_filenameWithEscapedSpaceEs	z1FTPFileListingTests.test_filenameWithEscapedSpacecsHt���d�G�fdd�dtj�}��fdd�}t�|���}|�|�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
cseZdZ�fdd�ZdS)z0FTPFileListingTests.test_Year.<locals>.PrintLinecs|j���|j��dS)N)rCr$rD)r)�exampleLinerrr"fsz?FTPFileListingTests.test_Year.<locals>.PrintLine.connectionMadeN)r)r*r+r"r)r{rr�	PrintLineesr|csJ�jd}��|ddkd���|ddkd���|ddkd�dS)	Nrr"izmisparsed fileitemrhzJan 29 2003rirj)r_r�)rmrn)r`rrrrojs



z,FTPFileListingTests.test_Year.<locals>.check)rr\r�Protocolrrarb)rr|ror0r)r{r`rr�	test_Year\szFTPFileListingTests.test_YearN)
r)r*r+rbrprurxryrzr~rrrrr^�s!r^c@s eZdZdZdd�Zdd�ZdS)�1FTPClientFailedRETRAndErrbacksUponDisconnectTestsz:
    FTP client fails and RETR fails and disconnects.
    cs�t��}d|_tjd|dd�}|�|j�|��j}ddddd|d	?|d
@fdg��fdd
�|_	tj
ttjdd�}|�
d|�}dd�}|�|�|�|tj�S)z
        RETR fails.
        rz	127.0.0.1)rAz1220 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.cst��S)N)rX)rI)�	responsesrrr��r-zSFTPClientFailedRETRAndErrbacksUponDisconnectTests.test_FailedRETR.<locals>.<lambda>r�)�passivecSst��}|�d|�S)Nz/file/that/doesnt/exist)rr}r�)rMrdrrrrN�szTFTPClientFailedRETRAndErrbacksUponDisconnectTests.test_FailedRETR.<locals>.gotClient)rr�Znoisyr
r\rHr]r^r;rFr_rr�rarbrwrx)rr!r;rer�r0rNr)r�r�test_FailedRETRzs$

zAFTPClientFailedRETRAndErrbacksUponDisconnectTests.test_FailedRETRcstt��}t��}|�|�||_|�dt��}g��fdd�}|�|�ddl	m
}|�t�
|��|����|S)zl
        Test the ftp command errbacks when a connection lost happens during
        the operation.
        z	some pathcs��|�dS)N)r#)r)�mrr�_eb�s
zZFTPClientFailedRETRAndErrbacksUponDisconnectTests.test_errbacksUponDisconnect.<locals>._ebr)�CONNECTION_LOST)rr�rrTrUrr�rr�Ztwisted.internet.mainr�r4r�Failurer�)r�	ftpClient�trr0r�r�r)r�r�test_errbacksUponDisconnect�s

zMFTPClientFailedRETRAndErrbacksUponDisconnectTests.test_errbacksUponDisconnectN)r)r*r+r|r�r�rrrrrvs!rc@sXeZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd�Zd d!�Zd"d#�Zd$d%�Zd&d'�Zd(d)�Zd*d+�Zd,d-�Zd.d/�Zd0d1�Zd2d3�Zd4d5�Zd6d7�Zd8d9�Zd:d;�Z d<d=�Z!d>d?�Z"d@dA�Z#dBdC�Z$dDdE�Z%dFdG�Z&dHdI�Z'dJdK�Z(dLdM�Z)dNdO�Z*dPdQ�Z+dRdS�Z,dTS)U�FTPClientTestsz,
    Test advanced FTP client commands.
    cCs0t��|_t��|_|j�|j�|j|j_dS)zG
        Create a FTP client and connect it to fake transport.
        N)rr�rMrrTrCrUr)rrrrrg�s

zFTPClientTests.setUpcCs|j�t���dS)z�
        Deliver disconnection notification to the client so that it can
        perform any cleanup which may be required.
        N)rMr4r�ConnectionLost)rrrrr8�szFTPClientTests.tearDowncCsr|�|j��d�|j�d�|�|j��d�|j��|j�d�|�|j��d�|j��|j�d�dS)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)rhrCr�rMr%�clear)rrrr�
_testLogin�s

zFTPClientTests._testLogincCsz|�|j��d�|j�d�|�|j��d�|j�d�|�|j��d�|j��|j�d�|�|j��d�dS)z9
            Test encoding behaviour of sendLine
        r-N�s
�és�
)rhrCr�rMrVr�)rrrr�
test_sendLine�s
zFTPClientTests.test_sendLinecsP�fdd�}����j���|�}���j��d��j���j�d�|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)
        cs��|dd�dS)Nrz&250 Requested File Action Completed OK)rh)r�)rrr�cbCdup�sz(FTPClientTests.test_CDUP.<locals>.cbCdupsCDUP
s&250 Requested File Action Completed OK)	r�rM�cduprbrhrCr�r�r%)rr�r0r)rr�	test_CDUP�s

zFTPClientTests.test_CDUPcCsL|��|j��}|�|tj�|�|j��d�|j�	�|j�
d�|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}.
        sCDUP
s!550 ..: No such file or directory)r�rMr�rwrrxrhrCr�r�r%)rr0rrr�test_failedCDUP�s

zFTPClientTests.test_failedCDUPcsF�fdd�}����j���|�}���j��d��j�d�|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)
        cs��t�|d�d�dS)Nrz/bar/baz)rhrZparsePWDResponse)r�)rrr�cbPwdsz&FTPClientTests.test_PWD.<locals>.cbPwdsPWD
s257 "/bar/baz")r�rM�pwdrbrhrCr�r%)rr�r0r)rr�test_PWD
s
zFTPClientTests.test_PWDcCsB|��|j��}|�|tj�|�|j��d�|j�	d�|S)z�
        Test a failure in PWD command.

        When the PWD command fails, the returned Deferred should errback
        with L{ftp.CommandFailed}.
        sPWD
s'550 /bar/baz: No such file or directory)
r�rMr�rwrrxrhrCr�r%)rr0rrr�test_failedPWDs
zFTPClientTests.test_failedPWDcsH�fdd�}����j�d��|�}���j��d��j�d�|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)
        cs��|dd�dS)Nrz&250 Requested File Action Completed OK)rh)r�)rrr�cbCwd7sz&FTPClientTests.test_CWD.<locals>.cbCwdzbar/foos
CWD bar/foo
s&250 Requested File Action Completed OK)r�rM�cwdrbrhrCr�r%)rr�r0r)rr�test_CWD-s
zFTPClientTests.test_CWDcCsD|��|j�d�}|�|tj�|�|j��d�|j�	d�|S)z�
        Test a failure in CWD command.

        When the PWD command fails, the returned Deferred should errback
        with L{ftp.CommandFailed}.
        zbar/foos
CWD bar/foo
s&550 bar/foo: No such file or directory)
r�rMr�rwrrxrhrCr�r%)rr0rrr�test_failedCWDAszFTPClientTests.test_failedCWDcs��fdd�}�fdd�}|�j_���t�}�j�d|�}|�||����j��d��j�	��j�
t�j�����j��d��j�	��j�
d�|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)
        cs��|jd�dS)Ns�xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)rhr.)r�r�)rrr�cbRetr[sz/FTPClientTests.test_passiveRETR.<locals>.cbRetrcsd��|d���|d�|�||f�}|�t����j�d�|�d�|�t	�
t�d���dS)Nz	127.0.0.1i90s4150 File status okay; about to open data connection.s�xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxr�)
rhrFrUr�StringTransportrMr%r1r4rr�r�ConnectionDone)r:r;r r�)rrr�	cbConnect^s
z2FTPClientTests.test_passiveRETR.<locals>.cbConnect�spamsPASV
sRETR spam
s226 Transfer Complete.)rM�connectFactoryr�r,r�rbrhrCr�r�r%r=)rr�r�r�r0r)rr�test_passiveRETRPs


zFTPClientTests.test_passiveRETRcs�d�j_dd�}�fdd�}|�j_���t�}�j�d|�}|�||����j�	�dt
�dd	�f��jj
���j���j�d
����j�	�d��j���j�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.
        FcSsLdt�dd�f|_|j�t���|j�d�|j�t	�
t�d���dS)NzPORT %sz	127.0.0.1i�&s�xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxr�)
rr7�textrrUrr�r1r4rr�rr�)�portCmdrrr�generatePort�s
z.FTPClientTests.test_RETR.<locals>.generatePortcs��|jd�dS)Ns�xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)rhr.)r�r�)rrrr��sz(FTPClientTests.test_RETR.<locals>.cbRetrr�z	PORT %s
z	127.0.0.1i�&s200 PORT OKsRETR spam
s226 Transfer Complete.)rMr��generatePortCommandr�r,r�rbrhrCr�rr7r8r9r�r%)rr�r�r�r0r)rr�	test_RETRvs&

zFTPClientTests.test_RETRcs��fdd�}|�j_���t�}�j�d|�}��|tj����j	�
�d��j	���j�t
�j�����j	�
�d��j	���j�d�|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.
        csZ��|d���|d�|�||f�}|�t����j�d�|�t�	t
�d���dS)Nz	127.0.0.1i90s4150 File status okay; about to open data connection.r�)rhrFrUrr�rMr%r4rr�rr�)r:r;r r�)rrrr��sz1FTPClientTests.test_failedRETR.<locals>.cbConnectr�sPASV
sRETR spam
s#550 spam: No such file or directory)rMr�r�r,r�rwrrxrhrCr�r�r%r=)rr�r�r0r)rr�test_failedRETR�s	

zFTPClientTests.test_failedRETRcs�d|j_g��fdd�}||j_|��t�}|j�d|�}|�|j��dt	�
dd�f�|jj��|j�
�|j�d�|�|j��d	�|����d
��|j��|�|t	j�|S)z�
        Try a RETR, but disconnect during the transfer.
        L{ftp.FTPClient.retrieveFile} should return a Deferred which
        errbacks with L{ftp.ConnectionLost)
        FcsJdt�dd�f|_t��}|j�|�|j|_|j�d���|�dS)NzPORT %sz	127.0.0.1i�&s�xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)	rr7r�rrTrrUr1r#)r�r�)r9rrr��sz2FTPClientTests.test_lostRETR.<locals>.generatePortr�z	PORT %s
z	127.0.0.1i�&s200 PORT OKsRETR spam
r)rMr�r�r�r,r�rhrCr�rr7r8r9r�r%r�rDrwr�)rr�r�r0r)r9r�
test_lostRETR�s$


zFTPClientTests.test_lostRETRcs�t����fdd�}��fdd�}��fdd�}|�j_����j�d�\}}|�|�|�|����j�	�d��j�
��j�t�j�����j�	�d	��j�
��j�d
�t
�||g�S)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).
        cs:�j�d�|j�d�|��|�t�t�	d���dS)Ns4150 File status okay; about to open data connection.s�xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxr�)
rMr%rCr$�finishr4rr�rr�)�sender)rrr�cbStore�s
z0FTPClientTests.test_passiveSTOR.<locals>.cbStorecs�����d�dS)Ns�xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)rhr�)�ign)rr�rr�cbFinish�sz1FTPClientTests.test_passiveSTOR.<locals>.cbFinishcs4��|d���|d�|�||f�}|���dS)Nz	127.0.0.1i90)rhrFrU)r:r;r r�)rr�rrr��sz2FTPClientTests.test_passiveSTOR.<locals>.cbConnectr�sPASV
sSTOR spam
s226 Transfer Complete.)rr�rMr�r�r�rbrhrCr�r�r%r=r
rc)rr�r�r�rJrfr)rr�r�test_passiveSTOR�s 



zFTPClientTests.test_passiveSTORcs�t����fdd�}��fdd�}|�j_����j�d�\}}|�|���|tj	���
�j��d��j�
��j�t�j����
�j��d��j�
��j�d�t�||g�S)	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}.
        cs:�j�d�|j�d�|��|�t�t�	d���dS)Ns4150 File status okay; about to open data connection.s�xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxr�)
rMr%rCr$r�r4rr�rr�)r�)rrrr�s
z/FTPClientTests.test_failedSTOR.<locals>.cbStorecs4��|d���|d�|�||f�}|���dS)Nz	127.0.0.1i90)rhrFrU)r:r;r r�)rr�rrr�sz1FTPClientTests.test_failedSTOR.<locals>.cbConnectr�sPASV
sSTOR spam
s.426 Transfer aborted.  Data connection closed.)rr�rMr�r�r�rbrwrrxrhrCr�r�r%r=r
rc)rr�r�rJrfr)rr�r�test_failedSTORs 


zFTPClientTests.test_failedSTORcsxt���d�j_�fdd�}�fdd�}��fdd�}|�j_����j�d�\}}|�|�|�|�t�	||g�S)	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.
        Fcs"dt�dd�|_|j���dS)NzPORT z	127.0.0.1i�&)rr7r�rrU)r�)r�rrr�;sz.FTPClientTests.test_STOR.<locals>.generatePortcs����j��dt�dd�f��jj���j���j�	d����j��d��j���j�	d�|j�
d�|��|�t
�t�d����j�	d	�dS)
Nz	PORT %s
z	127.0.0.1i�&s200 PORT OKsSTOR spam
s4150 File status okay; about to open data connection.s�xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxr�s226 Transfer Complete.)rhrCr�rr7r8rMr9r�r%r$r�r4rr�rr�)r�)rrrr�?s

z)FTPClientTests.test_STOR.<locals>.cbStorecs�����d�dS)Ns�xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx)rhr�)r�)rr�rrr�Nsz*FTPClientTests.test_STOR.<locals>.cbFinishr�)
rr�rMr�r�r�r�rbr
rc)rr�r�r�rJrfr)rr�r�	test_STOR1s

zFTPClientTests.test_STORcs��fdd�}�fdd�}|�j_���t��}�j�d|��||�}���j�	�d��j�
��j�t�j�����j�	�d��j�d�|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)
        cs:dd�|jD�}dddg}|��|����||�dS)NcSsg|]}|d�qS)rir)r6r!rrrr7mszCFTPClientTests.test_passiveLIST.<locals>.cbList.<locals>.<listcomp>r�r��baz)r_rrh)r�r`�fls�expected)rrr�cbListls

z/FTPClientTests.test_passiveLIST.<locals>.cbListcs|��|d���|d�|�||f�}|�t����j�d�dddg}x|D]}|�|�qPW|�t	�
t�d���dS)Nz	127.0.0.1i90s4150 File status okay; about to open data connection.s8-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
r�)
rhrFrUrr�rMr%r1r4rr�rr�)r:r;r r��sendingr�)rrrr�ss
z2FTPClientTests.test_passiveLIST.<locals>.cbConnectzfoo/barsPASV
sLIST foo/bar
s226 Transfer Complete.)
rMr�r�rr\r�rbrhrCr�r�r%r=)rr�r�r`r0r)rr�test_passiveLISTYs
zFTPClientTests.test_passiveLISTcs�d�j_�fdd�}�fdd�}|�j_���t��}�j�d|��||�}���j	�
�dt�dd	�f��jj
���j	���j�d
����j	�
�d��j	���j�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.
        Fcspdt�dd�f|_|j�t����j�d�dddg}x|D]}|j�	|�q@W|j�
t�t
�d���dS)	NzPORT %sz	127.0.0.1i�&s4150 File status okay; about to open data connection.s8-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
r�)rr7r�rrUrr�rMr%r1r4rr�rr�)r�r�r�)rrrr��s
z.FTPClientTests.test_LIST.<locals>.generatePortcs:dd�|jD�}dddg}|��|����||�dS)NcSsg|]}|d�qS)rir)r6r!rrrr7�sz<FTPClientTests.test_LIST.<locals>.cbList.<locals>.<listcomp>r�r�r�)r_rrh)r�r`r�r�)rrrr��s

z(FTPClientTests.test_LIST.<locals>.cbListzfoo/barz	PORT %s
z	127.0.0.1i�&s200 PORT OKsLIST foo/bar
s226 Transfer Complete.)rMr�r�r�rr\r�rbrhrCr�r7r8r9r�r%)rr�r�r`r0r)rr�	test_LIST�s 

zFTPClientTests.test_LISTcs��fdd�}|�j_���t��}�j�d|�}��|tj����j	�
�d��j	���j�t
�j�����j	�
�d��j�d�|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.
        csZ��|d���|d�|�||f�}|�t����j�d�|�t�	t
�d���dS)Nz	127.0.0.1i90s4150 File status okay; about to open data connection.r�)rhrFrUrr�rMr%r4rr�rr�)r:r;r r�)rrrr��sz1FTPClientTests.test_failedLIST.<locals>.cbConnectzfoo/barsPASV
sLIST foo/bar
s&550 foo/bar: No such file or directory)rMr�r�rr\r�rwrxrhrCr�r�r%r=)rr�r`r0r)rr�test_failedLIST�s	
zFTPClientTests.test_failedLISTcs�d�j_�fdd�}�fdd�}|�j_���t�}�j�d|��||�}���j�	�dt
�dd	�f��jj
���j���j�d
����j�	�d��j�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.
        Fcspdt�dd�f|_|j�t����j�d�|j�	d�|j�	d�|j�	d�|j�
t�t
�d���dS)	NzPORT %sz	127.0.0.1i�&s4150 File status okay; about to open data connection.sfoo
sbar
sbaz
r�)rr7r�rrUrr�rMr%r1r4rr�rr�)r�)rrrr��sz.FTPClientTests.test_NLST.<locals>.generatePortcs>|j��jj���}dddg}|��|����||�dS)Nr�r�r�)r.�decoderMr9rrrh)r�r�r�r�)rrrr��s

z(FTPClientTests.test_NLST.<locals>.cbListzfoo/barz	PORT %s
z	127.0.0.1i�&s200 PORT OKsNLST foo/bar
s226 Transfer Complete.)rMr�r�r�r,�nlstrbrhrCr�rr7r8r9r�r%)rr�r��lstprotor0r)rr�	test_NLST�s
zFTPClientTests.test_NLSTcs��fdd�}�fdd�}|�j_���t�}�j�d|��||�}���j��d��j�	��j�
t�j�����j��d��j�
d�|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.
        cs4|j��}dddg}|��|����||�dS)Nsfoosbarsbaz)r.rrrh)r�r�r�r�)rrrr�	s


z/FTPClientTests.test_passiveNLST.<locals>.cbListcsx��|d���|d�|�||f�}|�t����j�d�|�d�|�d�|�d�|�t	�
t�d���dS)Nz	127.0.0.1i90s4150 File status okay; about to open data connection.sfoo
sbar
sbaz
r�)
rhrFrUrr�rMr%r1r4rr�rr�)r:r;r r�)rrrr�	s


z2FTPClientTests.test_passiveNLST.<locals>.cbConnectzfoo/barsPASV
sNLST foo/bar
s226 Transfer Complete.)rMr�r�r,r�rbrhrCr�r�r%r=)rr�r�r�r0r)rr�test_passiveNLST	s
zFTPClientTests.test_passiveNLSTcs�t�����fdd�}|�j_���t�}�j�d|�}��|tj	���
�j��d��j�
��j�t�j����
�j��d��j�d�|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.
        csV��|d���|d�|�||f�}|����j�d�|�t�t�	d���dS)Nz	127.0.0.1i90s4150 File status okay; about to open data connection.r�)
rhrFrUrMr%r4rr�rr�)r:r;r r�)rr�rrr�3	s
z1FTPClientTests.test_failedNLST.<locals>.cbConnectzfoo/barsPASV
sNLST foo/bar
s&550 foo/bar: No such file or directory)rr�rMr�r�r,r�rwrrxrhrCr�r�r%r=)rr�r�r0r)rr�r�test_failedNLST*	s	
zFTPClientTests.test_failedNLSTcCs�|��|j�dd�}|�|j��d�|j��d}|j�|�|jj	��|�|j��d�d}|j�|�|jj	��|�
|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.
        z/spamz/hamsRNFR /spam
z8350 Requested file action pending further information.
sRNTO /ham
z&250 Requested File Action Completed OK)r�rM�renamerhrCr�r�r%r8r9rb)rr0ZfromResponseZ
toResponserrr�test_renameFromToI	s
z FTPClientTests.test_renameFromTocCsL|��d}d}|j�||�|j�d�|j�d�|�|j��d�dS)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)r�rMr�r%rhrCr�)rZfromFileZtoFilerrr�test_renameFromToEscapesPaths`	sz,FTPClientTests.test_renameFromToEscapesPathscCs^|��|j�dd�}|�|j��d�|j��|j�d�|�|j��d�|�|t	j
�S)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).
        z/spamz/hamsRNFR /spam
s!550 Requested file unavailable.
r-)r�rMr�rhrCr�r�r%rwrrx)rr0rrr�$test_renameFromToFailingOnFirstErrorr	s
z3FTPClientTests.test_renameFromToFailingOnFirstErrorcCsj|��|j�dd�}|�|j��d�|j��|j�d�|�|j��d�|j�d�|�|t	j
�S)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).
        z/spamz/hamsRNFR /spam
s8350 Requested file action pending further information.
sRNTO /ham
s!550 Requested file unavailable.
)r�rMr�rhrCr�r�r%rwrrx)rr0rrr�"test_renameFromToFailingOnRenameTo�	s
z1FTPClientTests.test_renameFromToFailingOnRenameTocCsB|��|j�d�}|�|j��d�|j�d�|�|jdg�S)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.
        z/spamsMKD /spam
s257 "/spam" created.z257 "/spam" created.)r�rM�
makeDirectoryrhrCr�r%rb)rr0rrr�test_makeDirectory�	s
z!FTPClientTests.test_makeDirectorycCs6|��|j�d�}|�|j��d�|j�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)r�rMr�rhrCr�r%)rr0rrr�test_makeDirectoryPathEscape�	s
z+FTPClientTests.test_makeDirectoryPathEscapecCs@|��|j�d�}|�|j��d�|j�d�|�|tj	�S)z�
        L{ftp.FTPClient.makeDirectory} returns a L{Deferred} which is errbacked
        with L{CommandFailed} if the server returns an error response code.
        z/spamsMKD /spam
s550 PERMISSION DENIED)
r�rMr�rhrCr�r%rwrrx)rr0rrr�test_failedMakeDirectory�	s
z'FTPClientTests.test_failedMakeDirectorycsF�fdd�}����j���|�}���j��d��j�d�|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.
        cs��|d�dS)Nz/bar/baz)rh)r�)rrr�cbGet�	sz/FTPClientTests.test_getDirectory.<locals>.cbGetsPWD
s257 "/bar/baz")r�rM�getDirectoryrbrhrCr�r%)rr�r0r)rr�test_getDirectory�	sz FTPClientTests.test_getDirectorycCsB|��|j��}|�|tj�|�|j��d�|j�	d�|S)zj
        Test a failure in getDirectory method.

        The behaviour should be the same as PWD.
        sPWD
s'550 /bar/baz: No such file or directory)
r�rMr�rwrrxrhrCr�r%)rr0rrr�test_failedGetDirectory�	s
z&FTPClientTests.test_failedGetDirectorycCsB|��|j��}|�|tj�|�|j��d�|j�	d�|S)z�
        Test a different failure in getDirectory method.

        The response should be quoted to be parsed, so it returns an error
        otherwise.
        sPWD
s257 /bar/baz)
r�rMr�rwrrxrhrCr�r%)rr0rrr�test_anotherFailedGetDirectory�	s
z-FTPClientTests.test_anotherFailedGetDirectorycCsP|��|j�d�}|�|j��d�d}|j�|�|jj��|�	|j|g�S)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.
        z	/tmp/testsDELE /tmp/test
z*250 Requested file action okay, completed.)
r�rM�
removeFilerhrCr�r%r8r9rb)rr0�responserrr�test_removeFile�	szFTPClientTests.test_removeFilecsf����j�d�}���j��d�d��j����jj����	|t
j�}|���fdd��|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}.
        z	/tmp/testsDELE /tmp/test
z,501 Syntax error in parameters or arguments.cs��|j�gf�S)N)rhrs)�exc)r�rrrr�
r-z6FTPClientTests.test_failedRemoveFile.<locals>.<lambda>)
r�rMr�rhrCr�r%r8r9rwrrxrb)rr0r)r�rr�test_failedRemoveFile�	sz$FTPClientTests.test_failedRemoveFilecsT����j�d�}d��j����jj����|tj�}|�	��fdd��|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.
        z	/tmp/testz765 blah blah blahcs��|j�gf�S)N)rhrs)r�)r�rrrr�
r-zBFTPClientTests.test_unparsableRemoveFileResponse.<locals>.<lambda>)
r�rMr�r%r8r9rwr�BadResponserb)rr0r)r�rr�!test_unparsableRemoveFileResponse
sz0FTPClientTests.test_unparsableRemoveFileResponsecCs8|��|j�d�}|j�d�|j�d�|�|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.
        z	/tmp/tests250-perhaps a progress reports250 okay)r�rMr�r%rbr�)rr0rrr� test_multilineRemoveFileResponse
s
z/FTPClientTests.test_multilineRemoveFileResponsecCsP|��|j�d�}|�|j��d�d}|j�|�|jj��|�	|j|g�S)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.
        z	/tmp/testsRMD /tmp/test
z*250 Requested file action okay, completed.)
r�rM�removeDirectoryrhrCr�r%r8r9rb)rr0r�rrr�test_removeDirectory+
sz#FTPClientTests.test_removeDirectorycsf����j�d�}���j��d�d��j����jj����	|t
j�}|���fdd��|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}.
        z	/tmp/testsRMD /tmp/test
z,501 Syntax error in parameters or arguments.cs��|j�gf�S)N)rhrs)r�)r�rrrr�F
r-z;FTPClientTests.test_failedRemoveDirectory.<locals>.<lambda>)
r�rMr�rhrCr�r%r8r9rwrrxrb)rr0r)r�rr�test_failedRemoveDirectory9
sz)FTPClientTests.test_failedRemoveDirectorycsT����j�d�}d��j����jj����|tj�}|�	��fdd��|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.
        z	/tmp/testz765 blah blah blahcs��|j�gf�S)N)rhrs)r�)r�rrrr�U
r-zGFTPClientTests.test_unparsableRemoveDirectoryResponse.<locals>.<lambda>)
r�rMr�r%r8r9rwrr�rb)rr0r)r�rr�&test_unparsableRemoveDirectoryResponseJ
sz5FTPClientTests.test_unparsableRemoveDirectoryResponsecCs8|��|j�d�}|j�d�|j�d�|�|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.
        z	/tmp/tests250-perhaps a progress reports250 okay)r�rMr�r%rbr�)rr0rrr�%test_multilineRemoveDirectoryResponseY
s
z4FTPClientTests.test_multilineRemoveDirectoryResponseN)-r)r*r+r|rgr8r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�r�rrrrr��sT
&&#.%(6.('

r�c@s8eZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�ZdS)
�FTPClientBasicTestsz
    FTP client
    cCs&t��}|�d�|�dg|j�dS)z?
        The first response is captured as a greeting.
        s220 Imaginary FTP.z220 Imaginary FTP.N)rr}r%rh�greeting)rr�rrr�
test_greetingk
s
z!FTPClientBasicTests.test_greetingcCs&t��}|�d�|�dg|j�dS)z�
        Responses with no message are still valid, i.e. three digits
        followed by a space is complete response.
        s220 z220 N)rr}r%rhr�)rr�rrr�test_responseWithNoMessaget
s
z.FTPClientBasicTests.test_responseWithNoMessagec	Cs�t��}t��|_|�d�|�d�}g}|�|j�|�	|j
�|�d�|�g|�|�d�|�g|�|�d�|�g|�|�d�|�g|�|�d�|�g|�|�d�|�g|�|�d	�|�d
ddd
dddg|d�dS)z$
        Multiline response
        s220 Imaginary FTP.ZBLAHs210-First line.s123-Second line.sJust some text.sHir-s321s	210 Done.z210-First line.z123-Second line.zJust some text.ZHir�Z321z	210 Done.rN)rr}rr�rCr%rlrbr#r�r�rh)rr�r�r�rrr�test_MultilineResponse~
s8









z*FTPClientBasicTests.test_MultilineResponsecCsdt��}t��|_|�d�|�dd�|�d|j���|j�	�|�d�|�d|j���dS)zO
        Passing None as the password avoids sending the PASS command.
        s220 Welcome to Imaginary FTP.�bobNs
USER bob
s200 Hello bob.r-)
rr}rr�rCr%�
queueLoginrhr�r�)rr�rrr�test_noPasswordGiven�
s



z(FTPClientBasicTests.test_noPasswordGivencCsdt��}t��|_|�d�|�dd�|�d|j���|j�	�|�d�|�d|j���dS)zQ
        Receiving a 230 response to USER prevents PASS from being sent.
        s220 Welcome to Imaginary FTP.r�Zsecrets
USER bob
s#230 Hello bob.  No password needed.r-N)
rr}rr�rCr%r�rhr�r�)rr�rrr�test_noPasswordNeeded�
s



z)FTPClientBasicTests.test_noPasswordNeededN)	r)r*r+r|r�r�r�r�r�rrrrr�g
s	
3r�c@seZdZdZdd�ZdS)�PathHandlingTestsz
    Handling paths.
    c
Cs:xbddgfddgfdgfddddgfddddgfddgfd	dgfgD]\}}|�t�g|�|�qDWxvdddgfd
ddgfddgfddgfd
dddgfddddgfdddgfdddgfgD]\}}|�t�dg|�|�q�WxFdgfddgfddgfdddgfgD]\}}|�t�g|�|��qWxBdgfddgfddddgfgD] \}}|�t�dg|�|��qDWx�dgfdgfddgfdgfddgfddgfdddgfdddgfd dgfd!dgfd"gfd#gfgD] \}}|�t�dg|�|��q�Wx"d$D]}|�tjtjg|��q�Wx$d%D]}|�tjtjdg|��qWd&S)'z"
        Normalize paths.
        r�z/a�/za/b/cr��cz/a/b/cz/a/za/zb/z/bz/b/zb/czb/c/z/b/cz/b/c/z//z//aza//za//bz//bzb//cz..z../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/../)	z..z../za/../..za/../../z/..z/../z/a/../..z	/a/../../z
/a/b/../../..)z../..z../../z
../a/../..N)rhrZ
toSegmentsr�ZInvalidPath)rZinpZoutprrr�test_Normalizer�
sV






z!PathHandlingTests.test_NormalizerN)r)r*r+r|r�rrrrr��
sr�c@s(eZdZdZdd�Zdd�Zdd�ZdS)	�IsGlobbingExpressionTestsz;
    Tests for _isGlobbingExpression utility function.
    cCs2|�t���|�t�g��|�t�d��dS)z^
        _isGlobbingExpression will return False for None, or empty
        segments.
        N)r�r�_isGlobbingExpression)rrrr�&test_isGlobbingExpressionEmptySegments"sz@IsGlobbingExpressionTests.test_isGlobbingExpressionEmptySegmentscCs,|�t�ddg��|�t�ddg��dS)z�
        _isGlobbingExpression will return False for plain segments.

        Also, it only checks the last segment part (filename) and will not
        check the path name.
        r��exprz*.txtN)r�rr�)rrrr�test_isGlobbingExpressionNoGlob,sz9IsGlobbingExpressionTests.test_isGlobbingExpressionNoGlobcCs@|�t�ddg��|�t�ddg��|�t�ddg��dS)z�
        _isGlobbingExpression will return True for segments which contains
        globbing characters in the last segment part (filename).
        r�z*.txtz	[a-b].txtzfil?.txtN)r�rr�)rrrr�test_isGlobbingExpressionGlob7sz7IsGlobbingExpressionTests.test_isGlobbingExpressionGlobN)r)r*r+r|r�r�r�rrrrr�s
r�c@s0eZdZdZdd�Zdd�Zdd�Zdd	�Zd
S)�BaseFTPRealmTestsz�
    Tests for L{ftp.BaseFTPRealm}, a base class to help define L{IFTPShell}
    realms with different user home directory policies.
    cCs|�tttj��dS)z;
        L{ftp.BaseFTPRealm} implements L{IRealm}.
        N)r�rr	r�BaseFTPRealm)rrrr�test_interfaceGsz BaseFTPRealmTests.test_interfacecslt�|����g�G��fdd�dtj�}||���}|�ddtj�\}}}|�|tj�|�	|j
��dS)z�
        L{ftp.BaseFTPRealm} calls its C{getHomeDirectory} method with the
        avatarId being requested to determine the home directory for that
        avatar.
        cseZdZ��fdd�ZdS)z:BaseFTPRealmTests.test_getHomeDirectory.<locals>.TestRealmcs��|��S)N)r#)rZavatarId)�avatarsr�rr�getHomeDirectoryWs
zKBaseFTPRealmTests.test_getHomeDirectory.<locals>.TestRealm.getHomeDirectoryN)r)r*r+r�r)r�r�rr�	TestRealmVsr�zalice@example.comN)rrSrOrr��
requestAvatar�	IFTPShellr��FTPShellrh�filesystemRoot)rr��realm�iface�avatar�logoutr)r�r�r�test_getHomeDirectoryNsz'BaseFTPRealmTests.test_getHomeDirectorycCsP|��}t�|�}|�tjdtj�\}}}|�|tj�|�	|j
t�|��dS)zy
        L{ftp.BaseFTPRealm} returns an L{ftp.FTPAnonymousShell} instance for
        anonymous avatar requests.
        N)
rOrr�r�rZ	ANONYMOUSr�r�r�rhr�rrS)rr?r�r�r�r�rrr�test_anonymousbs
z BaseFTPRealmTests.test_anonymouscCs$t�|���}|�t|jt��dS)z�
        L{ftp.BaseFTPRealm.getHomeDirectory} should be overridden by a subclass
        and raises L{NotImplementedError} if it is not.
        N)rr�rOr��NotImplementedErrorr�r�)rr�rrr�test_notImplementedosz%BaseFTPRealmTests.test_notImplementedN)r)r*r+r|r�rrrrrrrr�Bs

r�c@s eZdZdZdd�Zdd�ZdS)�
FTPRealmTestsz$
    Tests for L{ftp.FTPRealm}.
    cCs:d}t�|��|�}|�d�}|�t�|��d�|�dS)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/homezalice@example.comN)rrUrOr�rhrrSr�)r�baser��homerrrr}s

z#FTPRealmTests.test_getHomeDirectorycCs.t�|���}|�d�}|�t�d�|�dS)z�
        If no extra directory is passed to L{ftp.FTPRealm}, it uses C{"/home"}
        as the base directory containing all user home directories.
        zalice@example.comz/home/alice@example.comN)rrUrOr�rhrrS)rr�rrrr�test_defaultHomeDirectory�s
z'FTPRealmTests.test_defaultHomeDirectoryN)r)r*r+r|rrrrrrrys
rc@s$eZdZdZeZdd�Zdd�ZdS)�SystemFTPRealmTestsz*
    Tests for L{ftp.SystemFTPRealm}.
    cCsJt��}ddl}|�|�j}t�|���}|�|�}|�	|t
�|��dS)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)�getpassZgetuserr��getpwnam�pw_dirr�SystemFTPRealmrOr�rhrrS)rrr�r�r�rrrrr�s
z)SystemFTPRealmTests.test_getHomeDirectorycCsFt�tj�d�dd�td�D��}t�|���}|�	t
|j|�dS)z�
        L{ftp.SystemFTPRealm.getHomeDirectory} raises L{UnauthorizedLogin} when
        passed a username which has no corresponding home directory in the
        system's accounts database.
        r�css |]}t�tjtj�VqdS)N)�random�choice�string�
ascii_letters�digits)r6r�rrr�	<genexpr>�sz6SystemFTPRealmTests.test_noSuchUser.<locals>.<genexpr>r�N)r
rrrr�rrrrOr�rr�)rrr�rrr�test_noSuchUser�sz#SystemFTPRealmTests.test_noSuchUserN)r)r*r+r|�nonPOSIXSkip�skiprrrrrrr�src@sHeZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�Zdd
�Z	dd�Z
dS)�ErrnoToFailureTestsz9
    Tests for L{ftp.errnoToFailure} errno checking.
    cCst�tjd�}|�|tj�S)zS
        C{errno.ENOENT} should be translated to L{ftp.FileNotFoundError}.
        r�)r�errnoToFailure�errno�ENOENTrw�FileNotFoundError)rr0rrr�
test_notFound�sz!ErrnoToFailureTests.test_notFoundcCst�tjd�}|�|tj�S)zV
        C{errno.EPERM} should be translated to L{ftp.PermissionDeniedError}.
        r�)rrr�EPERMrw�PermissionDeniedError)rr0rrr�test_permissionDenied�sz)ErrnoToFailureTests.test_permissionDeniedcCst�tjd�}|�|tj�S)zW
        C{errno.EACCES} should be translated to L{ftp.PermissionDeniedError}.
        r�)rrr�EACCESrwr)rr0rrr�test_accessDenied�sz%ErrnoToFailureTests.test_accessDeniedcCst�tjd�}|�|tj�S)zW
        C{errno.ENOTDIR} should be translated to L{ftp.IsNotADirectoryError}.
        r�)rrr�ENOTDIRrw�IsNotADirectoryError)rr0rrr�test_notDirectory�sz%ErrnoToFailureTests.test_notDirectorycCst�tjd�}|�|tj�S)zQ
        C{errno.EEXIST} should be translated to L{ftp.FileExistsError}.
        r�)rrr�EEXISTrw�FileExistsError)rr0rrr�test_fileExists�sz#ErrnoToFailureTests.test_fileExistscCst�tjd�}|�|tj�S)zS
        C{errno.EISDIR} should be translated to L{ftp.IsADirectoryError}.
        r�)rrrZEISDIRrwr�)rr0rrr�test_isDirectory�sz$ErrnoToFailureTests.test_isDirectorycCs0ytd��Wnt�dd�}|�|t�SdS)z�
        If an unknown errno is passed to L{ftp.errnoToFailure}, it should let
        the originating exception pass through.
        r�r�r�N)r�rrrw)rr0rrr�test_passThrough�s
z$ErrnoToFailureTests.test_passThroughN)r)r*r+r|rrr r#r&r'r(rrrrr�src@seZdZdZdd�ZdS)�AnonymousFTPShellTestsz*
    Test anonymous shell properties.
    cCs&t�d�}|�d�}|�|tj�|S)zt
        Check that L{ftp.FTPAnonymousShell} returns an error when trying to
        open it in write mode.
        r�)r�)rr�r�rwr)rr�r0rrr�test_anonymousWrites

z*AnonymousFTPShellTests.test_anonymousWriteN)r)r*r+r|r*rrrrr)�sr)c@s2eZdZdZdd�Zdd�Zdd�ZdLd	d
�Zdd�Zd
d�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zdd �Zd!d"�Zd#d$�Zd%d&�Zd'd(�Zd)d*�Zd+d,�Zd-d.�Zd/d0�Zd1d2�Zd3d4�Zd5d6�Zd7d8�Zd9d:�Zd;d<�Z d=d>�Z!d?d@�Z"dAdB�Z#dCdD�Z$dEdF�Z%dGdH�Z&dIdJ�Z'dKS)M�IFTPShellTestsMixinz7
    Generic tests for the C{IFTPShell} interface.
    cCs
t��dS)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}
        N)r)rr
rrr�directoryExistssz#IFTPShellTestsMixin.directoryExistscCs
t��dS)z�
        Create a directory in C{path}.

        @param path: the relative path of the directory to create, with one
            segment.
        @type path: C{str}
        N)r)rr
rrrr�#sz#IFTPShellTestsMixin.createDirectorycCs
t��dS)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}
        N)r)rr
rrr�
fileExists.szIFTPShellTestsMixin.fileExistsr-cCs
t��dS)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}
        N)r)rr
�fileContentrrr�
createFile<szIFTPShellTestsMixin.createFilecCs.|�|�d��|�d�|�|�d��dS)z�
        C{directoryExists} should report correctly about directory existence,
        and C{createDirectory} should create a directory detectable by
        C{directoryExists}.
        r�N)r�r,r�r�)rrrr�test_createDirectoryJs
z(IFTPShellTestsMixin.test_createDirectorycCs.|�|�d��|�d�|�|�d��dS)z�
        C{fileExists} should report correctly about file existence, and
        C{createFile} should create a file detectable by C{fileExists}.
        zfile.txtN)r�r-r/r�)rrrr�test_createFileUs
z#IFTPShellTestsMixin.test_createFilecs"�j�d�}�fdd�}|�|�S)zI
        Create a directory and check it ends in the filesystem.
        )r�cs����d��dS)Nr�)r�r,)r�)rrrr�dsz2IFTPShellTestsMixin.test_makeDirectory.<locals>.cb)r�r�rb)rr0r�r)rrr�_sz&IFTPShellTestsMixin.test_makeDirectorycCs$|�d�|j�d�}|�|tj�S)zm
        Creating a directory that already exists should fail with a
        C{ftp.FileExistsError}.
        r�)r�)r�r�r�rwrr%)rr0rrr�test_makeDirectoryErroris
z+IFTPShellTestsMixin.test_makeDirectoryErrorcs,��d��j�d�}�fdd�}|�|�S)zW
        Try to remove a directory and check it's removed from the filesystem.
        r�)r�cs����d��dS)Nr�)r�r,)r�)rrrr�ysz4IFTPShellTestsMixin.test_removeDirectory.<locals>.cb)r�r�r�rb)rr0r�r)rrr�ss
z(IFTPShellTestsMixin.test_removeDirectorycCs$|�d�|j�d�}|�|tj�S)zn
        removeDirectory should not work in file and fail with a
        C{ftp.IsNotADirectoryError}.
        zfile.txt)zfile.txt)r/r�r�rwrr")rr0rrr�test_removeDirectoryOnFile~s
z.IFTPShellTestsMixin.test_removeDirectoryOnFilecCs|j�d�}|�|tj�S)zl
        Removing directory that doesn't exist should fail with a
        C{ftp.FileNotFoundError}.
        )r�)r�r�rwrr)rr0rrr�test_removeNotExistingDirectory�sz3IFTPShellTestsMixin.test_removeNotExistingDirectorycs0��d��j�d�}�fdd�}|�|�|S)zR
        Try to remove a file and check it's removed from the filesystem.
        zfile.txt)zfile.txtcs����d��dS)Nzfile.txt)r�r-)r�)rrrr��sz/IFTPShellTestsMixin.test_removeFile.<locals>.cb)r/r�r�rb)rr0r�r)rrr��s


z#IFTPShellTestsMixin.test_removeFilecCs$|�d�|j�d�}|�|tj�S)z:
        removeFile should not work on directory.
        �ned)r5)r�r�r�rwrr�)rr0rrr�test_removeFileOnDirectory�s
z.IFTPShellTestsMixin.test_removeFileOnDirectorycCs|j�d�}|�|tj�S)zl
        Try to remove a non existent file, and check it raises a
        L{ftp.FileNotFoundError}.
        )r�)r�r�rwrr)rr0rrr�test_removeNotExistingFile�sz.IFTPShellTestsMixin.test_removeNotExistingFilecs6��d���d��j�d�}�fdd�}|�|�S)z6
        Check the output of the list method.
        r5zfile.txt)�.cs$|����|dgfdgfg�dS)Nzfile.txtr5)rrh)r9)rrrr��sz)IFTPShellTestsMixin.test_list.<locals>.cb)r�r/r�r�rb)rr0r�r)rr�	test_list�s


zIFTPShellTestsMixin.test_listcs8��d���d��j�dd�}�fdd�}|�|�S)z<
        Check the output of list with asked stats.
        r5zfile.txt)r8)r"Zpermissionscst|����t|�d���|ddd���|ddd���t|dd�d���t|dd�d�dS)Nrrzfile.txtr�r5)rrhr�)r9)rrrr��sz1IFTPShellTestsMixin.test_listWithStat.<locals>.cb)r�r/r�r�rb)rr0r�r)rr�test_listWithStat�s


	z%IFTPShellTestsMixin.test_listWithStatcCs$|�d�|j�dd�}|�|t�S)zP
        Querying an invalid stat should result to a C{AttributeError}.
        r5)r8)r"�whateverstat)r�r�r�rw�AttributeError)rr0rrr�test_listWithInvalidStat�s
z,IFTPShellTestsMixin.test_listWithInvalidStatcs,��d��j�d�}�fdd�}|�|�S)z@
        Check the output of the list method on a file.
        zfile.txt)zfile.txtcs|����|dgfg�dS)Nzfile.txt)rrh)r9)rrrr��sz-IFTPShellTestsMixin.test_listFile.<locals>.cb)r/r�r�rb)rr0r�r)rr�
test_listFile�s
z!IFTPShellTestsMixin.test_listFilecCs|j�d�}|�|tj�S)zm
        list on a directory that doesn't exist should fail with a
        L{ftp.FileNotFoundError}.
        )r�)r�r�rwrr)rr0rrr�test_listNotExistingDirectory�sz1IFTPShellTestsMixin.test_listNotExistingDirectorycCs|�d�|j�d�}|S)z+
        Try to access a resource.
        r5)r5)r�r��access)rr0rrr�test_access�s
zIFTPShellTestsMixin.test_accesscCs|j�d�}|�|tj�S)zF
        access should fail on a resource that doesn't exist.
        )r�)r�r@rwrr)rr0rrr�test_accessNotFound�sz'IFTPShellTestsMixin.test_accessNotFoundcs0��d��j�d�}�fdd�}|�|�|S)zY
        Check that openForReading returns an object providing C{ftp.IReadFile}.
        zfile.txt)zfile.txtcs��tj�|��dS)N)r�rZ	IReadFile�
providedBy)r�)rrrr�
sz3IFTPShellTestsMixin.test_openForReading.<locals>.cb)r/r�r�rb)rr0r�r)rr�test_openForReading
s


z'IFTPShellTestsMixin.test_openForReadingcCs|j�d�}|�|tj�S)zr
        openForReading should fail with a C{ftp.FileNotFoundError} on a file
        that doesn't exist.
        )r5)r�r�rwrr)rr0rrr�test_openForReadingNotFound
sz/IFTPShellTestsMixin.test_openForReadingNotFoundcCs$|�d�|j�d�}|�|tj�S)z>
        openForReading should not work on directory.
        r5)r5)r�r�r�rwrr�)rr0rrr�test_openForReadingOnDirectory
s
z2IFTPShellTestsMixin.test_openForReadingOnDirectorycs4�j�d�}��fdd�}�fdd��|�|�|S)zZ
        Check that openForWriting returns an object providing C{ftp.IWriteFile}.
        )r�cs ��tj�|��|�����S)N)r�r�
IWriteFilerCr�rb)r�)�cb2rrr�cb1#
sz4IFTPShellTestsMixin.test_openForWriting.<locals>.cb1cs��t�|��dS)N)r�rrC)r�)rrrrH&
sz4IFTPShellTestsMixin.test_openForWriting.<locals>.cb2)r�r�rb)rr0rIr)rHrr�test_openForWriting
s

z'IFTPShellTestsMixin.test_openForWritingcCs$|�d�|j�d�}|�|tj�S)zd
        openForWriting should not be able to open a directory that already
        exists.
        r5)r5)r�r�r�rwrr�)rr0rrr�$test_openForWritingExistingDirectory,
s
z8IFTPShellTestsMixin.test_openForWritingExistingDirectorycCs$|�d�|j�d�}|�|tj�S)z�
        openForWring should fail with a L{ftp.FileNotFoundError} if you specify
        a file in a directory that doesn't exist.
        r5)r5Zidonotexistr�)r�r�r�rwrr)rr0rrr�)test_openForWritingInNotExistingDirectory6
s
z=IFTPShellTestsMixin.test_openForWritingInNotExistingDirectorycs:d���d���j�dd�}��fdd�}|�|�|S)z@
        Check the output of the stat method on a file.
        swobble
zfile.txt)zfile.txt)r"rPcs&��|dt�����|d�dS)Nrr�)rhr�r�)r�)r.rrrr�G
sz-IFTPShellTestsMixin.test_statFile.<locals>.cb)r/r��statrb)rr0r�r)r.rr�
test_statFile@
s
z!IFTPShellTestsMixin.test_statFilecs2��d��j�dd�}�fdd�}|�|�|S)zE
        Check the output of the stat method on a directory.
        r5)r5)r"rPcs��|d�dS)Nr�)r�)r�)rrrr�T
sz2IFTPShellTestsMixin.test_statDirectory.<locals>.cb)r�r�rMrb)rr0r�r)rr�test_statDirectoryN
s


z&IFTPShellTestsMixin.test_statDirectorycs2��d��j�dd�}�fdd�}|�|�|S)z3
        Check the owner and groups stats.
        r5)r5)rfrcs��t|�d�dS)Nr)rhr�)r�)rrrr�`
sz3IFTPShellTestsMixin.test_statOwnerGroup.<locals>.cb)r�r�rMrb)rr0r�r)rr�test_statOwnerGroupZ
s


z'IFTPShellTestsMixin.test_statOwnerGroupcsV|jj�dd����fdd�}||j_|�d�|j�dd�}|�|�|�dg�d	S)
z�
        If L{twisted.python.filepath.FilePath.getNumberOfHardLinks} is not
        implemented, the number returned is 0
        cSst�dS)N)rrrrr�raiseNotImplementedm
szQIFTPShellTestsMixin.test_statHardlinksNotImplemented.<locals>.raiseNotImplementedcs�|�}�|_|S)N)ZgetNumberOfHardLinks)r
r!)�pathFuncrQrr�notImplementedFilePathp
szTIFTPShellTestsMixin.test_statHardlinksNotImplemented.<locals>.notImplementedFilePathr5)r5)Z	hardlinksrN)r��_pathr�rMrh�successResultOf)rrSr0r)rRrQr� test_statHardlinksNotImplementedf
s
z4IFTPShellTestsMixin.test_statHardlinksNotImplementedcsX|jj�dd����fdd�}||j_|�d�|j�dd�}|�|�|�ddg�d	S)
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"
        cSst�dS)N)rrrrrrQ�
szRIFTPShellTestsMixin.test_statOwnerGroupNotImplemented.<locals>.raiseNotImplementedcs�|�}�|_�|_|S)N)Z	getUserIDZ
getGroupID)r
r!)rRrQrrrS�
szUIFTPShellTestsMixin.test_statOwnerGroupNotImplemented.<locals>.notImplementedFilePathr5)r5)rfr�0N)r�rTr�rMrhrU)rrSr0r)rRrQr�!test_statOwnerGroupNotImplemented|
s
z5IFTPShellTestsMixin.test_statOwnerGroupNotImplementedcCs|j�dd�}|�|tj�S)zf
        stat should fail with L{ftp.FileNotFoundError} on a file that doesn't
        exist.
        )r�)r"rP)r�rMrwrr)rr0rrr�test_statNotExisting�
sz(IFTPShellTestsMixin.test_statNotExistingcCs$|�d�|j�dd�}|�|t�S)zP
        Querying an invalid stat should result to a C{AttributeError}.
        r5)r5)r"r;)r�r�rMrwr<)rr0rrr�test_invalidStat�
s
z$IFTPShellTestsMixin.test_invalidStatcs.��d��j�dd�}�fdd�}|�|�S)z,
        Try to rename a directory.
        r5)r5)r�cs$����d������d��dS)Nr�r5)r�r,r�)r�)rrrr��
sz+IFTPShellTestsMixin.test_rename.<locals>.cb)r�r�r�rb)rr0r�r)rr�test_rename�
s
zIFTPShellTestsMixin.test_renamecCs|j�dd�}|�|tj�S)zl
        Renaming a directory that doesn't exist should fail with
        L{ftp.FileNotFoundError}.
        )r�)r�)r�r�rwrr)rr0rrr�test_renameNotExisting�
sz*IFTPShellTestsMixin.test_renameNotExistingN)r-)(r)r*r+r|r,r�r-r/r0r1r�r2r�r3r4r�r6r7r9r:r=r>r?rArBrDrErFrJrKrLrNrOrPrVrXrYrZr[r\rrrrr+sJ




				
				

		r+c@s:eZdZdZdd�Zdd�Zdd�Zdd	�Zddd�Zd
S)�
FTPShellTestsz/
    Tests for the C{ftp.FTPShell} object.
    cCs,t�|���|_|j��t�|j�|_dS)zB
        Create a root directory and instantiate a shell.
        N)rrSrOrgr�rr�r�)rrrrrg�
s
zFTPShellTests.setUpcCs|j�|���S)z:
        Test if the directory exists at C{path}.
        )rgr��isdir)rr
rrrr,�
szFTPShellTests.directoryExistscCs|j�|���S)z0
        Create a directory in C{path}.
        )rgr�r�)rr
rrrr��
szFTPShellTests.createDirectorycCs|j�|���S)z5
        Test if the file exists at C{path}.
        )rgr��isfile)rr
rrrr-�
szFTPShellTests.fileExistsr-cCs|j�|��|�S)z@
        Create a file named C{path} with some content.
        )rgr��
setContent)rr
r.rrrr/�
szFTPShellTests.createFileN)r-)	r)r*r+r|rgr,r�r-r/rrrrr]�
s	r]c@s,eZdZdZdZdd�Zdd�Zdd�ZdS)	�TestConsumerz�
    A simple consumer for tests. It only works with non-streaming producers.

    @ivar producer: an object providing
        L{twisted.internet.interfaces.IPullProducer}.
    NcCs(|jdkst�g|_||_|j��dS)z�
        Simple register of producer, checks that no register has happened
        before.

        @param producer: pull producer to use
        @param streaming: unused
        N)�producerr�r.�resumeProducing)rrbZ	streamingrrr�registerProducer�
szTestConsumer.registerProducercCs|jdk	st�d|_dS)zN
        Unregister the producer, it should be done after a register.
        N)rbr�)rrrr�unregisterProducerszTestConsumer.unregisterProducercCs|j�|�|j��dS)zN
        Save the data received.

        @param data: data to append
        N)r.r#rbrc)rr&rrrr$szTestConsumer.write)r)r*r+r|rbrdrer$rrrrra�
s
rac@s eZdZdZdd�Zdd�ZdS)�TestProducerz
    A dumb producer.
    cCs||_||_dS)z�
        @param toProduce: data to write
        @type toProduce: C{str}
        @param consumer: the consumer of data.
        @type consumer: C{IConsumer}
        N)�	toProducer�)rrgr�rrrrszTestProducer.__init__cCs|j�|j�dS)z+
        Send the data to consume.
        N)r�r$rg)rrrr�start#szTestProducer.startN)r)r*r+r|rrhrrrrrfsrfc@s8eZdZdZdd�Zdd�Zdd�Zdd	�Zd
d�ZdS)
�IReadWriteTestsMixinzJ
    Generic tests for the C{IReadFile} and C{IWriteFile} interfaces.
    cCs
t��dS)z
        Return an object providing C{IReadFile}, ready to send data C{content}.

        @param content: data to send
        N)r)r�contentrrr�
getFileReader0sz"IReadWriteTestsMixin.getFileReadercCs
t��dS)zR
        Return an object providing C{IWriteFile}, ready to receive data.
        N)r)rrrr�
getFileWriter9sz"IReadWriteTestsMixin.getFileWritercCs
t��dS)z6
        Return the content of the file used.
        N)r)rrrr�getFileContent@sz#IReadWriteTestsMixin.getFileContentcs8d�t����fdd�}���fdd�������|�S)z�
        Test L{ftp.IReadFile}: the implementation should have a send method
        returning a C{Deferred} which fires when all the data has been sent
        to the consumer, and the data should be correctly send to the consumer.
        swobble
cs|������S)N)r�rb)�reader)�cbSendr�rrr�Osz-IReadWriteTestsMixin.test_read.<locals>.cbGetcs��d��j���dS)Nr-)rhr�r.)r�)r�rjrrrroQsz.IReadWriteTestsMixin.test_read.<locals>.cbSend)rarkrb)rr�r)ror�rjrr�	test_readGs
zIReadWriteTestsMixin.test_readcs:d��fdd�}��fdd����fdd������|�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
cs|����|�S)N)r�rb)�writer)�	cbReceiverrr�^sz.IReadWriteTestsMixin.test_write.<locals>.cbGetcs4t�|�}|�dd�|��|��|�����S)NT)rfrdrhre�closerb)r�rqrb)�cbCloserjrrrr`s

z2IReadWriteTestsMixin.test_write.<locals>.cbReceivecs�������dS)N)rhrm)rm)rjrrrrtfsz0IReadWriteTestsMixin.test_write.<locals>.cbClose)rlrb)rr�r)rtrrrjrr�
test_writeVs
zIReadWriteTestsMixin.test_writeN)	r)r*r+r|rkrlrmrprurrrrri+s	ric@s0eZdZdZdd�Zdd�Zdd�Zdd	�Zd
S)�FTPReadWriteTestsz�
    Tests for C{ftp._FileReader} and C{ftp._FileWriter}, the objects returned
    by the shell in C{openForReading}/C{openForWriting}.
    cCs2t�|���|_|j��t�|j�|_d|_dS)z5
        Create a temporary file used later.
        zfile.txtN)	rrSrOrgr�rr�r�ri)rrrrrgrs
zFTPReadWriteTests.setUpcCs$|j�|j��|�|j�|jf�S)zV
        Return a C{ftp._FileReader} instance with a file opened for reading.
        )rgr�rir`r�r�)rrjrrrrk|szFTPReadWriteTests.getFileReadercCs|j�|jf�S)zV
        Return a C{ftp._FileWriter} instance with a file opened for writing.
        )r�r�ri)rrrrrl�szFTPReadWriteTests.getFileWritercCs|j�|j���S)z;
        Return the content of the temporary file.
        )rgr�riZ
getContent)rrrrrm�sz FTPReadWriteTests.getFileContentN)r)r*r+r|rgrkrlrmrrrrrvls

rvc@s$eZdZdZdZdd�Zdd�ZdS)�CloseTestWriterz"
    Close writing to a file.
    FcCst�|_t�|j�}t�|�S)z>
        Receive bytes.

        @return: L{Deferred}
        )rr.rZFileConsumerr
rp)rZfcrrrr��szCloseTestWriter.receivecCsd|_|jS)z<
        Close bytes.

        @return: L{Deferred}
        T)�closeStartedr0)rrrrrs�szCloseTestWriter.closeN)r)r*r+r|rxr�rsrrrrrw�srwc@seZdZdZdd�ZdS)�CloseTestShellz
    Close writing shell.
    cCst�|j�S)N)r
rprq)rZsegsrrrr��szCloseTestShell.openForWritingN)r)r*r+r|r�rrrrry�sryc@seZdZdZdd�ZdS)�
FTPCloseTestsz8
    Tests that the server invokes IWriteFile.close
    cCs�t��}dg|_t�|_t�|j_t��|jj_	t�
�|_d|j_|�
t��t��}t�|�|_||_|�
d�g}|�d�}|�|j�|�|jjjd�|�d�|�|jjjd�|�d�|�|jjjd�|�|�|jjj	�d�|�|�|S)	z�
            Confirm that FTP uploads (i.e. ftp_STOR) correctly call and wait
            upon the IWriteFile object's close() method
        rgNr
zclose() called earlyssome data herezreason is ignoredzclose() not calledzallow close() to finish)rZFTPZworkingDirectoryryr�rwrqr
r/r0r[r ZtimeOutrUrrIrAr�Zftp_STORrbr#r�rxr1r4r�r2)rr!ZdiZ	stor_doner0rrrru�s0







zFTPCloseTests.test_writeN)r)r*r+r|rurrrrrz�srzc@seZdZdZdd�ZdS)�FTPResponseCodeTestsz4
    Tests relating directly to response codes.
    cCsvttj�}t�}x`tt���D]P\}}t|t�r|��r|�||d||f�|�	||d||f�|�
|�qWdS)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.
        z0Code %r with value %r missing from RESPONSE dictzDuplicate code %r with value %rN)�setrZRESPONSE�vars�items�
isinstancer��isupperr�ZassertNotIn�add)rZ	allValuesZ
seenValues�keyr�rrr�test_unique�s
z FTPResponseCodeTests.test_uniqueN)r)r*r+r|r�rrrrr{�sr{)r5r6)Ur|rQr�iorr	rr
Zzope.interfacerZzope.interface.verifyrZtwisted.credrrrZtwisted.cred.errorrZtwisted.cred.portalr	Ztwisted.internetr
rrr
rZtwisted.internet.interfacesrZtwisted.protocolsrZtwisted.pythonrrrZtwisted.python.compatrZtwisted.testrZ
twisted.trialrrr�platformZ	isWindowsrZLineReceiverrr}r,r=ZTestCaser>r~r�r�r�r0r=rSrXr\rZr^rr�r�r�r�r�rrrr)r+r]r�rarfrirvrGrwryrzr{rrrr�<module>s�
sRU	*;=x>%7(B/++A'	*