From a2fff3c153d70832fbee2b0cc14fe3ffdd567506 Mon Sep 17 00:00:00 2001 From: Winnie Tsang Date: Fri, 22 Apr 2016 23:16:01 +0000 Subject: [PATCH] [Magnum] Scenario to create a Magnum bay Measure time to create a bay In this scenario, a single bay is created. This can be used to establish the baseline in a test environment. The job yaml file describes the attribute of the bay to be created in the scenario, such as node count. The baymodel should already be created by the context: Kubernetes, Swarm, Mesos. Change-Id: I182abf34212d693d2bb246d195a5daba61e0efe4 Co-Authored-By: Spyros Trigazis Co-Authored-By: Ton Ngo Partially-Implements: blueprint benchmark-scenarios-for-magnum --- etc/rally/rally.conf.sample | 12 ++++ rally-jobs/rally-magnum.yaml | 27 ++++++++ rally/plugins/openstack/cleanup/resources.py | 27 ++++++-- .../openstack/scenarios/magnum/utils.py | 66 +++++++++++++++++++ tests/ci/osresources.py | 21 +++++- .../openstack/cleanup/test_resources.py | 30 +++++---- .../openstack/scenarios/magnum/test_utils.py | 39 ++++++++++- 7 files changed, 198 insertions(+), 24 deletions(-) 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")