[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 <strigazi@gmail.com>
Co-Authored-By: Ton Ngo <ton@us.ibm.com>
Partially-Implements: blueprint benchmark-scenarios-for-magnum
This commit is contained in:
Winnie Tsang 2016-04-22 23:16:01 +00:00 committed by Spyros Trigazis
parent 6a8be4193e
commit a2fff3c153
7 changed files with 198 additions and 24 deletions

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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):

View File

@ -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):

View File

@ -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")