[CalendarServer-changes] [8162] CalendarServer/branches/users/glyph/shared-pool-take2/twext/ enterprise
source_changes at macosforge.org
source_changes at macosforge.org
Mon Oct 10 08:03:15 PDT 2011
Revision: 8162
http://trac.macosforge.org/projects/calendarserver/changeset/8162
Author: glyph at apple.com
Date: 2011-10-10 08:03:14 -0700 (Mon, 10 Oct 2011)
Log Message:
-----------
test coverage for sending oracle derived parameters across the wire via ConnectionPoolClient
Modified Paths:
--------------
CalendarServer/branches/users/glyph/shared-pool-take2/twext/enterprise/dal/test/test_sqlsyntax.py
CalendarServer/branches/users/glyph/shared-pool-take2/twext/enterprise/test/test_adbapi2.py
Modified: CalendarServer/branches/users/glyph/shared-pool-take2/twext/enterprise/dal/test/test_sqlsyntax.py
===================================================================
--- CalendarServer/branches/users/glyph/shared-pool-take2/twext/enterprise/dal/test/test_sqlsyntax.py 2011-10-10 15:03:01 UTC (rev 8161)
+++ CalendarServer/branches/users/glyph/shared-pool-take2/twext/enterprise/dal/test/test_sqlsyntax.py 2011-10-10 15:03:14 UTC (rev 8162)
@@ -18,23 +18,24 @@
Tests for L{twext.enterprise.dal.syntax}
"""
-from twext.enterprise.dal.model import Schema
from twext.enterprise.dal.parseschema import addSQLToSchema
from twext.enterprise.dal import syntax
from twext.enterprise.dal.syntax import (
- SchemaSyntax, Select, Insert, Update, Delete, Lock, SQLFragment,
- TableMismatch, Parameter, Max, Len, NotEnoughValues
-, Savepoint, RollbackToSavepoint, ReleaseSavepoint, SavepointAction)
+ Select, Insert, Update, Delete, Lock, SQLFragment,
+ TableMismatch, Parameter, Max, Len, NotEnoughValues,
+ Savepoint, RollbackToSavepoint, ReleaseSavepoint, SavepointAction
+)
from twext.enterprise.dal.syntax import Function
from twext.enterprise.dal.syntax import FixedPlaceholder, NumericPlaceholder
from twext.enterprise.ienterprise import POSTGRES_DIALECT, ORACLE_DIALECT
-from twext.enterprise.test.test_adbapi2 import ConnectionFactory
-from twext.enterprise.adbapi2 import ConnectionPool
from twext.enterprise.test.test_adbapi2 import resultOf
-from twext.enterprise.test.test_adbapi2 import FakeThreadHolder
from twisted.internet.defer import succeed
+from twext.enterprise.dal.test.test_parseschema import SchemaTestHelper
+from twext.enterprise.dal.syntax import SchemaSyntax
+from twext.enterprise.test.test_adbapi2 import ConnectionPoolHelper
+from twext.enterprise.test.test_adbapi2 import NetworkedPoolHelper
from twisted.trial.unittest import TestCase
@@ -69,28 +70,36 @@
def execSQL(self, text, params, exc):
return succeed([[None, None]])
-class GenerationTests(TestCase):
+
+EXAMPLE_SCHEMA = """
+create sequence A_SEQ;
+create table FOO (BAR integer, BAZ varchar(255));
+create table BOZ (QUX integer, QUUX integer);
+create table OTHER (BAR integer,
+ FOO_BAR integer not null);
+create table TEXTUAL (MYTEXT varchar(255));
+create table LEVELS (ACCESS integer,
+ USERNAME varchar(255));
+create table NULLCHECK (ASTRING varchar(255) not null,
+ ANUMBER integer);
+"""
+
+class ExampleSchemaHelper(SchemaTestHelper):
"""
- Tests for syntactic helpers to generate SQL queries.
+ setUp implementor.
"""
def setUp(self):
- s = Schema(self.id())
- addSQLToSchema(schema=s, schemaData="""
- create sequence A_SEQ;
- create table FOO (BAR integer, BAZ varchar(255));
- create table BOZ (QUX integer, QUUX integer);
- create table OTHER (BAR integer,
- FOO_BAR integer not null);
- create table TEXTUAL (MYTEXT varchar(255));
- create table LEVELS (ACCESS integer,
- USERNAME varchar(255));
- create table NULLCHECK (ASTRING varchar(255) not null,
- ANUMBER integer);
- """)
- self.schema = SchemaSyntax(s)
+ self.schema = SchemaSyntax(self.schemaFromString(EXAMPLE_SCHEMA))
+
+class GenerationTests(ExampleSchemaHelper, TestCase):
+ """
+ Tests for syntactic helpers to generate SQL queries.
+ """
+
+
def test_simplestSelect(self):
"""
L{Select} generates a 'select' statement, by default, asking for all
@@ -623,46 +632,6 @@
)
- def simulateOracleConnection(self):
- """
- Create a fake oracle-ish connection pool without using real threads or a
- real database.
-
- @return: a 3-tuple of L{IAsyncTransaction}, L{ConnectionPool},
- L{ConnectionFactory}.
- """
- self.patch(syntax, 'cx_Oracle', FakeCXOracleModule)
- factory = ConnectionFactory()
- pool = ConnectionPool(factory.connect, maxConnections=2,
- dialect=ORACLE_DIALECT,
- paramstyle='numeric')
- self.paused = False
- pool._createHolder = lambda : FakeThreadHolder(self)
- pool.startService()
- conn = pool.connection()
- return conn, pool, factory
-
-
- def test_insertMultiReturnOnOracleTxn(self):
- """
- As described in L{test_insertMultiReturnOracle}, Oracle deals with
- 'returning' clauses by using out parameters. However, this is not quite
- enough, as the code needs to actually retrieve the values from the out
- parameters.
- """
- conn, _ignore_pool, factory = self.simulateOracleConnection()
- i = Insert({self.schema.FOO.BAR: 40,
- self.schema.FOO.BAZ: 50},
- Return=(self.schema.FOO.BAR, self.schema.FOO.BAZ))
- # See fake result generation in test_adbapi2.py.
- result = resultOf(i.on(conn))
- self.assertEquals(result, [[[300, 301]]])
- curvars = factory.connections[0].cursors[0].variables
- self.assertEquals(len(curvars), 2)
- self.assertEquals(curvars[0].type, FakeCXOracleModule.NUMBER)
- self.assertEquals(curvars[1].type, FakeCXOracleModule.STRING)
-
-
def test_insertMismatch(self):
"""
L{Insert} raises L{TableMismatch} if the columns specified aren't all
@@ -985,26 +954,6 @@
self.assertEquals(rows, [['', None]])
- def test_rewriteOracleNULLs_Insert(self):
- """
- The behavior described in L{test_rewriteOracleNULLs_Select} applies to
- other statement types as well, specifically those with 'returning'
- clauses.
- """
- conn, _ignore_pool, factory = self.simulateOracleConnection()
- # Add 2 cursor variable values so that these will be used by
- # FakeVariable.getvalue.
- factory.varvals.extend([None, None])
- rows = resultOf(
- Insert({self.schema.NULLCHECK.ASTRING: '',
- self.schema.NULLCHECK.ANUMBER: None},
- Return=[self.schema.NULLCHECK.ASTRING,
- self.schema.NULLCHECK.ANUMBER]
- ).on(conn))[0]
-
- self.assertEquals(rows, [['', None]])
-
-
def test_nestedLogicalExpressions(self):
"""
Make sure that logical operator precedence inserts proper parenthesis
@@ -1151,3 +1100,75 @@
self.assertEquals(values, {})
+
+class OracleConnectionMethods(object):
+ def test_rewriteOracleNULLs_Insert(self):
+ """
+ The behavior described in L{test_rewriteOracleNULLs_Select} applies to
+ other statement types as well, specifically those with 'returning'
+ clauses.
+ """
+ # Add 2 cursor variable values so that these will be used by
+ # FakeVariable.getvalue.
+ self.factory.varvals.extend([None, None])
+ rows = self.resultOf(
+ Insert({self.schema.NULLCHECK.ASTRING: '',
+ self.schema.NULLCHECK.ANUMBER: None},
+ Return=[self.schema.NULLCHECK.ASTRING,
+ self.schema.NULLCHECK.ANUMBER]
+ ).on(self.createTransaction()))[0]
+ self.assertEquals(rows, [['', None]])
+
+
+ def test_insertMultiReturnOnOracleTxn(self):
+ """
+ As described in L{test_insertMultiReturnOracle}, Oracle deals with
+ 'returning' clauses by using out parameters. However, this is not quite
+ enough, as the code needs to actually retrieve the values from the out
+ parameters.
+ """
+ i = Insert({self.schema.FOO.BAR: 40,
+ self.schema.FOO.BAZ: 50},
+ Return=(self.schema.FOO.BAR, self.schema.FOO.BAZ))
+ self.factory.varvals.extend(["first val!", "second val!"])
+ result = self.resultOf(i.on(self.createTransaction()))
+ self.assertEquals(result, [[["first val!", "second val!"]]])
+ curvars = self.factory.connections[0].cursors[0].variables
+ self.assertEquals(len(curvars), 2)
+ self.assertEquals(curvars[0].type, FakeCXOracleModule.NUMBER)
+ self.assertEquals(curvars[1].type, FakeCXOracleModule.STRING)
+
+
+
+class OracleConnectionTests(ConnectionPoolHelper, ExampleSchemaHelper,
+ OracleConnectionMethods, TestCase):
+ """
+ Tests which use an oracle connection.
+ """
+
+ dialect = ORACLE_DIALECT
+
+ def setUp(self):
+ """
+ Create a fake oracle-ish connection pool without using real threads or a
+ real database.
+ """
+ self.patch(syntax, 'cx_Oracle', FakeCXOracleModule)
+ super(OracleConnectionTests, self).setUp()
+ ExampleSchemaHelper.setUp(self)
+
+
+
+
+class OracleNetConnectionTests(NetworkedPoolHelper, ExampleSchemaHelper,
+ OracleConnectionMethods, TestCase):
+
+ dialect = ORACLE_DIALECT
+
+ def setUp(self):
+ self.patch(syntax, 'cx_Oracle', FakeCXOracleModule)
+ super(OracleNetConnectionTests, self).setUp()
+ ExampleSchemaHelper.setUp(self)
+ self.pump.client.dialect = ORACLE_DIALECT
+
+
Modified: CalendarServer/branches/users/glyph/shared-pool-take2/twext/enterprise/test/test_adbapi2.py
===================================================================
--- CalendarServer/branches/users/glyph/shared-pool-take2/twext/enterprise/test/test_adbapi2.py 2011-10-10 15:03:01 UTC (rev 8161)
+++ CalendarServer/branches/users/glyph/shared-pool-take2/twext/enterprise/test/test_adbapi2.py 2011-10-10 15:03:14 UTC (rev 8162)
@@ -42,6 +42,7 @@
from twext.enterprise.adbapi2 import ConnectionPoolClient
from twext.enterprise.adbapi2 import ConnectionPoolConnection
from twext.enterprise.ienterprise import IAsyncTransaction
+from twext.enterprise.ienterprise import POSTGRES_DIALECT
from twext.enterprise.adbapi2 import ConnectionPool
@@ -225,7 +226,11 @@
return self.cursor.variables.index(self) + 300
+ def __reduce__(self):
+ raise RuntimeError("Not pickleable (since oracle vars aren't)")
+
+
class ConnectionFactory(Parent):
rollbackFail = False
@@ -430,11 +435,14 @@
-class ConnectionPoolBase(TestCase):
+class ConnectionPoolHelper(object):
"""
- Common functionality for testing L{ConnectionPool}.
+ Connection pool setting-up facilities for tests that need a
+ L{ConnectionPool}.
"""
+ dialect = POSTGRES_DIALECT
+
def setUp(self):
"""
Create a L{ConnectionPool} attached to a C{ConnectionFactory}. Start
@@ -444,7 +452,8 @@
self.holders = []
self.factory = ConnectionFactory()
self.pool = ConnectionPool(self.factory.connect,
- maxConnections=2)
+ maxConnections=2,
+ dialect=self.dialect)
self.pool._createHolder = self.makeAHolder
self.clock = self.pool.reactor = ClockWithThreads()
self.pool.startService()
@@ -492,7 +501,7 @@
-class ConnectionPoolTests(ConnectionPoolBase):
+class ConnectionPoolTests(ConnectionPoolHelper, TestCase):
"""
Tests for L{ConnectionPool}.
"""
@@ -1319,29 +1328,20 @@
-class NetworkedConnectionPoolTests(ConnectionPoolTests):
+class NetworkedPoolHelper(ConnectionPoolHelper):
"""
- Tests for L{ConnectionPoolConnection} and L{ConnectionPoolClient}
- interacting with each other.
+ An extension of L{ConnectionPoolHelper} that can set up a
+ L{ConnectionPoolClient} and L{ConnectionPoolConnection} attached to each
+ other.
"""
- # Don't run these tests.
- def test_propagateDialect(self):
- """
- Paramstyle and dialect are configured differently for
- shared-connection-pool transactions.
- """
-
- test_propagateParamstyle = test_propagateDialect
- test_propagateParamstyle.skip = test_propagateParamstyle.__doc__.strip()
-
def setUp(self):
"""
Do the same setup from L{ConnectionPoolBase}, but also establish a
loopback connection between a L{ConnectionPoolConnection} and a
L{ConnectionPoolClient}.
"""
- super(NetworkedConnectionPoolTests, self).setUp()
+ super(NetworkedPoolHelper, self).setUp()
self.pump = IOPump(ConnectionPoolClient(),
ConnectionPoolConnection(self.pool))
@@ -1352,7 +1352,7 @@
pending network I/O.
"""
self.pump.flush()
- super(NetworkedConnectionPoolTests, self).flushHolders()
+ super(NetworkedPoolHelper, self).flushHolders()
self.pump.flush()
@@ -1379,6 +1379,24 @@
return result
+
+class NetworkedConnectionPoolTests(NetworkedPoolHelper, ConnectionPoolTests):
+ """
+ Tests for L{ConnectionPoolConnection} and L{ConnectionPoolClient}
+ interacting with each other.
+ """
+
+ # Don't run these tests.
+ def test_propagateDialect(self):
+ """
+ Paramstyle and dialect are configured differently for
+ shared-connection-pool transactions.
+ """
+
+
+ test_propagateParamstyle = test_propagateDialect
+ test_propagateParamstyle.skip = test_propagateParamstyle.__doc__.strip()
+
def test_newTransaction(self):
"""
L{ConnectionPoolClient.newTransaction} returns a provider of
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20111010/f494e784/attachment-0001.html>
More information about the calendarserver-changes
mailing list