]> git.proxmox.com Git - ceph.git/blame - ceph/src/pybind/mgr/tests/__init__.py
bump version to 15.2.6-pve1
[ceph.git] / ceph / src / pybind / mgr / tests / __init__.py
CommitLineData
9f95a23c
TL
1# type: ignore
2from __future__ import absolute_import
3
f6b5b4d7
TL
4import json
5import logging
9f95a23c
TL
6import os
7
8if 'UNITTEST' in os.environ:
9
10 # Mock ceph_module. Otherwise every module that is involved in a testcase and imports it will
11 # raise an ImportError
12
13 import sys
14
15 try:
16 from unittest import mock
17 except ImportError:
18 import mock
19
e306af50
TL
20 M_classes = set()
21
9f95a23c 22 class M(object):
f6b5b4d7
TL
23 """
24 Note that:
e306af50 25
f6b5b4d7
TL
26 * self.set_store() populates self._store
27 * self.set_module_option() populates self._store[module_name]
28 * self.get(thing) comes from self._store['_ceph_get' + thing]
29
30 """
31
32 def mock_store_get(self, kind, key, default):
33 if not hasattr(self, '_store'):
34 self._store = {}
35 return self._store.get(f'mock_store/{kind}/{key}', default)
36
37 def mock_store_set(self, kind, key, value):
38 if not hasattr(self, '_store'):
39 self._store = {}
40 k = f'mock_store/{kind}/{key}'
41 if value is None:
e306af50
TL
42 if k in self._store:
43 del self._store[k]
44 else:
f6b5b4d7 45 self._store[k] = value
e306af50 46
f6b5b4d7
TL
47 def mock_store_preifx(self, kind, prefix):
48 if not hasattr(self, '_store'):
49 self._store = {}
50 full_prefix = f'mock_store/{kind}/{prefix}'
51 kind_len = len(f'mock_store/{kind}/')
e306af50 52 return {
f6b5b4d7
TL
53 k[kind_len:]: v for k, v in self._store.items()
54 if k.startswith(full_prefix)
e306af50
TL
55 }
56
f6b5b4d7
TL
57 def _ceph_get_store(self, k):
58 return self.mock_store_get('store', k, None)
59
60 def _ceph_set_store(self, k, v):
61 self.mock_store_set('store', k, v)
62
63 def _ceph_get_store_prefix(self, prefix):
64 return self.mock_store_preifx('store', prefix)
65
66 def _ceph_get_module_option(self, module, key, localized_prefix= None):
67 try:
68 _, val, _ = self.check_mon_command({
69 'prefix': 'config get',
70 'who': 'mgr',
71 'key': f'mgr/{module}/{key}'
72 })
73 except FileNotFoundError:
74 val = None
75 mo = [o for o in self.MODULE_OPTIONS if o['name'] == key]
76 if len(mo) == 1 and val is not None:
77 cls = {
78 'str': str,
79 'secs': int,
80 'bool': lambda s: bool(s) and s != 'false' and s != 'False',
81 'int': int,
82 }[mo[0].get('type', 'str')]
83 return cls(val)
84 return val
e306af50
TL
85
86 def _ceph_set_module_option(self, module, key, val):
f6b5b4d7
TL
87 _, _, _ = self.check_mon_command({
88 'prefix': 'config set',
89 'who': 'mgr',
90 'name': f'mgr/{module}/{key}',
91 'value': val
92 })
93 return val
94
95 def _ceph_get(self, data_name):
96 return self.mock_store_get('_ceph_get', data_name, mock.MagicMock())
97
98 def _ceph_send_command(self, res, svc_type, svc_id, command, tag):
99 cmd = json.loads(command)
100
101 # Mocking the config store is handy sometimes:
102 def config_get():
103 who = cmd['who'].split('.')
104 whos = ['global'] + ['.'.join(who[:i+1]) for i in range(len(who))]
105 for attepmt in reversed(whos):
106 val = self.mock_store_get('config', f'{attepmt}/{cmd["key"]}', None)
107 if val is not None:
108 return val
109 return None
110
111 def config_set():
112 self.mock_store_set('config', f'{cmd["who"]}/{cmd["name"]}', cmd['value'])
113 return ''
114
115 def config_dump():
116 r = []
117 for prefix, value in self.mock_store_preifx('config', '').items():
118 section, name = prefix.split('/', 1)
119 r.append({
120 'name': name,
121 'section': section,
122 'value': value
123 })
124 return json.dumps(r)
125
126 outb = ''
127 if cmd['prefix'] == 'config get':
128 outb = config_get()
129 elif cmd['prefix'] == 'config set':
130 outb = config_set()
131 elif cmd['prefix'] == 'config dump':
132 outb = config_dump()
133 elif hasattr(self, '_mon_command_mock_' + cmd['prefix'].replace(' ', '_')):
134 a = getattr(self, '_mon_command_mock_' + cmd['prefix'].replace(' ', '_'))
135 outb = a(cmd)
136
137 res.complete(0, outb, '')
138
139 @property
140 def _logger(self):
141 return logging.getLogger(__name__)
142
143 @_logger.setter
144 def _logger(self, _):
145 pass
e306af50 146
9f95a23c 147 def __init__(self, *args):
f6b5b4d7
TL
148 if not hasattr(self, '_store'):
149 self._store = {}
150
e306af50
TL
151
152 if self.__class__.__name__ not in M_classes:
153 # call those only once.
154 self._register_commands('')
155 self._register_options('')
156 M_classes.add(self.__class__.__name__)
157
9f95a23c
TL
158 super(M, self).__init__()
159 self._ceph_get_version = mock.Mock()
9f95a23c 160 self._ceph_get_option = mock.MagicMock()
e306af50
TL
161 self._ceph_get_context = mock.MagicMock()
162 self._ceph_register_client = mock.MagicMock()
f6b5b4d7 163 self._ceph_set_health_checks = mock.MagicMock()
9f95a23c
TL
164 self._configure_logging = lambda *_: None
165 self._unconfigure_logging = mock.MagicMock()
166 self._ceph_log = mock.MagicMock()
9f95a23c
TL
167 self._ceph_dispatch_remote = lambda *_: None
168
169
170 cm = mock.Mock()
171 cm.BaseMgrModule = M
172 cm.BaseMgrStandbyModule = M
173 sys.modules['ceph_module'] = cm
e306af50
TL
174
175 def mock_ceph_modules():
176 class MockRadosError(Exception):
177 def __init__(self, message, errno=None):
178 super(MockRadosError, self).__init__(message)
179 self.errno = errno
180
181 def __str__(self):
182 msg = super(MockRadosError, self).__str__()
183 if self.errno is None:
184 return msg
185 return '[errno {0}] {1}'.format(self.errno, msg)
186
187
188 sys.modules.update({
f6b5b4d7 189 'rados': mock.MagicMock(Error=MockRadosError, OSError=MockRadosError),
e306af50
TL
190 'rbd': mock.Mock(),
191 'cephfs': mock.Mock(),
192 })