You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by mc...@apache.org on 2013/11/01 01:21:18 UTC

[07/50] [abbrv] git commit: updated refs/heads/rbac to 2ef4d52

Adding missing test cases: Snapshots Improvement


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/1972d612
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/1972d612
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/1972d612

Branch: refs/heads/rbac
Commit: 1972d6121db6bbc21e5db35ab9787f98ed10527e
Parents: 9c57e13
Author: Gaurav Aradhye <ga...@clogeny.com>
Authored: Wed Sep 18 00:33:03 2013 -0400
Committer: SrikanteswaraRao Talluri <ta...@apache.org>
Committed: Tue Oct 29 23:42:38 2013 +0530

----------------------------------------------------------------------
 .../component/test_snapshots_improvement.py     | 693 +++++++++++++++++++
 tools/marvin/marvin/asyncJobMgr.py              |   4 +-
 2 files changed, 695 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1972d612/test/integration/component/test_snapshots_improvement.py
----------------------------------------------------------------------
diff --git a/test/integration/component/test_snapshots_improvement.py b/test/integration/component/test_snapshots_improvement.py
new file mode 100644
index 0000000..190db55
--- /dev/null
+++ b/test/integration/component/test_snapshots_improvement.py
@@ -0,0 +1,693 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+
+""" P1 tests for Snapshots Improvements
+"""
+# Import Local Modules
+from nose.plugins.attrib import attr
+from marvin.cloudstackTestCase import cloudstackTestCase, unittest
+from marvin.integration.lib.utils import (random_gen)
+from marvin.integration.lib.base import (
+                                        Account,
+                                        ServiceOffering,
+                                        VirtualMachine,
+                                        Snapshot,
+                                        Template,
+                                        Volume,
+                                        DiskOffering
+                                        )
+from marvin.integration.lib.common import (get_domain,
+                                        get_zone,
+                                        get_template,
+                                        cleanup_resources,
+                                        list_snapshots
+                                        )
+from marvin.cloudstackAPI import (createSnapshot,
+                                  createVolume,
+                                  createTemplate,
+                                  listOsTypes,
+                                  stopVirtualMachine
+                                  )
+from marvin.integration.lib.utils import is_snapshot_on_nfs
+
+
+class Services:
+    def __init__(self):
+        self.services = {
+                        "service_offering": {
+                                    "name": "Tiny Instance",
+                                    "displaytext": "Tiny Instance",
+                                    "cpunumber": 1,
+                                    "cpuspeed": 200,    # in MHz
+                                    "memory": 256,    # In MBs
+                        },
+                         "service_offering2": {
+                                    "name": "Med Instance",
+                                    "displaytext": "Med Instance",
+                                    "cpunumber": 1,
+                                    "cpuspeed": 1000,    # In MHz
+                                    "memory": 1024,    # In MBs
+                        },
+                        "disk_offering": {
+                                    "displaytext": "Small Disk",
+                                    "name": "Small Disk",
+                                    "disksize": 1,
+                                    "storagetype": "shared",
+                        },
+                        "disk_offering2": {
+                                    "displaytext": "Med Disk",
+                                    "name": "Med Disk",
+                                    "disksize": 5,
+                                    "storagetype": "shared",
+                        },
+                        "account": {
+                                    "email": "test@test.com",
+                                    "firstname": "Test",
+                                    "lastname": "User",
+                                    "username": "test",
+                                    # Random characters are appended in create account to
+                                    # ensure unique username generated each time
+                                    "password": "password",
+                        },
+                        "virtual_machine": {
+                                    "displayname": "TestVM",
+                                    "username": "root",
+                                    "password": "password",
+                                    "ssh_port": 22,
+                                    "hypervisor": 'XenServer',
+                                    "privateport": 22,
+                                    "publicport": 22,
+                                    "protocol": 'TCP',
+                        },
+                        "template": {
+                                    "displaytext": "Public Template",
+                                    "name": "Public template",
+                                    "ostype": 'CentOS 5.3 (64-bit)',
+                                    "isfeatured": True,
+                                    "ispublic": True,
+                                    "isextractable": True,
+                                    "templatefilter": 'self',
+                        },
+                        "volume": {
+                                   "diskname": "TestDiskServ",
+                                   "size": 1,    # GBs
+                        },
+                        "diskdevice": "/dev/xvda",
+                        "rootdisk": "/dev/xvda",
+
+                        "mount_dir": "/mnt/tmp",
+                        "sub_dir": "test",
+                        "sub_lvl_dir1": "test1",
+                        "sub_lvl_dir2": "test2",
+                        "random_data": "random.data",
+
+                        "ostype": 'CentOS 5.3 (64-bit)',
+                        "NumberOfThreads": 1,
+                        "sleep": 60,
+                        "timeout": 10,
+                        "mode": 'advanced',
+                        # Networking mode: Advanced, Basic
+                }
+
+class TestSnapshotOnRootVolume(cloudstackTestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        cls.api_client = super(TestSnapshotOnRootVolume,
+                               cls).getClsTestClient().getApiClient()
+        cls.services = Services().services
+        cls.domain = get_domain(cls.api_client, cls.services)
+        cls.zone = get_zone(cls.api_client, cls.services)
+        cls.template = get_template(
+                                    cls.api_client,
+                                    cls.zone.id,
+                                    cls.services["ostype"])
+        cls.account = Account.create(cls.api_client,
+                                     cls.services["account"],
+                                     domainid=cls.domain.id)
+        # pdb.set_trace()
+        cls.service_offering = ServiceOffering.create(
+                                            cls.api_client,
+                                            cls.services["service_offering"])
+        cls.disk_offering = DiskOffering.create(
+                                    cls.api_client,
+                                    cls.services["disk_offering"],
+                                    domainid=cls.domain.id)
+        cls.service_offering2 = ServiceOffering.create(
+                                            cls.api_client,
+                                            cls.services["service_offering2"])
+        cls.disk_offering2 = DiskOffering.create(
+                                    cls.api_client,
+                                    cls.services["disk_offering2"],
+                                    domainid=cls.domain.id)
+
+        cls._cleanup = [cls.account,
+                        cls.service_offering,
+                        cls.disk_offering,
+                        cls.service_offering2,
+                        cls.disk_offering2]
+
+    @classmethod
+    def tearDownClass(cls):
+        try:
+            # Cleanup resources used
+            cleanup_resources(cls.api_client, cls._cleanup)
+        except Exception as e:
+            raise Exception("Warning: Exception during cleanup : %s" % e)
+        return
+
+    def setUp(self):
+        self.apiclient = self.testClient.getApiClient()
+        self.dbclient = self.testClient.getDbConnection()
+        self.cleanup = []
+        return
+
+    def tearDown(self):
+        try:
+            # Clean up, terminate the created instance, volumes and snapshots
+            cleanup_resources(self.apiclient, self.cleanup)
+        except Exception as e:
+            raise Exception("Warning: Exception during cleanup : %s" % e)
+        return
+
+    @attr(tags=["advanced", "basic"])
+    def test_01_snapshot_on_rootVolume(self):
+        """Test create VM with default cent os template and create snapshot
+            on root disk of the vm
+        """
+        # Validate the following
+        # 1. Deploy a Linux VM using default CentOS template, use small service
+        #    offering, disk offering
+        # 2. Create snapshot on the root disk of this newly cteated vm
+        # 3. listSnapshots should list the snapshot that was created.
+        # 4. verify that secondary storage NFS share contains the reqd
+        # volume under /secondary/snapshots/$accountid/$volumeid/$snapshot_uuid
+        # 5. verify backup_snap_id was non null in the `snapshots` table
+
+        # Create virtual machine with small systerm offering and disk offering
+        new_virtual_machine = VirtualMachine.create(
+                                    self.apiclient,
+                                    self.services["virtual_machine"],
+                                    templateid=self.template.id,
+                                    zoneid=self.zone.id,
+                                    accountid=self.account.name,
+                                    domainid=self.account.domainid,
+                                    serviceofferingid=self.service_offering.id,
+                                    diskofferingid=self.disk_offering.id,
+                                )
+        self.debug("Virtual machine got created with id: %s" %
+                                                    new_virtual_machine.id)
+        list_virtual_machine_response = VirtualMachine.list(
+                                                    self.apiclient,
+                                                    id=new_virtual_machine.id)
+        self.assertEqual(isinstance(list_virtual_machine_response, list),
+                         True,
+                         "Check listVirtualMachines returns a valid list")
+
+        self.assertNotEqual(len(list_virtual_machine_response),
+                            0,
+                            "Check listVirtualMachines response")
+        self.cleanup.append(new_virtual_machine)
+
+        # Getting root volume id of the vm created above
+        list_volume_response = Volume.list(
+                                self.apiclient,
+                                virtualmachineid=list_virtual_machine_response[0].id,
+                                type="ROOT",
+                                account=self.account.name,
+                                domainid=self.account.domainid)
+
+        self.assertEqual(isinstance(list_volume_response, list),
+                         True,
+                         "Check listVolumes returns a valid list")
+        self.assertNotEqual(len(list_volume_response),
+                            0,
+                            "Check listVolumes response")
+        self.debug(
+            "Snapshot will be created on the volume with voluem id: %s" %
+                                                    list_volume_response[0].id)
+
+        # Perform snapshot on the root volume
+        root_volume_snapshot = Snapshot.create(
+                                        self.apiclient,
+                                       volume_id=list_volume_response[0].id)
+        self.debug("Created snapshot: %s for vm: %s" % (
+                                        root_volume_snapshot.id,
+                                        list_virtual_machine_response[0].id))
+        list_snapshot_response = Snapshot.list(
+                                        self.apiclient,
+                                        id=root_volume_snapshot.id,
+                                        account=self.account.name,
+                                        domainid=self.account.domainid)
+        self.assertEqual(isinstance(list_snapshot_response, list),
+                         True,
+                         "Check listSnapshots returns a valid list")
+
+        self.assertNotEqual(len(list_snapshot_response),
+                            0,
+                            "Check listSnapshots response")
+        # Verify Snapshot state
+        self.assertEqual(
+                            list_snapshot_response[0].state in [
+                                                                'BackedUp',
+                                                                'CreatedOnPrimary'
+                                                                ],
+                            True,
+                            "Snapshot state is not as expected. It is %s" %
+                            list_snapshot_response[0].state
+                        )
+
+        self.assertEqual(
+                list_snapshot_response[0].volumeid,
+                list_volume_response[0].id,
+                "Snapshot volume id is not matching with the vm's volume id")
+        self.cleanup.append(root_volume_snapshot)
+
+        # Below code is to verify snapshots in the backend and in db.
+        # Verify backup_snap_id field in the snapshots table for the snapshot created, it should not be null
+
+        self.debug("select id, removed, backup_snap_id from snapshots where uuid = '%s';" % root_volume_snapshot.id)
+        qryresult = self.dbclient.execute("select id, removed, backup_snap_id from snapshots where uuid = '%s';" % root_volume_snapshot.id)
+        self.assertNotEqual(len(qryresult), 0, "Check sql query to return snapshots list")
+        snapshot_qry_response = qryresult[0]
+        snapshot_id = snapshot_qry_response[0]
+        is_removed = snapshot_qry_response[1]
+        backup_snap_id = snapshot_qry_response[2]
+        self.assertNotEqual(is_removed, "NULL", "Snapshot is removed from CS, please check the logs")
+        msg = "Backup snapshot id is set to null for the backedup snapshot :%s" % snapshot_id
+        self.assertNotEqual(backup_snap_id, "NULL", msg )
+
+        # Check if the snapshot is present on the secondary storage
+        self.assertTrue(is_snapshot_on_nfs(self.apiclient, self.dbclient, self.config, self.zone.id, root_volume_snapshot.id))
+
+        return
+
+class TestCreateSnapshot(cloudstackTestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        cls.api_client = super(
+                               TestCreateSnapshot,
+                               cls).getClsTestClient().getApiClient()
+        cls.services = Services().services
+        # Get Zone, Domain and templates
+        cls.domain = get_domain(cls.api_client, cls.services)
+        cls.zone = get_zone(cls.api_client, cls.services)
+
+        cls.template = get_template(
+                            cls.api_client,
+                            cls.zone.id,
+                            cls.services["ostype"]
+                            )
+
+        cls.services["virtual_machine"]["zoneid"] = cls.zone.id
+
+        # Create VMs, NAT Rules etc
+        cls.service_offering = ServiceOffering.create(
+                                            cls.api_client,
+                                            cls.services["service_offering"]
+                                            )
+        cls._cleanup = [
+                        cls.service_offering,
+                        ]
+        return
+
+    @classmethod
+    def tearDownClass(cls):
+        try:
+            # Cleanup resources used
+            cleanup_resources(cls.api_client, cls._cleanup)
+        except Exception as e:
+            raise Exception("Warning: Exception during cleanup : %s" % e)
+        return
+
+    def setUp(self):
+        self.apiclient = self.testClient.getApiClient()
+        self.dbclient = self.testClient.getDbConnection()
+
+        self.account = Account.create(
+                            self.apiclient,
+                            self.services["account"],
+                            domainid=self.domain.id
+                            )
+        self.cleanup = [self.account, ]
+        return
+
+    def tearDown(self):
+        try:
+            # Clean up, terminate the created instance, volumes and snapshots
+            cleanup_resources(self.apiclient, self.cleanup)
+        except Exception as e:
+            raise Exception("Warning: Exception during cleanup : %s" % e)
+        return
+
+    def create_VM(self, host_id=None):
+        try:
+            self.debug('Creating VM for account=%s' %
+                                            self.account.name)
+            vm = VirtualMachine.create(
+                                    self.apiclient,
+                                    self.services["virtual_machine"],
+                                    templateid=self.template.id,
+                                    accountid=self.account.name,
+                                    domainid=self.account.domainid,
+                                    serviceofferingid=self.service_offering.id,
+                                    hostid=host_id,
+                                    mode=self.services["mode"]
+                                    )
+            self.debug('Created VM=%s in account=%s' %
+                                        (vm.id, self.account.name))
+            return vm
+        except Exception as e:
+            self.fail('Unable to deploy VM in a account=%s - %s' %
+                                                (self.account.name, e))
+
+    def stop_VM(self, virtual_machine):
+        """ Return Stop Virtual Machine command"""
+
+        cmd = stopVirtualMachine.stopVirtualMachineCmd()
+        cmd.id = virtual_machine.id
+        return cmd
+
+    def create_Snapshot_On_Root_Disk(self, virtual_machine):
+        try:
+            volumes = Volume.list(
+                                  self.apiclient,
+                                  virtualmachineid=virtual_machine.id,
+                                  type='ROOT',
+                                  listall=True
+                                  )
+            self.assertEqual(
+                            isinstance(volumes, list),
+                            True,
+                            "Check list response returns a valid list"
+                        )
+            volume = volumes[0]
+
+            cmd = createSnapshot.createSnapshotCmd()
+            cmd.volumeid = volume.id
+            cmd.account = self.account.name
+            cmd.domainid = self.account.domainid
+            return cmd
+        except Exception as e:
+            self.fail('Unable to create new job for snapshot: %s' % e)
+
+    def create_Template_from_Snapshot(self, snapshot):
+        try:
+            self.debug("Creating template from snapshot: %s" % snapshot.name)
+
+            cmd = createTemplate.createTemplateCmd()
+            cmd.displaytext = self.services["template"]["displaytext"]
+            cmd.name = "-".join([self.services["template"]["name"],
+                                 random_gen()])
+
+            ncmd = listOsTypes.listOsTypesCmd()
+            ncmd.description = self.services["template"]["ostype"]
+            ostypes = self.apiclient.listOsTypes(ncmd)
+
+            if not isinstance(ostypes, list):
+                raise Exception(
+                    "Unable to find Ostype id with desc: %s" %
+                                        self.services["template"]["ostype"])
+            cmd.ostypeid = ostypes[0].id
+            cmd.snapshotid = snapshot.id
+
+            return cmd
+        except Exception as e:
+            self.fail("Failed to create template from snapshot: %s - %s" %
+                                                        (snapshot.name, e))
+
+    def create_Volume_from_Snapshot(self, snapshot):
+        try:
+            self.debug("Creating volume from snapshot: %s" % snapshot.name)
+
+            cmd = createVolume.createVolumeCmd()
+            cmd.name = "-".join([
+                                self.services["volume"]["diskname"],
+                                random_gen()])
+            cmd.snapshotid = snapshot.id
+            cmd.zoneid = self.zone.id
+            cmd.size = self.services["volume"]["size"]
+            cmd.account = self.account.name
+            cmd.domainid = self.account.domainid
+            return cmd
+        except Exception as e:
+            self.fail("Failed to create volume from snapshot: %s - %s" %
+                                                        (snapshot.name, e))
+
+    def create_Snapshot_VM(self):
+        """Creates a virtual machine and take a snapshot on root disk
+
+            1. Create a virtual machine
+            2. SSH into virtual machine
+            3. Create dummy folders on the ROOT disk of the virtual machine
+            4. Take a snapshot of ROOT disk"""
+
+        jobs = []
+        self.debug("Deploying VM for account: %s" % self.account.name)
+        for i in range(self.services["NumberOfThreads"]):
+            vm = self.create_VM()
+
+            self.debug("Create snapshot on ROOT disk")
+            jobs.append(self.create_Snapshot_On_Root_Disk(vm))
+
+        # Submit snapshot job at one go
+        self.testClient.submitCmdsAndWait(jobs)
+        return
+
+    def create_Snaphot_Stop_VM(self):
+        """Creates a snapshot on ROOT disk while vm is in stopping state
+
+            1. Create a virtual machine
+            2. SSH into virtual machine
+            3. Create dummy folders on the ROOT disk of the virtual machine
+            4. Create snapshot on ROOT disk
+            5. Stop virtual machine while snapshots are taken on ROOT disk"""
+
+
+        jobs = []
+        self.debug("Deploying VM for account: %s" % self.account.name)
+        for i in range(self.services["NumberOfThreads"]):
+            vm = self.create_VM()
+
+            self.debug("Create thread to stop virtual machine: %s" % vm.name)
+            jobs.append(self.stop_VM(vm))
+
+            self.debug("Create snapshot on ROOT disk")
+            jobs.append(self.create_Snapshot_On_Root_Disk(vm))
+
+        self.debug("Running concurrent migration jobs in account: %s" %
+                                                    self.account.name)
+        # Submit snapshot job at one go
+        self.testClient.submitCmdsAndWait(jobs)
+
+        return
+
+    def get_Snapshots_For_Account(self, account, domainid):
+        try:
+            snapshots = list_snapshots(
+                                      self.apiclient,
+                                      account=account,
+                                      domainid=domainid,
+                                      listall=True,
+                                      key='type',
+                                      value='manual'
+                                      )
+            self.debug("List Snapshots result : %s" % snapshots)
+            self.assertEqual(
+                             isinstance(snapshots, list),
+                             True,
+                             "List snapshots shall return a valid list"
+                             )
+            return snapshots
+        except Exception as e:
+            self.fail("Failed to fetch snapshots for account: %s - %s" %
+                                                                (account, e))
+
+    def verify_Snapshots(self):
+        try:
+            self.debug("Listing snapshots for accout : %s" % self.account.name)
+            snapshots = self.get_Snapshots_For_Account(
+                                            self.account.name,
+                                            self.account.domainid)
+            self.assertEqual(
+                    len(snapshots),
+                    int(self.services["NumberOfThreads"]),
+                    "No of snapshots should equal to no of threads spawned"
+                 )
+        except Exception as e:
+            self.fail("Failed to verify snapshots created: %s" % e)
+
+    @attr(speed="slow")
+    @attr(tags=["advanced", "advancedns"])
+    @attr(configuration='concurrent.snapshots.threshold.perhost')
+    def test_01_concurrent_snapshots_live_migrate(self):
+        """Test perform concurrent snapshots and migrate the vm from one host
+            to another
+
+            1.Configure the concurrent.snapshots.threshold.perhost=3
+            2.Deploy a Linux VM using default CentOS template, use small
+            service offering, disk offering
+            3.Perform snapshot on the root disk of this newly created VMs"""
+
+        # Validate the following
+        # a. Check all snapshots jobs are running concurrently on backgrounds
+        # b. listSnapshots should list this newly created snapshot.
+
+        self.debug("Create virtual machine and snapshot on ROOT disk volume")
+        self.create_Snapshot_VM()
+
+        self.debug("Verify whether snapshots were created properly or not?")
+        self.verify_Snapshots()
+        return
+
+    @attr(speed="slow")
+    @attr(tags=["advanced", "advancedns"])
+    @attr(configuration='concurrent.snapshots.threshold.perhost')
+    def test_02_stop_vm_concurrent_snapshots(self):
+        """Test stop running VM while performing concurrent snapshot on volume
+
+            1.Configure the concurrent.snapshots.threshold.perhost=3
+            2.Deploy a Linux VM using default CentOS template, use small
+            service offering, disk offering
+            3.Perform snapshot on root disk of this newly created VM
+            4.stop the running Vms while snapshot on volume in progress
+        """
+
+        # Validate the following
+        # a. check all snapshots jobs are running concurrently on back grounds
+        # b. listSnapshots should list this newly created snapshot.
+
+        self.debug("Create virtual machine and snapshot on ROOT disk volume")
+        self.create_Snaphot_Stop_VM()
+
+        self.debug("Verify whether snapshots were created properly or not?")
+        self.verify_Snapshots()
+        return
+
+    @attr(speed="slow")
+    @attr(tags=["advanced", "advancedns"])
+    @attr(configuration='concurrent.snapshots.threshold.perhost')
+    def test_03_concurrent_snapshots_create_template(self):
+        """Test while parent concurrent snapshot job in progress,create
+            template from completed snapshot
+
+            1.Configure the concurrent.snapshots.threshold.perhost=3
+            2.Deploy a Linux VM using default CentOS template, use small
+            service offering, disk offering
+            3.Perform snapshot on root disk of this newly created VMs(10 vms)
+            4.while parent concurrent snapshot job in progress,create template
+            from completed snapshot"""
+
+        # Validate the following
+        # a.Able to create Template from snapshots
+        # b.check all snapshots jobs are running concurrently on back grounds
+        # c.listSnapshots should list this newly created snapshot.
+
+        self.debug("Create virtual machine and snapshot on ROOT disk")
+        self.create_Snapshot_VM()
+
+        self.debug("Verify whether snapshots were created properly or not?")
+        self.verify_Snapshots()
+
+        self.debug("Fetch the list of snapshots belong to account: %s" %
+                                                    self.account.name)
+        snapshots = self.get_Snapshots_For_Account(
+                                                self.account.name,
+                                                self.account.domainid)
+        jobs = []
+        for snapshot in snapshots:
+            self.debug("Create a template from snapshot: %s" % snapshot.name)
+            jobs.append(self.create_Template_from_Snapshot(snapshot))
+
+        # Verify IO usage by submitting the concurrent jobs
+        self.testClient.submitCmdsAndWait(jobs)
+
+        self.debug("Verifying if templates are created properly or not?")
+        templates = Template.list(
+                            self.apiclient,
+                            templatefilter=self.services["template"]["templatefilter"],
+                            account=self.account.name,
+                            domainid=self.account.domainid,
+                            listall=True)
+        self.assertNotEqual(templates,
+                            None,
+                            "Check if result exists in list item call")
+        for template in templates:
+            self.assertEqual(template.isready,
+                         True,
+                        "Check new template state in list templates call")
+
+        self.debug("Test completed successfully.")
+        return
+
+    @attr(speed="slow")
+    @attr(tags=["advanced", "advancedns"])
+    @attr(configuration='concurrent.snapshots.threshold.perhost')
+    def test_04_concurrent_snapshots_create_volume(self):
+        """Test while parent concurrent snapshot job in progress,create volume
+            from completed snapshot
+
+            1.Configure the concurrent.snapshots.threshold.perhost=3
+            2.Deploy a Linux VM using default CentOS template, use small
+            service offering, disk offering.
+            3.Perform snapshot on root disk of this newly created VM
+            4.while parent concurrent snapshot job in progress,create volume
+            from completed snapshot"""
+
+        # Validate the following
+        # a.Able to create Volume from snapshots
+        # b.check all snapshots jobs are running concurrently on back grounds
+        # c.listSnapshots should list this newly created snapshot.
+
+        self.debug("Create virtual machine and snapshot on ROOT disk thread")
+        self.create_Snapshot_VM()
+
+        self.debug("Verify whether snapshots were created properly or not?")
+        self.verify_Snapshots()
+
+        self.debug("Fetch the list of snapshots belong to account: %s" %
+                                                    self.account.name)
+        snapshots = self.get_Snapshots_For_Account(
+                                                self.account.name,
+                                                self.account.domainid)
+        jobs = []
+        for snapshot in snapshots:
+            self.debug("Create a volume from snapshot: %s" % snapshot.name)
+            jobs.append(self.create_Volume_from_Snapshot(snapshot))
+
+        # Verify IO usage by submitting the concurrent jobs
+        self.testClient.submitCmdsAndWait(jobs)
+
+        self.debug("Verifying if volume created properly or not?")
+        volumes = Volume.list(self.apiclient,
+                              account=self.account.name,
+                              domainid=self.account.domainid,
+                              listall=True,
+                              type='ROOT')
+
+        self.assertNotEqual(volumes,
+                            None,
+                            "Check if result exists in list item call")
+        for volume in volumes:
+            self.debug("Volume: %s, state: %s" % (volume.name, volume.state))
+            self.assertEqual(volume.state,
+                         "Ready",
+                         "Check new volume state in list volumes call")
+
+        self.debug("Test completed successfully.")
+        return

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/1972d612/tools/marvin/marvin/asyncJobMgr.py
----------------------------------------------------------------------
diff --git a/tools/marvin/marvin/asyncJobMgr.py b/tools/marvin/marvin/asyncJobMgr.py
index 25818a6..0d7939c 100644
--- a/tools/marvin/marvin/asyncJobMgr.py
+++ b/tools/marvin/marvin/asyncJobMgr.py
@@ -81,14 +81,14 @@ class workThread(threading.Thread):
             if cmd.isAsync == "false":
                 jobstatus.startTime = datetime.datetime.now()
 
-                result = self.connection.make_request(cmd)
+                result = self.connection.marvin_request(cmd)
                 jobstatus.result = result
                 jobstatus.endTime = datetime.datetime.now()
                 jobstatus.duration =\
                     time.mktime(jobstatus.endTime.timetuple()) - time.mktime(
                         jobstatus.startTime.timetuple())
             else:
-                result = self.connection.make_request(cmd, None, True)
+                result = self.connection.marvin_request(cmd)
                 if result is None:
                     jobstatus.status = False
                 else: