]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
pybind/mgr: Also mock the config store in pytest
authorSebastian Wagner <sebastian.wagner@suse.com>
Fri, 7 Aug 2020 14:21:18 +0000 (16:21 +0200)
committerSebastian Wagner <sebastian.wagner@suse.com>
Mon, 17 Aug 2020 11:08:31 +0000 (13:08 +0200)
This will be used to dry-run mgr/cephadm/upgrade.py

Signed-off-by: Sebastian Wagner <sebastian.wagner@suse.com>
src/pybind/mgr/cephadm/tests/fixtures.py
src/pybind/mgr/cephadm/tests/test_cephadm.py
src/pybind/mgr/tests/__init__.py

index 05683aa2376942746bbd3a94f430dab64d243343..a65f501926458ab43b5253d87618e2c08a3ae9d4 100644 (file)
@@ -51,10 +51,10 @@ def with_cephadm_module(module_options=None, store=None):
         if store is None:
             store = {}
         if '_ceph_get/mon_map' not in store:
-            store['_ceph_get/mon_map'] = {
+            m.mock_store_set('_ceph_get', 'mon_map', {
                 'modified': datetime.datetime.utcnow().strftime(CEPH_DATEFMT),
                 'fsid': 'foobar',
-            }
+            })
         for k, v in store.items():
             m._ceph_set_store(k, v)
 
index d97f1517cc521e928b03da42aade74e4910163a4..d4fff4604322016ed947ffaab78ca6eb90e29a53 100644 (file)
@@ -105,7 +105,7 @@ class TestCephadm(object):
             assert wait(cephadm_module, cephadm_module.get_hosts()) == [HostSpec('test', 'test')]
 
             # Be careful with backward compatibility when changing things here:
-            assert json.loads(cephadm_module._store['inventory']) == \
+            assert json.loads(cephadm_module.get_store('inventory')) == \
                    {"test": {"hostname": "test", "addr": "test", "labels": [], "status": ""}}
 
             with with_host(cephadm_module, 'second'):
@@ -234,10 +234,10 @@ class TestCephadm(object):
                     _ceph_send_command.side_effect = Exception("myerror")
 
                     # Make sure, _check_daemons does a redeploy due to monmap change:
-                    cephadm_module._store['_ceph_get/mon_map'] = {
+                    cephadm_module.mock_store_set('_ceph_get', 'mon_map', {
                         'modified': datetime.datetime.utcnow().strftime(CEPH_DATEFMT),
                         'fsid': 'foobar',
-                    }
+                    })
                     cephadm_module.notify('mon_map', None)
 
                     cephadm_module._check_daemons()
@@ -252,14 +252,14 @@ class TestCephadm(object):
             with with_service(cephadm_module, ServiceSpec(service_type='grafana'), CephadmOrchestrator.apply_grafana, 'test'):
 
                 # Make sure, _check_daemons does a redeploy due to monmap change:
-                cephadm_module._store['_ceph_get/mon_map'] = {
+                cephadm_module.mock_store_set('_ceph_get', 'mon_map', {
                     'modified': datetime.datetime.utcnow().strftime(CEPH_DATEFMT),
                     'fsid': 'foobar',
-                }
+                })
                 cephadm_module.notify('mon_map', None)
-                cephadm_module._store['_ceph_get/mgr_map'] = {
+                cephadm_module.mock_store_set('_ceph_get', 'mgr_map', {
                     'modules': ['dashboard']
-                }
+                })
 
                 with mock.patch("cephadm.module.CephadmOrchestrator.mon_command") as _mon_cmd:
 
@@ -745,10 +745,10 @@ class TestCephadm(object):
             assert not cephadm_module.cache.host_needs_new_etc_ceph_ceph_conf('test')
 
             # Make sure, _check_daemons does a redeploy due to monmap change:
-            cephadm_module._store['_ceph_get/mon_map'] = {
+            cephadm_module.mock_store_set('_ceph_get', 'mon_map', {
                 'modified': datetime.datetime.utcnow().strftime(CEPH_DATEFMT),
                 'fsid': 'foobar',
-            }
+            })
             cephadm_module.notify('mon_map', mock.MagicMock())
             assert cephadm_module.cache.host_needs_new_etc_ceph_ceph_conf('test')
             cephadm_module.cache.last_etc_ceph_ceph_conf = {}
index e3491cce937f5ae5ff8c77e62646d24e09964c3c..a34dbe9dc5a4ebf96e66b0a2cc5af9d1d23a7444 100644 (file)
@@ -1,7 +1,8 @@
 # type: ignore
 from __future__ import absolute_import
 
-
+import json
+import logging
 import os
 
 if 'UNITTEST' in os.environ:
@@ -27,30 +28,50 @@ if 'UNITTEST' in os.environ:
         * self.get(thing) comes from self._store['_ceph_get' + thing]
 
         """
-        def _ceph_get_store(self, k):
+
+        def mock_store_get(self, kind, key, default):
             if not hasattr(self, '_store'):
                 self._store = {}
-            return self._store.get(k, None)
+            return self._store.get(f'mock_store/{kind}/{key}', default)
 
-        def _ceph_set_store(self, k, v):
+        def mock_store_set(self, kind, key, value):
             if not hasattr(self, '_store'):
                 self._store = {}
-            if v is None:
+            k = f'mock_store/{kind}/{key}'
+            if value is None:
                 if k in self._store:
                     del self._store[k]
             else:
-                self._store[k] = v
+                self._store[k] = value
 
-        def _ceph_get_store_prefix(self, prefix):
+        def mock_store_preifx(self, kind, prefix):
             if not hasattr(self, '_store'):
                 self._store = {}
+            full_prefix = f'mock_store/{kind}/{prefix}'
+            kind_len = len(f'mock_store/{kind}/')
             return {
-                k: v for k, v in self._store.items()
-                if k.startswith(prefix)
+                k[kind_len:]: v for k, v in self._store.items()
+                if k.startswith(full_prefix)
             }
 
-        def _ceph_get_module_option(self, module, key, localized_prefix: None):
-            val =  self._ceph_get_store(f'{module}/{key}')
+        def _ceph_get_store(self, k):
+            return self.mock_store_get('store', k, None)
+
+        def _ceph_set_store(self, k, v):
+            self.mock_store_set('store', k, v)
+
+        def _ceph_get_store_prefix(self, prefix):
+            return self.mock_store_preifx('store', prefix)
+
+        def _ceph_get_module_option(self, module, key, localized_prefix= None):
+            try:
+                _, val, _ = self.check_mon_command({
+                    'prefix': 'config get',
+                    'who': 'mgr',
+                    'key': f'mgr/{module}/{key}'
+                })
+            except FileNotFoundError:
+                val = None
             mo = [o for o in self.MODULE_OPTIONS if o['name'] == key]
             if len(mo) == 1 and val is not None:
                 cls = {
@@ -63,15 +84,62 @@ if 'UNITTEST' in os.environ:
             return val
 
         def _ceph_set_module_option(self, module, key, val):
-            return self._ceph_set_store(f'{module}/{key}', val)
+            _, _, _ = self.check_mon_command({
+                'prefix': 'config set',
+                'who': 'mgr',
+                'name': f'mgr/{module}/{key}',
+                'value': val
+            })
+            return val
 
         def _ceph_get(self, data_name):
-            if not hasattr(self, '_store'):
-                self._store = {}
-            return self._store.get(f'_ceph_get/{data_name}', mock.MagicMock())
-
-        def _ceph_send_command(self, ev, *args):
-            ev.complete(0, '', '')
+            return self.mock_store_get('_ceph_get', data_name, mock.MagicMock())
+
+        def _ceph_send_command(self, res, svc_type, svc_id, command, tag):
+            cmd = json.loads(command)
+
+            # Mocking the config store is handy sometimes:
+            def config_get():
+                who = cmd['who'].split('.')
+                whos = ['global'] + ['.'.join(who[:i+1]) for i in range(len(who))]
+                for attepmt in reversed(whos):
+                    val = self.mock_store_get('config', f'{attepmt}/{cmd["key"]}', None)
+                    if val is not None:
+                        return val
+                return None
+
+            def config_set():
+                self.mock_store_set('config', f'{cmd["who"]}/{cmd["name"]}', cmd['value'])
+                return ''
+
+            def config_dump():
+                r = []
+                for prefix, value in self.mock_store_preifx('config', '').items():
+                    section, name = prefix.split('/', 1)
+                    r.append({
+                        'name': name,
+                        'section': section,
+                        'value': value
+                    })
+                return json.dumps(r)
+
+            outb = ''
+            if cmd['prefix'] == 'config get':
+                outb = config_get()
+            elif cmd['prefix'] == 'config set':
+                outb = config_set()
+            elif cmd['prefix'] == 'config dump':
+                outb = config_dump()
+
+            res.complete(0, outb, '')
+
+        @property
+        def _logger(self):
+            return logging.getLogger(__name__)
+
+        @_logger.setter
+        def _logger(self, _):
+            pass
 
         def __init__(self, *args):
             if not hasattr(self, '_store'):