Le Tian Ren 5e1c266859 Initial code base commit.
Change-Id: Id1e336028fa662ddee865841ac7b6c31a316f854
Closes-Bug: #1317383
2014-05-08 22:00:29 +08:00

460 lines
16 KiB
Python

COPYRIGHT = """
*************************************************************
Licensed Materials - Property of IBM
OCO Source Materials
(C) Copyright IBM Corp. 2013 All Rights Reserved
*************************************************************
"""
from cinderclient.tests.v1 import fakes
from cinderclient.tests.v1.test_volumes import VolumesTest
from cinderclient.tests.v1.test_types import TypesTest
from cinderclient.tests import utils
from cinderclient.v1.volumes import Volume
from cinderclient.v1.volume_types import VolumeType
from cinderclient.v1.volume_types import VolumeTypeManager
from powervc.common.client.extensions import cinder as ext_cinder
from powervc.common.client import delegate
from powervc.common import utils as commonutils
import mock
import sys
"""
This class similarly extend the current cinder client test cases
and also provided are examples of how someone can override and existing
method in the event we need to test something unique to powerVC.
The current methods that are overridden expect the same results as the base
class test cases and are only provided for example.
For specific PowerVC data model, just override the parent fake data
structure and corresponding testcase methods logic that could verify
the functions.
To run the testcases, alternatively:
1. Right click the TestCinderClient.py --> Run As --> Python unit-test
or
2. Refer to this link for detail UT running information:
https://jazz04.rchland.ibm.com:9443/jazz/service/ +
com.ibm.team.workitem.common.internal.rest.IAttachmentRestService/ +
itemName/com.ibm.team.workitem.Attachment/67843
All the testcases should be run successfully.
"""
class PVCFakeClient(fakes.FakeClient):
"""
This PVCFakeClient class extends the current cinder FakeClient,
and pvccinderclient.CinderClient.
aiming to set the self client variable to PVCFakeHTTPClient
"""
def __init__(self, *args, **kwargs):
fakes.FakeClient.__init__(self, *args, **kwargs)
self.client = PVCFakeHTTPClient(**kwargs)
sys.modules['powervc.common.client.factory'] = mock.MagicMock()
class PVCFakeHTTPClient(fakes.FakeHTTPClient):
"""
This PVCFakeHTTPClient class extends the current cinder FakeHTTPClient.
For all the HTTP requests in this class, it returns a fake json data
as specified beforehand instead of requesting to a real environment.
Ex, to test if json data from powerVC volume RESTAPI:
1. Add expected powerVC volumes json raw data into
get_volumes_detail() method
2. Add get_volumes_{volume_id} method to return the volume
3. Add post_volumes_{volume_id}_action to handle post logic
4. Add testcase and new added methods will be called
"""
def __init__(self, **kwargs):
fakes.FakeHTTPClient.__init__(self, **kwargs)
def get_volumes_pvcvolume(self, **kw):
r = {'volume': self.get_volumes_detail()[2]['volumes'][1]}
return (200, {}, r)
def get_volumes_detail(self, **kw):
"""
Override the parent method to a new powerVC specified volume,
Here is the same structure as OpenStack one for example.
"""
return (200, {}, {"volumes": [
{'id': 1234,
'name': 'sample-volume for cinder',
'attachments': [{'server_id': 12234}]},
{'id': 'pvcvolume',
'name': 'pvc sample-volume for cinder',
'attachments': [{'server_id': 54321}]}
]})
def post_volumes_pvcvolume_action(self, body, **kw):
"""
Add this method to handle powerVC volume post actions
Here is the same logic as OpenStack one for example.
"""
_body = None
resp = 202
assert len(list(body.keys())) == 1
action = list(body.keys())[0]
if action == 'os-attach':
assert sorted(list(body[action])) == ['instance_uuid',
'mode',
'mountpoint']
elif action == 'os-detach':
assert body[action] is None
elif action == 'os-reserve':
assert body[action] is None
elif action == 'os-unreserve':
assert body[action] is None
elif action == 'os-initialize_connection':
assert list(body[action].keys()) == ['connector']
return (202, {}, {'connection_info': 'foos'})
elif action == 'os-terminate_connection':
assert list(body[action].keys()) == ['connector']
elif action == 'os-begin_detaching':
assert body[action] is None
elif action == 'os-roll_detaching':
assert body[action] is None
elif action == 'os-reset_status':
assert 'status' in body[action]
else:
raise AssertionError("Unexpected action: %s" % action)
return (resp, {}, _body)
def get_storage_providers_2(self, **kw):
"""
To get a fake detail storage_providers
"""
return (200, {}, {"storage_provider":
{
"backend_type": "svc",
"volume_count": "null",
"service": {
"host_display_name": "shared_v7000_1",
"host": "shared_v7000_1",
"id": 4
},
"backend_id": "00000200A0204C30",
"health_status": {
"health_value": "OK"
},
"free_capacity_gb": 873.5,
"total_capacity_gb": 1115.5,
"storage_hostname": "shared_v7000_1",
"id": 2,
"backend_state": "running"
}})
def get_storage_providers_detail(self, **kw):
"""
To return a fake detail storage_providers
"""
return (200, {}, {"storage_providers": [
{
"backend_type": "svc",
"volume_count": "null",
"service": {
"host_display_name": "shared_v7000_1",
"host": "shared_v7000_1",
"id": 4
},
"backend_id": "00000200A0204C30",
"health_status": {
"health_value": "OK"
},
"free_capacity_gb": 873.5,
"total_capacity_gb": 1115.5,
"storage_hostname": "shared_v7000_1",
"id": 2,
"backend_state": "running"
},
{
"backend_type": "fc",
"volume_count": "null",
"service": {
"host_display_name": "shared_v7000_1",
"host": "shared_v7000_1",
"id": 4
},
"backend_id": "00000200A0204C31",
"health_status": {
"health_value": "OK"
},
"free_capacity_gb": 73.5,
"total_capacity_gb": 115.5,
"storage_hostname": "shared_v7000_2",
"id": 3,
"backend_state": "running"
}
]})
def get_types(self, **kw):
return (200, {}, {
"volume_types": [
{
"extra_specs": {
"drivers:storage_pool": "P-NGP01-pool",
"capabilities:volume_backend_name": "shared_v7000_1",
"drivers:rsize": "-1"
},
"name": "shared_v7000_1-default",
"id": "6627888e-9f59-4996-8c22-5d528c3273f0"
},
{
"extra_specs": {},
"name": "dm-crypt",
"id": "a3ae95f6-4aab-4446-b1d2-0fc2f60a89bb"
},
{
"extra_specs": {},
"name": "LUKS",
"id": "291f81a2-591b-4164-b2b2-829abc935573"
}
]
})
class PVCCinderVolumesTest(VolumesTest):
"""
This PVCCinderVolumesTest class extends the current cinder
VolumesTest class to provide volume related UT cases.
"""
volume_list = [
{
'id': 1234,
'name': 'sample-volume for cinder',
'attachments': [{'server_id': 12234}]},
{
'id': 'pvcvolume',
'name': 'pvc sample-volume for cinder',
'attachments': [{'server_id': 54321}]
}]
def setUp(self):
super(PVCCinderVolumesTest, self).setUp()
# get cinder client
cinder_fakeclient = PVCFakeClient('r', 'p')
# delegate to nova extension class
cinder_client = delegate.new_composite_deletgate(
[ext_cinder.Client(cinder_fakeclient), cinder_fakeclient])
self.cs = cinder_client
def tearDown(self):
super(PVCCinderVolumesTest, self).tearDown()
def test_pvcvolume_attach(self):
"""
Add this method to test if powerVC volume attach functions
Here is the same logic as OpenStack for example.
"""
v = self.cs.volumes.get('pvcvolume')
self.cs.volumes.attach(v, 1, '/dev/vdc')
self.cs.assert_called('POST',
'/volumes/pvcvolume/action')
def test_list_all_volumes(self):
resluts = self.cs.volumes.list_all_volumes()
self.cs.assert_called('GET', '/volumes/detail')
self.assertEqual(resluts[0].id, 1234)
self.assertEqual(resluts[1].name, 'pvc sample-volume for cinder')
def test_list_volumes_1(self):
returnvalues = [Volume(self, res, loaded=True)
for res in self.volume_list if res]
commonutils.get_utils().get_multi_scg_accessible_volumes = \
mock.MagicMock(return_value=returnvalues)
result = self.cs.volumes.list()
self.assertEquals(result[0].id, 1234)
self.assertEquals(result[1].name, "pvc sample-volume for cinder")
def test_list_volumes_2(self):
returnvalues = [Volume(self, res, loaded=True)
for res in self.volume_list if res]
commonutils.get_utils().get_scg_accessible_volumes = \
mock.MagicMock(return_value=returnvalues)
result = self.cs.volumes.list(True, None, 'SCGUUID', None)
self.assertEquals(result[0].name, "sample-volume for cinder")
class PVCCinderTypesTest(TypesTest):
"""
This PVCCinderTypesTest class extends the current cinder
TypesTest class to provide volume Type related UT cases.
"""
volumes_type_list = [
{
"extra_specs": {
"drivers:storage_pool": "P-NGP01-pool",
"capabilities:volume_backend_name": "shared_v7000_1",
"drivers:rsize": "-1"
},
"name": "shared_v7000_1-default",
"id": "6627888e-9f59-4996-8c22-5d528c3273f"
},
{
"extra_specs": {},
"name": "dm-crypt",
"id": "a3ae95f6-4aab-4446-b1d2-0fc2f60a89b"
},
{
"extra_specs": {},
"name": "LUKS",
"id": "291f81a2-591b-4164-b2b2-829abc93557"
}]
def setUp(self):
super(PVCCinderTypesTest, self).setUp()
# get cinder client
cinder_fakeclient = PVCFakeClient('r', 'p')
# delegate to nova extension class
cinder_client = delegate.new_composite_deletgate(
[ext_cinder.Client(cinder_fakeclient), cinder_fakeclient])
self.cs = cinder_client
def tearDown(self):
super(PVCCinderTypesTest, self).tearDown()
def test_list_all_storage_templates(self):
reslut = self.cs.volume_types.list_all_storage_templates()
self.assertEqual(reslut[0].name, "shared_v7000_1-default")
def test_list_storage_templates_1(self):
returnvalues = [VolumeType(VolumeTypeManager, res, loaded=True)
for res in self.volumes_type_list if res]
commonutils.get_utils().get_multi_scg_accessible_storage_templates = \
mock.MagicMock(return_value=returnvalues)
result = self.cs.volume_types.list()
self.assertEquals(result[0].id, "6627888e-9f59-4996-8c22-5d528c3273f")
self.assertEquals(result[1].name, "dm-crypt")
self.assertEquals(result[2].name, "LUKS")
def test_list_storage_templates_2(self):
data = self.volumes_type_list[2]
returnvalues = [VolumeType(VolumeTypeManager, res, loaded=True)
for res in [data] if res]
commonutils.get_utils().get_scg_accessible_storage_templates = \
mock.MagicMock(return_value=returnvalues)
result = self.cs.volume_types.list("SCGUUID", None)
self.assertEquals(result[0].name, "LUKS")
class PVCStorageProvidersTest(utils.TestCase):
"""
Class PVCStorageProvidersTest is used to provide
Storage Providers related UT cases.
"""
expected_sp = [
dict(
backend_type="svc",
volume_count="null",
service=dict(
host_display_name="shared_v7000_1",
host="shared_v7000_1",
id=4),
backend_id="00000200A0204C30",
health_status=dict(health_value="OK"),
free_capacity_gb=873.5,
total_capacity_gb=1115.5,
storage_hostname="shared_v7000_1",
id=2,
backend_state="running",
storage_type="fc")]
def setUp(self):
super(PVCStorageProvidersTest, self).setUp()
# get cinder client
cinder_fakeclient = PVCFakeClient('r', 'p')
# delegate to nova extension class
cinder_client = delegate.new_composite_deletgate(
[ext_cinder.Client(cinder_fakeclient), cinder_fakeclient])
self.cs = cinder_client
def tearDown(self):
super(PVCStorageProvidersTest, self).tearDown()
def compare_to_expected(self, expected, hyper):
for key, value in expected.items():
self.assertEqual(getattr(hyper, key), value)
def test_get_detail_SPs(self):
expected = [
dict(id=2,
backend_type="svc",
backend_id="00000200A0204C30",
free_capacity_gb=873.5,
total_capacity_gb=1115.5,
storage_hostname="shared_v7000_1",
backend_state="running"),
dict(id=3,
backend_type="fc",
backend_id="00000200A0204C31",
free_capacity_gb=73.5,
total_capacity_gb=115.5,
storage_hostname="shared_v7000_2",
backend_state="running")]
result = self.cs.storage_providers.list_all_providers()
self.cs.assert_called('GET', '/storage-providers/detail')
for idx, hyper in enumerate(result):
self.compare_to_expected(expected[idx], hyper)
def test_get_storage_provider(self):
expected = dict(id=2,
backend_type="svc",
backend_id="00000200A0204C30",
free_capacity_gb=873.5,
total_capacity_gb=1115.5,
storage_hostname="shared_v7000_1",
backend_state="running")
result = self.cs.storage_providers.get(2)
self.cs.assert_called('GET',
'/storage-providers/2')
self.compare_to_expected(expected, result)
def test_list_SP_1(self):
expected = self.expected_sp
returnvalue = [ext_cinder.StorageProvider(None, expected[0], True)]
commonutils.get_utils().get_scg_accessible_storage_providers = \
mock.MagicMock(return_value=returnvalue)
result = self.cs.storage_providers.list(True, None, "SCGUUID", None)
for idx, hyper in enumerate(result):
self.compare_to_expected(expected[idx], hyper)
def test_list_SP_2(self):
expected = self.expected_sp
returnvalue = [ext_cinder.StorageProvider(None, expected[0], True)]
commonutils.get_utils().get_multi_scg_accessible_storage_providers = \
mock.MagicMock(return_value=returnvalue)
result = self.cs.storage_providers.list()
for idx, hyper in enumerate(result):
self.compare_to_expected(expected[idx], hyper)