diff --git a/test/integration/component/test_snapshot_gc.py b/test/integration/component/test_snapshot_gc.py index ac18bd52cb5..04328e89853 100644 --- a/test/integration/component/test_snapshot_gc.py +++ b/test/integration/component/test_snapshot_gc.py @@ -86,12 +86,6 @@ class Services: "publicport": 22, "protocol": 'TCP', }, - "mgmt_server": { - "ipaddress": '192.168.100.21', - "username": "root", - "password": "password", - "port": 22, - }, "recurring_snapshot": { "intervaltype": 'HOURLY', # Frequency of snapshots @@ -157,7 +151,8 @@ class TestAccountSnapshotClean(cloudstackTestCase): cls.services["account"] = cls.account.name cls._cleanup.append(cls.account) - cls.services["service_offering"]["storagetype"] = "local" + if cls.zone.localstorageenabled: + cls.services["service_offering"]["storagetype"] = "local" cls.service_offering = ServiceOffering.create( cls.api_client, cls.services["service_offering"] @@ -302,9 +297,9 @@ class TestAccountSnapshotClean(cloudstackTestCase): # State of this VM should be "Running" # 3. a)listSnapshots should list the snapshot that was created. # b)verify that secondary storage NFS share contains the reqd volume - # under /secondary/snapshots/$accountid/$volumeid/$snapshot_uuid + # under /secondary/snapshots/$accountid/$volumeid/$snapshot_id # 4. a)listAccounts should not list account that is deleted - # b) snapshot image($snapshot_uuid) should be deleted from the + # b) snapshot image($snapshot_id) should be deleted from the # /secondary/snapshots/$accountid/$volumeid/ accounts = list_accounts( @@ -385,9 +380,9 @@ class TestAccountSnapshotClean(cloudstackTestCase): ) qresult = qresultset[0] - snapshot_uuid = qresult[0] + snapshot_id = qresult[0] - self.assertTrue(self.is_snapshot_on_nfs(snapshot_uuid), "Snapshot was not found no NFS") + self.assertTrue(self.is_snapshot_on_nfs(snapshot_id), "Snapshot was not found no NFS") self.debug("Deleting account: %s" % self.account.name) # Delete account @@ -405,5 +400,5 @@ class TestAccountSnapshotClean(cloudstackTestCase): "List accounts should return empty list after account deletion" ) - self.assertFalse(self.is_snapshot_on_nfs(snapshot_uuid), "Snapshot was still found no NFS after account gc") + self.assertFalse(self.is_snapshot_on_nfs(snapshot_id), "Snapshot was still found no NFS after account gc") return \ No newline at end of file diff --git a/test/integration/component/test_snapshot_limits.py b/test/integration/component/test_snapshot_limits.py index 5acd066a478..a1cd45d0396 100644 --- a/test/integration/component/test_snapshot_limits.py +++ b/test/integration/component/test_snapshot_limits.py @@ -86,12 +86,6 @@ class Services: "publicport": 22, "protocol": 'TCP', }, - "mgmt_server": { - "ipaddress": '192.168.100.21', - "username": "root", - "password": "password", - "port": 22, - }, "recurring_snapshot": { "intervaltype": 'HOURLY', # Frequency of snapshots @@ -135,48 +129,57 @@ class TestSnapshotLimit(cloudstackTestCase): cls.domain = get_domain(cls.api_client, cls.services) cls.zone = get_zone(cls.api_client, cls.services) cls.services['mode'] = cls.zone.networktype + cls._cleanup = [] - template = get_template( - cls.api_client, - cls.zone.id, - cls.services["ostype"] - ) - cls.services["server"]["zoneid"] = cls.zone.id - - cls.services["template"] = template.id - - # Create VMs, NAT Rules etc - cls.account = Account.create( - cls.api_client, - cls.services["account"], - domainid=cls.domain.id - ) - - cls.services["account"] = cls.account.name - - cls.service_offering = ServiceOffering.create( - cls.api_client, - cls.services["service_offering"] - ) - cls.virtual_machine = VirtualMachine.create( + try: + template = get_template( cls.api_client, - cls.services["server"], - templateid=template.id, - accountid=cls.account.name, - domainid=cls.account.domainid, - serviceofferingid=cls.service_offering.id + cls.zone.id, + cls.services["ostype"] ) - cls._cleanup = [ - cls.service_offering, - cls.account, - ] + cls.services["server"]["zoneid"] = cls.zone.id + + cls.services["template"] = template.id + + # Create VMs, NAT Rules etc + cls.account = Account.create( + cls.api_client, + cls.services["account"], + domainid=cls.domain.id + ) + cls._cleanup.append(cls.account) + + cls.services["account"] = cls.account.name + + if cls.zone.localstorageenabled: + cls.services["service_offering"]["storagetype"] = "local" + cls.service_offering = ServiceOffering.create( + cls.api_client, + cls.services["service_offering"] + ) + cls._cleanup.append(cls.service_offering) + cls.virtual_machine = VirtualMachine.create( + cls.api_client, + cls.services["server"], + templateid=template.id, + accountid=cls.account.name, + domainid=cls.account.domainid, + serviceofferingid=cls.service_offering.id + ) + cls._cleanup.append(cls.virtual_machine) + except Exception, e: + cls.tearDownClass() + unittest.SkipTest("setupClass fails for %s" % cls.__name__) + raise e + else: + cls._cleanup.remove(cls.account) return @classmethod def tearDownClass(cls): try: #Cleanup resources used - cleanup_resources(cls.api_client, cls._cleanup) + cleanup_resources(cls.api_client, reversed(cls._cleanup)) except Exception as e: raise Exception("Warning: Exception during cleanup : %s" % e) return @@ -195,6 +198,82 @@ class TestSnapshotLimit(cloudstackTestCase): raise Exception("Warning: Exception during cleanup : %s" % e) return + def is_snapshot_on_nfs(self, snapshot_id): + """ + Checks whether a snapshot with id (not UUID) `snapshot_id` is present on the nfs storage + + @param snapshot_id: id of the snapshot (not uuid) + @return: True if snapshot is found, False otherwise + """ + secondaryStores = ImageStore.list(self.apiclient, zoneid=self.zone.id) + self.assertTrue(isinstance(secondaryStores, list), "Not a valid response for listImageStores") + self.assertNotEqual(len(secondaryStores), 0, "No image stores found in zone %s" % self.zone.id) + secondaryStore = secondaryStores[0] + if str(secondaryStore.providername).lower() != "nfs": + self.skipTest("TODO: %s test works only against nfs secondary storage" % self._testMethodName) + + qresultset = self.dbclient.execute( + "select install_path from snapshot_store_ref where snapshot_id='%s' and store_role='Image';" % snapshot_id + ) + self.assertEqual( + isinstance(qresultset, list), + True, + "Invalid db query response for snapshot %s" % self.snapshot.id + ) + self.assertNotEqual( + len(qresultset), + 0, + "No such snapshot %s found in the cloudstack db" % self.snapshot.id + ) + snapshotPath = qresultset[0][0] + nfsurl = secondaryStore.url + # parse_url = ['nfs:', '', '192.168.100.21', 'export', 'test'] + from urllib2 import urlparse + parse_url = urlparse.urlsplit(nfsurl, scheme='nfs') + host, path = parse_url.netloc, parse_url.path + # Sleep to ensure that snapshot is reflected in sec storage + time.sleep(self.services["sleep"]) + snapshots = [] + try: + # Login to Secondary storage VM to check snapshot present on sec disk + ssh_client = remoteSSHClient( + self.config.mgtSvr[0].mgtSvrIp, + 22, + self.config.mgtSvr[0].user, + self.config.mgtSvr[0].passwd, + ) + + cmds = [ + "mkdir -p %s" % self.services["paths"]["mount_dir"], + "mount -t %s %s/%s %s" % ( + 'nfs', + host, + path, + self.services["paths"]["mount_dir"] + ), + "ls %s" % ( + snapshotPath + ), + ] + + for c in cmds: + self.debug("command: %s" % c) + result = ssh_client.execute(c) + self.debug("Result: %s" % result) + + snapshots.extend(result) + # Unmount the Sec Storage + cmds = [ + "umount %s" % (self.services["paths"]["mount_dir"]), + ] + for c in cmds: + ssh_client.execute(c) + except Exception as e: + self.fail("SSH failed for management server: %s - %s" % + (self.services["mgmt_server"]["ipaddress"], e)) + res = str(snapshots) + return res.count(snapshot_id) == 1 + @attr(speed = "slow") @attr(tags = ["advanced", "advancedns"]) def test_04_snapshot_limit(self): @@ -288,97 +367,21 @@ class TestSnapshotLimit(cloudstackTestCase): # Fetch values from database qresultset = self.dbclient.execute( - "select backup_snap_id, account_id, volume_id from snapshots where uuid = '%s';" \ + "select id from snapshots where uuid = '%s';" \ % snapshot.id ) self.assertEqual( isinstance(qresultset, list), True, - "Check DBQuery returns a valid list" + "Invalid db query response for snapshot %s" % self.snapshot.id ) self.assertNotEqual( len(qresultset), 0, - "Check DB Query result set" + "No such snapshot %s found in the cloudstack db" % self.snapshot.id ) qresult = qresultset[0] - snapshot_uuid = qresult[0] # backup_snap_id = snapshot UUID - account_id = qresult[1] - volume_id = qresult[2] - - # Get the Secondary Storage details from list Hosts - hosts = list_hosts( - self.apiclient, - type='SecondaryStorage', - zoneid=self.zone.id - ) - self.assertEqual( - isinstance(hosts, list), - True, - "Check list response returns a valid list" - ) - uuids = [] - for host in hosts: - # hosts[0].name = "nfs://192.168.100.21/export/test" - parse_url = (host.name).split('/') - # parse_url = ['nfs:', '', '192.168.100.21', 'export', 'test'] - - # Stripping end ':' from storage type - storage_type = parse_url[0][:-1] - # Split IP address and export path from name - sec_storage_ip = parse_url[2] - # Sec Storage IP: 192.168.100.21 - - if sec_storage_ip[-1] != ":": - sec_storage_ip = sec_storage_ip + ":" - - export_path = '/'.join(parse_url[3:]) - # Export path: export/test - try: - # Login to VM to check snapshot present on sec disk - ssh_client = remoteSSHClient( - self.services["mgmt_server"]["ipaddress"], - self.services["mgmt_server"]["port"], - self.services["mgmt_server"]["username"], - self.services["mgmt_server"]["password"], - ) - - cmds = [ - "mkdir -p %s" % self.services["paths"]["mount_dir"], - "mount -t %s %s/%s %s" % ( - storage_type, - sec_storage_ip, - export_path, - self.services["paths"]["mount_dir"] - ), - "ls %s/snapshots/%s/%s" % ( - self.services["paths"]["mount_dir"], - account_id, - volume_id - ), - ] - - for c in cmds: - result = ssh_client.execute(c) - - uuids.append(result) - - # Unmount the Sec Storage - cmds = [ - "umount %s" % (self.services["paths"]["mount_dir"]), - ] - for c in cmds: - result = ssh_client.execute(c) - except Exception as e: - raise Exception( - "SSH access failed for management server: %s - %s" % - (self.services["mgmt_server"]["ipaddress"], e)) - - res = str(uuids) - self.assertEqual( - res.count(snapshot_uuid), - 1, - "Check snapshot UUID in secondary storage and database" - ) + snapshot_id = qresult[0] + self.is_snapshot_on_nfs(snapshot_id) return \ No newline at end of file