]> kaliko git repositories - mpd-sima.git/commitdiff
Add abstract unix socket support for MPD connection
authorkaliko <kaliko@azylum.org>
Wed, 5 May 2021 16:30:45 +0000 (18:30 +0200)
committerkaliko <kaliko@azylum.org>
Fri, 7 May 2021 16:27:31 +0000 (18:27 +0200)
Add unittests for env var parsing

doc/Changelog
sima/utils/config.py
sima/utils/utils.py
tests/test_config.py

index c487b0ef66422f091ce90abcccc5bdabefd7b1c7..0e390f1297a603c6ea3a9149294a3ff0c9a6b5b8 100644 (file)
@@ -2,6 +2,7 @@ MPD_sima v0.18.0.dev0
 
  * Removed obsolete --create-db and --generate-config options
  * Fixed crash when setting XDG_CONFIG_HOME (closes #50)
+ * Add abstract unix socket support for MPD connection
 
  -- kaliko <kaliko@azylum.org>  Wed, 28 Apr 2021 17:21:39 +0200
 
index 854d6df9cb36adc8213354b1e3b0386a4d45fc80..a46c0c66493e3519ab1af41cefe7d88e8087ddbf 100644 (file)
@@ -139,7 +139,7 @@ class ConfMan:  # CONFIG MANAGER CLASS
         self.use_envar()
         self.startopt = options
 
-        ## INIT CALLS
+        # INIT CALLS
         self.init_config()
         self.supersedes_config_with_cmd_line_options()
         # set dbfile
@@ -204,9 +204,11 @@ class ConfMan:  # CONFIG MANAGER CLASS
         # honor MPD_HOST format as in mpc(1)  for command line option --host
         if self.startopt.get('host'):
             if '@' in self.startopt.get('host'):
-                passwd, host = self.startopt.get('host').split('@')
-                self.config.set('MPD', 'password', passwd)
-                self.config.set('MPD', 'host', host)
+                host, passwd = utils.parse_mpd_host(self.startopt.get('host'))
+                if passwd:
+                    self.config.set('MPD', 'password', passwd)
+                if host:
+                    self.config.set('MPD', 'host', host)
 
     def use_envar(self):
         """Use MPD en.var. to set defaults"""
index 8e07e7ae965e5f7342b5425a3094a46f61730bc3..b9dc980c37f5a109b207e133b660df4bb26517df 100644 (file)
@@ -30,7 +30,7 @@ from argparse import ArgumentError, Action
 from base64 import b64decode as push
 from codecs import getencoder
 from datetime import datetime
-from os import environ, access, getcwd, W_OK, R_OK
+from os import getenv, access, getcwd, W_OK, R_OK
 from os.path import dirname, isabs, join, normpath, exists, isdir, isfile
 from time import sleep
 
@@ -45,22 +45,33 @@ def getws(dic):
     aka = getencoder('rot-13')(str((aka), 'utf-8'))[0]
     dic.update({'apikey': aka})
 
+def parse_mpd_host(value):
+    passwd = host = None
+    # If password is set: MPD_HOST=pass@host
+    if '@' in value:
+        mpd_host_env = value.split('@', 1)
+        if mpd_host_env[0]:
+            # A password is actually set
+            passwd = mpd_host_env[0]
+            if mpd_host_env[1]:
+                host = mpd_host_env[1]
+        elif mpd_host_env[1]:
+            # No password set but leading @ is an abstract socket
+            host = '@'+mpd_host_env[1]
+    else:
+        # MPD_HOST is a plain host
+        host = value
+    return host, passwd
+
 
 def get_mpd_environ():
     """
     Retrieve MPD env. var.
     """
     passwd = host = None
-    mpd_host_env = environ.get('MPD_HOST')
-    if mpd_host_env:
-        # If password is set:
-        # mpd_host_env = ['pass', 'host'] because MPD_HOST=pass@host
-        mpd_host_env = mpd_host_env.split('@')
-        mpd_host_env.reverse()
-        host = mpd_host_env[0]
-        if len(mpd_host_env) > 1 and mpd_host_env[1]:
-            passwd = mpd_host_env[1]
-    return (host, environ.get('MPD_PORT', None), passwd)
+    if getenv('MPD_HOST'):
+        host, passwd = parse_mpd_host(getenv('MPD_HOST'))
+    return (host, getenv('MPD_PORT', None), passwd)
 
 
 def normalize_path(path):
index 36ba2accf0bf9d5da101acfd1cb6b40f439720fe..eee93bd8a06c58f3e14bab31009ac6b2e0d5b110 100644 (file)
@@ -12,6 +12,11 @@ from sima.lib.logger import set_logger
 
 
 class TestConfMan(unittest.TestCase):
+    """For some tests we don't care about file access check, then to ensure
+    checks are properly mocked run test forcing non existent locations:
+
+    XDG_DATA_HOME=/non/existent/ XDG_HOME_CONFIG=/non/existent/ python3 -m unittest -vf tests/test_config.py
+    """
 
     @patch('sima.utils.config.makedirs')
     @patch('sima.utils.config.chmod')
@@ -46,5 +51,63 @@ class TestConfMan(unittest.TestCase):
         expected_config = os.path.join(home, '.config', DIRNAME, CONF_FILE)
         self.assertEqual(constructed_config_location, expected_config)
 
+    @patch('sima.utils.config.makedirs')
+    @patch('sima.utils.config.chmod')
+    @patch('sima.utils.config.ConfMan.control_facc')
+    def test_MPD_env_var(self, *args):
+        host = 'example.org'
+        passwd = 's2cr34!'
+        port = '6601'
+        os.environ.pop('MPD_HOST', None)
+        os.environ.pop('MPD_PORT', None)
+        # Test defaults
+        conf = ConfMan({})
+        self.assertEqual(dict(conf.config['MPD']),
+                         {'host': 'localhost', 'port': '6600'})
+        # Test provided env. var.
+        os.environ['MPD_HOST'] = host
+        conf = ConfMan({})
+        self.assertEqual(dict(conf.config['MPD']),
+                         {'host': host, 'port': '6600'})
+        os.environ['MPD_HOST'] = f'{passwd}@{host}'
+        conf = ConfMan({})
+        self.assertEqual(dict(conf.config['MPD']),
+                         {'host': host,
+                          'password': passwd,
+                          'port': '6600'})
+        # Test abstract unix socket support with password
+        os.environ['MPD_HOST'] = f'{passwd}@@/{host}'
+        conf = ConfMan({})
+        self.assertEqual(dict(conf.config['MPD']),
+                         {'host': f'@/{host}',
+                          'password': passwd,
+                          'port': '6600'})
+        # Test abstract unix socket support only
+        os.environ['MPD_HOST'] = f'@/{host}'
+        conf = ConfMan({})
+        self.assertEqual(dict(conf.config['MPD']),
+                         {'host': f'@/{host}',
+                          'port': '6600'})
+        # Test port
+        os.environ['MPD_PORT'] = f'{port}'
+        conf = ConfMan({})
+        self.assertEqual(conf.config['MPD']['port'], port)
+
+    @patch('sima.utils.config.makedirs')
+    @patch('sima.utils.config.chmod')
+    @patch('sima.utils.config.ConfMan.control_facc')
+    def test_config_origin_priority(self, *args):
+        # cli provided host overrides env. var.
+        os.environ['MPD_HOST'] = 'baz.foo'
+        conf = ConfMan({'host': 'cli.host'})
+        self.assertEqual(conf.config['MPD']['host'], 'cli.host')
+        # cli provided abstract socket overrides env. var.
+        conf = ConfMan({'host': '@/abstract'})
+        self.assertEqual(conf.config['MPD']['host'], '@/abstract')
+        # cli provided passord and abstract socket overrides env. var.
+        conf = ConfMan({'host': 'pass!@@/abstract'})
+        self.assertEqual(conf.config['MPD']['host'], '@/abstract')
+        self.assertEqual(conf.config['MPD']['password'], 'pass!')
+
 # VIM MODLINE
 # vim: ai ts=4 sw=4 sts=4 expandtab fileencoding=utf8