cinder/cinder/tests/unit/test_nexenta_edge.py

186 lines
6.6 KiB
Python

#
# Copyright 2015 Nexenta Systems, Inc.
# All Rights Reserved.
#
# 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
from cinder import context
from cinder import exception
from cinder import test
from cinder.volume import configuration as conf
from cinder.volume.drivers.nexenta.nexentaedge import iscsi
NEDGE_URL = 'service/isc/iscsi'
NEDGE_BUCKET = 'c/t/bk'
NEDGE_SERVICE = 'isc'
NEDGE_BLOCKSIZE = 4096
NEDGE_CHUNKSIZE = 16384
MOCK_VOL = {
'id': 'vol1',
'name': 'vol1',
'size': 1
}
MOCK_VOL2 = {
'id': 'vol2',
'name': 'vol2',
'size': 1
}
MOCK_VOL3 = {
'id': 'vol3',
'name': 'vol3',
'size': 2
}
MOCK_SNAP = {
'id': 'snap1',
'name': 'snap1',
'volume_name': 'vol1'
}
NEW_VOL_SIZE = 2
ISCSI_TARGET_NAME = 'iscsi_target_name'
ISCSI_TARGET_STATUS = 'Target 1: ' + ISCSI_TARGET_NAME
class TestNexentaEdgeISCSIDriver(test.TestCase):
def setUp(self):
super(TestNexentaEdgeISCSIDriver, self).setUp()
self.cfg = mock.Mock(spec=conf.Configuration)
self.cfg.nexenta_client_address = '0.0.0.0'
self.cfg.nexenta_rest_address = '0.0.0.0'
self.cfg.nexenta_rest_port = 8080
self.cfg.nexenta_rest_protocol = 'http'
self.cfg.nexenta_iscsi_target_portal_port = 3260
self.cfg.nexenta_rest_user = 'admin'
self.cfg.nexenta_rest_password = 'admin'
self.cfg.nexenta_lun_container = NEDGE_BUCKET
self.cfg.nexenta_iscsi_service = NEDGE_SERVICE
self.cfg.nexenta_blocksize = NEDGE_BLOCKSIZE
self.cfg.nexenta_chunksize = NEDGE_CHUNKSIZE
mock_exec = mock.Mock()
mock_exec.return_value = ('', '')
self.driver = iscsi.NexentaEdgeISCSIDriver(execute=mock_exec,
configuration=self.cfg)
self.api_patcher = mock.patch('cinder.volume.drivers.nexenta.'
'nexentaedge.jsonrpc.'
'NexentaEdgeJSONProxy.__call__')
self.mock_api = self.api_patcher.start()
self.mock_api.return_value = {
'data': {'value': ISCSI_TARGET_STATUS}
}
self.driver.do_setup(context.get_admin_context())
self.addCleanup(self.api_patcher.stop)
def test_check_do_setup(self):
self.assertEqual(ISCSI_TARGET_NAME, self.driver.target_name)
def test_create_volume(self):
self.driver.create_volume(MOCK_VOL)
self.mock_api.assert_called_with(NEDGE_URL, {
'objectPath': NEDGE_BUCKET + '/' + MOCK_VOL['id'],
'volSizeMB': MOCK_VOL['size'] * 1024,
'blockSize': NEDGE_BLOCKSIZE,
'chunkSize': NEDGE_CHUNKSIZE
})
def test_create_volume_fail(self):
self.mock_api.side_effect = RuntimeError
self.assertRaises(RuntimeError, self.driver.create_volume, MOCK_VOL)
def test_delete_volume(self):
self.mock_api.side_effect = exception.VolumeBackendAPIException(
'No volume')
self.driver.delete_volume(MOCK_VOL)
self.mock_api.assert_called_with(NEDGE_URL, {
'objectPath': NEDGE_BUCKET + '/' + MOCK_VOL['id']
})
def test_delete_volume_fail(self):
self.mock_api.side_effect = RuntimeError
self.assertRaises(RuntimeError, self.driver.delete_volume, MOCK_VOL)
def test_extend_volume(self):
self.driver.extend_volume(MOCK_VOL, NEW_VOL_SIZE)
self.mock_api.assert_called_with(NEDGE_URL + '/resize', {
'objectPath': NEDGE_BUCKET + '/' + MOCK_VOL['id'],
'newSizeMB': NEW_VOL_SIZE * 1024
})
def test_extend_volume_fail(self):
self.mock_api.side_effect = RuntimeError
self.assertRaises(RuntimeError, self.driver.extend_volume,
MOCK_VOL, NEW_VOL_SIZE)
def test_create_snapshot(self):
self.driver.create_snapshot(MOCK_SNAP)
self.mock_api.assert_called_with(NEDGE_URL + '/snapshot', {
'objectPath': NEDGE_BUCKET + '/' + MOCK_VOL['id'],
'snapName': MOCK_SNAP['id']
})
def test_create_snapshot_fail(self):
self.mock_api.side_effect = RuntimeError
self.assertRaises(RuntimeError, self.driver.create_snapshot, MOCK_SNAP)
def test_delete_snapshot(self):
self.driver.delete_snapshot(MOCK_SNAP)
self.mock_api.assert_called_with(NEDGE_URL + '/snapshot', {
'objectPath': NEDGE_BUCKET + '/' + MOCK_VOL['id'],
'snapName': MOCK_SNAP['id']
})
def test_delete_snapshot_fail(self):
self.mock_api.side_effect = RuntimeError
self.assertRaises(RuntimeError, self.driver.delete_snapshot, MOCK_SNAP)
def test_create_volume_from_snapshot(self):
self.driver.create_volume_from_snapshot(MOCK_VOL2, MOCK_SNAP)
self.mock_api.assert_called_with(NEDGE_URL + '/snapshot/clone', {
'objectPath': NEDGE_BUCKET + '/' + MOCK_SNAP['volume_name'],
'clonePath': NEDGE_BUCKET + '/' + MOCK_VOL2['id'],
'snapName': MOCK_SNAP['id']
})
def test_create_volume_from_snapshot_fail(self):
self.mock_api.side_effect = RuntimeError
self.assertRaises(RuntimeError,
self.driver.create_volume_from_snapshot,
MOCK_VOL2, MOCK_SNAP)
def test_create_cloned_volume(self):
self.driver.create_cloned_volume(MOCK_VOL2, MOCK_VOL)
self.mock_api.assert_called_with(NEDGE_URL, {
'objectPath': NEDGE_BUCKET + '/' + MOCK_VOL2['id'],
'volSizeMB': MOCK_VOL2['size'] * 1024,
'blockSize': NEDGE_BLOCKSIZE,
'chunkSize': NEDGE_CHUNKSIZE
})
def test_create_cloned_volume_larger(self):
self.driver.create_cloned_volume(MOCK_VOL3, MOCK_VOL)
# ignore the clone call, this has been tested before
self.mock_api.assert_called_with(NEDGE_URL + '/resize', {
'objectPath': NEDGE_BUCKET + '/' + MOCK_VOL3['id'],
'newSizeMB': MOCK_VOL3['size'] * 1024
})
def test_create_cloned_volume_fail(self):
self.mock_api.side_effect = RuntimeError
self.assertRaises(RuntimeError, self.driver.create_cloned_volume,
MOCK_VOL2, MOCK_VOL)