summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBarry Warsaw2015-04-22 10:28:04 -0400
committerBarry Warsaw2015-04-22 10:28:04 -0400
commit16570b8a7525dcb6720bc4b04790b6117ac3483b (patch)
tree097efcd0ca15da887c887b41f7d799ce08e30891 /src
parentab41980bf3e69b81eff43172149667e2c0834a2e (diff)
parent6ab77ea42b65839ac87876719dc3069c0989d67a (diff)
downloadmailman-16570b8a7525dcb6720bc4b04790b6117ac3483b.tar.gz
mailman-16570b8a7525dcb6720bc4b04790b6117ac3483b.tar.zst
mailman-16570b8a7525dcb6720bc4b04790b6117ac3483b.zip
Diffstat (limited to 'src')
-rw-r--r--src/mailman/bin/master.py16
-rw-r--r--src/mailman/database/factory.py6
-rw-r--r--src/mailman/database/postgresql.py15
-rw-r--r--src/mailman/docs/NEWS.rst2
-rw-r--r--src/mailman/utilities/importer.py15
5 files changed, 36 insertions, 18 deletions
diff --git a/src/mailman/bin/master.py b/src/mailman/bin/master.py
index 5ffe59647..ebf08ba11 100644
--- a/src/mailman/bin/master.py
+++ b/src/mailman/bin/master.py
@@ -45,6 +45,12 @@ LOCK_LIFETIME = timedelta(days=1, hours=6)
SECONDS_IN_A_DAY = 86400
SUBPROC_START_WAIT = timedelta(seconds=20)
+# Environment variables to forward into subprocesses.
+PRESERVE_ENVS = (
+ 'COVERAGE_PROCESS_START',
+ 'MAILMAN_EXTRA_TESTING_CFG',
+ )
+
class ScriptOptions(Options):
@@ -373,11 +379,11 @@ class Loop:
var_dir = os.environ.get('MAILMAN_VAR_DIR')
if var_dir is not None:
env['MAILMAN_VAR_DIR'] = var_dir
- # For the testing framework, if this environment variable is set, pass
- # it on to the subprocess.
- coverage_env = os.environ.get('COVERAGE_PROCESS_START')
- if coverage_env is not None:
- env['COVERAGE_PROCESS_START'] = coverage_env
+ # For the testing framework, if these environment variables are set,
+ # pass them on to the subprocess.
+ for envvar in PRESERVE_ENVS:
+ if envvar in os.environ:
+ env[envvar] = os.environ[envvar]
args.append(env)
os.execle(*args)
# We should never get here.
diff --git a/src/mailman/database/factory.py b/src/mailman/database/factory.py
index 7222ba395..8b30b9417 100644
--- a/src/mailman/database/factory.py
+++ b/src/mailman/database/factory.py
@@ -135,6 +135,12 @@ class DatabaseTestingFactory:
database = call_name(database_class)
verifyObject(IDatabase, database)
database.initialize()
+ # Remove existing tables (PostgreSQL will keep them across runs)
+ metadata = MetaData(bind=database.engine)
+ metadata.reflect()
+ metadata.drop_all()
+ database.commit()
+ # Now create the current model without Alembic upgrades.
Model.metadata.create_all(database.engine)
database.commit()
# Make _reset() a bound method of the database instance.
diff --git a/src/mailman/database/postgresql.py b/src/mailman/database/postgresql.py
index 9877f110d..ea6540721 100644
--- a/src/mailman/database/postgresql.py
+++ b/src/mailman/database/postgresql.py
@@ -24,6 +24,7 @@ __all__ = [
from mailman.database.base import SABaseDatabase
from mailman.database.model import Model
+from sqlalchemy import Integer
@@ -42,8 +43,12 @@ class PostgreSQLDatabase(SABaseDatabase):
# http://stackoverflow.com/questions/544791/
# django-postgresql-how-to-reset-primary-key
for table in tables:
- store.execute("""\
- SELECT setval('"{0}_id_seq"', coalesce(max("id"), 1),
- max("id") IS NOT null)
- FROM "{0}";
- """.format(table))
+ for column in table.primary_key:
+ if (column.autoincrement
+ and isinstance(column.type, Integer)
+ and not column.foreign_keys):
+ store.execute("""\
+ SELECT setval('"{0}_{1}_seq"', coalesce(max("{1}"), 1),
+ max("{1}") IS NOT null)
+ FROM "{0}";
+ """.format(table, column.name))
diff --git a/src/mailman/docs/NEWS.rst b/src/mailman/docs/NEWS.rst
index 17d5bdc4b..74d124f4e 100644
--- a/src/mailman/docs/NEWS.rst
+++ b/src/mailman/docs/NEWS.rst
@@ -45,6 +45,8 @@ Bugs
list itself is deleted. (LP: #1432239)
* The built-in example ``IArchiver`` implementations now explicitly return
None. (LP: #1203359)
+ * The test suite now runs successfully again with PostgreSQL. Given by
+ Aurélien Bompard. (LP: #1435941)
Configuration
-------------
diff --git a/src/mailman/utilities/importer.py b/src/mailman/utilities/importer.py
index 66a23123c..b55d8c38d 100644
--- a/src/mailman/utilities/importer.py
+++ b/src/mailman/utilities/importer.py
@@ -47,6 +47,7 @@ from mailman.interfaces.nntp import NewsgroupModeration
from mailman.interfaces.usermanager import IUserManager
from mailman.utilities.filesystem import makedirs
from mailman.utilities.i18n import search
+from sqlalchemy import Boolean
from urllib.error import URLError
from zope.component import getUtility
@@ -151,9 +152,9 @@ enabled: yes
-# Attributes in Mailman 2 which have a different type in Mailman 3.
+# Attributes in Mailman 2 which have a different type in Mailman 3. Some
+# types (e.g. bools) are autodetected from their SA column types.
TYPES = dict(
- allow_list_posts=bool,
autorespond_owner=ResponseAction,
autorespond_postings=ResponseAction,
autorespond_requests=ResponseAction,
@@ -163,24 +164,18 @@ TYPES = dict(
default_member_action=member_action_mapping,
default_nonmember_action=nonmember_action_mapping,
digest_volume_frequency=DigestFrequency,
- emergency=bool,
- encode_ascii_prefixes=bool,
filter_action=filter_action_mapping,
filter_extensions=list_members_to_unicode,
filter_types=list_members_to_unicode,
forward_unrecognized_bounces_to=UnrecognizedBounceDisposition,
- gateway_to_mail=bool,
- include_rfc2369_headers=bool,
moderator_password=str_to_bytes,
newsgroup_moderation=NewsgroupModeration,
- nntp_prefix_subject_too=bool,
pass_extensions=list_members_to_unicode,
pass_types=list_members_to_unicode,
personalize=Personalization,
preferred_language=check_language_code,
reply_goes_to_list=ReplyToMunging,
subscription_policy=SubscriptionPolicy,
- topics_enabled=bool,
)
@@ -253,6 +248,10 @@ def import_config_pck(mlist, config_dict):
value = bytes_to_str(value)
# Some types require conversion.
converter = TYPES.get(key)
+ if converter is None:
+ column = getattr(mlist.__class__, key, None)
+ if column is not None and isinstance(column.type, Boolean):
+ converter = bool
try:
if converter is not None:
value = converter(value)