Add common openstack opertation scenarios: image & volume 95/39095/4
authorJingLu5 <lvjing5@huawei.com>
Fri, 11 Aug 2017 02:58:20 +0000 (02:58 +0000)
committerJingLu5 <lvjing5@huawei.com>
Fri, 11 Aug 2017 03:32:11 +0000 (03:32 +0000)
JIRA: YARDSTICK-781

This patch adds some common openstack opertation scenarios

Change-Id: I3de7dbb30eaebac4feebcf07dd6a0d2bdcf428d9
Signed-off-by: JingLu5 <lvjing5@huawei.com>
tests/unit/benchmark/scenarios/lib/test_create_image.py [new file with mode: 0644]
tests/unit/benchmark/scenarios/lib/test_create_volume.py [new file with mode: 0644]
tests/unit/benchmark/scenarios/lib/test_delete_image.py [new file with mode: 0644]
tests/unit/benchmark/scenarios/lib/test_delete_server.py [new file with mode: 0644]
yardstick/benchmark/scenarios/lib/create_image.py [new file with mode: 0644]
yardstick/benchmark/scenarios/lib/create_volume.py [new file with mode: 0644]
yardstick/benchmark/scenarios/lib/delete_image.py [new file with mode: 0644]
yardstick/benchmark/scenarios/lib/delete_server.py [new file with mode: 0644]
yardstick/common/openstack_utils.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 (file)
index 0000000..c213ceb
--- /dev/null
@@ -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 (file)
index 0000000..fc63313
--- /dev/null
@@ -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 (file)
index 0000000..2bbf14d
--- /dev/null
@@ -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 (file)
index 0000000..622ead5
--- /dev/null
@@ -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 (file)
index 0000000..bcffc74
--- /dev/null
@@ -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 (file)
index 0000000..c7086d0
--- /dev/null
@@ -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 (file)
index 0000000..0e3a853
--- /dev/null
@@ -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 (file)
index 0000000..bcd8fab
--- /dev/null
@@ -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!")
index f027b79..5e0cae8 100644 (file)
@@ -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