67d49e188c
Change-Id: I9830704bf37920bcb56369b8d2be2f08c99a58fa
244 lines
10 KiB
Python
244 lines
10 KiB
Python
#
|
|
# 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 collections
|
|
import copy
|
|
|
|
import mock
|
|
import six
|
|
|
|
from heat.common import exception
|
|
from heat.common import template_format
|
|
from heat.engine import resource
|
|
from heat.engine.resources.openstack.manila import share as mshare
|
|
from heat.engine import rsrc_defn
|
|
from heat.engine import scheduler
|
|
from heat.tests import common
|
|
from heat.tests import utils
|
|
|
|
|
|
manila_template = """
|
|
heat_template_version: 2015-04-30
|
|
resources:
|
|
test_share:
|
|
type: OS::Manila::Share
|
|
properties:
|
|
share_protocol: NFS
|
|
size: 1
|
|
access_rules:
|
|
- access_to: 127.0.0.1
|
|
access_type: ip
|
|
access_level: ro
|
|
name: basic_test_share
|
|
description: basic test share
|
|
is_public: True
|
|
metadata: {"key": "value"}
|
|
"""
|
|
|
|
|
|
class DummyShare(object):
|
|
def __init__(self):
|
|
self.availability_zone = 'az'
|
|
self.host = 'host'
|
|
self.export_locations = 'el'
|
|
self.share_server_id = 'id'
|
|
self.created_at = 'ca'
|
|
self.status = 's'
|
|
self.project_id = 'p_id'
|
|
|
|
|
|
class ManilaShareTest(common.HeatTestCase):
|
|
|
|
def setUp(self):
|
|
super(ManilaShareTest, self).setUp()
|
|
utils.setup_dummy_db()
|
|
self.ctx = utils.dummy_context()
|
|
|
|
self.fake_share = mock.MagicMock(id="test_share_id")
|
|
self.available_share = mock.MagicMock(
|
|
id="test_share_id",
|
|
status=mshare.ManilaShare.STATUS_AVAILABLE)
|
|
self.failed_share = mock.MagicMock(
|
|
id="test_share_id",
|
|
status=mshare.ManilaShare.STATUS_ERROR)
|
|
self.deleting_share = mock.MagicMock(
|
|
id="test_share_id",
|
|
status=mshare.ManilaShare.STATUS_DELETING)
|
|
|
|
def _init_share(self, stack_name):
|
|
tmp = template_format.parse(manila_template)
|
|
self.stack = utils.parse_stack(tmp, stack_name=stack_name)
|
|
res_def = self.stack.t.resource_definitions(self.stack)["test_share"]
|
|
share = mshare.ManilaShare("test_share", res_def, self.stack)
|
|
|
|
# replace clients and plugins with mocks
|
|
mock_client = mock.MagicMock()
|
|
client = mock.MagicMock(return_value=mock_client)
|
|
share.client = client
|
|
mock_plugin = mock.MagicMock()
|
|
client_plugin = mock.MagicMock(return_value=mock_plugin)
|
|
share.client_plugin = client_plugin
|
|
|
|
return share
|
|
|
|
def _create_share(self, stack_name):
|
|
share = self._init_share(stack_name)
|
|
share.client().shares.create.return_value = self.fake_share
|
|
share.client().shares.get.return_value = self.available_share
|
|
scheduler.TaskRunner(share.create)()
|
|
return share
|
|
|
|
def test_share_create(self):
|
|
share = self._create_share("stack_share_create")
|
|
|
|
expected_state = (share.CREATE, share.COMPLETE)
|
|
self.assertEqual(expected_state, share.state,
|
|
"Share is not in expected state")
|
|
self.assertEqual(self.fake_share.id, share.resource_id,
|
|
"Expected share ID was not propagated to share")
|
|
|
|
share.client().shares.allow.assert_called_once_with(
|
|
access="127.0.0.1", access_level="ro",
|
|
share=share.resource_id, access_type="ip")
|
|
args, kwargs = share.client().shares.create.call_args
|
|
message_end = " parameter was not passed to manila client"
|
|
self.assertEqual(u"NFS", kwargs["share_proto"],
|
|
"Share protocol" + message_end)
|
|
self.assertEqual(1, kwargs["size"], "Share size" + message_end)
|
|
self.assertEqual("basic_test_share", kwargs["name"],
|
|
"Share name" + message_end)
|
|
self.assertEqual("basic test share", kwargs["description"],
|
|
"Share description" + message_end)
|
|
self.assertEqual({u"key": u"value"}, kwargs["metadata"],
|
|
"Metadata" + message_end)
|
|
self.assertTrue(kwargs["is_public"])
|
|
share.client().shares.get.assert_called_once_with(self.fake_share.id)
|
|
|
|
def test_share_create_fail(self):
|
|
share = self._init_share("stack_share_create_fail")
|
|
share.client().shares.get.return_value = self.failed_share
|
|
exc = self.assertRaises(resource.ResourceInError,
|
|
share.check_create_complete,
|
|
self.failed_share)
|
|
self.assertIn("Error during creation", six.text_type(exc))
|
|
|
|
def test_share_create_unknown_status(self):
|
|
share = self._init_share("stack_share_create_unknown")
|
|
share.client().shares.get.return_value = self.deleting_share
|
|
exc = self.assertRaises(resource.ResourceUnknownStatus,
|
|
share.check_create_complete,
|
|
self.deleting_share)
|
|
self.assertIn("Unknown status", six.text_type(exc))
|
|
|
|
def test_share_delete(self):
|
|
share = self._create_share("stack_share_delete")
|
|
share.client().shares.get.side_effect = exception.NotFound()
|
|
share.client_plugin().ignore_not_found.return_value = None
|
|
scheduler.TaskRunner(share.delete)()
|
|
share.client().shares.delete.assert_called_once_with(
|
|
self.fake_share.id)
|
|
|
|
def test_share_delete_fail(self):
|
|
share = self._create_share("stack_share_delete_fail")
|
|
share.client().shares.delete.return_value = None
|
|
share.client().shares.get.return_value = self.failed_share
|
|
exc = self.assertRaises(exception.ResourceFailure,
|
|
scheduler.TaskRunner(share.delete))
|
|
self.assertIn("Error during deleting share", six.text_type(exc))
|
|
|
|
def test_share_check(self):
|
|
share = self._create_share("stack_share_check")
|
|
scheduler.TaskRunner(share.check)()
|
|
expected_state = (share.CHECK, share.COMPLETE)
|
|
self.assertEqual(expected_state, share.state,
|
|
"Share is not in expected state")
|
|
|
|
def test_share_check_fail(self):
|
|
share = self._create_share("stack_share_check_fail")
|
|
share.client().shares.get.return_value = self.failed_share
|
|
exc = self.assertRaises(exception.ResourceFailure,
|
|
scheduler.TaskRunner(share.check))
|
|
self.assertIn("Error: resources.test_share: 'status': expected "
|
|
"'['available']'", six.text_type(exc))
|
|
|
|
def test_share_update(self):
|
|
share = self._create_share("stack_share_update")
|
|
updated_share_props = copy.deepcopy(share.properties.data)
|
|
updated_share_props[mshare.ManilaShare.DESCRIPTION] = "desc"
|
|
updated_share_props[mshare.ManilaShare.NAME] = "name"
|
|
updated_share_props[mshare.ManilaShare.IS_PUBLIC] = True
|
|
share.client().shares.update.return_value = None
|
|
after = rsrc_defn.ResourceDefinition(share.name, share.type(),
|
|
updated_share_props)
|
|
scheduler.TaskRunner(share.update, after)()
|
|
kwargs = {
|
|
"display_name": "name",
|
|
"display_description": "desc",
|
|
}
|
|
share.client().shares.update.assert_called_once_with(
|
|
share.resource_id, **kwargs)
|
|
|
|
def test_share_update_access_rules(self):
|
|
share = self._create_share("stack_share_update_access_rules")
|
|
updated_share_props = copy.deepcopy(share.properties.data)
|
|
updated_share_props[mshare.ManilaShare.ACCESS_RULES] = [
|
|
{mshare.ManilaShare.ACCESS_TO: "127.0.0.2",
|
|
mshare.ManilaShare.ACCESS_TYPE: "ip",
|
|
mshare.ManilaShare.ACCESS_LEVEL: "ro"}]
|
|
share.client().shares.deny.return_value = None
|
|
current_rule = {
|
|
mshare.ManilaShare.ACCESS_TO: "127.0.0.1",
|
|
mshare.ManilaShare.ACCESS_TYPE: "ip",
|
|
mshare.ManilaShare.ACCESS_LEVEL: "ro",
|
|
"id": "test_access_rule"
|
|
}
|
|
rule_tuple = collections.namedtuple("DummyRule",
|
|
list(current_rule.keys()))
|
|
share.client().shares.access_list.return_value = [
|
|
rule_tuple(**current_rule)]
|
|
after = rsrc_defn.ResourceDefinition(share.name, share.type(),
|
|
updated_share_props)
|
|
scheduler.TaskRunner(share.update, after)()
|
|
|
|
share.client().shares.access_list.assert_called_once_with(
|
|
share.resource_id)
|
|
share.client().shares.allow.assert_called_with(
|
|
share=share.resource_id, access_type="ip",
|
|
access="127.0.0.2", access_level="ro")
|
|
share.client().shares.deny.assert_called_once_with(
|
|
share=share.resource_id, id="test_access_rule")
|
|
|
|
def test_share_update_metadata(self):
|
|
share = self._create_share("stack_share_update_metadata")
|
|
updated_share_props = copy.deepcopy(share.properties.data)
|
|
updated_share_props[mshare.ManilaShare.METADATA] = {
|
|
"fake_key": "fake_value"}
|
|
share.client().shares.update_all_metadata.return_value = None
|
|
|
|
after = rsrc_defn.ResourceDefinition(share.name, share.type(),
|
|
updated_share_props)
|
|
scheduler.TaskRunner(share.update, after)()
|
|
share.client().shares.update_all_metadata.assert_called_once_with(
|
|
share.resource_id,
|
|
updated_share_props[mshare.ManilaShare.METADATA])
|
|
|
|
def test_attributes(self):
|
|
share = self._create_share("share")
|
|
share.client().shares.get.return_value = DummyShare()
|
|
self.assertEqual('az', share.FnGetAtt('availability_zone'))
|
|
self.assertEqual('host', share.FnGetAtt('host'))
|
|
self.assertEqual('el', share.FnGetAtt('export_locations'))
|
|
self.assertEqual('id', share.FnGetAtt('share_server_id'))
|
|
self.assertEqual('ca', share.FnGetAtt('created_at'))
|
|
self.assertEqual('s', share.FnGetAtt('status'))
|
|
self.assertEqual('p_id', share.FnGetAtt('project_id'))
|