U
    �AcjÂb  ã                   @   sš   d Z ddlmZmZ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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.
é    )ÚDeferredÚDeferredListÚTimeoutErrorÚgatherResults)ÚConnectionDone)ÚClock)Ú StringTransportWithDisconnection)ÚClientErrorÚMemCacheProtocolÚNoSuchCommandÚServerError)ÚTestCasec                   @   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   ú>/tmp/pip-unpacked-wheel-nrvc_22y/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_getMultiple6   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_getMultipleWithEmptyB   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_setN   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
r.   T©r   r   Úaddr!   r   r   r   Útest_addZ   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
r.   T©r   r   Úreplacer!   r   r   r   Útest_replacef   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   r1   ó   NOT STORED
Fr2   r!   r   r   r   Útest_errorAddr   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   r5   r9   Fr6   r!   r   r   r   Útest_errorReplace   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
rA   rB   rC   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
rF   rG   rH   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
rN   r   rO   rP   rR   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-   r0   r4   r8   r:   r;   r?   r@   rE   rI   rK   rM   rT   rU   rW   rX   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)re   r`   ÚvalueÚaddCallbackr   ÚdataReceived)r   r   r   r   r   rh   r   rg   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ÚRuntimeErrorrk   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*   rl   rm   rk   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   r/   rl   rm   rk   r!   r   r   r   Útest_invalidEndResponse2  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)re   Ústr)Úerrorr!   r   r   ÚcheckMessageJ  s    z0MemCacheTests.test_timeOut.<locals>.checkMessage)r   r    r   ÚcallbackÚconnectionLostr^   ÚadvanceÚpersistentTimeOutÚassertFailurer   rj   r   r   )r   Úd1Úd2Úd3rs   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   )re   Úlenr^   Úcalls)r   r!   r   r   ÚcheckZ  s    z0MemCacheTests.test_timeoutRemoved.<locals>.check)r   r    r^   rv   rw   rk   rj   )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   rt   ru   rk   r^   rv   rw   rx   r   r   r   ©r   ry   rz   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   rS   r   rt   ru   rk   r^   rv   rw   rx   r   r   r   r�   r   r   r   Útest_timeOutStatq  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,   )re   r}   r^   r~   Úranger   rw   rv   rx   r   rj   )r   Úi©Ú	checkTimerz   r   r   r   r   �  s
    z3MemCacheTests.test_timeoutPipelining.<locals>.checkc                    s"   ˆ   ˆ j ¡ dˆ jj d ¡ d S )Né   r,   )re   r^   Úsecondsr   rw   )Zignoredr!   r   r   r‡   ”  s    z7MemCacheTests.test_timeoutPipelining.<locals>.checkTime)r   r    r   rt   ru   r^   rv   rw   rk   rj   rx   r   )r   ry   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   rt   ru   r^   rv   rw   rx   r   r   r   )r   ry   r{   rz   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^   rv   rw   rx   r   rm   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 rd   )ZassertFalseZtrapr   )ÚresultsÚsuccessr   r!   r   r   ÚcheckFailuresÆ  s    
z8MemCacheTests.test_connectionLost.<locals>.checkFailures)r   r    r`   ÚloseConnectionr   rj   )r   ry   rz   Ú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   )
rx   r   r/   r	   rD   r    ÚappendÚprependr*   r   )r   ry   rz   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}.
        rQ   r   r   r   ó    s   egg foo 0 0 3
bar
s   ERROR
)r   Z_setre   r`   ri   rx   r   rk   ©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©re   rq   Úrepr©Úerrr!   r   r   r   ó  s    z-MemCacheTests.test_clientError.<locals>.checks)   CLIENT_ERROR We don't like egg and spam
)	r   r/   re   r`   ri   rx   r	   rj   rk   ©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   r/   re   r`   ri   rx   r   rj   rk   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,   ÚbarrQ   )rx   r   r/   r	   rD   r    r>   r“   r”   r*   r   )r   ry   rz   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¦   )rx   r   r/   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   spamspamspamTrQ   )r   rO   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    rj   re   r/   r`   ri   rk   r   )r   ry   rz   r{   r   r   r   Útest_pipelining  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    rj   re   r`   ri   rk   rš   r   r   r   Útest_getInChunks6  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
r.   T)r   r   r“   r!   r   r   r   Útest_appendD  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
r.   T)r   r   r”   r!   r   r   r   Útest_prependQ  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_gets^  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_emptyGetsk  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   2345rO   ©r   r®   rQ   ©r   r   r)   r!   r   r   r   Útest_getsMultiplet  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
r.   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)"rY   rZ   r[   r\   rc   r   rn   ro   rp   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^   r_   r   r`   ra   rb   r�   r!   r   r   r   rc   ¸  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.
        )rx   rm   r   r   r   r   r   Ä  s    zCommandFailureTests._testN)rY   rZ   r[   r\   rc   r   r   r   r   r   rÀ   ²  s   rÀ   N)r\   Ztwisted.internet.deferr   r   r   r   Ztwisted.internet.errorr   Ztwisted.internet.taskr   Ztwisted.internet.testingr   Ztwisted.protocols.memcacher	   r
   r   r   Ztwisted.trial.unittestr   r   r]   rÀ   r   r   r   r   Ú<module>   s    Y   G