예제 #1
0
# GNU Mailman.  If not, see <https://www.gnu.org/licenses/>.
"""Alembic migration environment."""

from alembic import context
from contextlib import closing
from mailman.config import config
from mailman.core.initialize import initialize_1
from mailman.database.model import Model
from mailman.utilities.string import expand
from sqlalchemy import create_engine

try:
    url = expand(config.database.url, None, config.paths)
except AttributeError:
    # Initialize config object for external alembic calls
    initialize_1()
    url = expand(config.database.url, None, config.paths)


# We can't use @public here.  See GL#423
def run_migrations_offline():
    """Run migrations in 'offline' mode.

    This configures the context with just a URL and not an Engine,
    though an Engine is acceptable here as well.  By skipping the Engine
    creation we don't even need a DBAPI to be available.

    Calls to context.execute() here emit the given string to the script
    output.
    """
    context.configure(url=url, target_metadata=Model.metadata)
예제 #2
0
    ]


from alembic import context
from contextlib import closing
from mailman.core.initialize import initialize_1
from mailman.config import config
from mailman.database.model import Model
from mailman.utilities.string import expand
from sqlalchemy import create_engine

try:
    url = expand(config.database.url, config.paths)
except AttributeError:
    # Initialize config object for external alembic calls
    initialize_1()
    url = expand(config.database.url, config.paths)


def run_migrations_offline():
    """Run migrations in 'offline' mode.

    This configures the context with just a URL and not an Engine,
    though an Engine is acceptable here as well.  By skipping the Engine
    creation we don't even need a DBAPI to be available.

    Calls to context.execute() here emit the given string to the script
    output.
    """
    context.configure(url=url, target_metadata=Model.metadata)
    with context.begin_transaction():
예제 #3
0
 def setUp(cls):
     # Set up the basic configuration stuff.  Turn off path creation until
     # we've pushed the testing config.
     config.create_paths = False
     initialize.initialize_1(INHIBIT_CONFIG_FILE)
     assert cls.var_dir is None, "Layer already set up"
     # Calculate a temporary VAR_DIR directory so that run-time artifacts
     # of the tests won't tread on the installation's data.  This also
     # makes it easier to clean up after the tests are done, and insures
     # isolation of test suite runs.
     cls.var_dir = tempfile.mkdtemp()
     # We need a test configuration both for the foreground process and any
     # child processes that get spawned.  lazr.config would allow us to do
     # it all in a string that gets pushed, and we'll do that for the
     # foreground, but because we may be spawning processes (such as
     # runners) we'll need a file that we can specify to the with the -C
     # option.  Craft the full test configuration string here, push it, and
     # also write it out to a temp file for -C.
     test_config = dedent(
         """
     [mailman]
     layout: testing
     [passwords]
     password_scheme: cleartext
     [paths.testing]
     var_dir: %s
     [devmode]
     testing: yes
     """
         % cls.var_dir
     )
     # Read the testing config and push it.
     test_config += resource_string("mailman.testing", "testing.cfg")
     config.create_paths = True
     config.push("test config", test_config)
     # Initialize everything else.
     initialize.initialize_2()
     initialize.initialize_3()
     # When stderr debugging is enabled, subprocess root loggers should
     # also be more verbose.
     if cls.stderr:
         test_config += dedent(
             """
         [logging.root]
         propagate: yes
         level: debug
         """
         )
     # Enable log message propagation and reset the log paths so that the
     # doctests can check the output.
     for logger_config in config.logger_configs:
         sub_name = logger_config.name.split(".")[-1]
         if sub_name == "root":
             continue
         logger_name = "mailman." + sub_name
         log = logging.getLogger(logger_name)
         log.propagate = True
         # Reopen the file to a new path that tests can get at.  Instead of
         # using the configuration file path though, use a path that's
         # specific to the logger so that tests can find expected output
         # more easily.
         path = os.path.join(config.LOG_DIR, sub_name)
         get_handler(sub_name).reopen(path)
         log.setLevel(logging.DEBUG)
         # If stderr debugging is enabled, make sure subprocesses are also
         # more verbose.
         if cls.stderr:
             test_config += expand(
                 dedent(
                     """
             [logging.$name]
             propagate: yes
             level: debug
             """
                 ),
                 dict(name=sub_name, path=path),
             )
     # zope.testing sets up logging before we get to our own initialization
     # function.  This messes with the root logger, so explicitly set it to
     # go to stderr.
     if cls.stderr:
         console = logging.StreamHandler(sys.stderr)
         formatter = logging.Formatter(config.logging.root.format, config.logging.root.datefmt)
         console.setFormatter(formatter)
         logging.getLogger().addHandler(console)
     # Write the configuration file for subprocesses and set up the config
     # object to pass that properly on the -C option.
     config_file = os.path.join(cls.var_dir, "test.cfg")
     with open(config_file, "w") as fp:
         fp.write(test_config)
         print(file=fp)
     config.filename = config_file
예제 #4
0
 def setUp(cls):
     # Set up the basic configuration stuff.  Turn off path creation until
     # we've pushed the testing config.
     config.create_paths = False
     initialize.initialize_1(INHIBIT_CONFIG_FILE)
     assert cls.var_dir is None, 'Layer already set up'
     # Calculate a temporary VAR_DIR directory so that run-time artifacts
     # of the tests won't tread on the installation's data.  This also
     # makes it easier to clean up after the tests are done, and insures
     # isolation of test suite runs.
     cls.var_dir = tempfile.mkdtemp()
     # We need a test configuration both for the foreground process and any
     # child processes that get spawned.  lazr.config would allow us to do
     # it all in a string that gets pushed, and we'll do that for the
     # foreground, but because we may be spawning processes (such as
     # runners) we'll need a file that we can specify to the with the -C
     # option.  Craft the full test configuration string here, push it, and
     # also write it out to a temp file for -C.
     #
     # Create a dummy postfix.cfg file so that the test suite doesn't try
     # to run the actual postmap command, which may not exist anyway.
     postfix_cfg = os.path.join(cls.var_dir, 'postfix.cfg')
     with open(postfix_cfg, 'w') as fp:
         print(dedent("""
         [postfix]
         postmap_command: true
         """), file=fp)
     test_config = dedent("""
     [mailman]
     layout: testing
     [paths.testing]
     var_dir: {0}
     [devmode]
     testing: yes
     [mta]
     configuration: {1}
     """.format(cls.var_dir, postfix_cfg))
     # Read the testing config and push it.
     more = resource_bytes('mailman.testing', 'testing.cfg')
     test_config += more.decode('utf-8')
     config.create_paths = True
     config.push('test config', test_config)
     # Initialize everything else.
     initialize.initialize_2(testing=True)
     initialize.initialize_3()
     # When stderr debugging is enabled, subprocess root loggers should
     # also be more verbose.
     if cls.stderr:
         test_config += dedent("""
         [logging.root]
         level: debug
         """)
     # Enable log message propagation and reset the log paths so that the
     # doctests can check the output.
     for logger_config in config.logger_configs:
         sub_name = logger_config.name.split('.')[-1]
         if sub_name == 'root':
             continue
         logger_name = 'mailman.' + sub_name
         log = logging.getLogger(logger_name)
         log.propagate = cls.stderr
         # Reopen the file to a new path that tests can get at.  Instead of
         # using the configuration file path though, use a path that's
         # specific to the logger so that tests can find expected output
         # more easily.
         path = os.path.join(config.LOG_DIR, sub_name)
         get_handler(sub_name).reopen(path)
         log.setLevel(logging.DEBUG)
         # If stderr debugging is enabled, make sure subprocesses are also
         # more verbose.
         if cls.stderr:
             test_config += expand(dedent("""
             [logging.$name]
             propagate: yes
             level: debug
             """), dict(name=sub_name, path=path))
     # The root logger will already have a handler, but it's not the right
     # handler.  Remove that and set our own.
     if cls.stderr:
         console = logging.StreamHandler(sys.stderr)
         formatter = logging.Formatter(config.logging.root.format,
                                       config.logging.root.datefmt)
         console.setFormatter(formatter)
         root = logging.getLogger()
         del root.handlers[:]
         root.addHandler(console)
     # Write the configuration file for subprocesses and set up the config
     # object to pass that properly on the -C option.
     config_file = os.path.join(cls.var_dir, 'test.cfg')
     with open(config_file, 'w') as fp:
         fp.write(test_config)
         print(file=fp)
     config.filename = config_file
예제 #5
0
def config_initialize(request):
    # Set up the basic configuration stuff.  Turn off path creation until
    # we've pushed the testing config.
    config.create_paths = False
    initialize.initialize_1(INHIBIT_CONFIG_FILE)
    # Calculate a temporary VAR_DIR directory so that run-time artifacts
    # of the tests won't tread on the installation's data.  This also
    # makes it easier to clean up after the tests are done, and insures
    # isolation of test suite runs.
    var_dir = tempfile.mkdtemp()
    # We need a test configuration both for the foreground process and any
    # child processes that get spawned.  lazr.config would allow us to do
    # it all in a string that gets pushed, and we'll do that for the
    # foreground, but because we may be spawning processes (such as
    # runners) we'll need a file that we can specify to the with the -C
    # option.  Craft the full test configuration string here, push it, and
    # also write it out to a temp file for -C.
    #
    # Create a dummy postfix.cfg file so that the test suite doesn't try
    # to run the actual postmap command, which may not exist anyway.
    postfix_cfg = os.path.join(var_dir, 'postfix.cfg')
    with open(postfix_cfg, 'w') as fp:
        print(dedent("""
        [postfix]
        postmap_command: true
        transport_file_type: hash
        """),
              file=fp)
        test_config = dedent("""
        [mailman]
        layout: testing
        [paths.testing]
        var_dir: {}
        [mta]
        configuration: {}
        [devmode]
        enabled: yes
        testing: yes
        recipient: [email protected]

        [mta]
        smtp_port: 9025
        lmtp_port: 9024
        incoming: mailman.testing.mta.FakeMTA

        [webservice]
        port: 9001

        [archiver.mhonarc]
        enable: yes

        [archiver.mail_archive]
        enable: yes

        [archiver.prototype]
        enable: yes
        """.format(var_dir, postfix_cfg))
        config.create_paths = True
        config.push('test config', test_config)
        # Initialize everything else.
    initialize.initialize_2(testing=True)
    initialize.initialize_3()

    config_file = os.path.join(var_dir, 'test.cfg')
    with open(config_file, 'w') as fp:
        fp.write(test_config)
        print(file=fp)
        config.filename = config_file
    # Start the Mailman's test runner.
    server = TestableMaster(wait_for_webservice)
    server.start('rest', 'in')
    request.addfinalizer(server.stop)
    # Run the test.
    yield
    reset_the_world()
    # Destroy the test database after the tests are done so that there is
    # no data in case the tests are rerun with a database layer like mysql
    # or postgresql which are not deleted in teardown.
    shutil.rmtree(var_dir)
    # Prevent the bit of post-processing on the .pop() that creates
    # directories.  We're basically shutting down everything and we don't
    # need the directories created.  Plus, doing so leaves a var directory
    # turd in the source tree's top-level directory.  We do it this way
    # rather than shutil.rmtree'ing the resulting var directory because
    # it's possible the user created a valid such directory for
    # operational or test purposes.
    config.create_paths = False
    config.pop('test config')