From 18e1f4432adea4e115a82fac96238970389ab07e Mon Sep 17 00:00:00 2001 From: JingLu5 Date: Fri, 11 Aug 2017 02:58:20 +0000 Subject: Add common openstack opertation scenarios: image & volume JIRA: YARDSTICK-781 This patch adds some common openstack opertation scenarios Change-Id: I3de7dbb30eaebac4feebcf07dd6a0d2bdcf428d9 Signed-off-by: JingLu5 --- .../benchmark/scenarios/lib/test_create_image.py | 41 ++++++++++++ .../benchmark/scenarios/lib/test_create_volume.py | 40 ++++++++++++ .../benchmark/scenarios/lib/test_delete_image.py | 36 +++++++++++ .../benchmark/scenarios/lib/test_delete_server.py | 35 +++++++++++ yardstick/benchmark/scenarios/lib/create_image.py | 72 ++++++++++++++++++++++ yardstick/benchmark/scenarios/lib/create_volume.py | 71 +++++++++++++++++++++ yardstick/benchmark/scenarios/lib/delete_image.py | 61 ++++++++++++++++++ yardstick/benchmark/scenarios/lib/delete_server.py | 51 +++++++++++++++ yardstick/common/openstack_utils.py | 60 ++++++++++++++++++ 9 files changed, 467 insertions(+) create mode 100644 tests/unit/benchmark/scenarios/lib/test_create_image.py create mode 100644 tests/unit/benchmark/scenarios/lib/test_create_volume.py create mode 100644 tests/unit/benchmark/scenarios/lib/test_delete_image.py create mode 100644 tests/unit/benchmark/scenarios/lib/test_delete_server.py create mode 100644 yardstick/benchmark/scenarios/lib/create_image.py create mode 100644 yardstick/benchmark/scenarios/lib/create_volume.py create mode 100644 yardstick/benchmark/scenarios/lib/delete_image.py create mode 100644 yardstick/benchmark/scenarios/lib/delete_server.py diff --git a/tests/unit/benchmark/scenarios/lib/test_create_image.py b/tests/unit/benchmark/scenarios/lib/test_create_image.py new file mode 100644 index 000000000..c213ceba0 --- /dev/null +++ b/tests/unit/benchmark/scenarios/lib/test_create_image.py @@ -0,0 +1,41 @@ +############################################################################## +# Copyright (c) 2017 Huawei Technologies Co.,Ltd and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## +import unittest +import mock + +from yardstick.benchmark.scenarios.lib.create_image import CreateImage + + +class CreateImageTestCase(unittest.TestCase): + + @mock.patch('yardstick.common.openstack_utils.create_image') + @mock.patch('yardstick.common.openstack_utils.get_glance_client') + def test_create_image(self, mock_get_glance_client, mock_create_image): + options = { + 'image_name': 'yardstick_test_image_01', + 'disk_format': 'qcow2', + 'container_format': 'bare', + 'min_disk': '1', + 'min_ram': '512', + 'protected': 'False', + 'tags': '["yardstick automatic test image"]', + 'file_path': '/home/opnfv/images/cirros-0.3.5-x86_64-disk.img' + } + args = {"options": options} + obj = CreateImage(args, {}) + obj.run({}) + self.assertTrue(mock_create_image.called) + + +def main(): + unittest.main() + + +if __name__ == '__main__': + main() diff --git a/tests/unit/benchmark/scenarios/lib/test_create_volume.py b/tests/unit/benchmark/scenarios/lib/test_create_volume.py new file mode 100644 index 000000000..fc633139e --- /dev/null +++ b/tests/unit/benchmark/scenarios/lib/test_create_volume.py @@ -0,0 +1,40 @@ +############################################################################## +# Copyright (c) 2017 Huawei Technologies Co.,Ltd and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## +import unittest +import mock + +from yardstick.benchmark.scenarios.lib.create_volume import CreateVolume + + +class CreateVolumeTestCase(unittest.TestCase): + + @mock.patch('yardstick.common.openstack_utils.create_volume') + @mock.patch('yardstick.common.openstack_utils.get_image_id') + @mock.patch('yardstick.common.openstack_utils.get_cinder_client') + @mock.patch('yardstick.common.openstack_utils.get_glance_client') + def test_create_volume(self, mock_get_glance_client, mock_get_cinder_client, mock_image_id, mock_create_volume): + options = { + 'volume_name': 'yardstick_test_volume_01', + 'size': '256', + 'image': 'cirros-0.3.5' + } + args = {"options": options} + obj = CreateVolume(args, {}) + obj.run({}) + self.assertTrue(mock_create_volume.called) + self.assertTrue(mock_image_id.called) + self.assertTrue(mock_get_glance_client.called) + self.assertTrue(mock_get_cinder_client.called) + +def main(): + unittest.main() + + +if __name__ == '__main__': + main() diff --git a/tests/unit/benchmark/scenarios/lib/test_delete_image.py b/tests/unit/benchmark/scenarios/lib/test_delete_image.py new file mode 100644 index 000000000..2bbf14d16 --- /dev/null +++ b/tests/unit/benchmark/scenarios/lib/test_delete_image.py @@ -0,0 +1,36 @@ +############################################################################## +# Copyright (c) 2017 Huawei Technologies Co.,Ltd and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## +import unittest +import mock + +from yardstick.benchmark.scenarios.lib.delete_image import DeleteImage + + +class DeleteImageTestCase(unittest.TestCase): + + @mock.patch('yardstick.common.openstack_utils.delete_image') + @mock.patch('yardstick.common.openstack_utils.get_image_id') + @mock.patch('yardstick.common.openstack_utils.get_glance_client') + def test_delete_image(self, mock_get_glance_client, mock_image_id, mock_delete_image): + options = { + 'image_name': 'yardstick_test_image_01' + } + args = {"options": options} + obj = DeleteImage(args, {}) + obj.run({}) + self.assertTrue(mock_delete_image.called) + self.assertTrue(mock_image_id.called) + self.assertTrue(mock_get_glance_client.called) + +def main(): + unittest.main() + + +if __name__ == '__main__': + main() diff --git a/tests/unit/benchmark/scenarios/lib/test_delete_server.py b/tests/unit/benchmark/scenarios/lib/test_delete_server.py new file mode 100644 index 000000000..622ead5ac --- /dev/null +++ b/tests/unit/benchmark/scenarios/lib/test_delete_server.py @@ -0,0 +1,35 @@ +############################################################################## +# Copyright (c) 2017 Huawei Technologies Co.,Ltd and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## +import unittest +import mock + +from yardstick.benchmark.scenarios.lib.delete_server import DeleteServer + + +class DeleteServerTestCase(unittest.TestCase): + + @mock.patch('yardstick.common.openstack_utils.delete_instance') + @mock.patch('yardstick.common.openstack_utils.get_nova_client') + def test_delete_server(self, mock_get_nova_client, mock_delete_instance): + options = { + 'server_id': '1234-4567-0000' + } + args = {"options": options} + obj = DeleteServer(args, {}) + obj.run({}) + self.assertTrue(mock_get_nova_client.called) + self.assertTrue(mock_delete_instance.called) + + +def main(): + unittest.main() + + +if __name__ == '__main__': + main() diff --git a/yardstick/benchmark/scenarios/lib/create_image.py b/yardstick/benchmark/scenarios/lib/create_image.py new file mode 100644 index 000000000..bcffc7452 --- /dev/null +++ b/yardstick/benchmark/scenarios/lib/create_image.py @@ -0,0 +1,72 @@ +############################################################################## +# Copyright (c) 2017 Huawei Technologies Co.,Ltd and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +from __future__ import print_function +from __future__ import absolute_import + +import logging + +from yardstick.benchmark.scenarios import base +import yardstick.common.openstack_utils as op_utils + +LOG = logging.getLogger(__name__) + + +class CreateImage(base.Scenario): + """Create an OpenStack image""" + + __scenario_type__ = "CreateImage" + + def __init__(self, scenario_cfg, context_cfg): + self.scenario_cfg = scenario_cfg + self.context_cfg = context_cfg + self.options = self.scenario_cfg['options'] + + self.image_name = self.options.get("image_name", "TestImage") + self.file_path = self.options.get("file_path", None) + self.disk_format = self.options.get("disk_format", "qcow2") + self.container_format = self.options.get("container_format", "bare") + self.min_disk = self.options.get("min_disk", 0) + self.min_ram = self.options.get("min_ram", 0) + self.protected = self.options.get("protected", False) + self.public = self.options.get("public", "public") + self.tags = self.options.get("tags", []) + self.custom_property = self.options.get("property", {}) + + self.glance_client = op_utils.get_glance_client() + + self.setup_done = False + + def setup(self): + """scenario setup""" + + self.setup_done = True + + def run(self, result): + """execute the test""" + + if not self.setup_done: + self.setup() + + image_id = op_utils.create_image(self.glance_client, self.image_name, + self.file_path, self.disk_format, + self.container_format, self.min_disk, + self.min_ram, self.protected, self.tags, + self.public, **self.custom_property) + + if image_id: + LOG.info("Create image successful!") + values = [image_id] + + else: + LOG.info("Create image failed!") + values = [] + + keys = self.scenario_cfg.get('output', '').split() + return self._push_to_outputs(keys, values) diff --git a/yardstick/benchmark/scenarios/lib/create_volume.py b/yardstick/benchmark/scenarios/lib/create_volume.py new file mode 100644 index 000000000..c7086d0ef --- /dev/null +++ b/yardstick/benchmark/scenarios/lib/create_volume.py @@ -0,0 +1,71 @@ +############################################################################## +# Copyright (c) 2017 Huawei Technologies Co.,Ltd and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +from __future__ import print_function +from __future__ import absolute_import + +import time +import logging + +from yardstick.benchmark.scenarios import base +import yardstick.common.openstack_utils as op_utils + +LOG = logging.getLogger(__name__) + + +class CreateVolume(base.Scenario): + """Create an OpenStack volume""" + + __scenario_type__ = "CreateVolume" + + def __init__(self, scenario_cfg, context_cfg): + self.scenario_cfg = scenario_cfg + self.context_cfg = context_cfg + self.options = self.scenario_cfg['options'] + + self.volume_name = self.options.get("volume_name", "TestVolume") + self.volume_size = self.options.get("size", 100) + self.image_name = self.options.get("image", None) + self.image_id = None + + self.glance_client = op_utils.get_glance_client() + self.cinder_client = op_utils.get_cinder_client() + + self.setup_done = False + + def setup(self): + """scenario setup""" + + self.setup_done = True + + def run(self, result): + """execute the test""" + + if not self.setup_done: + self.setup() + + if self.image_name: + self.image_id = op_utils.get_image_id(self.glance_client, + self.image_name) + + volume = op_utils.create_volume(self.cinder_client, self.volume_name, + self.volume_size, self.image_id) + + status = volume.status + while(status == 'creating' or status == 'downloading'): + LOG.info("Volume status is: %s" % status) + time.sleep(5) + volume = op_utils.get_volume_by_name(self.volume_name) + status = volume.status + + LOG.info("Create volume successful!") + + values = [volume.id] + keys = self.scenario_cfg.get('output', '').split() + return self._push_to_outputs(keys, values) diff --git a/yardstick/benchmark/scenarios/lib/delete_image.py b/yardstick/benchmark/scenarios/lib/delete_image.py new file mode 100644 index 000000000..0e3a853e5 --- /dev/null +++ b/yardstick/benchmark/scenarios/lib/delete_image.py @@ -0,0 +1,61 @@ +############################################################################## +# Copyright (c) 2017 Huawei Technologies Co.,Ltd and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +from __future__ import print_function +from __future__ import absolute_import + +import logging + +from yardstick.benchmark.scenarios import base +import yardstick.common.openstack_utils as op_utils + +LOG = logging.getLogger(__name__) + + +class DeleteImage(base.Scenario): + """Delete an OpenStack image""" + + __scenario_type__ = "DeleteImage" + + def __init__(self, scenario_cfg, context_cfg): + self.scenario_cfg = scenario_cfg + self.context_cfg = context_cfg + self.options = self.scenario_cfg['options'] + + self.image_name = self.options.get("image_name", "TestImage") + self.image_id = None + + self.glance_client = op_utils.get_glance_client() + + self.setup_done = False + + def setup(self): + """scenario setup""" + + self.setup_done = True + + def run(self, result): + """execute the test""" + + if not self.setup_done: + self.setup() + + self.image_id = op_utils.get_image_id(self.glance_client, self.image_name) + LOG.info("Deleting image: %s", self.image_name) + status = op_utils.delete_image(self.glance_client, self.image_id) + + if status: + LOG.info("Delete image successful!") + values = [status] + else: + LOG.info("Delete image failed!") + values = [] + + keys = self.scenario_cfg.get('output', '').split() + return self._push_to_outputs(keys, values) diff --git a/yardstick/benchmark/scenarios/lib/delete_server.py b/yardstick/benchmark/scenarios/lib/delete_server.py new file mode 100644 index 000000000..bcd8faba7 --- /dev/null +++ b/yardstick/benchmark/scenarios/lib/delete_server.py @@ -0,0 +1,51 @@ +############################################################################## +# Copyright (c) 2017 Huawei Technologies Co.,Ltd and others. +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +from __future__ import print_function +from __future__ import absolute_import + +import logging + +from yardstick.benchmark.scenarios import base +import yardstick.common.openstack_utils as op_utils + +LOG = logging.getLogger(__name__) + + +class DeleteServer(base.Scenario): + """Delete an OpenStack server""" + + __scenario_type__ = "DeleteServer" + + def __init__(self, scenario_cfg, context_cfg): + self.scenario_cfg = scenario_cfg + self.context_cfg = context_cfg + self.options = self.scenario_cfg['options'] + self.server_id = self.options.get("server_id", None) + self.nova_client = op_utils.get_nova_client() + + self.setup_done = False + + def setup(self): + """scenario setup""" + + self.setup_done = True + + def run(self, result): + """execute the test""" + + if not self.setup_done: + self.setup() + + status = op_utils.delete_instance(self.nova_client, + instance_id=self.server_id) + if status: + LOG.info("Delete server successful!") + else: + LOG.error("Delete server failed!") diff --git a/yardstick/common/openstack_utils.py b/yardstick/common/openstack_utils.py index f027b7922..5e0cae8ff 100644 --- a/yardstick/common/openstack_utils.py +++ b/yardstick/common/openstack_utils.py @@ -448,9 +448,69 @@ def get_image_id(glance_client, image_name): # pragma: no cover return next((i.id for i in images if i.name == image_name), None) +def create_image(glance_client, image_name, file_path, disk_format, + container_format, min_disk, min_ram, protected, tag, + public, **kwargs): # pragma: no cover + if not os.path.isfile(file_path): + log.error("Error: file %s does not exist." % file_path) + return None + try: + image_id = get_image_id(glance_client, image_name) + if image_id is not None: + log.info("Image %s already exists." % image_name) + else: + log.info("Creating image '%s' from '%s'...", image_name, file_path) + + image = glance_client.images.create(name=image_name, + visibility=public, + disk_format=disk_format, + container_format=container_format, + min_disk=min_disk, + min_ram=min_ram, + tags=tag, + protected=protected, + **kwargs) + image_id = image.id + with open(file_path) as image_data: + glance_client.images.upload(image_id, image_data) + return image_id + except Exception: + log.error("Error [create_glance_image(glance_client, '%s', '%s', '%s')]", + image_name, file_path, public) + return None + + +def delete_image(glance_client, image_id): # pragma: no cover + try: + glance_client.images.delete(image_id) + + except Exception: + log.exception("Error [delete_flavor(glance_client, %s)]", image_id) + return False + else: + return True + + # ********************************************* # CINDER # ********************************************* def get_volume_id(volume_name): # pragma: no cover volumes = get_cinder_client().volumes.list() return next((v.id for v in volumes if v.name == volume_name), None) + + +def create_volume(cinder_client, volume_name, volume_size, + volume_image=False): # pragma: no cover + try: + if volume_image: + volume = cinder_client.volumes.create(name=volume_name, + size=volume_size, + imageRef=volume_image) + else: + volume = cinder_client.volumes.create(name=volume_name, + size=volume_size) + return volume + except Exception: + log.exception("Error [create_volume(cinder_client, %s)]", + (volume_name, volume_size)) + return None -- cgit 1.2.3-korg