summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBarry Warsaw2012-04-20 17:32:27 -0400
committerBarry Warsaw2012-04-20 17:32:27 -0400
commit847409ba333375bd9c168e28f15748e58970404f (patch)
tree1ca1044e3f2a90a0022a77910d1297bf52ff1159 /src
parentcd3f84b301c2150fea5402129a2e7bc862fbb52b (diff)
downloadmailman-847409ba333375bd9c168e28f15748e58970404f.tar.gz
mailman-847409ba333375bd9c168e28f15748e58970404f.tar.zst
mailman-847409ba333375bd9c168e28f15748e58970404f.zip
Diffstat (limited to 'src')
-rw-r--r--src/mailman/database/tests/data/__init__.py0
-rw-r--r--src/mailman/database/tests/data/mailman_01.dbbin0 -> 48128 bytes
-rw-r--r--src/mailman/database/tests/test_migrations.py56
-rw-r--r--src/mailman/database/transaction.py6
-rw-r--r--src/mailman/rest/wsgiapp.py13
-rw-r--r--src/mailman/runners/lmtp.py4
6 files changed, 45 insertions, 34 deletions
diff --git a/src/mailman/database/tests/data/__init__.py b/src/mailman/database/tests/data/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/mailman/database/tests/data/__init__.py
diff --git a/src/mailman/database/tests/data/mailman_01.db b/src/mailman/database/tests/data/mailman_01.db
new file mode 100644
index 000000000..1ff8d8343
--- /dev/null
+++ b/src/mailman/database/tests/data/mailman_01.db
Binary files differ
diff --git a/src/mailman/database/tests/test_migrations.py b/src/mailman/database/tests/test_migrations.py
index bf3decc88..8b4dd1f43 100644
--- a/src/mailman/database/tests/test_migrations.py
+++ b/src/mailman/database/tests/test_migrations.py
@@ -31,12 +31,14 @@ import sqlite3
import tempfile
import unittest
+from pkg_resources import resource_filename
from zope.component import getUtility
-from mailman.app.lifecycle import create_list
from mailman.config import config
from mailman.interfaces.domain import IDomainManager
-from mailman.testing.helpers import configuration, temporary_db
+from mailman.interfaces.listmanager import IListManager
+from mailman.interfaces.mailinglist import IAcceptableAliasSet
+from mailman.testing.helpers import configuration
from mailman.testing.layers import ConfigLayer
from mailman.utilities.modules import call_name
@@ -66,7 +68,8 @@ class TestMigration20120407(unittest.TestCase):
shutil.rmtree(self._tempdir)
def test_sqlite_base(self):
- # Test the SQLite base schema.
+ # Test that before the migration, the old table columns are present
+ # and the new database columns are not.
url = 'sqlite:///' + os.path.join(self._tempdir, 'mailman.db')
database_class = config.database['class']
database = call_name(database_class)
@@ -74,14 +77,6 @@ class TestMigration20120407(unittest.TestCase):
database.initialize()
# Load all the database SQL to just before ours.
database.load_migrations('20120406999999')
- # Populate the test database with a domain and a mailing list.
- with temporary_db(database):
- getUtility(IDomainManager).add(
- 'example.com', 'An example domain.',
- 'http://lists.example.com', 'postmaster@example.com')
- mlist = create_list('test@example.com')
- del mlist
- database.commit()
# Verify that the database has not yet been migrated.
for missing in ('archive_policy',
'nntp_prefix_subject_too'):
@@ -100,7 +95,8 @@ class TestMigration20120407(unittest.TestCase):
'select {0} from mailinglist;'.format(present))
def test_sqlite_migration(self):
- # Test the SQLite base schema.
+ # Test that after the migration, the old table columns are missing
+ # and the new database columns are present.
url = 'sqlite:///' + os.path.join(self._tempdir, 'mailman.db')
database_class = config.database['class']
database = call_name(database_class)
@@ -108,14 +104,6 @@ class TestMigration20120407(unittest.TestCase):
database.initialize()
# Load all the database SQL to just before ours.
database.load_migrations('20120406999999')
- # Populate the test database with a domain and a mailing list.
- with temporary_db(database):
- getUtility(IDomainManager).add(
- 'example.com', 'An example domain.',
- 'http://lists.example.com', 'postmaster@example.com')
- mlist = create_list('test@example.com')
- del mlist
- database.commit()
# Load all migrations, up to and including this one.
database.load_migrations('20120407000000')
# Verify that the database has been migrated.
@@ -134,3 +122,31 @@ class TestMigration20120407(unittest.TestCase):
self.assertRaises(sqlite3.OperationalError,
database.store.execute,
'select {0} from mailinglist;'.format(missing))
+
+ def test_data_after_migration(self):
+ # Ensure that the existing data and foreign key references are
+ # preserved across a migration. Unfortunately, this requires sample
+ # data, which kind of sucks.
+ dst = os.path.join(self._tempdir, 'mailman.db')
+ src = resource_filename('mailman.database.tests.data', 'mailman_01.db')
+ shutil.copyfile(src, dst)
+ url = 'sqlite:///' + dst
+ database_class = config.database['class']
+ database = call_name(database_class)
+ with configuration('database', url=url):
+ # Initialize the database and perform the migrations.
+ database.initialize()
+ database.load_migrations('20120407000000')
+ # Check that the domains survived the migration. This table was
+ # not touched so it should be fine.
+ domains = list(getUtility(IDomainManager))
+ self.assertEqual(len(domains), 1)
+ self.assertEqual(domains[0].mail_host, 'example.com')
+ # There should be exactly one mailing list defined.
+ mlists = list(getUtility(IListManager).mailing_lists)
+ self.assertEqual(len(mlists), 1)
+ # Get the mailing list object and check its acceptable aliases.
+ # This tests that foreign keys continue to work.
+ aliases_set = IAcceptableAliasSet(mlists)
+ self.assertEqual(set(aliases_set.aliases),
+ set(['foo@example.com', 'bar@example.com']))
diff --git a/src/mailman/database/transaction.py b/src/mailman/database/transaction.py
index 47e58d3e2..7a6ba00af 100644
--- a/src/mailman/database/transaction.py
+++ b/src/mailman/database/transaction.py
@@ -17,11 +17,11 @@
"""Transactional support."""
-from __future__ import absolute_import, unicode_literals
+from __future__ import absolute_import, print_function, unicode_literals
__metaclass__ = type
__all__ = [
- 'txn',
+ 'transactional',
]
@@ -29,7 +29,7 @@ from mailman.config import config
-class txn(object):
+class transactional:
"""Decorator for transactional support.
When the function this decorator wraps exits cleanly, the current
diff --git a/src/mailman/rest/wsgiapp.py b/src/mailman/rest/wsgiapp.py
index 36e8ae5ac..a735d2012 100644
--- a/src/mailman/rest/wsgiapp.py
+++ b/src/mailman/rest/wsgiapp.py
@@ -33,6 +33,7 @@ from wsgiref.simple_server import WSGIRequestHandler
from wsgiref.simple_server import make_server as wsgi_server
from mailman.config import config
+from mailman.database.transaction import transactional
from mailman.rest.root import Root
@@ -51,17 +52,11 @@ class AdminWebServiceWSGIRequestHandler(WSGIRequestHandler):
class AdminWebServiceApplication(RestishApp):
"""Connect the restish WSGI application to Mailman's database."""
+ @transactional
def __call__(self, environ, start_response):
"""See `RestishApp`."""
- try:
- response = super(AdminWebServiceApplication, self).__call__(
- environ, start_response)
- except:
- config.db.abort()
- raise
- else:
- config.db.commit()
- return response
+ return super(AdminWebServiceApplication, self).__call__(
+ environ, start_response)
diff --git a/src/mailman/runners/lmtp.py b/src/mailman/runners/lmtp.py
index 45fa5a783..249ab94c1 100644
--- a/src/mailman/runners/lmtp.py
+++ b/src/mailman/runners/lmtp.py
@@ -41,7 +41,7 @@ from zope.component import getUtility
from mailman.config import config
from mailman.core.runner import Runner
-from mailman.database.transaction import txn
+from mailman.database.transaction import transactional
from mailman.email.message import Message
from mailman.interfaces.listmanager import IListManager
from mailman.utilities.datetime import now
@@ -154,7 +154,7 @@ class LMTPRunner(Runner, smtpd.SMTPServer):
Channel(self, conn, addr)
slog.debug('LMTP accept from %s', addr)
- @txn
+ @transactional
def process_message(self, peer, mailfrom, rcpttos, data):
try:
# Refresh the list of list names every time we process a message