# Copyright 2016 Mirantis 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 copy from unittest import mock import ddt from rally_openstack.common import consts as rally_consts from rally_openstack.task.contexts.manila import consts from rally_openstack.task.contexts.manila import manila_shares from rally_openstack.task.scenarios.manila import utils as manila_utils from tests.unit import test MANILA_UTILS_PATH = ( "rally_openstack.task.scenarios.manila.utils.ManilaScenario.") class Fake(object): def __init__(self, **kwargs): for k, v in kwargs.items(): setattr(self, k, v) def __getitem__(self, item): return getattr(self, item) def to_dict(self): return self.__dict__ @ddt.ddt class SharesTestCase(test.TestCase): TENANTS_AMOUNT = 3 USERS_PER_TENANT = 4 SHARES_PER_TENANT = 7 SHARE_NETWORKS = [{"id": "sn_%s_id" % d} for d in range(3)] def _get_context(self, use_share_networks=False, shares_per_tenant=None, share_size=1, share_proto="fake_proto", share_type=None): tenants = {} for t_id in range(self.TENANTS_AMOUNT): tenants[str(t_id)] = {"name": str(t_id)} users = [] for t_id in sorted(list(tenants.keys())): for i in range(self.USERS_PER_TENANT): users.append({ "id": i, "tenant_id": t_id, "credential": mock.MagicMock()}) context = { "config": { "users": { "tenants": self.TENANTS_AMOUNT, "users_per_tenant": self.USERS_PER_TENANT, "user_choice_method": "round_robin", }, consts.SHARE_NETWORKS_CONTEXT_NAME: { "use_share_networks": use_share_networks, "share_networks": self.SHARE_NETWORKS, }, consts.SHARES_CONTEXT_NAME: { "shares_per_tenant": ( shares_per_tenant or self.SHARES_PER_TENANT), "size": share_size, "share_proto": share_proto, "share_type": share_type, }, }, "admin": { "credential": mock.MagicMock(), }, "task": mock.MagicMock(), "owner_id": "foo_uuid", "users": users, "tenants": tenants, } if use_share_networks: for t in context["tenants"].keys(): context["tenants"][t][consts.SHARE_NETWORKS_CONTEXT_NAME] = { "share_networks": self.SHARE_NETWORKS, } return context def test_init(self): ctxt = { "task": mock.MagicMock(), "config": { consts.SHARES_CONTEXT_NAME: {"foo": "bar"}, "fake": {"fake_key": "fake_value"}, }, } inst = manila_shares.Shares(ctxt) self.assertEqual( {"foo": "bar", "shares_per_tenant": 1, "size": 1, "share_proto": "NFS", "share_type": None}, inst.config) self.assertIn( rally_consts.JSON_SCHEMA, inst.CONFIG_SCHEMA.get("$schema")) self.assertFalse(inst.CONFIG_SCHEMA.get("additionalProperties")) self.assertEqual("object", inst.CONFIG_SCHEMA.get("type")) props = inst.CONFIG_SCHEMA.get("properties", {}) self.assertEqual( {"minimum": 1, "type": "integer"}, props.get("shares_per_tenant")) self.assertEqual({"minimum": 1, "type": "integer"}, props.get("size")) self.assertEqual({"type": "string"}, props.get("share_proto")) self.assertEqual({"type": "string"}, props.get("share_type")) self.assertEqual(455, inst.get_order()) self.assertEqual(consts.SHARES_CONTEXT_NAME, inst.get_name()) @mock.patch(MANILA_UTILS_PATH + "_create_share") @ddt.data(True, False) def test_setup( self, use_share_networks, mock_manila_scenario__create_share): share_type = "fake_share_type" ctxt = self._get_context( use_share_networks=use_share_networks, share_type=share_type) inst = manila_shares.Shares(ctxt) shares = [ Fake(id="fake_share_id_%d" % s_id) for s_id in range(self.TENANTS_AMOUNT * self.SHARES_PER_TENANT) ] mock_manila_scenario__create_share.side_effect = shares expected_ctxt = copy.deepcopy(ctxt) inst.setup() self.assertEqual( self.TENANTS_AMOUNT * self.SHARES_PER_TENANT, mock_manila_scenario__create_share.call_count) for d in range(self.TENANTS_AMOUNT): self.assertEqual( [ s.to_dict() for s in shares[ (d * self.SHARES_PER_TENANT):( d * self.SHARES_PER_TENANT + self.SHARES_PER_TENANT ) ] ], inst.context.get("tenants", {}).get("%s" % d, {}).get("shares") ) self.assertEqual(expected_ctxt["task"], inst.context.get("task")) self.assertEqual(expected_ctxt["config"], inst.context.get("config")) self.assertEqual(expected_ctxt["users"], inst.context.get("users")) if use_share_networks: mock_calls = [ mock.call( share_proto=ctxt["config"][consts.SHARES_CONTEXT_NAME][ "share_proto"], size=ctxt["config"][consts.SHARES_CONTEXT_NAME]["size"], share_type=ctxt["config"][consts.SHARES_CONTEXT_NAME][ "share_type"], share_network=self.SHARE_NETWORKS[ int(t_id) % len(self.SHARE_NETWORKS)]["id"] ) for t_id in expected_ctxt["tenants"].keys() ] else: mock_calls = [ mock.call( share_proto=ctxt["config"][consts.SHARES_CONTEXT_NAME][ "share_proto"], size=ctxt["config"][consts.SHARES_CONTEXT_NAME]["size"], share_type=ctxt["config"][consts.SHARES_CONTEXT_NAME][ "share_type"], ) for t_id in expected_ctxt["tenants"].keys() ] mock_manila_scenario__create_share.assert_has_calls( mock_calls, any_order=True) @mock.patch(MANILA_UTILS_PATH + "_create_share") @mock.patch("rally_openstack.task.cleanup.manager.cleanup") def test_cleanup( self, mock_cleanup_manager_cleanup, mock_manila_scenario__create_share): ctxt = self._get_context() inst = manila_shares.Shares(ctxt) shares = [ Fake(id="fake_share_id_%d" % s_id) for s_id in range(self.TENANTS_AMOUNT * self.SHARES_PER_TENANT) ] mock_manila_scenario__create_share.side_effect = shares inst.setup() inst.cleanup() mock_cleanup_manager_cleanup.assert_called_once_with( names=["manila.shares"], users=inst.context.get("users", []), superclass=manila_utils.ManilaScenario, task_id="foo_uuid")