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, do_rm: 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, do_rm: 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')