3 # Copyright (C) 2015, 2016 Red Hat <contact@redhat.com>
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU Library Public License as published by
7 # the Free Software Foundation; either version 2, or (at your option)
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU Library Public License for more details.
15 from mock
import patch
, DEFAULT
23 from ceph_disk
import main
28 import __builtin__
as builtins
31 def fail_to_mount(dev
, fstype
, options
):
32 raise main
.MountError(dev
+ " mount fail")
35 class TestCephDisk(object):
37 def setup_class(self
):
38 main
.setup_logging(verbose
=True, log_stdout
=False)
40 def test_main_list_json(self
, capsys
):
41 if platform
.system() == "FreeBSD":
44 data
= tempfile
.mkdtemp()
45 main
.setup_statedir(data
)
46 args
= main
.parse_args(['list', '--format', 'json'])
49 list_devices
=lambda: {}):
51 out
, err
= capsys
.readouterr()
55 def test_main_list_plain(self
, capsys
):
56 if platform
.system() == "FreeBSD":
59 data
= tempfile
.mkdtemp()
60 main
.setup_statedir(data
)
61 args
= main
.parse_args(['list'])
64 list_devices
=lambda: {}):
66 out
, err
= capsys
.readouterr()
70 def test_list_format_more_osd_info_plain(self
):
75 'journal_dev': '/dev/Xda2',
77 out
= main
.list_format_more_osd_info_plain(dev
)
78 assert dev
['cluster'] in " ".join(out
)
79 assert dev
['journal_dev'] in " ".join(out
)
80 assert dev
['whoami'] in " ".join(out
)
85 'journal_dev': '/dev/Xda2',
87 out
= main
.list_format_more_osd_info_plain(dev
)
88 assert 'unknown cluster' in " ".join(out
)
90 def test_list_format_plain(self
):
95 'mount': '/somewhere',
97 out
= main
.list_format_plain(payload
)
98 assert payload
[0]['path'] in out
99 assert payload
[0]['type'] in out
100 assert payload
[0]['mount'] in out
107 out
= main
.list_format_plain(payload
)
108 assert payload
[0]['path'] in out
109 assert payload
[0]['type'] in out
117 'is_partition': True,
120 'mounted': '/somewhere',
125 out
= main
.list_format_plain(payload
)
126 assert payload
[0]['path'] in out
127 assert payload
[0]['partitions'][0]['path'] in out
129 def test_list_format_dev_plain(dev
):
135 'ptype': main
.PTYPE
['regular']['osd']['ready'],
139 out
= main
.list_format_dev_plain(dev
)
141 assert dev
['whoami'] in out
142 assert dev
['state'] in out
148 'ptype': main
.PTYPE
['regular']['journal']['ready'],
149 'journal_for': '/dev/Xda1',
151 out
= main
.list_format_dev_plain(dev
)
152 assert 'journal' in out
153 assert dev
['journal_for'] in out
159 main
.PTYPE
['plain']['osd']['ready']: 'plain',
160 main
.PTYPE
['luks']['osd']['ready']: 'luks',
162 for (ptype
, type) in ptype2type
.items():
163 for holders
in ((), ("dm_0",), ("dm_0", "dm_1")):
174 out
= main
.list_format_dev_plain(dev
)
176 assert 'dmcrypt' in out
178 if len(holders
) == 1:
179 assert dev
['whoami'] in out
180 for holder
in holders
:
187 main
.PTYPE
['plain']['journal']['ready']: 'plain',
188 main
.PTYPE
['luks']['journal']['ready']: 'luks',
190 for (ptype
, type) in ptype2type
.items():
191 for holders
in ((), ("dm_0",)):
195 'journal_for': '/dev/Xda1',
201 out
= main
.list_format_dev_plain(dev
)
202 assert 'journal' in out
203 assert 'dmcrypt' in out
205 assert dev
['journal_for'] in out
206 if len(holders
) == 1:
207 assert holders
[0] in out
209 def test_list_dev_osd(self
):
211 mount_path
= '/mount/path'
216 def more_osd_info(path
, uuid_map
, desc
):
217 desc
['cluster'] = cluster
219 # mounted therefore active
223 is_mounted
=lambda dev
: mount_path
,
224 get_dev_fs
=lambda dev
: fs_type
,
225 more_osd_info
=more_osd_info
228 main
.list_dev_osd(dev
, uuid_map
, desc
)
229 assert {'cluster': 'ceph',
231 'mount': '/mount/path',
232 'state': 'active'} == desc
234 # not mounted and cannot mount: unprepared
239 is_mounted
=lambda dev
: mount_path
,
240 get_dev_fs
=lambda dev
: fs_type
,
242 more_osd_info
=more_osd_info
245 main
.list_dev_osd(dev
, uuid_map
, desc
)
246 assert {'fs_type': 'ext4',
248 'state': 'unprepared'} == desc
250 # not mounted and magic found: prepared
253 def get_oneliner(path
, what
):
255 return main
.CEPH_OSD_ONDISK_MAGIC
257 raise Exception('unknown ' + what
)
260 is_mounted
=lambda dev
: mount_path
,
261 get_dev_fs
=lambda dev
: fs_type
,
264 get_oneliner
=get_oneliner
,
265 more_osd_info
=more_osd_info
268 main
.list_dev_osd(dev
, uuid_map
, desc
)
269 assert {'cluster': 'ceph',
272 'magic': main
.CEPH_OSD_ONDISK_MAGIC
,
273 'state': 'prepared'} == desc
275 def test_list_all_partitions(self
):
276 if platform
.system() == "FreeBSD":
284 listdir
=lambda path
: [disk
],
287 list_partitions
=lambda dev
: [partition
],
289 assert {disk
: [partition
]} == main
.list_all_partitions()
291 def test_list_data(self
):
293 # a data partition that fails to mount is silently
296 if platform
.system() == "FreeBSD":
299 partition_uuid
= "56244cf5-83ef-4984-888a-2d8b8e0e04b2"
304 def get_partition_type(dev
):
305 return main
.PTYPE
['regular']['osd']['ready']
308 list_all_partitions
=lambda: {disk
: [partition
]},
309 get_partition_uuid
=lambda dev
: partition_uuid
,
310 get_partition_type
=get_partition_type
,
311 get_dev_fs
=lambda dev
: fs_type
,
314 is_partition
=lambda dev
: True,
316 expect
= [{'path': '/dev/' + disk
,
320 'is_partition': True,
322 'path': '/dev/' + partition
,
323 'ptype': main
.PTYPE
['regular']['osd']['ready'],
324 'state': 'unprepared',
326 'uuid': partition_uuid
,
328 assert expect
== main
.list_devices()
330 def test_list_dmcrypt_data(self
):
331 if platform
.system() == "FreeBSD":
334 partition_type2type
= {
335 main
.PTYPE
['plain']['osd']['ready']: 'plain',
336 main
.PTYPE
['luks']['osd']['ready']: 'LUKS',
338 for (partition_type
, type) in partition_type2type
.items():
340 # dmcrypt data partition with one holder
342 partition_uuid
= "56244cf5-83ef-4984-888a-2d8b8e0e04b2"
345 holders
= ["dm-dummy"]
348 is_held
=lambda dev
: holders
,
349 list_all_partitions
=lambda: {disk
: [partition
]},
350 get_partition_uuid
=lambda dev
: partition_uuid
,
351 get_partition_type
=lambda dev
: partition_type
,
352 is_partition
=lambda dev
: True,
354 expect
= [{'path': '/dev/' + disk
,
361 'is_partition': True,
363 'path': '/dev/' + partition
,
364 'ptype': partition_type
,
365 'state': 'unprepared',
367 'uuid': partition_uuid
,
369 assert expect
== main
.list_devices()
371 # dmcrypt data partition with two holders
373 partition_uuid
= "56244cf5-83ef-4984-888a-2d8b8e0e04b2"
376 holders
= ["dm-dummy", "dm-dummy1"]
379 is_held
=lambda dev
: holders
,
380 list_all_partitions
=lambda: {disk
: [partition
]},
381 get_partition_uuid
=lambda dev
: partition_uuid
,
382 get_partition_type
=lambda dev
: partition_type
,
383 is_partition
=lambda dev
: True,
385 expect
= [{'path': '/dev/' + disk
,
391 'is_partition': True,
392 'path': '/dev/' + partition
,
393 'ptype': partition_type
,
395 'uuid': partition_uuid
,
397 assert expect
== main
.list_devices()
399 def test_list_multipath(self
):
401 # multipath data partition
403 if platform
.system() == "FreeBSD":
406 partition_uuid
= "56244cf5-83ef-4984-888a-2d8b8e0e04b2"
410 def get_partition_type(dev
):
411 return main
.PTYPE
['mpath']['osd']['ready']
414 list_all_partitions
=lambda: {disk
: [partition
]},
415 get_partition_uuid
=lambda dev
: partition_uuid
,
416 get_partition_type
=get_partition_type
,
417 is_partition
=lambda dev
: True,
419 expect
= [{'path': '/dev/' + disk
,
423 'is_partition': True,
426 'path': '/dev/' + partition
,
427 'ptype': main
.PTYPE
['mpath']['osd']['ready'],
428 'state': 'unprepared',
430 'uuid': partition_uuid
,
432 assert expect
== main
.list_devices()
434 # multipath journal partition
436 journal_partition_uuid
= "2cc40457-259e-4542-b029-785c7cc37871"
438 def get_partition_type(dev
):
439 return main
.PTYPE
['mpath']['journal']['ready']
442 list_all_partitions
=lambda: {disk
: [partition
]},
443 get_partition_uuid
=lambda dev
: journal_partition_uuid
,
444 get_partition_type
=get_partition_type
,
445 is_partition
=lambda dev
: True,
447 expect
= [{'path': '/dev/' + disk
,
450 'is_partition': True,
452 'path': '/dev/' + partition
,
453 'ptype': main
.PTYPE
['mpath']['journal']['ready'],
455 'uuid': journal_partition_uuid
,
457 assert expect
== main
.list_devices()
459 def test_list_default(self
):
460 self
.list(main
.PTYPE
['plain']['osd']['ready'],
461 main
.PTYPE
['plain']['journal']['ready'])
462 self
.list(main
.PTYPE
['luks']['osd']['ready'],
463 main
.PTYPE
['luks']['journal']['ready'])
464 self
.list(main
.PTYPE
['regular']['osd']['ready'],
465 main
.PTYPE
['regular']['journal']['ready'])
467 def test_list_bluestore(self
):
468 if platform
.system() == "FreeBSD":
471 self
.list(main
.PTYPE
['plain']['osd']['ready'],
472 main
.PTYPE
['plain']['block']['ready'])
473 self
.list(main
.PTYPE
['luks']['osd']['ready'],
474 main
.PTYPE
['luks']['block']['ready'])
475 self
.list(main
.PTYPE
['regular']['osd']['ready'],
476 main
.PTYPE
['regular']['block']['ready'])
478 def list(self
, data_ptype
, space_ptype
):
480 # a single disk has a data partition and a journal
481 # partition and the osd is active
483 name
= main
.Ptype
.space_ptype_to_name(space_ptype
)
484 data_uuid
= "56244cf5-83ef-4984-888a-2d8b8e0e04b2"
487 data_holder
= "dm-dummy"
489 space_holder
= "dm-dummy"
490 mount_path
= '/mount/path'
492 space_uuid
= "7ad5e65a-0ca5-40e4-a896-62a74ca61c55"
493 ceph_fsid
= "60a2ef70-d99b-4b9b-a83c-8a86e5e60091"
496 def get_oneliner(path
, what
):
498 if what
== name
+ '_uuid':
502 elif what
== 'ceph_fsid':
504 elif what
== 'whoami':
507 raise Exception('unknown ' + what
)
509 def get_partition_uuid(dev
):
510 if dev
== '/dev/' + data
:
512 elif dev
== '/dev/' + space
:
515 raise Exception('unknown ' + dev
)
517 def get_partition_type(dev
):
518 if (dev
== '/dev/' + data
or
519 dev
== '/dev/' + data_holder
):
521 elif (dev
== '/dev/' + space
or
522 dev
== '/dev/' + space_holder
):
525 raise Exception('unknown ' + dev
)
527 if data_ptype
== main
.PTYPE
['regular']['osd']['ready']:
529 elif data_ptype
== main
.PTYPE
['plain']['osd']['ready']:
532 'holders': [data_holder
],
534 elif data_ptype
== main
.PTYPE
['luks']['osd']['ready']:
537 'holders': [data_holder
],
540 raise Exception('unknown ' + data_ptype
)
542 if space_ptype
== main
.PTYPE
['regular'][name
]['ready']:
544 elif space_ptype
== main
.PTYPE
['plain'][name
]['ready']:
547 'holders': [space_holder
],
549 elif space_ptype
== main
.PTYPE
['luks'][name
]['ready']:
552 'holders': [space_holder
],
555 raise Exception('unknown ' + space_ptype
)
559 if dev
== '/dev/' + data
:
561 elif dev
== '/dev/' + space
:
562 return [space_holder
]
564 raise Exception('unknown ' + dev
)
571 list_all_partitions
=lambda: {disk
: [data
, space
]},
572 get_dev_fs
=lambda dev
: fs_type
,
573 is_mounted
=lambda dev
: mount_path
,
574 get_partition_uuid
=get_partition_uuid
,
575 get_partition_type
=get_partition_type
,
576 find_cluster_by_uuid
=lambda ceph_fsid
: cluster
,
577 is_partition
=lambda dev
: True,
580 get_oneliner
=get_oneliner
,
583 expect
= [{'path': '/dev/' + disk
,
585 'ceph_fsid': ceph_fsid
,
587 'dmcrypt': data_dmcrypt
,
589 'is_partition': True,
590 name
+ '_dev': '/dev/' + space
,
591 name
+ '_uuid': space_uuid
,
593 'path': '/dev/' + data
,
600 'dmcrypt': space_dmcrypt
,
601 'is_partition': True,
602 name
+ '_for': '/dev/' + data
,
603 'path': '/dev/' + space
,
604 'ptype': space_ptype
,
608 assert expect
== main
.list_devices()
610 def test_list_other(self
):
612 # not swap, unknown fs type, not mounted, with uuid
614 if platform
.system() == "FreeBSD":
617 partition_uuid
= "56244cf5-83ef-4984-888a-2d8b8e0e04b2"
618 partition_type
= "e51adfb9-e9fd-4718-9fc1-7a0cb03ea3f4"
623 list_all_partitions
=lambda: {disk
: [partition
]},
624 get_partition_uuid
=lambda dev
: partition_uuid
,
625 get_partition_type
=lambda dev
: partition_type
,
626 is_partition
=lambda dev
: True,
628 expect
= [{'path': '/dev/' + disk
,
629 'partitions': [{'dmcrypt': {},
630 'is_partition': True,
631 'path': '/dev/' + partition
,
632 'ptype': partition_type
,
634 'uuid': partition_uuid
}]}]
635 assert expect
== main
.list_devices()
637 # not swap, mounted, ext4 fs type, with uuid
639 partition_uuid
= "56244cf5-83ef-4984-888a-2d8b8e0e04b2"
640 partition_type
= "e51adfb9-e9fd-4718-9fc1-7a0cb03ea3f4"
643 mount_path
= '/mount/path'
647 list_all_partitions
=lambda: {disk
: [partition
]},
648 get_dev_fs
=lambda dev
: fs_type
,
649 is_mounted
=lambda dev
: mount_path
,
650 get_partition_uuid
=lambda dev
: partition_uuid
,
651 get_partition_type
=lambda dev
: partition_type
,
652 is_partition
=lambda dev
: True,
654 expect
= [{'path': '/dev/' + disk
,
657 'is_partition': True,
660 'path': '/dev/' + partition
,
661 'ptype': partition_type
,
663 'uuid': partition_uuid
,
665 assert expect
== main
.list_devices()
670 partition_uuid
= "56244cf5-83ef-4984-888a-2d8b8e0e04b2"
671 partition_type
= "e51adfb9-e9fd-4718-9fc1-7a0cb03ea3f4"
676 list_all_partitions
=lambda: {disk
: [partition
]},
677 is_swap
=lambda dev
: True,
678 get_partition_uuid
=lambda dev
: partition_uuid
,
679 get_partition_type
=lambda dev
: partition_type
,
680 is_partition
=lambda dev
: True,
682 expect
= [{'path': '/dev/' + disk
,
683 'partitions': [{'dmcrypt': {},
684 'is_partition': True,
685 'path': '/dev/' + partition
,
686 'ptype': partition_type
,
688 'uuid': partition_uuid
}]}]
689 assert expect
== main
.list_devices()
694 partition_uuid
= "56244cf5-83ef-4984-888a-2d8b8e0e04b2"
699 list_all_partitions
=lambda: {disk
: []},
700 is_partition
=lambda dev
: False,
702 expect
= [{'path': '/dev/' + disk
,
704 'is_partition': False,
707 assert expect
== main
.list_devices()
710 class TestCephDiskDeactivateAndDestroy(unittest
.TestCase
):
712 def setup_class(self
):
713 main
.setup_logging(verbose
=True, log_stdout
=False)
715 @patch('{0}.open'.format(builtins
.__name
__))
716 def test_main_deactivate(self
, mock_open
):
717 data
= tempfile
.mkdtemp()
718 main
.setup_statedir(data
)
719 DMCRYPT_LUKS_OSD_UUID
= '4fbd7e29-9d25-41b8-afd0-35865ceff05d'
720 part_uuid
= '0ce28a16-6d5d-11e5-aec3-fa163e5c167b'
723 # Can not find match device by osd-id
725 args
= main
.parse_args(['deactivate',
727 '--deactivate-by-id', '5566'])
728 fake_device
= [{'path': '/dev/' + disk
,
735 list_devices
=lambda: fake_device
,
737 self
.assertRaises(Exception, main
.main_deactivate
, args
)
740 # find match device by osd-id, status: OSD_STATUS_IN_DOWN
741 # with --mark-out option
743 args
= main
.parse_args(['deactivate',
745 '--deactivate-by-id', '5566',
747 fake_device
= [{'path': '/dev/' + disk
,
749 'ptype': DMCRYPT_LUKS_OSD_UUID
,
752 'mount': '/var/lib/ceph/osd/ceph-5566/',
757 list_devices
=lambda: fake_device
,
758 _check_osd_status
=lambda cluster
, osd_id
: 2,
759 _mark_osd_out
=lambda cluster
, osd_id
: True
761 main
.main_deactivate(args
)
764 # find match device by device partition, status: OSD_STATUS_IN_DOWN
766 args
= main
.parse_args(['deactivate',
769 fake_device
= [{'path': '/dev/' + disk
,
771 'ptype': DMCRYPT_LUKS_OSD_UUID
,
774 'mount': '/var/lib/ceph/osd/ceph-5566/',
779 list_devices
=lambda: fake_device
,
780 _check_osd_status
=lambda cluster
, osd_id
: 0,
782 main
.main_deactivate(args
)
785 # find match device by device partition, status: OSD_STATUS_IN_UP
786 # with --mark-out option
788 args
= main
.parse_args(['deactivate',
792 fake_device
= [{'path': '/dev/' + disk
,
794 'ptype': DMCRYPT_LUKS_OSD_UUID
,
797 'mount': '/var/lib/ceph/osd/ceph-5566/',
801 # mock the file open.
802 file_opened
= io
.StringIO()
803 file_opened
.write(u
'deactive')
804 mock_open
.return_value
= file_opened
809 list_devices
=lambda: fake_device
,
810 _check_osd_status
=lambda cluster
, osd_id
: 3,
811 _mark_osd_out
=lambda cluster
, osd_id
: True,
812 stop_daemon
=lambda cluster
, osd_id
: True,
813 _remove_osd_directory_files
=lambda path
, cluster
: True,
814 path_set_context
=lambda path
: True,
815 unmount
=lambda path
: True,
816 dmcrypt_unmap
=lambda part_uuid
: True,
818 main
.main_deactivate(args
)
821 # find match device by osd-id, status: OSD_STATUS_OUT_UP
823 args
= main
.parse_args(['deactivate',
825 '--deactivate-by-id', '5566'])
826 fake_device
= [{'path': '/dev/' + disk
,
828 'ptype': DMCRYPT_LUKS_OSD_UUID
,
831 'mount': '/var/lib/ceph/osd/ceph-5566/',
835 # mock the file open.
836 file_opened
= io
.StringIO()
837 file_opened
.write(u
'deactive')
838 mock_open
.return_value
= file_opened
843 list_devices
=lambda: fake_device
,
844 _check_osd_status
=lambda cluster
, osd_id
: 1,
845 _mark_osd_out
=lambda cluster
, osd_id
: True,
846 stop_daemon
=lambda cluster
, osd_id
: True,
847 _remove_osd_directory_files
=lambda path
, cluster
: True,
848 path_set_context
=lambda path
: True,
849 unmount
=lambda path
: True,
850 dmcrypt_unmap
=lambda part_uuid
: True,
852 main
.main_deactivate(args
)
855 def test_mark_out_out(self
):
856 def mark_osd_out_fail(osd_id
):
857 raise main
.Error('Could not find osd.%s, is a vaild/exist osd id?'
862 command
=mark_osd_out_fail
,
864 self
.assertRaises(Exception, main
._mark
_osd
_out
, 'ceph', '5566')
866 def test_check_osd_status(self
):
872 command
=raise_command_error
,
874 self
.assertRaises(Exception, main
._check
_osd
_status
,
881 fake_data
= ('{"osds":[{"osd":0,"up":1,"in":1},'
882 '{"osd":1,"up":1,"in":1}]}')
884 def return_fake_value(cmd
):
885 return fake_data
, '', 0
889 command
=return_fake_value
,
891 self
.assertRaises(Exception, main
._check
_osd
_status
,
898 fake_data
= ('{"osds":[{"osd":0,"up":1,"in":1},'
899 '{"osd":5566,"up":1,"in":1}]}')
901 def return_fake_value(cmd
):
902 return fake_data
, '', 0
906 command
=return_fake_value
,
908 main
._check
_osd
_status
('ceph', '5566')
910 def test_stop_daemon(self
):
911 STATEDIR
= '/var/lib/ceph'
915 def stop_daemon_fail(cmd
):
916 raise Exception('ceph osd stop failed')
921 with
patch('os.path.exists', return_value
=False):
922 self
.assertRaises(Exception, main
.stop_daemon
, 'ceph', '5566')
927 fake_path
= (STATEDIR
+ '/osd/{cluster}-{osd_id}/upstart').format(
928 cluster
=cluster
, osd_id
=osd_id
)
930 def path_exist(check_path
):
931 if check_path
== fake_path
:
936 patcher
= patch('os.path.exists')
937 check_path
= patcher
.start()
938 check_path
.side_effect
= path_exist
942 command_check_call
=stop_daemon_fail
,
944 self
.assertRaises(Exception, main
.stop_daemon
, 'ceph', '5566')
949 fake_path
= (STATEDIR
+ '/osd/{cluster}-{osd_id}/sysvinit').format(
950 cluster
=cluster
, osd_id
=osd_id
)
952 def path_exist(check_path
):
953 if check_path
== fake_path
:
958 patcher
= patch('os.path.exists')
959 check_path
= patcher
.start()
960 check_path
.side_effect
= path_exist
964 which
=lambda name
: True,
965 command_check_call
=stop_daemon_fail
,
967 self
.assertRaises(Exception, main
.stop_daemon
, 'ceph', '5566')
972 fake_path
= (STATEDIR
+ '/osd/{cluster}-{osd_id}/systemd').format(
973 cluster
=cluster
, osd_id
=osd_id
)
975 def path_exist(check_path
):
976 if check_path
== fake_path
:
981 def stop_daemon_fail(cmd
):
983 raise Exception('ceph osd stop failed')
987 patcher
= patch('os.path.exists')
988 check_path
= patcher
.start()
989 check_path
.side_effect
= path_exist
993 command_check_call
=stop_daemon_fail
,
995 self
.assertRaises(Exception, main
.stop_daemon
, 'ceph', '5566')
997 def test_remove_osd_directory_files(self
):
999 mounted_path
= 'somewhere'
1001 fake_path_remove_2
= None
1002 fake_path_remove_init
= None
1004 def handle_path_exist(check_path
):
1005 if check_path
== fake_path
:
1007 elif fake_path_2
and check_path
== fake_path_2
:
1012 def handle_path_remove(remove_path
):
1013 if remove_path
== fake_path_remove
:
1015 elif fake_path_remove_2
and remove_path
== fake_path_remove_2
:
1017 elif (fake_path_remove_init
and
1018 remove_path
== fake_path_remove_init
):
1024 # remove ready file failure
1026 fake_path
= os
.path
.join(mounted_path
, 'ready')
1027 fake_path_remove
= os
.path
.join(mounted_path
, 'no_ready')
1029 patcher_exist
= patch('os.path.exists')
1030 patcher_remove
= patch('os.remove')
1031 path_exist
= patcher_exist
.start()
1032 path_remove
= patcher_remove
.start()
1033 path_exist
.side_effect
= handle_path_exist
1034 path_remove
.side_effect
= handle_path_remove
1035 with patch
.multiple(
1039 get_conf
=lambda cluster
, **kwargs
: True,
1041 self
.assertRaises(Exception, main
._remove
_osd
_directory
_files
,
1042 'somewhere', cluster
)
1045 # remove active fil failure
1047 fake_path
= os
.path
.join(mounted_path
, 'ready')
1048 fake_path_2
= os
.path
.join(mounted_path
, 'active')
1049 fake_path_remove
= os
.path
.join(mounted_path
, 'ready')
1050 fake_path_remove_2
= os
.path
.join(mounted_path
, 'no_active')
1052 patcher_exist
= patch('os.path.exists')
1053 patcher_remove
= patch('os.remove')
1054 path_exist
= patcher_exist
.start()
1055 path_remove
= patcher_remove
.start()
1056 path_exist
.side_effect
= handle_path_exist
1057 path_remove
.side_effect
= handle_path_remove
1058 with patch
.multiple(
1062 get_conf
=lambda cluster
, **kwargs
: True,
1064 self
.assertRaises(Exception, main
._remove
_osd
_directory
_files
,
1065 'somewhere', cluster
)
1068 # conf_val is None and remove init file failure
1070 fake_path
= os
.path
.join(mounted_path
, 'ready')
1071 fake_path_2
= os
.path
.join(mounted_path
, 'active')
1072 fake_path_remove
= os
.path
.join(mounted_path
, 'ready')
1073 fake_path_remove_2
= os
.path
.join(mounted_path
, 'active')
1074 fake_path_remove_init
= os
.path
.join(mounted_path
, 'init_failure')
1076 patcher_exist
= patch('os.path.exists')
1077 patcher_remove
= patch('os.remove')
1078 path_exist
= patcher_exist
.start()
1079 path_remove
= patcher_remove
.start()
1080 path_exist
.side_effect
= handle_path_exist
1081 path_remove
.side_effect
= handle_path_remove
1082 with patch
.multiple(
1086 get_conf
=lambda cluster
, **kwargs
: None,
1087 init_get
=lambda: 'upstart',
1089 self
.assertRaises(Exception, main
._remove
_osd
_directory
_files
,
1090 'somewhere', cluster
)
1093 # already remove `ready`, `active` and remove init file successfully
1095 fake_path
= os
.path
.join(mounted_path
, 'no_ready')
1096 fake_path_2
= os
.path
.join(mounted_path
, 'no_active')
1097 fake_path_remove
= os
.path
.join(mounted_path
, 'upstart')
1099 patcher_exist
= patch('os.path.exists')
1100 patcher_remove
= patch('os.remove')
1101 path_exist
= patcher_exist
.start()
1102 path_remove
= patcher_remove
.start()
1103 path_exist
.side_effect
= handle_path_exist
1104 path_remove
.side_effect
= handle_path_remove
1105 with patch
.multiple(
1109 get_conf
=lambda cluster
, **kwargs
: 'upstart',
1111 main
._remove
_osd
_directory
_files
('somewhere', cluster
)
1113 def test_path_set_context(self
):
1115 with patch
.multiple(
1117 get_ceph_user
=lambda **kwargs
: 'ceph',
1119 main
.path_set_context(path
)
1121 def test_mount(self
):
1128 self
.assertRaises(Exception, main
.mount
, dev
, fs_type
, option
)
1136 self
.assertRaises(Exception, main
.mount
, dev
, fs_type
, option
)
1144 with
patch('tempfile.mkdtemp', return_value
='/mnt'):
1145 self
.assertRaises(Exception, main
.mount
, dev
, fstype
, options
)
1148 # mount successfully
1150 def create_temp_directory(*args
, **kwargs
):
1156 patcher
= patch('tempfile.mkdtemp')
1157 create_tmpdir
= patcher
.start()
1158 create_tmpdir
.side_effect
= create_temp_directory
1159 with patch
.multiple(
1162 command_check_call
=lambda cmd
: True,
1164 main
.mount(dev
, fstype
, options
)
1166 def test_umount(self
):
1171 self
.assertRaises(Exception, main
.unmount
, path
)
1174 # umount successfully
1176 def remove_directory_successfully(path
):
1180 patcher
= patch('os.rmdir')
1181 rm_directory
= patcher
.start()
1182 rm_directory
.side_effect
= remove_directory_successfully
1183 with patch
.multiple(
1186 command_check_call
=lambda cmd
: True,
1190 def test_main_destroy(self
):
1191 data
= tempfile
.mkdtemp()
1192 main
.setup_statedir(data
)
1193 OSD_UUID
= '4fbd7e29-9d25-41b8-afd0-062c0ceff05d'
1194 MPATH_OSD_UUID
= '4fbd7e29-8ae0-4982-bf9d-5a8d867af560'
1195 part_uuid
= '0ce28a16-6d5d-11e5-aec3-fa163e5c167b'
1196 journal_uuid
= "7ad5e65a-0ca5-40e4-a896-62a74ca61c55"
1197 mount_5566
= '/var/lib/ceph/osd/ceph-5566/'
1199 fake_devices_normal
= [{'path': '/dev/sdY',
1204 'path': '/dev/sdY1',
1206 'mount': mount_5566
,
1208 'journal_uuid': journal_uuid
}]},
1209 {'path': '/dev/sdX',
1213 'ptype': MPATH_OSD_UUID
,
1214 'path': '/dev/sdX1',
1216 'mount': '/var/lib/ceph/osd/ceph-7788/',
1218 'journal_uuid': journal_uuid
}]}]
1220 def list_devices_return():
1221 return fake_devices_normal
1224 # input device is not the device partition
1226 args
= main
.parse_args(['destroy', '--cluster', 'ceph', '/dev/sdX'])
1227 with patch
.multiple(
1229 is_partition
=lambda path
: False,
1231 self
.assertRaises(Exception, main
.main_destroy
, args
)
1234 # skip the redundent devices and not found by dev
1236 args
= main
.parse_args(['destroy', '--cluster', 'ceph', '/dev/sdZ1'])
1237 with patch
.multiple(
1239 is_partition
=lambda path
: True,
1240 list_devices
=list_devices_return
,
1242 self
.assertRaises(Exception, main
.main_destroy
, args
)
1245 # skip the redundent devices and not found by osd-id
1247 args
= main
.parse_args(['destroy', '--cluster', 'ceph',
1248 '--destroy-by-id', '1234'])
1249 with patch
.multiple(
1251 is_partition
=lambda path
: True,
1252 list_devices
=list_devices_return
,
1254 self
.assertRaises(Exception, main
.main_destroy
, args
)
1257 # skip the redundent devices and found by dev
1259 args
= main
.parse_args(['destroy', '--cluster',
1260 'ceph', '/dev/sdY1', '--zap'])
1261 with patch
.multiple(
1263 is_partition
=lambda path
: True,
1264 list_devices
=list_devices_return
,
1265 get_partition_base
=lambda dev_path
: '/dev/sdY',
1266 _check_osd_status
=lambda cluster
, osd_id
: 0,
1267 zap
=lambda dev
: True
1269 main
.main_destroy(args
)
1272 # skip the redundent devices and found by osd-id
1273 # with active status and MPATH_OSD
1275 args
= main
.parse_args(['destroy', '--cluster', 'ceph',
1276 '--destroy-by-id', '7788'])
1277 with patch
.multiple(
1279 is_partition
=lambda path
: True,
1280 list_devices
=list_devices_return
,
1281 get_partition_base_mpath
=lambda dev_path
: '/dev/sdX',
1282 _check_osd_status
=lambda cluster
, osd_id
: 1,
1284 self
.assertRaises(Exception, main
.main_destroy
, args
)
1287 def test_main_fix(self
):
1288 if platform
.system() == "FreeBSD":
1291 args
= main
.parse_args(['fix', '--all', '--selinux', '--permissions'])
1295 commands
.append(" ".join(x
))
1296 return ("", "", None)
1305 with patch
.multiple(
1308 command_init
=lambda x
: commands
.append(x
),
1309 command_wait
=lambda x
: None,
1313 commands
= " ".join(commands
)
1314 assert '/var/lib/ceph' in commands
1315 assert 'restorecon' in commands
1316 assert 'chown' in commands
1317 assert 'find' in commands
1320 def raise_command_error(*args
):
1321 e
= subprocess
.CalledProcessError('aaa', 'bbb', 'ccc')