o
    ¯bÄ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mZmZmZ ddl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)ÚClientErrorÚMemCacheProtocolÚNoSuchCommandÚServerError)Ú StringTransportWithDisconnection)Ú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 ƒ ‚)zp
        Helper test method to test the resulting C{Deferred} of a
        L{MemCacheProtocol} command.
        )ÚNotImplementedError©ÚselfÚdÚsendÚrecvÚresult© r   ú</usr/lib/python3/dist-packages/twisted/test/test_memcache.pyÚ_test   s   zCommandMixin._testc                 C   ó   |   | 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   r   )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   ó"   |   | 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   ó   üzCommandMixin.test_getMultiplec                 C   r'   )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   r.   z&CommandMixin.test_getMultipleWithEmptyc                 C   ó   |   | 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   ó   üzCommandMixin.test_setc                 C   r1   )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
r2   T©r   r    Úaddr"   r   r   r   Útest_addZ   r5   zCommandMixin.test_addc                 C   r1   )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
r2   T©r   r    Úreplacer"   r   r   r   Útest_replacef   r5   zCommandMixin.test_replacec                 C   r1   )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   r6   ó   NOT STORED
Fr7   r"   r   r   r   Útest_errorAddr   ó   üzCommandMixin.test_errorAddc                 C   r1   )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   r:   r>   Fr;   r"   r   r   r   Útest_errorReplace   r@   zCommandMixin.test_errorReplacec                 C   r   )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   r   )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   rB   s   NOT FOUND
FrC   r"   r   r   r   Útest_errorDelete•   s   ÿzCommandMixin.test_errorDeletec                 C   r   )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Ÿ   ó   zCommandMixin.test_incrementc                 C   r   )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    Ú	decrementr"   r   r   r   Útest_decrement§   rL   zCommandMixin.test_decrementc                 C   r1   )z‘
        L{MemCacheProtocol.increment} takes an optional argument C{value} which
        replaces the default value of 1 when specified.
        r   é   s   incr foo 8
rG   rH   rI   r"   r   r   r   Útest_incrementVal¯   ó   ÿzCommandMixin.test_incrementValc                 C   r1   )z‘
        L{MemCacheProtocol.decrement} takes an optional argument C{value} which
        replaces the default value of 1 when specified.
        r   é   s   decr foo 3
rM   rN   rO   r"   r   r   r   Útest_decrementVal¸   rT   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
rW   r   rX   rY   r[   r"   r   r   r   Útest_statsWithArgumentÎ   s   
üz#CommandMixin.test_statsWithArgumentc                 C   ó   |   | 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   r_   )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    ÚflushAllr"   r   r   r   Útest_flushAllæ   s   zCommandMixin.test_flushAllN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r#   r&   r-   r0   r4   r9   r=   r?   rA   rE   rF   rK   rQ   rS   rV   r]   r^   ra   rc   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)rp   rk   ÚvalueÚaddCallbackr    ÚdataReceived)r   r   r   r   r   rs   r   rr   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ÚRuntimeErrorrv   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,   rw   rx   rv   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    r3   rw   rx   rv   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)rp   Ústr)Úerrorr"   r   r   ÚcheckMessageJ  s   z0MemCacheTests.test_timeOut.<locals>.checkMessage)r    r!   r   ÚcallbackÚconnectionLostri   ÚadvanceÚpersistentTimeOutÚassertFailurer   ru   r   r   )r   Úd1Úd2Úd3r~   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   )rp   Úlenri   Úcalls)r   r"   r   r   ÚcheckZ  s   z0MemCacheTests.test_timeoutRemoved.<locals>.check)r    r!   ri   r   r‚   rv   ru   )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   r   r€   rv   ri   r   r‚   rƒ   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    r\   r   r   r€   rv   ri   r   r‚   rƒ   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/   )rp   rˆ   ri   r‰   Úranger    r‚   r   rƒ   r   ru   )r   Úi©Ú	checkTimer…   r   r   r   rŠ     s
   z3MemCacheTests.test_timeoutPipelining.<locals>.checkc                    s"   ˆ   ˆ j ¡ dˆ jj d ¡ d S )Né   r/   )rp   ri   Úsecondsr    r‚   )Úignoredr"   r   r   r’   ”  s   "z7MemCacheTests.test_timeoutPipelining.<locals>.checkTime)r    r!   r   r   r€   ri   r   r‚   rv   ru   rƒ   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   r   r€   ri   r   r‚   rƒ   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!   ri   r   r‚   rƒ   r   rx   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)ÚconsumeErrorsc                    s&   | D ]\}}ˆ   |¡ | t¡ qd S ro   )ÚassertFalseÚtrapr   )ÚresultsÚsuccessr   r"   r   r   ÚcheckFailuresÆ  s   
þz8MemCacheTests.test_connectionLost.<locals>.checkFailures)r    r!   rk   ÚloseConnectionr   ru   )r   r„   r…   Ú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   )
rƒ   r    r3   r   rJ   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}.
        rZ   r   r   r   ó    s   egg foo 0 0 3
bar
s   ERROR
)r    Ú_setrp   rk   rt   rƒ   r
   rv   ©r   r   r   r   r   Útest_invalidCommandÜ  s
   z!MemCacheTests.test_invalidCommandc                    óV   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                    ó   ˆ   t| ƒtdƒ¡ d S )Ns   We don't like egg and spam©rp   r|   Úrepr©Úerrr"   r   r   rŠ   ó  ó   z-MemCacheTests.test_clientError.<locals>.checks)   CLIENT_ERROR We don't like egg and spam
)	r    r3   rp   rk   rt   rƒ   r   ru   rv   ©r   Úar   rŠ   r   r"   r   Útest_clientErrorè  ó   
zMemCacheTests.test_clientErrorc                    r¬   )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                    r¯   )Ns   zomgr°   r²   r"   r   r   rŠ     r´   z-MemCacheTests.test_serverError.<locals>.checks   SERVER_ERROR zomg
)	r    r3   rp   rk   rt   rƒ   r   ru   rv   rµ   r   r"   r   Útest_serverErrorú  r¸   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.
        Úfoor   Úeggr/   ÚbarrZ   )rƒ   r    r3   r   rJ   r!   rD   r¢   r£   r,   r   )r   r„   r…   r†   r¤   r¥   r¦   Ú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¼   )rƒ   r    r3   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   spamspamspamTrZ   )r   rX   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!   ru   rp   r3   rk   rt   rv   r   )r   r„   r…   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!   ru   rp   rk   rt   rv   rª   r   r   r   Útest_getInChunks6  s   zMemCacheTests.test_getInChunksc                 C   r1   )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
r2   T)r   r    r¢   r"   r   r   r   Útest_appendD  r@   zMemCacheTests.test_appendc                 C   r1   )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
r2   T)r   r    r£   r"   r   r   r   Útest_prependQ  r@   zMemCacheTests.test_prependc                 C   r1   )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^  r@   zMemCacheTests.test_getsc                 C   r1   )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  rT   zMemCacheTests.test_emptyGetsc                 C   ó$   |   | 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   2345rX   ©r   rÅ   rZ   ©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   rÉ   )	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   ó   |   | 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Å   ©Úcasó   cas foo 0 0 3 1234
bar
r2   T©r   r    ÚcheckAndSetr"   r   r   r   Útest_checkAndSet™  ó   üzMemCacheTests.test_checkAndSetc                 C   rÓ   )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¥  rÚ   zMemCacheTests.test_casUnknowKeyN)"rd   re   rf   rg   rn   r   ry   rz   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   rh   î   s@    		rh   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   ri   rj   r   rk   rl   rm   rŸ   r"   r   r   r   rn   ¸  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.
        )rƒ   rx   r   r   r   r   r   Ä  s   zCommandFailureTests._testN)rd   re   rf   rg   rn   r   r   r   r   r   rÜ   ²  s    rÜ   N)rg   Útwisted.internet.deferr   r   r   r   Útwisted.internet.errorr   Útwisted.internet.taskr   Útwisted.protocols.memcacher   r	   r
   r   Útwisted.test.proto_helpersr   Útwisted.trial.unittestr   r   rh   rÜ   r   r   r   r   Ú<module>   s    Y   G