Barry Warsaw pushed to branch master at mailman / Mailman
Commits: 212127e9 by Barry Warsaw at 2015-11-01T15:52:03Z Revert "Fix issue #3 by searching for the 'master' script in several possible" This reverts commit 8c471e067c4b31064c2f69c0afd048a7e756a429. The fix wasn't correct. Now we have a test for the expected behavior. - - - - - 3 changed files: - src/mailman/commands/tests/test_control.py - src/mailman/config/config.py - src/mailman/docs/NEWS.rst Changes: ===================================== src/mailman/commands/tests/test_control.py ===================================== --- a/src/mailman/commands/tests/test_control.py +++ b/src/mailman/commands/tests/test_control.py @@ -18,6 +18,7 @@ """Test some additional corner cases for starting/stopping.""" __all__ = [ + 'TestBinDir', 'TestStart', 'find_master', 'make_config', @@ -33,10 +34,13 @@ import shutil import socket import unittest +from contextlib import ExitStack from datetime import timedelta, datetime from mailman.commands.cli_control import Start, kill_watcher -from mailman.config import config +from mailman.config import Configuration, config +from mailman.testing.helpers import configuration from mailman.testing.layers import ConfigLayer +from tempfile import TemporaryDirectory SEP = '|' @@ -159,3 +163,54 @@ class TestStart(unittest.TestCase): self.command.process(self.args) pid = find_master() self.assertNotEqual(pid, None) + + + +class TestBinDir(unittest.TestCase): + """Test issues related to bin_dir, e.g. issue #3""" + + layer = ConfigLayer + + def setUp(self): + self.command = Start() + self.command.parser = FakeParser() + self.args = FakeArgs() + self.args.config = make_config() + + def test_master_is_elsewhere(self): + with ExitStack() as resources: + # Patch os.fork() so that we can record the failing child process's + # id. We need to wait on the child exiting in either case, and + # when it fails, no master.pid will be written. + bin_dir = resources.enter_context(TemporaryDirectory()) + old_master = os.path.join(config.BIN_DIR, 'master') + new_master = os.path.join(bin_dir, 'master') + shutil.move(old_master, new_master) + resources.callback(shutil.move, new_master, old_master) + # Starting mailman should fail because 'master' can't be found. + # XXX This will print Errno 2 on the console because we're not + # silencing the child process's stderr. + self.command.process(self.args) + # There should be no pid file. + args_config = Configuration() + args_config.load(self.args.config) + self.assertFalse(os.path.exists(args_config.PID_FILE)) + os.wait() + + def test_master_is_elsewhere_and_findable(self): + with ExitStack() as resources: + bin_dir = resources.enter_context(TemporaryDirectory()) + old_master = os.path.join(config.BIN_DIR, 'master') + new_master = os.path.join(bin_dir, 'master') + shutil.move(old_master, new_master) + resources.enter_context( + configuration('paths.testing', bin_dir=bin_dir)) + resources.callback(shutil.move, new_master, old_master) + # Starting mailman should find master in the new bin_dir. + self.command.process(self.args) + # There should a pid file and the process it describes should be + # killable. We might have to wait until the process has started. + master_pid = find_master() + self.assertIsNotNone(master_pid, 'master did not start') + os.kill(master_pid, signal.SIGTERM) + os.waitpid(master_pid, 0) ===================================== src/mailman/config/config.py ===================================== --- a/src/mailman/config/config.py +++ b/src/mailman/config/config.py @@ -134,20 +134,8 @@ class Configuration: def _expand_paths(self): """Expand all configuration paths.""" - # First we need to locate the bin directory. This can differ in - # several cases, such as, if we're installing into a virtual - # environment, /usr/bin, /usr/local/bin, or running the test suite. - # We'll try some common locations, looking for a landmark. First - # location wins. - for origin in (sys.executable, sys.argv[0]): - bin_dir = os.path.abspath(os.path.dirname(origin)) - # Search for 'master' in this directory, since that's the thing we - # actually need to be able to run. - if os.path.exists(os.path.join(bin_dir, 'master')): - break - else: - print("Could not find the 'master' script", file=sys.stderr) - sys.exit(1) + # Set up directories. + default_bin_dir = os.path.abspath(os.path.dirname(sys.executable)) # Now that we've loaded all the configuration files we're going to # load, set up some useful directories based on the settings in the # configuration file. @@ -168,7 +156,7 @@ class Configuration: var_dir = os.environ.get('MAILMAN_VAR_DIR', category.var_dir) substitutions = dict( cwd = os.getcwd(), - argv = bin_dir, + argv = default_bin_dir, # Directories. bin_dir = category.bin_dir, data_dir = category.data_dir, ===================================== src/mailman/docs/NEWS.rst ===================================== --- a/src/mailman/docs/NEWS.rst +++ b/src/mailman/docs/NEWS.rst @@ -16,9 +16,6 @@ Bugs ---- * When the mailing list's `admin_notify_mchanges` is True, the list owners now get the subscription notification. (Closes: #1) - * When `pip` installing Mailman into `/usr/local`, the `master` script is - searched for relative to several landmark locations. Originally given by - Sambuddha Basu, adapted by Barry Warsaw. (Closes: #3) * Fix the traceback that occurred when trying to convert a `text/html` subpart to plaintext via the `mimedel` handler. Now, a configuration variable `[mailman]html_to_plain_text_command` in the `mailman.cfg` file View it on GitLab: https://gitlab.com/mailman/mailman/commit/212127e9374ec6791a90306f176d1961b3befc67
_______________________________________________ Mailman-checkins mailing list Mailman-checkins@python.org Unsubscribe: https://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org