Updating the older hpssacli with the new ssacli command. This change continue to support hpssacli by falling back when ssacli is not available allowing the user to update the environment. Change-Id: Ia763eff898dff2836fd4f1bc1889ae6f44206261
551 lines
27 KiB
Python
551 lines
27 KiB
Python
# Copyright 2014 Hewlett-Packard Development Company, L.P.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
import mock
|
|
import testtools
|
|
|
|
from proliantutils import exception
|
|
from proliantutils.hpssa import manager
|
|
from proliantutils.hpssa import objects
|
|
from proliantutils.tests.hpssa import raid_constants
|
|
|
|
|
|
@mock.patch.object(objects.Server, '_get_all_details')
|
|
class ManagerTestCases(testtools.TestCase):
|
|
|
|
def _test_create_configuration_with_disk_input(self,
|
|
controller_exec_cmd_mock,
|
|
get_all_details_mock):
|
|
ld1 = {'size_gb': 50,
|
|
'raid_level': '1',
|
|
'controller': 'Smart Array P822 in Slot 2',
|
|
'physical_disks': ['5I:1:1',
|
|
'5I:1:2']}
|
|
ld2 = {'size_gb': 100,
|
|
'raid_level': '5',
|
|
'controller': 'Smart Array P822 in Slot 2',
|
|
'physical_disks': ['5I:1:3',
|
|
'5I:1:4',
|
|
'6I:1:5']}
|
|
|
|
raid_info = {'logical_disks': [ld1, ld2]}
|
|
|
|
current_config = manager.create_configuration(raid_info)
|
|
|
|
ld1_drives = '5I:1:1,5I:1:2'
|
|
ld2_drives = '5I:1:3,5I:1:4,6I:1:5'
|
|
controller_exec_cmd_mock.assert_any_call("create",
|
|
"type=logicaldrive",
|
|
"drives=%s" % ld2_drives,
|
|
"raid=5",
|
|
"size=%d" % (100*1024),
|
|
process_input='y')
|
|
# Verify that we created the 50GB disk the last.
|
|
controller_exec_cmd_mock.assert_called_with("create",
|
|
"type=logicaldrive",
|
|
"drives=%s" % ld1_drives,
|
|
"raid=1",
|
|
"size=%d" % (50*1024),
|
|
process_input='y')
|
|
|
|
ld1_ret = [x for x in current_config['logical_disks']
|
|
if x['raid_level'] == '1'][0]
|
|
ld2_ret = [x for x in current_config['logical_disks']
|
|
if x['raid_level'] == '5'][0]
|
|
|
|
self.assertIsNotNone(ld1_ret['root_device_hint']['wwn'])
|
|
self.assertIsNotNone(ld2_ret['root_device_hint']['wwn'])
|
|
self.assertIsNotNone(ld1_ret['volume_name'])
|
|
self.assertIsNotNone(ld2_ret['volume_name'])
|
|
|
|
# Assert physical disk info
|
|
pds_active = [x['id'] for x in current_config['physical_disks']
|
|
if x['status'] == 'active']
|
|
pds_ready = [x['id'] for x in current_config['physical_disks']
|
|
if x['status'] == 'ready']
|
|
pds_active_expected = ['5I:1:3', '5I:1:4', '6I:1:5',
|
|
'5I:1:1', '5I:1:2']
|
|
pds_ready_expected = ['6I:1:6', '6I:1:7']
|
|
self.assertEqual(sorted(pds_active_expected), sorted(pds_active))
|
|
self.assertEqual(sorted(pds_ready_expected), sorted(pds_ready))
|
|
|
|
@mock.patch.object(objects.Controller, 'execute_cmd')
|
|
def test_create_configuration_with_disk_input_create_succeeds(
|
|
self, controller_exec_cmd_mock, get_all_details_mock):
|
|
no_drives = raid_constants.HPSSA_NO_DRIVES
|
|
one_drive = raid_constants.HPSSA_ONE_DRIVE_100GB_RAID_5
|
|
two_drives = raid_constants.HPSSA_TWO_DRIVES_100GB_RAID5_50GB_RAID1
|
|
get_all_details_mock.side_effect = [no_drives, one_drive, two_drives]
|
|
self._test_create_configuration_with_disk_input(
|
|
controller_exec_cmd_mock, get_all_details_mock)
|
|
|
|
@mock.patch.object(objects.Controller, 'execute_cmd')
|
|
def test_create_configuration_with_disk_input_create_fails(
|
|
self, controller_exec_cmd_mock, get_all_details_mock):
|
|
no_drives = raid_constants.HPSSA_NO_DRIVES
|
|
one_drive = raid_constants.HPSSA_ONE_DRIVE_100GB_RAID_5
|
|
get_all_details_mock.side_effect = [no_drives, one_drive, one_drive]
|
|
ex = self.assertRaises(exception.HPSSAOperationError,
|
|
self._test_create_configuration_with_disk_input,
|
|
controller_exec_cmd_mock, get_all_details_mock)
|
|
self.assertIn("raid_level '1' and size 50 GB not found", str(ex))
|
|
|
|
def test_create_configuration_invalid_logical_disks(self,
|
|
get_all_details_mock):
|
|
|
|
drives = raid_constants.HPSSA_NO_DRIVES
|
|
get_all_details_mock.return_value = drives
|
|
raid_info = {}
|
|
self.assertRaises(exception.InvalidInputError,
|
|
manager.create_configuration,
|
|
raid_info)
|
|
|
|
raid_info = {'logical_disks': 'foo'}
|
|
self.assertRaises(exception.InvalidInputError,
|
|
manager.create_configuration,
|
|
raid_info)
|
|
|
|
no_drives = raid_constants.HPSSA_NO_DRIVES
|
|
get_all_details_mock.return_value = no_drives
|
|
raid_info = {'logical_disks': [
|
|
{'size_gb': 50,
|
|
'raid_level': '1',
|
|
'controller': 'Smart Array P822 in Slot 0',
|
|
'physical_disks': ["6I:1:5", "6I:1:6"]}]}
|
|
msg = ("Invalid Input: Unable to find controller named 'Smart Array "
|
|
"P822 in Slot 0'. The available controllers are "
|
|
"'Smart Array P822 in Slot 2'.")
|
|
ex = self.assertRaises(exception.InvalidInputError,
|
|
manager.create_configuration,
|
|
raid_info)
|
|
self.assertEqual(msg, str(ex))
|
|
|
|
@mock.patch.object(objects.Controller, 'execute_cmd')
|
|
def test_create_configuration_without_disk_input_succeeds(
|
|
self, controller_exec_cmd_mock, get_all_details_mock):
|
|
no_drives = raid_constants.HPSSA_NO_DRIVES
|
|
one_drive = raid_constants.HPSSA_ONE_DRIVE_100GB_RAID_5
|
|
two_drives = raid_constants.HPSSA_TWO_DRIVES_100GB_RAID5_50GB_RAID1
|
|
get_all_details_mock.side_effect = [no_drives, one_drive, two_drives]
|
|
raid_info = {'logical_disks': [{'size_gb': 50,
|
|
'raid_level': '1'},
|
|
{'size_gb': 100,
|
|
'raid_level': '5'}]}
|
|
current_config = manager.create_configuration(raid_info)
|
|
controller_exec_cmd_mock.assert_any_call("create",
|
|
"type=logicaldrive",
|
|
mock.ANY,
|
|
"raid=5",
|
|
"size=%d" % (100*1024),
|
|
process_input='y')
|
|
# Verify that we created the 50GB disk the last.
|
|
controller_exec_cmd_mock.assert_called_with("create",
|
|
"type=logicaldrive",
|
|
mock.ANY,
|
|
"raid=1",
|
|
"size=%d" % (50*1024),
|
|
process_input='y')
|
|
|
|
ld1_ret = [x for x in current_config['logical_disks']
|
|
if x['raid_level'] == '1'][0]
|
|
ld2_ret = [x for x in current_config['logical_disks']
|
|
if x['raid_level'] == '5'][0]
|
|
self.assertEqual('0x600508b1001cc42c',
|
|
ld2_ret['root_device_hint']['wwn'])
|
|
self.assertEqual('0x600508b1001ce1e1',
|
|
ld1_ret['root_device_hint']['wwn'])
|
|
|
|
@mock.patch.object(objects.Controller, 'execute_cmd')
|
|
def test_create_configuration_without_disk_input_fails_on_disk_type(
|
|
self, controller_exec_cmd_mock, get_all_details_mock):
|
|
no_drives = raid_constants.HPSSA_NO_DRIVES
|
|
one_drive = raid_constants.HPSSA_ONE_DRIVE_100GB_RAID_5
|
|
two_drives = raid_constants.HPSSA_TWO_DRIVES_100GB_RAID5_50GB_RAID1
|
|
get_all_details_mock.side_effect = [no_drives, one_drive, two_drives]
|
|
raid_info = {'logical_disks': [{'size_gb': 50,
|
|
'raid_level': '1',
|
|
'disk_type': 'ssd'},
|
|
{'size_gb': 100,
|
|
'raid_level': '5',
|
|
'disk_type': 'hdd'}]}
|
|
exc = self.assertRaises(exception.PhysicalDisksNotFoundError,
|
|
manager.create_configuration,
|
|
raid_info)
|
|
self.assertIn("of size 50 GB and raid level 1", str(exc))
|
|
|
|
def test_create_configuration_hba_enabled(self, get_all_details_mock):
|
|
drives = raid_constants.HPSSA_HBA_MODE
|
|
get_all_details_mock.return_value = drives
|
|
|
|
raid_info = {'logical_disks': 'foo'}
|
|
|
|
msg = ("An error was encountered while doing ssa configuration: None"
|
|
" of the available SSA controllers Smart Array P822 in "
|
|
"Slot 3 have RAID enabled")
|
|
ex = self.assertRaises(exception.HPSSAOperationError,
|
|
manager.create_configuration,
|
|
raid_info)
|
|
self.assertIn(msg, str(ex))
|
|
|
|
@mock.patch.object(objects.Controller, 'execute_cmd')
|
|
def test_create_configuration_share_physical_disks(
|
|
self, controller_exec_cmd_mock, get_all_details_mock):
|
|
no_drives = raid_constants.HPSSA_NO_DRIVES_3_PHYSICAL_DISKS
|
|
one_drive = raid_constants.ONE_DRIVE_RAID_1
|
|
two_drives = raid_constants.TWO_DRIVES_50GB_RAID1
|
|
get_all_details_mock.side_effect = [no_drives, one_drive, two_drives]
|
|
controller_exec_cmd_mock.side_effect = [
|
|
(None, None),
|
|
(raid_constants.DRIVE_2_RAID_1_OKAY_TO_SHARE, None),
|
|
(None, None)]
|
|
raid_info = {'logical_disks': [{'size_gb': 50,
|
|
'share_physical_disks': True,
|
|
'number_of_physical_disks': 2,
|
|
'raid_level': '0',
|
|
'disk_type': 'hdd'},
|
|
{'size_gb': 50,
|
|
'share_physical_disks': True,
|
|
'raid_level': '1',
|
|
'disk_type': 'hdd'}]}
|
|
raid_info = manager.create_configuration(raid_info)
|
|
ld1 = raid_info['logical_disks'][0]
|
|
ld2 = raid_info['logical_disks'][1]
|
|
self.assertEqual('Smart Array P822 in Slot 2', ld1['controller'])
|
|
self.assertEqual('Smart Array P822 in Slot 2', ld2['controller'])
|
|
self.assertEqual(sorted(['5I:1:1', '5I:1:2']),
|
|
sorted(ld1['physical_disks']))
|
|
self.assertEqual(sorted(['5I:1:1', '5I:1:2']),
|
|
sorted(ld2['physical_disks']))
|
|
controller_exec_cmd_mock.assert_any_call(
|
|
'create', 'type=logicaldrive', 'drives=5I:1:1,5I:1:2',
|
|
'raid=1', 'size=51200', process_input='y')
|
|
controller_exec_cmd_mock.assert_any_call(
|
|
'array', 'A', 'create', 'type=logicaldrive', 'raid=0', 'size=?',
|
|
dont_transform_to_hpssa_exception=True)
|
|
controller_exec_cmd_mock.assert_any_call(
|
|
'array', 'A', 'create', 'type=logicaldrive', 'raid=0',
|
|
'size=51200', process_input='y')
|
|
|
|
@mock.patch.object(objects.Controller, 'execute_cmd')
|
|
def test_create_configuration_share_nonshare_physical_disks(
|
|
self, controller_exec_cmd_mock, get_all_details_mock):
|
|
no_drives = raid_constants.HPSSA_NO_DRIVES_3_PHYSICAL_DISKS
|
|
one_drive = raid_constants.ONE_DRIVE_RAID_1
|
|
two_drives = raid_constants.TWO_DRIVES_50GB_RAID1
|
|
get_all_details_mock.side_effect = [no_drives, one_drive, two_drives]
|
|
controller_exec_cmd_mock.side_effect = [
|
|
(None, None),
|
|
(raid_constants.DRIVE_2_RAID_1_OKAY_TO_SHARE, None),
|
|
(None, None)]
|
|
raid_info = {'logical_disks': [{'size_gb': 50,
|
|
'raid_level': '1',
|
|
'disk_type': 'hdd'},
|
|
{'size_gb': 50,
|
|
'share_physical_disks': True,
|
|
'raid_level': '0',
|
|
'disk_type': 'hdd'}]}
|
|
raid_info = manager.create_configuration(raid_info)
|
|
ld1 = raid_info['logical_disks'][0]
|
|
ld2 = raid_info['logical_disks'][1]
|
|
self.assertEqual('Smart Array P822 in Slot 2', ld1['controller'])
|
|
self.assertEqual('Smart Array P822 in Slot 2', ld2['controller'])
|
|
self.assertEqual(sorted(['5I:1:1', '5I:1:2']),
|
|
sorted(ld1['physical_disks']))
|
|
self.assertEqual(sorted(['5I:1:1', '5I:1:2']),
|
|
sorted(ld2['physical_disks']))
|
|
controller_exec_cmd_mock.assert_any_call(
|
|
'create', 'type=logicaldrive', 'drives=5I:1:1,5I:1:2',
|
|
'raid=1', 'size=51200', process_input='y')
|
|
controller_exec_cmd_mock.assert_any_call(
|
|
'create', 'type=logicaldrive', 'drives=5I:1:3', 'raid=0',
|
|
'size=51200', process_input='y')
|
|
|
|
@mock.patch.object(objects.Controller, 'execute_cmd')
|
|
def test_create_configuration_max_as_size_gb(
|
|
self, controller_exec_cmd_mock, get_all_details_mock):
|
|
no_drives = raid_constants.NO_DRIVES_HPSSA_7_DISKS
|
|
one_drive = raid_constants.ONE_DRIVE_RAID_1_50_GB
|
|
two_drives = raid_constants.TWO_DRIVES_50GB_RAID1_MAXGB_RAID5
|
|
get_all_details_mock.side_effect = [no_drives, one_drive, two_drives]
|
|
raid_info = {'logical_disks': [{'size_gb': 50,
|
|
'raid_level': '1',
|
|
'disk_type': 'hdd'},
|
|
{'size_gb': 'MAX',
|
|
'raid_level': '5',
|
|
'disk_type': 'hdd'}]}
|
|
raid_info = manager.create_configuration(raid_info)
|
|
ld1 = raid_info['logical_disks'][0]
|
|
ld2 = raid_info['logical_disks'][1]
|
|
self.assertEqual('Smart Array P822 in Slot 3', ld1['controller'])
|
|
self.assertEqual('Smart Array P822 in Slot 3', ld2['controller'])
|
|
self.assertEqual(sorted(['5I:1:1', '5I:1:2']),
|
|
sorted(ld1['physical_disks']))
|
|
self.assertEqual(sorted(['5I:1:3', '5I:1:4', '6I:1:5']),
|
|
sorted(ld2['physical_disks']))
|
|
controller_exec_cmd_mock.assert_any_call(
|
|
'create', 'type=logicaldrive', 'drives=5I:1:1,5I:1:2',
|
|
'raid=1', 'size=51200', process_input='y')
|
|
controller_exec_cmd_mock.assert_any_call(
|
|
'create', 'type=logicaldrive', 'drives=5I:1:3,5I:1:4,6I:1:5',
|
|
'raid=5', process_input='y')
|
|
|
|
def test__sort_shared_logical_disks(self, get_all_details_mock):
|
|
logical_disk_sorted_expected = [
|
|
{'size_gb': 500, 'disk_type': 'hdd', 'raid_level': '1'},
|
|
{'share_physical_disks': True, 'size_gb': 450, 'disk_type': 'hdd',
|
|
'number_of_physical_disks': 6, 'raid_level': '0'},
|
|
{'share_physical_disks': True, 'size_gb': 200, 'disk_type': 'hdd',
|
|
'raid_level': '1+0'},
|
|
{'share_physical_disks': True, 'size_gb': 200, 'disk_type': 'hdd',
|
|
'raid_level': '0'},
|
|
{'share_physical_disks': True, 'size_gb': 100, 'disk_type': 'hdd',
|
|
'raid_level': '0'}]
|
|
logical_disks = [{'size_gb': 500,
|
|
'disk_type': 'hdd',
|
|
'raid_level': '1'},
|
|
{'share_physical_disks': True,
|
|
'size_gb': 450,
|
|
'disk_type': 'hdd',
|
|
'number_of_physical_disks': 6,
|
|
'raid_level': '0'},
|
|
{'share_physical_disks': True,
|
|
'size_gb': 200,
|
|
'disk_type': 'hdd',
|
|
'raid_level': '1+0'},
|
|
{'share_physical_disks': True,
|
|
'size_gb': 200,
|
|
'disk_type': 'hdd',
|
|
'raid_level': '0'},
|
|
{'share_physical_disks': True,
|
|
'size_gb': 100,
|
|
'disk_type': 'hdd',
|
|
'raid_level': '0'}]
|
|
logical_disks_sorted = manager._sort_shared_logical_disks(
|
|
logical_disks)
|
|
self.assertEqual(logical_disks_sorted, logical_disk_sorted_expected)
|
|
|
|
def test__sort_shared_logical_disks_raid10(self, get_all_details_mock):
|
|
logical_disk_sorted_expected = [
|
|
{'size_gb': 600, 'disk_type': 'hdd', 'raid_level': '1'},
|
|
{'share_physical_disks': False, 'size_gb': 400, 'disk_type': 'hdd',
|
|
'raid_level': '1+0'},
|
|
{'share_physical_disks': False, 'size_gb': 100, 'disk_type': 'hdd',
|
|
'raid_level': '5'},
|
|
{'share_physical_disks': True, 'size_gb': 550, 'disk_type': 'hdd',
|
|
'raid_level': '1'},
|
|
{'share_physical_disks': True, 'size_gb': 200, 'disk_type': 'hdd',
|
|
'raid_level': '1+0'},
|
|
{'share_physical_disks': True, 'size_gb': 450, 'disk_type': 'hdd',
|
|
'number_of_physical_disks': 5, 'raid_level': '0'},
|
|
{'share_physical_disks': True, 'size_gb': 300, 'disk_type': 'hdd',
|
|
'raid_level': '5'}]
|
|
logical_disks = [
|
|
{'size_gb': 600, 'disk_type': 'hdd', 'raid_level': '1'},
|
|
{'share_physical_disks': True, 'size_gb': 550, 'disk_type': 'hdd',
|
|
'raid_level': '1'},
|
|
{'share_physical_disks': True, 'size_gb': 450, 'disk_type': 'hdd',
|
|
'number_of_physical_disks': 5, 'raid_level': '0'},
|
|
{'share_physical_disks': False, 'size_gb': 400, 'disk_type': 'hdd',
|
|
'raid_level': '1+0'},
|
|
{'share_physical_disks': True, 'size_gb': 300, 'disk_type': 'hdd',
|
|
'raid_level': '5'},
|
|
{'share_physical_disks': True, 'size_gb': 200, 'disk_type': 'hdd',
|
|
'raid_level': '1+0'},
|
|
{'share_physical_disks': False, 'size_gb': 100, 'disk_type': 'hdd',
|
|
'raid_level': '5'}]
|
|
logical_disks_sorted = manager._sort_shared_logical_disks(
|
|
logical_disks)
|
|
self.assertEqual(logical_disks_sorted, logical_disk_sorted_expected)
|
|
|
|
@mock.patch.object(manager, 'get_configuration')
|
|
@mock.patch.object(objects.Controller, 'execute_cmd')
|
|
def test_delete_configuration(self, controller_exec_cmd_mock,
|
|
get_configuration_mock,
|
|
get_all_details_mock):
|
|
get_all_details_mock.return_value = raid_constants.HPSSA_ONE_DRIVE
|
|
get_configuration_mock.return_value = 'foo'
|
|
|
|
ret = manager.delete_configuration()
|
|
|
|
controller_exec_cmd_mock.assert_called_with(
|
|
"logicaldrive", "all", "delete", "forced")
|
|
get_configuration_mock.assert_called_once_with()
|
|
self.assertEqual('foo', ret)
|
|
|
|
@mock.patch.object(manager, 'get_configuration')
|
|
@mock.patch.object(objects.Controller, 'execute_cmd')
|
|
def test_delete_configuration_no_arrays(
|
|
self, controller_exec_cmd_mock,
|
|
get_configuration_mock, get_all_details_mock):
|
|
|
|
get_all_details_mock.return_value = raid_constants.HPSSA_NO_DRIVES
|
|
get_configuration_mock.return_value = 'foo'
|
|
|
|
ret = manager.delete_configuration()
|
|
|
|
self.assertFalse(controller_exec_cmd_mock.called)
|
|
get_configuration_mock.assert_called_once_with()
|
|
self.assertEqual('foo', ret)
|
|
|
|
@mock.patch.object(manager, 'get_configuration')
|
|
def test_delete_configuration_hba_enabled(self, get_configuration,
|
|
get_all_details_mock):
|
|
drives = raid_constants.HPSSA_HBA_MODE
|
|
get_all_details_mock.return_value = drives
|
|
|
|
msg = ("An error was encountered while doing ssa configuration: None"
|
|
" of the available SSA controllers Smart Array P822 in "
|
|
"Slot 3 have RAID enabled")
|
|
ex = self.assertRaises(exception.HPSSAOperationError,
|
|
manager.delete_configuration)
|
|
self.assertIn(msg, str(ex))
|
|
|
|
def test_get_configuration(self, get_all_details_mock):
|
|
|
|
get_all_details_mock.return_value = raid_constants.HPSSA_ONE_DRIVE
|
|
|
|
raid_info_returned = manager.get_configuration()
|
|
|
|
ld1_expected = {'size_gb': 557,
|
|
'raid_level': '1',
|
|
'controller': 'Smart Array P822 in Slot 2',
|
|
'physical_disks': ['5I:1:1',
|
|
'5I:1:2'],
|
|
'volume_name': '01F42227PDVTF0BRH5T0MOAB64',
|
|
'root_device_hint': {
|
|
'wwn': '0x600508b1001c321c'}}
|
|
|
|
# NOTE(rameshg87: Cannot directly compare because
|
|
# of 'physical_disks' key.
|
|
ld1_returned = raid_info_returned['logical_disks'][0]
|
|
self.assertEqual(ld1_expected['size_gb'],
|
|
ld1_returned['size_gb'])
|
|
self.assertEqual(ld1_expected['raid_level'],
|
|
ld1_returned['raid_level'])
|
|
self.assertEqual(ld1_expected['controller'],
|
|
ld1_returned['controller'])
|
|
self.assertEqual(ld1_expected['volume_name'],
|
|
ld1_returned['volume_name'])
|
|
self.assertEqual(ld1_expected['root_device_hint'],
|
|
ld1_returned['root_device_hint'])
|
|
self.assertEqual(sorted(ld1_expected['physical_disks']),
|
|
sorted(ld1_returned['physical_disks']))
|
|
|
|
# Assert physical disk info
|
|
pds_active = [x['id'] for x in raid_info_returned['physical_disks']
|
|
if x['status'] == 'active']
|
|
pds_ready = [x['id'] for x in raid_info_returned['physical_disks']
|
|
if x['status'] == 'ready']
|
|
pds_active_expected = ['5I:1:1', '5I:1:2']
|
|
pds_ready_expected = ['6I:1:6', '6I:1:7', '5I:1:3',
|
|
'5I:1:4', '6I:1:5']
|
|
self.assertEqual(sorted(pds_active_expected), sorted(pds_active))
|
|
self.assertEqual(sorted(pds_ready_expected), sorted(pds_ready))
|
|
|
|
def test__select_controllers_by_hba(self, get_all_details_mock):
|
|
get_all_details_mock.return_value = raid_constants.HPSSA_HBA_MODE
|
|
|
|
server = objects.Server()
|
|
select_controllers = lambda x: not x.properties.get('HBA Mode Enabled',
|
|
False)
|
|
|
|
msg = ("An error was encountered while doing ssa configuration: "
|
|
"None of the available SSA controllers Smart Array P822 "
|
|
"in Slot 3 have Raid enabled.")
|
|
ex = self.assertRaises(exception.HPSSAOperationError,
|
|
manager._select_controllers_by,
|
|
server, select_controllers, 'Raid enabled')
|
|
self.assertIn(msg, str(ex))
|
|
|
|
def test__select_controllers_by(self, get_all_details_mock):
|
|
get_all_details_mock.return_value = raid_constants.HPSSA_NO_DRIVES
|
|
|
|
server = objects.Server()
|
|
select_controllers = lambda x: not x.properties.get('HBA Mode Enabled',
|
|
False)
|
|
ctrl_expected = server.controllers
|
|
|
|
manager._select_controllers_by(server, select_controllers,
|
|
'Raid enabled')
|
|
self.assertEqual(ctrl_expected, server.controllers)
|
|
|
|
@mock.patch.object(objects.Controller, 'execute_cmd')
|
|
def test_erase_devices(self, controller_exec_cmd_mock,
|
|
get_all_details_mock):
|
|
erase_drive = raid_constants.SSA_ERASE_DRIVE
|
|
erase_complete = raid_constants.SSA_ERASE_COMPLETE
|
|
cmd_args = []
|
|
cmd_args.append("pd 1I:2:1")
|
|
cmd_args.extend(['modify', 'erase',
|
|
'erasepattern=overwrite',
|
|
'unrestricted=off',
|
|
'forced'])
|
|
expt_ret = {
|
|
'Smart Array P440 in Slot 2': {
|
|
'1I:2:1': 'Erase Complete. Reenable Before Using.'}}
|
|
get_all_details_mock.side_effect = [erase_drive, erase_complete,
|
|
erase_complete]
|
|
|
|
ret = manager.erase_devices()
|
|
self.assertTrue(controller_exec_cmd_mock.called)
|
|
controller_exec_cmd_mock.assert_any_call(*cmd_args)
|
|
self.assertEqual(expt_ret, ret)
|
|
|
|
@mock.patch.object(objects.Controller, 'execute_cmd')
|
|
def test_erase_devices_no_drives(self, controller_exec_cmd_mock,
|
|
get_all_details_mock):
|
|
erase_no_drives = raid_constants.SSA_ERASE_NOT_SUPPORTED
|
|
get_all_details_mock.side_effect = [erase_no_drives]
|
|
ex = self.assertRaises(exception.HPSSAOperationError,
|
|
manager.erase_devices)
|
|
expt_ret = ("None of the available SSA controllers Smart "
|
|
"Array P440 in Slot 2 have Sanitize Erase Supported.")
|
|
self.assertIn(expt_ret, str(ex))
|
|
|
|
@mock.patch.object(objects.Controller, 'execute_cmd')
|
|
def test_erase_devices_in_progress(self, controller_exec_cmd_mock,
|
|
get_all_details_mock):
|
|
erase_progress = raid_constants.SSA_ERASE_IN_PROGRESS
|
|
erase_complete = raid_constants.SSA_ERASE_COMPLETE
|
|
|
|
expt_ret = {
|
|
'Smart Array P440 in Slot 2': {
|
|
'1I:2:1': 'Erase Complete. Reenable Before Using.'}}
|
|
get_all_details_mock.side_effect = [erase_progress, erase_complete,
|
|
erase_complete]
|
|
|
|
ret = manager.erase_devices()
|
|
self.assertFalse(controller_exec_cmd_mock.called)
|
|
self.assertEqual(expt_ret, ret)
|
|
|
|
|
|
class RaidConfigValidationTestCases(testtools.TestCase):
|
|
|
|
def test_validate_fails_min_disks_number(self):
|
|
raid_config = {'logical_disks':
|
|
[{'size_gb': 100,
|
|
'raid_level': '5',
|
|
'number_of_physical_disks': 2}]}
|
|
msg = "RAID level 5 requires at least 3 disks"
|
|
self.assertRaisesRegex(exception.InvalidInputError, msg,
|
|
manager.validate, raid_config)
|
|
|
|
def test_validate_fails_min_physical_disks(self):
|
|
raid_config = {'logical_disks':
|
|
[{'size_gb': 100, 'raid_level': '5',
|
|
'physical_disks': ['foo']}]}
|
|
msg = "RAID level 5 requires at least 3 disks"
|
|
self.assertRaisesRegex(exception.InvalidInputError, msg,
|
|
manager.validate, raid_config)
|