[prev in list] [next in list] [prev in thread] [next in thread] 

List:       mailman-cvs
Subject:    [Mailman-checkins] SF.net SVN: mailman: [8192] trunk/mailman/Mailman
From:       bwarsaw () users ! sourceforge ! net
Date:       2007-04-17 21:37:50
Message-ID: E1HdvN0-0002Zg-B9 () sc8-pr-svn1 ! sourceforge ! net
[Download RAW message or body]

Revision: 8192
          http://svn.sourceforge.net/mailman/?rev=8192&view=rev
Author:   bwarsaw
Date:     2007-04-17 14:37:49 -0700 (Tue, 17 Apr 2007)

Log Message:
-----------
Another round of merges of my Pycon branch...

bin/testall.py
    - Improvements to setting up the tests with temporary files for the db and
      configuration.  Don't accept -C/--config because that will just confuse
      things.
    - Copy our new testing.cfg.in template file to a temp file, populate it
      with a few additional run-time calculate values, and use that in both
      the parent (bin/testall script) and children (bin/mailmanctl and
      friends).

Mailman/initialize.py
    - Split up initialize() into two functions as required by the test suite
      reorg above.  Almost everything else in Mailman will continue to use the
      initialize() function though.

Mailman/configuration.py
    - Store the filename that was used to load the .cfg file from on the
      configuration object.

Modified Paths:
--------------
    trunk/mailman/Mailman/bin/testall.py
    trunk/mailman/Mailman/configuration.py
    trunk/mailman/Mailman/initialize.py
    trunk/mailman/Mailman/testing/Makefile.in
    trunk/mailman/Mailman/testing/base.py
    trunk/mailman/Mailman/testing/emailbase.py
    trunk/mailman/Mailman/testing/test_enum.py

Added Paths:
-----------
    trunk/mailman/Mailman/testing/inmemory.py
    trunk/mailman/Mailman/testing/testing.cfg.in

Modified: trunk/mailman/Mailman/bin/testall.py
===================================================================
--- trunk/mailman/Mailman/bin/testall.py	2007-04-12 18:39:57 UTC (rev 8191)
+++ trunk/mailman/Mailman/bin/testall.py	2007-04-17 21:37:49 UTC (rev 8192)
@@ -17,15 +17,26 @@
 
 """Mailman unit test driver."""
 
+from __future__ import with_statement
+
 import os
 import re
+import grp
+import pwd
 import sys
+import shutil
 import optparse
+import tempfile
 import unittest
 
+import Mailman
+import Mailman.testing
+
 from Mailman import Version
+from Mailman.configuration import config
+from Mailman.database.dbcontext import dbcontext
 from Mailman.i18n import _
-from Mailman.initialize import initialize
+from Mailman.initialize import initialize_1, initialize_2
 
 __i18n_templates__ = True
 
@@ -63,8 +74,6 @@
     parser.add_option('-e', '--stderr',
                       default=False, action='store_true',
                       help=_('Propagate log errors to stderr.'))
-    parser.add_option('-C', '--config',
-                      help=_('Alternative configuration file to use'))
     opts, args = parser.parse_args()
     return parser, opts, args
 
@@ -137,14 +146,48 @@
     global basedir
 
     parser, opts, args = parseargs()
-    initialize(opts.config, propagate_logs=opts.stderr)
     if not args:
         args = ['.']
 
-    import Mailman
-    basedir = os.path.dirname(Mailman.__file__)
-    runner = unittest.TextTestRunner(verbosity=opts.verbosity)
-    results = runner.run(suite(args))
+    # Set up the testing configuration file both for this process, and for all
+    # sub-processes testing will spawn (e.g. the qrunners).
+    #
+    # Calculate various temporary files needed by the test suite, but only for
+    # those files which must also go into shared configuration file.
+    cfg_in = os.path.join(os.path.dirname(Mailman.testing.__file__),
+                           'testing.cfg.in')
+    fd, cfg_out = tempfile.mkstemp(suffix='.cfg')
+    os.close(fd)
+    shutil.copyfile(cfg_in, cfg_out)
+
+    initialize_1(cfg_out, propagate_logs=opts.stderr)
+    mailman_uid = pwd.getpwnam(config.MAILMAN_USER).pw_uid
+    mailman_gid = grp.getgrnam(config.MAILMAN_GROUP).gr_gid
+    os.chmod(cfg_out, 0660)
+    os.chown(cfg_out, mailman_uid, mailman_gid)
+
+    fd, config.dbfile = tempfile.mkstemp(dir=config.DATA_DIR, suffix='.db')
+    os.close(fd)
+    os.chmod(config.dbfile, 0660)
+    os.chown(config.dbfile, mailman_uid, mailman_gid)
+
+    # Patch ups
+    test_engine_url = 'sqlite:///' + config.dbfile
+    config.SQLALCHEMY_ENGINE_URL = test_engine_url
+
+    with open(cfg_out, 'a') as fp:
+        print >> fp, 'SQLALCHEMY_ENGINE_URL = "%s"' % test_engine_url
+
+    initialize_2()
+
+    try:
+        basedir = os.path.dirname(Mailman.__file__)
+        runner = unittest.TextTestRunner(verbosity=opts.verbosity)
+        results = runner.run(suite(args))
+    finally:
+        os.remove(cfg_out)
+        os.remove(config.dbfile)
+
     sys.exit(bool(results.failures or results.errors))
 
 

Modified: trunk/mailman/Mailman/configuration.py
===================================================================
--- trunk/mailman/Mailman/configuration.py	2007-04-12 18:39:57 UTC (rev 8191)
+++ trunk/mailman/Mailman/configuration.py	2007-04-17 21:37:49 UTC (rev 8192)
@@ -72,12 +72,14 @@
         path = os.path.abspath(os.path.expanduser(filename))
         try:
             execfile(path, ns, ns)
+            self.filename = path
         except EnvironmentError, e:
             if e.errno <> errno.ENOENT or original_filename:
                 raise
             # The file didn't exist, so try mm_cfg.py
             from Mailman import mm_cfg
             ns.update(mm_cfg.__dict__)
+            self.filename = None
         # Based on values possibly set in mailman.cfg, add additional qrunners
         if ns['USE_MAILDIR']:
             self.add_qrunner('Maildir')

Modified: trunk/mailman/Mailman/initialize.py
===================================================================
--- trunk/mailman/Mailman/initialize.py	2007-04-12 18:39:57 UTC (rev 8191)
+++ trunk/mailman/Mailman/initialize.py	2007-04-17 21:37:49 UTC (rev 8192)
@@ -32,7 +32,12 @@
 
 
 
-def initialize(config=None, propagate_logs=False):
+# These initialization calls are separated for the testing framework, which
+# needs to do some internal calculations after config file loading and log
+# initialization, but before database initialization.  Generally all other
+# code will just call initialize().
+
+def initialize_1(config, propagate_logs):
     # By default, set the umask so that only owner and group can read and
     # write our files.  Specifically we must have g+rw and we probably want
     # o-rwx although I think in most cases it doesn't hurt if other can read
@@ -42,4 +47,12 @@
     os.umask(007)
     Mailman.configuration.config.load(config)
     Mailman.loginit.initialize(propagate_logs)
+
+
+def initialize_2():
     Mailman.database.initialize()
+
+
+def initialize(config=None, propagate_logs=False):
+    initialize_1(config, propagate_logs)
+    initialize_2()

Modified: trunk/mailman/Mailman/testing/Makefile.in
===================================================================
--- trunk/mailman/Mailman/testing/Makefile.in	2007-04-12 18:39:57 UTC (rev 8191)
+++ trunk/mailman/Mailman/testing/Makefile.in	2007-04-17 21:37:49 UTC (rev 8192)
@@ -42,6 +42,7 @@
 SHELL=		/bin/sh
 
 MODULES=	*.py
+OTHERFILES=	testing.cfg.in
 
 # Modes for directories and executables created by the install
 # process.  Default to group-writable directories but
@@ -59,7 +60,7 @@
 all:
 
 install: 
-	for f in $(MODULES); \
+	for f in $(MODULES) $(OTHERFILES); \
 	do \
 	    $(INSTALL) -m $(FILEMODE) $(srcdir)/$$f $(DESTDIR)$(PACKAGEDIR); \
 	done

Modified: trunk/mailman/Mailman/testing/base.py
===================================================================
--- trunk/mailman/Mailman/testing/base.py	2007-04-12 18:39:57 UTC (rev 8191)
+++ trunk/mailman/Mailman/testing/base.py	2007-04-17 21:37:49 UTC (rev 8192)
@@ -41,26 +41,7 @@
 
 
 
-def dummy_mta_function(*args, **kws):
-    pass
-
-
-
 class TestBase(unittest.TestCase):
-    def _configure(self, fp):
-        # Make sure that we don't pollute the real database with our test
-        # mailing list.
-        test_engine_url = 'sqlite:///' + self._dbfile
-        print >> fp, 'SQLALCHEMY_ENGINE_URL = "%s"' % test_engine_url
-        config.SQLALCHEMY_ENGINE_URL = test_engine_url
-        # Use the Mailman.MTA.stub module
-        print >> fp, 'MTA = "stub"'
-        config.MTA = 'stub'
-        print >> fp, 'add_domain("example.com", "www.example.com")'
-        # Only add this domain once to the current process
-        if 'example.com' not in config.domains:
-            config.add_domain('example.com', 'www.example.com')
-
     def ndiffAssertEqual(self, first, second):
         """Like failUnlessEqual except use ndiff for readable output."""
         if first <> second:
@@ -72,30 +53,6 @@
             raise self.failureException(fp.getvalue())
 
     def setUp(self):
-        mailman_uid = pwd.getpwnam(config.MAILMAN_USER).pw_uid
-        mailman_gid = grp.getgrnam(config.MAILMAN_GROUP).gr_gid
-        # Write a temporary configuration file, but allow for subclasses to
-        # add additional data.  Make sure the config and db files, which
-        # mkstemp creates, has the proper ownership and permissions.
-        fd, self._config = tempfile.mkstemp(dir=config.DATA_DIR, suffix='.cfg')
-        os.close(fd)
-        os.chmod(self._config, 0440)
-        os.chown(self._config, mailman_uid, mailman_gid)
-        fd, self._dbfile = tempfile.mkstemp(dir=config.DATA_DIR, suffix='.db')
-        os.close(fd)
-        os.chmod(self._dbfile, 0660)
-        os.chown(self._dbfile, mailman_uid, mailman_gid)
-        fp = open(self._config, 'w')
-        try:
-            self._configure(fp)
-        finally:
-            fp.close()
-        # Create a fake new Mailman.MTA module which stubs out the create()
-        # and remove() functions.
-        stubmta_module = new.module('Mailman.MTA.stub')
-        sys.modules['Mailman.MTA.stub'] = stubmta_module
-        stubmta_module.create = dummy_mta_function
-        stubmta_module.remove = dummy_mta_function
         # Be sure to close the connection to the current database, and then
         # reconnect to the new temporary SQLite database.  Otherwise we end up
         # with turds in the main database and our qrunner subprocesses won't
@@ -116,8 +73,6 @@
         self._mlist.Unlock()
         rmlist.delete_list(self._mlist.fqdn_listname, self._mlist,
                            archives=True, quiet=True)
-        os.unlink(self._config)
-        os.unlink(self._dbfile)
         # Clear out any site locks, which can be left over if tests fail.
         for filename in os.listdir(config.LOCK_DIR):
             if filename.startswith('<site>'):

Modified: trunk/mailman/Mailman/testing/emailbase.py
===================================================================
--- trunk/mailman/Mailman/testing/emailbase.py	2007-04-12 18:39:57 UTC (rev 8191)
+++ trunk/mailman/Mailman/testing/emailbase.py	2007-04-17 21:37:49 UTC (rev 8192)
@@ -52,15 +52,6 @@
 
 
 class EmailBase(TestBase):
-    def _configure(self, fp):
-        TestBase._configure(self, fp)
-        print >> fp, 'SMTPPORT =', TESTPORT
-        config.SMTPPORT = TESTPORT
-        # Don't go nuts on mailmanctl restarts.  If a qrunner fails once, it
-        # will keep failing.
-        print >> fp, 'MAX_RESTARTS = 1'
-        config.MAX_RESTARTS = 1
-
     def setUp(self):
         TestBase.setUp(self)
         try:
@@ -70,7 +61,7 @@
             TestBase.tearDown(self)
             raise
         try:
-            os.system('bin/mailmanctl -C %s -q start' % self._config)
+            os.system('bin/mailmanctl -C %s -q start' % config.filename)
             # If any errors occur in the above, be sure to manually call
             # tearDown().  unittest doesn't call tearDown() for errors in
             # setUp().
@@ -79,7 +70,7 @@
             raise
 
     def tearDown(self):
-        os.system('bin/mailmanctl -C %s -q stop' % self._config)
+        os.system('bin/mailmanctl -C %s -q stop' % config.filename)
         self._server.close()
         # Wait a while until the server actually goes away
         while True:

Added: trunk/mailman/Mailman/testing/inmemory.py
===================================================================
--- trunk/mailman/Mailman/testing/inmemory.py	                        (rev 0)
+++ trunk/mailman/Mailman/testing/inmemory.py	2007-04-17 21:37:49 UTC (rev 8192)
@@ -0,0 +1,488 @@
+# Copyright (C) 2007 by the Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+# USA.
+
+"""In-memory implementations of Mailman interfaces, for testing purposes."""
+
+import datetime
+import urlparse
+
+from Mailman import Utils
+from Mailman import passwords
+from Mailman.interfaces import *
+
+from zope.interface import implements
+
+
+
+class UserManager(object):
+    implements(IUserManager)
+
+    def __init__(self):
+        self._users     = set()
+        self._next_id   = 1
+
+    @property
+    def users(self):
+        for user in self._users:
+            yield user
+
+    def create_user(self):
+        user = User(self._next_id, self)
+        self._next_id += 1
+        self._users.add(user)
+        return user
+
+    def remove(self, user):
+        self._users.discard(user)
+
+    def get(self, address):
+        # Yes, this is slow and icky, but it's only for testing purposes
+        for user in self._users:
+            if user.controls(address):
+                return user
+        return None
+
+
+
+class User(object):
+    implements(IUser)
+
+    def __init__(self, user_id, user_mgr):
+        self._user_id   = user_id
+        self._user_mgr  = user_mgr
+        self._addresses = set()
+        self.real_name  = u''
+        self.password   = passwords.NoPasswordScheme.make_secret('ignore')
+        self.default_profile = None
+
+    def __eq__(self, other):
+        return (IUser.implementedBy(other) and
+                self.user_id == other.user_id and
+                self.user_manager is other.user_manager)
+
+    def __ne__(self, other):
+        return not self.__eq__(other)
+
+    @property
+    def user_id(self):
+        return self._user_id
+
+    @property
+    def user_manager(self):
+        return self._user_mgr
+
+    @property
+    def addresses(self):
+        for address in self._addresses:
+            yield address
+
+    def add_address(self, address):
+        if self.controls(address):
+            return
+        user_address = Address(address, self)
+        self._addresses.add(user_address)
+
+    def remove_address(self, address):
+        if not self.controls(address):
+            return
+        user_address = Address(address, self)
+        self._addresses.discard(user_address)
+
+    def controls(self, address):
+        for user_address in self.addresses:
+            if user_address == address:
+                return True
+        return False
+
+
+
+class Address(object):
+    implements(IAddress)
+
+    def __init__(self, email_address, user, profile=None):
+        self._address       = email_address
+        self._user          = user
+        self.profile        = profile or Profile()
+        self.validated_on   = None
+
+    def __eq__(self, other):
+        return (IAddress.implementedBy(other) and
+                self.address == other.address and
+                self.user == other.user)
+
+    @property
+    def address(self):
+        return self._address
+
+    @property
+    def user(self):
+        return self._user
+
+
+
+class RegularDelivery(object):
+    implements(IRegularDelivery)
+
+
+class PlainTextDigestDelivery(object):
+    implements(IPlainTextDigestDelivery)
+
+
+class MIMEDigestDelivery(object):
+    implements(IMIMEDigestDeliver)
+
+
+
+class DeliveryEnabled(object):
+    implements(IDeliveryStatus)
+
+    @property
+    def enabled(self):
+        return True
+
+
+class DeliveryDisabled(object):
+    implements(IDeliveryStatus)
+
+    @property
+    def enabled(self):
+        return False
+
+
+class DeliveryDisabledByUser(DeliveryDisabled):
+    implements(IDeliveryDisabledByUser)
+
+
+class DeliveryDisabledbyAdministrator(DeliveryDisabled):
+    implements(IDeliveryDisabledByAdministrator)
+
+    reason = u'Unknown'
+
+
+class DeliveryDisabledByBounces(DeliveryDisabled):
+    implements(IDeliveryDisabledByBounces)
+
+    bounce_info = 'XXX'
+
+
+class DeliveryTemporarilySuspended(object):
+    implements(IDeliveryTemporarilySuspended)
+
+    def __init__(self, start_date, end_date):
+        self.start_date = start_date
+        self.end_date   = end_date
+
+    @property
+    def enabled(self):
+        now = datetime.datetime.now()
+        return not (self.start_date <= now < self.end_date)
+
+
+
+class OkayToPost(object):
+    implements(IPostingPermission)
+
+    # XXX
+    okay_to_post = True
+
+
+
+class Profile(object):
+    implements(IProfile)
+
+    # System defaults
+    acknowledge         = False
+    hide                = True
+    language            = 'en'
+    list_copy           = True
+    own_postings        = True
+    delivery_mode       = RegularDelivery()
+    delivery_status     = DeliveryEnabled()
+    posting_permission  = OkayToPost()
+
+
+
+class Roster(object):
+    implements(IRoster)
+
+    def __init__(self, name):
+        self._name      = name
+        self._members   = set()
+
+    def __eq__(self, other):
+        return (IRoster.implementedBy(other) and
+                self.name == other.name)
+
+    def __ne__(self, other):
+        return not self.__eq__(other)
+
+    @property
+    def name(self):
+        return self._name
+
+    def add(self, member):
+        self._members.add(member)
+
+    def remove(self, member):
+        self._members.remove(member)
+
+    @property
+    def members(self):
+        for member in self._members:
+            yield member
+
+
+
+class Member(object):
+    implements(IMember)
+
+    def __init__(self, address, roster, profile=None):
+        self._address   = address
+        self._roster    = roster
+        self.profile    = profile or Profile()
+
+    @property
+    def address(self):
+        return self._address
+
+    @property
+    def roster(self):
+        return self._roster
+
+
+
+class ListManager(object):
+    implements(IListManager)
+
+    def __init__(self):
+        self._mlists = {}
+
+    def add(self, mlist):
+        self._mlists[mlist.fqdn_listname] = mlist
+
+    def remove(self, mlist):
+        del self._mlists[mlist.fqdn_listname]
+
+    @property
+    def mailing_lists(self):
+        return self._mlists.itervalues()
+
+    @property
+    def names(self):
+        return self._mlists.iterkeys()
+
+    def get(self, fqdn_listname):
+        return self._mlists.get(fqdn_listname)
+
+
+
+class MailingList(object):
+    implements(IMailingListIdentity,
+               IMailingListAddresses,
+               IMailingListURLs,
+               IMailingListRosters,
+               IMailingListStatistics,
+               )
+
+    def __init__(self, list_name, host_name, web_host):
+        self._listname      = list_name
+        self._hostname      = hostname
+        self._webhost       = web_host
+        self._fqdn_listname = Utils.fqdn_listname(list_name, host_name)
+        # Rosters
+        self._owners        = set(Roster(self.owner_address))
+        self._moderators    = set(Roster(self._listname + '-moderators@' +
+                                         self._hostname))
+        self._members       = set(Roster(self.posting_address))
+        # Statistics
+        self._created_on    = datetime.datetime.now()
+        self._last_posting  = None
+        self._post_number   = 0
+        self._last_digest   = None
+
+    # IMailingListIdentity
+
+    @property
+    def list_name(self):
+        return self._listname
+
+    @property
+    def host_name(self):
+        return self._hostname
+
+    @property
+    def fqdn_listname(self):
+        return self._fqdn_listname
+
+    # IMailingListAddresses
+
+    @property
+    def posting_address(self):
+        return self._fqdn_listname
+
+    @property
+    def noreply_address(self):
+        return self._listname + '-noreply@' + self._hostname
+
+    @property
+    def owner_address(self):
+        return self._listname + '-owner@' + self._hostname
+
+    @property
+    def request_address(self):
+        return self._listname + '-request@' + self._hostname
+
+    @property
+    def bounces_address(self):
+        return self._listname + '-bounces@' + self._hostname
+
+    @property
+    def confirm_address(self):
+        return self._listname + '-confirm@' + self._hostname
+
+    @property
+    def join_address(self):
+        return self._listname + '-join@' + self._hostname
+
+    @property
+    def leave_address(self):
+        return self._listname + '-leave@' + self._hostname
+
+    @property
+    def subscribe_address(self):
+        return self._listname + '-subscribe@' + self._hostname
+
+    @property
+    def unsubscribe_address(self):
+        return self._listname + '-unsubscribe@' + self._hostname
+
+    # IMailingListURLs
+
+    protocol = 'http'
+
+    @property
+    def web_host(self):
+        return self._webhost
+
+    def script_url(self, target, context=None):
+        if context is None:
+            return urlparse.urlunsplit((self.protocol, self.web_host, target,
+                                        # no extra query or fragment
+                                        '', ''))
+        return urlparse.urljoin(context.location, target)
+
+    # IMailingListRosters
+
+    @property
+    def owner_rosters(self):
+        return iter(self._owners)
+
+    @property
+    def moderator_rosters(self):
+        return iter(self._moderators)
+
+    @property
+    def member_rosters(self):
+        return iter(self._members)
+
+    def add_owner_roster(self, roster):
+        self._owners.add(roster)
+
+    def add_moderator_roster(self, roster):
+        self._moderators.add(roster)
+
+    def add_member_roster(self, roster):
+        self._members.add(roster)
+
+    def remove_owner_roster(self, roster):
+        self._owners.discard(roster)
+
+    def remove_moderator_roster(self, roster):
+        self._moderators.discard(roster)
+
+    def remove_member_roster(self, roster):
+        self._members.discard(roster)
+
+    @property
+    def owners(self):
+        for roster in self._owners:
+            for member in roster.members:
+                yield member
+
+    @property
+    def moderators(self):
+        for roster in self._moderators:
+            for member in roster.members:
+                yield member
+
+    @property
+    def administrators(self):
+        for member in self.owners:
+            yield member
+        for member in self.moderators:
+            yield member
+
+    @property
+    def members(self):
+        for roster in self._members:
+            for member in roster.members:
+                yield member
+
+    @property
+    def regular_members(self):
+        for member in self.members:
+            if IRegularDelivery.implementedBy(member.profile.delivery_mode):
+                yield member
+
+    @property
+    def digest_member(self):
+        for member in self.members:
+            if IDigestDelivery.implementedBy(member.profile.delivery_mode):
+                yield member
+
+    # Statistic
+
+    @property
+    def creation_date(self):
+        return self._created_on
+
+    @property
+    def last_post_date(self):
+        return self._last_posting
+
+    @property
+    def post_number(self):
+        return self._post_number
+
+    @property
+    def last_digest_date(self):
+        return self._last_digest
+
+
+
+class MailingListRequest(object):
+    implements(IMailingListRequest)
+
+    location = ''
+
+
+
+def initialize():
+    from Mailman.configuration import config
+    config.user_manager     = UserManager()
+    config.list_manager     = ListManager()
+    config.message_manager  = None

Modified: trunk/mailman/Mailman/testing/test_enum.py
===================================================================
--- trunk/mailman/Mailman/testing/test_enum.py	2007-04-12 18:39:57 UTC (rev 8191)
+++ trunk/mailman/Mailman/testing/test_enum.py	2007-04-17 21:37:49 UTC (rev 8192)
@@ -93,9 +93,10 @@
         eq(int(Colors.blue), 3)
         eq(int(MoreColors.red), 1)
         eq(int(OtherColors.blue), 2)
-        
+
     def test_enum_duplicates(self):
         try:
+            # This is bad because kyle and kenny have the same integer value.
             class Bad(Enum):
                 cartman = 1
                 stan    = 2

Added: trunk/mailman/Mailman/testing/testing.cfg.in
===================================================================
--- trunk/mailman/Mailman/testing/testing.cfg.in	                        (rev 0)
+++ trunk/mailman/Mailman/testing/testing.cfg.in	2007-04-17 21:37:49 UTC (rev 8192)
@@ -0,0 +1,14 @@
+# -*- python -*-
+
+# Configuration file template for the unit test suite.  We need this because
+# both the process running the tests and all sub-processes (e.g. qrunners)
+# must share the same configuration file.
+
+MANAGERS_INIT_FUNCTION  = 'Mailman.testing.inmemory.initialize'
+SMTPPORT                = 10825
+MAX_RESTARTS            = 1
+MTA                     = None
+
+add_domain('example.com', 'www.example.com')
+
+# bin/testall will add a SQLALCHEMY_ENGINE_URL below


This was sent by the SourceForge.net collaborative development platform, the world's \
largest Open Source development site. _______________________________________________
Mailman-checkins mailing list
Mailman-checkins@python.org
Unsubscribe: http://mail.python.org/mailman/options/mailman-checkins/mailman-cvs%40progressive-comp.com



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic