[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