summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mailman/config/configure.zcml14
-rw-r--r--src/mailman/database/factory.py58
-rw-r--r--src/mailman/database/postgresql.py40
-rw-r--r--src/mailman/database/sqlite.py28
-rw-r--r--src/mailman/interfaces/database.py19
5 files changed, 94 insertions, 65 deletions
diff --git a/src/mailman/config/configure.zcml b/src/mailman/config/configure.zcml
index 481ef6d0b..ed85ae1a6 100644
--- a/src/mailman/config/configure.zcml
+++ b/src/mailman/config/configure.zcml
@@ -22,6 +22,20 @@
factory="mailman.model.requests.ListRequests"
/>
+ <adapter
+ for="mailman.interfaces.database.IDatabase"
+ provides="mailman.interfaces.database.ITemporaryDatabase"
+ factory="mailman.database.sqlite.make_temporary"
+ name="sqlite"
+ />
+
+ <adapter
+ for="mailman.interfaces.database.IDatabase"
+ provides="mailman.interfaces.database.ITemporaryDatabase"
+ factory="mailman.database.postgresql.make_temporary"
+ name="postgres"
+ />
+
<utility
provides="mailman.interfaces.bans.IBanManager"
factory="mailman.model.bans.BanManager"
diff --git a/src/mailman/database/factory.py b/src/mailman/database/factory.py
index 0ea2f4776..127c4aaeb 100644
--- a/src/mailman/database/factory.py
+++ b/src/mailman/database/factory.py
@@ -27,19 +27,15 @@ __all__ = [
]
-import os
import types
-import shutil
-import tempfile
-from functools import partial
-from urlparse import urlsplit, urlunsplit
+from zope.component import getAdapter
from zope.interface import implementer
from zope.interface.verify import verifyObject
from mailman.config import config
-from mailman.interfaces.database import IDatabase, IDatabaseFactory
-from mailman.testing.helpers import configuration
+from mailman.interfaces.database import (
+ IDatabase, IDatabaseFactory, ITemporaryDatabase)
from mailman.utilities.modules import call_name
@@ -90,16 +86,6 @@ class DatabaseTestingFactory:
-def _sqlite_cleanup(self, tempdir):
- shutil.rmtree(tempdir)
-
-
-def _postgresql_cleanup(self, database, tempdb_name):
- database.store.rollback()
- database.store.close()
- config.db.store.execute('DROP DATABASE {0}'.format(tempdb_name))
-
-
@implementer(IDatabaseFactory)
class DatabaseTemporaryFactory:
"""Create a temporary database for some of the migration tests."""
@@ -110,38 +96,6 @@ class DatabaseTemporaryFactory:
database_class_name = config.database['class']
database = call_name(database_class_name)
verifyObject(IDatabase, database)
- if database.TAG == 'sqlite':
- tempdir = tempfile.mkdtemp()
- url = 'sqlite:///' + os.path.join(tempdir, 'mailman.db')
- with configuration('database', url=url):
- database.initialize()
- database._cleanup = types.MethodType(
- partial(_sqlite_cleanup, tempdir=tempdir), database)
- # bool column values in SQLite must be integers.
- database.FALSE = 0
- database.TRUE = 1
- elif database.TAG == 'postgres':
- parts = urlsplit(config.database.url)
- assert parts.scheme == 'postgres'
- new_parts = list(parts)
- new_parts[2] = '/mmtest'
- url = urlunsplit(new_parts)
- # Use the existing database connection to create a new testing
- # database.
- config.db.store.execute('ABORT;')
- config.db.store.execute('CREATE DATABASE mmtest;')
- with configuration('database', url=url):
- database.initialize()
- database._cleanup = types.MethodType(
- partial(_postgresql_cleanup,
- database=database,
- tempdb_name='mmtest'),
- database)
- # bool column values in PostgreSQL.
- database.FALSE = 'False'
- database.TRUE = 'True'
- else:
- raise RuntimeError(
- 'Unsupported test database: {0}'.format(database.TAG))
- # Don't load the migrations.
- return database
+ adapted_database = getAdapter(
+ database, ITemporaryDatabase, database.TAG)
+ return adapted_database
diff --git a/src/mailman/database/postgresql.py b/src/mailman/database/postgresql.py
index 1fb831b3b..49188148f 100644
--- a/src/mailman/database/postgresql.py
+++ b/src/mailman/database/postgresql.py
@@ -22,12 +22,18 @@ from __future__ import absolute_import, print_function, unicode_literals
__metaclass__ = type
__all__ = [
'PostgreSQLDatabase',
+ 'make_temporary',
]
+import types
+
+from functools import partial
from operator import attrgetter
+from urlparse import urlsplit, urlunsplit
from mailman.database.base import StormBaseDatabase
+from mailman.testing.helpers import configuration
@@ -63,3 +69,37 @@ class PostgreSQLDatabase(StormBaseDatabase):
max("id") IS NOT null)
FROM "{0}";
""".format(model_class.__storm_table__))
+
+
+
+# Test suite adapter for ITemporaryDatabase.
+
+def _cleanup(self, store, tempdb_name):
+ from mailman.config import config
+ store.rollback()
+ store.close()
+ # From the original database connection, drop the now unused database.
+ config.db.store.execute('DROP DATABASE {0}'.format(tempdb_name))
+
+
+def make_temporary(database):
+ """Adapts by monkey patching an existing PostgreSQL IDatabase."""
+ from mailman.config import config
+ parts = urlsplit(config.database.url)
+ assert parts.scheme == 'postgres'
+ new_parts = list(parts)
+ new_parts[2] = '/mmtest'
+ url = urlunsplit(new_parts)
+ # Use the existing database connection to create a new testing
+ # database.
+ config.db.store.execute('ABORT;')
+ config.db.store.execute('CREATE DATABASE mmtest;')
+ with configuration('database', url=url):
+ database.initialize()
+ database._cleanup = types.MethodType(
+ partial(_cleanup, store=database.store, tempdb_name='mmtest'),
+ database)
+ # bool column values in PostgreSQL.
+ database.FALSE = 'False'
+ database.TRUE = 'True'
+ return database
diff --git a/src/mailman/database/sqlite.py b/src/mailman/database/sqlite.py
index 305fa006e..a9683457a 100644
--- a/src/mailman/database/sqlite.py
+++ b/src/mailman/database/sqlite.py
@@ -22,14 +22,20 @@ from __future__ import absolute_import, unicode_literals
__metaclass__ = type
__all__ = [
'SQLiteDatabase',
+ 'make_temporary',
]
import os
+import types
+import shutil
+import tempfile
+from functools import partial
from urlparse import urlparse
from mailman.database.base import StormBaseDatabase
+from mailman.testing.helpers import configuration
@@ -54,3 +60,25 @@ class SQLiteDatabase(StormBaseDatabase):
# Ignore errors
if fd > 0:
os.close(fd)
+
+
+
+# Test suite adapter for ITemporaryDatabase.
+
+def _cleanup(self, tempdir):
+ shutil.rmtree(tempdir)
+
+
+def make_temporary(database):
+ """Adapts by monkey patching an existing SQLite IDatabase."""
+ tempdir = tempfile.mkdtemp()
+ url = 'sqlite:///' + os.path.join(tempdir, 'mailman.db')
+ with configuration('database', url=url):
+ database.initialize()
+ database._cleanup = types.MethodType(
+ partial(_cleanup, tempdir=tempdir),
+ database)
+ # bool column values in SQLite must be integers.
+ database.FALSE = 0
+ database.TRUE = 1
+ return database
diff --git a/src/mailman/interfaces/database.py b/src/mailman/interfaces/database.py
index a74ddd71f..1f39daee7 100644
--- a/src/mailman/interfaces/database.py
+++ b/src/mailman/interfaces/database.py
@@ -24,6 +24,7 @@ __all__ = [
'DatabaseError',
'IDatabase',
'IDatabaseFactory',
+ 'ITemporaryDatabase',
]
@@ -50,19 +51,6 @@ class IDatabase(Interface):
configuration file setting.
"""
- def _make_temporary():
- """Make a temporary database.
-
- This is a @staticmethod used in the test framework.
-
- :return: An object with one attribute and one method. The attribute
- `database` is the temporary `IDatabase`. The method is a callable
- named `cleanup()`, taking no arguments which should be called when
- the temporary database is no longer necessary. The database will
- already be initialized, but no migrations will have been loaded
- into it.
- """
-
def begin():
"""Begin the current transaction."""
@@ -77,6 +65,11 @@ class IDatabase(Interface):
+class ITemporaryDatabase(Interface):
+ """Marker interface for test suite adaptation."""
+
+
+
class IDatabaseFactory(Interface):
"Interface for creating new databases."""