]>
git.proxmox.com Git - ceph.git/blob - ceph/src/ceph-volume/ceph_volume/tests/util/test_prepare.py
2 from textwrap
import dedent
4 from ceph_volume
.util
import prepare
5 from ceph_volume
.util
.prepare
import system
6 from ceph_volume
import conf
7 from ceph_volume
.tests
.conftest
import Factory
10 class TestOSDIDAvailable(object):
12 def test_false_if_id_is_none(self
):
13 assert not prepare
.osd_id_available(None)
15 def test_returncode_is_not_zero(self
, monkeypatch
):
16 monkeypatch
.setattr('ceph_volume.process.call', lambda *a
, **kw
: ('', '', 1))
17 with pytest
.raises(RuntimeError):
18 prepare
.osd_id_available(1)
20 def test_id_does_exist_but_not_available(self
, monkeypatch
):
22 dict(id=0, status
="up"),
24 stdout
= ['', json
.dumps(stdout
)]
25 monkeypatch
.setattr('ceph_volume.process.call', lambda *a
, **kw
: (stdout
, '', 0))
26 result
= prepare
.osd_id_available(0)
29 def test_id_does_not_exist(self
, monkeypatch
):
33 stdout
= ['', json
.dumps(stdout
)]
34 monkeypatch
.setattr('ceph_volume.process.call', lambda *a
, **kw
: (stdout
, '', 0))
35 result
= prepare
.osd_id_available(1)
38 def test_invalid_osd_id(self
, monkeypatch
):
42 stdout
= ['', json
.dumps(stdout
)]
43 monkeypatch
.setattr('ceph_volume.process.call', lambda *a
, **kw
: (stdout
, '', 0))
44 result
= prepare
.osd_id_available("foo")
47 def test_returns_true_when_id_is_destroyed(self
, monkeypatch
):
49 dict(id=0, status
="destroyed"),
51 stdout
= ['', json
.dumps(stdout
)]
52 monkeypatch
.setattr('ceph_volume.process.call', lambda *a
, **kw
: (stdout
, '', 0))
53 result
= prepare
.osd_id_available(0)
57 class TestFormatDevice(object):
59 def test_include_force(self
, fake_run
, monkeypatch
):
60 monkeypatch
.setattr(conf
, 'ceph', Factory(get_list
=lambda *a
, **kw
: []))
61 prepare
.format_device('/dev/sxx')
62 flags
= fake_run
.calls
[0]['args'][0]
65 def test_device_is_always_appended(self
, fake_run
, conf_ceph
):
66 conf_ceph(get_list
=lambda *a
, **kw
: [])
67 prepare
.format_device('/dev/sxx')
68 flags
= fake_run
.calls
[0]['args'][0]
69 assert flags
[-1] == '/dev/sxx'
71 def test_extra_flags_are_added(self
, fake_run
, conf_ceph
):
72 conf_ceph(get_list
=lambda *a
, **kw
: ['--why-yes'])
73 prepare
.format_device('/dev/sxx')
74 flags
= fake_run
.calls
[0]['args'][0]
75 assert '--why-yes' in flags
77 def test_default_options(self
, conf_ceph_stub
, fake_run
):
78 conf_ceph_stub(dedent("""[global]
79 fsid = 1234lkjh1234"""))
81 prepare
.format_device('/dev/sda1')
84 '-f', '-i', 'size=2048', # default flags
86 assert expected
== fake_run
.calls
[0]['args'][0]
88 def test_multiple_options_are_used(self
, conf_ceph_stub
, fake_run
):
89 conf_ceph_stub(dedent("""[global]
92 osd mkfs options xfs = -f -i size=1024"""))
94 prepare
.format_device('/dev/sda1')
97 '-f', '-i', 'size=1024',
99 assert expected
== fake_run
.calls
[0]['args'][0]
101 def test_multiple_options_will_get_the_force_flag(self
, conf_ceph_stub
, fake_run
):
102 conf_ceph_stub(dedent("""[global]
105 osd mkfs options xfs = -i size=1024"""))
106 conf
.cluster
= 'ceph'
107 prepare
.format_device('/dev/sda1')
110 '-f', '-i', 'size=1024',
112 assert expected
== fake_run
.calls
[0]['args'][0]
114 def test_underscore_options_are_used(self
, conf_ceph_stub
, fake_run
):
115 conf_ceph_stub(dedent("""[global]
118 osd_mkfs_options_xfs = -i size=128"""))
119 conf
.cluster
= 'ceph'
120 prepare
.format_device('/dev/sda1')
123 '-f', '-i', 'size=128',
125 assert expected
== fake_run
.calls
[0]['args'][0]
128 mkfs_filestore_flags
= [
131 '--osd-objectstore', 'filestore',
135 '--keyfile', '-', # goes through stdin
144 class TestOsdMkfsFilestore(object):
146 @pytest.mark
.parametrize('flag', mkfs_filestore_flags
)
147 def test_keyring_is_used(self
, fake_call
, monkeypatch
, flag
):
148 monkeypatch
.setattr(prepare
, '__release__', 'mimic')
149 monkeypatch
.setattr(system
, 'chown', lambda path
: True)
150 prepare
.osd_mkfs_filestore(1, 'asdf', keyring
='secret')
151 assert flag
in fake_call
.calls
[0]['args'][0]
153 def test_keyring_is_used_luminous(self
, fake_call
, monkeypatch
):
154 monkeypatch
.setattr(prepare
, '__release__', 'luminous')
155 monkeypatch
.setattr(system
, 'chown', lambda path
: True)
156 prepare
.osd_mkfs_filestore(1, 'asdf', keyring
='secret')
157 assert '--keyfile' not in fake_call
.calls
[0]['args'][0]
160 class TestOsdMkfsBluestore(object):
162 def test_keyring_is_added(self
, fake_call
, monkeypatch
):
163 monkeypatch
.setattr(system
, 'chown', lambda path
: True)
164 prepare
.osd_mkfs_bluestore(1, 'asdf', keyring
='secret')
165 assert '--keyfile' in fake_call
.calls
[0]['args'][0]
167 def test_keyring_is_not_added(self
, fake_call
, monkeypatch
):
168 monkeypatch
.setattr(system
, 'chown', lambda path
: True)
169 prepare
.osd_mkfs_bluestore(1, 'asdf')
170 assert '--keyfile' not in fake_call
.calls
[0]['args'][0]
172 def test_keyring_is_not_added_luminous(self
, fake_call
, monkeypatch
):
173 monkeypatch
.setattr(system
, 'chown', lambda path
: True)
174 prepare
.osd_mkfs_bluestore(1, 'asdf')
175 monkeypatch
.setattr(prepare
, '__release__', 'luminous')
176 assert '--keyfile' not in fake_call
.calls
[0]['args'][0]
178 def test_wal_is_added(self
, fake_call
, monkeypatch
):
179 monkeypatch
.setattr(system
, 'chown', lambda path
: True)
180 prepare
.osd_mkfs_bluestore(1, 'asdf', wal
='/dev/smm1')
181 assert '--bluestore-block-wal-path' in fake_call
.calls
[0]['args'][0]
182 assert '/dev/smm1' in fake_call
.calls
[0]['args'][0]
184 def test_db_is_added(self
, fake_call
, monkeypatch
):
185 monkeypatch
.setattr(system
, 'chown', lambda path
: True)
186 prepare
.osd_mkfs_bluestore(1, 'asdf', db
='/dev/smm2')
187 assert '--bluestore-block-db-path' in fake_call
.calls
[0]['args'][0]
188 assert '/dev/smm2' in fake_call
.calls
[0]['args'][0]
191 class TestMountOSD(object):
193 def test_default_options(self
, conf_ceph_stub
, fake_run
):
194 conf_ceph_stub(dedent("""[global]
195 fsid = 1234lkjh1234"""))
196 conf
.cluster
= 'ceph'
197 prepare
.mount_osd('/dev/sda1', 1)
199 'mount', '-t', 'xfs', '-o',
200 'rw,noatime,inode64', # default flags
201 '/dev/sda1', '/var/lib/ceph/osd/ceph-1']
202 assert expected
== fake_run
.calls
[0]['args'][0]
204 def test_mount_options_are_used(self
, conf_ceph_stub
, fake_run
):
205 conf_ceph_stub(dedent("""[global]
208 osd mount options xfs = rw"""))
209 conf
.cluster
= 'ceph'
210 prepare
.mount_osd('/dev/sda1', 1)
212 'mount', '-t', 'xfs', '-o',
214 '/dev/sda1', '/var/lib/ceph/osd/ceph-1']
215 assert expected
== fake_run
.calls
[0]['args'][0]
217 def test_multiple_whitespace_options_are_used(self
, conf_ceph_stub
, fake_run
):
218 conf_ceph_stub(dedent("""[global]
221 osd mount options xfs = rw auto exec"""))
222 conf
.cluster
= 'ceph'
223 prepare
.mount_osd('/dev/sda1', 1)
225 'mount', '-t', 'xfs', '-o',
227 '/dev/sda1', '/var/lib/ceph/osd/ceph-1']
228 assert expected
== fake_run
.calls
[0]['args'][0]
230 def test_multiple_comma_whitespace_options_are_used(self
, conf_ceph_stub
, fake_run
):
231 conf_ceph_stub(dedent("""[global]
234 osd mount options xfs = rw, auto, exec"""))
235 conf
.cluster
= 'ceph'
236 prepare
.mount_osd('/dev/sda1', 1)
238 'mount', '-t', 'xfs', '-o',
240 '/dev/sda1', '/var/lib/ceph/osd/ceph-1']
241 assert expected
== fake_run
.calls
[0]['args'][0]
243 def test_underscore_mount_options_are_used(self
, conf_ceph_stub
, fake_run
):
244 conf_ceph_stub(dedent("""[global]
247 osd mount options xfs = rw"""))
248 conf
.cluster
= 'ceph'
249 prepare
.mount_osd('/dev/sda1', 1)
251 'mount', '-t', 'xfs', '-o',
253 '/dev/sda1', '/var/lib/ceph/osd/ceph-1']
254 assert expected
== fake_run
.calls
[0]['args'][0]
257 ceph_conf_mount_values
= [
258 ['rw,', 'auto,' 'exec'],
259 ['rw', 'auto', 'exec'],
260 [' rw ', ' auto ', ' exec '],
261 ['rw,', 'auto,', 'exec,'],
262 [',rw ', ',auto ', ',exec,'],
263 [',rw,', ',auto,', ',exec,'],
266 string_mount_values
= [
279 class TestNormalizeFlags(object):
280 # a bit overkill since most of this is already tested in prepare.mount_osd
283 @pytest.mark
.parametrize("flags", ceph_conf_mount_values
)
284 def test_normalize_lists(self
, flags
):
285 result
= sorted(prepare
._normalize
_mount
_flags
(flags
).split(','))
286 assert ','.join(result
) == 'auto,exec,rw'
288 @pytest.mark
.parametrize("flags", string_mount_values
)
289 def test_normalize_strings(self
, flags
):
290 result
= sorted(prepare
._normalize
_mount
_flags
(flags
).split(','))
291 assert ','.join(result
) == 'auto,exec,rw'
293 @pytest.mark
.parametrize("flags", ceph_conf_mount_values
)
294 def test_normalize_extra_flags(self
, flags
):
295 result
= prepare
._normalize
_mount
_flags
(flags
, extras
=['discard'])
296 assert sorted(result
.split(',')) == ['auto', 'discard', 'exec', 'rw']
298 @pytest.mark
.parametrize("flags", ceph_conf_mount_values
)
299 def test_normalize_duplicate_extra_flags(self
, flags
):
300 result
= prepare
._normalize
_mount
_flags
(flags
, extras
=['rw', 'discard'])
301 assert sorted(result
.split(',')) == ['auto', 'discard', 'exec', 'rw']
303 @pytest.mark
.parametrize("flags", string_mount_values
)
304 def test_normalize_strings_flags(self
, flags
):
305 result
= sorted(prepare
._normalize
_mount
_flags
(flags
, extras
=['discard']).split(','))
306 assert ','.join(result
) == 'auto,discard,exec,rw'
308 @pytest.mark
.parametrize("flags", string_mount_values
)
309 def test_normalize_strings_duplicate_flags(self
, flags
):
310 result
= sorted(prepare
._normalize
_mount
_flags
(flags
, extras
=['discard','rw']).split(','))
311 assert ','.join(result
) == 'auto,discard,exec,rw'
314 class TestMkfsBluestore(object):
316 def test_non_zero_exit_status(self
, stub_call
, monkeypatch
):
317 conf
.cluster
= 'ceph'
318 monkeypatch
.setattr('ceph_volume.util.prepare.system.chown', lambda x
: True)
319 stub_call(([], [], 1))
320 with pytest
.raises(RuntimeError) as error
:
321 prepare
.osd_mkfs_bluestore('1', 'asdf-1234', keyring
='keyring')
322 assert "Command failed with exit code 1" in str(error
)
324 def test_non_zero_exit_formats_command_correctly(self
, stub_call
, monkeypatch
):
325 conf
.cluster
= 'ceph'
326 monkeypatch
.setattr('ceph_volume.util.prepare.system.chown', lambda x
: True)
327 stub_call(([], [], 1))
328 with pytest
.raises(RuntimeError) as error
:
329 prepare
.osd_mkfs_bluestore('1', 'asdf-1234', keyring
='keyring')
330 expected
= ' '.join([
334 '--osd-objectstore', 'bluestore', '--mkfs',
335 '-i', '1', '--monmap', '/var/lib/ceph/osd/ceph-1/activate.monmap',
336 '--keyfile', '-', '--osd-data', '/var/lib/ceph/osd/ceph-1/',
337 '--osd-uuid', 'asdf-1234',
338 '--setuser', 'ceph', '--setgroup', 'ceph'])
339 assert expected
in str(error
)
342 class TestGetJournalSize(object):
344 def test_undefined_size_fallbacks_formatted(self
, conf_ceph_stub
):
345 conf_ceph_stub(dedent("""
347 fsid = a25d19a6-7d57-4eda-b006-78e35d2c4d9f
349 result
= prepare
.get_journal_size()
350 assert result
== '5G'
352 def test_undefined_size_fallbacks_unformatted(self
, conf_ceph_stub
):
353 conf_ceph_stub(dedent("""
355 fsid = a25d19a6-7d57-4eda-b006-78e35d2c4d9f
357 result
= prepare
.get_journal_size(lv_format
=False)
358 assert result
.gb
.as_int() == 5
360 def test_defined_size_unformatted(self
, conf_ceph_stub
):
361 conf_ceph_stub(dedent("""
363 fsid = a25d19a6-7d57-4eda-b006-78e35d2c4d9f
366 osd journal size = 10240
368 result
= prepare
.get_journal_size(lv_format
=False)
369 assert result
.gb
.as_int() == 10
371 def test_defined_size_formatted(self
, conf_ceph_stub
):
372 conf_ceph_stub(dedent("""
374 fsid = a25d19a6-7d57-4eda-b006-78e35d2c4d9f
377 osd journal size = 10240
379 result
= prepare
.get_journal_size()
380 assert result
== '10G'
382 def test_refuse_tiny_journals(self
, conf_ceph_stub
):
383 conf_ceph_stub(dedent("""
385 fsid = a25d19a6-7d57-4eda-b006-78e35d2c4d9f
388 osd journal size = 1024
390 with pytest
.raises(RuntimeError) as error
:
391 prepare
.get_journal_size()
392 assert 'journal sizes must be larger' in str(error
)
393 assert 'detected: 1024.00 MB' in str(error
)