o
    ¯b?f  ã                   @   sš  d Z ddlZddlZddlmZmZ ddlmZmZm	Z	m
Z
 ddlmZmZmZ ddlmZ ddlmZ ddlmZ d	ZG d
d„ dƒZG dd„ dƒZG dd„ dƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZdd„ Zeede ƒ ƒ eede ƒ ƒ G d d!„ d!ƒZ!G d"d#„ d#ej"ƒZ#G d$d%„ d%ej"ƒZ$G d&d'„ d'ƒZ%G d(d)„ d)e	ƒZ&G d*d+„ d+ƒZ'G d,d-„ d-ej"ƒZ(dS ).z&
Tests for twisted.enterprise.adbapi.
é    N)ÚDictÚOptional)Ú
ConnectionÚConnectionLostÚConnectionPoolÚTransaction)ÚdeferÚ
interfacesÚreactor)ÚFailure©ÚrequireModule)Úunittestz%
CREATE TABLE simple (
  x integer
)
c                   @   sô   e Zd ZU dZi Zeeef ed< e	 
ed¡du rdZdd„ Zdd„ Zd	d
„ Zd3d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/d0„ Z"d1d2„ Z#dS )4ÚADBAPITestBasez,
    Test the asynchronous DB-API code.
    Úopenfun_calledNú5ADB-API requires threads, no way to test without themc                 C   s&   |   ¡  | j| jd�| _| j ¡  dS )zR
        Set up the database and create a connection pool pointing at it.
        )Ú
cp_openfunN)ÚstartDBÚmakePoolÚopenfunÚdbpoolÚstart©Úself© r   ú:/usr/lib/python3/dist-packages/twisted/test/test_adbapi.pyÚ
extraSetUp(   s   zADBAPITestBase.extraSetUpc                    ó4   ˆ j  d¡}| ‡ fdd„¡ | ‡ fdd„¡ |S )NúDROP TABLE simplec                    ó
   ˆ j  ¡ S ©N©r   Úclose©Úresr   r   r   Ú<lambda>2   ó   
 z)ADBAPITestBase.tearDown.<locals>.<lambda>c                    ó   ˆ   ¡ S r    ©ÚstopDBr#   r   r   r   r%   3   ó    ©r   ÚrunOperationÚaddCallback©r   Údr   r   r   ÚtearDown0   ó   zADBAPITestBase.tearDownc                 C   s   d| j |< d S )NT)r   ©r   Úconnr   r   r   r   6   s   zADBAPITestBase.openfunc                 C   s&   |s
|   | j¡ d S |  || j¡ d S r    )Ú
assertTruer   ÚassertInr2   r   r   r   ÚcheckOpenfunCalled9   s   z!ADBAPITestBase.checkOpenfunCalledc                    s¸   ˆ j  t¡}ˆ jr*| ˆ j¡ | ˆ j¡ | ˆ j¡ | ˆ j¡ | ‡ fdd„¡ | ˆ j	¡ | ˆ j
¡ | ˆ j¡ | ˆ j¡ | ˆ j¡ | ˆ j¡ | ˆ j¡ | ˆ j¡ |S )Nc                    r'   r    )ÚflushLoggedErrorsr#   r   r   r   r%   F   r*   z*ADBAPITestBase.test_pool.<locals>.<lambda>)r   r,   Úsimple_table_schemaÚtest_failuresr-   Ú_testPool_1_1Ú_testPool_1_2Ú_testPool_1_3Ú_testPool_1_4Ú_testPool_2Ú_testPool_3Ú_testPool_4Ú_testPool_5Ú_testPool_6Ú_testPool_7Ú_testPool_8Ú_testPool_9r.   r   r   r   Ú	test_pool?   s    zADBAPITestBase.test_poolc                    ó,   t  ˆ jjd¡}| ‡ fdd„dd„ ¡ |S )Núselect * from NOTABLEc                    ó
   ˆ   d¡S ©Nzno exception©Úfailr#   r   r   r   r%   S   r&   z.ADBAPITestBase._testPool_1_1.<locals>.<lambda>c                 S   ó   d S r    r   ©Úfr   r   r   r%   S   ó    ©r   ÚmaybeDeferredr   ÚrunQueryÚaddCallbacks©r   r$   r/   r   r   r   r:   Q   ó   zADBAPITestBase._testPool_1_1c                    rG   )Nzdeletexxx from NOTABLEc                    rI   rJ   rK   r#   r   r   r   r%   X   r&   z.ADBAPITestBase._testPool_1_2.<locals>.<lambda>c                 S   rM   r    r   rN   r   r   r   r%   X   rP   )r   rR   r   r,   rT   rU   r   r   r   r;   V   rV   zADBAPITestBase._testPool_1_2c                    ó.   t  ˆ jjˆ j¡}| ‡ fdd„dd„ ¡ |S )Nc                    rI   rJ   rK   r#   r   r   r   r%   ]   r&   z.ADBAPITestBase._testPool_1_3.<locals>.<lambda>c                 S   rM   r    r   rN   r   r   r   r%   ]   rP   )r   rR   r   ÚrunInteractionÚbad_interactionrT   rU   r   r   r   r<   [   ó   zADBAPITestBase._testPool_1_3c                    rW   )Nc                    rI   rJ   rK   r#   r   r   r   r%   b   r&   z.ADBAPITestBase._testPool_1_4.<locals>.<lambda>c                 S   rM   r    r   rN   r   r   r   r%   b   rP   )r   rR   r   ÚrunWithConnectionÚbad_withConnectionrT   rU   r   r   r   r=   `   rZ   zADBAPITestBase._testPool_1_4c                    ó*   d}ˆ j  |¡}‡ fdd„}| |¡ |S )Núselect count(1) from simplec                    ó(   ˆ   t| d d ƒdkd¡ ˆ  ¡  d S )Nr   zInteraction not rolled back)r4   Úintr6   ©Úrowr   r   r   Ú_checkj   s   z*ADBAPITestBase._testPool_2.<locals>._check©r   rS   r-   ©r   r$   Úsqlr/   rc   r   r   r   r>   e   s
   
zADBAPITestBase._testPool_2c                    sl   d}g }t ˆ jƒD ]}d| }| ˆ j |¡¡ q	t |¡}‡ fdd„}| |¡ ‡ fdd„}| |¡ |S )Nr^   z insert into simple(x) values(%d)c                    s   d}ˆ j  |¡}|S )Núselect x from simple order by x)r   rS   )r$   rf   r/   r   r   r   Ú_selectz   s   z+ADBAPITestBase._testPool_3.<locals>._selectc                    sZ   ˆ   t| ƒˆ jkd¡ tˆ jƒD ]}ˆ   t| | ƒdkd¡ ˆ   | | d |kd¡ qd S )NzWrong number of rowsé   úWrong size rowr   zValues not returned.)r4   ÚlenÚnum_iterationsÚrange)ÚrowsÚir   r   r   rc   ‚   s
   þz*ADBAPITestBase._testPool_3.<locals>._check)rm   rl   Úappendr   r,   r   ÚgatherResultsr-   )r   r$   rf   Úinsertsro   r/   rh   rc   r   r   r   r?   q   s   


zADBAPITestBase._testPool_3c                    ó$   ˆ j  ˆ j¡}| ‡ fdd„¡ |S )Nc                    ó   ˆ   | d¡S ©NÚdone©ÚassertEqualr#   r   r   r   r%   �   ó    z,ADBAPITestBase._testPool_4.<locals>.<lambda>)r   rX   Úinteractionr-   rU   r   r   r   r@   Œ   ó   zADBAPITestBase._testPool_4c                    rs   )Nc                    rt   ru   rw   r#   r   r   r   r%   •   ry   z,ADBAPITestBase._testPool_5.<locals>.<lambda>)r   r[   ÚwithConnectionr-   rU   r   r   r   rA   ’   r{   zADBAPITestBase._testPool_5c                 C   s   | j  | j¡}|S r    )r   r[   Úclose_withConnectionrU   r   r   r   rB   ˜   s   zADBAPITestBase._testPool_6c                    sV   g }t ˆ jƒD ]}d| }| ˆ j |¡¡ qtj|dd�}‡ fdd„}| |¡ |S )Nz!select x from simple where x = %dT©ÚfireOnOneErrbackc                    s4   t ˆ jƒD ]}ˆ  | | d d d |kd¡ qd S )Nri   r   zValue not returned)rm   rl   r4   )Úresultro   r   r   r   rc   ¥   s   "ÿz*ADBAPITestBase._testPool_7.<locals>._check)rm   rl   rp   r   rS   r   ÚDeferredListr-   )r   r$   Údsro   rf   Údlistrc   r   r   r   rC   �   s   
zADBAPITestBase._testPool_7c                 C   s@   g }t | jƒD ]}d| }| | j |¡¡ qtj|dd�}|S )Nzdelete from simple where x = %dTr~   )rm   rl   rp   r   r,   r   r�   )r   r$   r‚   ro   rf   rƒ   r   r   r   rD   ¬   s   zADBAPITestBase._testPool_8c                    r]   )Nr^   c                    r_   )Nr   z)Didn't successfully delete table contents)r4   r`   ÚcheckConnectra   r   r   r   rc   º   s   ÿz*ADBAPITestBase._testPool_9.<locals>._checkrd   re   r   r   r   rE   µ   s
   
zADBAPITestBase._testPool_9c                 C   s°   | j  ¡ }|  |¡ | ¡ }| d¡ | d¡ | ¡ }|  t|ƒd¡ |  t|d ƒd¡ |  |d d d¡ | d¡ | d¡ |  t| ¡ ƒd¡ | ¡  | j  	|¡ dS )z/Check the connect/disconnect synchronous calls.zinsert into simple(x) values(1)zselect x from simpleri   r   zdelete from simpleN)
r   Úconnectr6   ÚcursorÚexecuteÚfetchallrx   rk   r"   Ú
disconnect)r   r3   Úcursr$   r   r   r   r„   Ã   s   





zADBAPITestBase.checkConnectc                 C   s^   |  d¡ t| jƒD ]}| ¡ }|  t|ƒdkd¡ |  |d |kd¡ q
|  | ¡ d¡ dS )Nrg   ri   rj   r   úValue not returned.zToo many rowsrv   )r‡   rm   rl   Úfetchoner4   rk   ÚassertIsNone)r   Útransactionro   rb   r   r   r   rz   Ô   s   
zADBAPITestBase.interactionc                 C   s   | j r| d¡ | d¡ d S )Nzinsert into simple(x) values(0)rH   )Úcan_rollbackr‡   )r   rŽ   r   r   r   rY   Ý   ó   
zADBAPITestBase.bad_interactionc                 C   sl   |  ¡ }z,| d¡ t| jƒD ]}| ¡ }|  t|ƒdkd¡ |  |d |kd¡ qW | ¡  dS | ¡  w )Nrg   ri   rj   r   r‹   rv   )r†   r‡   rm   rl   rŒ   r4   rk   r"   )r   r3   rŠ   ro   rb   r   r   r   r|   ã   s   
ý
ÿzADBAPITestBase.withConnectionc                 C   s   |  ¡  d S r    )r"   r2   r   r   r   r}   ï   s   z#ADBAPITestBase.close_withConnectionc                 C   s,   |  ¡ }z| d¡ W | ¡  d S | ¡  w )NrH   )r†   r‡   r"   )r   r3   rŠ   r   r   r   r\   ò   s   z!ADBAPITestBase.bad_withConnectionr    )$Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   ÚobjectÚboolÚ__annotations__r	   ÚIReactorThreadsr
   Úskipr   r0   r   r6   rF   r:   r;   r<   r=   r>   r?   r@   rA   rB   rC   rD   rE   r„   rz   rY   r|   r}   r\   r   r   r   r   r      s8   
 
		r   c                   @   sd   e Zd ZdZe ed¡du r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 )ÚReconnectTestBasez;
    Test the asynchronous DB-API code with reconnect.
    Nr   c                 C   sF   | j du r
t d¡‚|  ¡  | jdd| j d�| _| j ¡  | j t¡S )z¹
        Skip the test if C{good_sql} is unavailable.  Otherwise, set up the
        database, create a connection pool pointed at it, and set up a simple
        schema in it.
        Nzno good sql for reconnect testri   T)Úcp_maxÚcp_reconnectÚcp_good_sql)	Úgood_sqlr   ÚSkipTestr   r   r   r   r,   r8   r   r   r   r   r     s   

ÿ
zReconnectTestBase.extraSetUpc                    r   )Nr   c                    r   r    r!   r#   r   r   r   r%     r&   z,ReconnectTestBase.tearDown.<locals>.<lambda>c                    r'   r    r(   r#   r   r   r   r%     r*   r+   r.   r   r   r   r0     r1   zReconnectTestBase.tearDownc                 C   sP   t  d ¡}| | j¡ | | j¡ | js| | j¡ | | j¡ | | j¡ |S r    )	r   Úsucceedr-   Ú_testPool_1r>   Úearly_reconnectr?   r@   rA   r.   r   r   r   rF     s   
zReconnectTestBase.test_poolc                    r]   )Nr^   c                    ó    ˆ   t| d d ƒdkd¡ d S ©Nr   zTable not empty©r4   r`   ra   r   r   r   rc   %  ó    z-ReconnectTestBase._testPool_1.<locals>._checkrd   re   r   r   r   r¡   !  ó
   
zReconnectTestBase._testPool_1c                 C   s   t | jj ¡ ƒd  ¡  d S )Nr   )Úlistr   ÚconnectionsÚvaluesr"   )r   r$   r   r   r   r>   +  s   zReconnectTestBase._testPool_2c                    s0   d}t  ˆ jj|¡}| ‡ fdd„dd„ ¡ |S )Nr^   c                    rI   rJ   rK   r#   r   r   r   r%   2  r&   z/ReconnectTestBase._testPool_3.<locals>.<lambda>c                 S   rM   r    r   rN   r   r   r   r%   2  rP   rQ   ©r   r$   rf   r/   r   r   r   r?   /  s   zReconnectTestBase._testPool_3c                    r]   )Nr^   c                    r£   r¤   r¥   ra   r   r   r   rc   9  r¦   z-ReconnectTestBase._testPool_4.<locals>._checkrd   re   r   r   r   r@   5  r§   zReconnectTestBase._testPool_4c                    s<   ˆ   ¡  d}t ˆ jj|¡}| ‡ fdd„‡ fdd„¡ |S )NrH   c                    rI   rJ   rK   r#   r   r   r   r%   D  r&   z/ReconnectTestBase._testPool_5.<locals>.<lambda>c                    s   ˆ   |  t¡¡S r    )ÚassertFalseÚcheckr   rN   r   r   r   r%   E  s    )r7   r   rR   r   rS   rT   r«   r   r   r   rA   ?  s   

þzReconnectTestBase._testPool_5)r‘   r’   r“   r”   r	   r˜   r
   r™   r   r0   rF   r¡   r>   r?   r@   rA   r   r   r   r   rš   ú   s    


rš   c                   @   s”   e Zd ZU dZdZee ed< dZdZ	dZ
dZdZdZdZdZdZejZee ed< dZdZdZdd	„ Zd
d„ Zdd„ Zdd„ Zdd„ Zdd„ ZdS )ÚDBTestConnectora>  
    A class which knows how to test for the presence of
    and establish a connection to a relational database.

    To enable test cases  which use a central, system database,
    you must create a database named DB_NAME with a user DB_USER
    and password DB_PASS with full access rights to database DB_NAME.
    NÚTEST_PREFIXÚtwisted_testTrž   é2   c                 C   s6   |   ¡ | _t | j¡ |  ¡ st d| j ¡‚|  ¡ S )Nz%s: Cannot access db)	ÚmktempÚDB_DIRÚosÚmkdirÚcan_connectr   rŸ   r¯   r   r   r   r   r   ÚsetUpi  s
   
zDBTestConnector.setUpc                 C   ó   t ƒ ‚)zXReturn true if this database is present on the system
        and can be used in a test.©ÚNotImplementedErrorr   r   r   r   r¶   p  s   zDBTestConnector.can_connectc                 C   ó   dS )z+Take any steps needed to bring database up.Nr   r   r   r   r   r   u  ó   zDBTestConnector.startDBc                 C   r»   )zBring database down, if needed.Nr   r   r   r   r   r)   y  r¼   zDBTestConnector.stopDBc                 K   s,   |   ¡ \}}| ¡ }| |¡ t|i |¤ŽS )z;Create a connection pool with additional keyword arguments.)ÚgetPoolArgsÚcopyÚupdater   )r   ÚnewkwÚargsÚkwr   r   r   r   }  s   
zDBTestConnector.makePoolc                 C   r¸   )z™Return a tuple (args, kw) of list and keyword arguments
        that need to be passed to ConnectionPool to create a connection
        to this database.r¹   r   r   r   r   r½   „  s   zDBTestConnector.getPoolArgs)r‘   r’   r“   r”   r¯   r   Ústrr—   ÚDB_NAMEÚDB_USERÚDB_PASSr³   Únulls_okÚtrailing_spaces_okr�   r9   Úescape_slashesr   rž   r¢   Ú	can_clearrl   r·   r¶   r   r)   r   r½   r   r   r   r   r®   J  s,   
 
r®   c                   @   ó4   e Zd ZdZdZdZdZdd„ Zdd„ Zd	d
„ Z	dS )ÚSQLite3ConnectorzB
    Connector that uses the stdlib SQLite3 database support.
    ÚSQLite3Fri   c                 C   ó   t dƒd u rdS dS )NÚsqlite3FTr   r   r   r   r   r¶   ”  ó   zSQLite3Connector.can_connectc                 C   ó6   t j | j| j¡| _t j | j¡rt  | j¡ d S d S r    ©r´   ÚpathÚjoinr³   rÄ   ÚdatabaseÚexistsÚunlinkr   r   r   r   r   š  ó   ÿzSQLite3Connector.startDBc                 C   ó   d}| j dddœ}||fS )N)rÏ   ri   F©rÕ   r›   Úcheck_same_thread©rÕ   ©r   rÁ   rÂ   r   r   r   r½   Ÿ  ó   zSQLite3Connector.getPoolArgsN©
r‘   r’   r“   r”   r¯   rÉ   rl   r¶   r   r½   r   r   r   r   rÌ   ‹  ó    rÌ   c                   @   rË   )ÚPySQLite2ConnectorzA
    Connector that uses pysqlite's SQLite database support.
    Ú	pysqlite2Fri   c                 C   rÎ   )Núpysqlite2.dbapi2FTr   r   r   r   r   r¶   ®  rÐ   zPySQLite2Connector.can_connectc                 C   rÑ   r    rÒ   r   r   r   r   r   ´  rØ   zPySQLite2Connector.startDBc                 C   rÙ   )N)rã   ri   FrÚ   rÜ   rÝ   r   r   r   r½   ¹  rÞ   zPySQLite2Connector.getPoolArgsNrß   r   r   r   r   rá   ¥  rà   rá   c                   @   ó    e Zd ZdZdd„ Zdd„ ZdS )ÚPyPgSQLConnectorÚPyPgSQLc                 C   s`   zddl m} W n
 ty   Y dS w z|j| j| j| jd�}| ¡  W dS  ty/   Y dS w )Nr   )ÚPgSQLF©rÕ   ÚuserÚpasswordT)ÚpyPgSQLrç   ÚBaseExceptionr…   rÄ   rÅ   rÆ   r"   )r   rç   r3   r   r   r   r¶   Â  s   ÿÿÿzPyPgSQLConnector.can_connectc                 C   ó    d}| j | j| jddœ}||fS )N)zpyPgSQL.PgSQLr   ©rÕ   ré   rê   Úcp_min©rÄ   rÅ   rÆ   rÝ   r   r   r   r½   Ð  ó   üzPyPgSQLConnector.getPoolArgsN©r‘   r’   r“   r¯   r¶   r½   r   r   r   r   rå   ¿  ó    rå   c                   @   rä   )ÚPsycopgConnectorÚPsycopgc                 C   ó\   zdd l }W n
 ty   Y dS w z|j| j| j| jd�}| ¡  W dS  ty-   Y dS w )Nr   Frè   T)Úpsycopgrì   r…   rÄ   rÅ   rÆ   r"   )r   r÷   r3   r   r   r   r¶   Þ  ó   ÿÿÿzPsycopgConnector.can_connectc                 C   rí   )N)r÷   r   rî   rð   rÝ   r   r   r   r½   ì  rñ   zPsycopgConnector.getPoolArgsNrò   r   r   r   r   rô   Û  ró   rô   c                   @   s,   e Zd ZdZdZdZdZdd„ Zdd„ ZdS )ÚMySQLConnectorÚMySQLFc                 C   rö   )Nr   F©Údbré   ÚpasswdT)ÚMySQLdbrì   r…   rÄ   rÅ   rÆ   r"   )r   rþ   r3   r   r   r   r¶   þ  rø   zMySQLConnector.can_connectc                 C   s   d}| j | j| jdœ}||fS )N)rþ   rû   rð   rÝ   r   r   r   r½     s   zMySQLConnector.getPoolArgsN)	r‘   r’   r“   r¯   rÈ   r�   r¢   r¶   r½   r   r   r   r   rù   ÷  s    rù   c                   @   sD   e Zd ZdZdZdZdZdZdZdd„ Z	dd„ Z
d	d
„ Zdd„ ZdS )ÚFirebirdConnectorÚFirebirdFNé   c                 C   s<   t dƒd u rdS z|  ¡  |  ¡  W dS  ty   Y dS w )NÚkinterbasdbFT)r   r   r)   rì   r   r   r   r   r¶     s   ÿzFirebirdConnector.can_connectc                 C   sf   dd l }tj | jtj¡| _t | jtj	tj
 tj ¡ d}|| j| j| jf; }| |¡}| ¡  d S )Nr   z,create database "%s" user "%s" password "%s")r  r´   rÓ   rÔ   r³   r®   rÄ   ÚchmodÚstatÚS_IRWXUÚS_IRWXGÚS_IRWXOrÅ   rÆ   Úcreate_databaser"   )r   r  rf   r3   r   r   r   r   &  s   
zFirebirdConnector.startDBc                 C   s    d}| j d| j| jdœ}||fS )N)r  ú	127.0.0.1©rÕ   Úhostré   rê   rð   rÝ   r   r   r   r½   0  s   üzFirebirdConnector.getPoolArgsc                 C   s,   dd l }|j| jd| j| jd�}| ¡  d S )Nr   r	  r
  )r  r…   rÄ   rÅ   rÆ   Údrop_database)r   r  r3   r   r   r   r)   :  s   üzFirebirdConnector.stopDB)r‘   r’   r“   r¯   r9   rÉ   rž   rÊ   rl   r¶   r   r½   r)   r   r   r   r   rÿ     s    


rÿ   c                    sˆ   t tttttg}i }|D ]0‰ ˆ j| }G ‡ fdd„dˆ | tjƒ}||_	t
ˆ dƒr8d ˆ j ¡ dd… |g ¡|_|||< q| |¡ dS )aQ  
    Make a test case for every db connector which can connect.

    @param base: Base class for test case. Additional base classes
                 will be a DBConnector subclass and unittest.TestCase
    @param suffix: A suffix used to create test case names. Prefixes
                   are defined in the DBConnector subclasses.
    c                       s   e Zd Z” jZdS )zmakeSQLTests.<locals>.testcaseN)r‘   r’   r“   r   ©Ú	connclassr   r   Útestcase[  s    
r  r“   Ú.r   éÿÿÿÿN)rá   rÌ   rå   rô   rù   rÿ   r¯   r   ÚTestCaser‘   ÚhasattrrÔ   r“   Úsplitr¿   )ÚbaseÚsuffixÚglobalsÚ
connectorsÚtestsÚnamer  r   r  r   ÚmakeSQLTestsF  s$   
ú

ÿ
r  ÚADBAPITestsÚReconnectTestsc                   @   s0   e Zd ZdZdZdZdd„ Zdd„ Zdd„ Zd	S )
ÚFakePoolz¿
    A fake L{ConnectionPool} for tests.

    @ivar connectionFactory: factory for making connections returned by the
        C{connect} method.
    @type connectionFactory: any callable
    Tc                 C   s
   || _ d S r    ©ÚconnectionFactory)r   r   r   r   r   Ú__init__}  s   
zFakePool.__init__c                 C   s   |   ¡ S )zB
        Return an instance of C{self.connectionFactory}.
        r  r   r   r   r   r…   €  s   zFakePool.connectc                 C   r»   )z
        Do nothing.
        Nr   )r   Ú
connectionr   r   r   r‰   †  rP   zFakePool.disconnectN)	r‘   r’   r“   r”   Ú	reconnectÚnoisyr!  r…   r‰   r   r   r   r   r  q  s    r  c                   @   ó   e Zd ZdZdd„ ZdS )ÚConnectionTestsz,
    Tests for the L{Connection} class.
    c                 C   sb   G dd„ dƒ}t |ƒ}t|ƒ}|  t|j¡ |  t¡}|  t|ƒd¡ |  |d j	j
d d¡ dS )z|
        If an error happens during rollback, L{ConnectionLost} is raised but
        the original error is logged.
        c                   @   ó   e Zd Zdd„ ZdS )zIConnectionTests.test_rollbackErrorLogged.<locals>.ConnectionRollbackRaisec                 S   ó   t dƒ‚©Núproblem!©ÚRuntimeErrorr   r   r   r   Úrollback˜  ó   zRConnectionTests.test_rollbackErrorLogged.<locals>.ConnectionRollbackRaise.rollbackN)r‘   r’   r“   r-  r   r   r   r   ÚConnectionRollbackRaise—  ó    r/  ri   r   r*  N)r  r   ÚassertRaisesr   r-  r7   r,  rx   rk   ÚvaluerÁ   )r   r/  Úpoolr"  Úerrorsr   r   r   Útest_rollbackErrorLogged‘  s   
z(ConnectionTests.test_rollbackErrorLoggedN)r‘   r’   r“   r”   r5  r   r   r   r   r&  Œ  ó    r&  c                   @   r%  )ÚTransactionTestsz-
    Tests for the L{Transaction} class.
    c                 C   s`   G dd„ dƒ}t dƒ}t||ƒ ƒ}| ¡  |  t¡}|  t|ƒd¡ |  |d jjd d¡ dS )z„
        If the cursor creation raises an error in L{Transaction.reopen}, it
        reconnects but log the error occurred.
        c                   @   rä   )zNTransactionTests.test_reopenLogErrorIfReconnect.<locals>.ConnectionCursorRaiser   c                 S   rM   r    r   r   r   r   r   r#  ±  ó   zXTransactionTests.test_reopenLogErrorIfReconnect.<locals>.ConnectionCursorRaise.reconnectc                 S   s$   | j dkr|  j d7  _ tdƒ‚d S )Nr   ri   r*  )Úcountr,  r   r   r   r   r†   ´  s   
þzUTransactionTests.test_reopenLogErrorIfReconnect.<locals>.ConnectionCursorRaise.cursorN)r‘   r’   r“   r9  r#  r†   r   r   r   r   ÚConnectionCursorRaise®  s    r:  Nri   r   r*  )	r  r   Úreopenr7   r,  rx   rk   r2  rÁ   )r   r:  r3  rŽ   r4  r   r   r   Útest_reopenLogErrorIfReconnect¨  s   
z/TransactionTests.test_reopenLogErrorIfReconnectN)r‘   r’   r“   r”   r<  r   r   r   r   r7  £  r6  r7  c                   @   r'  )ÚNonThreadPoolc                 O   sB   d}z	||i |¤Ž}W n t y   d}tƒ }Y nw |||ƒ d S )NTF)Ú	Exceptionr   )r   ÚonResultrO   ÚarÂ   Úsuccessr€   r   r   r   ÚcallInThreadWithCallbackÂ  s   
þz&NonThreadPool.callInThreadWithCallbackN)r‘   r’   r“   rB  r   r   r   r   r=  Á  r0  r=  c                   @   s   e Zd ZdZeƒ Zdd„ ZdS )ÚDummyConnectionPoolz'
    A testable L{ConnectionPool};
    c                 C   s
   t | _dS )z*
        Don't forward init call.
        N)r
   Ú_reactorr   r   r   r   r!  Ó  s   
zDummyConnectionPool.__init__N)r‘   r’   r“   r”   r=  Ú
threadpoolr!  r   r   r   r   rC  Ì  s    rC  c                   @   s0   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
S )ÚEventReactora  
    Partial L{IReactorCore} implementation with simple event-related
    methods.

    @ivar _running: A C{bool} indicating whether the reactor is pretending
        to have been started already or not.

    @ivar triggers: A C{list} of pending system event triggers.
    c                 C   s   || _ g | _d S r    )Ú_runningÚtriggers)r   Úrunningr   r   r   r!  å  s   
zEventReactor.__init__c                 C   s   | j r|ƒ  d S |  dd|¡S )NÚafterÚstartup)rG  ÚaddSystemEventTrigger)r   Úfunctionr   r   r   ÚcallWhenRunningé  r�   zEventReactor.callWhenRunningc                 C   s   |||f}| j  |¡ |S r    )rH  rp   )r   ÚphaseÚeventÚtriggerÚhandler   r   r   rL  ï  s   
z"EventReactor.addSystemEventTriggerc                 C   s   | j  |¡ d S r    )rH  Úremove)r   rR  r   r   r   ÚremoveSystemEventTriggerô  s   z%EventReactor.removeSystemEventTriggerN)r‘   r’   r“   r”   r!  rN  rL  rT  r   r   r   r   rF  Ú  s    
rF  c                   @   s8   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ ZdS )ÚConnectionPoolTestsz+
    Unit tests for L{ConnectionPool}.
    c                    sR   G dd„ dƒ}dd„ }t ƒ }||_| |¡}ˆ  |t¡}‡ fdd„}| |¡ |S )z‘
        If rollback fails, L{ConnectionPool.runWithConnection} raises the
        original exception and log the error of the rollback.
        c                   @   ó   e Zd Zdd„ Zdd„ ZdS )z]ConnectionPoolTests.test_runWithConnectionRaiseOriginalError.<locals>.ConnectionRollbackRaisec                 S   rM   r    r   ©r   r3  r   r   r   r!    r8  zfConnectionPoolTests.test_runWithConnectionRaiseOriginalError.<locals>.ConnectionRollbackRaise.__init__c                 S   r(  r)  r+  r   r   r   r   r-    r.  zfConnectionPoolTests.test_runWithConnectionRaiseOriginalError.<locals>.ConnectionRollbackRaise.rollbackN©r‘   r’   r“   r!  r-  r   r   r   r   r/    ó    r/  c                 S   r(  ©NÚfoo©Ú
ValueError)r"  r   r   r   ÚraisingFunction
  r.  zUConnectionPoolTests.test_runWithConnectionRaiseOriginalError.<locals>.raisingFunctionc                    ó6   ˆ   t¡}ˆ  t|ƒd¡ ˆ  |d jjd d¡ d S ©Nri   r   r*  ©r7   r,  rx   rk   r2  rÁ   ©Úignoredr4  r   r   r   ÚcbFailed  ó   
zNConnectionPoolTests.test_runWithConnectionRaiseOriginalError.<locals>.cbFailed)rC  r   r[   ÚassertFailurer]  r-   )r   r/  r^  r3  r/   rd  r   r   r   Ú(test_runWithConnectionRaiseOriginalErrorý  s   

z<ConnectionPoolTests.test_runWithConnectionRaiseOriginalErrorc                 C   sV   G dd„ dƒ}t ƒ }| |ƒ ¡ |  t¡}|  t|ƒd¡ |  |d jjd d¡ dS )z;
        L{ConnectionPool._close} logs exceptions.
        c                   @   r'  )zDConnectionPoolTests.test_closeLogError.<locals>.ConnectionCloseRaisec                 S   r(  r)  r+  r   r   r   r   r"      r.  zJConnectionPoolTests.test_closeLogError.<locals>.ConnectionCloseRaise.closeN)r‘   r’   r“   r"   r   r   r   r   ÚConnectionCloseRaise  r0  rh  ri   r   r*  N)rC  Ú_closer7   r,  rx   rk   r2  rÁ   )r   rh  r3  r4  r   r   r   Útest_closeLogError  s   
z&ConnectionPoolTests.test_closeLogErrorc                    sf   G dd„ dƒ}G dd„ dƒ}dd„ }t ƒ }||_||_| |¡}ˆ  |t¡}‡ fdd„}| |¡ |S )	zŽ
        If rollback fails, L{ConnectionPool.runInteraction} raises the
        original exception and log the error of the rollback.
        c                   @   rV  )z^ConnectionPoolTests.test_runWithInteractionRaiseOriginalError.<locals>.ConnectionRollbackRaisec                 S   rM   r    r   rW  r   r   r   r!  1  r8  zgConnectionPoolTests.test_runWithInteractionRaiseOriginalError.<locals>.ConnectionRollbackRaise.__init__c                 S   r(  r)  r+  r   r   r   r   r-  4  r.  zgConnectionPoolTests.test_runWithInteractionRaiseOriginalError.<locals>.ConnectionRollbackRaise.rollbackNrX  r   r   r   r   r/  0  rY  r/  c                   @   r'  )zWConnectionPoolTests.test_runWithInteractionRaiseOriginalError.<locals>.DummyTransactionc                 S   rM   r    r   )r   r3  r"  r   r   r   r!  8  r8  z`ConnectionPoolTests.test_runWithInteractionRaiseOriginalError.<locals>.DummyTransaction.__init__N)r‘   r’   r“   r!  r   r   r   r   ÚDummyTransaction7  r0  rk  c                 S   r(  rZ  r\  )rŽ   r   r   r   r^  ;  r.  zVConnectionPoolTests.test_runWithInteractionRaiseOriginalError.<locals>.raisingFunctionc                    r_  r`  ra  rb  r   r   r   rd  E  re  zOConnectionPoolTests.test_runWithInteractionRaiseOriginalError.<locals>.cbFailed)rC  r   ÚtransactionFactoryrX   rf  r]  r-   )r   r/  rk  r^  r3  r/   rd  r   r   r   Ú)test_runWithInteractionRaiseOriginalError*  s   

z=ConnectionPoolTests.test_runWithInteractionRaiseOriginalErrorc                 C   óD   t dƒ}td|d�}|  |jdd|jfg¡ | ¡  |  |j¡ dS )z™
        If L{ConnectionPool.close} is called without L{ConnectionPool.start}
        having been called, the pool's startup event is cancelled.
        Fútwisted.test.test_adbapi©Ú
cp_reactorrJ  rK  N)rF  r   rx   rH  Ú_startr"   r¬   ©r   r
   r3  r   r   r   Útest_unstartedCloseM  ó
   z'ConnectionPoolTests.test_unstartedClosec                 C   rn  )z�
        If L{ConnectionPool.close} is called after it has been started, but
        not by its shutdown trigger, the shutdown trigger is cancelled.
        Tro  rp  ÚduringÚshutdownN)rF  r   rx   rH  Ú
finalCloser"   r¬   rs  r   r   r   Útest_startedCloseZ  ru  z%ConnectionPoolTests.test_startedCloseN)	r‘   r’   r“   r”   rg  rj  rm  rt  ry  r   r   r   r   rU  ø  s    #rU  ))r”   r´   r  Útypingr   r   Útwisted.enterprise.adbapir   r   r   r   Útwisted.internetr   r	   r
   Útwisted.python.failurer   Útwisted.python.reflectr   Útwisted.trialr   r8   r   rš   r®   rÌ   rá   rå   rô   rù   rÿ   r  r  r  r  r&  r7  r=  rC  rF  rU  r   r   r   r   Ú<module>   s<    ]PA4$