diff --git a/etc/rally/rally.conf.sample b/etc/rally/rally.conf.sample index fe912439..69ac10b9 100644 --- a/etc/rally/rally.conf.sample +++ b/etc/rally/rally.conf.sample @@ -237,6 +237,18 @@ # (floating point value) #ironic_node_create_poll_interval = 1.0 +# Time(in sec) to sleep after creating a resource before polling for +# the status. (floating point value) +#magnum_bay_create_prepoll_delay = 5.0 + +# Time(in sec) to wait for magnum bay to be created. (floating point +# value) +#magnum_bay_create_timeout = 1200.0 + +# Time interval(in sec) between checks when waiting for bay creation. +# (floating point value) +#magnum_bay_create_poll_interval = 1.0 + # Delay between creating Manila share and polling for its status. # (floating point value) #manila_share_create_prepoll_delay = 2.0 diff --git a/rally-jobs/rally-magnum.yaml b/rally-jobs/rally-magnum.yaml index 77315e1c..096d4bc2 100644 --- a/rally-jobs/rally-magnum.yaml +++ b/rally-jobs/rally-magnum.yaml @@ -47,3 +47,30 @@ sla: failure_rate: max: 0 + + MagnumBays.create_and_list_bays: + - + args: + node_count: 1 + runner: + type: "constant" + times: 1 + concurrency: 1 + context: + users: + tenants: 1 + users_per_tenant: 1 + baymodels: + image_id: "fedora-atomic-latest" + flavor_id: "m1.small" + master_flavor_id: "m1.small" + external_network_id: "public" + dns_nameserver: "8.8.8.8" + docker_volume_size: 5 + coe: "swarm" + network_driver: "docker" + docker_storage_driver: "devicemapper" + master_lb_enabled: False + sla: + failure_rate: + max: 0 diff --git a/rally/plugins/openstack/cleanup/resources.py b/rally/plugins/openstack/cleanup/resources.py index 4234806a..7983ed3b 100644 --- a/rally/plugins/openstack/cleanup/resources.py +++ b/rally/plugins/openstack/cleanup/resources.py @@ -68,8 +68,11 @@ class QuotaMixin(SynchronizedDeletion): # MAGNUM -@base.resource("magnum", "baymodels", order=80, tenant_resource=True) -class MagnumBaymodel(base.ResourceManager): +_magnum_order = get_order(80) + + +@base.resource(service=None, resource=None) +class MagnumMixin(base.ResourceManager): def id(self): """Returns id of resource.""" @@ -79,14 +82,26 @@ class MagnumBaymodel(base.ResourceManager): result = [] marker = None while True: - baymodels = self._manager().list(marker=marker) - if not baymodels: + resources = self._manager().list(marker=marker) + if not resources: break - result.extend(baymodels) - marker = baymodels[-1].uuid + result.extend(resources) + marker = resources[-1].uuid return result +@base.resource("magnum", "bays", order=next(_magnum_order), + tenant_resource=True) +class MagnumBay(MagnumMixin): + """Resource class for Magnum bay.""" + + +@base.resource("magnum", "baymodels", order=next(_magnum_order), + tenant_resource=True) +class MagnumBaymodel(MagnumMixin): + """Resource class for Magnum baymodel.""" + + # HEAT @base.resource("heat", "stacks", order=100, tenant_resource=True) diff --git a/rally/plugins/openstack/scenarios/magnum/utils.py b/rally/plugins/openstack/scenarios/magnum/utils.py index d2f22ae9..511cbfb9 100644 --- a/rally/plugins/openstack/scenarios/magnum/utils.py +++ b/rally/plugins/openstack/scenarios/magnum/utils.py @@ -12,8 +12,30 @@ # License for the specific language governing permissions and limitations # under the License. +from oslo_config import cfg + +from rally.common import utils as common_utils from rally.plugins.openstack import scenario from rally.task import atomic +from rally.task import utils + +MAGNUM_BENCHMARK_OPTS = [ + cfg.FloatOpt("magnum_bay_create_prepoll_delay", + default=5.0, + help="Time(in sec) to sleep after creating a resource before " + "polling for the status."), + cfg.FloatOpt("magnum_bay_create_timeout", + default=1200.0, + help="Time(in sec) to wait for magnum bay to be created."), + cfg.FloatOpt("magnum_bay_create_poll_interval", + default=1.0, + help="Time interval(in sec) between checks when waiting for " + "bay creation."), +] + +CONF = cfg.CONF +benchmark_group = cfg.OptGroup(name="benchmark", title="benchmark options") +CONF.register_opts(MAGNUM_BENCHMARK_OPTS, group=benchmark_group) class MagnumScenario(scenario.OpenStackScenario): @@ -48,3 +70,47 @@ class MagnumScenario(scenario.OpenStackScenario): kwargs["name"] = self.generate_random_name() return self.clients("magnum").baymodels.create(**kwargs) + + @atomic.action_timer("magnum.list_bays") + def _list_bays(self, limit=None, **kwargs): + """Return list of bays. + + :param limit: (Optional) the maximum number of results to return + per request, if: + + 1) limit > 0, the maximum number of bays to return. + 2) limit param is NOT specified (None), the number of items + returned respect the maximum imposed by the Magnum API + (see Magnum's api.max_limit option). + :param kwargs: Optional additional arguments for bays listing + + :returns: bays list + """ + return self.clients("magnum").bays.list(limit=limit, **kwargs) + + @atomic.action_timer("magnum.create_bay") + def _create_bay(self, baymodel, node_count, **kwargs): + """Create a bay + + :param baymodel: baymodel for the bay + :param node_count: the bay node count + :param kwargs: optional additional arguments for bay creation + :returns: magnum bay + """ + + name = self.generate_random_name() + bay = self.clients("magnum").bays.create( + name=name, baymodel_id=baymodel, + node_count=node_count, **kwargs) + + common_utils.interruptable_sleep( + CONF.benchmark.magnum_bay_create_prepoll_delay) + bay = utils.wait_for_status( + bay, + ready_statuses=["CREATE_COMPLETE"], + update_resource=utils.get_from_manager(), + timeout=CONF.benchmark.magnum_bay_create_timeout, + check_interval=CONF.benchmark.magnum_bay_create_poll_interval, + id_attr="uuid" + ) + return bay diff --git a/tests/ci/osresources.py b/tests/ci/osresources.py index a0981758..b260c99d 100755 --- a/tests/ci/osresources.py +++ b/tests/ci/osresources.py @@ -97,7 +97,26 @@ class Magnum(ResourceManager): REQUIRED_SERVICE = consts.Service.MAGNUM def list_baymodels(self): - return self.client.baymodels.list() + result = [] + marker = None + while True: + baymodels = self.client.baymodels.list(marker=marker) + if not baymodels: + break + result.extend(baymodels) + marker = baymodels[-1].uuid + return result + + def list_bays(self): + result = [] + marker = None + while True: + bays = self.client.bays.list(marker=marker) + if not bays: + break + result.extend(bays) + marker = bays[-1].uuid + return result class Nova(ResourceManager): diff --git a/tests/unit/plugins/openstack/cleanup/test_resources.py b/tests/unit/plugins/openstack/cleanup/test_resources.py index 37014498..3572231f 100644 --- a/tests/unit/plugins/openstack/cleanup/test_resources.py +++ b/tests/unit/plugins/openstack/cleanup/test_resources.py @@ -65,25 +65,27 @@ class QuotaMixinTestCase(test.TestCase): self.assertEqual([quota.tenant_uuid], quota.list()) -class MagnumBaymodelTestCase(test.TestCase): +class MagnumMixinTestCase(test.TestCase): def test_id(self): - baymodel = resources.MagnumBaymodel() - baymodel.raw_resource = mock.MagicMock() - self.assertEqual(baymodel.raw_resource.uuid, baymodel.id()) + magnum = resources.MagnumMixin() + magnum._service = "magnum" + magnum.raw_resource = mock.MagicMock() + self.assertEqual(magnum.raw_resource.uuid, magnum.id()) def test_list(self): - baymodels = [mock.MagicMock(), mock.MagicMock(), mock.MagicMock(), - mock.MagicMock()] - baymodel = resources.MagnumBaymodel() - baymodel._manager = mock.MagicMock() - baymodel._manager.return_value.list.side_effect = ( - baymodels[:2], baymodels[2:4], []) - self.assertEqual(baymodels, baymodel.list()) + magnum = resources.MagnumMixin() + magnum._service = "magnum" + some_resources = [mock.MagicMock(), mock.MagicMock(), + mock.MagicMock(), mock.MagicMock()] + magnum._manager = mock.MagicMock() + magnum._manager.return_value.list.side_effect = ( + some_resources[:2], some_resources[2:4], []) + self.assertEqual(some_resources, magnum.list()) self.assertEqual( - [mock.call(marker=None), mock.call(marker=baymodels[1].uuid), - mock.call(marker=baymodels[3].uuid)], - baymodel._manager.return_value.list.call_args_list) + [mock.call(marker=None), mock.call(marker=some_resources[1].uuid), + mock.call(marker=some_resources[3].uuid)], + magnum._manager.return_value.list.call_args_list) class NovaServerTestCase(test.TestCase): diff --git a/tests/unit/plugins/openstack/scenarios/magnum/test_utils.py b/tests/unit/plugins/openstack/scenarios/magnum/test_utils.py index 747a1edd..d9248de9 100644 --- a/tests/unit/plugins/openstack/scenarios/magnum/test_utils.py +++ b/tests/unit/plugins/openstack/scenarios/magnum/test_utils.py @@ -17,23 +17,25 @@ import mock from rally.plugins.openstack.scenarios.magnum import utils from tests.unit import test +CONF = utils.CONF + class MagnumScenarioTestCase(test.ScenarioTestCase): def setUp(self): super(MagnumScenarioTestCase, self).setUp() self.baymodel = mock.Mock() + self.bay = mock.Mock() self.scenario = utils.MagnumScenario(self.context) def test_list_baymodels(self): - scenario = utils.MagnumScenario(self.context) fake_baymodel_list = [self.baymodel] self.clients("magnum").baymodels.list.return_value = fake_baymodel_list - return_baymodels_list = scenario._list_baymodels() + return_baymodels_list = self.scenario._list_baymodels() self.assertEqual(fake_baymodel_list, return_baymodels_list) self.clients("magnum").baymodels.list.assert_called_once_with() - self._test_atomic_action_timer(scenario.atomic_actions(), + self._test_atomic_action_timer(self.scenario.atomic_actions(), "magnum.list_baymodels") def test_create_baymodel(self): @@ -58,3 +60,34 @@ class MagnumScenarioTestCase(test.ScenarioTestCase): self._test_atomic_action_timer(self.scenario.atomic_actions(), "magnum.create_baymodel") + + def test_list_bays(self): + return_bays_list = self.scenario._list_bays(limit="foo1") + self.clients("magnum").bays.list.assert_called_once_with(limit="foo1") + self.assertEqual(self.clients("magnum").bays.list.return_value, + return_bays_list) + self._test_atomic_action_timer( + self.scenario.atomic_actions(), "magnum.list_bays") + + def test_create_bay(self): + self.scenario.generate_random_name = mock.Mock( + return_value="generated_name") + self.clients("magnum").bays.create.return_value = self.bay + return_bay = self.scenario._create_bay( + baymodel="generated_uuid", node_count=2) + self.mock_wait_for_status.mock.assert_called_once_with( + self.bay, + ready_statuses=["CREATE_COMPLETE"], + update_resource=self.mock_get_from_manager.mock.return_value, + check_interval=CONF.benchmark. + magnum_bay_create_poll_interval, + timeout=CONF.benchmark.magnum_bay_create_timeout, + id_attr="uuid") + args, kwargs = self.clients("magnum").bays.create.call_args + self.assertEqual("generated_name", kwargs["name"]) + self.assertEqual("generated_uuid", kwargs["baymodel_id"]) + self.mock_get_from_manager.mock.assert_called_once_with() + self.assertEqual( + self.mock_wait_for_status.mock.return_value, return_bay) + self._test_atomic_action_timer( + self.scenario.atomic_actions(), "magnum.create_bay")