Add 'snapshot_support' attr to share details
Recently was introduced feature where snapshots become optional. Share started have new attr "snapshot_support". But it is absent in share payload and, hence, can not be used outside of Manila. Also, fix lost import of translation function for related snapshot API. Change-Id: Iddb0cf1e046b9d480a22e79b33c8674a2405362e Closes-Bug: #1491345 Closes-Bug: #1491346
This commit is contained in:
parent
6a00600ac0
commit
3ea5752570
@ -24,7 +24,7 @@ from manila.api import common
|
||||
from manila.api.openstack import wsgi
|
||||
from manila.api.views import share_snapshots as snapshot_views
|
||||
from manila import exception
|
||||
from manila.i18n import _LI
|
||||
from manila.i18n import _, _LI
|
||||
from manila import share
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
@ -212,10 +212,7 @@ class ShareController(wsgi.Controller):
|
||||
@wsgi.Controller.api_version("1.0", "2.3") # noqa
|
||||
def create(self, req, body): # pylint: disable=E0102
|
||||
# Remove consistency group attributes
|
||||
share = body.get('share', {})
|
||||
if 'consistency_group_id' in share:
|
||||
del body['share']['consistency_group_id']
|
||||
|
||||
body.get('share', {}).pop('consistency_group_id', None)
|
||||
share = self._create(req, body)
|
||||
return share
|
||||
|
||||
|
@ -21,6 +21,7 @@ class ViewBuilder(common.ViewBuilder):
|
||||
|
||||
_collection_name = 'shares'
|
||||
_detail_version_modifiers = [
|
||||
"add_snapshot_support_field",
|
||||
"add_consistency_group_fields",
|
||||
"add_task_state_field",
|
||||
"modify_share_type_field",
|
||||
@ -88,6 +89,10 @@ class ViewBuilder(common.ViewBuilder):
|
||||
share_dict['share_server_id'] = share.get('share_server_id')
|
||||
return {'share': share_dict}
|
||||
|
||||
@common.ViewBuilder.versioned_method("2.2")
|
||||
def add_snapshot_support_field(self, share_dict, share):
|
||||
share_dict['snapshot_support'] = share.get('snapshot_support')
|
||||
|
||||
@common.ViewBuilder.versioned_method("2.4")
|
||||
def add_consistency_group_fields(self, share_dict, share):
|
||||
share_dict['consistency_group_id'] = share.get(
|
||||
|
@ -16,6 +16,7 @@
|
||||
import copy
|
||||
import datetime
|
||||
|
||||
import ddt
|
||||
import mock
|
||||
from oslo_config import cfg
|
||||
import webob
|
||||
@ -46,6 +47,7 @@ def app():
|
||||
return mapper
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class ShareApiTest(test.TestCase):
|
||||
"""Share Api Test."""
|
||||
def setUp(self):
|
||||
@ -103,6 +105,7 @@ class ShareApiTest(test.TestCase):
|
||||
'status': 'fakestatus',
|
||||
'share_type': '1',
|
||||
'volume_type': '1',
|
||||
'snapshot_support': True,
|
||||
'is_public': False,
|
||||
'links': [
|
||||
{
|
||||
@ -127,25 +130,38 @@ class ShareApiTest(test.TestCase):
|
||||
share['share_server_id'] = 'fake_share_server_id'
|
||||
return {'share': share}
|
||||
|
||||
def test_share_create(self):
|
||||
@ddt.data("1.0", "2.0", "2.1")
|
||||
def test_share_create_original(self, microversion):
|
||||
self.mock_object(share_api.API, 'create', self.create_mock)
|
||||
|
||||
body = {"share": copy.deepcopy(self.share)}
|
||||
req = fakes.HTTPRequest.blank('/shares')
|
||||
req = fakes.HTTPRequest.blank('/shares', version=microversion)
|
||||
|
||||
res_dict = self.controller.create(req, body)
|
||||
|
||||
expected = self._get_expected_share_detailed_response(self.share)
|
||||
expected['share'].pop('snapshot_support')
|
||||
self.assertEqual(expected, res_dict)
|
||||
|
||||
@ddt.data("2.2", "2.3")
|
||||
def test_share_create_with_snapshot_support_without_cg(self, microversion):
|
||||
self.mock_object(share_api.API, 'create', self.create_mock)
|
||||
body = {"share": copy.deepcopy(self.share)}
|
||||
req = fakes.HTTPRequest.blank('/shares', version=microversion)
|
||||
|
||||
res_dict = self.controller.create(req, body)
|
||||
|
||||
expected = self._get_expected_share_detailed_response(self.share)
|
||||
self.assertEqual(expected, res_dict)
|
||||
|
||||
def test_share_create_with_consistency_group(self):
|
||||
@ddt.data("2.4", "2.5")
|
||||
def test_share_create_with_consistency_group(self, microversion):
|
||||
self.mock_object(share_api.API, 'create', self.create_mock)
|
||||
|
||||
body = {"share": copy.deepcopy(self.share)}
|
||||
req = fakes.HTTPRequest.blank('/shares', version="2.4")
|
||||
req = fakes.HTTPRequest.blank('/shares', version=microversion)
|
||||
|
||||
res_dict = self.controller.create(req, body)
|
||||
|
||||
expected = self._get_expected_share_detailed_response(self.share)
|
||||
|
||||
expected['share']['consistency_group_id'] = None
|
||||
expected['share']['source_cgsnapshot_member_id'] = None
|
||||
self.assertEqual(expected, res_dict)
|
||||
@ -161,6 +177,7 @@ class ShareApiTest(test.TestCase):
|
||||
res_dict = self.controller.create(req, body)
|
||||
|
||||
expected = self._get_expected_share_detailed_response(self.share)
|
||||
expected['share'].pop('snapshot_support')
|
||||
share_types.get_share_type_by_name.assert_called_once_with(
|
||||
utils.IsAMatcher(context.RequestContext), self.vt['name'])
|
||||
self.assertEqual(expected, res_dict)
|
||||
@ -202,6 +219,7 @@ class ShareApiTest(test.TestCase):
|
||||
res_dict = self.controller.create(req, body)
|
||||
|
||||
expected = self._get_expected_share_detailed_response(shr)
|
||||
expected['share'].pop('snapshot_support')
|
||||
self.assertEqual(expected, res_dict)
|
||||
self.assertEqual(create_mock.call_args[1]['share_network_id'],
|
||||
"fakenetid")
|
||||
@ -285,6 +303,7 @@ class ShareApiTest(test.TestCase):
|
||||
req = fakes.HTTPRequest.blank('/shares')
|
||||
res_dict = self.controller.create(req, body)
|
||||
expected = self._get_expected_share_detailed_response(shr)
|
||||
expected['share'].pop('snapshot_support')
|
||||
self.assertEqual(expected, res_dict)
|
||||
|
||||
def test_share_create_from_snapshot_without_share_net_parent_exists(self):
|
||||
@ -318,6 +337,7 @@ class ShareApiTest(test.TestCase):
|
||||
req = fakes.HTTPRequest.blank('/shares')
|
||||
res_dict = self.controller.create(req, body)
|
||||
expected = self._get_expected_share_detailed_response(shr)
|
||||
expected['share'].pop('snapshot_support')
|
||||
self.assertEqual(expected, res_dict)
|
||||
self.assertEqual(create_mock.call_args[1]['share_network_id'],
|
||||
parent_share_net)
|
||||
@ -353,6 +373,7 @@ class ShareApiTest(test.TestCase):
|
||||
req = fakes.HTTPRequest.blank('/shares')
|
||||
res_dict = self.controller.create(req, body)
|
||||
expected = self._get_expected_share_detailed_response(shr)
|
||||
expected['share'].pop('snapshot_support')
|
||||
self.assertEqual(res_dict, expected)
|
||||
self.assertEqual(create_mock.call_args[1]['share_network_id'],
|
||||
parent_share_net)
|
||||
@ -412,16 +433,21 @@ class ShareApiTest(test.TestCase):
|
||||
|
||||
def test_share_show(self):
|
||||
req = fakes.HTTPRequest.blank('/shares/1')
|
||||
res_dict = self.controller.show(req, '1')
|
||||
expected = self._get_expected_share_detailed_response()
|
||||
expected['share'].pop('snapshot_support')
|
||||
|
||||
res_dict = self.controller.show(req, '1')
|
||||
|
||||
self.assertEqual(expected, res_dict)
|
||||
|
||||
def test_share_show_with_consistency_group(self):
|
||||
req = fakes.HTTPRequest.blank('/shares/1', version='2.4')
|
||||
res_dict = self.controller.show(req, '1')
|
||||
expected = self._get_expected_share_detailed_response()
|
||||
expected['share']['consistency_group_id'] = None
|
||||
expected['share']['source_cgsnapshot_member_id'] = None
|
||||
|
||||
res_dict = self.controller.show(req, '1')
|
||||
|
||||
self.assertEqual(expected, res_dict)
|
||||
|
||||
def test_share_show_with_share_type_name(self):
|
||||
@ -435,8 +461,11 @@ class ShareApiTest(test.TestCase):
|
||||
|
||||
def test_share_show_admin(self):
|
||||
req = fakes.HTTPRequest.blank('/shares/1', use_admin_context=True)
|
||||
res_dict = self.controller.show(req, '1')
|
||||
expected = self._get_expected_share_detailed_response(admin=True)
|
||||
expected['share'].pop('snapshot_support')
|
||||
|
||||
res_dict = self.controller.show(req, '1')
|
||||
|
||||
self.assertEqual(expected, res_dict)
|
||||
|
||||
def test_share_show_no_share(self):
|
||||
@ -706,6 +735,7 @@ class ShareApiTest(test.TestCase):
|
||||
'host': 'fakehost',
|
||||
'id': '1',
|
||||
'snapshot_id': '2',
|
||||
'snapshot_support': True,
|
||||
'share_network_id': None,
|
||||
'created_at': datetime.datetime(1, 1, 1, 1, 1, 1),
|
||||
'size': 1,
|
||||
@ -738,6 +768,7 @@ class ShareApiTest(test.TestCase):
|
||||
env = {'QUERY_STRING': 'name=Share+Test+Name'}
|
||||
req = fakes.HTTPRequest.blank('/shares/detail', environ=env)
|
||||
expected = self._list_detail_common_expected()
|
||||
expected['shares'][0].pop('snapshot_support')
|
||||
self._list_detail_test_common(req, expected)
|
||||
|
||||
def test_share_list_detail_with_consistency_group(self):
|
||||
|
@ -288,7 +288,7 @@ class BaseSharesTest(test.BaseTestCase):
|
||||
share_network_id=None, share_type_id=None,
|
||||
consistency_group_id=None, client=None,
|
||||
cleanup_in_class=True, is_public=False, **kwargs):
|
||||
client = client or cls.shares_client
|
||||
client = client or cls.shares_v2_client
|
||||
description = description or "Tempest's share"
|
||||
share_network_id = share_network_id or client.share_network_id or None
|
||||
metadata = metadata or {}
|
||||
@ -358,7 +358,7 @@ class BaseSharesTest(test.BaseTestCase):
|
||||
"Expected only 'args' and 'kwargs' keys. "
|
||||
"Provided %s" % list(d))
|
||||
d["kwargs"]["client"] = d["kwargs"].get(
|
||||
"client", cls.shares_client)
|
||||
"client", cls.shares_v2_client)
|
||||
d["share"] = cls._create_share(*d["args"], **d["kwargs"])
|
||||
d["cnt"] = 0
|
||||
d["available"] = False
|
||||
|
@ -13,6 +13,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import six
|
||||
from tempest import config # noqa
|
||||
from tempest import test # noqa
|
||||
from tempest_lib import exceptions as lib_exc # noqa
|
||||
@ -35,17 +36,19 @@ class SharesNFSTest(base.BaseSharesTest):
|
||||
raise cls.skipException(message)
|
||||
cls.share = cls.create_share(cls.protocol)
|
||||
|
||||
@test.attr(type=["gate", ])
|
||||
def test_create_delete_share(self):
|
||||
def _create_delete_share(self, version):
|
||||
|
||||
# create share
|
||||
share = self.create_share(self.protocol)
|
||||
share = self.create_share(
|
||||
self.protocol, version=six.text_type(version))
|
||||
detailed_elements = {'name', 'id', 'availability_zone',
|
||||
'description', 'export_location', 'project_id',
|
||||
'host', 'created_at', 'share_proto', 'metadata',
|
||||
'size', 'snapshot_id', 'share_network_id',
|
||||
'status', 'share_type', 'volume_type', 'links',
|
||||
'is_public'}
|
||||
if version > 2.2:
|
||||
detailed_elements.add('snapshot_support')
|
||||
self.assertTrue(detailed_elements.issubset(share.keys()),
|
||||
'At least one expected element missing from share '
|
||||
'response. Expected %(expected)s, got %(actual)s.' % {
|
||||
@ -60,6 +63,14 @@ class SharesNFSTest(base.BaseSharesTest):
|
||||
self.shares_client.get_share,
|
||||
share['id'])
|
||||
|
||||
@test.attr(type=["gate", ])
|
||||
def test_create_delete_share_without_snapshot_support_feature(self):
|
||||
self._create_delete_share(2.1)
|
||||
|
||||
@test.attr(type=["gate", ])
|
||||
def test_create_delete_share_with_snapshot_support_feature(self):
|
||||
self._create_delete_share(2.2)
|
||||
|
||||
@test.attr(type=["gate", ])
|
||||
@testtools.skipUnless(CONF.share.run_snapshot_tests,
|
||||
"Snapshot tests are disabled.")
|
||||
|
@ -13,6 +13,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import six
|
||||
from tempest import config # noqa
|
||||
from tempest import test # noqa
|
||||
from tempest_lib.common.utils import data_utils # noqa
|
||||
@ -71,33 +72,44 @@ class SharesActionsTest(base.BaseSharesTest):
|
||||
snapshot_id=cls.snap['id'],
|
||||
))
|
||||
|
||||
@test.attr(type=["gate", ])
|
||||
def test_get_share(self):
|
||||
def _get_share(self, version):
|
||||
|
||||
# get share
|
||||
share = self.shares_client.get_share(self.shares[0]['id'])
|
||||
share = self.shares_v2_client.get_share(
|
||||
self.shares[0]['id'], version=six.text_type(version))
|
||||
|
||||
# verify keys
|
||||
expected_keys = ["status", "description", "links", "availability_zone",
|
||||
"created_at", "export_location", "share_proto",
|
||||
"name", "snapshot_id", "id", "size"]
|
||||
actual_keys = share.keys()
|
||||
if version > 2.1:
|
||||
expected_keys.append("snapshot_support")
|
||||
actual_keys = list(share.keys())
|
||||
[self.assertIn(key, actual_keys) for key in expected_keys]
|
||||
|
||||
# verify values
|
||||
msg = "Expected name: '%s', actual name: '%s'" % (self.share_name,
|
||||
share["name"])
|
||||
self.assertEqual(self.share_name, str(share["name"]), msg)
|
||||
self.assertEqual(self.share_name, six.text_type(share["name"]), msg)
|
||||
|
||||
msg = "Expected description: '%s', "\
|
||||
"actual description: '%s'" % (self.share_desc,
|
||||
share["description"])
|
||||
self.assertEqual(self.share_desc, str(share["description"]), msg)
|
||||
self.assertEqual(
|
||||
self.share_desc, six.text_type(share["description"]), msg)
|
||||
|
||||
msg = "Expected size: '%s', actual size: '%s'" % (self.share_size,
|
||||
share["size"])
|
||||
self.assertEqual(self.share_size, int(share["size"]), msg)
|
||||
|
||||
@test.attr(type=["gate", ])
|
||||
def test_get_share_no_snapshot_support_key(self):
|
||||
self._get_share(2.1)
|
||||
|
||||
@test.attr(type=["gate", ])
|
||||
def test_get_share_with_snapshot_support_key(self):
|
||||
self._get_share(2.2)
|
||||
|
||||
@test.attr(type=["gate", ])
|
||||
def test_list_shares(self):
|
||||
|
||||
@ -114,11 +126,11 @@ class SharesActionsTest(base.BaseSharesTest):
|
||||
msg = "expected id lists %s times in share list" % (len(gen))
|
||||
self.assertEqual(1, len(gen), msg)
|
||||
|
||||
@test.attr(type=["gate", ])
|
||||
def test_list_shares_with_detail(self):
|
||||
def _list_shares_with_detail(self, version):
|
||||
|
||||
# list shares
|
||||
shares = self.shares_client.list_shares_with_detail()
|
||||
shares = self.shares_v2_client.list_shares_with_detail(
|
||||
version=six.text_type(version))
|
||||
|
||||
# verify keys
|
||||
keys = [
|
||||
@ -126,6 +138,8 @@ class SharesActionsTest(base.BaseSharesTest):
|
||||
"created_at", "export_location", "share_proto", "host",
|
||||
"name", "snapshot_id", "id", "size", "project_id",
|
||||
]
|
||||
if version > 2.1:
|
||||
keys.append("snapshot_support")
|
||||
[self.assertIn(key, sh.keys()) for sh in shares for key in keys]
|
||||
|
||||
# our shares in list and have no duplicates
|
||||
@ -134,6 +148,14 @@ class SharesActionsTest(base.BaseSharesTest):
|
||||
msg = "expected id lists %s times in share list" % (len(gen))
|
||||
self.assertEqual(1, len(gen), msg)
|
||||
|
||||
@test.attr(type=["gate", ])
|
||||
def test_list_shares_with_detail_without_snapshot_support_key(self):
|
||||
self._list_shares_with_detail(2.1)
|
||||
|
||||
@test.attr(type=["gate", ])
|
||||
def test_list_shares_with_detail_and_snapshot_support_key(self):
|
||||
self._list_shares_with_detail(2.2)
|
||||
|
||||
@test.attr(type=["gate", ])
|
||||
def test_list_shares_with_detail_filter_by_metadata(self):
|
||||
filters = {'metadata': self.metadata}
|
||||
|
Loading…
x
Reference in New Issue
Block a user