U
    
W[7b  ã                   @   sº   d Z ddlmZmZ ddlmZ ddlmZmZ ddlm	Z	m
Z
 ddlmZ ddlmZ ddlmZ dd	lmZmZmZ dd
lmZ G dd„ dƒZG dd„ deeƒZG dd„ deeƒZdS )z$
Test the memcache client protocol.
é    )Úabsolute_importÚdivision)ÚConnectionDone)ÚMemCacheProtocolÚNoSuchCommand)ÚClientErrorÚServerError)ÚTestCase)Ú StringTransportWithDisconnection)ÚClock)ÚDeferredÚgatherResultsÚTimeoutError)ÚDeferredListc                   @   s°   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd d!„ Zd"d#„ Zd$d%„ Zd&d'„ Zd(d)„ Zd*S )+ÚCommandMixinzO
    Setup and tests for basic invocation of L{MemCacheProtocol} commands.
    c                 C   s
   t ƒ ‚dS )zp
        Helper test method to test the resulting C{Deferred} of a
        L{MemCacheProtocol} command.
        N)ÚNotImplementedError©ÚselfÚdÚsendÚrecvÚresult© r   ú</usr/lib/python3/dist-packages/twisted/test/test_memcache.pyÚ_test   s    zCommandMixin._testc                 C   s   |   | j d¡ddd¡S )zÉ
        L{MemCacheProtocol.get} returns a L{Deferred} which is called back with
        the value and the flag associated with the given key if the server
        returns a successful result.
        ó   fooó	   get foo
ó   VALUE foo 0 3
bar
END
©r   ó   bar©r   ÚprotoÚget©r   r   r   r   Útest_get$   s    
  þzCommandMixin.test_getc                 C   s   |   | j d¡ddd¡S )zu
        Test getting a non-available key: it succeeds but return L{None} as
        value and C{0} as flag.
        r   r   ó   END
©r   Nr    r#   r   r   r   Útest_emptyGet/   s    
  þzCommandMixin.test_emptyGetc                 C   s"   |   | j ddg¡dddddœ¡S )z™
        L{MemCacheProtocol.getMultiple} returns a L{Deferred} which is called
        back with a dictionary of flag, value for each given key.
        r   ó   cowó   get foo cow
s1   VALUE foo 0 3
bar
VALUE cow 0 7
chicken
END
)r   s   chickenr   ©r(   r   ©r   r!   ÚgetMultipler#   r   r   r   Útest_getMultiple9   s    üzCommandMixin.test_getMultiplec                 C   s"   |   | j ddg¡dddddœ¡S )z‰
        When L{MemCacheProtocol.getMultiple} is called with non-available keys,
        the corresponding tuples are (0, None).
        r   r(   r)   s   VALUE cow 1 3
bar
END
)é   r   r&   r*   r+   r#   r   r   r   Útest_getMultipleWithEmptyE   s    üz&CommandMixin.test_getMultipleWithEmptyc                 C   s   |   | j dd¡ddd¡S )z†
        L{MemCacheProtocol.set} returns a L{Deferred} which is called back with
        C{True} when the operation succeeds.
        r   r   s   set foo 0 0 3
bar
ó   STORED
T)r   r!   Úsetr#   r   r   r   Útest_setQ   s      þzCommandMixin.test_setc                 C   s   |   | j dd¡ddd¡S )z†
        L{MemCacheProtocol.add} returns a L{Deferred} which is called back with
        C{True} when the operation succeeds.
        r   r   ó   add foo 0 0 3
bar
r0   T©r   r!   Úaddr#   r   r   r   Útest_add[   s      þzCommandMixin.test_addc                 C   s   |   | j dd¡ddd¡S )zŠ
        L{MemCacheProtocol.replace} returns a L{Deferred} which is called back
        with C{True} when the operation succeeds.
        r   r   ó   replace foo 0 0 3
bar
r0   T©r   r!   Úreplacer#   r   r   r   Útest_replacee   s      þzCommandMixin.test_replacec                 C   s   |   | j dd¡ddd¡S )zæ
        Test an erroneous add: if a L{MemCacheProtocol.add} is called but the
        key already exists on the server, it returns a B{NOT STORED} answer,
        which calls back the resulting L{Deferred} with C{False}.
        r   r   r3   ó   NOT STORED
Fr4   r#   r   r   r   Útest_errorAddo   s      þzCommandMixin.test_errorAddc                 C   s   |   | j dd¡ddd¡S )zí
        Test an erroneous replace: if a L{MemCacheProtocol.replace} is called
        but the key doesn't exist on the server, it returns a B{NOT STORED}
        answer, which calls back the resulting L{Deferred} with C{False}.
        r   r   r7   r;   Fr8   r#   r   r   r   Útest_errorReplacez   s      þzCommandMixin.test_errorReplacec                 C   s   |   | j d¡ddd¡S )z
        L{MemCacheProtocol.delete} returns a L{Deferred} which is called back
        with C{True} when the server notifies a success.
        r   ó   delete bar
s	   DELETED
T©r   r!   Údeleter#   r   r   r   Útest_delete…   s    
   ÿzCommandMixin.test_deletec                 C   s   |   | j d¡ddd¡S )z¿
        Test an error during a delete: if key doesn't exist on the server, it
        returns a B{NOT FOUND} answer which calls back the resulting
        L{Deferred} with C{False}.
        r   r>   s   NOT FOUND
Fr?   r#   r   r   r   Útest_errorDeleteŽ   s    
  þzCommandMixin.test_errorDeletec                 C   s   |   | j d¡ddd¡S )zµ
        Test incrementing a variable: L{MemCacheProtocol.increment} returns a
        L{Deferred} which is called back with the incremented value of the
        given key.
        r   s   incr foo 1
ó   4
é   ©r   r!   Ú	incrementr#   r   r   r   Útest_increment™   s    
   ÿzCommandMixin.test_incrementc                 C   s   |   | j d¡ddd¡S )zµ
        Test decrementing a variable: L{MemCacheProtocol.decrement} returns a
        L{Deferred} which is called back with the decremented value of the
        given key.
        r   s   decr foo 1
ó   5
é   ©r   r!   Z	decrementr#   r   r   r   Útest_decrement£   s    
   ÿzCommandMixin.test_decrementc                 C   s   |   | j dd¡ddd¡S )z‘
        L{MemCacheProtocol.increment} takes an optional argument C{value} which
        replaces the default value of 1 when specified.
        r   é   s   incr foo 8
rC   rD   rE   r#   r   r   r   Útest_incrementVal­   s       ÿzCommandMixin.test_incrementValc                 C   s   |   | j dd¡ddd¡S )z‘
        L{MemCacheProtocol.decrement} takes an optional argument C{value} which
        replaces the default value of 1 when specified.
        r   é   s   decr foo 3
rH   rI   rJ   r#   r   r   r   Útest_decrementVal¶   s       ÿzCommandMixin.test_decrementValc                 C   s   |   | j ¡ dddddœ¡S )zë
        Test retrieving server statistics via the L{MemCacheProtocol.stats}
        command: it parses the data sent by the server and calls back the
        resulting L{Deferred} with a dictionary of the received statistics.
        s   stats
ó"   STAT foo bar
STAT egg spam
END
r   ó   spam©r   ó   egg©r   r!   Ústatsr#   r   r   r   Ú
test_stats¿   s     ýzCommandMixin.test_statsc                 C   s   |   | j d¡dddddœ¡S )a9  
        L{MemCacheProtocol.stats} takes an optional C{bytes} argument which,
        if specified, is sent along with the I{STAT} command.  The I{STAT}
        responses from the server are parsed as key/value pairs and returned
        as a C{dict} (as in the case where the argument is not specified).
        s   blahs   stats blah
rP   r   rQ   rR   rT   r#   r   r   r   Útest_statsWithArgumentË   s    
 ýz#CommandMixin.test_statsWithArgumentc                 C   s   |   | j ¡ ddd¡S )z¸
        Test version retrieval via the L{MemCacheProtocol.version} command: it
        returns a L{Deferred} which is called back with the version sent by the
        server.
        s	   version
s   VERSION 1.1
s   1.1)r   r!   Úversionr#   r   r   r   Útest_versionØ   s       ÿzCommandMixin.test_versionc                 C   s   |   | j ¡ ddd¡S )z’
        L{MemCacheProtocol.flushAll} returns a L{Deferred} which is called back
        with C{True} if the server acknowledges success.
        s   flush_all
s   OK
T)r   r!   ZflushAllr#   r   r   r   Útest_flushAllâ   s       ÿzCommandMixin.test_flushAllN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r$   r'   r-   r/   r2   r6   r:   r<   r=   rA   rB   rG   rK   rM   rO   rV   rW   rY   rZ   r   r   r   r   r      s*   



	

		
r   c                   @   s   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd d!„ Zd"d#„ Zd$d%„ Zd&d'„ Zd(d)„ Zd*d+„ Zd,d-„ Zd.d/„ Zd0d1„ Zd2d3„ Zd4d5„ Zd6d7„ Zd8d9„ Zd:d;„ Z d<d=„ Z!d>S )?ÚMemCacheTestsz9
    Test client protocol class L{MemCacheProtocol}.
    c                 C   s@   t ƒ | _tƒ | _| jj| j_tƒ | _| j| j_| j | j¡ dS )z{
        Create a memcache client, connect it to a string protocol, and make it
        use a deterministic clock.
        N)	r   r!   r   ÚclockÚ	callLaterr
   Ú	transportÚprotocolÚmakeConnectionr#   r   r   r   ÚsetUpñ   s    
zMemCacheTests.setUpc                    s:   ‡ ‡fdd„}ˆ  ˆj ¡ |¡ | |¡ ˆj |¡ |S )aõ  
        Implementation of C{_test} which checks that the command sends C{send}
        data, and that upon reception of C{recv} the result is C{result}.

        @param d: the resulting deferred from the memcache command.
        @type d: C{Deferred}

        @param send: the expected data to be sent.
        @type send: C{bytes}

        @param recv: the data to simulate as reception.
        @type recv: C{bytes}

        @param result: the expected result.
        @type result: C{any}
        c                    s   ˆ  | ˆ ¡ d S ©N)ÚassertEqual)Úres©r   r   r   r   Úcb  s    zMemCacheTests._test.<locals>.cb)rg   rb   ÚvalueÚaddCallbackr!   ÚdataReceived)r   r   r   r   r   rj   r   ri   r   r   þ   s
    
zMemCacheTests._testc                 C   s"   | j  d¡ |  t| j jd¡ dS )z¥
        If the value returned doesn't match the expected key of the current
        C{get} command, an error is raised in L{MemCacheProtocol.dataReceived}.
        r   s   VALUE bar 0 7
spamegg
END
N)r!   r"   ÚassertRaisesÚRuntimeErrorrm   r#   r   r   r   Útest_invalidGetResponse  s     þz%MemCacheTests.test_invalidGetResponsec                 C   s&   | j  ddg¡ |  t| j jd¡ dS )zÁ
        If the value returned doesn't match one the expected keys of the
        current multiple C{get} command, an error is raised error in
        L{MemCacheProtocol.dataReceived}.
        r   r   s   VALUE egg 0 7
spamegg
END
N)r!   r,   rn   ro   rm   r#   r   r   r   Útest_invalidMultipleGetResponse"  s     þz-MemCacheTests.test_invalidMultipleGetResponsec                 C   s$   | j  dd¡ |  t| j jd¡ dS )z´
        If an END is received in response to an operation that isn't C{get},
        C{gets}, or C{stats}, an error is raised in
        L{MemCacheProtocol.dataReceived}.
        s   keys   valuer%   N)r!   r1   rn   ro   rm   r#   r   r   r   Útest_invalidEndResponse.  s     þz%MemCacheTests.test_invalidEndResponsec                    s€   ˆ j  d¡}ˆ j  d¡}tƒ }|jˆ j _ˆ j ˆ j j¡ ˆ  |t	¡ ˆ  |t	¡ ‡ fdd„}| 
|¡ ˆ  |t¡ t|||gƒS )z²
        Test the timeout on outgoing requests: when timeout is detected, all
        current commands fail with a L{TimeoutError}, and the connection is
        closed.
        r   r   c                    s   ˆ   t| ƒd¡ d S )NzConnection timeout)rg   Ústr)Úerrorr#   r   r   ÚcheckMessageI  s    z0MemCacheTests.test_timeOut.<locals>.checkMessage)r!   r"   r   ÚcallbackÚconnectionLostr`   ÚadvanceÚpersistentTimeOutÚassertFailurer   rl   r   r   )r   Úd1Úd2Úd3ru   r   r#   r   Útest_timeOut:  s    

zMemCacheTests.test_timeOutc                    sF   ˆ j  d¡}ˆ j ˆ j jd ¡ ˆ j  d¡ ‡ fdd„}| |¡ |S )zY
        When a request gets a response, no pending timeout call remains around.
        r   r.   r   c                    s$   ˆ   | d¡ ˆ   tˆ jjƒd¡ d S )Nr   r   )rg   Úlenr`   Úcalls)r   r#   r   r   ÚcheckZ  s    z0MemCacheTests.test_timeoutRemoved.<locals>.check)r!   r"   r`   rx   ry   rm   rl   )r   r   r   r   r#   r   Útest_timeoutRemovedQ  s    
z!MemCacheTests.test_timeoutRemovedc                 C   s\   | j  d¡}tƒ }|j| j _| j  d¡ | j | j j¡ |  	|t
¡ |  	|t¡ t||gƒS )zÈ
        Test the timeout when raw mode was started: the timeout is not reset
        until all the data has been received, so we can have a L{TimeoutError}
        when waiting for raw data.
        r   s   VALUE foo 0 10
12345)r!   r"   r   rv   rw   rm   r`   rx   ry   rz   r   r   r   ©r   r{   r|   r   r   r   Útest_timeOutRawa  s    
zMemCacheTests.test_timeOutRawc                 C   sZ   | j  ¡ }tƒ }|j| j _| j  d¡ | j | j j¡ |  	|t
¡ |  	|t¡ t||gƒS )z†
        Test the timeout when stat command has started: the timeout is not
        reset until the final B{END} is received.
        s   STAT foo bar
)r!   rU   r   rv   rw   rm   r`   rx   ry   rz   r   r   r   rƒ   r   r   r   Útest_timeOutStatr  s    

zMemCacheTests.test_timeOutStatc                    s~   ˆj  d¡}ˆj  d¡‰tƒ }|jˆj _ˆj ˆj jd ¡ ˆj  d¡ ‡ ‡‡fdd„}‡fdd„‰ | 	|¡ ˆ 
|t¡ |S )	zŒ
        When two requests are sent, a timeout call remains around for the
        second request, and its timeout time is correct.
        r   r   r.   r   c                    sP   ˆ  | d¡ ˆ  tˆjjƒd¡ tˆjjƒD ]}ˆj d¡ q,ˆ ˆt	¡ 
ˆ ¡S )Nr   r.   )rg   r   r`   r€   Úranger!   ry   rx   rz   r   rl   )r   Úi©Ú	checkTimer|   r   r   r   r     s
    z3MemCacheTests.test_timeoutPipelining.<locals>.checkc                    s"   ˆ   ˆ j ¡ dˆ jj d ¡ d S )Né   r.   )rg   r`   Zsecondsr!   ry   )Zignoredr#   r   r   r‰   –  s     ÿz7MemCacheTests.test_timeoutPipelining.<locals>.checkTime)r!   r"   r   rv   rw   r`   rx   ry   rm   rl   rz   r   )r   r{   r}   r   r   rˆ   r   Útest_timeoutPipelining‚  s    

z$MemCacheTests.test_timeoutPipeliningc                 C   sz   | j  d¡}tƒ }|j| j _| j | j jd ¡ | j  d¡}| j d¡ |  |t	¡ |  |t	¡ |  |t
¡ t|||gƒS )z
        Check that timeout is not resetted for every command, but keep the
        timeout from the first command without response.
        r   r.   r   )r!   r"   r   rv   rw   r`   rx   ry   rz   r   r   r   )r   r{   r}   r|   r   r   r   Útest_timeoutNotReset¡  s    
z"MemCacheTests.test_timeoutNotResetc                 C   sL   | j  d¡}| j | j j¡ |  |t¡ | j  d¡}|  |t¡ t||gƒS )a  
        C{timeoutConnection} cleans the list of commands that it fires with
        C{TimeoutError}: C{connectionLost} doesn't try to fire them again, but
        sets the disconnected state so that future commands fail with a
        C{RuntimeError}.
        r   r   )	r!   r"   r`   rx   ry   rz   r   ro   r   rƒ   r   r   r   Útest_timeoutCleanDeferreds³  s    z(MemCacheTests.test_timeoutCleanDeferredsc                    sH   ˆ j  d¡}ˆ j  d¡}ˆ j ¡  t||gdd}‡ fdd„}| |¡S )zl
        When disconnection occurs while commands are still outstanding, the
        commands fail.
        r   r   T)ZconsumeErrorsc                    s&   | D ]\}}ˆ   |¡ | t¡ qd S rf   )ZassertFalseZtrapr   )ZresultsZsuccessr   r#   r   r   ÚcheckFailuresÌ  s    
z8MemCacheTests.test_connectionLost.<locals>.checkFailures)r!   r"   rb   ÚloseConnectionr   rl   )r   r{   r|   ZdonerŽ   r   r#   r   Útest_connectionLostÂ  s    
z!MemCacheTests.test_connectionLostc                 C   s–   |   | j dd¡t¡}|   | j d¡t¡}|   | j d¡t¡}|   | j dd¡t¡}|   | j dd¡t¡}|   | j ddg¡t¡}t	||||||gƒS )z›
        An error is raised when trying to use a too long key: the called
        command returns a L{Deferred} which fails with a L{ClientError}.
        sô  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaar   r   )
rz   r!   r1   r   rF   r"   ÚappendÚprependr,   r   )r   r{   r|   r}   Úd4Úd5Úd6r   r   r   Útest_tooLongKeyÔ  s&     ÿ ÿ ÿ ÿzMemCacheTests.test_tooLongKeyc                 C   sD   | j  dddddd¡}|  | j ¡ d¡ |  |t¡ | j  d¡ |S )z¼
        When an unknown command is sent directly (not through public API), the
        server answers with an B{ERROR} token, and the command fails with
        L{NoSuchCommand}.
        rS   r   r   r   ó    s   egg foo 0 0 3
bar
s   ERROR
)r!   Z_setrg   rb   rk   rz   r   rm   ©r   r   r   r   r   Útest_invalidCommandæ  s
    z!MemCacheTests.test_invalidCommandc                    sV   d}ˆ j  d|¡}ˆ  ˆ j ¡ d¡ ˆ  |t¡ ‡ fdd„}| |¡ ˆ j  d¡ |S )zÖ
        Test the L{ClientError} error: when the server sends a B{CLIENT_ERROR}
        token, the originating command fails with L{ClientError}, and the error
        contains the text sent by the server.
        ó   eggspammr   ó   set foo 0 0 8
eggspamm
c                    s   ˆ   t| ƒtdƒ¡ d S )Ns   We don't like egg and spam©rg   rs   Úrepr©Úerrr#   r   r   r   ÿ  s    z-MemCacheTests.test_clientError.<locals>.checks)   CLIENT_ERROR We don't like egg and spam
)	r!   r1   rg   rb   rk   rz   r   rl   rm   ©r   Úar   r   r   r#   r   Útest_clientErroró  s    ÿ
zMemCacheTests.test_clientErrorc                    sV   d}ˆ j  d|¡}ˆ  ˆ j ¡ d¡ ˆ  |t¡ ‡ fdd„}| |¡ ˆ j  d¡ |S )zÖ
        Test the L{ServerError} error: when the server sends a B{SERVER_ERROR}
        token, the originating command fails with L{ServerError}, and the error
        contains the text sent by the server.
        rš   r   r›   c                    s   ˆ   t| ƒtdƒ¡ d S )Ns   zomgrœ   rž   r#   r   r   r     s    z-MemCacheTests.test_serverError.<locals>.checks   SERVER_ERROR zomg
)	r!   r1   rg   rb   rk   rz   r   rl   rm   r    r   r#   r   Útest_serverError  s    ÿ
zMemCacheTests.test_serverErrorc                 C   s¬   |   | j dd¡t¡}|   | j d¡t¡}|   | j d¡t¡}|   | j d¡t¡}|   | j dd¡t¡}|   | j dd¡t¡}|   | j 	ddg¡t¡}t
|||||||gƒS )zQ
        Using a non-string key as argument to commands raises an error.
        Zfoor   Zeggr.   ÚbarrS   )rz   r!   r1   r   rF   r"   r@   r‘   r’   r,   r   )r   r{   r|   r}   r“   r”   r•   Zd7r   r   r   Útest_unicodeKey  s     ÿ ÿzMemCacheTests.test_unicodeKeyc                 C   s   |   | j dd¡t¡S )z;
        Using a non-string value raises an error.
        r   r¤   )rz   r!   r1   r   r#   r   r   r   Útest_unicodeValue+  s    zMemCacheTests.test_unicodeValuec                 C   s|   | j  d¡}| | jd¡ | j  dd¡}| | jd¡ | j  d¡}| | jd¡ |  | j ¡ d¡ | j  d	¡ t|||gƒS )
z½
        Multiple requests can be sent subsequently to the server, and the
        protocol orders the responses correctly and dispatch to the
        corresponding client command.
        r   r   r   s   spamspamspamTrS   )r   rQ   s0   get foo
set bar 0 0 12
spamspamspam
get egg
s;   VALUE foo 0 3
bar
END
STORED
VALUE egg 0 4
spam
END
)	r!   r"   rl   rg   r1   rb   rk   rm   r   )r   r{   r|   r}   r   r   r   Útest_pipelining2  s    þzMemCacheTests.test_pipeliningc                 C   s`   | j  d¡}| | jd¡ |  | j ¡ d¡ | j  d¡ | j  d¡ | j  d¡ | j  d¡ |S )z”
        If the value retrieved by a C{get} arrive in chunks, the protocol
        is able to reconstruct it and to produce the good value.
        r   )r   s
   0123456789r   s   VALUE foo 0 10
0123456s   789s   
ENDs   
)r!   r"   rl   rg   rb   rk   rm   r˜   r   r   r   Útest_getInChunksG  s    zMemCacheTests.test_getInChunksc                 C   s   |   | j dd¡ddd¡S )zÃ
        L{MemCacheProtocol.append} behaves like a L{MemCacheProtocol.set}
        method: it returns a L{Deferred} which is called back with C{True} when
        the operation succeeds.
        r   r   s   append foo 0 0 3
bar
r0   T)r   r!   r‘   r#   r   r   r   Útest_appendV  s      þzMemCacheTests.test_appendc                 C   s   |   | j dd¡ddd¡S )zÄ
        L{MemCacheProtocol.prepend} behaves like a L{MemCacheProtocol.set}
        method: it returns a L{Deferred} which is called back with C{True} when
        the operation succeeds.
        r   r   s   prepend foo 0 0 3
bar
r0   T)r   r!   r’   r#   r   r   r   Útest_prependa  s      þzMemCacheTests.test_prependc                 C   s   |   | j dd¡ddd¡S )z©
        L{MemCacheProtocol.get} handles an additional cas result when
        C{withIdentifier} is C{True} and forward it in the resulting
        L{Deferred}.
        r   Tó
   gets foo
s   VALUE foo 0 3 1234
bar
END
)r   ó   1234r   r    r#   r   r   r   Ú	test_getsl  s      þzMemCacheTests.test_getsc                 C   s   |   | j dd¡ddd¡S )z“
        Test getting a non-available key with gets: it succeeds but return
        L{None} as value, C{0} as flag and an empty cas value.
        r   Tr«   r%   ©r   r—   Nr    r#   r   r   r   Útest_emptyGetsw  s      þzMemCacheTests.test_emptyGetsc                 C   s$   |   | j ddgd¡dddddœ¡S )	z‘
        L{MemCacheProtocol.getMultiple} handles an additional cas field in the
        returned tuples if C{withIdentifier} is C{True}.
        r   r   Tó   gets foo bar
ó8   VALUE foo 0 3 1234
egg
VALUE bar 0 4 2345
spam
END
©r   s   2345rQ   ©r   r¬   rS   ©r   r   r+   r#   r   r   r   Útest_getsMultiple  s    ûzMemCacheTests.test_getsMultiplec                 C   s(   |   | j tddgƒd¡dddddœ¡S )	zO
        L{MemCacheProtocol.getMultiple} accepts any iterable of keys.
        r   r   Tr°   r±   r²   r³   r´   )r   r!   r,   Úiterr#   r   r   r   Útest_getsMultipleIterableKeysŽ  s    ûz+MemCacheTests.test_getsMultipleIterableKeysc                 C   s$   |   | j ddgd¡dddddœ¡S )	a  
        When getting a non-available key with L{MemCacheProtocol.getMultiple}
        when C{withIdentifier} is C{True}, the other keys are retrieved
        correctly, and the non-available key gets a tuple of C{0} as flag,
        L{None} as value, and an empty cas value.
        r   r   Tr°   s   VALUE foo 0 3 1234
egg
END
r®   r³   r´   r+   r#   r   r   r   Útest_getsMultipleWithEmptyš  s    üz(MemCacheTests.test_getsMultipleWithEmptyc                 C   s   |   | jjddddddd¡S )z
        L{MemCacheProtocol.checkAndSet} passes an additional cas identifier
        that the server handles to check if the data has to be updated.
        r   r   r¬   ©Zcasó   cas foo 0 0 3 1234
bar
r0   T©r   r!   ZcheckAndSetr#   r   r   r   Útest_checkAndSet¨  s      þzMemCacheTests.test_checkAndSetc                 C   s   |   | jjddddddd¡S )z„
        When L{MemCacheProtocol.checkAndSet} response is C{EXISTS}, the
        resulting L{Deferred} fires with C{False}.
        r   r   r¬   r¹   rº   s   EXISTS
Fr»   r#   r   r   r   Útest_casUnknowKey²  s      þzMemCacheTests.test_casUnknowKeyN)"r[   r\   r]   r^   re   r   rp   rq   rr   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_   ì   s>   

r_   c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )ÚCommandFailureTestszZ
    Tests for correct failure of commands on a disconnected
    L{MemCacheProtocol}.
    c                 C   sJ   t ƒ | _tƒ | _| jj| j_tƒ | _| j| j_| j | j¡ | j 	¡  dS )zU
        Create a disconnected memcache client, using a deterministic clock.
        N)
r   r!   r   r`   ra   r
   rb   rc   rd   r   r#   r   r   r   re   Ã  s    
zCommandFailureTests.setUpc                 C   s   |   |t¡S )zÈ
        Implementation of C{_test} which checks that the command fails with
        C{RuntimeError} because the transport is disconnected. All the
        parameters except C{d} are ignored.
        )rz   ro   r   r   r   r   r   Ð  s    zCommandFailureTests._testN)r[   r\   r]   r^   re   r   r   r   r   r   r¾   ½  s   r¾   N)r^   Z
__future__r   r   Ztwisted.internet.errorr   Ztwisted.protocols.memcacher   r   r   r   Ztwisted.trial.unittestr	   Ztwisted.test.proto_helpersr
   Ztwisted.internet.taskr   Ztwisted.internet.deferr   r   r   r   r   r_   r¾   r   r   r   r   Ú<module>   s     V   T