ϪfeNdZddlZddlZddlmZmZddlmZmZm Z m Z ddl m Z m Z mZddlmZddlmZddlmZd ZGd d ZGd d ZGddZGddeZGddeZGddeZGddeZGddeZGddeZdZeede eede Gdd Z!Gd!d"ejDZ#Gd#d$ejDZ$Gd%d&Z%Gd'd(e Z&Gd)d*Z'Gd+d,ejDZ(y)-z& Tests for twisted.enterprise.adbapi. N)DictOptional) ConnectionConnectionLostConnectionPool Transaction)defer interfacesreactor)Failure requireModule)unittestz% CREATE TABLE simple ( x integer ) ceZdZUdZiZeeefed<e je ddZ dZ dZdZddZd Zd Zd Zd Zd ZdZdZdZdZdZdZdZdZdZdZdZ dZ!dZ"dZ#y)ADBAPITestBasez, Test the asynchronous DB-API code. openfun_calledN5ADB-API requires threads, no way to test without themc|j|j|j|_|jj y)zR Set up the database and create a connection pool pointing at it. ) cp_openfunN)startDBmakePoolopenfundbpoolstartselfs :/usr/lib/python3/dist-packages/twisted/test/test_adbapi.py extraSetUpzADBAPITestBase.extraSetUp(s3 mmt||m<  cjjd}|jfd|jfd|S)NDROP TABLE simplec8jjSNrcloseresrs rz)ADBAPITestBase.tearDown..2$++"3"3"5rc$jSr#stopDBr&s rr(z)ADBAPITestBase.tearDown..3 $++-rr runOperation addCallbackrds` rtearDownzADBAPITestBase.tearDown07 KK $ $%8 9 56 /0rc"d|j|<y)NT)rrconns rrzADBAPITestBase.openfun6s$(D!rcx|s|j|jy|j||jyr#) assertTruerassertInr6s rcheckOpenfunCalledz!ADBAPITestBase.checkOpenfunCalled9s+ OOD// 0 MM$ 3 3 4rcjjt}jr|j j |j j |j j|j j|j fd|j j|j j|j j|j j|j j|j j|j j|j j |S)Nc$jSr#)flushLoggedErrorsr&s rr(z*ADBAPITestBase.test_pool..Fsd&<&<&>r)rr/simple_table_schema test_failuresr0 _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_9r1s` r test_poolzADBAPITestBase.test_pool?s  KK $ $%8 9    MM$,, - MM$,, - MM$,, - MM$,, - MM> ? d&&' d&&' d&&' d&&' d&&' d&&' d&&' d&&'rctjjjd}|j fdd|S)Nselect * from NOTABLEc&jdSNz no exceptionfailr&s rr(z.ADBAPITestBase._testPool_1_1..S499^#<rcyr#fs rr(z.ADBAPITestBase._testPool_1_1..Srr maybeDeferredrrunQuery addCallbacksrr'r2s` rrAzADBAPITestBase._testPool_1_1Qs4    4 46M N .XrTrcyr#rVrWs rr(z.ADBAPITestBase._testPool_1_2..XrYr)r r[rr/r]r^s` rrBzADBAPITestBase._testPool_1_2Vs4    8 8:R S .]rTrcyr#rVrWs rr(z.ADBAPITestBase._testPool_1_3..]rYr)r r[rrunInteractionbad_interactionr]r^s` rrCzADBAPITestBase._testPool_1_3[s9    : :D.brTrcyr#rVrWs rr(z.ADBAPITestBase._testPool_1_4..brYr)r r[rrunWithConnectionbad_withConnectionr]r^s` rrDzADBAPITestBase._testPool_1_4`s9    = =t?V?V W ._checkjs/ OOCAq Na/1N O  # # %rrr\r0rr'sqlr2rrs` rrEzADBAPITestBase._testPool_2es4+ KK  % & frc$d}g}tjD]1}d|z}|jjj |3t j |}fd}|j|fd}|j||S)Nrmz insert into simple(x) values(%d)cBd}jj|}|S)Nselect x from simple order by x)rr\)r'rur2rs r_selectz+ADBAPITestBase._testPool_3.._selectzs!3C $$S)AHrcjt|jk(dtjD]>}jt||dk(dj||d|k(d@y)NzWrong number of rowsWrong size rowrzValues not returned.)r9lennum_iterationsrange)rowsirs rrrz*ADBAPITestBase._testPool_3.._checkst OOCI)<)<<>T U4../ IDG  13CDQ a1GH Ir)rr~appendrr/r gatherResultsr0)rr'ruinsertsrr2ryrrs` rrFzADBAPITestBase._testPool_3qs+t**+ :A4q8C NN4;;33C8 9 :    (  g I frczjjj}|jfd|S)Nc(j|dSNdone assertEqualr&s rr(z,ADBAPITestBase._testPool_4..$"2"23"?r)rre interactionr0r^s` rrGzADBAPITestBase._testPool_4s/ KK & &t'7'7 8 ?@rczjjj}|jfd|S)Nc(j|dSrrr&s rr(z,ADBAPITestBase._testPool_5..rr)rrjwithConnectionr0r^s` rrHzADBAPITestBase._testPool_5s/ KK ) )$*=*= > ?@rcP|jj|j}|Sr#)rrjclose_withConnectionr^s rrIzADBAPITestBase._testPool_6s! KK ) )$*C*C Drcg}tjD]1}d|z}|jjj |3t j |d}fd}|j||S)Nz!select x from simple where x = %dTfireOnOneErrbackc|tjD]#}j||ddd|k(d%y)Nr{rzValue not returned)rr~r9)resultrrs rrrz*ADBAPITestBase._testPool_7.._checksD4../ Oq ! Q 2a 79MN Or)rr~rrr\r DeferredListr0)rr'dsrrudlistrrs` rrJzADBAPITestBase._testPool_7sv t**+ 1A59C IIdkk**3/ 0 1""2= O &! rcg}t|jD]1}d|z}|j|jj |3t j |d}|S)Nzdelete from simple where x = %dTr)rr~rrr/r r)rr'rrrurs rrKzADBAPITestBase._testPool_8s_ t**+ 5A3a7C IIdkk..s3 4 5""2= rcnd}jj|}fd}|j||S)Nrmcnjt|dddk(djy)Nrz)Didn't successfully delete table contents)r9ro checkConnectrps rrrz*ADBAPITestBase._testPool_9.._checks4 OOCF1I!#%P     rrsrts` rrLzADBAPITestBase._testPool_9s4+ KK  % frcl|jj}|j||j}|j d|j d|j }|j t|d|j t|dd|j |ddd|j d|j d|j t|j d|j|jj|y)z/Check the connect/disconnect synchronous calls.zinsert into simple(x) values(1)zselect x from simpler{rzdelete from simpleN) rconnectr;cursorexecutefetchallrr}r% disconnect)rr7cursr's rrzADBAPITestBase.checkConnects{{""$ %{{} 67 +,mmo S1% SVa( QA& )* +, T]]_-q1  t$rc&|jdt|jD]H}|j}|j t |dk(d|j |d|k(dJ|j |jdy)Nrxr{r|rValue not returned.z Too many rowsr)rrr~fetchoner9r} assertIsNone)r transactionrrqs rrzADBAPITestBase.interactions=>t**+ @A&&(C OOCHM+; < OOCFaK)> ? @ +..0/Brc`|jr|jd|jdy)Nzinsert into simple(x) values(0)rO) can_rollbackr)rrs rrfzADBAPITestBase.bad_interactions)       A B34rcT|j} |jdt|jD]H}|j }|j t |dk(d|j |d|k(dJ |jy#|jwxYw)Nrxr{r|rrr)rrrr~rr9r}r%)rr7rrrqs rrzADBAPITestBase.withConnections{{}  LL: ;4../ DmmoCA /?@A! -BC D JJL JJLs A1BB'c$|jyr#)r%r6s rrz#ADBAPITestBase.close_withConnections  rc|j} |jd|jy#|jwxYw)NrO)rrr%)rr7rs rrkz!ADBAPITestBase.bad_withConnections2{{}  LL0 1 JJLDJJLs 4Ar#)$__name__ __module__ __qualname____doc__rrobjectbool__annotations__r IReactorThreadsr skiprr3rr;rMrArBrCrDrErFrGrHrIrJrKrLrrrfrrrkrVrrrrs*,ND&+!z!!'408F )5 $    6    %"5 rrcjeZdZdZej eddZdZdZ dZ dZ dZ d Z d Zd Zy) ReconnectTestBasez; Test the asynchronous DB-API code with reconnect. Nrc|jtjd|j|j dd|j|_|j j |j jtS)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. zno good sql for reconnect testr{T)cp_max cp_reconnect cp_good_sql) good_sqlrSkipTestrrrrr/r?rs rrzReconnectTestBase.extraSetUpsq == ##$DE E mm4T]]$   {{''(;<.r)rc$jSr#r+r&s rr(z,ReconnectTestBase.tearDown..r-rr.r1s` rr3zReconnectTestBase.tearDownr4rcVtjd}|j|j|j|j|j s|j|j |j|j|j|j|Sr#) r succeedr0 _testPool_1rEearly_reconnectrFrGrHr1s rrMzReconnectTestBase.test_poolsx MM$  d&&' d&&'## MM$** + d&&' d&&'rcnd}jj|}fd}|j||S)NrmcNjt|dddk(dyNrzTable not emptyr9rorps rrrz-ReconnectTestBase._testPool_1.._check%# OOCAq Na/1B Crrsrts` rrzReconnectTestBase._testPool_1!5+ KK  % D frct|jjjdj y)Nr)listr connectionsvaluesr%)rr's rrEzReconnectTestBase._testPool_2+s+ T[[ $ $ + + -.q1779rcd}tjjj|}|j fdd|S)Nrmc&jdSrQrRr&s rr(z/ReconnectTestBase._testPool_3..2rTrcyr#rVrWs rr(z/ReconnectTestBase._testPool_3..2rYrrZrr'rur2s` rrFzReconnectTestBase._testPool_3/s8+    4 4c : ._check9rrrsrts` rrGzReconnectTestBase._testPool_45rrcjd}tjjj|}|j fdfd|S)NrOc&jdSrQrRr&s rr(z/ReconnectTestBase._testPool_5..Ds .1rcLj|jtSr#) assertFalsecheckr)rXrs rr(z/ReconnectTestBase._testPool_5..Esd&&qww~'>?r)r>r r[rr\r]rs` rrHzReconnectTestBase._testPool_5?sI  %    4 4c :  1 ? r)rrrrr rr rrr3rMrrErFrGrHrVrrrrsK"z!!'408F = : rrceZdZUdZdZeeed<dZdZ dZ dZ dZ dZ dZdZdZej$Zeeed<dZdZdZdZd Zd Zd Zd Zd Zy)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_testTr2c|j|_tj|j|j s"t j d|jz|jS)Nz%s: Cannot access db) mktempDB_DIRosmkdir can_connectrrrrrs rsetUpzDBTestConnector.setUpisUkkm  !##$:T=M=M$MN N  rct)zXReturn true if this database is present on the system and can be used in a test.NotImplementedErrorrs rrzDBTestConnector.can_connectps "##rcy)z+Take any steps needed to bring database up.NrVrs rrzDBTestConnector.startDBu rcy)zBring database down, if needed.NrVrs rr,zDBTestConnector.stopDByrrc |j\}}|j}|j|t|i|S)z;Create a connection pool with additional keyword arguments.) getPoolArgscopyupdater)rnewkwargskws rrzDBTestConnector.makePool}s;##%b WWY %t*r**rct)zReturn a tuple (args, kw) of list and keyword arguments that need to be passed to ConnectionPool to create a connection to this database.rrs rrzDBTestConnector.getPoolArgss "##r)rrrrrrstrrDB_NAMEDB_USERDB_PASSrnulls_oktrailing_spaces_okrr@escape_slashesrrr can_clearr~rrrr,rrrVrrrrJs"&K#%GGG FHLMN,55Hhsm5OIN!$   +$rrc.eZdZdZdZdZdZdZdZdZ y) SQLite3ConnectorzB Connector that uses the stdlib SQLite3 database support. SQLite3Fr{ctdyy)Nsqlite3FTr rs rrzSQLite3Connector.can_connects  # +rctjj|j|j|_tjj |j r tj|j yyr#rpathjoinrrdatabaseexistsunlinkrs rrzSQLite3Connector.startDBI T[[$,,? 77>>$-- ( IIdmm $ )rc.d}|jddd}||fS)N)rr{Frrcheck_same_threadrrrrs rrzSQLite3Connector.getPoolArgss --15 QRxrN rrrrrrr~rrrrVrrrrs'KNN % rrc.eZdZdZdZdZdZdZdZdZ y) PySQLite2ConnectorzA Connector that uses pysqlite's SQLite database support. pysqlite2Fr{ctdyy)Npysqlite2.dbapi2FTr rs rrzPySQLite2Connector.can_connects + , 4rctjj|j|j|_tjj |j r tj|j yyr#rrs rrzPySQLite2Connector.startDBr rc.d}|jddd}||fS)N)rr{Fr rrs rrzPySQLite2Connector.getPoolArgss $--15 QRxrNrrVrrrrs'KNN % rrceZdZdZdZdZy)PyPgSQLConnectorPyPgSQLc ddlm} |j|j|j |j }|jy#t$rYywxYw#t$rYywxYw)Nr)PgSQLFruserpasswordT)pyPgSQLr BaseExceptionrrrrr%)rrr7s rrzPyPgSQLConnector.can_connectsj  % ==DLL4<<!D JJL    s#A AA AA A'&A'cXd}|j|j|jdd}||fS)N)z pyPgSQL.PgSQLrrrrcp_minrrrrs rrzPyPgSQLConnector.getPoolArgss1! LL    RxrNrrrrrrrVrrrrK rrceZdZdZdZdZy)PsycopgConnectorPsycopgc ddl} |j|j|j|j }|j y#t$rYywxYw#t$rYywxYw)NrFrT)psycopgr!rrrrr%)rr,r7s rrzPsycopgConnector.can_connectsj   ??DLL4<<#D JJL    #A AA AA A%$A%cXd}|j|j|jdd}||fS)N)r,rr#r%rs rrzPsycopgConnector.getPoolArgss1 LL    RxrNr&rVrrr)r)r'rr)c(eZdZdZdZdZdZdZdZy)MySQLConnectorMySQLFc ddl} |j|j|j|j }|j y#t$rYywxYw#t$rYywxYw)NrFdbrpasswdT)MySQLdbr!rrrrr%)rr6r7s rrzMySQLConnector.can_connectsj   ??<.testcaseN)rrr) connclasssrtestcaserM[s"--JrrOr.rN)rrrr)r0r9rrTestCaserhasattrrrsplitr)basesuffixglobals connectorstestsnamerOrNs @r makeSQLTestsr[Fs  J E  $$v- .y$(9(9 .! 9n -$'HH&&,,.q4v=%H !d   NN5r ADBAPITestsReconnectTestsc*eZdZdZdZdZdZdZdZy)FakePoolz A fake L{ConnectionPool} for tests. @ivar connectionFactory: factory for making connections returned by the C{connect} method. @type connectionFactory: any callable Tc||_yr#connectionFactory)rrbs r__init__zFakePool.__init__}s !2rc"|jS)zB Return an instance of C{self.connectionFactory}. rars rrzFakePool.connects%%''rcy)z Do nothing. NrV)r connections rrzFakePool.disconnectrYrN) rrrr reconnectnoisyrcrrrVrrr_r_qs"I E3(  rr_ceZdZdZdZy)ConnectionTestsz, Tests for the L{Connection} class. c<Gdd}t|}t|}|jt|j|j t }|jt|d|j|djjddy)z| If an error happens during rollback, L{ConnectionLost} is raised but the original error is logged. ceZdZdZy)IConnectionTests.test_rollbackErrorLogged..ConnectionRollbackRaisectdNproblem! RuntimeErrorrs rrollbackzRConnectionTests.test_rollbackErrorLogged..ConnectionRollbackRaise.rollback ":..rN)rrrrsrVrrConnectionRollbackRaiserm /rrur{rrpN) r_r assertRaisesrrsr>rrrr}valuer)rrupoolrferrorss rtest_rollbackErrorLoggedz(ConnectionTests.test_rollbackErrorLoggeds  / //0%  .**=*=>'' 5 Va( --a0*=rN)rrrrr{rVrrrjrjs >rrjceZdZdZdZy)TransactionTestsz- Tests for the L{Transaction} class. c(Gdd}td}t||}|j|jt}|j t |d|j |djjddy)z If the cursor creation raises an error in L{Transaction.reopen}, it reconnects but log the error occurred. ceZdZdZdZdZy)NTransactionTests.test_reopenLogErrorIfReconnect..ConnectionCursorRaisercyr#rVrs rrgzXTransactionTests.test_reopenLogErrorIfReconnect..ConnectionCursorRaise.reconnectrcb|jdk(r |xjdz c_tdy)Nrr{rp)countrrrs rrzUTransactionTests.test_reopenLogErrorIfReconnect..ConnectionCursorRaise.cursors*::?JJ!OJ&z22#rN)rrrrrgrrVrrConnectionCursorRaisersE  3rrNr{rrp) r_rreopenr>rrrr}rxr)rrryrrzs rtest_reopenLogErrorIfReconnectz/TransactionTests.test_reopenLogErrorIfReconnectsz 3 3~!$(=(?@ '' 5 Va( --a0*=rN)rrrrrrVrrr}r}s >rr}ceZdZdZy) NonThreadPoolcbd} ||i|}|||y#t$rd}t}Y!wxYw)NTF) Exceptionr )ronResultrXarsuccessrs rcallInThreadWithCallbackz&NonThreadPool.callInThreadWithCallbacksB [R[F &! GYF s ..N)rrrrrVrrrrs"rrc$eZdZdZeZdZy)DummyConnectionPoolz' A testable L{ConnectionPool}; ct|_y)z* Don't forward init call. N)r _reactorrs rrczDummyConnectionPool.__init__s   rN)rrrrr threadpoolrcrVrrrrsJ rrc(eZdZdZdZdZdZdZy) 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 ||_g|_yr#)_runningtriggers)rrunnings rrczEventReactor.__init__s  rcP|jr|y|jdd|S)Nafterstartup)raddSystemEventTrigger)rfunctions rcallWhenRunningzEventReactor.callWhenRunnings# == J--gy(K KrcF|||f}|jj||Sr#)rr)rphaseeventtriggerhandles rrz"EventReactor.addSystemEventTriggers%( V$ rc:|jj|yr#)rremove)rrs rremoveSystemEventTriggerz%EventReactor.removeSystemEventTriggers V$rN)rrrrrcrrrrVrrrrsL  %rrc.eZdZdZdZdZdZdZdZy)ConnectionPoolTestsz+ Unit tests for L{ConnectionPool}. cGdd}d}t}||_|j|}j|t}fd}|j ||S)z If rollback fails, L{ConnectionPool.runWithConnection} raises the original exception and log the error of the rollback. ceZdZdZdZy)]ConnectionPoolTests.test_runWithConnectionRaiseOriginalError..ConnectionRollbackRaisecyr#rVrrys rrczfConnectionPoolTests.test_runWithConnectionRaiseOriginalError..ConnectionRollbackRaise.__init__rrctdrorqrs rrszfConnectionPoolTests.test_runWithConnectionRaiseOriginalError..ConnectionRollbackRaise.rollbackrtrNrrrrcrsrVrrrur   /rructdNfoo ValueError)rfs rraisingFunctionzUConnectionPoolTests.test_runWithConnectionRaiseOriginalError..raisingFunction  U# #rcjt}jt|dj|djj ddyNr{rrpr>rrrr}rxrignoredrzrs rcbFailedzNConnectionPoolTests.test_runWithConnectionRaiseOriginalError..cbFailedJ++L9F   S[! ,   VAY__11!4j Ar)rrbrj assertFailurerr0)rrurryr2rs` r(test_runWithConnectionRaiseOriginalErrorz.ConnectionCloseRaisectdrorqrs rr%zJConnectionPoolTests.test_closeLogError..ConnectionCloseRaise.close rtrN)rrrr%rVrrConnectionCloseRaiserrvrrr{rrpN)r_closer>rrrr}rxr)rrryrzs rtest_closeLogErrorz&ConnectionPoolTests.test_closeLogErrorsm  / /#$ (*+'' 5 Va( --a0*=rcGdd}Gdd}d}t}||_||_|j|}j |t }fd}|j ||S)z If rollback fails, L{ConnectionPool.runInteraction} raises the original exception and log the error of the rollback. ceZdZdZdZy)^ConnectionPoolTests.test_runWithInteractionRaiseOriginalError..ConnectionRollbackRaisecyr#rVrs rrczgConnectionPoolTests.test_runWithInteractionRaiseOriginalError..ConnectionRollbackRaise.__init__1rrctdrorqrs rrszgConnectionPoolTests.test_runWithInteractionRaiseOriginalError..ConnectionRollbackRaise.rollback4rtrNrrVrrrur0rrruceZdZdZy)WConnectionPoolTests.test_runWithInteractionRaiseOriginalError..DummyTransactioncyr#rV)rryrfs rrcz`ConnectionPoolTests.test_runWithInteractionRaiseOriginalError..DummyTransaction.__init__8rrN)rrrrcrVrrDummyTransactionr7s rrctdrr)rs rrzVConnectionPoolTests.test_runWithInteractionRaiseOriginalError..raisingFunction;rrcjt}jt|dj|djj ddyrrrs rrzOConnectionPoolTests.test_runWithInteractionRaiseOriginalError..cbFailedErr)rrbtransactionFactoryrerrr0)rrurrryr2rs` r)test_runWithInteractionRaiseOriginalErrorz=ConnectionPoolTests.test_runWithInteractionRaiseOriginalError*sq  / /   $#$!8"2    0   q* - B hrctd}td|}|j|jdd|jfg|j |j |jy)z If L{ConnectionPool.close} is called without L{ConnectionPool.start} having been called, the pool's startup event is cancelled. Ftwisted.test.test_adbapi cp_reactorrrN)rrrr_startr%rrr rys rtest_unstartedClosez'ConnectionPoolTests.test_unstartedCloseMs\ u%8WM ))Wi,M+NO  ))*rctd}td|}|j|jdd|jfg|j |j |jy)z If L{ConnectionPool.close} is called after it has been started, but not by its shutdown trigger, the shutdown trigger is cancelled. TrrduringshutdownN)rrrr finalCloser%rrs rtest_startedClosez%ConnectionPoolTests.test_startedCloseZs\ t$8WM ))Xz4??,S+TU  ))*rN) rrrrrrrrrrVrrrrs!:> !F + +rr))rrr@typingrrtwisted.enterprise.adbapirrrrtwisted.internetr r r twisted.python.failurer twisted.python.reflectr twisted.trialrr?rrrrrrr)r0r9r[rWr_rRrjr}rrrrrVrrrs0 ! 87*0"YYxMM`>$>$B4488_611hH ^]GI6  0')<  6>h''>.>x((><""  .  %%