]>
git.proxmox.com Git - ceph.git/blob - ceph/src/ceph-volume/ceph_volume/tests/util/test_prepare.py
d4ebd48c24b9a13f778830e1b5016a40f2368c6e
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_returns_true_when_id_is_destroyed(self
, monkeypatch
):
40 dict(id=0, status
="destroyed"),
42 stdout
= ['', json
.dumps(stdout
)]
43 monkeypatch
.setattr('ceph_volume.process.call', lambda *a
, **kw
: (stdout
, '', 0))
44 result
= prepare
.osd_id_available(0)
48 class TestFormatDevice(object):
50 def test_include_force(self
, fake_run
, monkeypatch
):
51 monkeypatch
.setattr(conf
, 'ceph', Factory(get_list
=lambda *a
, **kw
: []))
52 prepare
.format_device('/dev/sxx')
53 flags
= fake_run
.calls
[0]['args'][0]
56 def test_device_is_always_appended(self
, fake_run
, conf_ceph
):
57 conf_ceph(get_list
=lambda *a
, **kw
: [])
58 prepare
.format_device('/dev/sxx')
59 flags
= fake_run
.calls
[0]['args'][0]
60 assert flags
[-1] == '/dev/sxx'
62 def test_extra_flags_are_added(self
, fake_run
, conf_ceph
):
63 conf_ceph(get_list
=lambda *a
, **kw
: ['--why-yes'])
64 prepare
.format_device('/dev/sxx')
65 flags
= fake_run
.calls
[0]['args'][0]
66 assert '--why-yes' in flags
68 def test_default_options(self
, conf_ceph_stub
, fake_run
):
69 conf_ceph_stub(dedent("""[global]
70 fsid = 1234lkjh1234"""))
72 prepare
.format_device('/dev/sda1')
75 '-f', '-i', 'size=2048', # default flags
77 assert expected
== fake_run
.calls
[0]['args'][0]
79 def test_multiple_options_are_used(self
, conf_ceph_stub
, fake_run
):
80 conf_ceph_stub(dedent("""[global]
83 osd mkfs options xfs = -f -i size=1024"""))
85 prepare
.format_device('/dev/sda1')
88 '-f', '-i', 'size=1024',
90 assert expected
== fake_run
.calls
[0]['args'][0]
92 def test_multiple_options_will_get_the_force_flag(self
, conf_ceph_stub
, fake_run
):
93 conf_ceph_stub(dedent("""[global]
96 osd mkfs options xfs = -i size=1024"""))
98 prepare
.format_device('/dev/sda1')
101 '-f', '-i', 'size=1024',
103 assert expected
== fake_run
.calls
[0]['args'][0]
105 def test_underscore_options_are_used(self
, conf_ceph_stub
, fake_run
):
106 conf_ceph_stub(dedent("""[global]
109 osd_mkfs_options_xfs = -i size=128"""))
110 conf
.cluster
= 'ceph'
111 prepare
.format_device('/dev/sda1')
114 '-f', '-i', 'size=128',
116 assert expected
== fake_run
.calls
[0]['args'][0]
119 mkfs_filestore_flags
= [
122 '--osd-objectstore', 'filestore',
126 '--keyfile', '-', # goes through stdin
135 class TestOsdMkfsFilestore(object):
137 @pytest.mark
.parametrize('flag', mkfs_filestore_flags
)
138 def test_keyring_is_used(self
, fake_call
, monkeypatch
, flag
):
139 monkeypatch
.setattr(system
, 'chown', lambda path
: True)
140 prepare
.osd_mkfs_filestore(1, 'asdf', keyring
='secret')
141 assert flag
in fake_call
.calls
[0]['args'][0]
144 class TestOsdMkfsBluestore(object):
146 def test_keyring_is_added(self
, fake_call
, monkeypatch
):
147 monkeypatch
.setattr(system
, 'chown', lambda path
: True)
148 prepare
.osd_mkfs_bluestore(1, 'asdf', keyring
='secret')
149 assert '--keyfile' in fake_call
.calls
[0]['args'][0]
151 def test_keyring_is_not_added(self
, fake_call
, monkeypatch
):
152 monkeypatch
.setattr(system
, 'chown', lambda path
: True)
153 prepare
.osd_mkfs_bluestore(1, 'asdf')
154 assert '--keyfile' not in fake_call
.calls
[0]['args'][0]
156 def test_wal_is_added(self
, fake_call
, monkeypatch
):
157 monkeypatch
.setattr(system
, 'chown', lambda path
: True)
158 prepare
.osd_mkfs_bluestore(1, 'asdf', wal
='/dev/smm1')
159 assert '--bluestore-block-wal-path' in fake_call
.calls
[0]['args'][0]
160 assert '/dev/smm1' in fake_call
.calls
[0]['args'][0]
162 def test_db_is_added(self
, fake_call
, monkeypatch
):
163 monkeypatch
.setattr(system
, 'chown', lambda path
: True)
164 prepare
.osd_mkfs_bluestore(1, 'asdf', db
='/dev/smm2')
165 assert '--bluestore-block-db-path' in fake_call
.calls
[0]['args'][0]
166 assert '/dev/smm2' in fake_call
.calls
[0]['args'][0]
169 class TestMountOSD(object):
171 def test_default_options(self
, conf_ceph_stub
, fake_run
):
172 conf_ceph_stub(dedent("""[global]
173 fsid = 1234lkjh1234"""))
174 conf
.cluster
= 'ceph'
175 prepare
.mount_osd('/dev/sda1', 1)
177 'mount', '-t', 'xfs', '-o',
178 'rw,noatime,inode64', # default flags
179 '/dev/sda1', '/var/lib/ceph/osd/ceph-1']
180 assert expected
== fake_run
.calls
[0]['args'][0]
182 def test_mount_options_are_used(self
, conf_ceph_stub
, fake_run
):
183 conf_ceph_stub(dedent("""[global]
186 osd mount options xfs = rw"""))
187 conf
.cluster
= 'ceph'
188 prepare
.mount_osd('/dev/sda1', 1)
190 'mount', '-t', 'xfs', '-o',
192 '/dev/sda1', '/var/lib/ceph/osd/ceph-1']
193 assert expected
== fake_run
.calls
[0]['args'][0]
195 def test_multiple_whitespace_options_are_used(self
, conf_ceph_stub
, fake_run
):
196 conf_ceph_stub(dedent("""[global]
199 osd mount options xfs = rw auto exec"""))
200 conf
.cluster
= 'ceph'
201 prepare
.mount_osd('/dev/sda1', 1)
203 'mount', '-t', 'xfs', '-o',
205 '/dev/sda1', '/var/lib/ceph/osd/ceph-1']
206 assert expected
== fake_run
.calls
[0]['args'][0]
208 def test_multiple_comma_whitespace_options_are_used(self
, conf_ceph_stub
, fake_run
):
209 conf_ceph_stub(dedent("""[global]
212 osd mount options xfs = rw, auto, exec"""))
213 conf
.cluster
= 'ceph'
214 prepare
.mount_osd('/dev/sda1', 1)
216 'mount', '-t', 'xfs', '-o',
218 '/dev/sda1', '/var/lib/ceph/osd/ceph-1']
219 assert expected
== fake_run
.calls
[0]['args'][0]
221 def test_underscore_mount_options_are_used(self
, conf_ceph_stub
, fake_run
):
222 conf_ceph_stub(dedent("""[global]
225 osd mount options xfs = rw"""))
226 conf
.cluster
= 'ceph'
227 prepare
.mount_osd('/dev/sda1', 1)
229 'mount', '-t', 'xfs', '-o',
231 '/dev/sda1', '/var/lib/ceph/osd/ceph-1']
232 assert expected
== fake_run
.calls
[0]['args'][0]
235 ceph_conf_mount_values
= [
236 ['rw,', 'auto,' 'exec'],
237 ['rw', 'auto', 'exec'],
238 [' rw ', ' auto ', ' exec '],
239 ['rw,', 'auto,', 'exec,'],
240 [',rw ', ',auto ', ',exec,'],
241 [',rw,', ',auto,', ',exec,'],
244 string_mount_values
= [
257 class TestNormalizeFlags(object):
258 # a bit overkill since most of this is already tested in prepare.mount_osd
261 @pytest.mark
.parametrize("flags", ceph_conf_mount_values
)
262 def test_normalize_lists(self
, flags
):
263 result
= sorted(prepare
._normalize
_mount
_flags
(flags
).split(','))
264 assert ','.join(result
) == 'auto,exec,rw'
266 @pytest.mark
.parametrize("flags", string_mount_values
)
267 def test_normalize_strings(self
, flags
):
268 result
= sorted(prepare
._normalize
_mount
_flags
(flags
).split(','))
269 assert ','.join(result
) == 'auto,exec,rw'
271 @pytest.mark
.parametrize("flags", ceph_conf_mount_values
)
272 def test_normalize_extra_flags(self
, flags
):
273 result
= prepare
._normalize
_mount
_flags
(flags
, extras
=['discard'])
274 assert sorted(result
.split(',')) == ['auto', 'discard', 'exec', 'rw']
276 @pytest.mark
.parametrize("flags", ceph_conf_mount_values
)
277 def test_normalize_duplicate_extra_flags(self
, flags
):
278 result
= prepare
._normalize
_mount
_flags
(flags
, extras
=['rw', 'discard'])
279 assert sorted(result
.split(',')) == ['auto', 'discard', 'exec', 'rw']
281 @pytest.mark
.parametrize("flags", string_mount_values
)
282 def test_normalize_strings_flags(self
, flags
):
283 result
= sorted(prepare
._normalize
_mount
_flags
(flags
, extras
=['discard']).split(','))
284 assert ','.join(result
) == 'auto,discard,exec,rw'
286 @pytest.mark
.parametrize("flags", string_mount_values
)
287 def test_normalize_strings_duplicate_flags(self
, flags
):
288 result
= sorted(prepare
._normalize
_mount
_flags
(flags
, extras
=['discard','rw']).split(','))
289 assert ','.join(result
) == 'auto,discard,exec,rw'
292 class TestMkfsFilestore(object):
294 def test_non_zero_exit_status(self
, stub_call
, monkeypatch
):
295 conf
.cluster
= 'ceph'
296 monkeypatch
.setattr('ceph_volume.util.prepare.system.chown', lambda x
: True)
297 stub_call(([], [], 1))
298 with pytest
.raises(RuntimeError) as error
:
299 prepare
.osd_mkfs_filestore('1', 'asdf-1234', 'keyring')
300 assert "Command failed with exit code 1" in str(error
.value
)
302 def test_non_zero_exit_formats_command_correctly(self
, stub_call
, monkeypatch
):
303 conf
.cluster
= 'ceph'
304 monkeypatch
.setattr('ceph_volume.util.prepare.system.chown', lambda x
: True)
305 stub_call(([], [], 1))
306 with pytest
.raises(RuntimeError) as error
:
307 prepare
.osd_mkfs_filestore('1', 'asdf-1234', 'keyring')
308 expected
= ' '.join([
312 '--osd-objectstore', 'filestore', '--mkfs',
313 '-i', '1', '--monmap', '/var/lib/ceph/osd/ceph-1/activate.monmap',
314 '--keyfile', '-', '--osd-data', '/var/lib/ceph/osd/ceph-1/',
315 '--osd-journal', '/var/lib/ceph/osd/ceph-1/journal',
316 '--osd-uuid', 'asdf-1234',
317 '--setuser', 'ceph', '--setgroup', 'ceph'])
318 assert expected
in str(error
.value
)
321 class TestMkfsBluestore(object):
323 def test_non_zero_exit_status(self
, stub_call
, monkeypatch
):
324 conf
.cluster
= 'ceph'
325 monkeypatch
.setattr('ceph_volume.util.prepare.system.chown', lambda x
: True)
326 stub_call(([], [], 1))
327 with pytest
.raises(RuntimeError) as error
:
328 prepare
.osd_mkfs_bluestore('1', 'asdf-1234', keyring
='keyring')
329 assert "Command failed with exit code 1" in str(error
.value
)
331 def test_non_zero_exit_formats_command_correctly(self
, stub_call
, monkeypatch
):
332 conf
.cluster
= 'ceph'
333 monkeypatch
.setattr('ceph_volume.util.prepare.system.chown', lambda x
: True)
334 stub_call(([], [], 1))
335 with pytest
.raises(RuntimeError) as error
:
336 prepare
.osd_mkfs_bluestore('1', 'asdf-1234', keyring
='keyring')
337 expected
= ' '.join([
341 '--osd-objectstore', 'bluestore', '--mkfs',
342 '-i', '1', '--monmap', '/var/lib/ceph/osd/ceph-1/activate.monmap',
343 '--keyfile', '-', '--osd-data', '/var/lib/ceph/osd/ceph-1/',
344 '--osd-uuid', 'asdf-1234',
345 '--setuser', 'ceph', '--setgroup', 'ceph'])
346 assert expected
in str(error
.value
)
349 class TestGetJournalSize(object):
351 def test_undefined_size_fallbacks_formatted(self
, conf_ceph_stub
):
352 conf_ceph_stub(dedent("""
354 fsid = a25d19a6-7d57-4eda-b006-78e35d2c4d9f
356 result
= prepare
.get_journal_size()
357 assert result
== '5G'
359 def test_undefined_size_fallbacks_unformatted(self
, conf_ceph_stub
):
360 conf_ceph_stub(dedent("""
362 fsid = a25d19a6-7d57-4eda-b006-78e35d2c4d9f
364 result
= prepare
.get_journal_size(lv_format
=False)
365 assert result
.gb
.as_int() == 5
367 def test_defined_size_unformatted(self
, conf_ceph_stub
):
368 conf_ceph_stub(dedent("""
370 fsid = a25d19a6-7d57-4eda-b006-78e35d2c4d9f
373 osd journal size = 10240
375 result
= prepare
.get_journal_size(lv_format
=False)
376 assert result
.gb
.as_int() == 10
378 def test_defined_size_formatted(self
, conf_ceph_stub
):
379 conf_ceph_stub(dedent("""
381 fsid = a25d19a6-7d57-4eda-b006-78e35d2c4d9f
384 osd journal size = 10240
386 result
= prepare
.get_journal_size()
387 assert result
== '10G'
389 def test_refuse_tiny_journals(self
, conf_ceph_stub
):
390 conf_ceph_stub(dedent("""
392 fsid = a25d19a6-7d57-4eda-b006-78e35d2c4d9f
395 osd journal size = 1024
397 with pytest
.raises(RuntimeError) as error
:
398 prepare
.get_journal_size()
399 assert 'journal sizes must be larger' in str(error
.value
)
400 assert 'detected: 1024.00 MB' in str(error
.value
)