Repository: ClearcodeHQ/pytest-rabbitmq (language: python)

Issue:
feature: add --rabbitmq-plugindir and rabbitmq_plugindir
Hi,

this pull request will add an option to manually configure the `RABBITMQ_ENABLED_PLUGINS_FILE` env variable. Is not a mandatory feature, but i found it quite useful in several occasions in which i had to start the server with already enabled plugins in order to inspect and debug my project while it was hung in testing.



Discussion / hints:

Fix patch:
diff --git a/CHANGES.rst b/CHANGES.rst
index 6b6138b..cdae956 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -1,6 +1,15 @@
 CHANGELOG
 =========
 
+unreleased
+----------
+
+- [feature] Allow to configure plugin's location with the use of
+
+  * **--rabbitmq-logsdir** command line argument
+  * **rabbitmq_logsdir** ini file configuration option
+  * **logsdir** factory argument
+
 2.0.1
 ----------
 
diff --git a/README.rst b/README.rst
index f3f3c37..4c15540 100644
--- a/README.rst
+++ b/README.rst
@@ -106,6 +106,11 @@ You can pick which you prefer, but remember that these settings are handled in t
      - --rabbitmq-logsdir
      - rabbitmq_logsdir
      - $TMPDIR
+   * - Plugin directory location
+     - plugin_path
+     - --rabbitmq-plugindir
+     - rabbitmq_plugindir
+     - $TMPDIR
    * - Node name
      - node
      - --rabbitmq-node
diff --git a/pylintrc b/pylintrc
index c298f22..61dabd5 100644
--- a/pylintrc
+++ b/pylintrc
@@ -134,7 +134,7 @@ indent-after-paren=4
 indent-string='    '
 
 # Maximum number of characters on a single line.
-max-line-length=80
+max-line-length=100
 
 # Maximum number of lines in a module
 max-module-lines=1000
diff --git a/setup.cfg b/setup.cfg
index 795cfe6..ce1d9c9 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,5 +1,5 @@
 [pycodestyle]
-max-line-length = 80
+max-line-length = 100
 exclude = docs/*,build/*,venv/*
 
 [pydocstyle]


Test patch:
diff --git a/src/pytest_rabbitmq/factories/executor.py b/src/pytest_rabbitmq/factories/executor.py
index a38cba7..7486e61 100644
--- a/src/pytest_rabbitmq/factories/executor.py
+++ b/src/pytest_rabbitmq/factories/executor.py
@@ -9,8 +9,16 @@ class RabbitMqExecutor(TCPExecutor):
     """RabbitMQ executor to start specific rabbitmq instances."""
 
     def __init__(
-            self, command, host, port, rabbit_ctl, logpath, path,
-            node_name=None, **kwargs
+        self,
+        command,
+        host,
+        port,
+        rabbit_ctl,
+        logpath,
+        path,
+        plugin_path,
+        node_name=None,
+        **kwargs,
     ):  # pylint:disable=too-many-arguments
         """
         Initialize RabbitMQ executor.
@@ -25,17 +33,15 @@ def __init__(
         :param kwargs: see TCPExecutor for description
         """
         envvars = {
-            'RABBITMQ_LOG_BASE': logpath + f'/rabbit-server.{port}.log',
-            'RABBITMQ_MNESIA_BASE': path + 'mnesia',
-            'RABBITMQ_ENABLED_PLUGINS_FILE': path + 'plugins',
-            'RABBITMQ_NODE_PORT': str(port),
+            "RABBITMQ_LOG_BASE": logpath + f"/rabbit-server.{port}.log",
+            "RABBITMQ_MNESIA_BASE": path + "mnesia",
+            "RABBITMQ_ENABLED_PLUGINS_FILE": plugin_path + "/plugins",
+            "RABBITMQ_NODE_PORT": str(port),
             # Use the port number in node name, so multiple instances started
             # at different ports will work separately instead of clustering.
-            'RABBITMQ_NODENAME': node_name or f'rabbitmq-test-{port}',
+            "RABBITMQ_NODENAME": node_name or f"rabbitmq-test-{port}",
         }
-        super().__init__(
-            command, host, port, timeout=60, envvars=envvars, **kwargs
-        )
+        super().__init__(command, host, port, timeout=60, envvars=envvars, **kwargs)
         self.rabbit_ctl = rabbit_ctl
 
     def rabbitctl_output(self, *args):
@@ -47,17 +53,16 @@ def rabbitctl_output(self, *args):
         ctl_command = [self.rabbit_ctl]
         ctl_command.extend(args)
         return subprocess.check_output(
-            ctl_command,
-            env=self._popen_kwargs['env']
-        ).decode('utf-8')
+            ctl_command, env=self._popen_kwargs["env"]
+        ).decode("utf-8")
 
     def list_exchanges(self):
         """Get exchanges defined on given rabbitmq."""
         exchanges = []
-        output = self.rabbitctl_output('list_exchanges', 'name')
-        unwanted_exchanges = ['Listing exchanges ...', '...done.']
+        output = self.rabbitctl_output("list_exchanges", "name")
+        unwanted_exchanges = ["Listing exchanges ...", "...done."]
 
-        for exchange in output.split('\n'):
+        for exchange in output.split("\n"):
             if exchange and exchange not in unwanted_exchanges:
                 exchanges.append(str(exchange))
 
@@ -66,11 +71,11 @@ def list_exchanges(self):
     def list_queues(self):
         """Get queues defined on given rabbitmq."""
         queues = []
-        output = self.rabbitctl_output('list_queues', 'name')
-        unwanted_queues = ['listing queues', 'done']
+        output = self.rabbitctl_output("list_queues", "name")
+        unwanted_queues = ["listing queues", "done"]
 
-        for queue in output.split('\n'):
-            if queue and queue.strip('. ').lower() not in unwanted_queues:
+        for queue in output.split("\n"):
+            if queue and queue.strip(". ").lower() not in unwanted_queues:
                 queues.append(str(queue))
 
         return queues
diff --git a/src/pytest_rabbitmq/factories/process.py b/src/pytest_rabbitmq/factories/process.py
index d8966a0..acf06b8 100644
--- a/src/pytest_rabbitmq/factories/process.py
+++ b/src/pytest_rabbitmq/factories/process.py
@@ -30,20 +30,24 @@
 def get_config(request):
     """Return a dictionary with config options."""
     config = {}
-    options = [
-        'logsdir', 'host', 'port', 'server', 'ctl', 'node'
-    ]
+    options = ["logsdir", "host", "port", "server", "ctl", "node", "plugindir"]
     for option in options:
-        option_name = 'rabbitmq_' + option
-        conf = request.config.getoption(option_name) or \
-            request.config.getini(option_name)
+        option_name = "rabbitmq_" + option
+        conf = request.config.getoption(option_name) or request.config.getini(
+            option_name
+        )
         config[option] = conf
     return config
 
 
 def rabbitmq_proc(
-        server=None, host=None, port=-1,
-        node=None, ctl=None, logsdir=None,
+    server=None,
+    host=None,
+    port=-1,
+    node=None,
+    ctl=None,
+    logsdir=None,
+    plugindir=None,
 ):
     """
     Fixture factory for RabbitMQ process.
@@ -65,7 +69,8 @@ def rabbitmq_proc(
 
     :returns pytest fixture with RabbitMQ process executor
     """
-    @pytest.fixture(scope='session')
+
+    @pytest.fixture(scope="session")
     def rabbitmq_proc_fixture(request):
         """
         Fixture for RabbitMQ process.
@@ -87,24 +92,23 @@ def rabbitmq_proc_fixture(request):
         :returns: tcp executor of running rabbitmq-server
         """
         config = get_config(request)
-        rabbit_ctl = ctl or config['ctl']
-        rabbit_server = server or config['server']
-        rabbit_host = host or config['host']
-        rabbit_port = get_port(port) or get_port(config['port'])
-
-        rabbit_path = os.path.join(
-            gettempdir(),
-            f'rabbitmq.{rabbit_port}/'
-        )
+        rabbit_ctl = ctl or config["ctl"]
+        rabbit_server = server or config["server"]
+        rabbit_host = host or config["host"]
+        rabbit_port = get_port(port) or get_port(config["port"])
+
+        rabbit_path = os.path.join(gettempdir(), f"rabbitmq.{rabbit_port}/")
+        rabbit_plugin_path = plugindir or config["plugindir"] or rabbit_path
 
         rabbit_executor = RabbitMqExecutor(
             rabbit_server,
             rabbit_host,
             rabbit_port,
             rabbit_ctl,
-            logpath=config['logsdir'] or logsdir,
+            logpath=config["logsdir"] or logsdir,
             path=rabbit_path,
-            node_name=node or config['node'],
+            plugin_path=rabbit_plugin_path,
+            node_name=node or config["node"],
         )
 
         rabbit_executor.start()
diff --git a/src/pytest_rabbitmq/plugin.py b/src/pytest_rabbitmq/plugin.py
index 16ef45c..5689e21 100644
--- a/src/pytest_rabbitmq/plugin.py
+++ b/src/pytest_rabbitmq/plugin.py
@@ -25,82 +25,82 @@
 _help_ctl = "RabbitMQ ctl path"
 _help_server = "RabbitMQ server path"
 _help_logsdir = "Logs directory location"
-_help_host = 'Host at which RabbitMQ will accept connections'
-_help_port = 'Port at which RabbitMQ will accept connections'
-_help_node = 'Node name for rabbitmq instance'
+_help_plugindir = "Directory where 'plugin' file is located"
+_help_host = "Host at which RabbitMQ will accept connections"
+_help_port = "Port at which RabbitMQ will accept connections"
+_help_node = "Node name for rabbitmq instance"
 
 
 def pytest_addoption(parser):
     """Confioguration option."""
+    parser.addini(name="rabbitmq_host", help=_help_host, default="127.0.0.1")
     parser.addini(
-        name='rabbitmq_host',
-        help=_help_host,
-        default='127.0.0.1'
-    )
-    parser.addini(
-        name='rabbitmq_port',
+        name="rabbitmq_port",
         help=_help_port,
         default=None,
     )
     parser.addini(
-        name='rabbitmq_ctl',
+        name="rabbitmq_ctl",
         help=_help_ctl,
-        default='/usr/lib/rabbitmq/bin/rabbitmqctl',
+        default="/usr/lib/rabbitmq/bin/rabbitmqctl",
     )
     parser.addini(
-        name='rabbitmq_server',
+        name="rabbitmq_server",
         help=_help_server,
-        default='/usr/lib/rabbitmq/bin/rabbitmq-server',
+        default="/usr/lib/rabbitmq/bin/rabbitmq-server",
     )
     parser.addini(
-        name='rabbitmq_logsdir',
+        name="rabbitmq_logsdir",
         help=_help_logsdir,
         default=gettempdir(),
     )
     parser.addini(
-        name='rabbitmq_node',
+        name="rabbitmq_plugindir",
+        help=_help_logsdir,
+        default=gettempdir(),
+    )
+    parser.addini(
+        name="rabbitmq_node",
         help=_help_node,
         default=None,
     )
 
     parser.addoption(
-        '--rabbitmq-host',
-        action='store',
-        dest='rabbitmq_host',
+        "--rabbitmq-host",
+        action="store",
+        dest="rabbitmq_host",
         help=_help_host,
     )
     parser.addoption(
-        '--rabbitmq-port',
-        action='store',
-        dest='rabbitmq_port',
-        help=_help_port
+        "--rabbitmq-port", action="store", dest="rabbitmq_port", help=_help_port
     )
     parser.addoption(
-        '--rabbitmq-ctl',
-        action='store',
-        dest='rabbitmq_ctl',
-        help=_help_ctl
+        "--rabbitmq-ctl", action="store", dest="rabbitmq_ctl", help=_help_ctl
     )
     parser.addoption(
-        '--rabbitmq-server',
-        action='store',
-        dest='rabbitmq_server',
-        help=_help_server
+        "--rabbitmq-server", action="store", dest="rabbitmq_server", help=_help_server
     )
     parser.addoption(
-        '--rabbitmq-logsdir',
-        action='store',
-        metavar='path',
-        dest='rabbitmq_logsdir',
+        "--rabbitmq-logsdir",
+        action="store",
+        metavar="path",
+        dest="rabbitmq_logsdir",
         help=_help_logsdir,
     )
     parser.addoption(
-        '--rabbitmq-node',
-        action='store',
-        dest='rabbitmq_node',
+        "--rabbitmq-plugindir",
+        action="store",
+        metavar="path",
+        dest="rabbitmq_plugindir",
+        help=_help_plugindir,
+    )
+    parser.addoption(
+        "--rabbitmq-node",
+        action="store",
+        dest="rabbitmq_node",
         help=_help_node,
     )
 
 
 rabbitmq_proc = factories.rabbitmq_proc()
-rabbitmq = factories.rabbitmq('rabbitmq_proc')
+rabbitmq = factories.rabbitmq("rabbitmq_proc")
diff --git a/tests/conftest.py b/tests/conftest.py
index 835d401..961ddd2 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -2,10 +2,11 @@
 from pytest_rabbitmq import factories
 
 # pylint:disable=invalid-name
-rabbitmq_proc2 = factories.rabbitmq_proc(port=5674, node='test2')
-rabbitmq2 = factories.rabbitmq('rabbitmq_proc2')
-rabbitmq_rand_proc = factories.rabbitmq_proc(port=None, node='test3')
-rabbitmq_rand = factories.rabbitmq('rabbitmq_rand_proc')
+rabbitmq_proc2 = factories.rabbitmq_proc(port=5674, node="test2")
+rabbitmq2 = factories.rabbitmq("rabbitmq_proc2")
+rabbitmq_rand_proc = factories.rabbitmq_proc(port=None, node="test3")
+rabbitmq_rand = factories.rabbitmq("rabbitmq_rand_proc")
 rabbitmq_rand_proc2 = factories.rabbitmq_proc(port=None)
 rabbitmq_rand_proc3 = factories.rabbitmq_proc(port=None)
+rabbitmq_plugindir = factories.rabbitmq_proc(plugindir="/etc")
 # pylint:enable=invalid-name
diff --git a/tests/test_rabbitmq.py b/tests/test_rabbitmq.py
index ea5eeae..b8370c8 100644
--- a/tests/test_rabbitmq.py
+++ b/tests/test_rabbitmq.py
@@ -12,11 +12,11 @@ def test_rabbitmq(rabbitmq):
 
 def test_second_rabbitmq(rabbitmq, rabbitmq2):
     """Check whether two rabbitmq are started correctly."""
-    print('checking first channel')
+    print("checking first channel")
     channel = rabbitmq.channel()
     assert channel.state == channel.OPEN
 
-    print('checking second channel')
+    print("checking second channel")
     channel2 = rabbitmq2.channel()
     assert channel2.state == channel.OPEN
 
@@ -30,7 +30,7 @@ def test_rabbitmq_clear_exchanges(rabbitmq, rabbitmq_proc):
     no_exchanges = rabbitmq_proc.list_exchanges()
 
     # declare exchange and list exchanges afterwards
-    exchange = Exchange(channel, 'cache-in')
+    exchange = Exchange(channel, "cache-in")
     exchange.declare()
     exchanges = rabbitmq_proc.list_exchanges()
 
@@ -53,7 +53,7 @@ def test_rabbitmq_clear_queues(rabbitmq, rabbitmq_proc):
     assert not no_queues
 
     # declare queue, and get new output
-    queue = Queue(channel, 'fastlane')
+    queue = Queue(channel, "fastlane")
     queue.declare()
     queues = rabbitmq_proc.list_queues()
     assert queues
@@ -76,6 +76,17 @@ def test_random_port(rabbitmq_rand):
 def test_random_port_node_names(rabbitmq_rand_proc2, rabbitmq_rand_proc3):
     """Test node names for different processes."""
     # pylint:disable=protected-access
-    assert (rabbitmq_rand_proc2._envvars['RABBITMQ_NODENAME'] !=
-            rabbitmq_rand_proc3._envvars['RABBITMQ_NODENAME'])
+    assert (
+        rabbitmq_rand_proc2._envvars["RABBITMQ_NODENAME"]
+        != rabbitmq_rand_proc3._envvars["RABBITMQ_NODENAME"]
+    )
+    # pylint:enable=protected-access
+
+
+def test_plugin_directory(rabbitmq_plugindir):
+    """Test node names for different processes."""
+    # pylint:disable=protected-access
+    assert (
+        rabbitmq_plugindir._envvars["RABBITMQ_ENABLED_PLUGINS_FILE"] == "/etc/plugins"
+    )
     # pylint:enable=protected-access