[Magnum] Context and scenario for Magnum baymodel

Context and scenario to create baymodel

All Magnum scenarios will use some baymodels.
This patch sets up the Rally context to create any
baymodels needed by a scenario.  All baymodels created
will be cleaned up at the end of the job.

A simple scenario is included to test a Magnum job in
Rally.  Currently the scenario only lists the baymodel created
by the context, but later more user query type of actions can
be added to similate a large user base interacting with Magnum.

The job yaml file specifies the 3 bay types to be created by the
context:  Kubernetes, Swarm, Mesos.

Partially-Implements: blueprint benchmark-scenarios-for-magnum
Co-Authored-By: Ton Ngo <ton@us.ibm.com>
Co-Authored-By: Spyros Trigazis <strigazi@gmail.com>
Change-Id: I0979f2461c6e33c9163e19a6d7884fe1c7967e3f
This commit is contained in:
Winnie Tsang 2016-04-22 18:19:17 +00:00
parent ea43123c2d
commit cc00bd60ed
11 changed files with 232 additions and 2 deletions

View File

@ -0,0 +1,49 @@
---
MagnumBaymodels.list_baymodels:
-
runner:
type: "constant"
times: 40
concurrency: 20
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: "kubernetes"
network_driver: "flannel"
docker_storage_driver: "devicemapper"
master_lb_enabled: False
sla:
failure_rate:
max: 0
-
runner:
type: "constant"
times: 40
concurrency: 20
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

View File

@ -66,6 +66,27 @@ class QuotaMixin(SynchronizedDeletion):
return [self.tenant_uuid] if self.tenant_uuid else []
# MAGNUM
@base.resource("magnum", "baymodels", order=80, tenant_resource=True)
class MagnumBaymodel(base.ResourceManager):
def id(self):
"""Returns id of resource."""
return self.raw_resource.uuid
def list(self):
result = []
marker = None
while True:
baymodels = self._manager().list(marker=marker)
if not baymodels:
break
result.extend(baymodels)
marker = baymodels[-1].uuid
return result
# HEAT
@base.resource("heat", "stacks", order=100, tenant_resource=True)

View File

@ -0,0 +1,50 @@
# 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.
from rally.plugins.openstack import scenario
from rally.task import atomic
class MagnumScenario(scenario.OpenStackScenario):
"""Base class for Magnum scenarios with basic atomic actions."""
@atomic.action_timer("magnum.list_baymodels")
def _list_baymodels(self, **kwargs):
"""Return list of baymodels.
:param limit: (Optional) The maximum number of results to return
per request, if:
1) limit > 0, the maximum number of baymodels 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 baymodels listing
:returns: baymodels list
"""
return self.clients("magnum").baymodels.list(**kwargs)
@atomic.action_timer("magnum.create_baymodel")
def _create_baymodel(self, **kwargs):
"""Create a baymodel
:param kwargs: optional additional arguments for baymodel creation
:returns: magnum baymodel
"""
kwargs["name"] = self.generate_random_name()
return self.clients("magnum").baymodels.create(**kwargs)

View File

@ -92,6 +92,14 @@ class Keystone(ResourceManager):
return self.client.roles.list()
class Magnum(ResourceManager):
REQUIRED_SERVICE = consts.Service.MAGNUM
def list_baymodels(self):
return self.client.baymodels.list()
class Nova(ResourceManager):
REQUIRED_SERVICE = consts.Service.NOVA

View File

@ -322,6 +322,10 @@ class FakeObject(FakeResource):
pass
class FakeBaymodel(FakeResource):
pass
class FakeManager(object):
def __init__(self):
@ -514,6 +518,23 @@ class FakeKeypairManager(FakeManager):
self.resources_order.remove(resource)
class FakeBaymodelManager(FakeManager):
def create(self, name):
baymodel = FakeBaymodel(self)
baymodel.name = name or baymodel.name
return self._cache(baymodel)
def delete(self, resource):
if not isinstance(resource, six.string_types):
resource = resource.id
cached = self.get(resource)
if cached is not None:
del self.cache[resource]
self.resources_order.remove(resource)
class FakeStackManager(FakeManager):
def create(self, name):
@ -1512,7 +1533,7 @@ class FakeSenlinClient(object):
class FakeMagnumClient(object):
def __init__(self):
pass
self.baymodels = FakeBaymodelManager()
class FakeWatcherClient(object):

View File

@ -65,6 +65,27 @@ class QuotaMixinTestCase(test.TestCase):
self.assertEqual([quota.tenant_uuid], quota.list())
class MagnumBaymodelTestCase(test.TestCase):
def test_id(self):
baymodel = resources.MagnumBaymodel()
baymodel.raw_resource = mock.MagicMock()
self.assertEqual(baymodel.raw_resource.uuid, baymodel.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())
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)
class NovaServerTestCase(test.TestCase):
def test_list(self):
@ -879,4 +900,4 @@ class WatcherActionPlanTestCase(test.TestCase):
watcher.list()
self.assertEqual("action_plan", watcher._resource)
watcher._manager().list.assert_called_once_with(limit=0)
watcher._manager().list.assert_called_once_with(limit=0)

View File

@ -0,0 +1,60 @@
# 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 mock
from rally.plugins.openstack.scenarios.magnum import utils
from tests.unit import test
class MagnumScenarioTestCase(test.ScenarioTestCase):
def setUp(self):
super(MagnumScenarioTestCase, self).setUp()
self.baymodel = 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()
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(),
"magnum.list_baymodels")
def test_create_baymodel(self):
self.scenario.generate_random_name = mock.Mock(
return_value="generated_name")
fake_baymodel = self.baymodel
self.clients("magnum").baymodels.create.return_value = fake_baymodel
return_baymodel = self.scenario._create_baymodel(
image="test_image",
keypair="test_key",
external_network="public",
dns_nameserver="8.8.8.8",
flavor="m1.large",
docker_volume_size=50,
network_driver="docker",
coe="swarm")
self.assertEqual(fake_baymodel, return_baymodel)
args, kwargs = self.clients("magnum").baymodels.create.call_args
self.assertEqual("generated_name", kwargs["name"])
self._test_atomic_action_timer(self.scenario.atomic_actions(),
"magnum.create_baymodel")