# 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)
] 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():
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
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
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')